From 3e4ec13eddebe9127165eabc840e724c371dfc25 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Thu, 30 Nov 2023 22:28:51 +0100 Subject: [PATCH 01/45] [SolidMechanics.Spring] Implement buildStiffnessMatrix for TriangularBendingSprings (#4295) Co-authored-by: Hugo --- .../spring/TriangularBendingSprings.h | 1 + .../spring/TriangularBendingSprings.inl | 30 +++++++++++- .../Spring/TriangularBendingSprings.scn | 48 ++++++++----------- 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.h index 1c4a57cea86..6b37f9cbfc9 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.h @@ -139,6 +139,7 @@ class TriangularBendingSprings : public core::behavior::ForceField void addForce(const core::MechanicalParams* mparams, DataVecDeriv& d_f, const DataVecCoord& d_x, const DataVecDeriv& d_v) override; void addDForce(const core::MechanicalParams* mparams, DataVecDeriv& d_df, const DataVecDeriv& d_dx) override; + void buildStiffnessMatrix(core::behavior::StiffnessMatrix* matrix) override; void buildDampingMatrix(core::behavior::DampingMatrix* /*matrix*/) final; void draw(const core::visual::VisualParams* vparams) override; diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.inl b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.inl index 90d04039e56..fd9f38232c2 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.inl +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.inl @@ -502,7 +502,7 @@ void TriangularBendingSprings::addForce(const core::MechanicalParams* template void TriangularBendingSprings::addDForce(const core::MechanicalParams* mparams, DataVecDeriv& d_df, const DataVecDeriv& d_dx) { - VecDeriv& df = *d_df.beginEdit(); + auto df = sofa::helper::getWriteAccessor(d_df); const VecDeriv& dx = d_dx.getValue(); Real kFactor = (Real)sofa::core::mechanicalparams::kFactorIncludingRayleighDamping(mparams, this->rayleighStiffness.getValue()); @@ -524,7 +524,33 @@ void TriangularBendingSprings::addDForce(const core::MechanicalParams df[a]+= dforce * kFactor; df[b]-= dforce * kFactor; } - d_df.endEdit(); +} + +template +void TriangularBendingSprings::buildStiffnessMatrix( + core::behavior::StiffnessMatrix* matrix) +{ + auto dfdx = matrix->getForceDerivativeIn(this->mstate) + .withRespectToPositionsIn(this->mstate); + + const type::vector& edgeInf = edgeInfo.getValue(); + + for (sofa::Index i = 0; i < m_topology->getNbEdges(); i++) + { + const EdgeInformation& einfo = edgeInf[i]; + if (einfo.is_activated) // edge not in middle of 2 triangles + { + const sofa::Index a = Deriv::total_size * einfo.m1; + const sofa::Index b = Deriv::total_size * einfo.m2; + + const Mat& dfdxLocal = einfo.DfDx; + + dfdx(a, a) += -dfdxLocal; + dfdx(a, b) += dfdxLocal; + dfdx(b, a) += dfdxLocal; + dfdx(b, b) += -dfdxLocal; + } + } } template diff --git a/examples/Component/SolidMechanics/Spring/TriangularBendingSprings.scn b/examples/Component/SolidMechanics/Spring/TriangularBendingSprings.scn index 608bfc799ed..1b7c86c3000 100644 --- a/examples/Component/SolidMechanics/Spring/TriangularBendingSprings.scn +++ b/examples/Component/SolidMechanics/Spring/TriangularBendingSprings.scn @@ -1,43 +1,37 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - + - + + - + - - - + + From 4ecb558f19811320881916aa756f3fb2d65c49f9 Mon Sep 17 00:00:00 2001 From: Hugo Date: Fri, 1 Dec 2023 17:27:17 +0100 Subject: [PATCH 02/45] [all] Fix warnings (#4291) * [all] Fix warnings * revert change on scenes wrongly committed * Apply suggestions from code review Co-authored-by: Alex Bilger * [all] Fix warnings * Fix runtime error due to useless destructor * take reviews into account: d_nbThreads back to int --------- Co-authored-by: Alex Bilger --- .../tests/FixedPlaneConstraint_test.cpp | 2 +- .../iterative/MatrixLinearSolver.inl | 8 +- .../matrixaccumulators/ConstantLocalMatrix.h | 4 + .../tests/MatrixLinearSystem_test.cpp | 36 ++++- .../mechanicalload/EllipsoidForceField.h | 46 ++---- .../mechanicalload/EllipsoidForceField.inl | 10 +- .../sofa/component/mechanicalload/config.h.in | 6 +- .../elastic/TriangularFEMForceFieldOptim.inl | 2 - .../CompressedRowSparseMatrixGeneric.h | 2 +- .../sofa/simulation/DefaultAnimationLoop.cpp | 1 + .../DefaultCollisionGroupManager_test.cpp | 10 +- .../SofaValidation_test/Monitor_test.cpp | 2 +- .../examples/benchmark_cubes.scn | 144 +++++++++--------- .../src/MultiThreading/TaskSchedulerUser.cpp | 2 +- ...allelCompressedRowSparseMatrixMechanical.h | 8 +- .../examples/SimpleBox-Method2.scn | 2 +- .../image/image_test/ImageEngine_test.cpp | 14 +- .../SofaPhysicsAPI/SofaPhysicsBindings.cpp | 2 +- .../tutorials/chainHybrid/chainHybrid.cpp | 3 +- .../compositeObject/compositeObject.cpp | 6 +- .../tutorials/mixedPendulum/mixedPendulum.cpp | 6 +- .../tutorials/oneParticle/oneParticle.cpp | 3 +- 22 files changed, 163 insertions(+), 156 deletions(-) diff --git a/Sofa/Component/Constraint/Projective/tests/FixedPlaneConstraint_test.cpp b/Sofa/Component/Constraint/Projective/tests/FixedPlaneConstraint_test.cpp index 5ed1c9ca855..b040bfced84 100644 --- a/Sofa/Component/Constraint/Projective/tests/FixedPlaneConstraint_test.cpp +++ b/Sofa/Component/Constraint/Projective/tests/FixedPlaneConstraint_test.cpp @@ -67,7 +67,7 @@ struct FixedPlaneConstraint_test : public BaseSimulationTest /// Scene initialization sofa::simulation::Simulation* simulation; - sofa::simulation::setSimulation(simulation = new sofa::simulation::graph::DAGSimulation()); + simulation = sofa::simulation::getSimulation(); simulation::Node::SPtr root = simulation->createNewGraph("root"); root->setGravity( type::Vec3(0,0,0) ); diff --git a/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.inl b/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.inl index e4e87e3b355..39297dbb067 100644 --- a/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.inl +++ b/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.inl @@ -45,14 +45,14 @@ using namespace sofa::component::linearsystem; template MatrixLinearSolver::MatrixLinearSolver() : Inherit() + , d_parallelInverseProduct(initData(&d_parallelInverseProduct, false, + "parallelInverseProduct", "Parallelize the computation of the product J*M^{-1}*J^T " + "where M is the matrix of the linear system and J is any " + "matrix with compatible dimensions")) , invertData() , linearSystem() , currentMFactor(), currentBFactor(), currentKFactor() , l_linearSystem(initLink("linearSystem", "The linear system to solve")) - , d_parallelInverseProduct(initData(&d_parallelInverseProduct, false, - "parallelInverseProduct", "Parallelize the computation of the product J*M^{-1}*J^T " - "where M is the matrix of the linear system and J is any " - "matrix with compatible dimensions")) { this->addUpdateCallback("parallelInverseProduct", {&d_parallelInverseProduct}, [this](const core::DataTracker& tracker) -> sofa::core::objectmodel::ComponentState diff --git a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/ConstantLocalMatrix.h b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/ConstantLocalMatrix.h index cdb9a88978c..4442e1bd00d 100644 --- a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/ConstantLocalMatrix.h +++ b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/ConstantLocalMatrix.h @@ -52,6 +52,8 @@ class ConstantLocalMatrix : public virtual AssemblingMatrixAccumulator template void ConstantLocalMatrix::add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, float value) { + SOFA_UNUSED(row); + SOFA_UNUSED(col); static_cast(this->m_globalMatrix)->colsValue[insertionOrderList[currentId++]] += this->m_cachedFactor * value; } @@ -59,6 +61,8 @@ void ConstantLocalMatrix::add(const core::matrixaccumulator::no_chec template void ConstantLocalMatrix::add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, double value) { + SOFA_UNUSED(row); + SOFA_UNUSED(col); static_cast(this->m_globalMatrix)->colsValue[insertionOrderList[currentId++]] += this->m_cachedFactor * value; } diff --git a/Sofa/Component/LinearSystem/tests/MatrixLinearSystem_test.cpp b/Sofa/Component/LinearSystem/tests/MatrixLinearSystem_test.cpp index a1e0825af21..bf951a8e182 100644 --- a/Sofa/Component/LinearSystem/tests/MatrixLinearSystem_test.cpp +++ b/Sofa/Component/LinearSystem/tests/MatrixLinearSystem_test.cpp @@ -250,9 +250,23 @@ template dfdx(10, 20) += 0.; } - void addForce(const sofa::core::MechanicalParams*, typename Inherit1::DataVecDeriv& f, const typename Inherit1::DataVecCoord& x, const typename Inherit1::DataVecDeriv& v) override {} - void addDForce(const sofa::core::MechanicalParams* mparams, typename Inherit1::DataVecDeriv& df, const typename Inherit1::DataVecDeriv& dx ) override {} - SReal getPotentialEnergy(const sofa::core::MechanicalParams*, const typename Inherit1::DataVecCoord& x) const override { return 0._sreal; } + void addForce(const sofa::core::MechanicalParams*, typename Inherit1::DataVecDeriv& f, const typename Inherit1::DataVecCoord& x, const typename Inherit1::DataVecDeriv& v) override + { + SOFA_UNUSED(f); + SOFA_UNUSED(x); + SOFA_UNUSED(v); + } + void addDForce(const sofa::core::MechanicalParams* mparams, typename Inherit1::DataVecDeriv& df, const typename Inherit1::DataVecDeriv& dx ) override + { + SOFA_UNUSED(mparams); + SOFA_UNUSED(df); + SOFA_UNUSED(dx); + } + SReal getPotentialEnergy(const sofa::core::MechanicalParams*, const typename Inherit1::DataVecCoord& x) const override + { + SOFA_UNUSED(x); + return 0._sreal; + } }; /// Empty matrix class with the interface of a BaseMatrix @@ -273,26 +287,42 @@ class EmptyMatrix : public sofa::linearalgebra::BaseMatrix } SReal element(Index i, Index j) const override { + SOFA_UNUSED(i); + SOFA_UNUSED(j); return {}; } void resize(Index nbRow, Index nbCol) override { + SOFA_UNUSED(nbRow); + SOFA_UNUSED(nbCol); } void clear() override { } void set(Index i, Index j, double v) override { + SOFA_UNUSED(i); + SOFA_UNUSED(j); + SOFA_UNUSED(v); } void add(Index row, Index col, double v) override { + SOFA_UNUSED(row); + SOFA_UNUSED(col); + SOFA_UNUSED(v); //add method is empty to prevent crashes in tests } void add(Index row, Index col, const sofa::type::Mat3x3d& _M) override { + SOFA_UNUSED(row); + SOFA_UNUSED(col); + SOFA_UNUSED(_M); } void add(Index row, Index col, const sofa::type::Mat3x3f& _M) override { + SOFA_UNUSED(row); + SOFA_UNUSED(col); + SOFA_UNUSED(_M); } static const char* Name() { return "EmptyMatrix"; } }; diff --git a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.h b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.h index 7bf769b9c3a..4cc2bfbae6d 100644 --- a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.h +++ b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.h @@ -82,41 +82,27 @@ class EllipsoidForceField : public core::behavior::ForceField }; - union - { - SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DEPRECATED() Data > contacts; ///< Contacts - Data > d_contacts; ///< Contacts - }; + Data > d_contacts; ///< Vector of contacts + SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DISABLED() DeprecatedAndRemoved contacts; ///< Contacts EllipsoidForceFieldInternalData data; public: - union - { - Data d_center; ///< ellipsoid center - SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DEPRECATED() Data center; ///< ellipsoid center - }; - union - { - Data d_vradius; ///< ellipsoid radius - SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DEPRECATED() Data vradius; ///< ellipsoid radius - }; - union - { - Data d_stiffness; ///< force stiffness (positive to repulse outward, negative inward) - SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DEPRECATED() Data stiffness; ///< force stiffness (positive to repulse outward, negative inward) - }; - union - { - Data d_damping; ///< force damping - SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DEPRECATED() Data damping; ///< force damping - }; - union - { - Data d_color; ///< ellipsoid color. (default=0,0.5,1.0,1.0) - SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DEPRECATED() Data color; ///< ellipsoid color. (default=0,0.5,1.0,1.0) - }; + Data d_center; ///< ellipsoid center + SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DISABLED() DeprecatedAndRemoved center; ///< ellipsoid center + + Data d_vradius; ///< ellipsoid radius + SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DISABLED() DeprecatedAndRemoved vradius; ///< ellipsoid radius + + Data d_stiffness; ///< force stiffness (positive to repulse outward, negative inward) + SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DISABLED() DeprecatedAndRemoved stiffness; ///< force stiffness (positive to repulse outward, negative inward) + + Data d_damping; ///< force damping + SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DISABLED() DeprecatedAndRemoved damping; ///< force damping + + Data d_color; ///< ellipsoid color. (default=0,0.5,1.0,1.0) + SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DISABLED() DeprecatedAndRemoved color; ///< ellipsoid color. (default=0,0.5,1.0,1.0) protected: EllipsoidForceField(); diff --git a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.inl b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.inl index 4459517d8eb..49c6a8c2527 100644 --- a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.inl +++ b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.inl @@ -57,7 +57,7 @@ namespace sofa::component::mechanicalload template EllipsoidForceField::EllipsoidForceField() - : d_contacts(initData(&d_contacts,"contacts", "Contacts")) + : d_contacts(initData(&d_contacts,"contacts", "Vector of contacts")) , d_center(initData(&d_center, "center", "ellipsoid center")) , d_vradius(initData(&d_vradius, "vradius", "ellipsoid radius")) , d_stiffness(initData(&d_stiffness, (Real)500, "stiffness", "force stiffness (positive to repulse outward, negative inward)")) @@ -69,12 +69,6 @@ EllipsoidForceField::EllipsoidForceField() template EllipsoidForceField::~EllipsoidForceField() { - d_contacts.~Data(); - d_center.~Data(); - d_vradius.~Data(); - d_stiffness.~Data(); - d_damping.~Data(); - d_color.~Data(); } template @@ -115,7 +109,7 @@ void EllipsoidForceField::addForce(const sofa::core::MechanicalParams { Coord dp = p1[i] - center; Real norm2 = 0; - for (int j=0; j void TriangularFEMForceFieldOptim::computePrincipalStress() { const VecElement& triangles = m_topology->getTriangles(); - - sofa::helper::ReadAccessor< core::objectmodel::Data< VecTriangleState > > triStates = d_triangleState; sofa::helper::WriteAccessor< core::objectmodel::Data< VecTriangleInfo > > triInfos = d_triangleInfo; Real minStress = 0; diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixGeneric.h b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixGeneric.h index 4647c6f9a1a..31fd33baf5c 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixGeneric.h +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixGeneric.h @@ -263,7 +263,7 @@ public : /// Returns the range of indices from the column indices corresponding to the id-th row Range getRowRange(Index id) const { - if (id + 1 >= rowBegin.size()) + if (id + 1 >= static_cast(rowBegin.size())) { return Range(s_invalidIndex, s_invalidIndex); } diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.cpp index 0bf53d191c8..5d54680785b 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.cpp @@ -71,6 +71,7 @@ DefaultAnimationLoop::DefaultAnimationLoop(simulation::Node* _m_node) : Inherit() , d_parallelODESolving(initData(&d_parallelODESolving, false, "parallelODESolving", "If true, solves all the ODEs in parallel")) { + SOFA_UNUSED(_m_node); this->addUpdateCallback("parallelODESolving", {&d_parallelODESolving}, [this](const core::DataTracker& tracker) -> sofa::core::objectmodel::ComponentState { diff --git a/applications/collections/deprecated/modules/SofaMiscCollision/SofaMiscCollision_test/DefaultCollisionGroupManager_test.cpp b/applications/collections/deprecated/modules/SofaMiscCollision/SofaMiscCollision_test/DefaultCollisionGroupManager_test.cpp index 8c5514b3658..8df65f4ce69 100644 --- a/applications/collections/deprecated/modules/SofaMiscCollision/SofaMiscCollision_test/DefaultCollisionGroupManager_test.cpp +++ b/applications/collections/deprecated/modules/SofaMiscCollision/SofaMiscCollision_test/DefaultCollisionGroupManager_test.cpp @@ -58,15 +58,15 @@ void DefaultCollisionGroupManager_test::onSetUp() + "/DefaultCollisionGroupManager_singleObject_test.scn"; // Init simulation - sofa::simulation::setSimulation(simulation = new sofa::simulation::graph::DAGSimulation()); - root = sofa::simulation::getSimulation()->load(sceneFilename.c_str()); + simulation = sofa::simulation::getSimulation(); + root = sofa::simulation::node::load(sceneFilename.c_str()); } void DefaultCollisionGroupManager_test::onTearDown() { if (root != nullptr) { - sofa::simulation::getSimulation()->unload(root); + sofa::simulation::node::unload(root); } } @@ -75,7 +75,7 @@ bool DefaultCollisionGroupManager_test::combineSingleObject() EXPECT_TRUE(root != nullptr); EXPECT_TRUE(sofa::simulation::getSimulation() != nullptr); - sofa::simulation::getSimulation()->init(root.get()); + sofa::simulation::node::initRoot(root.get()); // run 200 time steps // objectives: @@ -83,7 +83,7 @@ bool DefaultCollisionGroupManager_test::combineSingleObject() // 2) Collision prevents the cube to fall through the floor for (unsigned int i = 0; i < 200; ++i) { - sofa::simulation::getSimulation()->animate(root.get(), 0.01); + sofa::simulation::node::animate(root.get(), 0.01); } auto* baseObject = root->getTreeNode("Cube1")->getObject("mechanicalObject"); diff --git a/applications/collections/deprecated/modules/SofaValidation/SofaValidation_test/Monitor_test.cpp b/applications/collections/deprecated/modules/SofaValidation/SofaValidation_test/Monitor_test.cpp index 4f71d377d38..5c6024decd5 100644 --- a/applications/collections/deprecated/modules/SofaValidation/SofaValidation_test/Monitor_test.cpp +++ b/applications/collections/deprecated/modules/SofaValidation/SofaValidation_test/Monitor_test.cpp @@ -147,7 +147,7 @@ struct Monitor_test : public BaseSimulationTest // make a few steps before checkinf if values are correctly updated in // Monitor for (int i = 0; i < 10; ++i) - simulation::getSimulation()->animate(root.get(), 1.0); + simulation::node::animate(root.get(), 1.0); monitor->testModif(mo.get()); diff --git a/applications/plugins/CollisionOBBCapsule/examples/benchmark_cubes.scn b/applications/plugins/CollisionOBBCapsule/examples/benchmark_cubes.scn index e3e29fe85d1..bf34abd651d 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/benchmark_cubes.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/benchmark_cubes.scn @@ -43,7 +43,7 @@ - + @@ -51,7 +51,7 @@ - + @@ -59,7 +59,7 @@ - + @@ -67,7 +67,7 @@ - + @@ -75,7 +75,7 @@ - + @@ -83,7 +83,7 @@ - + @@ -91,7 +91,7 @@ - + @@ -99,7 +99,7 @@ - + @@ -107,7 +107,7 @@ - + @@ -115,7 +115,7 @@ - + @@ -123,7 +123,7 @@ - + @@ -131,7 +131,7 @@ - + @@ -139,7 +139,7 @@ - + @@ -147,7 +147,7 @@ - + @@ -155,7 +155,7 @@ - + @@ -163,7 +163,7 @@ - + @@ -171,7 +171,7 @@ - + @@ -179,7 +179,7 @@ - + @@ -187,7 +187,7 @@ - + @@ -195,7 +195,7 @@ - + @@ -203,7 +203,7 @@ - + @@ -211,7 +211,7 @@ - + @@ -219,7 +219,7 @@ - + @@ -227,7 +227,7 @@ - + @@ -235,7 +235,7 @@ - + @@ -243,7 +243,7 @@ - + @@ -251,7 +251,7 @@ - + @@ -259,7 +259,7 @@ - + @@ -267,7 +267,7 @@ - + @@ -275,7 +275,7 @@ - + @@ -283,7 +283,7 @@ - + @@ -291,7 +291,7 @@ - + @@ -299,7 +299,7 @@ - + @@ -307,7 +307,7 @@ - + @@ -315,7 +315,7 @@ - + @@ -323,7 +323,7 @@ - + @@ -331,7 +331,7 @@ - + @@ -339,7 +339,7 @@ - + @@ -347,7 +347,7 @@ - + @@ -355,7 +355,7 @@ - + @@ -363,7 +363,7 @@ - + @@ -371,7 +371,7 @@ - + @@ -379,7 +379,7 @@ - + @@ -387,7 +387,7 @@ - + @@ -395,7 +395,7 @@ - + @@ -403,7 +403,7 @@ - + @@ -411,7 +411,7 @@ - + @@ -419,7 +419,7 @@ - + @@ -427,7 +427,7 @@ - + @@ -435,7 +435,7 @@ - + @@ -443,7 +443,7 @@ - + @@ -451,7 +451,7 @@ - + @@ -459,7 +459,7 @@ - + @@ -467,7 +467,7 @@ - + @@ -475,7 +475,7 @@ - + @@ -483,7 +483,7 @@ - + @@ -491,7 +491,7 @@ - + @@ -499,7 +499,7 @@ - + @@ -507,7 +507,7 @@ - + @@ -515,7 +515,7 @@ - + @@ -523,7 +523,7 @@ - + @@ -531,7 +531,7 @@ - + @@ -539,7 +539,7 @@ - + @@ -547,7 +547,7 @@ - + @@ -555,7 +555,7 @@ - + @@ -563,7 +563,7 @@ - + @@ -571,7 +571,7 @@ - + @@ -579,7 +579,7 @@ - + @@ -587,7 +587,7 @@ - + @@ -595,7 +595,7 @@ - + @@ -603,7 +603,7 @@ - + @@ -611,7 +611,7 @@ - + diff --git a/applications/plugins/MultiThreading/src/MultiThreading/TaskSchedulerUser.cpp b/applications/plugins/MultiThreading/src/MultiThreading/TaskSchedulerUser.cpp index c005b5ee945..a60da64108f 100644 --- a/applications/plugins/MultiThreading/src/MultiThreading/TaskSchedulerUser.cpp +++ b/applications/plugins/MultiThreading/src/MultiThreading/TaskSchedulerUser.cpp @@ -65,7 +65,7 @@ void TaskSchedulerUser::reinitTaskScheduler() if (m_taskScheduler) { const auto nbThreads = d_nbThreads.getValue(); - if ( nbThreads != m_taskScheduler->getThreadCount() ) + if ( nbThreads != static_cast(m_taskScheduler->getThreadCount()) ) { m_taskScheduler->init(nbThreads); sofa::simulation::initThreadLocalData(); diff --git a/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCompressedRowSparseMatrixMechanical.h b/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCompressedRowSparseMatrixMechanical.h index 2f12e06811d..c246aae0a7c 100644 --- a/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCompressedRowSparseMatrixMechanical.h +++ b/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCompressedRowSparseMatrixMechanical.h @@ -125,7 +125,7 @@ class ParallelCompressedRowSparseMatrixMechanical : public sofa::linearalgebra:: // transfer a chunk of large vector to a local block-sized vector sofa::type::Vec v; //Index jN = colsIndex[xj] * NC; // scalar column index - for (Index bj = 0; bj < NC; ++bj) + for (sofa::Index bj = 0; bj < NC; ++bj) { v[bj] = vget(vec, m_crs.colsIndex[xj], NC, bj); } @@ -133,9 +133,9 @@ class ParallelCompressedRowSparseMatrixMechanical : public sofa::linearalgebra:: // multiply the block with the local vector const typename Base::Block& b = m_crs.colsValue[xj]; // non-null block has block-indices (rowIndex[xi],colsIndex[xj]) and value colsValue[xj] - for (Index bi = 0; bi < NL; ++bi) + for (sofa::Index bi = 0; bi < NL; ++bi) { - for (Index bj = 0; bj < NC; ++bj) + for (sofa::Index bj = 0; bj < NC; ++bj) { r[bi] += Base::traits::v(b, bi, bj) * v[bj]; } @@ -144,7 +144,7 @@ class ParallelCompressedRowSparseMatrixMechanical : public sofa::linearalgebra:: // transfer the local result to the large result vector //Index iN = rowIndex[xi] * NL; // scalar row index - for (Index bi = 0; bi < NL; ++bi) + for (sofa::Index bi = 0; bi < NL; ++bi) { vset(res, m_crs.rowIndex[xi], NL, bi, r[bi]); } diff --git a/applications/plugins/SensableEmulation/examples/SimpleBox-Method2.scn b/applications/plugins/SensableEmulation/examples/SimpleBox-Method2.scn index f1ad8c485b3..becbb2480b0 100644 --- a/applications/plugins/SensableEmulation/examples/SimpleBox-Method2.scn +++ b/applications/plugins/SensableEmulation/examples/SimpleBox-Method2.scn @@ -53,7 +53,7 @@ - + diff --git a/applications/plugins/image/image_test/ImageEngine_test.cpp b/applications/plugins/image/image_test/ImageEngine_test.cpp index 9549af5a122..50ad94855fa 100644 --- a/applications/plugins/image/image_test/ImageEngine_test.cpp +++ b/applications/plugins/image/image_test/ImageEngine_test.cpp @@ -54,7 +54,7 @@ struct ImageEngine_test : public sofa::testing::BaseTest void TearDown() { if (root!=NULL) - sofa::simulation::getSimulation()->unload(root); + sofa::simulation::node::unload(root); } // Test link @@ -130,7 +130,7 @@ struct ImageEngine_test : public sofa::testing::BaseTest TestImageEngine::SPtr imageEngine; // Create a scene - sofa::simulation::setSimulation(simulation = new sofa::simulation::graph::DAGSimulation()); + simulation = sofa::simulation::getSimulation(); // Root node root = simulation->createNewGraph("root"); @@ -156,12 +156,12 @@ struct ImageEngine_test : public sofa::testing::BaseTest sofa::modeling::setDataLink(&imageEngine->outputImage,&imageEngine2->inputImage); // Init simulation - sofa::simulation::getSimulation()->init(root.get()); + sofa::simulation::node::initRoot(root.get()); // do several steps of animation for(int l=0;l<2;++l) { - sofa::simulation::getSimulation()->animate(root.get(),0.5); + sofa::simulation::node::animate(root.get(),0.5); } // Check if pointers of images that should be shared are equal @@ -190,7 +190,7 @@ struct ImageEngine_test : public sofa::testing::BaseTest ImageViewer::SPtr imageViewer; // Create a scene - sofa::simulation::setSimulation(simulation = new sofa::simulation::graph::DAGSimulation()); + simulation = sofa::simulation::getSimulation(); // Root node root = simulation->createNewGraph("root"); @@ -221,12 +221,12 @@ struct ImageEngine_test : public sofa::testing::BaseTest //sofa::modeling::setDataLink(&imageContainer->image,&imageViewer->image); // Init simulation - sofa::simulation::getSimulation()->init(root.get()); + sofa::simulation::node::initRoot(root.get()); // do several steps of animation for(int l=0;l<2;++l) { - sofa::simulation::getSimulation()->animate(root.get(),0.5); + sofa::simulation::node::animate(root.get(),0.5); } diff --git a/applications/projects/SofaPhysicsAPI/src/SofaPhysicsAPI/SofaPhysicsBindings.cpp b/applications/projects/SofaPhysicsAPI/src/SofaPhysicsAPI/SofaPhysicsBindings.cpp index 0e2ae2a3573..c3e83065873 100644 --- a/applications/projects/SofaPhysicsAPI/src/SofaPhysicsAPI/SofaPhysicsBindings.cpp +++ b/applications/projects/SofaPhysicsAPI/src/SofaPhysicsAPI/SofaPhysicsBindings.cpp @@ -354,7 +354,7 @@ int sofaVisualModel_getNbEdges(void* api_ptr, const char* name) } -int sofaVisualModel_getEdges(void* api_ptr, const char* name, int* buffer) +int sofaVisualModel_getEdges(void* /*api_ptr*/, const char* /*name*/, int* /*buffer*/) { //TODO diff --git a/applications/tutorials/chainHybrid/chainHybrid.cpp b/applications/tutorials/chainHybrid/chainHybrid.cpp index fd5245e43ab..54351897099 100644 --- a/applications/tutorials/chainHybrid/chainHybrid.cpp +++ b/applications/tutorials/chainHybrid/chainHybrid.cpp @@ -244,7 +244,6 @@ int main(int argc, char** argv) sofa::gui::common::GUIManager::Init(argv[0]); auto simulation = sofa::simpleapi::createSimulation(); - sofa::simulation::setSimulation( simulation.get() ); // The graph root node Node::SPtr root = sofa::modeling::createRootWithCollisionPipeline(); @@ -255,7 +254,7 @@ int main(int argc, char** argv) root->setAnimate(false); - sofa::simulation::getSimulation()->init(root.get()); + sofa::simulation::node::initRoot(root.get()); //======================================= diff --git a/applications/tutorials/compositeObject/compositeObject.cpp b/applications/tutorials/compositeObject/compositeObject.cpp index ede322d8a9a..cd9a2cefe61 100644 --- a/applications/tutorials/compositeObject/compositeObject.cpp +++ b/applications/tutorials/compositeObject/compositeObject.cpp @@ -256,13 +256,11 @@ int main(int argc, char** argv) if (int err=sofa::gui::common::GUIManager::createGUI(NULL)) return err; sofa::gui::common::GUIManager::SetDimension(800,600); - sofa::simulation::setSimulation(new sofa::simulation::graph::DAGSimulation()); - //================================================= sofa::simulation::Node::SPtr groot = createGridScene(Vec3(0,0,0), Vec3(5,1,1), 6,2,2, 1.0 ); //================================================= - sofa::simulation::getSimulation()->init(groot.get()); + sofa::simulation::node::initRoot(groot.get()); sofa::gui::common::GUIManager::SetScene(groot); groot->setAnimate(true); @@ -271,7 +269,7 @@ int main(int argc, char** argv) if (int err = sofa::gui::common::GUIManager::MainLoop(groot)) return err; - sofa::simulation::getSimulation()->unload(groot); + sofa::simulation::node::unload(groot); sofa::gui::common::GUIManager::closeGUI(); sofa::simulation::graph::cleanup(); diff --git a/applications/tutorials/mixedPendulum/mixedPendulum.cpp b/applications/tutorials/mixedPendulum/mixedPendulum.cpp index f7084a5ed35..41e2a186ac0 100644 --- a/applications/tutorials/mixedPendulum/mixedPendulum.cpp +++ b/applications/tutorials/mixedPendulum/mixedPendulum.cpp @@ -66,7 +66,6 @@ int main(int argc, char** argv) double splength = 1.; //-------------------- The graph root node - sofa::simulation::setSimulation(new sofa::simulation::graph::DAGSimulation()); auto groot = sofa::simulation::getSimulation()->createNewGraph("root"); groot->setGravity({ 0,-10,0 }); @@ -199,7 +198,7 @@ int main(int argc, char** argv) sofa::gui::common::GUIManager::SetDimension(800, 600); //=========================== Init the scene - sofa::simulation::getSimulation()->init(groot.get()); + sofa::simulation::node::initRoot(groot.get()); sofa::gui::common::GUIManager::SetScene(groot); groot->setAnimate(true); @@ -208,9 +207,8 @@ int main(int argc, char** argv) sofa::gui::common::GUIManager::MainLoop(groot); if (groot != NULL) - sofa::simulation::getSimulation()->unload(groot); + sofa::simulation::node::unload(groot); sofa::simulation::graph::cleanup(); return 0; } - diff --git a/applications/tutorials/oneParticle/oneParticle.cpp b/applications/tutorials/oneParticle/oneParticle.cpp index b8f405609b4..f0697745daa 100644 --- a/applications/tutorials/oneParticle/oneParticle.cpp +++ b/applications/tutorials/oneParticle/oneParticle.cpp @@ -64,7 +64,6 @@ int main(int argc, char** argv) sofa::gui::common::GUIManager::Init(argv[0]); // The graph root node - sofa::simulation::setSimulation(new sofa::simulation::graph::DAGSimulation()); sofa::simulation::Node::SPtr groot = sofa::simulation::getSimulation()->createNewGraph("root"); groot->setGravity({ 0,-10,0 }); @@ -113,7 +112,7 @@ int main(int argc, char** argv) flags.setShowCollisionModels(true); style->displayFlags.endEdit(); - sofa::simulation::graph::getSimulation()->init(groot.get()); + sofa::simulation::node::initRoot(groot.get()); groot->setAnimate(false); //====================================== From 3ae2d8794bd5ba52f2969f6f30523dde6703fc1a Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Mon, 4 Dec 2023 02:28:56 +0100 Subject: [PATCH 03/45] [FEM.Elastic] Reference instead of a copy in TriangularFEMForceField (#4332) * remove collision pipeline * [FEM.Elastic] Reference instead of a copy in TriangularFEMForceField As it appears in the initialization, it won't affect the performances during the simulation * Missing required plugins --- .../fem/elastic/TriangularFEMForceField.inl | 2 +- .../FEM/TriangularFEMForceField.scn | 34 ++++++++----------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularFEMForceField.inl b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularFEMForceField.inl index 1c4d719f71b..f0a7b3218da 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularFEMForceField.inl +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularFEMForceField.inl @@ -215,7 +215,7 @@ void TriangularFEMForceField::initLarge(int i, Index& a, Index& b, In } else { - VecCoord initialPoints = (this->mstate->read(core::ConstVecCoordId::restPosition())->getValue()); + const VecCoord& initialPoints = (this->mstate->read(core::ConstVecCoordId::restPosition())->getValue()); tinfo->rotation = tinfo->initialTransformation; if (a >= (initialPoints).size() || b >= (initialPoints).size() || c >= (initialPoints).size()) { diff --git a/examples/Component/SolidMechanics/FEM/TriangularFEMForceField.scn b/examples/Component/SolidMechanics/FEM/TriangularFEMForceField.scn index 5b28fade3ca..93562748dea 100644 --- a/examples/Component/SolidMechanics/FEM/TriangularFEMForceField.scn +++ b/examples/Component/SolidMechanics/FEM/TriangularFEMForceField.scn @@ -1,25 +1,21 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - From 07c4df5ee03bc8a03ef22bf78878c584fdeda012 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Mon, 4 Dec 2023 05:29:01 +0100 Subject: [PATCH 04/45] [SolidMechanics.Springs] Cleaning of QuadularBendingSprings (#4304) * Massive cleaning * Implement buildStiffnessMatrix * final cleaning --- .../spring/QuadularBendingSprings.h | 47 +- .../spring/QuadularBendingSprings.inl | 436 +++++++----------- .../Spring/QuadularBendingSprings.scn | 69 ++- 3 files changed, 220 insertions(+), 332 deletions(-) diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.h index 80485ee7f5c..f8709ac2f5c 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.h @@ -75,25 +75,31 @@ class QuadularBendingSprings : public core::behavior::ForceField class EdgeInformation { public: - Mat DfDx; /// the edge stiffness matrix - int m1, m2; /// the two extremities of the first spring: masses m1 and m2 - int m3, m4; /// the two extremities of the second spring: masses m3 and m4 + struct Spring + { + sofa::topology::Edge edge; + Real restLength; + Mat DfDx; /// the edge stiffness matrix + }; - SReal ks; /// spring stiffness (initialized to the default value) - SReal kd; /// damping factor (initialized to the default value) + sofa::type::fixed_array springs; - SReal restlength1; /// rest length of the first spring - SReal restlength2; /// rest length of the second spring + SReal ks {}; /// spring stiffness + SReal kd {}; /// damping factor bool is_activated; bool is_initialized; - EdgeInformation(int m1=0, int m2=0, int m3=0, int m4=0, SReal restlength1=0.0, SReal restlength2=0.0, bool is_activated=false, bool is_initialized=false) - : m1(m1), m2(m2), m3(m3), m4(m4), restlength1(restlength1), restlength2(restlength2), is_activated(is_activated), is_initialized(is_initialized) - { - } + EdgeInformation(int m1 = 0, int m2 = 0, int m3 = 0, int m4 = 0, + SReal restlength1 = 0_sreal, SReal restlength2 = 0_sreal, + const bool is_activated = false, const bool is_initialized = false) + : springs{ + Spring{ {m1, m2}, restlength1}, + Spring{ {m3, m4}, restlength2} + }, is_activated(is_activated), is_initialized(is_initialized) + { } /// Output stream inline friend std::ostream& operator<< ( std::ostream& os, const EdgeInformation& /*ei*/ ) @@ -108,14 +114,13 @@ class QuadularBendingSprings : public core::behavior::ForceField } }; - - public: /// Searches quad topology and creates the bending springs void init() override; void addForce(const core::MechanicalParams* mparams, DataVecDeriv& d_f, const DataVecCoord& d_x, const DataVecDeriv& d_v) override; void addDForce(const core::MechanicalParams* mparams, DataVecDeriv& d_df, const DataVecDeriv& d_dx) override; + void buildStiffnessMatrix(core::behavior::StiffnessMatrix* matrix) override; void buildDampingMatrix(core::behavior::DampingMatrix* /*matrix*/) final; SReal getPotentialEnergy(const core::MechanicalParams* /* mparams */, const DataVecCoord& /* d_x */) const override; @@ -132,10 +137,7 @@ class QuadularBendingSprings : public core::behavior::ForceField f_kd.setValue((SReal)kd); } - // -- VisualModel interface void draw(const core::visual::VisualParams* vparams) override; - void initTextures() { } - void update() { } sofa::core::topology::EdgeData > &getEdgeInfo() {return edgeInfo;} @@ -178,6 +180,19 @@ class QuadularBendingSprings : public core::behavior::ForceField protected: sofa::core::topology::EdgeData > edgeInfo; ///< Internal edge data + struct ForceOutput + { + Deriv force; + Real forceIntensity; + Real inverseLength; + }; + + ForceOutput computeForce(const VecDeriv& v, const EdgeInformation& einfo, const typename EdgeInformation::Spring& spring, Coord direction, Real distance); + Mat computeLocalJacobian(EdgeInformation& einfo, const Coord& direction, const ForceOutput& force); + void computeSpringForce(VecDeriv& f, const VecCoord& x, const VecDeriv& v, + EdgeInformation& einfo, + typename EdgeInformation::Spring& spring); + /// Pointer to the current topology sofa::core::topology::BaseMeshTopology* m_topology; diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.inl b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.inl index 3c352c1b6a8..3f4674fa59b 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.inl +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.inl @@ -40,14 +40,10 @@ template< class DataTypes> void QuadularBendingSprings::applyEdgeCreation(Index /*edgeIndex*/, EdgeInformation &ei, const core::topology::Edge &, const sofa::type::vector &, const sofa::type::vector &) { - unsigned int u,v; /// set to zero the edge stiffness matrix - for (u=0; u::applyQuadCreation(const sofa::type::vect EdgeInformation &ei = edgeData[te2[j]]; // ff->edgeInfo if(!(ei.is_initialized)) { - unsigned int edgeIndex = te2[j]; ei.is_activated=true; /// set to zero the edge stiffness matrix - for (u=0; um_topology->getQuadsAroundEdge(edgeIndex); @@ -105,14 +97,11 @@ void QuadularBendingSprings::applyQuadCreation(const sofa::type::vect if(shell[0] == quadAdded[i]) { - te1 = this->m_topology->getEdgesInQuad(shell[1]); t1 = this->m_topology->getQuad(shell[1]); - } else // shell[1] == quadAdded[i] { - te1 = this->m_topology->getEdgesInQuad(shell[0]); t1 = this->m_topology->getQuad(shell[0]); } @@ -120,32 +109,27 @@ void QuadularBendingSprings::applyQuadCreation(const sofa::type::vect const int i1 = this->m_topology->getEdgeIndexInQuad(te1, edgeIndex); //edgeIndex //te1[j] const int i2 = this->m_topology->getEdgeIndexInQuad(te2, edgeIndex); // edgeIndex //te2[j] - ei.m1 = t1[i1]; // i1 - ei.m2 = t2[(i2+3)%4]; // i2 + ei.springs[0].edge[0] = t1[i1]; // i1 + ei.springs[0].edge[1] = t2[(i2+3)%4]; // i2 - ei.m3 = t1[(i1+3)%4]; // (i1+3)%4 - ei.m4 = t2[i2]; // (i2+3)%4 + ei.springs[1].edge[0] = t1[(i1+3)%4]; // (i1+3)%4 + ei.springs[1].edge[1] = t2[i2]; // (i2+3)%4 //QuadularBendingSprings *fftest= (QuadularBendingSprings *)param; ei.ks=m_ks; //(fftest->ks).getValue(); ei.kd=m_kd; //(fftest->kd).getValue(); - Coord u1 = (restPosition)[ei.m1] - (restPosition)[ei.m2]; - Real d1 = u1.norm(); - ei.restlength1=(SReal) d1; - - Coord u2 = (restPosition)[ei.m3] - (restPosition)[ei.m4]; - Real d2 = u2.norm(); - ei.restlength2=(SReal) d2; + for (auto& s : ei.springs) + { + const Coord diff = restPosition[s.edge[0]] - restPosition[s.edge[1]]; + s.restLength = diff.norm(); + } ei.is_activated=true; - } else { - ei.is_activated=false; - } ei.is_initialized = true; @@ -225,23 +209,21 @@ void QuadularBendingSprings::applyQuadDestruction(const sofa::type::v const int i1 = this->m_topology->getEdgeIndexInQuad(te1, edgeIndex); const int i2 = this->m_topology->getEdgeIndexInQuad(te2, edgeIndex); - ei.m1 = t1[i1]; - ei.m2 = t2[(i2+3)%4]; + ei.springs[0].edge[0] = t1[i1]; + ei.springs[0].edge[1] = t2[(i2+3)%4]; - ei.m3 = t1[(i1+3)%4]; - ei.m4 = t2[i2]; + ei.springs[1].edge[0] = t1[(i1+3)%4]; + ei.springs[1].edge[1] = t2[i2]; //QuadularBendingSprings *fftest= (QuadularBendingSprings *)param; ei.ks=m_ks; //(fftest->ks).getValue(); ei.kd=m_kd; //(fftest->kd).getValue(); - Coord u1 = (restPosition)[ei.m1] - (restPosition)[ei.m2]; - Real d1 = u1.norm(); - ei.restlength1=(SReal) d1; - - Coord u2 = (restPosition)[ei.m3] - (restPosition)[ei.m4]; - Real d2 = u2.norm(); - ei.restlength2=(SReal) d2; + for (auto& s : ei.springs) + { + const Coord u = restPosition[s.edge[0]] - restPosition[s.edge[1]]; + s.restLength = u.norm(); + } ei.is_activated=true; @@ -270,10 +252,7 @@ void QuadularBendingSprings::applyQuadDestruction(const sofa::type::v template< class DataTypes> void QuadularBendingSprings::applyPointDestruction(const sofa::type::vector &tab) { - const bool debug_mode = false; - unsigned int last = this->m_topology->getNbPoints() -1; - unsigned int i,j; helper::WriteOnlyAccessor< Data< type::vector > > edgeInf = edgeInfo; @@ -284,7 +263,7 @@ void QuadularBendingSprings::applyPointDestruction(const sofa::type:: lastIndexVec.push_back(last - i_init); } - for ( i = 0; i < tab.size(); ++i) + for ( unsigned int i = 0; i < tab.size(); ++i) { unsigned int i_next = i; bool is_reached = false; @@ -303,82 +282,30 @@ void QuadularBendingSprings::applyPointDestruction(const sofa::type:: } const auto &shell= this->m_topology->getQuadsAroundVertex(lastIndexVec[i]); - for (j=0; jm_topology->getQuad(shell[j]); const unsigned int vertexIndex = this->m_topology->getVertexIndexInQuad(tj, lastIndexVec[i]); - EdgesInQuad tej = this->m_topology->getEdgesInQuad(shell[j]); + const EdgesInQuad& tej = this->m_topology->getEdgesInQuad(shell[j]); for (unsigned int j_edge=vertexIndex; j_edge%4 !=(vertexIndex+2)%4; ++j_edge) { - unsigned int ind_j = tej[j_edge%4]; - if (edgeInf[ind_j].m1 == (int) last) + for (auto& s : edgeInf[ind_j].springs) { - edgeInf[ind_j].m1=(int) tab[i]; - } - else - { - if (edgeInf[ind_j].m2 == (int) last) - { - edgeInf[ind_j].m2=(int) tab[i]; - } - } - - if (edgeInf[ind_j].m3 == (int) last) - { - edgeInf[ind_j].m3=(int) tab[i]; - } - else - { - if (edgeInf[ind_j].m4 == (int) last) + for (auto& e : s.edge) { - edgeInf[ind_j].m4=(int) tab[i]; - } - } - - } - } - - if(debug_mode) - { - for (unsigned int j_loc=0; j_loc::applyPointDestruction(const sofa::type:: template< class DataTypes> void QuadularBendingSprings::applyPointRenumbering(const sofa::type::vector &tab) { - helper::WriteOnlyAccessor< Data< type::vector > > edgeInf = edgeInfo; - for (unsigned int i = 0; i < this->m_topology->getNbEdges(); ++i) + for (auto& edgeInf : sofa::helper::getWriteOnlyAccessor(edgeInfo)) { - if(edgeInf[i].is_activated) + if (edgeInf.is_activated) { - edgeInf[i].m1 = tab[edgeInf[i].m1]; - edgeInf[i].m2 = tab[edgeInf[i].m2]; - edgeInf[i].m3 = tab[edgeInf[i].m3]; - edgeInf[i].m4 = tab[edgeInf[i].m4]; + for (auto& s : edgeInf.springs) + { + for (auto& e : s.edge) + { + e = tab[e]; + } + } } } } @@ -514,172 +443,148 @@ SReal QuadularBendingSprings::getPotentialEnergy(const core::Mechanic return 0; } +template +auto QuadularBendingSprings::computeForce( + const VecDeriv& v, + const EdgeInformation& einfo, const typename EdgeInformation::Spring& spring, + Coord direction, + Real distance) -> ForceOutput +{ + ForceOutput force; + + force.inverseLength = 1 / distance; + direction *= force.inverseLength; + const Real elongation = distance - spring.restLength; + m_potentialEnergy += elongation * elongation * einfo.ks / 2; + + const Deriv relativeVelocity = v[spring.edge[1]] - v[spring.edge[0]]; + const Real elongationVelocity = sofa::type::dot(direction, relativeVelocity); + force.forceIntensity = einfo.ks * elongation + einfo.kd * elongationVelocity; + force.force = direction * force.forceIntensity; + + return force; +} + +template +auto QuadularBendingSprings::computeLocalJacobian(EdgeInformation& einfo, const Coord& direction, const ForceOutput& force) +-> Mat +{ + const Real tgt = force.forceIntensity * force.inverseLength; + Mat jacobian = (einfo.ks - tgt) * sofa::type::dyad(direction, direction); + for (int j = 0; j < N; ++j) + { + jacobian[j][j] += tgt; + } + return jacobian; +} + +template +void QuadularBendingSprings::computeSpringForce(VecDeriv& f, const VecCoord& x, + const VecDeriv& v, EdgeInformation& einfo, typename EdgeInformation::Spring& spring) +{ + const auto e0 = spring.edge[0]; + const auto e1 = spring.edge[1]; + + const Coord difference = x[e1] - x[e0]; + const Real distance = difference.norm(); + + if (distance > 1.0e-4) + { + const ForceOutput force = computeForce(v, einfo, spring, difference, distance); + + f[e0] += force.force; + f[e1] -= force.force; + + updateMatrix = true; + + spring.DfDx += computeLocalJacobian(einfo, difference / distance, force); + } +} + template void QuadularBendingSprings::addForce(const core::MechanicalParams* /* mparams */, DataVecDeriv& d_f, const DataVecCoord& d_x, const DataVecDeriv& d_v) { - VecDeriv& f = *d_f.beginEdit(); + auto f = sofa::helper::getWriteAccessor(d_f); + const VecCoord& x = d_x.getValue(); const VecDeriv& v = d_v.getValue(); - const size_t nbEdges=m_topology->getNbEdges(); - - EdgeInformation *einfo; - - type::vector& edgeInf = *(edgeInfo.beginEdit()); + auto edgeInf = sofa::helper::getWriteAccessor(edgeInfo); - //const type::vector& m_springs= this->springs.getValue(); - //this->dfdx.resize(nbEdges); //m_springs.size() f.resize(x.size()); m_potentialEnergy = 0; - for(unsigned int i=0; iis_activated) + if (einfo.is_activated) { - //this->addSpringForce(m_potentialEnergy,f,x,v, i, einfo->spring); - - int a1 = einfo->m1; - int b1 = einfo->m2; - int a2 = einfo->m3; - int b2 = einfo->m4; - Coord u1 = x[b1]-x[a1]; - Real d1 = u1.norm(); - Coord u2 = x[b2]-x[a2]; - Real d2 = u2.norm(); - if( d1>1.0e-4 ) - { - Real inverseLength = 1.0f/d1; - u1 *= inverseLength; - Real elongation = (Real)(d1 - einfo->restlength1); - m_potentialEnergy += elongation * elongation * einfo->ks / 2; - - Deriv relativeVelocity = v[b1]-v[a1]; - Real elongationVelocity = dot(u1,relativeVelocity); - Real forceIntensity = (Real)(einfo->ks*elongation+einfo->kd*elongationVelocity); - Deriv force = u1*forceIntensity; - f[a1]+=force; - f[b1]-=force; - - updateMatrix=true; - - Mat& m = einfo->DfDx; //Mat& m = this->dfdx[i]; - Real tgt = forceIntensity * inverseLength; - for( int j=0; jks-tgt) * u1[j] * u1[k]; - } - m[j][j] += tgt; - } - } - else // null length, no force and no stiffness - { - Mat& m = einfo->DfDx; //Mat& m = this->dfdx[i]; - for( int j=0; j1.0e-4 ) - { - Real inverseLength = 1.0f/d2; - u2 *= inverseLength; - Real elongation = (Real)(d2 - einfo->restlength2); - m_potentialEnergy += elongation * elongation * einfo->ks / 2; - - Deriv relativeVelocity = v[b2]-v[a2]; - Real elongationVelocity = dot(u2,relativeVelocity); - Real forceIntensity = (Real)(einfo->ks*elongation+einfo->kd*elongationVelocity); - Deriv force = u2*forceIntensity; - f[a2]+=force; - f[b2]-=force; - - updateMatrix=true; - - Mat& m = einfo->DfDx; //Mat& m = this->dfdx[i]; - Real tgt = forceIntensity * inverseLength; - for( int j=0; jks-tgt) * u2[j] * u2[k]; - } - m[j][j] += tgt; - } - } - else // null length, no force and no stiffness + for (auto& s : einfo.springs) { - Mat& m = einfo->DfDx; //Mat& m = this->dfdx[i]; - for( int j=0; jaddSpringForce(m_potentialEnergy,f,x,v, i, springs[i]); - //} } template void QuadularBendingSprings::addDForce(const core::MechanicalParams* mparams, DataVecDeriv& d_df, const DataVecDeriv& d_dx) { - VecDeriv& df = *d_df.beginEdit(); + auto df = sofa::helper::getWriteAccessor(d_df); const VecDeriv& dx = d_dx.getValue(); Real kFactor = (Real)sofa::core::mechanicalparams::kFactorIncludingRayleighDamping(mparams, this->rayleighStiffness.getValue()); - const size_t nbEdges=m_topology->getNbEdges(); - - const EdgeInformation *einfo; - const type::vector& edgeInf = edgeInfo.getValue(); df.resize(dx.size()); - //const type::vector& springs = this->springs.getValue(); - for(unsigned int i=0; iis_activated) + if (einfo.is_activated) { - //this->addSpringDForce(df,dx, i, einfo->spring); - - const int a1 = einfo->m1; - const int b1 = einfo->m2; - const Coord d1 = dx[b1]-dx[a1]; - const int a2 = einfo->m3; - const int b2 = einfo->m4; - const Coord d2 = dx[b2]-dx[a2]; - const Deriv dforce1 = (einfo->DfDx*d1) * kFactor; - const Deriv dforce2 = (einfo->DfDx*d2) * kFactor; - df[a1]+=dforce1; - df[b1]-=dforce1; - df[a2]+=dforce2; - df[b2]-=dforce2; - - updateMatrix=false; + for (const auto& s : einfo.springs) + { + const auto e0 = s.edge[0]; + const auto e1 = s.edge[1]; + const Coord ddx = dx[e1] - dx[e0]; + const Deriv dforce = s.DfDx * (ddx * kFactor); + + df[e0] += dforce; + df[e1] -= dforce; + } + + updateMatrix = false; } } - d_df.endEdit(); +} + +template +void QuadularBendingSprings::buildStiffnessMatrix( + core::behavior::StiffnessMatrix* matrix) +{ + auto dfdx = matrix->getForceDerivativeIn(this->mstate) + .withRespectToPositionsIn(this->mstate); + + const type::vector& edgeInf = edgeInfo.getValue(); + for (const auto& einfo : edgeInf) + { + if (einfo.is_activated) // edge not in middle of 2 triangles + { + for (const auto& s : einfo.springs) + { + const sofa::Index a = Deriv::total_size * s.edge[0]; + const sofa::Index b = Deriv::total_size * s.edge[1]; + + const auto& dfdxLocal = s.DfDx; + + dfdx(a, a) += -dfdxLocal; + dfdx(a, b) += dfdxLocal; + dfdx(b, a) += dfdxLocal; + dfdx(b, b) += -dfdxLocal; + } + } + } } template @@ -715,44 +620,21 @@ void QuadularBendingSprings::draw(const core::visual::VisualParams* v { if(edgeInf[i].is_activated) { - const bool external=true; - Real d1 = (x[edgeInf[i].m2]-x[edgeInf[i].m1]).norm(); - if (external) + for (const auto& s : edgeInf[i].springs) { - if (d1drawTool()->drawLines(vertices, 1, colors); @@ -768,8 +650,6 @@ void QuadularBendingSprings::draw(const core::visual::VisualParams* v vertices.push_back(x[m_topology->getQuad(i)[j]]); } vparams->drawTool()->drawQuads(vertices, sofa::type::RGBAColor::red()); - - } diff --git a/examples/Component/SolidMechanics/Spring/QuadularBendingSprings.scn b/examples/Component/SolidMechanics/Spring/QuadularBendingSprings.scn index 0d76942ae89..e13e58e6e3d 100644 --- a/examples/Component/SolidMechanics/Spring/QuadularBendingSprings.scn +++ b/examples/Component/SolidMechanics/Spring/QuadularBendingSprings.scn @@ -1,49 +1,42 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - + - - - - - - - - - - - - + + + + + + + + - + + - + + + + From 9528dbeb8d6e6b0e09fc5121760945bff1a38a3d Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Mon, 4 Dec 2023 17:46:48 +0900 Subject: [PATCH 05/45] [Type] RGBAColor: remove inheritance from type::fixed_array and use std::array to store its components (#4263) * rgbacolor: remove inheritance from fixed_array and use std::array composition * fix datatype info for rgbacolor * add deprecation macro and polish * fix sofacuda * update tests * use sofa size * Apply suggestions from code review (use static field and explicit keyword) Co-authored-by: Alex Bilger * fix and fwd fixed_array in rgbacolor header * Update Sofa/framework/Type/src/sofa/type/config.h.in (change date) Co-authored-by: Hugo * use functions from fixed_array_algo --------- Co-authored-by: Alex Bilger Co-authored-by: Hugo Co-authored-by: Paul Baksic <30337881+bakpaul@users.noreply.github.com> --- Sofa/GL/src/sofa/gl/Axis.cpp | 49 ++++- Sofa/GL/src/sofa/gl/Axis.h | 30 ++- Sofa/GL/src/sofa/gl/DrawToolGL.cpp | 36 ++-- .../Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp | 21 +- .../GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h | 2 + .../src/sofa/gui/qt/viewer/qgl/QtGLViewer.cpp | 2 +- .../Qt/src/sofa/gui/qt/viewer/qt/QtViewer.cpp | 2 +- .../defaulttype/typeinfo/TypeInfo_RGBAColor.h | 2 +- .../Type/src/sofa/type/RGBAColor.cpp | 35 +++- Sofa/framework/Type/src/sofa/type/RGBAColor.h | 183 ++++++++++++++---- Sofa/framework/Type/src/sofa/type/config.h.in | 9 + .../src/sofa/type/fixed_array_algorithms.h | 4 +- Sofa/framework/Type/test/Color_test.cpp | 6 +- .../component/mass/CudaUniformMass.inl | 4 +- 14 files changed, 288 insertions(+), 97 deletions(-) diff --git a/Sofa/GL/src/sofa/gl/Axis.cpp b/Sofa/GL/src/sofa/gl/Axis.cpp index f7da3a42e4a..751d7d4cd34 100644 --- a/Sofa/GL/src/sofa/gl/Axis.cpp +++ b/Sofa/GL/src/sofa/gl/Axis.cpp @@ -130,7 +130,7 @@ void Axis::initDraw() glEndList(); } -void Axis::draw( const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ ) +void Axis::draw( const type::RGBAColor& colorX, const type::RGBAColor& colorY, const type::RGBAColor& colorZ ) { initDraw(); @@ -263,42 +263,42 @@ Axis::AxisSPtr Axis::get(const type::Vec3& len) return a; } -void Axis::draw(const type::Vec3& center, const Quaternion& orient, const type::Vec3& len, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ ) +void Axis::draw(const type::Vec3& center, const Quaternion& orient, const type::Vec3& len, const type::RGBAColor& colorX, const type::RGBAColor& colorY, const type::RGBAColor& colorZ ) { const auto a = get(len); a->update(center, orient); a->draw( colorX, colorY, colorZ ); } -void Axis::draw(const type::Vec3& center, const double orient[4][4], const type::Vec3& len, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +void Axis::draw(const type::Vec3& center, const double orient[4][4], const type::Vec3& len, const type::RGBAColor& colorX, const type::RGBAColor& colorY, const type::RGBAColor& colorZ) { const auto a = get(len); a->update(center, orient); a->draw( colorX, colorY, colorZ ); } -void Axis::draw(const double *mat, const type::Vec3& len, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +void Axis::draw(const double *mat, const type::Vec3& len, const type::RGBAColor& colorX, const type::RGBAColor& colorY, const type::RGBAColor& colorZ) { const auto a = get(len); a->update(mat); a->draw( colorX, colorY, colorZ ); } -void Axis::draw(const type::Vec3& center, const Quaternion& orient, SReal len, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +void Axis::draw(const type::Vec3& center, const Quaternion& orient, SReal len, const type::RGBAColor& colorX, const type::RGBAColor& colorY, const type::RGBAColor& colorZ) { const auto a = get(type::Vec3(len,len,len)); a->update(center, orient); a->draw( colorX, colorY, colorZ ); } -void Axis::draw(const type::Vec3& center, const double orient[4][4], SReal len, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +void Axis::draw(const type::Vec3& center, const double orient[4][4], SReal len, const type::RGBAColor& colorX, const type::RGBAColor& colorY, const type::RGBAColor& colorZ) { const auto a = get(type::Vec3(len,len,len)); a->update(center, orient); a->draw( colorX, colorY, colorZ ); } -void Axis::draw(const double *mat, SReal len, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +void Axis::draw(const double *mat, SReal len, const type::RGBAColor& colorX, const type::RGBAColor& colorY, const type::RGBAColor& colorZ) { const auto a = get(type::Vec3(len,len,len)); a->update(mat); @@ -389,4 +389,39 @@ void Axis::draw(const type::Vec3& p1, const type::Vec3& p2, const double& r1, co } +void Axis::draw(const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +{ + draw(type::RGBAColor::fromVec4(colorX), type::RGBAColor::fromVec4(colorY), type::RGBAColor::fromVec4(colorZ)); +} + +void Axis::draw(const type::Vec3& center, const Quaternion& orient, const type::Vec3& length, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +{ + draw(center, orient, length, type::RGBAColor::fromVec4(colorX), type::RGBAColor::fromVec4(colorY), type::RGBAColor::fromVec4(colorZ)); +} + +void Axis::draw(const type::Vec3& center, const double orient[4][4], const type::Vec3& length, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +{ + draw(center, orient, length, type::RGBAColor::fromVec4(colorX), type::RGBAColor::fromVec4(colorY), type::RGBAColor::fromVec4(colorZ)); +} + +void Axis::draw(const double* mat, const type::Vec3& length, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +{ + draw(mat, length, type::RGBAColor::fromVec4(colorX), type::RGBAColor::fromVec4(colorY), type::RGBAColor::fromVec4(colorZ)); +} + +void Axis::draw(const type::Vec3& center, const Quaternion& orient, SReal length, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +{ + draw(center, orient, length, type::RGBAColor::fromVec4(colorX), type::RGBAColor::fromVec4(colorY), type::RGBAColor::fromVec4(colorZ)); +} + +void Axis::draw(const type::Vec3& center, const double orient[4][4], SReal length, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +{ + draw(center, orient, length, type::RGBAColor::fromVec4(colorX), type::RGBAColor::fromVec4(colorY), type::RGBAColor::fromVec4(colorZ)); +} + +void Axis::draw(const double* mat, SReal length, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +{ + draw(mat, length, type::RGBAColor::fromVec4(colorX), type::RGBAColor::fromVec4(colorY), type::RGBAColor::fromVec4(colorZ)); +} + } // namespace sofa::gl diff --git a/Sofa/GL/src/sofa/gl/Axis.h b/Sofa/GL/src/sofa/gl/Axis.h index 5295c74ee21..129a16997e2 100644 --- a/Sofa/GL/src/sofa/gl/Axis.h +++ b/Sofa/GL/src/sofa/gl/Axis.h @@ -22,6 +22,7 @@ #pragma once #include #include +#include #include #include @@ -57,14 +58,29 @@ class SOFA_GL_API Axis void update(const type::Vec3& center, const double orient[4][4]); void update(const double *mat); - void draw( const type::Vec4f& colorX=type::Vec4f(1,0,0,1), const type::Vec4f& colorY=type::Vec4f(0,1,0,1), const type::Vec4f& colorZ=type::Vec4f(0,0,1,1) ); + void draw(const type::RGBAColor& colorX = type::RGBAColor::red(), const type::RGBAColor& colorY = type::RGBAColor::green(), const type::RGBAColor& colorZ = type::RGBAColor::red()); + static void draw(const type::Vec3& center, const Quaternion& orient, const type::Vec3& length, const type::RGBAColor& colorX = type::RGBAColor::red(), const type::RGBAColor& colorY = type::RGBAColor::green(), const type::RGBAColor& colorZ = type::RGBAColor::red()); + static void draw(const type::Vec3& center, const double orient[4][4], const type::Vec3& length, const type::RGBAColor& colorX = type::RGBAColor::red(), const type::RGBAColor& colorY = type::RGBAColor::green(), const type::RGBAColor& colorZ = type::RGBAColor::red()); + static void draw(const double* mat, const type::Vec3& length, const type::RGBAColor& colorX = type::RGBAColor::red(), const type::RGBAColor& colorY = type::RGBAColor::green(), const type::RGBAColor& colorZ = type::RGBAColor::red()); + static void draw(const type::Vec3& center, const Quaternion& orient, SReal length = 1.0_sreal, const type::RGBAColor& colorX = type::RGBAColor::red(), const type::RGBAColor& colorY = type::RGBAColor::green(), const type::RGBAColor& colorZ = type::RGBAColor::red()); + static void draw(const type::Vec3& center, const double orient[4][4], SReal length = 1.0_sreal, const type::RGBAColor& colorX = type::RGBAColor::red(), const type::RGBAColor& colorY = type::RGBAColor::green(), const type::RGBAColor& colorZ = type::RGBAColor::red()); + static void draw(const double* mat, SReal length = 1.0_sreal, const type::RGBAColor& colorX = type::RGBAColor::red(), const type::RGBAColor& colorY = type::RGBAColor::green(), const type::RGBAColor& colorZ = type::RGBAColor::red()); + + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + void draw(const type::Vec4f& colorX = type::Vec4f(1, 0, 0, 1), const type::Vec4f& colorY = type::Vec4f(0, 1, 0, 1), const type::Vec4f& colorZ = type::Vec4f(0, 0, 1, 1)); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + static void draw(const type::Vec3& center, const Quaternion& orient, const type::Vec3& length, const type::Vec4f& colorX = type::Vec4f(1, 0, 0, 1), const type::Vec4f& colorY = type::Vec4f(0, 1, 0, 1), const type::Vec4f& colorZ = type::Vec4f(0, 0, 1, 1)); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + static void draw(const type::Vec3& center, const double orient[4][4], const type::Vec3& length, const type::Vec4f& colorX = type::Vec4f(1, 0, 0, 1), const type::Vec4f& colorY = type::Vec4f(0, 1, 0, 1), const type::Vec4f& colorZ = type::Vec4f(0, 0, 1, 1)); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + void draw(const double* mat, const type::Vec3& length, const type::Vec4f& colorX = type::Vec4f(1, 0, 0, 1), const type::Vec4f& colorY = type::Vec4f(0, 1, 0, 1), const type::Vec4f& colorZ = type::Vec4f(0, 0, 1, 1)); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + static void draw(const type::Vec3& center, const Quaternion& orient, SReal length = 1.0_sreal, const type::Vec4f& colorX = type::Vec4f(1, 0, 0, 1), const type::Vec4f& colorY = type::Vec4f(0, 1, 0, 1), const type::Vec4f& colorZ = type::Vec4f(0, 0, 1, 1)); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + static void draw(const type::Vec3& center, const double orient[4][4], SReal length = 1.0_sreal, const type::Vec4f& colorX = type::Vec4f(1, 0, 0, 1), const type::Vec4f& colorY = type::Vec4f(0, 1, 0, 1), const type::Vec4f& colorZ = type::Vec4f(0, 0, 1, 1)); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + static void draw(const double* mat, SReal length = 1.0_sreal, const type::Vec4f& colorX = type::Vec4f(1, 0, 0, 1), const type::Vec4f& colorY = type::Vec4f(0, 1, 0, 1), const type::Vec4f& colorZ = type::Vec4f(0, 0, 1, 1)); - static void draw(const type::Vec3& center, const Quaternion& orient, const type::Vec3& length, const type::Vec4f& colorX=type::Vec4f(1,0,0,1), const type::Vec4f& colorY=type::Vec4f(0,1,0,1), const type::Vec4f& colorZ=type::Vec4f(0,0,1,1) ); - static void draw(const type::Vec3& center, const double orient[4][4], const type::Vec3& length, const type::Vec4f& colorX=type::Vec4f(1,0,0,1), const type::Vec4f& colorY=type::Vec4f(0,1,0,1), const type::Vec4f& colorZ=type::Vec4f(0,0,1,1) ); - static void draw(const double *mat, const type::Vec3& length, const type::Vec4f& colorX=type::Vec4f(1,0,0,1), const type::Vec4f& colorY=type::Vec4f(0,1,0,1), const type::Vec4f& colorZ=type::Vec4f(0,0,1,1) ); - static void draw(const type::Vec3& center, const Quaternion& orient, SReal length=1.0_sreal, const type::Vec4f& colorX=type::Vec4f(1,0,0,1), const type::Vec4f& colorY=type::Vec4f(0,1,0,1), const type::Vec4f& colorZ=type::Vec4f(0,0,1,1) ); - static void draw(const type::Vec3& center, const double orient[4][4], SReal length=1.0_sreal, const type::Vec4f& colorX=type::Vec4f(1,0,0,1), const type::Vec4f& colorY=type::Vec4f(0,1,0,1), const type::Vec4f& colorZ=type::Vec4f(0,0,1,1) ); - static void draw(const double *mat, SReal length=1.0_sreal, const type::Vec4f& colorX=type::Vec4f(1,0,0,1), const type::Vec4f& colorY=type::Vec4f(0,1,0,1), const type::Vec4f& colorZ=type::Vec4f(0,0,1,1) ); //Draw a nice vector (cylinder + cone) given 2 points and a radius (used to draw the cylinder) static void draw(const type::Vec3& center, const type::Vec3& ext, const double& radius ); diff --git a/Sofa/GL/src/sofa/gl/DrawToolGL.cpp b/Sofa/GL/src/sofa/gl/DrawToolGL.cpp index ae7b2c608ef..79becb03757 100644 --- a/Sofa/GL/src/sofa/gl/DrawToolGL.cpp +++ b/Sofa/GL/src/sofa/gl/DrawToolGL.cpp @@ -437,7 +437,7 @@ void DrawToolGL::drawTriangleFan(const std::vector &points, void DrawToolGL::drawFrame(const Vec3& position, const Quaternion &orientation, const Vec<3,float> &size) { setPolygonMode(0,false); - gl::Axis::draw(position, orientation, size); + gl::Axis::draw(position, orientation, size, type::RGBAColor::red(), type::RGBAColor::green(), type::RGBAColor::blue()); } void DrawToolGL::drawFrame(const Vec3& position, const Quaternion &orientation, const Vec<3,float> &size, const type::RGBAColor &color) { @@ -748,11 +748,11 @@ void DrawToolGL::internalDrawTriangle(const Vec3 &p1,const Vec3 &p2,const Vec3 & const type::RGBAColor &c1, const type::RGBAColor &c2, const type::RGBAColor &c3) { glNormalT(normal); - glColor4fv(c1.array()); + glColor4fv(c1.data()); glVertexNv<3>(p1.ptr()); - glColor4fv(c2.array()); + glColor4fv(c2.data()); glVertexNv<3>(p2.ptr()); - glColor4fv(c3.array()); + glColor4fv(c3.data()); glVertexNv<3>(p3.ptr()); } @@ -762,13 +762,13 @@ void DrawToolGL::internalDrawTriangle(const Vec3 &p1,const Vec3 &p2,const Vec3 & const type::RGBAColor &c1, const type::RGBAColor &c2, const type::RGBAColor &c3) { glNormalT(normal1); - glColor4fv(c1.array()); + glColor4fv(c1.data()); glVertexNv<3>(p1.ptr()); glNormalT(normal2); - glColor4fv(c2.array()); + glColor4fv(c2.data()); glVertexNv<3>(p2.ptr()); glNormalT(normal3); - glColor4fv(c3.array()); + glColor4fv(c3.data()); glVertexNv<3>(p3.ptr()); } @@ -777,7 +777,7 @@ void DrawToolGL::internalDrawTriangle( const Vec3 &p1, const Vec3 &p2, const Vec const Vec3 &normal, const type::RGBAColor &c) { glNormalT(normal); - glColor4fv(c.array()); + glColor4fv(c.data()); glVertexNv<3>(p1.ptr()); glVertexNv<3>(p2.ptr()); glVertexNv<3>(p3.ptr()); @@ -845,7 +845,7 @@ void DrawToolGL::internalDrawQuad(const Vec3 &p1,const Vec3 &p2,const Vec3 &p3,c const Vec3 &normal, const type::RGBAColor &c) { glNormalT(normal); - glColor4fv(c.array()); + glColor4fv(c.data()); glVertexNv<3>(p1.ptr()); glVertexNv<3>(p2.ptr()); glVertexNv<3>(p3.ptr()); @@ -857,13 +857,13 @@ void DrawToolGL::internalDrawQuad(const Vec3 &p1,const Vec3 &p2,const Vec3 &p3,c const type::RGBAColor &c1, const type::RGBAColor &c2, const type::RGBAColor &c3, const type::RGBAColor &c4) { glNormalT(normal); - glColor4fv(c1.array()); + glColor4fv(c1.data()); glVertexNv<3>(p1.ptr()); - glColor4fv(c2.array()); + glColor4fv(c2.data()); glVertexNv<3>(p2.ptr()); - glColor4fv(c3.array()); + glColor4fv(c3.data()); glVertexNv<3>(p3.ptr()); - glColor4fv(c4.array()); + glColor4fv(c4.data()); glVertexNv<3>(p4.ptr()); } @@ -872,16 +872,16 @@ void DrawToolGL::internalDrawQuad(const Vec3 &p1,const Vec3 &p2,const Vec3 &p3,c const type::RGBAColor &c1, const type::RGBAColor &c2, const type::RGBAColor &c3, const type::RGBAColor &c4) { glNormalT(normal1); - glColor4fv(c1.array()); + glColor4fv(c1.data()); glVertexNv<3>(p1.ptr()); glNormalT(normal2); - glColor4fv(c2.array()); + glColor4fv(c2.data()); glVertexNv<3>(p2.ptr()); glNormalT(normal3); - glColor4fv(c3.array()); + glColor4fv(c3.data()); glVertexNv<3>(p3.ptr()); glNormalT(normal4); - glColor4fv(c4.array()); + glColor4fv(c4.data()); glVertexNv<3>(p4.ptr()); } @@ -1411,7 +1411,7 @@ void DrawToolGL::disableDepthTest() ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void DrawToolGL::draw3DText(const Vec3 &p, float scale, const type::RGBAColor &color, const char* text) { - glColor4fv(color.array()); + glColor4fv(color.data()); sofa::gl::GlText::draw(text, p, (double)scale); } diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp b/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp index 4110cb16b60..31bbb94cbe8 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp @@ -64,7 +64,7 @@ QRGBAColorPicker::QRGBAColorPicker(QWidget* parent) : QWidget(parent) Vec4f QRGBAColorPicker::getColor() const { typedef unsigned char uchar; - const uchar max = std::numeric_limits::max(); + constexpr uchar max = std::numeric_limits::max(); Vec4f color; float r = _r->text().toFloat(); float g = _g->text().toFloat(); @@ -94,14 +94,14 @@ void QRGBAColorPicker::updateRGBAColor() redrawColorButton(); } -void QRGBAColorPicker::setColor(const Vec4f& color) +void QRGBAColorPicker::setColor(const type::RGBAColor& color) { typedef unsigned char uchar; - const uchar max = std::numeric_limits::max(); - const uchar r = uchar( max * color[0] ); - const uchar g = uchar( max * color[1] ); - const uchar b = uchar( max * color[2] ); - const uchar a = uchar( max * color[3] ); + constexpr uchar max = std::numeric_limits::max(); + const uchar r = uchar(max * color[0]); + const uchar g = uchar(max * color[1]); + const uchar b = uchar(max * color[2]); + const uchar a = uchar(max * color[3]); QString str; str.setNum(r); _r->setText(str); @@ -111,11 +111,16 @@ void QRGBAColorPicker::setColor(const Vec4f& color) _b->setText(str); str.setNum(a); _a->setText(str); - _rgba = qRgba(r,g,b,a); + _rgba = qRgba(r, g, b, a); redrawColorButton(); } +void QRGBAColorPicker::setColor(const Vec4f& color) +{ + setColor(type::RGBAColor{color[0], color[1] , color[2] ,color[3]}); +} + void QRGBAColorPicker::redrawColorButton() { const int w=_colorButton->width(); diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h b/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h index 15887a57717..8c8fd37bd6f 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h @@ -58,6 +58,8 @@ class QRGBAColorPicker : public QWidget public: QRGBAColorPicker(QWidget* parent); + void setColor(const type::RGBAColor& color); + void setColor( const Vec4f& color ); Vec4f getColor() const; diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/viewer/qgl/QtGLViewer.cpp b/Sofa/GUI/Qt/src/sofa/gui/qt/viewer/qgl/QtGLViewer.cpp index 315ff47ccb4..ab80a8c4299 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/viewer/qgl/QtGLViewer.cpp +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/viewer/qgl/QtGLViewer.cpp @@ -609,7 +609,7 @@ void QtGLViewer::DisplayOBJs() , this->camera()->orientation()[1] , this->camera()->orientation()[2] , this->camera()->orientation()[3]); - gl::Axis::draw(sofa::type::Vec3(30.0_sreal,30.0_sreal,0.0_sreal),sofaQuat.inverse(), 25.0); + gl::Axis::draw(sofa::type::Vec3(30.0_sreal,30.0_sreal,0.0_sreal),sofaQuat.inverse(), 25.0, sofa::type::RGBAColor::red(), sofa::type::RGBAColor::green(), sofa::type::RGBAColor::blue()); glMatrixMode(GL_PROJECTION); glPopMatrix(); diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/viewer/qt/QtViewer.cpp b/Sofa/GUI/Qt/src/sofa/gui/qt/viewer/qt/QtViewer.cpp index 716b0704913..29f4d94fad7 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/viewer/qt/QtViewer.cpp +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/viewer/qt/QtViewer.cpp @@ -599,7 +599,7 @@ void QtViewer::DisplayOBJs() glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); - gl::Axis::draw(sofa::type::Vec3(30.0,30.0,0.0),currentCamera->getOrientation().inverse(), 25.0); + gl::Axis::draw(sofa::type::Vec3(30.0,30.0,0.0),currentCamera->getOrientation().inverse(), 25.0, sofa::type::RGBAColor::red(), sofa::type::RGBAColor::green(), sofa::type::RGBAColor::blue()); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); diff --git a/Sofa/framework/DefaultType/src/sofa/defaulttype/typeinfo/TypeInfo_RGBAColor.h b/Sofa/framework/DefaultType/src/sofa/defaulttype/typeinfo/TypeInfo_RGBAColor.h index 2d456b27fd3..2a3d63739e0 100644 --- a/Sofa/framework/DefaultType/src/sofa/defaulttype/typeinfo/TypeInfo_RGBAColor.h +++ b/Sofa/framework/DefaultType/src/sofa/defaulttype/typeinfo/TypeInfo_RGBAColor.h @@ -29,7 +29,7 @@ namespace sofa::defaulttype { template<> -class DataTypeInfo< sofa::type::RGBAColor > : public FixedArrayTypeInfo> +class DataTypeInfo< sofa::type::RGBAColor > : public FixedArrayTypeInfo { public: static std::string name() { return "RGBAColor"; } diff --git a/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp b/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp index 47044186fbf..d5f67d51a62 100644 --- a/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp +++ b/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp @@ -24,11 +24,14 @@ #include #include +#include #include + using namespace sofa::type::pairwise; namespace // anonymous { + template T rclamp(const T& value, const T& low, const T& high) { @@ -81,6 +84,12 @@ static void extractValidatedHexaString(std::istream& in, std::string& s) in.clear(in.rdstate() & ~std::ios_base::failbit) ; } + +RGBAColor::RGBAColor(const type::fixed_array& c) + : m_components{ c[0], c[1], c[2], c[3] } +{ +} + bool RGBAColor::read(const std::string& str, RGBAColor& color) { std::stringstream s(str); @@ -93,10 +102,10 @@ bool RGBAColor::read(const std::string& str, RGBAColor& color) void RGBAColor::set(const float r, const float g, const float b, const float a) { - this->elems[0] = r; - this->elems[1] = g; - this->elems[2] = b; - this->elems[3] = a; + this->m_components[0] = r; + this->m_components[1] = g; + this->m_components[2] = b; + this->m_components[3] = a; } @@ -117,13 +126,13 @@ RGBAColor RGBAColor::fromFloat(const float r, const float g, const float b, cons } -RGBAColor RGBAColor::fromVec4(const fixed_array& color) +RGBAColor RGBAColor::fromStdArray(const std::array& color) { return RGBAColor(color) ; } -RGBAColor RGBAColor::fromVec4(const fixed_array& color) +RGBAColor RGBAColor::fromStdArray(const std::array& color) { return RGBAColor(float(color[0]), float(color[1]), float(color[2]), float(color[3])); } @@ -159,6 +168,15 @@ RGBAColor RGBAColor::fromHSVA(const float h, const float s, const float v, const return rgba; } +RGBAColor RGBAColor::fromVec4(const type::fixed_array& color) +{ + return RGBAColor(float(color[0]), float(color[1]), float(color[2]), float(color[3])); +} + +RGBAColor RGBAColor::fromVec4(const type::fixed_array& color) +{ + return RGBAColor(float(color[0]), float(color[1]), float(color[2]), float(color[3])); +} /// This function remove the leading space in the stream. static std::istream& trimInitialSpaces(std::istream& in) @@ -263,8 +281,9 @@ SOFA_TYPE_API std::ostream& operator << ( std::ostream& out, const RGBAColor& t /// @brief enlight a color by a given factor. RGBAColor RGBAColor::lighten(const RGBAColor& in, const SReal factor) { - RGBAColor c = in + ( (RGBAColor::white() - clamp(in, 0.0f, 1.0f)) * rclamp(float(factor), 0.0f, 1.0f)); - c.a()=1.0; + RGBAColor c = in + ( (RGBAColor::white() - RGBAColor::clamp(in, 0.0f, 1.0f)) * rclamp(float(factor), 0.0f, 1.0f)); + + c.a() = 1.0; return c ; } diff --git a/Sofa/framework/Type/src/sofa/type/RGBAColor.h b/Sofa/framework/Type/src/sofa/type/RGBAColor.h index bd3554f6b44..f649f2ef8f6 100644 --- a/Sofa/framework/Type/src/sofa/type/RGBAColor.h +++ b/Sofa/framework/Type/src/sofa/type/RGBAColor.h @@ -22,33 +22,55 @@ #pragma once #include -#include +#include #include #include #include #include +#include +#include +#include + +#include namespace sofa::type { -using sofa::type::fixed_array ; - - #define RGBACOLOR_EQUALITY_THRESHOLD 1e-6 /** * \brief encode a 4 RGBA component color */ -class SOFA_TYPE_API RGBAColor : public fixed_array +class SOFA_TYPE_API RGBAColor { public: - static RGBAColor fromString(const std::string& str) ; - static RGBAColor fromFloat(float r, float g, float b, float a) ; - static RGBAColor fromVec4(const fixed_array& color) ; - static RGBAColor fromVec4(const fixed_array& color) ; + static constexpr sofa::Size NumberOfComponents = 4; + using ComponentArray = std::array; + + constexpr RGBAColor() + : m_components{ 1.f, 1.f, 1.f, 1.f } {} + + constexpr explicit RGBAColor(const std::array& c) + : m_components(c) {} + + constexpr RGBAColor(float r, float g, float b, float a) + : m_components{ r, g, b, a } {} - static RGBAColor fromHSVA(float h, float s, float v, float a) ; + // compat + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + RGBAColor(const type::fixed_array& c); + + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + static RGBAColor fromVec4(const type::fixed_array& color); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + static RGBAColor fromVec4(const type::fixed_array& color); + + static RGBAColor fromString(const std::string& str); + static RGBAColor fromFloat(float r, float g, float b, float a); + static RGBAColor fromStdArray(const std::array& color); + static RGBAColor fromStdArray(const std::array& color); + static RGBAColor fromHSVA(float h, float s, float v, float a); static bool read(const std::string& str, RGBAColor& color) ; @@ -67,33 +89,52 @@ class SOFA_TYPE_API RGBAColor : public fixed_array /// @brief enlight a color by a given factor. static RGBAColor lighten(const RGBAColor& in, const SReal factor); - constexpr float& r(){ return this->elems[0] ; } - constexpr float& g(){ return this->elems[1] ; } - constexpr float& b(){ return this->elems[2] ; } - constexpr float& a(){ return this->elems[3] ; } - constexpr const float& r() const { return this->elems[0] ; } - constexpr const float& g() const { return this->elems[1] ; } - constexpr const float& b() const { return this->elems[2] ; } - constexpr const float& a() const { return this->elems[3] ; } - - constexpr void r(const float r){ this->elems[0]=r; } - constexpr void g(const float g){ this->elems[1]=g; } - constexpr void b(const float b){ this->elems[2]=b; } - constexpr void a(const float a){ this->elems[3]=a; } + constexpr float& r(){ return this->m_components[0] ; } + constexpr float& g(){ return this->m_components[1] ; } + constexpr float& b(){ return this->m_components[2] ; } + constexpr float& a(){ return this->m_components[3] ; } + constexpr const float& r() const { return this->m_components[0] ; } + constexpr const float& g() const { return this->m_components[1] ; } + constexpr const float& b() const { return this->m_components[2] ; } + constexpr const float& a() const { return this->m_components[3] ; } + + constexpr void r(const float r){ this->m_components[0]=r; } + constexpr void g(const float g){ this->m_components[1]=g; } + constexpr void b(const float b){ this->m_components[2]=b; } + constexpr void a(const float a){ this->m_components[3]=a; } + + // operator[] + constexpr float& operator[](std::size_t i) + { + assert(i < NumberOfComponents && "index in RGBAColor must be smaller than 4"); + return m_components[i]; + } + constexpr const float& operator[](std::size_t i) const + { + assert(i < NumberOfComponents && "index in RGBAColor must be smaller than 4"); + return m_components[i]; + } void set(float r, float g, float b, float a) ; - bool operator==(const fixed_array& b) const + bool operator==(const RGBAColor& b) const { for (int i=0; i<4; i++) - if ( fabs( this->elems[i] - b[i] ) > RGBACOLOR_EQUALITY_THRESHOLD ) return false; + if ( fabs( this->m_components[i] - b[i] ) > RGBACOLOR_EQUALITY_THRESHOLD ) return false; return true; } - bool operator!=(const fixed_array& b) const + bool operator!=(const RGBAColor& b) const { for (int i=0; i<4; i++) - if ( fabs( this->elems[i] - b[i] ) > RGBACOLOR_EQUALITY_THRESHOLD ) return true; + if ( fabs( this->m_components[i] - b[i] ) > RGBACOLOR_EQUALITY_THRESHOLD ) return true; + return false; + } + + bool operator<(const RGBAColor& b) const + { + for (int i = 0; i < 4; i++) + if (this->m_components[i] < b[i]) return true; return false; } @@ -102,23 +143,83 @@ class SOFA_TYPE_API RGBAColor : public fixed_array friend SOFA_TYPE_API std::ostream& operator<<(std::ostream& i, const RGBAColor& t) ; friend SOFA_TYPE_API std::istream& operator>>(std::istream& i, RGBAColor& t) ; - constexpr RGBAColor() : fixed_array(1.f, 1.f, 1.f, 1.f) {} - constexpr RGBAColor(const fixed_array& c) : fixed_array(c) {} - constexpr RGBAColor(float r, float g, float b, float a) : fixed_array(r, g, b, a) {} + // direct access to data + constexpr const float* data() const noexcept + { + return m_components.data(); + } + + /// direct access to array + constexpr const ComponentArray& array() const noexcept + { + return m_components; + } + /// direct access to array + constexpr ComponentArray& array() noexcept + { + return m_components; + } + + static constexpr RGBAColor clamp(const RGBAColor& color, float min, float max) + { + RGBAColor result{}; + + for(sofa::Size i = 0 ; i < NumberOfComponents; ++i) + { + result[i] = std::clamp(color[i], min, max); + } + return result; + } + + constexpr ComponentArray::iterator begin() noexcept + { + return m_components.begin(); + } + constexpr ComponentArray::const_iterator begin() const noexcept + { + return m_components.begin(); + } + + constexpr ComponentArray::iterator end() noexcept + { + return m_components.end(); + } + constexpr ComponentArray::const_iterator end() const noexcept + { + return m_components.end(); + } + + static constexpr sofa::Size static_size = NumberOfComponents; + static constexpr sofa::Size size() { return static_size; } + using value_type = float; + using size_type = sofa::Size; + +private: + ComponentArray m_components; }; -inline constexpr RGBAColor g_white {1.0f,1.0f,1.0f,1.0f}; -inline constexpr RGBAColor g_black {0.0f,0.0f,0.0f,1.0f}; -inline constexpr RGBAColor g_red {1.0f,0.0f,0.0f,1.0f}; -inline constexpr RGBAColor g_green {0.0f,1.0f,0.0f,1.0f}; -inline constexpr RGBAColor g_blue {0.0f,0.0f,1.0f,1.0f}; -inline constexpr RGBAColor g_cyan {0.0f,1.0f,1.0f,1.0f}; -inline constexpr RGBAColor g_magenta {1.0f,0.0f,1.0f,1.0f}; -inline constexpr RGBAColor g_yellow {1.0f,1.0f,0.0f,1.0f}; -inline constexpr RGBAColor g_gray {0.5f,0.5f,0.5f,1.0f}; -inline constexpr RGBAColor g_darkgray {0.25f,0.25f,0.25f,1.0f}; -inline constexpr RGBAColor g_lightgray {0.75f,0.75f,0.75f,1.0f}; +constexpr RGBAColor operator-(const RGBAColor& l, const RGBAColor& r) +{ + return sofa::type::pairwise::operator-(l, r); +} + +constexpr RGBAColor operator+(const RGBAColor& l, const RGBAColor& r) +{ + return sofa::type::pairwise::operator+(l, r); +} + +constexpr RGBAColor g_white {1.0f,1.0f,1.0f,1.0f}; +constexpr RGBAColor g_black {0.0f,0.0f,0.0f,1.0f}; +constexpr RGBAColor g_red {1.0f,0.0f,0.0f,1.0f}; +constexpr RGBAColor g_green {0.0f,1.0f,0.0f,1.0f}; +constexpr RGBAColor g_blue {0.0f,0.0f,1.0f,1.0f}; +constexpr RGBAColor g_cyan {0.0f,1.0f,1.0f,1.0f}; +constexpr RGBAColor g_magenta {1.0f,0.0f,1.0f,1.0f}; +constexpr RGBAColor g_yellow {1.0f,1.0f,0.0f,1.0f}; +constexpr RGBAColor g_gray {0.5f,0.5f,0.5f,1.0f}; +constexpr RGBAColor g_darkgray {0.25f,0.25f,0.25f,1.0f}; +constexpr RGBAColor g_lightgray {0.75f,0.75f,0.75f,1.0f}; constexpr const RGBAColor& RGBAColor::white() { return g_white; } constexpr const RGBAColor& RGBAColor::black() { return g_black; } diff --git a/Sofa/framework/Type/src/sofa/type/config.h.in b/Sofa/framework/Type/src/sofa/type/config.h.in index 8c4d79837dd..cb02a404a1c 100644 --- a/Sofa/framework/Type/src/sofa/type/config.h.in +++ b/Sofa/framework/Type/src/sofa/type/config.h.in @@ -41,3 +41,12 @@ "v22.12", "v23.06", \ "As an alternative, use sofa::type::Mat::Identity().") #endif + +#ifdef SOFA_BUILD_SOFA_TYPE +#define SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() +#else +#define SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() \ + SOFA_ATTRIBUTE_DEPRECATED( \ + "v23.12", "v24.06", \ + "RGBAColor does not inherit anymore from sofa::type::fixed_array. Use respective functions accordingly.") +#endif diff --git a/Sofa/framework/Type/src/sofa/type/fixed_array_algorithms.h b/Sofa/framework/Type/src/sofa/type/fixed_array_algorithms.h index dc7fe119e13..951fb579a04 100644 --- a/Sofa/framework/Type/src/sofa/type/fixed_array_algorithms.h +++ b/Sofa/framework/Type/src/sofa/type/fixed_array_algorithms.h @@ -46,7 +46,7 @@ T clamp(const T& in, const TT& minValue, const TT& maxValue) /// @brief pairwise add of two fixed_array template -T operator+(const T& l, const T& r) +constexpr T operator+(const T& l, const T& r) { T result {}; for(typename T::size_type i=0; i < typename T::size_type(TN); ++i) @@ -58,7 +58,7 @@ T operator+(const T& l, const T& r) /// @brief pairwise subtract of two fixed_array template -T operator-(const T& l, const T& r) +constexpr T operator-(const T& l, const T& r) { T result {}; for(typename T::size_type i=0; i < typename T::size_type(TN); ++i) diff --git a/Sofa/framework/Type/test/Color_test.cpp b/Sofa/framework/Type/test/Color_test.cpp index 3701c64330e..c4b062879ba 100644 --- a/Sofa/framework/Type/test/Color_test.cpp +++ b/Sofa/framework/Type/test/Color_test.cpp @@ -134,12 +134,16 @@ void Color_Test::checkCreateFromDouble() const Vec4d tt(2,3,4,5) ; EXPECT_EQ( RGBAColor::fromVec4(tt), RGBAColor(2,3,4,5)) ; + + const std::array stdarrtt{ 2, 3, 4, 5 }; + EXPECT_EQ(RGBAColor::fromStdArray(stdarrtt), RGBAColor(2, 3, 4, 5)); } void Color_Test::checkConstructors() { - EXPECT_EQ( RGBAColor(sofa::type::Vec<4,float>(1,2,3,4)), RGBAColor(1,2,3,4) ) ; + EXPECT_EQ(RGBAColor(std::array{1, 2, 3, 4}), RGBAColor(1, 2, 3, 4)); + EXPECT_EQ( RGBAColor(sofa::type::Vec<4, float>(1, 2, 3, 4)), RGBAColor(1, 2, 3, 4)); } diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/mass/CudaUniformMass.inl b/applications/plugins/SofaCUDA/src/SofaCUDA/component/mass/CudaUniformMass.inl index cd496289a2b..4e996628794 100644 --- a/applications/plugins/SofaCUDA/src/SofaCUDA/component/mass/CudaUniformMass.inl +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/mass/CudaUniformMass.inl @@ -241,7 +241,7 @@ void UniformMass::draw(const core::visual::VisualPa for (unsigned int i=0; i::draw(const core::visual::VisualPa for (unsigned int i=0; i Date: Tue, 5 Dec 2023 18:40:26 +0900 Subject: [PATCH 06/45] [All] ColorMap uses RGBAColor (#4270) * colormap use rgbcolor * add an other version for fromVec4 --- .../fem/elastic/TetrahedronFEMForceField.h | 2 +- .../fem/elastic/TetrahedronFEMForceField.inl | 10 ++-- .../gl/component/rendering3d/DataDisplay.cpp | 24 ++++---- .../Helper/src/sofa/helper/ColorMap.cpp | 59 ++++++++++--------- .../Helper/src/sofa/helper/ColorMap.h | 19 +++--- .../Type/src/sofa/type/RGBAColor.cpp | 11 ++++ Sofa/framework/Type/src/sofa/type/RGBAColor.h | 15 +++++ 7 files changed, 84 insertions(+), 56 deletions(-) diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedronFEMForceField.h b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedronFEMForceField.h index fd934892fef..e357c896a40 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedronFEMForceField.h +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedronFEMForceField.h @@ -224,7 +224,7 @@ class TetrahedronFEMForceField : public core::behavior::ForceField, p Data _computeVonMisesStress; ///< compute and display von Mises stress: 0: no computations, 1: using corotational strain, 2: using full Green strain Data > _vonMisesPerElement; ///< von Mises Stress per element Data > _vonMisesPerNode; ///< von Mises Stress per node - Data > _vonMisesStressColors; ///< Vector of colors describing the VonMises stress + Data > _vonMisesStressColors; ///< Vector of colors describing the VonMises stress Real m_minVonMisesPerNode; Real m_maxVonMisesPerNode; diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedronFEMForceField.inl b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedronFEMForceField.inl index 6feea67d608..f7be5b0ab61 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedronFEMForceField.inl +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedronFEMForceField.inl @@ -1900,7 +1900,7 @@ void TetrahedronFEMForceField::drawTrianglesFromRangeOfTetrahedra( else { sofa::helper::ColorMap::evaluator evalColor = this->m_VonMisesColorMap->getEvaluator(minVM, maxVM); - auto col = sofa::type::RGBAColor::fromVec4(evalColor(vM[elementId])); + auto col = evalColor(vM[elementId]); col[3] = 1.0f; color[0] = col; color[1] = col; @@ -2542,7 +2542,7 @@ void TetrahedronFEMForceField::computeVonMisesStress() updateVonMisesStress=false; - helper::WriteAccessor > > vonMisesStressColors(_vonMisesStressColors); + helper::WriteAccessor > > vonMisesStressColors(_vonMisesStressColors); vonMisesStressColors.clear(); type::vector vonMisesStressColorsCoeff; @@ -2565,12 +2565,12 @@ void TetrahedronFEMForceField::computeVonMisesStress() for(it = _indexedElements->begin() ; it != _indexedElements->end() ; ++it, ++i) { helper::ColorMap::evaluator evalColor = m_VonMisesColorMap->getEvaluator(minVM, maxVM); - const type::Vec4f col = evalColor(vME[i]); + const auto col = evalColor(vME[i]); Tetrahedron tetra = (*_indexedElements)[i]; for(unsigned int j=0 ; j<4 ; j++) { - vonMisesStressColors[tetra[j]] += (col); + vonMisesStressColors[tetra[j]] = vonMisesStressColors[tetra[j]]+(col); vonMisesStressColorsCoeff[tetra[j]] ++; } } @@ -2579,7 +2579,7 @@ void TetrahedronFEMForceField::computeVonMisesStress() { if(vonMisesStressColorsCoeff[i] != 0) { - vonMisesStressColors[i] /= vonMisesStressColorsCoeff[i]; + vonMisesStressColors[i] = vonMisesStressColors[i] / vonMisesStressColorsCoeff[i]; } } } diff --git a/Sofa/GL/Component/Rendering3D/src/sofa/gl/component/rendering3d/DataDisplay.cpp b/Sofa/GL/Component/Rendering3D/src/sofa/gl/component/rendering3d/DataDisplay.cpp index fb8a266112e..698d214bc9c 100644 --- a/Sofa/GL/Component/Rendering3D/src/sofa/gl/component/rendering3d/DataDisplay.cpp +++ b/Sofa/GL/Component/Rendering3D/src/sofa/gl/component/rendering3d/DataDisplay.cpp @@ -252,7 +252,7 @@ void DataDisplay::doDrawVisual(const core::visual::VisualParams* vparams) { RGBAColor color = std::isnan(triData[i]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(triData[i])); + : eval(triData[i]); color[3] = transparency; const Triangle& t = m_topology->getTriangle(i); vparams->drawTool()->drawTriangle( @@ -272,15 +272,15 @@ void DataDisplay::doDrawVisual(const core::visual::VisualParams* vparams) { RGBAColor color0 = std::isnan(pointTriData[i*3]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(pointTriData[i*3])); + : eval(pointTriData[i*3]); color0[3] = transparency; RGBAColor color1 = std::isnan(pointTriData[i*3+1]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(pointTriData[i*3+1])); + : eval(pointTriData[i*3+1]); color1[3] = transparency; RGBAColor color2 = std::isnan(pointTriData[i*3+2]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(pointTriData[i*3+2])); + : eval(pointTriData[i*3+2]); color2[3] = transparency; const Triangle& t = m_topology->getTriangle(i); @@ -308,7 +308,7 @@ void DataDisplay::doDrawVisual(const core::visual::VisualParams* vparams) { RGBAColor color = std::isnan(quadData[i]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(quadData[i])); + : eval(quadData[i]); color[3] = transparency; const Quad& t = m_topology->getQuad(i); vparams->drawTool()->drawQuad( @@ -326,18 +326,18 @@ void DataDisplay::doDrawVisual(const core::visual::VisualParams* vparams) { RGBAColor color0 = std::isnan(pointQuadData[i*4]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(pointQuadData[i*4])); + : eval(pointQuadData[i*4]); RGBAColor color1 = std::isnan(pointQuadData[i*4+1]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(pointQuadData[i*4+1])); + : eval(pointQuadData[i*4+1]); color1[3] = transparency; RGBAColor color2 = std::isnan(pointQuadData[i*4+2]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(pointQuadData[i*4+2])); + : eval(pointQuadData[i*4+2]); color2[3] = transparency; RGBAColor color3 = std::isnan(pointQuadData[i*4+3]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(pointQuadData[i*4+3])); + : eval(pointQuadData[i*4+3]); color1[3] = transparency; const Quad& q = m_topology->getQuad(i); @@ -370,7 +370,7 @@ void DataDisplay::doDrawVisual(const core::visual::VisualParams* vparams) { RGBAColor color = std::isnan(ptData[i]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(ptData[i])); + : eval(ptData[i]); color[3] = transparency; vparams->drawTool()->drawPoint(x[i], color); } @@ -388,7 +388,7 @@ void DataDisplay::doDrawVisual(const core::visual::VisualParams* vparams) for (int j=0; j<3; j++) { color[j] = std::isnan(ptData[t[j]]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(ptData[t[j]])); + : eval(ptData[t[j]]); color[j][3] = transparency; } glNormal3fv(m_normals[t[0]].ptr()); @@ -416,7 +416,7 @@ void DataDisplay::doDrawVisual(const core::visual::VisualParams* vparams) { color[j] = std::isnan(ptData[q[j]]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(ptData[q[j]])); + : eval(ptData[q[j]]); color[j][3] = transparency; } diff --git a/Sofa/framework/Helper/src/sofa/helper/ColorMap.cpp b/Sofa/framework/Helper/src/sofa/helper/ColorMap.cpp index e80ce082233..60cb9448ea3 100644 --- a/Sofa/framework/Helper/src/sofa/helper/ColorMap.cpp +++ b/Sofa/framework/Helper/src/sofa/helper/ColorMap.cpp @@ -174,136 +174,136 @@ void ColorMap::reinit() const float step = (2.0f/3.0f)/(nColors-1); for (unsigned int i=0; i #include +#include #include #include #include @@ -40,10 +41,7 @@ namespace helper class SOFA_HELPER_API ColorMap { public: - - typedef type::Vec3f Color3; // Color tripplet - typedef type::Vec4f Color; // ... with alpha value - typedef sofa::type::vector VecColor; + typedef sofa::type::vector VecColor; ColorMap(unsigned int paletteSize = 256, const std::string& colorScheme = "HSV"); virtual ~ColorMap(); @@ -59,7 +57,7 @@ class SOFA_HELPER_API ColorMap evaluator(const ColorMap* map, Real vmin, Real vmax) : map(map), vmin(vmin), vmax(vmax), vscale((vmax == vmin) ? (Real)0 : (map->entries.size()-1)/(vmax-vmin)) {} - Color operator()(Real r) const + auto operator()(Real r) const { Real e = (r-vmin)*vscale; if (e<0) return map->entries.front(); @@ -67,8 +65,8 @@ class SOFA_HELPER_API ColorMap unsigned int i = (unsigned int)(e); if (i>=map->entries.size()-1) return map->entries.back(); - Color c1 = map->entries[i]; - const Color c2 = map->entries[i+1]; + const auto& c1 = map->entries[i]; + const auto& c2 = map->entries[i+1]; return c1+(c2-c1)*(e-i); } protected: @@ -93,9 +91,9 @@ class SOFA_HELPER_API ColorMap void setColorScheme(const std::string& colorScheme) { m_colorScheme = colorScheme; } unsigned int getNbColors() const { return (unsigned int) entries.size(); } - Color getColor(unsigned int i) { + type::RGBAColor getColor(unsigned int i) { if (i < entries.size()) return entries[i]; - return Color(0.f, 0.f, 0.f, 0.f); + return type::RGBAColor(0.f, 0.f, 0.f, 0.f); } static ColorMap* getDefault(); @@ -110,7 +108,8 @@ class SOFA_HELPER_API ColorMap } } - Color3 hsv2rgb(const Color3 &hsv); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + type::Vec3f hsv2rgb(const type::Vec3f& hsv); inline friend std::ostream& operator << (std::ostream& out, const ColorMap& m ) { diff --git a/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp b/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp index d5f67d51a62..7e0e88208dd 100644 --- a/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp +++ b/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp @@ -26,6 +26,7 @@ #include #include +#include using namespace sofa::type::pairwise; @@ -178,6 +179,16 @@ RGBAColor RGBAColor::fromVec4(const type::fixed_array& color) return RGBAColor(float(color[0]), float(color[1]), float(color[2]), float(color[3])); } +RGBAColor RGBAColor::fromVec4(const type::Vec4f& color) +{ + return RGBAColor(float(color[0]), float(color[1]), float(color[2]), float(color[3])); +} + +RGBAColor RGBAColor::fromVec4(const type::Vec4d& color) +{ + return RGBAColor(float(color[0]), float(color[1]), float(color[2]), float(color[3])); +} + /// This function remove the leading space in the stream. static std::istream& trimInitialSpaces(std::istream& in) { diff --git a/Sofa/framework/Type/src/sofa/type/RGBAColor.h b/Sofa/framework/Type/src/sofa/type/RGBAColor.h index f649f2ef8f6..76a44dc3fb0 100644 --- a/Sofa/framework/Type/src/sofa/type/RGBAColor.h +++ b/Sofa/framework/Type/src/sofa/type/RGBAColor.h @@ -65,6 +65,10 @@ class SOFA_TYPE_API RGBAColor static RGBAColor fromVec4(const type::fixed_array& color); SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() static RGBAColor fromVec4(const type::fixed_array& color); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + static RGBAColor fromVec4(const Vec4f& color); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + static RGBAColor fromVec4(const Vec4d& color); static RGBAColor fromString(const std::string& str); static RGBAColor fromFloat(float r, float g, float b, float a); @@ -209,6 +213,17 @@ constexpr RGBAColor operator+(const RGBAColor& l, const RGBAColor& r) return sofa::type::pairwise::operator+(l, r); } +constexpr RGBAColor operator/(const RGBAColor& l, const float div) +{ + RGBAColor result{}; + for (std::size_t i = 0; i < 4; ++i) + { + result[i] = l[i] / div; + } + return result; +} + + constexpr RGBAColor g_white {1.0f,1.0f,1.0f,1.0f}; constexpr RGBAColor g_black {0.0f,0.0f,0.0f,1.0f}; constexpr RGBAColor g_red {1.0f,0.0f,0.0f,1.0f}; From 3fadc10492662a63eab725fa45894f2c5b3fe9bd Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Wed, 6 Dec 2023 01:07:27 +0100 Subject: [PATCH 07/45] [ODESolver.Backward] Convert double to SReal in NewmarkImplicitSolver (#4341) * [ODESolver.Backward] Convert double to SReal in NewmarkImplicitSolver * Adapt default values to the new type SReal --- .../backward/NewmarkImplicitSolver.cpp | 23 +++++++++++-------- .../backward/NewmarkImplicitSolver.h | 10 ++++---- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.cpp b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.cpp index be829e69fb6..62d1ade2042 100644 --- a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.cpp +++ b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.cpp @@ -42,11 +42,16 @@ using namespace sofa::defaulttype; using namespace core::behavior; NewmarkImplicitSolver::NewmarkImplicitSolver() - : d_rayleighStiffness(initData(&d_rayleighStiffness,0.0,"rayleighStiffness","Rayleigh damping coefficient related to stiffness") ) - , d_rayleighMass( initData(&d_rayleighMass,0.0,"rayleighMass","Rayleigh damping coefficient related to mass")) - , d_velocityDamping( initData(&d_velocityDamping,0.0,"vdamping","Velocity decay coefficient (no decay if null)") ) - , d_gamma( initData(&d_gamma, 0.5, "gamma", "Newmark scheme gamma coefficient")) - , d_beta( initData(&d_beta, 0.25, "beta", "Newmark scheme beta coefficient") ) + : d_rayleighStiffness(initData(&d_rayleighStiffness, 0_sreal, + "rayleighStiffness", + "Rayleigh damping coefficient related to stiffness")) + , d_rayleighMass(initData(&d_rayleighMass, 0_sreal, "rayleighMass", + "Rayleigh damping coefficient related to mass")) + , d_velocityDamping(initData(&d_velocityDamping, 0_sreal, "vdamping", + "Velocity decay coefficient (no decay if null)")) + , d_gamma(initData(&d_gamma, 0.5_sreal, "gamma", + "Newmark scheme gamma coefficient")) + , d_beta(initData(&d_beta, 0.25_sreal, "beta", "Newmark scheme beta coefficient")) , d_threadSafeVisitor(initData(&d_threadSafeVisitor, false, "threadSafeVisitor", "If true, do not use realloc and free visitors in fwdInteractionForceField.")) { cpt=0; @@ -70,10 +75,10 @@ void NewmarkImplicitSolver::solve(const core::ExecParams* params, SReal dt, sofa const SReal h = dt; - const double gamma = d_gamma.getValue(); - const double beta = d_beta.getValue(); - const double rM = d_rayleighMass.getValue(); - const double rK = d_rayleighStiffness.getValue(); + const SReal gamma = d_gamma.getValue(); + const SReal beta = d_beta.getValue(); + const SReal rM = d_rayleighMass.getValue(); + const SReal rK = d_rayleighStiffness.getValue(); // 1. Initialize a_t and to store it as a vecId to be used in the resolution of this solver (using as well old xand v) // Once we have a_{t+dt} we can update the new x and v. diff --git a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.h b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.h index 52ac563b514..fec55b13481 100644 --- a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.h +++ b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.h @@ -56,12 +56,12 @@ class SOFA_COMPONENT_ODESOLVER_BACKWARD_API NewmarkImplicitSolver : public sofa: public: SOFA_CLASS(NewmarkImplicitSolver, sofa::core::behavior::OdeSolver); - Data d_rayleighStiffness; ///< Rayleigh damping coefficient related to stiffness - Data d_rayleighMass; ///< Rayleigh damping coefficient related to mass - Data d_velocityDamping; ///< Velocity decay coefficient (no decay if null) + Data d_rayleighStiffness; ///< Rayleigh damping coefficient related to stiffness + Data d_rayleighMass; ///< Rayleigh damping coefficient related to mass + Data d_velocityDamping; ///< Velocity decay coefficient (no decay if null) - Data d_gamma; ///< Newmark scheme gamma coefficient - Data d_beta; ///< Newmark scheme beta coefficient + Data d_gamma; ///< Newmark scheme gamma coefficient + Data d_beta; ///< Newmark scheme beta coefficient Data d_threadSafeVisitor; ///< If true, do not use realloc and free visitors in fwdInteractionForceField. From 058f9d4db9ed111d02829d0022c10f4082295db3 Mon Sep 17 00:00:00 2001 From: Hugo Date: Thu, 7 Dec 2023 02:36:57 +0100 Subject: [PATCH 08/45] [SolidMechanics] Implement buildStiffnessMatrix for PolynomialSpringsFF (#4301) * [SolidMechanics] Implement buildStiffnessMatrix for PolynomialSpringsForceField * Remove timer --------- Co-authored-by: Alex Bilger --- .../spring/PolynomialSpringsForceField.h | 2 + .../spring/PolynomialSpringsForceField.inl | 69 ++++++++++++++++++- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.h index 7e5e085e2db..057c75e5a98 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.h @@ -127,6 +127,8 @@ class PolynomialSpringsForceField : public core::behavior::PairInteractionForceF /// Brings ForceField contribution to the global system stiffness matrix. virtual void addKToMatrix(const core::MechanicalParams* mparams, const core::behavior::MultiMatrixAccessor* matrix) override; + void buildStiffnessMatrix(core::behavior::StiffnessMatrix* matrix) override; + void buildDampingMatrix(core::behavior::DampingMatrix* /*matrix*/) final; virtual void draw(const core::visual::VisualParams* vparams) override; diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.inl b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.inl index 404401f9001..3f5b9d9fab2 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.inl +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.inl @@ -60,7 +60,6 @@ PolynomialSpringsForceField::PolynomialSpringsForceField(MechanicalSt { } - template void PolynomialSpringsForceField::bwdInit() { @@ -394,8 +393,6 @@ void PolynomialSpringsForceField::draw(const core::visual::VisualPara } - - template void PolynomialSpringsForceField::addKToMatrix(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix ) @@ -461,6 +458,72 @@ void PolynomialSpringsForceField::addKToMatrix(const core::Mechanical } } +template +void PolynomialSpringsForceField::buildStiffnessMatrix(core::behavior::StiffnessMatrix* matrix) +{ + unsigned int firstIndex = 0; + unsigned int secondIndex = 0; + + if (this->mstate1 == this->mstate2) + { + auto dfdx = matrix->getForceDerivativeIn(this->mstate1.get()) + .withRespectToPositionsIn(this->mstate1.get()); + + for (unsigned int index = 0; index < m_firstObjectIndices.size(); index++) + { + firstIndex = m_firstObjectIndices[index]; + secondIndex = m_secondObjectIndices[index]; + const JacobianMatrix& jacobMatrix = m_differential[index]; + + for(unsigned int i = 0; i < m_dimension; i++) + { + for (unsigned int j = 0; j < m_dimension; j++) + { + Real stiffnessDeriv = jacobMatrix[i][j]; + dfdx(m_dimension * firstIndex + i, m_dimension * firstIndex + j) += - stiffnessDeriv; + dfdx(m_dimension * firstIndex + i, m_dimension * secondIndex + j) += stiffnessDeriv; + dfdx(m_dimension * secondIndex + i, m_dimension * firstIndex + j) += stiffnessDeriv; + dfdx(m_dimension * secondIndex + i, m_dimension * secondIndex + j) += - stiffnessDeriv; + } + } + } + } + else + { + auto* m1 = this->mstate1.get(); + auto* m2 = this->mstate2.get(); + + auto df1_dx1 = matrix->getForceDerivativeIn(m1).withRespectToPositionsIn(m1); + auto df1_dx2 = matrix->getForceDerivativeIn(m1).withRespectToPositionsIn(m2); + auto df2_dx1 = matrix->getForceDerivativeIn(m2).withRespectToPositionsIn(m1); + auto df2_dx2 = matrix->getForceDerivativeIn(m2).withRespectToPositionsIn(m2); + + df1_dx1.checkValidity(this); + df1_dx2.checkValidity(this); + df2_dx1.checkValidity(this); + df2_dx2.checkValidity(this); + + for (unsigned int index = 0; index < m_firstObjectIndices.size(); index++) + { + firstIndex = m_firstObjectIndices[index]; + secondIndex = m_secondObjectIndices[index]; + const JacobianMatrix& jacobMatrix = m_differential[index]; + + for(unsigned int i = 0; i < m_dimension; i++) + { + for (unsigned int j = 0; j < m_dimension; j++) + { + Real stiffnessDeriv = jacobMatrix[i][j]; + df1_dx1(m_dimension * firstIndex + i, m_dimension * firstIndex + j) += -stiffnessDeriv; + df1_dx2(m_dimension * firstIndex + i, m_dimension * secondIndex + j) += stiffnessDeriv; + df2_dx1(m_dimension * secondIndex + i, m_dimension * firstIndex + j) += stiffnessDeriv; + df2_dx2(m_dimension * secondIndex + i, m_dimension * secondIndex + j) += -stiffnessDeriv; + } + } + } + } +} + template void PolynomialSpringsForceField::buildDampingMatrix(core::behavior::DampingMatrix*) { From 7272629546545b4b9ab2238c3e3a9f4a1704cf72 Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Fri, 8 Dec 2023 22:26:35 +0900 Subject: [PATCH 09/45] [ODESolver] Fix compilation with SOFA_NO_VMULTIOP (#4325) fix when SOFA_NO_VMULTIOP is defined Co-authored-by: erik pernod --- .../odesolver/forward/CentralDifferenceSolver.cpp | 4 ++-- .../src/sofa/component/odesolver/forward/EulerSolver.cpp | 8 ++++---- .../component/odesolver/forward/RungeKutta2Solver.cpp | 4 ++-- .../component/odesolver/forward/RungeKutta4Solver.cpp | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/CentralDifferenceSolver.cpp b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/CentralDifferenceSolver.cpp index 06b9d39d42c..3ed6e8202e9 100644 --- a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/CentralDifferenceSolver.cpp +++ b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/CentralDifferenceSolver.cpp @@ -103,9 +103,9 @@ void CentralDifferenceSolver::solve(const core::ExecParams* params, SReal dt, so { #ifdef SOFA_NO_VMULTIOP // unoptimized version vel2.eq( vel, dx, dt ); // vel = vel + dt M^{-1} ( P_n - K u_n ) - mop.solveConstraint(vel2, core::ConstraintParams::ConstOrder::VEL); + mop.solveConstraint(vel2,core::ConstraintOrder::VEL); pos2.eq( pos, vel2, dt ); // pos = pos + h vel - mop.solveConstraint(pos2, core::ConstraintParams::ConstOrder::POS); + mop.solveConstraint(pos2,core::ConstraintOrder::POS); #else // single-operation optimization diff --git a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp index 59a9e6d7f90..97fb91c7c88 100644 --- a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp +++ b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp @@ -135,10 +135,10 @@ void EulerExplicitSolver::updateState(sofa::simulation::common::VectorOperations //newPos = pos + newVel * dt newVel.eq(vel, acc.id(), dt); - mop->solveConstraint(newVel, core::ConstraintParams::ConstOrder::VEL); + mop->solveConstraint(newVel,core::ConstraintOrder::VEL); newPos.eq(pos, newVel, dt); - mop->solveConstraint(newPos, core::ConstraintParams::ConstOrder::POS); + mop->solveConstraint(newPos,core::ConstraintOrder::POS); } else { @@ -146,10 +146,10 @@ void EulerExplicitSolver::updateState(sofa::simulation::common::VectorOperations //newVel = vel + acc * dt newPos.eq(pos, vel, dt); - mop->solveConstraint(newPos, core::ConstraintParams::ConstOrder::POS); + mop->solveConstraint(newPos,core::ConstraintOrder::POS); newVel.eq(vel, acc.id(), dt); - mop->solveConstraint(newVel, core::ConstraintParams::ConstOrder::VEL); + mop->solveConstraint(newVel,core::ConstraintOrder::VEL); } #else // single-operation optimization { diff --git a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta2Solver.cpp b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta2Solver.cpp index 0b3eb389aee..4e75919e1a5 100644 --- a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta2Solver.cpp +++ b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta2Solver.cpp @@ -91,9 +91,9 @@ void RungeKutta2Solver::solve(const core::ExecParams* params, SReal dt, sofa::co // Use the derivative at newX, newV to update the state #ifdef SOFA_NO_VMULTIOP // unoptimized version pos2.eq(pos,newV,dt); - solveConstraint(dt,pos2,core::ConstraintParams::ConstOrder::POS); + mop.solveConstraint(pos2,core::ConstraintOrder::POS); vel2.eq(vel,acc,dt); - solveConstraint(dt,vel2,core::ConstraintParams::ConstOrder::VEL); + mop.solveConstraint(vel2,core::ConstraintOrder::VEL); #else // single-operation optimization { typedef core::behavior::BaseMechanicalState::VMultiOp VMultiOp; diff --git a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta4Solver.cpp b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta4Solver.cpp index 30ec32ed555..bdd8b21795d 100644 --- a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta4Solver.cpp +++ b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta4Solver.cpp @@ -160,9 +160,9 @@ void RungeKutta4Solver::solve(const core::ExecParams* params, SReal dt, sofa::co pos2.peq(k3v,stepBy3); vel2.peq(k3a,stepBy3); pos2.peq(k4v,stepBy6); - solveConstraint(dt, pos2, core::ConstraintParams::ConstOrder::POS); + mop.solveConstraint(pos2, core::ConstraintOrder::POS); vel2.peq(k4a,stepBy6); - solveConstraint(dt, vel2, core::ConstraintParams::ConstOrder::VEL); + mop.solveConstraint(vel2, core::ConstraintOrder::VEL); #else // single-operation optimization { typedef core::behavior::BaseMechanicalState::VMultiOp VMultiOp; From da70359feb76e03393ca5d43bdb156417bf78e3d Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Fri, 8 Dec 2023 22:27:56 +0900 Subject: [PATCH 10/45] [image] image_gui to compile with Qt6 (#4330) image_gui compiling with qt6 Co-authored-by: Hugo --- applications/plugins/image/image_gui/CMakeLists.txt | 1 - applications/plugins/image/image_gui/HistogramWidget.h | 4 ++-- applications/plugins/image/image_gui/ImagePlaneWidget.h | 8 ++++---- .../image/imagetoolbox/imagetoolboxcentralwidget.h | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/applications/plugins/image/image_gui/CMakeLists.txt b/applications/plugins/image/image_gui/CMakeLists.txt index 146d0e8f16b..c08ae5d1f95 100644 --- a/applications/plugins/image/image_gui/CMakeLists.txt +++ b/applications/plugins/image/image_gui/CMakeLists.txt @@ -29,7 +29,6 @@ if (NOT Qt5Core_FOUND) find_package(Qt6 COMPONENTS Core CoreTools REQUIRED QUIET) if (Qt6Core_FOUND) qt6_wrap_cpp(MOC_FILES ${MOC_HEADER_FILES}) - message(FATAL_ERROR "Image_gui is not compatible with Qt6 yet.") # to remove once image_gui has been updated endif() # else() should never happened as it would already break in Sofa.GUI.Qt endif() diff --git a/applications/plugins/image/image_gui/HistogramWidget.h b/applications/plugins/image/image_gui/HistogramWidget.h index be53b8bab47..78e523a06da 100644 --- a/applications/plugins/image/image_gui/HistogramWidget.h +++ b/applications/plugins/image/image_gui/HistogramWidget.h @@ -86,7 +86,7 @@ class THistogramSetting: public HistogramSetting label3=new QLabel(parent); QHBoxLayout *layout = new QHBoxLayout(parent); - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(label1); layout->addStretch(); layout->addWidget(label2); @@ -268,7 +268,7 @@ class HistogramOptionWidget: public QWidget label->setNum(0); QHBoxLayout *layout = new QHBoxLayout(this); - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(10); layout->addWidget(labelName); layout->addWidget(slider); diff --git a/applications/plugins/image/image_gui/ImagePlaneWidget.h b/applications/plugins/image/image_gui/ImagePlaneWidget.h index a80d205b2cf..21b44730d1c 100644 --- a/applications/plugins/image/image_gui/ImagePlaneWidget.h +++ b/applications/plugins/image/image_gui/ImagePlaneWidget.h @@ -159,9 +159,9 @@ public slots: void fitInView() // modified version of original fitinview (no margin) { - QRectF unity = this->matrix().mapRect(QRectF(0, 0, 1, 1)); + QRectF unity = this->transform().mapRect(QRectF(0, 0, 1, 1)); scale(1 / unity.width(), 1 / unity.height()); - QRectF sceneRect = this->matrix().mapRect(roi); + QRectF sceneRect = this->transform().mapRect(roi); scale(viewport()->rect().width() / sceneRect.width(), viewport()->rect().height() / sceneRect.height()); centerOn(roi.center()); } @@ -224,7 +224,7 @@ public slots: else { scene->P1=pt; emit cursorChangedX(pt.x()); emit cursorChangedY(pt.y()); Render ();} } - void wheelEvent (QWheelEvent *wheelev) override { emit wheelevent((wheelev->delta()>0)?1:-1); } + void wheelEvent (QWheelEvent *wheelev) override { emit wheelevent((wheelev->angleDelta().y()>0)?1:-1); } ImagePlaneGraphScene * scene; QRectF roi; @@ -438,7 +438,7 @@ class ImagePlaneOptionWidget: public QWidget QObject::connect(this,SIGNAL(toggled(bool)),label,SLOT(setVisible(bool))); QHBoxLayout *layout = new QHBoxLayout(this); - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(10); layout->addWidget(toggle); layout->addWidget(slider); diff --git a/applications/plugins/image/imagetoolbox/imagetoolboxcentralwidget.h b/applications/plugins/image/imagetoolbox/imagetoolboxcentralwidget.h index edd274227a1..5506312d2f7 100644 --- a/applications/plugins/image/imagetoolbox/imagetoolboxcentralwidget.h +++ b/applications/plugins/image/imagetoolbox/imagetoolboxcentralwidget.h @@ -87,7 +87,7 @@ class SOFA_IMAGE_GUI_API ImageToolBoxOptionCentralWidget: public QWidget QObject::connect(slider,SIGNAL(valueChanged(int)),this,SIGNAL(valueChanged())); QHBoxLayout *layout = new QHBoxLayout(this); - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(10); //layout->add(toggle); layout->addWidget(slider); From 384d495c10ac33d3d88e38dd7b79b45848cfc13f Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Sat, 9 Dec 2023 01:10:46 +0900 Subject: [PATCH 11/45] [Simulation.Core] Deprecate LocalStorage feature (#4327) * remove unused local storage feat * deprecate localstorage and impl * restore and deprecate functions using localstorage --------- Co-authored-by: Hugo --- .../Core/src/sofa/simulation/BaseMechanicalVisitor.h | 6 ++++-- .../Core/src/sofa/simulation/CactusStackStorage.h | 3 +++ .../Simulation/Core/src/sofa/simulation/LocalStorage.h | 5 +++++ .../Simulation/Core/src/sofa/simulation/Visitor.h | 2 ++ .../Simulation/Core/src/sofa/simulation/config.h.in | 10 ++++++++++ .../Simulation/Core/src/sofa/simulation/fwd.h | 1 - 6 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/BaseMechanicalVisitor.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/BaseMechanicalVisitor.h index a52ae7f2b50..bd25f9e25b7 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/BaseMechanicalVisitor.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/BaseMechanicalVisitor.h @@ -79,7 +79,8 @@ class SOFA_SIMULATION_CORE_API BaseMechanicalVisitor : public Visitor /// Parallel version of processNodeTopDown. /// This method calls the fwd* methods during the forward traversal. You typically do not overload it. - Result processNodeTopDown(simulation::Node* node, LocalStorage* stack) override; + SOFA_ATTRIBUTE_DEPRECATED_LOCALSTORAGE() + Result processNodeTopDown(simulation::Node * node, LocalStorage * stack) override; /// Process the OdeSolver virtual Result fwdOdeSolver(simulation::Node* /*node*/, sofa::core::behavior::OdeSolver* /*solver*/); @@ -169,7 +170,8 @@ class SOFA_SIMULATION_CORE_API BaseMechanicalVisitor : public Visitor /// Parallel version of processNodeBottomUp. /// This method calls the bwd* methods during the backward traversal. You typically do not overload it. - void processNodeBottomUp(simulation::Node* /*node*/, LocalStorage* stack) override; + SOFA_ATTRIBUTE_DEPRECATED_LOCALSTORAGE() + void processNodeBottomUp(simulation::Node* /*node*/, LocalStorage * stack) override; /// Process the BaseMechanicalState when it is not mapped from parent level virtual void bwdMechanicalState(simulation::Node* /*node*/,sofa::core::behavior::BaseMechanicalState* /*mm*/); diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/CactusStackStorage.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/CactusStackStorage.h index 6afb0cca3df..4bb1222f39f 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/CactusStackStorage.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/CactusStackStorage.h @@ -26,6 +26,8 @@ #include #include +SOFA_HEADER_DEPRECATED_LOCALSTORAGE() + namespace sofa { @@ -36,6 +38,7 @@ namespace simulation /// Cactus Stack implementation of LocalStorage. /// See http://www.nist.gov/dads/HTML/cactusstack.html +SOFA_ATTRIBUTE_DEPRECATED_LOCALSTORAGE() class SOFA_SIMULATION_CORE_API CactusStackStorage : public simulation::LocalStorage { protected: diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/LocalStorage.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/LocalStorage.h index f06d2a3c528..2df86d938c2 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/LocalStorage.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/LocalStorage.h @@ -22,6 +22,10 @@ #ifndef SOFA_SIMULATION_TREE_LOCALSTORAGE_H #define SOFA_SIMULATION_TREE_LOCALSTORAGE_H +#include + +SOFA_HEADER_DEPRECATED_LOCALSTORAGE() + namespace sofa { @@ -32,6 +36,7 @@ namespace simulation class Visitor; /// Abstract class allowing actions to store local data as a stack while traversing the graph. +SOFA_ATTRIBUTE_DEPRECATED_LOCALSTORAGE() class LocalStorage { protected: diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/Visitor.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/Visitor.h index 42d0fb245e7..90b09b3da91 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/Visitor.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/Visitor.h @@ -160,10 +160,12 @@ class SOFA_SIMULATION_CORE_API Visitor /// Callback method called when decending to a new node. Recursion will stop if this method returns RESULT_PRUNE /// This version is offered a LocalStorage to store temporary data + SOFA_ATTRIBUTE_DEPRECATED_LOCALSTORAGE() virtual Result processNodeTopDown(simulation::Node* node, LocalStorage*) { return processNodeTopDown(node); } /// Callback method called after child node have been processed and before going back to the parent node. /// This version is offered a LocalStorage to store temporary data + SOFA_ATTRIBUTE_DEPRECATED_LOCALSTORAGE() virtual void processNodeBottomUp(simulation::Node* node, LocalStorage*) { processNodeBottomUp(node); } typedef sofa::core::objectmodel::Tag Tag; diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/config.h.in b/Sofa/framework/Simulation/Core/src/sofa/simulation/config.h.in index dce81618ee4..a949327fc2c 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/config.h.in +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/config.h.in @@ -238,3 +238,13 @@ SOFA_ATTRIBUTE_DEPRECATED( \ #define SOFA_HEADER_DEPRECATED_PARALLELVISITORSCHEDULER() \ SOFA_DEPRECATED_HEADER_NOT_REPLACED("v23.12", "v24.06") #endif // SOFA_BUILD_SOFA_SIMULATION_CORE + +#ifdef SOFA_BUILD_SOFA_SIMULATION_CORE +#define SOFA_HEADER_DEPRECATED_LOCALSTORAGE() +#define SOFA_ATTRIBUTE_DEPRECATED_LOCALSTORAGE() +#else +#define SOFA_HEADER_DEPRECATED_LOCALSTORAGE() \ + SOFA_DEPRECATED_HEADER_NOT_REPLACED("v23.12", "v24.06") +#define SOFA_ATTRIBUTE_DEPRECATED_LOCALSTORAGE() \ + SOFA_ATTRIBUTE_DEPRECATED("v23.12", "v24.06", "LocalStorage feature was seemingly not used so it has been deprecated.") +#endif // SOFA_BUILD_SOFA_SIMULATION_CORE diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/fwd.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/fwd.h index 69e091bca8a..ca6ae46f75b 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/fwd.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/fwd.h @@ -46,7 +46,6 @@ namespace sofa::simulation */ SOFA_SIMULATION_CORE_API Simulation* getSimulation(); - class LocalStorage; class MutationListener; class Visitor; From d33ae528aa1c12b4445845b83e235e56f5083fd9 Mon Sep 17 00:00:00 2001 From: Hugo Date: Mon, 11 Dec 2023 11:55:47 +0100 Subject: [PATCH 12/45] [GitHub] Add a python-based action managing discussions (#4268) * [GitHub] Add a python-based action managing discussions * add python script * make action triggered on labels * simplify action * add python-graphql-client dependency * add dateutil dependency * activate script limited on 1 topic per activation and remove cron temporarily * add verbosity on discussions, add cron & dispatch trigger, remove trigger on label changes * Rename action as: Stale GitHub Discussions * Apply suggestions from code review Co-authored-by: Alex Bilger --------- Co-authored-by: Alex Bilger --- .../workflows/stale_github_discussions.yml | 32 ++ scripts/comment-close-old-discussions.py | 335 ++++++++++++++++++ 2 files changed, 367 insertions(+) create mode 100644 .github/workflows/stale_github_discussions.yml create mode 100644 scripts/comment-close-old-discussions.py diff --git a/.github/workflows/stale_github_discussions.yml b/.github/workflows/stale_github_discussions.yml new file mode 100644 index 00000000000..cfac73e28d0 --- /dev/null +++ b/.github/workflows/stale_github_discussions.yml @@ -0,0 +1,32 @@ +name: Stale GitHub Discussions + +on: + workflow_dispatch: + schedule: + - cron: '0 6 * * 1' # Every Monday at 6:00 AM UTC (8:00 AM CET) + +jobs: + run: + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.10' # Use the desired Python version + + - name: Install dependencies + run: | + pip install python-graphql-client + pip install python-dateutil + working-directory: ${{ github.workspace }} + + - name: Run script comment-close-old-discussions.py + run: | + python scripts/comment-close-old-discussions.py + working-directory: ${{ github.workspace }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/scripts/comment-close-old-discussions.py b/scripts/comment-close-old-discussions.py new file mode 100644 index 00000000000..e7bb28baeed --- /dev/null +++ b/scripts/comment-close-old-discussions.py @@ -0,0 +1,335 @@ +#!python + +# DEPENDENCIES +# python3 -m pip install python-graphql-client + +#Ref : Action in python https://www.python-engineer.com/posts/run-python-github-actions/ + + +#TEST steps: +# - add cron & dispatch trigger, remove trigger on label changes (yml) +# - test with only one entry (break) +# - remove break +# - after 1st of December 2023, remove the temporary layer + +import os +import sys +import json +from datetime import datetime, timedelta, date +from python_graphql_client import GraphqlClient +from dateutil.relativedelta import relativedelta + + +client = GraphqlClient(endpoint="https://api.github.com/graphql") +github_token = os.environ['GITHUB_TOKEN'] + + +# List of the repository to scan +repos=[['sofa-framework','sofa']] + + +# Format the reference date (with which the last reply will be compared) +# Today +date_today = date.today() +# warning delay = 2-month delay for warning +delay_warning = relativedelta(months = 2) +date_reference_warning = date_today - delay_warning +# closing delay = 2+2.5-month delay for closing +delay_closing = relativedelta(months = 2) + relativedelta(weeks = 1) +date_reference_closing = date_today - delay_closing + + +# List of reviewers on GitHub Discussions +reviewer_logins=[["alxbilger"],["hugtalbot"],["bakpaul"],["fredroy"],["epernod"],["damienmarchal"],["VannesteFelix"],["EulalieCoevoet"],["github-actions"]] + + +# Check if the "createdAt" is older than the "date_reference" +def isOlderThan(date_reference, createdAt): + # Format date of creation YYYY-MM-DD + creation_date = createdAt[:-10] + creation_date = datetime.strptime(creation_date, '%Y-%m-%d') + + if creation_date.date() > date_reference: + return False + else : + return True + +# Returns true of the date "createdAt" is more than the warning delay +def isToBeWarned(createdAt): + return isOlderThan(date_reference_warning, createdAt) + + +# Returns true of the date "createdAt" is more than the closing delay +def isToBeClosed(createdAt): + return isOlderThan(date_reference_closing, createdAt) + + + +def computeListOfDiscussionToProcess(): + for repo in repos: + + owner = repo[0] + name = repo[1] + + has_next_page = True + after_cursor = None + + to_be_warned_discussion_number = [] + to_be_warned_discussion_id = [] + to_be_warned_discussion_author = [] + + to_be_closed_discussion_number = [] + to_be_closed_discussion_id = [] + to_be_closed_discussion_author = [] + + while has_next_page: + # Trigger the query on discussions + data = client.execute( + query = make_query_discussions(owner, name, after_cursor), + headers = {"Authorization": "Bearer {}".format(github_token)}, + ) + + # Process each discussion + for discussion in data["data"]["repository"]["discussions"]["nodes"]: + + # Save original author of the discussion + discussionAuthor = discussion["author"]["login"] + + # Detect the last comment + lastCommentId = len(discussion["comments"]["nodes"]) - 1 + + # Pass to the next discussion item, if no comment in the discussion + if(lastCommentId < 0): + continue + + lastReplyOnLastComment = len(discussion["comments"]["nodes"][lastCommentId]["replies"]["nodes"]) - 1 + + # No replies on the last comment + if(lastReplyOnLastComment < 0): + author = discussion["comments"]["nodes"][lastCommentId]["author"]["login"] + dateLastMessage = discussion["comments"]["nodes"][lastCommentId]["createdAt"] + # Select the last reply of the last comment + else: + author = discussion["comments"]["nodes"][lastCommentId]["replies"]["nodes"][lastReplyOnLastComment]["author"]["login"] + dateLastMessage = discussion["comments"]["nodes"][lastCommentId]["replies"]["nodes"][lastReplyOnLastComment]["createdAt"] + + authorAsList = [author] + + # Check if author is indeed a reviewer + if authorAsList in reviewer_logins: + #Check dates + if isToBeClosed(dateLastMessage) == True: + to_be_closed_discussion_number.append(discussion["number"]) + to_be_closed_discussion_id.append(discussion["id"]) + to_be_closed_discussion_author.append(discussionAuthor) + elif isToBeWarned(dateLastMessage) == True and author != "github-actions": + to_be_warned_discussion_number.append(discussion["number"]) + to_be_warned_discussion_id.append(discussion["id"]) + to_be_warned_discussion_author.append(discussionAuthor) + + + # save if request has another page to browse and its cursor pointers + has_next_page = data["data"]["repository"]["discussions"]["pageInfo"]["hasNextPage"] + after_cursor = data["data"]["repository"]["discussions"]["pageInfo"]["endCursor"] + return [to_be_warned_discussion_number,to_be_warned_discussion_id,to_be_warned_discussion_author,to_be_closed_discussion_number,to_be_closed_discussion_id,to_be_closed_discussion_author] + + +# Query to access all discussions +def make_query_discussions(owner, name, after_cursor=None): + query = """ + query { + repository(owner: "%s" name: "%s") { + discussions(answered: false, first: 10, after:AFTER) { + totalCount + pageInfo { + hasNextPage + endCursor + } + nodes { + id + number + authorAssociation + author { + login + } + answer { + body + } + comments (first: 100) { + nodes { + createdAt + author { + login + } + replies (first: 100) { + nodes { + createdAt + author { + login + } + } + } + } + } + } + } + } + }""" % (owner, name) + return query.replace("AFTER", '"{}"'.format(after_cursor) if after_cursor else "null") + + + + +def make_github_warning_comment(discussion_id, discussion_author): + message = ":warning: :warning: :warning:
@"+str(discussion_author)+"
Feedback has been given to you by the project reviewers, however we have not received a response from you. Without further news in the coming weeks, this discussion will be automatically closed in order to keep this forum clean and fresh :seedling: Thank you for your understanding" + + query = """ + mutation { + addDiscussionComment(input: {body: "%s", discussionId: "%s"}) { + comment { + id + } + } + } +""" % (message, discussion_id) + return query + + + +def make_github_closing_comment(discussion_id, discussion_author): + message = ":warning: :warning: :warning:
@"+str(discussion_author)+"
In accordance with our forum management policy, the last reply is more than 4 months old and is therefore closed. Our objective is to keep the forum up to date and offer the best support experience.

Please feel free to reopen it if the topic is still active by providing us with an update. Please feel free to open a new thread at any time - we'll be happy to help where and when we can." + + query = """ + mutation { + addDiscussionComment(input: {body: "%s", discussionId: "%s"}) { + comment { + id + } + } + } +""" % (message, discussion_id) + return query + +def close_github_discussion(discussion_id): + + query = """ + mutation { + closeDiscussion(input: {discussionId: "%s"}) { + discussion { + id + } + } + } +""" % (discussion_id) + return + + +# ------- TO REMOVE !!!! --------- +def temporary_github_closing_comment(discussion_id, discussion_author): + message = ":warning: :warning: :warning:
@"+str(discussion_author)+"
We are setting a new forum management policy: topics like this one, in which the last reply is more than 4 months old, will automatically be closed. Without further news in the coming weeks, our bot will proceed to automatic closure, thus keeping this forum clean and fresh :seedling: Thank you for your understanding" + + query = """ + mutation { + addDiscussionComment(input: {body: "%s", discussionId: "%s"}) { + comment { + id + } + } + } +""" % (message, discussion_id) + return query +# -------------------------------- + + + + +#========================================================== +# STEPS computed by the script +#========================================================== +# 1 - get the discussion to be warned and closed +result = computeListOfDiscussionToProcess() +to_be_warned_discussion_number = result[0] +to_be_warned_discussion_id = result[1] +to_be_warned_discussion_author = result[2] +to_be_closed_discussion_number = result[3] +to_be_closed_discussion_id = result[4] +to_be_closed_discussion_author = result[5] +#========================================================== +# 2- do it using github API +if(len(to_be_warned_discussion_id)!=len(to_be_warned_discussion_author)): + print('Error: size of both vectors number/author for discussions to be warned is different') + exit(1) +if(len(to_be_closed_discussion_id)!=len(to_be_closed_discussion_author)): + print('Error: size of both vectors number/author for discussions to be closed is different') + exit(1) + +print("** Output lists **") +print("******************") +print("to_be_warned_discussion_number = "+str(to_be_warned_discussion_number) +print("to_be_warned_discussion_id = "+str(to_be_warned_discussion_id) +print("to_be_warned_discussion_author = "+str(to_be_warned_discussion_author) +print("to_be_closed_discussion_number = "+str(to_be_closed_discussion_number) +print("to_be_closed_discussion_id = "+str(to_be_closed_discussion_id) +print("to_be_closed_discussion_author = "+str(to_be_closed_discussion_author) +print("******************") + +#========================================================== +# WARNING step +for index, discussion_id in enumerate(to_be_warned_discussion_id): + print("to_be_warned_discussion_number[index] = "+str(to_be_warned_discussion_number[index])) + print("to_be_warned_discussion_author[index] = "+str(to_be_warned_discussion_author[index])) + print("discussion_id = "+str(discussion_id)) + # Warning comment + data = client.execute( + query = make_github_warning_comment( discussion_id, to_be_warned_discussion_author[index] ), + headers = {"Authorization": "Bearer {}".format(github_token)}, + ) + print(data) + break# ------- TO REMOVE !!!! + + +#========================================================== +# CLOSING step +# ------- TO REMOVE !!!! --------- +date_today = date.today() +date_end_temporary_message = date.fromisoformat('2023-12-01') +temporary_case = False + +if date_today > date_end_temporary_message: + temporary_case = False +else: + temporary_case = True + +if temporary_case: + print(str(date_end_temporary_message-date_today[:-9])+" days to go before end of temporary message") +# -------------------------------- + +for index, discussion_id in enumerate(to_be_closed_discussion_id): + print("to_be_closed_discussion_number[index] = "+str(to_be_closed_discussion_number[index])) + print("to_be_closed_discussion_author[index] = "+str(to_be_closed_discussion_author[index])) + print("discussion_id = "+str(discussion_id)) + # ------- TO REMOVE !!!! --------- + if temporary_case: + # Closing comment + data = client.execute( + query = temporary_github_closing_comment( discussion_id, to_be_closed_discussion_author[index] ), + headers = {"Authorization": "Bearer {}".format(github_token)}, + ) + print(data) + else: + # -------------------------------- + # Closing comment + data = client.execute( + query = make_github_closing_comment( discussion_id, to_be_closed_discussion_author[index] ), + headers = {"Authorization": "Bearer {}".format(github_token)}, + ) + print(data) + # Close discussion + data = client.execute( + query = close_github_discussion( discussion_id ), + headers = {"Authorization": "Bearer {}".format(github_token)}, + ) + print(data) + break# ------- TO REMOVE !!!! + +#========================================================== \ No newline at end of file From 9c9e377c7e148188e831d1617e9c3dec1ead4e91 Mon Sep 17 00:00:00 2001 From: Hugo Date: Mon, 11 Dec 2023 13:53:42 +0100 Subject: [PATCH 13/45] [github] quick fix for GHD script (#4347) --- scripts/comment-close-old-discussions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/comment-close-old-discussions.py b/scripts/comment-close-old-discussions.py index e7bb28baeed..a25dffd59f2 100644 --- a/scripts/comment-close-old-discussions.py +++ b/scripts/comment-close-old-discussions.py @@ -292,7 +292,7 @@ def temporary_github_closing_comment(discussion_id, discussion_author): # CLOSING step # ------- TO REMOVE !!!! --------- date_today = date.today() -date_end_temporary_message = date.fromisoformat('2023-12-01') +date_end_temporary_message = date.fromisoformat('2024-01-01') temporary_case = False if date_today > date_end_temporary_message: From 877035bc77309118dbd1a68b9fbf4171c7c65ebc Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Tue, 12 Dec 2023 05:52:37 +0100 Subject: [PATCH 14/45] [Haption] Partially fix the plugin (#4338) * [Haption] Partially fix the plugin CMake passes with SOFA-NG Fix some types and includes due to changes from SOFA-NG The plugin still does not compile * Add a readme file --- applications/plugins/Haption/CMakeLists.txt | 19 +++++++-- .../plugins/Haption/HaptionDriver.cpp | 40 +++++++++---------- applications/plugins/Haption/HaptionDriver.h | 40 +++++++++---------- applications/plugins/Haption/README.md | 7 ++++ 4 files changed, 62 insertions(+), 44 deletions(-) create mode 100644 applications/plugins/Haption/README.md diff --git a/applications/plugins/Haption/CMakeLists.txt b/applications/plugins/Haption/CMakeLists.txt index 21648d5ee44..a568175813b 100644 --- a/applications/plugins/Haption/CMakeLists.txt +++ b/applications/plugins/Haption/CMakeLists.txt @@ -1,8 +1,12 @@ cmake_minimum_required(VERSION 3.12) project(Haption) -find_package(SofaHaptics REQUIRED) -find_package(SofaOpenglVisual REQUIRED) +find_package(Sofa.Config REQUIRED) +sofa_find_package(Sofa.Component.Haptics REQUIRED) +sofa_find_package(Sofa.GL.Component.Rendering3D REQUIRED) +sofa_find_package(Sofa.Component.Mapping.NonLinear REQUIRED) +sofa_find_package(Sofa.Component.Controller REQUIRED) +sofa_find_package(Sofa.Component.StateContainer REQUIRED) set(HEADER_FILES HaptionDriver.h @@ -15,12 +19,19 @@ set(SOURCE_FILES ) set(README_FILES + README.md PluginHaption.txt ) -add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES}) +add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES} ${README_FILES}) set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-DSOFA_BUILD_HAPTIONPLUGIN") -target_link_libraries(${PROJECT_NAME} SofaHaptics SofaOpenglVisual) +target_link_libraries(${PROJECT_NAME} + Sofa.Component.Haptics + Sofa.GL.Component.Rendering3D + Sofa.Component.Mapping.NonLinear + Sofa.Component.Controller + Sofa.Component.StateContainer +) include_directories("${CMAKE_CURRENT_SOURCE_DIR}/..") install(TARGETS ${PROJECT_NAME} diff --git a/applications/plugins/Haption/HaptionDriver.cpp b/applications/plugins/Haption/HaptionDriver.cpp index fba135a7e31..adfbf1be9f9 100644 --- a/applications/plugins/Haption/HaptionDriver.cpp +++ b/applications/plugins/Haption/HaptionDriver.cpp @@ -43,11 +43,11 @@ void HaptionDriver::haptic_callback(VirtContext, void *param) virtGetAvatarPosition(data->m_virtContext, position); SolidTypes::Transform sofaWorld_H_Tool( - Vec3d(data->scale*position[0],data->scale*position[1],data->scale*position[2]), - Quat(position[3],position[4],position[5],position[6])); + type::Vec3d(data->scale*position[0],data->scale*position[1],data->scale*position[2]), + type::Quat(position[3],position[4],position[5],position[6])); - SolidTypes::SpatialVector Twist_tool_inWorld(Vec3d(0.0,0.0,0.0), Vec3d(0.0,0.0,0.0)); - SolidTypes::SpatialVector Wrench_tool_inWorld(Vec3d(0.0,0.0,0.0), Vec3d(0.0,0.0,0.0)); + SolidTypes::SpatialVector Twist_tool_inWorld(type::Vec3d(0.0,0.0,0.0), type::Vec3d(0.0,0.0,0.0)); + SolidTypes::SpatialVector Wrench_tool_inWorld(type::Vec3d(0.0,0.0,0.0), type::Vec3d(0.0,0.0,0.0)); if(data->forceFeedback != NULL) { @@ -169,7 +169,7 @@ void HaptionDriver::init() visuActif=true; } - visualHaptionDOF = new sofa::component::container::MechanicalObject(); + visualHaptionDOF = new sofa::component::statecontainer::MechanicalObject(); nodeHaptionVisual->addObject(visualHaptionDOF); visualHaptionDOF->name.setValue("rigidDOF"); @@ -186,7 +186,7 @@ void HaptionDriver::init() //context->addChild(nodeAxesVisual); //nodeAxesVisual->updateContext(); - visualAxesDOF = new sofa::component::container::MechanicalObject(); + visualAxesDOF = new sofa::component::statecontainer::MechanicalObject(); nodeAxesVisual->addObject(visualAxesDOF); visualAxesDOF->name.setValue("rigidDOF"); @@ -212,7 +212,7 @@ void HaptionDriver::init() visualNode[i].mapping = NULL; if(visualNode[i].visu == NULL && visualNode[i].mapping == NULL) { - visualNode[i].visu = new sofa::component::visualmodel::OglModel(); + visualNode[i].visu = new sofa::gl::component::rendering3d::OglModel(); visualNode[i].node->addObject(visualNode[i].visu); visualNode[i].visu->name.setValue("VisualParticles"); if(i==0) @@ -238,9 +238,9 @@ void HaptionDriver::init() visualNode[i].visu->initVisual(); visualNode[i].visu->updateVisual(); if(i<2) - visualNode[i].mapping = new sofa::component::mapping::RigidMapping< Rigid3dTypes, Vec3fTypes >(visualHaptionDOF,visualNode[i].visu); + visualNode[i].mapping = new sofa::component::mapping::nonlinear::RigidMapping< Rigid3dTypes, Vec3fTypes >(visualHaptionDOF,visualNode[i].visu); else - visualNode[i].mapping = new sofa::component::mapping::RigidMapping< Rigid3dTypes, Vec3fTypes >(visualAxesDOF,visualNode[i].visu); + visualNode[i].mapping = new sofa::component::mapping::nonlinear::RigidMapping< Rigid3dTypes, Vec3fTypes >(visualAxesDOF,visualNode[i].visu); visualNode[i].node->addObject(visualNode[i].mapping); visualNode[i].mapping->name.setValue("RigidMapping"); visualNode[i].mapping->f_mapConstraints.setValue(false); @@ -294,7 +294,7 @@ void HaptionDriver::bwdInit() simulation::Node *context = dynamic_cast(this->getContext()); - rigidDOF = context->get > (); + rigidDOF = context->get > (); if (rigidDOF==NULL) @@ -303,7 +303,7 @@ void HaptionDriver::bwdInit() } //search force feedback - MechanicalStateForceFeedback* ff = context->getTreeObject>(); + haptics::MechanicalStateForceFeedback* ff = context->getTreeObject>(); if(ff) { @@ -312,7 +312,7 @@ void HaptionDriver::bwdInit() } } -void HaptionDriver::setForceFeedback(MechanicalStateForceFeedback* ff) +void HaptionDriver::setForceFeedback(haptics::MechanicalStateForceFeedback* ff) { if(myData.forceFeedback == ff) { @@ -451,7 +451,7 @@ void HaptionDriver::onKeyPressedEvent(core::objectmodel::KeypressedEvent *kpe) if(modX || modY || modZ) { VecCoord& posB =(*posBase.beginEdit()); - posB[0].getCenter()+=posB[0].getOrientation().rotate(Vec3d(-(int)modX,-(int)modY,-(int)modZ)); + posB[0].getCenter()+=posB[0].getOrientation().rotate(type::Vec3d(-(int)modX,-(int)modY,-(int)modZ)); posBase.endEdit(); } else @@ -466,7 +466,7 @@ void HaptionDriver::onKeyPressedEvent(core::objectmodel::KeypressedEvent *kpe) if(modX || modY || modZ) { VecCoord& posB =(*posBase.beginEdit()); - posB[0].getCenter()+=posB[0].getOrientation().rotate(Vec3d((int)modX,(int)modY,(int)modZ)); + posB[0].getCenter()+=posB[0].getOrientation().rotate(type::Vec3d((int)modX,(int)modY,(int)modZ)); posBase.endEdit(); } else @@ -478,14 +478,14 @@ void HaptionDriver::onKeyPressedEvent(core::objectmodel::KeypressedEvent *kpe) else if ((kpe->getKey()==21) && (modX || modY || modZ)) //down { VecCoord& posB =(*posBase.beginEdit()); - sofa::type::Quat quarter_transform(Vec3d((int)modX,(int)modY,(int)modZ),-M_PI/50); + sofa::type::Quat quarter_transform(type::Vec3d((int)modX,(int)modY,(int)modZ),-M_PI/50); posB[0].getOrientation()*=quarter_transform; posBase.endEdit(); } else if ((kpe->getKey()==19) && (modX || modY || modZ)) //up { VecCoord& posB =(*posBase.beginEdit()); - sofa::type::Quat quarter_transform(Vec3d((int)modX,(int)modY,(int)modZ),+M_PI/50); + sofa::type::Quat quarter_transform(type::Vec3d((int)modX,(int)modY,(int)modZ),+M_PI/50); posB[0].getOrientation()*=quarter_transform; posBase.endEdit(); } @@ -558,8 +558,8 @@ void HaptionDriver::onAnimateBeginEvent() virtGetAvatarPosition(myData.m_virtContext, position); VecCoord& posR = (*rigidDOF->x0.beginEdit()); - posR[0].getCenter() = Vec3d(scale.getValue()*position[0],scale.getValue()*position[1],scale.getValue()*position[2]); - posR[0].getOrientation() = Quat(position[3],position[4],position[5],position[6]); + posR[0].getCenter() = type::Vec3d(scale.getValue()*position[0],scale.getValue()*position[1],scale.getValue()*position[2]); + posR[0].getOrientation() = type::Quat(position[3],position[4],position[5],position[6]); rigidDOF->x0.endEdit(); //button_state @@ -571,8 +571,8 @@ void HaptionDriver::onAnimateBeginEvent() if(visuActif) { VecCoord& posH = (*visualHaptionDOF->x.beginEdit()); - posH[1].getCenter() = Vec3d(scale.getValue()*position[0],scale.getValue()*position[1],scale.getValue()*position[2]); - posH[1].getOrientation() = Quat(position[3],position[4],position[5],position[6]); + posH[1].getCenter() = type::Vec3d(scale.getValue()*position[0],scale.getValue()*position[1],scale.getValue()*position[2]); + posH[1].getOrientation() = type::Quat(position[3],position[4],position[5],position[6]); visualHaptionDOF->x.endEdit(); } diff --git a/applications/plugins/Haption/HaptionDriver.h b/applications/plugins/Haption/HaptionDriver.h index 484a7d78b11..16586a777bf 100644 --- a/applications/plugins/Haption/HaptionDriver.h +++ b/applications/plugins/Haption/HaptionDriver.h @@ -29,15 +29,15 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include -#include +#include #include -#include -#include +#include +#include #include #include #include @@ -66,14 +66,14 @@ using core::objectmodel::Data; typedef struct { simulation::Node *node; - sofa::component::visualmodel::OglModel *visu; - sofa::component::mapping::RigidMapping< Rigid3dTypes , Vec3fTypes > *mapping; + sofa::gl::component::rendering3d::OglModel *visu; + sofa::component::mapping::nonlinear::RigidMapping< Rigid3dTypes , Vec3fTypes > *mapping; } VisualComponent; typedef struct { VirtContext m_virtContext; - MechanicalStateForceFeedback* forceFeedback; + haptics::MechanicalStateForceFeedback* forceFeedback; float scale; float torqueScale; float forceScale; @@ -98,19 +98,19 @@ class HaptionDriver : public Controller HaptionDriver(); virtual ~HaptionDriver(); - virtual void init(); - virtual void reinit(); - virtual void bwdInit(); - virtual void reset(); - virtual void handleEvent(core::objectmodel::Event *); - void onKeyPressedEvent(core::objectmodel::KeypressedEvent *); - void onKeyReleasedEvent(core::objectmodel::KeyreleasedEvent *); + void init() override; + void reinit() override; + void bwdInit() override; + void reset() override; + void handleEvent(core::objectmodel::Event *) override; + void onKeyPressedEvent(core::objectmodel::KeypressedEvent *) override; + void onKeyReleasedEvent(core::objectmodel::KeyreleasedEvent *) override; void onAnimateBeginEvent(); int initDevice(char* ip); void closeDevice(); static void haptic_callback(VirtContext, void *); - void setForceFeedback(MechanicalStateForceFeedback* ff); + void setForceFeedback(haptics::MechanicalStateForceFeedback* ff); private: @@ -121,12 +121,12 @@ class HaptionDriver : public Controller float m_forceFactor; float haptic_time_step; int connection_device; - sofa::component::container::MechanicalObject *rigidDOF; + sofa::component::statecontainer::MechanicalObject *rigidDOF; bool initCallback; simulation::Node *nodeHaptionVisual; - sofa::component::container::MechanicalObject *visualHaptionDOF; + sofa::component::statecontainer::MechanicalObject *visualHaptionDOF; simulation::Node *nodeAxesVisual; - sofa::component::container::MechanicalObject *visualAxesDOF; + sofa::component::statecontainer::MechanicalObject *visualAxesDOF; VisualComponent visualNode[5]; float oldScale; diff --git a/applications/plugins/Haption/README.md b/applications/plugins/Haption/README.md new file mode 100644 index 00000000000..d1184a4e3fd --- /dev/null +++ b/applications/plugins/Haption/README.md @@ -0,0 +1,7 @@ +# Haption + +SOFA plugin allowing the use a Haption's haptic device in a SOFA simulation. + +## Requirements + +The plugin relies on the [Virtuose API](https://www.haption.com/en/software-en/virtuose-en.html), which is not provided with the plugin. From 3249be864e6805a7cc347db890f7b44c325140a9 Mon Sep 17 00:00:00 2001 From: Olivier-Goury Date: Tue, 12 Dec 2023 10:15:53 +0100 Subject: [PATCH 15/45] [Topology] Check indices out-of-bound in TriangleSetTopologyContainer (#4242) * Check that triangles index match the size of the triangleAroundVertexArray (Like it is done in EdgeSetTopologyContainer for EdgeAroundVertexArray) * Fix some typos --- .../container/dynamic/EdgeSetTopologyContainer.cpp | 2 +- .../container/dynamic/TriangleSetTopologyContainer.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetTopologyContainer.cpp b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetTopologyContainer.cpp index 791d760f0f9..26f90cca3ca 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetTopologyContainer.cpp +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetTopologyContainer.cpp @@ -122,7 +122,7 @@ void EdgeSetTopologyContainer::createEdgesAroundVertexArray() if (edge[0] >= unsigned(nbPoints) || edge[1] >= unsigned(nbPoints)) { - msg_warning() << "EdgesAroundVertex creation failed, Edge buffer is not concistent with number of points: Edge: " << edge << " for: " << nbPoints << " points."; + msg_warning() << "EdgesAroundVertex creation failed, Edge buffer is not consistent with number of points, Edge: " << edge << " for: " << nbPoints << " points."; continue; } diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetTopologyContainer.cpp b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetTopologyContainer.cpp index 96b6d62727b..f7a81582eb8 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetTopologyContainer.cpp +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetTopologyContainer.cpp @@ -125,6 +125,13 @@ void TriangleSetTopologyContainer::createTrianglesAroundVertexArray() m_trianglesAroundVertex.resize(getNbPoints()); for (size_t i = 0; i < m_triangle.size(); ++i) { + if (m_triangle[i][0] >= getNbPoints() || m_triangle[i][1] >= getNbPoints() || m_triangle[i][2] >= getNbPoints()) + { + msg_warning() << "trianglesAroundVertex creation failed, Triangle buffer is not consistent with number of points, Triangle: " << m_triangle[i] << " for: " << getNbPoints() << " points."; + continue; + } + + // adding edge i in the edge shell of both points for (unsigned int j=0; j<3; ++j) m_trianglesAroundVertex[ m_triangle[i][j] ].push_back( (TriangleID)i ); From 4a40054c53e679a594966c927b5512e2e2159e4a Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Tue, 12 Dec 2023 18:53:10 +0900 Subject: [PATCH 16/45] [Type] Refactor Vec (#4296) * WIP * fix vecnoinit/vec, and constexpr init of array * add an other conversion for rgbacolor * correct aliases * fix tests compil * use correct type for getClosest * add compat for picking * polish * change type in image * remove superfluous typenames * no need to clear as it is already zero-init --- ...BarycentricMapperHexahedronSetTopology.inl | 2 +- .../linear/BarycentricMappingRigid.cpp | 2 +- .../fem/elastic/HexahedronFEMForceField.h | 2 +- .../fem/elastic/HexahedronFEMForceField.inl | 2 +- .../spring/JointSpringForceField.inl | 10 +- .../sofa/gui/common/ColourPickingVisitor.cpp | 37 ++++-- .../sofa/gui/common/ColourPickingVisitor.h | 16 ++- Sofa/GUI/Qt/src/sofa/gui/qt/GLPickHandler.cpp | 6 +- .../Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp | 4 +- .../GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h | 2 +- .../Topology/src/sofa/topology/Hexahedron.h | 2 +- .../Topology/test/Hexahedron_test.cpp | 2 +- .../Type/src/sofa/type/BoundingBox.cpp | 16 +-- .../Type/src/sofa/type/RGBAColor.cpp | 5 + Sofa/framework/Type/src/sofa/type/RGBAColor.h | 2 + Sofa/framework/Type/src/sofa/type/Vec.h | 118 ++++++++++++++++-- Sofa/framework/Type/test/Color_test.cpp | 2 +- applications/plugins/image/ImageAlgorithms.h | 20 +-- 18 files changed, 191 insertions(+), 59 deletions(-) diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappers/BarycentricMapperHexahedronSetTopology.inl b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappers/BarycentricMapperHexahedronSetTopology.inl index 302fc6f7fe1..1887f6e2fd3 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappers/BarycentricMapperHexahedronSetTopology.inl +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappers/BarycentricMapperHexahedronSetTopology.inl @@ -184,7 +184,7 @@ void BarycentricMapperHexahedronSetTopology::handleTopologyChange(core:: const auto j = *iter; if ( mapData[j].in_index == sofa::InvalidID ) // compute new mapping { - sofa::type::fixed_array coefs; + type::Vec3 coefs; typename In::Coord pos; pos[0] = mapData[j].baryCoords[0]; pos[1] = mapData[j].baryCoords[1]; diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappingRigid.cpp b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappingRigid.cpp index 35911c33c3c..212bd8a786f 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappingRigid.cpp +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappingRigid.cpp @@ -86,7 +86,7 @@ void BarycentricMapperHexahedronSetTopology coefs; + sofa::type::Vec3 coefs; defaulttype::Vec3Types::Coord pos; pos[0] = mapData[j].baryCoords[0]; pos[1] = mapData[j].baryCoords[1]; diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.h b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.h index 536c7f45172..14801c77b62 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.h +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.h @@ -195,7 +195,7 @@ class HexahedronFEMForceField : virtual public core::behavior::ForceFieldgetHexahedra()); } virtual void computeElementStiffness( ElementStiffness &K, const MaterialStiffness &M, - const type::fixed_array &nodes, const sofa::Index elementIndice, + const type::Vec<8, Coord> &nodes, const sofa::Index elementIndice, double stiffnessFactor=1.0) const; static Mat33 integrateStiffness( int signx0, int signy0, int signz0, int signx1, int signy1, int signz1, const Real u, const Real v, const Real w, const Mat33& J_1 ); diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.inl b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.inl index 63546fe2062..0cf9f338b26 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.inl +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.inl @@ -325,7 +325,7 @@ const typename HexahedronFEMForceField::Transformation& HexahedronFEM template -void HexahedronFEMForceField::computeElementStiffness( ElementStiffness &K, const MaterialStiffness &M, const type::fixed_array &nodes, const sofa::Index elementIndice, double stiffnessFactor) const +void HexahedronFEMForceField::computeElementStiffness( ElementStiffness &K, const MaterialStiffness &M, const type::Vec<8, Coord> &nodes, const sofa::Index elementIndice, double stiffnessFactor) const { const bool verbose = elementIndice==0; // X = n0 (1-x1)(1-x2)(1-x3)/8 + n1 (1+x1)(1-x2)(1-x3)/8 + n2 (1+x1)(1+x2)(1-x3)/8 + n3 (1-x1)(1+x2)(1-x3)/8 + n4 (1-x1)(1-x2)(1+x3)/8 + n5 (1+x1)(1-x2)(1+x3)/8 + n6 (1+x1)(1+x2)(1+x3)/8 + n7 (1-x1)(1+x2)(1+x3)/8 diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/JointSpringForceField.inl b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/JointSpringForceField.inl index e864065094a..8eba611bac6 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/JointSpringForceField.inl +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/JointSpringForceField.inl @@ -384,22 +384,22 @@ void JointSpringForceField::draw(const core::visual::VisualParams* vp for (sofa::Index i=0; i::min(); } -void decodeCollisionElement(const sofa::type::Vec4f colour, BodyPicked& body) +void decodeCollisionElement(const RGBAColor& colour, BodyPicked& body) { if( colour[0] > threshold || colour[1] > threshold || colour[2] > threshold ) // make sure we are not picking the background... @@ -70,7 +70,7 @@ void decodeCollisionElement(const sofa::type::Vec4f colour, BodyPicked& body) } -void decodePosition(BodyPicked& body, const sofa::type::Vec4f colour, const TriangleCollisionModel* model, +void decodePosition(BodyPicked& body, const RGBAColor& colour, const TriangleCollisionModel* model, const unsigned int index) { @@ -83,9 +83,11 @@ void decodePosition(BodyPicked& body, const sofa::type::Vec4f colour, const Tria } -void decodePosition(BodyPicked& body, const sofa::type::Vec4f /*colour*/, const SphereCollisionModel *model, +void decodePosition(BodyPicked& body, const RGBAColor& colour, const SphereCollisionModel *model, const unsigned int index) { + SOFA_UNUSED(colour); + const Sphere s(const_cast*>(model),index); body.point = s.center(); } @@ -97,6 +99,23 @@ simulation::Visitor::Result ColourPickingVisitor::processNodeTopDown(simulation: return RESULT_CONTINUE; } +void decodeCollisionElement(const sofa::type::Vec4f& colour, BodyPicked& body) +{ + decodeCollisionElement(sofa::type::RGBAColor::fromVec4(colour), body); +} + +void decodePosition(BodyPicked& body, const sofa::type::Vec4f& colour, const TriangleCollisionModel* model, + const unsigned int index) +{ + decodePosition(body, sofa::type::RGBAColor::fromVec4(colour), model, index); +} + +void decodePosition(BodyPicked& body, const sofa::type::Vec4f& colour, const SphereCollisionModel *model, + const unsigned int index) +{ + decodePosition(body, sofa::type::RGBAColor::fromVec4(colour), model, index); +} + void ColourPickingVisitor::processCollisionModel(simulation::Node* node , core::CollisionModel* o) { using namespace core::objectmodel; @@ -145,9 +164,9 @@ void ColourPickingVisitor::processTriangleModel(simulation::Node * node, sofa::c points.push_back( t.p1() ); points.push_back( t.p2() ); points.push_back( t.p3() ); - colours.push_back( Vec<4,float>(r,g,0,1) ); - colours.push_back( Vec<4,float>(r,g,0,1) ); - colours.push_back( Vec<4,float>(r,g,0,1) ); + colours.emplace_back( r,g,0,1 ); + colours.emplace_back( r,g,0,1 ); + colours.emplace_back( r,g,0,1 ); } break; case ENCODE_RELATIVEPOSITION: @@ -158,9 +177,9 @@ void ColourPickingVisitor::processTriangleModel(simulation::Node * node, sofa::c points.push_back( t.p1() ); points.push_back( t.p2() ); points.push_back( t.p3() ); - colours.push_back( Vec<4,float>(1,0,0,1) ); - colours.push_back( Vec<4,float>(0,1,0,1) ); - colours.push_back( Vec<4,float>(0,0,1,1) ); + colours.emplace_back( 1,0,0,1 ); + colours.emplace_back( 0,1,0,1 ); + colours.emplace_back( 0,0,1,1 ); } break; default: assert(false); diff --git a/Sofa/GUI/Common/src/sofa/gui/common/ColourPickingVisitor.h b/Sofa/GUI/Common/src/sofa/gui/common/ColourPickingVisitor.h index 2ad0d313b79..a49882953f6 100644 --- a/Sofa/GUI/Common/src/sofa/gui/common/ColourPickingVisitor.h +++ b/Sofa/GUI/Common/src/sofa/gui/common/ColourPickingVisitor.h @@ -29,10 +29,20 @@ namespace sofa::gui::common { -void SOFA_GUI_COMMON_API decodeCollisionElement( const sofa::type::Vec4f colour, sofa::gui::component::performer::BodyPicked& body ); -void SOFA_GUI_COMMON_API decodePosition( sofa::gui::component::performer::BodyPicked& body, const sofa::type::Vec4f colour, const sofa::component::collision::geometry::TriangleCollisionModel* model, +void SOFA_GUI_COMMON_API decodeCollisionElement( const type::RGBAColor& colour, sofa::gui::component::performer::BodyPicked& body ); +void SOFA_GUI_COMMON_API decodePosition( sofa::gui::component::performer::BodyPicked& body, const type::RGBAColor& colour, const sofa::component::collision::geometry::TriangleCollisionModel* model, const unsigned int index); -void SOFA_GUI_COMMON_API decodePosition( sofa::gui::component::performer::BodyPicked& body, const sofa::type::Vec4f colour, const sofa::component::collision::geometry::SphereCollisionModel* model, +void SOFA_GUI_COMMON_API decodePosition( sofa::gui::component::performer::BodyPicked& body, const type::RGBAColor& colour, const sofa::component::collision::geometry::SphereCollisionModel* model, + const unsigned int index); + +// compat +SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() +void SOFA_GUI_COMMON_API decodeCollisionElement( const sofa::type::Vec4f& colour, sofa::gui::component::performer::BodyPicked& body ); +SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() +void SOFA_GUI_COMMON_API decodePosition( sofa::gui::component::performer::BodyPicked& body, const sofa::type::Vec4f& colour, const sofa::component::collision::geometry::TriangleCollisionModel* model, + const unsigned int index); +SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() +void SOFA_GUI_COMMON_API decodePosition( sofa::gui::component::performer::BodyPicked& body, const sofa::type::Vec4f& colour, const sofa::component::collision::geometry::SphereCollisionModel* model, const unsigned int index); diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/GLPickHandler.cpp b/Sofa/GUI/Qt/src/sofa/gui/qt/GLPickHandler.cpp index c8fc4a28201..3a9c874eea1 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/GLPickHandler.cpp +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/GLPickHandler.cpp @@ -107,7 +107,7 @@ BodyPicked GLPickHandler::findCollisionUsingColourCoding(const type::Vec3& origi BodyPicked result; result.dist = 0; - sofa::type::Vec4f color; + type::RGBAColor color; const int x = mousePosition.x; const int y = mousePosition.screenHeight - mousePosition.y; TriangleCollisionModel* tmodel; @@ -116,10 +116,10 @@ BodyPicked GLPickHandler::findCollisionUsingColourCoding(const type::Vec3& origi if(renderCallback) { renderCallback->render(ColourPickingVisitor::ENCODE_COLLISIONELEMENT ); - glReadPixels(x,y,1,1,_fboParams.colorFormat,_fboParams.colorType,color.elems); + glReadPixels(x,y,1,1,_fboParams.colorFormat,_fboParams.colorType, &color[0]); decodeCollisionElement(color,result); renderCallback->render(ColourPickingVisitor::ENCODE_RELATIVEPOSITION ); - glReadPixels(x,y,1,1,_fboParams.colorFormat,_fboParams.colorType,color.elems); + glReadPixels(x,y,1,1,_fboParams.colorFormat,_fboParams.colorType, &color[0]); if( ( tmodel = dynamic_cast*>(result.body) ) != nullptr ) { decodePosition(result,color,tmodel,result.indexCollisionElement); diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp b/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp index 31bbb94cbe8..8148021a158 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp @@ -61,11 +61,11 @@ QRGBAColorPicker::QRGBAColorPicker(QWidget* parent) : QWidget(parent) connect( _colorButton, SIGNAL( clicked() ), this, SLOT( raiseQColorDialog() ) ); } -Vec4f QRGBAColorPicker::getColor() const +type::RGBAColor QRGBAColorPicker::getColor() const { typedef unsigned char uchar; constexpr uchar max = std::numeric_limits::max(); - Vec4f color; + type::RGBAColor color; float r = _r->text().toFloat(); float g = _g->text().toFloat(); float b = _b->text().toFloat(); diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h b/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h index 8c8fd37bd6f..684bae13677 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h @@ -61,7 +61,7 @@ class QRGBAColorPicker : public QWidget void setColor(const type::RGBAColor& color); void setColor( const Vec4f& color ); - Vec4f getColor() const; + type::RGBAColor getColor() const; protected: QRgb _rgba; diff --git a/Sofa/framework/Topology/src/sofa/topology/Hexahedron.h b/Sofa/framework/Topology/src/sofa/topology/Hexahedron.h index 873f2251461..619ac1ee282 100644 --- a/Sofa/framework/Topology/src/sofa/topology/Hexahedron.h +++ b/Sofa/framework/Topology/src/sofa/topology/Hexahedron.h @@ -32,7 +32,7 @@ namespace sofa::topology template static constexpr sofa::Index getClosestHexahedronIndex(const VectorCoordinates& hexahedronPositions, const sofa::type::vector& hexahedra, - const Coordinates& pos, sofa::type::fixed_array& barycentricCoefficients, SReal& distance) + const Coordinates& pos, type::Vec3& barycentricCoefficients, SReal& distance) { sofa::Index index = sofa::InvalidID; distance = std::numeric_limits::max(); diff --git a/Sofa/framework/Topology/test/Hexahedron_test.cpp b/Sofa/framework/Topology/test/Hexahedron_test.cpp index 240bcfcf75f..080a0858617 100644 --- a/Sofa/framework/Topology/test/Hexahedron_test.cpp +++ b/Sofa/framework/Topology/test/Hexahedron_test.cpp @@ -77,7 +77,7 @@ namespace sofa TEST(TopologyHexahedron_test, getClosestHexahedronIndex) { - sofa::type::fixed_array coeffs{}; + type::Vec3 coeffs{}; SReal distance{}; const sofa::type::Vec3d pos0{0.001, 0., 0.}; diff --git a/Sofa/framework/Type/src/sofa/type/BoundingBox.cpp b/Sofa/framework/Type/src/sofa/type/BoundingBox.cpp index 5baae9df773..08c9121191e 100644 --- a/Sofa/framework/Type/src/sofa/type/BoundingBox.cpp +++ b/Sofa/framework/Type/src/sofa/type/BoundingBox.cpp @@ -114,22 +114,22 @@ BoundingBox::operator bbox_t() const SReal* BoundingBox::minBBoxPtr() { - return bbox.first.elems; + return bbox.first.ptr(); } SReal* BoundingBox::maxBBoxPtr() { - return bbox.second.elems; + return bbox.second.ptr(); } const SReal* BoundingBox::minBBoxPtr() const { - return bbox.first.elems; + return bbox.first.ptr(); } const SReal* BoundingBox::maxBBoxPtr() const { - return bbox.second.elems; + return bbox.second.ptr(); } const sofa::type::Vec3& BoundingBox::minBBox() const @@ -360,22 +360,22 @@ BoundingBox2D::operator bbox_t() const SReal* BoundingBox2D::minBBoxPtr() { - return bbox.first.elems; + return bbox.first.ptr(); } SReal* BoundingBox2D::maxBBoxPtr() { - return bbox.second.elems; + return bbox.second.ptr(); } const SReal* BoundingBox2D::minBBoxPtr() const { - return bbox.first.elems; + return bbox.first.ptr(); } const SReal* BoundingBox2D::maxBBoxPtr() const { - return bbox.second.elems; + return bbox.second.ptr(); } const sofa::type::Vec<2, SReal>& BoundingBox2D::minBBox() const diff --git a/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp b/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp index 7e0e88208dd..3d01fc53646 100644 --- a/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp +++ b/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp @@ -91,6 +91,11 @@ RGBAColor::RGBAColor(const type::fixed_array& c) { } +RGBAColor::RGBAColor(const type::Vec4f& c) + : m_components{ c[0], c[1], c[2], c[3] } +{ +} + bool RGBAColor::read(const std::string& str, RGBAColor& color) { std::stringstream s(str); diff --git a/Sofa/framework/Type/src/sofa/type/RGBAColor.h b/Sofa/framework/Type/src/sofa/type/RGBAColor.h index 76a44dc3fb0..637b0c86ddb 100644 --- a/Sofa/framework/Type/src/sofa/type/RGBAColor.h +++ b/Sofa/framework/Type/src/sofa/type/RGBAColor.h @@ -60,6 +60,8 @@ class SOFA_TYPE_API RGBAColor // compat SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() RGBAColor(const type::fixed_array& c); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + RGBAColor(const type::Vec4f& c); SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() static RGBAColor fromVec4(const type::fixed_array& color); diff --git a/Sofa/framework/Type/src/sofa/type/Vec.h b/Sofa/framework/Type/src/sofa/type/Vec.h index e090a3d5e8f..7c1bd70928e 100644 --- a/Sofa/framework/Type/src/sofa/type/Vec.h +++ b/Sofa/framework/Type/src/sofa/type/Vec.h @@ -30,6 +30,7 @@ #include #include #include +#include #define EQUALITY_THRESHOLD 1e-6 @@ -54,13 +55,25 @@ struct NoInit {}; constexpr NoInit NOINIT; template < sofa::Size N, typename ValueType> -class Vec : public sofa::type::fixed_array +class Vec { - static_assert( N > 0, "" ); public: - typedef sofa::Size Size; + using ArrayType = std::array; + ArrayType elems{}; + + typedef sofa::Size Size; + typedef ValueType value_type; + typedef typename ArrayType::iterator iterator; + typedef typename ArrayType::const_iterator const_iterator; + typedef typename ArrayType::reference reference; + typedef typename ArrayType::const_reference const_reference; + typedef sofa::Size size_type; + typedef std::ptrdiff_t difference_type; + + static constexpr sofa::Size static_size = N; + static constexpr sofa::Size size() { return static_size; } /// Compile-time constant specifying the number of scalars within this vector (equivalent to static_size and size() method) static constexpr Size total_size = N; @@ -68,10 +81,7 @@ class Vec : public sofa::type::fixed_array static constexpr Size spatial_dimensions = N; /// Default constructor: sets all values to 0. - constexpr Vec() - { - this->clear(); - } + constexpr Vec() = default; /// Fast constructor: no initialization explicit constexpr Vec(NoInit) @@ -90,7 +100,7 @@ class Vec : public sofa::type::fixed_array typename = std::enable_if_t< (sizeof...(ArgsT) == N && sizeof...(ArgsT) > 1) > > constexpr Vec(ArgsT&&... r) noexcept - : sofa::type::fixed_array(std::forward(r)...) + : elems{ static_cast(std::forward< ArgsT >(r))... } {} /// Specific constructor for 6-elements vectors, taking two 3-elements vectors @@ -237,6 +247,13 @@ class Vec : public sofa::type::fixed_array this->elems[i] = (ValueType)v(i); } + // assign one value to all elements + constexpr void assign(const ValueType& value) noexcept + { + for (size_type i = 0; i < N; i++) + elems[i] = value; + } + /// Sets every element to 0. constexpr void clear() noexcept { @@ -264,13 +281,13 @@ class Vec : public sofa::type::fixed_array /// Cast into a const array of values. constexpr const ValueType* ptr() const noexcept { - return this->elems; + return this->elems.data(); } /// Cast into an array of values. constexpr ValueType* ptr() noexcept { - return this->elems; + return this->elems.data(); } // LINEAR ALGEBRA @@ -527,7 +544,7 @@ class Vec : public sofa::type::fixed_array /// return true if norm()==1 bool isNormalized( ValueType threshold=std::numeric_limits::epsilon()*(ValueType)10 ) const - { + { return rabs( norm2() - static_cast(1) ) <= threshold; } @@ -569,10 +586,66 @@ class Vec : public sofa::type::fixed_array return false; } + + // operator[] + constexpr reference operator[](size_type i) + { + assert(i < N && "index in Vec must be smaller than size"); + return elems[i]; + } + constexpr const_reference operator[](size_type i) const + { + assert(i < N && "index in Vec must be smaller than size"); + return elems[i]; + } + + // direct access to data + constexpr const ValueType* data() const noexcept + { + return elems.data(); + } + + constexpr iterator begin() noexcept + { + return elems.begin(); + } + constexpr const_iterator begin() const noexcept + { + return elems.begin(); + } + + constexpr iterator end() noexcept + { + return elems.end(); + } + constexpr const_iterator end() const noexcept + { + return elems.end(); + } + + constexpr reference front() + { + return elems[0]; + } + constexpr const_reference front() const + { + return elems[0]; + } + constexpr reference back() + { + return elems[N - 1]; + } + constexpr const_reference back() const + { + return elems[N - 1]; + } + /// @} }; + + /// Same as Vec except the values are not initialized by default template class VecNoInit : public Vec @@ -581,6 +654,15 @@ class VecNoInit : public Vec constexpr VecNoInit() noexcept : Vec(NOINIT) {} + + constexpr VecNoInit(const Vec& v) noexcept + : Vec(v) + {} + + constexpr VecNoInit(Vec&& v) noexcept + : Vec(v) + {} + using Vec::Vec; using Vec::operator=; // make every = from Vec available @@ -648,6 +730,20 @@ constexpr Vec operator*(const float& a, const Vec& V) noexcept return V * a; } +/// Checks if v1 is lexicographically less than v2. Similar to std::lexicographical_compare +template +constexpr bool operator<(const Vec& v1, const Vec& v2) noexcept +{ + for (sofa::Size i = 0; i < N; i++) + { + if (v1[i] < v2[i]) + return true; + if (v2[i] < v1[i]) + return false; + } + return false; +} + } // namespace sofa::type // Specialization of the std comparison function, to use Vec as std::map key diff --git a/Sofa/framework/Type/test/Color_test.cpp b/Sofa/framework/Type/test/Color_test.cpp index c4b062879ba..3e722c8d03a 100644 --- a/Sofa/framework/Type/test/Color_test.cpp +++ b/Sofa/framework/Type/test/Color_test.cpp @@ -142,7 +142,7 @@ void Color_Test::checkCreateFromDouble() void Color_Test::checkConstructors() { - EXPECT_EQ(RGBAColor(std::array{1, 2, 3, 4}), RGBAColor(1, 2, 3, 4)); + EXPECT_EQ( RGBAColor(std::array{1, 2, 3, 4}), RGBAColor(1, 2, 3, 4)); EXPECT_EQ( RGBAColor(sofa::type::Vec<4, float>(1, 2, 3, 4)), RGBAColor(1, 2, 3, 4)); } diff --git a/applications/plugins/image/ImageAlgorithms.h b/applications/plugins/image/ImageAlgorithms.h index 3fed474aae1..b29d85b475d 100644 --- a/applications/plugins/image/ImageAlgorithms.h +++ b/applications/plugins/image/ImageAlgorithms.h @@ -300,7 +300,7 @@ real norm(cimg_library::CImg& distances, sofa::type::fixed_array& /// @brief Replace value at oldCoord with a combinaison of value at newCoord, a offset and a bias if provided template void replace(cimg_library::CImg& voronoi, cimg_library::CImg& distances, sofa::type::fixed_array& oldCoord, sofa::type::fixed_array& newCoord, - sofa::type::fixed_array& offset, const sofa::type::fixed_array& voxelSize, const cimg_library::CImg* bias) + sofa::type::fixed_array& offset, const sofa::type::Vec<3, real>& voxelSize, const cimg_library::CImg* bias) { real b=1.0; if(bias) @@ -313,7 +313,7 @@ void replace(cimg_library::CImg& voronoi, cimg_library::CImg /// @brief Update value of the pixel of an image after comparing it with its neighbor template -void update(cimg_library::CImg& distances, cimg_library::CImg& voronoi, sofa::type::fixed_array< sofa::type::fixed_array, 10 >& coord, sofa::type::fixed_array< sofa::type::fixed_array, 10 >& offset, const sofa::type::fixed_array& voxelSize, const cimg_library::CImg* bias) +void update(cimg_library::CImg& distances, cimg_library::CImg& voronoi, sofa::type::fixed_array< sofa::type::fixed_array, 10 >& coord, sofa::type::fixed_array< sofa::type::fixed_array, 10 >& offset, const sofa::type::Vec<3, real>& voxelSize, const cimg_library::CImg* bias) { real l_curr=norm(distances,coord[0]); for(int l=1; l<=9; ++l) @@ -348,7 +348,7 @@ bool hasConverged(cimg_library::CImg& previous, cimg_library::CImg& /// @brief Perform a raster scan from left to right to update distances template -void left(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::fixed_array& vx, const cimg_library::CImg* bias) +void left(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::Vec<3, real>& vx, const cimg_library::CImg* bias) { for(int i=d.width()-2; i>=0; --i) { @@ -375,7 +375,7 @@ void left(cimg_library::CImg& v, cimg_library::CImg& d, cons /// @brief Perform a raster scan from right to left to update distances template -void right(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::fixed_array& vx, const cimg_library::CImg* bias) +void right(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::Vec<3, real>& vx, const cimg_library::CImg* bias) { for(int i=1; i& v, cimg_library::CImg& d, con /// @brief Perform a raster scan from down to up to update distances template -void down(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::fixed_array& vx, const cimg_library::CImg* bias) +void down(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::Vec<3, real>& vx, const cimg_library::CImg* bias) { for(int j=d.height()-2; j>=0; --j) { @@ -429,7 +429,7 @@ void down(cimg_library::CImg& v, cimg_library::CImg& d, cons /// @brief Perform a raster scan from up to down to update distances template -void up(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::fixed_array& vx, const cimg_library::CImg* bias) +void up(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::Vec<3, real>& vx, const cimg_library::CImg* bias) { for(int j=1; j& v, cimg_library::CImg& d, const /// @brief Perform a raster scan from backward to forward to update distances template -void backward(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::fixed_array& vx, const cimg_library::CImg* bias) +void backward(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::Vec<3, real>& vx, const cimg_library::CImg* bias) { for(int k=d.depth()-2; k>=0; --k) { @@ -483,7 +483,7 @@ void backward(cimg_library::CImg& v, cimg_library::CImg& d, /// @brief Perform a raster scan from forward to backward to update distances template -void forward(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::fixed_array& vx, const cimg_library::CImg* bias) +void forward(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::Vec<3, real>& vx, const cimg_library::CImg* bias) { for(int k=1; k& v, cimg_library::CImg& d, c /// @brief Perform 6 raster scan of an image to fully cover it. template -void rasterScan(cimg_library::CImg& voronoi, cimg_library::CImg& distances, const sofa::type::fixed_array& voxelSize, const cimg_library::CImg* biasFactor=NULL) +void rasterScan(cimg_library::CImg& voronoi, cimg_library::CImg& distances, const sofa::type::Vec<3, real>& voxelSize, const cimg_library::CImg* biasFactor=NULL) { right(voronoi, distances, voxelSize, biasFactor); left(voronoi, distances, voxelSize, biasFactor); @@ -528,7 +528,7 @@ void rasterScan(cimg_library::CImg& voronoi, cimg_library::CImg -void parallelMarching(cimg_library::CImg& distances, cimg_library::CImg& voronoi, const sofa::type::fixed_array& voxelSize, const unsigned int maxIter=std::numeric_limits::max(), const SReal tolerance=10, const cimg_library::CImg* biasFactor=NULL) +void parallelMarching(cimg_library::CImg& distances, cimg_library::CImg& voronoi, const sofa::type::Vec<3, real>& voxelSize, const unsigned int maxIter=std::numeric_limits::max(), const SReal tolerance=10, const cimg_library::CImg* biasFactor=NULL) { if(distances.width()<3 || distances.height()<3 || distances.depth()<3) { From 9792d3d8a5ac1a2bf4406489d46fb8edf085e6ae Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Wed, 13 Dec 2023 23:05:49 +0900 Subject: [PATCH 17/45] [Simulation.Core] Remove usage of ill-used nodeData in MechanicalGetNonDiagonalMassesCountVisitor and MechanicalVDotVisitor (#4328) * remove ill-used nodedata for nondiagmass visitor * remove ill-used nodedata for vdot visitor * set to const ptr * replace result type by an integer * add keyword for lifecycle --- .../component/odesolver/forward/EulerSolver.cpp | 2 +- .../MechanicalGetNonDiagonalMassesCountVisitor.cpp | 6 +++++- .../MechanicalGetNonDiagonalMassesCountVisitor.h | 13 ++++++++----- .../mechanicalvisitor/MechanicalVDotVisitor.cpp | 6 ++++-- .../mechanicalvisitor/MechanicalVDotVisitor.h | 7 ++++--- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp index 97fb91c7c88..7681f7b5fb9 100644 --- a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp +++ b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp @@ -76,7 +76,7 @@ void EulerExplicitSolver::solve(const core::ExecParams* params, addSeparateGravity(&mop, dt, vResult); computeForce(&mop, f); - SReal nbNonDiagonalMasses = 0; + sofa::Size nbNonDiagonalMasses = 0; MechanicalGetNonDiagonalMassesCountVisitor(&mop.mparams, &nbNonDiagonalMasses).execute(this->getContext()); // Mass matrix is diagonal, solution can thus be found by computing acc = f/m diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalGetNonDiagonalMassesCountVisitor.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalGetNonDiagonalMassesCountVisitor.cpp index 46dcaa06907..321aa0e5e7a 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalGetNonDiagonalMassesCountVisitor.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalGetNonDiagonalMassesCountVisitor.cpp @@ -27,7 +27,11 @@ namespace sofa::simulation::mechanicalvisitor Visitor::Result MechanicalGetNonDiagonalMassesCountVisitor::fwdMass(VisitorContext* ctx, core::behavior::BaseMass* mass) { - *ctx->nodeData += !mass->isDiagonal(); + SOFA_UNUSED(ctx); + + if(this->m_nbNonDiagonalMassesPtr && !mass->isDiagonal()) + (*m_nbNonDiagonalMassesPtr)++; + return RESULT_CONTINUE; } diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalGetNonDiagonalMassesCountVisitor.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalGetNonDiagonalMassesCountVisitor.h index cbe37f6c740..6053eb36900 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalGetNonDiagonalMassesCountVisitor.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalGetNonDiagonalMassesCountVisitor.h @@ -30,10 +30,14 @@ namespace sofa::simulation::mechanicalvisitor class SOFA_SIMULATION_CORE_API MechanicalGetNonDiagonalMassesCountVisitor : public MechanicalVisitor { public: - MechanicalGetNonDiagonalMassesCountVisitor(const sofa::core::MechanicalParams* mparams, SReal* result) - : MechanicalVisitor(mparams) + sofa::Size* const m_nbNonDiagonalMassesPtr { nullptr }; + + // SOFA_ATTRIBUTE_DISABLED("v24.06", "v24.12", "given result is not a Real anymore since https://github.com/sofa-framework/sofa/pull/4328") + MechanicalGetNonDiagonalMassesCountVisitor(const sofa::core::MechanicalParams* mparams, SReal* result) = delete; + + MechanicalGetNonDiagonalMassesCountVisitor(const sofa::core::MechanicalParams* mparams, sofa::Size* result) + : MechanicalVisitor(mparams), m_nbNonDiagonalMassesPtr(result) { - rootData = result; } Result fwdMass(VisitorContext* ctx, sofa::core::behavior::BaseMass* mass) override; @@ -46,7 +50,6 @@ class SOFA_SIMULATION_CORE_API MechanicalGetNonDiagonalMassesCountVisitor : publ { return true; } - }; -} \ No newline at end of file +} diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVDotVisitor.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVDotVisitor.cpp index 760ed560a9e..fed001bfd58 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVDotVisitor.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVDotVisitor.cpp @@ -29,7 +29,9 @@ namespace sofa::simulation::mechanicalvisitor Visitor::Result MechanicalVDotVisitor::fwdMechanicalState(VisitorContext* ctx, core::behavior::BaseMechanicalState* mm) { - *ctx->nodeData += mm->vDot(this->params, a.getId(mm),b.getId(mm) ); + if(m_total) + *m_total += mm->vDot(this->params, a.getId(mm),b.getId(mm) ); + return RESULT_CONTINUE; } @@ -40,4 +42,4 @@ std::string MechanicalVDotVisitor::getInfos() const return name; } -} \ No newline at end of file +} diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVDotVisitor.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVDotVisitor.h index 30d855a3a1b..837ee617d86 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVDotVisitor.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVDotVisitor.h @@ -32,13 +32,14 @@ class SOFA_SIMULATION_CORE_API MechanicalVDotVisitor : public BaseMechanicalVisi public: sofa::core::ConstMultiVecId a; sofa::core::ConstMultiVecId b; + SReal* const m_total { nullptr }; + MechanicalVDotVisitor(const sofa::core::ExecParams* params, sofa::core::ConstMultiVecId a, sofa::core::ConstMultiVecId b, SReal* t) - : BaseMechanicalVisitor(params) , a(a), b(b) //, total(t) + : BaseMechanicalVisitor(params) , a(a), b(b), m_total(t) { #ifdef SOFA_DUMP_VISITOR_INFO setReadWriteVectors(); #endif - rootData = t; } Result fwdMechanicalState(VisitorContext* ctx,sofa::core::behavior::BaseMechanicalState* mm) override; @@ -65,4 +66,4 @@ class SOFA_SIMULATION_CORE_API MechanicalVDotVisitor : public BaseMechanicalVisi } #endif }; -} \ No newline at end of file +} From 4a3db69b544139c7e23064aaa0afefd264fccdaf Mon Sep 17 00:00:00 2001 From: Hugo Date: Wed, 13 Dec 2023 15:08:46 +0100 Subject: [PATCH 18/45] [github] fix stale action (#4348) * [github] fix stale action * Remove breaks to apply on ALL topics * add missing filter to avoid writing in answered or closed topics --- scripts/comment-close-old-discussions.py | 37 +++++++++++++++--------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/scripts/comment-close-old-discussions.py b/scripts/comment-close-old-discussions.py index a25dffd59f2..00acbfb3dae 100644 --- a/scripts/comment-close-old-discussions.py +++ b/scripts/comment-close-old-discussions.py @@ -7,9 +7,6 @@ #TEST steps: -# - add cron & dispatch trigger, remove trigger on label changes (yml) -# - test with only one entry (break) -# - remove break # - after 1st of December 2023, remove the temporary layer import os @@ -98,8 +95,9 @@ def computeListOfDiscussionToProcess(): # Detect the last comment lastCommentId = len(discussion["comments"]["nodes"]) - 1 - # Pass to the next discussion item, if no comment in the discussion - if(lastCommentId < 0): + # Pass to the next discussion item if : + # no comment in the discussion OR discussion is answered OR closed + if(lastCommentId < 0 or discussion["closed"] == True or discussion["isAnswered"] == True ): continue lastReplyOnLastComment = len(discussion["comments"]["nodes"][lastCommentId]["replies"]["nodes"]) - 1 @@ -148,6 +146,8 @@ def make_query_discussions(owner, name, after_cursor=None): nodes { id number + isAnswered + closed authorAssociation author { login @@ -265,16 +265,22 @@ def temporary_github_closing_comment(discussion_id, discussion_author): print("** Output lists **") print("******************") -print("to_be_warned_discussion_number = "+str(to_be_warned_discussion_number) -print("to_be_warned_discussion_id = "+str(to_be_warned_discussion_id) -print("to_be_warned_discussion_author = "+str(to_be_warned_discussion_author) -print("to_be_closed_discussion_number = "+str(to_be_closed_discussion_number) -print("to_be_closed_discussion_id = "+str(to_be_closed_discussion_id) -print("to_be_closed_discussion_author = "+str(to_be_closed_discussion_author) +print("Nb discussions to be WARNED = "+str(len(to_be_warned_discussion_number))) +print("Nb discussions to be CLOSED = "+str(len(to_be_closed_discussion_number))) +print("******************") +print("to_be_warned_discussion_number = "+str(to_be_warned_discussion_number)) +print("to_be_warned_discussion_id = "+str(to_be_warned_discussion_id)) +print("to_be_warned_discussion_author = "+str(to_be_warned_discussion_author)) +print("******************") +print("to_be_closed_discussion_number = "+str(to_be_closed_discussion_number)) +print("to_be_closed_discussion_id = "+str(to_be_closed_discussion_id)) +print("to_be_closed_discussion_author = "+str(to_be_closed_discussion_author)) +print("******************") print("******************") #========================================================== # WARNING step +print("** WARNING step **") for index, discussion_id in enumerate(to_be_warned_discussion_id): print("to_be_warned_discussion_number[index] = "+str(to_be_warned_discussion_number[index])) print("to_be_warned_discussion_author[index] = "+str(to_be_warned_discussion_author[index])) @@ -285,11 +291,14 @@ def temporary_github_closing_comment(discussion_id, discussion_author): headers = {"Authorization": "Bearer {}".format(github_token)}, ) print(data) - break# ------- TO REMOVE !!!! +print("******************") +print("******************") #========================================================== # CLOSING step +print("** CLOSING step **") + # ------- TO REMOVE !!!! --------- date_today = date.today() date_end_temporary_message = date.fromisoformat('2024-01-01') @@ -301,7 +310,8 @@ def temporary_github_closing_comment(discussion_id, discussion_author): temporary_case = True if temporary_case: - print(str(date_end_temporary_message-date_today[:-9])+" days to go before end of temporary message") + remaining_time = date_end_temporary_message-date_today + print(str(remaining_time)[:-9]+" days to go before end of temporary message") # -------------------------------- for index, discussion_id in enumerate(to_be_closed_discussion_id): @@ -330,6 +340,5 @@ def temporary_github_closing_comment(discussion_id, discussion_author): headers = {"Authorization": "Bearer {}".format(github_token)}, ) print(data) - break# ------- TO REMOVE !!!! #========================================================== \ No newline at end of file From 6ed9f8fe0b0016c6cee4e6691fe48fc2b391dd26 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Thu, 14 Dec 2023 04:34:36 +0100 Subject: [PATCH 19/45] [LinearAlgebra] Use class template argument deduction with MatrixExpr (#4351) --- .../CompressedRowSparseMatrixMechanical.h | 10 +++--- .../src/sofa/linearalgebra/DiagonalMatrix.h | 10 +++--- .../src/sofa/linearalgebra/MatrixExpr.h | 33 +++++++++++-------- .../src/sofa/linearalgebra/SparseMatrix.h | 12 +++---- 4 files changed, 35 insertions(+), 30 deletions(-) diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixMechanical.h b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixMechanical.h index bacbdbada0d..93f6df95d12 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixMechanical.h +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixMechanical.h @@ -1311,7 +1311,7 @@ class CompressedRowSparseMatrixMechanical final // final is used to allow the co template void operator-=(const CompressedRowSparseMatrixMechanical& m) { - equal(MatrixExpr< MatrixNegative< CompressedRowSparseMatrixMechanical > >(MatrixNegative< CompressedRowSparseMatrixMechanical >(m)), true); + equal(MatrixExpr { MatrixNegative< CompressedRowSparseMatrixMechanical >(m) }, true); } template @@ -1329,23 +1329,23 @@ class CompressedRowSparseMatrixMechanical final // final is used to allow the co template void operator-=(const MatrixExpr< Expr2 >& m) { - addEqual(MatrixExpr< MatrixNegative< Expr2 > >(MatrixNegative< Expr2 >(m))); + addEqual(MatrixExpr{ MatrixNegative< Expr2 >(m) } ); } MatrixExpr< MatrixTranspose< Matrix > > t() const { - return MatrixExpr< MatrixTranspose< Matrix > >(MatrixTranspose< Matrix >(*this)); + return MatrixExpr{ MatrixTranspose< Matrix >{*this} }; } MatrixExpr< MatrixNegative< Matrix > > operator-() const { - return MatrixExpr< MatrixNegative< Matrix > >(MatrixNegative< Matrix >(*this)); + return MatrixExpr{ MatrixNegative< Matrix >(*this) }; } MatrixExpr< MatrixScale< Matrix, double > > operator*(const double& r) const { - return MatrixExpr< MatrixScale< Matrix, double > >(MatrixScale< Matrix, double >(*this, r)); + return MatrixExpr{ MatrixScale< Matrix, double >(*this, r) }; } diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/DiagonalMatrix.h b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/DiagonalMatrix.h index d1657a96455..65e66c640c7 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/DiagonalMatrix.h +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/DiagonalMatrix.h @@ -283,27 +283,27 @@ class DiagonalMatrix : public linearalgebra::BaseMatrix template void operator-=(const MatrixExpr< Expr2 >& m) { - addEqual(MatrixExpr< MatrixNegative< Expr2 > >(MatrixNegative< Expr2 >(m))); + addEqual(MatrixExpr { MatrixNegative< Expr2 >(m) } ); } MatrixExpr< MatrixTranspose< DiagonalMatrix > > t() const { - return MatrixExpr< MatrixTranspose< DiagonalMatrix > >(MatrixTranspose< DiagonalMatrix >(*this)); + return MatrixExpr { MatrixTranspose< DiagonalMatrix >(*this) }; } MatrixExpr< MatrixInverse< DiagonalMatrix > > i() const { - return MatrixExpr< MatrixInverse< DiagonalMatrix > >(MatrixInverse< DiagonalMatrix >(*this)); + return MatrixExpr { MatrixInverse< DiagonalMatrix >(*this) }; } MatrixExpr< MatrixNegative< DiagonalMatrix > > operator-() const { - return MatrixExpr< MatrixNegative< DiagonalMatrix > >(MatrixNegative< DiagonalMatrix >(*this)); + return MatrixExpr { MatrixNegative< DiagonalMatrix >(*this) }; } MatrixExpr< MatrixScale< DiagonalMatrix, double > > operator*(const double& r) const { - return MatrixExpr< MatrixScale< DiagonalMatrix, double > >(MatrixScale< DiagonalMatrix, double >(*this, r)); + return MatrixExpr { MatrixScale< DiagonalMatrix, double >(*this, r) }; } friend std::ostream& operator << (std::ostream& out, const DiagonalMatrix& v ) diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/MatrixExpr.h b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/MatrixExpr.h index 569e324648c..bc828e0c30c 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/MatrixExpr.h +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/MatrixExpr.h @@ -45,60 +45,62 @@ class MatrixNegative; template class MatrixScale; +/// Data structure representing an operation on matrices. Used in the context of +/// the expression templates pattern. template class MatrixExpr : public T { public: typedef T Expr; - MatrixExpr(const Expr& e) : Expr(e) {} + explicit MatrixExpr(const Expr& e) : Expr(e) {} template MatrixExpr< MatrixProduct< Expr, typename M2::Expr > > operator*(const M2& m) const { - return MatrixExpr< MatrixProduct< Expr, typename M2::Expr > >(MatrixProduct< Expr, typename M2::Expr >(*this, m)); + return MatrixExpr { MatrixProduct< Expr, typename M2::Expr >(*this, m) }; } template MatrixExpr< MatrixAddition< Expr, typename M2::Expr > > operator+(const M2& m) const { - return MatrixExpr< MatrixAddition< Expr, typename M2::Expr > >(MatrixAddition< Expr, typename M2::Expr >(*this, m)); + return MatrixExpr { MatrixAddition< Expr, typename M2::Expr >(*this, m) }; } template MatrixExpr< MatrixSubstraction< Expr, typename M2::Expr > > operator-(const M2& m) const { - return MatrixExpr< MatrixSubstraction< Expr, typename M2::Expr > >(MatrixSubstraction< Expr, typename M2::Expr >(*this, m)); + return MatrixExpr { MatrixSubstraction< Expr, typename M2::Expr >(*this, m) }; } MatrixExpr< MatrixNegative< Expr > > operator-() const { - return MatrixExpr< MatrixNegative< Expr > >(MatrixNegative< Expr >(*this)); + return MatrixExpr { MatrixNegative< Expr >(*this) }; } MatrixExpr< MatrixTranspose< Expr > > t() const { - return MatrixExpr< MatrixTranspose< Expr > >(MatrixTranspose< Expr >(*this)); + return MatrixExpr { MatrixTranspose< Expr >(*this) }; } MatrixExpr< MatrixScale< Expr, double > > operator*(double d) const { - return MatrixExpr< MatrixScale< Expr, double > >(MatrixScale< Expr, double >(*this, d)); + return MatrixExpr { MatrixScale< Expr, double >(*this, d) }; } friend MatrixExpr< MatrixScale< Expr, double > > operator*(double d, const MatrixExpr& m) { - return MatrixExpr< MatrixScale< Expr, double > >(MatrixScale< Expr, double >(m, d)); + return MatrixExpr { MatrixScale< Expr, double >(m, d) }; } template friend MatrixExpr< MatrixProduct< typename M1::Expr, Expr > > operator*(const M1& m1, const MatrixExpr& m2) { - return MatrixExpr< MatrixProduct< typename M1::Expr, Expr > >(MatrixProduct< typename M1::Expr, Expr >(m1,m2)); + return MatrixExpr { MatrixProduct< typename M1::Expr, Expr >(m1,m2) }; } template friend MatrixExpr< MatrixAddition< typename M1::Expr, Expr > > operator+(const M1& m1, const MatrixExpr& m2) { - return MatrixExpr< MatrixAddition< typename M1::Expr, Expr > >(MatrixAddition< typename M1::Expr, Expr >(m1,m2)); + return MatrixExpr { MatrixAddition< typename M1::Expr, Expr >(m1,m2) }; } template friend MatrixExpr< MatrixSubstraction< typename M1::Expr, Expr > > operator-(const M1& m1, const MatrixExpr& m2) { - return MatrixExpr< MatrixSubstraction< typename M1::Expr, Expr > >(MatrixSubstraction< typename M1::Expr, Expr >(m1,m2)); + return MatrixExpr { MatrixSubstraction< typename M1::Expr, Expr >(m1,m2) }; } }; @@ -216,7 +218,8 @@ class MatrixNegative typedef typename M1::matrix_type matrix_type; const M1& m1; - MatrixNegative(const M1& m1) : m1(m1) + + explicit MatrixNegative(const M1& m1) : m1(m1) {} bool valid() const @@ -274,7 +277,8 @@ class MatrixTranspose typedef typename M1::matrix_type matrix_type; const M1& m1; - MatrixTranspose(const M1& m1) : m1(m1) + + explicit MatrixTranspose(const M1& m1) : m1(m1) {} bool valid() const @@ -556,7 +560,8 @@ class MatrixInverse enum { operand = 0 }; const M1& m1; - MatrixInverse(const M1& m1) : m1(m1) + + explicit MatrixInverse(const M1& m1) : m1(m1) {} bool valid() const diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/SparseMatrix.h b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/SparseMatrix.h index 3c0d5462cc8..7c0e4e169d2 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/SparseMatrix.h +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/SparseMatrix.h @@ -331,35 +331,35 @@ class SparseMatrix : public linearalgebra::BaseMatrix MatrixExpr< MatrixTranspose< SparseMatrix > > t() const { - return MatrixExpr< MatrixTranspose< SparseMatrix > >(MatrixTranspose< SparseMatrix >(*this)); + return MatrixExpr { MatrixTranspose< SparseMatrix >(*this) }; } MatrixExpr< MatrixNegative< SparseMatrix > > operator-() const { - return MatrixExpr< MatrixNegative< SparseMatrix > >(MatrixNegative< SparseMatrix >(*this)); + return MatrixExpr { MatrixNegative< SparseMatrix >(*this) }; } template MatrixExpr< MatrixProduct< SparseMatrix, SparseMatrix > > operator*(const SparseMatrix& m) const { - return MatrixExpr< MatrixProduct< SparseMatrix, SparseMatrix > >(MatrixProduct< SparseMatrix, SparseMatrix >(*this, m)); + return MatrixExpr { MatrixProduct< SparseMatrix, SparseMatrix >(*this, m) }; } MatrixExpr< MatrixScale< SparseMatrix, double > > operator*(const double& r) const { - return MatrixExpr< MatrixScale< SparseMatrix, double > >(MatrixScale< SparseMatrix, double >(*this, r)); + return MatrixExpr { MatrixScale< SparseMatrix, double >(*this, r) }; } template MatrixExpr< MatrixAddition< SparseMatrix, SparseMatrix > > operator+(const SparseMatrix& m) const { - return MatrixExpr< MatrixAddition< SparseMatrix, SparseMatrix > >(MatrixAddition< SparseMatrix, SparseMatrix >(*this, m)); + return MatrixExpr { MatrixAddition< SparseMatrix, SparseMatrix >(*this, m) }; } template MatrixExpr< MatrixAddition< SparseMatrix, SparseMatrix > > operator-(const SparseMatrix& m) const { - return MatrixExpr< MatrixAddition< SparseMatrix, SparseMatrix > >(MatrixAddition< SparseMatrix, SparseMatrix >(*this, m)); + return MatrixExpr { MatrixAddition< SparseMatrix, SparseMatrix >(*this, m) }; } void swap(SparseMatrix& m) From 8774d298d49c66b9755fe309418117ff93bf8d34 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Thu, 14 Dec 2023 07:04:04 +0100 Subject: [PATCH 20/45] [LinearAlgebra] constexpr if statement when possible (#4352) * [LinearAlgebra] constexpr if statement when possible * Use structured binding --- .../src/sofa/linearalgebra/BaseMatrix.cpp | 152 ++++++++++-------- 1 file changed, 88 insertions(+), 64 deletions(-) diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BaseMatrix.cpp b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BaseMatrix.cpp index be01bdfc369..a6119f7b485 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BaseMatrix.cpp +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BaseMatrix.cpp @@ -29,7 +29,7 @@ namespace sofa::linearalgebra { -BaseMatrix::BaseMatrix() {} +BaseMatrix::BaseMatrix() = default; BaseMatrix::~BaseMatrix() {} @@ -64,20 +64,27 @@ struct BaseMatrixLinearOpMV_BlockDiagonal const Index colSize = mat->colSize(); BlockData buffer; - if (!add) - opVresize(result, (transpose ? colSize : rowSize)); - for (std::pair rowRange = mat->bRowsRange(); - rowRange.first != rowRange.second; - ++rowRange.first) + if constexpr (!add) + { + if constexpr (transpose) + { + opVresize(result, colSize); + } + else + { + opVresize(result, rowSize); + } + } + for (auto [rowIt, rowEnd] = mat->bRowsRange(); rowIt != rowEnd; ++rowIt) { - std::pair colRange = rowRange.first.range(); - if (colRange.first != colRange.second) // diagonal block exists + auto [colBegin, colEnd] = rowIt.range(); + if (colBegin != colEnd) // diagonal block exists { - BlockConstAccessor block = colRange.first.bloc(); + BlockConstAccessor block = colBegin.bloc(); const BlockData& bdata = *(const BlockData*)block.elements(buffer.ptr()); const Index i = block.getRow() * NL; const Index j = block.getCol() * NC; - if (!transpose) + if constexpr (!transpose) { type::VecNoInit vj; for (int bj = 0; bj < NC; ++bj) @@ -162,8 +169,17 @@ struct BaseMatrixLinearOpMV_BlockDiagonal { const Index rowSize = mat->rowSize(); const Index colSize = mat->colSize(); - if (!add) - opVresize(result, (transpose ? colSize : rowSize)); + if constexpr (!add) + { + if constexpr (transpose) + { + opVresize(result, colSize); + } + else + { + opVresize(result, rowSize); + } + } const Index size = (rowSize < colSize) ? rowSize : colSize; for (Index i=0; i vtmpj; type::Vec vtmpi; - if (!add) + if constexpr (!add) + { opVresize(result, (transpose ? colSize : rowSize)); - for (std::pair rowRange = mat->bRowsRange(); - rowRange.first != rowRange.second; - ++rowRange.first) + } + for (auto [rowIt, rowEnd] = mat->bRowsRange(); rowIt != rowEnd; ++rowIt) { - const Index i = rowRange.first.row() * NL; - if (!transpose) + const Index i = rowIt.row() * NL; + if constexpr (!transpose) { for (int bi = 0; bi < NL; ++bi) vtmpi[bi] = (Real)0; @@ -205,14 +221,12 @@ struct BaseMatrixLinearOpMV_BlockSparse for (int bi = 0; bi < NL; ++bi) vtmpi[bi] = (Real)opVget(v, i+bi); } - for (std::pair colRange = rowRange.first.range(); - colRange.first != colRange.second; - ++colRange.first) + for (auto [colIt, colEnd] = rowIt.range(); colIt != colEnd; ++colIt) { - BlockConstAccessor block = colRange.first.bloc(); + BlockConstAccessor block = colIt.bloc(); const BlockData& bdata = *(const BlockData*)block.elements(buffer.ptr()); const Index j = block.getCol() * NC; - if (!transpose) + if constexpr (!transpose) { for (int bj = 0; bj < NC; ++bj) vtmpj[bj] = (Real)opVget(v, j+bj); @@ -231,14 +245,11 @@ struct BaseMatrixLinearOpMV_BlockSparse opVadd(result, j+bj, vtmpj[bj]); } } - if (!transpose) + if constexpr (!transpose) { for (int bi = 0; bi < NL; ++bi) opVadd(result, i+bi, vtmpi[bi]); } - else - { - } } } }; @@ -253,9 +264,18 @@ class BaseMatrixLinearOpMV { const Index rowSize = mat->rowSize(); const Index colSize = mat->colSize(); - if (!add) - opVresize(result, (transpose ? colSize : rowSize)); - if (!transpose) + if constexpr (!add) + { + if constexpr (transpose) + { + opVresize(result, colSize); + } + else + { + opVresize(result, rowSize); + } + } + if constexpr (!transpose) { for (Index i=0; irowSize(); const Index colSize = mat->colSize(); - if (!add) - opVresize(result, (transpose ? colSize : rowSize)); + if constexpr (!add) + { + if constexpr (transpose) + { + opVresize(result, colSize); + } + else + { + opVresize(result, rowSize); + } + } const Index size = (rowSize < colSize) ? rowSize : colSize; for (Index i=0; irowSize(); const Index colSize = mat->colSize(); - if (!add) - opVresize(result, (transpose ? colSize : rowSize)); + if constexpr (!add) + { + if (transpose) + { + opVresize(result, colSize); + } + else + { + opVresize(result, rowSize); + } + } const Index size = (rowSize < colSize) ? rowSize : colSize; for (Index i=0; i rowRange = m1->bRowsRange(); - rowRange.first != rowRange.second; - ++rowRange.first) + for (auto [rowIt, rowEnd] = m1->bRowsRange(); rowIt != rowEnd; ++rowIt) { - const Index i = rowRange.first.row() * NL; + const Index i = rowIt.row() * NL; - for (std::pair colRange = rowRange.first.range(); - colRange.first != colRange.second; - ++colRange.first) + for (auto [colIt, colEnd] = rowIt.range(); colIt != colEnd; ++colIt) { - BlockConstAccessor block = colRange.first.bloc(); + BlockConstAccessor block = colIt.bloc(); const BlockData& bdata = *(const BlockData*)block.elements(buffer.ptr()); const Index j = block.getCol() * NC; - if (!transpose) + if constexpr (!transpose) { for (int bi = 0; bi < NL; ++bi) for (int bj = 0; bj < NC; ++bj) @@ -544,21 +578,16 @@ struct BaseMatrixLinearOpAMS_BlockSparse { BlockData buffer; - for (std::pair rowRange = m1->bRowsRange(); - rowRange.first != rowRange.second; - ++rowRange.first) + for (auto [rowIt, rowEnd] = m1->bRowsRange(); rowIt != rowEnd; ++rowIt) { - const Index i = rowRange.first.row() * NL; + const Index i = rowIt.row() * NL; - for (std::pair colRange = rowRange.first.range(); - colRange.first != colRange.second; - ++colRange.first) + for (auto [colIt, colEnd] = rowIt.range(); colIt != colEnd; ++colIt) { - - BlockConstAccessor block = colRange.first.bloc(); + BlockConstAccessor block = colIt.bloc(); const BlockData& bdata = *(const BlockData*)block.elements(buffer.ptr()); const Index j = block.getCol() * NC; - if (!transpose) + if constexpr (!transpose) { for (int bi = 0; bi < NL; ++bi) for (int bj = 0; bj < NC; ++bj) @@ -588,22 +617,17 @@ struct BaseMatrixLinearOpAM1_BlockSparse { BlockData buffer; - for (std::pair rowRange = m1->bRowsRange(); - rowRange.first != rowRange.second; - ++rowRange.first) + for (auto [rowIt, rowEnd] = m1->bRowsRange(); rowIt != rowEnd; ++rowIt) { - const Index i = rowRange.first.row(); + const Index i = rowIt.row(); - for (std::pair colRange = rowRange.first.range(); - colRange.first != colRange.second; - ++colRange.first) + for (auto [colIt, colEnd] = rowIt.range(); colIt != colEnd; ++colIt) { - - BlockConstAccessor block = colRange.first.bloc(); + BlockConstAccessor block = colIt.bloc(); const BlockData& bdata = *(const BlockData*)block.elements(&buffer); const Index j = block.getCol(); - if (!transpose) + if constexpr (!transpose) { m2->add(i,j,bdata * fact); } @@ -626,7 +650,7 @@ class BaseMatrixLinearOpAM { const Index rowSize = m1->rowSize(); const Index colSize = m2->colSize(); - if (!transpose) + if constexpr (!transpose) { for (Index j=0; j Date: Thu, 14 Dec 2023 10:29:48 +0100 Subject: [PATCH 21/45] [GUI] Fix compilation using QDocBrowser (#4354) FIX qt target handling subdirectory was overriding the variable used to store qt target dependency --- Sofa/GUI/Qt/CMakeLists.txt | 33 ++++++++++++++----- .../Qt/libQGLViewer/QGLViewer/CMakeLists.txt | 6 ++-- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Sofa/GUI/Qt/CMakeLists.txt b/Sofa/GUI/Qt/CMakeLists.txt index 8de94a80a93..df9d2362224 100644 --- a/Sofa/GUI/Qt/CMakeLists.txt +++ b/Sofa/GUI/Qt/CMakeLists.txt @@ -2,10 +2,13 @@ cmake_minimum_required(VERSION 3.12) project(Sofa.GUI.Qt LANGUAGES CXX) # Qt dependencies -set(QT_TARGETS "") +set(SOFA_GUI_QT_TARGETS "") set(QT_USE_IMPORTED_TARGETS 1) set(QT5_NO_LINK_QTMAIN 1) + + + # Will only use Qt6 if Qt6 is found and Qt5 is not found # if Qt5 and Qt6 are both found, Qt5 will take priority # Qt6 needs cmake >= 3.16, https://doc.qt.io/qt-6/cmake-get-started.html @@ -19,11 +22,11 @@ endif() if (Qt5Core_FOUND) message("${PROJECT_NAME}: will use Qt5") sofa_find_package(Qt5 COMPONENTS Core Gui OpenGL REQUIRED) - set(QT_TARGETS ${QT_TARGETS} Qt5::Core Qt5::Gui Qt5::OpenGL) + set(SOFA_GUI_QT_TARGETS ${SOFA_GUI_QT_TARGETS} Qt5::Core Qt5::Gui Qt5::OpenGL) elseif (Qt6Core_FOUND) message("${PROJECT_NAME}: will use Qt6 (beta)") sofa_find_package(Qt6 COMPONENTS Gui GuiTools Widgets WidgetsTools OpenGLWidgets REQUIRED) - set(QT_TARGETS ${QT_TARGETS} Qt::Core Qt::Gui Qt::Widgets Qt::OpenGLWidgets ) + set(SOFA_GUI_QT_TARGETS ${SOFA_GUI_QT_TARGETS} Qt::Core Qt::Gui Qt::Widgets Qt::OpenGLWidgets ) else() message(SEND_ERROR "${PROJECT_NAME}: Could not find either Qt5 or Qt6.") endif() @@ -32,7 +35,7 @@ if (Qt5Core_FOUND) # Profiling sofa_find_package(Qt5 COMPONENTS Charts QUIET BOTH_SCOPES) if(Qt5Charts_FOUND) - set(QT_TARGETS ${QT_TARGETS} Qt5::Charts) + set(SOFA_GUI_QT_TARGETS ${SOFA_GUI_QT_TARGETS} Qt5::Charts) else() message(STATUS "${PROJECT_NAME}: Qt5Charts not found. No chart nor Profile will be compiled") endif() @@ -40,16 +43,17 @@ if (Qt5Core_FOUND) # QDocBrowser find_package(Qt5 COMPONENTS WebEngine QUIET) # if found, then QDocBrowser will be ON by default option(SOFA_GUI_QT_ENABLE_QDOCBROWSER "Build the QDocBrowser. QtWebEngine is needed." ${Qt5WebEngine_FOUND}) + if(SOFA_GUI_QT_ENABLE_QDOCBROWSER) sofa_find_package(Qt5 COMPONENTS WebEngine WebEngineWidgets REQUIRED BOTH_SCOPES) - set(QT_TARGETS ${QT_TARGETS} Qt5::WebEngine Qt5::WebEngineWidgets) + set(SOFA_GUI_QT_TARGETS ${SOFA_GUI_QT_TARGETS} Qt5::WebEngine Qt5::WebEngineWidgets) endif() elseif (Qt6Core_FOUND) # Profiling sofa_find_package(Qt6 COMPONENTS Charts QUIET BOTH_SCOPES) if(Qt6Charts_FOUND) - set(QT_TARGETS ${QT_TARGETS} Qt::Charts) + set(SOFA_GUI_QT_TARGETS ${SOFA_GUI_QT_TARGETS} Qt::Charts) else() message(STATUS "${PROJECT_NAME}: Qt6 Charts not found. No chart nor Profile will be compiled") endif() @@ -60,11 +64,13 @@ elseif (Qt6Core_FOUND) if(SOFA_GUI_QT_ENABLE_QDOCBROWSER) # WebEngineCore needs Positioning WebChannel at cmake configure step (?) sofa_find_package(Qt6 COMPONENTS Positioning WebChannel WebEngineCore WebEngineWidgets REQUIRED BOTH_SCOPES) - set(QT_TARGETS ${QT_TARGETS} Qt::WebEngineCore Qt::WebEngineWidgets) + set(SOFA_GUI_QT_TARGETS ${SOFA_GUI_QT_TARGETS} Qt::WebEngineCore Qt::WebEngineWidgets) endif() endif() + find_package(Sofa.GL QUIET) + # QtViewer and QGLViewer if(Sofa.GL_FOUND) # QtViewer @@ -109,6 +115,8 @@ if(SOFA_DUMP_VISITOR_INFO) sofa_find_package(TinyXML REQUIRED BOTH_SCOPES) endif() + + set(SRC_ROOT src/sofa/gui/qt) set(MOC_HEADER_FILES @@ -212,6 +220,7 @@ set(QRC_FILES ${SRC_ROOT}/resources/RealGUI.qrc ) + if(SOFA_DUMP_VISITOR_INFO) list(APPEND MOC_HEADER_FILES ${SRC_ROOT}/WindowVisitor.h @@ -286,6 +295,8 @@ else() endif() + + #NodeEditor if (SOFA_GUI_QT_ENABLE_NODEGRAPH) list(APPEND MOC_HEADER_FILES @@ -315,13 +326,16 @@ sofa_find_package(Sofa.Component.SceneUtility REQUIRED) set(CMAKE_AUTORCC ON) add_library(${PROJECT_NAME} SHARED ${MOC_HEADER_FILES} ${HEADER_FILES} ${MOC_FILES} ${FORM_FILES} ${SOURCE_FILES} ${QRC_FILES}) + # For files generated by the moc target_include_directories(${PROJECT_NAME} PUBLIC "$") target_link_libraries(${PROJECT_NAME} PUBLIC Sofa.GUI.Common) target_link_libraries(${PROJECT_NAME} PUBLIC Sofa.Component.Visual) target_link_libraries(${PROJECT_NAME} PUBLIC Sofa.Component.SceneUtility) -target_link_libraries(${PROJECT_NAME} PUBLIC ${QT_TARGETS}) +target_link_libraries(${PROJECT_NAME} PUBLIC ${SOFA_GUI_QT_TARGETS}) + + if(SOFA_DUMP_VISITOR_INFO) target_link_libraries(${PROJECT_NAME} PUBLIC tinyxml) @@ -357,6 +371,9 @@ install(FILES "${CMAKE_BINARY_DIR}/etc/installed${PROJECT_NAME}.ini" DESTINATION install(DIRECTORY "${SRC_ROOT}/resources/" DESTINATION "share/sofa/gui/qt" COMPONENT resources) + + + sofa_create_package_with_targets( PACKAGE_NAME ${PROJECT_NAME} PACKAGE_VERSION ${Sofa_VERSION} diff --git a/Sofa/GUI/Qt/libQGLViewer/QGLViewer/CMakeLists.txt b/Sofa/GUI/Qt/libQGLViewer/QGLViewer/CMakeLists.txt index 51850801cf3..37bd944469c 100644 --- a/Sofa/GUI/Qt/libQGLViewer/QGLViewer/CMakeLists.txt +++ b/Sofa/GUI/Qt/libQGLViewer/QGLViewer/CMakeLists.txt @@ -12,10 +12,10 @@ endif() if (Qt5Core_FOUND) sofa_find_package(Qt5 COMPONENTS Core Gui Xml OpenGL Widgets REQUIRED) - set(QT_TARGETS Qt5::Core Qt5::Gui Qt5::Xml Qt5::OpenGL Qt5::Widgets) + set(QGLViewer_QT_TARGETS Qt5::Core Qt5::Gui Qt5::Xml Qt5::OpenGL Qt5::Widgets) elseif (Qt6Core_FOUND) sofa_find_package(Qt6 COMPONENTS Gui GuiTools Widgets WidgetsTools OpenGLWidgets Xml REQUIRED) - set(QT_TARGETS ${QT_TARGETS} Qt::Core Qt::Gui Qt::Widgets Qt::OpenGLWidgets Qt::Xml) + set(QGLViewer_QT_TARGETS ${QGLViewer_QT_TARGETS} Qt::Core Qt::Gui Qt::Widgets Qt::OpenGLWidgets Qt::Xml) endif() set(MOC_HEADER_FILES @@ -98,7 +98,7 @@ endif() add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${MOC_FILES} ${FORM_FILES} ${SOURCE_FILES}) set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER "SofaExtlibs") -target_link_libraries(${PROJECT_NAME} PUBLIC ${QT_TARGETS}) +target_link_libraries(${PROJECT_NAME} PUBLIC ${QGLViewer_QT_TARGETS}) if(TARGET OpenGL::GL AND TARGET OpenGL::GLU) # Imported targets defined since CMake 3.8 target_link_libraries(${PROJECT_NAME} PUBLIC OpenGL::GL OpenGL::GLU) else() From 7b1ffe2807b97e87e3dc9794c250a4a90f7b74ad Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Mon, 18 Dec 2023 00:34:41 +0100 Subject: [PATCH 22/45] [Mapping.Linear] Replace a few beginEdit by accessors (#4363) --- .../BarycentricMapperEdgeSetTopology.inl | 13 +++++---- ...BarycentricMapperHexahedronSetTopology.inl | 27 +++++++++---------- .../mapping/linear/BarycentricMapping.inl | 13 +++++---- 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappers/BarycentricMapperEdgeSetTopology.inl b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappers/BarycentricMapperEdgeSetTopology.inl index 1b13e87ceca..05575f639ce 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappers/BarycentricMapperEdgeSetTopology.inl +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappers/BarycentricMapperEdgeSetTopology.inl @@ -32,15 +32,14 @@ BarycentricMapperEdgeSetTopology::BarycentricMapperEdgeSetTopology(sofa: {} template -typename BarycentricMapperEdgeSetTopology::Index BarycentricMapperEdgeSetTopology::addPointInLine ( const Index edgeIndex, const SReal* baryCoords ) +auto BarycentricMapperEdgeSetTopology::addPointInLine ( const Index edgeIndex, const SReal* baryCoords ) -> Index { - type::vector& vectorData = *(d_map.beginEdit()); - vectorData.resize ( d_map.getValue().size() +1 ); - d_map.endEdit(); - MappingData& data = *vectorData.rbegin(); + auto vectorData = sofa::helper::getWriteAccessor(d_map); + MappingData data; data.in_index = edgeIndex; - data.baryCoords[0] = ( Real ) baryCoords[0]; - return Size(d_map.getValue().size()-1); + data.baryCoords[0] = static_cast(baryCoords[0]); + vectorData->emplace_back(data); + return static_cast(vectorData.size() - 1u); } template diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappers/BarycentricMapperHexahedronSetTopology.inl b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappers/BarycentricMapperHexahedronSetTopology.inl index 1887f6e2fd3..409b029bf3f 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappers/BarycentricMapperHexahedronSetTopology.inl +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappers/BarycentricMapperHexahedronSetTopology.inl @@ -50,15 +50,14 @@ template typename BarycentricMapperHexahedronSetTopology::Index BarycentricMapperHexahedronSetTopology::addPointInCube ( const Index cubeIndex, const SReal* baryCoords ) { - type::vector& vectorData = *(d_map.beginEdit()); - vectorData.resize ( d_map.getValue().size() +1 ); - MappingData& data = *vectorData.rbegin(); - d_map.endEdit(); + auto vectorData = sofa::helper::getWriteAccessor(d_map); + MappingData data; data.in_index = cubeIndex; - data.baryCoords[0] = ( Real ) baryCoords[0]; - data.baryCoords[1] = ( Real ) baryCoords[1]; - data.baryCoords[2] = ( Real ) baryCoords[2]; - return (int)d_map.getValue().size()-1; + data.baryCoords[0] = static_cast(baryCoords[0]); + data.baryCoords[1] = static_cast(baryCoords[1]); + data.baryCoords[2] = static_cast(baryCoords[2]); + vectorData->emplace_back(data); + return static_cast(vectorData.size() - 1u); } @@ -66,16 +65,16 @@ template typename BarycentricMapperHexahedronSetTopology::Index BarycentricMapperHexahedronSetTopology::setPointInCube ( const Index pointIndex, const Index cubeIndex, const SReal* baryCoords ) { - if ( pointIndex >= d_map.getValue().size() ) + auto vectorData = sofa::helper::getWriteAccessor(d_map); + + if ( pointIndex >= vectorData.size() ) return sofa::InvalidID; - type::vector& vectorData = *(d_map.beginEdit()); MappingData& data = vectorData[pointIndex]; data.in_index = cubeIndex; - data.baryCoords[0] = ( Real ) baryCoords[0]; - data.baryCoords[1] = ( Real ) baryCoords[1]; - data.baryCoords[2] = ( Real ) baryCoords[2]; - d_map.endEdit(); + data.baryCoords[0] = static_cast(baryCoords[0]); + data.baryCoords[1] = static_cast(baryCoords[1]); + data.baryCoords[2] = static_cast(baryCoords[2]); if(cubeIndex == sofa::InvalidID) m_invalidIndex.insert(pointIndex); diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMapping.inl b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMapping.inl index d33e72cd968..7330a12a798 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMapping.inl +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMapping.inl @@ -307,12 +307,11 @@ void BarycentricMapping::applyJ (const core::MechanicalParams * mpara { SOFA_UNUSED(mparams); - typename Out::VecDeriv* out = _out.beginEdit(); if (d_mapper != nullptr) { - d_mapper->applyJ(*out, in.getValue()); + auto outWriteAccessor = sofa::helper::getWriteAccessor(_out); + d_mapper->applyJ(outWriteAccessor.wref(), in.getValue()); } - _out.endEdit(); } @@ -323,8 +322,8 @@ void BarycentricMapping::applyJT (const core::MechanicalParams * mpar if (d_mapper != nullptr) { - d_mapper->applyJT(*out.beginEdit(), in.getValue()); - out.endEdit(); + auto outWriteAccessor = sofa::helper::getWriteAccessor(out); + d_mapper->applyJT(outWriteAccessor.wref(), in.getValue()); } } @@ -376,8 +375,8 @@ void BarycentricMapping::applyJT(const core::ConstraintParams * cpara if (d_mapper!=nullptr ) { - d_mapper->applyJT(*out.beginEdit(), in.getValue()); - out.endEdit(); + auto outWriteAccessor = sofa::helper::getWriteAccessor(out); + d_mapper->applyJT(outWriteAccessor.wref(), in.getValue()); } } From beb325179b8aeacec02b5ad84022215edfea98db Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Tue, 19 Dec 2023 01:07:23 +0100 Subject: [PATCH 23/45] [Type] Remove test of a deprecated constructor (#4391) --- Sofa/framework/Type/test/Color_test.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Sofa/framework/Type/test/Color_test.cpp b/Sofa/framework/Type/test/Color_test.cpp index 3e722c8d03a..fb30479c4af 100644 --- a/Sofa/framework/Type/test/Color_test.cpp +++ b/Sofa/framework/Type/test/Color_test.cpp @@ -132,10 +132,7 @@ void Color_Test::checkCreateFromDouble() EXPECT_EQ( RGBAColor::fromFloat(1.0,1.0,0.0,1.0), RGBAColor(1.0,1.0,0.0,1.0)) ; EXPECT_EQ( RGBAColor::fromFloat(1.0,1.0,1.0,0.0), RGBAColor(1.0,1.0,1.0,0.0)) ; - const Vec4d tt(2,3,4,5) ; - EXPECT_EQ( RGBAColor::fromVec4(tt), RGBAColor(2,3,4,5)) ; - - const std::array stdarrtt{ 2, 3, 4, 5 }; + constexpr std::array stdarrtt{ 2, 3, 4, 5 }; EXPECT_EQ(RGBAColor::fromStdArray(stdarrtt), RGBAColor(2, 3, 4, 5)); } @@ -143,7 +140,6 @@ void Color_Test::checkCreateFromDouble() void Color_Test::checkConstructors() { EXPECT_EQ( RGBAColor(std::array{1, 2, 3, 4}), RGBAColor(1, 2, 3, 4)); - EXPECT_EQ( RGBAColor(sofa::type::Vec<4, float>(1, 2, 3, 4)), RGBAColor(1, 2, 3, 4)); } From 00abf7cbdc4f3a9953f7bd9f3074072c27dc1f65 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Tue, 19 Dec 2023 02:52:42 +0100 Subject: [PATCH 24/45] [LinearAlgebra] Factorize template specializations of filterValues in CRS matrix (#4355) --- .../CompressedRowSparseMatrixMechanical.cpp | 260 ++++-------------- .../test/CompressedRowSparseMatrix_test.cpp | 28 ++ 2 files changed, 75 insertions(+), 213 deletions(-) diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixMechanical.cpp b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixMechanical.cpp index d991e71c118..b73b3662a99 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixMechanical.cpp +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixMechanical.cpp @@ -64,263 +64,97 @@ void CompressedRowSparseMatrixMechanical >::add(Index row } -template <> template <> -void CompressedRowSparseMatrixMechanical::filterValues(CompressedRowSparseMatrixMechanical >& M, filter_fn* filter, const Real ref, bool keepEmptyRows) +template +void filterValuesImpl( + CompressedRowSparseMatrixMechanical& dest, + CompressedRowSparseMatrixMechanical >& src, + typename CompressedRowSparseMatrixMechanical::filter_fn* filter, + const RealDest ref, const bool keepEmptyRows) { - M.compress(); - nRow = M.rowSize(); - nCol = M.colSize(); - nBlockRow = M.rowSize(); - nBlockCol = M.colSize(); - rowIndex.clear(); - rowBegin.clear(); - colsIndex.clear(); - colsValue.clear(); - btemp.clear(); - skipCompressZero = true; - rowIndex.reserve(M.rowIndex.size() * 3); - rowBegin.reserve(M.rowBegin.size() * 3); - colsIndex.reserve(M.colsIndex.size() * 9); - colsValue.reserve(M.colsValue.size() * 9); + src.compress(); + dest.nRow = src.rowSize(); + dest.nCol = src.colSize(); + dest.nBlockRow = src.rowSize(); + dest.nBlockCol = src.colSize(); + dest.rowIndex.clear(); + dest.rowBegin.clear(); + dest.colsIndex.clear(); + dest.colsValue.clear(); + dest.btemp.clear(); + dest.skipCompressZero = true; + dest.rowIndex.reserve(src.rowIndex.size() * 3); + dest.rowBegin.reserve(src.rowBegin.size() * 3); + dest.colsIndex.reserve(src.colsIndex.size() * 9); + dest.colsValue.reserve(src.colsValue.size() * 9); Index vid = 0; - for (std::size_t rowId = 0; rowId < M.rowIndex.size(); ++rowId) + for (std::size_t rowId = 0; rowId < src.rowIndex.size(); ++rowId) { - const Index i = M.rowIndex[rowId] * 3; + const Index i = src.rowIndex[rowId] * 3; - Range rowRange(M.rowBegin[rowId], M.rowBegin[rowId + 1]); + typename CompressedRowSparseMatrixMechanical::Range rowRange(src.rowBegin[rowId], src.rowBegin[rowId + 1]); for (Index lb = 0; lb < 3; lb++) { - rowIndex.push_back(i + lb); - rowBegin.push_back(vid); + dest.rowIndex.push_back(i + lb); + dest.rowBegin.push_back(vid); for (std::size_t xj = static_cast(rowRange.begin()); xj < static_cast(rowRange.end()); ++xj) { - const Index j = M.colsIndex[xj] * 3; - type::Mat<3, 3, double> b = M.colsValue[xj]; + const Index j = src.colsIndex[xj] * 3; + type::Mat<3, 3, RealDest> b = src.colsValue[xj]; if ((*filter)(i + lb, j + 0, b[lb][0], ref)) { - colsIndex.push_back(j + 0); - colsValue.push_back(b[lb][0]); + dest.colsIndex.push_back(j + 0); + dest.colsValue.push_back(b[lb][0]); ++vid; } if ((*filter)(i + lb, j + 1, b[lb][1], ref)) { - colsIndex.push_back(j + 1); - colsValue.push_back(b[lb][1]); + dest.colsIndex.push_back(j + 1); + dest.colsValue.push_back(b[lb][1]); ++vid; } if ((*filter)(i + lb, j + 2, b[lb][2], ref)) { - colsIndex.push_back(j + 2); - colsValue.push_back(b[lb][2]); + dest.colsIndex.push_back(j + 2); + dest.colsValue.push_back(b[lb][2]); ++vid; } } - if (!keepEmptyRows && rowBegin.back() == vid) // row was empty + if (!keepEmptyRows && dest.rowBegin.back() == vid) // row was empty { - rowIndex.pop_back(); - rowBegin.pop_back(); + dest.rowIndex.pop_back(); + dest.rowBegin.pop_back(); } } } - rowBegin.push_back(vid); // end of last row + dest.rowBegin.push_back(vid); // end of last row } template <> template <> -void CompressedRowSparseMatrixMechanical::filterValues(CompressedRowSparseMatrixMechanical >& M, filter_fn* filter, const Real ref, bool keepEmptyRows) +void CompressedRowSparseMatrixMechanical::filterValues(CompressedRowSparseMatrixMechanical >& M, filter_fn* filter, const Real ref, bool keepEmptyRows) { - M.compress(); - nRow = M.rowSize(); - nCol = M.colSize(); - nBlockRow = M.rowSize(); - nBlockCol = M.colSize(); - rowIndex.clear(); - rowBegin.clear(); - colsIndex.clear(); - colsValue.clear(); - skipCompressZero = true; - btemp.clear(); - rowIndex.reserve(M.rowIndex.size() * 3); - rowBegin.reserve(M.rowBegin.size() * 3); - colsIndex.reserve(M.colsIndex.size() * 9); - colsValue.reserve(M.colsValue.size() * 9); - - Index vid = 0; - for (std::size_t rowId = 0; rowId < M.rowIndex.size(); ++rowId) - { - const Index i = M.rowIndex[rowId] * 3; - - Range rowRange(M.rowBegin[rowId], M.rowBegin[rowId + 1]); - - for (Index lb = 0; lb < 3; lb++) - { - rowIndex.push_back(i + lb); - rowBegin.push_back(vid); - - for (std::size_t xj = static_cast(rowRange.begin()); xj < static_cast(rowRange.end()); ++xj) - { - const Index j = M.colsIndex[xj] * 3; - type::Mat<3, 3, double> b = M.colsValue[xj]; - if ((*filter)(i + lb, j + 0, b[lb][0], ref)) - { - colsIndex.push_back(j + 0); - colsValue.push_back(b[lb][0]); - ++vid; - } - if ((*filter)(i + lb, j + 1, b[lb][1], ref)) - { - colsIndex.push_back(j + 1); - colsValue.push_back(b[lb][1]); - ++vid; - } - if ((*filter)(i + lb, j + 2, b[lb][2], ref)) - { - colsIndex.push_back(j + 2); - colsValue.push_back(b[lb][2]); - ++vid; - } - } + filterValuesImpl(*this, M, filter, ref, keepEmptyRows); +} - if (!keepEmptyRows && rowBegin.back() == vid) // row was empty - { - rowIndex.pop_back(); - rowBegin.pop_back(); - } - } - } - rowBegin.push_back(vid); // end of last row +template <> template <> +void CompressedRowSparseMatrixMechanical::filterValues(CompressedRowSparseMatrixMechanical >& M, filter_fn* filter, const Real ref, bool keepEmptyRows) +{ + filterValuesImpl(*this, M, filter, ref, keepEmptyRows); } template <> template <> void CompressedRowSparseMatrixMechanical::filterValues(CompressedRowSparseMatrixMechanical >& M, filter_fn* filter, const Real ref, bool keepEmptyRows) { - M.compress(); - nRow = M.rowSize(); - nCol = M.colSize(); - nBlockRow = M.rowSize(); - nBlockCol = M.colSize(); - rowIndex.clear(); - rowBegin.clear(); - colsIndex.clear(); - colsValue.clear(); - skipCompressZero = true; - btemp.clear(); - rowIndex.reserve(M.rowIndex.size() * 3); - rowBegin.reserve(M.rowBegin.size() * 3); - colsIndex.reserve(M.colsIndex.size() * 9); - colsValue.reserve(M.colsValue.size() * 9); - - Index vid = 0; - for (std::size_t rowId = 0; rowId < M.rowIndex.size(); ++rowId) - { - const Index i = M.rowIndex[rowId] * 3; - - Range rowRange(M.rowBegin[rowId], M.rowBegin[rowId + 1]); - - for (Index lb = 0; lb < 3; lb++) - { - rowIndex.push_back(i + lb); - rowBegin.push_back(vid); - - for (std::size_t xj = static_cast(rowRange.begin()); xj < static_cast(rowRange.end()); ++xj) - { - const Index j = M.colsIndex[xj] * 3; - type::Mat<3, 3, float> b = M.colsValue[xj]; - if ((*filter)(i + lb, j + 0, b[lb][0], ref)) - { - colsIndex.push_back(j + 0); - colsValue.push_back(b[lb][0]); - ++vid; - } - if ((*filter)(i + lb, j + 1, b[lb][1], ref)) - { - colsIndex.push_back(j + 1); - colsValue.push_back(b[lb][1]); - ++vid; - } - if ((*filter)(i + lb, j + 2, b[lb][2], ref)) - { - colsIndex.push_back(j + 2); - colsValue.push_back(b[lb][2]); - ++vid; - } - } - - if (!keepEmptyRows && rowBegin.back() == vid) // row was empty - { - rowIndex.pop_back(); - rowBegin.pop_back(); - } - } - } - rowBegin.push_back(vid); // end of last row + filterValuesImpl(*this, M, filter, ref, keepEmptyRows); } template <> template <> void CompressedRowSparseMatrixMechanical::filterValues(CompressedRowSparseMatrixMechanical >& M, filter_fn* filter, const Real ref, bool keepEmptyRows) { - M.compress(); - nRow = M.rowSize(); - nCol = M.colSize(); - nBlockRow = 1; - nBlockCol = 1; - rowIndex.clear(); - rowBegin.clear(); - colsIndex.clear(); - colsValue.clear(); - skipCompressZero = true; - btemp.clear(); - rowIndex.reserve(M.rowIndex.size() * 3); - rowBegin.reserve(M.rowBegin.size() * 3); - colsIndex.reserve(M.colsIndex.size() * 9); - colsValue.reserve(M.colsValue.size() * 9); - - Index vid = 0; - for (std::size_t rowId = 0; rowId < M.rowIndex.size(); ++rowId) - { - const Index i = M.rowIndex[rowId] * 3; - - Range rowRange(M.rowBegin[rowId], M.rowBegin[rowId + 1]); - - for (Index lb = 0; lb < 3; lb++) - { - rowIndex.push_back(i + lb); - rowBegin.push_back(vid); - - for (std::size_t xj = static_cast(rowRange.begin()); xj < static_cast(rowRange.end()); ++xj) - { - const Index j = M.colsIndex[xj] * 3; - type::Mat<3, 3, float> b = M.colsValue[xj]; - if ((*filter)(i + lb, j + 0, b[lb][0], ref)) - { - colsIndex.push_back(j + 0); - colsValue.push_back(b[lb][0]); - ++vid; - } - if ((*filter)(i + lb, j + 1, b[lb][1], ref)) - { - colsIndex.push_back(j + 1); - ++vid; - } - if ((*filter)(i + lb, j + 2, b[lb][2], ref)) - { - colsIndex.push_back(j + 2); - colsValue.push_back(b[lb][2]); - ++vid; - } - } - - if (!keepEmptyRows && rowBegin.back() == vid) // row was empty - { - rowIndex.pop_back(); - rowBegin.pop_back(); - } - } - } - rowBegin.push_back(vid); // end of last row + filterValuesImpl(*this, M, filter, ref, keepEmptyRows); } using namespace sofa::type; diff --git a/Sofa/framework/LinearAlgebra/test/CompressedRowSparseMatrix_test.cpp b/Sofa/framework/LinearAlgebra/test/CompressedRowSparseMatrix_test.cpp index aa6fad1daef..b1082b8d17f 100644 --- a/Sofa/framework/LinearAlgebra/test/CompressedRowSparseMatrix_test.cpp +++ b/Sofa/framework/LinearAlgebra/test/CompressedRowSparseMatrix_test.cpp @@ -249,6 +249,34 @@ TEST(CompressedRowSparseMatrix, copyNonZeros) EXPECT_EQ(numberNonZeroValues1, numberNonZeroValues3); } +TEST(CompressedRowSparseMatrix, copyNonZerosFromBlocks) +{ + sofa::linearalgebra::CompressedRowSparseMatrix> A; + generateMatrix(A, 1321, 3556, 0.0003, 12); + + const auto numberNonZeroValues1 = A.colsValue.size(); + + A.add(23, 569, 0); + A.add(874, 326, 0); + A.add(769, 1789, 0); + A.compress(); + + const auto numberNonZeroValues2 = A.colsValue.size(); + EXPECT_GT(numberNonZeroValues2, numberNonZeroValues1); + + sofa::linearalgebra::CompressedRowSparseMatrix B; + + B.copyNonZeros(A); + + for (unsigned int r = 0; r < A.rowSize(); ++r) + { + for (unsigned int c = 0; c < A.rowSize(); ++c) + { + EXPECT_NEAR(A(r, c), B(r, c), 1e-12_sreal); + } + } +} + TEST(CompressedRowSparseMatrix, emptyMatrixGetRowRange) { EXPECT_EQ(sofa::linearalgebra::CompressedRowSparseMatrixMechanical::s_invalidIndex, std::numeric_limits::lowest()); From fcd1b0e5932f2291e251de5d3884e652a13e8a33 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Tue, 19 Dec 2023 05:42:15 +0100 Subject: [PATCH 25/45] [Core] Remove pragma directive in cpp file (#4393) --- .../framework/Core/src/sofa/core/objectmodel/DeprecatedData.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/DeprecatedData.cpp b/Sofa/framework/Core/src/sofa/core/objectmodel/DeprecatedData.cpp index 139b7a14508..5b1f42517be 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/DeprecatedData.cpp +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/DeprecatedData.cpp @@ -19,8 +19,6 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#pragma once - #include #include #include From 27878bd40464de1dbe15832674d151162c9fde6d Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Tue, 19 Dec 2023 06:40:49 +0100 Subject: [PATCH 26/45] [MultiThreading] Fix failing test on ParallelImplementationsRegistry (#4392) * More details when test fails * Test initializing the module at init --- .../MultiThreading/src/MultiThreading/initMultiThreading.cpp | 4 ++++ .../test/ParallelImplementationsRegistry_test.cpp | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/applications/plugins/MultiThreading/src/MultiThreading/initMultiThreading.cpp b/applications/plugins/MultiThreading/src/MultiThreading/initMultiThreading.cpp index b2defc710f7..6220f2b4ddb 100644 --- a/applications/plugins/MultiThreading/src/MultiThreading/initMultiThreading.cpp +++ b/applications/plugins/MultiThreading/src/MultiThreading/initMultiThreading.cpp @@ -22,6 +22,9 @@ #include #include +#include + + namespace multithreading { @@ -39,6 +42,7 @@ void init() static bool first = true; if (first) { + sofa::component::linearsolver::iterative::init(); first = false; } } diff --git a/applications/plugins/MultiThreading/test/ParallelImplementationsRegistry_test.cpp b/applications/plugins/MultiThreading/test/ParallelImplementationsRegistry_test.cpp index 4a8254b2541..83d38f23066 100644 --- a/applications/plugins/MultiThreading/test/ParallelImplementationsRegistry_test.cpp +++ b/applications/plugins/MultiThreading/test/ParallelImplementationsRegistry_test.cpp @@ -36,8 +36,8 @@ TEST(ParallelImplementationsRegistry, existInObjectFactory) ASSERT_FALSE(seq.empty()); ASSERT_FALSE(par.empty()); - EXPECT_TRUE(sofa::core::ObjectFactory::getInstance()->hasCreator(seq)); - EXPECT_TRUE(sofa::core::ObjectFactory::getInstance()->hasCreator(par)); + EXPECT_TRUE(sofa::core::ObjectFactory::getInstance()->hasCreator(seq)) << seq; + EXPECT_TRUE(sofa::core::ObjectFactory::getInstance()->hasCreator(par)) << par; } } } From b1c49a761faec4ea63a5bffd32e8bfda67e552f2 Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Wed, 20 Dec 2023 10:06:33 +0100 Subject: [PATCH 27/45] [Simulation.Core] BaseMechanicalVisitor: Deprecate rootData (#4350) * remove ref to nodedata * add compat * Update Sofa/framework/Simulation/Core/src/sofa/simulation/config.h.in (typo) Co-authored-by: Alex Bilger --------- Co-authored-by: Alex Bilger --- .../sofa/simulation/BaseMechanicalVisitor.cpp | 69 ++----------------- .../sofa/simulation/BaseMechanicalVisitor.h | 19 +++-- .../Core/src/sofa/simulation/config.h.in | 7 ++ ...chanicalGetNonDiagonalMassesCountVisitor.h | 5 -- .../mechanicalvisitor/MechanicalVDotVisitor.h | 4 -- .../MechanicalVMultiOpVisitor.h | 4 -- .../MechanicalVNormVisitor.h | 4 -- .../mechanicalvisitor/MechanicalVOpVisitor.h | 4 -- 8 files changed, 23 insertions(+), 93 deletions(-) diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/BaseMechanicalVisitor.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/BaseMechanicalVisitor.cpp index be36afdee57..46925012b52 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/BaseMechanicalVisitor.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/BaseMechanicalVisitor.cpp @@ -200,57 +200,15 @@ Visitor::Result BaseMechanicalVisitor::fwdInteractionConstraint(VisitorContext* Visitor::Result BaseMechanicalVisitor::processNodeTopDown(simulation::Node* node, LocalStorage* stack) { - if (root == nullptr) - { - root = node; - } - - VisitorContext ctx; - ctx.root = root; - ctx.node = node; - ctx.nodeData = rootData; - - const bool writeData = writeNodeData(); - if (writeData) - { - // create temporary accumulation buffer for parallel reductions (dot products) - if (node != root) - { - const SReal* parentData = stack->empty() ? rootData : (SReal*)stack->top(); - ctx.nodeData = new SReal(0.0); - setNodeData(node, ctx.nodeData, parentData); - stack->push(ctx.nodeData); - } - } - - return processNodeTopDown(node, &ctx); + SOFA_UNUSED(stack); + return processNodeTopDown(node); } void BaseMechanicalVisitor::processNodeBottomUp(simulation::Node* node, LocalStorage* stack) { - VisitorContext ctx; - ctx.root = root; - ctx.node = node; - ctx.nodeData = rootData; - SReal* parentData = rootData; - - const bool writeData = writeNodeData(); - - if (writeData) - { - // use temporary accumulation buffer for parallel reductions (dot products) - if (node != root) - { - ctx.nodeData = (SReal*)stack->pop(); - parentData = stack->empty() ? rootData : (SReal*)stack->top(); - } - } - - processNodeBottomUp(node, &ctx); - - if (writeData && parentData != ctx.nodeData) - addNodeData(node, parentData, ctx.nodeData); + SOFA_UNUSED(stack); + return processNodeBottomUp(node); } @@ -408,25 +366,6 @@ void BaseMechanicalVisitor::end(simulation::Node* node, core::objectmodel::BaseO //} -/// Return true if this visitor need to read the node-specific data if given -bool BaseMechanicalVisitor::readNodeData() const -{ return false; } - -/// Return true if this visitor need to write to the node-specific data if given -bool BaseMechanicalVisitor::writeNodeData() const -{ return false; } - -void BaseMechanicalVisitor::setNodeData(simulation::Node* /*node*/, SReal* nodeData, const SReal* parentData) -{ - *nodeData = (parentData == nullptr) ? 0.0 : *parentData; -} - -void BaseMechanicalVisitor::addNodeData(simulation::Node* /*node*/, SReal* parentData, const SReal* nodeData) -{ - if (parentData) - *parentData += *nodeData; -} - /// Return a class name for this visitor /// Only used for debugging / profiling purposes const char* BaseMechanicalVisitor::getClassName() const { return "MechanicalVisitor"; } diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/BaseMechanicalVisitor.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/BaseMechanicalVisitor.h index bd25f9e25b7..0120f5f0c12 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/BaseMechanicalVisitor.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/BaseMechanicalVisitor.h @@ -45,7 +45,9 @@ class SOFA_SIMULATION_CORE_API BaseMechanicalVisitor : public Visitor protected: simulation::Node* root; ///< root node from which the visitor was executed - SReal* rootData; ///< data for root node + + SOFA_ATTRIBUTE_DEPRECATED_NODEDATA() + SReal* rootData { nullptr }; ///< data for root node virtual Result processNodeTopDown(simulation::Node* node, VisitorContext* ctx); virtual void processNodeBottomUp(simulation::Node* node, VisitorContext* ctx); @@ -53,14 +55,17 @@ class SOFA_SIMULATION_CORE_API BaseMechanicalVisitor : public Visitor public: BaseMechanicalVisitor(const sofa::core::ExecParams* params); - /// Return true if this visitor need to read the node-specific data if given - virtual bool readNodeData() const; + SOFA_ATTRIBUTE_DEPRECATED_NODEDATA() + virtual bool readNodeData() const { return false; }; + + SOFA_ATTRIBUTE_DEPRECATED_NODEDATA() + virtual bool writeNodeData() const { return false; }; - /// Return true if this visitor need to write to the node-specific data if given - virtual bool writeNodeData() const; + SOFA_ATTRIBUTE_DEPRECATED_NODEDATA() + virtual void setNodeData(simulation::Node* /*node*/, SReal* /*nodeData*/, const SReal* /*parentData*/) {}; - virtual void setNodeData(simulation::Node* /*node*/, SReal* nodeData, const SReal* parentData); - virtual void addNodeData(simulation::Node* /*node*/, SReal* parentData, const SReal* nodeData); + SOFA_ATTRIBUTE_DEPRECATED_NODEDATA() + virtual void addNodeData(simulation::Node* /*node*/, SReal* /*parentData*/, const SReal* /*nodeData*/) {}; /// Return a class name for this visitor /// Only used for debugging / profiling purposes diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/config.h.in b/Sofa/framework/Simulation/Core/src/sofa/simulation/config.h.in index a949327fc2c..9c80cf1bd83 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/config.h.in +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/config.h.in @@ -248,3 +248,10 @@ SOFA_ATTRIBUTE_DEPRECATED( \ #define SOFA_ATTRIBUTE_DEPRECATED_LOCALSTORAGE() \ SOFA_ATTRIBUTE_DEPRECATED("v23.12", "v24.06", "LocalStorage feature was seemingly not used so it has been deprecated.") #endif // SOFA_BUILD_SOFA_SIMULATION_CORE + +#ifdef SOFA_BUILD_SOFA_SIMULATION_CORE +#define SOFA_ATTRIBUTE_DEPRECATED_NODEDATA() +#else +#define SOFA_ATTRIBUTE_DEPRECATED_NODEDATA() \ +SOFA_ATTRIBUTE_DEPRECATED("v23.12", "v24.06", "rootdata/nodedata feature was never really used so it has been deprecated. All the related functions/members/variables won't do anything.") +#endif // SOFA_BUILD_SOFA_SIMULATION_CORE diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalGetNonDiagonalMassesCountVisitor.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalGetNonDiagonalMassesCountVisitor.h index 6053eb36900..6b173d74223 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalGetNonDiagonalMassesCountVisitor.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalGetNonDiagonalMassesCountVisitor.h @@ -45,11 +45,6 @@ class SOFA_SIMULATION_CORE_API MechanicalGetNonDiagonalMassesCountVisitor : publ /// Return a class name for this visitor /// Only used for debugging / profiling purposes const char* getClassName() const override { return "MechanicalGetNonDiagonalMassesCountVisitor";} - - bool writeNodeData() const override - { - return true; - } }; } diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVDotVisitor.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVDotVisitor.h index 837ee617d86..87ccad2fbe8 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVDotVisitor.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVDotVisitor.h @@ -53,10 +53,6 @@ class SOFA_SIMULATION_CORE_API MechanicalVDotVisitor : public BaseMechanicalVisi { return true; } - bool writeNodeData() const override - { - return true; - } #ifdef SOFA_DUMP_VISITOR_INFO void setReadWriteVectors() override diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVMultiOpVisitor.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVMultiOpVisitor.h index 4e148074844..162d6c7fe13 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVMultiOpVisitor.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVMultiOpVisitor.h @@ -59,10 +59,6 @@ class SOFA_SIMULATION_CORE_API MechanicalVMultiOpVisitor : public BaseMechanical { return true; } - bool readNodeData() const override - { - return true; - } #ifdef SOFA_DUMP_VISITOR_INFO void setReadWriteVectors() override { diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVNormVisitor.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVNormVisitor.h index 45d53382d1d..8f161ec7172 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVNormVisitor.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVNormVisitor.h @@ -58,10 +58,6 @@ class SOFA_SIMULATION_CORE_API MechanicalVNormVisitor : public BaseMechanicalVis { return true; } - bool writeNodeData() const override - { - return true; - } #ifdef SOFA_DUMP_VISITOR_INFO void setReadWriteVectors() override diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVOpVisitor.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVOpVisitor.h index b4f512fc693..3bf1f0fd93d 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVOpVisitor.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalVOpVisitor.h @@ -64,10 +64,6 @@ class SOFA_SIMULATION_CORE_API MechanicalVOpVisitor : public BaseMechanicalVisit { return true; } - bool readNodeData() const override - { - return true; - } #ifdef SOFA_DUMP_VISITOR_INFO void setReadWriteVectors() override { From 026a501f816093a9730e87b045a0c620df3c2044 Mon Sep 17 00:00:00 2001 From: Paul Baksic <30337881+bakpaul@users.noreply.github.com> Date: Wed, 20 Dec 2023 12:10:58 +0100 Subject: [PATCH 28/45] [Constraint] Make name of constraints more explicit (#4302) * Added projective and lagrangian suffix * Reported changes to Cuda plugin * Modify rest of the code to avoid warning from compatibility layer * Add compatibility layer for deprecated header in CUDA * add alias for compatibility layer in scene construction * Report name modification to all scenes * Revert Compat modification... * [LinearAlgera, Core] Fix linking with LTO on MacOS/Clang (#4293) Fix linking with LTO on macos * [LinearSolver] Remove CSparse-based linear solvers (#4258) * [LinearSolver.Direct] Remove CSparse based solvers * Remove csparse extlib * Fetchable CSparseSolvers plugin * Remove references of SparseLUSolver * Remove references to SparseCholeskySolver * Remove csparse * Try to fix on Linux * Update the compat * [LinearSolver.Direct] Remove CSparse based solvers * Fix direct solver * [GUI.Qt] Minor single-line cleaning (#4308) Co-authored-by: erik pernod * [Sofa.GUI.Qt] Add cmake module for QGLViewer (#4290) * Add cmake module for QGLViewer * Support library name for apt packages * Fix qglviewer cmake finder module to first seach for a config cmake file. * Update cmake/Modules/FindQGLViewer.cmake Co-authored-by: Hugo --------- Co-authored-by: Frederick Roy Co-authored-by: Hugo * [MultiThreading] Avoid Static Initialization Order Fiasco (#4307) * [Core] Minor clean of DefaultAnimationLoop (#4314) * Remove unlogical use of visitor * Delete unused methods * [LinearSystem] Speedup computation of Jacobian matrices (#4317) * [LinearSystem] Speedup computation of Jacobian matrices in case both mstates are the same * minor reformat to align calls to computeJacobiansFrom * [SofaCUDA] FIX compilation SofaCUDA along with SparseGrid with Cuda12 (#4319) * FIX compilation SofaCUDA along with SparseGrid with Cuda12 * Use a multiplication instead * [Common] Add message to make the fetch mechanism less hidden (#4310) * Add message to make it more clear * slight modifications to be even more clear and add an error the dependency cannot be met * [Collections] Remove reference to non-existing SofaSimulation (#4320) remove ref to non-existent sofasimu Co-authored-by: Paul Baksic <30337881+bakpaul@users.noreply.github.com> * Remove repeating preffix from projective constraints * Moved alias to original header * Changed deprecation date * add component change entry * Change name following discussion with Hugo * Change remaining scene with FixedConstraint * remove last occurences in py files * Changed the message display of sceneCheckUsingAlias when aliased component is in component change * Fix factory * Add alias creation when object in componentRenamed in factory * Remove precedently added aliases --------- Co-authored-by: Frederick Roy Co-authored-by: Alex Bilger Co-authored-by: erik pernod Co-authored-by: Olivier Roussel Co-authored-by: Hugo --- .../response/contact/FrictionContact.h | 4 +- .../response/contact/FrictionContact.inl | 2 +- .../response/contact/StickContactConstraint.h | 4 +- .../contact/StickContactConstraint.inl | 2 +- .../Lagrangian/Model/CMakeLists.txt | 23 +- .../model/BilateralInteractionConstraint.h | 171 +---- .../model/BilateralInteractionConstraint.inl | 411 +---------- ....cpp => BilateralLagrangianConstraint.cpp} | 156 ++--- .../model/BilateralLagrangianConstraint.h | 195 ++++++ .../model/BilateralLagrangianConstraint.inl | 433 ++++++++++++ .../lagrangian/model/SlidingConstraint.h | 93 +-- .../lagrangian/model/SlidingConstraint.inl | 204 +----- ...nt.cpp => SlidingLagrangianConstraint.cpp} | 10 +- .../model/SlidingLagrangianConstraint.h | 113 +++ .../model/SlidingLagrangianConstraint.inl | 226 ++++++ .../lagrangian/model/StopperConstraint.h | 106 +-- .../lagrangian/model/StopperConstraint.inl | 59 +- ...nt.cpp => StopperLagrangianConstraint.cpp} | 10 +- .../model/StopperLagrangianConstraint.h | 127 ++++ .../model/StopperLagrangianConstraint.inl | 81 +++ .../lagrangian/model/UniformConstraint.h | 57 +- .../lagrangian/model/UniformConstraint.inl | 115 +--- ...nt.cpp => UniformLagrangianConstraint.cpp} | 10 +- .../model/UniformLagrangianConstraint.h | 78 +++ .../model/UniformLagrangianConstraint.inl | 137 ++++ .../model/UnilateralConstraintResolution.h | 100 +++ .../model/UnilateralInteractionConstraint.h | 207 +----- .../model/UnilateralInteractionConstraint.inl | 399 +---------- ...cpp => UnilateralLagrangianConstraint.cpp} | 10 +- .../model/UnilateralLagrangianConstraint.h | 158 +++++ .../model/UnilateralLagrangianConstraint.inl | 421 ++++++++++++ ...lInteractionLagrangianConstraint_test.cpp} | 32 +- .../BilateralInteractionConstraint.scn | 4 +- .../Constraint/Projective/CMakeLists.txt | 82 ++- .../projective/AffineMovementConstraint.h | 145 +--- .../projective/AffineMovementConstraint.inl | 288 +------- ...=> AffineMovementProjectiveConstraint.cpp} | 14 +- .../AffineMovementProjectiveConstraint.h | 165 +++++ .../AffineMovementProjectiveConstraint.inl | 310 +++++++++ .../constraint/projective/AttachConstraint.h | 104 +-- .../projective/AttachConstraint.inl | 621 +---------------- ...int.cpp => AttachProjectiveConstraint.cpp} | 28 +- .../projective/AttachProjectiveConstraint.h | 124 ++++ .../projective/AttachProjectiveConstraint.inl | 643 ++++++++++++++++++ ....cpp => DirectionProjectiveConstraint.cpp} | 15 +- .../DirectionProjectiveConstraint.h | 133 ++++ .../DirectionProjectiveConstraint.inl | 277 ++++++++ .../constraint/projective/FixedConstraint.h | 118 +--- .../constraint/projective/FixedConstraint.inl | 404 +---------- .../projective/FixedPlaneConstraint.h | 114 +--- .../projective/FixedPlaneConstraint.inl | 295 +------- ...cpp => FixedPlaneProjectiveConstraint.cpp} | 18 +- .../FixedPlaneProjectiveConstraint.h | 135 ++++ .../FixedPlaneProjectiveConstraint.inl | 317 +++++++++ ...aint.cpp => FixedProjectiveConstraint.cpp} | 39 +- .../projective/FixedProjectiveConstraint.h | 137 ++++ .../projective/FixedProjectiveConstraint.inl | 426 ++++++++++++ .../projective/FixedRotationConstraint.h | 60 +- .../projective/FixedRotationConstraint.inl | 120 +--- ... => FixedRotationProjectiveConstraint.cpp} | 11 +- .../FixedRotationProjectiveConstraint.h | 79 +++ .../FixedRotationProjectiveConstraint.inl | 142 ++++ .../projective/FixedTranslationConstraint.h | 86 +-- .../projective/FixedTranslationConstraint.inl | 186 +---- ... FixedTranslationProjectiveConstraint.cpp} | 21 +- .../FixedTranslationProjectiveConstraint.h | 105 +++ .../FixedTranslationProjectiveConstraint.inl | 208 ++++++ .../projective/HermiteSplineConstraint.h | 114 +--- .../projective/HermiteSplineConstraint.inl | 245 +------ ... => HermiteSplineProjectiveConstraint.cpp} | 16 +- .../HermiteSplineProjectiveConstraint.h | 134 ++++ .../HermiteSplineProjectiveConstraint.inl | 267 ++++++++ ...raint.cpp => LineProjectiveConstraint.cpp} | 16 +- .../projective/LineProjectiveConstraint.h | 137 ++++ .../projective/LineProjectiveConstraint.inl | 286 ++++++++ .../projective/LinearMovementConstraint.h | 148 +--- .../projective/LinearMovementConstraint.inl | 453 +----------- ...=> LinearMovementProjectiveConstraint.cpp} | 33 +- .../LinearMovementProjectiveConstraint.h | 168 +++++ .../LinearMovementProjectiveConstraint.inl | 475 +++++++++++++ .../projective/LinearVelocityConstraint.h | 115 +--- .../projective/LinearVelocityConstraint.inl | 326 +-------- ...=> LinearVelocityProjectiveConstraint.cpp} | 27 +- .../LinearVelocityProjectiveConstraint.h | 135 ++++ .../LinearVelocityProjectiveConstraint.inl | 348 ++++++++++ .../projective/OscillatorConstraint.h | 90 +-- .../projective/OscillatorConstraint.inl | 105 +-- ...cpp => OscillatorProjectiveConstraint.cpp} | 15 +- .../OscillatorProjectiveConstraint.h | 112 +++ .../OscillatorProjectiveConstraint.inl | 127 ++++ .../projective/ParabolicConstraint.h | 105 +-- .../projective/ParabolicConstraint.inl | 241 +------ ....cpp => ParabolicProjectiveConstraint.cpp} | 15 +- .../ParabolicProjectiveConstraint.h | 126 ++++ .../ParabolicProjectiveConstraint.inl | 263 +++++++ .../projective/PartialFixedConstraint.h | 86 +-- .../projective/PartialFixedConstraint.inl | 321 +-------- ...p => PartialFixedProjectiveConstraint.cpp} | 31 +- .../PartialFixedProjectiveConstraint.h | 105 +++ .../PartialFixedProjectiveConstraint.inl | 343 ++++++++++ .../PartialLinearMovementConstraint.h | 156 +---- .../PartialLinearMovementConstraint.inl | 485 +------------ ...ialLinearMovementProjectiveConstraint.cpp} | 27 +- ...artialLinearMovementProjectiveConstraint.h | 176 +++++ ...tialLinearMovementProjectiveConstraint.inl | 507 ++++++++++++++ .../projective/PatchTestMovementConstraint.h | 143 +--- .../PatchTestMovementConstraint.inl | 427 +----------- ...PatchTestMovementProjectiveConstraint.cpp} | 15 +- .../PatchTestMovementProjectiveConstraint.h | 165 +++++ .../PatchTestMovementProjectiveConstraint.inl | 449 ++++++++++++ ...aint.cpp => PlaneProjectiveConstraint.cpp} | 16 +- .../projective/PlaneProjectiveConstraint.h | 137 ++++ .../projective/PlaneProjectiveConstraint.inl | 276 ++++++++ ...aint.cpp => PointProjectiveConstraint.cpp} | 23 +- .../projective/PointProjectiveConstraint.h | 130 ++++ .../projective/PointProjectiveConstraint.inl | 324 +++++++++ .../PositionBasedDynamicsConstraint.h | 94 +-- .../PositionBasedDynamicsConstraint.inl | 116 +--- ...tionBasedDynamicsProjectiveConstraint.cpp} | 32 +- ...ositionBasedDynamicsProjectiveConstraint.h | 114 ++++ ...itionBasedDynamicsProjectiveConstraint.inl | 138 ++++ .../projective/ProjectDirectionConstraint.h | 114 +--- .../projective/ProjectDirectionConstraint.inl | 255 +------ .../projective/ProjectToLineConstraint.h | 118 +--- .../projective/ProjectToLineConstraint.inl | 264 +------ .../projective/ProjectToPlaneConstraint.h | 117 +--- .../projective/ProjectToPlaneConstraint.inl | 254 +------ .../projective/ProjectToPointConstraint.h | 111 +-- .../projective/ProjectToPointConstraint.inl | 302 +------- .../projective/SkeletalMotionConstraint.h | 228 +------ .../projective/SkeletalMotionConstraint.inl | 400 +---------- ...=> SkeletalMotionProjectiveConstraint.cpp} | 11 +- .../SkeletalMotionProjectiveConstraint.h | 247 +++++++ .../SkeletalMotionProjectiveConstraint.inl | 422 ++++++++++++ ...fineMovementProjectiveConstraint_test.cpp} | 8 +- .../Projective/tests/CMakeLists.txt | 16 +- ...=> DirectionProjectiveConstraint_test.cpp} | 20 +- ...> FixedPlaneProjectiveConstraint_test.cpp} | 16 +- ...cpp => FixedProjectiveConstraint_test.cpp} | 20 +- ....cpp => LineProjectiveConstraint_test.cpp} | 20 +- ...PartialFixedProjectiveConstraint_test.cpp} | 16 +- ...cpp => PlaneProjectiveConstraint_test.cpp} | 20 +- ...cpp => PointProjectiveConstraint_test.cpp} | 20 +- .../TetrahedronDiffusionFEMForceField.scn | 6 +- .../tests/SquareDistanceMapping_test.cpp | 2 +- .../tests/SkeletalMotionConstraint_test.cpp | 14 +- .../odesolver/backward/StaticSolver.cpp | 4 +- .../tests/EulerImplicitSolverStatic_test.cpp | 2 +- .../Backward/tests/StaticSolver_test.cpp | 2 +- .../scenes/EulerImplicitSpringDynamicTest.xml | 4 +- .../odesolver/forward/EulerSolver.cpp | 4 +- .../component/odesolver/forward/EulerSolver.h | 2 +- .../testing/MassSpringSystemCreation.h | 2 +- .../Elastic/tests/BeamFEMForceField_test.cpp | 2 +- .../tests/TetrahedronFEMForceField_test.cpp | 2 +- .../tests/TriangleFEMForceField_test.cpp | 2 +- ...edronHyperelasticityFEMForceField_base.scn | 4 +- ...edronHyperelasticityFEMForceField_test.scn | 4 +- .../simutests/AffinePatch_test.cpp | 4 +- .../simutests/LinearElasticity_test.cpp | 24 +- .../testing/RegularGridNodeCreation.h | 6 +- .../performer/ConstraintAttachBodyPerformer.h | 6 +- .../ConstraintAttachBodyPerformer.inl | 6 +- .../performer/FixParticlePerformer.inl | 4 +- .../performer/SuturePointPerformer.h | 4 +- .../Core/src/sofa/core/ObjectFactory.cpp | 16 + .../src/sofa/helper/ComponentChange.cpp | 242 ++++--- .../Helper/src/sofa/helper/ComponentChange.h | 25 + .../SofaExporter/examples/OBJExporter.scn | 4 +- .../examples/ArticulatedSystemMapping.scn | 6 +- .../examples/BulletConvexHullDemo.scn | 4 +- .../examples/BulletLMDragon.scn | 2 +- .../examples/BulletSphere.scn | 4 +- .../examples/GlobalBulletCollision.py | 4 +- .../CollisionOBBCapsule/examples/OBBCap.scn | 4 +- .../CollisionOBBCapsule/examples/OBBCap1.scn | 4 +- .../examples/OBBCapEdgeEdge.scn | 4 +- .../examples/OBBCapEdgeVertex.scn | 4 +- .../examples/OBBCapVertexEdge.scn | 4 +- .../examples/OBBCapVertexVertex.scn | 4 +- .../CollisionOBBCapsule/examples/OBBOBB.scn | 4 +- .../CollisionOBBCapsule/examples/OBBOBB2.scn | 4 +- .../examples/OBBOBBAlea.scn | 4 +- .../examples/OBBOBBCollision.scn | 4 +- .../examples/OBBOBBEdgeEdge.scn | 4 +- .../examples/OBBOBBEdgeVertex.scn | 4 +- .../examples/OBBOBBFaceEdge.scn | 4 +- .../examples/OBBOBBVertexVertex.scn | 4 +- .../examples/OBBSphere.scn | 4 +- .../examples/OBBSphere2.scn | 4 +- .../examples/OBBSphereEdge.scn | 4 +- .../examples/OBBSphereVertex.scn | 4 +- .../CollisionOBBCapsule/examples/OBBTri.scn | 4 +- .../examples/OBBTriEdgeEdge.scn | 4 +- .../examples/OBBTriEdgeEdge2.scn | 4 +- .../examples/OBBTriEdgeVerex.scn | 4 +- .../examples/OBBTriFaceVertex.scn | 4 +- .../examples/OBBTriVertexEdge.scn | 4 +- .../examples/OBBTriVertexFace.scn | 4 +- .../examples/OBBTriVertexVertex.scn | 4 +- .../example/MultiMapping.py | 2 +- .../ExternalBehaviorModel/example/simple.scn | 6 +- .../scenes/Geomagic-DeformableCubes.scn | 6 +- .../scenes/Geomagic-DeformableSphere.scn | 4 +- .../Geomagic/scenes/Geomagic-FEMLiver.scn | 4 +- .../plugins/LeapMotion/examples/buffoon.scn | 2 +- .../examples/BeamLinearMapping_mt.scn | 4 +- .../examples/ParallelCGLinearSolver.scn | 4 +- .../ParallelHexahedronFEMForceField.scn | 4 +- .../examples/ParallelMeshSpringForceField.scn | 4 +- .../ParallelTetrahedronFEMForceField.scn | 4 +- .../TriangularForceFieldComparison.scn | 10 +- .../MultiThreading/examples/livers.scn | 10 +- .../examples/liversMeanPositions.scn | 12 +- .../plugins/Sensable/examples/Carving.scn | 4 +- .../Sensable/examples/Deformable-Method1.scn | 4 +- .../examples/Old Examples/flexibleRaptor.scn | 2 +- .../Old Examples/omni-probing-liver.scn | 2 +- .../SixenseHydra/Scenes/Hydra_buffon.scn | 2 +- .../plugins/SofaAssimp/SceneColladaLoader.cpp | 16 +- .../plugins/SofaAssimp/SceneColladaLoader.h | 4 +- .../plugins/SofaAssimp/doc/index.html | 4 +- .../SofaAssimp/examples/character_clothes.py | 2 +- applications/plugins/SofaCUDA/CMakeLists.txt | 22 +- .../SofaCUDA/examples/CudaDiagonalMass3f.scn | 4 +- .../examples/CudaMeshMatrixMass3f.scn | 4 +- .../SofaCUDA/examples/SquareTissue-cpu.scn | 4 +- .../SofaCUDA/examples/SquareTissue-cuda.scn | 4 +- .../plugins/SofaCUDA/examples/liver-CUDA.scn | 4 +- .../SofaCUDA/examples/quadSpringSphere.scn | 2 +- .../examples/quadSpringSphere2CUDA.scn | 2 +- .../plugins/SofaCUDA/examples/raptor-cpu.scn | 2 +- .../plugins/SofaCUDA/examples/raptor-cuda.scn | 4 +- .../SofaCUDA/examples/raptor-surface-cpu.scn | 4 +- .../SofaCUDA/examples/raptor-surface-cuda.scn | 4 +- .../plugins/SofaCUDA/examples/raptor.scn | 4 +- ...ahedronTLEDForceField_beam10x10x40_gpu.scn | 4 +- ...ahedronTLEDForceField_beam10x10x40_gpu.scn | 4 +- ...ahedronTLEDForceField_beam16x16x76_gpu.scn | 4 +- ...xahedronFEMForceField_beam10x10x40_cpu.scn | 4 +- ...xahedronFEMForceField_beam10x10x40_gpu.scn | 4 +- ...xahedronFEMForceField_beam16x16x76_cpu.scn | 4 +- ...xahedronFEMForceField_beam16x16x76_gpu.scn | 4 +- .../MeshSpringForceField_beam10x10x40_cpu.scn | 4 +- .../MeshSpringForceField_beam10x10x40_gpu.scn | 4 +- .../benchmarks/QuadSpringsSphere_cpu.scn | 2 +- .../benchmarks/QuadSpringsSphere_gpu.scn | 2 +- ...rahedronFEMForceField_beam10x10x40_cpu.scn | 4 +- ...rahedronFEMForceField_beam10x10x40_gpu.scn | 4 +- ...rahedronFEMForceField_beam16x16x76_cpu.scn | 4 +- ...rahedronFEMForceField_beam16x16x76_gpu.scn | 4 +- ...arFEMForceFieldOptim_tissue100x100_cpu.scn | 4 +- ...arFEMForceFieldOptim_tissue100x100_gpu.scn | 4 +- ...ronFEMForceField_beam10x10x40_implicit.scn | 8 +- ...xahedronFEMForceField_beam10x10x40_rk4.scn | 8 +- ...SpringForceField_beam10x10x40_implicit.scn | 8 +- ...aMeshSpringForceField_beam10x10x40_rk4.scn | 8 +- ...ronFEMForceField_beam10x10x40_implicit.scn | 8 +- ...rahedronFEMForceField_beam10x10x40_rk4.scn | 8 +- ...ForceFieldOptim_tissue100x100_implicit.scn | 8 +- ...EMForceFieldOptim_tissue20x20_implicit.scn | 8 +- .../cpu-gpu_validation/QuadSpringsSphere.scn | 4 +- ... => CudaBilateralLagrangianConstraint.cpp} | 20 +- .../projective/CudaFixedConstraint.cu | 223 ------ .../projective/CudaFixedConstraint.h | 89 +-- .../projective/CudaFixedConstraint.inl | 431 +----------- ....cpp => CudaFixedProjectiveConstraint.cpp} | 40 +- .../CudaFixedProjectiveConstraint.cu | 223 ++++++ .../CudaFixedProjectiveConstraint.h | 112 +++ .../CudaFixedProjectiveConstraint.inl | 453 ++++++++++++ ...aFixedTranslationProjectiveConstraint.cpp} | 36 +- .../CudaLinearMovementConstraint.cu | 208 ------ .../projective/CudaLinearMovementConstraint.h | 188 +---- .../CudaLinearMovementConstraint.inl | 574 +--------------- ...udaLinearMovementProjectiveConstraint.cpp} | 20 +- .../CudaLinearMovementProjectiveConstraint.cu | 208 ++++++ .../CudaLinearMovementProjectiveConstraint.h | 210 ++++++ ...CudaLinearMovementProjectiveConstraint.inl | 596 ++++++++++++++++ ...udaLinearVelocityProjectiveConstraint.cpp} | 20 +- .../SofaCarving/examples/CarvingTool.scn | 6 +- .../SofaCarving/examples/SimpleCarving.py | 2 +- .../SofaCarving/examples/SimpleCarving.scn | 4 +- .../SimpleCarving_withPenetration.scn | 4 +- .../FFDDistanceGridCollisionModel.scn | 4 +- .../plugins/SofaHAPI/examples/SofaHAPI1.scn | 4 +- .../examples/ComplianceMatrixExporter.scn | 8 +- .../examples/ComplianceMatrixImage.scn | 8 +- .../examples/FillReducingOrdering.scn | 6 +- .../examples/GlobalSystemMatrixExporter.scn | 10 +- .../examples/GlobalSystemMatrixImage.scn | 6 +- .../examples/MatrixContributions121.scn | 6 +- .../examples/MatrixContributions122.scn | 10 +- .../examples/MatrixContributions123.scn | 10 +- .../examples/FEMBAR-SparsePARDISOSolver.scn | 2 +- .../plugins/SofaSimpleGUI/examples/liver.scn | 4 +- .../plugins/SofaSimpleGUI/examples/oneTet.scn | 4 +- .../examples/ParticlesRepulsionForceField.scn | 2 +- .../plugins/SofaTest/Elasticity_test.h | 4 +- .../plugins/SofaTest/Elasticity_test.inl | 22 +- .../plugins/SofaTest/InitPlugin_test.h | 2 +- .../SofaTest/SofaTest_test/scenes/damping.py | 4 +- .../SceneChecking/SceneCheckUsingAlias.cpp | 8 +- .../TriangleFEMForceField_compare.scn | 8 +- .../Accuracy/cylinder_PhantomSolution.scn | 4 +- .../Bar16-fem-implicit-CudaVec3f.pscn | 2 +- .../Performance/Bar16-fem-implicit-Vec3d.pscn | 4 +- .../Performance/Bar16-fem-implicit-Vec3f.pscn | 2 +- .../Bar16-spring-rk4-CudaVec3f.pscn | 2 +- .../Performance/Bar16-spring-rk4-Vec3d.pscn | 4 +- .../Performance/Bar16-spring-rk4-Vec3f.pscn | 2 +- .../MatrixAssembly_assembledCG.scn | 4 +- .../MatrixAssembly_assembledCG_blocs.scn | 4 +- .../MatrixAssembly/MatrixAssembly_direct.scn | 4 +- .../MatrixAssembly_direct_blocs.scn | 4 +- .../MatrixAssembly_matrixfreeCG.scn | 4 +- ...neMovementConstraint__RemovingMeshTest.scn | 4 +- .../FixedConstraint_RemovingMeshTest.scn | 4 +- .../FixedPlaneConstraint_RemovingMeshTest.scn | 4 +- ...earMovementConstraint_RemovingMeshTest.scn | 4 +- ...ctDirectionConstraint_RemovingMeshTest.scn | 4 +- ...ojectToLineConstraint_RemovingMeshTest.scn | 4 +- ...jectToPlaneConstraint_RemovingMeshTest.scn | 4 +- ...jectToPointConstraint_RemovingMeshTest.scn | 4 +- .../BilateralInteractionConstraint_NNCG.scn | 12 +- .../BilateralInteractionConstraint_PGS.scn | 12 +- .../BilateralInteractionConstraint_Rigid.scn | 10 +- .../BilateralInteractionConstraint_UGS.scn | 12 +- .../Lagrangian/InextensiblePendulum.scn | 8 +- .../Lagrangian/SlidingConstraint.scn | 6 +- .../Projective/AffineMovementConstraint.scn | 4 +- .../Projective/AffineMovementConstraint3D.scn | 4 +- .../Projective/AttachConstraint.scn | 10 +- .../Projective/AttachConstraintMatrix.scn | 10 +- .../Projective/BilinearConstraint.scn | 4 +- .../Projective/BilinearConstraint3D.scn | 4 +- .../Constraint/Projective/BoxConstraint.scn | 2 +- .../Constraint/Projective/FixedConstraint.scn | 4 +- .../Projective/FixedPlaneConstraint.scn | 4 +- .../Projective/FixedRotationConstraint.scn | 8 +- .../Projective/HermiteSplineConstraint.scn | 6 +- .../Projective/LinearMovementConstraint.scn | 8 +- .../Projective/OscillatorConstraint.scn | 6 +- .../Projective/OscillatorConstraint_rigid.scn | 6 +- .../Projective/ParabolicConstraint.scn | 4 +- .../Projective/PartialFixedConstraint.scn | 4 +- .../Projective/PatchTestConstraint.scn | 4 +- .../Constraint/Projective/PlaneConstraint.scn | 2 +- .../Projective/ProjectDirectionConstraint.scn | 4 +- .../Projective/ProjectToLineConstraint.scn | 4 +- .../Projective/ProjectToPlaneConstraint.scn | 4 +- .../Projective/ProjectToPointConstraint.scn | 4 +- .../Controller/MechanicalStateController.scn | 4 +- .../TetrahedronDiffusionFEMForceField.scn | 6 +- .../Engine/Analyze/ShapeMatching.scn | 4 +- .../Engine/Generate/GenerateCylinder.scn | 8 +- .../Engine/Generate/GenerateGrid.scn | 14 +- .../Component/Engine/Generate/MergePoints.scn | 2 +- .../Engine/Generate/MeshTetraStuffing.scn | 2 +- examples/Component/Engine/Select/BoxROI.scn | 4 +- .../Component/Engine/Select/BoxROI_1d.scn | 4 +- .../Component/Engine/Select/BoxROI_2d.scn | 4 +- .../Engine/Select/MeshBoundaryROI.scn | 4 +- .../Engine/Select/MeshSplittingEngine.scn | 4 +- .../Engine/Select/NearestPointROI.scn | 16 +- examples/Component/Engine/Select/PlaneROI.scn | 4 +- .../Engine/Select/PointsFromIndices.scn | 4 +- .../Component/Engine/Select/ProximityROI.scn | 4 +- .../Component/Engine/Select/SphereROI.scn | 4 +- .../Engine/Select/SubsetTopology.scn | 4 +- .../SubsetTopology_localIndicesOption.scn | 4 +- .../Select/SubsetTopology_refiningMesh.scn | 2 +- .../Select/SubsetTopology_withtetrahedra.scn | 6 +- .../ValuesFromPositions_vectorField.scn | 4 +- .../Transform/DisplacementMatrixEngine.scn | 4 +- examples/Component/IO/Mesh/GIDMeshLoader.scn | 4 +- .../Component/IO/Mesh/GridMeshCreator.scn | 2 +- .../Component/IO/Mesh/LiverUseNewLoaders.scn | 4 +- examples/Component/IO/Mesh/MeshGmshLoader.scn | 6 +- .../LinearSolver/Direct/Eigen3-SVD.scn | 4 +- .../Direct/FEMBAR_SVDLinearSolver.scn | 2 +- .../Component/LinearSolver/FEMBAR-common.xml | 4 +- .../LinearSolver/Iterative/CGLinearSolver.scn | 4 +- .../LinearSystem/CompositeLinearSystem.scn | 8 +- .../ConstantSparsityPatternSystem.scn | 8 +- .../LinearSystem/MatrixLinearSystem.scn | 8 +- .../PendulumSpringsDistanceMapping.scn | 6 +- .../Linear/BarycentricMappingTrussBeam.scn | 4 +- .../Linear/BarycentricTetraMapping.scn | 4 +- .../Mapping/Linear/CenterOfMassMapping.scn | 4 +- .../Linear/DeformableOnRigidFrameMapping.scn | 4 +- ...formableOnRigidFrameMappingConstraints.scn | 2 +- .../Mapping/Linear/IdentityMapping.scn | 4 +- ...impleTesselatedTetraTopologicalMapping.scn | 4 +- .../Mapping/Linear/SkinningMapping.scn | 4 +- .../Mapping/Linear/SubsetMapping.scn | 4 +- .../Mapping/NonLinear/DistanceMapping.scn | 4 +- .../NonLinear/DistanceMultiMapping.scn | 6 +- .../Mapping/NonLinear/RigidMapping-basic.scn | 4 +- .../NonLinear/RigidMapping2d-basic.scn | 4 +- .../NonLinear/RigidRigidMapping-basic.scn | 4 +- .../Mapping/NonLinear/RigidRigidMapping.scn | 4 +- .../NonLinear/SquareDistanceMapping.scn | 4 +- .../Mapping/NonLinear/SquareMapping.scn | 6 +- examples/Component/Mass/DiagonalMass.scn | 4 +- examples/Component/Mass/MeshMatrixMass.scn | 4 +- examples/Component/Mass/UniformMass.scn | 4 +- .../MechanicalLoad/ConstantForceField.scn | 2 +- .../MechanicalLoad/EllipsoidForceField.scn | 4 +- .../InteractionEllipsoidForceField.scn | 8 +- .../MechanicalLoad/SphereForceField.scn | 2 +- .../SurfacePressureForceField.scn | 2 +- .../TaitSurfacePressureForceField.scn | 2 +- .../TrianglePressureForceField.scn | 6 +- .../EulerImplicitSolver-comparison.scn | 10 +- .../Backward/EulerImplicitSolver.scn | 4 +- .../Backward/NewmarkImplicitSolver.scn | 8 +- .../ODESolver/Backward/StaticSolver.scn | 8 +- .../Backward/VariationalSymplecticSolver.scn | 2 +- .../ODESolver/Forward/EulerExplicitSolver.scn | 4 +- .../Forward/EulerExplicitSolver_diagonal.scn | 4 +- .../Forward/EulerSymplecticSolver.scn | 4 +- .../EulerSymplecticSolver_diagonal.scn | 4 +- .../ODESolver/Forward/RungeKutta4Solver.scn | 4 +- examples/Component/SceneUtility/Monitor.scn | 4 +- .../SolidMechanics/FEM/BeamFEMForceField.scn | 8 +- .../FastTetrahedralCorotationalForceField.scn | 10 +- ...edronCorotationalForceField_validation.scn | 6 +- ...Heterogeneous-TetrahedronFEMForceField.scn | 2 +- .../FEM/HexahedralFEMForceField.scn | 4 +- .../FEM/HexahedralFEMForceFieldAndMass.scn | 4 +- ...exahedronCompositeFEMForceFieldAndMass.scn | 2 +- .../FEM/HexahedronCompositeFEMMapping.scn | 2 +- .../FEM/HexahedronFEMForceField.scn | 4 +- .../FEM/HexahedronFEMForceFieldAndMass.scn | 4 +- .../FEM/QuadBendingFEMForceField.scn | 4 +- .../FEM/StandardTetrahedralFEMForceField.scn | 12 +- .../TetrahedralCorotationalFEMForceField.scn | 8 +- .../FEM/TetrahedronFEMForceField.scn | 10 +- .../FEM/TetrahedronFEMForceField_assemble.scn | 6 +- ...etrahedronHyperelasticityFEMForceField.scn | 12 +- .../SolidMechanics/FEM/TopoMap_cylinder3d.scn | 6 +- .../FEM/TriangleFEMForceField.scn | 8 +- .../FEM/TriangularFEMForceField.scn | 4 +- .../FEM/TriangularFEMForceFieldOptim.scn | 6 +- .../FEM/TriangularForceFieldComparison.scn | 14 +- .../Spring/FastTriangularBendingSprings.scn | 4 +- .../Spring/GearSpringForceField.scn | 4 +- .../Spring/JointSpringForceField.scn | 4 +- .../Spring/PolynomialSpringsForceField.scn | 4 +- .../Spring/QuadBendingSprings.scn | 4 +- .../Spring/QuadularBendingSprings.scn | 4 +- .../Spring/StiffSpringForceField.scn | 4 +- .../Spring/StiffSpringForceField_simple.scn | 4 +- .../Spring/TriangleBendingSprings.scn | 8 +- .../Spring/TriangularBendingSprings.scn | 4 +- ...TriangularBiquadraticSpringsForceField.scn | 4 +- .../TriangularQuadraticSpringsForceField.scn | 4 +- .../Spring/angularSpringForceField.scn | 4 +- .../TetrahedralTensorMassForceField.scn | 4 +- .../TriangularTensorMassForceField.scn | 4 +- .../Container/Constant/CubeTopology.scn | 4 +- .../Container/Constant/MeshTopology.scn | 4 +- .../Dynamic/AddingHexa2QuadProcess.scn | 2 +- .../Dynamic/AddingQuad2TriangleProcess.scn | 4 +- .../Dynamic/AddingTetra2TriangleProcess.scn | 4 +- .../Container/Dynamic/AddingTetraProcess.scn | 4 +- .../Dynamic/AddingTriangle2EdgeProcess.scn | 4 +- .../Dynamic/AddingTrianglesProcess.scn | 4 +- .../Dynamic/IncisionTrianglesProcess.scn | 6 +- .../QuadForceFieldTopologyChangeHandling.scn | 6 +- ...RemovingBilateralInteractionConstraint.scn | 8 +- .../Dynamic/RemovingHexa2QuadProcess.scn | 4 +- .../Dynamic/RemovingHexa2TetraProcess.scn | 4 +- .../Dynamic/RemovingPointSprings.scn | 4 +- .../Dynamic/RemovingQuad2TriangleProcess.scn | 4 +- .../Dynamic/RemovingTetra2TriangleProcess.scn | 6 +- ...gTetra2TriangleProcess_performanceTest.scn | 6 +- .../RemovingTetra2Triangle_options1.scn | 4 +- .../RemovingTetra2Triangle_options2.scn | 4 +- .../Dynamic/RemovingTetraProcess.scn | 4 +- ...emovingTetraProcess_withCollisionModel.scn | 4 +- .../Dynamic/RemovingTrianglesProcess.scn | 4 +- ...hedronForceFieldTopologyChangeHandling.scn | 10 +- ...ngularForceFieldTopologyChangeHandling.scn | 14 +- .../Container/Grid/CylinderGridTopology.scn | 2 +- .../Container/Grid/RegularGridTopology.scn | 2 +- .../RegularGridTopology_TrianglesMesh.scn | 4 +- .../Grid/RegularGridTopology_dimension.scn | 8 +- .../Grid/SparseGridRamificationTopology.scn | 2 +- .../Container/Grid/SparseGridTopology.scn | 2 +- .../Container/Grid/SphereGridTopology.scn | 2 +- .../Mapping/Edge2QuadTopologicalMapping.scn | 4 +- .../Mapping/Hexa2QuadTopologicalMapping.scn | 4 +- .../Mapping/Hexa2TetraTopologicalMapping.scn | 4 +- .../Hexa2TetraTopologicalMapping_export.scn | 4 +- .../Mapping/Mesh2PointTopologicalMapping.scn | 4 +- .../Quad2TriangleTopologicalMapping.scn | 4 +- .../Mapping/SubsetTopologicalMapping.scn | 4 +- .../Mapping/SubsetTopologicalMapping2.scn | 4 +- .../Tetra2TriangleTopologicalMapping.scn | 6 +- ...ogicalMapping_NoInitialTriangle_option.scn | 6 +- ...pologicalMapping_with_TetrahedronModel.scn | 6 +- .../Mapping/TopoMap_Hexa2Quad2Triangle.scn | 4 +- .../Triangle2EdgeTopologicalMapping.scn | 4 +- examples/Component/Visual/DataDisplay.scn | 4 +- .../Visual/LinearBlendSkinningGPU.scn | 4 +- examples/Component/Visual/OglShader.scn | 4 +- .../Visual/OglShader_tessellation.scn | 2 +- examples/Component/Visual/OglViewport.scn | 4 +- .../PostProcessManager_DepthOfField.scn | 4 +- examples/Component/Visual/VisualStyle.scn | 4 +- examples/Demos/TriangleSurfaceCutting.scn | 4 +- examples/Demos/include_test.scn | 2 +- examples/Demos/include_test.xml | 2 +- examples/Demos/liver.scn | 4 +- examples/Demos/liverConfiguration.scn | 4 +- examples/Demos/rigidifiedSectionsInBeam.scn | 6 +- examples/Demos/simpleBoundaryConditions.scn | 8 +- examples/Demos/simpleSphere.scn | 4 +- examples/Demos/skybox.scn | 4 +- examples/Objects/BoxConstraint.xml | 2 +- examples/Objects/InstrumentCoil.xml | 2 +- examples/Objects/PlaneConstraint.xml | 2 +- .../Tutorials/Basic/TutorialBasicPendulum.scn | 4 +- .../TutorialForceFieldLiverFEM.scn | 4 +- .../TutorialForceFieldLiverHexaFEM.scn | 4 +- .../TutorialForceFieldLiverSprings.scn | 4 +- .../TutorialForceFieldLiverTriangleFEM.scn | 4 +- .../TutorialMappingLiverBarycentric.scn | 4 +- examples/Tutorials/OldTutorials/demo1.scn | 2 +- examples/Tutorials/OldTutorials/demo2.scn | 2 +- examples/Tutorials/OldTutorials/demo3.scn | 4 +- examples/Tutorials/OldTutorials/demo4.scn | 4 +- examples/Tutorials/OldTutorials/demo5.scn | 4 +- examples/Tutorials/OldTutorials/demo6.scn | 4 +- .../Tutorials/OldTutorials/demo6Triangle.scn | 4 +- examples/Tutorials/OldTutorials/demo7.scn | 4 +- .../Tutorials/OldTutorials/demo7Triangle.scn | 4 +- .../StepByStep/Pendulum/2_Pendulum.scn | 4 +- .../StepByStep/Pendulum/3_Pendulum.scn | 4 +- .../StepByStep/Pendulum/4_Pendulum.scn | 4 +- .../StepByStep/Pendulum/5_Pendulum.scn | 4 +- .../StepByStep/Pendulum/6_Pendulum.scn | 4 +- .../StepByStep/Pendulum/7_Pendulum.scn | 4 +- .../TopologicalMapping/2_TopoMapping.html | 2 +- .../TopologicalMapping/2_TopoMapping.scn | 6 +- .../TopologicalMapping/3_TopoMapping.scn | 6 +- .../TopologicalMapping/4_TopoMapping.scn | 6 +- .../TopologicalMapping/5_TopoMapping.scn | 4 +- .../TopologicalMapping/6_TopoMapping.scn | 4 +- .../Topologies/TopologyDynamicSurfaceMesh.scn | 6 +- .../TopologyHexa2QuadTopologicalMapping.scn | 4 +- .../TopologyHexa2TetraTopologicalMapping.scn | 4 +- .../TopologyLinearDifferentMesh.scn | 8 +- .../Topologies/TopologyLinearMesh.scn | 6 +- ...opologyQuad2TriangleTopologicalMapping.scn | 4 +- .../TopologySurfaceDifferentMesh.scn | 8 +- ...pologyTetra2TriangleTopologicalMapping.scn | 6 +- ...opologyTriangle2EdgeTopologicalMapping.scn | 4 +- .../TopologyVolumeDifferentMesh.scn | 8 +- .../sandbox/explicit_singlehexaFEM.scn | 4 +- .../sandbox/implicit_singlehexaFEM.scn | 4 +- .../sandbox/implicit_singlehexaFEM_2.scn | 4 +- .../sandbox/rungekutta_singlehexaFEM.scn | 4 +- 564 files changed, 15086 insertions(+), 13387 deletions(-) rename Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/{BilateralInteractionConstraint.cpp => BilateralLagrangianConstraint.cpp} (58%) create mode 100644 Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralLagrangianConstraint.h create mode 100644 Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralLagrangianConstraint.inl rename Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/{SlidingConstraint.cpp => SlidingLagrangianConstraint.cpp} (85%) create mode 100644 Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingLagrangianConstraint.h create mode 100644 Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingLagrangianConstraint.inl rename Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/{StopperConstraint.cpp => StopperLagrangianConstraint.cpp} (85%) create mode 100644 Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperLagrangianConstraint.h create mode 100644 Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperLagrangianConstraint.inl rename Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/{UniformConstraint.cpp => UniformLagrangianConstraint.cpp} (82%) create mode 100644 Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformLagrangianConstraint.h create mode 100644 Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformLagrangianConstraint.inl create mode 100644 Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralConstraintResolution.h rename Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/{UnilateralInteractionConstraint.cpp => UnilateralLagrangianConstraint.cpp} (91%) create mode 100644 Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralLagrangianConstraint.h create mode 100644 Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralLagrangianConstraint.inl rename Sofa/Component/Constraint/Lagrangian/Model/tests/{BilateralInteractionConstraint_test.cpp => BilateralInteractionLagrangianConstraint_test.cpp} (85%) rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{AffineMovementConstraint.cpp => AffineMovementProjectiveConstraint.cpp} (79%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{AttachConstraint.cpp => AttachProjectiveConstraint.cpp} (71%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{ProjectDirectionConstraint.cpp => DirectionProjectiveConstraint.cpp} (76%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/DirectionProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/DirectionProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{FixedPlaneConstraint.cpp => FixedPlaneProjectiveConstraint.cpp} (78%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{FixedConstraint.cpp => FixedProjectiveConstraint.cpp} (73%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{FixedRotationConstraint.cpp => FixedRotationProjectiveConstraint.cpp} (82%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{FixedTranslationConstraint.cpp => FixedTranslationProjectiveConstraint.cpp} (76%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{HermiteSplineConstraint.cpp => HermiteSplineProjectiveConstraint.cpp} (77%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{ProjectToPlaneConstraint.cpp => LineProjectiveConstraint.cpp} (80%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LineProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LineProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{LinearMovementConstraint.cpp => LinearMovementProjectiveConstraint.cpp} (71%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{LinearVelocityConstraint.cpp => LinearVelocityProjectiveConstraint.cpp} (74%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{OscillatorConstraint.cpp => OscillatorProjectiveConstraint.cpp} (79%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{ParabolicConstraint.cpp => ParabolicProjectiveConstraint.cpp} (77%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{PartialFixedConstraint.cpp => PartialFixedProjectiveConstraint.cpp} (72%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{PartialLinearMovementConstraint.cpp => PartialLinearMovementProjectiveConstraint.cpp} (73%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{PatchTestMovementConstraint.cpp => PatchTestMovementProjectiveConstraint.cpp} (84%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{ProjectToLineConstraint.cpp => PlaneProjectiveConstraint.cpp} (77%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PlaneProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PlaneProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{ProjectToPointConstraint.cpp => PointProjectiveConstraint.cpp} (69%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PointProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PointProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{PositionBasedDynamicsConstraint.cpp => PositionBasedDynamicsProjectiveConstraint.cpp} (80%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/{SkeletalMotionConstraint.cpp => SkeletalMotionProjectiveConstraint.cpp} (83%) create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionProjectiveConstraint.h create mode 100644 Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionProjectiveConstraint.inl rename Sofa/Component/Constraint/Projective/tests/{AffineMovementConstraint_test.cpp => AffineMovementProjectiveConstraint_test.cpp} (95%) rename Sofa/Component/Constraint/Projective/tests/{ProjectDirectionConstraint_test.cpp => DirectionProjectiveConstraint_test.cpp} (92%) rename Sofa/Component/Constraint/Projective/tests/{FixedPlaneConstraint_test.cpp => FixedPlaneProjectiveConstraint_test.cpp} (89%) rename Sofa/Component/Constraint/Projective/tests/{FixedConstraint_test.cpp => FixedProjectiveConstraint_test.cpp} (92%) rename Sofa/Component/Constraint/Projective/tests/{ProjectToLineConstraint_test.cpp => LineProjectiveConstraint_test.cpp} (92%) rename Sofa/Component/Constraint/Projective/tests/{PartialFixedConstraint_test.cpp => PartialFixedProjectiveConstraint_test.cpp} (88%) rename Sofa/Component/Constraint/Projective/tests/{ProjectToPlaneConstraint_test.cpp => PlaneProjectiveConstraint_test.cpp} (92%) rename Sofa/Component/Constraint/Projective/tests/{ProjectToPointConstraint_test.cpp => PointProjectiveConstraint_test.cpp} (92%) rename applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/lagrangian/model/{CudaBilateralInteractionConstraint.cpp => CudaBilateralLagrangianConstraint.cpp} (72%) delete mode 100644 applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedConstraint.cu rename applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/{CudaFixedConstraint.cpp => CudaFixedProjectiveConstraint.cpp} (54%) create mode 100644 applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedProjectiveConstraint.cu create mode 100644 applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedProjectiveConstraint.h create mode 100644 applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedProjectiveConstraint.inl rename applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/{CudaFixedTranslationConstraint.cpp => CudaFixedTranslationProjectiveConstraint.cpp} (70%) delete mode 100644 applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementConstraint.cu rename applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/{CudaLinearMovementConstraint.cpp => CudaLinearMovementProjectiveConstraint.cpp} (72%) create mode 100644 applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementProjectiveConstraint.cu create mode 100644 applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementProjectiveConstraint.h create mode 100644 applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementProjectiveConstraint.inl rename applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/{CudaLinearVelocityConstraint.cpp => CudaLinearVelocityProjectiveConstraint.cpp} (75%) diff --git a/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/FrictionContact.h b/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/FrictionContact.h index abfe6878d00..a50fc209383 100644 --- a/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/FrictionContact.h +++ b/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/FrictionContact.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include @@ -60,7 +60,7 @@ class FrictionContact : public core::collision::Contact, public ContactIdentifie mapper::ContactMapper mapper1; mapper::ContactMapper mapper2; - constraint::lagrangian::model::UnilateralInteractionConstraint::SPtr m_constraint; + constraint::lagrangian::model::UnilateralLagrangianConstraint::SPtr m_constraint; core::objectmodel::BaseContext* parent; Data mu; ///< friction coefficient (0 for frictionless contacts) diff --git a/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/FrictionContact.inl b/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/FrictionContact.inl index d753e9ed690..d0d093e4db1 100644 --- a/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/FrictionContact.inl +++ b/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/FrictionContact.inl @@ -144,7 +144,7 @@ void FrictionContact::activ { mmodel2 = mapper2.createMapping(getName().c_str()); } - m_constraint = sofa::core::objectmodel::New >(mmodel1, mmodel2); + m_constraint = sofa::core::objectmodel::New >(mmodel1, mmodel2); m_constraint->setName( getName() ); setInteractionTags(mmodel1, mmodel2); m_constraint->setCustomTolerance( tol.getValue() ); diff --git a/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/StickContactConstraint.h b/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/StickContactConstraint.h index f612ad49d70..f51e5f20b53 100644 --- a/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/StickContactConstraint.h +++ b/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/StickContactConstraint.h @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include @@ -58,7 +58,7 @@ class StickContactConstraint : public core::collision::Contact, public ContactId mapper::ContactMapper mapper1; mapper::ContactMapper mapper2; - constraint::lagrangian::model::BilateralInteractionConstraint::SPtr m_constraint; + constraint::lagrangian::model::BilateralLagrangianConstraint::SPtr m_constraint; core::objectmodel::BaseContext* parent; std::vector< sofa::core::collision::DetectionOutput* > contacts; diff --git a/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/StickContactConstraint.inl b/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/StickContactConstraint.inl index f3af1c76aca..49ad5f0e91a 100644 --- a/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/StickContactConstraint.inl +++ b/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/StickContactConstraint.inl @@ -128,7 +128,7 @@ void StickContactConstraint::activateMappers( msg_info() << "Creating StickContactConstraint bilateral constraints"; MechanicalState1* mstate1 = mapper1.createMapping(mapper::GenerateStringID::generate().c_str()); MechanicalState2* mstate2 = mapper2.createMapping(mapper::GenerateStringID::generate().c_str()); - m_constraint = sofa::core::objectmodel::New >(mstate1, mstate2); + m_constraint = sofa::core::objectmodel::New >(mstate1, mstate2); m_constraint->setName( getName() ); } diff --git a/Sofa/Component/Constraint/Lagrangian/Model/CMakeLists.txt b/Sofa/Component/Constraint/Lagrangian/Model/CMakeLists.txt index 147e6931b3e..0271b551fcc 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/CMakeLists.txt +++ b/Sofa/Component/Constraint/Lagrangian/Model/CMakeLists.txt @@ -15,17 +15,30 @@ set(HEADER_FILES ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/StopperConstraint.inl ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/UniformConstraint.h ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/UniformConstraint.inl + ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/UnilateralConstraintResolution.h ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/UnilateralInteractionConstraint.h ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/UnilateralInteractionConstraint.inl + + ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/BilateralLagrangianConstraint.h + ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/BilateralLagrangianConstraint.inl + ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/SlidingLagrangianConstraint.h + ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/SlidingLagrangianConstraint.inl + ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/StopperLagrangianConstraint.h + ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/StopperLagrangianConstraint.inl + ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/UniformLagrangianConstraint.h + ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/UniformLagrangianConstraint.inl + ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/UnilateralLagrangianConstraint.h + ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/UnilateralLagrangianConstraint.inl ) set(SOURCE_FILES ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/init.cpp - ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/BilateralInteractionConstraint.cpp - ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/SlidingConstraint.cpp - ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/StopperConstraint.cpp - ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/UniformConstraint.cpp - ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/UnilateralInteractionConstraint.cpp + ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/BilateralLagrangianConstraint.cpp + ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/SlidingLagrangianConstraint.cpp + ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/StopperLagrangianConstraint.cpp + ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/UniformLagrangianConstraint.cpp + ${SOFACOMPONENTCONSTRAINTLAGRANGIANMODEL_SOURCE_DIR}/UnilateralLagrangianConstraint.cpp + ) sofa_find_package(Sofa.Simulation.Core REQUIRED) diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralInteractionConstraint.h b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralInteractionConstraint.h index af6f155bde2..88739f76ee8 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralInteractionConstraint.h +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralInteractionConstraint.h @@ -20,176 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include +#include -#include -#include -#include -#include - -#include - -#include +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/lagrangian/model/BilateralLagrangianConstraint.h") namespace sofa::component::constraint::lagrangian::model { - -/// These 'using' are in a per-file namespace so they will not leak -/// and polluate the standard namespace. -using sofa::core::behavior::BaseConstraint ; -using sofa::core::behavior::ConstraintResolution ; -using sofa::core::behavior::PairInteractionConstraint ; -using sofa::core::objectmodel::Data ; -using sofa::core::ConstraintParams ; -using sofa::core::ConstVecCoordId; - -using sofa::linearalgebra::BaseVector ; -using sofa::type::Vec3d; -using sofa::type::Quat ; - -using sofa::defaulttype::Rigid3Types ; -using sofa::defaulttype::Vec3Types ; - - template -class BilateralInteractionConstraintSpecialization {}; - - -template -class BilateralInteractionConstraint : public PairInteractionConstraint -{ -public: - SOFA_CLASS(SOFA_TEMPLATE(BilateralInteractionConstraint,DataTypes), - SOFA_TEMPLATE(PairInteractionConstraint,DataTypes)); - - /// That any templates variation of BilateralInteractionConstraintSpecialization are friend. - template - friend class BilateralInteractionConstraintSpecialization ; - - typedef PairInteractionConstraint Inherit; - - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename Coord::value_type Real; - typedef typename DataTypes::MatrixDeriv::RowIterator MatrixDerivRowIterator; - - typedef core::behavior::MechanicalState MechanicalState; - typedef BaseConstraint::PersistentID PersistentID; - - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef Data DataMatrixDeriv; - - using SubsetIndices = type::vector; - using DataSubsetIndices = sofa::core::topology::TopologySubsetIndices; - -protected: - std::vector dfree; - Quat q; - - std::vector cid; - - DataSubsetIndices m1; ///< index of the constraint on the first model - DataSubsetIndices m2; ///< index of the constraint on the second model - Data restVector; ///< Relative position to maintain between attached points (optional) - VecCoord initialDifference; - - Data d_numericalTolerance; ///< a real value specifying the tolerance during the constraint solving. (default=0.0001 - Data d_activate; ///< bool to control constraint activation - Data keepOrientDiff; ///< keep the initial difference in orientation (only for rigids) - - - SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology1; ///< Link to be set to the first topology container in order to support topological changes - SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology2; ///< Link to be set to the second topology container in order to support topological changes - - std::vector prevForces; - - SOFA_ATTRIBUTE_DISABLED__BILATERALINTERACTIONCONSTRAINTDATA("Data 'activateAtIteration' has been removed, please use the Data d_activate instead and an engine or a script to change the behavior at the right step (see PR #3327).") - sofa::core::objectmodel::lifecycle::RemovedData activateAtIteration{this, "v22.12", "v23.06", "activateAtIteration", "use the boolean data 'activate' instead and an engine or a script to change the behavior at the right step (see PR #3327)."}; - - SOFA_ATTRIBUTE_DISABLED__BILATERALINTERACTIONCONSTRAINTDATA("Data 'merge' has been removed. Its behavior was unused, undocumented, untested, and unclear (see PR #3328).") - sofa::core::objectmodel::lifecycle::RemovedData merge{this, "v22.12", "v23.06", "merge", "Its behavior was unused, undocumented, untested, and unclear (see PR #3328), please report to sofa-dev if you want the feature back."}; - - SOFA_ATTRIBUTE_DISABLED__BILATERALINTERACTIONCONSTRAINTDATA("Data 'derivative' has been removed. Its behavior was unused, undocumented, untested, and unclear (see PR #3328).") - sofa::core::objectmodel::lifecycle::RemovedData derivative{this, "v22.12", "v23.06", "derivative", "Its behavior was unused, undocumented, untested, and unclear (see PR #3328), please report to sofa-dev if you want the feature back."}; - - - BilateralInteractionConstraint(MechanicalState* object1, MechanicalState* object2) ; - BilateralInteractionConstraint(MechanicalState* object) ; - BilateralInteractionConstraint(); - - virtual ~BilateralInteractionConstraint(){} -public: - void init() override; - - void bwdInit() override {} - - void reinit() override; - - void buildConstraintMatrix(const ConstraintParams* cParams, - DataMatrixDeriv &c1, DataMatrixDeriv &c2, - unsigned int &cIndex, - const DataVecCoord &x1, const DataVecCoord &x2) override; - - void getConstraintViolation(const ConstraintParams* cParams, - BaseVector *v, - const DataVecCoord &x1, const DataVecCoord &x2, - const DataVecDeriv &v1, const DataVecDeriv &v2) override; - - void getVelocityViolation(BaseVector *v, - const DataVecCoord &x1, const DataVecCoord &x2, - const DataVecDeriv &v1, const DataVecDeriv &v2); - - void getConstraintResolution(const ConstraintParams* cParams, - std::vector& resTab, - unsigned int& offset) override; - - void handleEvent(sofa::core::objectmodel::Event *event) override; - - void draw(const core::visual::VisualParams* vparams) override; - - void clear(int reserve = 0) ; - - virtual void addContact(Deriv norm, Coord P, Coord Q, Real contactDistance, - int m1, int m2, Coord Pfree, Coord Qfree, - long id=0, PersistentID localid=0); - - void addContact(Deriv norm, Coord P, Coord Q, Real contactDistance, - int m1, int m2, long id=0, PersistentID localid=0) ; - - void addContact(Deriv norm, Real contactDistance, int m1, int m2, - long id=0, PersistentID localid=0) ; - - /// Method to remove a contact using point @param indices and id of buffer: @sa m1 (resp. @sa 2m) if @param objectId is equal to 0 (resp. to 1) - void removeContact(int objectId, SubsetIndices indices); - - virtual type::vector getBilateralInteractionIdentifiers() {return {};} - - virtual type::vector getPairInteractionIdentifiers() override final - { - type::vector ids = getBilateralInteractionIdentifiers(); - ids.push_back("Bilateral"); - return ids; - } - -private: - void unspecializedInit() ; - - /// Method to get the index position of a @param point Id inside @sa m1 or @sa m2) depending of the value passed in @param cIndices. Return InvalidID if not found. - Index indexOfElemConstraint(const SubsetIndices& cIndices, Index Id); -}; - - -#if !defined(SOFA_COMPONENT_CONSTRAINTSET_BILATERALINTERACTIONCONSTRAINT_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API BilateralInteractionConstraint< Vec3Types >; -extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API BilateralInteractionConstraint< Rigid3Types >; -#endif - -} // namespace sofa::component::constraint::lagrangian::model +using BilateralInteractionConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "BilateralInteractionConstraint has been renamed to BilateralLagrangianConstraint") = BilateralLagrangianConstraint; +} diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralInteractionConstraint.inl b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralInteractionConstraint.inl index 0aeec985ed2..35da6a06b6d 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralInteractionConstraint.inl +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralInteractionConstraint.inl @@ -20,414 +20,7 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include // for std::min +#include -namespace sofa::component::constraint::lagrangian::model -{ - -using sofa::core::objectmodel::KeypressedEvent ; -using sofa::core::objectmodel::Event ; -using sofa::helper::WriteAccessor ; -using sofa::type::Vec; - -template -BilateralInteractionConstraint::BilateralInteractionConstraint(MechanicalState* object1, MechanicalState* object2) - : Inherit(object1, object2) - , m1(initData(&m1, "first_point","index of the constraint on the first model")) - , m2(initData(&m2, "second_point","index of the constraint on the second model")) - , restVector(initData(&restVector, "rest_vector","Relative position to maintain between attached points (optional)")) - , d_numericalTolerance(initData(&d_numericalTolerance, 0.0001, "numericalTolerance", - "a real value specifying the tolerance during the constraint solving. (optional, default=0.0001)") ) - , d_activate( initData(&d_activate, true, "activate", "control constraint activation (true by default)")) - , keepOrientDiff(initData(&keepOrientDiff,false, "keepOrientationDifference", "keep the initial difference in orientation (only for rigids)")) - , l_topology1(initLink("topology1", "link to the first topology container")) - , l_topology2(initLink("topology2", "link to the second topology container")) -{ - this->f_listening.setValue(true); -} - -template -BilateralInteractionConstraint::BilateralInteractionConstraint(MechanicalState* object) - : BilateralInteractionConstraint(object, object) -{ -} - -template -BilateralInteractionConstraint::BilateralInteractionConstraint() - : BilateralInteractionConstraint(nullptr, nullptr) -{ -} - -template -void BilateralInteractionConstraint::unspecializedInit() -{ - /// Do general check of validity for inputs - Inherit1::init(); - - /// Using assert means that the previous lines have check that there is two valid mechanical state. - assert(this->mstate1); - assert(this->mstate2); - - prevForces.clear(); -} - -template -void BilateralInteractionConstraint::init() -{ - unspecializedInit(); - - if (sofa::core::topology::BaseMeshTopology* _topology1 = l_topology1.get()) - { - m1.createTopologyHandler(_topology1); - m1.addTopologyEventCallBack(core::topology::TopologyChangeType::POINTSREMOVED, - [this](const core::topology::TopologyChange* change) - { - const auto* pointsRemoved = static_cast(change); - removeContact(0, pointsRemoved->getArray()); - }); - } - - if (sofa::core::topology::BaseMeshTopology* _topology2 = l_topology2.get()) - { - m2.createTopologyHandler(_topology2); - m2.addTopologyEventCallBack(core::topology::TopologyChangeType::POINTSREMOVED, - [this](const core::topology::TopologyChange* change) - { - const auto* pointsRemoved = static_cast(change); - removeContact(1, pointsRemoved->getArray()); - }); - } -} - -template -void BilateralInteractionConstraint::reinit() -{ - prevForces.clear(); -} - - -template -void BilateralInteractionConstraint::buildConstraintMatrix(const ConstraintParams*, DataMatrixDeriv &c1_d, DataMatrixDeriv &c2_d, unsigned int &constraintId - , const DataVecCoord &/*x1*/, const DataVecCoord &/*x2*/) -{ - if (!d_activate.getValue()) - return; - - const unsigned minp = std::min(m1.getValue().size(), m2.getValue().size()); - if (minp == 0) - return; - - const SubsetIndices& m1Indices = m1.getValue(); - const SubsetIndices& m2Indices = m2.getValue(); - - MatrixDeriv &c1 = *c1_d.beginEdit(); - MatrixDeriv &c2 = *c2_d.beginEdit(); - - cid.resize(minp); - - for (unsigned pid=0; pid cx(1,0,0), cy(0,1,0), cz(0,0,1); - - cid[pid] = constraintId; - constraintId += 3; - - MatrixDerivRowIterator c1_it = c1.writeLine(cid[pid]); - c1_it.addCol(tm1, -cx); - - MatrixDerivRowIterator c2_it = c2.writeLine(cid[pid]); - c2_it.addCol(tm2, cx); - - c1_it = c1.writeLine(cid[pid] + 1); - c1_it.setCol(tm1, -cy); - - c2_it = c2.writeLine(cid[pid] + 1); - c2_it.setCol(tm2, cy); - - c1_it = c1.writeLine(cid[pid] + 2); - c1_it.setCol(tm1, -cz); - - c2_it = c2.writeLine(cid[pid] + 2); - c2_it.setCol(tm2, cz); - } - - c1_d.endEdit(); - c2_d.endEdit(); -} - - -template -void BilateralInteractionConstraint::getConstraintViolation(const ConstraintParams* cParams, - BaseVector *v, - const DataVecCoord &d_x1, const DataVecCoord &d_x2 - , const DataVecDeriv & d_v1, const DataVecDeriv & d_v2) -{ - if (!d_activate.getValue()) return; - - const SubsetIndices& m1Indices = m1.getValue(); - const SubsetIndices& m2Indices = m2.getValue(); - - unsigned minp = std::min(m1Indices.size(), m2Indices.size()); - - const VecDeriv& restVector = this->restVector.getValue(); - - if (cParams->constOrder() == sofa::core::ConstraintOrder::VEL) - { - getVelocityViolation(v, d_x1, d_x2, d_v1, d_v2); - return; - } - - const VecCoord &x1 = d_x1.getValue(); - const VecCoord &x2 = d_x2.getValue(); - - dfree.resize(minp); - - for (unsigned pid=0; pidset(cid[pid] , dfree[pid][0]); - v->set(cid[pid]+1, dfree[pid][1]); - v->set(cid[pid]+2, dfree[pid][2]); - } -} - - -template -void BilateralInteractionConstraint::getVelocityViolation(BaseVector *v, - const DataVecCoord &d_x1, - const DataVecCoord &d_x2, - const DataVecDeriv &d_v1, - const DataVecDeriv &d_v2) -{ - const SubsetIndices& m1Indices = m1.getValue(); - const SubsetIndices& m2Indices = m2.getValue(); - - SOFA_UNUSED(d_x1); - SOFA_UNUSED(d_x2); - - const VecCoord &v1 = d_v1.getValue(); - const VecCoord &v2 = d_v2.getValue(); - - const unsigned minp = std::min(m1Indices.size(), m2Indices.size()); - const VecDeriv& restVector = this->restVector.getValue(); - - auto pos1 = this->getMState1()->readPositions(); - auto pos2 = this->getMState2()->readPositions(); - - const SReal dt = this->getContext()->getDt(); - const SReal invDt = SReal(1.0) / dt; - - for (unsigned pid=0; pidset(cid[pid] , dVfree[0] + dPos[0] ); - v->set(cid[pid]+1, dVfree[1] + dPos[1] ); - v->set(cid[pid]+2, dVfree[2] + dPos[2] ); - } -} - - -template -void BilateralInteractionConstraint::getConstraintResolution(const ConstraintParams* cParams, - std::vector& resTab, - unsigned int& offset) -{ - SOFA_UNUSED(cParams); - const unsigned minp=std::min(m1.getValue().size(),m2.getValue().size()); - - prevForces.resize(minp); - for (unsigned pid=0; pid -void BilateralInteractionConstraint::addContact(Deriv /*norm*/, Coord P, Coord Q, - Real /*contactDistance*/, int m1, int m2, - Coord /*Pfree*/, Coord /*Qfree*/, - long /*id*/, PersistentID /*localid*/) -{ - WriteAccessor > wm1 = this->m1; - WriteAccessor > wm2 = this->m2; - WriteAccessor > wrest = this->restVector; - wm1.push_back(m1); - wm2.push_back(m2); - wrest.push_back(Q-P); -} - - -template -void BilateralInteractionConstraint::addContact(Deriv norm, Coord P, Coord Q, Real - contactDistance, int m1, int m2, - long id, PersistentID localid) -{ - addContact(norm, P, Q, contactDistance, m1, m2, - this->getMState2()->read(ConstVecCoordId::freePosition())->getValue()[m2], - this->getMState1()->read(ConstVecCoordId::freePosition())->getValue()[m1], - id, localid); -} - -template -void BilateralInteractionConstraint::addContact(Deriv norm, Real contactDistance, - int m1, int m2, long id, PersistentID localid) -{ - addContact(norm, - this->getMState2()->read(ConstVecCoordId::position())->getValue()[m2], - this->getMState1()->read(ConstVecCoordId::position())->getValue()[m1], - contactDistance, m1, m2, - this->getMState2()->read(ConstVecCoordId::freePosition())->getValue()[m2], - this->getMState1()->read(ConstVecCoordId::freePosition())->getValue()[m1], - id, localid); -} - - -template -void BilateralInteractionConstraint::removeContact(int objectId, SubsetIndices indices) -{ - WriteAccessor > m1Indices = this->m1; - WriteAccessor > m2Indices = this->m2; - WriteAccessor > wrest = this->restVector; - - const SubsetIndices& cIndices1 = m1.getValue(); - const SubsetIndices& cIndices2 = m2.getValue(); - - for (sofa::Size i = 0; i < indices.size(); ++i) - { - const Index elemId = indices[i]; - Index posId = sofa::InvalidID; - - if (objectId == 0) - posId = indexOfElemConstraint(cIndices1, elemId); - else if (objectId == 1) - posId = indexOfElemConstraint(cIndices2, elemId); - - if (posId != sofa::InvalidID) - { - if (wrest.size() == m1Indices.size()) - wrest.erase(wrest.begin() + posId); - - m1Indices.erase(m1Indices.begin() + posId); - m2Indices.erase(m2Indices.begin() + posId); - } - } - -} - - -template -void BilateralInteractionConstraint::clear(int reserve) -{ - WriteAccessor > wm1 = this->m1; - WriteAccessor > wm2 = this->m2; - WriteAccessor > wrest = this->restVector; - wm1.clear(); - wm2.clear(); - wrest.clear(); - if (reserve) - { - wm1.reserve(reserve); - wm2.reserve(reserve); - wrest.reserve(reserve); - } -} - - -template -Index BilateralInteractionConstraint::indexOfElemConstraint(const SubsetIndices& cIndices, Index Id) -{ - const auto it = std::find(cIndices.begin(), cIndices.end(), Id); - - if (it != cIndices.end()) - return Index(std::distance(cIndices.begin(), it)); - else - return sofa::InvalidID; -} - - -template -void BilateralInteractionConstraint::draw(const core::visual::VisualParams* vparams) -{ - if (!vparams->displayFlags().getShowInteractionForceFields()) return; - - const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); - vparams->drawTool()->disableLighting(); - - constexpr sofa::type::RGBAColor colorActive = sofa::type::RGBAColor::magenta(); - constexpr sofa::type::RGBAColor colorNotActive = sofa::type::RGBAColor::green(); - std::vector< sofa::type::Vec3 > vertices; - - const unsigned minp = std::min(m1.getValue().size(),m2.getValue().size()); - auto positionsM1 = sofa::helper::getReadAccessor(*this->mstate1->read(ConstVecCoordId::position())); - auto positionsM2 = sofa::helper::getReadAccessor(*this->mstate2->read(ConstVecCoordId::position())); - const auto indicesM1 = sofa::helper::getReadAccessor(m1); - const auto indicesM2 = sofa::helper::getReadAccessor(m2); - - for (unsigned i=0; idrawTool()->drawPoints(vertices, 10, (d_activate.getValue()) ? colorActive : colorNotActive); - - -} - -//TODO(dmarchal): implementing keyboard interaction behavior directly in a component is not a valid -//design for a component. Interaction should be defered to an independent Component implemented in the SofaInteraction -//a second possibility is to implement this behavir using script. -template -void BilateralInteractionConstraint::handleEvent(Event *event) -{ - if (KeypressedEvent::checkEventType(event)) - { - const KeypressedEvent *ev = static_cast(event); - switch(ev->getKey()) - { - - case 'A': - case 'a': - if (d_activate.getValue()) - { - msg_info() << "Unactivating constraint"; - d_activate.setValue(false); - } - else - { - msg_info() << "Activating constraint"; - d_activate.setValue(true); - } - - break; - } - } - -} - - -} //namespace sofa::component::constraint::lagrangian::model +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/lagrangian/model/BilateralLagrangianConstraint.inl") diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralInteractionConstraint.cpp b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralLagrangianConstraint.cpp similarity index 58% rename from Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralInteractionConstraint.cpp rename to Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralLagrangianConstraint.cpp index 64743d5addb..fe045eab820 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralInteractionConstraint.cpp +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralLagrangianConstraint.cpp @@ -19,9 +19,9 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_CONSTRAINTSET_BILATERALINTERACTIONCONSTRAINT_CPP +#define SOFA_COMPONENT_CONSTRAINTSET_BILATERALLAGRANGIANCONSTRAINT_CPP -#include +#include #include #include @@ -33,37 +33,37 @@ class RigidImpl {}; template<> -class BilateralInteractionConstraintSpecialization +class BilateralLagrangianConstraintSpecialization { public: template - static void bwdInit(BilateralInteractionConstraint& self) { + static void bwdInit(BilateralLagrangianConstraint& self) { if (!self.keepOrientDiff.getValue()) return; - helper::WriteAccessor::VecDeriv > > wrest = self.restVector; + helper::WriteAccessor::VecDeriv > > wrest = self.restVector; if (wrest.size() > 0) { - msg_warning("BilateralInteractionConstraintSpecialization") << "keepOrientationDifference is activated, rest_vector will be ignored! " ; + msg_warning("BilateralLagrangianConstraintSpecialization") << "keepOrientationDifference is activated, rest_vector will be ignored! " ; wrest.resize(0); } - const typename BilateralInteractionConstraint::SubsetIndices& m1Indices = self.m1.getValue(); - const typename BilateralInteractionConstraint::SubsetIndices& m2Indices = self.m2.getValue(); + const typename BilateralLagrangianConstraint::SubsetIndices& m1Indices = self.m1.getValue(); + const typename BilateralLagrangianConstraint::SubsetIndices& m2Indices = self.m2.getValue(); const unsigned minp = std::min(m1Indices.size(),m2Indices.size()); - const typename BilateralInteractionConstraint::DataVecCoord &d_x1 = *self.mstate1->read(core::ConstVecCoordId::position()); - const typename BilateralInteractionConstraint::DataVecCoord &d_x2 = *self.mstate2->read(core::ConstVecCoordId::position()); + const typename BilateralLagrangianConstraint::DataVecCoord &d_x1 = *self.mstate1->read(core::ConstVecCoordId::position()); + const typename BilateralLagrangianConstraint::DataVecCoord &d_x2 = *self.mstate2->read(core::ConstVecCoordId::position()); - const typename BilateralInteractionConstraint::VecCoord &x1 = d_x1.getValue(); - const typename BilateralInteractionConstraint::VecCoord &x2 = d_x2.getValue(); + const typename BilateralLagrangianConstraint::VecCoord &x1 = d_x1.getValue(); + const typename BilateralLagrangianConstraint::VecCoord &x2 = d_x2.getValue(); for (unsigned pid=0; pid::Coord P = x1[m1Indices[pid]]; - const typename BilateralInteractionConstraint::Coord Q = x2[m2Indices[pid]]; + const typename BilateralLagrangianConstraint::Coord P = x1[m1Indices[pid]]; + const typename BilateralLagrangianConstraint::Coord Q = x2[m2Indices[pid]]; type::Quat qP, qQ, dQP; qP = P.getOrientation(); @@ -73,7 +73,7 @@ class BilateralInteractionConstraintSpecialization dQP = qP.quatDiff(qQ, qP); dQP.normalize(); - typename BilateralInteractionConstraint::Coord df; + typename BilateralLagrangianConstraint::Coord df; df.getCenter() = Q.getCenter() - P.getCenter(); df.getOrientation() = dQP; self.initialDifference.push_back(df); @@ -83,7 +83,7 @@ class BilateralInteractionConstraintSpecialization template - static void getConstraintResolution(BilateralInteractionConstraint& self, + static void getConstraintResolution(BilateralLagrangianConstraint& self, const ConstraintParams* cParams, std::vector& resTab, unsigned int& offset, double tolerance) @@ -104,26 +104,26 @@ class BilateralInteractionConstraintSpecialization template - static void buildConstraintMatrix(BilateralInteractionConstraint& self, + static void buildConstraintMatrix(BilateralLagrangianConstraint& self, const ConstraintParams* cParams, - typename BilateralInteractionConstraint::DataMatrixDeriv &c1_d, - typename BilateralInteractionConstraint::DataMatrixDeriv &c2_d, + typename BilateralLagrangianConstraint::DataMatrixDeriv &c1_d, + typename BilateralLagrangianConstraint::DataMatrixDeriv &c2_d, unsigned int &constraintId, - const typename BilateralInteractionConstraint::DataVecCoord &/*x1*/, - const typename BilateralInteractionConstraint::DataVecCoord &/*x2*/) + const typename BilateralLagrangianConstraint::DataVecCoord &/*x1*/, + const typename BilateralLagrangianConstraint::DataVecCoord &/*x2*/) { SOFA_UNUSED(cParams) ; - const typename BilateralInteractionConstraint::SubsetIndices& m1Indices = self.m1.getValue(); - const typename BilateralInteractionConstraint::SubsetIndices& m2Indices = self.m2.getValue(); + const typename BilateralLagrangianConstraint::SubsetIndices& m1Indices = self.m1.getValue(); + const typename BilateralLagrangianConstraint::SubsetIndices& m2Indices = self.m2.getValue(); unsigned minp = std::min(m1Indices.size(),m2Indices.size()); self.cid.resize(minp); - typename BilateralInteractionConstraint::MatrixDeriv &c1 = *c1_d.beginEdit(); - typename BilateralInteractionConstraint::MatrixDeriv &c2 = *c2_d.beginEdit(); + typename BilateralLagrangianConstraint::MatrixDeriv &c1 = *c1_d.beginEdit(); + typename BilateralLagrangianConstraint::MatrixDeriv &c2 = *c2_d.beginEdit(); - const Vec<3, typename BilateralInteractionConstraint::Real> cx(1,0,0), cy(0,1,0), cz(0,0,1); - const Vec<3, typename BilateralInteractionConstraint::Real> vZero(0,0,0); + const Vec<3, typename BilateralLagrangianConstraint::Real> cx(1,0,0), cy(0,1,0), cz(0,0,1); + const Vec<3, typename BilateralLagrangianConstraint::Real> vZero(0,0,0); for (unsigned pid=0; pid constraintId += 6; //Apply constraint for position - typename BilateralInteractionConstraint::MatrixDerivRowIterator c1_it = c1.writeLine(self.cid[pid]); - c1_it.addCol(tm1, typename BilateralInteractionConstraint::Deriv(-cx, vZero)); + typename BilateralLagrangianConstraint::MatrixDerivRowIterator c1_it = c1.writeLine(self.cid[pid]); + c1_it.addCol(tm1, typename BilateralLagrangianConstraint::Deriv(-cx, vZero)); - typename BilateralInteractionConstraint::MatrixDerivRowIterator c2_it = c2.writeLine(self.cid[pid]); - c2_it.addCol(tm2, typename BilateralInteractionConstraint::Deriv(cx, vZero)); + typename BilateralLagrangianConstraint::MatrixDerivRowIterator c2_it = c2.writeLine(self.cid[pid]); + c2_it.addCol(tm2, typename BilateralLagrangianConstraint::Deriv(cx, vZero)); c1_it = c1.writeLine(self.cid[pid] + 1); - c1_it.setCol(tm1, typename BilateralInteractionConstraint::Deriv(-cy, vZero)); + c1_it.setCol(tm1, typename BilateralLagrangianConstraint::Deriv(-cy, vZero)); c2_it = c2.writeLine(self.cid[pid] + 1); - c2_it.setCol(tm2, typename BilateralInteractionConstraint::Deriv(cy, vZero)); + c2_it.setCol(tm2, typename BilateralLagrangianConstraint::Deriv(cy, vZero)); c1_it = c1.writeLine(self.cid[pid] + 2); - c1_it.setCol(tm1, typename BilateralInteractionConstraint::Deriv(-cz, vZero)); + c1_it.setCol(tm1, typename BilateralLagrangianConstraint::Deriv(-cz, vZero)); c2_it = c2.writeLine(self.cid[pid] + 2); - c2_it.setCol(tm2, typename BilateralInteractionConstraint::Deriv(cz, vZero)); + c2_it.setCol(tm2, typename BilateralLagrangianConstraint::Deriv(cz, vZero)); //Apply constraint for orientation c1_it = c1.writeLine(self.cid[pid] + 3); - c1_it.setCol(tm1, typename BilateralInteractionConstraint::Deriv(vZero, -cx)); + c1_it.setCol(tm1, typename BilateralLagrangianConstraint::Deriv(vZero, -cx)); c2_it = c2.writeLine(self.cid[pid] + 3); - c2_it.setCol(tm2, typename BilateralInteractionConstraint::Deriv(vZero, cx)); + c2_it.setCol(tm2, typename BilateralLagrangianConstraint::Deriv(vZero, cx)); c1_it = c1.writeLine(self.cid[pid] + 4); - c1_it.setCol(tm1, typename BilateralInteractionConstraint::Deriv(vZero, -cy)); + c1_it.setCol(tm1, typename BilateralLagrangianConstraint::Deriv(vZero, -cy)); c2_it = c2.writeLine(self.cid[pid] + 4); - c2_it.setCol(tm2, typename BilateralInteractionConstraint::Deriv(vZero, cy)); + c2_it.setCol(tm2, typename BilateralLagrangianConstraint::Deriv(vZero, cy)); c1_it = c1.writeLine(self.cid[pid] + 5); - c1_it.setCol(tm1, typename BilateralInteractionConstraint::Deriv(vZero, -cz)); + c1_it.setCol(tm1, typename BilateralLagrangianConstraint::Deriv(vZero, -cz)); c2_it = c2.writeLine(self.cid[pid] + 5); - c2_it.setCol(tm2, typename BilateralInteractionConstraint::Deriv(vZero, cz)); + c2_it.setCol(tm2, typename BilateralLagrangianConstraint::Deriv(vZero, cz)); } c1_d.endEdit(); @@ -178,34 +178,34 @@ class BilateralInteractionConstraintSpecialization template - static void getConstraintViolation(BilateralInteractionConstraint& self, + static void getConstraintViolation(BilateralLagrangianConstraint& self, const ConstraintParams* /*cParams*/, BaseVector *v, - const typename BilateralInteractionConstraint::DataVecCoord &d_x1, - const typename BilateralInteractionConstraint::DataVecCoord &d_x2, - const typename BilateralInteractionConstraint::DataVecDeriv &/*v1*/, - const typename BilateralInteractionConstraint::DataVecDeriv &/*v2*/) + const typename BilateralLagrangianConstraint::DataVecCoord &d_x1, + const typename BilateralLagrangianConstraint::DataVecCoord &d_x2, + const typename BilateralLagrangianConstraint::DataVecDeriv &/*v1*/, + const typename BilateralLagrangianConstraint::DataVecDeriv &/*v2*/) { - const typename BilateralInteractionConstraint::SubsetIndices& m1Indices = self.m1.getValue(); - const typename BilateralInteractionConstraint::SubsetIndices& m2Indices = self.m2.getValue(); + const typename BilateralLagrangianConstraint::SubsetIndices& m1Indices = self.m1.getValue(); + const typename BilateralLagrangianConstraint::SubsetIndices& m2Indices = self.m2.getValue(); unsigned min = std::min(m1Indices.size(), m2Indices.size()); - const typename BilateralInteractionConstraint::VecDeriv& restVector = self.restVector.getValue(); + const typename BilateralLagrangianConstraint::VecDeriv& restVector = self.restVector.getValue(); self.dfree.resize(min); - const typename BilateralInteractionConstraint::VecCoord &x1 = d_x1.getValue(); - const typename BilateralInteractionConstraint::VecCoord &x2 = d_x2.getValue(); + const typename BilateralLagrangianConstraint::VecCoord &x1 = d_x1.getValue(); + const typename BilateralLagrangianConstraint::VecCoord &x2 = d_x2.getValue(); for (unsigned pid=0; pid::Coord dof1 = x1[m1Indices[pid]]; - //typename BilateralInteractionConstraint::Coord dof2 = x2[m2Indices[pid]]; - typename BilateralInteractionConstraint::Coord dof1; + //typename BilateralLagrangianConstraint::Coord dof1 = x1[m1Indices[pid]]; + //typename BilateralLagrangianConstraint::Coord dof2 = x2[m2Indices[pid]]; + typename BilateralLagrangianConstraint::Coord dof1; if (self.keepOrientDiff.getValue()) { - const typename BilateralInteractionConstraint::Coord dof1c = x1[m1Indices[pid]]; + const typename BilateralLagrangianConstraint::Coord dof1c = x1[m1Indices[pid]]; - typename BilateralInteractionConstraint::Coord corr=self.initialDifference[pid]; + typename BilateralLagrangianConstraint::Coord corr=self.initialDifference[pid]; type::Quat df = corr.getOrientation(); type::Quat o1 = dof1c.getOrientation(); type::Quat ro1 = o1 * df; @@ -215,7 +215,7 @@ class BilateralInteractionConstraintSpecialization } else dof1 = x1[m1Indices[pid]]; - const typename BilateralInteractionConstraint::Coord dof2 = x2[m2Indices[pid]]; + const typename BilateralLagrangianConstraint::Coord dof2 = x2[m2Indices[pid]]; getVCenter(self.dfree[pid]) = dof2.getCenter() - dof1.getCenter(); getVOrientation(self.dfree[pid]) = dof1.rotate(self.q.angularDisplacement(dof2.getOrientation() , @@ -229,14 +229,14 @@ class BilateralInteractionConstraintSpecialization } - template > - static void addContact(BilateralInteractionConstraint& self, typename MyClass::Deriv /*norm*/, + template > + static void addContact(BilateralLagrangianConstraint& self, typename MyClass::Deriv /*norm*/, typename MyClass::Coord P, typename MyClass::Coord Q, typename MyClass::Real /*contactDistance*/, int m1, int m2, typename MyClass::Coord /*Pfree*/, typename MyClass::Coord /*Qfree*/, long /*id*/, typename MyClass::PersistentID /*localid*/) { - helper::WriteAccessor::SubsetIndices > > wm1 = self.m1; - helper::WriteAccessor::SubsetIndices > > wm2 = self.m2; + helper::WriteAccessor::SubsetIndices > > wm1 = self.m1; + helper::WriteAccessor::SubsetIndices > > wm2 = self.m2; helper::WriteAccessor > wrest = self.restVector; wm1.push_back(m1); wm2.push_back(m2); @@ -251,52 +251,52 @@ class BilateralInteractionConstraintSpecialization template<> SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API -void BilateralInteractionConstraint::init(){ +void BilateralLagrangianConstraint::init(){ unspecializedInit() ; } template<> SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API -void BilateralInteractionConstraint::bwdInit() { - BilateralInteractionConstraintSpecialization::bwdInit(*this); +void BilateralLagrangianConstraint::bwdInit() { + BilateralLagrangianConstraintSpecialization::bwdInit(*this); } template<> SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API -void BilateralInteractionConstraint::getConstraintResolution(const ConstraintParams* cParams, +void BilateralLagrangianConstraint::getConstraintResolution(const ConstraintParams* cParams, std::vector& resTab, unsigned int& offset) { - BilateralInteractionConstraintSpecialization::getConstraintResolution(*this, + BilateralLagrangianConstraintSpecialization::getConstraintResolution(*this, cParams, resTab, offset, d_numericalTolerance.getValue()) ; } template <> SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API -void BilateralInteractionConstraint::buildConstraintMatrix(const ConstraintParams* cParams, +void BilateralLagrangianConstraint::buildConstraintMatrix(const ConstraintParams* cParams, DataMatrixDeriv &c1_d, DataMatrixDeriv &c2_d, unsigned int &constraintId, const DataVecCoord &x1, const DataVecCoord &x2) { - BilateralInteractionConstraintSpecialization::buildConstraintMatrix(*this, + BilateralLagrangianConstraintSpecialization::buildConstraintMatrix(*this, cParams, c1_d, c2_d, constraintId, x1, x2) ; } template <> SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API -void BilateralInteractionConstraint::getConstraintViolation(const ConstraintParams* cParams, +void BilateralLagrangianConstraint::getConstraintViolation(const ConstraintParams* cParams, BaseVector *v, const DataVecCoord &d_x1, const DataVecCoord &d_x2, const DataVecDeriv &v1, const DataVecDeriv &v2) { - BilateralInteractionConstraintSpecialization::getConstraintViolation(*this, + BilateralLagrangianConstraintSpecialization::getConstraintViolation(*this, cParams, v, d_x1, d_x2, v1, v2) ; } template <> SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API -void BilateralInteractionConstraint::getVelocityViolation(BaseVector * /*v*/, +void BilateralLagrangianConstraint::getVelocityViolation(BaseVector * /*v*/, const DataVecCoord &/*x1*/, const DataVecCoord &/*x2*/, const DataVecDeriv &/*v1*/, @@ -306,25 +306,25 @@ void BilateralInteractionConstraint::getVelocityViolation(BaseVecto } template<> SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API -void BilateralInteractionConstraint::addContact(Deriv norm, +void BilateralLagrangianConstraint::addContact(Deriv norm, Coord P, Coord Q, Real contactDistance, int m1, int m2, Coord Pfree, Coord Qfree, long id, PersistentID localid) { - BilateralInteractionConstraintSpecialization::addContact(*this, + BilateralLagrangianConstraintSpecialization::addContact(*this, norm, P, Q, contactDistance, m1, m2, Pfree, Qfree, id, localid) ; } -int BilateralInteractionConstraintClass = core::RegisterObject("BilateralInteractionConstraint defining an holonomic equality constraint (attachment)") - .add< BilateralInteractionConstraint >() - .add< BilateralInteractionConstraint >() +int BilateralLagrangianConstraintClass = core::RegisterObject("BilateralLagrangianConstraint defining an holonomic equality constraint (attachment)") + .add< BilateralLagrangianConstraint >() + .add< BilateralLagrangianConstraint >() ; -template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API BilateralInteractionConstraint; -template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API BilateralInteractionConstraint; +template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API BilateralLagrangianConstraint; +template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API BilateralLagrangianConstraint; } //namespace sofa::component::constraint::lagrangian::model diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralLagrangianConstraint.h b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralLagrangianConstraint.h new file mode 100644 index 00000000000..0b23e4521a1 --- /dev/null +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralLagrangianConstraint.h @@ -0,0 +1,195 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +namespace sofa::component::constraint::lagrangian::model +{ + +/// These 'using' are in a per-file namespace so they will not leak +/// and polluate the standard namespace. +using sofa::core::behavior::BaseConstraint ; +using sofa::core::behavior::ConstraintResolution ; +using sofa::core::behavior::PairInteractionConstraint ; +using sofa::core::objectmodel::Data ; +using sofa::core::ConstraintParams ; +using sofa::core::ConstVecCoordId; + +using sofa::linearalgebra::BaseVector ; +using sofa::type::Vec3d; +using sofa::type::Quat ; + +using sofa::defaulttype::Rigid3Types ; +using sofa::defaulttype::Vec3Types ; + + +template +class BilateralLagrangianConstraintSpecialization {}; + + +template +class BilateralLagrangianConstraint : public PairInteractionConstraint +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(BilateralLagrangianConstraint,DataTypes), + SOFA_TEMPLATE(PairInteractionConstraint,DataTypes)); + + /// That any templates variation of BilateralLagrangianConstraintSpecialization are friend. + template + friend class BilateralLagrangianConstraintSpecialization ; + + typedef PairInteractionConstraint Inherit; + + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename Coord::value_type Real; + typedef typename DataTypes::MatrixDeriv::RowIterator MatrixDerivRowIterator; + + typedef core::behavior::MechanicalState MechanicalState; + typedef BaseConstraint::PersistentID PersistentID; + + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef Data DataMatrixDeriv; + + using SubsetIndices = type::vector; + using DataSubsetIndices = sofa::core::topology::TopologySubsetIndices; + +protected: + std::vector dfree; + Quat q; + + std::vector cid; + + DataSubsetIndices m1; ///< index of the constraint on the first model + DataSubsetIndices m2; ///< index of the constraint on the second model + Data restVector; ///< Relative position to maintain between attached points (optional) + VecCoord initialDifference; + + Data d_numericalTolerance; ///< a real value specifying the tolerance during the constraint solving. (default=0.0001 + Data d_activate; ///< bool to control constraint activation + Data keepOrientDiff; ///< keep the initial difference in orientation (only for rigids) + + + SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology1; ///< Link to be set to the first topology container in order to support topological changes + SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology2; ///< Link to be set to the second topology container in order to support topological changes + + std::vector prevForces; + + SOFA_ATTRIBUTE_DISABLED__BILATERALINTERACTIONCONSTRAINTDATA("Data 'activateAtIteration' has been removed, please use the Data d_activate instead and an engine or a script to change the behavior at the right step (see PR #3327).") + sofa::core::objectmodel::lifecycle::RemovedData activateAtIteration{this, "v22.12", "v23.06", "activateAtIteration", "use the boolean data 'activate' instead and an engine or a script to change the behavior at the right step (see PR #3327)."}; + + SOFA_ATTRIBUTE_DISABLED__BILATERALINTERACTIONCONSTRAINTDATA("Data 'merge' has been removed. Its behavior was unused, undocumented, untested, and unclear (see PR #3328).") + sofa::core::objectmodel::lifecycle::RemovedData merge{this, "v22.12", "v23.06", "merge", "Its behavior was unused, undocumented, untested, and unclear (see PR #3328), please report to sofa-dev if you want the feature back."}; + + SOFA_ATTRIBUTE_DISABLED__BILATERALINTERACTIONCONSTRAINTDATA("Data 'derivative' has been removed. Its behavior was unused, undocumented, untested, and unclear (see PR #3328).") + sofa::core::objectmodel::lifecycle::RemovedData derivative{this, "v22.12", "v23.06", "derivative", "Its behavior was unused, undocumented, untested, and unclear (see PR #3328), please report to sofa-dev if you want the feature back."}; + + + BilateralLagrangianConstraint(MechanicalState* object1, MechanicalState* object2) ; + BilateralLagrangianConstraint(MechanicalState* object) ; + BilateralLagrangianConstraint(); + + virtual ~BilateralLagrangianConstraint(){} +public: + void init() override; + + void bwdInit() override {} + + void reinit() override; + + void buildConstraintMatrix(const ConstraintParams* cParams, + DataMatrixDeriv &c1, DataMatrixDeriv &c2, + unsigned int &cIndex, + const DataVecCoord &x1, const DataVecCoord &x2) override; + + void getConstraintViolation(const ConstraintParams* cParams, + BaseVector *v, + const DataVecCoord &x1, const DataVecCoord &x2, + const DataVecDeriv &v1, const DataVecDeriv &v2) override; + + void getVelocityViolation(BaseVector *v, + const DataVecCoord &x1, const DataVecCoord &x2, + const DataVecDeriv &v1, const DataVecDeriv &v2); + + void getConstraintResolution(const ConstraintParams* cParams, + std::vector& resTab, + unsigned int& offset) override; + + void handleEvent(sofa::core::objectmodel::Event *event) override; + + void draw(const core::visual::VisualParams* vparams) override; + + void clear(int reserve = 0) ; + + virtual void addContact(Deriv norm, Coord P, Coord Q, Real contactDistance, + int m1, int m2, Coord Pfree, Coord Qfree, + long id=0, PersistentID localid=0); + + void addContact(Deriv norm, Coord P, Coord Q, Real contactDistance, + int m1, int m2, long id=0, PersistentID localid=0) ; + + void addContact(Deriv norm, Real contactDistance, int m1, int m2, + long id=0, PersistentID localid=0) ; + + /// Method to remove a contact using point @param indices and id of buffer: @sa m1 (resp. @sa 2m) if @param objectId is equal to 0 (resp. to 1) + void removeContact(int objectId, SubsetIndices indices); + + virtual type::vector getBilateralInteractionIdentifiers() {return {};} + + virtual type::vector getPairInteractionIdentifiers() override final + { + type::vector ids = getBilateralInteractionIdentifiers(); + ids.push_back("Bilateral"); + return ids; + } + +private: + void unspecializedInit() ; + + /// Method to get the index position of a @param point Id inside @sa m1 or @sa m2) depending of the value passed in @param cIndices. Return InvalidID if not found. + Index indexOfElemConstraint(const SubsetIndices& cIndices, Index Id); +}; + + +#if !defined(SOFA_COMPONENT_CONSTRAINTSET_BILATERALLAGRANGIANCONSTRAINT_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API BilateralLagrangianConstraint< Vec3Types >; +extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API BilateralLagrangianConstraint< Rigid3Types >; +#endif + +} // namespace sofa::component::constraint::lagrangian::model diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralLagrangianConstraint.inl b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralLagrangianConstraint.inl new file mode 100644 index 00000000000..434272f872b --- /dev/null +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralLagrangianConstraint.inl @@ -0,0 +1,433 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include +#include +#include + +#include +#include +#include +#include +#include // for std::min + +namespace sofa::component::constraint::lagrangian::model +{ + +using sofa::core::objectmodel::KeypressedEvent ; +using sofa::core::objectmodel::Event ; +using sofa::helper::WriteAccessor ; +using sofa::type::Vec; + +template +BilateralLagrangianConstraint::BilateralLagrangianConstraint(MechanicalState* object1, MechanicalState* object2) + : Inherit(object1, object2) + , m1(initData(&m1, "first_point","index of the constraint on the first model")) + , m2(initData(&m2, "second_point","index of the constraint on the second model")) + , restVector(initData(&restVector, "rest_vector","Relative position to maintain between attached points (optional)")) + , d_numericalTolerance(initData(&d_numericalTolerance, 0.0001, "numericalTolerance", + "a real value specifying the tolerance during the constraint solving. (optional, default=0.0001)") ) + , d_activate( initData(&d_activate, true, "activate", "control constraint activation (true by default)")) + , keepOrientDiff(initData(&keepOrientDiff,false, "keepOrientationDifference", "keep the initial difference in orientation (only for rigids)")) + , l_topology1(initLink("topology1", "link to the first topology container")) + , l_topology2(initLink("topology2", "link to the second topology container")) +{ + this->f_listening.setValue(true); +} + +template +BilateralLagrangianConstraint::BilateralLagrangianConstraint(MechanicalState* object) + : BilateralLagrangianConstraint(object, object) +{ +} + +template +BilateralLagrangianConstraint::BilateralLagrangianConstraint() + : BilateralLagrangianConstraint(nullptr, nullptr) +{ +} + +template +void BilateralLagrangianConstraint::unspecializedInit() +{ + /// Do general check of validity for inputs + Inherit1::init(); + + /// Using assert means that the previous lines have check that there is two valid mechanical state. + assert(this->mstate1); + assert(this->mstate2); + + prevForces.clear(); +} + +template +void BilateralLagrangianConstraint::init() +{ + unspecializedInit(); + + if (sofa::core::topology::BaseMeshTopology* _topology1 = l_topology1.get()) + { + m1.createTopologyHandler(_topology1); + m1.addTopologyEventCallBack(core::topology::TopologyChangeType::POINTSREMOVED, + [this](const core::topology::TopologyChange* change) + { + const auto* pointsRemoved = static_cast(change); + removeContact(0, pointsRemoved->getArray()); + }); + } + + if (sofa::core::topology::BaseMeshTopology* _topology2 = l_topology2.get()) + { + m2.createTopologyHandler(_topology2); + m2.addTopologyEventCallBack(core::topology::TopologyChangeType::POINTSREMOVED, + [this](const core::topology::TopologyChange* change) + { + const auto* pointsRemoved = static_cast(change); + removeContact(1, pointsRemoved->getArray()); + }); + } +} + +template +void BilateralLagrangianConstraint::reinit() +{ + prevForces.clear(); +} + + +template +void BilateralLagrangianConstraint::buildConstraintMatrix(const ConstraintParams*, DataMatrixDeriv &c1_d, DataMatrixDeriv &c2_d, unsigned int &constraintId + , const DataVecCoord &/*x1*/, const DataVecCoord &/*x2*/) +{ + if (!d_activate.getValue()) + return; + + const unsigned minp = std::min(m1.getValue().size(), m2.getValue().size()); + if (minp == 0) + return; + + const SubsetIndices& m1Indices = m1.getValue(); + const SubsetIndices& m2Indices = m2.getValue(); + + MatrixDeriv &c1 = *c1_d.beginEdit(); + MatrixDeriv &c2 = *c2_d.beginEdit(); + + cid.resize(minp); + + for (unsigned pid=0; pid cx(1,0,0), cy(0,1,0), cz(0,0,1); + + cid[pid] = constraintId; + constraintId += 3; + + MatrixDerivRowIterator c1_it = c1.writeLine(cid[pid]); + c1_it.addCol(tm1, -cx); + + MatrixDerivRowIterator c2_it = c2.writeLine(cid[pid]); + c2_it.addCol(tm2, cx); + + c1_it = c1.writeLine(cid[pid] + 1); + c1_it.setCol(tm1, -cy); + + c2_it = c2.writeLine(cid[pid] + 1); + c2_it.setCol(tm2, cy); + + c1_it = c1.writeLine(cid[pid] + 2); + c1_it.setCol(tm1, -cz); + + c2_it = c2.writeLine(cid[pid] + 2); + c2_it.setCol(tm2, cz); + } + + c1_d.endEdit(); + c2_d.endEdit(); +} + + +template +void BilateralLagrangianConstraint::getConstraintViolation(const ConstraintParams* cParams, + BaseVector *v, + const DataVecCoord &d_x1, const DataVecCoord &d_x2 + , const DataVecDeriv & d_v1, const DataVecDeriv & d_v2) +{ + if (!d_activate.getValue()) return; + + const SubsetIndices& m1Indices = m1.getValue(); + const SubsetIndices& m2Indices = m2.getValue(); + + unsigned minp = std::min(m1Indices.size(), m2Indices.size()); + + const VecDeriv& restVector = this->restVector.getValue(); + + if (cParams->constOrder() == sofa::core::ConstraintOrder::VEL) + { + getVelocityViolation(v, d_x1, d_x2, d_v1, d_v2); + return; + } + + const VecCoord &x1 = d_x1.getValue(); + const VecCoord &x2 = d_x2.getValue(); + + dfree.resize(minp); + + for (unsigned pid=0; pidset(cid[pid] , dfree[pid][0]); + v->set(cid[pid]+1, dfree[pid][1]); + v->set(cid[pid]+2, dfree[pid][2]); + } +} + + +template +void BilateralLagrangianConstraint::getVelocityViolation(BaseVector *v, + const DataVecCoord &d_x1, + const DataVecCoord &d_x2, + const DataVecDeriv &d_v1, + const DataVecDeriv &d_v2) +{ + const SubsetIndices& m1Indices = m1.getValue(); + const SubsetIndices& m2Indices = m2.getValue(); + + SOFA_UNUSED(d_x1); + SOFA_UNUSED(d_x2); + + const VecCoord &v1 = d_v1.getValue(); + const VecCoord &v2 = d_v2.getValue(); + + const unsigned minp = std::min(m1Indices.size(), m2Indices.size()); + const VecDeriv& restVector = this->restVector.getValue(); + + auto pos1 = this->getMState1()->readPositions(); + auto pos2 = this->getMState2()->readPositions(); + + const SReal dt = this->getContext()->getDt(); + const SReal invDt = SReal(1.0) / dt; + + for (unsigned pid=0; pidset(cid[pid] , dVfree[0] + dPos[0] ); + v->set(cid[pid]+1, dVfree[1] + dPos[1] ); + v->set(cid[pid]+2, dVfree[2] + dPos[2] ); + } +} + + +template +void BilateralLagrangianConstraint::getConstraintResolution(const ConstraintParams* cParams, + std::vector& resTab, + unsigned int& offset) +{ + SOFA_UNUSED(cParams); + const unsigned minp=std::min(m1.getValue().size(),m2.getValue().size()); + + prevForces.resize(minp); + for (unsigned pid=0; pid +void BilateralLagrangianConstraint::addContact(Deriv /*norm*/, Coord P, Coord Q, + Real /*contactDistance*/, int m1, int m2, + Coord /*Pfree*/, Coord /*Qfree*/, + long /*id*/, PersistentID /*localid*/) +{ + WriteAccessor > wm1 = this->m1; + WriteAccessor > wm2 = this->m2; + WriteAccessor > wrest = this->restVector; + wm1.push_back(m1); + wm2.push_back(m2); + wrest.push_back(Q-P); +} + + +template +void BilateralLagrangianConstraint::addContact(Deriv norm, Coord P, Coord Q, Real + contactDistance, int m1, int m2, + long id, PersistentID localid) +{ + addContact(norm, P, Q, contactDistance, m1, m2, + this->getMState2()->read(ConstVecCoordId::freePosition())->getValue()[m2], + this->getMState1()->read(ConstVecCoordId::freePosition())->getValue()[m1], + id, localid); +} + +template +void BilateralLagrangianConstraint::addContact(Deriv norm, Real contactDistance, + int m1, int m2, long id, PersistentID localid) +{ + addContact(norm, + this->getMState2()->read(ConstVecCoordId::position())->getValue()[m2], + this->getMState1()->read(ConstVecCoordId::position())->getValue()[m1], + contactDistance, m1, m2, + this->getMState2()->read(ConstVecCoordId::freePosition())->getValue()[m2], + this->getMState1()->read(ConstVecCoordId::freePosition())->getValue()[m1], + id, localid); +} + + +template +void BilateralLagrangianConstraint::removeContact(int objectId, SubsetIndices indices) +{ + WriteAccessor > m1Indices = this->m1; + WriteAccessor > m2Indices = this->m2; + WriteAccessor > wrest = this->restVector; + + const SubsetIndices& cIndices1 = m1.getValue(); + const SubsetIndices& cIndices2 = m2.getValue(); + + for (sofa::Size i = 0; i < indices.size(); ++i) + { + const Index elemId = indices[i]; + Index posId = sofa::InvalidID; + + if (objectId == 0) + posId = indexOfElemConstraint(cIndices1, elemId); + else if (objectId == 1) + posId = indexOfElemConstraint(cIndices2, elemId); + + if (posId != sofa::InvalidID) + { + if (wrest.size() == m1Indices.size()) + wrest.erase(wrest.begin() + posId); + + m1Indices.erase(m1Indices.begin() + posId); + m2Indices.erase(m2Indices.begin() + posId); + } + } + +} + + +template +void BilateralLagrangianConstraint::clear(int reserve) +{ + WriteAccessor > wm1 = this->m1; + WriteAccessor > wm2 = this->m2; + WriteAccessor > wrest = this->restVector; + wm1.clear(); + wm2.clear(); + wrest.clear(); + if (reserve) + { + wm1.reserve(reserve); + wm2.reserve(reserve); + wrest.reserve(reserve); + } +} + + +template +Index BilateralLagrangianConstraint::indexOfElemConstraint(const SubsetIndices& cIndices, Index Id) +{ + const auto it = std::find(cIndices.begin(), cIndices.end(), Id); + + if (it != cIndices.end()) + return Index(std::distance(cIndices.begin(), it)); + else + return sofa::InvalidID; +} + + +template +void BilateralLagrangianConstraint::draw(const core::visual::VisualParams* vparams) +{ + if (!vparams->displayFlags().getShowInteractionForceFields()) return; + + const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); + vparams->drawTool()->disableLighting(); + + constexpr sofa::type::RGBAColor colorActive = sofa::type::RGBAColor::magenta(); + constexpr sofa::type::RGBAColor colorNotActive = sofa::type::RGBAColor::green(); + std::vector< sofa::type::Vec3 > vertices; + + const unsigned minp = std::min(m1.getValue().size(),m2.getValue().size()); + auto positionsM1 = sofa::helper::getReadAccessor(*this->mstate1->read(ConstVecCoordId::position())); + auto positionsM2 = sofa::helper::getReadAccessor(*this->mstate2->read(ConstVecCoordId::position())); + const auto indicesM1 = sofa::helper::getReadAccessor(m1); + const auto indicesM2 = sofa::helper::getReadAccessor(m2); + + for (unsigned i=0; idrawTool()->drawPoints(vertices, 10, (d_activate.getValue()) ? colorActive : colorNotActive); + + +} + +//TODO(dmarchal): implementing keyboard interaction behavior directly in a component is not a valid +//design for a component. Interaction should be defered to an independent Component implemented in the SofaInteraction +//a second possibility is to implement this behavir using script. +template +void BilateralLagrangianConstraint::handleEvent(Event *event) +{ + if (KeypressedEvent::checkEventType(event)) + { + const KeypressedEvent *ev = static_cast(event); + switch(ev->getKey()) + { + + case 'A': + case 'a': + if (d_activate.getValue()) + { + msg_info() << "Unactivating constraint"; + d_activate.setValue(false); + } + else + { + msg_info() << "Activating constraint"; + d_activate.setValue(true); + } + + break; + } + } + +} + + +} //namespace sofa::component::constraint::lagrangian::model diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingConstraint.h b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingConstraint.h index 19e2a124a90..b78a9991843 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingConstraint.h +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingConstraint.h @@ -20,94 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include +#include -namespace sofa::component::constraint::lagrangian::model -{ +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/lagrangian/model/SlidingLagrangianConstraint.h") -using sofa::core::ConstraintParams; - -template -class SlidingConstraint : public core::behavior::PairInteractionConstraint +namespace sofa::component::constraint::lagrangian::model { -public: - SOFA_CLASS(SOFA_TEMPLATE(SlidingConstraint,DataTypes), SOFA_TEMPLATE(core::behavior::PairInteractionConstraint,DataTypes)); - - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::MatrixDeriv::RowIterator MatrixDerivRowIterator; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename Coord::value_type Real; - typedef typename core::behavior::MechanicalState MechanicalState; - typedef typename core::behavior::PairInteractionConstraint Inherit; - - typedef core::objectmodel::Data DataVecCoord; - typedef core::objectmodel::Data DataVecDeriv; - typedef core::objectmodel::Data DataMatrixDeriv; - -protected: - - Data d_m1; ///< index of the spliding point on the first model - Data d_m2a; ///< index of one end of the sliding axis - Data d_m2b; ///< index of the other end of the sliding axis - Data d_force; ///< interaction force - - Real m_dist; // constraint violation - Real m_thirdConstraint; // 0 if A getSlidingIdentifiers() { return {}; } - - virtual type::vector getPairInteractionIdentifiers() override final - { - type::vector ids = getSlidingIdentifiers(); - ids.push_back("Sliding"); - return ids; - } - - -public: - void init() override; - - void buildConstraintMatrix(const core::ConstraintParams* cParams, DataMatrixDeriv &c1, DataMatrixDeriv &c2, unsigned int &cIndex - , const DataVecCoord &x1, const DataVecCoord &x2) override; - - void getConstraintViolation(const core::ConstraintParams* cParams, linearalgebra::BaseVector *v, const DataVecCoord &x1, const DataVecCoord &x2 - , const DataVecDeriv &v1, const DataVecDeriv &v2) override; - - void getConstraintResolution(const core::ConstraintParams*, - std::vector& resTab, - unsigned int& offset) override; - void storeLambda(const ConstraintParams* cParams, sofa::core::MultiVecDerivId res, const sofa::linearalgebra::BaseVector* lambda) override; - - void draw(const core::visual::VisualParams* vparams) override; - -private: - // storage of force - Deriv m_dirAxe, m_dirProj, m_dirOrtho; - - - -}; - -#if !defined(SOFA_COMPONENT_CONSTRAINTSET_SLIDINGCONSTRAINT_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API SlidingConstraint< defaulttype::Vec3Types >; - -#endif - -} //namespace sofa::component::constraint::lagrangian::model +template +using SlidingConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "SlidingConstraint has been renamed to SlidingLagrangianConstraint") = SlidingLagrangianConstraint; +} diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingConstraint.inl b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingConstraint.inl index e656c12cc7c..777bbaf511e 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingConstraint.inl +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingConstraint.inl @@ -20,207 +20,7 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -namespace sofa::component::constraint::lagrangian::model -{ -template -SlidingConstraint::SlidingConstraint() - : SlidingConstraint(nullptr, nullptr) -{ -} +#include -template -SlidingConstraint::SlidingConstraint(MechanicalState* object) - : SlidingConstraint(object, object) -{ -} - -template -SlidingConstraint::SlidingConstraint(MechanicalState* object1, MechanicalState* object2) - : Inherit(object1, object2) - , d_m1(initData(&d_m1, 0, "sliding_point","index of the spliding point on the first model")) - , d_m2a(initData(&d_m2a, 0, "axis_1","index of one end of the sliding axis")) - , d_m2b(initData(&d_m2b, 0, "axis_2","index of the other end of the sliding axis")) - , d_force(initData(&d_force,"force","force (impulse) used to solve the constraint")) -{ -} - -template -void SlidingConstraint::init() -{ - assert(this->mstate1); - assert(this->mstate2); - - m_thirdConstraint = 0; -} - - -template -void SlidingConstraint::buildConstraintMatrix(const core::ConstraintParams*, DataMatrixDeriv &c1_d, DataMatrixDeriv &c2_d, unsigned int &cIndex - , const DataVecCoord &x1, const DataVecCoord &x2) -{ - int tm1 = d_m1.getValue(); - int tm2a = d_m2a.getValue(); - int tm2b = d_m2b.getValue(); - - MatrixDeriv &c1 = *c1_d.beginEdit(); - MatrixDeriv &c2 = *c2_d.beginEdit(); - - const Coord P = x1.getValue()[tm1]; - const Coord A = x2.getValue()[tm2a]; - const Coord B = x2.getValue()[tm2b]; - - // the axis - m_dirAxe = B - A; - const Real ab = m_dirAxe.norm(); - m_dirAxe.normalize(); - - // projection of the point on the axis - Real r = (P-A) * m_dirAxe; - Real r2 = r / ab; - const Deriv proj = A + m_dirAxe * r; - - // We move the constraint point onto the projection - m_dirProj = P - proj; - m_dist = m_dirProj.norm(); // constraint violation - m_dirProj.normalize(); // direction of the constraint - - m_dirOrtho = cross(m_dirProj, m_dirAxe); - m_dirOrtho.normalize(); - - m_cid = cIndex; - cIndex += 2; - - MatrixDerivRowIterator c1_it = c1.writeLine(m_cid); - c1_it.addCol(tm1, m_dirProj); - - MatrixDerivRowIterator c2_it = c2.writeLine(m_cid); - c2_it.addCol(tm2a, -m_dirProj * (1-r2)); - c2_it.addCol(tm2b, -m_dirProj * r2); - - c1_it = c1.writeLine(m_cid + 1); - c1_it.setCol(tm1, m_dirOrtho); - - c2_it = c2.writeLine(m_cid + 1); - c2_it.addCol(tm2a, -m_dirOrtho * (1-r2)); - c2_it.addCol(tm2b, -m_dirOrtho * r2); - - m_thirdConstraint = 0; - - if (r < 0) - { - m_thirdConstraint = r; - cIndex++; - - c1_it = c1.writeLine(m_cid + 2); - c1_it.setCol(tm1, m_dirAxe); - - c2_it = c2.writeLine(m_cid + 2); - c2_it.addCol(tm2a, -m_dirAxe); - } - else if (r > ab) - { - m_thirdConstraint = r - ab; - cIndex++; - - c1_it = c1.writeLine(m_cid + 2); - c1_it.setCol(tm1, -m_dirAxe); - - c2_it = c2.writeLine(m_cid + 2); - c2_it.addCol(tm2b, m_dirAxe); - } - - c1_d.endEdit(); - c2_d.endEdit(); -} - - -template -void SlidingConstraint::getConstraintViolation(const core::ConstraintParams *, linearalgebra::BaseVector *v, const DataVecCoord &, const DataVecCoord & - , const DataVecDeriv &, const DataVecDeriv &) -{ - v->set(m_cid, m_dist); - v->set(m_cid+1, 0.0); - - if(m_thirdConstraint) - { - if(m_thirdConstraint>0) - v->set(m_cid+2, -m_thirdConstraint); - else - v->set(m_cid+2, m_thirdConstraint); - } -} - - -template -void SlidingConstraint::getConstraintResolution(const ConstraintParams*, - std::vector& resTab, - unsigned int& offset) -{ - resTab[offset++] = new BilateralConstraintResolution(); - resTab[offset++] = new BilateralConstraintResolution(); - - if(m_thirdConstraint) - resTab[offset++] = new UnilateralConstraintResolution(); -} - - -template -void SlidingConstraint::storeLambda(const ConstraintParams* /*cParams*/, sofa::core::MultiVecDerivId /*res*/, const sofa::linearalgebra::BaseVector* lambda) -{ - Real lamb1,lamb2, lamb3; - - lamb1 = lambda->element(m_cid); - lamb2 = lambda->element(m_cid+1); - - if(m_thirdConstraint) - { - lamb3 = lambda->element(m_cid+2); - d_force.setValue( m_dirProj* lamb1 + m_dirOrtho * lamb2 + m_dirAxe * lamb3); - } - else - { - d_force.setValue( m_dirProj* lamb1 + m_dirOrtho * lamb2 ); - } -} - -template -void SlidingConstraint::draw(const core::visual::VisualParams* vparams) -{ - if (!vparams->displayFlags().getShowInteractionForceFields()) - return; - - const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); - - vparams->drawTool()->disableLighting(); - - sofa::type::RGBAColor color; - - if(m_thirdConstraint<0) - color = sofa::type::RGBAColor::yellow(); - else if(m_thirdConstraint>0) - color = sofa::type::RGBAColor::green(); - else - color = sofa::type::RGBAColor::magenta(); - - std::vector vertices; - vertices.push_back(DataTypes::getCPos((this->mstate1->read(core::ConstVecCoordId::position())->getValue())[d_m1.getValue()])); - - vparams->drawTool()->drawPoints(vertices, 10, color); - vertices.clear(); - - color = sofa::type::RGBAColor::blue(); - vertices.push_back(DataTypes::getCPos((this->mstate2->read(core::ConstVecCoordId::position())->getValue())[d_m2a.getValue()])); - vertices.push_back(DataTypes::getCPos((this->mstate2->read(core::ConstVecCoordId::position())->getValue())[d_m2b.getValue()])); - vparams->drawTool()->drawLines(vertices, 1, color); - - -} - -} //namespace sofa::component::constraint::lagrangian::model +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/lagrangian/model/SlidingLagrangianConstraint.inl") diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingConstraint.cpp b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingLagrangianConstraint.cpp similarity index 85% rename from Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingConstraint.cpp rename to Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingLagrangianConstraint.cpp index a3e1d474ae9..86f42c1935b 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingConstraint.cpp +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingLagrangianConstraint.cpp @@ -19,9 +19,9 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_CONSTRAINTSET_SLIDINGCONSTRAINT_CPP +#define SOFA_COMPONENT_CONSTRAINTSET_SLIDINGLAGRANGIANCONSTRAINT_CPP -#include +#include #include #include @@ -32,10 +32,10 @@ namespace sofa::component::constraint::lagrangian::model using namespace sofa::defaulttype; using namespace sofa::helper; -int SlidingConstraintClass = core::RegisterObject("TODO-SlidingConstraint") - .add< SlidingConstraint >(true); +int SlidingLagrangianConstraintClass = core::RegisterObject("TODO-SlidingLagrangianConstraint") + .add< SlidingLagrangianConstraint >(true); -template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API SlidingConstraint; +template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API SlidingLagrangianConstraint; } //namespace sofa::component::constraint::lagrangian::model diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingLagrangianConstraint.h b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingLagrangianConstraint.h new file mode 100644 index 00000000000..81015097548 --- /dev/null +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingLagrangianConstraint.h @@ -0,0 +1,113 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include + +namespace sofa::component::constraint::lagrangian::model +{ + +using sofa::core::ConstraintParams; + +template +class SlidingLagrangianConstraint : public core::behavior::PairInteractionConstraint +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(SlidingLagrangianConstraint,DataTypes), SOFA_TEMPLATE(core::behavior::PairInteractionConstraint,DataTypes)); + + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::MatrixDeriv::RowIterator MatrixDerivRowIterator; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename Coord::value_type Real; + typedef typename core::behavior::MechanicalState MechanicalState; + typedef typename core::behavior::PairInteractionConstraint Inherit; + + typedef core::objectmodel::Data DataVecCoord; + typedef core::objectmodel::Data DataVecDeriv; + typedef core::objectmodel::Data DataMatrixDeriv; + +protected: + + Data d_m1; ///< index of the spliding point on the first model + Data d_m2a; ///< index of one end of the sliding axis + Data d_m2b; ///< index of the other end of the sliding axis + Data d_force; ///< interaction force + + Real m_dist; // constraint violation + Real m_thirdConstraint; // 0 if A getSlidingIdentifiers() { return {}; } + + virtual type::vector getPairInteractionIdentifiers() override final + { + type::vector ids = getSlidingIdentifiers(); + ids.push_back("Sliding"); + return ids; + } + + +public: + void init() override; + + void buildConstraintMatrix(const core::ConstraintParams* cParams, DataMatrixDeriv &c1, DataMatrixDeriv &c2, unsigned int &cIndex + , const DataVecCoord &x1, const DataVecCoord &x2) override; + + void getConstraintViolation(const core::ConstraintParams* cParams, linearalgebra::BaseVector *v, const DataVecCoord &x1, const DataVecCoord &x2 + , const DataVecDeriv &v1, const DataVecDeriv &v2) override; + + void getConstraintResolution(const core::ConstraintParams*, + std::vector& resTab, + unsigned int& offset) override; + void storeLambda(const ConstraintParams* cParams, sofa::core::MultiVecDerivId res, const sofa::linearalgebra::BaseVector* lambda) override; + + void draw(const core::visual::VisualParams* vparams) override; + +private: + // storage of force + Deriv m_dirAxe, m_dirProj, m_dirOrtho; + + + +}; + +#if !defined(SOFA_COMPONENT_CONSTRAINTSET_SLIDINGLAGRANGIANCONSTRAINT_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API SlidingLagrangianConstraint< defaulttype::Vec3Types >; + +#endif + +} //namespace sofa::component::constraint::lagrangian::model diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingLagrangianConstraint.inl b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingLagrangianConstraint.inl new file mode 100644 index 00000000000..0a010e9a7e9 --- /dev/null +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingLagrangianConstraint.inl @@ -0,0 +1,226 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include +#include +#include +#include +#include +#include +namespace sofa::component::constraint::lagrangian::model +{ + +template +SlidingLagrangianConstraint::SlidingLagrangianConstraint() + : SlidingLagrangianConstraint(nullptr, nullptr) +{ +} + +template +SlidingLagrangianConstraint::SlidingLagrangianConstraint(MechanicalState* object) + : SlidingLagrangianConstraint(object, object) +{ +} + +template +SlidingLagrangianConstraint::SlidingLagrangianConstraint(MechanicalState* object1, MechanicalState* object2) + : Inherit(object1, object2) + , d_m1(initData(&d_m1, 0, "sliding_point","index of the spliding point on the first model")) + , d_m2a(initData(&d_m2a, 0, "axis_1","index of one end of the sliding axis")) + , d_m2b(initData(&d_m2b, 0, "axis_2","index of the other end of the sliding axis")) + , d_force(initData(&d_force,"force","force (impulse) used to solve the constraint")) +{ +} + +template +void SlidingLagrangianConstraint::init() +{ + assert(this->mstate1); + assert(this->mstate2); + + m_thirdConstraint = 0; +} + + +template +void SlidingLagrangianConstraint::buildConstraintMatrix(const core::ConstraintParams*, DataMatrixDeriv &c1_d, DataMatrixDeriv &c2_d, unsigned int &cIndex + , const DataVecCoord &x1, const DataVecCoord &x2) +{ + int tm1 = d_m1.getValue(); + int tm2a = d_m2a.getValue(); + int tm2b = d_m2b.getValue(); + + MatrixDeriv &c1 = *c1_d.beginEdit(); + MatrixDeriv &c2 = *c2_d.beginEdit(); + + const Coord P = x1.getValue()[tm1]; + const Coord A = x2.getValue()[tm2a]; + const Coord B = x2.getValue()[tm2b]; + + // the axis + m_dirAxe = B - A; + const Real ab = m_dirAxe.norm(); + m_dirAxe.normalize(); + + // projection of the point on the axis + Real r = (P-A) * m_dirAxe; + Real r2 = r / ab; + const Deriv proj = A + m_dirAxe * r; + + // We move the constraint point onto the projection + m_dirProj = P - proj; + m_dist = m_dirProj.norm(); // constraint violation + m_dirProj.normalize(); // direction of the constraint + + m_dirOrtho = cross(m_dirProj, m_dirAxe); + m_dirOrtho.normalize(); + + m_cid = cIndex; + cIndex += 2; + + MatrixDerivRowIterator c1_it = c1.writeLine(m_cid); + c1_it.addCol(tm1, m_dirProj); + + MatrixDerivRowIterator c2_it = c2.writeLine(m_cid); + c2_it.addCol(tm2a, -m_dirProj * (1-r2)); + c2_it.addCol(tm2b, -m_dirProj * r2); + + c1_it = c1.writeLine(m_cid + 1); + c1_it.setCol(tm1, m_dirOrtho); + + c2_it = c2.writeLine(m_cid + 1); + c2_it.addCol(tm2a, -m_dirOrtho * (1-r2)); + c2_it.addCol(tm2b, -m_dirOrtho * r2); + + m_thirdConstraint = 0; + + if (r < 0) + { + m_thirdConstraint = r; + cIndex++; + + c1_it = c1.writeLine(m_cid + 2); + c1_it.setCol(tm1, m_dirAxe); + + c2_it = c2.writeLine(m_cid + 2); + c2_it.addCol(tm2a, -m_dirAxe); + } + else if (r > ab) + { + m_thirdConstraint = r - ab; + cIndex++; + + c1_it = c1.writeLine(m_cid + 2); + c1_it.setCol(tm1, -m_dirAxe); + + c2_it = c2.writeLine(m_cid + 2); + c2_it.addCol(tm2b, m_dirAxe); + } + + c1_d.endEdit(); + c2_d.endEdit(); +} + + +template +void SlidingLagrangianConstraint::getConstraintViolation(const core::ConstraintParams *, linearalgebra::BaseVector *v, const DataVecCoord &, const DataVecCoord & + , const DataVecDeriv &, const DataVecDeriv &) +{ + v->set(m_cid, m_dist); + v->set(m_cid+1, 0.0); + + if(m_thirdConstraint) + { + if(m_thirdConstraint>0) + v->set(m_cid+2, -m_thirdConstraint); + else + v->set(m_cid+2, m_thirdConstraint); + } +} + + +template +void SlidingLagrangianConstraint::getConstraintResolution(const ConstraintParams*, + std::vector& resTab, + unsigned int& offset) +{ + resTab[offset++] = new BilateralConstraintResolution(); + resTab[offset++] = new BilateralConstraintResolution(); + + if(m_thirdConstraint) + resTab[offset++] = new UnilateralConstraintResolution(); +} + + +template +void SlidingLagrangianConstraint::storeLambda(const ConstraintParams* /*cParams*/, sofa::core::MultiVecDerivId /*res*/, const sofa::linearalgebra::BaseVector* lambda) +{ + Real lamb1,lamb2, lamb3; + + lamb1 = lambda->element(m_cid); + lamb2 = lambda->element(m_cid+1); + + if(m_thirdConstraint) + { + lamb3 = lambda->element(m_cid+2); + d_force.setValue( m_dirProj* lamb1 + m_dirOrtho * lamb2 + m_dirAxe * lamb3); + } + else + { + d_force.setValue( m_dirProj* lamb1 + m_dirOrtho * lamb2 ); + } +} + +template +void SlidingLagrangianConstraint::draw(const core::visual::VisualParams* vparams) +{ + if (!vparams->displayFlags().getShowInteractionForceFields()) + return; + + const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); + + vparams->drawTool()->disableLighting(); + + sofa::type::RGBAColor color; + + if(m_thirdConstraint<0) + color = sofa::type::RGBAColor::yellow(); + else if(m_thirdConstraint>0) + color = sofa::type::RGBAColor::green(); + else + color = sofa::type::RGBAColor::magenta(); + + std::vector vertices; + vertices.push_back(DataTypes::getCPos((this->mstate1->read(core::ConstVecCoordId::position())->getValue())[d_m1.getValue()])); + + vparams->drawTool()->drawPoints(vertices, 10, color); + vertices.clear(); + + color = sofa::type::RGBAColor::blue(); + vertices.push_back(DataTypes::getCPos((this->mstate2->read(core::ConstVecCoordId::position())->getValue())[d_m2a.getValue()])); + vertices.push_back(DataTypes::getCPos((this->mstate2->read(core::ConstVecCoordId::position())->getValue())[d_m2b.getValue()])); + vparams->drawTool()->drawLines(vertices, 1, color); + + +} + +} //namespace sofa::component::constraint::lagrangian::model diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperConstraint.h b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperConstraint.h index 42cdea0cfcf..f73e0306abe 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperConstraint.h +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperConstraint.h @@ -20,108 +20,14 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::lagrangian::model -{ - -class StopperConstraintResolution1Dof : public core::behavior::ConstraintResolution -{ -protected: - double _invW, _w, _min, _max ; - -public: - - StopperConstraintResolution1Dof(const double &min, const double &max) - : core::behavior::ConstraintResolution(1) - , _min(min) - , _max(max) - { - } - - void init(int line, SReal** w, SReal*force) override - { - _w = w[line][line]; - _invW = 1.0/_w; - force[line ] = 0.0; - } +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/lagrangian/model/StopperLagrangianConstraint.h") - void resolution(int line, SReal** /*w*/, SReal* d, SReal* force, SReal*) override - { - const double dfree = d[line] - _w * force[line]; - if (dfree > _max) - force[line] = (_max - dfree) * _invW; - else if (dfree < _min) - force[line] = (_min - dfree) * _invW; - else - force[line] = 0; - } -}; - -template< class DataTypes > -class StopperConstraint : public core::behavior::Constraint +namespace sofa::component::constraint::lagrangian::model { -public: - SOFA_CLASS(SOFA_TEMPLATE(StopperConstraint,DataTypes), SOFA_TEMPLATE(core::behavior::Constraint,DataTypes)); - - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename Coord::value_type Real; - typedef typename core::behavior::MechanicalState MechanicalState; - typedef typename core::behavior::Constraint Inherit; - - typedef typename DataTypes::MatrixDeriv::RowIterator MatrixDerivRowIterator; - typedef core::objectmodel::Data DataVecCoord; - typedef core::objectmodel::Data DataVecDeriv; - typedef core::objectmodel::Data DataMatrixDeriv; - -protected: - - unsigned int cid; - - Data index; ///< index of the stop constraint - Data min; ///< minimum value accepted - Data max; ///< maximum value accepted - - - - StopperConstraint(MechanicalState* object = nullptr); - - virtual ~StopperConstraint() {} - - - virtual type::vector getConstraintIdentifiers() override final - { - type::vector ids = getStopperIdentifiers(); - ids.push_back("Stopper"); - ids.push_back("Unilateral"); - return ids; - } - - virtual type::vector getStopperIdentifiers(){ return {}; } - - - -public: - void init() override; - void buildConstraintMatrix(const core::ConstraintParams* cParams, DataMatrixDeriv &c_d, unsigned int &cIndex, const DataVecCoord &x) override; - void getConstraintViolation(const core::ConstraintParams* cParams, linearalgebra::BaseVector *resV, const DataVecCoord &x, const DataVecDeriv &v) override; - - void getConstraintResolution(const core::ConstraintParams *, std::vector& resTab, unsigned int& offset) override; -}; - -#if !defined(SOFA_COMPONENT_CONSTRAINTSET_STOPPERCONSTRAINT_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API StopperConstraint; - -#endif - -} //namespace sofa::component::constraint::lagrangian::model +template +using StopperConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "StopperConstraint has been renamed to StopperLagrangianConstraint") = StopperLagrangianConstraint; +} diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperConstraint.inl b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperConstraint.inl index 6f1e04be10f..9c4215fb990 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperConstraint.inl +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperConstraint.inl @@ -20,62 +20,7 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include +#include -namespace sofa::component::constraint::lagrangian::model -{ - -template -StopperConstraint::StopperConstraint(MechanicalState* object) - : Inherit(object) - , index(initData(&index, 0, "index", "index of the stop constraint")) - , min(initData(&min, -100.0_sreal, "min", "minimum value accepted")) - , max(initData(&max, 100.0_sreal, "max", "maximum value accepted")) -{ -} - -template -void StopperConstraint::init() -{ - this->mstate = dynamic_cast(this->getContext()->getMechanicalState()); - assert(this->mstate); - - helper::WriteAccessor > xData = *this->mstate->write(core::VecCoordId::position()); - VecCoord& x = xData.wref(); - if (x[index.getValue()].x() < min.getValue()) - x[index.getValue()].x() = (Real) min.getValue(); - if (x[index.getValue()].x() > max.getValue()) - x[index.getValue()].x() = (Real) max.getValue(); -} - -template -void StopperConstraint::buildConstraintMatrix(const core::ConstraintParams* /*cParams*/, DataMatrixDeriv &c_d, unsigned int &cIndex, const DataVecCoord &/*x*/) -{ - cid = cIndex; - - MatrixDeriv& c = *c_d.beginEdit(); - - MatrixDerivRowIterator c_it = c.writeLine(cid); - c_it.setCol(index.getValue(), Coord(1)); - - cIndex++; - c_d.endEdit(); -} - -template -void StopperConstraint::getConstraintViolation(const core::ConstraintParams* /*cParams*/, linearalgebra::BaseVector *resV, const DataVecCoord &x, const DataVecDeriv &/*v*/) -{ - resV->set(cid, x.getValue()[index.getValue()][0]); -} - -template -void StopperConstraint::getConstraintResolution(const core::ConstraintParams *, std::vector& resTab, unsigned int& offset) -{ - for(int i=0; i<1; i++) - resTab[offset++] = new StopperConstraintResolution1Dof(min.getValue(), max.getValue()); -} - -} //namespace sofa::component::constraint::lagrangian::model +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/lagrangian/model/StopperLagrangianConstraint.inl") diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperConstraint.cpp b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperLagrangianConstraint.cpp similarity index 85% rename from Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperConstraint.cpp rename to Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperLagrangianConstraint.cpp index a56e09d0713..431a80e8428 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperConstraint.cpp +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperLagrangianConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_CONSTRAINTSET_STOPPERCONSTRAINT_CPP -#include +#define SOFA_COMPONENT_CONSTRAINTSET_STOPPERLAGRANGIANCONSTRAINT_CPP +#include #include #include @@ -31,12 +31,12 @@ namespace sofa::component::constraint::lagrangian::model using namespace sofa::defaulttype; using namespace sofa::helper; -int StopperConstraintClass = core::RegisterObject("TODO-StopperConstraint") - .add< StopperConstraint >() +int StopperLagrangianConstraintClass = core::RegisterObject("TODO-StopperLagrangianConstraint") + .add< StopperLagrangianConstraint >() ; -template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API StopperConstraint; +template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API StopperLagrangianConstraint; } //namespace sofa::component::constraint::lagrangian::model diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperLagrangianConstraint.h b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperLagrangianConstraint.h new file mode 100644 index 00000000000..e9f6d463985 --- /dev/null +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperLagrangianConstraint.h @@ -0,0 +1,127 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include +#include + +namespace sofa::component::constraint::lagrangian::model +{ + +class StopperLagrangianConstraintResolution1Dof : public core::behavior::ConstraintResolution +{ +protected: + double _invW, _w, _min, _max ; + +public: + + StopperLagrangianConstraintResolution1Dof(const double &min, const double &max) + : core::behavior::ConstraintResolution(1) + , _min(min) + , _max(max) + { + } + + void init(int line, SReal** w, SReal*force) override + { + _w = w[line][line]; + _invW = 1.0/_w; + force[line ] = 0.0; + } + + void resolution(int line, SReal** /*w*/, SReal* d, SReal* force, SReal*) override + { + const double dfree = d[line] - _w * force[line]; + + if (dfree > _max) + force[line] = (_max - dfree) * _invW; + else if (dfree < _min) + force[line] = (_min - dfree) * _invW; + else + force[line] = 0; + } +}; + +template< class DataTypes > +class StopperLagrangianConstraint : public core::behavior::Constraint +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(StopperLagrangianConstraint,DataTypes), SOFA_TEMPLATE(core::behavior::Constraint,DataTypes)); + + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename Coord::value_type Real; + typedef typename core::behavior::MechanicalState MechanicalState; + typedef typename core::behavior::Constraint Inherit; + + typedef typename DataTypes::MatrixDeriv::RowIterator MatrixDerivRowIterator; + typedef core::objectmodel::Data DataVecCoord; + typedef core::objectmodel::Data DataVecDeriv; + typedef core::objectmodel::Data DataMatrixDeriv; + +protected: + + unsigned int cid; + + Data index; ///< index of the stop constraint + Data min; ///< minimum value accepted + Data max; ///< maximum value accepted + + + + StopperLagrangianConstraint(MechanicalState* object = nullptr); + + virtual ~StopperLagrangianConstraint() {} + + + virtual type::vector getConstraintIdentifiers() override final + { + type::vector ids = getStopperIdentifiers(); + ids.push_back("Stopper"); + ids.push_back("Unilateral"); + return ids; + } + + virtual type::vector getStopperIdentifiers(){ return {}; } + + + +public: + void init() override; + void buildConstraintMatrix(const core::ConstraintParams* cParams, DataMatrixDeriv &c_d, unsigned int &cIndex, const DataVecCoord &x) override; + void getConstraintViolation(const core::ConstraintParams* cParams, linearalgebra::BaseVector *resV, const DataVecCoord &x, const DataVecDeriv &v) override; + + void getConstraintResolution(const core::ConstraintParams *, std::vector& resTab, unsigned int& offset) override; +}; + +#if !defined(SOFA_COMPONENT_CONSTRAINTSET_STOPPERLAGRANGIANCONSTRAINT_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API StopperLagrangianConstraint; + +#endif + +} //namespace sofa::component::constraint::lagrangian::model diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperLagrangianConstraint.inl b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperLagrangianConstraint.inl new file mode 100644 index 00000000000..7265ab54804 --- /dev/null +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperLagrangianConstraint.inl @@ -0,0 +1,81 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include +#include + +#include + +namespace sofa::component::constraint::lagrangian::model +{ + +template +StopperLagrangianConstraint::StopperLagrangianConstraint(MechanicalState* object) + : Inherit(object) + , index(initData(&index, 0, "index", "index of the stop constraint")) + , min(initData(&min, -100.0_sreal, "min", "minimum value accepted")) + , max(initData(&max, 100.0_sreal, "max", "maximum value accepted")) +{ +} + +template +void StopperLagrangianConstraint::init() +{ + this->mstate = dynamic_cast(this->getContext()->getMechanicalState()); + assert(this->mstate); + + helper::WriteAccessor > xData = *this->mstate->write(core::VecCoordId::position()); + VecCoord& x = xData.wref(); + if (x[index.getValue()].x() < min.getValue()) + x[index.getValue()].x() = (Real) min.getValue(); + if (x[index.getValue()].x() > max.getValue()) + x[index.getValue()].x() = (Real) max.getValue(); +} + +template +void StopperLagrangianConstraint::buildConstraintMatrix(const core::ConstraintParams* /*cParams*/, DataMatrixDeriv &c_d, unsigned int &cIndex, const DataVecCoord &/*x*/) +{ + cid = cIndex; + + MatrixDeriv& c = *c_d.beginEdit(); + + MatrixDerivRowIterator c_it = c.writeLine(cid); + c_it.setCol(index.getValue(), Coord(1)); + + cIndex++; + c_d.endEdit(); +} + +template +void StopperLagrangianConstraint::getConstraintViolation(const core::ConstraintParams* /*cParams*/, linearalgebra::BaseVector *resV, const DataVecCoord &x, const DataVecDeriv &/*v*/) +{ + resV->set(cid, x.getValue()[index.getValue()][0]); +} + +template +void StopperLagrangianConstraint::getConstraintResolution(const core::ConstraintParams *, std::vector& resTab, unsigned int& offset) +{ + for(int i=0; i<1; i++) + resTab[offset++] = new StopperLagrangianConstraintResolution1Dof(min.getValue(), max.getValue()); +} + +} //namespace sofa::component::constraint::lagrangian::model diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformConstraint.h b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformConstraint.h index e53399c5b9a..23e3d697dec 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformConstraint.h +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformConstraint.h @@ -20,58 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include +#include -namespace sofa::component::constraint::lagrangian::model -{ +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/lagrangian/model/UniformLagrangianConstraint.h") -template < class DataTypes > -class UniformConstraint : public sofa::core::behavior::Constraint< DataTypes > +namespace sofa::component::constraint::lagrangian::model { -public: - SOFA_CLASS(SOFA_TEMPLATE(UniformConstraint, DataTypes), SOFA_TEMPLATE(sofa::core::behavior::Constraint, DataTypes)); - - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::Real Real; - - typedef sofa::Data DataVecCoord; - typedef sofa::Data DataVecDeriv; - typedef sofa::Data DataMatrixDeriv; - - void buildConstraintMatrix(const sofa::core::ConstraintParams* cParams, DataMatrixDeriv & c, unsigned int &cIndex, const DataVecCoord &x) override; - - void getConstraintViolation(const sofa::core::ConstraintParams* cParams, sofa::linearalgebra::BaseVector *resV, const DataVecCoord &x, const DataVecDeriv &v) override; - - void getConstraintResolution(const sofa::core::ConstraintParams* cParams, std::vector& crVector, unsigned int& offset) override; - - sofa::Data d_iterative; ///< Iterate over the bilateral constraints, otherwise a block factorisation is computed. - sofa::Data d_constraintRestPos; ///< if false, constrains the pos to be zero / if true constraint the current position to stay at rest position -protected: - - unsigned int m_constraintIndex; - - UniformConstraint(); - - virtual type::vector getConstraintIdentifiers() override final - { - type::vector ids = getStopperIdentifiers(); - ids.push_back("Uniform"); - ids.push_back("Bilateral"); - return ids; - } - - virtual type::vector getStopperIdentifiers(){ return {}; } - -}; - -#if !defined(SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_UNIFORMCONSTRAINT_CPP) - extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API UniformConstraint; -#endif - -} // namespace sofa::component::constraint::lagrangian::model +template +using UniformConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "UniformConstraint has been renamed to UniformLagrangianConstraint") = UniformLagrangianConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformConstraint.inl b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformConstraint.inl index b34a9377b97..991bb0accc8 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformConstraint.inl +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformConstraint.inl @@ -19,119 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ - #pragma once -#include - -#include -#include -#include - -namespace sofa::component::constraint::lagrangian::model -{ - -template< class DataTypes > -UniformConstraint::UniformConstraint() - :d_iterative(initData(&d_iterative, true, "iterative", "Iterate over the bilateral constraints, otherwise a block factorisation is computed.")) - ,d_constraintRestPos(initData(&d_constraintRestPos, false, "constrainToRestPos", "if false, constrains the pos to be zero / if true constraint the current position to stay at rest position")) - ,m_constraintIndex(0) -{ - -} - -template< class DataTypes > -void UniformConstraint::buildConstraintMatrix(const sofa::core::ConstraintParams* cParams, DataMatrixDeriv & c, unsigned int &cIndex, const DataVecCoord &x) -{ - SOFA_UNUSED(cParams); - - const auto N = Deriv::size(); // MatrixDeriv is a container of Deriv types. - - auto& jacobian = sofa::helper::getWriteAccessor(c).wref(); - auto xVec = sofa::helper::getReadAccessor(x); - - m_constraintIndex = cIndex; // we should not have to remember this, it should be available through the API directly. - - for (std::size_t i = 0; i < xVec.size(); ++i) - { - for (std::size_t j = 0; j < N; ++j) - { - auto row = jacobian.writeLine(N*i + j + m_constraintIndex); - Deriv d; - d[j] = Real(1); - row.setCol(i, d); - ++cIndex; - } - } -} - -template -void computeViolation(DstV& resV, unsigned int constraintIndex, const - Free& free, size_t N, std::function f) -{ - for (std::size_t i = 0; i < free.size(); ++i) - { - for (std::size_t j = 0; j < N; ++j) - { - resV->set(constraintIndex + i*N + j, f(i, j) ); - } - } -} - -template< class DataTypes > -void UniformConstraint::getConstraintViolation(const sofa::core::ConstraintParams* cParams, sofa::linearalgebra::BaseVector *resV, const DataVecCoord &x, const DataVecDeriv &v) -{ - auto xfree = sofa::helper::getReadAccessor(x); - auto vfree = sofa::helper::getReadAccessor(v); - const SReal dt = this->getContext()->getDt(); - const SReal invDt = 1.0 / dt; - - auto pos = this->getMState()->readPositions(); - auto restPos = this->getMState()->readRestPositions(); - - if (cParams->constOrder() == sofa::core::ConstraintOrder::VEL) - { - if (d_constraintRestPos.getValue()){ - computeViolation(resV, m_constraintIndex, vfree, Deriv::size(),[&invDt,&pos,&vfree,&restPos](int i, int j) - { return vfree[i][j] + invDt *(pos[i][j]-restPos[i][j]); }); - } - else { - computeViolation(resV, m_constraintIndex, vfree, Deriv::size(),[&invDt,&pos,&vfree](int i, int j) - { return vfree[i][j] + invDt *pos[i][j]; }); - } - } - else - { - if( d_constraintRestPos.getValue() ) - computeViolation(resV, m_constraintIndex, xfree, Coord::size(), - [&xfree,&restPos](int i, int j){ return xfree[i][j] - restPos[i][j]; }); - else - computeViolation(resV, m_constraintIndex, xfree, Coord::size(),[&xfree](int i, int j){ return xfree[i][j]; }); - } -} - -template< class DataTypes > -void UniformConstraint::getConstraintResolution(const sofa::core::ConstraintParams* cParams, std::vector& crVector, unsigned int& offset) -{ - SOFA_UNUSED(cParams); - if (d_iterative.getValue()) - { - for (std::size_t i = 0; i < this->getMState()->getSize(); ++i) - { - for (std::size_t j = 0; j < Deriv::size(); ++j) - { - auto* cr = new sofa::component::constraint::lagrangian::model::BilateralConstraintResolution(); - crVector[offset++] = cr; - } - } - } - else - { - const std::size_t nbLines = this->getMState()->getSize() * Deriv::size(); - auto* cr = new sofa::component::constraint::lagrangian::model::BilateralConstraintResolutionNDof(nbLines); - crVector[offset] = cr; - offset += nbLines; - } -} +#include -} // namespace sofa::component::constraint::lagrangian::model +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/lagrangian/model/UniformLagrangianConstraint.inl") diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformConstraint.cpp b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformLagrangianConstraint.cpp similarity index 82% rename from Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformConstraint.cpp rename to Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformLagrangianConstraint.cpp index 60f11dac072..eb993968042 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformConstraint.cpp +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformLagrangianConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_UNIFORMCONSTRAINT_CPP -#include +#define SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_UNIFORMLAGRANGIANCONSTRAINT_CPP +#include #include #include @@ -28,11 +28,11 @@ namespace sofa::component::constraint::lagrangian::model { -int UniformConstraintClass = sofa::core::RegisterObject("A constraint equation applied on all dofs.") -.add< UniformConstraint >() +int UniformLagrangianConstraintClass = sofa::core::RegisterObject("A constraint equation applied on all dofs.") +.add< UniformLagrangianConstraint >() ; -template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API UniformConstraint; +template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API UniformLagrangianConstraint; } // namespace sofa::component::constraint::lagrangian::model diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformLagrangianConstraint.h b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformLagrangianConstraint.h new file mode 100644 index 00000000000..7576ad73b2f --- /dev/null +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformLagrangianConstraint.h @@ -0,0 +1,78 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include + +namespace sofa::component::constraint::lagrangian::model +{ + +template < class DataTypes > +class UniformLagrangianConstraint : public sofa::core::behavior::Constraint< DataTypes > +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(UniformLagrangianConstraint, DataTypes), SOFA_TEMPLATE(sofa::core::behavior::Constraint, DataTypes)); + + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::Real Real; + + typedef sofa::Data DataVecCoord; + typedef sofa::Data DataVecDeriv; + typedef sofa::Data DataMatrixDeriv; + + void buildConstraintMatrix(const sofa::core::ConstraintParams* cParams, DataMatrixDeriv & c, unsigned int &cIndex, const DataVecCoord &x) override; + + void getConstraintViolation(const sofa::core::ConstraintParams* cParams, sofa::linearalgebra::BaseVector *resV, const DataVecCoord &x, const DataVecDeriv &v) override; + + void getConstraintResolution(const sofa::core::ConstraintParams* cParams, std::vector& crVector, unsigned int& offset) override; + + sofa::Data d_iterative; ///< Iterate over the bilateral constraints, otherwise a block factorisation is computed. + sofa::Data d_constraintRestPos; ///< if false, constrains the pos to be zero / if true constraint the current position to stay at rest position +protected: + + unsigned int m_constraintIndex; + + UniformLagrangianConstraint(); + + virtual type::vector getConstraintIdentifiers() override final + { + type::vector ids = getStopperIdentifiers(); + ids.push_back("Uniform"); + ids.push_back("Bilateral"); + return ids; + } + + virtual type::vector getStopperIdentifiers(){ return {}; } + +}; + +#if !defined(SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_UNIFORMLAGRANGIANCONSTRAINT_CPP) + extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API UniformLagrangianConstraint; +#endif + + +} // namespace sofa::component::constraint::lagrangian::model diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformLagrangianConstraint.inl b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformLagrangianConstraint.inl new file mode 100644 index 00000000000..707797df0c4 --- /dev/null +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformLagrangianConstraint.inl @@ -0,0 +1,137 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ + +#pragma once +#include + +#include +#include +#include + +namespace sofa::component::constraint::lagrangian::model +{ + +template< class DataTypes > +UniformLagrangianConstraint::UniformLagrangianConstraint() + :d_iterative(initData(&d_iterative, true, "iterative", "Iterate over the bilateral constraints, otherwise a block factorisation is computed.")) + ,d_constraintRestPos(initData(&d_constraintRestPos, false, "constrainToRestPos", "if false, constrains the pos to be zero / if true constraint the current position to stay at rest position")) + ,m_constraintIndex(0) +{ + +} + +template< class DataTypes > +void UniformLagrangianConstraint::buildConstraintMatrix(const sofa::core::ConstraintParams* cParams, DataMatrixDeriv & c, unsigned int &cIndex, const DataVecCoord &x) +{ + SOFA_UNUSED(cParams); + + const auto N = Deriv::size(); // MatrixDeriv is a container of Deriv types. + + auto& jacobian = sofa::helper::getWriteAccessor(c).wref(); + auto xVec = sofa::helper::getReadAccessor(x); + + m_constraintIndex = cIndex; // we should not have to remember this, it should be available through the API directly. + + for (std::size_t i = 0; i < xVec.size(); ++i) + { + for (std::size_t j = 0; j < N; ++j) + { + auto row = jacobian.writeLine(N*i + j + m_constraintIndex); + Deriv d; + d[j] = Real(1); + row.setCol(i, d); + ++cIndex; + } + } +} + +template +void computeViolation(DstV& resV, unsigned int constraintIndex, const + Free& free, size_t N, std::function f) +{ + for (std::size_t i = 0; i < free.size(); ++i) + { + for (std::size_t j = 0; j < N; ++j) + { + resV->set(constraintIndex + i*N + j, f(i, j) ); + } + } +} + +template< class DataTypes > +void UniformLagrangianConstraint::getConstraintViolation(const sofa::core::ConstraintParams* cParams, sofa::linearalgebra::BaseVector *resV, const DataVecCoord &x, const DataVecDeriv &v) +{ + auto xfree = sofa::helper::getReadAccessor(x); + auto vfree = sofa::helper::getReadAccessor(v); + const SReal dt = this->getContext()->getDt(); + const SReal invDt = 1.0 / dt; + + auto pos = this->getMState()->readPositions(); + auto restPos = this->getMState()->readRestPositions(); + + if (cParams->constOrder() == sofa::core::ConstraintOrder::VEL) + { + if (d_constraintRestPos.getValue()){ + computeViolation(resV, m_constraintIndex, vfree, Deriv::size(),[&invDt,&pos,&vfree,&restPos](int i, int j) + { return vfree[i][j] + invDt *(pos[i][j]-restPos[i][j]); }); + } + else { + computeViolation(resV, m_constraintIndex, vfree, Deriv::size(),[&invDt,&pos,&vfree](int i, int j) + { return vfree[i][j] + invDt *pos[i][j]; }); + } + } + else + { + if( d_constraintRestPos.getValue() ) + computeViolation(resV, m_constraintIndex, xfree, Coord::size(), + [&xfree,&restPos](int i, int j){ return xfree[i][j] - restPos[i][j]; }); + else + computeViolation(resV, m_constraintIndex, xfree, Coord::size(),[&xfree](int i, int j){ return xfree[i][j]; }); + } +} + +template< class DataTypes > +void UniformLagrangianConstraint::getConstraintResolution(const sofa::core::ConstraintParams* cParams, std::vector& crVector, unsigned int& offset) +{ + SOFA_UNUSED(cParams); + + if (d_iterative.getValue()) + { + for (std::size_t i = 0; i < this->getMState()->getSize(); ++i) + { + for (std::size_t j = 0; j < Deriv::size(); ++j) + { + auto* cr = new sofa::component::constraint::lagrangian::model::BilateralConstraintResolution(); + crVector[offset++] = cr; + } + } + } + else + { + const std::size_t nbLines = this->getMState()->getSize() * Deriv::size(); + auto* cr = new sofa::component::constraint::lagrangian::model::BilateralConstraintResolutionNDof(nbLines); + crVector[offset] = cr; + offset += nbLines; + } +} + +} // namespace sofa::component::constraint::lagrangian::model diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralConstraintResolution.h b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralConstraintResolution.h new file mode 100644 index 00000000000..3cf9f7847e5 --- /dev/null +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralConstraintResolution.h @@ -0,0 +1,100 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include +#include +#include + + +namespace sofa::component::constraint::lagrangian::model +{ + +class UnilateralConstraintResolution : public core::behavior::ConstraintResolution +{ + public: + UnilateralConstraintResolution() : core::behavior::ConstraintResolution(1) {} + + void resolution(int line, SReal** w, SReal* d, SReal* force, SReal* dfree) override + { + SOFA_UNUSED(dfree); + force[line] -= d[line] / w[line][line]; + if (force[line] < 0) force[line] = 0.0; + } +}; + +// A little experiment on how to best save the forces for the hot start. +// TODO : save as a map (index of the contact <-> force) +class PreviousForcesContainer +{ + public: + PreviousForcesContainer() : resetFlag(true) {} + SReal popForce() + { + resetFlag = true; + if (forces.empty()) return 0; + const SReal f = forces.front(); + forces.pop_front(); + return f; + } + + void pushForce(SReal f) + { + if (resetFlag) + { + forces.clear(); + resetFlag = false; + } + + forces.push_back(f); + } + + protected: + std::deque forces; + bool resetFlag; // We delete all forces that were not read +}; + +class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API UnilateralConstraintResolutionWithFriction + : public core::behavior::ConstraintResolution +{ + public: + UnilateralConstraintResolutionWithFriction(SReal mu, PreviousForcesContainer* prev = nullptr, + bool* active = nullptr) + : core::behavior::ConstraintResolution(3), _mu(mu), _prev(prev), _active(active) + { + } + + void init(int line, SReal** w, SReal* force) override; + void resolution(int line, SReal** w, SReal* d, SReal* force, SReal* dFree) override; + void store(int line, SReal* force, bool /*convergence*/) override; + + protected: + SReal _mu; + SReal _W[6]; + PreviousForcesContainer* _prev; + bool* _active; // Will set this after the resolution +}; + +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralInteractionConstraint.h b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralInteractionConstraint.h index 254103f59fe..70f6cfd932b 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralInteractionConstraint.h +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralInteractionConstraint.h @@ -20,210 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include +#include +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/lagrangian/model/UnilateralLagrangianConstraint.h") namespace sofa::component::constraint::lagrangian::model { -class UnilateralConstraintResolution : public core::behavior::ConstraintResolution -{ -public: - - UnilateralConstraintResolution() : core::behavior::ConstraintResolution(1) - { - - } - - void resolution(int line, SReal** w, SReal* d, SReal* force, SReal *dfree) override - { - SOFA_UNUSED(dfree); - force[line] -= d[line] / w[line][line]; - if(force[line] < 0) - force[line] = 0.0; - } -}; - -// A little experiment on how to best save the forces for the hot start. -// TODO : save as a map (index of the contact <-> force) -class PreviousForcesContainer -{ -public: - PreviousForcesContainer() : resetFlag(true) {} - SReal popForce() - { - resetFlag = true; - if(forces.empty()) return 0; - const SReal f = forces.front(); - forces.pop_front(); - return f; - } - - void pushForce(SReal f) - { - if(resetFlag) - { - forces.clear(); - resetFlag = false; - } - - forces.push_back(f); - } - -protected: - std::deque forces; - bool resetFlag; // We delete all forces that were not read -}; - -class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API UnilateralConstraintResolutionWithFriction : public core::behavior::ConstraintResolution -{ -public: - UnilateralConstraintResolutionWithFriction(SReal mu, PreviousForcesContainer* prev = nullptr, bool* active = nullptr) - :core::behavior::ConstraintResolution(3) - , _mu(mu) - , _prev(prev) - , _active(active) - { - } - - void init(int line, SReal** w, SReal* force) override; - void resolution(int line, SReal** w, SReal* d, SReal* force, SReal *dFree) override; - void store(int line, SReal* force, bool /*convergence*/) override; - -protected: - SReal _mu; - SReal _W[6]; - PreviousForcesContainer* _prev; - bool* _active; // Will set this after the resolution -}; - - -template -class UnilateralInteractionConstraint : public core::behavior::PairInteractionConstraint -{ -public: - SOFA_CLASS(SOFA_TEMPLATE(UnilateralInteractionConstraint,DataTypes), SOFA_TEMPLATE(core::behavior::PairInteractionConstraint,DataTypes)); - - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::MatrixDeriv::RowConstIterator MatrixDerivRowConstIterator; - typedef typename DataTypes::MatrixDeriv::ColConstIterator MatrixDerivColConstIterator; - typedef typename DataTypes::MatrixDeriv::RowIterator MatrixDerivRowIterator; - typedef typename DataTypes::MatrixDeriv::ColIterator MatrixDerivColIterator; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename Coord::value_type Real; - typedef typename core::behavior::MechanicalState MechanicalState; - - typedef core::behavior::BaseConstraint::ConstraintBlockInfo ConstraintBlockInfo; - typedef core::behavior::BaseConstraint::PersistentID PersistentID; - typedef core::behavior::BaseConstraint::ConstCoord ConstCoord; - - typedef core::behavior::BaseConstraint::VecConstraintBlockInfo VecConstraintBlockInfo; - typedef core::behavior::BaseConstraint::VecPersistentID VecPersistentID; - typedef core::behavior::BaseConstraint::VecConstCoord VecConstCoord; - typedef core::behavior::BaseConstraint::VecConstDeriv VecConstDeriv; - typedef core::behavior::BaseConstraint::VecConstArea VecConstArea; - - typedef core::objectmodel::Data DataVecCoord; - typedef core::objectmodel::Data DataVecDeriv; - typedef core::objectmodel::Data DataMatrixDeriv; - - typedef typename core::behavior::PairInteractionConstraint Inherit; - -protected: - - struct Contact - { - int m1, m2; ///< the two extremities of the spring: masses m1 and m2 - Deriv norm; ///< contact normal, from m1 to m2 - Deriv t; ///< added for friction - Deriv s; ///< added for friction - Real contactDistance; - - unsigned int id; - long contactId; - PersistentID localId; - SReal mu; ///< angle for friction - - Coord P, Q; - - mutable Real dfree; - }; - - sofa::type::vector contacts; - Real epsilon; - bool yetIntegrated; - SReal customTolerance; - - PreviousForcesContainer prevForces; - bool* contactsStatus; - - /// Computes constraint violation in position and stores it into resolution global vector - /// - /// @param v Global resolution vector - virtual void getPositionViolation(linearalgebra::BaseVector *v); - - ///Computes constraint violation in velocity and stores it into resolution global vector - /// - /// @param v Global resolution vector - virtual void getVelocityViolation(linearalgebra::BaseVector *v); - -public: - - unsigned int constraintId; -protected: - - virtual type::vector getUnilateralInteractionIdentifiers() {return {};} - - virtual type::vector getPairInteractionIdentifiers() override final - { - type::vector ids = getUnilateralInteractionIdentifiers(); - ids.push_back("Unilateral"); - return ids; - } - - - UnilateralInteractionConstraint(MechanicalState* object1=nullptr, MechanicalState* object2=nullptr); - virtual ~UnilateralInteractionConstraint(); - -public: - void setCustomTolerance(SReal tol) { customTolerance = tol; } - - void clear(int reserve = 0); - - virtual void addContact(SReal mu, Deriv norm, Coord P, Coord Q, Real contactDistance, int m1, int m2, Coord Pfree, Coord Qfree, long id=0, PersistentID localid=0); - - void addContact(SReal mu, Deriv norm, Coord P, Coord Q, Real contactDistance, int m1, int m2, long id=0, PersistentID localid=0); - void addContact(SReal mu, Deriv norm, Real contactDistance, int m1, int m2, long id=0, PersistentID localid=0); - - void buildConstraintMatrix(const core::ConstraintParams* cParams, DataMatrixDeriv &c1, DataMatrixDeriv &c2, unsigned int &cIndex - , const DataVecCoord &x1, const DataVecCoord &x2) override; - - void getConstraintViolation(const core::ConstraintParams* cParams, linearalgebra::BaseVector *v, const DataVecCoord &x1, const DataVecCoord &x2 - , const DataVecDeriv &v1, const DataVecDeriv &v2) override; - - - void getConstraintInfo(const core::ConstraintParams* cParams, VecConstraintBlockInfo& blocks, VecPersistentID& ids, VecConstCoord& positions, VecConstDeriv& directions, VecConstArea& areas) override; - - void getConstraintResolution(const core::ConstraintParams *,std::vector& resTab, unsigned int& offset) override; - bool isActive() const override; - - void draw(const core::visual::VisualParams* vparams) override; -}; - - -#if !defined(SOFA_COMPONENT_CONSTRAINTSET_UNILATERALINTERACTIONCONSTRAINT_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API UnilateralInteractionConstraint; - -#endif - -} //namespace sofa::component::constraint::lagrangian::model +template +using UnilateralInteractionConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "UnilateralInteractionConstraint has been renamed to UnilateralLagrangianConstraint") = UnilateralLagrangianConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralInteractionConstraint.inl b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralInteractionConstraint.inl index 7cd50ba7b9b..d747c9ea9da 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralInteractionConstraint.inl +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralInteractionConstraint.inl @@ -20,402 +20,7 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -namespace sofa::component::constraint::lagrangian::model -{ +#include -template -UnilateralInteractionConstraint::UnilateralInteractionConstraint(MechanicalState* object1, MechanicalState* object2) - : Inherit(object1, object2) - , epsilon(Real(0.001)) - , yetIntegrated(false) - , customTolerance(0.0) - , contactsStatus(nullptr) -{ -} - -template -UnilateralInteractionConstraint::~UnilateralInteractionConstraint() -{ - if(contactsStatus) - delete[] contactsStatus; -} - -template -void UnilateralInteractionConstraint::clear(int reserve) -{ - contacts.clear(); - if (reserve) - contacts.reserve(reserve); -} - -template -void UnilateralInteractionConstraint::addContact(SReal mu, Deriv norm, Coord P, Coord Q, Real contactDistance, int m1, int m2, long id, PersistentID localid) -{ - addContact(mu, norm, P, Q, contactDistance, m1, m2, - this->getMState2()->read(core::ConstVecCoordId::freePosition())->getValue()[m2], - this->getMState1()->read(core::ConstVecCoordId::freePosition())->getValue()[m1], - id, localid); -} - -template -void UnilateralInteractionConstraint::addContact(SReal mu, Deriv norm, Real contactDistance, int m1, int m2, long id, PersistentID localid) -{ - addContact(mu, norm, - this->getMState2()->read(core::ConstVecCoordId::position())->getValue()[m2], - this->getMState1()->read(core::ConstVecCoordId::position())->getValue()[m1], - contactDistance, m1, m2, - this->getMState2()->read(core::ConstVecCoordId::freePosition())->getValue()[m2], - this->getMState1()->read(core::ConstVecCoordId::freePosition())->getValue()[m1], - id, localid); -} - -template -void UnilateralInteractionConstraint::addContact(SReal mu, Deriv norm, Coord P, Coord Q, Real contactDistance, int m1, int m2, Coord /*Pfree*/, Coord /*Qfree*/, long id, PersistentID localid) -{ - contacts.resize(contacts.size() + 1); - Contact &c = contacts.back(); - - c.P = P; - c.Q = Q; - c.m1 = m1; - c.m2 = m2; - c.norm = norm; - c.t = Deriv(norm.z(), norm.x(), norm.y()); - c.s = cross(norm, c.t); - c.s = c.s / c.s.norm(); - c.t = cross((-norm), c.s); - c.mu = mu; - c.contactId = id; - c.localId = localid; - c.contactDistance = contactDistance; -} - - -template -void UnilateralInteractionConstraint::buildConstraintMatrix(const core::ConstraintParams *, DataMatrixDeriv &c1_d, DataMatrixDeriv &c2_d, unsigned int &contactId - , const DataVecCoord &, const DataVecCoord &) -{ - assert(this->mstate1); - assert(this->mstate2); - - if (this->mstate1 == this->mstate2) - { - MatrixDeriv& c1 = *c1_d.beginEdit(); - - for (unsigned int i = 0; i < contacts.size(); i++) - { - Contact& c = contacts[i]; - - c.id = contactId++; - - MatrixDerivRowIterator c1_it = c1.writeLine(c.id); - - c1_it.addCol(c.m1, -c.norm); - c1_it.addCol(c.m2, c.norm); - - if (c.mu > 0.0) - { - c1_it = c1.writeLine(c.id + 1); - c1_it.setCol(c.m1, -c.t); - c1_it.setCol(c.m2, c.t); - - c1_it = c1.writeLine(c.id + 2); - c1_it.setCol(c.m1, -c.s); - c1_it.setCol(c.m2, c.s); - - contactId += 2; - } - } - - c1_d.endEdit(); - } - else - { - MatrixDeriv& c1 = *c1_d.beginEdit(); - MatrixDeriv& c2 = *c2_d.beginEdit(); - - for (unsigned int i = 0; i < contacts.size(); i++) - { - Contact& c = contacts[i]; - - c.id = contactId++; - - MatrixDerivRowIterator c1_it = c1.writeLine(c.id); - c1_it.addCol(c.m1, -c.norm); - - MatrixDerivRowIterator c2_it = c2.writeLine(c.id); - c2_it.addCol(c.m2, c.norm); - - if (c.mu > 0.0) - { - c1_it = c1.writeLine(c.id + 1); - c1_it.setCol(c.m1, -c.t); - - c1_it = c1.writeLine(c.id + 2); - c1_it.setCol(c.m1, -c.s); - - c2_it = c2.writeLine(c.id + 1); - c2_it.setCol(c.m2, c.t); - - c2_it = c2.writeLine(c.id + 2); - c2_it.setCol(c.m2, c.s); - - contactId += 2; - } - } - - c1_d.endEdit(); - c2_d.endEdit(); - } -} - - -template -void UnilateralInteractionConstraint::getPositionViolation(linearalgebra::BaseVector *v) -{ - const VecCoord &PfreeVec = this->getMState2()->read(core::ConstVecCoordId::freePosition())->getValue(); - const VecCoord &QfreeVec = this->getMState1()->read(core::ConstVecCoordId::freePosition())->getValue(); - - Real dfree = (Real)0.0; - Real dfree_t = (Real)0.0; - Real dfree_s = (Real)0.0; - - const unsigned int cSize = contacts.size(); - - for (unsigned int i = 0; i < cSize; i++) - { - const Contact& c = contacts[i]; - - // Compute dfree, dfree_t and d_free_s - - const Coord &Pfree = PfreeVec[c.m2]; - const Coord &Qfree = QfreeVec[c.m1]; - - const Coord PPfree = Pfree - c.P; - const Coord QQfree = Qfree - c.Q; - - const Real ref_dist = PPfree.norm() + QQfree.norm(); - - dfree = dot(Pfree - Qfree, c.norm) - c.contactDistance; - const Real delta = dot(c.P - c.Q, c.norm) - c.contactDistance; - - if ((helper::rabs(delta) < 0.00001 * ref_dist) && (helper::rabs(dfree) < 0.00001 * ref_dist)) - { - dfree_t = dot(PPfree, c.t) - dot(QQfree, c.t); - dfree_s = dot(PPfree, c.s) - dot(QQfree, c.s); - } - else if (helper::rabs(delta - dfree) > 0.001 * delta) - { - const Real dt = delta / (delta - dfree); - - if (dt > 0.0 && dt < 1.0) - { - const Coord Pt = c.P * (1 - dt) + Pfree * dt; - const Coord Qt = c.Q * (1 - dt) + Qfree * dt; - const Coord PtPfree = Pfree - Pt; - const Coord QtQfree = Qfree - Qt; - - dfree_t = dot(PtPfree, c.t) - dot(QtQfree, c.t); - dfree_s = dot(PtPfree, c.s) - dot(QtQfree, c.s); - } - else if (dfree < 0.0) - { - dfree_t = dot(PPfree, c.t) - dot(QQfree, c.t); - dfree_s = dot(PPfree, c.s) - dot(QQfree, c.s); - } - else - { - dfree_t = 0; - dfree_s = 0; - } - } - else - { - dfree_t = dot(PPfree, c.t) - dot(QQfree, c.t); - dfree_s = dot(PPfree, c.s) - dot(QQfree, c.s); - } - - // Sets dfree in global violation vector - - v->set(c.id, dfree); - - c.dfree = dfree; // PJ : For isActive() method. Don't know if it's still usefull. - - if (c.mu > 0.0) - { - v->set(c.id + 1, dfree_t); - v->set(c.id + 2, dfree_s); - } - } -} - - -template -void UnilateralInteractionConstraint::getVelocityViolation(linearalgebra::BaseVector *v) -{ - auto P = this->getMState2()->readPositions(); - auto Q = this->getMState1()->readPositions(); - - const SReal dt = this->getContext()->getDt(); - const SReal invDt = SReal(1.0) / dt; - - const VecDeriv &PvfreeVec = this->getMState2()->read(core::ConstVecDerivId::freeVelocity())->getValue(); - const VecDeriv &QvfreeVec = this->getMState1()->read(core::ConstVecDerivId::freeVelocity())->getValue(); - - const unsigned int cSize = contacts.size(); - - for (unsigned int i = 0; i < cSize; i++) - { - const Contact& c = contacts[i]; - - const Deriv QP_invDt = (P[c.m2] - Q[c.m1])*invDt; - const Deriv QP_vfree = PvfreeVec[c.m2] - QvfreeVec[c.m1]; - const Deriv dFreeVec = QP_vfree + QP_invDt; - - v->set(c.id, dot(dFreeVec, c.norm) - c.contactDistance*invDt ); // dvfree = 1/dt * [ dot ( P - Q, n) - contactDist ] + dot(v_P - v_Q , n ) ] - - if (c.mu > 0.0) - { - v->set(c.id + 1, dot(QP_vfree, c.t)); // dfree_t - v->set(c.id + 2, dot(QP_vfree, c.s)); // dfree_s - } - } -} - - -template -void UnilateralInteractionConstraint::getConstraintViolation(const core::ConstraintParams *cparams, linearalgebra::BaseVector *v, const DataVecCoord &, const DataVecCoord & - , const DataVecDeriv &, const DataVecDeriv &) -{ - switch (cparams->constOrder()) - { - case core::ConstraintOrder::POS_AND_VEL : - case core::ConstraintOrder::POS : - getPositionViolation(v); - break; - - case core::ConstraintOrder::ACC : - case core::ConstraintOrder::VEL : - getVelocityViolation(v); - break; - - default : - msg_error() << "UnilateralInteractionConstraint doesn't implement " << cparams->getName() << " constraint violation\n"; - break; - } -} - - -template -void UnilateralInteractionConstraint::getConstraintInfo(const core::ConstraintParams*, VecConstraintBlockInfo& blocks, VecPersistentID& ids, VecConstCoord& /*positions*/, VecConstDeriv& directions, VecConstArea& /*areas*/) -{ - if (contacts.empty()) return; - const bool friction = (contacts[0].mu > 0.0); /// @todo: can there be both friction-less and friction contacts in the same UnilateralInteractionConstraint ??? - ConstraintBlockInfo info; - info.parent = this; - info.const0 = contacts[0].id; - info.nbLines = friction ? 3 : 1; - info.hasId = true; - info.offsetId = ids.size(); - info.hasDirection = true; - info.offsetDirection = directions.size(); - info.nbGroups = contacts.size(); - - for (unsigned int i=0; i -void UnilateralInteractionConstraint::getConstraintResolution(const core::ConstraintParams *, std::vector& resTab, unsigned int& offset) -{ - if(contactsStatus) - { - delete[] contactsStatus; - contactsStatus = nullptr; - } - - if (contacts.size() > 0) - { - contactsStatus = new bool[contacts.size()]; - memset(contactsStatus, 0, sizeof(bool)*contacts.size()); - } - - for(unsigned int i=0; i 0.0) - { - UnilateralConstraintResolutionWithFriction* ucrwf = new UnilateralConstraintResolutionWithFriction(c.mu, nullptr, &contactsStatus[i]); - ucrwf->setTolerance(customTolerance); - resTab[offset] = ucrwf; - - // TODO : cette méthode de stockage des forces peu mal fonctionner avec 2 threads quand on utilise l'haptique - offset += 3; - } - else - resTab[offset++] = new UnilateralConstraintResolution(); - } -} - -template -bool UnilateralInteractionConstraint::isActive() const -{ - for(unsigned int i = 0; i < contacts.size(); i++) - if(contacts[i].dfree < 0) - return true; - - return false; -} - -template -void UnilateralInteractionConstraint::draw(const core::visual::VisualParams* vparams) -{ - if (!vparams->displayFlags().getShowInteractionForceFields()) return; - - const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); - vparams->drawTool()->disableLighting(); - - std::vector redVertices; - std::vector otherVertices; - std::vector otherColors; - - for (unsigned int i=0; idrawTool()->drawLines(otherVertices, 3, otherColors); - - - - -} - -} //namespace sofa::component::constraint::lagrangian::model +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/lagrangian/model/UnilateralLagrangianConstraint.inl") diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralInteractionConstraint.cpp b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralLagrangianConstraint.cpp similarity index 91% rename from Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralInteractionConstraint.cpp rename to Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralLagrangianConstraint.cpp index 731d7ff2372..911955ed2e5 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralInteractionConstraint.cpp +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralLagrangianConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_CONSTRAINTSET_UNILATERALINTERACTIONCONSTRAINT_CPP -#include +#define SOFA_COMPONENT_CONSTRAINTSET_UNILATERALLAGRANGIANCONSTRAINT_CPP +#include #include #include @@ -31,13 +31,13 @@ using namespace sofa::defaulttype; using namespace sofa::helper; //TODO(dmarchal) What does this TODO mean ? -int UnilateralInteractionConstraintClass = core::RegisterObject("TODO-UnilateralInteractionConstraint") - .add< UnilateralInteractionConstraint >() +int UnilateralLagrangianConstraintClass = core::RegisterObject("TODO-UnilateralLagrangianConstraint") + .add< UnilateralLagrangianConstraint >() ; -template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API UnilateralInteractionConstraint; +template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API UnilateralLagrangianConstraint; diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralLagrangianConstraint.h b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralLagrangianConstraint.h new file mode 100644 index 00000000000..f58a0ac1b72 --- /dev/null +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralLagrangianConstraint.h @@ -0,0 +1,158 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::lagrangian::model +{ + +template +class UnilateralLagrangianConstraint : public core::behavior::PairInteractionConstraint +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(UnilateralLagrangianConstraint,DataTypes), SOFA_TEMPLATE(core::behavior::PairInteractionConstraint,DataTypes)); + + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::MatrixDeriv::RowConstIterator MatrixDerivRowConstIterator; + typedef typename DataTypes::MatrixDeriv::ColConstIterator MatrixDerivColConstIterator; + typedef typename DataTypes::MatrixDeriv::RowIterator MatrixDerivRowIterator; + typedef typename DataTypes::MatrixDeriv::ColIterator MatrixDerivColIterator; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename Coord::value_type Real; + typedef typename core::behavior::MechanicalState MechanicalState; + + typedef core::behavior::BaseConstraint::ConstraintBlockInfo ConstraintBlockInfo; + typedef core::behavior::BaseConstraint::PersistentID PersistentID; + typedef core::behavior::BaseConstraint::ConstCoord ConstCoord; + + typedef core::behavior::BaseConstraint::VecConstraintBlockInfo VecConstraintBlockInfo; + typedef core::behavior::BaseConstraint::VecPersistentID VecPersistentID; + typedef core::behavior::BaseConstraint::VecConstCoord VecConstCoord; + typedef core::behavior::BaseConstraint::VecConstDeriv VecConstDeriv; + typedef core::behavior::BaseConstraint::VecConstArea VecConstArea; + + typedef core::objectmodel::Data DataVecCoord; + typedef core::objectmodel::Data DataVecDeriv; + typedef core::objectmodel::Data DataMatrixDeriv; + + typedef typename core::behavior::PairInteractionConstraint Inherit; + +protected: + + struct Contact + { + int m1, m2; ///< the two extremities of the spring: masses m1 and m2 + Deriv norm; ///< contact normal, from m1 to m2 + Deriv t; ///< added for friction + Deriv s; ///< added for friction + Real contactDistance; + + unsigned int id; + long contactId; + PersistentID localId; + SReal mu; ///< angle for friction + + Coord P, Q; + + mutable Real dfree; + }; + + sofa::type::vector contacts; + Real epsilon; + bool yetIntegrated; + SReal customTolerance; + + PreviousForcesContainer prevForces; + bool* contactsStatus; + + /// Computes constraint violation in position and stores it into resolution global vector + /// + /// @param v Global resolution vector + virtual void getPositionViolation(linearalgebra::BaseVector *v); + + ///Computes constraint violation in velocity and stores it into resolution global vector + /// + /// @param v Global resolution vector + virtual void getVelocityViolation(linearalgebra::BaseVector *v); + +public: + + unsigned int constraintId; +protected: + + virtual type::vector getUnilateralInteractionIdentifiers() {return {};} + + virtual type::vector getPairInteractionIdentifiers() override final + { + type::vector ids = getUnilateralInteractionIdentifiers(); + ids.push_back("Unilateral"); + return ids; + } + + + UnilateralLagrangianConstraint(MechanicalState* object1=nullptr, MechanicalState* object2=nullptr); + virtual ~UnilateralLagrangianConstraint(); + +public: + void setCustomTolerance(SReal tol) { customTolerance = tol; } + + void clear(int reserve = 0); + + virtual void addContact(SReal mu, Deriv norm, Coord P, Coord Q, Real contactDistance, int m1, int m2, Coord Pfree, Coord Qfree, long id=0, PersistentID localid=0); + + void addContact(SReal mu, Deriv norm, Coord P, Coord Q, Real contactDistance, int m1, int m2, long id=0, PersistentID localid=0); + void addContact(SReal mu, Deriv norm, Real contactDistance, int m1, int m2, long id=0, PersistentID localid=0); + + void buildConstraintMatrix(const core::ConstraintParams* cParams, DataMatrixDeriv &c1, DataMatrixDeriv &c2, unsigned int &cIndex + , const DataVecCoord &x1, const DataVecCoord &x2) override; + + void getConstraintViolation(const core::ConstraintParams* cParams, linearalgebra::BaseVector *v, const DataVecCoord &x1, const DataVecCoord &x2 + , const DataVecDeriv &v1, const DataVecDeriv &v2) override; + + + void getConstraintInfo(const core::ConstraintParams* cParams, VecConstraintBlockInfo& blocks, VecPersistentID& ids, VecConstCoord& positions, VecConstDeriv& directions, VecConstArea& areas) override; + + void getConstraintResolution(const core::ConstraintParams *,std::vector& resTab, unsigned int& offset) override; + bool isActive() const override; + + void draw(const core::visual::VisualParams* vparams) override; +}; + + +#if !defined(SOFA_COMPONENT_CONSTRAINTSET_UNILATERALLAGRANGIANCONSTRAINT_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API UnilateralLagrangianConstraint; +#endif + + +} //namespace sofa::component::constraint::lagrangian::model diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralLagrangianConstraint.inl b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralLagrangianConstraint.inl new file mode 100644 index 00000000000..ff7dbbe72c9 --- /dev/null +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralLagrangianConstraint.inl @@ -0,0 +1,421 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::lagrangian::model +{ + +template +UnilateralLagrangianConstraint::UnilateralLagrangianConstraint(MechanicalState* object1, MechanicalState* object2) + : Inherit(object1, object2) + , epsilon(Real(0.001)) + , yetIntegrated(false) + , customTolerance(0.0) + , contactsStatus(nullptr) +{ +} + +template +UnilateralLagrangianConstraint::~UnilateralLagrangianConstraint() +{ + if(contactsStatus) + delete[] contactsStatus; +} + +template +void UnilateralLagrangianConstraint::clear(int reserve) +{ + contacts.clear(); + if (reserve) + contacts.reserve(reserve); +} + +template +void UnilateralLagrangianConstraint::addContact(SReal mu, Deriv norm, Coord P, Coord Q, Real contactDistance, int m1, int m2, long id, PersistentID localid) +{ + addContact(mu, norm, P, Q, contactDistance, m1, m2, + this->getMState2()->read(core::ConstVecCoordId::freePosition())->getValue()[m2], + this->getMState1()->read(core::ConstVecCoordId::freePosition())->getValue()[m1], + id, localid); +} + +template +void UnilateralLagrangianConstraint::addContact(SReal mu, Deriv norm, Real contactDistance, int m1, int m2, long id, PersistentID localid) +{ + addContact(mu, norm, + this->getMState2()->read(core::ConstVecCoordId::position())->getValue()[m2], + this->getMState1()->read(core::ConstVecCoordId::position())->getValue()[m1], + contactDistance, m1, m2, + this->getMState2()->read(core::ConstVecCoordId::freePosition())->getValue()[m2], + this->getMState1()->read(core::ConstVecCoordId::freePosition())->getValue()[m1], + id, localid); +} + +template +void UnilateralLagrangianConstraint::addContact(SReal mu, Deriv norm, Coord P, Coord Q, Real contactDistance, int m1, int m2, Coord /*Pfree*/, Coord /*Qfree*/, long id, PersistentID localid) +{ + contacts.resize(contacts.size() + 1); + Contact &c = contacts.back(); + + c.P = P; + c.Q = Q; + c.m1 = m1; + c.m2 = m2; + c.norm = norm; + c.t = Deriv(norm.z(), norm.x(), norm.y()); + c.s = cross(norm, c.t); + c.s = c.s / c.s.norm(); + c.t = cross((-norm), c.s); + c.mu = mu; + c.contactId = id; + c.localId = localid; + c.contactDistance = contactDistance; +} + + +template +void UnilateralLagrangianConstraint::buildConstraintMatrix(const core::ConstraintParams *, DataMatrixDeriv &c1_d, DataMatrixDeriv &c2_d, unsigned int &contactId + , const DataVecCoord &, const DataVecCoord &) +{ + assert(this->mstate1); + assert(this->mstate2); + + if (this->mstate1 == this->mstate2) + { + MatrixDeriv& c1 = *c1_d.beginEdit(); + + for (unsigned int i = 0; i < contacts.size(); i++) + { + Contact& c = contacts[i]; + + c.id = contactId++; + + MatrixDerivRowIterator c1_it = c1.writeLine(c.id); + + c1_it.addCol(c.m1, -c.norm); + c1_it.addCol(c.m2, c.norm); + + if (c.mu > 0.0) + { + c1_it = c1.writeLine(c.id + 1); + c1_it.setCol(c.m1, -c.t); + c1_it.setCol(c.m2, c.t); + + c1_it = c1.writeLine(c.id + 2); + c1_it.setCol(c.m1, -c.s); + c1_it.setCol(c.m2, c.s); + + contactId += 2; + } + } + + c1_d.endEdit(); + } + else + { + MatrixDeriv& c1 = *c1_d.beginEdit(); + MatrixDeriv& c2 = *c2_d.beginEdit(); + + for (unsigned int i = 0; i < contacts.size(); i++) + { + Contact& c = contacts[i]; + + c.id = contactId++; + + MatrixDerivRowIterator c1_it = c1.writeLine(c.id); + c1_it.addCol(c.m1, -c.norm); + + MatrixDerivRowIterator c2_it = c2.writeLine(c.id); + c2_it.addCol(c.m2, c.norm); + + if (c.mu > 0.0) + { + c1_it = c1.writeLine(c.id + 1); + c1_it.setCol(c.m1, -c.t); + + c1_it = c1.writeLine(c.id + 2); + c1_it.setCol(c.m1, -c.s); + + c2_it = c2.writeLine(c.id + 1); + c2_it.setCol(c.m2, c.t); + + c2_it = c2.writeLine(c.id + 2); + c2_it.setCol(c.m2, c.s); + + contactId += 2; + } + } + + c1_d.endEdit(); + c2_d.endEdit(); + } +} + + +template +void UnilateralLagrangianConstraint::getPositionViolation(linearalgebra::BaseVector *v) +{ + const VecCoord &PfreeVec = this->getMState2()->read(core::ConstVecCoordId::freePosition())->getValue(); + const VecCoord &QfreeVec = this->getMState1()->read(core::ConstVecCoordId::freePosition())->getValue(); + + Real dfree = (Real)0.0; + Real dfree_t = (Real)0.0; + Real dfree_s = (Real)0.0; + + const unsigned int cSize = contacts.size(); + + for (unsigned int i = 0; i < cSize; i++) + { + const Contact& c = contacts[i]; + + // Compute dfree, dfree_t and d_free_s + + const Coord &Pfree = PfreeVec[c.m2]; + const Coord &Qfree = QfreeVec[c.m1]; + + const Coord PPfree = Pfree - c.P; + const Coord QQfree = Qfree - c.Q; + + const Real ref_dist = PPfree.norm() + QQfree.norm(); + + dfree = dot(Pfree - Qfree, c.norm) - c.contactDistance; + const Real delta = dot(c.P - c.Q, c.norm) - c.contactDistance; + + if ((helper::rabs(delta) < 0.00001 * ref_dist) && (helper::rabs(dfree) < 0.00001 * ref_dist)) + { + dfree_t = dot(PPfree, c.t) - dot(QQfree, c.t); + dfree_s = dot(PPfree, c.s) - dot(QQfree, c.s); + } + else if (helper::rabs(delta - dfree) > 0.001 * delta) + { + const Real dt = delta / (delta - dfree); + + if (dt > 0.0 && dt < 1.0) + { + const Coord Pt = c.P * (1 - dt) + Pfree * dt; + const Coord Qt = c.Q * (1 - dt) + Qfree * dt; + const Coord PtPfree = Pfree - Pt; + const Coord QtQfree = Qfree - Qt; + + dfree_t = dot(PtPfree, c.t) - dot(QtQfree, c.t); + dfree_s = dot(PtPfree, c.s) - dot(QtQfree, c.s); + } + else if (dfree < 0.0) + { + dfree_t = dot(PPfree, c.t) - dot(QQfree, c.t); + dfree_s = dot(PPfree, c.s) - dot(QQfree, c.s); + } + else + { + dfree_t = 0; + dfree_s = 0; + } + } + else + { + dfree_t = dot(PPfree, c.t) - dot(QQfree, c.t); + dfree_s = dot(PPfree, c.s) - dot(QQfree, c.s); + } + + // Sets dfree in global violation vector + + v->set(c.id, dfree); + + c.dfree = dfree; // PJ : For isActive() method. Don't know if it's still usefull. + + if (c.mu > 0.0) + { + v->set(c.id + 1, dfree_t); + v->set(c.id + 2, dfree_s); + } + } +} + + +template +void UnilateralLagrangianConstraint::getVelocityViolation(linearalgebra::BaseVector *v) +{ + auto P = this->getMState2()->readPositions(); + auto Q = this->getMState1()->readPositions(); + + const SReal dt = this->getContext()->getDt(); + const SReal invDt = SReal(1.0) / dt; + + const VecDeriv &PvfreeVec = this->getMState2()->read(core::ConstVecDerivId::freeVelocity())->getValue(); + const VecDeriv &QvfreeVec = this->getMState1()->read(core::ConstVecDerivId::freeVelocity())->getValue(); + + const unsigned int cSize = contacts.size(); + + for (unsigned int i = 0; i < cSize; i++) + { + const Contact& c = contacts[i]; + + const Deriv QP_invDt = (P[c.m2] - Q[c.m1])*invDt; + const Deriv QP_vfree = PvfreeVec[c.m2] - QvfreeVec[c.m1]; + const Deriv dFreeVec = QP_vfree + QP_invDt; + + v->set(c.id, dot(dFreeVec, c.norm) - c.contactDistance*invDt ); // dvfree = 1/dt * [ dot ( P - Q, n) - contactDist ] + dot(v_P - v_Q , n ) ] + + if (c.mu > 0.0) + { + v->set(c.id + 1, dot(QP_vfree, c.t)); // dfree_t + v->set(c.id + 2, dot(QP_vfree, c.s)); // dfree_s + } + } +} + + +template +void UnilateralLagrangianConstraint::getConstraintViolation(const core::ConstraintParams *cparams, linearalgebra::BaseVector *v, const DataVecCoord &, const DataVecCoord & + , const DataVecDeriv &, const DataVecDeriv &) +{ + switch (cparams->constOrder()) + { + case core::ConstraintOrder::POS_AND_VEL : + case core::ConstraintOrder::POS : + getPositionViolation(v); + break; + + case core::ConstraintOrder::ACC : + case core::ConstraintOrder::VEL : + getVelocityViolation(v); + break; + + default : + msg_error() << "UnilateralLagrangianConstraint doesn't implement " << cparams->getName() << " constraint violation\n"; + break; + } +} + + +template +void UnilateralLagrangianConstraint::getConstraintInfo(const core::ConstraintParams*, VecConstraintBlockInfo& blocks, VecPersistentID& ids, VecConstCoord& /*positions*/, VecConstDeriv& directions, VecConstArea& /*areas*/) +{ + if (contacts.empty()) return; + const bool friction = (contacts[0].mu > 0.0); /// @todo: can there be both friction-less and friction contacts in the same UnilateralLagrangianConstraint ??? + ConstraintBlockInfo info; + info.parent = this; + info.const0 = contacts[0].id; + info.nbLines = friction ? 3 : 1; + info.hasId = true; + info.offsetId = ids.size(); + info.hasDirection = true; + info.offsetDirection = directions.size(); + info.nbGroups = contacts.size(); + + for (unsigned int i=0; i +void UnilateralLagrangianConstraint::getConstraintResolution(const core::ConstraintParams *, std::vector& resTab, unsigned int& offset) +{ + if(contactsStatus) + { + delete[] contactsStatus; + contactsStatus = nullptr; + } + + if (contacts.size() > 0) + { + contactsStatus = new bool[contacts.size()]; + memset(contactsStatus, 0, sizeof(bool)*contacts.size()); + } + + for(unsigned int i=0; i 0.0) + { + UnilateralConstraintResolutionWithFriction* ucrwf = new UnilateralConstraintResolutionWithFriction(c.mu, nullptr, &contactsStatus[i]); + ucrwf->setTolerance(customTolerance); + resTab[offset] = ucrwf; + + // TODO : cette méthode de stockage des forces peu mal fonctionner avec 2 threads quand on utilise l'haptique + offset += 3; + } + else + resTab[offset++] = new UnilateralConstraintResolution(); + } +} + +template +bool UnilateralLagrangianConstraint::isActive() const +{ + for(unsigned int i = 0; i < contacts.size(); i++) + if(contacts[i].dfree < 0) + return true; + + return false; +} + +template +void UnilateralLagrangianConstraint::draw(const core::visual::VisualParams* vparams) +{ + if (!vparams->displayFlags().getShowInteractionForceFields()) return; + + const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); + vparams->drawTool()->disableLighting(); + + std::vector redVertices; + std::vector otherVertices; + std::vector otherColors; + + for (unsigned int i=0; idrawTool()->drawLines(otherVertices, 3, otherColors); + + + + +} + +} //namespace sofa::component::constraint::lagrangian::model diff --git a/Sofa/Component/Constraint/Lagrangian/Model/tests/BilateralInteractionConstraint_test.cpp b/Sofa/Component/Constraint/Lagrangian/Model/tests/BilateralInteractionLagrangianConstraint_test.cpp similarity index 85% rename from Sofa/Component/Constraint/Lagrangian/Model/tests/BilateralInteractionConstraint_test.cpp rename to Sofa/Component/Constraint/Lagrangian/Model/tests/BilateralInteractionLagrangianConstraint_test.cpp index 49925d5a621..a00f9d760d1 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/tests/BilateralInteractionConstraint_test.cpp +++ b/Sofa/Component/Constraint/Lagrangian/Model/tests/BilateralInteractionLagrangianConstraint_test.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include using sofa::core::execparams::defaultInstance; @@ -50,7 +50,7 @@ using namespace component; using namespace defaulttype; template -struct BilateralInteractionConstraint_test : public NumericTest<> +struct BilateralInteractionLangrangianConstraint_test : public NumericTest<> { typedef _DataTypes DataTypes; typedef typename DataTypes::VecCoord VecCoord; @@ -59,7 +59,7 @@ struct BilateralInteractionConstraint_test : public NumericTest<> typedef typename DataTypes::Deriv Deriv; typedef typename DataTypes::CPos CPos; typedef typename Coord::value_type Real; - typedef constraintset::BilateralInteractionConstraint BilateralInteractionConstraint; + typedef constraintset::BilateralInteractionLangrangianConstraint BilateralInteractionLangrangianConstraint; typedef component::topology::PointSetTopologyContainer PointSetTopologyContainer; typedef container::MechanicalObject MechanicalObject; @@ -103,7 +103,7 @@ struct BilateralInteractionConstraint_test : public NumericTest<> " \n" " \n" " \n" - " \n" + " \n" " \n" ; Node::SPtr root = SceneLoaderXML::loadFromMemory ("testscene", @@ -111,7 +111,7 @@ struct BilateralInteractionConstraint_test : public NumericTest<> scene.str().size()) ; root->init(sofa::core::execparams::defaultInstance()) ; - BilateralInteractionConstraint* constraint = root->getTreeObject() ; + BilateralInteractionLangrangianConstraint* constraint = root->getTreeObject() ; EXPECT_TRUE( constraint != nullptr ) ; EXPECT_TRUE( constraint->findData("first_point") != nullptr ) ; @@ -135,7 +135,7 @@ struct BilateralInteractionConstraint_test : public NumericTest<> std::stringstream scene; scene << " \n" " \n" - " \n" + " \n" " \n" ; Node::SPtr root = SceneLoaderXML::loadFromMemory ("testscene", @@ -150,7 +150,7 @@ struct BilateralInteractionConstraint_test : public NumericTest<> }; template<> -void BilateralInteractionConstraint_test::checkRigid3fFixForBackwardCompatibility(){ +void BilateralInteractionLangrangianConstraint_test::checkRigid3fFixForBackwardCompatibility(){ EXPECT_MSG_EMIT(Warning) ; /// I'm using '\n' so that the XML parser correctly report the line number @@ -160,7 +160,7 @@ void BilateralInteractionConstraint_test::checkRigid3fFixForBackwa " \n" " \n" " \n" - " \n" + " \n" " \n" ; Node::SPtr root = SceneLoaderXML::loadFromMemory ("testscene", @@ -172,12 +172,12 @@ void BilateralInteractionConstraint_test::checkRigid3fFixForBackwa template<> -void BilateralInteractionConstraint_test::init_Vec3Setup() +void BilateralInteractionLangrangianConstraint_test::init_Vec3Setup() { /// Load the scene //TODO(dmarchal): This general load should be updated... there is no reason to load // a scene independently of the data template to use. - std::string sceneName = "BilateralInteractionConstraint.scn"; + std::string sceneName = "BilateralInteractionLangrangianConstraint.scn"; std::string fileName = std::string(SOFATEST_SCENES_DIR) + "/" + sceneName; root = sofa::simulation::getSimulation()->load(fileName.c_str()).get(); @@ -199,7 +199,7 @@ void BilateralInteractionConstraint_test::init_Vec3Setup() } template<> -bool BilateralInteractionConstraint_test::test_Vec3ConstrainedPositions() +bool BilateralInteractionLangrangianConstraint_test::test_Vec3ConstrainedPositions() { std::vector meca; root->get(&meca,std::string("mecaConstraint"),root->SearchDown); @@ -240,27 +240,27 @@ typedef Types DataTypes; // the types to instanciate. // Test suite for all the instanciations -TYPED_TEST_SUITE(BilateralInteractionConstraint_test, DataTypes); +TYPED_TEST_SUITE(BilateralInteractionLangrangianConstraint_test, DataTypes); //TODO(dmarchal): Needs a serious refactor !!! -TYPED_TEST( BilateralInteractionConstraint_test , checkVec3ConstrainedPositions ) +TYPED_TEST( BilateralInteractionLangrangianConstraint_test , checkVec3ConstrainedPositions ) { this->init_Vec3Setup(); ASSERT_TRUE( this->test_Vec3ConstrainedPositions() ); } -TYPED_TEST( BilateralInteractionConstraint_test , attributesTests ) +TYPED_TEST( BilateralInteractionLangrangianConstraint_test , attributesTests ) { ASSERT_NO_THROW( this->attributesTests() ); } -TYPED_TEST( BilateralInteractionConstraint_test , checkMstateRequiredAssumption ) +TYPED_TEST( BilateralInteractionLangrangianConstraint_test , checkMstateRequiredAssumption ) { ASSERT_NO_THROW( this->checkMstateRequiredAssumption() ); } -TYPED_TEST( BilateralInteractionConstraint_test , checkRigid3fFixForBackwardCompatibility) +TYPED_TEST( BilateralInteractionLangrangianConstraint_test , checkRigid3fFixForBackwardCompatibility) { ASSERT_NO_THROW( this->checkRigid3fFixForBackwardCompatibility() ); } diff --git a/Sofa/Component/Constraint/Lagrangian/Model/tests/scenes_test/BilateralInteractionConstraint.scn b/Sofa/Component/Constraint/Lagrangian/Model/tests/scenes_test/BilateralInteractionConstraint.scn index 6bcda80a448..b447ce22419 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/tests/scenes_test/BilateralInteractionConstraint.scn +++ b/Sofa/Component/Constraint/Lagrangian/Model/tests/scenes_test/BilateralInteractionConstraint.scn @@ -1,4 +1,4 @@ - + @@ -33,5 +33,5 @@
- +
diff --git a/Sofa/Component/Constraint/Projective/CMakeLists.txt b/Sofa/Component/Constraint/Projective/CMakeLists.txt index fcb8797553f..a6f2a49cda8 100644 --- a/Sofa/Component/Constraint/Projective/CMakeLists.txt +++ b/Sofa/Component/Constraint/Projective/CMakeLists.txt @@ -45,30 +45,72 @@ set(HEADER_FILES ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/ProjectToPointConstraint.inl ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/ProjectDirectionConstraint.h ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/ProjectDirectionConstraint.inl + + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/AffineMovementProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/AffineMovementProjectiveConstraint.inl + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/AttachProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/AttachProjectiveConstraint.inl + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/FixedProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/FixedProjectiveConstraint.inl + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/FixedPlaneProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/FixedPlaneProjectiveConstraint.inl + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/FixedRotationProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/FixedRotationProjectiveConstraint.inl + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/FixedTranslationProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/FixedTranslationProjectiveConstraint.inl + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/HermiteSplineProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/HermiteSplineProjectiveConstraint.inl + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/LinearMovementProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/LinearMovementProjectiveConstraint.inl + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/LinearVelocityProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/LinearVelocityProjectiveConstraint.inl + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/OscillatorProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/OscillatorProjectiveConstraint.inl + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/ParabolicProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/ParabolicProjectiveConstraint.inl + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PartialFixedProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PartialFixedProjectiveConstraint.inl + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PartialLinearMovementProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PartialLinearMovementProjectiveConstraint.inl + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PatchTestMovementProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PatchTestMovementProjectiveConstraint.inl + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PositionBasedDynamicsProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PositionBasedDynamicsProjectiveConstraint.inl + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/SkeletalMotionProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/SkeletalMotionProjectiveConstraint.inl + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/LineProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/LineProjectiveConstraint.inl + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PlaneProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PlaneProjectiveConstraint.inl + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PointProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PointProjectiveConstraint.inl + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/DirectionProjectiveConstraint.h + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/DirectionProjectiveConstraint.inl + ) set(SOURCE_FILES ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/init.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/AffineMovementConstraint.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/AttachConstraint.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/FixedConstraint.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/FixedPlaneConstraint.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/FixedRotationConstraint.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/FixedTranslationConstraint.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/HermiteSplineConstraint.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/LinearMovementConstraint.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/LinearVelocityConstraint.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/OscillatorConstraint.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/ParabolicConstraint.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PartialFixedConstraint.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PartialLinearMovementConstraint.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PatchTestMovementConstraint.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PositionBasedDynamicsConstraint.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/SkeletalMotionConstraint.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/ProjectToLineConstraint.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/ProjectToPlaneConstraint.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/ProjectToPointConstraint.cpp - ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/ProjectDirectionConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/AffineMovementProjectiveConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/AttachProjectiveConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/FixedProjectiveConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/FixedPlaneProjectiveConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/FixedRotationProjectiveConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/FixedTranslationProjectiveConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/HermiteSplineProjectiveConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/LinearMovementProjectiveConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/LinearVelocityProjectiveConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/OscillatorProjectiveConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/ParabolicProjectiveConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PartialFixedProjectiveConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PartialLinearMovementProjectiveConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PatchTestMovementProjectiveConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PositionBasedDynamicsProjectiveConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/SkeletalMotionProjectiveConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/LineProjectiveConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PlaneProjectiveConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/PointProjectiveConstraint.cpp + ${SOFACOMPONENTCONSTRAINTPROJECTIVE_SOURCE_DIR}/DirectionProjectiveConstraint.cpp ) sofa_find_package(Sofa.Simulation.Core REQUIRED) diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementConstraint.h index 74f2cae555c..d17e1e9364d 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementConstraint.h @@ -20,146 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -template -class AffineMovementConstraintInternalData -{ -}; +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/AffineMovementConstraint.h") -/** - Impose a motion to all the boundary points of a mesh. The motion of the 4 corners are given in the data m_cornerMovements and the movements of the edge points are computed by linear interpolation. -*/ -template -class AffineMovementConstraint : public core::behavior::ProjectiveConstraintSet +namespace sofa::component::constraint::projective { -public: - SOFA_CLASS(SOFA_TEMPLATE(AffineMovementConstraint,TDataTypes), - SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, TDataTypes)); - - using Index = sofa::Index; - typedef TDataTypes DataTypes; - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::CPos CPos; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::Real Real; - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef type::vector SetIndexArray; - typedef sofa::core::topology::TopologySubsetIndices SetIndex; - typedef type::Quat Quat; - typedef type::Vec3 Vec3; - - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef core::objectmodel::Data DataMatrixDeriv; - - static const auto CoordSize = Coord::total_size; - typedef type::Mat<3,3,Real> RotationMatrix; - -protected: - AffineMovementConstraintInternalData *data; - friend class AffineMovementConstraintInternalData; - -public : - /// indices of the DOFs of the mesh - SetIndex m_meshIndices; - /// indices of the DOFs the constraint is applied to - SetIndex m_indices; - /// data begin time when the constraint is applied - Data m_beginConstraintTime; - /// data end time when the constraint is applied - Data m_endConstraintTime; - /// Rotation Matrix of affine transformation - Data m_rotation; - /// Quaternion of affine transformation (for rigid) - Data m_quaternion; - /// Translation Matrix of affine transformation - Data m_translation; - /// Draw constrained points - Data m_drawConstrainedPoints; - /// initial constrained DOFs position - VecCoord x0; - /// final constrained DOFs position - VecCoord xf; - /// initial mesh DOFs position - VecCoord meshPointsX0; - /// final mesh DOFs position - VecCoord meshPointsXf; - - /// Link to be set to the topology container in the component graph. - SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; - -protected: - AffineMovementConstraint(); - - virtual ~AffineMovementConstraint(); - -public: - //Add or clear constraints - void clearConstraints(); - void addConstraint(Index index); - void removeConstraint(Index index); - - /// -- Constraint interface - void init() override; - - /// Cancel the possible forces - void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; - /// Cancel the possible velocities - void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; - /// Apply the computed movements to the border mesh points between beginConstraintTime and endConstraintTime - void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; - - void projectJacobianMatrix(const core::MechanicalParams* /*mparams*/, DataMatrixDeriv& /* cData */) override - { - msg_error() << "projectJacobianMatrix not implemented"; - } - - /// Compute the theoretical final positions - void getFinalPositions (VecCoord& finalPos, DataVecCoord& xData); - - // Implement projectMatrix for assembled solver of compliant - void projectMatrix( sofa::linearalgebra::BaseMatrix* /*M*/, unsigned /*offset*/ ) override; - - /// Draw the constrained points (= border mesh points) - void draw(const core::visual::VisualParams* vparams) override; - -protected: - - void projectResponseImpl(VecDeriv& dx); - -private: - - /// Initialize initial positions - void initializeInitialPositions (const SetIndexArray & indices, DataVecCoord& xData, VecCoord& x0); - - /// Initialize final positions - void initializeFinalPositions (const SetIndexArray & indices, DataVecCoord& xData, VecCoord& x0 , VecCoord& xf); - - /// Apply affine transform - void transform(const SetIndexArray & indices, VecCoord& x0 , VecCoord& xf); -}; - -#if !defined(SOFABOUNDARYCONDITION_AFFINEMOVEMENTCONSTRAINT_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AffineMovementConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AffineMovementConstraint; -#endif //SOFABOUNDARYCONDITION_AFFINEMOVEMENTCONSTRAINT_CPP - -} // namespace sofa::component::constraint::projective +template +using AffineMovementConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "AffineMovementConstraint has been renamed to AffineMovementProjectiveConstraint") = AffineMovementProjectiveConstraint; +} diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementConstraint.inl index b6434701c86..5230ec8026b 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementConstraint.inl @@ -21,290 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include +#include -#include - -namespace sofa::component::constraint::projective -{ - -template -AffineMovementConstraint::AffineMovementConstraint() - : core::behavior::ProjectiveConstraintSet(nullptr) - , data(new AffineMovementConstraintInternalData) - , m_meshIndices( initData(&m_meshIndices,"meshIndices","Indices of the mesh") ) - , m_indices( initData(&m_indices,"indices","Indices of the constrained points") ) - , m_beginConstraintTime( initData(&m_beginConstraintTime,"beginConstraintTime","Begin time of the bilinear constraint") ) - , m_endConstraintTime( initData(&m_endConstraintTime,"endConstraintTime","End time of the bilinear constraint") ) - , m_rotation( initData(&m_rotation,"rotation","rotation applied to border points") ) - , m_quaternion( initData(&m_quaternion,"quaternion","quaternion applied to border points") ) - , m_translation( initData(&m_translation,"translation","translation applied to border points") ) - , m_drawConstrainedPoints( initData(&m_drawConstrainedPoints,"drawConstrainedPoints","draw constrained points") ) - , l_topology(initLink("topology", "link to the topology container")) -{ - if(!m_beginConstraintTime.isSet()) - m_beginConstraintTime = 0; - if(!m_endConstraintTime.isSet()) - m_endConstraintTime = 20; -} - - - -template -AffineMovementConstraint::~AffineMovementConstraint() -{ - -} - -template -void AffineMovementConstraint::clearConstraints() -{ - m_indices.beginEdit()->clear(); - m_indices.endEdit(); -} - -template -void AffineMovementConstraint::addConstraint(Index index) -{ - m_indices.beginEdit()->push_back(index); - m_indices.endEdit(); -} - -template -void AffineMovementConstraint::removeConstraint(Index index) -{ - removeValue(*m_indices.beginEdit(),index); - m_indices.endEdit(); -} - -// -- Constraint interface - - -template -void AffineMovementConstraint::init() -{ - this->core::behavior::ProjectiveConstraintSet::init(); - - if (l_topology.empty()) - { - msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; - l_topology.set(this->getContext()->getMeshTopologyLink()); - } - - if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) - { - msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; - - // Initialize topological changes support - m_indices.createTopologyHandler(_topology); - } - else - { - msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; - } - - const SetIndexArray & indices = m_indices.getValue(); - - auto maxIndex=this->mstate->getSize(); - for (Size i=0; i= maxIndex) - { - msg_error() << "Index " << index << " not valid!"; - removeConstraint(index); - } - } - -} - -template -void AffineMovementConstraint::projectResponseImpl(VecDeriv& dx) -{ - const SetIndexArray & indices = m_indices.getValue(); - for (size_t i = 0; i< indices.size(); ++i) - { - dx[indices[i]]=Deriv(); - } -} - -template -void AffineMovementConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) -{ - SOFA_UNUSED(mparams); - helper::WriteAccessor res = resData; - projectResponseImpl(res.wref()); -} - - - -template -void AffineMovementConstraint::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) -{ - SOFA_UNUSED(mparams); - helper::WriteAccessor res = vData; - projectResponseImpl(res.wref()); -} - -template -void AffineMovementConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) -{ - helper::WriteAccessor x = xData; - const SetIndexArray & indices = m_indices.getValue(); - - // Time - SReal beginTime = m_beginConstraintTime.getValue(); - SReal endTime = m_endConstraintTime.getValue(); - SReal totalTime = endTime - beginTime; - - //initialize initial mesh Dofs positions, if it's not done - if(meshPointsX0.size()==0) - this->initializeInitialPositions(m_meshIndices.getValue(),xData,meshPointsX0); - - //initialize final mesh Dofs positions, if it's not done - if(meshPointsXf.size()==0) - this->initializeFinalPositions(m_meshIndices.getValue(),xData, meshPointsX0, meshPointsXf); - - //initialize initial constrained Dofs positions, if it's not done - if(x0.size() == 0) - this->initializeInitialPositions(indices,xData,x0); - - //initialize final constrained Dofs positions, if it's not done - if (xf.size() == 0) - this->initializeFinalPositions(indices,xData,x0,xf); - // Update the intermediate Dofs positions computed by linear interpolation - SReal time = sofa::core::objectmodel::basecontext::getTime(this->getContext()->getRootContext()); - if( time > beginTime && time <= endTime && totalTime > 0) - { - for (auto index : indices) - { - DataTypes::setCPos( x[index], - ((DataTypes::getCPos(xf[index])-DataTypes::getCPos(x0[index]))*time + - (DataTypes::getCPos(x0[index])*endTime - DataTypes::getCPos(xf[index])*beginTime))/totalTime); - } - } - else if (time > endTime) - { - for (auto index : indices) - { - x[index] = xf[index]; - } - } -} - -template -void AffineMovementConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned /*offset*/ ) -{ - // clears the rows and columns associated with constrained particles - const unsigned blockSize = DataTypes::deriv_total_size; - - for (const auto id : m_indices.getValue()) - { - M->clearRowsCols( id * blockSize, (id+1) * blockSize ); - } -} - -template -void AffineMovementConstraint::getFinalPositions( VecCoord& finalPos,DataVecCoord& xData) -{ - // Indices of mesh points - const SetIndexArray & meshIndices = m_meshIndices.getValue(); - - // Initialize final positions - if(meshPointsXf.size()==0) - {this->initializeFinalPositions(meshIndices,xData,meshPointsX0,meshPointsXf);} - - // Set final positions - finalPos.resize(meshIndices.size()); - for (size_t i=0; i < meshIndices.size() ; ++i) - { - finalPos[meshIndices[i]] = meshPointsXf[meshIndices[i]]; - } -} - -template -void AffineMovementConstraint::initializeInitialPositions (const SetIndexArray & indices, DataVecCoord& xData, VecCoord& x0) -{ - helper::WriteAccessor x = xData; - - x0.resize(x.size()); - for (size_t i=0; i < indices.size() ; ++i) - { - x0[indices[i]] = x[indices[i]]; - } -} - - -template <> -void AffineMovementConstraint::transform(const SetIndexArray & indices, - defaulttype::Rigid3Types::VecCoord& x0, - defaulttype::Rigid3Types::VecCoord& xf) -{ - // Get quaternion and translation values - RotationMatrix rotationMat(0); - const Quat quat = m_quaternion.getValue(); - quat.toMatrix(rotationMat); - const Vec3 translation = m_translation.getValue(); - - // Apply transformation - for (size_t i=0; i < indices.size() ; ++i) - { - // Translation - xf[indices[i]].getCenter() = rotationMat*(x0[indices[i]].getCenter()) + translation; - // Rotation - xf[indices[i]].getOrientation() = (quat)+x0[indices[i]].getOrientation(); - } -} - -template -void AffineMovementConstraint::transform(const SetIndexArray & indices, VecCoord& x0, VecCoord& xf) -{ - Vec3 translation = m_translation.getValue(); - - for (size_t i=0; i < indices.size() ; ++i) - { - DataTypes::setCPos(xf[indices[i]], (m_rotation.getValue())*DataTypes::getCPos(x0[indices[i]]) + translation); - } -} - - -template -void AffineMovementConstraint::initializeFinalPositions (const SetIndexArray & indices, DataVecCoord& xData, VecCoord& x0, VecCoord& xf) -{ - helper::WriteAccessor x = xData; - - xf.resize(x.size()); - - // if the positions were not initialized - if(x0.size() == 0) - this->initializeInitialPositions(indices,xData,x0); - - transform(indices,x0,xf); -} - -template -void AffineMovementConstraint::draw(const core::visual::VisualParams* vparams) -{ - const SetIndexArray & indices = m_indices.getValue(); - const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); - Vec3 point; - - if(m_drawConstrainedPoints.getValue()) - { - std::vector< Vec3 > points; - for( auto& index : indices ) - { - point = DataTypes::getCPos(x[index]); - points.push_back(point); - } - constexpr sofa::type::RGBAColor color(1,0.5,0.5,1); - vparams->drawTool()->drawPoints(points, 10, color); - } -} - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/AffineMovementConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementProjectiveConstraint.cpp similarity index 79% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementProjectiveConstraint.cpp index 433bad30dff..a34416970dc 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementProjectiveConstraint.cpp @@ -19,24 +19,24 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFABOUNDARYCONDITION_AFFINEMOVEMENTCONSTRAINT_CPP +#define SOFABOUNDARYCONDITION_AFFINEMOVEMENTPROJECTIVECONSTRAINT_CPP #include #include #include #include -#include +#include namespace sofa::component::constraint::projective { -int AffineMovementConstraintRegister = core::RegisterObject("Constraint the movement by a rigid transform.") - .add< AffineMovementConstraint >() - .add< AffineMovementConstraint >() +int AffineMovementProjectiveConstraintRegister = core::RegisterObject("Constraint the movement by a rigid transform.") + .add< AffineMovementProjectiveConstraint >() + .add< AffineMovementProjectiveConstraint >() ; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AffineMovementConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AffineMovementConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AffineMovementProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AffineMovementProjectiveConstraint; } // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementProjectiveConstraint.h new file mode 100644 index 00000000000..74ca2823e84 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementProjectiveConstraint.h @@ -0,0 +1,165 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +template +class AffineMovementProjectiveConstraintInternalData +{ +}; + +/** + Impose a motion to all the boundary points of a mesh. The motion of the 4 corners are given in the data m_cornerMovements and the movements of the edge points are computed by linear interpolation. +*/ +template +class AffineMovementProjectiveConstraint : public core::behavior::ProjectiveConstraintSet +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(AffineMovementProjectiveConstraint,TDataTypes), + SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, TDataTypes)); + + using Index = sofa::Index; + typedef TDataTypes DataTypes; + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::CPos CPos; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::Real Real; + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef type::vector SetIndexArray; + typedef sofa::core::topology::TopologySubsetIndices SetIndex; + typedef type::Quat Quat; + typedef type::Vec3 Vec3; + + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef core::objectmodel::Data DataMatrixDeriv; + + static const auto CoordSize = Coord::total_size; + typedef type::Mat<3,3,Real> RotationMatrix; + +protected: + AffineMovementProjectiveConstraintInternalData *data; + friend class AffineMovementProjectiveConstraintInternalData; + +public : + /// indices of the DOFs of the mesh + SetIndex m_meshIndices; + /// indices of the DOFs the constraint is applied to + SetIndex m_indices; + /// data begin time when the constraint is applied + Data m_beginConstraintTime; + /// data end time when the constraint is applied + Data m_endConstraintTime; + /// Rotation Matrix of affine transformation + Data m_rotation; + /// Quaternion of affine transformation (for rigid) + Data m_quaternion; + /// Translation Matrix of affine transformation + Data m_translation; + /// Draw constrained points + Data m_drawConstrainedPoints; + /// initial constrained DOFs position + VecCoord x0; + /// final constrained DOFs position + VecCoord xf; + /// initial mesh DOFs position + VecCoord meshPointsX0; + /// final mesh DOFs position + VecCoord meshPointsXf; + + /// Link to be set to the topology container in the component graph. + SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; + +protected: + AffineMovementProjectiveConstraint(); + + virtual ~AffineMovementProjectiveConstraint(); + +public: + //Add or clear constraints + void clearConstraints(); + void addConstraint(Index index); + void removeConstraint(Index index); + + /// -- Constraint interface + void init() override; + + /// Cancel the possible forces + void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; + /// Cancel the possible velocities + void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; + /// Apply the computed movements to the border mesh points between beginConstraintTime and endConstraintTime + void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; + + void projectJacobianMatrix(const core::MechanicalParams* /*mparams*/, DataMatrixDeriv& /* cData */) override + { + msg_error() << "projectJacobianMatrix not implemented"; + } + + /// Compute the theoretical final positions + void getFinalPositions (VecCoord& finalPos, DataVecCoord& xData); + + // Implement projectMatrix for assembled solver of compliant + void projectMatrix( sofa::linearalgebra::BaseMatrix* /*M*/, unsigned /*offset*/ ) override; + + /// Draw the constrained points (= border mesh points) + void draw(const core::visual::VisualParams* vparams) override; + +protected: + + void projectResponseImpl(VecDeriv& dx); + +private: + + /// Initialize initial positions + void initializeInitialPositions (const SetIndexArray & indices, DataVecCoord& xData, VecCoord& x0); + + /// Initialize final positions + void initializeFinalPositions (const SetIndexArray & indices, DataVecCoord& xData, VecCoord& x0 , VecCoord& xf); + + /// Apply affine transform + void transform(const SetIndexArray & indices, VecCoord& x0 , VecCoord& xf); +}; + +#if !defined(SOFABOUNDARYCONDITION_AFFINEMOVEMENTPROJECTIVECONSTRAINT_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AffineMovementProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AffineMovementProjectiveConstraint; +#endif //SOFABOUNDARYCONDITION_AFFINEMOVEMENTPROJECTIVECONSTRAINT_CPP + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementProjectiveConstraint.inl new file mode 100644 index 00000000000..ee7a56d83ac --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementProjectiveConstraint.inl @@ -0,0 +1,310 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include + +namespace sofa::component::constraint::projective +{ + +template +AffineMovementProjectiveConstraint::AffineMovementProjectiveConstraint() + : core::behavior::ProjectiveConstraintSet(nullptr) + , data(new AffineMovementProjectiveConstraintInternalData) + , m_meshIndices( initData(&m_meshIndices,"meshIndices","Indices of the mesh") ) + , m_indices( initData(&m_indices,"indices","Indices of the constrained points") ) + , m_beginConstraintTime( initData(&m_beginConstraintTime,"beginConstraintTime","Begin time of the bilinear constraint") ) + , m_endConstraintTime( initData(&m_endConstraintTime,"endConstraintTime","End time of the bilinear constraint") ) + , m_rotation( initData(&m_rotation,"rotation","rotation applied to border points") ) + , m_quaternion( initData(&m_quaternion,"quaternion","quaternion applied to border points") ) + , m_translation( initData(&m_translation,"translation","translation applied to border points") ) + , m_drawConstrainedPoints( initData(&m_drawConstrainedPoints,"drawConstrainedPoints","draw constrained points") ) + , l_topology(initLink("topology", "link to the topology container")) +{ + if(!m_beginConstraintTime.isSet()) + m_beginConstraintTime = 0; + if(!m_endConstraintTime.isSet()) + m_endConstraintTime = 20; +} + + + +template +AffineMovementProjectiveConstraint::~AffineMovementProjectiveConstraint() +{ + +} + +template +void AffineMovementProjectiveConstraint::clearConstraints() +{ + m_indices.beginEdit()->clear(); + m_indices.endEdit(); +} + +template +void AffineMovementProjectiveConstraint::addConstraint(Index index) +{ + m_indices.beginEdit()->push_back(index); + m_indices.endEdit(); +} + +template +void AffineMovementProjectiveConstraint::removeConstraint(Index index) +{ + removeValue(*m_indices.beginEdit(),index); + m_indices.endEdit(); +} + +// -- Constraint interface + + +template +void AffineMovementProjectiveConstraint::init() +{ + this->core::behavior::ProjectiveConstraintSet::init(); + + if (l_topology.empty()) + { + msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; + l_topology.set(this->getContext()->getMeshTopologyLink()); + } + + if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) + { + msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; + + // Initialize topological changes support + m_indices.createTopologyHandler(_topology); + } + else + { + msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; + } + + const SetIndexArray & indices = m_indices.getValue(); + + auto maxIndex=this->mstate->getSize(); + for (Size i=0; i= maxIndex) + { + msg_error() << "Index " << index << " not valid!"; + removeConstraint(index); + } + } + +} + +template +void AffineMovementProjectiveConstraint::projectResponseImpl(VecDeriv& dx) +{ + const SetIndexArray & indices = m_indices.getValue(); + for (size_t i = 0; i< indices.size(); ++i) + { + dx[indices[i]]=Deriv(); + } +} + +template +void AffineMovementProjectiveConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) +{ + SOFA_UNUSED(mparams); + helper::WriteAccessor res = resData; + projectResponseImpl(res.wref()); +} + + + +template +void AffineMovementProjectiveConstraint::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) +{ + SOFA_UNUSED(mparams); + helper::WriteAccessor res = vData; + projectResponseImpl(res.wref()); +} + +template +void AffineMovementProjectiveConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) +{ + helper::WriteAccessor x = xData; + const SetIndexArray & indices = m_indices.getValue(); + + // Time + SReal beginTime = m_beginConstraintTime.getValue(); + SReal endTime = m_endConstraintTime.getValue(); + SReal totalTime = endTime - beginTime; + + //initialize initial mesh Dofs positions, if it's not done + if(meshPointsX0.size()==0) + this->initializeInitialPositions(m_meshIndices.getValue(),xData,meshPointsX0); + + //initialize final mesh Dofs positions, if it's not done + if(meshPointsXf.size()==0) + this->initializeFinalPositions(m_meshIndices.getValue(),xData, meshPointsX0, meshPointsXf); + + //initialize initial constrained Dofs positions, if it's not done + if(x0.size() == 0) + this->initializeInitialPositions(indices,xData,x0); + + //initialize final constrained Dofs positions, if it's not done + if (xf.size() == 0) + this->initializeFinalPositions(indices,xData,x0,xf); + // Update the intermediate Dofs positions computed by linear interpolation + SReal time = sofa::core::objectmodel::basecontext::getTime(this->getContext()->getRootContext()); + if( time > beginTime && time <= endTime && totalTime > 0) + { + for (auto index : indices) + { + DataTypes::setCPos( x[index], + ((DataTypes::getCPos(xf[index])-DataTypes::getCPos(x0[index]))*time + + (DataTypes::getCPos(x0[index])*endTime - DataTypes::getCPos(xf[index])*beginTime))/totalTime); + } + } + else if (time > endTime) + { + for (auto index : indices) + { + x[index] = xf[index]; + } + } +} + +template +void AffineMovementProjectiveConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned /*offset*/ ) +{ + // clears the rows and columns associated with constrained particles + const unsigned blockSize = DataTypes::deriv_total_size; + + for (const auto id : m_indices.getValue()) + { + M->clearRowsCols( id * blockSize, (id+1) * blockSize ); + } +} + +template +void AffineMovementProjectiveConstraint::getFinalPositions( VecCoord& finalPos,DataVecCoord& xData) +{ + // Indices of mesh points + const SetIndexArray & meshIndices = m_meshIndices.getValue(); + + // Initialize final positions + if(meshPointsXf.size()==0) + {this->initializeFinalPositions(meshIndices,xData,meshPointsX0,meshPointsXf);} + + // Set final positions + finalPos.resize(meshIndices.size()); + for (size_t i=0; i < meshIndices.size() ; ++i) + { + finalPos[meshIndices[i]] = meshPointsXf[meshIndices[i]]; + } +} + +template +void AffineMovementProjectiveConstraint::initializeInitialPositions (const SetIndexArray & indices, DataVecCoord& xData, VecCoord& x0) +{ + helper::WriteAccessor x = xData; + + x0.resize(x.size()); + for (size_t i=0; i < indices.size() ; ++i) + { + x0[indices[i]] = x[indices[i]]; + } +} + + +template <> +void AffineMovementProjectiveConstraint::transform(const SetIndexArray & indices, + defaulttype::Rigid3Types::VecCoord& x0, + defaulttype::Rigid3Types::VecCoord& xf) +{ + // Get quaternion and translation values + RotationMatrix rotationMat(0); + const Quat quat = m_quaternion.getValue(); + quat.toMatrix(rotationMat); + const Vec3 translation = m_translation.getValue(); + + // Apply transformation + for (size_t i=0; i < indices.size() ; ++i) + { + // Translation + xf[indices[i]].getCenter() = rotationMat*(x0[indices[i]].getCenter()) + translation; + // Rotation + xf[indices[i]].getOrientation() = (quat)+x0[indices[i]].getOrientation(); + } +} + +template +void AffineMovementProjectiveConstraint::transform(const SetIndexArray & indices, VecCoord& x0, VecCoord& xf) +{ + Vec3 translation = m_translation.getValue(); + + for (size_t i=0; i < indices.size() ; ++i) + { + DataTypes::setCPos(xf[indices[i]], (m_rotation.getValue())*DataTypes::getCPos(x0[indices[i]]) + translation); + } +} + + +template +void AffineMovementProjectiveConstraint::initializeFinalPositions (const SetIndexArray & indices, DataVecCoord& xData, VecCoord& x0, VecCoord& xf) +{ + helper::WriteAccessor x = xData; + + xf.resize(x.size()); + + // if the positions were not initialized + if(x0.size() == 0) + this->initializeInitialPositions(indices,xData,x0); + + transform(indices,x0,xf); +} + +template +void AffineMovementProjectiveConstraint::draw(const core::visual::VisualParams* vparams) +{ + const SetIndexArray & indices = m_indices.getValue(); + const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); + Vec3 point; + + if(m_drawConstrainedPoints.getValue()) + { + std::vector< Vec3 > points; + for( auto& index : indices ) + { + point = DataTypes::getCPos(x[index]); + points.push_back(point); + } + constexpr sofa::type::RGBAColor color(1,0.5,0.5,1); + vparams->drawTool()->drawPoints(points, 10, color); + } +} + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachConstraint.h index 14eff971abb..692f1178c2d 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachConstraint.h @@ -20,105 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/AttachProjectiveConstraint.h") -/** Attach given pair of particles, projecting the positions of the second particles to the first ones. -*/ -template -class AttachConstraint : public core::behavior::PairInteractionProjectiveConstraintSet +namespace sofa::component::constraint::projective { -public: - SOFA_CLASS(SOFA_TEMPLATE(AttachConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::PairInteractionProjectiveConstraintSet,DataTypes)); - - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::Real Real; - - typedef core::objectmodel::Data DataVecCoord; - typedef core::objectmodel::Data DataVecDeriv; - - typedef type::vector SetIndexArray; - typedef sofa::core::topology::TopologySubsetIndices SetIndex; - -public: - SetIndex f_indices1; ///< Indices of the source points on the first model - SetIndex f_indices2; ///< Indices of the fixed points on the second model - Data f_twoWay; ///< true if forces should be projected back from model2 to model1 - Data f_freeRotations; ///< true to keep rotations free (only used for Rigid DOFs) - Data f_lastFreeRotation; ///< true to keep rotation of the last attached point free (only used for Rigid DOFs) - Data f_restRotations; ///< true to use rest rotations local offsets (only used for Rigid DOFs) - Data f_lastPos; ///< position at which the attach constraint should become inactive - Data f_lastDir; ///< direction from lastPos at which the attach coustraint should become inactive - Data f_clamp; ///< true to clamp particles at lastPos instead of freeing them. - Data f_minDistance; ///< the constraint become inactive if the distance between the points attached is bigger than minDistance. - Data< Real > d_positionFactor; ///< IN: Factor applied to projection of position - Data< Real > d_velocityFactor; ///< IN: Factor applied to projection of velocity - Data< Real > d_responseFactor; ///< IN: Factor applied to projection of force/acceleration - Data< type::vector > d_constraintFactor; ///< Constraint factor per pair of points constrained. 0 -> the constraint is released. 1 -> the constraint is fully constrained - - type::vector activeFlags; - type::vector constraintReleased; - type::vector lastDist; - type::vector> restRotations; - -protected: - AttachConstraint(); - AttachConstraint(core::behavior::MechanicalState *mm1, core::behavior::MechanicalState *mm2); - ~AttachConstraint() override; - -public: - - /// Inherited from Base - void init() override; - void reinit() override; - void draw(const core::visual::VisualParams* vparams) override; - - /// Inherited from Constraint - void projectJacobianMatrix(const core::MechanicalParams* mparams, core::MultiMatrixDerivId cId) override; - void projectResponse(const core::MechanicalParams *mparams, DataVecDeriv& dx1, DataVecDeriv& dx2) override; - void projectVelocity(const core::MechanicalParams *mparams, DataVecDeriv& v1, DataVecDeriv& v2) override; - void projectPosition(const core::MechanicalParams *mparams, DataVecCoord& x1, DataVecCoord& x2) override; - - /// Project the global Mechanical Matrix to constrained space using offset parameter - void applyConstraint(const core::MechanicalParams *mparams, - const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - - /// Project the global Mechanical Vector to constrained space using offset parameter - void applyConstraint(const core::MechanicalParams *mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - - virtual void reinitIfChanged(); - - template - static std::string templateName(const T* ptr= nullptr) { - return core::behavior::PairInteractionProjectiveConstraintSet::templateName(ptr); - } - -protected : - const Real getConstraintFactor(const int index); - void doProjectPosition(Coord& x1, Coord& x2, bool freeRotations, unsigned index, Real positionFactor); - void doProjectVelocity(Deriv& x1, Deriv& x2, bool freeRotations, unsigned index, Real velocityFactor); - void doProjectResponse(Deriv& dx1, Deriv& dx2, bool freeRotations, bool twoway, unsigned index, Real responseFactor); - - void calcRestRotations(); - static unsigned int DerivConstrainedSize(bool freeRotations); - -}; - - -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ATTACHCONSTRAINT_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachConstraint; -#endif - -} // namespace sofa::component::constraint::projective +template +using AttachConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "AttachConstraint has been renamed to AttachProjectiveConstraint") = AttachProjectiveConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachConstraint.inl index a77b223d41d..ed5521f875d 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachConstraint.inl @@ -20,624 +20,7 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -namespace sofa::component::constraint::projective -{ +#include -using sofa::simulation::Node ; - -template<> -inline void AttachConstraint::doProjectPosition(Coord& x1, Coord& x2, bool freeRotations, unsigned index, Real positionFactor) -{ - SOFA_UNUSED(positionFactor); - // do nothing if distance between x2 & x1 is bigger than f_minDistance - if (f_minDistance.getValue() != -1.0 && - (x2.getCenter() - x1.getCenter()).norm() > f_minDistance.getValue()) - { - constraintReleased[index] = true; - return; - } - constraintReleased[index] = false; - - x2.getCenter() = x1.getCenter(); - if (!freeRotations) - { - if (!restRotations.empty()) - { - if (index+1 >= lastDist.size() || activeFlags[index+1]) - x2.getOrientation() = x1.getOrientation()*restRotations[index]; - else - { - // gradually set the velocity along the direction axis - const Real fact = -lastDist[index] / (lastDist[index+1]-lastDist[index]); - const sofa::type::Vec3 axis(restRotations[index][0], restRotations[index][1], restRotations[index][2]); - const Real angle = acos(restRotations[index][3])*2; - x2.getOrientation() = x1.getOrientation()*sofa::type::Quat(axis,angle*fact); - } - } - else - x2.getOrientation() = x1.getOrientation(); - } -} - - -template<> -inline void AttachConstraint::doProjectPosition(Coord& x1, Coord& x2, bool freeRotations, unsigned index, Real positionFactor) -{ - SOFA_UNUSED(positionFactor); - // do nothing if distance between x2 & x1 is bigger than f_minDistance - if (f_minDistance.getValue() != -1 && - (x2.getCenter() - x1.getCenter()).norm() > f_minDistance.getValue()) - { - constraintReleased[index] = true; - return; - } - constraintReleased[index] = false; - - x2.getCenter() = x1.getCenter(); - if (!freeRotations) - x2.getOrientation() = x1.getOrientation(); -} - - -template<> -inline void AttachConstraint::doProjectVelocity(Deriv& x1, Deriv& x2, bool freeRotations, unsigned index, Real velocityFactor) -{ - SOFA_UNUSED(velocityFactor); - // do nothing if distance between x2 & x1 is bigger than f_minDistance - if (constraintReleased[index]) - return; - - getVCenter( x2) = getVCenter(x1); - if (!freeRotations) - getVOrientation(x2) = getVOrientation(x1); -} - - -template<> -inline void AttachConstraint::doProjectVelocity(Deriv& x1, Deriv& x2, bool freeRotations, unsigned index, Real velocityFactor) -{ - SOFA_UNUSED(velocityFactor); - // do nothing if distance between x2 & x1 is bigger than f_minDistance - if (constraintReleased[index]) return; - - getVCenter(x2) = getVCenter(x1); - if (!freeRotations) - getVOrientation(x2) = getVOrientation(x1); -} - -template<> -inline void AttachConstraint::doProjectResponse(Deriv& dx1, Deriv& dx2, bool freeRotations, bool twoway, unsigned index, Real responseFactor) -{ - SOFA_UNUSED(responseFactor); - // do nothing if distance between x2 & x1 is bigger than f_minDistance - if (constraintReleased[index]) return; - - if (!twoway) - { - if (!freeRotations) - dx2 = Deriv(); - else - getVCenter(dx2).clear(); - } - else - { - if (!freeRotations) - { - dx1 += dx2; - dx2 = dx1; - } - else - { - getVCenter(dx1) += getVCenter(dx2); - getVCenter(dx2) = getVCenter(dx1); - } - } -} - - -template<> -inline void AttachConstraint::doProjectResponse(Deriv& dx1, Deriv& dx2, bool freeRotations, bool twoway, unsigned index, Real responseFactor) -{ - SOFA_UNUSED(responseFactor); - // do nothing if distance between x2 & x1 is bigger than f_minDistance - if (constraintReleased[index]) return; - - if (!twoway) - { - if (!freeRotations) - dx2 = Deriv(); - else - getVCenter(dx2).clear(); - } - else - { - if (!freeRotations) - { - dx1 += dx2; - dx2 = dx1; - } - else - { - getVCenter(dx1) += getVCenter(dx2); - getVCenter(dx2) = getVCenter(dx1); - } - } -} - -template -inline unsigned int AttachConstraint::DerivConstrainedSize(bool freeRotations) -{ - if (std::is_same::value || std::is_same::value) { - if (freeRotations) - return Deriv::spatial_dimensions; - else - return Deriv::total_size; - } - else { - SOFA_UNUSED(freeRotations); - return Deriv::size(); - } -} - -// Could be simplified with default values for mm1 and mm2, but that way we are assured that either both or neither of mm1/mm2 are set. -template -AttachConstraint::AttachConstraint() - : AttachConstraint::AttachConstraint(nullptr, nullptr) -{ -} - -template -AttachConstraint::AttachConstraint(core::behavior::MechanicalState *mm1, core::behavior::MechanicalState *mm2) - : core::behavior::PairInteractionProjectiveConstraintSet(mm1,mm2) - , f_indices1( initData(&f_indices1,"indices1","Indices of the source points on the first model") ) - , f_indices2( initData(&f_indices2,"indices2","Indices of the fixed points on the second model") ) - , f_twoWay( initData(&f_twoWay,false,"twoWay", "true if forces should be projected back from model2 to model1") ) - , f_freeRotations( initData(&f_freeRotations,false,"freeRotations", "true to keep rotations free (only used for Rigid DOFs)") ) - , f_lastFreeRotation( initData(&f_lastFreeRotation,false,"lastFreeRotation", "true to keep rotation of the last attached point free (only used for Rigid DOFs)") ) - , f_restRotations( initData(&f_restRotations,false,"restRotations", "true to use rest rotations local offsets (only used for Rigid DOFs)") ) - , f_lastPos( initData(&f_lastPos,"lastPos", "position at which the attach constraint should become inactive") ) - , f_lastDir( initData(&f_lastDir,"lastDir", "direction from lastPos at which the attach coustraint should become inactive") ) - , f_clamp( initData(&f_clamp, false,"clamp", "true to clamp particles at lastPos instead of freeing them.") ) - , f_minDistance( initData(&f_minDistance, static_cast(-1),"minDistance", "the constraint become inactive if the distance between the points attached is bigger than minDistance.") ) - , d_positionFactor(initData(&d_positionFactor, static_cast(1.0), "positionFactor", "IN: Factor applied to projection of position")) - , d_velocityFactor(initData(&d_velocityFactor, static_cast(1.0), "velocityFactor", "IN: Factor applied to projection of velocity")) - , d_responseFactor(initData(&d_responseFactor, static_cast(1.0), "responseFactor", "IN: Factor applied to projection of force/acceleration")) - , d_constraintFactor( initData(&d_constraintFactor,"constraintFactor","Constraint factor per pair of points constrained. 0 -> the constraint is released. 1 -> the constraint is fully constrained") ) -{ - -} - -template -AttachConstraint::~AttachConstraint() -{ -} - -template -void AttachConstraint::init() -{ - this->core::behavior::PairInteractionProjectiveConstraintSet::init(); - reinit(); -} - -template -void AttachConstraint::reinit() -{ - // Check coherency of size between indices vectors 1 and 2 - if(f_indices1.getValue().size() != f_indices2.getValue().size()) - { - msg_warning() << "Size mismatch between indices1 and indices2 (" - << f_indices1.getValue().size() << " != " << f_indices2.getValue().size() << ")."; - } - - // Set to the correct length if dynamic, else check coherency. - if(d_constraintFactor.getValue().size()) - { - helper::ReadAccessor>> constraintFactor = d_constraintFactor; - if(constraintFactor.size() != f_indices2.getValue().size()) - { - msg_warning() << "Size of vector constraintFactor, do not fit number of indices attached (" << constraintFactor.size() << " != " << f_indices2.getValue().size() << ")."; - } - else - { - for (unsigned int j=0; j 1.0) || (constraintFactor[j] < 0.0)) - { - msg_warning() << "Value of vector constraintFactor at indice "< 1.0e-10) { - lastDist.resize(f_indices2.getValue().size()); - } - - if (f_restRotations.getValue()) - calcRestRotations(); - this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); -} - -template -void AttachConstraint::reinitIfChanged() { - if((f_indices1.getParent() || f_indices2.getParent()) && constraintReleased.size() != f_indices2.getValue().size()) - { - reinit(); - } -} - -template -void AttachConstraint::calcRestRotations() -{ -} - -template <> -void AttachConstraint::calcRestRotations(); - -template -void AttachConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, core::MultiMatrixDerivId cId) -{ - SOFA_UNUSED(mparams); - SOFA_UNUSED(cId); -} - -template -void AttachConstraint::projectPosition(const core::MechanicalParams * mparams, DataVecCoord& res1_d, DataVecCoord& res2_d) -{ - SOFA_UNUSED(mparams); - const SetIndexArray & indices1 = f_indices1.getValue(); - const SetIndexArray & indices2 = f_indices2.getValue(); - const bool freeRotations = f_freeRotations.getValue(); - const bool lastFreeRotation = f_lastFreeRotation.getValue(); - const bool last = (f_lastDir.isSet() && f_lastDir.getValue().norm() > 1.0e-10); - const bool clamp = f_clamp.getValue(); - - VecCoord &res1 = *res1_d.beginEdit(); - VecCoord &res2 = *res2_d.beginEdit(); - - // update active flags - reinitIfChanged(); - - for (unsigned int i=0; i p3d; - DataTypes::get(p3d[0],p3d[1],p3d[2],p); - lastDist[i] = (Real)( (p3d-f_lastPos.getValue())*f_lastDir.getValue()); - if (lastDist[i] > 0.0) - { - if (clamp) - { - msg_info_when(activeFlags[i]) << "AttachConstraint: point " - <> positionFactor = d_positionFactor; - for (unsigned int i=0; i=activeFlags.size() || !activeFlags[i+1])), i, positionFactor); - } - else if (clamp) - { - DataTypes::set(p,f_lastPos.getValue()[0],f_lastPos.getValue()[1],f_lastPos.getValue()[2]); - - msg_info() << "AttachConstraint: x2["< -void AttachConstraint::projectVelocity(const core::MechanicalParams * mparams, DataVecDeriv& res1_d, DataVecDeriv& res2_d) -{ - SOFA_UNUSED(mparams); - VecDeriv &res1 = *res1_d.beginEdit(); - VecDeriv &res2 = *res2_d.beginEdit(); - - const SetIndexArray & indices1 = f_indices1.getValue(); - const SetIndexArray & indices2 = f_indices2.getValue(); - const bool freeRotations = f_freeRotations.getValue(); - const bool lastFreeRotation = f_lastFreeRotation.getValue(); - const bool clamp = f_clamp.getValue(); - - reinitIfChanged(); - helper::ReadAccessor> velocityFactor = d_velocityFactor; - for (unsigned int i=0; i=activeFlags.size() || !activeFlags[i+1])), i, velocityFactor); - } - else if (clamp) - { - msg_info() << "AttachConstraint: v2["< -void AttachConstraint::projectResponse(const core::MechanicalParams * mparams, DataVecDeriv& res1_d, DataVecDeriv& res2_d) -{ - SOFA_UNUSED(mparams); - VecDeriv &res1 = *res1_d.beginEdit(); - VecDeriv &res2 = *res2_d.beginEdit(); - - const SetIndexArray & indices1 = f_indices1.getValue(); - const SetIndexArray & indices2 = f_indices2.getValue(); - const bool twoway = f_twoWay.getValue(); - const bool freeRotations = f_freeRotations.getValue(); - const bool lastFreeRotation = f_lastFreeRotation.getValue(); - const bool clamp = f_clamp.getValue(); - - reinitIfChanged(); - helper::ReadAccessor> responseFactor = d_responseFactor; - for (unsigned int i=0; i=activeFlags.size() || !activeFlags[i+1])), twoway, i, responseFactor); - - msg_info() << " final r2["< -void AttachConstraint::applyConstraint(const core::MechanicalParams * mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) -{ - SOFA_UNUSED(mparams); - if (f_twoWay.getValue()) - return; - - const sofa::core::behavior::MultiMatrixAccessor::MatrixRef r = matrix->getMatrix(this->mstate2); - if (!r) - return; - - sofa::linearalgebra::BaseMatrix *mat = r.matrix; - const unsigned int offset = r.offset; - - const SetIndexArray & indices = f_indices2.getValue(); - const unsigned int N = Deriv::size(); - const unsigned int NC = DerivConstrainedSize(f_freeRotations.getValue()); - const unsigned int NCLast = DerivConstrainedSize(f_lastFreeRotation.getValue()); - unsigned int i=0; - const bool clamp = f_clamp.getValue(); - - reinitIfChanged(); - - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it, ++i) - { - if (!clamp && i < activeFlags.size() && !activeFlags[i]) - continue; - - msg_info() << "AttachConstraint: apply in matrix column/row "<<(*it); - - if (NCLast != NC && (i>=activeFlags.size() || !activeFlags[i+1])) - { - // Reset Fixed Row and Col - for (unsigned int c=0; cclearRowCol(offset + N * (*it) + c); - // Set Fixed Vertex - for (unsigned int c=0; cset(offset + N * (*it) + c, offset + N * (*it) + c, 1.0); - } - else - { - // Reset Fixed Row and Col - for (unsigned int c=0; cclearRowCol(offset + N * (*it) + c); - // Set Fixed Vertex - for (unsigned int c=0; cset(offset + N * (*it) + c, offset + N * (*it) + c, 1.0); - } - } -} - - -template -void AttachConstraint::applyConstraint(const core::MechanicalParams * mparams, linearalgebra::BaseVector* vect, const sofa::core::behavior::MultiMatrixAccessor* matrix) -{ - SOFA_UNUSED(mparams); - if (f_twoWay.getValue()) - return; - - const int o = matrix->getGlobalOffset(this->mstate2); - if (o < 0) - return; - - unsigned int offset = (unsigned int)o; - - msg_info() << "applyConstraint in Vector with offset = " << offset ; - - const SetIndexArray & indices = f_indices2.getValue(); - const unsigned int N = Deriv::size(); - const unsigned int NC = DerivConstrainedSize(f_freeRotations.getValue()); - const unsigned int NCLast = DerivConstrainedSize(f_lastFreeRotation.getValue()); - unsigned int i = 0; - const bool clamp = f_clamp.getValue(); - - reinitIfChanged(); - - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it, ++i) - { - if (!clamp && i < activeFlags.size() && !activeFlags[i]) - continue; - - if (NCLast != NC && (i>=activeFlags.size() || !activeFlags[i+1])) - { - for (unsigned int c=0; cclear(offset + N * (*it) + c); - } - else - { - for (unsigned int c=0; cclear(offset + N * (*it) + c); - } - } -} - -template -const typename DataTypes::Real AttachConstraint::getConstraintFactor(const int index) { - return d_constraintFactor.getValue().size() ? d_constraintFactor.getValue()[index] : 1; -} - -template -void AttachConstraint::doProjectPosition(Coord& x1, Coord& x2, bool freeRotations, unsigned index, Real positionFactor) -{ - SOFA_UNUSED(freeRotations); - // do nothing if distance between x2 & x1 is bigger than f_minDistance - if (f_minDistance.getValue() != -1 && - (x2 - x1).norm() > f_minDistance.getValue()) - { - constraintReleased[index] = true; - return; - } - constraintReleased[index] = false; - - Deriv corr = (x2-x1)*(0.5*positionFactor*getConstraintFactor(index)); - - x1 += corr; - x2 -= corr; -} - -template -void AttachConstraint::doProjectVelocity(Deriv &x1, Deriv &x2, bool freeRotations, unsigned index, Real velocityFactor) -{ - SOFA_UNUSED(freeRotations); - // do nothing if distance between x2 & x1 is bigger than f_minDistance - if (constraintReleased[index]) return; - - Deriv corr = (x2-x1)*(0.5*velocityFactor*getConstraintFactor(index)); - - x1 += corr; - x2 -= corr; -} - -template -void AttachConstraint::doProjectResponse(Deriv& dx1, Deriv& dx2, bool freeRotations, bool twoway, unsigned index, Real responseFactor) -{ - SOFA_UNUSED(freeRotations); - // do nothing if distance between x2 & x1 is bigger than f_minDistance - if (constraintReleased[index]) return; - - if (!twoway) - { - dx2 = Deriv(); - } - else - { - Deriv corr = (dx2-dx1)*0.5*responseFactor*getConstraintFactor(index); - dx1 += corr; - dx2 -= corr; - } -} - - -template -void AttachConstraint::draw(const core::visual::VisualParams* vparams) -{ - if (!vparams->displayFlags().getShowBehaviorModels()) - return; - - const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); - vparams->drawTool()->disableLighting(); - - const SetIndexArray & indices1 = f_indices1.getValue(); - const SetIndexArray & indices2 = f_indices2.getValue(); - const VecCoord& x1 = this->mstate1->read(core::ConstVecCoordId::position())->getValue(); - const VecCoord& x2 = this->mstate2->read(core::ConstVecCoordId::position())->getValue(); - - constexpr sofa::type::RGBAColor color1(1,0.5,0.5,1); - std::vector vertices; - - for (unsigned int i=0; i i && !activeFlags[i]) - continue; - vertices.push_back(sofa::type::Vec3(x2[indices2[i]][0],x2[indices2[i]][1],x2[indices2[i]][2])); - } - vparams->drawTool()->drawPoints(vertices,10,color1); - vertices.clear(); - - constexpr sofa::type::RGBAColor color2(1,0.5,0.5,1); - for (unsigned int i=0; i i && !activeFlags[i]) - continue; - vertices.push_back(sofa::type::Vec3(x1[indices1[i]][0],x1[indices1[i]][1],x1[indices1[i]][2])); - vertices.push_back(sofa::type::Vec3(x2[indices2[i]][0],x2[indices2[i]][1],x2[indices2[i]][2])); - } - vparams->drawTool()->drawLines(vertices,1,color2); - -} - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/AttachProjectiveConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachProjectiveConstraint.cpp similarity index 71% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachProjectiveConstraint.cpp index 8642434e285..2c2683c9d1c 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachProjectiveConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ATTACHCONSTRAINT_CPP -#include +#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ATTACHPROJECTIVECONSTRAINT_CPP +#include #include namespace sofa::component::constraint::projective @@ -30,16 +30,16 @@ using namespace sofa::type; using namespace sofa::defaulttype; using namespace sofa::helper; -int AttachConstraintClass = core::RegisterObject("Attach given pair of particles, projecting the positions of the second particles to the first ones") - .add< AttachConstraint >() - .add< AttachConstraint >() - .add< AttachConstraint >() - .add< AttachConstraint >() - .add< AttachConstraint >() +int AttachProjectiveConstraintClass = core::RegisterObject("Attach given pair of particles, projecting the positions of the second particles to the first ones") + .add< AttachProjectiveConstraint >() + .add< AttachProjectiveConstraint >() + .add< AttachProjectiveConstraint >() + .add< AttachProjectiveConstraint >() + .add< AttachProjectiveConstraint >() ; template <> SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API -void AttachConstraint::calcRestRotations() +void AttachProjectiveConstraint::calcRestRotations() { const SetIndexArray & indices2 = f_indices2.getValue(); const VecCoord& x0 = this->mstate2->read(core::ConstVecCoordId::restPosition())->getValue(); @@ -61,11 +61,11 @@ void AttachConstraint::calcRestRotations() } } -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachProjectiveConstraint; diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachProjectiveConstraint.h new file mode 100644 index 00000000000..37ed886dc4b --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachProjectiveConstraint.h @@ -0,0 +1,124 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include + +namespace sofa::component::constraint::projective +{ + +/** Attach given pair of particles, projecting the positions of the second particles to the first ones. +*/ +template +class AttachProjectiveConstraint : public core::behavior::PairInteractionProjectiveConstraintSet +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(AttachProjectiveConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::PairInteractionProjectiveConstraintSet,DataTypes)); + + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::Real Real; + + typedef core::objectmodel::Data DataVecCoord; + typedef core::objectmodel::Data DataVecDeriv; + + typedef type::vector SetIndexArray; + typedef sofa::core::topology::TopologySubsetIndices SetIndex; + +public: + SetIndex f_indices1; ///< Indices of the source points on the first model + SetIndex f_indices2; ///< Indices of the fixed points on the second model + Data f_twoWay; ///< true if forces should be projected back from model2 to model1 + Data f_freeRotations; ///< true to keep rotations free (only used for Rigid DOFs) + Data f_lastFreeRotation; ///< true to keep rotation of the last attached point free (only used for Rigid DOFs) + Data f_restRotations; ///< true to use rest rotations local offsets (only used for Rigid DOFs) + Data f_lastPos; ///< position at which the attach constraint should become inactive + Data f_lastDir; ///< direction from lastPos at which the attach coustraint should become inactive + Data f_clamp; ///< true to clamp particles at lastPos instead of freeing them. + Data f_minDistance; ///< the constraint become inactive if the distance between the points attached is bigger than minDistance. + Data< Real > d_positionFactor; ///< IN: Factor applied to projection of position + Data< Real > d_velocityFactor; ///< IN: Factor applied to projection of velocity + Data< Real > d_responseFactor; ///< IN: Factor applied to projection of force/acceleration + Data< type::vector > d_constraintFactor; ///< Constraint factor per pair of points constrained. 0 -> the constraint is released. 1 -> the constraint is fully constrained + + type::vector activeFlags; + type::vector constraintReleased; + type::vector lastDist; + type::vector> restRotations; + +protected: + AttachProjectiveConstraint(); + AttachProjectiveConstraint(core::behavior::MechanicalState *mm1, core::behavior::MechanicalState *mm2); + ~AttachProjectiveConstraint() override; + +public: + + /// Inherited from Base + void init() override; + void reinit() override; + void draw(const core::visual::VisualParams* vparams) override; + + /// Inherited from Constraint + void projectJacobianMatrix(const core::MechanicalParams* mparams, core::MultiMatrixDerivId cId) override; + void projectResponse(const core::MechanicalParams *mparams, DataVecDeriv& dx1, DataVecDeriv& dx2) override; + void projectVelocity(const core::MechanicalParams *mparams, DataVecDeriv& v1, DataVecDeriv& v2) override; + void projectPosition(const core::MechanicalParams *mparams, DataVecCoord& x1, DataVecCoord& x2) override; + + /// Project the global Mechanical Matrix to constrained space using offset parameter + void applyConstraint(const core::MechanicalParams *mparams, + const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + + /// Project the global Mechanical Vector to constrained space using offset parameter + void applyConstraint(const core::MechanicalParams *mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + + virtual void reinitIfChanged(); + + template + static std::string templateName(const T* ptr= nullptr) { + return core::behavior::PairInteractionProjectiveConstraintSet::templateName(ptr); + } + +protected : + const Real getConstraintFactor(const int index); + void doProjectPosition(Coord& x1, Coord& x2, bool freeRotations, unsigned index, Real positionFactor); + void doProjectVelocity(Deriv& x1, Deriv& x2, bool freeRotations, unsigned index, Real velocityFactor); + void doProjectResponse(Deriv& dx1, Deriv& dx2, bool freeRotations, bool twoway, unsigned index, Real responseFactor); + + void calcRestRotations(); + static unsigned int DerivConstrainedSize(bool freeRotations); + +}; + + +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ATTACHPROJECTIVECONSTRAINT_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachProjectiveConstraint; +#endif + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachProjectiveConstraint.inl new file mode 100644 index 00000000000..e7bd429434f --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachProjectiveConstraint.inl @@ -0,0 +1,643 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +using sofa::simulation::Node ; + +template<> +inline void AttachProjectiveConstraint::doProjectPosition(Coord& x1, Coord& x2, bool freeRotations, unsigned index, Real positionFactor) +{ + SOFA_UNUSED(positionFactor); + // do nothing if distance between x2 & x1 is bigger than f_minDistance + if (f_minDistance.getValue() != -1.0 && + (x2.getCenter() - x1.getCenter()).norm() > f_minDistance.getValue()) + { + constraintReleased[index] = true; + return; + } + constraintReleased[index] = false; + + x2.getCenter() = x1.getCenter(); + if (!freeRotations) + { + if (!restRotations.empty()) + { + if (index+1 >= lastDist.size() || activeFlags[index+1]) + x2.getOrientation() = x1.getOrientation()*restRotations[index]; + else + { + // gradually set the velocity along the direction axis + const Real fact = -lastDist[index] / (lastDist[index+1]-lastDist[index]); + const sofa::type::Vec3 axis(restRotations[index][0], restRotations[index][1], restRotations[index][2]); + const Real angle = acos(restRotations[index][3])*2; + x2.getOrientation() = x1.getOrientation()*sofa::type::Quat(axis,angle*fact); + } + } + else + x2.getOrientation() = x1.getOrientation(); + } +} + + +template<> +inline void AttachProjectiveConstraint::doProjectPosition(Coord& x1, Coord& x2, bool freeRotations, unsigned index, Real positionFactor) +{ + SOFA_UNUSED(positionFactor); + // do nothing if distance between x2 & x1 is bigger than f_minDistance + if (f_minDistance.getValue() != -1 && + (x2.getCenter() - x1.getCenter()).norm() > f_minDistance.getValue()) + { + constraintReleased[index] = true; + return; + } + constraintReleased[index] = false; + + x2.getCenter() = x1.getCenter(); + if (!freeRotations) + x2.getOrientation() = x1.getOrientation(); +} + + +template<> +inline void AttachProjectiveConstraint::doProjectVelocity(Deriv& x1, Deriv& x2, bool freeRotations, unsigned index, Real velocityFactor) +{ + SOFA_UNUSED(velocityFactor); + // do nothing if distance between x2 & x1 is bigger than f_minDistance + if (constraintReleased[index]) + return; + + getVCenter( x2) = getVCenter(x1); + if (!freeRotations) + getVOrientation(x2) = getVOrientation(x1); +} + + +template<> +inline void AttachProjectiveConstraint::doProjectVelocity(Deriv& x1, Deriv& x2, bool freeRotations, unsigned index, Real velocityFactor) +{ + SOFA_UNUSED(velocityFactor); + // do nothing if distance between x2 & x1 is bigger than f_minDistance + if (constraintReleased[index]) return; + + getVCenter(x2) = getVCenter(x1); + if (!freeRotations) + getVOrientation(x2) = getVOrientation(x1); +} + +template<> +inline void AttachProjectiveConstraint::doProjectResponse(Deriv& dx1, Deriv& dx2, bool freeRotations, bool twoway, unsigned index, Real responseFactor) +{ + SOFA_UNUSED(responseFactor); + // do nothing if distance between x2 & x1 is bigger than f_minDistance + if (constraintReleased[index]) return; + + if (!twoway) + { + if (!freeRotations) + dx2 = Deriv(); + else + getVCenter(dx2).clear(); + } + else + { + if (!freeRotations) + { + dx1 += dx2; + dx2 = dx1; + } + else + { + getVCenter(dx1) += getVCenter(dx2); + getVCenter(dx2) = getVCenter(dx1); + } + } +} + + +template<> +inline void AttachProjectiveConstraint::doProjectResponse(Deriv& dx1, Deriv& dx2, bool freeRotations, bool twoway, unsigned index, Real responseFactor) +{ + SOFA_UNUSED(responseFactor); + // do nothing if distance between x2 & x1 is bigger than f_minDistance + if (constraintReleased[index]) return; + + if (!twoway) + { + if (!freeRotations) + dx2 = Deriv(); + else + getVCenter(dx2).clear(); + } + else + { + if (!freeRotations) + { + dx1 += dx2; + dx2 = dx1; + } + else + { + getVCenter(dx1) += getVCenter(dx2); + getVCenter(dx2) = getVCenter(dx1); + } + } +} + +template +inline unsigned int AttachProjectiveConstraint::DerivConstrainedSize(bool freeRotations) +{ + if (std::is_same::value || std::is_same::value) { + if (freeRotations) + return Deriv::spatial_dimensions; + else + return Deriv::total_size; + } + else { + SOFA_UNUSED(freeRotations); + return Deriv::size(); + } +} + +// Could be simplified with default values for mm1 and mm2, but that way we are assured that either both or neither of mm1/mm2 are set. +template +AttachProjectiveConstraint::AttachProjectiveConstraint() + : AttachProjectiveConstraint::AttachProjectiveConstraint(nullptr, nullptr) +{ +} + +template +AttachProjectiveConstraint::AttachProjectiveConstraint(core::behavior::MechanicalState *mm1, core::behavior::MechanicalState *mm2) + : core::behavior::PairInteractionProjectiveConstraintSet(mm1,mm2) + , f_indices1( initData(&f_indices1,"indices1","Indices of the source points on the first model") ) + , f_indices2( initData(&f_indices2,"indices2","Indices of the fixed points on the second model") ) + , f_twoWay( initData(&f_twoWay,false,"twoWay", "true if forces should be projected back from model2 to model1") ) + , f_freeRotations( initData(&f_freeRotations,false,"freeRotations", "true to keep rotations free (only used for Rigid DOFs)") ) + , f_lastFreeRotation( initData(&f_lastFreeRotation,false,"lastFreeRotation", "true to keep rotation of the last attached point free (only used for Rigid DOFs)") ) + , f_restRotations( initData(&f_restRotations,false,"restRotations", "true to use rest rotations local offsets (only used for Rigid DOFs)") ) + , f_lastPos( initData(&f_lastPos,"lastPos", "position at which the attach constraint should become inactive") ) + , f_lastDir( initData(&f_lastDir,"lastDir", "direction from lastPos at which the attach coustraint should become inactive") ) + , f_clamp( initData(&f_clamp, false,"clamp", "true to clamp particles at lastPos instead of freeing them.") ) + , f_minDistance( initData(&f_minDistance, static_cast(-1),"minDistance", "the constraint become inactive if the distance between the points attached is bigger than minDistance.") ) + , d_positionFactor(initData(&d_positionFactor, static_cast(1.0), "positionFactor", "IN: Factor applied to projection of position")) + , d_velocityFactor(initData(&d_velocityFactor, static_cast(1.0), "velocityFactor", "IN: Factor applied to projection of velocity")) + , d_responseFactor(initData(&d_responseFactor, static_cast(1.0), "responseFactor", "IN: Factor applied to projection of force/acceleration")) + , d_constraintFactor( initData(&d_constraintFactor,"constraintFactor","Constraint factor per pair of points constrained. 0 -> the constraint is released. 1 -> the constraint is fully constrained") ) +{ + +} + +template +AttachProjectiveConstraint::~AttachProjectiveConstraint() +{ +} + +template +void AttachProjectiveConstraint::init() +{ + this->core::behavior::PairInteractionProjectiveConstraintSet::init(); + reinit(); +} + +template +void AttachProjectiveConstraint::reinit() +{ + // Check coherency of size between indices vectors 1 and 2 + if(f_indices1.getValue().size() != f_indices2.getValue().size()) + { + msg_warning() << "Size mismatch between indices1 and indices2 (" + << f_indices1.getValue().size() << " != " << f_indices2.getValue().size() << ")."; + } + + // Set to the correct length if dynamic, else check coherency. + if(d_constraintFactor.getValue().size()) + { + helper::ReadAccessor>> constraintFactor = d_constraintFactor; + if(constraintFactor.size() != f_indices2.getValue().size()) + { + msg_warning() << "Size of vector constraintFactor, do not fit number of indices attached (" << constraintFactor.size() << " != " << f_indices2.getValue().size() << ")."; + } + else + { + for (unsigned int j=0; j 1.0) || (constraintFactor[j] < 0.0)) + { + msg_warning() << "Value of vector constraintFactor at indice "< 1.0e-10) { + lastDist.resize(f_indices2.getValue().size()); + } + + if (f_restRotations.getValue()) + calcRestRotations(); + this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); +} + +template +void AttachProjectiveConstraint::reinitIfChanged() { + if((f_indices1.getParent() || f_indices2.getParent()) && constraintReleased.size() != f_indices2.getValue().size()) + { + reinit(); + } +} + +template +void AttachProjectiveConstraint::calcRestRotations() +{ +} + +template <> +void AttachProjectiveConstraint::calcRestRotations(); + +template +void AttachProjectiveConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, core::MultiMatrixDerivId cId) +{ + SOFA_UNUSED(mparams); + SOFA_UNUSED(cId); +} + +template +void AttachProjectiveConstraint::projectPosition(const core::MechanicalParams * mparams, DataVecCoord& res1_d, DataVecCoord& res2_d) +{ + SOFA_UNUSED(mparams); + const SetIndexArray & indices1 = f_indices1.getValue(); + const SetIndexArray & indices2 = f_indices2.getValue(); + const bool freeRotations = f_freeRotations.getValue(); + const bool lastFreeRotation = f_lastFreeRotation.getValue(); + const bool last = (f_lastDir.isSet() && f_lastDir.getValue().norm() > 1.0e-10); + const bool clamp = f_clamp.getValue(); + + VecCoord &res1 = *res1_d.beginEdit(); + VecCoord &res2 = *res2_d.beginEdit(); + + // update active flags + reinitIfChanged(); + + for (unsigned int i=0; i p3d; + DataTypes::get(p3d[0],p3d[1],p3d[2],p); + lastDist[i] = (Real)( (p3d-f_lastPos.getValue())*f_lastDir.getValue()); + if (lastDist[i] > 0.0) + { + if (clamp) + { + msg_info_when(activeFlags[i]) << "AttachProjectiveConstraint: point " + <> positionFactor = d_positionFactor; + for (unsigned int i=0; i=activeFlags.size() || !activeFlags[i+1])), i, positionFactor); + } + else if (clamp) + { + DataTypes::set(p,f_lastPos.getValue()[0],f_lastPos.getValue()[1],f_lastPos.getValue()[2]); + + msg_info() << "AttachProjectiveConstraint: x2["< +void AttachProjectiveConstraint::projectVelocity(const core::MechanicalParams * mparams, DataVecDeriv& res1_d, DataVecDeriv& res2_d) +{ + SOFA_UNUSED(mparams); + VecDeriv &res1 = *res1_d.beginEdit(); + VecDeriv &res2 = *res2_d.beginEdit(); + + const SetIndexArray & indices1 = f_indices1.getValue(); + const SetIndexArray & indices2 = f_indices2.getValue(); + const bool freeRotations = f_freeRotations.getValue(); + const bool lastFreeRotation = f_lastFreeRotation.getValue(); + const bool clamp = f_clamp.getValue(); + + reinitIfChanged(); + helper::ReadAccessor> velocityFactor = d_velocityFactor; + for (unsigned int i=0; i=activeFlags.size() || !activeFlags[i+1])), i, velocityFactor); + } + else if (clamp) + { + msg_info() << "AttachProjectiveConstraint: v2["< +void AttachProjectiveConstraint::projectResponse(const core::MechanicalParams * mparams, DataVecDeriv& res1_d, DataVecDeriv& res2_d) +{ + SOFA_UNUSED(mparams); + VecDeriv &res1 = *res1_d.beginEdit(); + VecDeriv &res2 = *res2_d.beginEdit(); + + const SetIndexArray & indices1 = f_indices1.getValue(); + const SetIndexArray & indices2 = f_indices2.getValue(); + const bool twoway = f_twoWay.getValue(); + const bool freeRotations = f_freeRotations.getValue(); + const bool lastFreeRotation = f_lastFreeRotation.getValue(); + const bool clamp = f_clamp.getValue(); + + reinitIfChanged(); + helper::ReadAccessor> responseFactor = d_responseFactor; + for (unsigned int i=0; i=activeFlags.size() || !activeFlags[i+1])), twoway, i, responseFactor); + + msg_info() << " final r2["< +void AttachProjectiveConstraint::applyConstraint(const core::MechanicalParams * mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) +{ + SOFA_UNUSED(mparams); + if (f_twoWay.getValue()) + return; + + const sofa::core::behavior::MultiMatrixAccessor::MatrixRef r = matrix->getMatrix(this->mstate2); + if (!r) + return; + + sofa::linearalgebra::BaseMatrix *mat = r.matrix; + const unsigned int offset = r.offset; + + const SetIndexArray & indices = f_indices2.getValue(); + const unsigned int N = Deriv::size(); + const unsigned int NC = DerivConstrainedSize(f_freeRotations.getValue()); + const unsigned int NCLast = DerivConstrainedSize(f_lastFreeRotation.getValue()); + unsigned int i=0; + const bool clamp = f_clamp.getValue(); + + reinitIfChanged(); + + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it, ++i) + { + if (!clamp && i < activeFlags.size() && !activeFlags[i]) + continue; + + msg_info() << "AttachProjectiveConstraint: apply in matrix column/row "<<(*it); + + if (NCLast != NC && (i>=activeFlags.size() || !activeFlags[i+1])) + { + // Reset Fixed Row and Col + for (unsigned int c=0; cclearRowCol(offset + N * (*it) + c); + // Set Fixed Vertex + for (unsigned int c=0; cset(offset + N * (*it) + c, offset + N * (*it) + c, 1.0); + } + else + { + // Reset Fixed Row and Col + for (unsigned int c=0; cclearRowCol(offset + N * (*it) + c); + // Set Fixed Vertex + for (unsigned int c=0; cset(offset + N * (*it) + c, offset + N * (*it) + c, 1.0); + } + } +} + + +template +void AttachProjectiveConstraint::applyConstraint(const core::MechanicalParams * mparams, linearalgebra::BaseVector* vect, const sofa::core::behavior::MultiMatrixAccessor* matrix) +{ + SOFA_UNUSED(mparams); + if (f_twoWay.getValue()) + return; + + const int o = matrix->getGlobalOffset(this->mstate2); + if (o < 0) + return; + + unsigned int offset = (unsigned int)o; + + msg_info() << "applyConstraint in Vector with offset = " << offset ; + + const SetIndexArray & indices = f_indices2.getValue(); + const unsigned int N = Deriv::size(); + const unsigned int NC = DerivConstrainedSize(f_freeRotations.getValue()); + const unsigned int NCLast = DerivConstrainedSize(f_lastFreeRotation.getValue()); + unsigned int i = 0; + const bool clamp = f_clamp.getValue(); + + reinitIfChanged(); + + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it, ++i) + { + if (!clamp && i < activeFlags.size() && !activeFlags[i]) + continue; + + if (NCLast != NC && (i>=activeFlags.size() || !activeFlags[i+1])) + { + for (unsigned int c=0; cclear(offset + N * (*it) + c); + } + else + { + for (unsigned int c=0; cclear(offset + N * (*it) + c); + } + } +} + +template +const typename DataTypes::Real AttachProjectiveConstraint::getConstraintFactor(const int index) { + return d_constraintFactor.getValue().size() ? d_constraintFactor.getValue()[index] : 1; +} + +template +void AttachProjectiveConstraint::doProjectPosition(Coord& x1, Coord& x2, bool freeRotations, unsigned index, Real positionFactor) +{ + SOFA_UNUSED(freeRotations); + // do nothing if distance between x2 & x1 is bigger than f_minDistance + if (f_minDistance.getValue() != -1 && + (x2 - x1).norm() > f_minDistance.getValue()) + { + constraintReleased[index] = true; + return; + } + constraintReleased[index] = false; + + Deriv corr = (x2-x1)*(0.5*positionFactor*getConstraintFactor(index)); + + x1 += corr; + x2 -= corr; +} + +template +void AttachProjectiveConstraint::doProjectVelocity(Deriv &x1, Deriv &x2, bool freeRotations, unsigned index, Real velocityFactor) +{ + SOFA_UNUSED(freeRotations); + // do nothing if distance between x2 & x1 is bigger than f_minDistance + if (constraintReleased[index]) return; + + Deriv corr = (x2-x1)*(0.5*velocityFactor*getConstraintFactor(index)); + + x1 += corr; + x2 -= corr; +} + +template +void AttachProjectiveConstraint::doProjectResponse(Deriv& dx1, Deriv& dx2, bool freeRotations, bool twoway, unsigned index, Real responseFactor) +{ + SOFA_UNUSED(freeRotations); + // do nothing if distance between x2 & x1 is bigger than f_minDistance + if (constraintReleased[index]) return; + + if (!twoway) + { + dx2 = Deriv(); + } + else + { + Deriv corr = (dx2-dx1)*0.5*responseFactor*getConstraintFactor(index); + dx1 += corr; + dx2 -= corr; + } +} + + +template +void AttachProjectiveConstraint::draw(const core::visual::VisualParams* vparams) +{ + if (!vparams->displayFlags().getShowBehaviorModels()) + return; + + const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); + vparams->drawTool()->disableLighting(); + + const SetIndexArray & indices1 = f_indices1.getValue(); + const SetIndexArray & indices2 = f_indices2.getValue(); + const VecCoord& x1 = this->mstate1->read(core::ConstVecCoordId::position())->getValue(); + const VecCoord& x2 = this->mstate2->read(core::ConstVecCoordId::position())->getValue(); + + constexpr sofa::type::RGBAColor color1(1,0.5,0.5,1); + std::vector vertices; + + for (unsigned int i=0; i i && !activeFlags[i]) + continue; + vertices.push_back(sofa::type::Vec3(x2[indices2[i]][0],x2[indices2[i]][1],x2[indices2[i]][2])); + } + vparams->drawTool()->drawPoints(vertices,10,color1); + vertices.clear(); + + constexpr sofa::type::RGBAColor color2(1,0.5,0.5,1); + for (unsigned int i=0; i i && !activeFlags[i]) + continue; + vertices.push_back(sofa::type::Vec3(x1[indices1[i]][0],x1[indices1[i]][1],x1[indices1[i]][2])); + vertices.push_back(sofa::type::Vec3(x2[indices2[i]][0],x2[indices2[i]][1],x2[indices2[i]][2])); + } + vparams->drawTool()->drawLines(vertices,1,color2); + +} + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectDirectionConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/DirectionProjectiveConstraint.cpp similarity index 76% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectDirectionConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/DirectionProjectiveConstraint.cpp index 9d956a1949d..2d0a68442dd 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectDirectionConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/DirectionProjectiveConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ProjectDirectionConstraint_CPP -#include +#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_DirectionProjectiveConstraint_CPP +#include #include #include @@ -32,14 +32,13 @@ using namespace sofa::defaulttype; using namespace sofa::helper; -int ProjectDirectionConstraintClass = core::RegisterObject("Attach given particles to their initial positions") - .add< ProjectDirectionConstraint >() - .add< ProjectDirectionConstraint >() - +int DirectionProjectiveConstraintClass = core::RegisterObject("Attach given particles to their initial positions") + .add< DirectionProjectiveConstraint >() + .add< DirectionProjectiveConstraint >() ; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectDirectionConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectDirectionConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API DirectionProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API DirectionProjectiveConstraint; } // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/DirectionProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/DirectionProjectiveConstraint.h new file mode 100644 index 00000000000..29c85fc63e0 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/DirectionProjectiveConstraint.h @@ -0,0 +1,133 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +/// This class can be overridden if needed for additionnal storage within template specializations. +template +class DirectionProjectiveConstraintInternalData +{ + +}; + +/** Project particles to an affine straight line going through the particle original position. +*/ +template +class DirectionProjectiveConstraint : public core::behavior::ProjectiveConstraintSet +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(DirectionProjectiveConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, DataTypes)); + + using Index = sofa::Index; + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::CPos CPos; + typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; + typedef typename MatrixDeriv::RowType MatrixDerivRowType; + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef Data DataMatrixDeriv; + typedef type::vector Indices; + SOFA_ATTRIBUTE_REPLACED__TYPEMEMBER(Vector3, sofa::type::Vec3); + typedef sofa::core::topology::TopologySubsetIndices IndexSubsetData; + typedef linearalgebra::EigenBaseSparseMatrix BaseSparseMatrix; + typedef linearalgebra::EigenSparseMatrix SparseMatrix; + typedef typename SparseMatrix::Block Block; ///< projection matrix of a particle displacement to the plane + enum {bsize=SparseMatrix::Nin}; ///< size of a block + + +protected: + DirectionProjectiveConstraint(); + + virtual ~DirectionProjectiveConstraint(); + +public: + IndexSubsetData f_indices; ///< the particles to project + Data f_drawSize; ///< The size of the square used to display the constrained particles + Data f_direction; ///< The direction of the line. Will be normalized by init() + + /// Link to be set to the topology container in the component graph. + SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; + +protected: + DirectionProjectiveConstraintInternalData* data; + friend class DirectionProjectiveConstraintInternalData; + + type::vector m_origin; + + +public: + void clearConstraints(); + void addConstraint(Index index); + void removeConstraint(Index index); + + // -- Constraint interface + void init() override; + void reinit() override; + + void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; + void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; + void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; + void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; + + void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + + /// Project the given matrix (Experimental API, see the spec in sofa::core::behavior::BaseProjectiveConstraintSet). + void projectMatrix( sofa::linearalgebra::BaseMatrix* /*M*/, unsigned /*offset*/ ) override; + + + void draw(const core::visual::VisualParams* vparams) override; + +protected : + + SparseMatrix jacobian; ///< projection matrix in local state + SparseMatrix J; ///< auxiliary variable +}; + + +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_DirectionProjectiveConstraint_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API DirectionProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API DirectionProjectiveConstraint; +#endif + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/DirectionProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/DirectionProjectiveConstraint.inl new file mode 100644 index 00000000000..77d50d83146 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/DirectionProjectiveConstraint.inl @@ -0,0 +1,277 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + + +namespace sofa::component::constraint::projective +{ + +template +DirectionProjectiveConstraint::DirectionProjectiveConstraint() + : core::behavior::ProjectiveConstraintSet(nullptr) + , f_indices( initData(&f_indices,"indices","Indices of the fixed points") ) + , f_drawSize( initData(&f_drawSize,(SReal)0.0,"drawSize","0 -> point based rendering, >0 -> radius of spheres") ) + , f_direction( initData(&f_direction,CPos(),"direction","Direction of the line")) + , l_topology(initLink("topology", "link to the topology container")) + , data(new DirectionProjectiveConstraintInternalData()) +{ + f_indices.beginEdit()->push_back(0); + f_indices.endEdit(); +} + + +template +DirectionProjectiveConstraint::~DirectionProjectiveConstraint() +{ + delete data; +} + +template +void DirectionProjectiveConstraint::clearConstraints() +{ + f_indices.beginEdit()->clear(); + f_indices.endEdit(); +} + +template +void DirectionProjectiveConstraint::addConstraint(Index index) +{ + f_indices.beginEdit()->push_back(index); + f_indices.endEdit(); +} + +template +void DirectionProjectiveConstraint::removeConstraint(Index index) +{ + sofa::type::removeValue(*f_indices.beginEdit(),index); + f_indices.endEdit(); +} + +// -- Constraint interface + + +template +void DirectionProjectiveConstraint::init() +{ + this->core::behavior::ProjectiveConstraintSet::init(); + + if (l_topology.empty()) + { + msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; + l_topology.set(this->getContext()->getMeshTopologyLink()); + } + + + if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) + { + msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; + + // Initialize topological changes support + f_indices.createTopologyHandler(_topology); + } + else + { + msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; + } + + const Indices & indices = f_indices.getValue(); + + const Index maxIndex=this->mstate->getSize(); + for (unsigned int i=0; i= maxIndex) + { + msg_error() << "Index " << index << " not valid!"; + removeConstraint(index); + } + } + + reinit(); +} + +template +void DirectionProjectiveConstraint::reinit() +{ + // normalize the normal vector + CPos n = f_direction.getValue(); + if( n.norm()==0 ) + n[1]=0; + else n *= 1/n.norm(); + f_direction.setValue(n); + + // create the matrix blocks corresponding to the projection to the line: nn^t or to the identity + Block bProjection; + for(unsigned i=0; imstate->getSize(); + const unsigned blockSize = DataTypes::deriv_total_size; + jacobian.resize( numBlocks*blockSize,numBlocks*blockSize ); + + // fill the jacobian in ascending order + Indices::const_iterator it = tmp.begin(); + unsigned i = 0; + while( i < numBlocks ) + { + if( it != tmp.end() && i==*it ) // constrained particle: set diagonal to projection block, and the cursor to the next constraint + { + jacobian.insertBackBlock(i,i,bProjection); + ++it; + } + else // unconstrained particle: set diagonal to identity block + { + jacobian.insertBackBlock(i,i,Block::Identity()); + } + i++; + } + jacobian.compress(); + + const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); + const Indices &indices = f_indices.getValue(); + for (const auto id : indices) + { + m_origin.push_back(DataTypes::getCPos(x[id])); + } + +} + +template +void DirectionProjectiveConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) +{ + J.copy(jacobian, M->colSize(), offset); // projection matrix for an assembled state + BaseSparseMatrix* E = dynamic_cast(M); + assert(E); + E->compressedMatrix = J.compressedMatrix * E->compressedMatrix * J.compressedMatrix; +} + + + +template +void DirectionProjectiveConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) +{ + SOFA_UNUSED(mparams); + + helper::WriteAccessor res ( resData ); + jacobian.mult(res.wref(),res.ref()); +} + +template +void DirectionProjectiveConstraint::projectJacobianMatrix(const core::MechanicalParams* /*mparams*/ , DataMatrixDeriv& /*cData*/) +{ + msg_error() << "projectJacobianMatrix(const core::MechanicalParams*, DataMatrixDeriv& ) is not implemented"; +} + +template +void DirectionProjectiveConstraint::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) +{ + projectResponse(mparams,vData); +} + +template +void DirectionProjectiveConstraint::projectPosition(const core::MechanicalParams* /*mparams*/ , DataVecCoord& xData) +{ + VecCoord& x = *xData.beginEdit(); + + const CPos& n = f_direction.getValue(); + + const Indices& indices = f_indices.getValue(); + for(unsigned i=0; i +void DirectionProjectiveConstraint::applyConstraint(const core::MechanicalParams* /*mparams*/, const sofa::core::behavior::MultiMatrixAccessor* /*matrix*/) +{ + msg_error() << "applyConstraint is not implemented"; +} + +template +void DirectionProjectiveConstraint::applyConstraint(const core::MechanicalParams* /*mparams*/, linearalgebra::BaseVector* /*vector*/, const sofa::core::behavior::MultiMatrixAccessor* /*matrix*/) +{ + dmsg_error() << "DirectionProjectiveConstraint::applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) is not implemented"; +} + + + + +template +void DirectionProjectiveConstraint::draw(const core::visual::VisualParams* vparams) +{ + if (!vparams->displayFlags().getShowBehaviorModels()) return; + if (!this->isActive()) return; + const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); + + const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); + + const Indices & indices = f_indices.getValue(); + + if( f_drawSize.getValue() == 0) // old classical drawing by points + { + std::vector< sofa::type::Vec3 > points; + sofa::type::Vec3 point; + for (unsigned int index : indices) + { + point = DataTypes::getCPos(x[index]); + points.push_back(point); + } + vparams->drawTool()->drawPoints(points, 10, sofa::type::RGBAColor(1,0.5,0.5,1)); + } + else // new drawing by spheres + { + std::vector< sofa::type::Vec3 > points; + sofa::type::Vec3 point; + for (unsigned int index : indices) + { + point = DataTypes::getCPos(x[index]); + points.push_back(point); + } + vparams->drawTool()->drawSpheres(points, (float)f_drawSize.getValue(), sofa::type::RGBAColor(1.0f,0.35f,0.35f,1.0f)); + } + + +} + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedConstraint.h index 7c83fb40cb8..1ddf32be894 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedConstraint.h @@ -20,119 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -/// This class can be overridden if needed for additionnal storage within template specializations. -template -class FixedConstraintInternalData -{ +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/FixedProjectiveConstraint.h") -}; - - -/** Maintain a constant velocity. - * If the particle is initially fixed then it is attached to its initial position. - * Otherwise it keeps on drifting. - * For maintaining particles fixed in any case, @sa ProjectToPointConstraint -*/ -template -class FixedConstraint : public core::behavior::ProjectiveConstraintSet +namespace sofa::component::constraint::projective { -public: - SOFA_CLASS(SOFA_TEMPLATE(FixedConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, DataTypes)); - - using Index = sofa::Index; - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; - typedef typename MatrixDeriv::RowType MatrixDerivRowType; - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef Data DataMatrixDeriv; - typedef type::vector SetIndexArray; - typedef sofa::core::topology::TopologySubsetIndices SetIndex; - typedef sofa::core::topology::Point Point; - - SOFA_ATTRIBUTE_REPLACED__TYPEMEMBER(Vec3, sofa::type::Vec3); -protected: - FixedConstraint(); - - virtual ~FixedConstraint(); - -public: - SetIndex d_indices; - Data d_fixAll; ///< filter all the DOF to implement a fixed object - Data d_showObject; ///< draw or not the fixed constraints - Data d_drawSize; ///< 0 -> point based rendering, >0 -> radius of spheres - Data d_projectVelocity; ///< activate project velocity to set velocity to zero - - /// Link to be set to the topology container in the component graph. - SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; -protected: - FixedConstraintInternalData* data; - friend class FixedConstraintInternalData; - - -public: - void clearConstraints(); - void addConstraint(Index index); - void removeConstraint(Index index); - - // -- Constraint interface - void init() override; - void reinit() override; - - void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; - void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; - void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; - void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; - - - void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vect, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - - /** Project the given matrix (Experimental API). - See doc in base parent class - */ - void projectMatrix( sofa::linearalgebra::BaseMatrix* /*M*/, unsigned /*offset*/ ) override; - - void applyConstraint(sofa::core::behavior::ZeroDirichletCondition* matrix) override; - - void draw(const core::visual::VisualParams* vparams) override; - - bool fixAllDOFs() const { return d_fixAll.getValue(); } - -protected : - /// Function check values of given indices - void checkIndices(); - -}; - -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDCONSTRAINT_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedConstraint; - -#endif - -} // namespace sofa::component::constraint::projective +template +using FixedConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "FixedConstraint has been renamed to FixedProjectiveConstraint") = FixedProjectiveConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedConstraint.inl index 23fcc61269d..4244fcd3b94 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedConstraint.inl @@ -21,406 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include +#include -using sofa::core::objectmodel::ComponentState; - - -namespace sofa::component::constraint::projective -{ - -template -FixedConstraint::FixedConstraint() - : core::behavior::ProjectiveConstraintSet(nullptr) - , d_indices( initData(&d_indices,"indices","Indices of the fixed points") ) - , d_fixAll( initData(&d_fixAll,false,"fixAll","filter all the DOF to implement a fixed object") ) - , d_showObject(initData(&d_showObject,true,"showObject","draw or not the fixed constraints")) - , d_drawSize( initData(&d_drawSize,(SReal)0.0,"drawSize","0 -> point based rendering, >0 -> radius of spheres") ) - , d_projectVelocity( initData(&d_projectVelocity,false,"activate_projectVelocity","activate project velocity to set velocity") ) - , l_topology(initLink("topology", "link to the topology container")) - , data(new FixedConstraintInternalData()) -{ - // default to indice 0 - d_indices.beginEdit()->push_back(0); - d_indices.endEdit(); - - this->addUpdateCallback("updateIndices", { &d_indices}, [this](const core::DataTracker& t) - { - SOFA_UNUSED(t); - checkIndices(); - return sofa::core::objectmodel::ComponentState::Valid; - }, {}); -} - - -template -FixedConstraint::~FixedConstraint() -{ - delete data; -} - -template -void FixedConstraint::clearConstraints() -{ - d_indices.beginEdit()->clear(); - d_indices.endEdit(); -} - -template -void FixedConstraint::addConstraint(Index index) -{ - d_indices.beginEdit()->push_back(index); - d_indices.endEdit(); -} - -template -void FixedConstraint::removeConstraint(Index index) -{ - sofa::type::removeValue(*d_indices.beginEdit(),index); - d_indices.endEdit(); -} - -// -- Constraint interface - - -template -void FixedConstraint::init() -{ - this->d_componentState.setValue(ComponentState::Invalid); - this->core::behavior::ProjectiveConstraintSet::init(); - - if (!this->mstate.get()) - { - msg_warning() << "Missing mstate, cannot initialize the component."; - return; - } - - if (l_topology.empty()) - { - msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; - l_topology.set(this->getContext()->getMeshTopologyLink()); - } - - if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) - { - msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; - - // Initialize topological changes support - d_indices.createTopologyHandler(_topology); - } - else - { - msg_info() << "Can not find the topology, won't be able to handle topological changes"; - } - - this->checkIndices(); - this->d_componentState.setValue(ComponentState::Valid); -} - -template -void FixedConstraint::reinit() -{ - this->checkIndices(); -} - -template -void FixedConstraint::checkIndices() -{ - // Check value of given indices - Index maxIndex=this->mstate->getSize(); - - const SetIndexArray & indices = d_indices.getValue(); - SetIndexArray invalidIndices; - for (unsigned int i=0; i= maxIndex) - { - msg_warning() << "Index " << index << " not valid, should be [0,"<< maxIndex <<"]. Constraint will be removed."; - invalidIndices.push_back(index); - } - } - - // if invalid indices, sort them and remove in decreasing order as removeConstraint perform a swap and pop_back. - if (!invalidIndices.empty()) - { - std::sort( invalidIndices.begin(), invalidIndices.end(), std::greater() ); - const int max = invalidIndices.size()-1; - for (int i=max; i>= 0; i--) - { - removeConstraint(invalidIndices[i]); - } - } -} - -template -void FixedConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) -{ - static const unsigned blockSize = DataTypes::deriv_total_size; - - if( d_fixAll.getValue() ) - { - const unsigned size = this->mstate->getSize(); - for( unsigned i=0; iclearRowsCols( offset + i * blockSize, offset + (i+1) * (blockSize) ); - } - } - else - { - // clears the rows and columns associated with fixed particles - for (const auto id : d_indices.getValue()) - { - M->clearRowsCols( offset + id * blockSize, offset + (id+1) * blockSize ); - } - } -} - - -template -void FixedConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) -{ - SOFA_UNUSED(mparams); - - helper::WriteAccessor res (resData ); - const SetIndexArray & indices = d_indices.getValue(); - - if( d_fixAll.getValue() ) - { - // fix everything - typename VecDeriv::iterator it; - for( it = res.begin(); it != res.end(); ++it ) - { - *it = Deriv(); - } - } - else - { - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - res[*it] = Deriv(); - } - } -} - -template -void FixedConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) -{ - SOFA_UNUSED(mparams); - - helper::WriteAccessor c (cData ); - - if( d_fixAll.getValue() ) - { - // fix everything - c->clear(); - } - else - { - const SetIndexArray& indices = d_indices.getValue(); - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - c->clearColBlock(*it); - } - } -} - -// projectVelocity applies the same changes on velocity vector as projectResponse on position vector : -// Each fixed point received a null velocity vector. -// When a new fixed point is added while its velocity vector is already null, projectVelocity is not usefull. -// But when a new fixed point is added while its velocity vector is not null, it's necessary to fix it to null or -// to set the projectVelocity option to True. If not, the fixed point is going to drift. -template -void FixedConstraint::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) -{ - SOFA_UNUSED(mparams); - - if(!d_projectVelocity.getValue()) return; - - helper::WriteAccessor res (vData ); - - if ( d_fixAll.getValue() ) // fix everyting - { - for(Size i=0; id_indices.getValue(); - for(Index ind : indices) - { - res[ind] = Deriv(); - } - } -} - - -template -void FixedConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& /*xData*/) -{ - -} - -// Matrix Integration interface -template -void FixedConstraint::applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) -{ - SOFA_UNUSED(mparams); - if(const core::behavior::MultiMatrixAccessor::MatrixRef r = matrix->getMatrix(this->mstate.get())) - { - const unsigned int N = Deriv::size(); - - if( d_fixAll.getValue() ) - { - const unsigned size = this->mstate->getSize(); - for(unsigned int i=0; iclearRowCol(r.offset + N * i + c); - // Set Fixed Vertex - for (unsigned int c=0; cset(r.offset + N * i + c, r.offset + N * i + c, 1.0); - } - } - else - { - const SetIndexArray & indices = d_indices.getValue(); - - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - // Reset Fixed Row and Col - for (unsigned int c=0; cclearRowCol(r.offset + N * (*it) + c); - // Set Fixed Vertex - for (unsigned int c=0; cset(r.offset + N * (*it) + c, r.offset + N * (*it) + c, 1.0); - } - } - } -} - -template -void FixedConstraint::applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vect, const sofa::core::behavior::MultiMatrixAccessor* matrix) -{ - SOFA_UNUSED(mparams); - const int o = matrix->getGlobalOffset(this->mstate.get()); - if (o >= 0) - { - const unsigned int offset = (unsigned int)o; - const unsigned int N = Deriv::size(); - - if( d_fixAll.getValue() ) - { - for(sofa::Size i=0; i < (sofa::Size) vect->size(); i++ ) - { - for (unsigned int c=0; cclear(offset + N * i + c); - } - } - else - { - const SetIndexArray & indices = d_indices.getValue(); - for (const auto & index : indices) - { - for (unsigned int c=0; cclear(offset + N * index + c); - } - } - } -} - -template -void FixedConstraint::applyConstraint(sofa::core::behavior::ZeroDirichletCondition* matrix) -{ - static constexpr unsigned int N = Deriv::size(); - - if( d_fixAll.getValue() ) - { - const sofa::Size size = this->mstate->getMatrixSize(); - for(sofa::Index i = 0; i < size; ++i) - { - matrix->discardRowCol(i, i); - } - } - else - { - const SetIndexArray & indices = d_indices.getValue(); - - for (const auto index : indices) - { - for (unsigned int c = 0; c < N; ++c) - { - matrix->discardRowCol(N * index + c, N * index + c); - } - } - } -} - -template -void FixedConstraint::draw(const core::visual::VisualParams* vparams) -{ - if (this->d_componentState.getValue() != ComponentState::Valid) return; - if (!vparams->displayFlags().getShowBehaviorModels()) return; - if (!d_showObject.getValue()) return; - if (!this->isActive()) return; - - const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); - - const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); - const SetIndexArray & indices = d_indices.getValue(); - - if( d_drawSize.getValue() == 0) // old classical drawing by points - { - std::vector< sofa::type::Vec3 > points; - sofa::type::Vec3 point; - - if (d_fixAll.getValue()) - { - for (unsigned i = 0; i < x.size(); i++) - { - point = DataTypes::getCPos(x[i]); - points.push_back(point); - } - } - else - { - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - point = DataTypes::getCPos(x[*it]); - points.push_back(point); - } - } - vparams->drawTool()->drawPoints(points, 10, sofa::type::RGBAColor(1,0.5,0.5,1)); - } - else // new drawing by spheres - { - vparams->drawTool()->setLightingEnabled(true); - - std::vector< sofa::type::Vec3 > points; - sofa::type::Vec3 point; - if( d_fixAll.getValue()==true ) - for (unsigned i=0; idrawTool()->drawSpheres(points, (float)d_drawSize.getValue(), sofa::type::RGBAColor(1.0f,0.35f,0.35f,1.0f)); - } - - -} - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/FixedProjectiveConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneConstraint.h index d6b7e177dd0..8848ba55069 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneConstraint.h @@ -20,117 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include +#include -#include -#include -#include -#include +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/FixedPlaneProjectiveConstraint.h") namespace sofa::component::constraint::projective { - -using sofa::linearalgebra::BaseVector; -using sofa::core::MechanicalParams; -using sofa::core::visual::VisualParams; -using sofa::core::topology::BaseMeshTopology; -using sofa::core::behavior::MultiMatrixAccessor; -using sofa::core::behavior::ProjectiveConstraintSet; - -/// This class can be overriden if needed for additionnal storage within template specilizations. -template -class FixedPlaneConstraintInternalData -{ -}; - -template -class FixedPlaneConstraint : public ProjectiveConstraintSet -{ -public: - SOFA_CLASS(SOFA_TEMPLATE(FixedPlaneConstraint,DataTypes), - SOFA_TEMPLATE(ProjectiveConstraintSet, DataTypes)); - - using Index = sofa::Index; - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename Coord::value_type Real; - typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; - typedef typename MatrixDeriv::RowType MatrixDerivRowType; - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef Data DataMatrixDeriv; - typedef type::vector SetIndexArray; - typedef core::topology::TopologySubsetIndices SetIndex; -public: - Data d_direction; ///< direction on which the constraint applied - Data d_dmin; ///< coordinates min of the plane for the vertex selection - Data d_dmax; ///< coordinates max of the plane for the vertex selection - SetIndex d_indices; ///< the set of vertex indices - - /// Link to be set to the topology container in the component graph. - SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; - - - /// inherited from the BaseObject interface - void init() override; - void draw(const VisualParams* vparams) override; - - /// -- Constraint interface - void projectResponse(const MechanicalParams* mparams, DataVecDeriv& resData) override; - void projectVelocity(const MechanicalParams* mparams, DataVecDeriv& vData) override; - void projectPosition(const MechanicalParams* mparams, DataVecCoord& xData) override; - - /// Implement projectMatrix for assembled solver of compliant - void projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset) override; - void projectJacobianMatrix(const MechanicalParams* mparams, DataMatrixDeriv& cData) override; - - /// Implement applyConstraint for direct solvers - void applyConstraint(const MechanicalParams* mparams, - const MultiMatrixAccessor* matrix) override; - - void applyConstraint(const MechanicalParams* mparams, BaseVector* vect, - const MultiMatrixAccessor* matrix) override; - - void applyConstraint(sofa::core::behavior::ZeroDirichletCondition* matrix) override; - - void setDirection (Coord dir); - void selectVerticesAlongPlane(); - void setDminAndDmax(const Real _dmin,const Real _dmax); - - void addConstraint(Index index); - void removeConstraint(Index index); - -protected: - FixedPlaneConstraint(); - ~FixedPlaneConstraint(); - - FixedPlaneConstraintInternalData data; - friend class FixedPlaneConstraintInternalData; - - /// whether vertices should be selected from 2 parallel planes - bool m_selectVerticesFromPlanes {false}; - - ////////////////////////// Inherited attributes //////////////////////////// - /// https://gcc.gnu.org/onlinedocs/gcc/Name-lookup.html - /// Bring inherited attributes and function in the current lookup context. - /// otherwise any access to the base::attribute would require - /// the "this->" approach. - using ProjectiveConstraintSet::mstate; - using ProjectiveConstraintSet::getContext; - - bool isPointInPlane(const Coord& p) const ; -}; - -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDPLANECONSTRAINT_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedPlaneConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedPlaneConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedPlaneConstraint; - -#endif - -} // namespace sofa::component::constraint::projective +template +using FixedPlaneConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "FixedPlaneConstraint has been renamed to FixedPlaneProjectiveConstraint") = FixedPlaneProjectiveConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneConstraint.inl index 9c8dad30165..34acfcbe022 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneConstraint.inl @@ -21,297 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -using sofa::helper::WriteAccessor; -using sofa::type::Vec; - -/////////////////////////// DEFINITION OF FixedPlaneConstraint ///////////////////////////////////// -template -FixedPlaneConstraint::FixedPlaneConstraint() - : d_direction( initData(&d_direction,"direction","normal direction of the plane")) - , d_dmin( initData(&d_dmin,(Real)0,"dmin","Minimum plane distance from the origin")) - , d_dmax( initData(&d_dmax,(Real)0,"dmax","Maximum plane distance from the origin") ) - , d_indices( initData(&d_indices,"indices","Indices of the fixed points")) - , l_topology(initLink("topology", "link to the topology container")) -{ - m_selectVerticesFromPlanes=false; -} - -template -FixedPlaneConstraint::~FixedPlaneConstraint() -{ - -} - -/// Matrix Integration interface -template -void FixedPlaneConstraint::applyConstraint(const MechanicalParams* mparams, const MultiMatrixAccessor* matrix) -{ - SOFA_UNUSED(mparams); - if(const MultiMatrixAccessor::MatrixRef r = matrix->getMatrix(mstate.get())) - { - /// Implement plane constraint only when the direction is along the coordinates directions - // TODO : generalize projection to any direction - - const unsigned int N = Deriv::size(); - Coord dir=d_direction.getValue(); - for (auto& index : d_indices.getValue()) - { - /// Reset Fixed Row and Col - for (unsigned int c=0; cclearRowCol(r.offset + N * index + c); - /// Set Fixed Vertex - for (unsigned int c=0; cset(r.offset + N * index + c, r.offset + N * index + c, 1.0); - } - } -} - -template -void FixedPlaneConstraint::applyConstraint(const MechanicalParams* mparams, - BaseVector* vect, - const MultiMatrixAccessor* matrix) -{ - SOFA_UNUSED(mparams); - const int o = matrix->getGlobalOffset(mstate.get()); - if (o >= 0) - { - const unsigned int offset = (unsigned int)o; - /// Implement plane constraint only when the direction is along the coordinates directions - // TODO : generalize projection to any direction - Coord dir=d_direction.getValue(); - - const unsigned int N = Deriv::size(); - - for (auto& index : d_indices.getValue()) - { - for (unsigned int c=0; cclear(offset + N * index + c); - } - } -} - -template -void FixedPlaneConstraint::applyConstraint( - sofa::core::behavior::ZeroDirichletCondition* matrix) -{ - static constexpr unsigned int N = Deriv::size(); - const Coord dir = d_direction.getValue(); - for (auto& index : d_indices.getValue()) - { - for (unsigned int c=0; cdiscardRowCol(N * index + c, N * index + c); - } - } - } -} - -template -void FixedPlaneConstraint::addConstraint(Index index) -{ - d_indices.beginEdit()->push_back(index); - d_indices.endEdit(); -} - -template -void FixedPlaneConstraint::removeConstraint(Index index) -{ - sofa::type::removeValue(*d_indices.beginEdit(),(unsigned int)index); - d_indices.endEdit(); -} - - -/// This function are there to provide kind of type translation to the vector one so we can -/// implement the algorithm as is the different objects where of similar type. -/// this solution is not really satisfactory but for the moment it does the job. -/// A better solution would that all the used types are following the same interface which -/// requires to touch core sofa classes. -sofa::type::Vec3d& getVec(sofa::defaulttype::Rigid3dTypes::Deriv& i) { return i.getVCenter(); } -sofa::type::Vec3d& getVec(sofa::defaulttype::Rigid3dTypes::Coord& i) { return i.getCenter(); } -const sofa::type::Vec3d& getVec(const sofa::defaulttype::Rigid3dTypes::Deriv& i) { return i.getVCenter(); } -const sofa::type::Vec3d& getVec(const sofa::defaulttype::Rigid3dTypes::Coord& i) { return i.getCenter(); } -sofa::type::Vec3d& getVec(sofa::defaulttype::Vec3dTypes::Deriv& i) { return i; } -const sofa::type::Vec3d& getVec(const sofa::defaulttype::Vec3dTypes::Deriv& i) { return i; } -sofa::type::Vec6d& getVec(sofa::defaulttype::Vec6dTypes::Deriv& i) { return i; } -const sofa::type::Vec6d& getVec(const sofa::defaulttype::Vec6dTypes::Deriv& i) { return i; } - -sofa::type::Vec3f& getVec(sofa::defaulttype::Rigid3fTypes::Deriv& i) { return i.getVCenter(); } -sofa::type::Vec3f& getVec(sofa::defaulttype::Rigid3fTypes::Coord& i) { return i.getCenter(); } -const sofa::type::Vec3f& getVec(const sofa::defaulttype::Rigid3fTypes::Deriv& i) { return i.getVCenter(); } -const sofa::type::Vec3f& getVec(const sofa::defaulttype::Rigid3fTypes::Coord& i) { return i.getCenter(); } -sofa::type::Vec3f& getVec(sofa::defaulttype::Vec3fTypes::Deriv& i) { return i; } -const sofa::type::Vec3f& getVec(const sofa::defaulttype::Vec3fTypes::Deriv& i) { return i; } -sofa::type::Vec6f& getVec(sofa::defaulttype::Vec6fTypes::Deriv& i) { return i; } -const sofa::type::Vec6f& getVec(const sofa::defaulttype::Vec6fTypes::Deriv& i) { return i; } - -template -void FixedPlaneConstraint::projectResponse(const MechanicalParams* mparams, DataVecDeriv& resData) -{ - SOFA_UNUSED(mparams); - WriteAccessor res = resData; - - const auto& indices = d_indices.getValue(); - const auto& dir = getVec(d_direction.getValue()); - auto& dx = res.wref(); - for (const auto& i : indices) - { - /// only constraint one projection of the displacement to be zero - auto val = getVec(dx[i]); - val = val - (dir * dot(val, dir)); - DataTypes::setDPos(dx[i], val); - } -} - -/// project dx to constrained space (dx models a velocity) -template -void FixedPlaneConstraint::projectVelocity(const MechanicalParams* /*mparams*/, DataVecDeriv& /*vData*/) -{ - -} - -/// project x to constrained space (x models a position) -template -void FixedPlaneConstraint::projectPosition(const MechanicalParams* /*mparams*/, DataVecCoord& /*xData*/) -{ - -} - -template -void FixedPlaneConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned /*offset*/ ) -{ - /// clears the rows and columns associated with constrained particles - const unsigned blockSize = DataTypes::deriv_total_size; - - for(auto& index : d_indices.getValue()) - { - M->clearRowsCols((index) * blockSize,(index+1) * (blockSize) ); - } -} - -template -void FixedPlaneConstraint::projectJacobianMatrix(const MechanicalParams* mparams, DataMatrixDeriv& cData) -{ - SOFA_UNUSED(mparams); - WriteAccessor c = cData; - - const auto& indices = d_indices.getValue(); - const auto& dir = getVec(d_direction.getValue()); - auto& dx = c.wref(); - - auto itRow = dx.begin(); - auto itRowEnd = dx.end(); - while (itRow != itRowEnd) - { - for (auto colIt = itRow.begin(); colIt != itRow.end(); colIt++) - { - if (std::find(indices.begin(), indices.end(), colIt.index()) != indices.end()) - { - auto val = getVec(colIt.val()); - Deriv r(type::NOINIT); - DataTypes::setDPos(r, -(dir * dot(val, dir))); - dx.writeLine(itRow.index()).addCol(colIt.index(), r); - } - } - } -} - -template -void FixedPlaneConstraint::setDirection(Coord dir) -{ - if (dir.norm2()>0) - { - d_direction.setValue(dir); - } -} - -template -void FixedPlaneConstraint::selectVerticesAlongPlane() -{ - const VecCoord& x = mstate->read(core::ConstVecCoordId::position())->getValue(); - for(unsigned int i=0; i -void FixedPlaneConstraint::init() -{ - ProjectiveConstraintSet::init(); - - if (l_topology.empty()) - { - msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; - l_topology.set(this->getContext()->getMeshTopologyLink()); - } - - if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) - { - msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; - - // Initialize topological changes support - d_indices.createTopologyHandler(_topology); - } - else - { - msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; - } - - /// test that dmin or dmax are different from zero - if (d_dmin.getValue()!=d_dmax.getValue()) - m_selectVerticesFromPlanes=true; - - if (m_selectVerticesFromPlanes) - selectVerticesAlongPlane(); -} - -template -void FixedPlaneConstraint::setDminAndDmax(const Real _dmin,const Real _dmax) -{ - d_dmin=_dmin; - d_dmax=_dmax; - m_selectVerticesFromPlanes=true; -} - -template -void FixedPlaneConstraint::draw(const VisualParams* vparams) -{ - if (!vparams->displayFlags().getShowBehaviorModels()) return; - const VecCoord& x = mstate->read(core::ConstVecCoordId::position())->getValue(); - vparams->drawTool()->disableLighting(); - - type::vector points; - for(auto& index : d_indices.getValue()) - { - points.push_back({x[index][0], x[index][1], x[index][2]}); - } - - vparams->drawTool()->drawPoints(points, 10, sofa::type::RGBAColor{1,1.0,0.5,1}); -} - -template -bool FixedPlaneConstraint::isPointInPlane(const Coord& p) const -{ - const Real d = getVec(p) * getVec(d_direction.getValue()); - return d > d_dmin.getValue() && d < d_dmax.getValue(); -} - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/FixedPlaneProjectiveConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneProjectiveConstraint.cpp similarity index 78% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneProjectiveConstraint.cpp index 725d791f612..ab9c9e49cc6 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneProjectiveConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDPLANECONSTRAINT_CPP -#include +#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDPLANEPROJECTIVECONSTRAINT_CPP +#include #include #include #include @@ -32,15 +32,15 @@ using namespace sofa::defaulttype; using namespace sofa::helper; -int FixedPlaneConstraintClass = core::RegisterObject("Project particles on a given plane") - .add< FixedPlaneConstraint >() - .add< FixedPlaneConstraint >() - .add< FixedPlaneConstraint >() +int FixedPlaneProjectiveConstraintClass = core::RegisterObject("Project particles on a given plane") + .add< FixedPlaneProjectiveConstraint >() + .add< FixedPlaneProjectiveConstraint >() + .add< FixedPlaneProjectiveConstraint >() ; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedPlaneConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedPlaneConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedPlaneConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedPlaneProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedPlaneProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedPlaneProjectiveConstraint; } // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneProjectiveConstraint.h new file mode 100644 index 00000000000..6885db83f9e --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneProjectiveConstraint.h @@ -0,0 +1,135 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include + +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +using sofa::linearalgebra::BaseVector; +using sofa::core::MechanicalParams; +using sofa::core::visual::VisualParams; +using sofa::core::topology::BaseMeshTopology; +using sofa::core::behavior::MultiMatrixAccessor; +using sofa::core::behavior::ProjectiveConstraintSet; + +/// This class can be overriden if needed for additionnal storage within template specilizations. +template +class FixedPlaneProjectiveConstraintInternalData +{ +}; + +template +class FixedPlaneProjectiveConstraint : public ProjectiveConstraintSet +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(FixedPlaneProjectiveConstraint,DataTypes), + SOFA_TEMPLATE(ProjectiveConstraintSet, DataTypes)); + + using Index = sofa::Index; + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename Coord::value_type Real; + typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; + typedef typename MatrixDeriv::RowType MatrixDerivRowType; + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef Data DataMatrixDeriv; + typedef type::vector SetIndexArray; + typedef core::topology::TopologySubsetIndices SetIndex; +public: + Data d_direction; ///< direction on which the constraint applied + Data d_dmin; ///< coordinates min of the plane for the vertex selection + Data d_dmax; ///< coordinates max of the plane for the vertex selection + SetIndex d_indices; ///< the set of vertex indices + + /// Link to be set to the topology container in the component graph. + SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; + + + /// inherited from the BaseObject interface + void init() override; + void draw(const VisualParams* vparams) override; + + /// -- Constraint interface + void projectResponse(const MechanicalParams* mparams, DataVecDeriv& resData) override; + void projectVelocity(const MechanicalParams* mparams, DataVecDeriv& vData) override; + void projectPosition(const MechanicalParams* mparams, DataVecCoord& xData) override; + + /// Implement projectMatrix for assembled solver of compliant + void projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset) override; + void projectJacobianMatrix(const MechanicalParams* mparams, DataMatrixDeriv& cData) override; + + /// Implement applyConstraint for direct solvers + void applyConstraint(const MechanicalParams* mparams, + const MultiMatrixAccessor* matrix) override; + + void applyConstraint(const MechanicalParams* mparams, BaseVector* vect, + const MultiMatrixAccessor* matrix) override; + + void applyConstraint(sofa::core::behavior::ZeroDirichletCondition* matrix) override; + + void setDirection (Coord dir); + void selectVerticesAlongPlane(); + void setDminAndDmax(const Real _dmin,const Real _dmax); + + void addConstraint(Index index); + void removeConstraint(Index index); + +protected: + FixedPlaneProjectiveConstraint(); + ~FixedPlaneProjectiveConstraint(); + + FixedPlaneProjectiveConstraintInternalData data; + friend class FixedPlaneProjectiveConstraintInternalData; + + /// whether vertices should be selected from 2 parallel planes + bool m_selectVerticesFromPlanes {false}; + + ////////////////////////// Inherited attributes //////////////////////////// + /// https://gcc.gnu.org/onlinedocs/gcc/Name-lookup.html + /// Bring inherited attributes and function in the current lookup context. + /// otherwise any access to the base::attribute would require + /// the "this->" approach. + using ProjectiveConstraintSet::mstate; + using ProjectiveConstraintSet::getContext; + + bool isPointInPlane(const Coord& p) const ; +}; + +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDPLANEPROJECTIVECONSTRAINT_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedPlaneProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedPlaneProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedPlaneProjectiveConstraint; +#endif + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneProjectiveConstraint.inl new file mode 100644 index 00000000000..49b29b03583 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedPlaneProjectiveConstraint.inl @@ -0,0 +1,317 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +using sofa::helper::WriteAccessor; +using sofa::type::Vec; + +/////////////////////////// DEFINITION OF FixedPlaneProjectiveConstraint ///////////////////////////////////// +template +FixedPlaneProjectiveConstraint::FixedPlaneProjectiveConstraint() + : d_direction( initData(&d_direction,"direction","normal direction of the plane")) + , d_dmin( initData(&d_dmin,(Real)0,"dmin","Minimum plane distance from the origin")) + , d_dmax( initData(&d_dmax,(Real)0,"dmax","Maximum plane distance from the origin") ) + , d_indices( initData(&d_indices,"indices","Indices of the fixed points")) + , l_topology(initLink("topology", "link to the topology container")) +{ + m_selectVerticesFromPlanes=false; +} + +template +FixedPlaneProjectiveConstraint::~FixedPlaneProjectiveConstraint() +{ + +} + +/// Matrix Integration interface +template +void FixedPlaneProjectiveConstraint::applyConstraint(const MechanicalParams* mparams, const MultiMatrixAccessor* matrix) +{ + SOFA_UNUSED(mparams); + if(const MultiMatrixAccessor::MatrixRef r = matrix->getMatrix(mstate.get())) + { + /// Implement plane constraint only when the direction is along the coordinates directions + // TODO : generalize projection to any direction + + const unsigned int N = Deriv::size(); + Coord dir=d_direction.getValue(); + for (auto& index : d_indices.getValue()) + { + /// Reset Fixed Row and Col + for (unsigned int c=0; cclearRowCol(r.offset + N * index + c); + /// Set Fixed Vertex + for (unsigned int c=0; cset(r.offset + N * index + c, r.offset + N * index + c, 1.0); + } + } +} + +template +void FixedPlaneProjectiveConstraint::applyConstraint(const MechanicalParams* mparams, + BaseVector* vect, + const MultiMatrixAccessor* matrix) +{ + SOFA_UNUSED(mparams); + const int o = matrix->getGlobalOffset(mstate.get()); + if (o >= 0) + { + const unsigned int offset = (unsigned int)o; + /// Implement plane constraint only when the direction is along the coordinates directions + // TODO : generalize projection to any direction + Coord dir=d_direction.getValue(); + + const unsigned int N = Deriv::size(); + + for (auto& index : d_indices.getValue()) + { + for (unsigned int c=0; cclear(offset + N * index + c); + } + } +} + +template +void FixedPlaneProjectiveConstraint::applyConstraint( + sofa::core::behavior::ZeroDirichletCondition* matrix) +{ + static constexpr unsigned int N = Deriv::size(); + const Coord dir = d_direction.getValue(); + for (auto& index : d_indices.getValue()) + { + for (unsigned int c=0; cdiscardRowCol(N * index + c, N * index + c); + } + } + } +} + +template +void FixedPlaneProjectiveConstraint::addConstraint(Index index) +{ + d_indices.beginEdit()->push_back(index); + d_indices.endEdit(); +} + +template +void FixedPlaneProjectiveConstraint::removeConstraint(Index index) +{ + sofa::type::removeValue(*d_indices.beginEdit(),(unsigned int)index); + d_indices.endEdit(); +} + + +/// This function are there to provide kind of type translation to the vector one so we can +/// implement the algorithm as is the different objects where of similar type. +/// this solution is not really satisfactory but for the moment it does the job. +/// A better solution would that all the used types are following the same interface which +/// requires to touch core sofa classes. +sofa::type::Vec3d& getVec(sofa::defaulttype::Rigid3dTypes::Deriv& i) { return i.getVCenter(); } +sofa::type::Vec3d& getVec(sofa::defaulttype::Rigid3dTypes::Coord& i) { return i.getCenter(); } +const sofa::type::Vec3d& getVec(const sofa::defaulttype::Rigid3dTypes::Deriv& i) { return i.getVCenter(); } +const sofa::type::Vec3d& getVec(const sofa::defaulttype::Rigid3dTypes::Coord& i) { return i.getCenter(); } +sofa::type::Vec3d& getVec(sofa::defaulttype::Vec3dTypes::Deriv& i) { return i; } +const sofa::type::Vec3d& getVec(const sofa::defaulttype::Vec3dTypes::Deriv& i) { return i; } +sofa::type::Vec6d& getVec(sofa::defaulttype::Vec6dTypes::Deriv& i) { return i; } +const sofa::type::Vec6d& getVec(const sofa::defaulttype::Vec6dTypes::Deriv& i) { return i; } + +sofa::type::Vec3f& getVec(sofa::defaulttype::Rigid3fTypes::Deriv& i) { return i.getVCenter(); } +sofa::type::Vec3f& getVec(sofa::defaulttype::Rigid3fTypes::Coord& i) { return i.getCenter(); } +const sofa::type::Vec3f& getVec(const sofa::defaulttype::Rigid3fTypes::Deriv& i) { return i.getVCenter(); } +const sofa::type::Vec3f& getVec(const sofa::defaulttype::Rigid3fTypes::Coord& i) { return i.getCenter(); } +sofa::type::Vec3f& getVec(sofa::defaulttype::Vec3fTypes::Deriv& i) { return i; } +const sofa::type::Vec3f& getVec(const sofa::defaulttype::Vec3fTypes::Deriv& i) { return i; } +sofa::type::Vec6f& getVec(sofa::defaulttype::Vec6fTypes::Deriv& i) { return i; } +const sofa::type::Vec6f& getVec(const sofa::defaulttype::Vec6fTypes::Deriv& i) { return i; } + +template +void FixedPlaneProjectiveConstraint::projectResponse(const MechanicalParams* mparams, DataVecDeriv& resData) +{ + SOFA_UNUSED(mparams); + WriteAccessor res = resData; + + const auto& indices = d_indices.getValue(); + const auto& dir = getVec(d_direction.getValue()); + auto& dx = res.wref(); + for (const auto& i : indices) + { + /// only constraint one projection of the displacement to be zero + auto val = getVec(dx[i]); + val = val - (dir * dot(val, dir)); + DataTypes::setDPos(dx[i], val); + } +} + +/// project dx to constrained space (dx models a velocity) +template +void FixedPlaneProjectiveConstraint::projectVelocity(const MechanicalParams* /*mparams*/, DataVecDeriv& /*vData*/) +{ + +} + +/// project x to constrained space (x models a position) +template +void FixedPlaneProjectiveConstraint::projectPosition(const MechanicalParams* /*mparams*/, DataVecCoord& /*xData*/) +{ + +} + +template +void FixedPlaneProjectiveConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned /*offset*/ ) +{ + /// clears the rows and columns associated with constrained particles + const unsigned blockSize = DataTypes::deriv_total_size; + + for(auto& index : d_indices.getValue()) + { + M->clearRowsCols((index) * blockSize,(index+1) * (blockSize) ); + } +} + +template +void FixedPlaneProjectiveConstraint::projectJacobianMatrix(const MechanicalParams* mparams, DataMatrixDeriv& cData) +{ + SOFA_UNUSED(mparams); + WriteAccessor c = cData; + + const auto& indices = d_indices.getValue(); + const auto& dir = getVec(d_direction.getValue()); + auto& dx = c.wref(); + + auto itRow = dx.begin(); + auto itRowEnd = dx.end(); + while (itRow != itRowEnd) + { + for (auto colIt = itRow.begin(); colIt != itRow.end(); colIt++) + { + if (std::find(indices.begin(), indices.end(), colIt.index()) != indices.end()) + { + auto val = getVec(colIt.val()); + Deriv r(type::NOINIT); + DataTypes::setDPos(r, -(dir * dot(val, dir))); + dx.writeLine(itRow.index()).addCol(colIt.index(), r); + } + } + } +} + +template +void FixedPlaneProjectiveConstraint::setDirection(Coord dir) +{ + if (dir.norm2()>0) + { + d_direction.setValue(dir); + } +} + +template +void FixedPlaneProjectiveConstraint::selectVerticesAlongPlane() +{ + const VecCoord& x = mstate->read(core::ConstVecCoordId::position())->getValue(); + for(unsigned int i=0; i +void FixedPlaneProjectiveConstraint::init() +{ + ProjectiveConstraintSet::init(); + + if (l_topology.empty()) + { + msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; + l_topology.set(this->getContext()->getMeshTopologyLink()); + } + + if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) + { + msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; + + // Initialize topological changes support + d_indices.createTopologyHandler(_topology); + } + else + { + msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; + } + + /// test that dmin or dmax are different from zero + if (d_dmin.getValue()!=d_dmax.getValue()) + m_selectVerticesFromPlanes=true; + + if (m_selectVerticesFromPlanes) + selectVerticesAlongPlane(); +} + +template +void FixedPlaneProjectiveConstraint::setDminAndDmax(const Real _dmin,const Real _dmax) +{ + d_dmin=_dmin; + d_dmax=_dmax; + m_selectVerticesFromPlanes=true; +} + +template +void FixedPlaneProjectiveConstraint::draw(const VisualParams* vparams) +{ + if (!vparams->displayFlags().getShowBehaviorModels()) return; + const VecCoord& x = mstate->read(core::ConstVecCoordId::position())->getValue(); + vparams->drawTool()->disableLighting(); + + type::vector points; + for(auto& index : d_indices.getValue()) + { + points.push_back({x[index][0], x[index][1], x[index][2]}); + } + + vparams->drawTool()->drawPoints(points, 10, sofa::type::RGBAColor{1,1.0,0.5,1}); +} + +template +bool FixedPlaneProjectiveConstraint::isPointInPlane(const Coord& p) const +{ + const Real d = getVec(p) * getVec(d_direction.getValue()); + return d > d_dmin.getValue() && d < d_dmax.getValue(); +} + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedProjectiveConstraint.cpp similarity index 73% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedProjectiveConstraint.cpp index 42021e2cdbc..c622b3d4724 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedProjectiveConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDCONSTRAINT_CPP -#include +#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDPROJECTIVECONSTRAINT_CPP +#include #include #include @@ -32,37 +32,36 @@ using namespace sofa::defaulttype; using namespace sofa::helper; -int FixedConstraintClass = core::RegisterObject("Attach given particles to their initial positions") - .add< FixedConstraint >() - .add< FixedConstraint >() - .add< FixedConstraint >() - .add< FixedConstraint >() - .add< FixedConstraint >() - .add< FixedConstraint >() - +int FixedProjectiveConstraintClass = core::RegisterObject("Attach given particles to their initial positions") + .add< FixedProjectiveConstraint >() + .add< FixedProjectiveConstraint >() + .add< FixedProjectiveConstraint >() + .add< FixedProjectiveConstraint >() + .add< FixedProjectiveConstraint >() + .add< FixedProjectiveConstraint >() ; // methods specilizations declaration template <> SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API -void FixedConstraint::draw(const core::visual::VisualParams* vparams); +void FixedProjectiveConstraint::draw(const core::visual::VisualParams* vparams); template <> SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API -void FixedConstraint::draw(const core::visual::VisualParams* vparams); +void FixedProjectiveConstraint::draw(const core::visual::VisualParams* vparams); -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedProjectiveConstraint; // methods specilizations definition template <> -void FixedConstraint::draw(const core::visual::VisualParams* vparams) +void FixedProjectiveConstraint::draw(const core::visual::VisualParams* vparams) { if (this->d_componentState.getValue() != ComponentState::Valid) return; if (!d_showObject.getValue()) return; @@ -104,7 +103,7 @@ void FixedConstraint::draw(const core::visual::VisualParams* vparam } template <> -void FixedConstraint::draw(const core::visual::VisualParams* vparams) +void FixedProjectiveConstraint::draw(const core::visual::VisualParams* vparams) { if (this->d_componentState.getValue() != ComponentState::Valid) return; if (!d_showObject.getValue()) return; diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedProjectiveConstraint.h new file mode 100644 index 00000000000..d2fad673643 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedProjectiveConstraint.h @@ -0,0 +1,137 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +/// This class can be overridden if needed for additionnal storage within template specializations. +template +class FixedProjectiveConstraintInternalData +{ + +}; + + +/** Maintain a constant velocity. + * If the particle is initially fixed then it is attached to its initial position. + * Otherwise it keeps on drifting. + * For maintaining particles fixed in any case, @sa PointProjectiveConstraint +*/ +template +class FixedProjectiveConstraint : public core::behavior::ProjectiveConstraintSet +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(FixedProjectiveConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, DataTypes)); + + using Index = sofa::Index; + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; + typedef typename MatrixDeriv::RowType MatrixDerivRowType; + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef Data DataMatrixDeriv; + typedef type::vector SetIndexArray; + typedef sofa::core::topology::TopologySubsetIndices SetIndex; + typedef sofa::core::topology::Point Point; + + SOFA_ATTRIBUTE_REPLACED__TYPEMEMBER(Vec3, sofa::type::Vec3); +protected: + FixedProjectiveConstraint(); + + virtual ~FixedProjectiveConstraint(); + +public: + SetIndex d_indices; + Data d_fixAll; ///< filter all the DOF to implement a fixed object + Data d_showObject; ///< draw or not the fixed constraints + Data d_drawSize; ///< 0 -> point based rendering, >0 -> radius of spheres + Data d_projectVelocity; ///< activate project velocity to set velocity to zero + + /// Link to be set to the topology container in the component graph. + SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; +protected: + FixedProjectiveConstraintInternalData* data; + friend class FixedProjectiveConstraintInternalData; + + +public: + void clearConstraints(); + void addConstraint(Index index); + void removeConstraint(Index index); + + // -- Constraint interface + void init() override; + void reinit() override; + + void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; + void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; + void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; + void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; + + + void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vect, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + + /** Project the given matrix (Experimental API). + See doc in base parent class + */ + void projectMatrix( sofa::linearalgebra::BaseMatrix* /*M*/, unsigned /*offset*/ ) override; + + void applyConstraint(sofa::core::behavior::ZeroDirichletCondition* matrix) override; + + void draw(const core::visual::VisualParams* vparams) override; + + bool fixAllDOFs() const { return d_fixAll.getValue(); } + +protected : + /// Function check values of given indices + void checkIndices(); + +}; + +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDPROJECTIVECONSTRAINT_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedProjectiveConstraint; +#endif + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedProjectiveConstraint.inl new file mode 100644 index 00000000000..78bd3636d2e --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedProjectiveConstraint.inl @@ -0,0 +1,426 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include + +using sofa::core::objectmodel::ComponentState; + + +namespace sofa::component::constraint::projective +{ + +template +FixedProjectiveConstraint::FixedProjectiveConstraint() + : core::behavior::ProjectiveConstraintSet(nullptr) + , d_indices( initData(&d_indices,"indices","Indices of the fixed points") ) + , d_fixAll( initData(&d_fixAll,false,"fixAll","filter all the DOF to implement a fixed object") ) + , d_showObject(initData(&d_showObject,true,"showObject","draw or not the fixed constraints")) + , d_drawSize( initData(&d_drawSize,(SReal)0.0,"drawSize","0 -> point based rendering, >0 -> radius of spheres") ) + , d_projectVelocity( initData(&d_projectVelocity,false,"activate_projectVelocity","activate project velocity to set velocity") ) + , l_topology(initLink("topology", "link to the topology container")) + , data(new FixedProjectiveConstraintInternalData()) +{ + // default to indice 0 + d_indices.beginEdit()->push_back(0); + d_indices.endEdit(); + + this->addUpdateCallback("updateIndices", { &d_indices}, [this](const core::DataTracker& t) + { + SOFA_UNUSED(t); + checkIndices(); + return sofa::core::objectmodel::ComponentState::Valid; + }, {}); +} + + +template +FixedProjectiveConstraint::~FixedProjectiveConstraint() +{ + delete data; +} + +template +void FixedProjectiveConstraint::clearConstraints() +{ + d_indices.beginEdit()->clear(); + d_indices.endEdit(); +} + +template +void FixedProjectiveConstraint::addConstraint(Index index) +{ + d_indices.beginEdit()->push_back(index); + d_indices.endEdit(); +} + +template +void FixedProjectiveConstraint::removeConstraint(Index index) +{ + sofa::type::removeValue(*d_indices.beginEdit(),index); + d_indices.endEdit(); +} + +// -- Constraint interface + + +template +void FixedProjectiveConstraint::init() +{ + this->d_componentState.setValue(ComponentState::Invalid); + this->core::behavior::ProjectiveConstraintSet::init(); + + if (!this->mstate.get()) + { + msg_warning() << "Missing mstate, cannot initialize the component."; + return; + } + + if (l_topology.empty()) + { + msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; + l_topology.set(this->getContext()->getMeshTopologyLink()); + } + + if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) + { + msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; + + // Initialize topological changes support + d_indices.createTopologyHandler(_topology); + } + else + { + msg_info() << "Can not find the topology, won't be able to handle topological changes"; + } + + this->checkIndices(); + this->d_componentState.setValue(ComponentState::Valid); +} + +template +void FixedProjectiveConstraint::reinit() +{ + this->checkIndices(); +} + +template +void FixedProjectiveConstraint::checkIndices() +{ + // Check value of given indices + Index maxIndex=this->mstate->getSize(); + + const SetIndexArray & indices = d_indices.getValue(); + SetIndexArray invalidIndices; + for (unsigned int i=0; i= maxIndex) + { + msg_warning() << "Index " << index << " not valid, should be [0,"<< maxIndex <<"]. Constraint will be removed."; + invalidIndices.push_back(index); + } + } + + // if invalid indices, sort them and remove in decreasing order as removeConstraint perform a swap and pop_back. + if (!invalidIndices.empty()) + { + std::sort( invalidIndices.begin(), invalidIndices.end(), std::greater() ); + const int max = invalidIndices.size()-1; + for (int i=max; i>= 0; i--) + { + removeConstraint(invalidIndices[i]); + } + } +} + +template +void FixedProjectiveConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) +{ + static const unsigned blockSize = DataTypes::deriv_total_size; + + if( d_fixAll.getValue() ) + { + const unsigned size = this->mstate->getSize(); + for( unsigned i=0; iclearRowsCols( offset + i * blockSize, offset + (i+1) * (blockSize) ); + } + } + else + { + // clears the rows and columns associated with fixed particles + for (const auto id : d_indices.getValue()) + { + M->clearRowsCols( offset + id * blockSize, offset + (id+1) * blockSize ); + } + } +} + + +template +void FixedProjectiveConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) +{ + SOFA_UNUSED(mparams); + + helper::WriteAccessor res (resData ); + const SetIndexArray & indices = d_indices.getValue(); + + if( d_fixAll.getValue() ) + { + // fix everything + typename VecDeriv::iterator it; + for( it = res.begin(); it != res.end(); ++it ) + { + *it = Deriv(); + } + } + else + { + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + res[*it] = Deriv(); + } + } +} + +template +void FixedProjectiveConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) +{ + SOFA_UNUSED(mparams); + + helper::WriteAccessor c (cData ); + + if( d_fixAll.getValue() ) + { + // fix everything + c->clear(); + } + else + { + const SetIndexArray& indices = d_indices.getValue(); + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + c->clearColBlock(*it); + } + } +} + +// projectVelocity applies the same changes on velocity vector as projectResponse on position vector : +// Each fixed point received a null velocity vector. +// When a new fixed point is added while its velocity vector is already null, projectVelocity is not usefull. +// But when a new fixed point is added while its velocity vector is not null, it's necessary to fix it to null or +// to set the projectVelocity option to True. If not, the fixed point is going to drift. +template +void FixedProjectiveConstraint::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) +{ + SOFA_UNUSED(mparams); + + if(!d_projectVelocity.getValue()) return; + + helper::WriteAccessor res (vData ); + + if ( d_fixAll.getValue() ) // fix everyting + { + for(Size i=0; id_indices.getValue(); + for(Index ind : indices) + { + res[ind] = Deriv(); + } + } +} + + +template +void FixedProjectiveConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& /*xData*/) +{ + +} + +// Matrix Integration interface +template +void FixedProjectiveConstraint::applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) +{ + SOFA_UNUSED(mparams); + if(const core::behavior::MultiMatrixAccessor::MatrixRef r = matrix->getMatrix(this->mstate.get())) + { + const unsigned int N = Deriv::size(); + + if( d_fixAll.getValue() ) + { + const unsigned size = this->mstate->getSize(); + for(unsigned int i=0; iclearRowCol(r.offset + N * i + c); + // Set Fixed Vertex + for (unsigned int c=0; cset(r.offset + N * i + c, r.offset + N * i + c, 1.0); + } + } + else + { + const SetIndexArray & indices = d_indices.getValue(); + + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + // Reset Fixed Row and Col + for (unsigned int c=0; cclearRowCol(r.offset + N * (*it) + c); + // Set Fixed Vertex + for (unsigned int c=0; cset(r.offset + N * (*it) + c, r.offset + N * (*it) + c, 1.0); + } + } + } +} + +template +void FixedProjectiveConstraint::applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vect, const sofa::core::behavior::MultiMatrixAccessor* matrix) +{ + SOFA_UNUSED(mparams); + const int o = matrix->getGlobalOffset(this->mstate.get()); + if (o >= 0) + { + const unsigned int offset = (unsigned int)o; + const unsigned int N = Deriv::size(); + + if( d_fixAll.getValue() ) + { + for(sofa::Size i=0; i < (sofa::Size) vect->size(); i++ ) + { + for (unsigned int c=0; cclear(offset + N * i + c); + } + } + else + { + const SetIndexArray & indices = d_indices.getValue(); + for (const auto & index : indices) + { + for (unsigned int c=0; cclear(offset + N * index + c); + } + } + } +} + +template +void FixedProjectiveConstraint::applyConstraint(sofa::core::behavior::ZeroDirichletCondition* matrix) +{ + static constexpr unsigned int N = Deriv::size(); + + if( d_fixAll.getValue() ) + { + const sofa::Size size = this->mstate->getMatrixSize(); + for(sofa::Index i = 0; i < size; ++i) + { + matrix->discardRowCol(i, i); + } + } + else + { + const SetIndexArray & indices = d_indices.getValue(); + + for (const auto index : indices) + { + for (unsigned int c = 0; c < N; ++c) + { + matrix->discardRowCol(N * index + c, N * index + c); + } + } + } +} + +template +void FixedProjectiveConstraint::draw(const core::visual::VisualParams* vparams) +{ + if (this->d_componentState.getValue() != ComponentState::Valid) return; + if (!vparams->displayFlags().getShowBehaviorModels()) return; + if (!d_showObject.getValue()) return; + if (!this->isActive()) return; + + const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); + + const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); + const SetIndexArray & indices = d_indices.getValue(); + + if( d_drawSize.getValue() == 0) // old classical drawing by points + { + std::vector< sofa::type::Vec3 > points; + sofa::type::Vec3 point; + + if (d_fixAll.getValue()) + { + for (unsigned i = 0; i < x.size(); i++) + { + point = DataTypes::getCPos(x[i]); + points.push_back(point); + } + } + else + { + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + point = DataTypes::getCPos(x[*it]); + points.push_back(point); + } + } + vparams->drawTool()->drawPoints(points, 10, sofa::type::RGBAColor(1,0.5,0.5,1)); + } + else // new drawing by spheres + { + vparams->drawTool()->setLightingEnabled(true); + + std::vector< sofa::type::Vec3 > points; + sofa::type::Vec3 point; + if( d_fixAll.getValue()==true ) + for (unsigned i=0; idrawTool()->drawSpheres(points, (float)d_drawSize.getValue(), sofa::type::RGBAColor(1.0f,0.35f,0.35f,1.0f)); + } + + +} + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationConstraint.h index cd66b14734a..511c63a88d4 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationConstraint.h @@ -20,61 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/FixedRotationProjectiveConstraint.h") -/** - * Prevents rotation around X or Y or Z axis - */ -template -class FixedRotationConstraint : public core::behavior::ProjectiveConstraintSet +namespace sofa::component::constraint::projective { -public: - SOFA_CLASS(SOFA_TEMPLATE(FixedRotationConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, DataTypes)); - - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::MatrixDeriv::RowType MatrixDerivRowType; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::Real Real; - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef Data DataMatrixDeriv; - typedef type::Vec<3,Real> Vec3; - - -protected: - FixedRotationConstraint(); - ~FixedRotationConstraint() override; -public: - void init() override; - - void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& dx) override; - void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& dx) override; - void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& x) override; - void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& c) override; - - void draw(const core::visual::VisualParams* vparams) override; - - -protected : - Data< bool > FixedXRotation; ///< Prevent Rotation around X axis - Data< bool > FixedYRotation; ///< Prevent Rotation around Y axis - Data< bool > FixedZRotation; ///< Prevent Rotation around Z axis - type::vector> previousOrientation; -}; - - -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDROTATIONCONSTRAINT_CPP) -extern template class FixedRotationConstraint; - -#endif - -} // namespace sofa::component::constraint::projective +template +using FixedRotationConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "FixedRotationConstraint has been renamed to FixedRotationProjectiveConstraint") = FixedRotationProjectiveConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationConstraint.inl index 0f1a6731a8d..0ecc0e7851c 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationConstraint.inl @@ -21,122 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include -#include +#include - -namespace sofa::component::constraint::projective -{ - - -template -FixedRotationConstraint::FixedRotationConstraint() - : core::behavior::ProjectiveConstraintSet(nullptr), - FixedXRotation( initData( &FixedXRotation, false, "FixedXRotation", "Prevent Rotation around X axis")), - FixedYRotation( initData( &FixedYRotation, false, "FixedYRotation", "Prevent Rotation around Y axis")), - FixedZRotation( initData( &FixedZRotation, false, "FixedZRotation", "Prevent Rotation around Z axis")) -{ -} - - -template -FixedRotationConstraint::~FixedRotationConstraint() -{ -} - - -template -void FixedRotationConstraint::init() -{ - this->core::behavior::ProjectiveConstraintSet::init(); - - // Retrieves mechanical state - VecCoord x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); - - // Stores initial orientation for each vertex - previousOrientation.resize(x.size()); - for (unsigned int i=0; i -void FixedRotationConstraint::projectResponse(const core::MechanicalParams* /*mparams*/, DataVecDeriv& /*res*/) -{ - -} - -template -void FixedRotationConstraint::projectJacobianMatrix(const core::MechanicalParams* /*mparams*/, DataMatrixDeriv& /*res*/) -{ - -} - -template -void FixedRotationConstraint::projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& /*dx*/) -{ - -} - -template -void FixedRotationConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) -{ - helper::WriteAccessor x = xData; - for (unsigned int i = 0; i < x.size(); ++i) - { - // Current orientations - const sofa::type::Quat& Q = x[i].getOrientation(); - // Previous orientations - const sofa::type::Quat& Q_prev = previousOrientation[i]; - - auto project = [](const Vec3 a, const Vec3 b) -> Vec3 { - return (a * b) * b; - }; - auto decompose_ts = [&](const sofa::type::Quat q, const Vec3 twistAxis) { - Vec3 vec3_part(q[0], q[1], q[2]); - Vec3 projected = project(vec3_part, twistAxis); - sofa::type::Quat twist(projected[0], projected[1], projected[2], q[3]); - // Singularity : A perpendicular angle would give you quaternion (0, 0, 0, 0) - if (std::none_of(twist.ptr(), twist.ptr() + 4, [](SReal x) {return x != 0.; })) { - twist = sofa::type::Quat::identity(); - } - twist.normalize(); - sofa::type::Quat swing = q * twist.inverse(); - swing.normalize(); - return std::make_pair(twist, swing); - }; - const Vec3 vx(1, 0, 0), vy(0, 1, 0), vz(0, 0, 1); - - sofa::type::Quat Q_remaining = Q; - sofa::type::Quat Qp_remaining = Q_prev; - sofa::type::Quat to_keep = sofa::type::Quat::identity(); - - auto remove_rotation = [&](const Vec3 axis) { - Q_remaining = decompose_ts(Q_remaining, axis).second; - sofa::type::Quat twist; - std::tie(twist, Qp_remaining) = decompose_ts(Qp_remaining, axis); - to_keep = twist * to_keep; - }; - - if (FixedXRotation.getValue() == true){ - remove_rotation(vx); - } - if (FixedYRotation.getValue() == true){ - remove_rotation(vy); - } - if (FixedZRotation.getValue() == true){ - remove_rotation(vz); - } - x[i].getOrientation() = Q_remaining * to_keep; - } -} - - -template -void FixedRotationConstraint::draw(const core::visual::VisualParams* ) -{ -} - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/FixedRotationProjectiveConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationProjectiveConstraint.cpp similarity index 82% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationProjectiveConstraint.cpp index 3a47b6bbd69..d812af0e473 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationProjectiveConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDROTATIONCONSTRAINT_CPP -#include +#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDROTATIONPROJECTIVECONSTRAINT_CPP +#include #include #include @@ -31,10 +31,11 @@ namespace sofa::component::constraint::projective using namespace sofa::defaulttype; -int FixedRotationConstraintClass = core::RegisterObject("Prevents rotation around x or/and y or/and z axis") - .add< FixedRotationConstraint >() +int FixedRotationProjectiveConstraintClass = core::RegisterObject("Prevents rotation around x or/and y or/and z axis") + .add< FixedRotationProjectiveConstraint >() + ; -template class FixedRotationConstraint; +template class FixedRotationProjectiveConstraint; } // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationProjectiveConstraint.h new file mode 100644 index 00000000000..fa9800c22fe --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationProjectiveConstraint.h @@ -0,0 +1,79 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include + +namespace sofa::component::constraint::projective +{ + +/** + * Prevents rotation around X or Y or Z axis + */ +template +class FixedRotationProjectiveConstraint : public core::behavior::ProjectiveConstraintSet +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(FixedRotationProjectiveConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, DataTypes)); + + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::MatrixDeriv::RowType MatrixDerivRowType; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::Real Real; + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef Data DataMatrixDeriv; + typedef type::Vec<3,Real> Vec3; + + +protected: + FixedRotationProjectiveConstraint(); + ~FixedRotationProjectiveConstraint() override; +public: + void init() override; + + void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& dx) override; + void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& dx) override; + void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& x) override; + void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& c) override; + + void draw(const core::visual::VisualParams* vparams) override; + + +protected : + Data< bool > FixedXRotation; ///< Prevent Rotation around X axis + Data< bool > FixedYRotation; ///< Prevent Rotation around Y axis + Data< bool > FixedZRotation; ///< Prevent Rotation around Z axis + type::vector> previousOrientation; +}; + + +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDROTATIONPROJECTIVECONSTRAINT_CPP) +extern template class FixedRotationProjectiveConstraint; +#endif + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationProjectiveConstraint.inl new file mode 100644 index 00000000000..d900e468c9c --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationProjectiveConstraint.inl @@ -0,0 +1,142 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include + + +namespace sofa::component::constraint::projective +{ + + +template +FixedRotationProjectiveConstraint::FixedRotationProjectiveConstraint() + : core::behavior::ProjectiveConstraintSet(nullptr), + FixedXRotation( initData( &FixedXRotation, false, "FixedXRotation", "Prevent Rotation around X axis")), + FixedYRotation( initData( &FixedYRotation, false, "FixedYRotation", "Prevent Rotation around Y axis")), + FixedZRotation( initData( &FixedZRotation, false, "FixedZRotation", "Prevent Rotation around Z axis")) +{ +} + + +template +FixedRotationProjectiveConstraint::~FixedRotationProjectiveConstraint() +{ +} + + +template +void FixedRotationProjectiveConstraint::init() +{ + this->core::behavior::ProjectiveConstraintSet::init(); + + // Retrieves mechanical state + VecCoord x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); + + // Stores initial orientation for each vertex + previousOrientation.resize(x.size()); + for (unsigned int i=0; i +void FixedRotationProjectiveConstraint::projectResponse(const core::MechanicalParams* /*mparams*/, DataVecDeriv& /*res*/) +{ + +} + +template +void FixedRotationProjectiveConstraint::projectJacobianMatrix(const core::MechanicalParams* /*mparams*/, DataMatrixDeriv& /*res*/) +{ + +} + +template +void FixedRotationProjectiveConstraint::projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& /*dx*/) +{ + +} + +template +void FixedRotationProjectiveConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) +{ + helper::WriteAccessor x = xData; + for (unsigned int i = 0; i < x.size(); ++i) + { + // Current orientations + const sofa::type::Quat& Q = x[i].getOrientation(); + // Previous orientations + const sofa::type::Quat& Q_prev = previousOrientation[i]; + + auto project = [](const Vec3 a, const Vec3 b) -> Vec3 { + return (a * b) * b; + }; + auto decompose_ts = [&](const sofa::type::Quat q, const Vec3 twistAxis) { + Vec3 vec3_part(q[0], q[1], q[2]); + Vec3 projected = project(vec3_part, twistAxis); + sofa::type::Quat twist(projected[0], projected[1], projected[2], q[3]); + // Singularity : A perpendicular angle would give you quaternion (0, 0, 0, 0) + if (std::none_of(twist.ptr(), twist.ptr() + 4, [](SReal x) {return x != 0.; })) { + twist = sofa::type::Quat::identity(); + } + twist.normalize(); + sofa::type::Quat swing = q * twist.inverse(); + swing.normalize(); + return std::make_pair(twist, swing); + }; + const Vec3 vx(1, 0, 0), vy(0, 1, 0), vz(0, 0, 1); + + sofa::type::Quat Q_remaining = Q; + sofa::type::Quat Qp_remaining = Q_prev; + sofa::type::Quat to_keep = sofa::type::Quat::identity(); + + auto remove_rotation = [&](const Vec3 axis) { + Q_remaining = decompose_ts(Q_remaining, axis).second; + sofa::type::Quat twist; + std::tie(twist, Qp_remaining) = decompose_ts(Qp_remaining, axis); + to_keep = twist * to_keep; + }; + + if (FixedXRotation.getValue() == true){ + remove_rotation(vx); + } + if (FixedYRotation.getValue() == true){ + remove_rotation(vy); + } + if (FixedZRotation.getValue() == true){ + remove_rotation(vz); + } + x[i].getOrientation() = Q_remaining * to_keep; + } +} + + +template +void FixedRotationProjectiveConstraint::draw(const core::visual::VisualParams* ) +{ +} + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationConstraint.h index 29360c58629..47203f733ee 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationConstraint.h @@ -20,87 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/FixedTranslationProjectiveConstraint.h") -/// This class can be overridden if needed for additionnal storage within template specializations. -template -class FixedTranslationConstraintInternalData -{ -}; - -/** Attach given particles to their initial positions. -*/ -template -class FixedTranslationConstraint : public core::behavior::ProjectiveConstraintSet +namespace sofa::component::constraint::projective { -public: - SOFA_CLASS(SOFA_TEMPLATE(FixedTranslationConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, DataTypes)); - - using Index = sofa::Index; - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename MatrixDeriv::RowType MatrixDerivRowType; - typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef Data DataMatrixDeriv; - typedef type::vector SetIndexArray; - typedef sofa::core::topology::TopologySubsetIndices SetIndex; -protected: - FixedTranslationConstraintInternalData data; - friend class FixedTranslationConstraintInternalData; - -public: - SetIndex f_indices; ///< Indices of the fixed points - Data f_fixAll; ///< filter all the DOF to implement a fixed object - Data _drawSize; ///< 0 -> point based rendering, >0 -> radius of spheres - SetIndex f_coordinates; ///< Coordinates of the fixed points - - /// Link to be set to the topology container in the component graph. - SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; -protected: - FixedTranslationConstraint(); - - virtual ~FixedTranslationConstraint(); -public: - // methods to add/remove some indices - void clearIndices(); - void addIndex(Index index); - void removeIndex(Index index); - - // -- Constraint interface - void init() override; - - void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; - void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; - void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; - void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; - - - void draw(const core::visual::VisualParams* vparams) override; - -protected: - template - void projectResponseT(DataDeriv& dx, - const std::function& clear); - -}; - -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDTRANSLATIONCONSTRAINT_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedTranslationConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedTranslationConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedTranslationConstraint; - -#endif - -} // namespace sofa::component::constraint::projective +template +using FixedTranslationConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "FixedTranslationConstraint has been renamed to FixedTranslationProjectiveConstraint") = FixedTranslationProjectiveConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationConstraint.inl index 9c734a4b1c4..7b1b96bad54 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationConstraint.inl @@ -21,188 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -template< class DataTypes> -FixedTranslationConstraint::FixedTranslationConstraint() - : core::behavior::ProjectiveConstraintSet(nullptr) - , f_indices( initData(&f_indices,"indices","Indices of the fixed points") ) - , f_fixAll( initData(&f_fixAll,false,"fixAll","filter all the DOF to implement a fixed object") ) - , _drawSize( initData(&_drawSize,(SReal)0.0,"drawSize","0 -> point based rendering, >0 -> radius of spheres") ) - , f_coordinates( initData(&f_coordinates,"coordinates","Coordinates of the fixed points") ) - , l_topology(initLink("topology", "link to the topology container")) -{ - // default to indice 0 - f_indices.beginEdit()->push_back(0); - f_indices.endEdit(); -} - - -template -FixedTranslationConstraint::~FixedTranslationConstraint() -{ - -} - -template -void FixedTranslationConstraint::clearIndices() -{ - f_indices.beginEdit()->clear(); - f_indices.endEdit(); -} - -template -void FixedTranslationConstraint::addIndex(Index index) -{ - f_indices.beginEdit()->push_back(index); - f_indices.endEdit(); -} - -template -void FixedTranslationConstraint::removeIndex(Index index) -{ - sofa::type::removeValue(*f_indices.beginEdit(),index); - f_indices.endEdit(); -} - -// -- Constraint interface -template -void FixedTranslationConstraint::init() -{ - this->core::behavior::ProjectiveConstraintSet::init(); - - if (l_topology.empty()) - { - msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; - l_topology.set(this->getContext()->getMeshTopologyLink()); - } - - if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) - { - msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; - - // Initialize topological changes support - f_indices.createTopologyHandler(_topology); - f_coordinates.createTopologyHandler(_topology); - } - else - { - msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; - } -} - - -template -static inline void clearPos(defaulttype::RigidDeriv& v) -{ - getVCenter(v).clear(); -} - -template -static inline void clearPos(type::Vec<6,T>& v) -{ - for (unsigned int i=0; i<3; ++i) - v[i] = 0; -} - -template template -void FixedTranslationConstraint::projectResponseT(DataDeriv& dx, - const std::function& clear) -{ - if (f_fixAll.getValue()) - { - for (std::size_t i = 0; i < dx.size(); i++) - { - clear(dx, i); - } - } - else - { - const SetIndexArray & indices = f_indices.getValue(); - for (const auto index : indices) - { - clear(dx, index); - } - } -} - -template -void FixedTranslationConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) -{ - SOFA_UNUSED(mparams); - helper::WriteAccessor res = resData; - projectResponseT(res.wref(), [](auto& dx, const unsigned int index) {dx[index].clear(); }); -} - -template -void FixedTranslationConstraint::projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& /*vData*/) -{ - -} - -template -void FixedTranslationConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& /*xData*/) -{ - -} - -template -void FixedTranslationConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) -{ - SOFA_UNUSED(mparams); - helper::WriteAccessor c = cData; - projectResponseT(c.wref(), [](MatrixDeriv& res, const unsigned int index) { res.clearColBlock(index); }); -} - - -template -void FixedTranslationConstraint::draw(const core::visual::VisualParams* vparams) -{ - const SetIndexArray & indices = f_indices.getValue(); - if (!vparams->displayFlags().getShowBehaviorModels()) - return; - const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); - - const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); - vparams->drawTool()->disableLighting(); - - std::vector vertices; - constexpr sofa::type::RGBAColor color(1, 0.5, 0.5, 1); - - if (f_fixAll.getValue() == true) - { - for (unsigned i = 0; i < x.size(); i++) - { - sofa::type::Vec3 v; - const typename DataTypes::CPos& cpos = DataTypes::getCPos(x[i]); - for(Size j=0 ; jdrawTool()->drawPoints(vertices, 10, color); - - -} - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/FixedTranslationProjectiveConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationProjectiveConstraint.cpp similarity index 76% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationProjectiveConstraint.cpp index c4acd3e16f1..e65ea931ed2 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationProjectiveConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDTRANSLATIONCONSTRAINT_CPP -#include +#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDTRANSLATIONPROJECTIVECONSTRAINT_CPP +#include #include #include @@ -31,16 +31,15 @@ namespace sofa::component::constraint::projective using namespace sofa::defaulttype; using namespace sofa::helper; -int FixedTranslationConstraintClass = core::RegisterObject("Attach given rigids to their initial positions but they still can have rotations") - .add< FixedTranslationConstraint >() - .add< FixedTranslationConstraint >() - .add< FixedTranslationConstraint >() +int FixedTranslationProjectiveConstraintClass = core::RegisterObject("Attach given rigids to their initial positions but they still can have rotations") + .add< FixedTranslationProjectiveConstraint >() + .add< FixedTranslationProjectiveConstraint >() + .add< FixedTranslationProjectiveConstraint >() + ; - ; - -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedTranslationConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedTranslationConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedTranslationConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedTranslationProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedTranslationProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedTranslationProjectiveConstraint; } // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationProjectiveConstraint.h new file mode 100644 index 00000000000..4290a2c6d13 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationProjectiveConstraint.h @@ -0,0 +1,105 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +/// This class can be overridden if needed for additionnal storage within template specializations. +template +class FixedTranslationProjectiveConstraintInternalData +{ +}; + +/** Attach given particles to their initial positions. +*/ +template +class FixedTranslationProjectiveConstraint : public core::behavior::ProjectiveConstraintSet +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(FixedTranslationProjectiveConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, DataTypes)); + + using Index = sofa::Index; + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename MatrixDeriv::RowType MatrixDerivRowType; + typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef Data DataMatrixDeriv; + typedef type::vector SetIndexArray; + typedef sofa::core::topology::TopologySubsetIndices SetIndex; +protected: + FixedTranslationProjectiveConstraintInternalData data; + friend class FixedTranslationProjectiveConstraintInternalData; + +public: + SetIndex f_indices; ///< Indices of the fixed points + Data f_fixAll; ///< filter all the DOF to implement a fixed object + Data _drawSize; ///< 0 -> point based rendering, >0 -> radius of spheres + SetIndex f_coordinates; ///< Coordinates of the fixed points + + /// Link to be set to the topology container in the component graph. + SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; +protected: + FixedTranslationProjectiveConstraint(); + + virtual ~FixedTranslationProjectiveConstraint(); +public: + // methods to add/remove some indices + void clearIndices(); + void addIndex(Index index); + void removeIndex(Index index); + + // -- Constraint interface + void init() override; + + void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; + void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; + void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; + void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; + + + void draw(const core::visual::VisualParams* vparams) override; + +protected: + template + void projectResponseT(DataDeriv& dx, + const std::function& clear); + +}; + +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDTRANSLATIONPROJECTIVECONSTRAINT_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedTranslationProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedTranslationProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedTranslationProjectiveConstraint; +#endif + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationProjectiveConstraint.inl new file mode 100644 index 00000000000..d1f7408b8c8 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationProjectiveConstraint.inl @@ -0,0 +1,208 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +template< class DataTypes> +FixedTranslationProjectiveConstraint::FixedTranslationProjectiveConstraint() + : core::behavior::ProjectiveConstraintSet(nullptr) + , f_indices( initData(&f_indices,"indices","Indices of the fixed points") ) + , f_fixAll( initData(&f_fixAll,false,"fixAll","filter all the DOF to implement a fixed object") ) + , _drawSize( initData(&_drawSize,(SReal)0.0,"drawSize","0 -> point based rendering, >0 -> radius of spheres") ) + , f_coordinates( initData(&f_coordinates,"coordinates","Coordinates of the fixed points") ) + , l_topology(initLink("topology", "link to the topology container")) +{ + // default to indice 0 + f_indices.beginEdit()->push_back(0); + f_indices.endEdit(); +} + + +template +FixedTranslationProjectiveConstraint::~FixedTranslationProjectiveConstraint() +{ + +} + +template +void FixedTranslationProjectiveConstraint::clearIndices() +{ + f_indices.beginEdit()->clear(); + f_indices.endEdit(); +} + +template +void FixedTranslationProjectiveConstraint::addIndex(Index index) +{ + f_indices.beginEdit()->push_back(index); + f_indices.endEdit(); +} + +template +void FixedTranslationProjectiveConstraint::removeIndex(Index index) +{ + sofa::type::removeValue(*f_indices.beginEdit(),index); + f_indices.endEdit(); +} + +// -- Constraint interface +template +void FixedTranslationProjectiveConstraint::init() +{ + this->core::behavior::ProjectiveConstraintSet::init(); + + if (l_topology.empty()) + { + msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; + l_topology.set(this->getContext()->getMeshTopologyLink()); + } + + if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) + { + msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; + + // Initialize topological changes support + f_indices.createTopologyHandler(_topology); + f_coordinates.createTopologyHandler(_topology); + } + else + { + msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; + } +} + + +template +static inline void clearPos(defaulttype::RigidDeriv& v) +{ + getVCenter(v).clear(); +} + +template +static inline void clearPos(type::Vec<6,T>& v) +{ + for (unsigned int i=0; i<3; ++i) + v[i] = 0; +} + +template template +void FixedTranslationProjectiveConstraint::projectResponseT(DataDeriv& dx, + const std::function& clear) +{ + if (f_fixAll.getValue()) + { + for (std::size_t i = 0; i < dx.size(); i++) + { + clear(dx, i); + } + } + else + { + const SetIndexArray & indices = f_indices.getValue(); + for (const auto index : indices) + { + clear(dx, index); + } + } +} + +template +void FixedTranslationProjectiveConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) +{ + SOFA_UNUSED(mparams); + helper::WriteAccessor res = resData; + projectResponseT(res.wref(), [](auto& dx, const unsigned int index) {dx[index].clear(); }); +} + +template +void FixedTranslationProjectiveConstraint::projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& /*vData*/) +{ + +} + +template +void FixedTranslationProjectiveConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& /*xData*/) +{ + +} + +template +void FixedTranslationProjectiveConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) +{ + SOFA_UNUSED(mparams); + helper::WriteAccessor c = cData; + projectResponseT(c.wref(), [](MatrixDeriv& res, const unsigned int index) { res.clearColBlock(index); }); +} + + +template +void FixedTranslationProjectiveConstraint::draw(const core::visual::VisualParams* vparams) +{ + const SetIndexArray & indices = f_indices.getValue(); + if (!vparams->displayFlags().getShowBehaviorModels()) + return; + const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); + + const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); + vparams->drawTool()->disableLighting(); + + std::vector vertices; + constexpr sofa::type::RGBAColor color(1, 0.5, 0.5, 1); + + if (f_fixAll.getValue() == true) + { + for (unsigned i = 0; i < x.size(); i++) + { + sofa::type::Vec3 v; + const typename DataTypes::CPos& cpos = DataTypes::getCPos(x[i]); + for(Size j=0 ; jdrawTool()->drawPoints(vertices, 10, color); + + +} + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineConstraint.h index 858a5ab5a6c..9d2f358ef52 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineConstraint.h @@ -20,115 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/HermiteSplineProjectiveConstraint.h") -/** - Impose a trajectory to given Dofs following a Hermite cubic spline constraint. - Control parameters are : - - begin and end points - - derivates at this points - - acceleration curve on the trajectory - */ -template -class HermiteSplineConstraint : public core::behavior::ProjectiveConstraintSet +namespace sofa::component::constraint::projective { -public: - SOFA_CLASS(SOFA_TEMPLATE(HermiteSplineConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, DataTypes)); - - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename Coord::value_type Real; - typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; - typedef typename MatrixDeriv::RowType MatrixDerivRowType; - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef Data DataMatrixDeriv; - typedef type::vector SetIndexArray; - typedef sofa::core::topology::TopologySubsetIndices SetIndex; - typedef typename type::Vec<3, Real> Vec3R; - typedef typename type::Vec<2, Real> Vec2R; - typedef typename type::Quat QuatR; - -public: - ///indices of the DOFs constraints - SetIndex m_indices; - - /// the time steps defining the duration of the constraint - Data m_tBegin; - Data m_tEnd; ///< End Time of the motion - - /// control parameters : - /// first control point - Data m_x0; - /// first derivated control point - Data m_dx0; - /// second control point - Data m_x1; - /// second derivated control point - Data m_dx1; - /// acceleration parameters : the accaleration curve is itself a hermite spline, with first point at (0,0) and second at (1,1) - /// and derivated on this points are : - Data m_sx0; - Data m_sx1; ///< second interpolation vector - - /// Link to be set to the topology container in the component graph. - SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; - -protected: - explicit HermiteSplineConstraint(core::behavior::MechanicalState* mstate = nullptr); - - ~HermiteSplineConstraint(); -public: - void clearConstraints(); - void addConstraint(unsigned index ); - - void setBeginTime(const Real &t) {m_tBegin.setValue(t);} - void setEndTime(const Real &t) {m_tEnd.setValue(t);} - - Real getBeginTime() {return m_tBegin.getValue();} - Real getEndTime() {return m_tEnd.getValue();} - - void computeHermiteCoefs( const Real u, Real &H00, Real &H10, Real &H01, Real &H11); - void computeDerivateHermiteCoefs( const Real u, Real &dH00, Real &dH10, Real &dH01, Real &dH11); - - /// -- Constraint interface - void init() override; - void reinit() override; - - - void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; - void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; - void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; - void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; - - void draw(const core::visual::VisualParams* vparams) override; - -protected: - template - void projectResponseT(DataDeriv& dx, - const std::function& clear); - -}; - -template <> -void SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API HermiteSplineConstraint::init(); - - -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_HERMITESPLINECONSTRAINT_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API HermiteSplineConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API HermiteSplineConstraint; - -#endif - -} // namespace sofa::component::constraint::projective +template +using HermiteSplineConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "HermiteSplineConstraint has been renamed to HermiteSplineProjectiveConstraint") = HermiteSplineProjectiveConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineConstraint.inl index 6fc823bf0c1..6064b936335 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineConstraint.inl @@ -21,247 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -template -HermiteSplineConstraint::HermiteSplineConstraint(core::behavior::MechanicalState* mstate) - : core::behavior::ProjectiveConstraintSet(mstate) - , m_indices( initData(&m_indices,"indices","Indices of the constrained points") ) - , m_tBegin(initData(&m_tBegin,"BeginTime","Begin Time of the motion") ) - , m_tEnd(initData(&m_tEnd,"EndTime","End Time of the motion") ) - , m_x0(initData(&m_x0,"X0","first control point") ) - , m_dx0(initData(&m_dx0,"dX0","first control tangente") ) - , m_x1(initData(&m_x1,"X1","second control point") ) - , m_dx1(initData(&m_dx1,"dX1","sceond control tangente") ) - , m_sx0(initData(&m_sx0,"SX0","first interpolation vector") ) - , m_sx1(initData(&m_sx1,"SX1","second interpolation vector") ) - , l_topology(initLink("topology", "link to the topology container")) -{ -} - -template -HermiteSplineConstraint::~HermiteSplineConstraint() -{ -} - -template -void HermiteSplineConstraint::clearConstraints() -{ - m_indices.beginEdit()->clear(); - m_indices.endEdit(); -} - -template -void HermiteSplineConstraint::addConstraint(unsigned index) -{ - m_indices.beginEdit()->push_back(index); - m_indices.endEdit(); -} - - -template -void HermiteSplineConstraint::init() -{ - this->core::behavior::ProjectiveConstraintSet::init(); - - if (l_topology.empty()) - { - msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; - l_topology.set(this->getContext()->getMeshTopologyLink()); - } - - if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) - { - msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; - - // Initialize functions and parameters for topology data and handler - m_indices.createTopologyHandler(_topology); - } - else - { - msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; - } -} - -template -void HermiteSplineConstraint::reinit() -{ - init(); -} - - -template -void HermiteSplineConstraint::computeHermiteCoefs( const Real u, Real &H00, Real &H10, Real &H01, Real &H11) -{ - //-- time interpolation --> acceleration is itself computed from hemite - Real u2 = u*u; - Real u3 = u*u*u; - //Real uH00 = 2*u3 -3*u2 +1 ; //hermite coefs - Real uH10 = u3 -2*u2 +u; - Real uH01 = -2*u3 + 3*u2; - Real uH11 = u3 -u2; - Vec2R pu = m_sx0.getValue()*uH10 + Vec2R(1,1)*uH01 + m_sx1.getValue()*uH11; - Real su = pu.y(); - - Real su2 = su*su; - Real su3 = su*su*su; - H00 = 2*su3 -3*su2 +1 ; - H10 = su3 -2*su2 +su; - H01 = -2*su3 + 3*su2; - H11 = su3 -su2; -} - -template -void HermiteSplineConstraint::computeDerivateHermiteCoefs( const Real u, Real &dH00, Real &dH10, Real &dH01, Real &dH11) -{ - //-- time interpolation --> acceleration is itself computed from hemite - Real u2 = u*u; - Real u3 = u*u*u; - Real uH10 = u3 -2*u2 +u; - Real uH01 = -2*u3 + 3*u2; - Real uH11 = u3 -u2; - Vec2R pu = m_sx0.getValue()*uH10 + Vec2R(1,1)*uH01 + m_sx1.getValue()*uH11; - Real su = pu.y(); - - Real su2 = su*su; - dH00 = 6*su2 -6*su ; - dH10 = 3*su2 -4*su +1; - dH01 = -6*su2 + 6*su; - dH11 = 3*su2 -2*su; -} - - -template template -void HermiteSplineConstraint::projectResponseT(DataDeriv& dx, - const std::function& clear) -{ - Real t = (Real) this->getContext()->getTime(); - if ( t >= m_tBegin.getValue() && t <= m_tEnd.getValue()) - { - const SetIndexArray & indices = m_indices.getValue(); - for(SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - clear(dx, *it); - } -} - -template -void HermiteSplineConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) -{ - SOFA_UNUSED(mparams); - helper::WriteAccessor res = resData; - projectResponseT(res.wref(), [](auto& dx, const unsigned int index) {dx[index].clear();}); -} - -template -void HermiteSplineConstraint::projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& vData) -{ - helper::WriteAccessor dx = vData; - Real t = (Real) this->getContext()->getTime(); - - if ( t >= m_tBegin.getValue() && t <= m_tEnd.getValue() ) - { - Real DT = m_tEnd.getValue() - m_tBegin.getValue(); - const SetIndexArray & indices = m_indices.getValue(); - - t -= m_tBegin.getValue(); - Real u = t/DT; - - Real dH00, dH10, dH01, dH11; - computeDerivateHermiteCoefs( u, dH00, dH10, dH01, dH11); - - for(SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - dx[*it] = m_x0.getValue()*dH00 + m_dx0.getValue()*dH10 + m_x1.getValue()*dH01 + m_dx1.getValue()*dH11; - } - } -} - -template -void HermiteSplineConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) -{ - helper::WriteAccessor x = xData; - Real t = (Real) this->getContext()->getTime(); - - if ( t >= m_tBegin.getValue() && t <= m_tEnd.getValue() ) - { - Real DT = m_tEnd.getValue() - m_tBegin.getValue(); - const SetIndexArray & indices = m_indices.getValue(); - - t -= m_tBegin.getValue(); - Real u = t/DT; - - Real H00, H10, H01, H11; - computeHermiteCoefs( u, H00, H10, H01, H11); - - for(SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - x[*it] = m_x0.getValue()*H00 + m_dx0.getValue()*H10 + m_x1.getValue()*H01 + m_dx1.getValue()*H11; - } - } -} - -template -void HermiteSplineConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) -{ - SOFA_UNUSED(mparams); - helper::WriteAccessor c = cData; - - projectResponseT(c.wref(), [](MatrixDeriv& res, const unsigned int index) { res.clearColBlock(index); }); -} - -template -void HermiteSplineConstraint::draw(const core::visual::VisualParams* vparams) -{ - if (!vparams->displayFlags().getShowBehaviorModels()) return; - - Real dt = (Real) this->getContext()->getDt(); - Real DT = m_tEnd.getValue() - m_tBegin.getValue(); - - const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); - vparams->drawTool()->disableLighting(); - - std::vector vertices; - constexpr sofa::type::RGBAColor color(1, 0.5, 0.5, 1); - - const Vec3R& mx0 = m_x0.getValue(); - const Vec3R& mx1 = m_x0.getValue(); - const Vec3R& mdx0 = m_dx0.getValue(); - const Vec3R& mdx1 = m_dx1.getValue(); - - for (Real t=0.0 ; t< DT ; t+= dt) - { - Real u = t/DT; - - Real H00, H10, H01, H11; - computeHermiteCoefs( u, H00, H10, H01, H11); - - Vec3R p = mx0*H00 + mdx0*H10 + mx1*H01 + mdx1*H11; - - sofa::type::Vec3 v(p[0], p[1],p[2]); - vertices.push_back(v); - } - vparams->drawTool()->drawLineStrip(vertices, 2, color); - - vertices.clear(); - vertices.push_back(sofa::type::Vec3(mx0[0], mx0[1], mx0[2])); - vertices.push_back(sofa::type::Vec3(mx1[0], mx1[1], mx1[2])); - - vparams->drawTool()->drawPoints(vertices, 5.0, sofa::type::RGBAColor::red()); - - //display control tangents - vertices.clear(); - vertices.push_back(mx0); - vertices.push_back(mx0 + mdx0*0.1); - vertices.push_back(mx1); - vertices.push_back(mx1 + mdx1*0.1); - - vparams->drawTool()->drawLines(vertices, 1.0, sofa::type::RGBAColor::red()); - -} - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/HermiteSplineProjectiveConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineProjectiveConstraint.cpp similarity index 77% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineProjectiveConstraint.cpp index 1d6ec21d8bb..aa10b586bf7 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineProjectiveConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_HERMITESPLINECONSTRAINT_CPP -#include +#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_HERMITESPLINEPROJECTIVECONSTRAINT_CPP +#include #include #include #include @@ -28,18 +28,18 @@ namespace sofa::component::constraint::projective { -int HermiteSplineConstraintClass = core::RegisterObject("Apply a hermite cubic spline trajectory to given points") - .add< HermiteSplineConstraint >() - .add< HermiteSplineConstraint >() +int HermiteSplineProjectiveConstraintClass = core::RegisterObject("Apply a hermite cubic spline trajectory to given points") + .add< HermiteSplineProjectiveConstraint >() + .add< HermiteSplineProjectiveConstraint >() ; template <> -void HermiteSplineConstraint::init() +void HermiteSplineProjectiveConstraint::init() { this->core::behavior::ProjectiveConstraintSet::init(); } -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API HermiteSplineConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API HermiteSplineConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API HermiteSplineProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API HermiteSplineProjectiveConstraint; } // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineProjectiveConstraint.h new file mode 100644 index 00000000000..1777e0bda2f --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineProjectiveConstraint.h @@ -0,0 +1,134 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +/** + Impose a trajectory to given Dofs following a Hermite cubic spline constraint. + Control parameters are : + - begin and end points + - derivates at this points + - acceleration curve on the trajectory + */ +template +class HermiteSplineProjectiveConstraint : public core::behavior::ProjectiveConstraintSet +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(HermiteSplineProjectiveConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, DataTypes)); + + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename Coord::value_type Real; + typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; + typedef typename MatrixDeriv::RowType MatrixDerivRowType; + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef Data DataMatrixDeriv; + typedef type::vector SetIndexArray; + typedef sofa::core::topology::TopologySubsetIndices SetIndex; + typedef typename type::Vec<3, Real> Vec3R; + typedef typename type::Vec<2, Real> Vec2R; + typedef typename type::Quat QuatR; + +public: + ///indices of the DOFs constraints + SetIndex m_indices; + + /// the time steps defining the duration of the constraint + Data m_tBegin; + Data m_tEnd; ///< End Time of the motion + + /// control parameters : + /// first control point + Data m_x0; + /// first derivated control point + Data m_dx0; + /// second control point + Data m_x1; + /// second derivated control point + Data m_dx1; + /// acceleration parameters : the accaleration curve is itself a hermite spline, with first point at (0,0) and second at (1,1) + /// and derivated on this points are : + Data m_sx0; + Data m_sx1; ///< second interpolation vector + + /// Link to be set to the topology container in the component graph. + SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; + +protected: + explicit HermiteSplineProjectiveConstraint(core::behavior::MechanicalState* mstate = nullptr); + + ~HermiteSplineProjectiveConstraint(); +public: + void clearConstraints(); + void addConstraint(unsigned index ); + + void setBeginTime(const Real &t) {m_tBegin.setValue(t);} + void setEndTime(const Real &t) {m_tEnd.setValue(t);} + + Real getBeginTime() {return m_tBegin.getValue();} + Real getEndTime() {return m_tEnd.getValue();} + + void computeHermiteCoefs( const Real u, Real &H00, Real &H10, Real &H01, Real &H11); + void computeDerivateHermiteCoefs( const Real u, Real &dH00, Real &dH10, Real &dH01, Real &dH11); + + /// -- Constraint interface + void init() override; + void reinit() override; + + + void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; + void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; + void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; + void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; + + void draw(const core::visual::VisualParams* vparams) override; + +protected: + template + void projectResponseT(DataDeriv& dx, + const std::function& clear); + +}; + +template <> +void SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API HermiteSplineProjectiveConstraint::init(); + + +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_HERMITESPLINEPROJECTIVECONSTRAINT_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API HermiteSplineProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API HermiteSplineProjectiveConstraint; + +#endif + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineProjectiveConstraint.inl new file mode 100644 index 00000000000..eeef7815197 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/HermiteSplineProjectiveConstraint.inl @@ -0,0 +1,267 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +template +HermiteSplineProjectiveConstraint::HermiteSplineProjectiveConstraint(core::behavior::MechanicalState* mstate) + : core::behavior::ProjectiveConstraintSet(mstate) + , m_indices( initData(&m_indices,"indices","Indices of the constrained points") ) + , m_tBegin(initData(&m_tBegin,"BeginTime","Begin Time of the motion") ) + , m_tEnd(initData(&m_tEnd,"EndTime","End Time of the motion") ) + , m_x0(initData(&m_x0,"X0","first control point") ) + , m_dx0(initData(&m_dx0,"dX0","first control tangente") ) + , m_x1(initData(&m_x1,"X1","second control point") ) + , m_dx1(initData(&m_dx1,"dX1","sceond control tangente") ) + , m_sx0(initData(&m_sx0,"SX0","first interpolation vector") ) + , m_sx1(initData(&m_sx1,"SX1","second interpolation vector") ) + , l_topology(initLink("topology", "link to the topology container")) +{ +} + +template +HermiteSplineProjectiveConstraint::~HermiteSplineProjectiveConstraint() +{ +} + +template +void HermiteSplineProjectiveConstraint::clearConstraints() +{ + m_indices.beginEdit()->clear(); + m_indices.endEdit(); +} + +template +void HermiteSplineProjectiveConstraint::addConstraint(unsigned index) +{ + m_indices.beginEdit()->push_back(index); + m_indices.endEdit(); +} + + +template +void HermiteSplineProjectiveConstraint::init() +{ + this->core::behavior::ProjectiveConstraintSet::init(); + + if (l_topology.empty()) + { + msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; + l_topology.set(this->getContext()->getMeshTopologyLink()); + } + + if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) + { + msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; + + // Initialize functions and parameters for topology data and handler + m_indices.createTopologyHandler(_topology); + } + else + { + msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; + } +} + +template +void HermiteSplineProjectiveConstraint::reinit() +{ + init(); +} + + +template +void HermiteSplineProjectiveConstraint::computeHermiteCoefs( const Real u, Real &H00, Real &H10, Real &H01, Real &H11) +{ + //-- time interpolation --> acceleration is itself computed from hemite + Real u2 = u*u; + Real u3 = u*u*u; + //Real uH00 = 2*u3 -3*u2 +1 ; //hermite coefs + Real uH10 = u3 -2*u2 +u; + Real uH01 = -2*u3 + 3*u2; + Real uH11 = u3 -u2; + Vec2R pu = m_sx0.getValue()*uH10 + Vec2R(1,1)*uH01 + m_sx1.getValue()*uH11; + Real su = pu.y(); + + Real su2 = su*su; + Real su3 = su*su*su; + H00 = 2*su3 -3*su2 +1 ; + H10 = su3 -2*su2 +su; + H01 = -2*su3 + 3*su2; + H11 = su3 -su2; +} + +template +void HermiteSplineProjectiveConstraint::computeDerivateHermiteCoefs( const Real u, Real &dH00, Real &dH10, Real &dH01, Real &dH11) +{ + //-- time interpolation --> acceleration is itself computed from hemite + Real u2 = u*u; + Real u3 = u*u*u; + Real uH10 = u3 -2*u2 +u; + Real uH01 = -2*u3 + 3*u2; + Real uH11 = u3 -u2; + Vec2R pu = m_sx0.getValue()*uH10 + Vec2R(1,1)*uH01 + m_sx1.getValue()*uH11; + Real su = pu.y(); + + Real su2 = su*su; + dH00 = 6*su2 -6*su ; + dH10 = 3*su2 -4*su +1; + dH01 = -6*su2 + 6*su; + dH11 = 3*su2 -2*su; +} + + +template template +void HermiteSplineProjectiveConstraint::projectResponseT(DataDeriv& dx, + const std::function& clear) +{ + Real t = (Real) this->getContext()->getTime(); + if ( t >= m_tBegin.getValue() && t <= m_tEnd.getValue()) + { + const SetIndexArray & indices = m_indices.getValue(); + for(SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + clear(dx, *it); + } +} + +template +void HermiteSplineProjectiveConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) +{ + SOFA_UNUSED(mparams); + helper::WriteAccessor res = resData; + projectResponseT(res.wref(), [](auto& dx, const unsigned int index) {dx[index].clear();}); +} + +template +void HermiteSplineProjectiveConstraint::projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& vData) +{ + helper::WriteAccessor dx = vData; + Real t = (Real) this->getContext()->getTime(); + + if ( t >= m_tBegin.getValue() && t <= m_tEnd.getValue() ) + { + Real DT = m_tEnd.getValue() - m_tBegin.getValue(); + const SetIndexArray & indices = m_indices.getValue(); + + t -= m_tBegin.getValue(); + Real u = t/DT; + + Real dH00, dH10, dH01, dH11; + computeDerivateHermiteCoefs( u, dH00, dH10, dH01, dH11); + + for(SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + dx[*it] = m_x0.getValue()*dH00 + m_dx0.getValue()*dH10 + m_x1.getValue()*dH01 + m_dx1.getValue()*dH11; + } + } +} + +template +void HermiteSplineProjectiveConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) +{ + helper::WriteAccessor x = xData; + Real t = (Real) this->getContext()->getTime(); + + if ( t >= m_tBegin.getValue() && t <= m_tEnd.getValue() ) + { + Real DT = m_tEnd.getValue() - m_tBegin.getValue(); + const SetIndexArray & indices = m_indices.getValue(); + + t -= m_tBegin.getValue(); + Real u = t/DT; + + Real H00, H10, H01, H11; + computeHermiteCoefs( u, H00, H10, H01, H11); + + for(SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + x[*it] = m_x0.getValue()*H00 + m_dx0.getValue()*H10 + m_x1.getValue()*H01 + m_dx1.getValue()*H11; + } + } +} + +template +void HermiteSplineProjectiveConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) +{ + SOFA_UNUSED(mparams); + helper::WriteAccessor c = cData; + + projectResponseT(c.wref(), [](MatrixDeriv& res, const unsigned int index) { res.clearColBlock(index); }); +} + +template +void HermiteSplineProjectiveConstraint::draw(const core::visual::VisualParams* vparams) +{ + if (!vparams->displayFlags().getShowBehaviorModels()) return; + + Real dt = (Real) this->getContext()->getDt(); + Real DT = m_tEnd.getValue() - m_tBegin.getValue(); + + const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); + vparams->drawTool()->disableLighting(); + + std::vector vertices; + constexpr sofa::type::RGBAColor color(1, 0.5, 0.5, 1); + + const Vec3R& mx0 = m_x0.getValue(); + const Vec3R& mx1 = m_x0.getValue(); + const Vec3R& mdx0 = m_dx0.getValue(); + const Vec3R& mdx1 = m_dx1.getValue(); + + for (Real t=0.0 ; t< DT ; t+= dt) + { + Real u = t/DT; + + Real H00, H10, H01, H11; + computeHermiteCoefs( u, H00, H10, H01, H11); + + Vec3R p = mx0*H00 + mdx0*H10 + mx1*H01 + mdx1*H11; + + sofa::type::Vec3 v(p[0], p[1],p[2]); + vertices.push_back(v); + } + vparams->drawTool()->drawLineStrip(vertices, 2, color); + + vertices.clear(); + vertices.push_back(sofa::type::Vec3(mx0[0], mx0[1], mx0[2])); + vertices.push_back(sofa::type::Vec3(mx1[0], mx1[1], mx1[2])); + + vparams->drawTool()->drawPoints(vertices, 5.0, sofa::type::RGBAColor::red()); + + //display control tangents + vertices.clear(); + vertices.push_back(mx0); + vertices.push_back(mx0 + mdx0*0.1); + vertices.push_back(mx1); + vertices.push_back(mx1 + mdx1*0.1); + + vparams->drawTool()->drawLines(vertices, 1.0, sofa::type::RGBAColor::red()); + +} + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPlaneConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LineProjectiveConstraint.cpp similarity index 80% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPlaneConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LineProjectiveConstraint.cpp index 8d584ac88e0..e22a8f51b56 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPlaneConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LineProjectiveConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ProjectToPlaneConstraint_CPP -#include +#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_LineProjectiveConstraint_CPP +#include #include namespace sofa::component::constraint::projective @@ -30,14 +30,12 @@ using namespace sofa::defaulttype; using namespace sofa::helper; -int ProjectToPlaneConstraintClass = core::RegisterObject("Attach given particles to their initial positions") - .add< ProjectToPlaneConstraint >() - .add< ProjectToPlaneConstraint >() - +int LineProjectiveConstraintClass = core::RegisterObject("Attach given particles to their initial positions") + .add< LineProjectiveConstraint >() + .add< LineProjectiveConstraint >() ; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToPlaneConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToPlaneConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LineProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LineProjectiveConstraint; } // namespace sofa::component::constraint::projective - diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LineProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LineProjectiveConstraint.h new file mode 100644 index 00000000000..5a907598823 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LineProjectiveConstraint.h @@ -0,0 +1,137 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +/// This class can be overridden if needed for additionnal storage within template specializations. +template +class LineProjectiveConstraintInternalData +{ + +}; + +/** Project particles to an affine straight line. + @author Francois Faure, 2012 + @todo Optimized versions for lines parallel to the main directions +*/ +template +class LineProjectiveConstraint : public core::behavior::ProjectiveConstraintSet +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(LineProjectiveConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, DataTypes)); + + using Index = sofa::Index; + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::CPos CPos; + typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; + typedef typename MatrixDeriv::RowType MatrixDerivRowType; + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef Data DataMatrixDeriv; + SOFA_ATTRIBUTE_REPLACED__TYPEMEMBER(Vector3, sofa::type::Vec3); + typedef type::vector Indices; + typedef sofa::core::topology::TopologySubsetIndices IndexSubsetData; + typedef linearalgebra::EigenBaseSparseMatrix BaseSparseMatrix; + typedef linearalgebra::EigenSparseMatrix SparseMatrix; + typedef typename SparseMatrix::Block Block; ///< projection matrix of a particle displacement to the plane + enum {bsize=SparseMatrix::Nin}; ///< size of a block + + +protected: + LineProjectiveConstraint(); + + virtual ~LineProjectiveConstraint(); + +public: + IndexSubsetData f_indices; ///< the particles to project + Data f_drawSize; ///< The size of the square used to display the constrained particles + Data f_origin; ///< A point on the line + Data f_direction; ///< The direction of the line. Will be normalized by init() + + /// Link to be set to the topology container in the component graph. + SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; + +protected: + LineProjectiveConstraintInternalData* data; + friend class LineProjectiveConstraintInternalData; + + +public: + void clearConstraints(); + void addConstraint(Index index); + void removeConstraint(Index index); + + // -- Constraint interface + void init() override; + void reinit() override; + + void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; + void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; + void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; + void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; + + void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + + /// Project the given matrix (Experimental API, see the spec in sofa::core::behavior::BaseProjectiveConstraintSet). + void projectMatrix( sofa::linearalgebra::BaseMatrix* /*M*/, unsigned /*offset*/ ) override; + + + void draw(const core::visual::VisualParams* vparams) override; + +protected : + + SparseMatrix jacobian; ///< projection matrix in local state + SparseMatrix J; ///< auxiliary variable + + /// Resize/update Jacobian matrix according to the linked mechanical state and the direction + void updateJacobian(); + +}; + + +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_LineProjectiveConstraint_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LineProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LineProjectiveConstraint; +#endif + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LineProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LineProjectiveConstraint.inl new file mode 100644 index 00000000000..2111e6be0f1 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LineProjectiveConstraint.inl @@ -0,0 +1,286 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +template +LineProjectiveConstraint::LineProjectiveConstraint() + : core::behavior::ProjectiveConstraintSet(nullptr) + , f_indices( initData(&f_indices,"indices","Indices of the fixed points") ) + , f_drawSize( initData(&f_drawSize,(SReal)0.0,"drawSize","0 -> point based rendering, >0 -> radius of spheres") ) + , f_origin( initData(&f_origin,CPos(),"origin","A point in the line")) + , f_direction( initData(&f_direction,CPos(),"direction","Direction of the line")) + , l_topology(initLink("topology", "link to the topology container")) + , data(new LineProjectiveConstraintInternalData()) +{ + f_indices.beginEdit()->push_back(0); + f_indices.endEdit(); +} + + +template +LineProjectiveConstraint::~LineProjectiveConstraint() +{ + delete data; +} + +template +void LineProjectiveConstraint::clearConstraints() +{ + f_indices.beginEdit()->clear(); + f_indices.endEdit(); +} + +template +void LineProjectiveConstraint::addConstraint(Index index) +{ + f_indices.beginEdit()->push_back(index); + f_indices.endEdit(); +} + +template +void LineProjectiveConstraint::removeConstraint(Index index) +{ + sofa::type::removeValue(*f_indices.beginEdit(),index); + f_indices.endEdit(); +} + +// -- Constraint interface + + +template +void LineProjectiveConstraint::init() +{ + this->core::behavior::ProjectiveConstraintSet::init(); + + if (l_topology.empty()) + { + msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; + l_topology.set(this->getContext()->getMeshTopologyLink()); + } + + if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) + { + msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; + + // Initialize topological changes support + f_indices.createTopologyHandler(_topology); + } + else + { + msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; + } + + const Indices & indices = f_indices.getValue(); + + const Index maxIndex=this->mstate->getSize(); + for (unsigned int i=0; i= maxIndex) + { + msg_error() << "Index " << index << " not valid!"; + removeConstraint(index); + } + } + + updateJacobian(); +} + +template +void LineProjectiveConstraint::reinit() +{ + updateJacobian(); +} + +template +void LineProjectiveConstraint::updateJacobian() +{ + // normalize the normal vector + CPos n = f_direction.getValue(); + if( n.norm()==0 ) + n[0]=1; // arbritary normal vector + else n *= 1/n.norm(); + f_direction.setValue(n); + + // create the matrix blocks corresponding to the projection to the line: nn^t or to the identity + Block bProjection; + for(unsigned i=0; imstate->getSize(); + const unsigned blockSize = DataTypes::deriv_total_size; + jacobian.resize( numBlocks*blockSize,numBlocks*blockSize ); + + // fill the jacobian in ascending order + Indices::const_iterator it = tmp.begin(); + unsigned i = 0; + while( i < numBlocks ) // (FF) do not stop after the last constrained particle, for the remainder of the diagonal would be null, while it must be identity. + { + if( it!=tmp.end() && i==*it ) // constrained particle: set diagonal to projection block, and the cursor to the next constraint + { + jacobian.insertBackBlock(i,i,bProjection); + ++it; + } + else // unconstrained particle: set diagonal to identity block + { + jacobian.insertBackBlock(i,i,Block::Identity()); + } + i++; + } + jacobian.compress(); +} + +template +void LineProjectiveConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) +{ + J.copy(jacobian, M->colSize(), offset); // projection matrix for an assembled state + BaseSparseMatrix* E = dynamic_cast(M); + assert(E); + E->compressedMatrix = J.compressedMatrix * E->compressedMatrix * J.compressedMatrix; +} + + + +template +void LineProjectiveConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) +{ + SOFA_UNUSED(mparams); + + helper::WriteAccessor res(resData); + + using Size = decltype(jacobian.colSize()); + if( (jacobian.colSize() / Size(DataTypes::deriv_total_size)) != Size(res.size())) + { + updateJacobian(); + } + + jacobian.mult(res.wref(),res.ref()); +} + +template +void LineProjectiveConstraint::projectJacobianMatrix(const core::MechanicalParams* /*mparams*/ , DataMatrixDeriv& /*cData*/) +{ + msg_error() << "projectJacobianMatrix(const core::MechanicalParams*, DataMatrixDeriv& ) is not implemented"; +} + +template +void LineProjectiveConstraint::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) +{ + projectResponse(mparams,vData); +} + +template +void LineProjectiveConstraint::projectPosition(const core::MechanicalParams* /*mparams*/ , DataVecCoord& xData) +{ + VecCoord& x = *xData.beginEdit(); + + const CPos& n = f_direction.getValue(); + const CPos& o = f_origin.getValue(); + + const Indices& indices = f_indices.getValue(); + for(unsigned i=0; i +void LineProjectiveConstraint::applyConstraint(const core::MechanicalParams* /*mparams*/, const sofa::core::behavior::MultiMatrixAccessor* /*matrix*/) +{ + msg_error() << "applyConstraint is not implemented "; +} + +template +void LineProjectiveConstraint::applyConstraint(const core::MechanicalParams* /*mparams*/, linearalgebra::BaseVector* /*vector*/, const sofa::core::behavior::MultiMatrixAccessor* /*matrix*/) +{ + msg_error() << "LineProjectiveConstraint::applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) is not implemented "; +} + + + + +template +void LineProjectiveConstraint::draw(const core::visual::VisualParams* vparams) +{ + if (!vparams->displayFlags().getShowBehaviorModels()) return; + if (!this->isActive()) return; + const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); + + const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); + + const Indices & indices = f_indices.getValue(); + + if( f_drawSize.getValue() == 0) // old classical drawing by points + { + std::vector< sofa::type::Vec3 > points; + sofa::type::Vec3 point; + + for (Indices::const_iterator it = indices.begin(); + it != indices.end(); + ++it) + { + point = DataTypes::getCPos(x[*it]); + points.push_back(point); + } + vparams->drawTool()->drawPoints(points, 10, sofa::type::RGBAColor(1,0.5,0.5,1)); + } + else // new drawing by spheres + { + std::vector< sofa::type::Vec3 > points; + sofa::type::Vec3 point; + for (unsigned int index : indices) + { + point = DataTypes::getCPos(x[index]); + points.push_back(point); + } + vparams->drawTool()->drawSpheres(points, (float)f_drawSize.getValue(), sofa::type::RGBAColor(1.0f,0.35f,0.35f,1.0f)); + } + + +} + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementConstraint.h index 4df6f686718..f06082811df 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementConstraint.h @@ -20,149 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -template -class LinearMovementConstraintInternalData -{ -}; +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/LinearMovementProjectiveConstraint.h") -/** impose a motion to given DOFs (translation and rotation) - The motion between 2 key times is linearly interpolated - Rigid version doesn't handle Topology change. -*/ -template -class LinearMovementConstraint : public core::behavior::ProjectiveConstraintSet +namespace sofa::component::constraint::projective { -public: - SOFA_CLASS(SOFA_TEMPLATE(LinearMovementConstraint,TDataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, TDataTypes)); - - using Index = sofa::Index; - typedef TDataTypes DataTypes; - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::Real Real; - typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; - typedef typename MatrixDeriv::RowType MatrixDerivRowType; - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef Data DataMatrixDeriv; - typedef type::vector SetIndexArray; - typedef sofa::core::topology::TopologySubsetIndices SetIndex; - -protected: - LinearMovementConstraintInternalData *data; - friend class LinearMovementConstraintInternalData; - -public : - /// indices of the DOFs the constraint is applied to - SetIndex m_indices; - /// the key frames when the motion is defined by the user - Data > m_keyTimes; - /// the motions corresponding to the key frames - Data m_keyMovements; - - /// indicates whether movements are relative to the dof or absolute - Data< bool > d_relativeMovements; - - /// attributes to precise display - /// if showMovement is true we display the expected movement - /// otherwise we show which are the fixed dofs - Data< bool > showMovement; - - - /// the key times surrounding the current simulation time (for interpolation) - Real prevT, nextT; - ///the motions corresponding to the surrouding key times - Deriv prevM, nextM; - ///initial constrained DOFs position - VecCoord x0; - - /// Link to be set to the topology container in the component graph. - SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; - -protected: - LinearMovementConstraint(); - ~LinearMovementConstraint() override; - -public: - ///methods to add/remove some indices, keyTimes, keyMovement - void clearIndices(); - void addIndex(Index index); - void removeIndex(Index index); - void clearKeyMovements(); - - ///@brief Add a new key movement - /// @param time : the simulation time you want to set a movement (in sec) - /// @param movement : the corresponding motion - /// for instance, addKeyMovement(1.0, Deriv(5,0,0) ) will set a translation of 5 in x direction a time 1.0s - /// - void addKeyMovement(Real time, Deriv movement); - - /// -- Constraint interface - void init() override; - void reset() override; - - void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; - void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; - void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; - void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; - - void projectMatrix( sofa::linearalgebra::BaseMatrix* /*M*/, unsigned /*offset*/ ) override; - - void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - void applyConstraint(sofa::core::behavior::ZeroDirichletCondition* matrix) override; - - void draw(const core::visual::VisualParams* vparams) override; - -protected: - template - void projectResponseT(DataDeriv& dx, - const std::function& clear); - - template - void interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x); - template - void interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x); - -private: - /// to keep the time corresponding to the key times - Real currentTime; - - /// to know if we found the key times - bool finished; - - /// find previous and next time keys - void findKeyTimes(); -}; - - -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_LINEARMOVEMENTCONSTRAINT_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementConstraint; -#endif - -} // namespace sofa::component::constraint::projective +template +using LinearMovementConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "LinearMovementConstraint has been renamed to LinearMovementProjectiveConstraint") = LinearMovementProjectiveConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementConstraint.inl index d1700e27943..1a8538c38a0 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementConstraint.inl @@ -21,455 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -template -LinearMovementConstraint::LinearMovementConstraint() - : core::behavior::ProjectiveConstraintSet(nullptr) - , data(new LinearMovementConstraintInternalData) - , m_indices( initData(&m_indices,"indices","Indices of the constrained points") ) - , m_keyTimes( initData(&m_keyTimes,"keyTimes","key times for the movements") ) - , m_keyMovements( initData(&m_keyMovements,"movements","movements corresponding to the key times") ) - , d_relativeMovements( initData(&d_relativeMovements, bool(true), "relativeMovements", "If true, movements are relative to first position, absolute otherwise") ) - , showMovement( initData(&showMovement, bool(false), "showMovement", "Visualization of the movement to be applied to constrained dofs.")) - , l_topology(initLink("topology", "link to the topology container")) - , finished(false) -{ - // default to indice 0 - m_indices.beginEdit()->push_back(0); - m_indices.endEdit(); - - //default valueEvent to 0 - m_keyTimes.beginEdit()->push_back( 0.0 ); - m_keyTimes.endEdit(); - m_keyMovements.beginEdit()->push_back( Deriv() ); - m_keyMovements.endEdit(); -} - - - -template -LinearMovementConstraint::~LinearMovementConstraint() -{ - -} - -template -void LinearMovementConstraint::clearIndices() -{ - m_indices.beginEdit()->clear(); - m_indices.endEdit(); -} - -template -void LinearMovementConstraint::addIndex(Index index) -{ - m_indices.beginEdit()->push_back(index); - m_indices.endEdit(); -} - -template -void LinearMovementConstraint::removeIndex(Index index) -{ - sofa::type::removeValue(*m_indices.beginEdit(),index); - m_indices.endEdit(); -} - -template -void LinearMovementConstraint::clearKeyMovements() -{ - m_keyTimes.beginEdit()->clear(); - m_keyTimes.endEdit(); - m_keyMovements.beginEdit()->clear(); - m_keyMovements.endEdit(); -} - -template -void LinearMovementConstraint::addKeyMovement(Real time, Deriv movement) -{ - m_keyTimes.beginEdit()->push_back( time ); - m_keyTimes.endEdit(); - m_keyMovements.beginEdit()->push_back( movement ); - m_keyMovements.endEdit(); -} - -// -- Constraint interface -template -void LinearMovementConstraint::init() -{ - this->core::behavior::ProjectiveConstraintSet::init(); - - if (l_topology.empty()) - { - msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; - l_topology.set(this->getContext()->getMeshTopologyLink()); - } - - if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) - { - msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; - - // Initialize topological changes support - m_indices.createTopologyHandler(_topology); - } - else - { - msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; - } - - x0.resize(0); - nextM = prevM = Deriv(); - - currentTime = -1.0; - finished = false; -} - - -template -void LinearMovementConstraint::reset() -{ - nextT = prevT = 0.0; - nextM = prevM = Deriv(); - - currentTime = -1.0; - finished = false; -} - - -template -template -void LinearMovementConstraint::projectResponseT(DataDeriv& dx, - const std::function& clear) -{ - Real cT = static_cast(this->getContext()->getTime()); - if ((cT != currentTime) || !finished) - { - findKeyTimes(); - } - - if (finished && nextT != prevT) - { - const SetIndexArray & indices = m_indices.getValue(); - - //set the motion to the Dofs - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - clear(dx, *it); - } - } -} - -template -void LinearMovementConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) -{ - SOFA_UNUSED(mparams); - helper::WriteAccessor res = resData; - projectResponseT(res.wref(), [](auto& dx, const unsigned int index) {dx[index].clear(); }); -} - -template -void LinearMovementConstraint::projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& vData) -{ - helper::WriteAccessor dx = vData; - Real cT = static_cast(this->getContext()->getTime()); - if ((cT != currentTime) || !finished) - { - findKeyTimes(); - } - - if (finished && nextT != prevT) - { - const SetIndexArray & indices = m_indices.getValue(); - - //set the motion to the Dofs - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - dx[*it] = (nextM - prevM)*(1.0 / (nextT - prevT)); - } - } -} - - -template -void LinearMovementConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) -{ - helper::WriteAccessor x = xData; - Real cT = static_cast(this->getContext()->getTime()); - - //initialize initial Dofs positions, if it's not done - if (x0.size() == 0) - { - const SetIndexArray & indices = m_indices.getValue(); - x0.resize(x.size()); - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - x0[*it] = x[*it]; - } - } - - if ((cT != currentTime) || !finished) - { - findKeyTimes(); - } - - //if we found 2 keyTimes, we have to interpolate a velocity (linear interpolation) - if(finished && nextT != prevT) - { - interpolatePosition(cT, x.wref()); - } -} - -template -template -void LinearMovementConstraint::interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x) -{ - const SetIndexArray & indices = m_indices.getValue(); - - Real dt = (cT - prevT) / (nextT - prevT); - Deriv m = prevM + (nextM-prevM)*dt; - - //set the motion to the Dofs - if (d_relativeMovements.getValue()) - { - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - x[*it] = x0[*it] + m ; - } - } - else - { - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - x[*it] = m ; - } - } -} - -template -template -void LinearMovementConstraint::interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x) -{ - const SetIndexArray & indices = m_indices.getValue(); - - Real dt = (cT - prevT) / (nextT - prevT); - Deriv m = prevM + (nextM-prevM)*dt; - type::Quat prevOrientation = type::Quat::createQuaterFromEuler(getVOrientation(prevM)); - type::Quat nextOrientation = type::Quat::createQuaterFromEuler(getVOrientation(nextM)); - - //set the motion to the Dofs - if (d_relativeMovements.getValue()) - { - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - x[*it].getCenter() = x0[*it].getCenter() + getVCenter(m) ; - x[*it].getOrientation() = x0[*it].getOrientation() * prevOrientation.slerp2(nextOrientation, dt); - } - } - else - { - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - x[*it].getCenter() = getVCenter(m) ; - x[*it].getOrientation() = prevOrientation.slerp2(nextOrientation, dt); - } - } -} - -template -void LinearMovementConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) -{ - SOFA_UNUSED(mparams); - helper::WriteAccessor c = cData; - - projectResponseT(c.wref(), [](MatrixDeriv& res, const unsigned int index) { res.clearColBlock(index); }); -} - -template -void LinearMovementConstraint::findKeyTimes() -{ - Real cT = static_cast(this->getContext()->getTime()); - finished = false; - - if(m_keyTimes.getValue().size() != 0 && cT >= *m_keyTimes.getValue().begin() && cT <= *m_keyTimes.getValue().rbegin()) - { - nextT = *m_keyTimes.getValue().begin(); - prevT = nextT; - - typename type::vector::const_iterator it_t = m_keyTimes.getValue().begin(); - typename VecDeriv::const_iterator it_m = m_keyMovements.getValue().begin(); - - //WARNING : we consider that the key-events are in chronological order - //here we search between which keyTimes we are, to know which are the motion to interpolate - while( it_t != m_keyTimes.getValue().end() && !finished) - { - if( *it_t <= cT) - { - prevT = *it_t; - prevM = *it_m; - } - else - { - nextT = *it_t; - nextM = *it_m; - finished = true; - } - ++it_t; - ++it_m; - } - } -} - - -template -void LinearMovementConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) -{ - static const unsigned blockSize = DataTypes::deriv_total_size; - - // clears the rows and columns associated with fixed particles - for (const auto id : m_indices.getValue()) - { - M->clearRowsCols( offset + id * blockSize, offset + (id+1) * blockSize ); - } - -} - - -// Matrix Integration interface -template -void LinearMovementConstraint::applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) -{ - SOFA_UNUSED(mparams); - if(const core::behavior::MultiMatrixAccessor::MatrixRef r = matrix->getMatrix(this->mstate.get())) - { - const unsigned int N = Deriv::size(); - const SetIndexArray & indices = m_indices.getValue(); - - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - // Reset Fixed Row and Col - for (unsigned int c=0; cclearRowCol(r.offset + N * (*it) + c); - // Set Fixed Vertex - for (unsigned int c=0; cset(r.offset + N * (*it) + c, r.offset + N * (*it) + c, 1.0); - } - } -} - -template -void LinearMovementConstraint::applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) -{ - SOFA_UNUSED(mparams); - const int o = matrix->getGlobalOffset(this->mstate.get()); - if (o >= 0) - { - const unsigned int offset = (unsigned int)o; - const unsigned int N = Deriv::size(); - - const SetIndexArray & indices = m_indices.getValue(); - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - for (unsigned int c=0; cclear(offset + N * (*it) + c); - } - } -} - -template -void LinearMovementConstraint::applyConstraint( - sofa::core::behavior::ZeroDirichletCondition* matrix) -{ - constexpr unsigned int N = Deriv::size(); - - for (const auto index : m_indices.getValue()) - { - for (unsigned int c = 0; c < N; ++c) - { - matrix->discardRowCol(N * index + c, N * index + c); - } - } -} - -//display the path the constrained dofs will go through -template -void LinearMovementConstraint::draw(const core::visual::VisualParams* vparams) -{ - if (!vparams->displayFlags().getShowBehaviorModels() || m_keyTimes.getValue().size() == 0) - return; - - const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); - constexpr sofa::type::RGBAColor color(1, 0.5, 0.5, 1); - - if (showMovement.getValue()) - { - vparams->drawTool()->disableLighting(); - - std::vector vertices; - - constexpr auto minDimensions = std::min(DataTypes::spatial_dimensions, 3u); - - const SetIndexArray & indices = m_indices.getValue(); - const VecDeriv& keyMovements = m_keyMovements.getValue(); - if (d_relativeMovements.getValue()) - { - for (unsigned int i = 0; i < m_keyMovements.getValue().size() - 1; i++) - { - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - const auto& tmp0 = DataTypes::getCPos(x0[*it]) + DataTypes::getDPos(keyMovements[i]); - const auto& tmp1 = DataTypes::getCPos(x0[*it]) + DataTypes::getDPos(keyMovements[i + 1]); - sofa::type::Vec3 v0, v1; - std::copy_n(tmp0.begin(), minDimensions, v0.begin()); - std::copy_n(tmp1.begin(), minDimensions, v1.begin()); - vertices.push_back(v0); - vertices.push_back(v1); - } - } - } - else - { - for (unsigned int i = 0; i < keyMovements.size() - 1; i++) - { - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - const auto& tmp0 = DataTypes::getDPos(keyMovements[i]); - const auto& tmp1 = DataTypes::getDPos(keyMovements[i + 1]); - sofa::type::Vec3 v0, v1; - std::copy_n(tmp0.begin(), minDimensions, v0.begin()); - std::copy_n(tmp1.begin(), minDimensions, v1.begin()); - vertices.push_back(v0); - vertices.push_back(v1); - } - } - } - vparams->drawTool()->drawLines(vertices, 10, color); - } - else - { - const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); - - sofa::type::vector points; - type::Vec3 point; - const SetIndexArray & indices = m_indices.getValue(); - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - point = DataTypes::getCPos(x[*it]); - points.push_back(point); - } - vparams->drawTool()->drawPoints(points, 10, color); - } - - -} - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/LinearMovementProjectiveConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementProjectiveConstraint.cpp similarity index 71% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementProjectiveConstraint.cpp index 3c47dc2dbce..e3f98526572 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementProjectiveConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_LINEARMOVEMENTCONSTRAINT_CPP -#include +#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_LINEARMOVEMENTPROJECTIVECONSTRAINT_CPP +#include #include #include #include @@ -29,7 +29,7 @@ namespace sofa::component::constraint::projective { template <> SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API -void LinearMovementConstraint::init() +void LinearMovementProjectiveConstraint::init() { this->core::behavior::ProjectiveConstraintSet::init(); @@ -42,18 +42,19 @@ void LinearMovementConstraint::init() //declaration of the class, for the factory -int LinearMovementConstraintClass = core::RegisterObject("translate given particles") - .add< LinearMovementConstraint >() - .add< LinearMovementConstraint >() - .add< LinearMovementConstraint >() - .add< LinearMovementConstraint >() - .add< LinearMovementConstraint >(); - - -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementConstraint; +int LinearMovementProjectiveConstraintClass = core::RegisterObject("translate given particles") + .add< LinearMovementProjectiveConstraint >() + .add< LinearMovementProjectiveConstraint >() + .add< LinearMovementProjectiveConstraint >() + .add< LinearMovementProjectiveConstraint >() + .add< LinearMovementProjectiveConstraint >() + ; + + +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementProjectiveConstraint; } // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementProjectiveConstraint.h new file mode 100644 index 00000000000..b5013c890a0 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementProjectiveConstraint.h @@ -0,0 +1,168 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +template +class LinearMovementProjectiveConstraintInternalData +{ +}; + +/** impose a motion to given DOFs (translation and rotation) + The motion between 2 key times is linearly interpolated + Rigid version doesn't handle Topology change. +*/ +template +class LinearMovementProjectiveConstraint : public core::behavior::ProjectiveConstraintSet +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(LinearMovementProjectiveConstraint,TDataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, TDataTypes)); + + using Index = sofa::Index; + typedef TDataTypes DataTypes; + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::Real Real; + typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; + typedef typename MatrixDeriv::RowType MatrixDerivRowType; + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef Data DataMatrixDeriv; + typedef type::vector SetIndexArray; + typedef sofa::core::topology::TopologySubsetIndices SetIndex; + +protected: + LinearMovementProjectiveConstraintInternalData *data; + friend class LinearMovementProjectiveConstraintInternalData; + +public : + /// indices of the DOFs the constraint is applied to + SetIndex m_indices; + /// the key frames when the motion is defined by the user + Data > m_keyTimes; + /// the motions corresponding to the key frames + Data m_keyMovements; + + /// indicates whether movements are relative to the dof or absolute + Data< bool > d_relativeMovements; + + /// attributes to precise display + /// if showMovement is true we display the expected movement + /// otherwise we show which are the fixed dofs + Data< bool > showMovement; + + + /// the key times surrounding the current simulation time (for interpolation) + Real prevT, nextT; + ///the motions corresponding to the surrouding key times + Deriv prevM, nextM; + ///initial constrained DOFs position + VecCoord x0; + + /// Link to be set to the topology container in the component graph. + SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; + +protected: + LinearMovementProjectiveConstraint(); + ~LinearMovementProjectiveConstraint() override; + +public: + ///methods to add/remove some indices, keyTimes, keyMovement + void clearIndices(); + void addIndex(Index index); + void removeIndex(Index index); + void clearKeyMovements(); + + ///@brief Add a new key movement + /// @param time : the simulation time you want to set a movement (in sec) + /// @param movement : the corresponding motion + /// for instance, addKeyMovement(1.0, Deriv(5,0,0) ) will set a translation of 5 in x direction a time 1.0s + /// + void addKeyMovement(Real time, Deriv movement); + + /// -- Constraint interface + void init() override; + void reset() override; + + void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; + void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; + void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; + void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; + + void projectMatrix( sofa::linearalgebra::BaseMatrix* /*M*/, unsigned /*offset*/ ) override; + + void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + void applyConstraint(sofa::core::behavior::ZeroDirichletCondition* matrix) override; + + void draw(const core::visual::VisualParams* vparams) override; + +protected: + template + void projectResponseT(DataDeriv& dx, + const std::function& clear); + + template + void interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x); + template + void interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x); + +private: + /// to keep the time corresponding to the key times + Real currentTime; + + /// to know if we found the key times + bool finished; + + /// find previous and next time keys + void findKeyTimes(); +}; + + +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_LINEARMOVEMENTPROJECTIVECONSTRAINT_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementProjectiveConstraint; +#endif + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementProjectiveConstraint.inl new file mode 100644 index 00000000000..a5b6f81616b --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementProjectiveConstraint.inl @@ -0,0 +1,475 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +template +LinearMovementProjectiveConstraint::LinearMovementProjectiveConstraint() + : core::behavior::ProjectiveConstraintSet(nullptr) + , data(new LinearMovementProjectiveConstraintInternalData) + , m_indices( initData(&m_indices,"indices","Indices of the constrained points") ) + , m_keyTimes( initData(&m_keyTimes,"keyTimes","key times for the movements") ) + , m_keyMovements( initData(&m_keyMovements,"movements","movements corresponding to the key times") ) + , d_relativeMovements( initData(&d_relativeMovements, bool(true), "relativeMovements", "If true, movements are relative to first position, absolute otherwise") ) + , showMovement( initData(&showMovement, bool(false), "showMovement", "Visualization of the movement to be applied to constrained dofs.")) + , l_topology(initLink("topology", "link to the topology container")) + , finished(false) +{ + // default to indice 0 + m_indices.beginEdit()->push_back(0); + m_indices.endEdit(); + + //default valueEvent to 0 + m_keyTimes.beginEdit()->push_back( 0.0 ); + m_keyTimes.endEdit(); + m_keyMovements.beginEdit()->push_back( Deriv() ); + m_keyMovements.endEdit(); +} + + + +template +LinearMovementProjectiveConstraint::~LinearMovementProjectiveConstraint() +{ + +} + +template +void LinearMovementProjectiveConstraint::clearIndices() +{ + m_indices.beginEdit()->clear(); + m_indices.endEdit(); +} + +template +void LinearMovementProjectiveConstraint::addIndex(Index index) +{ + m_indices.beginEdit()->push_back(index); + m_indices.endEdit(); +} + +template +void LinearMovementProjectiveConstraint::removeIndex(Index index) +{ + sofa::type::removeValue(*m_indices.beginEdit(),index); + m_indices.endEdit(); +} + +template +void LinearMovementProjectiveConstraint::clearKeyMovements() +{ + m_keyTimes.beginEdit()->clear(); + m_keyTimes.endEdit(); + m_keyMovements.beginEdit()->clear(); + m_keyMovements.endEdit(); +} + +template +void LinearMovementProjectiveConstraint::addKeyMovement(Real time, Deriv movement) +{ + m_keyTimes.beginEdit()->push_back( time ); + m_keyTimes.endEdit(); + m_keyMovements.beginEdit()->push_back( movement ); + m_keyMovements.endEdit(); +} + +// -- Constraint interface +template +void LinearMovementProjectiveConstraint::init() +{ + this->core::behavior::ProjectiveConstraintSet::init(); + + if (l_topology.empty()) + { + msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; + l_topology.set(this->getContext()->getMeshTopologyLink()); + } + + if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) + { + msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; + + // Initialize topological changes support + m_indices.createTopologyHandler(_topology); + } + else + { + msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; + } + + x0.resize(0); + nextM = prevM = Deriv(); + + currentTime = -1.0; + finished = false; +} + + +template +void LinearMovementProjectiveConstraint::reset() +{ + nextT = prevT = 0.0; + nextM = prevM = Deriv(); + + currentTime = -1.0; + finished = false; +} + + +template +template +void LinearMovementProjectiveConstraint::projectResponseT(DataDeriv& dx, + const std::function& clear) +{ + Real cT = static_cast(this->getContext()->getTime()); + if ((cT != currentTime) || !finished) + { + findKeyTimes(); + } + + if (finished && nextT != prevT) + { + const SetIndexArray & indices = m_indices.getValue(); + + //set the motion to the Dofs + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + clear(dx, *it); + } + } +} + +template +void LinearMovementProjectiveConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) +{ + SOFA_UNUSED(mparams); + helper::WriteAccessor res = resData; + projectResponseT(res.wref(), [](auto& dx, const unsigned int index) {dx[index].clear(); }); +} + +template +void LinearMovementProjectiveConstraint::projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& vData) +{ + helper::WriteAccessor dx = vData; + Real cT = static_cast(this->getContext()->getTime()); + if ((cT != currentTime) || !finished) + { + findKeyTimes(); + } + + if (finished && nextT != prevT) + { + const SetIndexArray & indices = m_indices.getValue(); + + //set the motion to the Dofs + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + dx[*it] = (nextM - prevM)*(1.0 / (nextT - prevT)); + } + } +} + + +template +void LinearMovementProjectiveConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) +{ + helper::WriteAccessor x = xData; + Real cT = static_cast(this->getContext()->getTime()); + + //initialize initial Dofs positions, if it's not done + if (x0.size() == 0) + { + const SetIndexArray & indices = m_indices.getValue(); + x0.resize(x.size()); + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + x0[*it] = x[*it]; + } + } + + if ((cT != currentTime) || !finished) + { + findKeyTimes(); + } + + //if we found 2 keyTimes, we have to interpolate a velocity (linear interpolation) + if(finished && nextT != prevT) + { + interpolatePosition(cT, x.wref()); + } +} + +template +template +void LinearMovementProjectiveConstraint::interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x) +{ + const SetIndexArray & indices = m_indices.getValue(); + + Real dt = (cT - prevT) / (nextT - prevT); + Deriv m = prevM + (nextM-prevM)*dt; + + //set the motion to the Dofs + if (d_relativeMovements.getValue()) + { + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + x[*it] = x0[*it] + m ; + } + } + else + { + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + x[*it] = m ; + } + } +} + +template +template +void LinearMovementProjectiveConstraint::interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x) +{ + const SetIndexArray & indices = m_indices.getValue(); + + Real dt = (cT - prevT) / (nextT - prevT); + Deriv m = prevM + (nextM-prevM)*dt; + type::Quat prevOrientation = type::Quat::createQuaterFromEuler(getVOrientation(prevM)); + type::Quat nextOrientation = type::Quat::createQuaterFromEuler(getVOrientation(nextM)); + + //set the motion to the Dofs + if (d_relativeMovements.getValue()) + { + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + x[*it].getCenter() = x0[*it].getCenter() + getVCenter(m) ; + x[*it].getOrientation() = x0[*it].getOrientation() * prevOrientation.slerp2(nextOrientation, dt); + } + } + else + { + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + x[*it].getCenter() = getVCenter(m) ; + x[*it].getOrientation() = prevOrientation.slerp2(nextOrientation, dt); + } + } +} + +template +void LinearMovementProjectiveConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) +{ + SOFA_UNUSED(mparams); + helper::WriteAccessor c = cData; + + projectResponseT(c.wref(), [](MatrixDeriv& res, const unsigned int index) { res.clearColBlock(index); }); +} + +template +void LinearMovementProjectiveConstraint::findKeyTimes() +{ + Real cT = static_cast(this->getContext()->getTime()); + finished = false; + + if(m_keyTimes.getValue().size() != 0 && cT >= *m_keyTimes.getValue().begin() && cT <= *m_keyTimes.getValue().rbegin()) + { + nextT = *m_keyTimes.getValue().begin(); + prevT = nextT; + + typename type::vector::const_iterator it_t = m_keyTimes.getValue().begin(); + typename VecDeriv::const_iterator it_m = m_keyMovements.getValue().begin(); + + //WARNING : we consider that the key-events are in chronological order + //here we search between which keyTimes we are, to know which are the motion to interpolate + while( it_t != m_keyTimes.getValue().end() && !finished) + { + if( *it_t <= cT) + { + prevT = *it_t; + prevM = *it_m; + } + else + { + nextT = *it_t; + nextM = *it_m; + finished = true; + } + ++it_t; + ++it_m; + } + } +} + + +template +void LinearMovementProjectiveConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) +{ + static const unsigned blockSize = DataTypes::deriv_total_size; + + // clears the rows and columns associated with fixed particles + for (const auto id : m_indices.getValue()) + { + M->clearRowsCols( offset + id * blockSize, offset + (id+1) * blockSize ); + } + +} + + +// Matrix Integration interface +template +void LinearMovementProjectiveConstraint::applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) +{ + SOFA_UNUSED(mparams); + if(const core::behavior::MultiMatrixAccessor::MatrixRef r = matrix->getMatrix(this->mstate.get())) + { + const unsigned int N = Deriv::size(); + const SetIndexArray & indices = m_indices.getValue(); + + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + // Reset Fixed Row and Col + for (unsigned int c=0; cclearRowCol(r.offset + N * (*it) + c); + // Set Fixed Vertex + for (unsigned int c=0; cset(r.offset + N * (*it) + c, r.offset + N * (*it) + c, 1.0); + } + } +} + +template +void LinearMovementProjectiveConstraint::applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) +{ + SOFA_UNUSED(mparams); + const int o = matrix->getGlobalOffset(this->mstate.get()); + if (o >= 0) + { + const unsigned int offset = (unsigned int)o; + const unsigned int N = Deriv::size(); + + const SetIndexArray & indices = m_indices.getValue(); + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + for (unsigned int c=0; cclear(offset + N * (*it) + c); + } + } +} + +template +void LinearMovementProjectiveConstraint::applyConstraint( + sofa::core::behavior::ZeroDirichletCondition* matrix) +{ + constexpr unsigned int N = Deriv::size(); + + for (const auto index : m_indices.getValue()) + { + for (unsigned int c = 0; c < N; ++c) + { + matrix->discardRowCol(N * index + c, N * index + c); + } + } +} + +//display the path the constrained dofs will go through +template +void LinearMovementProjectiveConstraint::draw(const core::visual::VisualParams* vparams) +{ + if (!vparams->displayFlags().getShowBehaviorModels() || m_keyTimes.getValue().size() == 0) + return; + + const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); + constexpr sofa::type::RGBAColor color(1, 0.5, 0.5, 1); + + if (showMovement.getValue()) + { + vparams->drawTool()->disableLighting(); + + std::vector vertices; + + constexpr auto minDimensions = std::min(DataTypes::spatial_dimensions, 3u); + + const SetIndexArray & indices = m_indices.getValue(); + const VecDeriv& keyMovements = m_keyMovements.getValue(); + if (d_relativeMovements.getValue()) + { + for (unsigned int i = 0; i < m_keyMovements.getValue().size() - 1; i++) + { + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + const auto& tmp0 = DataTypes::getCPos(x0[*it]) + DataTypes::getDPos(keyMovements[i]); + const auto& tmp1 = DataTypes::getCPos(x0[*it]) + DataTypes::getDPos(keyMovements[i + 1]); + sofa::type::Vec3 v0, v1; + std::copy_n(tmp0.begin(), minDimensions, v0.begin()); + std::copy_n(tmp1.begin(), minDimensions, v1.begin()); + vertices.push_back(v0); + vertices.push_back(v1); + } + } + } + else + { + for (unsigned int i = 0; i < keyMovements.size() - 1; i++) + { + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + const auto& tmp0 = DataTypes::getDPos(keyMovements[i]); + const auto& tmp1 = DataTypes::getDPos(keyMovements[i + 1]); + sofa::type::Vec3 v0, v1; + std::copy_n(tmp0.begin(), minDimensions, v0.begin()); + std::copy_n(tmp1.begin(), minDimensions, v1.begin()); + vertices.push_back(v0); + vertices.push_back(v1); + } + } + } + vparams->drawTool()->drawLines(vertices, 10, color); + } + else + { + const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); + + sofa::type::vector points; + type::Vec3 point; + const SetIndexArray & indices = m_indices.getValue(); + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + point = DataTypes::getCPos(x[*it]); + points.push_back(point); + } + vparams->drawTool()->drawPoints(points, 10, color); + } + + +} + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityConstraint.h index e347423b33b..297a56d6f2c 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityConstraint.h @@ -20,116 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace sofa::component::constraint::projective -{ +#include +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/LinearVelocityProjectiveConstraint.h") -/** impose a motion to given DOFs (translation and rotation) - The motion between 2 key times is linearly interpolated -*/ -template -class LinearVelocityConstraint : public core::behavior::ProjectiveConstraintSet +namespace sofa::component::constraint::projective { -public: - SOFA_CLASS(SOFA_TEMPLATE(LinearVelocityConstraint,TDataTypes),SOFA_TEMPLATE(core::behavior::ProjectiveConstraintSet,TDataTypes)); - - using Index = sofa::Index; - typedef TDataTypes DataTypes; - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::Real Real; - typedef typename MatrixDeriv::RowType MatrixDerivRowType; - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef Data DataMatrixDeriv; - typedef type::vector SetIndexArray; - typedef sofa::core::topology::TopologySubsetIndices SetIndex; - -public : - /// indices of the DOFs the constraint is applied to - SetIndex d_indices; - /// the key frames when the motion is defined by the user - Data > d_keyTimes; - /// the motions corresponding to the key frames - Data d_keyVelocities; - /// the coordinates on which to applay velocities - SetIndex d_coordinates; - - /// the key times surrounding the current simulation time (for interpolation) - Real prevT, nextT; - ///the velocities corresponding to the surrouding key times - Deriv prevV, nextV; - ///position at the initial step for constrained DOFs position - VecCoord x0; - ///position at the previous step for constrained DOFs position - VecCoord xP; - - /// Link to be set to the topology container in the component graph. - SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; - -protected: - LinearVelocityConstraint(); - - virtual ~LinearVelocityConstraint(); -public: - ///methods to add/remove some indices, keyTimes, keyVelocity - void clearIndices(); - void addIndex(Index index); - void removeIndex(Index index); - void clearKeyVelocities(); - /**add a new key movement - @param time : the simulation time you want to set a movement (in sec) - @param movement : the corresponding motion - for instance, addKeyMovement(1.0, Deriv(5,0,0) ) will set a translation of 5 in x direction a time 1.0s - **/ - void addKeyVelocity(Real time, Deriv movement); - - - /// -- Constraint interface - void init() override; - void reset() override; - void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; - void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; - void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; - void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; - - void draw(const core::visual::VisualParams* vparams) override; - -private: - - /// to keep the time corresponding to the key times - Real currentTime; - - /// to know if we found the key times - bool finished; - - /// find previous and next time keys - void findKeyTimes(); -}; - -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_LINEARVELOCITYCONSTRAINT_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityConstraint; - -#endif - -} // namespace sofa::component::constraint::projective +template +using LinearVelocityConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "LinearVelocityConstraint has been renamed to LinearVelocityProjectiveConstraint") = LinearVelocityProjectiveConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityConstraint.inl index 9457ccfcb94..4e9baec9e9f 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityConstraint.inl @@ -21,328 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include +#include - -namespace sofa::component::constraint::projective -{ - -template -LinearVelocityConstraint::LinearVelocityConstraint() - : core::behavior::ProjectiveConstraintSet(nullptr) - , d_indices( initData(&d_indices,"indices","Indices of the constrained points") ) - , d_keyTimes( initData(&d_keyTimes,"keyTimes","key times for the movements") ) - , d_keyVelocities( initData(&d_keyVelocities,"velocities","velocities corresponding to the key times") ) - , d_coordinates( initData(&d_coordinates, "coordinates", "coordinates on which to apply velocities") ) - , l_topology(initLink("topology", "link to the topology container")) - , finished(false) -{ - d_indices.beginEdit()->push_back(0); - d_indices.endEdit(); - - d_keyTimes.beginEdit()->push_back( 0.0 ); - d_keyTimes.endEdit(); - d_keyVelocities.beginEdit()->push_back( Deriv() ); - d_keyVelocities.endEdit(); -} - - -template -LinearVelocityConstraint::~LinearVelocityConstraint() -{ - -} - -template -void LinearVelocityConstraint::clearIndices() -{ - d_indices.beginEdit()->clear(); - d_indices.endEdit(); -} - -template -void LinearVelocityConstraint::addIndex(Index index) -{ - d_indices.beginEdit()->push_back(index); - d_indices.endEdit(); -} - -template -void LinearVelocityConstraint::removeIndex(Index index) -{ - sofa::type::removeValue(*d_indices.beginEdit(),index); - d_indices.endEdit(); -} - -template -void LinearVelocityConstraint::clearKeyVelocities() -{ - d_keyTimes.beginEdit()->clear(); - d_keyTimes.endEdit(); - d_keyVelocities.beginEdit()->clear(); - d_keyVelocities.endEdit(); -} - -template -void LinearVelocityConstraint::addKeyVelocity(Real time, Deriv movement) -{ - d_keyTimes.beginEdit()->push_back( time ); - d_keyTimes.endEdit(); - d_keyVelocities.beginEdit()->push_back( movement ); - d_keyVelocities.endEdit(); -} - -// -- Constraint interface - - -template -void LinearVelocityConstraint::init() -{ - this->core::behavior::ProjectiveConstraintSet::init(); - - if (l_topology.empty()) - { - msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; - l_topology.set(this->getContext()->getMeshTopologyLink()); - } - - if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) - { - msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; - - // Initialize topological changes support - d_indices.createTopologyHandler(_topology); - d_coordinates.createTopologyHandler(_topology); - } - else - { - msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; - } - - x0.resize(0); - xP.resize(0); - nextV = prevV = Deriv(); - - currentTime = -1.0; - finished = false; -} - -template -void LinearVelocityConstraint::reset() -{ - nextT = prevT = 0.0; - nextV = prevV = Deriv(); - - currentTime = -1.0; - finished = false; -} - - -template -void LinearVelocityConstraint::projectResponse(const core::MechanicalParams* /*mparams*/, DataVecDeriv& resData) -{ - helper::WriteAccessor res = resData; - VecDeriv& dx = res.wref(); - - Real cT = (Real) this->getContext()->getTime(); - if ((cT != currentTime) || !finished) - { - findKeyTimes(); - } - - if (finished && nextT != prevT) - { - const SetIndexArray & indices = d_indices.getValue(); - - //set the motion to the Dofs - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - dx[*it] = Deriv(); - } - } - -} - -template -void LinearVelocityConstraint::projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& vData) -{ - helper::WriteAccessor dx = vData; - Real cT = (Real) this->getContext()->getTime(); - - if ((cT != currentTime) || !finished) - { - findKeyTimes(); - } - - if (finished && nextT != prevT) - { - //if we found 2 keyTimes, we have to interpolate a velocity (linear interpolation) - Deriv v = ((nextV - prevV)*((cT - prevT)/(nextT - prevT))) + prevV; - - const SetIndexArray & indices = d_indices.getValue(); - const SetIndexArray & coordinates = d_coordinates.getValue(); - - if (coordinates.size() == 0) - { - //set the motion to the Dofs - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - dx[*it] = v; - } - } - else - { - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - for(SetIndexArray::const_iterator itInd = coordinates.begin(); itInd != coordinates.end(); ++itInd) - { - dx[*it][*itInd] = v[*itInd]; - } - } - } - } -} - - -template -void LinearVelocityConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) -{ - helper::WriteAccessor x = xData; - - //initialize initial Dofs positions, if it's not done - if (x0.size() == 0) - { - const SetIndexArray & indices = d_indices.getValue(); - x0.resize( x.size() ); - xP.resize( x.size() ); - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - x0[*it] = x[*it]; - xP[*it] = x0[*it]; - } - } - - Real cT = (Real) this->getContext()->getTime(); - - if ((cT != currentTime) || !finished) - { - findKeyTimes(); - } - - - Real dTsimu = (Real) this->getContext()->getDt(); - - - if(finished) - { - Real dt = (cT - prevT) / (nextT - prevT); - Deriv m = (nextV-prevV)*dt + prevV; - - const SetIndexArray & indices = d_indices.getValue(); - const SetIndexArray & coordinates = d_coordinates.getValue(); - - if (coordinates.size() == 0) - { - //set the motion to the Dofs - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - x[*it] = xP[*it] + m*dTsimu; - xP[*it] = x[*it]; - } - } - else - { - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - for(SetIndexArray::const_iterator itInd = coordinates.begin(); itInd != coordinates.end(); ++itInd) - { - x[*it][*itInd] = xP[*it][*itInd] + m[*itInd]*dTsimu; - xP[*it] = x[*it]; - } - } - } - } -} - -template -void LinearVelocityConstraint::findKeyTimes() -{ - Real cT = (Real) this->getContext()->getTime(); - finished = false; - - if(d_keyTimes.getValue().size() != 0 && cT >= *d_keyTimes.getValue().begin() && cT <= *d_keyTimes.getValue().rbegin()) - { - nextT = *d_keyTimes.getValue().begin(); - prevT = nextT; - - typename type::vector::const_iterator it_t = d_keyTimes.getValue().begin(); - typename VecDeriv::const_iterator it_v = d_keyVelocities.getValue().begin(); - - //WARNING : we consider that the key-events are in chronological order - //here we search between which keyTimes we are, to know which are the motion to interpolate - while( it_t != d_keyTimes.getValue().end() && !finished) - { - if( *it_t <= cT) - { - prevT = *it_t; - prevV = *it_v; - } - else - { - nextT = *it_t; - nextV = *it_v; - finished = true; - } - ++it_t; - ++it_v; - } - } -}// LinearVelocityConstraint::findKeyTimes - -template -void LinearVelocityConstraint::projectJacobianMatrix(const core::MechanicalParams* /*mparams*/, DataMatrixDeriv& /*cData*/) -{ - -} - -//display the path the constrained dofs will go through -template -void LinearVelocityConstraint::draw(const core::visual::VisualParams* vparams) -{ - if (!vparams->displayFlags().getShowBehaviorModels() || d_keyTimes.getValue().size() == 0 ) return; - const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); - - vparams->drawTool()->disableLighting(); - - std::vector vertices; - constexpr sofa::type::RGBAColor color(1, 0.5, 0.5, 1); - const VecDeriv& keyVelocities = d_keyVelocities.getValue(); - const SetIndexArray & indices = d_indices.getValue(); - for (unsigned int i=0 ; idrawTool()->drawLines(vertices, 1.0, color); - - -} - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/LinearVelocityProjectiveConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityProjectiveConstraint.cpp similarity index 74% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityProjectiveConstraint.cpp index 163a066f18c..5c8c0ef4a29 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityProjectiveConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_LINEARVELOCITYCONSTRAINT_CPP -#include +#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_LINEARVELOCITYPROJECTIVECONSTRAINT_CPP +#include #include #include #include @@ -32,19 +32,18 @@ using namespace sofa::defaulttype; using namespace sofa::helper; //declaration of the class, for the factory -int LinearVelocityConstraintClass = core::RegisterObject("apply velocity to given particles") - .add< LinearVelocityConstraint >() - .add< LinearVelocityConstraint >() - .add< LinearVelocityConstraint >() - .add< LinearVelocityConstraint >() - .add< LinearVelocityConstraint >() - +int LinearVelocityProjectiveConstraintClass = core::RegisterObject("apply velocity to given particles") + .add< LinearVelocityProjectiveConstraint >() + .add< LinearVelocityProjectiveConstraint >() + .add< LinearVelocityProjectiveConstraint >() + .add< LinearVelocityProjectiveConstraint >() + .add< LinearVelocityProjectiveConstraint >() ; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityProjectiveConstraint; } // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityProjectiveConstraint.h new file mode 100644 index 00000000000..74c67b83997 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityProjectiveConstraint.h @@ -0,0 +1,135 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + + +/** impose a motion to given DOFs (translation and rotation) + The motion between 2 key times is linearly interpolated +*/ +template +class LinearVelocityProjectiveConstraint : public core::behavior::ProjectiveConstraintSet +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(LinearVelocityProjectiveConstraint,TDataTypes),SOFA_TEMPLATE(core::behavior::ProjectiveConstraintSet,TDataTypes)); + + using Index = sofa::Index; + typedef TDataTypes DataTypes; + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::Real Real; + typedef typename MatrixDeriv::RowType MatrixDerivRowType; + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef Data DataMatrixDeriv; + typedef type::vector SetIndexArray; + typedef sofa::core::topology::TopologySubsetIndices SetIndex; + +public : + /// indices of the DOFs the constraint is applied to + SetIndex d_indices; + /// the key frames when the motion is defined by the user + Data > d_keyTimes; + /// the motions corresponding to the key frames + Data d_keyVelocities; + /// the coordinates on which to applay velocities + SetIndex d_coordinates; + + /// the key times surrounding the current simulation time (for interpolation) + Real prevT, nextT; + ///the velocities corresponding to the surrouding key times + Deriv prevV, nextV; + ///position at the initial step for constrained DOFs position + VecCoord x0; + ///position at the previous step for constrained DOFs position + VecCoord xP; + + /// Link to be set to the topology container in the component graph. + SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; + +protected: + LinearVelocityProjectiveConstraint(); + + virtual ~LinearVelocityProjectiveConstraint(); +public: + ///methods to add/remove some indices, keyTimes, keyVelocity + void clearIndices(); + void addIndex(Index index); + void removeIndex(Index index); + void clearKeyVelocities(); + /**add a new key movement + @param time : the simulation time you want to set a movement (in sec) + @param movement : the corresponding motion + for instance, addKeyMovement(1.0, Deriv(5,0,0) ) will set a translation of 5 in x direction a time 1.0s + **/ + void addKeyVelocity(Real time, Deriv movement); + + + /// -- Constraint interface + void init() override; + void reset() override; + void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; + void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; + void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; + void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; + + void draw(const core::visual::VisualParams* vparams) override; + +private: + + /// to keep the time corresponding to the key times + Real currentTime; + + /// to know if we found the key times + bool finished; + + /// find previous and next time keys + void findKeyTimes(); +}; + +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_LINEARVELOCITYPROJECTIVECONSTRAINT_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityProjectiveConstraint; + +#endif + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityProjectiveConstraint.inl new file mode 100644 index 00000000000..80ff4e51937 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityProjectiveConstraint.inl @@ -0,0 +1,348 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + + +namespace sofa::component::constraint::projective +{ + +template +LinearVelocityProjectiveConstraint::LinearVelocityProjectiveConstraint() + : core::behavior::ProjectiveConstraintSet(nullptr) + , d_indices( initData(&d_indices,"indices","Indices of the constrained points") ) + , d_keyTimes( initData(&d_keyTimes,"keyTimes","key times for the movements") ) + , d_keyVelocities( initData(&d_keyVelocities,"velocities","velocities corresponding to the key times") ) + , d_coordinates( initData(&d_coordinates, "coordinates", "coordinates on which to apply velocities") ) + , l_topology(initLink("topology", "link to the topology container")) + , finished(false) +{ + d_indices.beginEdit()->push_back(0); + d_indices.endEdit(); + + d_keyTimes.beginEdit()->push_back( 0.0 ); + d_keyTimes.endEdit(); + d_keyVelocities.beginEdit()->push_back( Deriv() ); + d_keyVelocities.endEdit(); +} + + +template +LinearVelocityProjectiveConstraint::~LinearVelocityProjectiveConstraint() +{ + +} + +template +void LinearVelocityProjectiveConstraint::clearIndices() +{ + d_indices.beginEdit()->clear(); + d_indices.endEdit(); +} + +template +void LinearVelocityProjectiveConstraint::addIndex(Index index) +{ + d_indices.beginEdit()->push_back(index); + d_indices.endEdit(); +} + +template +void LinearVelocityProjectiveConstraint::removeIndex(Index index) +{ + sofa::type::removeValue(*d_indices.beginEdit(),index); + d_indices.endEdit(); +} + +template +void LinearVelocityProjectiveConstraint::clearKeyVelocities() +{ + d_keyTimes.beginEdit()->clear(); + d_keyTimes.endEdit(); + d_keyVelocities.beginEdit()->clear(); + d_keyVelocities.endEdit(); +} + +template +void LinearVelocityProjectiveConstraint::addKeyVelocity(Real time, Deriv movement) +{ + d_keyTimes.beginEdit()->push_back( time ); + d_keyTimes.endEdit(); + d_keyVelocities.beginEdit()->push_back( movement ); + d_keyVelocities.endEdit(); +} + +// -- Constraint interface + + +template +void LinearVelocityProjectiveConstraint::init() +{ + this->core::behavior::ProjectiveConstraintSet::init(); + + if (l_topology.empty()) + { + msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; + l_topology.set(this->getContext()->getMeshTopologyLink()); + } + + if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) + { + msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; + + // Initialize topological changes support + d_indices.createTopologyHandler(_topology); + d_coordinates.createTopologyHandler(_topology); + } + else + { + msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; + } + + x0.resize(0); + xP.resize(0); + nextV = prevV = Deriv(); + + currentTime = -1.0; + finished = false; +} + +template +void LinearVelocityProjectiveConstraint::reset() +{ + nextT = prevT = 0.0; + nextV = prevV = Deriv(); + + currentTime = -1.0; + finished = false; +} + + +template +void LinearVelocityProjectiveConstraint::projectResponse(const core::MechanicalParams* /*mparams*/, DataVecDeriv& resData) +{ + helper::WriteAccessor res = resData; + VecDeriv& dx = res.wref(); + + Real cT = (Real) this->getContext()->getTime(); + if ((cT != currentTime) || !finished) + { + findKeyTimes(); + } + + if (finished && nextT != prevT) + { + const SetIndexArray & indices = d_indices.getValue(); + + //set the motion to the Dofs + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + dx[*it] = Deriv(); + } + } + +} + +template +void LinearVelocityProjectiveConstraint::projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& vData) +{ + helper::WriteAccessor dx = vData; + Real cT = (Real) this->getContext()->getTime(); + + if ((cT != currentTime) || !finished) + { + findKeyTimes(); + } + + if (finished && nextT != prevT) + { + //if we found 2 keyTimes, we have to interpolate a velocity (linear interpolation) + Deriv v = ((nextV - prevV)*((cT - prevT)/(nextT - prevT))) + prevV; + + const SetIndexArray & indices = d_indices.getValue(); + const SetIndexArray & coordinates = d_coordinates.getValue(); + + if (coordinates.size() == 0) + { + //set the motion to the Dofs + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + dx[*it] = v; + } + } + else + { + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + for(SetIndexArray::const_iterator itInd = coordinates.begin(); itInd != coordinates.end(); ++itInd) + { + dx[*it][*itInd] = v[*itInd]; + } + } + } + } +} + + +template +void LinearVelocityProjectiveConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) +{ + helper::WriteAccessor x = xData; + + //initialize initial Dofs positions, if it's not done + if (x0.size() == 0) + { + const SetIndexArray & indices = d_indices.getValue(); + x0.resize( x.size() ); + xP.resize( x.size() ); + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + x0[*it] = x[*it]; + xP[*it] = x0[*it]; + } + } + + Real cT = (Real) this->getContext()->getTime(); + + if ((cT != currentTime) || !finished) + { + findKeyTimes(); + } + + + Real dTsimu = (Real) this->getContext()->getDt(); + + + if(finished) + { + Real dt = (cT - prevT) / (nextT - prevT); + Deriv m = (nextV-prevV)*dt + prevV; + + const SetIndexArray & indices = d_indices.getValue(); + const SetIndexArray & coordinates = d_coordinates.getValue(); + + if (coordinates.size() == 0) + { + //set the motion to the Dofs + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + x[*it] = xP[*it] + m*dTsimu; + xP[*it] = x[*it]; + } + } + else + { + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + for(SetIndexArray::const_iterator itInd = coordinates.begin(); itInd != coordinates.end(); ++itInd) + { + x[*it][*itInd] = xP[*it][*itInd] + m[*itInd]*dTsimu; + xP[*it] = x[*it]; + } + } + } + } +} + +template +void LinearVelocityProjectiveConstraint::findKeyTimes() +{ + Real cT = (Real) this->getContext()->getTime(); + finished = false; + + if(d_keyTimes.getValue().size() != 0 && cT >= *d_keyTimes.getValue().begin() && cT <= *d_keyTimes.getValue().rbegin()) + { + nextT = *d_keyTimes.getValue().begin(); + prevT = nextT; + + typename type::vector::const_iterator it_t = d_keyTimes.getValue().begin(); + typename VecDeriv::const_iterator it_v = d_keyVelocities.getValue().begin(); + + //WARNING : we consider that the key-events are in chronological order + //here we search between which keyTimes we are, to know which are the motion to interpolate + while( it_t != d_keyTimes.getValue().end() && !finished) + { + if( *it_t <= cT) + { + prevT = *it_t; + prevV = *it_v; + } + else + { + nextT = *it_t; + nextV = *it_v; + finished = true; + } + ++it_t; + ++it_v; + } + } +}// LinearVelocityProjectiveConstraint::findKeyTimes + +template +void LinearVelocityProjectiveConstraint::projectJacobianMatrix(const core::MechanicalParams* /*mparams*/, DataMatrixDeriv& /*cData*/) +{ + +} + +//display the path the constrained dofs will go through +template +void LinearVelocityProjectiveConstraint::draw(const core::visual::VisualParams* vparams) +{ + if (!vparams->displayFlags().getShowBehaviorModels() || d_keyTimes.getValue().size() == 0 ) return; + const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); + + vparams->drawTool()->disableLighting(); + + std::vector vertices; + constexpr sofa::type::RGBAColor color(1, 0.5, 0.5, 1); + const VecDeriv& keyVelocities = d_keyVelocities.getValue(); + const SetIndexArray & indices = d_indices.getValue(); + for (unsigned int i=0 ; idrawTool()->drawLines(vertices, 1.0, color); + + +} + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorConstraint.h index ab2389a61da..9bbd88c7ce1 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorConstraint.h @@ -20,93 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include +#include +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/OscillatorProjectiveConstraint.h") namespace sofa::component::constraint::projective { - -/** - * Apply sinusoidal trajectories to particles. - * Defined as \f$ x = x_m A \sin ( \omega t + \phi )\f$ - * where \f$ x_m, A , \omega t , \phi \f$ are the mean value, the amplitude, the pulsation and the phase, respectively. - */ -template -class OscillatorConstraint : public core::behavior::ProjectiveConstraintSet -{ -public: - SOFA_CLASS(SOFA_TEMPLATE(OscillatorConstraint,TDataTypes),SOFA_TEMPLATE(core::behavior::ProjectiveConstraintSet,TDataTypes)); - - typedef TDataTypes DataTypes; - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::Real Real; - typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; - typedef typename MatrixDeriv::RowType MatrixDerivRowType; - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef Data DataMatrixDeriv; - -protected: - struct Oscillator - { - unsigned int index; - Coord mean; - Deriv amplitude; - Real pulsation; - Real phase; - - Oscillator(); - Oscillator(unsigned int i, const Coord& m, const Deriv& a, - const Real& w, const Real& p); - - inline friend std::istream& operator >>(std::istream& in, Oscillator& o) - { - in >> o.index >> o.mean >> o.amplitude >> o.pulsation >> o.phase; - return in; - } - - inline friend std::ostream& operator <<(std::ostream& out, const Oscillator& o) - { - out << o.index << " " << o.mean << " " << o.amplitude << " " - << o.pulsation << " " << o.phase << "\n"; - return out; - } - }; - - Data< type::vector< Oscillator > > constraints; ///< constrained particles - - -public: - explicit OscillatorConstraint(core::behavior::MechanicalState* mstate=nullptr); - ~OscillatorConstraint() override ; - - OscillatorConstraint* addConstraint(unsigned index, - const Coord& mean, const Deriv& amplitude, - Real pulsation, Real phase); - - void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; - void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; - void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; - void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; - -protected: - template - void projectResponseT(DataDeriv& dx, - const std::function& clear); -}; - - -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_OSCILLATORCONSTRAINT_CPP) -extern template class OscillatorConstraint; -extern template class OscillatorConstraint; -#endif - -} // namespace sofa::component::constraint::projective +template +using OscillatorConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "OscillatorConstraint has been renamed to OscillatorProjectiveConstraint") = OscillatorProjectiveConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorConstraint.inl index 831e3468cfb..72eca9675a6 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorConstraint.inl @@ -21,107 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -template -OscillatorConstraint::OscillatorConstraint(core::behavior::MechanicalState* mstate) - : core::behavior::ProjectiveConstraintSet(mstate) - , constraints(initData(&constraints,"oscillators","Define a sequence of oscillating particules: \n[index, Mean(x,y,z), amplitude(x,y,z), pulsation, phase]")) -{ -} - -template -OscillatorConstraint::~OscillatorConstraint() -{ -} - -template -OscillatorConstraint* OscillatorConstraint::addConstraint(unsigned index, const Coord& mean, const Deriv& amplitude, Real pulsation, Real phase) -{ - this->constraints.beginEdit()->push_back( Oscillator(index,mean,amplitude,pulsation,phase) ); - return this; -} - - -template template -void OscillatorConstraint::projectResponseT(DataDeriv& res, - const std::function& clear) -{ - const auto& oscillators = constraints.getValue(); - - for (unsigned i = 0; i < oscillators.size(); ++i) - { - const unsigned& index = oscillators[i].index; - clear(res, index); - } -} - -template -void OscillatorConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) -{ - SOFA_UNUSED(mparams); - helper::WriteAccessor res = resData; - projectResponseT(res.wref(),[](VecDeriv& res, const unsigned int index) { res[index].clear(); }); -} - -template -void OscillatorConstraint::projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& vData) -{ - helper::WriteAccessor v = vData; - const type::vector& oscillators = constraints.getValue(); - Real t = (Real) this->getContext()->getTime(); - for (unsigned i = 0; i < oscillators.size(); ++i) - { - const unsigned& index = oscillators[i].index; - const Deriv& a = oscillators[i].amplitude; - const Real& w = oscillators[i].pulsation; - const Real& p = oscillators[i].phase; - - v[index] = a * w * cos(w * t + p); - } -} - -template -void OscillatorConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) -{ - helper::WriteAccessor x = xData; - const type::vector &oscillators = constraints.getValue(); - Real t = (Real) this->getContext()->getTime(); - for (unsigned i = 0; i < oscillators.size(); ++i) - { - const unsigned& index = oscillators[i].index; - const Coord& m = oscillators[i].mean; - const Deriv& a = oscillators[i].amplitude; - const Real& w = oscillators[i].pulsation; - const Real& p = oscillators[i].phase; - - x[index] = m + a * sin(w * t + p); - } -} - -template -void OscillatorConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) -{ - SOFA_UNUSED(mparams); - helper::WriteAccessor c = cData; - projectResponseT(c.wref(), [](MatrixDeriv& res, const unsigned int index) { res.clearColBlock(index); }); -} - -template -OscillatorConstraint::Oscillator::Oscillator(): index(0) -{ -} - -template -OscillatorConstraint::Oscillator::Oscillator(unsigned int i, const Coord& m, const Deriv& a, - const Real& w, const Real& p) : - index(i), mean(m), amplitude(a), pulsation(w), phase(p) -{ -} - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/OscillatorProjectiveConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorProjectiveConstraint.cpp similarity index 79% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorProjectiveConstraint.cpp index 8edb65b5447..967fb6e369d 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorProjectiveConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_OSCILLATORCONSTRAINT_CPP -#include +#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_OSCILLATORPROJECTIVECONSTRAINT_CPP +#include #include #include #include @@ -31,11 +31,12 @@ namespace sofa::component::constraint::projective using namespace sofa::defaulttype; using namespace sofa::helper; -int OscillatorConstraintClass = core::RegisterObject("Apply a sinusoidal trajectory to given points") - .add< OscillatorConstraint >() - .add< OscillatorConstraint >(); +int OscillatorProjectiveConstraintClass = core::RegisterObject("Apply a sinusoidal trajectory to given points") + .add< OscillatorProjectiveConstraint >() + .add< OscillatorProjectiveConstraint >() + ; -template class OscillatorConstraint; -template class OscillatorConstraint; +template class OscillatorProjectiveConstraint; +template class OscillatorProjectiveConstraint; } // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorProjectiveConstraint.h new file mode 100644 index 00000000000..dd97f5d8b45 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorProjectiveConstraint.h @@ -0,0 +1,112 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include + + +namespace sofa::component::constraint::projective +{ + +/** + * Apply sinusoidal trajectories to particles. + * Defined as \f$ x = x_m A \sin ( \omega t + \phi )\f$ + * where \f$ x_m, A , \omega t , \phi \f$ are the mean value, the amplitude, the pulsation and the phase, respectively. + */ +template +class OscillatorProjectiveConstraint : public core::behavior::ProjectiveConstraintSet +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(OscillatorProjectiveConstraint,TDataTypes),SOFA_TEMPLATE(core::behavior::ProjectiveConstraintSet,TDataTypes)); + + typedef TDataTypes DataTypes; + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::Real Real; + typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; + typedef typename MatrixDeriv::RowType MatrixDerivRowType; + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef Data DataMatrixDeriv; + +protected: + struct Oscillator + { + unsigned int index; + Coord mean; + Deriv amplitude; + Real pulsation; + Real phase; + + Oscillator(); + Oscillator(unsigned int i, const Coord& m, const Deriv& a, + const Real& w, const Real& p); + + inline friend std::istream& operator >>(std::istream& in, Oscillator& o) + { + in >> o.index >> o.mean >> o.amplitude >> o.pulsation >> o.phase; + return in; + } + + inline friend std::ostream& operator <<(std::ostream& out, const Oscillator& o) + { + out << o.index << " " << o.mean << " " << o.amplitude << " " + << o.pulsation << " " << o.phase << "\n"; + return out; + } + }; + + Data< type::vector< Oscillator > > constraints; ///< constrained particles + + +public: + explicit OscillatorProjectiveConstraint(core::behavior::MechanicalState* mstate=nullptr); + ~OscillatorProjectiveConstraint() override ; + + OscillatorProjectiveConstraint* addConstraint(unsigned index, + const Coord& mean, const Deriv& amplitude, + Real pulsation, Real phase); + + void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; + void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; + void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; + void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; + +protected: + template + void projectResponseT(DataDeriv& dx, + const std::function& clear); +}; + + +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_OSCILLATORPROJECTIVECONSTRAINT_CPP) +extern template class OscillatorProjectiveConstraint; +extern template class OscillatorProjectiveConstraint; +#endif + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorProjectiveConstraint.inl new file mode 100644 index 00000000000..0f089b2eea1 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorProjectiveConstraint.inl @@ -0,0 +1,127 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +template +OscillatorProjectiveConstraint::OscillatorProjectiveConstraint(core::behavior::MechanicalState* mstate) + : core::behavior::ProjectiveConstraintSet(mstate) + , constraints(initData(&constraints,"oscillators","Define a sequence of oscillating particules: \n[index, Mean(x,y,z), amplitude(x,y,z), pulsation, phase]")) +{ +} + +template +OscillatorProjectiveConstraint::~OscillatorProjectiveConstraint() +{ +} + +template +OscillatorProjectiveConstraint* OscillatorProjectiveConstraint::addConstraint(unsigned index, const Coord& mean, const Deriv& amplitude, Real pulsation, Real phase) +{ + this->constraints.beginEdit()->push_back( Oscillator(index,mean,amplitude,pulsation,phase) ); + return this; +} + + +template template +void OscillatorProjectiveConstraint::projectResponseT(DataDeriv& res, + const std::function& clear) +{ + const auto& oscillators = constraints.getValue(); + + for (unsigned i = 0; i < oscillators.size(); ++i) + { + const unsigned& index = oscillators[i].index; + clear(res, index); + } +} + +template +void OscillatorProjectiveConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) +{ + SOFA_UNUSED(mparams); + helper::WriteAccessor res = resData; + projectResponseT(res.wref(),[](VecDeriv& res, const unsigned int index) { res[index].clear(); }); +} + +template +void OscillatorProjectiveConstraint::projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& vData) +{ + helper::WriteAccessor v = vData; + const type::vector& oscillators = constraints.getValue(); + Real t = (Real) this->getContext()->getTime(); + for (unsigned i = 0; i < oscillators.size(); ++i) + { + const unsigned& index = oscillators[i].index; + const Deriv& a = oscillators[i].amplitude; + const Real& w = oscillators[i].pulsation; + const Real& p = oscillators[i].phase; + + v[index] = a * w * cos(w * t + p); + } +} + +template +void OscillatorProjectiveConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) +{ + helper::WriteAccessor x = xData; + const type::vector &oscillators = constraints.getValue(); + Real t = (Real) this->getContext()->getTime(); + for (unsigned i = 0; i < oscillators.size(); ++i) + { + const unsigned& index = oscillators[i].index; + const Coord& m = oscillators[i].mean; + const Deriv& a = oscillators[i].amplitude; + const Real& w = oscillators[i].pulsation; + const Real& p = oscillators[i].phase; + + x[index] = m + a * sin(w * t + p); + } +} + +template +void OscillatorProjectiveConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) +{ + SOFA_UNUSED(mparams); + helper::WriteAccessor c = cData; + projectResponseT(c.wref(), [](MatrixDeriv& res, const unsigned int index) { res.clearColBlock(index); }); +} + +template +OscillatorProjectiveConstraint::Oscillator::Oscillator(): index(0) +{ +} + +template +OscillatorProjectiveConstraint::Oscillator::Oscillator(unsigned int i, const Coord& m, const Deriv& a, + const Real& w, const Real& p) : + index(i), mean(m), amplitude(a), pulsation(w), phase(p) +{ +} + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicConstraint.h index 4b6b1bc7c75..9dcfe542353 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicConstraint.h @@ -20,108 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include +#include +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/ParabolicProjectiveConstraint.h") namespace sofa::component::constraint::projective { - -/** Apply a parabolic trajectory to particles going through 3 points specified by the user. - The DOFs set in the "indices" list follow the computed parabol from "tBegin" to "tEnd". - */ -template -class ParabolicConstraint : public core::behavior::ProjectiveConstraintSet -{ -public: - SOFA_CLASS(SOFA_TEMPLATE(ParabolicConstraint,DataTypes),SOFA_TEMPLATE(core::behavior::ProjectiveConstraintSet,DataTypes)); - - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::Real Real; - typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; - typedef typename MatrixDeriv::RowType MatrixDerivRowType; - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef Data DataMatrixDeriv; - typedef type::vector SetIndexArray; - typedef sofa::core::topology::TopologySubsetIndices SetIndex; - typedef type::Vec<3, Real> Vec3R; - typedef type::Quat QuatR; - -protected: - ///indices of the DOFs constraints - SetIndex m_indices; - - /// the three points defining the parabol - Data m_P1; - Data m_P2; ///< second point of the parabol - Data m_P3; ///< third point of the parabol - - /// the time steps defining the velocity of the movement - Data m_tBegin; - Data m_tEnd; ///< End Time of the motion - - /// Link to be set to the topology container in the component graph. - SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; - - /// the 3 points projected in the parabol plan - Vec3R m_locP1; - Vec3R m_locP2; - Vec3R m_locP3; - - /// the quaternion doing the projection - QuatR m_projection; - - explicit ParabolicConstraint(core::behavior::MechanicalState* mstate = nullptr); - - ~ParabolicConstraint(); -public: - void addConstraint(unsigned index ); - - void setP1(const Vec3R &p) {m_P1.setValue(p);} - void setP2(const Vec3R &p) {m_P2.setValue(p);} - void setP3(const Vec3R &p) {m_P3.setValue(p);} - - void setBeginTime(const Real &t) {m_tBegin.setValue(t);} - void setEndTime(const Real &t) {m_tEnd.setValue(t);} - - Vec3R getP1() {return m_P1.getValue();} - Vec3R getP2() {return m_P2.getValue();} - Vec3R getP3() {return m_P3.getValue();} - - Real getBeginTime() {return m_tBegin.getValue();} - Real getEndTime() {return m_tEnd.getValue();} - - /// -- Constraint interface - void init() override; - void reinit() override; - - void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; - void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; - void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; - void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; - - void draw(const core::visual::VisualParams* vparams) override; - -protected: - template - void projectResponseT(DataDeriv& dx, - const std::function& clear); -}; - - -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PARABOLICCONSTRAINT_CPP) -extern template class ParabolicConstraint; -extern template class ParabolicConstraint; - -#endif - -} // namespace sofa::component::constraint::projective +template +using ParabolicConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "ParabolicConstraint has been renamed to ParabolicProjectiveConstraint") = ParabolicProjectiveConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicConstraint.inl index e8b6489cc9c..7c6fa4b59a2 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicConstraint.inl @@ -21,243 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -template -ParabolicConstraint::ParabolicConstraint(core::behavior::MechanicalState* mstate) - : core::behavior::ProjectiveConstraintSet(mstate) - , m_indices( initData(&m_indices,"indices","Indices of the constrained points") ) - , m_P1(initData(&m_P1,"P1","first point of the parabol") ) - , m_P2(initData(&m_P2,"P2","second point of the parabol") ) - , m_P3(initData(&m_P3,"P3","third point of the parabol") ) - , m_tBegin(initData(&m_tBegin,"BeginTime","Begin Time of the motion") ) - , m_tEnd(initData(&m_tEnd,"EndTime","End Time of the motion") ) - , l_topology(initLink("topology", "link to the topology container")) -{ -} - -template -ParabolicConstraint::~ParabolicConstraint() -{ -} - -template -void ParabolicConstraint::addConstraint(unsigned index) -{ - m_indices.beginEdit()->push_back(index); - m_indices.endEdit(); -} - - -template -void ParabolicConstraint::init() -{ - this->core::behavior::ProjectiveConstraintSet::init(); - - if (l_topology.empty()) - { - msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; - l_topology.set(this->getContext()->getMeshTopologyLink()); - } - - if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) - { - msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; - - // Initialize functions and parameters for topology data and handler - m_indices.createTopologyHandler(_topology); - } - else - { - msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; - } - - Vec3R P1 = m_P1.getValue(); - Vec3R P2 = m_P2.getValue(); - Vec3R P3 = m_P3.getValue(); - - //compute the projection to go in the parabol plan, - //such as P1 is the origin, P1P3 vector is the x axis, and P1P2 is in the xy plan - //by the way the computation of the parabol equation is much easier - if(P1 != P2 && P1 != P3 && P2 != P3) - { - - Vec3R P1P2 = P2 - P1; - Vec3R P1P3 = P3 - P1; - - Vec3R ax = P1P3; - Vec3R az = cross(P1P3, P1P2); - Vec3R ay = cross(az, ax); - ax.normalize(); - ay.normalize(); - az.normalize(); - - - type::Mat<3,3,Real> Mrot(ax, ay, az); - type::Mat<3,3,Real> Mrot2; - Mrot2.transpose(Mrot); - m_projection.fromMatrix(Mrot2); - m_projection.normalize(); - - m_locP1 = Vec3R(); - m_locP2 = m_projection.inverseRotate(P1P2); - m_locP3 = m_projection.inverseRotate(P1P3); - } -} - -template -void ParabolicConstraint::reinit() -{ - init(); -} - - -template -template -void ParabolicConstraint::projectResponseT(DataDeriv& dx, - const std::function& clear) -{ - Real t = (Real) this->getContext()->getTime(); - if ( t >= m_tBegin.getValue() && t <= m_tEnd.getValue()) - { - const SetIndexArray & indices = m_indices.getValue(); - for(SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - clear(dx, *it); - } -} - -template -void ParabolicConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) -{ - SOFA_UNUSED(mparams); - helper::WriteAccessor res = resData; - projectResponseT(res.wref(),[](VecDeriv& dx, const unsigned int index) { dx[index].clear(); }); -} - -template -void ParabolicConstraint::projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& vData) -{ - helper::WriteAccessor dx = vData; - Real t = (Real) this->getContext()->getTime(); - Real dt = (Real) this->getContext()->getDt(); - - if ( t >= m_tBegin.getValue() && t <= m_tEnd.getValue() ) - { - Real relativeTime = (t - m_tBegin.getValue() ) / (m_tEnd.getValue() - m_tBegin.getValue()); - const SetIndexArray & indices = m_indices.getValue(); - - for(SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - //compute velocity by doing v = dx/dt - Real pxP = m_locP3.x()*relativeTime; - Real pyP = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (pxP *pxP) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * pxP; - relativeTime = (t+dt - m_tBegin.getValue() ) / (m_tEnd.getValue() - m_tBegin.getValue()); - Real pxN = m_locP3.x()*relativeTime; - Real pyN = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (pxN *pxN) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * pxN; - - Vec3R locVel = Vec3R( (pxN-pxP)/dt, (pyN-pyP)/dt, 0.0); - - Vec3R worldVel = m_projection.rotate(locVel); - - dx[*it] = worldVel; - } - } -} - -template -void ParabolicConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) -{ - helper::WriteAccessor x = xData; - Real t = (Real) this->getContext()->getTime(); - - if ( t >= m_tBegin.getValue() && t <= m_tEnd.getValue() ) - { - Real relativeTime = (t - m_tBegin.getValue() ) / (m_tEnd.getValue() - m_tBegin.getValue()); - const SetIndexArray & indices = m_indices.getValue(); - - for(SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - //compute position from the equation of the parabol : Y = -y2/(x3*x2-x2�) * X� + (x3*y2)/(x3*x2-x2�) * X - //with P1:(0,0,0), P2:(x2,y2,z2), P3:(x3,y3,z3) , projected in parabol plan - Real px = m_locP3.x()*relativeTime; - Real py = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (px *px) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * px; - Vec3R locPos( px , py, 0.0); - - //projection to world coordinates - Vec3R worldPos = m_P1.getValue() + m_projection.rotate(locPos); - - x[*it] = worldPos; - } - } -} - -template -void ParabolicConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) -{ - SOFA_UNUSED(mparams); - helper::WriteAccessor c = cData; - - projectResponseT(c.wref(), [](MatrixDeriv& res, const unsigned int index) { res.clearColBlock(index); }); -} - - -template -void ParabolicConstraint::draw(const core::visual::VisualParams* vparams) -{ - const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); - - if (!vparams->displayFlags().getShowBehaviorModels()) return; - - Real dt = (Real) this->getContext()->getDt(); - Real t = m_tEnd.getValue() - m_tBegin.getValue(); - Real nbStep = t/dt; - - vparams->drawTool()->disableLighting(); - constexpr sofa::type::RGBAColor color(1, 0.5, 0.5, 1); - std::vector vertices; - - for (unsigned int i=0 ; i< nbStep ; i++) - { - //draw lines between each step of the parabolic trajectory - //so, the smaller is dt, the finer is the parabol - Real relativeTime = i/nbStep; - Real px = m_locP3.x()*relativeTime; - Real py = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (px *px) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * px; - Vec3R locPos( px , py, 0.0); - Vec3R worldPos = m_P1.getValue() + m_projection.rotate(locPos); - - vertices.push_back(sofa::type::Vec3(worldPos[0],worldPos[1],worldPos[2])); - - relativeTime = (i+1)/nbStep; - px = m_locP3.x()*relativeTime; - py = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (px *px) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * px; - locPos = Vec3R( px , py, 0.0); - worldPos = m_P1.getValue() + m_projection.rotate(locPos); - - - vertices.push_back(sofa::type::Vec3(worldPos[0],worldPos[1],worldPos[2])); - - } - vparams->drawTool()->drawLines(vertices, 1.0, color); - vertices.clear(); - - //draw points for the 3 control points - const Vec3R& mp1 = m_P1.getValue(); - const Vec3R& mp2 = m_P2.getValue(); - const Vec3R& mp3 = m_P3.getValue(); - vertices.push_back(sofa::type::Vec3(mp1[0],mp1[1],mp1[2])); - vertices.push_back(sofa::type::Vec3(mp2[0],mp2[1],mp2[2])); - vertices.push_back(sofa::type::Vec3(mp3[0],mp3[1],mp3[2])); - - vparams->drawTool()->drawPoints(vertices, 5.0, color); - - - -} - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/ParabolicProjectiveConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicProjectiveConstraint.cpp similarity index 77% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicProjectiveConstraint.cpp index 15239ed4f36..47503a2d77f 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicProjectiveConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PARABOLICCONSTRAINT_CPP -#include +#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PARABOLICPROJECTIVECONSTRAINT_CPP +#include #include #include #include @@ -28,11 +28,12 @@ namespace sofa::component::constraint::projective { -int ParabolicConstraintClass = core::RegisterObject("Apply a parabolic trajectory to given points") - .add< ParabolicConstraint >() - .add< ParabolicConstraint >(); +int ParabolicProjectiveConstraintClass = core::RegisterObject("Apply a parabolic trajectory to given points") + .add< ParabolicProjectiveConstraint >() + .add< ParabolicProjectiveConstraint >() + ; -template class ParabolicConstraint; -template class ParabolicConstraint; +template class ParabolicProjectiveConstraint; +template class ParabolicProjectiveConstraint; } // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicProjectiveConstraint.h new file mode 100644 index 00000000000..422c9cb020b --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicProjectiveConstraint.h @@ -0,0 +1,126 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include +#include + + +namespace sofa::component::constraint::projective +{ + +/** Apply a parabolic trajectory to particles going through 3 points specified by the user. + The DOFs set in the "indices" list follow the computed parabol from "tBegin" to "tEnd". + */ +template +class ParabolicProjectiveConstraint : public core::behavior::ProjectiveConstraintSet +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(ParabolicProjectiveConstraint,DataTypes),SOFA_TEMPLATE(core::behavior::ProjectiveConstraintSet,DataTypes)); + + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::Real Real; + typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; + typedef typename MatrixDeriv::RowType MatrixDerivRowType; + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef Data DataMatrixDeriv; + typedef type::vector SetIndexArray; + typedef sofa::core::topology::TopologySubsetIndices SetIndex; + typedef type::Vec<3, Real> Vec3R; + typedef type::Quat QuatR; + +protected: + ///indices of the DOFs constraints + SetIndex m_indices; + + /// the three points defining the parabol + Data m_P1; + Data m_P2; ///< second point of the parabol + Data m_P3; ///< third point of the parabol + + /// the time steps defining the velocity of the movement + Data m_tBegin; + Data m_tEnd; ///< End Time of the motion + + /// Link to be set to the topology container in the component graph. + SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; + + /// the 3 points projected in the parabol plan + Vec3R m_locP1; + Vec3R m_locP2; + Vec3R m_locP3; + + /// the quaternion doing the projection + QuatR m_projection; + + explicit ParabolicProjectiveConstraint(core::behavior::MechanicalState* mstate = nullptr); + + ~ParabolicProjectiveConstraint(); +public: + void addConstraint(unsigned index ); + + void setP1(const Vec3R &p) {m_P1.setValue(p);} + void setP2(const Vec3R &p) {m_P2.setValue(p);} + void setP3(const Vec3R &p) {m_P3.setValue(p);} + + void setBeginTime(const Real &t) {m_tBegin.setValue(t);} + void setEndTime(const Real &t) {m_tEnd.setValue(t);} + + Vec3R getP1() {return m_P1.getValue();} + Vec3R getP2() {return m_P2.getValue();} + Vec3R getP3() {return m_P3.getValue();} + + Real getBeginTime() {return m_tBegin.getValue();} + Real getEndTime() {return m_tEnd.getValue();} + + /// -- Constraint interface + void init() override; + void reinit() override; + + void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; + void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; + void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; + void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; + + void draw(const core::visual::VisualParams* vparams) override; + +protected: + template + void projectResponseT(DataDeriv& dx, + const std::function& clear); +}; + + +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PARABOLICPROJECTIVECONSTRAINT_CPP) +extern template class ParabolicProjectiveConstraint; +extern template class ParabolicProjectiveConstraint; +#endif + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicProjectiveConstraint.inl new file mode 100644 index 00000000000..09a34cc7b9b --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicProjectiveConstraint.inl @@ -0,0 +1,263 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +template +ParabolicProjectiveConstraint::ParabolicProjectiveConstraint(core::behavior::MechanicalState* mstate) + : core::behavior::ProjectiveConstraintSet(mstate) + , m_indices( initData(&m_indices,"indices","Indices of the constrained points") ) + , m_P1(initData(&m_P1,"P1","first point of the parabol") ) + , m_P2(initData(&m_P2,"P2","second point of the parabol") ) + , m_P3(initData(&m_P3,"P3","third point of the parabol") ) + , m_tBegin(initData(&m_tBegin,"BeginTime","Begin Time of the motion") ) + , m_tEnd(initData(&m_tEnd,"EndTime","End Time of the motion") ) + , l_topology(initLink("topology", "link to the topology container")) +{ +} + +template +ParabolicProjectiveConstraint::~ParabolicProjectiveConstraint() +{ +} + +template +void ParabolicProjectiveConstraint::addConstraint(unsigned index) +{ + m_indices.beginEdit()->push_back(index); + m_indices.endEdit(); +} + + +template +void ParabolicProjectiveConstraint::init() +{ + this->core::behavior::ProjectiveConstraintSet::init(); + + if (l_topology.empty()) + { + msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; + l_topology.set(this->getContext()->getMeshTopologyLink()); + } + + if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) + { + msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; + + // Initialize functions and parameters for topology data and handler + m_indices.createTopologyHandler(_topology); + } + else + { + msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; + } + + Vec3R P1 = m_P1.getValue(); + Vec3R P2 = m_P2.getValue(); + Vec3R P3 = m_P3.getValue(); + + //compute the projection to go in the parabol plan, + //such as P1 is the origin, P1P3 vector is the x axis, and P1P2 is in the xy plan + //by the way the computation of the parabol equation is much easier + if(P1 != P2 && P1 != P3 && P2 != P3) + { + + Vec3R P1P2 = P2 - P1; + Vec3R P1P3 = P3 - P1; + + Vec3R ax = P1P3; + Vec3R az = cross(P1P3, P1P2); + Vec3R ay = cross(az, ax); + ax.normalize(); + ay.normalize(); + az.normalize(); + + + type::Mat<3,3,Real> Mrot(ax, ay, az); + type::Mat<3,3,Real> Mrot2; + Mrot2.transpose(Mrot); + m_projection.fromMatrix(Mrot2); + m_projection.normalize(); + + m_locP1 = Vec3R(); + m_locP2 = m_projection.inverseRotate(P1P2); + m_locP3 = m_projection.inverseRotate(P1P3); + } +} + +template +void ParabolicProjectiveConstraint::reinit() +{ + init(); +} + + +template +template +void ParabolicProjectiveConstraint::projectResponseT(DataDeriv& dx, + const std::function& clear) +{ + Real t = (Real) this->getContext()->getTime(); + if ( t >= m_tBegin.getValue() && t <= m_tEnd.getValue()) + { + const SetIndexArray & indices = m_indices.getValue(); + for(SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + clear(dx, *it); + } +} + +template +void ParabolicProjectiveConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) +{ + SOFA_UNUSED(mparams); + helper::WriteAccessor res = resData; + projectResponseT(res.wref(),[](VecDeriv& dx, const unsigned int index) { dx[index].clear(); }); +} + +template +void ParabolicProjectiveConstraint::projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& vData) +{ + helper::WriteAccessor dx = vData; + Real t = (Real) this->getContext()->getTime(); + Real dt = (Real) this->getContext()->getDt(); + + if ( t >= m_tBegin.getValue() && t <= m_tEnd.getValue() ) + { + Real relativeTime = (t - m_tBegin.getValue() ) / (m_tEnd.getValue() - m_tBegin.getValue()); + const SetIndexArray & indices = m_indices.getValue(); + + for(SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + //compute velocity by doing v = dx/dt + Real pxP = m_locP3.x()*relativeTime; + Real pyP = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (pxP *pxP) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * pxP; + relativeTime = (t+dt - m_tBegin.getValue() ) / (m_tEnd.getValue() - m_tBegin.getValue()); + Real pxN = m_locP3.x()*relativeTime; + Real pyN = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (pxN *pxN) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * pxN; + + Vec3R locVel = Vec3R( (pxN-pxP)/dt, (pyN-pyP)/dt, 0.0); + + Vec3R worldVel = m_projection.rotate(locVel); + + dx[*it] = worldVel; + } + } +} + +template +void ParabolicProjectiveConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) +{ + helper::WriteAccessor x = xData; + Real t = (Real) this->getContext()->getTime(); + + if ( t >= m_tBegin.getValue() && t <= m_tEnd.getValue() ) + { + Real relativeTime = (t - m_tBegin.getValue() ) / (m_tEnd.getValue() - m_tBegin.getValue()); + const SetIndexArray & indices = m_indices.getValue(); + + for(SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + //compute position from the equation of the parabol : Y = -y2/(x3*x2-x2�) * X� + (x3*y2)/(x3*x2-x2�) * X + //with P1:(0,0,0), P2:(x2,y2,z2), P3:(x3,y3,z3) , projected in parabol plan + Real px = m_locP3.x()*relativeTime; + Real py = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (px *px) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * px; + Vec3R locPos( px , py, 0.0); + + //projection to world coordinates + Vec3R worldPos = m_P1.getValue() + m_projection.rotate(locPos); + + x[*it] = worldPos; + } + } +} + +template +void ParabolicProjectiveConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) +{ + SOFA_UNUSED(mparams); + helper::WriteAccessor c = cData; + + projectResponseT(c.wref(), [](MatrixDeriv& res, const unsigned int index) { res.clearColBlock(index); }); +} + + +template +void ParabolicProjectiveConstraint::draw(const core::visual::VisualParams* vparams) +{ + const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); + + if (!vparams->displayFlags().getShowBehaviorModels()) return; + + Real dt = (Real) this->getContext()->getDt(); + Real t = m_tEnd.getValue() - m_tBegin.getValue(); + Real nbStep = t/dt; + + vparams->drawTool()->disableLighting(); + constexpr sofa::type::RGBAColor color(1, 0.5, 0.5, 1); + std::vector vertices; + + for (unsigned int i=0 ; i< nbStep ; i++) + { + //draw lines between each step of the parabolic trajectory + //so, the smaller is dt, the finer is the parabol + Real relativeTime = i/nbStep; + Real px = m_locP3.x()*relativeTime; + Real py = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (px *px) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * px; + Vec3R locPos( px , py, 0.0); + Vec3R worldPos = m_P1.getValue() + m_projection.rotate(locPos); + + vertices.push_back(sofa::type::Vec3(worldPos[0],worldPos[1],worldPos[2])); + + relativeTime = (i+1)/nbStep; + px = m_locP3.x()*relativeTime; + py = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (px *px) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * px; + locPos = Vec3R( px , py, 0.0); + worldPos = m_P1.getValue() + m_projection.rotate(locPos); + + + vertices.push_back(sofa::type::Vec3(worldPos[0],worldPos[1],worldPos[2])); + + } + vparams->drawTool()->drawLines(vertices, 1.0, color); + vertices.clear(); + + //draw points for the 3 control points + const Vec3R& mp1 = m_P1.getValue(); + const Vec3R& mp2 = m_P2.getValue(); + const Vec3R& mp3 = m_P3.getValue(); + vertices.push_back(sofa::type::Vec3(mp1[0],mp1[1],mp1[2])); + vertices.push_back(sofa::type::Vec3(mp2[0],mp2[1],mp2[2])); + vertices.push_back(sofa::type::Vec3(mp3[0],mp3[1],mp3[2])); + + vparams->drawTool()->drawPoints(vertices, 5.0, color); + + + +} + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedConstraint.h index b54bdc2b611..b5d76e4379f 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedConstraint.h @@ -20,87 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/PartialFixedProjectiveConstraint.h") -/** - * Attach given particles to their initial positions, in some directions only. - * The fixed and free directioons are the same for all the particles, defined in the fixedDirections attribute. - **/ -template -class PartialFixedConstraint : public FixedConstraint +namespace sofa::component::constraint::projective { -public: - SOFA_CLASS(SOFA_TEMPLATE(PartialFixedConstraint,DataTypes),SOFA_TEMPLATE(FixedConstraint, DataTypes)); - - typedef FixedConstraint Inherited; - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::Real Real; - typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; - typedef typename MatrixDeriv::RowType MatrixDerivRowType; - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef Data DataMatrixDeriv; - typedef type::vector SetIndexArray; - typedef sofa::core::topology::TopologySubsetIndices SetIndex; - -public: - enum { NumDimensions = Deriv::total_size }; - typedef sofa::type::fixed_array VecBool; - Data d_fixedDirections; ///< Defines the directions in which the particles are fixed: true (or 1) for fixed, false (or 0) for free. - Data d_projectVelocity; ///< activate project velocity to set velocity to zero - -protected: - PartialFixedConstraint(); - virtual ~PartialFixedConstraint(); - -public: - - // -- Constraint interface - void reinit() override; - - void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; - void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; - void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; - - void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - - void projectMatrix( sofa::linearalgebra::BaseMatrix* /*M*/, unsigned /*offset*/ ) override; - - void applyConstraint(sofa::core::behavior::ZeroDirichletCondition* matrix) override; - -protected: - template - void projectResponseT(DataDeriv& dx, - const std::function& clear); -}; - -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PARTIALFIXEDCONSTRAINT_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedConstraint; - -#endif - -} // namespace sofa::component::constraint::projective +template +using PartialFixedConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "PartialFixedConstraint has been renamed to PartialFixedProjectiveConstraint") = PartialFixedProjectiveConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedConstraint.inl index 1e0a8bb8b9f..1fd9f96ae7b 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedConstraint.inl @@ -21,323 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include +#include - -namespace sofa::component::constraint::projective -{ - -template -PartialFixedConstraint::PartialFixedConstraint() - : d_fixedDirections( initData(&d_fixedDirections,"fixedDirections","for each direction, 1 if fixed, 0 if free") ) - , d_projectVelocity(initData(&d_projectVelocity, false, "projectVelocity", "project velocity to ensure no drift of the fixed point")) -{ - VecBool blockedDirection; - for( unsigned i=0; i -PartialFixedConstraint::~PartialFixedConstraint() -{ - //Parent class FixedConstraint already destruct : pointHandler and data -} - -template -void PartialFixedConstraint::reinit() -{ - this->Inherited::reinit(); -} - - -template -template -void PartialFixedConstraint::projectResponseT(DataDeriv& res, - const std::function& clear) -{ - const VecBool& blockedDirection = d_fixedDirections.getValue(); - - if (this->d_fixAll.getValue() == true) - { - // fix everything - for( std::size_t i=0; id_indices.getValue(); - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - clear(res, *it, blockedDirection); - } - } -} - -template -void PartialFixedConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) -{ - SOFA_UNUSED(mparams); - helper::WriteAccessor res = resData; - projectResponseT(res.wref(), - [](VecDeriv& dx, const unsigned int index, const VecBool& b) - { - for (std::size_t j = 0; j < b.size(); j++) if (b[j]) dx[index][j] = 0.0; - } - ); -} - -// projectVelocity applies the same changes on velocity vector as projectResponse on position vector : -// Each fixed point received a null velocity vector. -// When a new fixed point is added while its velocity vector is already null, projectVelocity is not usefull. -// But when a new fixed point is added while its velocity vector is not null, it's necessary to fix it to null or -// to set the projectVelocity option to True. If not, the fixed point is going to drift. -template -void PartialFixedConstraint::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) -{ - SOFA_UNUSED(mparams); - - if(!d_projectVelocity.getValue()) return; - - const VecBool& blockedDirection = d_fixedDirections.getValue(); - helper::WriteAccessor res = vData; - - if ( this->d_fixAll.getValue() ) - { - // fix everyting - for (Size i = 0; i < res.size(); i++) - { - for (unsigned int c = 0; c < NumDimensions; ++c) - { - if (blockedDirection[c]) res[i][c] = 0; - } - } - } - else - { - const SetIndexArray & indices = this->d_indices.getValue(); - for(Index ind : indices) - { - for (unsigned int c = 0; c < NumDimensions; ++c) - { - if (blockedDirection[c]) - res[ind][c] = 0; - } - } - } -} - - -template -void PartialFixedConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) -{ - SOFA_UNUSED(mparams); - helper::WriteAccessor c = cData; - - projectResponseT(c.wref(), - [](MatrixDeriv& res, const unsigned int index, const VecBool& btype) - { - auto itRow = res.begin(); - auto itRowEnd = res.end(); - - while (itRow != itRowEnd) - { - for (auto colIt = itRow.begin(); colIt != itRow.end(); colIt++) - { - if (index == (unsigned int)colIt.index()) - { - Deriv b = colIt.val(); - for (unsigned int j = 0; j < btype.size(); j++) - if (btype[j]) b[j] = 0.0; - res.writeLine(itRow.index()).setCol(colIt.index(), b); - } - } - ++itRow; - } - }); -} - -template -void PartialFixedConstraint::applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) -{ - SOFA_UNUSED(mparams); - const int o = matrix->getGlobalOffset(this->mstate.get()); - if (o >= 0) - { - const unsigned int offset = (unsigned int)o; - const unsigned int N = Deriv::size(); - - const VecBool& blockedDirection = d_fixedDirections.getValue(); - - if( this->d_fixAll.getValue() ) - { - for(sofa::Index i=0; i<(sofa::Size) vector->size(); i++ ) - { - for (unsigned int c = 0; c < N; ++c) - { - if (blockedDirection[c]) - { - vector->clear(offset + N * i + c); - } - } - } - } - else - { - const SetIndexArray & indices = this->d_indices.getValue(); - for (const unsigned int index : indices) - { - for (unsigned int c = 0; c < N; ++c) - { - if (blockedDirection[c]) - { - vector->clear(offset + N * index + c); - } - } - } - } - } -} - -template -void PartialFixedConstraint::applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) -{ - SOFA_UNUSED(mparams); - if(const core::behavior::MultiMatrixAccessor::MatrixRef r = matrix->getMatrix(this->mstate.get())) - { - const unsigned int N = Deriv::size(); - const VecBool& blockedDirection = d_fixedDirections.getValue(); - const SetIndexArray & indices = this->d_indices.getValue(); - - if( this->d_fixAll.getValue() ) - { - const unsigned size = this->mstate->getSize(); - for(unsigned int i=0; iclearRowCol(r.offset + N * i + c); - } - } - // Set Fixed Vertex - for (unsigned int c=0; cset(r.offset + N * i + c, r.offset + N * i + c, 1.0); - } - } - } - } - else - { - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - // Reset Fixed Row and Col - for (unsigned int c=0; cclearRowCol(r.offset + N * (*it) + c); - } - } - // Set Fixed Vertex - for (unsigned int c=0; cset(r.offset + N * (*it) + c, r.offset + N * (*it) + c, 1.0); - } - } - } - } - } -} - -template -void PartialFixedConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) -{ - static const unsigned blockSize = DataTypes::deriv_total_size; - - const VecBool& blockedDirection = d_fixedDirections.getValue(); - - if( this->d_fixAll.getValue() ) - { - const unsigned size = this->mstate->getSize(); - for( unsigned i=0; iclearRowCol( offset + i * blockSize + c ); - } - } - } - } - else - { - const SetIndexArray & indices = this->d_indices.getValue(); - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - for (unsigned int c = 0; c < blockSize; ++c) - { - if (blockedDirection[c]) - { - M->clearRowCol( offset + (*it) * blockSize + c); - } - } - } - } -} - -template -void PartialFixedConstraint::applyConstraint( - sofa::core::behavior::ZeroDirichletCondition* matrix) -{ - static constexpr unsigned int N = Deriv::size(); - const VecBool& blockedDirection = d_fixedDirections.getValue(); - - if( this->d_fixAll.getValue() ) - { - const sofa::Size size = this->mstate->getSize(); - - for(sofa::Index i = 0; i < size; ++i) - { - for (unsigned int c=0; cdiscardRowCol(N * i + c, N * i + c); - } - } - } - } - else - { - const SetIndexArray & indices = this->d_indices.getValue(); - - for (const auto index : indices) - { - for (unsigned int c = 0; c < N; ++c) - { - if (blockedDirection[c]) - { - matrix->discardRowCol(N * index + c, N * index + c); - } - } - } - } -} -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/PartialFixedProjectiveConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedProjectiveConstraint.cpp similarity index 72% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedProjectiveConstraint.cpp index d28aae72e24..a28195e0254 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedProjectiveConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PARTIALFIXEDCONSTRAINT_CPP -#include +#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PARTIALFIXEDPROJECTIVECONSTRAINT_CPP +#include #include #include @@ -31,21 +31,20 @@ using namespace sofa::defaulttype; using namespace sofa::helper; -int PartialFixedConstraintClass = core::RegisterObject("Attach given particles to their initial positions") - .add< PartialFixedConstraint >() - .add< PartialFixedConstraint >() - .add< PartialFixedConstraint >() - .add< PartialFixedConstraint >() - .add< PartialFixedConstraint >() - .add< PartialFixedConstraint >() - +int PartialFixedProjectiveConstraintClass = core::RegisterObject("Attach given particles to their initial positions") + .add< PartialFixedProjectiveConstraint >() + .add< PartialFixedProjectiveConstraint >() + .add< PartialFixedProjectiveConstraint >() + .add< PartialFixedProjectiveConstraint >() + .add< PartialFixedProjectiveConstraint >() + .add< PartialFixedProjectiveConstraint >() ; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedProjectiveConstraint; } // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedProjectiveConstraint.h new file mode 100644 index 00000000000..28e99260259 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedProjectiveConstraint.h @@ -0,0 +1,105 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +/** + * Attach given particles to their initial positions, in some directions only. + * The fixed and free directioons are the same for all the particles, defined in the fixedDirections attribute. + **/ +template +class PartialFixedProjectiveConstraint : public FixedProjectiveConstraint +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(PartialFixedProjectiveConstraint,DataTypes),SOFA_TEMPLATE(FixedProjectiveConstraint, DataTypes)); + + typedef FixedProjectiveConstraint Inherited; + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::Real Real; + typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; + typedef typename MatrixDeriv::RowType MatrixDerivRowType; + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef Data DataMatrixDeriv; + typedef type::vector SetIndexArray; + typedef sofa::core::topology::TopologySubsetIndices SetIndex; + +public: + enum { NumDimensions = Deriv::total_size }; + typedef sofa::type::fixed_array VecBool; + Data d_fixedDirections; ///< Defines the directions in which the particles are fixed: true (or 1) for fixed, false (or 0) for free. + Data d_projectVelocity; ///< activate project velocity to set velocity to zero + +protected: + PartialFixedProjectiveConstraint(); + virtual ~PartialFixedProjectiveConstraint(); + +public: + + // -- Constraint interface + void reinit() override; + + void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; + void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; + void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; + + void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + + void projectMatrix( sofa::linearalgebra::BaseMatrix* /*M*/, unsigned /*offset*/ ) override; + + void applyConstraint(sofa::core::behavior::ZeroDirichletCondition* matrix) override; + +protected: + template + void projectResponseT(DataDeriv& dx, + const std::function& clear); +}; + +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PARTIALFIXEDPROJECTIVECONSTRAINT_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedProjectiveConstraint; +#endif + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedProjectiveConstraint.inl new file mode 100644 index 00000000000..3c9b090d771 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedProjectiveConstraint.inl @@ -0,0 +1,343 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include +#include + + +namespace sofa::component::constraint::projective +{ + +template +PartialFixedProjectiveConstraint::PartialFixedProjectiveConstraint() + : d_fixedDirections( initData(&d_fixedDirections,"fixedDirections","for each direction, 1 if fixed, 0 if free") ) + , d_projectVelocity(initData(&d_projectVelocity, false, "projectVelocity", "project velocity to ensure no drift of the fixed point")) +{ + VecBool blockedDirection; + for( unsigned i=0; i +PartialFixedProjectiveConstraint::~PartialFixedProjectiveConstraint() +{ + //Parent class FixedConstraint already destruct : pointHandler and data +} + +template +void PartialFixedProjectiveConstraint::reinit() +{ + this->Inherited::reinit(); +} + + +template +template +void PartialFixedProjectiveConstraint::projectResponseT(DataDeriv& res, + const std::function& clear) +{ + const VecBool& blockedDirection = d_fixedDirections.getValue(); + + if (this->d_fixAll.getValue() == true) + { + // fix everything + for( std::size_t i=0; id_indices.getValue(); + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + clear(res, *it, blockedDirection); + } + } +} + +template +void PartialFixedProjectiveConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) +{ + SOFA_UNUSED(mparams); + helper::WriteAccessor res = resData; + projectResponseT(res.wref(), + [](VecDeriv& dx, const unsigned int index, const VecBool& b) + { + for (std::size_t j = 0; j < b.size(); j++) if (b[j]) dx[index][j] = 0.0; + } + ); +} + +// projectVelocity applies the same changes on velocity vector as projectResponse on position vector : +// Each fixed point received a null velocity vector. +// When a new fixed point is added while its velocity vector is already null, projectVelocity is not usefull. +// But when a new fixed point is added while its velocity vector is not null, it's necessary to fix it to null or +// to set the projectVelocity option to True. If not, the fixed point is going to drift. +template +void PartialFixedProjectiveConstraint::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) +{ + SOFA_UNUSED(mparams); + + if(!d_projectVelocity.getValue()) return; + + const VecBool& blockedDirection = d_fixedDirections.getValue(); + helper::WriteAccessor res = vData; + + if ( this->d_fixAll.getValue() ) + { + // fix everyting + for (Size i = 0; i < res.size(); i++) + { + for (unsigned int c = 0; c < NumDimensions; ++c) + { + if (blockedDirection[c]) res[i][c] = 0; + } + } + } + else + { + const SetIndexArray & indices = this->d_indices.getValue(); + for(Index ind : indices) + { + for (unsigned int c = 0; c < NumDimensions; ++c) + { + if (blockedDirection[c]) + res[ind][c] = 0; + } + } + } +} + + +template +void PartialFixedProjectiveConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) +{ + SOFA_UNUSED(mparams); + helper::WriteAccessor c = cData; + + projectResponseT(c.wref(), + [](MatrixDeriv& res, const unsigned int index, const VecBool& btype) + { + auto itRow = res.begin(); + auto itRowEnd = res.end(); + + while (itRow != itRowEnd) + { + for (auto colIt = itRow.begin(); colIt != itRow.end(); colIt++) + { + if (index == (unsigned int)colIt.index()) + { + Deriv b = colIt.val(); + for (unsigned int j = 0; j < btype.size(); j++) + if (btype[j]) b[j] = 0.0; + res.writeLine(itRow.index()).setCol(colIt.index(), b); + } + } + ++itRow; + } + }); +} + +template +void PartialFixedProjectiveConstraint::applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) +{ + SOFA_UNUSED(mparams); + const int o = matrix->getGlobalOffset(this->mstate.get()); + if (o >= 0) + { + const unsigned int offset = (unsigned int)o; + const unsigned int N = Deriv::size(); + + const VecBool& blockedDirection = d_fixedDirections.getValue(); + + if( this->d_fixAll.getValue() ) + { + for(sofa::Index i=0; i<(sofa::Size) vector->size(); i++ ) + { + for (unsigned int c = 0; c < N; ++c) + { + if (blockedDirection[c]) + { + vector->clear(offset + N * i + c); + } + } + } + } + else + { + const SetIndexArray & indices = this->d_indices.getValue(); + for (const unsigned int index : indices) + { + for (unsigned int c = 0; c < N; ++c) + { + if (blockedDirection[c]) + { + vector->clear(offset + N * index + c); + } + } + } + } + } +} + +template +void PartialFixedProjectiveConstraint::applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) +{ + SOFA_UNUSED(mparams); + if(const core::behavior::MultiMatrixAccessor::MatrixRef r = matrix->getMatrix(this->mstate.get())) + { + const unsigned int N = Deriv::size(); + const VecBool& blockedDirection = d_fixedDirections.getValue(); + const SetIndexArray & indices = this->d_indices.getValue(); + + if( this->d_fixAll.getValue() ) + { + const unsigned size = this->mstate->getSize(); + for(unsigned int i=0; iclearRowCol(r.offset + N * i + c); + } + } + // Set Fixed Vertex + for (unsigned int c=0; cset(r.offset + N * i + c, r.offset + N * i + c, 1.0); + } + } + } + } + else + { + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + // Reset Fixed Row and Col + for (unsigned int c=0; cclearRowCol(r.offset + N * (*it) + c); + } + } + // Set Fixed Vertex + for (unsigned int c=0; cset(r.offset + N * (*it) + c, r.offset + N * (*it) + c, 1.0); + } + } + } + } + } +} + +template +void PartialFixedProjectiveConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) +{ + static const unsigned blockSize = DataTypes::deriv_total_size; + + const VecBool& blockedDirection = d_fixedDirections.getValue(); + + if( this->d_fixAll.getValue() ) + { + const unsigned size = this->mstate->getSize(); + for( unsigned i=0; iclearRowCol( offset + i * blockSize + c ); + } + } + } + } + else + { + const SetIndexArray & indices = this->d_indices.getValue(); + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + for (unsigned int c = 0; c < blockSize; ++c) + { + if (blockedDirection[c]) + { + M->clearRowCol( offset + (*it) * blockSize + c); + } + } + } + } +} + +template +void PartialFixedProjectiveConstraint::applyConstraint( + sofa::core::behavior::ZeroDirichletCondition* matrix) +{ + static constexpr unsigned int N = Deriv::size(); + const VecBool& blockedDirection = d_fixedDirections.getValue(); + + if( this->d_fixAll.getValue() ) + { + const sofa::Size size = this->mstate->getSize(); + + for(sofa::Index i = 0; i < size; ++i) + { + for (unsigned int c=0; cdiscardRowCol(N * i + c, N * i + c); + } + } + } + } + else + { + const SetIndexArray & indices = this->d_indices.getValue(); + + for (const auto index : indices) + { + for (unsigned int c = 0; c < N; ++c) + { + if (blockedDirection[c]) + { + matrix->discardRowCol(N * index + c, N * index + c); + } + } + } + } +} +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementConstraint.h index 072548a5030..f3eb83d8868 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementConstraint.h @@ -20,157 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -template -class PartialLinearMovementConstraintInternalData -{ -}; +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.h") -/** impose a motion to given DOFs (translation and rotation) in some directions only. - The moved and free directioons are the same for all the particles, defined in the movedDirections attribute. - The motion between 2 key times is linearly interpolated -*/ -template -class PartialLinearMovementConstraint : public core::behavior::ProjectiveConstraintSet +namespace sofa::component::constraint::projective { -public: - SOFA_CLASS(SOFA_TEMPLATE(PartialLinearMovementConstraint,TDataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, TDataTypes)); - - using Index = sofa::Index; - typedef TDataTypes DataTypes; - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::Real Real; - typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; - typedef typename MatrixDeriv::RowType MatrixDerivRowType; - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef Data DataMatrixDeriv; - typedef type::vector SetIndexArray; - typedef sofa::core::topology::TopologySubsetIndices SetIndex; - -protected: - PartialLinearMovementConstraintInternalData *data; - friend class PartialLinearMovementConstraintInternalData; - -public : - /// indices of the DOFs the constraint is applied to - SetIndex m_indices; - /// the key frames when the motion is defined by the user - core::objectmodel::Data > m_keyTimes; - /// the motions corresponding to the key frames - core::objectmodel::Data m_keyMovements; - - /// attributes to precise display - /// if showMovement is true we display the expected movement - /// otherwise we show which are the fixed dofs - core::objectmodel::Data< bool > showMovement; - - /// the key times surrounding the current simulation time (for interpolation) - Real prevT, nextT; - ///the motions corresponding to the surrouding key times - Deriv prevM, nextM; - ///initial constrained DOFs position - VecCoord x0; - - core::objectmodel::Data linearMovementBetweenNodesInIndices; ///< Take into account the linear movement between the constrained points - core::objectmodel::Data mainIndice; ///< The main indice node in the list of constrained nodes, it defines how to apply the linear movement between this constrained nodes - core::objectmodel::Data minDepIndice; ///< The indice node in the list of constrained nodes, which is imposed the minimum displacment - core::objectmodel::Data maxDepIndice; ///< The indice node in the list of constrained nodes, which is imposed the maximum displacment - core::objectmodel::Data > m_imposedDisplacmentOnMacroNodes; ///< imposed displacement at u1 u2 u3 u4 for 2d case - ///< and u1 u2 u3 u4 u5 u6 u7 u8 for 3d case - Data X0; ///< Size of specimen in X-direction - Data Y0; ///< Size of specimen in Y-direction - Data Z0; ///< Size of specimen in Z-direction - - enum { NumDimensions = Deriv::total_size }; - typedef sofa::type::fixed_array VecBool; - core::objectmodel::Data movedDirections; ///< Defines the directions in which the particles are moved: true (or 1) for fixed, false (or 0) for free. - - /// Link to be set to the topology container in the component graph. - SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; - -protected: - PartialLinearMovementConstraint(); - ~PartialLinearMovementConstraint() override; - -public: - ///methods to add/remove some indices, keyTimes, keyMovement - void clearIndices(); - void addIndex(Index index); - void removeIndex(Index index); - void clearKeyMovements(); - - ///@brief Add a new key movement - ///@param time : the simulation time you want to set a movement (in sec) - ///@param movement : the corresponding motion - ///for instance, addKeyMovement(1.0, Deriv(5,0,0) ) will set a translation of 5 in x direction a time 1.0s - void addKeyMovement(Real time, Deriv movement); - - - /// -- Constraint interface - void init() override; - void reset() override; - - void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; - void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; - void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; - void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; - - void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - - void draw(const core::visual::VisualParams*) override; - -protected: - template - void projectResponseT(DataDeriv& dx, - const std::function& clear); - - template - void interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x); - template - void interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x); - -private: - - /// to keep the time corresponding to the key times - Real currentTime; - - /// to know if we found the key times - bool finished; - - /// find previous and next time keys - void findKeyTimes(); -}; - - -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PARTIALLINEARMOVEMENTCONSTRAINT_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementConstraint; -#endif - -} // namespace sofa::component::constraint::projective +template +using PartialLinearMovementConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "PartialLinearMovementConstraint has been renamed to PartialLinearMovementProjectiveConstraint") = PartialLinearMovementProjectiveConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementConstraint.inl index 08bd3e7df9d..4d212e34cae 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementConstraint.inl @@ -21,487 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include - -namespace sofa::component::constraint::projective -{ - -template -PartialLinearMovementConstraint::PartialLinearMovementConstraint() - : core::behavior::ProjectiveConstraintSet(nullptr) - , data(new PartialLinearMovementConstraintInternalData) - , m_indices( initData(&m_indices,"indices","Indices of the constrained points") ) - , m_keyTimes( initData(&m_keyTimes,"keyTimes","key times for the movements") ) - , m_keyMovements( initData(&m_keyMovements,"movements","movements corresponding to the key times") ) - , showMovement( initData(&showMovement, (bool)false, "showMovement", "Visualization of the movement to be applied to constrained dofs.")) - , linearMovementBetweenNodesInIndices( initData(&linearMovementBetweenNodesInIndices, (bool)false, "linearMovementBetweenNodesInIndices", "Take into account the linear movement between the constrained points")) - , mainIndice( initData(&mainIndice, "mainIndice", "The main indice node in the list of constrained nodes, it defines how to apply the linear movement between this constrained nodes ")) - , minDepIndice( initData(&minDepIndice, "minDepIndice", "The indice node in the list of constrained nodes, which is imposed the minimum displacment ")) - , maxDepIndice( initData(&maxDepIndice, "maxDepIndice", "The indice node in the list of constrained nodes, which is imposed the maximum displacment ")) - , m_imposedDisplacmentOnMacroNodes( initData(&m_imposedDisplacmentOnMacroNodes,"imposedDisplacmentOnMacroNodes","The imposed displacment on macro nodes") ) - , X0 ( initData ( &X0, Real(0.0),"X0","Size of specimen in X-direction" ) ) - , Y0 ( initData ( &Y0, Real(0.0),"Y0","Size of specimen in Y-direction" ) ) - , Z0 ( initData ( &Z0, Real(0.0),"Z0","Size of specimen in Z-direction" ) ) - , movedDirections( initData(&movedDirections,"movedDirections","for each direction, 1 if moved, 0 if free") ) - , l_topology(initLink("topology", "link to the topology container")) - , finished(false) -{ - // default to indice 0 - m_indices.beginEdit()->push_back(0); - m_indices.endEdit(); - - //default valueEvent to 0 - m_keyTimes.beginEdit()->push_back( 0.0 ); - m_keyTimes.endEdit(); - m_keyMovements.beginEdit()->push_back( Deriv() ); - m_keyMovements.endEdit(); - VecBool movedDirection; - for( unsigned i=0; i -PartialLinearMovementConstraint::~PartialLinearMovementConstraint() -{ - -} - -template -void PartialLinearMovementConstraint::clearIndices() -{ - m_indices.beginEdit()->clear(); - m_indices.endEdit(); -} - -template -void PartialLinearMovementConstraint::addIndex(Index index) -{ - m_indices.beginEdit()->push_back(index); - m_indices.endEdit(); -} - -template -void PartialLinearMovementConstraint::removeIndex(Index index) -{ - sofa::type::removeValue(*m_indices.beginEdit(),index); - m_indices.endEdit(); -} - -template -void PartialLinearMovementConstraint::clearKeyMovements() -{ - m_keyTimes.beginEdit()->clear(); - m_keyTimes.endEdit(); - m_keyMovements.beginEdit()->clear(); - m_keyMovements.endEdit(); -} - -template -void PartialLinearMovementConstraint::addKeyMovement(Real time, Deriv movement) -{ - m_keyTimes.beginEdit()->push_back( time ); - m_keyTimes.endEdit(); - m_keyMovements.beginEdit()->push_back( movement ); - m_keyMovements.endEdit(); -} - -// -- Constraint interface - - -template -void PartialLinearMovementConstraint::init() -{ - this->core::behavior::ProjectiveConstraintSet::init(); - - if (l_topology.empty()) - { - msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; - l_topology.set(this->getContext()->getMeshTopologyLink()); - } - - if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) - { - msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; - - // Initialize topological changes support - m_indices.createTopologyHandler(_topology); - } - else - { - msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; - } - - x0.resize(0); - nextM = prevM = Deriv(); - - currentTime = -1.0; - finished = false; -} - - -template -void PartialLinearMovementConstraint::reset() -{ - nextT = prevT = 0.0; - nextM = prevM = Deriv(); - - currentTime = -1.0; - finished = false; -} - - -template -template -void PartialLinearMovementConstraint::projectResponseT(DataDeriv& dx, - const std::function& clear) -{ - Real cT = (Real) this->getContext()->getTime(); - VecBool movedDirection = movedDirections.getValue(); - if ((cT != currentTime) || !finished) - { - findKeyTimes(); - } - - if (finished && nextT != prevT) - { - const SetIndexArray & indices = m_indices.getValue(); - - //set the motion to the Dofs - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - clear(dx, *it, movedDirection); - } - } -} - -template -void PartialLinearMovementConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) -{ - SOFA_UNUSED(mparams); - helper::WriteAccessor res = resData; - projectResponseT(res.wref(), [](VecDeriv& dx, const unsigned int index, const VecBool& b) - { for (unsigned j = 0; j < b.size(); j++) if (b[j]) dx[index][j] = 0.0; }); -} - -template -void PartialLinearMovementConstraint::projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& vData) -{ - helper::WriteAccessor dx = vData; - Real cT = (Real) this->getContext()->getTime(); - if ((cT != currentTime) || !finished) - { - findKeyTimes(); - } - - if (finished && nextT != prevT) - { - const SetIndexArray & indices = m_indices.getValue(); - - //set the motion to the Dofs - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - dx[*it] = (nextM - prevM)*(1.0 / (nextT - prevT)); - } - } -} - - -template -void PartialLinearMovementConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) -{ - helper::WriteAccessor x = xData; - Real cT = (Real) this->getContext()->getTime(); - - //initialize initial Dofs positions, if it's not done - if (x0.size() == 0) - { - const SetIndexArray & indices = m_indices.getValue(); - x0.resize(x.size()); - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - x0[*it] = x[*it]; - } - } - - if ((cT != currentTime) || !finished) - { - findKeyTimes(); - } - - //if we found 2 keyTimes, we have to interpolate a velocity (linear interpolation) - if(finished && nextT != prevT) - { - interpolatePosition(cT, x.wref()); - } -} - -template -template -void PartialLinearMovementConstraint::interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x) -{ - const SetIndexArray & indices = m_indices.getValue(); - Real dt = (cT - prevT) / (nextT - prevT); - Deriv m = prevM + (nextM-prevM)*dt; - VecBool movedDirection = movedDirections.getValue(); - //set the motion to the Dofs - if(linearMovementBetweenNodesInIndices.getValue()) - { - - const type::vector &imposedDisplacmentOnMacroNodes = this->m_imposedDisplacmentOnMacroNodes.getValue(); - Real a = X0.getValue(); - Real b = Y0.getValue(); - Real c = Z0.getValue(); - bool case2d=false; - if((a==0.0)||(b==0.0)||(c==0.0)) case2d=true; - if(a==0.0) {a=b; b=c;} - if(b==0.0) {b=c;} - - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - for( unsigned j=0; j< NumDimensions; j++) - { - if(movedDirection[j]) - { - if(case2d) - { - x[*it][j] = x0[*it][j] + ((Real)1.0/(a*b))*((a-x0[*it][0])*(b-x0[*it][1])*imposedDisplacmentOnMacroNodes[0]+ ///< N1 - x0[*it][0]*(b-x0[*it][1])*imposedDisplacmentOnMacroNodes[1]+ ///< N2 - x0[*it][0]*x0[*it][1]*imposedDisplacmentOnMacroNodes[2]+ ///< N3 - (a-x0[*it][0])*x0[*it][1]*imposedDisplacmentOnMacroNodes[3])*m[j]; ///< N4 - // 4|----------------|3 - // | | - // | | - // | | - // 1|----------------|2 - } - else ///< case3d - { - // |Y - // 5---------8 - // /| /| - // / | / | - // 6--|------7 | - // | |/ | | - // | 1------|--4--->X - // | / | / - // |/ |/ - // 2---------3 - // Z/ - // - - x[*it][j] = x0[*it][j] + ((Real)1.0/(a*b*c))*( - (a-x0[*it][0])*(b-x0[*it][1])*(c-x0[*it][2])*imposedDisplacmentOnMacroNodes[0]+ ///< N1 - (a-x0[*it][0])*(b-x0[*it][1])*x0[*it][2]*imposedDisplacmentOnMacroNodes[1]+ ///< N2 - x0[*it][0]*(b-x0[*it][1])*x0[*it][2]*imposedDisplacmentOnMacroNodes[2]+ ///< N3 - x0[*it][0]*(b-x0[*it][1])*(c-x0[*it][2])*imposedDisplacmentOnMacroNodes[3]+ ///< N4 - (a-x0[*it][0])*x0[*it][1]*(c-x0[*it][2])*imposedDisplacmentOnMacroNodes[4]+ ///< N5 - (a-x0[*it][0])*x0[*it][1]*x0[*it][2]*imposedDisplacmentOnMacroNodes[5]+ ///< N6 - x0[*it][0]*x0[*it][1]*x0[*it][2]*imposedDisplacmentOnMacroNodes[6]+ ///< N7 - x0[*it][0]*x0[*it][1]*(c-x0[*it][2])*imposedDisplacmentOnMacroNodes[7] ///< N8 - - )*m[j]; - - } - } - } - } - - } - else - { - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - for( unsigned j=0; j< NumDimensions; j++) - if(movedDirection[j]) x[*it][j] = x0[*it][j] + m[j] ; - } - } - -} - -template -template -void PartialLinearMovementConstraint::interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x) -{ - const SetIndexArray & indices = m_indices.getValue(); - - Real dt = (cT - prevT) / (nextT - prevT); - Deriv m = prevM + (nextM-prevM)*dt; - type::Quat prevOrientation = type::Quat::createQuaterFromEuler(getVOrientation(prevM)); - type::Quat nextOrientation = type::Quat::createQuaterFromEuler(getVOrientation(nextM)); - - //set the motion to the Dofs - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - x[*it].getCenter() = x0[*it].getCenter() + getVCenter(m) ; - x[*it].getOrientation() = x0[*it].getOrientation() * prevOrientation.slerp2(nextOrientation, dt); - } -} - -template -void PartialLinearMovementConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) -{ - SOFA_UNUSED(mparams); - helper::WriteAccessor c = cData; - projectResponseT(c.wref(), - [](MatrixDeriv& res, const unsigned int index, const VecBool& btype) - { - auto itRow = res.begin(); - auto itRowEnd = res.end(); - - while (itRow != itRowEnd) - { - for (auto colIt = itRow.begin(); colIt != itRow.end(); colIt++) - { - if (index == (unsigned int)colIt.index()) - { - Deriv b = colIt.val(); - for (unsigned int j = 0; j < btype.size(); j++) if (btype[j]) b[j] = 0.0; - res.writeLine(itRow.index()).setCol(colIt.index(), b); - } - } - } - }); -} - -template -void PartialLinearMovementConstraint::findKeyTimes() -{ - Real cT = (Real) this->getContext()->getTime(); - finished = false; - - if(m_keyTimes.getValue().size() != 0 && cT >= *m_keyTimes.getValue().begin() && cT <= *m_keyTimes.getValue().rbegin()) - { - nextT = *m_keyTimes.getValue().begin(); - prevT = nextT; - - typename type::vector::const_iterator it_t = m_keyTimes.getValue().begin(); - typename VecDeriv::const_iterator it_m = m_keyMovements.getValue().begin(); - - //WARNING : we consider that the key-events are in chronological order - //here we search between which keyTimes we are, to know which are the motion to interpolate - while( it_t != m_keyTimes.getValue().end() && !finished) - { - if( *it_t <= cT) - { - prevT = *it_t; - prevM = *it_m; - } - else - { - nextT = *it_t; - nextM = *it_m; - finished = true; - } - ++it_t; - ++it_m; - } - } -} - -// Matrix Integration interface -template -void PartialLinearMovementConstraint::applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) -{ - SOFA_UNUSED(mparams); - const SetIndexArray & indices = m_indices.getValue(); - - if (core::behavior::MultiMatrixAccessor::MatrixRef r = matrix->getMatrix(this->mstate.get())) - { - VecBool movedDirection = movedDirections.getValue(); - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - // Reset Fixed Row and Col - for (unsigned int c=0; cclearRowCol(r.offset + NumDimensions * (*it) + c); - } - // Set Fixed Vertex - for (unsigned int c=0; cset(r.offset + NumDimensions * (*it) + c, r.offset + NumDimensions * (*it) + c, 1.0); - } - } - } -} - -template -void PartialLinearMovementConstraint::applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) -{ - SOFA_UNUSED(mparams); - const int o = matrix->getGlobalOffset(this->mstate.get()); - if (o >= 0) { - unsigned int offset = (unsigned int)o; - VecBool movedDirection = movedDirections.getValue(); - const SetIndexArray & indices = m_indices.getValue(); - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - for (unsigned int c = 0; c < NumDimensions; ++c) - { - if (movedDirection[c]) - { - vector->clear(offset + NumDimensions * (*it) + c); - } - } - } - } -} - -//display the path the constrained dofs will go through -template -void PartialLinearMovementConstraint::draw(const core::visual::VisualParams* vparams) -{ - const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); - - if (!vparams->displayFlags().getShowBehaviorModels() || m_keyTimes.getValue().size() == 0) - return; - - sofa::type::vector vertices; - constexpr sofa::type::RGBAColor color(1, 0.5, 0.5, 1); - - if (showMovement.getValue()) - { - vparams->drawTool()->disableLighting(); - - const SetIndexArray & indices = m_indices.getValue(); - const VecDeriv& keyMovements = m_keyMovements.getValue(); - for (unsigned int i = 0; i < keyMovements.size() - 1; i++) - { - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - const type::Vec3 v0 { DataTypes::getCPos(x0[*it]) + DataTypes::getDPos(keyMovements[i]) }; - const type::Vec3 v1 { DataTypes::getCPos(x0[*it]) + DataTypes::getDPos(keyMovements[i + 1]) }; - - vertices.push_back(v0); - vertices.push_back(v1); - } - } - vparams->drawTool()->drawLines(vertices, 1, color); - } - else - { - const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); - - type::Vec3 point; - const SetIndexArray & indices = m_indices.getValue(); - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - point = DataTypes::getCPos(x[*it]); - vertices.push_back(point); - } - vparams->drawTool()->drawPoints(vertices, 10, color); - } - - -} -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.cpp similarity index 73% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.cpp index 694c399bc9c..fed36af54b7 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PARTIALLINEARMOVEMENTCONSTRAINT_CPP -#include +#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PARTIALLINEARMOVEMENTPROJECTIVECONSTRAINT_CPP +#include #include #include #include @@ -29,19 +29,18 @@ namespace sofa::component::constraint::projective { //declaration of the class, for the factory -int PartialLinearMovementConstraintClass = core::RegisterObject("translate given particles") - .add< PartialLinearMovementConstraint >() - .add< PartialLinearMovementConstraint >() - .add< PartialLinearMovementConstraint >() - .add< PartialLinearMovementConstraint >() - .add< PartialLinearMovementConstraint >() - +int PartialLinearMovementProjectiveConstraintClass = core::RegisterObject("translate given particles") + .add< PartialLinearMovementProjectiveConstraint >() + .add< PartialLinearMovementProjectiveConstraint >() + .add< PartialLinearMovementProjectiveConstraint >() + .add< PartialLinearMovementProjectiveConstraint >() + .add< PartialLinearMovementProjectiveConstraint >() ; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementProjectiveConstraint; } // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.h new file mode 100644 index 00000000000..336f0bf2ce6 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.h @@ -0,0 +1,176 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +template +class PartialLinearMovementProjectiveConstraintInternalData +{ +}; + +/** impose a motion to given DOFs (translation and rotation) in some directions only. + The moved and free directioons are the same for all the particles, defined in the movedDirections attribute. + The motion between 2 key times is linearly interpolated +*/ +template +class PartialLinearMovementProjectiveConstraint : public core::behavior::ProjectiveConstraintSet +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(PartialLinearMovementProjectiveConstraint,TDataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, TDataTypes)); + + using Index = sofa::Index; + typedef TDataTypes DataTypes; + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::Real Real; + typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; + typedef typename MatrixDeriv::RowType MatrixDerivRowType; + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef Data DataMatrixDeriv; + typedef type::vector SetIndexArray; + typedef sofa::core::topology::TopologySubsetIndices SetIndex; + +protected: + PartialLinearMovementProjectiveConstraintInternalData *data; + friend class PartialLinearMovementProjectiveConstraintInternalData; + +public : + /// indices of the DOFs the constraint is applied to + SetIndex m_indices; + /// the key frames when the motion is defined by the user + core::objectmodel::Data > m_keyTimes; + /// the motions corresponding to the key frames + core::objectmodel::Data m_keyMovements; + + /// attributes to precise display + /// if showMovement is true we display the expected movement + /// otherwise we show which are the fixed dofs + core::objectmodel::Data< bool > showMovement; + + /// the key times surrounding the current simulation time (for interpolation) + Real prevT, nextT; + ///the motions corresponding to the surrouding key times + Deriv prevM, nextM; + ///initial constrained DOFs position + VecCoord x0; + + core::objectmodel::Data linearMovementBetweenNodesInIndices; ///< Take into account the linear movement between the constrained points + core::objectmodel::Data mainIndice; ///< The main indice node in the list of constrained nodes, it defines how to apply the linear movement between this constrained nodes + core::objectmodel::Data minDepIndice; ///< The indice node in the list of constrained nodes, which is imposed the minimum displacment + core::objectmodel::Data maxDepIndice; ///< The indice node in the list of constrained nodes, which is imposed the maximum displacment + core::objectmodel::Data > m_imposedDisplacmentOnMacroNodes; ///< imposed displacement at u1 u2 u3 u4 for 2d case + ///< and u1 u2 u3 u4 u5 u6 u7 u8 for 3d case + Data X0; ///< Size of specimen in X-direction + Data Y0; ///< Size of specimen in Y-direction + Data Z0; ///< Size of specimen in Z-direction + + enum { NumDimensions = Deriv::total_size }; + typedef sofa::type::fixed_array VecBool; + core::objectmodel::Data movedDirections; ///< Defines the directions in which the particles are moved: true (or 1) for fixed, false (or 0) for free. + + /// Link to be set to the topology container in the component graph. + SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; + +protected: + PartialLinearMovementProjectiveConstraint(); + ~PartialLinearMovementProjectiveConstraint() override; + +public: + ///methods to add/remove some indices, keyTimes, keyMovement + void clearIndices(); + void addIndex(Index index); + void removeIndex(Index index); + void clearKeyMovements(); + + ///@brief Add a new key movement + ///@param time : the simulation time you want to set a movement (in sec) + ///@param movement : the corresponding motion + ///for instance, addKeyMovement(1.0, Deriv(5,0,0) ) will set a translation of 5 in x direction a time 1.0s + void addKeyMovement(Real time, Deriv movement); + + + /// -- Constraint interface + void init() override; + void reset() override; + + void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; + void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; + void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; + void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; + + void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + + void draw(const core::visual::VisualParams*) override; + +protected: + template + void projectResponseT(DataDeriv& dx, + const std::function& clear); + + template + void interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x); + template + void interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x); + +private: + + /// to keep the time corresponding to the key times + Real currentTime; + + /// to know if we found the key times + bool finished; + + /// find previous and next time keys + void findKeyTimes(); +}; + + +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PARTIALLINEARMOVEMENTPROJECTIVECONSTRAINT_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementProjectiveConstraint; +#endif + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.inl new file mode 100644 index 00000000000..af02bb262d2 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.inl @@ -0,0 +1,507 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace sofa::component::constraint::projective +{ + +template +PartialLinearMovementProjectiveConstraint::PartialLinearMovementProjectiveConstraint() + : core::behavior::ProjectiveConstraintSet(nullptr) + , data(new PartialLinearMovementProjectiveConstraintInternalData) + , m_indices( initData(&m_indices,"indices","Indices of the constrained points") ) + , m_keyTimes( initData(&m_keyTimes,"keyTimes","key times for the movements") ) + , m_keyMovements( initData(&m_keyMovements,"movements","movements corresponding to the key times") ) + , showMovement( initData(&showMovement, (bool)false, "showMovement", "Visualization of the movement to be applied to constrained dofs.")) + , linearMovementBetweenNodesInIndices( initData(&linearMovementBetweenNodesInIndices, (bool)false, "linearMovementBetweenNodesInIndices", "Take into account the linear movement between the constrained points")) + , mainIndice( initData(&mainIndice, "mainIndice", "The main indice node in the list of constrained nodes, it defines how to apply the linear movement between this constrained nodes ")) + , minDepIndice( initData(&minDepIndice, "minDepIndice", "The indice node in the list of constrained nodes, which is imposed the minimum displacment ")) + , maxDepIndice( initData(&maxDepIndice, "maxDepIndice", "The indice node in the list of constrained nodes, which is imposed the maximum displacment ")) + , m_imposedDisplacmentOnMacroNodes( initData(&m_imposedDisplacmentOnMacroNodes,"imposedDisplacmentOnMacroNodes","The imposed displacment on macro nodes") ) + , X0 ( initData ( &X0, Real(0.0),"X0","Size of specimen in X-direction" ) ) + , Y0 ( initData ( &Y0, Real(0.0),"Y0","Size of specimen in Y-direction" ) ) + , Z0 ( initData ( &Z0, Real(0.0),"Z0","Size of specimen in Z-direction" ) ) + , movedDirections( initData(&movedDirections,"movedDirections","for each direction, 1 if moved, 0 if free") ) + , l_topology(initLink("topology", "link to the topology container")) + , finished(false) +{ + // default to indice 0 + m_indices.beginEdit()->push_back(0); + m_indices.endEdit(); + + //default valueEvent to 0 + m_keyTimes.beginEdit()->push_back( 0.0 ); + m_keyTimes.endEdit(); + m_keyMovements.beginEdit()->push_back( Deriv() ); + m_keyMovements.endEdit(); + VecBool movedDirection; + for( unsigned i=0; i +PartialLinearMovementProjectiveConstraint::~PartialLinearMovementProjectiveConstraint() +{ + +} + +template +void PartialLinearMovementProjectiveConstraint::clearIndices() +{ + m_indices.beginEdit()->clear(); + m_indices.endEdit(); +} + +template +void PartialLinearMovementProjectiveConstraint::addIndex(Index index) +{ + m_indices.beginEdit()->push_back(index); + m_indices.endEdit(); +} + +template +void PartialLinearMovementProjectiveConstraint::removeIndex(Index index) +{ + sofa::type::removeValue(*m_indices.beginEdit(),index); + m_indices.endEdit(); +} + +template +void PartialLinearMovementProjectiveConstraint::clearKeyMovements() +{ + m_keyTimes.beginEdit()->clear(); + m_keyTimes.endEdit(); + m_keyMovements.beginEdit()->clear(); + m_keyMovements.endEdit(); +} + +template +void PartialLinearMovementProjectiveConstraint::addKeyMovement(Real time, Deriv movement) +{ + m_keyTimes.beginEdit()->push_back( time ); + m_keyTimes.endEdit(); + m_keyMovements.beginEdit()->push_back( movement ); + m_keyMovements.endEdit(); +} + +// -- Constraint interface + + +template +void PartialLinearMovementProjectiveConstraint::init() +{ + this->core::behavior::ProjectiveConstraintSet::init(); + + if (l_topology.empty()) + { + msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; + l_topology.set(this->getContext()->getMeshTopologyLink()); + } + + if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) + { + msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; + + // Initialize topological changes support + m_indices.createTopologyHandler(_topology); + } + else + { + msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; + } + + x0.resize(0); + nextM = prevM = Deriv(); + + currentTime = -1.0; + finished = false; +} + + +template +void PartialLinearMovementProjectiveConstraint::reset() +{ + nextT = prevT = 0.0; + nextM = prevM = Deriv(); + + currentTime = -1.0; + finished = false; +} + + +template +template +void PartialLinearMovementProjectiveConstraint::projectResponseT(DataDeriv& dx, + const std::function& clear) +{ + Real cT = (Real) this->getContext()->getTime(); + VecBool movedDirection = movedDirections.getValue(); + if ((cT != currentTime) || !finished) + { + findKeyTimes(); + } + + if (finished && nextT != prevT) + { + const SetIndexArray & indices = m_indices.getValue(); + + //set the motion to the Dofs + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + clear(dx, *it, movedDirection); + } + } +} + +template +void PartialLinearMovementProjectiveConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) +{ + SOFA_UNUSED(mparams); + helper::WriteAccessor res = resData; + projectResponseT(res.wref(), [](VecDeriv& dx, const unsigned int index, const VecBool& b) + { for (unsigned j = 0; j < b.size(); j++) if (b[j]) dx[index][j] = 0.0; }); +} + +template +void PartialLinearMovementProjectiveConstraint::projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& vData) +{ + helper::WriteAccessor dx = vData; + Real cT = (Real) this->getContext()->getTime(); + if ((cT != currentTime) || !finished) + { + findKeyTimes(); + } + + if (finished && nextT != prevT) + { + const SetIndexArray & indices = m_indices.getValue(); + + //set the motion to the Dofs + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + dx[*it] = (nextM - prevM)*(1.0 / (nextT - prevT)); + } + } +} + + +template +void PartialLinearMovementProjectiveConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) +{ + helper::WriteAccessor x = xData; + Real cT = (Real) this->getContext()->getTime(); + + //initialize initial Dofs positions, if it's not done + if (x0.size() == 0) + { + const SetIndexArray & indices = m_indices.getValue(); + x0.resize(x.size()); + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + x0[*it] = x[*it]; + } + } + + if ((cT != currentTime) || !finished) + { + findKeyTimes(); + } + + //if we found 2 keyTimes, we have to interpolate a velocity (linear interpolation) + if(finished && nextT != prevT) + { + interpolatePosition(cT, x.wref()); + } +} + +template +template +void PartialLinearMovementProjectiveConstraint::interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x) +{ + const SetIndexArray & indices = m_indices.getValue(); + Real dt = (cT - prevT) / (nextT - prevT); + Deriv m = prevM + (nextM-prevM)*dt; + VecBool movedDirection = movedDirections.getValue(); + //set the motion to the Dofs + if(linearMovementBetweenNodesInIndices.getValue()) + { + + const type::vector &imposedDisplacmentOnMacroNodes = this->m_imposedDisplacmentOnMacroNodes.getValue(); + Real a = X0.getValue(); + Real b = Y0.getValue(); + Real c = Z0.getValue(); + bool case2d=false; + if((a==0.0)||(b==0.0)||(c==0.0)) case2d=true; + if(a==0.0) {a=b; b=c;} + if(b==0.0) {b=c;} + + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + for( unsigned j=0; j< NumDimensions; j++) + { + if(movedDirection[j]) + { + if(case2d) + { + x[*it][j] = x0[*it][j] + ((Real)1.0/(a*b))*((a-x0[*it][0])*(b-x0[*it][1])*imposedDisplacmentOnMacroNodes[0]+ ///< N1 + x0[*it][0]*(b-x0[*it][1])*imposedDisplacmentOnMacroNodes[1]+ ///< N2 + x0[*it][0]*x0[*it][1]*imposedDisplacmentOnMacroNodes[2]+ ///< N3 + (a-x0[*it][0])*x0[*it][1]*imposedDisplacmentOnMacroNodes[3])*m[j]; ///< N4 + // 4|----------------|3 + // | | + // | | + // | | + // 1|----------------|2 + } + else ///< case3d + { + // |Y + // 5---------8 + // /| /| + // / | / | + // 6--|------7 | + // | |/ | | + // | 1------|--4--->X + // | / | / + // |/ |/ + // 2---------3 + // Z/ + // + + x[*it][j] = x0[*it][j] + ((Real)1.0/(a*b*c))*( + (a-x0[*it][0])*(b-x0[*it][1])*(c-x0[*it][2])*imposedDisplacmentOnMacroNodes[0]+ ///< N1 + (a-x0[*it][0])*(b-x0[*it][1])*x0[*it][2]*imposedDisplacmentOnMacroNodes[1]+ ///< N2 + x0[*it][0]*(b-x0[*it][1])*x0[*it][2]*imposedDisplacmentOnMacroNodes[2]+ ///< N3 + x0[*it][0]*(b-x0[*it][1])*(c-x0[*it][2])*imposedDisplacmentOnMacroNodes[3]+ ///< N4 + (a-x0[*it][0])*x0[*it][1]*(c-x0[*it][2])*imposedDisplacmentOnMacroNodes[4]+ ///< N5 + (a-x0[*it][0])*x0[*it][1]*x0[*it][2]*imposedDisplacmentOnMacroNodes[5]+ ///< N6 + x0[*it][0]*x0[*it][1]*x0[*it][2]*imposedDisplacmentOnMacroNodes[6]+ ///< N7 + x0[*it][0]*x0[*it][1]*(c-x0[*it][2])*imposedDisplacmentOnMacroNodes[7] ///< N8 + + )*m[j]; + + } + } + } + } + + } + else + { + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + for( unsigned j=0; j< NumDimensions; j++) + if(movedDirection[j]) x[*it][j] = x0[*it][j] + m[j] ; + } + } + +} + +template +template +void PartialLinearMovementProjectiveConstraint::interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x) +{ + const SetIndexArray & indices = m_indices.getValue(); + + Real dt = (cT - prevT) / (nextT - prevT); + Deriv m = prevM + (nextM-prevM)*dt; + type::Quat prevOrientation = type::Quat::createQuaterFromEuler(getVOrientation(prevM)); + type::Quat nextOrientation = type::Quat::createQuaterFromEuler(getVOrientation(nextM)); + + //set the motion to the Dofs + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + x[*it].getCenter() = x0[*it].getCenter() + getVCenter(m) ; + x[*it].getOrientation() = x0[*it].getOrientation() * prevOrientation.slerp2(nextOrientation, dt); + } +} + +template +void PartialLinearMovementProjectiveConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) +{ + SOFA_UNUSED(mparams); + helper::WriteAccessor c = cData; + projectResponseT(c.wref(), + [](MatrixDeriv& res, const unsigned int index, const VecBool& btype) + { + auto itRow = res.begin(); + auto itRowEnd = res.end(); + + while (itRow != itRowEnd) + { + for (auto colIt = itRow.begin(); colIt != itRow.end(); colIt++) + { + if (index == (unsigned int)colIt.index()) + { + Deriv b = colIt.val(); + for (unsigned int j = 0; j < btype.size(); j++) if (btype[j]) b[j] = 0.0; + res.writeLine(itRow.index()).setCol(colIt.index(), b); + } + } + } + }); +} + +template +void PartialLinearMovementProjectiveConstraint::findKeyTimes() +{ + Real cT = (Real) this->getContext()->getTime(); + finished = false; + + if(m_keyTimes.getValue().size() != 0 && cT >= *m_keyTimes.getValue().begin() && cT <= *m_keyTimes.getValue().rbegin()) + { + nextT = *m_keyTimes.getValue().begin(); + prevT = nextT; + + typename type::vector::const_iterator it_t = m_keyTimes.getValue().begin(); + typename VecDeriv::const_iterator it_m = m_keyMovements.getValue().begin(); + + //WARNING : we consider that the key-events are in chronological order + //here we search between which keyTimes we are, to know which are the motion to interpolate + while( it_t != m_keyTimes.getValue().end() && !finished) + { + if( *it_t <= cT) + { + prevT = *it_t; + prevM = *it_m; + } + else + { + nextT = *it_t; + nextM = *it_m; + finished = true; + } + ++it_t; + ++it_m; + } + } +} + +// Matrix Integration interface +template +void PartialLinearMovementProjectiveConstraint::applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) +{ + SOFA_UNUSED(mparams); + const SetIndexArray & indices = m_indices.getValue(); + + if (core::behavior::MultiMatrixAccessor::MatrixRef r = matrix->getMatrix(this->mstate.get())) + { + VecBool movedDirection = movedDirections.getValue(); + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + // Reset Fixed Row and Col + for (unsigned int c=0; cclearRowCol(r.offset + NumDimensions * (*it) + c); + } + // Set Fixed Vertex + for (unsigned int c=0; cset(r.offset + NumDimensions * (*it) + c, r.offset + NumDimensions * (*it) + c, 1.0); + } + } + } +} + +template +void PartialLinearMovementProjectiveConstraint::applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) +{ + SOFA_UNUSED(mparams); + const int o = matrix->getGlobalOffset(this->mstate.get()); + if (o >= 0) { + unsigned int offset = (unsigned int)o; + VecBool movedDirection = movedDirections.getValue(); + const SetIndexArray & indices = m_indices.getValue(); + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + for (unsigned int c = 0; c < NumDimensions; ++c) + { + if (movedDirection[c]) + { + vector->clear(offset + NumDimensions * (*it) + c); + } + } + } + } +} + +//display the path the constrained dofs will go through +template +void PartialLinearMovementProjectiveConstraint::draw(const core::visual::VisualParams* vparams) +{ + const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); + + if (!vparams->displayFlags().getShowBehaviorModels() || m_keyTimes.getValue().size() == 0) + return; + + sofa::type::vector vertices; + constexpr sofa::type::RGBAColor color(1, 0.5, 0.5, 1); + + if (showMovement.getValue()) + { + vparams->drawTool()->disableLighting(); + + const SetIndexArray & indices = m_indices.getValue(); + const VecDeriv& keyMovements = m_keyMovements.getValue(); + for (unsigned int i = 0; i < keyMovements.size() - 1; i++) + { + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + const type::Vec3 v0 { DataTypes::getCPos(x0[*it]) + DataTypes::getDPos(keyMovements[i]) }; + const type::Vec3 v1 { DataTypes::getCPos(x0[*it]) + DataTypes::getDPos(keyMovements[i + 1]) }; + + vertices.push_back(v0); + vertices.push_back(v1); + } + } + vparams->drawTool()->drawLines(vertices, 1, color); + } + else + { + const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); + + type::Vec3 point; + const SetIndexArray & indices = m_indices.getValue(); + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + point = DataTypes::getCPos(x[*it]); + vertices.push_back(point); + } + vparams->drawTool()->drawPoints(vertices, 10, color); + } + + +} +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementConstraint.h index 2a53250282d..3857c8c889c 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementConstraint.h @@ -20,146 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include -#include -#include +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/PatchTestMovementProjectiveConstraint.h") namespace sofa::component::constraint::projective { - -template -class PatchTestMovementConstraintInternalData -{ -}; - -/** - Impose a motion to all the boundary points of a mesh. The motion of the 4 corners are given in the data d_cornerMovements and the movements of the edge points are computed by linear interpolation. -*/ -template -class PatchTestMovementConstraint : public core::behavior::ProjectiveConstraintSet -{ -public: - SOFA_CLASS(SOFA_TEMPLATE(PatchTestMovementConstraint,TDataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, TDataTypes)); - - using Index = sofa::Index; - typedef TDataTypes DataTypes; - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::Real Real; - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef type::vector SetIndexArray; - typedef sofa::core::topology::TopologySubsetIndices SetIndex; - - static constexpr unsigned int CoordSize = Coord::total_size; - - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef core::objectmodel::Data DataMatrixDeriv; - -protected: - PatchTestMovementConstraintInternalData *data; - friend class PatchTestMovementConstraintInternalData; - -public : - /// indices of the DOFs of the mesh - SetIndex d_meshIndices; - /// indices of the DOFs the constraint is applied to - SetIndex d_indices; - /// data begin time when the constraint is applied - Data d_beginConstraintTime; - /// data end time when the constraint is applied - Data d_endConstraintTime; - /// coordinates of the DOFs the constraint is applied to - Data d_constrainedPoints; - /// the movements of the corner points (this is the difference between initial and final positions of the 4 corners) - Data d_cornerMovements; - /// the coordinates of the corner points - Data d_cornerPoints; - /// Draw constrained points - Data d_drawConstrainedPoints; - /// initial constrained DOFs position - VecCoord x0; - /// final constrained DOFs position - VecCoord xf; - /// initial mesh DOFs position - VecCoord meshPointsX0; - /// final mesh DOFs position - VecCoord meshPointsXf; - - /// Link to be set to the topology container in the component graph. - SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; - -protected: - PatchTestMovementConstraint(); - - virtual ~PatchTestMovementConstraint(); - -public: - //Add or clear constraints - void clearConstraints(); - void addConstraint(Index index); - void removeConstraint(Index index); - - /// -- Constraint interface - void init() override; - - /// Cancel the possible forces - void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; - /// Cancel the possible velocities - void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; - /// Apply the computed movements to the border mesh points between beginConstraintTime and endConstraintTime - void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; - // Implement projectMatrix for assembled solver of compliant - void projectMatrix( sofa::linearalgebra::BaseMatrix* /*M*/, unsigned /*offset*/ ) override; - - void projectJacobianMatrix(const core::MechanicalParams* /*mparams*/, DataMatrixDeriv& /* cData */) override - { - msg_error() <<"projectJacobianMatrix not implemented"; - } - - /// Compute the theoretical final positions - void getFinalPositions (VecCoord& finalPos, DataVecCoord& xData); - - /// Draw the constrained points (= border mesh points) - void draw(const core::visual::VisualParams* vparams) override; - -protected: - - void projectResponseImpl(VecDeriv& dx); - -private: - - /// Find the corners of the grid mesh - void findCornerPoints(); - - /// Compute the displacement of each mesh point by linear interpolation with the displacement of corner points - void computeInterpolatedDisplacement (int pointIndice,const DataVecCoord& xData, Deriv& displacement); - - /// Initialize initial positions - void initializeInitialPositions (const SetIndexArray & indices, DataVecCoord& xData, VecCoord& x0); - - /// Initialize final positions - void initializeFinalPositions (const SetIndexArray & indices, DataVecCoord& xData, VecCoord& x0 , VecCoord& xf); -}; - - -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PATCHTESTMOVEMENTCONSTRAINT_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PatchTestMovementConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PatchTestMovementConstraint; - -#endif - -} // namespace sofa::component::constraint::projective +template +using PatchTestMovementConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "PatchTestMovementConstraint has been renamed to PatchTestMovementProjectiveConstraint") = PatchTestMovementProjectiveConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementConstraint.inl index be21d19e187..7a3a2a49a06 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementConstraint.inl @@ -21,429 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -template -PatchTestMovementConstraint::PatchTestMovementConstraint() - : core::behavior::ProjectiveConstraintSet(nullptr) - , data(new PatchTestMovementConstraintInternalData) - , d_meshIndices( initData(&d_meshIndices,"meshIndices","Indices of the mesh") ) - , d_indices( initData(&d_indices,"indices","Indices of the constrained points") ) - , d_beginConstraintTime( initData(&d_beginConstraintTime,"beginConstraintTime","Begin time of the bilinear constraint") ) - , d_endConstraintTime( initData(&d_endConstraintTime,"endConstraintTime","End time of the bilinear constraint") ) - , d_constrainedPoints( initData(&d_constrainedPoints,"constrainedPoints","Coordinates of the constrained points") ) - , d_cornerMovements( initData(&d_cornerMovements,"cornerMovements","movements of the corners of the grid") ) - , d_cornerPoints( initData(&d_cornerPoints,"cornerPoints","corner points for computing constraint") ) - , d_drawConstrainedPoints( initData(&d_drawConstrainedPoints,"drawConstrainedPoints","draw constrained points") ) - , l_topology(initLink("topology", "link to the topology container")) -{ - if(!d_beginConstraintTime.isSet()) - d_beginConstraintTime = 0; - if(!d_endConstraintTime.isSet()) - d_endConstraintTime = 20; -} - - - -template -PatchTestMovementConstraint::~PatchTestMovementConstraint() -{ - -} - -template -void PatchTestMovementConstraint::clearConstraints() -{ - d_indices.beginEdit()->clear(); - d_indices.endEdit(); -} - -template -void PatchTestMovementConstraint::addConstraint(Index index) -{ - d_indices.beginEdit()->push_back(index); - d_indices.endEdit(); -} - -template -void PatchTestMovementConstraint::removeConstraint(Index index) -{ - sofa::type::removeValue(*d_indices.beginEdit(),index); - d_indices.endEdit(); -} - -// -- Constraint interface - - -template -void PatchTestMovementConstraint::init() -{ - this->core::behavior::ProjectiveConstraintSet::init(); - - if (l_topology.empty()) - { - msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; - l_topology.set(this->getContext()->getMeshTopologyLink()); - } - - if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) - { - msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; - - // Initialize topological changes support - d_indices.createTopologyHandler(_topology); - } - else - { - msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; - } - - const SetIndexArray & indices = d_indices.getValue(); - - const Index maxIndex=this->mstate->getSize(); - for (unsigned int i=0; i= maxIndex) - { - msg_error() <<"Index " << index << " not valid!"; - removeConstraint(index); - } - } - - // Find the 4 corners of the grid topology - this->findCornerPoints(); -} - -template -void PatchTestMovementConstraint::findCornerPoints() -{ - Coord corner0, corner1, corner2, corner3,corner4,corner5,corner6,corner7; - // Write accessor - helper::WriteAccessor< Data > cornerPositions = d_cornerPoints; - helper::WriteAccessor< Data > constrainedPoints = d_constrainedPoints; - bool isMeshin3D = false; - - if (!constrainedPoints.empty()) - { - const Coord& point = constrainedPoints[0]; - - // Search if the constrained points are in the same plane - for(Size i = 0; i < constrainedPoints.size() ; i++) - { - if(CoordSize > 2 && constrainedPoints[i][2]!=point[2]) - { - isMeshin3D = true; - } - } - } - - if(constrainedPoints.size() > 0) - { - corner0 = constrainedPoints[0]; - corner1 = constrainedPoints[0]; - corner2 = constrainedPoints[0]; - corner3 = constrainedPoints[0]; - corner4 = constrainedPoints[0]; - corner5 = constrainedPoints[0]; - corner6 = constrainedPoints[0]; - corner7 = constrainedPoints[0]; - - for (size_t i = 0; i < constrainedPoints.size() ; i++) - { - if(constrainedPoints[i][0] < corner0[0] || constrainedPoints[i][1] < corner0[1] || ( CoordSize>2 && constrainedPoints[i][2] < corner0[2] ) ) - { - corner0 = constrainedPoints[i]; - } - - if(constrainedPoints[i][0] > corner2[0] || constrainedPoints[i][1] > corner2[1] || ( CoordSize>2 && constrainedPoints[i][2] < corner2[2] ) ) - { - corner2 = constrainedPoints[i]; - } - - if(constrainedPoints[i][1] < corner1[1] || constrainedPoints[i][0] > corner1[0] || ( CoordSize>2 && constrainedPoints[i][2] < corner1[2] )) - { - corner1 = constrainedPoints[i]; - } - - if(constrainedPoints[i][0] < corner3[0] || constrainedPoints[i][1] > corner3[1] || ( CoordSize>2 && constrainedPoints[i][2] < corner3[2] )) - { - corner3 = constrainedPoints[i]; - } - - if(isMeshin3D && (constrainedPoints[i][0] < corner4[0] || constrainedPoints[i][1] < corner4[1] || (CoordSize>2 && constrainedPoints[i][2] > corner0[2] )) ) - { - corner4 = constrainedPoints[i]; - } - - if(isMeshin3D && (constrainedPoints[i][0] > corner6[0] || constrainedPoints[i][1] > corner6[1] || (CoordSize>2 && constrainedPoints[i][2] > corner2[2] )) ) - { - corner6 = constrainedPoints[i]; - } - - if(isMeshin3D && (constrainedPoints[i][1] < corner5[1] || constrainedPoints[i][0] > corner5[0] || (CoordSize>2 && constrainedPoints[i][2] > corner5[2] )) ) - { - corner5 = constrainedPoints[i]; - } - - else if(isMeshin3D && (constrainedPoints[i][0] < corner7[0] || constrainedPoints[i][1] > corner7[1] || (CoordSize>2 && constrainedPoints[i][2] > corner7[2] )) ) - { - corner7 = constrainedPoints[i]; - } - } - - cornerPositions.push_back(corner0); - cornerPositions.push_back(corner1); - cornerPositions.push_back(corner2); - cornerPositions.push_back(corner3); - - // 3D - if(isMeshin3D) - { - cornerPositions.push_back(corner4); - cornerPositions.push_back(corner5); - cornerPositions.push_back(corner6); - cornerPositions.push_back(corner7); - } - } -} - -template -void PatchTestMovementConstraint::projectResponseImpl(VecDeriv& dx) -{ - const SetIndexArray & indices = d_indices.getValue(); - for (size_t i = 0; i< indices.size(); ++i) - { - dx[indices[i]]=Deriv(); - } -} - -template -void PatchTestMovementConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) -{ - SOFA_UNUSED(mparams); - helper::WriteAccessor res = resData; - projectResponseImpl(res.wref()); -} - -template -void PatchTestMovementConstraint::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) -{ - SOFA_UNUSED(mparams); - helper::WriteAccessor res = vData; - projectResponseImpl(res.wref()); -} - -template -void PatchTestMovementConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) -{ - const sofa::simulation::Node::SPtr root = down_cast( this->getContext()->getRootContext() ); - helper::WriteAccessor x = xData; - const SetIndexArray & indices = d_indices.getValue(); - - // Time - double beginTime = d_beginConstraintTime.getValue(); - double endTime = d_endConstraintTime.getValue(); - double totalTime = endTime - beginTime; - - //initialize initial mesh Dofs positions, if it's not done - if(meshPointsX0.size()==0) - this->initializeInitialPositions(d_meshIndices.getValue(),xData,meshPointsX0); - - //initialize final mesh Dofs positions, if it's not done - if(meshPointsXf.size()==0) - this->initializeFinalPositions(d_meshIndices.getValue(),xData, meshPointsX0, meshPointsXf); - - //initialize initial constrained Dofs positions, if it's not done - if(x0.size() == 0) - this->initializeInitialPositions(indices,xData,x0); - - //initialize final constrained Dofs positions, if it's not done - if (xf.size() == 0) - this->initializeFinalPositions(indices,xData,x0,xf); - - // Update the intermediate Dofs positions computed by linear interpolation - double time = root->getTime(); - if( time > beginTime && time <= endTime && totalTime > 0) - { - for (size_t i = 0; i< indices.size(); ++i) - { - x[indices[i]] = ((xf[indices[i]]-x0[indices[i]])*time + (x0[indices[i]]*endTime - xf[indices[i]]*beginTime))/totalTime; - } - } - else if (time > endTime) - { - for (size_t i = 0; i< indices.size(); ++i) - { - x[indices[i]] = xf[indices[i]]; - } - } -} - -template -void PatchTestMovementConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) -{ - // clears the rows and columns associated with constrained particles - const unsigned blockSize = DataTypes::deriv_total_size; - - for (const auto id : d_indices.getValue()) - { - M->clearRowsCols( offset + id * blockSize, offset + (id+1) * blockSize ); - } - -} - -template -void PatchTestMovementConstraint::getFinalPositions( VecCoord& finalPos,DataVecCoord& xData) -{ - // Indices of mesh points - const SetIndexArray & meshIndices = d_meshIndices.getValue(); - - // Initialize final positions - if(meshPointsXf.size()==0) - {this->initializeFinalPositions(meshIndices,xData,meshPointsX0,meshPointsXf);} - - // Set final positions - finalPos.resize(meshIndices.size()); - for (size_t i=0; i < meshIndices.size() ; ++i) - { - finalPos[meshIndices[i]] = meshPointsXf[meshIndices[i]]; - } -} - -template -void PatchTestMovementConstraint::initializeInitialPositions (const SetIndexArray & indices, DataVecCoord& xData, VecCoord& x0) -{ - helper::WriteAccessor x = xData; - - x0.resize(x.size()); - for (size_t i=0; i < indices.size() ; ++i) - { - x0[indices[i]] = x[indices[i]]; - } - -} - -template -void PatchTestMovementConstraint::initializeFinalPositions (const SetIndexArray & indices, DataVecCoord& xData, VecCoord& x0, VecCoord& xf) -{ - Deriv displacement; - helper::WriteAccessor x = xData; - - xf.resize(x.size()); - - // if the positions were not initialized - if(x0.size() == 0) - this->initializeInitialPositions(indices,xData,x0); - - for (size_t i=0; i < indices.size() ; ++i) - { - this->computeInterpolatedDisplacement(indices[i],xData,displacement); - xf[indices[i]] = x0[indices[i]] + displacement ; - } - -} - -template -void PatchTestMovementConstraint::computeInterpolatedDisplacement(int pointIndice,const DataVecCoord& xData, Deriv& displacement) -{ - // For each mesh point compute the associated displacement - - // The 3 barycentric coefficients along x, y and z axis - Real alpha, beta, gamma; - - // Corner points - const VecCoord& cornerPoints = d_cornerPoints.getValue(); - if(cornerPoints.size()==0) - this->findCornerPoints(); - - if(cornerPoints.size() == 4) - { - Coord corner0 = cornerPoints[0]; - Coord corner1 = cornerPoints[1]; - Coord corner3 = cornerPoints[3]; - - // Coord of the point - helper::ReadAccessor x = xData; - Coord point = x[pointIndice]; - - // Compute alpha = barycentric coefficient along the x axis - alpha = fabs(point[0]-corner0[0])/fabs(corner1[0]-corner0[0]); - - // Compute beta = barycentric coefficient along the y axis - beta = fabs(point[1]-corner0[1])/fabs(corner3[1]-corner0[1]); - - // cornerMovements - const VecDeriv& cornerMovements = d_cornerMovements.getValue(); - - // Compute displacement by linear interpolation - displacement = cornerMovements[0]*(1-alpha)*(1-beta) + cornerMovements[1]*alpha*(1-beta)+ cornerMovements[2]*alpha*beta+cornerMovements[3]*(1-alpha)*beta; - } - - else if(cornerPoints.size() == 8) - { - Coord corner0 = cornerPoints[0]; - Coord corner1 = cornerPoints[1]; - Coord corner3 = cornerPoints[3]; - Coord corner4 = cornerPoints[4]; - - // Coord of the point - helper::ReadAccessor x = xData; - Coord point = x[pointIndice]; - - // Compute alpha = barycentric coefficient along the x axis - alpha = fabs(point[0]-corner0[0])/fabs(corner1[0]-corner0[0]); - - // Compute beta = barycentric coefficient along the y axis - beta = fabs(point[1]-corner0[1])/fabs(corner3[1]-corner0[1]); - - // Compute gamma = barycentric coefficient along the z axis - if( CoordSize>2 ) - gamma = fabs(point[2]-corner0[2])/fabs(corner4[2]-corner0[2]); // 3D - else - gamma = 0; // 2D - - // cornerMovements - const VecDeriv& cornerMovements = d_cornerMovements.getValue(); - - // Compute displacement by linear interpolation - displacement = (cornerMovements[0]*(1-alpha)*(1-beta) + cornerMovements[1]*alpha*(1-beta)+ cornerMovements[2]*alpha*beta+cornerMovements[3]*(1-alpha)*beta) * (1-gamma) - + (cornerMovements[4]*(1-alpha)*(1-beta) + cornerMovements[5]*alpha*(1-beta)+ cornerMovements[6]*alpha*beta+cornerMovements[7]*(1-alpha)*beta) * gamma; - } - else - { - msg_info() << "error don't find the corner points" ; - } - -} - -template -void PatchTestMovementConstraint::draw(const core::visual::VisualParams* vparams) -{ - const SetIndexArray & indices = d_indices.getValue(); - const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); - type::Vec3 point; - - if(d_drawConstrainedPoints.getValue()) - { - std::vector< type::Vec3 > points; - for (unsigned int index : indices) - { - point = DataTypes::getCPos(x[index]); - points.push_back(point); - } - vparams->drawTool()->drawPoints(points, 10, sofa::type::RGBAColor(1,0.5,0.5,1)); - } -} - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/PatchTestMovementProjectiveConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementProjectiveConstraint.cpp similarity index 84% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementProjectiveConstraint.cpp index beb420617e0..3b17d682ecd 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementProjectiveConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PATCHTESTMOVEMENTCONSTRAINT_CPP -#include +#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PATCHTESTMOVEMENTPROJECTIVECONSTRAINT_CPP +#include #include #include #include @@ -29,14 +29,13 @@ namespace sofa::component::constraint::projective { //declaration of the class, for the factory -int PatchTestMovementConstraintClass = core::RegisterObject("bilinear constraint") - .add< PatchTestMovementConstraint >() - .add< PatchTestMovementConstraint >() - +int PatchTestMovementProjectiveConstraintClass = core::RegisterObject("bilinear constraint") + .add< PatchTestMovementProjectiveConstraint >() + .add< PatchTestMovementProjectiveConstraint >() ; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PatchTestMovementConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PatchTestMovementConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PatchTestMovementProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PatchTestMovementProjectiveConstraint; } // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementProjectiveConstraint.h new file mode 100644 index 00000000000..5cabd8d460f --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementProjectiveConstraint.h @@ -0,0 +1,165 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace sofa::component::constraint::projective +{ + +template +class PatchTestMovementProjectiveConstraintInternalData +{ +}; + +/** + Impose a motion to all the boundary points of a mesh. The motion of the 4 corners are given in the data d_cornerMovements and the movements of the edge points are computed by linear interpolation. +*/ +template +class PatchTestMovementProjectiveConstraint : public core::behavior::ProjectiveConstraintSet +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(PatchTestMovementProjectiveConstraint,TDataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, TDataTypes)); + + using Index = sofa::Index; + typedef TDataTypes DataTypes; + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::Real Real; + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef type::vector SetIndexArray; + typedef sofa::core::topology::TopologySubsetIndices SetIndex; + + static constexpr unsigned int CoordSize = Coord::total_size; + + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef core::objectmodel::Data DataMatrixDeriv; + +protected: + PatchTestMovementProjectiveConstraintInternalData *data; + friend class PatchTestMovementProjectiveConstraintInternalData; + +public : + /// indices of the DOFs of the mesh + SetIndex d_meshIndices; + /// indices of the DOFs the constraint is applied to + SetIndex d_indices; + /// data begin time when the constraint is applied + Data d_beginConstraintTime; + /// data end time when the constraint is applied + Data d_endConstraintTime; + /// coordinates of the DOFs the constraint is applied to + Data d_constrainedPoints; + /// the movements of the corner points (this is the difference between initial and final positions of the 4 corners) + Data d_cornerMovements; + /// the coordinates of the corner points + Data d_cornerPoints; + /// Draw constrained points + Data d_drawConstrainedPoints; + /// initial constrained DOFs position + VecCoord x0; + /// final constrained DOFs position + VecCoord xf; + /// initial mesh DOFs position + VecCoord meshPointsX0; + /// final mesh DOFs position + VecCoord meshPointsXf; + + /// Link to be set to the topology container in the component graph. + SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; + +protected: + PatchTestMovementProjectiveConstraint(); + + virtual ~PatchTestMovementProjectiveConstraint(); + +public: + //Add or clear constraints + void clearConstraints(); + void addConstraint(Index index); + void removeConstraint(Index index); + + /// -- Constraint interface + void init() override; + + /// Cancel the possible forces + void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; + /// Cancel the possible velocities + void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; + /// Apply the computed movements to the border mesh points between beginConstraintTime and endConstraintTime + void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; + // Implement projectMatrix for assembled solver of compliant + void projectMatrix( sofa::linearalgebra::BaseMatrix* /*M*/, unsigned /*offset*/ ) override; + + void projectJacobianMatrix(const core::MechanicalParams* /*mparams*/, DataMatrixDeriv& /* cData */) override + { + msg_error() <<"projectJacobianMatrix not implemented"; + } + + /// Compute the theoretical final positions + void getFinalPositions (VecCoord& finalPos, DataVecCoord& xData); + + /// Draw the constrained points (= border mesh points) + void draw(const core::visual::VisualParams* vparams) override; + +protected: + + void projectResponseImpl(VecDeriv& dx); + +private: + + /// Find the corners of the grid mesh + void findCornerPoints(); + + /// Compute the displacement of each mesh point by linear interpolation with the displacement of corner points + void computeInterpolatedDisplacement (int pointIndice,const DataVecCoord& xData, Deriv& displacement); + + /// Initialize initial positions + void initializeInitialPositions (const SetIndexArray & indices, DataVecCoord& xData, VecCoord& x0); + + /// Initialize final positions + void initializeFinalPositions (const SetIndexArray & indices, DataVecCoord& xData, VecCoord& x0 , VecCoord& xf); +}; + + +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PATCHTESTMOVEMENTPROJECTIVECONSTRAINT_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PatchTestMovementProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PatchTestMovementProjectiveConstraint; +#endif + + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementProjectiveConstraint.inl new file mode 100644 index 00000000000..b93be91ea5c --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementProjectiveConstraint.inl @@ -0,0 +1,449 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +template +PatchTestMovementProjectiveConstraint::PatchTestMovementProjectiveConstraint() + : core::behavior::ProjectiveConstraintSet(nullptr) + , data(new PatchTestMovementProjectiveConstraintInternalData) + , d_meshIndices( initData(&d_meshIndices,"meshIndices","Indices of the mesh") ) + , d_indices( initData(&d_indices,"indices","Indices of the constrained points") ) + , d_beginConstraintTime( initData(&d_beginConstraintTime,"beginConstraintTime","Begin time of the bilinear constraint") ) + , d_endConstraintTime( initData(&d_endConstraintTime,"endConstraintTime","End time of the bilinear constraint") ) + , d_constrainedPoints( initData(&d_constrainedPoints,"constrainedPoints","Coordinates of the constrained points") ) + , d_cornerMovements( initData(&d_cornerMovements,"cornerMovements","movements of the corners of the grid") ) + , d_cornerPoints( initData(&d_cornerPoints,"cornerPoints","corner points for computing constraint") ) + , d_drawConstrainedPoints( initData(&d_drawConstrainedPoints,"drawConstrainedPoints","draw constrained points") ) + , l_topology(initLink("topology", "link to the topology container")) +{ + if(!d_beginConstraintTime.isSet()) + d_beginConstraintTime = 0; + if(!d_endConstraintTime.isSet()) + d_endConstraintTime = 20; +} + + + +template +PatchTestMovementProjectiveConstraint::~PatchTestMovementProjectiveConstraint() +{ + +} + +template +void PatchTestMovementProjectiveConstraint::clearConstraints() +{ + d_indices.beginEdit()->clear(); + d_indices.endEdit(); +} + +template +void PatchTestMovementProjectiveConstraint::addConstraint(Index index) +{ + d_indices.beginEdit()->push_back(index); + d_indices.endEdit(); +} + +template +void PatchTestMovementProjectiveConstraint::removeConstraint(Index index) +{ + sofa::type::removeValue(*d_indices.beginEdit(),index); + d_indices.endEdit(); +} + +// -- Constraint interface + + +template +void PatchTestMovementProjectiveConstraint::init() +{ + this->core::behavior::ProjectiveConstraintSet::init(); + + if (l_topology.empty()) + { + msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; + l_topology.set(this->getContext()->getMeshTopologyLink()); + } + + if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) + { + msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; + + // Initialize topological changes support + d_indices.createTopologyHandler(_topology); + } + else + { + msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; + } + + const SetIndexArray & indices = d_indices.getValue(); + + const Index maxIndex=this->mstate->getSize(); + for (unsigned int i=0; i= maxIndex) + { + msg_error() <<"Index " << index << " not valid!"; + removeConstraint(index); + } + } + + // Find the 4 corners of the grid topology + this->findCornerPoints(); +} + +template +void PatchTestMovementProjectiveConstraint::findCornerPoints() +{ + Coord corner0, corner1, corner2, corner3,corner4,corner5,corner6,corner7; + // Write accessor + helper::WriteAccessor< Data > cornerPositions = d_cornerPoints; + helper::WriteAccessor< Data > constrainedPoints = d_constrainedPoints; + bool isMeshin3D = false; + + if (!constrainedPoints.empty()) + { + const Coord& point = constrainedPoints[0]; + + // Search if the constrained points are in the same plane + for(Size i = 0; i < constrainedPoints.size() ; i++) + { + if(CoordSize > 2 && constrainedPoints[i][2]!=point[2]) + { + isMeshin3D = true; + } + } + } + + if(constrainedPoints.size() > 0) + { + corner0 = constrainedPoints[0]; + corner1 = constrainedPoints[0]; + corner2 = constrainedPoints[0]; + corner3 = constrainedPoints[0]; + corner4 = constrainedPoints[0]; + corner5 = constrainedPoints[0]; + corner6 = constrainedPoints[0]; + corner7 = constrainedPoints[0]; + + for (size_t i = 0; i < constrainedPoints.size() ; i++) + { + if(constrainedPoints[i][0] < corner0[0] || constrainedPoints[i][1] < corner0[1] || ( CoordSize>2 && constrainedPoints[i][2] < corner0[2] ) ) + { + corner0 = constrainedPoints[i]; + } + + if(constrainedPoints[i][0] > corner2[0] || constrainedPoints[i][1] > corner2[1] || ( CoordSize>2 && constrainedPoints[i][2] < corner2[2] ) ) + { + corner2 = constrainedPoints[i]; + } + + if(constrainedPoints[i][1] < corner1[1] || constrainedPoints[i][0] > corner1[0] || ( CoordSize>2 && constrainedPoints[i][2] < corner1[2] )) + { + corner1 = constrainedPoints[i]; + } + + if(constrainedPoints[i][0] < corner3[0] || constrainedPoints[i][1] > corner3[1] || ( CoordSize>2 && constrainedPoints[i][2] < corner3[2] )) + { + corner3 = constrainedPoints[i]; + } + + if(isMeshin3D && (constrainedPoints[i][0] < corner4[0] || constrainedPoints[i][1] < corner4[1] || (CoordSize>2 && constrainedPoints[i][2] > corner0[2] )) ) + { + corner4 = constrainedPoints[i]; + } + + if(isMeshin3D && (constrainedPoints[i][0] > corner6[0] || constrainedPoints[i][1] > corner6[1] || (CoordSize>2 && constrainedPoints[i][2] > corner2[2] )) ) + { + corner6 = constrainedPoints[i]; + } + + if(isMeshin3D && (constrainedPoints[i][1] < corner5[1] || constrainedPoints[i][0] > corner5[0] || (CoordSize>2 && constrainedPoints[i][2] > corner5[2] )) ) + { + corner5 = constrainedPoints[i]; + } + + else if(isMeshin3D && (constrainedPoints[i][0] < corner7[0] || constrainedPoints[i][1] > corner7[1] || (CoordSize>2 && constrainedPoints[i][2] > corner7[2] )) ) + { + corner7 = constrainedPoints[i]; + } + } + + cornerPositions.push_back(corner0); + cornerPositions.push_back(corner1); + cornerPositions.push_back(corner2); + cornerPositions.push_back(corner3); + + // 3D + if(isMeshin3D) + { + cornerPositions.push_back(corner4); + cornerPositions.push_back(corner5); + cornerPositions.push_back(corner6); + cornerPositions.push_back(corner7); + } + } +} + +template +void PatchTestMovementProjectiveConstraint::projectResponseImpl(VecDeriv& dx) +{ + const SetIndexArray & indices = d_indices.getValue(); + for (size_t i = 0; i< indices.size(); ++i) + { + dx[indices[i]]=Deriv(); + } +} + +template +void PatchTestMovementProjectiveConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) +{ + SOFA_UNUSED(mparams); + helper::WriteAccessor res = resData; + projectResponseImpl(res.wref()); +} + +template +void PatchTestMovementProjectiveConstraint::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) +{ + SOFA_UNUSED(mparams); + helper::WriteAccessor res = vData; + projectResponseImpl(res.wref()); +} + +template +void PatchTestMovementProjectiveConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) +{ + const sofa::simulation::Node::SPtr root = down_cast( this->getContext()->getRootContext() ); + helper::WriteAccessor x = xData; + const SetIndexArray & indices = d_indices.getValue(); + + // Time + double beginTime = d_beginConstraintTime.getValue(); + double endTime = d_endConstraintTime.getValue(); + double totalTime = endTime - beginTime; + + //initialize initial mesh Dofs positions, if it's not done + if(meshPointsX0.size()==0) + this->initializeInitialPositions(d_meshIndices.getValue(),xData,meshPointsX0); + + //initialize final mesh Dofs positions, if it's not done + if(meshPointsXf.size()==0) + this->initializeFinalPositions(d_meshIndices.getValue(),xData, meshPointsX0, meshPointsXf); + + //initialize initial constrained Dofs positions, if it's not done + if(x0.size() == 0) + this->initializeInitialPositions(indices,xData,x0); + + //initialize final constrained Dofs positions, if it's not done + if (xf.size() == 0) + this->initializeFinalPositions(indices,xData,x0,xf); + + // Update the intermediate Dofs positions computed by linear interpolation + double time = root->getTime(); + if( time > beginTime && time <= endTime && totalTime > 0) + { + for (size_t i = 0; i< indices.size(); ++i) + { + x[indices[i]] = ((xf[indices[i]]-x0[indices[i]])*time + (x0[indices[i]]*endTime - xf[indices[i]]*beginTime))/totalTime; + } + } + else if (time > endTime) + { + for (size_t i = 0; i< indices.size(); ++i) + { + x[indices[i]] = xf[indices[i]]; + } + } +} + +template +void PatchTestMovementProjectiveConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) +{ + // clears the rows and columns associated with constrained particles + const unsigned blockSize = DataTypes::deriv_total_size; + + for (const auto id : d_indices.getValue()) + { + M->clearRowsCols( offset + id * blockSize, offset + (id+1) * blockSize ); + } + +} + +template +void PatchTestMovementProjectiveConstraint::getFinalPositions( VecCoord& finalPos,DataVecCoord& xData) +{ + // Indices of mesh points + const SetIndexArray & meshIndices = d_meshIndices.getValue(); + + // Initialize final positions + if(meshPointsXf.size()==0) + {this->initializeFinalPositions(meshIndices,xData,meshPointsX0,meshPointsXf);} + + // Set final positions + finalPos.resize(meshIndices.size()); + for (size_t i=0; i < meshIndices.size() ; ++i) + { + finalPos[meshIndices[i]] = meshPointsXf[meshIndices[i]]; + } +} + +template +void PatchTestMovementProjectiveConstraint::initializeInitialPositions (const SetIndexArray & indices, DataVecCoord& xData, VecCoord& x0) +{ + helper::WriteAccessor x = xData; + + x0.resize(x.size()); + for (size_t i=0; i < indices.size() ; ++i) + { + x0[indices[i]] = x[indices[i]]; + } + +} + +template +void PatchTestMovementProjectiveConstraint::initializeFinalPositions (const SetIndexArray & indices, DataVecCoord& xData, VecCoord& x0, VecCoord& xf) +{ + Deriv displacement; + helper::WriteAccessor x = xData; + + xf.resize(x.size()); + + // if the positions were not initialized + if(x0.size() == 0) + this->initializeInitialPositions(indices,xData,x0); + + for (size_t i=0; i < indices.size() ; ++i) + { + this->computeInterpolatedDisplacement(indices[i],xData,displacement); + xf[indices[i]] = x0[indices[i]] + displacement ; + } + +} + +template +void PatchTestMovementProjectiveConstraint::computeInterpolatedDisplacement(int pointIndice,const DataVecCoord& xData, Deriv& displacement) +{ + // For each mesh point compute the associated displacement + + // The 3 barycentric coefficients along x, y and z axis + Real alpha, beta, gamma; + + // Corner points + const VecCoord& cornerPoints = d_cornerPoints.getValue(); + if(cornerPoints.size()==0) + this->findCornerPoints(); + + if(cornerPoints.size() == 4) + { + Coord corner0 = cornerPoints[0]; + Coord corner1 = cornerPoints[1]; + Coord corner3 = cornerPoints[3]; + + // Coord of the point + helper::ReadAccessor x = xData; + Coord point = x[pointIndice]; + + // Compute alpha = barycentric coefficient along the x axis + alpha = fabs(point[0]-corner0[0])/fabs(corner1[0]-corner0[0]); + + // Compute beta = barycentric coefficient along the y axis + beta = fabs(point[1]-corner0[1])/fabs(corner3[1]-corner0[1]); + + // cornerMovements + const VecDeriv& cornerMovements = d_cornerMovements.getValue(); + + // Compute displacement by linear interpolation + displacement = cornerMovements[0]*(1-alpha)*(1-beta) + cornerMovements[1]*alpha*(1-beta)+ cornerMovements[2]*alpha*beta+cornerMovements[3]*(1-alpha)*beta; + } + + else if(cornerPoints.size() == 8) + { + Coord corner0 = cornerPoints[0]; + Coord corner1 = cornerPoints[1]; + Coord corner3 = cornerPoints[3]; + Coord corner4 = cornerPoints[4]; + + // Coord of the point + helper::ReadAccessor x = xData; + Coord point = x[pointIndice]; + + // Compute alpha = barycentric coefficient along the x axis + alpha = fabs(point[0]-corner0[0])/fabs(corner1[0]-corner0[0]); + + // Compute beta = barycentric coefficient along the y axis + beta = fabs(point[1]-corner0[1])/fabs(corner3[1]-corner0[1]); + + // Compute gamma = barycentric coefficient along the z axis + if( CoordSize>2 ) + gamma = fabs(point[2]-corner0[2])/fabs(corner4[2]-corner0[2]); // 3D + else + gamma = 0; // 2D + + // cornerMovements + const VecDeriv& cornerMovements = d_cornerMovements.getValue(); + + // Compute displacement by linear interpolation + displacement = (cornerMovements[0]*(1-alpha)*(1-beta) + cornerMovements[1]*alpha*(1-beta)+ cornerMovements[2]*alpha*beta+cornerMovements[3]*(1-alpha)*beta) * (1-gamma) + + (cornerMovements[4]*(1-alpha)*(1-beta) + cornerMovements[5]*alpha*(1-beta)+ cornerMovements[6]*alpha*beta+cornerMovements[7]*(1-alpha)*beta) * gamma; + } + else + { + msg_info() << "error don't find the corner points" ; + } + +} + +template +void PatchTestMovementProjectiveConstraint::draw(const core::visual::VisualParams* vparams) +{ + const SetIndexArray & indices = d_indices.getValue(); + const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); + type::Vec3 point; + + if(d_drawConstrainedPoints.getValue()) + { + std::vector< type::Vec3 > points; + for (unsigned int index : indices) + { + point = DataTypes::getCPos(x[index]); + points.push_back(point); + } + vparams->drawTool()->drawPoints(points, 10, sofa::type::RGBAColor(1,0.5,0.5,1)); + } +} + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToLineConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PlaneProjectiveConstraint.cpp similarity index 77% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToLineConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PlaneProjectiveConstraint.cpp index 5c701444225..dc33393e99f 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToLineConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PlaneProjectiveConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ProjectToLineConstraint_CPP -#include +#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PlaneProjectiveConstraint_CPP +#include #include namespace sofa::component::constraint::projective @@ -30,13 +30,13 @@ using namespace sofa::defaulttype; using namespace sofa::helper; -int ProjectToLineConstraintClass = core::RegisterObject("Attach given particles to their initial positions") - .add< ProjectToLineConstraint >() - .add< ProjectToLineConstraint >() - +int PlaneProjectiveConstraintClass = core::RegisterObject("Attach given particles to their initial positions") + .add< PlaneProjectiveConstraint >() + .add< PlaneProjectiveConstraint >() ; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToLineConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToLineConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PlaneProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PlaneProjectiveConstraint; } // namespace sofa::component::constraint::projective + diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PlaneProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PlaneProjectiveConstraint.h new file mode 100644 index 00000000000..13a325f7d8c --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PlaneProjectiveConstraint.h @@ -0,0 +1,137 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +/// This class can be overridden if needed for additionnal storage within template specializations. +template +class PlaneProjectiveConstraintInternalData +{ + +}; + +/** Project particles to an affine plane. + @author Francois Faure, 2012 + @todo Optimized versions for planes parallel to the main directions +*/ +template +class PlaneProjectiveConstraint : public core::behavior::ProjectiveConstraintSet +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(PlaneProjectiveConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, DataTypes)); + + using Index = sofa::Index; + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::CPos CPos; + typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; + typedef typename MatrixDeriv::RowType MatrixDerivRowType; + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef Data DataMatrixDeriv; + typedef type::vector Indices; + typedef sofa::core::topology::TopologySubsetIndices IndexSubsetData; + typedef linearalgebra::EigenBaseSparseMatrix BaseSparseMatrix; + typedef linearalgebra::EigenSparseMatrix SparseMatrix; + typedef typename SparseMatrix::Block Block; ///< projection matrix of a particle displacement to the plane + enum {bsize=SparseMatrix::Nin}; ///< size of a block + + SOFA_ATTRIBUTE_REPLACED__TYPEMEMBER(Vector3, sofa::type::Vec3); + +protected: + PlaneProjectiveConstraint(); + + virtual ~PlaneProjectiveConstraint(); + +public: + IndexSubsetData f_indices; ///< the particles to project + Data f_origin; ///< A point in the plane + Data f_normal; ///< The normal to the plane. Will be normalized by init(). + Data f_drawSize; ///< The size of the display of the constrained particles + + /// Link to be set to the topology container in the component graph. + SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; + +protected: + PlaneProjectiveConstraintInternalData* data; + friend class PlaneProjectiveConstraintInternalData; + + +public: + void clearConstraints(); + void addConstraint(Index index); + void removeConstraint(Index index); + + // -- Constraint interface + void init() override; + void reinit() override; + + void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; + void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; + void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; + void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; + + void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + + /** Project the given matrix (Experimental API). + Replace M with PMP, where P is the projection matrix corresponding to the projectResponse method, shifted by the given offset, i.e. P is the identity matrix with a block on the diagonal replaced by the projection matrix. + */ + void projectMatrix( sofa::linearalgebra::BaseMatrix* /*M*/, unsigned /*offset*/ ) override; + + + void draw(const core::visual::VisualParams* vparams) override; + +protected : + + SparseMatrix jacobian; ///< projection matrix in local state + SparseMatrix J; ///< auxiliary variable +}; + + +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PlaneProjectiveConstraint_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PlaneProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PlaneProjectiveConstraint; + +#endif + +} // namespace sofa::component::constraint::projective + diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PlaneProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PlaneProjectiveConstraint.inl new file mode 100644 index 00000000000..9ba0cae1e0d --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PlaneProjectiveConstraint.inl @@ -0,0 +1,276 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +template +PlaneProjectiveConstraint::PlaneProjectiveConstraint() + : core::behavior::ProjectiveConstraintSet(nullptr) + , f_indices( initData(&f_indices,"indices","Indices of the fixed points") ) + , f_origin( initData(&f_origin,CPos(),"origin","A point in the plane")) + , f_normal( initData(&f_normal,CPos(),"normal","Normal vector to the plane")) + , f_drawSize( initData(&f_drawSize,(SReal)0.0,"drawSize","0 -> point based rendering, >0 -> radius of spheres") ) + , l_topology(initLink("topology", "link to the topology container")) + , data(new PlaneProjectiveConstraintInternalData()) +{ + f_indices.beginEdit()->push_back(0); + f_indices.endEdit(); +} + + +template +PlaneProjectiveConstraint::~PlaneProjectiveConstraint() +{ + delete data; +} + +template +void PlaneProjectiveConstraint::clearConstraints() +{ + f_indices.beginEdit()->clear(); + f_indices.endEdit(); +} + +template +void PlaneProjectiveConstraint::addConstraint(Index index) +{ + f_indices.beginEdit()->push_back(index); + f_indices.endEdit(); +} + +template +void PlaneProjectiveConstraint::removeConstraint(Index index) +{ + sofa::type::removeValue(*f_indices.beginEdit(),index); + f_indices.endEdit(); +} + +// -- Constraint interface + + +template +void PlaneProjectiveConstraint::init() +{ + this->core::behavior::ProjectiveConstraintSet::init(); + + if (l_topology.empty()) + { + msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; + l_topology.set(this->getContext()->getMeshTopologyLink()); + } + + if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) + { + msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; + + // Initialize topological changes support + f_indices.createTopologyHandler(_topology); + } + else + { + msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; + } + + const Indices & indices = f_indices.getValue(); + + const Index maxIndex=this->mstate->getSize(); + for (unsigned int i=0; i= maxIndex) + { + msg_error() << "Index " << index << " not valid!"; + removeConstraint(index); + } + } + + reinit(); + +} + +template +void PlaneProjectiveConstraint::reinit() +{ + + // normalize the normal vector + CPos n = f_normal.getValue(); + if( n.norm()==0 ) + n[1]=0; + else n *= 1/n.norm(); + f_normal.setValue(n); + + // create the matrix blocks corresponding to the projection to the plane: I-nn^t or to the identity + Block bProjection; + for(unsigned i=0; imstate->getSize(); + const unsigned blockSize = DataTypes::deriv_total_size; + jacobian.resize( numBlocks*blockSize,numBlocks*blockSize ); + + // fill the jacobian in ascending order + unsigned i=0; + Indices::const_iterator it = tmp.begin(); + while( i +void PlaneProjectiveConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) +{ + J.copy(jacobian, M->colSize(), offset); // projection matrix for an assembled state + BaseSparseMatrix* E = dynamic_cast(M); + assert(E); + E->compressedMatrix = J.compressedMatrix * E->compressedMatrix * J.compressedMatrix; +} + + + +template +void PlaneProjectiveConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) +{ + SOFA_UNUSED(mparams); + + helper::WriteAccessor res ( resData ); + jacobian.mult(res.wref(),res.ref()); +} + +template +void PlaneProjectiveConstraint::projectJacobianMatrix(const core::MechanicalParams* /*mparams*/ , DataMatrixDeriv& /*cData*/) +{ + msg_error() << "projectJacobianMatrix(const core::MechanicalParams*, DataMatrixDeriv& ) is not implemented"; +} + +template +void PlaneProjectiveConstraint::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) +{ + projectResponse(mparams,vData); +} + +template +void PlaneProjectiveConstraint::projectPosition(const core::MechanicalParams* /*mparams*/ , DataVecCoord& xData) +{ + VecCoord& x = *xData.beginEdit(); + + const CPos& n = f_normal.getValue(); + const CPos& o = f_origin.getValue(); + + const Indices& indices = f_indices.getValue(); + for(unsigned i=0; i +void PlaneProjectiveConstraint::applyConstraint(const core::MechanicalParams* /*mparams*/, const sofa::core::behavior::MultiMatrixAccessor* /*matrix*/) +{ + msg_error() << "applyConstraint is not implemented "; +} + +template +void PlaneProjectiveConstraint::applyConstraint(const core::MechanicalParams* /*mparams*/, linearalgebra::BaseVector* /*vector*/, const sofa::core::behavior::MultiMatrixAccessor* /*matrix*/) +{ + msg_error() << "PlaneProjectiveConstraint::applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) is not implemented "; +} + +template +void PlaneProjectiveConstraint::draw(const core::visual::VisualParams* vparams) +{ + if (!vparams->displayFlags().getShowBehaviorModels()) return; + if (!this->isActive()) return; + const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); + + const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); + + const Indices & indices = f_indices.getValue(); + + if( f_drawSize.getValue() == 0) // old classical drawing by points + { + std::vector< sofa::type::Vec3 > points; + sofa::type::Vec3 point; + for (unsigned int index : indices) + { + point = DataTypes::getCPos(x[index]); + points.push_back(point); + } + vparams->drawTool()->drawPoints(points, 10, sofa::type::RGBAColor(1,0.5,0.5,1)); + } + else // new drawing by spheres + { + std::vector< sofa::type::Vec3 > points; + sofa::type::Vec3 point; + + for (unsigned int index : indices) + { + point = DataTypes::getCPos(x[index]); + points.push_back(point); + } + vparams->drawTool()->drawSpheres(points, (float)f_drawSize.getValue(), sofa::type::RGBAColor(1.0f,0.35f,0.35f,1.0f)); + } + + +} + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPointConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PointProjectiveConstraint.cpp similarity index 69% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPointConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PointProjectiveConstraint.cpp index e76a0ffe931..cac90a54160 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPointConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PointProjectiveConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ProjectToPointConstraint_CPP -#include +#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PointProjectiveConstraint_CPP +#include #include #include @@ -32,17 +32,16 @@ using namespace sofa::defaulttype; using namespace sofa::helper; -int ProjectToPointConstraintClass = core::RegisterObject("Project particles to a point") - .add< ProjectToPointConstraint >() - .add< ProjectToPointConstraint >() - .add< ProjectToPointConstraint >() - .add< ProjectToPointConstraint >() - +int PointProjectiveConstraintClass = core::RegisterObject("Project particles to a point") + .add< PointProjectiveConstraint >() + .add< PointProjectiveConstraint >() + .add< PointProjectiveConstraint >() + .add< PointProjectiveConstraint >() ; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToPointConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToPointConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToPointConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToPointConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PointProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PointProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PointProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PointProjectiveConstraint; } // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PointProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PointProjectiveConstraint.h new file mode 100644 index 00000000000..2055e7fe236 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PointProjectiveConstraint.h @@ -0,0 +1,130 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +/// This class can be overridden if needed for additionnal storage within template specializations. +template +class PointProjectiveConstraintInternalData +{ + +}; + +/** Attach given particles to their initial positions. + * Contrary to FixedConstraint, this one stops the particles even if they have a non-null initial velocity. + * @sa FixedConstraint +*/ +template +class PointProjectiveConstraint : public core::behavior::ProjectiveConstraintSet +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(PointProjectiveConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, DataTypes)); + + using Index = sofa::Index; + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; + typedef typename MatrixDeriv::RowType MatrixDerivRowType; + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef Data DataMatrixDeriv; + typedef type::vector SetIndexArray; + typedef sofa::core::topology::TopologySubsetIndices SetIndex; + + SOFA_ATTRIBUTE_REPLACED__TYPEMEMBER(Vector3, sofa::type::Vec3); + +protected: + PointProjectiveConstraint(); + + virtual ~PointProjectiveConstraint(); + +public: + SetIndex f_indices; ///< the indices of the points to project to the target + Data f_point; ///< the target of the projection + Data f_fixAll; ///< to project all the points, rather than those listed in f_indices + Data f_drawSize; ///< 0 -> point based rendering, >0 -> radius of spheres + + /// Link to be set to the topology container in the component graph. + SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; + +protected: + PointProjectiveConstraintInternalData* data; + friend class PointProjectiveConstraintInternalData; + + +public: + void clearConstraints(); + void addConstraint(Index index); + void removeConstraint(Index index); + + // -- Constraint interface + void init() override; + void reinit() override; + + void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; + void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; + void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; + void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; + + void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + + /** Project the given matrix (Experimental API). + Replace M with PMP, where P is the projection matrix corresponding to the projectResponse method, shifted by the given offset, i.e. P is the identity matrix with a block on the diagonal replaced by the projection matrix. + */ + void projectMatrix( sofa::linearalgebra::BaseMatrix* /*M*/, unsigned /*offset*/ ) override; + + + void draw(const core::visual::VisualParams* vparams) override; + + bool fixAllDOFs() const { return f_fixAll.getValue(); } + +protected : + +}; + + +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PointProjectiveConstraint_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PointProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PointProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PointProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PointProjectiveConstraint; +#endif + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PointProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PointProjectiveConstraint.inl new file mode 100644 index 00000000000..b50b5aedd38 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PointProjectiveConstraint.inl @@ -0,0 +1,324 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace sofa::component::constraint::projective +{ + +template +PointProjectiveConstraint::PointProjectiveConstraint() + : core::behavior::ProjectiveConstraintSet(nullptr) + , f_indices( initData(&f_indices,"indices","Indices of the points to project") ) + , f_point( initData(&f_point,"point","Target of the projection") ) + , f_fixAll( initData(&f_fixAll,false,"fixAll","filter all the DOF to implement a fixed object") ) + , f_drawSize( initData(&f_drawSize,(SReal)0.0,"drawSize","0 -> point based rendering, >0 -> radius of spheres") ) + , l_topology(initLink("topology", "link to the topology container")) + , data(new PointProjectiveConstraintInternalData()) +{ + f_indices.beginEdit()->push_back(0); + f_indices.endEdit(); +} + + +template +PointProjectiveConstraint::~PointProjectiveConstraint() +{ + delete data; +} + +template +void PointProjectiveConstraint::clearConstraints() +{ + f_indices.beginEdit()->clear(); + f_indices.endEdit(); +} + +template +void PointProjectiveConstraint::addConstraint(Index index) +{ + f_indices.beginEdit()->push_back(index); + f_indices.endEdit(); +} + +template +void PointProjectiveConstraint::removeConstraint(Index index) +{ + sofa::type::removeValue(*f_indices.beginEdit(),index); + f_indices.endEdit(); +} + +// -- Constraint interface + + +template +void PointProjectiveConstraint::init() +{ + this->core::behavior::ProjectiveConstraintSet::init(); + + if (l_topology.empty()) + { + msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; + l_topology.set(this->getContext()->getMeshTopologyLink()); + } + + if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) + { + msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; + + // Initialize topological changes support + f_indices.createTopologyHandler(_topology); + } + else + { + msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; + } + + const SetIndexArray & indices = f_indices.getValue(); + + std::stringstream sstream; + const Index maxIndex=this->mstate->getSize(); + for (unsigned int i=0; i= maxIndex) + { + sstream << "Index " << index << " not valid!\n"; + removeConstraint(index); + } + } + msg_error_when(!sstream.str().empty()) << sstream.str(); + + reinit(); +} + +template +void PointProjectiveConstraint::reinit() +{ + + // get the indices sorted + SetIndexArray tmp = f_indices.getValue(); + std::sort(tmp.begin(),tmp.end()); +} + +template +void PointProjectiveConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) +{ + const unsigned blockSize = DataTypes::deriv_total_size; + + // clears the rows and columns associated with fixed particles + for (const auto id : f_indices.getValue()) + { + M->clearRowsCols( offset + id * blockSize, offset + (id+1) * blockSize ); + } +} + +template +void PointProjectiveConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) +{ + SOFA_UNUSED(mparams); + + helper::WriteAccessor res ( resData ); + const SetIndexArray & indices = f_indices.getValue(); + if( f_fixAll.getValue() ) + { + // fix everything + typename VecDeriv::iterator it; + for( it = res.begin(); it != res.end(); ++it ) + { + *it = Deriv(); + } + } + else + { + for (SetIndexArray::const_iterator it = indices.begin(); + it != indices.end(); + ++it) + { + res[*it] = Deriv(); + } + } +} + +template +void PointProjectiveConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) +{ + SOFA_UNUSED(mparams); + + helper::WriteAccessor c ( cData ); + + if( f_fixAll.getValue() ) + { + // fix everything + c->clear(); + } + else + { + const SetIndexArray& indices = f_indices.getValue(); + for (SetIndexArray::const_iterator it = indices.begin(); + it != indices.end(); + ++it) + { + c->clearColBlock(*it); + } + } +} + +template +void PointProjectiveConstraint::projectVelocity(const core::MechanicalParams* mparams , DataVecDeriv& vData) +{ + projectResponse(mparams, vData); +} + +template +void PointProjectiveConstraint::projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) +{ + SOFA_UNUSED(mparams); + + helper::WriteAccessor res ( xData ); + const SetIndexArray & indices = f_indices.getValue(); + if( f_fixAll.getValue() ) + { + // fix everything + typename VecCoord::iterator it; + for( it = res.begin(); it != res.end(); ++it ) + { + *it = f_point.getValue(); + } + } + else + { + for (SetIndexArray::const_iterator it = indices.begin(); + it != indices.end(); + ++it) + { + res[*it] = f_point.getValue(); + } + } +} + +template +void PointProjectiveConstraint::applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) +{ + SOFA_UNUSED(mparams); + if(const core::behavior::MultiMatrixAccessor::MatrixRef r = matrix->getMatrix(this->mstate.get())) + { + const unsigned int N = Deriv::size(); + const SetIndexArray & indices = f_indices.getValue(); + + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + // Reset Fixed Row and Col + for (unsigned int c=0; cclearRowCol(r.offset + N * (*it) + c); + // Set Fixed Vertex + for (unsigned int c=0; cset(r.offset + N * (*it) + c, r.offset + N * (*it) + c, 1.0); + } + } +} + +template +void PointProjectiveConstraint::applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) +{ + SOFA_UNUSED(mparams); + const int o = matrix->getGlobalOffset(this->mstate.get()); + if (o >= 0) + { + const unsigned int offset = (unsigned int)o; + const unsigned int N = Deriv::size(); + + const SetIndexArray & indices = f_indices.getValue(); + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + for (unsigned int c=0; cclear(offset + N * (*it) + c); + } + } +} + + + + +template +void PointProjectiveConstraint::draw(const core::visual::VisualParams* vparams) +{ + if (!vparams->displayFlags().getShowBehaviorModels()) return; + if (!this->isActive()) return; + const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); + const SetIndexArray & indices = f_indices.getValue(); + + const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); + + if( f_drawSize.getValue() == 0) // old classical drawing by points + { + std::vector< sofa::type::Vec3 > points; + sofa::type::Vec3 point; + if( f_fixAll.getValue() ) + for (unsigned i=0; idrawTool()->drawPoints(points, 10, sofa::type::RGBAColor(1,0.5,0.5,1)); + } + else // new drawing by spheres + { + std::vector< sofa::type::Vec3 > points; + sofa::type::Vec3 point; + if(f_fixAll.getValue()) + for (unsigned i=0; idrawTool()->drawSpheres(points, (float)f_drawSize.getValue(), sofa::type::RGBAColor(1.0f,0.35f,0.35f,1.0f)); + } + + +} + +} // namespace sofa::component::constraint::projective + + + diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsConstraint.h index d861e5a7a72..f27bc01bb64 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsConstraint.h @@ -20,95 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -/// This class can be overridden if needed for additionnal storage within template specializations. -template -class PositionBasedDynamicsConstraintInternalData -{ -}; - -/** Position-based dynamics as described in [Muller06]: -input: target positions X -output : x(t) <- x(t) + stiffness.( X - x(t) ) - v(t) <- [ x(t) - x(t-1) ] / dt = v(t) + stiffness.( X - x(t) ) /dt - -*/ +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/PositionBasedDynamicsProjectiveConstraint.h") -template -class PositionBasedDynamicsConstraint : public core::behavior::ProjectiveConstraintSet +namespace sofa::component::constraint::projective { -public: - SOFA_CLASS(SOFA_TEMPLATE(PositionBasedDynamicsConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, DataTypes)); - - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::Real Real; - typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; - typedef typename MatrixDeriv::RowType MatrixDerivRowType; - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef Data DataMatrixDeriv; - -protected: - PositionBasedDynamicsConstraintInternalData data; - friend class PositionBasedDynamicsConstraintInternalData; - -public: - Data< Real > stiffness; ///< Blending between current pos and target pos. - Data< VecCoord > position; ///< Target positions. - - Data < VecDeriv > velocity; ///< Velocities. - Data < VecCoord > old_position; ///< Old positions. - - PositionBasedDynamicsConstraint(); - - virtual ~PositionBasedDynamicsConstraint(); - - // -- Constraint interface - void init() override; - void reset() override; - - void projectResponse(const core::MechanicalParams* , DataVecDeriv& ) override {} - void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; - void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; - void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; - - // Handle topological changes - void handleTopologyChange() override; - -protected : - - - -}; - - -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_POSITIONBASEDDYNAMICSCONSTRAINT_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsConstraint; -//extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsConstraint; - -#endif - -} // namespace sofa::component::constraint::projective +template +using PositionBasedDynamicsConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "PositionBasedDynamicsConstraint has been renamed to PositionBasedDynamicsProjectiveConstraint") = PositionBasedDynamicsProjectiveConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsConstraint.inl index 80117815e5d..35018c27864 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsConstraint.inl @@ -21,118 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - - -template -PositionBasedDynamicsConstraint::PositionBasedDynamicsConstraint() - : core::behavior::ProjectiveConstraintSet(nullptr) - , stiffness(initData(&stiffness,(Real)1.0,"stiffness","Blending between current pos and target pos.")) - , position(initData(&position,"position","Target positions.")) - , velocity(initData(&velocity,"velocity","Velocities.")) - , old_position(initData(&old_position,"old_position","Old positions.")) -{ -} - - -// Handle topological changes -template void PositionBasedDynamicsConstraint::handleTopologyChange() -{ - this->reinit(); -} - -template -PositionBasedDynamicsConstraint::~PositionBasedDynamicsConstraint() -{ -} - - -// -- Constraint interface - - -template -void PositionBasedDynamicsConstraint::init() -{ - this->core::behavior::ProjectiveConstraintSet::init(); - if ((int)position.getValue().size() != (int)this->mstate->getSize()) msg_error() << "Invalid target position vector size." ; -} - - -template -void PositionBasedDynamicsConstraint::reset() -{ - this->core::behavior::ProjectiveConstraintSet::reset(); - - helper::WriteAccessor vel ( velocity ); - std::fill(vel.begin(),vel.end(),Deriv()); - - helper::WriteAccessor old_pos ( old_position ); - const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); - old_pos.resize(x.size()); - std::copy(x.begin(),x.end(),old_pos.begin()); -} - - - -template -void PositionBasedDynamicsConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) -{ - SOFA_UNUSED(mparams); - helper::WriteAccessor c ( cData ); -} - - - -template -void PositionBasedDynamicsConstraint::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) -{ - SOFA_UNUSED(mparams); - - helper::WriteAccessor res (vData ); - helper::ReadAccessor vel ( velocity ); - - if (vel.size() != res.size()) { msg_error() << "Invalid target position vector size." ; return; } - std::copy(vel.begin(),vel.end(),res.begin()); -} - -template -void PositionBasedDynamicsConstraint::projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) -{ - SOFA_UNUSED(mparams); - - helper::WriteAccessor res ( xData ); - helper::WriteAccessor vel ( velocity ); - helper::WriteAccessor old_pos ( old_position ); - helper::ReadAccessor tpos = position ; - if (tpos.size() != res.size()) { msg_error() << "Invalid target position vector size." ; return; } - - Real dt = (Real)this->getContext()->getDt(); - if(!dt) return; - Real invdt=(Real)(1./dt); - - vel.resize(res.size()); - - if(old_pos.size() != res.size()) { - old_pos.resize(res.size()); - std::copy(res.begin(),res.end(),old_pos.begin()); - } - - for( size_t i=0; i -void PositionBasedDynamicsConstraint::projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData); - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/PositionBasedDynamicsProjectiveConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsProjectiveConstraint.cpp similarity index 80% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsProjectiveConstraint.cpp index 8861bb04b35..43655dd1df7 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsProjectiveConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_POSITIONBASEDDYNAMICSCONSTRAINT_CPP -#include +#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_POSITIONBASEDDYNAMICSPROJECTIVECONSTRAINT_CPP +#include #include #include @@ -35,30 +35,28 @@ using namespace sofa::defaulttype; using namespace sofa::helper; -int PositionBasedDynamicsConstraintClass = core::RegisterObject("Position-based dynamics") - - .add< PositionBasedDynamicsConstraint >(true) - .add< PositionBasedDynamicsConstraint >() - .add< PositionBasedDynamicsConstraint >() - .add< PositionBasedDynamicsConstraint >() - .add< PositionBasedDynamicsConstraint >() -//.add< PositionBasedDynamicsConstraint >() +int PositionBasedDynamicsProjectiveConstraintClass = core::RegisterObject("Position-based dynamics") + .add< PositionBasedDynamicsProjectiveConstraint >(true) + .add< PositionBasedDynamicsProjectiveConstraint >() + .add< PositionBasedDynamicsProjectiveConstraint >() + .add< PositionBasedDynamicsProjectiveConstraint >() + .add< PositionBasedDynamicsProjectiveConstraint >() ; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsConstraint; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsConstraint; -//template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsProjectiveConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsProjectiveConstraint; +//template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsProjectiveConstraint; // specialization for rigids template <> -void PositionBasedDynamicsConstraint::projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) +void PositionBasedDynamicsProjectiveConstraint::projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) { SOFA_UNUSED(mparams); diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsProjectiveConstraint.h new file mode 100644 index 00000000000..ad225656f55 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsProjectiveConstraint.h @@ -0,0 +1,114 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +/// This class can be overridden if needed for additionnal storage within template specializations. +template +class PositionBasedDynamicsProjectiveConstraintInternalData +{ +}; + +/** Position-based dynamics as described in [Muller06]: +input: target positions X +output : x(t) <- x(t) + stiffness.( X - x(t) ) + v(t) <- [ x(t) - x(t-1) ] / dt = v(t) + stiffness.( X - x(t) ) /dt + +*/ + +template +class PositionBasedDynamicsProjectiveConstraint : public core::behavior::ProjectiveConstraintSet +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(PositionBasedDynamicsProjectiveConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, DataTypes)); + + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::Real Real; + typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; + typedef typename MatrixDeriv::RowType MatrixDerivRowType; + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef Data DataMatrixDeriv; + +protected: + PositionBasedDynamicsProjectiveConstraintInternalData data; + friend class PositionBasedDynamicsProjectiveConstraintInternalData; + +public: + Data< Real > stiffness; ///< Blending between current pos and target pos. + Data< VecCoord > position; ///< Target positions. + + Data < VecDeriv > velocity; ///< Velocities. + Data < VecCoord > old_position; ///< Old positions. + + PositionBasedDynamicsProjectiveConstraint(); + + virtual ~PositionBasedDynamicsProjectiveConstraint(); + + // -- Constraint interface + void init() override; + void reset() override; + + void projectResponse(const core::MechanicalParams* , DataVecDeriv& ) override {} + void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; + void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; + void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; + + // Handle topological changes + void handleTopologyChange() override; + +protected : + + + +}; + + +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_POSITIONBASEDDYNAMICSPROJECTIVECONSTRAINT_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsProjectiveConstraint; +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsProjectiveConstraint; +//extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsProjectiveConstraint; +#endif + + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsProjectiveConstraint.inl new file mode 100644 index 00000000000..473b6ceafa1 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsProjectiveConstraint.inl @@ -0,0 +1,138 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + + +template +PositionBasedDynamicsProjectiveConstraint::PositionBasedDynamicsProjectiveConstraint() + : core::behavior::ProjectiveConstraintSet(nullptr) + , stiffness(initData(&stiffness,(Real)1.0,"stiffness","Blending between current pos and target pos.")) + , position(initData(&position,"position","Target positions.")) + , velocity(initData(&velocity,"velocity","Velocities.")) + , old_position(initData(&old_position,"old_position","Old positions.")) +{ +} + + +// Handle topological changes +template void PositionBasedDynamicsProjectiveConstraint::handleTopologyChange() +{ + this->reinit(); +} + +template +PositionBasedDynamicsProjectiveConstraint::~PositionBasedDynamicsProjectiveConstraint() +{ +} + + +// -- Constraint interface + + +template +void PositionBasedDynamicsProjectiveConstraint::init() +{ + this->core::behavior::ProjectiveConstraintSet::init(); + if ((int)position.getValue().size() != (int)this->mstate->getSize()) msg_error() << "Invalid target position vector size." ; +} + + +template +void PositionBasedDynamicsProjectiveConstraint::reset() +{ + this->core::behavior::ProjectiveConstraintSet::reset(); + + helper::WriteAccessor vel ( velocity ); + std::fill(vel.begin(),vel.end(),Deriv()); + + helper::WriteAccessor old_pos ( old_position ); + const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); + old_pos.resize(x.size()); + std::copy(x.begin(),x.end(),old_pos.begin()); +} + + + +template +void PositionBasedDynamicsProjectiveConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) +{ + SOFA_UNUSED(mparams); + helper::WriteAccessor c ( cData ); +} + + + +template +void PositionBasedDynamicsProjectiveConstraint::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) +{ + SOFA_UNUSED(mparams); + + helper::WriteAccessor res (vData ); + helper::ReadAccessor vel ( velocity ); + + if (vel.size() != res.size()) { msg_error() << "Invalid target position vector size." ; return; } + std::copy(vel.begin(),vel.end(),res.begin()); +} + +template +void PositionBasedDynamicsProjectiveConstraint::projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) +{ + SOFA_UNUSED(mparams); + + helper::WriteAccessor res ( xData ); + helper::WriteAccessor vel ( velocity ); + helper::WriteAccessor old_pos ( old_position ); + helper::ReadAccessor tpos = position ; + if (tpos.size() != res.size()) { msg_error() << "Invalid target position vector size." ; return; } + + Real dt = (Real)this->getContext()->getDt(); + if(!dt) return; + Real invdt=(Real)(1./dt); + + vel.resize(res.size()); + + if(old_pos.size() != res.size()) { + old_pos.resize(res.size()); + std::copy(res.begin(),res.end(),old_pos.begin()); + } + + for( size_t i=0; i +void PositionBasedDynamicsProjectiveConstraint::projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData); + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectDirectionConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectDirectionConstraint.h index 73b8f78525c..53470fae7fd 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectDirectionConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectDirectionConstraint.h @@ -20,115 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -/// This class can be overridden if needed for additionnal storage within template specializations. -template -class ProjectDirectionConstraintInternalData -{ +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/DirectionProjectiveConstraint.h") -}; - -/** Project particles to an affine straight line going through the particle original position. -*/ -template -class ProjectDirectionConstraint : public core::behavior::ProjectiveConstraintSet +namespace sofa::component::constraint::projective { -public: - SOFA_CLASS(SOFA_TEMPLATE(ProjectDirectionConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, DataTypes)); - - using Index = sofa::Index; - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::CPos CPos; - typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; - typedef typename MatrixDeriv::RowType MatrixDerivRowType; - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef Data DataMatrixDeriv; - typedef type::vector Indices; - SOFA_ATTRIBUTE_REPLACED__TYPEMEMBER(Vector3, sofa::type::Vec3); - typedef sofa::core::topology::TopologySubsetIndices IndexSubsetData; - typedef linearalgebra::EigenBaseSparseMatrix BaseSparseMatrix; - typedef linearalgebra::EigenSparseMatrix SparseMatrix; - typedef typename SparseMatrix::Block Block; ///< projection matrix of a particle displacement to the plane - enum {bsize=SparseMatrix::Nin}; ///< size of a block - - -protected: - ProjectDirectionConstraint(); - - virtual ~ProjectDirectionConstraint(); - -public: - IndexSubsetData f_indices; ///< the particles to project - Data f_drawSize; ///< The size of the square used to display the constrained particles - Data f_direction; ///< The direction of the line. Will be normalized by init() - - /// Link to be set to the topology container in the component graph. - SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; - -protected: - ProjectDirectionConstraintInternalData* data; - friend class ProjectDirectionConstraintInternalData; - - type::vector m_origin; - - -public: - void clearConstraints(); - void addConstraint(Index index); - void removeConstraint(Index index); - - // -- Constraint interface - void init() override; - void reinit() override; - - void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; - void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; - void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; - void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; - - void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - - /// Project the given matrix (Experimental API, see the spec in sofa::core::behavior::BaseProjectiveConstraintSet). - void projectMatrix( sofa::linearalgebra::BaseMatrix* /*M*/, unsigned /*offset*/ ) override; - - - void draw(const core::visual::VisualParams* vparams) override; - -protected : - - SparseMatrix jacobian; ///< projection matrix in local state - SparseMatrix J; ///< auxiliary variable -}; - - -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ProjectDirectionConstraint_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectDirectionConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectDirectionConstraint; - -#endif - -} // namespace sofa::component::constraint::projective +template +using ProjectDirectionConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "ProjectDirectionConstraint has been renamed to DirectionProjectiveConstraint") = DirectionProjectiveConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectDirectionConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectDirectionConstraint.inl index 1d63aa29002..8f9d63e5751 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectDirectionConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectDirectionConstraint.inl @@ -21,257 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include +#include - -namespace sofa::component::constraint::projective -{ - -template -ProjectDirectionConstraint::ProjectDirectionConstraint() - : core::behavior::ProjectiveConstraintSet(nullptr) - , f_indices( initData(&f_indices,"indices","Indices of the fixed points") ) - , f_drawSize( initData(&f_drawSize,(SReal)0.0,"drawSize","0 -> point based rendering, >0 -> radius of spheres") ) - , f_direction( initData(&f_direction,CPos(),"direction","Direction of the line")) - , l_topology(initLink("topology", "link to the topology container")) - , data(new ProjectDirectionConstraintInternalData()) -{ - f_indices.beginEdit()->push_back(0); - f_indices.endEdit(); -} - - -template -ProjectDirectionConstraint::~ProjectDirectionConstraint() -{ - delete data; -} - -template -void ProjectDirectionConstraint::clearConstraints() -{ - f_indices.beginEdit()->clear(); - f_indices.endEdit(); -} - -template -void ProjectDirectionConstraint::addConstraint(Index index) -{ - f_indices.beginEdit()->push_back(index); - f_indices.endEdit(); -} - -template -void ProjectDirectionConstraint::removeConstraint(Index index) -{ - sofa::type::removeValue(*f_indices.beginEdit(),index); - f_indices.endEdit(); -} - -// -- Constraint interface - - -template -void ProjectDirectionConstraint::init() -{ - this->core::behavior::ProjectiveConstraintSet::init(); - - if (l_topology.empty()) - { - msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; - l_topology.set(this->getContext()->getMeshTopologyLink()); - } - - - if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) - { - msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; - - // Initialize topological changes support - f_indices.createTopologyHandler(_topology); - } - else - { - msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; - } - - const Indices & indices = f_indices.getValue(); - - const Index maxIndex=this->mstate->getSize(); - for (unsigned int i=0; i= maxIndex) - { - msg_error() << "Index " << index << " not valid!"; - removeConstraint(index); - } - } - - reinit(); -} - -template -void ProjectDirectionConstraint::reinit() -{ - // normalize the normal vector - CPos n = f_direction.getValue(); - if( n.norm()==0 ) - n[1]=0; - else n *= 1/n.norm(); - f_direction.setValue(n); - - // create the matrix blocks corresponding to the projection to the line: nn^t or to the identity - Block bProjection; - for(unsigned i=0; imstate->getSize(); - const unsigned blockSize = DataTypes::deriv_total_size; - jacobian.resize( numBlocks*blockSize,numBlocks*blockSize ); - - // fill the jacobian in ascending order - Indices::const_iterator it = tmp.begin(); - unsigned i = 0; - while( i < numBlocks ) - { - if( it != tmp.end() && i==*it ) // constrained particle: set diagonal to projection block, and the cursor to the next constraint - { - jacobian.insertBackBlock(i,i,bProjection); - ++it; - } - else // unconstrained particle: set diagonal to identity block - { - jacobian.insertBackBlock(i,i,Block::Identity()); - } - i++; - } - jacobian.compress(); - - const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); - const Indices &indices = f_indices.getValue(); - for (const auto id : indices) - { - m_origin.push_back(DataTypes::getCPos(x[id])); - } - -} - -template -void ProjectDirectionConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) -{ - J.copy(jacobian, M->colSize(), offset); // projection matrix for an assembled state - BaseSparseMatrix* E = dynamic_cast(M); - assert(E); - E->compressedMatrix = J.compressedMatrix * E->compressedMatrix * J.compressedMatrix; -} - - - -template -void ProjectDirectionConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) -{ - SOFA_UNUSED(mparams); - - helper::WriteAccessor res ( resData ); - jacobian.mult(res.wref(),res.ref()); -} - -template -void ProjectDirectionConstraint::projectJacobianMatrix(const core::MechanicalParams* /*mparams*/ , DataMatrixDeriv& /*cData*/) -{ - msg_error() << "projectJacobianMatrix(const core::MechanicalParams*, DataMatrixDeriv& ) is not implemented"; -} - -template -void ProjectDirectionConstraint::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) -{ - projectResponse(mparams,vData); -} - -template -void ProjectDirectionConstraint::projectPosition(const core::MechanicalParams* /*mparams*/ , DataVecCoord& xData) -{ - VecCoord& x = *xData.beginEdit(); - - const CPos& n = f_direction.getValue(); - - const Indices& indices = f_indices.getValue(); - for(unsigned i=0; i -void ProjectDirectionConstraint::applyConstraint(const core::MechanicalParams* /*mparams*/, const sofa::core::behavior::MultiMatrixAccessor* /*matrix*/) -{ - msg_error() << "applyConstraint is not implemented"; -} - -template -void ProjectDirectionConstraint::applyConstraint(const core::MechanicalParams* /*mparams*/, linearalgebra::BaseVector* /*vector*/, const sofa::core::behavior::MultiMatrixAccessor* /*matrix*/) -{ - dmsg_error() << "ProjectDirectionConstraint::applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) is not implemented"; -} - - - - -template -void ProjectDirectionConstraint::draw(const core::visual::VisualParams* vparams) -{ - if (!vparams->displayFlags().getShowBehaviorModels()) return; - if (!this->isActive()) return; - const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); - - const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); - - const Indices & indices = f_indices.getValue(); - - if( f_drawSize.getValue() == 0) // old classical drawing by points - { - std::vector< sofa::type::Vec3 > points; - sofa::type::Vec3 point; - for (unsigned int index : indices) - { - point = DataTypes::getCPos(x[index]); - points.push_back(point); - } - vparams->drawTool()->drawPoints(points, 10, sofa::type::RGBAColor(1,0.5,0.5,1)); - } - else // new drawing by spheres - { - std::vector< sofa::type::Vec3 > points; - sofa::type::Vec3 point; - for (unsigned int index : indices) - { - point = DataTypes::getCPos(x[index]); - points.push_back(point); - } - vparams->drawTool()->drawSpheres(points, (float)f_drawSize.getValue(), sofa::type::RGBAColor(1.0f,0.35f,0.35f,1.0f)); - } - - -} - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/DirectionProjectiveConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToLineConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToLineConstraint.h index 9e30c5687d7..1824578181a 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToLineConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToLineConstraint.h @@ -20,119 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -/// This class can be overridden if needed for additionnal storage within template specializations. -template -class ProjectToLineConstraintInternalData -{ +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/LineProjectiveConstraint.h") -}; - -/** Project particles to an affine straight line. - @author Francois Faure, 2012 - @todo Optimized versions for lines parallel to the main directions -*/ -template -class ProjectToLineConstraint : public core::behavior::ProjectiveConstraintSet +namespace sofa::component::constraint::projective { -public: - SOFA_CLASS(SOFA_TEMPLATE(ProjectToLineConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, DataTypes)); - - using Index = sofa::Index; - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::CPos CPos; - typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; - typedef typename MatrixDeriv::RowType MatrixDerivRowType; - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef Data DataMatrixDeriv; - SOFA_ATTRIBUTE_REPLACED__TYPEMEMBER(Vector3, sofa::type::Vec3); - typedef type::vector Indices; - typedef sofa::core::topology::TopologySubsetIndices IndexSubsetData; - typedef linearalgebra::EigenBaseSparseMatrix BaseSparseMatrix; - typedef linearalgebra::EigenSparseMatrix SparseMatrix; - typedef typename SparseMatrix::Block Block; ///< projection matrix of a particle displacement to the plane - enum {bsize=SparseMatrix::Nin}; ///< size of a block - - -protected: - ProjectToLineConstraint(); - - virtual ~ProjectToLineConstraint(); - -public: - IndexSubsetData f_indices; ///< the particles to project - Data f_drawSize; ///< The size of the square used to display the constrained particles - Data f_origin; ///< A point on the line - Data f_direction; ///< The direction of the line. Will be normalized by init() - - /// Link to be set to the topology container in the component graph. - SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; - -protected: - ProjectToLineConstraintInternalData* data; - friend class ProjectToLineConstraintInternalData; - - -public: - void clearConstraints(); - void addConstraint(Index index); - void removeConstraint(Index index); - - // -- Constraint interface - void init() override; - void reinit() override; - - void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; - void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; - void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; - void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; - - void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - - /// Project the given matrix (Experimental API, see the spec in sofa::core::behavior::BaseProjectiveConstraintSet). - void projectMatrix( sofa::linearalgebra::BaseMatrix* /*M*/, unsigned /*offset*/ ) override; - - - void draw(const core::visual::VisualParams* vparams) override; - -protected : - - SparseMatrix jacobian; ///< projection matrix in local state - SparseMatrix J; ///< auxiliary variable - - /// Resize/update Jacobian matrix according to the linked mechanical state and the direction - void updateJacobian(); - -}; - - -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ProjectToLineConstraint_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToLineConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToLineConstraint; - -#endif - -} // namespace sofa::component::constraint::projective +template +using ProjectToLineConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "ProjectToLineConstraint has been renamed to LineProjectiveConstraint") = LineProjectiveConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToLineConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToLineConstraint.inl index 7abe1ce1c5e..3b15b549d19 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToLineConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToLineConstraint.inl @@ -21,266 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -template -ProjectToLineConstraint::ProjectToLineConstraint() - : core::behavior::ProjectiveConstraintSet(nullptr) - , f_indices( initData(&f_indices,"indices","Indices of the fixed points") ) - , f_drawSize( initData(&f_drawSize,(SReal)0.0,"drawSize","0 -> point based rendering, >0 -> radius of spheres") ) - , f_origin( initData(&f_origin,CPos(),"origin","A point in the line")) - , f_direction( initData(&f_direction,CPos(),"direction","Direction of the line")) - , l_topology(initLink("topology", "link to the topology container")) - , data(new ProjectToLineConstraintInternalData()) -{ - f_indices.beginEdit()->push_back(0); - f_indices.endEdit(); -} - - -template -ProjectToLineConstraint::~ProjectToLineConstraint() -{ - delete data; -} - -template -void ProjectToLineConstraint::clearConstraints() -{ - f_indices.beginEdit()->clear(); - f_indices.endEdit(); -} - -template -void ProjectToLineConstraint::addConstraint(Index index) -{ - f_indices.beginEdit()->push_back(index); - f_indices.endEdit(); -} - -template -void ProjectToLineConstraint::removeConstraint(Index index) -{ - sofa::type::removeValue(*f_indices.beginEdit(),index); - f_indices.endEdit(); -} - -// -- Constraint interface - - -template -void ProjectToLineConstraint::init() -{ - this->core::behavior::ProjectiveConstraintSet::init(); - - if (l_topology.empty()) - { - msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; - l_topology.set(this->getContext()->getMeshTopologyLink()); - } - - if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) - { - msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; - - // Initialize topological changes support - f_indices.createTopologyHandler(_topology); - } - else - { - msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; - } - - const Indices & indices = f_indices.getValue(); - - const Index maxIndex=this->mstate->getSize(); - for (unsigned int i=0; i= maxIndex) - { - msg_error() << "Index " << index << " not valid!"; - removeConstraint(index); - } - } - - updateJacobian(); -} - -template -void ProjectToLineConstraint::reinit() -{ - updateJacobian(); -} - -template -void ProjectToLineConstraint::updateJacobian() -{ - // normalize the normal vector - CPos n = f_direction.getValue(); - if( n.norm()==0 ) - n[0]=1; // arbritary normal vector - else n *= 1/n.norm(); - f_direction.setValue(n); - - // create the matrix blocks corresponding to the projection to the line: nn^t or to the identity - Block bProjection; - for(unsigned i=0; imstate->getSize(); - const unsigned blockSize = DataTypes::deriv_total_size; - jacobian.resize( numBlocks*blockSize,numBlocks*blockSize ); - - // fill the jacobian in ascending order - Indices::const_iterator it = tmp.begin(); - unsigned i = 0; - while( i < numBlocks ) // (FF) do not stop after the last constrained particle, for the remainder of the diagonal would be null, while it must be identity. - { - if( it!=tmp.end() && i==*it ) // constrained particle: set diagonal to projection block, and the cursor to the next constraint - { - jacobian.insertBackBlock(i,i,bProjection); - ++it; - } - else // unconstrained particle: set diagonal to identity block - { - jacobian.insertBackBlock(i,i,Block::Identity()); - } - i++; - } - jacobian.compress(); -} - -template -void ProjectToLineConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) -{ - J.copy(jacobian, M->colSize(), offset); // projection matrix for an assembled state - BaseSparseMatrix* E = dynamic_cast(M); - assert(E); - E->compressedMatrix = J.compressedMatrix * E->compressedMatrix * J.compressedMatrix; -} - - - -template -void ProjectToLineConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) -{ - SOFA_UNUSED(mparams); - - helper::WriteAccessor res(resData); - - using Size = decltype(jacobian.colSize()); - if( (jacobian.colSize() / Size(DataTypes::deriv_total_size)) != Size(res.size())) - { - updateJacobian(); - } - - jacobian.mult(res.wref(),res.ref()); -} - -template -void ProjectToLineConstraint::projectJacobianMatrix(const core::MechanicalParams* /*mparams*/ , DataMatrixDeriv& /*cData*/) -{ - msg_error() << "projectJacobianMatrix(const core::MechanicalParams*, DataMatrixDeriv& ) is not implemented"; -} - -template -void ProjectToLineConstraint::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) -{ - projectResponse(mparams,vData); -} - -template -void ProjectToLineConstraint::projectPosition(const core::MechanicalParams* /*mparams*/ , DataVecCoord& xData) -{ - VecCoord& x = *xData.beginEdit(); - - const CPos& n = f_direction.getValue(); - const CPos& o = f_origin.getValue(); - - const Indices& indices = f_indices.getValue(); - for(unsigned i=0; i -void ProjectToLineConstraint::applyConstraint(const core::MechanicalParams* /*mparams*/, const sofa::core::behavior::MultiMatrixAccessor* /*matrix*/) -{ - msg_error() << "applyConstraint is not implemented "; -} - -template -void ProjectToLineConstraint::applyConstraint(const core::MechanicalParams* /*mparams*/, linearalgebra::BaseVector* /*vector*/, const sofa::core::behavior::MultiMatrixAccessor* /*matrix*/) -{ - msg_error() << "ProjectToLineConstraint::applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) is not implemented "; -} - - - - -template -void ProjectToLineConstraint::draw(const core::visual::VisualParams* vparams) -{ - if (!vparams->displayFlags().getShowBehaviorModels()) return; - if (!this->isActive()) return; - const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); - - const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); - - const Indices & indices = f_indices.getValue(); - - if( f_drawSize.getValue() == 0) // old classical drawing by points - { - std::vector< sofa::type::Vec3 > points; - sofa::type::Vec3 point; - - for (Indices::const_iterator it = indices.begin(); - it != indices.end(); - ++it) - { - point = DataTypes::getCPos(x[*it]); - points.push_back(point); - } - vparams->drawTool()->drawPoints(points, 10, sofa::type::RGBAColor(1,0.5,0.5,1)); - } - else // new drawing by spheres - { - std::vector< sofa::type::Vec3 > points; - sofa::type::Vec3 point; - for (unsigned int index : indices) - { - point = DataTypes::getCPos(x[index]); - points.push_back(point); - } - vparams->drawTool()->drawSpheres(points, (float)f_drawSize.getValue(), sofa::type::RGBAColor(1.0f,0.35f,0.35f,1.0f)); - } - - -} - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/LineProjectiveConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPlaneConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPlaneConstraint.h index 925bf007d65..d7fb513705e 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPlaneConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPlaneConstraint.h @@ -20,118 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -/// This class can be overridden if needed for additionnal storage within template specializations. -template -class ProjectToPlaneConstraintInternalData -{ +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/PlaneProjectiveConstraint.h") -}; - -/** Project particles to an affine plane. - @author Francois Faure, 2012 - @todo Optimized versions for planes parallel to the main directions -*/ -template -class ProjectToPlaneConstraint : public core::behavior::ProjectiveConstraintSet +namespace sofa::component::constraint::projective { -public: - SOFA_CLASS(SOFA_TEMPLATE(ProjectToPlaneConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, DataTypes)); - - using Index = sofa::Index; - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::CPos CPos; - typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; - typedef typename MatrixDeriv::RowType MatrixDerivRowType; - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef Data DataMatrixDeriv; - typedef type::vector Indices; - typedef sofa::core::topology::TopologySubsetIndices IndexSubsetData; - typedef linearalgebra::EigenBaseSparseMatrix BaseSparseMatrix; - typedef linearalgebra::EigenSparseMatrix SparseMatrix; - typedef typename SparseMatrix::Block Block; ///< projection matrix of a particle displacement to the plane - enum {bsize=SparseMatrix::Nin}; ///< size of a block - - SOFA_ATTRIBUTE_REPLACED__TYPEMEMBER(Vector3, sofa::type::Vec3); - -protected: - ProjectToPlaneConstraint(); - - virtual ~ProjectToPlaneConstraint(); - -public: - IndexSubsetData f_indices; ///< the particles to project - Data f_origin; ///< A point in the plane - Data f_normal; ///< The normal to the plane. Will be normalized by init(). - Data f_drawSize; ///< The size of the display of the constrained particles - - /// Link to be set to the topology container in the component graph. - SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; - -protected: - ProjectToPlaneConstraintInternalData* data; - friend class ProjectToPlaneConstraintInternalData; - - -public: - void clearConstraints(); - void addConstraint(Index index); - void removeConstraint(Index index); - - // -- Constraint interface - void init() override; - void reinit() override; - - void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; - void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; - void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; - void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; - - void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - - /** Project the given matrix (Experimental API). - Replace M with PMP, where P is the projection matrix corresponding to the projectResponse method, shifted by the given offset, i.e. P is the identity matrix with a block on the diagonal replaced by the projection matrix. - */ - void projectMatrix( sofa::linearalgebra::BaseMatrix* /*M*/, unsigned /*offset*/ ) override; - - - void draw(const core::visual::VisualParams* vparams) override; - -protected : - - SparseMatrix jacobian; ///< projection matrix in local state - SparseMatrix J; ///< auxiliary variable -}; - - -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ProjectToPlaneConstraint_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToPlaneConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToPlaneConstraint; - -#endif - -} // namespace sofa::component::constraint::projective - +template +using ProjectToPlaneConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "ProjectToPlaneConstraint has been renamed to PlaneProjectiveConstraint") = PlaneProjectiveConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPlaneConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPlaneConstraint.inl index 6e7fd9be4f2..b003eab4b41 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPlaneConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPlaneConstraint.inl @@ -21,256 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -template -ProjectToPlaneConstraint::ProjectToPlaneConstraint() - : core::behavior::ProjectiveConstraintSet(nullptr) - , f_indices( initData(&f_indices,"indices","Indices of the fixed points") ) - , f_origin( initData(&f_origin,CPos(),"origin","A point in the plane")) - , f_normal( initData(&f_normal,CPos(),"normal","Normal vector to the plane")) - , f_drawSize( initData(&f_drawSize,(SReal)0.0,"drawSize","0 -> point based rendering, >0 -> radius of spheres") ) - , l_topology(initLink("topology", "link to the topology container")) - , data(new ProjectToPlaneConstraintInternalData()) -{ - f_indices.beginEdit()->push_back(0); - f_indices.endEdit(); -} - - -template -ProjectToPlaneConstraint::~ProjectToPlaneConstraint() -{ - delete data; -} - -template -void ProjectToPlaneConstraint::clearConstraints() -{ - f_indices.beginEdit()->clear(); - f_indices.endEdit(); -} - -template -void ProjectToPlaneConstraint::addConstraint(Index index) -{ - f_indices.beginEdit()->push_back(index); - f_indices.endEdit(); -} - -template -void ProjectToPlaneConstraint::removeConstraint(Index index) -{ - sofa::type::removeValue(*f_indices.beginEdit(),index); - f_indices.endEdit(); -} - -// -- Constraint interface - - -template -void ProjectToPlaneConstraint::init() -{ - this->core::behavior::ProjectiveConstraintSet::init(); - - if (l_topology.empty()) - { - msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; - l_topology.set(this->getContext()->getMeshTopologyLink()); - } - - if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) - { - msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; - - // Initialize topological changes support - f_indices.createTopologyHandler(_topology); - } - else - { - msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; - } - - const Indices & indices = f_indices.getValue(); - - const Index maxIndex=this->mstate->getSize(); - for (unsigned int i=0; i= maxIndex) - { - msg_error() << "Index " << index << " not valid!"; - removeConstraint(index); - } - } - - reinit(); - -} - -template -void ProjectToPlaneConstraint::reinit() -{ - - // normalize the normal vector - CPos n = f_normal.getValue(); - if( n.norm()==0 ) - n[1]=0; - else n *= 1/n.norm(); - f_normal.setValue(n); - - // create the matrix blocks corresponding to the projection to the plane: I-nn^t or to the identity - Block bProjection; - for(unsigned i=0; imstate->getSize(); - const unsigned blockSize = DataTypes::deriv_total_size; - jacobian.resize( numBlocks*blockSize,numBlocks*blockSize ); - - // fill the jacobian in ascending order - unsigned i=0; - Indices::const_iterator it = tmp.begin(); - while( i -void ProjectToPlaneConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) -{ - J.copy(jacobian, M->colSize(), offset); // projection matrix for an assembled state - BaseSparseMatrix* E = dynamic_cast(M); - assert(E); - E->compressedMatrix = J.compressedMatrix * E->compressedMatrix * J.compressedMatrix; -} - - - -template -void ProjectToPlaneConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) -{ - SOFA_UNUSED(mparams); - - helper::WriteAccessor res ( resData ); - jacobian.mult(res.wref(),res.ref()); -} - -template -void ProjectToPlaneConstraint::projectJacobianMatrix(const core::MechanicalParams* /*mparams*/ , DataMatrixDeriv& /*cData*/) -{ - msg_error() << "projectJacobianMatrix(const core::MechanicalParams*, DataMatrixDeriv& ) is not implemented"; -} - -template -void ProjectToPlaneConstraint::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) -{ - projectResponse(mparams,vData); -} - -template -void ProjectToPlaneConstraint::projectPosition(const core::MechanicalParams* /*mparams*/ , DataVecCoord& xData) -{ - VecCoord& x = *xData.beginEdit(); - - const CPos& n = f_normal.getValue(); - const CPos& o = f_origin.getValue(); - - const Indices& indices = f_indices.getValue(); - for(unsigned i=0; i -void ProjectToPlaneConstraint::applyConstraint(const core::MechanicalParams* /*mparams*/, const sofa::core::behavior::MultiMatrixAccessor* /*matrix*/) -{ - msg_error() << "applyConstraint is not implemented "; -} - -template -void ProjectToPlaneConstraint::applyConstraint(const core::MechanicalParams* /*mparams*/, linearalgebra::BaseVector* /*vector*/, const sofa::core::behavior::MultiMatrixAccessor* /*matrix*/) -{ - msg_error() << "ProjectToPlaneConstraint::applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) is not implemented "; -} - -template -void ProjectToPlaneConstraint::draw(const core::visual::VisualParams* vparams) -{ - if (!vparams->displayFlags().getShowBehaviorModels()) return; - if (!this->isActive()) return; - const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); - - const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); - - const Indices & indices = f_indices.getValue(); - - if( f_drawSize.getValue() == 0) // old classical drawing by points - { - std::vector< sofa::type::Vec3 > points; - sofa::type::Vec3 point; - for (unsigned int index : indices) - { - point = DataTypes::getCPos(x[index]); - points.push_back(point); - } - vparams->drawTool()->drawPoints(points, 10, sofa::type::RGBAColor(1,0.5,0.5,1)); - } - else // new drawing by spheres - { - std::vector< sofa::type::Vec3 > points; - sofa::type::Vec3 point; - - for (unsigned int index : indices) - { - point = DataTypes::getCPos(x[index]); - points.push_back(point); - } - vparams->drawTool()->drawSpheres(points, (float)f_drawSize.getValue(), sofa::type::RGBAColor(1.0f,0.35f,0.35f,1.0f)); - } - - -} - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/PlaneProjectiveConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPointConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPointConstraint.h index 91a50f2b7c0..c5902f37823 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPointConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPointConstraint.h @@ -20,112 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -/// This class can be overridden if needed for additionnal storage within template specializations. -template -class ProjectToPointConstraintInternalData -{ +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/PointProjectiveConstraint.h") -}; - -/** Attach given particles to their initial positions. - * Contrary to FixedConstraint, this one stops the particles even if they have a non-null initial velocity. - * @sa FixedConstraint -*/ -template -class ProjectToPointConstraint : public core::behavior::ProjectiveConstraintSet +namespace sofa::component::constraint::projective { -public: - SOFA_CLASS(SOFA_TEMPLATE(ProjectToPointConstraint,DataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, DataTypes)); - - using Index = sofa::Index; - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; - typedef typename MatrixDeriv::RowType MatrixDerivRowType; - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef Data DataMatrixDeriv; - typedef type::vector SetIndexArray; - typedef sofa::core::topology::TopologySubsetIndices SetIndex; - - SOFA_ATTRIBUTE_REPLACED__TYPEMEMBER(Vector3, sofa::type::Vec3); - -protected: - ProjectToPointConstraint(); - - virtual ~ProjectToPointConstraint(); - -public: - SetIndex f_indices; ///< the indices of the points to project to the target - Data f_point; ///< the target of the projection - Data f_fixAll; ///< to project all the points, rather than those listed in f_indices - Data f_drawSize; ///< 0 -> point based rendering, >0 -> radius of spheres - - /// Link to be set to the topology container in the component graph. - SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; - -protected: - ProjectToPointConstraintInternalData* data; - friend class ProjectToPointConstraintInternalData; - - -public: - void clearConstraints(); - void addConstraint(Index index); - void removeConstraint(Index index); - - // -- Constraint interface - void init() override; - void reinit() override; - - void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; - void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData) override; - void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) override; - void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; - - void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - - /** Project the given matrix (Experimental API). - Replace M with PMP, where P is the projection matrix corresponding to the projectResponse method, shifted by the given offset, i.e. P is the identity matrix with a block on the diagonal replaced by the projection matrix. - */ - void projectMatrix( sofa::linearalgebra::BaseMatrix* /*M*/, unsigned /*offset*/ ) override; - - - void draw(const core::visual::VisualParams* vparams) override; - - bool fixAllDOFs() const { return f_fixAll.getValue(); } - -protected : - -}; - - -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ProjectToPointConstraint_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToPointConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToPointConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToPointConstraint; -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToPointConstraint; - -#endif - -} // namespace sofa::component::constraint::projective +template +using ProjectToPointConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "ProjectToPointConstraint has been renamed to PointProjectiveConstraint") = PointProjectiveConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPointConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPointConstraint.inl index 8bfd98db63a..70213c8c05f 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPointConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPointConstraint.inl @@ -21,304 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace sofa::component::constraint::projective -{ - -template -ProjectToPointConstraint::ProjectToPointConstraint() - : core::behavior::ProjectiveConstraintSet(nullptr) - , f_indices( initData(&f_indices,"indices","Indices of the points to project") ) - , f_point( initData(&f_point,"point","Target of the projection") ) - , f_fixAll( initData(&f_fixAll,false,"fixAll","filter all the DOF to implement a fixed object") ) - , f_drawSize( initData(&f_drawSize,(SReal)0.0,"drawSize","0 -> point based rendering, >0 -> radius of spheres") ) - , l_topology(initLink("topology", "link to the topology container")) - , data(new ProjectToPointConstraintInternalData()) -{ - f_indices.beginEdit()->push_back(0); - f_indices.endEdit(); -} - - -template -ProjectToPointConstraint::~ProjectToPointConstraint() -{ - delete data; -} - -template -void ProjectToPointConstraint::clearConstraints() -{ - f_indices.beginEdit()->clear(); - f_indices.endEdit(); -} - -template -void ProjectToPointConstraint::addConstraint(Index index) -{ - f_indices.beginEdit()->push_back(index); - f_indices.endEdit(); -} - -template -void ProjectToPointConstraint::removeConstraint(Index index) -{ - sofa::type::removeValue(*f_indices.beginEdit(),index); - f_indices.endEdit(); -} - -// -- Constraint interface - - -template -void ProjectToPointConstraint::init() -{ - this->core::behavior::ProjectiveConstraintSet::init(); - - if (l_topology.empty()) - { - msg_info() << "link to Topology container should be set to ensure right behavior. First Topology found in current context will be used."; - l_topology.set(this->getContext()->getMeshTopologyLink()); - } - - if (sofa::core::topology::BaseMeshTopology* _topology = l_topology.get()) - { - msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'"; - - // Initialize topological changes support - f_indices.createTopologyHandler(_topology); - } - else - { - msg_info() << "No topology component found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name; - } - - const SetIndexArray & indices = f_indices.getValue(); - - std::stringstream sstream; - const Index maxIndex=this->mstate->getSize(); - for (unsigned int i=0; i= maxIndex) - { - sstream << "Index " << index << " not valid!\n"; - removeConstraint(index); - } - } - msg_error_when(!sstream.str().empty()) << sstream.str(); - - reinit(); -} - -template -void ProjectToPointConstraint::reinit() -{ - - // get the indices sorted - SetIndexArray tmp = f_indices.getValue(); - std::sort(tmp.begin(),tmp.end()); -} - -template -void ProjectToPointConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) -{ - const unsigned blockSize = DataTypes::deriv_total_size; - - // clears the rows and columns associated with fixed particles - for (const auto id : f_indices.getValue()) - { - M->clearRowsCols( offset + id * blockSize, offset + (id+1) * blockSize ); - } -} - -template -void ProjectToPointConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) -{ - SOFA_UNUSED(mparams); - - helper::WriteAccessor res ( resData ); - const SetIndexArray & indices = f_indices.getValue(); - if( f_fixAll.getValue() ) - { - // fix everything - typename VecDeriv::iterator it; - for( it = res.begin(); it != res.end(); ++it ) - { - *it = Deriv(); - } - } - else - { - for (SetIndexArray::const_iterator it = indices.begin(); - it != indices.end(); - ++it) - { - res[*it] = Deriv(); - } - } -} - -template -void ProjectToPointConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) -{ - SOFA_UNUSED(mparams); - - helper::WriteAccessor c ( cData ); - - if( f_fixAll.getValue() ) - { - // fix everything - c->clear(); - } - else - { - const SetIndexArray& indices = f_indices.getValue(); - for (SetIndexArray::const_iterator it = indices.begin(); - it != indices.end(); - ++it) - { - c->clearColBlock(*it); - } - } -} - -template -void ProjectToPointConstraint::projectVelocity(const core::MechanicalParams* mparams , DataVecDeriv& vData) -{ - projectResponse(mparams, vData); -} - -template -void ProjectToPointConstraint::projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData) -{ - SOFA_UNUSED(mparams); - - helper::WriteAccessor res ( xData ); - const SetIndexArray & indices = f_indices.getValue(); - if( f_fixAll.getValue() ) - { - // fix everything - typename VecCoord::iterator it; - for( it = res.begin(); it != res.end(); ++it ) - { - *it = f_point.getValue(); - } - } - else - { - for (SetIndexArray::const_iterator it = indices.begin(); - it != indices.end(); - ++it) - { - res[*it] = f_point.getValue(); - } - } -} - -template -void ProjectToPointConstraint::applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) -{ - SOFA_UNUSED(mparams); - if(const core::behavior::MultiMatrixAccessor::MatrixRef r = matrix->getMatrix(this->mstate.get())) - { - const unsigned int N = Deriv::size(); - const SetIndexArray & indices = f_indices.getValue(); - - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - // Reset Fixed Row and Col - for (unsigned int c=0; cclearRowCol(r.offset + N * (*it) + c); - // Set Fixed Vertex - for (unsigned int c=0; cset(r.offset + N * (*it) + c, r.offset + N * (*it) + c, 1.0); - } - } -} - -template -void ProjectToPointConstraint::applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) -{ - SOFA_UNUSED(mparams); - const int o = matrix->getGlobalOffset(this->mstate.get()); - if (o >= 0) - { - const unsigned int offset = (unsigned int)o; - const unsigned int N = Deriv::size(); - - const SetIndexArray & indices = f_indices.getValue(); - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - for (unsigned int c=0; cclear(offset + N * (*it) + c); - } - } -} - - - - -template -void ProjectToPointConstraint::draw(const core::visual::VisualParams* vparams) -{ - if (!vparams->displayFlags().getShowBehaviorModels()) return; - if (!this->isActive()) return; - const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); - const SetIndexArray & indices = f_indices.getValue(); - - const auto stateLifeCycle = vparams->drawTool()->makeStateLifeCycle(); - - if( f_drawSize.getValue() == 0) // old classical drawing by points - { - std::vector< sofa::type::Vec3 > points; - sofa::type::Vec3 point; - if( f_fixAll.getValue() ) - for (unsigned i=0; idrawTool()->drawPoints(points, 10, sofa::type::RGBAColor(1,0.5,0.5,1)); - } - else // new drawing by spheres - { - std::vector< sofa::type::Vec3 > points; - sofa::type::Vec3 point; - if(f_fixAll.getValue()) - for (unsigned i=0; idrawTool()->drawSpheres(points, (float)f_drawSize.getValue(), sofa::type::RGBAColor(1.0f,0.35f,0.35f,1.0f)); - } - - -} - -} // namespace sofa::component::constraint::projective - - +#include +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/PointProjectiveConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionConstraint.h index e383eee8dad..9a5b8fc1fca 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionConstraint.h @@ -20,229 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -// a joint of the skeletal hierarchy, it participates in the skeletal animation chain and may be animated -template -struct SkeletonJoint; - -// joints index to export in the MechanicalObject (in order to use them for skinning for instance) -typedef int SkeletonBone; - -// impose a specific motion (translation and rotation) for each DOFs of a MechanicalObject -template -class SkeletalMotionConstraint : public core::behavior::ProjectiveConstraintSet -{ -public: - SOFA_CLASS(SOFA_TEMPLATE(SkeletalMotionConstraint,TDataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, TDataTypes)); - typedef TDataTypes DataTypes; - typedef sofa::core::behavior::ProjectiveConstraintSet TProjectiveConstraintSet; - typedef sofa::core::behavior::MechanicalState MechanicalState; - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::Coord Coord; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::Real Real; - typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; - typedef typename MatrixDeriv::RowType MatrixDerivRowType; - typedef Data DataVecCoord; - typedef Data DataVecDeriv; - typedef Data DataMatrixDeriv; - -protected: - SkeletalMotionConstraint(); - - virtual ~SkeletalMotionConstraint(); - -public: - - void init() override; - void reset() override; - - float getAnimationSpeed() const {return animationSpeed.getValue();} - void setAnimationSpeed(float speed) {animationSpeed.setValue(speed);} - - void findKeyTimes(Real ct); - - void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; - void projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& vData) override; - void projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) override; - void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; - - using core::behavior::ProjectiveConstraintSet::applyConstraint; - void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; - - void projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) override; +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/SkeletalMotionProjectiveConstraint.h") - void draw(const core::visual::VisualParams* vparams) override; - - template - void localToGlobal(typename std::enable_if >::value, VecCoord>::type& x); - - void setSkeletalMotion(const type::vector >& skeletonJoints, const type::vector& skeletonBones); - - void addChannel(unsigned int jointIndex , Coord channel, double time); - -protected: - template - void projectResponseT(DataDeriv& dx, - const std::function& clear); - - template - void interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x); - -protected: - // every nodes needed in the animation chain - Data > > skeletonJoints; ///< skeleton joints - // mesh skeleton bones which need to be updated according to the animated nodes, we use them to fill the mechanical object - Data > skeletonBones; ///< skeleton bones - - // control how fast the animation is played since animation time is not simulation time - Data animationSpeed; ///< animation speed - - /// is the projective constraint activated? - Data active; - -private: - /// the key times surrounding the current simulation time (for interpolation) - Real prevT, nextT; - - /// the global position of the bones at time t+dt used for the velocities computation - VecCoord nextPositions; - - /// to know if we found the key times - bool finished; - -}; - -template -struct SkeletonJoint +namespace sofa::component::constraint::projective { - friend class SkeletalMotionConstraint; - - typedef typename DataTypes::Coord Coord; - - SkeletonJoint() - : mParentIndex(-1) - , mChannels() - , mTimes() - , mPreviousMotionTime(0) - , mNextMotionTime(0) - {} - - virtual ~SkeletonJoint(){} - - void addChannel(Coord channel, double time) - { - mChannels.push_back(channel); - mTimes.push_back(time); - } - - inline friend std::ostream& operator << (std::ostream& out, const SkeletonJoint& skeletonJoint) - { - out << "Parent" << " " << skeletonJoint.mParentIndex << " "; - out << "Channels" << " " << skeletonJoint.mChannels.size() << " " << skeletonJoint.mChannels << " "; - out << "Times" << " " << skeletonJoint.mTimes.size() << " " << skeletonJoint.mTimes << " "; - out << "PreviousMotion" << " " << skeletonJoint.mPreviousMotion << " "; - out << "PreviousMotionTime" << " " << skeletonJoint.mPreviousMotionTime << " "; - out << "NextMotion" << " " << skeletonJoint.mNextMotion << " "; - out << "NextMotionTime" << " " << skeletonJoint.mNextMotionTime << " "; - out << "LocalRigid" << " " << skeletonJoint.mLocalRigid; - - return out; - } - - inline friend std::istream& operator >> (std::istream& in, SkeletonJoint& skeletonJoint) - { - std::string tmp; - - in >> tmp >> skeletonJoint.mParentIndex; - - size_t numChannel; - in >> tmp >> numChannel; - skeletonJoint.mChannels.resize(numChannel); - Coord channel; - for(Size i = 0; i < numChannel; ++i) - { - in >> channel; - skeletonJoint.mChannels[i] = channel; - } - - size_t numTime; - in >> tmp >> numTime; - skeletonJoint.mTimes.resize(numTime); - double time; - for(Size i = 0; i < numTime; ++i) - { - in >> time; - skeletonJoint.mTimes[i] = time; - } - - in >> tmp >> skeletonJoint.mPreviousMotion; - in >> tmp >> skeletonJoint.mNextMotion; - in >> tmp >> skeletonJoint.mLocalRigid; - - return in; - } - - // parent joint, set to -1 if root, you must set this value - int mParentIndex; - - // set the joint rest position, you must set this value - void setRestPosition(const Coord& restPosition) - { - mPreviousMotion = restPosition; - mNextMotion = restPosition; - mLocalRigid = restPosition; - } - - // following data are useful for animation only, you must fill those vectors if this joint is animated - - // each channel represents a local transformation at a given time in the animation - type::vector mChannels; - - // times corresponding to each animation channel, the channel mChannels[i] must be played at the time contained in mTimes[i] - type::vector mTimes; - -private: - - // following data are used internally to compute the final joint transformation at a specific time using interpolation - - // previous joint motion - Coord mPreviousMotion; - - // next joint motion - Coord mNextMotion; - - // time position for previous joint motion - double mPreviousMotionTime; - - // time position for next joint motion - double mNextMotionTime; - - // this rigid represent the animated node at a specific time relatively to its parent, it may be an interpolation between two channels - // we need to store the current rigid in order to compute the final world position of its rigid children - Coord mLocalRigid; - - // mCurrentRigid in the world coordinate - Coord mWorldRigid; -}; - -#if defined(WIN32) && !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_SKELETALMOTIONCONSTRAINT_CPP) -extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API SkeletalMotionConstraint; - -#endif - - -} // namespace sofa::component::constraint::projective - +template +using SkeletalMotionConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "SkeletalMotionConstraint has been renamed to SkeletalMotionProjectiveConstraint") = SkeletalMotionProjectiveConstraint; +} \ No newline at end of file diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionConstraint.inl index 47194a6e86f..2682541f635 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionConstraint.inl @@ -21,402 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -template -SkeletalMotionConstraint::SkeletalMotionConstraint() : - sofa::core::behavior::ProjectiveConstraintSet() - , skeletonJoints(initData(&skeletonJoints, "joints", "skeleton joints")) - , skeletonBones(initData(&skeletonBones, "bones", "skeleton bones")) - , animationSpeed(initData(&animationSpeed, 1.0f, "animationSpeed", "animation speed")) - , active(initData(&active, true, "active", "is the constraint active?")) - , finished(false) -{ -} - -template -SkeletalMotionConstraint::~SkeletalMotionConstraint() -{ -} - -template -void SkeletalMotionConstraint::init() -{ - nextPositions.resize(skeletonBones.getValue().size()); - sofa::core::behavior::ProjectiveConstraintSet::init(); -} - -template -void SkeletalMotionConstraint::reset() -{ - sofa::core::behavior::ProjectiveConstraintSet::reset(); -} - -template -void SkeletalMotionConstraint::findKeyTimes(Real ct) -{ - //Note: works only if the times are sorted - - finished = false; - - for(unsigned int i = 0; i < skeletonJoints.getValue().size(); ++i) - { - SkeletonJoint& skeletonJoint = (*skeletonJoints.beginEdit())[i]; - - - if(skeletonJoint.mChannels.empty() || skeletonJoint.mChannels.size() != skeletonJoint.mTimes.size()) - continue; - - for(unsigned int j = 0; j < skeletonJoint.mTimes.size(); ++j) - { - Real keyTime = (Real) skeletonJoint.mTimes[j]; - if(keyTime <= ct) - { - { - skeletonJoint.mPreviousMotionTime = keyTime; - const defaulttype::RigidCoord<3, Real>& motion = skeletonJoint.mChannels[j]; - skeletonJoint.mPreviousMotion = motion; - } - if(prevT < keyTime) - prevT = keyTime; - } - else - { - { - skeletonJoint.mNextMotionTime = keyTime; - const defaulttype::RigidCoord<3, Real>& motion = skeletonJoint.mChannels[j]; - skeletonJoint.mNextMotion = motion; - } - if(nextT > keyTime) - nextT = keyTime; - - finished = true; - break; - } - } - skeletonJoints.endEdit(); - } -} - -template template -void SkeletalMotionConstraint::projectResponseT(DataDeriv& res, - const std::function& clear) -{ - if( !active.getValue() ) return; - - for (unsigned int i = 0; i < res.size(); ++i) - clear(res, i); -} - -template -void SkeletalMotionConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) -{ - SOFA_UNUSED(mparams); - if( !active.getValue() ) return; - - helper::WriteAccessor res = resData; - projectResponseT(res.wref(), [](VecDeriv& res, const unsigned int index) { res[index].clear(); }); -} - -template -void SkeletalMotionConstraint::projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& vData) -{ - if( !active.getValue() ) return; - - helper::WriteAccessor dx = vData; - helper::ReadAccessor x = ((MechanicalState*)this->getContext()->getMechanicalState())->readPositions(); - Real cT = (Real) this->getContext()->getTime() * animationSpeed.getValue(); - Real dt = (Real) this->getContext()->getDt(); - - if(0.0 != cT) - { - findKeyTimes(cT+dt); - if(finished) - { - // compute the position of the bones at cT + dt - this->interpolatePosition(cT+dt, nextPositions); - // compute the velocity using finite difference - for (unsigned i=0; i -void SkeletalMotionConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) -{ - if( !active.getValue() ) return; - - helper::WriteAccessor x = xData; - Real cT = (Real) this->getContext()->getTime() * animationSpeed.getValue(); - - if(0.0 != cT) - { - findKeyTimes(cT); - - // if we found 2 keyTimes, we have to interpolate a velocity (linear interpolation) - interpolatePosition(cT, x.wref()); - } -} - -template -template -void SkeletalMotionConstraint::interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x) -{ - // set the motion to the SkeletonJoint corresponding rigid - - if(finished) - for(unsigned int i = 0; i < skeletonJoints.getValue().size(); ++i) - { - - SkeletonJoint& skeletonJoint = (*skeletonJoints.beginEdit())[i]; - if( skeletonJoint.mPreviousMotionTime != skeletonJoint.mNextMotionTime) - { - Real dt = (Real)((cT - skeletonJoint.mPreviousMotionTime) / (skeletonJoint.mNextMotionTime - skeletonJoint.mPreviousMotionTime)); - - const type::vector >& channels = skeletonJoint.mChannels; - - if(channels.empty()) - continue; - - skeletonJoint.mLocalRigid.getCenter() = skeletonJoint.mPreviousMotion.getCenter() + (skeletonJoint.mNextMotion.getCenter() - skeletonJoint.mPreviousMotion.getCenter()) * dt; - skeletonJoint.mLocalRigid.getOrientation().slerp(skeletonJoint.mPreviousMotion.getOrientation(), skeletonJoint.mNextMotion.getOrientation(), (float) dt, true); - - skeletonJoints.endEdit(); - } - else - { - const type::vector >& channels = skeletonJoint.mChannels; - - if(channels.empty()) - continue; - - skeletonJoint.mLocalRigid.getCenter() = skeletonJoint.mNextMotion.getCenter(); - skeletonJoint.mLocalRigid.getOrientation() = skeletonJoint.mNextMotion.getOrientation(); - - skeletonJoints.endEdit(); - } - } - else - { - for(unsigned int i = 0; i < skeletonJoints.getValue().size(); ++i) - { - SkeletonJoint& skeletonJoint = (*skeletonJoints.beginEdit())[i]; - - const type::vector >& channels = skeletonJoint.mChannels; - - if(channels.empty()) - continue; - - skeletonJoint.mLocalRigid.getCenter() = skeletonJoint.mNextMotion.getCenter(); - skeletonJoint.mLocalRigid.getOrientation() = skeletonJoint.mNextMotion.getOrientation(); - - skeletonJoints.endEdit(); - } - } - - // apply the final transformation from skeletonBones to dofs here - localToGlobal(x); -} - -template -void SkeletalMotionConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) -{ - SOFA_UNUSED(mparams); - if( !active.getValue() ) return; - - helper::WriteAccessor c = cData; - - projectResponseT(c.wref(), [](MatrixDeriv& res, const unsigned int index) { res.clearColBlock(index); }); -} - -template -template -void SkeletalMotionConstraint::localToGlobal(typename std::enable_if >::value, VecCoord>::type& x) -{ - for(unsigned int i = 0; i < skeletonJoints.getValue().size(); ++i) - { - SkeletonJoint& skeletonJoint = (*skeletonJoints.beginEdit())[i]; - - defaulttype::RigidCoord< 3, Real> worldRigid = skeletonJoint.mLocalRigid; - - // break if the parent joint is the root - for(int parentIndex = skeletonJoint.mParentIndex; -1 != parentIndex; parentIndex = skeletonJoints.getValue()[parentIndex].mParentIndex) - { - defaulttype::RigidCoord< 3, Real> parentLocalRigid = skeletonJoints.getValue()[parentIndex].mLocalRigid; - worldRigid = parentLocalRigid.mult(worldRigid); - } - - skeletonJoint.mWorldRigid = worldRigid; - - skeletonJoints.endEdit(); - } - - for(unsigned int i = 0; i < skeletonBones.getValue().size(); ++i) - x[i] = skeletonJoints.getValue()[skeletonBones.getValue()[i]].mWorldRigid; -} - -template -void SkeletalMotionConstraint::setSkeletalMotion(const type::vector >& skeletonJoints, const type::vector& skeletonBones) -{ - this->skeletonJoints.setValue(skeletonJoints); - this->skeletonBones.setValue(skeletonBones); - this->init(); -} - -template -void SkeletalMotionConstraint::addChannel(unsigned int jointIndex , Coord channel, double time) -{ - (*skeletonJoints.beginEdit())[jointIndex].addChannel(channel, time); - skeletonJoints.endEdit(); -} - -// Matrix Integration interface -template -void SkeletalMotionConstraint::applyConstraint(const core::MechanicalParams* /*mparams*/, const sofa::core::behavior::MultiMatrixAccessor* /*matrix*/) -{ - if( !active.getValue() ) return; - - /*const unsigned int N = Deriv::size(); - const SetIndexArray & indices = m_indices.getValue(); - - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - // Reset Fixed Row and Col - for (unsigned int c=0;cclearRowCol(offset + N * (*it) + c); - // Set Fixed Vertex - for (unsigned int c=0;cset(offset + N * (*it) + c, offset + N * (*it) + c, 1.0); - }*/ -} - -template -void SkeletalMotionConstraint::applyConstraint(const core::MechanicalParams* /*mparams*/, linearalgebra::BaseVector* /*vector*/, const sofa::core::behavior::MultiMatrixAccessor* /*matrix*/) -{ - if( !active.getValue() ) return; - - /*const unsigned int N = Deriv::size(); - - const SetIndexArray & indices = m_indices.getValue(); - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - for (unsigned int c=0;cclear(offset + N * (*it) + c); - }*/ -} - -template -void SkeletalMotionConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) -{ - const unsigned blockSize = DataTypes::deriv_total_size; - const unsigned size = this->mstate->getSize(); - for( unsigned i=0; iclearRowsCols( offset + i * blockSize, offset + (i+1) * (blockSize) ); - } -} - -// display the paths the constrained dofs will go through -template -void SkeletalMotionConstraint::draw(const core::visual::VisualParams* vparams) -{ - if( !active.getValue() ) return; - - if (!vparams->displayFlags().getShowBehaviorModels()) - return; - - sofa::type::vector points; - sofa::type::vector linesX; - sofa::type::vector linesY; - sofa::type::vector linesZ; - sofa::type::vector colorFalloff; - - type::Vec3 point; - type::Vec3 line; - - // draw joints (not bones we draw them differently later) - { - for(unsigned int i = 0; i < skeletonJoints.getValue().size(); ++i) - { - defaulttype::RigidCoord< 3, Real> jointWorldRigid = skeletonJoints.getValue()[i].mWorldRigid; - - unsigned int j; - for(j = 0; j < skeletonBones.getValue().size(); ++j) - if((int)i == skeletonBones.getValue()[j]) - break; - - if(skeletonBones.getValue().size() != j) - continue; - - point = DataTypes::getCPos(jointWorldRigid); - points.push_back(point); - - linesX.push_back(point); - line = point + DataTypes::getCRot(jointWorldRigid).rotate(type::Vec3f(0.1f, 0.0f, 0.0f)); - linesX.push_back(line); - - linesY.push_back(point); - line = point + DataTypes::getCRot(jointWorldRigid).rotate(type::Vec3f(0.0f, 0.1f, 0.0f)); - linesY.push_back(line); - - linesZ.push_back(point); - line = point + DataTypes::getCRot(jointWorldRigid).rotate(type::Vec3f(0.0f, 0.0f, 0.1f)); - linesZ.push_back(line); - } - vparams->drawTool()->drawPoints(points, 10, sofa::type::RGBAColor (1.0f , 0.5f , 0.5f , 1.0f)); - vparams->drawTool()->drawLines (linesX, 2, sofa::type::RGBAColor (0.75f, 0.0f , 0.0f , 1.0f)); - vparams->drawTool()->drawLines (linesY, 2, sofa::type::RGBAColor (0.0f , 0.75f, 0.0f , 1.0f)); - vparams->drawTool()->drawLines (linesZ, 2, sofa::type::RGBAColor (0.0f , 0.0f , 0.75f, 1.0f)); - } - - points.clear(); - linesX.clear(); - linesY.clear(); - linesZ.clear(); - - // draw bones now - { - for(unsigned int i = 0; i < skeletonBones.getValue().size(); ++i) - { - defaulttype::RigidCoord< 3, Real> boneWorldRigid = skeletonJoints.getValue()[skeletonBones.getValue()[i]].mWorldRigid; - - point = DataTypes::getCPos(boneWorldRigid); - points.push_back(point); - - linesX.push_back(point); - line = point + DataTypes::getCRot(boneWorldRigid).rotate(type::Vec3f(0.1f, 0.0f, 0.0f)); - linesX.push_back(line); - - linesY.push_back(point); - line = point + DataTypes::getCRot(boneWorldRigid).rotate(type::Vec3f(0.0f, 0.1f, 0.0f)); - linesY.push_back(line); - - linesZ.push_back(point); - line = point + DataTypes::getCRot(boneWorldRigid).rotate(type::Vec3f(0.0f, 0.0f, 0.1f)); - linesZ.push_back(line); - } - vparams->drawTool()->drawPoints(points, 10, sofa::type::RGBAColor (1.0f, 0.5f, 0.5f, 1.0f)); - vparams->drawTool()->drawLines (linesX, 2 , sofa::type::RGBAColor (1.0f, 0.0f, 0.0f, 1.0f)); - vparams->drawTool()->drawLines (linesY, 2 , sofa::type::RGBAColor (0.0f, 1.0f, 0.0f, 1.0f)); - vparams->drawTool()->drawLines (linesZ, 2 , sofa::type::RGBAColor (0.0f, 0.0f, 1.0f, 1.0f)); - } -} - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v24.06", "v25.06", "sofa/component/constraint/projective/SkeletalMotionProjectiveConstraint.inl") diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionProjectiveConstraint.cpp similarity index 83% rename from Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionConstraint.cpp rename to Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionProjectiveConstraint.cpp index e8010c918f6..7116610d74d 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionProjectiveConstraint.cpp @@ -19,8 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_SKELETALMOTIONCONSTRAINT_CPP -#include +#define SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_SKELETALMOTIONPROJECTIVECONSTRAINT_CPP +#include #include #include @@ -28,11 +28,10 @@ namespace sofa::component::constraint::projective { //declaration of the class, for the factory -int SkeletalMotionConstraintClass = core::RegisterObject("animate a skeleton") - .add< SkeletalMotionConstraint >() - +int SkeletalMotionProjectiveConstraintClass = core::RegisterObject("animate a skeleton") + .add< SkeletalMotionProjectiveConstraint >() ; -template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API SkeletalMotionConstraint; +template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API SkeletalMotionProjectiveConstraint; } // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionProjectiveConstraint.h new file mode 100644 index 00000000000..b47595e588e --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionProjectiveConstraint.h @@ -0,0 +1,247 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include + +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +// a joint of the skeletal hierarchy, it participates in the skeletal animation chain and may be animated +template +struct SkeletonJoint; + +// joints index to export in the MechanicalObject (in order to use them for skinning for instance) +typedef int SkeletonBone; + +// impose a specific motion (translation and rotation) for each DOFs of a MechanicalObject +template +class SkeletalMotionProjectiveConstraint : public core::behavior::ProjectiveConstraintSet +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(SkeletalMotionProjectiveConstraint,TDataTypes),SOFA_TEMPLATE(sofa::core::behavior::ProjectiveConstraintSet, TDataTypes)); + typedef TDataTypes DataTypes; + typedef sofa::core::behavior::ProjectiveConstraintSet TProjectiveConstraintSet; + typedef sofa::core::behavior::MechanicalState MechanicalState; + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::Real Real; + typedef typename MatrixDeriv::RowIterator MatrixDerivRowIterator; + typedef typename MatrixDeriv::RowType MatrixDerivRowType; + typedef Data DataVecCoord; + typedef Data DataVecDeriv; + typedef Data DataMatrixDeriv; + +protected: + SkeletalMotionProjectiveConstraint(); + + virtual ~SkeletalMotionProjectiveConstraint(); + +public: + + void init() override; + void reset() override; + + float getAnimationSpeed() const {return animationSpeed.getValue();} + void setAnimationSpeed(float speed) {animationSpeed.setValue(speed);} + + void findKeyTimes(Real ct); + + void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) override; + void projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& vData) override; + void projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) override; + void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) override; + + using core::behavior::ProjectiveConstraintSet::applyConstraint; + void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + + void projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) override; + + void draw(const core::visual::VisualParams* vparams) override; + + template + void localToGlobal(typename std::enable_if >::value, VecCoord>::type& x); + + void setSkeletalMotion(const type::vector >& skeletonJoints, const type::vector& skeletonBones); + + void addChannel(unsigned int jointIndex , Coord channel, double time); + +protected: + template + void projectResponseT(DataDeriv& dx, + const std::function& clear); + + template + void interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x); + +protected: + // every nodes needed in the animation chain + Data > > skeletonJoints; ///< skeleton joints + // mesh skeleton bones which need to be updated according to the animated nodes, we use them to fill the mechanical object + Data > skeletonBones; ///< skeleton bones + + // control how fast the animation is played since animation time is not simulation time + Data animationSpeed; ///< animation speed + + /// is the projective constraint activated? + Data active; + +private: + /// the key times surrounding the current simulation time (for interpolation) + Real prevT, nextT; + + /// the global position of the bones at time t+dt used for the velocities computation + VecCoord nextPositions; + + /// to know if we found the key times + bool finished; + +}; + +template +struct SkeletonJoint +{ + friend class SkeletalMotionProjectiveConstraint; + + typedef typename DataTypes::Coord Coord; + + SkeletonJoint() + : mParentIndex(-1) + , mChannels() + , mTimes() + , mPreviousMotionTime(0) + , mNextMotionTime(0) + {} + + virtual ~SkeletonJoint(){} + + void addChannel(Coord channel, double time) + { + mChannels.push_back(channel); + mTimes.push_back(time); + } + + inline friend std::ostream& operator << (std::ostream& out, const SkeletonJoint& skeletonJoint) + { + out << "Parent" << " " << skeletonJoint.mParentIndex << " "; + out << "Channels" << " " << skeletonJoint.mChannels.size() << " " << skeletonJoint.mChannels << " "; + out << "Times" << " " << skeletonJoint.mTimes.size() << " " << skeletonJoint.mTimes << " "; + out << "PreviousMotion" << " " << skeletonJoint.mPreviousMotion << " "; + out << "PreviousMotionTime" << " " << skeletonJoint.mPreviousMotionTime << " "; + out << "NextMotion" << " " << skeletonJoint.mNextMotion << " "; + out << "NextMotionTime" << " " << skeletonJoint.mNextMotionTime << " "; + out << "LocalRigid" << " " << skeletonJoint.mLocalRigid; + + return out; + } + + inline friend std::istream& operator >> (std::istream& in, SkeletonJoint& skeletonJoint) + { + std::string tmp; + + in >> tmp >> skeletonJoint.mParentIndex; + + size_t numChannel; + in >> tmp >> numChannel; + skeletonJoint.mChannels.resize(numChannel); + Coord channel; + for(Size i = 0; i < numChannel; ++i) + { + in >> channel; + skeletonJoint.mChannels[i] = channel; + } + + size_t numTime; + in >> tmp >> numTime; + skeletonJoint.mTimes.resize(numTime); + double time; + for(Size i = 0; i < numTime; ++i) + { + in >> time; + skeletonJoint.mTimes[i] = time; + } + + in >> tmp >> skeletonJoint.mPreviousMotion; + in >> tmp >> skeletonJoint.mNextMotion; + in >> tmp >> skeletonJoint.mLocalRigid; + + return in; + } + + // parent joint, set to -1 if root, you must set this value + int mParentIndex; + + // set the joint rest position, you must set this value + void setRestPosition(const Coord& restPosition) + { + mPreviousMotion = restPosition; + mNextMotion = restPosition; + mLocalRigid = restPosition; + } + + // following data are useful for animation only, you must fill those vectors if this joint is animated + + // each channel represents a local transformation at a given time in the animation + type::vector mChannels; + + // times corresponding to each animation channel, the channel mChannels[i] must be played at the time contained in mTimes[i] + type::vector mTimes; + +private: + + // following data are used internally to compute the final joint transformation at a specific time using interpolation + + // previous joint motion + Coord mPreviousMotion; + + // next joint motion + Coord mNextMotion; + + // time position for previous joint motion + double mPreviousMotionTime; + + // time position for next joint motion + double mNextMotionTime; + + // this rigid represent the animated node at a specific time relatively to its parent, it may be an interpolation between two channels + // we need to store the current rigid in order to compute the final world position of its rigid children + Coord mLocalRigid; + + // mCurrentRigid in the world coordinate + Coord mWorldRigid; +}; + +#if defined(WIN32) && !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_SKELETALMOTIONPROJECTIVECONSTRAINT_CPP) +extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API SkeletalMotionProjectiveConstraint; + +#endif + +} // namespace sofa::component::constraint::projective + diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionProjectiveConstraint.inl new file mode 100644 index 00000000000..7c06a73fd18 --- /dev/null +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/SkeletalMotionProjectiveConstraint.inl @@ -0,0 +1,422 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sofa::component::constraint::projective +{ + +template +SkeletalMotionProjectiveConstraint::SkeletalMotionProjectiveConstraint() : + sofa::core::behavior::ProjectiveConstraintSet() + , skeletonJoints(initData(&skeletonJoints, "joints", "skeleton joints")) + , skeletonBones(initData(&skeletonBones, "bones", "skeleton bones")) + , animationSpeed(initData(&animationSpeed, 1.0f, "animationSpeed", "animation speed")) + , active(initData(&active, true, "active", "is the constraint active?")) + , finished(false) +{ +} + +template +SkeletalMotionProjectiveConstraint::~SkeletalMotionProjectiveConstraint() +{ +} + +template +void SkeletalMotionProjectiveConstraint::init() +{ + nextPositions.resize(skeletonBones.getValue().size()); + sofa::core::behavior::ProjectiveConstraintSet::init(); +} + +template +void SkeletalMotionProjectiveConstraint::reset() +{ + sofa::core::behavior::ProjectiveConstraintSet::reset(); +} + +template +void SkeletalMotionProjectiveConstraint::findKeyTimes(Real ct) +{ + //Note: works only if the times are sorted + + finished = false; + + for(unsigned int i = 0; i < skeletonJoints.getValue().size(); ++i) + { + SkeletonJoint& skeletonJoint = (*skeletonJoints.beginEdit())[i]; + + + if(skeletonJoint.mChannels.empty() || skeletonJoint.mChannels.size() != skeletonJoint.mTimes.size()) + continue; + + for(unsigned int j = 0; j < skeletonJoint.mTimes.size(); ++j) + { + Real keyTime = (Real) skeletonJoint.mTimes[j]; + if(keyTime <= ct) + { + { + skeletonJoint.mPreviousMotionTime = keyTime; + const defaulttype::RigidCoord<3, Real>& motion = skeletonJoint.mChannels[j]; + skeletonJoint.mPreviousMotion = motion; + } + if(prevT < keyTime) + prevT = keyTime; + } + else + { + { + skeletonJoint.mNextMotionTime = keyTime; + const defaulttype::RigidCoord<3, Real>& motion = skeletonJoint.mChannels[j]; + skeletonJoint.mNextMotion = motion; + } + if(nextT > keyTime) + nextT = keyTime; + + finished = true; + break; + } + } + skeletonJoints.endEdit(); + } +} + +template template +void SkeletalMotionProjectiveConstraint::projectResponseT(DataDeriv& res, + const std::function& clear) +{ + if( !active.getValue() ) return; + + for (unsigned int i = 0; i < res.size(); ++i) + clear(res, i); +} + +template +void SkeletalMotionProjectiveConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) +{ + SOFA_UNUSED(mparams); + if( !active.getValue() ) return; + + helper::WriteAccessor res = resData; + projectResponseT(res.wref(), [](VecDeriv& res, const unsigned int index) { res[index].clear(); }); +} + +template +void SkeletalMotionProjectiveConstraint::projectVelocity(const core::MechanicalParams* /*mparams*/, DataVecDeriv& vData) +{ + if( !active.getValue() ) return; + + helper::WriteAccessor dx = vData; + helper::ReadAccessor x = ((MechanicalState*)this->getContext()->getMechanicalState())->readPositions(); + Real cT = (Real) this->getContext()->getTime() * animationSpeed.getValue(); + Real dt = (Real) this->getContext()->getDt(); + + if(0.0 != cT) + { + findKeyTimes(cT+dt); + if(finished) + { + // compute the position of the bones at cT + dt + this->interpolatePosition(cT+dt, nextPositions); + // compute the velocity using finite difference + for (unsigned i=0; i +void SkeletalMotionProjectiveConstraint::projectPosition(const core::MechanicalParams* /*mparams*/, DataVecCoord& xData) +{ + if( !active.getValue() ) return; + + helper::WriteAccessor x = xData; + Real cT = (Real) this->getContext()->getTime() * animationSpeed.getValue(); + + if(0.0 != cT) + { + findKeyTimes(cT); + + // if we found 2 keyTimes, we have to interpolate a velocity (linear interpolation) + interpolatePosition(cT, x.wref()); + } +} + +template +template +void SkeletalMotionProjectiveConstraint::interpolatePosition(Real cT, typename std::enable_if >::value, VecCoord>::type& x) +{ + // set the motion to the SkeletonJoint corresponding rigid + + if(finished) + for(unsigned int i = 0; i < skeletonJoints.getValue().size(); ++i) + { + + SkeletonJoint& skeletonJoint = (*skeletonJoints.beginEdit())[i]; + if( skeletonJoint.mPreviousMotionTime != skeletonJoint.mNextMotionTime) + { + Real dt = (Real)((cT - skeletonJoint.mPreviousMotionTime) / (skeletonJoint.mNextMotionTime - skeletonJoint.mPreviousMotionTime)); + + const type::vector >& channels = skeletonJoint.mChannels; + + if(channels.empty()) + continue; + + skeletonJoint.mLocalRigid.getCenter() = skeletonJoint.mPreviousMotion.getCenter() + (skeletonJoint.mNextMotion.getCenter() - skeletonJoint.mPreviousMotion.getCenter()) * dt; + skeletonJoint.mLocalRigid.getOrientation().slerp(skeletonJoint.mPreviousMotion.getOrientation(), skeletonJoint.mNextMotion.getOrientation(), (float) dt, true); + + skeletonJoints.endEdit(); + } + else + { + const type::vector >& channels = skeletonJoint.mChannels; + + if(channels.empty()) + continue; + + skeletonJoint.mLocalRigid.getCenter() = skeletonJoint.mNextMotion.getCenter(); + skeletonJoint.mLocalRigid.getOrientation() = skeletonJoint.mNextMotion.getOrientation(); + + skeletonJoints.endEdit(); + } + } + else + { + for(unsigned int i = 0; i < skeletonJoints.getValue().size(); ++i) + { + SkeletonJoint& skeletonJoint = (*skeletonJoints.beginEdit())[i]; + + const type::vector >& channels = skeletonJoint.mChannels; + + if(channels.empty()) + continue; + + skeletonJoint.mLocalRigid.getCenter() = skeletonJoint.mNextMotion.getCenter(); + skeletonJoint.mLocalRigid.getOrientation() = skeletonJoint.mNextMotion.getOrientation(); + + skeletonJoints.endEdit(); + } + } + + // apply the final transformation from skeletonBones to dofs here + localToGlobal(x); +} + +template +void SkeletalMotionProjectiveConstraint::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData) +{ + SOFA_UNUSED(mparams); + if( !active.getValue() ) return; + + helper::WriteAccessor c = cData; + + projectResponseT(c.wref(), [](MatrixDeriv& res, const unsigned int index) { res.clearColBlock(index); }); +} + +template +template +void SkeletalMotionProjectiveConstraint::localToGlobal(typename std::enable_if >::value, VecCoord>::type& x) +{ + for(unsigned int i = 0; i < skeletonJoints.getValue().size(); ++i) + { + SkeletonJoint& skeletonJoint = (*skeletonJoints.beginEdit())[i]; + + defaulttype::RigidCoord< 3, Real> worldRigid = skeletonJoint.mLocalRigid; + + // break if the parent joint is the root + for(int parentIndex = skeletonJoint.mParentIndex; -1 != parentIndex; parentIndex = skeletonJoints.getValue()[parentIndex].mParentIndex) + { + defaulttype::RigidCoord< 3, Real> parentLocalRigid = skeletonJoints.getValue()[parentIndex].mLocalRigid; + worldRigid = parentLocalRigid.mult(worldRigid); + } + + skeletonJoint.mWorldRigid = worldRigid; + + skeletonJoints.endEdit(); + } + + for(unsigned int i = 0; i < skeletonBones.getValue().size(); ++i) + x[i] = skeletonJoints.getValue()[skeletonBones.getValue()[i]].mWorldRigid; +} + +template +void SkeletalMotionProjectiveConstraint::setSkeletalMotion(const type::vector >& skeletonJoints, const type::vector& skeletonBones) +{ + this->skeletonJoints.setValue(skeletonJoints); + this->skeletonBones.setValue(skeletonBones); + this->init(); +} + +template +void SkeletalMotionProjectiveConstraint::addChannel(unsigned int jointIndex , Coord channel, double time) +{ + (*skeletonJoints.beginEdit())[jointIndex].addChannel(channel, time); + skeletonJoints.endEdit(); +} + +// Matrix Integration interface +template +void SkeletalMotionProjectiveConstraint::applyConstraint(const core::MechanicalParams* /*mparams*/, const sofa::core::behavior::MultiMatrixAccessor* /*matrix*/) +{ + if( !active.getValue() ) return; + + /*const unsigned int N = Deriv::size(); + const SetIndexArray & indices = m_indices.getValue(); + + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + // Reset Fixed Row and Col + for (unsigned int c=0;cclearRowCol(offset + N * (*it) + c); + // Set Fixed Vertex + for (unsigned int c=0;cset(offset + N * (*it) + c, offset + N * (*it) + c, 1.0); + }*/ +} + +template +void SkeletalMotionProjectiveConstraint::applyConstraint(const core::MechanicalParams* /*mparams*/, linearalgebra::BaseVector* /*vector*/, const sofa::core::behavior::MultiMatrixAccessor* /*matrix*/) +{ + if( !active.getValue() ) return; + + /*const unsigned int N = Deriv::size(); + + const SetIndexArray & indices = m_indices.getValue(); + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + for (unsigned int c=0;cclear(offset + N * (*it) + c); + }*/ +} + +template +void SkeletalMotionProjectiveConstraint::projectMatrix( sofa::linearalgebra::BaseMatrix* M, unsigned offset ) +{ + const unsigned blockSize = DataTypes::deriv_total_size; + const unsigned size = this->mstate->getSize(); + for( unsigned i=0; iclearRowsCols( offset + i * blockSize, offset + (i+1) * (blockSize) ); + } +} + +// display the paths the constrained dofs will go through +template +void SkeletalMotionProjectiveConstraint::draw(const core::visual::VisualParams* vparams) +{ + if( !active.getValue() ) return; + + if (!vparams->displayFlags().getShowBehaviorModels()) + return; + + sofa::type::vector points; + sofa::type::vector linesX; + sofa::type::vector linesY; + sofa::type::vector linesZ; + sofa::type::vector colorFalloff; + + type::Vec3 point; + type::Vec3 line; + + // draw joints (not bones we draw them differently later) + { + for(unsigned int i = 0; i < skeletonJoints.getValue().size(); ++i) + { + defaulttype::RigidCoord< 3, Real> jointWorldRigid = skeletonJoints.getValue()[i].mWorldRigid; + + unsigned int j; + for(j = 0; j < skeletonBones.getValue().size(); ++j) + if((int)i == skeletonBones.getValue()[j]) + break; + + if(skeletonBones.getValue().size() != j) + continue; + + point = DataTypes::getCPos(jointWorldRigid); + points.push_back(point); + + linesX.push_back(point); + line = point + DataTypes::getCRot(jointWorldRigid).rotate(type::Vec3f(0.1f, 0.0f, 0.0f)); + linesX.push_back(line); + + linesY.push_back(point); + line = point + DataTypes::getCRot(jointWorldRigid).rotate(type::Vec3f(0.0f, 0.1f, 0.0f)); + linesY.push_back(line); + + linesZ.push_back(point); + line = point + DataTypes::getCRot(jointWorldRigid).rotate(type::Vec3f(0.0f, 0.0f, 0.1f)); + linesZ.push_back(line); + } + vparams->drawTool()->drawPoints(points, 10, sofa::type::RGBAColor (1.0f , 0.5f , 0.5f , 1.0f)); + vparams->drawTool()->drawLines (linesX, 2, sofa::type::RGBAColor (0.75f, 0.0f , 0.0f , 1.0f)); + vparams->drawTool()->drawLines (linesY, 2, sofa::type::RGBAColor (0.0f , 0.75f, 0.0f , 1.0f)); + vparams->drawTool()->drawLines (linesZ, 2, sofa::type::RGBAColor (0.0f , 0.0f , 0.75f, 1.0f)); + } + + points.clear(); + linesX.clear(); + linesY.clear(); + linesZ.clear(); + + // draw bones now + { + for(unsigned int i = 0; i < skeletonBones.getValue().size(); ++i) + { + defaulttype::RigidCoord< 3, Real> boneWorldRigid = skeletonJoints.getValue()[skeletonBones.getValue()[i]].mWorldRigid; + + point = DataTypes::getCPos(boneWorldRigid); + points.push_back(point); + + linesX.push_back(point); + line = point + DataTypes::getCRot(boneWorldRigid).rotate(type::Vec3f(0.1f, 0.0f, 0.0f)); + linesX.push_back(line); + + linesY.push_back(point); + line = point + DataTypes::getCRot(boneWorldRigid).rotate(type::Vec3f(0.0f, 0.1f, 0.0f)); + linesY.push_back(line); + + linesZ.push_back(point); + line = point + DataTypes::getCRot(boneWorldRigid).rotate(type::Vec3f(0.0f, 0.0f, 0.1f)); + linesZ.push_back(line); + } + vparams->drawTool()->drawPoints(points, 10, sofa::type::RGBAColor (1.0f, 0.5f, 0.5f, 1.0f)); + vparams->drawTool()->drawLines (linesX, 2 , sofa::type::RGBAColor (1.0f, 0.0f, 0.0f, 1.0f)); + vparams->drawTool()->drawLines (linesY, 2 , sofa::type::RGBAColor (0.0f, 1.0f, 0.0f, 1.0f)); + vparams->drawTool()->drawLines (linesZ, 2 , sofa::type::RGBAColor (0.0f, 0.0f, 1.0f, 1.0f)); + } +} + +} // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/tests/AffineMovementConstraint_test.cpp b/Sofa/Component/Constraint/Projective/tests/AffineMovementProjectiveConstraint_test.cpp similarity index 95% rename from Sofa/Component/Constraint/Projective/tests/AffineMovementConstraint_test.cpp rename to Sofa/Component/Constraint/Projective/tests/AffineMovementProjectiveConstraint_test.cpp index 82379cb5145..a1d845afc32 100644 --- a/Sofa/Component/Constraint/Projective/tests/AffineMovementConstraint_test.cpp +++ b/Sofa/Component/Constraint/Projective/tests/AffineMovementProjectiveConstraint_test.cpp @@ -27,7 +27,7 @@ using sofa::testing::NumericTest; #include #include #include -#include +#include #include #include #include @@ -42,7 +42,7 @@ namespace sofa { namespace { template -struct AffineMovementConstraint_test : public BaseSimulationTest, NumericTest +struct AffineMovementProjectiveConstraint_test : public BaseSimulationTest, NumericTest { typedef _DataTypes DataTypes; typedef typename DataTypes::Coord Coord; @@ -197,9 +197,9 @@ typedef Types< > DataTypes; // the types to instanciate. // Test suite for all the instanciations -TYPED_TEST_SUITE(AffineMovementConstraint_test, DataTypes); +TYPED_TEST_SUITE(AffineMovementProjectiveConstraint_test, DataTypes); // first test case -TYPED_TEST( AffineMovementConstraint_test , testValue ) +TYPED_TEST( AffineMovementProjectiveConstraint_test , testValue ) { EXPECT_MSG_NOEMIT(Error) ; ASSERT_TRUE( this->projectPosition(5e-6,5e-5)); diff --git a/Sofa/Component/Constraint/Projective/tests/CMakeLists.txt b/Sofa/Component/Constraint/Projective/tests/CMakeLists.txt index 042f7537a21..7e271d937b6 100644 --- a/Sofa/Component/Constraint/Projective/tests/CMakeLists.txt +++ b/Sofa/Component/Constraint/Projective/tests/CMakeLists.txt @@ -3,14 +3,14 @@ cmake_minimum_required(VERSION 3.12) project(Sofa.Component.Constraint.Projective_test) set(SOURCE_FILES - AffineMovementConstraint_test.cpp - FixedConstraint_test.cpp - FixedPlaneConstraint_test.cpp - PartialFixedConstraint_test.cpp - ProjectDirectionConstraint_test.cpp - ProjectToLineConstraint_test.cpp - ProjectToPlaneConstraint_test.cpp - ProjectToPointConstraint_test.cpp + AffineMovementProjectiveConstraint_test.cpp + FixedProjectiveConstraint_test.cpp + FixedPlaneProjectiveConstraint_test.cpp + PartialFixedProjectiveConstraint_test.cpp + DirectionProjectiveConstraint_test.cpp + LineProjectiveConstraint_test.cpp + PlaneProjectiveConstraint_test.cpp + PointProjectiveConstraint_test.cpp ) add_executable(${PROJECT_NAME} ${SOURCE_FILES}) diff --git a/Sofa/Component/Constraint/Projective/tests/ProjectDirectionConstraint_test.cpp b/Sofa/Component/Constraint/Projective/tests/DirectionProjectiveConstraint_test.cpp similarity index 92% rename from Sofa/Component/Constraint/Projective/tests/ProjectDirectionConstraint_test.cpp rename to Sofa/Component/Constraint/Projective/tests/DirectionProjectiveConstraint_test.cpp index 3a60bde1807..697184f6f30 100644 --- a/Sofa/Component/Constraint/Projective/tests/ProjectDirectionConstraint_test.cpp +++ b/Sofa/Component/Constraint/Projective/tests/DirectionProjectiveConstraint_test.cpp @@ -27,7 +27,7 @@ using sofa::testing::NumericTest; #include #include #include -#include +#include #include #include #include @@ -41,11 +41,11 @@ using namespace component; using namespace defaulttype; using namespace core::objectmodel; -/** Test suite for ProjectDirectionConstraint. +/** Test suite for DirectionProjectiveConstraint. The test cases are defined in the #Test_Cases member group. */ template -struct ProjectDirectionConstraint_test : public BaseSimulationTest, NumericTest +struct DirectionProjectiveConstraint_test : public BaseSimulationTest, NumericTest { typedef _DataTypes DataTypes; typedef typename DataTypes::VecCoord VecCoord; @@ -54,8 +54,8 @@ struct ProjectDirectionConstraint_test : public BaseSimulationTest, NumericTest< typedef typename DataTypes::Deriv Deriv; typedef typename DataTypes::CPos CPos; typedef typename Coord::value_type Real; - typedef constraint::projective::ProjectDirectionConstraint ProjectDirectionConstraint; - typedef typename ProjectDirectionConstraint::Indices Indices; + typedef constraint::projective::DirectionProjectiveConstraint DirectionProjectiveConstraint; + typedef typename DirectionProjectiveConstraint::Indices Indices; typedef component::topology::container::dynamic::PointSetTopologyContainer PointSetTopologyContainer; typedef statecontainer::MechanicalObject MechanicalObject; @@ -65,7 +65,7 @@ struct ProjectDirectionConstraint_test : public BaseSimulationTest, NumericTest< unsigned numNodes; ///< number of particles used for the test Indices indices; ///< indices of the nodes to project CPos direction; ///< direction to project to - typename ProjectDirectionConstraint::SPtr projection; + typename DirectionProjectiveConstraint::SPtr projection; typename MechanicalObject::SPtr dofs; /// Create the context for the tests. @@ -85,7 +85,7 @@ struct ProjectDirectionConstraint_test : public BaseSimulationTest, NumericTest< root->addObject(dofs); // Project direction constraint - projection = New(); + projection = New(); root->addObject(projection); /// Set the values @@ -236,10 +236,10 @@ typedef Types< > DataTypes; // the types to instanciate. // Test suite for all the instanciations -TYPED_TEST_SUITE(ProjectDirectionConstraint_test, DataTypes); +TYPED_TEST_SUITE(DirectionProjectiveConstraint_test, DataTypes); // first test case -TYPED_TEST( ProjectDirectionConstraint_test , oneConstrainedParticle ) +TYPED_TEST( DirectionProjectiveConstraint_test , oneConstrainedParticle ) { EXPECT_MSG_NOEMIT(Error) ; this->init_oneConstrainedParticle(); @@ -247,7 +247,7 @@ TYPED_TEST( ProjectDirectionConstraint_test , oneConstrainedParticle ) ASSERT_TRUE( this->test_projectVelocity() ); } // second test case -TYPED_TEST( ProjectDirectionConstraint_test , allParticlesConstrained ) +TYPED_TEST( DirectionProjectiveConstraint_test , allParticlesConstrained ) { EXPECT_MSG_NOEMIT(Error) ; this->init_allParticlesConstrained(); diff --git a/Sofa/Component/Constraint/Projective/tests/FixedPlaneConstraint_test.cpp b/Sofa/Component/Constraint/Projective/tests/FixedPlaneProjectiveConstraint_test.cpp similarity index 89% rename from Sofa/Component/Constraint/Projective/tests/FixedPlaneConstraint_test.cpp rename to Sofa/Component/Constraint/Projective/tests/FixedPlaneProjectiveConstraint_test.cpp index b040bfced84..ab521298505 100644 --- a/Sofa/Component/Constraint/Projective/tests/FixedPlaneConstraint_test.cpp +++ b/Sofa/Component/Constraint/Projective/tests/FixedPlaneProjectiveConstraint_test.cpp @@ -23,7 +23,7 @@ #include using sofa::testing::BaseSimulationTest; -#include +#include #include #include #include @@ -46,12 +46,12 @@ void createUniformMass(simulation::Node::SPtr node, component::statecontainer::M } template -struct FixedPlaneConstraint_test : public BaseSimulationTest +struct FixedPlaneProjectiveConstraint_test : public BaseSimulationTest { typedef _DataTypes DataTypes; typedef typename DataTypes::Real Real; - typedef component::constraint::projective::FixedPlaneConstraint FixedPlaneConstraint; + typedef component::constraint::projective::FixedPlaneProjectiveConstraint FixedPlaneProjectiveConstraint; typedef component::mechanicalload::ConstantForceField ForceField; typedef component::statecontainer::MechanicalObject MechanicalObject; @@ -89,7 +89,7 @@ struct FixedPlaneConstraint_test : public BaseSimulationTest typename ForceField::SPtr forceField = addNew(node); forceField->setForce( 0, force ); - typename FixedPlaneConstraint::SPtr constraint = addNew(node); + typename FixedPlaneProjectiveConstraint::SPtr constraint = addNew(node); constraint->d_indices.setValue({0}); if(constraint->d_indices.getValue().empty()) { @@ -134,22 +134,22 @@ typedef Types< > DataTypes; // the types to instanciate. // Test suite for all the instanciations -TYPED_TEST_SUITE(FixedPlaneConstraint_test, DataTypes); +TYPED_TEST_SUITE(FixedPlaneProjectiveConstraint_test, DataTypes); // test cases -TYPED_TEST( FixedPlaneConstraint_test , testContraintExplicit ) +TYPED_TEST( FixedPlaneProjectiveConstraint_test , testContraintExplicit ) { EXPECT_MSG_NOEMIT(Error) ; EXPECT_TRUE( this->test(1e-8, std::string("Explicit")) ); } -TYPED_TEST( FixedPlaneConstraint_test , testConstraintImplicitWithCG ) +TYPED_TEST( FixedPlaneProjectiveConstraint_test , testConstraintImplicitWithCG ) { EXPECT_MSG_NOEMIT(Error) ; EXPECT_TRUE( this->test(1e-8, std::string("Implicit")) ); } -TYPED_TEST( FixedPlaneConstraint_test , testConstraintImplicitWithSparseLDL ) +TYPED_TEST( FixedPlaneProjectiveConstraint_test , testConstraintImplicitWithSparseLDL ) { EXPECT_MSG_NOEMIT(Error) ; EXPECT_TRUE( this->test(1e-8, std::string("Implicit_SparseLDL")) ); diff --git a/Sofa/Component/Constraint/Projective/tests/FixedConstraint_test.cpp b/Sofa/Component/Constraint/Projective/tests/FixedProjectiveConstraint_test.cpp similarity index 92% rename from Sofa/Component/Constraint/Projective/tests/FixedConstraint_test.cpp rename to Sofa/Component/Constraint/Projective/tests/FixedProjectiveConstraint_test.cpp index e755e35fdd6..e717e5d6b82 100644 --- a/Sofa/Component/Constraint/Projective/tests/FixedConstraint_test.cpp +++ b/Sofa/Component/Constraint/Projective/tests/FixedProjectiveConstraint_test.cpp @@ -20,7 +20,7 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#include +#include #include #include #include @@ -49,10 +49,10 @@ void createUniformMass(simulation::Node::SPtr node, component::statecontainer::M } template -struct FixedConstraint_test : public BaseTest +struct FixedProjectiveConstraint_test : public BaseTest { typedef _DataTypes DataTypes; - typedef component::constraint::projective::FixedConstraint FixedConstraint; + typedef component::constraint::projective::FixedProjectiveConstraint FixedProjectiveConstraint; typedef component::mechanicalload::ConstantForceField ForceField; typedef component::statecontainer::MechanicalObject MechanicalObject; @@ -106,7 +106,7 @@ struct FixedConstraint_test : public BaseTest forceField->setForce( 1, force ); /// Let's fix the particle's movement for particle number 1 (the second one). - typename FixedConstraint::SPtr cst = sofa::core::objectmodel::New(); + typename FixedProjectiveConstraint::SPtr cst = sofa::core::objectmodel::New(); cst->findData("indices")->read("1"); node->addObject(cst); @@ -197,7 +197,7 @@ struct FixedConstraint_test : public BaseTest } /// Add fixconstraint - typename FixedConstraint::SPtr cst = sofa::core::objectmodel::New(); + typename FixedProjectiveConstraint::SPtr cst = sofa::core::objectmodel::New(); type::vector indices = { 0, 1, 2 }; cst->d_indices.setValue(indices); node->addObject(cst); @@ -247,27 +247,27 @@ typedef Types< > DataTypes; // the types to instanciate. // Test suite for all the instanciations -TYPED_TEST_SUITE(FixedConstraint_test, DataTypes); +TYPED_TEST_SUITE(FixedProjectiveConstraint_test, DataTypes); // first test case -TYPED_TEST( FixedConstraint_test , testValueImplicitWithCG ) +TYPED_TEST( FixedProjectiveConstraint_test , testValueImplicitWithCG ) { EXPECT_MSG_NOEMIT(Error) ; EXPECT_TRUE( this->test(1e-8,std::string("Implicit")) ); } -TYPED_TEST( FixedConstraint_test , testValueExplicit ) +TYPED_TEST( FixedProjectiveConstraint_test , testValueExplicit ) { EXPECT_MSG_NOEMIT(Error) ; EXPECT_TRUE( this->test(1e-8, std::string("Explicit")) ); } -TYPED_TEST( FixedConstraint_test , testValueImplicitWithSparseLDL ) +TYPED_TEST( FixedProjectiveConstraint_test , testValueImplicitWithSparseLDL ) { EXPECT_MSG_NOEMIT(Error) ; EXPECT_TRUE( this->test(1e-8, std::string("Implicit_SparseLDL")) ); } -TYPED_TEST(FixedConstraint_test, testTopologicalChanges) +TYPED_TEST(FixedProjectiveConstraint_test, testTopologicalChanges) { EXPECT_MSG_NOEMIT(Error); EXPECT_TRUE(this->testTopologicalChanges()); diff --git a/Sofa/Component/Constraint/Projective/tests/ProjectToLineConstraint_test.cpp b/Sofa/Component/Constraint/Projective/tests/LineProjectiveConstraint_test.cpp similarity index 92% rename from Sofa/Component/Constraint/Projective/tests/ProjectToLineConstraint_test.cpp rename to Sofa/Component/Constraint/Projective/tests/LineProjectiveConstraint_test.cpp index 8308103367a..bda02f7bf43 100644 --- a/Sofa/Component/Constraint/Projective/tests/ProjectToLineConstraint_test.cpp +++ b/Sofa/Component/Constraint/Projective/tests/LineProjectiveConstraint_test.cpp @@ -27,7 +27,7 @@ using sofa::testing::NumericTest; #include #include #include -#include +#include #include #include #include @@ -39,11 +39,11 @@ using namespace defaulttype; -/** Test suite for ProjectToLineConstraint. +/** Test suite for LineProjectiveConstraint. The test cases are defined in the #Test_Cases member group. */ template -struct ProjectToLineConstraint_test : public BaseSimulationTest, NumericTest +struct LineProjectiveConstraint_test : public BaseSimulationTest, NumericTest { typedef _DataTypes DataTypes; typedef typename DataTypes::VecCoord VecCoord; @@ -52,8 +52,8 @@ struct ProjectToLineConstraint_test : public BaseSimulationTest, NumericTest ProjectToLineConstraint; - typedef typename ProjectToLineConstraint::Indices Indices; + typedef constraint::projective::LineProjectiveConstraint LineProjectiveConstraint; + typedef typename LineProjectiveConstraint::Indices Indices; typedef component::topology::container::dynamic::PointSetTopologyContainer PointSetTopologyContainer; typedef statecontainer::MechanicalObject MechanicalObject; @@ -64,7 +64,7 @@ struct ProjectToLineConstraint_test : public BaseSimulationTest, NumericTest(); root->addObject(dofs); - projection = core::objectmodel::New(); + projection = core::objectmodel::New(); root->addObject(projection); /// Set the values @@ -221,9 +221,9 @@ typedef Types< > DataTypes; // the types to instanciate. // Test suite for all the instanciations -TYPED_TEST_SUITE(ProjectToLineConstraint_test, DataTypes); +TYPED_TEST_SUITE(LineProjectiveConstraint_test, DataTypes); // first test case -TYPED_TEST( ProjectToLineConstraint_test , oneConstrainedParticle ) +TYPED_TEST( LineProjectiveConstraint_test , oneConstrainedParticle ) { EXPECT_MSG_NOEMIT(Error) ; this->init_oneConstrainedParticle(); @@ -231,7 +231,7 @@ TYPED_TEST( ProjectToLineConstraint_test , oneConstrainedParticle ) ASSERT_TRUE( this->test_projectVelocity() ); } // next test case -TYPED_TEST( ProjectToLineConstraint_test , allParticlesConstrained ) +TYPED_TEST( LineProjectiveConstraint_test , allParticlesConstrained ) { EXPECT_MSG_NOEMIT(Error) ; this->init_allParticlesConstrained(); diff --git a/Sofa/Component/Constraint/Projective/tests/PartialFixedConstraint_test.cpp b/Sofa/Component/Constraint/Projective/tests/PartialFixedProjectiveConstraint_test.cpp similarity index 88% rename from Sofa/Component/Constraint/Projective/tests/PartialFixedConstraint_test.cpp rename to Sofa/Component/Constraint/Projective/tests/PartialFixedProjectiveConstraint_test.cpp index a7b462c0f5e..3ca05c51679 100644 --- a/Sofa/Component/Constraint/Projective/tests/PartialFixedConstraint_test.cpp +++ b/Sofa/Component/Constraint/Projective/tests/PartialFixedProjectiveConstraint_test.cpp @@ -22,7 +22,7 @@ #include using sofa::testing::BaseSimulationTest; -#include +#include #include #include #include @@ -45,12 +45,12 @@ void createUniformMass(simulation::Node::SPtr node, component::statecontainer::M } template -struct PartialFixedConstraint_test : public BaseSimulationTest +struct PartialFixedProjectiveConstraint_test : public BaseSimulationTest { typedef _DataTypes DataTypes; typedef typename DataTypes::Real Real; - typedef component::constraint::projective::PartialFixedConstraint PartialFixedConstraint; + typedef component::constraint::projective::PartialFixedProjectiveConstraint PartialFixedProjectiveConstraint; typedef component::mechanicalload::ConstantForceField ForceField; typedef component::statecontainer::MechanicalObject MechanicalObject; @@ -92,7 +92,7 @@ struct PartialFixedConstraint_test : public BaseSimulationTest typename ForceField::SPtr forceField = addNew(node); forceField->setForce( 0, force ); - typename PartialFixedConstraint::SPtr constraint = addNew(node); + typename PartialFixedProjectiveConstraint::SPtr constraint = addNew(node); // Init simulation sofa::simulation::node::initRoot(root.get()); @@ -134,22 +134,22 @@ typedef Types< > DataTypes; // the types to instanciate. // Test suite for all the instanciations -TYPED_TEST_SUITE(PartialFixedConstraint_test, DataTypes); +TYPED_TEST_SUITE(PartialFixedProjectiveConstraint_test, DataTypes); // test cases -TYPED_TEST( PartialFixedConstraint_test , testContraintExplicit ) +TYPED_TEST( PartialFixedProjectiveConstraint_test , testContraintExplicit ) { EXPECT_MSG_NOEMIT(Error) ; EXPECT_TRUE( this->test(1e-8, std::string("Explicit")) ); } -TYPED_TEST( PartialFixedConstraint_test , testContraintImplicitWithCG ) +TYPED_TEST( PartialFixedProjectiveConstraint_test , testContraintImplicitWithCG ) { EXPECT_MSG_NOEMIT(Error) ; EXPECT_TRUE( this->test(1e-8, std::string("Implicit")) ); } -TYPED_TEST( PartialFixedConstraint_test , testContraintImplicitWithSparseLDL ) +TYPED_TEST( PartialFixedProjectiveConstraint_test , testContraintImplicitWithSparseLDL ) { EXPECT_MSG_NOEMIT(Error) ; EXPECT_TRUE( this->test(1e-8, std::string("Implicit_SparseLDL")) ); diff --git a/Sofa/Component/Constraint/Projective/tests/ProjectToPlaneConstraint_test.cpp b/Sofa/Component/Constraint/Projective/tests/PlaneProjectiveConstraint_test.cpp similarity index 92% rename from Sofa/Component/Constraint/Projective/tests/ProjectToPlaneConstraint_test.cpp rename to Sofa/Component/Constraint/Projective/tests/PlaneProjectiveConstraint_test.cpp index 76c5e46ae25..c09830aed0c 100644 --- a/Sofa/Component/Constraint/Projective/tests/ProjectToPlaneConstraint_test.cpp +++ b/Sofa/Component/Constraint/Projective/tests/PlaneProjectiveConstraint_test.cpp @@ -27,7 +27,7 @@ using sofa::testing::NumericTest; #include #include #include -#include +#include #include #include #include @@ -40,11 +40,11 @@ using namespace defaulttype; -/** Test suite for ProjectToPlaneConstraint. +/** Test suite for PlaneProjectiveConstraint. The test cases are defined in the #Test_Cases member group. */ template -struct ProjectToPlaneConstraint_test : public BaseSimulationTest, NumericTest +struct PlaneProjectiveConstraint_test : public BaseSimulationTest, NumericTest { typedef _DataTypes DataTypes; typedef typename DataTypes::VecCoord VecCoord; @@ -53,8 +53,8 @@ struct ProjectToPlaneConstraint_test : public BaseSimulationTest, NumericTest ProjectToPlaneConstraint; - typedef typename ProjectToPlaneConstraint::Indices Indices; + typedef constraint::projective::PlaneProjectiveConstraint PlaneProjectiveConstraint; + typedef typename PlaneProjectiveConstraint::Indices Indices; typedef component::topology::container::dynamic::PointSetTopologyContainer PointSetTopologyContainer; typedef statecontainer::MechanicalObject MechanicalObject; @@ -65,7 +65,7 @@ struct ProjectToPlaneConstraint_test : public BaseSimulationTest, NumericTest(); root->addObject(dofs); - projection = core::objectmodel::New(); + projection = core::objectmodel::New(); root->addObject(projection); /// Set the values @@ -220,9 +220,9 @@ typedef Types< > DataTypes; // the types to instanciate. // Test suite for all the instanciations -TYPED_TEST_SUITE(ProjectToPlaneConstraint_test, DataTypes); +TYPED_TEST_SUITE(PlaneProjectiveConstraint_test, DataTypes); // first test case -TYPED_TEST( ProjectToPlaneConstraint_test , oneConstrainedParticle ) +TYPED_TEST( PlaneProjectiveConstraint_test , oneConstrainedParticle ) { EXPECT_MSG_NOEMIT(Error) ; this->init_oneConstrainedParticle(); @@ -230,7 +230,7 @@ TYPED_TEST( ProjectToPlaneConstraint_test , oneConstrainedParticle ) ASSERT_TRUE( this->test_projectVelocity() ); } // next test case -TYPED_TEST( ProjectToPlaneConstraint_test , allParticlesConstrained ) +TYPED_TEST( PlaneProjectiveConstraint_test , allParticlesConstrained ) { EXPECT_MSG_NOEMIT(Error) ; this->init_allParticlesConstrained(); diff --git a/Sofa/Component/Constraint/Projective/tests/ProjectToPointConstraint_test.cpp b/Sofa/Component/Constraint/Projective/tests/PointProjectiveConstraint_test.cpp similarity index 92% rename from Sofa/Component/Constraint/Projective/tests/ProjectToPointConstraint_test.cpp rename to Sofa/Component/Constraint/Projective/tests/PointProjectiveConstraint_test.cpp index 1b33c49fe5f..fdcbc6ddfa5 100644 --- a/Sofa/Component/Constraint/Projective/tests/ProjectToPointConstraint_test.cpp +++ b/Sofa/Component/Constraint/Projective/tests/PointProjectiveConstraint_test.cpp @@ -27,7 +27,7 @@ using sofa::testing::NumericTest; #include #include #include -#include +#include #include #include #include @@ -41,11 +41,11 @@ using namespace defaulttype; using sofa::core::objectmodel::New; -/** Test suite for ProjectToPointConstraint. +/** Test suite for PointProjectiveConstraint. The test cases are defined in the #Test_Cases member group. */ template -struct ProjectToPointConstraint_test : public BaseSimulationTest, NumericTest +struct PointProjectiveConstraint_test : public BaseSimulationTest, NumericTest { typedef _DataTypes DataTypes; typedef typename DataTypes::VecCoord VecCoord; @@ -54,8 +54,8 @@ struct ProjectToPointConstraint_test : public BaseSimulationTest, NumericTest ProjectToPointConstraint; - typedef typename ProjectToPointConstraint::SetIndexArray Indices; + typedef constraint::projective::PointProjectiveConstraint PointProjectiveConstraint; + typedef typename PointProjectiveConstraint::SetIndexArray Indices; typedef component::topology::container::dynamic::PointSetTopologyContainer PointSetTopologyContainer; typedef statecontainer::MechanicalObject MechanicalObject; @@ -65,7 +65,7 @@ struct ProjectToPointConstraint_test : public BaseSimulationTest, NumericTestaddObject(dofs); // Project to point constraint - projection = New(); + projection = New(); root->addObject(projection); /// Set the values @@ -224,9 +224,9 @@ typedef Types< > DataTypes; // the types to instanciate. // Test suite for all the instanciations -TYPED_TEST_SUITE(ProjectToPointConstraint_test, DataTypes); +TYPED_TEST_SUITE(PointProjectiveConstraint_test, DataTypes); // first test case -TYPED_TEST( ProjectToPointConstraint_test , oneConstrainedParticle ) +TYPED_TEST( PointProjectiveConstraint_test , oneConstrainedParticle ) { EXPECT_MSG_NOEMIT(Error) ; this->init_oneConstrainedParticle(); @@ -234,7 +234,7 @@ TYPED_TEST( ProjectToPointConstraint_test , oneConstrainedParticle ) ASSERT_TRUE( this->test_projectVelocity() ); } // next test case -TYPED_TEST( ProjectToPointConstraint_test , allParticlesConstrained ) +TYPED_TEST( PointProjectiveConstraint_test , allParticlesConstrained ) { EXPECT_MSG_NOEMIT(Error) ; this->init_allParticlesConstrained(); diff --git a/Sofa/Component/Diffusion/tests/scenes/TetrahedronDiffusionFEMForceField.scn b/Sofa/Component/Diffusion/tests/scenes/TetrahedronDiffusionFEMForceField.scn index b54a164645c..c5a6db9c33b 100644 --- a/Sofa/Component/Diffusion/tests/scenes/TetrahedronDiffusionFEMForceField.scn +++ b/Sofa/Component/Diffusion/tests/scenes/TetrahedronDiffusionFEMForceField.scn @@ -1,6 +1,6 @@ - + @@ -36,8 +36,8 @@ - - + +
diff --git a/Sofa/Component/Mapping/NonLinear/tests/SquareDistanceMapping_test.cpp b/Sofa/Component/Mapping/NonLinear/tests/SquareDistanceMapping_test.cpp index cf5d2724d67..8472a6f1a3c 100644 --- a/Sofa/Component/Mapping/NonLinear/tests/SquareDistanceMapping_test.cpp +++ b/Sofa/Component/Mapping/NonLinear/tests/SquareDistanceMapping_test.cpp @@ -168,7 +168,7 @@ struct SquareDistanceMappingCompare_test : NumericTest {{"position", "@../loader.position"}, {"edges", "@../loader.edges"}, {"name", "topology"}}); simpleapi::createObject(node, "MechanicalObject", {{"name", "defoDOF"}, {"template", "Vec3"}}); simpleapi::createObject(node, "EdgeSetGeometryAlgorithms"); - simpleapi::createObject(node, "FixedConstraint", {{"indices", "0"}}); + simpleapi::createObject(node, "FixedProjectiveConstraint", {{"indices", "0"}}); simpleapi::createObject(node, "DiagonalMass", {{"totalMass", "1e-2"}}); } diff --git a/Sofa/Component/MechanicalLoad/tests/SkeletalMotionConstraint_test.cpp b/Sofa/Component/MechanicalLoad/tests/SkeletalMotionConstraint_test.cpp index eb5c9790beb..f6a846d532b 100644 --- a/Sofa/Component/MechanicalLoad/tests/SkeletalMotionConstraint_test.cpp +++ b/Sofa/Component/MechanicalLoad/tests/SkeletalMotionConstraint_test.cpp @@ -27,7 +27,7 @@ using sofa::testing::NumericTest; #include #include #include -#include +#include #include #include #include @@ -44,7 +44,7 @@ using namespace defaulttype; The test cases are defined in the #Test_Cases member group. */ template -struct SkeletalMotionConstraint_test : public BaseSimulationTest, NumericTest +struct SkeletalMotionProjectiveConstraint_test : public BaseSimulationTest, NumericTest { typedef _DataTypes DataTypes; typedef typename DataTypes::VecCoord VecCoord; @@ -55,7 +55,7 @@ struct SkeletalMotionConstraint_test : public BaseSimulationTest, NumericTest SkeletalMotionConstraint; + typedef constraint::projective::SkeletalMotionProjectiveConstraint SkeletalMotionProjectiveConstraint; typedef constraint::projective::SkeletonJoint SkeletonJoint; typedef statecontainer::MechanicalObject MechanicalObject; @@ -63,7 +63,7 @@ struct SkeletalMotionConstraint_test : public BaseSimulationTest, NumericTest joints; ///< skeletal joint - typename SkeletalMotionConstraint::SPtr projection; + typename SkeletalMotionProjectiveConstraint::SPtr projection; typename MechanicalObject::SPtr dofs; /// Create the context for the tests. @@ -77,7 +77,7 @@ struct SkeletalMotionConstraint_test : public BaseSimulationTest, NumericTest(); root->addObject(dofs); - projection = core::objectmodel::New(); + projection = core::objectmodel::New(); root->addObject(projection); @@ -184,9 +184,9 @@ typedef Types< > DataTypes; // the types to instanciate. // Test suite for all the instanciations -TYPED_TEST_SUITE(SkeletalMotionConstraint_test, DataTypes); +TYPED_TEST_SUITE(SkeletalMotionProjectiveConstraint_test, DataTypes); // first test case -TYPED_TEST( SkeletalMotionConstraint_test , twoConstrainedBones ) +TYPED_TEST( SkeletalMotionProjectiveConstraint_test , twoConstrainedBones ) { EXPECT_MSG_NOEMIT(Error) ; this->init_2bones(); diff --git a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/StaticSolver.cpp b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/StaticSolver.cpp index 04679365b1a..e999ad4621f 100644 --- a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/StaticSolver.cpp +++ b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/StaticSolver.cpp @@ -174,7 +174,7 @@ void StaticSolver::solve(const sofa::core::ExecParams* params, SReal dt, sofa::c // Step 2 Projective constraints // Calls the "projectResponse" method of every BaseProjectiveConstraintSet objects found in the - // current context tree. An example of such constraint set is the FixedConstraint. In this case, + // current context tree. An example of such constraint set is the FixedProjectiveConstraint. In this case, // it will set to 0 every row (i, _) of the right-hand side (force) vector for the ith degree of // freedom. mop.projectResponse(force); @@ -218,7 +218,7 @@ void StaticSolver::solve(const sofa::core::ExecParams* params, SReal dt, sofa::c // B. For LinearSolver using other type of matrices (FullMatrix, SparseMatrix, CompressedRowSparseMatrix), // the "addMBKToMatrix" method is called on each BaseForceField objects and the "applyConstraint" method // is called on every BaseProjectiveConstraintSet objects. An example of such constraint set is the - // FixedConstraint. In this case, it will set to 0 every column (_, i) and row (i, _) of the assembled + // FixedProjectiveConstraint. In this case, it will set to 0 every column (_, i) and row (i, _) of the assembled // matrix for the ith degree of freedom. matrix.setSystemMBKMatrix(MechanicalMatrix::K * -1.0); } diff --git a/Sofa/Component/ODESolver/Backward/tests/EulerImplicitSolverStatic_test.cpp b/Sofa/Component/ODESolver/Backward/tests/EulerImplicitSolverStatic_test.cpp index 226deeb18ca..6e35c3245b1 100644 --- a/Sofa/Component/ODESolver/Backward/tests/EulerImplicitSolverStatic_test.cpp +++ b/Sofa/Component/ODESolver/Backward/tests/EulerImplicitSolverStatic_test.cpp @@ -131,7 +131,7 @@ struct EulerImplicit_test_2_particles_to_equilibrium : public BaseSimulationTest 0.1 // damping ratio ); - simpleapi::createObject(string, "FixedConstraint", { + simpleapi::createObject(string, "FixedProjectiveConstraint", { { "indices", "0"} }); diff --git a/Sofa/Component/ODESolver/Backward/tests/StaticSolver_test.cpp b/Sofa/Component/ODESolver/Backward/tests/StaticSolver_test.cpp index 512f0f2a4fe..b13f1a66af3 100644 --- a/Sofa/Component/ODESolver/Backward/tests/StaticSolver_test.cpp +++ b/Sofa/Component/ODESolver/Backward/tests/StaticSolver_test.cpp @@ -71,7 +71,7 @@ class StaticSolverTest : public sofa::testing::BaseTest }); createObject(root, "BoxROI", {{"name", "top_roi"}, {"box", "-7.5 -7.5 -0.9 7.5 7.5 0.1"}}); - createObject(root, "FixedConstraint", {{"indices", "@top_roi.indices"}}); + createObject(root, "FixedProjectiveConstraint", {{"indices", "@top_roi.indices"}}); createObject(root, "BoxROI", {{"name", "base_roi"}, {"box", "-7.5 -7.5 79.9 7.5 7.5 80.1"}}); createObject(root, "SurfacePressureForceField", {{"pressure", "100"}, {"mainDirection", "0 -1 0"}, {"triangleIndices", "@base_roi.trianglesInROI"}}); diff --git a/Sofa/Component/ODESolver/Backward/tests/scenes/EulerImplicitSpringDynamicTest.xml b/Sofa/Component/ODESolver/Backward/tests/scenes/EulerImplicitSpringDynamicTest.xml index 9d80018d423..6164322ee8d 100644 --- a/Sofa/Component/ODESolver/Backward/tests/scenes/EulerImplicitSpringDynamicTest.xml +++ b/Sofa/Component/ODESolver/Backward/tests/scenes/EulerImplicitSpringDynamicTest.xml @@ -1,6 +1,6 @@ - + @@ -14,7 +14,7 @@ - + diff --git a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp index 7681f7b5fb9..c6804085622 100644 --- a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp +++ b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp @@ -297,7 +297,7 @@ void EulerExplicitSolver::projectResponse(sofa::simulation::common::MechanicalOp SCOPED_TIMER("projectResponse"); // Calls the "projectResponse" method of every BaseProjectiveConstraintSet objects found in the - // current context tree. An example of such constraint set is the FixedConstraint. In this case, + // current context tree. An example of such constraint set is the FixedProjectiveConstraint. In this case, // it will set to 0 every row (i, _) of the input vector for the ith degree of freedom. mop->projectResponse(vecId); } @@ -326,7 +326,7 @@ void EulerExplicitSolver::assembleSystemMatrix(core::behavior::MultiMatrix - + @@ -27,7 +27,7 @@ - + diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/tests/scenes/TetrahedronHyperelasticityFEMForceField_test.scn b/Sofa/Component/SolidMechanics/FEM/HyperElastic/tests/scenes/TetrahedronHyperelasticityFEMForceField_test.scn index 275d2734611..cfcca0d0492 100644 --- a/Sofa/Component/SolidMechanics/FEM/HyperElastic/tests/scenes/TetrahedronHyperelasticityFEMForceField_test.scn +++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/tests/scenes/TetrahedronHyperelasticityFEMForceField_test.scn @@ -1,7 +1,7 @@ - + @@ -24,7 +24,7 @@ - + diff --git a/Sofa/Component/SolidMechanics/simutests/AffinePatch_test.cpp b/Sofa/Component/SolidMechanics/simutests/AffinePatch_test.cpp index 90c87619417..b0779c4062b 100644 --- a/Sofa/Component/SolidMechanics/simutests/AffinePatch_test.cpp +++ b/Sofa/Component/SolidMechanics/simutests/AffinePatch_test.cpp @@ -30,7 +30,7 @@ #include // Including constraint, force and mass -#include +#include #include #include #include @@ -61,7 +61,7 @@ struct AffinePatch_sofa_test : public sofa::testing::BaseSimulationTest, sofa::t typedef typename DataTypes::VecDeriv VecDeriv; typedef typename DataTypes::Deriv Deriv; typedef typename DataTypes::Real Real; - typedef constraint::projective::AffineMovementConstraint AffineMovementConstraint; + typedef constraint::projective::AffineMovementProjectiveConstraint AffineMovementProjectiveConstraint; typedef statecontainer::MechanicalObject MechanicalObject; typedef typename component::solidmechanics::spring::MeshSpringForceField MeshSpringForceField; typedef typename component::solidmechanics::fem::elastic::TetrahedronFEMForceField TetraForceField; diff --git a/Sofa/Component/SolidMechanics/simutests/LinearElasticity_test.cpp b/Sofa/Component/SolidMechanics/simutests/LinearElasticity_test.cpp index 197433adacf..b9d34e25cc2 100644 --- a/Sofa/Component/SolidMechanics/simutests/LinearElasticity_test.cpp +++ b/Sofa/Component/SolidMechanics/simutests/LinearElasticity_test.cpp @@ -39,9 +39,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include namespace sofa { @@ -136,13 +136,13 @@ CylinderTractionStruct createCylinderTractionScene( typename BoxRoi::SPtr boxRoi1 = modeling::addNew(root,"boxRoiFix"); boxRoi1->d_alignedBoxes.setValue(vecBox); boxRoi1->d_strict.setValue(false); - // FixedConstraint - typename component::constraint::projective::FixedConstraint::SPtr fc= - modeling::addNew >(root); + // FixedProjectiveConstraint + typename component::constraint::projective::FixedProjectiveConstraint::SPtr fc= + modeling::addNew >(root); sofa::modeling::setDataLink(&boxRoi1->d_indices,&fc->d_indices); - // FixedPlaneConstraint - typename component::constraint::projective::FixedPlaneConstraint::SPtr fpc= - modeling::addNew >(root); + // FixedPlaneProjectiveConstraint + typename component::constraint::projective::FixedPlaneProjectiveConstraint::SPtr fpc= + modeling::addNew >(root); fpc->d_dmin= -0.01; fpc->d_dmax= 0.01; fpc->d_direction=Coord(0,0,1); @@ -158,9 +158,9 @@ CylinderTractionStruct createCylinderTractionScene( modeling::addNew >(root); tractionStruct.forceField=tpff; sofa::modeling::setDataLink(&boxRoi2->d_triangleIndices,&tpff->triangleList); - // ProjectToLineConstraint - typename component::constraint::projective::ProjectToLineConstraint::SPtr ptlc= - modeling::addNew >(root); + // LineProjectiveConstraint + typename component::constraint::projective::LineProjectiveConstraint::SPtr ptlc= + modeling::addNew >(root); ptlc->f_direction=Coord(1,0,0); ptlc->f_origin=Coord(0,0,0); sofa::type::vector vArray; diff --git a/Sofa/Component/Topology/Testing/src/sofa/component/topology/testing/RegularGridNodeCreation.h b/Sofa/Component/Topology/Testing/src/sofa/component/topology/testing/RegularGridNodeCreation.h index d4b22e9e5c6..6a6799a8d6e 100644 --- a/Sofa/Component/Topology/Testing/src/sofa/component/topology/testing/RegularGridNodeCreation.h +++ b/Sofa/Component/Topology/Testing/src/sofa/component/topology/testing/RegularGridNodeCreation.h @@ -40,7 +40,7 @@ template struct PatchTestStruct { simulation::Node::SPtr SquareNode; - typename component::constraint::projective::AffineMovementConstraint::SPtr affineConstraint; + typename component::constraint::projective::AffineMovementProjectiveConstraint::SPtr affineConstraint; typename component::statecontainer::MechanicalObject::SPtr dofs; }; @@ -66,7 +66,7 @@ PatchTestStruct createRegularGridScene( typedef component::topology::container::grid::RegularGridTopology RegularGridTopology; typedef typename component::engine::select::BoxROI BoxRoi; typedef typename sofa::component::engine::select::PairBoxROI PairBoxRoi; - typedef typename component::constraint::projective::AffineMovementConstraint AffineMovementConstraint; + typedef typename component::constraint::projective::AffineMovementProjectiveConstraint AffineMovementProjectiveConstraint; typedef component::linearsolver::iterative::CGLinearSolver CGLinearSolver; // Root node @@ -114,7 +114,7 @@ PatchTestStruct createRegularGridScene( pairBoxRoi->includedBox.setValue(includedBox); //Affine constraint - patchStruct.affineConstraint = modeling::addNew(SquareNode,"affineConstraint"); + patchStruct.affineConstraint = modeling::addNew(SquareNode,"affineConstraint"); modeling::setDataLink(&boxRoi->d_indices,&patchStruct.affineConstraint->m_meshIndices); modeling::setDataLink(&pairBoxRoi->f_indices,& patchStruct.affineConstraint->m_indices); diff --git a/Sofa/GUI/Component/src/sofa/gui/component/performer/ConstraintAttachBodyPerformer.h b/Sofa/GUI/Component/src/sofa/gui/component/performer/ConstraintAttachBodyPerformer.h index 76657bbf82d..42e6bf06bb4 100644 --- a/Sofa/GUI/Component/src/sofa/gui/component/performer/ConstraintAttachBodyPerformer.h +++ b/Sofa/GUI/Component/src/sofa/gui/component/performer/ConstraintAttachBodyPerformer.h @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include @@ -57,7 +57,7 @@ class ConstraintAttachBodyPerformer: public TInteractionPerformer typedef typename DataTypes::VecCoord VecCoord; typedef sofa::component::collision::response::mapper::BaseContactMapper< DataTypes > MouseContactMapper; typedef sofa::core::behavior::MechanicalState< DataTypes > MouseContainer; -// typedef sofa::component::constraint::lagrangian::model::BilateralInteractionConstraint< DataTypes > MouseConstraint; +// typedef sofa::component::constraint::lagrangian::model::BilateralLagrangianConstraint< DataTypes > MouseConstraint; // typedef sofa::core::behavior::BaseForceField MouseForceField; @@ -91,7 +91,7 @@ class ConstraintAttachBodyPerformer: public TInteractionPerformer virtual bool start_partial(const BodyPicked& picked); MouseContactMapper *mapper; - sofa::component::constraint::lagrangian::model::BilateralInteractionConstraint::SPtr m_constraint; + sofa::component::constraint::lagrangian::model::BilateralLagrangianConstraint::SPtr m_constraint; core::visual::DisplayFlags flags; diff --git a/Sofa/GUI/Component/src/sofa/gui/component/performer/ConstraintAttachBodyPerformer.inl b/Sofa/GUI/Component/src/sofa/gui/component/performer/ConstraintAttachBodyPerformer.inl index 1c42a3fbdae..921a7aacee7 100644 --- a/Sofa/GUI/Component/src/sofa/gui/component/performer/ConstraintAttachBodyPerformer.inl +++ b/Sofa/GUI/Component/src/sofa/gui/component/performer/ConstraintAttachBodyPerformer.inl @@ -172,10 +172,10 @@ bool ConstraintAttachBodyPerformer::start_partial(const BodyPicked& p type::Vec3d point1; type::Vec3d point2; - using sofa::component::constraint::lagrangian::model::BilateralInteractionConstraint; + using sofa::component::constraint::lagrangian::model::BilateralLagrangianConstraint; - m_constraint = sofa::core::objectmodel::New >(mstate1, mstate2); - BilateralInteractionConstraint< DataTypes >* bconstraint = static_cast< BilateralInteractionConstraint< sofa::defaulttype::Vec3Types >* >(m_constraint.get()); + m_constraint = sofa::core::objectmodel::New >(mstate1, mstate2); + BilateralLagrangianConstraint< DataTypes >* bconstraint = static_cast< BilateralLagrangianConstraint< sofa::defaulttype::Vec3Types >* >(m_constraint.get()); bconstraint->setName("Constraint-Mouse-Contact"); type::Vec3d normal = point1-point2; diff --git a/Sofa/GUI/Component/src/sofa/gui/component/performer/FixParticlePerformer.inl b/Sofa/GUI/Component/src/sofa/gui/component/performer/FixParticlePerformer.inl index b96e142bbbd..a52c148ef2f 100644 --- a/Sofa/GUI/Component/src/sofa/gui/component/performer/FixParticlePerformer.inl +++ b/Sofa/GUI/Component/src/sofa/gui/component/performer/FixParticlePerformer.inl @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include @@ -62,7 +62,7 @@ void FixParticlePerformer::start() //Fix all the points - typename sofa::component::constraint::projective::FixedConstraint::SPtr fixFixation = sofa::core::objectmodel::New< sofa::component::constraint::projective::FixedConstraint >(); + typename sofa::component::constraint::projective::FixedProjectiveConstraint::SPtr fixFixation = sofa::core::objectmodel::New< sofa::component::constraint::projective::FixedProjectiveConstraint >(); fixFixation->d_fixAll.setValue(true); nodeFixation->addObject(fixFixation); diff --git a/Sofa/GUI/Component/src/sofa/gui/component/performer/SuturePointPerformer.h b/Sofa/GUI/Component/src/sofa/gui/component/performer/SuturePointPerformer.h index b12adce22fb..7412259eac9 100644 --- a/Sofa/GUI/Component/src/sofa/gui/component/performer/SuturePointPerformer.h +++ b/Sofa/GUI/Component/src/sofa/gui/component/performer/SuturePointPerformer.h @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include @@ -51,7 +51,7 @@ class SOFA_GUI_COMPONENT_API SuturePointPerformer: public TInteractionPerformer< typedef typename DataTypes::Real Real; typedef sofa::component::solidmechanics::spring::LinearSpring Spring; typedef sofa::component::solidmechanics::spring::StiffSpringForceField SpringObjectType; - typedef sofa::component::constraint::projective::FixedConstraint FixObjectType; + typedef sofa::component::constraint::projective::FixedProjectiveConstraint FixObjectType; SuturePointPerformer(BaseMouseInteractor *i); ~SuturePointPerformer(); diff --git a/Sofa/framework/Core/src/sofa/core/ObjectFactory.cpp b/Sofa/framework/Core/src/sofa/core/ObjectFactory.cpp index 412011f4879..5777d2acae9 100644 --- a/Sofa/framework/Core/src/sofa/core/ObjectFactory.cpp +++ b/Sofa/framework/Core/src/sofa/core/ObjectFactory.cpp @@ -149,6 +149,16 @@ objectmodel::BaseObject::SPtr ObjectFactory::createObject(objectmodel::BaseConte //////////////////////////////////////////////////////////////////////////////////////////////// + //Check if object has been renamed + + using sofa::helper::lifecycle::renamedComponents; + auto renamedComponent = renamedComponents.find(classname); + if( renamedComponent != renamedComponents.end() ) + { + classname = renamedComponent->second.getNewName(); + } + + // In order to get the errors from the creators only, we save the current errors at this point // and we clear them. Once we extracted the errors from the creators, we put push them back. std::map> creators_errors; // (template_name, errors) @@ -206,14 +216,20 @@ objectmodel::BaseObject::SPtr ObjectFactory::createObject(objectmodel::BaseConte using sofa::helper::lifecycle::ComponentChange; using sofa::helper::lifecycle::uncreatableComponents; + using sofa::helper::lifecycle::movedComponents; if(it == registry.end()) { arg->logError("The object '" + classname + "' is not in the factory."); auto uuncreatableComponent = uncreatableComponents.find(classname); + auto movedComponent = movedComponents.find(classname); if( uuncreatableComponent != uncreatableComponents.end() ) { arg->logError( uuncreatableComponent->second.getMessage() ); } + else if (movedComponent != movedComponents.end()) + { + arg->logError( movedComponent->second.getMessage() ); + } else { std::vector possibleNames; diff --git a/Sofa/framework/Helper/src/sofa/helper/ComponentChange.cpp b/Sofa/framework/Helper/src/sofa/helper/ComponentChange.cpp index a3cb1196bed..1e7ada3fcc2 100644 --- a/Sofa/framework/Helper/src/sofa/helper/ComponentChange.cpp +++ b/Sofa/framework/Helper/src/sofa/helper/ComponentChange.cpp @@ -32,7 +32,7 @@ const std::map > deprecatedComponents = { {"RigidRigidMapping", Deprecated("v23.06", "v23.12", "You can use the component RigidMapping with template='Rigid3,Rigid3' instead.")}, }; -const std::map > uncreatableComponents = { +const std::map > movedComponents = { // SofaValidation was pluginized in #1302 {"CompareState", Pluginized("v20.06", "SofaValidation")}, {"CompareTopology", Pluginized("v20.06", "SofaValidation")}, @@ -66,107 +66,6 @@ const std::map > uncreatableComponents { "LMConstraintSolver", Pluginized("v20.12", "LMConstraint") }, { "LMConstraintDirectSolver", Pluginized("v20.12", "LMConstraint") }, - /***********************/ - // REMOVED SINCE v23.06 - - { "OglGrid", Removed("v22.12", "v23.06")}, - { "OglLineAxis", Removed("v22.12", "v23.06")}, - - /***********************/ - // REMOVED SINCE v22.06 - - {"PointConstraint", Removed("v21.12", "v22.06")}, - - /***********************/ - // REMOVED SINCE v21.12 - - { "LMDNewProximityIntersection", Removed("v21.12", "v21.12") }, - { "LocalMinDistanceFilter", Removed("v21.12", "v21.12") }, - { "LineLocalMinDistanceFilter", Removed("v21.12", "v21.12") }, - { "PointLocalMinDistanceFilter", Removed("v21.12", "v21.12") }, - { "TriangleLocalMinDistanceFilter", Removed("v21.12", "v21.12") }, - - /***********************/ - // REMOVED SINCE v21.06 - - {"LengthContainer", Removed("v21.06", "v21.06")}, - {"PoissonContainer", Removed("v21.06", "v21.06")}, - {"RadiusContainer", Removed("v21.06", "v21.06")}, - {"StiffnessContainer", Removed("v21.06", "v21.06")}, - - /***********************/ - // REMOVED SINCE v20.12 - - { "DynamicSparseGridTopologyAlgorithms", Removed("v20.12", "v20.12") }, - { "HexahedronSetTopologyAlgorithms", Removed("v20.12", "v20.12") }, - { "TetrahedronSetTopologyAlgorithms", Removed("v20.12", "v20.12") }, - { "QuadSetTopologyAlgorithms", Removed("v20.12", "v20.12") }, - { "TriangleSetTopologyAlgorithms", Removed("v20.12", "v20.12") }, - { "EdgeSetTopologyAlgorithms", Removed("v20.12", "v20.12") }, - { "PointSetTopologyAlgorithms", Removed("v20.12", "v20.12") }, - - /***********************/ - // REMOVED SINCE v20.06 - - {"Euler", Removed("v19.12", "v20.06")}, - {"EulerExplicit", Removed("v19.12", "v20.06")}, - {"ExplicitEuler", Removed("v19.12", "v20.06")}, - {"EulerSolver", Removed("v19.12", "v20.06")}, - {"ExplicitEulerSolver", Removed("v19.12", "v20.06")}, - - {"Capsule", Removed("v19.12", "v20.06")}, - {"CapsuleModel", Removed("v19.12", "v20.06")}, - {"TCapsuleModel", Removed("v19.12", "v20.06")}, - - {"Cube", Removed("v19.12", "v20.06")}, - {"CubeModel", Removed("v19.12", "v20.06")}, - - {"CudaPoint", Removed("v19.12", "v20.06")}, - {"CudaPointModel", Removed("v19.12", "v20.06")}, - - {"Cylinder", Removed("v19.12", "v20.06")}, - {"CylinderModel", Removed("v19.12", "v20.06")}, - - {"Line", Removed("v19.12", "v20.06")}, - {"TLineModel", Removed("v19.12", "v20.06")}, - {"LineMeshModel", Removed("v19.12", "v20.06")}, - {"LineSetModel", Removed("v19.12", "v20.06")}, - {"LineMesh", Removed("v19.12", "v20.06")}, - {"LineSet", Removed("v19.12", "v20.06")}, - {"LineModel", Removed("v19.12", "v20.06")}, - - {"OBB", Removed("v19.12", "v20.06")}, - {"OBBModel", Removed("v19.12", "v20.06")}, - {"TOBBModel", Removed("v19.12", "v20.06")}, - - {"Point", Removed("v19.12", "v20.06")}, - {"TPointModel", Removed("v19.12", "v20.06")}, - {"PointModel", Removed("v19.12", "v20.06")}, - {"PointMesh", Removed("v19.12", "v20.06")}, - {"PointSet", Removed("v19.12", "v20.06")}, - - {"Ray", Removed("v19.12", "v20.06")}, - {"RayModel", Removed("v19.12", "v20.06")}, - - {"RigidCapsule", Removed("v19.12", "v20.06")}, - {"RigidCapsuleModel", Removed("v19.12", "v20.06")}, - {"RigidCapsuleCollisionModel", Removed("v19.12", "v20.06")}, - - {"Sphere", Removed("v19.12", "v20.06")}, - {"SphereModel", Removed("v19.12", "v20.06")}, - {"TSphereModel", Removed("v19.12", "v20.06")}, - - {"Tetrahedron", Removed("v19.12", "v20.06")}, - {"TetrahedronModel", Removed("v19.12", "v20.06")}, - - {"Triangle", Removed("v19.12", "v20.06")}, - {"TriangleSet", Removed("v19.12", "v20.06")}, - {"TriangleMesh", Removed("v19.12", "v20.06")}, - {"TriangleSetModel", Removed("v19.12", "v20.06")}, - {"TriangleMeshModel", Removed("v19.12", "v20.06")}, - {"TriangleModel", Removed("v19.12", "v20.06")}, - {"TTriangleModel", Removed("v19.12", "v20.06")}, - /***********************/ // MOVED SINCE v21.06 { "SpatialGridPointModel", Moved("v21.06", "SofaMiscCollision", "SofaSphFluid") }, @@ -721,7 +620,144 @@ const std::map > uncreatableComponents // Moved to CSparseSolvers { "SparseCholeskySolver", Moved("v23.12", "Sofa.Component.LinearSolver.Direct", "CSparseSolvers") }, - { "SparseLUSolver", Moved("v23.12", "Sofa.Component.LinearSolver.Direct", "CSparseSolvers") }, + { "SparseLUSolver", Moved("v23.12", "Sofa.Component.LinearSolver.Direct", "CSparseSolvers") } + +}; + +const std::map > uncreatableComponents = { + + /***********************/ + // REMOVED SINCE v23.06 + + { "OglGrid", Removed("v22.12", "v23.06")}, + { "OglLineAxis", Removed("v22.12", "v23.06")}, + + /***********************/ + // REMOVED SINCE v22.06 + + {"PointConstraint", Removed("v21.12", "v22.06")}, + + /***********************/ + // REMOVED SINCE v21.12 + + { "LMDNewProximityIntersection", Removed("v21.12", "v21.12") }, + { "LocalMinDistanceFilter", Removed("v21.12", "v21.12") }, + { "LineLocalMinDistanceFilter", Removed("v21.12", "v21.12") }, + { "PointLocalMinDistanceFilter", Removed("v21.12", "v21.12") }, + { "TriangleLocalMinDistanceFilter", Removed("v21.12", "v21.12") }, + + /***********************/ + // REMOVED SINCE v21.06 + + {"LengthContainer", Removed("v21.06", "v21.06")}, + {"PoissonContainer", Removed("v21.06", "v21.06")}, + {"RadiusContainer", Removed("v21.06", "v21.06")}, + {"StiffnessContainer", Removed("v21.06", "v21.06")}, + + /***********************/ + // REMOVED SINCE v20.12 + + { "DynamicSparseGridTopologyAlgorithms", Removed("v20.12", "v20.12") }, + { "HexahedronSetTopologyAlgorithms", Removed("v20.12", "v20.12") }, + { "TetrahedronSetTopologyAlgorithms", Removed("v20.12", "v20.12") }, + { "QuadSetTopologyAlgorithms", Removed("v20.12", "v20.12") }, + { "TriangleSetTopologyAlgorithms", Removed("v20.12", "v20.12") }, + { "EdgeSetTopologyAlgorithms", Removed("v20.12", "v20.12") }, + { "PointSetTopologyAlgorithms", Removed("v20.12", "v20.12") }, + + /***********************/ + // REMOVED SINCE v20.06 + + {"Euler", Removed("v19.12", "v20.06")}, + {"EulerExplicit", Removed("v19.12", "v20.06")}, + {"ExplicitEuler", Removed("v19.12", "v20.06")}, + {"EulerSolver", Removed("v19.12", "v20.06")}, + {"ExplicitEulerSolver", Removed("v19.12", "v20.06")}, + + {"Capsule", Removed("v19.12", "v20.06")}, + {"CapsuleModel", Removed("v19.12", "v20.06")}, + {"TCapsuleModel", Removed("v19.12", "v20.06")}, + + {"Cube", Removed("v19.12", "v20.06")}, + {"CubeModel", Removed("v19.12", "v20.06")}, + + {"CudaPoint", Removed("v19.12", "v20.06")}, + {"CudaPointModel", Removed("v19.12", "v20.06")}, + + {"Cylinder", Removed("v19.12", "v20.06")}, + {"CylinderModel", Removed("v19.12", "v20.06")}, + + {"Line", Removed("v19.12", "v20.06")}, + {"TLineModel", Removed("v19.12", "v20.06")}, + {"LineMeshModel", Removed("v19.12", "v20.06")}, + {"LineSetModel", Removed("v19.12", "v20.06")}, + {"LineMesh", Removed("v19.12", "v20.06")}, + {"LineSet", Removed("v19.12", "v20.06")}, + {"LineModel", Removed("v19.12", "v20.06")}, + + {"OBB", Removed("v19.12", "v20.06")}, + {"OBBModel", Removed("v19.12", "v20.06")}, + {"TOBBModel", Removed("v19.12", "v20.06")}, + + {"Point", Removed("v19.12", "v20.06")}, + {"TPointModel", Removed("v19.12", "v20.06")}, + {"PointModel", Removed("v19.12", "v20.06")}, + {"PointMesh", Removed("v19.12", "v20.06")}, + {"PointSet", Removed("v19.12", "v20.06")}, + + {"Ray", Removed("v19.12", "v20.06")}, + {"RayModel", Removed("v19.12", "v20.06")}, + + {"RigidCapsule", Removed("v19.12", "v20.06")}, + {"RigidCapsuleModel", Removed("v19.12", "v20.06")}, + {"RigidCapsuleCollisionModel", Removed("v19.12", "v20.06")}, + + {"Sphere", Removed("v19.12", "v20.06")}, + {"SphereModel", Removed("v19.12", "v20.06")}, + {"TSphereModel", Removed("v19.12", "v20.06")}, + + {"Tetrahedron", Removed("v19.12", "v20.06")}, + {"TetrahedronModel", Removed("v19.12", "v20.06")}, + + {"Triangle", Removed("v19.12", "v20.06")}, + {"TriangleSet", Removed("v19.12", "v20.06")}, + {"TriangleMesh", Removed("v19.12", "v20.06")}, + {"TriangleSetModel", Removed("v19.12", "v20.06")}, + {"TriangleMeshModel", Removed("v19.12", "v20.06")}, + {"TriangleModel", Removed("v19.12", "v20.06")}, + {"TTriangleModel", Removed("v19.12", "v20.06")}, + +}; + + +const std::map< std::string, Renamed, std::less<> > renamedComponents = { + // Change Constraint naming #4302 + {"AffineMovementConstraint", Renamed("v24.06","v25.06","AffineMovementProjectiveConstraint")}, + {"AttachConstraint", Renamed("v24.06","v25.06","AttachProjectiveConstraint")}, + {"FixedConstraint", Renamed("v24.06","v25.06","FixedProjectiveConstraint")}, + {"FixedPlaneConstraint", Renamed("v24.06","v25.06","FixedPlaneProjectiveConstraint")}, + {"FixedRotationConstraint", Renamed("v24.06","v25.06","FixedRotationProjectiveConstraint")}, + {"FixedTranslationConstraint", Renamed("v24.06","v25.06","FixedTranslationProjectiveConstraint")}, + {"HermiteSplineConstraint", Renamed("v24.06","v25.06","HermiteSplineProjectiveConstraint")}, + {"LinearMovementConstraint", Renamed("v24.06","v25.06","LinearMovementProjectiveConstraint")}, + {"LinearVelocityConstraint", Renamed("v24.06","v25.06","LinearVelocityProjectiveConstraint")}, + {"OscillatorConstraint", Renamed("v24.06","v25.06","OscillatorProjectiveConstraint")}, + {"ParabolicConstraint", Renamed("v24.06","v25.06","ParabolicProjectiveConstraint")}, + {"PartialFixedConstraint", Renamed("v24.06","v25.06","PartialFixedProjectiveConstraint")}, + {"PartialLinearMovementConstraint", Renamed("v24.06","v25.06","PartialLinearMovementProjectiveConstraint")}, + {"PatchTestMovementConstraint", Renamed("v24.06","v25.06","PatchTestMovementProjectiveConstraint")}, + {"PositionBasedDynamicsConstraint", Renamed("v24.06","v25.06","PositionBasedDynamicsProjectiveConstraint")}, + {"SkeletalMotionConstraint", Renamed("v24.06","v25.06","SkeletalMotionProjectiveConstraint")}, + {"ProjectToLineConstraint", Renamed("v24.06","v25.06","LineProjectiveConstraint")}, + {"ProjectToPlaneConstraint", Renamed("v24.06","v25.06","PlaneProjectiveConstraint")}, + {"ProjectToPointConstraint", Renamed("v24.06","v25.06","PointProjectiveConstraint")}, + {"ProjectDirectionConstraint", Renamed("v24.06","v25.06","DirectionProjectiveConstraint")}, + {"BilateralInteractionConstraint", Renamed("v24.06","v25.06","BilateralLagrangianConstraint")}, + {"SlidingConstraint", Renamed("v24.06","v25.06","SlidingLagrangianConstraint")}, + {"StopperConstraint", Renamed("v24.06","v25.06","StopperLagrangianConstraint")}, + {"UniformConstraint", Renamed("v24.06","v25.06","UniformLagrangianConstraint")}, + {"UnilateralInteractionConstraint", Renamed("v24.06","v25.06","UnilateralLagrangianConstraint")} + }; } // namespace sofa::helper::lifecycle diff --git a/Sofa/framework/Helper/src/sofa/helper/ComponentChange.h b/Sofa/framework/Helper/src/sofa/helper/ComponentChange.h index 732065b8bc9..6bd25e04c63 100644 --- a/Sofa/framework/Helper/src/sofa/helper/ComponentChange.h +++ b/Sofa/framework/Helper/src/sofa/helper/ComponentChange.h @@ -111,7 +111,32 @@ class SOFA_HELPER_API Moved : public ComponentChange } }; +class SOFA_HELPER_API Renamed : public ComponentChange +{ +public: + Renamed(const std::string& sinceVersion, const std::string& untilVersion, const std::string& newName) + { + std::stringstream output; + output << "This component has been RENAMED to " << newName << " since SOFA " << sinceVersion + << ", and this alias will be removed in SOFA " << untilVersion << "." + << " To continue using this component after SOFA "<< untilVersion <<" you will need to update your scene "; + m_message = output.str(); + m_changeVersion = untilVersion; + m_newName = newName; + } + + const std::string& getNewName() const + { + return m_newName; + } + +private: + std::string m_newName; +}; + extern SOFA_HELPER_API const std::map< std::string, Deprecated, std::less<> > deprecatedComponents; +extern SOFA_HELPER_API const std::map< std::string, ComponentChange, std::less<> > movedComponents; +extern SOFA_HELPER_API const std::map< std::string, Renamed, std::less<> > renamedComponents; extern SOFA_HELPER_API const std::map< std::string, ComponentChange, std::less<> > uncreatableComponents; } // namespace sofa::helper::lifecycle diff --git a/applications/collections/deprecated/modules/SofaExporter/examples/OBJExporter.scn b/applications/collections/deprecated/modules/SofaExporter/examples/OBJExporter.scn index 7a3879a7e45..47ba602efd0 100644 --- a/applications/collections/deprecated/modules/SofaExporter/examples/OBJExporter.scn +++ b/applications/collections/deprecated/modules/SofaExporter/examples/OBJExporter.scn @@ -1,5 +1,5 @@ - + @@ -18,7 +18,7 @@ - + diff --git a/applications/plugins/ArticulatedSystemPlugin/examples/ArticulatedSystemMapping.scn b/applications/plugins/ArticulatedSystemPlugin/examples/ArticulatedSystemMapping.scn index 59ff8a7857f..14f8ceb8057 100644 --- a/applications/plugins/ArticulatedSystemPlugin/examples/ArticulatedSystemMapping.scn +++ b/applications/plugins/ArticulatedSystemPlugin/examples/ArticulatedSystemMapping.scn @@ -5,7 +5,7 @@ - + @@ -27,7 +27,7 @@ - + @@ -36,7 +36,7 @@ - + diff --git a/applications/plugins/BulletCollisionDetection/examples/BulletConvexHullDemo.scn b/applications/plugins/BulletCollisionDetection/examples/BulletConvexHullDemo.scn index 6941d64206f..8b451789701 100644 --- a/applications/plugins/BulletCollisionDetection/examples/BulletConvexHullDemo.scn +++ b/applications/plugins/BulletCollisionDetection/examples/BulletConvexHullDemo.scn @@ -6,7 +6,7 @@ - + @@ -43,7 +43,7 @@ - + diff --git a/applications/plugins/BulletCollisionDetection/examples/BulletLMDragon.scn b/applications/plugins/BulletCollisionDetection/examples/BulletLMDragon.scn index dfe56efbf3f..d4d284f4e3c 100644 --- a/applications/plugins/BulletCollisionDetection/examples/BulletLMDragon.scn +++ b/applications/plugins/BulletCollisionDetection/examples/BulletLMDragon.scn @@ -26,7 +26,7 @@ - + diff --git a/applications/plugins/BulletCollisionDetection/examples/BulletSphere.scn b/applications/plugins/BulletCollisionDetection/examples/BulletSphere.scn index 5b6cf8c420f..5c549726185 100644 --- a/applications/plugins/BulletCollisionDetection/examples/BulletSphere.scn +++ b/applications/plugins/BulletCollisionDetection/examples/BulletSphere.scn @@ -6,7 +6,7 @@ - + @@ -34,7 +34,7 @@ - + diff --git a/applications/plugins/BulletCollisionDetection/examples/GlobalBulletCollision.py b/applications/plugins/BulletCollisionDetection/examples/GlobalBulletCollision.py index 4d4f23c6de4..a2914792e0b 100644 --- a/applications/plugins/BulletCollisionDetection/examples/GlobalBulletCollision.py +++ b/applications/plugins/BulletCollisionDetection/examples/GlobalBulletCollision.py @@ -21,7 +21,7 @@ def createGraph(self,node): # a container floorNode = self.rootNode.createChild('Floor') rigid_meca = floorNode.createObject('MechanicalObject',name='father',template='Rigid',position='0 0 0 0 0 0 1') - floorNode.createObject('FixedConstraint',template='Rigid') + floorNode.createObject('FixedProjectiveConstraint',template='Rigid') #floorNode.createObject('UniformMass',template='Rigid',totalMass=1) mapped = floorNode.createChild('mapped') mapped.createObject('MeshOBJLoader', name='loader', filename='mesh/SaladBowl.obj') @@ -38,7 +38,7 @@ def createGraph(self,node): # meca = node.createObject('MechanicalObject',name='rigidDOF',template='Rigid',position='0 0 0 0 0 0 1') # mass = node.createObject('UniformMass',name='mass',totalMass=1,template='Rigid') - # node.createObject('FixedConstraint',template='Rigid') + # node.createObject('FixedProjectiveConstraint',template='Rigid') # node.createObject('BulletOBBModel',template='Rigid',name='BASE',extents='15 15 0.2',margin="0.5") diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBCap.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBCap.scn index 5b99c835abf..a3b22ccb2ba 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBCap.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBCap.scn @@ -4,7 +4,7 @@ - + @@ -26,7 +26,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBCap1.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBCap1.scn index ad6980d15de..be3d5623649 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBCap1.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBCap1.scn @@ -4,7 +4,7 @@ - + @@ -26,7 +26,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBCapEdgeEdge.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBCapEdgeEdge.scn index 69cb203fb53..f067b42d1a9 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBCapEdgeEdge.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBCapEdgeEdge.scn @@ -4,7 +4,7 @@ - + @@ -26,7 +26,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBCapEdgeVertex.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBCapEdgeVertex.scn index 007317fed3d..b4bd1bff158 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBCapEdgeVertex.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBCapEdgeVertex.scn @@ -4,7 +4,7 @@ - + @@ -26,7 +26,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBCapVertexEdge.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBCapVertexEdge.scn index 553a46dc083..8b5f3fd8f50 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBCapVertexEdge.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBCapVertexEdge.scn @@ -4,7 +4,7 @@ - + @@ -26,7 +26,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBCapVertexVertex.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBCapVertexVertex.scn index 0df0fd3a3bf..74699c66456 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBCapVertexVertex.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBCapVertexVertex.scn @@ -4,7 +4,7 @@ - + @@ -26,7 +26,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBOBB.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBOBB.scn index bb2e1d1fcee..6e30f739230 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBOBB.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBOBB.scn @@ -4,7 +4,7 @@ - + @@ -24,7 +24,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBOBB2.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBOBB2.scn index f07ebf0d8c1..b3b6f6f3737 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBOBB2.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBOBB2.scn @@ -4,7 +4,7 @@ - + @@ -29,7 +29,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBOBBAlea.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBOBBAlea.scn index 09785b19869..98404d9e504 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBOBBAlea.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBOBBAlea.scn @@ -4,7 +4,7 @@ - + @@ -24,7 +24,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBOBBCollision.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBOBBCollision.scn index 8b4b816a814..cb722ba85a4 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBOBBCollision.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBOBBCollision.scn @@ -4,7 +4,7 @@ - + @@ -29,7 +29,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBOBBEdgeEdge.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBOBBEdgeEdge.scn index 2e592d5f536..8809f875aca 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBOBBEdgeEdge.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBOBBEdgeEdge.scn @@ -4,7 +4,7 @@ - + @@ -24,7 +24,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBOBBEdgeVertex.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBOBBEdgeVertex.scn index 6db3a901805..39ba344e353 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBOBBEdgeVertex.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBOBBEdgeVertex.scn @@ -4,7 +4,7 @@ - + @@ -24,7 +24,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBOBBFaceEdge.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBOBBFaceEdge.scn index b717a476163..a8281fd12f9 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBOBBFaceEdge.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBOBBFaceEdge.scn @@ -4,7 +4,7 @@ - + @@ -24,7 +24,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBOBBVertexVertex.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBOBBVertexVertex.scn index f7fe9535c12..48bff4ce98e 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBOBBVertexVertex.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBOBBVertexVertex.scn @@ -4,7 +4,7 @@ - + @@ -24,7 +24,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBSphere.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBSphere.scn index a21c57e5398..3986adc9c3b 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBSphere.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBSphere.scn @@ -5,7 +5,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBSphere2.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBSphere2.scn index 67dcef7f5bb..6958086322e 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBSphere2.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBSphere2.scn @@ -5,7 +5,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBSphereEdge.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBSphereEdge.scn index 73ce0986e7d..fb19177217f 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBSphereEdge.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBSphereEdge.scn @@ -5,7 +5,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBSphereVertex.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBSphereVertex.scn index 532a53d0986..e1131d724bc 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBSphereVertex.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBSphereVertex.scn @@ -5,7 +5,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBTri.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBTri.scn index d5c1c45527b..013b2b8509c 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBTri.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBTri.scn @@ -5,7 +5,7 @@ - + @@ -38,7 +38,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBTriEdgeEdge.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBTriEdgeEdge.scn index 0dfb625fa80..1fc60715158 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBTriEdgeEdge.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBTriEdgeEdge.scn @@ -5,7 +5,7 @@ - + @@ -38,7 +38,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBTriEdgeEdge2.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBTriEdgeEdge2.scn index c8474887f48..940298e3d69 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBTriEdgeEdge2.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBTriEdgeEdge2.scn @@ -5,7 +5,7 @@ - + @@ -38,7 +38,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBTriEdgeVerex.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBTriEdgeVerex.scn index 66ca20abf4d..182c5ef73da 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBTriEdgeVerex.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBTriEdgeVerex.scn @@ -5,7 +5,7 @@ - + @@ -38,7 +38,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBTriFaceVertex.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBTriFaceVertex.scn index b2ebf71afec..73e1e1535ef 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBTriFaceVertex.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBTriFaceVertex.scn @@ -5,7 +5,7 @@ - + @@ -38,7 +38,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBTriVertexEdge.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBTriVertexEdge.scn index d30e39a726a..4db77349d71 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBTriVertexEdge.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBTriVertexEdge.scn @@ -5,7 +5,7 @@ - + @@ -38,7 +38,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBTriVertexFace.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBTriVertexFace.scn index c1893aca86d..e25636aae4e 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBTriVertexFace.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBTriVertexFace.scn @@ -5,7 +5,7 @@ - + @@ -38,7 +38,7 @@ - + diff --git a/applications/plugins/CollisionOBBCapsule/examples/OBBTriVertexVertex.scn b/applications/plugins/CollisionOBBCapsule/examples/OBBTriVertexVertex.scn index 37a9abb241c..452b69386b4 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/OBBTriVertexVertex.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/OBBTriVertexVertex.scn @@ -5,7 +5,7 @@ - + @@ -40,7 +40,7 @@ - + diff --git a/applications/plugins/ExternalBehaviorModel/example/MultiMapping.py b/applications/plugins/ExternalBehaviorModel/example/MultiMapping.py index 40912650f48..c3503363497 100644 --- a/applications/plugins/ExternalBehaviorModel/example/MultiMapping.py +++ b/applications/plugins/ExternalBehaviorModel/example/MultiMapping.py @@ -14,7 +14,7 @@ def createGraph(self,node): rigidNode = self.rootNode.createChild('rigid') rigidNode.createObject('MechanicalObject', template='Rigid', name='dofs', position="0 0 0 0 0 0 1", showObject='1', showObjectScale='0.8') rigidNode.createObject('UniformMass', template='Rigid', totalMass="1") - rigidNode.createObject('PartialFixedConstraint',indices="0",fixedDirections="1 1 1 0 0 0") + rigidNode.createObject('PartialFixedProjectiveConstraint',indices="0",fixedDirections="1 1 1 0 0 0") rigidCollisionNode = rigidNode.createChild('rigid') rigidCollisionNode.createObject('MeshOBJLoader', filename="mesh/cube.obj", name="loader") diff --git a/applications/plugins/ExternalBehaviorModel/example/simple.scn b/applications/plugins/ExternalBehaviorModel/example/simple.scn index b9e6b608b89..ef6ce72b566 100644 --- a/applications/plugins/ExternalBehaviorModel/example/simple.scn +++ b/applications/plugins/ExternalBehaviorModel/example/simple.scn @@ -3,7 +3,7 @@ - + @@ -25,7 +25,7 @@ - + @@ -44,7 +44,7 @@ - + diff --git a/applications/plugins/Geomagic/scenes/Geomagic-DeformableCubes.scn b/applications/plugins/Geomagic/scenes/Geomagic-DeformableCubes.scn index b6ebff5c894..8447dc4d862 100644 --- a/applications/plugins/Geomagic/scenes/Geomagic-DeformableCubes.scn +++ b/applications/plugins/Geomagic/scenes/Geomagic-DeformableCubes.scn @@ -8,7 +8,7 @@ - + @@ -50,7 +50,7 @@ - + @@ -86,7 +86,7 @@ - + diff --git a/applications/plugins/Geomagic/scenes/Geomagic-DeformableSphere.scn b/applications/plugins/Geomagic/scenes/Geomagic-DeformableSphere.scn index d6f8c9ff6ce..d3f88c411bb 100644 --- a/applications/plugins/Geomagic/scenes/Geomagic-DeformableSphere.scn +++ b/applications/plugins/Geomagic/scenes/Geomagic-DeformableSphere.scn @@ -8,7 +8,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/applications/plugins/Geomagic/scenes/Geomagic-FEMLiver.scn b/applications/plugins/Geomagic/scenes/Geomagic-FEMLiver.scn index cdf81e4fab8..81d53f6df1b 100644 --- a/applications/plugins/Geomagic/scenes/Geomagic-FEMLiver.scn +++ b/applications/plugins/Geomagic/scenes/Geomagic-FEMLiver.scn @@ -8,7 +8,7 @@ - + @@ -49,7 +49,7 @@ - + diff --git a/applications/plugins/LeapMotion/examples/buffoon.scn b/applications/plugins/LeapMotion/examples/buffoon.scn index bfd57985440..5e9cbdc251e 100644 --- a/applications/plugins/LeapMotion/examples/buffoon.scn +++ b/applications/plugins/LeapMotion/examples/buffoon.scn @@ -85,7 +85,7 @@ - + diff --git a/applications/plugins/MultiThreading/examples/BeamLinearMapping_mt.scn b/applications/plugins/MultiThreading/examples/BeamLinearMapping_mt.scn index defb33bfc4d..0bb5ba0765e 100644 --- a/applications/plugins/MultiThreading/examples/BeamLinearMapping_mt.scn +++ b/applications/plugins/MultiThreading/examples/BeamLinearMapping_mt.scn @@ -4,7 +4,7 @@ - + @@ -35,7 +35,7 @@ --> - + - + @@ -23,7 +23,7 @@ - + diff --git a/applications/plugins/MultiThreading/examples/ParallelHexahedronFEMForceField.scn b/applications/plugins/MultiThreading/examples/ParallelHexahedronFEMForceField.scn index e147745648a..1b5a5f24201 100644 --- a/applications/plugins/MultiThreading/examples/ParallelHexahedronFEMForceField.scn +++ b/applications/plugins/MultiThreading/examples/ParallelHexahedronFEMForceField.scn @@ -1,7 +1,7 @@ - + @@ -28,7 +28,7 @@ - + diff --git a/applications/plugins/MultiThreading/examples/ParallelMeshSpringForceField.scn b/applications/plugins/MultiThreading/examples/ParallelMeshSpringForceField.scn index 726abe07d5b..64bb539add1 100644 --- a/applications/plugins/MultiThreading/examples/ParallelMeshSpringForceField.scn +++ b/applications/plugins/MultiThreading/examples/ParallelMeshSpringForceField.scn @@ -2,7 +2,7 @@ - + @@ -34,7 +34,7 @@ - + diff --git a/applications/plugins/MultiThreading/examples/ParallelTetrahedronFEMForceField.scn b/applications/plugins/MultiThreading/examples/ParallelTetrahedronFEMForceField.scn index 655bd5c2f4a..31594029598 100644 --- a/applications/plugins/MultiThreading/examples/ParallelTetrahedronFEMForceField.scn +++ b/applications/plugins/MultiThreading/examples/ParallelTetrahedronFEMForceField.scn @@ -1,6 +1,6 @@ - + @@ -31,7 +31,7 @@ method="large" computeVonMisesStress="1" showVonMisesStressPerElement="true"/> - + diff --git a/applications/plugins/MultiThreading/examples/TriangularForceFieldComparison.scn b/applications/plugins/MultiThreading/examples/TriangularForceFieldComparison.scn index e1d4f772a79..a3e67630803 100644 --- a/applications/plugins/MultiThreading/examples/TriangularForceFieldComparison.scn +++ b/applications/plugins/MultiThreading/examples/TriangularForceFieldComparison.scn @@ -5,7 +5,7 @@ - + @@ -38,7 +38,7 @@ - + @@ -69,7 +69,7 @@ - + @@ -98,7 +98,7 @@ - + @@ -127,7 +127,7 @@ - + diff --git a/applications/plugins/MultiThreading/examples/livers.scn b/applications/plugins/MultiThreading/examples/livers.scn index 9a612b523a7..ec48c42ebc2 100644 --- a/applications/plugins/MultiThreading/examples/livers.scn +++ b/applications/plugins/MultiThreading/examples/livers.scn @@ -7,7 +7,7 @@ - + @@ -38,7 +38,7 @@ - + @@ -71,7 +71,7 @@ - + @@ -104,7 +104,7 @@ - + @@ -138,7 +138,7 @@ - + diff --git a/applications/plugins/MultiThreading/examples/liversMeanPositions.scn b/applications/plugins/MultiThreading/examples/liversMeanPositions.scn index 537edd0c458..4338d44d9e8 100644 --- a/applications/plugins/MultiThreading/examples/liversMeanPositions.scn +++ b/applications/plugins/MultiThreading/examples/liversMeanPositions.scn @@ -7,7 +7,7 @@ - + @@ -38,7 +38,7 @@ - + @@ -71,7 +71,7 @@ - + @@ -104,7 +104,7 @@ - + @@ -138,7 +138,7 @@ - + @@ -179,7 +179,7 @@ - + diff --git a/applications/plugins/Sensable/examples/Carving.scn b/applications/plugins/Sensable/examples/Carving.scn index f14b61c400f..085515da169 100644 --- a/applications/plugins/Sensable/examples/Carving.scn +++ b/applications/plugins/Sensable/examples/Carving.scn @@ -21,8 +21,8 @@ - - + + diff --git a/applications/plugins/Sensable/examples/Deformable-Method1.scn b/applications/plugins/Sensable/examples/Deformable-Method1.scn index 39152d3c235..2490a666f80 100644 --- a/applications/plugins/Sensable/examples/Deformable-Method1.scn +++ b/applications/plugins/Sensable/examples/Deformable-Method1.scn @@ -17,8 +17,8 @@ - - + + diff --git a/applications/plugins/Sensable/examples/Old Examples/flexibleRaptor.scn b/applications/plugins/Sensable/examples/Old Examples/flexibleRaptor.scn index 20955efe5e6..864a1e2dec6 100644 --- a/applications/plugins/Sensable/examples/Old Examples/flexibleRaptor.scn +++ b/applications/plugins/Sensable/examples/Old Examples/flexibleRaptor.scn @@ -25,7 +25,7 @@ - + diff --git a/applications/plugins/Sensable/examples/Old Examples/omni-probing-liver.scn b/applications/plugins/Sensable/examples/Old Examples/omni-probing-liver.scn index 72f342fe938..4031bae0c17 100644 --- a/applications/plugins/Sensable/examples/Old Examples/omni-probing-liver.scn +++ b/applications/plugins/Sensable/examples/Old Examples/omni-probing-liver.scn @@ -15,7 +15,7 @@ - + diff --git a/applications/plugins/SixenseHydra/Scenes/Hydra_buffon.scn b/applications/plugins/SixenseHydra/Scenes/Hydra_buffon.scn index b442bb87892..77a761c3713 100644 --- a/applications/plugins/SixenseHydra/Scenes/Hydra_buffon.scn +++ b/applications/plugins/SixenseHydra/Scenes/Hydra_buffon.scn @@ -69,7 +69,7 @@ - + diff --git a/applications/plugins/SofaAssimp/SceneColladaLoader.cpp b/applications/plugins/SofaAssimp/SceneColladaLoader.cpp index c13aae99da0..2021ecae599 100644 --- a/applications/plugins/SofaAssimp/SceneColladaLoader.cpp +++ b/applications/plugins/SofaAssimp/SceneColladaLoader.cpp @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include @@ -331,18 +331,18 @@ bool SceneColladaLoader::readDAE (std::ifstream &/*file*/, const char* /*filenam } } - // generating a SkeletalMotionConstraint and filling up its properties - SkeletalMotionConstraint::SPtr currentSkeletalMotionConstraint = sofa::core::objectmodel::New >(); + // generating a SkeletalMotionProjectiveConstraint and filling up its properties + SkeletalMotionProjectiveConstraint::SPtr currentSkeletalMotionProjectiveConstraint = sofa::core::objectmodel::New >(); { - // adding the generated SkeletalMotionConstraint to its parent Node - currentSubNode->addObject(currentSkeletalMotionConstraint); + // adding the generated SkeletalMotionProjectiveConstraint to its parent Node + currentSubNode->addObject(currentSkeletalMotionProjectiveConstraint); std::stringstream nameStream(meshName); if(meshName.empty()) nameStream << componentIndex++; - currentSkeletalMotionConstraint->setName(nameStream.str()); + currentSkeletalMotionProjectiveConstraint->setName(nameStream.str()); - currentSkeletalMotionConstraint->setAnimationSpeed(animationSpeed.getValue()); + currentSkeletalMotionProjectiveConstraint->setAnimationSpeed(animationSpeed.getValue()); aiNode* parentAiNode = NULL; if(parentNodeInfo) @@ -351,7 +351,7 @@ bool SceneColladaLoader::readDAE (std::ifstream &/*file*/, const char* /*filenam type::vector > skeletonJoints; type::vector skeletonBones; fillSkeletalInfo(currentAiScene, parentAiNode, currentAiNode, currentTransformation, currentAiMesh, skeletonJoints, skeletonBones); - currentSkeletalMotionConstraint->setSkeletalMotion(skeletonJoints, skeletonBones); + currentSkeletalMotionProjectiveConstraint->setSkeletalMotion(skeletonJoints, skeletonBones); } } else diff --git a/applications/plugins/SofaAssimp/SceneColladaLoader.h b/applications/plugins/SofaAssimp/SceneColladaLoader.h index 117a5ae5f6f..869e8519399 100644 --- a/applications/plugins/SofaAssimp/SceneColladaLoader.h +++ b/applications/plugins/SofaAssimp/SceneColladaLoader.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include // C++ importer interface #include // Output data structure @@ -130,7 +130,7 @@ class SOFA_ASSIMP_API SceneColladaLoader : public sofa::core::loader::SceneLoade private: - // build the joints and bones array used in the SkeletalMotionConstraint + // build the joints and bones array used in the SkeletalMotionProjectiveConstraint bool fillSkeletalInfo(const aiScene* scene, aiNode* meshParentNode, aiNode* meshNode, aiMatrix4x4 meshTransformation, aiMesh* mesh, type::vector >& skeletonJoints, type::vector& skeletonBones) const; // clean the scene graph of its empty and useless intermediary nodes diff --git a/applications/plugins/SofaAssimp/doc/index.html b/applications/plugins/SofaAssimp/doc/index.html index 3b7b3d369a2..7c553b03b3b 100644 --- a/applications/plugins/SofaAssimp/doc/index.html +++ b/applications/plugins/SofaAssimp/doc/index.html @@ -131,11 +131,11 @@

Examples



      As you can see in Sofa Modeler, the scene to load a collada file is very simple. We have the SceneColladaLoader to load it and, important thing, we also have an EulerSolver -which will be used by the potential SkeletalMotionConstraints to "play" the animation updating positions and velocities. +which will be used by the potential SkeletalMotionProjectiveConstraints to "play" the animation updating positions and velocities. When you launch runSofa with this scene, a new node will be added which contains the whole collada scene. The name of this node is the name you gave to the SceneColladaLoader plus the string "_scene". On the right picture, the loader generated two child nodes call "mesh 0" which contains a mesh without skinning (the sphere), and "mesh 1" which contains a mesh with skinning and bones animation directly from the collada file. -The SkeletalMotionConstraint automatically interpolates between animation frames, play with the animation time step to slown down or speed up the animation. +The SkeletalMotionProjectiveConstraint automatically interpolates between animation frames, play with the animation time step to slown down or speed up the animation.

As you can see on the other example below, the woman's hair does not fit her head very well because its coordinates system belongs to a dummy object not supported for the moment. diff --git a/applications/plugins/SofaAssimp/examples/character_clothes.py b/applications/plugins/SofaAssimp/examples/character_clothes.py index 7a22571e62e..9f6ae51734e 100644 --- a/applications/plugins/SofaAssimp/examples/character_clothes.py +++ b/applications/plugins/SofaAssimp/examples/character_clothes.py @@ -65,7 +65,7 @@ def createBox(parent): parent.createObject('MechanicalObject', template='Rigid', name='model', position='0 100.0 0 0 0 0 1') parent.createObject('UniformMass') - parent.createObject('FixedConstraint', indices='0') + parent.createObject('FixedProjectiveConstraint', indices='0') collisionNode = parent.createChild('collision') collisionNode.createObject('MeshOBJLoader', name='loader', filename=mesh_path + 'cube.obj') diff --git a/applications/plugins/SofaCUDA/CMakeLists.txt b/applications/plugins/SofaCUDA/CMakeLists.txt index 18d32a9d0c5..cede9c498cc 100644 --- a/applications/plugins/SofaCUDA/CMakeLists.txt +++ b/applications/plugins/SofaCUDA/CMakeLists.txt @@ -88,10 +88,10 @@ set(HEADER_FILES ${SOFACUDA_SOURCE_DIR}/component/collision/geometry/CudaTriangleModel.h ### Constraints - ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaFixedConstraint.h - ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaFixedConstraint.inl - ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaLinearMovementConstraint.h - ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaLinearMovementConstraint.inl + ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaFixedProjectiveConstraint.h + ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaFixedProjectiveConstraint.inl + ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaLinearMovementProjectiveConstraint.h + ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaLinearMovementProjectiveConstraint.inl ${SOFACUDA_SOURCE_DIR}/component/collision/response/contact/CudaPenalityContactForceField.h ${SOFACUDA_SOURCE_DIR}/component/collision/response/contact/CudaPenalityContactForceField.inl @@ -155,11 +155,11 @@ set(SOURCE_FILES ${SOFACUDA_SOURCE_DIR}/component/collision/geometry/CudaTriangleModel.cpp ### Constraints - ${SOFACUDA_SOURCE_DIR}/component/constraint/lagrangian/model/CudaBilateralInteractionConstraint.cpp - ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaFixedConstraint.cpp - ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaFixedTranslationConstraint.cpp - ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaLinearMovementConstraint.cpp - ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaLinearVelocityConstraint.cpp + ${SOFACUDA_SOURCE_DIR}/component/constraint/lagrangian/model/CudaBilateralLagrangianConstraint.cpp + ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaFixedProjectiveConstraint.cpp + ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaFixedTranslationProjectiveConstraint.cpp + ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaLinearMovementProjectiveConstraint.cpp + ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaLinearVelocityProjectiveConstraint.cpp ${SOFACUDA_SOURCE_DIR}/component/mapping/linear/CudaBeamLinearMapping.cpp ${SOFACUDA_SOURCE_DIR}/component/engine/select/CudaBoxROI.cpp @@ -214,8 +214,8 @@ set(CUDA_SOURCES ### Collisions ### Constraints - ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaFixedConstraint.cu - ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaLinearMovementConstraint.cu + ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaFixedProjectiveConstraint.cu + ${SOFACUDA_SOURCE_DIR}/component/constraint/projective/CudaLinearMovementProjectiveConstraint.cu ) diff --git a/applications/plugins/SofaCUDA/examples/CudaDiagonalMass3f.scn b/applications/plugins/SofaCUDA/examples/CudaDiagonalMass3f.scn index a41d7f7d812..a050a77b4df 100644 --- a/applications/plugins/SofaCUDA/examples/CudaDiagonalMass3f.scn +++ b/applications/plugins/SofaCUDA/examples/CudaDiagonalMass3f.scn @@ -5,7 +5,7 @@ - + @@ -16,7 +16,7 @@ - + diff --git a/applications/plugins/SofaCUDA/examples/CudaMeshMatrixMass3f.scn b/applications/plugins/SofaCUDA/examples/CudaMeshMatrixMass3f.scn index c37d31a435e..96be448a5c7 100644 --- a/applications/plugins/SofaCUDA/examples/CudaMeshMatrixMass3f.scn +++ b/applications/plugins/SofaCUDA/examples/CudaMeshMatrixMass3f.scn @@ -5,7 +5,7 @@ - + @@ -16,7 +16,7 @@ - + diff --git a/applications/plugins/SofaCUDA/examples/SquareTissue-cpu.scn b/applications/plugins/SofaCUDA/examples/SquareTissue-cpu.scn index 8c4fc663c16..24a9bfef1f3 100644 --- a/applications/plugins/SofaCUDA/examples/SquareTissue-cpu.scn +++ b/applications/plugins/SofaCUDA/examples/SquareTissue-cpu.scn @@ -4,7 +4,7 @@ - + @@ -35,7 +35,7 @@ - + diff --git a/applications/plugins/SofaCUDA/examples/SquareTissue-cuda.scn b/applications/plugins/SofaCUDA/examples/SquareTissue-cuda.scn index 0de5b702db0..dd98b0408bc 100644 --- a/applications/plugins/SofaCUDA/examples/SquareTissue-cuda.scn +++ b/applications/plugins/SofaCUDA/examples/SquareTissue-cuda.scn @@ -9,7 +9,7 @@ - + @@ -29,7 +29,7 @@ - + diff --git a/applications/plugins/SofaCUDA/examples/liver-CUDA.scn b/applications/plugins/SofaCUDA/examples/liver-CUDA.scn index 5a0d97d9267..aab06f1e869 100644 --- a/applications/plugins/SofaCUDA/examples/liver-CUDA.scn +++ b/applications/plugins/SofaCUDA/examples/liver-CUDA.scn @@ -8,7 +8,7 @@ - + @@ -31,7 +31,7 @@ - + diff --git a/applications/plugins/SofaCUDA/examples/quadSpringSphere.scn b/applications/plugins/SofaCUDA/examples/quadSpringSphere.scn index 68b670c1f6c..2bb630e301f 100644 --- a/applications/plugins/SofaCUDA/examples/quadSpringSphere.scn +++ b/applications/plugins/SofaCUDA/examples/quadSpringSphere.scn @@ -3,7 +3,7 @@ - + diff --git a/applications/plugins/SofaCUDA/examples/quadSpringSphere2CUDA.scn b/applications/plugins/SofaCUDA/examples/quadSpringSphere2CUDA.scn index 93848be19a2..c64e31937aa 100644 --- a/applications/plugins/SofaCUDA/examples/quadSpringSphere2CUDA.scn +++ b/applications/plugins/SofaCUDA/examples/quadSpringSphere2CUDA.scn @@ -6,7 +6,7 @@ - + - + @@ -28,7 +28,7 @@ - + diff --git a/applications/plugins/SofaCUDA/examples/raptor-surface-cpu.scn b/applications/plugins/SofaCUDA/examples/raptor-surface-cpu.scn index 3d81d8eee70..1b552f2fee4 100644 --- a/applications/plugins/SofaCUDA/examples/raptor-surface-cpu.scn +++ b/applications/plugins/SofaCUDA/examples/raptor-surface-cpu.scn @@ -1,5 +1,5 @@ - + @@ -27,7 +27,7 @@ - + diff --git a/applications/plugins/SofaCUDA/examples/raptor-surface-cuda.scn b/applications/plugins/SofaCUDA/examples/raptor-surface-cuda.scn index c1f13507fcc..678a2fc71a1 100644 --- a/applications/plugins/SofaCUDA/examples/raptor-surface-cuda.scn +++ b/applications/plugins/SofaCUDA/examples/raptor-surface-cuda.scn @@ -4,7 +4,7 @@ - + @@ -20,7 +20,7 @@ - + diff --git a/applications/plugins/SofaCUDA/examples/raptor.scn b/applications/plugins/SofaCUDA/examples/raptor.scn index 2578f49d39f..0a6c0019fe9 100644 --- a/applications/plugins/SofaCUDA/examples/raptor.scn +++ b/applications/plugins/SofaCUDA/examples/raptor.scn @@ -10,7 +10,7 @@ - + @@ -31,7 +31,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/benchmarks/CudaHexahedronTLEDForceField_beam10x10x40_gpu.scn b/applications/plugins/SofaCUDA/scenes/benchmarks/CudaHexahedronTLEDForceField_beam10x10x40_gpu.scn index 8fa7c7bffd9..7627e77bd95 100644 --- a/applications/plugins/SofaCUDA/scenes/benchmarks/CudaHexahedronTLEDForceField_beam10x10x40_gpu.scn +++ b/applications/plugins/SofaCUDA/scenes/benchmarks/CudaHexahedronTLEDForceField_beam10x10x40_gpu.scn @@ -9,7 +9,7 @@ - + @@ -37,7 +37,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/benchmarks/CudaTetrahedronTLEDForceField_beam10x10x40_gpu.scn b/applications/plugins/SofaCUDA/scenes/benchmarks/CudaTetrahedronTLEDForceField_beam10x10x40_gpu.scn index 2ef393cbcd6..978a4024548 100644 --- a/applications/plugins/SofaCUDA/scenes/benchmarks/CudaTetrahedronTLEDForceField_beam10x10x40_gpu.scn +++ b/applications/plugins/SofaCUDA/scenes/benchmarks/CudaTetrahedronTLEDForceField_beam10x10x40_gpu.scn @@ -9,7 +9,7 @@ - + @@ -42,7 +42,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/benchmarks/CudaTetrahedronTLEDForceField_beam16x16x76_gpu.scn b/applications/plugins/SofaCUDA/scenes/benchmarks/CudaTetrahedronTLEDForceField_beam16x16x76_gpu.scn index 874433d4ddc..fb541d527d5 100644 --- a/applications/plugins/SofaCUDA/scenes/benchmarks/CudaTetrahedronTLEDForceField_beam16x16x76_gpu.scn +++ b/applications/plugins/SofaCUDA/scenes/benchmarks/CudaTetrahedronTLEDForceField_beam16x16x76_gpu.scn @@ -11,7 +11,7 @@ - + @@ -43,7 +43,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/benchmarks/HexahedronFEMForceField_beam10x10x40_cpu.scn b/applications/plugins/SofaCUDA/scenes/benchmarks/HexahedronFEMForceField_beam10x10x40_cpu.scn index 6252c3efb66..105193031cc 100644 --- a/applications/plugins/SofaCUDA/scenes/benchmarks/HexahedronFEMForceField_beam10x10x40_cpu.scn +++ b/applications/plugins/SofaCUDA/scenes/benchmarks/HexahedronFEMForceField_beam10x10x40_cpu.scn @@ -3,7 +3,7 @@ - + @@ -40,7 +40,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/benchmarks/HexahedronFEMForceField_beam10x10x40_gpu.scn b/applications/plugins/SofaCUDA/scenes/benchmarks/HexahedronFEMForceField_beam10x10x40_gpu.scn index 380b07e84e9..5c3d6865027 100644 --- a/applications/plugins/SofaCUDA/scenes/benchmarks/HexahedronFEMForceField_beam10x10x40_gpu.scn +++ b/applications/plugins/SofaCUDA/scenes/benchmarks/HexahedronFEMForceField_beam10x10x40_gpu.scn @@ -10,7 +10,7 @@ - + @@ -35,7 +35,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/benchmarks/HexahedronFEMForceField_beam16x16x76_cpu.scn b/applications/plugins/SofaCUDA/scenes/benchmarks/HexahedronFEMForceField_beam16x16x76_cpu.scn index 6e62626d07d..9a22dfc3dc9 100644 --- a/applications/plugins/SofaCUDA/scenes/benchmarks/HexahedronFEMForceField_beam16x16x76_cpu.scn +++ b/applications/plugins/SofaCUDA/scenes/benchmarks/HexahedronFEMForceField_beam16x16x76_cpu.scn @@ -3,7 +3,7 @@ - + @@ -41,7 +41,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/benchmarks/HexahedronFEMForceField_beam16x16x76_gpu.scn b/applications/plugins/SofaCUDA/scenes/benchmarks/HexahedronFEMForceField_beam16x16x76_gpu.scn index a4dc1cf195e..a10083418e6 100644 --- a/applications/plugins/SofaCUDA/scenes/benchmarks/HexahedronFEMForceField_beam16x16x76_gpu.scn +++ b/applications/plugins/SofaCUDA/scenes/benchmarks/HexahedronFEMForceField_beam16x16x76_gpu.scn @@ -12,7 +12,7 @@ - + @@ -37,7 +37,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/benchmarks/MeshSpringForceField_beam10x10x40_cpu.scn b/applications/plugins/SofaCUDA/scenes/benchmarks/MeshSpringForceField_beam10x10x40_cpu.scn index ac8153d6f7b..7796da7c44c 100644 --- a/applications/plugins/SofaCUDA/scenes/benchmarks/MeshSpringForceField_beam10x10x40_cpu.scn +++ b/applications/plugins/SofaCUDA/scenes/benchmarks/MeshSpringForceField_beam10x10x40_cpu.scn @@ -3,7 +3,7 @@ - + @@ -44,7 +44,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/benchmarks/MeshSpringForceField_beam10x10x40_gpu.scn b/applications/plugins/SofaCUDA/scenes/benchmarks/MeshSpringForceField_beam10x10x40_gpu.scn index 5e6d8de2f26..d17803e7c3d 100644 --- a/applications/plugins/SofaCUDA/scenes/benchmarks/MeshSpringForceField_beam10x10x40_gpu.scn +++ b/applications/plugins/SofaCUDA/scenes/benchmarks/MeshSpringForceField_beam10x10x40_gpu.scn @@ -10,7 +10,7 @@ - + @@ -39,7 +39,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/benchmarks/QuadSpringsSphere_cpu.scn b/applications/plugins/SofaCUDA/scenes/benchmarks/QuadSpringsSphere_cpu.scn index 1679a23ead9..0e8d83018f0 100644 --- a/applications/plugins/SofaCUDA/scenes/benchmarks/QuadSpringsSphere_cpu.scn +++ b/applications/plugins/SofaCUDA/scenes/benchmarks/QuadSpringsSphere_cpu.scn @@ -1,6 +1,6 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/benchmarks/QuadSpringsSphere_gpu.scn b/applications/plugins/SofaCUDA/scenes/benchmarks/QuadSpringsSphere_gpu.scn index b6a75ba6749..04e69c0d70a 100644 --- a/applications/plugins/SofaCUDA/scenes/benchmarks/QuadSpringsSphere_gpu.scn +++ b/applications/plugins/SofaCUDA/scenes/benchmarks/QuadSpringsSphere_gpu.scn @@ -7,7 +7,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/benchmarks/TetrahedronFEMForceField_beam10x10x40_cpu.scn b/applications/plugins/SofaCUDA/scenes/benchmarks/TetrahedronFEMForceField_beam10x10x40_cpu.scn index 9582735633f..a927ece7da5 100644 --- a/applications/plugins/SofaCUDA/scenes/benchmarks/TetrahedronFEMForceField_beam10x10x40_cpu.scn +++ b/applications/plugins/SofaCUDA/scenes/benchmarks/TetrahedronFEMForceField_beam10x10x40_cpu.scn @@ -3,7 +3,7 @@ - + @@ -48,7 +48,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/benchmarks/TetrahedronFEMForceField_beam10x10x40_gpu.scn b/applications/plugins/SofaCUDA/scenes/benchmarks/TetrahedronFEMForceField_beam10x10x40_gpu.scn index 04db6e4a562..62633ccb794 100644 --- a/applications/plugins/SofaCUDA/scenes/benchmarks/TetrahedronFEMForceField_beam10x10x40_gpu.scn +++ b/applications/plugins/SofaCUDA/scenes/benchmarks/TetrahedronFEMForceField_beam10x10x40_gpu.scn @@ -10,7 +10,7 @@ - + @@ -44,7 +44,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/benchmarks/TetrahedronFEMForceField_beam16x16x76_cpu.scn b/applications/plugins/SofaCUDA/scenes/benchmarks/TetrahedronFEMForceField_beam16x16x76_cpu.scn index ff4eabb5c35..dee6efd1fca 100644 --- a/applications/plugins/SofaCUDA/scenes/benchmarks/TetrahedronFEMForceField_beam16x16x76_cpu.scn +++ b/applications/plugins/SofaCUDA/scenes/benchmarks/TetrahedronFEMForceField_beam16x16x76_cpu.scn @@ -3,7 +3,7 @@ - + @@ -49,7 +49,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/benchmarks/TetrahedronFEMForceField_beam16x16x76_gpu.scn b/applications/plugins/SofaCUDA/scenes/benchmarks/TetrahedronFEMForceField_beam16x16x76_gpu.scn index 0e5df06504b..096de16b541 100644 --- a/applications/plugins/SofaCUDA/scenes/benchmarks/TetrahedronFEMForceField_beam16x16x76_gpu.scn +++ b/applications/plugins/SofaCUDA/scenes/benchmarks/TetrahedronFEMForceField_beam16x16x76_gpu.scn @@ -12,7 +12,7 @@ - + @@ -45,7 +45,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/benchmarks/TriangularFEMForceFieldOptim_tissue100x100_cpu.scn b/applications/plugins/SofaCUDA/scenes/benchmarks/TriangularFEMForceFieldOptim_tissue100x100_cpu.scn index b5e3b8c6510..9aa2db094bd 100644 --- a/applications/plugins/SofaCUDA/scenes/benchmarks/TriangularFEMForceFieldOptim_tissue100x100_cpu.scn +++ b/applications/plugins/SofaCUDA/scenes/benchmarks/TriangularFEMForceFieldOptim_tissue100x100_cpu.scn @@ -3,7 +3,7 @@ - + @@ -37,7 +37,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/benchmarks/TriangularFEMForceFieldOptim_tissue100x100_gpu.scn b/applications/plugins/SofaCUDA/scenes/benchmarks/TriangularFEMForceFieldOptim_tissue100x100_gpu.scn index a8e58525301..437e8d591a1 100644 --- a/applications/plugins/SofaCUDA/scenes/benchmarks/TriangularFEMForceFieldOptim_tissue100x100_gpu.scn +++ b/applications/plugins/SofaCUDA/scenes/benchmarks/TriangularFEMForceFieldOptim_tissue100x100_gpu.scn @@ -9,7 +9,7 @@ - + @@ -34,7 +34,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaHexahedronFEMForceField_beam10x10x40_implicit.scn b/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaHexahedronFEMForceField_beam10x10x40_implicit.scn index 1d5b9a9ede3..718ffb9e7bc 100644 --- a/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaHexahedronFEMForceField_beam10x10x40_implicit.scn +++ b/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaHexahedronFEMForceField_beam10x10x40_implicit.scn @@ -3,7 +3,7 @@ - + @@ -16,7 +16,7 @@ - + @@ -40,7 +40,7 @@ - + @@ -69,7 +69,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaHexahedronFEMForceField_beam10x10x40_rk4.scn b/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaHexahedronFEMForceField_beam10x10x40_rk4.scn index 58965778e86..b8076ed393b 100644 --- a/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaHexahedronFEMForceField_beam10x10x40_rk4.scn +++ b/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaHexahedronFEMForceField_beam10x10x40_rk4.scn @@ -3,7 +3,7 @@ - + @@ -15,7 +15,7 @@ - + @@ -38,7 +38,7 @@ - + @@ -66,7 +66,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaMeshSpringForceField_beam10x10x40_implicit.scn b/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaMeshSpringForceField_beam10x10x40_implicit.scn index 8fba50c8a84..e584d442fb7 100644 --- a/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaMeshSpringForceField_beam10x10x40_implicit.scn +++ b/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaMeshSpringForceField_beam10x10x40_implicit.scn @@ -3,7 +3,7 @@ - + @@ -16,7 +16,7 @@ - + @@ -45,7 +45,7 @@ - + @@ -65,7 +65,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaMeshSpringForceField_beam10x10x40_rk4.scn b/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaMeshSpringForceField_beam10x10x40_rk4.scn index 80cf963b23a..dce457e8680 100644 --- a/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaMeshSpringForceField_beam10x10x40_rk4.scn +++ b/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaMeshSpringForceField_beam10x10x40_rk4.scn @@ -3,7 +3,7 @@ - + @@ -15,7 +15,7 @@ - + @@ -43,7 +43,7 @@ - + @@ -62,7 +62,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaTetrahedronFEMForceField_beam10x10x40_implicit.scn b/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaTetrahedronFEMForceField_beam10x10x40_implicit.scn index 35e427802eb..c44f740e076 100644 --- a/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaTetrahedronFEMForceField_beam10x10x40_implicit.scn +++ b/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaTetrahedronFEMForceField_beam10x10x40_implicit.scn @@ -3,7 +3,7 @@ - + @@ -16,7 +16,7 @@ - + @@ -49,7 +49,7 @@ - + @@ -79,7 +79,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaTetrahedronFEMForceField_beam10x10x40_rk4.scn b/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaTetrahedronFEMForceField_beam10x10x40_rk4.scn index 02270abfece..1a5df4ad730 100644 --- a/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaTetrahedronFEMForceField_beam10x10x40_rk4.scn +++ b/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaTetrahedronFEMForceField_beam10x10x40_rk4.scn @@ -3,7 +3,7 @@ - + @@ -15,7 +15,7 @@ - + @@ -47,7 +47,7 @@ - + @@ -76,7 +76,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaTriangularFEMForceFieldOptim_tissue100x100_implicit.scn b/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaTriangularFEMForceFieldOptim_tissue100x100_implicit.scn index cbf2b07201e..e02a3548e2a 100644 --- a/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaTriangularFEMForceFieldOptim_tissue100x100_implicit.scn +++ b/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaTriangularFEMForceFieldOptim_tissue100x100_implicit.scn @@ -3,7 +3,7 @@ - + @@ -14,7 +14,7 @@ - + @@ -39,7 +39,7 @@ - + @@ -61,7 +61,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaTriangularFEMForceFieldOptim_tissue20x20_implicit.scn b/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaTriangularFEMForceFieldOptim_tissue20x20_implicit.scn index 51687ad146c..7d5e1e5f69a 100644 --- a/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaTriangularFEMForceFieldOptim_tissue20x20_implicit.scn +++ b/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/CudaTriangularFEMForceFieldOptim_tissue20x20_implicit.scn @@ -3,7 +3,7 @@ - + @@ -14,7 +14,7 @@ - + @@ -39,7 +39,7 @@ - + @@ -61,7 +61,7 @@ - + diff --git a/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/QuadSpringsSphere.scn b/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/QuadSpringsSphere.scn index b974d155a30..9d0f01b6e19 100644 --- a/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/QuadSpringsSphere.scn +++ b/applications/plugins/SofaCUDA/scenes/cpu-gpu_validation/QuadSpringsSphere.scn @@ -1,6 +1,6 @@ - + @@ -12,7 +12,7 @@ - + diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/lagrangian/model/CudaBilateralInteractionConstraint.cpp b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/lagrangian/model/CudaBilateralLagrangianConstraint.cpp similarity index 72% rename from applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/lagrangian/model/CudaBilateralInteractionConstraint.cpp rename to applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/lagrangian/model/CudaBilateralLagrangianConstraint.cpp index b0486fe7930..c014599a76f 100644 --- a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/lagrangian/model/CudaBilateralInteractionConstraint.cpp +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/lagrangian/model/CudaBilateralLagrangianConstraint.cpp @@ -21,18 +21,18 @@ ******************************************************************************/ #include #include -#include +#include #include namespace sofa::component::constraint::lagrangian::model { -template class SOFA_GPU_CUDA_API BilateralInteractionConstraint; -template class SOFA_GPU_CUDA_API BilateralInteractionConstraint; +template class SOFA_GPU_CUDA_API BilateralLagrangianConstraint; +template class SOFA_GPU_CUDA_API BilateralLagrangianConstraint; #ifdef SOFA_GPU_CUDA_DOUBLE -template class SOFA_GPU_CUDA_API BilateralInteractionConstraint; -template class SOFA_GPU_CUDA_API BilateralInteractionConstraint; +template class SOFA_GPU_CUDA_API BilateralLagrangianConstraint; +template class SOFA_GPU_CUDA_API BilateralLagrangianConstraint; #endif // SOFA_GPU_CUDA_DOUBLE } //namespace sofa::component::constraint::lagrangian::model @@ -42,12 +42,12 @@ namespace sofa::gpu::cuda using namespace sofa::component::constraint::lagrangian::model; -int BilateralInteractionConstraintCudaClass = core::RegisterObject("Supports GPU-side computations using CUDA") - .add< BilateralInteractionConstraint >() - .add< BilateralInteractionConstraint >() +int BilateralLagrangianConstraintCudaClass = core::RegisterObject("Supports GPU-side computations using CUDA") + .add< BilateralLagrangianConstraint >() + .add< BilateralLagrangianConstraint >() #ifdef SOFA_GPU_CUDA_DOUBLE - .add< BilateralInteractionConstraint >() - .add< BilateralInteractionConstraint >() + .add< BilateralLagrangianConstraint >() + .add< BilateralLagrangianConstraint >() #endif // SOFA_GPU_CUDA_DOUBLE ; } // namespace sofa::gpu::cuda diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedConstraint.cu b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedConstraint.cu deleted file mode 100644 index b193ef8ef77..00000000000 --- a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedConstraint.cu +++ /dev/null @@ -1,223 +0,0 @@ -/****************************************************************************** -* SOFA, Simulation Open-Framework Architecture * -* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * -* * -* This program is free software; you can redistribute it and/or modify it * -* under the terms of the GNU Lesser General Public License as published by * -* the Free Software Foundation; either version 2.1 of the License, or (at * -* your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, but WITHOUT * -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * -* for more details. * -* * -* You should have received a copy of the GNU Lesser General Public License * -* along with this program. If not, see . * -******************************************************************************* -* Authors: The SOFA Team and external contributors (see Authors.txt) * -* * -* Contact information: contact@sofa-framework.org * -******************************************************************************/ -#include -#include -#include "cuda.h" -#include - -#if defined(__cplusplus) && CUDA_VERSION < 2000 -namespace sofa -{ -namespace gpu -{ -namespace cuda -{ -#endif - -extern "C" -{ - void FixedConstraintCuda1f_projectResponseContiguous(unsigned int size, void* dx); - void FixedConstraintCuda1f_projectResponseIndexed(unsigned int size, const void* indices, void* dx); - void FixedConstraintCuda3f_projectResponseContiguous(unsigned int size, void* dx); - void FixedConstraintCuda3f_projectResponseIndexed(unsigned int size, const void* indices, void* dx); - void FixedConstraintCuda3f1_projectResponseContiguous(unsigned int size, void* dx); - void FixedConstraintCuda3f1_projectResponseIndexed(unsigned int size, const void* indices, void* dx); - void FixedConstraintCudaRigid3f_projectResponseContiguous(unsigned int size, void* dx); - void FixedConstraintCudaRigid3f_projectResponseIndexed(unsigned int size, const void* indices, void* dx); - -#ifdef SOFA_GPU_CUDA_DOUBLE - - void FixedConstraintCuda3d_projectResponseContiguous(unsigned int size, void* dx); - void FixedConstraintCuda3d_projectResponseIndexed(unsigned int size, const void* indices, void* dx); - void FixedConstraintCuda3d1_projectResponseContiguous(unsigned int size, void* dx); - void FixedConstraintCuda3d1_projectResponseIndexed(unsigned int size, const void* indices, void* dx); - void FixedConstraintCudaRigid3d_projectResponseContiguous(unsigned int size, void* dx); - void FixedConstraintCudaRigid3d_projectResponseIndexed(unsigned int size, const void* indices, void* dx); - -#endif // SOFA_GPU_CUDA_DOUBLE -} - -////////////////////// -// GPU-side methods // -////////////////////// - -template -__global__ void FixedConstraintCuda1t_projectResponseContiguous_kernel(int size, real* dx) -{ - int index = blockIdx.x * BSIZE+threadIdx.x; - if (index < size) - dx[index] = 0.0f; -} - -template -__global__ void FixedConstraintCuda3t_projectResponseContiguous_kernel(int size, CudaVec3* dx) -{ - int index = blockIdx.x * BSIZE+threadIdx.x; - if (index < size) - dx[index] = CudaVec3::make(0.0f,0.0f,0.0f); -} - -template -__global__ void FixedConstraintCuda3t1_projectResponseContiguous_kernel(int size, CudaVec4* dx) -{ - int index = blockIdx.x * BSIZE+threadIdx.x; - if (index < size) - dx[index] = CudaVec4::make(0.0f,0.0f,0.0f,0.0f); -} - -template -__global__ void FixedConstraintCudaRigid3t_projectResponseContiguous_kernel(int size, CudaRigidDeriv3* dx) -{ - int index = blockIdx.x * BSIZE+threadIdx.x; - if (index < size) - dx[index] = CudaRigidDeriv3::make(0.0f,0.0f,0.0f,0.0f,0.0f,0.0f); -} - -template -__global__ void FixedConstraintCuda1t_projectResponseIndexed_kernel(int size, const int* indices, real* dx) -{ - int index = blockIdx.x * BSIZE+threadIdx.x; - if (index < size) - dx[indices[index]] = 0.0f; -} - -template -__global__ void FixedConstraintCuda3t_projectResponseIndexed_kernel(int size, const int* indices, CudaVec3* dx) -{ - int index = blockIdx.x * BSIZE+threadIdx.x; - if (index < size) - dx[indices[index]] = CudaVec3::make(0.0f,0.0f,0.0f); -} - -template -__global__ void FixedConstraintCuda3t1_projectResponseIndexed_kernel(int size, const int* indices, CudaVec4* dx) -{ - int index = blockIdx.x * BSIZE+threadIdx.x; - if (index < size) - dx[indices[index]] = CudaVec4::make(0.0f,0.0f,0.0f,0.0f); -} - -template -__global__ void FixedConstraintCudaRigid3t_projectResponseIndexed_kernel(int size, const int* indices, CudaRigidDeriv3* dx) -{ - int index = blockIdx.x * BSIZE+threadIdx.x; - if (index < size) - dx[indices[index]] = CudaRigidDeriv3::make(0.0f,0.0f,0.0f,0.0f,0.0f,0.0f); -} - -////////////////////// -// CPU-side methods // -////////////////////// - -void FixedConstraintCuda1f_projectResponseContiguous(unsigned int size, void* dx) -{ - cudaMemset(dx, 0, size*sizeof(float)); -} - -void FixedConstraintCuda3f_projectResponseContiguous(unsigned int size, void* dx) -{ - cudaMemset(dx, 0, size*3*sizeof(float)); -} - -void FixedConstraintCuda3f1_projectResponseContiguous(unsigned int size, void* dx) -{ - cudaMemset(dx, 0, size*4*sizeof(float)); -} - -void FixedConstraintCudaRigid3f_projectResponseContiguous(unsigned int size, void* dx) -{ - cudaMemset(dx, 0, size*6*sizeof(float)); -} - -void FixedConstraintCuda1f_projectResponseIndexed(unsigned int size, const void* indices, void* dx) -{ - dim3 threads(BSIZE,1); - dim3 grid((size+BSIZE-1)/BSIZE,1); - {FixedConstraintCuda1t_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (float*)dx); mycudaDebugError("FixedConstraintCuda1t_projectResponseIndexed_kernel");} -} - -void FixedConstraintCuda3f_projectResponseIndexed(unsigned int size, const void* indices, void* dx) -{ - dim3 threads(BSIZE,1); - dim3 grid((size+BSIZE-1)/BSIZE,1); - {FixedConstraintCuda3t_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaVec3*)dx); mycudaDebugError("FixedConstraintCuda3t_projectResponseIndexed_kernel");} -} - -void FixedConstraintCuda3f1_projectResponseIndexed(unsigned int size, const void* indices, void* dx) -{ - dim3 threads(BSIZE,1); - dim3 grid((size+BSIZE-1)/BSIZE,1); - {FixedConstraintCuda3t1_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaVec4*)dx); mycudaDebugError("FixedConstraintCuda3t1_projectResponseIndexed_kernel");} -} - -void FixedConstraintCudaRigid3f_projectResponseIndexed(unsigned int size, const void* indices, void* dx) -{ - dim3 threads(BSIZE,1); - dim3 grid((size+BSIZE-1)/BSIZE,1); - {FixedConstraintCudaRigid3t_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaRigidDeriv3*)dx); mycudaDebugError("FixedConstraintCudaRigid3t_projectResponseIndexed_kernel");} -} - -#ifdef SOFA_GPU_CUDA_DOUBLE - -void FixedConstraintCuda3d_projectResponseContiguous(unsigned int size, void* dx) -{ - cudaMemset(dx, 0, size*3*sizeof(double)); -} - -void FixedConstraintCuda3d1_projectResponseContiguous(unsigned int size, void* dx) -{ - cudaMemset(dx, 0, size*4*sizeof(double)); -} - -void FixedConstraintCudaRigid3d_projectResponseContiguous(unsigned int size, void* dx) -{ - cudaMemset(dx, 0, size*6*sizeof(double)); -} - -void FixedConstraintCuda3d_projectResponseIndexed(unsigned int size, const void* indices, void* dx) -{ - dim3 threads(BSIZE,1); - dim3 grid((size+BSIZE-1)/BSIZE,1); - {FixedConstraintCuda3t_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaVec3*)dx); mycudaDebugError("FixedConstraintCuda3t_projectResponseIndexed_kernel");} -} - -void FixedConstraintCuda3d1_projectResponseIndexed(unsigned int size, const void* indices, void* dx) -{ - dim3 threads(BSIZE,1); - dim3 grid((size+BSIZE-1)/BSIZE,1); - {FixedConstraintCuda3t1_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaVec4*)dx); mycudaDebugError("FixedConstraintCuda3t1_projectResponseIndexed_kernel");} -} - -void FixedConstraintCudaRigid3d_projectResponseIndexed(unsigned int size, const void* indices, void* dx) -{ - dim3 threads(BSIZE,1); - dim3 grid((size+BSIZE-1)/BSIZE,1); - {FixedConstraintCudaRigid3t_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaRigidDeriv3*)dx); mycudaDebugError("FixedConstraintCudaRigid3t_projectResponseIndexed_kernel");} -} - -#endif // SOFA_GPU_CUDA_DOUBLE - -#if defined(__cplusplus) && CUDA_VERSION < 2000 -} // namespace cuda -} // namespace gpu -} // namespace sofa -#endif diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedConstraint.h b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedConstraint.h index 15e27ce1a2a..f92c6941f62 100644 --- a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedConstraint.h +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedConstraint.h @@ -21,91 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include +#include -namespace sofa::component::constraint::projective -{ - -template -class FixedConstraintInternalData< gpu::cuda::CudaVectorTypes > -{ -public: - using Index = sofa::Index; - typedef FixedConstraintInternalData< gpu::cuda::CudaVectorTypes > Data; - typedef gpu::cuda::CudaVectorTypes DataTypes; - typedef FixedConstraint Main; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::Real Real; - typedef typename Main::SetIndex SetIndex; - typedef typename Main::SetIndexArray SetIndexArray; - - // min/max fixed indices for contiguous constraints - Index minIndex; - Index maxIndex; - // vector of indices for general case - gpu::cuda::CudaVector cudaIndices; - - - static void init(Main* m); - - static void addConstraint(Main* m, Index index); - - static void removeConstraint(Main* m, Index index); - - static void projectResponse(Main* m, VecDeriv& dx); -}; - -template -class FixedConstraintInternalData< gpu::cuda::CudaRigidTypes > -{ -public: - using Index = sofa::Index; - typedef FixedConstraintInternalData< gpu::cuda::CudaRigidTypes > Data; - typedef gpu::cuda::CudaRigidTypes DataTypes; - typedef FixedConstraint Main; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::Real Real; - typedef typename Main::SetIndex SetIndex; - typedef typename Main::SetIndexArray SetIndexArray; - - // min/max fixed indices for contiguous constraints - Index minIndex; - Index maxIndex; - // vector of indices for general case - gpu::cuda::CudaVector cudaIndices; - - - static void init(Main* m); - - static void addConstraint(Main* m, Index index); - - static void removeConstraint(Main* m, Index index); - - static void projectResponse(Main* m, VecDeriv& dx); -}; - -// I know using macros is bad design but this is the only way not to repeat the code for all CUDA types -#define CudaFixedConstraint_DeclMethods(T) \ - template<> void FixedConstraint< T >::init(); \ - template<> void FixedConstraint< T >::addConstraint(Index index); \ - template<> void FixedConstraint< T >::removeConstraint(Index index); \ - template<> void FixedConstraint< T >::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData); - -CudaFixedConstraint_DeclMethods(gpu::cuda::CudaVec3fTypes); -CudaFixedConstraint_DeclMethods(gpu::cuda::CudaVec3f1Types); -CudaFixedConstraint_DeclMethods(gpu::cuda::CudaRigid3fTypes); - -#ifdef SOFA_GPU_CUDA_DOUBLE - -CudaFixedConstraint_DeclMethods(gpu::cuda::CudaVec3dTypes); -CudaFixedConstraint_DeclMethods(gpu::cuda::CudaVec3d1Types); -CudaFixedConstraint_DeclMethods(gpu::cuda::CudaRigid3dTypes); - -#endif // SOFA_GPU_CUDA_DOUBLE - -#undef CudaFixedConstraint_DeclMethods - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v23.12", "v24.12", "SofaCUDA/component/constraint/projective/CudaFixedProjectiveConstraint.h") diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedConstraint.inl b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedConstraint.inl index 1054b5a3784..95ad8d25985 100644 --- a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedConstraint.inl +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedConstraint.inl @@ -21,433 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include +#include -namespace sofa::gpu::cuda -{ - -extern "C" -{ - void FixedConstraintCuda1f_projectResponseContiguous(unsigned int size, void* dx); - void FixedConstraintCuda1f_projectResponseIndexed(unsigned int size, const void* indices, void* dx); - void FixedConstraintCuda3f_projectResponseContiguous(unsigned int size, void* dx); - void FixedConstraintCuda3f_projectResponseIndexed(unsigned int size, const void* indices, void* dx); - void FixedConstraintCuda3f1_projectResponseContiguous(unsigned int size, void* dx); - void FixedConstraintCuda3f1_projectResponseIndexed(unsigned int size, const void* indices, void* dx); - void FixedConstraintCudaRigid3f_projectResponseContiguous(unsigned int size, void* dx); - void FixedConstraintCudaRigid3f_projectResponseIndexed(unsigned int size, const void* indices, void* dx); - -#ifdef SOFA_GPU_CUDA_DOUBLE - - void FixedConstraintCuda3d_projectResponseContiguous(unsigned int size, void* dx); - void FixedConstraintCuda3d_projectResponseIndexed(unsigned int size, const void* indices, void* dx); - void FixedConstraintCuda3d1_projectResponseContiguous(unsigned int size, void* dx); - void FixedConstraintCuda3d1_projectResponseIndexed(unsigned int size, const void* indices, void* dx); - void FixedConstraintCudaRigid3d_projectResponseContiguous(unsigned int size, void* dx); - void FixedConstraintCudaRigid3d_projectResponseIndexed(unsigned int size, const void* indices, void* dx); - -#endif // SOFA_GPU_CUDA_DOUBLE -} - -} // namespace sofa::gpu::cuda - -namespace sofa::component::constraint::projective -{ - -using namespace gpu::cuda; - -template -void FixedConstraintInternalData< gpu::cuda::CudaVectorTypes >::init(Main* m) -{ - Data& data = *m->data; - data.minIndex = sofa::InvalidID; - data.maxIndex = sofa::InvalidID; - data.cudaIndices.clear(); - m->core::behavior::template ProjectiveConstraintSet::init(); - const SetIndexArray& indices = m->d_indices.getValue(); - if (!indices.empty()) - { - // put indices in a set to sort them and remove duplicates - std::set sortedIndices; - for (typename SetIndex::const_iterator it = indices.begin(); it!=indices.end(); ++it) - sortedIndices.insert(*it); - // check if the indices are contiguous - if (*sortedIndices.begin() + (int)sortedIndices.size()-1 == *sortedIndices.rbegin()) - { - data.minIndex = *sortedIndices.begin(); - data.maxIndex = *sortedIndices.rbegin(); - msg_info("CudaFixedConstraint") << "init: " << sortedIndices.size() << " contiguous fixed indices, " << data.minIndex << " - " << data.maxIndex; - } - else - { - msg_info("CudaFixedConstraint") << "init: " << sortedIndices.size() << " non-contiguous fixed indices"; - data.cudaIndices.reserve(sortedIndices.size()); - for (std::set::const_iterator it = sortedIndices.begin(); it!=sortedIndices.end(); ++it) - data.cudaIndices.push_back(*it); - } - } - - m->d_componentState.setValue(ComponentState::Valid); -} - -template -void FixedConstraintInternalData< gpu::cuda::CudaVectorTypes >::addConstraint(Main* m, Index index) -{ - Data& data = *m->data; - //std::cout << "CudaFixedConstraint::addConstraint("<d_indices.beginEdit()->push_back(index); - m->d_indices.endEdit(); - if (data.cudaIndices.empty()) - { - if (data.minIndex == sofa::InvalidID) - { - //std::cout << "CudaFixedConstraint: single index "<= data.minIndex && index <= data.maxIndex) - { - // point already fixed - } - else if (data.minIndex == index + 1) - { - data.minIndex = index; - //std::cout << "CudaFixedConstraint: new min index "< -void FixedConstraintInternalData< gpu::cuda::CudaVectorTypes >::removeConstraint(Main* m, Index index) -{ - Data& data = *m->data; - removeValue(*m->d_indices.beginEdit(),index); - m->d_indices.endEdit(); - if (data.cudaIndices.empty()) - { - if (data.minIndex <= index && index <= data.maxIndex) - { - if (data.minIndex == index) - { - if (data.maxIndex == index) - { - // empty set - data.minIndex = sofa::InvalidID; - data.maxIndex = sofa::InvalidID; - } - else - ++data.minIndex; - } - else if (data.maxIndex == index) - --data.maxIndex; - else - { - data.cudaIndices.reserve(data.maxIndex-data.minIndex); - for (int i=data.minIndex; i -void FixedConstraintInternalData< gpu::cuda::CudaRigidTypes >::init(Main* m) -{ - Data& data = *m->data; - data.minIndex = sofa::InvalidID; - data.maxIndex = sofa::InvalidID; - data.cudaIndices.clear(); - m->core::behavior::template ProjectiveConstraintSet::init(); - const SetIndexArray& indices = m->d_indices.getValue(); - if (!indices.empty()) - { - // put indices in a set to sort them and remove duplicates - std::set sortedIndices; - for (typename SetIndex::const_iterator it = indices.begin(); it!=indices.end(); ++it) - sortedIndices.insert(*it); - // check if the indices are contiguous - if (*sortedIndices.begin() + (int)sortedIndices.size()-1 == *sortedIndices.rbegin()) - { - data.minIndex = *sortedIndices.begin(); - data.maxIndex = *sortedIndices.rbegin(); - msg_info("CudaFixedConstraint") << "init: " << sortedIndices.size() << " contiguous fixed indices, " << data.minIndex << " - " << data.maxIndex; - } - else - { - msg_info("CudaFixedConstraint") << "init: " << sortedIndices.size() << " non-contiguous fixed indices"; - data.cudaIndices.reserve(sortedIndices.size()); - for (std::set::const_iterator it = sortedIndices.begin(); it!=sortedIndices.end(); ++it) - data.cudaIndices.push_back(*it); - } - } - - m->d_componentState.setValue(ComponentState::Valid); -} - -template -void FixedConstraintInternalData< gpu::cuda::CudaRigidTypes >::addConstraint(Main* m, Index index) -{ - Data& data = *m->data; - //std::cout << "CudaFixedConstraint::addConstraint("<d_indices.beginEdit()->push_back(index); - m->d_indices.endEdit(); - if (data.cudaIndices.empty()) - { - if (data.minIndex == sofa::InvalidID) - { - //std::cout << "CudaFixedConstraint: single index "<= data.minIndex && index <= data.maxIndex) - { - // point already fixed - } - else if (data.minIndex == index+1) - { - data.minIndex = index; - //std::cout << "CudaFixedConstraint: new min index "< -void FixedConstraintInternalData< gpu::cuda::CudaRigidTypes >::removeConstraint(Main* m, Index index) -{ - Data& data = *m->data; - removeValue(*m->d_indices.beginEdit(),index); - m->d_indices.endEdit(); - if (data.cudaIndices.empty()) - { - if (data.minIndex <= index && index <= data.maxIndex) - { - if (data.minIndex == index) - { - if (data.maxIndex == index) - { - // empty set - data.minIndex = sofa::InvalidID; - data.maxIndex = sofa::InvalidID; - } - else - ++data.minIndex; - } - else if (data.maxIndex == index) - --data.maxIndex; - else - { - data.cudaIndices.reserve(data.maxIndex-data.minIndex); - for (int i=data.minIndex; i -void FixedConstraintInternalData::projectResponse(Main* m, VecDeriv& dx) -{ - const Data& data = *m->data; - if (m->d_fixAll.getValue()) - FixedConstraintCuda1f_projectResponseContiguous(dx.size(), ((float*)dx.deviceWrite())); - else if (data.minIndex >= 0) - FixedConstraintCuda1f_projectResponseContiguous(data.maxIndex-data.minIndex+1, ((float*)dx.deviceWrite())+data.minIndex); - else - FixedConstraintCuda1f_projectResponseIndexed(data.cudaIndices.size(), data.cudaIndices.deviceRead(), dx.deviceWrite()); -} - - -template <> -void FixedConstraintInternalData::projectResponse(Main* m, VecDeriv& dx) -{ - const Data& data = *m->data; - if (m->d_fixAll.getValue()) - FixedConstraintCuda3f_projectResponseContiguous(dx.size(), ((float*)dx.deviceWrite())); - else if (data.minIndex != sofa::InvalidID) - FixedConstraintCuda3f_projectResponseContiguous(data.maxIndex - data.minIndex + 1, ((float*)dx.deviceWrite()) + 3 * data.minIndex); - else - FixedConstraintCuda3f_projectResponseIndexed(data.cudaIndices.size(), data.cudaIndices.deviceRead(), dx.deviceWrite()); -} - - -template <> -void FixedConstraintInternalData::projectResponse(Main* m, VecDeriv& dx) -{ - const Data& data = *m->data; - if (m->d_fixAll.getValue()) - FixedConstraintCuda3f1_projectResponseContiguous(dx.size(), ((float*)dx.deviceWrite())); - else if (data.minIndex != sofa::InvalidID) - FixedConstraintCuda3f1_projectResponseContiguous(data.maxIndex-data.minIndex+1, ((float*)dx.deviceWrite())+4*data.minIndex); - else - FixedConstraintCuda3f1_projectResponseIndexed(data.cudaIndices.size(), data.cudaIndices.deviceRead(), dx.deviceWrite()); -} - -template <> -void FixedConstraintInternalData::projectResponse(Main* m, VecDeriv& dx) -{ - const Data& data = *m->data; - if (m->d_fixAll.getValue()) - FixedConstraintCudaRigid3f_projectResponseContiguous(dx.size(), ((float*)dx.deviceWrite())); - else if (data.minIndex != sofa::InvalidID) - FixedConstraintCudaRigid3f_projectResponseContiguous(data.maxIndex-data.minIndex+1, ((float*)dx.deviceWrite())+6*data.minIndex); - else - FixedConstraintCudaRigid3f_projectResponseIndexed(data.cudaIndices.size(), data.cudaIndices.deviceRead(), dx.deviceWrite()); -} - - - -#ifdef SOFA_GPU_CUDA_DOUBLE - -// // Handle topological changes -// template <> -// void FixedConstraint::handleTopologyChange() { -// // std::list::const_iterator itBegin=topology->firstChange(); -// // std::list::const_iterator itEnd=topology->lastChange(); -// // -// // d_indices.beginEdit()->handleTopologyEvents(itBegin,itEnd,this->getMState()->getSize()); -// //printf("WARNING handleTopologyChange not implemented\n"); -// } - -template <> -void FixedConstraintInternalData::projectResponse(Main* m, VecDeriv& dx) -{ - Data& data = *m->data; - if (m->d_fixAll.getValue()) - FixedConstraintCuda3d_projectResponseContiguous(dx.size(), ((double*)dx.deviceWrite())); - else if (data.minIndex >= 0) - FixedConstraintCuda3d_projectResponseContiguous(data.maxIndex-data.minIndex+1, ((double*)dx.deviceWrite())+3*data.minIndex); - else - FixedConstraintCuda3d_projectResponseIndexed(data.cudaIndices.size(), data.cudaIndices.deviceRead(), dx.deviceWrite()); -} - -template <> -void FixedConstraintInternalData::projectResponse(Main* m, VecDeriv& dx) -{ - Data& data = *m->data; - if (m->d_fixAll.getValue()) - FixedConstraintCuda3d1_projectResponseContiguous(dx.size(), ((double*)dx.deviceWrite())); - else if (data.minIndex >= 0) - FixedConstraintCuda3d1_projectResponseContiguous(data.maxIndex-data.minIndex+1, ((double*)dx.deviceWrite())+4*data.minIndex); - else - FixedConstraintCuda3d1_projectResponseIndexed(data.cudaIndices.size(), data.cudaIndices.deviceRead(), dx.deviceWrite()); -} - -template <> -void FixedConstraintInternalData::projectResponse(Main* m, VecDeriv& dx) -{ - Data& data = *m->data; - if (m->d_fixAll.getValue()) - FixedConstraintCudaRigid3d_projectResponseContiguous(dx.size(), ((double*)dx.deviceWrite())); - else if (data.minIndex >= 0) - FixedConstraintCudaRigid3d_projectResponseContiguous(data.maxIndex-data.minIndex+1, ((double*)dx.deviceWrite())+6*data.minIndex); - else - FixedConstraintCudaRigid3d_projectResponseIndexed(data.cudaIndices.size(), data.cudaIndices.deviceRead(), dx.deviceWrite()); -} - -#endif // SOFA_GPU_CUDA_DOUBLE - -// I know using macros is bad design but this is the only way not to repeat the code for all CUDA types -#define CudaFixedConstraint_ImplMethods(T) \ - template<> void FixedConstraint< T >::init() \ - { data->init(this); } \ - template<> void FixedConstraint< T >::addConstraint(Index index) \ - { data->addConstraint(this, index); } \ - template<> void FixedConstraint< T >::removeConstraint(Index index) \ - { data->removeConstraint(this, index); } \ - template<> void FixedConstraint< T >::projectResponse(const core::MechanicalParams* /* mparams */, DataVecDeriv& d_resData) \ - { \ - VecDeriv &resData = *d_resData.beginEdit(); \ - data->projectResponse(this, resData); \ - d_resData.endEdit(); \ - } - -CudaFixedConstraint_ImplMethods(gpu::cuda::CudaVec3fTypes); -CudaFixedConstraint_ImplMethods(gpu::cuda::CudaVec3f1Types); -CudaFixedConstraint_ImplMethods(gpu::cuda::CudaRigid3fTypes); - -#ifdef SOFA_GPU_CUDA_DOUBLE - -CudaFixedConstraint_ImplMethods(gpu::cuda::CudaVec3dTypes); -CudaFixedConstraint_ImplMethods(gpu::cuda::CudaVec3d1Types); -CudaFixedConstraint_ImplMethods(gpu::cuda::CudaRigid3dTypes); - -#endif // SOFA_GPU_CUDA_DOUBLE - -#undef CudaFixedConstraint_ImplMethods - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v23.12", "v24.12", "SofaCUDA/component/constraint/projective/CudaFixedProjectiveConstraint.inl") diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedConstraint.cpp b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedProjectiveConstraint.cpp similarity index 54% rename from applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedConstraint.cpp rename to applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedProjectiveConstraint.cpp index eb3455d6c04..0384749ab2c 100644 --- a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedConstraint.cpp +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedProjectiveConstraint.cpp @@ -20,7 +20,7 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #include -#include +#include #include #include #include @@ -29,17 +29,17 @@ namespace sofa::component::constraint::projective { -template class SOFA_GPU_CUDA_API FixedConstraint; +template class SOFA_GPU_CUDA_API FixedProjectiveConstraint; -template class SOFA_GPU_CUDA_API FixedConstraint; -template class SOFA_GPU_CUDA_API FixedConstraint; -template class SOFA_GPU_CUDA_API FixedConstraint; -template class SOFA_GPU_CUDA_API FixedConstraint; +template class SOFA_GPU_CUDA_API FixedProjectiveConstraint; +template class SOFA_GPU_CUDA_API FixedProjectiveConstraint; +template class SOFA_GPU_CUDA_API FixedProjectiveConstraint; +template class SOFA_GPU_CUDA_API FixedProjectiveConstraint; #ifdef SOFA_GPU_CUDA_DOUBLE -template class SOFA_GPU_CUDA_API FixedConstraint; -template class SOFA_GPU_CUDA_API FixedConstraint; -template class SOFA_GPU_CUDA_API FixedConstraint; -template class SOFA_GPU_CUDA_API FixedConstraint; +template class SOFA_GPU_CUDA_API FixedProjectiveConstraint; +template class SOFA_GPU_CUDA_API FixedProjectiveConstraint; +template class SOFA_GPU_CUDA_API FixedProjectiveConstraint; +template class SOFA_GPU_CUDA_API FixedProjectiveConstraint; #endif // SOFA_GPU_CUDA_DOUBLE } // namespace sofa::component::constraint::projective @@ -47,17 +47,17 @@ template class SOFA_GPU_CUDA_API FixedConstraint; namespace sofa::gpu::cuda { -int FixedConstraintCudaClass = core::RegisterObject("Supports GPU-side computations using CUDA") - .add< component::constraint::projective::FixedConstraint >() - .add< component::constraint::projective::FixedConstraint >() - .add< component::constraint::projective::FixedConstraint >() - .add< component::constraint::projective::FixedConstraint >() - .add< component::constraint::projective::FixedConstraint >() +int FixedProjectiveConstraintCudaClass = core::RegisterObject("Supports GPU-side computations using CUDA") + .add< component::constraint::projective::FixedProjectiveConstraint >() + .add< component::constraint::projective::FixedProjectiveConstraint >() + .add< component::constraint::projective::FixedProjectiveConstraint >() + .add< component::constraint::projective::FixedProjectiveConstraint >() + .add< component::constraint::projective::FixedProjectiveConstraint >() #ifdef SOFA_GPU_CUDA_DOUBLE - .add< component::constraint::projective::FixedConstraint >() - .add< component::constraint::projective::FixedConstraint >() - .add< component::constraint::projective::FixedConstraint >() - .add< component::constraint::projective::FixedConstraint >() + .add< component::constraint::projective::FixedProjectiveConstraint >() + .add< component::constraint::projective::FixedProjectiveConstraint >() + .add< component::constraint::projective::FixedProjectiveConstraint >() + .add< component::constraint::projective::FixedProjectiveConstraint >() #endif // SOFA_GPU_CUDA_DOUBLE ; diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedProjectiveConstraint.cu b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedProjectiveConstraint.cu new file mode 100644 index 00000000000..24a7dd330c2 --- /dev/null +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedProjectiveConstraint.cu @@ -0,0 +1,223 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#include +#include +#include "cuda.h" +#include + +#if defined(__cplusplus) && CUDA_VERSION < 2000 +namespace sofa +{ +namespace gpu +{ +namespace cuda +{ +#endif + +extern "C" +{ + void FixedProjectiveConstraintCuda1f_projectResponseContiguous(unsigned int size, void* dx); + void FixedProjectiveConstraintCuda1f_projectResponseIndexed(unsigned int size, const void* indices, void* dx); + void FixedProjectiveConstraintCuda3f_projectResponseContiguous(unsigned int size, void* dx); + void FixedProjectiveConstraintCuda3f_projectResponseIndexed(unsigned int size, const void* indices, void* dx); + void FixedProjectiveConstraintCuda3f1_projectResponseContiguous(unsigned int size, void* dx); + void FixedProjectiveConstraintCuda3f1_projectResponseIndexed(unsigned int size, const void* indices, void* dx); + void FixedProjectiveConstraintCudaRigid3f_projectResponseContiguous(unsigned int size, void* dx); + void FixedProjectiveConstraintCudaRigid3f_projectResponseIndexed(unsigned int size, const void* indices, void* dx); + +#ifdef SOFA_GPU_CUDA_DOUBLE + + void FixedProjectiveConstraintCuda3d_projectResponseContiguous(unsigned int size, void* dx); + void FixedProjectiveConstraintCuda3d_projectResponseIndexed(unsigned int size, const void* indices, void* dx); + void FixedProjectiveConstraintCuda3d1_projectResponseContiguous(unsigned int size, void* dx); + void FixedProjectiveConstraintCuda3d1_projectResponseIndexed(unsigned int size, const void* indices, void* dx); + void FixedProjectiveConstraintCudaRigid3d_projectResponseContiguous(unsigned int size, void* dx); + void FixedProjectiveConstraintCudaRigid3d_projectResponseIndexed(unsigned int size, const void* indices, void* dx); + +#endif // SOFA_GPU_CUDA_DOUBLE +} + +////////////////////// +// GPU-side methods // +////////////////////// + +template +__global__ void FixedProjectiveConstraintCuda1t_projectResponseContiguous_kernel(int size, real* dx) +{ + int index = blockIdx.x * BSIZE+threadIdx.x; + if (index < size) + dx[index] = 0.0f; +} + +template +__global__ void FixedProjectiveConstraintCuda3t_projectResponseContiguous_kernel(int size, CudaVec3* dx) +{ + int index = blockIdx.x * BSIZE+threadIdx.x; + if (index < size) + dx[index] = CudaVec3::make(0.0f,0.0f,0.0f); +} + +template +__global__ void FixedProjectiveConstraintCuda3t1_projectResponseContiguous_kernel(int size, CudaVec4* dx) +{ + int index = blockIdx.x * BSIZE+threadIdx.x; + if (index < size) + dx[index] = CudaVec4::make(0.0f,0.0f,0.0f,0.0f); +} + +template +__global__ void FixedProjectiveConstraintCudaRigid3t_projectResponseContiguous_kernel(int size, CudaRigidDeriv3* dx) +{ + int index = blockIdx.x * BSIZE+threadIdx.x; + if (index < size) + dx[index] = CudaRigidDeriv3::make(0.0f,0.0f,0.0f,0.0f,0.0f,0.0f); +} + +template +__global__ void FixedProjectiveConstraintCuda1t_projectResponseIndexed_kernel(int size, const int* indices, real* dx) +{ + int index = blockIdx.x * BSIZE+threadIdx.x; + if (index < size) + dx[indices[index]] = 0.0f; +} + +template +__global__ void FixedProjectiveConstraintCuda3t_projectResponseIndexed_kernel(int size, const int* indices, CudaVec3* dx) +{ + int index = blockIdx.x * BSIZE+threadIdx.x; + if (index < size) + dx[indices[index]] = CudaVec3::make(0.0f,0.0f,0.0f); +} + +template +__global__ void FixedProjectiveConstraintCuda3t1_projectResponseIndexed_kernel(int size, const int* indices, CudaVec4* dx) +{ + int index = blockIdx.x * BSIZE+threadIdx.x; + if (index < size) + dx[indices[index]] = CudaVec4::make(0.0f,0.0f,0.0f,0.0f); +} + +template +__global__ void FixedProjectiveConstraintCudaRigid3t_projectResponseIndexed_kernel(int size, const int* indices, CudaRigidDeriv3* dx) +{ + int index = blockIdx.x * BSIZE+threadIdx.x; + if (index < size) + dx[indices[index]] = CudaRigidDeriv3::make(0.0f,0.0f,0.0f,0.0f,0.0f,0.0f); +} + +////////////////////// +// CPU-side methods // +////////////////////// + +void FixedProjectiveConstraintCuda1f_projectResponseContiguous(unsigned int size, void* dx) +{ + cudaMemset(dx, 0, size*sizeof(float)); +} + +void FixedProjectiveConstraintCuda3f_projectResponseContiguous(unsigned int size, void* dx) +{ + cudaMemset(dx, 0, size*3*sizeof(float)); +} + +void FixedProjectiveConstraintCuda3f1_projectResponseContiguous(unsigned int size, void* dx) +{ + cudaMemset(dx, 0, size*4*sizeof(float)); +} + +void FixedProjectiveConstraintCudaRigid3f_projectResponseContiguous(unsigned int size, void* dx) +{ + cudaMemset(dx, 0, size*6*sizeof(float)); +} + +void FixedProjectiveConstraintCuda1f_projectResponseIndexed(unsigned int size, const void* indices, void* dx) +{ + dim3 threads(BSIZE,1); + dim3 grid((size+BSIZE-1)/BSIZE,1); + {FixedProjectiveConstraintCuda1t_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (float*)dx); mycudaDebugError("FixedProjectiveConstraintCuda1t_projectResponseIndexed_kernel");} +} + +void FixedProjectiveConstraintCuda3f_projectResponseIndexed(unsigned int size, const void* indices, void* dx) +{ + dim3 threads(BSIZE,1); + dim3 grid((size+BSIZE-1)/BSIZE,1); + {FixedProjectiveConstraintCuda3t_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaVec3*)dx); mycudaDebugError("FixedProjectiveConstraintCuda3t_projectResponseIndexed_kernel");} +} + +void FixedProjectiveConstraintCuda3f1_projectResponseIndexed(unsigned int size, const void* indices, void* dx) +{ + dim3 threads(BSIZE,1); + dim3 grid((size+BSIZE-1)/BSIZE,1); + {FixedProjectiveConstraintCuda3t1_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaVec4*)dx); mycudaDebugError("FixedProjectiveConstraintCuda3t1_projectResponseIndexed_kernel");} +} + +void FixedProjectiveConstraintCudaRigid3f_projectResponseIndexed(unsigned int size, const void* indices, void* dx) +{ + dim3 threads(BSIZE,1); + dim3 grid((size+BSIZE-1)/BSIZE,1); + {FixedProjectiveConstraintCudaRigid3t_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaRigidDeriv3*)dx); mycudaDebugError("FixedProjectiveConstraintCudaRigid3t_projectResponseIndexed_kernel");} +} + +#ifdef SOFA_GPU_CUDA_DOUBLE + +void FixedProjectiveConstraintCuda3d_projectResponseContiguous(unsigned int size, void* dx) +{ + cudaMemset(dx, 0, size*3*sizeof(double)); +} + +void FixedProjectiveConstraintCuda3d1_projectResponseContiguous(unsigned int size, void* dx) +{ + cudaMemset(dx, 0, size*4*sizeof(double)); +} + +void FixedProjectiveConstraintCudaRigid3d_projectResponseContiguous(unsigned int size, void* dx) +{ + cudaMemset(dx, 0, size*6*sizeof(double)); +} + +void FixedProjectiveConstraintCuda3d_projectResponseIndexed(unsigned int size, const void* indices, void* dx) +{ + dim3 threads(BSIZE,1); + dim3 grid((size+BSIZE-1)/BSIZE,1); + {FixedProjectiveConstraintCuda3t_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaVec3*)dx); mycudaDebugError("FixedProjectiveConstraintCuda3t_projectResponseIndexed_kernel");} +} + +void FixedProjectiveConstraintCuda3d1_projectResponseIndexed(unsigned int size, const void* indices, void* dx) +{ + dim3 threads(BSIZE,1); + dim3 grid((size+BSIZE-1)/BSIZE,1); + {FixedProjectiveConstraintCuda3t1_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaVec4*)dx); mycudaDebugError("FixedProjectiveConstraintCuda3t1_projectResponseIndexed_kernel");} +} + +void FixedProjectiveConstraintCudaRigid3d_projectResponseIndexed(unsigned int size, const void* indices, void* dx) +{ + dim3 threads(BSIZE,1); + dim3 grid((size+BSIZE-1)/BSIZE,1); + {FixedProjectiveConstraintCudaRigid3t_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaRigidDeriv3*)dx); mycudaDebugError("FixedProjectiveConstraintCudaRigid3t_projectResponseIndexed_kernel");} +} + +#endif // SOFA_GPU_CUDA_DOUBLE + +#if defined(__cplusplus) && CUDA_VERSION < 2000 +} // namespace cuda +} // namespace gpu +} // namespace sofa +#endif diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedProjectiveConstraint.h b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedProjectiveConstraint.h new file mode 100644 index 00000000000..1c4d1bf8b08 --- /dev/null +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedProjectiveConstraint.h @@ -0,0 +1,112 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include + +namespace sofa::component::constraint::projective +{ + +template +class FixedProjectiveConstraintInternalData< gpu::cuda::CudaVectorTypes > +{ +public: + using Index = sofa::Index; + typedef FixedProjectiveConstraintInternalData< gpu::cuda::CudaVectorTypes > Data; + typedef gpu::cuda::CudaVectorTypes DataTypes; + typedef FixedProjectiveConstraint Main; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::Real Real; + typedef typename Main::SetIndex SetIndex; + typedef typename Main::SetIndexArray SetIndexArray; + + // min/max fixed indices for contiguous constraints + Index minIndex; + Index maxIndex; + // vector of indices for general case + gpu::cuda::CudaVector cudaIndices; + + + static void init(Main* m); + + static void addConstraint(Main* m, Index index); + + static void removeConstraint(Main* m, Index index); + + static void projectResponse(Main* m, VecDeriv& dx); +}; + +template +class FixedProjectiveConstraintInternalData< gpu::cuda::CudaRigidTypes > +{ +public: + using Index = sofa::Index; + typedef FixedProjectiveConstraintInternalData< gpu::cuda::CudaRigidTypes > Data; + typedef gpu::cuda::CudaRigidTypes DataTypes; + typedef FixedProjectiveConstraint Main; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::Real Real; + typedef typename Main::SetIndex SetIndex; + typedef typename Main::SetIndexArray SetIndexArray; + + // min/max fixed indices for contiguous constraints + Index minIndex; + Index maxIndex; + // vector of indices for general case + gpu::cuda::CudaVector cudaIndices; + + + static void init(Main* m); + + static void addConstraint(Main* m, Index index); + + static void removeConstraint(Main* m, Index index); + + static void projectResponse(Main* m, VecDeriv& dx); +}; + +// I know using macros is bad design but this is the only way not to repeat the code for all CUDA types +#define CudaFixedProjectiveConstraint_DeclMethods(T) \ + template<> void FixedProjectiveConstraint< T >::init(); \ + template<> void FixedProjectiveConstraint< T >::addConstraint(Index index); \ + template<> void FixedProjectiveConstraint< T >::removeConstraint(Index index); \ + template<> void FixedProjectiveConstraint< T >::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData); + +CudaFixedProjectiveConstraint_DeclMethods(gpu::cuda::CudaVec3fTypes); +CudaFixedProjectiveConstraint_DeclMethods(gpu::cuda::CudaVec3f1Types); +CudaFixedProjectiveConstraint_DeclMethods(gpu::cuda::CudaRigid3fTypes); + +#ifdef SOFA_GPU_CUDA_DOUBLE + +CudaFixedProjectiveConstraint_DeclMethods(gpu::cuda::CudaVec3dTypes); +CudaFixedProjectiveConstraint_DeclMethods(gpu::cuda::CudaVec3d1Types); +CudaFixedProjectiveConstraint_DeclMethods(gpu::cuda::CudaRigid3dTypes); + +#endif // SOFA_GPU_CUDA_DOUBLE + +#undef CudaFixedProjectiveConstraint_DeclMethods + + +} // namespace sofa::component::constraint::projective diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedProjectiveConstraint.inl b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedProjectiveConstraint.inl new file mode 100644 index 00000000000..6d3ce62aa71 --- /dev/null +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedProjectiveConstraint.inl @@ -0,0 +1,453 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include + +namespace sofa::gpu::cuda +{ + +extern "C" +{ + void FixedProjectiveConstraintCuda1f_projectResponseContiguous(unsigned int size, void* dx); + void FixedProjectiveConstraintCuda1f_projectResponseIndexed(unsigned int size, const void* indices, void* dx); + void FixedProjectiveConstraintCuda3f_projectResponseContiguous(unsigned int size, void* dx); + void FixedProjectiveConstraintCuda3f_projectResponseIndexed(unsigned int size, const void* indices, void* dx); + void FixedProjectiveConstraintCuda3f1_projectResponseContiguous(unsigned int size, void* dx); + void FixedProjectiveConstraintCuda3f1_projectResponseIndexed(unsigned int size, const void* indices, void* dx); + void FixedProjectiveConstraintCudaRigid3f_projectResponseContiguous(unsigned int size, void* dx); + void FixedProjectiveConstraintCudaRigid3f_projectResponseIndexed(unsigned int size, const void* indices, void* dx); + +#ifdef SOFA_GPU_CUDA_DOUBLE + + void FixedProjectiveConstraintCuda3d_projectResponseContiguous(unsigned int size, void* dx); + void FixedProjectiveConstraintCuda3d_projectResponseIndexed(unsigned int size, const void* indices, void* dx); + void FixedProjectiveConstraintCuda3d1_projectResponseContiguous(unsigned int size, void* dx); + void FixedProjectiveConstraintCuda3d1_projectResponseIndexed(unsigned int size, const void* indices, void* dx); + void FixedProjectiveConstraintCudaRigid3d_projectResponseContiguous(unsigned int size, void* dx); + void FixedProjectiveConstraintCudaRigid3d_projectResponseIndexed(unsigned int size, const void* indices, void* dx); + +#endif // SOFA_GPU_CUDA_DOUBLE +} + +} // namespace sofa::gpu::cuda + +namespace sofa::component::constraint::projective +{ + +using namespace gpu::cuda; + +template +void FixedProjectiveConstraintInternalData< gpu::cuda::CudaVectorTypes >::init(Main* m) +{ + Data& data = *m->data; + data.minIndex = sofa::InvalidID; + data.maxIndex = sofa::InvalidID; + data.cudaIndices.clear(); + m->core::behavior::template ProjectiveConstraintSet::init(); + const SetIndexArray& indices = m->d_indices.getValue(); + if (!indices.empty()) + { + // put indices in a set to sort them and remove duplicates + std::set sortedIndices; + for (typename SetIndex::const_iterator it = indices.begin(); it!=indices.end(); ++it) + sortedIndices.insert(*it); + // check if the indices are contiguous + if (*sortedIndices.begin() + (int)sortedIndices.size()-1 == *sortedIndices.rbegin()) + { + data.minIndex = *sortedIndices.begin(); + data.maxIndex = *sortedIndices.rbegin(); + msg_info("CudaFixedProjectiveConstraint") << "init: " << sortedIndices.size() << " contiguous fixed indices, " << data.minIndex << " - " << data.maxIndex; + } + else + { + msg_info("CudaFixedProjectiveConstraint") << "init: " << sortedIndices.size() << " non-contiguous fixed indices"; + data.cudaIndices.reserve(sortedIndices.size()); + for (std::set::const_iterator it = sortedIndices.begin(); it!=sortedIndices.end(); ++it) + data.cudaIndices.push_back(*it); + } + } + + m->d_componentState.setValue(ComponentState::Valid); +} + +template +void FixedProjectiveConstraintInternalData< gpu::cuda::CudaVectorTypes >::addConstraint(Main* m, Index index) +{ + Data& data = *m->data; + //std::cout << "CudaFixedProjectiveConstraint::addConstraint("<d_indices.beginEdit()->push_back(index); + m->d_indices.endEdit(); + if (data.cudaIndices.empty()) + { + if (data.minIndex == sofa::InvalidID) + { + //std::cout << "CudaFixedProjectiveConstraint: single index "<= data.minIndex && index <= data.maxIndex) + { + // point already fixed + } + else if (data.minIndex == index + 1) + { + data.minIndex = index; + //std::cout << "CudaFixedProjectiveConstraint: new min index "< +void FixedProjectiveConstraintInternalData< gpu::cuda::CudaVectorTypes >::removeConstraint(Main* m, Index index) +{ + Data& data = *m->data; + removeValue(*m->d_indices.beginEdit(),index); + m->d_indices.endEdit(); + if (data.cudaIndices.empty()) + { + if (data.minIndex <= index && index <= data.maxIndex) + { + if (data.minIndex == index) + { + if (data.maxIndex == index) + { + // empty set + data.minIndex = sofa::InvalidID; + data.maxIndex = sofa::InvalidID; + } + else + ++data.minIndex; + } + else if (data.maxIndex == index) + --data.maxIndex; + else + { + data.cudaIndices.reserve(data.maxIndex-data.minIndex); + for (int i=data.minIndex; i +void FixedProjectiveConstraintInternalData< gpu::cuda::CudaRigidTypes >::init(Main* m) +{ + Data& data = *m->data; + data.minIndex = sofa::InvalidID; + data.maxIndex = sofa::InvalidID; + data.cudaIndices.clear(); + m->core::behavior::template ProjectiveConstraintSet::init(); + const SetIndexArray& indices = m->d_indices.getValue(); + if (!indices.empty()) + { + // put indices in a set to sort them and remove duplicates + std::set sortedIndices; + for (typename SetIndex::const_iterator it = indices.begin(); it!=indices.end(); ++it) + sortedIndices.insert(*it); + // check if the indices are contiguous + if (*sortedIndices.begin() + (int)sortedIndices.size()-1 == *sortedIndices.rbegin()) + { + data.minIndex = *sortedIndices.begin(); + data.maxIndex = *sortedIndices.rbegin(); + msg_info("CudaFixedProjectiveConstraint") << "init: " << sortedIndices.size() << " contiguous fixed indices, " << data.minIndex << " - " << data.maxIndex; + } + else + { + msg_info("CudaFixedProjectiveConstraint") << "init: " << sortedIndices.size() << " non-contiguous fixed indices"; + data.cudaIndices.reserve(sortedIndices.size()); + for (std::set::const_iterator it = sortedIndices.begin(); it!=sortedIndices.end(); ++it) + data.cudaIndices.push_back(*it); + } + } + + m->d_componentState.setValue(ComponentState::Valid); +} + +template +void FixedProjectiveConstraintInternalData< gpu::cuda::CudaRigidTypes >::addConstraint(Main* m, Index index) +{ + Data& data = *m->data; + //std::cout << "CudaFixedProjectiveConstraint::addConstraint("<d_indices.beginEdit()->push_back(index); + m->d_indices.endEdit(); + if (data.cudaIndices.empty()) + { + if (data.minIndex == sofa::InvalidID) + { + //std::cout << "CudaFixedProjectiveConstraint: single index "<= data.minIndex && index <= data.maxIndex) + { + // point already fixed + } + else if (data.minIndex == index+1) + { + data.minIndex = index; + //std::cout << "CudaFixedProjectiveConstraint: new min index "< +void FixedProjectiveConstraintInternalData< gpu::cuda::CudaRigidTypes >::removeConstraint(Main* m, Index index) +{ + Data& data = *m->data; + removeValue(*m->d_indices.beginEdit(),index); + m->d_indices.endEdit(); + if (data.cudaIndices.empty()) + { + if (data.minIndex <= index && index <= data.maxIndex) + { + if (data.minIndex == index) + { + if (data.maxIndex == index) + { + // empty set + data.minIndex = sofa::InvalidID; + data.maxIndex = sofa::InvalidID; + } + else + ++data.minIndex; + } + else if (data.maxIndex == index) + --data.maxIndex; + else + { + data.cudaIndices.reserve(data.maxIndex-data.minIndex); + for (int i=data.minIndex; i +void FixedProjectiveConstraintInternalData::projectResponse(Main* m, VecDeriv& dx) +{ + const Data& data = *m->data; + if (m->d_fixAll.getValue()) + FixedProjectiveConstraintCuda1f_projectResponseContiguous(dx.size(), ((float*)dx.deviceWrite())); + else if (data.minIndex >= 0) + FixedProjectiveConstraintCuda1f_projectResponseContiguous(data.maxIndex-data.minIndex+1, ((float*)dx.deviceWrite())+data.minIndex); + else + FixedProjectiveConstraintCuda1f_projectResponseIndexed(data.cudaIndices.size(), data.cudaIndices.deviceRead(), dx.deviceWrite()); +} + + +template <> +void FixedProjectiveConstraintInternalData::projectResponse(Main* m, VecDeriv& dx) +{ + const Data& data = *m->data; + if (m->d_fixAll.getValue()) + FixedProjectiveConstraintCuda3f_projectResponseContiguous(dx.size(), ((float*)dx.deviceWrite())); + else if (data.minIndex != sofa::InvalidID) + FixedProjectiveConstraintCuda3f_projectResponseContiguous(data.maxIndex - data.minIndex + 1, ((float*)dx.deviceWrite()) + 3 * data.minIndex); + else + FixedProjectiveConstraintCuda3f_projectResponseIndexed(data.cudaIndices.size(), data.cudaIndices.deviceRead(), dx.deviceWrite()); +} + + +template <> +void FixedProjectiveConstraintInternalData::projectResponse(Main* m, VecDeriv& dx) +{ + const Data& data = *m->data; + if (m->d_fixAll.getValue()) + FixedProjectiveConstraintCuda3f1_projectResponseContiguous(dx.size(), ((float*)dx.deviceWrite())); + else if (data.minIndex != sofa::InvalidID) + FixedProjectiveConstraintCuda3f1_projectResponseContiguous(data.maxIndex-data.minIndex+1, ((float*)dx.deviceWrite())+4*data.minIndex); + else + FixedProjectiveConstraintCuda3f1_projectResponseIndexed(data.cudaIndices.size(), data.cudaIndices.deviceRead(), dx.deviceWrite()); +} + +template <> +void FixedProjectiveConstraintInternalData::projectResponse(Main* m, VecDeriv& dx) +{ + const Data& data = *m->data; + if (m->d_fixAll.getValue()) + FixedProjectiveConstraintCudaRigid3f_projectResponseContiguous(dx.size(), ((float*)dx.deviceWrite())); + else if (data.minIndex != sofa::InvalidID) + FixedProjectiveConstraintCudaRigid3f_projectResponseContiguous(data.maxIndex-data.minIndex+1, ((float*)dx.deviceWrite())+6*data.minIndex); + else + FixedProjectiveConstraintCudaRigid3f_projectResponseIndexed(data.cudaIndices.size(), data.cudaIndices.deviceRead(), dx.deviceWrite()); +} + + + +#ifdef SOFA_GPU_CUDA_DOUBLE + +// // Handle topological changes +// template <> +// void FixedProjectiveConstraint::handleTopologyChange() { +// // std::list::const_iterator itBegin=topology->firstChange(); +// // std::list::const_iterator itEnd=topology->lastChange(); +// // +// // d_indices.beginEdit()->handleTopologyEvents(itBegin,itEnd,this->getMState()->getSize()); +// //printf("WARNING handleTopologyChange not implemented\n"); +// } + +template <> +void FixedProjectiveConstraintInternalData::projectResponse(Main* m, VecDeriv& dx) +{ + Data& data = *m->data; + if (m->d_fixAll.getValue()) + FixedProjectiveConstraintCuda3d_projectResponseContiguous(dx.size(), ((double*)dx.deviceWrite())); + else if (data.minIndex >= 0) + FixedProjectiveConstraintCuda3d_projectResponseContiguous(data.maxIndex-data.minIndex+1, ((double*)dx.deviceWrite())+3*data.minIndex); + else + FixedProjectiveConstraintCuda3d_projectResponseIndexed(data.cudaIndices.size(), data.cudaIndices.deviceRead(), dx.deviceWrite()); +} + +template <> +void FixedProjectiveConstraintInternalData::projectResponse(Main* m, VecDeriv& dx) +{ + Data& data = *m->data; + if (m->d_fixAll.getValue()) + FixedProjectiveConstraintCuda3d1_projectResponseContiguous(dx.size(), ((double*)dx.deviceWrite())); + else if (data.minIndex >= 0) + FixedProjectiveConstraintCuda3d1_projectResponseContiguous(data.maxIndex-data.minIndex+1, ((double*)dx.deviceWrite())+4*data.minIndex); + else + FixedProjectiveConstraintCuda3d1_projectResponseIndexed(data.cudaIndices.size(), data.cudaIndices.deviceRead(), dx.deviceWrite()); +} + +template <> +void FixedProjectiveConstraintInternalData::projectResponse(Main* m, VecDeriv& dx) +{ + Data& data = *m->data; + if (m->d_fixAll.getValue()) + FixedProjectiveConstraintCudaRigid3d_projectResponseContiguous(dx.size(), ((double*)dx.deviceWrite())); + else if (data.minIndex >= 0) + FixedProjectiveConstraintCudaRigid3d_projectResponseContiguous(data.maxIndex-data.minIndex+1, ((double*)dx.deviceWrite())+6*data.minIndex); + else + FixedProjectiveConstraintCudaRigid3d_projectResponseIndexed(data.cudaIndices.size(), data.cudaIndices.deviceRead(), dx.deviceWrite()); +} + +#endif // SOFA_GPU_CUDA_DOUBLE + +// I know using macros is bad design but this is the only way not to repeat the code for all CUDA types +#define CudaFixedProjectiveConstraint_ImplMethods(T) \ + template<> void FixedProjectiveConstraint< T >::init() \ + { data->init(this); } \ + template<> void FixedProjectiveConstraint< T >::addConstraint(Index index) \ + { data->addConstraint(this, index); } \ + template<> void FixedProjectiveConstraint< T >::removeConstraint(Index index) \ + { data->removeConstraint(this, index); } \ + template<> void FixedProjectiveConstraint< T >::projectResponse(const core::MechanicalParams* /* mparams */, DataVecDeriv& d_resData) \ + { \ + VecDeriv &resData = *d_resData.beginEdit(); \ + data->projectResponse(this, resData); \ + d_resData.endEdit(); \ + } + +CudaFixedProjectiveConstraint_ImplMethods(gpu::cuda::CudaVec3fTypes); +CudaFixedProjectiveConstraint_ImplMethods(gpu::cuda::CudaVec3f1Types); +CudaFixedProjectiveConstraint_ImplMethods(gpu::cuda::CudaRigid3fTypes); + +#ifdef SOFA_GPU_CUDA_DOUBLE + +CudaFixedProjectiveConstraint_ImplMethods(gpu::cuda::CudaVec3dTypes); +CudaFixedProjectiveConstraint_ImplMethods(gpu::cuda::CudaVec3d1Types); +CudaFixedProjectiveConstraint_ImplMethods(gpu::cuda::CudaRigid3dTypes); + +#endif // SOFA_GPU_CUDA_DOUBLE + +#undef CudaFixedProjectiveConstraint_ImplMethods + +} // namespace sofa::component::constraint::projective diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedTranslationConstraint.cpp b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedTranslationProjectiveConstraint.cpp similarity index 70% rename from applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedTranslationConstraint.cpp rename to applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedTranslationProjectiveConstraint.cpp index 7d9d18db439..64ebf9fecac 100644 --- a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedTranslationConstraint.cpp +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaFixedTranslationProjectiveConstraint.cpp @@ -21,7 +21,7 @@ ******************************************************************************/ #include #include -#include +#include #include @@ -32,15 +32,15 @@ namespace sofa::component::constraint::projective { template<> -void FixedTranslationConstraint::draw(const core::visual::VisualParams* vparams); +void FixedTranslationProjectiveConstraint::draw(const core::visual::VisualParams* vparams); #ifdef SOFA_GPU_CUDA_DOUBLE template<> -void FixedTranslationConstraint::draw(const core::visual::VisualParams* vparams); +void FixedTranslationProjectiveConstraint::draw(const core::visual::VisualParams* vparams); #endif // SOFA_GPU_CUDA_DOUBLE template <> -void component::constraint::projective::FixedTranslationConstraint::draw(const core::visual::VisualParams* vparams) +void component::constraint::projective::FixedTranslationProjectiveConstraint::draw(const core::visual::VisualParams* vparams) { #if SOFACUDA_HAVE_SOFA_GL == 1 const SetIndexArray & indices = f_indices.getValue(); @@ -71,7 +71,7 @@ void component::constraint::projective::FixedTranslationConstraint -void component::constraint::projective::FixedTranslationConstraint::draw(const core::visual::VisualParams* vparams) +void component::constraint::projective::FixedTranslationProjectiveConstraint::draw(const core::visual::VisualParams* vparams) { const SetIndexArray & indices = f_indices.getValue(); if (!vparams->displayFlags().getShowBehaviorModels()) @@ -100,11 +100,11 @@ void component::constraint::projective::FixedTranslationConstraint; -template class SOFA_GPU_CUDA_API FixedTranslationConstraint; +template class SOFA_GPU_CUDA_API FixedTranslationProjectiveConstraint; +template class SOFA_GPU_CUDA_API FixedTranslationProjectiveConstraint; #ifdef SOFA_GPU_CUDA_DOUBLE -template class SOFA_GPU_CUDA_API FixedTranslationConstraint; -template class SOFA_GPU_CUDA_API FixedTranslationConstraint; +template class SOFA_GPU_CUDA_API FixedTranslationProjectiveConstraint; +template class SOFA_GPU_CUDA_API FixedTranslationProjectiveConstraint; #endif // SOFA_GPU_CUDA_DOUBLE }// namespace sofa::component::constraint::projective @@ -113,16 +113,16 @@ namespace sofa::gpu::cuda { -int FixedTranslationConstraintCudaClass = core::RegisterObject("Supports GPU-side computations using CUDA") -// .add< component::constraint::projective::FixedTranslationConstraint >() -// .add< component::constraint::projective::FixedTranslationConstraint >() - .add< component::constraint::projective::FixedTranslationConstraint >() - .add< component::constraint::projective::FixedTranslationConstraint >() +int FixedTranslationProjectiveConstraintCudaClass = core::RegisterObject("Supports GPU-side computations using CUDA") +// .add< component::constraint::projective::FixedTranslationProjectiveConstraint >() +// .add< component::constraint::projective::FixedTranslationProjectiveConstraint >() + .add< component::constraint::projective::FixedTranslationProjectiveConstraint >() + .add< component::constraint::projective::FixedTranslationProjectiveConstraint >() #ifdef SOFA_GPU_CUDA_DOUBLE -// .add< component::constraint::projective::FixedTranslationConstraint >() -// .add< component::constraint::projective::FixedTranslationConstraint >() - .add< component::constraint::projective::FixedTranslationConstraint >() - .add< component::constraint::projective::FixedTranslationConstraint >() +// .add< component::constraint::projective::FixedTranslationProjectiveConstraint >() +// .add< component::constraint::projective::FixedTranslationProjectiveConstraint >() + .add< component::constraint::projective::FixedTranslationProjectiveConstraint >() + .add< component::constraint::projective::FixedTranslationProjectiveConstraint >() #endif // SOFA_GPU_CUDA_DOUBLE ; diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementConstraint.cu b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementConstraint.cu deleted file mode 100644 index 2deca0a26ad..00000000000 --- a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementConstraint.cu +++ /dev/null @@ -1,208 +0,0 @@ -/****************************************************************************** -* SOFA, Simulation Open-Framework Architecture * -* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * -* * -* This program is free software; you can redistribute it and/or modify it * -* under the terms of the GNU Lesser General Public License as published by * -* the Free Software Foundation; either version 2.1 of the License, or (at * -* your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, but WITHOUT * -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * -* for more details. * -* * -* You should have received a copy of the GNU Lesser General Public License * -* along with this program. If not, see . * -******************************************************************************* -* Authors: The SOFA Team and external contributors (see Authors.txt) * -* * -* Contact information: contact@sofa-framework.org * -******************************************************************************/ -#include -#include -#include "cuda.h" -#include - -#if defined(__cplusplus) && CUDA_VERSION < 2000 -namespace sofa -{ -namespace gpu -{ -namespace cuda -{ -#endif - -extern "C" -{ - - void LinearMovementConstraintCudaVec6f_projectResponseIndexed(unsigned size, const void* indices, void* dx); - void LinearMovementConstraintCudaVec6f_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x); - void LinearMovementConstraintCudaVec6f_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx); - void LinearMovementConstraintCudaRigid3f_projectResponseIndexed(unsigned size, const void* indices, void* dx); - void LinearMovementConstraintCudaRigid3f_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x); - void LinearMovementConstraintCudaRigid3f_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx); - -#ifdef SOFA_GPU_CUDA_DOUBLE - void LinearMovementConstraintCudaVec6d_projectResponseIndexed(unsigned size, const void* indices, void* dx); - void LinearMovementConstraintCudaVec6d_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x); - void LinearMovementConstraintCudaVec6d_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx); - void LinearMovementConstraintCudaRigid3d_projectResponseIndexed(unsigned size, const void* indices, void* dx); - void LinearMovementConstraintCudaRigid3d_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x); - void LinearMovementConstraintCudaRigid3d_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx); -#endif // SOFA_GPU_CUDA_DOUBLE - -}// extern "C" - -////////////////////// -// GPU-side methods // -////////////////////// - -template -__global__ void LinearMovementConstraintCudaVec6t_projectPositionIndexed_kernel(unsigned size, const int* indices, real dirX, real dirY, real dirZ, real dirU, real dirV, real dirW, const CudaVec6* x0, CudaVec6* x) -{ - int index = blockIdx.x * BSIZE+threadIdx.x; - - CudaVec6 m = CudaVec6::make(dirX, dirY, dirZ, dirU, dirV, dirW); - if (index < size) - { - x[indices[index]] = x0[index]; - x[indices[index]] += m; - } -}// projectPositionIndexed_kernel - -template -__global__ void LinearMovementConstraintCudaRigid3t_projectResponseIndexed_kernel(unsigned size, const int* indices, CudaRigidDeriv3* dx) -{ - int index = blockIdx.x * BSIZE+threadIdx.x; - - if (index < size) - { - dx[indices[index]] = CudaRigidDeriv3::make(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); - } -}// kernel Indexed Cuda3t1 - -template -__global__ void LinearMovementConstraintCudaRigid3t_projectPositionIndexed_kernel(unsigned size, const int* indices, real dirX, real dirY, real dirZ, real dirU, real dirV, real dirW, const CudaRigidCoord3* x0, CudaRigidCoord3* x) -{ - int index = blockIdx.x * BSIZE+threadIdx.x; - - CudaRigidCoord3 m = CudaRigidCoord3::make(dirX, dirY, dirZ, dirU, dirV, dirW, 0.0); - if (index < size) - { - x[indices[index]] = x0[index]; - x[indices[index]] += m; - } -}// projectPositionIndexed_kernel - - -template -__global__ void LinearMovementConstraintCudaRigid3t_projectVelocityIndexed_kernel(unsigned size, const int* indices, real velX, real velY, real velZ, real velU, real velV, real velW, CudaRigidDeriv3* dx) -{ - int index = blockIdx.x * BSIZE+threadIdx.x; - - CudaRigidDeriv3 vel = CudaRigidDeriv3::make(velX, velY, velZ, velU, velV, velW); - if (index < size) - { - dx[indices[index]] = vel; - } -}// projectVelocityIndexed_kernel - -////////////////////// -// CPU-side methods // -////////////////////// -void LinearMovementConstraintCudaVec6f_projectResponseIndexed(unsigned size, const void* indices, void* dx) -{ - dim3 threads(BSIZE, 1); - dim3 grid((size+BSIZE-1)/BSIZE,1); - {LinearMovementConstraintCudaRigid3t_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaRigidDeriv3*)dx); mycudaDebugError("LinearMovementConstraintCudaRigid3t_projectResponseIndexed_kernel");} -} - -void LinearMovementConstraintCudaVec6f_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x) -{ - dim3 threads(BSIZE, 1); - dim3 grid((size+BSIZE-1)/BSIZE,1); - LinearMovementConstraintCudaVec6t_projectPositionIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, - ((float*)dir)[0], ((float*)dir)[1], ((float*)dir)[2], ((float*)dir)[3], ((float*)dir)[4], ((float*)dir)[5], - (const CudaVec6*) x0, (CudaVec6*)x); -} - -void LinearMovementConstraintCudaVec6f_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx) -{ - dim3 threads(BSIZE, 1); - dim3 grid((size+BSIZE-1)/BSIZE,1); - {LinearMovementConstraintCudaRigid3t_projectVelocityIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, ((float*)dir)[0], ((float*)dir)[1], ((float*)dir)[2], ((float*)dir)[3], ((float*)dir)[4], ((float*)dir)[5], (CudaRigidDeriv3*)dx); mycudaDebugError("LinearMovementConstraintCudaRigid3t_projectVelocityIndexed_kernel");} -} -void LinearMovementConstraintCudaRigid3f_projectResponseIndexed(unsigned size, const void* indices, void* dx) -{ - dim3 threads(BSIZE, 1); - dim3 grid((size+BSIZE-1)/BSIZE,1); - {LinearMovementConstraintCudaRigid3t_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaRigidDeriv3*)dx); mycudaDebugError("LinearMovementConstraintCudaRigid3t_projectResponseIndexed_kernel");} -} - -void LinearMovementConstraintCudaRigid3f_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x) -{ - dim3 threads(BSIZE, 1); - dim3 grid((size+BSIZE-1)/BSIZE,1); - {LinearMovementConstraintCudaRigid3t_projectPositionIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, ((float*)dir)[0], ((float*)dir)[1], ((float*)dir)[2], ((float*)dir)[3], ((float*)dir)[4], ((float*)dir)[5], (const CudaRigidCoord3*) x0, (CudaRigidCoord3*)x); mycudaDebugError("LinearMovementConstraintCudaRigid3t_projectPositionIndexed_kernel");} -} - -void LinearMovementConstraintCudaRigid3f_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx) -{ - dim3 threads(BSIZE, 1); - dim3 grid((size+BSIZE-1)/BSIZE,1); - {LinearMovementConstraintCudaRigid3t_projectVelocityIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, ((float*)dir)[0], ((float*)dir)[1], ((float*)dir)[2], ((float*)dir)[3], ((float*)dir)[4], ((float*)dir)[5], (CudaRigidDeriv3*)dx); mycudaDebugError("LinearMovementConstraintCudaRigid3t_projectVelocityIndexed_kernel");} -} - -#ifdef SOFA_GPU_CUDA_DOUBLE -void LinearMovementConstraintCudaVec6d_projectResponseIndexed(unsigned size, const void* indices, void* dx) -{ - dim3 threads(BSIZE, 1); - dim3 grid((size+BSIZE-1)/BSIZE,1); - {LinearMovementConstraintCudaRigid3t_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaRigidDeriv3*)dx); mycudaDebugError("LinearMovementConstraintCudaRigid3t_projectResponseIndexed_kernel");} -} - -void LinearMovementConstraintCudaVec6d_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x) -{ - dim3 threads(BSIZE, 1); - dim3 grid((size+BSIZE-1)/BSIZE,1); - LinearMovementConstraintCudaVec6t_projectPositionIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, - ((double*)dir)[0], ((double*)dir)[1], ((double*)dir)[2], ((double*)dir)[3], ((double*)dir)[4], ((double*)dir)[5], - (const CudaVec6*) x0, (CudaVec6*)x); -} - -void LinearMovementConstraintCudaVec6d_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx) -{ - dim3 threads(BSIZE, 1); - dim3 grid((size+BSIZE-1)/BSIZE,1); - {LinearMovementConstraintCudaRigid3t_projectVelocityIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, ((double*)dir)[0], ((double*)dir)[1], ((double*)dir)[2], ((double*)dir)[3], ((double*)dir)[4], ((double*)dir)[5], (CudaRigidDeriv3*)dx); mycudaDebugError("LinearMovementConstraintCudaRigid3t_projectVelocityIndexed_kernel");} -} - -void LinearMovementConstraintCudaRigid3d_projectResponseIndexed(unsigned size, const void* indices, void* dx) -{ - dim3 threads(BSIZE, 1); - dim3 grid((size+BSIZE-1)/BSIZE,1); - {LinearMovementConstraintCudaRigid3t_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaRigidDeriv3*)dx); mycudaDebugError("LinearMovementConstraintCudaRigid3t_projectResponseIndexed_kernel");} -} - -void LinearMovementConstraintCudaRigid3d_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x) -{ - dim3 threads(BSIZE, 1); - dim3 grid((size+BSIZE-1)/BSIZE,1); - {LinearMovementConstraintCudaRigid3t_projectPositionIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, ((double*)dir)[0], ((double*)dir)[1], ((double*)dir)[2], ((double*)dir)[3], ((double*)dir)[4], ((double*)dir)[5], (const CudaRigidCoord3*) x0, (CudaRigidCoord3*)x); mycudaDebugError("LinearMovementConstraintCudaRigid3t_projectPositionIndexed_kernel");} -} - -void LinearMovementConstraintCudaRigid3d_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx) -{ - dim3 threads(BSIZE, 1); - dim3 grid((size+BSIZE-1)/BSIZE,1); - {LinearMovementConstraintCudaRigid3t_projectVelocityIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, ((double*)dir)[0], ((double*)dir)[1], ((double*)dir)[2], ((double*)dir)[3], ((double*)dir)[4], ((double*)dir)[5], (CudaRigidDeriv3*)dx); mycudaDebugError("LinearMovementConstraintCudaRigid3t_projectVelocityIndexed_kernel");} -} - -#endif // SOFA_GPU_CUDA_DOUBLE - -#if defined(__cplusplus) && CUDA_VERSION < 2000 -} // namespace cuda -} // namespace gpu -} // namespace sofa -#endif diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementConstraint.h b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementConstraint.h index fcfa31f5a2f..a5251686676 100644 --- a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementConstraint.h +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementConstraint.h @@ -21,190 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include +#include -namespace sofa::gpu::cuda -{ - -template -class CudaKernelsLinearMovementConstraint; - -}// namespace sofa::gpu::cuda - -namespace sofa::component::constraint::projective -{ - -template -class LinearMovementConstraintInternalData< gpu::cuda::CudaVectorTypes > -{ -public: - using Index = sofa::Index; - typedef LinearMovementConstraintInternalData< gpu::cuda::CudaVectorTypes > Data; - typedef gpu::cuda::CudaVectorTypes DataTypes; - typedef LinearMovementConstraint Main; - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::MatrixDeriv::RowType MatrixDerivRowType; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::Real Real; - typedef typename DataTypes::Coord Coord; - typedef type::vector SetIndexArray; - typedef sofa::core::topology::PointSubsetData< SetIndexArray > SetIndex; - - typedef sofa::core::objectmodel::Data DataVecDeriv; - typedef sofa::core::objectmodel::Data DataMatrixDeriv; - - typedef gpu::cuda::CudaKernelsLinearMovementConstraint Kernels; - - // vector of indices for general case - gpu::cuda::CudaVector indices; - - // initial positions - gpu::cuda::CudaVector x0; - - int size; - - static void init(Main* m, VecCoord& x); - - static void addIndex(Main* m, Index index); - - static void removeIndex(Main* m, Index index); - - static void projectResponse(Main* m, VecDeriv& dx); - static void projectPosition(Main* m, VecCoord& x); - static void projectVelocity(Main* m, VecDeriv& dx); - -}; - - -template -class LinearMovementConstraintInternalData< gpu::cuda::CudaRigidTypes > -{ -public: - using Index = sofa::Index; - typedef LinearMovementConstraintInternalData< gpu::cuda::CudaRigidTypes > Data; - typedef gpu::cuda::CudaRigidTypes DataTypes; - typedef LinearMovementConstraint Main; - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::VecDeriv VecDeriv; - typedef typename DataTypes::MatrixDeriv MatrixDeriv; - typedef typename DataTypes::MatrixDeriv::RowType MatrixDerivRowType; - typedef typename DataTypes::Deriv Deriv; - typedef typename DataTypes::Real Real; - typedef typename DataTypes::Coord Coord; - typedef type::vector SetIndexArray; - typedef sofa::core::topology::PointSubsetData< SetIndexArray > SetIndex; - - typedef sofa::core::objectmodel::Data DataVecDeriv; - typedef sofa::core::objectmodel::Data DataMatrixDeriv; - - typedef gpu::cuda::CudaKernelsLinearMovementConstraint Kernels; - - // vector of indices for general case - gpu::cuda::CudaVector indices; - - // initial positions - gpu::cuda::CudaVector x0; - - int size; - - static void init(Main* m, VecCoord& x); - - static void addIndex(Main* m, Index index); - - static void removeIndex(Main* m, Index index); - - static void projectResponse(Main* m, VecDeriv& dx); - static void projectPosition(Main* m, VecCoord& x); - static void projectVelocity(Main* m, VecDeriv& dx); - -}; - - -// template<> -// void LinearMovementConstraint< gpu::cuda::CudaRigid3fTypes >::init(); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6fTypes >::addIndex(Index index); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6fTypes >::removeIndex(Index index); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6fTypes >::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& dx); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6fTypes >::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& dx); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6fTypes >::projectPosition(const core::MechanicalParams* mparams, DataVecCoord& x); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6fTypes >::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& dx); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3fTypes >::addIndex(Index index); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3fTypes >::removeIndex(Index index); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3fTypes >::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& dx); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3fTypes >::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& dx); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3fTypes >::projectPosition(const core::MechanicalParams* mparams, DataVecCoord& x); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3fTypes >::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& dx); - -#ifdef SOFA_GPU_CUDA_DOUBLE - -// template<> -// void LinearMovementConstraint< gpu::cuda::CudaRigid3dTypes >::init(); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6dTypes >::addIndex(Index index); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6dTypes >::removeIndex(Index index); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6dTypes >::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& dx); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6dTypes >::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& dx); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6dTypes >::projectPosition(const core::MechanicalParams* mparams, DataVecCoord& x); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6dTypes >::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& dx); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3dTypes >::addIndex(Index index); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3dTypes >::removeIndex(Index index); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3dTypes >::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& dx); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3dTypes >::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& dx); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3dTypes >::projectPosition(const core::MechanicalParams* mparams, DataVecCoord& x); - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3dTypes >::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& dx); - -#endif // SOFA_GPU_CUDA_DOUBLE - - - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v23.12", "v24.12", "SofaCUDA/component/constraint/projective/CudaLinearMovementProjectiveConstraint.h") diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementConstraint.inl b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementConstraint.inl index a9abcd99c24..1771a40013b 100644 --- a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementConstraint.inl +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementConstraint.inl @@ -21,576 +21,6 @@ ******************************************************************************/ #pragma once -#include -#include +#include -namespace sofa::gpu::cuda -{ - -extern "C" -{ - - void LinearMovementConstraintCudaVec6f_projectResponseIndexed(unsigned size, const void* indices, void* dx); - void LinearMovementConstraintCudaVec6f_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x); - void LinearMovementConstraintCudaVec6f_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx); - void LinearMovementConstraintCudaRigid3f_projectResponseIndexed(unsigned size, const void* indices, void* dx); - void LinearMovementConstraintCudaRigid3f_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x); - void LinearMovementConstraintCudaRigid3f_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx); - -#ifdef SOFA_GPU_CUDA_DOUBLE - void LinearMovementConstraintCudaVec6d_projectResponseIndexed(unsigned size, const void* indices, void* dx); - void LinearMovementConstraintCudaVec6d_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x); - void LinearMovementConstraintCudaVec6d_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx); - void LinearMovementConstraintCudaRigid3d_projectResponseIndexed(unsigned size, const void* indices, void* dx); - void LinearMovementConstraintCudaRigid3d_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x); - void LinearMovementConstraintCudaRigid3d_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx); -#endif // SOFA_GPU_CUDA_DOUBLE - -}// extern "C" - -template<> -class CudaKernelsLinearMovementConstraint< CudaVec6fTypes > -{ -public: - static void projectResponse(unsigned size, const void* indices, void* dx) - { - LinearMovementConstraintCudaVec6f_projectResponseIndexed(size, indices, dx); - } - static void projectPosition(unsigned size, const void* indices, const void* dir, const void* x0, void* x) - { - LinearMovementConstraintCudaVec6f_projectPositionIndexed(size, indices, dir, x0, x); - } - static void projectVelocity(unsigned size, const void* indices, const void* dir, void* dx) - { - LinearMovementConstraintCudaVec6f_projectVelocityIndexed(size, indices, dir, dx); - } -};// CudaKernelsLinearMovementConstraint - -template<> -class CudaKernelsLinearMovementConstraint< CudaRigid3fTypes > -{ -public: - static void projectResponse(unsigned size, const void* indices, void* dx) - { - LinearMovementConstraintCudaRigid3f_projectResponseIndexed(size, indices, dx); - } - static void projectPosition(unsigned size, const void* indices, const void* dir, const void* x0, void* x) - { - LinearMovementConstraintCudaRigid3f_projectPositionIndexed(size, indices, dir, x0, x); - } - static void projectVelocity(unsigned size, const void* indices, const void* dir, void* dx) - { - LinearMovementConstraintCudaRigid3f_projectVelocityIndexed(size, indices, dir, dx); - } -};// CudaKernelsLinearMovementConstraint - -#ifdef SOFA_GPU_CUDA_DOUBLE - -template<> -class CudaKernelsLinearMovementConstraint< CudaVec6dTypes > -{ -public: - static void projectResponse(unsigned size, const void* indices, void* dx) - { - LinearMovementConstraintCudaVec6d_projectResponseIndexed(size, indices, dx); - } - static void projectPosition(unsigned size, const void* indices, const void* dir, const void* x0, void* x) - { - LinearMovementConstraintCudaVec6d_projectPositionIndexed(size, indices, dir, x0, x); - } - static void projectVelocity(unsigned size, const void* indices, const void* dir, void* dx) - { - LinearMovementConstraintCudaVec6d_projectVelocityIndexed(size, indices, dir, dx); - } -};// CudaKernelsLinearMovementConstraint - -template<> -class CudaKernelsLinearMovementConstraint< CudaRigid3dTypes > -{ -public: - static void projectResponse(unsigned size, const void* indices, void* dx) - { - LinearMovementConstraintCudaRigid3d_projectResponseIndexed(size, indices, dx); - } - static void projectPosition(unsigned size, const void* indices, const void* dir, const void* x0, void* x) - { - LinearMovementConstraintCudaRigid3d_projectPositionIndexed(size, indices, dir, x0, x); - } - static void projectVelocity(unsigned size, const void* indices, const void* dir, void* dx) - { - LinearMovementConstraintCudaRigid3d_projectVelocityIndexed(size, indices, dir, dx); - } -};// CudaKernelsLinearMovementConstraint - -#endif // SOFA_GPU_CUDA_DOUBLE - -} // namespace sofa::gpu::cuda - -namespace sofa::component::constraint::projective -{ - -///////////////////////////////////// -// CudaVectorTypes specializations -///////////////////////////////////// -template -void LinearMovementConstraintInternalData< gpu::cuda::CudaVectorTypes >::addIndex(Main* m, Index index) -{ - Data& data = *m->data; - - m->m_indices.beginEdit()->push_back(index); - m->m_indices.endEdit(); - - data.indices.push_back(index); - // TODO : then it becomes non-consistent and also in the main version !!! -// data.x0.push_back(); - -}// LinearMovementConstraintInternalData::addIndex - -template -void LinearMovementConstraintInternalData< gpu::cuda::CudaVectorTypes >::removeIndex(Main* m, Index index) -{ - // Data& data = m->data; - - removeValue(*m->m_indices.beginEdit(),index); - m->m_indices.endEdit(); - - // removeValue(data.indices, index); - // TODO : then it becomes non-consistent and also in the main version !!! -// data.x0.push_back(); - -}// LinearMovementConstraintInternalData::removeIndex - -template -void LinearMovementConstraintInternalData< gpu::cuda::CudaVectorTypes >::init(Main* m, VecCoord& x) -{ - Data& data = *m->data; - const SetIndexArray & indices = m->m_indices.getValue(); -// m->x0.resize( indices.size() ); -// for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) -// m->x0[*it] = x[*it]; - - // gpu part - data.size = indices.size(); - data.indices.resize(data.size); - unsigned index =0; - for (typename SetIndex::const_iterator it = indices.begin(); it != indices.end(); it++) - { - data.indices[index] = *it; - index++; - } - - data.x0.resize(data.size); - index = 0; - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - data.x0[index] = x[*it]; - index++; - } -}// LinearMovementConstraintInternalData::init - -template -void LinearMovementConstraintInternalData< gpu::cuda::CudaVectorTypes >::projectResponse(Main* m, VecDeriv& dx) -{ - Data& data = *m->data; - - Real cT = (Real) m->getContext()->getTime(); - - if ((cT != m->currentTime) || !m->finished) - { - m->findKeyTimes(); - } - - if (m->finished && m->nextT != m->prevT) - { - Kernels::projectResponse( - data.size, - data.indices.deviceRead(), - dx.deviceWrite() - ); - } -}// LinearMovementConstraintInternalData::projectResponse - -template -void LinearMovementConstraintInternalData< gpu::cuda::CudaVectorTypes >::projectPosition(Main* m, VecCoord& x) -{ - Data& data = *m->data; - - Real cT = (Real) m->getContext()->getTime(); - - // initialize initial Dofs positions, if it's not done - if (data.x0.size() == 0) - { - data.init(m, x); - } - - if ((cT != m->currentTime) || !m->finished) - { - m->findKeyTimes(); - } - - if (m->finished && m->nextT != m->prevT) - { - Real dt = (cT - m->prevT) / (m->nextT - m->prevT); - Deriv depl = m->prevM + (m->nextM-m->prevM)*dt; - - Kernels::projectPosition( - data.size, - data.indices.deviceRead(), - depl.ptr(), - data.x0.deviceRead(), - x.deviceWrite() - ); - } -}// LinearMovementConstraintInternalData::projectPosition - -template -void LinearMovementConstraintInternalData< gpu::cuda::CudaVectorTypes >::projectVelocity(Main* m, VecDeriv& dx) -{ - Data& data = *m->data; - - Real cT = (Real) m->getContext()->getTime(); - - if ((cT != m->currentTime) || !m->finished) - m->findKeyTimes(); - - if (m->finished && m->nextT != m->prevT) - { - Deriv dv = (m->nextM - m->prevM)*(1.0/(m->nextT - m->prevT)); - - Kernels::projectVelocity( - data.size, - data.indices.deviceRead(), - dv.ptr(), - dx.deviceWrite() - ); - } -}// LinearMovementConstraintInternalData::projectVelocity - - -///////////////////////////////////// -// CudaRigidTypes specializations -///////////////////////////////////// - -template -void LinearMovementConstraintInternalData< gpu::cuda::CudaRigidTypes >::addIndex(Main* m, Index index) -{ - Data& data = *m->data; - - m->m_indices.beginEdit()->push_back(index); - m->m_indices.endEdit(); - - data.indices.push_back(index); - // TODO : then it becomes non-consistent and also in the main version !!! -// data.x0.push_back(); - -}// LinearMovementConstraintInternalData::addIndex - -template -void LinearMovementConstraintInternalData< gpu::cuda::CudaRigidTypes >::removeIndex(Main* m, Index index) -{ - // Data& data = m->data; - - removeValue(*m->m_indices.beginEdit(),index); - m->m_indices.endEdit(); - - // removeValue(data.indices, index); - // TODO : then it becomes non-consistent and also in the main version !!! -// data.x0.push_back(); - -}// LinearMovementConstraintInternalData::removeIndex - -template -void LinearMovementConstraintInternalData< gpu::cuda::CudaRigidTypes >::init(Main* m, VecCoord& x) -{ - Data& data = *m->data; - const SetIndexArray & indices = m->m_indices.getValue(); -// m->x0.resize( indices.size() ); -// for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) -// m->x0[*it] = x[*it]; - - // gpu part - data.size = indices.size(); - data.indices.resize(data.size); - unsigned index =0; - for (typename SetIndex::const_iterator it = indices.begin(); it != indices.end(); it++) - { - data.indices[index] = *it; - index++; - } - - data.x0.resize(data.size); - index = 0; - for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) - { - data.x0[index] = x[*it]; - index++; - } -}// LinearMovementConstraintInternalData::init - -template -void LinearMovementConstraintInternalData< gpu::cuda::CudaRigidTypes >::projectResponse(Main* m, VecDeriv& dx) -{ - Data& data = *m->data; - - Real cT = (Real) m->getContext()->getTime(); - - if ((cT != m->currentTime) || !m->finished) - { - m->findKeyTimes(); - } - - if (m->finished && m->nextT != m->prevT) - { - Kernels::projectResponse( - data.size, - data.indices.deviceRead(), - dx.deviceWrite() - ); - } -}// LinearMovementConstraintInternalData::projectResponse - -template -void LinearMovementConstraintInternalData< gpu::cuda::CudaRigidTypes >::projectPosition(Main* m, VecCoord& x) -{ - Data& data = *m->data; - - Real cT = (Real) m->getContext()->getTime(); - - // initialize initial Dofs positions, if it's not done - if (data.x0.size() == 0) - { - data.init(m, x); - } - - if ((cT != m->currentTime) || !m->finished) - { - m->findKeyTimes(); - } - - if (m->finished && m->nextT != m->prevT) - { - Real dt = (cT - m->prevT) / (m->nextT - m->prevT); - Deriv depl = m->prevM + (m->nextM-m->prevM)*dt; - - Kernels::projectPosition( - data.size, - data.indices.deviceRead(), - depl.ptr(), - data.x0.deviceRead(), - x.deviceWrite() - ); - } -}// LinearMovementConstraintInternalData::projectPosition - -template -void LinearMovementConstraintInternalData< gpu::cuda::CudaRigidTypes >::projectVelocity(Main* m, VecDeriv& dx) -{ - Data& data = *m->data; - - Real cT = (Real) m->getContext()->getTime(); - - if ((cT != m->currentTime) || !m->finished) - m->findKeyTimes(); - - if (m->finished && m->nextT != m->prevT) - { - Deriv dv = (m->nextM - m->prevM)*(1.0/(m->nextT - m->prevT)); - - Kernels::projectVelocity( - data.size, - data.indices.deviceRead(), - dv.ptr(), - dx.deviceWrite() - ); - } -}// LinearMovementConstraintInternalData::projectVelocity - - -////////////////////////////// -// Specializations -///////////////////////////// - -// template<> -// void LinearMovementConstraint< gpu::cuda::CudaRigid3fTypes >::init() -// { -// data.init(this); -// } - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6fTypes >::addIndex(Index index) -{ - data->addIndex(this, index); -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6fTypes >::removeIndex(Index index) -{ - data->removeIndex(this, index); -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6fTypes >::projectResponse(const core::MechanicalParams* /* mparams */, DataVecDeriv& dx) -{ - VecDeriv& _dx = *dx.beginEdit(); - data->projectResponse(this, _dx); - dx.endEdit(); -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6fTypes >::projectJacobianMatrix(const core::MechanicalParams* /* mparams */, DataMatrixDeriv& /*dx*/) -{ - /* data.projectResponseT(this, index); */ -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6fTypes >::projectPosition(const core::MechanicalParams* /* mparams */, DataVecCoord& x) -{ - VecCoord& _x = *x.beginEdit(); - data->projectPosition(this, _x); - x.endEdit(); -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6fTypes >::projectVelocity(const core::MechanicalParams* /* mparams */, DataVecDeriv& dx) -{ - VecDeriv& _dx = *dx.beginEdit(); - data->projectVelocity(this, _dx); - dx.endEdit(); -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3fTypes >::addIndex(Index index) -{ - data->addIndex(this, index); -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3fTypes >::removeIndex(Index index) -{ - data->removeIndex(this, index); -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3fTypes >::projectResponse(const core::MechanicalParams* /* mparams */, DataVecDeriv& dx) -{ - VecDeriv& _dx = *dx.beginEdit(); - data->projectResponse(this, _dx); - dx.endEdit(); -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3fTypes >::projectJacobianMatrix(const core::MechanicalParams* /* mparams */, DataMatrixDeriv& /*dx*/) -{ - /* data.projectResponseT(this, index); */ -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3fTypes >::projectPosition(const core::MechanicalParams* /* mparams */, DataVecCoord& x) -{ - VecCoord& _x = *x.beginEdit(); - data->projectPosition(this, _x); - x.endEdit(); -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3fTypes >::projectVelocity(const core::MechanicalParams* /* mparams */, DataVecDeriv& dx) -{ - VecDeriv& _dx = *dx.beginEdit(); - data->projectVelocity(this, _dx); - dx.endEdit(); -} - -#ifdef SOFA_GPU_CUDA_DOUBLE -// template<> -// void LinearMovementConstraint< gpu::cuda::CudaRigid3dTypes >::init() -// { -// data->init(this); -// } - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6dTypes >::addIndex(Index index) -{ - data->addIndex(this, index); -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6dTypes >::removeIndex(Index index) -{ - data->removeIndex(this, index); -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6dTypes >::projectResponse(const core::MechanicalParams* /* mparams */, DataVecDeriv& dx) -{ - VecDeriv& _dx = *dx.beginEdit(); - data->projectResponse(this, _dx); - dx.endEdit(); -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6dTypes >::projectJacobianMatrix(const core::MechanicalParams* /* mparams */, DataMatrixDeriv& /*dx*/) -{ - /* data.projectResponseT(this, index); */ -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6dTypes >::projectPosition(const core::MechanicalParams* /* mparams */, DataVecCoord& x) -{ - VecCoord& _x = *x.beginEdit(); - data->projectPosition(this, _x); - x.endEdit(); -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaVec6dTypes >::projectVelocity(const core::MechanicalParams* /* mparams */, DataVecDeriv& dx) -{ - VecDeriv& _dx = *dx.beginEdit(); - data->projectVelocity(this, _dx); - dx.endEdit(); -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3dTypes >::addIndex(Index index) -{ - data->addIndex(this, index); -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3dTypes >::removeIndex(Index index) -{ - data->removeIndex(this, index); -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3dTypes >::projectResponse(const core::MechanicalParams* /* mparams */, DataVecDeriv& dx) -{ - VecDeriv& _dx = *dx.beginEdit(); - data->projectResponse(this, _dx); - dx.endEdit(); -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3dTypes >::projectJacobianMatrix(const core::MechanicalParams* /* mparams */, DataMatrixDeriv& /*dx*/) -{ - /* data.projectResponseT(this, index); */ -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3dTypes >::projectPosition(const core::MechanicalParams* /* mparams */, DataVecCoord& x) -{ - VecCoord& _x = *x.beginEdit(); - data->projectPosition(this, _x); - x.endEdit(); -} - -template<> -void LinearMovementConstraint< gpu::cuda::CudaRigid3dTypes >::projectVelocity(const core::MechanicalParams* /* mparams */, DataVecDeriv& dx) -{ - VecDeriv& _dx = *dx.beginEdit(); - data->projectVelocity(this, _dx); - dx.endEdit(); -} - -#endif // SOFA_GPU_CUDA_DOUBLE - -} // namespace sofa::component::constraint::projective +SOFA_DEPRECATED_HEADER("v23.12", "v24.12", "SofaCUDA/component/constraint/projective/CudaLinearMovementProjectiveConstraint.inl") diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementConstraint.cpp b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementProjectiveConstraint.cpp similarity index 72% rename from applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementConstraint.cpp rename to applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementProjectiveConstraint.cpp index 6968e2ddfed..2ef5054b202 100644 --- a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementConstraint.cpp +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementProjectiveConstraint.cpp @@ -20,7 +20,7 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #include -#include +#include #include #include @@ -41,16 +41,16 @@ namespace sofa::gpu::cuda { -int LinearMovementConstraintCudaClass = core::RegisterObject("Supports GPU-side computations using CUDA") -// .add< component::constraint::projective::LinearMovementConstraint >() -// .add< component::constraint::projective::LinearMovementConstraint >() - .add< component::constraint::projective::LinearMovementConstraint >() - .add< component::constraint::projective::LinearMovementConstraint >() +int LinearMovementProjectiveConstraintCudaClass = core::RegisterObject("Supports GPU-side computations using CUDA") +// .add< component::constraint::projective::LinearMovementProjectiveConstraint >() +// .add< component::constraint::projective::LinearMovementProjectiveConstraint >() + .add< component::constraint::projective::LinearMovementProjectiveConstraint >() + .add< component::constraint::projective::LinearMovementProjectiveConstraint >() #ifdef SOFA_GPU_CUDA_DOUBLE -// .add< component::constraint::projective::LinearMovementConstraint >() -// .add< component::constraint::projective::LinearMovementConstraint >() - .add< component::constraint::projective::LinearMovementConstraint >() - .add< component::constraint::projective::LinearMovementConstraint >() +// .add< component::constraint::projective::LinearMovementProjectiveConstraint >() +// .add< component::constraint::projective::LinearMovementProjectiveConstraint >() + .add< component::constraint::projective::LinearMovementProjectiveConstraint >() + .add< component::constraint::projective::LinearMovementProjectiveConstraint >() #endif // SOFA_GPU_CUDA_DOUBLE ; diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementProjectiveConstraint.cu b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementProjectiveConstraint.cu new file mode 100644 index 00000000000..d315362b0de --- /dev/null +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementProjectiveConstraint.cu @@ -0,0 +1,208 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#include +#include +#include "cuda.h" +#include + +#if defined(__cplusplus) && CUDA_VERSION < 2000 +namespace sofa +{ +namespace gpu +{ +namespace cuda +{ +#endif + +extern "C" +{ + + void LinearMovementProjectiveConstraintCudaVec6f_projectResponseIndexed(unsigned size, const void* indices, void* dx); + void LinearMovementProjectiveConstraintCudaVec6f_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x); + void LinearMovementProjectiveConstraintCudaVec6f_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx); + void LinearMovementProjectiveConstraintCudaRigid3f_projectResponseIndexed(unsigned size, const void* indices, void* dx); + void LinearMovementProjectiveConstraintCudaRigid3f_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x); + void LinearMovementProjectiveConstraintCudaRigid3f_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx); + +#ifdef SOFA_GPU_CUDA_DOUBLE + void LinearMovementProjectiveConstraintCudaVec6d_projectResponseIndexed(unsigned size, const void* indices, void* dx); + void LinearMovementProjectiveConstraintCudaVec6d_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x); + void LinearMovementProjectiveConstraintCudaVec6d_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx); + void LinearMovementProjectiveConstraintCudaRigid3d_projectResponseIndexed(unsigned size, const void* indices, void* dx); + void LinearMovementProjectiveConstraintCudaRigid3d_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x); + void LinearMovementProjectiveConstraintCudaRigid3d_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx); +#endif // SOFA_GPU_CUDA_DOUBLE + +}// extern "C" + +////////////////////// +// GPU-side methods // +////////////////////// + +template +__global__ void LinearMovementProjectiveConstraintCudaVec6t_projectPositionIndexed_kernel(unsigned size, const int* indices, real dirX, real dirY, real dirZ, real dirU, real dirV, real dirW, const CudaVec6* x0, CudaVec6* x) +{ + int index = blockIdx.x * BSIZE+threadIdx.x; + + CudaVec6 m = CudaVec6::make(dirX, dirY, dirZ, dirU, dirV, dirW); + if (index < size) + { + x[indices[index]] = x0[index]; + x[indices[index]] += m; + } +}// projectPositionIndexed_kernel + +template +__global__ void LinearMovementProjectiveConstraintCudaRigid3t_projectResponseIndexed_kernel(unsigned size, const int* indices, CudaRigidDeriv3* dx) +{ + int index = blockIdx.x * BSIZE+threadIdx.x; + + if (index < size) + { + dx[indices[index]] = CudaRigidDeriv3::make(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); + } +}// kernel Indexed Cuda3t1 + +template +__global__ void LinearMovementProjectiveConstraintCudaRigid3t_projectPositionIndexed_kernel(unsigned size, const int* indices, real dirX, real dirY, real dirZ, real dirU, real dirV, real dirW, const CudaRigidCoord3* x0, CudaRigidCoord3* x) +{ + int index = blockIdx.x * BSIZE+threadIdx.x; + + CudaRigidCoord3 m = CudaRigidCoord3::make(dirX, dirY, dirZ, dirU, dirV, dirW, 0.0); + if (index < size) + { + x[indices[index]] = x0[index]; + x[indices[index]] += m; + } +}// projectPositionIndexed_kernel + + +template +__global__ void LinearMovementProjectiveConstraintCudaRigid3t_projectVelocityIndexed_kernel(unsigned size, const int* indices, real velX, real velY, real velZ, real velU, real velV, real velW, CudaRigidDeriv3* dx) +{ + int index = blockIdx.x * BSIZE+threadIdx.x; + + CudaRigidDeriv3 vel = CudaRigidDeriv3::make(velX, velY, velZ, velU, velV, velW); + if (index < size) + { + dx[indices[index]] = vel; + } +}// projectVelocityIndexed_kernel + +////////////////////// +// CPU-side methods // +////////////////////// +void LinearMovementProjectiveConstraintCudaVec6f_projectResponseIndexed(unsigned size, const void* indices, void* dx) +{ + dim3 threads(BSIZE, 1); + dim3 grid((size+BSIZE-1)/BSIZE,1); + {LinearMovementProjectiveConstraintCudaRigid3t_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaRigidDeriv3*)dx); mycudaDebugError("LinearMovementProjectiveConstraintCudaRigid3t_projectResponseIndexed_kernel");} +} + +void LinearMovementProjectiveConstraintCudaVec6f_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x) +{ + dim3 threads(BSIZE, 1); + dim3 grid((size+BSIZE-1)/BSIZE,1); + LinearMovementProjectiveConstraintCudaVec6t_projectPositionIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, + ((float*)dir)[0], ((float*)dir)[1], ((float*)dir)[2], ((float*)dir)[3], ((float*)dir)[4], ((float*)dir)[5], + (const CudaVec6*) x0, (CudaVec6*)x); +} + +void LinearMovementProjectiveConstraintCudaVec6f_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx) +{ + dim3 threads(BSIZE, 1); + dim3 grid((size+BSIZE-1)/BSIZE,1); + {LinearMovementProjectiveConstraintCudaRigid3t_projectVelocityIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, ((float*)dir)[0], ((float*)dir)[1], ((float*)dir)[2], ((float*)dir)[3], ((float*)dir)[4], ((float*)dir)[5], (CudaRigidDeriv3*)dx); mycudaDebugError("LinearMovementProjectiveConstraintCudaRigid3t_projectVelocityIndexed_kernel");} +} +void LinearMovementProjectiveConstraintCudaRigid3f_projectResponseIndexed(unsigned size, const void* indices, void* dx) +{ + dim3 threads(BSIZE, 1); + dim3 grid((size+BSIZE-1)/BSIZE,1); + {LinearMovementProjectiveConstraintCudaRigid3t_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaRigidDeriv3*)dx); mycudaDebugError("LinearMovementProjectiveConstraintCudaRigid3t_projectResponseIndexed_kernel");} +} + +void LinearMovementProjectiveConstraintCudaRigid3f_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x) +{ + dim3 threads(BSIZE, 1); + dim3 grid((size+BSIZE-1)/BSIZE,1); + {LinearMovementProjectiveConstraintCudaRigid3t_projectPositionIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, ((float*)dir)[0], ((float*)dir)[1], ((float*)dir)[2], ((float*)dir)[3], ((float*)dir)[4], ((float*)dir)[5], (const CudaRigidCoord3*) x0, (CudaRigidCoord3*)x); mycudaDebugError("LinearMovementProjectiveConstraintCudaRigid3t_projectPositionIndexed_kernel");} +} + +void LinearMovementProjectiveConstraintCudaRigid3f_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx) +{ + dim3 threads(BSIZE, 1); + dim3 grid((size+BSIZE-1)/BSIZE,1); + {LinearMovementProjectiveConstraintCudaRigid3t_projectVelocityIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, ((float*)dir)[0], ((float*)dir)[1], ((float*)dir)[2], ((float*)dir)[3], ((float*)dir)[4], ((float*)dir)[5], (CudaRigidDeriv3*)dx); mycudaDebugError("LinearMovementProjectiveConstraintCudaRigid3t_projectVelocityIndexed_kernel");} +} + +#ifdef SOFA_GPU_CUDA_DOUBLE +void LinearMovementProjectiveConstraintCudaVec6d_projectResponseIndexed(unsigned size, const void* indices, void* dx) +{ + dim3 threads(BSIZE, 1); + dim3 grid((size+BSIZE-1)/BSIZE,1); + {LinearMovementProjectiveConstraintCudaRigid3t_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaRigidDeriv3*)dx); mycudaDebugError("LinearMovementProjectiveConstraintCudaRigid3t_projectResponseIndexed_kernel");} +} + +void LinearMovementProjectiveConstraintCudaVec6d_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x) +{ + dim3 threads(BSIZE, 1); + dim3 grid((size+BSIZE-1)/BSIZE,1); + LinearMovementProjectiveConstraintCudaVec6t_projectPositionIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, + ((double*)dir)[0], ((double*)dir)[1], ((double*)dir)[2], ((double*)dir)[3], ((double*)dir)[4], ((double*)dir)[5], + (const CudaVec6*) x0, (CudaVec6*)x); +} + +void LinearMovementProjectiveConstraintCudaVec6d_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx) +{ + dim3 threads(BSIZE, 1); + dim3 grid((size+BSIZE-1)/BSIZE,1); + {LinearMovementProjectiveConstraintCudaRigid3t_projectVelocityIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, ((double*)dir)[0], ((double*)dir)[1], ((double*)dir)[2], ((double*)dir)[3], ((double*)dir)[4], ((double*)dir)[5], (CudaRigidDeriv3*)dx); mycudaDebugError("LinearMovementProjectiveConstraintCudaRigid3t_projectVelocityIndexed_kernel");} +} + +void LinearMovementProjectiveConstraintCudaRigid3d_projectResponseIndexed(unsigned size, const void* indices, void* dx) +{ + dim3 threads(BSIZE, 1); + dim3 grid((size+BSIZE-1)/BSIZE,1); + {LinearMovementProjectiveConstraintCudaRigid3t_projectResponseIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, (CudaRigidDeriv3*)dx); mycudaDebugError("LinearMovementProjectiveConstraintCudaRigid3t_projectResponseIndexed_kernel");} +} + +void LinearMovementProjectiveConstraintCudaRigid3d_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x) +{ + dim3 threads(BSIZE, 1); + dim3 grid((size+BSIZE-1)/BSIZE,1); + {LinearMovementProjectiveConstraintCudaRigid3t_projectPositionIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, ((double*)dir)[0], ((double*)dir)[1], ((double*)dir)[2], ((double*)dir)[3], ((double*)dir)[4], ((double*)dir)[5], (const CudaRigidCoord3*) x0, (CudaRigidCoord3*)x); mycudaDebugError("LinearMovementProjectiveConstraintCudaRigid3t_projectPositionIndexed_kernel");} +} + +void LinearMovementProjectiveConstraintCudaRigid3d_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx) +{ + dim3 threads(BSIZE, 1); + dim3 grid((size+BSIZE-1)/BSIZE,1); + {LinearMovementProjectiveConstraintCudaRigid3t_projectVelocityIndexed_kernel<<< grid, threads >>>(size, (const int*)indices, ((double*)dir)[0], ((double*)dir)[1], ((double*)dir)[2], ((double*)dir)[3], ((double*)dir)[4], ((double*)dir)[5], (CudaRigidDeriv3*)dx); mycudaDebugError("LinearMovementProjectiveConstraintCudaRigid3t_projectVelocityIndexed_kernel");} +} + +#endif // SOFA_GPU_CUDA_DOUBLE + +#if defined(__cplusplus) && CUDA_VERSION < 2000 +} // namespace cuda +} // namespace gpu +} // namespace sofa +#endif diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementProjectiveConstraint.h b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementProjectiveConstraint.h new file mode 100644 index 00000000000..be287995b87 --- /dev/null +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementProjectiveConstraint.h @@ -0,0 +1,210 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include + +namespace sofa::gpu::cuda +{ + +template +class CudaKernelsLinearMovementProjectiveConstraint; + +}// namespace sofa::gpu::cuda + +namespace sofa::component::constraint::projective +{ + +template +class LinearMovementProjectiveConstraintInternalData< gpu::cuda::CudaVectorTypes > +{ +public: + using Index = sofa::Index; + typedef LinearMovementProjectiveConstraintInternalData< gpu::cuda::CudaVectorTypes > Data; + typedef gpu::cuda::CudaVectorTypes DataTypes; + typedef LinearMovementProjectiveConstraint Main; + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::MatrixDeriv::RowType MatrixDerivRowType; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::Real Real; + typedef typename DataTypes::Coord Coord; + typedef type::vector SetIndexArray; + typedef sofa::core::topology::PointSubsetData< SetIndexArray > SetIndex; + + typedef sofa::core::objectmodel::Data DataVecDeriv; + typedef sofa::core::objectmodel::Data DataMatrixDeriv; + + typedef gpu::cuda::CudaKernelsLinearMovementProjectiveConstraint Kernels; + + // vector of indices for general case + gpu::cuda::CudaVector indices; + + // initial positions + gpu::cuda::CudaVector x0; + + int size; + + static void init(Main* m, VecCoord& x); + + static void addIndex(Main* m, Index index); + + static void removeIndex(Main* m, Index index); + + static void projectResponse(Main* m, VecDeriv& dx); + static void projectPosition(Main* m, VecCoord& x); + static void projectVelocity(Main* m, VecDeriv& dx); + +}; + + +template +class LinearMovementProjectiveConstraintInternalData< gpu::cuda::CudaRigidTypes > +{ +public: + using Index = sofa::Index; + typedef LinearMovementProjectiveConstraintInternalData< gpu::cuda::CudaRigidTypes > Data; + typedef gpu::cuda::CudaRigidTypes DataTypes; + typedef LinearMovementProjectiveConstraint Main; + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::VecDeriv VecDeriv; + typedef typename DataTypes::MatrixDeriv MatrixDeriv; + typedef typename DataTypes::MatrixDeriv::RowType MatrixDerivRowType; + typedef typename DataTypes::Deriv Deriv; + typedef typename DataTypes::Real Real; + typedef typename DataTypes::Coord Coord; + typedef type::vector SetIndexArray; + typedef sofa::core::topology::PointSubsetData< SetIndexArray > SetIndex; + + typedef sofa::core::objectmodel::Data DataVecDeriv; + typedef sofa::core::objectmodel::Data DataMatrixDeriv; + + typedef gpu::cuda::CudaKernelsLinearMovementProjectiveConstraint Kernels; + + // vector of indices for general case + gpu::cuda::CudaVector indices; + + // initial positions + gpu::cuda::CudaVector x0; + + int size; + + static void init(Main* m, VecCoord& x); + + static void addIndex(Main* m, Index index); + + static void removeIndex(Main* m, Index index); + + static void projectResponse(Main* m, VecDeriv& dx); + static void projectPosition(Main* m, VecCoord& x); + static void projectVelocity(Main* m, VecDeriv& dx); + +}; + + +// template<> +// void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3fTypes >::init(); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6fTypes >::addIndex(Index index); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6fTypes >::removeIndex(Index index); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6fTypes >::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& dx); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6fTypes >::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& dx); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6fTypes >::projectPosition(const core::MechanicalParams* mparams, DataVecCoord& x); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6fTypes >::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& dx); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3fTypes >::addIndex(Index index); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3fTypes >::removeIndex(Index index); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3fTypes >::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& dx); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3fTypes >::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& dx); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3fTypes >::projectPosition(const core::MechanicalParams* mparams, DataVecCoord& x); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3fTypes >::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& dx); + +#ifdef SOFA_GPU_CUDA_DOUBLE + +// template<> +// void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3dTypes >::init(); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6dTypes >::addIndex(Index index); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6dTypes >::removeIndex(Index index); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6dTypes >::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& dx); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6dTypes >::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& dx); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6dTypes >::projectPosition(const core::MechanicalParams* mparams, DataVecCoord& x); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6dTypes >::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& dx); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3dTypes >::addIndex(Index index); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3dTypes >::removeIndex(Index index); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3dTypes >::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& dx); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3dTypes >::projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& dx); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3dTypes >::projectPosition(const core::MechanicalParams* mparams, DataVecCoord& x); + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3dTypes >::projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& dx); + +#endif // SOFA_GPU_CUDA_DOUBLE + + + +} // namespace sofa::component::constraint::projective diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementProjectiveConstraint.inl b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementProjectiveConstraint.inl new file mode 100644 index 00000000000..e3f00a0f5d7 --- /dev/null +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearMovementProjectiveConstraint.inl @@ -0,0 +1,596 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include + +namespace sofa::gpu::cuda +{ + +extern "C" +{ + + void LinearMovementProjectiveConstraintCudaVec6f_projectResponseIndexed(unsigned size, const void* indices, void* dx); + void LinearMovementProjectiveConstraintCudaVec6f_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x); + void LinearMovementProjectiveConstraintCudaVec6f_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx); + void LinearMovementProjectiveConstraintCudaRigid3f_projectResponseIndexed(unsigned size, const void* indices, void* dx); + void LinearMovementProjectiveConstraintCudaRigid3f_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x); + void LinearMovementProjectiveConstraintCudaRigid3f_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx); + +#ifdef SOFA_GPU_CUDA_DOUBLE + void LinearMovementProjectiveConstraintCudaVec6d_projectResponseIndexed(unsigned size, const void* indices, void* dx); + void LinearMovementProjectiveConstraintCudaVec6d_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x); + void LinearMovementProjectiveConstraintCudaVec6d_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx); + void LinearMovementProjectiveConstraintCudaRigid3d_projectResponseIndexed(unsigned size, const void* indices, void* dx); + void LinearMovementProjectiveConstraintCudaRigid3d_projectPositionIndexed(unsigned size, const void* indices, const void* dir, const void* x0, void* x); + void LinearMovementProjectiveConstraintCudaRigid3d_projectVelocityIndexed(unsigned size, const void* indices, const void* dir, void* dx); +#endif // SOFA_GPU_CUDA_DOUBLE + +}// extern "C" + +template<> +class CudaKernelsLinearMovementProjectiveConstraint< CudaVec6fTypes > +{ +public: + static void projectResponse(unsigned size, const void* indices, void* dx) + { + LinearMovementProjectiveConstraintCudaVec6f_projectResponseIndexed(size, indices, dx); + } + static void projectPosition(unsigned size, const void* indices, const void* dir, const void* x0, void* x) + { + LinearMovementProjectiveConstraintCudaVec6f_projectPositionIndexed(size, indices, dir, x0, x); + } + static void projectVelocity(unsigned size, const void* indices, const void* dir, void* dx) + { + LinearMovementProjectiveConstraintCudaVec6f_projectVelocityIndexed(size, indices, dir, dx); + } +};// CudaKernelsLinearMovementProjectiveConstraint + +template<> +class CudaKernelsLinearMovementProjectiveConstraint< CudaRigid3fTypes > +{ +public: + static void projectResponse(unsigned size, const void* indices, void* dx) + { + LinearMovementProjectiveConstraintCudaRigid3f_projectResponseIndexed(size, indices, dx); + } + static void projectPosition(unsigned size, const void* indices, const void* dir, const void* x0, void* x) + { + LinearMovementProjectiveConstraintCudaRigid3f_projectPositionIndexed(size, indices, dir, x0, x); + } + static void projectVelocity(unsigned size, const void* indices, const void* dir, void* dx) + { + LinearMovementProjectiveConstraintCudaRigid3f_projectVelocityIndexed(size, indices, dir, dx); + } +};// CudaKernelsLinearMovementProjectiveConstraint + +#ifdef SOFA_GPU_CUDA_DOUBLE + +template<> +class CudaKernelsLinearMovementProjectiveConstraint< CudaVec6dTypes > +{ +public: + static void projectResponse(unsigned size, const void* indices, void* dx) + { + LinearMovementProjectiveConstraintCudaVec6d_projectResponseIndexed(size, indices, dx); + } + static void projectPosition(unsigned size, const void* indices, const void* dir, const void* x0, void* x) + { + LinearMovementProjectiveConstraintCudaVec6d_projectPositionIndexed(size, indices, dir, x0, x); + } + static void projectVelocity(unsigned size, const void* indices, const void* dir, void* dx) + { + LinearMovementProjectiveConstraintCudaVec6d_projectVelocityIndexed(size, indices, dir, dx); + } +};// CudaKernelsLinearMovementProjectiveConstraint + +template<> +class CudaKernelsLinearMovementProjectiveConstraint< CudaRigid3dTypes > +{ +public: + static void projectResponse(unsigned size, const void* indices, void* dx) + { + LinearMovementProjectiveConstraintCudaRigid3d_projectResponseIndexed(size, indices, dx); + } + static void projectPosition(unsigned size, const void* indices, const void* dir, const void* x0, void* x) + { + LinearMovementProjectiveConstraintCudaRigid3d_projectPositionIndexed(size, indices, dir, x0, x); + } + static void projectVelocity(unsigned size, const void* indices, const void* dir, void* dx) + { + LinearMovementProjectiveConstraintCudaRigid3d_projectVelocityIndexed(size, indices, dir, dx); + } +};// CudaKernelsLinearMovementProjectiveConstraint + +#endif // SOFA_GPU_CUDA_DOUBLE + +} // namespace sofa::gpu::cuda + +namespace sofa::component::constraint::projective +{ + +///////////////////////////////////// +// CudaVectorTypes specializations +///////////////////////////////////// +template +void LinearMovementProjectiveConstraintInternalData< gpu::cuda::CudaVectorTypes >::addIndex(Main* m, Index index) +{ + Data& data = *m->data; + + m->m_indices.beginEdit()->push_back(index); + m->m_indices.endEdit(); + + data.indices.push_back(index); + // TODO : then it becomes non-consistent and also in the main version !!! +// data.x0.push_back(); + +}// LinearMovementProjectiveConstraintInternalData::addIndex + +template +void LinearMovementProjectiveConstraintInternalData< gpu::cuda::CudaVectorTypes >::removeIndex(Main* m, Index index) +{ + // Data& data = m->data; + + removeValue(*m->m_indices.beginEdit(),index); + m->m_indices.endEdit(); + + // removeValue(data.indices, index); + // TODO : then it becomes non-consistent and also in the main version !!! +// data.x0.push_back(); + +}// LinearMovementProjectiveConstraintInternalData::removeIndex + +template +void LinearMovementProjectiveConstraintInternalData< gpu::cuda::CudaVectorTypes >::init(Main* m, VecCoord& x) +{ + Data& data = *m->data; + const SetIndexArray & indices = m->m_indices.getValue(); +// m->x0.resize( indices.size() ); +// for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) +// m->x0[*it] = x[*it]; + + // gpu part + data.size = indices.size(); + data.indices.resize(data.size); + unsigned index =0; + for (typename SetIndex::const_iterator it = indices.begin(); it != indices.end(); it++) + { + data.indices[index] = *it; + index++; + } + + data.x0.resize(data.size); + index = 0; + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + data.x0[index] = x[*it]; + index++; + } +}// LinearMovementProjectiveConstraintInternalData::init + +template +void LinearMovementProjectiveConstraintInternalData< gpu::cuda::CudaVectorTypes >::projectResponse(Main* m, VecDeriv& dx) +{ + Data& data = *m->data; + + Real cT = (Real) m->getContext()->getTime(); + + if ((cT != m->currentTime) || !m->finished) + { + m->findKeyTimes(); + } + + if (m->finished && m->nextT != m->prevT) + { + Kernels::projectResponse( + data.size, + data.indices.deviceRead(), + dx.deviceWrite() + ); + } +}// LinearMovementProjectiveConstraintInternalData::projectResponse + +template +void LinearMovementProjectiveConstraintInternalData< gpu::cuda::CudaVectorTypes >::projectPosition(Main* m, VecCoord& x) +{ + Data& data = *m->data; + + Real cT = (Real) m->getContext()->getTime(); + + // initialize initial Dofs positions, if it's not done + if (data.x0.size() == 0) + { + data.init(m, x); + } + + if ((cT != m->currentTime) || !m->finished) + { + m->findKeyTimes(); + } + + if (m->finished && m->nextT != m->prevT) + { + Real dt = (cT - m->prevT) / (m->nextT - m->prevT); + Deriv depl = m->prevM + (m->nextM-m->prevM)*dt; + + Kernels::projectPosition( + data.size, + data.indices.deviceRead(), + depl.ptr(), + data.x0.deviceRead(), + x.deviceWrite() + ); + } +}// LinearMovementProjectiveConstraintInternalData::projectPosition + +template +void LinearMovementProjectiveConstraintInternalData< gpu::cuda::CudaVectorTypes >::projectVelocity(Main* m, VecDeriv& dx) +{ + Data& data = *m->data; + + Real cT = (Real) m->getContext()->getTime(); + + if ((cT != m->currentTime) || !m->finished) + m->findKeyTimes(); + + if (m->finished && m->nextT != m->prevT) + { + Deriv dv = (m->nextM - m->prevM)*(1.0/(m->nextT - m->prevT)); + + Kernels::projectVelocity( + data.size, + data.indices.deviceRead(), + dv.ptr(), + dx.deviceWrite() + ); + } +}// LinearMovementProjectiveConstraintInternalData::projectVelocity + + +///////////////////////////////////// +// CudaRigidTypes specializations +///////////////////////////////////// + +template +void LinearMovementProjectiveConstraintInternalData< gpu::cuda::CudaRigidTypes >::addIndex(Main* m, Index index) +{ + Data& data = *m->data; + + m->m_indices.beginEdit()->push_back(index); + m->m_indices.endEdit(); + + data.indices.push_back(index); + // TODO : then it becomes non-consistent and also in the main version !!! +// data.x0.push_back(); + +}// LinearMovementProjectiveConstraintInternalData::addIndex + +template +void LinearMovementProjectiveConstraintInternalData< gpu::cuda::CudaRigidTypes >::removeIndex(Main* m, Index index) +{ + // Data& data = m->data; + + removeValue(*m->m_indices.beginEdit(),index); + m->m_indices.endEdit(); + + // removeValue(data.indices, index); + // TODO : then it becomes non-consistent and also in the main version !!! +// data.x0.push_back(); + +}// LinearMovementProjectiveConstraintInternalData::removeIndex + +template +void LinearMovementProjectiveConstraintInternalData< gpu::cuda::CudaRigidTypes >::init(Main* m, VecCoord& x) +{ + Data& data = *m->data; + const SetIndexArray & indices = m->m_indices.getValue(); +// m->x0.resize( indices.size() ); +// for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) +// m->x0[*it] = x[*it]; + + // gpu part + data.size = indices.size(); + data.indices.resize(data.size); + unsigned index =0; + for (typename SetIndex::const_iterator it = indices.begin(); it != indices.end(); it++) + { + data.indices[index] = *it; + index++; + } + + data.x0.resize(data.size); + index = 0; + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) + { + data.x0[index] = x[*it]; + index++; + } +}// LinearMovementProjectiveConstraintInternalData::init + +template +void LinearMovementProjectiveConstraintInternalData< gpu::cuda::CudaRigidTypes >::projectResponse(Main* m, VecDeriv& dx) +{ + Data& data = *m->data; + + Real cT = (Real) m->getContext()->getTime(); + + if ((cT != m->currentTime) || !m->finished) + { + m->findKeyTimes(); + } + + if (m->finished && m->nextT != m->prevT) + { + Kernels::projectResponse( + data.size, + data.indices.deviceRead(), + dx.deviceWrite() + ); + } +}// LinearMovementProjectiveConstraintInternalData::projectResponse + +template +void LinearMovementProjectiveConstraintInternalData< gpu::cuda::CudaRigidTypes >::projectPosition(Main* m, VecCoord& x) +{ + Data& data = *m->data; + + Real cT = (Real) m->getContext()->getTime(); + + // initialize initial Dofs positions, if it's not done + if (data.x0.size() == 0) + { + data.init(m, x); + } + + if ((cT != m->currentTime) || !m->finished) + { + m->findKeyTimes(); + } + + if (m->finished && m->nextT != m->prevT) + { + Real dt = (cT - m->prevT) / (m->nextT - m->prevT); + Deriv depl = m->prevM + (m->nextM-m->prevM)*dt; + + Kernels::projectPosition( + data.size, + data.indices.deviceRead(), + depl.ptr(), + data.x0.deviceRead(), + x.deviceWrite() + ); + } +}// LinearMovementProjectiveConstraintInternalData::projectPosition + +template +void LinearMovementProjectiveConstraintInternalData< gpu::cuda::CudaRigidTypes >::projectVelocity(Main* m, VecDeriv& dx) +{ + Data& data = *m->data; + + Real cT = (Real) m->getContext()->getTime(); + + if ((cT != m->currentTime) || !m->finished) + m->findKeyTimes(); + + if (m->finished && m->nextT != m->prevT) + { + Deriv dv = (m->nextM - m->prevM)*(1.0/(m->nextT - m->prevT)); + + Kernels::projectVelocity( + data.size, + data.indices.deviceRead(), + dv.ptr(), + dx.deviceWrite() + ); + } +}// LinearMovementProjectiveConstraintInternalData::projectVelocity + + +////////////////////////////// +// Specializations +///////////////////////////// + +// template<> +// void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3fTypes >::init() +// { +// data.init(this); +// } + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6fTypes >::addIndex(Index index) +{ + data->addIndex(this, index); +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6fTypes >::removeIndex(Index index) +{ + data->removeIndex(this, index); +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6fTypes >::projectResponse(const core::MechanicalParams* /* mparams */, DataVecDeriv& dx) +{ + VecDeriv& _dx = *dx.beginEdit(); + data->projectResponse(this, _dx); + dx.endEdit(); +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6fTypes >::projectJacobianMatrix(const core::MechanicalParams* /* mparams */, DataMatrixDeriv& /*dx*/) +{ + /* data.projectResponseT(this, index); */ +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6fTypes >::projectPosition(const core::MechanicalParams* /* mparams */, DataVecCoord& x) +{ + VecCoord& _x = *x.beginEdit(); + data->projectPosition(this, _x); + x.endEdit(); +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6fTypes >::projectVelocity(const core::MechanicalParams* /* mparams */, DataVecDeriv& dx) +{ + VecDeriv& _dx = *dx.beginEdit(); + data->projectVelocity(this, _dx); + dx.endEdit(); +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3fTypes >::addIndex(Index index) +{ + data->addIndex(this, index); +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3fTypes >::removeIndex(Index index) +{ + data->removeIndex(this, index); +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3fTypes >::projectResponse(const core::MechanicalParams* /* mparams */, DataVecDeriv& dx) +{ + VecDeriv& _dx = *dx.beginEdit(); + data->projectResponse(this, _dx); + dx.endEdit(); +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3fTypes >::projectJacobianMatrix(const core::MechanicalParams* /* mparams */, DataMatrixDeriv& /*dx*/) +{ + /* data.projectResponseT(this, index); */ +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3fTypes >::projectPosition(const core::MechanicalParams* /* mparams */, DataVecCoord& x) +{ + VecCoord& _x = *x.beginEdit(); + data->projectPosition(this, _x); + x.endEdit(); +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3fTypes >::projectVelocity(const core::MechanicalParams* /* mparams */, DataVecDeriv& dx) +{ + VecDeriv& _dx = *dx.beginEdit(); + data->projectVelocity(this, _dx); + dx.endEdit(); +} + +#ifdef SOFA_GPU_CUDA_DOUBLE +// template<> +// void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3dTypes >::init() +// { +// data->init(this); +// } + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6dTypes >::addIndex(Index index) +{ + data->addIndex(this, index); +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6dTypes >::removeIndex(Index index) +{ + data->removeIndex(this, index); +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6dTypes >::projectResponse(const core::MechanicalParams* /* mparams */, DataVecDeriv& dx) +{ + VecDeriv& _dx = *dx.beginEdit(); + data->projectResponse(this, _dx); + dx.endEdit(); +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6dTypes >::projectJacobianMatrix(const core::MechanicalParams* /* mparams */, DataMatrixDeriv& /*dx*/) +{ + /* data.projectResponseT(this, index); */ +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6dTypes >::projectPosition(const core::MechanicalParams* /* mparams */, DataVecCoord& x) +{ + VecCoord& _x = *x.beginEdit(); + data->projectPosition(this, _x); + x.endEdit(); +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaVec6dTypes >::projectVelocity(const core::MechanicalParams* /* mparams */, DataVecDeriv& dx) +{ + VecDeriv& _dx = *dx.beginEdit(); + data->projectVelocity(this, _dx); + dx.endEdit(); +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3dTypes >::addIndex(Index index) +{ + data->addIndex(this, index); +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3dTypes >::removeIndex(Index index) +{ + data->removeIndex(this, index); +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3dTypes >::projectResponse(const core::MechanicalParams* /* mparams */, DataVecDeriv& dx) +{ + VecDeriv& _dx = *dx.beginEdit(); + data->projectResponse(this, _dx); + dx.endEdit(); +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3dTypes >::projectJacobianMatrix(const core::MechanicalParams* /* mparams */, DataMatrixDeriv& /*dx*/) +{ + /* data.projectResponseT(this, index); */ +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3dTypes >::projectPosition(const core::MechanicalParams* /* mparams */, DataVecCoord& x) +{ + VecCoord& _x = *x.beginEdit(); + data->projectPosition(this, _x); + x.endEdit(); +} + +template<> +void LinearMovementProjectiveConstraint< gpu::cuda::CudaRigid3dTypes >::projectVelocity(const core::MechanicalParams* /* mparams */, DataVecDeriv& dx) +{ + VecDeriv& _dx = *dx.beginEdit(); + data->projectVelocity(this, _dx); + dx.endEdit(); +} + +#endif // SOFA_GPU_CUDA_DOUBLE + +} // namespace sofa::component::constraint::projective diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearVelocityConstraint.cpp b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearVelocityProjectiveConstraint.cpp similarity index 75% rename from applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearVelocityConstraint.cpp rename to applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearVelocityProjectiveConstraint.cpp index 57c4996f06d..c720af9db74 100644 --- a/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearVelocityConstraint.cpp +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/constraint/projective/CudaLinearVelocityProjectiveConstraint.cpp @@ -20,7 +20,7 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #include -#include +#include #include @@ -28,11 +28,11 @@ namespace sofa::component::constraint::projective { -template class SOFA_GPU_CUDA_API LinearVelocityConstraint; -template class SOFA_GPU_CUDA_API LinearVelocityConstraint; +template class SOFA_GPU_CUDA_API LinearVelocityProjectiveConstraint; +template class SOFA_GPU_CUDA_API LinearVelocityProjectiveConstraint; #ifdef SOFA_GPU_CUDA_DOUBLE -template class SOFA_GPU_CUDA_API LinearVelocityConstraint; -template class SOFA_GPU_CUDA_API LinearVelocityConstraint; +template class SOFA_GPU_CUDA_API LinearVelocityProjectiveConstraint; +template class SOFA_GPU_CUDA_API LinearVelocityProjectiveConstraint; #endif // SOFA_GPU_CUDA_DOUBLE }// namespace sofa::component::constraint::projective @@ -40,12 +40,12 @@ template class SOFA_GPU_CUDA_API LinearVelocityConstraint >() - .add< sofa::component::constraint::projective::LinearVelocityConstraint >() +int LinearVelocityProjectiveConstraintCudaClass = core::RegisterObject("Supports GPU-side computations using CUDA") + .add< sofa::component::constraint::projective::LinearVelocityProjectiveConstraint >() + .add< sofa::component::constraint::projective::LinearVelocityProjectiveConstraint >() #ifdef SOFA_GPU_CUDA_DOUBLE - .add< sofa::component::constraint::projective::LinearVelocityConstraint >() - .add< sofa::component::constraint::projective::LinearVelocityConstraint >() + .add< sofa::component::constraint::projective::LinearVelocityProjectiveConstraint >() + .add< sofa::component::constraint::projective::LinearVelocityProjectiveConstraint >() #endif // SOFA_GPU_CUDA_DOUBLE ; diff --git a/applications/plugins/SofaCarving/examples/CarvingTool.scn b/applications/plugins/SofaCarving/examples/CarvingTool.scn index 90f4e9fb695..c7be2d9f4be 100644 --- a/applications/plugins/SofaCarving/examples/CarvingTool.scn +++ b/applications/plugins/SofaCarving/examples/CarvingTool.scn @@ -5,7 +5,7 @@ - + @@ -43,7 +43,7 @@ - + @@ -66,7 +66,7 @@ - diff --git a/applications/plugins/SofaCarving/examples/SimpleCarving.py b/applications/plugins/SofaCarving/examples/SimpleCarving.py index 037de56f25b..9c453577571 100644 --- a/applications/plugins/SofaCarving/examples/SimpleCarving.py +++ b/applications/plugins/SofaCarving/examples/SimpleCarving.py @@ -59,7 +59,7 @@ def createScene(root): TT.addObject('TetrahedronSetGeometryAlgorithms', template="Vec3d", name="GeomAlgo") TT.addObject('DiagonalMass', massDensity=0.5) - TT.addObject('FixedConstraint', indices=[1, 3, 50]) + TT.addObject('FixedProjectiveConstraint', indices=[1, 3, 50]) TT.addObject('TetrahedralCorotationalFEMForceField', name="CFEM", youngModulus=160, poissonRatio=0.3, method="large") # Add corresponding surface topology diff --git a/applications/plugins/SofaCarving/examples/SimpleCarving.scn b/applications/plugins/SofaCarving/examples/SimpleCarving.scn index 73eece42082..7fa29ef2fcb 100644 --- a/applications/plugins/SofaCarving/examples/SimpleCarving.scn +++ b/applications/plugins/SofaCarving/examples/SimpleCarving.scn @@ -5,7 +5,7 @@ - + @@ -43,7 +43,7 @@ - + diff --git a/applications/plugins/SofaCarving/examples/SimpleCarving_withPenetration.scn b/applications/plugins/SofaCarving/examples/SimpleCarving_withPenetration.scn index b30466918a4..1150c133828 100644 --- a/applications/plugins/SofaCarving/examples/SimpleCarving_withPenetration.scn +++ b/applications/plugins/SofaCarving/examples/SimpleCarving_withPenetration.scn @@ -5,7 +5,7 @@ - + @@ -43,7 +43,7 @@ - + diff --git a/applications/plugins/SofaDistanceGrid/examples/FFDDistanceGridCollisionModel.scn b/applications/plugins/SofaDistanceGrid/examples/FFDDistanceGridCollisionModel.scn index 5f81a39f478..5917bf01f9c 100644 --- a/applications/plugins/SofaDistanceGrid/examples/FFDDistanceGridCollisionModel.scn +++ b/applications/plugins/SofaDistanceGrid/examples/FFDDistanceGridCollisionModel.scn @@ -4,7 +4,7 @@ - + @@ -38,7 +38,7 @@ - + diff --git a/applications/plugins/SofaHAPI/examples/SofaHAPI1.scn b/applications/plugins/SofaHAPI/examples/SofaHAPI1.scn index 39df2f1751d..ef2c5275e58 100644 --- a/applications/plugins/SofaHAPI/examples/SofaHAPI1.scn +++ b/applications/plugins/SofaHAPI/examples/SofaHAPI1.scn @@ -71,7 +71,7 @@ - + @@ -91,7 +91,7 @@ - + diff --git a/applications/plugins/SofaMatrix/examples/ComplianceMatrixExporter.scn b/applications/plugins/SofaMatrix/examples/ComplianceMatrixExporter.scn index 4949de49328..c25e38f1c05 100644 --- a/applications/plugins/SofaMatrix/examples/ComplianceMatrixExporter.scn +++ b/applications/plugins/SofaMatrix/examples/ComplianceMatrixExporter.scn @@ -1,9 +1,9 @@ - + - + @@ -30,12 +30,12 @@ - + - + diff --git a/applications/plugins/SofaMatrix/examples/ComplianceMatrixImage.scn b/applications/plugins/SofaMatrix/examples/ComplianceMatrixImage.scn index d443ea93089..c84dbe04205 100644 --- a/applications/plugins/SofaMatrix/examples/ComplianceMatrixImage.scn +++ b/applications/plugins/SofaMatrix/examples/ComplianceMatrixImage.scn @@ -1,9 +1,9 @@ - + - + @@ -30,12 +30,12 @@ - + - + diff --git a/applications/plugins/SofaMatrix/examples/FillReducingOrdering.scn b/applications/plugins/SofaMatrix/examples/FillReducingOrdering.scn index 6e5f3c40528..637e6cf2317 100644 --- a/applications/plugins/SofaMatrix/examples/FillReducingOrdering.scn +++ b/applications/plugins/SofaMatrix/examples/FillReducingOrdering.scn @@ -7,7 +7,7 @@ The scene compares two simulations in which only the vertices order differs: - The Node "Reorder" simulates the reordered mesh. --> - + @@ -41,7 +41,7 @@ The scene compares two simulations in which only the vertices order differs: - + @@ -63,7 +63,7 @@ The scene compares two simulations in which only the vertices order differs: - + diff --git a/applications/plugins/SofaMatrix/examples/GlobalSystemMatrixExporter.scn b/applications/plugins/SofaMatrix/examples/GlobalSystemMatrixExporter.scn index 7d8cb1f45ab..73aeaaefc6c 100644 --- a/applications/plugins/SofaMatrix/examples/GlobalSystemMatrixExporter.scn +++ b/applications/plugins/SofaMatrix/examples/GlobalSystemMatrixExporter.scn @@ -1,5 +1,5 @@ - + @@ -20,7 +20,7 @@ - + @@ -32,7 +32,7 @@ - + @@ -47,14 +47,14 @@ - + - + diff --git a/applications/plugins/SofaMatrix/examples/GlobalSystemMatrixImage.scn b/applications/plugins/SofaMatrix/examples/GlobalSystemMatrixImage.scn index f7b91bace85..dabb9ac50b3 100644 --- a/applications/plugins/SofaMatrix/examples/GlobalSystemMatrixImage.scn +++ b/applications/plugins/SofaMatrix/examples/GlobalSystemMatrixImage.scn @@ -1,5 +1,5 @@ - + @@ -22,14 +22,14 @@ - + - + diff --git a/applications/plugins/SofaNewmat/examples/MatrixContributions121.scn b/applications/plugins/SofaNewmat/examples/MatrixContributions121.scn index b62ead4bd7a..0531b6a07f9 100644 --- a/applications/plugins/SofaNewmat/examples/MatrixContributions121.scn +++ b/applications/plugins/SofaNewmat/examples/MatrixContributions121.scn @@ -7,7 +7,7 @@ - + @@ -36,7 +36,7 @@ - + @@ -61,7 +61,7 @@ - + diff --git a/applications/plugins/SofaNewmat/examples/MatrixContributions122.scn b/applications/plugins/SofaNewmat/examples/MatrixContributions122.scn index 329845633a7..32e9dbdb8aa 100644 --- a/applications/plugins/SofaNewmat/examples/MatrixContributions122.scn +++ b/applications/plugins/SofaNewmat/examples/MatrixContributions122.scn @@ -7,7 +7,7 @@ - + @@ -35,7 +35,7 @@ - + @@ -52,7 +52,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -83,7 +83,7 @@ - + diff --git a/applications/plugins/SofaNewmat/examples/MatrixContributions123.scn b/applications/plugins/SofaNewmat/examples/MatrixContributions123.scn index 0b01f17072a..92de546a666 100644 --- a/applications/plugins/SofaNewmat/examples/MatrixContributions123.scn +++ b/applications/plugins/SofaNewmat/examples/MatrixContributions123.scn @@ -7,7 +7,7 @@ - + @@ -35,7 +35,7 @@ - + @@ -56,7 +56,7 @@ - + @@ -83,7 +83,7 @@ - + @@ -104,7 +104,7 @@ - + diff --git a/applications/plugins/SofaPardisoSolver/examples/FEMBAR-SparsePARDISOSolver.scn b/applications/plugins/SofaPardisoSolver/examples/FEMBAR-SparsePARDISOSolver.scn index 3c0e22b9c78..72047b6b2c9 100644 --- a/applications/plugins/SofaPardisoSolver/examples/FEMBAR-SparsePARDISOSolver.scn +++ b/applications/plugins/SofaPardisoSolver/examples/FEMBAR-SparsePARDISOSolver.scn @@ -16,7 +16,7 @@ - + diff --git a/applications/plugins/SofaSimpleGUI/examples/liver.scn b/applications/plugins/SofaSimpleGUI/examples/liver.scn index e34960720fd..2ea0cb8954c 100644 --- a/applications/plugins/SofaSimpleGUI/examples/liver.scn +++ b/applications/plugins/SofaSimpleGUI/examples/liver.scn @@ -3,7 +3,7 @@ - + @@ -26,7 +26,7 @@ - + diff --git a/applications/plugins/SofaSimpleGUI/examples/oneTet.scn b/applications/plugins/SofaSimpleGUI/examples/oneTet.scn index 59664aa0625..a11bac2929f 100644 --- a/applications/plugins/SofaSimpleGUI/examples/oneTet.scn +++ b/applications/plugins/SofaSimpleGUI/examples/oneTet.scn @@ -1,7 +1,7 @@ - + @@ -16,7 +16,7 @@ - + diff --git a/applications/plugins/SofaSphFluid/examples/ParticlesRepulsionForceField.scn b/applications/plugins/SofaSphFluid/examples/ParticlesRepulsionForceField.scn index f297af3ddd5..c5e2feef46f 100644 --- a/applications/plugins/SofaSphFluid/examples/ParticlesRepulsionForceField.scn +++ b/applications/plugins/SofaSphFluid/examples/ParticlesRepulsionForceField.scn @@ -4,7 +4,7 @@ - + diff --git a/applications/plugins/SofaTest/Elasticity_test.h b/applications/plugins/SofaTest/Elasticity_test.h index fbe0c742828..1dd3d658302 100644 --- a/applications/plugins/SofaTest/Elasticity_test.h +++ b/applications/plugins/SofaTest/Elasticity_test.h @@ -31,7 +31,7 @@ #include #include -#include +#include #include namespace sofa { @@ -41,7 +41,7 @@ template struct PatchTestStruct { simulation::Node::SPtr SquareNode; - typename component::constraint::projective::AffineMovementConstraint::SPtr affineConstraint; + typename component::constraint::projective::AffineMovementProjectiveConstraint::SPtr affineConstraint; typename component::statecontainer::MechanicalObject::SPtr dofs; }; diff --git a/applications/plugins/SofaTest/Elasticity_test.inl b/applications/plugins/SofaTest/Elasticity_test.inl index f32feeac540..3433abc20af 100644 --- a/applications/plugins/SofaTest/Elasticity_test.inl +++ b/applications/plugins/SofaTest/Elasticity_test.inl @@ -36,10 +36,10 @@ // Constraint -#include +#include #include -#include -#include +#include +#include // ForceField #include @@ -98,7 +98,7 @@ Elasticity_test::createRegularGridScene( typedef component::topology::container::grid::RegularGridTopology RegularGridTopology; typedef typename component::engine::select::BoxROI BoxRoi; typedef typename sofa::component::engine::select::PairBoxROI PairBoxRoi; - typedef typename sofa::component::constraint::projective::AffineMovementConstraint AffineMovementConstraint; + typedef typename sofa::component::constraint::projective::AffineMovementProjectiveConstraint AffineMovementProjectiveConstraint; typedef component::linearsolver::iterative::CGLinearSolver CGLinearSolver; // Root node @@ -144,7 +144,7 @@ Elasticity_test::createRegularGridScene( pairBoxRoi->includedBox.setValue(includedBox); //Affine constraint - patchStruct.affineConstraint = modeling::addNew(SquareNode,"affineConstraint"); + patchStruct.affineConstraint = modeling::addNew(SquareNode,"affineConstraint"); modeling::setDataLink(&boxRoi->d_indices,&patchStruct.affineConstraint->m_meshIndices); modeling::setDataLink(&pairBoxRoi->f_indices,& patchStruct.affineConstraint->m_indices); @@ -223,9 +223,9 @@ CylinderTractionStruct Elasticity_test::createCylinderTra typename component::constraint::projective::FixedConstraint::SPtr fc= modeling::addNew >(root); sofa::modeling::setDataLink(&boxRoi1->d_indices,&fc->d_indices); - // FixedPlaneConstraint - typename component::constraint::projective::FixedPlaneConstraint::SPtr fpc= - modeling::addNew >(root); + // FixedPlaneProjectiveConstraint + typename component::constraint::projective::FixedPlaneProjectiveConstraint::SPtr fpc= + modeling::addNew >(root); fpc->d_dmin= -0.01; fpc->d_dmax= 0.01; fpc->d_direction=Coord(0,0,1); @@ -241,9 +241,9 @@ CylinderTractionStruct Elasticity_test::createCylinderTra modeling::addNew >(root); tractionStruct.forceField=tpff; sofa::modeling::setDataLink(&boxRoi2->d_triangleIndices,&tpff->triangleList); - // ProjectToLineConstraint - typename component::constraint::projective::ProjectToLineConstraint::SPtr ptlc= - modeling::addNew >(root); + // LineProjectiveConstraint + typename component::constraint::projective::LineProjectiveConstraint::SPtr ptlc= + modeling::addNew >(root); ptlc->f_direction=Coord(1,0,0); ptlc->f_origin=Coord(0,0,0); sofa::type::vector vArray; diff --git a/applications/plugins/SofaTest/InitPlugin_test.h b/applications/plugins/SofaTest/InitPlugin_test.h index f79c0bdeb81..140827304d8 100644 --- a/applications/plugins/SofaTest/InitPlugin_test.h +++ b/applications/plugins/SofaTest/InitPlugin_test.h @@ -95,7 +95,7 @@ Other solver tests are available in Compliant_test: AssembledSolver_test and Dam -if constrained particle have the expected position. -if unconstrained particle have not changed. -Some projective constraint tests are available in SofaTest_test: ProjectToLineConstraint and ProjectToPlaneConstraint. +Some projective constraint tests are available in SofaTest_test: LineProjectiveConstraint and ProjectToPlaneConstraint. - Engine test: To test engine you set input values and check if the ouput values correspond to the expected ones. The test Engine_test tests if the update method is called only if necessary. To test this a minimal engine TestEngine was created with a counter in its update method. diff --git a/applications/plugins/SofaTest/SofaTest_test/scenes/damping.py b/applications/plugins/SofaTest/SofaTest_test/scenes/damping.py index 3b5bd86d9c8..b5c763922e7 100644 --- a/applications/plugins/SofaTest/SofaTest_test/scenes/damping.py +++ b/applications/plugins/SofaTest/SofaTest_test/scenes/damping.py @@ -120,7 +120,7 @@ def createScene(node): angularNode.createObject('MechanicalObject', template="Rigid", name="dofs", position="0 0 0 0 0 0 1", velocity="0 0 0 "+str(INITIAL_VELOCITY)+" 0 0") angularNode.createObject('UniformMass', filename=rigidFilename) angularNode.createObject('UniformVelocityDampingForceField', dampingCoefficient=DAMPING_COEF) - #angularNode.createObject('PartialFixedConstraint', indices='0', fixedDirections="1 1 1 0 1 1") + #angularNode.createObject('PartialFixedProjectiveConstraint', indices='0', fixedDirections="1 1 1 0 1 1") # translation damping test @@ -130,7 +130,7 @@ def createScene(node): translationNode.createObject('MechanicalObject', template="Rigid", name="dofs", position="0 0 0 0 0 0 1", velocity=str(INITIAL_VELOCITY)+" 0 0 0 0 0") translationNode.createObject('UniformMass', filename=rigidFilename) translationNode.createObject('UniformVelocityDampingForceField', dampingCoefficient=DAMPING_COEF) - #translationNode.createObject('PartialFixedConstraint', indices='0', fixedDirections="0 1 1 1 1 1") + #translationNode.createObject('PartialFixedProjectiveConstraint', indices='0', fixedDirections="0 1 1 1 1 1") return node diff --git a/applications/projects/SceneChecking/src/SceneChecking/SceneCheckUsingAlias.cpp b/applications/projects/SceneChecking/src/SceneChecking/SceneCheckUsingAlias.cpp index dcdde083ad0..cde238845e9 100644 --- a/applications/projects/SceneChecking/src/SceneChecking/SceneCheckUsingAlias.cpp +++ b/applications/projects/SceneChecking/src/SceneChecking/SceneCheckUsingAlias.cpp @@ -85,13 +85,13 @@ void SceneCheckUsingAlias::doPrintSummary() const unsigned int count = std::count(i.second.begin(), i.second.end(), unique_alias); using sofa::helper::lifecycle::ComponentChange; - using sofa::helper::lifecycle::uncreatableComponents; + using sofa::helper::lifecycle::renamedComponents; usingAliasesWarning << " - " << i.first << ": " << count << " created with alias \"" << unique_alias << "\""; - auto searchAlias = uncreatableComponents.find(unique_alias); - if( searchAlias != uncreatableComponents.end() ) + auto searchAlias = renamedComponents.find(unique_alias); + if( searchAlias != renamedComponents.end() ) { - usingAliasesWarning << " This alias will be REMOVED at the SOFA release " << searchAlias->second.getVersion() << ", please update your scenes."; + usingAliasesWarning << " " << searchAlias->second.getMessage(); } if(unique_alias != unique_aliases.back()) usingAliasesWarning << msgendl; diff --git a/examples/Benchmark/Accuracy/TriangleFEMForceField_compare.scn b/examples/Benchmark/Accuracy/TriangleFEMForceField_compare.scn index acff67b6931..9d690bed376 100644 --- a/examples/Benchmark/Accuracy/TriangleFEMForceField_compare.scn +++ b/examples/Benchmark/Accuracy/TriangleFEMForceField_compare.scn @@ -1,7 +1,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -59,7 +59,7 @@ - + @@ -88,7 +88,7 @@ - + diff --git a/examples/Benchmark/Accuracy/cylinder_PhantomSolution.scn b/examples/Benchmark/Accuracy/cylinder_PhantomSolution.scn index c17a4fb2b37..85132630579 100644 --- a/examples/Benchmark/Accuracy/cylinder_PhantomSolution.scn +++ b/examples/Benchmark/Accuracy/cylinder_PhantomSolution.scn @@ -5,7 +5,7 @@ - + @@ -29,7 +29,7 @@ - + diff --git a/examples/Benchmark/Performance/Bar16-fem-implicit-CudaVec3f.pscn b/examples/Benchmark/Performance/Bar16-fem-implicit-CudaVec3f.pscn index 1b2601cdefb..c25c4b47529 100644 --- a/examples/Benchmark/Performance/Bar16-fem-implicit-CudaVec3f.pscn +++ b/examples/Benchmark/Performance/Bar16-fem-implicit-CudaVec3f.pscn @@ -15,7 +15,7 @@ /> --> '."\n"; ?> - + diff --git a/examples/Benchmark/Performance/Bar16-fem-implicit-Vec3d.pscn b/examples/Benchmark/Performance/Bar16-fem-implicit-Vec3d.pscn index d8df5a99135..32580e91d45 100644 --- a/examples/Benchmark/Performance/Bar16-fem-implicit-Vec3d.pscn +++ b/examples/Benchmark/Performance/Bar16-fem-implicit-Vec3d.pscn @@ -2,7 +2,7 @@ - + @@ -27,7 +27,7 @@ /> --> '."\n"; ?> - + diff --git a/examples/Benchmark/Performance/Bar16-fem-implicit-Vec3f.pscn b/examples/Benchmark/Performance/Bar16-fem-implicit-Vec3f.pscn index f911693ab22..70b4cc28ff4 100644 --- a/examples/Benchmark/Performance/Bar16-fem-implicit-Vec3f.pscn +++ b/examples/Benchmark/Performance/Bar16-fem-implicit-Vec3f.pscn @@ -15,7 +15,7 @@ /> --> '."\n"; ?> - + diff --git a/examples/Benchmark/Performance/Bar16-spring-rk4-CudaVec3f.pscn b/examples/Benchmark/Performance/Bar16-spring-rk4-CudaVec3f.pscn index 08e39fab926..c1f3e1d33d5 100644 --- a/examples/Benchmark/Performance/Bar16-spring-rk4-CudaVec3f.pscn +++ b/examples/Benchmark/Performance/Bar16-spring-rk4-CudaVec3f.pscn @@ -15,7 +15,7 @@ /> --> '."\n"; ?> - + diff --git a/examples/Benchmark/Performance/Bar16-spring-rk4-Vec3d.pscn b/examples/Benchmark/Performance/Bar16-spring-rk4-Vec3d.pscn index 8529cfce5cc..0ed5c7c7531 100644 --- a/examples/Benchmark/Performance/Bar16-spring-rk4-Vec3d.pscn +++ b/examples/Benchmark/Performance/Bar16-spring-rk4-Vec3d.pscn @@ -2,7 +2,7 @@ - + @@ -27,7 +27,7 @@ /> --> '."\n"; ?> - + diff --git a/examples/Benchmark/Performance/Bar16-spring-rk4-Vec3f.pscn b/examples/Benchmark/Performance/Bar16-spring-rk4-Vec3f.pscn index e1f658a0562..b467e0639b5 100644 --- a/examples/Benchmark/Performance/Bar16-spring-rk4-Vec3f.pscn +++ b/examples/Benchmark/Performance/Bar16-spring-rk4-Vec3f.pscn @@ -15,7 +15,7 @@ /> --> '."\n"; ?> - + diff --git a/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_assembledCG.scn b/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_assembledCG.scn index ccd8c09cf70..41bab20a46f 100644 --- a/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_assembledCG.scn +++ b/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_assembledCG.scn @@ -10,7 +10,7 @@ The differences are in the way the global system matrix is built and solved: --> - + @@ -39,7 +39,7 @@ The differences are in the way the global system matrix is built and solved: - + diff --git a/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_assembledCG_blocs.scn b/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_assembledCG_blocs.scn index d82a67aabbf..01f2c6d497c 100644 --- a/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_assembledCG_blocs.scn +++ b/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_assembledCG_blocs.scn @@ -10,7 +10,7 @@ The differences are in the way the global system matrix is built and solved: --> - + @@ -38,7 +38,7 @@ The differences are in the way the global system matrix is built and solved: - + diff --git a/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_direct.scn b/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_direct.scn index 02276f5d64c..e9d27faa57b 100644 --- a/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_direct.scn +++ b/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_direct.scn @@ -10,7 +10,7 @@ The differences are in the way the global system matrix is built and solved: --> - + @@ -40,7 +40,7 @@ The differences are in the way the global system matrix is built and solved: - + diff --git a/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_direct_blocs.scn b/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_direct_blocs.scn index 98675483b53..3a1e7a22ab2 100644 --- a/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_direct_blocs.scn +++ b/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_direct_blocs.scn @@ -10,7 +10,7 @@ The differences are in the way the global system matrix is built and solved: --> - + @@ -39,7 +39,7 @@ The differences are in the way the global system matrix is built and solved: - + diff --git a/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_matrixfreeCG.scn b/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_matrixfreeCG.scn index 3d13ce2db0d..e5f0867fd30 100644 --- a/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_matrixfreeCG.scn +++ b/examples/Benchmark/Performance/MatrixAssembly/MatrixAssembly_matrixfreeCG.scn @@ -10,7 +10,7 @@ The differences are in the way the global system matrix is built and solved: --> - + @@ -40,7 +40,7 @@ The differences are in the way the global system matrix is built and solved: - + diff --git a/examples/Benchmark/TopologicalChanges/AffineMovementConstraint__RemovingMeshTest.scn b/examples/Benchmark/TopologicalChanges/AffineMovementConstraint__RemovingMeshTest.scn index 483706da240..281c96ff109 100644 --- a/examples/Benchmark/TopologicalChanges/AffineMovementConstraint__RemovingMeshTest.scn +++ b/examples/Benchmark/TopologicalChanges/AffineMovementConstraint__RemovingMeshTest.scn @@ -4,7 +4,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/examples/Benchmark/TopologicalChanges/FixedConstraint_RemovingMeshTest.scn b/examples/Benchmark/TopologicalChanges/FixedConstraint_RemovingMeshTest.scn index c0406f6cca1..84fa89acc83 100644 --- a/examples/Benchmark/TopologicalChanges/FixedConstraint_RemovingMeshTest.scn +++ b/examples/Benchmark/TopologicalChanges/FixedConstraint_RemovingMeshTest.scn @@ -4,7 +4,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/examples/Benchmark/TopologicalChanges/FixedPlaneConstraint_RemovingMeshTest.scn b/examples/Benchmark/TopologicalChanges/FixedPlaneConstraint_RemovingMeshTest.scn index 411c3c7bb3f..66d04efb6cc 100644 --- a/examples/Benchmark/TopologicalChanges/FixedPlaneConstraint_RemovingMeshTest.scn +++ b/examples/Benchmark/TopologicalChanges/FixedPlaneConstraint_RemovingMeshTest.scn @@ -4,7 +4,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/examples/Benchmark/TopologicalChanges/LinearMovementConstraint_RemovingMeshTest.scn b/examples/Benchmark/TopologicalChanges/LinearMovementConstraint_RemovingMeshTest.scn index 9f30bb75e82..662cb14f052 100644 --- a/examples/Benchmark/TopologicalChanges/LinearMovementConstraint_RemovingMeshTest.scn +++ b/examples/Benchmark/TopologicalChanges/LinearMovementConstraint_RemovingMeshTest.scn @@ -4,7 +4,7 @@ - + @@ -30,7 +30,7 @@ - - + @@ -35,7 +35,7 @@ - + diff --git a/examples/Benchmark/TopologicalChanges/ProjectToLineConstraint_RemovingMeshTest.scn b/examples/Benchmark/TopologicalChanges/ProjectToLineConstraint_RemovingMeshTest.scn index 6a59053485f..82a7db960a9 100644 --- a/examples/Benchmark/TopologicalChanges/ProjectToLineConstraint_RemovingMeshTest.scn +++ b/examples/Benchmark/TopologicalChanges/ProjectToLineConstraint_RemovingMeshTest.scn @@ -4,7 +4,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/examples/Benchmark/TopologicalChanges/ProjectToPlaneConstraint_RemovingMeshTest.scn b/examples/Benchmark/TopologicalChanges/ProjectToPlaneConstraint_RemovingMeshTest.scn index d4d097c6af2..2171a27bc6b 100644 --- a/examples/Benchmark/TopologicalChanges/ProjectToPlaneConstraint_RemovingMeshTest.scn +++ b/examples/Benchmark/TopologicalChanges/ProjectToPlaneConstraint_RemovingMeshTest.scn @@ -4,7 +4,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/examples/Benchmark/TopologicalChanges/ProjectToPointConstraint_RemovingMeshTest.scn b/examples/Benchmark/TopologicalChanges/ProjectToPointConstraint_RemovingMeshTest.scn index f25820f316b..0fc9b098e3b 100644 --- a/examples/Benchmark/TopologicalChanges/ProjectToPointConstraint_RemovingMeshTest.scn +++ b/examples/Benchmark/TopologicalChanges/ProjectToPointConstraint_RemovingMeshTest.scn @@ -4,7 +4,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/examples/Component/Constraint/Lagrangian/BilateralInteractionConstraint_NNCG.scn b/examples/Component/Constraint/Lagrangian/BilateralInteractionConstraint_NNCG.scn index 1ba14adfb2e..f45125d24cf 100644 --- a/examples/Component/Constraint/Lagrangian/BilateralInteractionConstraint_NNCG.scn +++ b/examples/Component/Constraint/Lagrangian/BilateralInteractionConstraint_NNCG.scn @@ -1,5 +1,5 @@ - + @@ -7,7 +7,7 @@ - + @@ -72,7 +72,7 @@ - + @@ -98,7 +98,7 @@ - + @@ -124,7 +124,7 @@ - + @@ -150,5 +150,5 @@ - + diff --git a/examples/Component/Constraint/Lagrangian/BilateralInteractionConstraint_PGS.scn b/examples/Component/Constraint/Lagrangian/BilateralInteractionConstraint_PGS.scn index 043835a1768..b91d193492e 100644 --- a/examples/Component/Constraint/Lagrangian/BilateralInteractionConstraint_PGS.scn +++ b/examples/Component/Constraint/Lagrangian/BilateralInteractionConstraint_PGS.scn @@ -1,5 +1,5 @@ - + @@ -7,7 +7,7 @@ - + @@ -72,7 +72,7 @@ - + @@ -98,7 +98,7 @@ - + @@ -124,7 +124,7 @@ - + @@ -150,5 +150,5 @@ - + diff --git a/examples/Component/Constraint/Lagrangian/BilateralInteractionConstraint_Rigid.scn b/examples/Component/Constraint/Lagrangian/BilateralInteractionConstraint_Rigid.scn index 0a387c66ad4..5f2c6b2249f 100644 --- a/examples/Component/Constraint/Lagrangian/BilateralInteractionConstraint_Rigid.scn +++ b/examples/Component/Constraint/Lagrangian/BilateralInteractionConstraint_Rigid.scn @@ -1,12 +1,12 @@ - + - + - + @@ -26,7 +26,7 @@ - + @@ -44,5 +44,5 @@ - + diff --git a/examples/Component/Constraint/Lagrangian/BilateralInteractionConstraint_UGS.scn b/examples/Component/Constraint/Lagrangian/BilateralInteractionConstraint_UGS.scn index 80c1002e8e1..a9a540b5824 100644 --- a/examples/Component/Constraint/Lagrangian/BilateralInteractionConstraint_UGS.scn +++ b/examples/Component/Constraint/Lagrangian/BilateralInteractionConstraint_UGS.scn @@ -1,5 +1,5 @@ - + @@ -7,7 +7,7 @@ - + @@ -72,7 +72,7 @@ - + @@ -98,7 +98,7 @@ - + @@ -124,7 +124,7 @@ - + @@ -150,5 +150,5 @@ - + diff --git a/examples/Component/Constraint/Lagrangian/InextensiblePendulum.scn b/examples/Component/Constraint/Lagrangian/InextensiblePendulum.scn index ab6bdf1cb57..0d8004f572e 100644 --- a/examples/Component/Constraint/Lagrangian/InextensiblePendulum.scn +++ b/examples/Component/Constraint/Lagrangian/InextensiblePendulum.scn @@ -5,9 +5,9 @@ - + - + @@ -42,13 +42,13 @@ - + - + diff --git a/examples/Component/Constraint/Lagrangian/SlidingConstraint.scn b/examples/Component/Constraint/Lagrangian/SlidingConstraint.scn index 615a001036d..0adb51d70a3 100644 --- a/examples/Component/Constraint/Lagrangian/SlidingConstraint.scn +++ b/examples/Component/Constraint/Lagrangian/SlidingConstraint.scn @@ -6,7 +6,7 @@ - + @@ -53,7 +53,7 @@ - + @@ -81,5 +81,5 @@ - + diff --git a/examples/Component/Constraint/Projective/AffineMovementConstraint.scn b/examples/Component/Constraint/Projective/AffineMovementConstraint.scn index 5e87538455e..cf9dee066e4 100644 --- a/examples/Component/Constraint/Projective/AffineMovementConstraint.scn +++ b/examples/Component/Constraint/Projective/AffineMovementConstraint.scn @@ -1,6 +1,6 @@ - + @@ -21,6 +21,6 @@ - + diff --git a/examples/Component/Constraint/Projective/AffineMovementConstraint3D.scn b/examples/Component/Constraint/Projective/AffineMovementConstraint3D.scn index 6fe3cfe9ee2..9559ae20198 100644 --- a/examples/Component/Constraint/Projective/AffineMovementConstraint3D.scn +++ b/examples/Component/Constraint/Projective/AffineMovementConstraint3D.scn @@ -1,6 +1,6 @@ - + @@ -21,7 +21,7 @@ - + diff --git a/examples/Component/Constraint/Projective/AttachConstraint.scn b/examples/Component/Constraint/Projective/AttachConstraint.scn index e419879213c..80c6b41aa3f 100644 --- a/examples/Component/Constraint/Projective/AttachConstraint.scn +++ b/examples/Component/Constraint/Projective/AttachConstraint.scn @@ -1,5 +1,5 @@ - + @@ -50,8 +50,8 @@ - - + + @@ -80,7 +80,7 @@ - - + + diff --git a/examples/Component/Constraint/Projective/AttachConstraintMatrix.scn b/examples/Component/Constraint/Projective/AttachConstraintMatrix.scn index ec7ae3cf09a..b793d815853 100644 --- a/examples/Component/Constraint/Projective/AttachConstraintMatrix.scn +++ b/examples/Component/Constraint/Projective/AttachConstraintMatrix.scn @@ -1,5 +1,5 @@ - + @@ -37,8 +37,8 @@ --> - - + + @@ -66,7 +66,7 @@ --> - - + + diff --git a/examples/Component/Constraint/Projective/BilinearConstraint.scn b/examples/Component/Constraint/Projective/BilinearConstraint.scn index 3886aca51c9..86cf8836f0d 100644 --- a/examples/Component/Constraint/Projective/BilinearConstraint.scn +++ b/examples/Component/Constraint/Projective/BilinearConstraint.scn @@ -1,6 +1,6 @@ - + @@ -21,7 +21,7 @@ - diff --git a/examples/Component/Constraint/Projective/BilinearConstraint3D.scn b/examples/Component/Constraint/Projective/BilinearConstraint3D.scn index ba7c8b1a8c6..790ebfd1aa1 100644 --- a/examples/Component/Constraint/Projective/BilinearConstraint3D.scn +++ b/examples/Component/Constraint/Projective/BilinearConstraint3D.scn @@ -1,6 +1,6 @@ - + @@ -21,7 +21,7 @@ - - + diff --git a/examples/Component/Constraint/Projective/FixedConstraint.scn b/examples/Component/Constraint/Projective/FixedConstraint.scn index f7d7b948cb3..91adbd6b917 100644 --- a/examples/Component/Constraint/Projective/FixedConstraint.scn +++ b/examples/Component/Constraint/Projective/FixedConstraint.scn @@ -3,7 +3,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/examples/Component/Constraint/Projective/FixedPlaneConstraint.scn b/examples/Component/Constraint/Projective/FixedPlaneConstraint.scn index 33091349da8..e81e89fe67e 100644 --- a/examples/Component/Constraint/Projective/FixedPlaneConstraint.scn +++ b/examples/Component/Constraint/Projective/FixedPlaneConstraint.scn @@ -3,7 +3,7 @@ - + @@ -31,7 +31,7 @@ - + diff --git a/examples/Component/Constraint/Projective/FixedRotationConstraint.scn b/examples/Component/Constraint/Projective/FixedRotationConstraint.scn index 9a1d330bced..dff0cbf791f 100644 --- a/examples/Component/Constraint/Projective/FixedRotationConstraint.scn +++ b/examples/Component/Constraint/Projective/FixedRotationConstraint.scn @@ -2,7 +2,7 @@ - + @@ -23,8 +23,8 @@ - - + + @@ -35,7 +35,7 @@ - + diff --git a/examples/Component/Constraint/Projective/HermiteSplineConstraint.scn b/examples/Component/Constraint/Projective/HermiteSplineConstraint.scn index 0e9cebd5f00..94c103f3313 100644 --- a/examples/Component/Constraint/Projective/HermiteSplineConstraint.scn +++ b/examples/Component/Constraint/Projective/HermiteSplineConstraint.scn @@ -1,5 +1,5 @@ - + @@ -41,7 +41,7 @@ - + @@ -72,7 +72,7 @@ - + diff --git a/examples/Component/Constraint/Projective/LinearMovementConstraint.scn b/examples/Component/Constraint/Projective/LinearMovementConstraint.scn index 765e24d0691..a0c44039f02 100644 --- a/examples/Component/Constraint/Projective/LinearMovementConstraint.scn +++ b/examples/Component/Constraint/Projective/LinearMovementConstraint.scn @@ -1,7 +1,7 @@ - + @@ -15,7 +15,7 @@ - - - - + @@ -33,9 +33,9 @@ - + - + diff --git a/examples/Component/Constraint/Projective/OscillatorConstraint_rigid.scn b/examples/Component/Constraint/Projective/OscillatorConstraint_rigid.scn index 29e63ffcf16..ebf9b35dcdd 100644 --- a/examples/Component/Constraint/Projective/OscillatorConstraint_rigid.scn +++ b/examples/Component/Constraint/Projective/OscillatorConstraint_rigid.scn @@ -1,5 +1,5 @@ - + @@ -11,13 +11,13 @@ - + - + diff --git a/examples/Component/Constraint/Projective/ParabolicConstraint.scn b/examples/Component/Constraint/Projective/ParabolicConstraint.scn index 9ad9caf4787..3ca3981defe 100644 --- a/examples/Component/Constraint/Projective/ParabolicConstraint.scn +++ b/examples/Component/Constraint/Projective/ParabolicConstraint.scn @@ -3,7 +3,7 @@ - + @@ -26,7 +26,7 @@ - + diff --git a/examples/Component/Constraint/Projective/PartialFixedConstraint.scn b/examples/Component/Constraint/Projective/PartialFixedConstraint.scn index 9e235784ff4..2d58937d7d5 100644 --- a/examples/Component/Constraint/Projective/PartialFixedConstraint.scn +++ b/examples/Component/Constraint/Projective/PartialFixedConstraint.scn @@ -3,7 +3,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/examples/Component/Constraint/Projective/PatchTestConstraint.scn b/examples/Component/Constraint/Projective/PatchTestConstraint.scn index 4c1b2ad4c17..14a0cde03f6 100644 --- a/examples/Component/Constraint/Projective/PatchTestConstraint.scn +++ b/examples/Component/Constraint/Projective/PatchTestConstraint.scn @@ -1,6 +1,6 @@ - + @@ -21,7 +21,7 @@ - - + diff --git a/examples/Component/Constraint/Projective/ProjectDirectionConstraint.scn b/examples/Component/Constraint/Projective/ProjectDirectionConstraint.scn index 6ea4da00c66..eab3eae47e1 100644 --- a/examples/Component/Constraint/Projective/ProjectDirectionConstraint.scn +++ b/examples/Component/Constraint/Projective/ProjectDirectionConstraint.scn @@ -1,6 +1,6 @@ - + @@ -28,7 +28,7 @@ - + diff --git a/examples/Component/Constraint/Projective/ProjectToLineConstraint.scn b/examples/Component/Constraint/Projective/ProjectToLineConstraint.scn index ecfa2892dd8..4174189da28 100644 --- a/examples/Component/Constraint/Projective/ProjectToLineConstraint.scn +++ b/examples/Component/Constraint/Projective/ProjectToLineConstraint.scn @@ -1,6 +1,6 @@ - + @@ -28,7 +28,7 @@ - + diff --git a/examples/Component/Constraint/Projective/ProjectToPlaneConstraint.scn b/examples/Component/Constraint/Projective/ProjectToPlaneConstraint.scn index 8c46fd43d58..797dd281312 100644 --- a/examples/Component/Constraint/Projective/ProjectToPlaneConstraint.scn +++ b/examples/Component/Constraint/Projective/ProjectToPlaneConstraint.scn @@ -1,6 +1,6 @@ - + @@ -34,7 +34,7 @@ - + diff --git a/examples/Component/Constraint/Projective/ProjectToPointConstraint.scn b/examples/Component/Constraint/Projective/ProjectToPointConstraint.scn index ebef7961b34..c8fbd99a6fd 100644 --- a/examples/Component/Constraint/Projective/ProjectToPointConstraint.scn +++ b/examples/Component/Constraint/Projective/ProjectToPointConstraint.scn @@ -1,6 +1,6 @@ - + @@ -28,7 +28,7 @@ - + diff --git a/examples/Component/Controller/MechanicalStateController.scn b/examples/Component/Controller/MechanicalStateController.scn index 65db4fe0dbc..8c4010ccf6b 100644 --- a/examples/Component/Controller/MechanicalStateController.scn +++ b/examples/Component/Controller/MechanicalStateController.scn @@ -3,7 +3,7 @@ - + @@ -28,7 +28,7 @@ - + diff --git a/examples/Component/Diffusion/TetrahedronDiffusionFEMForceField.scn b/examples/Component/Diffusion/TetrahedronDiffusionFEMForceField.scn index b3b91f47d5a..6d8f39a209e 100644 --- a/examples/Component/Diffusion/TetrahedronDiffusionFEMForceField.scn +++ b/examples/Component/Diffusion/TetrahedronDiffusionFEMForceField.scn @@ -1,5 +1,5 @@ - + @@ -35,8 +35,8 @@ - - + + diff --git a/examples/Component/Engine/Analyze/ShapeMatching.scn b/examples/Component/Engine/Analyze/ShapeMatching.scn index 963419e8bb6..79d6cc58032 100644 --- a/examples/Component/Engine/Analyze/ShapeMatching.scn +++ b/examples/Component/Engine/Analyze/ShapeMatching.scn @@ -4,7 +4,7 @@ - + @@ -33,7 +33,7 @@ - + diff --git a/examples/Component/Engine/Generate/GenerateCylinder.scn b/examples/Component/Engine/Generate/GenerateCylinder.scn index d2eefb6e655..c0510c1ad90 100644 --- a/examples/Component/Engine/Generate/GenerateCylinder.scn +++ b/examples/Component/Engine/Generate/GenerateCylinder.scn @@ -1,6 +1,6 @@ - + @@ -21,10 +21,10 @@ - - + + - + diff --git a/examples/Component/Engine/Generate/GenerateGrid.scn b/examples/Component/Engine/Generate/GenerateGrid.scn index 5e3a62f1069..3759be30c7b 100644 --- a/examples/Component/Engine/Generate/GenerateGrid.scn +++ b/examples/Component/Engine/Generate/GenerateGrid.scn @@ -1,6 +1,6 @@ - + @@ -21,10 +21,10 @@ - - + + - + @@ -36,10 +36,10 @@ - - + + - + diff --git a/examples/Component/Engine/Generate/MergePoints.scn b/examples/Component/Engine/Generate/MergePoints.scn index 462b3657c57..14b1f6c0f46 100644 --- a/examples/Component/Engine/Generate/MergePoints.scn +++ b/examples/Component/Engine/Generate/MergePoints.scn @@ -4,7 +4,7 @@ - + diff --git a/examples/Component/Engine/Generate/MeshTetraStuffing.scn b/examples/Component/Engine/Generate/MeshTetraStuffing.scn index 1fc3eb5daf4..02736784952 100644 --- a/examples/Component/Engine/Generate/MeshTetraStuffing.scn +++ b/examples/Component/Engine/Generate/MeshTetraStuffing.scn @@ -1,6 +1,6 @@ - + diff --git a/examples/Component/Engine/Select/BoxROI.scn b/examples/Component/Engine/Select/BoxROI.scn index 446af45803e..d2aae26848b 100644 --- a/examples/Component/Engine/Select/BoxROI.scn +++ b/examples/Component/Engine/Select/BoxROI.scn @@ -4,7 +4,7 @@ - + @@ -35,7 +35,7 @@ - + diff --git a/examples/Component/Engine/Select/BoxROI_1d.scn b/examples/Component/Engine/Select/BoxROI_1d.scn index d7f3a38bfd3..29c05fad73b 100644 --- a/examples/Component/Engine/Select/BoxROI_1d.scn +++ b/examples/Component/Engine/Select/BoxROI_1d.scn @@ -1,6 +1,6 @@ - + @@ -22,7 +22,7 @@ - + diff --git a/examples/Component/Engine/Select/BoxROI_2d.scn b/examples/Component/Engine/Select/BoxROI_2d.scn index 8ff3eed83f2..d8aa11229f4 100644 --- a/examples/Component/Engine/Select/BoxROI_2d.scn +++ b/examples/Component/Engine/Select/BoxROI_2d.scn @@ -1,6 +1,6 @@ - + @@ -22,7 +22,7 @@ - + diff --git a/examples/Component/Engine/Select/MeshBoundaryROI.scn b/examples/Component/Engine/Select/MeshBoundaryROI.scn index 708f6c5f2ae..268abb6cc96 100644 --- a/examples/Component/Engine/Select/MeshBoundaryROI.scn +++ b/examples/Component/Engine/Select/MeshBoundaryROI.scn @@ -1,6 +1,6 @@ - + @@ -22,7 +22,7 @@ - + diff --git a/examples/Component/Engine/Select/MeshSplittingEngine.scn b/examples/Component/Engine/Select/MeshSplittingEngine.scn index 8016eba6c8d..9964396e546 100644 --- a/examples/Component/Engine/Select/MeshSplittingEngine.scn +++ b/examples/Component/Engine/Select/MeshSplittingEngine.scn @@ -2,7 +2,7 @@ - + @@ -33,7 +33,7 @@ - + diff --git a/examples/Component/Engine/Select/NearestPointROI.scn b/examples/Component/Engine/Select/NearestPointROI.scn index d0db2545113..f54e0aa60ed 100644 --- a/examples/Component/Engine/Select/NearestPointROI.scn +++ b/examples/Component/Engine/Select/NearestPointROI.scn @@ -2,9 +2,9 @@ - + - + @@ -34,7 +34,7 @@ - + @@ -50,7 +50,7 @@ - + @@ -58,8 +58,8 @@ - - + + - + @@ -34,7 +34,7 @@ - + diff --git a/examples/Component/Engine/Select/PointsFromIndices.scn b/examples/Component/Engine/Select/PointsFromIndices.scn index ed1337aee5b..7725226bba4 100644 --- a/examples/Component/Engine/Select/PointsFromIndices.scn +++ b/examples/Component/Engine/Select/PointsFromIndices.scn @@ -1,6 +1,6 @@ - + @@ -24,7 +24,7 @@ - + diff --git a/examples/Component/Engine/Select/ProximityROI.scn b/examples/Component/Engine/Select/ProximityROI.scn index 83001a35557..7ba48a66000 100644 --- a/examples/Component/Engine/Select/ProximityROI.scn +++ b/examples/Component/Engine/Select/ProximityROI.scn @@ -3,7 +3,7 @@ - + @@ -35,7 +35,7 @@ - + diff --git a/examples/Component/Engine/Select/SphereROI.scn b/examples/Component/Engine/Select/SphereROI.scn index 6b12d91a9f5..0b9e6848cd1 100644 --- a/examples/Component/Engine/Select/SphereROI.scn +++ b/examples/Component/Engine/Select/SphereROI.scn @@ -3,7 +3,7 @@ - + @@ -34,7 +34,7 @@ - + diff --git a/examples/Component/Engine/Select/SubsetTopology.scn b/examples/Component/Engine/Select/SubsetTopology.scn index 21e3ebf839d..f16a84ab8db 100644 --- a/examples/Component/Engine/Select/SubsetTopology.scn +++ b/examples/Component/Engine/Select/SubsetTopology.scn @@ -3,7 +3,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/examples/Component/Engine/Select/SubsetTopology_localIndicesOption.scn b/examples/Component/Engine/Select/SubsetTopology_localIndicesOption.scn index 31bd27fdd00..5e50f45b027 100644 --- a/examples/Component/Engine/Select/SubsetTopology_localIndicesOption.scn +++ b/examples/Component/Engine/Select/SubsetTopology_localIndicesOption.scn @@ -3,7 +3,7 @@ - + @@ -52,7 +52,7 @@ - + diff --git a/examples/Component/Engine/Select/SubsetTopology_refiningMesh.scn b/examples/Component/Engine/Select/SubsetTopology_refiningMesh.scn index 9278d14c0f0..56a2d8dfcdc 100644 --- a/examples/Component/Engine/Select/SubsetTopology_refiningMesh.scn +++ b/examples/Component/Engine/Select/SubsetTopology_refiningMesh.scn @@ -3,7 +3,7 @@ - + diff --git a/examples/Component/Engine/Select/SubsetTopology_withtetrahedra.scn b/examples/Component/Engine/Select/SubsetTopology_withtetrahedra.scn index c2ad7fcabc4..14972862716 100644 --- a/examples/Component/Engine/Select/SubsetTopology_withtetrahedra.scn +++ b/examples/Component/Engine/Select/SubsetTopology_withtetrahedra.scn @@ -3,7 +3,7 @@ - + @@ -33,8 +33,8 @@ - - + + diff --git a/examples/Component/Engine/Select/ValuesFromPositions_vectorField.scn b/examples/Component/Engine/Select/ValuesFromPositions_vectorField.scn index 7dae968e1ec..effa36cf9d9 100644 --- a/examples/Component/Engine/Select/ValuesFromPositions_vectorField.scn +++ b/examples/Component/Engine/Select/ValuesFromPositions_vectorField.scn @@ -4,7 +4,7 @@ - + @@ -31,7 +31,7 @@ - + diff --git a/examples/Component/Engine/Transform/DisplacementMatrixEngine.scn b/examples/Component/Engine/Transform/DisplacementMatrixEngine.scn index 3ad1146f2b3..bda26fff218 100644 --- a/examples/Component/Engine/Transform/DisplacementMatrixEngine.scn +++ b/examples/Component/Engine/Transform/DisplacementMatrixEngine.scn @@ -1,6 +1,6 @@ - + @@ -13,7 +13,7 @@ - + diff --git a/examples/Component/IO/Mesh/GIDMeshLoader.scn b/examples/Component/IO/Mesh/GIDMeshLoader.scn index 67d832f36aa..30cc187f067 100644 --- a/examples/Component/IO/Mesh/GIDMeshLoader.scn +++ b/examples/Component/IO/Mesh/GIDMeshLoader.scn @@ -1,6 +1,6 @@ - + @@ -21,7 +21,7 @@ - + diff --git a/examples/Component/IO/Mesh/GridMeshCreator.scn b/examples/Component/IO/Mesh/GridMeshCreator.scn index 57ad5cb3d65..f7fc089de77 100644 --- a/examples/Component/IO/Mesh/GridMeshCreator.scn +++ b/examples/Component/IO/Mesh/GridMeshCreator.scn @@ -1,6 +1,6 @@ - + diff --git a/examples/Component/IO/Mesh/LiverUseNewLoaders.scn b/examples/Component/IO/Mesh/LiverUseNewLoaders.scn index feb56b80452..33fc1206e06 100644 --- a/examples/Component/IO/Mesh/LiverUseNewLoaders.scn +++ b/examples/Component/IO/Mesh/LiverUseNewLoaders.scn @@ -4,7 +4,7 @@ - + @@ -33,7 +33,7 @@ - + diff --git a/examples/Component/IO/Mesh/MeshGmshLoader.scn b/examples/Component/IO/Mesh/MeshGmshLoader.scn index 0acff14cbf5..4158c668ac3 100644 --- a/examples/Component/IO/Mesh/MeshGmshLoader.scn +++ b/examples/Component/IO/Mesh/MeshGmshLoader.scn @@ -5,7 +5,7 @@ - + @@ -34,7 +34,7 @@ - + @@ -52,7 +52,7 @@ - + diff --git a/examples/Component/LinearSolver/Direct/Eigen3-SVD.scn b/examples/Component/LinearSolver/Direct/Eigen3-SVD.scn index 6cdfe62062d..356075b7f5f 100644 --- a/examples/Component/LinearSolver/Direct/Eigen3-SVD.scn +++ b/examples/Component/LinearSolver/Direct/Eigen3-SVD.scn @@ -1,7 +1,7 @@ - + @@ -19,7 +19,7 @@ - + diff --git a/examples/Component/LinearSolver/Direct/FEMBAR_SVDLinearSolver.scn b/examples/Component/LinearSolver/Direct/FEMBAR_SVDLinearSolver.scn index 1496fe41a7c..4c26c5c7735 100644 --- a/examples/Component/LinearSolver/Direct/FEMBAR_SVDLinearSolver.scn +++ b/examples/Component/LinearSolver/Direct/FEMBAR_SVDLinearSolver.scn @@ -1,6 +1,6 @@ - + diff --git a/examples/Component/LinearSolver/FEMBAR-common.xml b/examples/Component/LinearSolver/FEMBAR-common.xml index 2162436968d..924dcf4aec3 100644 --- a/examples/Component/LinearSolver/FEMBAR-common.xml +++ b/examples/Component/LinearSolver/FEMBAR-common.xml @@ -1,7 +1,7 @@ - + @@ -25,5 +25,5 @@ - + \ No newline at end of file diff --git a/examples/Component/LinearSolver/Iterative/CGLinearSolver.scn b/examples/Component/LinearSolver/Iterative/CGLinearSolver.scn index 24a12bf6f83..c7770743c4a 100644 --- a/examples/Component/LinearSolver/Iterative/CGLinearSolver.scn +++ b/examples/Component/LinearSolver/Iterative/CGLinearSolver.scn @@ -1,6 +1,6 @@ - + @@ -17,7 +17,7 @@ - + diff --git a/examples/Component/LinearSystem/CompositeLinearSystem.scn b/examples/Component/LinearSystem/CompositeLinearSystem.scn index b8db4d65117..d0c869966ad 100644 --- a/examples/Component/LinearSystem/CompositeLinearSystem.scn +++ b/examples/Component/LinearSystem/CompositeLinearSystem.scn @@ -1,5 +1,5 @@ - + @@ -41,7 +41,7 @@ - + @@ -65,7 +65,7 @@ - + @@ -79,7 +79,7 @@ - + diff --git a/examples/Component/LinearSystem/ConstantSparsityPatternSystem.scn b/examples/Component/LinearSystem/ConstantSparsityPatternSystem.scn index db3ae28eb81..af5194c5e13 100644 --- a/examples/Component/LinearSystem/ConstantSparsityPatternSystem.scn +++ b/examples/Component/LinearSystem/ConstantSparsityPatternSystem.scn @@ -1,7 +1,7 @@ - + @@ -29,7 +29,7 @@ - + @@ -53,7 +53,7 @@ - + @@ -67,7 +67,7 @@ - + diff --git a/examples/Component/LinearSystem/MatrixLinearSystem.scn b/examples/Component/LinearSystem/MatrixLinearSystem.scn index fa0299f2009..8b034949c81 100644 --- a/examples/Component/LinearSystem/MatrixLinearSystem.scn +++ b/examples/Component/LinearSystem/MatrixLinearSystem.scn @@ -1,7 +1,7 @@ - + @@ -42,7 +42,7 @@ - + @@ -67,7 +67,7 @@ - + @@ -93,7 +93,7 @@ - + diff --git a/examples/Component/LinearSystem/PendulumSpringsDistanceMapping.scn b/examples/Component/LinearSystem/PendulumSpringsDistanceMapping.scn index 8266e71cc48..70341c2f496 100644 --- a/examples/Component/LinearSystem/PendulumSpringsDistanceMapping.scn +++ b/examples/Component/LinearSystem/PendulumSpringsDistanceMapping.scn @@ -5,7 +5,7 @@ - + @@ -36,7 +36,7 @@ - + @@ -60,7 +60,7 @@ - + diff --git a/examples/Component/Mapping/Linear/BarycentricMappingTrussBeam.scn b/examples/Component/Mapping/Linear/BarycentricMappingTrussBeam.scn index 179bf348990..79102a5227b 100644 --- a/examples/Component/Mapping/Linear/BarycentricMappingTrussBeam.scn +++ b/examples/Component/Mapping/Linear/BarycentricMappingTrussBeam.scn @@ -3,7 +3,7 @@ - + @@ -53,7 +53,7 @@ - + diff --git a/examples/Component/Mapping/Linear/BarycentricTetraMapping.scn b/examples/Component/Mapping/Linear/BarycentricTetraMapping.scn index f98703a6526..7e22f035d0f 100644 --- a/examples/Component/Mapping/Linear/BarycentricTetraMapping.scn +++ b/examples/Component/Mapping/Linear/BarycentricTetraMapping.scn @@ -3,7 +3,7 @@ - + @@ -45,7 +45,7 @@ - + diff --git a/examples/Component/Mapping/Linear/CenterOfMassMapping.scn b/examples/Component/Mapping/Linear/CenterOfMassMapping.scn index c570784c849..a50d9cdbc89 100644 --- a/examples/Component/Mapping/Linear/CenterOfMassMapping.scn +++ b/examples/Component/Mapping/Linear/CenterOfMassMapping.scn @@ -3,7 +3,7 @@ - + @@ -32,7 +32,7 @@ free_velocity="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0" rest_position="0 0 0 0 0 0 1 1 0 0 0 0 0 1 3 0 0 0 0 0 1 5 0 0 0 0 0 1 7 0 0 0 0 0 1" /> - + - + @@ -42,7 +42,7 @@ - + diff --git a/examples/Component/Mapping/Linear/DeformableOnRigidFrameMappingConstraints.scn b/examples/Component/Mapping/Linear/DeformableOnRigidFrameMappingConstraints.scn index 463e57f4b12..b0cc566a42a 100644 --- a/examples/Component/Mapping/Linear/DeformableOnRigidFrameMappingConstraints.scn +++ b/examples/Component/Mapping/Linear/DeformableOnRigidFrameMappingConstraints.scn @@ -7,7 +7,7 @@ - + diff --git a/examples/Component/Mapping/Linear/IdentityMapping.scn b/examples/Component/Mapping/Linear/IdentityMapping.scn index a7758dd636f..ab825bf5fe3 100644 --- a/examples/Component/Mapping/Linear/IdentityMapping.scn +++ b/examples/Component/Mapping/Linear/IdentityMapping.scn @@ -4,7 +4,7 @@ - + @@ -32,7 +32,7 @@ - + diff --git a/examples/Component/Mapping/Linear/SimpleTesselatedTetraTopologicalMapping.scn b/examples/Component/Mapping/Linear/SimpleTesselatedTetraTopologicalMapping.scn index 4d1cc74a819..4773230ce07 100644 --- a/examples/Component/Mapping/Linear/SimpleTesselatedTetraTopologicalMapping.scn +++ b/examples/Component/Mapping/Linear/SimpleTesselatedTetraTopologicalMapping.scn @@ -4,7 +4,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/examples/Component/Mapping/Linear/SkinningMapping.scn b/examples/Component/Mapping/Linear/SkinningMapping.scn index 351649d07ae..4d78200855f 100644 --- a/examples/Component/Mapping/Linear/SkinningMapping.scn +++ b/examples/Component/Mapping/Linear/SkinningMapping.scn @@ -3,7 +3,7 @@ - + @@ -27,7 +27,7 @@ - + diff --git a/examples/Component/Mapping/Linear/SubsetMapping.scn b/examples/Component/Mapping/Linear/SubsetMapping.scn index d44ec9fc248..b3f9cc26273 100644 --- a/examples/Component/Mapping/Linear/SubsetMapping.scn +++ b/examples/Component/Mapping/Linear/SubsetMapping.scn @@ -4,7 +4,7 @@ - + @@ -41,7 +41,7 @@ /> - + diff --git a/examples/Component/Mapping/NonLinear/DistanceMapping.scn b/examples/Component/Mapping/NonLinear/DistanceMapping.scn index 2d79d67e6d1..fe92700c998 100644 --- a/examples/Component/Mapping/NonLinear/DistanceMapping.scn +++ b/examples/Component/Mapping/NonLinear/DistanceMapping.scn @@ -2,7 +2,7 @@ - + @@ -26,7 +26,7 @@ - + diff --git a/examples/Component/Mapping/NonLinear/DistanceMultiMapping.scn b/examples/Component/Mapping/NonLinear/DistanceMultiMapping.scn index 3a5f3a1e5f7..525c69acc04 100644 --- a/examples/Component/Mapping/NonLinear/DistanceMultiMapping.scn +++ b/examples/Component/Mapping/NonLinear/DistanceMultiMapping.scn @@ -2,7 +2,7 @@ - + @@ -31,7 +31,7 @@ - + @@ -47,7 +47,7 @@ - + diff --git a/examples/Component/Mapping/NonLinear/RigidMapping-basic.scn b/examples/Component/Mapping/NonLinear/RigidMapping-basic.scn index 7744bd8aec9..1288a343fcd 100644 --- a/examples/Component/Mapping/NonLinear/RigidMapping-basic.scn +++ b/examples/Component/Mapping/NonLinear/RigidMapping-basic.scn @@ -1,6 +1,6 @@ - + @@ -15,7 +15,7 @@ - + diff --git a/examples/Component/Mapping/NonLinear/RigidMapping2d-basic.scn b/examples/Component/Mapping/NonLinear/RigidMapping2d-basic.scn index 5f19f6a606d..f80e9ca2cc0 100644 --- a/examples/Component/Mapping/NonLinear/RigidMapping2d-basic.scn +++ b/examples/Component/Mapping/NonLinear/RigidMapping2d-basic.scn @@ -1,6 +1,6 @@ - + @@ -16,7 +16,7 @@ - + diff --git a/examples/Component/Mapping/NonLinear/RigidRigidMapping-basic.scn b/examples/Component/Mapping/NonLinear/RigidRigidMapping-basic.scn index 6027d7de902..cc1d920970c 100644 --- a/examples/Component/Mapping/NonLinear/RigidRigidMapping-basic.scn +++ b/examples/Component/Mapping/NonLinear/RigidRigidMapping-basic.scn @@ -1,6 +1,6 @@ - + @@ -14,7 +14,7 @@ - + diff --git a/examples/Component/Mapping/NonLinear/RigidRigidMapping.scn b/examples/Component/Mapping/NonLinear/RigidRigidMapping.scn index 7ac77700c1c..a4a83f1ea47 100644 --- a/examples/Component/Mapping/NonLinear/RigidRigidMapping.scn +++ b/examples/Component/Mapping/NonLinear/RigidRigidMapping.scn @@ -1,5 +1,5 @@ - + @@ -15,7 +15,7 @@ - + diff --git a/examples/Component/Mapping/NonLinear/SquareDistanceMapping.scn b/examples/Component/Mapping/NonLinear/SquareDistanceMapping.scn index 60e7ce3bd35..03b54fc6d5b 100644 --- a/examples/Component/Mapping/NonLinear/SquareDistanceMapping.scn +++ b/examples/Component/Mapping/NonLinear/SquareDistanceMapping.scn @@ -2,7 +2,7 @@ - + @@ -26,7 +26,7 @@ - + diff --git a/examples/Component/Mapping/NonLinear/SquareMapping.scn b/examples/Component/Mapping/NonLinear/SquareMapping.scn index dd96407b38a..db024529d70 100644 --- a/examples/Component/Mapping/NonLinear/SquareMapping.scn +++ b/examples/Component/Mapping/NonLinear/SquareMapping.scn @@ -2,7 +2,7 @@ - + @@ -28,7 +28,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/examples/Component/Mass/DiagonalMass.scn b/examples/Component/Mass/DiagonalMass.scn index ac24b41552c..f83e61ebcb5 100644 --- a/examples/Component/Mass/DiagonalMass.scn +++ b/examples/Component/Mass/DiagonalMass.scn @@ -4,7 +4,7 @@ - + @@ -34,7 +34,7 @@ - + diff --git a/examples/Component/Mass/MeshMatrixMass.scn b/examples/Component/Mass/MeshMatrixMass.scn index b8abec1d314..a837db2e000 100644 --- a/examples/Component/Mass/MeshMatrixMass.scn +++ b/examples/Component/Mass/MeshMatrixMass.scn @@ -4,7 +4,7 @@ - + @@ -36,7 +36,7 @@ - + diff --git a/examples/Component/Mass/UniformMass.scn b/examples/Component/Mass/UniformMass.scn index c85e272e18a..7de3a469e35 100644 --- a/examples/Component/Mass/UniformMass.scn +++ b/examples/Component/Mass/UniformMass.scn @@ -4,7 +4,7 @@ - + @@ -34,7 +34,7 @@ - + diff --git a/examples/Component/MechanicalLoad/ConstantForceField.scn b/examples/Component/MechanicalLoad/ConstantForceField.scn index f7f23dc35bb..c5969c4f212 100644 --- a/examples/Component/MechanicalLoad/ConstantForceField.scn +++ b/examples/Component/MechanicalLoad/ConstantForceField.scn @@ -22,7 +22,7 @@ - + diff --git a/examples/Component/MechanicalLoad/EllipsoidForceField.scn b/examples/Component/MechanicalLoad/EllipsoidForceField.scn index 73a6dbbef0a..717ab8d95db 100644 --- a/examples/Component/MechanicalLoad/EllipsoidForceField.scn +++ b/examples/Component/MechanicalLoad/EllipsoidForceField.scn @@ -5,7 +5,7 @@ - + @@ -36,7 +36,7 @@ - + diff --git a/examples/Component/MechanicalLoad/InteractionEllipsoidForceField.scn b/examples/Component/MechanicalLoad/InteractionEllipsoidForceField.scn index 697072de215..ef1a0060d8a 100644 --- a/examples/Component/MechanicalLoad/InteractionEllipsoidForceField.scn +++ b/examples/Component/MechanicalLoad/InteractionEllipsoidForceField.scn @@ -3,7 +3,7 @@ - + @@ -28,7 +28,7 @@ - + @@ -37,9 +37,9 @@ - + - + diff --git a/examples/Component/MechanicalLoad/SphereForceField.scn b/examples/Component/MechanicalLoad/SphereForceField.scn index 298742dfc7b..fd6fd1d8992 100644 --- a/examples/Component/MechanicalLoad/SphereForceField.scn +++ b/examples/Component/MechanicalLoad/SphereForceField.scn @@ -1,6 +1,6 @@ - + diff --git a/examples/Component/MechanicalLoad/SurfacePressureForceField.scn b/examples/Component/MechanicalLoad/SurfacePressureForceField.scn index f8c69abde25..63a14b6b4ed 100644 --- a/examples/Component/MechanicalLoad/SurfacePressureForceField.scn +++ b/examples/Component/MechanicalLoad/SurfacePressureForceField.scn @@ -3,7 +3,7 @@ - + diff --git a/examples/Component/MechanicalLoad/TaitSurfacePressureForceField.scn b/examples/Component/MechanicalLoad/TaitSurfacePressureForceField.scn index 375558764ff..91e97efe3d4 100644 --- a/examples/Component/MechanicalLoad/TaitSurfacePressureForceField.scn +++ b/examples/Component/MechanicalLoad/TaitSurfacePressureForceField.scn @@ -3,7 +3,7 @@ - + diff --git a/examples/Component/MechanicalLoad/TrianglePressureForceField.scn b/examples/Component/MechanicalLoad/TrianglePressureForceField.scn index 80d90907be9..eebfa803818 100644 --- a/examples/Component/MechanicalLoad/TrianglePressureForceField.scn +++ b/examples/Component/MechanicalLoad/TrianglePressureForceField.scn @@ -4,7 +4,7 @@ - + @@ -32,8 +32,8 @@ - - + + diff --git a/examples/Component/ODESolver/Backward/EulerImplicitSolver-comparison.scn b/examples/Component/ODESolver/Backward/EulerImplicitSolver-comparison.scn index 9db818361d8..5cf7e86aba4 100644 --- a/examples/Component/ODESolver/Backward/EulerImplicitSolver-comparison.scn +++ b/examples/Component/ODESolver/Backward/EulerImplicitSolver-comparison.scn @@ -1,6 +1,6 @@ - + @@ -24,7 +24,7 @@ - + @@ -39,7 +39,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -69,7 +69,7 @@ - + diff --git a/examples/Component/ODESolver/Backward/EulerImplicitSolver.scn b/examples/Component/ODESolver/Backward/EulerImplicitSolver.scn index bc2b9b85373..bb30a06a950 100644 --- a/examples/Component/ODESolver/Backward/EulerImplicitSolver.scn +++ b/examples/Component/ODESolver/Backward/EulerImplicitSolver.scn @@ -1,5 +1,5 @@ - + @@ -21,7 +21,7 @@ - + diff --git a/examples/Component/ODESolver/Backward/NewmarkImplicitSolver.scn b/examples/Component/ODESolver/Backward/NewmarkImplicitSolver.scn index 81796d0f426..3f391fb9ee9 100644 --- a/examples/Component/ODESolver/Backward/NewmarkImplicitSolver.scn +++ b/examples/Component/ODESolver/Backward/NewmarkImplicitSolver.scn @@ -1,5 +1,5 @@ - + @@ -24,7 +24,7 @@ - + @@ -41,7 +41,7 @@ - + @@ -57,7 +57,7 @@ - + diff --git a/examples/Component/ODESolver/Backward/StaticSolver.scn b/examples/Component/ODESolver/Backward/StaticSolver.scn index 4689fba42e4..0a79f591aa5 100644 --- a/examples/Component/ODESolver/Backward/StaticSolver.scn +++ b/examples/Component/ODESolver/Backward/StaticSolver.scn @@ -1,5 +1,5 @@ - + @@ -26,7 +26,7 @@ - + @@ -41,7 +41,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/examples/Component/ODESolver/Backward/VariationalSymplecticSolver.scn b/examples/Component/ODESolver/Backward/VariationalSymplecticSolver.scn index a031face7c0..ea118addb4d 100644 --- a/examples/Component/ODESolver/Backward/VariationalSymplecticSolver.scn +++ b/examples/Component/ODESolver/Backward/VariationalSymplecticSolver.scn @@ -1,5 +1,5 @@ - + diff --git a/examples/Component/ODESolver/Forward/EulerExplicitSolver.scn b/examples/Component/ODESolver/Forward/EulerExplicitSolver.scn index 1272f33b10a..9f8fb209521 100644 --- a/examples/Component/ODESolver/Forward/EulerExplicitSolver.scn +++ b/examples/Component/ODESolver/Forward/EulerExplicitSolver.scn @@ -7,7 +7,7 @@ trivially, it requires a linear solver, here SparseLDLSolver. --> - + @@ -37,7 +37,7 @@ trivially, it requires a linear solver, here SparseLDLSolver. - + diff --git a/examples/Component/ODESolver/Forward/EulerExplicitSolver_diagonal.scn b/examples/Component/ODESolver/Forward/EulerExplicitSolver_diagonal.scn index a95b1a42dea..5a803ed22c5 100644 --- a/examples/Component/ODESolver/Forward/EulerExplicitSolver_diagonal.scn +++ b/examples/Component/ODESolver/Forward/EulerExplicitSolver_diagonal.scn @@ -7,7 +7,7 @@ trivially, it does not require a linear solver. --> - + @@ -36,7 +36,7 @@ trivially, it does not require a linear solver. - + diff --git a/examples/Component/ODESolver/Forward/EulerSymplecticSolver.scn b/examples/Component/ODESolver/Forward/EulerSymplecticSolver.scn index 14d46ad801f..a82b531ff07 100644 --- a/examples/Component/ODESolver/Forward/EulerSymplecticSolver.scn +++ b/examples/Component/ODESolver/Forward/EulerSymplecticSolver.scn @@ -7,7 +7,7 @@ trivially, it requires a linear solver, here SparseLDLSolver. --> - + @@ -29,7 +29,7 @@ trivially, it requires a linear solver, here SparseLDLSolver. - + diff --git a/examples/Component/ODESolver/Forward/EulerSymplecticSolver_diagonal.scn b/examples/Component/ODESolver/Forward/EulerSymplecticSolver_diagonal.scn index 6d5620fc725..f8a7a002d4a 100644 --- a/examples/Component/ODESolver/Forward/EulerSymplecticSolver_diagonal.scn +++ b/examples/Component/ODESolver/Forward/EulerSymplecticSolver_diagonal.scn @@ -7,7 +7,7 @@ trivially, it does not require a linear solver. --> - + @@ -29,7 +29,7 @@ trivially, it does not require a linear solver. - + diff --git a/examples/Component/ODESolver/Forward/RungeKutta4Solver.scn b/examples/Component/ODESolver/Forward/RungeKutta4Solver.scn index 5eb51e00eab..c45ca8d11f1 100644 --- a/examples/Component/ODESolver/Forward/RungeKutta4Solver.scn +++ b/examples/Component/ODESolver/Forward/RungeKutta4Solver.scn @@ -1,6 +1,6 @@ - + @@ -19,7 +19,7 @@ - + diff --git a/examples/Component/SceneUtility/Monitor.scn b/examples/Component/SceneUtility/Monitor.scn index 10a2bf4132a..1810517d79d 100644 --- a/examples/Component/SceneUtility/Monitor.scn +++ b/examples/Component/SceneUtility/Monitor.scn @@ -3,7 +3,7 @@ - + @@ -17,7 +17,7 @@ - + diff --git a/examples/Component/SolidMechanics/FEM/BeamFEMForceField.scn b/examples/Component/SolidMechanics/FEM/BeamFEMForceField.scn index 6de3f836c54..f7d6d1850d5 100644 --- a/examples/Component/SolidMechanics/FEM/BeamFEMForceField.scn +++ b/examples/Component/SolidMechanics/FEM/BeamFEMForceField.scn @@ -6,7 +6,7 @@ - + @@ -32,7 +32,7 @@ - + @@ -49,7 +49,7 @@ - + @@ -70,7 +70,7 @@ - + diff --git a/examples/Component/SolidMechanics/FEM/FastTetrahedralCorotationalForceField.scn b/examples/Component/SolidMechanics/FEM/FastTetrahedralCorotationalForceField.scn index ef62a08a3f6..f51bfdca6ef 100644 --- a/examples/Component/SolidMechanics/FEM/FastTetrahedralCorotationalForceField.scn +++ b/examples/Component/SolidMechanics/FEM/FastTetrahedralCorotationalForceField.scn @@ -1,6 +1,6 @@ - + @@ -31,7 +31,7 @@ - + @@ -51,7 +51,7 @@ - + @@ -70,7 +70,7 @@ - + @@ -89,7 +89,7 @@ - + diff --git a/examples/Component/SolidMechanics/FEM/FastTetrahedronCorotationalForceField_validation.scn b/examples/Component/SolidMechanics/FEM/FastTetrahedronCorotationalForceField_validation.scn index 47999c5dfac..5b222445625 100644 --- a/examples/Component/SolidMechanics/FEM/FastTetrahedronCorotationalForceField_validation.scn +++ b/examples/Component/SolidMechanics/FEM/FastTetrahedronCorotationalForceField_validation.scn @@ -3,7 +3,7 @@ - + @@ -38,7 +38,7 @@ - + @@ -52,7 +52,7 @@ - + diff --git a/examples/Component/SolidMechanics/FEM/Heterogeneous-TetrahedronFEMForceField.scn b/examples/Component/SolidMechanics/FEM/Heterogeneous-TetrahedronFEMForceField.scn index 816e0241398..0fe9a314781 100644 --- a/examples/Component/SolidMechanics/FEM/Heterogeneous-TetrahedronFEMForceField.scn +++ b/examples/Component/SolidMechanics/FEM/Heterogeneous-TetrahedronFEMForceField.scn @@ -4,7 +4,7 @@ - + diff --git a/examples/Component/SolidMechanics/FEM/HexahedralFEMForceField.scn b/examples/Component/SolidMechanics/FEM/HexahedralFEMForceField.scn index 7452f277823..1c34905cb0a 100644 --- a/examples/Component/SolidMechanics/FEM/HexahedralFEMForceField.scn +++ b/examples/Component/SolidMechanics/FEM/HexahedralFEMForceField.scn @@ -4,7 +4,7 @@ - + @@ -31,7 +31,7 @@ - + diff --git a/examples/Component/SolidMechanics/FEM/HexahedralFEMForceFieldAndMass.scn b/examples/Component/SolidMechanics/FEM/HexahedralFEMForceFieldAndMass.scn index 0ec0270db84..c7f7d2032f5 100644 --- a/examples/Component/SolidMechanics/FEM/HexahedralFEMForceFieldAndMass.scn +++ b/examples/Component/SolidMechanics/FEM/HexahedralFEMForceFieldAndMass.scn @@ -4,7 +4,7 @@ - + @@ -24,7 +24,7 @@ - + diff --git a/examples/Component/SolidMechanics/FEM/HexahedronCompositeFEMForceFieldAndMass.scn b/examples/Component/SolidMechanics/FEM/HexahedronCompositeFEMForceFieldAndMass.scn index 60154bce09b..d9cacbce533 100644 --- a/examples/Component/SolidMechanics/FEM/HexahedronCompositeFEMForceFieldAndMass.scn +++ b/examples/Component/SolidMechanics/FEM/HexahedronCompositeFEMForceFieldAndMass.scn @@ -4,7 +4,7 @@ - + diff --git a/examples/Component/SolidMechanics/FEM/HexahedronCompositeFEMMapping.scn b/examples/Component/SolidMechanics/FEM/HexahedronCompositeFEMMapping.scn index 2f336d01caf..4504389e56c 100644 --- a/examples/Component/SolidMechanics/FEM/HexahedronCompositeFEMMapping.scn +++ b/examples/Component/SolidMechanics/FEM/HexahedronCompositeFEMMapping.scn @@ -1,6 +1,6 @@ - + diff --git a/examples/Component/SolidMechanics/FEM/HexahedronFEMForceField.scn b/examples/Component/SolidMechanics/FEM/HexahedronFEMForceField.scn index f42cbc5ec94..5b04f5ba4c1 100644 --- a/examples/Component/SolidMechanics/FEM/HexahedronFEMForceField.scn +++ b/examples/Component/SolidMechanics/FEM/HexahedronFEMForceField.scn @@ -4,7 +4,7 @@ - + @@ -26,7 +26,7 @@ - + diff --git a/examples/Component/SolidMechanics/FEM/HexahedronFEMForceFieldAndMass.scn b/examples/Component/SolidMechanics/FEM/HexahedronFEMForceFieldAndMass.scn index db7bd372a48..9593a932fb6 100644 --- a/examples/Component/SolidMechanics/FEM/HexahedronFEMForceFieldAndMass.scn +++ b/examples/Component/SolidMechanics/FEM/HexahedronFEMForceFieldAndMass.scn @@ -4,7 +4,7 @@ - + @@ -24,7 +24,7 @@ - + diff --git a/examples/Component/SolidMechanics/FEM/QuadBendingFEMForceField.scn b/examples/Component/SolidMechanics/FEM/QuadBendingFEMForceField.scn index bd43c7d7455..cf38273caee 100644 --- a/examples/Component/SolidMechanics/FEM/QuadBendingFEMForceField.scn +++ b/examples/Component/SolidMechanics/FEM/QuadBendingFEMForceField.scn @@ -3,7 +3,7 @@ - + @@ -35,7 +35,7 @@ - + diff --git a/examples/Component/SolidMechanics/FEM/StandardTetrahedralFEMForceField.scn b/examples/Component/SolidMechanics/FEM/StandardTetrahedralFEMForceField.scn index b986347c1f8..62ccba55d4c 100644 --- a/examples/Component/SolidMechanics/FEM/StandardTetrahedralFEMForceField.scn +++ b/examples/Component/SolidMechanics/FEM/StandardTetrahedralFEMForceField.scn @@ -1,6 +1,6 @@  - + @@ -27,7 +27,7 @@ - + @@ -50,7 +50,7 @@ - + @@ -73,7 +73,7 @@ - + @@ -97,7 +97,7 @@ - + @@ -121,7 +121,7 @@ - + diff --git a/examples/Component/SolidMechanics/FEM/TetrahedralCorotationalFEMForceField.scn b/examples/Component/SolidMechanics/FEM/TetrahedralCorotationalFEMForceField.scn index c6ce0dfa93c..c3df8204e17 100644 --- a/examples/Component/SolidMechanics/FEM/TetrahedralCorotationalFEMForceField.scn +++ b/examples/Component/SolidMechanics/FEM/TetrahedralCorotationalFEMForceField.scn @@ -3,7 +3,7 @@ - + @@ -40,7 +40,7 @@ - + @@ -59,7 +59,7 @@ - + @@ -78,7 +78,7 @@ - + diff --git a/examples/Component/SolidMechanics/FEM/TetrahedronFEMForceField.scn b/examples/Component/SolidMechanics/FEM/TetrahedronFEMForceField.scn index a408d693b72..d0256eddc4b 100644 --- a/examples/Component/SolidMechanics/FEM/TetrahedronFEMForceField.scn +++ b/examples/Component/SolidMechanics/FEM/TetrahedronFEMForceField.scn @@ -1,6 +1,6 @@ - + @@ -32,7 +32,7 @@ method="small" computeVonMisesStress="2" showVonMisesStressPerElement="true"/> - + @@ -53,7 +53,7 @@ method="large" computeVonMisesStress="1" showVonMisesStressPerElement="true"/> - + @@ -73,7 +73,7 @@ method="polar" computeVonMisesStress="1" showVonMisesStressPerElement="true"/> - + @@ -93,7 +93,7 @@ method="svd" computeVonMisesStress="1" showVonMisesStressPerElement="true"/> - + diff --git a/examples/Component/SolidMechanics/FEM/TetrahedronFEMForceField_assemble.scn b/examples/Component/SolidMechanics/FEM/TetrahedronFEMForceField_assemble.scn index dc6c9526fe9..d3ca3afc6ef 100644 --- a/examples/Component/SolidMechanics/FEM/TetrahedronFEMForceField_assemble.scn +++ b/examples/Component/SolidMechanics/FEM/TetrahedronFEMForceField_assemble.scn @@ -1,6 +1,6 @@ - + @@ -32,7 +32,7 @@ method="small" computeVonMisesStress="2" showVonMisesStressPerElement="true"/> - + @@ -53,7 +53,7 @@ method="large" computeVonMisesStress="1" showVonMisesStressPerElement="true"/> - + diff --git a/examples/Component/SolidMechanics/FEM/TetrahedronHyperelasticityFEMForceField.scn b/examples/Component/SolidMechanics/FEM/TetrahedronHyperelasticityFEMForceField.scn index 153604ed412..33f6f9ec77f 100644 --- a/examples/Component/SolidMechanics/FEM/TetrahedronHyperelasticityFEMForceField.scn +++ b/examples/Component/SolidMechanics/FEM/TetrahedronHyperelasticityFEMForceField.scn @@ -3,7 +3,7 @@ - + @@ -35,7 +35,7 @@ - + @@ -58,7 +58,7 @@ - + @@ -81,7 +81,7 @@ - + @@ -105,7 +105,7 @@ - + @@ -129,7 +129,7 @@ - + diff --git a/examples/Component/SolidMechanics/FEM/TopoMap_cylinder3d.scn b/examples/Component/SolidMechanics/FEM/TopoMap_cylinder3d.scn index 334b284bed6..667747cdd90 100644 --- a/examples/Component/SolidMechanics/FEM/TopoMap_cylinder3d.scn +++ b/examples/Component/SolidMechanics/FEM/TopoMap_cylinder3d.scn @@ -4,7 +4,7 @@ - + @@ -34,8 +34,8 @@ - - + + diff --git a/examples/Component/SolidMechanics/FEM/TriangleFEMForceField.scn b/examples/Component/SolidMechanics/FEM/TriangleFEMForceField.scn index 42e22aa28ac..de077cccc6f 100644 --- a/examples/Component/SolidMechanics/FEM/TriangleFEMForceField.scn +++ b/examples/Component/SolidMechanics/FEM/TriangleFEMForceField.scn @@ -5,7 +5,7 @@ - + @@ -29,7 +29,7 @@ - + @@ -43,7 +43,7 @@ - + @@ -57,7 +57,7 @@ - + diff --git a/examples/Component/SolidMechanics/FEM/TriangularFEMForceField.scn b/examples/Component/SolidMechanics/FEM/TriangularFEMForceField.scn index 93562748dea..b3af073835d 100644 --- a/examples/Component/SolidMechanics/FEM/TriangularFEMForceField.scn +++ b/examples/Component/SolidMechanics/FEM/TriangularFEMForceField.scn @@ -2,7 +2,7 @@ - + @@ -27,7 +27,7 @@ - + diff --git a/examples/Component/SolidMechanics/FEM/TriangularFEMForceFieldOptim.scn b/examples/Component/SolidMechanics/FEM/TriangularFEMForceFieldOptim.scn index 11109678816..335f377b2cc 100644 --- a/examples/Component/SolidMechanics/FEM/TriangularFEMForceFieldOptim.scn +++ b/examples/Component/SolidMechanics/FEM/TriangularFEMForceFieldOptim.scn @@ -1,6 +1,6 @@ - + @@ -26,7 +26,7 @@ - + @@ -42,7 +42,7 @@ - + diff --git a/examples/Component/SolidMechanics/FEM/TriangularForceFieldComparison.scn b/examples/Component/SolidMechanics/FEM/TriangularForceFieldComparison.scn index 742e0ede096..6c1db8b3e1b 100644 --- a/examples/Component/SolidMechanics/FEM/TriangularForceFieldComparison.scn +++ b/examples/Component/SolidMechanics/FEM/TriangularForceFieldComparison.scn @@ -4,7 +4,7 @@ - + @@ -33,7 +33,7 @@ - + @@ -51,7 +51,7 @@ - + @@ -69,7 +69,7 @@ - + @@ -86,7 +86,7 @@ - + @@ -104,7 +104,7 @@ - + @@ -122,7 +122,7 @@ - + diff --git a/examples/Component/SolidMechanics/Spring/FastTriangularBendingSprings.scn b/examples/Component/SolidMechanics/Spring/FastTriangularBendingSprings.scn index 2c641ed6442..d3248971fa9 100644 --- a/examples/Component/SolidMechanics/Spring/FastTriangularBendingSprings.scn +++ b/examples/Component/SolidMechanics/Spring/FastTriangularBendingSprings.scn @@ -1,6 +1,6 @@ - + @@ -23,7 +23,7 @@ - + diff --git a/examples/Component/SolidMechanics/Spring/GearSpringForceField.scn b/examples/Component/SolidMechanics/Spring/GearSpringForceField.scn index d4e8365c1c4..8638f562f7a 100644 --- a/examples/Component/SolidMechanics/Spring/GearSpringForceField.scn +++ b/examples/Component/SolidMechanics/Spring/GearSpringForceField.scn @@ -1,6 +1,6 @@ - + @@ -19,7 +19,7 @@ - + - + @@ -24,7 +24,7 @@ - + diff --git a/examples/Component/SolidMechanics/Spring/PolynomialSpringsForceField.scn b/examples/Component/SolidMechanics/Spring/PolynomialSpringsForceField.scn index 3fb4b48612c..4c371472940 100644 --- a/examples/Component/SolidMechanics/Spring/PolynomialSpringsForceField.scn +++ b/examples/Component/SolidMechanics/Spring/PolynomialSpringsForceField.scn @@ -1,6 +1,6 @@ - + @@ -26,7 +26,7 @@ - + diff --git a/examples/Component/SolidMechanics/Spring/QuadBendingSprings.scn b/examples/Component/SolidMechanics/Spring/QuadBendingSprings.scn index f31183aff9c..a558ca9c461 100644 --- a/examples/Component/SolidMechanics/Spring/QuadBendingSprings.scn +++ b/examples/Component/SolidMechanics/Spring/QuadBendingSprings.scn @@ -4,7 +4,7 @@ - + @@ -27,7 +27,7 @@ - + diff --git a/examples/Component/SolidMechanics/Spring/QuadularBendingSprings.scn b/examples/Component/SolidMechanics/Spring/QuadularBendingSprings.scn index e13e58e6e3d..cbd07d9dd5c 100644 --- a/examples/Component/SolidMechanics/Spring/QuadularBendingSprings.scn +++ b/examples/Component/SolidMechanics/Spring/QuadularBendingSprings.scn @@ -1,6 +1,6 @@ - + @@ -27,7 +27,7 @@ - + diff --git a/examples/Component/SolidMechanics/Spring/StiffSpringForceField.scn b/examples/Component/SolidMechanics/Spring/StiffSpringForceField.scn index 32915c1e0f3..3c258b02abe 100644 --- a/examples/Component/SolidMechanics/Spring/StiffSpringForceField.scn +++ b/examples/Component/SolidMechanics/Spring/StiffSpringForceField.scn @@ -1,6 +1,6 @@ - + @@ -18,7 +18,7 @@ - + - + @@ -19,7 +19,7 @@ - + diff --git a/examples/Component/SolidMechanics/Spring/TriangleBendingSprings.scn b/examples/Component/SolidMechanics/Spring/TriangleBendingSprings.scn index fbdf1ef7e0a..388c392d540 100644 --- a/examples/Component/SolidMechanics/Spring/TriangleBendingSprings.scn +++ b/examples/Component/SolidMechanics/Spring/TriangleBendingSprings.scn @@ -4,7 +4,7 @@ - + @@ -29,7 +29,7 @@ - + @@ -44,7 +44,7 @@ - + @@ -59,7 +59,7 @@ - + diff --git a/examples/Component/SolidMechanics/Spring/TriangularBendingSprings.scn b/examples/Component/SolidMechanics/Spring/TriangularBendingSprings.scn index 1b7c86c3000..8a54f619b88 100644 --- a/examples/Component/SolidMechanics/Spring/TriangularBendingSprings.scn +++ b/examples/Component/SolidMechanics/Spring/TriangularBendingSprings.scn @@ -1,7 +1,7 @@ - + @@ -26,7 +26,7 @@ - + diff --git a/examples/Component/SolidMechanics/Spring/TriangularBiquadraticSpringsForceField.scn b/examples/Component/SolidMechanics/Spring/TriangularBiquadraticSpringsForceField.scn index a18fbb939a4..6e302f05d1e 100644 --- a/examples/Component/SolidMechanics/Spring/TriangularBiquadraticSpringsForceField.scn +++ b/examples/Component/SolidMechanics/Spring/TriangularBiquadraticSpringsForceField.scn @@ -4,7 +4,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/examples/Component/SolidMechanics/Spring/TriangularQuadraticSpringsForceField.scn b/examples/Component/SolidMechanics/Spring/TriangularQuadraticSpringsForceField.scn index fad0a123be8..5eab98c9c75 100644 --- a/examples/Component/SolidMechanics/Spring/TriangularQuadraticSpringsForceField.scn +++ b/examples/Component/SolidMechanics/Spring/TriangularQuadraticSpringsForceField.scn @@ -4,7 +4,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/examples/Component/SolidMechanics/Spring/angularSpringForceField.scn b/examples/Component/SolidMechanics/Spring/angularSpringForceField.scn index 2054f6972a8..6befcf8641f 100644 --- a/examples/Component/SolidMechanics/Spring/angularSpringForceField.scn +++ b/examples/Component/SolidMechanics/Spring/angularSpringForceField.scn @@ -2,7 +2,7 @@ - + @@ -21,7 +21,7 @@ - + - + @@ -26,7 +26,7 @@ - + diff --git a/examples/Component/SolidMechanics/TensorMass/TriangularTensorMassForceField.scn b/examples/Component/SolidMechanics/TensorMass/TriangularTensorMassForceField.scn index e36ea927bee..0c343ed0451 100644 --- a/examples/Component/SolidMechanics/TensorMass/TriangularTensorMassForceField.scn +++ b/examples/Component/SolidMechanics/TensorMass/TriangularTensorMassForceField.scn @@ -4,7 +4,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/examples/Component/Topology/Container/Constant/CubeTopology.scn b/examples/Component/Topology/Container/Constant/CubeTopology.scn index b609a805318..7bbc5019a00 100644 --- a/examples/Component/Topology/Container/Constant/CubeTopology.scn +++ b/examples/Component/Topology/Container/Constant/CubeTopology.scn @@ -2,7 +2,7 @@ - + @@ -31,7 +31,7 @@ - + diff --git a/examples/Component/Topology/Container/Constant/MeshTopology.scn b/examples/Component/Topology/Container/Constant/MeshTopology.scn index 2fb0c26b4cb..bf9714109e2 100644 --- a/examples/Component/Topology/Container/Constant/MeshTopology.scn +++ b/examples/Component/Topology/Container/Constant/MeshTopology.scn @@ -3,7 +3,7 @@ - + @@ -29,7 +29,7 @@ - + diff --git a/examples/Component/Topology/Container/Dynamic/AddingHexa2QuadProcess.scn b/examples/Component/Topology/Container/Dynamic/AddingHexa2QuadProcess.scn index 7dfdc4189fd..12911430754 100644 --- a/examples/Component/Topology/Container/Dynamic/AddingHexa2QuadProcess.scn +++ b/examples/Component/Topology/Container/Dynamic/AddingHexa2QuadProcess.scn @@ -32,7 +32,7 @@ - + diff --git a/examples/Component/Topology/Container/Dynamic/AddingQuad2TriangleProcess.scn b/examples/Component/Topology/Container/Dynamic/AddingQuad2TriangleProcess.scn index 978ed3cd0a5..f581f4b1cc4 100644 --- a/examples/Component/Topology/Container/Dynamic/AddingQuad2TriangleProcess.scn +++ b/examples/Component/Topology/Container/Dynamic/AddingQuad2TriangleProcess.scn @@ -4,7 +4,7 @@ - + @@ -34,7 +34,7 @@ - + diff --git a/examples/Component/Topology/Container/Dynamic/AddingTetra2TriangleProcess.scn b/examples/Component/Topology/Container/Dynamic/AddingTetra2TriangleProcess.scn index 9f72d246ceb..e2e194409a7 100644 --- a/examples/Component/Topology/Container/Dynamic/AddingTetra2TriangleProcess.scn +++ b/examples/Component/Topology/Container/Dynamic/AddingTetra2TriangleProcess.scn @@ -5,7 +5,7 @@ - + @@ -37,7 +37,7 @@ - + diff --git a/examples/Component/Topology/Container/Dynamic/AddingTetraProcess.scn b/examples/Component/Topology/Container/Dynamic/AddingTetraProcess.scn index 49c575e37c0..9f03e52700f 100644 --- a/examples/Component/Topology/Container/Dynamic/AddingTetraProcess.scn +++ b/examples/Component/Topology/Container/Dynamic/AddingTetraProcess.scn @@ -1,7 +1,7 @@ - + @@ -26,7 +26,7 @@ - + diff --git a/examples/Component/Topology/Container/Dynamic/AddingTriangle2EdgeProcess.scn b/examples/Component/Topology/Container/Dynamic/AddingTriangle2EdgeProcess.scn index 8d8f6ca94f9..9db682d2432 100644 --- a/examples/Component/Topology/Container/Dynamic/AddingTriangle2EdgeProcess.scn +++ b/examples/Component/Topology/Container/Dynamic/AddingTriangle2EdgeProcess.scn @@ -4,7 +4,7 @@ - + @@ -34,7 +34,7 @@ - + diff --git a/examples/Component/Topology/Container/Dynamic/AddingTrianglesProcess.scn b/examples/Component/Topology/Container/Dynamic/AddingTrianglesProcess.scn index 0d9105af026..b66e3a2506d 100644 --- a/examples/Component/Topology/Container/Dynamic/AddingTrianglesProcess.scn +++ b/examples/Component/Topology/Container/Dynamic/AddingTrianglesProcess.scn @@ -2,7 +2,7 @@ - + @@ -27,7 +27,7 @@ - + diff --git a/examples/Component/Topology/Container/Dynamic/IncisionTrianglesProcess.scn b/examples/Component/Topology/Container/Dynamic/IncisionTrianglesProcess.scn index 2a5ca7c8d5b..56ab31ecb70 100644 --- a/examples/Component/Topology/Container/Dynamic/IncisionTrianglesProcess.scn +++ b/examples/Component/Topology/Container/Dynamic/IncisionTrianglesProcess.scn @@ -1,7 +1,7 @@ - + @@ -30,9 +30,9 @@ - + - + diff --git a/examples/Component/Topology/Container/Dynamic/QuadForceFieldTopologyChangeHandling.scn b/examples/Component/Topology/Container/Dynamic/QuadForceFieldTopologyChangeHandling.scn index d78dd21bf32..da98e773a16 100644 --- a/examples/Component/Topology/Container/Dynamic/QuadForceFieldTopologyChangeHandling.scn +++ b/examples/Component/Topology/Container/Dynamic/QuadForceFieldTopologyChangeHandling.scn @@ -4,7 +4,7 @@ - + @@ -35,7 +35,7 @@ - + @@ -60,7 +60,7 @@ - + diff --git a/examples/Component/Topology/Container/Dynamic/RemovingBilateralInteractionConstraint.scn b/examples/Component/Topology/Container/Dynamic/RemovingBilateralInteractionConstraint.scn index 99379c74861..f5add59b1cb 100644 --- a/examples/Component/Topology/Container/Dynamic/RemovingBilateralInteractionConstraint.scn +++ b/examples/Component/Topology/Container/Dynamic/RemovingBilateralInteractionConstraint.scn @@ -3,9 +3,9 @@ - + - + @@ -49,7 +49,7 @@ - + @@ -69,7 +69,7 @@ - diff --git a/examples/Component/Topology/Container/Dynamic/RemovingHexa2QuadProcess.scn b/examples/Component/Topology/Container/Dynamic/RemovingHexa2QuadProcess.scn index 8082325f57f..7e6a9ce7a36 100644 --- a/examples/Component/Topology/Container/Dynamic/RemovingHexa2QuadProcess.scn +++ b/examples/Component/Topology/Container/Dynamic/RemovingHexa2QuadProcess.scn @@ -4,7 +4,7 @@ - + @@ -35,7 +35,7 @@ - + diff --git a/examples/Component/Topology/Container/Dynamic/RemovingHexa2TetraProcess.scn b/examples/Component/Topology/Container/Dynamic/RemovingHexa2TetraProcess.scn index 2aeabffa5ff..47e266cdb05 100644 --- a/examples/Component/Topology/Container/Dynamic/RemovingHexa2TetraProcess.scn +++ b/examples/Component/Topology/Container/Dynamic/RemovingHexa2TetraProcess.scn @@ -4,7 +4,7 @@ - + @@ -31,7 +31,7 @@ - + diff --git a/examples/Component/Topology/Container/Dynamic/RemovingPointSprings.scn b/examples/Component/Topology/Container/Dynamic/RemovingPointSprings.scn index e8ca93ba73f..bd8f5173e25 100644 --- a/examples/Component/Topology/Container/Dynamic/RemovingPointSprings.scn +++ b/examples/Component/Topology/Container/Dynamic/RemovingPointSprings.scn @@ -1,6 +1,6 @@ - + @@ -23,7 +23,7 @@ - + diff --git a/examples/Component/Topology/Container/Dynamic/RemovingQuad2TriangleProcess.scn b/examples/Component/Topology/Container/Dynamic/RemovingQuad2TriangleProcess.scn index 5f768411e3d..0da9403d217 100644 --- a/examples/Component/Topology/Container/Dynamic/RemovingQuad2TriangleProcess.scn +++ b/examples/Component/Topology/Container/Dynamic/RemovingQuad2TriangleProcess.scn @@ -4,7 +4,7 @@ - + @@ -37,7 +37,7 @@ - + diff --git a/examples/Component/Topology/Container/Dynamic/RemovingTetra2TriangleProcess.scn b/examples/Component/Topology/Container/Dynamic/RemovingTetra2TriangleProcess.scn index b14df973ec3..e24313c4e8d 100644 --- a/examples/Component/Topology/Container/Dynamic/RemovingTetra2TriangleProcess.scn +++ b/examples/Component/Topology/Container/Dynamic/RemovingTetra2TriangleProcess.scn @@ -4,7 +4,7 @@ - + @@ -38,7 +38,7 @@ - + @@ -70,7 +70,7 @@ - + diff --git a/examples/Component/Topology/Container/Dynamic/RemovingTetra2TriangleProcess_performanceTest.scn b/examples/Component/Topology/Container/Dynamic/RemovingTetra2TriangleProcess_performanceTest.scn index a2f7b98388e..439d24d59d7 100644 --- a/examples/Component/Topology/Container/Dynamic/RemovingTetra2TriangleProcess_performanceTest.scn +++ b/examples/Component/Topology/Container/Dynamic/RemovingTetra2TriangleProcess_performanceTest.scn @@ -4,7 +4,7 @@ - + @@ -38,8 +38,8 @@ - - + + diff --git a/examples/Component/Topology/Container/Dynamic/RemovingTetra2Triangle_options1.scn b/examples/Component/Topology/Container/Dynamic/RemovingTetra2Triangle_options1.scn index a2501516c7c..5f89f112722 100644 --- a/examples/Component/Topology/Container/Dynamic/RemovingTetra2Triangle_options1.scn +++ b/examples/Component/Topology/Container/Dynamic/RemovingTetra2Triangle_options1.scn @@ -4,7 +4,7 @@ - + @@ -38,7 +38,7 @@ - + diff --git a/examples/Component/Topology/Container/Dynamic/RemovingTetra2Triangle_options2.scn b/examples/Component/Topology/Container/Dynamic/RemovingTetra2Triangle_options2.scn index bb16ddce2da..1354d9e00b3 100644 --- a/examples/Component/Topology/Container/Dynamic/RemovingTetra2Triangle_options2.scn +++ b/examples/Component/Topology/Container/Dynamic/RemovingTetra2Triangle_options2.scn @@ -4,7 +4,7 @@ - + @@ -38,7 +38,7 @@ - + diff --git a/examples/Component/Topology/Container/Dynamic/RemovingTetraProcess.scn b/examples/Component/Topology/Container/Dynamic/RemovingTetraProcess.scn index f2808233196..c54a981b324 100644 --- a/examples/Component/Topology/Container/Dynamic/RemovingTetraProcess.scn +++ b/examples/Component/Topology/Container/Dynamic/RemovingTetraProcess.scn @@ -1,7 +1,7 @@ - + @@ -27,7 +27,7 @@ - + diff --git a/examples/Component/Topology/Container/Dynamic/RemovingTetraProcess_withCollisionModel.scn b/examples/Component/Topology/Container/Dynamic/RemovingTetraProcess_withCollisionModel.scn index 568776286e5..dbe1160b8b9 100644 --- a/examples/Component/Topology/Container/Dynamic/RemovingTetraProcess_withCollisionModel.scn +++ b/examples/Component/Topology/Container/Dynamic/RemovingTetraProcess_withCollisionModel.scn @@ -5,7 +5,7 @@ - + @@ -35,7 +35,7 @@ - + diff --git a/examples/Component/Topology/Container/Dynamic/RemovingTrianglesProcess.scn b/examples/Component/Topology/Container/Dynamic/RemovingTrianglesProcess.scn index 02d9577caba..47177d68a17 100644 --- a/examples/Component/Topology/Container/Dynamic/RemovingTrianglesProcess.scn +++ b/examples/Component/Topology/Container/Dynamic/RemovingTrianglesProcess.scn @@ -2,7 +2,7 @@ - + @@ -28,7 +28,7 @@ - + diff --git a/examples/Component/Topology/Container/Dynamic/TetrahedronForceFieldTopologyChangeHandling.scn b/examples/Component/Topology/Container/Dynamic/TetrahedronForceFieldTopologyChangeHandling.scn index 5964665426c..25e635fc489 100644 --- a/examples/Component/Topology/Container/Dynamic/TetrahedronForceFieldTopologyChangeHandling.scn +++ b/examples/Component/Topology/Container/Dynamic/TetrahedronForceFieldTopologyChangeHandling.scn @@ -3,7 +3,7 @@ - + @@ -31,8 +31,8 @@ - - + + @@ -48,8 +48,8 @@ - - + + diff --git a/examples/Component/Topology/Container/Dynamic/TriangularForceFieldTopologyChangeHandling.scn b/examples/Component/Topology/Container/Dynamic/TriangularForceFieldTopologyChangeHandling.scn index 7d2df8a5707..9967f3e8619 100644 --- a/examples/Component/Topology/Container/Dynamic/TriangularForceFieldTopologyChangeHandling.scn +++ b/examples/Component/Topology/Container/Dynamic/TriangularForceFieldTopologyChangeHandling.scn @@ -4,7 +4,7 @@ - + @@ -34,7 +34,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -74,7 +74,7 @@ - + @@ -92,7 +92,7 @@ - + @@ -111,7 +111,7 @@ - + @@ -130,7 +130,7 @@ - + diff --git a/examples/Component/Topology/Container/Grid/CylinderGridTopology.scn b/examples/Component/Topology/Container/Grid/CylinderGridTopology.scn index 3a2c8fba836..c335012a561 100644 --- a/examples/Component/Topology/Container/Grid/CylinderGridTopology.scn +++ b/examples/Component/Topology/Container/Grid/CylinderGridTopology.scn @@ -1,5 +1,5 @@ - + diff --git a/examples/Component/Topology/Container/Grid/RegularGridTopology.scn b/examples/Component/Topology/Container/Grid/RegularGridTopology.scn index 98477edc65e..7e0a03a59ef 100644 --- a/examples/Component/Topology/Container/Grid/RegularGridTopology.scn +++ b/examples/Component/Topology/Container/Grid/RegularGridTopology.scn @@ -4,7 +4,7 @@ - + diff --git a/examples/Component/Topology/Container/Grid/RegularGridTopology_TrianglesMesh.scn b/examples/Component/Topology/Container/Grid/RegularGridTopology_TrianglesMesh.scn index 73c2db19208..ba5fa7211f6 100644 --- a/examples/Component/Topology/Container/Grid/RegularGridTopology_TrianglesMesh.scn +++ b/examples/Component/Topology/Container/Grid/RegularGridTopology_TrianglesMesh.scn @@ -4,7 +4,7 @@ - + @@ -37,7 +37,7 @@ - + diff --git a/examples/Component/Topology/Container/Grid/RegularGridTopology_dimension.scn b/examples/Component/Topology/Container/Grid/RegularGridTopology_dimension.scn index 4b6013ae741..971036289a1 100644 --- a/examples/Component/Topology/Container/Grid/RegularGridTopology_dimension.scn +++ b/examples/Component/Topology/Container/Grid/RegularGridTopology_dimension.scn @@ -5,7 +5,7 @@ - + @@ -40,7 +40,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -80,7 +80,7 @@ - + diff --git a/examples/Component/Topology/Container/Grid/SparseGridRamificationTopology.scn b/examples/Component/Topology/Container/Grid/SparseGridRamificationTopology.scn index 775017e130f..89913d936e9 100644 --- a/examples/Component/Topology/Container/Grid/SparseGridRamificationTopology.scn +++ b/examples/Component/Topology/Container/Grid/SparseGridRamificationTopology.scn @@ -4,7 +4,7 @@ - + diff --git a/examples/Component/Topology/Container/Grid/SparseGridTopology.scn b/examples/Component/Topology/Container/Grid/SparseGridTopology.scn index a0b48814d93..665e19b7f72 100644 --- a/examples/Component/Topology/Container/Grid/SparseGridTopology.scn +++ b/examples/Component/Topology/Container/Grid/SparseGridTopology.scn @@ -5,7 +5,7 @@ - + diff --git a/examples/Component/Topology/Container/Grid/SphereGridTopology.scn b/examples/Component/Topology/Container/Grid/SphereGridTopology.scn index e945880d4b0..81d16006618 100644 --- a/examples/Component/Topology/Container/Grid/SphereGridTopology.scn +++ b/examples/Component/Topology/Container/Grid/SphereGridTopology.scn @@ -1,6 +1,6 @@ - + diff --git a/examples/Component/Topology/Mapping/Edge2QuadTopologicalMapping.scn b/examples/Component/Topology/Mapping/Edge2QuadTopologicalMapping.scn index 4e6356f8d3c..0c855327e74 100644 --- a/examples/Component/Topology/Mapping/Edge2QuadTopologicalMapping.scn +++ b/examples/Component/Topology/Mapping/Edge2QuadTopologicalMapping.scn @@ -4,7 +4,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/examples/Component/Topology/Mapping/Hexa2QuadTopologicalMapping.scn b/examples/Component/Topology/Mapping/Hexa2QuadTopologicalMapping.scn index 115562bf8aa..cb9a02fc91f 100644 --- a/examples/Component/Topology/Mapping/Hexa2QuadTopologicalMapping.scn +++ b/examples/Component/Topology/Mapping/Hexa2QuadTopologicalMapping.scn @@ -4,7 +4,7 @@ - + @@ -34,7 +34,7 @@ - + diff --git a/examples/Component/Topology/Mapping/Hexa2TetraTopologicalMapping.scn b/examples/Component/Topology/Mapping/Hexa2TetraTopologicalMapping.scn index 376d4c23326..cb3e306da96 100644 --- a/examples/Component/Topology/Mapping/Hexa2TetraTopologicalMapping.scn +++ b/examples/Component/Topology/Mapping/Hexa2TetraTopologicalMapping.scn @@ -4,7 +4,7 @@ - + @@ -32,7 +32,7 @@ - + diff --git a/examples/Component/Topology/Mapping/Hexa2TetraTopologicalMapping_export.scn b/examples/Component/Topology/Mapping/Hexa2TetraTopologicalMapping_export.scn index 563a1e0b03e..d3ccf4b4902 100644 --- a/examples/Component/Topology/Mapping/Hexa2TetraTopologicalMapping_export.scn +++ b/examples/Component/Topology/Mapping/Hexa2TetraTopologicalMapping_export.scn @@ -3,7 +3,7 @@ - + @@ -32,7 +32,7 @@ - + diff --git a/examples/Component/Topology/Mapping/Mesh2PointTopologicalMapping.scn b/examples/Component/Topology/Mapping/Mesh2PointTopologicalMapping.scn index a6441cb623a..e2785cc0585 100644 --- a/examples/Component/Topology/Mapping/Mesh2PointTopologicalMapping.scn +++ b/examples/Component/Topology/Mapping/Mesh2PointTopologicalMapping.scn @@ -4,7 +4,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/examples/Component/Topology/Mapping/Quad2TriangleTopologicalMapping.scn b/examples/Component/Topology/Mapping/Quad2TriangleTopologicalMapping.scn index 69841881ae3..acb1a15e14b 100644 --- a/examples/Component/Topology/Mapping/Quad2TriangleTopologicalMapping.scn +++ b/examples/Component/Topology/Mapping/Quad2TriangleTopologicalMapping.scn @@ -4,7 +4,7 @@ - + @@ -33,7 +33,7 @@ - + diff --git a/examples/Component/Topology/Mapping/SubsetTopologicalMapping.scn b/examples/Component/Topology/Mapping/SubsetTopologicalMapping.scn index b1cbb23bb12..71d80fd5ae9 100644 --- a/examples/Component/Topology/Mapping/SubsetTopologicalMapping.scn +++ b/examples/Component/Topology/Mapping/SubsetTopologicalMapping.scn @@ -4,7 +4,7 @@ - + @@ -33,7 +33,7 @@ - + diff --git a/examples/Component/Topology/Mapping/SubsetTopologicalMapping2.scn b/examples/Component/Topology/Mapping/SubsetTopologicalMapping2.scn index 3fe5c8e41af..9a1dc9a39d4 100644 --- a/examples/Component/Topology/Mapping/SubsetTopologicalMapping2.scn +++ b/examples/Component/Topology/Mapping/SubsetTopologicalMapping2.scn @@ -4,7 +4,7 @@ - + @@ -36,7 +36,7 @@ - + diff --git a/examples/Component/Topology/Mapping/Tetra2TriangleTopologicalMapping.scn b/examples/Component/Topology/Mapping/Tetra2TriangleTopologicalMapping.scn index a3c10c569b0..bc4dab7563a 100644 --- a/examples/Component/Topology/Mapping/Tetra2TriangleTopologicalMapping.scn +++ b/examples/Component/Topology/Mapping/Tetra2TriangleTopologicalMapping.scn @@ -4,7 +4,7 @@ - + @@ -33,8 +33,8 @@ - - + + diff --git a/examples/Component/Topology/Mapping/Tetra2TriangleTopologicalMapping_NoInitialTriangle_option.scn b/examples/Component/Topology/Mapping/Tetra2TriangleTopologicalMapping_NoInitialTriangle_option.scn index 22a8eea5978..3b75eb4a480 100644 --- a/examples/Component/Topology/Mapping/Tetra2TriangleTopologicalMapping_NoInitialTriangle_option.scn +++ b/examples/Component/Topology/Mapping/Tetra2TriangleTopologicalMapping_NoInitialTriangle_option.scn @@ -4,7 +4,7 @@ - + @@ -32,8 +32,8 @@ - - + + diff --git a/examples/Component/Topology/Mapping/Tetra2TriangleTopologicalMapping_with_TetrahedronModel.scn b/examples/Component/Topology/Mapping/Tetra2TriangleTopologicalMapping_with_TetrahedronModel.scn index 6a54be5dd80..81b17db73c3 100644 --- a/examples/Component/Topology/Mapping/Tetra2TriangleTopologicalMapping_with_TetrahedronModel.scn +++ b/examples/Component/Topology/Mapping/Tetra2TriangleTopologicalMapping_with_TetrahedronModel.scn @@ -3,7 +3,7 @@ - + @@ -34,8 +34,8 @@ - - + + diff --git a/examples/Component/Topology/Mapping/TopoMap_Hexa2Quad2Triangle.scn b/examples/Component/Topology/Mapping/TopoMap_Hexa2Quad2Triangle.scn index 84386d456b8..377d96cb032 100644 --- a/examples/Component/Topology/Mapping/TopoMap_Hexa2Quad2Triangle.scn +++ b/examples/Component/Topology/Mapping/TopoMap_Hexa2Quad2Triangle.scn @@ -3,7 +3,7 @@ - + @@ -33,7 +33,7 @@ - + diff --git a/examples/Component/Topology/Mapping/Triangle2EdgeTopologicalMapping.scn b/examples/Component/Topology/Mapping/Triangle2EdgeTopologicalMapping.scn index 8d6c7fe6234..0b9ac8859f7 100644 --- a/examples/Component/Topology/Mapping/Triangle2EdgeTopologicalMapping.scn +++ b/examples/Component/Topology/Mapping/Triangle2EdgeTopologicalMapping.scn @@ -4,7 +4,7 @@ - + @@ -31,7 +31,7 @@ - + diff --git a/examples/Component/Visual/DataDisplay.scn b/examples/Component/Visual/DataDisplay.scn index 186da9b83d9..056cb1104ac 100644 --- a/examples/Component/Visual/DataDisplay.scn +++ b/examples/Component/Visual/DataDisplay.scn @@ -4,7 +4,7 @@ - + @@ -37,7 +37,7 @@ - + diff --git a/examples/Component/Visual/LinearBlendSkinningGPU.scn b/examples/Component/Visual/LinearBlendSkinningGPU.scn index 8b2f2a3a17b..78f55310d59 100644 --- a/examples/Component/Visual/LinearBlendSkinningGPU.scn +++ b/examples/Component/Visual/LinearBlendSkinningGPU.scn @@ -1,6 +1,6 @@ - + @@ -13,7 +13,7 @@ - + diff --git a/examples/Component/Visual/OglShader.scn b/examples/Component/Visual/OglShader.scn index 33a71916ab8..286a3e01e7f 100644 --- a/examples/Component/Visual/OglShader.scn +++ b/examples/Component/Visual/OglShader.scn @@ -4,7 +4,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/examples/Component/Visual/OglShader_tessellation.scn b/examples/Component/Visual/OglShader_tessellation.scn index 8ba7a2f79c5..8cca789e0ad 100644 --- a/examples/Component/Visual/OglShader_tessellation.scn +++ b/examples/Component/Visual/OglShader_tessellation.scn @@ -4,7 +4,7 @@ - + diff --git a/examples/Component/Visual/OglViewport.scn b/examples/Component/Visual/OglViewport.scn index f0ee97506a7..861b877b84f 100644 --- a/examples/Component/Visual/OglViewport.scn +++ b/examples/Component/Visual/OglViewport.scn @@ -3,7 +3,7 @@ - + @@ -33,7 +33,7 @@ - + diff --git a/examples/Component/Visual/PostProcessManager_DepthOfField.scn b/examples/Component/Visual/PostProcessManager_DepthOfField.scn index c64fa42544c..f7c484be59b 100644 --- a/examples/Component/Visual/PostProcessManager_DepthOfField.scn +++ b/examples/Component/Visual/PostProcessManager_DepthOfField.scn @@ -3,7 +3,7 @@ - + @@ -34,7 +34,7 @@ - + diff --git a/examples/Component/Visual/VisualStyle.scn b/examples/Component/Visual/VisualStyle.scn index 7b728fc39a2..cdabc70aa44 100644 --- a/examples/Component/Visual/VisualStyle.scn +++ b/examples/Component/Visual/VisualStyle.scn @@ -1,7 +1,7 @@ - + @@ -24,7 +24,7 @@ - + diff --git a/examples/Demos/TriangleSurfaceCutting.scn b/examples/Demos/TriangleSurfaceCutting.scn index ff1ac8f95c0..6606ffde44a 100644 --- a/examples/Demos/TriangleSurfaceCutting.scn +++ b/examples/Demos/TriangleSurfaceCutting.scn @@ -4,7 +4,7 @@ - + @@ -33,7 +33,7 @@ - + diff --git a/examples/Demos/include_test.scn b/examples/Demos/include_test.scn index e87c364c0a6..2abaeecc312 100644 --- a/examples/Demos/include_test.scn +++ b/examples/Demos/include_test.scn @@ -1,6 +1,6 @@ - + diff --git a/examples/Demos/include_test.xml b/examples/Demos/include_test.xml index b9d0af04bd9..630c537c627 100644 --- a/examples/Demos/include_test.xml +++ b/examples/Demos/include_test.xml @@ -3,7 +3,7 @@ - + diff --git a/examples/Demos/liver.scn b/examples/Demos/liver.scn index f9a61bcd922..97cbaccc4cd 100644 --- a/examples/Demos/liver.scn +++ b/examples/Demos/liver.scn @@ -4,7 +4,7 @@ - + @@ -33,7 +33,7 @@ - + diff --git a/examples/Demos/liverConfiguration.scn b/examples/Demos/liverConfiguration.scn index 79bb8040f47..320b1c9cd4a 100644 --- a/examples/Demos/liverConfiguration.scn +++ b/examples/Demos/liverConfiguration.scn @@ -4,7 +4,7 @@ - + @@ -49,7 +49,7 @@ - + diff --git a/examples/Demos/rigidifiedSectionsInBeam.scn b/examples/Demos/rigidifiedSectionsInBeam.scn index 6997800c1fd..1556d02f278 100644 --- a/examples/Demos/rigidifiedSectionsInBeam.scn +++ b/examples/Demos/rigidifiedSectionsInBeam.scn @@ -15,7 +15,7 @@ The distances do not vary over time for the rigidified beam, whereas we can obse - + @@ -41,7 +41,7 @@ The distances do not vary over time for the rigidified beam, whereas we can obse - + @@ -76,7 +76,7 @@ The distances do not vary over time for the rigidified beam, whereas we can obse - + diff --git a/examples/Demos/simpleBoundaryConditions.scn b/examples/Demos/simpleBoundaryConditions.scn index 4a2f8a3c4b5..003ba8a71e6 100644 --- a/examples/Demos/simpleBoundaryConditions.scn +++ b/examples/Demos/simpleBoundaryConditions.scn @@ -1,7 +1,7 @@ - + @@ -27,15 +27,15 @@ - + - + - + diff --git a/examples/Demos/simpleSphere.scn b/examples/Demos/simpleSphere.scn index ff25c96b2b5..3f368f5dc1e 100644 --- a/examples/Demos/simpleSphere.scn +++ b/examples/Demos/simpleSphere.scn @@ -4,7 +4,7 @@ - + @@ -32,7 +32,7 @@ - + diff --git a/examples/Demos/skybox.scn b/examples/Demos/skybox.scn index 71debbb798b..6291ef1f642 100644 --- a/examples/Demos/skybox.scn +++ b/examples/Demos/skybox.scn @@ -2,7 +2,7 @@ - + @@ -46,7 +46,7 @@ - + diff --git a/examples/Objects/BoxConstraint.xml b/examples/Objects/BoxConstraint.xml index c0e071328df..c738f9b2ee3 100644 --- a/examples/Objects/BoxConstraint.xml +++ b/examples/Objects/BoxConstraint.xml @@ -1,4 +1,4 @@ - + diff --git a/examples/Objects/InstrumentCoil.xml b/examples/Objects/InstrumentCoil.xml index 487295942a2..8fe3e9883a9 100644 --- a/examples/Objects/InstrumentCoil.xml +++ b/examples/Objects/InstrumentCoil.xml @@ -12,7 +12,7 @@ - + diff --git a/examples/Objects/PlaneConstraint.xml b/examples/Objects/PlaneConstraint.xml index 38c58c77d7d..3584c1a658f 100644 --- a/examples/Objects/PlaneConstraint.xml +++ b/examples/Objects/PlaneConstraint.xml @@ -1,4 +1,4 @@ - + diff --git a/examples/Tutorials/Basic/TutorialBasicPendulum.scn b/examples/Tutorials/Basic/TutorialBasicPendulum.scn index f7427773fe8..4b798c38a5a 100644 --- a/examples/Tutorials/Basic/TutorialBasicPendulum.scn +++ b/examples/Tutorials/Basic/TutorialBasicPendulum.scn @@ -2,7 +2,7 @@ - + @@ -22,7 +22,7 @@ - + diff --git a/examples/Tutorials/ForceFields/TutorialForceFieldLiverFEM.scn b/examples/Tutorials/ForceFields/TutorialForceFieldLiverFEM.scn index 42acfdc79f9..442c862eee6 100644 --- a/examples/Tutorials/ForceFields/TutorialForceFieldLiverFEM.scn +++ b/examples/Tutorials/ForceFields/TutorialForceFieldLiverFEM.scn @@ -5,7 +5,7 @@ - + @@ -32,7 +32,7 @@ - + diff --git a/examples/Tutorials/ForceFields/TutorialForceFieldLiverHexaFEM.scn b/examples/Tutorials/ForceFields/TutorialForceFieldLiverHexaFEM.scn index 26348f81c47..f6664899646 100644 --- a/examples/Tutorials/ForceFields/TutorialForceFieldLiverHexaFEM.scn +++ b/examples/Tutorials/ForceFields/TutorialForceFieldLiverHexaFEM.scn @@ -5,7 +5,7 @@ - + @@ -31,7 +31,7 @@ - + diff --git a/examples/Tutorials/ForceFields/TutorialForceFieldLiverSprings.scn b/examples/Tutorials/ForceFields/TutorialForceFieldLiverSprings.scn index 1bf78a60459..3c20e7699fb 100644 --- a/examples/Tutorials/ForceFields/TutorialForceFieldLiverSprings.scn +++ b/examples/Tutorials/ForceFields/TutorialForceFieldLiverSprings.scn @@ -5,7 +5,7 @@ - + @@ -32,7 +32,7 @@ - + diff --git a/examples/Tutorials/ForceFields/TutorialForceFieldLiverTriangleFEM.scn b/examples/Tutorials/ForceFields/TutorialForceFieldLiverTriangleFEM.scn index 839282b1a53..819b41a76a3 100644 --- a/examples/Tutorials/ForceFields/TutorialForceFieldLiverTriangleFEM.scn +++ b/examples/Tutorials/ForceFields/TutorialForceFieldLiverTriangleFEM.scn @@ -4,7 +4,7 @@ - + @@ -32,7 +32,7 @@ - + diff --git a/examples/Tutorials/Mappings/TutorialMappingLiverBarycentric.scn b/examples/Tutorials/Mappings/TutorialMappingLiverBarycentric.scn index ab44da46044..d97b935f351 100644 --- a/examples/Tutorials/Mappings/TutorialMappingLiverBarycentric.scn +++ b/examples/Tutorials/Mappings/TutorialMappingLiverBarycentric.scn @@ -3,7 +3,7 @@ - + @@ -33,7 +33,7 @@ - + diff --git a/examples/Tutorials/OldTutorials/demo1.scn b/examples/Tutorials/OldTutorials/demo1.scn index 83d3e361325..a25d89ff944 100644 --- a/examples/Tutorials/OldTutorials/demo1.scn +++ b/examples/Tutorials/OldTutorials/demo1.scn @@ -9,7 +9,7 @@ - + diff --git a/examples/Tutorials/OldTutorials/demo2.scn b/examples/Tutorials/OldTutorials/demo2.scn index ca64909df40..d43f195bc7f 100644 --- a/examples/Tutorials/OldTutorials/demo2.scn +++ b/examples/Tutorials/OldTutorials/demo2.scn @@ -9,7 +9,7 @@ - + diff --git a/examples/Tutorials/OldTutorials/demo3.scn b/examples/Tutorials/OldTutorials/demo3.scn index ef71cf6a933..78ebe2667a1 100644 --- a/examples/Tutorials/OldTutorials/demo3.scn +++ b/examples/Tutorials/OldTutorials/demo3.scn @@ -1,6 +1,6 @@ - + @@ -20,7 +20,7 @@ - + diff --git a/examples/Tutorials/OldTutorials/demo4.scn b/examples/Tutorials/OldTutorials/demo4.scn index 651dca14589..f877377b70b 100644 --- a/examples/Tutorials/OldTutorials/demo4.scn +++ b/examples/Tutorials/OldTutorials/demo4.scn @@ -1,7 +1,7 @@ - + @@ -21,7 +21,7 @@ - + diff --git a/examples/Tutorials/OldTutorials/demo5.scn b/examples/Tutorials/OldTutorials/demo5.scn index 3643ac61acf..5507e97dc42 100644 --- a/examples/Tutorials/OldTutorials/demo5.scn +++ b/examples/Tutorials/OldTutorials/demo5.scn @@ -1,7 +1,7 @@ - + @@ -22,7 +22,7 @@ - + diff --git a/examples/Tutorials/OldTutorials/demo6.scn b/examples/Tutorials/OldTutorials/demo6.scn index 6a8c288693d..ed6e6094f90 100644 --- a/examples/Tutorials/OldTutorials/demo6.scn +++ b/examples/Tutorials/OldTutorials/demo6.scn @@ -3,7 +3,7 @@ - + @@ -28,7 +28,7 @@ - + diff --git a/examples/Tutorials/OldTutorials/demo6Triangle.scn b/examples/Tutorials/OldTutorials/demo6Triangle.scn index 6680ccbe030..38bc1aad011 100644 --- a/examples/Tutorials/OldTutorials/demo6Triangle.scn +++ b/examples/Tutorials/OldTutorials/demo6Triangle.scn @@ -3,7 +3,7 @@ - + @@ -29,7 +29,7 @@ - + diff --git a/examples/Tutorials/OldTutorials/demo7.scn b/examples/Tutorials/OldTutorials/demo7.scn index c5ef158c0f4..9acd9e08f3f 100644 --- a/examples/Tutorials/OldTutorials/demo7.scn +++ b/examples/Tutorials/OldTutorials/demo7.scn @@ -4,7 +4,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/examples/Tutorials/OldTutorials/demo7Triangle.scn b/examples/Tutorials/OldTutorials/demo7Triangle.scn index 5029a221df6..ea0e55ddb40 100644 --- a/examples/Tutorials/OldTutorials/demo7Triangle.scn +++ b/examples/Tutorials/OldTutorials/demo7Triangle.scn @@ -4,7 +4,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/examples/Tutorials/StepByStep/Pendulum/2_Pendulum.scn b/examples/Tutorials/StepByStep/Pendulum/2_Pendulum.scn index 5321450246d..2c0ca124178 100644 --- a/examples/Tutorials/StepByStep/Pendulum/2_Pendulum.scn +++ b/examples/Tutorials/StepByStep/Pendulum/2_Pendulum.scn @@ -1,7 +1,7 @@ - + @@ -17,6 +17,6 @@ - + diff --git a/examples/Tutorials/StepByStep/Pendulum/3_Pendulum.scn b/examples/Tutorials/StepByStep/Pendulum/3_Pendulum.scn index 190879b5fbe..2b32034e94a 100644 --- a/examples/Tutorials/StepByStep/Pendulum/3_Pendulum.scn +++ b/examples/Tutorials/StepByStep/Pendulum/3_Pendulum.scn @@ -1,7 +1,7 @@ - + @@ -17,6 +17,6 @@ - + diff --git a/examples/Tutorials/StepByStep/Pendulum/4_Pendulum.scn b/examples/Tutorials/StepByStep/Pendulum/4_Pendulum.scn index 84def987c71..157cd1905a7 100644 --- a/examples/Tutorials/StepByStep/Pendulum/4_Pendulum.scn +++ b/examples/Tutorials/StepByStep/Pendulum/4_Pendulum.scn @@ -1,7 +1,7 @@ - + @@ -18,7 +18,7 @@ - + diff --git a/examples/Tutorials/StepByStep/Pendulum/5_Pendulum.scn b/examples/Tutorials/StepByStep/Pendulum/5_Pendulum.scn index ab7cfce6485..52daf599a7c 100644 --- a/examples/Tutorials/StepByStep/Pendulum/5_Pendulum.scn +++ b/examples/Tutorials/StepByStep/Pendulum/5_Pendulum.scn @@ -1,7 +1,7 @@ - + @@ -18,7 +18,7 @@ - + diff --git a/examples/Tutorials/StepByStep/Pendulum/6_Pendulum.scn b/examples/Tutorials/StepByStep/Pendulum/6_Pendulum.scn index 131dc8e3a0d..8eb715a9ed1 100644 --- a/examples/Tutorials/StepByStep/Pendulum/6_Pendulum.scn +++ b/examples/Tutorials/StepByStep/Pendulum/6_Pendulum.scn @@ -1,7 +1,7 @@ - + @@ -18,7 +18,7 @@ - + diff --git a/examples/Tutorials/StepByStep/Pendulum/7_Pendulum.scn b/examples/Tutorials/StepByStep/Pendulum/7_Pendulum.scn index 716589198f6..279fb7443af 100644 --- a/examples/Tutorials/StepByStep/Pendulum/7_Pendulum.scn +++ b/examples/Tutorials/StepByStep/Pendulum/7_Pendulum.scn @@ -1,7 +1,7 @@ - + @@ -20,7 +20,7 @@ - + diff --git a/examples/Tutorials/StepByStep/TopologicalMapping/2_TopoMapping.html b/examples/Tutorials/StepByStep/TopologicalMapping/2_TopoMapping.html index 6f85f2bb9fc..75bde4f22ea 100644 --- a/examples/Tutorials/StepByStep/TopologicalMapping/2_TopoMapping.html +++ b/examples/Tutorials/StepByStep/TopologicalMapping/2_TopoMapping.html @@ -31,7 +31,7 @@

Add a DiagonalMass component. In the Property 2/2 tab, change the mass density to "2".

-

Add a FixedPlaneConstraint component. In the Property 2/2 tab, change the normal direction of the plane to (0 0 1), the minimum plane distance from the origin to "-0.1" and the maximum plane distance from the origin to "0.1".

+

Add a FixedPlaneProjectiveConstraint component. In the Property 2/2 tab, change the normal direction of the plane to (0 0 1), the minimum plane distance from the origin to "-0.1" and the maximum plane distance from the origin to "0.1".

Add a FixedConstraint component.

diff --git a/examples/Tutorials/StepByStep/TopologicalMapping/2_TopoMapping.scn b/examples/Tutorials/StepByStep/TopologicalMapping/2_TopoMapping.scn index 62835d77397..aeb42eee4e1 100644 --- a/examples/Tutorials/StepByStep/TopologicalMapping/2_TopoMapping.scn +++ b/examples/Tutorials/StepByStep/TopologicalMapping/2_TopoMapping.scn @@ -2,7 +2,7 @@ - + @@ -29,7 +29,7 @@ - - + +
diff --git a/examples/Tutorials/StepByStep/TopologicalMapping/3_TopoMapping.scn b/examples/Tutorials/StepByStep/TopologicalMapping/3_TopoMapping.scn index 8ceefb5a0a0..8934fadbd89 100644 --- a/examples/Tutorials/StepByStep/TopologicalMapping/3_TopoMapping.scn +++ b/examples/Tutorials/StepByStep/TopologicalMapping/3_TopoMapping.scn @@ -2,7 +2,7 @@ - + @@ -31,8 +31,8 @@ - - + + diff --git a/examples/Tutorials/StepByStep/TopologicalMapping/4_TopoMapping.scn b/examples/Tutorials/StepByStep/TopologicalMapping/4_TopoMapping.scn index 08159c9da90..f22e47f1f07 100644 --- a/examples/Tutorials/StepByStep/TopologicalMapping/4_TopoMapping.scn +++ b/examples/Tutorials/StepByStep/TopologicalMapping/4_TopoMapping.scn @@ -3,7 +3,7 @@ - + @@ -33,8 +33,8 @@ - - + + diff --git a/examples/Tutorials/StepByStep/TopologicalMapping/5_TopoMapping.scn b/examples/Tutorials/StepByStep/TopologicalMapping/5_TopoMapping.scn index cd88d172300..2e3af39877c 100644 --- a/examples/Tutorials/StepByStep/TopologicalMapping/5_TopoMapping.scn +++ b/examples/Tutorials/StepByStep/TopologicalMapping/5_TopoMapping.scn @@ -2,7 +2,7 @@ - + @@ -27,6 +27,6 @@ - + diff --git a/examples/Tutorials/StepByStep/TopologicalMapping/6_TopoMapping.scn b/examples/Tutorials/StepByStep/TopologicalMapping/6_TopoMapping.scn index 5d1e2c99581..71f1ee35826 100644 --- a/examples/Tutorials/StepByStep/TopologicalMapping/6_TopoMapping.scn +++ b/examples/Tutorials/StepByStep/TopologicalMapping/6_TopoMapping.scn @@ -3,7 +3,7 @@ - + @@ -32,7 +32,7 @@ - + diff --git a/examples/Tutorials/Topologies/TopologyDynamicSurfaceMesh.scn b/examples/Tutorials/Topologies/TopologyDynamicSurfaceMesh.scn index b36132ea1d8..613ee62a277 100644 --- a/examples/Tutorials/Topologies/TopologyDynamicSurfaceMesh.scn +++ b/examples/Tutorials/Topologies/TopologyDynamicSurfaceMesh.scn @@ -5,7 +5,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -48,7 +48,7 @@ - + diff --git a/examples/Tutorials/Topologies/TopologyHexa2QuadTopologicalMapping.scn b/examples/Tutorials/Topologies/TopologyHexa2QuadTopologicalMapping.scn index a373dbd4c10..24397ec455e 100644 --- a/examples/Tutorials/Topologies/TopologyHexa2QuadTopologicalMapping.scn +++ b/examples/Tutorials/Topologies/TopologyHexa2QuadTopologicalMapping.scn @@ -5,7 +5,7 @@ - + @@ -39,7 +39,7 @@ - + diff --git a/examples/Tutorials/Topologies/TopologyHexa2TetraTopologicalMapping.scn b/examples/Tutorials/Topologies/TopologyHexa2TetraTopologicalMapping.scn index 147a8101d85..0988993861d 100644 --- a/examples/Tutorials/Topologies/TopologyHexa2TetraTopologicalMapping.scn +++ b/examples/Tutorials/Topologies/TopologyHexa2TetraTopologicalMapping.scn @@ -5,7 +5,7 @@ - + @@ -35,7 +35,7 @@ - + diff --git a/examples/Tutorials/Topologies/TopologyLinearDifferentMesh.scn b/examples/Tutorials/Topologies/TopologyLinearDifferentMesh.scn index e69b5ab4ab0..2cba18085b8 100644 --- a/examples/Tutorials/Topologies/TopologyLinearDifferentMesh.scn +++ b/examples/Tutorials/Topologies/TopologyLinearDifferentMesh.scn @@ -5,7 +5,7 @@ - + @@ -29,7 +29,7 @@ - + @@ -38,7 +38,7 @@ - + @@ -47,7 +47,7 @@ - + diff --git a/examples/Tutorials/Topologies/TopologyLinearMesh.scn b/examples/Tutorials/Topologies/TopologyLinearMesh.scn index b74b106e104..8d0ab41eff5 100644 --- a/examples/Tutorials/Topologies/TopologyLinearMesh.scn +++ b/examples/Tutorials/Topologies/TopologyLinearMesh.scn @@ -5,7 +5,7 @@ - + @@ -28,7 +28,7 @@ - + @@ -37,7 +37,7 @@ - + diff --git a/examples/Tutorials/Topologies/TopologyQuad2TriangleTopologicalMapping.scn b/examples/Tutorials/Topologies/TopologyQuad2TriangleTopologicalMapping.scn index df5bbe0f42e..405995b6f4e 100644 --- a/examples/Tutorials/Topologies/TopologyQuad2TriangleTopologicalMapping.scn +++ b/examples/Tutorials/Topologies/TopologyQuad2TriangleTopologicalMapping.scn @@ -5,7 +5,7 @@ - + @@ -37,7 +37,7 @@ - + diff --git a/examples/Tutorials/Topologies/TopologySurfaceDifferentMesh.scn b/examples/Tutorials/Topologies/TopologySurfaceDifferentMesh.scn index dfaa0ac1ecd..f106babd7c7 100644 --- a/examples/Tutorials/Topologies/TopologySurfaceDifferentMesh.scn +++ b/examples/Tutorials/Topologies/TopologySurfaceDifferentMesh.scn @@ -5,7 +5,7 @@ - + @@ -32,7 +32,7 @@ - + @@ -51,7 +51,7 @@ - + @@ -67,7 +67,7 @@ - + diff --git a/examples/Tutorials/Topologies/TopologyTetra2TriangleTopologicalMapping.scn b/examples/Tutorials/Topologies/TopologyTetra2TriangleTopologicalMapping.scn index f278c7c6683..cd31606b43e 100644 --- a/examples/Tutorials/Topologies/TopologyTetra2TriangleTopologicalMapping.scn +++ b/examples/Tutorials/Topologies/TopologyTetra2TriangleTopologicalMapping.scn @@ -5,7 +5,7 @@ - + @@ -37,8 +37,8 @@ - - + + diff --git a/examples/Tutorials/Topologies/TopologyTriangle2EdgeTopologicalMapping.scn b/examples/Tutorials/Topologies/TopologyTriangle2EdgeTopologicalMapping.scn index 38bd3ad2a1f..864bbb4448b 100644 --- a/examples/Tutorials/Topologies/TopologyTriangle2EdgeTopologicalMapping.scn +++ b/examples/Tutorials/Topologies/TopologyTriangle2EdgeTopologicalMapping.scn @@ -4,7 +4,7 @@ - + @@ -34,7 +34,7 @@ - + diff --git a/examples/Tutorials/Topologies/TopologyVolumeDifferentMesh.scn b/examples/Tutorials/Topologies/TopologyVolumeDifferentMesh.scn index ac65ea551bc..51c3c060145 100644 --- a/examples/Tutorials/Topologies/TopologyVolumeDifferentMesh.scn +++ b/examples/Tutorials/Topologies/TopologyVolumeDifferentMesh.scn @@ -5,7 +5,7 @@ - + @@ -32,7 +32,7 @@ - + @@ -48,7 +48,7 @@ - + @@ -63,7 +63,7 @@ - + diff --git a/examples/Tutorials/sandbox/explicit_singlehexaFEM.scn b/examples/Tutorials/sandbox/explicit_singlehexaFEM.scn index 60262a2943f..106be54f5d5 100644 --- a/examples/Tutorials/sandbox/explicit_singlehexaFEM.scn +++ b/examples/Tutorials/sandbox/explicit_singlehexaFEM.scn @@ -1,6 +1,6 @@ - + @@ -18,7 +18,7 @@ - + diff --git a/examples/Tutorials/sandbox/implicit_singlehexaFEM.scn b/examples/Tutorials/sandbox/implicit_singlehexaFEM.scn index 188ff6cd041..445f4f01c82 100644 --- a/examples/Tutorials/sandbox/implicit_singlehexaFEM.scn +++ b/examples/Tutorials/sandbox/implicit_singlehexaFEM.scn @@ -1,6 +1,6 @@ - + @@ -22,7 +22,7 @@ - + diff --git a/examples/Tutorials/sandbox/implicit_singlehexaFEM_2.scn b/examples/Tutorials/sandbox/implicit_singlehexaFEM_2.scn index 66eb8938126..3eade952857 100644 --- a/examples/Tutorials/sandbox/implicit_singlehexaFEM_2.scn +++ b/examples/Tutorials/sandbox/implicit_singlehexaFEM_2.scn @@ -1,6 +1,6 @@ - + @@ -22,7 +22,7 @@ - + diff --git a/examples/Tutorials/sandbox/rungekutta_singlehexaFEM.scn b/examples/Tutorials/sandbox/rungekutta_singlehexaFEM.scn index 2cb127cc6ab..42be6a45efa 100644 --- a/examples/Tutorials/sandbox/rungekutta_singlehexaFEM.scn +++ b/examples/Tutorials/sandbox/rungekutta_singlehexaFEM.scn @@ -1,6 +1,6 @@ - + @@ -17,7 +17,7 @@ - + From 384077fb13cb95e5fadd9093dd65f4fb9676386e Mon Sep 17 00:00:00 2001 From: erik pernod Date: Wed, 20 Dec 2023 22:37:17 +0100 Subject: [PATCH 29/45] [Constraint.Projective] Implement applyConstraint from new matrix assembly API (#4309) * [Constraint.Projective] Implement applyConstraint in AttachConstraint) * [Constraint.Projective] Implement applyConstraint in PartialLinearMovementConstraint * [Constraint.Projective] Implement applyConstraint in ProjectToPointConstraint * Fix compilation * revert rename Data --------- Co-authored-by: Paul Baksic --- .../constraint/projective/AttachConstraint.h | 2 +- .../projective/AttachProjectiveConstraint.h | 1 + .../projective/AttachProjectiveConstraint.inl | 43 +++++++++++++++++++ .../PartialLinearMovementConstraint.h | 2 +- ...artialLinearMovementProjectiveConstraint.h | 1 + ...tialLinearMovementProjectiveConstraint.inl | 19 ++++++++ .../projective/PointProjectiveConstraint.h | 1 + .../projective/PointProjectiveConstraint.inl | 13 ++++++ .../projective/ProjectToPointConstraint.h | 2 +- 9 files changed, 81 insertions(+), 3 deletions(-) diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachConstraint.h index 692f1178c2d..01a9ca4f4c2 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachConstraint.h @@ -29,4 +29,4 @@ namespace sofa::component::constraint::projective { template using AttachConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "AttachConstraint has been renamed to AttachProjectiveConstraint") = AttachProjectiveConstraint; -} \ No newline at end of file +} diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachProjectiveConstraint.h index 37ed886dc4b..a9a6d6f9dd2 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachProjectiveConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachProjectiveConstraint.h @@ -93,6 +93,7 @@ class AttachProjectiveConstraint : public core::behavior::PairInteractionProject /// Project the global Mechanical Vector to constrained space using offset parameter void applyConstraint(const core::MechanicalParams *mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + void applyConstraint(sofa::core::behavior::ZeroDirichletCondition* matrix) override; virtual void reinitIfChanged(); diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachProjectiveConstraint.inl index e7bd429434f..e84f25e1dca 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachProjectiveConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachProjectiveConstraint.inl @@ -545,6 +545,49 @@ void AttachProjectiveConstraint::applyConstraint(const core::Mechanic } } +template +void AttachProjectiveConstraint::applyConstraint(sofa::core::behavior::ZeroDirichletCondition* matrix) +{ + if (f_twoWay.getValue()) + return; + + reinitIfChanged(); + + static constexpr unsigned int N = Deriv::size(); + const SetIndexArray& indices = f_indices2.getValue(); + const unsigned int NC = DerivConstrainedSize(f_freeRotations.getValue()); + const unsigned int NCLast = DerivConstrainedSize(f_lastFreeRotation.getValue()); + unsigned int i = 0; + const bool clamp = f_clamp.getValue(); + + for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it, ++i) + { + if (!clamp && i < activeFlags.size() && !activeFlags[i]) + continue; + + auto index = (*it); + + if (NCLast != NC && (i >= activeFlags.size() || !activeFlags[i + 1])) + { + // Reset Fixed Row and Col + for (unsigned int c = 0; c < NCLast; ++c) + { + matrix->discardRowCol(N * index + c, N * index + c); + } + } + else + { + // Reset Fixed Row and Col + for (unsigned int c = 0; c < NC; ++c) + { + matrix->discardRowCol(N * index + c, N * index + c); + } + } + + ++i; + } +} + template const typename DataTypes::Real AttachProjectiveConstraint::getConstraintFactor(const int index) { return d_constraintFactor.getValue().size() ? d_constraintFactor.getValue()[index] : 1; diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementConstraint.h index f3eb83d8868..511449dff92 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementConstraint.h @@ -29,4 +29,4 @@ namespace sofa::component::constraint::projective { template using PartialLinearMovementConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "PartialLinearMovementConstraint has been renamed to PartialLinearMovementProjectiveConstraint") = PartialLinearMovementProjectiveConstraint; -} \ No newline at end of file +} diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.h index 336f0bf2ce6..105d833de27 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.h @@ -139,6 +139,7 @@ public : void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + void applyConstraint(sofa::core::behavior::ZeroDirichletCondition* matrix) override; void draw(const core::visual::VisualParams*) override; diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.inl index af02bb262d2..f28cda33b0a 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementProjectiveConstraint.inl @@ -457,6 +457,25 @@ void PartialLinearMovementProjectiveConstraint::applyConstraint(const } } + +template +void PartialLinearMovementProjectiveConstraint::applyConstraint(sofa::core::behavior::ZeroDirichletCondition* matrix) +{ + static constexpr unsigned int N = Deriv::size(); + const SetIndexArray& indices = m_indices.getValue(); + const VecBool& movedDirection = movedDirections.getValue(); + + for (const auto index : indices) + { + for (unsigned int c = 0; c < N; ++c) + { + if (movedDirection[c]) { + matrix->discardRowCol(N * index + c, N * index + c); + } + } + } +} + //display the path the constrained dofs will go through template void PartialLinearMovementProjectiveConstraint::draw(const core::visual::VisualParams* vparams) diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PointProjectiveConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PointProjectiveConstraint.h index 2055e7fe236..f67986ab49d 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PointProjectiveConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PointProjectiveConstraint.h @@ -104,6 +104,7 @@ class PointProjectiveConstraint : public core::behavior::ProjectiveConstraintSet void applyConstraint(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; void applyConstraint(const core::MechanicalParams* mparams, linearalgebra::BaseVector* vector, const sofa::core::behavior::MultiMatrixAccessor* matrix) override; + void applyConstraint(sofa::core::behavior::ZeroDirichletCondition* matrix) override; /** Project the given matrix (Experimental API). Replace M with PMP, where P is the projection matrix corresponding to the projectResponse method, shifted by the given offset, i.e. P is the identity matrix with a block on the diagonal replaced by the projection matrix. diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PointProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PointProjectiveConstraint.inl index b50b5aedd38..1c767cfded4 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PointProjectiveConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PointProjectiveConstraint.inl @@ -265,7 +265,20 @@ void PointProjectiveConstraint::applyConstraint(const core::Mechanica } } +template +void PointProjectiveConstraint::applyConstraint(sofa::core::behavior::ZeroDirichletCondition* matrix) +{ + static constexpr unsigned int N = Deriv::size(); + const SetIndexArray& indices = f_indices.getValue(); + for (const auto index : indices) + { + for (unsigned int c = 0; c < N; ++c) + { + matrix->discardRowCol(N * index + c, N * index + c); + } + } +} template diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPointConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPointConstraint.h index c5902f37823..b2c2780665f 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPointConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPointConstraint.h @@ -29,4 +29,4 @@ namespace sofa::component::constraint::projective { template using ProjectToPointConstraint SOFA_ATTRIBUTE_DEPRECATED("v24.06 ", "v25.06", "ProjectToPointConstraint has been renamed to PointProjectiveConstraint") = PointProjectiveConstraint; -} \ No newline at end of file +} From 357929def53ab114c1793b5763925bd6d8902c36 Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Thu, 21 Dec 2023 00:22:03 +0100 Subject: [PATCH 30/45] [Config] CMake: support interface-type target for install macro (#4356) * support interface-type for auto_target_properties install macro * try updating install macro * try updating install macro again * Update Sofa/framework/Config/cmake/SofaMacrosInstall.cmake --- .../Config/cmake/SofaMacrosInstall.cmake | 109 +++++++++++++----- 1 file changed, 80 insertions(+), 29 deletions(-) diff --git a/Sofa/framework/Config/cmake/SofaMacrosInstall.cmake b/Sofa/framework/Config/cmake/SofaMacrosInstall.cmake index 6c9efdd8579..eb7d22b0a0c 100644 --- a/Sofa/framework/Config/cmake/SofaMacrosInstall.cmake +++ b/Sofa/framework/Config/cmake/SofaMacrosInstall.cmake @@ -257,12 +257,20 @@ function(sofa_get_target_dependencies OUTPUT_LIST TARGET) if(aliased_target) set(TARGET ${aliased_target}) endif() + + get_target_property(target_type ${TARGET} TYPE) + if (${target_type} STREQUAL "INTERFACE_LIBRARY") + set(IS_INTERFACE_LIBRARY 1) + endif() + list(APPEND VISITED_TARGETS ${TARGET}) get_target_property(IMPORTED ${TARGET} IMPORTED) if(IMPORTED) get_target_property(LIBS ${TARGET} INTERFACE_LINK_LIBRARIES) else() - get_target_property(LIBS ${TARGET} LINK_LIBRARIES) + if(NOT IS_INTERFACE_LIBRARY) + get_target_property(LIBS ${TARGET} LINK_LIBRARIES) + endif() endif() set(LIB_TARGETS "") foreach(LIB ${LIBS}) @@ -338,26 +346,35 @@ macro(sofa_auto_set_target_version) set(target ${aliased_target}) endif() + # test if it is an interface (i.e header-only library) + get_target_property(target_type ${target} TYPE) + if (${target_type} STREQUAL "INTERFACE_LIBRARY") + set(IS_INTERFACE_LIBRARY 1) + endif() + string(TOUPPER "${target}" sofa_target_name_upper) # C Preprocessor definitions do not handle dot character, so it is replaced with an underscore string(REPLACE "." "_" sofa_target_name_upper "${sofa_target_name_upper}") set(${sofa_target_name_upper}_TARGET "${sofa_target_name_upper}") - # Set target properties - if(NOT "${target}" STREQUAL "${ARG_PACKAGE_NAME}") # Target is inside a package - set_target_properties(${target} PROPERTIES FOLDER ${ARG_PACKAGE_NAME}) # IDE folder - endif() - set_target_properties(${target} PROPERTIES DEBUG_POSTFIX "_d") - set(version "") - if(${target}_VERSION VERSION_GREATER "0.0") - set(version ${${target}_VERSION}) - elseif(ARG_PACKAGE_VERSION VERSION_GREATER "0.0") - set(version ${ARG_PACKAGE_VERSION}) - elseif(Sofa_VERSION VERSION_GREATER "0.0") - # Default to Sofa_VERSION for all SOFA modules - set(version ${Sofa_VERSION}) + if(NOT IS_INTERFACE_LIBRARY) # this test should not be necessary for cmake >3.24 + # Set target properties + if(NOT "${target}" STREQUAL "${ARG_PACKAGE_NAME}" ) # Target is inside a package + set_target_properties(${target} PROPERTIES FOLDER ${ARG_PACKAGE_NAME}) # IDE folder + endif() + set_target_properties(${target} PROPERTIES DEBUG_POSTFIX "_d") + + set(version "") + if(${target}_VERSION VERSION_GREATER "0.0") + set(version ${${target}_VERSION}) + elseif(ARG_PACKAGE_VERSION VERSION_GREATER "0.0") + set(version ${ARG_PACKAGE_VERSION}) + elseif(Sofa_VERSION VERSION_GREATER "0.0") + # Default to Sofa_VERSION for all SOFA modules + set(version ${Sofa_VERSION}) + endif() + set_target_properties(${target} PROPERTIES VERSION "${version}") endif() - set_target_properties(${target} PROPERTIES VERSION "${version}") set(${sofa_target_name_upper}_VERSION "${version}") set(PROJECT_VERSION "${version}") # warning: dangerous to touch this variable? endforeach() @@ -384,6 +401,15 @@ macro(sofa_auto_set_target_compile_definitions) set(target ${aliased_target}) endif() + # test if it is an interface (i.e header-only library) + get_target_property(target_type ${target} TYPE) + if (${target_type} STREQUAL "INTERFACE_LIBRARY") + set(IS_INTERFACE_LIBRARY 1) + set(TARGET_VISIBILITY INTERFACE) + else() + set(TARGET_VISIBILITY PRIVATE) + endif() + string(TOUPPER "${target}" sofa_target_name_upper) # C Preprocessor definitions do not handle dot character, so it is replaced with an underscore string(REPLACE "." "_" sofa_target_name_upper "${sofa_target_name_upper}") @@ -397,9 +423,10 @@ macro(sofa_auto_set_target_compile_definitions) string(REPLACE "Sofa" "" sofa_target_oldname "${sofa_target_oldname}") string(TOUPPER "${sofa_target_oldname}" sofa_target_oldname_upper) string(REPLACE "." "_" sofa_target_oldname_upper "${sofa_target_oldname_upper}") - target_compile_definitions(${target} PRIVATE "-DSOFA_BUILD${sofa_target_oldname_upper}") + + target_compile_definitions(${target} ${TARGET_VISIBILITY} "-DSOFA_BUILD${sofa_target_oldname_upper}") endif() - target_compile_definitions(${target} PRIVATE "-DSOFA_BUILD_${sofa_target_name_upper}") + target_compile_definitions(${target} ${TARGET_VISIBILITY} "-DSOFA_BUILD_${sofa_target_name_upper}") endforeach() endmacro() @@ -424,12 +451,23 @@ macro(sofa_auto_set_target_include_directories) set(target ${aliased_target}) endif() - get_target_property(target_sources ${target} SOURCES) - list(FILTER target_sources INCLUDE REGEX ".*(\\.h\\.in|\\.h|\\.inl)$") # keep only headers - if(NOT target_sources) - # target has no header - # setting include directories is not needed - continue() + # test if it is an interface (i.e header-only library) + get_target_property(target_type ${target} TYPE) + if (${target_type} STREQUAL "INTERFACE_LIBRARY") + set(IS_INTERFACE_LIBRARY 1) + set(TARGET_VISIBILITY INTERFACE) + else() + set(TARGET_VISIBILITY PUBLIC) + endif() + + if(NOT IS_INTERFACE_LIBRARY) + get_target_property(target_sources ${target} SOURCES) + list(FILTER target_sources INCLUDE REGEX ".*(\\.h\\.in|\\.h|\\.inl)$") # keep only headers + if(NOT target_sources) + # target has no header + # setting include directories is not needed + continue() + endif() endif() # Set target include directories (if not already set manually) @@ -441,26 +479,29 @@ macro(sofa_auto_set_target_include_directories) set(include_source_root "${CMAKE_CURRENT_SOURCE_DIR}/${ARG_INCLUDE_SOURCE_DIR}") endif() endif() - get_target_property(target_include_dirs ${target} "INCLUDE_DIRECTORIES") + + if(NOT IS_INTERFACE_LIBRARY) + get_target_property(target_include_dirs ${target} "INCLUDE_DIRECTORIES") + endif() if(NOT "\$" IN_LIST target_include_dirs) - target_include_directories(${target} PUBLIC "$") + target_include_directories(${target} ${TARGET_VISIBILITY} "$") endif() if(NOT "\$" IN_LIST target_include_dirs) - target_include_directories(${target} PUBLIC "$") + target_include_directories(${target} ${TARGET_VISIBILITY} "$") endif() if(ARG_RELOCATABLE) if(NOT "\$" IN_LIST target_include_dirs) - target_include_directories(${target} PUBLIC "$") + target_include_directories(${target} ${TARGET_VISIBILITY} "$") endif() elseif("${ARG_INCLUDE_INSTALL_DIR}" MATCHES "^${ARG_PACKAGE_NAME}") if(NOT "\$" IN_LIST target_include_dirs) - target_include_directories(${target} PUBLIC "$") + target_include_directories(${target} ${TARGET_VISIBILITY} "$") endif() else() if(NOT "\$" IN_LIST target_include_dirs) - target_include_directories(${target} PUBLIC "$") + target_include_directories(${target} ${TARGET_VISIBILITY} "$") endif() endif() #get_target_property(target_include_dirs ${target} "INCLUDE_DIRECTORIES") @@ -483,6 +524,16 @@ macro(sofa_auto_set_target_rpath) endforeach() foreach(target ${ARG_TARGETS}) # Most of the time there is only one target + # test if it is an interface (i.e header-only library) + get_target_property(target_type ${target} TYPE) + if (${target_type} STREQUAL "INTERFACE_LIBRARY") + set(IS_INTERFACE_LIBRARY 1) + endif() + + if(IS_INTERFACE_LIBRARY) + continue() + endif() + sofa_get_target_dependencies(target_deps ${target}) get_target_property(target_rpath ${target} "INSTALL_RPATH") foreach(dep ${target_deps}) From 0e3766ab50d93b078fa8a6b5c71567d670eb1960 Mon Sep 17 00:00:00 2001 From: Hugo Date: Thu, 21 Dec 2023 01:18:01 +0100 Subject: [PATCH 31/45] [github] Add new action checking PR age (#4386) --- .github/workflows/pr-timing-checker.yml | 48 +++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 .github/workflows/pr-timing-checker.yml diff --git a/.github/workflows/pr-timing-checker.yml b/.github/workflows/pr-timing-checker.yml new file mode 100644 index 00000000000..555d88ac2d8 --- /dev/null +++ b/.github/workflows/pr-timing-checker.yml @@ -0,0 +1,48 @@ +name: Check PR Age +on: + pull_request: + types: + - synchronize + - opened + - reopened + - labeled + - unlabeled + + +jobs: + + check_labels: + name: Check labels + runs-on: ubuntu-latest + steps: + - name: Check Labels and Age + id: check_labels_and_comment + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + // Get PR labels + const labels = context.payload.pull_request.labels.map(label => label.name); + + // Define the fast merge label + const fastMergeFlag = ['pr: fast merge']; + + // Check if any label fits fast merge + const isFastMerge = labels.some(label => fastMergeFlag.includes(label)); + + // If regular PR (not fast merge), check PR age + if (!isFastMerge) { + const creationDate = new Date(context.payload.pull_request.created_at); + const currentDate = new Date(); + + // Check if the PR is more than 7 days old + const daysDiff = Math.floor((currentDate - creationDate) / (1000 * 60 * 60 * 24)); + + if (daysDiff < 7) { + core.setFailed("PR is less than 7 days old and it is not flagged as 'pr: fast merge'"); + } else { + console.log('PR is more than 7 days old'); + } + } else { + console.log("PR is flagged as 'pr: fast merge'"); + } From 7140f1dab22b75346241a9c305c64192b913f408 Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Thu, 21 Dec 2023 01:26:51 +0100 Subject: [PATCH 32/45] [CImgPlugin] Add fetchable CImg and remove embedded cimg (#4357) * support interface-type for auto_target_properties install macro * try updating install macro * try updating install macro again * use (only) find_package for CImg * fix image compilation for newer version of cimg * remove cimg src * export mutex symbol with a .def file for windows * add comment * add fetchable cimg * fix packaging * fix image_gui * fix image_type comparison --------- Co-authored-by: erik pernod --- .../Config/cmake/SofaMacrosInstall.cmake | 1 + .../CImgPlugin/CImgPluginConfig.cmake.in | 2 + .../plugins/CImgPlugin/CMakeLists.txt | 45 +- .../plugins/CImgPlugin/cmake/FindCImg.cmake | 69 + applications/plugins/CImgPlugin/exports.def | 3 + .../plugins/CImgPlugin/extlibs/CImg/CImg.h | 56974 ----------- .../extlibs/CImg/CImgConfig.cmake.in | 8 - .../CImgPlugin/extlibs/CImg/CMakeLists.txt | 28 - .../extlibs/CImg/Licence_CeCILL-C_V1-en.txt | 508 - .../extlibs/CImg/Licence_CeCILL_V2-en.txt | 504 - .../CImgPlugin/extlibs/CImg/README.txt | 179 - .../extlibs/CImg/examples/CImg_demo.cpp | 1689 - .../extlibs/CImg/examples/CMakeLists.txt | 310 - .../CImgPlugin/extlibs/CImg/examples/Makefile | 667 - .../extlibs/CImg/examples/captcha.cpp | 163 - .../extlibs/CImg/examples/curve_editor2d.cpp | 356 - .../extlibs/CImg/examples/dtmri_view3d.cpp | 562 - .../extlibs/CImg/examples/edge_explorer2d.cpp | 218 - .../extlibs/CImg/examples/fade_images.cpp | 94 - .../extlibs/CImg/examples/gaussian_fit1d.cpp | 172 - .../CImg/examples/generate_loop_macros.cpp | 353 - .../CImg/examples/hough_transform2d.cpp | 146 - .../extlibs/CImg/examples/image2ascii.cpp | 157 - .../CImg/examples/image_registration2d.cpp | 216 - .../extlibs/CImg/examples/image_surface3d.cpp | 140 - .../extlibs/CImg/examples/img/CImg_demo.h | 27810 ------ .../extlibs/CImg/examples/img/logo.bmp | Bin 90534 -> 0 bytes .../extlibs/CImg/examples/img/milla.bmp | Bin 153966 -> 0 bytes .../extlibs/CImg/examples/img/odykill.h | 79162 ---------------- .../extlibs/CImg/examples/img/parrot.ppm | Bin 739676 -> 0 bytes .../extlibs/CImg/examples/img/parrot_mask.pgm | Bin 246569 -> 0 bytes .../extlibs/CImg/examples/img/sh0r.pgm | 256 - .../extlibs/CImg/examples/img/sh1r.pgm | 243 - .../extlibs/CImg/examples/img/tetris.h | 2313 - .../extlibs/CImg/examples/jawbreaker.cpp | 232 - .../extlibs/CImg/examples/mcf_levelsets2d.cpp | 120 - .../extlibs/CImg/examples/mcf_levelsets3d.cpp | 180 - .../extlibs/CImg/examples/odykill.cpp | 229 - .../examples/pde_TschumperleDeriche2d.cpp | 231 - .../extlibs/CImg/examples/pde_heatflow2d.cpp | 114 - .../extlibs/CImg/examples/plotter1d.cpp | 73 - .../CImg/examples/radon_transform2d.cpp | 379 - .../extlibs/CImg/examples/scene3d.cpp | 142 - .../CImg/examples/spherical_function3d.cpp | 113 - .../extlibs/CImg/examples/tetris.cpp | 208 - .../CImgPlugin/extlibs/CImg/examples/tron.cpp | 190 - .../extlibs/CImg/examples/tutorial.cpp | 133 - .../extlibs/CImg/examples/use_RGBclass.cpp | 138 - .../extlibs/CImg/examples/use_chlpca.cpp | 70 - .../extlibs/CImg/examples/use_cimgIPL.cpp | 155 - .../extlibs/CImg/examples/use_cimgmatlab.cpp | 102 - .../extlibs/CImg/examples/use_cimgmatlab.m | 33 - .../CImg/examples/use_draw_gradient.cpp | 138 - .../extlibs/CImg/examples/use_jpeg_buffer.cpp | 109 - .../extlibs/CImg/examples/use_nlmeans.cpp | 125 - .../extlibs/CImg/examples/use_patchmatch.cpp | 103 - .../extlibs/CImg/examples/use_skeleton.cpp | 119 - .../extlibs/CImg/examples/use_tiff_stream.cpp | 81 - .../CImg/examples/use_tinymatwriter.cpp | 135 - .../extlibs/CImg/examples/wavelet_atrous.cpp | 191 - .../extlibs/CImg/plugins/add_fileformat.h | 79 - .../CImgPlugin/extlibs/CImg/plugins/bayer.h | 212 - .../CImgPlugin/extlibs/CImg/plugins/chlpca.h | 322 - .../CImgPlugin/extlibs/CImg/plugins/cvMat.h | 350 - .../extlibs/CImg/plugins/draw_gradient.h | 269 - .../CImgPlugin/extlibs/CImg/plugins/inpaint.h | 500 - .../CImgPlugin/extlibs/CImg/plugins/ipl.h | 309 - .../CImgPlugin/extlibs/CImg/plugins/ipl_alt.h | 122 - .../extlibs/CImg/plugins/jpeg_buffer.h | 376 - .../extlibs/CImg/plugins/loop_macros.h | 24166 ----- .../CImgPlugin/extlibs/CImg/plugins/matlab.h | 287 - .../CImgPlugin/extlibs/CImg/plugins/nlmeans.h | 242 - .../extlibs/CImg/plugins/patchmatch.h | 227 - .../extlibs/CImg/plugins/skeleton.h | 587 - .../extlibs/CImg/plugins/tiff_stream.h | 192 - .../extlibs/CImg/plugins/tinymatwriter.h | 109 - .../CImgPlugin/extlibs/CImg/plugins/vrml.h | 894 - .../CImgPlugin/extlibs/CImg/plugins/vtk.h | 103 - .../CImg/resources/compile_win_icl.bat | 15 - .../CImg/resources/compile_win_visualcpp.bat | 15 - .../CImgPlugin/src/CImgPlugin/ImageCImg.cpp | 2 +- .../CImgPlugin/src/CImgPlugin/SOFACImg.h | 4 + .../src/CImgPlugin/initCImgPlugin.cpp | 6 +- .../image/ImageCoordValuesFromPositions.h | 6 +- applications/plugins/image/ImageFilter.h | 2 +- .../plugins/image/ImageValuesFromPositions.h | 2 +- .../plugins/image/image_gui/HistogramWidget.h | 2 +- 87 files changed, 128 insertions(+), 206463 deletions(-) create mode 100644 applications/plugins/CImgPlugin/cmake/FindCImg.cmake create mode 100644 applications/plugins/CImgPlugin/exports.def delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/CImg.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/CImgConfig.cmake.in delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/CMakeLists.txt delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/Licence_CeCILL-C_V1-en.txt delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/Licence_CeCILL_V2-en.txt delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/README.txt delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/CImg_demo.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/CMakeLists.txt delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/Makefile delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/captcha.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/curve_editor2d.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/dtmri_view3d.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/edge_explorer2d.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/fade_images.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/gaussian_fit1d.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/generate_loop_macros.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/hough_transform2d.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/image2ascii.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/image_registration2d.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/image_surface3d.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/img/CImg_demo.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/img/logo.bmp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/img/milla.bmp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/img/odykill.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/img/parrot.ppm delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/img/parrot_mask.pgm delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/img/sh0r.pgm delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/img/sh1r.pgm delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/img/tetris.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/jawbreaker.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/mcf_levelsets2d.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/mcf_levelsets3d.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/odykill.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/pde_TschumperleDeriche2d.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/pde_heatflow2d.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/plotter1d.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/radon_transform2d.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/scene3d.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/spherical_function3d.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/tetris.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/tron.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/tutorial.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/use_RGBclass.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/use_chlpca.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/use_cimgIPL.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/use_cimgmatlab.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/use_cimgmatlab.m delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/use_draw_gradient.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/use_jpeg_buffer.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/use_nlmeans.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/use_patchmatch.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/use_skeleton.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/use_tiff_stream.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/use_tinymatwriter.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/examples/wavelet_atrous.cpp delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/plugins/add_fileformat.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/plugins/bayer.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/plugins/chlpca.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/plugins/cvMat.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/plugins/draw_gradient.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/plugins/inpaint.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/plugins/ipl.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/plugins/ipl_alt.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/plugins/jpeg_buffer.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/plugins/loop_macros.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/plugins/matlab.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/plugins/nlmeans.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/plugins/patchmatch.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/plugins/skeleton.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/plugins/tiff_stream.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/plugins/tinymatwriter.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/plugins/vrml.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/plugins/vtk.h delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/resources/compile_win_icl.bat delete mode 100644 applications/plugins/CImgPlugin/extlibs/CImg/resources/compile_win_visualcpp.bat diff --git a/Sofa/framework/Config/cmake/SofaMacrosInstall.cmake b/Sofa/framework/Config/cmake/SofaMacrosInstall.cmake index eb7d22b0a0c..260765ae422 100644 --- a/Sofa/framework/Config/cmake/SofaMacrosInstall.cmake +++ b/Sofa/framework/Config/cmake/SofaMacrosInstall.cmake @@ -375,6 +375,7 @@ macro(sofa_auto_set_target_version) endif() set_target_properties(${target} PROPERTIES VERSION "${version}") endif() + set(${sofa_target_name_upper}_VERSION "${version}") set(PROJECT_VERSION "${version}") # warning: dangerous to touch this variable? endforeach() diff --git a/applications/plugins/CImgPlugin/CImgPluginConfig.cmake.in b/applications/plugins/CImgPlugin/CImgPluginConfig.cmake.in index 0222ce7c541..554b068ae16 100644 --- a/applications/plugins/CImgPlugin/CImgPluginConfig.cmake.in +++ b/applications/plugins/CImgPlugin/CImgPluginConfig.cmake.in @@ -10,6 +10,8 @@ set(CIMGPLUGIN_HAVE_ZLIB @CIMGPLUGIN_HAVE_ZLIB@) find_package(Sofa.Helper QUIET REQUIRED) find_package(Sofa.DefaultType QUIET REQUIRED) + +set(CImg_INCLUDE_DIRS "@CImg_INCLUDE_DIRS@") find_package(CImg QUIET REQUIRED) if(CIMGPLUGIN_HAVE_JPEG) diff --git a/applications/plugins/CImgPlugin/CMakeLists.txt b/applications/plugins/CImgPlugin/CMakeLists.txt index 9899625179c..608524b3f26 100644 --- a/applications/plugins/CImgPlugin/CMakeLists.txt +++ b/applications/plugins/CImgPlugin/CMakeLists.txt @@ -12,11 +12,35 @@ set(SOURCE_FILES src/CImgPlugin/initCImgPlugin.cpp ) -add_subdirectory(extlibs/CImg) - sofa_find_package(Sofa.Helper REQUIRED) sofa_find_package(Sofa.DefaultType REQUIRED) -sofa_find_package(CImg REQUIRED) + +# add FindCImg.cmake +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindCImg.cmake ${CMAKE_BINARY_DIR}/lib/cmake/FindCImg.cmake COPYONLY) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindCImg.cmake DESTINATION lib/cmake/${PROJECT_NAME} COMPONENT headers) + +sofa_find_package(CImg QUIET) + +if(NOT CImg_FOUND AND SOFA_ALLOW_FETCH_DEPENDENCIES) + message("CImgPlugin: DEPENDENCY CImg NOT FOUND. SOFA_ALLOW_FETCH_DEPENDENCIES is ON, fetching CImg...") + + include(FetchContent) + FetchContent_Declare(CImg + GIT_REPOSITORY https://github.com/GreycLab/CImg + GIT_TAG v.3.3.2 + ) + + FetchContent_GetProperties(CImg) + if(NOT CImg_POPULATED) + FetchContent_Populate(CImg) + + set(CIMG_H_DIR ${cimg_SOURCE_DIR}) + sofa_find_package(CImg REQUIRED) + endif() +elseif (NOT CImg_FOUND) + message(FATAL_ERROR "CImgPlugin: DEPENDENCY CImg NOT FOUND. SOFA_ALLOW_FETCH_DEPENDENCIES is OFF and thus cannot be fetched. Install cimg-dev, or enable SOFA_ALLOW_FETCH_DEPENDENCIES to fix this issue.") +endif() # OS X only: if the user installed its own JPEG/PNG lib (typically with homebrew/port), # it will allow to use those instead of those present in XCode's frameworks @@ -67,23 +91,34 @@ add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES}) target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC "$") target_compile_options(${PROJECT_NAME} PUBLIC ${CIMG_CFLAGS}) -target_link_libraries(${PROJECT_NAME} PUBLIC Sofa.Helper Sofa.DefaultType) +target_link_libraries(${PROJECT_NAME} PUBLIC Sofa.Helper Sofa.DefaultType ) +target_link_libraries(${PROJECT_NAME} INTERFACE CImg) target_link_libraries(${PROJECT_NAME} PUBLIC ${DEP_TARGETS}) if(SOFA_BUILD_RELEASE_PACKAGE OR CMAKE_SYSTEM_NAME STREQUAL Windows) sofa_install_libraries(TARGETS ${DEP_TARGETS}) endif() +if(MSVC) + target_link_options(${PROJECT_NAME} PRIVATE "/DEF:${CMAKE_CURRENT_SOURCE_DIR}/exports.def") +endif() + ## Install rules for the library; CMake package configurations files sofa_create_package_with_targets( PACKAGE_NAME ${PROJECT_NAME} PACKAGE_VERSION ${PROJECT_VERSION} - TARGETS ${PROJECT_NAME} AUTO_SET_TARGET_PROPERTIES + TARGETS ${PROJECT_NAME} CImg AUTO_SET_TARGET_PROPERTIES INCLUDE_SOURCE_DIR "src" INCLUDE_INSTALL_DIR "CImgPlugin" RELOCATABLE "plugins" ) +install(FILES + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindCImg.cmake" + DESTINATION lib/cmake/Modules + COMPONENT headers + ) + # Tests # If SOFA_BUILD_TESTS exists and is OFF, then these tests will be auto-disabled cmake_dependent_option(CIMGPLUGIN_BUILD_TESTS "Compile the automatic tests" ON "SOFA_BUILD_TESTS OR NOT DEFINED SOFA_BUILD_TESTS" OFF) diff --git a/applications/plugins/CImgPlugin/cmake/FindCImg.cmake b/applications/plugins/CImgPlugin/cmake/FindCImg.cmake new file mode 100644 index 00000000000..012a01f339a --- /dev/null +++ b/applications/plugins/CImgPlugin/cmake/FindCImg.cmake @@ -0,0 +1,69 @@ +#[=======================================================================[.rst: +FindCImg +------- + +Finds the CImg library. + +Imported Targets +^^^^^^^^^^^^^^^^ + +This module provides the following imported targets, if found: + +``CImg`` + The CImg library + +Result Variables +^^^^^^^^^^^^^^^^ + +This will define the following variables: + +``CImg_FOUND`` + True if the system has the CImg library. +``CImg_VERSION`` + The version of the CImg library which was found. +``CImg_INCLUDE_DIRS`` + Include directories needed to use CImg. + + +Cache Variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: + +``CImg_INCLUDE_DIR`` + The directory containing ``CImg.h``. + +#]=======================================================================] + +cmake_minimum_required(VERSION 3.9) + +find_path(CIMG_H_DIR + NAMES CImg.h + HINTS ${CMAKE_INSTALL_PREFIX} ${CIMG_DIR} + PATH_SUFFIXES include include/linux +) + +if(NOT CIMG_H_DIR) + set(CImg_FOUND FALSE) +else() + set(CImg_FOUND TRUE) + + set(CImg_INCLUDE_DIR ${CIMG_H_DIR} CACHE STRING "") + set(CImg_INCLUDE_DIRS ${CImg_INCLUDE_DIR}) + + file(READ "${CIMG_H_DIR}/CImg.h" header) + string(REGEX MATCH "#define cimg_version ([0-9a-zA-Z\.]+)" _ "${header}") + set(CImg_VERSION "${CMAKE_MATCH_1}") + + if(NOT TARGET CImg) + add_library(CImg INTERFACE) + endif() +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(CImg + FOUND_VAR CImg_FOUND + REQUIRED_VARS + CImg_INCLUDE_DIRS + VERSION_VAR CImg_VERSION +) diff --git a/applications/plugins/CImgPlugin/exports.def b/applications/plugins/CImgPlugin/exports.def new file mode 100644 index 00000000000..eec05dbba32 --- /dev/null +++ b/applications/plugins/CImgPlugin/exports.def @@ -0,0 +1,3 @@ +LIBRARY CIMGPLUGIN +EXPORTS + Mutex_attr @1 \ No newline at end of file diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/CImg.h b/applications/plugins/CImgPlugin/extlibs/CImg/CImg.h deleted file mode 100644 index dc6e62b3ec2..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/CImg.h +++ /dev/null @@ -1,56974 +0,0 @@ -/* - # - # File : CImg.h - # ( C++ header file ) - # - # Description : The C++ Template Image Processing Toolkit. - # This file is the main component of the CImg Library project. - # ( http://cimg.eu ) - # - # Project manager : David Tschumperle. - # ( http://tschumperle.users.greyc.fr/ ) - # - # A complete list of contributors is available in file 'README.txt' - # distributed within the CImg package. - # - # Licenses : This file is 'dual-licensed', you have to choose one - # of the two licenses below to apply. - # - # CeCILL-C - # The CeCILL-C license is close to the GNU LGPL. - # ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html ) - # - # or CeCILL v2.0 - # The CeCILL license is compatible with the GNU GPL. - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed either by the CeCILL or the CeCILL-C license - # under French law and abiding by the rules of distribution of free software. - # You can use, modify and or redistribute the software under the terms of - # the CeCILL or CeCILL-C licenses as circulated by CEA, CNRS and INRIA - # at the following URL: "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL and CeCILL-C licenses and that you accept its terms. - # -*/ - -// Set version number of the library. -#ifndef cimg_version -#define cimg_version 173 - -/*----------------------------------------------------------- - # - # Test and possibly auto-set CImg configuration variables - # and include required headers. - # - # If you find that the default configuration variables are - # not adapted to your system, you can override their values - # before including the header file "CImg.h" - # (use the #define directive). - # - ------------------------------------------------------------*/ - -// Include standard C++ headers. -// This is the minimal set of required headers to make CImg-based codes compile. -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Detect/configure OS variables. -// -// Define 'cimg_OS' to: '0' for an unknown OS (will try to minize library dependencies). -// '1' for a Unix-like OS (Linux, Solaris, BSD, MacOSX, Irix, ...). -// '2' for Microsoft Windows. -// (auto-detection is performed if 'cimg_OS' is not set by the user). -#ifndef cimg_OS -#if defined(unix) || defined(__unix) || defined(__unix__) \ - || defined(linux) || defined(__linux) || defined(__linux__) \ - || defined(sun) || defined(__sun) \ - || defined(BSD) || defined(__OpenBSD__) || defined(__NetBSD__) \ - || defined(__FreeBSD__) || defined (__DragonFly__) \ - || defined(sgi) || defined(__sgi) \ - || defined(__MACOSX__) || defined(__APPLE__) \ - || defined(__CYGWIN__) -#define cimg_OS 1 -#elif defined(_MSC_VER) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) \ - || defined(WIN64) || defined(_WIN64) || defined(__WIN64__) -#define cimg_OS 2 -#else -#define cimg_OS 0 -#endif -#elif !(cimg_OS==0 || cimg_OS==1 || cimg_OS==2) -#error CImg Library: Invalid configuration variable 'cimg_OS'. -#error (correct values are '0 = unknown OS', '1 = Unix-like OS', '2 = Microsoft Windows'). -#endif -#ifndef cimg_date -#define cimg_date __DATE__ -#endif -#ifndef cimg_time -#define cimg_time __TIME__ -#endif - -// Disable silly warnings on some Microsoft VC++ compilers. -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4127) -#pragma warning(disable:4244) -#pragma warning(disable:4311) -#pragma warning(disable:4312) -#pragma warning(disable:4512) -#pragma warning(disable:4571) -#pragma warning(disable:4640) -#pragma warning(disable:4706) -#pragma warning(disable:4710) -#pragma warning(disable:4800) -#pragma warning(disable:4804) -#pragma warning(disable:4820) -#pragma warning(disable:4996) -#define _CRT_SECURE_NO_DEPRECATE 1 -#define _CRT_SECURE_NO_WARNINGS 1 -#define _CRT_NONSTDC_NO_DEPRECATE 1 -#endif - -// Define correct string functions for each compiler and OS. -#if cimg_OS==2 && defined(_MSC_VER) -#define cimg_sscanf std::sscanf -#define cimg_sprintf std::sprintf -#define cimg_snprintf cimg::_snprintf -#define cimg_vsnprintf cimg::_vsnprintf -#else -#include -#if defined(__MACOSX__) || defined(__APPLE__) -#define cimg_sscanf cimg::_sscanf -#define cimg_sprintf cimg::_sprintf -#define cimg_snprintf cimg::_snprintf -#define cimg_vsnprintf cimg::_vsnprintf -#else -#define cimg_sscanf std::sscanf -#define cimg_sprintf std::sprintf -#define cimg_snprintf snprintf -#define cimg_vsnprintf vsnprintf -#endif -#endif - -// Include OS-specific headers. -#if cimg_OS==1 -#include -#include -#include -#include -#include -#include -#elif cimg_OS==2 -#ifndef std_fopen -#define std_fopen cimg::win_fopen -#endif -#ifndef NOMINMAX -#define NOMINMAX -#endif -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#ifndef _WIN32_IE -#define _WIN32_IE 0x0400 -#endif -#include -#include -#include -#endif - -// Look for C++11 features. -#if !defined(cimg_use_cpp11) && __cplusplus>201100 -#define cimg_use_cpp11 1 -#endif -#if defined(cimg_use_cpp11) && cimg_use_cpp11!=0 -#include -#include -#endif - -// Convenient macro to define pragma -#ifdef _MSC_VER_ -#define cimg_pragma(x) __pragma(x) -#else -#define cimg_pragma(x) _Pragma(#x) -#endif - -// Define own types 'cimg_long/ulong' and 'cimg_int64/uint64' to ensure portability. -// ( constrained to 'sizeof(cimg_ulong/cimg_long) = sizeof(void*)' and 'sizeof(cimg_int64/cimg_uint64)=8' ). -#if cimg_OS==2 -#define cimg_uint64 unsigned __int64 -#define cimg_int64 __int64 -#define cimg_ulong UINT_PTR -#define cimg_long INT_PTR -#else -#if UINTPTR_MAX==0xffffffff -#define cimg_uint64 unsigned long long -#define cimg_int64 long long -#else -#define cimg_uint64 unsigned long -#define cimg_int64 long -#endif -#define cimg_ulong unsigned long -#define cimg_long long -#endif - -// Configure filename separator. -// -// Filename separator is set by default to '/', except for Windows where it is '\'. -#ifndef cimg_file_separator -#if cimg_OS==2 -#define cimg_file_separator '\\' -#else -#define cimg_file_separator '/' -#endif -#endif - -// Configure verbosity of output messages. -// -// Define 'cimg_verbosity' to: '0' to hide library messages (quiet mode). -// '1' to output library messages on the console. -// '2' to output library messages on a basic dialog window (default behavior). -// '3' to do as '1' + add extra warnings (may slow down the code!). -// '4' to do as '2' + add extra warnings (may slow down the code!). -// -// Define 'cimg_strict_warnings' to replace warning messages by exception throwns. -// -// Define 'cimg_use_vt100' to allow output of color messages on VT100-compatible terminals. -#ifndef cimg_verbosity -#if cimg_OS==2 -#define cimg_verbosity 2 -#else -#define cimg_verbosity 1 -#endif -#elif !(cimg_verbosity==0 || cimg_verbosity==1 || cimg_verbosity==2 || cimg_verbosity==3 || cimg_verbosity==4) -#error CImg Library: Configuration variable 'cimg_verbosity' is badly defined. -#error (should be { 0=quiet | 1=console | 2=dialog | 3=console+warnings | 4=dialog+warnings }). -#endif - -// Configure display framework. -// -// Define 'cimg_display' to: '0' to disable display capabilities. -// '1' to use the X-Window framework (X11). -// '2' to use the Microsoft GDI32 framework. -#ifndef cimg_display -#if cimg_OS==0 -#define cimg_display 0 -#elif cimg_OS==1 -#define cimg_display 1 -#elif cimg_OS==2 -#define cimg_display 2 -#endif -#elif !(cimg_display==0 || cimg_display==1 || cimg_display==2) -#error CImg Library: Configuration variable 'cimg_display' is badly defined. -#error (should be { 0=none | 1=X-Window (X11) | 2=Microsoft GDI32 }). -#endif - -// Configure the 'abort' signal handler (does nothing by default). -// A typical signal handler can be defined in your own source like this: -// #define cimg_abort_test() if (is_abort) throw CImgAbortException("") -// -// where 'is_abort' is a boolean variable defined somewhere in your code and reachable in the method. -// 'cimg_abort_test2()' does the same but is called more often (in inner loops). -#if defined(cimg_abort_test) && defined(cimg_use_openmp) - -// Define abort macros to be used with OpenMP. -#ifndef cimg_abort_init -#define cimg_abort_init bool cimg_abort_go = true; cimg::unused(cimg_abort_go) -#endif -#ifndef cimg_abort_try -#define cimg_abort_try if (cimg_abort_go) try -#endif -#ifndef cimg_abort_catch -#define cimg_abort_catch() catch (...) { cimg_pragma(omp atomic) cimg_abort_go&=false; } -#endif -#ifdef cimg_abort_test2 -#ifndef cimg_abort_try2 -#define cimg_abort_try2 cimg_abort_try -#endif -#ifndef cimg_abort_catch2 -#define cimg_abort_catch2() cimg_abort_catch() -#endif -#endif - -#endif - -#ifndef cimg_abort_test -#define cimg_abort_test() -#endif -#ifndef cimg_abort_test2 -#define cimg_abort_test2() -#endif -#ifndef cimg_abort_init -#define cimg_abort_init -#endif -#ifndef cimg_abort_try -#define cimg_abort_try -#endif -#ifndef cimg_abort_catch -#define cimg_abort_catch() -#endif -#ifndef cimg_abort_try2 -#define cimg_abort_try2 -#endif -#ifndef cimg_abort_catch2 -#define cimg_abort_catch2() -#endif -#ifndef std_fopen -#define std_fopen std::fopen -#endif - -// Include display-specific headers. -#if cimg_display==1 -#include -#include -#include -#include -#ifdef cimg_use_xshm -#include -#include -#include -#endif -#ifdef cimg_use_xrandr -#include -#endif -#endif -#ifndef cimg_appname -#define cimg_appname "CImg" -#endif - -// Configure OpenMP support. -// (http://www.openmp.org) -// -// Define 'cimg_use_openmp' to enable OpenMP support. -// -// OpenMP directives may be used in a (very) few CImg functions to get -// advantages of multi-core CPUs. -#ifdef cimg_use_openmp -#include -#define cimg_pragma_openmp(p) cimg_pragma(omp p) -#else -#define cimg_pragma_openmp(p) -#endif - -// Configure OpenCV support. -// (http://opencv.willowgarage.com/wiki/) -// -// Define 'cimg_use_opencv' to enable OpenCV support. -// -// OpenCV library may be used to access images from cameras -// (see method 'CImg::load_camera()'). -#ifdef cimg_use_opencv -#ifdef True -#undef True -#define _cimg_redefine_True -#endif -#ifdef False -#undef False -#define _cimg_redefine_False -#endif -#include -#include "cv.h" -#include "highgui.h" -#endif - -// Configure LibPNG support. -// (http://www.libpng.org) -// -// Define 'cimg_use_png' to enable LibPNG support. -// -// PNG library may be used to get a native support of '.png' files. -// (see methods 'CImg::{load,save}_png()'. -#ifdef cimg_use_png -extern "C" { -#include "png.h" -} -#endif - -// Configure LibJPEG support. -// (http://en.wikipedia.org/wiki/Libjpeg) -// -// Define 'cimg_use_jpeg' to enable LibJPEG support. -// -// JPEG library may be used to get a native support of '.jpg' files. -// (see methods 'CImg::{load,save}_jpeg()'). -#ifdef cimg_use_jpeg -extern "C" { -#include "jpeglib.h" -#include "setjmp.h" -} -#endif - -// Configure LibTIFF support. -// (http://www.libtiff.org) -// -// Define 'cimg_use_tiff' to enable LibTIFF support. -// -// TIFF library may be used to get a native support of '.tif' files. -// (see methods 'CImg[List]::{load,save}_tiff()'). -#ifdef cimg_use_tiff -extern "C" { -#define uint64 uint64_hack_ -#define int64 int64_hack_ -#include "tiffio.h" -#undef uint64 -#undef int64 -} -#endif - -// Configure LibMINC2 support. -// (http://en.wikibooks.org/wiki/MINC/Reference/MINC2.0_File_Format_Reference) -// -// Define 'cimg_use_minc2' to enable LibMINC2 support. -// -// MINC2 library may be used to get a native support of '.mnc' files. -// (see methods 'CImg::{load,save}_minc2()'). -#ifdef cimg_use_minc2 -#include "minc_io_simple_volume.h" -#include "minc_1_simple.h" -#include "minc_1_simple_rw.h" -#endif - -// Configure Zlib support. -// (http://www.zlib.net) -// -// Define 'cimg_use_zlib' to enable Zlib support. -// -// Zlib library may be used to allow compressed data in '.cimgz' files -// (see methods 'CImg[List]::{load,save}_cimg()'). -#ifdef cimg_use_zlib -extern "C" { -#include "zlib.h" -} -#endif - -// Configure libcurl support. -// (http://curl.haxx.se/libcurl/) -// -// Define 'cimg_use_curl' to enable libcurl support. -// -// Libcurl may be used to get a native support of file downloading from the network. -// (see method 'cimg::load_network()'.) -#ifdef cimg_use_curl -#include "curl/curl.h" -#endif - -// Configure Magick++ support. -// (http://www.imagemagick.org/Magick++) -// -// Define 'cimg_use_magick' to enable Magick++ support. -// -// Magick++ library may be used to get a native support of various image file formats. -// (see methods 'CImg::{load,save}()'). -#ifdef cimg_use_magick -#include "Magick++.h" -#endif - -// Configure FFTW3 support. -// (http://www.fftw.org) -// -// Define 'cimg_use_fftw3' to enable libFFTW3 support. -// -// FFTW3 library may be used to efficiently compute the Fast Fourier Transform -// of image data, without restriction on the image size. -// (see method 'CImg[List]::FFT()'). -#ifdef cimg_use_fftw3 -extern "C" { -#include "fftw3.h" -} -#endif - -// Configure LibBoard support. -// (http://libboard.sourceforge.net/) -// -// Define 'cimg_use_board' to enable Board support. -// -// Board library may be used to draw 3d objects in vector-graphics canvas -// that can be saved as '.ps' or '.svg' files afterwards. -// (see method 'CImg::draw_object3d()'). -#ifdef cimg_use_board -#ifdef None -#undef None -#define _cimg_redefine_None -#endif -#include "Board.h" -#endif - -// Configure OpenEXR support. -// (http://www.openexr.com/) -// -// Define 'cimg_use_openexr' to enable OpenEXR support. -// -// OpenEXR library may be used to get a native support of '.exr' files. -// (see methods 'CImg::{load,save}_exr()'). -#ifdef cimg_use_openexr -#include "ImfRgbaFile.h" -#include "ImfInputFile.h" -#include "ImfChannelList.h" -#include "ImfMatrixAttribute.h" -#include "ImfArray.h" -#endif - -// Lapack configuration. -// (http://www.netlib.org/lapack) -// -// Define 'cimg_use_lapack' to enable LAPACK support. -// -// Lapack library may be used in several CImg methods to speed up -// matrix computations (eigenvalues, inverse, ...). -#ifdef cimg_use_lapack -extern "C" { - extern void sgetrf_(int*, int*, float*, int*, int*, int*); - extern void sgetri_(int*, float*, int*, int*, float*, int*, int*); - extern void sgetrs_(char*, int*, int*, float*, int*, int*, float*, int*, int*); - extern void sgesvd_(char*, char*, int*, int*, float*, int*, float*, float*, int*, float*, int*, float*, int*, int*); - extern void ssyev_(char*, char*, int*, float*, int*, float*, float*, int*, int*); - extern void dgetrf_(int*, int*, double*, int*, int*, int*); - extern void dgetri_(int*, double*, int*, int*, double*, int*, int*); - extern void dgetrs_(char*, int*, int*, double*, int*, int*, double*, int*, int*); - extern void dgesvd_(char*, char*, int*, int*, double*, int*, double*, double*, - int*, double*, int*, double*, int*, int*); - extern void dsyev_(char*, char*, int*, double*, int*, double*, double*, int*, int*); - extern void dgels_(char*, int*,int*,int*,double*,int*,double*,int*,double*,int*,int*); - extern void sgels_(char*, int*,int*,int*,float*,int*,float*,int*,float*,int*,int*); -} -#endif - -// Check if min/max/PI macros are defined. -// -// CImg does not compile if macros 'min', 'max' or 'PI' are defined, -// because it redefines functions min(), max() and const variable PI in the cimg:: namespace. -// so it '#undef' these macros if necessary, and restore them to reasonable -// values at the end of this file. -#ifdef min -#undef min -#define _cimg_redefine_min -#endif -#ifdef max -#undef max -#define _cimg_redefine_max -#endif -#ifdef PI -#undef PI -#define _cimg_redefine_PI -#endif - -// Define 'cimg_library' namespace suffix. -// -// You may want to add a suffix to the 'cimg_library' namespace, for instance if you need to work -// with several versions of the library at the same time. -#ifdef cimg_namespace_suffix -#define __cimg_library_suffixed(s) cimg_library_##s -#define _cimg_library_suffixed(s) __cimg_library_suffixed(s) -#define cimg_library_suffixed _cimg_library_suffixed(cimg_namespace_suffix) -#else -#define cimg_library_suffixed cimg_library -#endif - -/*------------------------------------------------------------------------------ - # - # Define user-friendly macros. - # - # These CImg macros are prefixed by 'cimg_' and can be used safely in your own - # code. They are useful to parse command line options, or to write image loops. - # - ------------------------------------------------------------------------------*/ - -// Macros to define program usage, and retrieve command line arguments. -#define cimg_usage(usage) cimg_library_suffixed::cimg::option((char*)0,argc,argv,(char*)0,usage,false) -#define cimg_help(str) cimg_library_suffixed::cimg::option((char*)0,argc,argv,str,(char*)0) -#define cimg_option(name,defaut,usage) cimg_library_suffixed::cimg::option(name,argc,argv,defaut,usage) - -// Macros to define and manipulate local neighborhoods. -#define CImg_2x2(I,T) T I[4]; \ - T& I##cc = I[0]; T& I##nc = I[1]; \ - T& I##cn = I[2]; T& I##nn = I[3]; \ - I##cc = I##nc = \ - I##cn = I##nn = 0 - -#define CImg_3x3(I,T) T I[9]; \ - T& I##pp = I[0]; T& I##cp = I[1]; T& I##np = I[2]; \ - T& I##pc = I[3]; T& I##cc = I[4]; T& I##nc = I[5]; \ - T& I##pn = I[6]; T& I##cn = I[7]; T& I##nn = I[8]; \ - I##pp = I##cp = I##np = \ - I##pc = I##cc = I##nc = \ - I##pn = I##cn = I##nn = 0 - -#define CImg_4x4(I,T) T I[16]; \ - T& I##pp = I[0]; T& I##cp = I[1]; T& I##np = I[2]; T& I##ap = I[3]; \ - T& I##pc = I[4]; T& I##cc = I[5]; T& I##nc = I[6]; T& I##ac = I[7]; \ - T& I##pn = I[8]; T& I##cn = I[9]; T& I##nn = I[10]; T& I##an = I[11]; \ - T& I##pa = I[12]; T& I##ca = I[13]; T& I##na = I[14]; T& I##aa = I[15]; \ - I##pp = I##cp = I##np = I##ap = \ - I##pc = I##cc = I##nc = I##ac = \ - I##pn = I##cn = I##nn = I##an = \ - I##pa = I##ca = I##na = I##aa = 0 - -#define CImg_5x5(I,T) T I[25]; \ - T& I##bb = I[0]; T& I##pb = I[1]; T& I##cb = I[2]; T& I##nb = I[3]; T& I##ab = I[4]; \ - T& I##bp = I[5]; T& I##pp = I[6]; T& I##cp = I[7]; T& I##np = I[8]; T& I##ap = I[9]; \ - T& I##bc = I[10]; T& I##pc = I[11]; T& I##cc = I[12]; T& I##nc = I[13]; T& I##ac = I[14]; \ - T& I##bn = I[15]; T& I##pn = I[16]; T& I##cn = I[17]; T& I##nn = I[18]; T& I##an = I[19]; \ - T& I##ba = I[20]; T& I##pa = I[21]; T& I##ca = I[22]; T& I##na = I[23]; T& I##aa = I[24]; \ - I##bb = I##pb = I##cb = I##nb = I##ab = \ - I##bp = I##pp = I##cp = I##np = I##ap = \ - I##bc = I##pc = I##cc = I##nc = I##ac = \ - I##bn = I##pn = I##cn = I##nn = I##an = \ - I##ba = I##pa = I##ca = I##na = I##aa = 0 - -#define CImg_2x2x2(I,T) T I[8]; \ - T& I##ccc = I[0]; T& I##ncc = I[1]; \ - T& I##cnc = I[2]; T& I##nnc = I[3]; \ - T& I##ccn = I[4]; T& I##ncn = I[5]; \ - T& I##cnn = I[6]; T& I##nnn = I[7]; \ - I##ccc = I##ncc = \ - I##cnc = I##nnc = \ - I##ccn = I##ncn = \ - I##cnn = I##nnn = 0 - -#define CImg_3x3x3(I,T) T I[27]; \ - T& I##ppp = I[0]; T& I##cpp = I[1]; T& I##npp = I[2]; \ - T& I##pcp = I[3]; T& I##ccp = I[4]; T& I##ncp = I[5]; \ - T& I##pnp = I[6]; T& I##cnp = I[7]; T& I##nnp = I[8]; \ - T& I##ppc = I[9]; T& I##cpc = I[10]; T& I##npc = I[11]; \ - T& I##pcc = I[12]; T& I##ccc = I[13]; T& I##ncc = I[14]; \ - T& I##pnc = I[15]; T& I##cnc = I[16]; T& I##nnc = I[17]; \ - T& I##ppn = I[18]; T& I##cpn = I[19]; T& I##npn = I[20]; \ - T& I##pcn = I[21]; T& I##ccn = I[22]; T& I##ncn = I[23]; \ - T& I##pnn = I[24]; T& I##cnn = I[25]; T& I##nnn = I[26]; \ - I##ppp = I##cpp = I##npp = \ - I##pcp = I##ccp = I##ncp = \ - I##pnp = I##cnp = I##nnp = \ - I##ppc = I##cpc = I##npc = \ - I##pcc = I##ccc = I##ncc = \ - I##pnc = I##cnc = I##nnc = \ - I##ppn = I##cpn = I##npn = \ - I##pcn = I##ccn = I##ncn = \ - I##pnn = I##cnn = I##nnn = 0 - -#define cimg_get2x2(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(x,y,z,c), I[1] = (T)(img)(_n1##x,y,z,c), I[2] = (T)(img)(x,_n1##y,z,c), \ - I[3] = (T)(img)(_n1##x,_n1##y,z,c) - -#define cimg_get3x3(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p1##x,_p1##y,z,c), I[1] = (T)(img)(x,_p1##y,z,c), I[2] = (T)(img)(_n1##x,_p1##y,z,c), \ - I[3] = (T)(img)(_p1##x,y,z,c), I[4] = (T)(img)(x,y,z,c), I[5] = (T)(img)(_n1##x,y,z,c), \ - I[6] = (T)(img)(_p1##x,_n1##y,z,c), I[7] = (T)(img)(x,_n1##y,z,c), I[8] = (T)(img)(_n1##x,_n1##y,z,c) - -#define cimg_get4x4(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p1##x,_p1##y,z,c), I[1] = (T)(img)(x,_p1##y,z,c), I[2] = (T)(img)(_n1##x,_p1##y,z,c), \ - I[3] = (T)(img)(_n2##x,_p1##y,z,c), I[4] = (T)(img)(_p1##x,y,z,c), I[5] = (T)(img)(x,y,z,c), \ - I[6] = (T)(img)(_n1##x,y,z,c), I[7] = (T)(img)(_n2##x,y,z,c), I[8] = (T)(img)(_p1##x,_n1##y,z,c), \ - I[9] = (T)(img)(x,_n1##y,z,c), I[10] = (T)(img)(_n1##x,_n1##y,z,c), I[11] = (T)(img)(_n2##x,_n1##y,z,c), \ - I[12] = (T)(img)(_p1##x,_n2##y,z,c), I[13] = (T)(img)(x,_n2##y,z,c), I[14] = (T)(img)(_n1##x,_n2##y,z,c), \ - I[15] = (T)(img)(_n2##x,_n2##y,z,c) - -#define cimg_get5x5(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p2##x,_p2##y,z,c), I[1] = (T)(img)(_p1##x,_p2##y,z,c), I[2] = (T)(img)(x,_p2##y,z,c), \ - I[3] = (T)(img)(_n1##x,_p2##y,z,c), I[4] = (T)(img)(_n2##x,_p2##y,z,c), I[5] = (T)(img)(_p2##x,_p1##y,z,c), \ - I[6] = (T)(img)(_p1##x,_p1##y,z,c), I[7] = (T)(img)(x,_p1##y,z,c), I[8] = (T)(img)(_n1##x,_p1##y,z,c), \ - I[9] = (T)(img)(_n2##x,_p1##y,z,c), I[10] = (T)(img)(_p2##x,y,z,c), I[11] = (T)(img)(_p1##x,y,z,c), \ - I[12] = (T)(img)(x,y,z,c), I[13] = (T)(img)(_n1##x,y,z,c), I[14] = (T)(img)(_n2##x,y,z,c), \ - I[15] = (T)(img)(_p2##x,_n1##y,z,c), I[16] = (T)(img)(_p1##x,_n1##y,z,c), I[17] = (T)(img)(x,_n1##y,z,c), \ - I[18] = (T)(img)(_n1##x,_n1##y,z,c), I[19] = (T)(img)(_n2##x,_n1##y,z,c), I[20] = (T)(img)(_p2##x,_n2##y,z,c), \ - I[21] = (T)(img)(_p1##x,_n2##y,z,c), I[22] = (T)(img)(x,_n2##y,z,c), I[23] = (T)(img)(_n1##x,_n2##y,z,c), \ - I[24] = (T)(img)(_n2##x,_n2##y,z,c) - -#define cimg_get6x6(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p2##x,_p2##y,z,c), I[1] = (T)(img)(_p1##x,_p2##y,z,c), I[2] = (T)(img)(x,_p2##y,z,c), \ - I[3] = (T)(img)(_n1##x,_p2##y,z,c), I[4] = (T)(img)(_n2##x,_p2##y,z,c), I[5] = (T)(img)(_n3##x,_p2##y,z,c), \ - I[6] = (T)(img)(_p2##x,_p1##y,z,c), I[7] = (T)(img)(_p1##x,_p1##y,z,c), I[8] = (T)(img)(x,_p1##y,z,c), \ - I[9] = (T)(img)(_n1##x,_p1##y,z,c), I[10] = (T)(img)(_n2##x,_p1##y,z,c), I[11] = (T)(img)(_n3##x,_p1##y,z,c), \ - I[12] = (T)(img)(_p2##x,y,z,c), I[13] = (T)(img)(_p1##x,y,z,c), I[14] = (T)(img)(x,y,z,c), \ - I[15] = (T)(img)(_n1##x,y,z,c), I[16] = (T)(img)(_n2##x,y,z,c), I[17] = (T)(img)(_n3##x,y,z,c), \ - I[18] = (T)(img)(_p2##x,_n1##y,z,c), I[19] = (T)(img)(_p1##x,_n1##y,z,c), I[20] = (T)(img)(x,_n1##y,z,c), \ - I[21] = (T)(img)(_n1##x,_n1##y,z,c), I[22] = (T)(img)(_n2##x,_n1##y,z,c), I[23] = (T)(img)(_n3##x,_n1##y,z,c), \ - I[24] = (T)(img)(_p2##x,_n2##y,z,c), I[25] = (T)(img)(_p1##x,_n2##y,z,c), I[26] = (T)(img)(x,_n2##y,z,c), \ - I[27] = (T)(img)(_n1##x,_n2##y,z,c), I[28] = (T)(img)(_n2##x,_n2##y,z,c), I[29] = (T)(img)(_n3##x,_n2##y,z,c), \ - I[30] = (T)(img)(_p2##x,_n3##y,z,c), I[31] = (T)(img)(_p1##x,_n3##y,z,c), I[32] = (T)(img)(x,_n3##y,z,c), \ - I[33] = (T)(img)(_n1##x,_n3##y,z,c), I[34] = (T)(img)(_n2##x,_n3##y,z,c), I[35] = (T)(img)(_n3##x,_n3##y,z,c) - -#define cimg_get7x7(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p3##x,_p3##y,z,c), I[1] = (T)(img)(_p2##x,_p3##y,z,c), I[2] = (T)(img)(_p1##x,_p3##y,z,c), \ - I[3] = (T)(img)(x,_p3##y,z,c), I[4] = (T)(img)(_n1##x,_p3##y,z,c), I[5] = (T)(img)(_n2##x,_p3##y,z,c), \ - I[6] = (T)(img)(_n3##x,_p3##y,z,c), I[7] = (T)(img)(_p3##x,_p2##y,z,c), I[8] = (T)(img)(_p2##x,_p2##y,z,c), \ - I[9] = (T)(img)(_p1##x,_p2##y,z,c), I[10] = (T)(img)(x,_p2##y,z,c), I[11] = (T)(img)(_n1##x,_p2##y,z,c), \ - I[12] = (T)(img)(_n2##x,_p2##y,z,c), I[13] = (T)(img)(_n3##x,_p2##y,z,c), I[14] = (T)(img)(_p3##x,_p1##y,z,c), \ - I[15] = (T)(img)(_p2##x,_p1##y,z,c), I[16] = (T)(img)(_p1##x,_p1##y,z,c), I[17] = (T)(img)(x,_p1##y,z,c), \ - I[18] = (T)(img)(_n1##x,_p1##y,z,c), I[19] = (T)(img)(_n2##x,_p1##y,z,c), I[20] = (T)(img)(_n3##x,_p1##y,z,c), \ - I[21] = (T)(img)(_p3##x,y,z,c), I[22] = (T)(img)(_p2##x,y,z,c), I[23] = (T)(img)(_p1##x,y,z,c), \ - I[24] = (T)(img)(x,y,z,c), I[25] = (T)(img)(_n1##x,y,z,c), I[26] = (T)(img)(_n2##x,y,z,c), \ - I[27] = (T)(img)(_n3##x,y,z,c), I[28] = (T)(img)(_p3##x,_n1##y,z,c), I[29] = (T)(img)(_p2##x,_n1##y,z,c), \ - I[30] = (T)(img)(_p1##x,_n1##y,z,c), I[31] = (T)(img)(x,_n1##y,z,c), I[32] = (T)(img)(_n1##x,_n1##y,z,c), \ - I[33] = (T)(img)(_n2##x,_n1##y,z,c), I[34] = (T)(img)(_n3##x,_n1##y,z,c), I[35] = (T)(img)(_p3##x,_n2##y,z,c), \ - I[36] = (T)(img)(_p2##x,_n2##y,z,c), I[37] = (T)(img)(_p1##x,_n2##y,z,c), I[38] = (T)(img)(x,_n2##y,z,c), \ - I[39] = (T)(img)(_n1##x,_n2##y,z,c), I[40] = (T)(img)(_n2##x,_n2##y,z,c), I[41] = (T)(img)(_n3##x,_n2##y,z,c), \ - I[42] = (T)(img)(_p3##x,_n3##y,z,c), I[43] = (T)(img)(_p2##x,_n3##y,z,c), I[44] = (T)(img)(_p1##x,_n3##y,z,c), \ - I[45] = (T)(img)(x,_n3##y,z,c), I[46] = (T)(img)(_n1##x,_n3##y,z,c), I[47] = (T)(img)(_n2##x,_n3##y,z,c), \ - I[48] = (T)(img)(_n3##x,_n3##y,z,c) - -#define cimg_get8x8(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p3##x,_p3##y,z,c), I[1] = (T)(img)(_p2##x,_p3##y,z,c), I[2] = (T)(img)(_p1##x,_p3##y,z,c), \ - I[3] = (T)(img)(x,_p3##y,z,c), I[4] = (T)(img)(_n1##x,_p3##y,z,c), I[5] = (T)(img)(_n2##x,_p3##y,z,c), \ - I[6] = (T)(img)(_n3##x,_p3##y,z,c), I[7] = (T)(img)(_n4##x,_p3##y,z,c), I[8] = (T)(img)(_p3##x,_p2##y,z,c), \ - I[9] = (T)(img)(_p2##x,_p2##y,z,c), I[10] = (T)(img)(_p1##x,_p2##y,z,c), I[11] = (T)(img)(x,_p2##y,z,c), \ - I[12] = (T)(img)(_n1##x,_p2##y,z,c), I[13] = (T)(img)(_n2##x,_p2##y,z,c), I[14] = (T)(img)(_n3##x,_p2##y,z,c), \ - I[15] = (T)(img)(_n4##x,_p2##y,z,c), I[16] = (T)(img)(_p3##x,_p1##y,z,c), I[17] = (T)(img)(_p2##x,_p1##y,z,c), \ - I[18] = (T)(img)(_p1##x,_p1##y,z,c), I[19] = (T)(img)(x,_p1##y,z,c), I[20] = (T)(img)(_n1##x,_p1##y,z,c), \ - I[21] = (T)(img)(_n2##x,_p1##y,z,c), I[22] = (T)(img)(_n3##x,_p1##y,z,c), I[23] = (T)(img)(_n4##x,_p1##y,z,c), \ - I[24] = (T)(img)(_p3##x,y,z,c), I[25] = (T)(img)(_p2##x,y,z,c), I[26] = (T)(img)(_p1##x,y,z,c), \ - I[27] = (T)(img)(x,y,z,c), I[28] = (T)(img)(_n1##x,y,z,c), I[29] = (T)(img)(_n2##x,y,z,c), \ - I[30] = (T)(img)(_n3##x,y,z,c), I[31] = (T)(img)(_n4##x,y,z,c), I[32] = (T)(img)(_p3##x,_n1##y,z,c), \ - I[33] = (T)(img)(_p2##x,_n1##y,z,c), I[34] = (T)(img)(_p1##x,_n1##y,z,c), I[35] = (T)(img)(x,_n1##y,z,c), \ - I[36] = (T)(img)(_n1##x,_n1##y,z,c), I[37] = (T)(img)(_n2##x,_n1##y,z,c), I[38] = (T)(img)(_n3##x,_n1##y,z,c), \ - I[39] = (T)(img)(_n4##x,_n1##y,z,c), I[40] = (T)(img)(_p3##x,_n2##y,z,c), I[41] = (T)(img)(_p2##x,_n2##y,z,c), \ - I[42] = (T)(img)(_p1##x,_n2##y,z,c), I[43] = (T)(img)(x,_n2##y,z,c), I[44] = (T)(img)(_n1##x,_n2##y,z,c), \ - I[45] = (T)(img)(_n2##x,_n2##y,z,c), I[46] = (T)(img)(_n3##x,_n2##y,z,c), I[47] = (T)(img)(_n4##x,_n2##y,z,c), \ - I[48] = (T)(img)(_p3##x,_n3##y,z,c), I[49] = (T)(img)(_p2##x,_n3##y,z,c), I[50] = (T)(img)(_p1##x,_n3##y,z,c), \ - I[51] = (T)(img)(x,_n3##y,z,c), I[52] = (T)(img)(_n1##x,_n3##y,z,c), I[53] = (T)(img)(_n2##x,_n3##y,z,c), \ - I[54] = (T)(img)(_n3##x,_n3##y,z,c), I[55] = (T)(img)(_n4##x,_n3##y,z,c), I[56] = (T)(img)(_p3##x,_n4##y,z,c), \ - I[57] = (T)(img)(_p2##x,_n4##y,z,c), I[58] = (T)(img)(_p1##x,_n4##y,z,c), I[59] = (T)(img)(x,_n4##y,z,c), \ - I[60] = (T)(img)(_n1##x,_n4##y,z,c), I[61] = (T)(img)(_n2##x,_n4##y,z,c), I[62] = (T)(img)(_n3##x,_n4##y,z,c), \ - I[63] = (T)(img)(_n4##x,_n4##y,z,c); - -#define cimg_get9x9(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p4##x,_p4##y,z,c), I[1] = (T)(img)(_p3##x,_p4##y,z,c), I[2] = (T)(img)(_p2##x,_p4##y,z,c), \ - I[3] = (T)(img)(_p1##x,_p4##y,z,c), I[4] = (T)(img)(x,_p4##y,z,c), I[5] = (T)(img)(_n1##x,_p4##y,z,c), \ - I[6] = (T)(img)(_n2##x,_p4##y,z,c), I[7] = (T)(img)(_n3##x,_p4##y,z,c), I[8] = (T)(img)(_n4##x,_p4##y,z,c), \ - I[9] = (T)(img)(_p4##x,_p3##y,z,c), I[10] = (T)(img)(_p3##x,_p3##y,z,c), I[11] = (T)(img)(_p2##x,_p3##y,z,c), \ - I[12] = (T)(img)(_p1##x,_p3##y,z,c), I[13] = (T)(img)(x,_p3##y,z,c), I[14] = (T)(img)(_n1##x,_p3##y,z,c), \ - I[15] = (T)(img)(_n2##x,_p3##y,z,c), I[16] = (T)(img)(_n3##x,_p3##y,z,c), I[17] = (T)(img)(_n4##x,_p3##y,z,c), \ - I[18] = (T)(img)(_p4##x,_p2##y,z,c), I[19] = (T)(img)(_p3##x,_p2##y,z,c), I[20] = (T)(img)(_p2##x,_p2##y,z,c), \ - I[21] = (T)(img)(_p1##x,_p2##y,z,c), I[22] = (T)(img)(x,_p2##y,z,c), I[23] = (T)(img)(_n1##x,_p2##y,z,c), \ - I[24] = (T)(img)(_n2##x,_p2##y,z,c), I[25] = (T)(img)(_n3##x,_p2##y,z,c), I[26] = (T)(img)(_n4##x,_p2##y,z,c), \ - I[27] = (T)(img)(_p4##x,_p1##y,z,c), I[28] = (T)(img)(_p3##x,_p1##y,z,c), I[29] = (T)(img)(_p2##x,_p1##y,z,c), \ - I[30] = (T)(img)(_p1##x,_p1##y,z,c), I[31] = (T)(img)(x,_p1##y,z,c), I[32] = (T)(img)(_n1##x,_p1##y,z,c), \ - I[33] = (T)(img)(_n2##x,_p1##y,z,c), I[34] = (T)(img)(_n3##x,_p1##y,z,c), I[35] = (T)(img)(_n4##x,_p1##y,z,c), \ - I[36] = (T)(img)(_p4##x,y,z,c), I[37] = (T)(img)(_p3##x,y,z,c), I[38] = (T)(img)(_p2##x,y,z,c), \ - I[39] = (T)(img)(_p1##x,y,z,c), I[40] = (T)(img)(x,y,z,c), I[41] = (T)(img)(_n1##x,y,z,c), \ - I[42] = (T)(img)(_n2##x,y,z,c), I[43] = (T)(img)(_n3##x,y,z,c), I[44] = (T)(img)(_n4##x,y,z,c), \ - I[45] = (T)(img)(_p4##x,_n1##y,z,c), I[46] = (T)(img)(_p3##x,_n1##y,z,c), I[47] = (T)(img)(_p2##x,_n1##y,z,c), \ - I[48] = (T)(img)(_p1##x,_n1##y,z,c), I[49] = (T)(img)(x,_n1##y,z,c), I[50] = (T)(img)(_n1##x,_n1##y,z,c), \ - I[51] = (T)(img)(_n2##x,_n1##y,z,c), I[52] = (T)(img)(_n3##x,_n1##y,z,c), I[53] = (T)(img)(_n4##x,_n1##y,z,c), \ - I[54] = (T)(img)(_p4##x,_n2##y,z,c), I[55] = (T)(img)(_p3##x,_n2##y,z,c), I[56] = (T)(img)(_p2##x,_n2##y,z,c), \ - I[57] = (T)(img)(_p1##x,_n2##y,z,c), I[58] = (T)(img)(x,_n2##y,z,c), I[59] = (T)(img)(_n1##x,_n2##y,z,c), \ - I[60] = (T)(img)(_n2##x,_n2##y,z,c), I[61] = (T)(img)(_n3##x,_n2##y,z,c), I[62] = (T)(img)(_n4##x,_n2##y,z,c), \ - I[63] = (T)(img)(_p4##x,_n3##y,z,c), I[64] = (T)(img)(_p3##x,_n3##y,z,c), I[65] = (T)(img)(_p2##x,_n3##y,z,c), \ - I[66] = (T)(img)(_p1##x,_n3##y,z,c), I[67] = (T)(img)(x,_n3##y,z,c), I[68] = (T)(img)(_n1##x,_n3##y,z,c), \ - I[69] = (T)(img)(_n2##x,_n3##y,z,c), I[70] = (T)(img)(_n3##x,_n3##y,z,c), I[71] = (T)(img)(_n4##x,_n3##y,z,c), \ - I[72] = (T)(img)(_p4##x,_n4##y,z,c), I[73] = (T)(img)(_p3##x,_n4##y,z,c), I[74] = (T)(img)(_p2##x,_n4##y,z,c), \ - I[75] = (T)(img)(_p1##x,_n4##y,z,c), I[76] = (T)(img)(x,_n4##y,z,c), I[77] = (T)(img)(_n1##x,_n4##y,z,c), \ - I[78] = (T)(img)(_n2##x,_n4##y,z,c), I[79] = (T)(img)(_n3##x,_n4##y,z,c), I[80] = (T)(img)(_n4##x,_n4##y,z,c) - -#define cimg_get2x2x2(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(x,y,z,c), I[1] = (T)(img)(_n1##x,y,z,c), I[2] = (T)(img)(x,_n1##y,z,c), \ - I[3] = (T)(img)(_n1##x,_n1##y,z,c), I[4] = (T)(img)(x,y,_n1##z,c), I[5] = (T)(img)(_n1##x,y,_n1##z,c), \ - I[6] = (T)(img)(x,_n1##y,_n1##z,c), I[7] = (T)(img)(_n1##x,_n1##y,_n1##z,c) - -#define cimg_get3x3x3(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p1##x,_p1##y,_p1##z,c), I[1] = (T)(img)(x,_p1##y,_p1##z,c), \ - I[2] = (T)(img)(_n1##x,_p1##y,_p1##z,c), I[3] = (T)(img)(_p1##x,y,_p1##z,c), I[4] = (T)(img)(x,y,_p1##z,c), \ - I[5] = (T)(img)(_n1##x,y,_p1##z,c), I[6] = (T)(img)(_p1##x,_n1##y,_p1##z,c), I[7] = (T)(img)(x,_n1##y,_p1##z,c), \ - I[8] = (T)(img)(_n1##x,_n1##y,_p1##z,c), I[9] = (T)(img)(_p1##x,_p1##y,z,c), I[10] = (T)(img)(x,_p1##y,z,c), \ - I[11] = (T)(img)(_n1##x,_p1##y,z,c), I[12] = (T)(img)(_p1##x,y,z,c), I[13] = (T)(img)(x,y,z,c), \ - I[14] = (T)(img)(_n1##x,y,z,c), I[15] = (T)(img)(_p1##x,_n1##y,z,c), I[16] = (T)(img)(x,_n1##y,z,c), \ - I[17] = (T)(img)(_n1##x,_n1##y,z,c), I[18] = (T)(img)(_p1##x,_p1##y,_n1##z,c), I[19] = (T)(img)(x,_p1##y,_n1##z,c), \ - I[20] = (T)(img)(_n1##x,_p1##y,_n1##z,c), I[21] = (T)(img)(_p1##x,y,_n1##z,c), I[22] = (T)(img)(x,y,_n1##z,c), \ - I[23] = (T)(img)(_n1##x,y,_n1##z,c), I[24] = (T)(img)(_p1##x,_n1##y,_n1##z,c), I[25] = (T)(img)(x,_n1##y,_n1##z,c), \ - I[26] = (T)(img)(_n1##x,_n1##y,_n1##z,c) - -// Macros to perform various image loops. -// -// These macros are simpler to use than loops with C++ iterators. -#define cimg_for(img,ptrs,T_ptrs) \ - for (T_ptrs *ptrs = (img)._data, *_max##ptrs = (img)._data + (img).size(); ptrs<_max##ptrs; ++ptrs) -#define cimg_rof(img,ptrs,T_ptrs) for (T_ptrs *ptrs = (img)._data + (img).size() - 1; ptrs>=(img)._data; --ptrs) -#define cimg_foroff(img,off) for (cimg_ulong off = 0, _max##off = (img).size(); off<_max##off; ++off) - -#define cimg_for1(bound,i) for (int i = 0; i<(int)(bound); ++i) -#define cimg_forX(img,x) cimg_for1((img)._width,x) -#define cimg_forY(img,y) cimg_for1((img)._height,y) -#define cimg_forZ(img,z) cimg_for1((img)._depth,z) -#define cimg_forC(img,c) cimg_for1((img)._spectrum,c) -#define cimg_forXY(img,x,y) cimg_forY(img,y) cimg_forX(img,x) -#define cimg_forXZ(img,x,z) cimg_forZ(img,z) cimg_forX(img,x) -#define cimg_forYZ(img,y,z) cimg_forZ(img,z) cimg_forY(img,y) -#define cimg_forXC(img,x,c) cimg_forC(img,c) cimg_forX(img,x) -#define cimg_forYC(img,y,c) cimg_forC(img,c) cimg_forY(img,y) -#define cimg_forZC(img,z,c) cimg_forC(img,c) cimg_forZ(img,z) -#define cimg_forXYZ(img,x,y,z) cimg_forZ(img,z) cimg_forXY(img,x,y) -#define cimg_forXYC(img,x,y,c) cimg_forC(img,c) cimg_forXY(img,x,y) -#define cimg_forXZC(img,x,z,c) cimg_forC(img,c) cimg_forXZ(img,x,z) -#define cimg_forYZC(img,y,z,c) cimg_forC(img,c) cimg_forYZ(img,y,z) -#define cimg_forXYZC(img,x,y,z,c) cimg_forC(img,c) cimg_forXYZ(img,x,y,z) - -#define cimg_rof1(bound,i) for (int i = (int)(bound) - 1; i>=0; --i) -#define cimg_rofX(img,x) cimg_rof1((img)._width,x) -#define cimg_rofY(img,y) cimg_rof1((img)._height,y) -#define cimg_rofZ(img,z) cimg_rof1((img)._depth,z) -#define cimg_rofC(img,c) cimg_rof1((img)._spectrum,c) -#define cimg_rofXY(img,x,y) cimg_rofY(img,y) cimg_rofX(img,x) -#define cimg_rofXZ(img,x,z) cimg_rofZ(img,z) cimg_rofX(img,x) -#define cimg_rofYZ(img,y,z) cimg_rofZ(img,z) cimg_rofY(img,y) -#define cimg_rofXC(img,x,c) cimg_rofC(img,c) cimg_rofX(img,x) -#define cimg_rofYC(img,y,c) cimg_rofC(img,c) cimg_rofY(img,y) -#define cimg_rofZC(img,z,c) cimg_rofC(img,c) cimg_rofZ(img,z) -#define cimg_rofXYZ(img,x,y,z) cimg_rofZ(img,z) cimg_rofXY(img,x,y) -#define cimg_rofXYC(img,x,y,c) cimg_rofC(img,c) cimg_rofXY(img,x,y) -#define cimg_rofXZC(img,x,z,c) cimg_rofC(img,c) cimg_rofXZ(img,x,z) -#define cimg_rofYZC(img,y,z,c) cimg_rofC(img,c) cimg_rofYZ(img,y,z) -#define cimg_rofXYZC(img,x,y,z,c) cimg_rofC(img,c) cimg_rofXYZ(img,x,y,z) - -#define cimg_for_in1(bound,i0,i1,i) \ - for (int i = (int)(i0)<0?0:(int)(i0), _max##i = (int)(i1)<(int)(bound)?(int)(i1):(int)(bound) - 1; i<=_max##i; ++i) -#define cimg_for_inX(img,x0,x1,x) cimg_for_in1((img)._width,x0,x1,x) -#define cimg_for_inY(img,y0,y1,y) cimg_for_in1((img)._height,y0,y1,y) -#define cimg_for_inZ(img,z0,z1,z) cimg_for_in1((img)._depth,z0,z1,z) -#define cimg_for_inC(img,c0,c1,c) cimg_for_in1((img)._spectrum,c0,c1,c) -#define cimg_for_inXY(img,x0,y0,x1,y1,x,y) cimg_for_inY(img,y0,y1,y) cimg_for_inX(img,x0,x1,x) -#define cimg_for_inXZ(img,x0,z0,x1,z1,x,z) cimg_for_inZ(img,z0,z1,z) cimg_for_inX(img,x0,x1,x) -#define cimg_for_inXC(img,x0,c0,x1,c1,x,c) cimg_for_inC(img,c0,c1,c) cimg_for_inX(img,x0,x1,x) -#define cimg_for_inYZ(img,y0,z0,y1,z1,y,z) cimg_for_inZ(img,x0,z1,z) cimg_for_inY(img,y0,y1,y) -#define cimg_for_inYC(img,y0,c0,y1,c1,y,c) cimg_for_inC(img,c0,c1,c) cimg_for_inY(img,y0,y1,y) -#define cimg_for_inZC(img,z0,c0,z1,c1,z,c) cimg_for_inC(img,c0,c1,c) cimg_for_inZ(img,z0,z1,z) -#define cimg_for_inXYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_inZ(img,z0,z1,z) cimg_for_inXY(img,x0,y0,x1,y1,x,y) -#define cimg_for_inXYC(img,x0,y0,c0,x1,y1,c1,x,y,c) cimg_for_inC(img,c0,c1,c) cimg_for_inXY(img,x0,y0,x1,y1,x,y) -#define cimg_for_inXZC(img,x0,z0,c0,x1,z1,c1,x,z,c) cimg_for_inC(img,c0,c1,c) cimg_for_inXZ(img,x0,z0,x1,z1,x,z) -#define cimg_for_inYZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_inC(img,c0,c1,c) cimg_for_inYZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_inXYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) \ - cimg_for_inC(img,c0,c1,c) cimg_for_inXYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) -#define cimg_for_insideX(img,x,n) cimg_for_inX(img,n,(img)._width - 1 - (n),x) -#define cimg_for_insideY(img,y,n) cimg_for_inY(img,n,(img)._height - 1 - (n),y) -#define cimg_for_insideZ(img,z,n) cimg_for_inZ(img,n,(img)._depth - 1 - (n),z) -#define cimg_for_insideC(img,c,n) cimg_for_inC(img,n,(img)._spectrum - 1 - (n),c) -#define cimg_for_insideXY(img,x,y,n) cimg_for_inXY(img,n,n,(img)._width - 1 - (n),(img)._height - 1 - (n),x,y) -#define cimg_for_insideXYZ(img,x,y,z,n) \ - cimg_for_inXYZ(img,n,n,n,(img)._width - 1 - (n),(img)._height - 1 - (n),(img)._depth - 1 - (n),x,y,z) -#define cimg_for_insideXYZC(img,x,y,z,c,n) \ - cimg_for_inXYZ(img,n,n,n,(img)._width - 1 - (n),(img)._height - 1 - (n),(img)._depth - 1 - (n),x,y,z) - -#define cimg_for_out1(boundi,i0,i1,i) \ - for (int i = (int)(i0)>0?0:(int)(i1) + 1; i<(int)(boundi); ++i, i = i==(int)(i0)?(int)(i1) + 1:i) -#define cimg_for_out2(boundi,boundj,i0,j0,i1,j1,i,j) \ - for (int j = 0; j<(int)(boundj); ++j) \ - for (int _n1j = (int)(j<(int)(j0) || j>(int)(j1)), i = _n1j?0:(int)(i0)>0?0:(int)(i1) + 1; i<(int)(boundi); \ - ++i, i = _n1j?i:(i==(int)(i0)?(int)(i1) + 1:i)) -#define cimg_for_out3(boundi,boundj,boundk,i0,j0,k0,i1,j1,k1,i,j,k) \ - for (int k = 0; k<(int)(boundk); ++k) \ - for (int _n1k = (int)(k<(int)(k0) || k>(int)(k1)), j = 0; j<(int)(boundj); ++j) \ - for (int _n1j = (int)(j<(int)(j0) || j>(int)(j1)), i = _n1j || _n1k?0:(int)(i0)>0?0:(int)(i1) + 1; i<(int)(boundi); \ - ++i, i = _n1j || _n1k?i:(i==(int)(i0)?(int)(i1) + 1:i)) -#define cimg_for_out4(boundi,boundj,boundk,boundl,i0,j0,k0,l0,i1,j1,k1,l1,i,j,k,l) \ - for (int l = 0; l<(int)(boundl); ++l) \ - for (int _n1l = (int)(l<(int)(l0) || l>(int)(l1)), k = 0; k<(int)(boundk); ++k) \ - for (int _n1k = (int)(k<(int)(k0) || k>(int)(k1)), j = 0; j<(int)(boundj); ++j) \ - for (int _n1j = (int)(j<(int)(j0) || j>(int)(j1)), i = _n1j || _n1k || _n1l?0:(int)(i0)>0?0:(int)(i1) + 1; \ - i<(int)(boundi); ++i, i = _n1j || _n1k || _n1l?i:(i==(int)(i0)?(int)(i1) + 1:i)) -#define cimg_for_outX(img,x0,x1,x) cimg_for_out1((img)._width,x0,x1,x) -#define cimg_for_outY(img,y0,y1,y) cimg_for_out1((img)._height,y0,y1,y) -#define cimg_for_outZ(img,z0,z1,z) cimg_for_out1((img)._depth,z0,z1,z) -#define cimg_for_outC(img,c0,c1,c) cimg_for_out1((img)._spectrum,c0,c1,c) -#define cimg_for_outXY(img,x0,y0,x1,y1,x,y) cimg_for_out2((img)._width,(img)._height,x0,y0,x1,y1,x,y) -#define cimg_for_outXZ(img,x0,z0,x1,z1,x,z) cimg_for_out2((img)._width,(img)._depth,x0,z0,x1,z1,x,z) -#define cimg_for_outXC(img,x0,c0,x1,c1,x,c) cimg_for_out2((img)._width,(img)._spectrum,x0,c0,x1,c1,x,c) -#define cimg_for_outYZ(img,y0,z0,y1,z1,y,z) cimg_for_out2((img)._height,(img)._depth,y0,z0,y1,z1,y,z) -#define cimg_for_outYC(img,y0,c0,y1,c1,y,c) cimg_for_out2((img)._height,(img)._spectrum,y0,c0,y1,c1,y,c) -#define cimg_for_outZC(img,z0,c0,z1,c1,z,c) cimg_for_out2((img)._depth,(img)._spectrum,z0,c0,z1,c1,z,c) -#define cimg_for_outXYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) \ - cimg_for_out3((img)._width,(img)._height,(img)._depth,x0,y0,z0,x1,y1,z1,x,y,z) -#define cimg_for_outXYC(img,x0,y0,c0,x1,y1,c1,x,y,c) \ - cimg_for_out3((img)._width,(img)._height,(img)._spectrum,x0,y0,c0,x1,y1,c1,x,y,c) -#define cimg_for_outXZC(img,x0,z0,c0,x1,z1,c1,x,z,c) \ - cimg_for_out3((img)._width,(img)._depth,(img)._spectrum,x0,z0,c0,x1,z1,c1,x,z,c) -#define cimg_for_outYZC(img,y0,z0,c0,y1,z1,c1,y,z,c) \ - cimg_for_out3((img)._height,(img)._depth,(img)._spectrum,y0,z0,c0,y1,z1,c1,y,z,c) -#define cimg_for_outXYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) \ - cimg_for_out4((img)._width,(img)._height,(img)._depth,(img)._spectrum,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) -#define cimg_for_borderX(img,x,n) cimg_for_outX(img,n,(img)._width - 1 - (n),x) -#define cimg_for_borderY(img,y,n) cimg_for_outY(img,n,(img)._height - 1 - (n),y) -#define cimg_for_borderZ(img,z,n) cimg_for_outZ(img,n,(img)._depth - 1 - (n),z) -#define cimg_for_borderC(img,c,n) cimg_for_outC(img,n,(img)._spectrum - 1 - (n),c) -#define cimg_for_borderXY(img,x,y,n) cimg_for_outXY(img,n,n,(img)._width - 1 - (n),(img)._height - 1 - (n),x,y) -#define cimg_for_borderXYZ(img,x,y,z,n) \ - cimg_for_outXYZ(img,n,n,n,(img)._width - 1 - (n),(img)._height - 1 - (n),(img)._depth - 1 - (n),x,y,z) -#define cimg_for_borderXYZC(img,x,y,z,c,n) \ - cimg_for_outXYZC(img,n,n,n,n,(img)._width - 1 - (n),(img)._height - 1 - (n), \ - (img)._depth - 1 - (n),(img)._spectrum - 1 - (n),x,y,z,c) - -#define cimg_for_spiralXY(img,x,y) \ - for (int x = 0, y = 0, _n1##x = 1, _n1##y = (img).width()*(img).height(); _n1##y; \ - --_n1##y, _n1##x+=(_n1##x>>2) - ((!(_n1##x&3)?--y:((_n1##x&3)==1?(img)._width - 1 - ++x:\ - ((_n1##x&3)==2?(img)._height - 1 - ++y:--x))))?0:1) - -#define cimg_for_lineXY(x,y,x0,y0,x1,y1) \ - for (int x = (int)(x0), y = (int)(y0), _sx = 1, _sy = 1, _steep = 0, \ - _dx=(x1)>(x0)?(int)(x1) - (int)(x0):(_sx=-1,(int)(x0) - (int)(x1)), \ - _dy=(y1)>(y0)?(int)(y1) - (int)(y0):(_sy=-1,(int)(y0) - (int)(y1)), \ - _counter = _dx, \ - _err = _dx>_dy?(_dy>>1):((_steep=1),(_counter=_dy),(_dx>>1)); \ - _counter>=0; \ - --_counter, x+=_steep? \ - (y+=_sy,(_err-=_dx)<0?_err+=_dy,_sx:0): \ - (y+=(_err-=_dy)<0?_err+=_dx,_sy:0,_sx)) - -#define cimg_for2(bound,i) \ - for (int i = 0, _n1##i = 1>=(bound)?(int)(bound) - 1:1; \ - _n1##i<(int)(bound) || i==--_n1##i; \ - ++i, ++_n1##i) -#define cimg_for2X(img,x) cimg_for2((img)._width,x) -#define cimg_for2Y(img,y) cimg_for2((img)._height,y) -#define cimg_for2Z(img,z) cimg_for2((img)._depth,z) -#define cimg_for2C(img,c) cimg_for2((img)._spectrum,c) -#define cimg_for2XY(img,x,y) cimg_for2Y(img,y) cimg_for2X(img,x) -#define cimg_for2XZ(img,x,z) cimg_for2Z(img,z) cimg_for2X(img,x) -#define cimg_for2XC(img,x,c) cimg_for2C(img,c) cimg_for2X(img,x) -#define cimg_for2YZ(img,y,z) cimg_for2Z(img,z) cimg_for2Y(img,y) -#define cimg_for2YC(img,y,c) cimg_for2C(img,c) cimg_for2Y(img,y) -#define cimg_for2ZC(img,z,c) cimg_for2C(img,c) cimg_for2Z(img,z) -#define cimg_for2XYZ(img,x,y,z) cimg_for2Z(img,z) cimg_for2XY(img,x,y) -#define cimg_for2XZC(img,x,z,c) cimg_for2C(img,c) cimg_for2XZ(img,x,z) -#define cimg_for2YZC(img,y,z,c) cimg_for2C(img,c) cimg_for2YZ(img,y,z) -#define cimg_for2XYZC(img,x,y,z,c) cimg_for2C(img,c) cimg_for2XYZ(img,x,y,z) - -#define cimg_for_in2(bound,i0,i1,i) \ - for (int i = (int)(i0)<0?0:(int)(i0), \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1; \ - i<=(int)(i1) && (_n1##i<(int)(bound) || i==--_n1##i); \ - ++i, ++_n1##i) -#define cimg_for_in2X(img,x0,x1,x) cimg_for_in2((img)._width,x0,x1,x) -#define cimg_for_in2Y(img,y0,y1,y) cimg_for_in2((img)._height,y0,y1,y) -#define cimg_for_in2Z(img,z0,z1,z) cimg_for_in2((img)._depth,z0,z1,z) -#define cimg_for_in2C(img,c0,c1,c) cimg_for_in2((img)._spectrum,c0,c1,c) -#define cimg_for_in2XY(img,x0,y0,x1,y1,x,y) cimg_for_in2Y(img,y0,y1,y) cimg_for_in2X(img,x0,x1,x) -#define cimg_for_in2XZ(img,x0,z0,x1,z1,x,z) cimg_for_in2Z(img,z0,z1,z) cimg_for_in2X(img,x0,x1,x) -#define cimg_for_in2XC(img,x0,c0,x1,c1,x,c) cimg_for_in2C(img,c0,c1,c) cimg_for_in2X(img,x0,x1,x) -#define cimg_for_in2YZ(img,y0,z0,y1,z1,y,z) cimg_for_in2Z(img,z0,z1,z) cimg_for_in2Y(img,y0,y1,y) -#define cimg_for_in2YC(img,y0,c0,y1,c1,y,c) cimg_for_in2C(img,c0,c1,c) cimg_for_in2Y(img,y0,y1,y) -#define cimg_for_in2ZC(img,z0,c0,z1,c1,z,c) cimg_for_in2C(img,c0,c1,c) cimg_for_in2Z(img,z0,z1,z) -#define cimg_for_in2XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in2Z(img,z0,z1,z) cimg_for_in2XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in2XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in2C(img,c0,c1,c) cimg_for_in2XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in2YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in2C(img,c0,c1,c) cimg_for_in2YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in2XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) \ - cimg_for_in2C(img,c0,c1,c) cimg_for_in2XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for3(bound,i) \ - for (int i = 0, _p1##i = 0, \ - _n1##i = 1>=(bound)?(int)(bound) - 1:1; \ - _n1##i<(int)(bound) || i==--_n1##i; \ - _p1##i = i++, ++_n1##i) -#define cimg_for3X(img,x) cimg_for3((img)._width,x) -#define cimg_for3Y(img,y) cimg_for3((img)._height,y) -#define cimg_for3Z(img,z) cimg_for3((img)._depth,z) -#define cimg_for3C(img,c) cimg_for3((img)._spectrum,c) -#define cimg_for3XY(img,x,y) cimg_for3Y(img,y) cimg_for3X(img,x) -#define cimg_for3XZ(img,x,z) cimg_for3Z(img,z) cimg_for3X(img,x) -#define cimg_for3XC(img,x,c) cimg_for3C(img,c) cimg_for3X(img,x) -#define cimg_for3YZ(img,y,z) cimg_for3Z(img,z) cimg_for3Y(img,y) -#define cimg_for3YC(img,y,c) cimg_for3C(img,c) cimg_for3Y(img,y) -#define cimg_for3ZC(img,z,c) cimg_for3C(img,c) cimg_for3Z(img,z) -#define cimg_for3XYZ(img,x,y,z) cimg_for3Z(img,z) cimg_for3XY(img,x,y) -#define cimg_for3XZC(img,x,z,c) cimg_for3C(img,c) cimg_for3XZ(img,x,z) -#define cimg_for3YZC(img,y,z,c) cimg_for3C(img,c) cimg_for3YZ(img,y,z) -#define cimg_for3XYZC(img,x,y,z,c) cimg_for3C(img,c) cimg_for3XYZ(img,x,y,z) - -#define cimg_for_in3(bound,i0,i1,i) \ - for (int i = (int)(i0)<0?0:(int)(i0), \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1; \ - i<=(int)(i1) && (_n1##i<(int)(bound) || i==--_n1##i); \ - _p1##i = i++, ++_n1##i) -#define cimg_for_in3X(img,x0,x1,x) cimg_for_in3((img)._width,x0,x1,x) -#define cimg_for_in3Y(img,y0,y1,y) cimg_for_in3((img)._height,y0,y1,y) -#define cimg_for_in3Z(img,z0,z1,z) cimg_for_in3((img)._depth,z0,z1,z) -#define cimg_for_in3C(img,c0,c1,c) cimg_for_in3((img)._spectrum,c0,c1,c) -#define cimg_for_in3XY(img,x0,y0,x1,y1,x,y) cimg_for_in3Y(img,y0,y1,y) cimg_for_in3X(img,x0,x1,x) -#define cimg_for_in3XZ(img,x0,z0,x1,z1,x,z) cimg_for_in3Z(img,z0,z1,z) cimg_for_in3X(img,x0,x1,x) -#define cimg_for_in3XC(img,x0,c0,x1,c1,x,c) cimg_for_in3C(img,c0,c1,c) cimg_for_in3X(img,x0,x1,x) -#define cimg_for_in3YZ(img,y0,z0,y1,z1,y,z) cimg_for_in3Z(img,z0,z1,z) cimg_for_in3Y(img,y0,y1,y) -#define cimg_for_in3YC(img,y0,c0,y1,c1,y,c) cimg_for_in3C(img,c0,c1,c) cimg_for_in3Y(img,y0,y1,y) -#define cimg_for_in3ZC(img,z0,c0,z1,c1,z,c) cimg_for_in3C(img,c0,c1,c) cimg_for_in3Z(img,z0,z1,z) -#define cimg_for_in3XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in3Z(img,z0,z1,z) cimg_for_in3XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in3XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in3C(img,c0,c1,c) cimg_for_in3XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in3YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in3C(img,c0,c1,c) cimg_for_in3YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in3XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) \ - cimg_for_in3C(img,c0,c1,c) cimg_for_in3XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for4(bound,i) \ - for (int i = 0, _p1##i = 0, _n1##i = 1>=(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(bound)?(int)(bound) - 1:2; \ - _n2##i<(int)(bound) || _n1##i==--_n2##i || i==(_n2##i = --_n1##i); \ - _p1##i = i++, ++_n1##i, ++_n2##i) -#define cimg_for4X(img,x) cimg_for4((img)._width,x) -#define cimg_for4Y(img,y) cimg_for4((img)._height,y) -#define cimg_for4Z(img,z) cimg_for4((img)._depth,z) -#define cimg_for4C(img,c) cimg_for4((img)._spectrum,c) -#define cimg_for4XY(img,x,y) cimg_for4Y(img,y) cimg_for4X(img,x) -#define cimg_for4XZ(img,x,z) cimg_for4Z(img,z) cimg_for4X(img,x) -#define cimg_for4XC(img,x,c) cimg_for4C(img,c) cimg_for4X(img,x) -#define cimg_for4YZ(img,y,z) cimg_for4Z(img,z) cimg_for4Y(img,y) -#define cimg_for4YC(img,y,c) cimg_for4C(img,c) cimg_for4Y(img,y) -#define cimg_for4ZC(img,z,c) cimg_for4C(img,c) cimg_for4Z(img,z) -#define cimg_for4XYZ(img,x,y,z) cimg_for4Z(img,z) cimg_for4XY(img,x,y) -#define cimg_for4XZC(img,x,z,c) cimg_for4C(img,c) cimg_for4XZ(img,x,z) -#define cimg_for4YZC(img,y,z,c) cimg_for4C(img,c) cimg_for4YZ(img,y,z) -#define cimg_for4XYZC(img,x,y,z,c) cimg_for4C(img,c) cimg_for4XYZ(img,x,y,z) - -#define cimg_for_in4(bound,i0,i1,i) \ - for (int i = (int)(i0)<0?0:(int)(i0), \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2; \ - i<=(int)(i1) && (_n2##i<(int)(bound) || _n1##i==--_n2##i || i==(_n2##i = --_n1##i)); \ - _p1##i = i++, ++_n1##i, ++_n2##i) -#define cimg_for_in4X(img,x0,x1,x) cimg_for_in4((img)._width,x0,x1,x) -#define cimg_for_in4Y(img,y0,y1,y) cimg_for_in4((img)._height,y0,y1,y) -#define cimg_for_in4Z(img,z0,z1,z) cimg_for_in4((img)._depth,z0,z1,z) -#define cimg_for_in4C(img,c0,c1,c) cimg_for_in4((img)._spectrum,c0,c1,c) -#define cimg_for_in4XY(img,x0,y0,x1,y1,x,y) cimg_for_in4Y(img,y0,y1,y) cimg_for_in4X(img,x0,x1,x) -#define cimg_for_in4XZ(img,x0,z0,x1,z1,x,z) cimg_for_in4Z(img,z0,z1,z) cimg_for_in4X(img,x0,x1,x) -#define cimg_for_in4XC(img,x0,c0,x1,c1,x,c) cimg_for_in4C(img,c0,c1,c) cimg_for_in4X(img,x0,x1,x) -#define cimg_for_in4YZ(img,y0,z0,y1,z1,y,z) cimg_for_in4Z(img,z0,z1,z) cimg_for_in4Y(img,y0,y1,y) -#define cimg_for_in4YC(img,y0,c0,y1,c1,y,c) cimg_for_in4C(img,c0,c1,c) cimg_for_in4Y(img,y0,y1,y) -#define cimg_for_in4ZC(img,z0,c0,z1,c1,z,c) cimg_for_in4C(img,c0,c1,c) cimg_for_in4Z(img,z0,z1,z) -#define cimg_for_in4XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in4Z(img,z0,z1,z) cimg_for_in4XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in4XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in4C(img,c0,c1,c) cimg_for_in4XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in4YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in4C(img,c0,c1,c) cimg_for_in4YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in4XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) \ - cimg_for_in4C(img,c0,c1,c) cimg_for_in4XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for5(bound,i) \ - for (int i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(bound)?(int)(bound) - 1:2; \ - _n2##i<(int)(bound) || _n1##i==--_n2##i || i==(_n2##i = --_n1##i); \ - _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i) -#define cimg_for5X(img,x) cimg_for5((img)._width,x) -#define cimg_for5Y(img,y) cimg_for5((img)._height,y) -#define cimg_for5Z(img,z) cimg_for5((img)._depth,z) -#define cimg_for5C(img,c) cimg_for5((img)._spectrum,c) -#define cimg_for5XY(img,x,y) cimg_for5Y(img,y) cimg_for5X(img,x) -#define cimg_for5XZ(img,x,z) cimg_for5Z(img,z) cimg_for5X(img,x) -#define cimg_for5XC(img,x,c) cimg_for5C(img,c) cimg_for5X(img,x) -#define cimg_for5YZ(img,y,z) cimg_for5Z(img,z) cimg_for5Y(img,y) -#define cimg_for5YC(img,y,c) cimg_for5C(img,c) cimg_for5Y(img,y) -#define cimg_for5ZC(img,z,c) cimg_for5C(img,c) cimg_for5Z(img,z) -#define cimg_for5XYZ(img,x,y,z) cimg_for5Z(img,z) cimg_for5XY(img,x,y) -#define cimg_for5XZC(img,x,z,c) cimg_for5C(img,c) cimg_for5XZ(img,x,z) -#define cimg_for5YZC(img,y,z,c) cimg_for5C(img,c) cimg_for5YZ(img,y,z) -#define cimg_for5XYZC(img,x,y,z,c) cimg_for5C(img,c) cimg_for5XYZ(img,x,y,z) - -#define cimg_for_in5(bound,i0,i1,i) \ - for (int i = (int)(i0)<0?0:(int)(i0), \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2; \ - i<=(int)(i1) && (_n2##i<(int)(bound) || _n1##i==--_n2##i || i==(_n2##i = --_n1##i)); \ - _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i) -#define cimg_for_in5X(img,x0,x1,x) cimg_for_in5((img)._width,x0,x1,x) -#define cimg_for_in5Y(img,y0,y1,y) cimg_for_in5((img)._height,y0,y1,y) -#define cimg_for_in5Z(img,z0,z1,z) cimg_for_in5((img)._depth,z0,z1,z) -#define cimg_for_in5C(img,c0,c1,c) cimg_for_in5((img)._spectrum,c0,c1,c) -#define cimg_for_in5XY(img,x0,y0,x1,y1,x,y) cimg_for_in5Y(img,y0,y1,y) cimg_for_in5X(img,x0,x1,x) -#define cimg_for_in5XZ(img,x0,z0,x1,z1,x,z) cimg_for_in5Z(img,z0,z1,z) cimg_for_in5X(img,x0,x1,x) -#define cimg_for_in5XC(img,x0,c0,x1,c1,x,c) cimg_for_in5C(img,c0,c1,c) cimg_for_in5X(img,x0,x1,x) -#define cimg_for_in5YZ(img,y0,z0,y1,z1,y,z) cimg_for_in5Z(img,z0,z1,z) cimg_for_in5Y(img,y0,y1,y) -#define cimg_for_in5YC(img,y0,c0,y1,c1,y,c) cimg_for_in5C(img,c0,c1,c) cimg_for_in5Y(img,y0,y1,y) -#define cimg_for_in5ZC(img,z0,c0,z1,c1,z,c) cimg_for_in5C(img,c0,c1,c) cimg_for_in5Z(img,z0,z1,z) -#define cimg_for_in5XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in5Z(img,z0,z1,z) cimg_for_in5XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in5XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in5C(img,c0,c1,c) cimg_for_in5XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in5YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in5C(img,c0,c1,c) cimg_for_in5YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in5XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) \ - cimg_for_in5C(img,c0,c1,c) cimg_for_in5XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for6(bound,i) \ - for (int i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(bound)?(int)(bound) - 1:3; \ - _n3##i<(int)(bound) || _n2##i==--_n3##i || _n1##i==--_n2##i || i==(_n3##i = _n2##i = --_n1##i); \ - _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i) -#define cimg_for6X(img,x) cimg_for6((img)._width,x) -#define cimg_for6Y(img,y) cimg_for6((img)._height,y) -#define cimg_for6Z(img,z) cimg_for6((img)._depth,z) -#define cimg_for6C(img,c) cimg_for6((img)._spectrum,c) -#define cimg_for6XY(img,x,y) cimg_for6Y(img,y) cimg_for6X(img,x) -#define cimg_for6XZ(img,x,z) cimg_for6Z(img,z) cimg_for6X(img,x) -#define cimg_for6XC(img,x,c) cimg_for6C(img,c) cimg_for6X(img,x) -#define cimg_for6YZ(img,y,z) cimg_for6Z(img,z) cimg_for6Y(img,y) -#define cimg_for6YC(img,y,c) cimg_for6C(img,c) cimg_for6Y(img,y) -#define cimg_for6ZC(img,z,c) cimg_for6C(img,c) cimg_for6Z(img,z) -#define cimg_for6XYZ(img,x,y,z) cimg_for6Z(img,z) cimg_for6XY(img,x,y) -#define cimg_for6XZC(img,x,z,c) cimg_for6C(img,c) cimg_for6XZ(img,x,z) -#define cimg_for6YZC(img,y,z,c) cimg_for6C(img,c) cimg_for6YZ(img,y,z) -#define cimg_for6XYZC(img,x,y,z,c) cimg_for6C(img,c) cimg_for6XYZ(img,x,y,z) - -#define cimg_for_in6(bound,i0,i1,i) \ - for (int i = (int)(i0)<0?0:(int)(i0), \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3; \ - i<=(int)(i1) && \ - (_n3##i<(int)(bound) || _n2##i==--_n3##i || _n1##i==--_n2##i || i==(_n3##i = _n2##i = --_n1##i)); \ - _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i) -#define cimg_for_in6X(img,x0,x1,x) cimg_for_in6((img)._width,x0,x1,x) -#define cimg_for_in6Y(img,y0,y1,y) cimg_for_in6((img)._height,y0,y1,y) -#define cimg_for_in6Z(img,z0,z1,z) cimg_for_in6((img)._depth,z0,z1,z) -#define cimg_for_in6C(img,c0,c1,c) cimg_for_in6((img)._spectrum,c0,c1,c) -#define cimg_for_in6XY(img,x0,y0,x1,y1,x,y) cimg_for_in6Y(img,y0,y1,y) cimg_for_in6X(img,x0,x1,x) -#define cimg_for_in6XZ(img,x0,z0,x1,z1,x,z) cimg_for_in6Z(img,z0,z1,z) cimg_for_in6X(img,x0,x1,x) -#define cimg_for_in6XC(img,x0,c0,x1,c1,x,c) cimg_for_in6C(img,c0,c1,c) cimg_for_in6X(img,x0,x1,x) -#define cimg_for_in6YZ(img,y0,z0,y1,z1,y,z) cimg_for_in6Z(img,z0,z1,z) cimg_for_in6Y(img,y0,y1,y) -#define cimg_for_in6YC(img,y0,c0,y1,c1,y,c) cimg_for_in6C(img,c0,c1,c) cimg_for_in6Y(img,y0,y1,y) -#define cimg_for_in6ZC(img,z0,c0,z1,c1,z,c) cimg_for_in6C(img,c0,c1,c) cimg_for_in6Z(img,z0,z1,z) -#define cimg_for_in6XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in6Z(img,z0,z1,z) cimg_for_in6XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in6XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in6C(img,c0,c1,c) cimg_for_in6XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in6YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in6C(img,c0,c1,c) cimg_for_in6YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in6XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) \ - cimg_for_in6C(img,c0,c1,c) cimg_for_in6XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for7(bound,i) \ - for (int i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(bound)?(int)(bound) - 1:3; \ - _n3##i<(int)(bound) || _n2##i==--_n3##i || _n1##i==--_n2##i || i==(_n3##i = _n2##i = --_n1##i); \ - _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i) -#define cimg_for7X(img,x) cimg_for7((img)._width,x) -#define cimg_for7Y(img,y) cimg_for7((img)._height,y) -#define cimg_for7Z(img,z) cimg_for7((img)._depth,z) -#define cimg_for7C(img,c) cimg_for7((img)._spectrum,c) -#define cimg_for7XY(img,x,y) cimg_for7Y(img,y) cimg_for7X(img,x) -#define cimg_for7XZ(img,x,z) cimg_for7Z(img,z) cimg_for7X(img,x) -#define cimg_for7XC(img,x,c) cimg_for7C(img,c) cimg_for7X(img,x) -#define cimg_for7YZ(img,y,z) cimg_for7Z(img,z) cimg_for7Y(img,y) -#define cimg_for7YC(img,y,c) cimg_for7C(img,c) cimg_for7Y(img,y) -#define cimg_for7ZC(img,z,c) cimg_for7C(img,c) cimg_for7Z(img,z) -#define cimg_for7XYZ(img,x,y,z) cimg_for7Z(img,z) cimg_for7XY(img,x,y) -#define cimg_for7XZC(img,x,z,c) cimg_for7C(img,c) cimg_for7XZ(img,x,z) -#define cimg_for7YZC(img,y,z,c) cimg_for7C(img,c) cimg_for7YZ(img,y,z) -#define cimg_for7XYZC(img,x,y,z,c) cimg_for7C(img,c) cimg_for7XYZ(img,x,y,z) - -#define cimg_for_in7(bound,i0,i1,i) \ - for (int i = (int)(i0)<0?0:(int)(i0), \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3; \ - i<=(int)(i1) && \ - (_n3##i<(int)(bound) || _n2##i==--_n3##i || _n1##i==--_n2##i || i==(_n3##i = _n2##i = --_n1##i)); \ - _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i) -#define cimg_for_in7X(img,x0,x1,x) cimg_for_in7((img)._width,x0,x1,x) -#define cimg_for_in7Y(img,y0,y1,y) cimg_for_in7((img)._height,y0,y1,y) -#define cimg_for_in7Z(img,z0,z1,z) cimg_for_in7((img)._depth,z0,z1,z) -#define cimg_for_in7C(img,c0,c1,c) cimg_for_in7((img)._spectrum,c0,c1,c) -#define cimg_for_in7XY(img,x0,y0,x1,y1,x,y) cimg_for_in7Y(img,y0,y1,y) cimg_for_in7X(img,x0,x1,x) -#define cimg_for_in7XZ(img,x0,z0,x1,z1,x,z) cimg_for_in7Z(img,z0,z1,z) cimg_for_in7X(img,x0,x1,x) -#define cimg_for_in7XC(img,x0,c0,x1,c1,x,c) cimg_for_in7C(img,c0,c1,c) cimg_for_in7X(img,x0,x1,x) -#define cimg_for_in7YZ(img,y0,z0,y1,z1,y,z) cimg_for_in7Z(img,z0,z1,z) cimg_for_in7Y(img,y0,y1,y) -#define cimg_for_in7YC(img,y0,c0,y1,c1,y,c) cimg_for_in7C(img,c0,c1,c) cimg_for_in7Y(img,y0,y1,y) -#define cimg_for_in7ZC(img,z0,c0,z1,c1,z,c) cimg_for_in7C(img,c0,c1,c) cimg_for_in7Z(img,z0,z1,z) -#define cimg_for_in7XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in7Z(img,z0,z1,z) cimg_for_in7XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in7XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in7C(img,c0,c1,c) cimg_for_in7XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in7YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in7C(img,c0,c1,c) cimg_for_in7YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in7XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) \ - cimg_for_in7C(img,c0,c1,c) cimg_for_in7XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for8(bound,i) \ - for (int i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(bound)?(int)(bound) - 1:4; \ - _n4##i<(int)(bound) || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n4##i = _n3##i = _n2##i = --_n1##i); \ - _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i) -#define cimg_for8X(img,x) cimg_for8((img)._width,x) -#define cimg_for8Y(img,y) cimg_for8((img)._height,y) -#define cimg_for8Z(img,z) cimg_for8((img)._depth,z) -#define cimg_for8C(img,c) cimg_for8((img)._spectrum,c) -#define cimg_for8XY(img,x,y) cimg_for8Y(img,y) cimg_for8X(img,x) -#define cimg_for8XZ(img,x,z) cimg_for8Z(img,z) cimg_for8X(img,x) -#define cimg_for8XC(img,x,c) cimg_for8C(img,c) cimg_for8X(img,x) -#define cimg_for8YZ(img,y,z) cimg_for8Z(img,z) cimg_for8Y(img,y) -#define cimg_for8YC(img,y,c) cimg_for8C(img,c) cimg_for8Y(img,y) -#define cimg_for8ZC(img,z,c) cimg_for8C(img,c) cimg_for8Z(img,z) -#define cimg_for8XYZ(img,x,y,z) cimg_for8Z(img,z) cimg_for8XY(img,x,y) -#define cimg_for8XZC(img,x,z,c) cimg_for8C(img,c) cimg_for8XZ(img,x,z) -#define cimg_for8YZC(img,y,z,c) cimg_for8C(img,c) cimg_for8YZ(img,y,z) -#define cimg_for8XYZC(img,x,y,z,c) cimg_for8C(img,c) cimg_for8XYZ(img,x,y,z) - -#define cimg_for_in8(bound,i0,i1,i) \ - for (int i = (int)(i0)<0?0:(int)(i0), \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4; \ - i<=(int)(i1) && (_n4##i<(int)(bound) || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i) -#define cimg_for_in8X(img,x0,x1,x) cimg_for_in8((img)._width,x0,x1,x) -#define cimg_for_in8Y(img,y0,y1,y) cimg_for_in8((img)._height,y0,y1,y) -#define cimg_for_in8Z(img,z0,z1,z) cimg_for_in8((img)._depth,z0,z1,z) -#define cimg_for_in8C(img,c0,c1,c) cimg_for_in8((img)._spectrum,c0,c1,c) -#define cimg_for_in8XY(img,x0,y0,x1,y1,x,y) cimg_for_in8Y(img,y0,y1,y) cimg_for_in8X(img,x0,x1,x) -#define cimg_for_in8XZ(img,x0,z0,x1,z1,x,z) cimg_for_in8Z(img,z0,z1,z) cimg_for_in8X(img,x0,x1,x) -#define cimg_for_in8XC(img,x0,c0,x1,c1,x,c) cimg_for_in8C(img,c0,c1,c) cimg_for_in8X(img,x0,x1,x) -#define cimg_for_in8YZ(img,y0,z0,y1,z1,y,z) cimg_for_in8Z(img,z0,z1,z) cimg_for_in8Y(img,y0,y1,y) -#define cimg_for_in8YC(img,y0,c0,y1,c1,y,c) cimg_for_in8C(img,c0,c1,c) cimg_for_in8Y(img,y0,y1,y) -#define cimg_for_in8ZC(img,z0,c0,z1,c1,z,c) cimg_for_in8C(img,c0,c1,c) cimg_for_in8Z(img,z0,z1,z) -#define cimg_for_in8XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in8Z(img,z0,z1,z) cimg_for_in8XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in8XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in8C(img,c0,c1,c) cimg_for_in8XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in8YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in8C(img,c0,c1,c) cimg_for_in8YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in8XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) \ - cimg_for_in8C(img,c0,c1,c) cimg_for_in8XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for9(bound,i) \ - for (int i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4; \ - _n4##i<(int)(bound) || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n4##i = _n3##i = _n2##i = --_n1##i); \ - _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i) -#define cimg_for9X(img,x) cimg_for9((img)._width,x) -#define cimg_for9Y(img,y) cimg_for9((img)._height,y) -#define cimg_for9Z(img,z) cimg_for9((img)._depth,z) -#define cimg_for9C(img,c) cimg_for9((img)._spectrum,c) -#define cimg_for9XY(img,x,y) cimg_for9Y(img,y) cimg_for9X(img,x) -#define cimg_for9XZ(img,x,z) cimg_for9Z(img,z) cimg_for9X(img,x) -#define cimg_for9XC(img,x,c) cimg_for9C(img,c) cimg_for9X(img,x) -#define cimg_for9YZ(img,y,z) cimg_for9Z(img,z) cimg_for9Y(img,y) -#define cimg_for9YC(img,y,c) cimg_for9C(img,c) cimg_for9Y(img,y) -#define cimg_for9ZC(img,z,c) cimg_for9C(img,c) cimg_for9Z(img,z) -#define cimg_for9XYZ(img,x,y,z) cimg_for9Z(img,z) cimg_for9XY(img,x,y) -#define cimg_for9XZC(img,x,z,c) cimg_for9C(img,c) cimg_for9XZ(img,x,z) -#define cimg_for9YZC(img,y,z,c) cimg_for9C(img,c) cimg_for9YZ(img,y,z) -#define cimg_for9XYZC(img,x,y,z,c) cimg_for9C(img,c) cimg_for9XYZ(img,x,y,z) - -#define cimg_for_in9(bound,i0,i1,i) \ - for (int i = (int)(i0)<0?0:(int)(i0), \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4; \ - i<=(int)(i1) && (_n4##i<(int)(bound) || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i) -#define cimg_for_in9X(img,x0,x1,x) cimg_for_in9((img)._width,x0,x1,x) -#define cimg_for_in9Y(img,y0,y1,y) cimg_for_in9((img)._height,y0,y1,y) -#define cimg_for_in9Z(img,z0,z1,z) cimg_for_in9((img)._depth,z0,z1,z) -#define cimg_for_in9C(img,c0,c1,c) cimg_for_in9((img)._spectrum,c0,c1,c) -#define cimg_for_in9XY(img,x0,y0,x1,y1,x,y) cimg_for_in9Y(img,y0,y1,y) cimg_for_in9X(img,x0,x1,x) -#define cimg_for_in9XZ(img,x0,z0,x1,z1,x,z) cimg_for_in9Z(img,z0,z1,z) cimg_for_in9X(img,x0,x1,x) -#define cimg_for_in9XC(img,x0,c0,x1,c1,x,c) cimg_for_in9C(img,c0,c1,c) cimg_for_in9X(img,x0,x1,x) -#define cimg_for_in9YZ(img,y0,z0,y1,z1,y,z) cimg_for_in9Z(img,z0,z1,z) cimg_for_in9Y(img,y0,y1,y) -#define cimg_for_in9YC(img,y0,c0,y1,c1,y,c) cimg_for_in9C(img,c0,c1,c) cimg_for_in9Y(img,y0,y1,y) -#define cimg_for_in9ZC(img,z0,c0,z1,c1,z,c) cimg_for_in9C(img,c0,c1,c) cimg_for_in9Z(img,z0,z1,z) -#define cimg_for_in9XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in9Z(img,z0,z1,z) cimg_for_in9XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in9XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in9C(img,c0,c1,c) cimg_for_in9XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in9YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in9C(img,c0,c1,c) cimg_for_in9YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in9XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) \ - cimg_for_in9C(img,c0,c1,c) cimg_for_in9XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for2x2(img,x,y,z,c,I,T) \ - cimg_for2((img)._height,y) for (int x = 0, \ - _n1##x = (int)( \ - (I[0] = (T)(img)(0,y,z,c)), \ - (I[2] = (T)(img)(0,_n1##y,z,c)), \ - 1>=(img)._width?(img).width() - 1:1); \ - (_n1##x<(img).width() && ( \ - (I[1] = (T)(img)(_n1##x,y,z,c)), \ - (I[3] = (T)(img)(_n1##x,_n1##y,z,c)),1)) || \ - x==--_n1##x; \ - I[0] = I[1], \ - I[2] = I[3], \ - ++x, ++_n1##x) - -#define cimg_for_in2x2(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in2((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _n1##x = (int)( \ - (I[0] = (T)(img)(x,y,z,c)), \ - (I[2] = (T)(img)(x,_n1##y,z,c)), \ - x + 1>=(int)(img)._width?(img).width() - 1:x + 1); \ - x<=(int)(x1) && ((_n1##x<(img).width() && ( \ - (I[1] = (T)(img)(_n1##x,y,z,c)), \ - (I[3] = (T)(img)(_n1##x,_n1##y,z,c)),1)) || \ - x==--_n1##x); \ - I[0] = I[1], \ - I[2] = I[3], \ - ++x, ++_n1##x) - -#define cimg_for3x3(img,x,y,z,c,I,T) \ - cimg_for3((img)._height,y) for (int x = 0, \ - _p1##x = 0, \ - _n1##x = (int)( \ - (I[0] = I[1] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[3] = I[4] = (T)(img)(0,y,z,c)), \ - (I[6] = I[7] = (T)(img)(0,_n1##y,z,c)), \ - 1>=(img)._width?(img).width() - 1:1); \ - (_n1##x<(img).width() && ( \ - (I[2] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[5] = (T)(img)(_n1##x,y,z,c)), \ - (I[8] = (T)(img)(_n1##x,_n1##y,z,c)),1)) || \ - x==--_n1##x; \ - I[0] = I[1], I[1] = I[2], \ - I[3] = I[4], I[4] = I[5], \ - I[6] = I[7], I[7] = I[8], \ - _p1##x = x++, ++_n1##x) - -#define cimg_for_in3x3(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in3((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = (int)( \ - (I[0] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[3] = (T)(img)(_p1##x,y,z,c)), \ - (I[6] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[1] = (T)(img)(x,_p1##y,z,c)), \ - (I[4] = (T)(img)(x,y,z,c)), \ - (I[7] = (T)(img)(x,_n1##y,z,c)), \ - x + 1>=(int)(img)._width?(img).width() - 1:x + 1); \ - x<=(int)(x1) && ((_n1##x<(img).width() && ( \ - (I[2] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[5] = (T)(img)(_n1##x,y,z,c)), \ - (I[8] = (T)(img)(_n1##x,_n1##y,z,c)),1)) || \ - x==--_n1##x); \ - I[0] = I[1], I[1] = I[2], \ - I[3] = I[4], I[4] = I[5], \ - I[6] = I[7], I[7] = I[8], \ - _p1##x = x++, ++_n1##x) - -#define cimg_for4x4(img,x,y,z,c,I,T) \ - cimg_for4((img)._height,y) for (int x = 0, \ - _p1##x = 0, \ - _n1##x = 1>=(img)._width?(img).width() - 1:1, \ - _n2##x = (int)( \ - (I[0] = I[1] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[4] = I[5] = (T)(img)(0,y,z,c)), \ - (I[8] = I[9] = (T)(img)(0,_n1##y,z,c)), \ - (I[12] = I[13] = (T)(img)(0,_n2##y,z,c)), \ - (I[2] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[6] = (T)(img)(_n1##x,y,z,c)), \ - (I[10] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[14] = (T)(img)(_n1##x,_n2##y,z,c)), \ - 2>=(img)._width?(img).width() - 1:2); \ - (_n2##x<(img).width() && ( \ - (I[3] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[7] = (T)(img)(_n2##x,y,z,c)), \ - (I[11] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[15] = (T)(img)(_n2##x,_n2##y,z,c)),1)) || \ - _n1##x==--_n2##x || x==(_n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], \ - I[4] = I[5], I[5] = I[6], I[6] = I[7], \ - I[8] = I[9], I[9] = I[10], I[10] = I[11], \ - I[12] = I[13], I[13] = I[14], I[14] = I[15], \ - _p1##x = x++, ++_n1##x, ++_n2##x) - -#define cimg_for_in4x4(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in4((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(int)(img)._width?(img).width() - 1:x + 1, \ - _n2##x = (int)( \ - (I[0] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[4] = (T)(img)(_p1##x,y,z,c)), \ - (I[8] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[12] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[1] = (T)(img)(x,_p1##y,z,c)), \ - (I[5] = (T)(img)(x,y,z,c)), \ - (I[9] = (T)(img)(x,_n1##y,z,c)), \ - (I[13] = (T)(img)(x,_n2##y,z,c)), \ - (I[2] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[6] = (T)(img)(_n1##x,y,z,c)), \ - (I[10] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[14] = (T)(img)(_n1##x,_n2##y,z,c)), \ - x + 2>=(int)(img)._width?(img).width() - 1:x + 2); \ - x<=(int)(x1) && ((_n2##x<(img).width() && ( \ - (I[3] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[7] = (T)(img)(_n2##x,y,z,c)), \ - (I[11] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[15] = (T)(img)(_n2##x,_n2##y,z,c)),1)) || \ - _n1##x==--_n2##x || x==(_n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], \ - I[4] = I[5], I[5] = I[6], I[6] = I[7], \ - I[8] = I[9], I[9] = I[10], I[10] = I[11], \ - I[12] = I[13], I[13] = I[14], I[14] = I[15], \ - _p1##x = x++, ++_n1##x, ++_n2##x) - -#define cimg_for5x5(img,x,y,z,c,I,T) \ - cimg_for5((img)._height,y) for (int x = 0, \ - _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=(img)._width?(img).width() - 1:1, \ - _n2##x = (int)( \ - (I[0] = I[1] = I[2] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[5] = I[6] = I[7] = (T)(img)(0,_p1##y,z,c)), \ - (I[10] = I[11] = I[12] = (T)(img)(0,y,z,c)), \ - (I[15] = I[16] = I[17] = (T)(img)(0,_n1##y,z,c)), \ - (I[20] = I[21] = I[22] = (T)(img)(0,_n2##y,z,c)), \ - (I[3] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[8] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[13] = (T)(img)(_n1##x,y,z,c)), \ - (I[18] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[23] = (T)(img)(_n1##x,_n2##y,z,c)), \ - 2>=(img)._width?(img).width() - 1:2); \ - (_n2##x<(img).width() && ( \ - (I[4] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[9] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[14] = (T)(img)(_n2##x,y,z,c)), \ - (I[19] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[24] = (T)(img)(_n2##x,_n2##y,z,c)),1)) || \ - _n1##x==--_n2##x || x==(_n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], \ - I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], \ - I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], \ - I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], \ - I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], \ - _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x) - -#define cimg_for_in5x5(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in5((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(int)(img)._width?(img).width() - 1:x + 1, \ - _n2##x = (int)( \ - (I[0] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[5] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[10] = (T)(img)(_p2##x,y,z,c)), \ - (I[15] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[20] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[1] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[6] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[11] = (T)(img)(_p1##x,y,z,c)), \ - (I[16] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[21] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[2] = (T)(img)(x,_p2##y,z,c)), \ - (I[7] = (T)(img)(x,_p1##y,z,c)), \ - (I[12] = (T)(img)(x,y,z,c)), \ - (I[17] = (T)(img)(x,_n1##y,z,c)), \ - (I[22] = (T)(img)(x,_n2##y,z,c)), \ - (I[3] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[8] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[13] = (T)(img)(_n1##x,y,z,c)), \ - (I[18] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[23] = (T)(img)(_n1##x,_n2##y,z,c)), \ - x + 2>=(int)(img)._width?(img).width() - 1:x + 2); \ - x<=(int)(x1) && ((_n2##x<(img).width() && ( \ - (I[4] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[9] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[14] = (T)(img)(_n2##x,y,z,c)), \ - (I[19] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[24] = (T)(img)(_n2##x,_n2##y,z,c)),1)) || \ - _n1##x==--_n2##x || x==(_n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], \ - I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], \ - I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], \ - I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], \ - I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], \ - _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x) - -#define cimg_for6x6(img,x,y,z,c,I,T) \ - cimg_for6((img)._height,y) for (int x = 0, \ - _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=(img)._width?(img).width() - 1:1, \ - _n2##x = 2>=(img)._width?(img).width() - 1:2, \ - _n3##x = (int)( \ - (I[0] = I[1] = I[2] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[6] = I[7] = I[8] = (T)(img)(0,_p1##y,z,c)), \ - (I[12] = I[13] = I[14] = (T)(img)(0,y,z,c)), \ - (I[18] = I[19] = I[20] = (T)(img)(0,_n1##y,z,c)), \ - (I[24] = I[25] = I[26] = (T)(img)(0,_n2##y,z,c)), \ - (I[30] = I[31] = I[32] = (T)(img)(0,_n3##y,z,c)), \ - (I[3] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[9] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[15] = (T)(img)(_n1##x,y,z,c)), \ - (I[21] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[27] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[33] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[4] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[10] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[16] = (T)(img)(_n2##x,y,z,c)), \ - (I[22] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[28] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[34] = (T)(img)(_n2##x,_n3##y,z,c)), \ - 3>=(img)._width?(img).width() - 1:3); \ - (_n3##x<(img).width() && ( \ - (I[5] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[11] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[17] = (T)(img)(_n3##x,y,z,c)), \ - (I[23] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[29] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[35] = (T)(img)(_n3##x,_n3##y,z,c)),1)) || \ - _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3## x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], \ - I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], \ - I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], \ - I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \ - I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], \ - I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], \ - _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x) - -#define cimg_for_in6x6(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in6((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)x0, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(int)(img)._width?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(int)(img)._width?(img).width() - 1:x + 2, \ - _n3##x = (int)( \ - (I[0] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[6] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[12] = (T)(img)(_p2##x,y,z,c)), \ - (I[18] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[24] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[30] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[1] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[7] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[13] = (T)(img)(_p1##x,y,z,c)), \ - (I[19] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[25] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[31] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[2] = (T)(img)(x,_p2##y,z,c)), \ - (I[8] = (T)(img)(x,_p1##y,z,c)), \ - (I[14] = (T)(img)(x,y,z,c)), \ - (I[20] = (T)(img)(x,_n1##y,z,c)), \ - (I[26] = (T)(img)(x,_n2##y,z,c)), \ - (I[32] = (T)(img)(x,_n3##y,z,c)), \ - (I[3] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[9] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[15] = (T)(img)(_n1##x,y,z,c)), \ - (I[21] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[27] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[33] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[4] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[10] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[16] = (T)(img)(_n2##x,y,z,c)), \ - (I[22] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[28] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[34] = (T)(img)(_n2##x,_n3##y,z,c)), \ - x + 3>=(int)(img)._width?(img).width() - 1:x + 3); \ - x<=(int)(x1) && ((_n3##x<(img).width() && ( \ - (I[5] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[11] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[17] = (T)(img)(_n3##x,y,z,c)), \ - (I[23] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[29] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[35] = (T)(img)(_n3##x,_n3##y,z,c)),1)) || \ - _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3## x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], \ - I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], \ - I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], \ - I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \ - I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], \ - I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], \ - _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x) - -#define cimg_for7x7(img,x,y,z,c,I,T) \ - cimg_for7((img)._height,y) for (int x = 0, \ - _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=(img)._width?(img).width() - 1:1, \ - _n2##x = 2>=(img)._width?(img).width() - 1:2, \ - _n3##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[7] = I[8] = I[9] = I[10] = (T)(img)(0,_p2##y,z,c)), \ - (I[14] = I[15] = I[16] = I[17] = (T)(img)(0,_p1##y,z,c)), \ - (I[21] = I[22] = I[23] = I[24] = (T)(img)(0,y,z,c)), \ - (I[28] = I[29] = I[30] = I[31] = (T)(img)(0,_n1##y,z,c)), \ - (I[35] = I[36] = I[37] = I[38] = (T)(img)(0,_n2##y,z,c)), \ - (I[42] = I[43] = I[44] = I[45] = (T)(img)(0,_n3##y,z,c)), \ - (I[4] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[11] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[18] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[25] = (T)(img)(_n1##x,y,z,c)), \ - (I[32] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[39] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[46] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[5] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[12] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[19] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[26] = (T)(img)(_n2##x,y,z,c)), \ - (I[33] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[40] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[47] = (T)(img)(_n2##x,_n3##y,z,c)), \ - 3>=(img)._width?(img).width() - 1:3); \ - (_n3##x<(img).width() && ( \ - (I[6] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[13] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[20] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[27] = (T)(img)(_n3##x,y,z,c)), \ - (I[34] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[41] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[48] = (T)(img)(_n3##x,_n3##y,z,c)),1)) || \ - _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], \ - I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], \ - I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], \ - I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], \ - I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], \ - I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], \ - I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], \ - _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x) - -#define cimg_for_in7x7(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in7((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(int)(img)._width?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(int)(img)._width?(img).width() - 1:x + 2, \ - _n3##x = (int)( \ - (I[0] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[7] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[14] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[21] = (T)(img)(_p3##x,y,z,c)), \ - (I[28] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[35] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[42] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[1] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[8] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[15] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[22] = (T)(img)(_p2##x,y,z,c)), \ - (I[29] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[36] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[43] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[2] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[9] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[16] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[23] = (T)(img)(_p1##x,y,z,c)), \ - (I[30] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[37] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[44] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[3] = (T)(img)(x,_p3##y,z,c)), \ - (I[10] = (T)(img)(x,_p2##y,z,c)), \ - (I[17] = (T)(img)(x,_p1##y,z,c)), \ - (I[24] = (T)(img)(x,y,z,c)), \ - (I[31] = (T)(img)(x,_n1##y,z,c)), \ - (I[38] = (T)(img)(x,_n2##y,z,c)), \ - (I[45] = (T)(img)(x,_n3##y,z,c)), \ - (I[4] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[11] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[18] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[25] = (T)(img)(_n1##x,y,z,c)), \ - (I[32] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[39] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[46] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[5] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[12] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[19] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[26] = (T)(img)(_n2##x,y,z,c)), \ - (I[33] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[40] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[47] = (T)(img)(_n2##x,_n3##y,z,c)), \ - x + 3>=(int)(img)._width?(img).width() - 1:x + 3); \ - x<=(int)(x1) && ((_n3##x<(img).width() && ( \ - (I[6] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[13] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[20] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[27] = (T)(img)(_n3##x,y,z,c)), \ - (I[34] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[41] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[48] = (T)(img)(_n3##x,_n3##y,z,c)),1)) || \ - _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], \ - I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], \ - I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], \ - I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], \ - I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], \ - I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], \ - I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], \ - _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x) - -#define cimg_for8x8(img,x,y,z,c,I,T) \ - cimg_for8((img)._height,y) for (int x = 0, \ - _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[8] = I[9] = I[10] = I[11] = (T)(img)(0,_p2##y,z,c)), \ - (I[16] = I[17] = I[18] = I[19] = (T)(img)(0,_p1##y,z,c)), \ - (I[24] = I[25] = I[26] = I[27] = (T)(img)(0,y,z,c)), \ - (I[32] = I[33] = I[34] = I[35] = (T)(img)(0,_n1##y,z,c)), \ - (I[40] = I[41] = I[42] = I[43] = (T)(img)(0,_n2##y,z,c)), \ - (I[48] = I[49] = I[50] = I[51] = (T)(img)(0,_n3##y,z,c)), \ - (I[56] = I[57] = I[58] = I[59] = (T)(img)(0,_n4##y,z,c)), \ - (I[4] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[12] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[20] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[28] = (T)(img)(_n1##x,y,z,c)), \ - (I[36] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[44] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[52] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[60] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[5] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[13] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[21] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[29] = (T)(img)(_n2##x,y,z,c)), \ - (I[37] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[45] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[53] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[61] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[6] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[14] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[22] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[30] = (T)(img)(_n3##x,y,z,c)), \ - (I[38] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[46] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[54] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[62] = (T)(img)(_n3##x,_n4##y,z,c)), \ - 4>=((img)._width)?(img).width() - 1:4); \ - (_n4##x<(img).width() && ( \ - (I[7] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[15] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[23] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[31] = (T)(img)(_n4##x,y,z,c)), \ - (I[39] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[47] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[55] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[63] = (T)(img)(_n4##x,_n4##y,z,c)),1)) || \ - _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], \ - I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], \ - I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \ - I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], \ - I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], \ - I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], \ - I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], \ - I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], \ - _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x) - -#define cimg_for_in8x8(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in8((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = (int)( \ - (I[0] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[8] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[16] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[24] = (T)(img)(_p3##x,y,z,c)), \ - (I[32] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[40] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[48] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[56] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[1] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[9] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[17] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[25] = (T)(img)(_p2##x,y,z,c)), \ - (I[33] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[41] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[49] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[57] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[2] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[10] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[18] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[26] = (T)(img)(_p1##x,y,z,c)), \ - (I[34] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[42] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[50] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[58] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[3] = (T)(img)(x,_p3##y,z,c)), \ - (I[11] = (T)(img)(x,_p2##y,z,c)), \ - (I[19] = (T)(img)(x,_p1##y,z,c)), \ - (I[27] = (T)(img)(x,y,z,c)), \ - (I[35] = (T)(img)(x,_n1##y,z,c)), \ - (I[43] = (T)(img)(x,_n2##y,z,c)), \ - (I[51] = (T)(img)(x,_n3##y,z,c)), \ - (I[59] = (T)(img)(x,_n4##y,z,c)), \ - (I[4] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[12] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[20] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[28] = (T)(img)(_n1##x,y,z,c)), \ - (I[36] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[44] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[52] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[60] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[5] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[13] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[21] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[29] = (T)(img)(_n2##x,y,z,c)), \ - (I[37] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[45] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[53] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[61] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[6] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[14] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[22] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[30] = (T)(img)(_n3##x,y,z,c)), \ - (I[38] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[46] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[54] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[62] = (T)(img)(_n3##x,_n4##y,z,c)), \ - x + 4>=(img).width()?(img).width() - 1:x + 4); \ - x<=(int)(x1) && ((_n4##x<(img).width() && ( \ - (I[7] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[15] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[23] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[31] = (T)(img)(_n4##x,y,z,c)), \ - (I[39] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[47] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[55] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[63] = (T)(img)(_n4##x,_n4##y,z,c)),1)) || \ - _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], \ - I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], \ - I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \ - I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], \ - I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], \ - I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], \ - I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], \ - I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], \ - _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x) - -#define cimg_for9x9(img,x,y,z,c,I,T) \ - cimg_for9((img)._height,y) for (int x = 0, \ - _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[9] = I[10] = I[11] = I[12] = I[13] = (T)(img)(0,_p3##y,z,c)), \ - (I[18] = I[19] = I[20] = I[21] = I[22] = (T)(img)(0,_p2##y,z,c)), \ - (I[27] = I[28] = I[29] = I[30] = I[31] = (T)(img)(0,_p1##y,z,c)), \ - (I[36] = I[37] = I[38] = I[39] = I[40] = (T)(img)(0,y,z,c)), \ - (I[45] = I[46] = I[47] = I[48] = I[49] = (T)(img)(0,_n1##y,z,c)), \ - (I[54] = I[55] = I[56] = I[57] = I[58] = (T)(img)(0,_n2##y,z,c)), \ - (I[63] = I[64] = I[65] = I[66] = I[67] = (T)(img)(0,_n3##y,z,c)), \ - (I[72] = I[73] = I[74] = I[75] = I[76] = (T)(img)(0,_n4##y,z,c)), \ - (I[5] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[14] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[23] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[32] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[41] = (T)(img)(_n1##x,y,z,c)), \ - (I[50] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[59] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[68] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[77] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[6] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[15] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[24] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[33] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[42] = (T)(img)(_n2##x,y,z,c)), \ - (I[51] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[60] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[69] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[78] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[7] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[16] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[25] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[34] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[43] = (T)(img)(_n3##x,y,z,c)), \ - (I[52] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[61] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[70] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[79] = (T)(img)(_n3##x,_n4##y,z,c)), \ - 4>=((img)._width)?(img).width() - 1:4); \ - (_n4##x<(img).width() && ( \ - (I[8] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[17] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[26] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[35] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[44] = (T)(img)(_n4##x,y,z,c)), \ - (I[53] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[62] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[71] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[80] = (T)(img)(_n4##x,_n4##y,z,c)),1)) || \ - _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], \ - I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], \ - I[16] = I[17], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], \ - I[24] = I[25], I[25] = I[26], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], \ - I[32] = I[33], I[33] = I[34], I[34] = I[35], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], \ - I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[45] = I[46], I[46] = I[47], I[47] = I[48], \ - I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[54] = I[55], I[55] = I[56], \ - I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[63] = I[64], \ - I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], \ - I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], \ - I[79] = I[80], \ - _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x) - -#define cimg_for_in9x9(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in9((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = (int)( \ - (I[0] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[9] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[18] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[27] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[36] = (T)(img)(_p4##x,y,z,c)), \ - (I[45] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[54] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[63] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[72] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[1] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[10] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[19] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[28] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[37] = (T)(img)(_p3##x,y,z,c)), \ - (I[46] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[55] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[64] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[73] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[2] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[11] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[20] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[29] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[38] = (T)(img)(_p2##x,y,z,c)), \ - (I[47] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[56] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[65] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[74] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[3] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[12] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[21] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[30] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[39] = (T)(img)(_p1##x,y,z,c)), \ - (I[48] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[57] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[66] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[75] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[4] = (T)(img)(x,_p4##y,z,c)), \ - (I[13] = (T)(img)(x,_p3##y,z,c)), \ - (I[22] = (T)(img)(x,_p2##y,z,c)), \ - (I[31] = (T)(img)(x,_p1##y,z,c)), \ - (I[40] = (T)(img)(x,y,z,c)), \ - (I[49] = (T)(img)(x,_n1##y,z,c)), \ - (I[58] = (T)(img)(x,_n2##y,z,c)), \ - (I[67] = (T)(img)(x,_n3##y,z,c)), \ - (I[76] = (T)(img)(x,_n4##y,z,c)), \ - (I[5] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[14] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[23] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[32] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[41] = (T)(img)(_n1##x,y,z,c)), \ - (I[50] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[59] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[68] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[77] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[6] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[15] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[24] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[33] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[42] = (T)(img)(_n2##x,y,z,c)), \ - (I[51] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[60] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[69] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[78] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[7] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[16] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[25] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[34] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[43] = (T)(img)(_n3##x,y,z,c)), \ - (I[52] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[61] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[70] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[79] = (T)(img)(_n3##x,_n4##y,z,c)), \ - x + 4>=(img).width()?(img).width() - 1:x + 4); \ - x<=(int)(x1) && ((_n4##x<(img).width() && ( \ - (I[8] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[17] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[26] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[35] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[44] = (T)(img)(_n4##x,y,z,c)), \ - (I[53] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[62] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[71] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[80] = (T)(img)(_n4##x,_n4##y,z,c)),1)) || \ - _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], \ - I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], \ - I[16] = I[17], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], \ - I[24] = I[25], I[25] = I[26], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], \ - I[32] = I[33], I[33] = I[34], I[34] = I[35], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], \ - I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[45] = I[46], I[46] = I[47], I[47] = I[48], \ - I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[54] = I[55], I[55] = I[56], \ - I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[63] = I[64], \ - I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], \ - I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], \ - I[79] = I[80], \ - _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x) - -#define cimg_for2x2x2(img,x,y,z,c,I,T) \ - cimg_for2((img)._depth,z) cimg_for2((img)._height,y) for (int x = 0, \ - _n1##x = (int)( \ - (I[0] = (T)(img)(0,y,z,c)), \ - (I[2] = (T)(img)(0,_n1##y,z,c)), \ - (I[4] = (T)(img)(0,y,_n1##z,c)), \ - (I[6] = (T)(img)(0,_n1##y,_n1##z,c)), \ - 1>=(img)._width?(img).width() - 1:1); \ - (_n1##x<(img).width() && ( \ - (I[1] = (T)(img)(_n1##x,y,z,c)), \ - (I[3] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[5] = (T)(img)(_n1##x,y,_n1##z,c)), \ - (I[7] = (T)(img)(_n1##x,_n1##y,_n1##z,c)),1)) || \ - x==--_n1##x; \ - I[0] = I[1], I[2] = I[3], I[4] = I[5], I[6] = I[7], \ - ++x, ++_n1##x) - -#define cimg_for_in2x2x2(img,x0,y0,z0,x1,y1,z1,x,y,z,c,I,T) \ - cimg_for_in2((img)._depth,z0,z1,z) cimg_for_in2((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _n1##x = (int)( \ - (I[0] = (T)(img)(x,y,z,c)), \ - (I[2] = (T)(img)(x,_n1##y,z,c)), \ - (I[4] = (T)(img)(x,y,_n1##z,c)), \ - (I[6] = (T)(img)(x,_n1##y,_n1##z,c)), \ - x + 1>=(int)(img)._width?(img).width() - 1:x + 1); \ - x<=(int)(x1) && ((_n1##x<(img).width() && ( \ - (I[1] = (T)(img)(_n1##x,y,z,c)), \ - (I[3] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[5] = (T)(img)(_n1##x,y,_n1##z,c)), \ - (I[7] = (T)(img)(_n1##x,_n1##y,_n1##z,c)),1)) || \ - x==--_n1##x); \ - I[0] = I[1], I[2] = I[3], I[4] = I[5], I[6] = I[7], \ - ++x, ++_n1##x) - -#define cimg_for3x3x3(img,x,y,z,c,I,T) \ - cimg_for3((img)._depth,z) cimg_for3((img)._height,y) for (int x = 0, \ - _p1##x = 0, \ - _n1##x = (int)( \ - (I[0] = I[1] = (T)(img)(_p1##x,_p1##y,_p1##z,c)), \ - (I[3] = I[4] = (T)(img)(0,y,_p1##z,c)), \ - (I[6] = I[7] = (T)(img)(0,_n1##y,_p1##z,c)), \ - (I[9] = I[10] = (T)(img)(0,_p1##y,z,c)), \ - (I[12] = I[13] = (T)(img)(0,y,z,c)), \ - (I[15] = I[16] = (T)(img)(0,_n1##y,z,c)), \ - (I[18] = I[19] = (T)(img)(0,_p1##y,_n1##z,c)), \ - (I[21] = I[22] = (T)(img)(0,y,_n1##z,c)), \ - (I[24] = I[25] = (T)(img)(0,_n1##y,_n1##z,c)), \ - 1>=(img)._width?(img).width() - 1:1); \ - (_n1##x<(img).width() && ( \ - (I[2] = (T)(img)(_n1##x,_p1##y,_p1##z,c)), \ - (I[5] = (T)(img)(_n1##x,y,_p1##z,c)), \ - (I[8] = (T)(img)(_n1##x,_n1##y,_p1##z,c)), \ - (I[11] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[14] = (T)(img)(_n1##x,y,z,c)), \ - (I[17] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[20] = (T)(img)(_n1##x,_p1##y,_n1##z,c)), \ - (I[23] = (T)(img)(_n1##x,y,_n1##z,c)), \ - (I[26] = (T)(img)(_n1##x,_n1##y,_n1##z,c)),1)) || \ - x==--_n1##x; \ - I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], \ - I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], \ - I[18] = I[19], I[19] = I[20], I[21] = I[22], I[22] = I[23], I[24] = I[25], I[25] = I[26], \ - _p1##x = x++, ++_n1##x) - -#define cimg_for_in3x3x3(img,x0,y0,z0,x1,y1,z1,x,y,z,c,I,T) \ - cimg_for_in3((img)._depth,z0,z1,z) cimg_for_in3((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = (int)( \ - (I[0] = (T)(img)(_p1##x,_p1##y,_p1##z,c)), \ - (I[3] = (T)(img)(_p1##x,y,_p1##z,c)), \ - (I[6] = (T)(img)(_p1##x,_n1##y,_p1##z,c)), \ - (I[9] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[12] = (T)(img)(_p1##x,y,z,c)), \ - (I[15] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[18] = (T)(img)(_p1##x,_p1##y,_n1##z,c)), \ - (I[21] = (T)(img)(_p1##x,y,_n1##z,c)), \ - (I[24] = (T)(img)(_p1##x,_n1##y,_n1##z,c)), \ - (I[1] = (T)(img)(x,_p1##y,_p1##z,c)), \ - (I[4] = (T)(img)(x,y,_p1##z,c)), \ - (I[7] = (T)(img)(x,_n1##y,_p1##z,c)), \ - (I[10] = (T)(img)(x,_p1##y,z,c)), \ - (I[13] = (T)(img)(x,y,z,c)), \ - (I[16] = (T)(img)(x,_n1##y,z,c)), \ - (I[19] = (T)(img)(x,_p1##y,_n1##z,c)), \ - (I[22] = (T)(img)(x,y,_n1##z,c)), \ - (I[25] = (T)(img)(x,_n1##y,_n1##z,c)), \ - x + 1>=(int)(img)._width?(img).width() - 1:x + 1); \ - x<=(int)(x1) && ((_n1##x<(img).width() && ( \ - (I[2] = (T)(img)(_n1##x,_p1##y,_p1##z,c)), \ - (I[5] = (T)(img)(_n1##x,y,_p1##z,c)), \ - (I[8] = (T)(img)(_n1##x,_n1##y,_p1##z,c)), \ - (I[11] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[14] = (T)(img)(_n1##x,y,z,c)), \ - (I[17] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[20] = (T)(img)(_n1##x,_p1##y,_n1##z,c)), \ - (I[23] = (T)(img)(_n1##x,y,_n1##z,c)), \ - (I[26] = (T)(img)(_n1##x,_n1##y,_n1##z,c)),1)) || \ - x==--_n1##x); \ - I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], \ - I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], \ - I[18] = I[19], I[19] = I[20], I[21] = I[22], I[22] = I[23], I[24] = I[25], I[25] = I[26], \ - _p1##x = x++, ++_n1##x) - -#define cimglist_for(list,l) for (int l = 0; l<(int)(list)._width; ++l) -#define cimglist_for_in(list,l0,l1,l) \ - for (int l = (int)(l0)<0?0:(int)(l0), _max##l = (unsigned int)l1<(list)._width?(int)(l1):(int)(list)._width - 1; \ - l<=_max##l; ++l) - -#define cimglist_apply(list,fn) cimglist_for(list,__##fn) (list)[__##fn].fn - -// Macros used to display error messages when exceptions are thrown. -// You should not use these macros is your own code. -#define _cimgdisplay_instance "[instance(%u,%u,%u,%c%s%c)] CImgDisplay::" -#define cimgdisplay_instance _width,_height,_normalization,_title?'\"':'[',_title?_title:"untitled",_title?'\"':']' -#define _cimg_instance "[instance(%u,%u,%u,%u,%p,%sshared)] CImg<%s>::" -#define cimg_instance _width,_height,_depth,_spectrum,_data,_is_shared?"":"non-",pixel_type() -#define _cimglist_instance "[instance(%u,%u,%p)] CImgList<%s>::" -#define cimglist_instance _width,_allocated_width,_data,pixel_type() - -/*------------------------------------------------ - # - # - # Define cimg_library:: namespace - # - # - -------------------------------------------------*/ -//! Contains all classes and functions of the \CImg library. -/** - This namespace is defined to avoid functions and class names collisions - that could happen with the inclusion of other C++ header files. - Anyway, it should not happen often and you should reasonnably start most of your - \CImg-based programs with - \code - #include "CImg.h" - using namespace cimg_library; - \endcode - to simplify the declaration of \CImg Library objects afterwards. -**/ -namespace cimg_library_suffixed { - - // Declare the four classes of the CImg Library. - template struct CImg; - template struct CImgList; - struct CImgDisplay; - struct CImgException; - - // Declare cimg:: namespace. - // This is an uncomplete namespace definition here. It only contains some - // necessary stuff to ensure a correct declaration order of the classes and functions - // defined afterwards. - namespace cimg { - - // Define ascii sequences for colored terminal output. -#ifdef cimg_use_vt100 - static const char t_normal[] = { 0x1b, '[', '0', ';', '0', ';', '0', 'm', 0 }; - static const char t_black[] = { 0x1b, '[', '0', ';', '3', '0', ';', '5', '9', 'm', 0 }; - static const char t_red[] = { 0x1b, '[', '0', ';', '3', '1', ';', '5', '9', 'm', 0 }; - static const char t_green[] = { 0x1b, '[', '0', ';', '3', '2', ';', '5', '9', 'm', 0 }; - static const char t_yellow[] = { 0x1b, '[', '0', ';', '3', '3', ';', '5', '9', 'm', 0 }; - static const char t_blue[] = { 0x1b, '[', '0', ';', '3', '4', ';', '5', '9', 'm', 0 }; - static const char t_magenta[] = { 0x1b, '[', '0', ';', '3', '5', ';', '5', '9', 'm', 0 }; - static const char t_cyan[] = { 0x1b, '[', '0', ';', '3', '6', ';', '5', '9', 'm', 0 }; - static const char t_white[] = { 0x1b, '[', '0', ';', '3', '7', ';', '5', '9', 'm', 0 }; - static const char t_bold[] = { 0x1b, '[', '1', 'm', 0 }; - static const char t_underscore[] = { 0x1b, '[', '4', 'm', 0 }; -#else - static const char t_normal[] = { 0 }; - static const char *const t_black = cimg::t_normal, - *const t_red = cimg::t_normal, - *const t_green = cimg::t_normal, - *const t_yellow = cimg::t_normal, - *const t_blue = cimg::t_normal, - *const t_magenta = cimg::t_normal, - *const t_cyan = cimg::t_normal, - *const t_white = cimg::t_normal, - *const t_bold = cimg::t_normal, - *const t_underscore = cimg::t_normal; -#endif - - inline std::FILE* output(std::FILE *file=0); - inline void info(); - - //! Avoid warning messages due to unused parameters. Do nothing actually. - template - inline void unused(const T&, ...) {} - - // [internal] Lock/unlock a mutex for managing concurrent threads. - // 'lock_mode' can be { 0=unlock | 1=lock | 2=trylock }. - // 'n' can be in [0,31] but mutex range [0,15] is reserved by CImg. - inline int mutex(const unsigned int n, const int lock_mode=1); - - inline unsigned int& _exception_mode(const unsigned int value, const bool is_set) { - static unsigned int mode = cimg_verbosity; - if (is_set) { cimg::mutex(0); mode = value<4?value:4; cimg::mutex(0,0); } - return mode; - } - - // Mandatory because Microsoft's _snprintf() and _vsnprintf() do not add the '\0' character - // at the end of the string. -#if cimg_OS==2 && defined(_MSC_VER) - inline int _snprintf(char *const s, const size_t size, const char *const format, ...) { - va_list ap; - va_start(ap,format); - const int result = _vsnprintf(s,size,format,ap); - va_end(ap); - return result; - } - - inline int _vsnprintf(char *const s, const size_t size, const char *const format, va_list ap) { - int result = -1; - cimg::mutex(6); - if (size) result = _vsnprintf_s(s,size,_TRUNCATE,format,ap); - if (result==-1) result = _vscprintf(format,ap); - cimg::mutex(6,0); - return result; - } - - // Mutex-protected version of sscanf, sprintf and snprintf. - // Used only MacOSX, as it seems those functions are not re-entrant on MacOSX. -#elif defined(__MACOSX__) || defined(__APPLE__) - inline int _sscanf(const char *const s, const char *const format, ...) { - cimg::mutex(6); - va_list args; - va_start(args,format); - const int result = std::vsscanf(s,format,args); - va_end(args); - cimg::mutex(6,0); - return result; - } - - inline int _sprintf(char *const s, const char *const format, ...) { - cimg::mutex(6); - va_list args; - va_start(args,format); - const int result = std::vsprintf(s,format,args); - va_end(args); - cimg::mutex(6,0); - return result; - } - - inline int _snprintf(char *const s, const size_t n, const char *const format, ...) { - cimg::mutex(6); - va_list args; - va_start(args,format); - const int result = std::vsnprintf(s,n,format,args); - va_end(args); - cimg::mutex(6,0); - return result; - } - - inline int _vsnprintf(char *const s, const size_t size, const char* format, va_list ap) { - cimg::mutex(6); - const int result = std::vsnprintf(s,size,format,ap); - cimg::mutex(6,0); - return result; - } -#endif - - //! Set current \CImg exception mode. - /** - The way error messages are handled by \CImg can be changed dynamically, using this function. - \param mode Desired exception mode. Possible values are: - - \c 0: Hide library messages (quiet mode). - - \c 1: Print library messages on the console. - - \c 2: Display library messages on a dialog window (default behavior). - - \c 3: Do as \c 1 + add extra debug warnings (slow down the code!). - - \c 4: Do as \c 2 + add extra debug warnings (slow down the code!). - **/ - inline unsigned int& exception_mode(const unsigned int mode) { - return _exception_mode(mode,true); - } - - //! Return current \CImg exception mode. - /** - \note By default, return the value of configuration macro \c cimg_verbosity - **/ - inline unsigned int& exception_mode() { - return _exception_mode(0,false); - } - - //! Set current \CImg openmp mode. - /** - The way openmp-based methods are handled by \CImg can be changed dynamically, using this function. - \param mode Desired openmp mode. Possible values are: - - \c 0: Never parallelize (quiet mode). - - \c 1: Always parallelize. - - \c 2: Adaptive parallelization mode (default behavior). - **/ - inline unsigned int& _openmp_mode(const unsigned int value, const bool is_set) { - static unsigned int mode = 2; - if (is_set) { cimg::mutex(0); mode = value<2?value:2; cimg::mutex(0,0); } - return mode; - } - - inline unsigned int& openmp_mode(const unsigned int mode) { - return _openmp_mode(mode,true); - } - - //! Return current \CImg openmp mode. - inline unsigned int& openmp_mode() { - return _openmp_mode(0,false); - } - -#define cimg_openmp_if(cond) if (cimg::openmp_mode()==1 || (cimg::openmp_mode()>1 && (cond))) - - // Display a simple dialog box, and wait for the user's response. - inline int dialog(const char *const title, const char *const msg, const char *const button1_label="OK", - const char *const button2_label=0, const char *const button3_label=0, - const char *const button4_label=0, const char *const button5_label=0, - const char *const button6_label=0, const bool centering=false); - - // Evaluate math expression. - inline double eval(const char *const expression, - const double x=0, const double y=0, const double z=0, const double c=0); - - } - - /*--------------------------------------- - # - # Define the CImgException structures - # - --------------------------------------*/ - //! Instances of \c CImgException are thrown when errors are encountered in a \CImg function call. - /** - \par Overview - - CImgException is the base class of all exceptions thrown by \CImg (except \b CImgAbortException). - CImgException is never thrown itself. Derived classes that specify the type of errord are thrown instead. - These classes can be: - - - \b CImgAbortException: Thrown when a computationally-intensive function is aborted by an external signal. - This is the only \c non-derived exception class. - - - \b CImgArgumentException: Thrown when one argument of a called \CImg function is invalid. - This is probably one of the most thrown exception by \CImg. - For instance, the following example throws a \c CImgArgumentException: - \code - CImg img(100,100,1,3); // Define a 100x100 color image with float-valued pixels. - img.mirror('e'); // Try to mirror image along the (non-existing) 'e'-axis. - \endcode - - - \b CImgDisplayException: Thrown when something went wrong during the display of images in CImgDisplay instances. - - - \b CImgInstanceException: Thrown when an instance associated to a called \CImg method does not fit - the function requirements. For instance, the following example throws a \c CImgInstanceException: - \code - const CImg img; // Define an empty image. - const float value = img.at(0); // Try to read first pixel value (does not exist). - \endcode - - - \b CImgIOException: Thrown when an error occured when trying to load or save image files. - This happens when trying to read files that do not exist or with invalid formats. - For instance, the following example throws a \c CImgIOException: - \code - const CImg img("missing_file.jpg"); // Try to load a file that does not exist. - \endcode - - - \b CImgWarningException: Thrown only if configuration macro \c cimg_strict_warnings is set, and - when a \CImg function has to display a warning message (see cimg::warn()). - - It is not recommended to throw CImgException instances by yourself, - since they are expected to be thrown only by \CImg. - When an error occurs in a library function call, \CImg may display error messages on the screen or on the - standard output, depending on the current \CImg exception mode. - The \CImg exception mode can be get and set by functions cimg::exception_mode() and - cimg::exception_mode(unsigned int). - - \par Exceptions handling - - In all cases, when an error occurs in \CImg, an instance of the corresponding exception class is thrown. - This may lead the program to break (this is the default behavior), but you can bypass this behavior by - handling the exceptions by yourself, - using a usual try { ... } catch () { ... } bloc, as in the following example: - \code - #define "CImg.h" - using namespace cimg_library; - int main() { - cimg::exception_mode(0); // Enable quiet exception mode. - try { - ... // Here, do what you want to stress CImg. - } catch (CImgException& e) { // You succeeded: something went wrong! - std::fprintf(stderr,"CImg Library Error: %s",e.what()); // Display your custom error message. - ... // Do what you want now to save the ship! - } - } - \endcode - **/ - struct CImgException : public std::exception { -#define _cimg_exception_err(etype,disp_flag) \ - std::va_list ap, ap2; \ - va_start(ap,format); va_start(ap2,format); \ - int size = cimg_vsnprintf(0,0,format,ap2); \ - if (size++>=0) { \ - delete[] _message; \ - _message = new char[size]; \ - cimg_vsnprintf(_message,size,format,ap); \ - if (cimg::exception_mode()) { \ - std::fprintf(cimg::output(),"\n%s[CImg] *** %s ***%s %s\n",cimg::t_red,etype,cimg::t_normal,_message); \ - if (cimg_display && disp_flag && !(cimg::exception_mode()%2)) try { cimg::dialog(etype,_message,"Abort"); } \ - catch (CImgException&) {} \ - if (cimg::exception_mode()>=3) cimg_library_suffixed::cimg::info(); \ - } \ - } \ - va_end(ap); va_end(ap2); \ - - char *_message; - CImgException() { _message = new char[1]; *_message = 0; } - CImgException(const char *const format, ...):_message(0) { _cimg_exception_err("CImgException",true); } - CImgException(const CImgException& e):std::exception(e) { - const size_t size = std::strlen(e._message); - _message = new char[size + 1]; - std::strncpy(_message,e._message,size); - _message[size] = 0; - } - ~CImgException() throw() { delete[] _message; } - CImgException& operator=(const CImgException& e) { - const size_t size = std::strlen(e._message); - _message = new char[size + 1]; - std::strncpy(_message,e._message,size); - _message[size] = 0; - return *this; - } - //! Return a C-string containing the error message associated to the thrown exception. - const char *what() const throw() { return _message; } - }; - - // The CImgAbortException class is used to throw an exception when - // a computationally-intensive function has been aborted by an external signal. - struct CImgAbortException : public std::exception { - char *_message; - CImgAbortException() { _message = new char[1]; *_message = 0; } - CImgAbortException(const char *const format, ...):_message(0) { _cimg_exception_err("CImgAbortException",true); } - CImgAbortException(const CImgAbortException& e):std::exception(e) { - const size_t size = std::strlen(e._message); - _message = new char[size + 1]; - std::strncpy(_message,e._message,size); - _message[size] = 0; - } - ~CImgAbortException() throw() { delete[] _message; } - CImgAbortException& operator=(const CImgAbortException& e) { - const size_t size = std::strlen(e._message); - _message = new char[size + 1]; - std::strncpy(_message,e._message,size); - _message[size] = 0; - return *this; - } - //! Return a C-string containing the error message associated to the thrown exception. - const char *what() const throw() { return _message; } - }; - - // The CImgArgumentException class is used to throw an exception related - // to invalid arguments encountered in a library function call. - struct CImgArgumentException : public CImgException { - CImgArgumentException(const char *const format, ...) { _cimg_exception_err("CImgArgumentException",true); } - }; - - // The CImgDisplayException class is used to throw an exception related - // to display problems encountered in a library function call. - struct CImgDisplayException : public CImgException { - CImgDisplayException(const char *const format, ...) { _cimg_exception_err("CImgDisplayException",false); } - }; - - // The CImgInstanceException class is used to throw an exception related - // to an invalid instance encountered in a library function call. - struct CImgInstanceException : public CImgException { - CImgInstanceException(const char *const format, ...) { _cimg_exception_err("CImgInstanceException",true); } - }; - - // The CImgIOException class is used to throw an exception related - // to input/output file problems encountered in a library function call. - struct CImgIOException : public CImgException { - CImgIOException(const char *const format, ...) { _cimg_exception_err("CImgIOException",true); } - }; - - // The CImgWarningException class is used to throw an exception for warnings - // encountered in a library function call. - struct CImgWarningException : public CImgException { - CImgWarningException(const char *const format, ...) { _cimg_exception_err("CImgWarningException",false); } - }; - - /*------------------------------------- - # - # Define cimg:: namespace - # - -----------------------------------*/ - //! Contains \a low-level functions and variables of the \CImg Library. - /** - Most of the functions and variables within this namespace are used by the \CImg library for low-level operations. - You may use them to access specific const values or environment variables internally used by \CImg. - \warning Never write using namespace cimg_library::cimg; in your source code. Lot of functions in the - cimg:: namespace have the same names as standard C functions that may be defined in the global - namespace ::. - **/ - namespace cimg { - - // Define traits that will be used to determine the best data type to work in CImg functions. - // - template struct type { - static const char* string() { - static const char* s[] = { "unknown", "unknown8", "unknown16", "unknown24", - "unknown32", "unknown40", "unknown48", "unknown56", - "unknown64", "unknown72", "unknown80", "unknown88", - "unknown96", "unknown104", "unknown112", "unknown120", - "unknown128" }; - return s[(sizeof(T)<17)?sizeof(T):0]; - } - static bool is_float() { return false; } - static bool is_inf(const T) { return false; } - static bool is_nan(const T) { return false; } - static T min() { return ~max(); } - static T max() { return (T)1<<(8*sizeof(T) - 1); } - static T inf() { return max(); } - static T cut(const double val) { return val<(double)min()?min():val>(double)max()?max():(T)val; } - static const char* format() { return "%s"; } - static const char* format(const T& val) { static const char *const s = "unknown"; cimg::unused(val); return s; } - }; - - template<> struct type { - static const char* string() { static const char *const s = "bool"; return s; } - static bool is_float() { return false; } - static bool is_inf(const bool) { return false; } - static bool is_nan(const bool) { return false; } - static bool min() { return false; } - static bool max() { return true; } - static bool inf() { return max(); } - static bool is_inf() { return false; } - static bool cut(const double val) { return val<(double)min()?min():val>(double)max()?max():(bool)val; } - static const char* format() { return "%s"; } - static const char* format(const bool val) { static const char* s[] = { "false", "true" }; return s[val?1:0]; } - }; - - template<> struct type { - static const char* string() { static const char *const s = "unsigned char"; return s; } - static bool is_float() { return false; } - static bool is_inf(const unsigned char) { return false; } - static bool is_nan(const unsigned char) { return false; } - static unsigned char min() { return 0; } - static unsigned char max() { return (unsigned char)-1; } - static unsigned char inf() { return max(); } - static unsigned char cut(const double val) { - return val<(double)min()?min():val>(double)max()?max():(unsigned char)val; } - static const char* format() { return "%u"; } - static unsigned int format(const unsigned char val) { return (unsigned int)val; } - }; - -#if defined(CHAR_MAX) && CHAR_MAX==255 - template<> struct type { - static const char* string() { static const char *const s = "char"; return s; } - static bool is_float() { return false; } - static bool is_inf(const char) { return false; } - static bool is_nan(const char) { return false; } - static char min() { return 0; } - static char max() { return (char)-1; } - static char inf() { return max(); } - static char cut(const double val) { - return val<(double)min()?min():val>(double)max()?max():(unsigned char)val; } - static const char* format() { return "%u"; } - static unsigned int format(const char val) { return (unsigned int)val; } - }; -#else - template<> struct type { - static const char* string() { static const char *const s = "char"; return s; } - static bool is_float() { return false; } - static bool is_inf(const char) { return false; } - static bool is_nan(const char) { return false; } - static char min() { return ~max(); } - static char max() { return (char)((unsigned char)-1>>1); } - static char inf() { return max(); } - static char cut(const double val) { return val<(double)min()?min():val>(double)max()?max():(char)val; } - static const char* format() { return "%d"; } - static int format(const char val) { return (int)val; } - }; -#endif - - template<> struct type { - static const char* string() { static const char *const s = "signed char"; return s; } - static bool is_float() { return false; } - static bool is_inf(const signed char) { return false; } - static bool is_nan(const signed char) { return false; } - static signed char min() { return ~max(); } - static signed char max() { return (signed char)((unsigned char)-1>>1); } - static signed char inf() { return max(); } - static signed char cut(const double val) { - return val<(double)min()?min():val>(double)max()?max():(signed char)val; } - static const char* format() { return "%d"; } - static int format(const signed char val) { return (int)val; } - }; - - template<> struct type { - static const char* string() { static const char *const s = "unsigned short"; return s; } - static bool is_float() { return false; } - static bool is_inf(const unsigned short) { return false; } - static bool is_nan(const unsigned short) { return false; } - static unsigned short min() { return 0; } - static unsigned short max() { return (unsigned short)-1; } - static unsigned short inf() { return max(); } - static unsigned short cut(const double val) { - return val<(double)min()?min():val>(double)max()?max():(unsigned short)val; } - static const char* format() { return "%u"; } - static unsigned int format(const unsigned short val) { return (unsigned int)val; } - }; - - template<> struct type { - static const char* string() { static const char *const s = "short"; return s; } - static bool is_float() { return false; } - static bool is_inf(const short) { return false; } - static bool is_nan(const short) { return false; } - static short min() { return ~max(); } - static short max() { return (short)((unsigned short)-1>>1); } - static short inf() { return max(); } - static short cut(const double val) { return val<(double)min()?min():val>(double)max()?max():(short)val; } - static const char* format() { return "%d"; } - static int format(const short val) { return (int)val; } - }; - - template<> struct type { - static const char* string() { static const char *const s = "unsigned int"; return s; } - static bool is_float() { return false; } - static bool is_inf(const unsigned int) { return false; } - static bool is_nan(const unsigned int) { return false; } - static unsigned int min() { return 0; } - static unsigned int max() { return (unsigned int)-1; } - static unsigned int inf() { return max(); } - static unsigned int cut(const double val) { - return val<(double)min()?min():val>(double)max()?max():(unsigned int)val; } - static const char* format() { return "%u"; } - static unsigned int format(const unsigned int val) { return val; } - }; - - template<> struct type { - static const char* string() { static const char *const s = "int"; return s; } - static bool is_float() { return false; } - static bool is_inf(const int) { return false; } - static bool is_nan(const int) { return false; } - static int min() { return ~max(); } - static int max() { return (int)((unsigned int)-1>>1); } - static int inf() { return max(); } - static int cut(const double val) { return val<(double)min()?min():val>(double)max()?max():(int)val; } - static const char* format() { return "%d"; } - static int format(const int val) { return val; } - }; - - template<> struct type { - static const char* string() { static const char *const s = "unsigned int64"; return s; } - static bool is_float() { return false; } - static bool is_inf(const cimg_uint64) { return false; } - static bool is_nan(const cimg_uint64) { return false; } - static cimg_uint64 min() { return 0; } - static cimg_uint64 max() { return (cimg_uint64)-1; } - static cimg_uint64 inf() { return max(); } - static cimg_uint64 cut(const double val) { - return val<(double)min()?min():val>(double)max()?max():(cimg_uint64)val; } - static const char* format() { return "%lu"; } - static unsigned long format(const cimg_uint64 val) { return (unsigned long)val; } - }; - - template<> struct type { - static const char* string() { static const char *const s = "int64"; return s; } - static bool is_float() { return false; } - static bool is_inf(const cimg_int64) { return false; } - static bool is_nan(const cimg_int64) { return false; } - static cimg_int64 min() { return ~max(); } - static cimg_int64 max() { return (cimg_int64)((cimg_uint64)-1>>1); } - static cimg_int64 inf() { return max(); } - static cimg_int64 cut(const double val) { return val<(double)min()?min():val>(double)max()?max():(cimg_int64)val; } - static const char* format() { return "%ld"; } - static long format(const long val) { return (long)val; } - }; - - template<> struct type { - static const char* string() { static const char *const s = "double"; return s; } - static bool is_float() { return true; } - static bool is_inf(const double val) { -#ifdef isinf - return (bool)isinf(val); -#else - return !is_nan(val) && (val::min() || val>cimg::type::max()); -#endif - } - static bool is_nan(const double val) { -#ifdef isnan - return (bool)isnan(val); -#else - return !(val==val); -#endif - } - static double min() { return -DBL_MAX; } - static double max() { return DBL_MAX; } - static double inf() { -#ifdef INFINITY - return (double)INFINITY; -#else - return max()*max(); -#endif - } - static double nan() { -#ifdef NAN - return (double)NAN; -#else - const double val_nan = -std::sqrt(-1.0); return val_nan; -#endif - } - static double cut(const double val) { return valmax()?max():val; } - static const char* format() { return "%.16g"; } - static double format(const double val) { return val; } - }; - - template<> struct type { - static const char* string() { static const char *const s = "float"; return s; } - static bool is_float() { return true; } - static bool is_inf(const float val) { -#ifdef isinf - return (bool)isinf(val); -#else - return !is_nan(val) && (val::min() || val>cimg::type::max()); -#endif - } - static bool is_nan(const float val) { -#ifdef isnan - return (bool)isnan(val); -#else - return !(val==val); -#endif - } - static float min() { return -FLT_MAX; } - static float max() { return FLT_MAX; } - static float inf() { return (float)cimg::type::inf(); } - static float nan() { return (float)cimg::type::nan(); } - static float cut(const double val) { return val<(double)min()?min():val>(double)max()?max():(float)val; } - static const char* format() { return "%.16g"; } - static double format(const float val) { return (double)val; } - }; - - template<> struct type { - static const char* string() { static const char *const s = "long double"; return s; } - static bool is_float() { return true; } - static bool is_inf(const long double val) { -#ifdef isinf - return (bool)isinf(val); -#else - return !is_nan(val) && (val::min() || val>cimg::type::max()); -#endif - } - static bool is_nan(const long double val) { -#ifdef isnan - return (bool)isnan(val); -#else - return !(val==val); -#endif - } - static long double min() { return -LDBL_MAX; } - static long double max() { return LDBL_MAX; } - static long double inf() { return max()*max(); } - static long double nan() { const long double val_nan = -std::sqrt(-1.0L); return val_nan; } - static long double cut(const long double val) { return valmax()?max():val; } - static const char* format() { return "%.16g"; } - static double format(const long double val) { return (double)val; } - }; - - template struct superset { typedef T type; }; - template<> struct superset { typedef unsigned char type; }; - template<> struct superset { typedef char type; }; - template<> struct superset { typedef signed char type; }; - template<> struct superset { typedef unsigned short type; }; - template<> struct superset { typedef short type; }; - template<> struct superset { typedef unsigned int type; }; - template<> struct superset { typedef int type; }; - template<> struct superset { typedef cimg_uint64 type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef float type; }; - template<> struct superset { typedef double type; }; - template<> struct superset { typedef short type; }; - template<> struct superset { typedef short type; }; - template<> struct superset { typedef unsigned short type; }; - template<> struct superset { typedef short type; }; - template<> struct superset { typedef unsigned int type; }; - template<> struct superset { typedef int type; }; - template<> struct superset { typedef cimg_uint64 type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef float type; }; - template<> struct superset { typedef double type; }; - template<> struct superset { typedef short type; }; - template<> struct superset { typedef short type; }; - template<> struct superset { typedef int type; }; - template<> struct superset { typedef short type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef int type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef float type; }; - template<> struct superset { typedef double type; }; - template<> struct superset { typedef short type; }; - template<> struct superset { typedef short type; }; - template<> struct superset { typedef int type; }; - template<> struct superset { typedef short type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef int type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef float type; }; - template<> struct superset { typedef double type; }; - template<> struct superset { typedef int type; }; - template<> struct superset { typedef int type; }; - template<> struct superset { typedef int type; }; - template<> struct superset { typedef unsigned int type; }; - template<> struct superset { typedef int type; }; - template<> struct superset { typedef cimg_uint64 type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef float type; }; - template<> struct superset { typedef double type; }; - template<> struct superset { typedef int type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef int type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef float type; }; - template<> struct superset { typedef double type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef cimg_uint64 type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef float type; }; - template<> struct superset { typedef double type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef float type; }; - template<> struct superset { typedef double type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef cimg_int64 type; }; - template<> struct superset { typedef double type; }; - template<> struct superset { typedef double type; }; - template<> struct superset { typedef double type; }; - template<> struct superset { typedef double type; }; - template<> struct superset { typedef double type; }; - - template struct superset2 { - typedef typename superset::type>::type type; - }; - - template struct superset3 { - typedef typename superset::type>::type type; - }; - - template struct last { typedef t2 type; }; - -#define _cimg_Tt typename cimg::superset::type -#define _cimg_Tfloat typename cimg::superset::type -#define _cimg_Ttfloat typename cimg::superset2::type -#define _cimg_Ttdouble typename cimg::superset2::type - - // Define variables used internally by CImg. -#if cimg_display==1 - struct X11_info { - unsigned int nb_wins; - pthread_t *events_thread; - pthread_cond_t wait_event; - pthread_mutex_t wait_event_mutex; - CImgDisplay **wins; - Display *display; - unsigned int nb_bits; - bool is_blue_first; - bool is_shm_enabled; - bool byte_order; -#ifdef cimg_use_xrandr - XRRScreenSize *resolutions; - Rotation curr_rotation; - unsigned int curr_resolution; - unsigned int nb_resolutions; -#endif - X11_info():nb_wins(0),events_thread(0),display(0), - nb_bits(0),is_blue_first(false),is_shm_enabled(false),byte_order(false) { -#ifdef __FreeBSD__ - XInitThreads(); -#endif - wins = new CImgDisplay*[1024]; - pthread_mutex_init(&wait_event_mutex,0); - pthread_cond_init(&wait_event,0); -#ifdef cimg_use_xrandr - resolutions = 0; - curr_rotation = 0; - curr_resolution = nb_resolutions = 0; -#endif - } - - ~X11_info() { - delete[] wins; - /* - if (events_thread) { - pthread_cancel(*events_thread); - delete events_thread; - } - if (display) { } // XCloseDisplay(display); } - pthread_cond_destroy(&wait_event); - pthread_mutex_unlock(&wait_event_mutex); - pthread_mutex_destroy(&wait_event_mutex); - */ - } - }; -#if defined(cimg_module) - X11_info& X11_attr(); -#elif defined(cimg_main) - X11_info& X11_attr() { static X11_info val; return val; } -#else - inline X11_info& X11_attr() { static X11_info val; return val; } -#endif -#define cimg_lock_display() cimg::mutex(15) -#define cimg_unlock_display() cimg::mutex(15,0) - -#elif cimg_display==2 - struct Win32_info { - HANDLE wait_event; - Win32_info() { wait_event = CreateEvent(0,FALSE,FALSE,0); } - }; -#if defined(cimg_module) - Win32_info& Win32_attr(); -#elif defined(cimg_main) - Win32_info& Win32_attr() { static Win32_info val; return val; } -#else - inline Win32_info& Win32_attr() { static Win32_info val; return val; } -#endif -#endif - - struct Mutex_info { -#if cimg_OS==2 - HANDLE mutex[32]; - Mutex_info() { for (unsigned int i = 0; i<32; ++i) mutex[i] = CreateMutex(0,FALSE,0); } - void lock(const unsigned int n) { WaitForSingleObject(mutex[n],INFINITE); } - void unlock(const unsigned int n) { ReleaseMutex(mutex[n]); } - int trylock(const unsigned int) { return 0; } -#elif defined(_PTHREAD_H) - pthread_mutex_t mutex[32]; - Mutex_info() { for (unsigned int i = 0; i<32; ++i) pthread_mutex_init(&mutex[i],0); } - void lock(const unsigned int n) { pthread_mutex_lock(&mutex[n]); } - void unlock(const unsigned int n) { pthread_mutex_unlock(&mutex[n]); } - int trylock(const unsigned int n) { return pthread_mutex_trylock(&mutex[n]); } -#else - Mutex_info() {} - void lock(const unsigned int) {} - void unlock(const unsigned int) {} - int trylock(const unsigned int) { return 0; } -#endif - }; - -#ifndef WIN32 -# define SOFACIMG_EXPORT_DYNAMIC_LIBRARY -# define SOFACIMG_IMPORT_DYNAMIC_LIBRARY -#else -# define SOFACIMG_EXPORT_DYNAMIC_LIBRARY __declspec( dllexport ) -# define SOFACIMG_IMPORT_DYNAMIC_LIBRARY __declspec( dllimport ) -# ifdef _MSC_VER -# pragma warning(disable : 4231) -# pragma warning(disable : 4910) -# endif -#endif - -#if defined(cimg_module) - extern "C" { - SOFACIMG_IMPORT_DYNAMIC_LIBRARY Mutex_info& Mutex_attr(); - } -#elif defined(cimg_main) - SOFACIMG_EXPORT_DYNAMIC_LIBRARY Mutex_info& Mutex_attr() { static Mutex_info val; return val; } -#else - inline Mutex_info& Mutex_attr() { static Mutex_info val; return val; } -#endif - -#if defined(cimg_use_magick) - static struct Magick_info { - Magick_info() { - Magick::InitializeMagick(""); - } - } _Magick_info; -#endif - -#if cimg_display==1 - // Define keycodes for X11-based graphical systems. - const unsigned int keyESC = XK_Escape; - const unsigned int keyF1 = XK_F1; - const unsigned int keyF2 = XK_F2; - const unsigned int keyF3 = XK_F3; - const unsigned int keyF4 = XK_F4; - const unsigned int keyF5 = XK_F5; - const unsigned int keyF6 = XK_F6; - const unsigned int keyF7 = XK_F7; - const unsigned int keyF8 = XK_F8; - const unsigned int keyF9 = XK_F9; - const unsigned int keyF10 = XK_F10; - const unsigned int keyF11 = XK_F11; - const unsigned int keyF12 = XK_F12; - const unsigned int keyPAUSE = XK_Pause; - const unsigned int key1 = XK_1; - const unsigned int key2 = XK_2; - const unsigned int key3 = XK_3; - const unsigned int key4 = XK_4; - const unsigned int key5 = XK_5; - const unsigned int key6 = XK_6; - const unsigned int key7 = XK_7; - const unsigned int key8 = XK_8; - const unsigned int key9 = XK_9; - const unsigned int key0 = XK_0; - const unsigned int keyBACKSPACE = XK_BackSpace; - const unsigned int keyINSERT = XK_Insert; - const unsigned int keyHOME = XK_Home; - const unsigned int keyPAGEUP = XK_Page_Up; - const unsigned int keyTAB = XK_Tab; - const unsigned int keyQ = XK_q; - const unsigned int keyW = XK_w; - const unsigned int keyE = XK_e; - const unsigned int keyR = XK_r; - const unsigned int keyT = XK_t; - const unsigned int keyY = XK_y; - const unsigned int keyU = XK_u; - const unsigned int keyI = XK_i; - const unsigned int keyO = XK_o; - const unsigned int keyP = XK_p; - const unsigned int keyDELETE = XK_Delete; - const unsigned int keyEND = XK_End; - const unsigned int keyPAGEDOWN = XK_Page_Down; - const unsigned int keyCAPSLOCK = XK_Caps_Lock; - const unsigned int keyA = XK_a; - const unsigned int keyS = XK_s; - const unsigned int keyD = XK_d; - const unsigned int keyF = XK_f; - const unsigned int keyG = XK_g; - const unsigned int keyH = XK_h; - const unsigned int keyJ = XK_j; - const unsigned int keyK = XK_k; - const unsigned int keyL = XK_l; - const unsigned int keyENTER = XK_Return; - const unsigned int keySHIFTLEFT = XK_Shift_L; - const unsigned int keyZ = XK_z; - const unsigned int keyX = XK_x; - const unsigned int keyC = XK_c; - const unsigned int keyV = XK_v; - const unsigned int keyB = XK_b; - const unsigned int keyN = XK_n; - const unsigned int keyM = XK_m; - const unsigned int keySHIFTRIGHT = XK_Shift_R; - const unsigned int keyARROWUP = XK_Up; - const unsigned int keyCTRLLEFT = XK_Control_L; - const unsigned int keyAPPLEFT = XK_Super_L; - const unsigned int keyALT = XK_Alt_L; - const unsigned int keySPACE = XK_space; - const unsigned int keyALTGR = XK_Alt_R; - const unsigned int keyAPPRIGHT = XK_Super_R; - const unsigned int keyMENU = XK_Menu; - const unsigned int keyCTRLRIGHT = XK_Control_R; - const unsigned int keyARROWLEFT = XK_Left; - const unsigned int keyARROWDOWN = XK_Down; - const unsigned int keyARROWRIGHT = XK_Right; - const unsigned int keyPAD0 = XK_KP_0; - const unsigned int keyPAD1 = XK_KP_1; - const unsigned int keyPAD2 = XK_KP_2; - const unsigned int keyPAD3 = XK_KP_3; - const unsigned int keyPAD4 = XK_KP_4; - const unsigned int keyPAD5 = XK_KP_5; - const unsigned int keyPAD6 = XK_KP_6; - const unsigned int keyPAD7 = XK_KP_7; - const unsigned int keyPAD8 = XK_KP_8; - const unsigned int keyPAD9 = XK_KP_9; - const unsigned int keyPADADD = XK_KP_Add; - const unsigned int keyPADSUB = XK_KP_Subtract; - const unsigned int keyPADMUL = XK_KP_Multiply; - const unsigned int keyPADDIV = XK_KP_Divide; - -#elif cimg_display==2 - // Define keycodes for Windows. - const unsigned int keyESC = VK_ESCAPE; - const unsigned int keyF1 = VK_F1; - const unsigned int keyF2 = VK_F2; - const unsigned int keyF3 = VK_F3; - const unsigned int keyF4 = VK_F4; - const unsigned int keyF5 = VK_F5; - const unsigned int keyF6 = VK_F6; - const unsigned int keyF7 = VK_F7; - const unsigned int keyF8 = VK_F8; - const unsigned int keyF9 = VK_F9; - const unsigned int keyF10 = VK_F10; - const unsigned int keyF11 = VK_F11; - const unsigned int keyF12 = VK_F12; - const unsigned int keyPAUSE = VK_PAUSE; - const unsigned int key1 = '1'; - const unsigned int key2 = '2'; - const unsigned int key3 = '3'; - const unsigned int key4 = '4'; - const unsigned int key5 = '5'; - const unsigned int key6 = '6'; - const unsigned int key7 = '7'; - const unsigned int key8 = '8'; - const unsigned int key9 = '9'; - const unsigned int key0 = '0'; - const unsigned int keyBACKSPACE = VK_BACK; - const unsigned int keyINSERT = VK_INSERT; - const unsigned int keyHOME = VK_HOME; - const unsigned int keyPAGEUP = VK_PRIOR; - const unsigned int keyTAB = VK_TAB; - const unsigned int keyQ = 'Q'; - const unsigned int keyW = 'W'; - const unsigned int keyE = 'E'; - const unsigned int keyR = 'R'; - const unsigned int keyT = 'T'; - const unsigned int keyY = 'Y'; - const unsigned int keyU = 'U'; - const unsigned int keyI = 'I'; - const unsigned int keyO = 'O'; - const unsigned int keyP = 'P'; - const unsigned int keyDELETE = VK_DELETE; - const unsigned int keyEND = VK_END; - const unsigned int keyPAGEDOWN = VK_NEXT; - const unsigned int keyCAPSLOCK = VK_CAPITAL; - const unsigned int keyA = 'A'; - const unsigned int keyS = 'S'; - const unsigned int keyD = 'D'; - const unsigned int keyF = 'F'; - const unsigned int keyG = 'G'; - const unsigned int keyH = 'H'; - const unsigned int keyJ = 'J'; - const unsigned int keyK = 'K'; - const unsigned int keyL = 'L'; - const unsigned int keyENTER = VK_RETURN; - const unsigned int keySHIFTLEFT = VK_SHIFT; - const unsigned int keyZ = 'Z'; - const unsigned int keyX = 'X'; - const unsigned int keyC = 'C'; - const unsigned int keyV = 'V'; - const unsigned int keyB = 'B'; - const unsigned int keyN = 'N'; - const unsigned int keyM = 'M'; - const unsigned int keySHIFTRIGHT = VK_SHIFT; - const unsigned int keyARROWUP = VK_UP; - const unsigned int keyCTRLLEFT = VK_CONTROL; - const unsigned int keyAPPLEFT = VK_LWIN; - const unsigned int keyALT = VK_LMENU; - const unsigned int keySPACE = VK_SPACE; - const unsigned int keyALTGR = VK_CONTROL; - const unsigned int keyAPPRIGHT = VK_RWIN; - const unsigned int keyMENU = VK_APPS; - const unsigned int keyCTRLRIGHT = VK_CONTROL; - const unsigned int keyARROWLEFT = VK_LEFT; - const unsigned int keyARROWDOWN = VK_DOWN; - const unsigned int keyARROWRIGHT = VK_RIGHT; - const unsigned int keyPAD0 = 0x60; - const unsigned int keyPAD1 = 0x61; - const unsigned int keyPAD2 = 0x62; - const unsigned int keyPAD3 = 0x63; - const unsigned int keyPAD4 = 0x64; - const unsigned int keyPAD5 = 0x65; - const unsigned int keyPAD6 = 0x66; - const unsigned int keyPAD7 = 0x67; - const unsigned int keyPAD8 = 0x68; - const unsigned int keyPAD9 = 0x69; - const unsigned int keyPADADD = VK_ADD; - const unsigned int keyPADSUB = VK_SUBTRACT; - const unsigned int keyPADMUL = VK_MULTIPLY; - const unsigned int keyPADDIV = VK_DIVIDE; - -#else - // Define random keycodes when no display is available. - // (should rarely be used then!). - const unsigned int keyESC = 1U; //!< Keycode for the \c ESC key (architecture-dependent). - const unsigned int keyF1 = 2U; //!< Keycode for the \c F1 key (architecture-dependent). - const unsigned int keyF2 = 3U; //!< Keycode for the \c F2 key (architecture-dependent). - const unsigned int keyF3 = 4U; //!< Keycode for the \c F3 key (architecture-dependent). - const unsigned int keyF4 = 5U; //!< Keycode for the \c F4 key (architecture-dependent). - const unsigned int keyF5 = 6U; //!< Keycode for the \c F5 key (architecture-dependent). - const unsigned int keyF6 = 7U; //!< Keycode for the \c F6 key (architecture-dependent). - const unsigned int keyF7 = 8U; //!< Keycode for the \c F7 key (architecture-dependent). - const unsigned int keyF8 = 9U; //!< Keycode for the \c F8 key (architecture-dependent). - const unsigned int keyF9 = 10U; //!< Keycode for the \c F9 key (architecture-dependent). - const unsigned int keyF10 = 11U; //!< Keycode for the \c F10 key (architecture-dependent). - const unsigned int keyF11 = 12U; //!< Keycode for the \c F11 key (architecture-dependent). - const unsigned int keyF12 = 13U; //!< Keycode for the \c F12 key (architecture-dependent). - const unsigned int keyPAUSE = 14U; //!< Keycode for the \c PAUSE key (architecture-dependent). - const unsigned int key1 = 15U; //!< Keycode for the \c 1 key (architecture-dependent). - const unsigned int key2 = 16U; //!< Keycode for the \c 2 key (architecture-dependent). - const unsigned int key3 = 17U; //!< Keycode for the \c 3 key (architecture-dependent). - const unsigned int key4 = 18U; //!< Keycode for the \c 4 key (architecture-dependent). - const unsigned int key5 = 19U; //!< Keycode for the \c 5 key (architecture-dependent). - const unsigned int key6 = 20U; //!< Keycode for the \c 6 key (architecture-dependent). - const unsigned int key7 = 21U; //!< Keycode for the \c 7 key (architecture-dependent). - const unsigned int key8 = 22U; //!< Keycode for the \c 8 key (architecture-dependent). - const unsigned int key9 = 23U; //!< Keycode for the \c 9 key (architecture-dependent). - const unsigned int key0 = 24U; //!< Keycode for the \c 0 key (architecture-dependent). - const unsigned int keyBACKSPACE = 25U; //!< Keycode for the \c BACKSPACE key (architecture-dependent). - const unsigned int keyINSERT = 26U; //!< Keycode for the \c INSERT key (architecture-dependent). - const unsigned int keyHOME = 27U; //!< Keycode for the \c HOME key (architecture-dependent). - const unsigned int keyPAGEUP = 28U; //!< Keycode for the \c PAGEUP key (architecture-dependent). - const unsigned int keyTAB = 29U; //!< Keycode for the \c TAB key (architecture-dependent). - const unsigned int keyQ = 30U; //!< Keycode for the \c Q key (architecture-dependent). - const unsigned int keyW = 31U; //!< Keycode for the \c W key (architecture-dependent). - const unsigned int keyE = 32U; //!< Keycode for the \c E key (architecture-dependent). - const unsigned int keyR = 33U; //!< Keycode for the \c R key (architecture-dependent). - const unsigned int keyT = 34U; //!< Keycode for the \c T key (architecture-dependent). - const unsigned int keyY = 35U; //!< Keycode for the \c Y key (architecture-dependent). - const unsigned int keyU = 36U; //!< Keycode for the \c U key (architecture-dependent). - const unsigned int keyI = 37U; //!< Keycode for the \c I key (architecture-dependent). - const unsigned int keyO = 38U; //!< Keycode for the \c O key (architecture-dependent). - const unsigned int keyP = 39U; //!< Keycode for the \c P key (architecture-dependent). - const unsigned int keyDELETE = 40U; //!< Keycode for the \c DELETE key (architecture-dependent). - const unsigned int keyEND = 41U; //!< Keycode for the \c END key (architecture-dependent). - const unsigned int keyPAGEDOWN = 42U; //!< Keycode for the \c PAGEDOWN key (architecture-dependent). - const unsigned int keyCAPSLOCK = 43U; //!< Keycode for the \c CAPSLOCK key (architecture-dependent). - const unsigned int keyA = 44U; //!< Keycode for the \c A key (architecture-dependent). - const unsigned int keyS = 45U; //!< Keycode for the \c S key (architecture-dependent). - const unsigned int keyD = 46U; //!< Keycode for the \c D key (architecture-dependent). - const unsigned int keyF = 47U; //!< Keycode for the \c F key (architecture-dependent). - const unsigned int keyG = 48U; //!< Keycode for the \c G key (architecture-dependent). - const unsigned int keyH = 49U; //!< Keycode for the \c H key (architecture-dependent). - const unsigned int keyJ = 50U; //!< Keycode for the \c J key (architecture-dependent). - const unsigned int keyK = 51U; //!< Keycode for the \c K key (architecture-dependent). - const unsigned int keyL = 52U; //!< Keycode for the \c L key (architecture-dependent). - const unsigned int keyENTER = 53U; //!< Keycode for the \c ENTER key (architecture-dependent). - const unsigned int keySHIFTLEFT = 54U; //!< Keycode for the \c SHIFTLEFT key (architecture-dependent). - const unsigned int keyZ = 55U; //!< Keycode for the \c Z key (architecture-dependent). - const unsigned int keyX = 56U; //!< Keycode for the \c X key (architecture-dependent). - const unsigned int keyC = 57U; //!< Keycode for the \c C key (architecture-dependent). - const unsigned int keyV = 58U; //!< Keycode for the \c V key (architecture-dependent). - const unsigned int keyB = 59U; //!< Keycode for the \c B key (architecture-dependent). - const unsigned int keyN = 60U; //!< Keycode for the \c N key (architecture-dependent). - const unsigned int keyM = 61U; //!< Keycode for the \c M key (architecture-dependent). - const unsigned int keySHIFTRIGHT = 62U; //!< Keycode for the \c SHIFTRIGHT key (architecture-dependent). - const unsigned int keyARROWUP = 63U; //!< Keycode for the \c ARROWUP key (architecture-dependent). - const unsigned int keyCTRLLEFT = 64U; //!< Keycode for the \c CTRLLEFT key (architecture-dependent). - const unsigned int keyAPPLEFT = 65U; //!< Keycode for the \c APPLEFT key (architecture-dependent). - const unsigned int keyALT = 66U; //!< Keycode for the \c ALT key (architecture-dependent). - const unsigned int keySPACE = 67U; //!< Keycode for the \c SPACE key (architecture-dependent). - const unsigned int keyALTGR = 68U; //!< Keycode for the \c ALTGR key (architecture-dependent). - const unsigned int keyAPPRIGHT = 69U; //!< Keycode for the \c APPRIGHT key (architecture-dependent). - const unsigned int keyMENU = 70U; //!< Keycode for the \c MENU key (architecture-dependent). - const unsigned int keyCTRLRIGHT = 71U; //!< Keycode for the \c CTRLRIGHT key (architecture-dependent). - const unsigned int keyARROWLEFT = 72U; //!< Keycode for the \c ARROWLEFT key (architecture-dependent). - const unsigned int keyARROWDOWN = 73U; //!< Keycode for the \c ARROWDOWN key (architecture-dependent). - const unsigned int keyARROWRIGHT = 74U; //!< Keycode for the \c ARROWRIGHT key (architecture-dependent). - const unsigned int keyPAD0 = 75U; //!< Keycode for the \c PAD0 key (architecture-dependent). - const unsigned int keyPAD1 = 76U; //!< Keycode for the \c PAD1 key (architecture-dependent). - const unsigned int keyPAD2 = 77U; //!< Keycode for the \c PAD2 key (architecture-dependent). - const unsigned int keyPAD3 = 78U; //!< Keycode for the \c PAD3 key (architecture-dependent). - const unsigned int keyPAD4 = 79U; //!< Keycode for the \c PAD4 key (architecture-dependent). - const unsigned int keyPAD5 = 80U; //!< Keycode for the \c PAD5 key (architecture-dependent). - const unsigned int keyPAD6 = 81U; //!< Keycode for the \c PAD6 key (architecture-dependent). - const unsigned int keyPAD7 = 82U; //!< Keycode for the \c PAD7 key (architecture-dependent). - const unsigned int keyPAD8 = 83U; //!< Keycode for the \c PAD8 key (architecture-dependent). - const unsigned int keyPAD9 = 84U; //!< Keycode for the \c PAD9 key (architecture-dependent). - const unsigned int keyPADADD = 85U; //!< Keycode for the \c PADADD key (architecture-dependent). - const unsigned int keyPADSUB = 86U; //!< Keycode for the \c PADSUB key (architecture-dependent). - const unsigned int keyPADMUL = 87U; //!< Keycode for the \c PADMUL key (architecture-dependent). - const unsigned int keyPADDIV = 88U; //!< Keycode for the \c PADDDIV key (architecture-dependent). -#endif - - const double PI = 3.14159265358979323846; //!< Value of the mathematical constant PI - - // Define a 12x13 font (small size). - static const char *const data_font12x13 = -" .wjwlwmyuw>wjwkwbwjwkwRxuwmwjwkwmyuwJwjwlx`w Fw mwlwlwuwnwuynwuwmyTwlwkwuwmwuwnwlwkwuwmwuw_wuxl" -"wlwkwuwnwuynwuwTwlwlwtwnwtwnw my Qw +wlw b{ \\w Wx`xTw_w[wbxawSwkw nynwkyw bwswcwkwuwjwuwozpwtwuwnwtwowkwjwmwuwuwkwIxmxuxowuwmwswowswmxnwjwhwowswowsw0wmwowswuwnwrwowswpwswowkwjwrwqw" -"rwpwkwkwtwnwkxsxqxswowswpwswnwswpwswowrwnwmwrwqwqwqwswswrwswowswjwpwlxjwkxuxLw[wcw_wSwkw mw\"wlwiw=wtwmxlwFw cwswnwuwnwkwjwswo{pwrwpwtwtwpwswby`w`yUwlw" -"twpwqwpwswowlw\\wrwrxuwHwrwfwuwjwlwlwTyuwVwlwtwawswowswowswcwuwmwuwmwuwmwuwmwuwlwkwuwnwswpwkwkwkwkwkwkwkwkwswoxswowswowswowswowswowswowrwpwswpwrwpwrwpw" -"rwpwrwpwswoznwtw Ww (wGwtwtwqwqwqwuwuwuwqwswuwqwqw=wqxtw`{nzp~q{ozowrwnxmwtwow bzawkwuwl}rwuwnwtwuwnwtwowkwjwlyjwIwlwswmwiwkwnwuwnwkwhwnwswowswowkwew" -"ewixnwsytwswuwnwrwpwkwrwpwkwkwkwrwpwkwkwuwmwkxsxqwuwtwpwqwqwswowqwqwswowiwmwrwpwswowtwtwpwuwmwuwjwowkwjwlxsxXynzmymznyozlzoznwkwkwtwnwkzuyrzmynzmzowux" -"myozmwswpwrwowtwtwrwrwpwrwp{mwlwiwHyuwpwtwkwmxlynzoxswmwmwswnwswowtxq|owtwtwpym{p{owswnwuwmwlwkwqwqxuwuxqwrwpwtwtwqwqwowlwuwuwkwmwlwtwowuwuwdwjznwl{nw" -"uwnwkx_wtxtwswtwlwtwWwuytwgyjwmwjwawswoyuwVwlwtwnwtwmwtwnwtwmwuwmwlwuwmwuwmwuwmwuwmwuwmwuwmxuwowkwkwkwkwkwkwkwkwkwrwpwuwtwpwqwqwqwqwqwqwqwqwqwowtwpwsw" -"uwqwrwpwrwpwrwpwrwowuwnwswowuwlymymymymymymyuyqymymymymynwkwkwkwjynzmymymymymykwmzowswowswowswowswpwrwozowrwW}q}qwtwtwqwtwtwqwtwtwA}rwuw_{p~r~r}pwtwow" -"rwnxmwtwow aw_w]wtwpwuwmxuwmybwjwlyjwIwlwswmwiwnynwtwnznzkwmynwswTyp}pylwmwtwtwtwswuwn{owkwrwp{o{owk|pwkwkxlwkwuwuwuwqwuwtwpwqwqwswowqwqwswoykwmwrwpws" -"wowuwuwuwowkwjwnwkwjwDwowswowkwswowswowkwswowswowkwkwuwmwkwswswswswowswowswowswoxlwswowkwswpwrwowtwtwqwtwowrwlwoxkwhxVxuxpwtypwuwjwnwtwnwkwswowtxnxmws" -"wowqwqwtwuxqwtwnwtwtwqwswowswmwm{nwuwlxnwkwqwqwtwtwqwrwpwtwtwqwuyuwpwiwhwnwmwrwnwbwkwuwlwlwswoxuxowlwtw`wuwrwszmwtwo}dwuwtwuw[}qymx`wswoyuwow_ylxlwtwo" -"yuwoyuwoyuwmwlwuwmwuwmwuwmwuwmwuwmwuwmwt{swk{o{o{o{owkwkwkwlztwpwuwtwpwqwqwqwqwqwqwqwqwqwnxowtwtwqwrwpwrwpwrwpwrwnwmwswowuwiwkwkwkwkwkwkwswswkwswowswo" -"wswowswowkwkwkwkwswowswowswowswowswowswowswcwtxowswowswowswowswpwrwowswpwrwWwtwtwqwqwqwuwuwuwqwuwswqwqw>wowuw`}q~q|q}qwrwpwrwowtwnwtwo~ izaw]wtwoykwux" -"qwtwswfwjwmwuwuwn}eyaxlwswmwjwjwpwswjwowswmwmwswnzWy]ypwlwtwtwuwswswowrwpwkwrwpwkwkwsyqwrwpwkwkwuwmwkwuwuwuwqwtwuwpwqwqznwqwqzkynwmwrwowuwnwuwuwuwowkw" -"jwnwkxkwGzowswowkwswo{owkwswowswowkwkxlwkwswswswswowswowswowswowjxmwkwswowtwnwuwuwuwpxmwtwlwlwlwiwlytwewtwtwqwswowtxoznwswnxmwswnwuwmwuwnwswowtwtwqwtw" -"twqwtwnwtwtwqwswowswmwmwswowswmwmwkwqwqwtwtwqwrwowuwuwpwuyuwq~own~own~owbwkwuwmznwswmwbwswawuwrwgwtwhwdwuytwXwJwswnxuw=wtwmwswowtxowswqxmwswowswowswow" -"swowswowswnwtwowkwkwkwkwkwkwkwkwkwrwpwtwuwpwqwqwqwqwqwqwqwqwqwnxowtwtwqwrwpwrwpwrwpwrwnwmwswowtwmznznznznznzn~swk{o{o{o{owkwkwkwkwswowswowswowswowswow" -"swowswo}qwuwuwowswowswowswowswowtwnwswowtwUwuwuwowswowswowswowsw@}qx`}q~pzo{pwrwpwrwowtwnwtwow aw_w_}owuwmwuwtwrwswuwewjwkwiwJwkwswmwkwiwp|kwowswmwmws" -"wkwWym}mypwlwszr{owrwpwkwrwpwkwkwqwqwrwpwkwkwtwnwkwtwtwqwtwuwpwqwqwkwqwqwtwiwnwmwrwowuwnwuwuwuwpwuwlwkwmwjwkwHwswowswowkwswowkwkwswowswowkwkwuwmwkwsws" -"wswswowswowswowswowhwnwkwswowtwnwuwuwuwpxmwtwmwkwlwiwmwtydwtwtwqwswowswowtwnwswowkwswnwuwnwtwnwswowtwtwqwtwtwqwtwnwtwtwqwswowswmwmwswowswnwlwkwqwqxuwu" -"xqwrwnyowqwpwiwhwpwuwuwowrwpwuwuwdwkwuwlwlwswo{owkxuwawtxtwszmwtwiwdwuwtwuwXwJwswmwuwKzmwtwlwtxowrwpwtxrxl{o{o{o{o{o{o{owkwkwkwkwkwkwkwkwkwrwpwtwuwpwq" -"wqwqwqwqwqwqwqwqwowtwpwuwswqwrwpwrwpwrwpwrwnwmznwswowswowswowswowswowswowswowswowkwkwkwkwkwkwkwkwkwswowswowswowswowswowswowswcwuwuwowswowswowswowswowt" -"wnwswowtwTymymymymy=wmw^wuwuwmxlxmyowrwowtwnwtwmxmw bwswIwuwmwuwmwuwtwrxswdwjw]wJwkxuxmwlwlwswlwjwowswmwmwswlwSycyawlwswowrwowswpwswowkwjwrwqwrwpwkwkw" -"swowkwqwqwsxowswpwjwswpwswowrwnwmxtxnwlwswpwswmwlwlwjwkwHwswowswowkwswowswowkwswowswowkwkwtwnwkwswswswswowswowswowswowkwswowkwswnxlwswpwtwmxmwjwlwiwTx" -"uxpwtxowswowtwnwswowkwswnynwtwnwswowtwtwqxuwuxqwtwnwtwtwqwswowswmwlwuwnwswowkwjwswo{pwrwmwmwswnwjwiwnymwtwnycwkwuwlwl{mwmwiw_wrwdwtwVwrw*wswmwuw?wtwlw" -"tzqwrwpwtzswkwswowswowswowswowswowswowswnwswpwkwkwkwkwkwkwkwkwswowsxowswowswowswowswowswowrwpwswpxtxpxtxpxtxpxtxnwmwkwswowswowswowswowswowswowswowtxow" -"kwswowswowswowswowkwkwkwkwswowswowswowswowswowswowswlwnxtwowswowswowswowswnxmwswnx >wlw\\wkx`wnwrwoznwtwmxl| gybw^wtwozmwsxpzuxfxlx]wnw_wlxjyn{o{nykwnz" -"mymwkynymwkwewewjwjwrwswqwp{myozn{owizpwrwpwkwkwrwp{owqwqwsxnyowiyowrwozmwlzmwlwswqxsxnwm}qwjxlwGzozmymznynwjzowswowkwkwswowkwswswswswnynzmzowjymxlznx" -"lwswqwrwnwm{mwlwiwHxuxpzmxlymynwswmwnwrwozmxuxo{pwtxn{pzmykwmyo}p{owkyuynwnwrwmwly`w_w_wbwjzo{pwqwnwmwhw_z>zY}M|nwuw2wqwqwryrwqwqyowqwqwqwqwqwqwqwqwqw" -"qwqwqwr{qyo{o{o{o{owkwkwkwkznwsxnymymymymycwuynznznznzmwmwkwuynznznznznznznyuzrymymymymynwkwkwkwjynwswnymymymymybzmznznznznwlzmw hwHwlwSwTw {+qnrmqapmp Kpepgpiuhpephscqfqhqfqhqfqhqfqhqfqhqfqhqixgudxdxdxdxdq]q]q]q]wcqjr" -"bt`t`t`t`taphpgplt`s_s_s_s_q`q]qmsctnqctnqctnqctnqctnqctnqbsktgs_uauauaucq]q]q]q[saqjqbs_s_s_s_sNpms_snqbsnqbsnqbsnqaq`qns_q !p Zp jp#q\\q6q7q l" -"q [sjq Qq -q OqZq]q Cq;q HqWq $rIq`qZq _q iqbqKqFqIq`q hp$q]u JqYpmpLp .p jp ]p Xr`q[r !p Tp\"p\\p6q6q mq Yx Qr -r Ps\\q_s" -" Ipkq:q HqWq $qHq`qZq _q iqbqKqFqIq`q hp$q]t IqYpmpLq /q kq Fq_q[q #s Tp\"q^q6p 1p Vu Rs YsJsMy &v])]2_4^U^ 6^T\\5])]1_2]T\\8^U^ K])]2`4^V^3] " -" U]*\\2a4`V\\8^U^5a F]*\\1\\X\\4^U^=]*\\" -"2a5^U^ 7aV\\4]*\\1a4`V\\8^U^ J]*\\1\\X\\4^V^3\\ " -" S],\\1\\W\\5g8^U^6c F],\\1\\V\\5^U^<],\\2]W]6^U^ 8h3],\\0\\W\\5g8^U^ I],\\1\\V\\5^V" -"^4\\ ;] " -" :\\-]2\\U\\6\\V`7^U^7]U] F\\-]2\\T\\6^U^;\\-]3]U]7^U^ 8\\Va1\\-]1\\U\\6\\V`7^U^ H\\-]2\\T\\6^V^5] =a " -" J] " -" N\\/]2\\S\\7\\T]6^U^7\\S\\ E\\/]2\\R\\7^U^:\\/]3]S]8^U^ 8\\T^/\\/]1\\S\\7\\T]6^U^ G\\/]2\\R\\7^V^6] =c L^ " -" *^ U` O^ )\\S\\ " -" !^$^3\\ E]U\\ K^$^4^ G^$^4] J^$^3\\ #^$^3\\ 4^ B[ " -"&^ Xe S^ (\\S\\ )Z Q^&^3^2]S\\ A\\S\\ K^&^3^ F^&^4_ >]S" -"\\9^&^3^2]S\\ W^&^3^ 6^ Q] M[ ?` ![1^H]?` =]4](\\ %` >b4c Bb ?`2a .a Ib Pb Aa `0`*^ $^.` <^F]F^F]G`G] F\\S\\ ;b %a2a2a2a2a a:]" -".a !^T_ Bg ` Dd2_8n?m7g3]:rD]P]P]@g <] 8] 8] B] 3e J^K^ If7^U^+b@d Fb@f5a Ad4e-] :f Ra0d AaF\\HaF\\HeJ\\?]._0_0_0_0_2\\U\\0tHh@n?n?n?n?].].].]" -"-h:_J]w " -"P[ 9[/a:aQa7[ Wl \"h E]1]T]+\\R\\;[4dL]Ag=])]2])\\ U^1f8c8k;j1`;k7h?n;h9g 5i*b:_8k6kBl=n?l7mD]H]C].].]L_A].`I`H`K]>kAj6kAj9kBuB]H]F]E]E^L_L^" -"R^L^D^I^BrBb7^+b(a D] ;] '] Gd A].].].].] ;] (b:].b #^Q] Dj !a Ff3_8n?m8i4]:rD]P]P]Bk ?_ 9] 9_ C]&[0f I]K]=]0g7^U^-fC\\S] IfBf6c B[" -"S]5[S].] `K]>k]*]3]W]6^U^._V_;]Wa5]*]2\\V\\6]Wa7^V^ I]*]2\\V\\5^V^2]7]+^V^ @]W\\=v P[ 9\\1c_8m:`R`Cn?n?l9`QaE]H]C].].]M_@].aKaH`K]?`S`Bk8`S`Bk;_R_BuB]H]F]E]D]MaM]P]L]B^K^ArB]1]&])c D] <] '] G] :].].].].] " -";] (^6]*^ #]P^ E^P\\ V^ H^T^4_8n?m:`S`6]:rD]P]P]C`S` Aa :] :a D]&[1^S\\ I^M^=]0^R[7^U^/^R^EZO\\ L^R^ N]U] :],\\0] \\H]B\\H]=\\M]>" -"]._0_0_0_0_0_/uK`R`Cn?n?n?n?].].].]-n@`K]?`S`>`S`>`S`>`S`>`S` H`ScE]H]C]H]C]H]C]H]E^K^@],^T^5],]1\\V\\6\\U`7^V^6]U\\ F],]2\\T\\6^U^=],]2\\U\\6^U^-e9\\U`4],]1\\" -"V\\6\\U`7^V^ H],]1\\V\\5^V^3]6]+^V^ B`1`1`1`1`6]W]>u P[ 9]2e>eUf;^ %q $^O\\ F]1]T],]S];[5]T]N\\@]P[=]*]0]2ZR\\RZ $]2]P]<_W]8]N]\\H\\A\\H\\<\\M\\=]/a2a2a" -"2a2a1_/]V];_M]C].].].].].].].]-]ObBaL]@^M^@^M^@^M^@^M^@^M^ J^N`D]H]C]H]C]H]C]H]E^K^@]-^Q]5].]1\\T\\7\\S]6^V^5c E].]2]S\\7^U^<].]2\\S\\7^U^,a6\\S]2].]1\\T\\7\\S" -"]6^V^ G].]1\\T\\6^V^4]5]+^V^ De6e6e6e6e9\\U\\>u P[ :_3f@gVf<_ &r $]M[ F]1]T],\\R]>d<^T^P]A^OZ=]+].]4]T\\T] &^3^P^=[S]8[K].]4\\X];],]!]<]N]>^O^ " -" 8ZM^3`P`Ba9]M^=^J\\C]K_B].],^H\\E]H]C].].]O_>].aKaHaL]A^K^D]N^<^K^D]N^>]JZ6]6]H]E]G]C]MaM]O^P^@^M^-^A]1]&]+_W_ D] >] '] H] 9] B].] ;] )]4](]" -" %]N]:c6] G] J^P^7a8_1],^K^;c=]H]D]P]P]E^K^ Ee <] \\I]A\\I]<\\N]=]/a2a2a2a2a2a1]U]<" -"^J\\C].].].].].].].]-]K_CaL]A^K^B^K^B^K^B^K^B^K^ K]K^D]H]C]H]C]H]C]H]D^M^?]-]P]4]0]1\\R\\ Ha C]0]2]R] E]0]2\\Q\\ 9c 9]0]1\\R\\ !]0]1\\R\\ ?]4] Di:i:i:i:i" -";\\6]G] P\\ :`5g@gWh>a (_ J]KZ F]1]T],\\R\\?h>]R]P\\@]1]+].]3^V\\V^.] T]2]N]5]8ZJ]-]6]X];]-]!^=]L]?]M] *]5_J_Ec:]L^>]H[C]I^C].],]F[E]H]C].].]" -"P_=].]X]M]X]HbM]A]I]D]M]<]I]D]M]?]%]6]H]E]G]C^NaN^N]Q^>^O^-^@]0]'],_U_ &] '] H] 9] B].] ;] )]4](] %]N]:d7] F] K]N]8c8^1],]I]>i@]H" -"]D]P]P]E]I] Fg =] =g G]&[2] <]O];]1] 1\\F\\=\\ Q\\F\\ S\\Q\\+]3\\.] IeU\\ M\\3\\N\\ ?\\I\\@\\I\\=]M\\<]0c4c4c4c4c3a1]U]<]H[C].].].].].].].]-]J_DbM]A]I]B]I]B]I]B]I]" -"B]I] L]J_E]H]C]H]C]H]C]H]C^O^>].]N] .] '`X_ I] FbWa=bWa=bWa=bWa=bWa<\\6^I^ ?Z2[ :a5gAiXh?c *^ H] 7]1]T]-]S]Aj>]R]Q]@]1]," -"],\\1^X\\X^,] T]3]L]6]'].]7]W];]-]!]<]L]?]M^ +]6^F^F]W]:]K]?]FZC]H^D].]-]DZE]H]C].].]Q_<].]X]M]X]H]X]M]B]G]E]M^>]G]E]M^@]%]6]H]E^I^B]O^X]O]M^R^=]O^" -"-^@]0]']-_S_ '] '] H] 9] B].] ;] )]4](] %]N]:e8_ H] L]M]8]W]7^2]-]G]AmB]H]D]P]P]F]G] Hi >] >i J[3] ;^Q^;]1] 2\\RbT\\Ge R\\VdR\\ T\\" -"Q\\+]4\\2a IfU\\ M\\3\\N\\ ?\\J\\?\\J\\AaM\\ G]W]4]W]4]W]4]W]4]W]4c3^U]=]FZC].].].].].].].]-]H]D]X]M]B]G]D]G]D]G]D]G]D]G]A[H[B]J`E]H]C]H]C]H]C]H]B]O^>g8]N] " -" 1]T_ 3[ 9] G_O^?_O^?_O^?_O^?_O^=\\5]I^ @\\3[ ;c6gAy?d7`8]L]7^7]L]>^ H] 6]1]T]-]S]B_W[U]>]R]R]?]1],],]0d*] T]3]L]6]'].]7\\V];]" -".] ]<]L]@]K] 7Z PZ X]7^D^G]W]:]K]?]/]G]D].]-]/]H]C].].]R_;].]X^O^X]H]X^N]B]G]E]L]>]G]E]L]@]%]6]H]D]I]A]O]W]O]L^T^<^Q^-^?]0]'].^O^ Sb7]U`2b4`U]8a8])`" -"7]T_ M].]%_O_@_2`0`3`/_3c9] )]4](] N_6]N]3^7a/c0_ <^ D[U^ Ga N]L]9]W]6^3]-]G]B`W]W`C]H]D]P]P]F]G] I_X]X_ ?] ?_X]X_ Nb7]2ZFZ=]Q]:]0] 3[SfU[I" -"g R[UfS[ T\\Q\\+]5]2a IfU\\ M\\3\\N\\ ?\\K]?\\K]AaN] G]W]4]W]4]W]4]W]4]W]4]W]3]T]=]/].].].].].].].]-]G]E]X^N]B]G]D]G]D]G]D]G]D]G]B]J]C]KbF]H]C]H]C]H]C]H]B" -"^Q^=j;]P_9b3b3b3b3b3b3bN`Bb3a2a2a2a V_2_2`1`1`1`1` ;aU] :]U` S^T]U^A^L^A^L^A^L^A^L^?]5]I] @^5\\ ]R]R\\>]1],],].`(] U^3]L]6]'].]8]V];].]!^<]L]@]K] :] P]#^8^A]I^W^;]K]@].]G^E].].].]H]C].].]S_:].]W]O]W]H]W]N]C]E]F]L]?]E]F]L]@]%]6]H]D]J^A]O]W]O]" -"L^U^:^S^-^>]0^(]/^M^ Wh:]Wd6f8dW]:e>h2dW]?]Vd<].].]O_>].]WdScK]Vd8f;]Wd7dW]?]Wa6h>h6]L]B]I]A]P`P]K^L^B^K^@l4]4](] PdU]A]N]2^8e5g;]Vd?^J^8]6]L] E]V`" -">pA]S]S]:e6kDo>]L]:^W^6^4].]E]D_U]U_D]H]D]P]P]G]E] K_W]W_ @] @_W]W_ Qf9]3\\H\\>^S^:]0_ 6[ThT[K]Q\\ S[T\\R]S[ U]S]+]6],] ?]L]@fU\\ M\\3\\N\\ ?\\K\\>\\K\\;]O\\ G" -"^W^6^W^6^W^6^W^6^W^5]W]4^T]>].].].].].].].].]-]G^F]W]N]C]E]F]E]F]E]F]E]F]E]D_L_E]K]W]F]H]C]H]C]H]C]H]A^S^^K^ O]S]S]B]I]B]I]B]I]B]I]@]5^K^ @]4[ ;f8gAyAg] F] 6]1]T]-\\R\\B]T[6]R]S]>^2]-]*\\.`(] U" -"]2]L]6]'].]9]U];].]!];]L]@]K] =` P`'^7]?\\I]U];]K]@].]F]E].].].]H]C].].]T_9].]W]O]W]H]W^O]C]E]F]L]?]E]F]L]@]%]6]H]C]K]@^P]W]P^K^V^9]S]-^=]/](]0^K^ Xi" -";]Xf9h9fX]h6]L]A]K]@^Q`Q^J^N^@]K]?l4]4](] QfW^A]O^1]6f9h;]Xg@_K]7]6]L]=]G]C^Wc@pA]S]S]]L]:]U" -"]5^5].]E]E^S]S^E]H]D]P]P]G]E]@Z+]V]V^-Z4]5ZKZ:]V]V^ Sh9]4^J^>]S]9]._ 8[U_Q[T[L]P\\ S[T\\Q]T[ T]U]*]7]*] @]L]@fU\\ M\\3\\N\\ ?\\L]>\\L]:]Q]:]1]U]6]U]6]U]6]" -"U]6]U]6^W^5]S]>].].].].].].].].]-]F]F]W^O]C]E]F]E]F]E]F]E]F]E]C_N_D]L^W]F]H]C]H]C]H]C]H]@]S];]P_=]S^8i:i:i:i:i:i:iVgIh9h9h9h9h<].].].]'d<]Xg:h9h9h9h9h" -"0^8k?]L]?]L]?]L]?]L]A]K]>]Xf>]K] O]R]R]D]G]D]VZOZV]D]KZV]D]G]A]4]K] @]3[ j=]L]8`7]N]?] F^ 6]1]T]5uI]T[6]R]S\\<^3]-]*]1d*] U]3]J]7]']" -".]9\\T];].\\Ua-^;]L]@]K^?].] Uc Pc+_8]>]J]U];]K]@].]F]E].].].]H]C].].]U_8].]W^Q^W]H]V]O]C]E]F]L]?]E]F]L]@^&]6]H]C]K]?]Q^V]Q]I^X^8^U^.^<]/](]1^I^ ]R_h6]L]A]K]?]Q`Q]H^P^?]K]?l4]4](] R^U^W]@]O]0^7g;_S];bT^@`L]8_7]L]>]E]E^W]V]@pA]S]S]" -"=_T_].].].].].].].].]-]F]F]V]O]C]E]F]E]F]E]F]E]F]E]B_P_C]L]V^G]H]C]H]C]H]C]H]@^U^;]N^>]T]6]R_;]R_;]R_;]R_;]R_;]R_;]R" -"_X_T^K_R\\:_S^;_S^;_S^;_S^=].].].]*h=bT^;_T_;_T_;_T_;_T_;_T_1^9_T`>]L]?]L]?]L]?]L]A]K]>aT_?]K] P]Q]R]E]F]E]V\\Q\\W]E]K\\W]E]F]A]4^L] A^@ZN\\ =i8e@yCk?^R^" -"=]L]9b8]O^?] Im B]1]T]5uI]T[6]S^T]<^3]-]*]3^X\\X^,] V^3]J]7](^/]9]T];e7]We/]9]N]?]K^?].] Wd Nd._8]O`U\\T\\K]S]<]L^A]-]F^F].]/]-]H]C].].]V_7].]V]Q" -"]V]H]V^P]D]C]G]L]@]C]G]L]?^']6]H]C^M^?]Q]U]Q]Ic6^W^._<]/^)]2^G^ !ZM^=`Q^=^NZ;^Q`>^P^=].^Q`?`Q^>].].]R_;].`R^X\\R^M`Q^=^P^>`Q^=^Q`?`1]MZ;].]L]A^M^?]Q`Q]" -"G^R^>^M^1^4]4](] D]P^A]R^X]@]P^/]9^Vb=^NZ;`Q^AaN^8_7]L]>]E]F^V]U]>]P]>]S]S]>^P^>`T`7]6]J]<]S]5^6]/]C]G]Q]Q]F]H]D]P]P]H]C]C^&]TZ,^7]7^N^6]TZ H]/^U[TZ9" -"]2n;]U]8]0d <[U]F[M\\P]2[R[ M[S\\P\\S[ Tb(]9]'\\ @]L]@fU\\ M\\3]P]9[R[1\\M\\<\\M\\7\\R\\8]2]S]8]S]8]S]8]S]8]S]7]U]6]R]?]-].].].].].].].]-]F]F]V^P]D]C]H]C]H]C]H]" -"C]H]C]B_R_C]L]T]G]H]C]H]C]H]C]H]?^W^:]M]>]U^6ZM^].].].]+i=`Q^=^P^=^P^=^P^=^P^=^P^2^:^P^>]L]?]L]?]L]?]L]" -"A^M^>`Q^@^M^ P]Q]Q]F]E]F]W^S^W]F]L^W]F]E]B]3]M^ B^B^O[ =k8d?xClA^P^>]L]9]X]8^P]>\\ Hl A] 9uI]T[5]T]T]:^ =]*]5^V\\V^.] V]2]J]7](]/^:]S];h:]Xg0]" -"9^P^?]K^?].]!e Je2_7\\PdW\\S\\L]S]<]M^@]-]E]F].]/]-]H]C].].]X_5].]V]Q]V]H]U^Q]D]C]G]L]@]C]G]M^?`)]6]H]B]M]>]Q]U]Q]Hb5c-^;].])] B]=_O]=].]O_>]N^>].]O_?_" -"O]>].].]S_:]._P`P]M_O]=]N]>_O]=]O_?_1]-].]L]@]M]>]RbR]G^R^=]M]1^3]4](] FaSaD^Qa?]R_.]9]R`>]._O]>^N]8`7]L]>]E]G^U]U^?]P]>]S]S]>]N]>^P^7]6]J]<]S]4^7]/]" -"C]G]Q]Q]F]H]D]P]P]H]C]D_&]&_8]8_N_7] B]/]T[3]1l:^W^8]1]W` >\\U\\E\\N\\P]3\\S\\ N\\S\\P\\S\\ S_']:]&\\ @]L]@fU\\ M\\2\\P\\8\\S\\2\\N]<\\N]7\\S]8]2]S]8]S]8]S]8]S]8]S]8]S]" -"7]R]?]-].].].].].].].]-]E]G]U^Q]D]C]H]C]H]C]H]C]H]C]A_T_B]M]S]G]H]C]H]C]H]C]H]>c9]M^?]U]'].].].].].].`O^N].]N^>]N^>]N^>]N^?].].].],_R^>_O]=]N]=]N]=]N]" -"=]N]=]N]2^:]O_?]L]?]L]?]L]?]L]@]M]=_O]?]M] O\\P]Q]F\\D]F\\U^U^V]F\\L^V]F\\D]B]3]M] RuJ`O[ >m9c>wCmA]N]>]L]9]X]7]P]?] Im A] 2\\R\\A]T[5^V^T\\:` ?](\\6]T" -"\\T]/] V]2]J]7])^1_9]S];i;bS^2^8^S_>]K^?].]$e@u@e6_7]QfX\\S\\M^S^=]N^?]-]E]F].]/]-]H]C].].c4].]U]S]U]H]T]Q]D]C]G]M^@]C]G]M]=c-]6]H]B]M]>^R]U]R^G`4c.^:]" -".])] B]=^M]?^/]M^?]L]>]/]M^?^N^?].].]T_9].^O_O^N^N^?]M^?^M]?]M^?^0]-].]L]@]M]>^S]X]S^F^T^<^O^2_3]4](] GcUcE]Pa?]Vb-]:]O_?].^N^>]O^8a8]L]?]C]H]T]T]?" -"]P]>]S]S]?]L]@^N^8]6]J]=^S^4^8]/]C]H^Q]Q^G]H]D]P]P]H]C]E_%]%_9]9_L_8] B]0^T[3]0_T_>cWc=]1]U_ ?[U\\C[N]R^4]T] N[R\\Q]R[ 'uG]&] @]L]?eU\\ M\\2]R]8]T]3\\N\\;" -"\\N\\7]S\\7]3^S^:^S^:^S^:^S^:^S^9]S]8^R]?]-].].].].].].].]-]E]G]T]Q]D]C]H]C]H]C]H]C]H]C]@_V_A]N]R]G]H]C]H]C]H]C]H]>c9]L]?]U]'].].].].].]._M]O^/]L]?]L]?]L" -"]?]L]?].].].]-^O]>^N^?]M^?]M^?]M^?]M^?]M^ I]O`?]L]?]L]?]L]?]L]@^O^=^M]@^O^ P]P]P\\G]C\\G]T^W^T\\G]M^T\\G]C\\B]3^O^ RuJ[X]P[ >o=\\XaX]BwDoC]L\\>]L]:^X^8]P]?" -"] E] 5] 3]S]A^U[4dT];b @](]6ZR\\RZ.] V]2]J]7]*^7d8]R];]R_]-]E]Fm>k=]-rC].].b3].]U]S]U]H]T^R]D]C]G]M]?]C]" -"G]N^^M]?].]M^?]L]>]/]M^?^M]?].].]U_8].^N^N]N^M]?]L]?^M]?]M^?^0]-].]L]@^O^=]S]X]S]D^V^:]O]2_2]4](] H\\U^W]U\\E]Pa?" -"]Vb-];]M^?].^M]>^P]7a8]L]?]C]H]T]T]?]P]>]S]S]?]L]@]L]8]6p=]Q]3^9]/]C]H]P]P]G]H]C]Q]Q]G]ViV]F_$]$_:]:_J_9] B]0]S[3]0]P]>o=]2]S_ @[U\\C[M]T_5^U^;u O[R\\R]" -"Q[ 'uH]/ZQ] ?]L]?eU\\ M\\1]T]7^U^4\\O]O]I\\O]T`MZQ]S]O]E]3]Q]:]Q]:]Q]:]Q]:]Q]:^S^9]QmO]-m>m>m>m>].].].]1hL]G]T^R]D]C]H]C]H]C]H]C]H]C]?_X_@]O]Q]G]H]C]H]C]" -"H]C]H]=a8]L]?]U]&].].].].].].^M]O].]L]?]L]?]L]?]L]?].].].].^M]?^M]?]L]?]L]?]L]?]L]?]L] I]Pa?]L]?]L]?]L]?]L]?]O]<^M]?]O] O]P]P\\G]C\\G]ScS\\G]N^S\\G]P]P\\B" -"]2]O] QuF]Q[ >oAqDuDqD]L]?]L]:^X^8^R^?\\ D] 5] 3]S]@`X[3bS\\R^G]W^N] P](].\\&] W]1]J]7]*^7c8]Q];ZM^=`O^4]4d:]M_?].])d:u:d=_5\\R]O^R\\N]Q]=j<]-]E]F" -"m>k=]-rC].].a2].]U^U^U]H]S]R]D]C]G]N^?]C]G]P_:g3]6]H]A]O]<]S]S]S]E^1_.^8]-]*] A]>^M]?]/^M^?]K]?]0^M^?]L]?].].]V_7].]M]M]N]L]@^L]?^M]@^M^?]/]-].]L]?]" -"O]<]S]X]S]C^X^9]O]2^1]4](]0_IZ O[R\\X]S\\G^O_>]Vd9_U];]L]?].]L]=]P]8]X^9]L]?]C]I^T]S]@]P]>]S]S]?]L]@]L^9]6p=]Q]3^9]/]C]H]P]P]G]H]C]Q]Q]G]ViV]G_#]#_;];_H" -"_:] B]0]S[3]0\\N\\>o=]2]Q^ A[U\\C[LcX\\6]T]9u O[RfP[ 'uIf7e >]L]>dU\\<] :f5d4]T]:fT\\O^NfT\\UdOeR\\O^F^3]Q]:]Q]:]Q]:]Q]:]Q]:]Q]:^QmO]-m>m>m>m>].].].]1hL]G]S]R" -"]D]C]H]C]H]C]H]C]H]C]>d?]P^Q]G]H]C]H]C]H]C]H]<_7]L]?]U^'].].].].].].^L]P].]K]@]K]@]K]@]K]@].].].].]L]?]L]@^L]@^L]@^L]@^L]@^L] I]Q]X^@]L]?]L]?]L]?]L]?]" -"O]<^M]?]O] O\\WmX]H\\WmX]H\\QaR]H\\N^R]H\\O]P]C]2]O] QuF]R\\ ?qCsDtDrE]L]?]L]:]V]7]R]>x '] 5] 3\\R\\?e3^R\\SbJ^V^O] P](].\\&] W]1]J]7]+^6e:]Q]-^>_M]5^6" -"h<^O` Qe8u8e@^5]R\\M]R\\O^Q^>m?]-]E]Fm>k=]KdFrC].].b3].]T]U]T]H]S^S]D]C]G]P_>]C]Gk6f5]6]H]A^Q^<]S]S]S]F_1_/_8]-]*] A]>]K]A].]K]@]J]?]0]K]?]L]?].].]W_" -"6].]M]M]N]L]@]J]@]K]A]K]?]/^.].]L]?]O]<]T^W]T]C^X^9^Q^3^1]3]']3dN\\ P\\R`Q[G]N_>]Q`;bW];\\K^?]/]L]=]Q^8]W]9]L]?]C]I]S]S]@]P]>]S]S]@]J]B^L^9]6p>^Q^4^9]/]C" -"]H]P]P]G]H]C]Q]Q]G]ViV]H_\"]\"_<]<_F_;] B]1]R[3]1]N]8a6]2]P^ B[U\\C[K`V\\7]T]8u O[RdN[ 'uIf5a <]L]=cU\\<] :f3`1]T];fU\\N^NfU\\T[S]NaQ\\N^G^3^Q^<^Q^<^Q^<^Q^<^Q" -"^;]Q]:]PmO]-m>m>m>m>].].].]1hL]G]S^S]D]C]H]C]H]C]H]C]H]C]=b>]P]P]G]H]C]H]C]H]C]H]<_7]L]?]U_(].].].].].].]K]Q].]J]A]J]A]J]A]J]@].].].].]L]?]L]@]J]A]J]A" -"]J]A]J]A]J] K]P\\V]@]L]?]L]?]L]?]L]?^Q^<]K]@^Q^ O\\WmX]H\\WmX]H\\P_Q]H\\O^Q]H\\O]P]C]2^Q^ D^<]R[ >qDuEsCqD]L]?]L]:]V]7]R]>x '] 5] 3\\R\\=f+]TdL^T^P] P]" -"(].\\2u *]1]J]7],^-_=]P],]>_M]5]7_R^<^Qa Sd .dC^4\\R]M]R\\O]O]>]N_@]-]E]F].]/]KdF]H]C].].]X^4].]T]U]T]H]R]S]D]C]Gk=]C]Gj1c6]6]H]@]Q];^T]S]T^Ga1].^7]-]*" -"] Lh>]K]A].]K]@]J]?]0]K]?]L]?].].]X_5].]M]M]N]L]@]J]@]K]A]K]?]._0].]L]>]Q];^U]V]U^Bb7]Q]3^1^3]'^6iS^ P[P^P[G]N_>]N^=dX]<]J]>^1]L]=^R]8^W]9]L]@]A]J]S" -"]S]@]P]>]S]S]@]J]B]J]9]6]J]>]O]5^8]/]C]H]P]P]G]H]B]R]R]F]C]Iz<]]K]@]" -"O[X\\I`3]O]<]O]<]O]<]O]<]O]<]O];]P]?]-].].].].].].].]-]E]G]R]S]D]C]H]C]H]C]H]C]H]C]<`=]Q]O]G]H]C]H]C]H]C]H];]6]L]?]T_4h9h9h9h9h9h9hK]Q].]J]A]J]A]J]A]J]" -"@].].].]/]J]@]L]@]J]A]J]A]J]A]J]A]J]?tG]Q\\U]@]L]?]L]?]L]?]L]>]Q];]K]?]Q] N\\WmX]H\\WmX]H\\P_Q]H\\P^P]H\\O]P]C]1]Q] C]:]S[ ?sEvEqAoC]L]?]L];^V^8^T^>x " -" '] 5] 4]S]]K]A].]K]@p?]0]K]?]L]?].].b3].]M]M]N]L]@]J]@]K]A]K]?].c4].]L]>]Q]:]U]V]U]@`6^S^4^5b2]&b^Ua<]J]=" -"c7]L]<]S^8]V^:]L]@]A]J]S]S]@]P]>]S]S]@]J]B]J]9]6]J]?^O^7^7]/]C]H]P]P]G]H]B]R]R]F]C]Iz<]\\I\\@\\O\\X\\J`3^O^>^O^>^O^>^O^>^O^=]O]<^P]?]-].].].].].].].]-]E]G]R^T]D]C]H]C]H]C]H]C]H]C];^<]R]N]G]H]C]H]C]H]C]H];]6]L]?]S`8j;j;j;j;j" -";j;|Q].pApApAp@].].].]/]J]@]L]@]J]A]J]A]J]A]J]A]J]?tG]R]U]@]L]?]L]?]L]?]L]>^S^;]K]?^S^ N\\WmX]H\\WmX]H\\QaR]H\\Q^O]H\\O]P]C]1^S^ D]9]T\\ ?sFwDo?nC]L]?]L];" -"]T]7]T]=] Hj ?] 4]S]8d/]T]T]N^R_R\\ O](] =u Se =]0]J]7].^(]?]O]+]?^K]7]7]L]]K]A].]K]@p?]0]K]?]L]?].].a2].]M]M]N]L]@]J]@]K]A]K]?]-f8].]L]>^S^:]U]V]U]?^4]S]4^4`0]$`<^Si O[O" -"\\O\\H]N^=]M^@^S`<]J]=c7]L]<]S]8^U]:]L]@]O]O]J]S]S]@]P]>]S]S]@]J]B]J]9]6]J]?]M]7]6]/^E^H]P]P]G]H]A]S]S]E]C]Iz<]]M]>]M]>]M]>]M]>^O^=]O]?]-].].].].].].].]-]E]G]Q]T]D]C]H]C]H]C]H]C]H]C]<`=]S]M]G]H]C]H]C]H]" -"C]H];]6]M^?]R`;l=l=l=l=l=l=~Q].pApApAp@].].].]/]J]@]L]@]J]A]J]A]J]A]J]A]J]?tG]S]T]@]L]?]L]?]L]?]L]=]S]:]K]>]S] M]P]P\\G]C\\G]ScS\\G]S^N\\G]P]P\\B]0]S] D]" -"7\\T[ >sFwCn?mB]L]?]L];]T]7]T]=] Hi >] 4]S]7[Xa1]T^T^O]P_T] O](] =u Se =]0]J]7]/^'^A]N]+]?^K]7]8^L^]K]A].]K]@p?]0]K]?]L]?].].b3].]M]M]N]L]@]J]@]K]A]K]?]+e9].]L]=]S]9]V]T]" -"V]@_4]S]5_4b2]&b<\\Nd M[O]P\\H]N^=]L]@]Q_<]J]?e7]L];]T]8]T]:]L]@]O]O]J]S]S]@]P]>]S]S]@]J]B]J]9]6]J]?]M]8^6].]E]G]P]Q^G]H]A^T]T^E]C]Iz<]]M]>]M]>]M]>]M]>]M]>^O]?]-].].].].].].].]-]E]G]Q^U]D]C]H]C]H]C]H]C]" -"H]C]=b>]T]L]G]H]C]H]C]H]C]H];]6]M]>]Qa>`P]>`P]>`P]>`P]>`P]>`P]>`PoQ].pApApAp@].].].]/]J]@]L]@]J]A]J]A]J]A]J]A]J]?tG]T]S]@]L]?]L]?]L]?]L]=]S]:]K]>]S] " -"L\\P]P\\F\\C\\F\\T^W^T\\F\\T^M\\F\\C\\B]0]S] E^7]U[ >sFwBl=kA]L]?]L]<^T^8^V^=] Ij >] ]K]A].]K]@],]0]K]?]L]?].].c4].]M]M]N]" -"L]@]J]@]K]A]K]?](d;].]L]=]S]9^W]T]W^@`5^U^5^/_3]'_8ZJ` K[O]P\\H]N^=]L]@]P];]J]@_0]L];]U^9^T^;]L]@]O]O]J]S]S]@]P]>]S]S]@]J]B]J]9]6]J]@^M^:^5].]E]F]Q]Q]F" -"]H]@^U]U^C]E]G_\"]\"_BZT]TZB_F_;] B]1]R[3]1\\L\\?o I_S] A[U]F[ V]T] W] N[S\\R]R[ S] ]L]6\\U\\ ']T]/\\O\\V\\@\\H\\A\\O\\V\\M_0o@o@o@o@o?m>l>].].].].].].].].]-]F^" -"G]P]U]C]E]F]E]F]E]F]E]F]E]=d?^V]L]F]H]C]H]C]H]C]H];]6]N^>]O`?]M]>]M]>]M]>]M]>]M]>]M]>]M]?].].].].]-].].].]/]J]@]L]@]J]A]J]A]J]A]J]A]J] K]U]R]@]L]?]L]?" -"]L]?]L]=^U^:]K]>^U^ L\\P]Q]F\\D]F\\U^U^V]F\\U^M]F\\D]B\\/^U^ OuD]V[ =sFwBk;i@]L]?]L]<]R]7]V];] F^ Nu=[T^3]S]R]O]N_V\\ N](] 1] ].]L]6]1_%]Aq0]>]K]" -"8]7]J]/] Md:u:d>]3\\R\\K\\S\\Po@]J]A].]F]E].].]E]F]H]C].].]S^9].]RaR]H]P^V]C]E]F].]E]F]M],]8]6]H]>]U^8]W^Q^W]H^U^4]2^3]+],] R^M]>]K]A].]K]@],]0]K]?]L]?" -"].].]X_5].]M]M]N]L]@]J]@]K]A]K]?]$`;].]L]=^U^8]W]T]W]@b5]U]5^,]3]'] J\\Q_Q[G]N^=]L]A]O];]J]@].]L];]U]8]R];]L]@]O]O]J]S]S]@]P]>]S]S]@]J]B]J]9]5]L]?]K];" -"^4].^G^F]Q]Q]F]H]?_W]W_B]E]F_#]#_B\\U]U\\B_H_A\\U]U[ H]1]R[3]1]N]?o H`V] @[T]G[ U]T] X] N[S\\Q]S[ S] ]L]6\\U\\ (]T]/]P\\U\\A]I]B]P\\U\\M^/o@o@o@o@o@o@m>].]" -".].].].].].].]-]F]F]P^V]C]E]F]E]F]E]F]E]F]E]>_X_?]W^L]F]H]C]H]C]H]C]H];]6]P_=]M^@^M]?^M]?^M]?^M]?^M]?^M]?^M]?].].].].]-].].].]/]J]@]L]@]J]A]J]A]J]A]J]" -"A]J] K]U\\Q]@]L]?]L]?]L]?]L]<]U]9]K]=]U] K]Q]Q]F]E]F]W^S^W]F]W^L]F]E]B\\.]U] NuC\\V[ =eXZXdFgXhAi9h@]L]?]L]<]R]7]V];] E] Nu=[S]3\\R]R]O]M_X\\ M](" -"] 1] ].]L]6]2_$]Aq0]>]K]8]7]J]/] Ke=u=e<]3\\R\\K\\S\\Po@]J]A].]F]E].].]E]F]H]C].].]R^:].]RaR]H]O^W]C]E]F].]E]F]M^-]8]6]H]>]U]7]W]O]W]I^S^5]3^2]+],] R" -"]L]>]K]A].]K]@],]0]K]?]L]?].].]W_6].]M]M]N]L]@]J]@]K]A]K]?]\"_<].]L]<]U]7]W]T]W]Ac5^W^6^+^4](] H[R\\X]S\\G]N^=]L]A]O];]J]A^.]L]:]W^9^R];]L]@]O]O]J]S]S]@" -"]P]>]S]S]@]J]B]J]9]5]L]?]K];^4]-]G]D]R]R]E]H]>kA]E]E_$]$_B^V]V^B_J_A^V]V] I]1]R[3]0\\N\\>o G`X] ?\\U_Q[T\\ T]T] ] N\\T\\Q]T\\ S] ]L]6\\U\\ )]T].\\P\\T\\A\\I]A" -"\\P\\T\\N^.o@o@o@o@o@o@m>].].].].].].].].]-]F]F]O^W]C]E]F]E]F]E]F]E]F]E]?_V_@]W]K]F]H]C]H]C]H]C]H];]6k<]L^A]L]?]L]?]L]?]L]?]L]?]L]?]L]?].].].].]-].].].]/" -"]J]@]L]@]J]A]J]A]J]A]J]A]J] K]V\\P]@]L]?]L]?]L]?]L]<^W^9]K]=^W^ J]R]R]D]G]D]W\\Q\\W]D]W\\L]D]G]A\\.^V] NuC]W[ ]K]9]6]J]/] He@u@e H\\R]M]T]Q^J]A]J]@]/]G^E].]-]F]F]H]C].].]Q^;].]Q_Q]H]N]W]B]G]E]-]G^F]L]-]8]6]I^>^W^7]" -"W]O]W]I^R^6]4^1]+],] R]M^>^M^@]/^M^?]-]0^M^?]L]?].].]V_7].]M]M]N]L]@^L]?^M^A^M^?] ]<].]L]<]U]7]X]R]X]B^W^5]W]6^)]4](] H\\T]W]U\\F]O_=]L]A]P^;^L^A]-]L" -"]:]W]8]P]<]L]@]O]O]J^T]T]?]P]>]S]S]@^L]A^L]8]5]L]@^J]=^3]-^I^D^S]S^E]H]]G]C_%]%_A_W]W_A_L_@_W]W_ J]0]S[3]0]P]5]4],b =[ThT[ R]T]!] M[T\\P]U[ R] ]L" -"]6\\U\\ *]T].]P[S\\B]J]A]P[S\\N].^J]B^J]B^J]B^J]B^J]B^K^A]M]=]/].].].].].].].]-]G^F]N]W]B]G]D]G]D]G]D]G]D]G]?_T_AbK]E]I^C]I^C]I^C]I^;]6j;]K]A]M^?]M^?]M^" -"?]M^?]M^?]M^?]M_?].].].].].].].].]/]J]@]L]@^L]@^L]@^L]@^L]@^L] J^X]Q]?]L]?]L]?]L]?]L];]W]8^M^<]W] I]R]S]C]H]C]VZOZW]C]VZL]C]H]@\\-]W] MuC]X[ ;cWZWbDe" -"WZXe>e6e>]L]?]L]=]P]8^X^:] F^ H\\R\\5[S]5]Q]R]O^L` K]*] 0] !^.]L]6]4_\"]2],^>^M]8]6]J]0] DeCuCe E]R\\M]T\\P]I]A]J]@]/]G]D].]-]F]F]H]C].].]P^<].]Q" -"_Q]H]N^X]B]G]E]-]G]E]L^.]8]5]J]<]W]6^X]O]X^J^Q^6]5^0]+^-] R]M^>^M]?].]M^?]-]/]M^?]L]?].].]U_8].]M]M]N]L]?]L]?^M]?]M^?] ]<].]M^<^W^6aRbB^V^6]W]7^(]4]" -"(] GcUcE]P_=]L]A]P]9]L]@]-]L]:^X]9^P]<]M^@]P^O]I]T]T]?]P]>]S]S]@^L]@]L]8]5]M]?]I]>^2],]I]B_U]U_D]H]:c<]G]B_&]&_?_X]X_?_N_>_X]X_ I]0]S[3]0_T_5]4]+` ;[" -"SfU[ P^U^#] L[U\\P]V[ Q] ]M^6\\U\\ ,^U^-\\P\\S\\B\\J]@\\P\\S\\N].]I]B]I]B]I]B]I]B]I]B]I]B^M]=]/].].].].].].].]-]G]E]N^X]B]G]D]G]D]G]D]G]D]G]@_R_A`J]D]J]A]J" -"]A]J]A]J]:]6g8]K]A]M^?]M^?]M^?]M^?]M^?]M^?]M_?].].].].].].].].].]L]?]L]?]L]?]L]?]L]?]L]?]L]3^;aP]?]M^?]M^?]M^?]M^;]W]8^M];]W] H]S]T^B]J^B]J^B]J^B]J^@" -"\\-]W] G^1_ :aW[V`BcW[Wc]N]<]P]7]X]8] F]KZ X]S]5[S]5\\P]R]N]K_ K]*] 0] !],]N]5]5_\"]1],]<]M]9^6^L^0] Ad Nd A\\R]O^U\\P^I^B]K^?]H[C]H^D]" -".],]G]F]H]C].].]O^=].]P^Q]H]M]X]A]I]D],]I^E]K]AZH^8]5]J]<]W]5bObJ^O^7]6_0]*]-] R]M^>^M]?^/]M^?^.]/]M^?]L]?].].]T_9].]M]M]N]L]?]L]?^M]?]M^?] ]<].]M^;" -"]W]5aRaB^U^6c8_(]4](] FaSaD]P_=]M]@]P]9]L]@]-]L]9b9]O^=^N^?\\P_Q]H]T]T]?]P]=]T]T]?^L]@]L]8]4]N]@^I^?]1],^K^A`W]W`C]H]7]8]I]@^&]&^=i=^N^^P^=^P]7]X]8_ H^M[ F] 6]S]>ZQ[T^6]P]S^N^K^ K]*] 0]:] 8]0],]O^5]6_2ZI]1]-^<^O^9]4]L]0]<].] Uc Pc1]2\\Q^S`W^P]G]B]K]" -">^J\\C]I^C].],^H]F]H]C].].]N^>].]C]H]MbA^K^D],^K^D]K^B[I]7]5^L^_O]=].]O_>].].]O_?]L]?].].]S_:].]M]M]N]L]>]N]>_O]=]O_?] ]<]-" -"]O_;]X^5aRaC^S^6a8_']4](] D]P^B^Ra>^N]@]Q]7]N]?^.]L]9a8]N]=^N^?]Q_Q]G]U]U]>]P]=]T]T]?_N]>]N]7]4^P^@]G]@^1]+^M^?mB]H]7]8^K^?\\%]%\\;g;\\L\\:g G]/]T[3]2n7]" -"4]'^ <\\F\\ M\\S\\ J\\F\\ L^N^6\\U\\ ,\\S\\-]OhG]K]@]OhQ]LZ=]G]D]G]D]G]D]G]D]G]D]G]D^L]<^J\\C].].].].].].].]-]J_D]MbA^K^B^K^B^K^B^K^B^K^A_N_B^K]B^L^A^L^A^" -"L^A^L^:]6].]K]A^O_?^O_?^O_?^O_?^O_?^O_?^Oa?].].].].]/].].].]-]N]>]L]>]N]=]N]=]N]=]N]=]N]2^;_O]=]O_>]O_>]O_>]O_:a7_O]9a E^P_>^P_>^P_>^P_>^P_>\\,a H^.]" -" /[5]T[S\\8a1`<]L]=^R^<]O^8b7_ H^O\\ F] 6\\R\\=[R[U^5\\N]T]L^M` L]*] 0]:] 8]1^+]P]4]7_1[L_1]ZM];].] R` P`.]2]QfXaN]G]B]L^=^L]C]K_B].]+" -"_J]F]H]C].].]M^?].]C]H]La@^M^C]+^M^C]J]B]L^7]4^N^:a4aMaK^M^8]7^.]*^.] Q]P`>`Q^=^NZ;^Q`>_LZ>].^Q`?]L]?].].]Q^;].]M]M]N]L]>^P^>`Q^=^Q`?]/ZL];]-^Q`:a4`" -"P`D^Q^7a8^&]4](] S]Sb>_P^@]R^7^P^>^MZ<]L]9a9]M]=_P`XZB]Q_Q]G^V]V^>]P]=^U]U^?`P^>^P^6]4]Q^?]G]A^0]*^O^]P`>]P`>]P`>]P`>]P`>]P]X^LZN^NZ;_LZ>_LZ>_LZ>_LZ?].].].]-^P^>]L]>^P^=^P^=^P^=^P^=^P^2^:^P^=^Q`>^Q`>^Q`>^Q`:a7`Q^9a Dk],a " -"H]-] /[,[._0_;]L]=j<]N]7`5a J_S^ F] 6\\R\\=^U[W_5]N^V^K_Rd L],] /]:] 8]1])^T^3]8_0^Q`0]<]Q_8^S^8^3_R_=]R^:].] O] P]+]1\\PdW`N^G^C]N_;`R`C]NaA].]*`O" -"`F]H]C].].]L^@].]C]H]La?`S`B]*`S`B]J]B`Q_6]3_R_9a4aMaL^K^9]8^-])].] Q_Tb>aS^;_R\\:^Sa=`Q]>]-^Sa?]L]?].].]P^<].]M]M]N]L]=_T_=aS^;^Sa?]/^R_:]-^Sa:a3_P_" -"C^P^7_8^%]4](] S_V^X^?aS^>]T^5_T_=`R]<]L]8_8]M^>`SdA]SaS]E^W]W^=]P^=_W]W_>]X]T_<_T_5^4^T^?^G^C^/])^Q^8c=]H]7]6`S` ?] ;c >c E]._W[V\\9]4^J^9]4]%] ;]L]" -" IZQZ H]L] !u ,`Sd9\\U\\ ,ZQZ,]E\\E]L]?]E\\M_S^>^G^F^G^F^G^F^G^F^G^F^G^F^K]:`R`C].].].].].].].]-]ObB]La?`S`>`S`>`S`>`S`>`S`?]J]CcS`?_R_=_R_=_R_=_R_8]6" -"].]V[R^?_Tb>_Tb>_Tb>_Tb>_Tb>_Tb>_T^V_Q]M_R\\:`Q]=`Q]=`Q]=`Q]?].].].],_T_=]L]=_T_;_T_;_T_;_T_;_T_1^:`T_;^Sa=^Sa=^Sa=^Sa9_6aS^7_ Bi:i:i:i:i=]+` I],] /[" -",[-].]:]L]]C]H]K`>kA])kA]J^Cm5" -"]2j7_2`M`K^J]9]8tC])].] PgX]>]Xf9h9fX]],fX]?]L]?].].]O^=].]M]M]N]L]qA^U]W]U^D" -"i<]O`?k=]Xg:h3a7f>uCn?]/eSe;]:]H]7]5k >] :a n?\\H\\8]4]%] 9^R^ *^R^ Xu ,q9\\U\\ /]D\\F]LfH]D\\Li>]E]F]E]F]E]F]E]F]E]F]E]F]JnIkBn?n?n?n?].].]." -"]-n@]K`>ki-]]C]H]K`]Wd6f8dW]:i>]+dW]?]L]?].].]N^>].]M]M]N]L];f;]Wd7dW]?]/i7c3dV]9_2_P_E^M^8_8m4]4](] QdV`B]Xe;d1f8h<]L]8_9]K]>]XdW_@eWeBg;]O" -"`=g;]Vd8f1`6d=uCn?]/eSe;]:]H]7]3g <] 9_ :_ C]+f>n>ZFZ7]4]%] 7f &f Vu ,]XdW_9\\U\\ /\\C\\F\\KfH\\C\\Kg=]E]F]E]F]E]F]E]F]E]F]E]F]JnHh@n?n?n?n?].].].]-l>" -"]K`]C]H]J_9a<]$d?]I^?c0].b3_2" -"_K_M^G^;]8tC](]/] M`T]>]U`2b4`U]7c;])`U]?]L]?].].]M^?].]M]M]N]L]8`8]U`3`U]?],c2a0_T]9_2^N^F^K^8]7m4]4](] O`R^B]Va8b-`3d:]L]7]9^J]?]V`T]>cUc?c9]N_:" -"a8]T`3`-_4`X IX *W FW " -" " -" " -" HX W 4Z 3VCT X W 4Z " -" HX W 4Z 'VCT ;X W 3Y 2UCT KX W 3Y 0W " -" " -" " -" @W !W 4\\ 5YET ?XHX 8] >W !W 4\\ 7XGX KW !W 4\\ 7XHX +YET :W !W 3[ 5ZFT ?XGX EW !W 3[ 7XGX 5W " -" " -" " -" >W \"V 3\\ 7]HU ?XHX 9` ?W \"" -"V 3\\ 7XGX JW \"V 3\\ 7XHX -]HU 9W \"V 3] 7]HT ?XGX DW \"V 3] 8XGX 5V " -" " -" " -" W $V 3VNV 8XGX IW $V 3VNV 8XHX -_KV 8W $V 2] 7_KU ?XGX CW $V " -"2] 8XGX 6V " -" " -" :W &W " -"4VLV :j >XHX :VJV >W &W 4VLV 9XGX HW &W 4VLV 9XHX .j 6W &W 3VMV 9i >XGX BW &W 3VMV 9XGX 7W MW " -" " -" " -" CV 'W 4VJV ;j >XHX ;UGV >V 'W 4VJV :XGX GV 'W 4VJV :XHX .j" -" 5V 'W 3VKV :i >XGX AV 'W 3VKV :XGX 8W N[ " -" " -" " -" DV )W 4VHU TEY ;XHX V ,V 2UEU TCU :XGX =U -V 2UCU =XGX ;V NV" -"IV \"W " -" " -" JU /V 3VBV ETBT :U /" -"V 3VBV FU /V 3VBV (U /V 2UAU DU /V 2UAU @V NVGV " -" $X " -" *X " -" JX GTBT MX GX 7V :UEU DX GX 7V " -" JX GX 7W 4X GX 6V GX GX 5V (X &X " -" )X 8V " -" ;X FTBT " -" LX IX 7X W E\\ AW ,W ,W ,W ,W " -" HY GV +Y 4Z NX @X %W " -" DUDU =Y 7W KW 6Z 4XDT BTAT BW KW 6Z IW KW 6[ ,Y )XDT AW KW 5Z 4XDT " -" KW KW 4Z ,W BW 8V (S W H_ AW ,W ,W ,W ,W L] GV +] ;a " -" #[ F^ 8XGX +W BTEU " -" *R 9a :W MW 6\\ 6ZET ?XHX W Ja AW ,W ,W ,W ,W N_ GV +_ " -"?e 8] J] Jb 8[ <[ $Y FY 7XGX =Z Di 5W 8Z .Y !W FW *Y 4W)V*W)V-Y(V " -" W $a MY " -" EW 5W >W Kb AW ,W ,W ,W ,W !a GV +a Ch =f ^ Mf 2Z @x Mx a 5a &W 0g #\\ -_ <\\*V.\\*V0a-V\"X )Z /Z /Z /Z /Z 4WJV 1~U+d Kx Mx Mx Mx MX -X -X -X ,j" -" @[3X Dc 8c 8c 8c 8c W \"W 4VNV 8]HU ?XHX " -"BW \"W 3VNV 8XHX 2W ?W &XHX ^ K~\\ >S 3Q +[ @[;[ ;Q ;e HX 2VFV #VBV FS 6`1V#g GV !V 3V !T 7W 0d" -" :` ;j ?k -[ Dq :g Ky Df ;d $f 1Z @o 5j Np Ex Mt :m\"X/X'X -X -X3Z%X -]0]0\\4X Gi Lm 4i Ln ;m#~W$X/X-X(X-X4Y4XCY1Y-Y.Y&~S%a >W $a N[ EV " -"5W >W Lc AW ,W ,W ,W ,W \"b GV +a Dk Aj \"_ h 3Z @x Mx ?i 6X C~Q)X?X?X Ni 6V /V /" -"V DX &f #W0W e >XGX %c#e +b\"i 9_ Be 9d 'V 3k %^ /c @^*V0^*V2d.V\"X )Z /Z /Z /Z /Z 3b 1~U.j Nx Mx Mx Mx MX -X -X -X ,p F\\4X Gi >i " -">i >i >i BiEV.X/X'X/X'X/X'X/X.Y.Y#X 'j ;V \"V 5VLV :_IT >XHX V \"V 5VLV 9XGX IV \"V 4VMV 9XGX ,ZHY A_IT XHX AV \"V 3VLV 9" -"XHX 2V >W &XHX !_ K~[ >T 4R -_ D_?_ >S =t Fh IX 2VFV #VBV FS 7c4V#i HV \"W 3V !T 7V 0f @e >o Co 0" -"\\ Dq W M" -"d AW ,W ,W ,W ,W HW 1b GV +b Fm Dm #` \"j 4Z @x Mx Am 8X C~Q)X?X?X!m 9X 0V 0X EX 'h" -" $W0W \"h ?XGX 'g%g 0h%i :a Cf :f *V 4m %^ 0e A^+V/^+V1f1V!X )Z /Z /Z /Z /Z 2` 1~V0o\"x Mx Mx Mx MX -X -X -X ,t J\\4X Im Bm Bm Bm Bm F" -"mHV-X/X'X/X'X/X'X/X-X.X\"X (l ;V $V 4UJU :ULXLU >XHX XHX @V $V 2UJU 9XHX 3V" -" =W &XHX !` K~Z >T 4S /a FaAa @T @w Hl KX 2VFV $WCV ES 8e5V$j HV \"V 1V \"T 7V 2j Eh ?q Dp 1\\ Dq >" -"l Ly Hn Bj +l %e E\\ At >s$v Kx Mt >u&X/X'X -X -X5Z#X -^2^0]5X Jo q ;o r Br%~W$X/X-X(X,X6[6XAY3Y+Y0Y%~S%W 3V IW !_ FW 7W >W Md AW " -",W ,W ,W ,W HW 2[ ?V #[ Hn En #` #l 6\\ Ax Mx Cp 9X C~Q)X?X?X\"o ;Z 1V 1Z FX KS 0i #W2" -"W LV ,i ?XGX *l'h 3l'i ;c Dg ;g ,W 6o %^ 1g B^,V.^,V0g3V X *\\ 1\\ 1\\ 1\\ 1\\ 2^ 0~V2s$x Mx Mx Mx MX -X -X -X ,v L]5X Jo Do Do Do Do HpKW" -"-X/X'X/X'X/X'X/X-Y0Y\"X )n XHX ;UEU XHX @W &W 3VJV :XHX 4W =W &XHX " -" 1\\ 1\\ 1\\ 1\\ 1\\ =XMV K~Y =S 4U 1c IdCc AU Dz In LX 2VFV $VBV ES 9g7V$k HV #W 1W #T 8W 3l Fh ?r Eq 3] Dq ?m L" -"y Ip Em -n )k H\\ Au Av%x Mx Mt ?x(X/X'X -X -X6Z\"X -^2^0]5X Ls\"s ?s\"s Et%~W$X/X,X*X+X6[6X@Y5Y)Y2Y$~S%W 3W JW \"a FW 8W >W NZ 6W ,W " -",W ,W ,W HW 2X \\ 2V 2\\ GX KS 1j #" -"W2W LV -j ?XGX +ZEZ)VGY 5ZDZ)i T 5V 2e KfEe CW G| Jp MX 2VFV $VBV ES 9XIX8V$l HV #V /V #T " -" 8V 3n Gh ?s Fr 5^ Dq @n Lx Ir Go .o -q L^ Bv Cx&z x Mt A{)X/X'X -X -X7Z!X -^2^0^6X Mu#t Au#t Gu%~W$X/X,X*X+X6[6X?X5X'X2X#~S%W 2V JW #c FW" -" 9W >W NX 4W ,W ,W ,W ,W HW 2W ;V NW IZCY Hp JY &ZDZ 9^ Bx Mx Eu W *W 2UFU ;XHX 6W ;W &XHX 7h =h =h =h =h DWJV K~X >T 5W 4g MgFg EY J~ K]FZ MX 2VFV $VBV " -"ES :XGX9V%\\GX HV $W /W 3PATAP GV 3[H[ Gh ?]F] GZE^ 6^ Dq A]FX Lx I\\F\\ G\\G[ /[H] 0u N^ Bw E_D^&{!x Mt B`C_)X/X'X -X -X8Z X -_4_0_7X N^" -"E^$u C^E^$u H^E\\%~W$X/X,Y,Y*W7]8X>Y7Y'Y4Y#~S%W 2V JW $e FV 9W >W NW 3W ,W ,W ,W ,W HW 2W ;V NW IY@X >X " -"4[AV IX &X@X 9^ Bx Mx F^E^ =X C~Q)X?X?X&^E^ B` 4V 4` IX KS 3\\GW \"W4W KV .YBT ?XGX .V7V,P=W :W8W /VEV 3V +V /V " -" 7eGU KU 3WCW ;U-V$U-V LV5V NX +^ 3^ 3^ 3^ 3^ 3^ 1~W6_D^&x Mx Mx Mx MX -X -X -X ,{\"_7X N^E^ L^E^ L^E^ L^E^ L^E^ !^Ed*X/X'X/X'X/X'X/X+Y4Y X +Y?" -"X ;V *V 4UDU >TEZ TEZ T 5Y 5g MhHi G[ M~Q L\\AW MX 2VFV $VCV DS :WEW:V%ZAU HV $V -V 3RCTCR HW 4ZDZ H\\LX ?Y?[ HV>\\ 8_ DX )[?T -Y J[B" -"[ I[CZ 0WAZ 2x ^ BX>^ G]=Z&X=b#X -X '];[)X/X'X -X -X:[ NX -_4_0_7X \\?\\%X@^ E\\?\\%X?] J[=X =X W X 3W 4W ,W HW 3X ;V NX KY?X Ca 9Y:R HX (X>X :VNV BZ /X '\\?\\ A^ FX0X)X?X?X'\\?\\ " -" Db 5V 5b JX KS 3ZBT !W6W JV .X?R 4V4U HV ;V4V 1VCV 4V *U 0V 7fGU KU 4WAW TDX ;a 6V ,V 4UBU GV ,V 3UCU 0` 6TDX 4V ,V" -" 2UDU >TDX >V ,V 1UDU :V 9W (o Do Do Do Do GWIU J~V >T 6Z 6i jIj I\\ N~R M[=U MX 2VFV %VBV H] AWCW;V%Y=R" -" HV %W -V 4UETEU IV 4ZBZ IWGX ?V;[ IS9Z 9VNX DX *Z;R -X JZ>Y JZ?Y 1U>Z 5`C_#` CX;[ H[7W&X9_$X -X (\\6X)X/X'X -X -X;[ MX -_4_0`8X![;[&X" -"=[ F[;[&X<[ LZ8U =X W W 2W 4W ,W HW 3W :V MW KX=W Cc " -";X7P HX (WR !X8X JV /X

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⪙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%0D@nG+{Aj*fN>ZEhOg(z0#e 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∓>sQz5}xm5=p=9LCry8L@i(-%(tXHM-) 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

>oE^l{G(;f5JwTQ<+9z+5`!es`7 zp7KV4>dPbw+3V~w4w_mR-w`kL5E4Ct#*UzUyWKoHoZTQD!k~wIeY!EIcBE&wpHF9C zKpQ1Y1Ky|}q*pWea=N(G>~yHvwX15^uHx<63b(#lwC#-&`)#E= zx0O3=t8~~}X8*Uc9dA_bvIA5*>@3}3SMTOo@8MnT;!)w`QncN^z;0Xqj%|=;{PjQb zx5Bn|#XENt?${11bGN>czkO@o_P>?dZ!OxsC4b9b3*UUbY}=a^cH8o{yq2})_3W)% ztah&(-~12#*1xK@{KdF)t6`U&e#chRu5AFzuB{o4b_HIpMQE?eKw>q8S{+GmV6p&Z zWQrN%BeJvOZ?}^;Ia6QT8nJD693hlJ3WpC3SVAy?6oK^%z#<7jZkQNvJj33FW#ahd%WHDL`R1>N5>F*yC4U9qKjjwmj~Sk9pi_mAkbmxfDkO%3q#%In*by8*Kxwv zaPlog{p&>IR&u^wbmgx222|Rlk9Gm0K7dg!dUASEth&FFWP!$foJQlT=3{lduxwsb zi4dy{cTe)h@bLhwn1tsM0#g0sB%xY!Y+4!x$XqK7G>AzCX#hYkAsHn>Mo9<=n}e9S zh6e~xffFb{*ydQl4^Z&}LAxuBO;oT06da-?g&L9Uea~j$ZPPY})0`o&vHf3^vRh3{=aa8iulCt7~kx@f#Zn9j0BKaV| zV%*OQ>*pO!56?0yta_12la#KBhZ=0#s#q2k6JXPF+=MbNT?K%j;=r*2lp)j8Y__E7 zipV@ErA$s8F(e*L=glOA%|($Gqk|4dg{(%0jpNY^5rGG2fgpsqkBXm*@R^H1?~Oq1 z4fnQj9mN+&Zx59)Ma)g#?% zP;NCCj|!A)JxF71Xpfg--J58EmE>R^5|PJASr{Mn^m4=C(EdbhkUx&#=p5zY+0El- zyW2P5JqAO)Mq+P*b^)yPE!I;ga?8V4|vLh^D_8m&bT>E zxjTU}Em*~YE-ui!O|R9mm#i7q>=YX^Qn5WYu!ezqKdC+;s6y!Y|r#zj( zv;xc~CSB}Dc5Ye0VHVL|L%Zx}-Q4F9UbCJyS=w{1+8Iut$5M4BpsI z2CKo#yWI=b>FV0)3~h7kck$|TMhv^6hTXgd+&%k%;hmg1oE_SocDK7Yw7WXCxi~fK zvahz^zKKe^tu}1m25HrfH*0oo1OMetmz^EX_FYc9Ivng_!)|xCVINFC+P4pbnF=IM z1rd5N9?fp{<#w-E?c7@LWM8v;d!x%PNGt8%EPeB};w}H#_gB3})cq~k@+Q4t8>`$?HsGzELTmP+Rr`IV;{;*P|Muesm~t^1l~)?q zSIZB}7SIYsSS8tmjq&FD;Y2vR81FA21Ph1^VW8T?k}IfsIax0b*&y(sfB6jw1Hsl= zzhNP#=Z65FtGQq#XCrnSrE>!TX>1#x+bBK7U!F{mCE;z(&WS`xB8eYI`z0p^B*zny7?@-RkU54;Lj%Az4qS(Ty8p`t z)Mf^{$>;Il^-M;wLOp@WH*B5VVuC%vcnBOTz|$F=KmjzO%ZB^sCXN5U$Q(!;$Z%78 z98w#TZ;*Me4!GSWT@EgCK)Ik*xJl-l^5!;`avPrm8{3A{fK4*rueYb&|w zHe!)A&_JSrv4f2Xq=OM@lZ0 zMfRy#dkx969P(Z|afulQWWEv=GU<;#KnVmR<3$R7k%HYv#>|JK06^*UWE+_S<|zal z$fUW5fW4vrBJ;^W->G2CL=a+})eFD=cvC2kU7{T1C#d?JO+tgLnP!N z&Z7@w8_f=)o%>Oa1K!R(UJk(LZCvNa9wE3+kWhmd_db*x^k0+yK4VyqA++PL=XS7c2II~-AFl;J zP`LE~yU#i7?tS2AO+*|E!5$4FoCpdyO7dUw@tyNZ?Ey)4%05~3tryf z;|7Aa;Oso%<~;1;H0BQWbEsJ~deGT*55^ameAwM(*xkwIv*zUvZpZ^(9(`!!a7bWJ zc&G;J0}R0k4~mJV357zCnvC{D>%8%8k*s=DZWo>aw%Vbyw|jBCE~R$K*cmH zE-pHjmCS>H#?VMsa4LhKwv-n5I{zCG5?F4k^avcs+E;E@pWp(7J9y`s0*c<#Ax>e znd6i*L}~y3@<|EJDDl(jz0&wT8h%KofSNA=GIviwp#|9gCi5VXKb7aNG{nf{lua@R zn<3zHn+>Rtq!oZ4sLc%21{;}&sJX$LWWLGds#IX||6ejE0G|sI2>f_FFDW1;J|vbI z;!E_Q#xWS2)G$^o(jWhqH~uXo0v8`oN{YkBGth|)Z?JOSAaieUj{BcvzRBwUA2N6Q zA7pOxlG|kRO)}r$bJs|J*Z(;(he7NHz^2D$&;w)+CT_V}n>Sppo|$9V824_FIq4JtZt=|;Z*y@QQiZDVFN)1tNw`z=bEIW5vg_*z@B&CNHQ=x?7?9fp+s$c=4Kk0+NQ=r6kqgC?T7E=_fU+QqnTZKL6i;1@3;+&a z2*V$u2ks~P?Wg$cBcu0`Q8Phq^Wk3e;odf4x4{>%5bie@j-Lzvzm&aabR2h<<;m(Q zi4x(``^?CQjEMB!8zekP!UH6{H}u|!6utKrBtQ_}dytYyQBuiQb#>KjclGS__Rh?n zvpd_npLh1_?$^El2moSNPfwpc=bbn~ctX@KZr=ZW@A)9(F%S-#=$xcw6K3fYEn8q!i>z*m(_;tm7jD}-zx%D%jlK2@ zjA@qALs#QEXEsclv|#%*Wt@a~Ht0r7hNlYIbB%nAHehuHycB41zsU1NSO&DnaoA5ZK^w;?{iMZ$5$MB4YR>K)rLkmYC>lEwjqc>xqGYV7I1jVmj~_f-?TfXU>{mni*D=(Q;vX9H544(l zD*0obv0rC;qR~CpXzr^O_f*om%Itd@$$eeUeZAy?L4Hq{b5ltmd`*#cO_6g`tw7z@ zs8J8}I((gbTJ`mu%sbMoC69f{ZF>_9tax1G96QEY`*nufa>;FZ_Nbkj^YZgP>$r^? zvzniql%u?H%E^pbP5n9<+^TW1HjdPk!!Tjf;d%PflrzlAU)nVMNA=f>C->lXX98uDc@Dvaj56SjT>m(h?iF6Xw;#2uxw|v zV!IzOuPnA!7qHmoEG%?}4#z@g7%b+p6t$_(!E<5Pvjv--OQJ^X16{AMzA&UK2x38 z0L&qkA)ZMITZcew!7wQzNQW}-%YVN_5iVYj_2i+j?(=AO-jS{}@i8{AERuEu)cFUy zau0N-M3@tsMR*nnFfSk^?@r@N9tXXp2YayMbN8p`PA{yj+%6Pg?(FUIvqN5RpK;-k%} zPg-)X?oQsWi7j=N!83ndnY)}9SV;%4748eHzf9Rya&0R~>uN4P9W*S&ndJlqn1koQ zJK;HCz8H6b{7b0-w#6+Z{UXev%qPO;F|TIAuN!q~)?x0X;H!*=?Js;RA-RVUU~U-T zwa-{(zeRzYCuSw=T>>wW8 zm1(GVlYCg437D_2+F{AI*DU=dX2a^u6LQTeYg?kZ8KZfQVHQ|+nq`Dda~3Fb3_^#^ zGRgwxG^V3t{{^sIPBXC^NLGL_U%7>=J@HxctO3EyWme> zqg}U6+#`eOfnIw@CA+6q-&d*cDwOw>O2GWCQgTjWj89DFCzJ_3%uQ+bwT!I~6cQ|Y`z9U#DivJ~2A2K7ao+Y+r@1T3?l;JX z%$g;?bIxsD4!H1Y;+bCgR7>9YOfSc3p((2g8?k5IG-}#u9Aj0(lx&n&jyg0$4%JJ) zX)0-bnc`j~Ed62AQ=hKiXS`!mf$HbY%2WEBqdLhEy`)$A!7;P+I4#3&sk46j&En*_ zgug|vs*y+<)#@6Jx>%l*GHOzG3&I1XbTBMQf z&?qW3vKp(boGt_=E1$^Jo}DwT`hcPL*iI#>BXK+n7dp2C|^@B z(iD!AJKA~+TRREN``TiFIci^XXoKfKIw>q3!Y0tZ-9eDN2hMrzdiB=$P(7P4uXMFm zI9tjcsOAbgcn+BFs*aSGg)16&BEEk4=`)N$*xh@OcDjSnNa^-?`OZ*TkzG*cY*hhW znQs~Gg@`GI^2Re%nbQJ;VKq#@S1^ z1(*~3_T~#BJT1^00RN?q;l2|k5;Y$PB{G``^#YObU@U-tytjZnCc5yjAde5+6M&1t zz9)}-3-Xjf45sGtmGfgW6Tkn*zuSNDgf;HuL)^|?JDS^eC6iw9&=azsm^M9y$GY-1 z3qR74u3VJJbK!wfa-@^g(GKz&1Va62OWr4~`R8k5S1KbbduwOPW2;rUOV}J&7m?{nBB?QaNmFeC{H$e9%ijvFo4MwEb4y6HYCZ=CMVK*WiyB z-2;p6wo!e{q`pCGuG1R8{5r2D<<#8q8E*x-^B%g*N}sQCXixJ|ea0F6M*}|1i;(`5WXn}U=3Q2KMW6Z5rd=!u-ZJIfF=Ret)ngtCD?U+6 z3HM6Oy%4a>dubTv^G?I8RX@e3CLz%&1u27K0``bbKBbqTK=m1uY|)~|3d_&kme)?p zD+jY?v%n{rF=$aRUZ#y2Y;Ybks-eSQ>XpL=74|s4G$`P%uiCB9@Y5#6h$ds%s$H`g zh7~z0X47XJ_nFl`tu?Ok*3TTyDU)fMqF|eob)PIV=eCnY7%VqsvtzNvC>F+1G+guv z3)ipLJ~bF7gTaAV?(J~$Vs*pt)!X+T_U}J&291-SoIba|wsEJ5I_8XAVO&@B^c}4Z zScb;Fu9RJuNv}yI*JYAx(kv8UeqWPKc&?Y+)n>!EzNyT$YS#^0pVuVWFsaKQecmqyi` z&5Whkt6s|&Vf$LZ`Z{2nV6~IHe!sCcU{y~-gu7De`+y6pC30#j+k=xQPKmP?m{YfCK2djEmbl_ zjY75CWZJG)rYLRF#+*HiK`Telk6GJu0Ij>&lHj!mJq&Be%ydYzk{VT^R$Zx9Rx9PZ zRML7?PMs#Ro|f;n$Z8o`H7(o8=!;n{=1OqhGDC1zcCa%u+?yFYkQqI=Epc#L?!k}K z2eXS$sj99~twX+}tL_8yuD;UWoJ7#J-m3egbo0t+Rmfy$!@UhvkCmtq=6>^7qvFP<^$e zdTYEr)t;VeZ&!`Cvzo|q;+dDbHhAu6sPxoUM^b59--)i{7+5(xba~*}$lB*Ss_UKJ zz>bm>(uoKn;s8|CL9Hmuam5Z$ zRLU!s2y-IK-!H*DFTrZgL%n%`IoZF7pa{J24VVMPfVmJ*S$E3?P>b$#DR@rAIjm;5 z+`{>zV1^TST|D$8u`E&N;TUu^-}iP$WVOJ#lw=nn$fMM>SG|&8*HShS=2+j1o8>q+AF+VvvoYID6epxk z@#u3bXdVwyBFu+9x)GOt#AO7`2M`YNv(KGokR0{YL12zebB}oSLr(RG(>!Fg4{7y% zMvJ;-QlbEJ)Fn!Ol~qES-*9Pf`;B)Z+~ok*X`|0nm%Uz?LlYT?^j%4AG!;P~Kto=9 ztheoqMR`i|0ggL|g8CC#Th3`dx)NqS4035RFgYsQNUzak8g76?6y zrmy%SudYA%_h0{RVfBj}kDsAE|HR2Nhnw3g4a_lL>=I+YtT*3Kt8XY3*H!XsfVo0` zRVD?}ujFK*ZYi?wt0i|eSuj|j$?xkGS0o?9HovP;!2?G8Iz> z_}OykB--uKkrxc+xvhR=$7!k5CdrJbm3dlCnMPfyRP0tt8k9Lrx|{}+w2sQIHcJ5W zDytbUeA1qz!(T}ScT2+ES-P zf(0;dib9ZsSb+x6;QYD` zE^2JTbFl<~|1)LYl_z@FfHtWvVx9|bIUJQ=ii88ZabzhbScpq68ZTlV20to!n(S%n z?P&V+;)S(*n=&t;K@)f8X%I zk8zw}yo40aWXaiR(Xpocy#IMDm^T*q3RUyfK%i&4v5n4S%pXCw4ep}iF_-;UaD#+DD(hF5R9RQ`IVUr>d|6TS!fAPAl0Ua-rhM#D#JL!DEJp21QTsZ~ z{T3uxK$vN(Va8^h;V5Y78QMUKQqNGzDU)>4C_#o!?x8O{@DWCc+xx`r>1hv(`jlZmzvBqPv*1FL#D@G zBanX2Z8~F;e9Fj=Q`udz4|_COM;z=iuN%EuWm3(K990u*D^Y6!^IRL(|K!=hvzOYB zo~hq=s-f>hGPlgZdi)%^uXU_6%O#VBREiRGma(CFMZ8y?g&BaXc@?maWx z+`Y!~!_h-mE$y9rN2{~DHg&Sq-Bn<&b^_-1#(=vu;%W*9TjPOBS3`F}Ygc|>XC9mu zz#Q@Ny)DQnMsWHGO};71MP=Tz+b@c9QJF)QcUQTAaRgex@U}{y7-$iA?f}mT%qxOr z711LXj$V3t|7`!$eb=sIU}LPXxS^%JFcGaRiX&KFTVSour>pW9RHa~;i^_cSTArlK z5@r;TzCBLCHZKn243yaBqBs|1xo*=f--LOt51DgH@WX{D;3m%r$qCO9Ss}^redK6T zG{&J?1-}K*UWfUH!9q4K3l0p)v=A9g;^M?Y7Y{2%)Z<+TyNM@Ktwjq(p0!fnYN6|GW#sh^|LX!bc)k#}%mwMi z2s3NalVbe_5j1$ti1Tz^nj)x6n0mFz_511p(f}|fQyB>v8&QZ5{ z#6=A{jnAA23NjBohFcEJr=0w>MfRyvf8K4p-l3%u| zuXv2N!|Vx*>Nu}&WK4~I-_+Rn%;%qDWDVtY1q#y3%d0oep1W3EHBgW|tIfG*&Ke7v z?r4!){`ECg<~>?-QTp-QqP&H$|B+6KKpjrymi%^7AuDPT824Kie9SU#JeC=|31C6s zaMo&^W%ZDhvlbMzx?+w&DW_@GtQk2La@+}%95rnu9t+3}m}6n_B2VL>6EL6S40F5= zC!W(5^_X7yncV?Pd`hnx*W}EZ6>~;4_&=$^jrKDe3yHqKnCEF~$;M5Ysb#kpCi%48 z2AD7U{bM`}m`~X`Xmtcy5J$(F(FuoR#AbVLw?FcS?#7a>4tI?|GBP^(Y;5B0i{a-J zQaCmk(!+h}<==WZ@O;*yTk-IdtYOwhkI>qsuxB~udtlbw zWmNNd{;6EsWRjgq&|?wfd@i$)rdNyjVZUlNmwg#AKJ{q^!gPO#xonZ%^61Z7kV5~U zPx;XvT656O9S?(MY}OTp>ywqvv)$BIG&T+5!`ph+I4_#ZMSyTB~G*f z=5&pV+vNq!ATZ2!t<`_5mE6&Ihmc(FJyzCAC1Mxok5 z4lu9Ix1ctWPN**Eb6jx`p6`sCQR^_@uvylfmVh=tpvm{^kV_=xB{mBx?f(VlK>CJ6 zFGkK>Jnj^3N=V)tGPO@Q$|Nu+*>XXa1K@&ahfPiVaKdf8OOUm~p{IECDO|xu@?L25 zE|M4rqJL52#5N(>KfHyQ+wbRCHqtC&Dn|GsNV60DzxkLDF)n7mH(^e`#U{+jO$n6w z!98_dZ8cYJU-{ji|5)DDXb4#yB_U5q*p&|0g3j$#rN@r89okz5m5&3(@C;)TRpwslsVSMJN zANr{qF8wFG`j|y|+GRfDVJ^7M7i=1E`=(ue)2h72NbcFxXVf2DwX1Hp4cC0s%`m%H zleym{Z!nu0eg3(Lsgb4So|7j4b1&9UFRk1-cm8Tk)ks;vbzXl%`!P(ON2aXXs*mpJ zv*E@gmGL^Ac%2(Z`r?UBjs?vNUhAUIwj8uB1$aVozj?`LUJTGnK4!*Yn0Hg)`HW3J zW7VK$IW=mAQ3B}z`y8zm<12G!6EIGEay=>V9Qu6C#xC0|fccEYFwYwoY=&{81fMl- zP`!58mM!e0PC2HQkP}r(vx){Hy?W7XSmS8G9LK2(ocWd8F~h)!aA5iJoXfr7^P#|1 z0&^!jyG{W;3h5|CW}sVw`VQX;@S`?4|z!S9<|`E9M@x;zsx!n<0@BZKOJMt)P8Ic%Z( zP5S#P)f2tp1!EbquwXbyK5DhSWDs=cP~%oBehjGemsa|P#qi81e{Mu5MLML<88^x% zDcQV5wZiMZu$kUE%dOFdE@2YB1FV!mt8z^KJyOCIBR&DA4j+duNp>zj+K)5 zc!I+L=v2Z2m@lN5#azqlV#f=Qaz2lL=21Oz$_69mXA%0kRrxSzfgN{9j^3iJdyLZk zobhBNT%4JezinHq(_UuM=h52jLD$o#PuG6?)9}id80_40{8B+tjm7M=>nN92ZewA*dGWu<2%rKhuZoY6Jhb?zH?^o*Jc&wLoD5ACYCRAyJXmV6Z*ianOlLJtA<^syr7}hQ-Wm~I2p-vn1jf2y?+XAznSHUtTN_ zw+COJ034^Eh+m4$Nq^P-y$C!n?ZN4T-*z z=Uh&@5M04Q=S+ZKOL>-}R?&`_^U{`Dxg7(q_Eir7t-&R~)JvHWhkB&!|4S zW!K$uneK%6dr^CrQQy;M;h^)&yzq0Q{E;GK3CdikML$Q>INWlf=Den5KRxR- zE_lq~`JBrz@6yjXb#r#@qFoP-jZU9AXmwa9lz!1dBbqo*8_Bt+PCW}{ZqUw|^b52B zdV9{SpJm7g!&D#B5_LLhkgf6*=sl&Ck18`~O|V(?D^_X^mb;a~mqN{$P3TBkb~#o& zo>4P5WB1Lw{BthPjKc+zkJ>C_c4j`{oO1KHf5|aqqdjAK#xYNPo=5R`hs)U-k5!a! z$G?+w*$%VKQMV4y)q0GNgU$zFuCFJshQyK*?? z#J`!drp!}@j6Ir<4zrpAZZ7%ZU&TNCs|F`mY*eK!hMh<)KJGtq;bz1B(+yY-e*AJg zx!q~=W5kw6Z*(fvR;irJk-BqoqH=keQCDrymn)=Y%B&*kN2RKdswru+)lkpr4-^#^ z`0`=5P?0Wu@~|TRlC1E$r0|ZW>an8iwzTYuWas6rMW4uOZn*c3S~~`OwYRtEOU*kD zg^ylgI`*5}>imaW9Gyj$I^U);ch!eI^^tImx1u%C)RWiQo$BpQ>}`+qwW0|$Ol+3M zh-kAwjf=Lq2y^ns-2pU&_SJ_V%Mne4yRz9d1ek;5BFvjB98Fcu#=1a7g|DHv?&P(L zXCJ@7x|62;pZrypG*hW4E6cB`OrdG0wurAOV5!!gJl!u>m)~Ks8H)IMZF@%|81BPejpL<>ATP<;|6gUC% zrCjGi5-@kn2667`g}uBON*>BpKwwa1KdUEaF{SI!?TF>wBo~C zR{c$<@j;k>5OeI2Z~eq-Jd+nYQd+PwH}})O{~vC=c&fDODGXG(ckBLzPcM|0&+M*S ztSY-C`4|zq2|G1lmOs*N8{ySY^qGqx=1s2ag<1Ac@!^t}UG#9^IbaSc4w5f;OkzQw z&$&z>Ie1Rqg1#ZQVcwxzau}eo0do{64Vc3c5eRIYrwriv43xQ0h$$|CQM6&fqDOt^ zVt{d|Q$!q>Sv?Ltr*zU0MFy1lyjiKo zHun_#7N>LEVTJSs%;$nmDB)2De_yA%uT=u(k6q3O;ZT>?*_Mdy*j|__O1Wbp+F>nB z7T(!^^k_lpK8iV^Hyq2#JdyG7S!w2Z`L+wnj|s+g5|QLcusk-&9vP*#lv{7ex1yg5 z^_*4@nze(J{)O3qw$lNF9yP*P#yS3l$vExcXI=c1oknhanAMH2x=~I&#wtc>*{~^R z!YrF($;%nQ{FRMh{4=|WI4y$B^2W`6;o|Tr=C#MY=5?>()rZSDAMnlvy`urwe12#$ z>6*xO0p=r7W+Xz*q)7AHbdbey3}AlC_?scWX3(#G8PVT&$i~yITQ=3FRMw|-_FnDB zhb+py4kr20Z{pj2Q_dO-jf${AnRHoSj80$)!md515@pTp2hOJQ(F_!@DAaDf-lfvm zWC~l3%$1!TluEX1wN-lEF14!Jq^eeB>{NW%KubI9`euvza6xiMAe|d7vqZY6}?PI1?bwmtU7KG~Xss^h!SKxz zo%6qdIe0GE=EQ9IH(*Y9ZhRl+AgTy(FdQNi1woGHNAT)I4;p6>6v;ojCoM{4We0D%DFSNQtVkRbT8*Sm(wn!%I6b~xrlu^=>gRjLUu&5=l$%A z-!kKe*}~3+8JIBB0SYzY7L>V5H|c>wQ;*rS1mg}0HEK8EI&3!$a=Kx+`H9nT)2g}Z zXD)>-=Mwe{xtHAUcNsN1*upN{A>XuE5koltscR$FSrln_X`ipsq zvt`@gEG_@=r#}wOPAX}oH|j`+9A#18nUegG^3t{HvIjZ^!g7d4OxmfZ`fal=&4g7x zX;Zw4FiU>pL&dL`y$rl@9J+zzxLgWLFlP?pNUupgLw}X9KR8 zfCnv>&n?tljpD9Bd(UCJ8w%|YhZ;h79bK9z#?aDWxFFX;^M|T-^(2z58rea;;xzCTI3)8f3*zE)4r+?mPFNJs!4cfj7+rJOme+aq033`4T_Pq;v--P|21^p{w&wR)=9^_|I?#ZNcGVR8{$(J!^ z1jq5k?&%o!%&MM`@~`q;cZ^$S67&cII zQ+{7kbx%@#E2rv4cI8!T_j6D0P_X&_7G-Xht2}x9vUBfYrlSFUptj~Bwl2)?3fVSb z?%EX!*M-VjlTE!v?H#GEju>nfi1T%r3+0Svs~J$U3hPM zmAk##g~CZ_d!2bkY-_*l`-wtg|nnOWU zcp$_ELBEd>eGy1e<}-lxM8Sh$AOZ>g3xr6-_v_+~%F)gVU3q7#0*_h?=Q}EvTgoTW zzSZr~=aY^rDcAL+^;XJ$JH|fA zwLMGP`eXc|oGobQyyG!|?RR|CWsuxq0?bbo7ySOKZ~x!n2)#}ND1E5sP5S9xBa05 z5O+R*Q{yg#@cF3UpPx$^naV)49`ipmvc1}z)0&L)y6jKnAD&ly1ejw4%5AOe9-8+J z8k~Cq<^z-pqrkxM0fgaM-6U_s>7;N#X&%F|rd~d7HjGo|X*mBDZpuPW!f3*e?X)0~ zg5Mqq9CBLW$XK<&s#ooX*DmUvpZ&_u{MK*zF35c!;(rL+e~P$%j<|jo@%|k3|2`T1 zF&+ZXzX+VXbZvy6AXTPIoFx2*Fi!$+{ zr6BLrHAnAZwzJjI*JN)gvF?fym^TC<&Rz9U*RBX)zOy-nbRwESyW11QGe zg!L%Gc9<9{uJHASi70co7BHXj8b_^~F{=>(AIBsso`J!O8n&5- ztOk-icNqGe22h#=4wJSk5zDQV`+nN|!&T;aYQ@Pe*~vW$_bW~YiD%VwmF|s(VbG4XVRY|J-GLrAIysiXtlAbPrpvNY<{ zZSu?`ip;Y**{5n8fRc3LO*LSyLN6yKYdzMhFdgNESutdiPjb3hD}`w@Q>+ewoGDr} zW>(-Ag;>szCI^Yld5%HeW`?2g^jUVWDB(9oerYQXdc{Gl+Dxb~-1L_|_L~6zt(z_+3Ozm2ygDQvT1o1 zyY*K#>BlaeBxPsRS-;_FQ<$)L#=F=Wp&B2`;^%|81rQ@9EwHjy@`mw+86IK7o61>U6q&K zRa8EcRy;jRPYUA2zR8haOp1610HI2U{xB;46yb@*Z*AOd%6!AbrZAq?>xSM{35V0oxJ3VN$Brq4SEWmt^$Z%YV zIDe1og(vpp{j(zCe0>TcFiyrNg3rP^DL9P6J)|!_1{4*362aaf&ki(l61IzYf4`{{ zKj)_LvJUeuvG-r>*2I3H>U-MSE?v97`tEms_rL$w=d16YfA+>! zl*ZoG|M7qO$B~)Aj;)59TYR=DdA>d|&{ndzw`QR>ccn75QXF1NdFNuz`J@{SK{GMic)d6L-WL?edIAb4DmSMd=PaF<^^8l`=7<_Qzb!Ipbwn-3;K-5LHe$j zLNEUj<<^V5`fr-L>;0QwyJe`(%9S-q6e1minMo?UH@4&u)4abK~sntAf}! zg|Yk6kA}_4wE*lCC`|c`RXNGZzKC(3N7*qZYtf;Y;c`|z285p%I1052C_!YxyT-kf zndfwb+cy0IuO%gDa$p<<6Br)&suk$gK$eTSlv$G+?uvkPElxH8b{vKdNfcvB?OV6! zE1!3fF`|CwrZx)jm4@4EpV||v|*yTe#9Mo7D!*TMW1&advg2=R>Kw5)tf^BPddptodJs8 zZgpUhM5j`RF!epREqtdyaF=$4wm{IO9BO%5qOh7dllerb@r^5Wsbthrgh z91pc8(hr_1x8gwaZO}GlR8APx^DKqqOB^4p*e&?sUpqJy{t93EobLjTFFZUf@vpr0 zZvwX%z{hN^gN3Z?opzFt==Z8q(yNLgrROn6A_eCoB zIvoVhXJSswa2s&Z&z#ImGK8M8XAb&>hsJP*=a}9W=AL*h4?WCC+W)|ByUZKzMSNF- z?xS8?g*qpg{h?L9jgf9;G}#_jugdv2FPXS<_sO&QwH?j9+cXx=8xKZu_w?@9XXa2D znZE4IxHKoNl;*4D329a&XIm&^YYnBZRY>a)%|i8Q6^P0lj3u#MI3B9A z7o9N{TvC+WSC&6lR1TP0hK;Q+HO>7wRX24F_vxmmzK&ysZK}cOlS%E7B}2HLl&Yp1S%-+o7h1 zQ-jCvJuYnN)4CE86TM9-4ac~KhEzogvFu?LNrORfaL2ihs}av=Gv4`^)F$*k=EGYIWaECq!iIA+2A>$F|fR$ z!~g%mT=Z%HaFNEyD-xdvF1^r457jMt8XHd;@o_`0|2oXc99lH~3muw&0rPwj=GaZq z-P-=ixtl9*e)?bj>;F6c?x(N*!#~*aq8XIxPyhI*)h}lI`YO6Q3l8ruLEkHR=^@xA z!tnu_e=Bw*{Y#jOU>812Kzdif@y>!X-Gyh{(&w8}51Mkvx=NRt3YKegmrKISxjw*r zHtxiL#JPlH%ufU6%L$^%Nk@NzN7Q`EZ-h4vq|XEyf#fEfb&ff;V|LY~OADC4WYysI zIB&*CSmZ8-c?)1Zh*=`M{)JWb!lr)i()YWKPyF0{kL7X5Ihgdl%=2Rt#B6D3G+{?H z@vc?fAF@0SSe{1haL!?y_a{AfO7pK&mw&mmHnH^P!o6p2fA@#mPwxA91(&g9uT9?{ zbxkF`D>2WHJJJJs$xBKBJ7w8NO<7g5Hti&uPlW6qho7RhTWwej z)UDF(%gQ>Gm4%_=*L7NS4_#L&(5DZN<%vN(gbD2y{Wz<~@xcV6!ov$ZN8zyG%Lt;9 z$|QNQyNLJOWawSo514i(-=PRUuc`$Qp zxk+2Ame;GK?dvel>6GSltEAX-bTkr8Q~vy5wKMM|m3LlM@<3hwLR0mEY8j*2Mh)#l zlG=OP`Uj@Q$KKATztRe=Y5fJ}M42~*54OYsa|Bo5vKM3Xx@ zD!n9~C=6+7uCZ5FJF9jDYkR6M_21svvsdkl>O66ona)&8BXPFAK3Tcl3Ya6ED9ZAh zG>>{8<`{b`@*KVV@54MF@s)LwgXa`BR{S?%p6gd{z?`6R(-tOv+F&~%FW4-5@=o@V5*`Evuw_u2np^~|%(T3BV!OOnUXxKJ&QCfSLpZ9QqNf654ta>DZ2qz0FF`ca4<4%uMlyiNs{gZ3G_858-I zJeDa|GjFHRrw?O%&Brd-;2x-EStYJ$s|T489R#Qm6oeVRV9~a-WmyE|8Ra~!z-i`!nH1vUDDeQ4oPiqf79AokFi&2)F#p^&rZbGG@wpU2>BCCN z8;@N)IbC8Y=ySl3klbb=%GPCB#o#FmUKAK#xmi447Odtuj+*B&XMj*$)aTf0F-n^T zjRqn3Z5hPGa!>pM7nnSD>Gum?e*e2az5DAwo z{8WzgrojlF-%u+tss*R0{bs`mht^kS#!j#JEQ>Cj4rpgN)i-em7>?81ufw(#=i>Me;aas8}@vQYsd*>{5zlXcR~M8emC5e zpPLS`@w;vfuF8ZiYQ){H`90saT%v+xly3_EuVvsgrI~ z%eU#2IT>3&j7E~f)30kg4_l+fa@xVT!VKpq%rDSnWw5erd-m42A~Pw=ELJNp&pai~ zNao;PTBXa`t;=auWOpiZx@Flt((Go5;*_T7uBKv8RsF)y z446+ceN(#DL2biBi1YCN!C%wcx2U7G`ooyG#kTKf+IyLnMom?|sW#tS6XWWW&iY(m zLtbK6Zb@ytp{1a&v#_rg;5q)nVf`Ux@&P|waenEU$yeJS}7Z9B+eEjBB>;@%Q!8RAqJ%s^= zn99`wk|zOk80nDx!r<|;y&b!HJ6cYjxiU8Q#h?G_|9-Ld_4C!$Kxx9@)(2D8+J^k2 zM;i_us5!KEhX8XJKIF+I+DGpRauO`xWVmocnvwwX^+IPTFkK%|8YkI84mo_7oL=4(2&uz?*mz|0^ z$D=k3iWv%E36W|l*Ma|S$6~gzh!u-1CZaZg`dYwwy`=EX_}Iks!nOPT-~RCr17rOG zTMoNz%ORinzTbk6>8DlmLHpZuXboF4;BvcY3@Tr6m=LkRIp&JXL_*`N8rpl_q7=zI zXO@H27>Wp)y}+n&4|5y12DDN57~GR$RExB7ftJlv@mkZImSqn2^Fd##YHxA1s7`nJjf`}LbK%rKMCg(+@BYKVDU6=-gv<&c$cfm^s z%uyIGAo3jM`KU>QB*~D`fRx}%GxLJ8Kg3cwtM75!{#Q>%-@g5BVrgY}XQMS}b-3uD zNxwS~+{3z#m>oyuhT~H0@r;~nI{i(99$SQ9vkYRr1!Ka9+F1uP=d`>ISw9c+YhL4m zUHx^;x?s;kJJraDE-Ie;aXp zAN70}c6}SN|1ReH-tYK1-~q;e_Pc-fx_X2^3bh+Rzztxo6a;>L<~^Ps>LwO7Q$8qj=m@yZ+N^P*{F?f8?rG4Qwj7PZ95Iq)VaOO4Ur|?Q)BI3O2b)HYe-i}Nxuf4nV zc<}l7#IBZIuvvoIkM`J2Pa~euun*Ip@C9F|{9l(OFo+L49|3rsW>~=^*xhDUAZ`Ia zob+-sV6|-4oIPX80i`jMcAipT%(wt*#WJm2Vh|?O%#lfnie*l#mh4MvYe>g7$jMF^}OwWv=`Kfx>o#^40+g!C zHMyR~l0-v(wAfLzJKooY&2fXZeqOJX5kaiKMpYxDzlHH)2Fc(Np(kx=-g>~tWHaAEFIZ7mX8lL&4 z;@#x=#=+u0hdD8#H(|b>R3w9832#A85$1sB2G5DCJ>HW`(jC9R9Qj58=_IVO9!(Kp zPBP&H=3=kq`l|pD=IetBg#n59k^Uvj$?2!~eevG+U@qoc)?rR2fYtVP*MD;U>eR}Y zKmAYt=hc^Umj;J+w%6$#Mx`Os?W3^98iNxt8H~)L5l(CYbK%v5c*?mkn_W2f+?)e1 z!W=$~2=jG)PGagL)&i&HVr%MJb!4okY^EVSmgXj6^i)8<6k{+Z5ht6oUNZuRs}XJm z*>bOG)?=9SV#|PT+^$=fzPH( zdj`jmZ&`lqZjvBe0p)FGWmZ;}&+-lh@4Yu9JV*irLDy`0wr9K7Y=PBjzdoo=4ir2qZQsV@33BRSut%$WaN2nZlKF*j& zS@x7m_>yx>jePRt!pzghzdnBTr;qpSkLMMJ1i_K1=!|yQ*ZMqQ$4dSK z4+FeE3)-HGFbB^uJ&q>)MO1he@jMN=aOZ7K;17Ah-{%G-n7<9Ve+_$n2@!z>7?7 zKLxEw75u`-Z{yj9%+$PvST$;kR&7#ep#XEAPk8;u|FBv`89iaG z!)Nw}^sLq64`rvN>0}u;Wu{+|9g)ic^U`cJNRBGVN-dVJsu0iCH`3YxjdG(w)t<4c zA?<@LF1E?a0BOq4l|&`a>fP!h}w!|z}Yqyy&3=3J!u zQll#_=}QAGQtP{+kOV!5F0~?%$=JDc+6at8(~#~jHPVvDATa>{czqs_z5}kd%e8EE zo9y#Rnh&A0ID8_t`qJx2uZgyQ=}W{laT(^~7!0vDmkJjJDf9d0sEo5w)Je?SO?=5X}MK= zFNi8+js=&S<+qlIO8TtI(0V7lbd-UxGd6E@sVyY;hz5iL5br$v~Xrrab$6Ak$UtGZxTpc9^P zn8zqgcT+f4!(r$diwb5br0?#oPe%T~jpkUGcRj@4gr8y5 z{xIge>tnClbl7hiSFD`Yq%IgT@7eS(eEhEoAE^Fw#D$6RS7H0h5Sbe%eKn}=<1s+~ zYi{Td`H^1|!C!Moy^ZRs}i~S-Gd{HFYJgFXkA{)7f>@6 zHD%67OIN0+a;hx9N*PhA3gnt1g}OwcK;_C(6KN~TvOgMeGn;wSMuT$5r0&;bwq~vD zF)2En)*Ow&@5qnjcALu%s;dsGYL9DL&Z9GDHZHP*SK0Mby7uFdZL{gY-W62oM|3V% z-WTlM&NcV3tv%Z68oI8AMHEC+g{`S9*j-=PRjpxGg%g^g^?_}Jq0K!Wz zbRrlo4k*Txoq0QfIjOb)3T-*U;|7|cv;@T@P%l{^YLJi)dvjlReXy+|-riE^@N@2{ z7r{b~f?Q)bps<*gjNa*{n;HrmD}zlHLQ9#mrPKzVw-j^DMHZ|Mp~TLdOqfeDi`1E; zIj_pGVipm`i6zk_(#e>j*q;OAsN#@rSz{^mX~fQx?Bhta1aoK?gy&+tXNt8Xl}HUX z!6{iOD%#waE1_PJHAMDGs0YkNPxAE=%o95{pom>LZkJkpF`7+^MJ7Bat^V>Yn7j;g z^0M#z%n=Fqj^wzH!&9{4DCrU)z5)@_rSC#m#>j@2zRuR|yACYedHN6k`G0%+_y7HO z7sk1mM`txS{fyP7+dR~^dwcKJjSXU;Msns*I{Fk(X{8GsPHBmd0<%P*TckIZjL5rx zf_Nse$bh;yX$hF`>Mz*4zGzQt@Vm~~^v1IB3eRYay5LdI1oU^YH{>_X`HfR<&Gj&I zJ8r!dvCLqYTtIV9Lo=WDKs+}{FrPx#EyDaft;FFYCcQB%4L7{=oE}ao$4nVN=~HJt zG@AAaix$l}U_Q?35c^0n>s|D$m&H2L^*r|(t8zNP0Ol|XmvmdB=Eu%NgmX6fB2S^uL~}mt=OOjum5*pL zaMhUP5Z0-iFsm`LLX1|DFqgxke1^&f%prz@=cp^mQY@IV=8Z|1&of|t`V5_hnq{)# zYEGudX%(jR;Cwzy>%nUDHw#x_^=MI*JY}`GMfJo2<&M|MXU$G{6K1m_vnZ!LzS|}`Ip3r2T)MlNf^e1@x z_fF5}W%ZZ8J^J^5|1WR;@^8O9d~Ek;U)n6JW%Wn(Jh#*1{?z3>U@(3~(cc(NKbeg1 zCm)5Yt(67L;ok)#afC$NjMyK+`tnd7c26Kg0njvS@RBB+x41#-_tu!j9CTvjG}s;uvr`5wiZ^VUI=J2N~0D z+PKeQEBx?-yp)e3sjDNh)Sx^qsFe9M3a3_WQ7KJI6|L5+S)CHVeQ;}hnuNyD5$IOH&=R>U@nrp*phU_6<3GE^-pXJab%`N99FE#v6P1i%$JRD$-ud| z1X>b?-EEbEz|bAH@=r--o&QgDqcT{v77`suUqdt}jI4$F1};kV^oj z6Sohx_pfUj*tmJm7eAbtzx&yV^PiqL?JdrA=J;Ge-fYus9BkRSy=UuCBVbOv8A+lj zF}9Uz>Cy(sizA4l^R3i}OOrqElbkG#iar3l`V050FW%dg_gPo&sezK|j{I}Qt}#J3 z={McRMt_jG954gdFcpN2$+e&b7?)rUjH95pU^fTza+ACoFh>D0m!0ecqsO}Us7Zz7 zdPpv(DA|wdkEU$8Nr*5OH0_2-E4IIl=rf_W6PSBw=sDO+I%iW&`zT_W9-(o&5aCIK z?c=9?&Le@)*Rg^JXJ>BQdOkXH^Rr{;_-KC5!2167wvF-NcQN1DMBpq;1FVp7jOfXy zJS=WuZ;Q?o&G{Gw4=B|Iyd$keAt4T4<=EB)lVMkmE*(nv97PKK`8*|;>ar>OiWxe& z4Bh)IB?I>HWE5<=@$K-!y+rF!xHD&=E)&ld=8{nlMP*X2zGT!AgIpT9&tzi!5)4~h zWHo8g$zZe(zFUhHGjUDi^w%&w60+QJ!$;SMqgWh?Uia|VJ+{kM4uurCD?B$vkvGCm zPGT=uJ^rv4NCcbu1c!-h->3OyW83%s zEMmQo<2)I49}T+>`&}pF;eE7eubJ*jORdXDE0?9mGgBh66o1y5fHFOx%62FfHkHbv z(b)`ic1l{n;}7O0LM8eBqC&0PW$=11#i683X=!O$>1if;mQ$q^l!};Aor87AYn?Je zu33f_om;M%`zHh2F3a+_uCUdw(1lW5Mc%a|f&LwA`+&B(iEe0NYpeODYOcOCxUROM zx7r=no2V6S4Tg~c`$)HIbC)pE4U&_+Aw*P2ZFv&r$Qx=8gXAL2eNtx*Z@>bMgM3`^w zB`cg_NgPgUIDk31Uc9@+0OrZdjr4=zpX37qWb@=HE%`>gzKC=JbMdPsB+PE0abs`u z=8>%jKL7sbzy7D$M?YVF@yh6T+T(st+(SE!0~^}6@8}yDY!W;3N+~}mnGGk#Pb~3V zJg$YvFP(Lg#Uip0DsC7h7yQX1;(6}Q{?bnd%HX4TaG>Oi_S~8N%8N}oqd0sFF*pES zjM$(&UvwDfeZ+zTmL>>sfE5*@*2vDj!$=MpU8ZS=0WgPP4&OY$97AqIV4?LVHF7Wq zs`aQ@c|xCg(jWuFvCac228C7`fW;$t5itwWd@XD{$0}#MCdr!-x5N;}Z-WW>tj~4C z=l?34^LTXb{){hHD}CP5FbGU zKW)m!Gm#|+OIutE@QsKK1;(e$x@p!hV> z7h>)GreMJ&Bu+vXu{UHf-EvTX`F$_-G|b&}nqV`Cfj~0p9k7G^IQJAcbf|YpqqJ#? zrY@L8;}php(rP*4bbV1+a$;!s*@H)qp1(SEX|{j!cDuz^?sW7;LVMi&H-h6ElkPA> zo#aes5a`BH2nm8Dg@8_Y0^bO^ZihXnTRz7vpY4{HLoVJ^zvHoof9m0%2{v@sZzG;x zW9YP9;4?^$DU|1AsS~$0EOny(mgA{+~%d_VcT+p^`Ks5M=ySGT5Tl&?uCkYyxfnE_c^C_5vfl>6lJfJzh483RU| zRVoT2p`6^f5D(g;0dvr6^t$vsr)8Pc)Km;E>a%1Hm6GIBD3sxBMN}q>XQY>^WNmt7 zhbFUEkuj*v+H91=_+?n1Ic&@vG|6DV)xetQGz~|GeU*FlmEWkVey3?YtM9tVZN6?9 zzUJ9^mm9ns{CGiDxaC7n%L-Fu1rxD1^agsjaP0#+5$2Yv?61i%pL%~rNhpD_OR#)X~sCGA3*jmc@<}$0qbIhDK ziYAJpNsD>e*qqq2ev+ ze-3jH`+ags@RZbS>2Xm*COK}1oFEuS>I4a%NQyHcIce0FrT8VJFT;Erf|!Y@BIXC- z;F7H56H!HyS;W>_B6AYv;!9x=QH1%@s{z_l{Ta;BrIUAGg8A0<703V`Uf({jVf~KX z`~UfW{XhQjPyfU8lV_P$+6t?Uf{5A43~XGtbw}^WU;}cIkikKcn){L0T!vdT=VE%LC@P)NI$9+>Yy2Xrz%GHwhP9953>^IVVXPz2RY(VSbIHFdqW7{Dxik zIEZ))8WY`EK1ICREx#28Uzj#W&kxBRZjBIa@H1bc%u_U`6AkCFX9^=+JO7iz`E^n8 z$xWN@-MDe%-n}E|r`By85ggvW;?ljfb-SG0@BGdqRx?twk+^!!!Q#*pac`JNTo8B^ zdh$C__r0j+PJqB1wkn96e(JZ~UI?uIIpTN~ zcD@Wb(2%3vgatJ4fceh>J7E4c>IBJupX2!@hWpqI;!)_s@zqyu>l=^bId6R>xSqId zn1p$m2tF+gldDO@1FQKtFOSX~CU2NC9}nALgMT*WI2}c2?mZsz9`gy`+pHt0X*(5) z_33HrWLZ_KQ%Vsn0nfwCw6H8arc#6za;)da4Tc;O?J?-e6VXI&REYbXQQtDmbrv=? zea)JbkMvoY=*)de1!VJZc6Lmb5ldfFuF7iFDUcu6ot?H`l>u{`O@>VAc7q|KPM+F8 z8>keOHp>>M*lnu#T3z{_2=j64$Te>BqIcI_>(G2?=c255$49=76;#d&CdSuv1-gg1 z)_!eOBU9hP)z<;$j;8Y5frgUKy!v%sr)NcJY*lxid`G`yYoBXtUl6jn)SOG(Lt=kU zc)kqt_nUK3V-aCqFY>(3FTosfa>R72DcVvK@&#F~Sy8sO*;SO!<`9^pGiPkN(uzoJ zr57-7D(5AbFLmbs4=@*lK`V2>aFARt@%(+5izNRI%(2cdslk|?mZroZdPqZqWZFcG z=}dAvc{)k>jCv2|B(+&A(%a)(mQM*K)Gq=5JpvQP7LbNnI#Go@LZ-o!B$tGAsLc}6 z@kZ}|3Ru1`{*dBM=*B$w#z@mO(yi2%!gg;*?gVjx6JQD;S$ zJd)Tr64*La8f0kC9Hp!0bGR|9c zV`i{jeU3P+l7cES?d7nSgkBn#j8PLLcN*HxLcly9#9Rssn{k-d&I!)r!PsZP++Q!> zzj5p3;nBHMb2n>y2ERXi^v2x6=#G(3?1qy$jx)RpKP?VqF*b9WRf6X*14L-TDJuJ< zA^WsGd(@zS(gNiilP!d_2<2o{<0jb!BZ=n3%=sKlR4|T+MqMwP(`U>XGiOYhGsY~E z>5MQ?v*w}^3`fwX<|3_t*DEqZVPJwne~!pY@O;9kBW2Qz<0Am{5LSb81dP*=iFbzq zD>~ zB6qCJQ$pq|@hS$>Qm2D%9Cc+U!iLEmXG>YQyP~u&w`X%a zuSixDNog)g-#zHwx!$#<&%32JFw%uHP=a*m=cpm1$gRWPkQ50TSQ1;3XQ0^e$2O>x zPa#EApe@G^QEv?*Dtz5-35Un1G%KsR*Lq5dn0P|tv}2&f$SU)Tg!*cKV~x;QVMklu zR4QsLr7%uJ@DPIJ7|{+FojHxF&7)8?`BYVcs)!paVulLRnd9h_n3^fY z?+46_wyZCbq$KfzMUD^fcSDJ1o#d>6bmL@mHYu}9`pmZ8itW7>A9t1S?ycCjuHe(= z(BYQQXu0cb+&mF5F6JT+)N;|OMUDeeS3E57J9RVUyb@%v=#ffrJu1Li3!U&OW9Aui z_Bjrodu09)JvlUU&>OfuP0LT3vW^=vVXun9gb50Bi6|@(VKwPm!i!hH^jhqS?ma`UI7QS;t9IxGunxN{8t|Fq~kV z(q1rWa4vu(dQ9M7w5TPRgVIcSsS6X>?%MQpazx?UHDQ;RzI|43O@RM~t zTT9Efu!gUl<{xM!Tr1DxLlaIs1Fk8Lh5T>lcLL`3!|um1&!edOY0UL3?#7@XX2>z4 zLR1v5^*%6eGd*(94{h{qi}9|Ny2sP#)j?)xFVM_!-1#;fd>bYT`I|8G7NVBp@n1xP zL~QgEr$n5b=J=lZ;nU(Kmjl1&ft7n1@Za}19|nZme%Cdh1D_EPr8MWUPP*j6f|g@7W|LB_kY%N*GE$K=B*?S#)VgA= zzF4W0VBV;cH>)!{l<6Ic)J|o3uPSrBPTsGVV<)sGE4?IJ?o)9l8SjboF@^hd#b2qL zPHQ_RESs+IBUf_{K5}ne4DPzEX*l#zX#FaC4Vv?8UnyU)*3rul17+&XFF+NUtEmJVXW*F>nr;cZN_B%!k?ogB^tD zL^f~rFO8ZLSM&Fb%|%Dt8dq;i7<)sG0Ijm9E4tSCs>&spt655KR>pH(4K;zLTJL)> z$6h}KbMPDyatMqwqy7x$l?g*-Tra`Aoa9p&q~@F?Q-~$XEJ>v$*QbW8A#TSIOGBwA zPm)}O`MV}ug!z)Jojm9iyVDBfK1fMJ;y9laMYJ3qN9JTOFq35L5@|(geTnVTgQCT* z*jmHRiwvtvC?*^R!^K%a5{*G-yu}PV;-g5M6_Y%dyuw6DhhUaC91`9x75VtEb*O%1 zxMg@p&%oC1+Wxluwz^<#l_nUf9@@O+i$lSp;?|B@bml{YcqWO%1DSEYDIt29l8aAH9+-;C3?!QJ?Y(6?d&+kASM2L6InW;avN<@`7&={GJ&l=`nE6JY zjX>2;VWVVTpfHq(!g(b|S>RQU#h*Jxkx7A_aAPrCamJ!R(hzp}Ay%Jb$xI-Dxj4`Q zn4>*Lp-aao3%-i{h_e>$7$ye&+}+YB7L;baW^fO|5LbLOI&(OXOC_GVazA)HI~|^X zdiKX(|M0hm&rBYhnQd6#Us_(Yf5-6ty7I5X_TypaNvm!Yf{#^y)~Y+fX-=}b6O8r* ztvODqkLa^b8Wp3o2F*XT`Y~E|fytV*LKIR=FtT%oHQ4c= zSoWc5XH{6Y$6N|FF-3Z-2+vIr;Z-Pf<~W*!`8AvVHvD*bE#?DZiVl+jsO1=ynKQ#Uot-wq9fiL{TP8UR z5`Td7pG@YD)3SHC!>2ZGfA-+Xi#NaDy#LEcNfplvn;Tm{ZE4+UXTSAuhxD@ZPS~AM zV;pwAtoL$5*Fx?^ul>5$aX%gZT+ChQEq3OS+lG4V zu|ITi_Z;*i5BpfKyp1Q1L7#dokDO+5;u#_)w{K&?*U`|6pbz!H%|8y(Sgcbn>bz4o;X$e_J?5if>2M0NdBAd*)qJIu zeI`r!OqTkEJnM6X;!B-spH{hDmE9>ztzG>=dFltX*=ySL@=n^&#n5dO(?qj9@k9a3 zSxtsmer~v^$S4RVuUE}NZD6%}om`%koxaABEpukca#d=;yv}6EOc9OkGMMIXTger!GF+qg;1n9hgC~wG})Q2lY)odgL$jJzuDW@B%olu)zc`T zx?zXgAiy=TvnA5n5-mWaM8KYCX^A$rvWWs52V)6TWy%u5*1Fm#;d!MC5fu%ke52@{ zNQ@K3eCPK&^O{@}>CAIY)d^!&jsY;Qicu2GksMbV62pd;crMPgkRUm-G&E2^_SQvn zTC}@_)_FFPV5e)$(m`gnWEzEHi3FZU5(k&tIVENXe+O3Z>EpiY?#4u8g}q*fr-rE%vYP>Iz2)&dN^_`Ov^Awi++_e!Jdl^ml0Z4@lo0q@Pi?mcP7G{$a{Ix($Ip*W z%np8X5HKI8tpBW~;}g5}dynmqPBHGbjv{P=r7rSj3<2Ix1kn#8h!Ze}Z{gFh57t;O zLhhGg*K_zBV&Krn6Hw>)KxW_<0Ds`L0_INy2bT2FX5;h|1uX?lI5s^oiw>T@f+`+x z{29z2!tK`0;~Rg8hh79cc$a%_crDtl!*LOvdDwR&=v(l)7ko~9;=^Y&v;-3_-MEiB z?=zhbTaP+)C+vnp>U1PY9m>x5Rw4UFrT$u_`c|+1La*JcQ4Gp6+fqJgm8JCPvfgXbEI^V#b0JeNjGBSz@h9*sJ4~ z5*Js@hnrj@`)Zrlx})wD<&l-WRmzXMxK9Q=63nsD4~G^q*79$_JoK(JZ}ktf_#~e9 z{+8z?X{b5e)DUUtt_hSRBK3`-x+XTiNayuv?N+%l+ZAAIs>4KSDSroZOq(}~r=Jqf z-|x&Nl1nhJj2k7Gi##VVm)ddwT)abWC71)DAo7pfbt@pT1)<03iq2;|2&0$De4va4))=6=qctNb#i?sn4 z4)XeV4*6aX8y_f^O8gm;?=F#?JR-gY_>4?vfO_Yyo{#r$NYv!#HkSu#t90RbY2Wba ztM?C&&urelsi(Jb%V3>!ZAxCM$U!HGE`^5k-XSkhpComN{37^6;Q&`$eUf;NtANOJ zV*f>E6#ENy!QY@a??89{r|t1$&9M_@!V!-KGm5tg9Cz|~zgDzZ7!9!g@YJl19hatU0$q48y<~PK$kiARRo%Knpnr#bgUjW*5o0iwJYfdrz@g#xxN{ zh1QH4RTr?8X;6aaD4dN#PDh~+hr1VC!GUx#dvAksLc?E|L{Y#$mIR5CRL~oCgvX&d zCthAC_y$~N_$v8tSl#36MFK8iO}P` z@KrZ|9}b7G#u7pgpjjj9VsGn3g@N*>iGUUJSv;oEU1?$f_0-RM| zgsoU0dJzQqg(qGP$_xq<>9`8O;TCN<o(lxF{+O8Zfn_LD06C#~X$UiXtud)R3B z9YuX-((g!Hvnl1HgBIiG9)7or``E<~a%>l4ZeuJR!C*0OH7k|wZ~!*%dY_>2xRk6# zL$j>KMp0(K+>nuKlgn^&TBz058ja-`Q(XOFo5cv8H|nz*bh2iHvQC{1C5M>9n@x>6 zb+u0AmuGQV*$TD8Rk7V%zDLt=MAI>59$d7J+=zbqRM>qt^4TLr;}0wIKF&z=WQLp5 zg`5l(cs&7qna z|Ay`T%>$jj%1UQRg|(+`7{RvD50&6U+*oPlDaAFk#}&0L%_hh~mZ7VumgWf3)V zF$uIfL7}R0OqDST1(Gkryd;QZXEEG4Ady@Pm}3JJ?Im%t9WLE9Bo)c=B={9O+hhy6 zta2|Y=aL43TTqTXlfYRt>>|xDS+^lQ?M4y_E%n$UqCx3o?b;}L=e{$}#m}((Rosy@ ze3C#)dhBJGiy716Vh&JA-em~wI*~;1X@c15iv2v{yj1U9DRv;$XjAoOc&B{Qy?I-A zQB!$gTfL{ElFlj91&hb7zqt47U+p^hNn3m6&dtpLvPkmemn{3qUH;+rqNBArkf4t{4A*j;FiX51 z;-G$DA`y05uxhy)axI44XDo(8iqyqK=tf?AI^@BL6?9H`uz=^-+`nkki9FY0z6Fzt zkkHR#fzhlX1&>@_2j4Bo+KUCz>4-2F6Bgobgh!8Ya!e8e;D~jb6IFUqsJBenxiiqr zdC%>`W8>%NuRnMhuBcI2tu^=$)M6RQi5*LX$0A->GU7^c%&_JJopF?vA2+KYu$*S0 zpKEX)`lB)x@u1M~iQku##vnQti?FPOSsF~~%-Jb8c+VlV*`h^1j7deY6u6zC2+T2C zj_DViY+?lQlG%h79fiS|b2|B`CJTBCT68kIf*>JG$XIlkU>P@SXKe75MVD^8>9u2H zC}{?6CSF@G-GY50dUD9-qAR2JI%F1J1A76SieBfF5g1TfNLC$V!gdlS9-Sp2v`3h> z@u(S|o3%5r8hBM0eU=D3j5y$h2nVefkj+DA%RLw}2gb$T+x|lA(lLAp@#N>Q53MzJ zJh8%$_z5WdxBy|h|FMsQEUj)3*`~vDpzzb;w7VfYY zTXfp43to_X&S@PpY4KrU9KR83x@4pA--)P$W#hk}QC0z}<6!*^C6`V;j%hO?mmN2% zVBUM2HXOH@kC>@LYUS5j)iJN@h+p_N?Efkf-pcb`G~GtiodG0Ccnva{GZ?Ui!v>#U zCwP?>Uc*>uGbgyc>g-H?`WjZ27Eoj-wCZxbrb?sES^ZI+LD_89G*j7)Mp>&_-ijfR z^bgzhSp%$Lol)0l&M@RIRss*j=~Z(D0+8;i!4zWp>k*!2bKe1NUQ}KZJc^ zO5v`|{EhOw9!0!V9*(ZI=`~SW6Vy|2tvN@-M6=k0GEiY&zoVq1PsojYkRMo4m-|sq zoqXGRC(b}O_e3#g4wA#oVuvB6cC@K;wjN(juAb{-r3j6>hpkb~L9<_Z@MKuMLbO)vv1WU&V-9)lu6 zE;*W5ix|*6vqbW$I1Q2`))^@kC}cX9hD;>^3NSAY7*It^g;8??z@hTpo67bKRgfC4 z#C;U#ik?<#p#gk!q2zYy^i!J91LBCdEy7&V97NWUV@fo)1ZWtN!5Fr9O1MOI*yJuV z{5N-&Vg8Fm{-q5Z17GOTQUU>K=F1s554S$o1f(}78PyWSzqV?FWmic zY<~9U?Bd;MRZXm-de^Q!h5pc%MB+pub|LD=%Z~G^}RTLsU7hSDaO65SSa}7(s{LLc|u%IKzXtx@jcM@${UPBKa4@FA+Qb6nwV;^Q%?@ za|q+m%rO`V&qmBBqTmv<$QiC-Q^Rw#8o^N#d+ik-GY0h(0&|GiC*pIt;iXsFa*&)2icU-Er1* z)NDFz(qkX$bjWuq8ak2}KNO38>~waU&8-yG9SF9DgNBTBm){SV>-<5jF94WpS%xiK!>Z+D+AMkAH^=~Gr zLkWrG!<_{Z%%$l>3Ff%nAi=zaED)hBhZk;NbF#$doWQ)jDcIH;Yw50N?5XvZlV`&H^Zvo6p%!KE~Ok)x5z)Oaa4nRS2R8_)^Idkj{ zRmAD?s2L^hftpLh=F%WdcpjjZU~Vc3m=HFE78H2gHCTz-Jy=d^Q^hBnDq!fH6evVJ z1XL%uCc;Z8L>Sws7AzG%1&C*nqS7J;5+yG{Gr@&c*I2BLMf=OH6 z2VxUX7!l^;wE*-UC`9lOWEQAWq}#{9d2iLO&hkTRD-X9>J0`p^25g%ZVZ@g3NJz+{cNv$FFF9O*l0?FadI_Ka(q4WOO0p54> z`;*U~{Csrme0_iaiOI?K);2%GepXxigI5?8Trdzo8+_W3ficJ<#w-Xy$BB%MuWo9=Oro|=?qh} ze1eiAJ#7{v<*b2BCsJg-5lYLLHe1wNFvLzsE-B~a(qKhg5rvgcOt3&IN8}tqHwPy! zLUmA@6bYWwf#k$)7aqJY_+oS*HdcxdQG^%^JefQV5z4aQv&t;oMvB^DFzm}r`<+IC;eQ}>p0_U8 zkW$Co^g3>P9j^*Pm}7YesRY)w;ba$$r6C-Eg6Ak$Y+>M>EO`2a7k=MExAT$L`yv{8 z84o>+_#wPJbULn6MywRwWHk4kCU|qbO?ZFFCF3j7>gWS6_XJ;cS?>B>&vGM=W8p=p zE1dPLRy~JAD#kc!)SOZ)$MovcYWXQu_F1j`v_^JZvF3y_^{gQa|FfQBu-i+)di|(2 zlN_Uqp{1uO%}Imqm{yG|+N9vV5D$*!M$cE4ejN$!_PB-|_H~T8+vjZ!__S+QxqW_H zFbI56!H~vk)w3LLwd6)aHj_b>`jIAOrAwjkW0zm2t1#$G(50uXF4trO=8eY8W>ZG1 zF{3*3!){&HCbPcRq-!@4m~$zsGgIXDI1U&0>ubN1SAW9{OkrIpcJN`|mroL3Ju-El zT2ppFUb$Ugx0S75M^#p=a+`DsR-d4l0uz&`Ve{l%fihTa?%tfJZ@0GA8;ip!<)IHc zO0sru3~ucS0On9vHh1QsEnn`;ksJrFEd)|PW5GbndN{OTZwPsyt$~52C73sQ`x=Q! z3ywj%>fP-Pf%fKTWn&_kFN7-da$9O#r9~#cj}lxNI+>c1H8vy~t3xf7n6ClMIl!Fo zd|rFPMuwhoy;VWAa;=;~aLmmYegXcKsd3@pgo+M8_77N2Q+m zU%{MwtVp)g=7%so}LRJ_y>F5P!@{J_yOTla15?yJSR z5bV$abMf~QKNk@7M%3rU7bI7-cQ7ZbNr3qh$qBkqV7Q2JiRWav5kD~ITXyzUebQC+ zRae#b9Tk)9m7~Q`1ngePagbPw00)?3rvn-bkdD(&oHHJ0Gsgwp?Go?xBJa45z#KL1 zLT9eWOhS_6PTfVTYTSbTP*^EKdm+P$&{!}gcODT8iI~)x1Lk*2e5cs-6Q&fn1ds*) zC793Ju|8=X^Aecf{@v+E_n)1(Fwr#7-?@1xAb9)?GZKq_=W&mD1z-WElV|nv<2u<< z%p!^~$IJ};VIa}}PW};^J&ak-xvA?xJ2oG$Vr$0D!SY6U5D6$d?Lj0z@!m8N16j7Fc4G( zm?!&l#+XDj121&gr<2$VnDN4c_bP}@8RlsNToxsm6Q1MxVm0F80%e1&IAQ)A!{;{Z zIhH+Rw}0jfd{f)-^PR_k{U83}?DVZ87Z%#P22?9om0B&^9QM5|yJOXdhxKX<^UPQ+ z3pW0Wo$wqmhjIGz+~A8GA95vNWBV-RdoHRXPyH^k0qV7*&|2T;+2?}ux!?iJ9}B`= zr}Lp8{G1bg@hyQ{7WRqT3JaHe4hp_5fH{g7ExK7!J}Y2;%gf{1@gyF3mWW;V zdgkqpF})U-Bpg7%It&a4%+G3-Ao+Qt8tYx7dihzM40oW>U9^}l@+^X7kL$BfnaETU z&OQM1<2uzbHI@r_!2EnHa6UIWSyT2+*uU59*y3_QHt!TXZ2_NQ&1#QVum^(hedS_N zz1^;5%y!O_9}l}&lO{bywfZBRfeP7*LY=v~NZz&wz?hD%u~TchAY^|7{nx|%N(BFrrt=K%A9uV3VU_0-sTI;HGWMfFZo z^Cx`!dbY7~rC`=3EXD$cDWuH#T1$c2TBr$CThI+u}Pj<&o)g!vNB3CvL<$!UJr9@hAe%{yY^VrAC{g#+Gc#a^n$n}K8?(!FIfvh zhandNk=w<)28(wN7LXzz1f+o$;B@&8+I7;aeeKYO#^LS#o3;w9xe;V~Ui4Bo3%z&BL+26e z90bhii*6%=IR30Jw%_WVKJe|c$FFWae3DaDYI4FH!&%_w%QG|1 z<>#MvIL2w_5^I5-Aoi7x>lLRd)hQGCgbvYFGLRXiGDtS4hq@lHAv$?c;IFv3MVLwn z9OBaE?Z#xmi3>_KDJ`UOz;g!v17@IG33(jCIAD%-A#%`(*%+OCOe@FMCuYmB)K3;Bg6|5EBeK^YZ|6HBG_3CO-lt-D=F1saCIIGc)X2S-E;$iOE=H zrraN{h-Ri%88tO}MUyt8S)JZ2U(>117&Pm;&Du7zHkh5lr>@FMlWXlok;Yxxvd^+g z4l(_++~7j=z{A3?UKW4*TGf8y!{Ys_#)Iay2VA{7?CW~h1RdIZ2UX^ziy5lW#1`uL zQgfuy)zBX*sMHPg+FB|UxsDZOfz|sqMYeZ`w)W(1T9+%eTiLoIY!M%TQ0#IRL3++XH%%9F5J>y7Rd30s|xem8u)@-gI}P$j&yBmhI%Dn z-qTUgQU;mDj$MAqp+(YI>Wk?5BBr*0hFVT4m&Jr5sw!?qrZZqJ@|+bN6ydwYh@CkF zjH3|f449)3?!3g_KZ7~65yEx}ViLzhY)TK3$KTg6-haaK3ogMtd7Qcob7<*HMPM%W z-bKhHl3*@LCDO-%rM5iTu`k1%@LXJ(UwW^1TdNYu;mV8dU6Q+@3t_p5c(ZJ*A6(zC zWyipVZ5vyL))#lJ_185~i4wIxcgJ@pK0k40+n%AW&hkAY_2|qcnB(=yRF7EFuTLH! z8~p^}QZ2s`sE#63C&3)0BR%kVF9FPVV@SRay*lCf&VkCEeHDAwmF#QDTin)pbA23%Wbp3>l0?f}ltTR#nc+fr_bxz@`5#i=w3nLg#vYCjbn{aC}%?=x` z83zM#7%<<<`6l*$^Wy32*MItV{=z(0#8;3A1kL(7mGVR^IvxyMpv=>V;4vAn?S4Y1 zIAhYBF{$9kd(JGM;FNglQB(TO5Ofv#x{teojdd@Qlwse^A%GqjziiV<1qg$jXoiW* zf1Lxe$A~tbSO>tKohQSMSo4SOJ#DpI zvO6XOFJOLhZQuOasoOW7oS3+>|NE0i&Q1s{A5iJGxZK}{g4;g)@Zg%2@aDS2GwA0R z+_ozoJ38}Qg8iNkiEmEPEYbDQi}7-}m%A~4a?i&99Pr=c_$N;HV~6Xh%kzMDKlKFf zSnW@|-p7Lbc_{SQ=ey%@EVA5PryITcO&fQEqfVxL06X00LD#c@^Rd@<+sT0BPa}R< zc)iGt;O_&&nQJclb+-eB+zou9!MU(h$kfKb4^BuC6-|bJ9A=E`1Lik_0$>g^nJK3Q ztH*#jl1*@~{k=Br7#3^;_E9hVTZFNMZ?Yo)NM7uq*EwWmddzeS!?wBHe0HYSWk+U* zIS^pNA(fR=n2aoChET+>Gnhb!su<}Fyn$>VBt2JpFHCbeV zNS@XvTRp_+J82EhM!ngqt(hrVnTjlP)K|U5Sn)-A{^!Q7NeSk8pFb=8{*Aox#}5kj z=-a-e)_p2$*yHIN&d3QW@*LK>AYE#qip*@Wi7&H6n}o7!+LjHy*A9R$g!{3 zvk@?lZ0jvZcIG7IIWfF02PJtYg5**-g>+}2Bh=p(?rRMZ!CWLcsGgKrkTlc~YOjwr zG!_P8?qCHv^F|IAHJ@M*oLR=K4ArWdx@cENuBe&Y!E*`bjU|?bViqK?D_}*E6HAub zTuV)Y1Y$*v5KNhLr$^xFF0CN$!fb()sP9$#B^5gH{k-kLw_VmXmkbnQxq>a%X1K5$2yiFuUI?3wgIdf?)1>cKWru~uvBRxWnM3)O- zC&CM@L&q-yeFl|8deU}=n9oQJIiYv*t%;CAE-@nKaU6iqI^5z%!m%E|3h)6X+MvBpNjz) zk6Z3m1hFxCDPo@RYA3yhNdXD+Ix*;(f{P1ILeY=|=9k?DM8HF7AQxe8wq3G){Lg7+pK#iyg29FYWv8KmVuy`S1SeU&>k= zOm=fYZZK|VVk=kt6!A~z$IsIgX7vb%+p5rMKVJ#o3eZCztDXVBp|6bkK1OWpg?hp^|G7GVyOUlknK7(x*9 zg8)3tE%*FH)_&-9JoMPG(F3vNzSI8P2bkL*J3Noi+ID_6o3pvGisR4bcR@=k@UEi+}9F?5-= zBFxuV(m#@A!g$f;EbTE@AI!+#uj@Et8Jr31znA#xS>@qhmCcY2z zsu)*^<~(Y~Obhn<%VVaZh#p0j`o%?l$!JTQW+5d1*Dzn=_HU@Z^dNz`#B(rw`3_(% z5_mbR;oZwhZ}D%yT;woLPQ_5U$Y*xy@*dB|m$i>JN+pI}a?F2Y=D z*KrNPKt8Su_|*V&DC#&_mZn^=K(wc;aNpY8iz5xUwzQtlv!8USuEf~IFxjkM5G*(` zghvxe0S?$E!C?gY_!)!*O$O=dC^If-CVe`nI>|ppm_sn1F{s2aXx%)m zTVxE^8KVUANu_+jWI)UuV2s zeS7S8k=;y>?FoiYJkFMBa5PdyO+=<{V=x zuXCeFN`e(6K8d`}4UfswE*X?a1%2Ri{IM(#;iu^T?_sehFC-l+U?3kP$37JD@^CJI zPapW>U`i94uw)t5VO)gofn9&Yg*IMykzmH2<)o;A8#Tuj#I@f?Ey+ zhxcnLs#g20=Bg-F>N1w_hC-UFa73Gf!7|zr%V_Vic6D2v>_9pO3&j!#xs$p?GDVKea*LzmxW!8mMMZ46MWmN3cjM9>F(HCXKcet7%mGTu zjP&I9duDiTZQoEgJW#)7TYvY)bzR#>diU)H%$eLWTVD0czy61*8#jCUn%4JM;k$P9 zFCcfnz(zgR2)_$ z*0{TROAd4uo!wAyKXmJa2j!DI^n0MLhMY) zie!p0gcf;>7?n8%_gXiB`6L!eZ0vEjcR%mGeBk^4`k(#_j`>3Qd1$Wk^CM9w7hbvI zhk*BDGz^&qn)#FobKuOVPII2pox^UXIN~y@O`R}hUZmi%k_|-M_F3R$g@$|?=8M?V zw4yWDV`&H{m7*`MX4-_{3DYzwye5L7EmIUbL9vr&%Onenauy#1kQPA*i6$BLhEP9j z^qk#{rX4WHSt>?Q2!v?^7KM-&hr&c6hQ?uph`DhTt`{>#-IPv^6jAI4L04Hcn+U@x zbmrg8Y|PZ~ptg{F{lz2L}(2 zeSY}#j^Q1f8rwHIJlibX7aHv$rQ)O>*EI$|_Pj%!^!AV)%!dIF)bcyn@h407c4#9w z!NmUlLkIiV$v<&9o(t}~HukC4{me_$@@K)|$u((MTzcRYka>E^pq@5r9)~@E_LGQ! zP8+}J4VUAbT6y0mEb=S{%b&)BZ;Nwr;lKeXhV5^Aov@U|A7R>{z0Gqt?Zq7C|4rC? zK*x1o=f0FJk|I%OFuj*EGv`ci=)Del@4a_`07yzKVi&tuKoTH85+Hgn1i`B2BHOVX z#VxUu*uIHxl9#;1iLY~g({AkOe*bd-h;s7YU2CsdLtp?5przm0=lg&A+jAN*q9fPL z^2c`drUN^pmCGi{3N6RxqX{h^Nej5Eu*$KmjUyfTYn%fefLWV2PLJaG}ULqdM}1`ozUbI z?PBzzXpb_*B~LVq<4#)ypJex+6V>Kc8N+mDj$YOA1ID{S4hk!1E0b3^FK zxkonMoa}cl^KQf3*-+wur=`BwURPwRE3nq*TN?@hbF8S~Mu%(_x$crIcUeVBc&x)1 z<%%fC(Z#2Von8!q2C4-6gnLsny#+!L?$cVloQ9GSe`>>VNK@I zs>~?J=4zBL99DA`dUDd11Lk33w|bH#py4Nh#x0?gYw zs?nL3v^V?eYap{2 zc=H72teb^B{oL}9qxasD(6>)Qxqm{DBW$lvgv>%bEp=%)4DG88PxEZk2^32O0qR>=>+!~ z1fCnm%mysAL3cfbT{$YioaEoaC5ZkUJRh?w(U7ALhu%K!Qck$F7bSZqoH~5@kU@$< z@XH9Jy6&)@w7bUpj{W+tfA#y{`5}frY?0v+kzS`k>wRPIX@`9xE`CIb15j#Qt{qqE zhQu-=p387dDVfsCM&&_+ygdN*14R(ht~Nb1?&aYRS+!Bfq{Zz#I=~qW?BG!+n4?6n zBf`frrsO}Ai?C*5T%kZ{AwsUkr09ow1IFs%$C%Komyiuk>qu~-K?#_% zow<@55rRZBf#_N}EQp$Em3mgMpV3h>_(G)|nd+qFR?El45L+bVtWzUHb3TJJLAi8F zBAQ0Guad#0NcvS1U@lpt;Eh3ZuHBkHq7iGUy&B;@8WsA{!txJ3{o%^XuOGR5`@;3n zfwlwPMHTgWbC1?=lpk_lD7eH6fXssX3+$W5{-aeS7Shy)g~n+n)N+h=uISV+?F=S; z*7T|st?ZEj0W3NMuskv;u>kai!vu#p`t2!PC3%4_J??b|(?b@lrM|`U9~K5d=zi*T zAP0EXU|gV?JAD2ow0FB1Hx%$^J`J2aY8g=5gSIfr5A#0R&K`mV~$X6-ZhE=&~ zC-uakK|M07R!xdcy9p`{P9NY4f>$4ZXXJw+s1x?r>l)r5Ekv_1;?W}Z94Rg%Va#x> z<5sl$O1PuPsB2Uy^TZOLNa_|!jdHca<}^6nT8C3-w<-)8LGa!vr?EKEonTgYwINFX zFG=>lrsM6mh(bJ4iAO9j`MqHc@=G^TMOIURQIjthW+SIX6pVSI45h%q+h+>gC-M*2 z?I)HoF}B=(Npg?0q)nMI%#Hr^`td*mS#E%IJ=2M^{Z4VE#GJS(&93*@x0Z<#=fC~WWw{j1O}BGZzeFuf+1EpM_wX|n*hZlahtP4 zpd>pnRDwc$;;VUy+&DjEmd|0{o`G5Z1FfljZNz8JRyttL79sg|0p<|c$+0GCyG!Q? zPnvubfq8QVDKdS}!kn9_Z;9(^i6g_9L^I)9?roSumtX^75GH`aJ0WwOO`Lj9Udgq) zuabQGIdL9tNgTwGv!%3yy7(&ch3qjdX|o&BTkA7Bx@wxb>YS?qUJjViv zhc?}MqW7Ltf8T?ZyYxhaZ939A7iAl^NFTa1m>WWH7KSd7#5GP+4;bTpT0g2+-%%oa zN`hm!5iQonk##u`&*6Rn&xdL8U9052Q-Qsom*jh=JUUn$5wUW|D86fw-=&pT?aWEL zWA?2xfA`=1=8u2;XA->ux6IM8Q696wxp((zr{iHl++DSHTt|&52+VH_B?RV}F4U08 z9Ym>I585+rkiwLLv(62dan-DWaJ|B)v5SGEh#Se4XJ8zUNKhPC1mX#z&M^ms*xLs( z*_d28tucV z*g%IbgxG=!(-EWMa+v*Cbl3;ebAR%~A5TAedE)BuyLTQQ?LIhAQrV!V`*nunA^dj) z{42o$M9;@wX-2k&V@O6xbwIM5`Ap3f}widMBwX(6yYHtAqZS)~+MEwsTXVM@WG zQrN}67VCQMHP4|d_S?h3e2p=$nrK|1F1@jPR4RHI8L{DV-i z2q=3D>tmz`bFYtV287bUU_T)ZSuv>5lLOlLL7Nsr^2as>3QwNmzKKzhTLznP-Aa+= ztu#)n4J!@?Q~!|fFc)^mEW7Je4>?ssZZ(va(FoIUl;u{m>vFiY+n{dNs0&1rbdlIC z5E!I#r`4vnJ9Tb1V6LQf{GdJ2E>n4GSc+W}Z&fMweMz)?mnLAJDTMEqNjx$U9ppy` z?1@oJOFgy%vp!!dP2=y)6!~Q-_!%l;xF`s_oCI&|_Y0B*DQxci0YO}|toQ=eG~zh4 z>OJ-}Yw**c!V7*mC&cBal~t#09p}OhoO9H+0_MAP3Pp@d7Gu?>IGOA)Cc|Y()tD27 z`L+7G7E?}IP^4p5O|HJP%Gp%|pE)T`Ek|<>l5;R`Ed|USq)P0~#W0yWfN@k)v8AEd z%)uPZIZ|+|^Bk4A-lA;MnMcN2^&X==Im(`$EeQ*gxCzVyBYmLFhr%={R|9S6$)T}u#Qp-z!E<6t-})3tPS!e*YRTka4sixJWsN8aeQjuW zqYt!^*?;ap6U{SPR)8I^!G;T{8QdcW^R47A;tAYxw*O9N&M}Qx1^!<{5DLbw zhtyaMXM6y4*Qgs(5ueGZT5(TddUG7>H_gt#U2*XvS|Bz95myz8u zN>R6rvYV9blFj^1XvA>W;U9eSd*A);pJZ3n@+e(+TzI70YTNVL*>Lw*QtSX^HSGKk)RP*Wkv)9|5X68eMYKh&V(9t(bLBEP8}!J*G6%Lf#{t z3Sh^NhShvp7CbKWdyHv)H?v_iJasb9J@#jAJASVf+K9G%nK8{93?MdlZJN-i7cJHm zixV)vCsmGVR8u;P)~XlHT8!30-NLaZE}e)kz%PO`UoM(vjaF>Xs>e1J2lEZ9^s!C$ z%&vN3Rje^GB#*7zG-UP)W!Az+ipeibJz&xS65pspJ?v22amep_wWFbi;Yj*UjQvW4 z6AVY*RO&%;OR@!8Ac>r^jjaHj=fx%yn2&Gy|lha|waBEE=`(=AygQrCs z6l9eOy=oaP2%rLXJCV)ep$lA8KCMU*?M)Hv@yP?zRQy;u-z^N1?cX2ZFYpV|c=Ni& zu??c^<5a_4+rV0Kq?KpoRj26IQ=tdWMRpCmZny2CG=fm8Fq|>^ zyi8^|o$j>ww8n&xoEmj)hoQV!m>Tn1ahmu*eJFwXc4y9EoPG45EpIJzg5*ss$pLc| z3v+W*G1E{?Hxx4U1!lk;dFEsdXkIwnEEQF0-WZ$&(~&tzi8ZwWj7{N<;Au$6d2}3; zm*Zu3I3FxTXYvRFka&bXqBH3FM-&qs= z1(7Io!)sj=X z;#R(hwJbYTQ;Y;zSS!&CX7F(U3S$@t^O;Bng2`-{0Win133T1>iUV)T1(Q|-#`o?U zw0AWM?8gDj?`t(98uf@qi^qGEhV<=>YSf|{v8%?t)HNL+JA;66WGaH>Hw=<%I>`l# z`Alf|^`@TheDs}z}!ZEC+Q1g(}0s{$w zxk3z81oFt7)`%s`XgE;-I5;+^)q&@WlwsLuTD4fvf&#P1Y=H-c2;&+#E(DO=aV?nD z=%+L~^yHY_fjGlC(uuCFBX0xyFXoY~h~rTV9H~XG!Wp^1<=GX%Q zm|yZ(PbEaZKQ;T^Z+>TD_361=qnB@vw3XMiW@G{8#~I57wd|reh~ir+|)_@yd&@k)V5 z6sQUG5Af%|5h(NKcF5x!1nEZ%4MW!cCBVF7{6~9oPx}|0kyM|PRh}?5pYZgZi#qVu zzEJOLv?0J{3UcZ7DK0w0Yfg7s({*%GNJf>iw#!&vCdf+OU6d;5t@mKrP)8M%7A&XO z>dF60n3HVtEtu2IrA%W9!@(Q_q4hadz`PnH&yA?8_JzeU;pq{@?R8a$j`A&TnLRvM zr4p#6B+@)P955$yLny!;$Dm0D4(52|U{0(o|KBiYR}PUa6)5ohKf&DB)8^}KPw#Kf z*nv6P@>gJ+rx3EcEWImLWRydi3Ra$mBcHgToM{^FroJ%{05`uF;9F=1IL~m>S zf!25!%Yk(AgylT6anAk+K?8aVcaDiCC_;6X%q-ZyKysGttp9M^70GSE;~sI+x>HbW zIvaD^oATRx8|yn8lS)gXi%JZMDaPbPWw} z3)0qx=-7_xs4vPX9L7oR3a89)iVD~cfNvF6<8A3M_#ojq78t?TdZ;exMtj!jO#9QO ztZAQpEy1)Fu3igMeU$243)PI9LMANI)kyQCOAmMAbhrfq%S@PQHk_VxYq9ig%q+of zP|SPYl=)v1`(d;nh8AEJL)m~i0DfPuyRA^&QL2a4+99oW)L^)8Hr}@y?$D~cRvj!Z zh$6qPlMFHH+l=C-QF_gwI7v|hChPtFQ{VsQk5|?|I(X??Ms1zeZ16alIHjP+roEdU zJ#5C#BNBUv@YpeV;IPDhNE$G%lM$F3m6+Cql#R(0JQA8wYFO!@+|DSaYbO0N&L!1Q zt)*j1sjzxw;X8H8vZ_hq{@AAmQp$9XES~^?O zvm15#K8^aCQ9ESNp4z<&CLHKLkle9a6fnm(+%Qwyape?R@nww^YWbR8@z`Q|#265A zh~rWGYLM0+SdbI8!#uz9e2#`eK*T-BHQYf*E2_B(k zyJ8J##a4bK%j2*Nw6)yB7SUMnq@~RHd1w9wnZ?{xYHln+XKt!5plkD)>KtQb zmbp6DTb>(QUX~OQ%M>*f9=m$}?8t0lX`9>{<0sMbm+j06%(>Ig&xb&_G!~BJIQ>i}vbhAFmL!sbyA^?p=DepZ6}2U>v}Hh1 z;WU;Vm>=v&JKT;8t`zt&IG%GSq}*vKdtmwnm~$dLr?i0NT(L?EfjN#2k+=(n_ch1# zx5NVJY#0kMesJn~XC3j15b`%Ab1S6T{+uY`uXgD>%{eiXZ)xL%`5eaKV~6xj)bGZ0 zJQ9<6qpu4jZ!GLM(9-p0Ur9%2N_D*^Cc%`PA`kVZR#jjTLrr5MZ}sl2bx;a!5+52Gjk?fH}VZn@y>M zojJ!+jZa%L0rN-6Rs`X$M(Vzr5xN;eWBLZ0I#ZgK8KIWXM%&P(BgJLLqet2~ ze2EXuQoIZ)N!NsXvFI6gL?|94WCNPHPIXVGy`@qODpj{sYQTJiqBxijqN6ry@0txa z)be-LGJyRKqrPU4U87XTbySazSv+;^hoAi9(dO6B-5qZ_a-8-!va`}EV%={>Fy|wT z5Na@UI;jg`PcVbvV7V>!1I(ecumTIQh2sfe4snCPoYv#~@u5@#`yXu506Q|T9*BcM zb=Eg1e5fX~pW_;g&tpCj;L?NPkZlRcw_(1hQ_r(72i1|$jf(}+%K z?}>QC)Xv9 z%t^vI(z;+!B*8W00Q4lI8*n>cJe&f|=bwB4nBN_rJKo)2pX_VU>Hzc0IyCUQ%R&2L ziO1Ds!AL=<$FGkV-baic2c5*eV%B5v#44piLCS{J@TtSPYNDQd9E%1$Iq0-7YgRKc zG}`G$UMq4YCk@gCMuWc$9x;1`AuRmXqcR?H53p8m7J2MO@uF3>>Qp`QXjg3b14`Gd zigg>57WukWM#?PRu*z}VxoVPc+O*h+`pAqEQY|EU;%TwTmrMlaOBM+ZsbNs$V9tpx z6D9=g>&Gmbdv@)xReje%-FI7u+_qa@@3m0xahs)!(v-=01xh|(t`!Lw6RmfL>cgVM z3?nxi{DNMyTBO~L8O_B}1&MU5Q^_a;7UuG@CT&f3nsW~3 z9LYJDyIIYgET>=#!HJHo1JDv^<{Zq8b@`_19I7&#smTM(J!NIFQSo#|XXV+U8>fe7 zs{1c!-D$xxV~|MY^jNbpVsg?vfO%dr1CsB+JTH!{90JU9WA!N3nyA@vvmiJTL;X8F zIavuxRt^!Kqdy1CliX4ifq8ops<%A_Z8_^jNkezN)upq_`9OOrf%&V=dGqHcMgaB; z&3W6F`-Ou!&P+K^BbX09b4@sT1j9)I<{ZxKbaB>gwuB@JcoXF%~c@$&N>{=J!%v%V89f z#^*5F@1lo{$_cM|HrhTHW1n#AacVgms-1Eu#>_0tX)&yfh`GZuW!P5`ZHg>hW!D{&zGKjba{CE+MNey4j*mL%BxbUIu(lZYK&sZZ%TPL1OX$`5cJsK^D^#7 z3_7&m&{Ecos>h5T4)e!W{Ti)aH$zTW!fFWH38WR=jG!Q@AoFkqn?upSvjv7jx5oq% zBqMS&qLtwzxZ{9#2nCqWGjb64X{7CIsgaxEmUXXT#j1we5R`uA(mb-r@c7)V#nw?| zFv72n%g1B8^^wK8Znm)Qbi)&;eu+SSWeCBAmajM8$KR2V@Q9p)Lk`GLi7+o--PacU{(@F!xor{T+|&5mY54I*XG>x!Vgs*nIiCPwK(f}x^Y1;G(&St6x~R|{e#K_1>4-jKjBh1@0) zDgpy|0fGDX^HrX7O?(wUbwE-6uI0drscWfm{^vo3r}kyPDXBQBu78_pd)wZ9Joe2~ zvaI}o*mzk|VqlnkH!ZN{L@?QQZ=u!flc!bb^XqjL^~&NhK}CtAwa(JTDlMJW;fOKk z7CMth;%0$0kt`b`CiAT#`{RIgsOaPvv;dkpU0Xn4UX?@F<-4kLJ;jBQfO+$g?km#| zkKCDRJU(cNE#j-}K@zQz(G}z+r^nk1QXK_J77peJOXTuzS&Wiw%!G=L!_fYY zRCMX+&->d*G%jQo%%|_PK0axLc%(4yh-o|VW>3HmH%xh^ZYV7Jf z_3qH>$KSs`_qg}cWj>>qSj`nZy(MiObx>Mr3wxR}(Mw~L0Q81^<|ab>}~g=Yqz-3dBiO_=Nl*?A)3W@+$s)F;|A;0>89i5^dLt|oh) z`Mev6w#V`2d9NBgM@lUW{xi zHSn|;WO#zWF7O=F?z3k71BQCXVLjybuHAm{;l_v9OmXPUmFsuMkMtbuErB(W?$PQm zXjF)by(S908oX~%5D48HJ@&j_JEu{v)6^rA7BEMM3M?hhoCeerCxv6jO^0sHqFuA= zk#C+ zmE`cRrbN6SYkwJKS+~odx%E$++UFh$B**Y6oa)#I`poHiVs~s@W_8TCckp3wdFQfCKe>v6P+4L;xF`jP0sf-NhP#I zq7C6Ig95Qv4qbW#rS!;o4pESW9{{}D6*7}pEDH?8TIhZI17((IZER6cLc5~$0@F2X z?p~-F|0DnGBl|KAh{_IX8jo4K-gfjHi8_2-o>LqgpQ_8s5hujFrVlaaM^oumSFzQW ztxGJY(kisYwd&$ZS#`Chxz^fM7ur!1j%uyI>}Mo`Sx{sMl=Ybd<|G1_-A}=i958ng zTT7vxxLI%jnvb5GuE}A@V$l51;=ITtpQr20;p4-DvtRpzgO?|Srg)Lg&6DZ1I%Q#Q zYIcINB+XR_m?zO}d?Gf1QtSaJG;;#;>==DEM{>k%VLwGAhWcNHIgUXU80Y6I!K*-V z&oKwu(Vf%XliSmsbD%rxU~lf>{@j6{oPqA_{;n(z=D^OYFh@Y{7h%p?!HGMaxLjUw zwh-;*)qfJx<12dmPJg})^CS-ST#wDcoO_PT2R?;*buyIYJj-xmWrqh6=9w%atu&;P z+J-sl$=Uv#z`P;9wXw9JqYGiwBWoXAo?N}Xyy~Y@2pLoJk)svuUC_*H>k0sKXe^LN zwqZ_^Sh)V2Yr_9C%-MT{t@BpyTC@F#NhPA&!w(N#2uHWL=)mh(UlrZgnKpa1y~-K* zpfGaW=UGT}KTY>OPIhc0S{5OmN1CvpXPnVsB!4|FY$@8g6y=y_H5LRO!sr5x1tdqT z3Sw9u7!`myCNak-1$d4GyfH}1v>FZ;Oal#5vYRTh3>3EEQIi6$@?o5KY6U|k$xVas zrcrc*77v-J>ssopDWYBN*|;(BumAknum0t;#y8JY^qxwu=t1J^^w3Z_BRvwTyXRF+ zIAz!b2be#k1a}ny=*&kH0%HGWVUGTs3)kXc4o#wYDW^5Q5IRQw zuOvA)-D;4Wg}D(I4w8DJ8C`)S8%P z2#?&&_v0yf4IPE;?b+B1gN`&cOiwEUL;QA0`TGHL6kv|40NQVzfalgLY*Ic>MQLG> zSsY?fNDX3a99j1xS^^0!MR9rB$KeY7BmkfUzm~+%WdmyB^PgQ@!)_vUG zOJJ_ZE#W2ksQe;%a?&mxpUI5@%pFBGXMr)k%#d2HDXdi$R>^8>b=xo}Ja4NcS-1!` z{~YF}p*t`~bN&j`}V`GK}%H0Nx84*NH8n6qv9mfM{0 zmYwm3FpeUxY)#uaEoCvjBdwEZQ{aw$J!#9?A}~jB?iXNur{~AZU`^jDc2yj{7I-AD zY|QL$%;{^$?ybwjb0U%hn4cHyE}$r3KE#%;y1dr9lB)VQ?_FkA?upSiqK!-GB0}+fO(Adiillc{`|0VVQVYBLviMnVB>oa<0&)oR; z|NYtR2h&PNq}&#rQQmX%;>gDQLQhiU;c)tnNAu84%r;XdtoRX)YlB8r{`WP!F|82R zL^8{Rlqy;aWdK?S+Q?ZgJl<-|?;sWSfkHa2S4`6yKzo7)$z|xtv5Of?`4U3Fmq_(xQk%QX^yU5g@bR5Ei4R zWTGEJJ!#98VyG+ZAV1<+NJ0w?Bp^1@0DwfoLkmnGWUt(sQ3m9~+=4@1*v^TJW7c1G zxcV5^^gF|wGcTWf_}z;`Q&={1tIY{H=)nJSOWS}Y!V>cYkf6HNHeJWxECXI}Rz%>c8QGXl)n1QpUA!vT&P z2h6eJiUyeDi~yZEA|+9Cv~hC z+TnOKVK@kR0(b(aC>~*h1jZj(HL#j5n`H37EHjwyCugRs4ECkMt4ZelS0T2$^@Qi4 zmibW2gp<1G)ZO(^H$Bu~tox*sYSx65i2dV4{utP&)N;n_v|)CbVd#iZrCH0@@G9GK zYFkp;yR#~bqtX)?Mi(py+$9L!tq}<*i9{z7DT0H=LH?pZKa)nL5%ZP&U{y$vR>Y^I zVr-)m2l9CS!Tx^1!77u&mGp+Eh^aeoXd87OUdq1yby4v-Vc|($VV|t3-_~=~)_pks z*hyJ-QDAH;T~tYB=kC%7^qCQcEVs4L;w`tvSDF&aRoPXt{2EDhgSN4b?r3m#)Ob2- z$TsKC4d)eMSR04te0ykUOK;(V%|Uf!n_~hLg}EUZS};1q&J8)sN~16w)Ox)0t-%W` zpZwtYAN)mS=ea2}3edBJxx0#W0x@j8iC(96px(1XEr-*O}|FJdWGuj5VO7 zBH7JxWc+h$-%y&DJcrDJg2NoMpTIa*CvRUldFRrFyBBYcU%U12{5v=Ldk^LJ3}hbY zOFPh$g6i!~?(IzJ>q_nINCwh5N^?#{@D_$}j^37i+o88W?P=Z`eZ_J*)Yd3gTXtV-769JgLW(@;%h8(u>`Y%C zKAK4d+{lU;O7To4IM#e#DCg^m=Jj~fa+nU*MC7#0yG$>VA{N{UGyLQ%vi-G}*25u`u5LY{_6(i~# zoWHK%-Jv8L%r7Y47-AH6Ou9=pZy)7czBu?V|N5Jm)yLM@RE;w>CZoEt>Cm^o^7W$y z89i?5wp)t~-f5bgyG`l^6MEh~bpTRX9^eF%CR6rcEXQHUDKk0^A-P6{ffwv+K%C11 zt!&DqMqUA={%MPR#;TaLDUp|pl*L78wl+k#5UVp>jwl?Y?vNZUJ^qRBKf`F}t;i&# zkeV{ClHUvtAZ|U1TL3MAbdMhasfRcuVRy$lCcHER<}#2RMIyEkW{ya69lYgY%rVW8 zlCL|c9hk2gq$mP&ShaN`=>LclykhqpFuKN1+*}!Z{OrT;y*s*iX=wcRt&#r5wvOyB*c2PtAfBmQ6PdJu^yTwxfb~<$T`I6=Y~nS$*7-NDI9&mHUpeKahX1ha$@=t z#&V43KXJR4Xd3zqoIKkwS7C~l=rFK5;#x+QD8X+@&U_~*+}c1emo3@kIQm3A2_-P! zbfMKJJbxKOqd)&J&hcKjZPSUcFN8N5a615n2e$@zgme#cJNzx{3~osPb5iiMtkPmQ z&#_z&!~U4T-p^6_NUMbVU{U3Mw0ay1-;?c55_sqc&TPBuSobtf@r@kc#lCP zqFq*Vq*vp#CFW;&62im=QCVAdd1FFzXL>_TLUx+f&IrYVFNg4Ut3)AK15HU}fVm_% zP#EB+k&Bf=zMK~<4++L+)nb7{z?TH^`2jq@JV2(CTBF}^B? z#iv4w2jtZQ*6ugW9eqh}pO$16_(dfF=Ej`DT^bRV^cZqH1m+dCxGFgs9@9L(FRy=_&YJBD-Crs%-|C@Y&oB;Pp$B{B;kISX^LsG`7%s?E1lmuA(Hu zm*crHbNku%zd8Q$8)KWlUw`1;5UD3PgupyKDGWZA;#3GMdJg7WN(<{Y-*U6WX|to1 zTxCYeQ5g{mEOh3^`9X4Q0wr_(p>iC9VswaX|J+V!8QS<@@}qBk^v6Ga`kmkZ{(t|| zAOFoC-<`Q|`rX#11Bsmn)4C65Hnu0#BN4IF*W2lXZ)0D4YG# zMCMF6%L?0*vpbYojhgGC34xnP&S6JGZbwrYV193A?GOL@pH{y9y&wGI@As&sd*q_g z#f5>B$La~pvoW}YgIBU94;xND->C$%`c`q@5cYUH;p7x@6M?zcwoJCj;<!W@qP2wo-CzFQ`Rej+r}2(mgVbE)cwjIeo%xJOIDx&un&5ltpjk%A@|>7J zFw}#Z)nm3u4S@v{M(E68{2o<_0b9VFY>~65rWq(U;su*>!6sj^W9$VUX(jIQk>bLw zoB+Vt(o6&9G=+^wGl-3{n&xe0OomSDj6*^`e0oq+u-y59PB>x2`7fRj+aBZy62_v! zL8k(il?9|D!i7j?`H4Le6HFjE*H&KBMYal-5Xzj*?;J0TXlU$bZooPbVM5Rjv@q?)Ist7Vafh6Sunhg7&ygG zT+vCMn3Ruc`BR(vG44Jvon+Aht-$!#Vk012Ltud+^O4iBVzsT=ZIEc7kmJ+jFQb_EV{9M9 z+BZGMXJHKV9MB&6IkcT;Zj2*o(Uw29W9(E%LR#3Ke1(=GzXgRm6x5ta0GKa3HCSs% zmSKe%7s3rQ(Z-Qb&2_i(S`>XTif+;IDir(U_`8k#y=qAyG9eGF)=Oo|5WbWbBn}FY3xzTvUlI~5<_FmZ(PDtrFY2`6R^?Tlab+IEq-=3Ud zyEb+EgCBiw{KY44U0JSfzZoKp4i-2hB57QdBR7R9&0xqv=M)`^6I=2UDK6Ru+=KPB=PwQ?az5Q12{hwjZ5gw16k7XO?tRO?W_id|8IwwsNlgak!B!}EB@Ir5I zOlhghfM#A%-Ei#ewdddY(}@?~__P20?*T^5E3JvbC`2M0k}YHlbk&@XoX8Z>p*)}Pb-lA3d}n*ag>Ztag$m7ojJfb+VZyM#MK9< z(`~Y2zOZY#F}D+~FeomiJJynn8!4ujX_hAmCh+`4g5xW`Fu;7)Dxa}PX06iCVa`Y< zv17=DBy$P;z#}@*h=zX;X{D41fwT{x71Qv9%Mh{wm?PR0nJs`ha%;!*WTo#_QNVQt zA19#~B>`CVcuk``&)5%9wy8sBZe1E|ZtG>D<{pCAV6&*GMU`|#P zQ9{6ct3Njia1sihPt($Em~RpIRhXkQAJ;0m&Kc`4kn}ri(SYZZCds^2f%bCE0ow+- z*$2;&&; zMB!KDU=Fhi%!e?Oqe!MANUoQ0Bqu+M%@1T}Khceg7b)SgUJRZ?IS0%!E((xh3lCs^ z!Wp%3?f#RgM>j`iPhA@snp2D~nYLAI+rgVqI!GQTKMc^&TzELdJ6zzi(as`v5 zD)F*P@XV}yVv%Fw5=}2RY6_U+aPx)N@x)`_blWf%v}&`i*&XW+CmD1#Qb0F%42ty@ zI6mNRQs92)ygD4r7i=mH=1^LmgqZ+y^ykmQsh3fvC7bwJxbayy{XBvJ%-@T$VW~8D z4(|$J4uuCKUu6)Gt3pBxVK_Q-S_+M2*(gSlKZQvQ*ZQJe0hnXq2zb5_s-F+n&&ScD zVd|SM`L$@nrD#*TKBP+J511Qxdz2!7I@E56@a8o&w!eKWrL4ddVJ~bctnMtRZq4fI zE3B?dh>TG(j*!>=c8LW+GJcRwB2@`OWc*<8TqY0z=28I~!W} zPQuLd?MTF}Ds)v9*uitaJSWebl4ZT}@cR2d{B-FXKRSEoMRmvR5J_Ah-=R>blH} zdCeBdx8aF@0_ONu5EY46jQCC$C@YeDhFKOId4sVMnX4vpE6bja+BWjWTgE3owo$CJcn4&*vKT zSAH&%5VBA()j(!JqYir~xf$uevFoAV!M*WwY>CEA#0O-)1!(j-$Wrk)8mm~xRT8$G79%(Eson=f=U7)w$(+1--7HR6pav!I} zqiX(rbqH1wAuuZjVtkI~C$OVA;ZLCO^ z`j04r@9_4G3Idk2WIkwK7QCtzJTi&jbL(LC20!t00dsP`Y0?4aPq7|Ik986l7c#F{ zEh}d8f{{#pLaHK`bw&rObH@Od@gaLK%c)lgv^GW`=B+z; zsPpuRn1W14a+I$+tFpVetR<`SU~yAVR%)Kj6(!%te=V4|PZScUk%-hnk%AvA=LKQ) zvr-r$7lp_rAquHLEte>z5+RSz3l8-6_ut1C2WYK(oavUDlg_^Jm{Xg{7v2+;UJ{p` zSJj@;)*hqkyO`FlgyTnp(h|iP>6+XurZjJtA!N5(smyhmN}QfrkGq0mGI^0j{FEwj zNt2^b5QcLnRt{lHMNOf*BHvY62&y}3 zOI<}p4qvvl@nHRl+ZRuaOrN~{xVraFfH-=;z@gMq@$un#K4)=;rO;<8Oht1}v8m=J zHrO1^If421GEfDpoRjQCxLL@`ArhRZ^s$|J8cT9G&l6dL;?4o+$dj+He)6O5|Lw2- z`rkkMKGT3Bfs7^S)EoJOrlS@!%PgIFLhCM|k;p(pzejNJ(_8=1BFwGg*=G@g%(%w>C zRoim;=EQ&dAHSV``HiDP!;!^#x`@#GOREQtAFpdDZD}j)Y|ZFwPQs67y)-@|p_3xc zNxT`(smQ%6SP=1MxHm?wFRVYG6VJ&bu0Hr|GueXI(}GGw;n!?!N@{KM)i&s4fGs<}`(*7VbZZ$t{BRBH>g2?xBy-!nZFH)T!q`RQ2ta@Pl;7v391*Zhf zIl6SL7D9kIW{a?I2+@c*+(aJ^wnK8^>YxK8{YJW z-U3MN24V}x4mh(M%{fR8s$jf@AlIaYn*}lp5xr>$*CeGDwiZ_7CCTLDNY$qGlbFyq zTOX)&ixvl#4r7lz#$*Vu=q*PaNR9zgsKod_I1HU-ND-Z!p(YqTR#lFhuyo$E?65(B zU$ATM>v6jwfU^Yx3l2kZYJhefFvr>;_!4I{0+`Ivjl*roZ6<Ch%8WO zM5W8LXvrj8q(VS)^ydpk$*f)kK?dgY2MYOBqj^9}e>^(7dUtw$?Zw2#%VSq>9XWCC z=)loRr?*V1IH}Q`kqB-`A+z|C#hN1C1BqZ-A)S*;R(0}Kjd)QlcxKl?(;!MUhIimL zHyhw5K?LHu4FD%GV&qT3n4p}4>Zo~>aZ;b7|oY(^9XwKouhnaId z)V$)PS6!xc9BaB6Yy$zs37D@# zIk!OnVJ~N-Ehnd+%W$w`Zq%+`awr#_>IH{t37xrHvlMNbPqaLYXKqC6uf-bQaw^(Q z!c?K3fw$jdHOh>X#_jGsbNuJl77vyr#fXU1Y5&a}|_$3+u9~dK#`w&VTFA{`twbf3YjT%~M4Aa!WI_ePn1T zl_^N03sVjGsRl0C95M^nndijoNU5uEetMtb6opV_7gm@r{ zqRve%5es@#c2`STXKPJmP3!r0$3OYW-!FXh>4O*VpBW$Z=48Hed$_v2y{4|XxdonB z$mXBJoOouMfOHbl3wjd;206X2tQ=*DO)>}2hoiXPh2?(|Y44lkQGj_b?q%@Lrj(ZY zq~?~ihGyTr2N!B8vsC_Hs!NJ$4|N}p^4`u&UM}*j6(qgPkA9IG@!aQnk?i`w=UH;f z*F&K&^TBh#e9k7BvOpOQfue$?%;>#gPz20@bZi|OqgCTZjholn8W3Q zb4g^9&zcPr6h&aJHY`|N6FTF(i6%SFtOjr!t~{;)b5d}}0p?g|#*o6z1vcD0G+_O- zZrWs8b34)ML#_eI(U61W_cbugsE|O8Wft(d5anDWM4ZyLcKu($+ATQl5;SB zWQU6z5F;>OrUi=>53)I6K5G<{+;x)KqQ$<9YqYgrZTQB$nWb9~Cl?;yUwk}p?pkZ- z!Oo`6rl^D(jp>+7bwMV(%=f=347e>08WHmWb13$+GV!WLx<)}c7sHx}phCc$@Z4&^ z+6bf*;HY%jgd8mbTO55N|C|IGn9V3q9Y!FSf*|$4^p1CqUx9-;u9BFU!kTQDIoI6g zRi}9~+yQih=kO>ZLmsyCH3u0!0>)QtWP#lhjkI$HL5_eq*?ff6Ay!P(;-FRvnBzGB zj=uw2vaQnum=y`k)r(HT^VLwpyj!~%Wn4(IP9<4y#nLz8EN?oLEfhaP8iW;ZZibQ? z^rpzj{&y}NymUFPupl(Um)BNSaj?9sx1g>szhNN1xFs<>&7gHi0)lr32kl2^4w%E) z!ttDiIcduQa|^9E8Z>-f5HHw2AZY&^e1V_Ju;1xpDvyO8n#jHW5z{p$DZ3&pI*ZO+ zU42AX+hJ+#4DD?XN{Nx@`V?8Iy1evVCh2QdsV+BEn`d^_dP1wr#*7eKhJSQ%NNKC7 ztN}2$x7Iq_tKDtr$w@*B5nHxL`(ZL?Qxg${TkJ+R4wBauz+uk$SlH!p1rBU;CNL)} zhin|o>$=N(Pam3i@xjl2{n;mf_S;?lZckioOV5$q!h)uF#FpbD;}@nE=Rf||; zky9KK#n#%gbYL-Mw^aVf5tqjnc!dX^lnkm058msc}Uq z>7~BRvb2KAjIyds?6t3}&Sg=$Jh zx-9+)TC$(|+y}@h)fngB$|P?f;pD(3NRCIKd*{-CCn&D%C$c>E936WrT<)0zZCQlI zfO&IfXH!8-Ln*Qm&tAIo*Z=z2@BhW$4Q)L6;Kx5|K5^{I*l0~>Q&mk~YgZmoHbBJuOIjo*nf(#q}c5_FkfW zJyi1|&IFiGnu2i#N_NAUMC=9%>9kExHVql%*d~BMArwsJa9^OXY5hJj3@utXTkcU< z3BSLsA~oW4uTN)5{;UGIP`_y-w2=veX__{p7HrOG6EkJd<8X7qLN*`+-2~}o7!>so7D!J{lYx4SA_C@< zG*(ooCrs)IqZZqImK}&?2~nJH)xch!>6EdC0t;MD@a>j%FVD01vc^L7Qzrr+@#}$fME8)u&&* zGqrl~{O$VogB`8?XKFeQgeUa`%ifXe&IJ$^3;AQi;^1L^04$LUO38{^w5Anrm=w?K zI)s)Z=N4Tt>C73-4H+>dikTp^=v??Y@(SS0$Fvd5Fep5M(;lWovSp85>VbDVtruZz z7Isjy<#QH2637w5^(@?lj4%9lt9H_#FWD(fk^=7=Zp)g3>^vgZ2#hbWFkeN$vQ2}# z5=;q!+c-gh)`W{1xvn8p!Kgss7!jkeuEM4wFn4K|+*-`Cp)+5IHqIn4fcd>t=dDEN z>2SK2k>!g6slB^2y!|Q@Wsiv+IDfVG+@+NAis-!Dtd{bU{_@I$rR6=@sOo{-#ENi7 zqUDX?FZ%`VhNuE*MJpESBqEgvnmLb?S!7~9V9wBbkUW^@=NItCo?zZynP!hQ(OPpn z?C^N$@HebobXGg8GqZ%;xfafSSo`nqcvmq^8zC@gOg5*SF zDR4IBlftH<>KtoTE`qkK2*SmAXho5ypwM&R?e?iB3qSq!zx@1PKD#yh@veZd)ow&>~tccIUbm*UDxb>$?+6sE-%r20zIb1Sk6D|5=Ka>^>QDk{@!Ycgu8eGPS) zwbj0++Vqx&bg;d(maV$fR#bf&G7K?3g96OAAkS{t+&*x`;AA3T&W*;CefKQJ|F1CT zj$DcS@(Rq64@2fUTM9dxN}8HmFI*e?#cw|Q;otoIp=*P^mo8>D)m@*wUxk#jn!L95 z(yrEgvR0!dog?`{_6fRuobYlnkL=^;&p~q1sN>+3^~rO06QA?^cVV80Js0h58FjTu zH?AM8s?OZMcbCV)IAr>cjM8JpbvKI3C(0`}i+se_S+#0NVe`uM^^uA9KmP8_;}4HtyWi0DR!`5-GY!4HQE8ol(sOd^ zoq!+?=ExQp5e7_3f-$4?*dSk2@HZ&gOP65><}iD&F&O_OVhfCjKswrTjLNPu25b(R z*J|c;7#Gs9R3|*g7Q879xy8Wy#4Q70j&lLD<#YHiVm7YXEfC%pL2RpW$pUG`jNcKa zeH40iu0@AK20vxPZbWCk19R{krv~`8vs&T2UIfKy>r8>&Re|G-MVl6aIS2E_F#W7s z&B1&!(Q-e{bvwy*DaPJM%W^{Ah|`EXI+<80wMRuAICCCKOHyfBWL|boTV-)yS>>U! zvIBV~Jz1593Vihm5m}+H2Y&gDfIT?qgj5c(#UPjJq^OR`iSi#j@0cK4f1`+a%EC0_0^ecc&hL6^JxEo)nsy|smxk}A*1)#T)> zv$EfCn0HZ9eNH%FZm$f(8K^o{WXl52LrS_VB~8YLMy9>q(OKu}sOET1V7{H8`2Pp< z#yqk%?u#&YRu*`1J5t|Mb>+d$mp}N?xBvVfkH5RLTO8YSdh*iHtS`4X%NL!OYUN-K zseA|KaGQhY9L%u~6b(6eo*s|Vq(!UQ&RpdqTZg^?bEqpE%mH?6c5Xg*q3yz@mh)#D z&K|EndnmWB-sFq0X2tRW)@5ZSCb8 z%*hF66Pb18V2KwHkp)9s64&Rej!1qx3fCswjI=f+x3*-o zx8@vqv!T2!dB6W_SbQ6_Pne%vcDnP-xw7_KrH#u)1&?!5U!;USiKd^%Fi#_>%?Kj| z>N$%X5;24Y*znL)-&OM-nlK8gL}!kfARwIt;bLB%F>r-lq7P{e2~^aJiQPplLSilI zt~>-P1QC{zPo)$ONwJ*BFycw>mD<LOyEDh79JQ(8^O&o1-%_T zIa~NRV9v_vm{gJjJAgTHV(T>6^@a#sEV6v-^HV9eexg$-3V5h_u#V<=Yb7C0@wQkf32P4*>#LJUYhzKYYChbQ|cErKwVum;(TU z1PGGIIgnr`#T-H8$eaV1GbILz62&CuoTErlIaRh@F1zh6=j?LcUYEOf?cVL)4s+T) z(>?3GKOo69o;iEYGY&+N5+#*CJluEReI9!Op713;K>Q-QmK53*e-;Iko^d;47W^!7OC>wlWcyd0U!xA&wC zKeDWT!YrGo+eZS8S3|5_RHIYj?2$X$#8uTknc2Yw2ByXsrqOw;6{o@}!D)PsUcxtv zV=H1f`7B-zRjCWn)rrlO{IW7(W0eXpca|t2w!m;+UmRWgIu5tS5m{|VXHMd_h+1w? zpxm8#rA|p;t`(!O&JU`WXqCnK*kWsn#*$I!EbEzGtn8bXAy0;%)qHb%bag+=Xw1%x zHe@N>ZgW`8VK_%&bqG{^=6sgsM6uxg(=!-i8h+zOhz2OPc|FUtmYI`L7J%`-K@#AoAL`S`F35t zEnj2HH5cVOO0>nLxg}+}mF1{x^y<|mDd<`eW{v{V;TvfvM>-0*4GLxgp{{n9NHOlw zk-jA)126nP3-7EUk{~Q`CDhmDOJv~895#boFb`ShKsE=vBEWMu!~k>b zgp#X6;XxZL8fqmZU@bIYjY$E_VKP}`Fjhm^+cBB_oS6N#>EHhN@Bj5*|McOvf4p$? zXm01;`0RSM-f=A><4$Vw0^+_EAT}K+AVIIlFhoCzgg`Fu9!~_A&LcKL#1nf#tYg4@A&WgPU(=$wxvY!ony-W%k9AQhj8g#_Rb zz{5gNpf~D>@@=>qBy3g6e4L$q8d15vMD{nY#i`=Ub<`&z(7pk|HN+Tg2WGb9P{H zlydJupBJ;AMvCzzFQcUJ{ymcm$)1iYXbTP&*vpTx-vpSG0IqO!`)dm208hA5*Zl6< z-aGGqviIo2v9*(%Gh2h#XReks)yL)5_=WY+A|?Z9^MU@De&T-gK?vnA$Zy;C(o=5m z+alIG;xNc8@5wlTIg}R2=72dsiUQ2Bvkze$@;F|PHiIcx9fHP!TX;LcK~P=LrGu`B z3quGzU`|f&;T;DLwoHFA`jiP^=0|z}oa)b&GNf`rRKZ&txY;UN`=mu|XT&IN|3prSH1;&rU$>|XC$LGM|LlTT3pplnL(JPpvEl2$F2?n4k(!DDZ zz{J*%L2>W%i}f71J6)c zfH}|Boj&r!xb!ueW13MkMzaji%G?kuVXpoyLgoP!%rs~LsG8sB^z#Pt&nqqZ*QQWJ&A(Dlw0?)C|@5VSt zUTwfSztVlsnUGv3A_cugBL&P$?P&$LmQYhPx_tzgD>F;|`5BJZvGMgiU6Cy>Cr+OO z*<6a%A+k4=%0?k>%Uv#>hZkUPD4Fd>dR}69F3G}mdspuFlgZA@=H%rIwPvB#D%9EC#n)T8D1%vGu!&3#l-OJ-G1(=i zLb1_-!V~v%iNPT^+7%{;TyIestgbRg>dgSY+GL7084_*AD|T~+L!aZ&>5H|-l7hmr zd`D4cDJH4_du4VF&Tdv@)S_K4C-uq-NKB02Jh7L&HjR)o7A`*wSsjJ60)6{+kr^nl zwO8e!Gso6{Yn7>`w#e=%=^YyX%|HC-!;ii*xV$^KvN5rLII*=++*n&wqK9VQP_1># zEF^KowQ%GfzrKDXojGa3UvV1%CpSs4e2U>O%Dsh3kY4dhBXW_Sbn;MOpqb-s2u8+D zb*6?|OKr8q!}Dwa#oy15Ddwki)Qt_5UB7MXylbvF$t`$0Bkn~4f%%IV?lUzPN&=Jz zm^wf_aCp-93_N(aNrdJc15m&mhlik?qd;{?E@(tiSQpx0hpa~g!;XlZ9avdV_;Lbs zoNSAL_XF#MU@w0sHfttYvry9iyPy6)zx>rdmA2m~?Y=d#v_CXDf32atB_Vz^HGYPN z#ZpKaL1dE!F@_S!u?P}6f1k~}CzKou#F$Io6$sp_HGbJcp#VjiaH;G>p*$2zPZTQX z^BWQDBZUyg7%Zql30Y@j6H0I_<=$67e&IlkxhEFmS3cyE&K%dAampFDH34?~nkc9! zaJJw}kb;E*|Iv=3rFYE=nRtQ$C~_ljczd;-IkhU`Z7IduGCp9AMXI~v2>bI|Ne*HJbd(} zroq{X<)hwfcRKA2)v>vCRBjJ7Vmu&ZF(7c2LfHwT;ZPk;i(*p=fiUk%x$nq%?iIf0pe?*W8>R^v3%mfIjmW&(}T8|xDz45y(FAZa$QFykOy5iXg;_o zM>eYP2NAKLlHu*llSr{Ef*46z;ui`92~Xg_&B%p-gI5ZG8n;#-cs)%C&3rB+ zW*|zCap|o|XW1|R`U_^8{w>e*1tld-{X^Q)(#Wg~Lqn0F*=p~wmG>4EciRnZhJqGD zPQ8H>E4@hZ_Vx7+^!338D8v@XEF4BKG;@DXPkazQb4Cc=%k#3gH~!~!&NuKaO4tQ? zjwO8)W;Otosh!O5XTLQu_f5r!mnr+*EVsAO8s;4Sb7^hN6*aD2PVY7#R>I} z4nCoFzp%p(9`5$P+sBk%gwXe0`$1+&H|vRn&7Q!PNW~Ju)J; zpym2#uEms_dqtO}He@KteF}F9E)iSUx-`P`S1^CwoTEPn%t7+3_%Ncepkl*8@~oJM z40Tv~6#DZ})Ek(G=jMm!=7#5F^R)#cqd{shd|NVjRT>>6#MM(@Zm73LI|G`mzCyLV18PjO~m%HOlNtflc?(;b`Hr-sU&7d zH_~6pGA_KMod&?svAcNwXPCEFkO-HSN}~(rrPqcgKl_(Iz4-d4Q-{xoHg+cVk7f@K z3L9!m%8Za%oHe>exEX6)9`)Da$!n66Eq;_6=7jd7NCHetSx$2)dHfvA-3|Po1sV4{ z3;aRqDso|ZCwaWpHV@D9{(*iJN;o?#p}ykQ)lw)eeFv7Bqg*Xuj%@Q6acIkV&!hQo zU=F0OGW{ofP6OtMG>5AkBhHlw3NQ}k9EIi_1uY%HEP(kY0=VGT!&OigAvrp8BDSys zQ84mB!2o;rxPtxItcAFONmB=4{>dkQ6P;gdZM!~?zoPMl-MQ8N+??BKiPL;KjvS#g z$0>?eFqeoAc)UH#Jq050959Du4ZjK=@o|VMq$EoVP1wBbw|$7z#ZZ$_!){L;(;32_K>dV9s&DJPe1AA0T3j8-$r7 zOy+Kw&vUs$Y{6V{{p0D4=g&UgfAEEpmK#gE&u@*cw%O||V{+=~{2n?7FrV|MEK{gk zw4g0qi)IER0v8+oxIpnzBKSg->>ZhaT#=LTT!%1VDG|AKaw3%rIdk5gYt%rz5m@x6 zZie7ghZu*GT-Q-av@hN}Y|{e~ID?Lwym;}$u>1udrW@v1lEt>s3xx{TnhwHnWe+gt zL6b+8JN%g-Iofi(1cTe~x8q#^cuo#*xH@q1L4+r8Xl^$q#=b;f!iyshDj9j*Jd$(q z-x2~M_L0mSE8L9}ZN`gMQ{>RhXVcZgapGLxb52d#M~@Gy>MJi(1B;s5yGAE9rR7ms zS%!vUz}(hluk0@^>nk#JnDU!+*$oD1dW<)d>gx})iZ{A(>G2>ejP9mu{RT#S2u>+ivn`Z0IjwuDQZ;9RrQ{OPCXqN4N_xM}g$2YSx?PT%<1ou?0FSuq?9_D(r<~ zvsGxcas&d%34goYB4u@sL2eKFryBs7zfn2S+(!Z$hqd3+otFcqWRpN}sQ=}W}A zB9XRGSl|%pY-sXbZ9M7ZWhRHrY*U!cN|Q0tSP*5<#2Gb7X6+SoL5|I+v77U3dW}tI zaA+(=1r~cYA$&B$lN;)Z!sIZ_3PC-b#4hj?1tZTX+AjEKp_&7-p1`tpME zV!hR*38V&G^z@lrV6Mg-bDIOvo1EiBlKC=eN`sff5O^Mj7#0$T3vW4i&LYh@{_hXN zIlcsiFM;hGR&6*&0N&lG#HHwr#p2FS-v90=-~9Q>$KM&h`}EH4gR!OU@xj|SjOMZI z%mo#1SBXz{9r1y&+_hX!nrChVR)KanZ0O;5T|ga+WiYFN;UGDrmAf(m^L?=xk0&bC zu|lyY;6n+4qz}U(zHO{_K2V79h~0StaJ&!*1Q?GV3tV^?a(207^hv-Di9ja2C*!^8 z%puE@KY|NB(D0$^>~c8^EXEWg=vIKwbOZwjl@3(AeL3eYOgLgDc5NX0V>k#aJ2`>D z3CF!QGL96m$Q66C%a4^Aa@7J-Hkxy6?ktG~gKX|zbI-dg`zH_HTiJc$&yL(Yd4K!x z`3+}pRYFz`C9IbgF&Ypw6F^y{(N^ifTMXtVh7mN{yGqqdyfKMjzbBWI8_j(FbD{8w zfd7~e@m##eAVSIm9tV+$IGndmqwF)7yTQyQ|G<4l_;EM~7x6ZNf)Ln_Zxy-+2^I?v z!K)bl+VK|V*5%Xq3q*VwL@nHAeS+JmJn?;w@F)y7oq2eTz}2KJx*rbV;Vl4$xp+k& zoq0qsBFIPzSvW2(g^)9O5lo`4uyF<&msrVd4royLD}}~__cHLi;@#h&lKdU+M)J0z z1#2<<%psUx z^1gi5C*X8o=vhgowETMR)O+b;?|bVL(>{)c?FCDBP}~W zC@0S^QGH3qJIkYR@?{YkL3BklGdGBxPmRd-%d1gn%B31(L|wV6sUoVbP=?OjWjKeY zC5DjP5nY2|bGy3A8dU*nqA?OM2fz`Ki}g>Ed8p-hZ#IYcM@CMVlQ{kS6;dVeSgTO$o=+5SnuWb6f&V z40lxotmawq5t(t}sPt%dMhpkxlbO-sfH_D`V20uyOPbuAz_*j2p}G=q?wr3*FqtBhOIC)jRM=N?#1%7k(vm}vd| zSROu-sMykh=C!i)#>2|KLtXL7mBhExVqYdlK^%A|F$yR?k@FC2f>|M)4C9`saIy_B zC;d5x4zmhC4U#W0={WJcz(9Y_gw#N;4zZc2&2Yl=m5@M)Eg(5;doU;xkB5Ls0LbTV z%A#hJiJO((|Mc0v{_&50`s}~{Y5Ca)UE_;a#}>Lcce_bnr}pM)}lBo3Bu)M z>3q6;Av?;>^cgO-Ki*jS`0L+%^2M(w8cWK1h6_7-BpDeQWr*j20VIrt$Si(7K0aRleqMor{&?c$eF?xn@9Y1T zfAB?VwxVKKGxdJ-wTD>$q}y*%OxKu>?ofN1u&O`+hAgoFa-LaAw__pmsv;h?(z#8!KlnDjC& z`R&xiEndWngc#iSJeKqEh8HPSaI;K!y|o(Rvk~FH5$1;hB4Cc4pd}^^FkfWS=a@mu z5lmdB*kH2|EwarH+YV=KhKDZWf+S$>dV7wQBJ6}BDFvv+e*Km#W=ayfUe^6L-~HWB zfAY8A`RpGS9=tm+vvqBJ`9|NZVS903V&aU7512z{CvU*vJdqN$1Q^Fw<~A>4ofYaD zafq$N!m_gCyAJ$PZ*wFs}sF;WNRWjtk~g zP;^5kzQq@8);B+%Svk7*_Q36>YSisH9O55)1l zjWA+RU!?jkQhmP|AN!6{4#OdCL%hI=PlzgP5+i_BPzc%(H}D%l1A*v)eNXp^Ph7ah zIS<6M!#t0cdzBWr5#oJYfjRB2lC>qK?<&JKmEmhD_G-LvDM_-Fu2{~CDGv4N*5@3}Pri8fgVDKlO?l(B zxlK!RD?cSEtHNl<=(EdG(QmIDve%DS8T(9$HJMi`H5nDUQ(kA!dYrxNaUR45!)XEj zr~rRoe}7*;Kc9dA?0G`#szb_pSmEj;%33r`>L*En&S@5I!s_**voLkytvLc zTSM3ALp1uptZe^`bV^#1U!3w3!z(O}&&puOl*h7i80_3&b_OM@Tv<@6O3kJ>R>$Jr z5MYkZ++{V7bYuKA%+Z-gS6N~!%`tf5hB*QfKL_(j+!!i0sG+fd zzBjnO_4Hdm{?6b1SG0~#zxdtR^`p$p?1J>T{1llfU1Y-XIGm_R<^Qi?PO@-Wq+CeP zjALcQhNi|a(qot|p0hym&%+$^P`(}mO$#t9GGVMqN?^9|O=h0ag65oOu)AAs(r=UY z8$Yx|S8+e#>uhYTgoy+H#N_0GH@2;5lDw z!Al8#7wGUpYq7{tCMl^@lvm42D`iFHQb#dlAGx(iZZ1}t3YA7jl)(|Hx2p}7XuToX zYy{FX%z3$%>^w_mfhkjG$+j2i%PMVEHTLRSdu^SqzQNYuv^O{lo18^W&1DUZX#F#Y`TJCGcL zJU~s*O_o@p=e+6F3BBDv1o_=CcX#z~WEPT$j>&0tZdFl6eT_LMD^4uo;EklOFXN(@ z2!T8si(jtLbgz_NJuGb8ic5Z&l>8()=|ma%JSk}daFdB1M2gXdK`I~jJ+;j6*x?3( z=kT;3Wy=L~$|8e`4gEPLb%7PU6dH_Upy2r?Ck(uWTMsuZ(7;1E$GdXeB!V3stu=|R zlE`)x3Dc6K8J+W6@BZ-PFaCJ>B6CqOrZZqkT~!%mP@tK{8R0_G$&7h6k!80XlnTY?kl#e{~2OLNo zJ|sYZk4P&3mcZO)*N=dbkL!ExL;{2oxD(oOk`Et&ytdBt!|NA$A#=eTa}Xq_T|ajk z@)X7jFrDJlpvYmug1*{y*qXVAAcas|N~Htl+d%Pje%s8zEw=xI$dFx$-;T)dP)^+uQ@4cFJ!R;o0z7B0LTQN;VFtRA8`C6W z7)4=2m8G4X-BnHPIxNQa4r!~ZBXhG-i*p?v=Hf16Wxu&<(Aqp*>ln1fl&2`HN!fKq z@36qrUgs`*UI4LSVu9E~_4f-v9*dtJcurvM>kZUj^0;`;$M=js-9K8ZuD+?C{g7L; z%qW_nSZ@THuQ43m7=VhZJGf;|pR58}u0A;57?_dcmzqjXPo*TOPci)hl_6oNyl6*k zSVkx(HnKaU=E%Wr3H`RGjX%%t#GpdzxW|wPNek$ldB9|t?^Ca<7_?Z zHO%q4ptZVT4vYilKsvyVU&__t7m97=vXUA_S&gc)HnO}%QCy}hELB(?q)d)TqfKqJ zM;UC<278R&60I}E=nImJ`ALSHbW={IDJ#dElV{E~l~{^vORF2J>zZonn`@nIq?+66 zP^}#e&UR;QtFyGRv*X6}kAMFkhhO^MSAX;Sk)7Sv+qb$$hl&~y+mc)FG`2QsTW~z0 zo}~2>jJt1ASLcAzu7c9y_C~^2^J?q=b37+nJ?isqJm60{b61dydvXf5Oid}`f33Nh zaWWat$JfKpFXZ$k?nU3Iy^X)FH4n@e_iS0}Hse!I;uB6{V;)4uyhu*o?rJvi|3GeG0|+mSBS+Q%;!>Fo$gG5^o92L2@McArtt%Ec8T#Ek!17 zG`RNM8Gt#c2-_r*Uf|wDYR#&EhE8%nnnz$BE4~*iJ&Bd#4jNuKumz7!7`{Yk#aMep z=IuM;Pz2Q;hx#M%95BaK2mqFBkMbE9q27dxrnTkW_06YGzwqG2m)9SD;OrUc>KhrV zYpsk;tfkU=sI(a-4e`Rup|JGR@OA^vPmp;v$p0P}*|YLTJoaNg2QyH>{63p@!14mj zVKqehF1~ZTr?|%_j(tQy0>U`Au^mc5{3FS<2@e6xk%xc}PWxTJ2Vcg?pt-@HkC+|& zI}V;djTdn!QEuSlkP{M#x5Lp|BN&GPm~S)5**^5%YXRQ72o1)iKdSE@%?BjEOY=RT z6Q1MHHh6x>WB}=Im~V6Zjuq5RfybWI_dr3}k_2u^sQXbk2FgTpz8cM2iV@5w%jPqp zx>OuJm*FhHs$h9b&(-|W>cZA8LtPE5iK&H|_I5*Ym%g&!R5fHFFz>gki?2wG329aO zAX&sI@3R*?&jaSr$)T2`Kyok~ojG_;V1D`H#mg7mF!zqikFLJ0n|eR2d@i(fhH4w8 zSgwXRI_TC$L1i1eq`@as7nElT&NEXob17+=fH^fO_H~L-# zE2B)6YUXDYgjSTu8mrU|rAl(5!Uc2Sn(+KJ%&ToNs2VFe^QbbT9NJ5{ol@PznI^CoROYyKweFX z+MFSU(n8vDU>xiG*Z}>XV2-S@qp078e+&_g@{0+$?w7Ljw0Y_Va&q3kK*?Loi(Ha5m-Q>WW6y(R4RiHCV zjdm35i!yy7N@^&Pno5l&VD8Ms~5d86z0@~40J_wWAhpa1&Tf4~3k7Y^Thzj2_;R$W+9Uf^u9Ha8kuTsh<& z4H~2YbX1eh9Bnpsky`80aBc}jQV@ak8WP6-hVU@DqsYnryoB5&gkm>_VJag(`$ow zmU@~y`n39?wA4Ft&Z305gPxEV;{HwX`{FnqTz}}#_e2m_Bu5hEu~Y>kB2;nGnafE* zasl4)2w4VF41VfRBD=4OLL2`uN^ue?!LNgF74IOh9E!2&A!4Q!_#6Q=nMZ2n3B(x* zA5*_$DS~iW50zLTqN6h>TU1ge&Scn_KmB9n~EJg;mIm8xhM8c8{y1tMyaLfJ?4;GYQ_y%D+#|=BA*m|(gVPWJXs1S#qA!T?W2*u?ChhUD>Un2Np0|?2MfHt-C)X2NWeDJe>2>3E#mAd z@9d%4|85L*Gm5emL*G<0))gU}D%NTwdpVl3lq_FNjqFizEkZ`8CBM7P+1}foTU1ir z+iz*8OE%?Qv8CGEw1u6T@@x6kH}p-D)y4fqYFn1fnlHgRc|rQQ;DGa<7hzd}3lTg= ze-4cM_<4K#dJwORpC8)t3m%uxc>AC7Wd_7rQrebM1|Kj>?l6icgRIwSmTPoNYp~hL za@4ULHQrekdY&UV&rZ$M(X%v+%xro}(j{T&DVC3yB$%Bd3QrY6ZxLvPadugp33ttK5;CYp+s%=otNx`F7VUbr_6)40flHf!bS~Re=z=a-F z3M&hg7JZanPYf;ncW!+2vmbx;*S~r1$A9zm8^2z;_m%ObNAa;)`iu-svf7+3H>FE( zKMs1!E2RG!<|Ne|ZMmz$+-*5Jb60cDL`VxZ`rjxmBskHP(1Ok!y)?+|egvg~biP5y z(d)Q6tqaR&wuye??!7q$I&hw^d)sz1Y=jUL`yh)y0bhoJ>+ zxx!>av#l@|DGkL6J$Y1`N}_G0@x`TyrRB-x6-i~K35Aw;hdIG&NVFJ|ExIcv144U} z48|0bEwivJr@Y$K*z9O&FKX$qH#J)t>dp0a)`sS~tGC;3&3BG2b=+D6u{%eWIz|?H zMi;M6tPDfvXxg-SASNzxa26>z~^ z3!gl|j&_{{NJ4=jc{Mp5P1Z6;t~!zzg4-&7lrtV-r#(dXj=t4XKQW-MSTC&FOpaTZ zaBXceb8&PHx>; z+`l=u+1=PRXfh9`B~K~XOHu~184pBc(+4jKsBLi=Tz@-a0bsrd7otRYPZkN7!@&ZW z@1wPLN#*w=mG_kLJ&^ztQZoIN$sR;Sov0KLWFAIihe&|X6=?e~#vIF}M0JmpL#{bQ z0#$7EgDBOpT#6X48P7Zr2y-nxZMV>zK}DYh-t{4LNF|*lNgM`k?wYH zZt?{)Lg{8*OQPb-{eAmFsF=5c$8=R$(e%&%e# z6{|BHb64#i_9$ZMPKwL|ya3klq11nz|R zZ83b7L(VQooLS?aJB$f9N($bLr)?&Mtj7nhsDf4_LzbdKm(=XVL@|_>p;$?wgtgk; zSYJ_8-_%&-Y#o?gY`!s+Q*26iU}Yx1#0B%J>$Pa&9pOg-Grf;0ug<`+5QCzW#ofJv}aZdYthNJmtrt#M?5u*5dl^(j8;Lh2wxZ z-3B)cfqA&Y8By5alWnKx6#?e7EImC_3z&zbrFu#uPKW!QXZr=I!$XrHo^$ycQLIB2 zZxSZthuTWT4UO@&Wv^gfQxscW7z2z0=C5TIT#+M_P&dY_Y~Z;JCx=MxmQIR2&~hDa zRYa8;qOi_yH>i#Jn7o46_TirGcVE2wgYSRv)8BsKC%@l$`t7-`cM}uxb(tCY$RY<2;81f?Ui2DV1;E_^;;3;3H|Qn`(zvGO!F=;Zh~;Lp?R+^xG? zr6FRtxln2?Bt}Fq+-Oo65niBIn+(_$RU6DPCTonz9FGwv+HaE%-jx`GHo;;{vYFEg z3v(-~bk%jHTBps~VySO3)wNj~`--}6mR}ol-kxh4UqUtCnsMH^({O#Vad@Wf_Davx zM(^}y$M{Ou#76JbHlDkydupq9`k>+ZQtkES>cRQX{{2tC{@4Hb>tFue@BZyS|L(v1 zad7h1mAth2wwj)y_U7*T#`dblj>_h?lIB)Ni__5DplzzlZmv&r9nMR`ZH|`ujF$SW z=DJLjOOrvEc{aJJ*O1v!myIIJO0{_?7+ty=wLm(+PI`FP782qd5kA)DG}cz+C&uw; zl#BRp_p%@7)CJD^&PQW6_o~zMQ;yQrjO2+3`a~%8c}CKU%w(L?eVC{`Qj6}Y1bZ?z z_V>xwCnp#rht{zc4!nmzB!{#z7U(k_8~~WlvncSNuW7(JRIs9xmi@&ot!Wg z$=!?!hscAY5)gI}v5S~5;@`$1r<}hl;~lDGhnQf>*@fZeGh-U^q_lJAy* z1ux;r=8G1(`4+oF66ew(!`%S%i7SRKUeC?{kgBB0+ zx!L{0rt5<-c`;UJW?_3~)nGx*Ekn)i(z2V?84VS&6*Z7vBP|uYw1QKY{4aV1czXGH z!Mft@=@;M~NDpu|=U(2vJ|Ou;Z|}3-w72|1LsE(~1AFr3t>D5*s(n1jb~DJ@PleCi z(#$DoXBW5nWEE0#3xjhVL0Km7oROK!$Vm5%5?mJ2FL3-lx&BlYBNV=aOiqkls@8Mk zwM>06&dnuNm8ojW)V0O2D8Ss+pTDvuzV6JUs%*+P<-Q+B7X0gV0 z+H8u^8so~_E3Pfw*?j-y!%u$n{*V9m;N^E0ci&67Qc#edR*)QHOjR0FrLSP_3TeU8 z5W>t+I`SAs42oA+`N>2uck!Ggw78b~NrED>6J7C%$WD9}go~UOw@$*<5L~+(Yyxms zy@5GC4vi(EzyzI~ILwVjuSS`A2bM#n<{~ntv^m5k6L$Pb8I59-MPjr_O;)AF5^1xk zEk~oGsAF+9ni}d1&RSCwtbr|#jvi}kkG*XG8;F&? z<2BdrGz`tw56;vL%vN8UZ5UZ?8rx`}+HSqG-Zr`3Jhs#{y4XCj&^ER_xO8x9<79aK zsB3DidwRWddIQxpv)Mhng-3j02T^UqS6ha;!I~f(Puz!z#N0rPA8HZag_-QJPCLqYD_g*fNE>hwl*3w(`7-_3;qxX zsghF{`FEB-SXlWWOOe@`XWuYd`kA4VJi(KUtcR(on+nnWL^YOQ?nVg@Bl&9r#v&3| z*mStci3>3zbeYMR51~)fXk!5ZQ*`Ql2o19N3Y)RY4PF;Ax5Ug%F>^;Ax~~eyP3OA` zHjFXwkU+0KfS4d;?Zv7WqSRO8^1k)#n;*UX{k<38*m&m~Gbis2FCBEY56m^S3~O?( zMFcL$ap0J~Cm^|tK<*w4&k9U7CHJCb>)6KxkX=7Kj#S)>Qr?SJ9jldxgzXAA5+RiX z<`BtYM?_f4{V4InXzAl<*^?Og(`eb_D9K}$2+c5V-mQiQtVIOwibHY9`Y|G;RFY@W zN_-VyPB!-u+r?u(mT|XP0mQ9`;HhvJLJ^3G}^1^&6!Jj?n^cQv&Y5^8wZIEN`dYx{-C)0sAP*D(z7>4gU7Nud z@MJ#l^fKeZa`?r=grJQ$pY^Q310!=?6No4C37)et0rRmz^GWR0Y{ginIxFO|P98SY z+d4iyVXSGW=;?2txYK-VIN6k9s7tjprBn>&RgV~}$16*3J9T|s=`GilMV%Z?ZIr3? zln>{$NAP7Ysu$E2&&znAhXzwaXb{lx{1wc7C~x_NadK-5#~-oFr-Q6xf#wmq^(L}e z0u3#!qHbA<5HM+m?=$qgF_}9Nb`S3@}`yXVan>18=FD47d|vGH0Q*si6fap>JT0U~|AcD}jm1j1NU+#4*!jgVSQ@8PTL%Jg28d29XB) zbJ91sO%!jJX7Y;a1v=LU&5+Hdma<4krOI9*H5R&bZ=1wmgWRt!Dn_ZSR=LR}(d%I; zgmqkQFe**vSi3FGVU4q!lI_sC4Jl~9wRs7;0>~yg#Ms>kGiqtiwX)u;r9FKW{R5@f z1}g@KOS*@Pdu~Thl~-roD_Z~p0r|L`Bb`S(A4`RBhG z-@9AY*RQRr?YT2`V{NTr_!goR+a@QvCda!bMw$n@8~a+E-PMhq#jTyiT|MP(9fj>( zj>cw-)2YQ-LuW&NbAzVUSpYZ_Wd=&STWojnoVa3e#<~XWI@q3t8>y|hzE?vgr}&cg zW@B!)DwN?xX7@odz|AJT9XIJZ7+w>+ zfIVplj$&X3A9h4|$d6QV)T0FTDlT#z;7!CD?hiES(C8A&~ zN4_foCQ{Q~hH$_fy)<}^<(gN6OPq~Xaj<@Vg!`DeaqsD`Jk5+bij&-r7e0;?5uV3L z(3xWr`cAZ*z#Ni`Lij|=$AUj#{*cQ<1~~TU(dxrAKF5hzv04wV^}qMd$BUaM&cT_Q zzOj4ne7rrk-ln%W{3vZSI#>!{BFy|q{elq%=0;35AG%=vf*bmdi2aNk`WOc$aKnfk zjHcoQ2KFwIMoTto5oNvsb;&T=hQRd->c@fY%L*&j>9LHSFU(6%>U381DFa&IWqHPP0VuS*3Z;c%NIN zUtXhLT=GA=!}4CGT)_9XLGyxCzDf6V@%-{8{StwB$VI?>JH%r?;4BKUmS#c z4RcC{HYhVEBquW@HOf~J5~OCGqMtn%dWjJq#?Ig-mc~UIg(?k0Q^culjs5?Dd997O zS%^WAR1{h5hj{LSIo61<+K(L~vPJ}$o8)$*!emnF%+VEXB@_Egw{}*aefNi-{O%w3 z-uc$-&O4bI=7Nk&4Pc%bWy+AdNG?EpBCdi0=I(j}bF}3sz&txK6!iw?E>BA^c>WhK zcU#Bd6^HW#78D33&`F43qSd1KIvq-&HzImPYAQ}BYs{=`&uVCezKxaqNRv@z)S>H+ zFSI2VJMb85H^thFiAB~}n<3t2jI|ijii>iqDh-WI=B5^FL#wH_36EB1dtuAf^1hLZ z{_*Cq74+EccQ)GYtaMDTbtOEjHYquNj`Mzd7$5U1}OzLp6_YwoL4FO&@m8 z9CXj_v`wzIPA;P@ZyH?&)jOwm23C%S*6t0h9reuZ_Ac&s&y&Z_xt;czt-6tg<_Yls zpm*W%^^N!TzVPYu?|$~ffBY{!i>qJw$ zTM9pWqr7J%GUKKw{%)4}AT@7+$9a?#y%Cf5o1%zSKI1S_uoxORN%6qI5rz{?822UY z9ZAG`q--H3x-T~87a#xhr{DeCAN<|FJ^l7CCikCC?L26#Z@pDsdRw12$PXT2`)^7@ zu-Uyuvb=-`h(L77DUai0Hh4Tx{jO4Wgrk;`G89OD7q%9aoMia`9!!+6z$c=?0ms7EQ$?-yi#pv^c*l;4Zxqd$Kd zBYdJ3A$Sm-`4imYaTQKEAT9QZfD4$zTe26*K<3phn>)uAOyp>Gy8FNQ;U^mhPp{qC zbPi0e9zI-zO7{XImI{>WV=PR3JZ{^wdq_p&vj{G?$V}0V`1heGXQg3smM+S&q)@pyE5Y7QT(4_P8Zv%Mb-*|xrArJ zA}28)644s~*J;H@0}8T<*Z>Pkq1;?@rJ^~fp`)OwJ-M_543}$jQEIaeB*#Zm%FEI! zE3#^niKJUfF-MqW5M+_l@elTX<4^ZM@;eOyljP_B&f0 zQ`=p4wmYUaJEylg=eOEtH|j^{Ye#0QZ%ozQnstsYG>)${O#t1St&`hbvj?Q+c3SVO zHcu=!;itw|pt^L<><_Hm8(cjG(t+`-%ZJ@_`+bXd+h=x~r?;wZEi_K@Pn(R+hJuFrJSQ%a zBXgiS+lk#J9D1(Lf!y9XcMeelZ^b$L`s z+H%#A%}B*ulp3A+ zFTe8X*S`GIumAe*4?g~O?a*ZJ#3EqcV>I?>r47r%CWLe-Jop}VB|?llVM@Uq6Y}_p znk?yqRRBn0R)}R!ARP@b8rt13`d)YtsE+$P5G%++C>EL! ziVJBSnn|4MVXX2&obrCW@@3W)!2DT8?A>VoNvw#xjzo!Z+~I{<{zNGS%pWO5$Qwj& z{}dP8xDj|G06Pka)fI?lxx$gG{Ntg~kG}ZL?V}e%^LuSK=f;=z#s@~7`G(>^T3;9o z6vg4}`9NRH9Ct&gh_uCh3c&msn*o@=C*-~>;5-))p2M98b30a(u$2iTB{|Q;eU}`5ex^+d%VxMtJm}F zRnK$RJkH+myEx4Vyy0^mFfBhW`@9dx_?^ME76j1&lD>I>=&Fpf4tQLS|V>rYXNl(QSJFZ+UM<%w&W^0_Y*h6Ow2e%++?=p9I5TaznS}}3x)euOcFj#|Gp506W}{$6gFpZ7X{!Rr#y%>C%6 ze3)`;w|(+)fPR2tz5$-QVNSDl1LiD8vv+P0O;;Y2UksR2GEIRQdN<6&a?>dZlHera zDb~feSQk{*c!?=Gp*l@vRYYMVSSGG+iLa?t*Oo*(i{cv!6990GK5?P~OZ`~wueK1w zd6_v17)MWzM?7~I(zo0fh{}!9Qlq5MD7KrVkXiKRxcZ*D^=BuOM|<_dh!L=qKABe&-v%`+H7G##W(C;O_KiEH-7t#zxu`Ad!H;k{nEhd!QP9H)>e0ml6F?e}*~vd=*-EF($bv zApN0Q_$X5FKq-Lsf_Rqua@o_EXm}B^(DX1$g690g6g4DhTuC4of|Ok3zCtG_`};z8 z`N(yQHHQCw1Raw~$S*jAK^8m_aw`?!k9k+ldk`yo6t6&Y4u|=1yzEIv%$E$=Cvmc4 zyp&)AOCS0TfcqD?bAePz2GpcUHfOo8_~&oG|MkE6 z;lauK*BACjR_-3Z_;_`4sV+xbMi1#=gg~`MW&-Y0;Ozs_RA2?ft|dZcp{_jVu`vC7 zDd1uZ`jm%bpj;SQkZQQa@WX2pi3sDfkynPoA}xlPn0PKSA(#tpdi!*~_0}9Kd`%=B z4`%iU_znkC1}UDsKIgkU&UJad)$e=$n(vu@zq9>5X9m5`T=O_JkY>v6&0HJR5v|hIVF#dJZS2r@hZ1EEgX56{;6tz8~VV>~jV@ho=Q3$9Dy5;u_t5 zi59R#4_xL1PO&cUU13a!&#fi-%_}b~$9k<_30_K|PbRS@vqf`dsTx^eZ$<9aUgzzp zk%s>3)xAT5v+FoHly1|cSfUH6lI)#X6+`;!u{y^4LGaC0xa{~)GmPgt@VUA_^h zcAoN-U+`ggcn4q`6bC67;laV-bcDB{EkEz=d&V#LRA9uF`tgF{V?X_XuYQQ`xDA*G z82W;2eL;w4u{C&QTY~gubPY7~Qc8w3FvIAVmQBgbjL_szQ=)=WmFI;4r$Wz34QjDb zolu>jw5nA)wxL2*-JD!slL)mOB(HbGqiSu@H8yfT4)KZP2|S9xxQpbZGq->&U`sMqTUVbwz|o)Shwr@j(Ql8yoTp!}Y#7MO$j(Yl&}J!h88QT$ zgXaZlJd`$_4VY_E!`kTUj^do!7E5QpsiRld+*;7ssBOZwq*LRB zldsd#b+z)=lyh>qdvWLL>H*Xe=+#Ydn~W{BPONlJu63Zb9$kXC-3g;0vS*ifyQf!O zJYOY($({A)iB+`U_2Y}^$wBh!8+Xu_1MGk~KHfaJ)-<)=cxR)2Vy$6vy>@J+YGkoy zbhU1Lys4AtDW=r(Ux~FKAk@K`iGzX zU+?|+x1av=zh_p|obsi8@khVec=6HD`oWFu!-?ZZfO+5MwsUULIXB-nztXv|+PkpX zzp~pkPo((vsa5=mx@NXVcAk#zJ;&qqm1E3aug~pj1FEKZof8I-+Q&Hv!|%F)85=}b+(wA|3ALoJF4x&`uit|x7mA7v5|xZ z5+L^8d+)uMB$hx(0xg6FAR&R6Vu?L%@WOaIaqQU6aO~`)P1>g8+aztDHmm%upx-{v zU%zwi(UBdDX`1u;T)pr6zArhav@*%aSo^%bCAbqk{fdO+_p0m1FsNK|9;ZIEwl}#I zyx*d*+&(8y;H}clUWTv`*_m%e1WjSRB;Xu&u@NGygkW-TagZZD1{`du=g)Jj%m*B7 zpu`A!=*$7;6KG9mK4@<;jdFqm6LJS*p7DiVUFiDEG+X%qb2LuqNoe*A`~3cA&mVsU zFkgP~{_xsW<;GRvfHV_JpoRpC{m^nB_ep>x#sl;dXtSXJ<|_n@rf_Izxz!jqs6}sA z5V|$~6Qq|K<$cnbgUbaHS~PMx&I?EmW86i+INoCo>k7tifcZMe??|sTAD<1P4?Gu+ z*Iiw&2VsG(U_pfQK$}>XaXWoDMW-RTyA4nsUO`3x!-*y?#?2ni2?77%TY=Yc*258g zj1?ks%@4f-Mnr#5SCGpA-q({N)&ud&M9ohNFo(|q0CNyqfaIF>QnVxV_L^lPH;ruu zY3`VM^ZHu=^V+zSVk>KaInTlrY(-LYBgo(# zw=#z5=LyU=oo#kq?E&VO-CZtwxNf^TKqBtCn>E;GrfrSjxF>wj(D+!K9N>r^akrs%o3;k#psvsj&e9D}GYrq1z`R@g zwH}?nrq6 zfzmQrZ-nft1Ao79)b#4fCR)N=123X4cEd@aif*21` zVQ93MUQ=FZWqC$RTa$2nh9jTq92jX}@{-EncpNUSBp{a>Rn(nW&a2AnsZHtbO=Hi- zGZzBe)NaLNf%Qu+aU3mO!WljLi+bh|V6LZs&dS!z!rlU`if46n0OkHdbq=H^YL3T2Wa9A^In9Fq3Cv5g z2%6436AL6S0(WA%cWFA@lKa0f&rL^XW&5V(1f`c}DRMRMcHu>Yf@bXcbe14^_i_r8B}P<8#5@a`JJq4E;Qb<2JuLpa0spx74@*n znB1y9F-Y8G@kF~+MU%||*?LA7pePb0$l%a>Qv}MEW0HgIgeI8*&k1LIi7uV#8k(XC zN1FsAFraJz0enCX^sZz}D*D8L^lHAemN!x>P}B>@>cz@B$#|`Bv|?biT%ai7j1;qF zW!$mK{>duARINzWGPKw_wAe0PqRCeo%FVv1UB>uUk8-n`H&Mf%tm&U=8d{^ux55@u^3(4Io+X@n-^w62M^iOU6xkOszj&+vVpu=b<` zMs2o`UMB5MZDS`jbh`P7vBXKdrvza(;Ao}}51b43XFFQ4>`aB8b_4GATqpZ6Jb`U( z*Q%}4uB#_-wBgxV0_2C>?4%wJ6W%W4D1_M71cssD42Q|7$Wo83f4<*H8}iSm-4F^d zZz(2#;h*|=>#eu%zJ&G9OV7VtzWZ!u_jW6po`oZ}hlj~Re8>G!;HUu_&tZ_uc%Ky? z!Xgd}+W4xUk47iQdq6V`;s!ucv%iVjRvP8{8{LVHOW_aHweF4 zh8ZQ?vP3#U^vafxH#lBEx7qa7l%{RQd0qkZzJ`V$7;$n~6VBM3B*UB>t(!u6avbf3vvQs+ZLY3dS=+tO7@XOUj#Y z|H#@9B4WDU)MKO4=O0Jsogv^{8TLf5+h4LQTyh;C}wV`f6r*KXH2 z-=TXBbaJ}hInY&LB+4>4!_+&))OmxYdy1)hhNX9&t$z`$O;TH1(9;Bl7l7wN!?REj z(Ie2gxQ0fLTEfq1q_of-x73pxodL;Z(n4|3THy1+`udYFO1Wj(S7K?X0dXILvkR&O@@f zjh(HYks);EZ|LZ1U~cLX->D33pEgWm=_GcWfoz^d2Wz5vc00h_EUiK}I>$6V-y*iq zBBsDNG|M7X;Sjl4^5(k72Gk8+Ux)*+IU)Jg5NFO)A0EE={+CBz|3j+2)y|ozZ|sYYN{k5bPmRK-M50q7yr4ifhXSP~ zA@u(?=kX!-$IZD$X3=!!Bu#0qR2*lULqZF9TK->;BJi99Qb|#6aB*H}X%Ub-va&3j z)>+=iDWo$h+3YeFtBl2{;IQ*(^!zSn!@vkdHc1(oB9DwW4a=+eq6%Jr4PR8tA8r~@ zv<<2{hUYq^^T6|NsivSgr-(GeO@KL>H`>INH*!W;iiQ5^b^g>UV`R2RK1&%;H1^8? z=Cyq3iBw(&Be^HR=em0+^6f1*Y> z(>yd!m8wr*&YakR>K@(bP^?vPG$gMZm$xbpxaA@}&;N zGJ9^HyRbj7bZubqs$gzkx^_#pep_-JX~G&^5-whrZ5&KreKdRH$;|#+QROVdZkemb18y*>8{LsWg!os_o zBm54m|1Y7O=h2Rf7=XDOJT)`}&=Z*Zq1FR1@P0d#a4EtM-Y@%l!H0q!BK(}r0CRX< z1<#BpWcg~29KqEjK>DELcxi-dNdrccTCBMYN zp~K#VX<#U|f`Q{P%&j$U7D%;PcCuV|v4K>^E8xj-L0ocofhACoSzrJP+eu*Rh7+9N z$$_D*($WBomr@ITxUwyQ%`YnhiM1gNwS`vty{5Wty634n=XxxSf#)m}jV3)zN_-HS)vgDxb?BtxHqS8iM3q!~oTVRb$xcK3)VQx`*#O$V!_-bM)yQF|w zn|cCs&SC^-7eiUaHg1KtUp?iNr=^WLtz)kX7IVD|X68mVcGi&ge@<8Xb?u91jBT{^ z9g;gHFl9o+)E=Egnn@PJEW6txugff(3NnjHa;0u`zHv;UMQpKoRH11|mT_>(Mc*KR zxoLE`Q6#`T0JI4>J8c@^>Xzb*&I>^21-Zw07LZd)n-j{)LMn;^>Iz99o7d#}f?9rz z@&AQ6H0s$WFxR+QG^RvNPY$=_kfo`}(lpN#n8N@xHyx9eNyx|!NXbuZWOR;gu5Uj2 z0E}UyYxleQ=bKu%QK2!h!9f7?)JQa(90HhwLGc9U|LM%b?4UUZm>=^TG?rtS!^KXR zfgZyg5)>hHOH&$;;z{(DO&GyCq&PRKQnUJ)PNo(1h?)jfT=kW)Yj2NUxi4I~%$?up zn_q<<6-I&7kqN+f^YD1Xan%iuR`Q3Sss++|k-S+v23|qx;1uv2s#P+hsX-M*0=7W# zdrt$>d&ibJ6KlfRE#cfY*d(Ao@0(l!^GVmpEPPEFQ(VzISjm-E^A#F;izcdtnyMAe zG)ouBie<{^QvJ|eF;AY$8Z2aKNM6oULR${aIVden;#tb@JY{$h^cHyEESawp&({hU zss(d(qNSRF#Rkc0)6hC)WUF&*=gwz89DMYr2fz6NWFNo8oKJuF^~U>Ou*TPV##VT< zyZwuo2A1|jD_8hS`~53dnW`-i=i#S$cju4$F%a)N*M)KD7!P!}2B3T&+8uO-3RK zlgYtww5uIyOG7)hdpUHtI}ZnvI;^b8diw2#h5{!$j;#gH&Rpzb13XutoW{MK2A#}? z5a!cpjqVNZHHoo-*hn8@J;0VMcl8*9C{n|V$PKKLl?fzoCt z2fhc5&Pq)$0Knlv2^q_;#1qlmA5|Eh;Yprr;gJCD_LFbDjNZnDKk=R>LfHma? zB6>ny1?5TM7#o6zWomj-MN@NeGrg*V-^!Oavqfp;g|0rf@p+`g3jg>jl14LUG{68f zZD28;x11n42xMHwQZL1@-?R?rXleVtu8#zz1rC22ni*Kwnj4tvYa8kU%(V=xUNiHG zCXc%2aRKIf$=&+NofbLWmbqP~nXTsOWW)Fx-KbKds8X}&BGZT>qmXQapw#m|L8ei0 z#*v{$(Im6jKxlK%yIX4`EfLXZbdJAwF3BSiUEH2q+>%mO9#K&oTvHfWlTQL}|F<)T z=KNT1!B=Maz$6r^JOfvjj{VQl&@s%*(lkm-QHD2=JSQCoFi+3&OU#OFWVAD6Bc0M2 zzUuPg{&UXAMs+O%I`in@z|=^ev?%YiD6iB=&y&tvqnU@>L&b;M0?ZRbG|bb>ZO|qz&)@loufFllAAiZH@7B_D zSUG%l>7CCzv$f)>8qp-Y)`?Y3!wZelMfgd`Bg>u2 zbtw2^cm#k-584iEa%XV;a6o+ntTL*DcV})qpT7QV@|fh1X$&>F_jq*o&EfSsLiIJ? z>}BD?)$PZhUViebroH`wiQWYZQ>_cm*2rAh?hm6ke$>*>N~pY6)B7U7VYj+@GcBq$ zJGi{uH@4W-CELn~5$w&6Axd*1*fE4gAD0R*n;I{NUVl8r$*$Shh-_rUb9Dw~fMsLO zwKo?aEQj4~N0Ih0ErsFfn5WCQo7=FhgWTR_*xC`yZwg1}VHXtF$-C0Q|BJhy|L}(+ z<=QQVa(!Uol5+jV-j)0L0b$hyKcO#vl;AxJUU95980R4N@I*78Lwl|H;xzgR%so+V zuy?On@bQFOW1b6|390WAo-~goEc)OV@K|u6YZA9GE@~fF6<{1?3wgGhjB$|Sp(RGU z1I&TspxbN(`LFn5H7lY%7?_P}lyEO+7)q{rgMAT#W#F=>^EA?Z8iN7{rVL>NLxBlT z`*CP@-R-8m9OiM(3qFVml;srKb|)0K;)jHl(k=LgJ}{64wcHC-ojno(vb;9oC)eEL za|XiOE=7SrLrqp}9(IvV_DVD3MvPud_ zVP!UsEmpQ%3k$J{sm#KB5(IWTt64|55CqM+nP$_|*&OaTgM$SQ#%;kdWe=NWcgs~z zNKH3gbcV=uaN}6RYS8 zkBrRmjV%kS8*a~JG$pb4=|XiZdpTKr7|PoBrfh}v-VdtV(b9`}-N65}uFY9pQwWAO zhJ14iql?A{rwt6Wj2(=y(f)N(>ok^OO0RxWk6vQCbq?JsyW1qA!z{hcAhu2?s=^?; z9C&UNSz-{HqaU1pmKbUh6>k_GY!(}25ffw|7o?AO(Xzj2h_&=g!(nnrs8n1DEx(kK zR#q8RRvc1Q7*JghpwZ0#!}H_mXBHl2pin0;2X`Xy{69-W(441ZAfyFeK}FBYz~`hB zGSd7~(gNV}LRDvHZ4ZYgRnOmepFeTAoGNN=mT3%73e&aYDyjsnn^OiwPx7<85+cUYzn%NPr9*CE(0nhof+n{OmO=}8B4oKI) zoGpb0_~eg}rHjDx#-aI!W0;@t6G&b;Fjc}G1)hVt0(C-iKst;#>otSU$^R`4%o{|r zO_Ie%vARLBRMkIUBT@s>YeWm}%B|(Mz8F|JTzTtbN56P2UAwt!k9Hn^+C947Aeev= zDm;VW$F3JmRSJ~w(Evyeukd7P7@lvEse$C0SE>3K=Bpr{w-3*OF%lH}&XE;>xp?Ie z01hNSfjRITFs=fyUwb;b{ZP7bw}1XBd*(7Qe`x*A-h02^Wk!_a z5!r6$rARvl3D@rFLbfm?o0{<5-680YX=B-IYu@ia zA8$Z6FdV`XAtMXMl(3Qye1@iX36DI1IXFo`ErEjF&v^{k0s~k5f&u0WI3G}2PGCOg z?Yu;AgZLECSODgb5CvK{L^#5qT87LPg3q!qVLdot)!%oSh=Wa1O$;O26D~3X#zDh@ zU>TU(PIs;^1Uv`3rqbP3<&A&=tD5Md^fH$sj4nqIHUdy!j{%s& zkA1BFAlETom;Latbh!a8N(glao_iopU=B|rfH?@}5IH#GXbUjsxVX?m!^f$e8*5kL z(vS#-EQhgt`nEoRe7^fGHF{q>NY?Ky1RWxgNYZfjO8P<&OG; zw%Q^m9XZ-miZbp;8F4XY^Z=*M2rm)2Ak@#%&gL8`%D0kIUqRk!AY9xw=6aXNlpa(Mbkj!RB$Hma)M$(IgW;Pc7?n=Uw$YQ!v=v08FNz2Il09 z(yFM6(lCH|m8LWIJ%RZN!z(l466i6{kDGIlSu~yb@#+wC? z;Y!8-!aObr0rlVh{N%(lARSJE!lj{bUj!7u{Kgl5x%Bdzk-hsfx8I$+_u=&2_XHa^ z_-ofFiaF-O277s@cX^AmvP+*`?VMbujjwc0u6C(5YKNyv1@e5>PtuYPsOq$?C(5{!vH4QJa=CAZEUX$&CGMwckk z**c*H&Y-BYDV91%*QnBkpiC0@SM+OMf#mSfKvN^DP|dOxfO(r@rBx1p z1)(bF0j$eKZ3Jib#Ds%c0 zcj21!(nBca^+)|HyW|1RIg^VQ&5T~xanQQxCE56`>dhmEVD4!*dJ*rlWXAIx-n+p? zGXWVxeqr@~m{_a>E(V2(L%IuUi-dKhnK;)dXVYw?T}KeE4eQbBWY=bI!}0K7Ae_3a zt?4#aOwi8}wgMOXAy>qpvvZ%Bjo1|{aK`jF`!Kx%XqbR@ZxRI?*5Q{_hDrM1;M31O z{Kv@Rt=VhuUVi7d%eUU$-oH;PDkq0W4iGV8L~mHw2WZbB5nx1F!nnfz<{FFmq1!41ufu+3ve(Fi(U0W!6N`VXMp*PC!D2lgoJhoiUClA z6h8wQTtt5rDO42_F&CXQ6&9-uiBJZIjt2xz`US{5y`+u~YCImkGpIcio~}?T97^u) z0#;0kqn+FXG2!ht3N8^yu)({*zUK@c(RNk~V7?uU(Rfz~DDcc|V9=XbZ#c=Zi9@Y< zd%`Pd?+{A}JvoTvnu4Am+H%b~X&X2*G3eq1FmLw_l-H5xrq>md>+Sr}p1~=$SXp0G zT@V;vU|~6D1{nl2jpLc41w>r(jL*}xUxWE3*V2%0ZOk;)r=C53T;MPc}cMW6}jh?Fp5BEcgHNgm_I zkZa?*c*(rQF!~(8Jd%IIr{fZdevl)1W$M@cnkihYK%UWc&^9pEH#Rb}H9Kc)c*ey1 z4LhV~aqS)>Kt+`5h307oWuEno zGK)^t4+*hJh_Z?cvyKX|2*$o0Nw#-U7P=qZjAb(;~v`=z0Ha!NL9_yVJgG`S_CC7LrM7qUC zxF$uq#f3P>2Rp-SY_LmAsB2sZlyh_lA|}WwDgY*-pt`s~Mf;12mpL_~1mt4Lh+&OGju5eeci+1inqds(81Dl7O#r+eQSBMk^97zhS za0=vAB4v$4S;`-ZZRrTDX^yCCi>&JktEMGUdHF0^VV}H0Fi9QV=$_eQP4CkuwrL7A z3_4*Us1D|y;t9}U$U_?7H-NMonzd$M^DTPrkeS{2Nf(Tf{T1vL%2yI3A$@<0p@p7MZ$jY`tB% z0e>|`zNVqNY>7IuM3F53$y-O}VI&F?I#+#7ym?2u^Kjz&vnh~S4&PVbeFddDcyIdp z^P%;-yt%7=)0YKHx5Vprq`Pmz*Mm;gs+j2*mT2jmxnOLhb-`Lo+l#AuF?su!(Befc z%bLv2M{zw*viR?#^QH-TW8RUiINvO!dx)PKHo(=ZtuR;I-jYV}jBv4nK}1#O?8tI+WwjlglPrd6Gs( zPa%a~Kuz{ezPj?(;f;?sZ+)`y;0x#|`sXf9EpCgb9n|P30l`~#ybS~}hp?|zIQM{Y z))>VJ9_xT~f|tfjh}SF)fer(y=HPN!0%-;3vrP0;;|Q?V4{Jn_k+?!YPr@lTybCmk z^GG|5n+4+ry0;38nep+N4hm65rA($2jAd1blJYq*X~M)DVPvu}C~7i1y2sLH*aJC@ z$E)zzQ8x$Z#-}kJQdbA?Ve)M)!HPNN?WzFr9PcrM_ge77%n^}o=U&?i#RJcmaj+-^ zb5(B;;kR%YI7kO3^Hnr-<}j{BEV?1)T^yn2oZ*lt03Z5d`Z~P^dMtfiwt;@1z8-*`XQazF*6BCZhDQMK`~>L& zqw`QFYzK^=$S-W&Q{!$n0y7=hHGrd35TwJ=*B`X9g4?O^IS8`arafJx4pswZ`o||_ zO~K15butuKX^R~66i7?4hY1^P){Qo64|brZ;JT|5LJ9V0cMA+2PPk_l)RG&z*bp~e z+r>c#hM@iNp-GY6kpx^ki7XfRmlr1X2;*6*(9Rjq%mL;^`W~TkFL(G8V&Q@Xrumd1 z@wA?swt)%2+}zImyt&C4bIWs1cx+aaQ#Rvb1lcf!sS{5JgCdCM;5oO>>Bp zlM4zPGKSza1ERLCt6Awz#KaB|J(z`0pyPZ6*cEUVNtX)7d(o< zb8KNI20HWn3}SX>Kt@(bNK$BCOH-E&rh&t0P3*X`uGk`KTvk;|Ms{dOKw^wfa*R(# zf=_BJHaP~B5{piV@`{gg*HnaCT)2CDs9SW1OH7D+bf{-+s8?K=XH1w!bg)}gkZW{+ zTNKGX(%&tbs*aH3u@Lsl+QCzfiYs(Sfi*ZdX9m3PFK z-j-f{N4RsJvv$B(+^38!R*FYU1+wI>-q_aexK>skN19CIC(<|xo$S~)R!l21qKO{X z)E!vc9@*RzOYKeV5~b561%2`op0aX4<3-7%a}%4|pfcN;S)F}l>=77ZHc8hThS%zc zR>3{Un7-0GyWcyv*QNlmMODU@7PE#+dPmB*%3`*XI=Vxfy24$$&0D#}T|NYzzf-x| zD4K>Yohn^wA6f5^Z_wl$C$C+K&ErL(4a(3eMY;z1Idth@V!Zn5o2i>`@t1eZeZ$SL z;mZ$R3e;CiStIm`E!x;R$n_d|M>q|i6dH#Xpa~~K6F#=tKEB;Cu>)^TU=AM*nxu0S z*&J(jo4^HXzM&~CDbdR{+rzm%z_;1kv&qT6)6JFX>B;i) zYIk(3H#cswGV4ItcRSg!-CX;C!>bOh0?Hqo%ttrmpYUkMFjS(=NTt+yjVw?~11qlw&AN>zk#U^zN=;(Qh5b(7L5)y&4= z(d#e? zW$C`b(K`+EP%g|v_0PZ?jdxM!jR6Y-uCX>l_X5Yv5SE3RhC2OLrb0Ld>WA$$xd=wq zej5{>l@Y9)L2!i7USH~I+3#r7Vf2OsX(RHoW}>WUSliYxPij22wIrJ8VTnRm;c%Gv zl=Q5MMj&}^Lw8nfr%!aMZ+K)_QUWnHFeo#!ltsp5B&PKWf~ZmwMH#`q8YjFL#5(Zn zzM3R>meuztqY7*?S=s1WJD#^hm|W)&(Y2!*pgA{)uGNbu*AFc<49hhP%R1!~aDfzJ5gTil66cf_{ z1{UW8l;ww36-UBrX?{3VNnTh{PDoxxKyF4*US?=cW>`jQSW-$D+$ko;#bh>7$zo-6 zRcAn9i+wfeTB{4o^&m>v7R>!3jyBvGGBH!C3zQv~K{C6zF|Yp`kt@VZ_jI zUq3%gV4zP#cu;VNZ+JuiyoQC7;5YqAJ_I5b%7=)>`C`3&(1bujDr+ER-Y zu|!a*Jp)AoWu0t^GO^RBSfxyCG(aycn=cV5vw8;-JDJJdoalCXIHfC*#>?Z%bJ!zU z99afuD7{yb#uCSMawDlMQeA6kV`oSMEr!a8YvUz#2vTUm)NVm4jh#U0j;(KvsiVd> zwkNf82R#45y85b&YKw*KVtHohn-go>y|GyC-%( z{^ybU{!`x4HZndlzPjz>e;kcpc~ssv%9+2~HL(eOIE({;=OEex$u;9n#R^rq**d<} zHn9z#GT?WP4K3!t z0kq=qX@a|WC|J5TeCcWb`opg2{noMV_K6KLc=9KwwT$$D=NHYK&YPnXE9I<(&*@8l z(lX9N#*f6ao+tOe#5Y`V&0lbc<$1@nx)5^g?J!POZV?!t=G+2$VSW}4Q{s(k_xEc; zdNv`PIz8MND0D9x(~58^H!-L*H>5b*bh#`fxY^P+`ArhHYke5oljw<9ibBq(^CKmdJXBfu9D0AQY| zxtD>m(f5Y2cq~;&VOW$|OQX z#3@OBL$S#tc~yHOOOukNVZki5V~Ea~m|efSv~^!7nr&|AZ7FT-DQNCaDQEh|aPWbn zK7<(}VFK+ng~te;9l*WAakP-*TqN#xO1#$?)_WX}U5W@6!tBymdnL>d#;UPB8?DI&$Bgv2Kjq65RS;xbz+3E3$bz5KuyaZu}c6lX6^a2U|D=ij{-!+wxA z@FbUcQ_CPg>mu@$p2ImqTO%769V?f!=5BWWnL%Y7fVoL5%^<$VFo|W7&M`@2nxxR3 zig=b8U3$@VMzQt!k(GL3rMkhzxOSd0xByfJijoev?M7nH#!|I zDrAHuB?l)a1w}>s#lo$#^hiK=R17I3+&3&TAS^m0A~rHKE;2YN-a9%mxv{f^IZP^| z5b|0aLUYWC38!q)*vNEZObRYEln@p|iV7o!1wmm0{k(kf*dTvQAPME?;}aZ23=Ip8 zjRTkAvX2q=@A7*o>Ua@~Y6}wCJqdh%QbPofq5FA5R}h zVu;e&!?}Xdf&pcra3ZgNG>bDF*})2L?G9?8`PH`)Ybp5JWX)yItd#IuyHYquU+IUHar6{7%o*K6B=3-|S7s)U{UG zR{O~IwGY0LtnT-zmW#UCu-5d>AAS@r9aOR>dS|cpsP@~GTa?jNDC*c6d2|(us$3_J zuEV3Peq^~;sy7_q~KAx@^taR=PQrC+)omAZwpqg za_09=G#~iE`W9|+=5KdTU#BW|TjX0UBb)G7G(lka%z}=SgO-lAo;Bj4xhEo^CZ}gt zara2eqDafUG@0=vmG?my?U6_EnoXh*nb74P0`3VPQzKhXbL%Wp$WSA>J|eP;K&bOZ zH+Xq9dAPTtPz(Z*N%U=WcgeRj&a*VAcCu`AwQF}nw0pWWyLr{)g8DK_3scH6v+5J_ zTB9;4@x`pPI!S|ItwFGo-XyAKO;dy`67^v-dtznlR#rfCt$)~PV6@6NblE3h%{Neu z#c9G=ykH|91=0#^&4YLXGfB4OR%Zx&9%X%ZBX$4EzlcMA6w4DfV8KF6cTF^KL6^rj2#4C2VXtiV<#N zCs(<<`;fiefTj7co!y87V${iH4B;xZb&%S_>K1};W-7L`g-AxZm-{5nTZuuzPEebU zcDuH2kC92Iz5&<431X0E0)xb!9z9l;t%e2-7tT|R3@Ao=6chbs6P*?leX_Z6i9HvFUL2vnHjKoLWvxEb9nNt0uCm(?SXg z37L5zRa8uI2dcOSQz?p~Erhhq22fO_mWA*(b!?~lv_p)Rh3`3A9|ISXzN7C&2j4UH zM32N;Y<{w}MwQzmv-m8K22Nj$NFof{b zmwLum*{WUD&1ZK$|L*n|-#_{D&yT+S*Wu@XnZ5lUXW>%c+zxAEovvJhw7_Dfq_S_M zpi@%Lgg`1trcyz2AS^}l=B_X&w&4wTc0Y*1(iFKbypr}Pe{vLz{f;%Hi5 zRA+B!J0pNh^KI(%sc-YC>m)RF`?fFx+c?1;yqKQB2%0deTO8KG4QXQsz_6pK3tJ6e z))mm)7uhC=>lsR7NRyaDCzaYaoWztQG6%vajBpA)sID!rwl#{}3*CEChY%{YOOnzx zkkHPHYi35*cPCJo$y9cBw=lI`5Krc%c8JnxLzxUId|6Jfth9f$d_Y;yH<&{o(5y&O zSgEc2?2e(_?vbLt@nZG_RHb0HlrvtI|hW^TS1*?!2K+lBw9AUXz|HqF9Wn8t$Xy^=py z&YcC5WI1mRK8Y0dflp?(S~SC)S+&OdzNT+vVCQkx+(X|r1)IiI-uVR?Bi1r146EEv zroWTI{=l!{hE1Z_E0N^|N((C9(8$f+*wNn&-&;*-PR%b32rno2m0^5pF!%<%PiH_- zn}0wJhLDT!$hLRRwRJ3XaH?=}FLQ7&bHSFN!|K9wvJxs%QfeZSYC{w10+Jj3)5+AK zO?c!LGsZI-g?ZHBlp2nmPohw!&I(H^4~${^MGg5zO%lS#v4Jx_!Lz=BN^hSDEMc1H zKOY=CP4t~25a$D+d-s)l<5hlv;~2t>F9}Gi3hvNk}3vr$oZiKMAtA^*HDCKv>P@NO-jcErh5lxpaRoU%i6=ztBFzhsfE<= zq%tl?ajax6FS6d*yPp(EM-w}cs74nA*~_)l8`F*?Fmb^QY`{=tf+9XG_Vsg# zr!LCElLW*_2>~XmvGSnk0dK!yVu%DED8UEydl5z6ff8&m+l|O@!fHmtZoW{RF8CHl zbftrLIl`w18%s{FfB(gw=eHiD*Ry?+YXac86P_0to*U*K5aU8fv-ixjaLBiIF0=P4 zw()HC^sjcpwz&Jz@geO)iclCtI!iw;O3R*>S@(K*H59xB-TqP=dx4!GB0tVu4?9NmxQgKwK<7 zJS8G6B_=yQF)t;nBCVt`siYydo|aKh%WvakxAF?RM3E(JNwtjhW=<7rw5nGjRNvsL z_M|%xI!4z8>v!kg`b=`=as9|@K6|o3u~o=d<@QZep!=G=KD_sM=+c{A6YG5S)#32Uq|Hr@iE0+}ecfR=L=!;*E zzWnv*(eJ-kKYSOmur59SeE#*GJo9lW#q$2(vC{oZf>`PT3Leemhu zZhZ9p(%WCoKm7FSr$0RW_Ltkg`Jclte%O8Q_mBVl>$C5Fz5dCc*B^hWyz)%E@o;eK z;r!i~>IWas-udwA%RhhmnB2;b zZ{|idu%laeQBC}~R#6OPAgrN}RM`d*VG;FoX!7Hld*SPoDcty`zGO;&ddFZ!*Ki(d zG_75d(><8akQOner7U?)yCk_$kl7-B{QFU;8Q?~h%7fBgFUs>4?h zt2=i2$=Kz$!Lif7aJ`13g#Vrk>5>wrEWc~8xJRB&73Flv3Yp{ijPU~IL~5Hjkt`@; zfnk0M9@D6ZWGy|jbCzze8@p+lgnBYIimSyp73R0^S(_y-#((% zDX7)~m855kF*b1Va3GXrR@G!z=Y%At;YjJ;M7UyBiYL|i1vdmnW_$Xky5f=$s8ob! zl8sZMrBjl%YpkVLl4ocNJ~2Er*Dp9bAg&@fxi&h#H6(|ULlHL#7E0;L^af#EDGQfa zV~UC^Z0M~mZ7Ge-CX-@W0r7q4;679!%gb-bKT;MF*G~))ks^jdqs0N?{lp-le<+U- z%)^K9aUsJ&F$2UWPCcD1TV1)lSHO?U z<0a(LLlSx;Q<;&ez0sL{FXGC5VA)$tpRvVgMOv-L6 z>h5Y3@}%q4ozgstD62(~(ZEY8>c}dgB`1~_XVq7xRhGpTltpG21f*6)#3==Z8;5H#VyP#8m)v% zFYlxlv{3S!o3h|!OI>+lMRR&xTTTQK0ZYyfZkIIEAjLNG? zuc*qXs7x;}O(-mh%`J(~t4b{^j>|8I&ZH!{S?8YYF_THB!*oDmL8PE2p{ zWwSilyl`rbKeZ-axUAT|vvBj>p|!)|&D+Yow_(*{_U3z=k3T#3=-V5w{s=oA55M{G z;FG^z{pgQZKl<~7Z+>~}4@Y-@^UrtxarEqON8Hte;r+Kh`uXVPk4NwQ@axAvAAR)C zqxZl68G!cXPe-bQ57ZAod-%tnp8oyl&HwrJ&bR+~_3P2cP(L4i`s1%BpnLoG|NQu; zqnH0YdiAfP=Rf@W{_noqc<+90p0{O}WeC7}D0ACLCl{cQE&yPy2? z=imNv1O=3S^|xO>{GWe)`QtIAe?9v8nAo5G{okMec=Yx+-+>JK)h|bnzWU2=e?I!{ zPe)(>eDu42AASAH(Kp9m34dzw_Tvx!`qM{$|MlhH{tX}V4?p_z-OvB_&bR-5|GT3P z|8_KU_}=i&!*<06Z|OQ?Y70K9LzWb5(|~JYXzSj@m3Jg7_r)uB<__N9di>@7d%wT; z`S*{0_pcBB=hwTRe*5aXpWvwhf6-_EIC}BdUv7T*=gZH&rikV{!QC;eu4IhlQ3b`F zlGHjzN*&EIuE-{_)H1FFkx}E2QH#iK@GPM~x#ZW{Wmi~dltK!bUPP8%MwMfBtyNO7 zM^OW`@x~4<%pyTbS?#%)k-L12G?`q+qmJ4JwX+;&}s(0km{Y)h|6w{tfl!Ew)hpa zcqUicN9E&ln*0i>p%tAG)!o4P5`cN9IHH1@(9pg4^s}+653)K~@ii?uZ9T=^Jc#y! zuw2H>HVjo^&$L#e0vV@mY?G?oZc%KM^-obop&{Sot=<)FzCF18OmXGI(W@`vy=d!! zeD7^oK>{NU2sM?x%8I_p^4_WP-U$%u>-tq-ttsmp&F>y6V#o`7M$%fvRQYDTSPd92 z>6^;wlIM0SD!G$kg-wnD@qt-&(WPB66#`N|r(yUow|Cbwofq4%&Q}FYHArx4Sh{@y{#<*O0y^{r@5l4 zn@r(RTevL^>^7>PqNcZ^aiFPtqPcIblqLr*rPQ#Zira`ORhZb)+-81mlOVmGpVKVK zCCjo}hFKF=X#)!a+2+{bx|}~d!JnJypPL<;A7;wM-NQ1@=$K%7TCzOKpIsQ)+*Vy* zQC?n_?_5$H2->BSBDG4o2Cs6iN-3Bh8<KXjLp&Pz-L$B%3nDHHqT7 zSaoM;RS?#SfM!up;4gZFl>KAv4UoLM@Yn!h*wG8`p!q+zxe9M zhwuGy`|#D`-m`_hXRs=`d-v0;Z+-Rn9CA9u%N{Wcz{Q(gQW*|6F@|`m}@4VQ3^zP1^?_GZT z)#kkqHtxQ^`QYW!;nSg|D_z606T5du)@}|hURU3I_W!Z<9Z+qZ+15_tLhrrz-m3~# zLLiVpU8thog%FYuz4u-X28@kuifs(I_uhMp?Icd`Wzr@ylgZ@eAO8nu-dk_|>tAcH zyRIa3udvbn&N<&XdoN$SzkT)0^3?|`H=pdiaC`0c^XbEvNB5tGH%=Zp^(U6j-_bS? z`oy8$aCY}eNX(|utNMoLk6+k-@jgsA&Y!rwdi6P+q~h5*G%;0K1)}03`ww-UxG{3+ z(ct-q1LqzX_MFhqA8%T_+IjL;-Ri~0!&jP*UTavt+OU4Tdih-S{xf}NZ{PXXt1CbK zvH1396PF$jow+}I{l&R2em(v9-!6Xpd*AW9eWxCdoPB%p@_R>K{(Sz+|Jr`$Ngp(p zuUwqE_-O9tyMyQM4PAINeDP`P+Ku+rn?q;c8NKkbe&6}J`C~iI-<>#nZSBQJM?U!e zz_Tw_UVL@*gYOsbebja6Qtj@e1IMldT9?mP&mHeSa{Iue&z}DF3YO`MpZ#*>i+?WP z{c!f;la>1)!@7L;yMNvK`qxXJ{B-%#pHIB_`s53!V80LglefP9`{75QpLq7wd;i*4 zngNe~_zf}_So%Nu{ok-O1K$7V#>#%{oBz7~{qN5pUHakQmp=Q)%A>CjKl}djm;Z$2 z{^8GmoPGJz!MmT2pLnwG#;2=~{xWsu*+%O0=`WKf?m$OP``+Wtv&VqgN7wHyUi0OLN=aQ)gfP6-w(6(oYymaTpK-j z8;&j0r#oiP4li7qS-Z9Uz?FT+9_&1Hb8_M0+{(>ehi*+QoSQ#9# z_U-)_Uo2htVD|XaJ?G!sb>_wB>J9kP3G0XQMW$#RGmEZ*QYT5)KvTA}^&^6ssbf!m zIDG4?b_JbL&0!w-Hq`TXzaUjB3W=I8M5GkfmYp~v5?J^lX3v+oYv z|K!AzuZNZ|)Q|2jDXYpPN=od@BZ!5v!9mEy}0=7 zFV|oG_3Y!X&p-Y8$gPj}o_)G{^}}PgzubTBz5Qq2UOxTwz?sLFpMG=c?e92t;o^%QAAIra+u!{G_~h4DAOGXk%fG+6@zLK;Jo@hJlb;`c_3sydef8w~SC78i z2pZw91v1~~|9JKA2cWVa4%~PjcD)Z=dwKZYC$M7zBXYOD_yydo4&8jd`^?>uC+~lH`r(&zC+~wIMBl=Nww<8Zc4=z;&f4`4KKaM1 z4}W=e`@+p-0x6iastuJ4Ey!ZUQlaD_Jx>!E{Xg@T;o`3uDv+tjL z{qLS#C)%giph~dg=(Rc+!S0)xT)hBc-oCSUkKTIs+{2I8t~@>W@WV%+{q^w|KdoH4 zd;He(yB~e~?svaldh+4bXP-Ry=$n_{{O#L+zIyrX&!=xZY#E&Fo7&ybF+4iGbmPg# zXKuXx?6V&}{rm49{q?tdAN}z3n_s{DVcfxUfoX;)P$!~eBLEb z-r2=#FTS|;;>*XM|23P!-|7~cf@1_E=DLQZWt8w7f)Wx7sM3Zmp|Mq2-EQjQvp0spJ9hiQ`qkTOS8nY;dmV)7W>(J4AGxys+})Yg^B|R6 z)iVj7_Rxh#yANNTKX&!d<$G&a?+q^<>YCfPe)Hkl^+)jP_|oy7nWcu|$-cRLlLrp( zI()WocCo5!sGzj8L@X?CZK)d?9@)1%zPLWKb_N#Z&Z$L)q6&Vae5Sg8AO89NAFm*D0YK3S01Wx$uYasR{&?lVdk5}3J9Ph@mHTfWd-DFp559W)=ii{3 z1jjpH|8nA;&yPL(eBt)HJ1;zhe(YwLf;@N$k|4O+`@g?}iW6|`$+tg0{OHsBfB8Sx zKmW(AuYQBC3?xU8_55!@!Rq#>Uw-i0zuy1nZ;5`Z`I0x8MBi$LpW|^uh0tzWs6J-n&O1y!-N(Kj821vwyvM_vb(EefIOA+b<5> zd~xXZhieZ$-g*AssTbdz`{1XQd!H@e`snzxPvMPFyn>|Z?zjI3GQ=BS{(Irt$NO%4 zbnT13oqXr3Q}2EYSsr};cmJ`mK&;*UK+|Ayt` z(NF(|p7WWL51~!5WAFKy(@&SKd~o%{UpBJEf4#c#$zQL1^2>>5-<*5@XGj>I{QTG;|eP=SC6 z)4s*Cr=NUz?&%jN?tkzSvd;Ivoj!7B=J*5X8(+Ho&Vifn!f?~T%B7C^ll{vVhE^|u z3Qg(6Q^p=*rdJU1u7{AtgUC zu;+Xiv_a0F>tDRA@7rhS-mCB0RX@JE@!q~gWB1Cp?3%x zK{tkQ`{!Hdj*hKfR=18Dd#1JRqt#<`v!||Vd&WUU8K|Rnbj3WhU(q}ZVIfT2!cVT< zc{zLX4%ojAET8Y)bEbdaxrsy94_$o;Jpb{puipRVm9%jjin=UgPvg`YOzA%P%kLZ1 zcm6T>pUN9XyLO-0dHnv;#TN&!zC8EryZJK@Y6j;OO+(zOE>=}L$iYFf+_`WX=6M@- ztiqfEkQm%_<@&p4pMAN0^BIWnoO$%Y7r(vw>R+$E`t8-1|9tf|R1&`Y+tRuFW6P)O zNA}c?FO+xhkks{=2Y2`GI*Cdw*W!x4D*2!vZCA_2#W&Y}4x zVO_%0!cq8GEV*TT4@po#Dy!_DTAkQ;I<0^kg(UjMW+vv6hjt&h|G~EhPTs8R-KnV? zrU|ODi2{zS+SD@AH@VcieP3l`zp1sab8NPIe7Cx~rM`2xdvvzCwVx|3&nGcG0>dH_ z({Lq>rq1E=Z*dm=$*U;X-V{GUCL#MAFIC1UJ>6_Zx-Yg=Ut2Ldt_2iwe z|9<=3uNP0;Sik)A>8F2x{PC~1-~H+K%b!o&eDU<-pWplTUk^Y0`Rtt!mXF_9f`ukV+zBNnSRM>zKKaeY3XPZnX9i9SJxQ22lkyj zzhmVnqL7BA@R|oFn}#RV)s5P^Mrma=OQtJgira^0;nzvc#=l|Z=ou0fl9(QmijF~{ zqfn?E8l^-e7@V7%T3%j0aXK_1B`p_M*V)_LGu$~msx+DST2)0;{q}`D9b;qly}iwY zBfXP5N9LBs=axrj7i&6)wB{B9OT<-H3N+Or2^khnKDJ -+~jom_3a{V)_JOQEZ1 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⁢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

nrtl?8+@dwXXHE9m(q^scW1Xq}uKXci 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

  • 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 >rm6zr>G&F7- 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

    S%@T9fL`##s{Y&r!T9VX;t&Dz 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 N&(J^tkB>d~{{!lA76;744:FY`YRT^kupz~kpzƷǶŻ»¼ƶŷúĹ¼TM>720--/15789::999=HRRNKMVisz}y\R`ry|»ýúû¹ĸĹĸǷûďWNT<2*$!"%),03689:;<<>ABA@>>BUkrV7--1569Diziccagy¼¾ºûźº»¼S"Z8%$$%&'*,0479:;;<==;:75540)1H^k`%&,.,***,?=<;::9741/.-+()1>>2#($=rz|xb`^[TONIKaw¹û¼¹¹¹ºc+&#*057:;=??=:6310/+)&%$#!# #((Abg[SXTJBIPPKFEFFJT[`kº¸ú¹ù»»|,!(/577777641-)&#! $'$$7>;8<97AFO`w¸(#*-,)&$$$#!!%((%" "&&'(*-.0//./0379:;;:9756>NküJ '*($ $(++($"!!"#$%&&&'(),.134554226==42xƿþƼ&"&$ #'+--)$!$&),0368::8669<91>[¿ľW"!!!&*./-(! $'+/25789:;<=;78@gȿ¾¾ƻ~K,#&%"#)-00-%!$(+.02357:;9441K{}z}uskedffb^]WPKHHGD@;986I' $/:?:1)" %+/0.)  #&(*,.146752.6?@2310+)-,''+'!&"#& #"$),*)+1.+*++)(7:::ųQ%#-7>>80)#"(,..* -  !"$'*.1332052* "$%!#)' $$(/-0-)((&!!%*)(+010,'(*+K"$)*)'%#!#(++' - - - - "&+/00.-($*%#'$(38044IDGP[cjsõO.   - -   -   - #'))&@q˸ø{(   - -  -   -   #''",NwʮV  - -  - - - - - - - -   -  #&"&4`ɲ; -  -  - - - - - - -   !!(AǸ\( - - -  - -  -  /dŸ5 - -  -  - -  - "Cŷ|  -   -  - (ZøD  - -   - -  ">h}  - -  !"! !!"!   ?_K  -  -"$#""#%()$ !(-,("  -  - - +Gp!   &'%#$&*/2*! !!"!!! ! !!""###$'/9>?<6-"  -  -   !5j;$ - !*($$&).49/$ "###"""""""""##$$%%&&'()*,19AGKMLI@4(       '?lL/) -  %+'%%(,16:0' #$%%%$$"#"""#$$%&'()*,,.04:@GMQSUURLC90& -  %%#Fz|vt[(,'   - -&+'%&).267/' #&'''&%$$####$%%'()*,.147CHMQVZ\^__^\WPJF?5)!   #+*0{H'61$   &)'&)-1562%! $+/+))'&%$##$$')+-.049?DHMRX\`cddedca[UPLH>/& -    - )"tyu~o NK0!    $(&'*/3995 "(34+))''%$##$&)-/138@HNQTX]bfijjjihge`[VSOE4)!    - - ' ZbU3FFo}+&fH) "&&(,16??=#-?:(()('%$##%(+048EGJ1! -GOL'((&').3:BJOTY]`cfiklqy~nkoaTI>70( - -  )+),8D8BDwWLx1(920'#")08?CGG3! (@JNK-,+(&(,4BFC2('?[VQK8540,)+1:BIPV\_cgjnszlvoROOG=5.%  $&$',4(ziº´F8H<2-*#&.6=@C=4;72017>FNUZ_dgkq{nvjMQTL@71) -  !2=öĺ?MD543.#$-5<>?=E^isnc]WOKGEB>:5227ANX^bcjwspeNTXNB:5-#  -  G<¾.QC69;0"$,6<@BK]ptqida^YTPNLJHC=505AKPWbvzibQWYO@<92( - -  +]?̼|>R79?@. ! "%-7@FP_ioomkigda^[ZXXWVWTOMRW^k|h`VYYL>=<6.%  -   8WBŹ>K3>D=&&)(&%)0:DM[hmqrppomjhfdb```accejs}naZ\WF:@>:3+" -  "3RD?D5>@1 #031/.07AKVclpstutsrpomljihjmrvy~wd^^U>7DB=81)   -IA|D=696#  -9:888;AKU^gmrvwxxwwutsrqpqtx}~ia`S68JFB>80%  -  )?>zE920) - - (7@@@CHMSZaglquy{|||zzyxxxxz}nfaR3>PLHGA6+   (:@w<6+*  - - !'4BHJLS\dinqsvx|~~~~~ukcQ6JYUMPN@1  -  %9Bxs/3&# - - - $)5CNSWZajrx{}~tiR9WebRVXK8# -  6@|hu~w'/! -   ).5GRZ^afmt{t[=`opXZ_UB( - 4=Vl~&) - -8>K[`dhkqymB_tz]\d[K,  - 2;Vo{}(& -  1HT\hjhkrxQX{b[icV0  .2sqov)% - Ngpopoqv}hGvuXjj_6 - - !6$ - %;DR¹yqn," - 6s|~qV`rlurH-   - - &;LVøwpp4$ -  GzqYutputQ8    - '?Wĸ|sr?+ - UzqikooTB'   -  ,C\xsK5 - - !^kfifUG0   !,BZPtZ=  -)eqpgWM:$  -  )?X}o`woE& -  ;dxpmiiimrzueWG1 - &=UsXwX3 -  ->c~sqqojggcRJE@==AIVjx~n_P='  - "3Q`og{lI% -  ?huib_\VMGDB>962126;CUgtvt{tnhaZW_mvy}z~ufZJ6 $COEV|s^8  >n~nc]ZYVPIB>:5/+)()-4>IXcidzuneYOHBB=;>ACM\hov|{maUB) "1M+~Z~smQ0 9753211247?CPmy|xqmhR1 -  - )5#{ğLh@% -4~yokjijklnqv}rdUF90-/4:AGR[nxvh[LB:3.,)%##$'+059<>@AA@DXjvwsqn]@ - -  -%-+twtA/!  -0}~pkiklnmnpnikmoq|zqaJ1)*/6>ISjy{naRE;510.,)),-15:>>>@ADECBM[ltttqcL    -"5#TiN2,(  !rqhilopokffaUMBAPWTT[\M<2//3?H[|tgYH=40/* &,--/48:;?ADFFELXepturdS& -  - &! d21D9 - h~~W]ovtpjbVM<8SroWONIB=73:BLtm]M=3*&%$15==832215;@DGIHMXcmsvsfV)   ƺw.-YZ5 QwrG{rlbT<7GjyfUQNMKJHE>;?EddO>1')=MUboqneWM?69?DHJKOZakruujV-   - '#jw+'ZoP4pt{kQ6~mh_C5PvhB0(")AJHJKLKC?EW~|X>1+*,;Yuxd__ailhcXG@BGJMNSZ`jsuxqV- -  fa-'Hi^7#+&NfmV`4zmfU;HkdB.%%0P?" QUFMORTODLNvpJ3.,1>Zpn^RH?<>IWcniQA=DLOQV\]jtuywX+  - QſL4/5O[Q:,!97*8DVT6zmdWCNTC?N@&() nmGKSY\]RSTle>457K[e^NJL:##"!+?TZWI:GPTcnb_k|wxg- &6Ưzb]gqwngc`Qy;bg}xsqrv~pdfmx:945GUUZ[TNRA7Dk{bSU`s2'!";kN25!yɿ~;Us}]qo;!7=FNN@)Votd\YVZhpt{ƿ}~~|zvspljfo|N}mQEaypkmqrw~þ~}|zwtqnkjbvV -0]17D[ntzutprz~|{yuqnljj]{% n¹}c)+  9Myyqqv~y||ywsolkieWr{{] `|[;4 &itst{~m^jy`V`nwy~{xupljjg^T`pzS(-G+btsqv}fO8.+/GeqtxupqhF+#%0DWmq}ytpkeflncfliQ8!,VqNQawFCTW^`KO6O$FuptyiI:2-)1ESX\ZYXM0"!%.ATku|wrmhcgrpOG>&3½@Oew{FHKBZXfq&2(ursw}wSA9632;CGGGGE>1.129I[o|ztojfckud'"_ýHZrbZJ7&8mb(#zuwvw{lWKJHA===;;;;;EKPU\hw{uokhhgr|( -r³IJŽđ9;Xnz](!*;[k(+ Wt|}yy|{qi^RE>988x}~{y{vk]MC=:SotxN A~~{wsoljhkpurk '@3;ovĺoKL^\cimwytQFD:EV]_YO #~|xwx{{|zvuvx~~{xtqnkiijpssj 3T/@wĹ|QObcgjkwumUQP9BJKF1i{}~ynggkswwvtsqpqstu~zulfeedeee_]YTTV^jw|}|zxurolkiijnprT .WN{Ĺ`Xfkkkk{moG6:H?-  Px|}~}}~yqdULGGNTX[]_`acdbahqqka\TQRQRQOJA?=;>BIVhrvwvtrpmkjiiilnm3 Hu¾ĺjcnqmkiz~t409E0  8wzy||||}}~~}ysj^PC<536;BHMOQRRNHDHMMLIMKJHEC@;4-,.169=IZgnqrqomkjihhgknk  )ztfmyûjivqigfr|]13E:   -!tyyuzzzyzzzywrld\TOOMJOXadaYROOOKBA?;==?EKNOSUTWTYbkpja[\agkmmlkjihhhejkcĵ[>>CIMF@P¾xdl|necdm~uR?GO* guwpvxwwvvutrpmlkkpy~~}|}|}zscZPEIP_nyzy}}xrnt~}tnhefhjjjiihghfbheI  -FkM44:?DDGUmmwÿ¿_go}kaadm|srxWYh> - Bstkrvutsrrqpppty~}xohffhhhhgggge_hj  - -Lw~t`I2-/13=RkxaJ¿Xipxg_afq~tqrcfg#  ,eniossrqponmnov~|}|sifffgggffffd^cZ 5TWdz{oh\T;)'-?jpWþ¼adkmc]bex|rlkhgV  -Ndfmqqpommlkknv|yyz|}|tkfeeefeeeefc^[?*C@BS`kmk{¾|sYA6CHIDBIT[[_g~dzpYMUWcsunjimqpnkf_^ab^Z^e^N  - - - - 8L]flkkjjhhhlt}xqkiloswyyyvw{~{||{xqib^]_aejnqsuuqkfeeedbaa_YO6  CGGDCGMNJKOXdřêoZMZgzqaeiggffffedca]XV\f^= - - - ->Q`hhiiihhils|wlbYSRV]diihkruspic]UMHINU\bhmprssqkheeedb_`[QC# ;G=>BEEDCEJMLNUZXaoyqmq|ŶoWQfz~i\`fgda_`bba_\YVV]g^- - - - -  -'2BVeefhhiiims{{qg]SJC??CCA@E@>;:9659BMW]chmprsssqmigffda^`WF1  9J@?BDEEDDEHJLQVUUY_afhmpnp{f^`q|~xsppu|}rc\`egc_]\]]\ZXVVW[`O - - - -  %*/A\ddgiiiknt{zrk`XQKFB=534466=AEKQXafjmptwxwvtrnjhggea^[N1  2HB@BDDEEDEEGILPQNNSY[VNPX[]eqv~johpvsnifegjmlid_\_egea][ZYXWVVVWVT? - - -   #("&=Wchiijlpv|}sjaYQLMNQSU\^]_adfimoqtx|~~|zwspljige_ZN1  -/GDABCDDDDEEEFHJLLLLMNMLOSX[_ehjkje`^_`elrztykmolgda_]]]]]\ZXY_ee`\YWWVUTUVVNI5 - - - -  "*9Tfkjjmqx}|zutx{}zurmkjhcXM5  .FEBBCDDDDDEEEFGHIIHHHILQVZ\]\WSQRUZ]^`dknbgq{{mklifca^ZWUTUURPPV_c_[WVUTTTUVUJE3 -     - .# 7Wgkjmry{wsnkjf^L6 - ,EFCBCDDDDDDDEEEGGHHIKNQVXZZYXWVUUWWXY\bgkaegjlx~|ynlkigda^ZURPONLJJOX]]XUTSRSTVWVMF3 -  - /& ;\ijlrz|xsnjg_Q7  - - 'AFDCDDDCDDCEEEFGGIJLORTVVUTSSRRQQRSTW[_dgmmljiovxvolkigea]YUQNLKHFFKSXYVTRQQRTWXYSK5 -   /) F`hlrz|vqkg_O8  - -!=FFEDDDDDCECEEFGHILNQRSSRRPPPPPPPQSUXZ]`arqpooqttromkjhe`\YTQMKJHFFKQUWURQOOPTWZ[YP8 -  /+ 'H^ipxyrle^P8  - 9FHGFEDDCECEDFFGIJLNPQQPPPPOOPPPQRTVXY[]^rqponopppnlljgc_[WTPMKIHFHMRUUTQOMLOTX[]^T=  -// - &F]hpx{tld\P: - 5FIJHEDDDCECFEGGIJLNOOPPPPOPPPQQRTUVXY[\]pponmmmmmlkjhe`\YVSPNLJHHKPTUUSPNKJLSY]]`UD .3! $G`inv{tld\O9  3FJLIFEDCDCEDFFHHJLMNNOOOOPPPQRRSTUXYZ\\]nmmlkkjjjihgea\YWUSQOLKJKMRUVUSPLIGIRY]\_SG +7( &B^djr}|rjb\Q8 4EIMJFEDDCDDEEGGIJKMMNNPOPPPQQRSTUVXY[\]]kkkjiihggfec`]YWVUSRPNMLMPSUWVTPKGEFPY][\PH '80  IYago{{qg^VP< -4EHMJGEDCDDEEFFHHJKLNLONPOPQQRRTTVVXZ[]]^iiihggfeecb`][YWVUTSPONNNQTVWVTPKFCCMX]Z[OJ(  !64"  *BT_fox}||{z{{{{|}~~{vndYPI9 -5FHLJFECDDDEFFGGIIJMLOMPNPPRRRTTUVWYZ\]^^gffffeedcb`_][YWWUTSQPPPPRTUVWUQLGBAKV\ZYOK7 16( ";MX`iptvvvxxy{{zywvtrrrqrswxxxvrld\SI=2 7GGJIFDCCCEEEGGHHJKJNLPNQPRQRSTTUVXYZ\]^^eeeeeddcba`^][YXWUUTRRPQQRSUVVURMHCAJTZYWPLC$  -+5-  1AOZbfhijjklnqrrokfcdfikmmmmmjd[SKB6':FEHGECCCDDDFEGGIJJMKPLQNRQRRSSUUVWYZ\]^^ccccccbcaa_^][ZYWWUTTRSPSRSTUUTRNJECIRWXVQLF/ &30 - -'7FNSX[\\]^_``_]YTQPTY]]ZYYYVQJA7+=DCEECCCCDEFEGGHIILKOLQNROSQSSTTUVWXY[\]^bbbbcac_b_`]^[[YYWVUTTQTPSSSUTTSOKGDHOUVURMF6 - !03!  -6%.4$  !)/24555565445530/023431/-(   7A??@AABCCEDGEHHIJIMJOLQNSOUQTSTTUUVVWXYYY____`^a\b[a[`Z]Y[WXVTVQVQTTRURSRPNKIILOQRRPLD1  )4(  !$%&&%%$%&&%$##$$$" 0?@==?@ABCEDGEHGHIILJOKQNROUOURTTUUUUVVWWWW]^]^]_\a[bZ`Z_Z[YYXWWTWQURSTQTRRQNLKJLNPQQPLF9*  "1+  -  -)9?=;<=?ABCDFEHGHIILIOJPMQNTOUQTSTTTUUUUVVVV\\][^[_[`Z`[_[\[YZXXUWRWRTTRUQSRPPNLLMNPPQPMH?5# *+ - -  -#3;;9:;=?ABCEEGGHIIKIMJQKRNSOUPTRTTTUTTVUUUUU[\Y]Y]Y_Z_[^[]\Z\YYWXTYQUSSTQSRQQOONNNOOPQPNJD=1 -!(" - - - - - -  -$278778:=?ACDEGGIIIKIMJOJRMSNUOTRTTTTUTVSUUUUUZX\W]W]Y^[][][[\Y[XYWYRYRUTRTRQTOROPNPNPPQQPMHD=* #$ )4754568:=?ACEFGHIIKIMJNKQLSMUOURTTSTTUURWRWRVTX[W\U]V]Y[[[][\[[Y[XYUYRWSUTTQTPTORNRNRORRRRPMIG;# " -78412358:=@BDEGHIJLINJNKPLRMSOUQTSSTTTTTWRXPYQVYVZU]S]V\ZZ][[[[[[ZZXYUZRXRURURSQSPSNTNSPRRSRPMLF5  - ".673//0358:>ACEGHIJKKMJOKPLRMROSQTRTTTTTUTTURYOWSVYU[Q^S]W[[Y\[[[Z[ZYYXYUYSWSUSSTRRRPTNUNTRSTTSPMJB3   -'1452/-.0368BEHJLMMNNPNONPNSOSQSRTSTTTSUSSUSTTTRTSWTXR]O\S\U\X[Z[[[Z[[ZYZXWYVWWSYQXRVTSUPXOURTTTUSOKH?,    -"(,,,***+./259=@DFILMNONPNPOPOROSPSRSSUSUTURTTSSTRTRRTTWSYO]Q[S]U]X\Z[[[[[Z[XZYWYWUYSZRXTUUSWPWPTRRSTTQNLH;+   - - $%'))))*+,.147;>BEHKLNOOQNQPPPQPSPSRSSURWRUSTTRSSRSQTRRVSWR[O\Q]Q^T]W[YZZ[Z[W[XXYXXXUYSZSXUUWRYQVRSRRRRRONLE8*  -   "$%%&'(()*,-036:=ACFIKMNOPORPPQPQRPTRTSURWQVRTSSSSQRRRQRQTWSXP\N^O`P_S]W[YZYZXZXYYWYWYYVZUZUYWUYRWRSRQPQQQPNMIA6)    "$$$$%&'')+-/269<@BEGIJMNOOQNQPPQRPTRTSURWQWRURSRRRQRPRQQRUTVRYN]M_N_Q]T[WYXYXYWXWWYWYWYYWZVYWVYSYSUSRPOOPPPONLF?7. -   "####$$%'(*-/1598+   -  !"######%'),/269=?ACDEFGIJLLMNNPOQPSQVRUTUTVSUSSRRRRORQORPOQTUURWQYQZRZTYWXWXWVWUVUUUVVXWZXZX[W\U]SYUUTRPNNNNOPPPPNLID>3"  -  !!"""""##%(+/26:@ABCDDEEGGHHIJKLMNOPQSTUUVUVUTSTRSQRPQOPOPNQO \ No newline at end of file diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/img/sh1r.pgm b/applications/plugins/CImgPlugin/extlibs/CImg/examples/img/sh1r.pgm deleted file mode 100644 index 532974c7f12..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/img/sh1r.pgm +++ /dev/null @@ -1,243 +0,0 @@ -P5 -# CREATOR: CImg : Original size=180x180x1x1 -180 180 -255 -}~k]WXY^elqqmsypk`QE?@FPY_bimkd`i~y`80-,+))+19DQ`moe_ZYant||woU5!#%)+*%##'-17I_e_Z[XWYi{{z|vog`XRpT>.%%)-/1/,++****)-8EHJKIFDHWpzpx~ogl}{zuTBDLUdu}ume\VNKE?<;50489537<>;99;?AA@@ABCaC61-(%##$%&'*,-./.-+-269:999;?F[d\G@JOGRcg^]oweTE?GVZWROPS[gkkjaZUQKB729840-)'(010///-,1320031/16875533??<:9840./01N:31.'!"%(+./01111001210/../024.-,(#!%*)$)=S[\Z^[N@552,1>@<<=?;7:>>?B;1-0430*'%$%).1/.-,,++("&'+165/3;AJQSRZ^eo{_410,& #'*-/11221110/.-+*(&$#"!!! !(./)),,.,+-./113577646:::93+%$%'((*,.15:?IOW`jt}ͪ^,1*""$'*,/1233211/.-+('%$"!!&+,.,++-0234566569>BCEK[s¾ǪY8$"!$&)+./1233210.-+)&$"  - - "%&''(*+,../0112259=>>?KeŪxl_JA:3,% &62 #&'(*+,./000/.-*(%#  !"$%')*++,--./02454202>X}ƪt\PE<2("" #%%)&)$$&'''&''()****(&#  "$%'()**+-./134667754CeƪvmbP?3/+!!%*")18AIQQG.!#&'&$"!!!!"""#" !"$%&()*+-.02345652/1;Lvƫ{D*)%#%#!#"!"%,3;DO]hux{t:!!%&#  "$%&(*,-/01234320/.0Fwūr*!#3@GPZels|["#" "$&(*,-./0222210,&(Gwūh D\r3"  #%(*+-..//00010-$+Gū[*q'"%()+,--...//11++_ūX"D{I "%()*+,,,,--.00 ,>ĪKFtG##%'()*++++++-.'*;_īHQ~D #%&'()))***+,*+/Hy¬M[TVl -#\ - - - - """     !"#" $ApO@TXNWg r'  - - -  !$'('$  -  ! )@kCGWSJT_ V -  - - - - - !%),-,("  - #-hICMUOGM\ $1  - - -  !$)-021-% - - "F|p8FSRMEG^+f  - - - -  #(-15761( - - -\B7@VQMECd-t^B"  - - - - - "&+059<;6,  ! !!!!!!! $%%!   "G24:WTMDEh},}u[>' - !$*/49>A@:1# !"####$##$$$$#"! %,11.)$ 2w22AWYLBKfz -J-#   #(-28=BED>5&!$%'((''&&&&&&&%$"!&/7<;61*# ^.6GW]MCQ`w0{;-)    "&,17D]bRFSYs3yA(/$    !$)/6;@DIMLC<0% !  $(,0110.+*)((((''&(09?BA@<6/(  !#"1y}.IEfgXHSTl4J,&1"  "'-4:?CGLONF@5+!"#"!!%*/2331.+*((((((),19?ABA@;6/)  !%'+ar2IMniZKSTd5-$&0"  $)07>BFINPOHD:2"!$%$#! !$(,./.,*(&&'(()+/39>@BCB@;5.(" &+('Ku5GVpiYLUV_9h$#'.!  %+2:@DGKOQOIF>6' #&'&#! !#$%$#"!"#%'),.26;?ACDDD@;4/)# - #+-$=6K[qgXNYYXACEGHGFA;5/*$ - (1(6u4Q^tkWQ[]M?k030+(!$+3:AEILPROJGB6+!!%)*)'# "'*-,+)((+.259;>ACFIKLLLHC<61+&! - - - - #003hujfv9Wczu[T_`DDV0?0*'"")18?DHLQROJFA5*# $(+,*'"$*.00.--/26:=?BDFIMPQRQOKD>83-(" - - - - '-0Q}idRMgN`ncYbd?KU8@,)($ &.5***%#*19?EJPSQLHC3)"!'+/0/+& "&)-148BGLQUX[^adgikmmlkhe_WNHC>83,%  -  -  Ejy{zihi,c2C(.5/#!$)/6=CHLOPNKG:(4569:70'"$,6?EKQX_cfilorstuutrqolg^RLGA;6/'"  -  -  !"Fu}jfg%gO5-14,!  "%&')+/5*7668:93+$ !&/:EMT\dkorux{}}}|zxwutrnfWPJE?:3(#""!  - ! #?zleeka3/21' #),./148=DJNPPPONLGB06645675/)$"$(1=JU^irx|}zyxvsj[TOHC?5(%'))'! -  -  !CHNSVXWWUSPLE7$&475446630,('+2=JXds}|{yul`XRKGB6*+1553*  4qebpE0')#  &.6:=AEKOTWZ]^_^]ZWRKB46BHFB><;:964104=HUex~|wnd\UOJE6-5>AB@6'  - 1uie~~A(## - - !%,5% - - - -  $'*27[ '{F0^o{uuwz}|uqprw{{||vsqopruwwxz}vmgeZE6) - - - !0E2J$} (q; 0`mzuuwz|}wngc_[UYbii^PHLMMORW`ioqsv{|yywpntxzzvsx}}{{|{smdVI8$  2:3:6z )Y:" -^nwtuvy||yqh_YUQLIGGE?9531..16;962/,*(''(+06;BKRW^lx~xqjbXNF@7/)%" !$&)-048;=@BGNYfqtqjeY@" 4~a:l~0  Sinpoolf`[WTSQOMKHEB@>;:997642136;@GOV]iu~|une]TKB93-*'%$#$%'*.26:=@BDEGKR]iqqmj_D$ J_@~s,!& - -Nikmmmid`[XVTRQOMMKJHEA<:986420038>CKU]fs}{rjbYQF<51-+((()+-0369;>ADFHHJLQZfnqomdH$ 0SZA~e.%7& Fgiillga]YUTSQONMMOQPLC81,*%! "'/6?AELX`^[X[_Q5#!%,1?Rao~ym`SC91*&##)/:HQYdg\ND9338?FKNPU[emqqomW'MgEHK6*'8C/$!! 5SfbidVQQXZVSNF=88>M_nuxvl\PMQVQC4,*+5GZm~{kWH71.*)+2;AP_eiqutl`UJ=7;DJNQUZdnqrqoZ)"K[AJ~O51*:G=.&$$"6RcbfXNRYa^URJ?68EXinaPJI@47>@CIIE<4/1@Me|zgK=20/036;CRg{}qmjhaTF?DKOSUYamrsrp\,4MQ;MW>?1>NL>4,')2H`^[KMS`g_TQE:7CQYWE, )*"$.58>EIFA86?G\zx]@7468=BISZTKB7//6H^jgd\NDEMRTWW\ktsrp^/!-[S@6Qv]JL;BV]PB7/..9U^QMNPdiaTOA:>GE<2)""!/@?508HSY[QFENSW[XVeutqo^1$,.Nc7Z0T|v`WXKIR^YNB741/>WJWHOhjcUMA==:5588/!&F\QA>DNUSHCJRqhLBJKKJKJGEE:&"%)*$!(4:FQQIEMUZc_RYpvqn]1 !#+22DN4z,Whsbb`]YMPPMG?=5%%*AZGUkmgYNC;648BMOB.!#,AaldWNJNX`WCOWm~bPUZMFECACMUH"$6C?9>FHGMU_im_P]utm^1"#%(.3*0*T'ZXUqdheilYLB>=?KN.djFYnplaWPKHHMU[]WH;59D`utmidbacjdCEYfssppt|y_W\RFOQPNR\e^8) %3EOKA;?DHNXdnsq_Tevpc4!$&(+/1&,3^lnjlvfPA948Qnqb1|Z^pssnhd_XSQTY`js}~yutsrrstuvX3GMO[wuSEIKAUcikhhkqs^E635:K^c\RIGHLS_kuxzoZUqrg1!#%%#%-G~^}vpowkSC928Ywzn:phruwvsqng^XUTUVWX[_bdfhjkmorsusb$79:8~#dkdhjjmr|wl8;(,^o`Z^behkmpsuxz}{||zxtqlghml)*d !}gpjkihkq{*7+._pa[[`cgjmpsuy{~}xurqqvukhlsy~|yvsokfgte >s~ !rdpplhfipz(035Wd_Y^aeilpsvy|~xpic][`m}nZPPVan{~{xtqmhfh{[ =q{ #b]pulechpz<1I- 0abY]`dhlosvz|ulcUIBBM`v}kR?7:DTfx}zvsokhgj~R  7mz %RVpvh`aiq|Y=bD*" Wd[]_bfkosvz}vl_N;.*/>Xjtxz{zxrgSOe{|yurnjgim}I d (SUnma\`kskLe\H855;Pf]]^afjnswz}zqdRA3+).:M\chlke_RB757;fb]\_bgmrvz}vi]PF@<99;===?@ACFKQU[ep{~{yurnkijpt_(#!#9Eps +XUXROQ^r~sqtqZ1$_h^\]afkquy|}ti]RJD>:8778:=BHNTZ_enw}zwtqmkkjpqN'._o ,SSSOMQdyl $Xga]]`diotx{|ti^ULD>97669>FNV\bgnu|~|yvromklkql=%-gj/MRPOMTnr __b^^_cgmrwz~{sh_VLD=988;BKV^djou{}zxtromlmmse- "=h` 4JUPQQ^v& X_b`_`bekquy|~xpg^UKD?<<@GR^flpuy~~{yvtqommpos\ %[uX 8N[RV[j|>  Jgeba`adinsw{}{unf]SKEBCGOZfmruy}~|zwurpnmmpprQ  -"\tV4\bSYds~s - - 2dhdb`acgkpuy{~}xsmf]UNLLPXdntxz}}zxvsqonmnrqoC -8_wU7ebVZju|z> -  #Xedbaabeinrwy|~~|xtohb\ZY]dnv{~}{ywtrponmnpnf/'KdmvR;`]\]lrtvy~kz - -Nccba`acgkptwz|}zwsokhgiox~~~}|yxusqpnmnnoi\Uzc```^\ZXVSQOMKJILL< - -  *GTWXXXYZ\^abbbbcglrrmikoqqplhhe[TPKDCFIPW_ehjnrqomqx}~~{uoifefgghhiiihgaH &EJKKKKJIHGFEDDDFGHJLNPQOOSX\_``_][YWWW7P{\W\][YWUSRPNLJHGHIG4 - -  :LRVVWWXY[^`cegkpuxyusrswzxrpt}zqpsw{|xussuy{|{yvqlhgffggggggfdV5 $DKLKKJJIHFFEDDDEFHKMOQSUX[\]\[YXVTSSSS0TeRVZZXVTRQOLKIGEEFF@- - -  -.AMSTTUVWX[]`cgkosvwxwwwxz||~{vtrstvwwwuroligffffffffd_G$  $CJMLKJIHGFFDDDDEFGKNQTWYZYYWVTSSRQQQRR.[zla^fwlYSUVVTSQPNKJGEDCCCB;) - -  %7FQTTTTUVX[]adinqtuutsqoqtzyspoopqrsssqnlihffffeeeee`S. 'FLMLKJIHFGDDDDDDEFHLORTUTRQOOOOOOOOOOO*']~vsvqic[SPOR\imf\VSSSRRPOMKIFDCAAAA?9' - -  +;KSSSSSUVXZ^bgknppponnnoptx{|~|vplkkkklmnnnmkihgffeedddd`S<  - ,ILNLJIIGGEFDDDCDDEGIKMNNMLKKKLMMNNNNNM2Agla^[SNLKLNQRUWXYWSPOOOONLJHFDBA@??@?:' -  - !)=NRRQRSUVX\_dhjkjihgghjklnprtvx{|~~|zyvrmhedbbbdfhiiiihggffedcddbXA%  - 1KMNLJIHHFFEDCDCCDDFGHIIIIHHIJJKLMMMMMM=Yf`XQMLKJJIIIJMOQPOMLLLMLLJIFDB@?>>?@@<) -  %@PRQQRTUWZ^behhgda][[]adghiknqsvwvtsqokgb_[XWX[_bdfggggggfedccd]I+ - 4JMMLJIHGGEDCF@ECCDDEFGGHGGHHIJKKLMMMMMO``YSPOOOMKJIGFFGIIIIHJJJJJIGEB@?===>@BA+   *FQQPRSTVY\`dffec^YSOMNQVZ]^`cfiiijkid\VPLLLOSX\`ceghhhhhgecbdbP5  - - 5GKMKJIGGEEDDAG>ECCDDEFGGGGHHJJKKLKMLML~`c]WSRQQPNLJHGEEDDEEFGHHIIHGECA?=<<<>@CD/  !! -2KPQRRSUX[_cegfda[TMFCADHLPRUWXYXTNJE@>=?DJPV[_cfghijjjihfbbcV>  - - 8EJLKJHGFFFCCE@F@ECCDEEFFGGHHJILJLKLMLMg`cb\XUTSQPNLJHGFDDDDDEFGGGHGFEB@><;;;=@EG2 "$ :JPSSTUX[_befhfd_ZSLE@<962////0259=>?CFKQW[_bfhjllmmmmljfbb\F   - - !;EJKJIHGFFDFCCDBDADDCEEFFGGGJHLHMJLMLMLX\d`[XVUSQONLJHGEDDCDDEEFFGGFFDB?=;:9:=@FL6 "&  !=KRTTUX\_behhihfb^XQJD?<;999<9889=AHM9  -!' (=LRTUX\_bfhiklljie`ZVSQPQRTY]bgjnnmlihjknpsuvwvutsrqpmg_P4 - - - - - '?DHIIHGFEECCDBDCBDCEAHCFHGHGKGLIKLKLLLM``]ZXWUTRPNLJHGFEECDDDDFCHDFEDC@>;9778I?FCCECFDGHGHIIIKKJMKLLKLXXWVUTRPOMKJHGFGCGBEDDCH?LBFEDC@=:8668GBDDDFEGFGGIGJJJJLKLLKLLVVUTSRQNMLJHGFGCH@GCDDFBJ@HDEDC@=:8667"  % 6MY]bglpsux{~~~}}||||}}~~}{yuqmif`L+  -  -BDE5  "& - -$>KU]ekpsvy{{zyxwwwwwwwwvvutttstttuuusoib[TI7 - -  - 3>AAABBBCAFAECCFCEEEFEFFFIDLELGJIKHKKKKKKKOONNMMKJIHGGEFEEDEDEEDECDDCCCA@?<:87668:=@CC7(  -'! %8HS\cjnqsuuutsssssssssrqqqpppqqqqpomg`XNB1 - -  -  .;?@@AABBCCAFAEDDEEDFEFFGGFIGJGJIIKJJJKKKKKNNNMMKJJHIFGGEEFEDDDDDDDDCDBBA@?<:877679<>AA9." &$ "6FQYagjlllmmmlmmmnmmmlkkkllmnmmlkhe^VK>-   -  *9????@AABACDAFBFDFEFFEGFFGGHGIGIJJIKJJJKJJKMMMMKKJIJFHFFFEEECFCDECDCDBCA@@=<:977779;=??:2)  "&"4CNV\`bcdddefgghhgeedddefgijifeda\TH:) - -  -%8@@>>??AA@CBCEBGCFEFFFGEHFGHGJFKHHKJJJKJJJKJLMLLKJIJGIFGFFEEDGBEEBECDBDAA@?=<:987889:<>>;5/# $ .=HPTWZZ[[\]]^__^]\\]^^_`aa_]\ZVNC5$  - -  "4??==>>??@BBCCCFCGEFGFFGHEHGGIEKGHKHJJJJKJJKJLKLJKIJGJFGFFFFEFAFDBECCDCABA??=<::88799:<=><83+   )8AFIKMMMMNPRTTSQPQRTUUSRQPNMJC8+ -  1<><;<=>>@@BBCDEDGEGGFGHGGGGGHFKFHKGKIJIJKIKJJKKJJJIHIGHGFFDFECFDCEBDDACBA@@>><;:98899:;===:82(    "-48;=>>>?@BDEDB@@?ACCCA@>;83*   -  0:;:::;<=??AACCDEFFGGGGGGGGGGGGHFJJGJIJJJJIMGKKKJJKHJHHHFFFFFEEEDCDCDACDAAA@??==;::999::;<==<:71% -   #)-/011001210/.-./010.*&!  - -  -.:;989:;<=>@@BCDEFGGGGHHHGHGHGHGHHHGJIIJIJJKGNHJIJJGKFJGHGGFEFEDEDDEAECABC@A@?>>=;<9;99;;;<<=<;97.  - !!!!""!!    - -  -$19;97789:<=>?ABDEFGGHHHHHHHHHFHGHHHHIHHIIJJJJKIKJJGJJEKEIFFFFGDFFCECCG@CDAAB@@?>><=:<9:;:;<;<<=<:94(   -    $29;866789:<=>@ACDFFGHHIHIHHJHGIGGHGHHHHIIIJJJHKJJJGLFHJEJEHGEHBIBFDDFABEC?EA@A@??=>;>9<;;;;;<<=<<;:7."    #/687556789:<=?@BCEFGHHIIIIIJFJGIGJEIGHHIHIIJJHJJJKIJDLFGIFIFGGCK?JBEDCGBBBF>CB?@?>><>:>:<;;<<<=<=<<;93'  - (.2343345789:;>=<>;<;;=:=<<====<:4+   -  $-//0001235689:;=?@BDFGHIJHKHJIKFLDLCNBLFHHHHHIJIJHHNFKFJICLBKBKDFCJ@JAEECECADC?CA?@??=>==<=<9?:><;====<;6-$    &020.-./0234679:;=?@CDFGHIIKHKIJIJFLEKDLDJHHHJHIIIIJLFNHIEHIEIEIDHEGDGCFDCEACCBBC@AA???>>=<=;;>9?:<>=====;6.&   --420--./0134679:;=?@CDFGHIJJJJJJIIIGIGIFIGHHHGJIHJIJHKHJ \ No newline at end of file diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/img/tetris.h b/applications/plugins/CImgPlugin/extlibs/CImg/examples/img/tetris.h deleted file mode 100644 index e18b158a3d1..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/img/tetris.h +++ /dev/null @@ -1,2313 +0,0 @@ -/*------------------------------------------------------------ - - Define hard-coded color image used in the 'tetris.cpp' - example file, so that the corresponding executable does not - depend on additional data files. - ---------------------------------------------------------------*/ - -const unsigned char data_logo[] = { - 45, 45, 46, 47, 48, 49, 50, 49, 48, 48, 49, 50, 52, 53, 55, 56, - 59, 62, 64, 65, 64, 64, 66, 66, 65, 66, 72, 76, 78, 80, 77, 74, - 83, 84, 79, 78, 82, 85, 91, 97, 85, 92, 90, 95, 97, 97, 93, 88, - 95, 87, 85, 88, 88, 85, 82, 81, 83, 77, 74, 81, 81, 78, 73, 69, - 67, 65, 63, 65, 66, 65, 65, 65, 64, 61, 59, 56, 54, 53, 52, 52, - 52, 51, 51, 49, 48, 47, 46, 45, 44, 43, 43, 43, 42, 41, 41, 41, - 40, 39, 39, 39, 38, 37, 36, 36, 36, 36, 35, 35, 34, 33, 33, 33, - 33, 33, 33, 31, 29, 29, 30, 32, 32, 32, 30, 29, 30, 29, 29, 30, - 45, 45, 46, 47, 48, 49, 50, 49, 48, 49, 49, 50, 52, 54, 56, 57, - 59, 61, 63, 64, 65, 65, 67, 67, 67, 67, 71, 75, 78, 81, 79, 76, - 83, 87, 83, 82, 84, 88, 94, 100, 91, 95, 94, 98, 100, 100, 96, 92, - 99, 91, 90, 91, 89, 85, 84, 83, 83, 78, 77, 82, 82, 78, 73, 69, - 68, 66, 66, 67, 66, 65, 65, 65, 64, 61, 59, 56, 54, 53, 52, 52, - 52, 51, 51, 49, 48, 47, 46, 45, 44, 43, 43, 43, 42, 41, 41, 41, - 40, 39, 39, 39, 38, 37, 36, 36, 36, 36, 35, 35, 34, 33, 33, 33, - 33, 33, 33, 31, 29, 29, 30, 32, 32, 32, 30, 30, 30, 30, 29, 30, - 45, 45, 46, 47, 48, 49, 50, 49, 49, 49, 50, 51, 53, 55, 56, 58, - 59, 61, 63, 64, 66, 67, 69, 70, 70, 70, 71, 74, 79, 82, 83, 79, - 83, 90, 88, 86, 86, 89, 96, 103, 97, 98, 100, 102, 103, 103, 100, 97, - 103, 95, 95, 95, 91, 86, 88, 86, 82, 80, 82, 84, 82, 77, 73, 70, - 69, 69, 69, 68, 67, 66, 65, 65, 63, 60, 58, 56, 54, 53, 52, 52, - 52, 51, 51, 49, 48, 47, 46, 45, 44, 43, 43, 43, 42, 41, 41, 41, - 40, 39, 39, 39, 38, 37, 36, 36, 36, 36, 35, 35, 34, 33, 33, 33, - 33, 33, 33, 31, 29, 29, 30, 32, 32, 32, 30, 30, 31, 30, 29, 30, - 45, 45, 46, 47, 48, 49, 50, 49, 49, 49, 50, 52, 54, 56, 57, 59, - 60, 62, 64, 65, 67, 69, 71, 72, 72, 72, 72, 74, 79, 83, 85, 83, - 83, 90, 92, 89, 87, 90, 97, 105, 102, 99, 103, 104, 105, 105, 101, 101, - 105, 97, 98, 98, 93, 88, 91, 89, 84, 83, 86, 86, 81, 76, 73, 71, - 71, 72, 72, 71, 69, 67, 66, 64, 63, 60, 58, 56, 54, 53, 52, 52, - 52, 51, 51, 49, 48, 47, 46, 45, 44, 43, 43, 43, 42, 41, 41, 41, - 40, 39, 39, 39, 38, 37, 36, 36, 36, 36, 35, 35, 34, 33, 33, 33, - 33, 33, 33, 31, 29, 29, 30, 32, 32, 32, 31, 31, 31, 31, 30, 30, - 45, 45, 46, 47, 48, 49, 50, 49, 50, 50, 51, 52, 55, 56, 58, 60, - 62, 64, 66, 67, 68, 70, 73, 74, 75, 77, 76, 76, 80, 84, 88, 89, - 86, 91, 96, 94, 90, 93, 101, 106, 107, 100, 108, 107, 109, 109, 105, 106, - 108, 100, 103, 100, 96, 92, 95, 91, 87, 88, 89, 86, 80, 76, 75, 75, - 74, 74, 74, 72, 70, 68, 66, 64, 62, 59, 57, 56, 54, 53, 52, 52, - 52, 51, 51, 49, 48, 47, 46, 45, 44, 43, 43, 43, 42, 41, 41, 41, - 40, 39, 39, 39, 38, 37, 36, 36, 36, 36, 35, 35, 34, 33, 33, 33, - 33, 33, 33, 31, 29, 29, 30, 32, 32, 32, 31, 31, 32, 31, 30, 30, - 45, 45, 46, 47, 48, 49, 50, 50, 50, 51, 52, 52, 56, 57, 59, 61, - 65, 66, 68, 68, 69, 72, 74, 75, 77, 80, 80, 79, 79, 84, 90, 96, - 92, 92, 101, 101, 95, 98, 106, 111, 114, 105, 114, 113, 116, 116, 112, 112, - 111, 103, 107, 100, 98, 95, 96, 92, 89, 93, 88, 83, 79, 75, 77, 79, - 78, 76, 75, 74, 72, 69, 66, 64, 62, 59, 57, 56, 54, 53, 52, 52, - 52, 51, 51, 49, 48, 47, 46, 45, 44, 43, 43, 43, 42, 41, 41, 41, - 40, 39, 39, 39, 38, 37, 36, 36, 36, 36, 35, 35, 34, 33, 33, 33, - 33, 33, 33, 31, 29, 29, 30, 32, 32, 32, 31, 32, 32, 32, 30, 30, - 45, 45, 46, 47, 48, 49, 50, 50, 50, 51, 52, 53, 57, 58, 60, 62, - 65, 67, 69, 70, 70, 73, 75, 77, 79, 82, 84, 83, 83, 85, 91, 98, - 97, 94, 101, 107, 99, 100, 109, 113, 119, 110, 117, 118, 120, 121, 115, 118, - 113, 108, 110, 103, 99, 100, 99, 93, 94, 96, 88, 81, 79, 77, 79, 81, - 80, 78, 76, 74, 71, 68, 65, 63, 61, 59, 57, 56, 55, 54, 52, 53, - 52, 52, 51, 49, 49, 48, 47, 46, 45, 44, 43, 43, 42, 41, 41, 41, - 40, 39, 39, 39, 38, 37, 36, 36, 36, 36, 35, 35, 34, 34, 33, 33, - 33, 33, 32, 31, 30, 29, 31, 32, 32, 32, 32, 33, 33, 33, 31, 30, - 45, 45, 46, 47, 48, 49, 50, 50, 51, 52, 53, 55, 57, 59, 63, 65, - 67, 70, 71, 73, 74, 75, 78, 79, 82, 85, 89, 91, 89, 87, 92, 96, - 101, 98, 98, 110, 106, 102, 110, 114, 124, 117, 121, 124, 124, 126, 118, 124, - 115, 116, 112, 107, 103, 107, 102, 96, 102, 97, 86, 80, 81, 82, 81, 83, - 82, 80, 78, 73, 70, 66, 63, 62, 61, 59, 58, 57, 56, 54, 53, 53, - 53, 53, 52, 51, 50, 48, 47, 46, 46, 45, 44, 43, 42, 41, 41, 41, - 40, 40, 39, 39, 38, 37, 37, 37, 37, 36, 36, 36, 35, 34, 33, 33, - 33, 33, 32, 31, 31, 31, 32, 34, 33, 32, 32, 34, 34, 34, 32, 31, - 45, 45, 46, 47, 49, 49, 50, 50, 51, 52, 54, 56, 58, 61, 64, 67, - 70, 73, 75, 77, 78, 79, 82, 83, 84, 89, 93, 95, 93, 93, 94, 96, - 102, 105, 102, 108, 117, 109, 109, 118, 127, 123, 125, 128, 129, 130, 122, 129, - 119, 122, 116, 109, 113, 112, 104, 105, 106, 95, 85, 82, 83, 85, 85, 86, - 84, 80, 77, 73, 70, 66, 63, 63, 61, 59, 58, 57, 56, 54, 53, 53, - 53, 53, 52, 51, 50, 48, 47, 46, 46, 45, 44, 43, 42, 41, 41, 41, - 41, 40, 39, 39, 38, 37, 37, 37, 37, 36, 36, 36, 35, 34, 33, 33, - 33, 33, 32, 31, 31, 31, 32, 34, 33, 32, 32, 34, 34, 34, 32, 31, - 45, 46, 47, 48, 49, 50, 51, 50, 52, 53, 56, 58, 60, 63, 68, 70, - 73, 75, 79, 81, 81, 83, 86, 87, 88, 92, 97, 100, 100, 102, 99, 97, - 102, 112, 111, 107, 122, 118, 111, 121, 131, 132, 131, 134, 135, 135, 128, 135, - 124, 129, 121, 113, 120, 114, 109, 113, 106, 93, 86, 87, 89, 90, 89, 89, - 86, 80, 76, 72, 69, 67, 64, 63, 62, 60, 59, 57, 56, 54, 53, 53, - 53, 53, 52, 51, 50, 48, 47, 46, 46, 45, 44, 44, 43, 42, 42, 42, - 41, 40, 40, 40, 39, 38, 37, 37, 37, 36, 36, 36, 35, 34, 33, 33, - 33, 33, 32, 31, 31, 31, 33, 34, 33, 32, 32, 34, 34, 34, 32, 31, - 46, 47, 47, 48, 50, 50, 51, 51, 52, 54, 58, 60, 62, 66, 71, 74, - 75, 78, 82, 84, 85, 86, 88, 90, 89, 93, 97, 101, 105, 107, 106, 102, - 103, 115, 121, 112, 121, 128, 119, 123, 134, 141, 137, 141, 143, 142, 136, 141, - 131, 134, 122, 119, 122, 115, 119, 116, 101, 94, 92, 94, 95, 93, 91, 89, - 85, 79, 74, 71, 69, 67, 65, 64, 63, 61, 59, 57, 56, 54, 53, 53, - 53, 53, 52, 51, 50, 48, 47, 46, 46, 45, 45, 44, 44, 43, 42, 43, - 42, 41, 41, 40, 39, 38, 38, 37, 37, 36, 36, 36, 35, 34, 33, 33, - 33, 33, 32, 32, 32, 32, 33, 34, 33, 32, 32, 34, 34, 34, 32, 31, - 46, 47, 48, 49, 50, 51, 52, 51, 53, 55, 59, 61, 64, 68, 74, 77, - 78, 81, 86, 88, 89, 91, 92, 94, 95, 97, 100, 103, 108, 112, 113, 111, - 107, 114, 125, 123, 123, 135, 132, 127, 138, 150, 142, 149, 152, 150, 144, 148, - 140, 137, 125, 129, 124, 124, 127, 114, 100, 98, 101, 101, 99, 95, 90, 86, - 83, 78, 73, 70, 69, 67, 65, 64, 63, 61, 60, 57, 56, 54, 53, 53, - 53, 53, 52, 51, 50, 48, 47, 46, 46, 45, 45, 45, 44, 43, 43, 43, - 42, 42, 41, 41, 40, 39, 38, 37, 37, 36, 36, 36, 35, 34, 33, 33, - 33, 33, 32, 32, 32, 32, 33, 34, 33, 32, 32, 34, 34, 34, 32, 31, - 47, 47, 48, 49, 50, 50, 51, 51, 52, 55, 60, 62, 65, 70, 75, 79, - 80, 83, 89, 91, 91, 94, 96, 98, 100, 101, 103, 105, 109, 113, 117, 117, - 110, 111, 124, 134, 128, 137, 142, 130, 141, 156, 147, 155, 159, 155, 150, 153, - 148, 140, 128, 137, 128, 134, 131, 112, 102, 102, 107, 105, 102, 96, 89, 84, - 81, 77, 73, 70, 68, 67, 66, 65, 63, 61, 60, 57, 56, 54, 53, 53, - 53, 53, 52, 51, 50, 48, 47, 46, 46, 45, 45, 45, 44, 43, 43, 43, - 43, 42, 41, 41, 40, 39, 38, 37, 37, 36, 36, 36, 35, 34, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 34, 33, 31, 32, 34, 34, 34, 32, 31, - 47, 48, 48, 49, 48, 49, 51, 51, 52, 56, 61, 65, 69, 73, 77, 80, - 78, 83, 90, 88, 89, 95, 102, 99, 102, 104, 109, 111, 108, 114, 115, 112, - 114, 117, 125, 134, 135, 128, 150, 129, 142, 160, 157, 160, 164, 156, 156, 153, - 151, 142, 137, 139, 137, 139, 125, 112, 114, 115, 113, 111, 103, 95, 88, 83, - 81, 77, 74, 71, 69, 66, 65, 65, 64, 62, 61, 58, 57, 55, 54, 51, - 51, 50, 49, 48, 47, 46, 45, 45, 46, 45, 45, 44, 44, 43, 42, 43, - 42, 42, 41, 42, 42, 42, 41, 40, 39, 38, 38, 37, 36, 35, 35, 35, - 35, 34, 34, 35, 34, 34, 32, 31, 31, 30, 32, 33, 33, 34, 32, 31, - 47, 48, 48, 49, 47, 48, 51, 51, 53, 57, 63, 66, 73, 77, 80, 82, - 79, 84, 87, 92, 97, 95, 97, 103, 104, 107, 109, 114, 116, 105, 114, 122, - 120, 127, 124, 128, 143, 129, 148, 145, 137, 167, 167, 173, 175, 166, 165, 156, - 153, 137, 148, 149, 149, 134, 115, 116, 125, 125, 116, 110, 102, 95, 88, 84, - 81, 78, 75, 72, 70, 67, 65, 64, 63, 61, 60, 58, 57, 55, 54, 52, - 51, 50, 50, 48, 47, 46, 46, 46, 46, 46, 46, 44, 44, 43, 42, 43, - 43, 42, 41, 42, 42, 42, 42, 41, 40, 39, 38, 37, 37, 36, 35, 35, - 35, 34, 34, 35, 34, 33, 31, 29, 29, 29, 31, 33, 33, 34, 32, 31, - 47, 48, 48, 49, 47, 49, 52, 52, 56, 59, 65, 69, 76, 81, 83, 88, - 90, 93, 92, 100, 101, 107, 110, 116, 113, 119, 124, 122, 121, 125, 122, 119, - 127, 145, 143, 134, 143, 144, 151, 167, 152, 177, 177, 183, 185, 179, 176, 163, - 165, 153, 163, 152, 159, 134, 121, 133, 130, 129, 119, 108, 100, 94, 89, 84, - 82, 79, 76, 73, 70, 68, 66, 64, 62, 61, 59, 57, 56, 54, 53, 53, - 53, 52, 51, 50, 49, 48, 47, 48, 47, 47, 47, 45, 45, 44, 43, 43, - 42, 41, 40, 42, 42, 42, 42, 41, 40, 39, 38, 38, 37, 36, 35, 34, - 33, 32, 32, 33, 32, 31, 30, 30, 30, 29, 31, 33, 33, 34, 32, 31, - 47, 48, 48, 49, 48, 49, 53, 54, 59, 63, 69, 72, 78, 83, 86, 91, - 94, 99, 105, 111, 111, 115, 108, 97, 90, 97, 113, 123, 131, 130, 129, 127, - 132, 148, 153, 144, 139, 156, 161, 166, 163, 177, 195, 195, 196, 192, 190, 178, - 163, 159, 168, 170, 150, 142, 138, 141, 134, 128, 119, 107, 98, 94, 90, 85, - 82, 79, 76, 72, 69, 67, 65, 64, 63, 62, 60, 58, 57, 55, 54, 55, - 55, 53, 53, 51, 51, 50, 49, 49, 48, 48, 47, 45, 45, 44, 44, 44, - 43, 42, 41, 43, 43, 43, 42, 42, 41, 40, 40, 39, 39, 38, 37, 36, - 35, 34, 33, 33, 32, 32, 31, 30, 30, 30, 31, 33, 33, 34, 32, 31, - 47, 48, 48, 49, 48, 50, 54, 56, 62, 66, 72, 75, 79, 85, 88, 95, - 99, 107, 116, 111, 97, 81, 68, 52, 44, 49, 67, 77, 98, 128, 139, 135, - 138, 128, 139, 144, 140, 156, 171, 178, 179, 176, 202, 201, 202, 200, 198, 185, - 164, 176, 174, 176, 151, 154, 156, 151, 138, 126, 114, 107, 99, 94, 91, 86, - 83, 80, 77, 72, 69, 66, 64, 66, 66, 64, 62, 61, 59, 57, 56, 57, - 56, 55, 55, 53, 52, 51, 51, 50, 49, 48, 47, 45, 45, 44, 44, 44, - 44, 43, 42, 43, 43, 43, 43, 44, 43, 42, 42, 42, 41, 40, 39, 38, - 38, 37, 36, 35, 34, 33, 32, 30, 31, 30, 31, 33, 33, 34, 32, 31, - 47, 48, 48, 49, 48, 51, 55, 57, 64, 69, 75, 77, 82, 88, 92, 101, - 112, 114, 102, 79, 53, 37, 31, 29, 25, 32, 47, 48, 53, 73, 112, 141, - 143, 66, 57, 78, 134, 156, 175, 177, 107, 84, 93, 97, 103, 99, 101, 90, - 89, 103, 82, 67, 76, 82, 89, 123, 130, 124, 111, 107, 101, 95, 90, 86, - 84, 80, 77, 74, 72, 69, 67, 67, 66, 65, 64, 62, 60, 58, 57, 57, - 57, 56, 56, 54, 53, 52, 52, 52, 51, 49, 47, 46, 46, 45, 44, 45, - 44, 43, 43, 44, 44, 44, 44, 45, 44, 43, 43, 43, 42, 41, 41, 40, - 40, 39, 38, 36, 35, 34, 33, 31, 31, 31, 32, 33, 33, 34, 32, 31, - 46, 48, 48, 50, 49, 52, 56, 59, 66, 71, 75, 78, 84, 91, 98, 108, - 114, 99, 60, 34, 35, 35, 32, 36, 37, 48, 59, 54, 51, 48, 64, 93, - 117, 34, 44, 50, 117, 163, 177, 199, 90, 66, 58, 73, 77, 76, 80, 78, - 75, 53, 49, 61, 66, 88, 92, 89, 113, 122, 112, 109, 102, 96, 91, 87, - 84, 81, 78, 77, 75, 72, 70, 69, 68, 66, 65, 63, 62, 60, 59, 59, - 58, 57, 57, 55, 54, 53, 53, 53, 52, 50, 48, 47, 46, 45, 44, 45, - 44, 43, 43, 44, 44, 44, 44, 45, 45, 44, 43, 44, 43, 42, 42, 43, - 42, 40, 39, 38, 37, 36, 34, 32, 32, 31, 32, 32, 33, 33, 32, 31, - 46, 48, 49, 50, 50, 53, 56, 61, 68, 73, 75, 80, 84, 98, 106, 114, - 94, 45, 36, 39, 41, 48, 58, 59, 58, 54, 49, 46, 51, 54, 54, 55, - 74, 47, 48, 38, 95, 178, 187, 198, 97, 75, 74, 88, 91, 95, 101, 84, - 64, 51, 60, 92, 101, 111, 106, 59, 110, 123, 115, 107, 101, 95, 91, 86, - 84, 81, 78, 77, 75, 73, 72, 72, 70, 69, 68, 65, 64, 62, 61, 62, - 62, 61, 60, 59, 58, 56, 55, 55, 54, 52, 51, 47, 46, 44, 43, 44, - 44, 44, 44, 45, 45, 46, 47, 47, 47, 47, 47, 47, 46, 45, 45, 44, - 43, 41, 40, 39, 39, 37, 35, 34, 33, 30, 31, 31, 30, 31, 32, 32, - 46, 48, 49, 51, 51, 55, 58, 63, 70, 75, 77, 82, 90, 104, 112, 99, - 56, 38, 41, 49, 58, 60, 53, 45, 55, 62, 61, 53, 49, 50, 47, 55, - 60, 69, 71, 49, 95, 178, 193, 201, 108, 73, 82, 91, 104, 94, 114, 73, - 68, 67, 83, 117, 130, 136, 121, 60, 108, 123, 114, 107, 101, 96, 93, 90, - 88, 85, 83, 81, 79, 77, 76, 76, 75, 73, 72, 68, 67, 65, 63, 63, - 63, 62, 61, 61, 60, 57, 56, 57, 55, 53, 52, 48, 47, 45, 44, 45, - 45, 45, 46, 49, 49, 51, 51, 50, 50, 50, 51, 51, 50, 49, 49, 49, - 47, 45, 44, 43, 42, 40, 37, 36, 35, 33, 33, 32, 31, 31, 32, 32, - 46, 48, 49, 51, 52, 56, 60, 66, 73, 78, 81, 88, 96, 108, 109, 69, - 49, 48, 48, 51, 52, 44, 39, 65, 88, 101, 103, 99, 76, 58, 46, 52, - 61, 73, 68, 51, 98, 180, 195, 210, 154, 108, 92, 84, 87, 75, 57, 23, - 48, 83, 111, 137, 127, 104, 92, 69, 109, 122, 114, 108, 103, 100, 98, 95, - 93, 90, 88, 85, 84, 82, 80, 80, 79, 77, 76, 73, 71, 69, 68, 67, - 66, 65, 65, 64, 63, 61, 60, 60, 58, 56, 54, 50, 49, 47, 46, 48, - 48, 49, 50, 52, 53, 55, 55, 54, 54, 54, 55, 55, 54, 53, 53, 54, - 52, 50, 48, 46, 45, 42, 40, 39, 37, 35, 34, 33, 31, 32, 31, 31, - 47, 49, 50, 52, 54, 58, 62, 69, 76, 82, 86, 94, 104, 113, 74, 33, - 36, 38, 36, 41, 41, 31, 59, 102, 117, 125, 129, 130, 126, 103, 55, 55, - 67, 87, 68, 46, 97, 176, 192, 222, 219, 181, 144, 95, 85, 69, 18, 22, - 81, 118, 136, 125, 74, 88, 99, 96, 118, 121, 116, 112, 109, 105, 103, 100, - 97, 95, 92, 89, 88, 86, 84, 82, 81, 79, 78, 75, 74, 72, 71, 71, - 70, 69, 69, 68, 67, 65, 64, 65, 62, 59, 57, 53, 51, 50, 49, 49, - 50, 52, 52, 53, 55, 57, 58, 57, 57, 57, 57, 58, 57, 56, 56, 57, - 55, 53, 51, 48, 47, 43, 41, 41, 38, 35, 35, 34, 32, 32, 31, 31, - 48, 50, 51, 53, 55, 60, 65, 72, 81, 87, 92, 99, 114, 104, 24, 25, - 36, 43, 50, 52, 38, 55, 105, 115, 120, 119, 121, 124, 134, 137, 101, 68, - 72, 78, 68, 48, 92, 173, 190, 214, 235, 237, 238, 177, 115, 56, 76, 115, - 133, 136, 140, 78, 68, 129, 137, 135, 134, 128, 123, 121, 117, 112, 110, 106, - 103, 100, 97, 94, 92, 91, 89, 87, 85, 83, 82, 80, 79, 77, 76, 76, - 76, 75, 74, 74, 73, 71, 69, 68, 67, 63, 60, 55, 54, 52, 52, 52, - 54, 56, 56, 56, 59, 61, 63, 63, 63, 63, 63, 65, 64, 63, 62, 61, - 60, 58, 56, 53, 52, 48, 44, 43, 40, 36, 36, 35, 33, 32, 31, 30, - 48, 50, 51, 53, 56, 61, 66, 73, 82, 89, 94, 105, 113, 70, 23, 52, - 60, 61, 60, 47, 43, 90, 116, 116, 120, 118, 117, 118, 126, 135, 137, 88, - 71, 74, 80, 63, 102, 180, 194, 215, 242, 249, 253, 226, 95, 58, 104, 134, - 134, 128, 125, 57, 112, 159, 156, 150, 146, 140, 132, 127, 123, 117, 114, 110, - 108, 104, 102, 99, 97, 95, 94, 91, 89, 88, 86, 83, 82, 80, 79, 79, - 79, 78, 77, 77, 75, 73, 72, 70, 67, 63, 60, 56, 54, 52, 53, 54, - 56, 57, 58, 60, 62, 65, 67, 69, 69, 69, 70, 71, 71, 69, 68, 66, - 64, 63, 62, 60, 57, 53, 49, 46, 43, 39, 37, 36, 33, 32, 31, 30, - 47, 49, 51, 54, 57, 63, 67, 75, 82, 89, 102, 111, 105, 49, 39, 65, - 64, 59, 47, 27, 61, 113, 117, 118, 122, 122, 122, 123, 133, 137, 144, 119, - 68, 86, 96, 78, 103, 188, 205, 224, 244, 249, 251, 237, 55, 99, 133, 137, - 134, 128, 113, 63, 139, 173, 169, 161, 156, 147, 136, 130, 127, 122, 117, 115, - 110, 105, 103, 102, 99, 99, 97, 89, 87, 87, 87, 86, 85, 82, 80, 81, - 81, 83, 80, 80, 76, 74, 73, 73, 68, 66, 63, 59, 57, 55, 56, 58, - 57, 58, 58, 61, 65, 71, 71, 71, 73, 75, 76, 76, 74, 73, 74, 71, - 67, 65, 67, 64, 63, 54, 53, 48, 45, 40, 37, 36, 32, 32, 31, 30, - 47, 48, 51, 54, 57, 63, 68, 77, 82, 92, 107, 119, 95, 37, 40, 63, - 55, 52, 42, 28, 83, 120, 120, 116, 121, 122, 124, 128, 134, 140, 144, 147, - 85, 82, 91, 78, 97, 191, 215, 234, 247, 250, 251, 246, 92, 126, 146, 135, - 121, 122, 116, 71, 153, 175, 168, 160, 151, 141, 132, 126, 123, 118, 113, 113, - 109, 102, 99, 99, 96, 98, 97, 83, 81, 84, 86, 87, 87, 84, 83, 87, - 85, 87, 84, 79, 82, 81, 75, 70, 71, 70, 64, 63, 61, 58, 60, 63, - 61, 59, 61, 65, 68, 75, 75, 74, 78, 82, 84, 83, 79, 75, 73, 73, - 73, 73, 70, 67, 61, 61, 59, 50, 46, 41, 37, 35, 32, 32, 32, 31, - 47, 48, 51, 54, 58, 63, 70, 79, 85, 98, 107, 115, 55, 10, 29, 56, - 52, 53, 42, 42, 103, 124, 117, 113, 116, 118, 121, 123, 129, 135, 141, 150, - 100, 83, 106, 81, 98, 194, 215, 239, 253, 252, 251, 245, 121, 124, 141, 132, - 126, 134, 124, 68, 146, 157, 144, 139, 134, 126, 121, 116, 113, 109, 106, 109, - 106, 101, 98, 95, 94, 98, 97, 89, 89, 92, 94, 91, 91, 89, 88, 88, - 84, 84, 85, 85, 81, 80, 84, 74, 76, 72, 67, 66, 63, 62, 63, 67, - 66, 64, 66, 69, 70, 76, 79, 78, 81, 84, 86, 84, 81, 77, 76, 75, - 76, 76, 70, 72, 66, 63, 58, 52, 48, 43, 38, 36, 33, 32, 32, 31, - 47, 48, 51, 54, 59, 65, 72, 80, 88, 99, 111, 88, 8, 9, 32, 52, - 59, 61, 38, 60, 116, 121, 111, 107, 110, 112, 115, 116, 121, 127, 134, 144, - 123, 94, 90, 55, 96, 189, 209, 234, 249, 250, 248, 247, 112, 87, 70, 96, - 120, 122, 121, 74, 151, 164, 156, 145, 134, 127, 121, 118, 117, 114, 111, 113, - 111, 107, 104, 101, 102, 103, 102, 96, 96, 98, 99, 100, 99, 96, 92, 87, - 87, 89, 90, 93, 90, 88, 89, 90, 83, 74, 76, 69, 67, 64, 65, 71, - 70, 69, 70, 72, 79, 84, 88, 86, 89, 92, 93, 93, 85, 82, 83, 79, - 74, 78, 76, 70, 78, 63, 60, 57, 51, 46, 40, 38, 34, 33, 32, 31, - 47, 48, 51, 54, 60, 66, 74, 82, 88, 98, 114, 67, 28, 44, 51, 64, - 60, 62, 34, 79, 119, 117, 107, 106, 107, 108, 110, 112, 119, 125, 131, 139, - 139, 95, 83, 53, 87, 178, 200, 224, 243, 251, 254, 250, 115, 86, 91, 85, - 97, 130, 130, 70, 146, 161, 157, 146, 136, 132, 130, 125, 123, 121, 120, 121, - 120, 116, 111, 109, 110, 109, 108, 112, 114, 113, 112, 112, 107, 102, 97, 94, - 96, 95, 94, 95, 97, 97, 94, 91, 89, 85, 79, 73, 70, 67, 68, 74, - 72, 74, 76, 80, 89, 91, 94, 93, 96, 99, 99, 98, 98, 92, 86, 81, - 83, 84, 81, 79, 72, 76, 67, 60, 54, 49, 42, 40, 35, 33, 32, 31, - 47, 48, 51, 54, 61, 68, 75, 84, 89, 100, 114, 59, 55, 60, 60, 73, - 65, 56, 33, 95, 119, 114, 106, 105, 105, 105, 108, 111, 117, 122, 128, 134, - 135, 62, 63, 57, 81, 172, 200, 228, 251, 254, 254, 247, 132, 117, 140, 119, - 89, 97, 105, 74, 149, 158, 145, 134, 126, 126, 127, 126, 126, 126, 124, 127, - 128, 124, 117, 116, 118, 117, 123, 126, 126, 123, 119, 118, 114, 109, 105, 100, - 101, 100, 105, 106, 92, 88, 98, 99, 93, 94, 83, 79, 75, 71, 72, 77, - 77, 79, 82, 86, 93, 96, 106, 109, 114, 117, 115, 103, 99, 98, 95, 91, - 91, 90, 99, 104, 81, 81, 69, 64, 57, 51, 44, 41, 36, 34, 32, 31, - 47, 48, 51, 54, 61, 68, 76, 86, 90, 106, 112, 62, 52, 55, 65, 78, - 79, 52, 34, 100, 117, 109, 102, 102, 104, 104, 107, 109, 112, 117, 120, 129, - 129, 48, 74, 80, 81, 174, 212, 234, 252, 254, 254, 250, 143, 150, 135, 138, - 125, 101, 76, 72, 153, 170, 163, 143, 130, 128, 128, 129, 131, 131, 129, 133, - 135, 129, 121, 125, 128, 130, 142, 161, 161, 156, 149, 124, 118, 115, 114, 112, - 112, 117, 138, 164, 166, 153, 134, 127, 96, 95, 92, 86, 80, 77, 77, 80, - 81, 84, 89, 95, 102, 114, 140, 156, 163, 167, 167, 145, 102, 92, 103, 102, - 99, 116, 144, 110, 118, 81, 76, 66, 59, 52, 45, 42, 37, 34, 32, 31, - 47, 49, 53, 56, 62, 68, 76, 86, 96, 104, 97, 47, 53, 71, 79, 85, - 82, 47, 45, 107, 117, 107, 101, 100, 100, 98, 99, 101, 106, 110, 116, 124, - 127, 114, 117, 93, 94, 184, 210, 231, 252, 248, 253, 247, 138, 139, 133, 146, - 142, 147, 140, 70, 151, 170, 160, 158, 153, 147, 140, 139, 135, 138, 150, 159, - 156, 148, 101, 132, 142, 159, 162, 138, 122, 136, 105, 108, 99, 115, 122, 124, - 129, 162, 166, 177, 194, 211, 218, 186, 130, 92, 95, 90, 84, 82, 83, 79, - 85, 94, 97, 103, 120, 126, 138, 148, 141, 142, 124, 70, 35, 100, 127, 113, - 124, 162, 139, 162, 163, 98, 72, 70, 60, 55, 46, 42, 36, 33, 32, 31, - 47, 49, 53, 57, 63, 69, 77, 86, 92, 109, 96, 59, 58, 83, 71, 63, - 42, 29, 47, 107, 110, 102, 97, 97, 95, 94, 95, 98, 103, 108, 112, 120, - 132, 133, 106, 90, 121, 184, 207, 232, 237, 240, 249, 248, 148, 133, 132, 118, - 142, 148, 141, 72, 138, 162, 159, 153, 151, 148, 148, 139, 171, 155, 153, 164, - 155, 152, 91, 130, 158, 189, 182, 136, 130, 116, 106, 109, 101, 90, 122, 135, - 166, 198, 181, 177, 206, 216, 214, 211, 177, 106, 90, 94, 89, 85, 84, 87, - 92, 96, 108, 134, 148, 156, 132, 123, 121, 131, 74, 77, 126, 180, 193, 134, - 154, 170, 143, 177, 164, 126, 60, 67, 63, 55, 48, 43, 38, 34, 32, 31, - 47, 49, 53, 57, 65, 71, 79, 88, 97, 109, 73, 52, 77, 90, 77, 74, - 59, 51, 57, 106, 104, 97, 93, 93, 93, 91, 92, 95, 100, 107, 113, 117, - 132, 155, 152, 143, 151, 185, 204, 228, 218, 234, 241, 246, 132, 117, 148, 131, - 133, 121, 126, 70, 131, 153, 154, 151, 154, 147, 152, 145, 174, 159, 160, 158, - 162, 149, 82, 150, 186, 195, 178, 187, 180, 192, 202, 198, 175, 121, 109, 155, - 168, 152, 178, 186, 208, 212, 212, 168, 156, 179, 86, 96, 96, 88, 87, 91, - 96, 103, 132, 180, 179, 180, 152, 128, 127, 128, 132, 178, 197, 200, 198, 179, - 162, 157, 151, 165, 140, 145, 53, 63, 65, 56, 50, 44, 39, 35, 34, 32, - 47, 49, 53, 57, 66, 73, 80, 90, 98, 108, 67, 70, 100, 83, 84, 75, - 67, 64, 58, 105, 101, 95, 92, 92, 92, 91, 93, 95, 99, 108, 116, 125, - 136, 146, 151, 157, 164, 183, 202, 217, 207, 232, 230, 241, 123, 118, 126, 114, - 144, 161, 147, 70, 135, 147, 145, 148, 149, 135, 147, 163, 166, 158, 167, 181, - 160, 167, 116, 181, 191, 196, 175, 186, 149, 203, 203, 205, 210, 182, 110, 189, - 182, 172, 189, 196, 212, 214, 195, 145, 175, 231, 104, 91, 102, 94, 92, 93, - 99, 120, 160, 187, 187, 184, 185, 171, 107, 81, 150, 198, 185, 164, 179, 157, - 150, 143, 134, 158, 138, 142, 42, 61, 66, 56, 50, 45, 39, 36, 34, 32, - 47, 49, 53, 57, 66, 72, 80, 89, 94, 109, 82, 93, 91, 76, 92, 70, - 84, 71, 58, 101, 100, 95, 93, 92, 92, 91, 94, 96, 100, 110, 119, 124, - 129, 141, 153, 161, 163, 178, 196, 200, 202, 227, 220, 233, 129, 142, 138, 115, - 133, 141, 143, 77, 140, 148, 139, 141, 139, 128, 144, 165, 161, 165, 176, 193, - 147, 160, 152, 199, 201, 185, 171, 187, 146, 198, 187, 203, 185, 190, 161, 212, - 194, 200, 219, 207, 201, 197, 176, 166, 234, 212, 111, 79, 105, 101, 98, 98, - 108, 143, 175, 187, 204, 188, 196, 137, 56, 74, 124, 179, 164, 131, 161, 151, - 166, 90, 89, 151, 161, 127, 40, 63, 65, 56, 49, 44, 39, 35, 34, 33, - 47, 49, 53, 57, 65, 71, 79, 88, 92, 107, 85, 79, 65, 75, 88, 58, - 77, 57, 67, 107, 100, 95, 93, 93, 90, 90, 93, 98, 106, 110, 116, 118, - 122, 136, 147, 152, 156, 171, 185, 184, 196, 213, 213, 230, 150, 139, 139, 131, - 148, 147, 145, 73, 135, 151, 141, 135, 136, 129, 137, 160, 157, 177, 183, 192, - 173, 153, 173, 193, 162, 119, 131, 190, 181, 205, 188, 169, 175, 202, 195, 199, - 192, 153, 157, 197, 201, 207, 198, 210, 197, 129, 131, 63, 106, 106, 102, 103, - 117, 156, 155, 140, 179, 175, 173, 61, 65, 110, 126, 141, 129, 130, 141, 134, - 165, 111, 80, 139, 127, 64, 37, 67, 62, 55, 47, 43, 37, 34, 33, 33, - 48, 49, 54, 58, 63, 70, 79, 88, 92, 105, 80, 69, 68, 77, 67, 54, - 107, 66, 74, 103, 100, 95, 93, 92, 89, 90, 94, 99, 107, 110, 113, 119, - 128, 137, 147, 153, 157, 164, 174, 177, 195, 197, 206, 215, 166, 155, 157, 148, - 147, 154, 153, 68, 128, 152, 146, 134, 132, 124, 120, 163, 165, 186, 181, 185, - 182, 157, 172, 148, 70, 74, 99, 169, 184, 191, 175, 182, 186, 189, 190, 189, - 102, 62, 83, 128, 181, 193, 159, 189, 154, 132, 124, 52, 105, 106, 102, 105, - 120, 153, 149, 157, 168, 147, 124, 43, 96, 129, 135, 137, 131, 152, 120, 127, - 143, 119, 75, 92, 69, 42, 63, 69, 60, 53, 45, 41, 35, 32, 32, 32, - 49, 50, 54, 58, 62, 70, 78, 87, 96, 103, 71, 75, 96, 92, 76, 90, - 116, 67, 79, 109, 103, 97, 94, 92, 91, 93, 97, 100, 101, 106, 113, 121, - 130, 138, 145, 151, 156, 156, 162, 177, 197, 178, 198, 206, 155, 163, 169, 161, - 160, 170, 161, 70, 127, 146, 145, 140, 132, 125, 125, 142, 165, 182, 180, 198, - 188, 169, 175, 79, 61, 111, 133, 151, 189, 203, 203, 199, 170, 164, 171, 126, - 47, 94, 118, 118, 131, 122, 94, 137, 151, 169, 159, 43, 104, 103, 102, 106, - 126, 155, 181, 184, 173, 141, 110, 50, 112, 128, 129, 136, 149, 162, 112, 133, - 106, 111, 61, 93, 82, 69, 72, 69, 59, 51, 43, 39, 33, 30, 30, 31, - 49, 50, 54, 58, 62, 69, 77, 87, 94, 107, 91, 96, 111, 109, 101, 120, - 113, 65, 78, 110, 106, 100, 97, 96, 95, 94, 95, 97, 99, 105, 112, 121, - 130, 134, 142, 149, 148, 147, 155, 174, 187, 171, 191, 198, 157, 160, 146, 165, - 172, 171, 170, 73, 126, 143, 142, 144, 136, 126, 131, 153, 178, 182, 175, 194, - 195, 184, 132, 51, 103, 128, 144, 151, 205, 220, 217, 218, 180, 197, 183, 63, - 75, 125, 130, 133, 160, 174, 177, 195, 182, 199, 175, 39, 102, 103, 103, 108, - 144, 174, 178, 172, 175, 155, 120, 48, 122, 124, 131, 140, 148, 147, 104, 128, - 131, 127, 48, 86, 90, 80, 74, 67, 58, 50, 42, 38, 33, 30, 30, 31, - 48, 50, 53, 57, 61, 69, 76, 86, 91, 110, 110, 114, 111, 110, 108, 123, - 97, 57, 76, 112, 108, 103, 100, 98, 95, 93, 92, 94, 98, 104, 111, 118, - 126, 132, 138, 143, 139, 140, 152, 172, 174, 165, 186, 190, 161, 160, 174, 174, - 176, 169, 181, 71, 124, 141, 139, 141, 135, 128, 133, 156, 180, 176, 183, 212, - 210, 161, 71, 70, 126, 130, 139, 154, 202, 213, 223, 221, 183, 196, 183, 48, - 106, 135, 132, 129, 177, 212, 210, 217, 211, 194, 166, 36, 102, 105, 106, 116, - 152, 167, 158, 143, 170, 164, 128, 56, 121, 129, 134, 141, 130, 128, 124, 137, - 147, 133, 43, 82, 93, 79, 71, 65, 56, 49, 42, 37, 32, 30, 30, 31, - 47, 49, 53, 57, 61, 68, 76, 86, 96, 108, 105, 100, 97, 99, 100, 104, - 95, 64, 78, 115, 111, 105, 101, 98, 90, 90, 91, 93, 98, 104, 111, 116, - 123, 131, 133, 133, 133, 138, 151, 168, 162, 163, 181, 192, 156, 167, 189, 163, - 189, 186, 179, 67, 123, 139, 136, 135, 133, 130, 133, 149, 169, 174, 199, 210, - 178, 80, 39, 91, 130, 143, 132, 151, 197, 216, 223, 199, 168, 181, 146, 57, - 123, 135, 139, 145, 158, 182, 166, 189, 189, 166, 146, 35, 103, 108, 107, 115, - 143, 153, 167, 161, 172, 153, 117, 59, 122, 127, 133, 136, 134, 146, 154, 150, - 137, 110, 42, 80, 88, 75, 68, 63, 54, 47, 40, 37, 33, 31, 30, 30, - 47, 49, 52, 56, 60, 67, 75, 85, 94, 108, 106, 101, 100, 100, 111, 108, - 113, 81, 81, 117, 114, 106, 100, 96, 89, 90, 91, 95, 99, 105, 112, 116, - 121, 129, 127, 127, 131, 139, 151, 162, 153, 162, 174, 187, 136, 157, 145, 150, - 186, 165, 160, 73, 124, 138, 134, 133, 132, 131, 136, 155, 176, 189, 201, 171, - 84, 99, 63, 100, 136, 137, 136, 142, 161, 186, 197, 160, 148, 190, 130, 68, - 133, 134, 136, 137, 153, 182, 159, 203, 175, 164, 134, 37, 106, 110, 109, 115, - 129, 141, 166, 155, 158, 146, 120, 54, 127, 123, 134, 141, 149, 150, 142, 138, - 122, 121, 43, 80, 86, 75, 69, 60, 52, 46, 40, 36, 33, 31, 30, 30, - 47, 49, 52, 56, 60, 67, 75, 85, 91, 108, 106, 101, 98, 94, 119, 118, - 121, 88, 77, 118, 114, 105, 98, 96, 94, 93, 93, 96, 100, 106, 113, 117, - 120, 124, 123, 126, 130, 140, 150, 156, 147, 161, 167, 179, 138, 163, 163, 154, - 153, 130, 137, 66, 125, 138, 134, 132, 128, 127, 136, 155, 181, 198, 180, 129, - 119, 203, 75, 107, 134, 131, 137, 141, 156, 180, 169, 146, 152, 194, 133, 74, - 136, 129, 133, 139, 142, 170, 170, 193, 164, 155, 119, 39, 109, 112, 109, 118, - 126, 147, 167, 153, 165, 153, 130, 63, 122, 129, 135, 144, 149, 135, 129, 133, - 125, 103, 38, 79, 85, 73, 65, 59, 51, 45, 40, 36, 32, 31, 30, 30, - 48, 49, 51, 54, 60, 66, 74, 84, 93, 108, 103, 89, 88, 96, 122, 124, - 124, 104, 69, 118, 114, 104, 98, 96, 95, 94, 96, 98, 102, 106, 115, 118, - 119, 118, 119, 128, 130, 142, 152, 148, 144, 159, 162, 175, 176, 181, 188, 176, - 160, 155, 156, 61, 124, 136, 133, 133, 126, 122, 133, 156, 187, 170, 124, 143, - 216, 235, 74, 102, 127, 128, 133, 144, 181, 180, 149, 154, 170, 191, 135, 74, - 131, 127, 129, 132, 135, 159, 152, 175, 152, 137, 113, 39, 110, 114, 111, 117, - 130, 159, 170, 160, 176, 166, 146, 75, 115, 132, 135, 142, 144, 119, 135, 142, - 140, 75, 45, 81, 83, 71, 62, 58, 49, 44, 39, 35, 33, 32, 30, 30, - 49, 49, 51, 53, 59, 66, 73, 83, 92, 108, 104, 89, 94, 109, 118, 130, - 126, 107, 69, 114, 113, 104, 100, 99, 97, 96, 98, 100, 103, 108, 115, 117, - 115, 115, 123, 132, 136, 146, 145, 141, 144, 158, 159, 177, 190, 170, 180, 186, - 187, 195, 160, 64, 123, 136, 133, 133, 126, 122, 130, 146, 161, 124, 174, 220, - 237, 194, 56, 101, 124, 124, 131, 142, 171, 162, 160, 183, 185, 184, 100, 73, - 128, 127, 125, 134, 145, 164, 171, 169, 140, 135, 134, 40, 111, 116, 112, 117, - 127, 147, 151, 149, 153, 146, 132, 76, 102, 137, 149, 146, 145, 125, 142, 143, - 127, 50, 48, 82, 80, 69, 62, 57, 49, 43, 37, 35, 34, 32, 30, 30, - 48, 48, 50, 53, 59, 65, 72, 82, 90, 105, 107, 95, 104, 120, 110, 139, - 141, 122, 68, 107, 114, 106, 103, 104, 100, 100, 101, 103, 105, 111, 116, 114, - 109, 116, 128, 131, 145, 151, 142, 139, 147, 156, 153, 173, 143, 166, 130, 171, - 191, 156, 124, 69, 123, 138, 133, 131, 127, 124, 130, 132, 116, 184, 239, 232, - 201, 166, 58, 99, 124, 124, 131, 142, 163, 188, 173, 194, 188, 182, 98, 73, - 128, 126, 125, 133, 157, 159, 182, 171, 144, 144, 149, 41, 113, 118, 115, 118, - 121, 126, 124, 140, 135, 134, 132, 116, 105, 128, 141, 136, 140, 131, 125, 120, - 74, 29, 65, 83, 76, 68, 62, 56, 48, 43, 37, 36, 34, 32, 30, 30, - 47, 48, 49, 52, 57, 64, 71, 81, 90, 105, 112, 106, 107, 125, 116, 152, - 158, 138, 69, 103, 118, 110, 104, 105, 102, 101, 103, 105, 108, 114, 116, 110, - 109, 120, 127, 139, 143, 144, 144, 138, 149, 153, 150, 167, 70, 83, 126, 190, - 158, 100, 142, 72, 122, 139, 133, 130, 127, 125, 129, 126, 181, 244, 236, 208, - 205, 194, 71, 98, 125, 125, 131, 135, 148, 205, 166, 187, 176, 176, 108, 72, - 127, 126, 126, 128, 160, 155, 168, 169, 156, 152, 143, 42, 114, 120, 115, 119, - 121, 122, 118, 131, 131, 142, 144, 146, 125, 125, 128, 111, 118, 125, 113, 90, - 38, 44, 82, 83, 72, 67, 61, 54, 47, 42, 36, 35, 34, 31, 30, 30, - 47, 47, 49, 52, 56, 62, 69, 80, 91, 104, 116, 115, 116, 132, 127, 158, - 148, 118, 76, 90, 118, 114, 106, 106, 104, 104, 106, 108, 112, 116, 117, 111, - 114, 119, 135, 168, 152, 133, 139, 134, 150, 149, 147, 166, 133, 115, 130, 131, - 78, 127, 186, 72, 121, 139, 134, 131, 127, 124, 130, 156, 225, 213, 202, 208, - 200, 215, 68, 100, 125, 126, 132, 131, 156, 196, 152, 185, 180, 182, 112, 71, - 127, 127, 126, 131, 158, 164, 167, 171, 160, 156, 147, 41, 114, 121, 116, 118, - 124, 128, 127, 123, 124, 133, 136, 153, 136, 123, 120, 109, 127, 121, 91, 57, - 39, 72, 85, 81, 70, 66, 59, 52, 46, 41, 37, 36, 33, 31, 30, 30, - 47, 47, 49, 51, 55, 62, 69, 79, 89, 100, 117, 120, 123, 138, 133, 158, - 136, 109, 97, 76, 114, 117, 108, 109, 109, 109, 111, 113, 115, 116, 116, 114, - 117, 122, 150, 192, 173, 129, 124, 135, 150, 144, 146, 168, 167, 193, 160, 124, - 121, 209, 192, 65, 121, 137, 135, 133, 127, 123, 130, 167, 217, 171, 163, 191, - 173, 218, 67, 101, 126, 126, 132, 141, 187, 190, 143, 168, 176, 179, 120, 72, - 127, 127, 127, 136, 146, 164, 173, 171, 158, 154, 151, 40, 113, 120, 115, 115, - 123, 130, 136, 128, 125, 129, 138, 158, 126, 108, 113, 126, 140, 96, 53, 46, - 68, 91, 85, 79, 69, 66, 58, 51, 45, 40, 36, 35, 33, 31, 30, 30, - 46, 47, 49, 51, 55, 62, 69, 79, 87, 97, 113, 118, 117, 137, 134, 159, - 153, 152, 137, 82, 112, 119, 111, 111, 113, 113, 114, 116, 115, 113, 114, 116, - 120, 134, 160, 186, 181, 121, 102, 133, 147, 140, 148, 160, 190, 195, 195, 200, - 211, 228, 210, 73, 122, 136, 135, 134, 127, 124, 133, 164, 190, 193, 208, 165, - 215, 220, 66, 103, 129, 128, 132, 142, 167, 165, 151, 158, 146, 133, 77, 71, - 127, 127, 126, 135, 124, 143, 167, 167, 160, 152, 144, 40, 112, 120, 115, 113, - 122, 130, 140, 134, 133, 140, 149, 135, 99, 105, 125, 122, 89, 49, 56, 81, - 103, 91, 85, 77, 69, 68, 57, 49, 44, 40, 35, 35, 33, 30, 30, 30, - 45, 49, 50, 53, 56, 62, 69, 79, 85, 93, 101, 111, 122, 135, 132, 150, - 165, 152, 150, 97, 107, 121, 114, 109, 114, 112, 117, 113, 117, 112, 115, 117, - 129, 149, 159, 150, 180, 88, 78, 132, 141, 138, 146, 159, 194, 191, 205, 214, - 219, 231, 218, 74, 120, 135, 132, 130, 128, 132, 139, 162, 179, 193, 226, 215, - 200, 186, 69, 107, 135, 129, 129, 133, 123, 143, 174, 189, 195, 172, 103, 69, - 122, 127, 123, 134, 106, 97, 113, 143, 156, 155, 139, 44, 119, 122, 117, 115, - 126, 136, 137, 118, 143, 143, 112, 67, 69, 72, 61, 60, 65, 78, 96, 104, - 101, 91, 83, 77, 73, 69, 60, 48, 41, 38, 34, 33, 30, 29, 30, 30, - 45, 48, 50, 53, 56, 62, 69, 77, 83, 89, 95, 107, 114, 121, 135, 144, - 151, 137, 141, 134, 93, 120, 115, 115, 117, 117, 119, 114, 113, 111, 114, 125, - 143, 182, 165, 175, 148, 51, 91, 132, 142, 141, 150, 161, 194, 178, 192, 213, - 195, 220, 189, 75, 118, 136, 135, 134, 129, 129, 139, 165, 198, 204, 191, 183, - 159, 157, 56, 108, 135, 130, 125, 134, 153, 189, 189, 190, 195, 175, 104, 64, - 121, 127, 126, 134, 142, 144, 120, 114, 127, 130, 120, 42, 113, 123, 115, 121, - 129, 130, 121, 127, 146, 138, 65, 57, 108, 115, 110, 113, 113, 112, 116, 114, - 103, 90, 84, 77, 73, 68, 59, 48, 42, 37, 33, 32, 29, 28, 30, 30, - 46, 48, 49, 52, 55, 60, 66, 73, 79, 86, 91, 101, 108, 116, 137, 130, - 126, 126, 158, 151, 112, 107, 126, 115, 119, 116, 117, 119, 115, 113, 114, 132, - 173, 191, 173, 173, 99, 55, 111, 138, 144, 141, 152, 169, 187, 180, 200, 199, - 185, 201, 153, 90, 109, 142, 133, 129, 130, 132, 136, 166, 202, 202, 164, 120, - 150, 152, 56, 111, 134, 128, 126, 141, 178, 200, 171, 181, 181, 166, 98, 69, - 120, 119, 125, 128, 147, 155, 160, 154, 126, 115, 120, 39, 115, 119, 115, 117, - 126, 122, 114, 118, 130, 133, 91, 91, 145, 142, 143, 141, 138, 129, 124, 120, - 108, 94, 87, 79, 73, 67, 59, 50, 43, 38, 33, 32, 29, 28, 30, 30, - 46, 48, 48, 50, 54, 58, 63, 69, 77, 83, 89, 98, 109, 126, 153, 155, - 156, 149, 164, 162, 136, 117, 115, 123, 123, 123, 121, 121, 116, 123, 131, 164, - 187, 186, 179, 153, 57, 84, 119, 141, 148, 142, 156, 174, 183, 189, 205, 196, - 189, 211, 187, 134, 100, 135, 135, 132, 131, 133, 134, 155, 189, 180, 197, 172, - 120, 131, 68, 99, 135, 130, 126, 144, 181, 178, 161, 180, 173, 163, 110, 67, - 118, 119, 123, 131, 152, 125, 155, 155, 160, 154, 139, 56, 107, 119, 119, 122, - 128, 116, 122, 123, 114, 111, 112, 92, 116, 120, 138, 143, 140, 137, 132, 124, - 115, 102, 91, 83, 75, 67, 59, 51, 44, 38, 34, 32, 29, 28, 30, 30, - 46, 47, 47, 49, 52, 56, 59, 65, 74, 81, 87, 93, 101, 111, 134, 156, - 166, 167, 168, 160, 148, 150, 114, 126, 120, 126, 120, 117, 123, 138, 155, 185, - 193, 185, 164, 87, 62, 103, 122, 138, 149, 149, 165, 174, 190, 193, 194, 192, - 192, 204, 200, 192, 136, 132, 138, 130, 131, 133, 140, 162, 176, 178, 200, 195, - 119, 123, 98, 97, 129, 131, 129, 163, 180, 161, 166, 179, 170, 166, 124, 61, - 115, 125, 121, 127, 147, 102, 160, 150, 152, 150, 146, 93, 92, 119, 115, 116, - 126, 104, 119, 101, 111, 111, 115, 88, 58, 85, 122, 110, 110, 118, 121, 122, - 120, 110, 97, 88, 77, 68, 60, 53, 45, 39, 34, 32, 29, 28, 30, 30, - 46, 47, 47, 48, 51, 54, 57, 62, 71, 77, 82, 89, 101, 108, 115, 134, - 132, 158, 176, 136, 128, 140, 133, 146, 127, 116, 121, 141, 174, 169, 136, 138, - 174, 170, 109, 50, 94, 112, 121, 138, 167, 181, 199, 194, 195, 195, 201, 207, - 201, 201, 192, 179, 187, 200, 185, 111, 128, 151, 158, 175, 178, 171, 169, 184, - 194, 190, 174, 138, 116, 123, 153, 183, 163, 152, 158, 171, 166, 156, 108, 88, - 114, 111, 110, 105, 113, 91, 163, 124, 142, 144, 135, 118, 112, 106, 106, 119, - 129, 81, 100, 98, 125, 118, 91, 70, 87, 116, 102, 73, 75, 83, 87, 96, - 103, 106, 103, 92, 81, 69, 61, 54, 46, 39, 34, 32, 29, 28, 30, 30, - 46, 47, 46, 47, 50, 52, 56, 60, 68, 74, 79, 84, 88, 101, 108, 119, - 125, 155, 157, 131, 104, 108, 127, 152, 149, 138, 147, 186, 195, 156, 145, 175, - 168, 132, 63, 84, 107, 113, 116, 131, 171, 192, 203, 195, 189, 195, 209, 210, - 198, 204, 188, 177, 200, 193, 178, 85, 125, 179, 177, 175, 182, 159, 179, 196, - 179, 179, 174, 160, 106, 114, 170, 170, 139, 150, 159, 168, 163, 144, 118, 124, - 107, 88, 91, 96, 101, 106, 155, 138, 139, 134, 127, 128, 129, 92, 94, 115, - 119, 64, 70, 79, 103, 109, 97, 97, 113, 117, 91, 78, 83, 88, 83, 82, - 86, 94, 102, 95, 81, 72, 61, 56, 47, 40, 35, 33, 30, 29, 30, 30, - 46, 46, 45, 46, 49, 50, 55, 58, 65, 72, 77, 83, 89, 94, 103, 110, - 113, 150, 140, 151, 157, 158, 175, 176, 186, 170, 177, 220, 203, 194, 190, 212, - 169, 73, 71, 111, 113, 110, 114, 131, 177, 191, 197, 182, 181, 192, 202, 197, - 201, 196, 176, 187, 206, 186, 162, 72, 129, 189, 177, 169, 174, 174, 192, 187, - 158, 155, 161, 160, 94, 101, 164, 144, 135, 155, 160, 162, 161, 137, 155, 103, - 86, 70, 71, 55, 70, 120, 156, 141, 137, 132, 129, 132, 119, 77, 73, 116, - 124, 100, 97, 116, 115, 118, 105, 105, 127, 116, 104, 98, 105, 104, 95, 90, - 81, 75, 80, 91, 84, 75, 62, 58, 49, 42, 37, 34, 31, 29, 30, 30, - 45, 46, 45, 45, 49, 50, 54, 57, 62, 68, 73, 80, 86, 90, 97, 105, - 110, 113, 124, 157, 171, 181, 193, 196, 214, 138, 198, 216, 175, 191, 187, 155, - 79, 72, 108, 113, 111, 109, 113, 126, 159, 161, 162, 160, 166, 178, 190, 191, - 193, 187, 183, 195, 204, 181, 173, 70, 121, 143, 123, 141, 161, 171, 184, 177, - 161, 159, 153, 135, 78, 102, 161, 153, 155, 162, 140, 117, 102, 54, 60, 66, - 93, 62, 111, 123, 125, 158, 154, 138, 135, 130, 127, 131, 118, 81, 77, 115, - 127, 116, 108, 118, 125, 130, 91, 102, 126, 100, 96, 91, 94, 86, 80, 81, - 76, 71, 60, 77, 88, 75, 64, 60, 51, 44, 38, 35, 31, 29, 30, 30, - 44, 45, 44, 45, 47, 48, 52, 54, 60, 65, 70, 77, 82, 86, 92, 98, - 103, 107, 111, 123, 160, 161, 179, 196, 180, 164, 213, 191, 140, 132, 77, 51, - 81, 105, 114, 114, 106, 109, 113, 120, 135, 115, 104, 104, 107, 111, 117, 119, - 112, 102, 102, 111, 116, 105, 108, 71, 118, 112, 86, 83, 90, 97, 99, 102, - 97, 94, 83, 78, 64, 99, 132, 105, 90, 80, 61, 48, 53, 48, 66, 83, - 70, 81, 127, 108, 85, 94, 81, 78, 76, 75, 74, 82, 69, 58, 76, 110, - 127, 123, 101, 106, 120, 101, 88, 117, 102, 72, 78, 83, 87, 80, 76, 69, - 71, 71, 56, 57, 82, 78, 68, 62, 53, 47, 39, 35, 32, 30, 30, 30, - 44, 44, 43, 44, 46, 47, 50, 52, 57, 64, 68, 74, 79, 83, 89, 93, - 99, 103, 107, 101, 92, 94, 120, 128, 105, 148, 143, 91, 79, 54, 66, 105, - 112, 115, 111, 103, 102, 107, 112, 115, 117, 98, 90, 94, 94, 92, 95, 106, - 103, 94, 92, 97, 98, 100, 96, 97, 115, 111, 96, 91, 92, 92, 91, 90, - 89, 92, 91, 86, 86, 98, 103, 94, 86, 83, 84, 84, 83, 77, 83, 79, - 76, 91, 98, 85, 74, 80, 80, 77, 80, 83, 85, 85, 83, 84, 101, 108, - 121, 131, 114, 98, 93, 72, 101, 98, 77, 78, 80, 83, 86, 82, 80, 72, - 68, 61, 55, 41, 66, 82, 71, 63, 54, 47, 40, 36, 32, 31, 31, 31, - 44, 44, 43, 44, 46, 46, 48, 50, 55, 61, 65, 71, 75, 79, 85, 88, - 91, 95, 105, 113, 111, 102, 93, 81, 75, 70, 70, 69, 81, 85, 94, 107, - 107, 107, 102, 97, 98, 105, 109, 110, 108, 104, 107, 112, 114, 112, 117, 123, - 115, 109, 107, 108, 108, 112, 102, 106, 104, 109, 106, 104, 104, 103, 104, 105, - 102, 99, 100, 99, 97, 96, 97, 100, 102, 102, 101, 98, 100, 94, 97, 87, - 93, 91, 97, 92, 92, 91, 88, 84, 88, 92, 95, 93, 100, 98, 101, 109, - 116, 133, 131, 113, 80, 95, 98, 78, 75, 87, 77, 81, 80, 78, 73, 66, - 62, 60, 59, 34, 54, 81, 72, 63, 54, 47, 40, 36, 33, 31, 32, 32, - 43, 43, 43, 44, 46, 45, 48, 50, 53, 59, 62, 67, 71, 76, 81, 83, - 85, 94, 97, 103, 104, 106, 102, 99, 103, 100, 97, 98, 92, 95, 106, 104, - 104, 98, 99, 94, 95, 104, 107, 107, 101, 105, 110, 111, 114, 109, 113, 123, - 115, 105, 103, 104, 107, 108, 103, 102, 101, 101, 102, 104, 103, 102, 102, 102, - 101, 97, 97, 96, 91, 91, 89, 97, 102, 99, 97, 98, 98, 94, 92, 87, - 85, 86, 86, 87, 84, 86, 84, 84, 86, 89, 92, 91, 97, 96, 100, 105, - 115, 121, 110, 99, 93, 92, 76, 71, 78, 80, 67, 72, 71, 73, 68, 62, - 62, 67, 61, 34, 48, 76, 73, 63, 54, 47, 40, 37, 33, 31, 32, 32, - 43, 44, 44, 45, 44, 46, 49, 51, 51, 56, 60, 63, 68, 72, 78, 80, - 85, 90, 93, 97, 99, 99, 98, 99, 102, 98, 99, 98, 98, 103, 104, 100, - 99, 96, 93, 91, 93, 99, 101, 100, 98, 100, 105, 106, 107, 106, 109, 118, - 111, 101, 97, 99, 102, 103, 100, 100, 100, 99, 99, 99, 99, 98, 97, 96, - 94, 93, 92, 92, 90, 90, 88, 92, 93, 92, 91, 91, 91, 90, 89, 85, - 85, 82, 82, 83, 82, 82, 82, 83, 83, 86, 87, 89, 93, 95, 101, 107, - 110, 80, 80, 93, 98, 82, 102, 94, 84, 69, 59, 56, 61, 61, 56, 60, - 58, 62, 49, 37, 40, 74, 70, 64, 54, 47, 40, 37, 33, 31, 32, 31, - 43, 44, 45, 45, 45, 48, 50, 52, 52, 54, 59, 61, 64, 68, 73, 77, - 81, 85, 89, 90, 92, 93, 93, 94, 94, 94, 93, 93, 96, 101, 101, 98, - 96, 92, 89, 88, 91, 94, 96, 95, 94, 96, 101, 103, 104, 103, 105, 113, - 108, 98, 94, 95, 98, 100, 97, 98, 99, 98, 97, 97, 96, 95, 94, 92, - 90, 90, 89, 88, 88, 86, 86, 86, 85, 84, 84, 85, 85, 84, 83, 83, - 82, 81, 81, 81, 81, 81, 81, 83, 82, 84, 85, 87, 91, 94, 101, 103, - 99, 84, 98, 96, 71, 60, 115, 125, 116, 106, 100, 92, 83, 67, 52, 52, - 62, 58, 46, 29, 30, 72, 72, 64, 55, 47, 40, 37, 33, 31, 32, 31, - 43, 44, 45, 46, 46, 47, 50, 51, 51, 53, 57, 59, 60, 64, 68, 72, - 74, 78, 81, 82, 85, 86, 87, 88, 87, 87, 88, 88, 91, 95, 94, 92, - 90, 87, 84, 83, 86, 89, 91, 90, 89, 91, 96, 98, 99, 97, 100, 106, - 102, 94, 90, 90, 92, 94, 93, 93, 93, 92, 91, 91, 90, 90, 88, 86, - 85, 84, 83, 82, 81, 80, 80, 79, 78, 77, 76, 79, 78, 77, 77, 77, - 77, 76, 75, 75, 75, 75, 75, 77, 77, 78, 81, 83, 87, 91, 99, 96, - 78, 76, 87, 77, 46, 47, 117, 130, 128, 126, 126, 121, 115, 105, 90, 52, - 54, 47, 33, 22, 32, 71, 71, 64, 53, 46, 39, 36, 32, 31, 32, 31, - 43, 44, 45, 46, 46, 47, 49, 50, 49, 51, 55, 56, 59, 61, 66, 68, - 70, 73, 76, 77, 80, 82, 84, 84, 83, 83, 84, 85, 88, 90, 89, 87, - 86, 84, 81, 81, 84, 87, 88, 86, 85, 87, 91, 93, 94, 92, 94, 101, - 98, 91, 86, 85, 88, 90, 89, 89, 89, 88, 88, 87, 87, 86, 85, 82, - 81, 80, 79, 77, 77, 76, 75, 73, 73, 72, 71, 73, 73, 72, 71, 73, - 73, 72, 72, 72, 72, 72, 72, 72, 73, 75, 77, 80, 85, 89, 99, 94, - 68, 61, 55, 64, 46, 52, 115, 117, 118, 121, 123, 124, 125, 124, 122, 62, - 34, 26, 24, 27, 41, 71, 68, 63, 52, 45, 38, 36, 32, 30, 31, 30, - 43, 44, 45, 46, 46, 47, 48, 49, 48, 50, 52, 54, 57, 59, 63, 64, - 67, 70, 72, 73, 75, 77, 80, 80, 78, 79, 81, 83, 86, 86, 84, 83, - 82, 81, 79, 79, 82, 85, 85, 83, 81, 82, 85, 88, 90, 87, 88, 95, - 93, 87, 83, 81, 84, 86, 86, 84, 86, 85, 84, 84, 83, 82, 81, 78, - 77, 76, 75, 73, 72, 72, 71, 69, 69, 68, 67, 68, 68, 67, 67, 69, - 69, 68, 67, 67, 67, 67, 67, 68, 69, 72, 75, 77, 82, 88, 98, 91, - 71, 62, 50, 75, 55, 61, 118, 113, 113, 115, 118, 120, 120, 120, 125, 78, - 32, 22, 47, 36, 43, 70, 69, 61, 51, 43, 37, 35, 31, 30, 30, 29, - 43, 44, 45, 46, 46, 47, 47, 48, 48, 49, 51, 52, 54, 56, 58, 60, - 63, 65, 66, 67, 69, 71, 74, 75, 73, 75, 77, 80, 83, 81, 79, 78, - 77, 75, 74, 75, 78, 80, 80, 78, 77, 78, 80, 83, 85, 82, 83, 89, - 88, 84, 78, 75, 78, 81, 81, 80, 80, 79, 78, 78, 78, 77, 76, 74, - 72, 72, 71, 69, 68, 67, 66, 66, 66, 65, 64, 63, 63, 62, 62, 64, - 63, 62, 62, 61, 61, 61, 61, 62, 64, 67, 70, 73, 79, 85, 95, 90, - 75, 68, 65, 85, 59, 62, 118, 112, 111, 112, 113, 115, 118, 121, 123, 72, - 40, 45, 65, 33, 46, 70, 69, 61, 51, 43, 37, 34, 31, 29, 30, 29, - 42, 43, 44, 45, 45, 46, 46, 47, 48, 49, 50, 51, 51, 53, 55, 56, - 59, 61, 62, 63, 64, 67, 69, 70, 69, 71, 74, 77, 80, 77, 75, 73, - 72, 70, 69, 71, 74, 75, 75, 75, 73, 74, 76, 79, 80, 77, 78, 83, - 84, 80, 74, 71, 74, 77, 77, 76, 75, 74, 73, 73, 73, 72, 71, 70, - 69, 68, 67, 65, 64, 63, 62, 63, 62, 61, 61, 59, 59, 58, 57, 59, - 60, 59, 58, 58, 58, 58, 59, 60, 60, 63, 67, 70, 75, 82, 93, 94, - 73, 62, 69, 75, 57, 60, 113, 115, 113, 113, 115, 114, 116, 119, 106, 38, - 33, 60, 49, 24, 59, 73, 62, 59, 50, 42, 36, 34, 31, 29, 30, 29, - 42, 43, 43, 44, 45, 45, 46, 47, 49, 49, 50, 51, 52, 53, 55, 55, - 55, 57, 59, 61, 64, 65, 67, 68, 67, 69, 73, 77, 77, 75, 73, 71, - 68, 66, 67, 69, 72, 73, 72, 72, 74, 76, 78, 78, 76, 75, 76, 81, - 82, 79, 73, 71, 72, 74, 75, 75, 74, 72, 70, 70, 70, 69, 68, 66, - 66, 65, 64, 64, 63, 62, 61, 59, 58, 57, 57, 56, 56, 55, 54, 57, - 57, 57, 57, 57, 56, 56, 57, 58, 59, 61, 63, 67, 74, 80, 91, 98, - 73, 52, 66, 62, 52, 50, 95, 113, 117, 119, 121, 122, 122, 112, 68, 27, - 46, 57, 35, 36, 71, 73, 61, 56, 48, 43, 37, 34, 32, 30, 28, 29, - 42, 43, 43, 44, 45, 45, 46, 47, 49, 50, 51, 51, 51, 51, 53, 54, - 54, 55, 57, 58, 60, 61, 63, 64, 65, 67, 71, 74, 73, 72, 70, 68, - 67, 66, 67, 68, 69, 71, 70, 68, 69, 71, 73, 73, 71, 70, 71, 76, - 78, 75, 70, 67, 68, 69, 71, 72, 72, 70, 68, 67, 66, 65, 65, 64, - 65, 64, 63, 61, 60, 59, 58, 58, 57, 56, 56, 55, 55, 54, 53, 55, - 55, 55, 55, 54, 54, 54, 54, 54, 55, 57, 60, 65, 71, 77, 88, 96, - 72, 43, 57, 47, 43, 37, 63, 99, 120, 123, 118, 116, 92, 63, 45, 37, - 57, 45, 21, 51, 75, 66, 62, 55, 47, 42, 36, 33, 31, 30, 28, 29, - 42, 43, 43, 44, 45, 45, 46, 47, 49, 50, 51, 50, 49, 49, 51, 51, - 51, 52, 54, 56, 57, 58, 60, 62, 64, 66, 69, 71, 69, 68, 66, 66, - 65, 65, 66, 67, 68, 69, 68, 66, 65, 67, 69, 69, 67, 66, 67, 72, - 74, 71, 66, 64, 64, 66, 67, 69, 69, 67, 65, 64, 63, 62, 61, 62, - 62, 61, 60, 58, 57, 56, 56, 55, 55, 54, 53, 53, 52, 51, 50, 51, - 52, 52, 52, 51, 51, 51, 51, 52, 52, 54, 56, 62, 68, 74, 82, 89, - 81, 48, 40, 39, 41, 39, 42, 54, 68, 70, 69, 68, 48, 32, 41, 54, - 54, 28, 37, 67, 76, 61, 61, 52, 45, 40, 35, 32, 31, 30, 28, 29, - 42, 43, 43, 44, 45, 45, 46, 47, 50, 51, 50, 50, 48, 48, 48, 49, - 48, 50, 51, 53, 55, 57, 58, 60, 63, 66, 69, 69, 67, 66, 65, 64, - 62, 62, 64, 66, 67, 68, 67, 65, 64, 66, 68, 68, 66, 65, 66, 70, - 73, 71, 67, 64, 64, 65, 67, 66, 65, 63, 62, 61, 61, 60, 60, 60, - 60, 59, 59, 58, 57, 56, 55, 54, 53, 52, 51, 51, 50, 49, 49, 50, - 50, 50, 50, 49, 49, 49, 49, 51, 51, 53, 55, 61, 66, 72, 79, 82, - 90, 70, 43, 38, 38, 46, 45, 53, 52, 50, 50, 43, 44, 47, 56, 57, - 37, 28, 60, 75, 72, 59, 55, 49, 43, 39, 34, 31, 30, 30, 28, 29, - 42, 43, 43, 44, 45, 45, 46, 47, 52, 51, 49, 49, 49, 48, 48, 47, - 47, 48, 50, 51, 54, 55, 57, 58, 61, 65, 66, 65, 64, 64, 64, 63, - 58, 59, 62, 64, 65, 66, 66, 63, 63, 65, 66, 66, 65, 63, 65, 69, - 72, 70, 66, 63, 62, 64, 66, 65, 63, 62, 60, 60, 60, 59, 58, 59, - 58, 58, 57, 56, 56, 55, 54, 52, 51, 50, 49, 49, 48, 47, 47, 48, - 49, 49, 49, 47, 47, 47, 47, 50, 50, 52, 55, 58, 64, 68, 75, 77, - 84, 90, 75, 50, 42, 50, 48, 54, 55, 50, 52, 52, 42, 44, 51, 36, - 36, 64, 77, 73, 65, 57, 50, 46, 40, 37, 33, 30, 29, 30, 28, 29, - 42, 43, 43, 44, 45, 45, 46, 47, 51, 51, 49, 49, 50, 49, 48, 48, - 47, 49, 51, 52, 52, 54, 55, 56, 58, 62, 62, 61, 61, 61, 62, 60, - 57, 58, 61, 62, 63, 64, 63, 61, 61, 63, 64, 64, 63, 61, 63, 67, - 70, 68, 65, 61, 61, 62, 64, 64, 63, 61, 60, 59, 58, 58, 57, 58, - 58, 57, 57, 55, 54, 53, 53, 51, 51, 50, 49, 49, 48, 47, 47, 48, - 48, 48, 48, 47, 47, 47, 47, 47, 48, 50, 52, 55, 60, 64, 70, 69, - 78, 89, 92, 81, 63, 59, 49, 50, 47, 43, 44, 40, 46, 40, 43, 54, - 69, 81, 79, 69, 61, 54, 49, 45, 40, 37, 32, 29, 29, 30, 28, 29, - 42, 42, 43, 44, 45, 45, 46, 47, 48, 48, 47, 48, 48, 48, 48, 48, - 48, 49, 50, 51, 52, 52, 54, 55, 56, 58, 58, 57, 57, 57, 58, 57, - 56, 57, 59, 61, 61, 62, 61, 60, 60, 61, 62, 63, 61, 60, 61, 63, - 66, 66, 63, 59, 58, 59, 61, 62, 61, 59, 59, 58, 57, 56, 55, 57, - 58, 57, 56, 54, 53, 52, 51, 51, 51, 50, 49, 49, 48, 47, 47, 46, - 46, 45, 45, 44, 44, 44, 44, 43, 44, 47, 49, 51, 56, 61, 66, 67, - 75, 83, 89, 92, 80, 73, 63, 55, 48, 45, 46, 44, 48, 53, 67, 82, - 86, 80, 75, 67, 61, 53, 49, 46, 41, 38, 34, 32, 31, 30, 28, 29, - 42, 42, 43, 44, 45, 46, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, - 49, 49, 50, 52, 53, 52, 54, 55, 56, 56, 56, 56, 56, 56, 56, 55, - 55, 57, 59, 60, 62, 61, 60, 60, 59, 60, 61, 62, 61, 60, 60, 61, - 64, 65, 62, 58, 57, 57, 59, 60, 59, 58, 57, 57, 56, 55, 55, 56, - 57, 56, 55, 53, 52, 51, 51, 51, 51, 50, 49, 49, 48, 47, 47, 45, - 45, 44, 43, 43, 43, 43, 42, 40, 42, 45, 47, 50, 54, 60, 63, 67, - 72, 78, 82, 85, 84, 81, 78, 75, 69, 66, 65, 64, 69, 73, 78, 82, - 80, 77, 71, 65, 59, 52, 49, 47, 42, 38, 35, 34, 31, 29, 28, 29, - 42, 42, 43, 44, 45, 45, 46, 47, 46, 46, 46, 46, 46, 47, 48, 48, - 49, 49, 50, 51, 53, 52, 54, 55, 55, 55, 55, 55, 55, 55, 55, 54, - 55, 57, 58, 60, 61, 60, 59, 59, 59, 60, 61, 61, 61, 60, 59, 60, - 63, 64, 61, 58, 56, 57, 58, 59, 58, 57, 57, 56, 56, 55, 54, 56, - 56, 55, 55, 53, 51, 51, 50, 50, 50, 49, 48, 48, 47, 46, 46, 45, - 44, 43, 42, 42, 42, 42, 41, 39, 41, 43, 45, 47, 52, 57, 60, 63, - 67, 73, 76, 79, 82, 82, 83, 86, 83, 82, 82, 80, 80, 79, 78, 77, - 75, 70, 65, 60, 55, 49, 46, 45, 41, 37, 35, 34, 31, 29, 28, 29, - 42, 42, 43, 44, 44, 45, 45, 46, 46, 46, 46, 46, 46, 46, 47, 48, - 48, 49, 50, 50, 51, 52, 54, 55, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 56, 58, 59, 59, 59, 58, 57, 58, 59, 59, 60, 59, 59, 58, 59, - 62, 63, 60, 58, 56, 55, 57, 57, 57, 56, 55, 55, 54, 54, 53, 54, - 55, 54, 53, 52, 51, 50, 49, 49, 48, 48, 47, 46, 46, 45, 44, 44, - 43, 42, 42, 42, 42, 42, 41, 38, 39, 42, 43, 45, 49, 53, 57, 59, - 63, 68, 70, 72, 74, 76, 77, 77, 77, 78, 78, 78, 75, 73, 72, 72, - 69, 64, 59, 56, 51, 46, 43, 42, 39, 35, 33, 33, 31, 29, 28, 29, - 42, 42, 43, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 46, 47, 47, - 48, 48, 49, 50, 50, 51, 54, 55, 53, 53, 53, 53, 53, 53, 53, 53, - 54, 55, 57, 58, 59, 58, 57, 56, 57, 58, 59, 59, 59, 58, 57, 58, - 61, 62, 59, 57, 55, 54, 55, 56, 56, 55, 54, 54, 53, 52, 52, 53, - 54, 53, 52, 51, 50, 49, 49, 48, 47, 47, 46, 45, 45, 44, 43, 43, - 43, 42, 41, 41, 41, 41, 41, 38, 39, 40, 41, 43, 47, 51, 53, 56, - 59, 63, 66, 68, 70, 70, 70, 73, 75, 76, 76, 74, 72, 71, 69, 68, - 64, 59, 55, 52, 49, 43, 41, 39, 37, 34, 32, 32, 30, 29, 29, 29, - 42, 42, 43, 43, 43, 44, 45, 45, 45, 45, 45, 45, 45, 45, 46, 47, - 47, 48, 49, 49, 49, 50, 54, 54, 52, 52, 52, 52, 52, 52, 52, 52, - 53, 55, 57, 58, 58, 57, 56, 56, 56, 57, 58, 58, 58, 57, 56, 57, - 60, 61, 58, 56, 55, 53, 54, 55, 55, 54, 53, 53, 52, 51, 51, 53, - 53, 52, 51, 51, 50, 49, 49, 47, 47, 46, 45, 45, 44, 43, 42, 43, - 42, 42, 41, 41, 41, 41, 40, 37, 38, 38, 39, 41, 44, 48, 50, 53, - 55, 59, 62, 63, 65, 65, 65, 68, 71, 71, 69, 66, 65, 64, 63, 61, - 59, 54, 51, 48, 44, 39, 38, 37, 35, 32, 31, 31, 30, 29, 29, 29, - 42, 42, 43, 43, 43, 44, 45, 45, 45, 45, 45, 45, 45, 45, 46, 47, - 47, 48, 49, 49, 49, 50, 54, 54, 52, 52, 52, 52, 52, 52, 52, 52, - 53, 55, 56, 57, 57, 56, 56, 55, 55, 56, 57, 58, 57, 56, 55, 56, - 60, 60, 57, 56, 55, 53, 53, 54, 54, 53, 53, 53, 52, 51, 50, 52, - 52, 51, 51, 51, 50, 49, 48, 47, 46, 45, 45, 44, 44, 43, 42, 42, - 42, 41, 41, 41, 41, 41, 40, 37, 37, 38, 38, 40, 42, 46, 48, 49, - 52, 55, 57, 56, 58, 61, 61, 63, 66, 66, 64, 64, 61, 59, 57, 55, - 54, 50, 47, 44, 40, 36, 35, 35, 33, 31, 30, 30, 30, 29, 29, 29, - 42, 42, 43, 43, 43, 43, 43, 43, 42, 43, 43, 44, 44, 45, 46, 47, - 47, 47, 48, 49, 49, 51, 53, 53, 51, 51, 51, 50, 50, 50, 50, 51, - 53, 53, 54, 55, 55, 55, 55, 55, 55, 56, 57, 57, 56, 55, 54, 55, - 57, 59, 57, 54, 52, 50, 50, 53, 54, 53, 53, 51, 50, 50, 49, 51, - 51, 50, 50, 50, 50, 49, 48, 47, 46, 45, 45, 44, 44, 43, 43, 43, - 43, 42, 41, 41, 40, 39, 38, 37, 38, 39, 40, 40, 42, 44, 46, 49, - 51, 53, 54, 55, 55, 57, 58, 60, 60, 60, 60, 59, 57, 55, 54, 52, - 49, 46, 44, 41, 39, 36, 34, 34, 32, 30, 29, 29, 29, 29, 29, 29, - 42, 42, 42, 42, 42, 42, 42, 42, 41, 42, 43, 44, 44, 45, 46, 46, - 46, 47, 48, 49, 49, 51, 52, 52, 50, 50, 50, 50, 50, 50, 50, 51, - 52, 53, 54, 54, 54, 54, 54, 54, 54, 55, 56, 56, 55, 54, 53, 54, - 57, 58, 56, 53, 51, 50, 50, 52, 53, 53, 53, 51, 50, 49, 48, 50, - 51, 50, 49, 49, 49, 49, 48, 47, 46, 45, 45, 44, 44, 44, 44, 44, - 43, 42, 41, 41, 40, 38, 38, 38, 38, 40, 40, 40, 41, 43, 45, 46, - 47, 49, 51, 51, 52, 53, 54, 55, 55, 55, 55, 54, 52, 51, 50, 49, - 46, 43, 42, 40, 38, 35, 34, 33, 32, 30, 29, 29, 29, 29, 29, 29, - 42, 42, 42, 42, 42, 42, 42, 41, 41, 42, 42, 43, 44, 44, 45, 46, - 46, 47, 47, 48, 49, 50, 52, 51, 49, 49, 49, 49, 49, 49, 49, 50, - 52, 53, 53, 54, 53, 53, 53, 53, 54, 55, 55, 55, 54, 53, 52, 53, - 56, 58, 56, 53, 51, 49, 49, 51, 52, 52, 52, 51, 50, 49, 48, 50, - 50, 49, 49, 49, 49, 48, 47, 47, 46, 45, 45, 44, 44, 44, 44, 43, - 42, 42, 41, 41, 40, 38, 38, 39, 39, 40, 40, 40, 41, 42, 43, 43, - 45, 46, 47, 47, 47, 48, 49, 51, 51, 51, 50, 48, 47, 45, 45, 44, - 42, 40, 38, 38, 37, 34, 33, 33, 31, 30, 29, 29, 29, 29, 29, 29, - 42, 42, 42, 42, 42, 42, 42, 41, 41, 41, 42, 43, 43, 44, 44, 45, - 46, 46, 47, 48, 49, 50, 51, 50, 49, 49, 49, 49, 49, 49, 49, 49, - 51, 52, 53, 53, 52, 52, 52, 52, 53, 53, 54, 54, 53, 52, 51, 52, - 55, 57, 55, 52, 50, 49, 49, 50, 51, 51, 51, 50, 49, 48, 48, 49, - 49, 49, 48, 49, 48, 47, 47, 47, 46, 45, 45, 43, 43, 43, 43, 43, - 42, 41, 41, 41, 40, 38, 38, 39, 39, 39, 39, 39, 39, 40, 41, 43, - 43, 44, 45, 45, 45, 45, 46, 48, 48, 48, 48, 46, 44, 43, 41, 39, - 38, 37, 36, 36, 35, 33, 32, 31, 31, 30, 29, 29, 29, 29, 28, 28, - 41, 41, 41, 41, 41, 41, 41, 41, 40, 41, 42, 42, 43, 43, 44, 45, - 45, 46, 47, 48, 50, 50, 50, 48, 48, 48, 48, 48, 48, 48, 48, 49, - 51, 51, 53, 52, 51, 51, 51, 51, 52, 52, 53, 53, 52, 51, 50, 51, - 54, 56, 53, 51, 50, 48, 48, 49, 50, 50, 50, 49, 49, 48, 47, 49, - 49, 48, 48, 48, 48, 47, 46, 46, 46, 45, 45, 43, 43, 43, 43, 42, - 42, 41, 40, 40, 40, 38, 38, 39, 38, 38, 38, 38, 38, 38, 39, 43, - 43, 43, 44, 44, 43, 43, 43, 46, 46, 46, 45, 44, 42, 40, 39, 37, - 36, 34, 34, 35, 33, 31, 31, 30, 30, 30, 29, 29, 29, 29, 28, 28, - 41, 41, 41, 41, 41, 41, 41, 40, 40, 40, 41, 42, 42, 43, 44, 44, - 45, 45, 46, 47, 50, 49, 49, 48, 47, 47, 47, 47, 48, 48, 48, 49, - 50, 51, 52, 52, 50, 50, 50, 50, 51, 51, 52, 52, 51, 50, 49, 50, - 53, 55, 52, 51, 50, 48, 48, 49, 49, 49, 49, 49, 48, 47, 47, 48, - 49, 48, 47, 47, 47, 46, 46, 46, 46, 45, 45, 42, 42, 42, 42, 42, - 41, 40, 40, 40, 40, 38, 38, 40, 40, 39, 38, 39, 39, 38, 39, 41, - 41, 42, 40, 41, 41, 39, 40, 42, 42, 42, 42, 41, 39, 37, 36, 35, - 34, 33, 32, 32, 31, 30, 30, 29, 30, 30, 29, 29, 29, 29, 28, 27, - 40, 40, 40, 40, 41, 41, 41, 40, 40, 40, 41, 41, 41, 42, 43, 43, - 44, 45, 46, 47, 49, 49, 49, 48, 47, 47, 47, 47, 47, 48, 48, 48, - 50, 50, 51, 51, 50, 50, 50, 49, 50, 51, 52, 52, 50, 50, 49, 50, - 53, 55, 53, 51, 49, 48, 48, 49, 49, 49, 49, 49, 48, 48, 47, 48, - 48, 47, 47, 47, 47, 46, 46, 46, 45, 44, 44, 42, 42, 42, 42, 42, - 41, 40, 40, 40, 39, 38, 38, 39, 39, 38, 37, 38, 38, 37, 37, 39, - 39, 39, 38, 39, 39, 38, 39, 40, 40, 39, 39, 38, 37, 36, 35, 34, - 33, 32, 31, 30, 30, 29, 29, 29, 30, 29, 29, 29, 29, 29, 28, 27, - 38, 39, 39, 40, 41, 41, 41, 40, 40, 40, 41, 41, 41, 41, 42, 43, - 43, 44, 46, 48, 49, 49, 49, 49, 48, 48, 48, 47, 46, 47, 48, 48, - 49, 49, 50, 50, 50, 50, 50, 49, 49, 50, 50, 51, 50, 49, 49, 50, - 53, 55, 54, 52, 50, 50, 49, 50, 51, 51, 51, 50, 49, 48, 47, 47, - 47, 47, 47, 46, 46, 46, 46, 44, 43, 43, 42, 42, 42, 42, 42, 42, - 42, 41, 41, 40, 39, 38, 38, 37, 37, 36, 36, 36, 36, 36, 36, 37, - 37, 37, 37, 37, 37, 37, 37, 38, 37, 36, 36, 37, 36, 35, 34, 32, - 31, 30, 29, 29, 28, 28, 29, 30, 30, 29, 29, 29, 29, 29, 28, 27, - 38, 39, 39, 40, 41, 41, 41, 40, 40, 40, 41, 41, 41, 41, 42, 43, - 43, 44, 46, 48, 49, 49, 49, 49, 49, 49, 49, 48, 47, 48, 48, 48, - 49, 49, 50, 50, 50, 50, 50, 49, 49, 50, 50, 51, 50, 49, 48, 50, - 53, 55, 55, 53, 51, 50, 50, 50, 51, 51, 51, 51, 50, 49, 48, 47, - 47, 47, 47, 46, 46, 46, 46, 44, 43, 43, 42, 42, 42, 42, 42, 42, - 42, 41, 41, 40, 39, 38, 38, 37, 37, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 35, 34, 34, 35, 34, 33, 32, 30, - 30, 29, 28, 29, 28, 27, 28, 30, 30, 29, 29, 29, 29, 29, 28, 27, - 38, 39, 39, 40, 41, 41, 41, 40, 40, 40, 41, 41, 41, 41, 42, 43, - 43, 44, 46, 48, 49, 49, 49, 49, 49, 49, 49, 48, 47, 48, 48, 48, - 48, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 49, 48, 50, - 53, 55, 55, 53, 51, 50, 50, 50, 51, 51, 51, 51, 50, 49, 48, 47, - 47, 47, 47, 46, 46, 46, 46, 44, 43, 43, 42, 42, 42, 42, 42, 42, - 42, 41, 41, 40, 39, 38, 38, 37, 37, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 35, 34, 34, 34, 34, 34, 33, 33, 32, 33, 32, 31, 30, 29, - 28, 27, 27, 29, 28, 27, 28, 30, 30, 29, 29, 29, 29, 29, 28, 27, - 69, 69, 70, 72, 73, 74, 75, 76, 77, 77, 79, 80, 82, 83, 85, 86, - 87, 90, 93, 95, 97, 100, 102, 102, 102, 104, 110, 114, 116, 118, 116, 115, - 125, 127, 122, 122, 126, 129, 135, 142, 132, 139, 137, 142, 144, 144, 140, 136, - 143, 133, 130, 132, 131, 126, 122, 122, 123, 116, 112, 116, 116, 111, 105, 102, - 100, 97, 95, 97, 98, 96, 96, 95, 93, 90, 88, 85, 83, 82, 81, 78, - 77, 76, 76, 74, 72, 71, 71, 70, 69, 68, 67, 67, 66, 65, 64, 63, - 62, 61, 61, 61, 60, 59, 58, 58, 58, 58, 57, 57, 56, 55, 54, 54, - 54, 54, 54, 52, 50, 50, 49, 48, 48, 48, 46, 45, 46, 45, 45, 46, - 69, 69, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 82, 84, 86, 87, - 87, 89, 93, 95, 98, 101, 103, 104, 104, 105, 109, 113, 117, 120, 118, 117, - 126, 130, 127, 126, 128, 132, 138, 146, 138, 142, 141, 145, 147, 147, 143, 140, - 147, 137, 135, 135, 132, 126, 125, 124, 123, 117, 115, 119, 116, 111, 105, 102, - 101, 98, 98, 99, 98, 97, 96, 95, 93, 90, 88, 85, 83, 82, 81, 78, - 77, 76, 76, 74, 72, 71, 71, 70, 69, 68, 67, 67, 66, 65, 64, 63, - 62, 61, 61, 61, 60, 59, 58, 58, 58, 58, 57, 57, 56, 55, 54, 54, - 54, 54, 54, 52, 50, 50, 49, 48, 48, 48, 46, 46, 46, 46, 45, 46, - 69, 69, 70, 72, 73, 74, 75, 76, 77, 78, 80, 81, 83, 85, 87, 88, - 88, 90, 93, 96, 100, 103, 106, 108, 108, 108, 109, 113, 118, 121, 122, 121, - 127, 134, 132, 130, 130, 134, 141, 149, 144, 145, 147, 149, 150, 150, 147, 145, - 151, 142, 140, 139, 134, 127, 128, 127, 124, 120, 121, 122, 117, 111, 105, 102, - 102, 101, 101, 100, 99, 98, 96, 94, 92, 89, 87, 85, 83, 82, 81, 78, - 77, 76, 76, 74, 72, 71, 71, 70, 69, 68, 67, 67, 66, 65, 64, 63, - 62, 61, 61, 61, 60, 59, 58, 58, 58, 58, 57, 57, 56, 55, 54, 54, - 54, 54, 54, 52, 50, 50, 49, 48, 48, 48, 46, 46, 47, 46, 45, 46, - 69, 69, 70, 72, 73, 74, 75, 76, 78, 79, 80, 82, 84, 86, 88, 89, - 89, 92, 95, 98, 102, 105, 109, 111, 112, 112, 112, 114, 120, 124, 126, 126, - 127, 134, 136, 134, 132, 135, 142, 151, 151, 148, 152, 153, 154, 154, 150, 150, - 154, 145, 145, 143, 137, 130, 133, 131, 127, 124, 126, 123, 118, 111, 107, 105, - 104, 105, 104, 103, 101, 99, 97, 94, 92, 90, 88, 85, 84, 83, 81, 78, - 77, 76, 76, 74, 72, 71, 71, 70, 69, 68, 67, 67, 66, 65, 64, 63, - 62, 61, 61, 61, 60, 59, 58, 58, 58, 58, 57, 57, 56, 55, 54, 54, - 54, 54, 54, 52, 50, 50, 49, 48, 48, 48, 47, 47, 47, 47, 46, 46, - 69, 69, 70, 72, 73, 74, 75, 76, 79, 80, 81, 82, 85, 87, 89, 91, - 92, 95, 99, 101, 104, 108, 111, 114, 116, 118, 118, 118, 122, 126, 130, 132, - 130, 135, 141, 140, 135, 138, 146, 155, 158, 151, 158, 157, 159, 159, 155, 156, - 158, 149, 150, 145, 140, 135, 137, 135, 130, 130, 129, 123, 117, 111, 109, 109, - 107, 107, 107, 104, 102, 100, 98, 94, 92, 89, 87, 86, 84, 83, 82, 78, - 77, 76, 76, 74, 72, 71, 71, 70, 69, 68, 67, 67, 66, 65, 64, 63, - 62, 61, 61, 61, 60, 59, 58, 58, 58, 58, 57, 57, 56, 55, 54, 54, - 54, 54, 54, 52, 50, 50, 49, 48, 48, 48, 47, 47, 48, 47, 46, 46, - 69, 69, 70, 72, 73, 74, 75, 76, 79, 81, 82, 82, 87, 88, 90, 92, - 96, 98, 102, 104, 106, 110, 115, 117, 120, 123, 124, 123, 123, 128, 135, 140, - 139, 139, 148, 149, 142, 146, 154, 161, 165, 156, 165, 164, 167, 167, 163, 163, - 163, 155, 157, 149, 144, 141, 140, 137, 134, 136, 131, 123, 116, 112, 112, 113, - 111, 109, 108, 106, 104, 101, 98, 94, 92, 89, 87, 86, 84, 83, 82, 78, - 77, 76, 76, 74, 72, 71, 71, 70, 69, 68, 67, 67, 66, 65, 64, 63, - 62, 61, 61, 61, 60, 59, 58, 58, 58, 58, 57, 57, 56, 55, 54, 54, - 54, 54, 54, 52, 50, 50, 49, 48, 48, 48, 47, 48, 48, 48, 46, 46, - 69, 69, 70, 72, 73, 74, 75, 76, 80, 81, 82, 83, 88, 89, 91, 94, - 98, 101, 104, 107, 109, 113, 117, 119, 123, 126, 128, 128, 127, 129, 136, 143, - 145, 142, 149, 156, 148, 150, 158, 163, 171, 162, 169, 170, 172, 173, 167, 171, - 167, 161, 161, 152, 146, 147, 144, 138, 140, 140, 132, 122, 117, 115, 115, 115, - 113, 111, 109, 106, 103, 100, 97, 93, 91, 89, 87, 86, 85, 84, 82, 78, - 77, 77, 76, 74, 73, 72, 71, 71, 70, 69, 67, 67, 66, 65, 64, 63, - 62, 61, 61, 61, 60, 59, 58, 58, 58, 58, 57, 57, 56, 56, 54, 54, - 54, 54, 53, 52, 51, 50, 50, 48, 48, 48, 48, 49, 49, 49, 47, 46, - 69, 69, 70, 72, 73, 74, 75, 76, 80, 82, 83, 85, 88, 90, 94, 97, - 101, 104, 108, 111, 114, 117, 121, 123, 126, 130, 133, 136, 134, 132, 137, 143, - 150, 148, 148, 161, 157, 153, 161, 166, 177, 170, 174, 177, 178, 179, 171, 179, - 170, 169, 165, 157, 151, 154, 149, 144, 150, 142, 131, 123, 121, 120, 118, 117, - 116, 113, 111, 106, 102, 98, 95, 93, 91, 89, 88, 87, 86, 84, 83, 79, - 78, 78, 77, 76, 74, 72, 72, 71, 71, 70, 68, 67, 66, 65, 64, 63, - 62, 62, 61, 61, 60, 59, 59, 59, 59, 58, 58, 58, 57, 56, 55, 54, - 54, 54, 53, 52, 52, 52, 51, 50, 49, 48, 48, 50, 50, 50, 48, 47, - 69, 69, 70, 72, 74, 74, 75, 76, 81, 82, 85, 87, 89, 92, 95, 99, - 105, 109, 113, 117, 120, 122, 126, 128, 130, 135, 140, 141, 140, 140, 141, 145, - 153, 157, 154, 161, 169, 161, 162, 172, 183, 179, 181, 184, 184, 185, 178, 186, - 176, 178, 171, 161, 163, 160, 151, 154, 155, 142, 130, 125, 125, 124, 122, 120, - 118, 114, 110, 106, 103, 98, 95, 93, 91, 89, 88, 87, 86, 84, 83, 79, - 78, 78, 77, 76, 74, 72, 72, 71, 71, 70, 68, 67, 66, 65, 65, 63, - 63, 62, 61, 61, 60, 59, 59, 59, 59, 58, 58, 58, 57, 56, 55, 54, - 54, 54, 53, 52, 52, 52, 51, 50, 49, 48, 48, 50, 50, 50, 48, 46, - 69, 70, 71, 73, 74, 75, 76, 77, 81, 83, 87, 89, 91, 94, 99, 104, - 110, 113, 119, 122, 125, 128, 131, 133, 135, 139, 144, 148, 148, 150, 147, 148, - 155, 165, 164, 160, 176, 172, 165, 177, 188, 189, 188, 191, 192, 192, 185, 193, - 183, 186, 176, 166, 172, 164, 158, 163, 155, 141, 132, 131, 131, 130, 127, 124, - 120, 114, 109, 105, 102, 99, 96, 94, 92, 90, 89, 87, 86, 84, 83, 79, - 78, 78, 77, 76, 74, 72, 72, 71, 71, 70, 68, 68, 67, 66, 65, 64, - 63, 62, 62, 62, 61, 60, 59, 59, 59, 58, 58, 58, 57, 56, 55, 54, - 54, 54, 53, 52, 52, 52, 52, 50, 49, 48, 48, 50, 50, 50, 48, 46, - 70, 71, 71, 73, 75, 75, 76, 77, 81, 85, 89, 91, 93, 97, 103, 107, - 112, 116, 122, 126, 129, 132, 135, 137, 139, 143, 147, 152, 156, 158, 157, 154, - 156, 168, 174, 166, 175, 182, 173, 178, 191, 198, 194, 198, 200, 199, 193, 200, - 191, 192, 179, 174, 175, 167, 168, 166, 152, 142, 139, 139, 138, 134, 130, 124, - 119, 113, 108, 104, 102, 100, 98, 95, 94, 92, 90, 88, 87, 85, 83, 79, - 78, 78, 77, 76, 74, 72, 72, 71, 71, 70, 69, 68, 68, 67, 66, 65, - 64, 63, 63, 62, 61, 60, 60, 59, 59, 58, 58, 58, 57, 56, 55, 54, - 54, 54, 53, 53, 53, 53, 52, 50, 49, 48, 48, 50, 50, 50, 48, 46, - 70, 71, 72, 74, 75, 76, 77, 78, 82, 86, 90, 92, 95, 99, 106, 110, - 115, 120, 127, 131, 133, 136, 139, 142, 145, 147, 151, 154, 159, 163, 164, 163, - 160, 167, 179, 177, 177, 189, 187, 183, 196, 208, 200, 206, 210, 208, 202, 207, - 200, 196, 182, 184, 177, 175, 176, 165, 151, 147, 148, 146, 142, 136, 130, 123, - 117, 112, 107, 104, 102, 100, 98, 96, 94, 92, 91, 88, 87, 85, 83, 79, - 78, 78, 77, 76, 74, 72, 72, 71, 71, 70, 69, 69, 68, 67, 66, 65, - 64, 64, 63, 63, 62, 61, 60, 59, 59, 58, 58, 58, 57, 56, 55, 54, - 54, 54, 53, 53, 53, 53, 52, 50, 49, 48, 48, 50, 50, 50, 48, 46, - 71, 71, 72, 74, 76, 77, 77, 79, 82, 87, 91, 93, 96, 101, 107, 113, - 120, 126, 132, 137, 140, 142, 145, 148, 152, 153, 154, 156, 161, 166, 171, 173, - 167, 165, 178, 190, 185, 194, 198, 189, 202, 217, 206, 214, 220, 217, 212, 214, - 209, 200, 186, 193, 181, 187, 182, 163, 154, 153, 155, 150, 145, 137, 129, 121, - 115, 111, 107, 103, 101, 100, 99, 96, 94, 92, 91, 88, 87, 85, 83, 80, - 79, 78, 77, 76, 74, 73, 72, 71, 71, 70, 69, 69, 68, 67, 66, 65, - 65, 64, 63, 63, 62, 61, 60, 59, 59, 58, 58, 58, 57, 56, 55, 54, - 54, 54, 54, 54, 54, 54, 53, 51, 50, 49, 48, 50, 50, 50, 48, 46, - 71, 72, 74, 76, 76, 78, 80, 82, 87, 89, 93, 96, 100, 106, 111, 118, - 126, 134, 144, 144, 145, 152, 158, 156, 159, 161, 162, 164, 163, 174, 179, 180, - 182, 176, 180, 194, 201, 194, 211, 192, 209, 225, 218, 222, 230, 225, 226, 222, - 217, 207, 197, 198, 195, 197, 186, 167, 163, 164, 159, 155, 146, 135, 126, 120, - 117, 113, 109, 106, 104, 102, 99, 96, 95, 93, 92, 89, 88, 85, 84, 80, - 79, 77, 77, 75, 75, 73, 71, 69, 70, 69, 69, 68, 67, 66, 65, 64, - 63, 62, 62, 63, 62, 62, 62, 59, 58, 57, 57, 56, 55, 54, 54, 55, - 54, 53, 53, 54, 53, 52, 53, 52, 51, 50, 49, 50, 50, 49, 47, 46, - 71, 72, 75, 76, 76, 79, 82, 85, 90, 93, 95, 99, 106, 113, 117, 125, - 133, 140, 145, 152, 156, 152, 153, 160, 163, 162, 161, 166, 171, 168, 184, 198, - 194, 188, 178, 188, 213, 201, 212, 211, 208, 233, 228, 234, 240, 236, 238, 228, - 223, 204, 211, 209, 209, 197, 179, 172, 173, 173, 163, 155, 144, 134, 126, 121, - 118, 115, 111, 108, 106, 103, 101, 97, 95, 92, 91, 90, 88, 85, 84, 81, - 80, 79, 78, 76, 75, 74, 73, 70, 70, 70, 70, 68, 67, 66, 65, 64, - 63, 62, 62, 63, 63, 63, 62, 60, 58, 58, 57, 56, 55, 54, 54, 55, - 54, 53, 53, 54, 53, 52, 53, 54, 52, 51, 50, 50, 49, 49, 47, 46, - 71, 72, 75, 76, 76, 80, 83, 87, 91, 95, 101, 105, 113, 120, 125, 134, - 144, 147, 147, 153, 152, 155, 155, 163, 164, 166, 169, 168, 171, 183, 186, 190, - 196, 200, 191, 190, 210, 214, 214, 231, 220, 240, 235, 241, 246, 243, 243, 234, - 237, 221, 225, 212, 219, 195, 184, 187, 179, 177, 166, 153, 143, 134, 127, 122, - 119, 116, 113, 109, 106, 104, 102, 97, 95, 94, 91, 89, 88, 86, 84, 82, - 82, 80, 79, 78, 77, 76, 74, 72, 71, 71, 71, 69, 68, 67, 66, 65, - 64, 63, 62, 64, 64, 64, 64, 62, 61, 60, 59, 59, 58, 57, 57, 56, - 55, 54, 54, 54, 53, 52, 53, 54, 53, 51, 51, 50, 50, 49, 47, 46, - 71, 72, 75, 77, 77, 80, 84, 89, 93, 99, 106, 112, 120, 127, 133, 140, - 146, 150, 153, 154, 151, 150, 140, 130, 128, 133, 147, 159, 171, 177, 182, 189, - 195, 196, 194, 194, 202, 224, 224, 229, 229, 237, 245, 246, 249, 247, 246, 242, - 234, 225, 228, 226, 204, 197, 195, 193, 183, 175, 166, 152, 142, 135, 129, 123, - 120, 117, 114, 109, 106, 103, 101, 98, 96, 94, 92, 90, 89, 87, 85, 84, - 84, 82, 82, 79, 79, 78, 77, 75, 74, 73, 72, 70, 69, 68, 67, 66, - 65, 64, 63, 65, 65, 65, 64, 63, 62, 61, 61, 60, 60, 59, 59, 58, - 57, 56, 55, 54, 53, 53, 53, 55, 53, 52, 51, 50, 50, 49, 47, 46, - 71, 72, 75, 77, 77, 81, 86, 91, 95, 103, 112, 119, 127, 135, 140, 147, - 149, 154, 156, 144, 124, 102, 85, 71, 67, 71, 89, 101, 126, 161, 178, 184, - 192, 167, 173, 186, 197, 221, 232, 235, 237, 228, 245, 241, 243, 242, 242, 238, - 226, 232, 223, 221, 194, 198, 202, 199, 187, 174, 162, 154, 144, 137, 131, 125, - 122, 119, 116, 110, 107, 104, 102, 100, 99, 96, 94, 93, 91, 89, 87, 87, - 86, 85, 85, 82, 81, 80, 80, 77, 76, 75, 74, 72, 71, 70, 69, 67, - 66, 65, 64, 65, 65, 65, 65, 65, 64, 63, 63, 63, 62, 61, 61, 60, - 60, 58, 57, 56, 55, 54, 55, 55, 54, 52, 51, 51, 50, 50, 48, 46, - 71, 73, 75, 77, 78, 82, 87, 92, 97, 105, 116, 126, 134, 142, 147, 154, - 158, 155, 133, 101, 66, 45, 36, 36, 35, 42, 58, 61, 70, 92, 134, 176, - 186, 96, 80, 112, 185, 217, 234, 228, 153, 121, 120, 120, 125, 123, 125, 123, - 130, 138, 110, 91, 98, 106, 116, 164, 180, 174, 161, 156, 147, 140, 133, 127, - 123, 119, 116, 113, 110, 107, 105, 103, 102, 99, 98, 96, 95, 92, 90, 89, - 89, 87, 86, 85, 84, 83, 81, 80, 79, 76, 74, 73, 73, 71, 70, 68, - 68, 67, 66, 67, 67, 67, 67, 67, 66, 65, 65, 65, 65, 64, 64, 64, - 63, 62, 60, 59, 58, 57, 57, 56, 54, 53, 52, 51, 50, 50, 48, 46, - 71, 73, 76, 78, 79, 83, 88, 94, 98, 107, 120, 131, 140, 147, 152, 157, - 154, 131, 81, 44, 36, 32, 29, 36, 41, 52, 63, 60, 58, 57, 73, 114, - 149, 53, 57, 76, 162, 220, 234, 245, 123, 91, 74, 82, 85, 83, 89, 92, - 93, 66, 55, 64, 68, 93, 103, 125, 164, 172, 163, 158, 150, 142, 135, 128, - 124, 120, 117, 116, 115, 112, 109, 106, 105, 102, 100, 99, 97, 96, 93, 91, - 90, 89, 88, 86, 85, 84, 84, 82, 80, 78, 76, 74, 73, 72, 71, 69, - 69, 68, 67, 68, 68, 68, 69, 69, 69, 68, 68, 68, 67, 66, 66, 67, - 66, 65, 63, 61, 60, 59, 58, 56, 55, 53, 52, 50, 50, 49, 48, 47, - 71, 73, 77, 79, 80, 85, 88, 96, 100, 111, 122, 135, 141, 153, 156, 158, - 125, 67, 47, 40, 37, 44, 56, 61, 63, 61, 58, 55, 58, 60, 57, 69, - 97, 56, 53, 57, 137, 232, 242, 242, 127, 95, 84, 92, 92, 96, 102, 88, - 67, 48, 54, 83, 94, 109, 110, 93, 163, 175, 167, 157, 150, 141, 136, 130, - 126, 123, 120, 119, 117, 115, 113, 110, 108, 107, 105, 102, 101, 99, 97, 95, - 94, 93, 92, 90, 89, 87, 86, 85, 84, 82, 80, 76, 75, 73, 72, 71, - 71, 71, 71, 72, 72, 73, 74, 74, 74, 74, 74, 74, 73, 72, 72, 71, - 70, 68, 66, 66, 66, 63, 61, 59, 56, 53, 51, 49, 47, 47, 48, 48, - 71, 73, 77, 79, 81, 87, 90, 98, 103, 115, 126, 137, 146, 155, 155, 134, - 79, 51, 45, 46, 52, 58, 57, 56, 71, 81, 80, 72, 65, 61, 54, 66, - 75, 72, 71, 65, 133, 232, 247, 243, 133, 88, 85, 90, 101, 91, 111, 69, - 60, 55, 69, 104, 119, 133, 126, 96, 162, 177, 167, 158, 152, 144, 140, 135, - 132, 129, 126, 124, 122, 120, 119, 115, 113, 111, 110, 106, 104, 102, 100, 99, - 97, 96, 95, 94, 93, 90, 89, 88, 86, 84, 83, 78, 77, 75, 74, 73, - 73, 73, 73, 76, 77, 78, 78, 78, 78, 78, 78, 78, 77, 76, 76, 76, - 75, 73, 71, 70, 69, 66, 64, 62, 59, 56, 53, 50, 48, 47, 48, 48, - 71, 73, 77, 79, 82, 88, 92, 101, 108, 119, 132, 143, 150, 153, 144, 94, - 64, 53, 47, 45, 48, 49, 55, 89, 118, 133, 138, 132, 105, 80, 61, 66, - 71, 71, 65, 66, 137, 233, 250, 248, 173, 119, 91, 79, 81, 70, 54, 17, - 34, 68, 95, 125, 122, 110, 106, 110, 165, 178, 169, 160, 155, 149, 146, 141, - 138, 135, 132, 129, 128, 126, 124, 120, 118, 116, 115, 111, 109, 106, 105, 104, - 102, 101, 100, 100, 98, 96, 95, 92, 90, 88, 86, 81, 80, 78, 77, 76, - 76, 77, 78, 80, 81, 83, 83, 83, 83, 83, 83, 84, 83, 82, 82, 82, - 80, 78, 76, 73, 73, 70, 67, 65, 61, 58, 55, 51, 48, 48, 47, 47, - 72, 74, 78, 80, 84, 90, 94, 104, 112, 125, 137, 149, 155, 151, 100, 48, - 43, 37, 31, 35, 42, 47, 90, 142, 160, 171, 179, 179, 171, 139, 83, 74, - 72, 83, 64, 62, 138, 232, 249, 254, 238, 191, 145, 90, 81, 66, 18, 19, - 71, 110, 130, 126, 86, 111, 132, 145, 175, 178, 172, 166, 161, 155, 151, 145, - 142, 140, 137, 133, 132, 130, 128, 125, 123, 121, 119, 116, 114, 113, 112, 110, - 108, 107, 107, 106, 105, 102, 100, 97, 94, 91, 89, 85, 83, 81, 79, 79, - 80, 81, 82, 83, 85, 87, 88, 88, 88, 88, 88, 89, 88, 87, 87, 88, - 86, 83, 80, 78, 76, 73, 69, 66, 62, 58, 56, 53, 49, 48, 47, 47, - 73, 75, 79, 81, 86, 92, 97, 107, 118, 131, 143, 153, 160, 136, 40, 30, - 37, 38, 41, 47, 46, 83, 152, 170, 175, 178, 184, 187, 192, 187, 142, 93, - 76, 72, 64, 65, 135, 231, 251, 253, 251, 244, 237, 172, 111, 56, 78, 115, - 131, 137, 145, 93, 98, 172, 191, 193, 192, 185, 180, 175, 169, 162, 158, 151, - 148, 145, 143, 139, 137, 135, 134, 130, 128, 125, 124, 122, 121, 119, 118, 115, - 115, 114, 113, 112, 111, 109, 107, 103, 99, 95, 93, 88, 86, 84, 83, 83, - 85, 87, 87, 87, 90, 92, 94, 95, 95, 95, 95, 97, 96, 95, 94, 93, - 91, 89, 87, 84, 82, 78, 73, 68, 64, 59, 57, 54, 50, 49, 47, 46, - 73, 75, 79, 81, 87, 94, 99, 110, 121, 135, 147, 157, 156, 96, 32, 51, - 57, 55, 52, 45, 58, 128, 173, 181, 181, 182, 185, 187, 190, 191, 185, 118, - 75, 69, 78, 80, 143, 238, 254, 253, 252, 251, 251, 220, 90, 57, 104, 135, - 136, 132, 135, 80, 150, 213, 220, 212, 204, 197, 188, 182, 175, 167, 161, 157, - 154, 151, 149, 146, 143, 141, 139, 136, 134, 132, 130, 126, 124, 123, 121, 118, - 118, 117, 116, 116, 114, 112, 110, 107, 104, 99, 96, 91, 89, 87, 85, 85, - 87, 89, 90, 92, 94, 97, 99, 102, 101, 101, 102, 104, 103, 102, 101, 99, - 97, 95, 93, 91, 88, 84, 78, 72, 67, 62, 58, 55, 51, 49, 47, 46, - 74, 75, 79, 83, 88, 96, 104, 114, 124, 137, 152, 156, 138, 65, 42, 62, - 61, 54, 44, 36, 88, 158, 177, 182, 180, 182, 185, 188, 196, 196, 199, 160, - 83, 86, 90, 88, 137, 238, 254, 252, 252, 252, 253, 238, 55, 98, 130, 138, - 136, 128, 119, 88, 186, 234, 236, 219, 207, 199, 188, 183, 178, 169, 162, 159, - 156, 152, 151, 151, 146, 144, 142, 142, 142, 140, 136, 132, 129, 126, 124, 120, - 119, 123, 121, 122, 119, 116, 114, 115, 110, 106, 100, 95, 92, 90, 88, 87, - 89, 92, 96, 97, 101, 105, 106, 109, 108, 108, 109, 109, 108, 109, 110, 107, - 102, 100, 100, 97, 95, 85, 83, 77, 71, 66, 60, 56, 52, 50, 48, 46, - 74, 75, 80, 85, 89, 98, 107, 118, 128, 141, 155, 156, 117, 45, 40, 61, - 53, 50, 45, 46, 121, 172, 180, 176, 176, 177, 182, 186, 194, 200, 205, 198, - 112, 87, 83, 82, 123, 234, 254, 255, 255, 254, 253, 250, 98, 127, 143, 137, - 123, 115, 117, 97, 204, 240, 232, 215, 200, 191, 184, 179, 174, 166, 158, 158, - 155, 151, 151, 151, 146, 145, 142, 145, 146, 143, 139, 136, 133, 131, 130, 129, - 125, 130, 128, 125, 129, 127, 120, 118, 118, 113, 104, 100, 97, 94, 92, 91, - 93, 98, 103, 108, 109, 113, 115, 118, 118, 117, 117, 118, 117, 117, 115, 113, - 114, 112, 108, 104, 96, 93, 89, 80, 74, 69, 62, 58, 53, 51, 49, 47, - 74, 75, 80, 85, 90, 100, 109, 120, 132, 147, 154, 150, 73, 15, 29, 54, - 50, 52, 48, 63, 143, 178, 177, 171, 170, 172, 176, 180, 189, 196, 202, 203, - 132, 92, 101, 84, 124, 236, 254, 254, 254, 254, 254, 250, 128, 126, 138, 134, - 127, 125, 124, 93, 198, 223, 209, 198, 190, 184, 179, 176, 172, 165, 158, 158, - 157, 155, 156, 154, 151, 150, 146, 150, 151, 148, 145, 139, 138, 139, 139, 138, - 134, 135, 135, 134, 131, 130, 132, 122, 124, 117, 110, 107, 103, 100, 99, 97, - 100, 106, 111, 115, 114, 117, 121, 125, 124, 123, 123, 124, 125, 126, 127, 125, - 125, 123, 115, 114, 104, 100, 93, 83, 77, 70, 63, 59, 54, 52, 49, 47, - 74, 75, 80, 85, 91, 101, 111, 122, 135, 147, 155, 120, 25, 14, 32, 50, - 56, 61, 47, 84, 157, 174, 168, 164, 164, 166, 169, 173, 179, 188, 195, 199, - 158, 104, 88, 61, 124, 231, 252, 253, 252, 251, 250, 250, 117, 89, 69, 99, - 121, 114, 121, 99, 204, 230, 221, 212, 202, 194, 187, 184, 182, 176, 170, 166, - 166, 167, 167, 165, 164, 160, 155, 150, 150, 148, 145, 147, 148, 147, 147, 146, - 146, 146, 144, 145, 141, 138, 138, 137, 130, 120, 122, 115, 110, 107, 105, 105, - 107, 113, 118, 120, 125, 126, 131, 133, 133, 133, 134, 137, 136, 138, 143, 139, - 131, 131, 125, 116, 119, 102, 95, 87, 80, 74, 66, 61, 55, 52, 49, 47, - 74, 75, 80, 85, 92, 103, 113, 125, 138, 145, 156, 95, 42, 47, 51, 63, - 58, 63, 46, 106, 162, 170, 164, 161, 159, 160, 164, 169, 176, 184, 192, 195, - 179, 110, 85, 63, 117, 220, 243, 247, 245, 251, 254, 251, 118, 88, 90, 88, - 98, 122, 129, 95, 198, 227, 222, 218, 210, 203, 197, 192, 189, 185, 180, 175, - 174, 176, 177, 175, 172, 165, 161, 159, 158, 155, 152, 155, 156, 155, 155, 157, - 159, 154, 147, 146, 146, 143, 139, 135, 134, 131, 128, 122, 117, 113, 111, 111, - 114, 119, 125, 129, 136, 133, 135, 136, 138, 139, 139, 142, 148, 149, 148, 146, - 143, 140, 130, 124, 112, 114, 101, 91, 84, 77, 68, 63, 57, 53, 49, 47, - 74, 75, 80, 86, 93, 104, 115, 127, 140, 148, 153, 85, 67, 62, 59, 72, - 64, 59, 49, 125, 165, 166, 162, 159, 155, 157, 161, 165, 173, 180, 187, 191, - 178, 84, 72, 73, 113, 214, 245, 250, 251, 254, 253, 248, 134, 119, 140, 123, - 90, 89, 105, 99, 201, 224, 211, 207, 202, 195, 191, 188, 186, 183, 180, 175, - 175, 177, 177, 177, 174, 166, 167, 163, 160, 156, 152, 156, 159, 162, 164, 163, - 161, 154, 153, 149, 130, 125, 134, 138, 135, 139, 132, 129, 126, 122, 119, 119, - 121, 126, 131, 133, 137, 136, 142, 141, 145, 150, 149, 141, 144, 149, 152, 153, - 149, 140, 142, 141, 114, 112, 99, 94, 86, 79, 70, 64, 58, 53, 49, 47, - 74, 75, 80, 86, 94, 105, 116, 129, 141, 153, 147, 84, 61, 56, 64, 77, - 79, 58, 54, 134, 164, 163, 158, 155, 153, 155, 158, 162, 167, 174, 178, 187, - 177, 75, 90, 100, 117, 219, 252, 254, 254, 255, 254, 250, 144, 151, 135, 142, - 126, 93, 76, 97, 206, 236, 228, 214, 201, 190, 182, 179, 179, 177, 175, 169, - 169, 170, 169, 174, 173, 167, 174, 186, 185, 179, 175, 154, 158, 165, 170, 167, - 163, 160, 173, 194, 191, 176, 158, 160, 132, 137, 138, 135, 132, 128, 126, 127, - 128, 132, 135, 138, 140, 148, 168, 175, 182, 188, 190, 172, 135, 131, 149, 154, - 146, 156, 176, 136, 140, 101, 101, 97, 89, 81, 72, 65, 58, 54, 49, 47, - 75, 77, 82, 88, 95, 105, 116, 129, 148, 150, 129, 65, 58, 70, 78, 84, - 81, 55, 68, 144, 165, 162, 154, 150, 148, 146, 149, 153, 160, 166, 172, 181, - 179, 148, 139, 121, 134, 231, 254, 254, 254, 254, 254, 250, 139, 139, 134, 151, - 143, 138, 140, 95, 203, 235, 225, 224, 214, 196, 179, 171, 166, 168, 179, 178, - 174, 174, 132, 164, 171, 182, 179, 152, 136, 149, 121, 130, 133, 159, 170, 164, - 163, 190, 186, 190, 202, 219, 227, 209, 159, 126, 137, 138, 135, 134, 135, 130, - 134, 140, 138, 139, 150, 152, 156, 152, 146, 150, 135, 83, 51, 122, 156, 148, - 155, 187, 157, 175, 173, 106, 90, 100, 91, 83, 73, 65, 58, 53, 49, 47, - 75, 77, 83, 88, 96, 107, 117, 131, 146, 155, 125, 71, 58, 82, 70, 63, - 43, 40, 74, 150, 162, 156, 149, 145, 143, 141, 144, 148, 156, 163, 168, 178, - 187, 172, 136, 125, 167, 234, 252, 254, 253, 254, 254, 250, 149, 133, 133, 123, - 143, 140, 140, 97, 191, 228, 224, 213, 204, 187, 173, 155, 184, 168, 166, 168, - 159, 163, 107, 148, 173, 198, 185, 141, 137, 122, 115, 124, 125, 127, 161, 161, - 185, 211, 188, 176, 203, 210, 211, 225, 198, 135, 126, 138, 138, 136, 138, 141, - 142, 139, 141, 160, 169, 172, 141, 118, 120, 133, 77, 80, 130, 186, 205, 153, - 169, 181, 148, 180, 165, 126, 73, 97, 93, 84, 75, 67, 60, 55, 49, 47, - 75, 77, 83, 89, 98, 109, 119, 133, 153, 154, 99, 61, 76, 88, 77, 75, - 61, 66, 89, 152, 157, 151, 143, 139, 138, 137, 140, 145, 152, 160, 167, 176, - 189, 199, 189, 185, 201, 235, 248, 254, 248, 254, 254, 252, 134, 116, 149, 137, - 134, 112, 126, 95, 184, 219, 219, 211, 204, 180, 168, 150, 175, 160, 162, 156, - 159, 151, 90, 160, 192, 196, 176, 188, 183, 193, 204, 207, 192, 149, 139, 169, - 176, 155, 175, 181, 200, 202, 204, 175, 169, 200, 116, 135, 141, 139, 142, 147, - 145, 141, 158, 197, 190, 188, 156, 122, 126, 132, 136, 179, 195, 196, 200, 186, - 167, 159, 150, 164, 138, 144, 65, 93, 95, 84, 76, 68, 61, 56, 51, 48, - 75, 77, 83, 89, 99, 110, 121, 135, 154, 152, 91, 75, 97, 80, 84, 76, - 68, 79, 93, 154, 156, 149, 140, 137, 136, 136, 139, 143, 149, 160, 170, 184, - 195, 194, 194, 205, 219, 235, 245, 254, 248, 254, 253, 250, 124, 117, 127, 118, - 145, 153, 147, 95, 187, 213, 210, 209, 200, 167, 160, 164, 162, 154, 166, 175, - 156, 169, 122, 188, 196, 196, 171, 187, 150, 201, 202, 207, 220, 201, 132, 196, - 184, 171, 187, 191, 206, 206, 188, 146, 180, 244, 129, 125, 145, 145, 146, 150, - 147, 154, 178, 196, 191, 187, 187, 172, 115, 96, 163, 204, 184, 158, 175, 158, - 150, 144, 134, 159, 140, 145, 57, 91, 96, 85, 77, 69, 61, 57, 51, 48, - 75, 77, 83, 89, 100, 110, 121, 134, 150, 153, 103, 97, 86, 71, 92, 71, - 85, 86, 94, 152, 157, 149, 141, 137, 135, 136, 139, 144, 151, 161, 171, 182, - 189, 192, 202, 214, 221, 233, 240, 245, 251, 254, 250, 246, 132, 141, 138, 119, - 135, 133, 143, 103, 192, 213, 204, 205, 196, 163, 157, 165, 157, 161, 174, 190, - 145, 163, 160, 208, 208, 188, 171, 188, 146, 196, 182, 201, 189, 203, 177, 217, - 195, 201, 220, 207, 200, 196, 174, 164, 234, 221, 131, 109, 147, 151, 152, 154, - 154, 172, 188, 190, 204, 187, 200, 150, 78, 103, 148, 193, 168, 128, 156, 149, - 165, 92, 93, 158, 171, 139, 60, 94, 95, 85, 76, 68, 61, 56, 51, 49, - 75, 77, 83, 89, 99, 109, 120, 134, 150, 151, 104, 81, 58, 69, 87, 58, - 79, 75, 105, 160, 157, 149, 141, 135, 133, 134, 139, 145, 154, 161, 168, 175, - 182, 189, 198, 208, 218, 227, 229, 233, 252, 255, 248, 247, 154, 137, 137, 135, - 149, 139, 144, 99, 187, 217, 207, 204, 199, 170, 155, 163, 156, 176, 184, 193, - 177, 161, 185, 206, 175, 130, 137, 194, 183, 202, 182, 164, 175, 209, 206, 203, - 196, 158, 166, 206, 209, 214, 203, 205, 194, 134, 147, 91, 146, 156, 157, 158, - 160, 181, 163, 138, 177, 174, 181, 85, 102, 154, 165, 168, 141, 133, 140, 133, - 167, 119, 91, 156, 148, 86, 64, 99, 92, 84, 74, 67, 60, 55, 51, 49, - 75, 77, 83, 89, 98, 109, 120, 134, 149, 147, 97, 68, 61, 70, 65, 54, - 108, 83, 112, 155, 155, 147, 139, 134, 133, 134, 140, 146, 155, 159, 163, 171, - 181, 188, 197, 209, 216, 220, 222, 229, 251, 251, 251, 239, 172, 153, 155, 151, - 149, 145, 153, 93, 180, 218, 211, 201, 198, 179, 157, 179, 168, 186, 182, 189, - 183, 157, 179, 166, 97, 103, 126, 191, 192, 189, 169, 178, 187, 194, 197, 198, - 117, 84, 108, 153, 197, 199, 160, 184, 152, 135, 137, 79, 146, 159, 160, 159, - 160, 173, 154, 155, 167, 148, 132, 69, 140, 186, 188, 172, 148, 158, 124, 132, - 150, 130, 93, 119, 102, 77, 98, 103, 92, 84, 73, 66, 59, 54, 50, 48, - 73, 76, 82, 89, 97, 108, 120, 135, 151, 142, 86, 72, 87, 85, 73, 88, - 116, 84, 114, 157, 155, 146, 138, 136, 137, 139, 144, 147, 148, 153, 161, 167, - 176, 185, 194, 203, 211, 211, 216, 227, 249, 240, 254, 240, 164, 160, 166, 165, - 161, 161, 161, 95, 180, 212, 210, 202, 199, 195, 182, 175, 174, 182, 180, 200, - 184, 159, 174, 102, 105, 163, 185, 194, 206, 200, 197, 198, 175, 170, 174, 141, - 77, 135, 164, 159, 154, 124, 87, 135, 150, 172, 171, 70, 147, 161, 165, 161, - 162, 170, 182, 182, 176, 146, 121, 75, 160, 194, 191, 176, 167, 168, 118, 144, - 116, 124, 83, 128, 126, 116, 114, 105, 93, 82, 72, 65, 58, 53, 50, 48, - 73, 75, 82, 89, 97, 108, 120, 135, 149, 145, 106, 93, 102, 102, 98, 118, - 112, 80, 113, 158, 156, 148, 141, 139, 141, 140, 141, 144, 146, 152, 159, 166, - 174, 180, 191, 200, 202, 203, 212, 225, 238, 233, 250, 235, 167, 157, 142, 169, - 174, 163, 170, 98, 178, 209, 207, 204, 203, 200, 194, 191, 190, 181, 176, 198, - 190, 172, 130, 77, 154, 189, 203, 200, 226, 217, 211, 216, 185, 203, 185, 81, - 112, 174, 183, 181, 186, 175, 169, 192, 182, 202, 187, 67, 146, 162, 166, 161, - 178, 187, 178, 169, 176, 160, 131, 75, 174, 195, 197, 182, 165, 153, 110, 136, - 138, 139, 70, 123, 138, 130, 119, 103, 91, 81, 71, 64, 58, 53, 50, 48, - 72, 75, 81, 88, 96, 108, 120, 134, 146, 149, 127, 114, 102, 104, 105, 121, - 95, 71, 109, 158, 159, 152, 145, 142, 141, 139, 138, 141, 145, 151, 158, 165, - 173, 179, 189, 195, 194, 196, 209, 224, 226, 228, 245, 227, 172, 158, 172, 179, - 177, 161, 181, 97, 176, 207, 204, 201, 202, 202, 197, 193, 191, 176, 183, 217, - 208, 153, 74, 99, 180, 194, 201, 203, 222, 210, 217, 220, 188, 203, 187, 70, - 149, 188, 186, 180, 206, 215, 205, 214, 211, 197, 178, 64, 146, 164, 168, 168, - 186, 180, 157, 139, 168, 166, 138, 86, 176, 202, 201, 182, 146, 132, 126, 139, - 150, 143, 65, 118, 140, 129, 115, 101, 89, 79, 69, 63, 57, 53, 49, 47, - 71, 74, 81, 88, 95, 107, 119, 134, 149, 147, 124, 103, 91, 93, 97, 100, - 92, 76, 110, 160, 162, 155, 147, 142, 136, 136, 138, 140, 145, 151, 158, 163, - 171, 181, 184, 187, 189, 194, 208, 221, 215, 226, 240, 229, 167, 165, 187, 167, - 190, 178, 179, 93, 176, 205, 200, 195, 199, 204, 197, 186, 180, 173, 200, 217, - 179, 77, 46, 125, 190, 211, 197, 202, 217, 214, 217, 198, 173, 187, 151, 85, - 170, 194, 199, 198, 190, 188, 161, 187, 189, 168, 158, 63, 147, 167, 170, 167, - 176, 166, 165, 156, 168, 153, 125, 92, 180, 202, 200, 177, 148, 148, 152, 145, - 136, 117, 64, 117, 135, 125, 111, 97, 86, 77, 68, 62, 56, 53, 49, 46, - 71, 74, 80, 87, 94, 106, 118, 133, 146, 148, 128, 108, 97, 95, 108, 105, - 109, 92, 111, 163, 165, 157, 148, 142, 136, 136, 138, 142, 146, 152, 160, 165, - 173, 182, 181, 182, 187, 196, 209, 216, 207, 227, 234, 225, 148, 155, 144, 154, - 187, 156, 160, 98, 176, 204, 199, 192, 198, 205, 199, 192, 187, 188, 202, 178, - 87, 98, 75, 139, 200, 209, 202, 193, 182, 184, 190, 159, 153, 197, 135, 101, - 186, 198, 200, 193, 186, 190, 156, 202, 174, 167, 146, 65, 150, 169, 171, 166, - 164, 155, 165, 149, 151, 142, 127, 90, 186, 197, 200, 180, 162, 151, 138, 128, - 118, 127, 65, 116, 133, 125, 112, 94, 83, 75, 66, 60, 55, 52, 49, 46, - 70, 74, 80, 87, 94, 106, 118, 132, 143, 150, 130, 111, 97, 90, 114, 114, - 116, 96, 106, 163, 167, 158, 147, 142, 141, 140, 140, 143, 148, 154, 161, 168, - 176, 179, 177, 180, 186, 197, 209, 211, 202, 226, 229, 218, 151, 162, 163, 159, - 154, 122, 137, 92, 177, 204, 198, 192, 195, 201, 200, 192, 192, 197, 181, 137, - 125, 205, 91, 152, 202, 205, 205, 193, 177, 178, 163, 145, 158, 201, 139, 110, - 194, 197, 200, 198, 177, 178, 167, 192, 164, 158, 130, 67, 153, 171, 172, 171, - 163, 164, 169, 148, 158, 148, 136, 99, 181, 200, 197, 179, 160, 135, 124, 120, - 119, 110, 61, 117, 132, 121, 108, 92, 82, 73, 65, 59, 54, 52, 48, 46, - 71, 74, 79, 85, 94, 105, 116, 131, 144, 152, 131, 103, 90, 93, 118, 119, - 118, 111, 95, 162, 167, 159, 149, 143, 142, 141, 143, 145, 149, 154, 163, 171, - 178, 176, 172, 179, 183, 198, 211, 203, 199, 225, 226, 215, 191, 182, 189, 183, - 161, 146, 156, 87, 176, 202, 198, 193, 193, 196, 196, 193, 198, 169, 125, 151, - 221, 238, 94, 150, 198, 203, 201, 196, 202, 178, 143, 154, 176, 199, 141, 114, - 192, 197, 198, 193, 170, 167, 149, 174, 152, 140, 124, 67, 154, 173, 174, 171, - 170, 180, 176, 159, 170, 160, 150, 108, 169, 198, 190, 172, 152, 119, 129, 129, - 136, 86, 71, 120, 129, 117, 102, 89, 79, 70, 62, 57, 54, 51, 47, 46, - 72, 74, 78, 84, 94, 105, 116, 130, 143, 151, 135, 106, 99, 108, 115, 123, - 119, 113, 94, 158, 167, 160, 152, 146, 144, 143, 145, 148, 151, 156, 163, 172, - 176, 171, 175, 180, 185, 200, 203, 196, 200, 225, 223, 220, 206, 171, 181, 192, - 188, 187, 160, 89, 175, 202, 198, 193, 193, 196, 194, 183, 172, 124, 175, 226, - 239, 198, 78, 151, 197, 200, 198, 193, 193, 160, 154, 183, 191, 192, 106, 115, - 192, 198, 196, 196, 180, 172, 168, 168, 139, 138, 146, 67, 155, 175, 175, 173, - 171, 175, 164, 152, 151, 140, 135, 104, 149, 194, 195, 168, 149, 125, 139, 134, - 128, 67, 80, 124, 125, 114, 100, 87, 77, 69, 60, 56, 53, 51, 47, 46, - 71, 72, 77, 83, 92, 103, 114, 128, 140, 150, 142, 117, 112, 119, 107, 132, - 133, 125, 92, 150, 169, 164, 156, 152, 147, 147, 148, 151, 153, 159, 164, 169, - 172, 171, 174, 172, 187, 200, 197, 194, 203, 224, 219, 216, 159, 168, 132, 178, - 192, 148, 124, 94, 175, 204, 198, 190, 194, 198, 193, 170, 127, 183, 239, 236, - 204, 169, 81, 151, 197, 199, 196, 193, 184, 186, 167, 193, 194, 189, 105, 116, - 192, 197, 194, 191, 190, 165, 176, 168, 143, 147, 161, 69, 157, 177, 178, 178, - 172, 164, 148, 151, 136, 131, 132, 133, 140, 172, 175, 150, 140, 131, 125, 118, - 85, 55, 105, 128, 121, 110, 97, 84, 75, 67, 59, 55, 53, 50, 47, 46, - 71, 72, 77, 82, 91, 102, 113, 126, 139, 150, 149, 130, 117, 126, 113, 144, - 149, 141, 92, 145, 172, 168, 159, 154, 149, 148, 150, 153, 156, 162, 164, 166, - 171, 171, 167, 172, 179, 187, 196, 191, 207, 222, 216, 210, 87, 87, 129, 197, - 159, 92, 142, 98, 175, 205, 198, 190, 194, 199, 193, 163, 192, 244, 236, 210, - 204, 196, 93, 150, 196, 198, 194, 186, 169, 204, 160, 186, 182, 183, 115, 115, - 191, 196, 193, 184, 190, 158, 160, 167, 155, 155, 155, 69, 158, 179, 180, 182, - 178, 167, 151, 149, 137, 142, 143, 155, 150, 159, 153, 118, 116, 126, 119, 96, - 58, 78, 128, 131, 117, 106, 93, 82, 72, 66, 58, 54, 52, 49, 47, 46, - 70, 71, 76, 82, 90, 101, 112, 125, 139, 150, 155, 142, 129, 133, 124, 150, - 139, 120, 96, 130, 173, 173, 161, 156, 152, 151, 153, 156, 160, 164, 165, 167, - 174, 166, 170, 195, 181, 170, 186, 187, 208, 218, 213, 209, 150, 119, 133, 139, - 79, 118, 186, 98, 174, 204, 198, 191, 194, 198, 193, 194, 236, 212, 201, 207, - 197, 216, 90, 151, 196, 196, 192, 181, 178, 195, 147, 185, 186, 189, 118, 113, - 190, 195, 192, 185, 186, 165, 155, 168, 160, 159, 159, 69, 158, 179, 181, 184, - 186, 181, 168, 147, 135, 135, 132, 154, 150, 145, 135, 109, 122, 123, 100, 71, - 67, 115, 136, 132, 114, 103, 90, 79, 70, 64, 57, 54, 51, 48, 46, 46, - 70, 71, 76, 81, 89, 100, 111, 124, 137, 147, 156, 148, 137, 138, 130, 150, - 125, 110, 117, 116, 169, 176, 164, 160, 157, 156, 159, 161, 163, 164, 165, 169, - 175, 166, 179, 212, 194, 161, 168, 185, 209, 213, 212, 211, 184, 197, 165, 131, - 122, 201, 192, 90, 173, 203, 199, 193, 193, 197, 193, 205, 229, 170, 163, 189, - 167, 218, 89, 151, 195, 194, 190, 189, 209, 189, 138, 168, 182, 186, 127, 114, - 189, 193, 191, 188, 172, 162, 161, 168, 158, 157, 163, 67, 157, 179, 181, 184, - 189, 189, 183, 158, 139, 132, 133, 153, 133, 123, 120, 122, 132, 99, 66, 67, - 102, 140, 141, 132, 113, 102, 87, 77, 69, 63, 56, 53, 50, 48, 46, 46, - 69, 71, 76, 80, 88, 99, 109, 122, 133, 143, 155, 150, 136, 140, 128, 148, - 143, 152, 153, 117, 160, 176, 170, 165, 162, 162, 164, 166, 167, 165, 166, 169, - 172, 173, 180, 199, 195, 148, 141, 184, 210, 211, 212, 204, 209, 201, 200, 205, - 210, 222, 213, 100, 172, 201, 200, 195, 193, 194, 193, 199, 200, 192, 206, 160, - 208, 219, 85, 149, 194, 193, 189, 190, 191, 168, 148, 157, 150, 141, 87, 114, - 188, 193, 191, 186, 150, 141, 155, 163, 158, 152, 153, 65, 156, 177, 180, 183, - 187, 187, 184, 163, 146, 142, 147, 135, 110, 124, 140, 130, 97, 67, 84, 116, - 148, 147, 145, 131, 113, 102, 86, 76, 68, 63, 56, 53, 50, 47, 46, 46, - 68, 73, 77, 81, 87, 97, 105, 117, 129, 140, 149, 154, 151, 143, 122, 132, - 155, 148, 155, 115, 140, 171, 177, 171, 166, 164, 170, 168, 172, 167, 171, 169, - 173, 177, 170, 151, 184, 107, 111, 185, 212, 208, 208, 203, 218, 203, 211, 212, - 213, 230, 228, 102, 167, 196, 200, 196, 192, 194, 191, 191, 187, 189, 217, 205, - 191, 184, 84, 146, 192, 192, 190, 183, 154, 155, 174, 187, 195, 177, 117, 117, - 186, 196, 191, 188, 135, 101, 103, 135, 149, 152, 144, 64, 157, 176, 180, 181, - 184, 181, 167, 134, 149, 144, 119, 93, 103, 112, 104, 106, 115, 131, 154, 163, - 163, 155, 144, 132, 117, 102, 89, 77, 69, 63, 57, 53, 49, 47, 46, 46, - 68, 72, 77, 80, 86, 95, 103, 114, 124, 136, 146, 153, 149, 134, 128, 129, - 142, 131, 141, 145, 118, 163, 174, 177, 173, 172, 175, 171, 170, 168, 169, 173, - 177, 202, 169, 173, 152, 71, 125, 186, 210, 206, 205, 201, 217, 189, 197, 210, - 191, 224, 203, 104, 161, 194, 200, 200, 195, 190, 188, 194, 207, 202, 183, 174, - 154, 158, 72, 146, 189, 194, 189, 182, 185, 203, 188, 185, 192, 180, 120, 114, - 186, 197, 195, 187, 173, 151, 114, 109, 123, 129, 127, 63, 152, 177, 180, 186, - 184, 168, 143, 136, 148, 138, 74, 92, 150, 163, 163, 172, 176, 177, 181, 178, - 169, 157, 146, 132, 117, 103, 90, 78, 70, 63, 57, 53, 49, 47, 47, 46, - 69, 72, 76, 79, 85, 93, 100, 110, 119, 131, 142, 150, 146, 136, 138, 123, - 119, 120, 155, 157, 131, 143, 175, 172, 177, 173, 174, 174, 168, 165, 163, 172, - 197, 204, 176, 174, 107, 81, 152, 192, 204, 198, 199, 202, 204, 186, 200, 197, - 186, 209, 170, 119, 150, 195, 193, 195, 196, 193, 185, 196, 213, 202, 161, 117, - 150, 157, 76, 151, 190, 193, 191, 185, 205, 210, 168, 173, 177, 168, 113, 118, - 183, 190, 192, 181, 178, 164, 157, 152, 127, 118, 131, 64, 156, 175, 180, 180, - 178, 158, 133, 126, 130, 131, 98, 124, 183, 186, 193, 196, 196, 190, 184, 180, - 169, 157, 147, 132, 117, 103, 91, 80, 71, 64, 57, 53, 49, 48, 47, 46, - 69, 72, 75, 78, 84, 91, 96, 106, 116, 127, 138, 148, 150, 154, 166, 157, - 151, 142, 159, 163, 148, 143, 153, 171, 179, 179, 174, 170, 162, 166, 170, 193, - 201, 193, 180, 158, 74, 119, 169, 195, 198, 187, 193, 198, 193, 191, 202, 195, - 194, 221, 203, 159, 135, 179, 186, 193, 196, 192, 181, 184, 202, 183, 198, 173, - 122, 140, 90, 139, 190, 193, 189, 182, 202, 184, 154, 170, 166, 163, 120, 111, - 176, 184, 186, 181, 181, 134, 154, 157, 164, 160, 152, 81, 148, 175, 182, 184, - 178, 149, 137, 126, 111, 107, 116, 115, 144, 152, 175, 186, 186, 185, 182, 176, - 171, 159, 147, 134, 119, 105, 93, 82, 72, 65, 57, 53, 49, 48, 47, 46, - 69, 71, 74, 76, 82, 88, 92, 101, 111, 123, 134, 145, 148, 148, 159, 171, - 167, 163, 164, 158, 152, 166, 139, 162, 168, 173, 164, 156, 158, 168, 182, 203, - 197, 186, 166, 98, 88, 147, 181, 192, 189, 183, 191, 187, 192, 189, 187, 191, - 198, 213, 213, 211, 162, 163, 175, 182, 190, 186, 181, 186, 187, 181, 201, 197, - 123, 132, 118, 134, 178, 187, 185, 194, 193, 162, 158, 168, 162, 164, 130, 97, - 165, 179, 172, 168, 170, 108, 158, 154, 157, 156, 158, 114, 128, 169, 175, 176, - 174, 134, 132, 101, 106, 104, 114, 99, 72, 103, 145, 138, 140, 150, 157, 164, - 166, 158, 147, 137, 122, 109, 95, 84, 73, 66, 58, 53, 50, 48, 47, 46, - 69, 71, 74, 75, 81, 86, 89, 97, 105, 117, 128, 140, 151, 152, 152, 160, - 141, 161, 174, 133, 128, 145, 144, 167, 160, 149, 149, 164, 192, 183, 148, 143, - 173, 170, 116, 69, 129, 164, 188, 191, 197, 206, 214, 200, 193, 188, 193, 205, - 204, 206, 200, 189, 199, 216, 205, 148, 176, 192, 188, 191, 183, 171, 168, 182, - 194, 195, 188, 164, 153, 168, 196, 207, 172, 151, 150, 162, 159, 154, 111, 113, - 149, 151, 147, 133, 127, 89, 156, 124, 142, 145, 140, 132, 138, 145, 156, 178, - 176, 109, 111, 97, 118, 111, 85, 68, 88, 119, 109, 84, 87, 98, 107, 125, - 136, 144, 146, 138, 125, 112, 99, 85, 75, 66, 58, 54, 50, 48, 47, 46, - 69, 71, 73, 74, 80, 84, 88, 95, 101, 112, 124, 135, 140, 150, 152, 154, - 144, 167, 162, 130, 102, 108, 131, 163, 166, 155, 160, 196, 201, 159, 145, 173, - 168, 137, 76, 110, 150, 170, 184, 182, 196, 210, 214, 198, 187, 190, 203, 208, - 199, 205, 191, 180, 204, 199, 185, 112, 162, 210, 198, 184, 182, 156, 176, 191, - 175, 179, 181, 177, 132, 146, 203, 188, 148, 150, 154, 162, 160, 144, 121, 140, - 130, 115, 115, 113, 106, 100, 145, 135, 138, 132, 128, 135, 147, 121, 134, 172, - 166, 93, 81, 78, 98, 103, 91, 91, 109, 115, 91, 80, 88, 95, 93, 99, - 107, 122, 136, 136, 125, 117, 101, 87, 76, 67, 59, 55, 51, 48, 47, 46, - 70, 70, 72, 73, 79, 82, 87, 93, 98, 109, 119, 130, 140, 145, 152, 152, - 142, 171, 153, 156, 158, 158, 177, 180, 189, 174, 178, 220, 201, 190, 185, 211, - 175, 86, 92, 145, 161, 170, 182, 180, 200, 208, 208, 188, 183, 192, 202, 197, - 202, 197, 177, 187, 205, 186, 162, 91, 158, 211, 191, 174, 173, 170, 189, 181, - 153, 154, 164, 172, 111, 124, 187, 160, 145, 160, 161, 163, 164, 142, 161, 114, - 100, 87, 85, 64, 70, 113, 145, 138, 134, 129, 127, 135, 130, 99, 107, 173, - 173, 132, 110, 117, 112, 114, 100, 99, 123, 113, 101, 97, 106, 106, 98, 97, - 93, 94, 106, 126, 125, 121, 103, 89, 78, 69, 61, 56, 52, 49, 47, 46, - 69, 70, 72, 72, 78, 81, 85, 91, 94, 105, 113, 124, 133, 140, 147, 152, - 148, 143, 145, 168, 177, 186, 199, 200, 212, 136, 195, 212, 172, 188, 184, 159, - 95, 94, 139, 154, 161, 169, 179, 174, 185, 180, 177, 172, 177, 187, 198, 198, - 197, 191, 187, 197, 206, 182, 174, 88, 147, 164, 137, 149, 164, 172, 185, 177, - 160, 161, 159, 146, 94, 123, 183, 171, 169, 173, 150, 127, 114, 68, 71, 78, - 107, 77, 124, 132, 128, 157, 152, 143, 137, 130, 127, 135, 130, 100, 110, 175, - 179, 152, 126, 124, 124, 129, 88, 100, 123, 97, 93, 89, 92, 86, 80, 82, - 82, 82, 78, 105, 126, 119, 106, 92, 80, 71, 62, 57, 52, 49, 47, 45, - 68, 69, 71, 72, 77, 79, 83, 88, 93, 101, 108, 117, 125, 133, 142, 146, - 149, 147, 142, 145, 176, 175, 193, 207, 181, 164, 214, 193, 145, 139, 87, 68, - 107, 137, 153, 161, 159, 165, 172, 169, 168, 143, 129, 128, 131, 134, 139, 137, - 129, 119, 118, 126, 130, 118, 121, 96, 149, 139, 109, 101, 105, 110, 112, 113, - 108, 107, 99, 97, 87, 126, 160, 130, 112, 101, 82, 72, 77, 72, 88, 103, - 93, 103, 148, 125, 100, 108, 95, 96, 92, 86, 85, 95, 90, 83, 114, 173, - 183, 164, 126, 118, 125, 103, 88, 117, 101, 71, 75, 80, 84, 78, 74, 68, - 73, 76, 66, 78, 115, 120, 108, 94, 82, 74, 64, 57, 53, 50, 47, 45, - 68, 68, 70, 71, 76, 77, 81, 86, 92, 99, 104, 111, 119, 126, 135, 141, - 151, 150, 145, 131, 118, 120, 145, 148, 117, 159, 157, 108, 100, 78, 93, 138, - 149, 155, 157, 153, 154, 161, 166, 164, 161, 137, 126, 130, 132, 130, 131, 139, - 137, 128, 125, 130, 130, 132, 128, 136, 156, 150, 132, 124, 124, 122, 120, 119, - 118, 122, 124, 120, 124, 138, 145, 130, 118, 116, 118, 120, 120, 113, 116, 114, - 115, 128, 135, 118, 107, 114, 115, 116, 114, 113, 113, 114, 118, 123, 151, 177, - 183, 177, 145, 117, 102, 78, 105, 99, 77, 77, 78, 80, 83, 80, 79, 73, - 67, 61, 60, 57, 95, 119, 109, 95, 83, 74, 65, 58, 53, 51, 48, 46, - 68, 68, 70, 71, 75, 76, 79, 84, 90, 96, 99, 105, 112, 119, 128, 136, - 147, 148, 150, 151, 145, 135, 128, 113, 100, 95, 97, 101, 117, 125, 138, 151, - 152, 154, 152, 149, 149, 155, 158, 160, 158, 151, 153, 160, 164, 160, 163, 169, - 164, 158, 156, 158, 157, 161, 152, 158, 157, 159, 155, 153, 152, 149, 147, 149, - 148, 147, 147, 147, 147, 148, 152, 144, 143, 144, 146, 146, 147, 140, 139, 136, - 146, 144, 148, 142, 142, 144, 142, 139, 139, 138, 139, 137, 150, 151, 161, 181, - 180, 183, 166, 136, 93, 104, 104, 81, 77, 88, 76, 79, 78, 76, 73, 69, - 63, 59, 62, 45, 78, 116, 109, 95, 83, 74, 65, 58, 54, 51, 48, 47, - 67, 68, 70, 71, 74, 75, 77, 82, 87, 92, 94, 99, 106, 113, 122, 129, - 140, 148, 145, 146, 143, 145, 143, 139, 138, 137, 135, 140, 138, 146, 160, 156, - 151, 147, 149, 145, 145, 151, 153, 157, 155, 157, 162, 165, 169, 164, 165, 177, - 172, 163, 162, 164, 166, 168, 164, 161, 159, 157, 158, 161, 159, 157, 154, 154, - 157, 154, 153, 152, 148, 151, 151, 147, 148, 147, 148, 150, 150, 145, 141, 145, - 146, 146, 145, 145, 143, 148, 148, 147, 146, 144, 144, 146, 155, 158, 166, 177, - 177, 168, 142, 121, 108, 106, 90, 84, 89, 88, 72, 76, 73, 75, 71, 67, - 63, 64, 61, 41, 68, 110, 110, 95, 83, 74, 65, 59, 54, 51, 48, 47, - 67, 68, 69, 70, 71, 73, 76, 79, 83, 86, 91, 96, 104, 109, 116, 122, - 132, 136, 138, 140, 141, 141, 142, 143, 145, 142, 144, 144, 145, 153, 155, 149, - 143, 141, 139, 137, 139, 143, 145, 147, 148, 150, 155, 157, 159, 157, 158, 170, - 167, 157, 154, 156, 159, 159, 156, 152, 151, 149, 149, 150, 149, 147, 146, 146, - 147, 146, 145, 144, 143, 144, 143, 142, 141, 140, 140, 141, 141, 139, 137, 137, - 138, 135, 135, 136, 134, 135, 136, 137, 136, 136, 139, 143, 149, 154, 163, 170, - 158, 109, 96, 105, 112, 106, 134, 127, 114, 96, 80, 73, 73, 70, 63, 63, - 56, 55, 44, 41, 60, 109, 107, 97, 85, 75, 65, 59, 54, 51, 49, 47, - 67, 68, 69, 69, 69, 72, 74, 77, 81, 84, 89, 94, 100, 105, 111, 116, - 123, 127, 131, 132, 134, 135, 136, 138, 141, 141, 140, 140, 143, 149, 148, 143, - 139, 135, 132, 131, 134, 137, 139, 139, 140, 143, 148, 149, 150, 149, 152, 162, - 160, 150, 147, 148, 151, 152, 149, 144, 143, 142, 141, 141, 140, 139, 138, 138, - 138, 138, 137, 136, 136, 135, 134, 134, 133, 132, 132, 133, 133, 132, 131, 128, - 127, 126, 126, 126, 126, 126, 126, 126, 127, 129, 133, 138, 143, 148, 156, 157, - 134, 98, 102, 99, 84, 91, 163, 178, 168, 154, 141, 127, 112, 92, 69, 57, - 60, 49, 40, 33, 51, 108, 111, 97, 85, 74, 65, 59, 54, 51, 49, 47, - 67, 68, 69, 70, 70, 71, 74, 75, 79, 83, 87, 91, 95, 100, 106, 110, - 115, 119, 123, 124, 127, 129, 130, 132, 134, 134, 135, 135, 138, 142, 141, 137, - 132, 129, 126, 125, 128, 131, 133, 134, 134, 136, 140, 143, 144, 142, 145, 154, - 152, 144, 141, 141, 143, 144, 142, 138, 136, 135, 135, 134, 134, 133, 132, 132, - 132, 132, 131, 130, 129, 128, 127, 126, 125, 124, 123, 126, 125, 124, 123, 121, - 120, 119, 118, 118, 118, 118, 118, 119, 120, 123, 127, 132, 139, 143, 153, 145, - 107, 86, 88, 80, 61, 81, 170, 196, 193, 189, 183, 173, 163, 149, 121, 61, - 55, 42, 28, 27, 53, 108, 110, 96, 84, 73, 64, 58, 53, 50, 49, 47, - 67, 68, 69, 70, 70, 71, 73, 74, 77, 81, 85, 88, 92, 97, 102, 106, - 110, 113, 116, 118, 121, 122, 125, 126, 128, 128, 130, 130, 134, 136, 134, 131, - 127, 124, 122, 122, 125, 127, 129, 129, 129, 131, 135, 137, 139, 136, 138, 146, - 146, 139, 136, 135, 137, 139, 137, 133, 131, 130, 129, 129, 128, 127, 127, 126, - 126, 125, 124, 123, 122, 121, 121, 119, 118, 117, 117, 119, 118, 117, 116, 115, - 114, 113, 113, 113, 113, 113, 113, 113, 114, 118, 122, 127, 134, 140, 149, 135, - 91, 66, 54, 67, 61, 88, 172, 192, 193, 193, 192, 189, 187, 183, 163, 75, - 38, 24, 22, 34, 63, 109, 107, 94, 82, 72, 63, 58, 53, 50, 48, 46, - 67, 68, 69, 70, 70, 71, 72, 73, 76, 78, 82, 85, 89, 94, 99, 102, - 105, 108, 110, 111, 114, 116, 119, 120, 122, 123, 124, 126, 129, 129, 128, 125, - 122, 120, 118, 118, 121, 124, 124, 124, 125, 126, 129, 132, 134, 131, 132, 139, - 139, 134, 129, 127, 130, 133, 131, 127, 126, 125, 124, 124, 123, 122, 121, 121, - 120, 119, 119, 117, 116, 115, 114, 113, 112, 111, 110, 111, 111, 110, 110, 108, - 108, 107, 106, 106, 106, 106, 106, 107, 108, 112, 117, 123, 130, 137, 145, 125, - 88, 64, 47, 77, 70, 96, 175, 192, 193, 193, 194, 193, 190, 187, 172, 92, - 39, 23, 47, 45, 67, 107, 108, 93, 81, 71, 62, 57, 52, 49, 47, 45, - 67, 68, 69, 70, 70, 71, 71, 72, 74, 76, 79, 82, 86, 89, 93, 96, - 101, 103, 104, 105, 108, 110, 113, 115, 114, 116, 118, 121, 124, 122, 120, 117, - 116, 114, 113, 114, 117, 119, 119, 119, 119, 120, 123, 125, 127, 124, 125, 131, - 131, 128, 122, 120, 123, 125, 124, 121, 120, 119, 118, 118, 117, 116, 115, 114, - 113, 112, 112, 109, 108, 107, 107, 106, 106, 105, 104, 103, 103, 102, 101, 101, - 100, 99, 99, 98, 98, 98, 98, 100, 101, 106, 112, 117, 124, 132, 139, 119, - 88, 67, 61, 84, 71, 94, 172, 188, 189, 188, 188, 186, 185, 187, 170, 88, - 48, 48, 69, 45, 73, 109, 108, 92, 80, 70, 61, 56, 52, 49, 47, 45, - 66, 67, 68, 69, 69, 70, 70, 71, 72, 74, 78, 80, 82, 85, 88, 91, - 95, 98, 99, 100, 102, 104, 107, 108, 107, 109, 111, 115, 117, 115, 113, 111, - 109, 108, 107, 109, 111, 113, 112, 113, 114, 115, 117, 120, 121, 118, 119, 124, - 125, 121, 116, 114, 116, 118, 118, 116, 114, 113, 112, 112, 112, 111, 110, 107, - 106, 105, 105, 103, 102, 101, 100, 100, 100, 99, 98, 97, 96, 95, 94, 94, - 93, 92, 91, 91, 91, 91, 91, 93, 95, 100, 105, 111, 118, 126, 135, 122, - 85, 62, 65, 74, 65, 85, 159, 181, 181, 180, 180, 176, 176, 175, 147, 52, - 41, 66, 57, 41, 88, 113, 102, 90, 79, 69, 61, 56, 52, 49, 47, 45, - 66, 67, 67, 68, 69, 69, 70, 71, 72, 74, 77, 79, 81, 84, 87, 89, - 90, 92, 94, 96, 100, 101, 103, 104, 103, 104, 109, 113, 112, 111, 108, 107, - 104, 102, 103, 105, 108, 109, 108, 109, 113, 114, 116, 116, 114, 113, 114, 119, - 120, 118, 112, 111, 111, 112, 113, 112, 111, 109, 107, 107, 107, 106, 105, 102, - 101, 100, 100, 99, 98, 97, 97, 95, 93, 93, 92, 91, 91, 90, 89, 88, - 88, 88, 88, 87, 87, 87, 87, 89, 90, 95, 99, 105, 113, 122, 132, 127, - 87, 55, 65, 61, 58, 69, 132, 166, 172, 172, 172, 170, 168, 156, 100, 37, - 53, 65, 48, 56, 103, 115, 101, 87, 77, 69, 62, 56, 53, 49, 45, 45, - 66, 67, 67, 68, 69, 69, 70, 71, 71, 73, 75, 77, 79, 81, 83, 85, - 87, 88, 90, 92, 94, 96, 98, 99, 99, 100, 104, 107, 106, 104, 103, 102, - 101, 100, 101, 103, 104, 105, 104, 105, 107, 109, 111, 111, 109, 108, 109, 113, - 115, 112, 108, 105, 106, 106, 108, 108, 106, 105, 103, 102, 101, 100, 99, 99, - 98, 97, 96, 94, 93, 92, 91, 90, 89, 89, 88, 87, 87, 86, 85, 85, - 84, 84, 84, 83, 83, 83, 83, 84, 85, 88, 93, 101, 109, 116, 127, 129, - 92, 52, 61, 49, 48, 50, 90, 134, 157, 159, 153, 148, 121, 92, 65, 45, - 65, 56, 38, 76, 109, 109, 102, 85, 75, 68, 61, 55, 52, 49, 45, 45, - 66, 67, 67, 68, 69, 69, 70, 71, 71, 72, 74, 75, 76, 78, 80, 81, - 82, 84, 86, 88, 89, 91, 93, 94, 94, 96, 100, 101, 99, 98, 97, 97, - 98, 97, 98, 99, 100, 101, 101, 101, 103, 105, 107, 106, 105, 104, 105, 108, - 109, 107, 103, 101, 101, 102, 102, 103, 101, 100, 98, 96, 96, 95, 94, 94, - 93, 93, 92, 90, 88, 87, 87, 86, 85, 84, 84, 83, 82, 82, 81, 80, - 80, 80, 80, 79, 79, 79, 79, 78, 80, 83, 87, 96, 104, 111, 121, 128, - 109, 65, 52, 47, 46, 48, 59, 74, 88, 89, 87, 85, 63, 46, 51, 62, - 65, 45, 59, 98, 113, 104, 99, 82, 73, 67, 59, 54, 52, 49, 45, 45, - 66, 67, 67, 68, 69, 69, 70, 71, 71, 71, 72, 74, 74, 76, 77, 78, - 79, 81, 83, 85, 87, 89, 90, 91, 92, 95, 97, 97, 95, 94, 94, 94, - 94, 94, 96, 98, 99, 100, 99, 99, 100, 102, 104, 103, 102, 100, 102, 104, - 106, 104, 100, 98, 97, 98, 99, 99, 97, 95, 94, 93, 93, 92, 92, 91, - 90, 89, 88, 87, 86, 85, 85, 82, 81, 80, 79, 79, 78, 78, 77, 75, - 75, 75, 75, 74, 74, 74, 74, 76, 76, 81, 85, 92, 100, 107, 117, 126, - 125, 96, 64, 52, 46, 54, 55, 58, 56, 54, 55, 48, 49, 51, 61, 67, - 51, 50, 90, 111, 112, 101, 93, 79, 71, 65, 58, 52, 51, 49, 45, 45, - 66, 67, 67, 68, 69, 69, 70, 71, 71, 71, 71, 72, 74, 75, 76, 77, - 77, 78, 80, 82, 85, 87, 88, 88, 89, 93, 94, 93, 92, 92, 92, 91, - 90, 90, 93, 95, 97, 98, 97, 96, 98, 100, 101, 101, 100, 98, 100, 102, - 103, 102, 99, 95, 95, 96, 97, 96, 95, 93, 91, 92, 92, 91, 90, 88, - 87, 87, 86, 85, 85, 84, 83, 80, 79, 78, 77, 77, 76, 75, 75, 73, - 73, 73, 73, 71, 71, 71, 71, 73, 74, 78, 82, 88, 96, 102, 113, 125, - 126, 124, 104, 70, 53, 57, 54, 54, 54, 50, 52, 53, 43, 46, 57, 49, - 56, 92, 112, 113, 106, 98, 85, 76, 68, 63, 56, 52, 50, 49, 45, 45, - 66, 67, 67, 68, 69, 69, 70, 70, 71, 71, 71, 71, 75, 76, 76, 76, - 76, 77, 79, 81, 82, 83, 85, 85, 86, 89, 90, 89, 89, 89, 90, 89, - 87, 88, 91, 92, 93, 94, 93, 93, 95, 97, 99, 99, 97, 96, 97, 99, - 100, 98, 96, 92, 92, 93, 94, 94, 93, 91, 90, 89, 88, 88, 87, 87, - 87, 86, 86, 84, 83, 82, 82, 79, 79, 78, 77, 77, 76, 75, 74, 72, - 72, 72, 72, 70, 70, 70, 70, 71, 72, 75, 80, 84, 91, 97, 108, 119, - 123, 128, 126, 106, 79, 70, 59, 53, 50, 48, 51, 48, 55, 49, 55, 72, - 92, 113, 117, 110, 101, 92, 82, 73, 66, 62, 55, 51, 50, 49, 45, 45, - 64, 65, 66, 66, 68, 68, 69, 70, 71, 70, 71, 71, 73, 73, 74, 74, - 75, 76, 77, 79, 80, 80, 81, 83, 84, 86, 86, 86, 86, 86, 87, 86, - 86, 87, 89, 91, 91, 92, 91, 90, 92, 94, 95, 95, 94, 93, 93, 94, - 96, 96, 93, 90, 89, 89, 91, 92, 91, 89, 89, 88, 87, 86, 85, 85, - 85, 84, 83, 81, 80, 79, 78, 78, 77, 76, 75, 75, 74, 73, 73, 70, - 69, 69, 68, 68, 68, 68, 68, 68, 70, 73, 77, 81, 87, 93, 101, 113, - 119, 124, 128, 128, 112, 102, 91, 78, 71, 69, 72, 70, 75, 80, 94, 110, - 117, 114, 111, 103, 94, 85, 77, 69, 63, 58, 54, 51, 48, 47, 44, 45, - 64, 64, 65, 66, 67, 68, 69, 70, 70, 70, 71, 71, 71, 71, 72, 73, - 74, 75, 76, 77, 79, 78, 79, 81, 84, 85, 85, 85, 85, 85, 86, 85, - 85, 87, 89, 90, 92, 91, 90, 90, 91, 92, 92, 93, 92, 92, 91, 92, - 94, 95, 92, 89, 87, 87, 89, 90, 89, 88, 87, 87, 86, 85, 85, 83, - 82, 81, 81, 78, 77, 76, 76, 76, 75, 74, 73, 73, 72, 71, 71, 69, - 69, 68, 67, 67, 67, 67, 67, 67, 70, 73, 76, 79, 84, 90, 97, 107, - 113, 120, 125, 129, 129, 126, 123, 117, 111, 108, 107, 106, 111, 116, 119, 119, - 117, 112, 105, 96, 88, 80, 72, 64, 60, 55, 52, 51, 48, 45, 44, 45, - 64, 64, 65, 66, 67, 67, 68, 69, 70, 70, 70, 70, 70, 71, 72, 73, - 74, 74, 75, 76, 78, 77, 79, 81, 83, 84, 84, 84, 84, 84, 85, 84, - 85, 87, 88, 90, 91, 90, 89, 89, 90, 91, 92, 92, 92, 91, 90, 91, - 93, 94, 91, 88, 86, 87, 88, 89, 88, 87, 87, 86, 86, 85, 84, 82, - 81, 80, 80, 78, 76, 76, 75, 75, 74, 73, 72, 72, 71, 70, 70, 69, - 68, 67, 66, 66, 66, 66, 67, 66, 69, 72, 74, 77, 82, 88, 93, 101, - 107, 113, 119, 123, 127, 129, 129, 130, 126, 125, 125, 123, 123, 122, 120, 115, - 111, 104, 97, 90, 83, 75, 68, 62, 58, 53, 51, 50, 47, 45, 44, 45, - 64, 64, 65, 66, 66, 67, 67, 68, 70, 70, 70, 70, 70, 70, 71, 72, - 73, 74, 75, 75, 76, 77, 79, 81, 82, 83, 83, 83, 83, 83, 84, 84, - 84, 86, 88, 89, 89, 89, 88, 87, 89, 90, 90, 91, 90, 89, 89, 89, - 92, 93, 90, 88, 86, 85, 87, 87, 87, 86, 85, 85, 84, 84, 83, 81, - 80, 79, 78, 77, 76, 75, 74, 74, 72, 72, 71, 70, 70, 69, 68, 68, - 67, 66, 66, 66, 66, 66, 65, 65, 67, 70, 71, 74, 78, 83, 88, 95, - 101, 107, 111, 115, 118, 122, 121, 120, 120, 120, 121, 120, 118, 115, 112, 109, - 104, 97, 90, 85, 78, 71, 65, 59, 56, 52, 49, 49, 47, 45, 44, 45, - 64, 64, 65, 66, 66, 66, 67, 68, 69, 69, 69, 69, 69, 70, 71, 71, - 72, 73, 74, 75, 75, 76, 79, 81, 81, 82, 82, 82, 82, 82, 83, 83, - 84, 85, 87, 88, 89, 88, 87, 86, 87, 88, 89, 89, 89, 88, 87, 88, - 91, 92, 89, 87, 85, 84, 85, 86, 86, 85, 84, 84, 83, 82, 82, 80, - 79, 78, 77, 76, 75, 74, 74, 73, 71, 71, 70, 69, 69, 68, 67, 67, - 67, 66, 65, 65, 65, 65, 65, 64, 65, 67, 68, 71, 75, 79, 83, 91, - 96, 101, 106, 110, 112, 114, 113, 113, 115, 116, 115, 113, 112, 110, 108, 103, - 98, 91, 85, 80, 74, 68, 62, 56, 54, 50, 48, 48, 46, 45, 45, 45, - 64, 64, 65, 65, 65, 66, 67, 67, 69, 69, 69, 69, 69, 69, 70, 71, - 71, 72, 73, 74, 73, 75, 78, 81, 80, 81, 81, 81, 81, 81, 82, 82, - 83, 85, 87, 88, 88, 87, 86, 86, 86, 87, 88, 88, 88, 87, 86, 87, - 90, 91, 88, 86, 85, 83, 84, 85, 85, 84, 83, 83, 82, 81, 81, 79, - 78, 77, 76, 76, 75, 74, 74, 71, 71, 70, 69, 69, 68, 67, 66, 67, - 66, 66, 65, 65, 65, 65, 64, 63, 64, 65, 66, 69, 72, 76, 79, 84, - 89, 95, 98, 103, 106, 107, 107, 106, 108, 109, 107, 104, 103, 102, 99, 95, - 91, 85, 80, 75, 69, 63, 58, 54, 52, 48, 47, 47, 46, 45, 45, 45, - 64, 64, 65, 65, 65, 66, 67, 67, 69, 69, 69, 69, 69, 69, 70, 71, - 71, 72, 73, 73, 73, 74, 78, 80, 80, 81, 81, 81, 81, 81, 82, 82, - 83, 85, 86, 87, 87, 86, 86, 85, 85, 86, 87, 88, 87, 86, 85, 86, - 90, 90, 87, 86, 85, 83, 83, 84, 84, 83, 83, 83, 82, 81, 80, 78, - 77, 76, 76, 76, 75, 74, 73, 71, 70, 69, 69, 68, 68, 67, 66, 66, - 66, 65, 65, 65, 65, 65, 64, 63, 63, 65, 65, 67, 70, 74, 76, 79, - 83, 88, 91, 91, 96, 99, 100, 99, 102, 101, 99, 99, 97, 94, 92, 88, - 85, 81, 75, 69, 64, 59, 55, 52, 50, 48, 46, 46, 46, 45, 45, 45, - 64, 64, 65, 65, 65, 65, 65, 65, 66, 67, 67, 68, 68, 69, 70, 71, - 71, 71, 72, 73, 73, 75, 77, 79, 79, 80, 80, 79, 79, 79, 80, 80, - 82, 83, 84, 84, 84, 84, 84, 84, 85, 86, 87, 87, 86, 85, 84, 85, - 86, 88, 86, 83, 81, 79, 79, 82, 83, 83, 83, 81, 79, 79, 78, 77, - 76, 75, 75, 75, 75, 74, 73, 71, 70, 69, 69, 68, 68, 67, 67, 67, - 67, 66, 65, 65, 64, 63, 62, 62, 62, 64, 64, 64, 67, 69, 71, 76, - 79, 83, 86, 87, 90, 93, 93, 92, 92, 92, 92, 91, 89, 87, 85, 82, - 78, 73, 68, 64, 61, 56, 53, 51, 49, 47, 45, 45, 45, 45, 45, 45, - 64, 64, 64, 64, 64, 64, 64, 64, 65, 66, 67, 68, 68, 69, 70, 70, - 70, 71, 72, 73, 73, 75, 76, 78, 79, 79, 79, 79, 79, 79, 80, 80, - 81, 82, 83, 83, 83, 83, 83, 84, 84, 85, 86, 86, 85, 84, 83, 83, - 86, 87, 85, 82, 80, 79, 79, 81, 82, 82, 82, 80, 79, 78, 77, 76, - 75, 74, 74, 74, 74, 73, 72, 71, 70, 69, 69, 68, 68, 68, 68, 68, - 67, 66, 65, 65, 64, 62, 61, 61, 62, 63, 64, 63, 65, 67, 69, 71, - 74, 77, 79, 81, 84, 86, 86, 85, 85, 85, 85, 83, 82, 80, 79, 77, - 74, 70, 66, 62, 58, 54, 52, 50, 49, 47, 45, 45, 45, 45, 45, 45, - 64, 64, 64, 64, 64, 64, 64, 64, 65, 66, 66, 67, 68, 68, 69, 70, - 70, 71, 71, 72, 73, 74, 76, 77, 77, 78, 78, 78, 78, 78, 79, 80, - 81, 82, 82, 83, 82, 82, 82, 82, 84, 85, 85, 85, 84, 83, 82, 83, - 85, 87, 85, 82, 80, 78, 78, 80, 81, 81, 81, 80, 79, 78, 77, 75, - 74, 73, 73, 73, 73, 72, 71, 71, 70, 69, 69, 68, 68, 68, 68, 67, - 66, 66, 65, 65, 64, 62, 61, 61, 61, 62, 62, 62, 63, 65, 66, 66, - 68, 70, 73, 75, 77, 78, 80, 79, 79, 79, 78, 76, 75, 73, 73, 71, - 68, 64, 62, 59, 56, 52, 50, 50, 48, 46, 45, 45, 45, 45, 45, 45, - 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 66, 67, 67, 68, 68, 69, - 70, 70, 71, 72, 73, 74, 75, 76, 77, 78, 78, 78, 78, 78, 79, 79, - 80, 81, 82, 82, 81, 81, 81, 81, 82, 83, 84, 83, 82, 82, 81, 81, - 84, 86, 84, 81, 79, 78, 78, 79, 80, 80, 80, 79, 78, 77, 77, 75, - 73, 73, 72, 73, 72, 71, 71, 71, 70, 69, 69, 67, 67, 67, 67, 67, - 66, 65, 65, 65, 64, 62, 61, 61, 61, 61, 61, 61, 61, 62, 63, 63, - 64, 67, 69, 71, 72, 73, 74, 74, 74, 74, 74, 72, 71, 69, 67, 65, - 63, 60, 58, 56, 53, 50, 49, 48, 48, 46, 45, 45, 45, 45, 44, 44, - 63, 63, 63, 63, 63, 63, 63, 63, 64, 65, 66, 66, 67, 67, 68, 69, - 69, 70, 71, 72, 74, 74, 74, 74, 76, 77, 77, 77, 77, 77, 78, 78, - 80, 80, 82, 81, 80, 80, 80, 80, 81, 81, 82, 82, 81, 80, 79, 80, - 83, 85, 82, 80, 79, 77, 77, 78, 79, 79, 79, 78, 78, 77, 76, 74, - 73, 72, 72, 72, 72, 71, 70, 70, 70, 69, 69, 67, 67, 67, 67, 66, - 66, 65, 64, 64, 64, 62, 61, 61, 60, 60, 60, 60, 60, 60, 61, 62, - 63, 65, 66, 69, 70, 70, 71, 70, 70, 70, 70, 68, 66, 64, 63, 61, - 59, 57, 54, 53, 50, 47, 47, 47, 47, 46, 45, 45, 45, 45, 44, 44, - 63, 63, 63, 63, 63, 63, 63, 63, 64, 64, 65, 66, 66, 67, 68, 68, - 69, 69, 70, 71, 74, 73, 73, 74, 75, 75, 75, 76, 76, 77, 77, 78, - 79, 80, 81, 81, 79, 79, 79, 79, 80, 80, 81, 81, 80, 79, 78, 79, - 82, 83, 81, 79, 78, 76, 77, 77, 77, 77, 77, 77, 77, 76, 75, 74, - 73, 72, 71, 71, 71, 70, 70, 70, 70, 69, 69, 66, 66, 66, 66, 66, - 65, 64, 64, 64, 64, 62, 61, 61, 60, 59, 58, 58, 58, 58, 58, 59, - 59, 61, 63, 65, 66, 66, 66, 65, 64, 64, 64, 63, 61, 60, 59, 58, - 57, 54, 52, 50, 47, 46, 46, 46, 46, 46, 45, 45, 45, 45, 44, 43, - 62, 62, 62, 62, 63, 63, 63, 63, 64, 64, 65, 65, 65, 66, 67, 67, - 68, 69, 70, 71, 73, 73, 73, 73, 74, 74, 74, 74, 75, 75, 76, 77, - 79, 79, 80, 80, 79, 79, 79, 78, 79, 80, 81, 81, 79, 79, 78, 78, - 80, 82, 80, 79, 77, 76, 76, 77, 77, 77, 77, 77, 76, 75, 74, 72, - 72, 71, 71, 71, 71, 70, 70, 70, 69, 68, 68, 66, 66, 66, 66, 65, - 64, 64, 63, 64, 63, 62, 61, 60, 59, 58, 57, 58, 58, 57, 57, 58, - 58, 59, 60, 62, 62, 63, 62, 62, 62, 61, 61, 60, 59, 58, 57, 56, - 55, 53, 52, 49, 48, 46, 45, 45, 46, 45, 45, 45, 45, 45, 44, 43, - 60, 61, 61, 62, 63, 63, 63, 63, 64, 64, 65, 65, 65, 65, 66, 67, - 67, 68, 70, 72, 73, 73, 73, 73, 73, 73, 73, 72, 71, 72, 73, 75, - 78, 78, 79, 79, 79, 79, 79, 78, 78, 79, 79, 80, 79, 78, 78, 77, - 78, 80, 80, 78, 76, 75, 75, 76, 77, 77, 77, 76, 75, 74, 73, 71, - 71, 71, 71, 70, 70, 70, 70, 68, 67, 67, 66, 66, 66, 66, 66, 65, - 64, 63, 63, 62, 61, 60, 60, 59, 59, 58, 58, 58, 58, 58, 58, 59, - 59, 59, 59, 59, 59, 59, 59, 60, 59, 58, 58, 58, 58, 57, 55, 53, - 52, 51, 50, 50, 48, 47, 47, 46, 46, 45, 45, 45, 45, 45, 44, 43, - 60, 61, 61, 62, 63, 63, 63, 63, 64, 64, 65, 65, 65, 65, 66, 67, - 67, 68, 70, 72, 73, 73, 73, 73, 73, 73, 73, 72, 71, 72, 72, 74, - 77, 78, 79, 79, 79, 79, 79, 78, 78, 79, 79, 80, 79, 78, 77, 77, - 78, 80, 80, 78, 76, 75, 75, 75, 76, 76, 76, 76, 75, 74, 73, 71, - 71, 71, 71, 70, 70, 70, 70, 68, 67, 67, 66, 66, 66, 66, 66, 65, - 64, 63, 63, 62, 61, 60, 60, 59, 59, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 57, 56, 55, 55, 56, 55, 54, 53, 51, - 51, 50, 49, 50, 49, 48, 47, 46, 46, 45, 45, 45, 45, 45, 44, 43, - 60, 61, 61, 62, 63, 63, 63, 63, 64, 64, 65, 65, 65, 65, 66, 67, - 67, 68, 70, 72, 73, 73, 73, 73, 73, 73, 73, 72, 71, 72, 72, 74, - 77, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 78, 77, 77, - 78, 80, 80, 78, 76, 75, 75, 75, 76, 76, 76, 76, 75, 74, 73, 71, - 71, 71, 71, 70, 70, 70, 70, 68, 67, 67, 66, 66, 66, 66, 66, 65, - 64, 63, 63, 62, 61, 60, 60, 59, 59, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 57, 56, 56, 56, 56, 55, 54, 54, 53, 54, 53, 52, 51, 50, - 49, 48, 48, 50, 49, 48, 47, 46, 46, 45, 45, 45, 45, 45, 44, 43, - 18, 17, 17, 16, 16, 17, 17, 18, 19, 19, 19, 20, 19, 19, 20, 22, - 27, 29, 31, 30, 30, 31, 32, 32, 31, 31, 36, 38, 39, 41, 37, 35, - 43, 45, 39, 36, 38, 40, 46, 52, 40, 47, 45, 50, 52, 52, 48, 46, - 54, 45, 41, 43, 41, 37, 33, 35, 41, 35, 31, 36, 38, 34, 30, 30, - 31, 29, 30, 32, 34, 35, 36, 36, 35, 32, 30, 27, 25, 24, 23, 20, - 19, 19, 19, 19, 20, 20, 19, 14, 13, 14, 15, 15, 16, 17, 16, 14, - 13, 12, 12, 12, 11, 10, 10, 12, 12, 12, 11, 11, 10, 9, 9, 11, - 11, 11, 11, 9, 7, 7, 9, 11, 11, 11, 9, 8, 9, 8, 7, 7, - 18, 17, 17, 16, 16, 17, 17, 18, 19, 19, 19, 20, 20, 20, 21, 22, - 26, 28, 29, 29, 30, 31, 32, 33, 32, 32, 34, 36, 39, 41, 38, 37, - 44, 47, 42, 39, 40, 42, 49, 54, 45, 49, 49, 53, 54, 54, 51, 49, - 58, 49, 45, 45, 42, 37, 35, 38, 41, 35, 35, 39, 38, 34, 29, 30, - 32, 31, 32, 33, 35, 35, 35, 36, 35, 32, 30, 27, 25, 24, 23, 20, - 19, 19, 19, 19, 20, 20, 19, 14, 13, 14, 15, 15, 16, 17, 16, 14, - 13, 12, 12, 12, 11, 10, 10, 12, 12, 12, 11, 11, 10, 9, 9, 11, - 11, 11, 11, 9, 7, 7, 9, 11, 11, 11, 9, 9, 9, 9, 7, 7, - 18, 17, 17, 16, 16, 17, 17, 18, 19, 20, 20, 20, 21, 21, 22, 22, - 25, 27, 28, 29, 31, 32, 34, 34, 34, 33, 34, 35, 39, 41, 41, 38, - 43, 49, 46, 42, 41, 44, 50, 56, 50, 51, 53, 55, 56, 56, 52, 53, - 59, 51, 49, 49, 44, 38, 38, 41, 40, 37, 39, 42, 39, 34, 29, 31, - 33, 34, 34, 35, 36, 35, 36, 36, 34, 31, 29, 27, 25, 24, 23, 20, - 19, 19, 19, 19, 20, 20, 19, 14, 13, 14, 15, 15, 16, 17, 16, 14, - 13, 12, 12, 12, 11, 10, 10, 12, 12, 12, 11, 11, 10, 9, 9, 11, - 11, 11, 11, 9, 7, 7, 9, 11, 11, 11, 9, 9, 10, 9, 7, 7, - 18, 17, 17, 16, 16, 17, 17, 18, 20, 20, 20, 20, 21, 21, 22, 22, - 24, 26, 28, 29, 31, 32, 34, 35, 35, 35, 34, 36, 39, 41, 43, 41, - 41, 48, 48, 44, 42, 43, 49, 56, 54, 51, 55, 55, 57, 57, 53, 54, - 60, 52, 52, 51, 45, 39, 41, 43, 41, 39, 42, 43, 38, 33, 30, 32, - 35, 36, 37, 37, 37, 36, 35, 35, 33, 30, 28, 26, 25, 23, 22, 20, - 19, 19, 19, 19, 20, 20, 19, 14, 13, 14, 15, 15, 16, 17, 16, 14, - 13, 12, 12, 12, 11, 10, 10, 12, 12, 12, 11, 11, 10, 9, 9, 11, - 11, 11, 11, 9, 7, 7, 9, 11, 11, 11, 10, 10, 10, 10, 8, 8, - 18, 17, 17, 16, 16, 17, 17, 18, 20, 20, 20, 19, 21, 21, 22, 24, - 25, 27, 29, 30, 31, 32, 35, 36, 37, 39, 37, 37, 38, 40, 45, 45, - 42, 46, 50, 47, 43, 44, 50, 56, 58, 51, 59, 57, 59, 60, 56, 57, - 60, 53, 54, 50, 46, 43, 45, 44, 42, 44, 45, 42, 37, 33, 33, 35, - 38, 38, 39, 39, 37, 37, 35, 34, 32, 29, 27, 26, 24, 23, 22, 20, - 19, 19, 19, 19, 20, 20, 19, 14, 13, 14, 15, 15, 16, 17, 16, 14, - 13, 12, 12, 12, 11, 10, 10, 12, 12, 12, 11, 11, 10, 9, 9, 11, - 11, 11, 11, 9, 7, 7, 9, 11, 11, 11, 10, 10, 11, 10, 9, 9, - 18, 17, 17, 16, 16, 17, 17, 18, 20, 19, 19, 19, 21, 21, 23, 24, - 26, 28, 29, 30, 30, 32, 35, 36, 38, 41, 39, 37, 36, 39, 45, 50, - 46, 46, 54, 52, 45, 47, 54, 60, 63, 53, 63, 61, 64, 64, 61, 61, - 61, 54, 57, 50, 47, 45, 46, 44, 43, 47, 44, 39, 35, 33, 36, 39, - 40, 38, 38, 38, 38, 36, 33, 32, 30, 27, 25, 24, 22, 21, 20, 20, - 19, 19, 19, 19, 20, 20, 19, 14, 13, 14, 15, 15, 16, 17, 16, 14, - 13, 12, 12, 12, 11, 10, 10, 12, 12, 12, 11, 11, 10, 9, 9, 11, - 11, 11, 11, 9, 7, 7, 9, 11, 11, 11, 10, 11, 11, 11, 10, 10, - 18, 17, 17, 16, 16, 17, 17, 18, 19, 19, 19, 19, 20, 22, 23, 24, - 25, 26, 28, 29, 30, 31, 34, 35, 37, 41, 41, 38, 37, 38, 44, 50, - 50, 46, 52, 56, 48, 48, 56, 60, 66, 56, 64, 65, 67, 67, 62, 64, - 60, 55, 57, 51, 47, 48, 47, 42, 46, 49, 43, 38, 36, 36, 38, 41, - 41, 39, 39, 38, 37, 34, 32, 31, 29, 27, 25, 24, 23, 22, 20, 20, - 19, 20, 19, 19, 21, 20, 20, 15, 13, 14, 15, 15, 16, 17, 16, 14, - 13, 12, 12, 12, 11, 10, 10, 12, 12, 12, 11, 11, 10, 10, 9, 11, - 11, 11, 10, 9, 8, 7, 9, 11, 11, 11, 11, 12, 12, 12, 10, 10, - 18, 17, 18, 16, 16, 17, 17, 18, 19, 19, 19, 20, 20, 22, 25, 25, - 25, 27, 29, 30, 31, 33, 34, 36, 38, 41, 44, 44, 41, 39, 42, 47, - 52, 49, 48, 59, 54, 49, 56, 60, 69, 62, 66, 69, 69, 71, 63, 69, - 59, 60, 57, 53, 50, 55, 50, 45, 52, 48, 41, 37, 39, 41, 41, 43, - 42, 41, 40, 37, 35, 31, 30, 30, 29, 27, 26, 25, 24, 22, 21, 21, - 20, 20, 20, 20, 21, 21, 20, 15, 14, 15, 16, 15, 16, 17, 16, 14, - 13, 13, 12, 12, 11, 10, 10, 13, 13, 12, 12, 12, 11, 10, 10, 11, - 11, 11, 10, 9, 9, 9, 10, 13, 12, 11, 11, 13, 13, 13, 12, 11, - 18, 17, 18, 17, 17, 17, 17, 18, 18, 18, 19, 20, 21, 23, 26, 26, - 27, 29, 32, 32, 33, 35, 36, 38, 40, 43, 47, 47, 44, 43, 43, 45, - 53, 55, 52, 56, 62, 54, 54, 62, 71, 68, 70, 73, 73, 74, 66, 72, - 61, 65, 60, 53, 59, 59, 51, 54, 55, 46, 38, 38, 43, 46, 46, 45, - 42, 40, 38, 35, 34, 31, 29, 29, 28, 26, 25, 24, 23, 21, 20, 21, - 20, 20, 20, 20, 21, 21, 20, 15, 14, 15, 16, 15, 16, 17, 17, 14, - 14, 13, 12, 12, 11, 10, 11, 13, 13, 12, 12, 12, 11, 10, 10, 11, - 11, 11, 10, 9, 9, 9, 10, 13, 12, 11, 11, 13, 13, 13, 12, 12, - 19, 18, 18, 17, 17, 17, 18, 18, 18, 19, 20, 21, 22, 24, 28, 28, - 28, 30, 34, 34, 36, 37, 40, 40, 41, 45, 49, 49, 49, 50, 46, 45, - 51, 61, 59, 52, 65, 61, 54, 64, 74, 75, 74, 77, 78, 78, 71, 75, - 63, 69, 62, 56, 64, 60, 57, 62, 55, 42, 38, 42, 48, 51, 52, 48, - 44, 40, 37, 34, 33, 31, 29, 29, 28, 26, 24, 23, 22, 20, 19, 19, - 20, 20, 20, 20, 21, 21, 20, 15, 14, 15, 16, 16, 17, 18, 17, 15, - 14, 13, 13, 13, 12, 11, 11, 13, 13, 12, 12, 12, 11, 10, 10, 11, - 11, 11, 10, 9, 9, 9, 11, 13, 12, 11, 11, 13, 13, 13, 13, 13, - 20, 19, 19, 18, 18, 18, 18, 18, 18, 18, 21, 23, 23, 27, 30, 31, - 28, 31, 35, 37, 38, 39, 41, 42, 42, 46, 48, 51, 54, 55, 52, 49, - 50, 61, 66, 55, 64, 69, 60, 63, 75, 82, 78, 82, 84, 83, 77, 80, - 69, 72, 63, 62, 65, 60, 65, 63, 49, 43, 45, 49, 54, 55, 54, 48, - 43, 37, 34, 32, 33, 31, 29, 28, 27, 25, 23, 21, 20, 18, 17, 19, - 20, 20, 20, 20, 21, 21, 20, 15, 14, 15, 17, 17, 18, 19, 18, 16, - 15, 14, 14, 13, 12, 11, 11, 13, 13, 12, 12, 12, 11, 10, 10, 11, - 11, 11, 10, 10, 10, 10, 11, 13, 12, 11, 11, 13, 13, 13, 13, 14, - 20, 19, 20, 18, 18, 19, 19, 18, 19, 19, 23, 24, 25, 29, 33, 34, - 30, 33, 38, 41, 41, 42, 44, 45, 47, 49, 51, 53, 56, 59, 59, 57, - 53, 59, 68, 65, 65, 75, 71, 66, 78, 90, 82, 88, 92, 89, 84, 85, - 75, 75, 64, 71, 67, 69, 73, 60, 47, 46, 52, 56, 59, 57, 54, 46, - 41, 36, 33, 32, 32, 31, 29, 28, 27, 25, 24, 21, 20, 18, 17, 19, - 20, 20, 20, 20, 21, 21, 20, 15, 14, 15, 17, 17, 18, 19, 18, 16, - 15, 15, 14, 14, 13, 12, 12, 13, 13, 12, 12, 12, 11, 10, 10, 11, - 11, 11, 10, 10, 10, 10, 11, 13, 12, 11, 11, 13, 13, 13, 13, 14, - 20, 19, 20, 19, 19, 19, 19, 18, 18, 20, 23, 25, 26, 30, 34, 35, - 32, 35, 39, 42, 43, 44, 46, 48, 50, 51, 52, 53, 57, 61, 65, 63, - 56, 55, 67, 76, 69, 78, 84, 70, 79, 95, 86, 93, 97, 94, 90, 90, - 82, 76, 66, 79, 70, 79, 77, 58, 49, 52, 58, 60, 61, 58, 53, 44, - 39, 35, 32, 32, 30, 31, 30, 28, 27, 25, 24, 21, 20, 18, 17, 19, - 19, 20, 19, 19, 20, 19, 20, 16, 15, 16, 17, 18, 20, 19, 19, 16, - 16, 15, 14, 14, 13, 12, 12, 13, 13, 12, 12, 12, 11, 10, 9, 9, - 10, 11, 11, 11, 11, 11, 12, 12, 12, 11, 11, 13, 13, 13, 13, 14, - 21, 21, 22, 21, 20, 20, 21, 20, 18, 22, 27, 29, 32, 35, 36, 36, - 30, 33, 38, 35, 35, 42, 50, 47, 49, 52, 57, 60, 58, 68, 71, 65, - 62, 63, 67, 76, 77, 75, 103, 74, 77, 100, 96, 95, 98, 93, 98, 95, - 89, 79, 74, 78, 78, 84, 74, 61, 62, 63, 62, 63, 60, 56, 52, 44, - 40, 37, 35, 34, 34, 32, 30, 27, 25, 25, 24, 22, 21, 20, 19, 16, - 16, 17, 16, 17, 17, 16, 17, 17, 17, 18, 20, 20, 20, 20, 19, 14, - 12, 12, 11, 12, 12, 12, 13, 15, 15, 14, 14, 13, 12, 11, 9, 9, - 9, 9, 9, 11, 12, 12, 12, 11, 11, 11, 11, 13, 13, 14, 15, 14, - 21, 22, 22, 22, 20, 20, 23, 22, 19, 23, 28, 31, 35, 37, 37, 36, - 28, 31, 33, 37, 41, 41, 45, 51, 50, 52, 53, 58, 61, 54, 65, 73, - 69, 74, 67, 68, 84, 76, 103, 88, 68, 106, 106, 106, 101, 97, 106, 97, - 91, 72, 82, 84, 86, 77, 61, 67, 74, 73, 64, 60, 57, 54, 52, 45, - 41, 38, 36, 35, 35, 33, 31, 26, 24, 23, 23, 22, 21, 21, 20, 16, - 14, 15, 15, 15, 16, 15, 17, 19, 19, 20, 22, 21, 22, 21, 19, 14, - 12, 11, 11, 12, 12, 12, 14, 17, 16, 16, 15, 14, 13, 12, 10, 8, - 8, 8, 9, 11, 11, 12, 11, 9, 9, 10, 12, 13, 14, 15, 15, 15, - 20, 20, 22, 21, 19, 21, 23, 24, 22, 25, 30, 32, 36, 38, 38, 37, - 34, 36, 37, 46, 48, 56, 61, 68, 62, 63, 64, 58, 53, 56, 53, 56, - 72, 90, 87, 76, 83, 85, 94, 101, 79, 113, 115, 114, 108, 105, 110, 99, - 97, 83, 93, 82, 91, 72, 64, 82, 82, 78, 67, 57, 53, 51, 49, 44, - 41, 38, 36, 34, 34, 32, 31, 26, 24, 24, 24, 22, 23, 23, 21, 18, - 18, 19, 18, 19, 19, 18, 19, 20, 19, 21, 21, 21, 22, 21, 20, 16, - 15, 14, 13, 15, 15, 15, 16, 18, 18, 17, 16, 16, 15, 14, 11, 9, - 9, 8, 9, 11, 12, 12, 10, 10, 10, 10, 11, 13, 14, 14, 15, 15, - 20, 20, 21, 21, 19, 21, 24, 25, 25, 28, 32, 32, 34, 36, 37, 38, - 36, 41, 51, 60, 64, 71, 67, 59, 51, 51, 59, 60, 62, 57, 53, 59, - 75, 96, 102, 91, 80, 91, 92, 91, 87, 110, 128, 123, 115, 112, 117, 107, - 89, 83, 92, 95, 78, 74, 74, 89, 89, 79, 67, 56, 49, 47, 47, 44, - 41, 39, 36, 33, 32, 30, 30, 28, 26, 26, 26, 24, 25, 25, 23, 22, - 21, 22, 21, 21, 22, 21, 22, 21, 21, 22, 21, 21, 22, 22, 21, 18, - 17, 16, 15, 16, 16, 16, 17, 19, 19, 18, 18, 17, 17, 16, 13, 11, - 10, 10, 11, 12, 13, 13, 11, 10, 10, 10, 11, 13, 13, 14, 14, 14, - 19, 20, 20, 21, 19, 21, 25, 27, 28, 31, 33, 31, 31, 35, 37, 41, - 42, 52, 66, 67, 59, 47, 37, 27, 23, 21, 30, 29, 41, 65, 73, 72, - 85, 81, 98, 99, 84, 88, 91, 101, 112, 120, 147, 138, 132, 128, 134, 122, - 97, 108, 106, 111, 88, 96, 101, 104, 95, 78, 63, 55, 48, 46, 44, 42, - 41, 38, 37, 33, 31, 29, 28, 30, 30, 28, 29, 28, 28, 28, 27, 25, - 24, 25, 25, 24, 25, 24, 26, 22, 21, 21, 21, 21, 22, 22, 21, 20, - 19, 18, 17, 18, 18, 18, 19, 21, 21, 20, 20, 20, 19, 18, 16, 14, - 14, 13, 14, 15, 15, 15, 12, 10, 10, 10, 11, 13, 13, 14, 13, 13, - 18, 18, 20, 20, 19, 22, 25, 28, 30, 32, 32, 30, 30, 35, 39, 48, - 60, 67, 62, 46, 27, 15, 11, 19, 27, 28, 33, 25, 23, 37, 73, 98, - 97, 29, 27, 46, 86, 87, 90, 113, 80, 69, 80, 77, 75, 70, 78, 67, - 65, 79, 58, 46, 56, 66, 74, 93, 88, 77, 61, 54, 48, 44, 42, 41, - 40, 37, 36, 34, 32, 30, 29, 32, 32, 31, 32, 30, 31, 31, 30, 26, - 26, 27, 26, 26, 27, 26, 26, 23, 21, 20, 20, 21, 21, 21, 21, 20, - 20, 19, 18, 19, 19, 19, 20, 22, 21, 20, 20, 20, 19, 18, 17, 16, - 16, 16, 16, 16, 16, 16, 14, 9, 9, 9, 10, 12, 13, 13, 12, 11, - 17, 18, 19, 19, 19, 21, 25, 28, 31, 32, 30, 28, 29, 37, 46, 59, - 73, 64, 34, 15, 22, 24, 22, 36, 50, 57, 61, 51, 44, 40, 56, 73, - 85, 15, 29, 29, 77, 99, 90, 143, 83, 72, 71, 79, 76, 73, 82, 83, - 79, 58, 54, 67, 72, 95, 98, 68, 71, 74, 61, 56, 48, 43, 40, 39, - 39, 37, 34, 35, 35, 33, 31, 34, 34, 33, 33, 32, 33, 31, 31, 28, - 27, 27, 28, 27, 27, 27, 26, 23, 22, 20, 19, 20, 20, 20, 20, 19, - 19, 18, 18, 19, 19, 19, 20, 21, 21, 20, 19, 20, 19, 18, 18, 17, - 17, 16, 16, 16, 16, 16, 14, 10, 9, 8, 10, 11, 12, 12, 12, 11, - 16, 16, 19, 20, 19, 22, 24, 30, 32, 33, 27, 27, 29, 46, 57, 72, - 65, 24, 23, 33, 40, 48, 56, 59, 61, 57, 50, 45, 52, 60, 64, 53, - 57, 38, 45, 28, 63, 118, 104, 135, 76, 69, 76, 88, 84, 88, 99, 86, - 65, 52, 62, 93, 100, 107, 99, 32, 67, 75, 63, 51, 45, 41, 39, 39, - 38, 36, 35, 35, 35, 34, 34, 36, 35, 34, 34, 33, 33, 31, 31, 28, - 28, 28, 28, 29, 29, 28, 27, 24, 22, 22, 21, 19, 19, 18, 17, 17, - 18, 18, 18, 19, 20, 20, 21, 22, 22, 22, 22, 22, 21, 20, 18, 17, - 17, 16, 16, 17, 18, 17, 13, 11, 9, 7, 7, 8, 8, 9, 11, 12, - 15, 16, 18, 20, 19, 23, 25, 30, 32, 33, 28, 28, 37, 56, 69, 65, - 38, 27, 38, 52, 62, 61, 50, 36, 38, 45, 44, 39, 41, 50, 55, 57, - 54, 70, 75, 45, 67, 123, 114, 138, 79, 61, 81, 92, 102, 92, 118, 81, - 76, 75, 90, 122, 129, 130, 111, 29, 62, 73, 60, 49, 46, 43, 42, 43, - 42, 40, 38, 38, 38, 37, 36, 38, 37, 36, 36, 34, 34, 32, 31, 28, - 28, 28, 28, 30, 29, 28, 27, 24, 23, 22, 21, 19, 20, 18, 17, 17, - 17, 17, 17, 20, 20, 22, 22, 20, 20, 20, 20, 20, 20, 18, 18, 18, - 18, 17, 17, 17, 18, 16, 14, 13, 11, 10, 8, 8, 8, 9, 10, 11, - 14, 16, 18, 20, 20, 23, 27, 32, 34, 34, 31, 33, 46, 64, 75, 45, - 40, 43, 52, 58, 56, 40, 28, 40, 46, 59, 64, 65, 51, 42, 38, 49, - 63, 80, 75, 47, 71, 126, 120, 143, 111, 84, 84, 81, 83, 75, 63, 32, - 58, 93, 118, 139, 121, 91, 72, 33, 62, 70, 58, 50, 49, 48, 47, 47, - 47, 44, 43, 42, 42, 41, 40, 39, 38, 38, 37, 35, 35, 33, 33, 29, - 29, 29, 30, 31, 30, 29, 28, 26, 25, 23, 23, 21, 21, 19, 17, 16, - 16, 17, 18, 20, 21, 23, 23, 19, 19, 19, 19, 19, 18, 17, 18, 20, - 19, 18, 17, 16, 16, 14, 14, 15, 12, 11, 9, 8, 8, 9, 9, 10, - 15, 16, 19, 19, 21, 25, 28, 35, 36, 37, 35, 40, 56, 75, 48, 16, - 30, 37, 41, 45, 39, 18, 34, 63, 61, 67, 73, 79, 83, 70, 31, 43, - 71, 94, 70, 36, 65, 121, 119, 140, 144, 128, 113, 71, 64, 52, 9, 17, - 74, 112, 126, 107, 45, 47, 49, 46, 67, 67, 59, 55, 54, 54, 54, 52, - 49, 47, 46, 44, 44, 43, 42, 40, 39, 37, 37, 37, 37, 35, 34, 31, - 32, 31, 32, 34, 32, 32, 31, 30, 28, 25, 25, 22, 22, 21, 19, 16, - 17, 18, 19, 20, 21, 23, 23, 19, 19, 19, 19, 19, 19, 18, 18, 20, - 19, 18, 18, 16, 16, 13, 13, 16, 12, 9, 9, 9, 7, 7, 7, 8, - 15, 17, 19, 20, 21, 27, 30, 37, 39, 39, 39, 47, 68, 72, 8, 15, - 32, 44, 52, 52, 28, 29, 64, 64, 61, 59, 61, 66, 82, 93, 64, 50, - 76, 82, 64, 31, 53, 113, 118, 125, 144, 170, 195, 145, 89, 38, 66, 108, - 124, 127, 125, 54, 32, 77, 74, 76, 79, 72, 65, 63, 63, 63, 63, 57, - 54, 52, 51, 49, 47, 47, 46, 42, 40, 39, 38, 39, 38, 38, 37, 34, - 33, 34, 34, 34, 35, 33, 34, 33, 32, 28, 27, 24, 23, 23, 21, 16, - 17, 19, 20, 20, 22, 24, 25, 20, 20, 20, 21, 22, 22, 21, 21, 22, - 21, 20, 19, 17, 17, 13, 14, 17, 14, 11, 11, 10, 8, 7, 7, 7, - 15, 17, 19, 20, 23, 26, 31, 37, 40, 40, 41, 53, 73, 44, 11, 45, - 55, 60, 60, 41, 23, 53, 65, 61, 68, 64, 61, 63, 73, 87, 94, 66, - 72, 75, 72, 40, 55, 115, 120, 129, 157, 191, 223, 208, 82, 53, 109, 141, - 140, 132, 123, 43, 82, 113, 99, 91, 88, 81, 72, 70, 69, 69, 69, 63, - 58, 56, 55, 53, 52, 50, 50, 44, 42, 40, 40, 39, 39, 39, 38, 35, - 34, 34, 34, 34, 34, 33, 34, 33, 32, 30, 27, 25, 25, 23, 22, 15, - 17, 19, 21, 22, 24, 27, 27, 25, 26, 26, 26, 27, 26, 26, 26, 25, - 23, 23, 21, 21, 20, 17, 18, 19, 16, 13, 12, 10, 7, 7, 7, 7, - 18, 19, 22, 24, 24, 27, 29, 35, 42, 35, 39, 59, 78, 39, 33, 56, - 56, 60, 49, 15, 24, 59, 63, 67, 69, 68, 66, 68, 78, 84, 94, 86, - 62, 92, 98, 60, 56, 122, 132, 138, 161, 202, 235, 232, 49, 96, 137, 143, - 139, 135, 112, 44, 101, 120, 109, 97, 94, 88, 77, 70, 69, 70, 72, 63, - 56, 55, 56, 57, 53, 50, 47, 40, 38, 37, 37, 36, 38, 39, 39, 38, - 35, 33, 30, 30, 28, 30, 30, 28, 26, 30, 30, 29, 28, 24, 20, 14, - 15, 20, 24, 26, 29, 32, 29, 27, 31, 31, 29, 26, 26, 32, 36, 32, - 25, 20, 21, 21, 24, 19, 21, 19, 16, 12, 11, 11, 9, 9, 9, 8, - 20, 21, 25, 27, 26, 26, 27, 34, 45, 34, 38, 67, 79, 41, 41, 51, - 45, 56, 47, 11, 30, 54, 66, 70, 65, 65, 68, 71, 77, 83, 87, 103, - 70, 91, 105, 71, 54, 126, 142, 149, 166, 209, 243, 247, 88, 119, 146, 135, - 121, 126, 112, 45, 103, 113, 101, 91, 85, 82, 74, 63, 58, 61, 67, 58, - 49, 48, 49, 51, 47, 45, 40, 32, 32, 31, 31, 33, 36, 38, 40, 42, - 36, 33, 26, 22, 28, 32, 29, 17, 22, 29, 29, 32, 29, 24, 19, 16, - 17, 22, 28, 33, 32, 34, 30, 28, 35, 37, 31, 26, 26, 34, 38, 32, - 29, 24, 20, 20, 21, 25, 25, 17, 14, 12, 11, 11, 11, 11, 11, 10, - 21, 22, 26, 27, 27, 25, 26, 35, 47, 39, 39, 66, 40, 15, 30, 44, - 42, 57, 47, 20, 46, 56, 64, 67, 62, 61, 64, 67, 72, 78, 83, 104, - 79, 88, 120, 76, 59, 130, 141, 154, 172, 212, 244, 248, 118, 117, 140, 130, - 125, 137, 120, 40, 94, 93, 77, 67, 62, 64, 60, 51, 46, 48, 55, 51, - 44, 41, 40, 39, 38, 40, 38, 37, 38, 37, 35, 33, 34, 35, 36, 35, - 28, 26, 25, 25, 25, 29, 32, 20, 25, 26, 25, 26, 25, 22, 21, 23, - 23, 25, 26, 27, 24, 25, 26, 26, 32, 35, 29, 22, 21, 26, 30, 26, - 26, 24, 19, 24, 22, 23, 23, 18, 16, 13, 11, 12, 11, 12, 11, 10, - 21, 22, 26, 27, 28, 26, 27, 35, 47, 41, 47, 46, 3, 16, 34, 42, - 49, 64, 40, 35, 59, 53, 56, 61, 57, 56, 59, 60, 64, 71, 77, 94, - 93, 89, 100, 52, 62, 128, 134, 149, 171, 208, 238, 246, 108, 82, 69, 94, - 119, 126, 116, 46, 99, 100, 89, 72, 61, 63, 58, 50, 46, 48, 55, 55, - 49, 42, 37, 35, 38, 42, 44, 47, 48, 45, 41, 39, 37, 33, 30, 22, - 23, 29, 33, 37, 37, 35, 36, 39, 32, 22, 25, 18, 19, 19, 23, 31, - 29, 26, 21, 18, 22, 23, 27, 29, 36, 40, 37, 31, 23, 22, 24, 19, - 18, 26, 28, 25, 33, 19, 20, 22, 17, 15, 13, 12, 12, 12, 11, 10, - 19, 22, 26, 26, 27, 28, 29, 36, 45, 42, 55, 29, 23, 50, 53, 55, - 52, 63, 31, 51, 63, 51, 53, 59, 53, 53, 55, 57, 63, 69, 75, 86, - 100, 82, 88, 51, 58, 120, 124, 140, 169, 207, 239, 244, 109, 81, 90, 82, - 96, 134, 125, 42, 94, 97, 90, 72, 62, 68, 68, 58, 53, 55, 62, 67, - 63, 51, 41, 37, 42, 48, 55, 69, 71, 65, 57, 51, 41, 34, 27, 20, - 28, 36, 42, 48, 50, 46, 42, 47, 41, 30, 20, 13, 15, 19, 26, 36, - 31, 25, 19, 19, 27, 28, 33, 38, 45, 50, 49, 43, 38, 28, 18, 15, - 24, 36, 40, 40, 29, 30, 24, 25, 21, 18, 15, 14, 13, 12, 11, 10, - 19, 21, 25, 25, 27, 28, 30, 37, 43, 46, 61, 26, 48, 65, 61, 66, - 59, 55, 25, 63, 63, 49, 52, 57, 52, 51, 54, 56, 62, 68, 72, 78, - 86, 40, 62, 54, 55, 117, 125, 145, 180, 208, 231, 237, 125, 113, 138, 115, - 88, 100, 100, 46, 97, 93, 78, 62, 58, 68, 72, 67, 63, 65, 71, 84, - 81, 65, 48, 45, 53, 62, 79, 93, 92, 83, 70, 61, 51, 40, 34, 26, - 35, 48, 66, 71, 54, 44, 51, 66, 54, 42, 22, 15, 18, 24, 31, 39, - 33, 27, 23, 25, 35, 42, 56, 64, 71, 77, 77, 63, 51, 39, 28, 25, - 36, 49, 68, 75, 46, 39, 27, 28, 23, 20, 16, 15, 13, 12, 11, 10, - 19, 20, 23, 24, 27, 28, 30, 37, 41, 54, 66, 34, 46, 59, 66, 73, - 76, 49, 21, 65, 60, 46, 49, 54, 51, 52, 53, 56, 58, 62, 66, 71, - 74, 17, 64, 72, 57, 122, 137, 153, 182, 204, 223, 234, 136, 145, 132, 134, - 124, 105, 71, 44, 102, 106, 96, 75, 69, 80, 83, 81, 79, 81, 87, 102, - 101, 81, 61, 62, 72, 85, 109, 138, 139, 128, 112, 76, 63, 52, 47, 43, - 53, 76, 111, 143, 141, 119, 97, 106, 67, 50, 33, 23, 24, 31, 36, 37, - 33, 31, 32, 42, 56, 76, 108, 128, 133, 139, 144, 123, 71, 47, 45, 42, - 52, 86, 124, 92, 93, 46, 38, 29, 24, 21, 16, 14, 12, 12, 11, 10, - 17, 19, 24, 26, 27, 26, 29, 36, 44, 55, 57, 25, 49, 75, 80, 83, - 81, 42, 27, 68, 60, 47, 47, 51, 48, 46, 47, 48, 53, 58, 63, 65, - 68, 74, 95, 78, 67, 134, 137, 154, 186, 192, 214, 225, 130, 136, 130, 141, - 141, 150, 135, 42, 99, 105, 93, 95, 100, 110, 110, 106, 99, 105, 123, 144, - 138, 116, 56, 84, 100, 129, 142, 128, 113, 121, 83, 76, 57, 64, 66, 68, - 85, 135, 155, 171, 184, 193, 195, 179, 113, 57, 44, 34, 33, 39, 43, 28, - 32, 42, 50, 65, 94, 111, 130, 140, 127, 127, 116, 68, 26, 74, 86, 66, - 91, 145, 132, 156, 150, 75, 40, 33, 25, 22, 16, 14, 12, 9, 10, 9, - 17, 19, 24, 26, 28, 28, 30, 34, 37, 62, 63, 43, 55, 88, 73, 63, - 45, 24, 26, 65, 55, 44, 43, 46, 45, 42, 44, 46, 51, 57, 60, 63, - 72, 83, 72, 64, 90, 134, 136, 158, 171, 178, 201, 219, 138, 131, 130, 114, - 141, 151, 136, 44, 87, 98, 93, 92, 106, 120, 130, 122, 150, 136, 140, 162, - 151, 135, 63, 98, 131, 171, 172, 136, 131, 113, 97, 92, 72, 55, 80, 96, - 136, 184, 181, 182, 208, 209, 204, 213, 171, 83, 50, 46, 41, 41, 41, 28, - 35, 48, 72, 112, 141, 159, 143, 130, 117, 121, 73, 87, 135, 173, 168, 104, - 134, 163, 144, 180, 159, 113, 33, 30, 26, 21, 16, 14, 11, 10, 9, 10, - 16, 18, 23, 25, 28, 29, 31, 35, 39, 63, 45, 42, 78, 94, 80, 77, - 64, 42, 29, 60, 49, 40, 39, 41, 42, 40, 42, 45, 50, 56, 61, 63, - 75, 101, 107, 106, 114, 134, 135, 157, 153, 167, 184, 210, 120, 116, 147, 127, - 132, 124, 121, 42, 79, 89, 88, 92, 111, 123, 142, 136, 163, 150, 158, 165, - 166, 144, 69, 133, 170, 185, 175, 190, 185, 196, 202, 192, 159, 99, 80, 129, - 151, 145, 181, 193, 215, 213, 211, 176, 156, 164, 55, 55, 50, 42, 38, 27, - 37, 60, 106, 171, 183, 193, 171, 142, 123, 114, 127, 190, 213, 203, 187, 163, - 152, 155, 155, 169, 138, 137, 30, 25, 28, 21, 18, 15, 13, 10, 10, 10, - 16, 18, 23, 24, 28, 30, 31, 34, 37, 64, 45, 65, 103, 87, 86, 79, - 73, 52, 26, 56, 46, 39, 39, 40, 42, 41, 43, 45, 49, 58, 66, 76, - 85, 88, 93, 108, 121, 132, 135, 148, 141, 160, 166, 201, 109, 118, 126, 109, - 143, 164, 142, 42, 83, 83, 78, 86, 102, 111, 138, 158, 159, 155, 171, 189, - 167, 169, 112, 174, 184, 190, 170, 188, 153, 208, 208, 205, 203, 169, 92, 175, - 173, 167, 189, 200, 216, 216, 197, 152, 175, 220, 79, 53, 54, 40, 33, 25, - 43, 84, 144, 187, 195, 195, 199, 182, 94, 55, 131, 202, 199, 169, 174, 150, - 145, 141, 133, 157, 133, 134, 20, 22, 29, 21, 19, 15, 13, 11, 10, 11, - 16, 18, 22, 24, 28, 29, 30, 32, 31, 65, 63, 92, 95, 79, 94, 75, - 91, 58, 22, 49, 45, 40, 39, 40, 42, 42, 44, 47, 51, 60, 69, 78, - 82, 81, 88, 102, 114, 126, 131, 134, 136, 151, 151, 190, 114, 142, 138, 111, - 133, 144, 138, 49, 88, 83, 72, 75, 86, 98, 131, 159, 156, 164, 182, 200, - 152, 164, 155, 199, 197, 177, 161, 183, 146, 202, 192, 207, 183, 182, 149, 206, - 189, 194, 214, 203, 199, 198, 178, 170, 232, 203, 89, 41, 54, 38, 28, 28, - 54, 113, 166, 190, 211, 191, 200, 140, 29, 27, 86, 169, 170, 133, 157, 150, - 162, 83, 79, 140, 150, 117, 17, 24, 26, 20, 17, 14, 12, 10, 10, 11, - 14, 18, 22, 24, 27, 28, 30, 31, 28, 65, 69, 81, 70, 77, 90, 64, - 86, 44, 28, 54, 45, 41, 39, 40, 42, 42, 45, 49, 56, 61, 67, 75, - 79, 74, 74, 86, 103, 117, 122, 121, 131, 135, 140, 184, 135, 140, 140, 126, - 147, 150, 140, 46, 83, 87, 74, 65, 75, 93, 119, 151, 151, 175, 187, 193, - 174, 156, 177, 194, 157, 107, 114, 178, 175, 206, 191, 173, 176, 197, 188, 196, - 186, 142, 143, 183, 192, 203, 197, 206, 191, 117, 110, 25, 50, 35, 23, 32, - 67, 132, 152, 145, 182, 167, 164, 54, 26, 42, 68, 115, 124, 125, 134, 135, - 161, 100, 61, 119, 109, 48, 14, 28, 23, 19, 15, 12, 10, 8, 9, 11, - 14, 18, 22, 24, 26, 27, 29, 31, 27, 65, 70, 73, 72, 75, 66, 61, - 117, 49, 30, 47, 46, 45, 40, 39, 42, 44, 47, 51, 59, 61, 64, 70, - 75, 74, 80, 91, 102, 107, 109, 114, 131, 120, 134, 167, 148, 155, 158, 143, - 147, 157, 149, 40, 76, 88, 79, 64, 67, 73, 86, 144, 156, 184, 183, 184, - 182, 159, 170, 137, 48, 41, 63, 140, 178, 196, 174, 185, 192, 186, 186, 186, - 81, 32, 49, 92, 160, 190, 155, 182, 150, 125, 107, 16, 49, 35, 25, 36, - 78, 140, 151, 157, 163, 139, 114, 20, 42, 53, 67, 99, 118, 146, 114, 123, - 144, 114, 55, 58, 32, 14, 33, 28, 21, 19, 16, 14, 11, 8, 8, 11, - 13, 18, 22, 25, 25, 27, 30, 31, 29, 65, 66, 82, 97, 85, 72, 97, - 127, 49, 28, 49, 50, 49, 42, 40, 47, 50, 53, 54, 54, 58, 64, 65, - 67, 77, 88, 98, 102, 96, 94, 111, 133, 106, 130, 159, 133, 159, 169, 156, - 159, 173, 156, 42, 75, 82, 78, 74, 65, 58, 70, 110, 154, 183, 182, 194, - 188, 170, 165, 52, 17, 54, 78, 105, 188, 214, 196, 202, 181, 163, 172, 121, - 8, 40, 64, 57, 99, 122, 87, 131, 153, 172, 149, 12, 49, 37, 32, 41, - 94, 156, 187, 178, 162, 141, 111, 17, 52, 51, 57, 91, 132, 161, 108, 124, - 113, 118, 43, 47, 27, 27, 35, 27, 21, 19, 18, 17, 13, 10, 8, 10, - 14, 17, 22, 24, 25, 27, 29, 31, 27, 68, 85, 102, 111, 102, 97, 127, - 124, 45, 28, 49, 51, 52, 45, 44, 52, 50, 50, 51, 53, 57, 63, 66, - 68, 77, 90, 98, 95, 89, 92, 111, 123, 100, 124, 152, 135, 155, 145, 161, - 172, 174, 166, 45, 74, 79, 76, 79, 68, 55, 69, 117, 166, 183, 177, 191, - 194, 185, 118, 18, 47, 63, 82, 99, 205, 233, 209, 220, 191, 197, 185, 54, - 24, 62, 69, 66, 126, 176, 172, 189, 185, 204, 167, 11, 48, 39, 33, 41, - 114, 179, 189, 168, 163, 156, 123, 15, 60, 45, 56, 91, 128, 148, 103, 119, - 140, 137, 31, 37, 31, 33, 35, 24, 20, 19, 18, 17, 14, 9, 9, 11, - 14, 17, 22, 24, 24, 26, 29, 30, 26, 70, 103, 118, 109, 104, 105, 130, - 106, 38, 28, 52, 54, 54, 48, 46, 52, 49, 48, 48, 51, 56, 62, 66, - 71, 79, 87, 92, 87, 85, 95, 114, 111, 94, 119, 143, 139, 156, 175, 171, - 175, 173, 177, 43, 72, 76, 72, 76, 67, 56, 71, 119, 168, 178, 185, 209, - 210, 161, 57, 32, 67, 64, 76, 102, 201, 226, 214, 222, 194, 197, 185, 35, - 52, 70, 68, 63, 145, 215, 207, 211, 215, 199, 158, 9, 48, 41, 36, 47, - 120, 172, 171, 143, 161, 164, 128, 23, 58, 45, 55, 88, 109, 130, 127, 133, - 157, 142, 27, 33, 34, 32, 32, 23, 19, 18, 18, 17, 12, 9, 9, 10, - 13, 16, 22, 24, 25, 27, 30, 33, 31, 66, 92, 101, 97, 95, 98, 108, - 103, 48, 34, 58, 57, 55, 49, 47, 46, 45, 46, 48, 50, 55, 61, 65, - 74, 81, 80, 78, 79, 86, 101, 115, 100, 92, 113, 145, 135, 163, 189, 160, - 188, 190, 174, 39, 71, 75, 69, 70, 65, 59, 72, 112, 157, 175, 201, 208, - 177, 80, 23, 50, 70, 76, 68, 98, 196, 229, 214, 200, 179, 181, 146, 38, - 64, 67, 74, 78, 127, 188, 163, 184, 192, 171, 138, 9, 49, 43, 36, 44, - 109, 157, 182, 167, 168, 153, 113, 24, 55, 40, 49, 81, 112, 149, 161, 150, - 148, 117, 24, 33, 31, 28, 27, 21, 18, 18, 17, 16, 12, 9, 9, 9, - 13, 16, 21, 25, 25, 27, 30, 33, 30, 65, 88, 99, 100, 98, 110, 111, - 118, 67, 41, 64, 59, 54, 49, 47, 45, 45, 46, 48, 51, 55, 62, 66, - 74, 78, 71, 69, 74, 86, 104, 112, 92, 92, 107, 141, 115, 153, 146, 147, - 185, 168, 156, 45, 72, 74, 67, 67, 63, 60, 74, 118, 164, 191, 203, 169, - 83, 98, 48, 59, 73, 68, 69, 88, 159, 198, 187, 161, 158, 190, 129, 44, - 68, 63, 70, 71, 123, 190, 158, 198, 178, 169, 126, 10, 52, 46, 37, 42, - 91, 141, 182, 165, 157, 144, 114, 22, 62, 36, 50, 85, 127, 155, 152, 142, - 132, 125, 25, 34, 31, 28, 29, 20, 17, 17, 16, 15, 12, 9, 9, 9, - 14, 17, 22, 25, 26, 26, 30, 34, 31, 63, 83, 95, 98, 95, 118, 120, - 125, 74, 43, 68, 59, 52, 48, 47, 49, 48, 47, 48, 51, 55, 62, 67, - 72, 70, 63, 62, 69, 84, 100, 106, 86, 92, 102, 134, 118, 160, 165, 151, - 152, 133, 132, 39, 73, 74, 67, 67, 60, 55, 74, 118, 169, 199, 182, 128, - 120, 201, 62, 65, 70, 60, 69, 85, 153, 190, 158, 145, 161, 192, 132, 45, - 67, 55, 68, 75, 114, 179, 170, 188, 168, 160, 110, 11, 55, 47, 38, 44, - 84, 142, 181, 164, 166, 150, 120, 31, 62, 47, 55, 90, 128, 140, 140, 138, - 132, 102, 19, 35, 32, 25, 25, 20, 17, 17, 16, 14, 11, 9, 8, 8, - 16, 18, 22, 23, 26, 27, 29, 34, 34, 61, 75, 79, 88, 100, 123, 124, - 125, 93, 40, 72, 58, 49, 48, 49, 50, 48, 49, 50, 51, 55, 63, 66, - 66, 61, 55, 61, 65, 84, 99, 96, 83, 90, 98, 130, 157, 179, 191, 174, - 159, 158, 152, 34, 72, 72, 66, 68, 58, 50, 71, 119, 175, 171, 127, 141, - 215, 231, 57, 58, 62, 55, 62, 87, 177, 189, 138, 153, 178, 188, 132, 41, - 59, 52, 64, 70, 107, 168, 151, 171, 155, 142, 104, 12, 56, 50, 40, 43, - 82, 144, 176, 168, 178, 162, 135, 48, 61, 58, 63, 94, 126, 123, 144, 146, - 142, 67, 18, 36, 31, 22, 21, 21, 16, 16, 15, 13, 11, 8, 7, 8, - 18, 19, 22, 23, 26, 27, 28, 33, 35, 58, 69, 74, 95, 115, 121, 128, - 125, 99, 44, 71, 56, 46, 49, 53, 51, 49, 50, 51, 52, 56, 63, 64, - 57, 54, 59, 66, 73, 86, 88, 86, 84, 90, 95, 134, 172, 168, 183, 183, - 186, 198, 155, 36, 71, 72, 66, 68, 58, 50, 68, 109, 149, 126, 176, 219, - 236, 190, 42, 55, 56, 49, 59, 84, 167, 171, 147, 180, 192, 180, 96, 38, - 54, 50, 61, 72, 118, 173, 170, 165, 143, 140, 126, 13, 57, 51, 41, 44, - 74, 122, 146, 151, 154, 141, 123, 54, 57, 73, 89, 107, 130, 127, 148, 145, - 122, 32, 15, 36, 30, 22, 21, 21, 16, 16, 14, 13, 11, 7, 6, 8, - 17, 20, 23, 24, 26, 27, 29, 34, 34, 52, 66, 76, 105, 129, 114, 135, - 137, 114, 49, 67, 57, 45, 51, 59, 53, 52, 52, 52, 54, 59, 62, 57, - 48, 57, 70, 75, 88, 93, 82, 81, 87, 89, 90, 130, 125, 165, 133, 169, - 190, 160, 120, 41, 71, 74, 66, 65, 59, 52, 68, 96, 104, 185, 241, 231, - 202, 163, 41, 52, 55, 48, 58, 84, 157, 196, 160, 190, 195, 176, 92, 36, - 52, 50, 62, 70, 130, 164, 178, 165, 147, 149, 141, 14, 59, 54, 45, 48, - 63, 88, 105, 133, 131, 129, 125, 100, 72, 82, 101, 112, 132, 129, 123, 114, - 59, 4, 25, 36, 27, 22, 21, 22, 18, 17, 14, 13, 9, 5, 6, 8, - 17, 20, 23, 24, 26, 26, 28, 34, 36, 49, 66, 83, 108, 136, 120, 146, - 153, 133, 53, 66, 60, 48, 53, 61, 54, 53, 53, 54, 56, 61, 62, 52, - 48, 65, 80, 95, 98, 92, 85, 78, 90, 86, 87, 124, 53, 83, 130, 188, - 157, 104, 137, 45, 71, 75, 66, 65, 59, 53, 68, 89, 169, 245, 238, 208, - 206, 192, 51, 51, 55, 47, 57, 76, 142, 213, 152, 184, 182, 171, 102, 36, - 52, 52, 63, 65, 130, 159, 161, 163, 159, 157, 135, 14, 60, 55, 47, 51, - 59, 72, 85, 114, 124, 139, 140, 138, 104, 97, 106, 103, 118, 120, 105, 77, - 16, 9, 35, 34, 25, 22, 20, 21, 17, 16, 13, 12, 9, 5, 6, 8, - 18, 19, 23, 24, 26, 25, 28, 34, 38, 47, 66, 89, 117, 144, 132, 151, - 142, 114, 63, 54, 61, 51, 55, 62, 56, 55, 56, 57, 60, 62, 63, 53, - 54, 71, 101, 140, 120, 90, 83, 77, 91, 82, 84, 124, 116, 115, 134, 130, - 77, 130, 181, 44, 70, 74, 67, 66, 59, 53, 68, 120, 213, 215, 204, 208, - 202, 214, 52, 52, 55, 47, 57, 71, 150, 204, 138, 181, 186, 177, 105, 36, - 53, 53, 64, 68, 128, 166, 157, 164, 164, 161, 139, 14, 60, 56, 49, 53, - 58, 66, 80, 96, 113, 130, 134, 151, 126, 110, 115, 114, 131, 114, 76, 37, - 7, 24, 31, 31, 24, 22, 19, 20, 16, 16, 14, 13, 8, 4, 5, 8, - 18, 19, 23, 24, 25, 26, 28, 34, 37, 42, 64, 92, 124, 150, 139, 150, - 128, 106, 87, 41, 56, 53, 58, 66, 61, 60, 60, 62, 62, 62, 62, 56, - 61, 81, 127, 176, 152, 94, 73, 79, 91, 77, 83, 126, 150, 193, 165, 122, - 120, 213, 188, 37, 69, 73, 68, 68, 58, 51, 68, 131, 205, 172, 165, 191, - 175, 218, 50, 53, 55, 47, 56, 79, 181, 198, 128, 164, 181, 173, 113, 37, - 54, 55, 66, 74, 114, 163, 162, 164, 162, 159, 143, 13, 59, 56, 49, 52, - 55, 60, 79, 93, 112, 126, 138, 161, 124, 108, 121, 142, 148, 87, 32, 21, - 26, 35, 27, 28, 23, 24, 18, 19, 15, 16, 14, 12, 7, 4, 4, 8, - 19, 20, 23, 23, 25, 26, 29, 34, 36, 39, 59, 85, 111, 143, 139, 154, - 145, 149, 129, 53, 60, 60, 58, 65, 65, 63, 62, 62, 60, 56, 58, 55, - 63, 97, 144, 181, 170, 91, 53, 78, 88, 71, 82, 116, 174, 197, 201, 201, - 212, 232, 205, 47, 72, 71, 65, 68, 57, 46, 65, 124, 178, 195, 210, 165, - 219, 222, 47, 52, 54, 47, 57, 83, 155, 169, 141, 155, 149, 129, 71, 36, - 57, 53, 62, 74, 93, 141, 159, 162, 162, 155, 137, 15, 60, 53, 45, 50, - 53, 63, 85, 101, 120, 136, 150, 136, 97, 104, 128, 128, 86, 30, 25, 45, - 55, 35, 30, 28, 23, 22, 15, 17, 14, 16, 14, 13, 9, 4, 5, 8, - 22, 25, 25, 23, 23, 26, 30, 37, 38, 41, 49, 68, 96, 126, 136, 154, - 157, 144, 141, 79, 72, 72, 55, 52, 67, 61, 59, 52, 52, 47, 53, 51, - 65, 110, 149, 154, 177, 63, 28, 76, 83, 65, 74, 112, 180, 198, 215, 220, - 224, 235, 213, 51, 76, 70, 54, 62, 54, 40, 55, 113, 167, 197, 225, 212, - 206, 195, 54, 52, 52, 45, 62, 82, 97, 137, 173, 192, 194, 169, 99, 33, - 58, 48, 46, 75, 77, 94, 115, 141, 156, 156, 131, 20, 69, 51, 38, 46, - 65, 87, 104, 99, 134, 139, 109, 60, 55, 49, 32, 27, 28, 36, 47, 49, - 48, 43, 39, 33, 26, 14, 11, 15, 13, 16, 16, 16, 12, 10, 8, 7, - 23, 25, 25, 23, 23, 26, 30, 37, 37, 40, 45, 60, 80, 103, 134, 149, - 147, 133, 138, 123, 67, 76, 55, 53, 65, 62, 58, 50, 49, 51, 58, 69, - 92, 153, 160, 180, 144, 24, 38, 75, 83, 69, 80, 118, 182, 185, 200, 219, - 202, 225, 186, 58, 79, 76, 59, 68, 56, 37, 56, 121, 190, 210, 188, 176, - 164, 164, 40, 51, 49, 46, 61, 88, 125, 180, 191, 191, 191, 173, 101, 27, - 60, 47, 46, 75, 114, 139, 126, 111, 125, 129, 112, 18, 64, 51, 34, 50, - 71, 90, 98, 116, 142, 135, 55, 29, 71, 68, 53, 50, 47, 46, 48, 47, - 43, 40, 39, 32, 25, 14, 13, 15, 14, 16, 16, 16, 13, 10, 8, 7, - 23, 24, 24, 22, 22, 25, 29, 35, 36, 38, 41, 54, 71, 93, 128, 131, - 130, 131, 161, 145, 90, 68, 70, 54, 62, 56, 55, 58, 57, 63, 69, 94, - 146, 179, 175, 177, 89, 21, 53, 79, 87, 75, 91, 133, 178, 184, 202, 202, - 192, 207, 153, 78, 78, 91, 68, 68, 61, 49, 65, 131, 200, 209, 161, 111, - 150, 156, 39, 56, 53, 50, 66, 97, 154, 193, 174, 180, 175, 161, 93, 34, - 61, 43, 48, 73, 119, 150, 164, 148, 123, 112, 111, 16, 67, 50, 36, 45, - 70, 87, 98, 115, 130, 131, 75, 47, 91, 80, 73, 63, 57, 48, 45, 48, - 40, 35, 34, 29, 27, 20, 18, 17, 15, 16, 16, 16, 12, 10, 8, 7, - 23, 24, 23, 21, 21, 23, 26, 32, 35, 37, 39, 49, 67, 96, 136, 150, - 164, 159, 172, 162, 121, 86, 68, 67, 63, 62, 61, 66, 68, 84, 99, 145, - 186, 190, 184, 153, 40, 43, 57, 82, 95, 86, 108, 148, 178, 192, 202, 196, - 197, 218, 189, 127, 77, 96, 85, 78, 69, 63, 79, 134, 195, 189, 193, 161, - 116, 132, 50, 50, 63, 60, 74, 107, 162, 174, 165, 180, 166, 157, 103, 35, - 64, 49, 52, 80, 129, 121, 158, 149, 157, 152, 130, 34, 64, 55, 43, 50, - 73, 86, 114, 127, 119, 110, 99, 58, 75, 71, 80, 80, 73, 70, 63, 51, - 45, 36, 30, 28, 29, 26, 23, 18, 15, 16, 16, 15, 12, 10, 9, 8, - 23, 23, 22, 20, 21, 22, 24, 30, 35, 36, 37, 45, 56, 75, 106, 142, - 173, 177, 178, 165, 141, 130, 82, 82, 65, 72, 71, 74, 88, 112, 136, 183, - 208, 196, 167, 78, 35, 56, 59, 81, 103, 106, 136, 162, 191, 195, 187, 191, - 199, 212, 204, 190, 123, 106, 103, 85, 76, 78, 102, 154, 188, 188, 195, 184, - 114, 123, 83, 57, 70, 75, 87, 136, 167, 162, 173, 180, 163, 159, 118, 35, - 70, 64, 60, 85, 128, 101, 164, 148, 151, 149, 142, 75, 55, 64, 48, 44, - 73, 80, 119, 112, 119, 109, 107, 77, 43, 64, 94, 77, 73, 81, 75, 60, - 56, 43, 33, 31, 32, 32, 27, 20, 16, 16, 15, 15, 12, 9, 9, 9, - 23, 23, 22, 20, 20, 22, 23, 29, 34, 35, 35, 40, 53, 65, 78, 108, - 130, 161, 182, 142, 129, 134, 119, 122, 91, 80, 89, 113, 152, 154, 126, 141, - 190, 177, 102, 28, 55, 61, 62, 87, 129, 155, 187, 196, 203, 198, 194, 203, - 206, 208, 198, 181, 181, 186, 163, 71, 79, 109, 136, 178, 194, 180, 162, 173, - 190, 191, 165, 110, 74, 83, 123, 166, 159, 161, 169, 175, 162, 151, 105, 72, - 81, 65, 64, 75, 104, 93, 170, 126, 144, 148, 136, 108, 84, 63, 50, 48, - 76, 59, 105, 113, 136, 117, 89, 83, 99, 123, 104, 72, 71, 79, 71, 58, - 55, 50, 45, 37, 36, 33, 28, 21, 17, 16, 14, 14, 11, 8, 9, 9, - 22, 23, 22, 20, 21, 22, 24, 29, 33, 35, 35, 37, 40, 54, 64, 83, - 108, 145, 154, 133, 108, 110, 129, 147, 131, 121, 131, 173, 183, 147, 137, 173, - 173, 126, 40, 46, 61, 60, 61, 85, 140, 176, 205, 206, 201, 199, 202, 204, - 199, 206, 192, 178, 197, 185, 163, 49, 81, 146, 163, 182, 195, 164, 170, 186, - 176, 180, 168, 142, 78, 86, 150, 160, 142, 162, 171, 172, 160, 141, 118, 117, - 85, 53, 56, 77, 98, 112, 162, 143, 146, 142, 132, 123, 110, 59, 46, 43, - 66, 42, 74, 93, 114, 107, 93, 107, 125, 126, 97, 81, 84, 88, 77, 67, - 59, 54, 52, 44, 35, 33, 26, 20, 17, 16, 14, 14, 11, 8, 8, 9, - 22, 22, 21, 19, 21, 21, 25, 29, 31, 35, 35, 36, 40, 45, 54, 66, - 81, 125, 124, 145, 160, 166, 187, 184, 184, 168, 175, 216, 197, 186, 180, 202, - 156, 49, 32, 60, 58, 57, 64, 89, 150, 184, 206, 196, 191, 193, 197, 189, - 196, 193, 175, 185, 202, 179, 150, 39, 88, 161, 167, 174, 181, 171, 178, 176, - 154, 153, 156, 149, 75, 82, 147, 135, 138, 167, 170, 163, 155, 131, 155, 101, - 70, 42, 43, 42, 70, 125, 160, 145, 144, 141, 134, 130, 105, 52, 31, 45, - 69, 75, 95, 125, 123, 117, 97, 102, 126, 113, 100, 93, 97, 94, 91, 97, - 76, 54, 44, 47, 38, 32, 23, 22, 18, 17, 15, 15, 11, 8, 8, 9, - 21, 20, 20, 19, 21, 22, 25, 29, 28, 33, 33, 35, 37, 40, 47, 55, - 63, 73, 95, 141, 167, 186, 205, 207, 219, 143, 200, 214, 169, 180, 171, 133, - 49, 31, 56, 55, 52, 57, 67, 85, 132, 152, 168, 168, 166, 171, 181, 179, - 178, 174, 172, 183, 192, 168, 157, 35, 79, 115, 109, 137, 156, 158, 163, 162, - 150, 150, 145, 124, 62, 84, 142, 140, 150, 166, 143, 109, 88, 44, 57, 62, - 78, 36, 86, 110, 122, 158, 151, 136, 134, 131, 125, 124, 102, 56, 36, 44, - 69, 84, 97, 118, 126, 127, 81, 90, 114, 89, 85, 80, 80, 69, 78, 101, - 87, 65, 37, 41, 44, 28, 21, 23, 19, 18, 16, 15, 10, 7, 8, 11, - 20, 19, 20, 19, 21, 22, 25, 27, 27, 31, 32, 35, 36, 38, 42, 45, - 49, 60, 73, 95, 144, 154, 177, 196, 176, 160, 210, 185, 129, 115, 54, 24, - 39, 55, 56, 53, 46, 56, 67, 77, 101, 100, 101, 98, 89, 90, 101, 98, - 86, 77, 78, 89, 94, 83, 84, 32, 74, 80, 65, 63, 67, 69, 70, 76, - 73, 71, 62, 58, 43, 73, 101, 79, 72, 70, 48, 26, 26, 26, 51, 69, - 48, 49, 96, 87, 72, 80, 62, 62, 63, 62, 60, 63, 45, 26, 30, 38, - 65, 80, 78, 96, 115, 95, 78, 105, 91, 64, 71, 76, 77, 67, 76, 93, - 88, 74, 43, 29, 40, 29, 21, 24, 20, 20, 17, 14, 11, 7, 9, 13, - 18, 18, 19, 18, 22, 22, 24, 26, 25, 30, 33, 37, 38, 38, 41, 41, - 46, 53, 62, 61, 60, 69, 97, 105, 80, 126, 125, 74, 58, 30, 36, 70, - 67, 65, 56, 43, 44, 53, 63, 64, 71, 70, 70, 66, 55, 55, 69, 75, - 64, 55, 53, 60, 61, 66, 62, 51, 66, 73, 61, 54, 51, 50, 51, 51, - 48, 51, 54, 53, 54, 59, 56, 50, 51, 55, 52, 43, 39, 40, 54, 51, - 40, 46, 56, 50, 43, 47, 41, 43, 48, 52, 54, 50, 44, 38, 47, 37, - 55, 78, 77, 75, 80, 63, 94, 93, 75, 80, 86, 89, 90, 82, 84, 86, - 78, 64, 48, 19, 29, 32, 22, 25, 21, 20, 17, 14, 10, 7, 10, 15, - 18, 18, 19, 19, 21, 22, 23, 25, 23, 28, 31, 36, 37, 37, 39, 39, - 42, 47, 57, 66, 66, 58, 50, 37, 29, 29, 35, 39, 52, 55, 60, 69, - 66, 62, 51, 42, 41, 50, 57, 51, 50, 63, 72, 66, 58, 61, 81, 85, - 67, 60, 58, 60, 61, 67, 58, 53, 51, 63, 61, 54, 50, 50, 56, 55, - 48, 44, 47, 54, 53, 43, 35, 40, 52, 57, 54, 44, 42, 45, 56, 46, - 43, 35, 41, 44, 48, 41, 31, 33, 39, 45, 48, 44, 48, 40, 38, 37, - 47, 73, 84, 80, 61, 85, 91, 72, 73, 91, 85, 90, 87, 81, 74, 66, - 64, 61, 54, 16, 19, 32, 24, 25, 21, 19, 16, 14, 10, 7, 10, 15, - 17, 18, 19, 20, 21, 21, 23, 25, 20, 24, 28, 33, 34, 35, 39, 39, - 40, 48, 48, 52, 52, 53, 47, 42, 43, 47, 50, 57, 56, 59, 68, 65, - 64, 55, 52, 44, 43, 50, 55, 46, 39, 56, 64, 55, 49, 51, 71, 80, - 62, 51, 48, 50, 53, 57, 54, 46, 45, 49, 49, 46, 41, 43, 49, 45, - 38, 34, 36, 41, 37, 29, 19, 29, 43, 43, 40, 36, 34, 37, 43, 37, - 27, 23, 24, 31, 30, 26, 18, 24, 28, 33, 35, 33, 36, 31, 32, 35, - 52, 66, 63, 66, 74, 81, 63, 56, 67, 75, 67, 74, 73, 74, 65, 55, - 59, 66, 58, 18, 16, 30, 25, 23, 19, 18, 16, 14, 10, 8, 10, 15, - 17, 18, 19, 19, 19, 21, 24, 24, 18, 22, 26, 29, 33, 35, 39, 41, - 43, 47, 48, 50, 50, 49, 46, 46, 48, 47, 52, 53, 54, 61, 61, 57, - 56, 51, 47, 44, 45, 49, 53, 47, 43, 51, 57, 55, 53, 53, 64, 71, - 62, 49, 44, 45, 49, 52, 52, 47, 45, 46, 45, 43, 41, 42, 44, 40, - 35, 34, 35, 37, 36, 31, 27, 32, 37, 37, 36, 33, 32, 34, 37, 34, - 31, 27, 27, 31, 30, 27, 24, 30, 31, 33, 33, 31, 32, 32, 35, 42, - 69, 53, 56, 80, 94, 68, 70, 56, 48, 40, 36, 42, 54, 60, 58, 63, - 62, 65, 47, 23, 11, 32, 23, 22, 18, 17, 16, 16, 12, 10, 12, 13, - 17, 18, 19, 19, 19, 22, 24, 25, 19, 21, 25, 26, 30, 33, 38, 40, - 42, 45, 47, 47, 48, 47, 46, 47, 47, 47, 46, 46, 49, 55, 54, 52, - 50, 47, 43, 42, 45, 48, 50, 49, 47, 49, 54, 56, 57, 56, 59, 67, - 62, 50, 43, 42, 47, 51, 51, 48, 47, 46, 45, 45, 44, 43, 42, 40, - 38, 38, 37, 36, 36, 34, 34, 35, 35, 34, 33, 34, 34, 33, 32, 33, - 33, 32, 32, 32, 32, 32, 33, 36, 35, 34, 33, 31, 33, 35, 39, 45, - 77, 81, 92, 94, 73, 38, 61, 62, 54, 47, 48, 49, 52, 44, 41, 56, - 68, 62, 45, 16, 5, 34, 28, 22, 17, 16, 16, 16, 14, 12, 12, 11, - 17, 18, 19, 20, 20, 21, 24, 24, 19, 21, 23, 24, 26, 30, 33, 35, - 36, 39, 40, 41, 42, 41, 42, 42, 42, 43, 43, 43, 46, 50, 50, 47, - 46, 43, 40, 39, 42, 45, 47, 45, 43, 45, 50, 52, 53, 52, 54, 62, - 57, 44, 38, 38, 42, 46, 47, 45, 44, 43, 42, 42, 41, 40, 39, 37, - 35, 34, 33, 32, 32, 31, 30, 31, 30, 29, 29, 31, 30, 29, 29, 30, - 30, 29, 28, 28, 28, 28, 29, 31, 31, 29, 29, 29, 30, 31, 38, 46, - 64, 79, 84, 74, 41, 14, 47, 52, 48, 48, 49, 50, 52, 47, 50, 40, - 49, 46, 29, 10, 8, 34, 27, 21, 17, 17, 16, 16, 14, 12, 12, 11, - 17, 18, 19, 20, 20, 21, 23, 22, 18, 19, 21, 23, 25, 28, 31, 32, - 32, 35, 36, 36, 38, 38, 39, 39, 38, 39, 40, 41, 44, 46, 45, 43, - 42, 40, 37, 37, 40, 43, 44, 42, 40, 42, 46, 48, 49, 47, 49, 56, - 53, 42, 35, 34, 38, 43, 45, 43, 41, 40, 39, 39, 38, 38, 37, 35, - 35, 33, 33, 31, 31, 30, 29, 29, 29, 28, 27, 29, 29, 28, 27, 28, - 28, 27, 27, 27, 27, 27, 27, 28, 28, 27, 26, 27, 29, 30, 40, 49, - 59, 69, 55, 60, 36, 10, 37, 42, 40, 41, 41, 44, 49, 51, 66, 37, - 20, 20, 20, 16, 17, 35, 25, 21, 17, 16, 15, 16, 14, 11, 11, 10, - 17, 18, 19, 20, 20, 21, 22, 21, 17, 18, 20, 21, 24, 26, 29, 31, - 29, 31, 33, 32, 33, 35, 36, 37, 36, 37, 39, 41, 44, 44, 42, 40, - 39, 37, 35, 35, 39, 41, 42, 40, 38, 40, 43, 45, 47, 44, 46, 53, - 49, 40, 32, 31, 35, 40, 42, 40, 38, 37, 36, 36, 36, 35, 34, 35, - 34, 33, 33, 31, 30, 29, 28, 28, 28, 27, 27, 28, 27, 26, 26, 28, - 27, 26, 26, 26, 26, 26, 26, 26, 25, 24, 25, 25, 28, 30, 41, 50, - 66, 76, 55, 72, 44, 12, 39, 47, 45, 43, 41, 43, 45, 46, 66, 45, - 14, 15, 44, 27, 20, 32, 25, 21, 16, 15, 15, 16, 13, 10, 10, 9, - 17, 18, 19, 20, 20, 21, 21, 20, 17, 18, 20, 20, 21, 24, 26, 28, - 28, 29, 30, 28, 29, 31, 33, 34, 32, 34, 36, 39, 42, 40, 38, 36, - 35, 34, 33, 33, 36, 38, 38, 37, 36, 37, 39, 42, 44, 41, 42, 49, - 47, 38, 31, 27, 31, 37, 40, 37, 35, 34, 33, 33, 32, 31, 31, 32, - 33, 32, 32, 29, 28, 27, 27, 28, 27, 26, 26, 25, 25, 24, 23, 26, - 27, 26, 26, 25, 25, 25, 24, 22, 22, 23, 23, 24, 26, 30, 40, 49, - 72, 84, 74, 88, 52, 18, 45, 53, 50, 47, 44, 46, 51, 57, 71, 44, - 26, 41, 66, 26, 22, 29, 23, 22, 17, 16, 15, 16, 12, 8, 9, 9, - 16, 17, 18, 19, 19, 20, 20, 20, 17, 18, 20, 21, 20, 21, 23, 25, - 26, 27, 28, 26, 26, 28, 30, 32, 31, 32, 35, 38, 41, 38, 36, 35, - 33, 32, 30, 32, 35, 36, 36, 35, 34, 35, 37, 40, 41, 38, 39, 45, - 45, 37, 28, 25, 29, 35, 39, 36, 34, 33, 32, 31, 31, 30, 30, 31, - 32, 31, 30, 28, 27, 26, 26, 28, 28, 27, 26, 24, 24, 23, 22, 25, - 26, 25, 25, 24, 24, 24, 24, 21, 21, 21, 21, 23, 25, 29, 39, 50, - 67, 76, 79, 84, 62, 33, 53, 51, 48, 46, 48, 50, 55, 62, 66, 24, - 29, 65, 53, 17, 32, 27, 15, 23, 18, 16, 15, 15, 12, 8, 8, 9, - 16, 17, 17, 18, 19, 19, 20, 20, 19, 20, 21, 21, 22, 23, 24, 24, - 23, 24, 25, 26, 28, 28, 29, 30, 30, 32, 36, 40, 40, 38, 36, 34, - 31, 29, 30, 32, 35, 36, 35, 34, 35, 37, 39, 39, 37, 36, 37, 44, - 45, 38, 30, 26, 28, 34, 38, 37, 35, 33, 31, 31, 31, 30, 30, 31, - 30, 29, 29, 28, 27, 26, 26, 25, 25, 24, 23, 23, 22, 21, 21, 24, - 25, 25, 25, 24, 24, 24, 23, 22, 21, 20, 20, 22, 25, 29, 38, 49, - 60, 60, 73, 74, 70, 44, 50, 42, 44, 46, 51, 58, 65, 63, 38, 27, - 52, 66, 39, 26, 40, 25, 13, 21, 19, 19, 17, 15, 13, 8, 6, 8, - 16, 17, 17, 18, 19, 19, 20, 21, 21, 22, 22, 22, 22, 22, 23, 24, - 23, 24, 24, 24, 25, 26, 26, 29, 30, 32, 36, 39, 38, 36, 34, 34, - 32, 31, 32, 33, 34, 36, 34, 33, 32, 34, 36, 36, 34, 33, 34, 41, - 43, 36, 28, 25, 27, 31, 36, 37, 35, 33, 31, 30, 29, 28, 28, 29, - 29, 29, 28, 25, 25, 24, 23, 24, 24, 24, 23, 22, 22, 21, 21, 23, - 24, 24, 24, 23, 23, 23, 22, 20, 19, 19, 19, 20, 23, 28, 35, 43, - 52, 41, 55, 55, 66, 45, 36, 39, 57, 63, 63, 69, 54, 34, 32, 46, - 68, 52, 19, 34, 41, 19, 17, 22, 18, 19, 17, 15, 12, 8, 6, 8, - 16, 17, 17, 18, 19, 19, 20, 21, 22, 22, 23, 22, 21, 21, 21, 22, - 22, 23, 23, 23, 23, 24, 24, 27, 30, 32, 35, 37, 35, 34, 33, 32, - 30, 30, 31, 32, 33, 34, 33, 31, 31, 32, 34, 34, 32, 32, 32, 38, - 41, 35, 27, 23, 25, 31, 34, 34, 33, 31, 29, 28, 27, 26, 26, 26, - 26, 26, 25, 23, 21, 20, 20, 22, 22, 22, 21, 20, 20, 19, 18, 20, - 21, 21, 21, 20, 20, 20, 19, 18, 16, 18, 17, 19, 22, 27, 31, 34, - 54, 34, 24, 39, 62, 54, 30, 18, 30, 34, 38, 44, 33, 26, 42, 64, - 60, 27, 24, 42, 41, 19, 21, 22, 19, 19, 17, 15, 12, 8, 6, 8, - 16, 17, 17, 18, 19, 19, 20, 21, 24, 24, 24, 22, 21, 20, 21, 21, - 20, 21, 23, 22, 24, 24, 24, 27, 31, 34, 36, 37, 35, 34, 33, 31, - 29, 28, 31, 33, 34, 35, 34, 31, 30, 32, 34, 34, 32, 31, 33, 38, - 41, 35, 29, 24, 26, 30, 35, 34, 31, 29, 28, 27, 27, 26, 25, 24, - 23, 22, 22, 21, 20, 19, 19, 20, 20, 19, 18, 18, 17, 16, 16, 17, - 17, 17, 17, 16, 16, 16, 16, 17, 18, 18, 18, 20, 22, 26, 28, 27, - 58, 42, 10, 20, 49, 58, 41, 45, 41, 39, 42, 39, 47, 55, 64, 59, - 29, 9, 31, 41, 37, 26, 23, 19, 17, 18, 17, 13, 11, 8, 6, 8, - 16, 17, 17, 18, 19, 19, 20, 21, 25, 25, 24, 22, 22, 21, 21, 20, - 20, 20, 22, 22, 23, 24, 24, 27, 30, 34, 35, 34, 33, 33, 33, 31, - 26, 26, 29, 31, 33, 33, 33, 31, 30, 32, 33, 33, 32, 31, 32, 39, - 41, 35, 30, 25, 26, 30, 36, 34, 31, 30, 28, 28, 28, 27, 26, 23, - 21, 21, 20, 19, 19, 18, 17, 18, 18, 17, 16, 16, 15, 14, 14, 15, - 15, 15, 15, 13, 13, 13, 13, 18, 18, 18, 18, 19, 20, 24, 26, 22, - 48, 51, 23, 13, 37, 51, 43, 59, 57, 48, 48, 47, 41, 46, 50, 22, - 10, 25, 31, 29, 30, 33, 25, 18, 17, 17, 15, 13, 10, 7, 6, 8, - 16, 17, 17, 18, 19, 19, 20, 22, 25, 25, 23, 22, 24, 22, 21, 21, - 20, 21, 22, 22, 22, 22, 23, 25, 28, 32, 32, 31, 31, 31, 32, 29, - 25, 26, 29, 30, 31, 32, 31, 28, 29, 31, 33, 33, 31, 30, 31, 36, - 38, 33, 28, 24, 25, 28, 34, 34, 32, 30, 29, 28, 27, 27, 26, 24, - 22, 21, 20, 19, 18, 17, 16, 18, 18, 17, 16, 16, 16, 15, 14, 14, - 15, 15, 15, 13, 13, 13, 14, 18, 17, 16, 16, 16, 19, 20, 22, 17, - 38, 43, 30, 31, 42, 47, 35, 46, 41, 30, 26, 19, 24, 19, 20, 25, - 28, 29, 22, 19, 26, 34, 30, 18, 16, 16, 15, 12, 10, 7, 6, 8, - 17, 18, 18, 19, 20, 21, 21, 23, 23, 23, 22, 21, 22, 22, 21, 21, - 19, 19, 21, 21, 21, 21, 22, 25, 29, 30, 30, 28, 28, 28, 28, 26, - 23, 24, 26, 28, 28, 29, 27, 26, 26, 27, 28, 29, 27, 27, 27, 31, - 34, 32, 28, 24, 24, 25, 30, 30, 29, 27, 26, 26, 25, 24, 23, 23, - 23, 22, 21, 19, 18, 17, 16, 19, 20, 19, 18, 18, 18, 17, 16, 16, - 16, 15, 15, 14, 14, 14, 15, 18, 19, 18, 18, 17, 19, 21, 22, 19, - 32, 35, 33, 41, 45, 42, 32, 29, 20, 12, 11, 7, 10, 15, 27, 40, - 37, 27, 22, 22, 25, 27, 26, 21, 17, 16, 14, 13, 11, 8, 7, 8, - 17, 18, 19, 19, 21, 21, 22, 23, 21, 21, 21, 21, 21, 21, 22, 21, - 18, 18, 19, 20, 21, 21, 22, 26, 31, 30, 30, 28, 27, 26, 26, 24, - 21, 23, 25, 26, 28, 27, 26, 25, 24, 25, 25, 26, 25, 25, 24, 27, - 30, 31, 28, 24, 23, 23, 26, 26, 25, 24, 24, 23, 23, 22, 21, 24, - 23, 22, 22, 19, 18, 18, 17, 21, 22, 21, 20, 20, 20, 19, 18, 18, - 18, 17, 16, 16, 16, 16, 16, 19, 20, 20, 19, 19, 20, 24, 24, 22, - 26, 31, 34, 37, 39, 35, 32, 28, 23, 19, 18, 17, 21, 26, 30, 32, - 31, 29, 27, 25, 23, 20, 21, 21, 17, 14, 14, 14, 12, 9, 7, 8, - 18, 18, 19, 20, 21, 21, 22, 22, 20, 20, 20, 20, 20, 21, 22, 21, - 17, 17, 18, 19, 21, 20, 22, 26, 31, 30, 29, 27, 26, 25, 25, 24, - 23, 25, 26, 28, 28, 28, 27, 24, 23, 24, 25, 25, 25, 24, 23, 26, - 31, 32, 29, 26, 24, 24, 26, 27, 26, 25, 24, 24, 23, 23, 22, 23, - 23, 22, 22, 20, 18, 18, 17, 21, 22, 21, 20, 20, 19, 18, 18, 18, - 18, 17, 16, 16, 16, 16, 16, 19, 20, 19, 18, 18, 19, 22, 22, 20, - 22, 26, 30, 33, 34, 35, 36, 38, 35, 34, 34, 32, 32, 31, 30, 27, - 25, 23, 22, 21, 18, 15, 17, 20, 16, 13, 12, 13, 11, 9, 8, 8, - 18, 18, 19, 20, 20, 21, 21, 22, 20, 20, 20, 20, 20, 20, 21, 20, - 17, 18, 18, 19, 20, 20, 22, 26, 29, 29, 28, 26, 25, 24, 24, 23, - 22, 24, 26, 27, 27, 27, 26, 24, 22, 23, 24, 25, 24, 23, 22, 26, - 30, 31, 28, 26, 24, 23, 25, 25, 25, 24, 23, 23, 22, 22, 21, 22, - 22, 21, 21, 19, 18, 17, 17, 20, 20, 20, 19, 18, 18, 17, 16, 18, - 17, 16, 16, 16, 16, 16, 16, 18, 18, 18, 16, 15, 17, 20, 20, 17, - 19, 23, 26, 27, 29, 31, 31, 31, 31, 31, 32, 31, 29, 26, 25, 24, - 22, 19, 18, 18, 16, 13, 14, 17, 14, 11, 11, 12, 11, 9, 8, 8, - 18, 18, 19, 20, 20, 20, 21, 21, 20, 19, 19, 19, 19, 20, 21, 20, - 18, 18, 19, 20, 20, 21, 24, 27, 29, 28, 27, 25, 24, 24, 23, 22, - 22, 23, 25, 26, 27, 26, 25, 24, 23, 24, 25, 25, 25, 24, 23, 25, - 29, 30, 27, 25, 23, 22, 23, 24, 24, 23, 22, 22, 21, 20, 20, 21, - 22, 21, 20, 19, 18, 17, 17, 19, 19, 19, 18, 17, 17, 16, 15, 17, - 17, 16, 15, 15, 15, 15, 15, 17, 17, 16, 15, 13, 15, 17, 17, 16, - 17, 22, 24, 26, 28, 27, 26, 28, 30, 31, 30, 28, 27, 25, 24, 21, - 20, 18, 17, 16, 15, 11, 12, 14, 12, 9, 10, 11, 10, 9, 8, 8, - 18, 18, 19, 19, 19, 20, 21, 21, 19, 19, 19, 19, 19, 19, 20, 20, - 18, 19, 20, 20, 20, 21, 25, 28, 28, 27, 26, 24, 23, 23, 22, 22, - 22, 24, 26, 27, 27, 26, 25, 24, 23, 24, 25, 25, 25, 24, 23, 26, - 30, 30, 27, 25, 24, 22, 23, 24, 24, 23, 22, 22, 22, 21, 20, 21, - 21, 20, 19, 19, 18, 17, 17, 19, 19, 18, 17, 17, 16, 15, 14, 17, - 16, 16, 15, 15, 15, 15, 15, 15, 16, 14, 13, 12, 13, 16, 16, 14, - 16, 19, 22, 23, 25, 26, 25, 26, 28, 29, 27, 24, 23, 22, 20, 18, - 17, 16, 15, 14, 11, 8, 10, 12, 10, 8, 9, 10, 10, 9, 8, 8, - 18, 18, 19, 19, 19, 20, 21, 20, 19, 19, 19, 19, 19, 19, 20, 20, - 19, 20, 21, 21, 21, 22, 26, 28, 28, 27, 26, 24, 23, 22, 22, 22, - 23, 25, 26, 27, 27, 26, 26, 24, 23, 24, 25, 26, 25, 24, 23, 26, - 30, 30, 27, 26, 25, 23, 23, 24, 24, 23, 23, 23, 22, 21, 20, 20, - 20, 19, 19, 19, 18, 17, 17, 18, 18, 17, 17, 16, 16, 15, 14, 16, - 16, 15, 15, 15, 15, 15, 15, 15, 15, 14, 12, 12, 13, 15, 16, 12, - 15, 18, 20, 18, 20, 23, 22, 24, 27, 26, 24, 24, 22, 20, 17, 16, - 16, 14, 14, 11, 9, 6, 7, 10, 8, 7, 8, 9, 10, 9, 8, 8, - 18, 18, 19, 19, 19, 19, 19, 18, 17, 17, 17, 18, 18, 19, 20, 20, - 19, 19, 20, 21, 21, 23, 25, 27, 27, 26, 25, 23, 21, 20, 20, 21, - 23, 24, 25, 26, 26, 26, 26, 24, 23, 24, 25, 25, 24, 23, 22, 24, - 28, 30, 28, 25, 23, 21, 21, 23, 24, 24, 24, 22, 21, 20, 20, 21, - 21, 20, 19, 20, 19, 19, 18, 18, 18, 17, 17, 16, 16, 15, 15, 17, - 17, 16, 15, 15, 14, 13, 12, 14, 13, 14, 13, 12, 13, 13, 15, 16, - 17, 19, 19, 20, 20, 21, 22, 23, 24, 24, 23, 22, 20, 19, 17, 17, - 15, 13, 12, 11, 10, 7, 7, 9, 7, 6, 7, 8, 9, 9, 8, 8, - 18, 18, 18, 18, 18, 18, 18, 18, 16, 16, 17, 18, 18, 19, 20, 20, - 19, 20, 21, 21, 22, 23, 25, 26, 27, 25, 25, 22, 21, 20, 20, 21, - 23, 24, 25, 25, 25, 25, 25, 25, 23, 24, 25, 24, 24, 23, 22, 25, - 28, 29, 27, 24, 22, 21, 21, 23, 24, 24, 24, 22, 21, 20, 19, 21, - 21, 20, 20, 20, 20, 19, 18, 18, 18, 17, 17, 16, 16, 16, 16, 17, - 17, 16, 15, 15, 14, 12, 12, 13, 12, 13, 14, 12, 13, 14, 15, 15, - 17, 18, 19, 19, 19, 20, 21, 22, 22, 22, 21, 20, 19, 17, 17, 18, - 16, 13, 12, 12, 12, 8, 8, 8, 7, 6, 7, 8, 9, 9, 8, 8, - 18, 18, 18, 18, 18, 18, 18, 17, 16, 16, 16, 17, 18, 18, 19, 20, - 20, 21, 21, 22, 23, 24, 26, 27, 25, 24, 23, 21, 20, 20, 19, 20, - 23, 24, 24, 25, 24, 24, 24, 24, 24, 25, 25, 25, 24, 23, 22, 24, - 27, 29, 27, 24, 22, 20, 20, 22, 23, 23, 23, 22, 21, 20, 19, 21, - 22, 21, 21, 21, 21, 20, 19, 19, 18, 17, 17, 16, 16, 16, 16, 17, - 16, 16, 15, 15, 14, 12, 12, 12, 12, 13, 13, 13, 14, 15, 16, 14, - 16, 17, 17, 17, 17, 18, 19, 19, 19, 19, 19, 17, 15, 14, 15, 18, - 15, 12, 12, 13, 11, 9, 8, 8, 6, 5, 7, 8, 9, 9, 8, 8, - 18, 18, 18, 18, 18, 18, 18, 17, 15, 15, 16, 17, 17, 18, 18, 19, - 21, 22, 22, 23, 25, 25, 26, 26, 25, 24, 23, 21, 20, 19, 19, 20, - 23, 24, 25, 25, 24, 24, 24, 23, 23, 24, 25, 24, 23, 23, 22, 24, - 27, 29, 27, 24, 22, 21, 21, 23, 23, 23, 23, 22, 21, 21, 20, 22, - 21, 21, 20, 21, 20, 19, 19, 19, 18, 17, 17, 15, 15, 15, 15, 16, - 16, 15, 15, 15, 14, 12, 12, 12, 12, 12, 12, 13, 14, 15, 15, 16, - 17, 18, 18, 17, 17, 17, 18, 18, 18, 18, 18, 16, 14, 13, 14, 16, - 14, 12, 11, 12, 10, 9, 8, 6, 6, 5, 7, 8, 9, 9, 8, 7, - 17, 17, 17, 17, 17, 17, 17, 16, 15, 15, 16, 16, 17, 17, 18, 19, - 21, 22, 23, 24, 26, 26, 26, 25, 24, 23, 22, 20, 19, 18, 18, 20, - 24, 24, 26, 25, 24, 24, 24, 23, 23, 23, 24, 24, 23, 22, 21, 23, - 27, 29, 26, 24, 23, 21, 21, 22, 23, 23, 23, 22, 22, 21, 20, 21, - 21, 20, 20, 20, 20, 19, 18, 18, 18, 17, 17, 15, 15, 15, 15, 16, - 16, 15, 14, 14, 14, 12, 12, 12, 11, 11, 11, 13, 13, 13, 15, 16, - 17, 18, 19, 19, 17, 17, 17, 18, 18, 18, 17, 15, 14, 12, 13, 14, - 13, 11, 11, 10, 9, 8, 7, 5, 5, 5, 7, 8, 9, 9, 8, 7, - 17, 17, 17, 17, 17, 17, 17, 16, 14, 14, 15, 16, 16, 17, 18, 18, - 21, 21, 22, 23, 26, 25, 25, 25, 23, 22, 21, 19, 19, 18, 18, 20, - 23, 24, 25, 25, 23, 23, 23, 22, 22, 22, 23, 23, 22, 21, 20, 22, - 26, 27, 25, 24, 23, 21, 21, 22, 22, 22, 22, 22, 21, 20, 20, 21, - 22, 22, 21, 21, 21, 20, 20, 19, 18, 17, 17, 14, 14, 14, 14, 15, - 15, 14, 14, 14, 14, 12, 12, 12, 12, 10, 11, 12, 13, 13, 13, 16, - 17, 17, 16, 17, 16, 15, 15, 16, 16, 16, 15, 14, 12, 11, 11, 14, - 13, 12, 11, 10, 8, 8, 6, 5, 5, 6, 7, 8, 9, 9, 7, 6, - 16, 16, 16, 16, 17, 17, 17, 16, 14, 14, 15, 15, 15, 16, 17, 18, - 19, 20, 21, 23, 25, 24, 24, 23, 22, 21, 21, 20, 19, 19, 18, 20, - 23, 23, 24, 24, 23, 23, 23, 22, 22, 22, 23, 23, 22, 21, 21, 22, - 25, 27, 25, 23, 21, 20, 20, 21, 22, 22, 22, 21, 20, 20, 19, 20, - 21, 21, 20, 20, 20, 19, 19, 18, 17, 17, 16, 14, 14, 14, 14, 15, - 15, 14, 14, 14, 13, 12, 11, 12, 12, 12, 11, 12, 12, 12, 12, 15, - 15, 15, 14, 15, 15, 14, 15, 15, 15, 15, 14, 14, 13, 11, 12, 14, - 13, 13, 12, 10, 9, 8, 7, 7, 7, 7, 8, 8, 9, 9, 7, 6, - 14, 15, 15, 16, 17, 17, 17, 16, 14, 14, 15, 15, 15, 15, 16, 17, - 17, 18, 20, 22, 23, 23, 23, 22, 21, 21, 21, 20, 18, 19, 19, 20, - 22, 22, 23, 23, 23, 23, 23, 22, 22, 23, 23, 24, 23, 22, 22, 22, - 23, 25, 25, 23, 21, 20, 20, 21, 22, 22, 22, 21, 20, 19, 18, 18, - 19, 19, 19, 18, 18, 18, 18, 18, 17, 17, 16, 16, 16, 16, 16, 16, - 15, 14, 14, 13, 12, 11, 11, 13, 12, 12, 12, 12, 12, 12, 12, 13, - 13, 13, 13, 13, 13, 13, 13, 15, 14, 13, 13, 14, 13, 12, 13, 13, - 13, 12, 11, 11, 10, 9, 9, 10, 9, 8, 8, 9, 9, 9, 8, 7, - 14, 15, 15, 16, 17, 17, 17, 16, 14, 14, 15, 15, 15, 15, 16, 17, - 17, 18, 20, 22, 23, 23, 23, 22, 21, 21, 21, 20, 19, 20, 20, 21, - 21, 22, 23, 23, 23, 23, 23, 22, 22, 23, 23, 24, 23, 22, 21, 21, - 23, 25, 25, 23, 21, 20, 20, 20, 21, 21, 21, 21, 20, 19, 18, 18, - 19, 19, 19, 18, 18, 18, 18, 18, 17, 17, 16, 16, 16, 16, 16, 16, - 15, 14, 14, 13, 12, 11, 11, 13, 13, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 14, 13, 12, 12, 13, 12, 11, 12, 12, - 12, 11, 10, 11, 10, 9, 9, 10, 10, 9, 9, 9, 9, 9, 8, 7, - 14, 15, 15, 16, 17, 17, 17, 16, 14, 14, 15, 15, 15, 15, 16, 17, - 17, 18, 20, 22, 23, 23, 23, 22, 21, 21, 21, 20, 19, 20, 20, 21, - 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 22, 21, 21, - 23, 25, 25, 23, 21, 20, 20, 20, 21, 21, 21, 21, 20, 19, 18, 18, - 19, 19, 19, 18, 18, 18, 18, 18, 17, 17, 16, 16, 16, 16, 16, 16, - 15, 14, 14, 13, 12, 11, 11, 13, 13, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 11, 10, 10, 10, 10, 12, 11, 11, 10, 11, 10, 9, 9, 11, - 10, 9, 9, 11, 10, 9, 9, 10, 10, 9, 9, 9, 9, 9, 8, 7 }; diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/jawbreaker.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/jawbreaker.cpp deleted file mode 100644 index 3bd6961aa99..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/jawbreaker.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/* - # - # File : jawbreaker.cpp - # ( C++ source file ) - # - # Description : A funny game featuring small colored balls. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#include "CImg.h" -using namespace cimg_library; -#undef min -#undef max - -// Main procedure -//---------------- -int main(int argc, char **argv) { - - // Display help (if option '-h' or '--help' specified) and retrieve program arguments - cimg_usage("A small and funny game featuring colored balls.\n (by David Tschumperle)."); - const char *score_file = cimg_option("-s",(char*)0,"Specify score file to use (0=default file)."); - cimg_help("\n" - "** Quick Help *********************************************************\n\n" - "Goal : Delete the board by clicking on groups of adjacent colored balls\n" - " (a group is made of at least two balls with the same color).\n" - " Suppressing large sets gives higher scores.\n\n" - "In-game keys : - BACKSPACE or SPACE = Undo last move\n" - " - CTRL+F = Toggle fullscreen mode\n" - " - ESC = Quit application\n" - " - Q = End current game\n\n" - "*********************************************************************"); - - // Load score file if available - CImgList score_history; - char filename_history[1024]; - std::sprintf(filename_history,"%s%s",score_file?"":cimg::temporary_path(),score_file?score_file:"/jawbreaker.score"); - std::FILE *file = std::fopen(filename_history,"r"); - if (file) { std::fclose(file); score_history = CImg::get_load_dlm(filename_history)<'y'; } - - // Create ball graphics - const unsigned int W = 12, H = 14, Wi = (W<<5), Hi = (H<<5); - unsigned int score = 0, previous_score = 0, shape_score = 0, - best_score = score_history?score_history.max():0U; - - const CImg<> colors(3,7,1,1, 255,255,255, 205,0,230, 0,235,0, 235,255,0, 235,0,0, 0,128,255, 450,350,300); - const unsigned char - white[] = { 255,255,255 }, orange[] = { 255,128,64 }, yellow[] = { 255,255,64 }, red[] = { 255,64,64 }, six = 6; - CImgList<> balls0(7,32,32,1,3,0); - cimglist_for(balls0,l) if (l) { - balls0[l].draw_circle(16,16,14,colors.data(0,l)); - cimg_forXYC(balls0[l],x,y,k) if (balls0(l,x,y,k)) (balls0(l,x,y,k)*=(32 - x + y)/60.0f)+=20; - balls0[l].draw_circle(16,16,14,colors.data(0,l),0.5f,~0U). - draw_circle(20,10,5,colors.data(),0.2f).draw_circle(22,8,2,colors.data(),0.4f).cut(0,255); - } - - // Create background graphics - CImgList balls(balls0); - CImg - mask = balls[1].get_cut(0,1).channel(0).dilate(3), - background = CImg(Wi,Hi,1,3,0). - noise(255,1).blur(6,20,0,true).equalize(100,0,255).blur(2,4,0,true); - background.get_shared_channel(0)/=4; background.get_shared_channel(1)/=8; background.get_shared_channel(2)/=2; - - // Begin user-interaction loop. - CImg board, previous_board, selected_board, shape, img(background); - CImgDisplay disp(img.width(),img.height(),"Jawbreaker",0); - bool redraw = true, gameover = false, title = true; - for (float opac = 0.0f; !disp.is_closed(); ) { - - // Init board - if (!board) { - (++((board.assign(W,H,1,1,5).noise(5,1))%=5)).get_shared_row(0).fill(0); - opac = (float)(score = previous_score = shape_score = 0); - gameover = false; redraw = title = true; - previous_board = board; - } - - // Draw graphical board - if (redraw) { - (img=background).draw_text(2,2,"Score : %u",yellow,0,0.7f,24,score). - draw_text(Wi - 90,2,"Best : %u",orange,0,0.9f,17,best_score); - if (selected_board) { - cimg_forXY(selected_board,x,y) if (selected_board(x,y)) - img.draw_image(x<<5,y<<5,balls[selected_board(x,y)],mask); - } else cimg_forXY(board,x,y) if (board(x,y)) img.draw_image(x<<5,y<<5,balls[board(x,y)],mask); - if (title) { - CImg text1, text2; - text1.draw_text(0,0,"- Jawbreaker -",white,0,1,48).resize(-100,-100,1,3); - text2.draw_text(0,0,"Press button to start",yellow,0,1,24).resize(-100,-100,1,3); - (img/=2).draw_image((Wi - text1.width())/2, - (Hi - text1.height())/2, - text1,text1.get_dilate(7),1,255). - draw_image((Wi - text2.width())/2, - (Hi + text1.height() + 10)/2, - text2,text2.get_dilate(5),0.7f,255); - for (float i = 1; i<10 && !disp.is_keyESC(); i+=0.25) - disp.display(img.get_crop((int)(Wi*(0.5f - i*i/200.0f)),(int)(Hi*(0.5f - i*i*i*i/20000.0f)), - (int)(Wi*(0.5f + i*i/200.0f)),(int)(Hi*(0.5f + i*i*i*i/20000.0f)))).wait(20); - } - } - if ((opac-=0.06f)>0) disp.display((+img).draw_text(disp.mouse_x() - 8,disp.mouse_y() - 80 + (int)(60*opac),"+%u", - white,0,(float)std::sqrt(opac),32,shape_score)).wait(20); - else { if (redraw) { disp.display(img); redraw = false; } else disp.wait(); } - - // Handle key and window events - if (disp.is_resized()) disp.resize(disp); - if (disp.is_keyBACKSPACE() || disp.is_keySPACE()) { - board = previous_board; score = previous_score; selected_board.assign(); redraw = true; disp.set_key(); - } - if (disp.is_keyQ()) { gameover = true; disp.set_key(); } - if (disp.is_keyESC()) disp.close(); - if (disp.is_keyCTRLLEFT() && disp.is_keyF()) disp.toggle_fullscreen().display(img); - - // Handle ball selection and removal - const int x = disp.mouse_x()*board.width()/disp.width(), y = disp.mouse_y()*board.height()/disp.height(); - if (disp.button()&1 && x>=0 && y>=0) { - if (title) { title = false; redraw = true; } else { - if (!board(x,y)) { selected_board.assign(); redraw = true; } - else { - if (!selected_board || selected_board(x,y)!=6) { - (selected_board=board).draw_fill(x,y,0,&six,1,shape); - if ((shape_score=(unsigned int)shape.sum())<2) selected_board.assign(); - else { shape_score-=1; shape_score*=shape_score; opac = 1.0f; redraw = true; } - } else { - selected_board.assign(); - previous_board = board; - previous_score = score; - score += shape_score; - board&=--shape; - redraw = true; - - // Handle board modification due to ball removal - for (int pmax = board.width(), p = 0; p=0; --q) { - while (qs>=0 && !board(p,qs)) --qs; - board(p,q) = (qs>=0?board(p,qs--):0); - } - if (!board(p,board.height() - 1)) { - board.draw_image(p,board.get_crop(p,0,board.width() - 1,board.height() - 1).shift(-1)); - if (p text1, text2, text3, text4, text5, text6; - text1.draw_text(0,0,"Game Over !",white,0,1,48).resize(-100,-100,1,3); - const unsigned int remaining_balls = (unsigned int)board.get_cut(0,1).sum(); - if (remaining_balls<8) { - const unsigned int bonus = (22 - 2*remaining_balls)*10; - score += bonus; - text2.draw_text(0,0,"Jawbreaker Bonus : +%u",white,0,1,24,bonus); - } - score_history.insert(CImg::vector(score)); - text3.draw_text(0,0,"Final score : %u",yellow,0,1,24,score).resize(-100,-100,1,3); - text4.draw_text(0,0,score>best_score?"** New record ! **":"Best score : %u", - orange,0,1,24,score>best_score?score:best_score).resize(-100,-100,1,3); - text5.draw_text(0,0,"Average score : %u",red,0,1,24, - score_history?(unsigned int)(score_history>'x').mean():0U).resize(-100,-100,1,3); - text6.draw_text(0,0,"Games played : %u",red,0,1,24,score_history.size()).resize(-100,-100,1,3); - if (score>best_score) best_score = score; - - unsigned int yt = (Hi - text1.height())/2 - 20; - (img/=2).draw_image((Wi - text1.width())/2,yt,text1,text1.get_dilate(7),1,255); yt+=80; - if (text2) { img.draw_image((Wi - text2.width())/2,yt,text2,text2.get_dilate(5),1,255); yt+=25; } - img.draw_image((Wi - text3.width())/2,yt,text3,text3.get_dilate(5),1,255). - draw_image((Wi - text4.width())/2,yt + 25,text4,text4.get_dilate(5),1,255). - draw_image((Wi - text5.width())/2,yt + 50,text5,text5.get_dilate(5),1,255). - draw_image((Wi - text6.width())/2,yt + 75,text6,text6.get_dilate(5),1,255).display(disp); - for (disp.flush(); !disp.is_closed() && !disp.key() && !disp.button(); disp.wait()) - if (disp.is_resized()) disp.resize(disp); - disp.flush(); - board.assign(); - for (float i = 10; i>0 && !disp.is_keyESC(); i-=0.25) - disp.display(img.get_crop((int)(Wi*(0.5f - i*i*i*i/20000.0f)),(int)(Hi*(0.5f - i*i/200.0f)), - (int)(Wi*(0.5f + i*i*i*i/20000.0f)),(int)(Hi*(0.5f + i*i/200.0f)))).wait(20); - } - } - - // Save score history if possible, and exit. - if (score_history) { - file = std::fopen(filename_history,"w"); - if (file) { std::fclose(file); (score_history>'y').save_dlm(filename_history); } - } - - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/mcf_levelsets2d.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/mcf_levelsets2d.cpp deleted file mode 100644 index 1e3cbb3b3e8..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/mcf_levelsets2d.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - # - # File : mcf_levelsets2d.cpp - # ( C++ source file ) - # - # Description : Implementation of the Mean Curvature Flow on a 2D curve, - # using the framework of Level Sets. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#include "CImg.h" -using namespace cimg_library; -#undef min -#undef max - -// Retrieve the curve corresponding to the zero level set of the distance function. -template -CImg get_level0(const CImg& img) { - CImg dest(img); - CImg_2x2(I,T); Inn = 0; - cimg_for2x2(img,x,y,0,0,I,T) if (Icc*Inc<0 || Icc*Icn<0) dest(x,y) = 255; else dest(x,y) = Icc<0?100:0; - return dest; -} - -/*-------------------- - - Main procedure - -----------------------*/ -int main(int argc,char **argv) { - cimg_usage("Perform a Mean Curvature Flow on closed curves, using Level Sets"); - const float dt = cimg_option("-dt",0.8f,"PDE time step"); - const unsigned int nb_iterations = cimg_option("-iter",10000,"Number of iterations"); - - // Create a user-defined closed curve. - CImg curve(256,256,1,2,0); - unsigned char col1[] = {0,255}, col2[] = {200,255}, col3[] = {255,255}; - curve.draw_grid(20,20,0,0,false,false,col1,0.4f,0xCCCCCCCC,0xCCCCCCCC). - draw_text(5,5,"Please draw your curve\nin this window\n(Use your mouse)",col1); - CImgDisplay disp(curve,"Mean curvature flow",0); - int xo = -1, yo = -1, x0 = -1, y0 = -1, x1 = -1, y1 = -1; - while (!disp.is_closed() && (x0<0 || disp.button())) { - if (disp.button() && disp.mouse_x()>=0 && disp.mouse_y()>=0) { - if (x0<0) { xo = x0 = disp.mouse_x(); yo = y0 = disp.mouse_y(); } else { - x1 = disp.mouse_x(); y1 = disp.mouse_y(); - curve.draw_line(x0,y0,x1,y1,col2).display(disp); - x0 = x1; y0 = y1; - } - } - disp.wait(); - if (disp.is_resized()) disp.resize(disp); - } - curve.draw_line(x1,y1,xo,yo,col2).channel(0).draw_fill(0,0,col3); - CImg<> img = CImg<>(curve.get_shared_channel(0)).normalize(-1,1); - - // Perform the "Mean Curvature Flow". - img.distance_eikonal(10); - CImg_3x3(I,float); - for (unsigned int iteration = 0; iteration velocity(img.width(),img.height(),img.depth(),img.spectrum()); - float *ptrd = velocity.data(), veloc_max = 0; - cimg_for3x3(img,x,y,0,0,I,float) { - const float - ix = (Inc - Ipc)/2, - iy = (Icn - Icp)/2, - ixx = Inc + Ipc - 2*Icc, - iyy = Icn + Icp - 2*Icc, - ixy = (Ipp + Inn - Inp - Ipn)/4, - ngrad = ix*ix + iy*iy, - iee = (ngrad>1e-5)?((iy*iy*ixx - 2*ix*iy*ixy + ix*ix*iyy)/ngrad):0; - *(ptrd++) = iee; - if (iee>veloc_max) veloc_max = iee; else if (-iee>veloc_max) veloc_max = -iee; - } - if (veloc_max>0) img+=(velocity*=dt/veloc_max); - if (!(iteration%10)) { - get_level0(img).resize(disp.width(),disp.height()). - draw_grid(20,20,0,0,false,false,col3,0.4f,0xCCCCCCCC,0xCCCCCCCC). - draw_text(5,5,"Iteration %d",col3,0,1,13,iteration).display(disp); - } - if (!(iteration%60)) img.distance_eikonal(1,3); - if (disp.is_resized()) disp.resize(); - } - - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/mcf_levelsets3d.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/mcf_levelsets3d.cpp deleted file mode 100644 index a40ed7ed9a5..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/mcf_levelsets3d.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/* - # - # File : mcf_levelsets3d.cpp - # ( C++ source file ) - # - # Description : Implementation of the Mean Curvature Flow on Surfaces - # using the framework of Level Sets 3D. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#include "CImg.h" -using namespace cimg_library; -#undef min -#undef max - -// Apply the Mean curvature flow PDE -//----------------------------------- -template CImg& mcf_PDE(CImg& img, const unsigned int nb_iterations, - const float dt=0.25f, const float narrow=4.0f) { - CImg velocity(img.width(),img.height(),img.depth(),img.spectrum()); - CImg_3x3x3(I,float); - for (unsigned int iteration = 0; iterationveloc_max) veloc_max = veloc; else if (-veloc>veloc_max) veloc_max = -veloc; - } else *(ptrd++) = 0; - if (veloc_max>0) img+=(velocity*=dt/veloc_max); - } - return img; -} - -/*---------------------- - - Main procedure - - --------------------*/ -int main(int argc,char **argv) { - cimg_usage("Mean curvature flow of a surface, using 3D level sets"); - const char *file_i = cimg_option("-i",(char*)0,"Input image"); - const float dt = cimg_option("-dt",0.05f,"PDE Time step"); - const float narrow = cimg_option("-band",5.0f,"Size of the narrow band"); - const bool both = cimg_option("-both",false,"Show both evolving and initial surface"); - - // Define the signed distance map of the initial surface. - CImg<> img; - if (file_i) { - const float sigma = cimg_option("-sigma",1.2f,"Segmentation regularity"); - const float alpha = cimg_option("-alpha",5.0f,"Region growing tolerance"); - img.load(file_i).channel(0); - CImg s; - CImgDisplay disp(img,"Please select a starting point"); - while (!s || s[0]<0) s = img.get_select(0,disp); - CImg<> region; - float tmp[] = { 0 }; - img.draw_fill(s[0],s[1],s[2],tmp,1,region,alpha); - ((img = region.normalize(-1,1))*=-1).blur(sigma); - } - else { // Create synthetic implicit function. - img.assign(60,60,60); - const float exte[] = { 1 }, inte[] = { -1 }; - img.fill(*exte).draw_rectangle(15,15,15,45,45,45,inte).draw_rectangle(25,25,0,35,35,img.depth() - 1,exte). - draw_rectangle(0,25,25,img.width() - 1,35,35,exte).draw_rectangle(25,0,25,35,img.height() - 1,35,exte).noise(0.7); - } - img.distance_eikonal(10,0,0.1f); - - // Compute corresponding surface triangularization by the marching cube algorithm (isovalue 0). - CImg<> points0; - CImgList faces0; - if (both) points0 = img.get_isosurface3d(faces0,0); - const CImgList colors0(faces0.size(),CImg::vector(100,200,255)); - const CImgList<> opacities0(faces0.size(),1,1,1,1,0.2f); - - // Perform MCF evolution. - CImgDisplay disp(256,256,0,1), disp3d(512,512,0,0); - float alpha = 0, beta = 0; - for (unsigned int iteration = 0; !disp.is_closed() && !disp3d.is_closed() && - !disp.is_keyESC() && !disp3d.is_keyESC() && !disp.is_keyQ() && !disp3d.is_keyQ(); ++iteration) { - disp.set_title("3D implicit Function (iter. %u)",iteration); - disp3d.set_title("Mean curvature flow 3D - Isosurface (iter. %u)",iteration); - - // Apply PDE on the distance function. - mcf_PDE(img,1,dt,narrow); // Do one iteration of mean curvature flow. - // Every 10 steps, do one iteration of distance function re-initialization. - if (!(iteration%10)) img.distance_eikonal(1,narrow,0.5f); - - // Compute surface triangularization by the marching cube algorithm (isovalue 0) - CImgList faces; - CImg<> points = img.get_isosurface3d(faces,0); - CImgList colors(faces.size(),CImg::vector(200,128,100)); - CImgList<> opacities(faces.size(),CImg<>::vector(1.0f)); - const float fact = 3*cimg::max(disp3d.width(),disp3d.height())/(4.0f*cimg::max(img.width(),img.height())); - - // Append initial object if necessary. - if (both) { - points.append_object3d(faces,points0,faces0); - colors.insert(colors0); - opacities.insert(opacities0); - } - - // Center and rescale the objects - cimg_forX(points,l) { - points(l,0)=(points(l,0) - img.width()/2)*fact; - points(l,1)=(points(l,1) - img.height()/2)*fact; - points(l,2)=(points(l,2) - img.depth()/2)*fact; - } - - // Display 3D object on the display window. - CImg visu(disp3d.width(),disp3d.height(),1,3,0); - const CImg<> rot = CImg<>::rotation_matrix(1,0,0,(beta+=0.01f))*CImg<>::rotation_matrix(0,1,1,(alpha+=0.05f)); - if (points.size()) { - visu.draw_object3d(visu.width()/2.0f,visu.height()/2.0f,0.0f, - rot*points,faces,colors,opacities,3, - false,500.0,0.0f,0.0f,-8000.0f).display(disp3d); - } else visu.fill(0).display(disp3d); - img.display(disp.wait(20)); - - if ((disp3d.button() || disp3d.key()) && points.size() && !disp3d.is_keyESC() && !disp3d.is_keyQ()) { - const unsigned char white[3] = { 255, 255, 255 }; - visu.fill(0).draw_text(10,10,"Time stopped, press any key to start again",white). - display_object3d(disp3d,points,faces,colors,opacities,true,4,3,false,500,0,0,-5000,0.4f,0.3f); - disp3d.set_key(); - } - if (disp.is_resized()) disp.resize(false); - if (disp3d.is_resized()) disp3d.resize(false); - disp.wait(50); - } - - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/odykill.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/odykill.cpp deleted file mode 100644 index a987a6a7699..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/odykill.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* - # - # File : odykill.cpp - # ( C++ source file ) - # - # Description : Simple shoot-em-up game featuring the Robotvis/Odyssee Team ! - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#include "img/odykill.h" -#include "CImg.h" -using namespace cimg_library; - -// Main procedure -//---------------- -int main(int argc,char **argv) { - - // Create game graphics - CImg graphics[21] = { - CImg(data_tomato,100,100,1,3,false), - CImg(data_heart,100,100,1,3,false), - CImg(data_dynamite,100,100,1,3,false), - CImg(data_brain,100,100,1,3,false), - CImg(data_cdrom,100,100,1,3,false), - CImg(data_enemy,113,150,1,3,false), - CImg(data_enemy2,116,155,1,3,false), - CImg(data_enemy3,104,134,1,3,false), - CImg(data_enemy4,141,151,1,3,false), - CImg(data_enemy5,140,152,1,3,false), - CImg(data_enemy6,131,156,1,3,false), - CImg(data_enemy7,114,125,1,3,false), - CImg(data_enemy8,97,125,1,3,false), - CImg(data_enemy9,143,134,1,3,false), - CImg(data_enemy10,158,214,1,3,false), - CImg(data_enemy11,131,168,1,3,false), - CImg(data_enemy12,114,138,1,3,false), - CImg(data_enemy13,144,144,1,3,false), - CImg(data_enemy14,132,153,1,3,false), - CImg(data_enemy15,152,151,1,3,false), - CImg(data_enemy16,139,185,1,3,false), - }; - CImg<> masks[21]; - const unsigned char black[] = { 0,0,0 }, white[] = { 255,255,255 }; - - // Display weapon selection menu - CImg back0(640,480,1,3), title(data_title,294,94,1,3,true), choose(data_choose,524,49,1,3,true); - back0.fill(0).draw_image(back0.width()/2 - title.width()/2,30,title). - draw_image(back0.width()/2 - choose.width()/2,150,choose); - CImgDisplay disp(back0,"OdyKill"); - int weapon=-1; - - while (!disp.is_closed() && !disp.button()) { - weapon = -1; - for (int k=0; k<5; k++) { - const int mx = disp.mouse_x(), my = disp.mouse_y(); - if (!((mx - 40)/110==k && my>250 && my<350)) back0.draw_image(40 + k*110,250,graphics[k]/2.0); - else back0.draw_image(40 + k*110,250,graphics[weapon=k]); - } - CImg tmp = CImg().draw_text(0,0, - weapon==0?" Tomato ": - weapon==1?" Heart ": - weapon==2?" Dynamite ": - weapon==3?" Brain ": - weapon==4?" CD-Rom ": - " ",white,black,1,32).resize(-100,-100,1,1), - tmp2 = tmp.get_blur(6).normalize(0,255).draw_image(tmp,0.5f); - cimg_forC(back0,k) back0.draw_image(250,390,0,k,tmp2); - - disp.resize(disp).display(back0).wait(); - if (disp.is_keyCTRLLEFT() && disp.is_keyF()) disp.toggle_fullscreen(); - if (disp.is_closed() || disp.is_keyQ() || disp.is_keyESC()) std::exit(0); - } - disp.hide_mouse(); - - /*--------------------------------- - - Go ! - - --------------------------------*/ - - const CImg - background = CImg(100,100,1,3,0).noise(100,2).draw_plasma(). - resize(back0.width(),back0.height(),1,3,5)/2.5; - { for (unsigned int k=0; k<21; k++) { - CImg<> tmp = graphics[k].resize(k<5?32:164,k<5?32:164,1,3); - cimg_forXY(tmp,x,y) tmp(x,y) = (tmp(x,y,0)==255 && tmp(x,y,1)==255 && tmp(x,y,2)==255)?0.0f:1.0f; - masks[k]=tmp.get_shared_channel(0); - graphics[k].resize(k<5?32:164,k<5?32:164,1,3,5); - }} - - CImg canvas(background); - int n = 5 + ((int)(200*cimg::rand())%16); - CImg tomato = graphics[weapon], enemy = graphics[n]; - CImg<> m_tomato = masks[weapon], m_enemy = masks[n]; - - double angle = 0; - int tomato_x = 0,tomato_y = 0,shooted = 0; - double enemy_x = -1000, enemy_y = -1000, enemy_z = -1000, tomato_z = 0, vx = 0, vy = 0, vz = 0, va = 0; - double speed = cimg_option("-speed",5.0,"Speed"); - int timeleft = 2000, score = 0; - CImg r_enemy; - - // Main loop - while (timeleft && !disp.is_closed() && !disp.is_keyESC() && !disp.is_keyQ()) { - --timeleft; - const int mx = disp.mouse_x()*back0.width()/disp.width(), my = disp.mouse_y()*back0.height()/disp.height(); - - // Handle object motion - if (tomato_z>0) { - tomato_z+=0.07; tomato_y -= (int)(20*std::cos(cimg::PI/7 + tomato_z*cimg::PI)); - if (tomato_z>=1) { tomato_z=0; tomato_x = mx; tomato_y = my; } - } - if (!shooted) { enemy_x +=vx; enemy_y +=vy; enemy_z +=vz; } - else { - va = 10; - enemy_y += vy; - vy += 2; - tomato_z = 0; - if (enemy_y>5*canvas.height()/4) { - shooted = 0; - int n = 5 + ((int)(200*cimg::rand())%16); - enemy = graphics[n]; - m_enemy = masks[n]; - enemy_x=cimg::rand(-1,1)*1e8; enemy_y=cimg::rand(-1,1)*1e8; enemy_z=cimg::rand(-1,1)*1e8; - va = angle = 0; - } - } - - if (enemy_x<0) { enemy_x=0; vx = speed*cimg::rand(-1,1); } - if (enemy_x>canvas.width()) { enemy_x=canvas.width(); vx = speed*cimg::rand(-1,1); } - if (enemy_y<0) { enemy_y=0; vy = speed*cimg::rand(-1,1); } - if (!shooted && enemy_y>canvas.height()) { enemy_y=canvas.height(); vy = speed*cimg::rand(-1,1); } - if (enemy_z<0.1) { enemy_z = 0.1; vz = speed*0.01*cimg::rand(-1,1); } - if (enemy_z>0.7) { enemy_z = 0.7; vz = speed*0.01*cimg::rand(-1,1); } - angle+=va; - - // Handle mouse interaction - if (!disp.button()) { - if (tomato_z==0) { - tomato_x = mx; tomato_y = my; - } - } else tomato_z +=0.0001; - - // Detect shooting - if (cimg::abs(tomato_z - enemy_z)<0.1) { - if (tomato_x>enemy_x - r_enemy.width()/2 && tomato_xenemy_y - r_enemy.height()/2 && tomato_y rm_enemy = m_enemy.get_resize(r_enemy.width(),r_enemy.height()); - CImg r_tomato = tomato.get_resize((int)(8 + tomato.width()*(1 - tomato_z)), - (int)(8 + tomato.height()*(1 - tomato_z)),-100,-100); - CImg<> rm_tomato = m_tomato.get_resize(r_tomato.width(),r_tomato.height()); - - if (angle!=0) { - r_enemy.rotate((float)angle,0,0); - rm_enemy.rotate((float)angle,0,0); - cimg_forXY(r_enemy,x,y) r_enemy(x,y,0) = (r_enemy(x,y,0) + 255)/2; - } - r_enemy*=(1 - (enemy_z - 0.1)/1.6); - r_tomato*=(1 - tomato_z/1.6); - rm_enemy*=(1 - (enemy_z - 0.1)/1.6); - - if (enemy_z>tomato_z) { - canvas.draw_image((int)(enemy_x - r_enemy.width()/2), - (int)(enemy_y - r_enemy.height()/2), - r_enemy,rm_enemy); - if (tomato_x>=0) canvas.draw_image(tomato_x - r_tomato.width()/2, - tomato_y - r_tomato.height()/2, - r_tomato,rm_tomato); - } - else { - if (tomato_x>=0) canvas.draw_image(tomato_x - r_tomato.width()/2, - tomato_y - r_tomato.height()/2, - r_tomato,rm_tomato); - canvas.draw_image((int)(enemy_x - r_enemy.width()/2), - (int)(enemy_y - r_enemy.height()/2), - r_enemy,rm_enemy); - } - canvas.draw_text(1,1," Time left %d, Score = %d",white,0,0.5f,24,timeleft,score); - disp.resize(disp).display(canvas).wait(25); - if (disp.is_keyCTRLLEFT() && disp.is_keyF()) disp.toggle_fullscreen(); - } - - std::fprintf(stderr,"\n\n YOUR SCORE : %d\n\n\n",score); - - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/pde_TschumperleDeriche2d.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/pde_TschumperleDeriche2d.cpp deleted file mode 100644 index 6d19832456d..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/pde_TschumperleDeriche2d.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/* - # - # File : pde_TschumperleDeriche2d.cpp - # ( C++ source file ) - # - # Description : Implementation of the Tschumperle-Deriche's Regularization - # PDE, for 2D multivalued images, as described in the articles below. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # (1) PDE-Based Regularization of Multivalued Images and Applications. - # (D. Tschumperle). PhD Thesis. University of Nice-Sophia Antipolis, December 2002. - # (2) Diffusion PDE's on Vector-valued Images : Local Approach and Geometric Viewpoint. - # (D. Tschumperle and R. Deriche). IEEE Signal Processing Magazine, October 2002. - # (3) Vector-Valued Image Regularization with PDE's : A Common Framework for Different Applications. - # (D. Tschumperle and R. Deriche). CVPR'2003, Computer Vision and Pattern Recognition, - # Madison, United States, June 2003. - # - # This code can be used to perform image restoration, inpainting, magnification or flow visualization. - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#include "CImg.h" -using namespace cimg_library; -#ifndef cimg_imagepath -#define cimg_imagepath "img/" -#endif -#undef min -#undef max - -// Main procedure -//---------------- -int main(int argc,char **argv) { - - // Read command line arguments - //----------------------------- - cimg_usage("Tschumperle-Deriche's flow for 2D Image Restoration, Inpainting, Magnification or Flow visualization"); - const char *file_i = cimg_option("-i",cimg_imagepath "milla.bmp","Input image"); - const char *file_m = cimg_option("-m",(char*)NULL,"Mask image (if Inpainting)"); - const char *file_f = cimg_option("-f",(char*)NULL,"Flow image (if Flow visualization)"); - const char *file_o = cimg_option("-o",(char*)NULL,"Output file"); - const double zoom = cimg_option("-zoom",1.0,"Image magnification"); - - const unsigned int nb_iter = cimg_option("-iter",100000,"Number of iterations"); - const double dt = cimg_option("-dt",20.0,"Adapting time step"); - const double alpha = cimg_option("-alpha",0.0,"Gradient smoothing"); - const double sigma = cimg_option("-sigma",0.5,"Structure tensor smoothing"); - const float a1 = cimg_option("-a1",0.5f,"Diffusion limiter along minimal variations"); - const float a2 = cimg_option("-a2",0.9f,"Diffusion limiter along maximal variations"); - const double noiseg = cimg_option("-ng",0.0,"Add gauss noise before aplying the algorithm"); - const double noiseu = cimg_option("-nu",0.0,"Add uniform noise before applying the algorithm"); - const double noises = cimg_option("-ns",0.0,"Add salt&pepper noise before applying the algorithm"); - const bool stflag = cimg_option("-stats",false,"Display image statistics at each iteration"); - const unsigned int save = cimg_option("-save",0,"Iteration saving step"); - const unsigned int visu = cimg_option("-visu",10,"Visualization step (0=no visualization)"); - const unsigned int init = cimg_option("-init",3,"Inpainting initialization (0=black, 1=white, 2=noise, 3=unchanged)"); - const unsigned int skip = cimg_option("-skip",1,"Step of image geometry computation"); - bool view_t = cimg_option("-d",false,"View tensor directions (useful for debug)"); - double xdt = 0; - - // Variable initialization - //------------------------- - CImg<> img, flow; - CImg mask; - - if (file_i) { - img = CImg<>(file_i).resize(-100,-100,1,-100); - if (file_m) mask = CImg(file_m).resize(img.width(),img.height(),1,1); - else if (zoom>1) { - mask = CImg(img.width(),img.height(),1,1,-1). - resize((int)(img.width()*zoom),(int)(img.height()*zoom),1,1,4) + 1; - img.resize((int)(img.width()*zoom),(int)(img.height()*zoom),1,-100,3); - } - } else { - if (file_f) { - flow = CImg<>(file_f); - img = CImg<>((int)(flow.width()*zoom),(int)(flow.height()*zoom),1,1,0).noise(100,2); - flow.resize(img.width(),img.height(),1,2,3); - } else - throw CImgException("You need to specify at least one input image (option -i), or one flow image (option -f)"); - } - img.noise(noiseg,0).noise(noiseu,1).noise(noises,2); - float initial_min, initial_max = img.max_min(initial_min); - if (mask && init!=3) - cimg_forXYC(img,x,y,k) if (mask(x,y)) - img(x,y,k) = (float)((init? - (init==1?initial_max:((initial_max - initial_min)*cimg::rand())): - initial_min)); - - CImgDisplay disp; - if (visu) disp.assign(img,"Iterated Image"); - CImg<> G(img.width(),img.height(),1,3,0), T(G), veloc(img), val(2), vec(2,2); - - // PDE main iteration loop - //------------------------- - for (unsigned int iter = 0; iter grad = img.get_gradient(); - if (alpha!=0) cimglist_for(grad,l) grad[l].blur((float)alpha); - G.fill(0); - cimg_forXYC(img,x,y,k) { - const float ix = grad[0](x,y,k), iy = grad[1](x,y,k); - G(x,y,0) += ix*ix; - G(x,y,1) += ix*iy; - G(x,y,2) += iy*iy; - } - if (sigma!=0) G.blur((float)sigma); - - // When using PDE for image restoration, inpainting or zooming - T.fill(0); - if (!mask) cimg_forXY(G,x,y) { - G.get_tensor_at(x,y).symmetric_eigen(val,vec); - const float - l1 = (float)std::pow(1.0f + val[0] + val[1],-a1), - l2 = (float)std::pow(1.0f + val[0] + val[1],-a2), - ux = vec(1,0), - uy = vec(1,1); - T(x,y,0) = l1*ux*ux + l2*uy*uy; - T(x,y,1) = l1*ux*uy - l2*ux*uy; - T(x,y,2) = l1*uy*uy + l2*ux*ux; - } - else cimg_forXY(G,x,y) if (mask(x,y)) { - G.get_tensor_at(x,y).symmetric_eigen(val,vec); - const float - ux = vec(1,0), - uy = vec(1,1); - T(x,y,0) = ux*ux; - T(x,y,1) = ux*uy; - T(x,y,2) = uy*uy; - } - } - } - - // Compute the PDE velocity and update the iterated image - //-------------------------------------------------------- - CImg_3x3(I,float); - veloc.fill(0); - cimg_forC(img,k) cimg_for3x3(img,x,y,0,k,I,float) { - const float - a = T(x,y,0), - b = T(x,y,1), - c = T(x,y,2), - ixx = Inc + Ipc - 2*Icc, - iyy = Icn + Icp - 2*Icc, - ixy = 0.25f*(Ipp + Inn - Ipn - Inp); - veloc(x,y,k) = a*ixx + 2*b*ixy + c*iyy; - } - if (dt>0) { - float m, M = veloc.max_min(m); - xdt = dt/cimg::max(cimg::abs(m),cimg::abs(M)); - } else xdt=-dt; - img+=veloc*xdt; - img.cut((float)initial_min,(float)initial_max); - - // Display and save iterations - if (disp && !(iter%visu)) { - if (!view_t) img.display(disp); - else { - const unsigned char white[3] = {255,255,255}; - CImg visu = img.get_resize(disp.width(),disp.height()).normalize(0,255); - CImg<> isophotes(img.width(),img.height(),1,2,0); - cimg_forXY(img,x,y) if (!mask || mask(x,y)) { - T.get_tensor_at(x,y).symmetric_eigen(val,vec); - isophotes(x,y,0) = vec(0,0); - isophotes(x,y,1) = vec(0,1); - } - visu.draw_quiver(isophotes,white,0.5f,10,9,0).display(disp); - } - } - if (save && file_o && !(iter%save)) img.save(file_o,iter); - if (disp) disp.resize().display(img); - } - - // Save result and exit. - if (file_o) img.save(file_o); - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/pde_heatflow2d.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/pde_heatflow2d.cpp deleted file mode 100644 index f7c1267fb46..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/pde_heatflow2d.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - # - # File : pde_heatflow2D.cpp - # ( C++ source file ) - # - # Description : A simple Heat flow on 2D images. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -// Include library header file -#include "CImg.h" -#ifndef cimg_imagepath -#define cimg_imagepath "img/" -#endif -#undef min -#undef max - -// Make a simpler namespace alias if one wants to avoid 'using namespace cimg_library' -namespace cil = cimg_library; - -// Main procedure -//---------------- -int main(int argc,char **argv) { - - // Read command line arguments, and init images and displays - //----------------------------------------------------------- - cimg_usage("Perform a simple Heat Flow on 2D images"); - cil::CImg<> img(cimg_option("-i",cimg_imagepath "milla.bmp","Input image")), veloc(img); - const double dt = cimg_option("-dt",3.0,"Adapting time step"); - img. - noise(cimg_option("-ng",0.0,"Add gaussian noise"),0). - noise(cimg_option("-nu",0.0,"Add uniform noise"),1). - noise(cimg_option("-ns",0.0,"Add Salt&Pepper noise"),2); - cil::CImgDisplay profile(400,300,"Intensity Profile",0,false,true), disp(img,"Heat flow 2D",0,false,true); - disp.move((cil::CImgDisplay::screen_width() - disp.width() - profile.width())/2, - (cil::CImgDisplay::screen_height() - disp.height())/2); - - profile.move(disp.window_x() + 8 + disp.window_width(), disp.window_y()); - const float white[] = { 255,255,255 }; - bool run_PDE = true; - - // Begin PDE iteration loop - //------------------------- - for (int iter = 0; !disp.is_closed() && !profile.is_closed() && - !disp.is_keyQ() && !disp.is_keyESC() && !profile.is_keyQ() && !profile.is_keyESC();) { - - // Compute one iteration of PDE explicit scheme - if (run_PDE) { - CImg_3x3(I,float); - cimg_forC(img,k) cimg_for3x3(img,x,y,0,k,I,float) veloc(x,y,k) = Inc + Ipc + Icn + Icp - 4*Icc; - float m, M = veloc.max_min(m); - const double xdt = dt/(M - m); - img += veloc*xdt; - cil::CImg<>(img).draw_text(2,2,"iter = %d",white,0,1,13,iter).display(disp.wait(25)); - } - - // Plot (R,G,B) intensity profiles and display it - if (disp.mouse_x()>=0) { - const int - mx = disp.mouse_x(), my = disp.mouse_y(), - mnx = mx*profile.width()/disp.width(); - const unsigned char red[] = { 255,0,0 }, green[] = { 0,255,0 }, blue[] = { 0,0,255 }, white[] = { 255,255,255 }; - cil::CImg(profile.width(),profile.height(),1,3,0). - draw_graph(img.get_shared_row(my,0,0),red,1,1,0,255,0). - draw_graph(img.get_shared_row(my,0,1),green,1,1,0,255,0). - draw_graph(img.get_shared_row(my,0,2),blue,1,1,0,255,0). - draw_line(mnx,0,mnx,profile.height() - 1,white,0.5f,cil::cimg::rol(0xFF00FF00,iter%32)). - draw_text(2,2,"(x,y)=(%d,%d)",white,0,1,13,mx,my). - display(profile); - } - - // Mouse button stops/starts PDE evolution. - if (disp.button() || profile.button()) { disp.set_button(); profile.set_button(); run_PDE = !run_PDE; } - profile.resize(); - disp.resize(disp); - if (run_PDE) ++iter; - } - - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/plotter1d.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/plotter1d.cpp deleted file mode 100644 index cfcd92fdd00..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/plotter1d.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - # - # File : plotter1d.cpp - # ( C++ source file ) - # - # Description : A simple math formula plotter. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -// Include CImg library file and use its main namespace -#include "CImg.h" -using namespace cimg_library; - -// Main procedure -//---------------- -int main(int argc,char **argv) { - - // Read command line argument. - cimg_usage("Simple plotter of mathematical formulas"); - const char *const formula = cimg_option("-f","sin(x/8) % cos(2*x)","Formula to plot"); - const float x0 = cimg_option("-x0",-5.0f,"Minimal X-value"); - const float x1 = cimg_option("-x1",5.0f,"Maximal X-value"); - const int resolution = cimg_option("-r",1024,"Plot resolution"); - const unsigned int nresolution = resolution>1?resolution:1024; - const unsigned int plot_type = cimg_option("-p",1,"Plot type"); - const unsigned int vertex_type = cimg_option("-v",1,"Vertex type"); - - // Create plot data. - CImg values(4,nresolution,1,1,0); - const unsigned int r = nresolution - 1; - cimg_forY(values,X) values(0,X) = x0 + X*(x1 - x0)/r; - cimg::eval(formula,values).move_to(values); - - // Display interactive plot window. - values.display_graph(formula,plot_type,vertex_type,"X-axis",x0,x1,"Y-axis"); - - // Quit. - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/radon_transform2d.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/radon_transform2d.cpp deleted file mode 100644 index e5c076a27ed..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/radon_transform2d.cpp +++ /dev/null @@ -1,379 +0,0 @@ -/* - # - # File : radon_transform2d.cpp - # ( C++ source file ) - # - # Description : An implementation of the Radon Transform. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David G. Starkweather - # ( starkdg@sourceforge.net - starkweatherd@cox.net ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#include "CImg.h" -using namespace cimg_library; -#ifndef cimg_imagepath -#define cimg_imagepath "img/" -#endif - -#define ROUNDING_FACTOR(x) (((x) >= 0) ? 0.5 : -0.5) - -CImg GaussianKernel(double rho); -CImg ApplyGaussian(CImg im,double rho); -CImg RGBtoGrayScale(CImg &im); -int GetAngle(int dy,int dx); -CImg CannyEdges(CImg im, double T1, double T2,bool doHysteresis); -CImg<> RadonTransform(CImg im,int N); - -// Main procedure -//---------------- -int main(int argc,char **argv) { - cimg_usage("Illustration of the Radon Transform"); - - const char *file = cimg_option("-f",cimg_imagepath "parrot.ppm","path and file name"); - const double sigma = cimg_option("-r",1.0,"blur coefficient for gaussian low pass filter (lpf)"), - thresh1 = cimg_option("-t1",0.50,"lower threshold for canny edge detector"), - thresh2 = cimg_option("-t2",1.25,"upper threshold for canny edge detector");; - const int N = cimg_option("-n",64,"number of angles to consider in the Radon transform - should be a power of 2"); - - //color to draw lines - const unsigned char green[] = {0,255,0}; - CImg src(file); - - int rhomax = (int)std::sqrt((double)(src.width()*src.width() + src.height()*src.height()))/2; - - if (cimg::dialog(cimg::basename(argv[0]), - "Instructions:\n" - "Click on space bar or Enter key to display Radon transform of given image\n" - "Click on anywhere in the transform window to display a \n" - "corresponding green line in the original image\n", - "Start", "Quit",0,0,0,0, - src.get_resize(100,100,1,3),true)) std::exit(0); - - //retrieve a grayscale from the image - CImg grayScaleIm; - if ((src.spectrum() == 3) && (src.width() > 0) && (src.height() > 0) && (src.depth() == 1)) - grayScaleIm = (CImg)src.get_norm(0).quantize(255,false); - else if ((src.spectrum() == 1)&&(src.width() > 0) && (src.height() > 0) && (src.depth() == 1)) - grayScaleIm = src; - else { // image in wrong format - if (cimg::dialog(cimg::basename("wrong file format"), - "Incorrect file format\n","OK",0,0,0,0,0, - src.get_resize(100,100,1,3),true)) std::exit(0); - } - - //blur the image with a Gaussian lpf to remove spurious edges (e.g. noise) - CImg blurredIm = ApplyGaussian(grayScaleIm,sigma); - - //use canny edge detection algorithm to get edge map of the image - //- the threshold values are used to perform hysteresis in the edge detection process - CImg cannyEdgeMap = CannyEdges(blurredIm,thresh1,thresh2,false); - CImg radonImage = *(new CImg(500,400,1,1,0)); - - //display the two windows - CImgDisplay dispImage(src,"original image"); - dispImage.move(CImgDisplay::screen_width()/8,CImgDisplay::screen_height()/8); - CImgDisplay dispRadon(radonImage,"Radon Transform"); - dispRadon.move(CImgDisplay::screen_width()/4,CImgDisplay::screen_height()/4); - CImgDisplay dispCanny(cannyEdgeMap,"canny edges"); - //start main display loop - while (!dispImage.is_closed() && !dispRadon.is_closed() && - !dispImage.is_keyQ() && !dispRadon.is_keyQ() && - !dispImage.is_keyESC() && !dispRadon.is_keyESC()) { - - CImgDisplay::wait(dispImage,dispRadon); - - if (dispImage.is_keySPACE() || dispRadon.is_keySPACE()) { - radonImage = (CImg)RadonTransform(cannyEdgeMap,N).quantize(255,false).resize(500,400); - radonImage.display(dispRadon); - } - - //when clicking on dispRadon window, draw line in original image window - if (dispRadon.button()) - { - const double rho = dispRadon.mouse_y()*rhomax/dispRadon.height(), - theta = (dispRadon.mouse_x()*N/dispRadon.width())*2*cimg::PI/N, - x = src.width()/2 + rho*std::cos(theta), - y = src.height()/2 + rho*std::sin(theta); - const int x0 = (int)(x + 1000*std::cos(theta + cimg::PI/2)), - y0 = (int)(y + 1000*std::sin(theta + cimg::PI/2)), - x1 = (int)(x - 1000*std::cos(theta + cimg::PI/2)), - y1 = (int)(y - 1000*std::sin(theta + cimg::PI/2)); - src.draw_line(x0,y0,x1,y1,green,1.0f,0xF0F0F0F0).display(dispImage); - } - } - return 0; -} -/** - * PURPOSE: create a 5x5 gaussian kernel matrix - * PARAM rho - gaussiam equation parameter (default = 1.0) - * RETURN CImg the gaussian kernel - **/ - -CImg GaussianKernel(double sigma = 1.0) -{ - CImg resultIm(5,5,1,1,0); - int midX = 3, midY = 3; - cimg_forXY(resultIm,X,Y) { - resultIm(X,Y) = std::ceil(256.0*(std::exp(-(midX*midX + midY*midY)/(2*sigma*sigma)))/(2*cimg::PI*sigma*sigma)); - } - return resultIm; -} -/* - * PURPOSE: convolve a given image with the gaussian kernel - * PARAM CImg im - image to be convolved upon - * PARAM double sigma - gaussian equation parameter - * RETURN CImg image resulting from the convolution - * */ -CImg ApplyGaussian(CImg im,double sigma) -{ - CImg smoothIm(im.width(),im.height(),1,1,0); - - //make gaussian kernel - CImg gk = GaussianKernel(sigma); - //apply gaussian - - CImg_5x5(I,int); - cimg_for5x5(im,X,Y,0,0,I,int) { - float sum = 0; - sum += gk(0,0)*Ibb + gk(0,1)*Ibp + gk(0,2)*Ibc + gk(0,3)*Ibn + gk(0,4)*Iba; - sum += gk(1,0)*Ipb + gk(1,1)*Ipp + gk(1,2)*Ipc + gk(1,3)*Ipn + gk(1,4)*Ipa; - sum += gk(2,0)*Icb + gk(2,1)*Icp + gk(2,2)*Icc + gk(2,3)*Icn + gk(2,4)*Ica; - sum += gk(3,0)*Inb + gk(3,1)*Inp + gk(3,2)*Inc + gk(3,3)*Inn + gk(3,4)*Ina; - sum += gk(4,0)*Iab + gk(4,1)*Iap + gk(4,2)*Iac + gk(4,3)*Ian + gk(4,4)*Iaa; - smoothIm(X,Y) = sum/256; - } - return smoothIm; -} -/** - * PURPOSE: convert a given rgb image to a MxNX1 single vector grayscale image - * PARAM: CImg im - rgb image to convert - * RETURN: CImg grayscale image with MxNx1x1 dimensions - **/ - -CImg RGBtoGrayScale(CImg &im) -{ - CImg grayImage(im.width(),im.height(),im.depth(),1,0); - if (im.spectrum() == 3) { - cimg_forXYZ(im,X,Y,Z) { - grayImage(X,Y,Z,0) = (unsigned char)(0.299*im(X,Y,Z,0) + 0.587*im(X,Y,Z,1) + 0.114*im(X,Y,Z,2)); - } - } - grayImage.quantize(255,false); - return grayImage; -} -/** - * PURPOSE: aux. function used by CannyEdges to quantize an angle theta given by gradients, dx and dy - * into 0 - 7 - * PARAM: dx,dy - gradient magnitudes - * RETURN int value between 0 and 7 - **/ -int GetAngle(int dy,int dx) -{ - double angle = cimg::abs(std::atan2((double)dy,(double)dx)); - if ((angle >= -cimg::PI/8)&&(angle <= cimg::PI/8))//-pi/8 to pi/8 => 0 - return 0; - else if ((angle >= cimg::PI/8)&&(angle <= 3*cimg::PI/8))//pi/8 to 3pi/8 => pi/4 - return 1; - else if ((angle > 3*cimg::PI/8)&&(angle <= 5*cimg::PI/8))//3pi/8 to 5pi/8 => pi/2 - return 2; - else if ((angle > 5*cimg::PI/8)&&(angle <= 7*cimg::PI/8))//5pi/8 to 7pi/8 => 3pi/4 - return 3; - else if (((angle > 7*cimg::PI/8) && (angle <= cimg::PI)) || - ((angle <= -7*cimg::PI/8)&&(angle >= -cimg::PI))) //-7pi/8 to -pi OR 7pi/8 to pi => pi - return 4; - else return 0; -} -/** - * PURPOSE: create an edge map of the given image with hysteresis using thresholds T1 and T2 - * PARAMS: CImg im the image to perform edge detection on - * T1 lower threshold - * T2 upper threshold - * RETURN CImg edge map - **/ -CImg CannyEdges(CImg im, double T1, double T2, bool doHysteresis=false) -{ - CImg edges(im); - CImg secDerivs(im); - secDerivs.fill(0); - edges.fill(0); - CImgList gradients = im.get_gradient("xy",1); - int image_width = im.width(); - int image_height = im.height(); - - cimg_forXY(im,X,Y) { - double Gr = std::sqrt(std::pow((double)gradients[0](X,Y),2.0) + std::pow((double)gradients[1](X,Y),2.0)); - double theta = GetAngle(Y,X); - //if Gradient magnitude is positive and X,Y within the image - //take the 2nd deriv in the appropriate direction - if ((Gr > 0)&&(X < image_width - 2)&&(Y < image_height - 2)) { - if (theta == 0) - secDerivs(X,Y) = im(X + 2,Y) - 2*im(X + 1,Y) + im(X,Y); - else if (theta == 1) - secDerivs(X,Y) = im(X + 2,Y + 2) - 2*im(X + 1,Y + 1) + im(X,Y); - else if (theta == 2) - secDerivs(X,Y) = im(X,Y + 2) - 2*im(X,Y + 1) + im(X,Y); - else if (theta == 3) - secDerivs(X,Y) = im(X + 2,Y + 2) - 2*im(X + 1,Y + 1) + im(X,Y); - else if (theta == 4) - secDerivs(X,Y) = im(X + 2,Y) - 2*im(X + 1,Y) + im(X,Y); - } - } - //for each 2nd deriv that crosses a zero point and magnitude passes the upper threshold. - //Perform hysteresis in the direction of the gradient, rechecking the gradient - //angle for each pixel that meets the threshold requirement. Stop checking when - //the lower threshold is not reached. - CImg_5x5(I,float); - cimg_for5x5(secDerivs,X,Y,0,0,I,float) { - if ( (Ipp*Ibb < 0) || - (Ipc*Ibc < 0)|| - (Icp*Icb < 0) ) { - double Gr = std::sqrt(std::pow((double)gradients[0](X,Y),2.0) + std::pow((double)gradients[1](X,Y),2.0)); - int dir = GetAngle(Y,X); - int Xt = X, Yt = Y, delta_x = 0, delta_y=0; - double GRt = Gr; - if (Gr >= T2) - edges(X,Y) = 255; - //work along the gradient in one direction - if (doHysteresis) { - while ((Xt > 0) && (Xt < image_width - 1) && (Yt > 0) && (Yt < image_height - 1)) { - switch (dir){ - case 0 : delta_x=0;delta_y=1;break; - case 1 : delta_x=1;delta_y=1;break; - case 2 : delta_x=1;delta_y=0;break; - case 3 : delta_x=1;delta_y=-1;break; - case 4 : delta_x=0;delta_y=1;break; - } - Xt += delta_x; - Yt += delta_y; - GRt = std::sqrt(std::pow((double)gradients[0](Xt,Yt),2.0) + std::pow((double)gradients[1](Xt,Yt),2.0)); - dir = GetAngle(Yt,Xt); - if (GRt >= T1) - edges(Xt,Yt) = 255; - } - //work along gradient in other direction - Xt = X; Yt = Y; - while ((Xt > 0) && (Xt < image_width - 1) && (Yt > 0) && (Yt < image_height - 1)) { - switch (dir){ - case 0 : delta_x=0;delta_y=1;break; - case 1 : delta_x=1;delta_y=1;break; - case 2 : delta_x=1;delta_y=0;break; - case 3 : delta_x=1;delta_y=-1;break; - case 4 : delta_x=0;delta_y=1;break; - } - Xt -= delta_x; - Yt -= delta_y; - GRt = std::sqrt(std::pow((double)gradients[0](Xt,Yt),2.0) + std::pow((double)gradients[1](Xt,Yt),2.0)); - dir = GetAngle(Yt,Xt); - if (GRt >= T1) - edges(Xt,Yt) = 255; - } - } - } - } - return edges; -} -/** - * PURPOSE: perform radon transform of given image - * PARAM: CImg im - image to detect lines - * int N - number of angles to consider (should be a power of 2) - * (the values of N will be spread over 0 to 2PI) - * RETURN CImg - transform of given image of size, N x D - * D = rhomax = sqrt(dimx*dimx + dimy*dimy)/2 - **/ -CImg<> RadonTransform(CImg im,int N) { - int image_width = im.width(); - int image_height = im.height(); - - //calc offsets to center the image - float xofftemp = image_width/2.0f - 1; - float yofftemp = image_height/2.0f - 1; - int xoffset = (int)std::floor(xofftemp + ROUNDING_FACTOR(xofftemp)); - int yoffset = (int)std::floor(yofftemp + ROUNDING_FACTOR(yofftemp)); - float dtemp = (float)std::sqrt((double)(xoffset*xoffset + yoffset*yoffset)); - int D = (int)std::floor(dtemp + ROUNDING_FACTOR(dtemp)); - - CImg<> imRadon(N,D,1,1,0); - - //for each angle k to consider - for (int k= 0 ; k < N; k++) { - //only consider from PI/8 to 3PI/8 and 5PI/8 to 7PI/8 - //to avoid computational complexity of a steep angle - if (k == 0){k = N/8;continue;} - else if (k == (3*N/8 + 1)){ k = 5*N/8;continue;} - else if (k == 7*N/8 + 1){k = N; continue;} - - //for each rho length, determine linear equation and sum the line - //sum is to sum the values along the line at angle k2pi/N - //sum2 is to sum the values along the line at angle k2pi/N + N/4 - //The sum2 is performed merely by swapping the x,y axis as if the image were rotated 90 degrees. - for (int d=0; d < D; d++) { - double theta = 2*k*cimg::PI/N;//calculate actual theta - double alpha = std::tan(theta + cimg::PI/2);//calculate the slope - double beta_temp = -alpha*d*std::cos(theta) + d*std::sin(theta);//y-axis intercept for the line - int beta = (int)std::floor(beta_temp + ROUNDING_FACTOR(beta_temp)); - //for each value of m along x-axis, calculate y - //if the x,y location is within the boundary for the respective image orientations, add to the sum - unsigned int sum1 = 0, - sum2 = 0; - int M = (image_width >= image_height) ? image_width : image_height; - for (int m=0;m < M; m++) { - //interpolate in-between values using nearest-neighbor approximation - //using m,n as x,y indices into image - double n_temp = alpha*(m - xoffset) + beta; - int n = (int)std::floor(n_temp + ROUNDING_FACTOR(n_temp)); - if ((m < image_width) && (n + yoffset >= 0) && (n + yoffset < image_height)) - { - sum1 += im(m, n + yoffset); - } - n_temp = alpha*(m - yoffset) + beta; - n = (int)std::floor(n_temp + ROUNDING_FACTOR(n_temp)); - if ((m < image_height)&&(n + xoffset >= 0)&&(n + xoffset < image_width)) - { - sum2 += im(-(n + xoffset) + image_width - 1, m); - } - } - //assign the sums into the result matrix - imRadon(k,d) = (float)sum1; - //assign sum2 to angle position for theta + PI/4 - imRadon(((k + N/4)%N),d) = (float)sum2; - } - } - return imRadon; -} -/* references: - * 1. See Peter Toft's thesis on the Radon transform: http://petertoft.dk/PhD/index.html - * While I changed his basic algorithm, the main idea is still the same and provides an excellent explanation. - * - * */ diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/scene3d.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/scene3d.cpp deleted file mode 100644 index ba05293a1a2..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/scene3d.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - # - # File : scene3d.cpp - # ( C++ source file ) - # - # Description : A simple program that demonstrates the use of the - # 3D functions of CImg, in conjonction with the Board library. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -// Uncomment the line below to use the Board library. -// ( You will need to link your code with the board library object ). -// ( Get the Board Library at : http://libboard.sourceforge.net/ ) -//#define cimg_use_board - -#include "CImg.h" -using namespace cimg_library; -#ifndef cimg_imagepath -#define cimg_imagepath "img/" -#endif - -// Main procedure -//---------------- -int main() { - - // Define a simple 3D scene, composed of various basic objects (torus, cone, cube, ...) - //------------------------------------------------------------------------------------- - std::fprintf(stderr," - Create 3D Scene.\n"); - - // Define objects vertices and primitives. - CImgList cube_prims, cone_prims, torus_prims, sphere_prims, plane_prims, scene_prims; - const CImg - cube_pts = CImg<>::box3d(cube_prims,60,60,60).shift_object3d().shift_object3d(-50,50,0), - cone_pts = CImg<>::cone3d(cone_prims,30,40).shift_object3d().shift_object3d(50,50,0), - torus_pts = CImg<>::torus3d(torus_prims,30,10).shift_object3d().shift_object3d(-50,-50,0), - sphere_pts = CImg<>::sphere3d(sphere_prims,30).shift_object3d().shift_object3d(50,-50,0), - plane_pts = CImg<>::plane3d(plane_prims,200,200,20,20).shift_object3d().shift_object3d(0,0,40); - plane_prims.insert(plane_prims.get_reverse_object3d()); - - // Define objects colors and textures. - const CImgList - cone_cols = CImgList(cone_prims.size(),CImg::vector(128,63,255)), - torus_cols = CImgList(torus_prims.size(),CImg::vector(255,55,163)), - sphere_cols = CImgList(sphere_prims.size(),CImg::vector(115,115,63)), - plane_cols = CImgList(plane_prims.size(),CImg::vector(60,120,180)); - const CImg texture = CImg(cimg_imagepath "milla.bmp").resize(128,128); - CImgList cube_cols; - cimglist_for(cube_prims,p) { - cube_cols.insert(texture,~0U,true); - cube_prims[p].append(CImg::vector(0,0,127,0,127,127,0,127),'y'); - } - - // Define objects opacities. - const CImg - cube_opacs(cube_prims.size(),1,1,1,1.0f), - cone_opacs(cone_prims.size(),1,1,1,0.8f), - torus_opacs(torus_prims.size(),1,1,1,0.6f), - sphere_opacs(sphere_prims.size(),1,1,1,0.4f), - plane_opacs(plane_prims.size(),1,1,1,0.4f); - - // Append all object in a single 3D scene. - const CImg scene_pts = CImg(). - append_object3d(scene_prims,cube_pts,cube_prims). - append_object3d(scene_prims,cone_pts,cone_prims). - append_object3d(scene_prims,torus_pts,torus_prims). - append_object3d(scene_prims,sphere_pts,sphere_prims). - append_object3d(scene_prims,plane_pts,plane_prims); - const CImgList scene_cols = (+cube_cols,cone_cols,torus_cols,sphere_cols,plane_cols); - const CImg scene_opacs = (cube_opacs,cone_opacs,torus_opacs,sphere_opacs,plane_opacs)>'x'; - - // Display object3D in a user-interacted window and get final position matrix. - std::fprintf(stderr," - Display 3D Scene.\n"); - const CImg visu = CImg(3,512,512,1).fill(230,230,255).permute_axes("yzcx"); - CImg view_matrix = CImg<>::identity_matrix(4); - visu.display_object3d("3D Scene",scene_pts,scene_prims,scene_cols,scene_opacs,true,4,4,false, - 500.0f,0,0,-5000,0.5f,0.1f,true,view_matrix.data()); - - // Save object 3D as OFF file. - std::fprintf(stderr," - Save .OFF 3D object file.\n"); - scene_pts.save_off(scene_prims,scene_cols,"output.off"); - - // Save 3D view in SVG, EPS and FIG files. - // (using the Board library : http://libboard.sourceforge.net/ ). -#ifdef cimg_use_board - - // Define a Board instance - LibBoard::Board B; - - // Set Background color of the board. - B.clear(230,230,255); - - // Draw object both in 'visu' and in the board. - (view_matrix.crop(0,0,2,2))*=2; - (+visu).draw_object3d(B,visu.width()/2,visu.height()/2,visu.depth()/2, - view_matrix*scene_pts,scene_prims,scene_cols,scene_opacs,3). - display("Snapshot for Board"); - - // Save board into a vector graphics file format. - std::fprintf(stderr," - Save .SVG, .EPS and .FIG snapshots\n"); - B.save("output.svg"); - B.save("output.eps"); - B.save("output.fig"); -#endif - - // Exit. - std::fprintf(stderr," - Exit.\n"); - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/spherical_function3d.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/spherical_function3d.cpp deleted file mode 100644 index c4febcf00e4..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/spherical_function3d.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - # - # File : spherical_function3d.cpp - # ( C++ source file ) - # - # Description : An example that shows how to build custom 3D objects in CImg. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#include "CImg.h" -using namespace cimg_library; - -/*--------------------------- - - Main procedure - - --------------------------*/ -int main() { - - CImgList object_colors; - CImgList object_opacities; - - // Define a 3D centered box. - CImg object_vertices = CImg(3,8,1,1, // Define the 8 vertices of the cube. - -1,-1,-1, // (x0,y0,z0) - 1,-1,-1, // (x1,y1,z1) - 1,1,-1, // ... - -1,1,-1, - -1,-1,1, - 1,-1,1, - 1,1,1, // (x6,y6,z6) - -1,1,1).transpose(); // (x7,y7,z7) - CImgList object_primitives(12,1,2,1,1, // Define the 12 segments of the cube. - 0,1, 1,2, 2,3, 3,0, - 4,5, 5,6, 6,7, 7,4, - 0,4, 1,5, 2,6, 3,7); - object_colors.insert(object_primitives.size(),CImg::vector(32,64,255)); - object_opacities.insert(object_primitives.size(),CImg::vector(0.3f)); - - // Define the spherical function's vertices. - CImgList spherical_vertices; - const float a = 1; - const unsigned int na = 132, nb = 132; - for (unsigned int v = 0; v::vector(altitude*x,altitude*y,altitude*z)); - } - - // Define the spherical function's mesh. - CImgList spherical_primitives; - for (unsigned int vv = 0; vv::vector(nb*vv + nu,nb*nv + uu,nb*vv + uu)); - spherical_primitives.insert(CImg::vector(nb*vv + nu,nb*nv + nu,nb*nv + uu)); - object_colors.insert(CImg<>::vector(0,255,255)); - object_colors.insert(CImg<>::vector(100,200,255)); - object_opacities.insert(2,CImg<>::vector(1)); - } - - // Merge 3D objects together. - object_vertices.append_object3d(object_primitives,spherical_vertices>'x',spherical_primitives); - char title[4096] = { 0 }; - std::sprintf(title,"3D Spherical Function (%u vertices, %u primitives)", - object_vertices.width(),object_primitives.size()); - CImgDisplay disp(640,480,title,0); - CImg(disp.width(),disp.height(),1,3,220). - display_object3d(disp,object_vertices,object_primitives,object_colors,object_opacities,true,4,3,false, - 500,0,0,-5000,0.1f,1.5f); - - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/tetris.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/tetris.cpp deleted file mode 100644 index 3d39089c3f5..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/tetris.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/* - # - # File : tetris.cpp - # ( C++ source file ) - # - # Description : A CImg version of the famous Tetris game. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#include "img/tetris.h" -#include "CImg.h" -using namespace cimg_library; - -// Main procedure -//---------------- -int main(int argc,char **argv) { - - // Read command line argument (if any) - cimg_usage("An implementation of the well known 'Tetris' game with CImg."); - unsigned int - blocdim = cimg_option("-blocdim",18,"Sprite bloc size"), - speed = cimg_option("-speed",20,"Initial speed"), - level = cimg_option("-level",0,"Level"); - const char *geometry = cimg_option("-g","12x20","Size of the board"); - unsigned int bwidth = 12,bheight = 20; - std::sscanf(geometry,"%u%*c%u",&bwidth,&bheight); - - const CImg dlogo = CImg(data_logo,128,96,1,3,true); - if (cimg::dialog("CImg Tetris", - "Welcome to the CImg version of Tetris.\n" - "( by David Tschumperle )\n\n" - "Press 'Start' when you are ready to play !","Start","Quit",0,0,0,0,dlogo,true)) std::exit(0); - - // Create sprite, background graphics and initial board data - const CImgList pieces = CImgList(). - insert(CImg(3,2).fill(1,1,1,0,0,1)). - insert(CImg(3,2).fill(2,2,2,2,0,0)). - insert(CImg(2,2).fill(3,3,3,3)). - insert(CImg(4,1).fill(4,4,4,4)). - insert(CImg(3,2).fill(5,5,0,0,5,5)). - insert(CImg(3,2).fill(0,6,6,6,6,0)). - insert(CImg(3,3).fill(0,7,0,7,7,7,0,7,0)). - insert(CImg(2,1).fill(8,8)). - insert(CImg(3,2).fill(9,9,9,0,9,0)). - insert(CImg(2,2).fill(10,10,0,10)). - insert(CImg(3,1).fill(11,11,11)); - - CImg board(bwidth,bheight,1,1,0), background(board.width()*blocdim,board.height()*blocdim,1,3,0); - (background.noise(30).draw_plasma().noise(30).deriche(5,0,'y').shift(0,-background.height()/2,0,0,2). - deriche(5,0,'y'))/=1.5f; - if (level) (board.get_shared_rows(board.height() - level,board.height() - 1,0,0).noise(100))%=pieces.size() + 1; - - // Create a set of small gradient-colored blocs used to draw the pieces. - CImgList blocs(pieces.size(),blocdim,blocdim,1,3); - cimglist_for(blocs,l) { - CImg color = CImg(3,1,1,1,128).noise(127,1).cut(120,255); - float val; - cimg_forXYC(blocs[l],x,y,k) - blocs[l](x,y,k) = (unsigned char)((val=(color[k]*0.7f*(x + y + 5)/blocdim))>255?255:val); - blocs[l].draw_line(0,0,0,blocdim - 1,(color>>1).data()). - draw_line(0,blocdim - 1,blocdim - 1,blocdim - 1,(color>>1).data()); - color = (CImg(color)*=2).cut(0,255); - blocs[l].draw_line(0,0,(int)blocdim - 1,0,color.data()). - draw_line(blocdim - 1,0,blocdim - 1,blocdim - 1,color.data()); - } - - // Initialize window display and enter the main event loop - CImgDisplay disp(background,"CImg Tetris",0,false,true); - disp.move((CImgDisplay::screen_width() - disp.width())/2, - (CImgDisplay::screen_height() - disp.height())/2).hide_mouse(); - const unsigned char white[3]={ 255, 255, 255 }; - CImg visu, nboard, piece, next, next_mask; - int cx = -1, cy = -1, cn = -1, nn = rand()%pieces.size(), time = 0, score = 0; - bool gameover = false, pause = false; - - while (!gameover && !disp.is_closed() && !disp.is_keyESC() && !disp.is_keyQ()) { - - if (!pause) { - - // Draw the board on the display window. - nboard = board; visu = background; - if (cx>=0 && cy>=0) - cimg_forXY(piece,x,y) if (piece(x,y)) nboard(cx - piece.width()/2 + x,cy - piece.height()/2 + y)=piece(x,y); - cimg_forXY(board,xx,yy) if (nboard(xx,yy)) visu.draw_image(xx*blocdim,yy*blocdim,blocs[nboard(xx,yy) - 1]); - visu.draw_text(5,5,"Lines : %d",white,0,1,13,score,nn).draw_text(visu.width() - 75,5,"Next :",white,0,1,13); - if (next) visu.draw_image(visu.width() - next.width() - 2,10 - next.height()/2,next,next_mask). - display(disp.wait(20)); - - if (cn<0) { - - // Introduce a new piece on the board (if necessary) and create representation of the next piece - board = nboard; - piece = pieces[cn=nn]; - nn = rand()%pieces.size(); - cx = board.width()/2; - cy = piece.height()/2; - next = CImg(pieces[nn].width()*blocdim,pieces[nn].height()*blocdim,1,3,0); - cimg_forXY(pieces[nn],xi,yi) - if (pieces[nn](xi,yi)) next.draw_image(xi*blocdim,yi*blocdim,blocs[pieces[nn](xi,yi) - 1]); - next_mask = next.resize(-50,-50).get_norm().threshold(0); - - // Detect tetris lines and do line removal animation if found. - cimg_forY(board,yyy) { - int Y = yyy*blocdim, line = 1; - cimg_forX(board,xxx) if (!board(xxx,yyy)) line=0; - if (line) { - board.draw_image(0,1,board.get_crop(0,0,board.width() - 1,yyy - 1)); - if (!((++score)%1) && speed>1) --speed; - for (float alpha=0; alpha<=1; alpha+=0.07f) - CImg(visu).draw_image(0,Y,background.get_crop(0,Y,visu.width() - 1, - Y + blocdim - 1),alpha). - display(disp.wait(20)); - visu.draw_image(0,Y,background.get_crop(0,Y,visu.width() - 1,Y + blocdim - 1)); - } - } - } - - // Handle motion & collisions - const int ox = cx, oy = cy; - bool rotated = false, collision; - switch (disp.key()) { - case cimg::keyP: pause = true; break; - case cimg::keyARROWUP: piece.rotate(90); rotated = true; disp.set_key(); break; - case cimg::keyARROWLEFT: --cx; disp.set_key(); break; - case cimg::keyARROWRIGHT: ++cx; disp.set_key(); break; - } - if (cx - piece.width()/2<0) cx = piece.width()/2; - if (cy - piece.height()/2<0) cy = piece.height()/2; - if (cx + (piece.width() - 1)/2>=board.width()) cx = board.width() - 1 - (piece.width() - 1)/2; - - // Detect collision along the X axis - collision = false; - cimg_forXY(piece,i,j) - if (piece(i,j) && board(cx - piece.width()/2 + i,cy - piece.height()/2 + j)) collision = true; - if (collision) { cx=ox; if (rotated) piece.rotate(-90); } - - if (disp.key()==cimg::keyARROWDOWN || !((++time)%speed)) { ++cy; disp.set_key(); } - // Detect collisiong along the Y axis - collision = false; - cimg_forXY(piece,ii,jj) - if (piece(ii,jj) && (cy - piece.height()/2 + jj>=board.height() || - board(cx - piece.width()/2 + ii,cy - piece.height()/2 + jj))) collision = true; - if (collision || cy + (piece.height() - 1)/2>=board.height()) { cy = oy; cn = -1; } - if (collision && cy==piece.height()/2) gameover = true; - } else { - - // If game is paused (key 'P'), do a little text animation - float A = 0, B = 0; - CImg pauselogo = CImg().draw_text(0,0,"Game Paused\nPress a key",white); - disp.set_key(); while (!disp.is_closed() && !disp.key()) { - const CImg pauserotated = pauselogo.get_rotate((float)(30*std::sin(A)),1,0). - resize((int)(-150 - 80*std::sin(B)),(int)(-150 - 80*std::sin(B))); - A+=0.08f; B+=0.043f; - CImg(background). - draw_image((background.width() - pauserotated.width())/2, - (background.height() - pauserotated.height())/2, - pauserotated.get_resize(-100,-100,1,3,2),pauserotated,1,255).display(disp.wait(20)); - if (disp.is_resized()) disp.resize(); - } - disp.set_key(); - pause = false; - } - background.shift(0,-20/(int)speed,0,0,2); - if (disp.is_resized()) disp.resize(); - } - - // End of game reached, display the score and do a 'game over' animation - cimg_forXYC(visu,x,y,k) if (x%2 || y%2) visu(x,y,k) = 0; - visu.display(disp); - char tmp[1024]; - std::sprintf(tmp,"Game Over !\n\nYour score : %d",score); - cimg::dialog("CImg Tetris",tmp,"Quit"); - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/tron.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/tron.cpp deleted file mode 100644 index 4d5ee464346..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/tron.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* - # - # File : tron.cpp - # ( C++ source file ) - # - # Description : A clone of the famous (and very simple) Tron game. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#include "CImg.h" -using namespace cimg_library; - -// Main procedure -//---------------- -int main(int argc, char **argv) { - - // Print usage, help and retrieve command line options - //----------------------------------------------------- - cimg_usage("A very simple Tron game, using the CImg Library"); - cimg_help("--- Quick help ----------------------------\n" - " Player 1 (blue) :\n" - " Use keys 'Z' (up), 'S' (down), 'Q' (left)\n" - " and 'D' (right) to control your player.\n" - " Right 'CONTROL' key enables turbospeed\n" - " Player 2 (red) : \n" - " Use arrow keys to control your player.\n" - " 'TAB' key enables turbospeed.\n" - "-------------------------------------------"); - - const char *geom = cimg_option("-g","300x300","Size of the game board"); - const int delay = cimg_option("-s",10,"Game speed (lower value means faster)"); - const bool twoplayers = !cimg_option("-1",false,"One player only"); - const int zoom = cimg_option("-z",1,"Zoom factor"); - const bool full = cimg_option("-f",false,"Fullscreen mode"); - unsigned int W = 400, H = 400; - std::sscanf(geom,"%u%*c%u",&W,&H); - - // Define game colors and variables - //---------------------------------- - const unsigned char blue[] = { 128,200,255}, red[] = { 255,0,0 }, white[] = { 255,255,255 }; - int score1 = 0, score2 = 0, round_over = 0, ix1 = -1, iy1 = -1, x1 = 0, y1 = 0, u1 = 0, v1 = 0, - ix2 = -1, iy2 = -1, x2 = 0, y2 = 0, u2 = 0, v2 = 0; - bool start_round = true, turbo1 = false, turbo2 = false; - - // Create background image - //-------------------------- - CImg background, img; - background.assign(64,64,1,3,0).noise(60).draw_plasma().resize(W,H).blur(2).normalize(0,128). - draw_rectangle(0,0,W-1,H-1,white,1.0f,~0U); - - // Open display window - //--------------------- - CImgDisplay disp(background,"* CImg-Tron *"); - if (zoom>1) disp.resize(-100*zoom,-100*zoom); - if (full) disp.toggle_fullscreen().display(background); - - // Start main game loop - //---------------------- - while (!disp.is_closed() && !disp.is_keyESC()) { - - // Init new game round if necessary - //---------------------------------- - if (start_round) { - - // Init game variables - round_over = 0; - ix1 = -1; iy1 = -1; x1 = 10; y1 = 10; u1 = 1; v1 = 0; turbo1 = false; - ix2 = -1; iy2 = -1; x2 = W - 11; y2 = H - 11; u2 = -1; v2 = 0; turbo2 = false; - img = background; - start_round = false; - - // Display a simple pre-round page - CImg logo, pressakey; - logo.draw_text(0,0," CImg-Tron ",white,0,1,33).resize(-100,-100,1,3); - CImg tmp = (+background).draw_image((W - logo.width())/2,(H - logo.height())/2 - 20, - logo,logo.get_channel(0).dilate(6).normalize(0,1)). - draw_text(W/2 - 60,H/2 + 10,"Blue ( %u )",blue,0,1,13,score1). - draw_text(W/2 + 10,H/2 + 10,"Red ( %u )",red,0,1,13,score2); - pressakey.draw_text(0,0,"* Press a key to start round *",white); - for (float i = 0; i<1; i+=0.05f) ((+tmp)*=i).display(disp.wait(20)); - disp.flush(); - for (unsigned long t = 0; !disp.key() && !disp.is_closed(); ++t) { - if (!(t%10)) { if (t%20) disp.display(tmp); - else disp.display((+tmp).draw_image(W/2 - 70,H/2 + 50,pressakey,pressakey,1,255)); } - if (disp.wait(20).is_resized()) disp.resize(disp); - } - if (disp.is_keyESC()) disp.flush(); - } - - // Test collision between players and borders - if (x1<0 || x1>=img.width() || y1<0 || y1>=img.height() || - img(x1,y1,0)!=background(x1,y1,0) || - img(x1,y1,1)!=background(x1,y1,1) || - img(x1,y1,2)!=background(x1,y1,2) || - ((ix1>=0 || iy1>=0) && (img(ix1,iy1,0)!=background(ix1,iy1,0) || // Collision test for turbo mode - img(ix1,iy1,1)!=background(ix1,iy1,1) || - img(ix1,iy1,2)!=background(ix1,iy1,2)))) { round_over=1; score2++; } - if (twoplayers) { - if (x2<0 || x2>=img.width() || y2<0 || y2>=img.height() || - img(x2,y2,0)!=background(x2,y2,0) || - img(x2,y2,1)!=background(x2,y2,1) || - img(x2,y2,2)!=background(x2,y2,2) || - ((ix2>=0 || iy2>=0) && (img(ix2,iy2,0)!=background(ix2,iy2,0) || // Collision test for turbo mode - img(ix2,iy2,1)!=background(ix2,iy2,1) || - img(ix2,iy2,2)!=background(ix2,iy2,2)))) { round_over=2; score1++; } - } - - // Draw new players positions - img.draw_point(x1,y1,blue); - if (ix1>=0 && iy1>=0) img.draw_point(ix1,iy1,blue); - if (twoplayers) { - img.draw_point(x2,y2,red); - if (ix2>=0 && iy2>=0) img.draw_point(ix2,iy2,red); - } - if (disp.is_resized()) disp.resize(disp); - img.display(disp); - - // Update players positions - x1+=u1; y1+=v1; - if (turbo1) { ix1 = x1; iy1 = y1; x1+=u1; y1+=v1; } else { ix1 = iy1 = -1; } - if (twoplayers) { - x2+=u2; y2+=v2; - if (turbo2) { ix2 = x2; iy2 = y2; x2+=u2; y2+=v2; } else { ix2 = iy2 = -1; } - } - - // Test keyboard events - int nu1 = u1, nv1 = v1, nu2 = u2, nv2 = v2; - if (disp.is_keyARROWLEFT()) { nu1 = -1; nv1 = 0; } - if (disp.is_keyARROWRIGHT()) { nu1 = 1; nv1 = 0; } - if (disp.is_keyARROWUP()) { nu1 = 0; nv1 = -1; } - if (disp.is_keyARROWDOWN()) { nu1 = 0; nv1 = 1; } - turbo1 = disp.is_keyCTRLRIGHT(); - if (twoplayers) { - if (disp.is_keyQ()) { nu2 = -1; nv2 = 0; } - if (disp.is_keyD()) { nu2 = 1; nv2 = 0; } - if (disp.is_keyZ()) { nu2 = 0; nv2 = -1; } - if (disp.is_keyS()) { nu2 = 0; nv2 = 1; } - turbo2 = disp.is_keyTAB(); - } - if (nu1!=-u1 && nv1!=-v1) { u1 = nu1; v1 = nv1; } - if (nu2!=-u2 && nv2!=-v2) { u2 = nu2; v2 = nv2; } - - // Check if round is over. - if (round_over) { - const int xc = round_over==1?x1:x2, yc = round_over==1?y1:y2; - for (int r=0; r<50; r+=3) img.draw_circle(xc,yc,r,round_over==1?blue:red,r/300.0f).display(disp.wait(20)); - for (int rr=0; rr<50; rr+=3) - ((+img)*=(50 - rr)/50.0f).draw_circle(xc,yc,(50 + rr),round_over==1?blue:red,1/6.0f).display(disp.wait(20)); - start_round = true; - } - - // Wait a small amount of time - disp.wait(delay); - } - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/tutorial.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/tutorial.cpp deleted file mode 100644 index e07433c7eb2..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/tutorial.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - # - # File : tutorial.cpp - # ( C++ source file ) - # - # Description : View the color profile of an image, along the X-axis. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -// Include CImg library file and use its main namespace -#include "CImg.h" -using namespace cimg_library; - -#ifndef cimg_imagepath -#define cimg_imagepath "img/" -#endif - -// Main procedure -//---------------- -int main(int argc,char **argv) { - - // Define program usage and read command line parameters - //------------------------------------------------------- - - // Display program usage, when invoked from the command line with option '-h'. - cimg_usage("View the color profile of an image along the X axis"); - - // Read image filename from the command line (or set it to "img/parrot.ppm" if option '-i' is not provided). - const char* file_i = cimg_option("-i",cimg_imagepath "parrot.ppm","Input image"); - - // Read pre-blurring variance from the command line (or set it to 1.0 if option '-blur' is not provided). - const double sigma = cimg_option("-blur",1.0,"Variance of gaussian pre-blurring"); - - // Init variables - //---------------- - - // Load an image, transform it to a color image (if necessary) and blur it with the standard deviation sigma. - const CImg image = CImg<>(file_i).normalize(0,255).blur((float)sigma).resize(-100,-100,1,3); - - // Create two display window, one for the image, the other for the color profile. - CImgDisplay - main_disp(image,"Color image (Try to move mouse pointer over)",0), - draw_disp(500,400,"Color profile of the X-axis",0); - - // Define colors used to plot the profile, and a hatch to draw the vertical line - unsigned int hatch = 0xF0F0F0F0; - const unsigned char - red[] = { 255,0,0 }, - green[] = { 0,255,0 }, - blue [] = { 0,0,255 }, - black[] = { 0,0,0 }; - - // Enter event loop. This loop ends when one of the two display window is closed or - // when the keys 'ESC' or 'Q' are pressed. - while (!main_disp.is_closed() && !draw_disp.is_closed() && - !main_disp.is_keyESC() && !draw_disp.is_keyESC() && !main_disp.is_keyQ() && !draw_disp.is_keyQ()) { - - // Handle display window resizing (if any) - if (main_disp.is_resized()) main_disp.resize().display(image); - draw_disp.resize(); - - if (main_disp.mouse_x()>=0 && main_disp.mouse_y()>=0) { // Mouse pointer is over the image - - const int - xm = main_disp.mouse_x(), // X-coordinate of the mouse pointer over the image - ym = main_disp.mouse_y(), // Y-coordinate of the mouse pointer over the image - xl = xm*draw_disp.width()/main_disp.width(), // Corresponding X-coordinate of the hatched line - x = xm*image.width()/main_disp.width(), // Corresponding X-coordinate of the pointed pixel in the image - y = ym*image.height()/main_disp.height(); // Corresponding Y-coordinate of the pointex pixel in the image - - // Retrieve color component values at pixel (x,y) - const unsigned int - val_red = image(x,y,0), - val_green = image(x,y,1), - val_blue = image(x,y,2); - - // Create and display the image of the intensity profile - CImg(draw_disp.width(),draw_disp.height(),1,3,255). - draw_grid(-50*100.0f/image.width(),-50*100.0f/256,0,0,false,true,black,0.2f,0xCCCCCCCC,0xCCCCCCCC). - draw_axes(0,image.width() - 1.0f,255.0f,0.0f,black). - draw_graph(image.get_shared_row(y,0,0),red,1,1,0,255,1). - draw_graph(image.get_shared_row(y,0,1),green,1,1,0,255,1). - draw_graph(image.get_shared_row(y,0,2),blue,1,1,0,255,1). - draw_text(30,5,"Pixel (%d,%d)={%d %d %d}",black,0,1,16, - main_disp.mouse_x(),main_disp.mouse_y(),val_red,val_green,val_blue). - draw_line(xl,0,xl,draw_disp.height() - 1,black,0.5f,hatch=cimg::rol(hatch)). - display(draw_disp); - } else - // else display a text in the profile display window. - CImg(draw_disp.width(),draw_disp.height()).fill(255). - draw_text(draw_disp.width()/2 - 130,draw_disp.height()/2 - 5,"Mouse pointer is outside the image", - black,0,1,16).display(draw_disp); - - // Temporize event loop - cimg::wait(20); - } - - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_RGBclass.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_RGBclass.cpp deleted file mode 100644 index 72dd92b6c4c..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_RGBclass.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - # - # File : use_RGBclass.cpp - # ( C++ source file ) - # - # Description : A small code that shows how to write a CImg plugin to - # handle color image manipulation using a user-defined RGB - # class, instead of using classical pixel access of CImg - # with operator(). - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#ifndef cimg_plugin -#define cimg_plugin "examples/use_RGBclass.cpp" // Path of the plugin is relative to the CImg.h file. -#include "CImg.h" -using namespace cimg_library; -#ifndef cimg_imagepath -#define cimg_imagepath "img/" -#endif - -// Main procedure -//---------------- -int main() { - - // Load images. - CImg img1(cimg_imagepath "milla.bmp"); - const CImg img2 = CImg(cimg_imagepath "parrot.ppm").resize(img1,3); - const float default_color[] = { 30,30,80 }; - - // Modify 'img1' using the RGB pixel accessor. - cimg_forXY(img1,x,y) - if (!((x*y)%31)) img1.RGB_at(x,y) = default_color; - else if ((x+y)%2) img1.RGB_at(x,y) = img2.RGB_at(x,y); - img1.display(); - - // Quit. - return 0; -} - -#else - -//------------------------- -// Start of the plugin code -//------------------------- - -// Define a simple structure of *references* to R,G,B values. -//----------------------------------------------------------- -// (Feel free to add your own operators in there !) -struct st_RGB { - T _R,_G,_B,&R,&G,&B; - - // Construct from R,G,B references of values. - st_RGB(const T& nR, const T& nG, const T& nB):_R(nR),_G(nG),_B(nB),R(_R),G(_G),B(_B) {} - st_RGB(T& nR, T& nG, T& nB):R(nR),G(nG),B(nB) {} - - // Copy constructors. - st_RGB(const st_RGB& rgb):_R(rgb.R),_G(rgb.G),_B(rgb.B),R(_R),G(_G),B(_B) {} - template - st_RGB(const t& rgb):_R(rgb[0]),_G(rgb[1]),_B(rgb[2]) {} - - // Assignement operator. - st_RGB& operator=(const st_RGB& rgb) { - R = (T)(rgb[0]); G = (T)(rgb[1]); B = (T)(rgb[2]); - return *this; - } - template - st_RGB& operator=(const t& rgb) { - R = (T)(rgb[0]); G = (T)(rgb[1]); B = (T)(rgb[2]); - return *this; - } - - // Data (R,G or B) access operator. - const T& operator[](const unsigned int i) const { - return i==2?B:(i==1?G:R); - } - T& operator[](const unsigned int i) { - return i==2?B:(i==1?G:R); - } - - // Print instance on the standard error. - const st_RGB& print() const { - std::fprintf(stderr,"{ %d %d %d }\n",(int)R,(int)G,(int)B); - return *this; - } -}; - -// Define CImg member functions which return pixel values as st_RGB instances. -//-------------------------------------------------------------------------------- -const st_RGB RGB_at(const int x, const int y=0, const int z=0) const { - const int whz = width()*height()*depth(); - const T *const pR = data() + x + y*width() + z*width()*height(), *const pG = pR + whz, *const pB = pG + whz; - return st_RGB(*pR,*pG,*pB); -} - -st_RGB RGB_at(const int x, const int y=0, const int z=0) { - const int whz = width()*height()*depth(); - T *const pR = data() + x + y*width() + z*width()*height(), *const pG = pR + whz, *const pB = pG + whz; - return st_RGB(*pR,*pG,*pB); -} - -//------------------------ -// End of the plugin code -//------------------------ -#endif diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_chlpca.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_chlpca.cpp deleted file mode 100644 index 6b769d06a70..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_chlpca.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - # - # File : use_chlpca.cpp - # ( C++ source file ) - # - # Description : Example of use for the CImg plugin 'plugins/chlpca.h'. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : Jerome Boulanger - # ( http://www.irisa.fr/vista/Equipe/People/Jerome.Boulanger.html ) - # - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#define cimg_plugin "plugins/chlpca.h" -#include "CImg.h" -using namespace cimg_library; -#ifndef cimg_imagepath -#define cimg_imagepath "img/" -#endif - -// Main procedure -//---------------- -int main(int argc,char **argv) { - cimg_usage("Patch based denoising "); - const char *file_i = cimg_option("-i",cimg_imagepath "milla.bmp","Input image"); - const int p = cimg_option("-p",3,"patch radius"); - const int w = cimg_option("-w",10,"window radius"); - const float lambda_min = cimg_option("-l",(float)2.f,"component selection threshold"); - const int nstep = cimg_option("-nstep",5,"sub-sampling"); - const float nsim = cimg_option("-nsim",(float)5.f,"dictionnary size a multiple of the patch size"); - const float noise_std = cimg_option("-sigma",(float)-1.f,"noise std (-1:estimated)"); - const bool use_svd = cimg_option("-svd",(float)-1.f,"use svd for computing PCA"); - const char *file_o = cimg_option("-o",(char*)NULL,"Output file"); - CImg<> img(file_i); - img = img.get_chlpca(p, w, nstep, nsim, lambda_min, noise_std, use_svd); - img.display(); - if (file_o) img.save(file_o); - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_cimgIPL.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_cimgIPL.cpp deleted file mode 100644 index 72d4e12052b..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_cimgIPL.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* -# -# File : use_cimgIPL.cpp -# ( C++ source file ) -# -# Description : Example of use for the CImg plugin 'plugins/cimgIPL.h'. -# This file is a part of the CImg Library project. -# ( http://cimg.eu ) -# -# Copyright : newleft (haibo.zheng@gmail.com) -# newleftist@hotmail.com -# -# License : CeCILL v2.0 -# ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) -# -# This software is governed by the CeCILL license under French law and -# abiding by the rules of distribution of free software. You can use, -# modify and/ or redistribute the software under the terms of the CeCILL -# license as circulated by CEA, CNRS and INRIA at the following URL -# "http://www.cecill.info". -# -# As a counterpart to the access to the source code and rights to copy, -# modify and redistribute granted by the license, users are provided only -# with a limited warranty and the software's author, the holder of the -# economic rights, and the successive licensors have only limited -# liability. -# -# In this respect, the user's attention is drawn to the risks associated -# with loading, using, modifying and/or developing or reproducing the -# software by the user in light of its specific status of free software, -# that may mean that it is complicated to manipulate, and that also -# therefore means that it is reserved for developers and experienced -# professionals having in-depth computer knowledge. Users are therefore -# encouraged to load and test the software's suitability as regards their -# requirements in conditions enabling the security of their systems and/or -# data to be ensured and, more generally, to use and operate it in the -# same conditions as regards security. -# -# The fact that you are presently reading this means that you have had -# knowledge of the CeCILL license and that you accept its terms. -# -*/ - -#include -#include -#include - -#pragma comment(lib, "cv.lib") -#pragma comment(lib, "cvaux.lib") -#pragma comment(lib, "cxcore.lib") -#pragma comment(lib, "highgui.lib") - -#define cimg_plugin1 "plugins\cimgIPL.h" -#include "CImg.h" -using namespace cimg_library; - -// Main procedure -//---------------- -int main(int argc, char* argv[]) { - int wid = 0; - CImg<> cImg(argv[1]); - cImg.display("cImg"); - IplImage* ipl; - //ipl = cvLoadImage(argv[1], -1); - ipl = cImg.get_IPL(); - - IplImage *ipl8; - IplImage *ipl16, *ipl32, *ipl64; - IplImage *ipl16to8, *ipl32to8, *ipl64to8; - cvNamedWindow("origin", wid++); - cvNamedWindow("8bit_OK", wid++); - cvNamedWindow("16bit", wid++); - cvNamedWindow("32bit", wid++); - cvNamedWindow("64bit", wid++); - cvNamedWindow("16bitto8", wid++); - cvNamedWindow("32bitto8", wid++); - cvNamedWindow("64bitto8", wid++); - - cvShowImage("origin", ipl); - - ipl8 = cvCreateImage(cvGetSize(ipl), IPL_DEPTH_8U, ipl->nChannels); - cvConvert(ipl, ipl8); - - ipl16 = cvCreateImage(cvGetSize(ipl), IPL_DEPTH_16U, ipl->nChannels); - cvConvert(ipl, ipl16); - - ipl32 = cvCreateImage(cvGetSize(ipl), IPL_DEPTH_32F, ipl->nChannels); - cvConvert(ipl, ipl32); - - ipl64 = cvCreateImage(cvGetSize(ipl), IPL_DEPTH_64F, ipl->nChannels); - cvConvert(ipl, ipl64); - - cvShowImage("8bit_OK", ipl8);// this canbe show properly - cvShowImage("16bit", ipl16);// maynot display properly, that's bug of cvShowImage - cvShowImage("32bit", ipl32);// maynot display properly, that's bug of cvShowImage - cvShowImage("64bit", ipl64);// maynot display properly, that's bug of cvShowImage - - // cvShowImage can only display IplImage with IPL_DEPTH_8X, proved by the following codes - ipl16to8 = cvCreateImage(cvGetSize(ipl16), IPL_DEPTH_8U, ipl16->nChannels); - cvConvert(ipl16, ipl16to8); - ipl32to8 = cvCreateImage(cvGetSize(ipl32), IPL_DEPTH_8U, ipl32->nChannels); - cvConvert(ipl32, ipl32to8); - ipl64to8 = cvCreateImage(cvGetSize(ipl64), IPL_DEPTH_8U, ipl64->nChannels); - cvConvert(ipl64, ipl64to8); - cvShowImage("16bitto8", ipl16to8); // diplay ok - cvShowImage("32bitto8", ipl32to8); // diplay ok - cvShowImage("64bitto8", ipl64to8); // diplay ok - - // now, we test ipl8->cImg, ipl16->cImg, ipl32->cImg, ipl64->cImg - cImg.assign(ipl8); - cImg.display("ipl8->cimg"); - cImg.assign(ipl16); - cImg.display("ipl16->cimg"); - cImg.assign(ipl32); - cImg.display("ipl32->cimg"); - cImg.assign(ipl64); - cImg.display("ipl64->cimg"); - - cvWaitKey(0); - - // test another construct - CImg testCImg1(ipl16); - testCImg1.display("testCImg1"); - CImg testCImg2(ipl32); - testCImg2.display("testCImg2"); - CImg testCImg3(ipl64); - testCImg3.display("testCImg3"); - - CImg testCImg4(ipl16); - testCImg4.display("testCImg4"); - CImg testCImg5(ipl32); - testCImg5.display("testCImg5"); - CImg testCImg6(ipl64); - testCImg6.display("testCImg6"); - - cvReleaseImage(&ipl); - cvReleaseImage(&ipl8); - cvReleaseImage(&ipl16); - cvReleaseImage(&ipl32); - cvReleaseImage(&ipl64); - cvReleaseImage(&ipl16to8); - cvReleaseImage(&ipl32to8); - cvReleaseImage(&ipl64to8); - - cvDestroyWindow("origin"); - cvDestroyWindow("8bit_OK"); - cvDestroyWindow("16bit"); - cvDestroyWindow("32bit"); - cvDestroyWindow("64bit"); - cvDestroyWindow("16bitto8"); - cvDestroyWindow("32bitto8"); - cvDestroyWindow("64bitto8"); - - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_cimgmatlab.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_cimgmatlab.cpp deleted file mode 100644 index 08c06777d09..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_cimgmatlab.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/*----------------------------------------------------------------------- - - File : use_cimgmatlab.cpp - - Description: Example of use for the CImg plugin 'plugins/cimgmatlab.h' - which allows to use CImg in order to develop matlab external - functions (mex functions). - User should be familiar with Matlab C/C++ mex function concepts, - as this file is by no way a mex programming tutorial. - - This simple example implements a mex function that can be called - as - - - v = cimgmatlab_cannyderiche(u,s) - - v = cimgmatlab_cannyderiche(u,sx,sy) - - v = cimgmatlab_cannyderiche(u,sx,sy,sz) - - The corresponding m-file is cimgmatlab_cannyderiche.m - - - Copyright : Francois Lauze - http://www.itu.dk/people/francois - This software is governed by the Gnu Lesser General Public License - see http://www.gnu.org/copyleft/lgpl.html - - The plugin home page is at - http://www.itu.dk/people/francois/cimgmatlab.html - - for the compilation: using the mex utility provided with matlab, just - remember to add the -I flags with paths to CImg.h and/or cimgmatlab.h. - The default lcc cannot be used, it is a C compiler and not a C++ one! - ---------------------------------------------------------------------------*/ - -#include -#define cimg_plugin "plugins/cimgmatlab.h" -#include - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { - if (nrhs < 2) mexErrMsgTxt("No enough input arguments."); - if (nrhs > 4) mexErrMsgTxt("Too many input arguments."); - cimg_library::CImg<> u(prhs[0],true); - if (nrhs == 2) { - const float s = (float)mxGetScalar(prhs[1]); - plhs[0] = u.get_blur(s).toMatlab(); - } else if (nrhs == 3) { - const float sx = (float)mxGetScalar(prhs[1]); - const float sy = (float)mxGetScalar(prhs[2]); - plhs[0] = u.get_blur(sx,sy,0).toMatlab(); - } else if (nrhs == 4) { - const float sx = (float)mxGetScalar(prhs[1]); - const float sy = (float)mxGetScalar(prhs[2]); - const float sz = (float)mxGetScalar(prhs[3]); - plhs[0] = u.get_blur(sx,sy,sz).toMatlab(); - } -} - -/*------------------------------------------------------------------ - - SPECIAL NOTE : - ------------- - - How to read a .mat file using plugin 'cimgmatlab.h' ? - (contribution by Vo Duc Khanh/Denso IT Lab, Tokyo, Japan). - - #include - #include - #include - - #define cimg_plugin "cimgmatlab.h" - - #include "CImg.h" - #include - #include - - ......... - - using namespace cimg_library; - using namespace std; - - // Load input images (125700 images) from training database 'BmpTrainingDb.mat' - MATFile *pmat, *pmat_out; - mxArray *pa, *pa_out; - const char data_path[256] = ".\\BmpTrainingDb.mat\0"; - const char *var_name; - - pmat = matOpen(data_path, "r"); - if (pmat == NULL) { - cout << "Error opening file " << data_path << endl; - return (1); - } - - pa = matGetNextVariable(pmat, &var_name); - if (pa == NULL){ - cout << "Error reading in file " << data_path << endl; - return (1); - } - - CImg train_db(pa,false); - ........ - - - -----------------------------------------------------------------------------*/ diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_cimgmatlab.m b/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_cimgmatlab.m deleted file mode 100644 index 30abf661261..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_cimgmatlab.m +++ /dev/null @@ -1,33 +0,0 @@ -/*----------------------------------------------------------------------- - File : use_cimgmatlab.m - - Description: Example of use for the CImg plugin 'plugins/cimgmatlab.h' - which allows to use CImg in order to develop matlab external - functions (mex functions). - User should be familiar with Matlab C/C++ mex function concepts, - as this file is by no way a mex programming tutorial. - - This simple example implements a mex function that can be called - as - - - v = cimgmatlab_cannyderiche(u,s) - - v = cimgmatlab_cannyderiche(u,sx,sy) - - v = cimgmatlab_cannyderiche(u,sx,sy,sz) - - The corresponding m-file is cimgmatlab_cannyderiche.m - - - Copyright : Francois Lauze - http://www.itu.dk/people/francois - This software is governed by the Gnu General Public License - see http://www.gnu.org/copyleft/gpl.html - - The plugin home page is at - http://www.itu.dk/people/francois/cimgmatlab.html - - for the compilation: using the mex utility provided with matlab, just - remember to add the -I flags with paths to CImg.h and/or cimgmatlab.h. - The default lcc cannot be used, it is a C compiler and not a C++ one! ---------------------------------------------------------------------------*/ - -function v = cimgmatlab_cannyderiche(u,sx,sy,sz) - diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_draw_gradient.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_draw_gradient.cpp deleted file mode 100644 index 94344545c41..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_draw_gradient.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - # - # File : use_draw_gradient.cpp - # ( C++ source file ) - # - # Description : Example of use for the CImg plugin 'plugins/draw_gradient.h'. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : Jerome Boulanger - # ( http://www.ricam.oeaw.ac.at/people/page.cgi?firstn=Jerome;lastn=Boulanger ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#define cimg_plugin "plugins/draw_gradient.h" -#include "CImg.h" -using namespace cimg_library; - -// Main procedure -//--------------- -int main(int argc,char **argv) { - - // Read command line arguments - //---------------------------- - cimg_usage("Example of the use of draw_gradient CImg plugin"); - const char *const file_i = cimg_option("-i",(char*)0,"Input image"); - const int shape = cimg_option("-s",1,"shape [0,6]"); - const int profile = cimg_option("-p",0,"profile [0,7]"); - - // Define an image - CImg img; - if (file_i) img.load(file_i).resize(-100,-100,-100,3); - else img.assign(300,200,1,3,0); - - // Define the color of the gradient - CImg col(3); - const unsigned char col1[3] = { 0,0,255 }, col2[3] = { 255,255,255 }; - CImgDisplay disp(img,"Click and drag to create color gradient",0); - while (!disp.is_closed() && !disp.key()) { - - // Get a vector direction from the user. - const CImg selection = img.get_select(disp,1); - - // Draw a gradient using the selected coordinated. - col.rand(100,255); - printf("Gradient with %s from color (%d,%d,%d) to (%d,%d,%d)\n", - CImg<>::get_gradient_str(shape,profile),col(0),col(1),col(2),col1[0],col1[1],col2[2]); - img.draw_gradient(selection(0),selection(1),selection(3),selection(4), - col.data(),col1,shape,profile,.7f).display(disp); - } - - // color 0 to transparency - if (file_i) img.load(file_i).resize(-100,-100,-100,3); - else img.assign(300,200,1,3,0); - img.display(disp); - disp.show().flush(); - while (!disp.is_closed() && !disp.key()) { - - // Get a vector direction from the user. - const CImg selection = img.get_select(disp,1); - - // Draw a gradient using the selected coordinated. - col.rand(100,255); - printf("Gradient with %s from color (%d,%d,%d) to transparency\n", - CImg<>::get_gradient_str(shape,profile),col(0),col(1),col(2)); - img.draw_gradient(selection(0),selection(1),selection(3),selection(4), - col.data(),0,shape,profile,.7f).display(disp); - } - - - // transparency to color 1 - if (file_i) img.load(file_i).resize(-100,-100,-100,3); - else img.assign(300,200,1,3,0); - img.display(disp); - disp.show().flush(); - while (!disp.is_closed() && !disp.key()) { - - // Get a vector direction from the user. - const CImg selection = img.get_select(disp,1); - - // Draw a gradient using the selected coordinated. - col.rand(100,255); - printf("Gradient with %s from transparency to color (%d,%d,%d)\n", - CImg<>::get_gradient_str(shape,profile),col(0),col(1),col(2)); - img.draw_gradient(selection(0),selection(1),selection(3),selection(4), - 0,col.data(),shape,profile,.7f).display(disp); - } - - // random - if (file_i) img.load(file_i).resize(-100,-100,-100,3); - else img.assign(300,200,1,3,0); - disp.set_title("Random color gradient").show().flush(); - CImg visu(img); - visu.display(disp); - while (!disp.is_closed() && !disp.key()) { - const int - x = (int)(cimg::rand()*visu.width()), - y = (int)(cimg::rand()*visu.height()), - rx = (int)((cimg::rand()*25 + 5)*(cimg::rand()>.5?-1:1)), - ry = (int)((cimg::rand()*25 + 5)*(cimg::rand()>.5?-1:1)); - col.rand(64,255); - img.draw_gradient(x,y,x + rx,y + ry,col.data(),0,shape,profile,.4f); - visu = img; - visu.draw_text(10,10,"%.1ffps",col2,0,1,13,disp.frames_per_second()).display(disp); - if (disp.is_resized()) disp.resize(); - } - - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_jpeg_buffer.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_jpeg_buffer.cpp deleted file mode 100644 index 65e86ff1d7f..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_jpeg_buffer.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - # - # File : use_jpeg_buffer.cpp - # ( C++ source file ) - # - # Description : Example of use for the CImg plugin 'plugins/jpeg_buffer.h'. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : Paolo Prete - # ( p4olo_prete(at)yahoo.it ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -// These includes are necessary to get the plug-in compile ! -#include -#include -#include - -// Define plugin and include the CImg Library. -#define cimg_plugin "plugins/jpeg_buffer.h" -#include "CImg.h" -using namespace cimg_library; - -// Main procedure -//---------------- -int main() { - - // Create a jpeg memory buffer from the content of a jpeg file. - // (this is for testing purposes only) - const char *filename_input = "foo.jpg"; - std::fprintf(stderr," - Reading file '%s'\n",filename_input); - std::FILE *file_input = std::fopen(filename_input,"rb"); - if (!file_input) { std::fprintf(stderr,"Input JPEG file not found !"); std::exit(0); } - - std::fprintf(stderr," - Construct input JPEG-coded buffer\n"); - unsigned buf_size = 500000; // Put the file size here ! - JOCTET *buffer_input = new JOCTET[buf_size]; - if (std::fread(buffer_input,sizeof(JOCTET),buf_size,file_input)) std::fclose(file_input); - // -> 'buffer_input' is now a valid jpeg-coded memory buffer. - - // Create a CImg instance from the jpeg-coded buffer using the plug-in function. - std::fprintf(stderr," - Create CImg instance from JPEG-coded buffer\n"); - CImg img; - img.load_jpeg_buffer(buffer_input, buf_size); - delete[] buffer_input; - - // Do you image processing stuff here .... - // Here, we just mirror the image and write "hello". - std::fprintf(stderr," - Do simple processing\n"); - const unsigned char purple[] = { 255, 0, 0 }; - const unsigned char black[] = { 0, 0, 0 }; - img.mirror('y').draw_text(0,0," Hello! ",purple,black,1,57); - - // Display image to see if everything's fine. - img.display("Using 'jpeg_buffer.h' plugin"); - - // Define a new JOCTET array where the processed image has to be saved - // (we don't know its dimension before compressing it, therefore we have to allocate enough memory ) - std::fprintf(stderr," - Construct output JPEG-coded buffer\n"); - JOCTET *buffer_output = new JOCTET[2*buf_size]; - - // Save processed image into this JOCTET buffer, compressed as jpeg. - // This is done again by using the plug-in function. - img.save_jpeg_buffer(buffer_output,buf_size,60); - // Note that here, the variable 'buf_size' contains the length of the - // data which have been written in the given output buffer. - - // Copy the content of the above array into a new file - // (it should give you a valid JPEG file then !) - const char *filename_output = "foo_output.jpg"; - std::fprintf(stderr," - Save output file '%s'\n",filename_output); - std::FILE* file_output = std::fopen(filename_output,"wb"); - std::fwrite(buffer_output, sizeof(JOCTET), buf_size, file_output); - std::fclose(file_output); - delete[] buffer_output; - - std::fprintf(stderr," - All done !\n"); - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_nlmeans.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_nlmeans.cpp deleted file mode 100644 index 2c20e3f7fec..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_nlmeans.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - # - # File : use_nlmeans.cpp - # ( C++ source file ) - # - # Description : Example of use for the CImg plugin 'plugins/nlmeans.h'. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : Jerome Boulanger - # ( http://www.irisa.fr/vista/Equipe/People/Jerome.Boulanger.html ) - # - # Benchmark : (CPU intel pentium 4 2.60GHz) compiled with cimg_debug=0. - # patch lambda* alpha T sigma PSNR - # 3x3 15 9x9 3.6s 20 28.22 - # 5x5 17 15x15 22.2s 20 27.91 - # 7x7 42 21x21 80.0s 20 28.68 - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#define cimg_plugin "plugins/nlmeans.h" -#include "CImg.h" -using namespace cimg_library; -#ifndef cimg_imagepath -#define cimg_imagepath "img/" -#endif - -// Main procedure -//---------------- -int main(int argc,char **argv) { - - // Read command line argument s - //----------------------------- - cimg_usage("Non-local means denoising algorithm.\n [1] Buades, A. Coll, B. and Morel, J.: A review of image " - "denoising algorithms, with a new one. Multiscale Modeling and Simulation: A SIAM Interdisciplinary " - "Journal 4 (2004) 490-530 \n [2] Gasser, T. Sroka,L. Jennen Steinmetz,C. Residual variance and residual " - "pattern nonlinear regression. Biometrika 73 (1986) 625-659 \n Build : "); - - // input/output and general options - const char *file_i = cimg_option("-i",cimg_imagepath "milla.bmp","Input image"); - const char *file_o = cimg_option("-o",(char*)NULL,"Output file"); - const double zoom = cimg_option("-zoom",1.0,"Image magnification"); - const double noiseg = cimg_option("-ng",0.0,"Add gauss noise before aplying the algorithm"); - const double noiseu = cimg_option("-nu",0.0,"Add uniform noise before applying the algorithm"); - const double noises = cimg_option("-ns",0.0,"Add salt&pepper noise before applying the algorithm"); - const unsigned int visu = cimg_option("-visu",1,"Visualization step (0=no visualization)"); - - // non local means options - const int patch_size = cimg_option("-p",1,"Half size of the patch (2p+1)x(2p+1)"); - const float lambda = (float)cimg_option("-lambda",-1.0f,"Bandwidth as defined in [1] (-1 : automatic bandwidth)"); - const double sigma = cimg_option("-sigma",-1,"Noise standard deviation (-1 : robust estimation)"); - const int alpha = cimg_option("-alpha",3,"Neighborhood size (3)"); - const int sampling = cimg_option("-sampling",1,"Sampling of the patch (1: slow, 2: fast)"); - - // Read image - //------------ - CImg<> img; - if (file_i) { - img = CImg<>(file_i); - if (zoom>1) - img.resize((int)(img.width()*zoom),(int)(img.height()*zoom),(int)(img.depth()*zoom),-100,3); - } else throw CImgException("You need to specify at least one input image (option -i)"); - CImg<> original=img; - - // Add some noise - //----------------- - img.noise(noiseg,0).noise(noiseu,1).noise(noises,2); - - // Apply the filter - //--------------------- - long tic = cimg::time(); - CImg<> dest; - dest = img.get_nlmeans(patch_size,lambda,alpha,sigma,sampling); - long tac = cimg::time(); - - // Save result - //----------------- - if (file_o) dest.cut(0,255.f).save(file_o); - - // Display (option -visu) - //----------------------- - if (visu){ - fprintf(stderr,"Image computed in %f s \n",(float)(tac - tic)/1000.); - fprintf(stderr,"The pnsr is %f \n", - 20.*std::log10(255./std::sqrt( (dest - original).pow(2).sum()/original.size() ))); - if (noiseg==0 && noiseu==0 && noises==0) - CImgList<>(original,dest,((dest - original)*=2)+=128).display("Original + Restored + Estimated Noise"); - - else { - CImgList<>(original,img,dest,((dest - img)*=2)+=128,((dest - original)*=2)+=128). - display("Original + Noisy + Restored + Estimated Noise + Original Noise"); - } - } - - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_patchmatch.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_patchmatch.cpp deleted file mode 100644 index 2a0307823fa..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_patchmatch.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - # - # File : use_patchmatch.cpp - # ( C++ source file ) - # - # Description : Example of use for the CImg plugin 'plugins/patchmatch.h'. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : Olivier D'Hondt - # (https://sites.google.com/site/dhondtolivier/) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#define cimg_plugin "plugins/patchmatch.h" -#include "CImg.h" - -using namespace cimg_library; -using namespace std; - -int main(int argc, char **argv) { - cimg_usage("PatchMatch: approximate nearest neighbour patch matching between two images img0 and img1."); - cimg_help("Input / Output parameters:\n--------------------------"); - const char *file0 = cimg_option("-i0", "img/sh0r.pgm", "Image 0"); - const char *file1 = cimg_option("-i1", "img/sh1r.pgm", "Image 1"); - const char *fileout = cimg_option("-o", (char*)0, - "Output image of offsets (channel 0: x offset, channel 1: y offset)"); - const int P = cimg_option("-s", 7, "Patch size"); - const int N = cimg_option("-n", 5, "Number of iterations"); - const bool DISP = cimg_option("-d", true, "Real-time display (slows down the process)"); - const bool VERB = cimg_option("-v", true, "Verbose"); - - if (!file0 || !file1) { - std::fprintf(stderr,"Must specify images with -i0 and -i1 options (-h for help).\n"); - exit(0); - } - - srand((unsigned int)time(NULL)); - - - CImg img0(file0); - CImg img1(file1); - CImg imgrec(img0, "xyzc", 0); - - CImg off; - - if(VERB){ - std::fprintf(stderr, - "\n--------\n" - "PatchMatch: approximate nearest neighbor search\n" - "From left to right: \n" - "(a) Image 0 \n" - "(b) Reconstructed version of image 0 from image 1 patches\n" - "(c) HSV displacement map (hue encodes the angle, saturation the magnitude)\n" - "(d) Image 1\n" - "--------\n\n"); - } - - // Optional display for real-time view - CImgDisplay *disp = 0; - if (DISP) disp = new CImgDisplay; - off.patchMatch(img0, img1, P, N, disp); - delete disp; - std::fprintf(stderr,"Done!\n\n"); - - (img0, - imgrec.reconstruct(img1, off), - off.get_vizFlow(100), - img1).display("PatchMatch: final result.", false); - - - if(fileout) - off.save_cimg(fileout); -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_skeleton.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_skeleton.cpp deleted file mode 100644 index 023d166f892..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_skeleton.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - # - # File : use_skeleton.cpp - # ( C++ source file ) - # - # Description : Example of use for the CImg plugin 'plugins/skeleton.h'. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : Francois-Xavier Dupe - # ( http://www.greyc.ensicaen.fr/~fdupe/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#include -#define cimg_plugin "plugins/skeleton.h" -#include "CImg.h" -using namespace cimg_library; -#ifndef cimg_imagepath -#define cimg_imagepath "img/" -#endif - -// Main procedure -//---------------- -int main (int argc, char **argv) { - - cimg_usage("Compute the skeleton of a shape, using Hamilton-Jacobi equations"); - - // Read command line arguments - cimg_help("Input/Output options\n" - "--------------------"); - const char* file_i = cimg_option("-i",cimg_imagepath "milla.bmp","Input (black&white) image"); - const int median = cimg_option("-median",0,"Apply median filter"); - const bool invert = cimg_option("-inv",false,"Invert image values"); - const char* file_o = cimg_option("-o",(char*)0,"Output skeleton image"); - const bool display = cimg_option("-visu",true,"Display results"); - - cimg_help("Skeleton computation parameters\n" - "-------------------------------"); - const float thresh = cimg_option("-t",-0.3f,"Threshold"); - const bool curve = cimg_option("-curve",false,"Create medial curve"); - - cimg_help("Torsello correction parameters\n" - "------------------------------"); - const bool correction = cimg_option("-corr",false,"Torsello correction"); - const float dlt1 = 2; - const float dlt2 = cimg_option("-dlt",1.0f,"Discrete step"); - - // Load the image (forcing it to be scalar with 2 values { 0,1 }). - CImg image0(file_i), image = image0.get_norm().quantize(2).normalize(0.0f,1.0f); - if (median) image.blur_median(median); - if (invert) (image-=1)*=-1; - if (display) (image0.get_normalize(0,255),image.get_normalize(0,255)).display("Input image - Binary image"); - - // Compute distance map. - CImgList visu; - CImg distance = image.get_distance(0); - if (display) visu.insert(distance); - - // Compute the gradient of the distance function, and the flux (divergence) of the gradient field. - const CImgList grad = distance.get_gradient("xyz"); - CImg flux = image.get_flux(grad,1,1); - if (display) visu.insert(flux); - - // Use the Torsello correction of the flux if necessary. - if (correction) { - CImg - logdensity = image.get_logdensity(distance,grad,flux,dlt1), - nflux = image.get_corrected_flux(logdensity,grad,flux,dlt2); - if (display) visu.insert(logdensity).insert(nflux); - flux = nflux; - } - - if (visu) { - cimglist_apply(visu,normalize)(0,255); - visu.display(visu.size()==2?"Distance function - Flux":"Distance function - Flux - Log-density - Corrected flux"); - } - - // Compute the skeleton - const CImg skel = image.get_skeleton(flux,distance,curve,thresh); - if (display) { - (image0.resize(-100,-100,1,3)*=0.7f).get_shared_channel(1)|=skel*255.0; - image0.draw_image(0,0,0,0,image*255.0,0.5f).display("Image + Skeleton"); - } - - // Save output image if necessary. - if (file_o) skel.save(file_o); - - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_tiff_stream.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_tiff_stream.cpp deleted file mode 100644 index 37b8e3cb41e..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_tiff_stream.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - # - # File : use_tiff_stream.cpp - # ( C++ source file ) - # - # Description : Example of use for the CImg plugin 'plugins/jpeg_buffer.h'. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : Wolf Blecher - # ( Wolf.Blecher(at)sirona.com ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - - -#include -// These includes are necessary to get the plug-in compile ! Don't forget to link with 'libtiff' and 'libtiffxx' ! -#include "tiffio.h" -#include "tiffio.hxx" - -// Define plugin and include the CImg Library. -#define cimg_plugin "plugins/tiff_stream.h" -#include "CImg.h" -using namespace cimg_library; - -// Main procedure -//---------------- -int main() { - - std::ifstream inFile("input.tif", std::ifstream::in | std::ifstream::binary); - std::ofstream outFile("outFile.tif", std::ofstream::out | std::ifstream::binary); - - if (!inFile.good()) - { - std::cout << "Error Reading from infile" << std::endl; - } - - cimg_library::CImg imgIn; - imgIn.load_tiff(&inFile); - imgIn.display(); - CImg imgOut = imgIn.save_tiff(&outFile, 2U); - imgOut.display(); - - inFile.close(); - outFile.close(); - - inFile.open("outFile.tif", std::ifstream::in | std::ifstream::binary); - imgIn.load_tiff(&inFile); - imgIn.display(); - inFile.close(); - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_tinymatwriter.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_tinymatwriter.cpp deleted file mode 100644 index d1146df7b51..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/use_tinymatwriter.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - # - # File : use_tinymatwriter.cpp - # ( C++ source file ) - # - # Description : Example of use for the CImg plugin 'plugins/tinymatwriter.h'. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : Jan W. Krieger - # ( https://github.com/jkriege2 ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -/* - This Matlab/Octave script tests the output: - clear all - more off - - subplot(2,2,1) - load("mat432.mat", "-v6") - disp('mat432.mat: CImg_image=') - disp(CImg_image) - imagesc(CImg_image(:,:,1)) - colorbar - - subplot(2,2,2) - load("mat432i16.mat", "-v6") - disp('mat432i16.mat: CImg_image=') - disp(CImg_image) - imagesc(double(CImg_image(:,:,2))) - colorbar - - subplot(2,2,3) - load("matb.mat", "-v6") - disp('matb.mat: CImg_image=') - disp(CImg_image) - imagesc(CImg_image(:,:,4)) - colorbar -*/ - -#include -#include -#include "tinymatwriter.h" -#include - -#define cimg_plugin "plugins/tinymatwriter.h" -#include "../CImg.h" - -using namespace std; -using namespace cimg_library; - -int main(int argc, const char** argv) { - - double mat432[4*3*2]= { - 1,2,3, - 4,5,6, - - 10,20,30, - 40,50,60, - - 100,200,300, - 400,500,600, - - 1000,2000,3000, - 4000,5000,6000, - }; - - int16_t mat432i16[4*3*2]= { - 1,2,3, - 4,5,6, - - 10,20,30, - 40,50,60, - - 100,200,300, - 400,500,600, - - 1000,-2000,3000, - -4000,5000,-6000, - }; - - // a boolean matrix - bool matb[4*3*2] = { - true,false,true, - false,true,false, - - true,true,true, - false,false,false, - - true,false,true, - true,false,true, - - true,true,false, - false,true,true - }; - - cimg_library::CImg ciD(mat432, 3,2,4); - cimg_library::CImg ciI16(mat432i16, 3,2,4); - cimg_library::CImg ciB(matb, 3,2,4); - - ciD.save_tinymat("mat432.mat"); - ciI16.save_tinymat("mat432i16.mat"); - ciB.save_tinymat("matb.mat"); - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/wavelet_atrous.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/wavelet_atrous.cpp deleted file mode 100644 index ac9fddeac23..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/wavelet_atrous.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* - # - # File : wavelet_atrous.cpp - # ( C++ source file ) - # - # Description : Performs a 2D or 3D 'a trous' wavelet transform - # (using a cubic spline) on an image or a video sequence. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Author : Renaud Peteri - # ( Renaud.Peteri(at)mines-paris.org ) - # Andrea Onofri - # ( Andrea.Onofri(at)teletu.it ) - # - # Institution : CWI, Amsterdam - # - # Date : February 2005 - # - # References : Starck, J.-L., Murtagh, F. and Bijaoui, A., - # Image Processing and Data Analysis: The Multiscale Approach, - # Cambridge University Press, 1998. - # (Hardback and softback, ISBN 0-521-59084-1 and 0-521-59914-8.) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#include "CImg.h" -using namespace cimg_library; -#ifndef cimg_imagepath -#define cimg_imagepath "img/" -#endif - -// Define convolution mask. -CImg mask(const unsigned char dirIdx, const unsigned char scale) { - const int - d1 = 1 << (scale-1), - d2 = 1 << scale, - c = d2, - vecLen = (1 << (scale + 1)) + 1; - - const float - valC = 0.375f, // 6/16 - valD1 = 0.25f, // 4/16 - valD2 = 0.0625f; // 1/16 - - switch(dirIdx) { - case 0 : { // x - CImg m(vecLen,1,1,1,0); - m(c) = valC; - m(c - d1) = m(c + d1) = valD1; - m(c - d2) = m(c + d2) = valD2; - return m; - } - case 1: { // y - CImg m(1,vecLen,1,1,0); - m(0,c) = valC; - m(0,c - d1) = m(0,c + d1) = valD1; - m(0,c - d2) = m(0,c + d2) = valD2; - return m; - } - case 2: { // t - CImg m(1,1,vecLen,1,0); - m(0,0,c) = valC; - m(0,0,c - d1) = m(0,0,c + d1) = valD1; - m(0,0,c - d2) = m(0,0,c + d2) = valD2; - return m; - } - default: throw CImgException("Error, unknow decompostion axe, dirIdx = '%c'.",dirIdx); - } -} - -/*------------------ - Main procedure - ----------------*/ -int main(int argc,char **argv) { - cimg_usage("Perform an 'a trous' wavelet transform (using a cubic spline) on an image or on a video sequence.\n" - "This wavelet transform is undecimated and produces 2 images/videos at each scale. For an example of\n" - "decomposition on a video, try -i img/trees.inr (sequence from the MIT).\n" - "\t(Type -h for help)"); - - // Read command line parameters - const char - *name_i = cimg_option("-i",cimg_imagepath "parrot.ppm","Input image or video"), - *name_o = cimg_option("-o","","Name of the multiscale analysis output"), - *axe_dec = cimg_option("-axe",(char*)0, - "Perform the multiscale decomposition in just one direction ('x', 'y' or 't')"); - const unsigned int - s = cimg_option("-s",3,"Scale of decomposition"); - - const bool help = cimg_option("-h",false,"Display Help"); - if (help) std::exit(0); - - // Initialize Image Data - std::fprintf(stderr," - Load image sequence '%s'...\n",cimg::basename(name_i)); - const CImg texture_in(name_i); - CImg mask_conv; - CImgList res(s,texture_in.width(),texture_in.height(),texture_in.depth()); - CImgList wav(s,texture_in.width(),texture_in.height(),texture_in.depth()); - cimglist_for(res,l) { res(l).fill(0.0); wav(l).fill(0.0); } - unsigned int i; - - int firstDirIdx = 0,lastDirIdx = 2; - if (axe_dec) { // The multiscale decomposition will be performed in just one direction - char c = cimg::lowercase(axe_dec[0]); - switch(c) { - case 'x': firstDirIdx = 0; break; - case 'y': firstDirIdx = 1; break; - case 't': firstDirIdx = 2; break; - default: throw CImgException("Error, unknow decompostion axe '%c', try 'x', 'y' or 't'",c); - } - lastDirIdx = firstDirIdx; // Only one direction - } - - for (i = 0; i get_load_foo(const char *filename) { - std::fprintf(stderr,"Load '%s' here..\n",filename); - return CImg(512,512,1,3,0).noise(30); -} - -CImg& load_foo(const char *filename) { - return get_load_foo(filename).swap(*this); -} - -// This function saves the instance image into a ".foo" file. -//----------------------------------------------------------- -const CImg& save_foo(const char *filename) const { - std::fprintf(stderr,"Save '%s' here..\n",filename); - return *this; -} - -// The code below allows to add the support for the specified extension. -//--------------------------------------------------------------------- -#ifndef cimg_load_plugin -#define cimg_load_plugin(filename) \ - if (!cimg::strncasecmp(cimg::split_filename(filename),"foo",3)) return load_foo(filename); -#endif -#ifndef cimg_save_plugin -#define cimg_save_plugin(filename) \ - if (!cimg::strncasecmp(cimg::split_filename(filename),"foo",3)) return save_foo(filename); -#endif - -// End of the plugin. -//------------------- -#endif /* cimg_plugin_addfileformat */ diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/bayer.h b/applications/plugins/CImgPlugin/extlibs/CImg/plugins/bayer.h deleted file mode 100644 index b848e560f69..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/bayer.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - # - # File : bayer.h - # ( C++ header file - CImg plug-in ) - # - # Description : CImg plugin that implements the conversion of a color image to a - # Bayer-coded matrix, and its reverse transform. - # - # Copyright : David Tschumperlé - # ( https://tschumperle.users.greyc.fr/ ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ -#ifndef cimg_plugin_bayer -#define cimg_plugin_bayer - -//! Convert RGB color image to a Bayer-coded scalar image. -/** - \note First (upper-left) pixel if the red component of the pixel color. -**/ -CImg& RGBtoBayer() { - return get_RGBtoBayer().move_to(*this); -} - -//! Convert RGB color image to a Bayer-coded scalar image \newinstance. -CImg get_RGBtoBayer() const { - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "RGBtoBayer(): Instance is not a RGB image.", - cimg_instance); - - CImg res(_width,_height,_depth,1); - const T *ptr_r = data(0,0,0,0), *ptr_g = data(0,0,0,1), *ptr_b = data(0,0,0,2); - T *ptrd = res._data; - cimg_forXYZ(*this,x,y,z) { - if (y%2) { - if (x%2) *(ptrd++) = *ptr_b; - else *(ptrd++) = *ptr_g; - } else { - if (x%2) *(ptrd++) = *ptr_g; - else *(ptrd++) = *ptr_r; - } - ++ptr_r; ++ptr_g; ++ptr_b; - } - return res; -} - -//! Convert Bayer-coded scalar image to a RGB color image. -CImg& BayertoRGB(const unsigned int interpolation_type=3) { - return get_BayertoRGB(interpolation_type).move_to(*this); -} - -//! Convert Bayer-coded scalar image to a RGB color image \newinstance. -CImg get_BayertoRGB(const unsigned int interpolation_type=3) const { - if (_spectrum!=1) - throw CImgInstanceException(_cimg_instance - "BayertoRGB(): Instance is not a Bayer image.", - cimg_instance); - - CImg res(_width,_height,_depth,3); - CImg_3x3(I,T); - Tuchar *ptr_r = res.data(0,0,0,0), *ptr_g = res.data(0,0,0,1), *ptr_b = res.data(0,0,0,2); - switch (interpolation_type) { - case 3 : { // Edge-directed - CImg_3x3(R,T); - CImg_3x3(G,T); - CImg_3x3(B,T); - cimg_forXYZ(*this,x,y,z) { - const int _p1x = x?x - 1:1, _p1y = y?y - 1:1, _n1x = x get_patch(int x, int y, int z, - int px, int py, int pz) const { - if (depth() == 1){ - const int x0 = x - px, y0 = y - py, x1 = x + px, y1 = y + py; - return get_crop(x0, y0, x1, y1).unroll('y'); - } else { - const int - x0 = x - px, y0 = y - py, z0 = z - pz, - x1 = x + px, y1 = y + py, z1 = z + pz; - return get_crop(x0, y0, z0, x1, y1, z1).unroll('y'); - } -} - -//! Extract a local patch dictionnary around point xi,yi,zi -CImg get_patch_dictionnary(const int xi, const int yi, const int zi, - const int px, const int py, const int pz, - const int wx, const int wy, const int wz, - int & idc) const { - const int - n = (2*wx + 1) * (2*wy + 1) * (2 * (depth()==1?0:wz) + 1), - d = (2*px + 1) * (2*py + 1) * (2 * (depth()==1?0:px) + 1) * spectrum(); - CImg<> S(n, d); - int idx = 0; - if (depth() == 1) { - cimg_forXY_window((*this), xi, yi, xj, yj, wx, wy){ - CImg patch = get_patch(xj, yj, 0, px, py, 1); - cimg_forY(S,y) S(idx,y) = patch(y); - if (xj==xi && yj==yi) idc = idx; - idx++; - } - } else { - cimg_forXYZ_window((*this), xi,yi,zi,xj,yj,zj,wx,wy,wz){ - CImg patch = get_patch(xj, yj, zj, px, py, pz); - cimg_forY(S,y) S(idx,y) = patch(y); - if (xj==xi && yj==yi && zj==zi) idc = idx; - idx++; - } - } - S.columns(0, idx - 1); - return S; -} - -//! Add a patch to the image -/** - \param x x-coordinate of the center of the patch - \param y y-coordinate of the center of the patch - \param z z-coordinate of the center of the patch - \param img the patch as a 1D column vector - \param px the patch half width - \param px the patch half height - \param px the patch half depth -**/ -CImg & add_patch(const int xi, const int yi, const int zi, - const CImg & patch, - const int px, const int py, const int pz) { - const int - x0 = xi - px, y0 = yi - py, z0 = (depth() == 1 ? 0 : zi - pz), - sx = 2 * px + 1, sy = 2 * py + 1, sz = (depth() == 1 ? 1 : 2 * pz +1); - draw_image(x0, y0, z0, 0, patch.get_resize(sx, sy, sz, spectrum(), -1), -1); - return (*this); -} - -//! Add a constant patch to the image -/** - \param x x-coordinate of the center of the patch - \param y y-coordinate of the center of the patch - \param z z-coordinate of the center of the patch - \param value in the patch - \param px the patch half width - \param px the patch half height - \param px the patch half depth -**/ -CImg & add_patch(const int xi, const int yi, const int zi, const T value, - const int px, const int py, const int pz) { - const int - x0 = xi - px, y0 = yi - py, z0 = (depth() == 1 ? 0 : zi - pz), - x1 = xi + px, y1 = yi + py, z1 = (depth() == 1 ? 0 : zi + pz); - draw_rectangle(x0, y0, z0, 0, x1, y1, z1, spectrum()-1, value, -1); -return (*this); -} - -//! CHLPCA denoising from the PhD thesis of Hu Haijuan -/** - \param px the patch half width - \param py the patch half height - \param pz the patch half depth - \param wx the training region half width - \param wy the training region half height - \param wz the training region half depth - \param nstep the subsampling of the image domain - \param nsim the number of patches used for training as a factor of the patch size - \param lambda_min the threshold on the eigen values of the PCA for dimension reduction - \param threshold the threshold on the value of the coefficients - \param pca_use_svd if true use the svd approach to perform the pca otherwise use the covariance method - \note please cite the PhD thesis of Hu Haijuan http://www.univ-ubs.fr/soutenance-de-these-hu-haijuan-337653.kjsp?RH=1318498222799 - **/ -CImg get_chlpca(const int px, const int py, const int pz, - const int wx, const int wy, const int wz, - const int nstep, const float nsim, - const float lambda_min, const float threshold, - const float noise_std, const bool pca_use_svd) const { - const int - nd = (2*px + 1) * (2*py + 1) * (depth()==1?1:2*pz + 1) * spectrum(), - K = (int)(nsim * nd); -#ifdef DEBUG - fprintf(stderr,"chlpca: p:%dx%dx%d,w:%dx%dx%d,nd:%d,K:%d\n", - 2*px + 1,2*py + 1,2*pz + 1,2*wx + 1,2*wy + 1,2*wz + 1,nd,K); -#endif - float sigma; - if (noise_std<0) sigma = (float)std::sqrt(variance_noise()); - else sigma = noise_std; - CImg dest(*this), count(*this); - dest.fill(0); - count.fill(0); - cimg_for_stepZ(*this,zi,(depth()==1||pz==0)?1:nstep){ -#ifdef cimg_use_openmp -#pragma omp parallel for -#endif - cimg_for_stepXY((*this),xi,yi,nstep){ - // extract the training region X - int idc = 0; - CImg S = get_patch_dictionnary(xi,yi,zi,px,py,pz,wx,wy,wz,idc); - // select the K most similar patches within the training set - CImg Sk(S); - CImg index(S.width()); - if (K < Sk.width() - 1){ - CImg mse(S.width()); - CImg perms; - cimg_forX(S,x) { mse(x) = (T)S.get_column(idc).MSE(S.get_column(x)); } - mse.sort(perms,true); - cimg_foroff(perms,i) { - cimg_forY(S,j) Sk(i,j) = S(perms(i),j); - index(perms(i)) = i; - } - Sk.columns(0, K); - perms.threshold(K); - } else { - cimg_foroff(index,i) index(i)=i; - } - // centering the patches - CImg M(1, Sk.height(), 1, 1, 0); - cimg_forXY(Sk,x,y) { M(y) += Sk(x,y); } - M /= (T)Sk.width(); - cimg_forXY(Sk,x,y) { Sk(x,y) -= M(y); } - // compute the principal component of the training set S - CImg P, lambda; - if (pca_use_svd) { - CImg V; - Sk.get_transpose().SVD(V,lambda,P,true,100); - } else { - (Sk * Sk.get_transpose()).symmetric_eigen(lambda, P); - lambda.sqrt(); - } - // dimension reduction - int s = 0; - const T tx = (T)(std::sqrt((double)Sk.width()-1.0) * lambda_min * sigma); - while((lambda(s) > tx) && (s < ((int)lambda.size() - 1))) { s++; } - P.columns(0,s); - // project all the patches on the basis (compute scalar product) - Sk = P.get_transpose() * Sk; - // threshold the coefficients - if (threshold > 0) { Sk.threshold(threshold, 1); } - // project back to pixel space - Sk = P * Sk; - // recenter the patches - cimg_forXY(Sk,x,y) { Sk(x,y) += M(y); } - int j = 0; - cimg_forXYZ_window((*this),xi,yi,zi,xj,yj,zj,wx,wy,wz){ - const int id = index(j); - if (id < Sk.width()) { - dest.add_patch(xj, yj, zj, Sk.get_column(id), px, py, pz); - count.add_patch(xj, yj, zj, (T)1, px, py, pz); - } - j++; - } - } - } - cimg_foroff(dest, i) { - if(count(i) != 0) { dest(i) /= count(i); } - else { dest(i) = (*this)(i); } - } - return dest; -} - -//! CHLPCA denoising from the PhD thesis of Hu Haijuan -/** - \param px the patch half width - \param px the patch half height - \param px the patch half depth - \param wx the training region half width - \param wy the training region half height - \param wz the training region half depth - \param nstep the subsampling of the image domain - \param nsim the number of patches used for training as a factor of the patch size - \param lambda_min the threshold on the eigen values of the PCA for dimension reduction - \param threshold the threshold on the value of the coefficients - \param pca_use_svd if true use the svd approach to perform the pca otherwise use the covariance method - \note please cite the PhD thesis of Hu Haijuan http://www.univ-ubs.fr/soutenance-de-these-hu-haijuan-337653.kjsp?RH=1318498222799 - **/ -CImg & chlpca(const int px, const int py, const int pz, - const int wx, const int wy, const int wz, - const int nstep, const float nsim, - const float lambda_min, const float threshold, - const float noise_std, const bool pca_use_svd) { - (*this) = get_chlpca(px, py, pz, wx, wy, wz, nstep, nsim, lambda_min, - threshold, noise_std, pca_use_svd); - return (*this); -} - -//! CHLPCA denoising from the PhD thesis of Hu Haijuan -/** - \param p the patch half size - \param w the training region half size - \param nstep the subsampling of the image domain - \param nsim the number of patches used for training as a factor of the patch size - \param lambda_min the threshold on the eigen values of the PCA for dimension reduction - \param threshold the threshold on the value of the coefficients - \param pca_use_svd if true use the svd approach to perform the pca otherwise use the covariance method - \note please cite the PhD thesis of Hu Haijuan http://www.univ-ubs.fr/soutenance-de-these-hu-haijuan-337653.kjsp?RH=1318498222799 - **/ -CImg get_chlpca(const int p=3, const int w=10, - const int nstep=5, const float nsim=10, - const float lambda_min=2, const float threshold = -1, - const float noise_std=-1, const bool pca_use_svd=true) const { - if (depth()==1) return get_chlpca(p, p, 0, w, w, 0, nstep, nsim, lambda_min, - threshold, noise_std, pca_use_svd); - else return get_chlpca(p, p, p, w, w, w, nstep, nsim, lambda_min, - threshold, noise_std, pca_use_svd); -} - -CImg chlpca(const int p=3, const int w=10, - const int nstep=5, const float nsim=10, - const float lambda_min=2, const float threshold = -1, - const float noise_std=-1, const bool pca_use_svd=true) { - (*this) = get_chlpca(p, w, nstep, nsim, lambda_min, - threshold, noise_std, pca_use_svd); - return (*this); -} - -#endif /* cimg_plugin_chlpca */ diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/cvMat.h b/applications/plugins/CImgPlugin/extlibs/CImg/plugins/cvMat.h deleted file mode 100644 index af5d4ea5c1c..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/cvMat.h +++ /dev/null @@ -1,350 +0,0 @@ -/* -# -# File : cvMat.h -# ( C++ header file - CImg plug-in ) -# -# Description : CImg plug-in providing the CImg->cvMat and cvMat->CImg -# conversions for generic image types -# ( IPL = Intel Performance Library ) -# This file is a part of the CImg Library project. -# ( http://cimg.eu ) -# -# Copyright : Alberto Albiol -# alalbiol@iteam.upv.es -# -# How to use : In the main program include: -# OPENCV 2.4.x -# #include "cv.h" -# #include "highgui.h" -# #define cimg_plugin1 "cvMat.h" -# #include "CImg.h" -# -# OPENCV 3.x.x -# #include -# #define cimg_plugin1 "cvMat.h" -# #include "CImg.h" - -*/ -#ifndef cimg_plugin_cvMat -#define cimg_plugin_cvMat - -// Conversion IPL -> CImg (constructor) -CImg(const cv::Mat& src):_width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) { - assign(src); -} - -// Conversion IPL -> CImg (in-place constructor) -CImg& assign(const cv::Mat & src) { - if (src.isContinuous()) { - switch (src.depth()) { - // case CV_1U: { // 1-bit int. - // IplImage *src1 = cvCreateImage(cvGetSize(src),CV_8U,1); - // cvConvert(src,src1); - // CImg((unsigned char*)src1->imageData,src1->nChannels,src1.cols,src1.rows,1,true). - // get_permute_axes("yzcx").move_to(*this); - // cvReleaseImage(&src1); - // } break; - case CV_8U: // 8-bit unsigned int. - if (src.channels()==1) { - CImg((unsigned char*)src.ptr(),src.cols,src.rows,true).move_to(*this); - } else { - std::vector channels; - cv::split(src,channels); - CImg - tmp(src.cols,src.rows,1,3), - R = tmp.get_shared_channel(2), - G = tmp.get_shared_channel(1), - B = tmp.get_shared_channel(0); - std::memcpy(R.data(),channels[0].ptr(),src.cols*src.rows*sizeof(uchar)); - std::memcpy(G.data(),channels[1].ptr(),src.cols*src.rows*sizeof(uchar)); - std::memcpy(B.data(),channels[2].ptr(),src.cols*src.rows*sizeof(uchar)); - tmp.move_to(*this); - } - break; - case CV_8S: // 8-bit signed int. - if (src.channels()==1) { - CImg((char*)src.ptr(),src.cols,src.rows,true).move_to(*this); - } else { - std::vector channels; - cv::split(src,channels); - CImg - tmp(src.cols,src.rows,1,3), - R = tmp.get_shared_channel(2), - G = tmp.get_shared_channel(1), - B = tmp.get_shared_channel(0); - std::memcpy(R.data(),channels[0].ptr(),src.cols*src.rows*sizeof(char)); - std::memcpy(G.data(),channels[1].ptr(),src.cols*src.rows*sizeof(char)); - std::memcpy(B.data(),channels[2].ptr(),src.cols*src.rows*sizeof(char)); - tmp.move_to(*this); - } - break; - case CV_16U: // 16-bit unsigned int. - if (src.channels()==1) { - CImg((unsigned short*)src.ptr(),src.cols,src.rows,true).move_to(*this); - } else { - std::vector channels; - cv::split(src,channels); - CImg - tmp(src.cols,src.rows,1,3), - R = tmp.get_shared_channel(2), - G = tmp.get_shared_channel(1), - B = tmp.get_shared_channel(0); - std::memcpy(R.data(),channels[0].ptr(),src.cols*src.rows*sizeof(unsigned short)); - std::memcpy(G.data(),channels[1].ptr(),src.cols*src.rows*sizeof(unsigned short)); - std::memcpy(B.data(),channels[2].ptr(),src.cols*src.rows*sizeof(unsigned short)); - tmp.move_to(*this); - } - break; - case CV_16S: // 16-bit signed int. - if (src.channels()==1) { - CImg((short*)src.ptr(),src.cols,src.rows,true).move_to(*this); - } else { - std::vector channels; - cv::split(src,channels); - CImg - tmp(src.cols,src.rows,1,3), - R = tmp.get_shared_channel(2), - G = tmp.get_shared_channel(1), - B = tmp.get_shared_channel(0); - std::memcpy(R.data(),channels[0].ptr(),src.cols*src.rows*sizeof(short)); - std::memcpy(G.data(),channels[1].ptr(),src.cols*src.rows*sizeof(short)); - std::memcpy(B.data(),channels[2].ptr(),src.cols*src.rows*sizeof(short)); - tmp.move_to(*this); - } - break; - case CV_32S: // 32-bit signed int. - if (src.channels()==1) { - CImg((int*)src.ptr(),src.cols,src.rows,true).move_to(*this); - } else { - std::vector channels; - cv::split(src,channels); - CImg - tmp(src.cols,src.rows,1,3), - R = tmp.get_shared_channel(2), - G = tmp.get_shared_channel(1), - B = tmp.get_shared_channel(0); - std::memcpy(R.data(),channels[0].ptr(),src.cols*src.rows*sizeof(int)); - std::memcpy(G.data(),channels[1].ptr(),src.cols*src.rows*sizeof(int)); - std::memcpy(B.data(),channels[2].ptr(),src.cols*src.rows*sizeof(int)); - tmp.move_to(*this); - } - break; - case CV_32F: // 32-bit float. - if (src.channels()==1) { - CImg((float*)src.ptr(),src.cols,src.rows,true).move_to(*this); - } else { - std::vector channels; - cv::split(src,channels); - CImg - tmp(src.cols,src.rows,1,3), - R = tmp.get_shared_channel(2), - G = tmp.get_shared_channel(1), - B = tmp.get_shared_channel(0); - std::memcpy(R.data(),channels[0].ptr(),src.cols*src.rows*sizeof(float)); - std::memcpy(G.data(),channels[1].ptr(),src.cols*src.rows*sizeof(float)); - std::memcpy(B.data(),channels[2].ptr(),src.cols*src.rows*sizeof(float)); - tmp.move_to(*this); - } - break; - case CV_64F: // 64-bit double. - if (src.channels()==1) { - CImg((double*)src.ptr(),src.cols,src.rows,true).move_to(*this); - } else { - std::vector channels; - cv::split(src,channels); - CImg - tmp(src.cols,src.rows,1,3), - R = tmp.get_shared_channel(2), - G = tmp.get_shared_channel(1), - B = tmp.get_shared_channel(0); - std::memcpy(R.data(),channels[0].ptr(),src.cols*src.rows*sizeof(double)); - std::memcpy(G.data(),channels[1].ptr(),src.cols*src.rows*sizeof(double)); - std::memcpy(B.data(),channels[2].ptr(),src.cols*src.rows*sizeof(double)); - tmp.move_to(*this); - } - break; - default: - throw CImgInstanceException(_cimg_instance - "assign(const cv::Mat&) : Mat depth is invalid.", - cimg_instance); - break; - } - } else { - cv::Size size = src.size(); - switch (src.depth()) { - case CV_8U: // 8-bit unsigned int. - if (src.channels()==1) { - CImg tmp(src.cols,src.rows); - for (int i = 0; i(i); - unsigned char *row_o = tmp.data(0,i); - std::memcpy(row_o,row_i,size.width*sizeof(unsigned char)); - } - tmp.move_to(*this); - } else { - CImg tmp(src.cols,src.rows,1,src.channels()); - std::vector channels; - cv::split(src,channels); - for (int c = 0; c plane = tmp.get_shared_channel(src.channels() - 1 - c); - for (int i = 0; i(i); - unsigned char *row_o = plane.data(0,i); - std::memcpy(row_o,row_i,size.width*sizeof(unsigned char)); - } - } - tmp.move_to(*this); - } - break; - case CV_8S: // 8-bit int. - if (src.channels()==1) { - CImg tmp(src.cols,src.rows); - for (int i = 0; i(i); - char* row_o = tmp.data(0,i); - std::memcpy(row_o,row_i,size.width*sizeof(charT)); - } - tmp.move_to(*this); - } else { - CImg tmp(src.cols,src.rows,1,src.channels()); - std::vector channels; - cv::split(src,channels); - for (int c = 0; c plane = tmp.get_shared_channel(src.channels() - 1 - c); - for (int i = 0; i(i); - char *row_o = plane.data(0,i); - std::memcpy(row_o,row_i,size.width*sizeof(char)); - } - } - tmp.move_to(*this); - } - break; - case CV_16S: // 16-bit int. - if (src.channels()==1) { - CImg tmp(src.cols,src.rows); - for (int i = 0; i(i); - short *row_o = tmp.data(0,i); - std::memcpy(row_o,row_i,size.width*sizeof(short)); - } - tmp.move_to(*this); - } else { - CImg tmp(src.cols,src.rows,1,src.channels()); - std::vector channels; - cv::split(src,channels); - for (int c = 0; c plane = tmp.get_shared_channel(src.channels() - 1 - c); - for (int i = 0; i(i); - short *row_o = plane.data(0,i); - std::memcpy(row_o,row_i,size.width*sizeof(short)); - } - } - tmp.move_to(*this); - } - break; - case CV_32F: // 32-bit float.float - if (src.channels()==1) { - CImg tmp(src.cols,src.rows); - for (int i = 0; i(i); - float *row_o = tmp.data(0,i); - std::memcpy(row_o,row_i,size.width*sizeof(float)); - } - tmp.move_to(*this); - } else { - CImg tmp(src.cols,src.rows,1,src.channels()); - std::vector channels; - cv::split(src,channels); - for (int c = 0; c plane = tmp.get_shared_channel(src.channels() - 1 - c); - for (int i = 0; i(i); - float *row_o = plane.data(0,i); - std::memcpy(row_o,row_i,size.width*sizeof(float)); - } - } - tmp.move_to(*this); - } - break; - case CV_64F: // 64-bit double. - if (src.channels()==1) { - CImg tmp(src.cols,src.rows); - for (int i = 0; i(i); - double *row_o = tmp.data(0,i); - std::memcpy(row_o,row_i,size.width*sizeof(double)); - } - tmp.move_to(*this); - } else { - CImg tmp(src.cols,src.rows,1,src.channels()); - std::vector channels; - cv::split(src,channels); - for (int c = 0; c plane = tmp.get_shared_channel(src.channels() - 1 - c); - for (int i = 0; i(i); - double *row_o = plane.data(0,i); - std::memcpy(row_o,row_i,size.width*sizeof(double)); - } - } - tmp.move_to(*this); - } - break; - default: - throw CImgInstanceException(_cimg_instance - "assign(const cv::Mat&) : Mat depth is invalid.", - cimg_instance); - break; - } - } - - // if (!std::strcmp(src->channelSeq,"BGR")) mirror('v'); - // else if (!std::strcmp(src->channelSeq,"BGRA")) get_shared_channels(0,2).mirror('v'); - return *this; -} - -// Conversion CImg -> MAT -cv::Mat get_MAT(const unsigned int z=0) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "get_MAT() : instance image is empty.", - cimg_instance); - if (z>=_depth) - throw CImgInstanceException(_cimg_instance - "get_MAT() : specified slice %u is out of image bounds.", - cimg_instance,z); - const CImg - _slice = _depth>1?get_slice(z):CImg(), - &slice = _depth>1?_slice:*this; - CImg buf(slice,true); - int - cols = buf.width(), - rows = buf.height(), - nchannels = buf.spectrum(), - matType=-1; - - if (!cimg::strcasecmp(buf.pixel_type(),"unsigned char")) matType = CV_8UC1; - if (!cimg::strcasecmp(buf.pixel_type(),"char")) matType = CV_8SC1; - if (!cimg::strcasecmp(buf.pixel_type(),"unsigned short")) matType = CV_16UC1; - if (!cimg::strcasecmp(buf.pixel_type(),"short")) matType = CV_16SC1; - if (!cimg::strcasecmp(buf.pixel_type(),"int")) matType = CV_32SC1; - if (!cimg::strcasecmp(buf.pixel_type(),"float")) matType = CV_32FC1; - if (!cimg::strcasecmp(buf.pixel_type(),"double")) matType = CV_64FC1; - if (matType<0) - throw CImgInstanceException(_cimg_instance - "get_MAT() : pixel type '%s' is not supported.", - cimg_instance,buf.pixel_type()); - cv::Mat out; - std::vector channels(nchannels); - if (nchannels>1) { - for (int c = 0; c(buf.data() + rows*cols*(nchannels - 1 - c))); - } // for channels - cv::merge(channels,out); - } else out = cv::Mat(rows,cols,matType,const_cast(buf.data())).clone(); - return out; -} - -#endif /* cimg_plugin_cvMat */ diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/draw_gradient.h b/applications/plugins/CImgPlugin/extlibs/CImg/plugins/draw_gradient.h deleted file mode 100644 index b5b7ed68b5f..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/draw_gradient.h +++ /dev/null @@ -1,269 +0,0 @@ -/* - # - # File : draw_gradient.h - # ( C++ header file - CImg plug-in ) - # - # Description : Plugin that can be used to draw color gradient on images. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : Jerome Boulanger - # ( http://www.ricam.oeaw.ac.at/people/page.cgi?firstn=Jerome;lastn=Boulanger ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#ifndef cimg_plugin_draw_gradient -#define cimg_plugin_draw_gradient - -// Convert the couple (shape,profile) into a description string -static inline const char *get_gradient_str(const int shape, const int profile) { - static char buf[128]; - switch(shape) { - case 0: std::sprintf(buf,"linear shape and"); break; - case 1: std::sprintf(buf,"spheric shape and"); break; - case 2: std::sprintf(buf,"conic shape and"); break; - case 3: std::sprintf(buf,"square shape and"); break; - case 4: std::sprintf(buf,"rectangle (L1) shape and"); break; - case 5: std::sprintf(buf,"rectangle (Linf) shape and"); break; - case 6: std::sprintf(buf,"Gaussian shape and"); break; - default: std::sprintf(buf,"undefined shape and"); break; - } - switch(profile) { - case 0: std::strcat(buf," linear profile"); break; - case 1: std::strcat(buf," wave profile"); break; - case 2: std::strcat(buf," ring/bar profile"); break; - case 3: std::strcat(buf," exponential"); break; - case 4: std::strcat(buf," vanishing wave profile"); break; - case 5: std::strcat(buf," vanishing ring/bar profile"); break; - case 6: std::strcat(buf," circ diffraction (Airy) profile"); break; - case 7: std::strcat(buf," rect diffraction (sinc2) profile"); break; - default: std::strcat(buf," undefined profile"); break; - } - return buf; -} - -template -void _draw_gradient_profile(T *const ptr, const float opacity, const float r, - const tc *const color0, const tc *const color1, - const int profile) { - const unsigned int id = (color0?1:0) + (color1?2:0); - const tc col0 = color0?*color0:0, col1 = color1?*color1:0; - switch(profile) { - case 0: { // linear - switch(id) { // map the 3 cases - case 3: *ptr = (T)((1 - opacity)**ptr + opacity*(col0*(1.f - r) + col1*r)); break; - case 1: if (r<1) *ptr = (T)((1 - opacity*(1 - r))**ptr + col0*opacity*(1 - r)); break; - case 2: if (r>0) *ptr = (T)((1 - opacity*r)**ptr + col1*opacity*r); break; - default: break; - } break; - } - case 1: { // waves - const float f = (1 - (float)std::cos(4.5f*r*2.f*cimg::PI))/2; - switch(id) { // map the 3 cases - case 3: *ptr = (T)((1 - opacity)**ptr + opacity*(col0*(1.f - f) + col1*f)); break; - case 1: if (f<1) *ptr = (T)((1 - opacity*(1 - f))**ptr + col0*opacity*(1 - f)); break; - case 2: if (f>0) *ptr = (T)((1 - opacity*f)**ptr + col1*opacity*f); break; - default: break; - } break; - } - case 2:{ // ring/bar - const float f = (1 + (float)std::cos(r*2.f*cimg::PI))/2; - switch(id) { // map the 3 cases - case 3: *ptr = (T)((1 - opacity)**ptr + opacity*(col0*(1.f - f) + col1*f)); break; - case 1: if (f<1) *ptr = (T)((1 - opacity*(1 - f))**ptr + col0*opacity*(1 - f)); break; - case 2: if (f>0) *ptr = (T)((1 - opacity*f)**ptr + col1*opacity*f); break; - default: break; - } break; - } - case 3: { // exponential - const float f = 1 - (float)std::exp(-r); - switch(id) { // map the 3 cases - case 3: *ptr = (T)((1 - opacity)**ptr + opacity*(col0*(1.f - f) + col1*f)); break; - case 1: if (f<1) *ptr = (T)((1 - opacity*(1 - f))**ptr + col0*opacity*(1 - f)); break; - case 2: if (f>0) *ptr = (T)((1 - opacity*f)**ptr + col1*opacity*f); break; - default: break; - } break; - } - case 4: { // vanishing wave - const float f = (1 - (float)std::cos(4.5f*r*2.f*cimg::PI))/2, o = r<.9f?(float)std::exp(-.5*r*r*12.f):0; - switch(id) { // map the 3 cases - case 3: if (o>0) *ptr = (T)((1 - o)**ptr + o*(col0*(1.f - f) + col1*f)); break; - case 1: if (f<1) *ptr = (T)((1 - o*(1 - f))**ptr + col0*o*(1 - f)); break; - case 2: if (f>0) *ptr = (T)((1 - o*f)**ptr + col1*o*f); break; - default: break; - } break; - } - case 5: { // vanishing ring/bar - const float f = (1 + (float)std::cos(r*2.f*cimg::PI))/2, o = r<.9?(float)std::exp(-.5*r*r*12.f):0; - switch(id) { // map the 3 cases - case 3: if (o>0) *ptr = (T)((1 - o)**ptr + o*(col0*(1.f - f) + col1*f)); break; - case 1: if (f<1) *ptr = (T)((1 - o*(1 - f))**ptr + col0*o*(1 - f)); break; - case 2: if (f>0) *ptr = (T)((1 - o*f)**ptr + col1*o*f); break; - default: break; - } break; - } - case 6: { // diffraction pattern of a circular aperture (Airy function) -#define myj1(x) (std::sin((x)<3?(x)*2.2/3:(x) - 0.8)*std::exp(-std::pow((x)/5.0,1/3.0))) - const float a = 10*(float)cimg::PI*r, tmp = a<0.2?.5f:((float)myj1(a)/a), f = 1 - 4*tmp*tmp; -#undef myj1 - switch(id) { // map the 3 cases - case 3: *ptr = (T)((1 - opacity)**ptr + opacity*(col0*(1.f - f) + col1*f)); break; - case 1: if (f<1) *ptr = (T)((1 - opacity*(1 - f))**ptr + col0*opacity*(1 - f)); break; - case 2: if (f>0) *ptr = (T)((1 - opacity*f)**ptr + col1*opacity*f); break; - default: break; - } - break; - } - case 7: { // diffraction pattern of a rectangular function (sinc function) - const float a = 10*(float)cimg::PI*r, tmp = a==0?1:(float)std::sin(a)/a, f = 1 - tmp*tmp; - switch(id) { // map the 3 cases - case 3: *ptr = (T)((1 - opacity)**ptr + opacity*(col0*(1.f - f) + col1*f)); break; - case 1: if (f<1) *ptr = (T)((1 - opacity*(1 - f))**ptr + col0*opacity*(1 - f)); break; - case 2: if (f>0) *ptr = (T)((1 - opacity*f)**ptr + col1*opacity*f); break; - default: break; - } break; - } - default: - CImgArgumentException("CImg<%s>::draw_gradient : unknown profile parameter",pixel_type()); break; - } -} - -//! Draw a gradient with various shape and profile -/** - \param x0 X-coordinate of the 1st control point - \param y0 Y-coordinate of the 1st control point - \param x1 X-coordinate of the 2nd control point - \param y1 Y-coordinate of the 2nd control point - \param color0 Array of dimv() values of type \c T, defining the 1st color. - \param color1 Array of dimv() values of type \c T, defining the 2nd color. - \param shape shape of the gradient (0,3) - \param profile select a profile function (0,7) - \param opacity Drawing opacity. - \note - - if one color is NULL then the gradient is done to transparency -**/ -template -CImg& draw_gradient(const int x0, const int y0, const int x1, const int y1, - const tc *const color0, const tc *const color1, - const int shape=0, const int profile=0, const float opacity=1.0f){ - if (is_empty()) return *this; - if (!color0 && !color1) - throw CImgArgumentException("CImg<%s>::draw_gradient : The two specified colors are (null).", - pixel_type()); - if (profile<0 || profile>7) { // catch this case before entering in the for loop - CImgArgumentException("CImg<%s>::draw_gradient : unknown profile parameter",pixel_type()); - return *this; - } - const float abx = (float)x1 - x0, aby = (float)y1 - y0, ab2 = abx*abx + aby*aby; // pt A=(x0,y0), B=(x1,y1) - const tc *pcol0 = color0, *pcol1 = color1; - T *ptr = data(); - - switch(shape) { - case 0: { // linear - cimg_forC(*this,v) { cimg_forXYZ(*this,x,y,z) { // point M=(x,z) - const float - amx = (float)x - x0, - amy = (float)y - y0, - r = cimg::max(0.f,cimg::min(1.f,(amx*abx + amy*aby)/ab2)); - _draw_gradient_profile(ptr++,opacity,r,pcol0,pcol1,profile); - } if (pcol0) ++pcol0; if (pcol1) ++pcol1; }} break; - case 1:{ // radial - cimg_forC(*this,v) { cimg_forXYZ(*this,x,y,z) { - const float - amx = (float)x - x0, - amy = (float)y - y0, - r = cimg::max(0.f,cimg::min(1.f,(amx*amx + amy*amy)/ab2)); - _draw_gradient_profile(ptr++,opacity,r,pcol0,pcol1,profile); - } if (pcol0) ++pcol0; if (pcol1) ++pcol1; }} break; - case 2:{ // radial cone - cimg_forC(*this,v) { cimg_forXYZ(*this,x,y,z) { - const float - amx = (float)x - x0, - amy = (float)y - y0, - r = cimg::max(0.f,cimg::min(1.f,(float)std::sqrt((amx*amx + amy*amy)/ab2))); - _draw_gradient_profile(ptr++,opacity,r,pcol0,pcol1,profile); - } if (pcol0) ++pcol0; if (pcol1) ++pcol1; }} break; - case 3:{ // square - cimg_forC(*this,v) { cimg_forXYZ(*this,x,y,z) { - const float - amx = (float)x - x0, - amy = (float)y - y0, - r=cimg::max(0.f,cimg::min(1.f,(cimg::abs(amx*abx + amy*aby) + cimg::abs(amx*aby - amy*abx))/ab2)); - _draw_gradient_profile(ptr++,opacity,r,pcol0,pcol1,profile); - } if (pcol0) ++pcol0; if (pcol1) ++pcol1; }} break; - case 4:{ // rectangle (L1) - cimg_forC(*this,v) { cimg_forXYZ(*this,x,y,z) { - const float - amx = (float)x - x0, - amy = (float)y - y0, - r = cimg::max(0.f,cimg::min(1.f,(cimg::abs(amx/abx) + cimg::abs(amy/aby)))); - _draw_gradient_profile(ptr++,opacity,r,pcol0,pcol1,profile); - } if (pcol0) ++pcol0; if (pcol1) ++pcol1; }} break; - case 5:{ // rectangle (Linf) - cimg_forC(*this,v) { cimg_forXYZ(*this,x,y,z) { - const float - amx = (float)x - x0, - amy = (float)y - y0, - r=cimg::max(0.f,cimg::min(1.f,cimg::max(cimg::abs(amx/abx),cimg::abs(amy/aby)))); - _draw_gradient_profile(ptr++,opacity,r,pcol0,pcol1,profile); - } if (pcol0) ++pcol0; if (pcol1) ++pcol1; }} break; - case 6:{ // gaussian - cimg_forC(*this,v) { cimg_forXYZ(*this,x,y,z) { - const float - amx = (float)x - x0, - amy = (float)y - y0, - r = cimg::max(0.f,cimg::min(1.f,1 - (float)std::exp(-(amx*amx + amy*amy)/ab2))); - _draw_gradient_profile(ptr++,opacity,r,pcol0,pcol1,profile); - } if (pcol0) ++pcol0; if (pcol1) ++pcol1; }} break; - default: - CImgArgumentException("CImg<%s>::draw_gradient : unknown shape parameter",pixel_type()); break; - } - return *this; -} - -template -CImg& draw_gradient(const int x0, const int y0, const int x1, const int y1, - const tc *const color0, const int color1, - const int shape=0, const int profile=0, const float opacity=1.0f) { - cimg::unused(color1); - return (*this).draw_gradient(x0,y0,x1,y1,color0,(tc*)0,shape,profile,opacity); -} - -template -CImg& draw_gradient(const int x0, const int y0, const int x1, const int y1, - const int color0, const tc *const color1, - const int shape=0, const int profile=0, const float opacity=1.0f) { - cimg::unused(color0); - return (*this).draw_gradient(x0,y0,x1,y1,(tc*)0,color1,shape,profile,opacity); -} - -#endif /* cimg_draw_gradient */ diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/inpaint.h b/applications/plugins/CImgPlugin/extlibs/CImg/plugins/inpaint.h deleted file mode 100644 index 350a9e0868b..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/inpaint.h +++ /dev/null @@ -1,500 +0,0 @@ -/* - # - # File : inpaint.h - # ( C++ header file - CImg plug-in ) - # - # Copyright : David Tschumperlé - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # Description : - # - # This plug-in implements the patch-based inpainting algorithm for 2d images, as - # described in the two following publications : - # - # "A Smarter Examplar-based Inpainting Algorithm using Local and Global Heuristics - # for more Geometric Coherence." - # (M. Daisy, P. Buyssens, D. Tschumperlé, O. Lezoray). - # IEEE International Conference on Image Processing (ICIP'14), Paris/France, Oct. 2014 - # - # and - # - # "A Fast Spatial Patch Blending Algorithm for Artefact Reduction in Pattern-based - # Image Inpainting." - # (M. Daisy, D. Tschumperlé, O. Lezoray). - # SIGGRAPH Asia 2013 Technical Briefs, Hong-Kong, November 2013. - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ -#ifndef cimg_plugin_inpaint -#define cimg_plugin_inpaint - -template -CImg& inpaint_patch(const CImg& mask, const unsigned int patch_size=11, - const unsigned int lookup_size=22, const float lookup_factor=1, - const int lookup_increment=1, - const unsigned int blend_size=0, const float blend_threshold=0.5f, - const float blend_decay=0.02, const unsigned int blend_scales=10, - const bool is_blend_outer=false) { - if (depth()>1) - throw CImgInstanceException(_cimg_instance - "inpaint_patch(): Instance image is volumetric (should be 2d).", - cimg_instance); - if (!is_sameXYZ(mask)) - throw CImgArgumentException(_cimg_instance - "inpaint_patch() : Sizes of instance image and specified mask " - "(%u,%u,%u,%u) do not match.", - cimg_instance, - mask._width,mask._height,mask._depth,mask._spectrum); - if (!patch_size) - throw CImgArgumentException(_cimg_instance - "inpaint_patch() : Specified patch size is 0, must be strictly " - "positive.", - cimg_instance); - if (!lookup_size) - throw CImgArgumentException(_cimg_instance - "inpaint_patch() : Specified lookup size is 0, must be strictly " - "positive.", - cimg_instance); - if (lookup_factor<0) - throw CImgArgumentException(_cimg_instance - "inpaint_patch() : Specified lookup factor %g is negative, must be " - "positive.", - cimg_instance, - lookup_factor); - if (!lookup_increment) - throw CImgArgumentException(_cimg_instance - "inpaint_patch() : Specified lookup increment is 0, must be " - "strictly positive.", - cimg_instance); - if (blend_decay<0) - throw CImgArgumentException(_cimg_instance - "inpaint_patch() : Specified blend decay %g is negative, must be " - "positive.", - cimg_instance, - blend_decay); - - // Find (dilated by 2) bounding box for the inpainting mask. - unsigned int xm0 = _width, ym0 = _height, xm1 = 0, ym1 = 0; - bool is_mask_found = false; - cimg_forXY(mask,x,y) if (mask(x,y)) { - is_mask_found = true; - if (x<(int)xm0) xm0 = (unsigned int)x; - if (x>(int)xm1) xm1 = (unsigned int)x; - if (y<(int)ym0) ym0 = (unsigned int)y; - if (y>(int)ym1) ym1 = (unsigned int)y; - } - if (!is_mask_found) return *this; - xm0 = xm0>2?xm0 - 2:0; - ym0 = ym0>2?ym0 - 2:0; - xm1 = xm1<_width - 3?xm1 + 2:_width - 1; - ym1 = ym1<_height - 3?ym1 + 2:_height - 1; - int ox = xm0, oy = ym0; - unsigned int dx = xm1 - xm0 + 1U, dy = ym1 - ym0 + 1U; - - // Construct normalized version of the mask. - CImg nmask(dx,dy); - unsigned char *ptrM = nmask.data(); - cimg_for_inXY(mask,xm0,ym0,xm1,ym1,x,y) *(ptrM++) = mask(x,y)?0:1; - xm0 = ym0 = 0; xm1 = dx - 1; ym1 = dy - 1; - - // Start patch filling algorithm. - const int p2 = (int)patch_size/2, p1 = (int)patch_size - p2 - 1; - const unsigned int patch_size2 = patch_size*patch_size; - unsigned int _lookup_size = lookup_size, nb_lookups = 0, nb_fails = 0, nb_saved_patches = 0; - bool is_strict_search = true; - const float one = 1; - - CImg confidences(nmask), priorities(dx,dy,1,2,-1), pC; - CImg saved_patches(4,256), is_visited(width(),height(),1,1,0); - CImg pM, pN; // Pre-declare patch variables (avoid iterative memory alloc/dealloc). - CImg pP, pbest; - CImg weights(patch_size,patch_size,1,1,0); - weights.draw_gaussian((float)p1,(float)p1,patch_size/15.0f,&one)/=patch_size2; - unsigned int target_index = 0; - - while (true) { - - // Extract mask border points and compute priorities to find target point. - unsigned int nb_border_points = 0; - float target_confidence = -1, target_priority = -1; - int target_x = -1, target_y = -1; - CImg_5x5(M,unsigned char); - - cimg_for_in5x5(nmask,xm0,ym0,xm1,ym1,x,y,0,0,M,unsigned char) - if (!Mcc && (Mcp || Mcn || Mpc || Mnc)) { // Found mask border point. - - float confidence_term = -1, data_term = -1; - if (priorities(x,y)>=0) { // If priority has already been computed. - confidence_term = priorities(x,y,0); - data_term = priorities(x,y,1); - } else { // If priority must be computed/updated. - - // Compute smoothed normal vector. - const float - // N = smoothed 3x3 neighborhood of M. - Npc = (4.0f*Mpc + 2.0f*Mbc + 2.0f*Mcc + 2.0f*Mpp + 2.0f*Mpn + Mbp + Mbn + Mcp + Mcn)/16, - Nnc = (4.0f*Mnc + 2.0f*Mac + 2.0f*Mcc + 2.0f*Mnp + 2.0f*Mnn + Map + Man + Mcp + Mcn)/16, - Ncp = (4.0f*Mcp + 2.0f*Mcb + 2.0f*Mcc + 2.0f*Mpp + 2.0f*Mnp + Mpb + Mnb + Mpc + Mnc)/16, - Ncn = (4.0f*Mcn + 2.0f*Mca + 2.0f*Mcc + 2.0f*Mpn + 2.0f*Mnn + Mpa + Mna + Mpc + Mnc)/16, - _nx = 0.5f*(Nnc - Npc), - _ny = 0.5f*(Ncn - Ncp), - nn = std::sqrt(1e-8f + _nx*_nx + _ny*_ny), - nx = _nx/nn, - ny = _ny/nn; - - // Compute confidence term. - nmask._inpaint_patch_crop(x - p1,y - p1,x + p2,y + p2,1).move_to(pM); - confidences._inpaint_patch_crop(x - p1,y - p1,x + p2,y + p2,1).move_to(pC); - confidence_term = 0; - const unsigned char *ptrM = pM.data(); - cimg_for(pC,ptrC,float) confidence_term+=*ptrC**(ptrM++); - confidence_term/=patch_size2; - priorities(x,y,0) = confidence_term; - - // Compute data term. - _inpaint_patch_crop(ox + x - p1,oy + y - p1,ox + x + p2,oy + y + p2,2).move_to(pP); - float mean_ix2 = 0, mean_ixiy = 0, mean_iy2 = 0; - - CImg_3x3(I,T); - CImg_3x3(_M, unsigned char); - cimg_forC(pP,c) cimg_for3x3(pP,p,q,0,c,I,T) { - // Compute weight-mean of structure tensor inside patch. - cimg_get3x3(pM,p,q,0,0,_M,unsigned char); - const float - ixf = (float)(_Mnc*_Mcc*(Inc - Icc)), - iyf = (float)(_Mcn*_Mcc*(Icn - Icc)), - ixb = (float)(_Mcc*_Mpc*(Icc - Ipc)), - iyb = (float)(_Mcc*_Mcp*(Icc - Icp)), - ix = cimg::abs(ixf)>cimg::abs(ixb)?ixf:ixb, - iy = cimg::abs(iyf)>cimg::abs(iyb)?iyf:iyb, - w = weights(p,q); - mean_ix2 += w*ix*ix; - mean_ixiy += w*ix*iy; - mean_iy2 += w*iy*iy; - } - const float // Compute tensor-directed data term. - ux = mean_ix2*(-ny) + mean_ixiy*nx, - uy = mean_ixiy*(-ny) + mean_iy2*nx; - data_term = std::sqrt(ux*ux + uy*uy); - priorities(x,y,1) = data_term; - } - const float priority = confidence_term*data_term; - if (priority>target_priority) { - target_priority = priority; target_confidence = confidence_term; - target_x = ox + x; target_y = oy + y; - } - ++nb_border_points; - } - if (!nb_border_points) break; // No more mask border points to inpaint! - - // Locate already reconstructed neighbors (if any), to get good origins for patch lookup. - CImg lookup_candidates(2,256); - unsigned int nb_lookup_candidates = 0, *ptr_lookup_candidates = lookup_candidates.data(); - const unsigned int *ptr_saved_patches = saved_patches.data(); - const int - x0 = target_x - (int)patch_size, y0 = target_y - (int)patch_size, - x1 = target_x + (int)patch_size, y1 = target_y + (int)patch_size; - for (unsigned int k = 0; k=x0 && (int)dest_y>=y0 && (int)dest_x<=x1 && (int)dest_y<=y1) { - const int off_x = target_x - dest_x, off_y = target_y - dest_y; - *(ptr_lookup_candidates++) = src_x + off_x; - *(ptr_lookup_candidates++) = src_y + off_y; - if (++nb_lookup_candidates>=lookup_candidates._height) - lookup_candidates.resize(2,-200,1,1,0); - } - } - // Add also target point as a center for the patch lookup. - *(ptr_lookup_candidates++) = target_x; - *(ptr_lookup_candidates++) = target_y; - ++nb_lookup_candidates; - - // Divide size of lookup regions if several lookup sources have been detected. - unsigned int final_lookup_size = _lookup_size; - if (nb_lookup_candidates>1) { - const unsigned int - _final_lookup_size = (unsigned int)cimg::round(_lookup_size*lookup_factor/ - std::sqrt((float)nb_lookup_candidates),1,1); - final_lookup_size = _final_lookup_size + 1 - (_final_lookup_size%2); - } - const int l2 = (int)final_lookup_size/2, l1 = (int)final_lookup_size - l2 - 1; - -#ifdef gmic_debug - CImg visu(*this,false); - for (unsigned int C = 0; C::vector(0,255,0).data(),0.2f); - } - visu.draw_rectangle(target_x - p1,target_y - p1,target_x + p2,target_y + p2, - CImg::vector(255,0,0).data(),0.5f); - static int foo = 0; - if (!(foo%1)) { - // visu.save("video.ppm",foo); - static CImgDisplay disp_debug; - disp_debug.display(visu).set_title("DEBUG"); - } - ++foo; -#endif // #ifdef gmic_debug - - // Find best patch candidate to fill target point. - _inpaint_patch_crop(target_x - p1,target_y - p1,target_x + p2,target_y + p2,0).move_to(pP); - nmask._inpaint_patch_crop(target_x - ox - p1,target_y - oy - p1,target_x - ox + p2,target_y - oy + p2,0). - move_to(pM); - ++target_index; - const unsigned int - _lookup_increment = (unsigned int)(lookup_increment>0?lookup_increment: - nb_lookup_candidates>1?1:-lookup_increment); - float best_ssd = cimg::type::max(); - int best_x = -1, best_y = -1; - for (unsigned int C = 0; C=best_ssd) break; - _pC-=pC._spectrum*patch_size2; - _pP-=pC._spectrum*patch_size2; - } - ++_pC; ++_pP; - } - if (ssd=4) { // If too much consecutive fails : - nb_fails = 0; - _lookup_size+=_lookup_size/2; // Try to expand the lookup size. - if (++nb_lookups>=3) { - if (is_strict_search) { // If still fails, switch to non-strict search mode. - is_strict_search = false; - _lookup_size = lookup_size; - nb_lookups = 0; - } - else return *this; // Pathological case, probably a weird mask. - } - } - } else { // Best patch found -> reconstruct missing part on the target patch. - _lookup_size = lookup_size; - nb_lookups = nb_fails = 0; - _inpaint_patch_crop(best_x - p1,best_y - p1,best_x + p2,best_y + p2,0).move_to(pbest); - nmask._inpaint_patch_crop(target_x - ox - p1,target_y - oy - p1,target_x - ox + p2,target_y - oy + p2,1). - move_to(pM); - cimg_for(pM,ptr,unsigned char) *ptr=1 - *ptr; - draw_image(target_x - p1,target_y - p1,pbest,pM,1,1); - confidences.draw_image(target_x - ox - p1,target_y - oy - p1,pC.fill(target_confidence),pM,1,1); - nmask.draw_rectangle(target_x - ox - p1,target_y - oy - p1,0,0,target_x - ox + p2,target_y - oy + p2,0,0,1); - priorities.draw_rectangle(target_x - ox - (int)patch_size, - target_y - oy - (int)patch_size,0,0, - target_x - ox + 3*p2/2, - target_y - oy + 3*p2/2,0,0,-1); - // Remember patch positions. - unsigned int *ptr_saved_patches = saved_patches.data(0,nb_saved_patches); - *(ptr_saved_patches++) = best_x; - *(ptr_saved_patches++) = best_y; - *(ptr_saved_patches++) = target_x; - *ptr_saved_patches = target_y; - if (++nb_saved_patches>=saved_patches._height) saved_patches.resize(4,-200,1,1,0); - } - } - nmask.assign(); // Free some unused memory resources. - priorities.assign(); - confidences.assign(); - is_visited.assign(); - - // Blend inpainting result (if requested), using multi-scale blending algorithm. - if (blend_size && blend_scales) { - const float _blend_threshold = cimg::max(0.0f,cimg::min(1.0f,blend_threshold)); - saved_patches._height = nb_saved_patches; - - // Re-crop image and mask if outer blending is activated. - if (is_blend_outer) { - const int - b2 = (int)blend_size/2, b1 = (int)blend_size - b2 - 1, - xb0 = cimg::max(0,ox - b1), - yb0 = cimg::max(0,oy - b1), - xb1 = cimg::min(_width - 1,xb0 + dx + b1 + b2), - yb1 = cimg::min(_height - 1,yb0 + dy + b1 + b2); - ox = xb0; oy = yb0; dx = xb1 - xb0 + 1U, dy = yb1 - yb0 + 1U; - } - - // Generate map of source offsets. - CImg offsets(dx,dy,1,2); - unsigned int *ptr = saved_patches.end(); - cimg_forY(saved_patches,i) { - const unsigned int yd = *(--ptr), xd = *(--ptr), ys = *(--ptr), xs = *(--ptr); - for (int l = -p1; l<=p2; ++l) - for (int k = -p1; k<=p2; ++k) { - const int xdk = xd + k, ydl = yd + l; - if (xdk>=0 && xdk<=width() - 1 && ydl>=0 && ydl<=height() - 1 && mask(xd + k,yd + l)) { - offsets(xd - ox + k,yd - oy + l,0) = xs + k; - offsets(xd - ox + k,yd - oy + l,1) = ys + l; - } - } - } - unsigned int *ptrx = offsets.data(0,0,0,0), *ptry = offsets.data(0,0,0,1); - cimg_forXY(offsets,x,y) { - if (!mask(x + ox,y + oy)) { *ptrx = x + ox; *ptry = y + oy; } - ++ptrx; ++ptry; - } - - // Generate map of local blending amplitudes. - CImg blend_map(dx,dy,1,1,0); - CImg_3x3(I,float); - cimg_for3XY(offsets,x,y) if (mask(x + ox,y + oy)) { - const float - iox = cimg::max((float)offsets(_n1x,y,0) - offsets(x,y,0), - (float)offsets(x,y,0) - offsets(_p1x,y,0)), - ioy = cimg::max((float)offsets(x,_n1y,1) - offsets(x,y,1), - (float)offsets(x,y,1) - offsets(x,_p1y,1)), - ion = std::sqrt(iox*iox + ioy*ioy); - float iin = 0; - cimg_forC(*this,c) { - cimg_get3x3(*this,x,y,0,c,I,float); - const float - iix = (float)cimg::max(Inc - Icc,Icc - Ipc), - iiy = (float)cimg::max(Icn - Icc,Icc - Icp); - iin+=std::log(1 + iix*iix + iiy*iiy); - } - iin/=_spectrum; - blend_map(x,y) = ion*iin; - } - blend_map.threshold(blend_map.max()*_blend_threshold).distance(1); - cimg_forXY(blend_map,x,y) blend_map(x,y) = 1/(1 + blend_decay*blend_map(x,y)); - blend_map.quantize(blend_scales + 1,false); - float bm, bM = blend_map.max_min(bm); - if (bm==bM) blend_map.fill((float)blend_scales); - - // Generate blending scales. - CImg result = _inpaint_patch_crop(ox,oy,ox + dx - 1,oy + dy - 1,0); - for (unsigned int blend_iter = 1; blend_iter<=blend_scales; ++blend_iter) { - const unsigned int - _blend_width = blend_iter*blend_size/blend_scales, - blend_width = _blend_width?_blend_width + 1 - (_blend_width%2):0; - if (!blend_width) continue; - const int b2 = (int)blend_width/2, b1 = (int)blend_width - b2 - 1; - CImg - blended = _inpaint_patch_crop(ox,oy,ox + dx - 1,oy + dy - 1,0), - cumul(dx,dy,1,1); - weights.assign(blend_width,blend_width,1,1,0). - draw_gaussian((float)b1,(float)b1,blend_width/4.0f,&one); - cimg_forXY(cumul,x,y) cumul(x,y) = mask(x + ox,y + oy)?0.0f:1.0f; - blended.mul(cumul); - - cimg_forY(saved_patches,l) { - const unsigned int *ptr = saved_patches.data(0,l); - const int - xs = (int)*(ptr++), - ys = (int)*(ptr++), - xd = (int)*(ptr++), - yd = (int)*(ptr++); - if (xs - b1<0 || ys - b1<0 || xs + b2>=width() || ys + b2>=height()) { // Blend with partial patch. - const int - xs0 = cimg::max(0,xs - b1), - ys0 = cimg::max(0,ys - b1), - xs1 = cimg::min(width() - 1,xs + b2), - ys1 = cimg::min(height() - 1,ys + b2); - _inpaint_patch_crop(xs0,ys0,xs1,ys1,0).move_to(pP); - weights._inpaint_patch_crop(xs0 - xs + b1,ys0 - ys + b1,xs1 - xs + b1,ys1 - ys + b1,0).move_to(pC); - blended.draw_image(xd + xs0 - xs - ox,yd + ys0 - ys - oy,pP,pC,-1); - cumul.draw_image(xd + xs0 - xs - ox,yd + ys0 - ys - oy,pC,-1); - } else { // Blend with full-size patch. - _inpaint_patch_crop(xs - b1,ys - b1,xs + b2,ys + b2,0).move_to(pP); - blended.draw_image(xd - b1 - ox,yd - b1 - oy,pP,weights,-1); - cumul.draw_image(xd - b1 - ox,yd - b1 - oy,weights,-1); - } - } - - if (is_blend_outer) { - cimg_forXY(blended,x,y) if (blend_map(x,y)==blend_iter) { - const float cum = cumul(x,y); - if (cum>0) cimg_forC(*this,c) result(x,y,c) = (T)(blended(x,y,c)/cum); - } - } else { cimg_forXY(blended,x,y) if (mask(x + ox,y + oy) && blend_map(x,y)==blend_iter) { - const float cum = cumul(x,y); - if (cum>0) cimg_forC(*this,c) result(x,y,c) = (T)(blended(x,y,c)/cum); - } - } - } - if (is_blend_outer) draw_image(ox,oy,result); - else cimg_forXY(result,x,y) if (mask(x + ox,y + oy)) - cimg_forC(*this,c) (*this)(x + ox,y + oy,c) = (T)result(x,y,c); - } - return *this; -} - -// Special crop function that supports more boundary conditions : -// 0=dirichlet (with value 0), 1=dirichlet (with value 1) and 2=neumann. -CImg _inpaint_patch_crop(const int x0, const int y0, const int x1, const int y1, - const unsigned int boundary=0) const { - const int - nx0 = x0 res(1U + nx1 - nx0,1U + ny1 - ny0,1,_spectrum); - if (nx0<0 || nx1>=width() || ny0<0 || ny1>=height()) { - if (boundary>=2) cimg_forXYZC(res,x,y,z,c) res(x,y,z,c) = _atXY(nx0 + x,ny0 + y,z,c); - else res.fill((T)boundary).draw_image(-nx0,-ny0,*this); - } else res.draw_image(-nx0,-ny0,*this); - return res; -} - -template -CImg get_inpaint_patch(const CImg& mask, const unsigned int patch_size=11, - const unsigned int lookup_size=22, const float lookup_factor=1, - const int lookup_increment=1, - const unsigned int blend_size=0, const float blend_threshold=0.5, - const float blend_decay=0.02f, const unsigned int blend_scales=10, - const bool is_blend_outer=false) const { - return (+*this).inpaint_patch(mask,patch_size,lookup_size,lookup_factor,lookup_increment, - blend_size,blend_threshold,blend_decay,blend_scales,is_blend_outer); -} - -#endif /* cimg_plugin_inpaint */ diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/ipl.h b/applications/plugins/CImgPlugin/extlibs/CImg/plugins/ipl.h deleted file mode 100644 index 5e21e18bc9a..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/ipl.h +++ /dev/null @@ -1,309 +0,0 @@ -/* -# -# File : ipl.h -# ( C++ header file - CImg plug-in ) -# -# Description : CImg plug-in providing the CImg->IPL and IPL->CImg -# conversions for generic image types -# ( IPL = Intel Performance Library ) -# This file is a part of the CImg Library project. -# ( http://cimg.eu ) -# -# Copyright : Hon-Kwok Fung (oldfung@graduate.hku.hk) -# -# License : CeCILL v2.0 -# ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) -# -# This software is governed by the CeCILL license under French law and -# abiding by the rules of distribution of free software. You can use, -# modify and/ or redistribute the software under the terms of the CeCILL -# license as circulated by CEA, CNRS and INRIA at the following URL -# "http://www.cecill.info". -# -# As a counterpart to the access to the source code and rights to copy, -# modify and redistribute granted by the license, users are provided only -# with a limited warranty and the software's author, the holder of the -# economic rights, and the successive licensors have only limited -# liability. -# -# In this respect, the user's attention is drawn to the risks associated -# with loading, using, modifying and/or developing or reproducing the -# software by the user in light of its specific status of free software, -# that may mean that it is complicated to manipulate, and that also -# therefore means that it is reserved for developers and experienced -# professionals having in-depth computer knowledge. Users are therefore -# encouraged to load and test the software's suitability as regards their -# requirements in conditions enabling the security of their systems and/or -# data to be ensured and, more generally, to use and operate it in the -# same conditions as regards security. -# -# The fact that you are presently reading this means that you have had -# knowledge of the CeCILL license and that you accept its terms. -# -# -# -# Usage : -# -# In your application code, #define the path of this plugin file as -# something like -# -# #define cimg_plugin1 "../some_directory/ipl.h" -# -# You should define such macro before the line #include . The source -# code of CImg provides eight slots cimg_plugin1, cimg_plugin2, ..., -# cimg_plugin8 for insertion of plugins. You may assign a different slot to -# this plugin if cimg_plugin1 is already occupied. -# -# You need also to include prior to CImg.h the following files : -# -# #include -# #include -# -# To create an IplImage from a CImg instance, you may write: -# -# // Given a CImg instance, say, c_img, ... -# IplImage *img = c_img.get_IplImage(); // (a) copy construction of IplImage -# -# CImg supports any number of color channels, while IplImage supports up to 4 -# channels. When the number of channels is 1 or 2, it is hard to tell if these -# channels have genuine color semantics. Even if the number of channels is 3, -# CImg and IplImage can have different channel orders (IplImage: usually BGR; -# CImg: always RGB). The default behaviour of get_IplImage() is to assume that -# the IplImage instance has a BGR channel order (which is the default order in -# OpenCV) and swap the channel order in the destination image buffer. That is, -# the default is to map OpenCV's blue (1st) and red (3rd) channels to CImg's -# blue (2nd) and red (0th) channel respectively. If the user wants to specify -# this default option explicitly, he/she can write: -# -# IplImage *img = c_img.get_IplImage(CV_CVTIMG_SWAP_RB); // identical to (a) -# -# where CV_CVTIMG_SWAP_RB is a flag value defined by OpenCV. If the user wants -# to keep the channel order unchanged (i.e. maps IplImage's 1st, 2nd, ... -# channels to CImg's 0th, 1st, ... channels resp.), he/she can use a zero flag -# value: -# -# IplImage *img = c_img.get_IplImage(0); -# -# However, when the number of channels is smaller than 3, this option will be -# ignored and the default behaviour (flag value CV_CVTIMG_SWAP_RB) will be -# assumed. -# -# CImg also differs from IplImage in that the latter represents a 2D image but -# the former can be a 3D image. If the size of the z-dimension (depth) of the -# CImg instance is larger than 1, one must choose which slice to copy: -# -# IplImage *img1 = c_img.get_IplImage(0, z); -# IplImage *img2 = c_img.get_IplImage(CV_CVTIMG_SWAP_RB, z); -# -# The default z-value is 0. -# -# To do conversion in another direction, write something like this: -# -# // Suppose img1 and img2 are two pointers to IplImage, where -# // img1->depth == IPL_DEPTH_8U and img2->depth == IPL_DEPTH_32F. -# CImg c_img1(img1); // (b) -# CImg c_img1(img1,CV_CVTIMG_SWAP_RB); // identical to (b) -# CImg c_img2(img2); // (c) -# CImg c_img2(img2,CV_CVTIMG_SWAP_RB); // identical to (c) -# -# Again, if one wants to keep the channel order unchanged when the number of -# channels is >= 3, one can write: -# -# CImg c_img1(img1,0); -# CImg c_img2(img2,0); -# -# All such conversions are deep copy constructions, because CImg and IplImage -# have different internal memory layouts. -# -# Technically, we can write code to do conversion between an IplImage instance -# and a CImg instance with different pixel types (e.g. between an IPL_DEPTH_8S -# IplImage instance and a CImg instance), but such conversion is -# problematic because either the semantics of the pixel type is lost or some -# casting is needed. Therefore, the conversion code in this plugin only allows -# conversions of images of identical pixel types. For instance, in line (b) of -# the example code above, if one writes -# -# CImg c_img1(img1); // error; img1's pixel type is IPL_DEPTH_8U -# -# the conversion will generate a runtime error, despite sizeof(char) is equal -# to sizeof(unsigned char). The is certainly inconvenient to some users as -# the pixel type of CImg has to be defined at compile time but the pixel type -# of IplImage is determined at runtime. -# -# Some architecture-dependent code is contained in the two helper functions -# -# bool not_pixel_type_of(const IplImage*) -# -# and -# -# int get_ipl_bit_depth() const -# -# which establish correspondences between IplImage's pixel type and C++ data -# type. For example, they assume that IPL_DEPTH_16S corresponds to a signed -# short and IPL_DEPTH_64F corresponds to a signed double, etc.. Change the -# code if necessary. -# -# Currently, this plugin provides only conversions of OpenCV IplImage instances -# to and from CImg instances. Conversions of general IplImage instances (e.g. -# those with bit-depth IPL_DEPTH_1U or those with origin==1) are not supported. -# Yet the conversion code has taken care of the data alignment to 4-byte or -# 8-byte boundary as well as the use of both interleaved and non-interleaved -# color channels in IplImage. -*/ - -#ifndef cimg_plugin_ipl -#define cimg_plugin_ipl - -//---------------------------- -// Architecture-dependent helper functions; change to suit your needs -//---------------------------- - -// Check if this CImg instance and a given IplImage have identical pixel types. -bool not_pixel_type_of(const IplImage *const img) const { - // to do : handle IPL_DEPTH_1U? - return (((unsigned int)img->depth == IPL_DEPTH_8U && typeid(T) != typeid(unsigned char)) || - ((unsigned int)img->depth == IPL_DEPTH_8S && typeid(T) != typeid(char)) || - ((unsigned int)img->depth == IPL_DEPTH_16U && typeid(T) != typeid(unsigned short)) || - ((unsigned int)img->depth == IPL_DEPTH_16S && typeid(T) != typeid(unsigned)) || - ((unsigned int)img->depth == IPL_DEPTH_32S && typeid(T) != typeid(int)) || - ((unsigned int)img->depth == IPL_DEPTH_32F && typeid(T) != typeid(float)) || - ((unsigned int)img->depth == IPL_DEPTH_64F && typeid(T) != typeid(double))); -} - -// Given this CImg instance, return the corresponding bit-depth flag for use in IplImage header. -int get_ipl_bit_depth() const { - // to do : handle IPL_DEPTH_1U? - if (typeid(T) == typeid(unsigned char)) return IPL_DEPTH_8U; - if (typeid(T) == typeid(char)) return IPL_DEPTH_8S; - if (typeid(T) == typeid(unsigned short)) return IPL_DEPTH_16U; - if (typeid(T) == typeid(short)) return IPL_DEPTH_16S; - if (typeid(T) == typeid(int)) return IPL_DEPTH_32S; - if (typeid(T) == typeid(float)) return IPL_DEPTH_32F; - if (typeid(T) == typeid(double)) return IPL_DEPTH_64F; - return 0; -} - -//---------------------------- -// IplImage-to-CImg conversion -//---------------------------- - -// Copy constructor; the optional flag will be ignored when the number of color channels is less than 3. -// Current flag options are 0 and CV_CVTIMG_SWAP_RB; -// may add CV_CVTIMG_FLIP and CV_CVTIMG_FLIP|CV_CVTIMG_SWAP_RB in the future. -CImg(const IplImage *const img, const int flag=0): -_width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) { - assign(img,flag); -} - -// In-place constructor; the optional flag will be ignored when the number of color channels is less than 3. -// Current flag options are 0 and CV_CVTIMG_SWAP_RB; -// may add CV_CVTIMG_FLIP and CV_CVTIMG_FLIP|CV_CVTIMG_SWAP_RB in the future. -CImg & assign(const IplImage *const img, const int flag=CV_CVTIMG_SWAP_RB) { - if (!img) return assign(); - if (not_pixel_type_of(img)) - throw CImgInstanceException(_cimg_instance - "assign(const IplImage*) : IplImage has no corresponding pixel type.", - cimg_instance); - // to do: handle roi - const int W = img->width, H = img->height; - const char *const dataPtrI = img->imageData; - assign(W,H,1,img->nChannels); - char *const dataPtrC = (char *)_data; - - const int - byte_depth = (img->depth & 255) >> 3, // number of bytes per color - widthStepI = img->widthStep, // to do: handle the case img->origin==1 (currently: img->origin==0) - widthStepC = W*byte_depth, - channelStepC = H*widthStepC; - - if (img->dataOrder==0) { // interleaved color channels - const int pix_size = byte_depth*img->nChannels; - for (int n = 0; nnChannels; ++n) { - const char *linePtrI = dataPtrI + n*byte_depth; - char *linePtrC = dataPtrC + (img->nChannels>=3 && (flag & CV_CVTIMG_SWAP_RB) && n<3?(2 - n):n)*channelStepC; - // color order is BGR in IplImage and RGB in CImg - - for (int i = 0; inChannels; ++n) { - const char *linePtrI = dataPtrI + n*byte_depth; - char *linePtrC = dataPtrC + (img->nChannels >= 3 && (flag & CV_CVTIMG_SWAP_RB) && n<3?(2 - n):n)*channelStepC; - for (int i = 0; i=_depth) - throw CImgInstanceException(_cimg_instance - "get_IplImage() : Instance has not Z-dimension %u.", - cimg_instance, - z); - if (_spectrum>4) - cimg::warn(_cimg_instance - "get_IplImage() : OpenCV supports only 4 channels, so only the first four will be copied.", - cimg_instance); - - IplImage *const img = cvCreateImage(cvSize(_width,_height),bit_depth,_spectrum); - const int - W = _width, - H = _height, - byte_depth = (img->depth & 255) >> 3, // number of bytes per color - widthStepI = img->widthStep, // to do: handle the case img->origin==1 (currently: img->origin==0) - widthStepC = W*byte_depth, - channelStepC = H*_depth*widthStepC; - const char *const dataPtrC = (char*)_data + z*H*widthStepC; - char *const dataPtrI = img->imageData; - - if (!img->dataOrder) { // interleaved color channels - const int pix_size = byte_depth*img->nChannels; - for (int n = 0; nnChannels; ++n) { - const char - *linePtrC = dataPtrC + (img->nChannels >= 3 && (flag & CV_CVTIMG_SWAP_RB) && n<3?(2 - n):n)*channelStepC; - char *linePtrI = dataPtrI + n*byte_depth; - - // color order is BGR in IplImage and RGB in CImg - for (int i = 0; inChannels; ++n) { - const char - *linePtrC = dataPtrC + (img->nChannels>= 3 && (flag & CV_CVTIMG_SWAP_RB) && n<3?(2 - n):n)*channelStepC; - char *linePtrI = dataPtrI + n*byte_depth; - for (int i = 0; iIPL and IPL->CImg -# conversions for generic image types -# ( IPL = Intel Performance Library ) -# This file is a part of the CImg Library project. -# ( http://cimg.eu ) -# -# Copyright : newleft (haibo.zheng@gmail.com) -# newleftist@hotmail.com -# -# License : CeCILL v2.0 -# ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) -# -# This software is governed by the CeCILL license under French law and -# abiding by the rules of distribution of free software. You can use, -# modify and/ or redistribute the software under the terms of the CeCILL -# license as circulated by CEA, CNRS and INRIA at the following URL -# "http://www.cecill.info". -# -# As a counterpart to the access to the source code and rights to copy, -# modify and redistribute granted by the license, users are provided only -# with a limited warranty and the software's author, the holder of the -# economic rights, and the successive licensors have only limited -# liability. -# -# In this respect, the user's attention is drawn to the risks associated -# with loading, using, modifying and/or developing or reproducing the -# software by the user in light of its specific status of free software, -# that may mean that it is complicated to manipulate, and that also -# therefore means that it is reserved for developers and experienced -# professionals having in-depth computer knowledge. Users are therefore -# encouraged to load and test the software's suitability as regards their -# requirements in conditions enabling the security of their systems and/or -# data to be ensured and, more generally, to use and operate it in the -# same conditions as regards security. -# -# The fact that you are presently reading this means that you have had -# knowledge of the CeCILL license and that you accept its terms. -# -*/ - -#ifndef cimg_plugin_IPL -#define cimg_plugin_IPL - -// Conversion IPL -> CImg (constructor) -CImg(const IplImage* src):_width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) { - assign(src); -} - -// Conversion IPL -> CImg (in-place constructor) -CImg& assign(const IplImage* src) { - if (!src) return assign(); - switch (src->depth) { - case IPL_DEPTH_1U: { // 1-bit int. - IplImage *src1 = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1); - cvConvert(src,src1); - CImg((unsigned char*)src1->imageData,src1->nChannels,src1->width,src1->height,1,true). - get_permute_axes("yzcx").move_to(*this); - cvReleaseImage(&src1); - } break; - case IPL_DEPTH_8U: // 8-bit unsigned int. - CImg((unsigned char*)src->imageData,src->nChannels,src->width,src->height,1,true). - get_permute_axes("yzcx").move_to(*this); - break; - case IPL_DEPTH_8S: // 8-bit signed int. - CImg((char*)src->imageData,src->nChannels,src->width,src->height,1,true). - get_permute_axes("yzcx").move_to(*this); - break; - case IPL_DEPTH_16U: // 16-bit unsigned int. - CImg((unsigned short*)src->imageData,src->nChannels,src->width,src->height,1,true). - get_permute_axes("yzcx").move_to(*this); - break; - case IPL_DEPTH_16S: // 16-bit signed int. - CImg((short*)src->imageData,src->nChannels,src->width,src->height,1,true). - get_permute_axes("yzcx").move_to(*this); - break; - case IPL_DEPTH_32S: // 32-bit signed int. - CImg((int*)src->imageData,src->nChannels,src->width,src->height,1,true). - get_permute_axes("yzcx").move_to(*this); - break; - case IPL_DEPTH_32F: // 32-bit float. - CImg((float*)src->imageData,src->nChannels,src->width,src->height,1,true). - get_permute_axes("yzcx").move_to(*this); - break; - case IPL_DEPTH_64F: // 64-bit double. - CImg((double*)src->imageData,src->nChannels,src->width,src->height,1,true). - get_permute_axes("yzcx").move_to(*this); - break; - default: - throw CImgInstanceException("CImg<%s>::assign(const IplImage* img) : IplImage depth is invalid.", - pixel_type()); - break; - } - if (!std::strcmp(src->channelSeq,"BGR")) mirror('v'); - else if (!std::strcmp(src->channelSeq,"BGRA")) get_shared_channels(0,2).mirror('v'); - return *this; -} - -// Conversion CImg -> IPL -IplImage* get_IPL(const unsigned int z=0) const { - if (is_empty()) - throw CImgInstanceException("CImg<%s>::get_IPL() : instance image (%u,%u,%u,%u,%p) is empty.", - pixel_type(),_width,_height,_depth,_spectrum,_data); - if (z>=_depth) - throw CImgInstanceException("CImg<%s>::get_IPL() : specified slice %u is out of image bounds (%u,%u,%u,%u,%p).", - pixel_type(),z,_width,_height,_depth,_spectrum,_data); - const CImg - _slice = _depth>1?get_slice(z):CImg(), - &slice = _depth>1?_slice:*this; - CImg buf(slice); - if (_spectrum==3 || _spectrum==4) buf.get_shared_channels(0,2).mirror('v'); - buf.permute_axes("cxyz"); - IplImage* const dst = cvCreateImage(cvSize(_width,_height),sizeof(T)*8,_spectrum); - std::memcpy(dst->imageData,buf.data(),buf.size()*sizeof(T)); - return dst; -} - -#endif /* cimg_plugin_IPL */ diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/jpeg_buffer.h b/applications/plugins/CImgPlugin/extlibs/CImg/plugins/jpeg_buffer.h deleted file mode 100644 index ac46a24000f..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/jpeg_buffer.h +++ /dev/null @@ -1,376 +0,0 @@ -/* - # - # File : jpeg_buffer.h - # ( C++ header file - CImg plug-in ) - # - # Description : This CImg plug-in provide functions to load and save jpeg images - # directly from/to memory buffers of JOCTET buffers, using the - # JPEG library (required to compile !) - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : Paolo Prete - # ( p4olo_prete@yahoo.it ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -/*----------------------------------------------------------------------------------- - - IMPORTANT NOTE : - - You *need* to include the following lines in your own code to use this plugin : - - #include - #include - #include - - (see example file provided in examples/use_jpeg_buffer.cpp). - -------------------------------------------------------------------------------------*/ - -#ifndef cimg_plugin_jpeg_buffer -#define cimg_plugin_jpeg_buffer - -/////////////////////////////////////////////////////////////////////////////////////// -// -// extension of libjpeg (helper functions for loading images from JOCTET arrays) -// hacked from -// http://www.koders.com/cpp/fidB5A4549ABB5CB01824058F57A43D095D3F95AB40.aspx -// -/////////////////////////////////////////////////////////////////////////////////////// - -#define INPUT_BUF_SIZE 4096 - -struct my_source_mem { - struct jpeg_source_mgr pub; // Public fields - int indexinmem; - JOCTET *inmem; // Source stream - JOCTET *buffer; // Start of buffer - int lenght; // Size of buffer in memory - boolean start_of_file; // Have we gotten any data yet? -}; - -struct my_source_mgr { - struct jpeg_source_mgr pub; // public fields - FILE *infile; // source stream - JOCTET *buffer; // start of buffer - boolean start_of_file; // have we gotten any data yet? -}; - -typedef my_source_mem *my_src_mptr; -typedef my_source_mgr *my_src_ptr; - -static boolean fill_minput_buffer(j_decompress_ptr cinfo) { - my_src_mptr src = (my_src_mptr) cinfo->src; - size_t nbytes; - if (src->indexinmem + INPUT_BUF_SIZE>src->lenght) nbytes=src->lenght - src->indexinmem; - else nbytes = INPUT_BUF_SIZE; - std::memcpy(src->buffer,src->inmem,nbytes); - src->inmem += nbytes; - src->indexinmem += (int)nbytes; - src->pub.next_input_byte = src->buffer; - src->pub.bytes_in_buffer = INPUT_BUF_SIZE; - src->start_of_file = FALSE; - return TRUE; -} - -static void skip_minput_data(j_decompress_ptr cinfo, long num_bytes) { - my_src_ptr src = (my_src_ptr)cinfo->src; - if (num_bytes > 0) { - while (num_bytes > (long) src->pub.bytes_in_buffer) { - num_bytes -= (long) src->pub.bytes_in_buffer; - fill_minput_buffer(cinfo); - // note we assume that fill_input_buffer will never return FALSE, - // so suspension need not be handled. - // - } - src->pub.next_input_byte += (size_t) num_bytes; - src->pub.bytes_in_buffer -= (size_t) num_bytes; - } -} - -static void init_msource(j_decompress_ptr cinfo) { - my_src_mptr src = (my_src_mptr)cinfo->src; - src->start_of_file = TRUE; -} - -static void term_source(j_decompress_ptr) { - // no work necessary here -} - -static void jpeg_mem_src(j_decompress_ptr cinfo, JOCTET * memptr,int lenght) { - my_src_mptr src; - - // The source object and input buffer are made permanent so that a series - //of JPEG images can be read from the same file by calling jpeg_stdio_src - // only before the first one. (If we discarded the buffer at the end of - // one image, we'd likely lose the start of the next one.) - // This makes it unsafe to use this manager and a different source - // manager serially with the same JPEG object. Caveat programmer. - // - - // first time for this JPEG object? - if (cinfo->src == NULL) { - cinfo->src = (struct jpeg_source_mgr*)(*cinfo->mem->alloc_small)((j_common_ptr) cinfo, - JPOOL_PERMANENT,sizeof(my_source_mem)); - src = (my_src_mptr) cinfo->src; - src->buffer = (JOCTET *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, - JPOOL_PERMANENT,INPUT_BUF_SIZE * sizeof(JOCTET)); - } - - src = (my_src_mptr) cinfo->src; - src->pub.init_source = init_msource; - src->pub.fill_input_buffer = fill_minput_buffer; - src->pub.skip_input_data = skip_minput_data; - //src->pub.resync_to_restart = jpeg_resync_to_restart; // use default method - src->pub.term_source = term_source; - src->inmem = memptr; - src->indexinmem = 0; - src->lenght = lenght; - src->pub.bytes_in_buffer = 0; // forces fill_input_buffer on first read - src->pub.next_input_byte = NULL; // until buffer loaded -} - -// The following declarations and 5 functions are jpeg related -// functions used by put_jpeg_grey_memory and put_jpeg_yuv420p_memory -// -struct mem_destination_mgr { - struct jpeg_destination_mgr pub; - JOCTET *buf; - size_t bufsize; - size_t jpegsize; -}; - -typedef mem_destination_mgr *mem_dest_ptr; - -static void init_destination(j_compress_ptr cinfo) { - mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; - dest->pub.next_output_byte = dest->buf; - dest->pub.free_in_buffer = dest->bufsize; - dest->jpegsize = 0; -} - -static boolean empty_output_buffer(j_compress_ptr cinfo) { - mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; - dest->pub.next_output_byte = dest->buf; - dest->pub.free_in_buffer = dest->bufsize; - return FALSE; - ERREXIT(cinfo, JERR_BUFFER_SIZE); -} - -static void term_destination(j_compress_ptr cinfo) { - mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; - dest->jpegsize = dest->bufsize - dest->pub.free_in_buffer; -} - -static void jpeg_mem_dest(j_compress_ptr cinfo, JOCTET* buf, size_t bufsize) { - mem_dest_ptr dest; - if (cinfo->dest == NULL) { - cinfo->dest = (struct jpeg_destination_mgr *) - (*cinfo->mem->alloc_small)((j_common_ptr)cinfo,JPOOL_PERMANENT,sizeof(mem_destination_mgr)); - } - dest = (mem_dest_ptr) cinfo->dest; - dest->pub.init_destination = init_destination; - dest->pub.empty_output_buffer = empty_output_buffer; - dest->pub.term_destination = term_destination; - dest->buf = buf; - dest->bufsize = bufsize; - dest->jpegsize = 0; -} - -static unsigned jpeg_mem_size(j_compress_ptr cinfo) { - mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; - return dest->jpegsize; -} - -///////////////////////////////////////////////////////////////// -// -// Define main CImg plugin functions. -// (you should use these functions only in your own code) -// -///////////////////////////////////////////////////////////////// - -//! Load image from a jpeg-coded memory buffer. -/** - \param buffer Memory buffer containing the jpeg-coded image data. - \param buffer_size Size of the memory buffer, in bytes. -**/ -static CImg get_load_jpeg_buffer(const JOCTET *const buffer, const unsigned buffer_size) { - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_decompress(&cinfo); - jpeg_mem_src(&cinfo,const_cast(buffer),buffer_size); - jpeg_read_header(&cinfo,TRUE); - jpeg_start_decompress(&cinfo); - - const unsigned int row_stride = cinfo.output_width * cinfo.output_components; - JOCTET *buf = new JOCTET[cinfo.output_width*cinfo.output_height*cinfo.output_components]; - const JOCTET *buf2 = buf; - JSAMPROW row_pointer[1]; - while (cinfo.output_scanline < cinfo.output_height) { - row_pointer[0] = buf + cinfo.output_scanline*row_stride; - jpeg_read_scanlines(&cinfo,row_pointer,1); - } - jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); - - CImg dest(cinfo.output_width,cinfo.output_height,1,cinfo.output_components); - switch (dest.spectrum()) { - case 1: { - T *ptr_g = dest.data(0,0,0,0); - cimg_foroff(dest,off) *(ptr_g++) = (T)*(buf2++); - } break; - case 3: { - T - *ptr_r = dest.data(0,0,0,0), - *ptr_g = dest.data(0,0,0,1), - *ptr_b = dest.data(0,0,0,2); - cimg_forXY(dest,x,y) { - *(ptr_r++) = (T)*(buf2++); - *(ptr_g++) = (T)*(buf2++); - *(ptr_b++) = (T)*(buf2++); - } - } break; - case 4: { - T - *ptr_r = dest.data(0,0,0,0), - *ptr_g = dest.data(0,0,0,1), - *ptr_b = dest.data(0,0,0,2), - *ptr_a = dest.data(0,0,0,3); - cimg_forXY(dest,x,y) { - *(ptr_r++) = (T)*(buf2++); - *(ptr_g++) = (T)*(buf2++); - *(ptr_b++) = (T)*(buf2++); - *(ptr_a++) = (T)*(buf2++); - } - } break; - } - delete[] buf; - - return dest; -} - -//! Load image from a jpeg-coded memory buffer (in-place version) -/** - \param buffer Memory buffer containing the jpeg-coded image data. - \param buffer_size Size of the memory buffer, in bytes. -**/ -CImg& load_jpeg_buffer(const JOCTET *const buffer, const unsigned buffer_size) { - return get_load_jpeg_buffer(buffer,buffer_size).move_to(*this); -} - -//! Save image in a memory buffer, directly as a jpeg-coded file -/** - \param buffer Memory buffer that will be written with the jpeg-coded image data. - \param buffer_size Initial size of the memory buffer. When the function returns, the variable - contains the effective length needed to fill the buffer. - \param quality Quality of the jpeg compression. -**/ -const CImg& save_jpeg_buffer(JOCTET *const buffer, unsigned int &buffer_size, const int quality=100) const { - - // Fill pixel buffer - JOCTET *buf; - unsigned int dimbuf=0; - J_COLOR_SPACE colortype=JCS_RGB; - switch (spectrum()) { - case 1: { - // Greyscale images - JOCTET *buf2 = buf = new JOCTET[width()*height()*(dimbuf=1)]; - const T - *ptr_g = data(); - colortype = JCS_GRAYSCALE; - cimg_foroff(*this,off) *(buf2++) = (JOCTET)*(ptr_g++); - } break; - case 2: - case 3: { - // RGB images - JOCTET *buf2 = buf = new JOCTET[width()*height()*(dimbuf=3)]; - const T - *ptr_r = data(0,0,0,0), - *ptr_g = data(0,0,0,1), - *ptr_b = data(0,0,0,spectrum()>2?2:0); - colortype = JCS_RGB; - cimg_forXY(*this,x,y) { - *(buf2++) = (JOCTET)*(ptr_r++); - *(buf2++) = (JOCTET)*(ptr_g++); - *(buf2++) = (JOCTET)*(ptr_b++); - } - } break; - default: { - // YCMYK images - JOCTET *buf2 = buf = new JOCTET[width()*height()*(dimbuf=4)]; - const T - *ptr_r = data(0,0,0,0), - *ptr_g = data(0,0,0,1), - *ptr_b = data(0,0,0,2), - *ptr_a = data(0,0,0,3); - colortype = JCS_CMYK; - cimg_forXY(*this,x,y) { - *(buf2++) = (JOCTET)*(ptr_r++); - *(buf2++) = (JOCTET)*(ptr_g++); - *(buf2++) = (JOCTET)*(ptr_b++); - *(buf2++) = (JOCTET)*(ptr_a++); - } - } break; - } - - // Call libjpeg functions - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_compress(&cinfo); - jpeg_mem_dest(&cinfo, buffer, buffer_size); - cinfo.image_width = width(); - cinfo.image_height = height(); - cinfo.input_components = dimbuf; - cinfo.in_color_space = colortype; - jpeg_set_defaults(&cinfo); - jpeg_set_quality(&cinfo,quality<100?quality:100,TRUE); - jpeg_start_compress(&cinfo,TRUE); - - const unsigned int row_stride = width()*dimbuf; - JSAMPROW row_pointer[1]; - while (cinfo.next_scanline < cinfo.image_height) { - row_pointer[0] = &buf[cinfo.next_scanline*row_stride]; - jpeg_write_scanlines(&cinfo,row_pointer,1); - } - jpeg_finish_compress(&cinfo); - delete[] buf; - buffer_size = jpeg_mem_size(&cinfo); - jpeg_destroy_compress(&cinfo); - return *this; -} - -// End of the plug-in -//------------------- -#endif /* cimg_plugin_jpeg_buffer */ diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/loop_macros.h b/applications/plugins/CImgPlugin/extlibs/CImg/plugins/loop_macros.h deleted file mode 100644 index 85406a244f6..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/loop_macros.h +++ /dev/null @@ -1,24166 +0,0 @@ -/* - # - # File : loop_macros.h - # ( C++ header file - CImg plug-in ) - # - # Description : CImg plug-in adding useful loop macros in CImg, in order to - # deal with NxN neighborhoods (where N=10..32) - # and NxNxN neighborhoods (where N=4..8) - # This file has been automatically generated using the loop - # macro generator available in 'examples/generate_loop_macros.cpp' - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#ifndef cimg_plugin_loop_macros -#define cimg_plugin_loop_macros - -// Define 10x10 loop macros -//------------------------- -#define cimg_for10(bound,i) for (int i = 0, \ - _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5; \ - _n5##i<(int)(bound) || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i) - -#define cimg_for10X(img,x) cimg_for10((img)._width,x) -#define cimg_for10Y(img,y) cimg_for10((img)._height,y) -#define cimg_for10Z(img,z) cimg_for10((img)._depth,z) -#define cimg_for10C(img,c) cimg_for10((img)._spectrum,c) -#define cimg_for10XY(img,x,y) cimg_for10Y(img,y) cimg_for10X(img,x) -#define cimg_for10XZ(img,x,z) cimg_for10Z(img,z) cimg_for10X(img,x) -#define cimg_for10XC(img,x,c) cimg_for10C(img,c) cimg_for10X(img,x) -#define cimg_for10YZ(img,y,z) cimg_for10Z(img,z) cimg_for10Y(img,y) -#define cimg_for10YC(img,y,c) cimg_for10C(img,c) cimg_for10Y(img,y) -#define cimg_for10ZC(img,z,c) cimg_for10C(img,c) cimg_for10Z(img,z) -#define cimg_for10XYZ(img,x,y,z) cimg_for10Z(img,z) cimg_for10XY(img,x,y) -#define cimg_for10XZC(img,x,z,c) cimg_for10C(img,c) cimg_for10XZ(img,x,z) -#define cimg_for10YZC(img,y,z,c) cimg_for10C(img,c) cimg_for10YZ(img,y,z) -#define cimg_for10XYZC(img,x,y,z,c) cimg_for10C(img,c) cimg_for10XYZ(img,x,y,z) - -#define cimg_for_in10(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5; \ - i<=(int)(i1) && (_n5##i<(int)(bound) || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i) - -#define cimg_for_in10X(img,x0,x1,x) cimg_for_in10((img)._width,x0,x1,x) -#define cimg_for_in10Y(img,y0,y1,y) cimg_for_in10((img)._height,y0,y1,y) -#define cimg_for_in10Z(img,z0,z1,z) cimg_for_in10((img)._depth,z0,z1,z) -#define cimg_for_in10C(img,c0,c1,c) cimg_for_in10((img)._spectrum,c0,c1,c) -#define cimg_for_in10XY(img,x0,y0,x1,y1,x,y) cimg_for_in10Y(img,y0,y1,y) cimg_for_in10X(img,x0,x1,x) -#define cimg_for_in10XZ(img,x0,z0,x1,z1,x,z) cimg_for_in10Z(img,z0,z1,z) cimg_for_in10X(img,x0,x1,x) -#define cimg_for_in10XC(img,x0,c0,x1,c1,x,c) cimg_for_in10C(img,c0,c1,c) cimg_for_in10X(img,x0,x1,x) -#define cimg_for_in10YZ(img,y0,z0,y1,z1,y,z) cimg_for_in10Z(img,z0,z1,z) cimg_for_in10Y(img,y0,y1,y) -#define cimg_for_in10YC(img,y0,c0,y1,c1,y,c) cimg_for_in10C(img,c0,c1,c) cimg_for_in10Y(img,y0,y1,y) -#define cimg_for_in10ZC(img,z0,c0,z1,c1,z,c) cimg_for_in10C(img,c0,c1,c) cimg_for_in10Z(img,z0,z1,z) -#define cimg_for_in10XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in10Z(img,z0,z1,z) cimg_for_in10XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in10XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in10C(img,c0,c1,c) cimg_for_in10XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in10YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in10C(img,c0,c1,c) cimg_for_in10YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in10XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in10C(img,c0,c1,c) cimg_for_in10XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for10x10(img,x,y,z,c,I,T) \ - cimg_for10((img)._height,y) for (int x = 0, \ - _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = (T)(img)(0,_p4##y,z,c)), \ - (I[10] = I[11] = I[12] = I[13] = I[14] = (T)(img)(0,_p3##y,z,c)), \ - (I[20] = I[21] = I[22] = I[23] = I[24] = (T)(img)(0,_p2##y,z,c)), \ - (I[30] = I[31] = I[32] = I[33] = I[34] = (T)(img)(0,_p1##y,z,c)), \ - (I[40] = I[41] = I[42] = I[43] = I[44] = (T)(img)(0,y,z,c)), \ - (I[50] = I[51] = I[52] = I[53] = I[54] = (T)(img)(0,_n1##y,z,c)), \ - (I[60] = I[61] = I[62] = I[63] = I[64] = (T)(img)(0,_n2##y,z,c)), \ - (I[70] = I[71] = I[72] = I[73] = I[74] = (T)(img)(0,_n3##y,z,c)), \ - (I[80] = I[81] = I[82] = I[83] = I[84] = (T)(img)(0,_n4##y,z,c)), \ - (I[90] = I[91] = I[92] = I[93] = I[94] = (T)(img)(0,_n5##y,z,c)), \ - (I[5] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[15] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[25] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[35] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[45] = (T)(img)(_n1##x,y,z,c)), \ - (I[55] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[65] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[75] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[85] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[95] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[6] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[16] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[26] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[36] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[46] = (T)(img)(_n2##x,y,z,c)), \ - (I[56] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[66] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[76] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[86] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[96] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[7] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[17] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[27] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[37] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[47] = (T)(img)(_n3##x,y,z,c)), \ - (I[57] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[67] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[77] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[87] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[97] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[8] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[18] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[28] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[38] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[48] = (T)(img)(_n4##x,y,z,c)), \ - (I[58] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[68] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[78] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[88] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[98] = (T)(img)(_n4##x,_n5##y,z,c)), \ - 5>=((img)._width)?(img).width() - 1:5); \ - (_n5##x<(img).width() && ( \ - (I[9] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[19] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[29] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[39] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[49] = (T)(img)(_n5##x,y,z,c)), \ - (I[59] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[69] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[79] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[89] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[99] = (T)(img)(_n5##x,_n5##y,z,c)),1)) || \ - _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], \ - I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], \ - I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], \ - I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], \ - I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], \ - I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], \ - I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], \ - I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], \ - I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], \ - I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], \ - _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x) - -#define cimg_for_in10x10(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in10((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = (int)( \ - (I[0] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[10] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[20] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[30] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[40] = (T)(img)(_p4##x,y,z,c)), \ - (I[50] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[60] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[70] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[80] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[90] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[1] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[11] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[21] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[31] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[41] = (T)(img)(_p3##x,y,z,c)), \ - (I[51] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[61] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[71] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[81] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[91] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[2] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[12] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[22] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[32] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[42] = (T)(img)(_p2##x,y,z,c)), \ - (I[52] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[62] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[72] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[82] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[92] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[3] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[13] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[23] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[33] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[43] = (T)(img)(_p1##x,y,z,c)), \ - (I[53] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[63] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[73] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[83] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[93] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[4] = (T)(img)(x,_p4##y,z,c)), \ - (I[14] = (T)(img)(x,_p3##y,z,c)), \ - (I[24] = (T)(img)(x,_p2##y,z,c)), \ - (I[34] = (T)(img)(x,_p1##y,z,c)), \ - (I[44] = (T)(img)(x,y,z,c)), \ - (I[54] = (T)(img)(x,_n1##y,z,c)), \ - (I[64] = (T)(img)(x,_n2##y,z,c)), \ - (I[74] = (T)(img)(x,_n3##y,z,c)), \ - (I[84] = (T)(img)(x,_n4##y,z,c)), \ - (I[94] = (T)(img)(x,_n5##y,z,c)), \ - (I[5] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[15] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[25] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[35] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[45] = (T)(img)(_n1##x,y,z,c)), \ - (I[55] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[65] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[75] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[85] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[95] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[6] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[16] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[26] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[36] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[46] = (T)(img)(_n2##x,y,z,c)), \ - (I[56] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[66] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[76] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[86] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[96] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[7] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[17] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[27] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[37] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[47] = (T)(img)(_n3##x,y,z,c)), \ - (I[57] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[67] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[77] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[87] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[97] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[8] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[18] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[28] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[38] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[48] = (T)(img)(_n4##x,y,z,c)), \ - (I[58] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[68] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[78] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[88] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[98] = (T)(img)(_n4##x,_n5##y,z,c)), \ - x + 5>=(img).width()?(img).width() - 1:x + 5); \ - x<=(int)(x1) && ((_n5##x<(img).width() && ( \ - (I[9] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[19] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[29] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[39] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[49] = (T)(img)(_n5##x,y,z,c)), \ - (I[59] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[69] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[79] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[89] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[99] = (T)(img)(_n5##x,_n5##y,z,c)),1)) || \ - _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], \ - I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], \ - I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], \ - I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], \ - I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], \ - I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], \ - I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], \ - I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], \ - I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], \ - I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], \ - _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x) - -#define cimg_get10x10(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p4##x,_p4##y,z,c), I[1] = (T)(img)(_p3##x,_p4##y,z,c), I[2] = (T)(img)(_p2##x,_p4##y,z,c), I[3] = (T)(img)(_p1##x,_p4##y,z,c), I[4] = (T)(img)(x,_p4##y,z,c), I[5] = (T)(img)(_n1##x,_p4##y,z,c), I[6] = (T)(img)(_n2##x,_p4##y,z,c), I[7] = (T)(img)(_n3##x,_p4##y,z,c), I[8] = (T)(img)(_n4##x,_p4##y,z,c), I[9] = (T)(img)(_n5##x,_p4##y,z,c), \ - I[10] = (T)(img)(_p4##x,_p3##y,z,c), I[11] = (T)(img)(_p3##x,_p3##y,z,c), I[12] = (T)(img)(_p2##x,_p3##y,z,c), I[13] = (T)(img)(_p1##x,_p3##y,z,c), I[14] = (T)(img)(x,_p3##y,z,c), I[15] = (T)(img)(_n1##x,_p3##y,z,c), I[16] = (T)(img)(_n2##x,_p3##y,z,c), I[17] = (T)(img)(_n3##x,_p3##y,z,c), I[18] = (T)(img)(_n4##x,_p3##y,z,c), I[19] = (T)(img)(_n5##x,_p3##y,z,c), \ - I[20] = (T)(img)(_p4##x,_p2##y,z,c), I[21] = (T)(img)(_p3##x,_p2##y,z,c), I[22] = (T)(img)(_p2##x,_p2##y,z,c), I[23] = (T)(img)(_p1##x,_p2##y,z,c), I[24] = (T)(img)(x,_p2##y,z,c), I[25] = (T)(img)(_n1##x,_p2##y,z,c), I[26] = (T)(img)(_n2##x,_p2##y,z,c), I[27] = (T)(img)(_n3##x,_p2##y,z,c), I[28] = (T)(img)(_n4##x,_p2##y,z,c), I[29] = (T)(img)(_n5##x,_p2##y,z,c), \ - I[30] = (T)(img)(_p4##x,_p1##y,z,c), I[31] = (T)(img)(_p3##x,_p1##y,z,c), I[32] = (T)(img)(_p2##x,_p1##y,z,c), I[33] = (T)(img)(_p1##x,_p1##y,z,c), I[34] = (T)(img)(x,_p1##y,z,c), I[35] = (T)(img)(_n1##x,_p1##y,z,c), I[36] = (T)(img)(_n2##x,_p1##y,z,c), I[37] = (T)(img)(_n3##x,_p1##y,z,c), I[38] = (T)(img)(_n4##x,_p1##y,z,c), I[39] = (T)(img)(_n5##x,_p1##y,z,c), \ - I[40] = (T)(img)(_p4##x,y,z,c), I[41] = (T)(img)(_p3##x,y,z,c), I[42] = (T)(img)(_p2##x,y,z,c), I[43] = (T)(img)(_p1##x,y,z,c), I[44] = (T)(img)(x,y,z,c), I[45] = (T)(img)(_n1##x,y,z,c), I[46] = (T)(img)(_n2##x,y,z,c), I[47] = (T)(img)(_n3##x,y,z,c), I[48] = (T)(img)(_n4##x,y,z,c), I[49] = (T)(img)(_n5##x,y,z,c), \ - I[50] = (T)(img)(_p4##x,_n1##y,z,c), I[51] = (T)(img)(_p3##x,_n1##y,z,c), I[52] = (T)(img)(_p2##x,_n1##y,z,c), I[53] = (T)(img)(_p1##x,_n1##y,z,c), I[54] = (T)(img)(x,_n1##y,z,c), I[55] = (T)(img)(_n1##x,_n1##y,z,c), I[56] = (T)(img)(_n2##x,_n1##y,z,c), I[57] = (T)(img)(_n3##x,_n1##y,z,c), I[58] = (T)(img)(_n4##x,_n1##y,z,c), I[59] = (T)(img)(_n5##x,_n1##y,z,c), \ - I[60] = (T)(img)(_p4##x,_n2##y,z,c), I[61] = (T)(img)(_p3##x,_n2##y,z,c), I[62] = (T)(img)(_p2##x,_n2##y,z,c), I[63] = (T)(img)(_p1##x,_n2##y,z,c), I[64] = (T)(img)(x,_n2##y,z,c), I[65] = (T)(img)(_n1##x,_n2##y,z,c), I[66] = (T)(img)(_n2##x,_n2##y,z,c), I[67] = (T)(img)(_n3##x,_n2##y,z,c), I[68] = (T)(img)(_n4##x,_n2##y,z,c), I[69] = (T)(img)(_n5##x,_n2##y,z,c), \ - I[70] = (T)(img)(_p4##x,_n3##y,z,c), I[71] = (T)(img)(_p3##x,_n3##y,z,c), I[72] = (T)(img)(_p2##x,_n3##y,z,c), I[73] = (T)(img)(_p1##x,_n3##y,z,c), I[74] = (T)(img)(x,_n3##y,z,c), I[75] = (T)(img)(_n1##x,_n3##y,z,c), I[76] = (T)(img)(_n2##x,_n3##y,z,c), I[77] = (T)(img)(_n3##x,_n3##y,z,c), I[78] = (T)(img)(_n4##x,_n3##y,z,c), I[79] = (T)(img)(_n5##x,_n3##y,z,c), \ - I[80] = (T)(img)(_p4##x,_n4##y,z,c), I[81] = (T)(img)(_p3##x,_n4##y,z,c), I[82] = (T)(img)(_p2##x,_n4##y,z,c), I[83] = (T)(img)(_p1##x,_n4##y,z,c), I[84] = (T)(img)(x,_n4##y,z,c), I[85] = (T)(img)(_n1##x,_n4##y,z,c), I[86] = (T)(img)(_n2##x,_n4##y,z,c), I[87] = (T)(img)(_n3##x,_n4##y,z,c), I[88] = (T)(img)(_n4##x,_n4##y,z,c), I[89] = (T)(img)(_n5##x,_n4##y,z,c), \ - I[90] = (T)(img)(_p4##x,_n5##y,z,c), I[91] = (T)(img)(_p3##x,_n5##y,z,c), I[92] = (T)(img)(_p2##x,_n5##y,z,c), I[93] = (T)(img)(_p1##x,_n5##y,z,c), I[94] = (T)(img)(x,_n5##y,z,c), I[95] = (T)(img)(_n1##x,_n5##y,z,c), I[96] = (T)(img)(_n2##x,_n5##y,z,c), I[97] = (T)(img)(_n3##x,_n5##y,z,c), I[98] = (T)(img)(_n4##x,_n5##y,z,c), I[99] = (T)(img)(_n5##x,_n5##y,z,c); - -// Define 11x11 loop macros -//------------------------- -#define cimg_for11(bound,i) for (int i = 0, \ - _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5; \ - _n5##i<(int)(bound) || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i) - -#define cimg_for11X(img,x) cimg_for11((img)._width,x) -#define cimg_for11Y(img,y) cimg_for11((img)._height,y) -#define cimg_for11Z(img,z) cimg_for11((img)._depth,z) -#define cimg_for11C(img,c) cimg_for11((img)._spectrum,c) -#define cimg_for11XY(img,x,y) cimg_for11Y(img,y) cimg_for11X(img,x) -#define cimg_for11XZ(img,x,z) cimg_for11Z(img,z) cimg_for11X(img,x) -#define cimg_for11XC(img,x,c) cimg_for11C(img,c) cimg_for11X(img,x) -#define cimg_for11YZ(img,y,z) cimg_for11Z(img,z) cimg_for11Y(img,y) -#define cimg_for11YC(img,y,c) cimg_for11C(img,c) cimg_for11Y(img,y) -#define cimg_for11ZC(img,z,c) cimg_for11C(img,c) cimg_for11Z(img,z) -#define cimg_for11XYZ(img,x,y,z) cimg_for11Z(img,z) cimg_for11XY(img,x,y) -#define cimg_for11XZC(img,x,z,c) cimg_for11C(img,c) cimg_for11XZ(img,x,z) -#define cimg_for11YZC(img,y,z,c) cimg_for11C(img,c) cimg_for11YZ(img,y,z) -#define cimg_for11XYZC(img,x,y,z,c) cimg_for11C(img,c) cimg_for11XYZ(img,x,y,z) - -#define cimg_for_in11(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5; \ - i<=(int)(i1) && (_n5##i<(int)(bound) || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i) - -#define cimg_for_in11X(img,x0,x1,x) cimg_for_in11((img)._width,x0,x1,x) -#define cimg_for_in11Y(img,y0,y1,y) cimg_for_in11((img)._height,y0,y1,y) -#define cimg_for_in11Z(img,z0,z1,z) cimg_for_in11((img)._depth,z0,z1,z) -#define cimg_for_in11C(img,c0,c1,c) cimg_for_in11((img)._spectrum,c0,c1,c) -#define cimg_for_in11XY(img,x0,y0,x1,y1,x,y) cimg_for_in11Y(img,y0,y1,y) cimg_for_in11X(img,x0,x1,x) -#define cimg_for_in11XZ(img,x0,z0,x1,z1,x,z) cimg_for_in11Z(img,z0,z1,z) cimg_for_in11X(img,x0,x1,x) -#define cimg_for_in11XC(img,x0,c0,x1,c1,x,c) cimg_for_in11C(img,c0,c1,c) cimg_for_in11X(img,x0,x1,x) -#define cimg_for_in11YZ(img,y0,z0,y1,z1,y,z) cimg_for_in11Z(img,z0,z1,z) cimg_for_in11Y(img,y0,y1,y) -#define cimg_for_in11YC(img,y0,c0,y1,c1,y,c) cimg_for_in11C(img,c0,c1,c) cimg_for_in11Y(img,y0,y1,y) -#define cimg_for_in11ZC(img,z0,c0,z1,c1,z,c) cimg_for_in11C(img,c0,c1,c) cimg_for_in11Z(img,z0,z1,z) -#define cimg_for_in11XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in11Z(img,z0,z1,z) cimg_for_in11XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in11XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in11C(img,c0,c1,c) cimg_for_in11XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in11YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in11C(img,c0,c1,c) cimg_for_in11YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in11XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in11C(img,c0,c1,c) cimg_for_in11XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for11x11(img,x,y,z,c,I,T) \ - cimg_for11((img)._height,y) for (int x = 0, \ - _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = (T)(img)(0,_p5##y,z,c)), \ - (I[11] = I[12] = I[13] = I[14] = I[15] = I[16] = (T)(img)(0,_p4##y,z,c)), \ - (I[22] = I[23] = I[24] = I[25] = I[26] = I[27] = (T)(img)(0,_p3##y,z,c)), \ - (I[33] = I[34] = I[35] = I[36] = I[37] = I[38] = (T)(img)(0,_p2##y,z,c)), \ - (I[44] = I[45] = I[46] = I[47] = I[48] = I[49] = (T)(img)(0,_p1##y,z,c)), \ - (I[55] = I[56] = I[57] = I[58] = I[59] = I[60] = (T)(img)(0,y,z,c)), \ - (I[66] = I[67] = I[68] = I[69] = I[70] = I[71] = (T)(img)(0,_n1##y,z,c)), \ - (I[77] = I[78] = I[79] = I[80] = I[81] = I[82] = (T)(img)(0,_n2##y,z,c)), \ - (I[88] = I[89] = I[90] = I[91] = I[92] = I[93] = (T)(img)(0,_n3##y,z,c)), \ - (I[99] = I[100] = I[101] = I[102] = I[103] = I[104] = (T)(img)(0,_n4##y,z,c)), \ - (I[110] = I[111] = I[112] = I[113] = I[114] = I[115] = (T)(img)(0,_n5##y,z,c)), \ - (I[6] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[17] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[28] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[39] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[50] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[61] = (T)(img)(_n1##x,y,z,c)), \ - (I[72] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[83] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[94] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[105] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[116] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[7] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[18] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[29] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[40] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[51] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[62] = (T)(img)(_n2##x,y,z,c)), \ - (I[73] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[84] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[95] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[106] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[117] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[8] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[19] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[30] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[41] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[52] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[63] = (T)(img)(_n3##x,y,z,c)), \ - (I[74] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[85] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[96] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[107] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[118] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[9] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[20] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[31] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[42] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[53] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[64] = (T)(img)(_n4##x,y,z,c)), \ - (I[75] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[86] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[97] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[108] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[119] = (T)(img)(_n4##x,_n5##y,z,c)), \ - 5>=((img)._width)?(img).width() - 1:5); \ - (_n5##x<(img).width() && ( \ - (I[10] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[21] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[32] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[43] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[54] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[65] = (T)(img)(_n5##x,y,z,c)), \ - (I[76] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[87] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[98] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[109] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[120] = (T)(img)(_n5##x,_n5##y,z,c)),1)) || \ - _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], \ - I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], \ - I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], \ - I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], \ - I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], \ - I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], \ - I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], \ - I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], \ - I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], \ - I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], \ - I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], \ - _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x) - -#define cimg_for_in11x11(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in11((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = (int)( \ - (I[0] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[11] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[22] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[33] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[44] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[55] = (T)(img)(_p5##x,y,z,c)), \ - (I[66] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[77] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[88] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[99] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[110] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[1] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[12] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[23] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[34] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[45] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[56] = (T)(img)(_p4##x,y,z,c)), \ - (I[67] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[78] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[89] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[100] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[111] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[2] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[13] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[24] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[35] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[46] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[57] = (T)(img)(_p3##x,y,z,c)), \ - (I[68] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[79] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[90] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[101] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[112] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[3] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[14] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[25] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[36] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[47] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[58] = (T)(img)(_p2##x,y,z,c)), \ - (I[69] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[80] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[91] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[102] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[113] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[4] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[15] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[26] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[37] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[48] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[59] = (T)(img)(_p1##x,y,z,c)), \ - (I[70] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[81] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[92] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[103] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[114] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[5] = (T)(img)(x,_p5##y,z,c)), \ - (I[16] = (T)(img)(x,_p4##y,z,c)), \ - (I[27] = (T)(img)(x,_p3##y,z,c)), \ - (I[38] = (T)(img)(x,_p2##y,z,c)), \ - (I[49] = (T)(img)(x,_p1##y,z,c)), \ - (I[60] = (T)(img)(x,y,z,c)), \ - (I[71] = (T)(img)(x,_n1##y,z,c)), \ - (I[82] = (T)(img)(x,_n2##y,z,c)), \ - (I[93] = (T)(img)(x,_n3##y,z,c)), \ - (I[104] = (T)(img)(x,_n4##y,z,c)), \ - (I[115] = (T)(img)(x,_n5##y,z,c)), \ - (I[6] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[17] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[28] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[39] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[50] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[61] = (T)(img)(_n1##x,y,z,c)), \ - (I[72] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[83] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[94] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[105] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[116] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[7] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[18] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[29] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[40] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[51] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[62] = (T)(img)(_n2##x,y,z,c)), \ - (I[73] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[84] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[95] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[106] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[117] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[8] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[19] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[30] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[41] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[52] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[63] = (T)(img)(_n3##x,y,z,c)), \ - (I[74] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[85] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[96] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[107] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[118] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[9] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[20] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[31] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[42] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[53] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[64] = (T)(img)(_n4##x,y,z,c)), \ - (I[75] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[86] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[97] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[108] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[119] = (T)(img)(_n4##x,_n5##y,z,c)), \ - x + 5>=(img).width()?(img).width() - 1:x + 5); \ - x<=(int)(x1) && ((_n5##x<(img).width() && ( \ - (I[10] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[21] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[32] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[43] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[54] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[65] = (T)(img)(_n5##x,y,z,c)), \ - (I[76] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[87] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[98] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[109] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[120] = (T)(img)(_n5##x,_n5##y,z,c)),1)) || \ - _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], \ - I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], \ - I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], \ - I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], \ - I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], \ - I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], \ - I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], \ - I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], \ - I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], \ - I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], \ - I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], \ - _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x) - -#define cimg_get11x11(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p5##x,_p5##y,z,c), I[1] = (T)(img)(_p4##x,_p5##y,z,c), I[2] = (T)(img)(_p3##x,_p5##y,z,c), I[3] = (T)(img)(_p2##x,_p5##y,z,c), I[4] = (T)(img)(_p1##x,_p5##y,z,c), I[5] = (T)(img)(x,_p5##y,z,c), I[6] = (T)(img)(_n1##x,_p5##y,z,c), I[7] = (T)(img)(_n2##x,_p5##y,z,c), I[8] = (T)(img)(_n3##x,_p5##y,z,c), I[9] = (T)(img)(_n4##x,_p5##y,z,c), I[10] = (T)(img)(_n5##x,_p5##y,z,c), \ - I[11] = (T)(img)(_p5##x,_p4##y,z,c), I[12] = (T)(img)(_p4##x,_p4##y,z,c), I[13] = (T)(img)(_p3##x,_p4##y,z,c), I[14] = (T)(img)(_p2##x,_p4##y,z,c), I[15] = (T)(img)(_p1##x,_p4##y,z,c), I[16] = (T)(img)(x,_p4##y,z,c), I[17] = (T)(img)(_n1##x,_p4##y,z,c), I[18] = (T)(img)(_n2##x,_p4##y,z,c), I[19] = (T)(img)(_n3##x,_p4##y,z,c), I[20] = (T)(img)(_n4##x,_p4##y,z,c), I[21] = (T)(img)(_n5##x,_p4##y,z,c), \ - I[22] = (T)(img)(_p5##x,_p3##y,z,c), I[23] = (T)(img)(_p4##x,_p3##y,z,c), I[24] = (T)(img)(_p3##x,_p3##y,z,c), I[25] = (T)(img)(_p2##x,_p3##y,z,c), I[26] = (T)(img)(_p1##x,_p3##y,z,c), I[27] = (T)(img)(x,_p3##y,z,c), I[28] = (T)(img)(_n1##x,_p3##y,z,c), I[29] = (T)(img)(_n2##x,_p3##y,z,c), I[30] = (T)(img)(_n3##x,_p3##y,z,c), I[31] = (T)(img)(_n4##x,_p3##y,z,c), I[32] = (T)(img)(_n5##x,_p3##y,z,c), \ - I[33] = (T)(img)(_p5##x,_p2##y,z,c), I[34] = (T)(img)(_p4##x,_p2##y,z,c), I[35] = (T)(img)(_p3##x,_p2##y,z,c), I[36] = (T)(img)(_p2##x,_p2##y,z,c), I[37] = (T)(img)(_p1##x,_p2##y,z,c), I[38] = (T)(img)(x,_p2##y,z,c), I[39] = (T)(img)(_n1##x,_p2##y,z,c), I[40] = (T)(img)(_n2##x,_p2##y,z,c), I[41] = (T)(img)(_n3##x,_p2##y,z,c), I[42] = (T)(img)(_n4##x,_p2##y,z,c), I[43] = (T)(img)(_n5##x,_p2##y,z,c), \ - I[44] = (T)(img)(_p5##x,_p1##y,z,c), I[45] = (T)(img)(_p4##x,_p1##y,z,c), I[46] = (T)(img)(_p3##x,_p1##y,z,c), I[47] = (T)(img)(_p2##x,_p1##y,z,c), I[48] = (T)(img)(_p1##x,_p1##y,z,c), I[49] = (T)(img)(x,_p1##y,z,c), I[50] = (T)(img)(_n1##x,_p1##y,z,c), I[51] = (T)(img)(_n2##x,_p1##y,z,c), I[52] = (T)(img)(_n3##x,_p1##y,z,c), I[53] = (T)(img)(_n4##x,_p1##y,z,c), I[54] = (T)(img)(_n5##x,_p1##y,z,c), \ - I[55] = (T)(img)(_p5##x,y,z,c), I[56] = (T)(img)(_p4##x,y,z,c), I[57] = (T)(img)(_p3##x,y,z,c), I[58] = (T)(img)(_p2##x,y,z,c), I[59] = (T)(img)(_p1##x,y,z,c), I[60] = (T)(img)(x,y,z,c), I[61] = (T)(img)(_n1##x,y,z,c), I[62] = (T)(img)(_n2##x,y,z,c), I[63] = (T)(img)(_n3##x,y,z,c), I[64] = (T)(img)(_n4##x,y,z,c), I[65] = (T)(img)(_n5##x,y,z,c), \ - I[66] = (T)(img)(_p5##x,_n1##y,z,c), I[67] = (T)(img)(_p4##x,_n1##y,z,c), I[68] = (T)(img)(_p3##x,_n1##y,z,c), I[69] = (T)(img)(_p2##x,_n1##y,z,c), I[70] = (T)(img)(_p1##x,_n1##y,z,c), I[71] = (T)(img)(x,_n1##y,z,c), I[72] = (T)(img)(_n1##x,_n1##y,z,c), I[73] = (T)(img)(_n2##x,_n1##y,z,c), I[74] = (T)(img)(_n3##x,_n1##y,z,c), I[75] = (T)(img)(_n4##x,_n1##y,z,c), I[76] = (T)(img)(_n5##x,_n1##y,z,c), \ - I[77] = (T)(img)(_p5##x,_n2##y,z,c), I[78] = (T)(img)(_p4##x,_n2##y,z,c), I[79] = (T)(img)(_p3##x,_n2##y,z,c), I[80] = (T)(img)(_p2##x,_n2##y,z,c), I[81] = (T)(img)(_p1##x,_n2##y,z,c), I[82] = (T)(img)(x,_n2##y,z,c), I[83] = (T)(img)(_n1##x,_n2##y,z,c), I[84] = (T)(img)(_n2##x,_n2##y,z,c), I[85] = (T)(img)(_n3##x,_n2##y,z,c), I[86] = (T)(img)(_n4##x,_n2##y,z,c), I[87] = (T)(img)(_n5##x,_n2##y,z,c), \ - I[88] = (T)(img)(_p5##x,_n3##y,z,c), I[89] = (T)(img)(_p4##x,_n3##y,z,c), I[90] = (T)(img)(_p3##x,_n3##y,z,c), I[91] = (T)(img)(_p2##x,_n3##y,z,c), I[92] = (T)(img)(_p1##x,_n3##y,z,c), I[93] = (T)(img)(x,_n3##y,z,c), I[94] = (T)(img)(_n1##x,_n3##y,z,c), I[95] = (T)(img)(_n2##x,_n3##y,z,c), I[96] = (T)(img)(_n3##x,_n3##y,z,c), I[97] = (T)(img)(_n4##x,_n3##y,z,c), I[98] = (T)(img)(_n5##x,_n3##y,z,c), \ - I[99] = (T)(img)(_p5##x,_n4##y,z,c), I[100] = (T)(img)(_p4##x,_n4##y,z,c), I[101] = (T)(img)(_p3##x,_n4##y,z,c), I[102] = (T)(img)(_p2##x,_n4##y,z,c), I[103] = (T)(img)(_p1##x,_n4##y,z,c), I[104] = (T)(img)(x,_n4##y,z,c), I[105] = (T)(img)(_n1##x,_n4##y,z,c), I[106] = (T)(img)(_n2##x,_n4##y,z,c), I[107] = (T)(img)(_n3##x,_n4##y,z,c), I[108] = (T)(img)(_n4##x,_n4##y,z,c), I[109] = (T)(img)(_n5##x,_n4##y,z,c), \ - I[110] = (T)(img)(_p5##x,_n5##y,z,c), I[111] = (T)(img)(_p4##x,_n5##y,z,c), I[112] = (T)(img)(_p3##x,_n5##y,z,c), I[113] = (T)(img)(_p2##x,_n5##y,z,c), I[114] = (T)(img)(_p1##x,_n5##y,z,c), I[115] = (T)(img)(x,_n5##y,z,c), I[116] = (T)(img)(_n1##x,_n5##y,z,c), I[117] = (T)(img)(_n2##x,_n5##y,z,c), I[118] = (T)(img)(_n3##x,_n5##y,z,c), I[119] = (T)(img)(_n4##x,_n5##y,z,c), I[120] = (T)(img)(_n5##x,_n5##y,z,c); - -// Define 12x12 loop macros -//------------------------- -#define cimg_for12(bound,i) for (int i = 0, \ - _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6; \ - _n6##i<(int)(bound) || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i) - -#define cimg_for12X(img,x) cimg_for12((img)._width,x) -#define cimg_for12Y(img,y) cimg_for12((img)._height,y) -#define cimg_for12Z(img,z) cimg_for12((img)._depth,z) -#define cimg_for12C(img,c) cimg_for12((img)._spectrum,c) -#define cimg_for12XY(img,x,y) cimg_for12Y(img,y) cimg_for12X(img,x) -#define cimg_for12XZ(img,x,z) cimg_for12Z(img,z) cimg_for12X(img,x) -#define cimg_for12XC(img,x,c) cimg_for12C(img,c) cimg_for12X(img,x) -#define cimg_for12YZ(img,y,z) cimg_for12Z(img,z) cimg_for12Y(img,y) -#define cimg_for12YC(img,y,c) cimg_for12C(img,c) cimg_for12Y(img,y) -#define cimg_for12ZC(img,z,c) cimg_for12C(img,c) cimg_for12Z(img,z) -#define cimg_for12XYZ(img,x,y,z) cimg_for12Z(img,z) cimg_for12XY(img,x,y) -#define cimg_for12XZC(img,x,z,c) cimg_for12C(img,c) cimg_for12XZ(img,x,z) -#define cimg_for12YZC(img,y,z,c) cimg_for12C(img,c) cimg_for12YZ(img,y,z) -#define cimg_for12XYZC(img,x,y,z,c) cimg_for12C(img,c) cimg_for12XYZ(img,x,y,z) - -#define cimg_for_in12(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6; \ - i<=(int)(i1) && (_n6##i<(int)(bound) || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i) - -#define cimg_for_in12X(img,x0,x1,x) cimg_for_in12((img)._width,x0,x1,x) -#define cimg_for_in12Y(img,y0,y1,y) cimg_for_in12((img)._height,y0,y1,y) -#define cimg_for_in12Z(img,z0,z1,z) cimg_for_in12((img)._depth,z0,z1,z) -#define cimg_for_in12C(img,c0,c1,c) cimg_for_in12((img)._spectrum,c0,c1,c) -#define cimg_for_in12XY(img,x0,y0,x1,y1,x,y) cimg_for_in12Y(img,y0,y1,y) cimg_for_in12X(img,x0,x1,x) -#define cimg_for_in12XZ(img,x0,z0,x1,z1,x,z) cimg_for_in12Z(img,z0,z1,z) cimg_for_in12X(img,x0,x1,x) -#define cimg_for_in12XC(img,x0,c0,x1,c1,x,c) cimg_for_in12C(img,c0,c1,c) cimg_for_in12X(img,x0,x1,x) -#define cimg_for_in12YZ(img,y0,z0,y1,z1,y,z) cimg_for_in12Z(img,z0,z1,z) cimg_for_in12Y(img,y0,y1,y) -#define cimg_for_in12YC(img,y0,c0,y1,c1,y,c) cimg_for_in12C(img,c0,c1,c) cimg_for_in12Y(img,y0,y1,y) -#define cimg_for_in12ZC(img,z0,c0,z1,c1,z,c) cimg_for_in12C(img,c0,c1,c) cimg_for_in12Z(img,z0,z1,z) -#define cimg_for_in12XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in12Z(img,z0,z1,z) cimg_for_in12XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in12XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in12C(img,c0,c1,c) cimg_for_in12XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in12YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in12C(img,c0,c1,c) cimg_for_in12YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in12XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in12C(img,c0,c1,c) cimg_for_in12XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for12x12(img,x,y,z,c,I,T) \ - cimg_for12((img)._height,y) for (int x = 0, \ - _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = (T)(img)(0,_p5##y,z,c)), \ - (I[12] = I[13] = I[14] = I[15] = I[16] = I[17] = (T)(img)(0,_p4##y,z,c)), \ - (I[24] = I[25] = I[26] = I[27] = I[28] = I[29] = (T)(img)(0,_p3##y,z,c)), \ - (I[36] = I[37] = I[38] = I[39] = I[40] = I[41] = (T)(img)(0,_p2##y,z,c)), \ - (I[48] = I[49] = I[50] = I[51] = I[52] = I[53] = (T)(img)(0,_p1##y,z,c)), \ - (I[60] = I[61] = I[62] = I[63] = I[64] = I[65] = (T)(img)(0,y,z,c)), \ - (I[72] = I[73] = I[74] = I[75] = I[76] = I[77] = (T)(img)(0,_n1##y,z,c)), \ - (I[84] = I[85] = I[86] = I[87] = I[88] = I[89] = (T)(img)(0,_n2##y,z,c)), \ - (I[96] = I[97] = I[98] = I[99] = I[100] = I[101] = (T)(img)(0,_n3##y,z,c)), \ - (I[108] = I[109] = I[110] = I[111] = I[112] = I[113] = (T)(img)(0,_n4##y,z,c)), \ - (I[120] = I[121] = I[122] = I[123] = I[124] = I[125] = (T)(img)(0,_n5##y,z,c)), \ - (I[132] = I[133] = I[134] = I[135] = I[136] = I[137] = (T)(img)(0,_n6##y,z,c)), \ - (I[6] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[18] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[30] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[42] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[54] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[66] = (T)(img)(_n1##x,y,z,c)), \ - (I[78] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[90] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[102] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[114] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[126] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[138] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[7] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[19] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[31] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[43] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[55] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[67] = (T)(img)(_n2##x,y,z,c)), \ - (I[79] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[91] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[103] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[115] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[127] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[139] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[8] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[20] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[32] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[44] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[56] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[68] = (T)(img)(_n3##x,y,z,c)), \ - (I[80] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[92] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[104] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[116] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[128] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[140] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[9] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[21] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[33] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[45] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[57] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[69] = (T)(img)(_n4##x,y,z,c)), \ - (I[81] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[93] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[105] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[117] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[129] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[141] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[10] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[22] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[34] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[46] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[58] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[70] = (T)(img)(_n5##x,y,z,c)), \ - (I[82] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[94] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[106] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[118] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[130] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[142] = (T)(img)(_n5##x,_n6##y,z,c)), \ - 6>=((img)._width)?(img).width() - 1:6); \ - (_n6##x<(img).width() && ( \ - (I[11] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[23] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[35] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[47] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[59] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[71] = (T)(img)(_n6##x,y,z,c)), \ - (I[83] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[95] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[107] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[119] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[131] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[143] = (T)(img)(_n6##x,_n6##y,z,c)),1)) || \ - _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], \ - I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \ - I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], \ - I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], \ - I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], \ - I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], \ - I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], \ - I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], \ - I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], \ - I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], \ - I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], \ - I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], \ - _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x) - -#define cimg_for_in12x12(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in12((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = (int)( \ - (I[0] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[12] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[24] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[36] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[48] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[60] = (T)(img)(_p5##x,y,z,c)), \ - (I[72] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[84] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[96] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[108] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[120] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[132] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[1] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[13] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[25] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[37] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[49] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[61] = (T)(img)(_p4##x,y,z,c)), \ - (I[73] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[85] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[97] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[109] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[121] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[133] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[2] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[14] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[26] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[38] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[50] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[62] = (T)(img)(_p3##x,y,z,c)), \ - (I[74] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[86] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[98] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[110] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[122] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[134] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[3] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[15] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[27] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[39] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[51] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[63] = (T)(img)(_p2##x,y,z,c)), \ - (I[75] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[87] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[99] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[111] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[123] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[135] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[4] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[16] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[28] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[40] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[52] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[64] = (T)(img)(_p1##x,y,z,c)), \ - (I[76] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[88] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[100] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[112] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[124] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[136] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[5] = (T)(img)(x,_p5##y,z,c)), \ - (I[17] = (T)(img)(x,_p4##y,z,c)), \ - (I[29] = (T)(img)(x,_p3##y,z,c)), \ - (I[41] = (T)(img)(x,_p2##y,z,c)), \ - (I[53] = (T)(img)(x,_p1##y,z,c)), \ - (I[65] = (T)(img)(x,y,z,c)), \ - (I[77] = (T)(img)(x,_n1##y,z,c)), \ - (I[89] = (T)(img)(x,_n2##y,z,c)), \ - (I[101] = (T)(img)(x,_n3##y,z,c)), \ - (I[113] = (T)(img)(x,_n4##y,z,c)), \ - (I[125] = (T)(img)(x,_n5##y,z,c)), \ - (I[137] = (T)(img)(x,_n6##y,z,c)), \ - (I[6] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[18] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[30] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[42] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[54] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[66] = (T)(img)(_n1##x,y,z,c)), \ - (I[78] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[90] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[102] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[114] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[126] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[138] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[7] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[19] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[31] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[43] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[55] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[67] = (T)(img)(_n2##x,y,z,c)), \ - (I[79] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[91] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[103] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[115] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[127] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[139] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[8] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[20] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[32] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[44] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[56] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[68] = (T)(img)(_n3##x,y,z,c)), \ - (I[80] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[92] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[104] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[116] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[128] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[140] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[9] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[21] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[33] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[45] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[57] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[69] = (T)(img)(_n4##x,y,z,c)), \ - (I[81] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[93] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[105] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[117] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[129] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[141] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[10] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[22] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[34] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[46] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[58] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[70] = (T)(img)(_n5##x,y,z,c)), \ - (I[82] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[94] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[106] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[118] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[130] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[142] = (T)(img)(_n5##x,_n6##y,z,c)), \ - x + 6>=(img).width()?(img).width() - 1:x + 6); \ - x<=(int)(x1) && ((_n6##x<(img).width() && ( \ - (I[11] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[23] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[35] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[47] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[59] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[71] = (T)(img)(_n6##x,y,z,c)), \ - (I[83] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[95] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[107] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[119] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[131] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[143] = (T)(img)(_n6##x,_n6##y,z,c)),1)) || \ - _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], \ - I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \ - I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], \ - I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], \ - I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], \ - I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], \ - I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], \ - I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], \ - I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], \ - I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], \ - I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], \ - I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], \ - _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x) - -#define cimg_get12x12(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p5##x,_p5##y,z,c), I[1] = (T)(img)(_p4##x,_p5##y,z,c), I[2] = (T)(img)(_p3##x,_p5##y,z,c), I[3] = (T)(img)(_p2##x,_p5##y,z,c), I[4] = (T)(img)(_p1##x,_p5##y,z,c), I[5] = (T)(img)(x,_p5##y,z,c), I[6] = (T)(img)(_n1##x,_p5##y,z,c), I[7] = (T)(img)(_n2##x,_p5##y,z,c), I[8] = (T)(img)(_n3##x,_p5##y,z,c), I[9] = (T)(img)(_n4##x,_p5##y,z,c), I[10] = (T)(img)(_n5##x,_p5##y,z,c), I[11] = (T)(img)(_n6##x,_p5##y,z,c), \ - I[12] = (T)(img)(_p5##x,_p4##y,z,c), I[13] = (T)(img)(_p4##x,_p4##y,z,c), I[14] = (T)(img)(_p3##x,_p4##y,z,c), I[15] = (T)(img)(_p2##x,_p4##y,z,c), I[16] = (T)(img)(_p1##x,_p4##y,z,c), I[17] = (T)(img)(x,_p4##y,z,c), I[18] = (T)(img)(_n1##x,_p4##y,z,c), I[19] = (T)(img)(_n2##x,_p4##y,z,c), I[20] = (T)(img)(_n3##x,_p4##y,z,c), I[21] = (T)(img)(_n4##x,_p4##y,z,c), I[22] = (T)(img)(_n5##x,_p4##y,z,c), I[23] = (T)(img)(_n6##x,_p4##y,z,c), \ - I[24] = (T)(img)(_p5##x,_p3##y,z,c), I[25] = (T)(img)(_p4##x,_p3##y,z,c), I[26] = (T)(img)(_p3##x,_p3##y,z,c), I[27] = (T)(img)(_p2##x,_p3##y,z,c), I[28] = (T)(img)(_p1##x,_p3##y,z,c), I[29] = (T)(img)(x,_p3##y,z,c), I[30] = (T)(img)(_n1##x,_p3##y,z,c), I[31] = (T)(img)(_n2##x,_p3##y,z,c), I[32] = (T)(img)(_n3##x,_p3##y,z,c), I[33] = (T)(img)(_n4##x,_p3##y,z,c), I[34] = (T)(img)(_n5##x,_p3##y,z,c), I[35] = (T)(img)(_n6##x,_p3##y,z,c), \ - I[36] = (T)(img)(_p5##x,_p2##y,z,c), I[37] = (T)(img)(_p4##x,_p2##y,z,c), I[38] = (T)(img)(_p3##x,_p2##y,z,c), I[39] = (T)(img)(_p2##x,_p2##y,z,c), I[40] = (T)(img)(_p1##x,_p2##y,z,c), I[41] = (T)(img)(x,_p2##y,z,c), I[42] = (T)(img)(_n1##x,_p2##y,z,c), I[43] = (T)(img)(_n2##x,_p2##y,z,c), I[44] = (T)(img)(_n3##x,_p2##y,z,c), I[45] = (T)(img)(_n4##x,_p2##y,z,c), I[46] = (T)(img)(_n5##x,_p2##y,z,c), I[47] = (T)(img)(_n6##x,_p2##y,z,c), \ - I[48] = (T)(img)(_p5##x,_p1##y,z,c), I[49] = (T)(img)(_p4##x,_p1##y,z,c), I[50] = (T)(img)(_p3##x,_p1##y,z,c), I[51] = (T)(img)(_p2##x,_p1##y,z,c), I[52] = (T)(img)(_p1##x,_p1##y,z,c), I[53] = (T)(img)(x,_p1##y,z,c), I[54] = (T)(img)(_n1##x,_p1##y,z,c), I[55] = (T)(img)(_n2##x,_p1##y,z,c), I[56] = (T)(img)(_n3##x,_p1##y,z,c), I[57] = (T)(img)(_n4##x,_p1##y,z,c), I[58] = (T)(img)(_n5##x,_p1##y,z,c), I[59] = (T)(img)(_n6##x,_p1##y,z,c), \ - I[60] = (T)(img)(_p5##x,y,z,c), I[61] = (T)(img)(_p4##x,y,z,c), I[62] = (T)(img)(_p3##x,y,z,c), I[63] = (T)(img)(_p2##x,y,z,c), I[64] = (T)(img)(_p1##x,y,z,c), I[65] = (T)(img)(x,y,z,c), I[66] = (T)(img)(_n1##x,y,z,c), I[67] = (T)(img)(_n2##x,y,z,c), I[68] = (T)(img)(_n3##x,y,z,c), I[69] = (T)(img)(_n4##x,y,z,c), I[70] = (T)(img)(_n5##x,y,z,c), I[71] = (T)(img)(_n6##x,y,z,c), \ - I[72] = (T)(img)(_p5##x,_n1##y,z,c), I[73] = (T)(img)(_p4##x,_n1##y,z,c), I[74] = (T)(img)(_p3##x,_n1##y,z,c), I[75] = (T)(img)(_p2##x,_n1##y,z,c), I[76] = (T)(img)(_p1##x,_n1##y,z,c), I[77] = (T)(img)(x,_n1##y,z,c), I[78] = (T)(img)(_n1##x,_n1##y,z,c), I[79] = (T)(img)(_n2##x,_n1##y,z,c), I[80] = (T)(img)(_n3##x,_n1##y,z,c), I[81] = (T)(img)(_n4##x,_n1##y,z,c), I[82] = (T)(img)(_n5##x,_n1##y,z,c), I[83] = (T)(img)(_n6##x,_n1##y,z,c), \ - I[84] = (T)(img)(_p5##x,_n2##y,z,c), I[85] = (T)(img)(_p4##x,_n2##y,z,c), I[86] = (T)(img)(_p3##x,_n2##y,z,c), I[87] = (T)(img)(_p2##x,_n2##y,z,c), I[88] = (T)(img)(_p1##x,_n2##y,z,c), I[89] = (T)(img)(x,_n2##y,z,c), I[90] = (T)(img)(_n1##x,_n2##y,z,c), I[91] = (T)(img)(_n2##x,_n2##y,z,c), I[92] = (T)(img)(_n3##x,_n2##y,z,c), I[93] = (T)(img)(_n4##x,_n2##y,z,c), I[94] = (T)(img)(_n5##x,_n2##y,z,c), I[95] = (T)(img)(_n6##x,_n2##y,z,c), \ - I[96] = (T)(img)(_p5##x,_n3##y,z,c), I[97] = (T)(img)(_p4##x,_n3##y,z,c), I[98] = (T)(img)(_p3##x,_n3##y,z,c), I[99] = (T)(img)(_p2##x,_n3##y,z,c), I[100] = (T)(img)(_p1##x,_n3##y,z,c), I[101] = (T)(img)(x,_n3##y,z,c), I[102] = (T)(img)(_n1##x,_n3##y,z,c), I[103] = (T)(img)(_n2##x,_n3##y,z,c), I[104] = (T)(img)(_n3##x,_n3##y,z,c), I[105] = (T)(img)(_n4##x,_n3##y,z,c), I[106] = (T)(img)(_n5##x,_n3##y,z,c), I[107] = (T)(img)(_n6##x,_n3##y,z,c), \ - I[108] = (T)(img)(_p5##x,_n4##y,z,c), I[109] = (T)(img)(_p4##x,_n4##y,z,c), I[110] = (T)(img)(_p3##x,_n4##y,z,c), I[111] = (T)(img)(_p2##x,_n4##y,z,c), I[112] = (T)(img)(_p1##x,_n4##y,z,c), I[113] = (T)(img)(x,_n4##y,z,c), I[114] = (T)(img)(_n1##x,_n4##y,z,c), I[115] = (T)(img)(_n2##x,_n4##y,z,c), I[116] = (T)(img)(_n3##x,_n4##y,z,c), I[117] = (T)(img)(_n4##x,_n4##y,z,c), I[118] = (T)(img)(_n5##x,_n4##y,z,c), I[119] = (T)(img)(_n6##x,_n4##y,z,c), \ - I[120] = (T)(img)(_p5##x,_n5##y,z,c), I[121] = (T)(img)(_p4##x,_n5##y,z,c), I[122] = (T)(img)(_p3##x,_n5##y,z,c), I[123] = (T)(img)(_p2##x,_n5##y,z,c), I[124] = (T)(img)(_p1##x,_n5##y,z,c), I[125] = (T)(img)(x,_n5##y,z,c), I[126] = (T)(img)(_n1##x,_n5##y,z,c), I[127] = (T)(img)(_n2##x,_n5##y,z,c), I[128] = (T)(img)(_n3##x,_n5##y,z,c), I[129] = (T)(img)(_n4##x,_n5##y,z,c), I[130] = (T)(img)(_n5##x,_n5##y,z,c), I[131] = (T)(img)(_n6##x,_n5##y,z,c), \ - I[132] = (T)(img)(_p5##x,_n6##y,z,c), I[133] = (T)(img)(_p4##x,_n6##y,z,c), I[134] = (T)(img)(_p3##x,_n6##y,z,c), I[135] = (T)(img)(_p2##x,_n6##y,z,c), I[136] = (T)(img)(_p1##x,_n6##y,z,c), I[137] = (T)(img)(x,_n6##y,z,c), I[138] = (T)(img)(_n1##x,_n6##y,z,c), I[139] = (T)(img)(_n2##x,_n6##y,z,c), I[140] = (T)(img)(_n3##x,_n6##y,z,c), I[141] = (T)(img)(_n4##x,_n6##y,z,c), I[142] = (T)(img)(_n5##x,_n6##y,z,c), I[143] = (T)(img)(_n6##x,_n6##y,z,c); - -// Define 13x13 loop macros -//------------------------- -#define cimg_for13(bound,i) for (int i = 0, \ - _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6; \ - _n6##i<(int)(bound) || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i) - -#define cimg_for13X(img,x) cimg_for13((img)._width,x) -#define cimg_for13Y(img,y) cimg_for13((img)._height,y) -#define cimg_for13Z(img,z) cimg_for13((img)._depth,z) -#define cimg_for13C(img,c) cimg_for13((img)._spectrum,c) -#define cimg_for13XY(img,x,y) cimg_for13Y(img,y) cimg_for13X(img,x) -#define cimg_for13XZ(img,x,z) cimg_for13Z(img,z) cimg_for13X(img,x) -#define cimg_for13XC(img,x,c) cimg_for13C(img,c) cimg_for13X(img,x) -#define cimg_for13YZ(img,y,z) cimg_for13Z(img,z) cimg_for13Y(img,y) -#define cimg_for13YC(img,y,c) cimg_for13C(img,c) cimg_for13Y(img,y) -#define cimg_for13ZC(img,z,c) cimg_for13C(img,c) cimg_for13Z(img,z) -#define cimg_for13XYZ(img,x,y,z) cimg_for13Z(img,z) cimg_for13XY(img,x,y) -#define cimg_for13XZC(img,x,z,c) cimg_for13C(img,c) cimg_for13XZ(img,x,z) -#define cimg_for13YZC(img,y,z,c) cimg_for13C(img,c) cimg_for13YZ(img,y,z) -#define cimg_for13XYZC(img,x,y,z,c) cimg_for13C(img,c) cimg_for13XYZ(img,x,y,z) - -#define cimg_for_in13(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6; \ - i<=(int)(i1) && (_n6##i<(int)(bound) || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i) - -#define cimg_for_in13X(img,x0,x1,x) cimg_for_in13((img)._width,x0,x1,x) -#define cimg_for_in13Y(img,y0,y1,y) cimg_for_in13((img)._height,y0,y1,y) -#define cimg_for_in13Z(img,z0,z1,z) cimg_for_in13((img)._depth,z0,z1,z) -#define cimg_for_in13C(img,c0,c1,c) cimg_for_in13((img)._spectrum,c0,c1,c) -#define cimg_for_in13XY(img,x0,y0,x1,y1,x,y) cimg_for_in13Y(img,y0,y1,y) cimg_for_in13X(img,x0,x1,x) -#define cimg_for_in13XZ(img,x0,z0,x1,z1,x,z) cimg_for_in13Z(img,z0,z1,z) cimg_for_in13X(img,x0,x1,x) -#define cimg_for_in13XC(img,x0,c0,x1,c1,x,c) cimg_for_in13C(img,c0,c1,c) cimg_for_in13X(img,x0,x1,x) -#define cimg_for_in13YZ(img,y0,z0,y1,z1,y,z) cimg_for_in13Z(img,z0,z1,z) cimg_for_in13Y(img,y0,y1,y) -#define cimg_for_in13YC(img,y0,c0,y1,c1,y,c) cimg_for_in13C(img,c0,c1,c) cimg_for_in13Y(img,y0,y1,y) -#define cimg_for_in13ZC(img,z0,c0,z1,c1,z,c) cimg_for_in13C(img,c0,c1,c) cimg_for_in13Z(img,z0,z1,z) -#define cimg_for_in13XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in13Z(img,z0,z1,z) cimg_for_in13XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in13XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in13C(img,c0,c1,c) cimg_for_in13XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in13YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in13C(img,c0,c1,c) cimg_for_in13YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in13XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in13C(img,c0,c1,c) cimg_for_in13XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for13x13(img,x,y,z,c,I,T) \ - cimg_for13((img)._height,y) for (int x = 0, \ - _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = (T)(img)(0,_p6##y,z,c)), \ - (I[13] = I[14] = I[15] = I[16] = I[17] = I[18] = I[19] = (T)(img)(0,_p5##y,z,c)), \ - (I[26] = I[27] = I[28] = I[29] = I[30] = I[31] = I[32] = (T)(img)(0,_p4##y,z,c)), \ - (I[39] = I[40] = I[41] = I[42] = I[43] = I[44] = I[45] = (T)(img)(0,_p3##y,z,c)), \ - (I[52] = I[53] = I[54] = I[55] = I[56] = I[57] = I[58] = (T)(img)(0,_p2##y,z,c)), \ - (I[65] = I[66] = I[67] = I[68] = I[69] = I[70] = I[71] = (T)(img)(0,_p1##y,z,c)), \ - (I[78] = I[79] = I[80] = I[81] = I[82] = I[83] = I[84] = (T)(img)(0,y,z,c)), \ - (I[91] = I[92] = I[93] = I[94] = I[95] = I[96] = I[97] = (T)(img)(0,_n1##y,z,c)), \ - (I[104] = I[105] = I[106] = I[107] = I[108] = I[109] = I[110] = (T)(img)(0,_n2##y,z,c)), \ - (I[117] = I[118] = I[119] = I[120] = I[121] = I[122] = I[123] = (T)(img)(0,_n3##y,z,c)), \ - (I[130] = I[131] = I[132] = I[133] = I[134] = I[135] = I[136] = (T)(img)(0,_n4##y,z,c)), \ - (I[143] = I[144] = I[145] = I[146] = I[147] = I[148] = I[149] = (T)(img)(0,_n5##y,z,c)), \ - (I[156] = I[157] = I[158] = I[159] = I[160] = I[161] = I[162] = (T)(img)(0,_n6##y,z,c)), \ - (I[7] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[20] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[33] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[46] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[59] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[72] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[85] = (T)(img)(_n1##x,y,z,c)), \ - (I[98] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[111] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[124] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[137] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[150] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[163] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[8] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[21] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[34] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[47] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[60] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[73] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[86] = (T)(img)(_n2##x,y,z,c)), \ - (I[99] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[112] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[125] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[138] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[151] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[164] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[9] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[22] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[35] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[48] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[61] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[74] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[87] = (T)(img)(_n3##x,y,z,c)), \ - (I[100] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[113] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[126] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[139] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[152] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[165] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[10] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[23] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[36] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[49] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[62] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[75] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[88] = (T)(img)(_n4##x,y,z,c)), \ - (I[101] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[114] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[127] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[140] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[153] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[166] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[11] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[24] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[37] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[50] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[63] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[76] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[89] = (T)(img)(_n5##x,y,z,c)), \ - (I[102] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[115] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[128] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[141] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[154] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[167] = (T)(img)(_n5##x,_n6##y,z,c)), \ - 6>=((img)._width)?(img).width() - 1:6); \ - (_n6##x<(img).width() && ( \ - (I[12] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[25] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[38] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[51] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[64] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[77] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[90] = (T)(img)(_n6##x,y,z,c)), \ - (I[103] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[116] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[129] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[142] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[155] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[168] = (T)(img)(_n6##x,_n6##y,z,c)),1)) || \ - _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], \ - I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], \ - I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], \ - I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], \ - I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], \ - I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], \ - I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], \ - I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], \ - I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], \ - I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], \ - I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], \ - I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], \ - I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], \ - _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x) - -#define cimg_for_in13x13(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in13((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = (int)( \ - (I[0] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[13] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[26] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[39] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[52] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[65] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[78] = (T)(img)(_p6##x,y,z,c)), \ - (I[91] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[104] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[117] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[130] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[143] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[156] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[1] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[14] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[27] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[40] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[53] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[66] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[79] = (T)(img)(_p5##x,y,z,c)), \ - (I[92] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[105] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[118] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[131] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[144] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[157] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[2] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[15] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[28] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[41] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[54] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[67] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[80] = (T)(img)(_p4##x,y,z,c)), \ - (I[93] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[106] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[119] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[132] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[145] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[158] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[3] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[16] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[29] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[42] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[55] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[68] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[81] = (T)(img)(_p3##x,y,z,c)), \ - (I[94] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[107] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[120] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[133] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[146] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[159] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[4] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[17] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[30] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[43] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[56] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[69] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[82] = (T)(img)(_p2##x,y,z,c)), \ - (I[95] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[108] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[121] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[134] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[147] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[160] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[5] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[18] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[31] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[44] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[57] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[70] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[83] = (T)(img)(_p1##x,y,z,c)), \ - (I[96] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[109] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[122] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[135] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[148] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[161] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[6] = (T)(img)(x,_p6##y,z,c)), \ - (I[19] = (T)(img)(x,_p5##y,z,c)), \ - (I[32] = (T)(img)(x,_p4##y,z,c)), \ - (I[45] = (T)(img)(x,_p3##y,z,c)), \ - (I[58] = (T)(img)(x,_p2##y,z,c)), \ - (I[71] = (T)(img)(x,_p1##y,z,c)), \ - (I[84] = (T)(img)(x,y,z,c)), \ - (I[97] = (T)(img)(x,_n1##y,z,c)), \ - (I[110] = (T)(img)(x,_n2##y,z,c)), \ - (I[123] = (T)(img)(x,_n3##y,z,c)), \ - (I[136] = (T)(img)(x,_n4##y,z,c)), \ - (I[149] = (T)(img)(x,_n5##y,z,c)), \ - (I[162] = (T)(img)(x,_n6##y,z,c)), \ - (I[7] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[20] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[33] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[46] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[59] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[72] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[85] = (T)(img)(_n1##x,y,z,c)), \ - (I[98] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[111] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[124] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[137] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[150] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[163] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[8] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[21] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[34] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[47] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[60] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[73] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[86] = (T)(img)(_n2##x,y,z,c)), \ - (I[99] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[112] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[125] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[138] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[151] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[164] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[9] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[22] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[35] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[48] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[61] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[74] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[87] = (T)(img)(_n3##x,y,z,c)), \ - (I[100] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[113] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[126] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[139] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[152] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[165] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[10] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[23] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[36] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[49] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[62] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[75] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[88] = (T)(img)(_n4##x,y,z,c)), \ - (I[101] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[114] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[127] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[140] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[153] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[166] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[11] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[24] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[37] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[50] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[63] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[76] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[89] = (T)(img)(_n5##x,y,z,c)), \ - (I[102] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[115] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[128] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[141] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[154] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[167] = (T)(img)(_n5##x,_n6##y,z,c)), \ - x + 6>=(img).width()?(img).width() - 1:x + 6); \ - x<=(int)(x1) && ((_n6##x<(img).width() && ( \ - (I[12] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[25] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[38] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[51] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[64] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[77] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[90] = (T)(img)(_n6##x,y,z,c)), \ - (I[103] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[116] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[129] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[142] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[155] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[168] = (T)(img)(_n6##x,_n6##y,z,c)),1)) || \ - _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], \ - I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], \ - I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], \ - I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], \ - I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], \ - I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], \ - I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], \ - I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], \ - I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], \ - I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], \ - I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], \ - I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], \ - I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], \ - _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x) - -#define cimg_get13x13(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p6##x,_p6##y,z,c), I[1] = (T)(img)(_p5##x,_p6##y,z,c), I[2] = (T)(img)(_p4##x,_p6##y,z,c), I[3] = (T)(img)(_p3##x,_p6##y,z,c), I[4] = (T)(img)(_p2##x,_p6##y,z,c), I[5] = (T)(img)(_p1##x,_p6##y,z,c), I[6] = (T)(img)(x,_p6##y,z,c), I[7] = (T)(img)(_n1##x,_p6##y,z,c), I[8] = (T)(img)(_n2##x,_p6##y,z,c), I[9] = (T)(img)(_n3##x,_p6##y,z,c), I[10] = (T)(img)(_n4##x,_p6##y,z,c), I[11] = (T)(img)(_n5##x,_p6##y,z,c), I[12] = (T)(img)(_n6##x,_p6##y,z,c), \ - I[13] = (T)(img)(_p6##x,_p5##y,z,c), I[14] = (T)(img)(_p5##x,_p5##y,z,c), I[15] = (T)(img)(_p4##x,_p5##y,z,c), I[16] = (T)(img)(_p3##x,_p5##y,z,c), I[17] = (T)(img)(_p2##x,_p5##y,z,c), I[18] = (T)(img)(_p1##x,_p5##y,z,c), I[19] = (T)(img)(x,_p5##y,z,c), I[20] = (T)(img)(_n1##x,_p5##y,z,c), I[21] = (T)(img)(_n2##x,_p5##y,z,c), I[22] = (T)(img)(_n3##x,_p5##y,z,c), I[23] = (T)(img)(_n4##x,_p5##y,z,c), I[24] = (T)(img)(_n5##x,_p5##y,z,c), I[25] = (T)(img)(_n6##x,_p5##y,z,c), \ - I[26] = (T)(img)(_p6##x,_p4##y,z,c), I[27] = (T)(img)(_p5##x,_p4##y,z,c), I[28] = (T)(img)(_p4##x,_p4##y,z,c), I[29] = (T)(img)(_p3##x,_p4##y,z,c), I[30] = (T)(img)(_p2##x,_p4##y,z,c), I[31] = (T)(img)(_p1##x,_p4##y,z,c), I[32] = (T)(img)(x,_p4##y,z,c), I[33] = (T)(img)(_n1##x,_p4##y,z,c), I[34] = (T)(img)(_n2##x,_p4##y,z,c), I[35] = (T)(img)(_n3##x,_p4##y,z,c), I[36] = (T)(img)(_n4##x,_p4##y,z,c), I[37] = (T)(img)(_n5##x,_p4##y,z,c), I[38] = (T)(img)(_n6##x,_p4##y,z,c), \ - I[39] = (T)(img)(_p6##x,_p3##y,z,c), I[40] = (T)(img)(_p5##x,_p3##y,z,c), I[41] = (T)(img)(_p4##x,_p3##y,z,c), I[42] = (T)(img)(_p3##x,_p3##y,z,c), I[43] = (T)(img)(_p2##x,_p3##y,z,c), I[44] = (T)(img)(_p1##x,_p3##y,z,c), I[45] = (T)(img)(x,_p3##y,z,c), I[46] = (T)(img)(_n1##x,_p3##y,z,c), I[47] = (T)(img)(_n2##x,_p3##y,z,c), I[48] = (T)(img)(_n3##x,_p3##y,z,c), I[49] = (T)(img)(_n4##x,_p3##y,z,c), I[50] = (T)(img)(_n5##x,_p3##y,z,c), I[51] = (T)(img)(_n6##x,_p3##y,z,c), \ - I[52] = (T)(img)(_p6##x,_p2##y,z,c), I[53] = (T)(img)(_p5##x,_p2##y,z,c), I[54] = (T)(img)(_p4##x,_p2##y,z,c), I[55] = (T)(img)(_p3##x,_p2##y,z,c), I[56] = (T)(img)(_p2##x,_p2##y,z,c), I[57] = (T)(img)(_p1##x,_p2##y,z,c), I[58] = (T)(img)(x,_p2##y,z,c), I[59] = (T)(img)(_n1##x,_p2##y,z,c), I[60] = (T)(img)(_n2##x,_p2##y,z,c), I[61] = (T)(img)(_n3##x,_p2##y,z,c), I[62] = (T)(img)(_n4##x,_p2##y,z,c), I[63] = (T)(img)(_n5##x,_p2##y,z,c), I[64] = (T)(img)(_n6##x,_p2##y,z,c), \ - I[65] = (T)(img)(_p6##x,_p1##y,z,c), I[66] = (T)(img)(_p5##x,_p1##y,z,c), I[67] = (T)(img)(_p4##x,_p1##y,z,c), I[68] = (T)(img)(_p3##x,_p1##y,z,c), I[69] = (T)(img)(_p2##x,_p1##y,z,c), I[70] = (T)(img)(_p1##x,_p1##y,z,c), I[71] = (T)(img)(x,_p1##y,z,c), I[72] = (T)(img)(_n1##x,_p1##y,z,c), I[73] = (T)(img)(_n2##x,_p1##y,z,c), I[74] = (T)(img)(_n3##x,_p1##y,z,c), I[75] = (T)(img)(_n4##x,_p1##y,z,c), I[76] = (T)(img)(_n5##x,_p1##y,z,c), I[77] = (T)(img)(_n6##x,_p1##y,z,c), \ - I[78] = (T)(img)(_p6##x,y,z,c), I[79] = (T)(img)(_p5##x,y,z,c), I[80] = (T)(img)(_p4##x,y,z,c), I[81] = (T)(img)(_p3##x,y,z,c), I[82] = (T)(img)(_p2##x,y,z,c), I[83] = (T)(img)(_p1##x,y,z,c), I[84] = (T)(img)(x,y,z,c), I[85] = (T)(img)(_n1##x,y,z,c), I[86] = (T)(img)(_n2##x,y,z,c), I[87] = (T)(img)(_n3##x,y,z,c), I[88] = (T)(img)(_n4##x,y,z,c), I[89] = (T)(img)(_n5##x,y,z,c), I[90] = (T)(img)(_n6##x,y,z,c), \ - I[91] = (T)(img)(_p6##x,_n1##y,z,c), I[92] = (T)(img)(_p5##x,_n1##y,z,c), I[93] = (T)(img)(_p4##x,_n1##y,z,c), I[94] = (T)(img)(_p3##x,_n1##y,z,c), I[95] = (T)(img)(_p2##x,_n1##y,z,c), I[96] = (T)(img)(_p1##x,_n1##y,z,c), I[97] = (T)(img)(x,_n1##y,z,c), I[98] = (T)(img)(_n1##x,_n1##y,z,c), I[99] = (T)(img)(_n2##x,_n1##y,z,c), I[100] = (T)(img)(_n3##x,_n1##y,z,c), I[101] = (T)(img)(_n4##x,_n1##y,z,c), I[102] = (T)(img)(_n5##x,_n1##y,z,c), I[103] = (T)(img)(_n6##x,_n1##y,z,c), \ - I[104] = (T)(img)(_p6##x,_n2##y,z,c), I[105] = (T)(img)(_p5##x,_n2##y,z,c), I[106] = (T)(img)(_p4##x,_n2##y,z,c), I[107] = (T)(img)(_p3##x,_n2##y,z,c), I[108] = (T)(img)(_p2##x,_n2##y,z,c), I[109] = (T)(img)(_p1##x,_n2##y,z,c), I[110] = (T)(img)(x,_n2##y,z,c), I[111] = (T)(img)(_n1##x,_n2##y,z,c), I[112] = (T)(img)(_n2##x,_n2##y,z,c), I[113] = (T)(img)(_n3##x,_n2##y,z,c), I[114] = (T)(img)(_n4##x,_n2##y,z,c), I[115] = (T)(img)(_n5##x,_n2##y,z,c), I[116] = (T)(img)(_n6##x,_n2##y,z,c), \ - I[117] = (T)(img)(_p6##x,_n3##y,z,c), I[118] = (T)(img)(_p5##x,_n3##y,z,c), I[119] = (T)(img)(_p4##x,_n3##y,z,c), I[120] = (T)(img)(_p3##x,_n3##y,z,c), I[121] = (T)(img)(_p2##x,_n3##y,z,c), I[122] = (T)(img)(_p1##x,_n3##y,z,c), I[123] = (T)(img)(x,_n3##y,z,c), I[124] = (T)(img)(_n1##x,_n3##y,z,c), I[125] = (T)(img)(_n2##x,_n3##y,z,c), I[126] = (T)(img)(_n3##x,_n3##y,z,c), I[127] = (T)(img)(_n4##x,_n3##y,z,c), I[128] = (T)(img)(_n5##x,_n3##y,z,c), I[129] = (T)(img)(_n6##x,_n3##y,z,c), \ - I[130] = (T)(img)(_p6##x,_n4##y,z,c), I[131] = (T)(img)(_p5##x,_n4##y,z,c), I[132] = (T)(img)(_p4##x,_n4##y,z,c), I[133] = (T)(img)(_p3##x,_n4##y,z,c), I[134] = (T)(img)(_p2##x,_n4##y,z,c), I[135] = (T)(img)(_p1##x,_n4##y,z,c), I[136] = (T)(img)(x,_n4##y,z,c), I[137] = (T)(img)(_n1##x,_n4##y,z,c), I[138] = (T)(img)(_n2##x,_n4##y,z,c), I[139] = (T)(img)(_n3##x,_n4##y,z,c), I[140] = (T)(img)(_n4##x,_n4##y,z,c), I[141] = (T)(img)(_n5##x,_n4##y,z,c), I[142] = (T)(img)(_n6##x,_n4##y,z,c), \ - I[143] = (T)(img)(_p6##x,_n5##y,z,c), I[144] = (T)(img)(_p5##x,_n5##y,z,c), I[145] = (T)(img)(_p4##x,_n5##y,z,c), I[146] = (T)(img)(_p3##x,_n5##y,z,c), I[147] = (T)(img)(_p2##x,_n5##y,z,c), I[148] = (T)(img)(_p1##x,_n5##y,z,c), I[149] = (T)(img)(x,_n5##y,z,c), I[150] = (T)(img)(_n1##x,_n5##y,z,c), I[151] = (T)(img)(_n2##x,_n5##y,z,c), I[152] = (T)(img)(_n3##x,_n5##y,z,c), I[153] = (T)(img)(_n4##x,_n5##y,z,c), I[154] = (T)(img)(_n5##x,_n5##y,z,c), I[155] = (T)(img)(_n6##x,_n5##y,z,c), \ - I[156] = (T)(img)(_p6##x,_n6##y,z,c), I[157] = (T)(img)(_p5##x,_n6##y,z,c), I[158] = (T)(img)(_p4##x,_n6##y,z,c), I[159] = (T)(img)(_p3##x,_n6##y,z,c), I[160] = (T)(img)(_p2##x,_n6##y,z,c), I[161] = (T)(img)(_p1##x,_n6##y,z,c), I[162] = (T)(img)(x,_n6##y,z,c), I[163] = (T)(img)(_n1##x,_n6##y,z,c), I[164] = (T)(img)(_n2##x,_n6##y,z,c), I[165] = (T)(img)(_n3##x,_n6##y,z,c), I[166] = (T)(img)(_n4##x,_n6##y,z,c), I[167] = (T)(img)(_n5##x,_n6##y,z,c), I[168] = (T)(img)(_n6##x,_n6##y,z,c); - -// Define 14x14 loop macros -//------------------------- -#define cimg_for14(bound,i) for (int i = 0, \ - _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6, \ - _n7##i = 7>=(int)(bound)?(int)(bound) - 1:7; \ - _n7##i<(int)(bound) || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i) - -#define cimg_for14X(img,x) cimg_for14((img)._width,x) -#define cimg_for14Y(img,y) cimg_for14((img)._height,y) -#define cimg_for14Z(img,z) cimg_for14((img)._depth,z) -#define cimg_for14C(img,c) cimg_for14((img)._spectrum,c) -#define cimg_for14XY(img,x,y) cimg_for14Y(img,y) cimg_for14X(img,x) -#define cimg_for14XZ(img,x,z) cimg_for14Z(img,z) cimg_for14X(img,x) -#define cimg_for14XC(img,x,c) cimg_for14C(img,c) cimg_for14X(img,x) -#define cimg_for14YZ(img,y,z) cimg_for14Z(img,z) cimg_for14Y(img,y) -#define cimg_for14YC(img,y,c) cimg_for14C(img,c) cimg_for14Y(img,y) -#define cimg_for14ZC(img,z,c) cimg_for14C(img,c) cimg_for14Z(img,z) -#define cimg_for14XYZ(img,x,y,z) cimg_for14Z(img,z) cimg_for14XY(img,x,y) -#define cimg_for14XZC(img,x,z,c) cimg_for14C(img,c) cimg_for14XZ(img,x,z) -#define cimg_for14YZC(img,y,z,c) cimg_for14C(img,c) cimg_for14YZ(img,y,z) -#define cimg_for14XYZC(img,x,y,z,c) cimg_for14C(img,c) cimg_for14XYZ(img,x,y,z) - -#define cimg_for_in14(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6, \ - _n7##i = i + 7>=(int)(bound)?(int)(bound) - 1:i + 7; \ - i<=(int)(i1) && (_n7##i<(int)(bound) || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i) - -#define cimg_for_in14X(img,x0,x1,x) cimg_for_in14((img)._width,x0,x1,x) -#define cimg_for_in14Y(img,y0,y1,y) cimg_for_in14((img)._height,y0,y1,y) -#define cimg_for_in14Z(img,z0,z1,z) cimg_for_in14((img)._depth,z0,z1,z) -#define cimg_for_in14C(img,c0,c1,c) cimg_for_in14((img)._spectrum,c0,c1,c) -#define cimg_for_in14XY(img,x0,y0,x1,y1,x,y) cimg_for_in14Y(img,y0,y1,y) cimg_for_in14X(img,x0,x1,x) -#define cimg_for_in14XZ(img,x0,z0,x1,z1,x,z) cimg_for_in14Z(img,z0,z1,z) cimg_for_in14X(img,x0,x1,x) -#define cimg_for_in14XC(img,x0,c0,x1,c1,x,c) cimg_for_in14C(img,c0,c1,c) cimg_for_in14X(img,x0,x1,x) -#define cimg_for_in14YZ(img,y0,z0,y1,z1,y,z) cimg_for_in14Z(img,z0,z1,z) cimg_for_in14Y(img,y0,y1,y) -#define cimg_for_in14YC(img,y0,c0,y1,c1,y,c) cimg_for_in14C(img,c0,c1,c) cimg_for_in14Y(img,y0,y1,y) -#define cimg_for_in14ZC(img,z0,c0,z1,c1,z,c) cimg_for_in14C(img,c0,c1,c) cimg_for_in14Z(img,z0,z1,z) -#define cimg_for_in14XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in14Z(img,z0,z1,z) cimg_for_in14XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in14XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in14C(img,c0,c1,c) cimg_for_in14XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in14YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in14C(img,c0,c1,c) cimg_for_in14YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in14XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in14C(img,c0,c1,c) cimg_for_in14XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for14x14(img,x,y,z,c,I,T) \ - cimg_for14((img)._height,y) for (int x = 0, \ - _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = 6>=((img)._width)?(img).width() - 1:6, \ - _n7##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = (T)(img)(0,_p6##y,z,c)), \ - (I[14] = I[15] = I[16] = I[17] = I[18] = I[19] = I[20] = (T)(img)(0,_p5##y,z,c)), \ - (I[28] = I[29] = I[30] = I[31] = I[32] = I[33] = I[34] = (T)(img)(0,_p4##y,z,c)), \ - (I[42] = I[43] = I[44] = I[45] = I[46] = I[47] = I[48] = (T)(img)(0,_p3##y,z,c)), \ - (I[56] = I[57] = I[58] = I[59] = I[60] = I[61] = I[62] = (T)(img)(0,_p2##y,z,c)), \ - (I[70] = I[71] = I[72] = I[73] = I[74] = I[75] = I[76] = (T)(img)(0,_p1##y,z,c)), \ - (I[84] = I[85] = I[86] = I[87] = I[88] = I[89] = I[90] = (T)(img)(0,y,z,c)), \ - (I[98] = I[99] = I[100] = I[101] = I[102] = I[103] = I[104] = (T)(img)(0,_n1##y,z,c)), \ - (I[112] = I[113] = I[114] = I[115] = I[116] = I[117] = I[118] = (T)(img)(0,_n2##y,z,c)), \ - (I[126] = I[127] = I[128] = I[129] = I[130] = I[131] = I[132] = (T)(img)(0,_n3##y,z,c)), \ - (I[140] = I[141] = I[142] = I[143] = I[144] = I[145] = I[146] = (T)(img)(0,_n4##y,z,c)), \ - (I[154] = I[155] = I[156] = I[157] = I[158] = I[159] = I[160] = (T)(img)(0,_n5##y,z,c)), \ - (I[168] = I[169] = I[170] = I[171] = I[172] = I[173] = I[174] = (T)(img)(0,_n6##y,z,c)), \ - (I[182] = I[183] = I[184] = I[185] = I[186] = I[187] = I[188] = (T)(img)(0,_n7##y,z,c)), \ - (I[7] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[21] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[35] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[49] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[63] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[77] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[91] = (T)(img)(_n1##x,y,z,c)), \ - (I[105] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[119] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[133] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[147] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[161] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[175] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[189] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[8] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[22] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[36] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[50] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[64] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[78] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[92] = (T)(img)(_n2##x,y,z,c)), \ - (I[106] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[120] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[134] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[148] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[162] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[176] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[190] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[9] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[23] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[37] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[51] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[65] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[79] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[93] = (T)(img)(_n3##x,y,z,c)), \ - (I[107] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[121] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[135] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[149] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[163] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[177] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[191] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[10] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[24] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[38] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[52] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[66] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[80] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[94] = (T)(img)(_n4##x,y,z,c)), \ - (I[108] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[122] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[136] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[150] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[164] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[178] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[192] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[11] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[25] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[39] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[53] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[67] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[81] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[95] = (T)(img)(_n5##x,y,z,c)), \ - (I[109] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[123] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[137] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[151] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[165] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[179] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[193] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[12] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[26] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[40] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[54] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[68] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[82] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[96] = (T)(img)(_n6##x,y,z,c)), \ - (I[110] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[124] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[138] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[152] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[166] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[180] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[194] = (T)(img)(_n6##x,_n7##y,z,c)), \ - 7>=((img)._width)?(img).width() - 1:7); \ - (_n7##x<(img).width() && ( \ - (I[13] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[27] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[41] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[55] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[69] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[83] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[97] = (T)(img)(_n7##x,y,z,c)), \ - (I[111] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[125] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[139] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[153] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[167] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[181] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[195] = (T)(img)(_n7##x,_n7##y,z,c)),1)) || \ - _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], \ - I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], \ - I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], \ - I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], \ - I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], \ - I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], \ - I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], \ - I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], \ - I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], \ - I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], \ - I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], \ - I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], \ - I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], \ - I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], \ - _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x) - -#define cimg_for_in14x14(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in14((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = x + 6>=(img).width()?(img).width() - 1:x + 6, \ - _n7##x = (int)( \ - (I[0] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[14] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[28] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[42] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[56] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[70] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[84] = (T)(img)(_p6##x,y,z,c)), \ - (I[98] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[112] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[126] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[140] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[154] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[168] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[182] = (T)(img)(_p6##x,_n7##y,z,c)), \ - (I[1] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[15] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[29] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[43] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[57] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[71] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[85] = (T)(img)(_p5##x,y,z,c)), \ - (I[99] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[113] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[127] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[141] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[155] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[169] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[183] = (T)(img)(_p5##x,_n7##y,z,c)), \ - (I[2] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[16] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[30] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[44] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[58] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[72] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[86] = (T)(img)(_p4##x,y,z,c)), \ - (I[100] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[114] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[128] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[142] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[156] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[170] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[184] = (T)(img)(_p4##x,_n7##y,z,c)), \ - (I[3] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[17] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[31] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[45] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[59] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[73] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[87] = (T)(img)(_p3##x,y,z,c)), \ - (I[101] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[115] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[129] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[143] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[157] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[171] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[185] = (T)(img)(_p3##x,_n7##y,z,c)), \ - (I[4] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[18] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[32] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[46] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[60] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[74] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[88] = (T)(img)(_p2##x,y,z,c)), \ - (I[102] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[116] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[130] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[144] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[158] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[172] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[186] = (T)(img)(_p2##x,_n7##y,z,c)), \ - (I[5] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[19] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[33] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[47] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[61] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[75] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[89] = (T)(img)(_p1##x,y,z,c)), \ - (I[103] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[117] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[131] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[145] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[159] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[173] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[187] = (T)(img)(_p1##x,_n7##y,z,c)), \ - (I[6] = (T)(img)(x,_p6##y,z,c)), \ - (I[20] = (T)(img)(x,_p5##y,z,c)), \ - (I[34] = (T)(img)(x,_p4##y,z,c)), \ - (I[48] = (T)(img)(x,_p3##y,z,c)), \ - (I[62] = (T)(img)(x,_p2##y,z,c)), \ - (I[76] = (T)(img)(x,_p1##y,z,c)), \ - (I[90] = (T)(img)(x,y,z,c)), \ - (I[104] = (T)(img)(x,_n1##y,z,c)), \ - (I[118] = (T)(img)(x,_n2##y,z,c)), \ - (I[132] = (T)(img)(x,_n3##y,z,c)), \ - (I[146] = (T)(img)(x,_n4##y,z,c)), \ - (I[160] = (T)(img)(x,_n5##y,z,c)), \ - (I[174] = (T)(img)(x,_n6##y,z,c)), \ - (I[188] = (T)(img)(x,_n7##y,z,c)), \ - (I[7] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[21] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[35] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[49] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[63] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[77] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[91] = (T)(img)(_n1##x,y,z,c)), \ - (I[105] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[119] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[133] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[147] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[161] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[175] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[189] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[8] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[22] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[36] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[50] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[64] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[78] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[92] = (T)(img)(_n2##x,y,z,c)), \ - (I[106] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[120] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[134] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[148] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[162] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[176] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[190] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[9] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[23] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[37] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[51] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[65] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[79] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[93] = (T)(img)(_n3##x,y,z,c)), \ - (I[107] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[121] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[135] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[149] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[163] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[177] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[191] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[10] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[24] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[38] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[52] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[66] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[80] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[94] = (T)(img)(_n4##x,y,z,c)), \ - (I[108] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[122] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[136] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[150] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[164] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[178] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[192] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[11] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[25] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[39] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[53] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[67] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[81] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[95] = (T)(img)(_n5##x,y,z,c)), \ - (I[109] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[123] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[137] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[151] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[165] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[179] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[193] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[12] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[26] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[40] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[54] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[68] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[82] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[96] = (T)(img)(_n6##x,y,z,c)), \ - (I[110] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[124] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[138] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[152] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[166] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[180] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[194] = (T)(img)(_n6##x,_n7##y,z,c)), \ - x + 7>=(img).width()?(img).width() - 1:x + 7); \ - x<=(int)(x1) && ((_n7##x<(img).width() && ( \ - (I[13] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[27] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[41] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[55] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[69] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[83] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[97] = (T)(img)(_n7##x,y,z,c)), \ - (I[111] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[125] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[139] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[153] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[167] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[181] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[195] = (T)(img)(_n7##x,_n7##y,z,c)),1)) || \ - _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], \ - I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], \ - I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], \ - I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], \ - I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], \ - I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], \ - I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], \ - I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], \ - I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], \ - I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], \ - I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], \ - I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], \ - I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], \ - I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], \ - _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x) - -#define cimg_get14x14(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p6##x,_p6##y,z,c), I[1] = (T)(img)(_p5##x,_p6##y,z,c), I[2] = (T)(img)(_p4##x,_p6##y,z,c), I[3] = (T)(img)(_p3##x,_p6##y,z,c), I[4] = (T)(img)(_p2##x,_p6##y,z,c), I[5] = (T)(img)(_p1##x,_p6##y,z,c), I[6] = (T)(img)(x,_p6##y,z,c), I[7] = (T)(img)(_n1##x,_p6##y,z,c), I[8] = (T)(img)(_n2##x,_p6##y,z,c), I[9] = (T)(img)(_n3##x,_p6##y,z,c), I[10] = (T)(img)(_n4##x,_p6##y,z,c), I[11] = (T)(img)(_n5##x,_p6##y,z,c), I[12] = (T)(img)(_n6##x,_p6##y,z,c), I[13] = (T)(img)(_n7##x,_p6##y,z,c), \ - I[14] = (T)(img)(_p6##x,_p5##y,z,c), I[15] = (T)(img)(_p5##x,_p5##y,z,c), I[16] = (T)(img)(_p4##x,_p5##y,z,c), I[17] = (T)(img)(_p3##x,_p5##y,z,c), I[18] = (T)(img)(_p2##x,_p5##y,z,c), I[19] = (T)(img)(_p1##x,_p5##y,z,c), I[20] = (T)(img)(x,_p5##y,z,c), I[21] = (T)(img)(_n1##x,_p5##y,z,c), I[22] = (T)(img)(_n2##x,_p5##y,z,c), I[23] = (T)(img)(_n3##x,_p5##y,z,c), I[24] = (T)(img)(_n4##x,_p5##y,z,c), I[25] = (T)(img)(_n5##x,_p5##y,z,c), I[26] = (T)(img)(_n6##x,_p5##y,z,c), I[27] = (T)(img)(_n7##x,_p5##y,z,c), \ - I[28] = (T)(img)(_p6##x,_p4##y,z,c), I[29] = (T)(img)(_p5##x,_p4##y,z,c), I[30] = (T)(img)(_p4##x,_p4##y,z,c), I[31] = (T)(img)(_p3##x,_p4##y,z,c), I[32] = (T)(img)(_p2##x,_p4##y,z,c), I[33] = (T)(img)(_p1##x,_p4##y,z,c), I[34] = (T)(img)(x,_p4##y,z,c), I[35] = (T)(img)(_n1##x,_p4##y,z,c), I[36] = (T)(img)(_n2##x,_p4##y,z,c), I[37] = (T)(img)(_n3##x,_p4##y,z,c), I[38] = (T)(img)(_n4##x,_p4##y,z,c), I[39] = (T)(img)(_n5##x,_p4##y,z,c), I[40] = (T)(img)(_n6##x,_p4##y,z,c), I[41] = (T)(img)(_n7##x,_p4##y,z,c), \ - I[42] = (T)(img)(_p6##x,_p3##y,z,c), I[43] = (T)(img)(_p5##x,_p3##y,z,c), I[44] = (T)(img)(_p4##x,_p3##y,z,c), I[45] = (T)(img)(_p3##x,_p3##y,z,c), I[46] = (T)(img)(_p2##x,_p3##y,z,c), I[47] = (T)(img)(_p1##x,_p3##y,z,c), I[48] = (T)(img)(x,_p3##y,z,c), I[49] = (T)(img)(_n1##x,_p3##y,z,c), I[50] = (T)(img)(_n2##x,_p3##y,z,c), I[51] = (T)(img)(_n3##x,_p3##y,z,c), I[52] = (T)(img)(_n4##x,_p3##y,z,c), I[53] = (T)(img)(_n5##x,_p3##y,z,c), I[54] = (T)(img)(_n6##x,_p3##y,z,c), I[55] = (T)(img)(_n7##x,_p3##y,z,c), \ - I[56] = (T)(img)(_p6##x,_p2##y,z,c), I[57] = (T)(img)(_p5##x,_p2##y,z,c), I[58] = (T)(img)(_p4##x,_p2##y,z,c), I[59] = (T)(img)(_p3##x,_p2##y,z,c), I[60] = (T)(img)(_p2##x,_p2##y,z,c), I[61] = (T)(img)(_p1##x,_p2##y,z,c), I[62] = (T)(img)(x,_p2##y,z,c), I[63] = (T)(img)(_n1##x,_p2##y,z,c), I[64] = (T)(img)(_n2##x,_p2##y,z,c), I[65] = (T)(img)(_n3##x,_p2##y,z,c), I[66] = (T)(img)(_n4##x,_p2##y,z,c), I[67] = (T)(img)(_n5##x,_p2##y,z,c), I[68] = (T)(img)(_n6##x,_p2##y,z,c), I[69] = (T)(img)(_n7##x,_p2##y,z,c), \ - I[70] = (T)(img)(_p6##x,_p1##y,z,c), I[71] = (T)(img)(_p5##x,_p1##y,z,c), I[72] = (T)(img)(_p4##x,_p1##y,z,c), I[73] = (T)(img)(_p3##x,_p1##y,z,c), I[74] = (T)(img)(_p2##x,_p1##y,z,c), I[75] = (T)(img)(_p1##x,_p1##y,z,c), I[76] = (T)(img)(x,_p1##y,z,c), I[77] = (T)(img)(_n1##x,_p1##y,z,c), I[78] = (T)(img)(_n2##x,_p1##y,z,c), I[79] = (T)(img)(_n3##x,_p1##y,z,c), I[80] = (T)(img)(_n4##x,_p1##y,z,c), I[81] = (T)(img)(_n5##x,_p1##y,z,c), I[82] = (T)(img)(_n6##x,_p1##y,z,c), I[83] = (T)(img)(_n7##x,_p1##y,z,c), \ - I[84] = (T)(img)(_p6##x,y,z,c), I[85] = (T)(img)(_p5##x,y,z,c), I[86] = (T)(img)(_p4##x,y,z,c), I[87] = (T)(img)(_p3##x,y,z,c), I[88] = (T)(img)(_p2##x,y,z,c), I[89] = (T)(img)(_p1##x,y,z,c), I[90] = (T)(img)(x,y,z,c), I[91] = (T)(img)(_n1##x,y,z,c), I[92] = (T)(img)(_n2##x,y,z,c), I[93] = (T)(img)(_n3##x,y,z,c), I[94] = (T)(img)(_n4##x,y,z,c), I[95] = (T)(img)(_n5##x,y,z,c), I[96] = (T)(img)(_n6##x,y,z,c), I[97] = (T)(img)(_n7##x,y,z,c), \ - I[98] = (T)(img)(_p6##x,_n1##y,z,c), I[99] = (T)(img)(_p5##x,_n1##y,z,c), I[100] = (T)(img)(_p4##x,_n1##y,z,c), I[101] = (T)(img)(_p3##x,_n1##y,z,c), I[102] = (T)(img)(_p2##x,_n1##y,z,c), I[103] = (T)(img)(_p1##x,_n1##y,z,c), I[104] = (T)(img)(x,_n1##y,z,c), I[105] = (T)(img)(_n1##x,_n1##y,z,c), I[106] = (T)(img)(_n2##x,_n1##y,z,c), I[107] = (T)(img)(_n3##x,_n1##y,z,c), I[108] = (T)(img)(_n4##x,_n1##y,z,c), I[109] = (T)(img)(_n5##x,_n1##y,z,c), I[110] = (T)(img)(_n6##x,_n1##y,z,c), I[111] = (T)(img)(_n7##x,_n1##y,z,c), \ - I[112] = (T)(img)(_p6##x,_n2##y,z,c), I[113] = (T)(img)(_p5##x,_n2##y,z,c), I[114] = (T)(img)(_p4##x,_n2##y,z,c), I[115] = (T)(img)(_p3##x,_n2##y,z,c), I[116] = (T)(img)(_p2##x,_n2##y,z,c), I[117] = (T)(img)(_p1##x,_n2##y,z,c), I[118] = (T)(img)(x,_n2##y,z,c), I[119] = (T)(img)(_n1##x,_n2##y,z,c), I[120] = (T)(img)(_n2##x,_n2##y,z,c), I[121] = (T)(img)(_n3##x,_n2##y,z,c), I[122] = (T)(img)(_n4##x,_n2##y,z,c), I[123] = (T)(img)(_n5##x,_n2##y,z,c), I[124] = (T)(img)(_n6##x,_n2##y,z,c), I[125] = (T)(img)(_n7##x,_n2##y,z,c), \ - I[126] = (T)(img)(_p6##x,_n3##y,z,c), I[127] = (T)(img)(_p5##x,_n3##y,z,c), I[128] = (T)(img)(_p4##x,_n3##y,z,c), I[129] = (T)(img)(_p3##x,_n3##y,z,c), I[130] = (T)(img)(_p2##x,_n3##y,z,c), I[131] = (T)(img)(_p1##x,_n3##y,z,c), I[132] = (T)(img)(x,_n3##y,z,c), I[133] = (T)(img)(_n1##x,_n3##y,z,c), I[134] = (T)(img)(_n2##x,_n3##y,z,c), I[135] = (T)(img)(_n3##x,_n3##y,z,c), I[136] = (T)(img)(_n4##x,_n3##y,z,c), I[137] = (T)(img)(_n5##x,_n3##y,z,c), I[138] = (T)(img)(_n6##x,_n3##y,z,c), I[139] = (T)(img)(_n7##x,_n3##y,z,c), \ - I[140] = (T)(img)(_p6##x,_n4##y,z,c), I[141] = (T)(img)(_p5##x,_n4##y,z,c), I[142] = (T)(img)(_p4##x,_n4##y,z,c), I[143] = (T)(img)(_p3##x,_n4##y,z,c), I[144] = (T)(img)(_p2##x,_n4##y,z,c), I[145] = (T)(img)(_p1##x,_n4##y,z,c), I[146] = (T)(img)(x,_n4##y,z,c), I[147] = (T)(img)(_n1##x,_n4##y,z,c), I[148] = (T)(img)(_n2##x,_n4##y,z,c), I[149] = (T)(img)(_n3##x,_n4##y,z,c), I[150] = (T)(img)(_n4##x,_n4##y,z,c), I[151] = (T)(img)(_n5##x,_n4##y,z,c), I[152] = (T)(img)(_n6##x,_n4##y,z,c), I[153] = (T)(img)(_n7##x,_n4##y,z,c), \ - I[154] = (T)(img)(_p6##x,_n5##y,z,c), I[155] = (T)(img)(_p5##x,_n5##y,z,c), I[156] = (T)(img)(_p4##x,_n5##y,z,c), I[157] = (T)(img)(_p3##x,_n5##y,z,c), I[158] = (T)(img)(_p2##x,_n5##y,z,c), I[159] = (T)(img)(_p1##x,_n5##y,z,c), I[160] = (T)(img)(x,_n5##y,z,c), I[161] = (T)(img)(_n1##x,_n5##y,z,c), I[162] = (T)(img)(_n2##x,_n5##y,z,c), I[163] = (T)(img)(_n3##x,_n5##y,z,c), I[164] = (T)(img)(_n4##x,_n5##y,z,c), I[165] = (T)(img)(_n5##x,_n5##y,z,c), I[166] = (T)(img)(_n6##x,_n5##y,z,c), I[167] = (T)(img)(_n7##x,_n5##y,z,c), \ - I[168] = (T)(img)(_p6##x,_n6##y,z,c), I[169] = (T)(img)(_p5##x,_n6##y,z,c), I[170] = (T)(img)(_p4##x,_n6##y,z,c), I[171] = (T)(img)(_p3##x,_n6##y,z,c), I[172] = (T)(img)(_p2##x,_n6##y,z,c), I[173] = (T)(img)(_p1##x,_n6##y,z,c), I[174] = (T)(img)(x,_n6##y,z,c), I[175] = (T)(img)(_n1##x,_n6##y,z,c), I[176] = (T)(img)(_n2##x,_n6##y,z,c), I[177] = (T)(img)(_n3##x,_n6##y,z,c), I[178] = (T)(img)(_n4##x,_n6##y,z,c), I[179] = (T)(img)(_n5##x,_n6##y,z,c), I[180] = (T)(img)(_n6##x,_n6##y,z,c), I[181] = (T)(img)(_n7##x,_n6##y,z,c), \ - I[182] = (T)(img)(_p6##x,_n7##y,z,c), I[183] = (T)(img)(_p5##x,_n7##y,z,c), I[184] = (T)(img)(_p4##x,_n7##y,z,c), I[185] = (T)(img)(_p3##x,_n7##y,z,c), I[186] = (T)(img)(_p2##x,_n7##y,z,c), I[187] = (T)(img)(_p1##x,_n7##y,z,c), I[188] = (T)(img)(x,_n7##y,z,c), I[189] = (T)(img)(_n1##x,_n7##y,z,c), I[190] = (T)(img)(_n2##x,_n7##y,z,c), I[191] = (T)(img)(_n3##x,_n7##y,z,c), I[192] = (T)(img)(_n4##x,_n7##y,z,c), I[193] = (T)(img)(_n5##x,_n7##y,z,c), I[194] = (T)(img)(_n6##x,_n7##y,z,c), I[195] = (T)(img)(_n7##x,_n7##y,z,c); - -// Define 15x15 loop macros -//------------------------- -#define cimg_for15(bound,i) for (int i = 0, \ - _p7##i = 0, _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6, \ - _n7##i = 7>=(int)(bound)?(int)(bound) - 1:7; \ - _n7##i<(int)(bound) || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i) - -#define cimg_for15X(img,x) cimg_for15((img)._width,x) -#define cimg_for15Y(img,y) cimg_for15((img)._height,y) -#define cimg_for15Z(img,z) cimg_for15((img)._depth,z) -#define cimg_for15C(img,c) cimg_for15((img)._spectrum,c) -#define cimg_for15XY(img,x,y) cimg_for15Y(img,y) cimg_for15X(img,x) -#define cimg_for15XZ(img,x,z) cimg_for15Z(img,z) cimg_for15X(img,x) -#define cimg_for15XC(img,x,c) cimg_for15C(img,c) cimg_for15X(img,x) -#define cimg_for15YZ(img,y,z) cimg_for15Z(img,z) cimg_for15Y(img,y) -#define cimg_for15YC(img,y,c) cimg_for15C(img,c) cimg_for15Y(img,y) -#define cimg_for15ZC(img,z,c) cimg_for15C(img,c) cimg_for15Z(img,z) -#define cimg_for15XYZ(img,x,y,z) cimg_for15Z(img,z) cimg_for15XY(img,x,y) -#define cimg_for15XZC(img,x,z,c) cimg_for15C(img,c) cimg_for15XZ(img,x,z) -#define cimg_for15YZC(img,y,z,c) cimg_for15C(img,c) cimg_for15YZ(img,y,z) -#define cimg_for15XYZC(img,x,y,z,c) cimg_for15C(img,c) cimg_for15XYZ(img,x,y,z) - -#define cimg_for_in15(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p7##i = i - 7<0?0:i - 7, \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6, \ - _n7##i = i + 7>=(int)(bound)?(int)(bound) - 1:i + 7; \ - i<=(int)(i1) && (_n7##i<(int)(bound) || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i) - -#define cimg_for_in15X(img,x0,x1,x) cimg_for_in15((img)._width,x0,x1,x) -#define cimg_for_in15Y(img,y0,y1,y) cimg_for_in15((img)._height,y0,y1,y) -#define cimg_for_in15Z(img,z0,z1,z) cimg_for_in15((img)._depth,z0,z1,z) -#define cimg_for_in15C(img,c0,c1,c) cimg_for_in15((img)._spectrum,c0,c1,c) -#define cimg_for_in15XY(img,x0,y0,x1,y1,x,y) cimg_for_in15Y(img,y0,y1,y) cimg_for_in15X(img,x0,x1,x) -#define cimg_for_in15XZ(img,x0,z0,x1,z1,x,z) cimg_for_in15Z(img,z0,z1,z) cimg_for_in15X(img,x0,x1,x) -#define cimg_for_in15XC(img,x0,c0,x1,c1,x,c) cimg_for_in15C(img,c0,c1,c) cimg_for_in15X(img,x0,x1,x) -#define cimg_for_in15YZ(img,y0,z0,y1,z1,y,z) cimg_for_in15Z(img,z0,z1,z) cimg_for_in15Y(img,y0,y1,y) -#define cimg_for_in15YC(img,y0,c0,y1,c1,y,c) cimg_for_in15C(img,c0,c1,c) cimg_for_in15Y(img,y0,y1,y) -#define cimg_for_in15ZC(img,z0,c0,z1,c1,z,c) cimg_for_in15C(img,c0,c1,c) cimg_for_in15Z(img,z0,z1,z) -#define cimg_for_in15XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in15Z(img,z0,z1,z) cimg_for_in15XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in15XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in15C(img,c0,c1,c) cimg_for_in15XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in15YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in15C(img,c0,c1,c) cimg_for_in15YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in15XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in15C(img,c0,c1,c) cimg_for_in15XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for15x15(img,x,y,z,c,I,T) \ - cimg_for15((img)._height,y) for (int x = 0, \ - _p7##x = 0, _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = 6>=((img)._width)?(img).width() - 1:6, \ - _n7##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = I[7] = (T)(img)(0,_p7##y,z,c)), \ - (I[15] = I[16] = I[17] = I[18] = I[19] = I[20] = I[21] = I[22] = (T)(img)(0,_p6##y,z,c)), \ - (I[30] = I[31] = I[32] = I[33] = I[34] = I[35] = I[36] = I[37] = (T)(img)(0,_p5##y,z,c)), \ - (I[45] = I[46] = I[47] = I[48] = I[49] = I[50] = I[51] = I[52] = (T)(img)(0,_p4##y,z,c)), \ - (I[60] = I[61] = I[62] = I[63] = I[64] = I[65] = I[66] = I[67] = (T)(img)(0,_p3##y,z,c)), \ - (I[75] = I[76] = I[77] = I[78] = I[79] = I[80] = I[81] = I[82] = (T)(img)(0,_p2##y,z,c)), \ - (I[90] = I[91] = I[92] = I[93] = I[94] = I[95] = I[96] = I[97] = (T)(img)(0,_p1##y,z,c)), \ - (I[105] = I[106] = I[107] = I[108] = I[109] = I[110] = I[111] = I[112] = (T)(img)(0,y,z,c)), \ - (I[120] = I[121] = I[122] = I[123] = I[124] = I[125] = I[126] = I[127] = (T)(img)(0,_n1##y,z,c)), \ - (I[135] = I[136] = I[137] = I[138] = I[139] = I[140] = I[141] = I[142] = (T)(img)(0,_n2##y,z,c)), \ - (I[150] = I[151] = I[152] = I[153] = I[154] = I[155] = I[156] = I[157] = (T)(img)(0,_n3##y,z,c)), \ - (I[165] = I[166] = I[167] = I[168] = I[169] = I[170] = I[171] = I[172] = (T)(img)(0,_n4##y,z,c)), \ - (I[180] = I[181] = I[182] = I[183] = I[184] = I[185] = I[186] = I[187] = (T)(img)(0,_n5##y,z,c)), \ - (I[195] = I[196] = I[197] = I[198] = I[199] = I[200] = I[201] = I[202] = (T)(img)(0,_n6##y,z,c)), \ - (I[210] = I[211] = I[212] = I[213] = I[214] = I[215] = I[216] = I[217] = (T)(img)(0,_n7##y,z,c)), \ - (I[8] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[23] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[38] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[53] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[68] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[83] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[98] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[113] = (T)(img)(_n1##x,y,z,c)), \ - (I[128] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[143] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[158] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[173] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[188] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[203] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[218] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[9] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[24] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[39] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[54] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[69] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[84] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[99] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[114] = (T)(img)(_n2##x,y,z,c)), \ - (I[129] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[144] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[159] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[174] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[189] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[204] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[219] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[10] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[25] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[40] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[55] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[70] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[85] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[100] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[115] = (T)(img)(_n3##x,y,z,c)), \ - (I[130] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[145] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[160] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[175] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[190] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[205] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[220] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[11] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[26] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[41] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[56] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[71] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[86] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[101] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[116] = (T)(img)(_n4##x,y,z,c)), \ - (I[131] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[146] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[161] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[176] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[191] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[206] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[221] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[12] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[27] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[42] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[57] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[72] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[87] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[102] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[117] = (T)(img)(_n5##x,y,z,c)), \ - (I[132] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[147] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[162] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[177] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[192] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[207] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[222] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[13] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[28] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[43] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[58] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[73] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[88] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[103] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[118] = (T)(img)(_n6##x,y,z,c)), \ - (I[133] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[148] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[163] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[178] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[193] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[208] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[223] = (T)(img)(_n6##x,_n7##y,z,c)), \ - 7>=((img)._width)?(img).width() - 1:7); \ - (_n7##x<(img).width() && ( \ - (I[14] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[29] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[44] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[59] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[74] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[89] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[104] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[119] = (T)(img)(_n7##x,y,z,c)), \ - (I[134] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[149] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[164] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[179] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[194] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[209] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[224] = (T)(img)(_n7##x,_n7##y,z,c)),1)) || \ - _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], \ - I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], \ - I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], \ - I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], \ - I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], \ - I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], \ - I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], \ - I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], \ - I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], \ - I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], \ - I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], \ - I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], \ - I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], \ - I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], \ - I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], \ - _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x) - -#define cimg_for_in15x15(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in15((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p7##x = x - 7<0?0:x - 7, \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = x + 6>=(img).width()?(img).width() - 1:x + 6, \ - _n7##x = (int)( \ - (I[0] = (T)(img)(_p7##x,_p7##y,z,c)), \ - (I[15] = (T)(img)(_p7##x,_p6##y,z,c)), \ - (I[30] = (T)(img)(_p7##x,_p5##y,z,c)), \ - (I[45] = (T)(img)(_p7##x,_p4##y,z,c)), \ - (I[60] = (T)(img)(_p7##x,_p3##y,z,c)), \ - (I[75] = (T)(img)(_p7##x,_p2##y,z,c)), \ - (I[90] = (T)(img)(_p7##x,_p1##y,z,c)), \ - (I[105] = (T)(img)(_p7##x,y,z,c)), \ - (I[120] = (T)(img)(_p7##x,_n1##y,z,c)), \ - (I[135] = (T)(img)(_p7##x,_n2##y,z,c)), \ - (I[150] = (T)(img)(_p7##x,_n3##y,z,c)), \ - (I[165] = (T)(img)(_p7##x,_n4##y,z,c)), \ - (I[180] = (T)(img)(_p7##x,_n5##y,z,c)), \ - (I[195] = (T)(img)(_p7##x,_n6##y,z,c)), \ - (I[210] = (T)(img)(_p7##x,_n7##y,z,c)), \ - (I[1] = (T)(img)(_p6##x,_p7##y,z,c)), \ - (I[16] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[31] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[46] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[61] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[76] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[91] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[106] = (T)(img)(_p6##x,y,z,c)), \ - (I[121] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[136] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[151] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[166] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[181] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[196] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[211] = (T)(img)(_p6##x,_n7##y,z,c)), \ - (I[2] = (T)(img)(_p5##x,_p7##y,z,c)), \ - (I[17] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[32] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[47] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[62] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[77] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[92] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[107] = (T)(img)(_p5##x,y,z,c)), \ - (I[122] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[137] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[152] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[167] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[182] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[197] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[212] = (T)(img)(_p5##x,_n7##y,z,c)), \ - (I[3] = (T)(img)(_p4##x,_p7##y,z,c)), \ - (I[18] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[33] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[48] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[63] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[78] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[93] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[108] = (T)(img)(_p4##x,y,z,c)), \ - (I[123] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[138] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[153] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[168] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[183] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[198] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[213] = (T)(img)(_p4##x,_n7##y,z,c)), \ - (I[4] = (T)(img)(_p3##x,_p7##y,z,c)), \ - (I[19] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[34] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[49] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[64] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[79] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[94] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[109] = (T)(img)(_p3##x,y,z,c)), \ - (I[124] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[139] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[154] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[169] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[184] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[199] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[214] = (T)(img)(_p3##x,_n7##y,z,c)), \ - (I[5] = (T)(img)(_p2##x,_p7##y,z,c)), \ - (I[20] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[35] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[50] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[65] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[80] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[95] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[110] = (T)(img)(_p2##x,y,z,c)), \ - (I[125] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[140] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[155] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[170] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[185] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[200] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[215] = (T)(img)(_p2##x,_n7##y,z,c)), \ - (I[6] = (T)(img)(_p1##x,_p7##y,z,c)), \ - (I[21] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[36] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[51] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[66] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[81] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[96] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[111] = (T)(img)(_p1##x,y,z,c)), \ - (I[126] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[141] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[156] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[171] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[186] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[201] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[216] = (T)(img)(_p1##x,_n7##y,z,c)), \ - (I[7] = (T)(img)(x,_p7##y,z,c)), \ - (I[22] = (T)(img)(x,_p6##y,z,c)), \ - (I[37] = (T)(img)(x,_p5##y,z,c)), \ - (I[52] = (T)(img)(x,_p4##y,z,c)), \ - (I[67] = (T)(img)(x,_p3##y,z,c)), \ - (I[82] = (T)(img)(x,_p2##y,z,c)), \ - (I[97] = (T)(img)(x,_p1##y,z,c)), \ - (I[112] = (T)(img)(x,y,z,c)), \ - (I[127] = (T)(img)(x,_n1##y,z,c)), \ - (I[142] = (T)(img)(x,_n2##y,z,c)), \ - (I[157] = (T)(img)(x,_n3##y,z,c)), \ - (I[172] = (T)(img)(x,_n4##y,z,c)), \ - (I[187] = (T)(img)(x,_n5##y,z,c)), \ - (I[202] = (T)(img)(x,_n6##y,z,c)), \ - (I[217] = (T)(img)(x,_n7##y,z,c)), \ - (I[8] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[23] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[38] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[53] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[68] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[83] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[98] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[113] = (T)(img)(_n1##x,y,z,c)), \ - (I[128] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[143] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[158] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[173] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[188] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[203] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[218] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[9] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[24] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[39] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[54] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[69] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[84] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[99] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[114] = (T)(img)(_n2##x,y,z,c)), \ - (I[129] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[144] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[159] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[174] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[189] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[204] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[219] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[10] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[25] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[40] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[55] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[70] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[85] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[100] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[115] = (T)(img)(_n3##x,y,z,c)), \ - (I[130] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[145] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[160] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[175] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[190] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[205] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[220] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[11] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[26] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[41] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[56] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[71] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[86] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[101] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[116] = (T)(img)(_n4##x,y,z,c)), \ - (I[131] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[146] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[161] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[176] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[191] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[206] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[221] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[12] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[27] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[42] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[57] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[72] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[87] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[102] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[117] = (T)(img)(_n5##x,y,z,c)), \ - (I[132] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[147] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[162] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[177] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[192] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[207] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[222] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[13] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[28] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[43] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[58] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[73] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[88] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[103] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[118] = (T)(img)(_n6##x,y,z,c)), \ - (I[133] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[148] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[163] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[178] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[193] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[208] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[223] = (T)(img)(_n6##x,_n7##y,z,c)), \ - x + 7>=(img).width()?(img).width() - 1:x + 7); \ - x<=(int)(x1) && ((_n7##x<(img).width() && ( \ - (I[14] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[29] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[44] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[59] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[74] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[89] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[104] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[119] = (T)(img)(_n7##x,y,z,c)), \ - (I[134] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[149] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[164] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[179] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[194] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[209] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[224] = (T)(img)(_n7##x,_n7##y,z,c)),1)) || \ - _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], \ - I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], \ - I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], \ - I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], \ - I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], \ - I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], \ - I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], \ - I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], \ - I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], \ - I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], \ - I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], \ - I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], \ - I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], \ - I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], \ - I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], \ - _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x) - -#define cimg_get15x15(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p7##x,_p7##y,z,c), I[1] = (T)(img)(_p6##x,_p7##y,z,c), I[2] = (T)(img)(_p5##x,_p7##y,z,c), I[3] = (T)(img)(_p4##x,_p7##y,z,c), I[4] = (T)(img)(_p3##x,_p7##y,z,c), I[5] = (T)(img)(_p2##x,_p7##y,z,c), I[6] = (T)(img)(_p1##x,_p7##y,z,c), I[7] = (T)(img)(x,_p7##y,z,c), I[8] = (T)(img)(_n1##x,_p7##y,z,c), I[9] = (T)(img)(_n2##x,_p7##y,z,c), I[10] = (T)(img)(_n3##x,_p7##y,z,c), I[11] = (T)(img)(_n4##x,_p7##y,z,c), I[12] = (T)(img)(_n5##x,_p7##y,z,c), I[13] = (T)(img)(_n6##x,_p7##y,z,c), I[14] = (T)(img)(_n7##x,_p7##y,z,c), \ - I[15] = (T)(img)(_p7##x,_p6##y,z,c), I[16] = (T)(img)(_p6##x,_p6##y,z,c), I[17] = (T)(img)(_p5##x,_p6##y,z,c), I[18] = (T)(img)(_p4##x,_p6##y,z,c), I[19] = (T)(img)(_p3##x,_p6##y,z,c), I[20] = (T)(img)(_p2##x,_p6##y,z,c), I[21] = (T)(img)(_p1##x,_p6##y,z,c), I[22] = (T)(img)(x,_p6##y,z,c), I[23] = (T)(img)(_n1##x,_p6##y,z,c), I[24] = (T)(img)(_n2##x,_p6##y,z,c), I[25] = (T)(img)(_n3##x,_p6##y,z,c), I[26] = (T)(img)(_n4##x,_p6##y,z,c), I[27] = (T)(img)(_n5##x,_p6##y,z,c), I[28] = (T)(img)(_n6##x,_p6##y,z,c), I[29] = (T)(img)(_n7##x,_p6##y,z,c), \ - I[30] = (T)(img)(_p7##x,_p5##y,z,c), I[31] = (T)(img)(_p6##x,_p5##y,z,c), I[32] = (T)(img)(_p5##x,_p5##y,z,c), I[33] = (T)(img)(_p4##x,_p5##y,z,c), I[34] = (T)(img)(_p3##x,_p5##y,z,c), I[35] = (T)(img)(_p2##x,_p5##y,z,c), I[36] = (T)(img)(_p1##x,_p5##y,z,c), I[37] = (T)(img)(x,_p5##y,z,c), I[38] = (T)(img)(_n1##x,_p5##y,z,c), I[39] = (T)(img)(_n2##x,_p5##y,z,c), I[40] = (T)(img)(_n3##x,_p5##y,z,c), I[41] = (T)(img)(_n4##x,_p5##y,z,c), I[42] = (T)(img)(_n5##x,_p5##y,z,c), I[43] = (T)(img)(_n6##x,_p5##y,z,c), I[44] = (T)(img)(_n7##x,_p5##y,z,c), \ - I[45] = (T)(img)(_p7##x,_p4##y,z,c), I[46] = (T)(img)(_p6##x,_p4##y,z,c), I[47] = (T)(img)(_p5##x,_p4##y,z,c), I[48] = (T)(img)(_p4##x,_p4##y,z,c), I[49] = (T)(img)(_p3##x,_p4##y,z,c), I[50] = (T)(img)(_p2##x,_p4##y,z,c), I[51] = (T)(img)(_p1##x,_p4##y,z,c), I[52] = (T)(img)(x,_p4##y,z,c), I[53] = (T)(img)(_n1##x,_p4##y,z,c), I[54] = (T)(img)(_n2##x,_p4##y,z,c), I[55] = (T)(img)(_n3##x,_p4##y,z,c), I[56] = (T)(img)(_n4##x,_p4##y,z,c), I[57] = (T)(img)(_n5##x,_p4##y,z,c), I[58] = (T)(img)(_n6##x,_p4##y,z,c), I[59] = (T)(img)(_n7##x,_p4##y,z,c), \ - I[60] = (T)(img)(_p7##x,_p3##y,z,c), I[61] = (T)(img)(_p6##x,_p3##y,z,c), I[62] = (T)(img)(_p5##x,_p3##y,z,c), I[63] = (T)(img)(_p4##x,_p3##y,z,c), I[64] = (T)(img)(_p3##x,_p3##y,z,c), I[65] = (T)(img)(_p2##x,_p3##y,z,c), I[66] = (T)(img)(_p1##x,_p3##y,z,c), I[67] = (T)(img)(x,_p3##y,z,c), I[68] = (T)(img)(_n1##x,_p3##y,z,c), I[69] = (T)(img)(_n2##x,_p3##y,z,c), I[70] = (T)(img)(_n3##x,_p3##y,z,c), I[71] = (T)(img)(_n4##x,_p3##y,z,c), I[72] = (T)(img)(_n5##x,_p3##y,z,c), I[73] = (T)(img)(_n6##x,_p3##y,z,c), I[74] = (T)(img)(_n7##x,_p3##y,z,c), \ - I[75] = (T)(img)(_p7##x,_p2##y,z,c), I[76] = (T)(img)(_p6##x,_p2##y,z,c), I[77] = (T)(img)(_p5##x,_p2##y,z,c), I[78] = (T)(img)(_p4##x,_p2##y,z,c), I[79] = (T)(img)(_p3##x,_p2##y,z,c), I[80] = (T)(img)(_p2##x,_p2##y,z,c), I[81] = (T)(img)(_p1##x,_p2##y,z,c), I[82] = (T)(img)(x,_p2##y,z,c), I[83] = (T)(img)(_n1##x,_p2##y,z,c), I[84] = (T)(img)(_n2##x,_p2##y,z,c), I[85] = (T)(img)(_n3##x,_p2##y,z,c), I[86] = (T)(img)(_n4##x,_p2##y,z,c), I[87] = (T)(img)(_n5##x,_p2##y,z,c), I[88] = (T)(img)(_n6##x,_p2##y,z,c), I[89] = (T)(img)(_n7##x,_p2##y,z,c), \ - I[90] = (T)(img)(_p7##x,_p1##y,z,c), I[91] = (T)(img)(_p6##x,_p1##y,z,c), I[92] = (T)(img)(_p5##x,_p1##y,z,c), I[93] = (T)(img)(_p4##x,_p1##y,z,c), I[94] = (T)(img)(_p3##x,_p1##y,z,c), I[95] = (T)(img)(_p2##x,_p1##y,z,c), I[96] = (T)(img)(_p1##x,_p1##y,z,c), I[97] = (T)(img)(x,_p1##y,z,c), I[98] = (T)(img)(_n1##x,_p1##y,z,c), I[99] = (T)(img)(_n2##x,_p1##y,z,c), I[100] = (T)(img)(_n3##x,_p1##y,z,c), I[101] = (T)(img)(_n4##x,_p1##y,z,c), I[102] = (T)(img)(_n5##x,_p1##y,z,c), I[103] = (T)(img)(_n6##x,_p1##y,z,c), I[104] = (T)(img)(_n7##x,_p1##y,z,c), \ - I[105] = (T)(img)(_p7##x,y,z,c), I[106] = (T)(img)(_p6##x,y,z,c), I[107] = (T)(img)(_p5##x,y,z,c), I[108] = (T)(img)(_p4##x,y,z,c), I[109] = (T)(img)(_p3##x,y,z,c), I[110] = (T)(img)(_p2##x,y,z,c), I[111] = (T)(img)(_p1##x,y,z,c), I[112] = (T)(img)(x,y,z,c), I[113] = (T)(img)(_n1##x,y,z,c), I[114] = (T)(img)(_n2##x,y,z,c), I[115] = (T)(img)(_n3##x,y,z,c), I[116] = (T)(img)(_n4##x,y,z,c), I[117] = (T)(img)(_n5##x,y,z,c), I[118] = (T)(img)(_n6##x,y,z,c), I[119] = (T)(img)(_n7##x,y,z,c), \ - I[120] = (T)(img)(_p7##x,_n1##y,z,c), I[121] = (T)(img)(_p6##x,_n1##y,z,c), I[122] = (T)(img)(_p5##x,_n1##y,z,c), I[123] = (T)(img)(_p4##x,_n1##y,z,c), I[124] = (T)(img)(_p3##x,_n1##y,z,c), I[125] = (T)(img)(_p2##x,_n1##y,z,c), I[126] = (T)(img)(_p1##x,_n1##y,z,c), I[127] = (T)(img)(x,_n1##y,z,c), I[128] = (T)(img)(_n1##x,_n1##y,z,c), I[129] = (T)(img)(_n2##x,_n1##y,z,c), I[130] = (T)(img)(_n3##x,_n1##y,z,c), I[131] = (T)(img)(_n4##x,_n1##y,z,c), I[132] = (T)(img)(_n5##x,_n1##y,z,c), I[133] = (T)(img)(_n6##x,_n1##y,z,c), I[134] = (T)(img)(_n7##x,_n1##y,z,c), \ - I[135] = (T)(img)(_p7##x,_n2##y,z,c), I[136] = (T)(img)(_p6##x,_n2##y,z,c), I[137] = (T)(img)(_p5##x,_n2##y,z,c), I[138] = (T)(img)(_p4##x,_n2##y,z,c), I[139] = (T)(img)(_p3##x,_n2##y,z,c), I[140] = (T)(img)(_p2##x,_n2##y,z,c), I[141] = (T)(img)(_p1##x,_n2##y,z,c), I[142] = (T)(img)(x,_n2##y,z,c), I[143] = (T)(img)(_n1##x,_n2##y,z,c), I[144] = (T)(img)(_n2##x,_n2##y,z,c), I[145] = (T)(img)(_n3##x,_n2##y,z,c), I[146] = (T)(img)(_n4##x,_n2##y,z,c), I[147] = (T)(img)(_n5##x,_n2##y,z,c), I[148] = (T)(img)(_n6##x,_n2##y,z,c), I[149] = (T)(img)(_n7##x,_n2##y,z,c), \ - I[150] = (T)(img)(_p7##x,_n3##y,z,c), I[151] = (T)(img)(_p6##x,_n3##y,z,c), I[152] = (T)(img)(_p5##x,_n3##y,z,c), I[153] = (T)(img)(_p4##x,_n3##y,z,c), I[154] = (T)(img)(_p3##x,_n3##y,z,c), I[155] = (T)(img)(_p2##x,_n3##y,z,c), I[156] = (T)(img)(_p1##x,_n3##y,z,c), I[157] = (T)(img)(x,_n3##y,z,c), I[158] = (T)(img)(_n1##x,_n3##y,z,c), I[159] = (T)(img)(_n2##x,_n3##y,z,c), I[160] = (T)(img)(_n3##x,_n3##y,z,c), I[161] = (T)(img)(_n4##x,_n3##y,z,c), I[162] = (T)(img)(_n5##x,_n3##y,z,c), I[163] = (T)(img)(_n6##x,_n3##y,z,c), I[164] = (T)(img)(_n7##x,_n3##y,z,c), \ - I[165] = (T)(img)(_p7##x,_n4##y,z,c), I[166] = (T)(img)(_p6##x,_n4##y,z,c), I[167] = (T)(img)(_p5##x,_n4##y,z,c), I[168] = (T)(img)(_p4##x,_n4##y,z,c), I[169] = (T)(img)(_p3##x,_n4##y,z,c), I[170] = (T)(img)(_p2##x,_n4##y,z,c), I[171] = (T)(img)(_p1##x,_n4##y,z,c), I[172] = (T)(img)(x,_n4##y,z,c), I[173] = (T)(img)(_n1##x,_n4##y,z,c), I[174] = (T)(img)(_n2##x,_n4##y,z,c), I[175] = (T)(img)(_n3##x,_n4##y,z,c), I[176] = (T)(img)(_n4##x,_n4##y,z,c), I[177] = (T)(img)(_n5##x,_n4##y,z,c), I[178] = (T)(img)(_n6##x,_n4##y,z,c), I[179] = (T)(img)(_n7##x,_n4##y,z,c), \ - I[180] = (T)(img)(_p7##x,_n5##y,z,c), I[181] = (T)(img)(_p6##x,_n5##y,z,c), I[182] = (T)(img)(_p5##x,_n5##y,z,c), I[183] = (T)(img)(_p4##x,_n5##y,z,c), I[184] = (T)(img)(_p3##x,_n5##y,z,c), I[185] = (T)(img)(_p2##x,_n5##y,z,c), I[186] = (T)(img)(_p1##x,_n5##y,z,c), I[187] = (T)(img)(x,_n5##y,z,c), I[188] = (T)(img)(_n1##x,_n5##y,z,c), I[189] = (T)(img)(_n2##x,_n5##y,z,c), I[190] = (T)(img)(_n3##x,_n5##y,z,c), I[191] = (T)(img)(_n4##x,_n5##y,z,c), I[192] = (T)(img)(_n5##x,_n5##y,z,c), I[193] = (T)(img)(_n6##x,_n5##y,z,c), I[194] = (T)(img)(_n7##x,_n5##y,z,c), \ - I[195] = (T)(img)(_p7##x,_n6##y,z,c), I[196] = (T)(img)(_p6##x,_n6##y,z,c), I[197] = (T)(img)(_p5##x,_n6##y,z,c), I[198] = (T)(img)(_p4##x,_n6##y,z,c), I[199] = (T)(img)(_p3##x,_n6##y,z,c), I[200] = (T)(img)(_p2##x,_n6##y,z,c), I[201] = (T)(img)(_p1##x,_n6##y,z,c), I[202] = (T)(img)(x,_n6##y,z,c), I[203] = (T)(img)(_n1##x,_n6##y,z,c), I[204] = (T)(img)(_n2##x,_n6##y,z,c), I[205] = (T)(img)(_n3##x,_n6##y,z,c), I[206] = (T)(img)(_n4##x,_n6##y,z,c), I[207] = (T)(img)(_n5##x,_n6##y,z,c), I[208] = (T)(img)(_n6##x,_n6##y,z,c), I[209] = (T)(img)(_n7##x,_n6##y,z,c), \ - I[210] = (T)(img)(_p7##x,_n7##y,z,c), I[211] = (T)(img)(_p6##x,_n7##y,z,c), I[212] = (T)(img)(_p5##x,_n7##y,z,c), I[213] = (T)(img)(_p4##x,_n7##y,z,c), I[214] = (T)(img)(_p3##x,_n7##y,z,c), I[215] = (T)(img)(_p2##x,_n7##y,z,c), I[216] = (T)(img)(_p1##x,_n7##y,z,c), I[217] = (T)(img)(x,_n7##y,z,c), I[218] = (T)(img)(_n1##x,_n7##y,z,c), I[219] = (T)(img)(_n2##x,_n7##y,z,c), I[220] = (T)(img)(_n3##x,_n7##y,z,c), I[221] = (T)(img)(_n4##x,_n7##y,z,c), I[222] = (T)(img)(_n5##x,_n7##y,z,c), I[223] = (T)(img)(_n6##x,_n7##y,z,c), I[224] = (T)(img)(_n7##x,_n7##y,z,c); - -// Define 16x16 loop macros -//------------------------- -#define cimg_for16(bound,i) for (int i = 0, \ - _p7##i = 0, _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6, \ - _n7##i = 7>=(int)(bound)?(int)(bound) - 1:7, \ - _n8##i = 8>=(int)(bound)?(int)(bound) - 1:8; \ - _n8##i<(int)(bound) || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i) - -#define cimg_for16X(img,x) cimg_for16((img)._width,x) -#define cimg_for16Y(img,y) cimg_for16((img)._height,y) -#define cimg_for16Z(img,z) cimg_for16((img)._depth,z) -#define cimg_for16C(img,c) cimg_for16((img)._spectrum,c) -#define cimg_for16XY(img,x,y) cimg_for16Y(img,y) cimg_for16X(img,x) -#define cimg_for16XZ(img,x,z) cimg_for16Z(img,z) cimg_for16X(img,x) -#define cimg_for16XC(img,x,c) cimg_for16C(img,c) cimg_for16X(img,x) -#define cimg_for16YZ(img,y,z) cimg_for16Z(img,z) cimg_for16Y(img,y) -#define cimg_for16YC(img,y,c) cimg_for16C(img,c) cimg_for16Y(img,y) -#define cimg_for16ZC(img,z,c) cimg_for16C(img,c) cimg_for16Z(img,z) -#define cimg_for16XYZ(img,x,y,z) cimg_for16Z(img,z) cimg_for16XY(img,x,y) -#define cimg_for16XZC(img,x,z,c) cimg_for16C(img,c) cimg_for16XZ(img,x,z) -#define cimg_for16YZC(img,y,z,c) cimg_for16C(img,c) cimg_for16YZ(img,y,z) -#define cimg_for16XYZC(img,x,y,z,c) cimg_for16C(img,c) cimg_for16XYZ(img,x,y,z) - -#define cimg_for_in16(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p7##i = i - 7<0?0:i - 7, \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6, \ - _n7##i = i + 7>=(int)(bound)?(int)(bound) - 1:i + 7, \ - _n8##i = i + 8>=(int)(bound)?(int)(bound) - 1:i + 8; \ - i<=(int)(i1) && (_n8##i<(int)(bound) || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i) - -#define cimg_for_in16X(img,x0,x1,x) cimg_for_in16((img)._width,x0,x1,x) -#define cimg_for_in16Y(img,y0,y1,y) cimg_for_in16((img)._height,y0,y1,y) -#define cimg_for_in16Z(img,z0,z1,z) cimg_for_in16((img)._depth,z0,z1,z) -#define cimg_for_in16C(img,c0,c1,c) cimg_for_in16((img)._spectrum,c0,c1,c) -#define cimg_for_in16XY(img,x0,y0,x1,y1,x,y) cimg_for_in16Y(img,y0,y1,y) cimg_for_in16X(img,x0,x1,x) -#define cimg_for_in16XZ(img,x0,z0,x1,z1,x,z) cimg_for_in16Z(img,z0,z1,z) cimg_for_in16X(img,x0,x1,x) -#define cimg_for_in16XC(img,x0,c0,x1,c1,x,c) cimg_for_in16C(img,c0,c1,c) cimg_for_in16X(img,x0,x1,x) -#define cimg_for_in16YZ(img,y0,z0,y1,z1,y,z) cimg_for_in16Z(img,z0,z1,z) cimg_for_in16Y(img,y0,y1,y) -#define cimg_for_in16YC(img,y0,c0,y1,c1,y,c) cimg_for_in16C(img,c0,c1,c) cimg_for_in16Y(img,y0,y1,y) -#define cimg_for_in16ZC(img,z0,c0,z1,c1,z,c) cimg_for_in16C(img,c0,c1,c) cimg_for_in16Z(img,z0,z1,z) -#define cimg_for_in16XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in16Z(img,z0,z1,z) cimg_for_in16XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in16XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in16C(img,c0,c1,c) cimg_for_in16XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in16YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in16C(img,c0,c1,c) cimg_for_in16YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in16XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in16C(img,c0,c1,c) cimg_for_in16XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for16x16(img,x,y,z,c,I,T) \ - cimg_for16((img)._height,y) for (int x = 0, \ - _p7##x = 0, _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = 6>=((img)._width)?(img).width() - 1:6, \ - _n7##x = 7>=((img)._width)?(img).width() - 1:7, \ - _n8##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = I[7] = (T)(img)(0,_p7##y,z,c)), \ - (I[16] = I[17] = I[18] = I[19] = I[20] = I[21] = I[22] = I[23] = (T)(img)(0,_p6##y,z,c)), \ - (I[32] = I[33] = I[34] = I[35] = I[36] = I[37] = I[38] = I[39] = (T)(img)(0,_p5##y,z,c)), \ - (I[48] = I[49] = I[50] = I[51] = I[52] = I[53] = I[54] = I[55] = (T)(img)(0,_p4##y,z,c)), \ - (I[64] = I[65] = I[66] = I[67] = I[68] = I[69] = I[70] = I[71] = (T)(img)(0,_p3##y,z,c)), \ - (I[80] = I[81] = I[82] = I[83] = I[84] = I[85] = I[86] = I[87] = (T)(img)(0,_p2##y,z,c)), \ - (I[96] = I[97] = I[98] = I[99] = I[100] = I[101] = I[102] = I[103] = (T)(img)(0,_p1##y,z,c)), \ - (I[112] = I[113] = I[114] = I[115] = I[116] = I[117] = I[118] = I[119] = (T)(img)(0,y,z,c)), \ - (I[128] = I[129] = I[130] = I[131] = I[132] = I[133] = I[134] = I[135] = (T)(img)(0,_n1##y,z,c)), \ - (I[144] = I[145] = I[146] = I[147] = I[148] = I[149] = I[150] = I[151] = (T)(img)(0,_n2##y,z,c)), \ - (I[160] = I[161] = I[162] = I[163] = I[164] = I[165] = I[166] = I[167] = (T)(img)(0,_n3##y,z,c)), \ - (I[176] = I[177] = I[178] = I[179] = I[180] = I[181] = I[182] = I[183] = (T)(img)(0,_n4##y,z,c)), \ - (I[192] = I[193] = I[194] = I[195] = I[196] = I[197] = I[198] = I[199] = (T)(img)(0,_n5##y,z,c)), \ - (I[208] = I[209] = I[210] = I[211] = I[212] = I[213] = I[214] = I[215] = (T)(img)(0,_n6##y,z,c)), \ - (I[224] = I[225] = I[226] = I[227] = I[228] = I[229] = I[230] = I[231] = (T)(img)(0,_n7##y,z,c)), \ - (I[240] = I[241] = I[242] = I[243] = I[244] = I[245] = I[246] = I[247] = (T)(img)(0,_n8##y,z,c)), \ - (I[8] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[24] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[40] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[56] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[72] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[88] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[104] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[120] = (T)(img)(_n1##x,y,z,c)), \ - (I[136] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[152] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[168] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[184] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[200] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[216] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[232] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[248] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[9] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[25] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[41] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[57] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[73] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[89] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[105] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[121] = (T)(img)(_n2##x,y,z,c)), \ - (I[137] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[153] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[169] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[185] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[201] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[217] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[233] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[249] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[10] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[26] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[42] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[58] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[74] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[90] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[106] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[122] = (T)(img)(_n3##x,y,z,c)), \ - (I[138] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[154] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[170] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[186] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[202] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[218] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[234] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[250] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[11] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[27] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[43] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[59] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[75] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[91] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[107] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[123] = (T)(img)(_n4##x,y,z,c)), \ - (I[139] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[155] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[171] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[187] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[203] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[219] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[235] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[251] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[12] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[28] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[44] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[60] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[76] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[92] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[108] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[124] = (T)(img)(_n5##x,y,z,c)), \ - (I[140] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[156] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[172] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[188] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[204] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[220] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[236] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[252] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[13] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[29] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[45] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[61] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[77] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[93] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[109] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[125] = (T)(img)(_n6##x,y,z,c)), \ - (I[141] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[157] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[173] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[189] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[205] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[221] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[237] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[253] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[14] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[30] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[46] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[62] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[78] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[94] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[110] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[126] = (T)(img)(_n7##x,y,z,c)), \ - (I[142] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[158] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[174] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[190] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[206] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[222] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[238] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[254] = (T)(img)(_n7##x,_n8##y,z,c)), \ - 8>=((img)._width)?(img).width() - 1:8); \ - (_n8##x<(img).width() && ( \ - (I[15] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[31] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[47] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[63] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[79] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[95] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[111] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[127] = (T)(img)(_n8##x,y,z,c)), \ - (I[143] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[159] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[175] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[191] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[207] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[223] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[239] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[255] = (T)(img)(_n8##x,_n8##y,z,c)),1)) || \ - _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], \ - I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], \ - I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], \ - I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], \ - I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], \ - I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], \ - I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], \ - I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], \ - I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], \ - I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], \ - I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], \ - I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], \ - I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], \ - I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], \ - I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], \ - I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], \ - _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x) - -#define cimg_for_in16x16(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in16((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p7##x = x - 7<0?0:x - 7, \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = x + 6>=(img).width()?(img).width() - 1:x + 6, \ - _n7##x = x + 7>=(img).width()?(img).width() - 1:x + 7, \ - _n8##x = (int)( \ - (I[0] = (T)(img)(_p7##x,_p7##y,z,c)), \ - (I[16] = (T)(img)(_p7##x,_p6##y,z,c)), \ - (I[32] = (T)(img)(_p7##x,_p5##y,z,c)), \ - (I[48] = (T)(img)(_p7##x,_p4##y,z,c)), \ - (I[64] = (T)(img)(_p7##x,_p3##y,z,c)), \ - (I[80] = (T)(img)(_p7##x,_p2##y,z,c)), \ - (I[96] = (T)(img)(_p7##x,_p1##y,z,c)), \ - (I[112] = (T)(img)(_p7##x,y,z,c)), \ - (I[128] = (T)(img)(_p7##x,_n1##y,z,c)), \ - (I[144] = (T)(img)(_p7##x,_n2##y,z,c)), \ - (I[160] = (T)(img)(_p7##x,_n3##y,z,c)), \ - (I[176] = (T)(img)(_p7##x,_n4##y,z,c)), \ - (I[192] = (T)(img)(_p7##x,_n5##y,z,c)), \ - (I[208] = (T)(img)(_p7##x,_n6##y,z,c)), \ - (I[224] = (T)(img)(_p7##x,_n7##y,z,c)), \ - (I[240] = (T)(img)(_p7##x,_n8##y,z,c)), \ - (I[1] = (T)(img)(_p6##x,_p7##y,z,c)), \ - (I[17] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[33] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[49] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[65] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[81] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[97] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[113] = (T)(img)(_p6##x,y,z,c)), \ - (I[129] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[145] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[161] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[177] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[193] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[209] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[225] = (T)(img)(_p6##x,_n7##y,z,c)), \ - (I[241] = (T)(img)(_p6##x,_n8##y,z,c)), \ - (I[2] = (T)(img)(_p5##x,_p7##y,z,c)), \ - (I[18] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[34] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[50] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[66] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[82] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[98] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[114] = (T)(img)(_p5##x,y,z,c)), \ - (I[130] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[146] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[162] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[178] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[194] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[210] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[226] = (T)(img)(_p5##x,_n7##y,z,c)), \ - (I[242] = (T)(img)(_p5##x,_n8##y,z,c)), \ - (I[3] = (T)(img)(_p4##x,_p7##y,z,c)), \ - (I[19] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[35] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[51] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[67] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[83] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[99] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[115] = (T)(img)(_p4##x,y,z,c)), \ - (I[131] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[147] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[163] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[179] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[195] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[211] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[227] = (T)(img)(_p4##x,_n7##y,z,c)), \ - (I[243] = (T)(img)(_p4##x,_n8##y,z,c)), \ - (I[4] = (T)(img)(_p3##x,_p7##y,z,c)), \ - (I[20] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[36] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[52] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[68] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[84] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[100] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[116] = (T)(img)(_p3##x,y,z,c)), \ - (I[132] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[148] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[164] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[180] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[196] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[212] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[228] = (T)(img)(_p3##x,_n7##y,z,c)), \ - (I[244] = (T)(img)(_p3##x,_n8##y,z,c)), \ - (I[5] = (T)(img)(_p2##x,_p7##y,z,c)), \ - (I[21] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[37] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[53] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[69] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[85] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[101] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[117] = (T)(img)(_p2##x,y,z,c)), \ - (I[133] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[149] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[165] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[181] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[197] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[213] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[229] = (T)(img)(_p2##x,_n7##y,z,c)), \ - (I[245] = (T)(img)(_p2##x,_n8##y,z,c)), \ - (I[6] = (T)(img)(_p1##x,_p7##y,z,c)), \ - (I[22] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[38] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[54] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[70] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[86] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[102] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[118] = (T)(img)(_p1##x,y,z,c)), \ - (I[134] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[150] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[166] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[182] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[198] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[214] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[230] = (T)(img)(_p1##x,_n7##y,z,c)), \ - (I[246] = (T)(img)(_p1##x,_n8##y,z,c)), \ - (I[7] = (T)(img)(x,_p7##y,z,c)), \ - (I[23] = (T)(img)(x,_p6##y,z,c)), \ - (I[39] = (T)(img)(x,_p5##y,z,c)), \ - (I[55] = (T)(img)(x,_p4##y,z,c)), \ - (I[71] = (T)(img)(x,_p3##y,z,c)), \ - (I[87] = (T)(img)(x,_p2##y,z,c)), \ - (I[103] = (T)(img)(x,_p1##y,z,c)), \ - (I[119] = (T)(img)(x,y,z,c)), \ - (I[135] = (T)(img)(x,_n1##y,z,c)), \ - (I[151] = (T)(img)(x,_n2##y,z,c)), \ - (I[167] = (T)(img)(x,_n3##y,z,c)), \ - (I[183] = (T)(img)(x,_n4##y,z,c)), \ - (I[199] = (T)(img)(x,_n5##y,z,c)), \ - (I[215] = (T)(img)(x,_n6##y,z,c)), \ - (I[231] = (T)(img)(x,_n7##y,z,c)), \ - (I[247] = (T)(img)(x,_n8##y,z,c)), \ - (I[8] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[24] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[40] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[56] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[72] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[88] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[104] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[120] = (T)(img)(_n1##x,y,z,c)), \ - (I[136] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[152] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[168] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[184] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[200] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[216] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[232] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[248] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[9] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[25] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[41] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[57] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[73] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[89] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[105] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[121] = (T)(img)(_n2##x,y,z,c)), \ - (I[137] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[153] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[169] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[185] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[201] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[217] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[233] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[249] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[10] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[26] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[42] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[58] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[74] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[90] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[106] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[122] = (T)(img)(_n3##x,y,z,c)), \ - (I[138] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[154] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[170] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[186] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[202] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[218] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[234] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[250] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[11] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[27] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[43] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[59] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[75] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[91] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[107] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[123] = (T)(img)(_n4##x,y,z,c)), \ - (I[139] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[155] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[171] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[187] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[203] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[219] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[235] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[251] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[12] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[28] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[44] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[60] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[76] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[92] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[108] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[124] = (T)(img)(_n5##x,y,z,c)), \ - (I[140] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[156] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[172] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[188] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[204] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[220] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[236] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[252] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[13] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[29] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[45] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[61] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[77] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[93] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[109] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[125] = (T)(img)(_n6##x,y,z,c)), \ - (I[141] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[157] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[173] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[189] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[205] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[221] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[237] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[253] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[14] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[30] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[46] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[62] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[78] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[94] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[110] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[126] = (T)(img)(_n7##x,y,z,c)), \ - (I[142] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[158] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[174] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[190] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[206] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[222] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[238] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[254] = (T)(img)(_n7##x,_n8##y,z,c)), \ - x + 8>=(img).width()?(img).width() - 1:x + 8); \ - x<=(int)(x1) && ((_n8##x<(img).width() && ( \ - (I[15] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[31] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[47] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[63] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[79] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[95] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[111] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[127] = (T)(img)(_n8##x,y,z,c)), \ - (I[143] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[159] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[175] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[191] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[207] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[223] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[239] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[255] = (T)(img)(_n8##x,_n8##y,z,c)),1)) || \ - _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], \ - I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], \ - I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], \ - I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], \ - I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], \ - I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], \ - I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], \ - I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], \ - I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], \ - I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], \ - I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], \ - I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], \ - I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], \ - I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], \ - I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], \ - I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], \ - _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x) - -#define cimg_get16x16(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p7##x,_p7##y,z,c), I[1] = (T)(img)(_p6##x,_p7##y,z,c), I[2] = (T)(img)(_p5##x,_p7##y,z,c), I[3] = (T)(img)(_p4##x,_p7##y,z,c), I[4] = (T)(img)(_p3##x,_p7##y,z,c), I[5] = (T)(img)(_p2##x,_p7##y,z,c), I[6] = (T)(img)(_p1##x,_p7##y,z,c), I[7] = (T)(img)(x,_p7##y,z,c), I[8] = (T)(img)(_n1##x,_p7##y,z,c), I[9] = (T)(img)(_n2##x,_p7##y,z,c), I[10] = (T)(img)(_n3##x,_p7##y,z,c), I[11] = (T)(img)(_n4##x,_p7##y,z,c), I[12] = (T)(img)(_n5##x,_p7##y,z,c), I[13] = (T)(img)(_n6##x,_p7##y,z,c), I[14] = (T)(img)(_n7##x,_p7##y,z,c), I[15] = (T)(img)(_n8##x,_p7##y,z,c), \ - I[16] = (T)(img)(_p7##x,_p6##y,z,c), I[17] = (T)(img)(_p6##x,_p6##y,z,c), I[18] = (T)(img)(_p5##x,_p6##y,z,c), I[19] = (T)(img)(_p4##x,_p6##y,z,c), I[20] = (T)(img)(_p3##x,_p6##y,z,c), I[21] = (T)(img)(_p2##x,_p6##y,z,c), I[22] = (T)(img)(_p1##x,_p6##y,z,c), I[23] = (T)(img)(x,_p6##y,z,c), I[24] = (T)(img)(_n1##x,_p6##y,z,c), I[25] = (T)(img)(_n2##x,_p6##y,z,c), I[26] = (T)(img)(_n3##x,_p6##y,z,c), I[27] = (T)(img)(_n4##x,_p6##y,z,c), I[28] = (T)(img)(_n5##x,_p6##y,z,c), I[29] = (T)(img)(_n6##x,_p6##y,z,c), I[30] = (T)(img)(_n7##x,_p6##y,z,c), I[31] = (T)(img)(_n8##x,_p6##y,z,c), \ - I[32] = (T)(img)(_p7##x,_p5##y,z,c), I[33] = (T)(img)(_p6##x,_p5##y,z,c), I[34] = (T)(img)(_p5##x,_p5##y,z,c), I[35] = (T)(img)(_p4##x,_p5##y,z,c), I[36] = (T)(img)(_p3##x,_p5##y,z,c), I[37] = (T)(img)(_p2##x,_p5##y,z,c), I[38] = (T)(img)(_p1##x,_p5##y,z,c), I[39] = (T)(img)(x,_p5##y,z,c), I[40] = (T)(img)(_n1##x,_p5##y,z,c), I[41] = (T)(img)(_n2##x,_p5##y,z,c), I[42] = (T)(img)(_n3##x,_p5##y,z,c), I[43] = (T)(img)(_n4##x,_p5##y,z,c), I[44] = (T)(img)(_n5##x,_p5##y,z,c), I[45] = (T)(img)(_n6##x,_p5##y,z,c), I[46] = (T)(img)(_n7##x,_p5##y,z,c), I[47] = (T)(img)(_n8##x,_p5##y,z,c), \ - I[48] = (T)(img)(_p7##x,_p4##y,z,c), I[49] = (T)(img)(_p6##x,_p4##y,z,c), I[50] = (T)(img)(_p5##x,_p4##y,z,c), I[51] = (T)(img)(_p4##x,_p4##y,z,c), I[52] = (T)(img)(_p3##x,_p4##y,z,c), I[53] = (T)(img)(_p2##x,_p4##y,z,c), I[54] = (T)(img)(_p1##x,_p4##y,z,c), I[55] = (T)(img)(x,_p4##y,z,c), I[56] = (T)(img)(_n1##x,_p4##y,z,c), I[57] = (T)(img)(_n2##x,_p4##y,z,c), I[58] = (T)(img)(_n3##x,_p4##y,z,c), I[59] = (T)(img)(_n4##x,_p4##y,z,c), I[60] = (T)(img)(_n5##x,_p4##y,z,c), I[61] = (T)(img)(_n6##x,_p4##y,z,c), I[62] = (T)(img)(_n7##x,_p4##y,z,c), I[63] = (T)(img)(_n8##x,_p4##y,z,c), \ - I[64] = (T)(img)(_p7##x,_p3##y,z,c), I[65] = (T)(img)(_p6##x,_p3##y,z,c), I[66] = (T)(img)(_p5##x,_p3##y,z,c), I[67] = (T)(img)(_p4##x,_p3##y,z,c), I[68] = (T)(img)(_p3##x,_p3##y,z,c), I[69] = (T)(img)(_p2##x,_p3##y,z,c), I[70] = (T)(img)(_p1##x,_p3##y,z,c), I[71] = (T)(img)(x,_p3##y,z,c), I[72] = (T)(img)(_n1##x,_p3##y,z,c), I[73] = (T)(img)(_n2##x,_p3##y,z,c), I[74] = (T)(img)(_n3##x,_p3##y,z,c), I[75] = (T)(img)(_n4##x,_p3##y,z,c), I[76] = (T)(img)(_n5##x,_p3##y,z,c), I[77] = (T)(img)(_n6##x,_p3##y,z,c), I[78] = (T)(img)(_n7##x,_p3##y,z,c), I[79] = (T)(img)(_n8##x,_p3##y,z,c), \ - I[80] = (T)(img)(_p7##x,_p2##y,z,c), I[81] = (T)(img)(_p6##x,_p2##y,z,c), I[82] = (T)(img)(_p5##x,_p2##y,z,c), I[83] = (T)(img)(_p4##x,_p2##y,z,c), I[84] = (T)(img)(_p3##x,_p2##y,z,c), I[85] = (T)(img)(_p2##x,_p2##y,z,c), I[86] = (T)(img)(_p1##x,_p2##y,z,c), I[87] = (T)(img)(x,_p2##y,z,c), I[88] = (T)(img)(_n1##x,_p2##y,z,c), I[89] = (T)(img)(_n2##x,_p2##y,z,c), I[90] = (T)(img)(_n3##x,_p2##y,z,c), I[91] = (T)(img)(_n4##x,_p2##y,z,c), I[92] = (T)(img)(_n5##x,_p2##y,z,c), I[93] = (T)(img)(_n6##x,_p2##y,z,c), I[94] = (T)(img)(_n7##x,_p2##y,z,c), I[95] = (T)(img)(_n8##x,_p2##y,z,c), \ - I[96] = (T)(img)(_p7##x,_p1##y,z,c), I[97] = (T)(img)(_p6##x,_p1##y,z,c), I[98] = (T)(img)(_p5##x,_p1##y,z,c), I[99] = (T)(img)(_p4##x,_p1##y,z,c), I[100] = (T)(img)(_p3##x,_p1##y,z,c), I[101] = (T)(img)(_p2##x,_p1##y,z,c), I[102] = (T)(img)(_p1##x,_p1##y,z,c), I[103] = (T)(img)(x,_p1##y,z,c), I[104] = (T)(img)(_n1##x,_p1##y,z,c), I[105] = (T)(img)(_n2##x,_p1##y,z,c), I[106] = (T)(img)(_n3##x,_p1##y,z,c), I[107] = (T)(img)(_n4##x,_p1##y,z,c), I[108] = (T)(img)(_n5##x,_p1##y,z,c), I[109] = (T)(img)(_n6##x,_p1##y,z,c), I[110] = (T)(img)(_n7##x,_p1##y,z,c), I[111] = (T)(img)(_n8##x,_p1##y,z,c), \ - I[112] = (T)(img)(_p7##x,y,z,c), I[113] = (T)(img)(_p6##x,y,z,c), I[114] = (T)(img)(_p5##x,y,z,c), I[115] = (T)(img)(_p4##x,y,z,c), I[116] = (T)(img)(_p3##x,y,z,c), I[117] = (T)(img)(_p2##x,y,z,c), I[118] = (T)(img)(_p1##x,y,z,c), I[119] = (T)(img)(x,y,z,c), I[120] = (T)(img)(_n1##x,y,z,c), I[121] = (T)(img)(_n2##x,y,z,c), I[122] = (T)(img)(_n3##x,y,z,c), I[123] = (T)(img)(_n4##x,y,z,c), I[124] = (T)(img)(_n5##x,y,z,c), I[125] = (T)(img)(_n6##x,y,z,c), I[126] = (T)(img)(_n7##x,y,z,c), I[127] = (T)(img)(_n8##x,y,z,c), \ - I[128] = (T)(img)(_p7##x,_n1##y,z,c), I[129] = (T)(img)(_p6##x,_n1##y,z,c), I[130] = (T)(img)(_p5##x,_n1##y,z,c), I[131] = (T)(img)(_p4##x,_n1##y,z,c), I[132] = (T)(img)(_p3##x,_n1##y,z,c), I[133] = (T)(img)(_p2##x,_n1##y,z,c), I[134] = (T)(img)(_p1##x,_n1##y,z,c), I[135] = (T)(img)(x,_n1##y,z,c), I[136] = (T)(img)(_n1##x,_n1##y,z,c), I[137] = (T)(img)(_n2##x,_n1##y,z,c), I[138] = (T)(img)(_n3##x,_n1##y,z,c), I[139] = (T)(img)(_n4##x,_n1##y,z,c), I[140] = (T)(img)(_n5##x,_n1##y,z,c), I[141] = (T)(img)(_n6##x,_n1##y,z,c), I[142] = (T)(img)(_n7##x,_n1##y,z,c), I[143] = (T)(img)(_n8##x,_n1##y,z,c), \ - I[144] = (T)(img)(_p7##x,_n2##y,z,c), I[145] = (T)(img)(_p6##x,_n2##y,z,c), I[146] = (T)(img)(_p5##x,_n2##y,z,c), I[147] = (T)(img)(_p4##x,_n2##y,z,c), I[148] = (T)(img)(_p3##x,_n2##y,z,c), I[149] = (T)(img)(_p2##x,_n2##y,z,c), I[150] = (T)(img)(_p1##x,_n2##y,z,c), I[151] = (T)(img)(x,_n2##y,z,c), I[152] = (T)(img)(_n1##x,_n2##y,z,c), I[153] = (T)(img)(_n2##x,_n2##y,z,c), I[154] = (T)(img)(_n3##x,_n2##y,z,c), I[155] = (T)(img)(_n4##x,_n2##y,z,c), I[156] = (T)(img)(_n5##x,_n2##y,z,c), I[157] = (T)(img)(_n6##x,_n2##y,z,c), I[158] = (T)(img)(_n7##x,_n2##y,z,c), I[159] = (T)(img)(_n8##x,_n2##y,z,c), \ - I[160] = (T)(img)(_p7##x,_n3##y,z,c), I[161] = (T)(img)(_p6##x,_n3##y,z,c), I[162] = (T)(img)(_p5##x,_n3##y,z,c), I[163] = (T)(img)(_p4##x,_n3##y,z,c), I[164] = (T)(img)(_p3##x,_n3##y,z,c), I[165] = (T)(img)(_p2##x,_n3##y,z,c), I[166] = (T)(img)(_p1##x,_n3##y,z,c), I[167] = (T)(img)(x,_n3##y,z,c), I[168] = (T)(img)(_n1##x,_n3##y,z,c), I[169] = (T)(img)(_n2##x,_n3##y,z,c), I[170] = (T)(img)(_n3##x,_n3##y,z,c), I[171] = (T)(img)(_n4##x,_n3##y,z,c), I[172] = (T)(img)(_n5##x,_n3##y,z,c), I[173] = (T)(img)(_n6##x,_n3##y,z,c), I[174] = (T)(img)(_n7##x,_n3##y,z,c), I[175] = (T)(img)(_n8##x,_n3##y,z,c), \ - I[176] = (T)(img)(_p7##x,_n4##y,z,c), I[177] = (T)(img)(_p6##x,_n4##y,z,c), I[178] = (T)(img)(_p5##x,_n4##y,z,c), I[179] = (T)(img)(_p4##x,_n4##y,z,c), I[180] = (T)(img)(_p3##x,_n4##y,z,c), I[181] = (T)(img)(_p2##x,_n4##y,z,c), I[182] = (T)(img)(_p1##x,_n4##y,z,c), I[183] = (T)(img)(x,_n4##y,z,c), I[184] = (T)(img)(_n1##x,_n4##y,z,c), I[185] = (T)(img)(_n2##x,_n4##y,z,c), I[186] = (T)(img)(_n3##x,_n4##y,z,c), I[187] = (T)(img)(_n4##x,_n4##y,z,c), I[188] = (T)(img)(_n5##x,_n4##y,z,c), I[189] = (T)(img)(_n6##x,_n4##y,z,c), I[190] = (T)(img)(_n7##x,_n4##y,z,c), I[191] = (T)(img)(_n8##x,_n4##y,z,c), \ - I[192] = (T)(img)(_p7##x,_n5##y,z,c), I[193] = (T)(img)(_p6##x,_n5##y,z,c), I[194] = (T)(img)(_p5##x,_n5##y,z,c), I[195] = (T)(img)(_p4##x,_n5##y,z,c), I[196] = (T)(img)(_p3##x,_n5##y,z,c), I[197] = (T)(img)(_p2##x,_n5##y,z,c), I[198] = (T)(img)(_p1##x,_n5##y,z,c), I[199] = (T)(img)(x,_n5##y,z,c), I[200] = (T)(img)(_n1##x,_n5##y,z,c), I[201] = (T)(img)(_n2##x,_n5##y,z,c), I[202] = (T)(img)(_n3##x,_n5##y,z,c), I[203] = (T)(img)(_n4##x,_n5##y,z,c), I[204] = (T)(img)(_n5##x,_n5##y,z,c), I[205] = (T)(img)(_n6##x,_n5##y,z,c), I[206] = (T)(img)(_n7##x,_n5##y,z,c), I[207] = (T)(img)(_n8##x,_n5##y,z,c), \ - I[208] = (T)(img)(_p7##x,_n6##y,z,c), I[209] = (T)(img)(_p6##x,_n6##y,z,c), I[210] = (T)(img)(_p5##x,_n6##y,z,c), I[211] = (T)(img)(_p4##x,_n6##y,z,c), I[212] = (T)(img)(_p3##x,_n6##y,z,c), I[213] = (T)(img)(_p2##x,_n6##y,z,c), I[214] = (T)(img)(_p1##x,_n6##y,z,c), I[215] = (T)(img)(x,_n6##y,z,c), I[216] = (T)(img)(_n1##x,_n6##y,z,c), I[217] = (T)(img)(_n2##x,_n6##y,z,c), I[218] = (T)(img)(_n3##x,_n6##y,z,c), I[219] = (T)(img)(_n4##x,_n6##y,z,c), I[220] = (T)(img)(_n5##x,_n6##y,z,c), I[221] = (T)(img)(_n6##x,_n6##y,z,c), I[222] = (T)(img)(_n7##x,_n6##y,z,c), I[223] = (T)(img)(_n8##x,_n6##y,z,c), \ - I[224] = (T)(img)(_p7##x,_n7##y,z,c), I[225] = (T)(img)(_p6##x,_n7##y,z,c), I[226] = (T)(img)(_p5##x,_n7##y,z,c), I[227] = (T)(img)(_p4##x,_n7##y,z,c), I[228] = (T)(img)(_p3##x,_n7##y,z,c), I[229] = (T)(img)(_p2##x,_n7##y,z,c), I[230] = (T)(img)(_p1##x,_n7##y,z,c), I[231] = (T)(img)(x,_n7##y,z,c), I[232] = (T)(img)(_n1##x,_n7##y,z,c), I[233] = (T)(img)(_n2##x,_n7##y,z,c), I[234] = (T)(img)(_n3##x,_n7##y,z,c), I[235] = (T)(img)(_n4##x,_n7##y,z,c), I[236] = (T)(img)(_n5##x,_n7##y,z,c), I[237] = (T)(img)(_n6##x,_n7##y,z,c), I[238] = (T)(img)(_n7##x,_n7##y,z,c), I[239] = (T)(img)(_n8##x,_n7##y,z,c), \ - I[240] = (T)(img)(_p7##x,_n8##y,z,c), I[241] = (T)(img)(_p6##x,_n8##y,z,c), I[242] = (T)(img)(_p5##x,_n8##y,z,c), I[243] = (T)(img)(_p4##x,_n8##y,z,c), I[244] = (T)(img)(_p3##x,_n8##y,z,c), I[245] = (T)(img)(_p2##x,_n8##y,z,c), I[246] = (T)(img)(_p1##x,_n8##y,z,c), I[247] = (T)(img)(x,_n8##y,z,c), I[248] = (T)(img)(_n1##x,_n8##y,z,c), I[249] = (T)(img)(_n2##x,_n8##y,z,c), I[250] = (T)(img)(_n3##x,_n8##y,z,c), I[251] = (T)(img)(_n4##x,_n8##y,z,c), I[252] = (T)(img)(_n5##x,_n8##y,z,c), I[253] = (T)(img)(_n6##x,_n8##y,z,c), I[254] = (T)(img)(_n7##x,_n8##y,z,c), I[255] = (T)(img)(_n8##x,_n8##y,z,c); - -// Define 17x17 loop macros -//------------------------- -#define cimg_for17(bound,i) for (int i = 0, \ - _p8##i = 0, _p7##i = 0, _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6, \ - _n7##i = 7>=(int)(bound)?(int)(bound) - 1:7, \ - _n8##i = 8>=(int)(bound)?(int)(bound) - 1:8; \ - _n8##i<(int)(bound) || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i) - -#define cimg_for17X(img,x) cimg_for17((img)._width,x) -#define cimg_for17Y(img,y) cimg_for17((img)._height,y) -#define cimg_for17Z(img,z) cimg_for17((img)._depth,z) -#define cimg_for17C(img,c) cimg_for17((img)._spectrum,c) -#define cimg_for17XY(img,x,y) cimg_for17Y(img,y) cimg_for17X(img,x) -#define cimg_for17XZ(img,x,z) cimg_for17Z(img,z) cimg_for17X(img,x) -#define cimg_for17XC(img,x,c) cimg_for17C(img,c) cimg_for17X(img,x) -#define cimg_for17YZ(img,y,z) cimg_for17Z(img,z) cimg_for17Y(img,y) -#define cimg_for17YC(img,y,c) cimg_for17C(img,c) cimg_for17Y(img,y) -#define cimg_for17ZC(img,z,c) cimg_for17C(img,c) cimg_for17Z(img,z) -#define cimg_for17XYZ(img,x,y,z) cimg_for17Z(img,z) cimg_for17XY(img,x,y) -#define cimg_for17XZC(img,x,z,c) cimg_for17C(img,c) cimg_for17XZ(img,x,z) -#define cimg_for17YZC(img,y,z,c) cimg_for17C(img,c) cimg_for17YZ(img,y,z) -#define cimg_for17XYZC(img,x,y,z,c) cimg_for17C(img,c) cimg_for17XYZ(img,x,y,z) - -#define cimg_for_in17(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p8##i = i - 8<0?0:i - 8, \ - _p7##i = i - 7<0?0:i - 7, \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6, \ - _n7##i = i + 7>=(int)(bound)?(int)(bound) - 1:i + 7, \ - _n8##i = i + 8>=(int)(bound)?(int)(bound) - 1:i + 8; \ - i<=(int)(i1) && (_n8##i<(int)(bound) || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i) - -#define cimg_for_in17X(img,x0,x1,x) cimg_for_in17((img)._width,x0,x1,x) -#define cimg_for_in17Y(img,y0,y1,y) cimg_for_in17((img)._height,y0,y1,y) -#define cimg_for_in17Z(img,z0,z1,z) cimg_for_in17((img)._depth,z0,z1,z) -#define cimg_for_in17C(img,c0,c1,c) cimg_for_in17((img)._spectrum,c0,c1,c) -#define cimg_for_in17XY(img,x0,y0,x1,y1,x,y) cimg_for_in17Y(img,y0,y1,y) cimg_for_in17X(img,x0,x1,x) -#define cimg_for_in17XZ(img,x0,z0,x1,z1,x,z) cimg_for_in17Z(img,z0,z1,z) cimg_for_in17X(img,x0,x1,x) -#define cimg_for_in17XC(img,x0,c0,x1,c1,x,c) cimg_for_in17C(img,c0,c1,c) cimg_for_in17X(img,x0,x1,x) -#define cimg_for_in17YZ(img,y0,z0,y1,z1,y,z) cimg_for_in17Z(img,z0,z1,z) cimg_for_in17Y(img,y0,y1,y) -#define cimg_for_in17YC(img,y0,c0,y1,c1,y,c) cimg_for_in17C(img,c0,c1,c) cimg_for_in17Y(img,y0,y1,y) -#define cimg_for_in17ZC(img,z0,c0,z1,c1,z,c) cimg_for_in17C(img,c0,c1,c) cimg_for_in17Z(img,z0,z1,z) -#define cimg_for_in17XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in17Z(img,z0,z1,z) cimg_for_in17XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in17XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in17C(img,c0,c1,c) cimg_for_in17XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in17YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in17C(img,c0,c1,c) cimg_for_in17YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in17XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in17C(img,c0,c1,c) cimg_for_in17XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for17x17(img,x,y,z,c,I,T) \ - cimg_for17((img)._height,y) for (int x = 0, \ - _p8##x = 0, _p7##x = 0, _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = 6>=((img)._width)?(img).width() - 1:6, \ - _n7##x = 7>=((img)._width)?(img).width() - 1:7, \ - _n8##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = I[7] = I[8] = (T)(img)(0,_p8##y,z,c)), \ - (I[17] = I[18] = I[19] = I[20] = I[21] = I[22] = I[23] = I[24] = I[25] = (T)(img)(0,_p7##y,z,c)), \ - (I[34] = I[35] = I[36] = I[37] = I[38] = I[39] = I[40] = I[41] = I[42] = (T)(img)(0,_p6##y,z,c)), \ - (I[51] = I[52] = I[53] = I[54] = I[55] = I[56] = I[57] = I[58] = I[59] = (T)(img)(0,_p5##y,z,c)), \ - (I[68] = I[69] = I[70] = I[71] = I[72] = I[73] = I[74] = I[75] = I[76] = (T)(img)(0,_p4##y,z,c)), \ - (I[85] = I[86] = I[87] = I[88] = I[89] = I[90] = I[91] = I[92] = I[93] = (T)(img)(0,_p3##y,z,c)), \ - (I[102] = I[103] = I[104] = I[105] = I[106] = I[107] = I[108] = I[109] = I[110] = (T)(img)(0,_p2##y,z,c)), \ - (I[119] = I[120] = I[121] = I[122] = I[123] = I[124] = I[125] = I[126] = I[127] = (T)(img)(0,_p1##y,z,c)), \ - (I[136] = I[137] = I[138] = I[139] = I[140] = I[141] = I[142] = I[143] = I[144] = (T)(img)(0,y,z,c)), \ - (I[153] = I[154] = I[155] = I[156] = I[157] = I[158] = I[159] = I[160] = I[161] = (T)(img)(0,_n1##y,z,c)), \ - (I[170] = I[171] = I[172] = I[173] = I[174] = I[175] = I[176] = I[177] = I[178] = (T)(img)(0,_n2##y,z,c)), \ - (I[187] = I[188] = I[189] = I[190] = I[191] = I[192] = I[193] = I[194] = I[195] = (T)(img)(0,_n3##y,z,c)), \ - (I[204] = I[205] = I[206] = I[207] = I[208] = I[209] = I[210] = I[211] = I[212] = (T)(img)(0,_n4##y,z,c)), \ - (I[221] = I[222] = I[223] = I[224] = I[225] = I[226] = I[227] = I[228] = I[229] = (T)(img)(0,_n5##y,z,c)), \ - (I[238] = I[239] = I[240] = I[241] = I[242] = I[243] = I[244] = I[245] = I[246] = (T)(img)(0,_n6##y,z,c)), \ - (I[255] = I[256] = I[257] = I[258] = I[259] = I[260] = I[261] = I[262] = I[263] = (T)(img)(0,_n7##y,z,c)), \ - (I[272] = I[273] = I[274] = I[275] = I[276] = I[277] = I[278] = I[279] = I[280] = (T)(img)(0,_n8##y,z,c)), \ - (I[9] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[26] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[43] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[60] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[77] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[94] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[111] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[128] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[145] = (T)(img)(_n1##x,y,z,c)), \ - (I[162] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[179] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[196] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[213] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[230] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[247] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[264] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[281] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[10] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[27] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[44] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[61] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[78] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[95] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[112] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[129] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[146] = (T)(img)(_n2##x,y,z,c)), \ - (I[163] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[180] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[197] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[214] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[231] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[248] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[265] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[282] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[11] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[28] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[45] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[62] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[79] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[96] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[113] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[130] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[147] = (T)(img)(_n3##x,y,z,c)), \ - (I[164] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[181] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[198] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[215] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[232] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[249] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[266] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[283] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[12] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[29] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[46] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[63] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[80] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[97] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[114] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[131] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[148] = (T)(img)(_n4##x,y,z,c)), \ - (I[165] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[182] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[199] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[216] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[233] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[250] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[267] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[284] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[13] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[30] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[47] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[64] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[81] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[98] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[115] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[132] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[149] = (T)(img)(_n5##x,y,z,c)), \ - (I[166] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[183] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[200] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[217] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[234] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[251] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[268] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[285] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[14] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[31] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[48] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[65] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[82] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[99] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[116] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[133] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[150] = (T)(img)(_n6##x,y,z,c)), \ - (I[167] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[184] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[201] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[218] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[235] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[252] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[269] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[286] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[15] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[32] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[49] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[66] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[83] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[100] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[117] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[134] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[151] = (T)(img)(_n7##x,y,z,c)), \ - (I[168] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[185] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[202] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[219] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[236] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[253] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[270] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[287] = (T)(img)(_n7##x,_n8##y,z,c)), \ - 8>=((img)._width)?(img).width() - 1:8); \ - (_n8##x<(img).width() && ( \ - (I[16] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[33] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[50] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[67] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[84] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[101] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[118] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[135] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[152] = (T)(img)(_n8##x,y,z,c)), \ - (I[169] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[186] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[203] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[220] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[237] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[254] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[271] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[288] = (T)(img)(_n8##x,_n8##y,z,c)),1)) || \ - _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], \ - I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], \ - I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], \ - I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], \ - I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], \ - I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], \ - I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], \ - I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], \ - I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], \ - I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], \ - I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], \ - I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], \ - I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], \ - I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], \ - I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], \ - I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], \ - I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], \ - _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x) - -#define cimg_for_in17x17(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in17((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p8##x = x - 8<0?0:x - 8, \ - _p7##x = x - 7<0?0:x - 7, \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = x + 6>=(img).width()?(img).width() - 1:x + 6, \ - _n7##x = x + 7>=(img).width()?(img).width() - 1:x + 7, \ - _n8##x = (int)( \ - (I[0] = (T)(img)(_p8##x,_p8##y,z,c)), \ - (I[17] = (T)(img)(_p8##x,_p7##y,z,c)), \ - (I[34] = (T)(img)(_p8##x,_p6##y,z,c)), \ - (I[51] = (T)(img)(_p8##x,_p5##y,z,c)), \ - (I[68] = (T)(img)(_p8##x,_p4##y,z,c)), \ - (I[85] = (T)(img)(_p8##x,_p3##y,z,c)), \ - (I[102] = (T)(img)(_p8##x,_p2##y,z,c)), \ - (I[119] = (T)(img)(_p8##x,_p1##y,z,c)), \ - (I[136] = (T)(img)(_p8##x,y,z,c)), \ - (I[153] = (T)(img)(_p8##x,_n1##y,z,c)), \ - (I[170] = (T)(img)(_p8##x,_n2##y,z,c)), \ - (I[187] = (T)(img)(_p8##x,_n3##y,z,c)), \ - (I[204] = (T)(img)(_p8##x,_n4##y,z,c)), \ - (I[221] = (T)(img)(_p8##x,_n5##y,z,c)), \ - (I[238] = (T)(img)(_p8##x,_n6##y,z,c)), \ - (I[255] = (T)(img)(_p8##x,_n7##y,z,c)), \ - (I[272] = (T)(img)(_p8##x,_n8##y,z,c)), \ - (I[1] = (T)(img)(_p7##x,_p8##y,z,c)), \ - (I[18] = (T)(img)(_p7##x,_p7##y,z,c)), \ - (I[35] = (T)(img)(_p7##x,_p6##y,z,c)), \ - (I[52] = (T)(img)(_p7##x,_p5##y,z,c)), \ - (I[69] = (T)(img)(_p7##x,_p4##y,z,c)), \ - (I[86] = (T)(img)(_p7##x,_p3##y,z,c)), \ - (I[103] = (T)(img)(_p7##x,_p2##y,z,c)), \ - (I[120] = (T)(img)(_p7##x,_p1##y,z,c)), \ - (I[137] = (T)(img)(_p7##x,y,z,c)), \ - (I[154] = (T)(img)(_p7##x,_n1##y,z,c)), \ - (I[171] = (T)(img)(_p7##x,_n2##y,z,c)), \ - (I[188] = (T)(img)(_p7##x,_n3##y,z,c)), \ - (I[205] = (T)(img)(_p7##x,_n4##y,z,c)), \ - (I[222] = (T)(img)(_p7##x,_n5##y,z,c)), \ - (I[239] = (T)(img)(_p7##x,_n6##y,z,c)), \ - (I[256] = (T)(img)(_p7##x,_n7##y,z,c)), \ - (I[273] = (T)(img)(_p7##x,_n8##y,z,c)), \ - (I[2] = (T)(img)(_p6##x,_p8##y,z,c)), \ - (I[19] = (T)(img)(_p6##x,_p7##y,z,c)), \ - (I[36] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[53] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[70] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[87] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[104] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[121] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[138] = (T)(img)(_p6##x,y,z,c)), \ - (I[155] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[172] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[189] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[206] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[223] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[240] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[257] = (T)(img)(_p6##x,_n7##y,z,c)), \ - (I[274] = (T)(img)(_p6##x,_n8##y,z,c)), \ - (I[3] = (T)(img)(_p5##x,_p8##y,z,c)), \ - (I[20] = (T)(img)(_p5##x,_p7##y,z,c)), \ - (I[37] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[54] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[71] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[88] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[105] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[122] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[139] = (T)(img)(_p5##x,y,z,c)), \ - (I[156] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[173] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[190] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[207] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[224] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[241] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[258] = (T)(img)(_p5##x,_n7##y,z,c)), \ - (I[275] = (T)(img)(_p5##x,_n8##y,z,c)), \ - (I[4] = (T)(img)(_p4##x,_p8##y,z,c)), \ - (I[21] = (T)(img)(_p4##x,_p7##y,z,c)), \ - (I[38] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[55] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[72] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[89] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[106] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[123] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[140] = (T)(img)(_p4##x,y,z,c)), \ - (I[157] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[174] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[191] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[208] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[225] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[242] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[259] = (T)(img)(_p4##x,_n7##y,z,c)), \ - (I[276] = (T)(img)(_p4##x,_n8##y,z,c)), \ - (I[5] = (T)(img)(_p3##x,_p8##y,z,c)), \ - (I[22] = (T)(img)(_p3##x,_p7##y,z,c)), \ - (I[39] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[56] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[73] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[90] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[107] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[124] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[141] = (T)(img)(_p3##x,y,z,c)), \ - (I[158] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[175] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[192] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[209] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[226] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[243] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[260] = (T)(img)(_p3##x,_n7##y,z,c)), \ - (I[277] = (T)(img)(_p3##x,_n8##y,z,c)), \ - (I[6] = (T)(img)(_p2##x,_p8##y,z,c)), \ - (I[23] = (T)(img)(_p2##x,_p7##y,z,c)), \ - (I[40] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[57] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[74] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[91] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[108] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[125] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[142] = (T)(img)(_p2##x,y,z,c)), \ - (I[159] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[176] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[193] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[210] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[227] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[244] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[261] = (T)(img)(_p2##x,_n7##y,z,c)), \ - (I[278] = (T)(img)(_p2##x,_n8##y,z,c)), \ - (I[7] = (T)(img)(_p1##x,_p8##y,z,c)), \ - (I[24] = (T)(img)(_p1##x,_p7##y,z,c)), \ - (I[41] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[58] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[75] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[92] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[109] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[126] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[143] = (T)(img)(_p1##x,y,z,c)), \ - (I[160] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[177] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[194] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[211] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[228] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[245] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[262] = (T)(img)(_p1##x,_n7##y,z,c)), \ - (I[279] = (T)(img)(_p1##x,_n8##y,z,c)), \ - (I[8] = (T)(img)(x,_p8##y,z,c)), \ - (I[25] = (T)(img)(x,_p7##y,z,c)), \ - (I[42] = (T)(img)(x,_p6##y,z,c)), \ - (I[59] = (T)(img)(x,_p5##y,z,c)), \ - (I[76] = (T)(img)(x,_p4##y,z,c)), \ - (I[93] = (T)(img)(x,_p3##y,z,c)), \ - (I[110] = (T)(img)(x,_p2##y,z,c)), \ - (I[127] = (T)(img)(x,_p1##y,z,c)), \ - (I[144] = (T)(img)(x,y,z,c)), \ - (I[161] = (T)(img)(x,_n1##y,z,c)), \ - (I[178] = (T)(img)(x,_n2##y,z,c)), \ - (I[195] = (T)(img)(x,_n3##y,z,c)), \ - (I[212] = (T)(img)(x,_n4##y,z,c)), \ - (I[229] = (T)(img)(x,_n5##y,z,c)), \ - (I[246] = (T)(img)(x,_n6##y,z,c)), \ - (I[263] = (T)(img)(x,_n7##y,z,c)), \ - (I[280] = (T)(img)(x,_n8##y,z,c)), \ - (I[9] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[26] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[43] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[60] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[77] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[94] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[111] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[128] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[145] = (T)(img)(_n1##x,y,z,c)), \ - (I[162] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[179] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[196] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[213] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[230] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[247] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[264] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[281] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[10] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[27] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[44] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[61] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[78] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[95] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[112] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[129] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[146] = (T)(img)(_n2##x,y,z,c)), \ - (I[163] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[180] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[197] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[214] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[231] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[248] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[265] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[282] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[11] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[28] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[45] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[62] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[79] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[96] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[113] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[130] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[147] = (T)(img)(_n3##x,y,z,c)), \ - (I[164] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[181] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[198] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[215] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[232] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[249] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[266] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[283] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[12] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[29] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[46] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[63] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[80] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[97] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[114] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[131] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[148] = (T)(img)(_n4##x,y,z,c)), \ - (I[165] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[182] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[199] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[216] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[233] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[250] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[267] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[284] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[13] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[30] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[47] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[64] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[81] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[98] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[115] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[132] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[149] = (T)(img)(_n5##x,y,z,c)), \ - (I[166] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[183] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[200] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[217] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[234] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[251] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[268] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[285] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[14] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[31] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[48] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[65] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[82] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[99] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[116] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[133] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[150] = (T)(img)(_n6##x,y,z,c)), \ - (I[167] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[184] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[201] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[218] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[235] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[252] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[269] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[286] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[15] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[32] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[49] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[66] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[83] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[100] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[117] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[134] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[151] = (T)(img)(_n7##x,y,z,c)), \ - (I[168] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[185] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[202] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[219] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[236] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[253] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[270] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[287] = (T)(img)(_n7##x,_n8##y,z,c)), \ - x + 8>=(img).width()?(img).width() - 1:x + 8); \ - x<=(int)(x1) && ((_n8##x<(img).width() && ( \ - (I[16] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[33] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[50] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[67] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[84] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[101] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[118] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[135] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[152] = (T)(img)(_n8##x,y,z,c)), \ - (I[169] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[186] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[203] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[220] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[237] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[254] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[271] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[288] = (T)(img)(_n8##x,_n8##y,z,c)),1)) || \ - _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], \ - I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], \ - I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], \ - I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], \ - I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], \ - I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], \ - I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], \ - I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], \ - I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], \ - I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], \ - I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], \ - I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], \ - I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], \ - I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], \ - I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], \ - I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], \ - I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], \ - _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x) - -#define cimg_get17x17(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p8##x,_p8##y,z,c), I[1] = (T)(img)(_p7##x,_p8##y,z,c), I[2] = (T)(img)(_p6##x,_p8##y,z,c), I[3] = (T)(img)(_p5##x,_p8##y,z,c), I[4] = (T)(img)(_p4##x,_p8##y,z,c), I[5] = (T)(img)(_p3##x,_p8##y,z,c), I[6] = (T)(img)(_p2##x,_p8##y,z,c), I[7] = (T)(img)(_p1##x,_p8##y,z,c), I[8] = (T)(img)(x,_p8##y,z,c), I[9] = (T)(img)(_n1##x,_p8##y,z,c), I[10] = (T)(img)(_n2##x,_p8##y,z,c), I[11] = (T)(img)(_n3##x,_p8##y,z,c), I[12] = (T)(img)(_n4##x,_p8##y,z,c), I[13] = (T)(img)(_n5##x,_p8##y,z,c), I[14] = (T)(img)(_n6##x,_p8##y,z,c), I[15] = (T)(img)(_n7##x,_p8##y,z,c), I[16] = (T)(img)(_n8##x,_p8##y,z,c), \ - I[17] = (T)(img)(_p8##x,_p7##y,z,c), I[18] = (T)(img)(_p7##x,_p7##y,z,c), I[19] = (T)(img)(_p6##x,_p7##y,z,c), I[20] = (T)(img)(_p5##x,_p7##y,z,c), I[21] = (T)(img)(_p4##x,_p7##y,z,c), I[22] = (T)(img)(_p3##x,_p7##y,z,c), I[23] = (T)(img)(_p2##x,_p7##y,z,c), I[24] = (T)(img)(_p1##x,_p7##y,z,c), I[25] = (T)(img)(x,_p7##y,z,c), I[26] = (T)(img)(_n1##x,_p7##y,z,c), I[27] = (T)(img)(_n2##x,_p7##y,z,c), I[28] = (T)(img)(_n3##x,_p7##y,z,c), I[29] = (T)(img)(_n4##x,_p7##y,z,c), I[30] = (T)(img)(_n5##x,_p7##y,z,c), I[31] = (T)(img)(_n6##x,_p7##y,z,c), I[32] = (T)(img)(_n7##x,_p7##y,z,c), I[33] = (T)(img)(_n8##x,_p7##y,z,c), \ - I[34] = (T)(img)(_p8##x,_p6##y,z,c), I[35] = (T)(img)(_p7##x,_p6##y,z,c), I[36] = (T)(img)(_p6##x,_p6##y,z,c), I[37] = (T)(img)(_p5##x,_p6##y,z,c), I[38] = (T)(img)(_p4##x,_p6##y,z,c), I[39] = (T)(img)(_p3##x,_p6##y,z,c), I[40] = (T)(img)(_p2##x,_p6##y,z,c), I[41] = (T)(img)(_p1##x,_p6##y,z,c), I[42] = (T)(img)(x,_p6##y,z,c), I[43] = (T)(img)(_n1##x,_p6##y,z,c), I[44] = (T)(img)(_n2##x,_p6##y,z,c), I[45] = (T)(img)(_n3##x,_p6##y,z,c), I[46] = (T)(img)(_n4##x,_p6##y,z,c), I[47] = (T)(img)(_n5##x,_p6##y,z,c), I[48] = (T)(img)(_n6##x,_p6##y,z,c), I[49] = (T)(img)(_n7##x,_p6##y,z,c), I[50] = (T)(img)(_n8##x,_p6##y,z,c), \ - I[51] = (T)(img)(_p8##x,_p5##y,z,c), I[52] = (T)(img)(_p7##x,_p5##y,z,c), I[53] = (T)(img)(_p6##x,_p5##y,z,c), I[54] = (T)(img)(_p5##x,_p5##y,z,c), I[55] = (T)(img)(_p4##x,_p5##y,z,c), I[56] = (T)(img)(_p3##x,_p5##y,z,c), I[57] = (T)(img)(_p2##x,_p5##y,z,c), I[58] = (T)(img)(_p1##x,_p5##y,z,c), I[59] = (T)(img)(x,_p5##y,z,c), I[60] = (T)(img)(_n1##x,_p5##y,z,c), I[61] = (T)(img)(_n2##x,_p5##y,z,c), I[62] = (T)(img)(_n3##x,_p5##y,z,c), I[63] = (T)(img)(_n4##x,_p5##y,z,c), I[64] = (T)(img)(_n5##x,_p5##y,z,c), I[65] = (T)(img)(_n6##x,_p5##y,z,c), I[66] = (T)(img)(_n7##x,_p5##y,z,c), I[67] = (T)(img)(_n8##x,_p5##y,z,c), \ - I[68] = (T)(img)(_p8##x,_p4##y,z,c), I[69] = (T)(img)(_p7##x,_p4##y,z,c), I[70] = (T)(img)(_p6##x,_p4##y,z,c), I[71] = (T)(img)(_p5##x,_p4##y,z,c), I[72] = (T)(img)(_p4##x,_p4##y,z,c), I[73] = (T)(img)(_p3##x,_p4##y,z,c), I[74] = (T)(img)(_p2##x,_p4##y,z,c), I[75] = (T)(img)(_p1##x,_p4##y,z,c), I[76] = (T)(img)(x,_p4##y,z,c), I[77] = (T)(img)(_n1##x,_p4##y,z,c), I[78] = (T)(img)(_n2##x,_p4##y,z,c), I[79] = (T)(img)(_n3##x,_p4##y,z,c), I[80] = (T)(img)(_n4##x,_p4##y,z,c), I[81] = (T)(img)(_n5##x,_p4##y,z,c), I[82] = (T)(img)(_n6##x,_p4##y,z,c), I[83] = (T)(img)(_n7##x,_p4##y,z,c), I[84] = (T)(img)(_n8##x,_p4##y,z,c), \ - I[85] = (T)(img)(_p8##x,_p3##y,z,c), I[86] = (T)(img)(_p7##x,_p3##y,z,c), I[87] = (T)(img)(_p6##x,_p3##y,z,c), I[88] = (T)(img)(_p5##x,_p3##y,z,c), I[89] = (T)(img)(_p4##x,_p3##y,z,c), I[90] = (T)(img)(_p3##x,_p3##y,z,c), I[91] = (T)(img)(_p2##x,_p3##y,z,c), I[92] = (T)(img)(_p1##x,_p3##y,z,c), I[93] = (T)(img)(x,_p3##y,z,c), I[94] = (T)(img)(_n1##x,_p3##y,z,c), I[95] = (T)(img)(_n2##x,_p3##y,z,c), I[96] = (T)(img)(_n3##x,_p3##y,z,c), I[97] = (T)(img)(_n4##x,_p3##y,z,c), I[98] = (T)(img)(_n5##x,_p3##y,z,c), I[99] = (T)(img)(_n6##x,_p3##y,z,c), I[100] = (T)(img)(_n7##x,_p3##y,z,c), I[101] = (T)(img)(_n8##x,_p3##y,z,c), \ - I[102] = (T)(img)(_p8##x,_p2##y,z,c), I[103] = (T)(img)(_p7##x,_p2##y,z,c), I[104] = (T)(img)(_p6##x,_p2##y,z,c), I[105] = (T)(img)(_p5##x,_p2##y,z,c), I[106] = (T)(img)(_p4##x,_p2##y,z,c), I[107] = (T)(img)(_p3##x,_p2##y,z,c), I[108] = (T)(img)(_p2##x,_p2##y,z,c), I[109] = (T)(img)(_p1##x,_p2##y,z,c), I[110] = (T)(img)(x,_p2##y,z,c), I[111] = (T)(img)(_n1##x,_p2##y,z,c), I[112] = (T)(img)(_n2##x,_p2##y,z,c), I[113] = (T)(img)(_n3##x,_p2##y,z,c), I[114] = (T)(img)(_n4##x,_p2##y,z,c), I[115] = (T)(img)(_n5##x,_p2##y,z,c), I[116] = (T)(img)(_n6##x,_p2##y,z,c), I[117] = (T)(img)(_n7##x,_p2##y,z,c), I[118] = (T)(img)(_n8##x,_p2##y,z,c), \ - I[119] = (T)(img)(_p8##x,_p1##y,z,c), I[120] = (T)(img)(_p7##x,_p1##y,z,c), I[121] = (T)(img)(_p6##x,_p1##y,z,c), I[122] = (T)(img)(_p5##x,_p1##y,z,c), I[123] = (T)(img)(_p4##x,_p1##y,z,c), I[124] = (T)(img)(_p3##x,_p1##y,z,c), I[125] = (T)(img)(_p2##x,_p1##y,z,c), I[126] = (T)(img)(_p1##x,_p1##y,z,c), I[127] = (T)(img)(x,_p1##y,z,c), I[128] = (T)(img)(_n1##x,_p1##y,z,c), I[129] = (T)(img)(_n2##x,_p1##y,z,c), I[130] = (T)(img)(_n3##x,_p1##y,z,c), I[131] = (T)(img)(_n4##x,_p1##y,z,c), I[132] = (T)(img)(_n5##x,_p1##y,z,c), I[133] = (T)(img)(_n6##x,_p1##y,z,c), I[134] = (T)(img)(_n7##x,_p1##y,z,c), I[135] = (T)(img)(_n8##x,_p1##y,z,c), \ - I[136] = (T)(img)(_p8##x,y,z,c), I[137] = (T)(img)(_p7##x,y,z,c), I[138] = (T)(img)(_p6##x,y,z,c), I[139] = (T)(img)(_p5##x,y,z,c), I[140] = (T)(img)(_p4##x,y,z,c), I[141] = (T)(img)(_p3##x,y,z,c), I[142] = (T)(img)(_p2##x,y,z,c), I[143] = (T)(img)(_p1##x,y,z,c), I[144] = (T)(img)(x,y,z,c), I[145] = (T)(img)(_n1##x,y,z,c), I[146] = (T)(img)(_n2##x,y,z,c), I[147] = (T)(img)(_n3##x,y,z,c), I[148] = (T)(img)(_n4##x,y,z,c), I[149] = (T)(img)(_n5##x,y,z,c), I[150] = (T)(img)(_n6##x,y,z,c), I[151] = (T)(img)(_n7##x,y,z,c), I[152] = (T)(img)(_n8##x,y,z,c), \ - I[153] = (T)(img)(_p8##x,_n1##y,z,c), I[154] = (T)(img)(_p7##x,_n1##y,z,c), I[155] = (T)(img)(_p6##x,_n1##y,z,c), I[156] = (T)(img)(_p5##x,_n1##y,z,c), I[157] = (T)(img)(_p4##x,_n1##y,z,c), I[158] = (T)(img)(_p3##x,_n1##y,z,c), I[159] = (T)(img)(_p2##x,_n1##y,z,c), I[160] = (T)(img)(_p1##x,_n1##y,z,c), I[161] = (T)(img)(x,_n1##y,z,c), I[162] = (T)(img)(_n1##x,_n1##y,z,c), I[163] = (T)(img)(_n2##x,_n1##y,z,c), I[164] = (T)(img)(_n3##x,_n1##y,z,c), I[165] = (T)(img)(_n4##x,_n1##y,z,c), I[166] = (T)(img)(_n5##x,_n1##y,z,c), I[167] = (T)(img)(_n6##x,_n1##y,z,c), I[168] = (T)(img)(_n7##x,_n1##y,z,c), I[169] = (T)(img)(_n8##x,_n1##y,z,c), \ - I[170] = (T)(img)(_p8##x,_n2##y,z,c), I[171] = (T)(img)(_p7##x,_n2##y,z,c), I[172] = (T)(img)(_p6##x,_n2##y,z,c), I[173] = (T)(img)(_p5##x,_n2##y,z,c), I[174] = (T)(img)(_p4##x,_n2##y,z,c), I[175] = (T)(img)(_p3##x,_n2##y,z,c), I[176] = (T)(img)(_p2##x,_n2##y,z,c), I[177] = (T)(img)(_p1##x,_n2##y,z,c), I[178] = (T)(img)(x,_n2##y,z,c), I[179] = (T)(img)(_n1##x,_n2##y,z,c), I[180] = (T)(img)(_n2##x,_n2##y,z,c), I[181] = (T)(img)(_n3##x,_n2##y,z,c), I[182] = (T)(img)(_n4##x,_n2##y,z,c), I[183] = (T)(img)(_n5##x,_n2##y,z,c), I[184] = (T)(img)(_n6##x,_n2##y,z,c), I[185] = (T)(img)(_n7##x,_n2##y,z,c), I[186] = (T)(img)(_n8##x,_n2##y,z,c), \ - I[187] = (T)(img)(_p8##x,_n3##y,z,c), I[188] = (T)(img)(_p7##x,_n3##y,z,c), I[189] = (T)(img)(_p6##x,_n3##y,z,c), I[190] = (T)(img)(_p5##x,_n3##y,z,c), I[191] = (T)(img)(_p4##x,_n3##y,z,c), I[192] = (T)(img)(_p3##x,_n3##y,z,c), I[193] = (T)(img)(_p2##x,_n3##y,z,c), I[194] = (T)(img)(_p1##x,_n3##y,z,c), I[195] = (T)(img)(x,_n3##y,z,c), I[196] = (T)(img)(_n1##x,_n3##y,z,c), I[197] = (T)(img)(_n2##x,_n3##y,z,c), I[198] = (T)(img)(_n3##x,_n3##y,z,c), I[199] = (T)(img)(_n4##x,_n3##y,z,c), I[200] = (T)(img)(_n5##x,_n3##y,z,c), I[201] = (T)(img)(_n6##x,_n3##y,z,c), I[202] = (T)(img)(_n7##x,_n3##y,z,c), I[203] = (T)(img)(_n8##x,_n3##y,z,c), \ - I[204] = (T)(img)(_p8##x,_n4##y,z,c), I[205] = (T)(img)(_p7##x,_n4##y,z,c), I[206] = (T)(img)(_p6##x,_n4##y,z,c), I[207] = (T)(img)(_p5##x,_n4##y,z,c), I[208] = (T)(img)(_p4##x,_n4##y,z,c), I[209] = (T)(img)(_p3##x,_n4##y,z,c), I[210] = (T)(img)(_p2##x,_n4##y,z,c), I[211] = (T)(img)(_p1##x,_n4##y,z,c), I[212] = (T)(img)(x,_n4##y,z,c), I[213] = (T)(img)(_n1##x,_n4##y,z,c), I[214] = (T)(img)(_n2##x,_n4##y,z,c), I[215] = (T)(img)(_n3##x,_n4##y,z,c), I[216] = (T)(img)(_n4##x,_n4##y,z,c), I[217] = (T)(img)(_n5##x,_n4##y,z,c), I[218] = (T)(img)(_n6##x,_n4##y,z,c), I[219] = (T)(img)(_n7##x,_n4##y,z,c), I[220] = (T)(img)(_n8##x,_n4##y,z,c), \ - I[221] = (T)(img)(_p8##x,_n5##y,z,c), I[222] = (T)(img)(_p7##x,_n5##y,z,c), I[223] = (T)(img)(_p6##x,_n5##y,z,c), I[224] = (T)(img)(_p5##x,_n5##y,z,c), I[225] = (T)(img)(_p4##x,_n5##y,z,c), I[226] = (T)(img)(_p3##x,_n5##y,z,c), I[227] = (T)(img)(_p2##x,_n5##y,z,c), I[228] = (T)(img)(_p1##x,_n5##y,z,c), I[229] = (T)(img)(x,_n5##y,z,c), I[230] = (T)(img)(_n1##x,_n5##y,z,c), I[231] = (T)(img)(_n2##x,_n5##y,z,c), I[232] = (T)(img)(_n3##x,_n5##y,z,c), I[233] = (T)(img)(_n4##x,_n5##y,z,c), I[234] = (T)(img)(_n5##x,_n5##y,z,c), I[235] = (T)(img)(_n6##x,_n5##y,z,c), I[236] = (T)(img)(_n7##x,_n5##y,z,c), I[237] = (T)(img)(_n8##x,_n5##y,z,c), \ - I[238] = (T)(img)(_p8##x,_n6##y,z,c), I[239] = (T)(img)(_p7##x,_n6##y,z,c), I[240] = (T)(img)(_p6##x,_n6##y,z,c), I[241] = (T)(img)(_p5##x,_n6##y,z,c), I[242] = (T)(img)(_p4##x,_n6##y,z,c), I[243] = (T)(img)(_p3##x,_n6##y,z,c), I[244] = (T)(img)(_p2##x,_n6##y,z,c), I[245] = (T)(img)(_p1##x,_n6##y,z,c), I[246] = (T)(img)(x,_n6##y,z,c), I[247] = (T)(img)(_n1##x,_n6##y,z,c), I[248] = (T)(img)(_n2##x,_n6##y,z,c), I[249] = (T)(img)(_n3##x,_n6##y,z,c), I[250] = (T)(img)(_n4##x,_n6##y,z,c), I[251] = (T)(img)(_n5##x,_n6##y,z,c), I[252] = (T)(img)(_n6##x,_n6##y,z,c), I[253] = (T)(img)(_n7##x,_n6##y,z,c), I[254] = (T)(img)(_n8##x,_n6##y,z,c), \ - I[255] = (T)(img)(_p8##x,_n7##y,z,c), I[256] = (T)(img)(_p7##x,_n7##y,z,c), I[257] = (T)(img)(_p6##x,_n7##y,z,c), I[258] = (T)(img)(_p5##x,_n7##y,z,c), I[259] = (T)(img)(_p4##x,_n7##y,z,c), I[260] = (T)(img)(_p3##x,_n7##y,z,c), I[261] = (T)(img)(_p2##x,_n7##y,z,c), I[262] = (T)(img)(_p1##x,_n7##y,z,c), I[263] = (T)(img)(x,_n7##y,z,c), I[264] = (T)(img)(_n1##x,_n7##y,z,c), I[265] = (T)(img)(_n2##x,_n7##y,z,c), I[266] = (T)(img)(_n3##x,_n7##y,z,c), I[267] = (T)(img)(_n4##x,_n7##y,z,c), I[268] = (T)(img)(_n5##x,_n7##y,z,c), I[269] = (T)(img)(_n6##x,_n7##y,z,c), I[270] = (T)(img)(_n7##x,_n7##y,z,c), I[271] = (T)(img)(_n8##x,_n7##y,z,c), \ - I[272] = (T)(img)(_p8##x,_n8##y,z,c), I[273] = (T)(img)(_p7##x,_n8##y,z,c), I[274] = (T)(img)(_p6##x,_n8##y,z,c), I[275] = (T)(img)(_p5##x,_n8##y,z,c), I[276] = (T)(img)(_p4##x,_n8##y,z,c), I[277] = (T)(img)(_p3##x,_n8##y,z,c), I[278] = (T)(img)(_p2##x,_n8##y,z,c), I[279] = (T)(img)(_p1##x,_n8##y,z,c), I[280] = (T)(img)(x,_n8##y,z,c), I[281] = (T)(img)(_n1##x,_n8##y,z,c), I[282] = (T)(img)(_n2##x,_n8##y,z,c), I[283] = (T)(img)(_n3##x,_n8##y,z,c), I[284] = (T)(img)(_n4##x,_n8##y,z,c), I[285] = (T)(img)(_n5##x,_n8##y,z,c), I[286] = (T)(img)(_n6##x,_n8##y,z,c), I[287] = (T)(img)(_n7##x,_n8##y,z,c), I[288] = (T)(img)(_n8##x,_n8##y,z,c); - -// Define 18x18 loop macros -//------------------------- -#define cimg_for18(bound,i) for (int i = 0, \ - _p8##i = 0, _p7##i = 0, _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6, \ - _n7##i = 7>=(int)(bound)?(int)(bound) - 1:7, \ - _n8##i = 8>=(int)(bound)?(int)(bound) - 1:8, \ - _n9##i = 9>=(int)(bound)?(int)(bound) - 1:9; \ - _n9##i<(int)(bound) || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i) - -#define cimg_for18X(img,x) cimg_for18((img)._width,x) -#define cimg_for18Y(img,y) cimg_for18((img)._height,y) -#define cimg_for18Z(img,z) cimg_for18((img)._depth,z) -#define cimg_for18C(img,c) cimg_for18((img)._spectrum,c) -#define cimg_for18XY(img,x,y) cimg_for18Y(img,y) cimg_for18X(img,x) -#define cimg_for18XZ(img,x,z) cimg_for18Z(img,z) cimg_for18X(img,x) -#define cimg_for18XC(img,x,c) cimg_for18C(img,c) cimg_for18X(img,x) -#define cimg_for18YZ(img,y,z) cimg_for18Z(img,z) cimg_for18Y(img,y) -#define cimg_for18YC(img,y,c) cimg_for18C(img,c) cimg_for18Y(img,y) -#define cimg_for18ZC(img,z,c) cimg_for18C(img,c) cimg_for18Z(img,z) -#define cimg_for18XYZ(img,x,y,z) cimg_for18Z(img,z) cimg_for18XY(img,x,y) -#define cimg_for18XZC(img,x,z,c) cimg_for18C(img,c) cimg_for18XZ(img,x,z) -#define cimg_for18YZC(img,y,z,c) cimg_for18C(img,c) cimg_for18YZ(img,y,z) -#define cimg_for18XYZC(img,x,y,z,c) cimg_for18C(img,c) cimg_for18XYZ(img,x,y,z) - -#define cimg_for_in18(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p8##i = i - 8<0?0:i - 8, \ - _p7##i = i - 7<0?0:i - 7, \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6, \ - _n7##i = i + 7>=(int)(bound)?(int)(bound) - 1:i + 7, \ - _n8##i = i + 8>=(int)(bound)?(int)(bound) - 1:i + 8, \ - _n9##i = i + 9>=(int)(bound)?(int)(bound) - 1:i + 9; \ - i<=(int)(i1) && (_n9##i<(int)(bound) || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i) - -#define cimg_for_in18X(img,x0,x1,x) cimg_for_in18((img)._width,x0,x1,x) -#define cimg_for_in18Y(img,y0,y1,y) cimg_for_in18((img)._height,y0,y1,y) -#define cimg_for_in18Z(img,z0,z1,z) cimg_for_in18((img)._depth,z0,z1,z) -#define cimg_for_in18C(img,c0,c1,c) cimg_for_in18((img)._spectrum,c0,c1,c) -#define cimg_for_in18XY(img,x0,y0,x1,y1,x,y) cimg_for_in18Y(img,y0,y1,y) cimg_for_in18X(img,x0,x1,x) -#define cimg_for_in18XZ(img,x0,z0,x1,z1,x,z) cimg_for_in18Z(img,z0,z1,z) cimg_for_in18X(img,x0,x1,x) -#define cimg_for_in18XC(img,x0,c0,x1,c1,x,c) cimg_for_in18C(img,c0,c1,c) cimg_for_in18X(img,x0,x1,x) -#define cimg_for_in18YZ(img,y0,z0,y1,z1,y,z) cimg_for_in18Z(img,z0,z1,z) cimg_for_in18Y(img,y0,y1,y) -#define cimg_for_in18YC(img,y0,c0,y1,c1,y,c) cimg_for_in18C(img,c0,c1,c) cimg_for_in18Y(img,y0,y1,y) -#define cimg_for_in18ZC(img,z0,c0,z1,c1,z,c) cimg_for_in18C(img,c0,c1,c) cimg_for_in18Z(img,z0,z1,z) -#define cimg_for_in18XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in18Z(img,z0,z1,z) cimg_for_in18XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in18XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in18C(img,c0,c1,c) cimg_for_in18XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in18YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in18C(img,c0,c1,c) cimg_for_in18YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in18XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in18C(img,c0,c1,c) cimg_for_in18XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for18x18(img,x,y,z,c,I,T) \ - cimg_for18((img)._height,y) for (int x = 0, \ - _p8##x = 0, _p7##x = 0, _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = 6>=((img)._width)?(img).width() - 1:6, \ - _n7##x = 7>=((img)._width)?(img).width() - 1:7, \ - _n8##x = 8>=((img)._width)?(img).width() - 1:8, \ - _n9##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = I[7] = I[8] = (T)(img)(0,_p8##y,z,c)), \ - (I[18] = I[19] = I[20] = I[21] = I[22] = I[23] = I[24] = I[25] = I[26] = (T)(img)(0,_p7##y,z,c)), \ - (I[36] = I[37] = I[38] = I[39] = I[40] = I[41] = I[42] = I[43] = I[44] = (T)(img)(0,_p6##y,z,c)), \ - (I[54] = I[55] = I[56] = I[57] = I[58] = I[59] = I[60] = I[61] = I[62] = (T)(img)(0,_p5##y,z,c)), \ - (I[72] = I[73] = I[74] = I[75] = I[76] = I[77] = I[78] = I[79] = I[80] = (T)(img)(0,_p4##y,z,c)), \ - (I[90] = I[91] = I[92] = I[93] = I[94] = I[95] = I[96] = I[97] = I[98] = (T)(img)(0,_p3##y,z,c)), \ - (I[108] = I[109] = I[110] = I[111] = I[112] = I[113] = I[114] = I[115] = I[116] = (T)(img)(0,_p2##y,z,c)), \ - (I[126] = I[127] = I[128] = I[129] = I[130] = I[131] = I[132] = I[133] = I[134] = (T)(img)(0,_p1##y,z,c)), \ - (I[144] = I[145] = I[146] = I[147] = I[148] = I[149] = I[150] = I[151] = I[152] = (T)(img)(0,y,z,c)), \ - (I[162] = I[163] = I[164] = I[165] = I[166] = I[167] = I[168] = I[169] = I[170] = (T)(img)(0,_n1##y,z,c)), \ - (I[180] = I[181] = I[182] = I[183] = I[184] = I[185] = I[186] = I[187] = I[188] = (T)(img)(0,_n2##y,z,c)), \ - (I[198] = I[199] = I[200] = I[201] = I[202] = I[203] = I[204] = I[205] = I[206] = (T)(img)(0,_n3##y,z,c)), \ - (I[216] = I[217] = I[218] = I[219] = I[220] = I[221] = I[222] = I[223] = I[224] = (T)(img)(0,_n4##y,z,c)), \ - (I[234] = I[235] = I[236] = I[237] = I[238] = I[239] = I[240] = I[241] = I[242] = (T)(img)(0,_n5##y,z,c)), \ - (I[252] = I[253] = I[254] = I[255] = I[256] = I[257] = I[258] = I[259] = I[260] = (T)(img)(0,_n6##y,z,c)), \ - (I[270] = I[271] = I[272] = I[273] = I[274] = I[275] = I[276] = I[277] = I[278] = (T)(img)(0,_n7##y,z,c)), \ - (I[288] = I[289] = I[290] = I[291] = I[292] = I[293] = I[294] = I[295] = I[296] = (T)(img)(0,_n8##y,z,c)), \ - (I[306] = I[307] = I[308] = I[309] = I[310] = I[311] = I[312] = I[313] = I[314] = (T)(img)(0,_n9##y,z,c)), \ - (I[9] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[27] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[45] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[63] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[81] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[99] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[117] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[135] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[153] = (T)(img)(_n1##x,y,z,c)), \ - (I[171] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[189] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[207] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[225] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[243] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[261] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[279] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[297] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[315] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[10] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[28] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[46] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[64] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[82] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[100] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[118] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[136] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[154] = (T)(img)(_n2##x,y,z,c)), \ - (I[172] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[190] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[208] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[226] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[244] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[262] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[280] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[298] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[316] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[11] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[29] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[47] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[65] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[83] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[101] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[119] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[137] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[155] = (T)(img)(_n3##x,y,z,c)), \ - (I[173] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[191] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[209] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[227] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[245] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[263] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[281] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[299] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[317] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[12] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[30] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[48] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[66] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[84] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[102] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[120] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[138] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[156] = (T)(img)(_n4##x,y,z,c)), \ - (I[174] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[192] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[210] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[228] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[246] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[264] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[282] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[300] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[318] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[13] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[31] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[49] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[67] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[85] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[103] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[121] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[139] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[157] = (T)(img)(_n5##x,y,z,c)), \ - (I[175] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[193] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[211] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[229] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[247] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[265] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[283] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[301] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[319] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[14] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[32] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[50] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[68] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[86] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[104] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[122] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[140] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[158] = (T)(img)(_n6##x,y,z,c)), \ - (I[176] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[194] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[212] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[230] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[248] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[266] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[284] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[302] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[320] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[15] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[33] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[51] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[69] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[87] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[105] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[123] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[141] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[159] = (T)(img)(_n7##x,y,z,c)), \ - (I[177] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[195] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[213] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[231] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[249] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[267] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[285] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[303] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[321] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[16] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[34] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[52] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[70] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[88] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[106] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[124] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[142] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[160] = (T)(img)(_n8##x,y,z,c)), \ - (I[178] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[196] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[214] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[232] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[250] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[268] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[286] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[304] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[322] = (T)(img)(_n8##x,_n9##y,z,c)), \ - 9>=((img)._width)?(img).width() - 1:9); \ - (_n9##x<(img).width() && ( \ - (I[17] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[35] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[53] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[71] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[89] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[107] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[125] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[143] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[161] = (T)(img)(_n9##x,y,z,c)), \ - (I[179] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[197] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[215] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[233] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[251] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[269] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[287] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[305] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[323] = (T)(img)(_n9##x,_n9##y,z,c)),1)) || \ - _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], \ - I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], \ - I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], \ - I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], \ - I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], \ - I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], \ - I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], \ - I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], \ - I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], \ - I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], \ - I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], \ - I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], \ - I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], \ - I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], \ - I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], \ - I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], \ - I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], \ - I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], \ - _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x) - -#define cimg_for_in18x18(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in18((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p8##x = x - 8<0?0:x - 8, \ - _p7##x = x - 7<0?0:x - 7, \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = x + 6>=(img).width()?(img).width() - 1:x + 6, \ - _n7##x = x + 7>=(img).width()?(img).width() - 1:x + 7, \ - _n8##x = x + 8>=(img).width()?(img).width() - 1:x + 8, \ - _n9##x = (int)( \ - (I[0] = (T)(img)(_p8##x,_p8##y,z,c)), \ - (I[18] = (T)(img)(_p8##x,_p7##y,z,c)), \ - (I[36] = (T)(img)(_p8##x,_p6##y,z,c)), \ - (I[54] = (T)(img)(_p8##x,_p5##y,z,c)), \ - (I[72] = (T)(img)(_p8##x,_p4##y,z,c)), \ - (I[90] = (T)(img)(_p8##x,_p3##y,z,c)), \ - (I[108] = (T)(img)(_p8##x,_p2##y,z,c)), \ - (I[126] = (T)(img)(_p8##x,_p1##y,z,c)), \ - (I[144] = (T)(img)(_p8##x,y,z,c)), \ - (I[162] = (T)(img)(_p8##x,_n1##y,z,c)), \ - (I[180] = (T)(img)(_p8##x,_n2##y,z,c)), \ - (I[198] = (T)(img)(_p8##x,_n3##y,z,c)), \ - (I[216] = (T)(img)(_p8##x,_n4##y,z,c)), \ - (I[234] = (T)(img)(_p8##x,_n5##y,z,c)), \ - (I[252] = (T)(img)(_p8##x,_n6##y,z,c)), \ - (I[270] = (T)(img)(_p8##x,_n7##y,z,c)), \ - (I[288] = (T)(img)(_p8##x,_n8##y,z,c)), \ - (I[306] = (T)(img)(_p8##x,_n9##y,z,c)), \ - (I[1] = (T)(img)(_p7##x,_p8##y,z,c)), \ - (I[19] = (T)(img)(_p7##x,_p7##y,z,c)), \ - (I[37] = (T)(img)(_p7##x,_p6##y,z,c)), \ - (I[55] = (T)(img)(_p7##x,_p5##y,z,c)), \ - (I[73] = (T)(img)(_p7##x,_p4##y,z,c)), \ - (I[91] = (T)(img)(_p7##x,_p3##y,z,c)), \ - (I[109] = (T)(img)(_p7##x,_p2##y,z,c)), \ - (I[127] = (T)(img)(_p7##x,_p1##y,z,c)), \ - (I[145] = (T)(img)(_p7##x,y,z,c)), \ - (I[163] = (T)(img)(_p7##x,_n1##y,z,c)), \ - (I[181] = (T)(img)(_p7##x,_n2##y,z,c)), \ - (I[199] = (T)(img)(_p7##x,_n3##y,z,c)), \ - (I[217] = (T)(img)(_p7##x,_n4##y,z,c)), \ - (I[235] = (T)(img)(_p7##x,_n5##y,z,c)), \ - (I[253] = (T)(img)(_p7##x,_n6##y,z,c)), \ - (I[271] = (T)(img)(_p7##x,_n7##y,z,c)), \ - (I[289] = (T)(img)(_p7##x,_n8##y,z,c)), \ - (I[307] = (T)(img)(_p7##x,_n9##y,z,c)), \ - (I[2] = (T)(img)(_p6##x,_p8##y,z,c)), \ - (I[20] = (T)(img)(_p6##x,_p7##y,z,c)), \ - (I[38] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[56] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[74] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[92] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[110] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[128] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[146] = (T)(img)(_p6##x,y,z,c)), \ - (I[164] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[182] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[200] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[218] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[236] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[254] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[272] = (T)(img)(_p6##x,_n7##y,z,c)), \ - (I[290] = (T)(img)(_p6##x,_n8##y,z,c)), \ - (I[308] = (T)(img)(_p6##x,_n9##y,z,c)), \ - (I[3] = (T)(img)(_p5##x,_p8##y,z,c)), \ - (I[21] = (T)(img)(_p5##x,_p7##y,z,c)), \ - (I[39] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[57] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[75] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[93] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[111] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[129] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[147] = (T)(img)(_p5##x,y,z,c)), \ - (I[165] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[183] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[201] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[219] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[237] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[255] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[273] = (T)(img)(_p5##x,_n7##y,z,c)), \ - (I[291] = (T)(img)(_p5##x,_n8##y,z,c)), \ - (I[309] = (T)(img)(_p5##x,_n9##y,z,c)), \ - (I[4] = (T)(img)(_p4##x,_p8##y,z,c)), \ - (I[22] = (T)(img)(_p4##x,_p7##y,z,c)), \ - (I[40] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[58] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[76] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[94] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[112] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[130] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[148] = (T)(img)(_p4##x,y,z,c)), \ - (I[166] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[184] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[202] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[220] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[238] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[256] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[274] = (T)(img)(_p4##x,_n7##y,z,c)), \ - (I[292] = (T)(img)(_p4##x,_n8##y,z,c)), \ - (I[310] = (T)(img)(_p4##x,_n9##y,z,c)), \ - (I[5] = (T)(img)(_p3##x,_p8##y,z,c)), \ - (I[23] = (T)(img)(_p3##x,_p7##y,z,c)), \ - (I[41] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[59] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[77] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[95] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[113] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[131] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[149] = (T)(img)(_p3##x,y,z,c)), \ - (I[167] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[185] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[203] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[221] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[239] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[257] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[275] = (T)(img)(_p3##x,_n7##y,z,c)), \ - (I[293] = (T)(img)(_p3##x,_n8##y,z,c)), \ - (I[311] = (T)(img)(_p3##x,_n9##y,z,c)), \ - (I[6] = (T)(img)(_p2##x,_p8##y,z,c)), \ - (I[24] = (T)(img)(_p2##x,_p7##y,z,c)), \ - (I[42] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[60] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[78] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[96] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[114] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[132] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[150] = (T)(img)(_p2##x,y,z,c)), \ - (I[168] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[186] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[204] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[222] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[240] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[258] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[276] = (T)(img)(_p2##x,_n7##y,z,c)), \ - (I[294] = (T)(img)(_p2##x,_n8##y,z,c)), \ - (I[312] = (T)(img)(_p2##x,_n9##y,z,c)), \ - (I[7] = (T)(img)(_p1##x,_p8##y,z,c)), \ - (I[25] = (T)(img)(_p1##x,_p7##y,z,c)), \ - (I[43] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[61] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[79] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[97] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[115] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[133] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[151] = (T)(img)(_p1##x,y,z,c)), \ - (I[169] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[187] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[205] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[223] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[241] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[259] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[277] = (T)(img)(_p1##x,_n7##y,z,c)), \ - (I[295] = (T)(img)(_p1##x,_n8##y,z,c)), \ - (I[313] = (T)(img)(_p1##x,_n9##y,z,c)), \ - (I[8] = (T)(img)(x,_p8##y,z,c)), \ - (I[26] = (T)(img)(x,_p7##y,z,c)), \ - (I[44] = (T)(img)(x,_p6##y,z,c)), \ - (I[62] = (T)(img)(x,_p5##y,z,c)), \ - (I[80] = (T)(img)(x,_p4##y,z,c)), \ - (I[98] = (T)(img)(x,_p3##y,z,c)), \ - (I[116] = (T)(img)(x,_p2##y,z,c)), \ - (I[134] = (T)(img)(x,_p1##y,z,c)), \ - (I[152] = (T)(img)(x,y,z,c)), \ - (I[170] = (T)(img)(x,_n1##y,z,c)), \ - (I[188] = (T)(img)(x,_n2##y,z,c)), \ - (I[206] = (T)(img)(x,_n3##y,z,c)), \ - (I[224] = (T)(img)(x,_n4##y,z,c)), \ - (I[242] = (T)(img)(x,_n5##y,z,c)), \ - (I[260] = (T)(img)(x,_n6##y,z,c)), \ - (I[278] = (T)(img)(x,_n7##y,z,c)), \ - (I[296] = (T)(img)(x,_n8##y,z,c)), \ - (I[314] = (T)(img)(x,_n9##y,z,c)), \ - (I[9] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[27] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[45] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[63] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[81] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[99] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[117] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[135] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[153] = (T)(img)(_n1##x,y,z,c)), \ - (I[171] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[189] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[207] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[225] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[243] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[261] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[279] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[297] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[315] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[10] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[28] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[46] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[64] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[82] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[100] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[118] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[136] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[154] = (T)(img)(_n2##x,y,z,c)), \ - (I[172] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[190] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[208] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[226] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[244] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[262] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[280] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[298] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[316] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[11] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[29] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[47] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[65] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[83] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[101] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[119] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[137] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[155] = (T)(img)(_n3##x,y,z,c)), \ - (I[173] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[191] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[209] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[227] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[245] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[263] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[281] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[299] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[317] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[12] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[30] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[48] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[66] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[84] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[102] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[120] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[138] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[156] = (T)(img)(_n4##x,y,z,c)), \ - (I[174] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[192] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[210] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[228] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[246] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[264] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[282] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[300] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[318] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[13] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[31] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[49] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[67] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[85] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[103] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[121] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[139] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[157] = (T)(img)(_n5##x,y,z,c)), \ - (I[175] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[193] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[211] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[229] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[247] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[265] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[283] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[301] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[319] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[14] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[32] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[50] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[68] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[86] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[104] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[122] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[140] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[158] = (T)(img)(_n6##x,y,z,c)), \ - (I[176] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[194] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[212] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[230] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[248] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[266] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[284] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[302] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[320] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[15] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[33] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[51] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[69] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[87] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[105] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[123] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[141] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[159] = (T)(img)(_n7##x,y,z,c)), \ - (I[177] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[195] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[213] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[231] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[249] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[267] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[285] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[303] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[321] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[16] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[34] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[52] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[70] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[88] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[106] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[124] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[142] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[160] = (T)(img)(_n8##x,y,z,c)), \ - (I[178] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[196] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[214] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[232] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[250] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[268] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[286] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[304] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[322] = (T)(img)(_n8##x,_n9##y,z,c)), \ - x + 9>=(img).width()?(img).width() - 1:x + 9); \ - x<=(int)(x1) && ((_n9##x<(img).width() && ( \ - (I[17] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[35] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[53] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[71] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[89] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[107] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[125] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[143] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[161] = (T)(img)(_n9##x,y,z,c)), \ - (I[179] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[197] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[215] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[233] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[251] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[269] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[287] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[305] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[323] = (T)(img)(_n9##x,_n9##y,z,c)),1)) || \ - _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], \ - I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], \ - I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], \ - I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], \ - I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], \ - I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], \ - I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], \ - I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], \ - I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], \ - I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], \ - I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], \ - I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], \ - I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], \ - I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], \ - I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], \ - I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], \ - I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], \ - I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], \ - _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x) - -#define cimg_get18x18(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p8##x,_p8##y,z,c), I[1] = (T)(img)(_p7##x,_p8##y,z,c), I[2] = (T)(img)(_p6##x,_p8##y,z,c), I[3] = (T)(img)(_p5##x,_p8##y,z,c), I[4] = (T)(img)(_p4##x,_p8##y,z,c), I[5] = (T)(img)(_p3##x,_p8##y,z,c), I[6] = (T)(img)(_p2##x,_p8##y,z,c), I[7] = (T)(img)(_p1##x,_p8##y,z,c), I[8] = (T)(img)(x,_p8##y,z,c), I[9] = (T)(img)(_n1##x,_p8##y,z,c), I[10] = (T)(img)(_n2##x,_p8##y,z,c), I[11] = (T)(img)(_n3##x,_p8##y,z,c), I[12] = (T)(img)(_n4##x,_p8##y,z,c), I[13] = (T)(img)(_n5##x,_p8##y,z,c), I[14] = (T)(img)(_n6##x,_p8##y,z,c), I[15] = (T)(img)(_n7##x,_p8##y,z,c), I[16] = (T)(img)(_n8##x,_p8##y,z,c), I[17] = (T)(img)(_n9##x,_p8##y,z,c), \ - I[18] = (T)(img)(_p8##x,_p7##y,z,c), I[19] = (T)(img)(_p7##x,_p7##y,z,c), I[20] = (T)(img)(_p6##x,_p7##y,z,c), I[21] = (T)(img)(_p5##x,_p7##y,z,c), I[22] = (T)(img)(_p4##x,_p7##y,z,c), I[23] = (T)(img)(_p3##x,_p7##y,z,c), I[24] = (T)(img)(_p2##x,_p7##y,z,c), I[25] = (T)(img)(_p1##x,_p7##y,z,c), I[26] = (T)(img)(x,_p7##y,z,c), I[27] = (T)(img)(_n1##x,_p7##y,z,c), I[28] = (T)(img)(_n2##x,_p7##y,z,c), I[29] = (T)(img)(_n3##x,_p7##y,z,c), I[30] = (T)(img)(_n4##x,_p7##y,z,c), I[31] = (T)(img)(_n5##x,_p7##y,z,c), I[32] = (T)(img)(_n6##x,_p7##y,z,c), I[33] = (T)(img)(_n7##x,_p7##y,z,c), I[34] = (T)(img)(_n8##x,_p7##y,z,c), I[35] = (T)(img)(_n9##x,_p7##y,z,c), \ - I[36] = (T)(img)(_p8##x,_p6##y,z,c), I[37] = (T)(img)(_p7##x,_p6##y,z,c), I[38] = (T)(img)(_p6##x,_p6##y,z,c), I[39] = (T)(img)(_p5##x,_p6##y,z,c), I[40] = (T)(img)(_p4##x,_p6##y,z,c), I[41] = (T)(img)(_p3##x,_p6##y,z,c), I[42] = (T)(img)(_p2##x,_p6##y,z,c), I[43] = (T)(img)(_p1##x,_p6##y,z,c), I[44] = (T)(img)(x,_p6##y,z,c), I[45] = (T)(img)(_n1##x,_p6##y,z,c), I[46] = (T)(img)(_n2##x,_p6##y,z,c), I[47] = (T)(img)(_n3##x,_p6##y,z,c), I[48] = (T)(img)(_n4##x,_p6##y,z,c), I[49] = (T)(img)(_n5##x,_p6##y,z,c), I[50] = (T)(img)(_n6##x,_p6##y,z,c), I[51] = (T)(img)(_n7##x,_p6##y,z,c), I[52] = (T)(img)(_n8##x,_p6##y,z,c), I[53] = (T)(img)(_n9##x,_p6##y,z,c), \ - I[54] = (T)(img)(_p8##x,_p5##y,z,c), I[55] = (T)(img)(_p7##x,_p5##y,z,c), I[56] = (T)(img)(_p6##x,_p5##y,z,c), I[57] = (T)(img)(_p5##x,_p5##y,z,c), I[58] = (T)(img)(_p4##x,_p5##y,z,c), I[59] = (T)(img)(_p3##x,_p5##y,z,c), I[60] = (T)(img)(_p2##x,_p5##y,z,c), I[61] = (T)(img)(_p1##x,_p5##y,z,c), I[62] = (T)(img)(x,_p5##y,z,c), I[63] = (T)(img)(_n1##x,_p5##y,z,c), I[64] = (T)(img)(_n2##x,_p5##y,z,c), I[65] = (T)(img)(_n3##x,_p5##y,z,c), I[66] = (T)(img)(_n4##x,_p5##y,z,c), I[67] = (T)(img)(_n5##x,_p5##y,z,c), I[68] = (T)(img)(_n6##x,_p5##y,z,c), I[69] = (T)(img)(_n7##x,_p5##y,z,c), I[70] = (T)(img)(_n8##x,_p5##y,z,c), I[71] = (T)(img)(_n9##x,_p5##y,z,c), \ - I[72] = (T)(img)(_p8##x,_p4##y,z,c), I[73] = (T)(img)(_p7##x,_p4##y,z,c), I[74] = (T)(img)(_p6##x,_p4##y,z,c), I[75] = (T)(img)(_p5##x,_p4##y,z,c), I[76] = (T)(img)(_p4##x,_p4##y,z,c), I[77] = (T)(img)(_p3##x,_p4##y,z,c), I[78] = (T)(img)(_p2##x,_p4##y,z,c), I[79] = (T)(img)(_p1##x,_p4##y,z,c), I[80] = (T)(img)(x,_p4##y,z,c), I[81] = (T)(img)(_n1##x,_p4##y,z,c), I[82] = (T)(img)(_n2##x,_p4##y,z,c), I[83] = (T)(img)(_n3##x,_p4##y,z,c), I[84] = (T)(img)(_n4##x,_p4##y,z,c), I[85] = (T)(img)(_n5##x,_p4##y,z,c), I[86] = (T)(img)(_n6##x,_p4##y,z,c), I[87] = (T)(img)(_n7##x,_p4##y,z,c), I[88] = (T)(img)(_n8##x,_p4##y,z,c), I[89] = (T)(img)(_n9##x,_p4##y,z,c), \ - I[90] = (T)(img)(_p8##x,_p3##y,z,c), I[91] = (T)(img)(_p7##x,_p3##y,z,c), I[92] = (T)(img)(_p6##x,_p3##y,z,c), I[93] = (T)(img)(_p5##x,_p3##y,z,c), I[94] = (T)(img)(_p4##x,_p3##y,z,c), I[95] = (T)(img)(_p3##x,_p3##y,z,c), I[96] = (T)(img)(_p2##x,_p3##y,z,c), I[97] = (T)(img)(_p1##x,_p3##y,z,c), I[98] = (T)(img)(x,_p3##y,z,c), I[99] = (T)(img)(_n1##x,_p3##y,z,c), I[100] = (T)(img)(_n2##x,_p3##y,z,c), I[101] = (T)(img)(_n3##x,_p3##y,z,c), I[102] = (T)(img)(_n4##x,_p3##y,z,c), I[103] = (T)(img)(_n5##x,_p3##y,z,c), I[104] = (T)(img)(_n6##x,_p3##y,z,c), I[105] = (T)(img)(_n7##x,_p3##y,z,c), I[106] = (T)(img)(_n8##x,_p3##y,z,c), I[107] = (T)(img)(_n9##x,_p3##y,z,c), \ - I[108] = (T)(img)(_p8##x,_p2##y,z,c), I[109] = (T)(img)(_p7##x,_p2##y,z,c), I[110] = (T)(img)(_p6##x,_p2##y,z,c), I[111] = (T)(img)(_p5##x,_p2##y,z,c), I[112] = (T)(img)(_p4##x,_p2##y,z,c), I[113] = (T)(img)(_p3##x,_p2##y,z,c), I[114] = (T)(img)(_p2##x,_p2##y,z,c), I[115] = (T)(img)(_p1##x,_p2##y,z,c), I[116] = (T)(img)(x,_p2##y,z,c), I[117] = (T)(img)(_n1##x,_p2##y,z,c), I[118] = (T)(img)(_n2##x,_p2##y,z,c), I[119] = (T)(img)(_n3##x,_p2##y,z,c), I[120] = (T)(img)(_n4##x,_p2##y,z,c), I[121] = (T)(img)(_n5##x,_p2##y,z,c), I[122] = (T)(img)(_n6##x,_p2##y,z,c), I[123] = (T)(img)(_n7##x,_p2##y,z,c), I[124] = (T)(img)(_n8##x,_p2##y,z,c), I[125] = (T)(img)(_n9##x,_p2##y,z,c), \ - I[126] = (T)(img)(_p8##x,_p1##y,z,c), I[127] = (T)(img)(_p7##x,_p1##y,z,c), I[128] = (T)(img)(_p6##x,_p1##y,z,c), I[129] = (T)(img)(_p5##x,_p1##y,z,c), I[130] = (T)(img)(_p4##x,_p1##y,z,c), I[131] = (T)(img)(_p3##x,_p1##y,z,c), I[132] = (T)(img)(_p2##x,_p1##y,z,c), I[133] = (T)(img)(_p1##x,_p1##y,z,c), I[134] = (T)(img)(x,_p1##y,z,c), I[135] = (T)(img)(_n1##x,_p1##y,z,c), I[136] = (T)(img)(_n2##x,_p1##y,z,c), I[137] = (T)(img)(_n3##x,_p1##y,z,c), I[138] = (T)(img)(_n4##x,_p1##y,z,c), I[139] = (T)(img)(_n5##x,_p1##y,z,c), I[140] = (T)(img)(_n6##x,_p1##y,z,c), I[141] = (T)(img)(_n7##x,_p1##y,z,c), I[142] = (T)(img)(_n8##x,_p1##y,z,c), I[143] = (T)(img)(_n9##x,_p1##y,z,c), \ - I[144] = (T)(img)(_p8##x,y,z,c), I[145] = (T)(img)(_p7##x,y,z,c), I[146] = (T)(img)(_p6##x,y,z,c), I[147] = (T)(img)(_p5##x,y,z,c), I[148] = (T)(img)(_p4##x,y,z,c), I[149] = (T)(img)(_p3##x,y,z,c), I[150] = (T)(img)(_p2##x,y,z,c), I[151] = (T)(img)(_p1##x,y,z,c), I[152] = (T)(img)(x,y,z,c), I[153] = (T)(img)(_n1##x,y,z,c), I[154] = (T)(img)(_n2##x,y,z,c), I[155] = (T)(img)(_n3##x,y,z,c), I[156] = (T)(img)(_n4##x,y,z,c), I[157] = (T)(img)(_n5##x,y,z,c), I[158] = (T)(img)(_n6##x,y,z,c), I[159] = (T)(img)(_n7##x,y,z,c), I[160] = (T)(img)(_n8##x,y,z,c), I[161] = (T)(img)(_n9##x,y,z,c), \ - I[162] = (T)(img)(_p8##x,_n1##y,z,c), I[163] = (T)(img)(_p7##x,_n1##y,z,c), I[164] = (T)(img)(_p6##x,_n1##y,z,c), I[165] = (T)(img)(_p5##x,_n1##y,z,c), I[166] = (T)(img)(_p4##x,_n1##y,z,c), I[167] = (T)(img)(_p3##x,_n1##y,z,c), I[168] = (T)(img)(_p2##x,_n1##y,z,c), I[169] = (T)(img)(_p1##x,_n1##y,z,c), I[170] = (T)(img)(x,_n1##y,z,c), I[171] = (T)(img)(_n1##x,_n1##y,z,c), I[172] = (T)(img)(_n2##x,_n1##y,z,c), I[173] = (T)(img)(_n3##x,_n1##y,z,c), I[174] = (T)(img)(_n4##x,_n1##y,z,c), I[175] = (T)(img)(_n5##x,_n1##y,z,c), I[176] = (T)(img)(_n6##x,_n1##y,z,c), I[177] = (T)(img)(_n7##x,_n1##y,z,c), I[178] = (T)(img)(_n8##x,_n1##y,z,c), I[179] = (T)(img)(_n9##x,_n1##y,z,c), \ - I[180] = (T)(img)(_p8##x,_n2##y,z,c), I[181] = (T)(img)(_p7##x,_n2##y,z,c), I[182] = (T)(img)(_p6##x,_n2##y,z,c), I[183] = (T)(img)(_p5##x,_n2##y,z,c), I[184] = (T)(img)(_p4##x,_n2##y,z,c), I[185] = (T)(img)(_p3##x,_n2##y,z,c), I[186] = (T)(img)(_p2##x,_n2##y,z,c), I[187] = (T)(img)(_p1##x,_n2##y,z,c), I[188] = (T)(img)(x,_n2##y,z,c), I[189] = (T)(img)(_n1##x,_n2##y,z,c), I[190] = (T)(img)(_n2##x,_n2##y,z,c), I[191] = (T)(img)(_n3##x,_n2##y,z,c), I[192] = (T)(img)(_n4##x,_n2##y,z,c), I[193] = (T)(img)(_n5##x,_n2##y,z,c), I[194] = (T)(img)(_n6##x,_n2##y,z,c), I[195] = (T)(img)(_n7##x,_n2##y,z,c), I[196] = (T)(img)(_n8##x,_n2##y,z,c), I[197] = (T)(img)(_n9##x,_n2##y,z,c), \ - I[198] = (T)(img)(_p8##x,_n3##y,z,c), I[199] = (T)(img)(_p7##x,_n3##y,z,c), I[200] = (T)(img)(_p6##x,_n3##y,z,c), I[201] = (T)(img)(_p5##x,_n3##y,z,c), I[202] = (T)(img)(_p4##x,_n3##y,z,c), I[203] = (T)(img)(_p3##x,_n3##y,z,c), I[204] = (T)(img)(_p2##x,_n3##y,z,c), I[205] = (T)(img)(_p1##x,_n3##y,z,c), I[206] = (T)(img)(x,_n3##y,z,c), I[207] = (T)(img)(_n1##x,_n3##y,z,c), I[208] = (T)(img)(_n2##x,_n3##y,z,c), I[209] = (T)(img)(_n3##x,_n3##y,z,c), I[210] = (T)(img)(_n4##x,_n3##y,z,c), I[211] = (T)(img)(_n5##x,_n3##y,z,c), I[212] = (T)(img)(_n6##x,_n3##y,z,c), I[213] = (T)(img)(_n7##x,_n3##y,z,c), I[214] = (T)(img)(_n8##x,_n3##y,z,c), I[215] = (T)(img)(_n9##x,_n3##y,z,c), \ - I[216] = (T)(img)(_p8##x,_n4##y,z,c), I[217] = (T)(img)(_p7##x,_n4##y,z,c), I[218] = (T)(img)(_p6##x,_n4##y,z,c), I[219] = (T)(img)(_p5##x,_n4##y,z,c), I[220] = (T)(img)(_p4##x,_n4##y,z,c), I[221] = (T)(img)(_p3##x,_n4##y,z,c), I[222] = (T)(img)(_p2##x,_n4##y,z,c), I[223] = (T)(img)(_p1##x,_n4##y,z,c), I[224] = (T)(img)(x,_n4##y,z,c), I[225] = (T)(img)(_n1##x,_n4##y,z,c), I[226] = (T)(img)(_n2##x,_n4##y,z,c), I[227] = (T)(img)(_n3##x,_n4##y,z,c), I[228] = (T)(img)(_n4##x,_n4##y,z,c), I[229] = (T)(img)(_n5##x,_n4##y,z,c), I[230] = (T)(img)(_n6##x,_n4##y,z,c), I[231] = (T)(img)(_n7##x,_n4##y,z,c), I[232] = (T)(img)(_n8##x,_n4##y,z,c), I[233] = (T)(img)(_n9##x,_n4##y,z,c), \ - I[234] = (T)(img)(_p8##x,_n5##y,z,c), I[235] = (T)(img)(_p7##x,_n5##y,z,c), I[236] = (T)(img)(_p6##x,_n5##y,z,c), I[237] = (T)(img)(_p5##x,_n5##y,z,c), I[238] = (T)(img)(_p4##x,_n5##y,z,c), I[239] = (T)(img)(_p3##x,_n5##y,z,c), I[240] = (T)(img)(_p2##x,_n5##y,z,c), I[241] = (T)(img)(_p1##x,_n5##y,z,c), I[242] = (T)(img)(x,_n5##y,z,c), I[243] = (T)(img)(_n1##x,_n5##y,z,c), I[244] = (T)(img)(_n2##x,_n5##y,z,c), I[245] = (T)(img)(_n3##x,_n5##y,z,c), I[246] = (T)(img)(_n4##x,_n5##y,z,c), I[247] = (T)(img)(_n5##x,_n5##y,z,c), I[248] = (T)(img)(_n6##x,_n5##y,z,c), I[249] = (T)(img)(_n7##x,_n5##y,z,c), I[250] = (T)(img)(_n8##x,_n5##y,z,c), I[251] = (T)(img)(_n9##x,_n5##y,z,c), \ - I[252] = (T)(img)(_p8##x,_n6##y,z,c), I[253] = (T)(img)(_p7##x,_n6##y,z,c), I[254] = (T)(img)(_p6##x,_n6##y,z,c), I[255] = (T)(img)(_p5##x,_n6##y,z,c), I[256] = (T)(img)(_p4##x,_n6##y,z,c), I[257] = (T)(img)(_p3##x,_n6##y,z,c), I[258] = (T)(img)(_p2##x,_n6##y,z,c), I[259] = (T)(img)(_p1##x,_n6##y,z,c), I[260] = (T)(img)(x,_n6##y,z,c), I[261] = (T)(img)(_n1##x,_n6##y,z,c), I[262] = (T)(img)(_n2##x,_n6##y,z,c), I[263] = (T)(img)(_n3##x,_n6##y,z,c), I[264] = (T)(img)(_n4##x,_n6##y,z,c), I[265] = (T)(img)(_n5##x,_n6##y,z,c), I[266] = (T)(img)(_n6##x,_n6##y,z,c), I[267] = (T)(img)(_n7##x,_n6##y,z,c), I[268] = (T)(img)(_n8##x,_n6##y,z,c), I[269] = (T)(img)(_n9##x,_n6##y,z,c), \ - I[270] = (T)(img)(_p8##x,_n7##y,z,c), I[271] = (T)(img)(_p7##x,_n7##y,z,c), I[272] = (T)(img)(_p6##x,_n7##y,z,c), I[273] = (T)(img)(_p5##x,_n7##y,z,c), I[274] = (T)(img)(_p4##x,_n7##y,z,c), I[275] = (T)(img)(_p3##x,_n7##y,z,c), I[276] = (T)(img)(_p2##x,_n7##y,z,c), I[277] = (T)(img)(_p1##x,_n7##y,z,c), I[278] = (T)(img)(x,_n7##y,z,c), I[279] = (T)(img)(_n1##x,_n7##y,z,c), I[280] = (T)(img)(_n2##x,_n7##y,z,c), I[281] = (T)(img)(_n3##x,_n7##y,z,c), I[282] = (T)(img)(_n4##x,_n7##y,z,c), I[283] = (T)(img)(_n5##x,_n7##y,z,c), I[284] = (T)(img)(_n6##x,_n7##y,z,c), I[285] = (T)(img)(_n7##x,_n7##y,z,c), I[286] = (T)(img)(_n8##x,_n7##y,z,c), I[287] = (T)(img)(_n9##x,_n7##y,z,c), \ - I[288] = (T)(img)(_p8##x,_n8##y,z,c), I[289] = (T)(img)(_p7##x,_n8##y,z,c), I[290] = (T)(img)(_p6##x,_n8##y,z,c), I[291] = (T)(img)(_p5##x,_n8##y,z,c), I[292] = (T)(img)(_p4##x,_n8##y,z,c), I[293] = (T)(img)(_p3##x,_n8##y,z,c), I[294] = (T)(img)(_p2##x,_n8##y,z,c), I[295] = (T)(img)(_p1##x,_n8##y,z,c), I[296] = (T)(img)(x,_n8##y,z,c), I[297] = (T)(img)(_n1##x,_n8##y,z,c), I[298] = (T)(img)(_n2##x,_n8##y,z,c), I[299] = (T)(img)(_n3##x,_n8##y,z,c), I[300] = (T)(img)(_n4##x,_n8##y,z,c), I[301] = (T)(img)(_n5##x,_n8##y,z,c), I[302] = (T)(img)(_n6##x,_n8##y,z,c), I[303] = (T)(img)(_n7##x,_n8##y,z,c), I[304] = (T)(img)(_n8##x,_n8##y,z,c), I[305] = (T)(img)(_n9##x,_n8##y,z,c), \ - I[306] = (T)(img)(_p8##x,_n9##y,z,c), I[307] = (T)(img)(_p7##x,_n9##y,z,c), I[308] = (T)(img)(_p6##x,_n9##y,z,c), I[309] = (T)(img)(_p5##x,_n9##y,z,c), I[310] = (T)(img)(_p4##x,_n9##y,z,c), I[311] = (T)(img)(_p3##x,_n9##y,z,c), I[312] = (T)(img)(_p2##x,_n9##y,z,c), I[313] = (T)(img)(_p1##x,_n9##y,z,c), I[314] = (T)(img)(x,_n9##y,z,c), I[315] = (T)(img)(_n1##x,_n9##y,z,c), I[316] = (T)(img)(_n2##x,_n9##y,z,c), I[317] = (T)(img)(_n3##x,_n9##y,z,c), I[318] = (T)(img)(_n4##x,_n9##y,z,c), I[319] = (T)(img)(_n5##x,_n9##y,z,c), I[320] = (T)(img)(_n6##x,_n9##y,z,c), I[321] = (T)(img)(_n7##x,_n9##y,z,c), I[322] = (T)(img)(_n8##x,_n9##y,z,c), I[323] = (T)(img)(_n9##x,_n9##y,z,c); - -// Define 19x19 loop macros -//------------------------- -#define cimg_for19(bound,i) for (int i = 0, \ - _p9##i = 0, _p8##i = 0, _p7##i = 0, _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6, \ - _n7##i = 7>=(int)(bound)?(int)(bound) - 1:7, \ - _n8##i = 8>=(int)(bound)?(int)(bound) - 1:8, \ - _n9##i = 9>=(int)(bound)?(int)(bound) - 1:9; \ - _n9##i<(int)(bound) || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i) - -#define cimg_for19X(img,x) cimg_for19((img)._width,x) -#define cimg_for19Y(img,y) cimg_for19((img)._height,y) -#define cimg_for19Z(img,z) cimg_for19((img)._depth,z) -#define cimg_for19C(img,c) cimg_for19((img)._spectrum,c) -#define cimg_for19XY(img,x,y) cimg_for19Y(img,y) cimg_for19X(img,x) -#define cimg_for19XZ(img,x,z) cimg_for19Z(img,z) cimg_for19X(img,x) -#define cimg_for19XC(img,x,c) cimg_for19C(img,c) cimg_for19X(img,x) -#define cimg_for19YZ(img,y,z) cimg_for19Z(img,z) cimg_for19Y(img,y) -#define cimg_for19YC(img,y,c) cimg_for19C(img,c) cimg_for19Y(img,y) -#define cimg_for19ZC(img,z,c) cimg_for19C(img,c) cimg_for19Z(img,z) -#define cimg_for19XYZ(img,x,y,z) cimg_for19Z(img,z) cimg_for19XY(img,x,y) -#define cimg_for19XZC(img,x,z,c) cimg_for19C(img,c) cimg_for19XZ(img,x,z) -#define cimg_for19YZC(img,y,z,c) cimg_for19C(img,c) cimg_for19YZ(img,y,z) -#define cimg_for19XYZC(img,x,y,z,c) cimg_for19C(img,c) cimg_for19XYZ(img,x,y,z) - -#define cimg_for_in19(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p9##i = i - 9<0?0:i - 9, \ - _p8##i = i - 8<0?0:i - 8, \ - _p7##i = i - 7<0?0:i - 7, \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6, \ - _n7##i = i + 7>=(int)(bound)?(int)(bound) - 1:i + 7, \ - _n8##i = i + 8>=(int)(bound)?(int)(bound) - 1:i + 8, \ - _n9##i = i + 9>=(int)(bound)?(int)(bound) - 1:i + 9; \ - i<=(int)(i1) && (_n9##i<(int)(bound) || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i) - -#define cimg_for_in19X(img,x0,x1,x) cimg_for_in19((img)._width,x0,x1,x) -#define cimg_for_in19Y(img,y0,y1,y) cimg_for_in19((img)._height,y0,y1,y) -#define cimg_for_in19Z(img,z0,z1,z) cimg_for_in19((img)._depth,z0,z1,z) -#define cimg_for_in19C(img,c0,c1,c) cimg_for_in19((img)._spectrum,c0,c1,c) -#define cimg_for_in19XY(img,x0,y0,x1,y1,x,y) cimg_for_in19Y(img,y0,y1,y) cimg_for_in19X(img,x0,x1,x) -#define cimg_for_in19XZ(img,x0,z0,x1,z1,x,z) cimg_for_in19Z(img,z0,z1,z) cimg_for_in19X(img,x0,x1,x) -#define cimg_for_in19XC(img,x0,c0,x1,c1,x,c) cimg_for_in19C(img,c0,c1,c) cimg_for_in19X(img,x0,x1,x) -#define cimg_for_in19YZ(img,y0,z0,y1,z1,y,z) cimg_for_in19Z(img,z0,z1,z) cimg_for_in19Y(img,y0,y1,y) -#define cimg_for_in19YC(img,y0,c0,y1,c1,y,c) cimg_for_in19C(img,c0,c1,c) cimg_for_in19Y(img,y0,y1,y) -#define cimg_for_in19ZC(img,z0,c0,z1,c1,z,c) cimg_for_in19C(img,c0,c1,c) cimg_for_in19Z(img,z0,z1,z) -#define cimg_for_in19XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in19Z(img,z0,z1,z) cimg_for_in19XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in19XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in19C(img,c0,c1,c) cimg_for_in19XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in19YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in19C(img,c0,c1,c) cimg_for_in19YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in19XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in19C(img,c0,c1,c) cimg_for_in19XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for19x19(img,x,y,z,c,I,T) \ - cimg_for19((img)._height,y) for (int x = 0, \ - _p9##x = 0, _p8##x = 0, _p7##x = 0, _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = 6>=((img)._width)?(img).width() - 1:6, \ - _n7##x = 7>=((img)._width)?(img).width() - 1:7, \ - _n8##x = 8>=((img)._width)?(img).width() - 1:8, \ - _n9##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = I[7] = I[8] = I[9] = (T)(img)(0,_p9##y,z,c)), \ - (I[19] = I[20] = I[21] = I[22] = I[23] = I[24] = I[25] = I[26] = I[27] = I[28] = (T)(img)(0,_p8##y,z,c)), \ - (I[38] = I[39] = I[40] = I[41] = I[42] = I[43] = I[44] = I[45] = I[46] = I[47] = (T)(img)(0,_p7##y,z,c)), \ - (I[57] = I[58] = I[59] = I[60] = I[61] = I[62] = I[63] = I[64] = I[65] = I[66] = (T)(img)(0,_p6##y,z,c)), \ - (I[76] = I[77] = I[78] = I[79] = I[80] = I[81] = I[82] = I[83] = I[84] = I[85] = (T)(img)(0,_p5##y,z,c)), \ - (I[95] = I[96] = I[97] = I[98] = I[99] = I[100] = I[101] = I[102] = I[103] = I[104] = (T)(img)(0,_p4##y,z,c)), \ - (I[114] = I[115] = I[116] = I[117] = I[118] = I[119] = I[120] = I[121] = I[122] = I[123] = (T)(img)(0,_p3##y,z,c)), \ - (I[133] = I[134] = I[135] = I[136] = I[137] = I[138] = I[139] = I[140] = I[141] = I[142] = (T)(img)(0,_p2##y,z,c)), \ - (I[152] = I[153] = I[154] = I[155] = I[156] = I[157] = I[158] = I[159] = I[160] = I[161] = (T)(img)(0,_p1##y,z,c)), \ - (I[171] = I[172] = I[173] = I[174] = I[175] = I[176] = I[177] = I[178] = I[179] = I[180] = (T)(img)(0,y,z,c)), \ - (I[190] = I[191] = I[192] = I[193] = I[194] = I[195] = I[196] = I[197] = I[198] = I[199] = (T)(img)(0,_n1##y,z,c)), \ - (I[209] = I[210] = I[211] = I[212] = I[213] = I[214] = I[215] = I[216] = I[217] = I[218] = (T)(img)(0,_n2##y,z,c)), \ - (I[228] = I[229] = I[230] = I[231] = I[232] = I[233] = I[234] = I[235] = I[236] = I[237] = (T)(img)(0,_n3##y,z,c)), \ - (I[247] = I[248] = I[249] = I[250] = I[251] = I[252] = I[253] = I[254] = I[255] = I[256] = (T)(img)(0,_n4##y,z,c)), \ - (I[266] = I[267] = I[268] = I[269] = I[270] = I[271] = I[272] = I[273] = I[274] = I[275] = (T)(img)(0,_n5##y,z,c)), \ - (I[285] = I[286] = I[287] = I[288] = I[289] = I[290] = I[291] = I[292] = I[293] = I[294] = (T)(img)(0,_n6##y,z,c)), \ - (I[304] = I[305] = I[306] = I[307] = I[308] = I[309] = I[310] = I[311] = I[312] = I[313] = (T)(img)(0,_n7##y,z,c)), \ - (I[323] = I[324] = I[325] = I[326] = I[327] = I[328] = I[329] = I[330] = I[331] = I[332] = (T)(img)(0,_n8##y,z,c)), \ - (I[342] = I[343] = I[344] = I[345] = I[346] = I[347] = I[348] = I[349] = I[350] = I[351] = (T)(img)(0,_n9##y,z,c)), \ - (I[10] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[29] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[48] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[67] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[86] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[105] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[124] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[143] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[162] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[181] = (T)(img)(_n1##x,y,z,c)), \ - (I[200] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[219] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[238] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[257] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[276] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[295] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[314] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[333] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[352] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[11] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[30] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[49] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[68] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[87] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[106] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[125] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[144] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[163] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[182] = (T)(img)(_n2##x,y,z,c)), \ - (I[201] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[220] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[239] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[258] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[277] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[296] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[315] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[334] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[353] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[12] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[31] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[50] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[69] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[88] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[107] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[126] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[145] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[164] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[183] = (T)(img)(_n3##x,y,z,c)), \ - (I[202] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[221] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[240] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[259] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[278] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[297] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[316] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[335] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[354] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[13] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[32] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[51] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[70] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[89] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[108] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[127] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[146] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[165] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[184] = (T)(img)(_n4##x,y,z,c)), \ - (I[203] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[222] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[241] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[260] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[279] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[298] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[317] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[336] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[355] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[14] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[33] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[52] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[71] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[90] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[109] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[128] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[147] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[166] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[185] = (T)(img)(_n5##x,y,z,c)), \ - (I[204] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[223] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[242] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[261] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[280] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[299] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[318] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[337] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[356] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[15] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[34] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[53] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[72] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[91] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[110] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[129] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[148] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[167] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[186] = (T)(img)(_n6##x,y,z,c)), \ - (I[205] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[224] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[243] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[262] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[281] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[300] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[319] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[338] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[357] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[16] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[35] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[54] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[73] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[92] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[111] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[130] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[149] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[168] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[187] = (T)(img)(_n7##x,y,z,c)), \ - (I[206] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[225] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[244] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[263] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[282] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[301] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[320] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[339] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[358] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[17] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[36] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[55] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[74] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[93] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[112] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[131] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[150] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[169] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[188] = (T)(img)(_n8##x,y,z,c)), \ - (I[207] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[226] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[245] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[264] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[283] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[302] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[321] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[340] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[359] = (T)(img)(_n8##x,_n9##y,z,c)), \ - 9>=((img)._width)?(img).width() - 1:9); \ - (_n9##x<(img).width() && ( \ - (I[18] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[37] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[56] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[75] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[94] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[113] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[132] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[151] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[170] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[189] = (T)(img)(_n9##x,y,z,c)), \ - (I[208] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[227] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[246] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[265] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[284] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[303] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[322] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[341] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[360] = (T)(img)(_n9##x,_n9##y,z,c)),1)) || \ - _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], \ - I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], \ - I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], \ - I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], \ - I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], \ - I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], \ - I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], \ - I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], \ - I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], \ - I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], \ - I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], \ - I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], \ - I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], \ - I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], \ - I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], \ - I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], \ - I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], \ - I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], \ - I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], \ - _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x) - -#define cimg_for_in19x19(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in19((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p9##x = x - 9<0?0:x - 9, \ - _p8##x = x - 8<0?0:x - 8, \ - _p7##x = x - 7<0?0:x - 7, \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = x + 6>=(img).width()?(img).width() - 1:x + 6, \ - _n7##x = x + 7>=(img).width()?(img).width() - 1:x + 7, \ - _n8##x = x + 8>=(img).width()?(img).width() - 1:x + 8, \ - _n9##x = (int)( \ - (I[0] = (T)(img)(_p9##x,_p9##y,z,c)), \ - (I[19] = (T)(img)(_p9##x,_p8##y,z,c)), \ - (I[38] = (T)(img)(_p9##x,_p7##y,z,c)), \ - (I[57] = (T)(img)(_p9##x,_p6##y,z,c)), \ - (I[76] = (T)(img)(_p9##x,_p5##y,z,c)), \ - (I[95] = (T)(img)(_p9##x,_p4##y,z,c)), \ - (I[114] = (T)(img)(_p9##x,_p3##y,z,c)), \ - (I[133] = (T)(img)(_p9##x,_p2##y,z,c)), \ - (I[152] = (T)(img)(_p9##x,_p1##y,z,c)), \ - (I[171] = (T)(img)(_p9##x,y,z,c)), \ - (I[190] = (T)(img)(_p9##x,_n1##y,z,c)), \ - (I[209] = (T)(img)(_p9##x,_n2##y,z,c)), \ - (I[228] = (T)(img)(_p9##x,_n3##y,z,c)), \ - (I[247] = (T)(img)(_p9##x,_n4##y,z,c)), \ - (I[266] = (T)(img)(_p9##x,_n5##y,z,c)), \ - (I[285] = (T)(img)(_p9##x,_n6##y,z,c)), \ - (I[304] = (T)(img)(_p9##x,_n7##y,z,c)), \ - (I[323] = (T)(img)(_p9##x,_n8##y,z,c)), \ - (I[342] = (T)(img)(_p9##x,_n9##y,z,c)), \ - (I[1] = (T)(img)(_p8##x,_p9##y,z,c)), \ - (I[20] = (T)(img)(_p8##x,_p8##y,z,c)), \ - (I[39] = (T)(img)(_p8##x,_p7##y,z,c)), \ - (I[58] = (T)(img)(_p8##x,_p6##y,z,c)), \ - (I[77] = (T)(img)(_p8##x,_p5##y,z,c)), \ - (I[96] = (T)(img)(_p8##x,_p4##y,z,c)), \ - (I[115] = (T)(img)(_p8##x,_p3##y,z,c)), \ - (I[134] = (T)(img)(_p8##x,_p2##y,z,c)), \ - (I[153] = (T)(img)(_p8##x,_p1##y,z,c)), \ - (I[172] = (T)(img)(_p8##x,y,z,c)), \ - (I[191] = (T)(img)(_p8##x,_n1##y,z,c)), \ - (I[210] = (T)(img)(_p8##x,_n2##y,z,c)), \ - (I[229] = (T)(img)(_p8##x,_n3##y,z,c)), \ - (I[248] = (T)(img)(_p8##x,_n4##y,z,c)), \ - (I[267] = (T)(img)(_p8##x,_n5##y,z,c)), \ - (I[286] = (T)(img)(_p8##x,_n6##y,z,c)), \ - (I[305] = (T)(img)(_p8##x,_n7##y,z,c)), \ - (I[324] = (T)(img)(_p8##x,_n8##y,z,c)), \ - (I[343] = (T)(img)(_p8##x,_n9##y,z,c)), \ - (I[2] = (T)(img)(_p7##x,_p9##y,z,c)), \ - (I[21] = (T)(img)(_p7##x,_p8##y,z,c)), \ - (I[40] = (T)(img)(_p7##x,_p7##y,z,c)), \ - (I[59] = (T)(img)(_p7##x,_p6##y,z,c)), \ - (I[78] = (T)(img)(_p7##x,_p5##y,z,c)), \ - (I[97] = (T)(img)(_p7##x,_p4##y,z,c)), \ - (I[116] = (T)(img)(_p7##x,_p3##y,z,c)), \ - (I[135] = (T)(img)(_p7##x,_p2##y,z,c)), \ - (I[154] = (T)(img)(_p7##x,_p1##y,z,c)), \ - (I[173] = (T)(img)(_p7##x,y,z,c)), \ - (I[192] = (T)(img)(_p7##x,_n1##y,z,c)), \ - (I[211] = (T)(img)(_p7##x,_n2##y,z,c)), \ - (I[230] = (T)(img)(_p7##x,_n3##y,z,c)), \ - (I[249] = (T)(img)(_p7##x,_n4##y,z,c)), \ - (I[268] = (T)(img)(_p7##x,_n5##y,z,c)), \ - (I[287] = (T)(img)(_p7##x,_n6##y,z,c)), \ - (I[306] = (T)(img)(_p7##x,_n7##y,z,c)), \ - (I[325] = (T)(img)(_p7##x,_n8##y,z,c)), \ - (I[344] = (T)(img)(_p7##x,_n9##y,z,c)), \ - (I[3] = (T)(img)(_p6##x,_p9##y,z,c)), \ - (I[22] = (T)(img)(_p6##x,_p8##y,z,c)), \ - (I[41] = (T)(img)(_p6##x,_p7##y,z,c)), \ - (I[60] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[79] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[98] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[117] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[136] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[155] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[174] = (T)(img)(_p6##x,y,z,c)), \ - (I[193] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[212] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[231] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[250] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[269] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[288] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[307] = (T)(img)(_p6##x,_n7##y,z,c)), \ - (I[326] = (T)(img)(_p6##x,_n8##y,z,c)), \ - (I[345] = (T)(img)(_p6##x,_n9##y,z,c)), \ - (I[4] = (T)(img)(_p5##x,_p9##y,z,c)), \ - (I[23] = (T)(img)(_p5##x,_p8##y,z,c)), \ - (I[42] = (T)(img)(_p5##x,_p7##y,z,c)), \ - (I[61] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[80] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[99] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[118] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[137] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[156] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[175] = (T)(img)(_p5##x,y,z,c)), \ - (I[194] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[213] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[232] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[251] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[270] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[289] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[308] = (T)(img)(_p5##x,_n7##y,z,c)), \ - (I[327] = (T)(img)(_p5##x,_n8##y,z,c)), \ - (I[346] = (T)(img)(_p5##x,_n9##y,z,c)), \ - (I[5] = (T)(img)(_p4##x,_p9##y,z,c)), \ - (I[24] = (T)(img)(_p4##x,_p8##y,z,c)), \ - (I[43] = (T)(img)(_p4##x,_p7##y,z,c)), \ - (I[62] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[81] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[100] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[119] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[138] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[157] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[176] = (T)(img)(_p4##x,y,z,c)), \ - (I[195] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[214] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[233] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[252] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[271] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[290] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[309] = (T)(img)(_p4##x,_n7##y,z,c)), \ - (I[328] = (T)(img)(_p4##x,_n8##y,z,c)), \ - (I[347] = (T)(img)(_p4##x,_n9##y,z,c)), \ - (I[6] = (T)(img)(_p3##x,_p9##y,z,c)), \ - (I[25] = (T)(img)(_p3##x,_p8##y,z,c)), \ - (I[44] = (T)(img)(_p3##x,_p7##y,z,c)), \ - (I[63] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[82] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[101] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[120] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[139] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[158] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[177] = (T)(img)(_p3##x,y,z,c)), \ - (I[196] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[215] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[234] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[253] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[272] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[291] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[310] = (T)(img)(_p3##x,_n7##y,z,c)), \ - (I[329] = (T)(img)(_p3##x,_n8##y,z,c)), \ - (I[348] = (T)(img)(_p3##x,_n9##y,z,c)), \ - (I[7] = (T)(img)(_p2##x,_p9##y,z,c)), \ - (I[26] = (T)(img)(_p2##x,_p8##y,z,c)), \ - (I[45] = (T)(img)(_p2##x,_p7##y,z,c)), \ - (I[64] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[83] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[102] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[121] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[140] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[159] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[178] = (T)(img)(_p2##x,y,z,c)), \ - (I[197] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[216] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[235] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[254] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[273] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[292] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[311] = (T)(img)(_p2##x,_n7##y,z,c)), \ - (I[330] = (T)(img)(_p2##x,_n8##y,z,c)), \ - (I[349] = (T)(img)(_p2##x,_n9##y,z,c)), \ - (I[8] = (T)(img)(_p1##x,_p9##y,z,c)), \ - (I[27] = (T)(img)(_p1##x,_p8##y,z,c)), \ - (I[46] = (T)(img)(_p1##x,_p7##y,z,c)), \ - (I[65] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[84] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[103] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[122] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[141] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[160] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[179] = (T)(img)(_p1##x,y,z,c)), \ - (I[198] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[217] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[236] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[255] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[274] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[293] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[312] = (T)(img)(_p1##x,_n7##y,z,c)), \ - (I[331] = (T)(img)(_p1##x,_n8##y,z,c)), \ - (I[350] = (T)(img)(_p1##x,_n9##y,z,c)), \ - (I[9] = (T)(img)(x,_p9##y,z,c)), \ - (I[28] = (T)(img)(x,_p8##y,z,c)), \ - (I[47] = (T)(img)(x,_p7##y,z,c)), \ - (I[66] = (T)(img)(x,_p6##y,z,c)), \ - (I[85] = (T)(img)(x,_p5##y,z,c)), \ - (I[104] = (T)(img)(x,_p4##y,z,c)), \ - (I[123] = (T)(img)(x,_p3##y,z,c)), \ - (I[142] = (T)(img)(x,_p2##y,z,c)), \ - (I[161] = (T)(img)(x,_p1##y,z,c)), \ - (I[180] = (T)(img)(x,y,z,c)), \ - (I[199] = (T)(img)(x,_n1##y,z,c)), \ - (I[218] = (T)(img)(x,_n2##y,z,c)), \ - (I[237] = (T)(img)(x,_n3##y,z,c)), \ - (I[256] = (T)(img)(x,_n4##y,z,c)), \ - (I[275] = (T)(img)(x,_n5##y,z,c)), \ - (I[294] = (T)(img)(x,_n6##y,z,c)), \ - (I[313] = (T)(img)(x,_n7##y,z,c)), \ - (I[332] = (T)(img)(x,_n8##y,z,c)), \ - (I[351] = (T)(img)(x,_n9##y,z,c)), \ - (I[10] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[29] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[48] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[67] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[86] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[105] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[124] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[143] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[162] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[181] = (T)(img)(_n1##x,y,z,c)), \ - (I[200] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[219] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[238] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[257] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[276] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[295] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[314] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[333] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[352] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[11] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[30] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[49] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[68] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[87] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[106] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[125] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[144] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[163] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[182] = (T)(img)(_n2##x,y,z,c)), \ - (I[201] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[220] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[239] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[258] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[277] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[296] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[315] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[334] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[353] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[12] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[31] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[50] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[69] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[88] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[107] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[126] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[145] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[164] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[183] = (T)(img)(_n3##x,y,z,c)), \ - (I[202] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[221] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[240] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[259] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[278] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[297] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[316] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[335] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[354] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[13] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[32] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[51] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[70] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[89] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[108] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[127] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[146] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[165] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[184] = (T)(img)(_n4##x,y,z,c)), \ - (I[203] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[222] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[241] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[260] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[279] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[298] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[317] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[336] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[355] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[14] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[33] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[52] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[71] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[90] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[109] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[128] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[147] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[166] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[185] = (T)(img)(_n5##x,y,z,c)), \ - (I[204] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[223] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[242] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[261] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[280] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[299] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[318] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[337] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[356] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[15] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[34] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[53] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[72] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[91] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[110] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[129] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[148] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[167] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[186] = (T)(img)(_n6##x,y,z,c)), \ - (I[205] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[224] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[243] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[262] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[281] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[300] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[319] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[338] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[357] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[16] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[35] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[54] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[73] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[92] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[111] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[130] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[149] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[168] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[187] = (T)(img)(_n7##x,y,z,c)), \ - (I[206] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[225] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[244] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[263] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[282] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[301] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[320] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[339] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[358] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[17] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[36] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[55] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[74] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[93] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[112] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[131] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[150] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[169] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[188] = (T)(img)(_n8##x,y,z,c)), \ - (I[207] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[226] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[245] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[264] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[283] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[302] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[321] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[340] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[359] = (T)(img)(_n8##x,_n9##y,z,c)), \ - x + 9>=(img).width()?(img).width() - 1:x + 9); \ - x<=(int)(x1) && ((_n9##x<(img).width() && ( \ - (I[18] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[37] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[56] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[75] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[94] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[113] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[132] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[151] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[170] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[189] = (T)(img)(_n9##x,y,z,c)), \ - (I[208] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[227] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[246] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[265] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[284] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[303] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[322] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[341] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[360] = (T)(img)(_n9##x,_n9##y,z,c)),1)) || \ - _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], \ - I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], \ - I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], \ - I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], \ - I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], \ - I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], \ - I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], \ - I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], \ - I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], \ - I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], \ - I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], \ - I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], \ - I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], \ - I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], \ - I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], \ - I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], \ - I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], \ - I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], \ - I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], \ - _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x) - -#define cimg_get19x19(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p9##x,_p9##y,z,c), I[1] = (T)(img)(_p8##x,_p9##y,z,c), I[2] = (T)(img)(_p7##x,_p9##y,z,c), I[3] = (T)(img)(_p6##x,_p9##y,z,c), I[4] = (T)(img)(_p5##x,_p9##y,z,c), I[5] = (T)(img)(_p4##x,_p9##y,z,c), I[6] = (T)(img)(_p3##x,_p9##y,z,c), I[7] = (T)(img)(_p2##x,_p9##y,z,c), I[8] = (T)(img)(_p1##x,_p9##y,z,c), I[9] = (T)(img)(x,_p9##y,z,c), I[10] = (T)(img)(_n1##x,_p9##y,z,c), I[11] = (T)(img)(_n2##x,_p9##y,z,c), I[12] = (T)(img)(_n3##x,_p9##y,z,c), I[13] = (T)(img)(_n4##x,_p9##y,z,c), I[14] = (T)(img)(_n5##x,_p9##y,z,c), I[15] = (T)(img)(_n6##x,_p9##y,z,c), I[16] = (T)(img)(_n7##x,_p9##y,z,c), I[17] = (T)(img)(_n8##x,_p9##y,z,c), I[18] = (T)(img)(_n9##x,_p9##y,z,c), \ - I[19] = (T)(img)(_p9##x,_p8##y,z,c), I[20] = (T)(img)(_p8##x,_p8##y,z,c), I[21] = (T)(img)(_p7##x,_p8##y,z,c), I[22] = (T)(img)(_p6##x,_p8##y,z,c), I[23] = (T)(img)(_p5##x,_p8##y,z,c), I[24] = (T)(img)(_p4##x,_p8##y,z,c), I[25] = (T)(img)(_p3##x,_p8##y,z,c), I[26] = (T)(img)(_p2##x,_p8##y,z,c), I[27] = (T)(img)(_p1##x,_p8##y,z,c), I[28] = (T)(img)(x,_p8##y,z,c), I[29] = (T)(img)(_n1##x,_p8##y,z,c), I[30] = (T)(img)(_n2##x,_p8##y,z,c), I[31] = (T)(img)(_n3##x,_p8##y,z,c), I[32] = (T)(img)(_n4##x,_p8##y,z,c), I[33] = (T)(img)(_n5##x,_p8##y,z,c), I[34] = (T)(img)(_n6##x,_p8##y,z,c), I[35] = (T)(img)(_n7##x,_p8##y,z,c), I[36] = (T)(img)(_n8##x,_p8##y,z,c), I[37] = (T)(img)(_n9##x,_p8##y,z,c), \ - I[38] = (T)(img)(_p9##x,_p7##y,z,c), I[39] = (T)(img)(_p8##x,_p7##y,z,c), I[40] = (T)(img)(_p7##x,_p7##y,z,c), I[41] = (T)(img)(_p6##x,_p7##y,z,c), I[42] = (T)(img)(_p5##x,_p7##y,z,c), I[43] = (T)(img)(_p4##x,_p7##y,z,c), I[44] = (T)(img)(_p3##x,_p7##y,z,c), I[45] = (T)(img)(_p2##x,_p7##y,z,c), I[46] = (T)(img)(_p1##x,_p7##y,z,c), I[47] = (T)(img)(x,_p7##y,z,c), I[48] = (T)(img)(_n1##x,_p7##y,z,c), I[49] = (T)(img)(_n2##x,_p7##y,z,c), I[50] = (T)(img)(_n3##x,_p7##y,z,c), I[51] = (T)(img)(_n4##x,_p7##y,z,c), I[52] = (T)(img)(_n5##x,_p7##y,z,c), I[53] = (T)(img)(_n6##x,_p7##y,z,c), I[54] = (T)(img)(_n7##x,_p7##y,z,c), I[55] = (T)(img)(_n8##x,_p7##y,z,c), I[56] = (T)(img)(_n9##x,_p7##y,z,c), \ - I[57] = (T)(img)(_p9##x,_p6##y,z,c), I[58] = (T)(img)(_p8##x,_p6##y,z,c), I[59] = (T)(img)(_p7##x,_p6##y,z,c), I[60] = (T)(img)(_p6##x,_p6##y,z,c), I[61] = (T)(img)(_p5##x,_p6##y,z,c), I[62] = (T)(img)(_p4##x,_p6##y,z,c), I[63] = (T)(img)(_p3##x,_p6##y,z,c), I[64] = (T)(img)(_p2##x,_p6##y,z,c), I[65] = (T)(img)(_p1##x,_p6##y,z,c), I[66] = (T)(img)(x,_p6##y,z,c), I[67] = (T)(img)(_n1##x,_p6##y,z,c), I[68] = (T)(img)(_n2##x,_p6##y,z,c), I[69] = (T)(img)(_n3##x,_p6##y,z,c), I[70] = (T)(img)(_n4##x,_p6##y,z,c), I[71] = (T)(img)(_n5##x,_p6##y,z,c), I[72] = (T)(img)(_n6##x,_p6##y,z,c), I[73] = (T)(img)(_n7##x,_p6##y,z,c), I[74] = (T)(img)(_n8##x,_p6##y,z,c), I[75] = (T)(img)(_n9##x,_p6##y,z,c), \ - I[76] = (T)(img)(_p9##x,_p5##y,z,c), I[77] = (T)(img)(_p8##x,_p5##y,z,c), I[78] = (T)(img)(_p7##x,_p5##y,z,c), I[79] = (T)(img)(_p6##x,_p5##y,z,c), I[80] = (T)(img)(_p5##x,_p5##y,z,c), I[81] = (T)(img)(_p4##x,_p5##y,z,c), I[82] = (T)(img)(_p3##x,_p5##y,z,c), I[83] = (T)(img)(_p2##x,_p5##y,z,c), I[84] = (T)(img)(_p1##x,_p5##y,z,c), I[85] = (T)(img)(x,_p5##y,z,c), I[86] = (T)(img)(_n1##x,_p5##y,z,c), I[87] = (T)(img)(_n2##x,_p5##y,z,c), I[88] = (T)(img)(_n3##x,_p5##y,z,c), I[89] = (T)(img)(_n4##x,_p5##y,z,c), I[90] = (T)(img)(_n5##x,_p5##y,z,c), I[91] = (T)(img)(_n6##x,_p5##y,z,c), I[92] = (T)(img)(_n7##x,_p5##y,z,c), I[93] = (T)(img)(_n8##x,_p5##y,z,c), I[94] = (T)(img)(_n9##x,_p5##y,z,c), \ - I[95] = (T)(img)(_p9##x,_p4##y,z,c), I[96] = (T)(img)(_p8##x,_p4##y,z,c), I[97] = (T)(img)(_p7##x,_p4##y,z,c), I[98] = (T)(img)(_p6##x,_p4##y,z,c), I[99] = (T)(img)(_p5##x,_p4##y,z,c), I[100] = (T)(img)(_p4##x,_p4##y,z,c), I[101] = (T)(img)(_p3##x,_p4##y,z,c), I[102] = (T)(img)(_p2##x,_p4##y,z,c), I[103] = (T)(img)(_p1##x,_p4##y,z,c), I[104] = (T)(img)(x,_p4##y,z,c), I[105] = (T)(img)(_n1##x,_p4##y,z,c), I[106] = (T)(img)(_n2##x,_p4##y,z,c), I[107] = (T)(img)(_n3##x,_p4##y,z,c), I[108] = (T)(img)(_n4##x,_p4##y,z,c), I[109] = (T)(img)(_n5##x,_p4##y,z,c), I[110] = (T)(img)(_n6##x,_p4##y,z,c), I[111] = (T)(img)(_n7##x,_p4##y,z,c), I[112] = (T)(img)(_n8##x,_p4##y,z,c), I[113] = (T)(img)(_n9##x,_p4##y,z,c), \ - I[114] = (T)(img)(_p9##x,_p3##y,z,c), I[115] = (T)(img)(_p8##x,_p3##y,z,c), I[116] = (T)(img)(_p7##x,_p3##y,z,c), I[117] = (T)(img)(_p6##x,_p3##y,z,c), I[118] = (T)(img)(_p5##x,_p3##y,z,c), I[119] = (T)(img)(_p4##x,_p3##y,z,c), I[120] = (T)(img)(_p3##x,_p3##y,z,c), I[121] = (T)(img)(_p2##x,_p3##y,z,c), I[122] = (T)(img)(_p1##x,_p3##y,z,c), I[123] = (T)(img)(x,_p3##y,z,c), I[124] = (T)(img)(_n1##x,_p3##y,z,c), I[125] = (T)(img)(_n2##x,_p3##y,z,c), I[126] = (T)(img)(_n3##x,_p3##y,z,c), I[127] = (T)(img)(_n4##x,_p3##y,z,c), I[128] = (T)(img)(_n5##x,_p3##y,z,c), I[129] = (T)(img)(_n6##x,_p3##y,z,c), I[130] = (T)(img)(_n7##x,_p3##y,z,c), I[131] = (T)(img)(_n8##x,_p3##y,z,c), I[132] = (T)(img)(_n9##x,_p3##y,z,c), \ - I[133] = (T)(img)(_p9##x,_p2##y,z,c), I[134] = (T)(img)(_p8##x,_p2##y,z,c), I[135] = (T)(img)(_p7##x,_p2##y,z,c), I[136] = (T)(img)(_p6##x,_p2##y,z,c), I[137] = (T)(img)(_p5##x,_p2##y,z,c), I[138] = (T)(img)(_p4##x,_p2##y,z,c), I[139] = (T)(img)(_p3##x,_p2##y,z,c), I[140] = (T)(img)(_p2##x,_p2##y,z,c), I[141] = (T)(img)(_p1##x,_p2##y,z,c), I[142] = (T)(img)(x,_p2##y,z,c), I[143] = (T)(img)(_n1##x,_p2##y,z,c), I[144] = (T)(img)(_n2##x,_p2##y,z,c), I[145] = (T)(img)(_n3##x,_p2##y,z,c), I[146] = (T)(img)(_n4##x,_p2##y,z,c), I[147] = (T)(img)(_n5##x,_p2##y,z,c), I[148] = (T)(img)(_n6##x,_p2##y,z,c), I[149] = (T)(img)(_n7##x,_p2##y,z,c), I[150] = (T)(img)(_n8##x,_p2##y,z,c), I[151] = (T)(img)(_n9##x,_p2##y,z,c), \ - I[152] = (T)(img)(_p9##x,_p1##y,z,c), I[153] = (T)(img)(_p8##x,_p1##y,z,c), I[154] = (T)(img)(_p7##x,_p1##y,z,c), I[155] = (T)(img)(_p6##x,_p1##y,z,c), I[156] = (T)(img)(_p5##x,_p1##y,z,c), I[157] = (T)(img)(_p4##x,_p1##y,z,c), I[158] = (T)(img)(_p3##x,_p1##y,z,c), I[159] = (T)(img)(_p2##x,_p1##y,z,c), I[160] = (T)(img)(_p1##x,_p1##y,z,c), I[161] = (T)(img)(x,_p1##y,z,c), I[162] = (T)(img)(_n1##x,_p1##y,z,c), I[163] = (T)(img)(_n2##x,_p1##y,z,c), I[164] = (T)(img)(_n3##x,_p1##y,z,c), I[165] = (T)(img)(_n4##x,_p1##y,z,c), I[166] = (T)(img)(_n5##x,_p1##y,z,c), I[167] = (T)(img)(_n6##x,_p1##y,z,c), I[168] = (T)(img)(_n7##x,_p1##y,z,c), I[169] = (T)(img)(_n8##x,_p1##y,z,c), I[170] = (T)(img)(_n9##x,_p1##y,z,c), \ - I[171] = (T)(img)(_p9##x,y,z,c), I[172] = (T)(img)(_p8##x,y,z,c), I[173] = (T)(img)(_p7##x,y,z,c), I[174] = (T)(img)(_p6##x,y,z,c), I[175] = (T)(img)(_p5##x,y,z,c), I[176] = (T)(img)(_p4##x,y,z,c), I[177] = (T)(img)(_p3##x,y,z,c), I[178] = (T)(img)(_p2##x,y,z,c), I[179] = (T)(img)(_p1##x,y,z,c), I[180] = (T)(img)(x,y,z,c), I[181] = (T)(img)(_n1##x,y,z,c), I[182] = (T)(img)(_n2##x,y,z,c), I[183] = (T)(img)(_n3##x,y,z,c), I[184] = (T)(img)(_n4##x,y,z,c), I[185] = (T)(img)(_n5##x,y,z,c), I[186] = (T)(img)(_n6##x,y,z,c), I[187] = (T)(img)(_n7##x,y,z,c), I[188] = (T)(img)(_n8##x,y,z,c), I[189] = (T)(img)(_n9##x,y,z,c), \ - I[190] = (T)(img)(_p9##x,_n1##y,z,c), I[191] = (T)(img)(_p8##x,_n1##y,z,c), I[192] = (T)(img)(_p7##x,_n1##y,z,c), I[193] = (T)(img)(_p6##x,_n1##y,z,c), I[194] = (T)(img)(_p5##x,_n1##y,z,c), I[195] = (T)(img)(_p4##x,_n1##y,z,c), I[196] = (T)(img)(_p3##x,_n1##y,z,c), I[197] = (T)(img)(_p2##x,_n1##y,z,c), I[198] = (T)(img)(_p1##x,_n1##y,z,c), I[199] = (T)(img)(x,_n1##y,z,c), I[200] = (T)(img)(_n1##x,_n1##y,z,c), I[201] = (T)(img)(_n2##x,_n1##y,z,c), I[202] = (T)(img)(_n3##x,_n1##y,z,c), I[203] = (T)(img)(_n4##x,_n1##y,z,c), I[204] = (T)(img)(_n5##x,_n1##y,z,c), I[205] = (T)(img)(_n6##x,_n1##y,z,c), I[206] = (T)(img)(_n7##x,_n1##y,z,c), I[207] = (T)(img)(_n8##x,_n1##y,z,c), I[208] = (T)(img)(_n9##x,_n1##y,z,c), \ - I[209] = (T)(img)(_p9##x,_n2##y,z,c), I[210] = (T)(img)(_p8##x,_n2##y,z,c), I[211] = (T)(img)(_p7##x,_n2##y,z,c), I[212] = (T)(img)(_p6##x,_n2##y,z,c), I[213] = (T)(img)(_p5##x,_n2##y,z,c), I[214] = (T)(img)(_p4##x,_n2##y,z,c), I[215] = (T)(img)(_p3##x,_n2##y,z,c), I[216] = (T)(img)(_p2##x,_n2##y,z,c), I[217] = (T)(img)(_p1##x,_n2##y,z,c), I[218] = (T)(img)(x,_n2##y,z,c), I[219] = (T)(img)(_n1##x,_n2##y,z,c), I[220] = (T)(img)(_n2##x,_n2##y,z,c), I[221] = (T)(img)(_n3##x,_n2##y,z,c), I[222] = (T)(img)(_n4##x,_n2##y,z,c), I[223] = (T)(img)(_n5##x,_n2##y,z,c), I[224] = (T)(img)(_n6##x,_n2##y,z,c), I[225] = (T)(img)(_n7##x,_n2##y,z,c), I[226] = (T)(img)(_n8##x,_n2##y,z,c), I[227] = (T)(img)(_n9##x,_n2##y,z,c), \ - I[228] = (T)(img)(_p9##x,_n3##y,z,c), I[229] = (T)(img)(_p8##x,_n3##y,z,c), I[230] = (T)(img)(_p7##x,_n3##y,z,c), I[231] = (T)(img)(_p6##x,_n3##y,z,c), I[232] = (T)(img)(_p5##x,_n3##y,z,c), I[233] = (T)(img)(_p4##x,_n3##y,z,c), I[234] = (T)(img)(_p3##x,_n3##y,z,c), I[235] = (T)(img)(_p2##x,_n3##y,z,c), I[236] = (T)(img)(_p1##x,_n3##y,z,c), I[237] = (T)(img)(x,_n3##y,z,c), I[238] = (T)(img)(_n1##x,_n3##y,z,c), I[239] = (T)(img)(_n2##x,_n3##y,z,c), I[240] = (T)(img)(_n3##x,_n3##y,z,c), I[241] = (T)(img)(_n4##x,_n3##y,z,c), I[242] = (T)(img)(_n5##x,_n3##y,z,c), I[243] = (T)(img)(_n6##x,_n3##y,z,c), I[244] = (T)(img)(_n7##x,_n3##y,z,c), I[245] = (T)(img)(_n8##x,_n3##y,z,c), I[246] = (T)(img)(_n9##x,_n3##y,z,c), \ - I[247] = (T)(img)(_p9##x,_n4##y,z,c), I[248] = (T)(img)(_p8##x,_n4##y,z,c), I[249] = (T)(img)(_p7##x,_n4##y,z,c), I[250] = (T)(img)(_p6##x,_n4##y,z,c), I[251] = (T)(img)(_p5##x,_n4##y,z,c), I[252] = (T)(img)(_p4##x,_n4##y,z,c), I[253] = (T)(img)(_p3##x,_n4##y,z,c), I[254] = (T)(img)(_p2##x,_n4##y,z,c), I[255] = (T)(img)(_p1##x,_n4##y,z,c), I[256] = (T)(img)(x,_n4##y,z,c), I[257] = (T)(img)(_n1##x,_n4##y,z,c), I[258] = (T)(img)(_n2##x,_n4##y,z,c), I[259] = (T)(img)(_n3##x,_n4##y,z,c), I[260] = (T)(img)(_n4##x,_n4##y,z,c), I[261] = (T)(img)(_n5##x,_n4##y,z,c), I[262] = (T)(img)(_n6##x,_n4##y,z,c), I[263] = (T)(img)(_n7##x,_n4##y,z,c), I[264] = (T)(img)(_n8##x,_n4##y,z,c), I[265] = (T)(img)(_n9##x,_n4##y,z,c), \ - I[266] = (T)(img)(_p9##x,_n5##y,z,c), I[267] = (T)(img)(_p8##x,_n5##y,z,c), I[268] = (T)(img)(_p7##x,_n5##y,z,c), I[269] = (T)(img)(_p6##x,_n5##y,z,c), I[270] = (T)(img)(_p5##x,_n5##y,z,c), I[271] = (T)(img)(_p4##x,_n5##y,z,c), I[272] = (T)(img)(_p3##x,_n5##y,z,c), I[273] = (T)(img)(_p2##x,_n5##y,z,c), I[274] = (T)(img)(_p1##x,_n5##y,z,c), I[275] = (T)(img)(x,_n5##y,z,c), I[276] = (T)(img)(_n1##x,_n5##y,z,c), I[277] = (T)(img)(_n2##x,_n5##y,z,c), I[278] = (T)(img)(_n3##x,_n5##y,z,c), I[279] = (T)(img)(_n4##x,_n5##y,z,c), I[280] = (T)(img)(_n5##x,_n5##y,z,c), I[281] = (T)(img)(_n6##x,_n5##y,z,c), I[282] = (T)(img)(_n7##x,_n5##y,z,c), I[283] = (T)(img)(_n8##x,_n5##y,z,c), I[284] = (T)(img)(_n9##x,_n5##y,z,c), \ - I[285] = (T)(img)(_p9##x,_n6##y,z,c), I[286] = (T)(img)(_p8##x,_n6##y,z,c), I[287] = (T)(img)(_p7##x,_n6##y,z,c), I[288] = (T)(img)(_p6##x,_n6##y,z,c), I[289] = (T)(img)(_p5##x,_n6##y,z,c), I[290] = (T)(img)(_p4##x,_n6##y,z,c), I[291] = (T)(img)(_p3##x,_n6##y,z,c), I[292] = (T)(img)(_p2##x,_n6##y,z,c), I[293] = (T)(img)(_p1##x,_n6##y,z,c), I[294] = (T)(img)(x,_n6##y,z,c), I[295] = (T)(img)(_n1##x,_n6##y,z,c), I[296] = (T)(img)(_n2##x,_n6##y,z,c), I[297] = (T)(img)(_n3##x,_n6##y,z,c), I[298] = (T)(img)(_n4##x,_n6##y,z,c), I[299] = (T)(img)(_n5##x,_n6##y,z,c), I[300] = (T)(img)(_n6##x,_n6##y,z,c), I[301] = (T)(img)(_n7##x,_n6##y,z,c), I[302] = (T)(img)(_n8##x,_n6##y,z,c), I[303] = (T)(img)(_n9##x,_n6##y,z,c), \ - I[304] = (T)(img)(_p9##x,_n7##y,z,c), I[305] = (T)(img)(_p8##x,_n7##y,z,c), I[306] = (T)(img)(_p7##x,_n7##y,z,c), I[307] = (T)(img)(_p6##x,_n7##y,z,c), I[308] = (T)(img)(_p5##x,_n7##y,z,c), I[309] = (T)(img)(_p4##x,_n7##y,z,c), I[310] = (T)(img)(_p3##x,_n7##y,z,c), I[311] = (T)(img)(_p2##x,_n7##y,z,c), I[312] = (T)(img)(_p1##x,_n7##y,z,c), I[313] = (T)(img)(x,_n7##y,z,c), I[314] = (T)(img)(_n1##x,_n7##y,z,c), I[315] = (T)(img)(_n2##x,_n7##y,z,c), I[316] = (T)(img)(_n3##x,_n7##y,z,c), I[317] = (T)(img)(_n4##x,_n7##y,z,c), I[318] = (T)(img)(_n5##x,_n7##y,z,c), I[319] = (T)(img)(_n6##x,_n7##y,z,c), I[320] = (T)(img)(_n7##x,_n7##y,z,c), I[321] = (T)(img)(_n8##x,_n7##y,z,c), I[322] = (T)(img)(_n9##x,_n7##y,z,c), \ - I[323] = (T)(img)(_p9##x,_n8##y,z,c), I[324] = (T)(img)(_p8##x,_n8##y,z,c), I[325] = (T)(img)(_p7##x,_n8##y,z,c), I[326] = (T)(img)(_p6##x,_n8##y,z,c), I[327] = (T)(img)(_p5##x,_n8##y,z,c), I[328] = (T)(img)(_p4##x,_n8##y,z,c), I[329] = (T)(img)(_p3##x,_n8##y,z,c), I[330] = (T)(img)(_p2##x,_n8##y,z,c), I[331] = (T)(img)(_p1##x,_n8##y,z,c), I[332] = (T)(img)(x,_n8##y,z,c), I[333] = (T)(img)(_n1##x,_n8##y,z,c), I[334] = (T)(img)(_n2##x,_n8##y,z,c), I[335] = (T)(img)(_n3##x,_n8##y,z,c), I[336] = (T)(img)(_n4##x,_n8##y,z,c), I[337] = (T)(img)(_n5##x,_n8##y,z,c), I[338] = (T)(img)(_n6##x,_n8##y,z,c), I[339] = (T)(img)(_n7##x,_n8##y,z,c), I[340] = (T)(img)(_n8##x,_n8##y,z,c), I[341] = (T)(img)(_n9##x,_n8##y,z,c), \ - I[342] = (T)(img)(_p9##x,_n9##y,z,c), I[343] = (T)(img)(_p8##x,_n9##y,z,c), I[344] = (T)(img)(_p7##x,_n9##y,z,c), I[345] = (T)(img)(_p6##x,_n9##y,z,c), I[346] = (T)(img)(_p5##x,_n9##y,z,c), I[347] = (T)(img)(_p4##x,_n9##y,z,c), I[348] = (T)(img)(_p3##x,_n9##y,z,c), I[349] = (T)(img)(_p2##x,_n9##y,z,c), I[350] = (T)(img)(_p1##x,_n9##y,z,c), I[351] = (T)(img)(x,_n9##y,z,c), I[352] = (T)(img)(_n1##x,_n9##y,z,c), I[353] = (T)(img)(_n2##x,_n9##y,z,c), I[354] = (T)(img)(_n3##x,_n9##y,z,c), I[355] = (T)(img)(_n4##x,_n9##y,z,c), I[356] = (T)(img)(_n5##x,_n9##y,z,c), I[357] = (T)(img)(_n6##x,_n9##y,z,c), I[358] = (T)(img)(_n7##x,_n9##y,z,c), I[359] = (T)(img)(_n8##x,_n9##y,z,c), I[360] = (T)(img)(_n9##x,_n9##y,z,c); - -// Define 20x20 loop macros -//------------------------- -#define cimg_for20(bound,i) for (int i = 0, \ - _p9##i = 0, _p8##i = 0, _p7##i = 0, _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6, \ - _n7##i = 7>=(int)(bound)?(int)(bound) - 1:7, \ - _n8##i = 8>=(int)(bound)?(int)(bound) - 1:8, \ - _n9##i = 9>=(int)(bound)?(int)(bound) - 1:9, \ - _n10##i = 10>=(int)(bound)?(int)(bound) - 1:10; \ - _n10##i<(int)(bound) || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i) - -#define cimg_for20X(img,x) cimg_for20((img)._width,x) -#define cimg_for20Y(img,y) cimg_for20((img)._height,y) -#define cimg_for20Z(img,z) cimg_for20((img)._depth,z) -#define cimg_for20C(img,c) cimg_for20((img)._spectrum,c) -#define cimg_for20XY(img,x,y) cimg_for20Y(img,y) cimg_for20X(img,x) -#define cimg_for20XZ(img,x,z) cimg_for20Z(img,z) cimg_for20X(img,x) -#define cimg_for20XC(img,x,c) cimg_for20C(img,c) cimg_for20X(img,x) -#define cimg_for20YZ(img,y,z) cimg_for20Z(img,z) cimg_for20Y(img,y) -#define cimg_for20YC(img,y,c) cimg_for20C(img,c) cimg_for20Y(img,y) -#define cimg_for20ZC(img,z,c) cimg_for20C(img,c) cimg_for20Z(img,z) -#define cimg_for20XYZ(img,x,y,z) cimg_for20Z(img,z) cimg_for20XY(img,x,y) -#define cimg_for20XZC(img,x,z,c) cimg_for20C(img,c) cimg_for20XZ(img,x,z) -#define cimg_for20YZC(img,y,z,c) cimg_for20C(img,c) cimg_for20YZ(img,y,z) -#define cimg_for20XYZC(img,x,y,z,c) cimg_for20C(img,c) cimg_for20XYZ(img,x,y,z) - -#define cimg_for_in20(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p9##i = i - 9<0?0:i - 9, \ - _p8##i = i - 8<0?0:i - 8, \ - _p7##i = i - 7<0?0:i - 7, \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6, \ - _n7##i = i + 7>=(int)(bound)?(int)(bound) - 1:i + 7, \ - _n8##i = i + 8>=(int)(bound)?(int)(bound) - 1:i + 8, \ - _n9##i = i + 9>=(int)(bound)?(int)(bound) - 1:i + 9, \ - _n10##i = i + 10>=(int)(bound)?(int)(bound) - 1:i + 10; \ - i<=(int)(i1) && (_n10##i<(int)(bound) || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i) - -#define cimg_for_in20X(img,x0,x1,x) cimg_for_in20((img)._width,x0,x1,x) -#define cimg_for_in20Y(img,y0,y1,y) cimg_for_in20((img)._height,y0,y1,y) -#define cimg_for_in20Z(img,z0,z1,z) cimg_for_in20((img)._depth,z0,z1,z) -#define cimg_for_in20C(img,c0,c1,c) cimg_for_in20((img)._spectrum,c0,c1,c) -#define cimg_for_in20XY(img,x0,y0,x1,y1,x,y) cimg_for_in20Y(img,y0,y1,y) cimg_for_in20X(img,x0,x1,x) -#define cimg_for_in20XZ(img,x0,z0,x1,z1,x,z) cimg_for_in20Z(img,z0,z1,z) cimg_for_in20X(img,x0,x1,x) -#define cimg_for_in20XC(img,x0,c0,x1,c1,x,c) cimg_for_in20C(img,c0,c1,c) cimg_for_in20X(img,x0,x1,x) -#define cimg_for_in20YZ(img,y0,z0,y1,z1,y,z) cimg_for_in20Z(img,z0,z1,z) cimg_for_in20Y(img,y0,y1,y) -#define cimg_for_in20YC(img,y0,c0,y1,c1,y,c) cimg_for_in20C(img,c0,c1,c) cimg_for_in20Y(img,y0,y1,y) -#define cimg_for_in20ZC(img,z0,c0,z1,c1,z,c) cimg_for_in20C(img,c0,c1,c) cimg_for_in20Z(img,z0,z1,z) -#define cimg_for_in20XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in20Z(img,z0,z1,z) cimg_for_in20XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in20XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in20C(img,c0,c1,c) cimg_for_in20XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in20YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in20C(img,c0,c1,c) cimg_for_in20YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in20XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in20C(img,c0,c1,c) cimg_for_in20XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for20x20(img,x,y,z,c,I,T) \ - cimg_for20((img)._height,y) for (int x = 0, \ - _p9##x = 0, _p8##x = 0, _p7##x = 0, _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = 6>=((img)._width)?(img).width() - 1:6, \ - _n7##x = 7>=((img)._width)?(img).width() - 1:7, \ - _n8##x = 8>=((img)._width)?(img).width() - 1:8, \ - _n9##x = 9>=((img)._width)?(img).width() - 1:9, \ - _n10##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = I[7] = I[8] = I[9] = (T)(img)(0,_p9##y,z,c)), \ - (I[20] = I[21] = I[22] = I[23] = I[24] = I[25] = I[26] = I[27] = I[28] = I[29] = (T)(img)(0,_p8##y,z,c)), \ - (I[40] = I[41] = I[42] = I[43] = I[44] = I[45] = I[46] = I[47] = I[48] = I[49] = (T)(img)(0,_p7##y,z,c)), \ - (I[60] = I[61] = I[62] = I[63] = I[64] = I[65] = I[66] = I[67] = I[68] = I[69] = (T)(img)(0,_p6##y,z,c)), \ - (I[80] = I[81] = I[82] = I[83] = I[84] = I[85] = I[86] = I[87] = I[88] = I[89] = (T)(img)(0,_p5##y,z,c)), \ - (I[100] = I[101] = I[102] = I[103] = I[104] = I[105] = I[106] = I[107] = I[108] = I[109] = (T)(img)(0,_p4##y,z,c)), \ - (I[120] = I[121] = I[122] = I[123] = I[124] = I[125] = I[126] = I[127] = I[128] = I[129] = (T)(img)(0,_p3##y,z,c)), \ - (I[140] = I[141] = I[142] = I[143] = I[144] = I[145] = I[146] = I[147] = I[148] = I[149] = (T)(img)(0,_p2##y,z,c)), \ - (I[160] = I[161] = I[162] = I[163] = I[164] = I[165] = I[166] = I[167] = I[168] = I[169] = (T)(img)(0,_p1##y,z,c)), \ - (I[180] = I[181] = I[182] = I[183] = I[184] = I[185] = I[186] = I[187] = I[188] = I[189] = (T)(img)(0,y,z,c)), \ - (I[200] = I[201] = I[202] = I[203] = I[204] = I[205] = I[206] = I[207] = I[208] = I[209] = (T)(img)(0,_n1##y,z,c)), \ - (I[220] = I[221] = I[222] = I[223] = I[224] = I[225] = I[226] = I[227] = I[228] = I[229] = (T)(img)(0,_n2##y,z,c)), \ - (I[240] = I[241] = I[242] = I[243] = I[244] = I[245] = I[246] = I[247] = I[248] = I[249] = (T)(img)(0,_n3##y,z,c)), \ - (I[260] = I[261] = I[262] = I[263] = I[264] = I[265] = I[266] = I[267] = I[268] = I[269] = (T)(img)(0,_n4##y,z,c)), \ - (I[280] = I[281] = I[282] = I[283] = I[284] = I[285] = I[286] = I[287] = I[288] = I[289] = (T)(img)(0,_n5##y,z,c)), \ - (I[300] = I[301] = I[302] = I[303] = I[304] = I[305] = I[306] = I[307] = I[308] = I[309] = (T)(img)(0,_n6##y,z,c)), \ - (I[320] = I[321] = I[322] = I[323] = I[324] = I[325] = I[326] = I[327] = I[328] = I[329] = (T)(img)(0,_n7##y,z,c)), \ - (I[340] = I[341] = I[342] = I[343] = I[344] = I[345] = I[346] = I[347] = I[348] = I[349] = (T)(img)(0,_n8##y,z,c)), \ - (I[360] = I[361] = I[362] = I[363] = I[364] = I[365] = I[366] = I[367] = I[368] = I[369] = (T)(img)(0,_n9##y,z,c)), \ - (I[380] = I[381] = I[382] = I[383] = I[384] = I[385] = I[386] = I[387] = I[388] = I[389] = (T)(img)(0,_n10##y,z,c)), \ - (I[10] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[30] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[50] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[70] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[90] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[110] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[130] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[150] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[170] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[190] = (T)(img)(_n1##x,y,z,c)), \ - (I[210] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[230] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[250] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[270] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[290] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[310] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[330] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[350] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[370] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[390] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[11] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[31] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[51] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[71] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[91] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[111] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[131] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[151] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[171] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[191] = (T)(img)(_n2##x,y,z,c)), \ - (I[211] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[231] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[251] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[271] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[291] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[311] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[331] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[351] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[371] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[391] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[12] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[32] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[52] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[72] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[92] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[112] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[132] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[152] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[172] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[192] = (T)(img)(_n3##x,y,z,c)), \ - (I[212] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[232] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[252] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[272] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[292] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[312] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[332] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[352] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[372] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[392] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[13] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[33] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[53] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[73] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[93] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[113] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[133] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[153] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[173] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[193] = (T)(img)(_n4##x,y,z,c)), \ - (I[213] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[233] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[253] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[273] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[293] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[313] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[333] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[353] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[373] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[393] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[14] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[34] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[54] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[74] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[94] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[114] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[134] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[154] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[174] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[194] = (T)(img)(_n5##x,y,z,c)), \ - (I[214] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[234] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[254] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[274] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[294] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[314] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[334] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[354] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[374] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[394] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[15] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[35] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[55] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[75] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[95] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[115] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[135] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[155] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[175] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[195] = (T)(img)(_n6##x,y,z,c)), \ - (I[215] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[235] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[255] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[275] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[295] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[315] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[335] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[355] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[375] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[395] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[16] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[36] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[56] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[76] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[96] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[116] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[136] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[156] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[176] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[196] = (T)(img)(_n7##x,y,z,c)), \ - (I[216] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[236] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[256] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[276] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[296] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[316] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[336] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[356] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[376] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[396] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[17] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[37] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[57] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[77] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[97] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[117] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[137] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[157] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[177] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[197] = (T)(img)(_n8##x,y,z,c)), \ - (I[217] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[237] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[257] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[277] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[297] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[317] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[337] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[357] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[377] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[397] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[18] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[38] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[58] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[78] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[98] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[118] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[138] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[158] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[178] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[198] = (T)(img)(_n9##x,y,z,c)), \ - (I[218] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[238] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[258] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[278] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[298] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[318] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[338] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[358] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[378] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[398] = (T)(img)(_n9##x,_n10##y,z,c)), \ - 10>=((img)._width)?(img).width() - 1:10); \ - (_n10##x<(img).width() && ( \ - (I[19] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[39] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[59] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[79] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[99] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[119] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[139] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[159] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[179] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[199] = (T)(img)(_n10##x,y,z,c)), \ - (I[219] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[239] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[259] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[279] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[299] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[319] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[339] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[359] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[379] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[399] = (T)(img)(_n10##x,_n10##y,z,c)),1)) || \ - _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], \ - I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], \ - I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], \ - I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], \ - I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], \ - I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], \ - I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], \ - I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], \ - I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], \ - I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], \ - I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], \ - I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], \ - I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], \ - I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], \ - I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], \ - I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], \ - I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], \ - I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], \ - I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], \ - I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], \ - _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x) - -#define cimg_for_in20x20(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in20((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p9##x = x - 9<0?0:x - 9, \ - _p8##x = x - 8<0?0:x - 8, \ - _p7##x = x - 7<0?0:x - 7, \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = x + 6>=(img).width()?(img).width() - 1:x + 6, \ - _n7##x = x + 7>=(img).width()?(img).width() - 1:x + 7, \ - _n8##x = x + 8>=(img).width()?(img).width() - 1:x + 8, \ - _n9##x = x + 9>=(img).width()?(img).width() - 1:x + 9, \ - _n10##x = (int)( \ - (I[0] = (T)(img)(_p9##x,_p9##y,z,c)), \ - (I[20] = (T)(img)(_p9##x,_p8##y,z,c)), \ - (I[40] = (T)(img)(_p9##x,_p7##y,z,c)), \ - (I[60] = (T)(img)(_p9##x,_p6##y,z,c)), \ - (I[80] = (T)(img)(_p9##x,_p5##y,z,c)), \ - (I[100] = (T)(img)(_p9##x,_p4##y,z,c)), \ - (I[120] = (T)(img)(_p9##x,_p3##y,z,c)), \ - (I[140] = (T)(img)(_p9##x,_p2##y,z,c)), \ - (I[160] = (T)(img)(_p9##x,_p1##y,z,c)), \ - (I[180] = (T)(img)(_p9##x,y,z,c)), \ - (I[200] = (T)(img)(_p9##x,_n1##y,z,c)), \ - (I[220] = (T)(img)(_p9##x,_n2##y,z,c)), \ - (I[240] = (T)(img)(_p9##x,_n3##y,z,c)), \ - (I[260] = (T)(img)(_p9##x,_n4##y,z,c)), \ - (I[280] = (T)(img)(_p9##x,_n5##y,z,c)), \ - (I[300] = (T)(img)(_p9##x,_n6##y,z,c)), \ - (I[320] = (T)(img)(_p9##x,_n7##y,z,c)), \ - (I[340] = (T)(img)(_p9##x,_n8##y,z,c)), \ - (I[360] = (T)(img)(_p9##x,_n9##y,z,c)), \ - (I[380] = (T)(img)(_p9##x,_n10##y,z,c)), \ - (I[1] = (T)(img)(_p8##x,_p9##y,z,c)), \ - (I[21] = (T)(img)(_p8##x,_p8##y,z,c)), \ - (I[41] = (T)(img)(_p8##x,_p7##y,z,c)), \ - (I[61] = (T)(img)(_p8##x,_p6##y,z,c)), \ - (I[81] = (T)(img)(_p8##x,_p5##y,z,c)), \ - (I[101] = (T)(img)(_p8##x,_p4##y,z,c)), \ - (I[121] = (T)(img)(_p8##x,_p3##y,z,c)), \ - (I[141] = (T)(img)(_p8##x,_p2##y,z,c)), \ - (I[161] = (T)(img)(_p8##x,_p1##y,z,c)), \ - (I[181] = (T)(img)(_p8##x,y,z,c)), \ - (I[201] = (T)(img)(_p8##x,_n1##y,z,c)), \ - (I[221] = (T)(img)(_p8##x,_n2##y,z,c)), \ - (I[241] = (T)(img)(_p8##x,_n3##y,z,c)), \ - (I[261] = (T)(img)(_p8##x,_n4##y,z,c)), \ - (I[281] = (T)(img)(_p8##x,_n5##y,z,c)), \ - (I[301] = (T)(img)(_p8##x,_n6##y,z,c)), \ - (I[321] = (T)(img)(_p8##x,_n7##y,z,c)), \ - (I[341] = (T)(img)(_p8##x,_n8##y,z,c)), \ - (I[361] = (T)(img)(_p8##x,_n9##y,z,c)), \ - (I[381] = (T)(img)(_p8##x,_n10##y,z,c)), \ - (I[2] = (T)(img)(_p7##x,_p9##y,z,c)), \ - (I[22] = (T)(img)(_p7##x,_p8##y,z,c)), \ - (I[42] = (T)(img)(_p7##x,_p7##y,z,c)), \ - (I[62] = (T)(img)(_p7##x,_p6##y,z,c)), \ - (I[82] = (T)(img)(_p7##x,_p5##y,z,c)), \ - (I[102] = (T)(img)(_p7##x,_p4##y,z,c)), \ - (I[122] = (T)(img)(_p7##x,_p3##y,z,c)), \ - (I[142] = (T)(img)(_p7##x,_p2##y,z,c)), \ - (I[162] = (T)(img)(_p7##x,_p1##y,z,c)), \ - (I[182] = (T)(img)(_p7##x,y,z,c)), \ - (I[202] = (T)(img)(_p7##x,_n1##y,z,c)), \ - (I[222] = (T)(img)(_p7##x,_n2##y,z,c)), \ - (I[242] = (T)(img)(_p7##x,_n3##y,z,c)), \ - (I[262] = (T)(img)(_p7##x,_n4##y,z,c)), \ - (I[282] = (T)(img)(_p7##x,_n5##y,z,c)), \ - (I[302] = (T)(img)(_p7##x,_n6##y,z,c)), \ - (I[322] = (T)(img)(_p7##x,_n7##y,z,c)), \ - (I[342] = (T)(img)(_p7##x,_n8##y,z,c)), \ - (I[362] = (T)(img)(_p7##x,_n9##y,z,c)), \ - (I[382] = (T)(img)(_p7##x,_n10##y,z,c)), \ - (I[3] = (T)(img)(_p6##x,_p9##y,z,c)), \ - (I[23] = (T)(img)(_p6##x,_p8##y,z,c)), \ - (I[43] = (T)(img)(_p6##x,_p7##y,z,c)), \ - (I[63] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[83] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[103] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[123] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[143] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[163] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[183] = (T)(img)(_p6##x,y,z,c)), \ - (I[203] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[223] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[243] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[263] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[283] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[303] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[323] = (T)(img)(_p6##x,_n7##y,z,c)), \ - (I[343] = (T)(img)(_p6##x,_n8##y,z,c)), \ - (I[363] = (T)(img)(_p6##x,_n9##y,z,c)), \ - (I[383] = (T)(img)(_p6##x,_n10##y,z,c)), \ - (I[4] = (T)(img)(_p5##x,_p9##y,z,c)), \ - (I[24] = (T)(img)(_p5##x,_p8##y,z,c)), \ - (I[44] = (T)(img)(_p5##x,_p7##y,z,c)), \ - (I[64] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[84] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[104] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[124] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[144] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[164] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[184] = (T)(img)(_p5##x,y,z,c)), \ - (I[204] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[224] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[244] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[264] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[284] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[304] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[324] = (T)(img)(_p5##x,_n7##y,z,c)), \ - (I[344] = (T)(img)(_p5##x,_n8##y,z,c)), \ - (I[364] = (T)(img)(_p5##x,_n9##y,z,c)), \ - (I[384] = (T)(img)(_p5##x,_n10##y,z,c)), \ - (I[5] = (T)(img)(_p4##x,_p9##y,z,c)), \ - (I[25] = (T)(img)(_p4##x,_p8##y,z,c)), \ - (I[45] = (T)(img)(_p4##x,_p7##y,z,c)), \ - (I[65] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[85] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[105] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[125] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[145] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[165] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[185] = (T)(img)(_p4##x,y,z,c)), \ - (I[205] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[225] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[245] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[265] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[285] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[305] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[325] = (T)(img)(_p4##x,_n7##y,z,c)), \ - (I[345] = (T)(img)(_p4##x,_n8##y,z,c)), \ - (I[365] = (T)(img)(_p4##x,_n9##y,z,c)), \ - (I[385] = (T)(img)(_p4##x,_n10##y,z,c)), \ - (I[6] = (T)(img)(_p3##x,_p9##y,z,c)), \ - (I[26] = (T)(img)(_p3##x,_p8##y,z,c)), \ - (I[46] = (T)(img)(_p3##x,_p7##y,z,c)), \ - (I[66] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[86] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[106] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[126] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[146] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[166] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[186] = (T)(img)(_p3##x,y,z,c)), \ - (I[206] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[226] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[246] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[266] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[286] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[306] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[326] = (T)(img)(_p3##x,_n7##y,z,c)), \ - (I[346] = (T)(img)(_p3##x,_n8##y,z,c)), \ - (I[366] = (T)(img)(_p3##x,_n9##y,z,c)), \ - (I[386] = (T)(img)(_p3##x,_n10##y,z,c)), \ - (I[7] = (T)(img)(_p2##x,_p9##y,z,c)), \ - (I[27] = (T)(img)(_p2##x,_p8##y,z,c)), \ - (I[47] = (T)(img)(_p2##x,_p7##y,z,c)), \ - (I[67] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[87] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[107] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[127] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[147] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[167] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[187] = (T)(img)(_p2##x,y,z,c)), \ - (I[207] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[227] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[247] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[267] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[287] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[307] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[327] = (T)(img)(_p2##x,_n7##y,z,c)), \ - (I[347] = (T)(img)(_p2##x,_n8##y,z,c)), \ - (I[367] = (T)(img)(_p2##x,_n9##y,z,c)), \ - (I[387] = (T)(img)(_p2##x,_n10##y,z,c)), \ - (I[8] = (T)(img)(_p1##x,_p9##y,z,c)), \ - (I[28] = (T)(img)(_p1##x,_p8##y,z,c)), \ - (I[48] = (T)(img)(_p1##x,_p7##y,z,c)), \ - (I[68] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[88] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[108] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[128] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[148] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[168] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[188] = (T)(img)(_p1##x,y,z,c)), \ - (I[208] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[228] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[248] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[268] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[288] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[308] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[328] = (T)(img)(_p1##x,_n7##y,z,c)), \ - (I[348] = (T)(img)(_p1##x,_n8##y,z,c)), \ - (I[368] = (T)(img)(_p1##x,_n9##y,z,c)), \ - (I[388] = (T)(img)(_p1##x,_n10##y,z,c)), \ - (I[9] = (T)(img)(x,_p9##y,z,c)), \ - (I[29] = (T)(img)(x,_p8##y,z,c)), \ - (I[49] = (T)(img)(x,_p7##y,z,c)), \ - (I[69] = (T)(img)(x,_p6##y,z,c)), \ - (I[89] = (T)(img)(x,_p5##y,z,c)), \ - (I[109] = (T)(img)(x,_p4##y,z,c)), \ - (I[129] = (T)(img)(x,_p3##y,z,c)), \ - (I[149] = (T)(img)(x,_p2##y,z,c)), \ - (I[169] = (T)(img)(x,_p1##y,z,c)), \ - (I[189] = (T)(img)(x,y,z,c)), \ - (I[209] = (T)(img)(x,_n1##y,z,c)), \ - (I[229] = (T)(img)(x,_n2##y,z,c)), \ - (I[249] = (T)(img)(x,_n3##y,z,c)), \ - (I[269] = (T)(img)(x,_n4##y,z,c)), \ - (I[289] = (T)(img)(x,_n5##y,z,c)), \ - (I[309] = (T)(img)(x,_n6##y,z,c)), \ - (I[329] = (T)(img)(x,_n7##y,z,c)), \ - (I[349] = (T)(img)(x,_n8##y,z,c)), \ - (I[369] = (T)(img)(x,_n9##y,z,c)), \ - (I[389] = (T)(img)(x,_n10##y,z,c)), \ - (I[10] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[30] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[50] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[70] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[90] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[110] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[130] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[150] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[170] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[190] = (T)(img)(_n1##x,y,z,c)), \ - (I[210] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[230] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[250] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[270] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[290] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[310] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[330] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[350] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[370] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[390] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[11] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[31] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[51] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[71] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[91] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[111] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[131] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[151] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[171] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[191] = (T)(img)(_n2##x,y,z,c)), \ - (I[211] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[231] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[251] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[271] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[291] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[311] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[331] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[351] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[371] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[391] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[12] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[32] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[52] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[72] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[92] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[112] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[132] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[152] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[172] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[192] = (T)(img)(_n3##x,y,z,c)), \ - (I[212] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[232] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[252] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[272] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[292] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[312] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[332] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[352] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[372] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[392] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[13] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[33] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[53] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[73] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[93] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[113] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[133] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[153] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[173] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[193] = (T)(img)(_n4##x,y,z,c)), \ - (I[213] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[233] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[253] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[273] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[293] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[313] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[333] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[353] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[373] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[393] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[14] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[34] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[54] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[74] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[94] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[114] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[134] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[154] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[174] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[194] = (T)(img)(_n5##x,y,z,c)), \ - (I[214] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[234] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[254] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[274] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[294] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[314] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[334] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[354] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[374] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[394] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[15] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[35] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[55] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[75] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[95] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[115] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[135] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[155] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[175] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[195] = (T)(img)(_n6##x,y,z,c)), \ - (I[215] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[235] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[255] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[275] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[295] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[315] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[335] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[355] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[375] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[395] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[16] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[36] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[56] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[76] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[96] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[116] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[136] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[156] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[176] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[196] = (T)(img)(_n7##x,y,z,c)), \ - (I[216] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[236] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[256] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[276] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[296] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[316] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[336] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[356] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[376] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[396] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[17] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[37] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[57] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[77] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[97] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[117] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[137] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[157] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[177] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[197] = (T)(img)(_n8##x,y,z,c)), \ - (I[217] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[237] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[257] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[277] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[297] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[317] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[337] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[357] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[377] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[397] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[18] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[38] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[58] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[78] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[98] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[118] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[138] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[158] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[178] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[198] = (T)(img)(_n9##x,y,z,c)), \ - (I[218] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[238] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[258] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[278] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[298] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[318] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[338] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[358] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[378] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[398] = (T)(img)(_n9##x,_n10##y,z,c)), \ - x + 10>=(img).width()?(img).width() - 1:x + 10); \ - x<=(int)(x1) && ((_n10##x<(img).width() && ( \ - (I[19] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[39] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[59] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[79] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[99] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[119] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[139] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[159] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[179] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[199] = (T)(img)(_n10##x,y,z,c)), \ - (I[219] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[239] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[259] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[279] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[299] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[319] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[339] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[359] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[379] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[399] = (T)(img)(_n10##x,_n10##y,z,c)),1)) || \ - _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], \ - I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], \ - I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], \ - I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], \ - I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], \ - I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], \ - I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], \ - I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], \ - I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], \ - I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], \ - I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], \ - I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], \ - I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], \ - I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], \ - I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], \ - I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], \ - I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], \ - I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], \ - I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], \ - I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], \ - _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x) - -#define cimg_get20x20(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p9##x,_p9##y,z,c), I[1] = (T)(img)(_p8##x,_p9##y,z,c), I[2] = (T)(img)(_p7##x,_p9##y,z,c), I[3] = (T)(img)(_p6##x,_p9##y,z,c), I[4] = (T)(img)(_p5##x,_p9##y,z,c), I[5] = (T)(img)(_p4##x,_p9##y,z,c), I[6] = (T)(img)(_p3##x,_p9##y,z,c), I[7] = (T)(img)(_p2##x,_p9##y,z,c), I[8] = (T)(img)(_p1##x,_p9##y,z,c), I[9] = (T)(img)(x,_p9##y,z,c), I[10] = (T)(img)(_n1##x,_p9##y,z,c), I[11] = (T)(img)(_n2##x,_p9##y,z,c), I[12] = (T)(img)(_n3##x,_p9##y,z,c), I[13] = (T)(img)(_n4##x,_p9##y,z,c), I[14] = (T)(img)(_n5##x,_p9##y,z,c), I[15] = (T)(img)(_n6##x,_p9##y,z,c), I[16] = (T)(img)(_n7##x,_p9##y,z,c), I[17] = (T)(img)(_n8##x,_p9##y,z,c), I[18] = (T)(img)(_n9##x,_p9##y,z,c), I[19] = (T)(img)(_n10##x,_p9##y,z,c), \ - I[20] = (T)(img)(_p9##x,_p8##y,z,c), I[21] = (T)(img)(_p8##x,_p8##y,z,c), I[22] = (T)(img)(_p7##x,_p8##y,z,c), I[23] = (T)(img)(_p6##x,_p8##y,z,c), I[24] = (T)(img)(_p5##x,_p8##y,z,c), I[25] = (T)(img)(_p4##x,_p8##y,z,c), I[26] = (T)(img)(_p3##x,_p8##y,z,c), I[27] = (T)(img)(_p2##x,_p8##y,z,c), I[28] = (T)(img)(_p1##x,_p8##y,z,c), I[29] = (T)(img)(x,_p8##y,z,c), I[30] = (T)(img)(_n1##x,_p8##y,z,c), I[31] = (T)(img)(_n2##x,_p8##y,z,c), I[32] = (T)(img)(_n3##x,_p8##y,z,c), I[33] = (T)(img)(_n4##x,_p8##y,z,c), I[34] = (T)(img)(_n5##x,_p8##y,z,c), I[35] = (T)(img)(_n6##x,_p8##y,z,c), I[36] = (T)(img)(_n7##x,_p8##y,z,c), I[37] = (T)(img)(_n8##x,_p8##y,z,c), I[38] = (T)(img)(_n9##x,_p8##y,z,c), I[39] = (T)(img)(_n10##x,_p8##y,z,c), \ - I[40] = (T)(img)(_p9##x,_p7##y,z,c), I[41] = (T)(img)(_p8##x,_p7##y,z,c), I[42] = (T)(img)(_p7##x,_p7##y,z,c), I[43] = (T)(img)(_p6##x,_p7##y,z,c), I[44] = (T)(img)(_p5##x,_p7##y,z,c), I[45] = (T)(img)(_p4##x,_p7##y,z,c), I[46] = (T)(img)(_p3##x,_p7##y,z,c), I[47] = (T)(img)(_p2##x,_p7##y,z,c), I[48] = (T)(img)(_p1##x,_p7##y,z,c), I[49] = (T)(img)(x,_p7##y,z,c), I[50] = (T)(img)(_n1##x,_p7##y,z,c), I[51] = (T)(img)(_n2##x,_p7##y,z,c), I[52] = (T)(img)(_n3##x,_p7##y,z,c), I[53] = (T)(img)(_n4##x,_p7##y,z,c), I[54] = (T)(img)(_n5##x,_p7##y,z,c), I[55] = (T)(img)(_n6##x,_p7##y,z,c), I[56] = (T)(img)(_n7##x,_p7##y,z,c), I[57] = (T)(img)(_n8##x,_p7##y,z,c), I[58] = (T)(img)(_n9##x,_p7##y,z,c), I[59] = (T)(img)(_n10##x,_p7##y,z,c), \ - I[60] = (T)(img)(_p9##x,_p6##y,z,c), I[61] = (T)(img)(_p8##x,_p6##y,z,c), I[62] = (T)(img)(_p7##x,_p6##y,z,c), I[63] = (T)(img)(_p6##x,_p6##y,z,c), I[64] = (T)(img)(_p5##x,_p6##y,z,c), I[65] = (T)(img)(_p4##x,_p6##y,z,c), I[66] = (T)(img)(_p3##x,_p6##y,z,c), I[67] = (T)(img)(_p2##x,_p6##y,z,c), I[68] = (T)(img)(_p1##x,_p6##y,z,c), I[69] = (T)(img)(x,_p6##y,z,c), I[70] = (T)(img)(_n1##x,_p6##y,z,c), I[71] = (T)(img)(_n2##x,_p6##y,z,c), I[72] = (T)(img)(_n3##x,_p6##y,z,c), I[73] = (T)(img)(_n4##x,_p6##y,z,c), I[74] = (T)(img)(_n5##x,_p6##y,z,c), I[75] = (T)(img)(_n6##x,_p6##y,z,c), I[76] = (T)(img)(_n7##x,_p6##y,z,c), I[77] = (T)(img)(_n8##x,_p6##y,z,c), I[78] = (T)(img)(_n9##x,_p6##y,z,c), I[79] = (T)(img)(_n10##x,_p6##y,z,c), \ - I[80] = (T)(img)(_p9##x,_p5##y,z,c), I[81] = (T)(img)(_p8##x,_p5##y,z,c), I[82] = (T)(img)(_p7##x,_p5##y,z,c), I[83] = (T)(img)(_p6##x,_p5##y,z,c), I[84] = (T)(img)(_p5##x,_p5##y,z,c), I[85] = (T)(img)(_p4##x,_p5##y,z,c), I[86] = (T)(img)(_p3##x,_p5##y,z,c), I[87] = (T)(img)(_p2##x,_p5##y,z,c), I[88] = (T)(img)(_p1##x,_p5##y,z,c), I[89] = (T)(img)(x,_p5##y,z,c), I[90] = (T)(img)(_n1##x,_p5##y,z,c), I[91] = (T)(img)(_n2##x,_p5##y,z,c), I[92] = (T)(img)(_n3##x,_p5##y,z,c), I[93] = (T)(img)(_n4##x,_p5##y,z,c), I[94] = (T)(img)(_n5##x,_p5##y,z,c), I[95] = (T)(img)(_n6##x,_p5##y,z,c), I[96] = (T)(img)(_n7##x,_p5##y,z,c), I[97] = (T)(img)(_n8##x,_p5##y,z,c), I[98] = (T)(img)(_n9##x,_p5##y,z,c), I[99] = (T)(img)(_n10##x,_p5##y,z,c), \ - I[100] = (T)(img)(_p9##x,_p4##y,z,c), I[101] = (T)(img)(_p8##x,_p4##y,z,c), I[102] = (T)(img)(_p7##x,_p4##y,z,c), I[103] = (T)(img)(_p6##x,_p4##y,z,c), I[104] = (T)(img)(_p5##x,_p4##y,z,c), I[105] = (T)(img)(_p4##x,_p4##y,z,c), I[106] = (T)(img)(_p3##x,_p4##y,z,c), I[107] = (T)(img)(_p2##x,_p4##y,z,c), I[108] = (T)(img)(_p1##x,_p4##y,z,c), I[109] = (T)(img)(x,_p4##y,z,c), I[110] = (T)(img)(_n1##x,_p4##y,z,c), I[111] = (T)(img)(_n2##x,_p4##y,z,c), I[112] = (T)(img)(_n3##x,_p4##y,z,c), I[113] = (T)(img)(_n4##x,_p4##y,z,c), I[114] = (T)(img)(_n5##x,_p4##y,z,c), I[115] = (T)(img)(_n6##x,_p4##y,z,c), I[116] = (T)(img)(_n7##x,_p4##y,z,c), I[117] = (T)(img)(_n8##x,_p4##y,z,c), I[118] = (T)(img)(_n9##x,_p4##y,z,c), I[119] = (T)(img)(_n10##x,_p4##y,z,c), \ - I[120] = (T)(img)(_p9##x,_p3##y,z,c), I[121] = (T)(img)(_p8##x,_p3##y,z,c), I[122] = (T)(img)(_p7##x,_p3##y,z,c), I[123] = (T)(img)(_p6##x,_p3##y,z,c), I[124] = (T)(img)(_p5##x,_p3##y,z,c), I[125] = (T)(img)(_p4##x,_p3##y,z,c), I[126] = (T)(img)(_p3##x,_p3##y,z,c), I[127] = (T)(img)(_p2##x,_p3##y,z,c), I[128] = (T)(img)(_p1##x,_p3##y,z,c), I[129] = (T)(img)(x,_p3##y,z,c), I[130] = (T)(img)(_n1##x,_p3##y,z,c), I[131] = (T)(img)(_n2##x,_p3##y,z,c), I[132] = (T)(img)(_n3##x,_p3##y,z,c), I[133] = (T)(img)(_n4##x,_p3##y,z,c), I[134] = (T)(img)(_n5##x,_p3##y,z,c), I[135] = (T)(img)(_n6##x,_p3##y,z,c), I[136] = (T)(img)(_n7##x,_p3##y,z,c), I[137] = (T)(img)(_n8##x,_p3##y,z,c), I[138] = (T)(img)(_n9##x,_p3##y,z,c), I[139] = (T)(img)(_n10##x,_p3##y,z,c), \ - I[140] = (T)(img)(_p9##x,_p2##y,z,c), I[141] = (T)(img)(_p8##x,_p2##y,z,c), I[142] = (T)(img)(_p7##x,_p2##y,z,c), I[143] = (T)(img)(_p6##x,_p2##y,z,c), I[144] = (T)(img)(_p5##x,_p2##y,z,c), I[145] = (T)(img)(_p4##x,_p2##y,z,c), I[146] = (T)(img)(_p3##x,_p2##y,z,c), I[147] = (T)(img)(_p2##x,_p2##y,z,c), I[148] = (T)(img)(_p1##x,_p2##y,z,c), I[149] = (T)(img)(x,_p2##y,z,c), I[150] = (T)(img)(_n1##x,_p2##y,z,c), I[151] = (T)(img)(_n2##x,_p2##y,z,c), I[152] = (T)(img)(_n3##x,_p2##y,z,c), I[153] = (T)(img)(_n4##x,_p2##y,z,c), I[154] = (T)(img)(_n5##x,_p2##y,z,c), I[155] = (T)(img)(_n6##x,_p2##y,z,c), I[156] = (T)(img)(_n7##x,_p2##y,z,c), I[157] = (T)(img)(_n8##x,_p2##y,z,c), I[158] = (T)(img)(_n9##x,_p2##y,z,c), I[159] = (T)(img)(_n10##x,_p2##y,z,c), \ - I[160] = (T)(img)(_p9##x,_p1##y,z,c), I[161] = (T)(img)(_p8##x,_p1##y,z,c), I[162] = (T)(img)(_p7##x,_p1##y,z,c), I[163] = (T)(img)(_p6##x,_p1##y,z,c), I[164] = (T)(img)(_p5##x,_p1##y,z,c), I[165] = (T)(img)(_p4##x,_p1##y,z,c), I[166] = (T)(img)(_p3##x,_p1##y,z,c), I[167] = (T)(img)(_p2##x,_p1##y,z,c), I[168] = (T)(img)(_p1##x,_p1##y,z,c), I[169] = (T)(img)(x,_p1##y,z,c), I[170] = (T)(img)(_n1##x,_p1##y,z,c), I[171] = (T)(img)(_n2##x,_p1##y,z,c), I[172] = (T)(img)(_n3##x,_p1##y,z,c), I[173] = (T)(img)(_n4##x,_p1##y,z,c), I[174] = (T)(img)(_n5##x,_p1##y,z,c), I[175] = (T)(img)(_n6##x,_p1##y,z,c), I[176] = (T)(img)(_n7##x,_p1##y,z,c), I[177] = (T)(img)(_n8##x,_p1##y,z,c), I[178] = (T)(img)(_n9##x,_p1##y,z,c), I[179] = (T)(img)(_n10##x,_p1##y,z,c), \ - I[180] = (T)(img)(_p9##x,y,z,c), I[181] = (T)(img)(_p8##x,y,z,c), I[182] = (T)(img)(_p7##x,y,z,c), I[183] = (T)(img)(_p6##x,y,z,c), I[184] = (T)(img)(_p5##x,y,z,c), I[185] = (T)(img)(_p4##x,y,z,c), I[186] = (T)(img)(_p3##x,y,z,c), I[187] = (T)(img)(_p2##x,y,z,c), I[188] = (T)(img)(_p1##x,y,z,c), I[189] = (T)(img)(x,y,z,c), I[190] = (T)(img)(_n1##x,y,z,c), I[191] = (T)(img)(_n2##x,y,z,c), I[192] = (T)(img)(_n3##x,y,z,c), I[193] = (T)(img)(_n4##x,y,z,c), I[194] = (T)(img)(_n5##x,y,z,c), I[195] = (T)(img)(_n6##x,y,z,c), I[196] = (T)(img)(_n7##x,y,z,c), I[197] = (T)(img)(_n8##x,y,z,c), I[198] = (T)(img)(_n9##x,y,z,c), I[199] = (T)(img)(_n10##x,y,z,c), \ - I[200] = (T)(img)(_p9##x,_n1##y,z,c), I[201] = (T)(img)(_p8##x,_n1##y,z,c), I[202] = (T)(img)(_p7##x,_n1##y,z,c), I[203] = (T)(img)(_p6##x,_n1##y,z,c), I[204] = (T)(img)(_p5##x,_n1##y,z,c), I[205] = (T)(img)(_p4##x,_n1##y,z,c), I[206] = (T)(img)(_p3##x,_n1##y,z,c), I[207] = (T)(img)(_p2##x,_n1##y,z,c), I[208] = (T)(img)(_p1##x,_n1##y,z,c), I[209] = (T)(img)(x,_n1##y,z,c), I[210] = (T)(img)(_n1##x,_n1##y,z,c), I[211] = (T)(img)(_n2##x,_n1##y,z,c), I[212] = (T)(img)(_n3##x,_n1##y,z,c), I[213] = (T)(img)(_n4##x,_n1##y,z,c), I[214] = (T)(img)(_n5##x,_n1##y,z,c), I[215] = (T)(img)(_n6##x,_n1##y,z,c), I[216] = (T)(img)(_n7##x,_n1##y,z,c), I[217] = (T)(img)(_n8##x,_n1##y,z,c), I[218] = (T)(img)(_n9##x,_n1##y,z,c), I[219] = (T)(img)(_n10##x,_n1##y,z,c), \ - I[220] = (T)(img)(_p9##x,_n2##y,z,c), I[221] = (T)(img)(_p8##x,_n2##y,z,c), I[222] = (T)(img)(_p7##x,_n2##y,z,c), I[223] = (T)(img)(_p6##x,_n2##y,z,c), I[224] = (T)(img)(_p5##x,_n2##y,z,c), I[225] = (T)(img)(_p4##x,_n2##y,z,c), I[226] = (T)(img)(_p3##x,_n2##y,z,c), I[227] = (T)(img)(_p2##x,_n2##y,z,c), I[228] = (T)(img)(_p1##x,_n2##y,z,c), I[229] = (T)(img)(x,_n2##y,z,c), I[230] = (T)(img)(_n1##x,_n2##y,z,c), I[231] = (T)(img)(_n2##x,_n2##y,z,c), I[232] = (T)(img)(_n3##x,_n2##y,z,c), I[233] = (T)(img)(_n4##x,_n2##y,z,c), I[234] = (T)(img)(_n5##x,_n2##y,z,c), I[235] = (T)(img)(_n6##x,_n2##y,z,c), I[236] = (T)(img)(_n7##x,_n2##y,z,c), I[237] = (T)(img)(_n8##x,_n2##y,z,c), I[238] = (T)(img)(_n9##x,_n2##y,z,c), I[239] = (T)(img)(_n10##x,_n2##y,z,c), \ - I[240] = (T)(img)(_p9##x,_n3##y,z,c), I[241] = (T)(img)(_p8##x,_n3##y,z,c), I[242] = (T)(img)(_p7##x,_n3##y,z,c), I[243] = (T)(img)(_p6##x,_n3##y,z,c), I[244] = (T)(img)(_p5##x,_n3##y,z,c), I[245] = (T)(img)(_p4##x,_n3##y,z,c), I[246] = (T)(img)(_p3##x,_n3##y,z,c), I[247] = (T)(img)(_p2##x,_n3##y,z,c), I[248] = (T)(img)(_p1##x,_n3##y,z,c), I[249] = (T)(img)(x,_n3##y,z,c), I[250] = (T)(img)(_n1##x,_n3##y,z,c), I[251] = (T)(img)(_n2##x,_n3##y,z,c), I[252] = (T)(img)(_n3##x,_n3##y,z,c), I[253] = (T)(img)(_n4##x,_n3##y,z,c), I[254] = (T)(img)(_n5##x,_n3##y,z,c), I[255] = (T)(img)(_n6##x,_n3##y,z,c), I[256] = (T)(img)(_n7##x,_n3##y,z,c), I[257] = (T)(img)(_n8##x,_n3##y,z,c), I[258] = (T)(img)(_n9##x,_n3##y,z,c), I[259] = (T)(img)(_n10##x,_n3##y,z,c), \ - I[260] = (T)(img)(_p9##x,_n4##y,z,c), I[261] = (T)(img)(_p8##x,_n4##y,z,c), I[262] = (T)(img)(_p7##x,_n4##y,z,c), I[263] = (T)(img)(_p6##x,_n4##y,z,c), I[264] = (T)(img)(_p5##x,_n4##y,z,c), I[265] = (T)(img)(_p4##x,_n4##y,z,c), I[266] = (T)(img)(_p3##x,_n4##y,z,c), I[267] = (T)(img)(_p2##x,_n4##y,z,c), I[268] = (T)(img)(_p1##x,_n4##y,z,c), I[269] = (T)(img)(x,_n4##y,z,c), I[270] = (T)(img)(_n1##x,_n4##y,z,c), I[271] = (T)(img)(_n2##x,_n4##y,z,c), I[272] = (T)(img)(_n3##x,_n4##y,z,c), I[273] = (T)(img)(_n4##x,_n4##y,z,c), I[274] = (T)(img)(_n5##x,_n4##y,z,c), I[275] = (T)(img)(_n6##x,_n4##y,z,c), I[276] = (T)(img)(_n7##x,_n4##y,z,c), I[277] = (T)(img)(_n8##x,_n4##y,z,c), I[278] = (T)(img)(_n9##x,_n4##y,z,c), I[279] = (T)(img)(_n10##x,_n4##y,z,c), \ - I[280] = (T)(img)(_p9##x,_n5##y,z,c), I[281] = (T)(img)(_p8##x,_n5##y,z,c), I[282] = (T)(img)(_p7##x,_n5##y,z,c), I[283] = (T)(img)(_p6##x,_n5##y,z,c), I[284] = (T)(img)(_p5##x,_n5##y,z,c), I[285] = (T)(img)(_p4##x,_n5##y,z,c), I[286] = (T)(img)(_p3##x,_n5##y,z,c), I[287] = (T)(img)(_p2##x,_n5##y,z,c), I[288] = (T)(img)(_p1##x,_n5##y,z,c), I[289] = (T)(img)(x,_n5##y,z,c), I[290] = (T)(img)(_n1##x,_n5##y,z,c), I[291] = (T)(img)(_n2##x,_n5##y,z,c), I[292] = (T)(img)(_n3##x,_n5##y,z,c), I[293] = (T)(img)(_n4##x,_n5##y,z,c), I[294] = (T)(img)(_n5##x,_n5##y,z,c), I[295] = (T)(img)(_n6##x,_n5##y,z,c), I[296] = (T)(img)(_n7##x,_n5##y,z,c), I[297] = (T)(img)(_n8##x,_n5##y,z,c), I[298] = (T)(img)(_n9##x,_n5##y,z,c), I[299] = (T)(img)(_n10##x,_n5##y,z,c), \ - I[300] = (T)(img)(_p9##x,_n6##y,z,c), I[301] = (T)(img)(_p8##x,_n6##y,z,c), I[302] = (T)(img)(_p7##x,_n6##y,z,c), I[303] = (T)(img)(_p6##x,_n6##y,z,c), I[304] = (T)(img)(_p5##x,_n6##y,z,c), I[305] = (T)(img)(_p4##x,_n6##y,z,c), I[306] = (T)(img)(_p3##x,_n6##y,z,c), I[307] = (T)(img)(_p2##x,_n6##y,z,c), I[308] = (T)(img)(_p1##x,_n6##y,z,c), I[309] = (T)(img)(x,_n6##y,z,c), I[310] = (T)(img)(_n1##x,_n6##y,z,c), I[311] = (T)(img)(_n2##x,_n6##y,z,c), I[312] = (T)(img)(_n3##x,_n6##y,z,c), I[313] = (T)(img)(_n4##x,_n6##y,z,c), I[314] = (T)(img)(_n5##x,_n6##y,z,c), I[315] = (T)(img)(_n6##x,_n6##y,z,c), I[316] = (T)(img)(_n7##x,_n6##y,z,c), I[317] = (T)(img)(_n8##x,_n6##y,z,c), I[318] = (T)(img)(_n9##x,_n6##y,z,c), I[319] = (T)(img)(_n10##x,_n6##y,z,c), \ - I[320] = (T)(img)(_p9##x,_n7##y,z,c), I[321] = (T)(img)(_p8##x,_n7##y,z,c), I[322] = (T)(img)(_p7##x,_n7##y,z,c), I[323] = (T)(img)(_p6##x,_n7##y,z,c), I[324] = (T)(img)(_p5##x,_n7##y,z,c), I[325] = (T)(img)(_p4##x,_n7##y,z,c), I[326] = (T)(img)(_p3##x,_n7##y,z,c), I[327] = (T)(img)(_p2##x,_n7##y,z,c), I[328] = (T)(img)(_p1##x,_n7##y,z,c), I[329] = (T)(img)(x,_n7##y,z,c), I[330] = (T)(img)(_n1##x,_n7##y,z,c), I[331] = (T)(img)(_n2##x,_n7##y,z,c), I[332] = (T)(img)(_n3##x,_n7##y,z,c), I[333] = (T)(img)(_n4##x,_n7##y,z,c), I[334] = (T)(img)(_n5##x,_n7##y,z,c), I[335] = (T)(img)(_n6##x,_n7##y,z,c), I[336] = (T)(img)(_n7##x,_n7##y,z,c), I[337] = (T)(img)(_n8##x,_n7##y,z,c), I[338] = (T)(img)(_n9##x,_n7##y,z,c), I[339] = (T)(img)(_n10##x,_n7##y,z,c), \ - I[340] = (T)(img)(_p9##x,_n8##y,z,c), I[341] = (T)(img)(_p8##x,_n8##y,z,c), I[342] = (T)(img)(_p7##x,_n8##y,z,c), I[343] = (T)(img)(_p6##x,_n8##y,z,c), I[344] = (T)(img)(_p5##x,_n8##y,z,c), I[345] = (T)(img)(_p4##x,_n8##y,z,c), I[346] = (T)(img)(_p3##x,_n8##y,z,c), I[347] = (T)(img)(_p2##x,_n8##y,z,c), I[348] = (T)(img)(_p1##x,_n8##y,z,c), I[349] = (T)(img)(x,_n8##y,z,c), I[350] = (T)(img)(_n1##x,_n8##y,z,c), I[351] = (T)(img)(_n2##x,_n8##y,z,c), I[352] = (T)(img)(_n3##x,_n8##y,z,c), I[353] = (T)(img)(_n4##x,_n8##y,z,c), I[354] = (T)(img)(_n5##x,_n8##y,z,c), I[355] = (T)(img)(_n6##x,_n8##y,z,c), I[356] = (T)(img)(_n7##x,_n8##y,z,c), I[357] = (T)(img)(_n8##x,_n8##y,z,c), I[358] = (T)(img)(_n9##x,_n8##y,z,c), I[359] = (T)(img)(_n10##x,_n8##y,z,c), \ - I[360] = (T)(img)(_p9##x,_n9##y,z,c), I[361] = (T)(img)(_p8##x,_n9##y,z,c), I[362] = (T)(img)(_p7##x,_n9##y,z,c), I[363] = (T)(img)(_p6##x,_n9##y,z,c), I[364] = (T)(img)(_p5##x,_n9##y,z,c), I[365] = (T)(img)(_p4##x,_n9##y,z,c), I[366] = (T)(img)(_p3##x,_n9##y,z,c), I[367] = (T)(img)(_p2##x,_n9##y,z,c), I[368] = (T)(img)(_p1##x,_n9##y,z,c), I[369] = (T)(img)(x,_n9##y,z,c), I[370] = (T)(img)(_n1##x,_n9##y,z,c), I[371] = (T)(img)(_n2##x,_n9##y,z,c), I[372] = (T)(img)(_n3##x,_n9##y,z,c), I[373] = (T)(img)(_n4##x,_n9##y,z,c), I[374] = (T)(img)(_n5##x,_n9##y,z,c), I[375] = (T)(img)(_n6##x,_n9##y,z,c), I[376] = (T)(img)(_n7##x,_n9##y,z,c), I[377] = (T)(img)(_n8##x,_n9##y,z,c), I[378] = (T)(img)(_n9##x,_n9##y,z,c), I[379] = (T)(img)(_n10##x,_n9##y,z,c), \ - I[380] = (T)(img)(_p9##x,_n10##y,z,c), I[381] = (T)(img)(_p8##x,_n10##y,z,c), I[382] = (T)(img)(_p7##x,_n10##y,z,c), I[383] = (T)(img)(_p6##x,_n10##y,z,c), I[384] = (T)(img)(_p5##x,_n10##y,z,c), I[385] = (T)(img)(_p4##x,_n10##y,z,c), I[386] = (T)(img)(_p3##x,_n10##y,z,c), I[387] = (T)(img)(_p2##x,_n10##y,z,c), I[388] = (T)(img)(_p1##x,_n10##y,z,c), I[389] = (T)(img)(x,_n10##y,z,c), I[390] = (T)(img)(_n1##x,_n10##y,z,c), I[391] = (T)(img)(_n2##x,_n10##y,z,c), I[392] = (T)(img)(_n3##x,_n10##y,z,c), I[393] = (T)(img)(_n4##x,_n10##y,z,c), I[394] = (T)(img)(_n5##x,_n10##y,z,c), I[395] = (T)(img)(_n6##x,_n10##y,z,c), I[396] = (T)(img)(_n7##x,_n10##y,z,c), I[397] = (T)(img)(_n8##x,_n10##y,z,c), I[398] = (T)(img)(_n9##x,_n10##y,z,c), I[399] = (T)(img)(_n10##x,_n10##y,z,c); - -// Define 21x21 loop macros -//------------------------- -#define cimg_for21(bound,i) for (int i = 0, \ - _p10##i = 0, _p9##i = 0, _p8##i = 0, _p7##i = 0, _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6, \ - _n7##i = 7>=(int)(bound)?(int)(bound) - 1:7, \ - _n8##i = 8>=(int)(bound)?(int)(bound) - 1:8, \ - _n9##i = 9>=(int)(bound)?(int)(bound) - 1:9, \ - _n10##i = 10>=(int)(bound)?(int)(bound) - 1:10; \ - _n10##i<(int)(bound) || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i) - -#define cimg_for21X(img,x) cimg_for21((img)._width,x) -#define cimg_for21Y(img,y) cimg_for21((img)._height,y) -#define cimg_for21Z(img,z) cimg_for21((img)._depth,z) -#define cimg_for21C(img,c) cimg_for21((img)._spectrum,c) -#define cimg_for21XY(img,x,y) cimg_for21Y(img,y) cimg_for21X(img,x) -#define cimg_for21XZ(img,x,z) cimg_for21Z(img,z) cimg_for21X(img,x) -#define cimg_for21XC(img,x,c) cimg_for21C(img,c) cimg_for21X(img,x) -#define cimg_for21YZ(img,y,z) cimg_for21Z(img,z) cimg_for21Y(img,y) -#define cimg_for21YC(img,y,c) cimg_for21C(img,c) cimg_for21Y(img,y) -#define cimg_for21ZC(img,z,c) cimg_for21C(img,c) cimg_for21Z(img,z) -#define cimg_for21XYZ(img,x,y,z) cimg_for21Z(img,z) cimg_for21XY(img,x,y) -#define cimg_for21XZC(img,x,z,c) cimg_for21C(img,c) cimg_for21XZ(img,x,z) -#define cimg_for21YZC(img,y,z,c) cimg_for21C(img,c) cimg_for21YZ(img,y,z) -#define cimg_for21XYZC(img,x,y,z,c) cimg_for21C(img,c) cimg_for21XYZ(img,x,y,z) - -#define cimg_for_in21(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p10##i = i - 10<0?0:i - 10, \ - _p9##i = i - 9<0?0:i - 9, \ - _p8##i = i - 8<0?0:i - 8, \ - _p7##i = i - 7<0?0:i - 7, \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6, \ - _n7##i = i + 7>=(int)(bound)?(int)(bound) - 1:i + 7, \ - _n8##i = i + 8>=(int)(bound)?(int)(bound) - 1:i + 8, \ - _n9##i = i + 9>=(int)(bound)?(int)(bound) - 1:i + 9, \ - _n10##i = i + 10>=(int)(bound)?(int)(bound) - 1:i + 10; \ - i<=(int)(i1) && (_n10##i<(int)(bound) || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i) - -#define cimg_for_in21X(img,x0,x1,x) cimg_for_in21((img)._width,x0,x1,x) -#define cimg_for_in21Y(img,y0,y1,y) cimg_for_in21((img)._height,y0,y1,y) -#define cimg_for_in21Z(img,z0,z1,z) cimg_for_in21((img)._depth,z0,z1,z) -#define cimg_for_in21C(img,c0,c1,c) cimg_for_in21((img)._spectrum,c0,c1,c) -#define cimg_for_in21XY(img,x0,y0,x1,y1,x,y) cimg_for_in21Y(img,y0,y1,y) cimg_for_in21X(img,x0,x1,x) -#define cimg_for_in21XZ(img,x0,z0,x1,z1,x,z) cimg_for_in21Z(img,z0,z1,z) cimg_for_in21X(img,x0,x1,x) -#define cimg_for_in21XC(img,x0,c0,x1,c1,x,c) cimg_for_in21C(img,c0,c1,c) cimg_for_in21X(img,x0,x1,x) -#define cimg_for_in21YZ(img,y0,z0,y1,z1,y,z) cimg_for_in21Z(img,z0,z1,z) cimg_for_in21Y(img,y0,y1,y) -#define cimg_for_in21YC(img,y0,c0,y1,c1,y,c) cimg_for_in21C(img,c0,c1,c) cimg_for_in21Y(img,y0,y1,y) -#define cimg_for_in21ZC(img,z0,c0,z1,c1,z,c) cimg_for_in21C(img,c0,c1,c) cimg_for_in21Z(img,z0,z1,z) -#define cimg_for_in21XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in21Z(img,z0,z1,z) cimg_for_in21XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in21XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in21C(img,c0,c1,c) cimg_for_in21XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in21YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in21C(img,c0,c1,c) cimg_for_in21YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in21XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in21C(img,c0,c1,c) cimg_for_in21XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for21x21(img,x,y,z,c,I,T) \ - cimg_for21((img)._height,y) for (int x = 0, \ - _p10##x = 0, _p9##x = 0, _p8##x = 0, _p7##x = 0, _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = 6>=((img)._width)?(img).width() - 1:6, \ - _n7##x = 7>=((img)._width)?(img).width() - 1:7, \ - _n8##x = 8>=((img)._width)?(img).width() - 1:8, \ - _n9##x = 9>=((img)._width)?(img).width() - 1:9, \ - _n10##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = I[7] = I[8] = I[9] = I[10] = (T)(img)(0,_p10##y,z,c)), \ - (I[21] = I[22] = I[23] = I[24] = I[25] = I[26] = I[27] = I[28] = I[29] = I[30] = I[31] = (T)(img)(0,_p9##y,z,c)), \ - (I[42] = I[43] = I[44] = I[45] = I[46] = I[47] = I[48] = I[49] = I[50] = I[51] = I[52] = (T)(img)(0,_p8##y,z,c)), \ - (I[63] = I[64] = I[65] = I[66] = I[67] = I[68] = I[69] = I[70] = I[71] = I[72] = I[73] = (T)(img)(0,_p7##y,z,c)), \ - (I[84] = I[85] = I[86] = I[87] = I[88] = I[89] = I[90] = I[91] = I[92] = I[93] = I[94] = (T)(img)(0,_p6##y,z,c)), \ - (I[105] = I[106] = I[107] = I[108] = I[109] = I[110] = I[111] = I[112] = I[113] = I[114] = I[115] = (T)(img)(0,_p5##y,z,c)), \ - (I[126] = I[127] = I[128] = I[129] = I[130] = I[131] = I[132] = I[133] = I[134] = I[135] = I[136] = (T)(img)(0,_p4##y,z,c)), \ - (I[147] = I[148] = I[149] = I[150] = I[151] = I[152] = I[153] = I[154] = I[155] = I[156] = I[157] = (T)(img)(0,_p3##y,z,c)), \ - (I[168] = I[169] = I[170] = I[171] = I[172] = I[173] = I[174] = I[175] = I[176] = I[177] = I[178] = (T)(img)(0,_p2##y,z,c)), \ - (I[189] = I[190] = I[191] = I[192] = I[193] = I[194] = I[195] = I[196] = I[197] = I[198] = I[199] = (T)(img)(0,_p1##y,z,c)), \ - (I[210] = I[211] = I[212] = I[213] = I[214] = I[215] = I[216] = I[217] = I[218] = I[219] = I[220] = (T)(img)(0,y,z,c)), \ - (I[231] = I[232] = I[233] = I[234] = I[235] = I[236] = I[237] = I[238] = I[239] = I[240] = I[241] = (T)(img)(0,_n1##y,z,c)), \ - (I[252] = I[253] = I[254] = I[255] = I[256] = I[257] = I[258] = I[259] = I[260] = I[261] = I[262] = (T)(img)(0,_n2##y,z,c)), \ - (I[273] = I[274] = I[275] = I[276] = I[277] = I[278] = I[279] = I[280] = I[281] = I[282] = I[283] = (T)(img)(0,_n3##y,z,c)), \ - (I[294] = I[295] = I[296] = I[297] = I[298] = I[299] = I[300] = I[301] = I[302] = I[303] = I[304] = (T)(img)(0,_n4##y,z,c)), \ - (I[315] = I[316] = I[317] = I[318] = I[319] = I[320] = I[321] = I[322] = I[323] = I[324] = I[325] = (T)(img)(0,_n5##y,z,c)), \ - (I[336] = I[337] = I[338] = I[339] = I[340] = I[341] = I[342] = I[343] = I[344] = I[345] = I[346] = (T)(img)(0,_n6##y,z,c)), \ - (I[357] = I[358] = I[359] = I[360] = I[361] = I[362] = I[363] = I[364] = I[365] = I[366] = I[367] = (T)(img)(0,_n7##y,z,c)), \ - (I[378] = I[379] = I[380] = I[381] = I[382] = I[383] = I[384] = I[385] = I[386] = I[387] = I[388] = (T)(img)(0,_n8##y,z,c)), \ - (I[399] = I[400] = I[401] = I[402] = I[403] = I[404] = I[405] = I[406] = I[407] = I[408] = I[409] = (T)(img)(0,_n9##y,z,c)), \ - (I[420] = I[421] = I[422] = I[423] = I[424] = I[425] = I[426] = I[427] = I[428] = I[429] = I[430] = (T)(img)(0,_n10##y,z,c)), \ - (I[11] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[32] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[53] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[74] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[95] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[116] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[137] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[158] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[179] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[200] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[221] = (T)(img)(_n1##x,y,z,c)), \ - (I[242] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[263] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[284] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[305] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[326] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[347] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[368] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[389] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[410] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[431] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[12] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[33] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[54] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[75] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[96] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[117] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[138] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[159] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[180] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[201] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[222] = (T)(img)(_n2##x,y,z,c)), \ - (I[243] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[264] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[285] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[306] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[327] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[348] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[369] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[390] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[411] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[432] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[13] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[34] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[55] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[76] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[97] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[118] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[139] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[160] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[181] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[202] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[223] = (T)(img)(_n3##x,y,z,c)), \ - (I[244] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[265] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[286] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[307] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[328] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[349] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[370] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[391] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[412] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[433] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[14] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[35] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[56] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[77] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[98] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[119] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[140] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[161] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[182] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[203] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[224] = (T)(img)(_n4##x,y,z,c)), \ - (I[245] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[266] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[287] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[308] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[329] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[350] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[371] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[392] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[413] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[434] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[15] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[36] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[57] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[78] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[99] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[120] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[141] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[162] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[183] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[204] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[225] = (T)(img)(_n5##x,y,z,c)), \ - (I[246] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[267] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[288] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[309] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[330] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[351] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[372] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[393] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[414] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[435] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[16] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[37] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[58] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[79] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[100] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[121] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[142] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[163] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[184] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[205] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[226] = (T)(img)(_n6##x,y,z,c)), \ - (I[247] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[268] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[289] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[310] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[331] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[352] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[373] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[394] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[415] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[436] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[17] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[38] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[59] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[80] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[101] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[122] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[143] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[164] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[185] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[206] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[227] = (T)(img)(_n7##x,y,z,c)), \ - (I[248] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[269] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[290] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[311] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[332] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[353] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[374] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[395] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[416] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[437] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[18] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[39] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[60] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[81] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[102] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[123] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[144] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[165] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[186] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[207] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[228] = (T)(img)(_n8##x,y,z,c)), \ - (I[249] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[270] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[291] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[312] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[333] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[354] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[375] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[396] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[417] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[438] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[19] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[40] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[61] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[82] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[103] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[124] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[145] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[166] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[187] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[208] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[229] = (T)(img)(_n9##x,y,z,c)), \ - (I[250] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[271] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[292] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[313] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[334] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[355] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[376] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[397] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[418] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[439] = (T)(img)(_n9##x,_n10##y,z,c)), \ - 10>=((img)._width)?(img).width() - 1:10); \ - (_n10##x<(img).width() && ( \ - (I[20] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[41] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[62] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[83] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[104] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[125] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[146] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[167] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[188] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[209] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[230] = (T)(img)(_n10##x,y,z,c)), \ - (I[251] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[272] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[293] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[314] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[335] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[356] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[377] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[398] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[419] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[440] = (T)(img)(_n10##x,_n10##y,z,c)),1)) || \ - _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], \ - I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], \ - I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], \ - I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], \ - I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], \ - I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], \ - I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], \ - I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], \ - I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], \ - I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], \ - I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], \ - I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], \ - I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], \ - I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], \ - I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], \ - I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], \ - I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], \ - I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], \ - I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], \ - I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], I[415] = I[416], I[416] = I[417], I[417] = I[418], I[418] = I[419], \ - I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], \ - _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x) - -#define cimg_for_in21x21(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in21((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p10##x = x - 10<0?0:x - 10, \ - _p9##x = x - 9<0?0:x - 9, \ - _p8##x = x - 8<0?0:x - 8, \ - _p7##x = x - 7<0?0:x - 7, \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = x + 6>=(img).width()?(img).width() - 1:x + 6, \ - _n7##x = x + 7>=(img).width()?(img).width() - 1:x + 7, \ - _n8##x = x + 8>=(img).width()?(img).width() - 1:x + 8, \ - _n9##x = x + 9>=(img).width()?(img).width() - 1:x + 9, \ - _n10##x = (int)( \ - (I[0] = (T)(img)(_p10##x,_p10##y,z,c)), \ - (I[21] = (T)(img)(_p10##x,_p9##y,z,c)), \ - (I[42] = (T)(img)(_p10##x,_p8##y,z,c)), \ - (I[63] = (T)(img)(_p10##x,_p7##y,z,c)), \ - (I[84] = (T)(img)(_p10##x,_p6##y,z,c)), \ - (I[105] = (T)(img)(_p10##x,_p5##y,z,c)), \ - (I[126] = (T)(img)(_p10##x,_p4##y,z,c)), \ - (I[147] = (T)(img)(_p10##x,_p3##y,z,c)), \ - (I[168] = (T)(img)(_p10##x,_p2##y,z,c)), \ - (I[189] = (T)(img)(_p10##x,_p1##y,z,c)), \ - (I[210] = (T)(img)(_p10##x,y,z,c)), \ - (I[231] = (T)(img)(_p10##x,_n1##y,z,c)), \ - (I[252] = (T)(img)(_p10##x,_n2##y,z,c)), \ - (I[273] = (T)(img)(_p10##x,_n3##y,z,c)), \ - (I[294] = (T)(img)(_p10##x,_n4##y,z,c)), \ - (I[315] = (T)(img)(_p10##x,_n5##y,z,c)), \ - (I[336] = (T)(img)(_p10##x,_n6##y,z,c)), \ - (I[357] = (T)(img)(_p10##x,_n7##y,z,c)), \ - (I[378] = (T)(img)(_p10##x,_n8##y,z,c)), \ - (I[399] = (T)(img)(_p10##x,_n9##y,z,c)), \ - (I[420] = (T)(img)(_p10##x,_n10##y,z,c)), \ - (I[1] = (T)(img)(_p9##x,_p10##y,z,c)), \ - (I[22] = (T)(img)(_p9##x,_p9##y,z,c)), \ - (I[43] = (T)(img)(_p9##x,_p8##y,z,c)), \ - (I[64] = (T)(img)(_p9##x,_p7##y,z,c)), \ - (I[85] = (T)(img)(_p9##x,_p6##y,z,c)), \ - (I[106] = (T)(img)(_p9##x,_p5##y,z,c)), \ - (I[127] = (T)(img)(_p9##x,_p4##y,z,c)), \ - (I[148] = (T)(img)(_p9##x,_p3##y,z,c)), \ - (I[169] = (T)(img)(_p9##x,_p2##y,z,c)), \ - (I[190] = (T)(img)(_p9##x,_p1##y,z,c)), \ - (I[211] = (T)(img)(_p9##x,y,z,c)), \ - (I[232] = (T)(img)(_p9##x,_n1##y,z,c)), \ - (I[253] = (T)(img)(_p9##x,_n2##y,z,c)), \ - (I[274] = (T)(img)(_p9##x,_n3##y,z,c)), \ - (I[295] = (T)(img)(_p9##x,_n4##y,z,c)), \ - (I[316] = (T)(img)(_p9##x,_n5##y,z,c)), \ - (I[337] = (T)(img)(_p9##x,_n6##y,z,c)), \ - (I[358] = (T)(img)(_p9##x,_n7##y,z,c)), \ - (I[379] = (T)(img)(_p9##x,_n8##y,z,c)), \ - (I[400] = (T)(img)(_p9##x,_n9##y,z,c)), \ - (I[421] = (T)(img)(_p9##x,_n10##y,z,c)), \ - (I[2] = (T)(img)(_p8##x,_p10##y,z,c)), \ - (I[23] = (T)(img)(_p8##x,_p9##y,z,c)), \ - (I[44] = (T)(img)(_p8##x,_p8##y,z,c)), \ - (I[65] = (T)(img)(_p8##x,_p7##y,z,c)), \ - (I[86] = (T)(img)(_p8##x,_p6##y,z,c)), \ - (I[107] = (T)(img)(_p8##x,_p5##y,z,c)), \ - (I[128] = (T)(img)(_p8##x,_p4##y,z,c)), \ - (I[149] = (T)(img)(_p8##x,_p3##y,z,c)), \ - (I[170] = (T)(img)(_p8##x,_p2##y,z,c)), \ - (I[191] = (T)(img)(_p8##x,_p1##y,z,c)), \ - (I[212] = (T)(img)(_p8##x,y,z,c)), \ - (I[233] = (T)(img)(_p8##x,_n1##y,z,c)), \ - (I[254] = (T)(img)(_p8##x,_n2##y,z,c)), \ - (I[275] = (T)(img)(_p8##x,_n3##y,z,c)), \ - (I[296] = (T)(img)(_p8##x,_n4##y,z,c)), \ - (I[317] = (T)(img)(_p8##x,_n5##y,z,c)), \ - (I[338] = (T)(img)(_p8##x,_n6##y,z,c)), \ - (I[359] = (T)(img)(_p8##x,_n7##y,z,c)), \ - (I[380] = (T)(img)(_p8##x,_n8##y,z,c)), \ - (I[401] = (T)(img)(_p8##x,_n9##y,z,c)), \ - (I[422] = (T)(img)(_p8##x,_n10##y,z,c)), \ - (I[3] = (T)(img)(_p7##x,_p10##y,z,c)), \ - (I[24] = (T)(img)(_p7##x,_p9##y,z,c)), \ - (I[45] = (T)(img)(_p7##x,_p8##y,z,c)), \ - (I[66] = (T)(img)(_p7##x,_p7##y,z,c)), \ - (I[87] = (T)(img)(_p7##x,_p6##y,z,c)), \ - (I[108] = (T)(img)(_p7##x,_p5##y,z,c)), \ - (I[129] = (T)(img)(_p7##x,_p4##y,z,c)), \ - (I[150] = (T)(img)(_p7##x,_p3##y,z,c)), \ - (I[171] = (T)(img)(_p7##x,_p2##y,z,c)), \ - (I[192] = (T)(img)(_p7##x,_p1##y,z,c)), \ - (I[213] = (T)(img)(_p7##x,y,z,c)), \ - (I[234] = (T)(img)(_p7##x,_n1##y,z,c)), \ - (I[255] = (T)(img)(_p7##x,_n2##y,z,c)), \ - (I[276] = (T)(img)(_p7##x,_n3##y,z,c)), \ - (I[297] = (T)(img)(_p7##x,_n4##y,z,c)), \ - (I[318] = (T)(img)(_p7##x,_n5##y,z,c)), \ - (I[339] = (T)(img)(_p7##x,_n6##y,z,c)), \ - (I[360] = (T)(img)(_p7##x,_n7##y,z,c)), \ - (I[381] = (T)(img)(_p7##x,_n8##y,z,c)), \ - (I[402] = (T)(img)(_p7##x,_n9##y,z,c)), \ - (I[423] = (T)(img)(_p7##x,_n10##y,z,c)), \ - (I[4] = (T)(img)(_p6##x,_p10##y,z,c)), \ - (I[25] = (T)(img)(_p6##x,_p9##y,z,c)), \ - (I[46] = (T)(img)(_p6##x,_p8##y,z,c)), \ - (I[67] = (T)(img)(_p6##x,_p7##y,z,c)), \ - (I[88] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[109] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[130] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[151] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[172] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[193] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[214] = (T)(img)(_p6##x,y,z,c)), \ - (I[235] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[256] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[277] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[298] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[319] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[340] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[361] = (T)(img)(_p6##x,_n7##y,z,c)), \ - (I[382] = (T)(img)(_p6##x,_n8##y,z,c)), \ - (I[403] = (T)(img)(_p6##x,_n9##y,z,c)), \ - (I[424] = (T)(img)(_p6##x,_n10##y,z,c)), \ - (I[5] = (T)(img)(_p5##x,_p10##y,z,c)), \ - (I[26] = (T)(img)(_p5##x,_p9##y,z,c)), \ - (I[47] = (T)(img)(_p5##x,_p8##y,z,c)), \ - (I[68] = (T)(img)(_p5##x,_p7##y,z,c)), \ - (I[89] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[110] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[131] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[152] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[173] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[194] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[215] = (T)(img)(_p5##x,y,z,c)), \ - (I[236] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[257] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[278] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[299] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[320] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[341] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[362] = (T)(img)(_p5##x,_n7##y,z,c)), \ - (I[383] = (T)(img)(_p5##x,_n8##y,z,c)), \ - (I[404] = (T)(img)(_p5##x,_n9##y,z,c)), \ - (I[425] = (T)(img)(_p5##x,_n10##y,z,c)), \ - (I[6] = (T)(img)(_p4##x,_p10##y,z,c)), \ - (I[27] = (T)(img)(_p4##x,_p9##y,z,c)), \ - (I[48] = (T)(img)(_p4##x,_p8##y,z,c)), \ - (I[69] = (T)(img)(_p4##x,_p7##y,z,c)), \ - (I[90] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[111] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[132] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[153] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[174] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[195] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[216] = (T)(img)(_p4##x,y,z,c)), \ - (I[237] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[258] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[279] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[300] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[321] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[342] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[363] = (T)(img)(_p4##x,_n7##y,z,c)), \ - (I[384] = (T)(img)(_p4##x,_n8##y,z,c)), \ - (I[405] = (T)(img)(_p4##x,_n9##y,z,c)), \ - (I[426] = (T)(img)(_p4##x,_n10##y,z,c)), \ - (I[7] = (T)(img)(_p3##x,_p10##y,z,c)), \ - (I[28] = (T)(img)(_p3##x,_p9##y,z,c)), \ - (I[49] = (T)(img)(_p3##x,_p8##y,z,c)), \ - (I[70] = (T)(img)(_p3##x,_p7##y,z,c)), \ - (I[91] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[112] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[133] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[154] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[175] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[196] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[217] = (T)(img)(_p3##x,y,z,c)), \ - (I[238] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[259] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[280] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[301] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[322] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[343] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[364] = (T)(img)(_p3##x,_n7##y,z,c)), \ - (I[385] = (T)(img)(_p3##x,_n8##y,z,c)), \ - (I[406] = (T)(img)(_p3##x,_n9##y,z,c)), \ - (I[427] = (T)(img)(_p3##x,_n10##y,z,c)), \ - (I[8] = (T)(img)(_p2##x,_p10##y,z,c)), \ - (I[29] = (T)(img)(_p2##x,_p9##y,z,c)), \ - (I[50] = (T)(img)(_p2##x,_p8##y,z,c)), \ - (I[71] = (T)(img)(_p2##x,_p7##y,z,c)), \ - (I[92] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[113] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[134] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[155] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[176] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[197] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[218] = (T)(img)(_p2##x,y,z,c)), \ - (I[239] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[260] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[281] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[302] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[323] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[344] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[365] = (T)(img)(_p2##x,_n7##y,z,c)), \ - (I[386] = (T)(img)(_p2##x,_n8##y,z,c)), \ - (I[407] = (T)(img)(_p2##x,_n9##y,z,c)), \ - (I[428] = (T)(img)(_p2##x,_n10##y,z,c)), \ - (I[9] = (T)(img)(_p1##x,_p10##y,z,c)), \ - (I[30] = (T)(img)(_p1##x,_p9##y,z,c)), \ - (I[51] = (T)(img)(_p1##x,_p8##y,z,c)), \ - (I[72] = (T)(img)(_p1##x,_p7##y,z,c)), \ - (I[93] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[114] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[135] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[156] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[177] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[198] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[219] = (T)(img)(_p1##x,y,z,c)), \ - (I[240] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[261] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[282] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[303] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[324] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[345] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[366] = (T)(img)(_p1##x,_n7##y,z,c)), \ - (I[387] = (T)(img)(_p1##x,_n8##y,z,c)), \ - (I[408] = (T)(img)(_p1##x,_n9##y,z,c)), \ - (I[429] = (T)(img)(_p1##x,_n10##y,z,c)), \ - (I[10] = (T)(img)(x,_p10##y,z,c)), \ - (I[31] = (T)(img)(x,_p9##y,z,c)), \ - (I[52] = (T)(img)(x,_p8##y,z,c)), \ - (I[73] = (T)(img)(x,_p7##y,z,c)), \ - (I[94] = (T)(img)(x,_p6##y,z,c)), \ - (I[115] = (T)(img)(x,_p5##y,z,c)), \ - (I[136] = (T)(img)(x,_p4##y,z,c)), \ - (I[157] = (T)(img)(x,_p3##y,z,c)), \ - (I[178] = (T)(img)(x,_p2##y,z,c)), \ - (I[199] = (T)(img)(x,_p1##y,z,c)), \ - (I[220] = (T)(img)(x,y,z,c)), \ - (I[241] = (T)(img)(x,_n1##y,z,c)), \ - (I[262] = (T)(img)(x,_n2##y,z,c)), \ - (I[283] = (T)(img)(x,_n3##y,z,c)), \ - (I[304] = (T)(img)(x,_n4##y,z,c)), \ - (I[325] = (T)(img)(x,_n5##y,z,c)), \ - (I[346] = (T)(img)(x,_n6##y,z,c)), \ - (I[367] = (T)(img)(x,_n7##y,z,c)), \ - (I[388] = (T)(img)(x,_n8##y,z,c)), \ - (I[409] = (T)(img)(x,_n9##y,z,c)), \ - (I[430] = (T)(img)(x,_n10##y,z,c)), \ - (I[11] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[32] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[53] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[74] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[95] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[116] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[137] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[158] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[179] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[200] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[221] = (T)(img)(_n1##x,y,z,c)), \ - (I[242] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[263] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[284] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[305] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[326] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[347] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[368] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[389] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[410] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[431] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[12] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[33] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[54] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[75] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[96] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[117] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[138] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[159] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[180] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[201] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[222] = (T)(img)(_n2##x,y,z,c)), \ - (I[243] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[264] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[285] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[306] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[327] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[348] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[369] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[390] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[411] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[432] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[13] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[34] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[55] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[76] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[97] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[118] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[139] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[160] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[181] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[202] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[223] = (T)(img)(_n3##x,y,z,c)), \ - (I[244] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[265] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[286] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[307] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[328] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[349] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[370] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[391] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[412] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[433] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[14] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[35] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[56] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[77] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[98] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[119] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[140] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[161] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[182] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[203] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[224] = (T)(img)(_n4##x,y,z,c)), \ - (I[245] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[266] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[287] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[308] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[329] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[350] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[371] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[392] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[413] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[434] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[15] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[36] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[57] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[78] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[99] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[120] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[141] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[162] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[183] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[204] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[225] = (T)(img)(_n5##x,y,z,c)), \ - (I[246] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[267] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[288] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[309] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[330] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[351] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[372] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[393] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[414] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[435] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[16] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[37] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[58] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[79] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[100] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[121] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[142] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[163] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[184] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[205] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[226] = (T)(img)(_n6##x,y,z,c)), \ - (I[247] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[268] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[289] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[310] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[331] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[352] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[373] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[394] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[415] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[436] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[17] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[38] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[59] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[80] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[101] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[122] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[143] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[164] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[185] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[206] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[227] = (T)(img)(_n7##x,y,z,c)), \ - (I[248] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[269] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[290] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[311] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[332] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[353] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[374] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[395] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[416] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[437] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[18] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[39] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[60] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[81] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[102] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[123] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[144] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[165] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[186] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[207] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[228] = (T)(img)(_n8##x,y,z,c)), \ - (I[249] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[270] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[291] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[312] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[333] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[354] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[375] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[396] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[417] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[438] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[19] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[40] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[61] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[82] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[103] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[124] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[145] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[166] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[187] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[208] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[229] = (T)(img)(_n9##x,y,z,c)), \ - (I[250] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[271] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[292] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[313] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[334] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[355] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[376] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[397] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[418] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[439] = (T)(img)(_n9##x,_n10##y,z,c)), \ - x + 10>=(img).width()?(img).width() - 1:x + 10); \ - x<=(int)(x1) && ((_n10##x<(img).width() && ( \ - (I[20] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[41] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[62] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[83] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[104] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[125] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[146] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[167] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[188] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[209] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[230] = (T)(img)(_n10##x,y,z,c)), \ - (I[251] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[272] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[293] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[314] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[335] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[356] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[377] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[398] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[419] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[440] = (T)(img)(_n10##x,_n10##y,z,c)),1)) || \ - _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], \ - I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], \ - I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], \ - I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], \ - I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], \ - I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], \ - I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], \ - I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], \ - I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], \ - I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], \ - I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], \ - I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], \ - I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], \ - I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], \ - I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], \ - I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], \ - I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], \ - I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], \ - I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], \ - I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], I[415] = I[416], I[416] = I[417], I[417] = I[418], I[418] = I[419], \ - I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], \ - _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x) - -#define cimg_get21x21(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p10##x,_p10##y,z,c), I[1] = (T)(img)(_p9##x,_p10##y,z,c), I[2] = (T)(img)(_p8##x,_p10##y,z,c), I[3] = (T)(img)(_p7##x,_p10##y,z,c), I[4] = (T)(img)(_p6##x,_p10##y,z,c), I[5] = (T)(img)(_p5##x,_p10##y,z,c), I[6] = (T)(img)(_p4##x,_p10##y,z,c), I[7] = (T)(img)(_p3##x,_p10##y,z,c), I[8] = (T)(img)(_p2##x,_p10##y,z,c), I[9] = (T)(img)(_p1##x,_p10##y,z,c), I[10] = (T)(img)(x,_p10##y,z,c), I[11] = (T)(img)(_n1##x,_p10##y,z,c), I[12] = (T)(img)(_n2##x,_p10##y,z,c), I[13] = (T)(img)(_n3##x,_p10##y,z,c), I[14] = (T)(img)(_n4##x,_p10##y,z,c), I[15] = (T)(img)(_n5##x,_p10##y,z,c), I[16] = (T)(img)(_n6##x,_p10##y,z,c), I[17] = (T)(img)(_n7##x,_p10##y,z,c), I[18] = (T)(img)(_n8##x,_p10##y,z,c), I[19] = (T)(img)(_n9##x,_p10##y,z,c), I[20] = (T)(img)(_n10##x,_p10##y,z,c), \ - I[21] = (T)(img)(_p10##x,_p9##y,z,c), I[22] = (T)(img)(_p9##x,_p9##y,z,c), I[23] = (T)(img)(_p8##x,_p9##y,z,c), I[24] = (T)(img)(_p7##x,_p9##y,z,c), I[25] = (T)(img)(_p6##x,_p9##y,z,c), I[26] = (T)(img)(_p5##x,_p9##y,z,c), I[27] = (T)(img)(_p4##x,_p9##y,z,c), I[28] = (T)(img)(_p3##x,_p9##y,z,c), I[29] = (T)(img)(_p2##x,_p9##y,z,c), I[30] = (T)(img)(_p1##x,_p9##y,z,c), I[31] = (T)(img)(x,_p9##y,z,c), I[32] = (T)(img)(_n1##x,_p9##y,z,c), I[33] = (T)(img)(_n2##x,_p9##y,z,c), I[34] = (T)(img)(_n3##x,_p9##y,z,c), I[35] = (T)(img)(_n4##x,_p9##y,z,c), I[36] = (T)(img)(_n5##x,_p9##y,z,c), I[37] = (T)(img)(_n6##x,_p9##y,z,c), I[38] = (T)(img)(_n7##x,_p9##y,z,c), I[39] = (T)(img)(_n8##x,_p9##y,z,c), I[40] = (T)(img)(_n9##x,_p9##y,z,c), I[41] = (T)(img)(_n10##x,_p9##y,z,c), \ - I[42] = (T)(img)(_p10##x,_p8##y,z,c), I[43] = (T)(img)(_p9##x,_p8##y,z,c), I[44] = (T)(img)(_p8##x,_p8##y,z,c), I[45] = (T)(img)(_p7##x,_p8##y,z,c), I[46] = (T)(img)(_p6##x,_p8##y,z,c), I[47] = (T)(img)(_p5##x,_p8##y,z,c), I[48] = (T)(img)(_p4##x,_p8##y,z,c), I[49] = (T)(img)(_p3##x,_p8##y,z,c), I[50] = (T)(img)(_p2##x,_p8##y,z,c), I[51] = (T)(img)(_p1##x,_p8##y,z,c), I[52] = (T)(img)(x,_p8##y,z,c), I[53] = (T)(img)(_n1##x,_p8##y,z,c), I[54] = (T)(img)(_n2##x,_p8##y,z,c), I[55] = (T)(img)(_n3##x,_p8##y,z,c), I[56] = (T)(img)(_n4##x,_p8##y,z,c), I[57] = (T)(img)(_n5##x,_p8##y,z,c), I[58] = (T)(img)(_n6##x,_p8##y,z,c), I[59] = (T)(img)(_n7##x,_p8##y,z,c), I[60] = (T)(img)(_n8##x,_p8##y,z,c), I[61] = (T)(img)(_n9##x,_p8##y,z,c), I[62] = (T)(img)(_n10##x,_p8##y,z,c), \ - I[63] = (T)(img)(_p10##x,_p7##y,z,c), I[64] = (T)(img)(_p9##x,_p7##y,z,c), I[65] = (T)(img)(_p8##x,_p7##y,z,c), I[66] = (T)(img)(_p7##x,_p7##y,z,c), I[67] = (T)(img)(_p6##x,_p7##y,z,c), I[68] = (T)(img)(_p5##x,_p7##y,z,c), I[69] = (T)(img)(_p4##x,_p7##y,z,c), I[70] = (T)(img)(_p3##x,_p7##y,z,c), I[71] = (T)(img)(_p2##x,_p7##y,z,c), I[72] = (T)(img)(_p1##x,_p7##y,z,c), I[73] = (T)(img)(x,_p7##y,z,c), I[74] = (T)(img)(_n1##x,_p7##y,z,c), I[75] = (T)(img)(_n2##x,_p7##y,z,c), I[76] = (T)(img)(_n3##x,_p7##y,z,c), I[77] = (T)(img)(_n4##x,_p7##y,z,c), I[78] = (T)(img)(_n5##x,_p7##y,z,c), I[79] = (T)(img)(_n6##x,_p7##y,z,c), I[80] = (T)(img)(_n7##x,_p7##y,z,c), I[81] = (T)(img)(_n8##x,_p7##y,z,c), I[82] = (T)(img)(_n9##x,_p7##y,z,c), I[83] = (T)(img)(_n10##x,_p7##y,z,c), \ - I[84] = (T)(img)(_p10##x,_p6##y,z,c), I[85] = (T)(img)(_p9##x,_p6##y,z,c), I[86] = (T)(img)(_p8##x,_p6##y,z,c), I[87] = (T)(img)(_p7##x,_p6##y,z,c), I[88] = (T)(img)(_p6##x,_p6##y,z,c), I[89] = (T)(img)(_p5##x,_p6##y,z,c), I[90] = (T)(img)(_p4##x,_p6##y,z,c), I[91] = (T)(img)(_p3##x,_p6##y,z,c), I[92] = (T)(img)(_p2##x,_p6##y,z,c), I[93] = (T)(img)(_p1##x,_p6##y,z,c), I[94] = (T)(img)(x,_p6##y,z,c), I[95] = (T)(img)(_n1##x,_p6##y,z,c), I[96] = (T)(img)(_n2##x,_p6##y,z,c), I[97] = (T)(img)(_n3##x,_p6##y,z,c), I[98] = (T)(img)(_n4##x,_p6##y,z,c), I[99] = (T)(img)(_n5##x,_p6##y,z,c), I[100] = (T)(img)(_n6##x,_p6##y,z,c), I[101] = (T)(img)(_n7##x,_p6##y,z,c), I[102] = (T)(img)(_n8##x,_p6##y,z,c), I[103] = (T)(img)(_n9##x,_p6##y,z,c), I[104] = (T)(img)(_n10##x,_p6##y,z,c), \ - I[105] = (T)(img)(_p10##x,_p5##y,z,c), I[106] = (T)(img)(_p9##x,_p5##y,z,c), I[107] = (T)(img)(_p8##x,_p5##y,z,c), I[108] = (T)(img)(_p7##x,_p5##y,z,c), I[109] = (T)(img)(_p6##x,_p5##y,z,c), I[110] = (T)(img)(_p5##x,_p5##y,z,c), I[111] = (T)(img)(_p4##x,_p5##y,z,c), I[112] = (T)(img)(_p3##x,_p5##y,z,c), I[113] = (T)(img)(_p2##x,_p5##y,z,c), I[114] = (T)(img)(_p1##x,_p5##y,z,c), I[115] = (T)(img)(x,_p5##y,z,c), I[116] = (T)(img)(_n1##x,_p5##y,z,c), I[117] = (T)(img)(_n2##x,_p5##y,z,c), I[118] = (T)(img)(_n3##x,_p5##y,z,c), I[119] = (T)(img)(_n4##x,_p5##y,z,c), I[120] = (T)(img)(_n5##x,_p5##y,z,c), I[121] = (T)(img)(_n6##x,_p5##y,z,c), I[122] = (T)(img)(_n7##x,_p5##y,z,c), I[123] = (T)(img)(_n8##x,_p5##y,z,c), I[124] = (T)(img)(_n9##x,_p5##y,z,c), I[125] = (T)(img)(_n10##x,_p5##y,z,c), \ - I[126] = (T)(img)(_p10##x,_p4##y,z,c), I[127] = (T)(img)(_p9##x,_p4##y,z,c), I[128] = (T)(img)(_p8##x,_p4##y,z,c), I[129] = (T)(img)(_p7##x,_p4##y,z,c), I[130] = (T)(img)(_p6##x,_p4##y,z,c), I[131] = (T)(img)(_p5##x,_p4##y,z,c), I[132] = (T)(img)(_p4##x,_p4##y,z,c), I[133] = (T)(img)(_p3##x,_p4##y,z,c), I[134] = (T)(img)(_p2##x,_p4##y,z,c), I[135] = (T)(img)(_p1##x,_p4##y,z,c), I[136] = (T)(img)(x,_p4##y,z,c), I[137] = (T)(img)(_n1##x,_p4##y,z,c), I[138] = (T)(img)(_n2##x,_p4##y,z,c), I[139] = (T)(img)(_n3##x,_p4##y,z,c), I[140] = (T)(img)(_n4##x,_p4##y,z,c), I[141] = (T)(img)(_n5##x,_p4##y,z,c), I[142] = (T)(img)(_n6##x,_p4##y,z,c), I[143] = (T)(img)(_n7##x,_p4##y,z,c), I[144] = (T)(img)(_n8##x,_p4##y,z,c), I[145] = (T)(img)(_n9##x,_p4##y,z,c), I[146] = (T)(img)(_n10##x,_p4##y,z,c), \ - I[147] = (T)(img)(_p10##x,_p3##y,z,c), I[148] = (T)(img)(_p9##x,_p3##y,z,c), I[149] = (T)(img)(_p8##x,_p3##y,z,c), I[150] = (T)(img)(_p7##x,_p3##y,z,c), I[151] = (T)(img)(_p6##x,_p3##y,z,c), I[152] = (T)(img)(_p5##x,_p3##y,z,c), I[153] = (T)(img)(_p4##x,_p3##y,z,c), I[154] = (T)(img)(_p3##x,_p3##y,z,c), I[155] = (T)(img)(_p2##x,_p3##y,z,c), I[156] = (T)(img)(_p1##x,_p3##y,z,c), I[157] = (T)(img)(x,_p3##y,z,c), I[158] = (T)(img)(_n1##x,_p3##y,z,c), I[159] = (T)(img)(_n2##x,_p3##y,z,c), I[160] = (T)(img)(_n3##x,_p3##y,z,c), I[161] = (T)(img)(_n4##x,_p3##y,z,c), I[162] = (T)(img)(_n5##x,_p3##y,z,c), I[163] = (T)(img)(_n6##x,_p3##y,z,c), I[164] = (T)(img)(_n7##x,_p3##y,z,c), I[165] = (T)(img)(_n8##x,_p3##y,z,c), I[166] = (T)(img)(_n9##x,_p3##y,z,c), I[167] = (T)(img)(_n10##x,_p3##y,z,c), \ - I[168] = (T)(img)(_p10##x,_p2##y,z,c), I[169] = (T)(img)(_p9##x,_p2##y,z,c), I[170] = (T)(img)(_p8##x,_p2##y,z,c), I[171] = (T)(img)(_p7##x,_p2##y,z,c), I[172] = (T)(img)(_p6##x,_p2##y,z,c), I[173] = (T)(img)(_p5##x,_p2##y,z,c), I[174] = (T)(img)(_p4##x,_p2##y,z,c), I[175] = (T)(img)(_p3##x,_p2##y,z,c), I[176] = (T)(img)(_p2##x,_p2##y,z,c), I[177] = (T)(img)(_p1##x,_p2##y,z,c), I[178] = (T)(img)(x,_p2##y,z,c), I[179] = (T)(img)(_n1##x,_p2##y,z,c), I[180] = (T)(img)(_n2##x,_p2##y,z,c), I[181] = (T)(img)(_n3##x,_p2##y,z,c), I[182] = (T)(img)(_n4##x,_p2##y,z,c), I[183] = (T)(img)(_n5##x,_p2##y,z,c), I[184] = (T)(img)(_n6##x,_p2##y,z,c), I[185] = (T)(img)(_n7##x,_p2##y,z,c), I[186] = (T)(img)(_n8##x,_p2##y,z,c), I[187] = (T)(img)(_n9##x,_p2##y,z,c), I[188] = (T)(img)(_n10##x,_p2##y,z,c), \ - I[189] = (T)(img)(_p10##x,_p1##y,z,c), I[190] = (T)(img)(_p9##x,_p1##y,z,c), I[191] = (T)(img)(_p8##x,_p1##y,z,c), I[192] = (T)(img)(_p7##x,_p1##y,z,c), I[193] = (T)(img)(_p6##x,_p1##y,z,c), I[194] = (T)(img)(_p5##x,_p1##y,z,c), I[195] = (T)(img)(_p4##x,_p1##y,z,c), I[196] = (T)(img)(_p3##x,_p1##y,z,c), I[197] = (T)(img)(_p2##x,_p1##y,z,c), I[198] = (T)(img)(_p1##x,_p1##y,z,c), I[199] = (T)(img)(x,_p1##y,z,c), I[200] = (T)(img)(_n1##x,_p1##y,z,c), I[201] = (T)(img)(_n2##x,_p1##y,z,c), I[202] = (T)(img)(_n3##x,_p1##y,z,c), I[203] = (T)(img)(_n4##x,_p1##y,z,c), I[204] = (T)(img)(_n5##x,_p1##y,z,c), I[205] = (T)(img)(_n6##x,_p1##y,z,c), I[206] = (T)(img)(_n7##x,_p1##y,z,c), I[207] = (T)(img)(_n8##x,_p1##y,z,c), I[208] = (T)(img)(_n9##x,_p1##y,z,c), I[209] = (T)(img)(_n10##x,_p1##y,z,c), \ - I[210] = (T)(img)(_p10##x,y,z,c), I[211] = (T)(img)(_p9##x,y,z,c), I[212] = (T)(img)(_p8##x,y,z,c), I[213] = (T)(img)(_p7##x,y,z,c), I[214] = (T)(img)(_p6##x,y,z,c), I[215] = (T)(img)(_p5##x,y,z,c), I[216] = (T)(img)(_p4##x,y,z,c), I[217] = (T)(img)(_p3##x,y,z,c), I[218] = (T)(img)(_p2##x,y,z,c), I[219] = (T)(img)(_p1##x,y,z,c), I[220] = (T)(img)(x,y,z,c), I[221] = (T)(img)(_n1##x,y,z,c), I[222] = (T)(img)(_n2##x,y,z,c), I[223] = (T)(img)(_n3##x,y,z,c), I[224] = (T)(img)(_n4##x,y,z,c), I[225] = (T)(img)(_n5##x,y,z,c), I[226] = (T)(img)(_n6##x,y,z,c), I[227] = (T)(img)(_n7##x,y,z,c), I[228] = (T)(img)(_n8##x,y,z,c), I[229] = (T)(img)(_n9##x,y,z,c), I[230] = (T)(img)(_n10##x,y,z,c), \ - I[231] = (T)(img)(_p10##x,_n1##y,z,c), I[232] = (T)(img)(_p9##x,_n1##y,z,c), I[233] = (T)(img)(_p8##x,_n1##y,z,c), I[234] = (T)(img)(_p7##x,_n1##y,z,c), I[235] = (T)(img)(_p6##x,_n1##y,z,c), I[236] = (T)(img)(_p5##x,_n1##y,z,c), I[237] = (T)(img)(_p4##x,_n1##y,z,c), I[238] = (T)(img)(_p3##x,_n1##y,z,c), I[239] = (T)(img)(_p2##x,_n1##y,z,c), I[240] = (T)(img)(_p1##x,_n1##y,z,c), I[241] = (T)(img)(x,_n1##y,z,c), I[242] = (T)(img)(_n1##x,_n1##y,z,c), I[243] = (T)(img)(_n2##x,_n1##y,z,c), I[244] = (T)(img)(_n3##x,_n1##y,z,c), I[245] = (T)(img)(_n4##x,_n1##y,z,c), I[246] = (T)(img)(_n5##x,_n1##y,z,c), I[247] = (T)(img)(_n6##x,_n1##y,z,c), I[248] = (T)(img)(_n7##x,_n1##y,z,c), I[249] = (T)(img)(_n8##x,_n1##y,z,c), I[250] = (T)(img)(_n9##x,_n1##y,z,c), I[251] = (T)(img)(_n10##x,_n1##y,z,c), \ - I[252] = (T)(img)(_p10##x,_n2##y,z,c), I[253] = (T)(img)(_p9##x,_n2##y,z,c), I[254] = (T)(img)(_p8##x,_n2##y,z,c), I[255] = (T)(img)(_p7##x,_n2##y,z,c), I[256] = (T)(img)(_p6##x,_n2##y,z,c), I[257] = (T)(img)(_p5##x,_n2##y,z,c), I[258] = (T)(img)(_p4##x,_n2##y,z,c), I[259] = (T)(img)(_p3##x,_n2##y,z,c), I[260] = (T)(img)(_p2##x,_n2##y,z,c), I[261] = (T)(img)(_p1##x,_n2##y,z,c), I[262] = (T)(img)(x,_n2##y,z,c), I[263] = (T)(img)(_n1##x,_n2##y,z,c), I[264] = (T)(img)(_n2##x,_n2##y,z,c), I[265] = (T)(img)(_n3##x,_n2##y,z,c), I[266] = (T)(img)(_n4##x,_n2##y,z,c), I[267] = (T)(img)(_n5##x,_n2##y,z,c), I[268] = (T)(img)(_n6##x,_n2##y,z,c), I[269] = (T)(img)(_n7##x,_n2##y,z,c), I[270] = (T)(img)(_n8##x,_n2##y,z,c), I[271] = (T)(img)(_n9##x,_n2##y,z,c), I[272] = (T)(img)(_n10##x,_n2##y,z,c), \ - I[273] = (T)(img)(_p10##x,_n3##y,z,c), I[274] = (T)(img)(_p9##x,_n3##y,z,c), I[275] = (T)(img)(_p8##x,_n3##y,z,c), I[276] = (T)(img)(_p7##x,_n3##y,z,c), I[277] = (T)(img)(_p6##x,_n3##y,z,c), I[278] = (T)(img)(_p5##x,_n3##y,z,c), I[279] = (T)(img)(_p4##x,_n3##y,z,c), I[280] = (T)(img)(_p3##x,_n3##y,z,c), I[281] = (T)(img)(_p2##x,_n3##y,z,c), I[282] = (T)(img)(_p1##x,_n3##y,z,c), I[283] = (T)(img)(x,_n3##y,z,c), I[284] = (T)(img)(_n1##x,_n3##y,z,c), I[285] = (T)(img)(_n2##x,_n3##y,z,c), I[286] = (T)(img)(_n3##x,_n3##y,z,c), I[287] = (T)(img)(_n4##x,_n3##y,z,c), I[288] = (T)(img)(_n5##x,_n3##y,z,c), I[289] = (T)(img)(_n6##x,_n3##y,z,c), I[290] = (T)(img)(_n7##x,_n3##y,z,c), I[291] = (T)(img)(_n8##x,_n3##y,z,c), I[292] = (T)(img)(_n9##x,_n3##y,z,c), I[293] = (T)(img)(_n10##x,_n3##y,z,c), \ - I[294] = (T)(img)(_p10##x,_n4##y,z,c), I[295] = (T)(img)(_p9##x,_n4##y,z,c), I[296] = (T)(img)(_p8##x,_n4##y,z,c), I[297] = (T)(img)(_p7##x,_n4##y,z,c), I[298] = (T)(img)(_p6##x,_n4##y,z,c), I[299] = (T)(img)(_p5##x,_n4##y,z,c), I[300] = (T)(img)(_p4##x,_n4##y,z,c), I[301] = (T)(img)(_p3##x,_n4##y,z,c), I[302] = (T)(img)(_p2##x,_n4##y,z,c), I[303] = (T)(img)(_p1##x,_n4##y,z,c), I[304] = (T)(img)(x,_n4##y,z,c), I[305] = (T)(img)(_n1##x,_n4##y,z,c), I[306] = (T)(img)(_n2##x,_n4##y,z,c), I[307] = (T)(img)(_n3##x,_n4##y,z,c), I[308] = (T)(img)(_n4##x,_n4##y,z,c), I[309] = (T)(img)(_n5##x,_n4##y,z,c), I[310] = (T)(img)(_n6##x,_n4##y,z,c), I[311] = (T)(img)(_n7##x,_n4##y,z,c), I[312] = (T)(img)(_n8##x,_n4##y,z,c), I[313] = (T)(img)(_n9##x,_n4##y,z,c), I[314] = (T)(img)(_n10##x,_n4##y,z,c), \ - I[315] = (T)(img)(_p10##x,_n5##y,z,c), I[316] = (T)(img)(_p9##x,_n5##y,z,c), I[317] = (T)(img)(_p8##x,_n5##y,z,c), I[318] = (T)(img)(_p7##x,_n5##y,z,c), I[319] = (T)(img)(_p6##x,_n5##y,z,c), I[320] = (T)(img)(_p5##x,_n5##y,z,c), I[321] = (T)(img)(_p4##x,_n5##y,z,c), I[322] = (T)(img)(_p3##x,_n5##y,z,c), I[323] = (T)(img)(_p2##x,_n5##y,z,c), I[324] = (T)(img)(_p1##x,_n5##y,z,c), I[325] = (T)(img)(x,_n5##y,z,c), I[326] = (T)(img)(_n1##x,_n5##y,z,c), I[327] = (T)(img)(_n2##x,_n5##y,z,c), I[328] = (T)(img)(_n3##x,_n5##y,z,c), I[329] = (T)(img)(_n4##x,_n5##y,z,c), I[330] = (T)(img)(_n5##x,_n5##y,z,c), I[331] = (T)(img)(_n6##x,_n5##y,z,c), I[332] = (T)(img)(_n7##x,_n5##y,z,c), I[333] = (T)(img)(_n8##x,_n5##y,z,c), I[334] = (T)(img)(_n9##x,_n5##y,z,c), I[335] = (T)(img)(_n10##x,_n5##y,z,c), \ - I[336] = (T)(img)(_p10##x,_n6##y,z,c), I[337] = (T)(img)(_p9##x,_n6##y,z,c), I[338] = (T)(img)(_p8##x,_n6##y,z,c), I[339] = (T)(img)(_p7##x,_n6##y,z,c), I[340] = (T)(img)(_p6##x,_n6##y,z,c), I[341] = (T)(img)(_p5##x,_n6##y,z,c), I[342] = (T)(img)(_p4##x,_n6##y,z,c), I[343] = (T)(img)(_p3##x,_n6##y,z,c), I[344] = (T)(img)(_p2##x,_n6##y,z,c), I[345] = (T)(img)(_p1##x,_n6##y,z,c), I[346] = (T)(img)(x,_n6##y,z,c), I[347] = (T)(img)(_n1##x,_n6##y,z,c), I[348] = (T)(img)(_n2##x,_n6##y,z,c), I[349] = (T)(img)(_n3##x,_n6##y,z,c), I[350] = (T)(img)(_n4##x,_n6##y,z,c), I[351] = (T)(img)(_n5##x,_n6##y,z,c), I[352] = (T)(img)(_n6##x,_n6##y,z,c), I[353] = (T)(img)(_n7##x,_n6##y,z,c), I[354] = (T)(img)(_n8##x,_n6##y,z,c), I[355] = (T)(img)(_n9##x,_n6##y,z,c), I[356] = (T)(img)(_n10##x,_n6##y,z,c), \ - I[357] = (T)(img)(_p10##x,_n7##y,z,c), I[358] = (T)(img)(_p9##x,_n7##y,z,c), I[359] = (T)(img)(_p8##x,_n7##y,z,c), I[360] = (T)(img)(_p7##x,_n7##y,z,c), I[361] = (T)(img)(_p6##x,_n7##y,z,c), I[362] = (T)(img)(_p5##x,_n7##y,z,c), I[363] = (T)(img)(_p4##x,_n7##y,z,c), I[364] = (T)(img)(_p3##x,_n7##y,z,c), I[365] = (T)(img)(_p2##x,_n7##y,z,c), I[366] = (T)(img)(_p1##x,_n7##y,z,c), I[367] = (T)(img)(x,_n7##y,z,c), I[368] = (T)(img)(_n1##x,_n7##y,z,c), I[369] = (T)(img)(_n2##x,_n7##y,z,c), I[370] = (T)(img)(_n3##x,_n7##y,z,c), I[371] = (T)(img)(_n4##x,_n7##y,z,c), I[372] = (T)(img)(_n5##x,_n7##y,z,c), I[373] = (T)(img)(_n6##x,_n7##y,z,c), I[374] = (T)(img)(_n7##x,_n7##y,z,c), I[375] = (T)(img)(_n8##x,_n7##y,z,c), I[376] = (T)(img)(_n9##x,_n7##y,z,c), I[377] = (T)(img)(_n10##x,_n7##y,z,c), \ - I[378] = (T)(img)(_p10##x,_n8##y,z,c), I[379] = (T)(img)(_p9##x,_n8##y,z,c), I[380] = (T)(img)(_p8##x,_n8##y,z,c), I[381] = (T)(img)(_p7##x,_n8##y,z,c), I[382] = (T)(img)(_p6##x,_n8##y,z,c), I[383] = (T)(img)(_p5##x,_n8##y,z,c), I[384] = (T)(img)(_p4##x,_n8##y,z,c), I[385] = (T)(img)(_p3##x,_n8##y,z,c), I[386] = (T)(img)(_p2##x,_n8##y,z,c), I[387] = (T)(img)(_p1##x,_n8##y,z,c), I[388] = (T)(img)(x,_n8##y,z,c), I[389] = (T)(img)(_n1##x,_n8##y,z,c), I[390] = (T)(img)(_n2##x,_n8##y,z,c), I[391] = (T)(img)(_n3##x,_n8##y,z,c), I[392] = (T)(img)(_n4##x,_n8##y,z,c), I[393] = (T)(img)(_n5##x,_n8##y,z,c), I[394] = (T)(img)(_n6##x,_n8##y,z,c), I[395] = (T)(img)(_n7##x,_n8##y,z,c), I[396] = (T)(img)(_n8##x,_n8##y,z,c), I[397] = (T)(img)(_n9##x,_n8##y,z,c), I[398] = (T)(img)(_n10##x,_n8##y,z,c), \ - I[399] = (T)(img)(_p10##x,_n9##y,z,c), I[400] = (T)(img)(_p9##x,_n9##y,z,c), I[401] = (T)(img)(_p8##x,_n9##y,z,c), I[402] = (T)(img)(_p7##x,_n9##y,z,c), I[403] = (T)(img)(_p6##x,_n9##y,z,c), I[404] = (T)(img)(_p5##x,_n9##y,z,c), I[405] = (T)(img)(_p4##x,_n9##y,z,c), I[406] = (T)(img)(_p3##x,_n9##y,z,c), I[407] = (T)(img)(_p2##x,_n9##y,z,c), I[408] = (T)(img)(_p1##x,_n9##y,z,c), I[409] = (T)(img)(x,_n9##y,z,c), I[410] = (T)(img)(_n1##x,_n9##y,z,c), I[411] = (T)(img)(_n2##x,_n9##y,z,c), I[412] = (T)(img)(_n3##x,_n9##y,z,c), I[413] = (T)(img)(_n4##x,_n9##y,z,c), I[414] = (T)(img)(_n5##x,_n9##y,z,c), I[415] = (T)(img)(_n6##x,_n9##y,z,c), I[416] = (T)(img)(_n7##x,_n9##y,z,c), I[417] = (T)(img)(_n8##x,_n9##y,z,c), I[418] = (T)(img)(_n9##x,_n9##y,z,c), I[419] = (T)(img)(_n10##x,_n9##y,z,c), \ - I[420] = (T)(img)(_p10##x,_n10##y,z,c), I[421] = (T)(img)(_p9##x,_n10##y,z,c), I[422] = (T)(img)(_p8##x,_n10##y,z,c), I[423] = (T)(img)(_p7##x,_n10##y,z,c), I[424] = (T)(img)(_p6##x,_n10##y,z,c), I[425] = (T)(img)(_p5##x,_n10##y,z,c), I[426] = (T)(img)(_p4##x,_n10##y,z,c), I[427] = (T)(img)(_p3##x,_n10##y,z,c), I[428] = (T)(img)(_p2##x,_n10##y,z,c), I[429] = (T)(img)(_p1##x,_n10##y,z,c), I[430] = (T)(img)(x,_n10##y,z,c), I[431] = (T)(img)(_n1##x,_n10##y,z,c), I[432] = (T)(img)(_n2##x,_n10##y,z,c), I[433] = (T)(img)(_n3##x,_n10##y,z,c), I[434] = (T)(img)(_n4##x,_n10##y,z,c), I[435] = (T)(img)(_n5##x,_n10##y,z,c), I[436] = (T)(img)(_n6##x,_n10##y,z,c), I[437] = (T)(img)(_n7##x,_n10##y,z,c), I[438] = (T)(img)(_n8##x,_n10##y,z,c), I[439] = (T)(img)(_n9##x,_n10##y,z,c), I[440] = (T)(img)(_n10##x,_n10##y,z,c); - -// Define 22x22 loop macros -//------------------------- -#define cimg_for22(bound,i) for (int i = 0, \ - _p10##i = 0, _p9##i = 0, _p8##i = 0, _p7##i = 0, _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6, \ - _n7##i = 7>=(int)(bound)?(int)(bound) - 1:7, \ - _n8##i = 8>=(int)(bound)?(int)(bound) - 1:8, \ - _n9##i = 9>=(int)(bound)?(int)(bound) - 1:9, \ - _n10##i = 10>=(int)(bound)?(int)(bound) - 1:10, \ - _n11##i = 11>=(int)(bound)?(int)(bound) - 1:11; \ - _n11##i<(int)(bound) || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i) - -#define cimg_for22X(img,x) cimg_for22((img)._width,x) -#define cimg_for22Y(img,y) cimg_for22((img)._height,y) -#define cimg_for22Z(img,z) cimg_for22((img)._depth,z) -#define cimg_for22C(img,c) cimg_for22((img)._spectrum,c) -#define cimg_for22XY(img,x,y) cimg_for22Y(img,y) cimg_for22X(img,x) -#define cimg_for22XZ(img,x,z) cimg_for22Z(img,z) cimg_for22X(img,x) -#define cimg_for22XC(img,x,c) cimg_for22C(img,c) cimg_for22X(img,x) -#define cimg_for22YZ(img,y,z) cimg_for22Z(img,z) cimg_for22Y(img,y) -#define cimg_for22YC(img,y,c) cimg_for22C(img,c) cimg_for22Y(img,y) -#define cimg_for22ZC(img,z,c) cimg_for22C(img,c) cimg_for22Z(img,z) -#define cimg_for22XYZ(img,x,y,z) cimg_for22Z(img,z) cimg_for22XY(img,x,y) -#define cimg_for22XZC(img,x,z,c) cimg_for22C(img,c) cimg_for22XZ(img,x,z) -#define cimg_for22YZC(img,y,z,c) cimg_for22C(img,c) cimg_for22YZ(img,y,z) -#define cimg_for22XYZC(img,x,y,z,c) cimg_for22C(img,c) cimg_for22XYZ(img,x,y,z) - -#define cimg_for_in22(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p10##i = i - 10<0?0:i - 10, \ - _p9##i = i - 9<0?0:i - 9, \ - _p8##i = i - 8<0?0:i - 8, \ - _p7##i = i - 7<0?0:i - 7, \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6, \ - _n7##i = i + 7>=(int)(bound)?(int)(bound) - 1:i + 7, \ - _n8##i = i + 8>=(int)(bound)?(int)(bound) - 1:i + 8, \ - _n9##i = i + 9>=(int)(bound)?(int)(bound) - 1:i + 9, \ - _n10##i = i + 10>=(int)(bound)?(int)(bound) - 1:i + 10, \ - _n11##i = i + 11>=(int)(bound)?(int)(bound) - 1:i + 11; \ - i<=(int)(i1) && (_n11##i<(int)(bound) || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i) - -#define cimg_for_in22X(img,x0,x1,x) cimg_for_in22((img)._width,x0,x1,x) -#define cimg_for_in22Y(img,y0,y1,y) cimg_for_in22((img)._height,y0,y1,y) -#define cimg_for_in22Z(img,z0,z1,z) cimg_for_in22((img)._depth,z0,z1,z) -#define cimg_for_in22C(img,c0,c1,c) cimg_for_in22((img)._spectrum,c0,c1,c) -#define cimg_for_in22XY(img,x0,y0,x1,y1,x,y) cimg_for_in22Y(img,y0,y1,y) cimg_for_in22X(img,x0,x1,x) -#define cimg_for_in22XZ(img,x0,z0,x1,z1,x,z) cimg_for_in22Z(img,z0,z1,z) cimg_for_in22X(img,x0,x1,x) -#define cimg_for_in22XC(img,x0,c0,x1,c1,x,c) cimg_for_in22C(img,c0,c1,c) cimg_for_in22X(img,x0,x1,x) -#define cimg_for_in22YZ(img,y0,z0,y1,z1,y,z) cimg_for_in22Z(img,z0,z1,z) cimg_for_in22Y(img,y0,y1,y) -#define cimg_for_in22YC(img,y0,c0,y1,c1,y,c) cimg_for_in22C(img,c0,c1,c) cimg_for_in22Y(img,y0,y1,y) -#define cimg_for_in22ZC(img,z0,c0,z1,c1,z,c) cimg_for_in22C(img,c0,c1,c) cimg_for_in22Z(img,z0,z1,z) -#define cimg_for_in22XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in22Z(img,z0,z1,z) cimg_for_in22XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in22XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in22C(img,c0,c1,c) cimg_for_in22XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in22YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in22C(img,c0,c1,c) cimg_for_in22YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in22XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in22C(img,c0,c1,c) cimg_for_in22XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for22x22(img,x,y,z,c,I,T) \ - cimg_for22((img)._height,y) for (int x = 0, \ - _p10##x = 0, _p9##x = 0, _p8##x = 0, _p7##x = 0, _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = 6>=((img)._width)?(img).width() - 1:6, \ - _n7##x = 7>=((img)._width)?(img).width() - 1:7, \ - _n8##x = 8>=((img)._width)?(img).width() - 1:8, \ - _n9##x = 9>=((img)._width)?(img).width() - 1:9, \ - _n10##x = 10>=((img)._width)?(img).width() - 1:10, \ - _n11##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = I[7] = I[8] = I[9] = I[10] = (T)(img)(0,_p10##y,z,c)), \ - (I[22] = I[23] = I[24] = I[25] = I[26] = I[27] = I[28] = I[29] = I[30] = I[31] = I[32] = (T)(img)(0,_p9##y,z,c)), \ - (I[44] = I[45] = I[46] = I[47] = I[48] = I[49] = I[50] = I[51] = I[52] = I[53] = I[54] = (T)(img)(0,_p8##y,z,c)), \ - (I[66] = I[67] = I[68] = I[69] = I[70] = I[71] = I[72] = I[73] = I[74] = I[75] = I[76] = (T)(img)(0,_p7##y,z,c)), \ - (I[88] = I[89] = I[90] = I[91] = I[92] = I[93] = I[94] = I[95] = I[96] = I[97] = I[98] = (T)(img)(0,_p6##y,z,c)), \ - (I[110] = I[111] = I[112] = I[113] = I[114] = I[115] = I[116] = I[117] = I[118] = I[119] = I[120] = (T)(img)(0,_p5##y,z,c)), \ - (I[132] = I[133] = I[134] = I[135] = I[136] = I[137] = I[138] = I[139] = I[140] = I[141] = I[142] = (T)(img)(0,_p4##y,z,c)), \ - (I[154] = I[155] = I[156] = I[157] = I[158] = I[159] = I[160] = I[161] = I[162] = I[163] = I[164] = (T)(img)(0,_p3##y,z,c)), \ - (I[176] = I[177] = I[178] = I[179] = I[180] = I[181] = I[182] = I[183] = I[184] = I[185] = I[186] = (T)(img)(0,_p2##y,z,c)), \ - (I[198] = I[199] = I[200] = I[201] = I[202] = I[203] = I[204] = I[205] = I[206] = I[207] = I[208] = (T)(img)(0,_p1##y,z,c)), \ - (I[220] = I[221] = I[222] = I[223] = I[224] = I[225] = I[226] = I[227] = I[228] = I[229] = I[230] = (T)(img)(0,y,z,c)), \ - (I[242] = I[243] = I[244] = I[245] = I[246] = I[247] = I[248] = I[249] = I[250] = I[251] = I[252] = (T)(img)(0,_n1##y,z,c)), \ - (I[264] = I[265] = I[266] = I[267] = I[268] = I[269] = I[270] = I[271] = I[272] = I[273] = I[274] = (T)(img)(0,_n2##y,z,c)), \ - (I[286] = I[287] = I[288] = I[289] = I[290] = I[291] = I[292] = I[293] = I[294] = I[295] = I[296] = (T)(img)(0,_n3##y,z,c)), \ - (I[308] = I[309] = I[310] = I[311] = I[312] = I[313] = I[314] = I[315] = I[316] = I[317] = I[318] = (T)(img)(0,_n4##y,z,c)), \ - (I[330] = I[331] = I[332] = I[333] = I[334] = I[335] = I[336] = I[337] = I[338] = I[339] = I[340] = (T)(img)(0,_n5##y,z,c)), \ - (I[352] = I[353] = I[354] = I[355] = I[356] = I[357] = I[358] = I[359] = I[360] = I[361] = I[362] = (T)(img)(0,_n6##y,z,c)), \ - (I[374] = I[375] = I[376] = I[377] = I[378] = I[379] = I[380] = I[381] = I[382] = I[383] = I[384] = (T)(img)(0,_n7##y,z,c)), \ - (I[396] = I[397] = I[398] = I[399] = I[400] = I[401] = I[402] = I[403] = I[404] = I[405] = I[406] = (T)(img)(0,_n8##y,z,c)), \ - (I[418] = I[419] = I[420] = I[421] = I[422] = I[423] = I[424] = I[425] = I[426] = I[427] = I[428] = (T)(img)(0,_n9##y,z,c)), \ - (I[440] = I[441] = I[442] = I[443] = I[444] = I[445] = I[446] = I[447] = I[448] = I[449] = I[450] = (T)(img)(0,_n10##y,z,c)), \ - (I[462] = I[463] = I[464] = I[465] = I[466] = I[467] = I[468] = I[469] = I[470] = I[471] = I[472] = (T)(img)(0,_n11##y,z,c)), \ - (I[11] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[33] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[55] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[77] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[99] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[121] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[143] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[165] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[187] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[209] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[231] = (T)(img)(_n1##x,y,z,c)), \ - (I[253] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[275] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[297] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[319] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[341] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[363] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[385] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[407] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[429] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[451] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[473] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[12] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[34] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[56] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[78] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[100] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[122] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[144] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[166] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[188] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[210] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[232] = (T)(img)(_n2##x,y,z,c)), \ - (I[254] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[276] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[298] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[320] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[342] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[364] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[386] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[408] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[430] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[452] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[474] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[13] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[35] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[57] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[79] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[101] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[123] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[145] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[167] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[189] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[211] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[233] = (T)(img)(_n3##x,y,z,c)), \ - (I[255] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[277] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[299] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[321] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[343] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[365] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[387] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[409] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[431] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[453] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[475] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[14] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[36] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[58] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[80] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[102] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[124] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[146] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[168] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[190] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[212] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[234] = (T)(img)(_n4##x,y,z,c)), \ - (I[256] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[278] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[300] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[322] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[344] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[366] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[388] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[410] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[432] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[454] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[476] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[15] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[37] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[59] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[81] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[103] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[125] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[147] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[169] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[191] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[213] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[235] = (T)(img)(_n5##x,y,z,c)), \ - (I[257] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[279] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[301] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[323] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[345] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[367] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[389] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[411] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[433] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[455] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[477] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[16] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[38] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[60] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[82] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[104] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[126] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[148] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[170] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[192] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[214] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[236] = (T)(img)(_n6##x,y,z,c)), \ - (I[258] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[280] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[302] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[324] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[346] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[368] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[390] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[412] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[434] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[456] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[478] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[17] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[39] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[61] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[83] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[105] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[127] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[149] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[171] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[193] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[215] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[237] = (T)(img)(_n7##x,y,z,c)), \ - (I[259] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[281] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[303] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[325] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[347] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[369] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[391] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[413] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[435] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[457] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[479] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[18] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[40] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[62] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[84] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[106] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[128] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[150] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[172] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[194] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[216] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[238] = (T)(img)(_n8##x,y,z,c)), \ - (I[260] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[282] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[304] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[326] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[348] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[370] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[392] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[414] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[436] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[458] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[480] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[19] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[41] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[63] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[85] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[107] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[129] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[151] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[173] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[195] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[217] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[239] = (T)(img)(_n9##x,y,z,c)), \ - (I[261] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[283] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[305] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[327] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[349] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[371] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[393] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[415] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[437] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[459] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[481] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[20] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[42] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[64] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[86] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[108] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[130] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[152] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[174] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[196] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[218] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[240] = (T)(img)(_n10##x,y,z,c)), \ - (I[262] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[284] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[306] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[328] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[350] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[372] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[394] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[416] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[438] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[460] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[482] = (T)(img)(_n10##x,_n11##y,z,c)), \ - 11>=((img)._width)?(img).width() - 1:11); \ - (_n11##x<(img).width() && ( \ - (I[21] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[43] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[65] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[87] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[109] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[131] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[153] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[175] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[197] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[219] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[241] = (T)(img)(_n11##x,y,z,c)), \ - (I[263] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[285] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[307] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[329] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[351] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[373] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[395] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[417] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[439] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[461] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[483] = (T)(img)(_n11##x,_n11##y,z,c)),1)) || \ - _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], \ - I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], \ - I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], \ - I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], \ - I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], \ - I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], \ - I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], \ - I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], \ - I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], \ - I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], \ - I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], \ - I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], \ - I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], \ - I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], \ - I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], \ - I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], \ - I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], \ - I[374] = I[375], I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], \ - I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], I[415] = I[416], I[416] = I[417], \ - I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], \ - I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], I[447] = I[448], I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], \ - I[462] = I[463], I[463] = I[464], I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], I[479] = I[480], I[480] = I[481], I[481] = I[482], I[482] = I[483], \ - _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x) - -#define cimg_for_in22x22(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in22((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p10##x = x - 10<0?0:x - 10, \ - _p9##x = x - 9<0?0:x - 9, \ - _p8##x = x - 8<0?0:x - 8, \ - _p7##x = x - 7<0?0:x - 7, \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = x + 6>=(img).width()?(img).width() - 1:x + 6, \ - _n7##x = x + 7>=(img).width()?(img).width() - 1:x + 7, \ - _n8##x = x + 8>=(img).width()?(img).width() - 1:x + 8, \ - _n9##x = x + 9>=(img).width()?(img).width() - 1:x + 9, \ - _n10##x = x + 10>=(img).width()?(img).width() - 1:x + 10, \ - _n11##x = (int)( \ - (I[0] = (T)(img)(_p10##x,_p10##y,z,c)), \ - (I[22] = (T)(img)(_p10##x,_p9##y,z,c)), \ - (I[44] = (T)(img)(_p10##x,_p8##y,z,c)), \ - (I[66] = (T)(img)(_p10##x,_p7##y,z,c)), \ - (I[88] = (T)(img)(_p10##x,_p6##y,z,c)), \ - (I[110] = (T)(img)(_p10##x,_p5##y,z,c)), \ - (I[132] = (T)(img)(_p10##x,_p4##y,z,c)), \ - (I[154] = (T)(img)(_p10##x,_p3##y,z,c)), \ - (I[176] = (T)(img)(_p10##x,_p2##y,z,c)), \ - (I[198] = (T)(img)(_p10##x,_p1##y,z,c)), \ - (I[220] = (T)(img)(_p10##x,y,z,c)), \ - (I[242] = (T)(img)(_p10##x,_n1##y,z,c)), \ - (I[264] = (T)(img)(_p10##x,_n2##y,z,c)), \ - (I[286] = (T)(img)(_p10##x,_n3##y,z,c)), \ - (I[308] = (T)(img)(_p10##x,_n4##y,z,c)), \ - (I[330] = (T)(img)(_p10##x,_n5##y,z,c)), \ - (I[352] = (T)(img)(_p10##x,_n6##y,z,c)), \ - (I[374] = (T)(img)(_p10##x,_n7##y,z,c)), \ - (I[396] = (T)(img)(_p10##x,_n8##y,z,c)), \ - (I[418] = (T)(img)(_p10##x,_n9##y,z,c)), \ - (I[440] = (T)(img)(_p10##x,_n10##y,z,c)), \ - (I[462] = (T)(img)(_p10##x,_n11##y,z,c)), \ - (I[1] = (T)(img)(_p9##x,_p10##y,z,c)), \ - (I[23] = (T)(img)(_p9##x,_p9##y,z,c)), \ - (I[45] = (T)(img)(_p9##x,_p8##y,z,c)), \ - (I[67] = (T)(img)(_p9##x,_p7##y,z,c)), \ - (I[89] = (T)(img)(_p9##x,_p6##y,z,c)), \ - (I[111] = (T)(img)(_p9##x,_p5##y,z,c)), \ - (I[133] = (T)(img)(_p9##x,_p4##y,z,c)), \ - (I[155] = (T)(img)(_p9##x,_p3##y,z,c)), \ - (I[177] = (T)(img)(_p9##x,_p2##y,z,c)), \ - (I[199] = (T)(img)(_p9##x,_p1##y,z,c)), \ - (I[221] = (T)(img)(_p9##x,y,z,c)), \ - (I[243] = (T)(img)(_p9##x,_n1##y,z,c)), \ - (I[265] = (T)(img)(_p9##x,_n2##y,z,c)), \ - (I[287] = (T)(img)(_p9##x,_n3##y,z,c)), \ - (I[309] = (T)(img)(_p9##x,_n4##y,z,c)), \ - (I[331] = (T)(img)(_p9##x,_n5##y,z,c)), \ - (I[353] = (T)(img)(_p9##x,_n6##y,z,c)), \ - (I[375] = (T)(img)(_p9##x,_n7##y,z,c)), \ - (I[397] = (T)(img)(_p9##x,_n8##y,z,c)), \ - (I[419] = (T)(img)(_p9##x,_n9##y,z,c)), \ - (I[441] = (T)(img)(_p9##x,_n10##y,z,c)), \ - (I[463] = (T)(img)(_p9##x,_n11##y,z,c)), \ - (I[2] = (T)(img)(_p8##x,_p10##y,z,c)), \ - (I[24] = (T)(img)(_p8##x,_p9##y,z,c)), \ - (I[46] = (T)(img)(_p8##x,_p8##y,z,c)), \ - (I[68] = (T)(img)(_p8##x,_p7##y,z,c)), \ - (I[90] = (T)(img)(_p8##x,_p6##y,z,c)), \ - (I[112] = (T)(img)(_p8##x,_p5##y,z,c)), \ - (I[134] = (T)(img)(_p8##x,_p4##y,z,c)), \ - (I[156] = (T)(img)(_p8##x,_p3##y,z,c)), \ - (I[178] = (T)(img)(_p8##x,_p2##y,z,c)), \ - (I[200] = (T)(img)(_p8##x,_p1##y,z,c)), \ - (I[222] = (T)(img)(_p8##x,y,z,c)), \ - (I[244] = (T)(img)(_p8##x,_n1##y,z,c)), \ - (I[266] = (T)(img)(_p8##x,_n2##y,z,c)), \ - (I[288] = (T)(img)(_p8##x,_n3##y,z,c)), \ - (I[310] = (T)(img)(_p8##x,_n4##y,z,c)), \ - (I[332] = (T)(img)(_p8##x,_n5##y,z,c)), \ - (I[354] = (T)(img)(_p8##x,_n6##y,z,c)), \ - (I[376] = (T)(img)(_p8##x,_n7##y,z,c)), \ - (I[398] = (T)(img)(_p8##x,_n8##y,z,c)), \ - (I[420] = (T)(img)(_p8##x,_n9##y,z,c)), \ - (I[442] = (T)(img)(_p8##x,_n10##y,z,c)), \ - (I[464] = (T)(img)(_p8##x,_n11##y,z,c)), \ - (I[3] = (T)(img)(_p7##x,_p10##y,z,c)), \ - (I[25] = (T)(img)(_p7##x,_p9##y,z,c)), \ - (I[47] = (T)(img)(_p7##x,_p8##y,z,c)), \ - (I[69] = (T)(img)(_p7##x,_p7##y,z,c)), \ - (I[91] = (T)(img)(_p7##x,_p6##y,z,c)), \ - (I[113] = (T)(img)(_p7##x,_p5##y,z,c)), \ - (I[135] = (T)(img)(_p7##x,_p4##y,z,c)), \ - (I[157] = (T)(img)(_p7##x,_p3##y,z,c)), \ - (I[179] = (T)(img)(_p7##x,_p2##y,z,c)), \ - (I[201] = (T)(img)(_p7##x,_p1##y,z,c)), \ - (I[223] = (T)(img)(_p7##x,y,z,c)), \ - (I[245] = (T)(img)(_p7##x,_n1##y,z,c)), \ - (I[267] = (T)(img)(_p7##x,_n2##y,z,c)), \ - (I[289] = (T)(img)(_p7##x,_n3##y,z,c)), \ - (I[311] = (T)(img)(_p7##x,_n4##y,z,c)), \ - (I[333] = (T)(img)(_p7##x,_n5##y,z,c)), \ - (I[355] = (T)(img)(_p7##x,_n6##y,z,c)), \ - (I[377] = (T)(img)(_p7##x,_n7##y,z,c)), \ - (I[399] = (T)(img)(_p7##x,_n8##y,z,c)), \ - (I[421] = (T)(img)(_p7##x,_n9##y,z,c)), \ - (I[443] = (T)(img)(_p7##x,_n10##y,z,c)), \ - (I[465] = (T)(img)(_p7##x,_n11##y,z,c)), \ - (I[4] = (T)(img)(_p6##x,_p10##y,z,c)), \ - (I[26] = (T)(img)(_p6##x,_p9##y,z,c)), \ - (I[48] = (T)(img)(_p6##x,_p8##y,z,c)), \ - (I[70] = (T)(img)(_p6##x,_p7##y,z,c)), \ - (I[92] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[114] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[136] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[158] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[180] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[202] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[224] = (T)(img)(_p6##x,y,z,c)), \ - (I[246] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[268] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[290] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[312] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[334] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[356] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[378] = (T)(img)(_p6##x,_n7##y,z,c)), \ - (I[400] = (T)(img)(_p6##x,_n8##y,z,c)), \ - (I[422] = (T)(img)(_p6##x,_n9##y,z,c)), \ - (I[444] = (T)(img)(_p6##x,_n10##y,z,c)), \ - (I[466] = (T)(img)(_p6##x,_n11##y,z,c)), \ - (I[5] = (T)(img)(_p5##x,_p10##y,z,c)), \ - (I[27] = (T)(img)(_p5##x,_p9##y,z,c)), \ - (I[49] = (T)(img)(_p5##x,_p8##y,z,c)), \ - (I[71] = (T)(img)(_p5##x,_p7##y,z,c)), \ - (I[93] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[115] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[137] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[159] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[181] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[203] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[225] = (T)(img)(_p5##x,y,z,c)), \ - (I[247] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[269] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[291] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[313] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[335] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[357] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[379] = (T)(img)(_p5##x,_n7##y,z,c)), \ - (I[401] = (T)(img)(_p5##x,_n8##y,z,c)), \ - (I[423] = (T)(img)(_p5##x,_n9##y,z,c)), \ - (I[445] = (T)(img)(_p5##x,_n10##y,z,c)), \ - (I[467] = (T)(img)(_p5##x,_n11##y,z,c)), \ - (I[6] = (T)(img)(_p4##x,_p10##y,z,c)), \ - (I[28] = (T)(img)(_p4##x,_p9##y,z,c)), \ - (I[50] = (T)(img)(_p4##x,_p8##y,z,c)), \ - (I[72] = (T)(img)(_p4##x,_p7##y,z,c)), \ - (I[94] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[116] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[138] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[160] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[182] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[204] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[226] = (T)(img)(_p4##x,y,z,c)), \ - (I[248] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[270] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[292] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[314] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[336] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[358] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[380] = (T)(img)(_p4##x,_n7##y,z,c)), \ - (I[402] = (T)(img)(_p4##x,_n8##y,z,c)), \ - (I[424] = (T)(img)(_p4##x,_n9##y,z,c)), \ - (I[446] = (T)(img)(_p4##x,_n10##y,z,c)), \ - (I[468] = (T)(img)(_p4##x,_n11##y,z,c)), \ - (I[7] = (T)(img)(_p3##x,_p10##y,z,c)), \ - (I[29] = (T)(img)(_p3##x,_p9##y,z,c)), \ - (I[51] = (T)(img)(_p3##x,_p8##y,z,c)), \ - (I[73] = (T)(img)(_p3##x,_p7##y,z,c)), \ - (I[95] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[117] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[139] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[161] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[183] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[205] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[227] = (T)(img)(_p3##x,y,z,c)), \ - (I[249] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[271] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[293] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[315] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[337] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[359] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[381] = (T)(img)(_p3##x,_n7##y,z,c)), \ - (I[403] = (T)(img)(_p3##x,_n8##y,z,c)), \ - (I[425] = (T)(img)(_p3##x,_n9##y,z,c)), \ - (I[447] = (T)(img)(_p3##x,_n10##y,z,c)), \ - (I[469] = (T)(img)(_p3##x,_n11##y,z,c)), \ - (I[8] = (T)(img)(_p2##x,_p10##y,z,c)), \ - (I[30] = (T)(img)(_p2##x,_p9##y,z,c)), \ - (I[52] = (T)(img)(_p2##x,_p8##y,z,c)), \ - (I[74] = (T)(img)(_p2##x,_p7##y,z,c)), \ - (I[96] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[118] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[140] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[162] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[184] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[206] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[228] = (T)(img)(_p2##x,y,z,c)), \ - (I[250] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[272] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[294] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[316] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[338] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[360] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[382] = (T)(img)(_p2##x,_n7##y,z,c)), \ - (I[404] = (T)(img)(_p2##x,_n8##y,z,c)), \ - (I[426] = (T)(img)(_p2##x,_n9##y,z,c)), \ - (I[448] = (T)(img)(_p2##x,_n10##y,z,c)), \ - (I[470] = (T)(img)(_p2##x,_n11##y,z,c)), \ - (I[9] = (T)(img)(_p1##x,_p10##y,z,c)), \ - (I[31] = (T)(img)(_p1##x,_p9##y,z,c)), \ - (I[53] = (T)(img)(_p1##x,_p8##y,z,c)), \ - (I[75] = (T)(img)(_p1##x,_p7##y,z,c)), \ - (I[97] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[119] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[141] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[163] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[185] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[207] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[229] = (T)(img)(_p1##x,y,z,c)), \ - (I[251] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[273] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[295] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[317] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[339] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[361] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[383] = (T)(img)(_p1##x,_n7##y,z,c)), \ - (I[405] = (T)(img)(_p1##x,_n8##y,z,c)), \ - (I[427] = (T)(img)(_p1##x,_n9##y,z,c)), \ - (I[449] = (T)(img)(_p1##x,_n10##y,z,c)), \ - (I[471] = (T)(img)(_p1##x,_n11##y,z,c)), \ - (I[10] = (T)(img)(x,_p10##y,z,c)), \ - (I[32] = (T)(img)(x,_p9##y,z,c)), \ - (I[54] = (T)(img)(x,_p8##y,z,c)), \ - (I[76] = (T)(img)(x,_p7##y,z,c)), \ - (I[98] = (T)(img)(x,_p6##y,z,c)), \ - (I[120] = (T)(img)(x,_p5##y,z,c)), \ - (I[142] = (T)(img)(x,_p4##y,z,c)), \ - (I[164] = (T)(img)(x,_p3##y,z,c)), \ - (I[186] = (T)(img)(x,_p2##y,z,c)), \ - (I[208] = (T)(img)(x,_p1##y,z,c)), \ - (I[230] = (T)(img)(x,y,z,c)), \ - (I[252] = (T)(img)(x,_n1##y,z,c)), \ - (I[274] = (T)(img)(x,_n2##y,z,c)), \ - (I[296] = (T)(img)(x,_n3##y,z,c)), \ - (I[318] = (T)(img)(x,_n4##y,z,c)), \ - (I[340] = (T)(img)(x,_n5##y,z,c)), \ - (I[362] = (T)(img)(x,_n6##y,z,c)), \ - (I[384] = (T)(img)(x,_n7##y,z,c)), \ - (I[406] = (T)(img)(x,_n8##y,z,c)), \ - (I[428] = (T)(img)(x,_n9##y,z,c)), \ - (I[450] = (T)(img)(x,_n10##y,z,c)), \ - (I[472] = (T)(img)(x,_n11##y,z,c)), \ - (I[11] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[33] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[55] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[77] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[99] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[121] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[143] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[165] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[187] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[209] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[231] = (T)(img)(_n1##x,y,z,c)), \ - (I[253] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[275] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[297] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[319] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[341] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[363] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[385] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[407] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[429] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[451] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[473] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[12] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[34] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[56] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[78] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[100] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[122] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[144] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[166] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[188] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[210] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[232] = (T)(img)(_n2##x,y,z,c)), \ - (I[254] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[276] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[298] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[320] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[342] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[364] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[386] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[408] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[430] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[452] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[474] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[13] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[35] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[57] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[79] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[101] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[123] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[145] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[167] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[189] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[211] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[233] = (T)(img)(_n3##x,y,z,c)), \ - (I[255] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[277] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[299] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[321] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[343] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[365] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[387] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[409] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[431] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[453] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[475] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[14] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[36] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[58] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[80] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[102] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[124] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[146] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[168] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[190] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[212] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[234] = (T)(img)(_n4##x,y,z,c)), \ - (I[256] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[278] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[300] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[322] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[344] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[366] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[388] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[410] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[432] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[454] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[476] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[15] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[37] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[59] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[81] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[103] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[125] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[147] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[169] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[191] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[213] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[235] = (T)(img)(_n5##x,y,z,c)), \ - (I[257] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[279] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[301] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[323] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[345] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[367] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[389] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[411] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[433] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[455] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[477] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[16] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[38] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[60] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[82] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[104] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[126] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[148] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[170] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[192] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[214] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[236] = (T)(img)(_n6##x,y,z,c)), \ - (I[258] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[280] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[302] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[324] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[346] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[368] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[390] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[412] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[434] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[456] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[478] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[17] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[39] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[61] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[83] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[105] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[127] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[149] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[171] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[193] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[215] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[237] = (T)(img)(_n7##x,y,z,c)), \ - (I[259] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[281] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[303] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[325] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[347] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[369] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[391] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[413] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[435] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[457] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[479] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[18] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[40] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[62] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[84] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[106] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[128] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[150] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[172] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[194] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[216] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[238] = (T)(img)(_n8##x,y,z,c)), \ - (I[260] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[282] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[304] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[326] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[348] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[370] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[392] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[414] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[436] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[458] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[480] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[19] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[41] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[63] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[85] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[107] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[129] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[151] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[173] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[195] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[217] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[239] = (T)(img)(_n9##x,y,z,c)), \ - (I[261] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[283] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[305] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[327] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[349] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[371] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[393] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[415] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[437] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[459] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[481] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[20] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[42] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[64] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[86] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[108] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[130] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[152] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[174] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[196] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[218] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[240] = (T)(img)(_n10##x,y,z,c)), \ - (I[262] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[284] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[306] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[328] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[350] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[372] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[394] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[416] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[438] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[460] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[482] = (T)(img)(_n10##x,_n11##y,z,c)), \ - x + 11>=(img).width()?(img).width() - 1:x + 11); \ - x<=(int)(x1) && ((_n11##x<(img).width() && ( \ - (I[21] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[43] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[65] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[87] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[109] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[131] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[153] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[175] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[197] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[219] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[241] = (T)(img)(_n11##x,y,z,c)), \ - (I[263] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[285] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[307] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[329] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[351] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[373] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[395] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[417] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[439] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[461] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[483] = (T)(img)(_n11##x,_n11##y,z,c)),1)) || \ - _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], \ - I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], \ - I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], \ - I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], \ - I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], \ - I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], \ - I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], \ - I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], \ - I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], \ - I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], \ - I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], \ - I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], \ - I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], \ - I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], \ - I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], \ - I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], \ - I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], \ - I[374] = I[375], I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], \ - I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], I[415] = I[416], I[416] = I[417], \ - I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], \ - I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], I[447] = I[448], I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], \ - I[462] = I[463], I[463] = I[464], I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], I[479] = I[480], I[480] = I[481], I[481] = I[482], I[482] = I[483], \ - _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x) - -#define cimg_get22x22(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p10##x,_p10##y,z,c), I[1] = (T)(img)(_p9##x,_p10##y,z,c), I[2] = (T)(img)(_p8##x,_p10##y,z,c), I[3] = (T)(img)(_p7##x,_p10##y,z,c), I[4] = (T)(img)(_p6##x,_p10##y,z,c), I[5] = (T)(img)(_p5##x,_p10##y,z,c), I[6] = (T)(img)(_p4##x,_p10##y,z,c), I[7] = (T)(img)(_p3##x,_p10##y,z,c), I[8] = (T)(img)(_p2##x,_p10##y,z,c), I[9] = (T)(img)(_p1##x,_p10##y,z,c), I[10] = (T)(img)(x,_p10##y,z,c), I[11] = (T)(img)(_n1##x,_p10##y,z,c), I[12] = (T)(img)(_n2##x,_p10##y,z,c), I[13] = (T)(img)(_n3##x,_p10##y,z,c), I[14] = (T)(img)(_n4##x,_p10##y,z,c), I[15] = (T)(img)(_n5##x,_p10##y,z,c), I[16] = (T)(img)(_n6##x,_p10##y,z,c), I[17] = (T)(img)(_n7##x,_p10##y,z,c), I[18] = (T)(img)(_n8##x,_p10##y,z,c), I[19] = (T)(img)(_n9##x,_p10##y,z,c), I[20] = (T)(img)(_n10##x,_p10##y,z,c), I[21] = (T)(img)(_n11##x,_p10##y,z,c), \ - I[22] = (T)(img)(_p10##x,_p9##y,z,c), I[23] = (T)(img)(_p9##x,_p9##y,z,c), I[24] = (T)(img)(_p8##x,_p9##y,z,c), I[25] = (T)(img)(_p7##x,_p9##y,z,c), I[26] = (T)(img)(_p6##x,_p9##y,z,c), I[27] = (T)(img)(_p5##x,_p9##y,z,c), I[28] = (T)(img)(_p4##x,_p9##y,z,c), I[29] = (T)(img)(_p3##x,_p9##y,z,c), I[30] = (T)(img)(_p2##x,_p9##y,z,c), I[31] = (T)(img)(_p1##x,_p9##y,z,c), I[32] = (T)(img)(x,_p9##y,z,c), I[33] = (T)(img)(_n1##x,_p9##y,z,c), I[34] = (T)(img)(_n2##x,_p9##y,z,c), I[35] = (T)(img)(_n3##x,_p9##y,z,c), I[36] = (T)(img)(_n4##x,_p9##y,z,c), I[37] = (T)(img)(_n5##x,_p9##y,z,c), I[38] = (T)(img)(_n6##x,_p9##y,z,c), I[39] = (T)(img)(_n7##x,_p9##y,z,c), I[40] = (T)(img)(_n8##x,_p9##y,z,c), I[41] = (T)(img)(_n9##x,_p9##y,z,c), I[42] = (T)(img)(_n10##x,_p9##y,z,c), I[43] = (T)(img)(_n11##x,_p9##y,z,c), \ - I[44] = (T)(img)(_p10##x,_p8##y,z,c), I[45] = (T)(img)(_p9##x,_p8##y,z,c), I[46] = (T)(img)(_p8##x,_p8##y,z,c), I[47] = (T)(img)(_p7##x,_p8##y,z,c), I[48] = (T)(img)(_p6##x,_p8##y,z,c), I[49] = (T)(img)(_p5##x,_p8##y,z,c), I[50] = (T)(img)(_p4##x,_p8##y,z,c), I[51] = (T)(img)(_p3##x,_p8##y,z,c), I[52] = (T)(img)(_p2##x,_p8##y,z,c), I[53] = (T)(img)(_p1##x,_p8##y,z,c), I[54] = (T)(img)(x,_p8##y,z,c), I[55] = (T)(img)(_n1##x,_p8##y,z,c), I[56] = (T)(img)(_n2##x,_p8##y,z,c), I[57] = (T)(img)(_n3##x,_p8##y,z,c), I[58] = (T)(img)(_n4##x,_p8##y,z,c), I[59] = (T)(img)(_n5##x,_p8##y,z,c), I[60] = (T)(img)(_n6##x,_p8##y,z,c), I[61] = (T)(img)(_n7##x,_p8##y,z,c), I[62] = (T)(img)(_n8##x,_p8##y,z,c), I[63] = (T)(img)(_n9##x,_p8##y,z,c), I[64] = (T)(img)(_n10##x,_p8##y,z,c), I[65] = (T)(img)(_n11##x,_p8##y,z,c), \ - I[66] = (T)(img)(_p10##x,_p7##y,z,c), I[67] = (T)(img)(_p9##x,_p7##y,z,c), I[68] = (T)(img)(_p8##x,_p7##y,z,c), I[69] = (T)(img)(_p7##x,_p7##y,z,c), I[70] = (T)(img)(_p6##x,_p7##y,z,c), I[71] = (T)(img)(_p5##x,_p7##y,z,c), I[72] = (T)(img)(_p4##x,_p7##y,z,c), I[73] = (T)(img)(_p3##x,_p7##y,z,c), I[74] = (T)(img)(_p2##x,_p7##y,z,c), I[75] = (T)(img)(_p1##x,_p7##y,z,c), I[76] = (T)(img)(x,_p7##y,z,c), I[77] = (T)(img)(_n1##x,_p7##y,z,c), I[78] = (T)(img)(_n2##x,_p7##y,z,c), I[79] = (T)(img)(_n3##x,_p7##y,z,c), I[80] = (T)(img)(_n4##x,_p7##y,z,c), I[81] = (T)(img)(_n5##x,_p7##y,z,c), I[82] = (T)(img)(_n6##x,_p7##y,z,c), I[83] = (T)(img)(_n7##x,_p7##y,z,c), I[84] = (T)(img)(_n8##x,_p7##y,z,c), I[85] = (T)(img)(_n9##x,_p7##y,z,c), I[86] = (T)(img)(_n10##x,_p7##y,z,c), I[87] = (T)(img)(_n11##x,_p7##y,z,c), \ - I[88] = (T)(img)(_p10##x,_p6##y,z,c), I[89] = (T)(img)(_p9##x,_p6##y,z,c), I[90] = (T)(img)(_p8##x,_p6##y,z,c), I[91] = (T)(img)(_p7##x,_p6##y,z,c), I[92] = (T)(img)(_p6##x,_p6##y,z,c), I[93] = (T)(img)(_p5##x,_p6##y,z,c), I[94] = (T)(img)(_p4##x,_p6##y,z,c), I[95] = (T)(img)(_p3##x,_p6##y,z,c), I[96] = (T)(img)(_p2##x,_p6##y,z,c), I[97] = (T)(img)(_p1##x,_p6##y,z,c), I[98] = (T)(img)(x,_p6##y,z,c), I[99] = (T)(img)(_n1##x,_p6##y,z,c), I[100] = (T)(img)(_n2##x,_p6##y,z,c), I[101] = (T)(img)(_n3##x,_p6##y,z,c), I[102] = (T)(img)(_n4##x,_p6##y,z,c), I[103] = (T)(img)(_n5##x,_p6##y,z,c), I[104] = (T)(img)(_n6##x,_p6##y,z,c), I[105] = (T)(img)(_n7##x,_p6##y,z,c), I[106] = (T)(img)(_n8##x,_p6##y,z,c), I[107] = (T)(img)(_n9##x,_p6##y,z,c), I[108] = (T)(img)(_n10##x,_p6##y,z,c), I[109] = (T)(img)(_n11##x,_p6##y,z,c), \ - I[110] = (T)(img)(_p10##x,_p5##y,z,c), I[111] = (T)(img)(_p9##x,_p5##y,z,c), I[112] = (T)(img)(_p8##x,_p5##y,z,c), I[113] = (T)(img)(_p7##x,_p5##y,z,c), I[114] = (T)(img)(_p6##x,_p5##y,z,c), I[115] = (T)(img)(_p5##x,_p5##y,z,c), I[116] = (T)(img)(_p4##x,_p5##y,z,c), I[117] = (T)(img)(_p3##x,_p5##y,z,c), I[118] = (T)(img)(_p2##x,_p5##y,z,c), I[119] = (T)(img)(_p1##x,_p5##y,z,c), I[120] = (T)(img)(x,_p5##y,z,c), I[121] = (T)(img)(_n1##x,_p5##y,z,c), I[122] = (T)(img)(_n2##x,_p5##y,z,c), I[123] = (T)(img)(_n3##x,_p5##y,z,c), I[124] = (T)(img)(_n4##x,_p5##y,z,c), I[125] = (T)(img)(_n5##x,_p5##y,z,c), I[126] = (T)(img)(_n6##x,_p5##y,z,c), I[127] = (T)(img)(_n7##x,_p5##y,z,c), I[128] = (T)(img)(_n8##x,_p5##y,z,c), I[129] = (T)(img)(_n9##x,_p5##y,z,c), I[130] = (T)(img)(_n10##x,_p5##y,z,c), I[131] = (T)(img)(_n11##x,_p5##y,z,c), \ - I[132] = (T)(img)(_p10##x,_p4##y,z,c), I[133] = (T)(img)(_p9##x,_p4##y,z,c), I[134] = (T)(img)(_p8##x,_p4##y,z,c), I[135] = (T)(img)(_p7##x,_p4##y,z,c), I[136] = (T)(img)(_p6##x,_p4##y,z,c), I[137] = (T)(img)(_p5##x,_p4##y,z,c), I[138] = (T)(img)(_p4##x,_p4##y,z,c), I[139] = (T)(img)(_p3##x,_p4##y,z,c), I[140] = (T)(img)(_p2##x,_p4##y,z,c), I[141] = (T)(img)(_p1##x,_p4##y,z,c), I[142] = (T)(img)(x,_p4##y,z,c), I[143] = (T)(img)(_n1##x,_p4##y,z,c), I[144] = (T)(img)(_n2##x,_p4##y,z,c), I[145] = (T)(img)(_n3##x,_p4##y,z,c), I[146] = (T)(img)(_n4##x,_p4##y,z,c), I[147] = (T)(img)(_n5##x,_p4##y,z,c), I[148] = (T)(img)(_n6##x,_p4##y,z,c), I[149] = (T)(img)(_n7##x,_p4##y,z,c), I[150] = (T)(img)(_n8##x,_p4##y,z,c), I[151] = (T)(img)(_n9##x,_p4##y,z,c), I[152] = (T)(img)(_n10##x,_p4##y,z,c), I[153] = (T)(img)(_n11##x,_p4##y,z,c), \ - I[154] = (T)(img)(_p10##x,_p3##y,z,c), I[155] = (T)(img)(_p9##x,_p3##y,z,c), I[156] = (T)(img)(_p8##x,_p3##y,z,c), I[157] = (T)(img)(_p7##x,_p3##y,z,c), I[158] = (T)(img)(_p6##x,_p3##y,z,c), I[159] = (T)(img)(_p5##x,_p3##y,z,c), I[160] = (T)(img)(_p4##x,_p3##y,z,c), I[161] = (T)(img)(_p3##x,_p3##y,z,c), I[162] = (T)(img)(_p2##x,_p3##y,z,c), I[163] = (T)(img)(_p1##x,_p3##y,z,c), I[164] = (T)(img)(x,_p3##y,z,c), I[165] = (T)(img)(_n1##x,_p3##y,z,c), I[166] = (T)(img)(_n2##x,_p3##y,z,c), I[167] = (T)(img)(_n3##x,_p3##y,z,c), I[168] = (T)(img)(_n4##x,_p3##y,z,c), I[169] = (T)(img)(_n5##x,_p3##y,z,c), I[170] = (T)(img)(_n6##x,_p3##y,z,c), I[171] = (T)(img)(_n7##x,_p3##y,z,c), I[172] = (T)(img)(_n8##x,_p3##y,z,c), I[173] = (T)(img)(_n9##x,_p3##y,z,c), I[174] = (T)(img)(_n10##x,_p3##y,z,c), I[175] = (T)(img)(_n11##x,_p3##y,z,c), \ - I[176] = (T)(img)(_p10##x,_p2##y,z,c), I[177] = (T)(img)(_p9##x,_p2##y,z,c), I[178] = (T)(img)(_p8##x,_p2##y,z,c), I[179] = (T)(img)(_p7##x,_p2##y,z,c), I[180] = (T)(img)(_p6##x,_p2##y,z,c), I[181] = (T)(img)(_p5##x,_p2##y,z,c), I[182] = (T)(img)(_p4##x,_p2##y,z,c), I[183] = (T)(img)(_p3##x,_p2##y,z,c), I[184] = (T)(img)(_p2##x,_p2##y,z,c), I[185] = (T)(img)(_p1##x,_p2##y,z,c), I[186] = (T)(img)(x,_p2##y,z,c), I[187] = (T)(img)(_n1##x,_p2##y,z,c), I[188] = (T)(img)(_n2##x,_p2##y,z,c), I[189] = (T)(img)(_n3##x,_p2##y,z,c), I[190] = (T)(img)(_n4##x,_p2##y,z,c), I[191] = (T)(img)(_n5##x,_p2##y,z,c), I[192] = (T)(img)(_n6##x,_p2##y,z,c), I[193] = (T)(img)(_n7##x,_p2##y,z,c), I[194] = (T)(img)(_n8##x,_p2##y,z,c), I[195] = (T)(img)(_n9##x,_p2##y,z,c), I[196] = (T)(img)(_n10##x,_p2##y,z,c), I[197] = (T)(img)(_n11##x,_p2##y,z,c), \ - I[198] = (T)(img)(_p10##x,_p1##y,z,c), I[199] = (T)(img)(_p9##x,_p1##y,z,c), I[200] = (T)(img)(_p8##x,_p1##y,z,c), I[201] = (T)(img)(_p7##x,_p1##y,z,c), I[202] = (T)(img)(_p6##x,_p1##y,z,c), I[203] = (T)(img)(_p5##x,_p1##y,z,c), I[204] = (T)(img)(_p4##x,_p1##y,z,c), I[205] = (T)(img)(_p3##x,_p1##y,z,c), I[206] = (T)(img)(_p2##x,_p1##y,z,c), I[207] = (T)(img)(_p1##x,_p1##y,z,c), I[208] = (T)(img)(x,_p1##y,z,c), I[209] = (T)(img)(_n1##x,_p1##y,z,c), I[210] = (T)(img)(_n2##x,_p1##y,z,c), I[211] = (T)(img)(_n3##x,_p1##y,z,c), I[212] = (T)(img)(_n4##x,_p1##y,z,c), I[213] = (T)(img)(_n5##x,_p1##y,z,c), I[214] = (T)(img)(_n6##x,_p1##y,z,c), I[215] = (T)(img)(_n7##x,_p1##y,z,c), I[216] = (T)(img)(_n8##x,_p1##y,z,c), I[217] = (T)(img)(_n9##x,_p1##y,z,c), I[218] = (T)(img)(_n10##x,_p1##y,z,c), I[219] = (T)(img)(_n11##x,_p1##y,z,c), \ - I[220] = (T)(img)(_p10##x,y,z,c), I[221] = (T)(img)(_p9##x,y,z,c), I[222] = (T)(img)(_p8##x,y,z,c), I[223] = (T)(img)(_p7##x,y,z,c), I[224] = (T)(img)(_p6##x,y,z,c), I[225] = (T)(img)(_p5##x,y,z,c), I[226] = (T)(img)(_p4##x,y,z,c), I[227] = (T)(img)(_p3##x,y,z,c), I[228] = (T)(img)(_p2##x,y,z,c), I[229] = (T)(img)(_p1##x,y,z,c), I[230] = (T)(img)(x,y,z,c), I[231] = (T)(img)(_n1##x,y,z,c), I[232] = (T)(img)(_n2##x,y,z,c), I[233] = (T)(img)(_n3##x,y,z,c), I[234] = (T)(img)(_n4##x,y,z,c), I[235] = (T)(img)(_n5##x,y,z,c), I[236] = (T)(img)(_n6##x,y,z,c), I[237] = (T)(img)(_n7##x,y,z,c), I[238] = (T)(img)(_n8##x,y,z,c), I[239] = (T)(img)(_n9##x,y,z,c), I[240] = (T)(img)(_n10##x,y,z,c), I[241] = (T)(img)(_n11##x,y,z,c), \ - I[242] = (T)(img)(_p10##x,_n1##y,z,c), I[243] = (T)(img)(_p9##x,_n1##y,z,c), I[244] = (T)(img)(_p8##x,_n1##y,z,c), I[245] = (T)(img)(_p7##x,_n1##y,z,c), I[246] = (T)(img)(_p6##x,_n1##y,z,c), I[247] = (T)(img)(_p5##x,_n1##y,z,c), I[248] = (T)(img)(_p4##x,_n1##y,z,c), I[249] = (T)(img)(_p3##x,_n1##y,z,c), I[250] = (T)(img)(_p2##x,_n1##y,z,c), I[251] = (T)(img)(_p1##x,_n1##y,z,c), I[252] = (T)(img)(x,_n1##y,z,c), I[253] = (T)(img)(_n1##x,_n1##y,z,c), I[254] = (T)(img)(_n2##x,_n1##y,z,c), I[255] = (T)(img)(_n3##x,_n1##y,z,c), I[256] = (T)(img)(_n4##x,_n1##y,z,c), I[257] = (T)(img)(_n5##x,_n1##y,z,c), I[258] = (T)(img)(_n6##x,_n1##y,z,c), I[259] = (T)(img)(_n7##x,_n1##y,z,c), I[260] = (T)(img)(_n8##x,_n1##y,z,c), I[261] = (T)(img)(_n9##x,_n1##y,z,c), I[262] = (T)(img)(_n10##x,_n1##y,z,c), I[263] = (T)(img)(_n11##x,_n1##y,z,c), \ - I[264] = (T)(img)(_p10##x,_n2##y,z,c), I[265] = (T)(img)(_p9##x,_n2##y,z,c), I[266] = (T)(img)(_p8##x,_n2##y,z,c), I[267] = (T)(img)(_p7##x,_n2##y,z,c), I[268] = (T)(img)(_p6##x,_n2##y,z,c), I[269] = (T)(img)(_p5##x,_n2##y,z,c), I[270] = (T)(img)(_p4##x,_n2##y,z,c), I[271] = (T)(img)(_p3##x,_n2##y,z,c), I[272] = (T)(img)(_p2##x,_n2##y,z,c), I[273] = (T)(img)(_p1##x,_n2##y,z,c), I[274] = (T)(img)(x,_n2##y,z,c), I[275] = (T)(img)(_n1##x,_n2##y,z,c), I[276] = (T)(img)(_n2##x,_n2##y,z,c), I[277] = (T)(img)(_n3##x,_n2##y,z,c), I[278] = (T)(img)(_n4##x,_n2##y,z,c), I[279] = (T)(img)(_n5##x,_n2##y,z,c), I[280] = (T)(img)(_n6##x,_n2##y,z,c), I[281] = (T)(img)(_n7##x,_n2##y,z,c), I[282] = (T)(img)(_n8##x,_n2##y,z,c), I[283] = (T)(img)(_n9##x,_n2##y,z,c), I[284] = (T)(img)(_n10##x,_n2##y,z,c), I[285] = (T)(img)(_n11##x,_n2##y,z,c), \ - I[286] = (T)(img)(_p10##x,_n3##y,z,c), I[287] = (T)(img)(_p9##x,_n3##y,z,c), I[288] = (T)(img)(_p8##x,_n3##y,z,c), I[289] = (T)(img)(_p7##x,_n3##y,z,c), I[290] = (T)(img)(_p6##x,_n3##y,z,c), I[291] = (T)(img)(_p5##x,_n3##y,z,c), I[292] = (T)(img)(_p4##x,_n3##y,z,c), I[293] = (T)(img)(_p3##x,_n3##y,z,c), I[294] = (T)(img)(_p2##x,_n3##y,z,c), I[295] = (T)(img)(_p1##x,_n3##y,z,c), I[296] = (T)(img)(x,_n3##y,z,c), I[297] = (T)(img)(_n1##x,_n3##y,z,c), I[298] = (T)(img)(_n2##x,_n3##y,z,c), I[299] = (T)(img)(_n3##x,_n3##y,z,c), I[300] = (T)(img)(_n4##x,_n3##y,z,c), I[301] = (T)(img)(_n5##x,_n3##y,z,c), I[302] = (T)(img)(_n6##x,_n3##y,z,c), I[303] = (T)(img)(_n7##x,_n3##y,z,c), I[304] = (T)(img)(_n8##x,_n3##y,z,c), I[305] = (T)(img)(_n9##x,_n3##y,z,c), I[306] = (T)(img)(_n10##x,_n3##y,z,c), I[307] = (T)(img)(_n11##x,_n3##y,z,c), \ - I[308] = (T)(img)(_p10##x,_n4##y,z,c), I[309] = (T)(img)(_p9##x,_n4##y,z,c), I[310] = (T)(img)(_p8##x,_n4##y,z,c), I[311] = (T)(img)(_p7##x,_n4##y,z,c), I[312] = (T)(img)(_p6##x,_n4##y,z,c), I[313] = (T)(img)(_p5##x,_n4##y,z,c), I[314] = (T)(img)(_p4##x,_n4##y,z,c), I[315] = (T)(img)(_p3##x,_n4##y,z,c), I[316] = (T)(img)(_p2##x,_n4##y,z,c), I[317] = (T)(img)(_p1##x,_n4##y,z,c), I[318] = (T)(img)(x,_n4##y,z,c), I[319] = (T)(img)(_n1##x,_n4##y,z,c), I[320] = (T)(img)(_n2##x,_n4##y,z,c), I[321] = (T)(img)(_n3##x,_n4##y,z,c), I[322] = (T)(img)(_n4##x,_n4##y,z,c), I[323] = (T)(img)(_n5##x,_n4##y,z,c), I[324] = (T)(img)(_n6##x,_n4##y,z,c), I[325] = (T)(img)(_n7##x,_n4##y,z,c), I[326] = (T)(img)(_n8##x,_n4##y,z,c), I[327] = (T)(img)(_n9##x,_n4##y,z,c), I[328] = (T)(img)(_n10##x,_n4##y,z,c), I[329] = (T)(img)(_n11##x,_n4##y,z,c), \ - I[330] = (T)(img)(_p10##x,_n5##y,z,c), I[331] = (T)(img)(_p9##x,_n5##y,z,c), I[332] = (T)(img)(_p8##x,_n5##y,z,c), I[333] = (T)(img)(_p7##x,_n5##y,z,c), I[334] = (T)(img)(_p6##x,_n5##y,z,c), I[335] = (T)(img)(_p5##x,_n5##y,z,c), I[336] = (T)(img)(_p4##x,_n5##y,z,c), I[337] = (T)(img)(_p3##x,_n5##y,z,c), I[338] = (T)(img)(_p2##x,_n5##y,z,c), I[339] = (T)(img)(_p1##x,_n5##y,z,c), I[340] = (T)(img)(x,_n5##y,z,c), I[341] = (T)(img)(_n1##x,_n5##y,z,c), I[342] = (T)(img)(_n2##x,_n5##y,z,c), I[343] = (T)(img)(_n3##x,_n5##y,z,c), I[344] = (T)(img)(_n4##x,_n5##y,z,c), I[345] = (T)(img)(_n5##x,_n5##y,z,c), I[346] = (T)(img)(_n6##x,_n5##y,z,c), I[347] = (T)(img)(_n7##x,_n5##y,z,c), I[348] = (T)(img)(_n8##x,_n5##y,z,c), I[349] = (T)(img)(_n9##x,_n5##y,z,c), I[350] = (T)(img)(_n10##x,_n5##y,z,c), I[351] = (T)(img)(_n11##x,_n5##y,z,c), \ - I[352] = (T)(img)(_p10##x,_n6##y,z,c), I[353] = (T)(img)(_p9##x,_n6##y,z,c), I[354] = (T)(img)(_p8##x,_n6##y,z,c), I[355] = (T)(img)(_p7##x,_n6##y,z,c), I[356] = (T)(img)(_p6##x,_n6##y,z,c), I[357] = (T)(img)(_p5##x,_n6##y,z,c), I[358] = (T)(img)(_p4##x,_n6##y,z,c), I[359] = (T)(img)(_p3##x,_n6##y,z,c), I[360] = (T)(img)(_p2##x,_n6##y,z,c), I[361] = (T)(img)(_p1##x,_n6##y,z,c), I[362] = (T)(img)(x,_n6##y,z,c), I[363] = (T)(img)(_n1##x,_n6##y,z,c), I[364] = (T)(img)(_n2##x,_n6##y,z,c), I[365] = (T)(img)(_n3##x,_n6##y,z,c), I[366] = (T)(img)(_n4##x,_n6##y,z,c), I[367] = (T)(img)(_n5##x,_n6##y,z,c), I[368] = (T)(img)(_n6##x,_n6##y,z,c), I[369] = (T)(img)(_n7##x,_n6##y,z,c), I[370] = (T)(img)(_n8##x,_n6##y,z,c), I[371] = (T)(img)(_n9##x,_n6##y,z,c), I[372] = (T)(img)(_n10##x,_n6##y,z,c), I[373] = (T)(img)(_n11##x,_n6##y,z,c), \ - I[374] = (T)(img)(_p10##x,_n7##y,z,c), I[375] = (T)(img)(_p9##x,_n7##y,z,c), I[376] = (T)(img)(_p8##x,_n7##y,z,c), I[377] = (T)(img)(_p7##x,_n7##y,z,c), I[378] = (T)(img)(_p6##x,_n7##y,z,c), I[379] = (T)(img)(_p5##x,_n7##y,z,c), I[380] = (T)(img)(_p4##x,_n7##y,z,c), I[381] = (T)(img)(_p3##x,_n7##y,z,c), I[382] = (T)(img)(_p2##x,_n7##y,z,c), I[383] = (T)(img)(_p1##x,_n7##y,z,c), I[384] = (T)(img)(x,_n7##y,z,c), I[385] = (T)(img)(_n1##x,_n7##y,z,c), I[386] = (T)(img)(_n2##x,_n7##y,z,c), I[387] = (T)(img)(_n3##x,_n7##y,z,c), I[388] = (T)(img)(_n4##x,_n7##y,z,c), I[389] = (T)(img)(_n5##x,_n7##y,z,c), I[390] = (T)(img)(_n6##x,_n7##y,z,c), I[391] = (T)(img)(_n7##x,_n7##y,z,c), I[392] = (T)(img)(_n8##x,_n7##y,z,c), I[393] = (T)(img)(_n9##x,_n7##y,z,c), I[394] = (T)(img)(_n10##x,_n7##y,z,c), I[395] = (T)(img)(_n11##x,_n7##y,z,c), \ - I[396] = (T)(img)(_p10##x,_n8##y,z,c), I[397] = (T)(img)(_p9##x,_n8##y,z,c), I[398] = (T)(img)(_p8##x,_n8##y,z,c), I[399] = (T)(img)(_p7##x,_n8##y,z,c), I[400] = (T)(img)(_p6##x,_n8##y,z,c), I[401] = (T)(img)(_p5##x,_n8##y,z,c), I[402] = (T)(img)(_p4##x,_n8##y,z,c), I[403] = (T)(img)(_p3##x,_n8##y,z,c), I[404] = (T)(img)(_p2##x,_n8##y,z,c), I[405] = (T)(img)(_p1##x,_n8##y,z,c), I[406] = (T)(img)(x,_n8##y,z,c), I[407] = (T)(img)(_n1##x,_n8##y,z,c), I[408] = (T)(img)(_n2##x,_n8##y,z,c), I[409] = (T)(img)(_n3##x,_n8##y,z,c), I[410] = (T)(img)(_n4##x,_n8##y,z,c), I[411] = (T)(img)(_n5##x,_n8##y,z,c), I[412] = (T)(img)(_n6##x,_n8##y,z,c), I[413] = (T)(img)(_n7##x,_n8##y,z,c), I[414] = (T)(img)(_n8##x,_n8##y,z,c), I[415] = (T)(img)(_n9##x,_n8##y,z,c), I[416] = (T)(img)(_n10##x,_n8##y,z,c), I[417] = (T)(img)(_n11##x,_n8##y,z,c), \ - I[418] = (T)(img)(_p10##x,_n9##y,z,c), I[419] = (T)(img)(_p9##x,_n9##y,z,c), I[420] = (T)(img)(_p8##x,_n9##y,z,c), I[421] = (T)(img)(_p7##x,_n9##y,z,c), I[422] = (T)(img)(_p6##x,_n9##y,z,c), I[423] = (T)(img)(_p5##x,_n9##y,z,c), I[424] = (T)(img)(_p4##x,_n9##y,z,c), I[425] = (T)(img)(_p3##x,_n9##y,z,c), I[426] = (T)(img)(_p2##x,_n9##y,z,c), I[427] = (T)(img)(_p1##x,_n9##y,z,c), I[428] = (T)(img)(x,_n9##y,z,c), I[429] = (T)(img)(_n1##x,_n9##y,z,c), I[430] = (T)(img)(_n2##x,_n9##y,z,c), I[431] = (T)(img)(_n3##x,_n9##y,z,c), I[432] = (T)(img)(_n4##x,_n9##y,z,c), I[433] = (T)(img)(_n5##x,_n9##y,z,c), I[434] = (T)(img)(_n6##x,_n9##y,z,c), I[435] = (T)(img)(_n7##x,_n9##y,z,c), I[436] = (T)(img)(_n8##x,_n9##y,z,c), I[437] = (T)(img)(_n9##x,_n9##y,z,c), I[438] = (T)(img)(_n10##x,_n9##y,z,c), I[439] = (T)(img)(_n11##x,_n9##y,z,c), \ - I[440] = (T)(img)(_p10##x,_n10##y,z,c), I[441] = (T)(img)(_p9##x,_n10##y,z,c), I[442] = (T)(img)(_p8##x,_n10##y,z,c), I[443] = (T)(img)(_p7##x,_n10##y,z,c), I[444] = (T)(img)(_p6##x,_n10##y,z,c), I[445] = (T)(img)(_p5##x,_n10##y,z,c), I[446] = (T)(img)(_p4##x,_n10##y,z,c), I[447] = (T)(img)(_p3##x,_n10##y,z,c), I[448] = (T)(img)(_p2##x,_n10##y,z,c), I[449] = (T)(img)(_p1##x,_n10##y,z,c), I[450] = (T)(img)(x,_n10##y,z,c), I[451] = (T)(img)(_n1##x,_n10##y,z,c), I[452] = (T)(img)(_n2##x,_n10##y,z,c), I[453] = (T)(img)(_n3##x,_n10##y,z,c), I[454] = (T)(img)(_n4##x,_n10##y,z,c), I[455] = (T)(img)(_n5##x,_n10##y,z,c), I[456] = (T)(img)(_n6##x,_n10##y,z,c), I[457] = (T)(img)(_n7##x,_n10##y,z,c), I[458] = (T)(img)(_n8##x,_n10##y,z,c), I[459] = (T)(img)(_n9##x,_n10##y,z,c), I[460] = (T)(img)(_n10##x,_n10##y,z,c), I[461] = (T)(img)(_n11##x,_n10##y,z,c), \ - I[462] = (T)(img)(_p10##x,_n11##y,z,c), I[463] = (T)(img)(_p9##x,_n11##y,z,c), I[464] = (T)(img)(_p8##x,_n11##y,z,c), I[465] = (T)(img)(_p7##x,_n11##y,z,c), I[466] = (T)(img)(_p6##x,_n11##y,z,c), I[467] = (T)(img)(_p5##x,_n11##y,z,c), I[468] = (T)(img)(_p4##x,_n11##y,z,c), I[469] = (T)(img)(_p3##x,_n11##y,z,c), I[470] = (T)(img)(_p2##x,_n11##y,z,c), I[471] = (T)(img)(_p1##x,_n11##y,z,c), I[472] = (T)(img)(x,_n11##y,z,c), I[473] = (T)(img)(_n1##x,_n11##y,z,c), I[474] = (T)(img)(_n2##x,_n11##y,z,c), I[475] = (T)(img)(_n3##x,_n11##y,z,c), I[476] = (T)(img)(_n4##x,_n11##y,z,c), I[477] = (T)(img)(_n5##x,_n11##y,z,c), I[478] = (T)(img)(_n6##x,_n11##y,z,c), I[479] = (T)(img)(_n7##x,_n11##y,z,c), I[480] = (T)(img)(_n8##x,_n11##y,z,c), I[481] = (T)(img)(_n9##x,_n11##y,z,c), I[482] = (T)(img)(_n10##x,_n11##y,z,c), I[483] = (T)(img)(_n11##x,_n11##y,z,c); - -// Define 23x23 loop macros -//------------------------- -#define cimg_for23(bound,i) for (int i = 0, \ - _p11##i = 0, _p10##i = 0, _p9##i = 0, _p8##i = 0, _p7##i = 0, _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6, \ - _n7##i = 7>=(int)(bound)?(int)(bound) - 1:7, \ - _n8##i = 8>=(int)(bound)?(int)(bound) - 1:8, \ - _n9##i = 9>=(int)(bound)?(int)(bound) - 1:9, \ - _n10##i = 10>=(int)(bound)?(int)(bound) - 1:10, \ - _n11##i = 11>=(int)(bound)?(int)(bound) - 1:11; \ - _n11##i<(int)(bound) || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i) - -#define cimg_for23X(img,x) cimg_for23((img)._width,x) -#define cimg_for23Y(img,y) cimg_for23((img)._height,y) -#define cimg_for23Z(img,z) cimg_for23((img)._depth,z) -#define cimg_for23C(img,c) cimg_for23((img)._spectrum,c) -#define cimg_for23XY(img,x,y) cimg_for23Y(img,y) cimg_for23X(img,x) -#define cimg_for23XZ(img,x,z) cimg_for23Z(img,z) cimg_for23X(img,x) -#define cimg_for23XC(img,x,c) cimg_for23C(img,c) cimg_for23X(img,x) -#define cimg_for23YZ(img,y,z) cimg_for23Z(img,z) cimg_for23Y(img,y) -#define cimg_for23YC(img,y,c) cimg_for23C(img,c) cimg_for23Y(img,y) -#define cimg_for23ZC(img,z,c) cimg_for23C(img,c) cimg_for23Z(img,z) -#define cimg_for23XYZ(img,x,y,z) cimg_for23Z(img,z) cimg_for23XY(img,x,y) -#define cimg_for23XZC(img,x,z,c) cimg_for23C(img,c) cimg_for23XZ(img,x,z) -#define cimg_for23YZC(img,y,z,c) cimg_for23C(img,c) cimg_for23YZ(img,y,z) -#define cimg_for23XYZC(img,x,y,z,c) cimg_for23C(img,c) cimg_for23XYZ(img,x,y,z) - -#define cimg_for_in23(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p11##i = i - 11<0?0:i - 11, \ - _p10##i = i - 10<0?0:i - 10, \ - _p9##i = i - 9<0?0:i - 9, \ - _p8##i = i - 8<0?0:i - 8, \ - _p7##i = i - 7<0?0:i - 7, \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6, \ - _n7##i = i + 7>=(int)(bound)?(int)(bound) - 1:i + 7, \ - _n8##i = i + 8>=(int)(bound)?(int)(bound) - 1:i + 8, \ - _n9##i = i + 9>=(int)(bound)?(int)(bound) - 1:i + 9, \ - _n10##i = i + 10>=(int)(bound)?(int)(bound) - 1:i + 10, \ - _n11##i = i + 11>=(int)(bound)?(int)(bound) - 1:i + 11; \ - i<=(int)(i1) && (_n11##i<(int)(bound) || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i) - -#define cimg_for_in23X(img,x0,x1,x) cimg_for_in23((img)._width,x0,x1,x) -#define cimg_for_in23Y(img,y0,y1,y) cimg_for_in23((img)._height,y0,y1,y) -#define cimg_for_in23Z(img,z0,z1,z) cimg_for_in23((img)._depth,z0,z1,z) -#define cimg_for_in23C(img,c0,c1,c) cimg_for_in23((img)._spectrum,c0,c1,c) -#define cimg_for_in23XY(img,x0,y0,x1,y1,x,y) cimg_for_in23Y(img,y0,y1,y) cimg_for_in23X(img,x0,x1,x) -#define cimg_for_in23XZ(img,x0,z0,x1,z1,x,z) cimg_for_in23Z(img,z0,z1,z) cimg_for_in23X(img,x0,x1,x) -#define cimg_for_in23XC(img,x0,c0,x1,c1,x,c) cimg_for_in23C(img,c0,c1,c) cimg_for_in23X(img,x0,x1,x) -#define cimg_for_in23YZ(img,y0,z0,y1,z1,y,z) cimg_for_in23Z(img,z0,z1,z) cimg_for_in23Y(img,y0,y1,y) -#define cimg_for_in23YC(img,y0,c0,y1,c1,y,c) cimg_for_in23C(img,c0,c1,c) cimg_for_in23Y(img,y0,y1,y) -#define cimg_for_in23ZC(img,z0,c0,z1,c1,z,c) cimg_for_in23C(img,c0,c1,c) cimg_for_in23Z(img,z0,z1,z) -#define cimg_for_in23XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in23Z(img,z0,z1,z) cimg_for_in23XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in23XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in23C(img,c0,c1,c) cimg_for_in23XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in23YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in23C(img,c0,c1,c) cimg_for_in23YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in23XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in23C(img,c0,c1,c) cimg_for_in23XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for23x23(img,x,y,z,c,I,T) \ - cimg_for23((img)._height,y) for (int x = 0, \ - _p11##x = 0, _p10##x = 0, _p9##x = 0, _p8##x = 0, _p7##x = 0, _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = 6>=((img)._width)?(img).width() - 1:6, \ - _n7##x = 7>=((img)._width)?(img).width() - 1:7, \ - _n8##x = 8>=((img)._width)?(img).width() - 1:8, \ - _n9##x = 9>=((img)._width)?(img).width() - 1:9, \ - _n10##x = 10>=((img)._width)?(img).width() - 1:10, \ - _n11##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = I[7] = I[8] = I[9] = I[10] = I[11] = (T)(img)(0,_p11##y,z,c)), \ - (I[23] = I[24] = I[25] = I[26] = I[27] = I[28] = I[29] = I[30] = I[31] = I[32] = I[33] = I[34] = (T)(img)(0,_p10##y,z,c)), \ - (I[46] = I[47] = I[48] = I[49] = I[50] = I[51] = I[52] = I[53] = I[54] = I[55] = I[56] = I[57] = (T)(img)(0,_p9##y,z,c)), \ - (I[69] = I[70] = I[71] = I[72] = I[73] = I[74] = I[75] = I[76] = I[77] = I[78] = I[79] = I[80] = (T)(img)(0,_p8##y,z,c)), \ - (I[92] = I[93] = I[94] = I[95] = I[96] = I[97] = I[98] = I[99] = I[100] = I[101] = I[102] = I[103] = (T)(img)(0,_p7##y,z,c)), \ - (I[115] = I[116] = I[117] = I[118] = I[119] = I[120] = I[121] = I[122] = I[123] = I[124] = I[125] = I[126] = (T)(img)(0,_p6##y,z,c)), \ - (I[138] = I[139] = I[140] = I[141] = I[142] = I[143] = I[144] = I[145] = I[146] = I[147] = I[148] = I[149] = (T)(img)(0,_p5##y,z,c)), \ - (I[161] = I[162] = I[163] = I[164] = I[165] = I[166] = I[167] = I[168] = I[169] = I[170] = I[171] = I[172] = (T)(img)(0,_p4##y,z,c)), \ - (I[184] = I[185] = I[186] = I[187] = I[188] = I[189] = I[190] = I[191] = I[192] = I[193] = I[194] = I[195] = (T)(img)(0,_p3##y,z,c)), \ - (I[207] = I[208] = I[209] = I[210] = I[211] = I[212] = I[213] = I[214] = I[215] = I[216] = I[217] = I[218] = (T)(img)(0,_p2##y,z,c)), \ - (I[230] = I[231] = I[232] = I[233] = I[234] = I[235] = I[236] = I[237] = I[238] = I[239] = I[240] = I[241] = (T)(img)(0,_p1##y,z,c)), \ - (I[253] = I[254] = I[255] = I[256] = I[257] = I[258] = I[259] = I[260] = I[261] = I[262] = I[263] = I[264] = (T)(img)(0,y,z,c)), \ - (I[276] = I[277] = I[278] = I[279] = I[280] = I[281] = I[282] = I[283] = I[284] = I[285] = I[286] = I[287] = (T)(img)(0,_n1##y,z,c)), \ - (I[299] = I[300] = I[301] = I[302] = I[303] = I[304] = I[305] = I[306] = I[307] = I[308] = I[309] = I[310] = (T)(img)(0,_n2##y,z,c)), \ - (I[322] = I[323] = I[324] = I[325] = I[326] = I[327] = I[328] = I[329] = I[330] = I[331] = I[332] = I[333] = (T)(img)(0,_n3##y,z,c)), \ - (I[345] = I[346] = I[347] = I[348] = I[349] = I[350] = I[351] = I[352] = I[353] = I[354] = I[355] = I[356] = (T)(img)(0,_n4##y,z,c)), \ - (I[368] = I[369] = I[370] = I[371] = I[372] = I[373] = I[374] = I[375] = I[376] = I[377] = I[378] = I[379] = (T)(img)(0,_n5##y,z,c)), \ - (I[391] = I[392] = I[393] = I[394] = I[395] = I[396] = I[397] = I[398] = I[399] = I[400] = I[401] = I[402] = (T)(img)(0,_n6##y,z,c)), \ - (I[414] = I[415] = I[416] = I[417] = I[418] = I[419] = I[420] = I[421] = I[422] = I[423] = I[424] = I[425] = (T)(img)(0,_n7##y,z,c)), \ - (I[437] = I[438] = I[439] = I[440] = I[441] = I[442] = I[443] = I[444] = I[445] = I[446] = I[447] = I[448] = (T)(img)(0,_n8##y,z,c)), \ - (I[460] = I[461] = I[462] = I[463] = I[464] = I[465] = I[466] = I[467] = I[468] = I[469] = I[470] = I[471] = (T)(img)(0,_n9##y,z,c)), \ - (I[483] = I[484] = I[485] = I[486] = I[487] = I[488] = I[489] = I[490] = I[491] = I[492] = I[493] = I[494] = (T)(img)(0,_n10##y,z,c)), \ - (I[506] = I[507] = I[508] = I[509] = I[510] = I[511] = I[512] = I[513] = I[514] = I[515] = I[516] = I[517] = (T)(img)(0,_n11##y,z,c)), \ - (I[12] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[35] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[58] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[81] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[104] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[127] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[150] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[173] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[196] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[219] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[242] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[265] = (T)(img)(_n1##x,y,z,c)), \ - (I[288] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[311] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[334] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[357] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[380] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[403] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[426] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[449] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[472] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[495] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[518] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[13] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[36] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[59] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[82] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[105] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[128] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[151] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[174] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[197] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[220] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[243] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[266] = (T)(img)(_n2##x,y,z,c)), \ - (I[289] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[312] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[335] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[358] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[381] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[404] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[427] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[450] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[473] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[496] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[519] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[14] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[37] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[60] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[83] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[106] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[129] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[152] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[175] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[198] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[221] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[244] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[267] = (T)(img)(_n3##x,y,z,c)), \ - (I[290] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[313] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[336] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[359] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[382] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[405] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[428] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[451] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[474] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[497] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[520] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[15] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[38] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[61] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[84] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[107] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[130] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[153] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[176] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[199] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[222] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[245] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[268] = (T)(img)(_n4##x,y,z,c)), \ - (I[291] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[314] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[337] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[360] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[383] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[406] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[429] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[452] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[475] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[498] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[521] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[16] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[39] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[62] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[85] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[108] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[131] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[154] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[177] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[200] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[223] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[246] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[269] = (T)(img)(_n5##x,y,z,c)), \ - (I[292] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[315] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[338] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[361] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[384] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[407] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[430] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[453] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[476] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[499] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[522] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[17] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[40] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[63] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[86] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[109] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[132] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[155] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[178] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[201] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[224] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[247] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[270] = (T)(img)(_n6##x,y,z,c)), \ - (I[293] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[316] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[339] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[362] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[385] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[408] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[431] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[454] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[477] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[500] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[523] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[18] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[41] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[64] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[87] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[110] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[133] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[156] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[179] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[202] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[225] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[248] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[271] = (T)(img)(_n7##x,y,z,c)), \ - (I[294] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[317] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[340] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[363] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[386] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[409] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[432] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[455] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[478] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[501] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[524] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[19] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[42] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[65] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[88] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[111] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[134] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[157] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[180] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[203] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[226] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[249] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[272] = (T)(img)(_n8##x,y,z,c)), \ - (I[295] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[318] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[341] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[364] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[387] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[410] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[433] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[456] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[479] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[502] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[525] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[20] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[43] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[66] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[89] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[112] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[135] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[158] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[181] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[204] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[227] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[250] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[273] = (T)(img)(_n9##x,y,z,c)), \ - (I[296] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[319] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[342] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[365] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[388] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[411] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[434] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[457] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[480] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[503] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[526] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[21] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[44] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[67] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[90] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[113] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[136] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[159] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[182] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[205] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[228] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[251] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[274] = (T)(img)(_n10##x,y,z,c)), \ - (I[297] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[320] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[343] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[366] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[389] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[412] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[435] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[458] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[481] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[504] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[527] = (T)(img)(_n10##x,_n11##y,z,c)), \ - 11>=((img)._width)?(img).width() - 1:11); \ - (_n11##x<(img).width() && ( \ - (I[22] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[45] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[68] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[91] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[114] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[137] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[160] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[183] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[206] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[229] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[252] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[275] = (T)(img)(_n11##x,y,z,c)), \ - (I[298] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[321] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[344] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[367] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[390] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[413] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[436] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[459] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[482] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[505] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[528] = (T)(img)(_n11##x,_n11##y,z,c)),1)) || \ - _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], \ - I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], \ - I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], \ - I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], \ - I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], \ - I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], \ - I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], \ - I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], \ - I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], \ - I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], \ - I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], \ - I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], \ - I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], \ - I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], \ - I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], \ - I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], \ - I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], \ - I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], \ - I[414] = I[415], I[415] = I[416], I[416] = I[417], I[417] = I[418], I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], \ - I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], I[447] = I[448], I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], I[458] = I[459], \ - I[460] = I[461], I[461] = I[462], I[462] = I[463], I[463] = I[464], I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], I[479] = I[480], I[480] = I[481], I[481] = I[482], \ - I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], I[493] = I[494], I[494] = I[495], I[495] = I[496], I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], I[503] = I[504], I[504] = I[505], \ - I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], I[511] = I[512], I[512] = I[513], I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], I[519] = I[520], I[520] = I[521], I[521] = I[522], I[522] = I[523], I[523] = I[524], I[524] = I[525], I[525] = I[526], I[526] = I[527], I[527] = I[528], \ - _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x) - -#define cimg_for_in23x23(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in23((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p11##x = x - 11<0?0:x - 11, \ - _p10##x = x - 10<0?0:x - 10, \ - _p9##x = x - 9<0?0:x - 9, \ - _p8##x = x - 8<0?0:x - 8, \ - _p7##x = x - 7<0?0:x - 7, \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = x + 6>=(img).width()?(img).width() - 1:x + 6, \ - _n7##x = x + 7>=(img).width()?(img).width() - 1:x + 7, \ - _n8##x = x + 8>=(img).width()?(img).width() - 1:x + 8, \ - _n9##x = x + 9>=(img).width()?(img).width() - 1:x + 9, \ - _n10##x = x + 10>=(img).width()?(img).width() - 1:x + 10, \ - _n11##x = (int)( \ - (I[0] = (T)(img)(_p11##x,_p11##y,z,c)), \ - (I[23] = (T)(img)(_p11##x,_p10##y,z,c)), \ - (I[46] = (T)(img)(_p11##x,_p9##y,z,c)), \ - (I[69] = (T)(img)(_p11##x,_p8##y,z,c)), \ - (I[92] = (T)(img)(_p11##x,_p7##y,z,c)), \ - (I[115] = (T)(img)(_p11##x,_p6##y,z,c)), \ - (I[138] = (T)(img)(_p11##x,_p5##y,z,c)), \ - (I[161] = (T)(img)(_p11##x,_p4##y,z,c)), \ - (I[184] = (T)(img)(_p11##x,_p3##y,z,c)), \ - (I[207] = (T)(img)(_p11##x,_p2##y,z,c)), \ - (I[230] = (T)(img)(_p11##x,_p1##y,z,c)), \ - (I[253] = (T)(img)(_p11##x,y,z,c)), \ - (I[276] = (T)(img)(_p11##x,_n1##y,z,c)), \ - (I[299] = (T)(img)(_p11##x,_n2##y,z,c)), \ - (I[322] = (T)(img)(_p11##x,_n3##y,z,c)), \ - (I[345] = (T)(img)(_p11##x,_n4##y,z,c)), \ - (I[368] = (T)(img)(_p11##x,_n5##y,z,c)), \ - (I[391] = (T)(img)(_p11##x,_n6##y,z,c)), \ - (I[414] = (T)(img)(_p11##x,_n7##y,z,c)), \ - (I[437] = (T)(img)(_p11##x,_n8##y,z,c)), \ - (I[460] = (T)(img)(_p11##x,_n9##y,z,c)), \ - (I[483] = (T)(img)(_p11##x,_n10##y,z,c)), \ - (I[506] = (T)(img)(_p11##x,_n11##y,z,c)), \ - (I[1] = (T)(img)(_p10##x,_p11##y,z,c)), \ - (I[24] = (T)(img)(_p10##x,_p10##y,z,c)), \ - (I[47] = (T)(img)(_p10##x,_p9##y,z,c)), \ - (I[70] = (T)(img)(_p10##x,_p8##y,z,c)), \ - (I[93] = (T)(img)(_p10##x,_p7##y,z,c)), \ - (I[116] = (T)(img)(_p10##x,_p6##y,z,c)), \ - (I[139] = (T)(img)(_p10##x,_p5##y,z,c)), \ - (I[162] = (T)(img)(_p10##x,_p4##y,z,c)), \ - (I[185] = (T)(img)(_p10##x,_p3##y,z,c)), \ - (I[208] = (T)(img)(_p10##x,_p2##y,z,c)), \ - (I[231] = (T)(img)(_p10##x,_p1##y,z,c)), \ - (I[254] = (T)(img)(_p10##x,y,z,c)), \ - (I[277] = (T)(img)(_p10##x,_n1##y,z,c)), \ - (I[300] = (T)(img)(_p10##x,_n2##y,z,c)), \ - (I[323] = (T)(img)(_p10##x,_n3##y,z,c)), \ - (I[346] = (T)(img)(_p10##x,_n4##y,z,c)), \ - (I[369] = (T)(img)(_p10##x,_n5##y,z,c)), \ - (I[392] = (T)(img)(_p10##x,_n6##y,z,c)), \ - (I[415] = (T)(img)(_p10##x,_n7##y,z,c)), \ - (I[438] = (T)(img)(_p10##x,_n8##y,z,c)), \ - (I[461] = (T)(img)(_p10##x,_n9##y,z,c)), \ - (I[484] = (T)(img)(_p10##x,_n10##y,z,c)), \ - (I[507] = (T)(img)(_p10##x,_n11##y,z,c)), \ - (I[2] = (T)(img)(_p9##x,_p11##y,z,c)), \ - (I[25] = (T)(img)(_p9##x,_p10##y,z,c)), \ - (I[48] = (T)(img)(_p9##x,_p9##y,z,c)), \ - (I[71] = (T)(img)(_p9##x,_p8##y,z,c)), \ - (I[94] = (T)(img)(_p9##x,_p7##y,z,c)), \ - (I[117] = (T)(img)(_p9##x,_p6##y,z,c)), \ - (I[140] = (T)(img)(_p9##x,_p5##y,z,c)), \ - (I[163] = (T)(img)(_p9##x,_p4##y,z,c)), \ - (I[186] = (T)(img)(_p9##x,_p3##y,z,c)), \ - (I[209] = (T)(img)(_p9##x,_p2##y,z,c)), \ - (I[232] = (T)(img)(_p9##x,_p1##y,z,c)), \ - (I[255] = (T)(img)(_p9##x,y,z,c)), \ - (I[278] = (T)(img)(_p9##x,_n1##y,z,c)), \ - (I[301] = (T)(img)(_p9##x,_n2##y,z,c)), \ - (I[324] = (T)(img)(_p9##x,_n3##y,z,c)), \ - (I[347] = (T)(img)(_p9##x,_n4##y,z,c)), \ - (I[370] = (T)(img)(_p9##x,_n5##y,z,c)), \ - (I[393] = (T)(img)(_p9##x,_n6##y,z,c)), \ - (I[416] = (T)(img)(_p9##x,_n7##y,z,c)), \ - (I[439] = (T)(img)(_p9##x,_n8##y,z,c)), \ - (I[462] = (T)(img)(_p9##x,_n9##y,z,c)), \ - (I[485] = (T)(img)(_p9##x,_n10##y,z,c)), \ - (I[508] = (T)(img)(_p9##x,_n11##y,z,c)), \ - (I[3] = (T)(img)(_p8##x,_p11##y,z,c)), \ - (I[26] = (T)(img)(_p8##x,_p10##y,z,c)), \ - (I[49] = (T)(img)(_p8##x,_p9##y,z,c)), \ - (I[72] = (T)(img)(_p8##x,_p8##y,z,c)), \ - (I[95] = (T)(img)(_p8##x,_p7##y,z,c)), \ - (I[118] = (T)(img)(_p8##x,_p6##y,z,c)), \ - (I[141] = (T)(img)(_p8##x,_p5##y,z,c)), \ - (I[164] = (T)(img)(_p8##x,_p4##y,z,c)), \ - (I[187] = (T)(img)(_p8##x,_p3##y,z,c)), \ - (I[210] = (T)(img)(_p8##x,_p2##y,z,c)), \ - (I[233] = (T)(img)(_p8##x,_p1##y,z,c)), \ - (I[256] = (T)(img)(_p8##x,y,z,c)), \ - (I[279] = (T)(img)(_p8##x,_n1##y,z,c)), \ - (I[302] = (T)(img)(_p8##x,_n2##y,z,c)), \ - (I[325] = (T)(img)(_p8##x,_n3##y,z,c)), \ - (I[348] = (T)(img)(_p8##x,_n4##y,z,c)), \ - (I[371] = (T)(img)(_p8##x,_n5##y,z,c)), \ - (I[394] = (T)(img)(_p8##x,_n6##y,z,c)), \ - (I[417] = (T)(img)(_p8##x,_n7##y,z,c)), \ - (I[440] = (T)(img)(_p8##x,_n8##y,z,c)), \ - (I[463] = (T)(img)(_p8##x,_n9##y,z,c)), \ - (I[486] = (T)(img)(_p8##x,_n10##y,z,c)), \ - (I[509] = (T)(img)(_p8##x,_n11##y,z,c)), \ - (I[4] = (T)(img)(_p7##x,_p11##y,z,c)), \ - (I[27] = (T)(img)(_p7##x,_p10##y,z,c)), \ - (I[50] = (T)(img)(_p7##x,_p9##y,z,c)), \ - (I[73] = (T)(img)(_p7##x,_p8##y,z,c)), \ - (I[96] = (T)(img)(_p7##x,_p7##y,z,c)), \ - (I[119] = (T)(img)(_p7##x,_p6##y,z,c)), \ - (I[142] = (T)(img)(_p7##x,_p5##y,z,c)), \ - (I[165] = (T)(img)(_p7##x,_p4##y,z,c)), \ - (I[188] = (T)(img)(_p7##x,_p3##y,z,c)), \ - (I[211] = (T)(img)(_p7##x,_p2##y,z,c)), \ - (I[234] = (T)(img)(_p7##x,_p1##y,z,c)), \ - (I[257] = (T)(img)(_p7##x,y,z,c)), \ - (I[280] = (T)(img)(_p7##x,_n1##y,z,c)), \ - (I[303] = (T)(img)(_p7##x,_n2##y,z,c)), \ - (I[326] = (T)(img)(_p7##x,_n3##y,z,c)), \ - (I[349] = (T)(img)(_p7##x,_n4##y,z,c)), \ - (I[372] = (T)(img)(_p7##x,_n5##y,z,c)), \ - (I[395] = (T)(img)(_p7##x,_n6##y,z,c)), \ - (I[418] = (T)(img)(_p7##x,_n7##y,z,c)), \ - (I[441] = (T)(img)(_p7##x,_n8##y,z,c)), \ - (I[464] = (T)(img)(_p7##x,_n9##y,z,c)), \ - (I[487] = (T)(img)(_p7##x,_n10##y,z,c)), \ - (I[510] = (T)(img)(_p7##x,_n11##y,z,c)), \ - (I[5] = (T)(img)(_p6##x,_p11##y,z,c)), \ - (I[28] = (T)(img)(_p6##x,_p10##y,z,c)), \ - (I[51] = (T)(img)(_p6##x,_p9##y,z,c)), \ - (I[74] = (T)(img)(_p6##x,_p8##y,z,c)), \ - (I[97] = (T)(img)(_p6##x,_p7##y,z,c)), \ - (I[120] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[143] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[166] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[189] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[212] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[235] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[258] = (T)(img)(_p6##x,y,z,c)), \ - (I[281] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[304] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[327] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[350] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[373] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[396] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[419] = (T)(img)(_p6##x,_n7##y,z,c)), \ - (I[442] = (T)(img)(_p6##x,_n8##y,z,c)), \ - (I[465] = (T)(img)(_p6##x,_n9##y,z,c)), \ - (I[488] = (T)(img)(_p6##x,_n10##y,z,c)), \ - (I[511] = (T)(img)(_p6##x,_n11##y,z,c)), \ - (I[6] = (T)(img)(_p5##x,_p11##y,z,c)), \ - (I[29] = (T)(img)(_p5##x,_p10##y,z,c)), \ - (I[52] = (T)(img)(_p5##x,_p9##y,z,c)), \ - (I[75] = (T)(img)(_p5##x,_p8##y,z,c)), \ - (I[98] = (T)(img)(_p5##x,_p7##y,z,c)), \ - (I[121] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[144] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[167] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[190] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[213] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[236] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[259] = (T)(img)(_p5##x,y,z,c)), \ - (I[282] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[305] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[328] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[351] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[374] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[397] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[420] = (T)(img)(_p5##x,_n7##y,z,c)), \ - (I[443] = (T)(img)(_p5##x,_n8##y,z,c)), \ - (I[466] = (T)(img)(_p5##x,_n9##y,z,c)), \ - (I[489] = (T)(img)(_p5##x,_n10##y,z,c)), \ - (I[512] = (T)(img)(_p5##x,_n11##y,z,c)), \ - (I[7] = (T)(img)(_p4##x,_p11##y,z,c)), \ - (I[30] = (T)(img)(_p4##x,_p10##y,z,c)), \ - (I[53] = (T)(img)(_p4##x,_p9##y,z,c)), \ - (I[76] = (T)(img)(_p4##x,_p8##y,z,c)), \ - (I[99] = (T)(img)(_p4##x,_p7##y,z,c)), \ - (I[122] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[145] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[168] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[191] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[214] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[237] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[260] = (T)(img)(_p4##x,y,z,c)), \ - (I[283] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[306] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[329] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[352] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[375] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[398] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[421] = (T)(img)(_p4##x,_n7##y,z,c)), \ - (I[444] = (T)(img)(_p4##x,_n8##y,z,c)), \ - (I[467] = (T)(img)(_p4##x,_n9##y,z,c)), \ - (I[490] = (T)(img)(_p4##x,_n10##y,z,c)), \ - (I[513] = (T)(img)(_p4##x,_n11##y,z,c)), \ - (I[8] = (T)(img)(_p3##x,_p11##y,z,c)), \ - (I[31] = (T)(img)(_p3##x,_p10##y,z,c)), \ - (I[54] = (T)(img)(_p3##x,_p9##y,z,c)), \ - (I[77] = (T)(img)(_p3##x,_p8##y,z,c)), \ - (I[100] = (T)(img)(_p3##x,_p7##y,z,c)), \ - (I[123] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[146] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[169] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[192] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[215] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[238] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[261] = (T)(img)(_p3##x,y,z,c)), \ - (I[284] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[307] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[330] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[353] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[376] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[399] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[422] = (T)(img)(_p3##x,_n7##y,z,c)), \ - (I[445] = (T)(img)(_p3##x,_n8##y,z,c)), \ - (I[468] = (T)(img)(_p3##x,_n9##y,z,c)), \ - (I[491] = (T)(img)(_p3##x,_n10##y,z,c)), \ - (I[514] = (T)(img)(_p3##x,_n11##y,z,c)), \ - (I[9] = (T)(img)(_p2##x,_p11##y,z,c)), \ - (I[32] = (T)(img)(_p2##x,_p10##y,z,c)), \ - (I[55] = (T)(img)(_p2##x,_p9##y,z,c)), \ - (I[78] = (T)(img)(_p2##x,_p8##y,z,c)), \ - (I[101] = (T)(img)(_p2##x,_p7##y,z,c)), \ - (I[124] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[147] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[170] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[193] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[216] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[239] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[262] = (T)(img)(_p2##x,y,z,c)), \ - (I[285] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[308] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[331] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[354] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[377] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[400] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[423] = (T)(img)(_p2##x,_n7##y,z,c)), \ - (I[446] = (T)(img)(_p2##x,_n8##y,z,c)), \ - (I[469] = (T)(img)(_p2##x,_n9##y,z,c)), \ - (I[492] = (T)(img)(_p2##x,_n10##y,z,c)), \ - (I[515] = (T)(img)(_p2##x,_n11##y,z,c)), \ - (I[10] = (T)(img)(_p1##x,_p11##y,z,c)), \ - (I[33] = (T)(img)(_p1##x,_p10##y,z,c)), \ - (I[56] = (T)(img)(_p1##x,_p9##y,z,c)), \ - (I[79] = (T)(img)(_p1##x,_p8##y,z,c)), \ - (I[102] = (T)(img)(_p1##x,_p7##y,z,c)), \ - (I[125] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[148] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[171] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[194] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[217] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[240] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[263] = (T)(img)(_p1##x,y,z,c)), \ - (I[286] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[309] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[332] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[355] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[378] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[401] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[424] = (T)(img)(_p1##x,_n7##y,z,c)), \ - (I[447] = (T)(img)(_p1##x,_n8##y,z,c)), \ - (I[470] = (T)(img)(_p1##x,_n9##y,z,c)), \ - (I[493] = (T)(img)(_p1##x,_n10##y,z,c)), \ - (I[516] = (T)(img)(_p1##x,_n11##y,z,c)), \ - (I[11] = (T)(img)(x,_p11##y,z,c)), \ - (I[34] = (T)(img)(x,_p10##y,z,c)), \ - (I[57] = (T)(img)(x,_p9##y,z,c)), \ - (I[80] = (T)(img)(x,_p8##y,z,c)), \ - (I[103] = (T)(img)(x,_p7##y,z,c)), \ - (I[126] = (T)(img)(x,_p6##y,z,c)), \ - (I[149] = (T)(img)(x,_p5##y,z,c)), \ - (I[172] = (T)(img)(x,_p4##y,z,c)), \ - (I[195] = (T)(img)(x,_p3##y,z,c)), \ - (I[218] = (T)(img)(x,_p2##y,z,c)), \ - (I[241] = (T)(img)(x,_p1##y,z,c)), \ - (I[264] = (T)(img)(x,y,z,c)), \ - (I[287] = (T)(img)(x,_n1##y,z,c)), \ - (I[310] = (T)(img)(x,_n2##y,z,c)), \ - (I[333] = (T)(img)(x,_n3##y,z,c)), \ - (I[356] = (T)(img)(x,_n4##y,z,c)), \ - (I[379] = (T)(img)(x,_n5##y,z,c)), \ - (I[402] = (T)(img)(x,_n6##y,z,c)), \ - (I[425] = (T)(img)(x,_n7##y,z,c)), \ - (I[448] = (T)(img)(x,_n8##y,z,c)), \ - (I[471] = (T)(img)(x,_n9##y,z,c)), \ - (I[494] = (T)(img)(x,_n10##y,z,c)), \ - (I[517] = (T)(img)(x,_n11##y,z,c)), \ - (I[12] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[35] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[58] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[81] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[104] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[127] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[150] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[173] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[196] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[219] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[242] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[265] = (T)(img)(_n1##x,y,z,c)), \ - (I[288] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[311] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[334] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[357] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[380] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[403] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[426] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[449] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[472] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[495] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[518] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[13] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[36] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[59] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[82] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[105] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[128] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[151] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[174] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[197] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[220] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[243] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[266] = (T)(img)(_n2##x,y,z,c)), \ - (I[289] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[312] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[335] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[358] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[381] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[404] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[427] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[450] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[473] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[496] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[519] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[14] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[37] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[60] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[83] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[106] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[129] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[152] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[175] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[198] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[221] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[244] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[267] = (T)(img)(_n3##x,y,z,c)), \ - (I[290] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[313] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[336] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[359] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[382] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[405] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[428] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[451] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[474] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[497] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[520] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[15] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[38] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[61] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[84] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[107] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[130] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[153] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[176] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[199] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[222] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[245] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[268] = (T)(img)(_n4##x,y,z,c)), \ - (I[291] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[314] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[337] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[360] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[383] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[406] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[429] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[452] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[475] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[498] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[521] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[16] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[39] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[62] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[85] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[108] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[131] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[154] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[177] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[200] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[223] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[246] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[269] = (T)(img)(_n5##x,y,z,c)), \ - (I[292] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[315] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[338] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[361] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[384] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[407] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[430] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[453] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[476] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[499] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[522] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[17] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[40] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[63] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[86] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[109] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[132] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[155] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[178] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[201] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[224] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[247] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[270] = (T)(img)(_n6##x,y,z,c)), \ - (I[293] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[316] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[339] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[362] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[385] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[408] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[431] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[454] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[477] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[500] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[523] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[18] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[41] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[64] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[87] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[110] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[133] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[156] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[179] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[202] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[225] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[248] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[271] = (T)(img)(_n7##x,y,z,c)), \ - (I[294] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[317] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[340] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[363] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[386] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[409] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[432] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[455] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[478] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[501] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[524] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[19] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[42] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[65] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[88] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[111] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[134] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[157] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[180] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[203] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[226] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[249] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[272] = (T)(img)(_n8##x,y,z,c)), \ - (I[295] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[318] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[341] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[364] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[387] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[410] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[433] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[456] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[479] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[502] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[525] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[20] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[43] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[66] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[89] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[112] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[135] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[158] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[181] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[204] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[227] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[250] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[273] = (T)(img)(_n9##x,y,z,c)), \ - (I[296] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[319] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[342] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[365] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[388] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[411] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[434] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[457] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[480] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[503] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[526] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[21] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[44] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[67] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[90] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[113] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[136] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[159] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[182] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[205] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[228] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[251] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[274] = (T)(img)(_n10##x,y,z,c)), \ - (I[297] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[320] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[343] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[366] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[389] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[412] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[435] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[458] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[481] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[504] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[527] = (T)(img)(_n10##x,_n11##y,z,c)), \ - x + 11>=(img).width()?(img).width() - 1:x + 11); \ - x<=(int)(x1) && ((_n11##x<(img).width() && ( \ - (I[22] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[45] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[68] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[91] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[114] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[137] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[160] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[183] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[206] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[229] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[252] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[275] = (T)(img)(_n11##x,y,z,c)), \ - (I[298] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[321] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[344] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[367] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[390] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[413] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[436] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[459] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[482] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[505] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[528] = (T)(img)(_n11##x,_n11##y,z,c)),1)) || \ - _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], \ - I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], \ - I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], \ - I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], \ - I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], \ - I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], \ - I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], \ - I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], \ - I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], \ - I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], \ - I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], \ - I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], \ - I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], \ - I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], \ - I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], \ - I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], \ - I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], \ - I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], \ - I[414] = I[415], I[415] = I[416], I[416] = I[417], I[417] = I[418], I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], \ - I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], I[447] = I[448], I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], I[458] = I[459], \ - I[460] = I[461], I[461] = I[462], I[462] = I[463], I[463] = I[464], I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], I[479] = I[480], I[480] = I[481], I[481] = I[482], \ - I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], I[493] = I[494], I[494] = I[495], I[495] = I[496], I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], I[503] = I[504], I[504] = I[505], \ - I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], I[511] = I[512], I[512] = I[513], I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], I[519] = I[520], I[520] = I[521], I[521] = I[522], I[522] = I[523], I[523] = I[524], I[524] = I[525], I[525] = I[526], I[526] = I[527], I[527] = I[528], \ - _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x) - -#define cimg_get23x23(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p11##x,_p11##y,z,c), I[1] = (T)(img)(_p10##x,_p11##y,z,c), I[2] = (T)(img)(_p9##x,_p11##y,z,c), I[3] = (T)(img)(_p8##x,_p11##y,z,c), I[4] = (T)(img)(_p7##x,_p11##y,z,c), I[5] = (T)(img)(_p6##x,_p11##y,z,c), I[6] = (T)(img)(_p5##x,_p11##y,z,c), I[7] = (T)(img)(_p4##x,_p11##y,z,c), I[8] = (T)(img)(_p3##x,_p11##y,z,c), I[9] = (T)(img)(_p2##x,_p11##y,z,c), I[10] = (T)(img)(_p1##x,_p11##y,z,c), I[11] = (T)(img)(x,_p11##y,z,c), I[12] = (T)(img)(_n1##x,_p11##y,z,c), I[13] = (T)(img)(_n2##x,_p11##y,z,c), I[14] = (T)(img)(_n3##x,_p11##y,z,c), I[15] = (T)(img)(_n4##x,_p11##y,z,c), I[16] = (T)(img)(_n5##x,_p11##y,z,c), I[17] = (T)(img)(_n6##x,_p11##y,z,c), I[18] = (T)(img)(_n7##x,_p11##y,z,c), I[19] = (T)(img)(_n8##x,_p11##y,z,c), I[20] = (T)(img)(_n9##x,_p11##y,z,c), I[21] = (T)(img)(_n10##x,_p11##y,z,c), I[22] = (T)(img)(_n11##x,_p11##y,z,c), \ - I[23] = (T)(img)(_p11##x,_p10##y,z,c), I[24] = (T)(img)(_p10##x,_p10##y,z,c), I[25] = (T)(img)(_p9##x,_p10##y,z,c), I[26] = (T)(img)(_p8##x,_p10##y,z,c), I[27] = (T)(img)(_p7##x,_p10##y,z,c), I[28] = (T)(img)(_p6##x,_p10##y,z,c), I[29] = (T)(img)(_p5##x,_p10##y,z,c), I[30] = (T)(img)(_p4##x,_p10##y,z,c), I[31] = (T)(img)(_p3##x,_p10##y,z,c), I[32] = (T)(img)(_p2##x,_p10##y,z,c), I[33] = (T)(img)(_p1##x,_p10##y,z,c), I[34] = (T)(img)(x,_p10##y,z,c), I[35] = (T)(img)(_n1##x,_p10##y,z,c), I[36] = (T)(img)(_n2##x,_p10##y,z,c), I[37] = (T)(img)(_n3##x,_p10##y,z,c), I[38] = (T)(img)(_n4##x,_p10##y,z,c), I[39] = (T)(img)(_n5##x,_p10##y,z,c), I[40] = (T)(img)(_n6##x,_p10##y,z,c), I[41] = (T)(img)(_n7##x,_p10##y,z,c), I[42] = (T)(img)(_n8##x,_p10##y,z,c), I[43] = (T)(img)(_n9##x,_p10##y,z,c), I[44] = (T)(img)(_n10##x,_p10##y,z,c), I[45] = (T)(img)(_n11##x,_p10##y,z,c), \ - I[46] = (T)(img)(_p11##x,_p9##y,z,c), I[47] = (T)(img)(_p10##x,_p9##y,z,c), I[48] = (T)(img)(_p9##x,_p9##y,z,c), I[49] = (T)(img)(_p8##x,_p9##y,z,c), I[50] = (T)(img)(_p7##x,_p9##y,z,c), I[51] = (T)(img)(_p6##x,_p9##y,z,c), I[52] = (T)(img)(_p5##x,_p9##y,z,c), I[53] = (T)(img)(_p4##x,_p9##y,z,c), I[54] = (T)(img)(_p3##x,_p9##y,z,c), I[55] = (T)(img)(_p2##x,_p9##y,z,c), I[56] = (T)(img)(_p1##x,_p9##y,z,c), I[57] = (T)(img)(x,_p9##y,z,c), I[58] = (T)(img)(_n1##x,_p9##y,z,c), I[59] = (T)(img)(_n2##x,_p9##y,z,c), I[60] = (T)(img)(_n3##x,_p9##y,z,c), I[61] = (T)(img)(_n4##x,_p9##y,z,c), I[62] = (T)(img)(_n5##x,_p9##y,z,c), I[63] = (T)(img)(_n6##x,_p9##y,z,c), I[64] = (T)(img)(_n7##x,_p9##y,z,c), I[65] = (T)(img)(_n8##x,_p9##y,z,c), I[66] = (T)(img)(_n9##x,_p9##y,z,c), I[67] = (T)(img)(_n10##x,_p9##y,z,c), I[68] = (T)(img)(_n11##x,_p9##y,z,c), \ - I[69] = (T)(img)(_p11##x,_p8##y,z,c), I[70] = (T)(img)(_p10##x,_p8##y,z,c), I[71] = (T)(img)(_p9##x,_p8##y,z,c), I[72] = (T)(img)(_p8##x,_p8##y,z,c), I[73] = (T)(img)(_p7##x,_p8##y,z,c), I[74] = (T)(img)(_p6##x,_p8##y,z,c), I[75] = (T)(img)(_p5##x,_p8##y,z,c), I[76] = (T)(img)(_p4##x,_p8##y,z,c), I[77] = (T)(img)(_p3##x,_p8##y,z,c), I[78] = (T)(img)(_p2##x,_p8##y,z,c), I[79] = (T)(img)(_p1##x,_p8##y,z,c), I[80] = (T)(img)(x,_p8##y,z,c), I[81] = (T)(img)(_n1##x,_p8##y,z,c), I[82] = (T)(img)(_n2##x,_p8##y,z,c), I[83] = (T)(img)(_n3##x,_p8##y,z,c), I[84] = (T)(img)(_n4##x,_p8##y,z,c), I[85] = (T)(img)(_n5##x,_p8##y,z,c), I[86] = (T)(img)(_n6##x,_p8##y,z,c), I[87] = (T)(img)(_n7##x,_p8##y,z,c), I[88] = (T)(img)(_n8##x,_p8##y,z,c), I[89] = (T)(img)(_n9##x,_p8##y,z,c), I[90] = (T)(img)(_n10##x,_p8##y,z,c), I[91] = (T)(img)(_n11##x,_p8##y,z,c), \ - I[92] = (T)(img)(_p11##x,_p7##y,z,c), I[93] = (T)(img)(_p10##x,_p7##y,z,c), I[94] = (T)(img)(_p9##x,_p7##y,z,c), I[95] = (T)(img)(_p8##x,_p7##y,z,c), I[96] = (T)(img)(_p7##x,_p7##y,z,c), I[97] = (T)(img)(_p6##x,_p7##y,z,c), I[98] = (T)(img)(_p5##x,_p7##y,z,c), I[99] = (T)(img)(_p4##x,_p7##y,z,c), I[100] = (T)(img)(_p3##x,_p7##y,z,c), I[101] = (T)(img)(_p2##x,_p7##y,z,c), I[102] = (T)(img)(_p1##x,_p7##y,z,c), I[103] = (T)(img)(x,_p7##y,z,c), I[104] = (T)(img)(_n1##x,_p7##y,z,c), I[105] = (T)(img)(_n2##x,_p7##y,z,c), I[106] = (T)(img)(_n3##x,_p7##y,z,c), I[107] = (T)(img)(_n4##x,_p7##y,z,c), I[108] = (T)(img)(_n5##x,_p7##y,z,c), I[109] = (T)(img)(_n6##x,_p7##y,z,c), I[110] = (T)(img)(_n7##x,_p7##y,z,c), I[111] = (T)(img)(_n8##x,_p7##y,z,c), I[112] = (T)(img)(_n9##x,_p7##y,z,c), I[113] = (T)(img)(_n10##x,_p7##y,z,c), I[114] = (T)(img)(_n11##x,_p7##y,z,c), \ - I[115] = (T)(img)(_p11##x,_p6##y,z,c), I[116] = (T)(img)(_p10##x,_p6##y,z,c), I[117] = (T)(img)(_p9##x,_p6##y,z,c), I[118] = (T)(img)(_p8##x,_p6##y,z,c), I[119] = (T)(img)(_p7##x,_p6##y,z,c), I[120] = (T)(img)(_p6##x,_p6##y,z,c), I[121] = (T)(img)(_p5##x,_p6##y,z,c), I[122] = (T)(img)(_p4##x,_p6##y,z,c), I[123] = (T)(img)(_p3##x,_p6##y,z,c), I[124] = (T)(img)(_p2##x,_p6##y,z,c), I[125] = (T)(img)(_p1##x,_p6##y,z,c), I[126] = (T)(img)(x,_p6##y,z,c), I[127] = (T)(img)(_n1##x,_p6##y,z,c), I[128] = (T)(img)(_n2##x,_p6##y,z,c), I[129] = (T)(img)(_n3##x,_p6##y,z,c), I[130] = (T)(img)(_n4##x,_p6##y,z,c), I[131] = (T)(img)(_n5##x,_p6##y,z,c), I[132] = (T)(img)(_n6##x,_p6##y,z,c), I[133] = (T)(img)(_n7##x,_p6##y,z,c), I[134] = (T)(img)(_n8##x,_p6##y,z,c), I[135] = (T)(img)(_n9##x,_p6##y,z,c), I[136] = (T)(img)(_n10##x,_p6##y,z,c), I[137] = (T)(img)(_n11##x,_p6##y,z,c), \ - I[138] = (T)(img)(_p11##x,_p5##y,z,c), I[139] = (T)(img)(_p10##x,_p5##y,z,c), I[140] = (T)(img)(_p9##x,_p5##y,z,c), I[141] = (T)(img)(_p8##x,_p5##y,z,c), I[142] = (T)(img)(_p7##x,_p5##y,z,c), I[143] = (T)(img)(_p6##x,_p5##y,z,c), I[144] = (T)(img)(_p5##x,_p5##y,z,c), I[145] = (T)(img)(_p4##x,_p5##y,z,c), I[146] = (T)(img)(_p3##x,_p5##y,z,c), I[147] = (T)(img)(_p2##x,_p5##y,z,c), I[148] = (T)(img)(_p1##x,_p5##y,z,c), I[149] = (T)(img)(x,_p5##y,z,c), I[150] = (T)(img)(_n1##x,_p5##y,z,c), I[151] = (T)(img)(_n2##x,_p5##y,z,c), I[152] = (T)(img)(_n3##x,_p5##y,z,c), I[153] = (T)(img)(_n4##x,_p5##y,z,c), I[154] = (T)(img)(_n5##x,_p5##y,z,c), I[155] = (T)(img)(_n6##x,_p5##y,z,c), I[156] = (T)(img)(_n7##x,_p5##y,z,c), I[157] = (T)(img)(_n8##x,_p5##y,z,c), I[158] = (T)(img)(_n9##x,_p5##y,z,c), I[159] = (T)(img)(_n10##x,_p5##y,z,c), I[160] = (T)(img)(_n11##x,_p5##y,z,c), \ - I[161] = (T)(img)(_p11##x,_p4##y,z,c), I[162] = (T)(img)(_p10##x,_p4##y,z,c), I[163] = (T)(img)(_p9##x,_p4##y,z,c), I[164] = (T)(img)(_p8##x,_p4##y,z,c), I[165] = (T)(img)(_p7##x,_p4##y,z,c), I[166] = (T)(img)(_p6##x,_p4##y,z,c), I[167] = (T)(img)(_p5##x,_p4##y,z,c), I[168] = (T)(img)(_p4##x,_p4##y,z,c), I[169] = (T)(img)(_p3##x,_p4##y,z,c), I[170] = (T)(img)(_p2##x,_p4##y,z,c), I[171] = (T)(img)(_p1##x,_p4##y,z,c), I[172] = (T)(img)(x,_p4##y,z,c), I[173] = (T)(img)(_n1##x,_p4##y,z,c), I[174] = (T)(img)(_n2##x,_p4##y,z,c), I[175] = (T)(img)(_n3##x,_p4##y,z,c), I[176] = (T)(img)(_n4##x,_p4##y,z,c), I[177] = (T)(img)(_n5##x,_p4##y,z,c), I[178] = (T)(img)(_n6##x,_p4##y,z,c), I[179] = (T)(img)(_n7##x,_p4##y,z,c), I[180] = (T)(img)(_n8##x,_p4##y,z,c), I[181] = (T)(img)(_n9##x,_p4##y,z,c), I[182] = (T)(img)(_n10##x,_p4##y,z,c), I[183] = (T)(img)(_n11##x,_p4##y,z,c), \ - I[184] = (T)(img)(_p11##x,_p3##y,z,c), I[185] = (T)(img)(_p10##x,_p3##y,z,c), I[186] = (T)(img)(_p9##x,_p3##y,z,c), I[187] = (T)(img)(_p8##x,_p3##y,z,c), I[188] = (T)(img)(_p7##x,_p3##y,z,c), I[189] = (T)(img)(_p6##x,_p3##y,z,c), I[190] = (T)(img)(_p5##x,_p3##y,z,c), I[191] = (T)(img)(_p4##x,_p3##y,z,c), I[192] = (T)(img)(_p3##x,_p3##y,z,c), I[193] = (T)(img)(_p2##x,_p3##y,z,c), I[194] = (T)(img)(_p1##x,_p3##y,z,c), I[195] = (T)(img)(x,_p3##y,z,c), I[196] = (T)(img)(_n1##x,_p3##y,z,c), I[197] = (T)(img)(_n2##x,_p3##y,z,c), I[198] = (T)(img)(_n3##x,_p3##y,z,c), I[199] = (T)(img)(_n4##x,_p3##y,z,c), I[200] = (T)(img)(_n5##x,_p3##y,z,c), I[201] = (T)(img)(_n6##x,_p3##y,z,c), I[202] = (T)(img)(_n7##x,_p3##y,z,c), I[203] = (T)(img)(_n8##x,_p3##y,z,c), I[204] = (T)(img)(_n9##x,_p3##y,z,c), I[205] = (T)(img)(_n10##x,_p3##y,z,c), I[206] = (T)(img)(_n11##x,_p3##y,z,c), \ - I[207] = (T)(img)(_p11##x,_p2##y,z,c), I[208] = (T)(img)(_p10##x,_p2##y,z,c), I[209] = (T)(img)(_p9##x,_p2##y,z,c), I[210] = (T)(img)(_p8##x,_p2##y,z,c), I[211] = (T)(img)(_p7##x,_p2##y,z,c), I[212] = (T)(img)(_p6##x,_p2##y,z,c), I[213] = (T)(img)(_p5##x,_p2##y,z,c), I[214] = (T)(img)(_p4##x,_p2##y,z,c), I[215] = (T)(img)(_p3##x,_p2##y,z,c), I[216] = (T)(img)(_p2##x,_p2##y,z,c), I[217] = (T)(img)(_p1##x,_p2##y,z,c), I[218] = (T)(img)(x,_p2##y,z,c), I[219] = (T)(img)(_n1##x,_p2##y,z,c), I[220] = (T)(img)(_n2##x,_p2##y,z,c), I[221] = (T)(img)(_n3##x,_p2##y,z,c), I[222] = (T)(img)(_n4##x,_p2##y,z,c), I[223] = (T)(img)(_n5##x,_p2##y,z,c), I[224] = (T)(img)(_n6##x,_p2##y,z,c), I[225] = (T)(img)(_n7##x,_p2##y,z,c), I[226] = (T)(img)(_n8##x,_p2##y,z,c), I[227] = (T)(img)(_n9##x,_p2##y,z,c), I[228] = (T)(img)(_n10##x,_p2##y,z,c), I[229] = (T)(img)(_n11##x,_p2##y,z,c), \ - I[230] = (T)(img)(_p11##x,_p1##y,z,c), I[231] = (T)(img)(_p10##x,_p1##y,z,c), I[232] = (T)(img)(_p9##x,_p1##y,z,c), I[233] = (T)(img)(_p8##x,_p1##y,z,c), I[234] = (T)(img)(_p7##x,_p1##y,z,c), I[235] = (T)(img)(_p6##x,_p1##y,z,c), I[236] = (T)(img)(_p5##x,_p1##y,z,c), I[237] = (T)(img)(_p4##x,_p1##y,z,c), I[238] = (T)(img)(_p3##x,_p1##y,z,c), I[239] = (T)(img)(_p2##x,_p1##y,z,c), I[240] = (T)(img)(_p1##x,_p1##y,z,c), I[241] = (T)(img)(x,_p1##y,z,c), I[242] = (T)(img)(_n1##x,_p1##y,z,c), I[243] = (T)(img)(_n2##x,_p1##y,z,c), I[244] = (T)(img)(_n3##x,_p1##y,z,c), I[245] = (T)(img)(_n4##x,_p1##y,z,c), I[246] = (T)(img)(_n5##x,_p1##y,z,c), I[247] = (T)(img)(_n6##x,_p1##y,z,c), I[248] = (T)(img)(_n7##x,_p1##y,z,c), I[249] = (T)(img)(_n8##x,_p1##y,z,c), I[250] = (T)(img)(_n9##x,_p1##y,z,c), I[251] = (T)(img)(_n10##x,_p1##y,z,c), I[252] = (T)(img)(_n11##x,_p1##y,z,c), \ - I[253] = (T)(img)(_p11##x,y,z,c), I[254] = (T)(img)(_p10##x,y,z,c), I[255] = (T)(img)(_p9##x,y,z,c), I[256] = (T)(img)(_p8##x,y,z,c), I[257] = (T)(img)(_p7##x,y,z,c), I[258] = (T)(img)(_p6##x,y,z,c), I[259] = (T)(img)(_p5##x,y,z,c), I[260] = (T)(img)(_p4##x,y,z,c), I[261] = (T)(img)(_p3##x,y,z,c), I[262] = (T)(img)(_p2##x,y,z,c), I[263] = (T)(img)(_p1##x,y,z,c), I[264] = (T)(img)(x,y,z,c), I[265] = (T)(img)(_n1##x,y,z,c), I[266] = (T)(img)(_n2##x,y,z,c), I[267] = (T)(img)(_n3##x,y,z,c), I[268] = (T)(img)(_n4##x,y,z,c), I[269] = (T)(img)(_n5##x,y,z,c), I[270] = (T)(img)(_n6##x,y,z,c), I[271] = (T)(img)(_n7##x,y,z,c), I[272] = (T)(img)(_n8##x,y,z,c), I[273] = (T)(img)(_n9##x,y,z,c), I[274] = (T)(img)(_n10##x,y,z,c), I[275] = (T)(img)(_n11##x,y,z,c), \ - I[276] = (T)(img)(_p11##x,_n1##y,z,c), I[277] = (T)(img)(_p10##x,_n1##y,z,c), I[278] = (T)(img)(_p9##x,_n1##y,z,c), I[279] = (T)(img)(_p8##x,_n1##y,z,c), I[280] = (T)(img)(_p7##x,_n1##y,z,c), I[281] = (T)(img)(_p6##x,_n1##y,z,c), I[282] = (T)(img)(_p5##x,_n1##y,z,c), I[283] = (T)(img)(_p4##x,_n1##y,z,c), I[284] = (T)(img)(_p3##x,_n1##y,z,c), I[285] = (T)(img)(_p2##x,_n1##y,z,c), I[286] = (T)(img)(_p1##x,_n1##y,z,c), I[287] = (T)(img)(x,_n1##y,z,c), I[288] = (T)(img)(_n1##x,_n1##y,z,c), I[289] = (T)(img)(_n2##x,_n1##y,z,c), I[290] = (T)(img)(_n3##x,_n1##y,z,c), I[291] = (T)(img)(_n4##x,_n1##y,z,c), I[292] = (T)(img)(_n5##x,_n1##y,z,c), I[293] = (T)(img)(_n6##x,_n1##y,z,c), I[294] = (T)(img)(_n7##x,_n1##y,z,c), I[295] = (T)(img)(_n8##x,_n1##y,z,c), I[296] = (T)(img)(_n9##x,_n1##y,z,c), I[297] = (T)(img)(_n10##x,_n1##y,z,c), I[298] = (T)(img)(_n11##x,_n1##y,z,c), \ - I[299] = (T)(img)(_p11##x,_n2##y,z,c), I[300] = (T)(img)(_p10##x,_n2##y,z,c), I[301] = (T)(img)(_p9##x,_n2##y,z,c), I[302] = (T)(img)(_p8##x,_n2##y,z,c), I[303] = (T)(img)(_p7##x,_n2##y,z,c), I[304] = (T)(img)(_p6##x,_n2##y,z,c), I[305] = (T)(img)(_p5##x,_n2##y,z,c), I[306] = (T)(img)(_p4##x,_n2##y,z,c), I[307] = (T)(img)(_p3##x,_n2##y,z,c), I[308] = (T)(img)(_p2##x,_n2##y,z,c), I[309] = (T)(img)(_p1##x,_n2##y,z,c), I[310] = (T)(img)(x,_n2##y,z,c), I[311] = (T)(img)(_n1##x,_n2##y,z,c), I[312] = (T)(img)(_n2##x,_n2##y,z,c), I[313] = (T)(img)(_n3##x,_n2##y,z,c), I[314] = (T)(img)(_n4##x,_n2##y,z,c), I[315] = (T)(img)(_n5##x,_n2##y,z,c), I[316] = (T)(img)(_n6##x,_n2##y,z,c), I[317] = (T)(img)(_n7##x,_n2##y,z,c), I[318] = (T)(img)(_n8##x,_n2##y,z,c), I[319] = (T)(img)(_n9##x,_n2##y,z,c), I[320] = (T)(img)(_n10##x,_n2##y,z,c), I[321] = (T)(img)(_n11##x,_n2##y,z,c), \ - I[322] = (T)(img)(_p11##x,_n3##y,z,c), I[323] = (T)(img)(_p10##x,_n3##y,z,c), I[324] = (T)(img)(_p9##x,_n3##y,z,c), I[325] = (T)(img)(_p8##x,_n3##y,z,c), I[326] = (T)(img)(_p7##x,_n3##y,z,c), I[327] = (T)(img)(_p6##x,_n3##y,z,c), I[328] = (T)(img)(_p5##x,_n3##y,z,c), I[329] = (T)(img)(_p4##x,_n3##y,z,c), I[330] = (T)(img)(_p3##x,_n3##y,z,c), I[331] = (T)(img)(_p2##x,_n3##y,z,c), I[332] = (T)(img)(_p1##x,_n3##y,z,c), I[333] = (T)(img)(x,_n3##y,z,c), I[334] = (T)(img)(_n1##x,_n3##y,z,c), I[335] = (T)(img)(_n2##x,_n3##y,z,c), I[336] = (T)(img)(_n3##x,_n3##y,z,c), I[337] = (T)(img)(_n4##x,_n3##y,z,c), I[338] = (T)(img)(_n5##x,_n3##y,z,c), I[339] = (T)(img)(_n6##x,_n3##y,z,c), I[340] = (T)(img)(_n7##x,_n3##y,z,c), I[341] = (T)(img)(_n8##x,_n3##y,z,c), I[342] = (T)(img)(_n9##x,_n3##y,z,c), I[343] = (T)(img)(_n10##x,_n3##y,z,c), I[344] = (T)(img)(_n11##x,_n3##y,z,c), \ - I[345] = (T)(img)(_p11##x,_n4##y,z,c), I[346] = (T)(img)(_p10##x,_n4##y,z,c), I[347] = (T)(img)(_p9##x,_n4##y,z,c), I[348] = (T)(img)(_p8##x,_n4##y,z,c), I[349] = (T)(img)(_p7##x,_n4##y,z,c), I[350] = (T)(img)(_p6##x,_n4##y,z,c), I[351] = (T)(img)(_p5##x,_n4##y,z,c), I[352] = (T)(img)(_p4##x,_n4##y,z,c), I[353] = (T)(img)(_p3##x,_n4##y,z,c), I[354] = (T)(img)(_p2##x,_n4##y,z,c), I[355] = (T)(img)(_p1##x,_n4##y,z,c), I[356] = (T)(img)(x,_n4##y,z,c), I[357] = (T)(img)(_n1##x,_n4##y,z,c), I[358] = (T)(img)(_n2##x,_n4##y,z,c), I[359] = (T)(img)(_n3##x,_n4##y,z,c), I[360] = (T)(img)(_n4##x,_n4##y,z,c), I[361] = (T)(img)(_n5##x,_n4##y,z,c), I[362] = (T)(img)(_n6##x,_n4##y,z,c), I[363] = (T)(img)(_n7##x,_n4##y,z,c), I[364] = (T)(img)(_n8##x,_n4##y,z,c), I[365] = (T)(img)(_n9##x,_n4##y,z,c), I[366] = (T)(img)(_n10##x,_n4##y,z,c), I[367] = (T)(img)(_n11##x,_n4##y,z,c), \ - I[368] = (T)(img)(_p11##x,_n5##y,z,c), I[369] = (T)(img)(_p10##x,_n5##y,z,c), I[370] = (T)(img)(_p9##x,_n5##y,z,c), I[371] = (T)(img)(_p8##x,_n5##y,z,c), I[372] = (T)(img)(_p7##x,_n5##y,z,c), I[373] = (T)(img)(_p6##x,_n5##y,z,c), I[374] = (T)(img)(_p5##x,_n5##y,z,c), I[375] = (T)(img)(_p4##x,_n5##y,z,c), I[376] = (T)(img)(_p3##x,_n5##y,z,c), I[377] = (T)(img)(_p2##x,_n5##y,z,c), I[378] = (T)(img)(_p1##x,_n5##y,z,c), I[379] = (T)(img)(x,_n5##y,z,c), I[380] = (T)(img)(_n1##x,_n5##y,z,c), I[381] = (T)(img)(_n2##x,_n5##y,z,c), I[382] = (T)(img)(_n3##x,_n5##y,z,c), I[383] = (T)(img)(_n4##x,_n5##y,z,c), I[384] = (T)(img)(_n5##x,_n5##y,z,c), I[385] = (T)(img)(_n6##x,_n5##y,z,c), I[386] = (T)(img)(_n7##x,_n5##y,z,c), I[387] = (T)(img)(_n8##x,_n5##y,z,c), I[388] = (T)(img)(_n9##x,_n5##y,z,c), I[389] = (T)(img)(_n10##x,_n5##y,z,c), I[390] = (T)(img)(_n11##x,_n5##y,z,c), \ - I[391] = (T)(img)(_p11##x,_n6##y,z,c), I[392] = (T)(img)(_p10##x,_n6##y,z,c), I[393] = (T)(img)(_p9##x,_n6##y,z,c), I[394] = (T)(img)(_p8##x,_n6##y,z,c), I[395] = (T)(img)(_p7##x,_n6##y,z,c), I[396] = (T)(img)(_p6##x,_n6##y,z,c), I[397] = (T)(img)(_p5##x,_n6##y,z,c), I[398] = (T)(img)(_p4##x,_n6##y,z,c), I[399] = (T)(img)(_p3##x,_n6##y,z,c), I[400] = (T)(img)(_p2##x,_n6##y,z,c), I[401] = (T)(img)(_p1##x,_n6##y,z,c), I[402] = (T)(img)(x,_n6##y,z,c), I[403] = (T)(img)(_n1##x,_n6##y,z,c), I[404] = (T)(img)(_n2##x,_n6##y,z,c), I[405] = (T)(img)(_n3##x,_n6##y,z,c), I[406] = (T)(img)(_n4##x,_n6##y,z,c), I[407] = (T)(img)(_n5##x,_n6##y,z,c), I[408] = (T)(img)(_n6##x,_n6##y,z,c), I[409] = (T)(img)(_n7##x,_n6##y,z,c), I[410] = (T)(img)(_n8##x,_n6##y,z,c), I[411] = (T)(img)(_n9##x,_n6##y,z,c), I[412] = (T)(img)(_n10##x,_n6##y,z,c), I[413] = (T)(img)(_n11##x,_n6##y,z,c), \ - I[414] = (T)(img)(_p11##x,_n7##y,z,c), I[415] = (T)(img)(_p10##x,_n7##y,z,c), I[416] = (T)(img)(_p9##x,_n7##y,z,c), I[417] = (T)(img)(_p8##x,_n7##y,z,c), I[418] = (T)(img)(_p7##x,_n7##y,z,c), I[419] = (T)(img)(_p6##x,_n7##y,z,c), I[420] = (T)(img)(_p5##x,_n7##y,z,c), I[421] = (T)(img)(_p4##x,_n7##y,z,c), I[422] = (T)(img)(_p3##x,_n7##y,z,c), I[423] = (T)(img)(_p2##x,_n7##y,z,c), I[424] = (T)(img)(_p1##x,_n7##y,z,c), I[425] = (T)(img)(x,_n7##y,z,c), I[426] = (T)(img)(_n1##x,_n7##y,z,c), I[427] = (T)(img)(_n2##x,_n7##y,z,c), I[428] = (T)(img)(_n3##x,_n7##y,z,c), I[429] = (T)(img)(_n4##x,_n7##y,z,c), I[430] = (T)(img)(_n5##x,_n7##y,z,c), I[431] = (T)(img)(_n6##x,_n7##y,z,c), I[432] = (T)(img)(_n7##x,_n7##y,z,c), I[433] = (T)(img)(_n8##x,_n7##y,z,c), I[434] = (T)(img)(_n9##x,_n7##y,z,c), I[435] = (T)(img)(_n10##x,_n7##y,z,c), I[436] = (T)(img)(_n11##x,_n7##y,z,c), \ - I[437] = (T)(img)(_p11##x,_n8##y,z,c), I[438] = (T)(img)(_p10##x,_n8##y,z,c), I[439] = (T)(img)(_p9##x,_n8##y,z,c), I[440] = (T)(img)(_p8##x,_n8##y,z,c), I[441] = (T)(img)(_p7##x,_n8##y,z,c), I[442] = (T)(img)(_p6##x,_n8##y,z,c), I[443] = (T)(img)(_p5##x,_n8##y,z,c), I[444] = (T)(img)(_p4##x,_n8##y,z,c), I[445] = (T)(img)(_p3##x,_n8##y,z,c), I[446] = (T)(img)(_p2##x,_n8##y,z,c), I[447] = (T)(img)(_p1##x,_n8##y,z,c), I[448] = (T)(img)(x,_n8##y,z,c), I[449] = (T)(img)(_n1##x,_n8##y,z,c), I[450] = (T)(img)(_n2##x,_n8##y,z,c), I[451] = (T)(img)(_n3##x,_n8##y,z,c), I[452] = (T)(img)(_n4##x,_n8##y,z,c), I[453] = (T)(img)(_n5##x,_n8##y,z,c), I[454] = (T)(img)(_n6##x,_n8##y,z,c), I[455] = (T)(img)(_n7##x,_n8##y,z,c), I[456] = (T)(img)(_n8##x,_n8##y,z,c), I[457] = (T)(img)(_n9##x,_n8##y,z,c), I[458] = (T)(img)(_n10##x,_n8##y,z,c), I[459] = (T)(img)(_n11##x,_n8##y,z,c), \ - I[460] = (T)(img)(_p11##x,_n9##y,z,c), I[461] = (T)(img)(_p10##x,_n9##y,z,c), I[462] = (T)(img)(_p9##x,_n9##y,z,c), I[463] = (T)(img)(_p8##x,_n9##y,z,c), I[464] = (T)(img)(_p7##x,_n9##y,z,c), I[465] = (T)(img)(_p6##x,_n9##y,z,c), I[466] = (T)(img)(_p5##x,_n9##y,z,c), I[467] = (T)(img)(_p4##x,_n9##y,z,c), I[468] = (T)(img)(_p3##x,_n9##y,z,c), I[469] = (T)(img)(_p2##x,_n9##y,z,c), I[470] = (T)(img)(_p1##x,_n9##y,z,c), I[471] = (T)(img)(x,_n9##y,z,c), I[472] = (T)(img)(_n1##x,_n9##y,z,c), I[473] = (T)(img)(_n2##x,_n9##y,z,c), I[474] = (T)(img)(_n3##x,_n9##y,z,c), I[475] = (T)(img)(_n4##x,_n9##y,z,c), I[476] = (T)(img)(_n5##x,_n9##y,z,c), I[477] = (T)(img)(_n6##x,_n9##y,z,c), I[478] = (T)(img)(_n7##x,_n9##y,z,c), I[479] = (T)(img)(_n8##x,_n9##y,z,c), I[480] = (T)(img)(_n9##x,_n9##y,z,c), I[481] = (T)(img)(_n10##x,_n9##y,z,c), I[482] = (T)(img)(_n11##x,_n9##y,z,c), \ - I[483] = (T)(img)(_p11##x,_n10##y,z,c), I[484] = (T)(img)(_p10##x,_n10##y,z,c), I[485] = (T)(img)(_p9##x,_n10##y,z,c), I[486] = (T)(img)(_p8##x,_n10##y,z,c), I[487] = (T)(img)(_p7##x,_n10##y,z,c), I[488] = (T)(img)(_p6##x,_n10##y,z,c), I[489] = (T)(img)(_p5##x,_n10##y,z,c), I[490] = (T)(img)(_p4##x,_n10##y,z,c), I[491] = (T)(img)(_p3##x,_n10##y,z,c), I[492] = (T)(img)(_p2##x,_n10##y,z,c), I[493] = (T)(img)(_p1##x,_n10##y,z,c), I[494] = (T)(img)(x,_n10##y,z,c), I[495] = (T)(img)(_n1##x,_n10##y,z,c), I[496] = (T)(img)(_n2##x,_n10##y,z,c), I[497] = (T)(img)(_n3##x,_n10##y,z,c), I[498] = (T)(img)(_n4##x,_n10##y,z,c), I[499] = (T)(img)(_n5##x,_n10##y,z,c), I[500] = (T)(img)(_n6##x,_n10##y,z,c), I[501] = (T)(img)(_n7##x,_n10##y,z,c), I[502] = (T)(img)(_n8##x,_n10##y,z,c), I[503] = (T)(img)(_n9##x,_n10##y,z,c), I[504] = (T)(img)(_n10##x,_n10##y,z,c), I[505] = (T)(img)(_n11##x,_n10##y,z,c), \ - I[506] = (T)(img)(_p11##x,_n11##y,z,c), I[507] = (T)(img)(_p10##x,_n11##y,z,c), I[508] = (T)(img)(_p9##x,_n11##y,z,c), I[509] = (T)(img)(_p8##x,_n11##y,z,c), I[510] = (T)(img)(_p7##x,_n11##y,z,c), I[511] = (T)(img)(_p6##x,_n11##y,z,c), I[512] = (T)(img)(_p5##x,_n11##y,z,c), I[513] = (T)(img)(_p4##x,_n11##y,z,c), I[514] = (T)(img)(_p3##x,_n11##y,z,c), I[515] = (T)(img)(_p2##x,_n11##y,z,c), I[516] = (T)(img)(_p1##x,_n11##y,z,c), I[517] = (T)(img)(x,_n11##y,z,c), I[518] = (T)(img)(_n1##x,_n11##y,z,c), I[519] = (T)(img)(_n2##x,_n11##y,z,c), I[520] = (T)(img)(_n3##x,_n11##y,z,c), I[521] = (T)(img)(_n4##x,_n11##y,z,c), I[522] = (T)(img)(_n5##x,_n11##y,z,c), I[523] = (T)(img)(_n6##x,_n11##y,z,c), I[524] = (T)(img)(_n7##x,_n11##y,z,c), I[525] = (T)(img)(_n8##x,_n11##y,z,c), I[526] = (T)(img)(_n9##x,_n11##y,z,c), I[527] = (T)(img)(_n10##x,_n11##y,z,c), I[528] = (T)(img)(_n11##x,_n11##y,z,c); - -// Define 24x24 loop macros -//------------------------- -#define cimg_for24(bound,i) for (int i = 0, \ - _p11##i = 0, _p10##i = 0, _p9##i = 0, _p8##i = 0, _p7##i = 0, _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6, \ - _n7##i = 7>=(int)(bound)?(int)(bound) - 1:7, \ - _n8##i = 8>=(int)(bound)?(int)(bound) - 1:8, \ - _n9##i = 9>=(int)(bound)?(int)(bound) - 1:9, \ - _n10##i = 10>=(int)(bound)?(int)(bound) - 1:10, \ - _n11##i = 11>=(int)(bound)?(int)(bound) - 1:11, \ - _n12##i = 12>=(int)(bound)?(int)(bound) - 1:12; \ - _n12##i<(int)(bound) || _n11##i==--_n12##i || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n12##i = _n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i, ++_n12##i) - -#define cimg_for24X(img,x) cimg_for24((img)._width,x) -#define cimg_for24Y(img,y) cimg_for24((img)._height,y) -#define cimg_for24Z(img,z) cimg_for24((img)._depth,z) -#define cimg_for24C(img,c) cimg_for24((img)._spectrum,c) -#define cimg_for24XY(img,x,y) cimg_for24Y(img,y) cimg_for24X(img,x) -#define cimg_for24XZ(img,x,z) cimg_for24Z(img,z) cimg_for24X(img,x) -#define cimg_for24XC(img,x,c) cimg_for24C(img,c) cimg_for24X(img,x) -#define cimg_for24YZ(img,y,z) cimg_for24Z(img,z) cimg_for24Y(img,y) -#define cimg_for24YC(img,y,c) cimg_for24C(img,c) cimg_for24Y(img,y) -#define cimg_for24ZC(img,z,c) cimg_for24C(img,c) cimg_for24Z(img,z) -#define cimg_for24XYZ(img,x,y,z) cimg_for24Z(img,z) cimg_for24XY(img,x,y) -#define cimg_for24XZC(img,x,z,c) cimg_for24C(img,c) cimg_for24XZ(img,x,z) -#define cimg_for24YZC(img,y,z,c) cimg_for24C(img,c) cimg_for24YZ(img,y,z) -#define cimg_for24XYZC(img,x,y,z,c) cimg_for24C(img,c) cimg_for24XYZ(img,x,y,z) - -#define cimg_for_in24(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p11##i = i - 11<0?0:i - 11, \ - _p10##i = i - 10<0?0:i - 10, \ - _p9##i = i - 9<0?0:i - 9, \ - _p8##i = i - 8<0?0:i - 8, \ - _p7##i = i - 7<0?0:i - 7, \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6, \ - _n7##i = i + 7>=(int)(bound)?(int)(bound) - 1:i + 7, \ - _n8##i = i + 8>=(int)(bound)?(int)(bound) - 1:i + 8, \ - _n9##i = i + 9>=(int)(bound)?(int)(bound) - 1:i + 9, \ - _n10##i = i + 10>=(int)(bound)?(int)(bound) - 1:i + 10, \ - _n11##i = i + 11>=(int)(bound)?(int)(bound) - 1:i + 11, \ - _n12##i = i + 12>=(int)(bound)?(int)(bound) - 1:i + 12; \ - i<=(int)(i1) && (_n12##i<(int)(bound) || _n11##i==--_n12##i || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n12##i = _n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i, ++_n12##i) - -#define cimg_for_in24X(img,x0,x1,x) cimg_for_in24((img)._width,x0,x1,x) -#define cimg_for_in24Y(img,y0,y1,y) cimg_for_in24((img)._height,y0,y1,y) -#define cimg_for_in24Z(img,z0,z1,z) cimg_for_in24((img)._depth,z0,z1,z) -#define cimg_for_in24C(img,c0,c1,c) cimg_for_in24((img)._spectrum,c0,c1,c) -#define cimg_for_in24XY(img,x0,y0,x1,y1,x,y) cimg_for_in24Y(img,y0,y1,y) cimg_for_in24X(img,x0,x1,x) -#define cimg_for_in24XZ(img,x0,z0,x1,z1,x,z) cimg_for_in24Z(img,z0,z1,z) cimg_for_in24X(img,x0,x1,x) -#define cimg_for_in24XC(img,x0,c0,x1,c1,x,c) cimg_for_in24C(img,c0,c1,c) cimg_for_in24X(img,x0,x1,x) -#define cimg_for_in24YZ(img,y0,z0,y1,z1,y,z) cimg_for_in24Z(img,z0,z1,z) cimg_for_in24Y(img,y0,y1,y) -#define cimg_for_in24YC(img,y0,c0,y1,c1,y,c) cimg_for_in24C(img,c0,c1,c) cimg_for_in24Y(img,y0,y1,y) -#define cimg_for_in24ZC(img,z0,c0,z1,c1,z,c) cimg_for_in24C(img,c0,c1,c) cimg_for_in24Z(img,z0,z1,z) -#define cimg_for_in24XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in24Z(img,z0,z1,z) cimg_for_in24XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in24XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in24C(img,c0,c1,c) cimg_for_in24XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in24YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in24C(img,c0,c1,c) cimg_for_in24YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in24XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in24C(img,c0,c1,c) cimg_for_in24XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for24x24(img,x,y,z,c,I,T) \ - cimg_for24((img)._height,y) for (int x = 0, \ - _p11##x = 0, _p10##x = 0, _p9##x = 0, _p8##x = 0, _p7##x = 0, _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = 6>=((img)._width)?(img).width() - 1:6, \ - _n7##x = 7>=((img)._width)?(img).width() - 1:7, \ - _n8##x = 8>=((img)._width)?(img).width() - 1:8, \ - _n9##x = 9>=((img)._width)?(img).width() - 1:9, \ - _n10##x = 10>=((img)._width)?(img).width() - 1:10, \ - _n11##x = 11>=((img)._width)?(img).width() - 1:11, \ - _n12##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = I[7] = I[8] = I[9] = I[10] = I[11] = (T)(img)(0,_p11##y,z,c)), \ - (I[24] = I[25] = I[26] = I[27] = I[28] = I[29] = I[30] = I[31] = I[32] = I[33] = I[34] = I[35] = (T)(img)(0,_p10##y,z,c)), \ - (I[48] = I[49] = I[50] = I[51] = I[52] = I[53] = I[54] = I[55] = I[56] = I[57] = I[58] = I[59] = (T)(img)(0,_p9##y,z,c)), \ - (I[72] = I[73] = I[74] = I[75] = I[76] = I[77] = I[78] = I[79] = I[80] = I[81] = I[82] = I[83] = (T)(img)(0,_p8##y,z,c)), \ - (I[96] = I[97] = I[98] = I[99] = I[100] = I[101] = I[102] = I[103] = I[104] = I[105] = I[106] = I[107] = (T)(img)(0,_p7##y,z,c)), \ - (I[120] = I[121] = I[122] = I[123] = I[124] = I[125] = I[126] = I[127] = I[128] = I[129] = I[130] = I[131] = (T)(img)(0,_p6##y,z,c)), \ - (I[144] = I[145] = I[146] = I[147] = I[148] = I[149] = I[150] = I[151] = I[152] = I[153] = I[154] = I[155] = (T)(img)(0,_p5##y,z,c)), \ - (I[168] = I[169] = I[170] = I[171] = I[172] = I[173] = I[174] = I[175] = I[176] = I[177] = I[178] = I[179] = (T)(img)(0,_p4##y,z,c)), \ - (I[192] = I[193] = I[194] = I[195] = I[196] = I[197] = I[198] = I[199] = I[200] = I[201] = I[202] = I[203] = (T)(img)(0,_p3##y,z,c)), \ - (I[216] = I[217] = I[218] = I[219] = I[220] = I[221] = I[222] = I[223] = I[224] = I[225] = I[226] = I[227] = (T)(img)(0,_p2##y,z,c)), \ - (I[240] = I[241] = I[242] = I[243] = I[244] = I[245] = I[246] = I[247] = I[248] = I[249] = I[250] = I[251] = (T)(img)(0,_p1##y,z,c)), \ - (I[264] = I[265] = I[266] = I[267] = I[268] = I[269] = I[270] = I[271] = I[272] = I[273] = I[274] = I[275] = (T)(img)(0,y,z,c)), \ - (I[288] = I[289] = I[290] = I[291] = I[292] = I[293] = I[294] = I[295] = I[296] = I[297] = I[298] = I[299] = (T)(img)(0,_n1##y,z,c)), \ - (I[312] = I[313] = I[314] = I[315] = I[316] = I[317] = I[318] = I[319] = I[320] = I[321] = I[322] = I[323] = (T)(img)(0,_n2##y,z,c)), \ - (I[336] = I[337] = I[338] = I[339] = I[340] = I[341] = I[342] = I[343] = I[344] = I[345] = I[346] = I[347] = (T)(img)(0,_n3##y,z,c)), \ - (I[360] = I[361] = I[362] = I[363] = I[364] = I[365] = I[366] = I[367] = I[368] = I[369] = I[370] = I[371] = (T)(img)(0,_n4##y,z,c)), \ - (I[384] = I[385] = I[386] = I[387] = I[388] = I[389] = I[390] = I[391] = I[392] = I[393] = I[394] = I[395] = (T)(img)(0,_n5##y,z,c)), \ - (I[408] = I[409] = I[410] = I[411] = I[412] = I[413] = I[414] = I[415] = I[416] = I[417] = I[418] = I[419] = (T)(img)(0,_n6##y,z,c)), \ - (I[432] = I[433] = I[434] = I[435] = I[436] = I[437] = I[438] = I[439] = I[440] = I[441] = I[442] = I[443] = (T)(img)(0,_n7##y,z,c)), \ - (I[456] = I[457] = I[458] = I[459] = I[460] = I[461] = I[462] = I[463] = I[464] = I[465] = I[466] = I[467] = (T)(img)(0,_n8##y,z,c)), \ - (I[480] = I[481] = I[482] = I[483] = I[484] = I[485] = I[486] = I[487] = I[488] = I[489] = I[490] = I[491] = (T)(img)(0,_n9##y,z,c)), \ - (I[504] = I[505] = I[506] = I[507] = I[508] = I[509] = I[510] = I[511] = I[512] = I[513] = I[514] = I[515] = (T)(img)(0,_n10##y,z,c)), \ - (I[528] = I[529] = I[530] = I[531] = I[532] = I[533] = I[534] = I[535] = I[536] = I[537] = I[538] = I[539] = (T)(img)(0,_n11##y,z,c)), \ - (I[552] = I[553] = I[554] = I[555] = I[556] = I[557] = I[558] = I[559] = I[560] = I[561] = I[562] = I[563] = (T)(img)(0,_n12##y,z,c)), \ - (I[12] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[36] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[60] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[84] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[108] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[132] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[156] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[180] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[204] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[228] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[252] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[276] = (T)(img)(_n1##x,y,z,c)), \ - (I[300] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[324] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[348] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[372] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[396] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[420] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[444] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[468] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[492] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[516] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[540] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[564] = (T)(img)(_n1##x,_n12##y,z,c)), \ - (I[13] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[37] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[61] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[85] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[109] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[133] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[157] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[181] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[205] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[229] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[253] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[277] = (T)(img)(_n2##x,y,z,c)), \ - (I[301] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[325] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[349] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[373] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[397] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[421] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[445] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[469] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[493] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[517] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[541] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[565] = (T)(img)(_n2##x,_n12##y,z,c)), \ - (I[14] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[38] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[62] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[86] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[110] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[134] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[158] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[182] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[206] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[230] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[254] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[278] = (T)(img)(_n3##x,y,z,c)), \ - (I[302] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[326] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[350] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[374] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[398] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[422] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[446] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[470] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[494] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[518] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[542] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[566] = (T)(img)(_n3##x,_n12##y,z,c)), \ - (I[15] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[39] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[63] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[87] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[111] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[135] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[159] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[183] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[207] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[231] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[255] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[279] = (T)(img)(_n4##x,y,z,c)), \ - (I[303] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[327] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[351] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[375] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[399] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[423] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[447] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[471] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[495] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[519] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[543] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[567] = (T)(img)(_n4##x,_n12##y,z,c)), \ - (I[16] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[40] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[64] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[88] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[112] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[136] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[160] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[184] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[208] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[232] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[256] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[280] = (T)(img)(_n5##x,y,z,c)), \ - (I[304] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[328] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[352] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[376] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[400] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[424] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[448] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[472] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[496] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[520] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[544] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[568] = (T)(img)(_n5##x,_n12##y,z,c)), \ - (I[17] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[41] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[65] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[89] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[113] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[137] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[161] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[185] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[209] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[233] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[257] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[281] = (T)(img)(_n6##x,y,z,c)), \ - (I[305] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[329] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[353] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[377] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[401] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[425] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[449] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[473] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[497] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[521] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[545] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[569] = (T)(img)(_n6##x,_n12##y,z,c)), \ - (I[18] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[42] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[66] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[90] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[114] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[138] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[162] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[186] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[210] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[234] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[258] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[282] = (T)(img)(_n7##x,y,z,c)), \ - (I[306] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[330] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[354] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[378] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[402] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[426] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[450] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[474] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[498] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[522] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[546] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[570] = (T)(img)(_n7##x,_n12##y,z,c)), \ - (I[19] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[43] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[67] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[91] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[115] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[139] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[163] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[187] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[211] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[235] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[259] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[283] = (T)(img)(_n8##x,y,z,c)), \ - (I[307] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[331] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[355] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[379] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[403] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[427] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[451] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[475] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[499] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[523] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[547] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[571] = (T)(img)(_n8##x,_n12##y,z,c)), \ - (I[20] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[44] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[68] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[92] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[116] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[140] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[164] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[188] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[212] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[236] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[260] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[284] = (T)(img)(_n9##x,y,z,c)), \ - (I[308] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[332] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[356] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[380] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[404] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[428] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[452] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[476] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[500] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[524] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[548] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[572] = (T)(img)(_n9##x,_n12##y,z,c)), \ - (I[21] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[45] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[69] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[93] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[117] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[141] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[165] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[189] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[213] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[237] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[261] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[285] = (T)(img)(_n10##x,y,z,c)), \ - (I[309] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[333] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[357] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[381] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[405] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[429] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[453] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[477] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[501] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[525] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[549] = (T)(img)(_n10##x,_n11##y,z,c)), \ - (I[573] = (T)(img)(_n10##x,_n12##y,z,c)), \ - (I[22] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[46] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[70] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[94] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[118] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[142] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[166] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[190] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[214] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[238] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[262] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[286] = (T)(img)(_n11##x,y,z,c)), \ - (I[310] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[334] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[358] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[382] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[406] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[430] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[454] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[478] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[502] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[526] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[550] = (T)(img)(_n11##x,_n11##y,z,c)), \ - (I[574] = (T)(img)(_n11##x,_n12##y,z,c)), \ - 12>=((img)._width)?(img).width() - 1:12); \ - (_n12##x<(img).width() && ( \ - (I[23] = (T)(img)(_n12##x,_p11##y,z,c)), \ - (I[47] = (T)(img)(_n12##x,_p10##y,z,c)), \ - (I[71] = (T)(img)(_n12##x,_p9##y,z,c)), \ - (I[95] = (T)(img)(_n12##x,_p8##y,z,c)), \ - (I[119] = (T)(img)(_n12##x,_p7##y,z,c)), \ - (I[143] = (T)(img)(_n12##x,_p6##y,z,c)), \ - (I[167] = (T)(img)(_n12##x,_p5##y,z,c)), \ - (I[191] = (T)(img)(_n12##x,_p4##y,z,c)), \ - (I[215] = (T)(img)(_n12##x,_p3##y,z,c)), \ - (I[239] = (T)(img)(_n12##x,_p2##y,z,c)), \ - (I[263] = (T)(img)(_n12##x,_p1##y,z,c)), \ - (I[287] = (T)(img)(_n12##x,y,z,c)), \ - (I[311] = (T)(img)(_n12##x,_n1##y,z,c)), \ - (I[335] = (T)(img)(_n12##x,_n2##y,z,c)), \ - (I[359] = (T)(img)(_n12##x,_n3##y,z,c)), \ - (I[383] = (T)(img)(_n12##x,_n4##y,z,c)), \ - (I[407] = (T)(img)(_n12##x,_n5##y,z,c)), \ - (I[431] = (T)(img)(_n12##x,_n6##y,z,c)), \ - (I[455] = (T)(img)(_n12##x,_n7##y,z,c)), \ - (I[479] = (T)(img)(_n12##x,_n8##y,z,c)), \ - (I[503] = (T)(img)(_n12##x,_n9##y,z,c)), \ - (I[527] = (T)(img)(_n12##x,_n10##y,z,c)), \ - (I[551] = (T)(img)(_n12##x,_n11##y,z,c)), \ - (I[575] = (T)(img)(_n12##x,_n12##y,z,c)),1)) || \ - _n11##x==--_n12##x || _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n12##x = _n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \ - I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], \ - I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], \ - I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], \ - I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], \ - I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], \ - I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], \ - I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], \ - I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], \ - I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], \ - I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], \ - I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], \ - I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], \ - I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], \ - I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], \ - I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], \ - I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], \ - I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], I[415] = I[416], I[416] = I[417], I[417] = I[418], I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], \ - I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], I[447] = I[448], I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], \ - I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], I[463] = I[464], I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], \ - I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], I[493] = I[494], I[494] = I[495], I[495] = I[496], I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], \ - I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], I[511] = I[512], I[512] = I[513], I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], I[519] = I[520], I[520] = I[521], I[521] = I[522], I[522] = I[523], I[523] = I[524], I[524] = I[525], I[525] = I[526], I[526] = I[527], \ - I[528] = I[529], I[529] = I[530], I[530] = I[531], I[531] = I[532], I[532] = I[533], I[533] = I[534], I[534] = I[535], I[535] = I[536], I[536] = I[537], I[537] = I[538], I[538] = I[539], I[539] = I[540], I[540] = I[541], I[541] = I[542], I[542] = I[543], I[543] = I[544], I[544] = I[545], I[545] = I[546], I[546] = I[547], I[547] = I[548], I[548] = I[549], I[549] = I[550], I[550] = I[551], \ - I[552] = I[553], I[553] = I[554], I[554] = I[555], I[555] = I[556], I[556] = I[557], I[557] = I[558], I[558] = I[559], I[559] = I[560], I[560] = I[561], I[561] = I[562], I[562] = I[563], I[563] = I[564], I[564] = I[565], I[565] = I[566], I[566] = I[567], I[567] = I[568], I[568] = I[569], I[569] = I[570], I[570] = I[571], I[571] = I[572], I[572] = I[573], I[573] = I[574], I[574] = I[575], \ - _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x, ++_n12##x) - -#define cimg_for_in24x24(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in24((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p11##x = x - 11<0?0:x - 11, \ - _p10##x = x - 10<0?0:x - 10, \ - _p9##x = x - 9<0?0:x - 9, \ - _p8##x = x - 8<0?0:x - 8, \ - _p7##x = x - 7<0?0:x - 7, \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = x + 6>=(img).width()?(img).width() - 1:x + 6, \ - _n7##x = x + 7>=(img).width()?(img).width() - 1:x + 7, \ - _n8##x = x + 8>=(img).width()?(img).width() - 1:x + 8, \ - _n9##x = x + 9>=(img).width()?(img).width() - 1:x + 9, \ - _n10##x = x + 10>=(img).width()?(img).width() - 1:x + 10, \ - _n11##x = x + 11>=(img).width()?(img).width() - 1:x + 11, \ - _n12##x = (int)( \ - (I[0] = (T)(img)(_p11##x,_p11##y,z,c)), \ - (I[24] = (T)(img)(_p11##x,_p10##y,z,c)), \ - (I[48] = (T)(img)(_p11##x,_p9##y,z,c)), \ - (I[72] = (T)(img)(_p11##x,_p8##y,z,c)), \ - (I[96] = (T)(img)(_p11##x,_p7##y,z,c)), \ - (I[120] = (T)(img)(_p11##x,_p6##y,z,c)), \ - (I[144] = (T)(img)(_p11##x,_p5##y,z,c)), \ - (I[168] = (T)(img)(_p11##x,_p4##y,z,c)), \ - (I[192] = (T)(img)(_p11##x,_p3##y,z,c)), \ - (I[216] = (T)(img)(_p11##x,_p2##y,z,c)), \ - (I[240] = (T)(img)(_p11##x,_p1##y,z,c)), \ - (I[264] = (T)(img)(_p11##x,y,z,c)), \ - (I[288] = (T)(img)(_p11##x,_n1##y,z,c)), \ - (I[312] = (T)(img)(_p11##x,_n2##y,z,c)), \ - (I[336] = (T)(img)(_p11##x,_n3##y,z,c)), \ - (I[360] = (T)(img)(_p11##x,_n4##y,z,c)), \ - (I[384] = (T)(img)(_p11##x,_n5##y,z,c)), \ - (I[408] = (T)(img)(_p11##x,_n6##y,z,c)), \ - (I[432] = (T)(img)(_p11##x,_n7##y,z,c)), \ - (I[456] = (T)(img)(_p11##x,_n8##y,z,c)), \ - (I[480] = (T)(img)(_p11##x,_n9##y,z,c)), \ - (I[504] = (T)(img)(_p11##x,_n10##y,z,c)), \ - (I[528] = (T)(img)(_p11##x,_n11##y,z,c)), \ - (I[552] = (T)(img)(_p11##x,_n12##y,z,c)), \ - (I[1] = (T)(img)(_p10##x,_p11##y,z,c)), \ - (I[25] = (T)(img)(_p10##x,_p10##y,z,c)), \ - (I[49] = (T)(img)(_p10##x,_p9##y,z,c)), \ - (I[73] = (T)(img)(_p10##x,_p8##y,z,c)), \ - (I[97] = (T)(img)(_p10##x,_p7##y,z,c)), \ - (I[121] = (T)(img)(_p10##x,_p6##y,z,c)), \ - (I[145] = (T)(img)(_p10##x,_p5##y,z,c)), \ - (I[169] = (T)(img)(_p10##x,_p4##y,z,c)), \ - (I[193] = (T)(img)(_p10##x,_p3##y,z,c)), \ - (I[217] = (T)(img)(_p10##x,_p2##y,z,c)), \ - (I[241] = (T)(img)(_p10##x,_p1##y,z,c)), \ - (I[265] = (T)(img)(_p10##x,y,z,c)), \ - (I[289] = (T)(img)(_p10##x,_n1##y,z,c)), \ - (I[313] = (T)(img)(_p10##x,_n2##y,z,c)), \ - (I[337] = (T)(img)(_p10##x,_n3##y,z,c)), \ - (I[361] = (T)(img)(_p10##x,_n4##y,z,c)), \ - (I[385] = (T)(img)(_p10##x,_n5##y,z,c)), \ - (I[409] = (T)(img)(_p10##x,_n6##y,z,c)), \ - (I[433] = (T)(img)(_p10##x,_n7##y,z,c)), \ - (I[457] = (T)(img)(_p10##x,_n8##y,z,c)), \ - (I[481] = (T)(img)(_p10##x,_n9##y,z,c)), \ - (I[505] = (T)(img)(_p10##x,_n10##y,z,c)), \ - (I[529] = (T)(img)(_p10##x,_n11##y,z,c)), \ - (I[553] = (T)(img)(_p10##x,_n12##y,z,c)), \ - (I[2] = (T)(img)(_p9##x,_p11##y,z,c)), \ - (I[26] = (T)(img)(_p9##x,_p10##y,z,c)), \ - (I[50] = (T)(img)(_p9##x,_p9##y,z,c)), \ - (I[74] = (T)(img)(_p9##x,_p8##y,z,c)), \ - (I[98] = (T)(img)(_p9##x,_p7##y,z,c)), \ - (I[122] = (T)(img)(_p9##x,_p6##y,z,c)), \ - (I[146] = (T)(img)(_p9##x,_p5##y,z,c)), \ - (I[170] = (T)(img)(_p9##x,_p4##y,z,c)), \ - (I[194] = (T)(img)(_p9##x,_p3##y,z,c)), \ - (I[218] = (T)(img)(_p9##x,_p2##y,z,c)), \ - (I[242] = (T)(img)(_p9##x,_p1##y,z,c)), \ - (I[266] = (T)(img)(_p9##x,y,z,c)), \ - (I[290] = (T)(img)(_p9##x,_n1##y,z,c)), \ - (I[314] = (T)(img)(_p9##x,_n2##y,z,c)), \ - (I[338] = (T)(img)(_p9##x,_n3##y,z,c)), \ - (I[362] = (T)(img)(_p9##x,_n4##y,z,c)), \ - (I[386] = (T)(img)(_p9##x,_n5##y,z,c)), \ - (I[410] = (T)(img)(_p9##x,_n6##y,z,c)), \ - (I[434] = (T)(img)(_p9##x,_n7##y,z,c)), \ - (I[458] = (T)(img)(_p9##x,_n8##y,z,c)), \ - (I[482] = (T)(img)(_p9##x,_n9##y,z,c)), \ - (I[506] = (T)(img)(_p9##x,_n10##y,z,c)), \ - (I[530] = (T)(img)(_p9##x,_n11##y,z,c)), \ - (I[554] = (T)(img)(_p9##x,_n12##y,z,c)), \ - (I[3] = (T)(img)(_p8##x,_p11##y,z,c)), \ - (I[27] = (T)(img)(_p8##x,_p10##y,z,c)), \ - (I[51] = (T)(img)(_p8##x,_p9##y,z,c)), \ - (I[75] = (T)(img)(_p8##x,_p8##y,z,c)), \ - (I[99] = (T)(img)(_p8##x,_p7##y,z,c)), \ - (I[123] = (T)(img)(_p8##x,_p6##y,z,c)), \ - (I[147] = (T)(img)(_p8##x,_p5##y,z,c)), \ - (I[171] = (T)(img)(_p8##x,_p4##y,z,c)), \ - (I[195] = (T)(img)(_p8##x,_p3##y,z,c)), \ - (I[219] = (T)(img)(_p8##x,_p2##y,z,c)), \ - (I[243] = (T)(img)(_p8##x,_p1##y,z,c)), \ - (I[267] = (T)(img)(_p8##x,y,z,c)), \ - (I[291] = (T)(img)(_p8##x,_n1##y,z,c)), \ - (I[315] = (T)(img)(_p8##x,_n2##y,z,c)), \ - (I[339] = (T)(img)(_p8##x,_n3##y,z,c)), \ - (I[363] = (T)(img)(_p8##x,_n4##y,z,c)), \ - (I[387] = (T)(img)(_p8##x,_n5##y,z,c)), \ - (I[411] = (T)(img)(_p8##x,_n6##y,z,c)), \ - (I[435] = (T)(img)(_p8##x,_n7##y,z,c)), \ - (I[459] = (T)(img)(_p8##x,_n8##y,z,c)), \ - (I[483] = (T)(img)(_p8##x,_n9##y,z,c)), \ - (I[507] = (T)(img)(_p8##x,_n10##y,z,c)), \ - (I[531] = (T)(img)(_p8##x,_n11##y,z,c)), \ - (I[555] = (T)(img)(_p8##x,_n12##y,z,c)), \ - (I[4] = (T)(img)(_p7##x,_p11##y,z,c)), \ - (I[28] = (T)(img)(_p7##x,_p10##y,z,c)), \ - (I[52] = (T)(img)(_p7##x,_p9##y,z,c)), \ - (I[76] = (T)(img)(_p7##x,_p8##y,z,c)), \ - (I[100] = (T)(img)(_p7##x,_p7##y,z,c)), \ - (I[124] = (T)(img)(_p7##x,_p6##y,z,c)), \ - (I[148] = (T)(img)(_p7##x,_p5##y,z,c)), \ - (I[172] = (T)(img)(_p7##x,_p4##y,z,c)), \ - (I[196] = (T)(img)(_p7##x,_p3##y,z,c)), \ - (I[220] = (T)(img)(_p7##x,_p2##y,z,c)), \ - (I[244] = (T)(img)(_p7##x,_p1##y,z,c)), \ - (I[268] = (T)(img)(_p7##x,y,z,c)), \ - (I[292] = (T)(img)(_p7##x,_n1##y,z,c)), \ - (I[316] = (T)(img)(_p7##x,_n2##y,z,c)), \ - (I[340] = (T)(img)(_p7##x,_n3##y,z,c)), \ - (I[364] = (T)(img)(_p7##x,_n4##y,z,c)), \ - (I[388] = (T)(img)(_p7##x,_n5##y,z,c)), \ - (I[412] = (T)(img)(_p7##x,_n6##y,z,c)), \ - (I[436] = (T)(img)(_p7##x,_n7##y,z,c)), \ - (I[460] = (T)(img)(_p7##x,_n8##y,z,c)), \ - (I[484] = (T)(img)(_p7##x,_n9##y,z,c)), \ - (I[508] = (T)(img)(_p7##x,_n10##y,z,c)), \ - (I[532] = (T)(img)(_p7##x,_n11##y,z,c)), \ - (I[556] = (T)(img)(_p7##x,_n12##y,z,c)), \ - (I[5] = (T)(img)(_p6##x,_p11##y,z,c)), \ - (I[29] = (T)(img)(_p6##x,_p10##y,z,c)), \ - (I[53] = (T)(img)(_p6##x,_p9##y,z,c)), \ - (I[77] = (T)(img)(_p6##x,_p8##y,z,c)), \ - (I[101] = (T)(img)(_p6##x,_p7##y,z,c)), \ - (I[125] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[149] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[173] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[197] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[221] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[245] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[269] = (T)(img)(_p6##x,y,z,c)), \ - (I[293] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[317] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[341] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[365] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[389] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[413] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[437] = (T)(img)(_p6##x,_n7##y,z,c)), \ - (I[461] = (T)(img)(_p6##x,_n8##y,z,c)), \ - (I[485] = (T)(img)(_p6##x,_n9##y,z,c)), \ - (I[509] = (T)(img)(_p6##x,_n10##y,z,c)), \ - (I[533] = (T)(img)(_p6##x,_n11##y,z,c)), \ - (I[557] = (T)(img)(_p6##x,_n12##y,z,c)), \ - (I[6] = (T)(img)(_p5##x,_p11##y,z,c)), \ - (I[30] = (T)(img)(_p5##x,_p10##y,z,c)), \ - (I[54] = (T)(img)(_p5##x,_p9##y,z,c)), \ - (I[78] = (T)(img)(_p5##x,_p8##y,z,c)), \ - (I[102] = (T)(img)(_p5##x,_p7##y,z,c)), \ - (I[126] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[150] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[174] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[198] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[222] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[246] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[270] = (T)(img)(_p5##x,y,z,c)), \ - (I[294] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[318] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[342] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[366] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[390] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[414] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[438] = (T)(img)(_p5##x,_n7##y,z,c)), \ - (I[462] = (T)(img)(_p5##x,_n8##y,z,c)), \ - (I[486] = (T)(img)(_p5##x,_n9##y,z,c)), \ - (I[510] = (T)(img)(_p5##x,_n10##y,z,c)), \ - (I[534] = (T)(img)(_p5##x,_n11##y,z,c)), \ - (I[558] = (T)(img)(_p5##x,_n12##y,z,c)), \ - (I[7] = (T)(img)(_p4##x,_p11##y,z,c)), \ - (I[31] = (T)(img)(_p4##x,_p10##y,z,c)), \ - (I[55] = (T)(img)(_p4##x,_p9##y,z,c)), \ - (I[79] = (T)(img)(_p4##x,_p8##y,z,c)), \ - (I[103] = (T)(img)(_p4##x,_p7##y,z,c)), \ - (I[127] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[151] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[175] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[199] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[223] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[247] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[271] = (T)(img)(_p4##x,y,z,c)), \ - (I[295] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[319] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[343] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[367] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[391] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[415] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[439] = (T)(img)(_p4##x,_n7##y,z,c)), \ - (I[463] = (T)(img)(_p4##x,_n8##y,z,c)), \ - (I[487] = (T)(img)(_p4##x,_n9##y,z,c)), \ - (I[511] = (T)(img)(_p4##x,_n10##y,z,c)), \ - (I[535] = (T)(img)(_p4##x,_n11##y,z,c)), \ - (I[559] = (T)(img)(_p4##x,_n12##y,z,c)), \ - (I[8] = (T)(img)(_p3##x,_p11##y,z,c)), \ - (I[32] = (T)(img)(_p3##x,_p10##y,z,c)), \ - (I[56] = (T)(img)(_p3##x,_p9##y,z,c)), \ - (I[80] = (T)(img)(_p3##x,_p8##y,z,c)), \ - (I[104] = (T)(img)(_p3##x,_p7##y,z,c)), \ - (I[128] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[152] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[176] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[200] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[224] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[248] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[272] = (T)(img)(_p3##x,y,z,c)), \ - (I[296] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[320] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[344] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[368] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[392] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[416] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[440] = (T)(img)(_p3##x,_n7##y,z,c)), \ - (I[464] = (T)(img)(_p3##x,_n8##y,z,c)), \ - (I[488] = (T)(img)(_p3##x,_n9##y,z,c)), \ - (I[512] = (T)(img)(_p3##x,_n10##y,z,c)), \ - (I[536] = (T)(img)(_p3##x,_n11##y,z,c)), \ - (I[560] = (T)(img)(_p3##x,_n12##y,z,c)), \ - (I[9] = (T)(img)(_p2##x,_p11##y,z,c)), \ - (I[33] = (T)(img)(_p2##x,_p10##y,z,c)), \ - (I[57] = (T)(img)(_p2##x,_p9##y,z,c)), \ - (I[81] = (T)(img)(_p2##x,_p8##y,z,c)), \ - (I[105] = (T)(img)(_p2##x,_p7##y,z,c)), \ - (I[129] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[153] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[177] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[201] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[225] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[249] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[273] = (T)(img)(_p2##x,y,z,c)), \ - (I[297] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[321] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[345] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[369] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[393] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[417] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[441] = (T)(img)(_p2##x,_n7##y,z,c)), \ - (I[465] = (T)(img)(_p2##x,_n8##y,z,c)), \ - (I[489] = (T)(img)(_p2##x,_n9##y,z,c)), \ - (I[513] = (T)(img)(_p2##x,_n10##y,z,c)), \ - (I[537] = (T)(img)(_p2##x,_n11##y,z,c)), \ - (I[561] = (T)(img)(_p2##x,_n12##y,z,c)), \ - (I[10] = (T)(img)(_p1##x,_p11##y,z,c)), \ - (I[34] = (T)(img)(_p1##x,_p10##y,z,c)), \ - (I[58] = (T)(img)(_p1##x,_p9##y,z,c)), \ - (I[82] = (T)(img)(_p1##x,_p8##y,z,c)), \ - (I[106] = (T)(img)(_p1##x,_p7##y,z,c)), \ - (I[130] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[154] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[178] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[202] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[226] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[250] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[274] = (T)(img)(_p1##x,y,z,c)), \ - (I[298] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[322] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[346] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[370] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[394] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[418] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[442] = (T)(img)(_p1##x,_n7##y,z,c)), \ - (I[466] = (T)(img)(_p1##x,_n8##y,z,c)), \ - (I[490] = (T)(img)(_p1##x,_n9##y,z,c)), \ - (I[514] = (T)(img)(_p1##x,_n10##y,z,c)), \ - (I[538] = (T)(img)(_p1##x,_n11##y,z,c)), \ - (I[562] = (T)(img)(_p1##x,_n12##y,z,c)), \ - (I[11] = (T)(img)(x,_p11##y,z,c)), \ - (I[35] = (T)(img)(x,_p10##y,z,c)), \ - (I[59] = (T)(img)(x,_p9##y,z,c)), \ - (I[83] = (T)(img)(x,_p8##y,z,c)), \ - (I[107] = (T)(img)(x,_p7##y,z,c)), \ - (I[131] = (T)(img)(x,_p6##y,z,c)), \ - (I[155] = (T)(img)(x,_p5##y,z,c)), \ - (I[179] = (T)(img)(x,_p4##y,z,c)), \ - (I[203] = (T)(img)(x,_p3##y,z,c)), \ - (I[227] = (T)(img)(x,_p2##y,z,c)), \ - (I[251] = (T)(img)(x,_p1##y,z,c)), \ - (I[275] = (T)(img)(x,y,z,c)), \ - (I[299] = (T)(img)(x,_n1##y,z,c)), \ - (I[323] = (T)(img)(x,_n2##y,z,c)), \ - (I[347] = (T)(img)(x,_n3##y,z,c)), \ - (I[371] = (T)(img)(x,_n4##y,z,c)), \ - (I[395] = (T)(img)(x,_n5##y,z,c)), \ - (I[419] = (T)(img)(x,_n6##y,z,c)), \ - (I[443] = (T)(img)(x,_n7##y,z,c)), \ - (I[467] = (T)(img)(x,_n8##y,z,c)), \ - (I[491] = (T)(img)(x,_n9##y,z,c)), \ - (I[515] = (T)(img)(x,_n10##y,z,c)), \ - (I[539] = (T)(img)(x,_n11##y,z,c)), \ - (I[563] = (T)(img)(x,_n12##y,z,c)), \ - (I[12] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[36] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[60] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[84] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[108] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[132] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[156] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[180] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[204] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[228] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[252] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[276] = (T)(img)(_n1##x,y,z,c)), \ - (I[300] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[324] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[348] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[372] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[396] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[420] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[444] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[468] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[492] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[516] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[540] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[564] = (T)(img)(_n1##x,_n12##y,z,c)), \ - (I[13] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[37] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[61] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[85] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[109] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[133] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[157] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[181] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[205] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[229] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[253] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[277] = (T)(img)(_n2##x,y,z,c)), \ - (I[301] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[325] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[349] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[373] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[397] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[421] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[445] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[469] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[493] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[517] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[541] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[565] = (T)(img)(_n2##x,_n12##y,z,c)), \ - (I[14] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[38] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[62] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[86] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[110] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[134] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[158] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[182] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[206] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[230] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[254] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[278] = (T)(img)(_n3##x,y,z,c)), \ - (I[302] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[326] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[350] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[374] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[398] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[422] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[446] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[470] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[494] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[518] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[542] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[566] = (T)(img)(_n3##x,_n12##y,z,c)), \ - (I[15] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[39] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[63] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[87] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[111] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[135] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[159] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[183] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[207] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[231] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[255] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[279] = (T)(img)(_n4##x,y,z,c)), \ - (I[303] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[327] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[351] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[375] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[399] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[423] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[447] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[471] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[495] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[519] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[543] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[567] = (T)(img)(_n4##x,_n12##y,z,c)), \ - (I[16] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[40] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[64] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[88] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[112] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[136] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[160] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[184] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[208] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[232] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[256] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[280] = (T)(img)(_n5##x,y,z,c)), \ - (I[304] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[328] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[352] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[376] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[400] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[424] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[448] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[472] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[496] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[520] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[544] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[568] = (T)(img)(_n5##x,_n12##y,z,c)), \ - (I[17] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[41] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[65] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[89] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[113] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[137] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[161] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[185] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[209] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[233] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[257] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[281] = (T)(img)(_n6##x,y,z,c)), \ - (I[305] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[329] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[353] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[377] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[401] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[425] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[449] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[473] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[497] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[521] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[545] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[569] = (T)(img)(_n6##x,_n12##y,z,c)), \ - (I[18] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[42] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[66] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[90] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[114] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[138] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[162] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[186] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[210] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[234] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[258] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[282] = (T)(img)(_n7##x,y,z,c)), \ - (I[306] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[330] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[354] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[378] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[402] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[426] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[450] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[474] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[498] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[522] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[546] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[570] = (T)(img)(_n7##x,_n12##y,z,c)), \ - (I[19] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[43] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[67] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[91] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[115] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[139] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[163] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[187] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[211] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[235] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[259] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[283] = (T)(img)(_n8##x,y,z,c)), \ - (I[307] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[331] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[355] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[379] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[403] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[427] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[451] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[475] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[499] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[523] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[547] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[571] = (T)(img)(_n8##x,_n12##y,z,c)), \ - (I[20] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[44] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[68] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[92] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[116] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[140] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[164] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[188] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[212] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[236] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[260] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[284] = (T)(img)(_n9##x,y,z,c)), \ - (I[308] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[332] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[356] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[380] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[404] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[428] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[452] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[476] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[500] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[524] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[548] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[572] = (T)(img)(_n9##x,_n12##y,z,c)), \ - (I[21] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[45] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[69] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[93] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[117] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[141] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[165] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[189] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[213] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[237] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[261] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[285] = (T)(img)(_n10##x,y,z,c)), \ - (I[309] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[333] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[357] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[381] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[405] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[429] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[453] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[477] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[501] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[525] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[549] = (T)(img)(_n10##x,_n11##y,z,c)), \ - (I[573] = (T)(img)(_n10##x,_n12##y,z,c)), \ - (I[22] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[46] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[70] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[94] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[118] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[142] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[166] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[190] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[214] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[238] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[262] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[286] = (T)(img)(_n11##x,y,z,c)), \ - (I[310] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[334] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[358] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[382] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[406] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[430] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[454] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[478] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[502] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[526] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[550] = (T)(img)(_n11##x,_n11##y,z,c)), \ - (I[574] = (T)(img)(_n11##x,_n12##y,z,c)), \ - x + 12>=(img).width()?(img).width() - 1:x + 12); \ - x<=(int)(x1) && ((_n12##x<(img).width() && ( \ - (I[23] = (T)(img)(_n12##x,_p11##y,z,c)), \ - (I[47] = (T)(img)(_n12##x,_p10##y,z,c)), \ - (I[71] = (T)(img)(_n12##x,_p9##y,z,c)), \ - (I[95] = (T)(img)(_n12##x,_p8##y,z,c)), \ - (I[119] = (T)(img)(_n12##x,_p7##y,z,c)), \ - (I[143] = (T)(img)(_n12##x,_p6##y,z,c)), \ - (I[167] = (T)(img)(_n12##x,_p5##y,z,c)), \ - (I[191] = (T)(img)(_n12##x,_p4##y,z,c)), \ - (I[215] = (T)(img)(_n12##x,_p3##y,z,c)), \ - (I[239] = (T)(img)(_n12##x,_p2##y,z,c)), \ - (I[263] = (T)(img)(_n12##x,_p1##y,z,c)), \ - (I[287] = (T)(img)(_n12##x,y,z,c)), \ - (I[311] = (T)(img)(_n12##x,_n1##y,z,c)), \ - (I[335] = (T)(img)(_n12##x,_n2##y,z,c)), \ - (I[359] = (T)(img)(_n12##x,_n3##y,z,c)), \ - (I[383] = (T)(img)(_n12##x,_n4##y,z,c)), \ - (I[407] = (T)(img)(_n12##x,_n5##y,z,c)), \ - (I[431] = (T)(img)(_n12##x,_n6##y,z,c)), \ - (I[455] = (T)(img)(_n12##x,_n7##y,z,c)), \ - (I[479] = (T)(img)(_n12##x,_n8##y,z,c)), \ - (I[503] = (T)(img)(_n12##x,_n9##y,z,c)), \ - (I[527] = (T)(img)(_n12##x,_n10##y,z,c)), \ - (I[551] = (T)(img)(_n12##x,_n11##y,z,c)), \ - (I[575] = (T)(img)(_n12##x,_n12##y,z,c)),1)) || \ - _n11##x==--_n12##x || _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n12##x = _n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \ - I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], \ - I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], \ - I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], \ - I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], \ - I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], \ - I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], \ - I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], \ - I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], \ - I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], \ - I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], \ - I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], \ - I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], \ - I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], \ - I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], \ - I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], \ - I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], \ - I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], I[415] = I[416], I[416] = I[417], I[417] = I[418], I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], \ - I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], I[447] = I[448], I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], \ - I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], I[463] = I[464], I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], \ - I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], I[493] = I[494], I[494] = I[495], I[495] = I[496], I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], \ - I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], I[511] = I[512], I[512] = I[513], I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], I[519] = I[520], I[520] = I[521], I[521] = I[522], I[522] = I[523], I[523] = I[524], I[524] = I[525], I[525] = I[526], I[526] = I[527], \ - I[528] = I[529], I[529] = I[530], I[530] = I[531], I[531] = I[532], I[532] = I[533], I[533] = I[534], I[534] = I[535], I[535] = I[536], I[536] = I[537], I[537] = I[538], I[538] = I[539], I[539] = I[540], I[540] = I[541], I[541] = I[542], I[542] = I[543], I[543] = I[544], I[544] = I[545], I[545] = I[546], I[546] = I[547], I[547] = I[548], I[548] = I[549], I[549] = I[550], I[550] = I[551], \ - I[552] = I[553], I[553] = I[554], I[554] = I[555], I[555] = I[556], I[556] = I[557], I[557] = I[558], I[558] = I[559], I[559] = I[560], I[560] = I[561], I[561] = I[562], I[562] = I[563], I[563] = I[564], I[564] = I[565], I[565] = I[566], I[566] = I[567], I[567] = I[568], I[568] = I[569], I[569] = I[570], I[570] = I[571], I[571] = I[572], I[572] = I[573], I[573] = I[574], I[574] = I[575], \ - _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x, ++_n12##x) - -#define cimg_get24x24(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p11##x,_p11##y,z,c), I[1] = (T)(img)(_p10##x,_p11##y,z,c), I[2] = (T)(img)(_p9##x,_p11##y,z,c), I[3] = (T)(img)(_p8##x,_p11##y,z,c), I[4] = (T)(img)(_p7##x,_p11##y,z,c), I[5] = (T)(img)(_p6##x,_p11##y,z,c), I[6] = (T)(img)(_p5##x,_p11##y,z,c), I[7] = (T)(img)(_p4##x,_p11##y,z,c), I[8] = (T)(img)(_p3##x,_p11##y,z,c), I[9] = (T)(img)(_p2##x,_p11##y,z,c), I[10] = (T)(img)(_p1##x,_p11##y,z,c), I[11] = (T)(img)(x,_p11##y,z,c), I[12] = (T)(img)(_n1##x,_p11##y,z,c), I[13] = (T)(img)(_n2##x,_p11##y,z,c), I[14] = (T)(img)(_n3##x,_p11##y,z,c), I[15] = (T)(img)(_n4##x,_p11##y,z,c), I[16] = (T)(img)(_n5##x,_p11##y,z,c), I[17] = (T)(img)(_n6##x,_p11##y,z,c), I[18] = (T)(img)(_n7##x,_p11##y,z,c), I[19] = (T)(img)(_n8##x,_p11##y,z,c), I[20] = (T)(img)(_n9##x,_p11##y,z,c), I[21] = (T)(img)(_n10##x,_p11##y,z,c), I[22] = (T)(img)(_n11##x,_p11##y,z,c), I[23] = (T)(img)(_n12##x,_p11##y,z,c), \ - I[24] = (T)(img)(_p11##x,_p10##y,z,c), I[25] = (T)(img)(_p10##x,_p10##y,z,c), I[26] = (T)(img)(_p9##x,_p10##y,z,c), I[27] = (T)(img)(_p8##x,_p10##y,z,c), I[28] = (T)(img)(_p7##x,_p10##y,z,c), I[29] = (T)(img)(_p6##x,_p10##y,z,c), I[30] = (T)(img)(_p5##x,_p10##y,z,c), I[31] = (T)(img)(_p4##x,_p10##y,z,c), I[32] = (T)(img)(_p3##x,_p10##y,z,c), I[33] = (T)(img)(_p2##x,_p10##y,z,c), I[34] = (T)(img)(_p1##x,_p10##y,z,c), I[35] = (T)(img)(x,_p10##y,z,c), I[36] = (T)(img)(_n1##x,_p10##y,z,c), I[37] = (T)(img)(_n2##x,_p10##y,z,c), I[38] = (T)(img)(_n3##x,_p10##y,z,c), I[39] = (T)(img)(_n4##x,_p10##y,z,c), I[40] = (T)(img)(_n5##x,_p10##y,z,c), I[41] = (T)(img)(_n6##x,_p10##y,z,c), I[42] = (T)(img)(_n7##x,_p10##y,z,c), I[43] = (T)(img)(_n8##x,_p10##y,z,c), I[44] = (T)(img)(_n9##x,_p10##y,z,c), I[45] = (T)(img)(_n10##x,_p10##y,z,c), I[46] = (T)(img)(_n11##x,_p10##y,z,c), I[47] = (T)(img)(_n12##x,_p10##y,z,c), \ - I[48] = (T)(img)(_p11##x,_p9##y,z,c), I[49] = (T)(img)(_p10##x,_p9##y,z,c), I[50] = (T)(img)(_p9##x,_p9##y,z,c), I[51] = (T)(img)(_p8##x,_p9##y,z,c), I[52] = (T)(img)(_p7##x,_p9##y,z,c), I[53] = (T)(img)(_p6##x,_p9##y,z,c), I[54] = (T)(img)(_p5##x,_p9##y,z,c), I[55] = (T)(img)(_p4##x,_p9##y,z,c), I[56] = (T)(img)(_p3##x,_p9##y,z,c), I[57] = (T)(img)(_p2##x,_p9##y,z,c), I[58] = (T)(img)(_p1##x,_p9##y,z,c), I[59] = (T)(img)(x,_p9##y,z,c), I[60] = (T)(img)(_n1##x,_p9##y,z,c), I[61] = (T)(img)(_n2##x,_p9##y,z,c), I[62] = (T)(img)(_n3##x,_p9##y,z,c), I[63] = (T)(img)(_n4##x,_p9##y,z,c), I[64] = (T)(img)(_n5##x,_p9##y,z,c), I[65] = (T)(img)(_n6##x,_p9##y,z,c), I[66] = (T)(img)(_n7##x,_p9##y,z,c), I[67] = (T)(img)(_n8##x,_p9##y,z,c), I[68] = (T)(img)(_n9##x,_p9##y,z,c), I[69] = (T)(img)(_n10##x,_p9##y,z,c), I[70] = (T)(img)(_n11##x,_p9##y,z,c), I[71] = (T)(img)(_n12##x,_p9##y,z,c), \ - I[72] = (T)(img)(_p11##x,_p8##y,z,c), I[73] = (T)(img)(_p10##x,_p8##y,z,c), I[74] = (T)(img)(_p9##x,_p8##y,z,c), I[75] = (T)(img)(_p8##x,_p8##y,z,c), I[76] = (T)(img)(_p7##x,_p8##y,z,c), I[77] = (T)(img)(_p6##x,_p8##y,z,c), I[78] = (T)(img)(_p5##x,_p8##y,z,c), I[79] = (T)(img)(_p4##x,_p8##y,z,c), I[80] = (T)(img)(_p3##x,_p8##y,z,c), I[81] = (T)(img)(_p2##x,_p8##y,z,c), I[82] = (T)(img)(_p1##x,_p8##y,z,c), I[83] = (T)(img)(x,_p8##y,z,c), I[84] = (T)(img)(_n1##x,_p8##y,z,c), I[85] = (T)(img)(_n2##x,_p8##y,z,c), I[86] = (T)(img)(_n3##x,_p8##y,z,c), I[87] = (T)(img)(_n4##x,_p8##y,z,c), I[88] = (T)(img)(_n5##x,_p8##y,z,c), I[89] = (T)(img)(_n6##x,_p8##y,z,c), I[90] = (T)(img)(_n7##x,_p8##y,z,c), I[91] = (T)(img)(_n8##x,_p8##y,z,c), I[92] = (T)(img)(_n9##x,_p8##y,z,c), I[93] = (T)(img)(_n10##x,_p8##y,z,c), I[94] = (T)(img)(_n11##x,_p8##y,z,c), I[95] = (T)(img)(_n12##x,_p8##y,z,c), \ - I[96] = (T)(img)(_p11##x,_p7##y,z,c), I[97] = (T)(img)(_p10##x,_p7##y,z,c), I[98] = (T)(img)(_p9##x,_p7##y,z,c), I[99] = (T)(img)(_p8##x,_p7##y,z,c), I[100] = (T)(img)(_p7##x,_p7##y,z,c), I[101] = (T)(img)(_p6##x,_p7##y,z,c), I[102] = (T)(img)(_p5##x,_p7##y,z,c), I[103] = (T)(img)(_p4##x,_p7##y,z,c), I[104] = (T)(img)(_p3##x,_p7##y,z,c), I[105] = (T)(img)(_p2##x,_p7##y,z,c), I[106] = (T)(img)(_p1##x,_p7##y,z,c), I[107] = (T)(img)(x,_p7##y,z,c), I[108] = (T)(img)(_n1##x,_p7##y,z,c), I[109] = (T)(img)(_n2##x,_p7##y,z,c), I[110] = (T)(img)(_n3##x,_p7##y,z,c), I[111] = (T)(img)(_n4##x,_p7##y,z,c), I[112] = (T)(img)(_n5##x,_p7##y,z,c), I[113] = (T)(img)(_n6##x,_p7##y,z,c), I[114] = (T)(img)(_n7##x,_p7##y,z,c), I[115] = (T)(img)(_n8##x,_p7##y,z,c), I[116] = (T)(img)(_n9##x,_p7##y,z,c), I[117] = (T)(img)(_n10##x,_p7##y,z,c), I[118] = (T)(img)(_n11##x,_p7##y,z,c), I[119] = (T)(img)(_n12##x,_p7##y,z,c), \ - I[120] = (T)(img)(_p11##x,_p6##y,z,c), I[121] = (T)(img)(_p10##x,_p6##y,z,c), I[122] = (T)(img)(_p9##x,_p6##y,z,c), I[123] = (T)(img)(_p8##x,_p6##y,z,c), I[124] = (T)(img)(_p7##x,_p6##y,z,c), I[125] = (T)(img)(_p6##x,_p6##y,z,c), I[126] = (T)(img)(_p5##x,_p6##y,z,c), I[127] = (T)(img)(_p4##x,_p6##y,z,c), I[128] = (T)(img)(_p3##x,_p6##y,z,c), I[129] = (T)(img)(_p2##x,_p6##y,z,c), I[130] = (T)(img)(_p1##x,_p6##y,z,c), I[131] = (T)(img)(x,_p6##y,z,c), I[132] = (T)(img)(_n1##x,_p6##y,z,c), I[133] = (T)(img)(_n2##x,_p6##y,z,c), I[134] = (T)(img)(_n3##x,_p6##y,z,c), I[135] = (T)(img)(_n4##x,_p6##y,z,c), I[136] = (T)(img)(_n5##x,_p6##y,z,c), I[137] = (T)(img)(_n6##x,_p6##y,z,c), I[138] = (T)(img)(_n7##x,_p6##y,z,c), I[139] = (T)(img)(_n8##x,_p6##y,z,c), I[140] = (T)(img)(_n9##x,_p6##y,z,c), I[141] = (T)(img)(_n10##x,_p6##y,z,c), I[142] = (T)(img)(_n11##x,_p6##y,z,c), I[143] = (T)(img)(_n12##x,_p6##y,z,c), \ - I[144] = (T)(img)(_p11##x,_p5##y,z,c), I[145] = (T)(img)(_p10##x,_p5##y,z,c), I[146] = (T)(img)(_p9##x,_p5##y,z,c), I[147] = (T)(img)(_p8##x,_p5##y,z,c), I[148] = (T)(img)(_p7##x,_p5##y,z,c), I[149] = (T)(img)(_p6##x,_p5##y,z,c), I[150] = (T)(img)(_p5##x,_p5##y,z,c), I[151] = (T)(img)(_p4##x,_p5##y,z,c), I[152] = (T)(img)(_p3##x,_p5##y,z,c), I[153] = (T)(img)(_p2##x,_p5##y,z,c), I[154] = (T)(img)(_p1##x,_p5##y,z,c), I[155] = (T)(img)(x,_p5##y,z,c), I[156] = (T)(img)(_n1##x,_p5##y,z,c), I[157] = (T)(img)(_n2##x,_p5##y,z,c), I[158] = (T)(img)(_n3##x,_p5##y,z,c), I[159] = (T)(img)(_n4##x,_p5##y,z,c), I[160] = (T)(img)(_n5##x,_p5##y,z,c), I[161] = (T)(img)(_n6##x,_p5##y,z,c), I[162] = (T)(img)(_n7##x,_p5##y,z,c), I[163] = (T)(img)(_n8##x,_p5##y,z,c), I[164] = (T)(img)(_n9##x,_p5##y,z,c), I[165] = (T)(img)(_n10##x,_p5##y,z,c), I[166] = (T)(img)(_n11##x,_p5##y,z,c), I[167] = (T)(img)(_n12##x,_p5##y,z,c), \ - I[168] = (T)(img)(_p11##x,_p4##y,z,c), I[169] = (T)(img)(_p10##x,_p4##y,z,c), I[170] = (T)(img)(_p9##x,_p4##y,z,c), I[171] = (T)(img)(_p8##x,_p4##y,z,c), I[172] = (T)(img)(_p7##x,_p4##y,z,c), I[173] = (T)(img)(_p6##x,_p4##y,z,c), I[174] = (T)(img)(_p5##x,_p4##y,z,c), I[175] = (T)(img)(_p4##x,_p4##y,z,c), I[176] = (T)(img)(_p3##x,_p4##y,z,c), I[177] = (T)(img)(_p2##x,_p4##y,z,c), I[178] = (T)(img)(_p1##x,_p4##y,z,c), I[179] = (T)(img)(x,_p4##y,z,c), I[180] = (T)(img)(_n1##x,_p4##y,z,c), I[181] = (T)(img)(_n2##x,_p4##y,z,c), I[182] = (T)(img)(_n3##x,_p4##y,z,c), I[183] = (T)(img)(_n4##x,_p4##y,z,c), I[184] = (T)(img)(_n5##x,_p4##y,z,c), I[185] = (T)(img)(_n6##x,_p4##y,z,c), I[186] = (T)(img)(_n7##x,_p4##y,z,c), I[187] = (T)(img)(_n8##x,_p4##y,z,c), I[188] = (T)(img)(_n9##x,_p4##y,z,c), I[189] = (T)(img)(_n10##x,_p4##y,z,c), I[190] = (T)(img)(_n11##x,_p4##y,z,c), I[191] = (T)(img)(_n12##x,_p4##y,z,c), \ - I[192] = (T)(img)(_p11##x,_p3##y,z,c), I[193] = (T)(img)(_p10##x,_p3##y,z,c), I[194] = (T)(img)(_p9##x,_p3##y,z,c), I[195] = (T)(img)(_p8##x,_p3##y,z,c), I[196] = (T)(img)(_p7##x,_p3##y,z,c), I[197] = (T)(img)(_p6##x,_p3##y,z,c), I[198] = (T)(img)(_p5##x,_p3##y,z,c), I[199] = (T)(img)(_p4##x,_p3##y,z,c), I[200] = (T)(img)(_p3##x,_p3##y,z,c), I[201] = (T)(img)(_p2##x,_p3##y,z,c), I[202] = (T)(img)(_p1##x,_p3##y,z,c), I[203] = (T)(img)(x,_p3##y,z,c), I[204] = (T)(img)(_n1##x,_p3##y,z,c), I[205] = (T)(img)(_n2##x,_p3##y,z,c), I[206] = (T)(img)(_n3##x,_p3##y,z,c), I[207] = (T)(img)(_n4##x,_p3##y,z,c), I[208] = (T)(img)(_n5##x,_p3##y,z,c), I[209] = (T)(img)(_n6##x,_p3##y,z,c), I[210] = (T)(img)(_n7##x,_p3##y,z,c), I[211] = (T)(img)(_n8##x,_p3##y,z,c), I[212] = (T)(img)(_n9##x,_p3##y,z,c), I[213] = (T)(img)(_n10##x,_p3##y,z,c), I[214] = (T)(img)(_n11##x,_p3##y,z,c), I[215] = (T)(img)(_n12##x,_p3##y,z,c), \ - I[216] = (T)(img)(_p11##x,_p2##y,z,c), I[217] = (T)(img)(_p10##x,_p2##y,z,c), I[218] = (T)(img)(_p9##x,_p2##y,z,c), I[219] = (T)(img)(_p8##x,_p2##y,z,c), I[220] = (T)(img)(_p7##x,_p2##y,z,c), I[221] = (T)(img)(_p6##x,_p2##y,z,c), I[222] = (T)(img)(_p5##x,_p2##y,z,c), I[223] = (T)(img)(_p4##x,_p2##y,z,c), I[224] = (T)(img)(_p3##x,_p2##y,z,c), I[225] = (T)(img)(_p2##x,_p2##y,z,c), I[226] = (T)(img)(_p1##x,_p2##y,z,c), I[227] = (T)(img)(x,_p2##y,z,c), I[228] = (T)(img)(_n1##x,_p2##y,z,c), I[229] = (T)(img)(_n2##x,_p2##y,z,c), I[230] = (T)(img)(_n3##x,_p2##y,z,c), I[231] = (T)(img)(_n4##x,_p2##y,z,c), I[232] = (T)(img)(_n5##x,_p2##y,z,c), I[233] = (T)(img)(_n6##x,_p2##y,z,c), I[234] = (T)(img)(_n7##x,_p2##y,z,c), I[235] = (T)(img)(_n8##x,_p2##y,z,c), I[236] = (T)(img)(_n9##x,_p2##y,z,c), I[237] = (T)(img)(_n10##x,_p2##y,z,c), I[238] = (T)(img)(_n11##x,_p2##y,z,c), I[239] = (T)(img)(_n12##x,_p2##y,z,c), \ - I[240] = (T)(img)(_p11##x,_p1##y,z,c), I[241] = (T)(img)(_p10##x,_p1##y,z,c), I[242] = (T)(img)(_p9##x,_p1##y,z,c), I[243] = (T)(img)(_p8##x,_p1##y,z,c), I[244] = (T)(img)(_p7##x,_p1##y,z,c), I[245] = (T)(img)(_p6##x,_p1##y,z,c), I[246] = (T)(img)(_p5##x,_p1##y,z,c), I[247] = (T)(img)(_p4##x,_p1##y,z,c), I[248] = (T)(img)(_p3##x,_p1##y,z,c), I[249] = (T)(img)(_p2##x,_p1##y,z,c), I[250] = (T)(img)(_p1##x,_p1##y,z,c), I[251] = (T)(img)(x,_p1##y,z,c), I[252] = (T)(img)(_n1##x,_p1##y,z,c), I[253] = (T)(img)(_n2##x,_p1##y,z,c), I[254] = (T)(img)(_n3##x,_p1##y,z,c), I[255] = (T)(img)(_n4##x,_p1##y,z,c), I[256] = (T)(img)(_n5##x,_p1##y,z,c), I[257] = (T)(img)(_n6##x,_p1##y,z,c), I[258] = (T)(img)(_n7##x,_p1##y,z,c), I[259] = (T)(img)(_n8##x,_p1##y,z,c), I[260] = (T)(img)(_n9##x,_p1##y,z,c), I[261] = (T)(img)(_n10##x,_p1##y,z,c), I[262] = (T)(img)(_n11##x,_p1##y,z,c), I[263] = (T)(img)(_n12##x,_p1##y,z,c), \ - I[264] = (T)(img)(_p11##x,y,z,c), I[265] = (T)(img)(_p10##x,y,z,c), I[266] = (T)(img)(_p9##x,y,z,c), I[267] = (T)(img)(_p8##x,y,z,c), I[268] = (T)(img)(_p7##x,y,z,c), I[269] = (T)(img)(_p6##x,y,z,c), I[270] = (T)(img)(_p5##x,y,z,c), I[271] = (T)(img)(_p4##x,y,z,c), I[272] = (T)(img)(_p3##x,y,z,c), I[273] = (T)(img)(_p2##x,y,z,c), I[274] = (T)(img)(_p1##x,y,z,c), I[275] = (T)(img)(x,y,z,c), I[276] = (T)(img)(_n1##x,y,z,c), I[277] = (T)(img)(_n2##x,y,z,c), I[278] = (T)(img)(_n3##x,y,z,c), I[279] = (T)(img)(_n4##x,y,z,c), I[280] = (T)(img)(_n5##x,y,z,c), I[281] = (T)(img)(_n6##x,y,z,c), I[282] = (T)(img)(_n7##x,y,z,c), I[283] = (T)(img)(_n8##x,y,z,c), I[284] = (T)(img)(_n9##x,y,z,c), I[285] = (T)(img)(_n10##x,y,z,c), I[286] = (T)(img)(_n11##x,y,z,c), I[287] = (T)(img)(_n12##x,y,z,c), \ - I[288] = (T)(img)(_p11##x,_n1##y,z,c), I[289] = (T)(img)(_p10##x,_n1##y,z,c), I[290] = (T)(img)(_p9##x,_n1##y,z,c), I[291] = (T)(img)(_p8##x,_n1##y,z,c), I[292] = (T)(img)(_p7##x,_n1##y,z,c), I[293] = (T)(img)(_p6##x,_n1##y,z,c), I[294] = (T)(img)(_p5##x,_n1##y,z,c), I[295] = (T)(img)(_p4##x,_n1##y,z,c), I[296] = (T)(img)(_p3##x,_n1##y,z,c), I[297] = (T)(img)(_p2##x,_n1##y,z,c), I[298] = (T)(img)(_p1##x,_n1##y,z,c), I[299] = (T)(img)(x,_n1##y,z,c), I[300] = (T)(img)(_n1##x,_n1##y,z,c), I[301] = (T)(img)(_n2##x,_n1##y,z,c), I[302] = (T)(img)(_n3##x,_n1##y,z,c), I[303] = (T)(img)(_n4##x,_n1##y,z,c), I[304] = (T)(img)(_n5##x,_n1##y,z,c), I[305] = (T)(img)(_n6##x,_n1##y,z,c), I[306] = (T)(img)(_n7##x,_n1##y,z,c), I[307] = (T)(img)(_n8##x,_n1##y,z,c), I[308] = (T)(img)(_n9##x,_n1##y,z,c), I[309] = (T)(img)(_n10##x,_n1##y,z,c), I[310] = (T)(img)(_n11##x,_n1##y,z,c), I[311] = (T)(img)(_n12##x,_n1##y,z,c), \ - I[312] = (T)(img)(_p11##x,_n2##y,z,c), I[313] = (T)(img)(_p10##x,_n2##y,z,c), I[314] = (T)(img)(_p9##x,_n2##y,z,c), I[315] = (T)(img)(_p8##x,_n2##y,z,c), I[316] = (T)(img)(_p7##x,_n2##y,z,c), I[317] = (T)(img)(_p6##x,_n2##y,z,c), I[318] = (T)(img)(_p5##x,_n2##y,z,c), I[319] = (T)(img)(_p4##x,_n2##y,z,c), I[320] = (T)(img)(_p3##x,_n2##y,z,c), I[321] = (T)(img)(_p2##x,_n2##y,z,c), I[322] = (T)(img)(_p1##x,_n2##y,z,c), I[323] = (T)(img)(x,_n2##y,z,c), I[324] = (T)(img)(_n1##x,_n2##y,z,c), I[325] = (T)(img)(_n2##x,_n2##y,z,c), I[326] = (T)(img)(_n3##x,_n2##y,z,c), I[327] = (T)(img)(_n4##x,_n2##y,z,c), I[328] = (T)(img)(_n5##x,_n2##y,z,c), I[329] = (T)(img)(_n6##x,_n2##y,z,c), I[330] = (T)(img)(_n7##x,_n2##y,z,c), I[331] = (T)(img)(_n8##x,_n2##y,z,c), I[332] = (T)(img)(_n9##x,_n2##y,z,c), I[333] = (T)(img)(_n10##x,_n2##y,z,c), I[334] = (T)(img)(_n11##x,_n2##y,z,c), I[335] = (T)(img)(_n12##x,_n2##y,z,c), \ - I[336] = (T)(img)(_p11##x,_n3##y,z,c), I[337] = (T)(img)(_p10##x,_n3##y,z,c), I[338] = (T)(img)(_p9##x,_n3##y,z,c), I[339] = (T)(img)(_p8##x,_n3##y,z,c), I[340] = (T)(img)(_p7##x,_n3##y,z,c), I[341] = (T)(img)(_p6##x,_n3##y,z,c), I[342] = (T)(img)(_p5##x,_n3##y,z,c), I[343] = (T)(img)(_p4##x,_n3##y,z,c), I[344] = (T)(img)(_p3##x,_n3##y,z,c), I[345] = (T)(img)(_p2##x,_n3##y,z,c), I[346] = (T)(img)(_p1##x,_n3##y,z,c), I[347] = (T)(img)(x,_n3##y,z,c), I[348] = (T)(img)(_n1##x,_n3##y,z,c), I[349] = (T)(img)(_n2##x,_n3##y,z,c), I[350] = (T)(img)(_n3##x,_n3##y,z,c), I[351] = (T)(img)(_n4##x,_n3##y,z,c), I[352] = (T)(img)(_n5##x,_n3##y,z,c), I[353] = (T)(img)(_n6##x,_n3##y,z,c), I[354] = (T)(img)(_n7##x,_n3##y,z,c), I[355] = (T)(img)(_n8##x,_n3##y,z,c), I[356] = (T)(img)(_n9##x,_n3##y,z,c), I[357] = (T)(img)(_n10##x,_n3##y,z,c), I[358] = (T)(img)(_n11##x,_n3##y,z,c), I[359] = (T)(img)(_n12##x,_n3##y,z,c), \ - I[360] = (T)(img)(_p11##x,_n4##y,z,c), I[361] = (T)(img)(_p10##x,_n4##y,z,c), I[362] = (T)(img)(_p9##x,_n4##y,z,c), I[363] = (T)(img)(_p8##x,_n4##y,z,c), I[364] = (T)(img)(_p7##x,_n4##y,z,c), I[365] = (T)(img)(_p6##x,_n4##y,z,c), I[366] = (T)(img)(_p5##x,_n4##y,z,c), I[367] = (T)(img)(_p4##x,_n4##y,z,c), I[368] = (T)(img)(_p3##x,_n4##y,z,c), I[369] = (T)(img)(_p2##x,_n4##y,z,c), I[370] = (T)(img)(_p1##x,_n4##y,z,c), I[371] = (T)(img)(x,_n4##y,z,c), I[372] = (T)(img)(_n1##x,_n4##y,z,c), I[373] = (T)(img)(_n2##x,_n4##y,z,c), I[374] = (T)(img)(_n3##x,_n4##y,z,c), I[375] = (T)(img)(_n4##x,_n4##y,z,c), I[376] = (T)(img)(_n5##x,_n4##y,z,c), I[377] = (T)(img)(_n6##x,_n4##y,z,c), I[378] = (T)(img)(_n7##x,_n4##y,z,c), I[379] = (T)(img)(_n8##x,_n4##y,z,c), I[380] = (T)(img)(_n9##x,_n4##y,z,c), I[381] = (T)(img)(_n10##x,_n4##y,z,c), I[382] = (T)(img)(_n11##x,_n4##y,z,c), I[383] = (T)(img)(_n12##x,_n4##y,z,c), \ - I[384] = (T)(img)(_p11##x,_n5##y,z,c), I[385] = (T)(img)(_p10##x,_n5##y,z,c), I[386] = (T)(img)(_p9##x,_n5##y,z,c), I[387] = (T)(img)(_p8##x,_n5##y,z,c), I[388] = (T)(img)(_p7##x,_n5##y,z,c), I[389] = (T)(img)(_p6##x,_n5##y,z,c), I[390] = (T)(img)(_p5##x,_n5##y,z,c), I[391] = (T)(img)(_p4##x,_n5##y,z,c), I[392] = (T)(img)(_p3##x,_n5##y,z,c), I[393] = (T)(img)(_p2##x,_n5##y,z,c), I[394] = (T)(img)(_p1##x,_n5##y,z,c), I[395] = (T)(img)(x,_n5##y,z,c), I[396] = (T)(img)(_n1##x,_n5##y,z,c), I[397] = (T)(img)(_n2##x,_n5##y,z,c), I[398] = (T)(img)(_n3##x,_n5##y,z,c), I[399] = (T)(img)(_n4##x,_n5##y,z,c), I[400] = (T)(img)(_n5##x,_n5##y,z,c), I[401] = (T)(img)(_n6##x,_n5##y,z,c), I[402] = (T)(img)(_n7##x,_n5##y,z,c), I[403] = (T)(img)(_n8##x,_n5##y,z,c), I[404] = (T)(img)(_n9##x,_n5##y,z,c), I[405] = (T)(img)(_n10##x,_n5##y,z,c), I[406] = (T)(img)(_n11##x,_n5##y,z,c), I[407] = (T)(img)(_n12##x,_n5##y,z,c), \ - I[408] = (T)(img)(_p11##x,_n6##y,z,c), I[409] = (T)(img)(_p10##x,_n6##y,z,c), I[410] = (T)(img)(_p9##x,_n6##y,z,c), I[411] = (T)(img)(_p8##x,_n6##y,z,c), I[412] = (T)(img)(_p7##x,_n6##y,z,c), I[413] = (T)(img)(_p6##x,_n6##y,z,c), I[414] = (T)(img)(_p5##x,_n6##y,z,c), I[415] = (T)(img)(_p4##x,_n6##y,z,c), I[416] = (T)(img)(_p3##x,_n6##y,z,c), I[417] = (T)(img)(_p2##x,_n6##y,z,c), I[418] = (T)(img)(_p1##x,_n6##y,z,c), I[419] = (T)(img)(x,_n6##y,z,c), I[420] = (T)(img)(_n1##x,_n6##y,z,c), I[421] = (T)(img)(_n2##x,_n6##y,z,c), I[422] = (T)(img)(_n3##x,_n6##y,z,c), I[423] = (T)(img)(_n4##x,_n6##y,z,c), I[424] = (T)(img)(_n5##x,_n6##y,z,c), I[425] = (T)(img)(_n6##x,_n6##y,z,c), I[426] = (T)(img)(_n7##x,_n6##y,z,c), I[427] = (T)(img)(_n8##x,_n6##y,z,c), I[428] = (T)(img)(_n9##x,_n6##y,z,c), I[429] = (T)(img)(_n10##x,_n6##y,z,c), I[430] = (T)(img)(_n11##x,_n6##y,z,c), I[431] = (T)(img)(_n12##x,_n6##y,z,c), \ - I[432] = (T)(img)(_p11##x,_n7##y,z,c), I[433] = (T)(img)(_p10##x,_n7##y,z,c), I[434] = (T)(img)(_p9##x,_n7##y,z,c), I[435] = (T)(img)(_p8##x,_n7##y,z,c), I[436] = (T)(img)(_p7##x,_n7##y,z,c), I[437] = (T)(img)(_p6##x,_n7##y,z,c), I[438] = (T)(img)(_p5##x,_n7##y,z,c), I[439] = (T)(img)(_p4##x,_n7##y,z,c), I[440] = (T)(img)(_p3##x,_n7##y,z,c), I[441] = (T)(img)(_p2##x,_n7##y,z,c), I[442] = (T)(img)(_p1##x,_n7##y,z,c), I[443] = (T)(img)(x,_n7##y,z,c), I[444] = (T)(img)(_n1##x,_n7##y,z,c), I[445] = (T)(img)(_n2##x,_n7##y,z,c), I[446] = (T)(img)(_n3##x,_n7##y,z,c), I[447] = (T)(img)(_n4##x,_n7##y,z,c), I[448] = (T)(img)(_n5##x,_n7##y,z,c), I[449] = (T)(img)(_n6##x,_n7##y,z,c), I[450] = (T)(img)(_n7##x,_n7##y,z,c), I[451] = (T)(img)(_n8##x,_n7##y,z,c), I[452] = (T)(img)(_n9##x,_n7##y,z,c), I[453] = (T)(img)(_n10##x,_n7##y,z,c), I[454] = (T)(img)(_n11##x,_n7##y,z,c), I[455] = (T)(img)(_n12##x,_n7##y,z,c), \ - I[456] = (T)(img)(_p11##x,_n8##y,z,c), I[457] = (T)(img)(_p10##x,_n8##y,z,c), I[458] = (T)(img)(_p9##x,_n8##y,z,c), I[459] = (T)(img)(_p8##x,_n8##y,z,c), I[460] = (T)(img)(_p7##x,_n8##y,z,c), I[461] = (T)(img)(_p6##x,_n8##y,z,c), I[462] = (T)(img)(_p5##x,_n8##y,z,c), I[463] = (T)(img)(_p4##x,_n8##y,z,c), I[464] = (T)(img)(_p3##x,_n8##y,z,c), I[465] = (T)(img)(_p2##x,_n8##y,z,c), I[466] = (T)(img)(_p1##x,_n8##y,z,c), I[467] = (T)(img)(x,_n8##y,z,c), I[468] = (T)(img)(_n1##x,_n8##y,z,c), I[469] = (T)(img)(_n2##x,_n8##y,z,c), I[470] = (T)(img)(_n3##x,_n8##y,z,c), I[471] = (T)(img)(_n4##x,_n8##y,z,c), I[472] = (T)(img)(_n5##x,_n8##y,z,c), I[473] = (T)(img)(_n6##x,_n8##y,z,c), I[474] = (T)(img)(_n7##x,_n8##y,z,c), I[475] = (T)(img)(_n8##x,_n8##y,z,c), I[476] = (T)(img)(_n9##x,_n8##y,z,c), I[477] = (T)(img)(_n10##x,_n8##y,z,c), I[478] = (T)(img)(_n11##x,_n8##y,z,c), I[479] = (T)(img)(_n12##x,_n8##y,z,c), \ - I[480] = (T)(img)(_p11##x,_n9##y,z,c), I[481] = (T)(img)(_p10##x,_n9##y,z,c), I[482] = (T)(img)(_p9##x,_n9##y,z,c), I[483] = (T)(img)(_p8##x,_n9##y,z,c), I[484] = (T)(img)(_p7##x,_n9##y,z,c), I[485] = (T)(img)(_p6##x,_n9##y,z,c), I[486] = (T)(img)(_p5##x,_n9##y,z,c), I[487] = (T)(img)(_p4##x,_n9##y,z,c), I[488] = (T)(img)(_p3##x,_n9##y,z,c), I[489] = (T)(img)(_p2##x,_n9##y,z,c), I[490] = (T)(img)(_p1##x,_n9##y,z,c), I[491] = (T)(img)(x,_n9##y,z,c), I[492] = (T)(img)(_n1##x,_n9##y,z,c), I[493] = (T)(img)(_n2##x,_n9##y,z,c), I[494] = (T)(img)(_n3##x,_n9##y,z,c), I[495] = (T)(img)(_n4##x,_n9##y,z,c), I[496] = (T)(img)(_n5##x,_n9##y,z,c), I[497] = (T)(img)(_n6##x,_n9##y,z,c), I[498] = (T)(img)(_n7##x,_n9##y,z,c), I[499] = (T)(img)(_n8##x,_n9##y,z,c), I[500] = (T)(img)(_n9##x,_n9##y,z,c), I[501] = (T)(img)(_n10##x,_n9##y,z,c), I[502] = (T)(img)(_n11##x,_n9##y,z,c), I[503] = (T)(img)(_n12##x,_n9##y,z,c), \ - I[504] = (T)(img)(_p11##x,_n10##y,z,c), I[505] = (T)(img)(_p10##x,_n10##y,z,c), I[506] = (T)(img)(_p9##x,_n10##y,z,c), I[507] = (T)(img)(_p8##x,_n10##y,z,c), I[508] = (T)(img)(_p7##x,_n10##y,z,c), I[509] = (T)(img)(_p6##x,_n10##y,z,c), I[510] = (T)(img)(_p5##x,_n10##y,z,c), I[511] = (T)(img)(_p4##x,_n10##y,z,c), I[512] = (T)(img)(_p3##x,_n10##y,z,c), I[513] = (T)(img)(_p2##x,_n10##y,z,c), I[514] = (T)(img)(_p1##x,_n10##y,z,c), I[515] = (T)(img)(x,_n10##y,z,c), I[516] = (T)(img)(_n1##x,_n10##y,z,c), I[517] = (T)(img)(_n2##x,_n10##y,z,c), I[518] = (T)(img)(_n3##x,_n10##y,z,c), I[519] = (T)(img)(_n4##x,_n10##y,z,c), I[520] = (T)(img)(_n5##x,_n10##y,z,c), I[521] = (T)(img)(_n6##x,_n10##y,z,c), I[522] = (T)(img)(_n7##x,_n10##y,z,c), I[523] = (T)(img)(_n8##x,_n10##y,z,c), I[524] = (T)(img)(_n9##x,_n10##y,z,c), I[525] = (T)(img)(_n10##x,_n10##y,z,c), I[526] = (T)(img)(_n11##x,_n10##y,z,c), I[527] = (T)(img)(_n12##x,_n10##y,z,c), \ - I[528] = (T)(img)(_p11##x,_n11##y,z,c), I[529] = (T)(img)(_p10##x,_n11##y,z,c), I[530] = (T)(img)(_p9##x,_n11##y,z,c), I[531] = (T)(img)(_p8##x,_n11##y,z,c), I[532] = (T)(img)(_p7##x,_n11##y,z,c), I[533] = (T)(img)(_p6##x,_n11##y,z,c), I[534] = (T)(img)(_p5##x,_n11##y,z,c), I[535] = (T)(img)(_p4##x,_n11##y,z,c), I[536] = (T)(img)(_p3##x,_n11##y,z,c), I[537] = (T)(img)(_p2##x,_n11##y,z,c), I[538] = (T)(img)(_p1##x,_n11##y,z,c), I[539] = (T)(img)(x,_n11##y,z,c), I[540] = (T)(img)(_n1##x,_n11##y,z,c), I[541] = (T)(img)(_n2##x,_n11##y,z,c), I[542] = (T)(img)(_n3##x,_n11##y,z,c), I[543] = (T)(img)(_n4##x,_n11##y,z,c), I[544] = (T)(img)(_n5##x,_n11##y,z,c), I[545] = (T)(img)(_n6##x,_n11##y,z,c), I[546] = (T)(img)(_n7##x,_n11##y,z,c), I[547] = (T)(img)(_n8##x,_n11##y,z,c), I[548] = (T)(img)(_n9##x,_n11##y,z,c), I[549] = (T)(img)(_n10##x,_n11##y,z,c), I[550] = (T)(img)(_n11##x,_n11##y,z,c), I[551] = (T)(img)(_n12##x,_n11##y,z,c), \ - I[552] = (T)(img)(_p11##x,_n12##y,z,c), I[553] = (T)(img)(_p10##x,_n12##y,z,c), I[554] = (T)(img)(_p9##x,_n12##y,z,c), I[555] = (T)(img)(_p8##x,_n12##y,z,c), I[556] = (T)(img)(_p7##x,_n12##y,z,c), I[557] = (T)(img)(_p6##x,_n12##y,z,c), I[558] = (T)(img)(_p5##x,_n12##y,z,c), I[559] = (T)(img)(_p4##x,_n12##y,z,c), I[560] = (T)(img)(_p3##x,_n12##y,z,c), I[561] = (T)(img)(_p2##x,_n12##y,z,c), I[562] = (T)(img)(_p1##x,_n12##y,z,c), I[563] = (T)(img)(x,_n12##y,z,c), I[564] = (T)(img)(_n1##x,_n12##y,z,c), I[565] = (T)(img)(_n2##x,_n12##y,z,c), I[566] = (T)(img)(_n3##x,_n12##y,z,c), I[567] = (T)(img)(_n4##x,_n12##y,z,c), I[568] = (T)(img)(_n5##x,_n12##y,z,c), I[569] = (T)(img)(_n6##x,_n12##y,z,c), I[570] = (T)(img)(_n7##x,_n12##y,z,c), I[571] = (T)(img)(_n8##x,_n12##y,z,c), I[572] = (T)(img)(_n9##x,_n12##y,z,c), I[573] = (T)(img)(_n10##x,_n12##y,z,c), I[574] = (T)(img)(_n11##x,_n12##y,z,c), I[575] = (T)(img)(_n12##x,_n12##y,z,c); - -// Define 25x25 loop macros -//------------------------- -#define cimg_for25(bound,i) for (int i = 0, \ - _p12##i = 0, _p11##i = 0, _p10##i = 0, _p9##i = 0, _p8##i = 0, _p7##i = 0, _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6, \ - _n7##i = 7>=(int)(bound)?(int)(bound) - 1:7, \ - _n8##i = 8>=(int)(bound)?(int)(bound) - 1:8, \ - _n9##i = 9>=(int)(bound)?(int)(bound) - 1:9, \ - _n10##i = 10>=(int)(bound)?(int)(bound) - 1:10, \ - _n11##i = 11>=(int)(bound)?(int)(bound) - 1:11, \ - _n12##i = 12>=(int)(bound)?(int)(bound) - 1:12; \ - _n12##i<(int)(bound) || _n11##i==--_n12##i || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n12##i = _n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p12##i = _p11##i, _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i, ++_n12##i) - -#define cimg_for25X(img,x) cimg_for25((img)._width,x) -#define cimg_for25Y(img,y) cimg_for25((img)._height,y) -#define cimg_for25Z(img,z) cimg_for25((img)._depth,z) -#define cimg_for25C(img,c) cimg_for25((img)._spectrum,c) -#define cimg_for25XY(img,x,y) cimg_for25Y(img,y) cimg_for25X(img,x) -#define cimg_for25XZ(img,x,z) cimg_for25Z(img,z) cimg_for25X(img,x) -#define cimg_for25XC(img,x,c) cimg_for25C(img,c) cimg_for25X(img,x) -#define cimg_for25YZ(img,y,z) cimg_for25Z(img,z) cimg_for25Y(img,y) -#define cimg_for25YC(img,y,c) cimg_for25C(img,c) cimg_for25Y(img,y) -#define cimg_for25ZC(img,z,c) cimg_for25C(img,c) cimg_for25Z(img,z) -#define cimg_for25XYZ(img,x,y,z) cimg_for25Z(img,z) cimg_for25XY(img,x,y) -#define cimg_for25XZC(img,x,z,c) cimg_for25C(img,c) cimg_for25XZ(img,x,z) -#define cimg_for25YZC(img,y,z,c) cimg_for25C(img,c) cimg_for25YZ(img,y,z) -#define cimg_for25XYZC(img,x,y,z,c) cimg_for25C(img,c) cimg_for25XYZ(img,x,y,z) - -#define cimg_for_in25(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p12##i = i - 12<0?0:i - 12, \ - _p11##i = i - 11<0?0:i - 11, \ - _p10##i = i - 10<0?0:i - 10, \ - _p9##i = i - 9<0?0:i - 9, \ - _p8##i = i - 8<0?0:i - 8, \ - _p7##i = i - 7<0?0:i - 7, \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6, \ - _n7##i = i + 7>=(int)(bound)?(int)(bound) - 1:i + 7, \ - _n8##i = i + 8>=(int)(bound)?(int)(bound) - 1:i + 8, \ - _n9##i = i + 9>=(int)(bound)?(int)(bound) - 1:i + 9, \ - _n10##i = i + 10>=(int)(bound)?(int)(bound) - 1:i + 10, \ - _n11##i = i + 11>=(int)(bound)?(int)(bound) - 1:i + 11, \ - _n12##i = i + 12>=(int)(bound)?(int)(bound) - 1:i + 12; \ - i<=(int)(i1) && (_n12##i<(int)(bound) || _n11##i==--_n12##i || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n12##i = _n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p12##i = _p11##i, _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i, ++_n12##i) - -#define cimg_for_in25X(img,x0,x1,x) cimg_for_in25((img)._width,x0,x1,x) -#define cimg_for_in25Y(img,y0,y1,y) cimg_for_in25((img)._height,y0,y1,y) -#define cimg_for_in25Z(img,z0,z1,z) cimg_for_in25((img)._depth,z0,z1,z) -#define cimg_for_in25C(img,c0,c1,c) cimg_for_in25((img)._spectrum,c0,c1,c) -#define cimg_for_in25XY(img,x0,y0,x1,y1,x,y) cimg_for_in25Y(img,y0,y1,y) cimg_for_in25X(img,x0,x1,x) -#define cimg_for_in25XZ(img,x0,z0,x1,z1,x,z) cimg_for_in25Z(img,z0,z1,z) cimg_for_in25X(img,x0,x1,x) -#define cimg_for_in25XC(img,x0,c0,x1,c1,x,c) cimg_for_in25C(img,c0,c1,c) cimg_for_in25X(img,x0,x1,x) -#define cimg_for_in25YZ(img,y0,z0,y1,z1,y,z) cimg_for_in25Z(img,z0,z1,z) cimg_for_in25Y(img,y0,y1,y) -#define cimg_for_in25YC(img,y0,c0,y1,c1,y,c) cimg_for_in25C(img,c0,c1,c) cimg_for_in25Y(img,y0,y1,y) -#define cimg_for_in25ZC(img,z0,c0,z1,c1,z,c) cimg_for_in25C(img,c0,c1,c) cimg_for_in25Z(img,z0,z1,z) -#define cimg_for_in25XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in25Z(img,z0,z1,z) cimg_for_in25XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in25XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in25C(img,c0,c1,c) cimg_for_in25XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in25YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in25C(img,c0,c1,c) cimg_for_in25YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in25XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in25C(img,c0,c1,c) cimg_for_in25XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for25x25(img,x,y,z,c,I,T) \ - cimg_for25((img)._height,y) for (int x = 0, \ - _p12##x = 0, _p11##x = 0, _p10##x = 0, _p9##x = 0, _p8##x = 0, _p7##x = 0, _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = 6>=((img)._width)?(img).width() - 1:6, \ - _n7##x = 7>=((img)._width)?(img).width() - 1:7, \ - _n8##x = 8>=((img)._width)?(img).width() - 1:8, \ - _n9##x = 9>=((img)._width)?(img).width() - 1:9, \ - _n10##x = 10>=((img)._width)?(img).width() - 1:10, \ - _n11##x = 11>=((img)._width)?(img).width() - 1:11, \ - _n12##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = I[7] = I[8] = I[9] = I[10] = I[11] = I[12] = (T)(img)(0,_p12##y,z,c)), \ - (I[25] = I[26] = I[27] = I[28] = I[29] = I[30] = I[31] = I[32] = I[33] = I[34] = I[35] = I[36] = I[37] = (T)(img)(0,_p11##y,z,c)), \ - (I[50] = I[51] = I[52] = I[53] = I[54] = I[55] = I[56] = I[57] = I[58] = I[59] = I[60] = I[61] = I[62] = (T)(img)(0,_p10##y,z,c)), \ - (I[75] = I[76] = I[77] = I[78] = I[79] = I[80] = I[81] = I[82] = I[83] = I[84] = I[85] = I[86] = I[87] = (T)(img)(0,_p9##y,z,c)), \ - (I[100] = I[101] = I[102] = I[103] = I[104] = I[105] = I[106] = I[107] = I[108] = I[109] = I[110] = I[111] = I[112] = (T)(img)(0,_p8##y,z,c)), \ - (I[125] = I[126] = I[127] = I[128] = I[129] = I[130] = I[131] = I[132] = I[133] = I[134] = I[135] = I[136] = I[137] = (T)(img)(0,_p7##y,z,c)), \ - (I[150] = I[151] = I[152] = I[153] = I[154] = I[155] = I[156] = I[157] = I[158] = I[159] = I[160] = I[161] = I[162] = (T)(img)(0,_p6##y,z,c)), \ - (I[175] = I[176] = I[177] = I[178] = I[179] = I[180] = I[181] = I[182] = I[183] = I[184] = I[185] = I[186] = I[187] = (T)(img)(0,_p5##y,z,c)), \ - (I[200] = I[201] = I[202] = I[203] = I[204] = I[205] = I[206] = I[207] = I[208] = I[209] = I[210] = I[211] = I[212] = (T)(img)(0,_p4##y,z,c)), \ - (I[225] = I[226] = I[227] = I[228] = I[229] = I[230] = I[231] = I[232] = I[233] = I[234] = I[235] = I[236] = I[237] = (T)(img)(0,_p3##y,z,c)), \ - (I[250] = I[251] = I[252] = I[253] = I[254] = I[255] = I[256] = I[257] = I[258] = I[259] = I[260] = I[261] = I[262] = (T)(img)(0,_p2##y,z,c)), \ - (I[275] = I[276] = I[277] = I[278] = I[279] = I[280] = I[281] = I[282] = I[283] = I[284] = I[285] = I[286] = I[287] = (T)(img)(0,_p1##y,z,c)), \ - (I[300] = I[301] = I[302] = I[303] = I[304] = I[305] = I[306] = I[307] = I[308] = I[309] = I[310] = I[311] = I[312] = (T)(img)(0,y,z,c)), \ - (I[325] = I[326] = I[327] = I[328] = I[329] = I[330] = I[331] = I[332] = I[333] = I[334] = I[335] = I[336] = I[337] = (T)(img)(0,_n1##y,z,c)), \ - (I[350] = I[351] = I[352] = I[353] = I[354] = I[355] = I[356] = I[357] = I[358] = I[359] = I[360] = I[361] = I[362] = (T)(img)(0,_n2##y,z,c)), \ - (I[375] = I[376] = I[377] = I[378] = I[379] = I[380] = I[381] = I[382] = I[383] = I[384] = I[385] = I[386] = I[387] = (T)(img)(0,_n3##y,z,c)), \ - (I[400] = I[401] = I[402] = I[403] = I[404] = I[405] = I[406] = I[407] = I[408] = I[409] = I[410] = I[411] = I[412] = (T)(img)(0,_n4##y,z,c)), \ - (I[425] = I[426] = I[427] = I[428] = I[429] = I[430] = I[431] = I[432] = I[433] = I[434] = I[435] = I[436] = I[437] = (T)(img)(0,_n5##y,z,c)), \ - (I[450] = I[451] = I[452] = I[453] = I[454] = I[455] = I[456] = I[457] = I[458] = I[459] = I[460] = I[461] = I[462] = (T)(img)(0,_n6##y,z,c)), \ - (I[475] = I[476] = I[477] = I[478] = I[479] = I[480] = I[481] = I[482] = I[483] = I[484] = I[485] = I[486] = I[487] = (T)(img)(0,_n7##y,z,c)), \ - (I[500] = I[501] = I[502] = I[503] = I[504] = I[505] = I[506] = I[507] = I[508] = I[509] = I[510] = I[511] = I[512] = (T)(img)(0,_n8##y,z,c)), \ - (I[525] = I[526] = I[527] = I[528] = I[529] = I[530] = I[531] = I[532] = I[533] = I[534] = I[535] = I[536] = I[537] = (T)(img)(0,_n9##y,z,c)), \ - (I[550] = I[551] = I[552] = I[553] = I[554] = I[555] = I[556] = I[557] = I[558] = I[559] = I[560] = I[561] = I[562] = (T)(img)(0,_n10##y,z,c)), \ - (I[575] = I[576] = I[577] = I[578] = I[579] = I[580] = I[581] = I[582] = I[583] = I[584] = I[585] = I[586] = I[587] = (T)(img)(0,_n11##y,z,c)), \ - (I[600] = I[601] = I[602] = I[603] = I[604] = I[605] = I[606] = I[607] = I[608] = I[609] = I[610] = I[611] = I[612] = (T)(img)(0,_n12##y,z,c)), \ - (I[13] = (T)(img)(_n1##x,_p12##y,z,c)), \ - (I[38] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[63] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[88] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[113] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[138] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[163] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[188] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[213] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[238] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[263] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[288] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[313] = (T)(img)(_n1##x,y,z,c)), \ - (I[338] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[363] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[388] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[413] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[438] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[463] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[488] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[513] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[538] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[563] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[588] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[613] = (T)(img)(_n1##x,_n12##y,z,c)), \ - (I[14] = (T)(img)(_n2##x,_p12##y,z,c)), \ - (I[39] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[64] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[89] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[114] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[139] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[164] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[189] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[214] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[239] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[264] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[289] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[314] = (T)(img)(_n2##x,y,z,c)), \ - (I[339] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[364] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[389] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[414] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[439] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[464] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[489] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[514] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[539] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[564] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[589] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[614] = (T)(img)(_n2##x,_n12##y,z,c)), \ - (I[15] = (T)(img)(_n3##x,_p12##y,z,c)), \ - (I[40] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[65] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[90] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[115] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[140] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[165] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[190] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[215] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[240] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[265] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[290] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[315] = (T)(img)(_n3##x,y,z,c)), \ - (I[340] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[365] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[390] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[415] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[440] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[465] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[490] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[515] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[540] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[565] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[590] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[615] = (T)(img)(_n3##x,_n12##y,z,c)), \ - (I[16] = (T)(img)(_n4##x,_p12##y,z,c)), \ - (I[41] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[66] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[91] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[116] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[141] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[166] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[191] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[216] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[241] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[266] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[291] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[316] = (T)(img)(_n4##x,y,z,c)), \ - (I[341] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[366] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[391] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[416] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[441] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[466] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[491] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[516] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[541] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[566] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[591] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[616] = (T)(img)(_n4##x,_n12##y,z,c)), \ - (I[17] = (T)(img)(_n5##x,_p12##y,z,c)), \ - (I[42] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[67] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[92] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[117] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[142] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[167] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[192] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[217] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[242] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[267] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[292] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[317] = (T)(img)(_n5##x,y,z,c)), \ - (I[342] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[367] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[392] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[417] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[442] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[467] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[492] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[517] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[542] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[567] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[592] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[617] = (T)(img)(_n5##x,_n12##y,z,c)), \ - (I[18] = (T)(img)(_n6##x,_p12##y,z,c)), \ - (I[43] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[68] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[93] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[118] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[143] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[168] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[193] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[218] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[243] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[268] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[293] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[318] = (T)(img)(_n6##x,y,z,c)), \ - (I[343] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[368] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[393] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[418] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[443] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[468] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[493] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[518] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[543] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[568] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[593] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[618] = (T)(img)(_n6##x,_n12##y,z,c)), \ - (I[19] = (T)(img)(_n7##x,_p12##y,z,c)), \ - (I[44] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[69] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[94] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[119] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[144] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[169] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[194] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[219] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[244] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[269] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[294] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[319] = (T)(img)(_n7##x,y,z,c)), \ - (I[344] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[369] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[394] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[419] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[444] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[469] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[494] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[519] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[544] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[569] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[594] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[619] = (T)(img)(_n7##x,_n12##y,z,c)), \ - (I[20] = (T)(img)(_n8##x,_p12##y,z,c)), \ - (I[45] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[70] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[95] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[120] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[145] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[170] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[195] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[220] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[245] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[270] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[295] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[320] = (T)(img)(_n8##x,y,z,c)), \ - (I[345] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[370] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[395] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[420] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[445] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[470] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[495] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[520] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[545] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[570] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[595] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[620] = (T)(img)(_n8##x,_n12##y,z,c)), \ - (I[21] = (T)(img)(_n9##x,_p12##y,z,c)), \ - (I[46] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[71] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[96] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[121] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[146] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[171] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[196] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[221] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[246] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[271] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[296] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[321] = (T)(img)(_n9##x,y,z,c)), \ - (I[346] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[371] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[396] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[421] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[446] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[471] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[496] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[521] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[546] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[571] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[596] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[621] = (T)(img)(_n9##x,_n12##y,z,c)), \ - (I[22] = (T)(img)(_n10##x,_p12##y,z,c)), \ - (I[47] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[72] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[97] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[122] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[147] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[172] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[197] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[222] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[247] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[272] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[297] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[322] = (T)(img)(_n10##x,y,z,c)), \ - (I[347] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[372] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[397] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[422] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[447] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[472] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[497] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[522] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[547] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[572] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[597] = (T)(img)(_n10##x,_n11##y,z,c)), \ - (I[622] = (T)(img)(_n10##x,_n12##y,z,c)), \ - (I[23] = (T)(img)(_n11##x,_p12##y,z,c)), \ - (I[48] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[73] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[98] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[123] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[148] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[173] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[198] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[223] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[248] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[273] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[298] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[323] = (T)(img)(_n11##x,y,z,c)), \ - (I[348] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[373] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[398] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[423] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[448] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[473] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[498] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[523] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[548] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[573] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[598] = (T)(img)(_n11##x,_n11##y,z,c)), \ - (I[623] = (T)(img)(_n11##x,_n12##y,z,c)), \ - 12>=((img)._width)?(img).width() - 1:12); \ - (_n12##x<(img).width() && ( \ - (I[24] = (T)(img)(_n12##x,_p12##y,z,c)), \ - (I[49] = (T)(img)(_n12##x,_p11##y,z,c)), \ - (I[74] = (T)(img)(_n12##x,_p10##y,z,c)), \ - (I[99] = (T)(img)(_n12##x,_p9##y,z,c)), \ - (I[124] = (T)(img)(_n12##x,_p8##y,z,c)), \ - (I[149] = (T)(img)(_n12##x,_p7##y,z,c)), \ - (I[174] = (T)(img)(_n12##x,_p6##y,z,c)), \ - (I[199] = (T)(img)(_n12##x,_p5##y,z,c)), \ - (I[224] = (T)(img)(_n12##x,_p4##y,z,c)), \ - (I[249] = (T)(img)(_n12##x,_p3##y,z,c)), \ - (I[274] = (T)(img)(_n12##x,_p2##y,z,c)), \ - (I[299] = (T)(img)(_n12##x,_p1##y,z,c)), \ - (I[324] = (T)(img)(_n12##x,y,z,c)), \ - (I[349] = (T)(img)(_n12##x,_n1##y,z,c)), \ - (I[374] = (T)(img)(_n12##x,_n2##y,z,c)), \ - (I[399] = (T)(img)(_n12##x,_n3##y,z,c)), \ - (I[424] = (T)(img)(_n12##x,_n4##y,z,c)), \ - (I[449] = (T)(img)(_n12##x,_n5##y,z,c)), \ - (I[474] = (T)(img)(_n12##x,_n6##y,z,c)), \ - (I[499] = (T)(img)(_n12##x,_n7##y,z,c)), \ - (I[524] = (T)(img)(_n12##x,_n8##y,z,c)), \ - (I[549] = (T)(img)(_n12##x,_n9##y,z,c)), \ - (I[574] = (T)(img)(_n12##x,_n10##y,z,c)), \ - (I[599] = (T)(img)(_n12##x,_n11##y,z,c)), \ - (I[624] = (T)(img)(_n12##x,_n12##y,z,c)),1)) || \ - _n11##x==--_n12##x || _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n12##x = _n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], \ - I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], \ - I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], \ - I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], \ - I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], \ - I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], \ - I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], \ - I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], \ - I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], \ - I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], \ - I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], \ - I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], \ - I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], \ - I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], \ - I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], \ - I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], \ - I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], I[415] = I[416], I[416] = I[417], I[417] = I[418], I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], \ - I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], I[447] = I[448], I[448] = I[449], \ - I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], I[463] = I[464], I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], \ - I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], I[479] = I[480], I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], I[493] = I[494], I[494] = I[495], I[495] = I[496], I[496] = I[497], I[497] = I[498], I[498] = I[499], \ - I[500] = I[501], I[501] = I[502], I[502] = I[503], I[503] = I[504], I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], I[511] = I[512], I[512] = I[513], I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], I[519] = I[520], I[520] = I[521], I[521] = I[522], I[522] = I[523], I[523] = I[524], \ - I[525] = I[526], I[526] = I[527], I[527] = I[528], I[528] = I[529], I[529] = I[530], I[530] = I[531], I[531] = I[532], I[532] = I[533], I[533] = I[534], I[534] = I[535], I[535] = I[536], I[536] = I[537], I[537] = I[538], I[538] = I[539], I[539] = I[540], I[540] = I[541], I[541] = I[542], I[542] = I[543], I[543] = I[544], I[544] = I[545], I[545] = I[546], I[546] = I[547], I[547] = I[548], I[548] = I[549], \ - I[550] = I[551], I[551] = I[552], I[552] = I[553], I[553] = I[554], I[554] = I[555], I[555] = I[556], I[556] = I[557], I[557] = I[558], I[558] = I[559], I[559] = I[560], I[560] = I[561], I[561] = I[562], I[562] = I[563], I[563] = I[564], I[564] = I[565], I[565] = I[566], I[566] = I[567], I[567] = I[568], I[568] = I[569], I[569] = I[570], I[570] = I[571], I[571] = I[572], I[572] = I[573], I[573] = I[574], \ - I[575] = I[576], I[576] = I[577], I[577] = I[578], I[578] = I[579], I[579] = I[580], I[580] = I[581], I[581] = I[582], I[582] = I[583], I[583] = I[584], I[584] = I[585], I[585] = I[586], I[586] = I[587], I[587] = I[588], I[588] = I[589], I[589] = I[590], I[590] = I[591], I[591] = I[592], I[592] = I[593], I[593] = I[594], I[594] = I[595], I[595] = I[596], I[596] = I[597], I[597] = I[598], I[598] = I[599], \ - I[600] = I[601], I[601] = I[602], I[602] = I[603], I[603] = I[604], I[604] = I[605], I[605] = I[606], I[606] = I[607], I[607] = I[608], I[608] = I[609], I[609] = I[610], I[610] = I[611], I[611] = I[612], I[612] = I[613], I[613] = I[614], I[614] = I[615], I[615] = I[616], I[616] = I[617], I[617] = I[618], I[618] = I[619], I[619] = I[620], I[620] = I[621], I[621] = I[622], I[622] = I[623], I[623] = I[624], \ - _p12##x = _p11##x, _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x, ++_n12##x) - -#define cimg_for_in25x25(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in25((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p12##x = x - 12<0?0:x - 12, \ - _p11##x = x - 11<0?0:x - 11, \ - _p10##x = x - 10<0?0:x - 10, \ - _p9##x = x - 9<0?0:x - 9, \ - _p8##x = x - 8<0?0:x - 8, \ - _p7##x = x - 7<0?0:x - 7, \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = x + 6>=(img).width()?(img).width() - 1:x + 6, \ - _n7##x = x + 7>=(img).width()?(img).width() - 1:x + 7, \ - _n8##x = x + 8>=(img).width()?(img).width() - 1:x + 8, \ - _n9##x = x + 9>=(img).width()?(img).width() - 1:x + 9, \ - _n10##x = x + 10>=(img).width()?(img).width() - 1:x + 10, \ - _n11##x = x + 11>=(img).width()?(img).width() - 1:x + 11, \ - _n12##x = (int)( \ - (I[0] = (T)(img)(_p12##x,_p12##y,z,c)), \ - (I[25] = (T)(img)(_p12##x,_p11##y,z,c)), \ - (I[50] = (T)(img)(_p12##x,_p10##y,z,c)), \ - (I[75] = (T)(img)(_p12##x,_p9##y,z,c)), \ - (I[100] = (T)(img)(_p12##x,_p8##y,z,c)), \ - (I[125] = (T)(img)(_p12##x,_p7##y,z,c)), \ - (I[150] = (T)(img)(_p12##x,_p6##y,z,c)), \ - (I[175] = (T)(img)(_p12##x,_p5##y,z,c)), \ - (I[200] = (T)(img)(_p12##x,_p4##y,z,c)), \ - (I[225] = (T)(img)(_p12##x,_p3##y,z,c)), \ - (I[250] = (T)(img)(_p12##x,_p2##y,z,c)), \ - (I[275] = (T)(img)(_p12##x,_p1##y,z,c)), \ - (I[300] = (T)(img)(_p12##x,y,z,c)), \ - (I[325] = (T)(img)(_p12##x,_n1##y,z,c)), \ - (I[350] = (T)(img)(_p12##x,_n2##y,z,c)), \ - (I[375] = (T)(img)(_p12##x,_n3##y,z,c)), \ - (I[400] = (T)(img)(_p12##x,_n4##y,z,c)), \ - (I[425] = (T)(img)(_p12##x,_n5##y,z,c)), \ - (I[450] = (T)(img)(_p12##x,_n6##y,z,c)), \ - (I[475] = (T)(img)(_p12##x,_n7##y,z,c)), \ - (I[500] = (T)(img)(_p12##x,_n8##y,z,c)), \ - (I[525] = (T)(img)(_p12##x,_n9##y,z,c)), \ - (I[550] = (T)(img)(_p12##x,_n10##y,z,c)), \ - (I[575] = (T)(img)(_p12##x,_n11##y,z,c)), \ - (I[600] = (T)(img)(_p12##x,_n12##y,z,c)), \ - (I[1] = (T)(img)(_p11##x,_p12##y,z,c)), \ - (I[26] = (T)(img)(_p11##x,_p11##y,z,c)), \ - (I[51] = (T)(img)(_p11##x,_p10##y,z,c)), \ - (I[76] = (T)(img)(_p11##x,_p9##y,z,c)), \ - (I[101] = (T)(img)(_p11##x,_p8##y,z,c)), \ - (I[126] = (T)(img)(_p11##x,_p7##y,z,c)), \ - (I[151] = (T)(img)(_p11##x,_p6##y,z,c)), \ - (I[176] = (T)(img)(_p11##x,_p5##y,z,c)), \ - (I[201] = (T)(img)(_p11##x,_p4##y,z,c)), \ - (I[226] = (T)(img)(_p11##x,_p3##y,z,c)), \ - (I[251] = (T)(img)(_p11##x,_p2##y,z,c)), \ - (I[276] = (T)(img)(_p11##x,_p1##y,z,c)), \ - (I[301] = (T)(img)(_p11##x,y,z,c)), \ - (I[326] = (T)(img)(_p11##x,_n1##y,z,c)), \ - (I[351] = (T)(img)(_p11##x,_n2##y,z,c)), \ - (I[376] = (T)(img)(_p11##x,_n3##y,z,c)), \ - (I[401] = (T)(img)(_p11##x,_n4##y,z,c)), \ - (I[426] = (T)(img)(_p11##x,_n5##y,z,c)), \ - (I[451] = (T)(img)(_p11##x,_n6##y,z,c)), \ - (I[476] = (T)(img)(_p11##x,_n7##y,z,c)), \ - (I[501] = (T)(img)(_p11##x,_n8##y,z,c)), \ - (I[526] = (T)(img)(_p11##x,_n9##y,z,c)), \ - (I[551] = (T)(img)(_p11##x,_n10##y,z,c)), \ - (I[576] = (T)(img)(_p11##x,_n11##y,z,c)), \ - (I[601] = (T)(img)(_p11##x,_n12##y,z,c)), \ - (I[2] = (T)(img)(_p10##x,_p12##y,z,c)), \ - (I[27] = (T)(img)(_p10##x,_p11##y,z,c)), \ - (I[52] = (T)(img)(_p10##x,_p10##y,z,c)), \ - (I[77] = (T)(img)(_p10##x,_p9##y,z,c)), \ - (I[102] = (T)(img)(_p10##x,_p8##y,z,c)), \ - (I[127] = (T)(img)(_p10##x,_p7##y,z,c)), \ - (I[152] = (T)(img)(_p10##x,_p6##y,z,c)), \ - (I[177] = (T)(img)(_p10##x,_p5##y,z,c)), \ - (I[202] = (T)(img)(_p10##x,_p4##y,z,c)), \ - (I[227] = (T)(img)(_p10##x,_p3##y,z,c)), \ - (I[252] = (T)(img)(_p10##x,_p2##y,z,c)), \ - (I[277] = (T)(img)(_p10##x,_p1##y,z,c)), \ - (I[302] = (T)(img)(_p10##x,y,z,c)), \ - (I[327] = (T)(img)(_p10##x,_n1##y,z,c)), \ - (I[352] = (T)(img)(_p10##x,_n2##y,z,c)), \ - (I[377] = (T)(img)(_p10##x,_n3##y,z,c)), \ - (I[402] = (T)(img)(_p10##x,_n4##y,z,c)), \ - (I[427] = (T)(img)(_p10##x,_n5##y,z,c)), \ - (I[452] = (T)(img)(_p10##x,_n6##y,z,c)), \ - (I[477] = (T)(img)(_p10##x,_n7##y,z,c)), \ - (I[502] = (T)(img)(_p10##x,_n8##y,z,c)), \ - (I[527] = (T)(img)(_p10##x,_n9##y,z,c)), \ - (I[552] = (T)(img)(_p10##x,_n10##y,z,c)), \ - (I[577] = (T)(img)(_p10##x,_n11##y,z,c)), \ - (I[602] = (T)(img)(_p10##x,_n12##y,z,c)), \ - (I[3] = (T)(img)(_p9##x,_p12##y,z,c)), \ - (I[28] = (T)(img)(_p9##x,_p11##y,z,c)), \ - (I[53] = (T)(img)(_p9##x,_p10##y,z,c)), \ - (I[78] = (T)(img)(_p9##x,_p9##y,z,c)), \ - (I[103] = (T)(img)(_p9##x,_p8##y,z,c)), \ - (I[128] = (T)(img)(_p9##x,_p7##y,z,c)), \ - (I[153] = (T)(img)(_p9##x,_p6##y,z,c)), \ - (I[178] = (T)(img)(_p9##x,_p5##y,z,c)), \ - (I[203] = (T)(img)(_p9##x,_p4##y,z,c)), \ - (I[228] = (T)(img)(_p9##x,_p3##y,z,c)), \ - (I[253] = (T)(img)(_p9##x,_p2##y,z,c)), \ - (I[278] = (T)(img)(_p9##x,_p1##y,z,c)), \ - (I[303] = (T)(img)(_p9##x,y,z,c)), \ - (I[328] = (T)(img)(_p9##x,_n1##y,z,c)), \ - (I[353] = (T)(img)(_p9##x,_n2##y,z,c)), \ - (I[378] = (T)(img)(_p9##x,_n3##y,z,c)), \ - (I[403] = (T)(img)(_p9##x,_n4##y,z,c)), \ - (I[428] = (T)(img)(_p9##x,_n5##y,z,c)), \ - (I[453] = (T)(img)(_p9##x,_n6##y,z,c)), \ - (I[478] = (T)(img)(_p9##x,_n7##y,z,c)), \ - (I[503] = (T)(img)(_p9##x,_n8##y,z,c)), \ - (I[528] = (T)(img)(_p9##x,_n9##y,z,c)), \ - (I[553] = (T)(img)(_p9##x,_n10##y,z,c)), \ - (I[578] = (T)(img)(_p9##x,_n11##y,z,c)), \ - (I[603] = (T)(img)(_p9##x,_n12##y,z,c)), \ - (I[4] = (T)(img)(_p8##x,_p12##y,z,c)), \ - (I[29] = (T)(img)(_p8##x,_p11##y,z,c)), \ - (I[54] = (T)(img)(_p8##x,_p10##y,z,c)), \ - (I[79] = (T)(img)(_p8##x,_p9##y,z,c)), \ - (I[104] = (T)(img)(_p8##x,_p8##y,z,c)), \ - (I[129] = (T)(img)(_p8##x,_p7##y,z,c)), \ - (I[154] = (T)(img)(_p8##x,_p6##y,z,c)), \ - (I[179] = (T)(img)(_p8##x,_p5##y,z,c)), \ - (I[204] = (T)(img)(_p8##x,_p4##y,z,c)), \ - (I[229] = (T)(img)(_p8##x,_p3##y,z,c)), \ - (I[254] = (T)(img)(_p8##x,_p2##y,z,c)), \ - (I[279] = (T)(img)(_p8##x,_p1##y,z,c)), \ - (I[304] = (T)(img)(_p8##x,y,z,c)), \ - (I[329] = (T)(img)(_p8##x,_n1##y,z,c)), \ - (I[354] = (T)(img)(_p8##x,_n2##y,z,c)), \ - (I[379] = (T)(img)(_p8##x,_n3##y,z,c)), \ - (I[404] = (T)(img)(_p8##x,_n4##y,z,c)), \ - (I[429] = (T)(img)(_p8##x,_n5##y,z,c)), \ - (I[454] = (T)(img)(_p8##x,_n6##y,z,c)), \ - (I[479] = (T)(img)(_p8##x,_n7##y,z,c)), \ - (I[504] = (T)(img)(_p8##x,_n8##y,z,c)), \ - (I[529] = (T)(img)(_p8##x,_n9##y,z,c)), \ - (I[554] = (T)(img)(_p8##x,_n10##y,z,c)), \ - (I[579] = (T)(img)(_p8##x,_n11##y,z,c)), \ - (I[604] = (T)(img)(_p8##x,_n12##y,z,c)), \ - (I[5] = (T)(img)(_p7##x,_p12##y,z,c)), \ - (I[30] = (T)(img)(_p7##x,_p11##y,z,c)), \ - (I[55] = (T)(img)(_p7##x,_p10##y,z,c)), \ - (I[80] = (T)(img)(_p7##x,_p9##y,z,c)), \ - (I[105] = (T)(img)(_p7##x,_p8##y,z,c)), \ - (I[130] = (T)(img)(_p7##x,_p7##y,z,c)), \ - (I[155] = (T)(img)(_p7##x,_p6##y,z,c)), \ - (I[180] = (T)(img)(_p7##x,_p5##y,z,c)), \ - (I[205] = (T)(img)(_p7##x,_p4##y,z,c)), \ - (I[230] = (T)(img)(_p7##x,_p3##y,z,c)), \ - (I[255] = (T)(img)(_p7##x,_p2##y,z,c)), \ - (I[280] = (T)(img)(_p7##x,_p1##y,z,c)), \ - (I[305] = (T)(img)(_p7##x,y,z,c)), \ - (I[330] = (T)(img)(_p7##x,_n1##y,z,c)), \ - (I[355] = (T)(img)(_p7##x,_n2##y,z,c)), \ - (I[380] = (T)(img)(_p7##x,_n3##y,z,c)), \ - (I[405] = (T)(img)(_p7##x,_n4##y,z,c)), \ - (I[430] = (T)(img)(_p7##x,_n5##y,z,c)), \ - (I[455] = (T)(img)(_p7##x,_n6##y,z,c)), \ - (I[480] = (T)(img)(_p7##x,_n7##y,z,c)), \ - (I[505] = (T)(img)(_p7##x,_n8##y,z,c)), \ - (I[530] = (T)(img)(_p7##x,_n9##y,z,c)), \ - (I[555] = (T)(img)(_p7##x,_n10##y,z,c)), \ - (I[580] = (T)(img)(_p7##x,_n11##y,z,c)), \ - (I[605] = (T)(img)(_p7##x,_n12##y,z,c)), \ - (I[6] = (T)(img)(_p6##x,_p12##y,z,c)), \ - (I[31] = (T)(img)(_p6##x,_p11##y,z,c)), \ - (I[56] = (T)(img)(_p6##x,_p10##y,z,c)), \ - (I[81] = (T)(img)(_p6##x,_p9##y,z,c)), \ - (I[106] = (T)(img)(_p6##x,_p8##y,z,c)), \ - (I[131] = (T)(img)(_p6##x,_p7##y,z,c)), \ - (I[156] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[181] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[206] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[231] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[256] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[281] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[306] = (T)(img)(_p6##x,y,z,c)), \ - (I[331] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[356] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[381] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[406] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[431] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[456] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[481] = (T)(img)(_p6##x,_n7##y,z,c)), \ - (I[506] = (T)(img)(_p6##x,_n8##y,z,c)), \ - (I[531] = (T)(img)(_p6##x,_n9##y,z,c)), \ - (I[556] = (T)(img)(_p6##x,_n10##y,z,c)), \ - (I[581] = (T)(img)(_p6##x,_n11##y,z,c)), \ - (I[606] = (T)(img)(_p6##x,_n12##y,z,c)), \ - (I[7] = (T)(img)(_p5##x,_p12##y,z,c)), \ - (I[32] = (T)(img)(_p5##x,_p11##y,z,c)), \ - (I[57] = (T)(img)(_p5##x,_p10##y,z,c)), \ - (I[82] = (T)(img)(_p5##x,_p9##y,z,c)), \ - (I[107] = (T)(img)(_p5##x,_p8##y,z,c)), \ - (I[132] = (T)(img)(_p5##x,_p7##y,z,c)), \ - (I[157] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[182] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[207] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[232] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[257] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[282] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[307] = (T)(img)(_p5##x,y,z,c)), \ - (I[332] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[357] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[382] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[407] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[432] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[457] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[482] = (T)(img)(_p5##x,_n7##y,z,c)), \ - (I[507] = (T)(img)(_p5##x,_n8##y,z,c)), \ - (I[532] = (T)(img)(_p5##x,_n9##y,z,c)), \ - (I[557] = (T)(img)(_p5##x,_n10##y,z,c)), \ - (I[582] = (T)(img)(_p5##x,_n11##y,z,c)), \ - (I[607] = (T)(img)(_p5##x,_n12##y,z,c)), \ - (I[8] = (T)(img)(_p4##x,_p12##y,z,c)), \ - (I[33] = (T)(img)(_p4##x,_p11##y,z,c)), \ - (I[58] = (T)(img)(_p4##x,_p10##y,z,c)), \ - (I[83] = (T)(img)(_p4##x,_p9##y,z,c)), \ - (I[108] = (T)(img)(_p4##x,_p8##y,z,c)), \ - (I[133] = (T)(img)(_p4##x,_p7##y,z,c)), \ - (I[158] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[183] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[208] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[233] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[258] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[283] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[308] = (T)(img)(_p4##x,y,z,c)), \ - (I[333] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[358] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[383] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[408] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[433] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[458] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[483] = (T)(img)(_p4##x,_n7##y,z,c)), \ - (I[508] = (T)(img)(_p4##x,_n8##y,z,c)), \ - (I[533] = (T)(img)(_p4##x,_n9##y,z,c)), \ - (I[558] = (T)(img)(_p4##x,_n10##y,z,c)), \ - (I[583] = (T)(img)(_p4##x,_n11##y,z,c)), \ - (I[608] = (T)(img)(_p4##x,_n12##y,z,c)), \ - (I[9] = (T)(img)(_p3##x,_p12##y,z,c)), \ - (I[34] = (T)(img)(_p3##x,_p11##y,z,c)), \ - (I[59] = (T)(img)(_p3##x,_p10##y,z,c)), \ - (I[84] = (T)(img)(_p3##x,_p9##y,z,c)), \ - (I[109] = (T)(img)(_p3##x,_p8##y,z,c)), \ - (I[134] = (T)(img)(_p3##x,_p7##y,z,c)), \ - (I[159] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[184] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[209] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[234] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[259] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[284] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[309] = (T)(img)(_p3##x,y,z,c)), \ - (I[334] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[359] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[384] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[409] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[434] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[459] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[484] = (T)(img)(_p3##x,_n7##y,z,c)), \ - (I[509] = (T)(img)(_p3##x,_n8##y,z,c)), \ - (I[534] = (T)(img)(_p3##x,_n9##y,z,c)), \ - (I[559] = (T)(img)(_p3##x,_n10##y,z,c)), \ - (I[584] = (T)(img)(_p3##x,_n11##y,z,c)), \ - (I[609] = (T)(img)(_p3##x,_n12##y,z,c)), \ - (I[10] = (T)(img)(_p2##x,_p12##y,z,c)), \ - (I[35] = (T)(img)(_p2##x,_p11##y,z,c)), \ - (I[60] = (T)(img)(_p2##x,_p10##y,z,c)), \ - (I[85] = (T)(img)(_p2##x,_p9##y,z,c)), \ - (I[110] = (T)(img)(_p2##x,_p8##y,z,c)), \ - (I[135] = (T)(img)(_p2##x,_p7##y,z,c)), \ - (I[160] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[185] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[210] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[235] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[260] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[285] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[310] = (T)(img)(_p2##x,y,z,c)), \ - (I[335] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[360] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[385] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[410] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[435] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[460] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[485] = (T)(img)(_p2##x,_n7##y,z,c)), \ - (I[510] = (T)(img)(_p2##x,_n8##y,z,c)), \ - (I[535] = (T)(img)(_p2##x,_n9##y,z,c)), \ - (I[560] = (T)(img)(_p2##x,_n10##y,z,c)), \ - (I[585] = (T)(img)(_p2##x,_n11##y,z,c)), \ - (I[610] = (T)(img)(_p2##x,_n12##y,z,c)), \ - (I[11] = (T)(img)(_p1##x,_p12##y,z,c)), \ - (I[36] = (T)(img)(_p1##x,_p11##y,z,c)), \ - (I[61] = (T)(img)(_p1##x,_p10##y,z,c)), \ - (I[86] = (T)(img)(_p1##x,_p9##y,z,c)), \ - (I[111] = (T)(img)(_p1##x,_p8##y,z,c)), \ - (I[136] = (T)(img)(_p1##x,_p7##y,z,c)), \ - (I[161] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[186] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[211] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[236] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[261] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[286] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[311] = (T)(img)(_p1##x,y,z,c)), \ - (I[336] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[361] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[386] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[411] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[436] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[461] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[486] = (T)(img)(_p1##x,_n7##y,z,c)), \ - (I[511] = (T)(img)(_p1##x,_n8##y,z,c)), \ - (I[536] = (T)(img)(_p1##x,_n9##y,z,c)), \ - (I[561] = (T)(img)(_p1##x,_n10##y,z,c)), \ - (I[586] = (T)(img)(_p1##x,_n11##y,z,c)), \ - (I[611] = (T)(img)(_p1##x,_n12##y,z,c)), \ - (I[12] = (T)(img)(x,_p12##y,z,c)), \ - (I[37] = (T)(img)(x,_p11##y,z,c)), \ - (I[62] = (T)(img)(x,_p10##y,z,c)), \ - (I[87] = (T)(img)(x,_p9##y,z,c)), \ - (I[112] = (T)(img)(x,_p8##y,z,c)), \ - (I[137] = (T)(img)(x,_p7##y,z,c)), \ - (I[162] = (T)(img)(x,_p6##y,z,c)), \ - (I[187] = (T)(img)(x,_p5##y,z,c)), \ - (I[212] = (T)(img)(x,_p4##y,z,c)), \ - (I[237] = (T)(img)(x,_p3##y,z,c)), \ - (I[262] = (T)(img)(x,_p2##y,z,c)), \ - (I[287] = (T)(img)(x,_p1##y,z,c)), \ - (I[312] = (T)(img)(x,y,z,c)), \ - (I[337] = (T)(img)(x,_n1##y,z,c)), \ - (I[362] = (T)(img)(x,_n2##y,z,c)), \ - (I[387] = (T)(img)(x,_n3##y,z,c)), \ - (I[412] = (T)(img)(x,_n4##y,z,c)), \ - (I[437] = (T)(img)(x,_n5##y,z,c)), \ - (I[462] = (T)(img)(x,_n6##y,z,c)), \ - (I[487] = (T)(img)(x,_n7##y,z,c)), \ - (I[512] = (T)(img)(x,_n8##y,z,c)), \ - (I[537] = (T)(img)(x,_n9##y,z,c)), \ - (I[562] = (T)(img)(x,_n10##y,z,c)), \ - (I[587] = (T)(img)(x,_n11##y,z,c)), \ - (I[612] = (T)(img)(x,_n12##y,z,c)), \ - (I[13] = (T)(img)(_n1##x,_p12##y,z,c)), \ - (I[38] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[63] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[88] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[113] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[138] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[163] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[188] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[213] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[238] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[263] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[288] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[313] = (T)(img)(_n1##x,y,z,c)), \ - (I[338] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[363] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[388] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[413] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[438] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[463] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[488] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[513] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[538] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[563] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[588] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[613] = (T)(img)(_n1##x,_n12##y,z,c)), \ - (I[14] = (T)(img)(_n2##x,_p12##y,z,c)), \ - (I[39] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[64] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[89] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[114] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[139] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[164] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[189] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[214] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[239] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[264] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[289] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[314] = (T)(img)(_n2##x,y,z,c)), \ - (I[339] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[364] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[389] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[414] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[439] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[464] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[489] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[514] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[539] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[564] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[589] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[614] = (T)(img)(_n2##x,_n12##y,z,c)), \ - (I[15] = (T)(img)(_n3##x,_p12##y,z,c)), \ - (I[40] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[65] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[90] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[115] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[140] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[165] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[190] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[215] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[240] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[265] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[290] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[315] = (T)(img)(_n3##x,y,z,c)), \ - (I[340] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[365] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[390] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[415] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[440] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[465] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[490] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[515] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[540] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[565] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[590] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[615] = (T)(img)(_n3##x,_n12##y,z,c)), \ - (I[16] = (T)(img)(_n4##x,_p12##y,z,c)), \ - (I[41] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[66] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[91] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[116] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[141] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[166] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[191] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[216] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[241] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[266] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[291] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[316] = (T)(img)(_n4##x,y,z,c)), \ - (I[341] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[366] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[391] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[416] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[441] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[466] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[491] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[516] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[541] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[566] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[591] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[616] = (T)(img)(_n4##x,_n12##y,z,c)), \ - (I[17] = (T)(img)(_n5##x,_p12##y,z,c)), \ - (I[42] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[67] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[92] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[117] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[142] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[167] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[192] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[217] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[242] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[267] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[292] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[317] = (T)(img)(_n5##x,y,z,c)), \ - (I[342] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[367] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[392] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[417] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[442] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[467] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[492] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[517] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[542] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[567] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[592] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[617] = (T)(img)(_n5##x,_n12##y,z,c)), \ - (I[18] = (T)(img)(_n6##x,_p12##y,z,c)), \ - (I[43] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[68] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[93] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[118] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[143] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[168] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[193] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[218] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[243] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[268] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[293] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[318] = (T)(img)(_n6##x,y,z,c)), \ - (I[343] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[368] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[393] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[418] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[443] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[468] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[493] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[518] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[543] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[568] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[593] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[618] = (T)(img)(_n6##x,_n12##y,z,c)), \ - (I[19] = (T)(img)(_n7##x,_p12##y,z,c)), \ - (I[44] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[69] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[94] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[119] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[144] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[169] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[194] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[219] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[244] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[269] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[294] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[319] = (T)(img)(_n7##x,y,z,c)), \ - (I[344] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[369] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[394] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[419] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[444] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[469] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[494] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[519] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[544] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[569] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[594] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[619] = (T)(img)(_n7##x,_n12##y,z,c)), \ - (I[20] = (T)(img)(_n8##x,_p12##y,z,c)), \ - (I[45] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[70] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[95] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[120] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[145] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[170] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[195] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[220] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[245] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[270] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[295] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[320] = (T)(img)(_n8##x,y,z,c)), \ - (I[345] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[370] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[395] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[420] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[445] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[470] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[495] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[520] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[545] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[570] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[595] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[620] = (T)(img)(_n8##x,_n12##y,z,c)), \ - (I[21] = (T)(img)(_n9##x,_p12##y,z,c)), \ - (I[46] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[71] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[96] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[121] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[146] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[171] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[196] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[221] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[246] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[271] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[296] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[321] = (T)(img)(_n9##x,y,z,c)), \ - (I[346] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[371] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[396] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[421] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[446] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[471] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[496] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[521] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[546] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[571] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[596] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[621] = (T)(img)(_n9##x,_n12##y,z,c)), \ - (I[22] = (T)(img)(_n10##x,_p12##y,z,c)), \ - (I[47] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[72] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[97] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[122] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[147] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[172] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[197] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[222] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[247] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[272] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[297] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[322] = (T)(img)(_n10##x,y,z,c)), \ - (I[347] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[372] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[397] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[422] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[447] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[472] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[497] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[522] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[547] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[572] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[597] = (T)(img)(_n10##x,_n11##y,z,c)), \ - (I[622] = (T)(img)(_n10##x,_n12##y,z,c)), \ - (I[23] = (T)(img)(_n11##x,_p12##y,z,c)), \ - (I[48] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[73] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[98] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[123] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[148] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[173] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[198] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[223] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[248] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[273] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[298] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[323] = (T)(img)(_n11##x,y,z,c)), \ - (I[348] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[373] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[398] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[423] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[448] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[473] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[498] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[523] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[548] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[573] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[598] = (T)(img)(_n11##x,_n11##y,z,c)), \ - (I[623] = (T)(img)(_n11##x,_n12##y,z,c)), \ - x + 12>=(img).width()?(img).width() - 1:x + 12); \ - x<=(int)(x1) && ((_n12##x<(img).width() && ( \ - (I[24] = (T)(img)(_n12##x,_p12##y,z,c)), \ - (I[49] = (T)(img)(_n12##x,_p11##y,z,c)), \ - (I[74] = (T)(img)(_n12##x,_p10##y,z,c)), \ - (I[99] = (T)(img)(_n12##x,_p9##y,z,c)), \ - (I[124] = (T)(img)(_n12##x,_p8##y,z,c)), \ - (I[149] = (T)(img)(_n12##x,_p7##y,z,c)), \ - (I[174] = (T)(img)(_n12##x,_p6##y,z,c)), \ - (I[199] = (T)(img)(_n12##x,_p5##y,z,c)), \ - (I[224] = (T)(img)(_n12##x,_p4##y,z,c)), \ - (I[249] = (T)(img)(_n12##x,_p3##y,z,c)), \ - (I[274] = (T)(img)(_n12##x,_p2##y,z,c)), \ - (I[299] = (T)(img)(_n12##x,_p1##y,z,c)), \ - (I[324] = (T)(img)(_n12##x,y,z,c)), \ - (I[349] = (T)(img)(_n12##x,_n1##y,z,c)), \ - (I[374] = (T)(img)(_n12##x,_n2##y,z,c)), \ - (I[399] = (T)(img)(_n12##x,_n3##y,z,c)), \ - (I[424] = (T)(img)(_n12##x,_n4##y,z,c)), \ - (I[449] = (T)(img)(_n12##x,_n5##y,z,c)), \ - (I[474] = (T)(img)(_n12##x,_n6##y,z,c)), \ - (I[499] = (T)(img)(_n12##x,_n7##y,z,c)), \ - (I[524] = (T)(img)(_n12##x,_n8##y,z,c)), \ - (I[549] = (T)(img)(_n12##x,_n9##y,z,c)), \ - (I[574] = (T)(img)(_n12##x,_n10##y,z,c)), \ - (I[599] = (T)(img)(_n12##x,_n11##y,z,c)), \ - (I[624] = (T)(img)(_n12##x,_n12##y,z,c)),1)) || \ - _n11##x==--_n12##x || _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n12##x = _n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], \ - I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], \ - I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], \ - I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], \ - I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], \ - I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], \ - I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], \ - I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], \ - I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], \ - I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], \ - I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], \ - I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], \ - I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], \ - I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], \ - I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], \ - I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], \ - I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], I[415] = I[416], I[416] = I[417], I[417] = I[418], I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], \ - I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], I[447] = I[448], I[448] = I[449], \ - I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], I[463] = I[464], I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], \ - I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], I[479] = I[480], I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], I[493] = I[494], I[494] = I[495], I[495] = I[496], I[496] = I[497], I[497] = I[498], I[498] = I[499], \ - I[500] = I[501], I[501] = I[502], I[502] = I[503], I[503] = I[504], I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], I[511] = I[512], I[512] = I[513], I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], I[519] = I[520], I[520] = I[521], I[521] = I[522], I[522] = I[523], I[523] = I[524], \ - I[525] = I[526], I[526] = I[527], I[527] = I[528], I[528] = I[529], I[529] = I[530], I[530] = I[531], I[531] = I[532], I[532] = I[533], I[533] = I[534], I[534] = I[535], I[535] = I[536], I[536] = I[537], I[537] = I[538], I[538] = I[539], I[539] = I[540], I[540] = I[541], I[541] = I[542], I[542] = I[543], I[543] = I[544], I[544] = I[545], I[545] = I[546], I[546] = I[547], I[547] = I[548], I[548] = I[549], \ - I[550] = I[551], I[551] = I[552], I[552] = I[553], I[553] = I[554], I[554] = I[555], I[555] = I[556], I[556] = I[557], I[557] = I[558], I[558] = I[559], I[559] = I[560], I[560] = I[561], I[561] = I[562], I[562] = I[563], I[563] = I[564], I[564] = I[565], I[565] = I[566], I[566] = I[567], I[567] = I[568], I[568] = I[569], I[569] = I[570], I[570] = I[571], I[571] = I[572], I[572] = I[573], I[573] = I[574], \ - I[575] = I[576], I[576] = I[577], I[577] = I[578], I[578] = I[579], I[579] = I[580], I[580] = I[581], I[581] = I[582], I[582] = I[583], I[583] = I[584], I[584] = I[585], I[585] = I[586], I[586] = I[587], I[587] = I[588], I[588] = I[589], I[589] = I[590], I[590] = I[591], I[591] = I[592], I[592] = I[593], I[593] = I[594], I[594] = I[595], I[595] = I[596], I[596] = I[597], I[597] = I[598], I[598] = I[599], \ - I[600] = I[601], I[601] = I[602], I[602] = I[603], I[603] = I[604], I[604] = I[605], I[605] = I[606], I[606] = I[607], I[607] = I[608], I[608] = I[609], I[609] = I[610], I[610] = I[611], I[611] = I[612], I[612] = I[613], I[613] = I[614], I[614] = I[615], I[615] = I[616], I[616] = I[617], I[617] = I[618], I[618] = I[619], I[619] = I[620], I[620] = I[621], I[621] = I[622], I[622] = I[623], I[623] = I[624], \ - _p12##x = _p11##x, _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x, ++_n12##x) - -#define cimg_get25x25(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p12##x,_p12##y,z,c), I[1] = (T)(img)(_p11##x,_p12##y,z,c), I[2] = (T)(img)(_p10##x,_p12##y,z,c), I[3] = (T)(img)(_p9##x,_p12##y,z,c), I[4] = (T)(img)(_p8##x,_p12##y,z,c), I[5] = (T)(img)(_p7##x,_p12##y,z,c), I[6] = (T)(img)(_p6##x,_p12##y,z,c), I[7] = (T)(img)(_p5##x,_p12##y,z,c), I[8] = (T)(img)(_p4##x,_p12##y,z,c), I[9] = (T)(img)(_p3##x,_p12##y,z,c), I[10] = (T)(img)(_p2##x,_p12##y,z,c), I[11] = (T)(img)(_p1##x,_p12##y,z,c), I[12] = (T)(img)(x,_p12##y,z,c), I[13] = (T)(img)(_n1##x,_p12##y,z,c), I[14] = (T)(img)(_n2##x,_p12##y,z,c), I[15] = (T)(img)(_n3##x,_p12##y,z,c), I[16] = (T)(img)(_n4##x,_p12##y,z,c), I[17] = (T)(img)(_n5##x,_p12##y,z,c), I[18] = (T)(img)(_n6##x,_p12##y,z,c), I[19] = (T)(img)(_n7##x,_p12##y,z,c), I[20] = (T)(img)(_n8##x,_p12##y,z,c), I[21] = (T)(img)(_n9##x,_p12##y,z,c), I[22] = (T)(img)(_n10##x,_p12##y,z,c), I[23] = (T)(img)(_n11##x,_p12##y,z,c), I[24] = (T)(img)(_n12##x,_p12##y,z,c), \ - I[25] = (T)(img)(_p12##x,_p11##y,z,c), I[26] = (T)(img)(_p11##x,_p11##y,z,c), I[27] = (T)(img)(_p10##x,_p11##y,z,c), I[28] = (T)(img)(_p9##x,_p11##y,z,c), I[29] = (T)(img)(_p8##x,_p11##y,z,c), I[30] = (T)(img)(_p7##x,_p11##y,z,c), I[31] = (T)(img)(_p6##x,_p11##y,z,c), I[32] = (T)(img)(_p5##x,_p11##y,z,c), I[33] = (T)(img)(_p4##x,_p11##y,z,c), I[34] = (T)(img)(_p3##x,_p11##y,z,c), I[35] = (T)(img)(_p2##x,_p11##y,z,c), I[36] = (T)(img)(_p1##x,_p11##y,z,c), I[37] = (T)(img)(x,_p11##y,z,c), I[38] = (T)(img)(_n1##x,_p11##y,z,c), I[39] = (T)(img)(_n2##x,_p11##y,z,c), I[40] = (T)(img)(_n3##x,_p11##y,z,c), I[41] = (T)(img)(_n4##x,_p11##y,z,c), I[42] = (T)(img)(_n5##x,_p11##y,z,c), I[43] = (T)(img)(_n6##x,_p11##y,z,c), I[44] = (T)(img)(_n7##x,_p11##y,z,c), I[45] = (T)(img)(_n8##x,_p11##y,z,c), I[46] = (T)(img)(_n9##x,_p11##y,z,c), I[47] = (T)(img)(_n10##x,_p11##y,z,c), I[48] = (T)(img)(_n11##x,_p11##y,z,c), I[49] = (T)(img)(_n12##x,_p11##y,z,c), \ - I[50] = (T)(img)(_p12##x,_p10##y,z,c), I[51] = (T)(img)(_p11##x,_p10##y,z,c), I[52] = (T)(img)(_p10##x,_p10##y,z,c), I[53] = (T)(img)(_p9##x,_p10##y,z,c), I[54] = (T)(img)(_p8##x,_p10##y,z,c), I[55] = (T)(img)(_p7##x,_p10##y,z,c), I[56] = (T)(img)(_p6##x,_p10##y,z,c), I[57] = (T)(img)(_p5##x,_p10##y,z,c), I[58] = (T)(img)(_p4##x,_p10##y,z,c), I[59] = (T)(img)(_p3##x,_p10##y,z,c), I[60] = (T)(img)(_p2##x,_p10##y,z,c), I[61] = (T)(img)(_p1##x,_p10##y,z,c), I[62] = (T)(img)(x,_p10##y,z,c), I[63] = (T)(img)(_n1##x,_p10##y,z,c), I[64] = (T)(img)(_n2##x,_p10##y,z,c), I[65] = (T)(img)(_n3##x,_p10##y,z,c), I[66] = (T)(img)(_n4##x,_p10##y,z,c), I[67] = (T)(img)(_n5##x,_p10##y,z,c), I[68] = (T)(img)(_n6##x,_p10##y,z,c), I[69] = (T)(img)(_n7##x,_p10##y,z,c), I[70] = (T)(img)(_n8##x,_p10##y,z,c), I[71] = (T)(img)(_n9##x,_p10##y,z,c), I[72] = (T)(img)(_n10##x,_p10##y,z,c), I[73] = (T)(img)(_n11##x,_p10##y,z,c), I[74] = (T)(img)(_n12##x,_p10##y,z,c), \ - I[75] = (T)(img)(_p12##x,_p9##y,z,c), I[76] = (T)(img)(_p11##x,_p9##y,z,c), I[77] = (T)(img)(_p10##x,_p9##y,z,c), I[78] = (T)(img)(_p9##x,_p9##y,z,c), I[79] = (T)(img)(_p8##x,_p9##y,z,c), I[80] = (T)(img)(_p7##x,_p9##y,z,c), I[81] = (T)(img)(_p6##x,_p9##y,z,c), I[82] = (T)(img)(_p5##x,_p9##y,z,c), I[83] = (T)(img)(_p4##x,_p9##y,z,c), I[84] = (T)(img)(_p3##x,_p9##y,z,c), I[85] = (T)(img)(_p2##x,_p9##y,z,c), I[86] = (T)(img)(_p1##x,_p9##y,z,c), I[87] = (T)(img)(x,_p9##y,z,c), I[88] = (T)(img)(_n1##x,_p9##y,z,c), I[89] = (T)(img)(_n2##x,_p9##y,z,c), I[90] = (T)(img)(_n3##x,_p9##y,z,c), I[91] = (T)(img)(_n4##x,_p9##y,z,c), I[92] = (T)(img)(_n5##x,_p9##y,z,c), I[93] = (T)(img)(_n6##x,_p9##y,z,c), I[94] = (T)(img)(_n7##x,_p9##y,z,c), I[95] = (T)(img)(_n8##x,_p9##y,z,c), I[96] = (T)(img)(_n9##x,_p9##y,z,c), I[97] = (T)(img)(_n10##x,_p9##y,z,c), I[98] = (T)(img)(_n11##x,_p9##y,z,c), I[99] = (T)(img)(_n12##x,_p9##y,z,c), \ - I[100] = (T)(img)(_p12##x,_p8##y,z,c), I[101] = (T)(img)(_p11##x,_p8##y,z,c), I[102] = (T)(img)(_p10##x,_p8##y,z,c), I[103] = (T)(img)(_p9##x,_p8##y,z,c), I[104] = (T)(img)(_p8##x,_p8##y,z,c), I[105] = (T)(img)(_p7##x,_p8##y,z,c), I[106] = (T)(img)(_p6##x,_p8##y,z,c), I[107] = (T)(img)(_p5##x,_p8##y,z,c), I[108] = (T)(img)(_p4##x,_p8##y,z,c), I[109] = (T)(img)(_p3##x,_p8##y,z,c), I[110] = (T)(img)(_p2##x,_p8##y,z,c), I[111] = (T)(img)(_p1##x,_p8##y,z,c), I[112] = (T)(img)(x,_p8##y,z,c), I[113] = (T)(img)(_n1##x,_p8##y,z,c), I[114] = (T)(img)(_n2##x,_p8##y,z,c), I[115] = (T)(img)(_n3##x,_p8##y,z,c), I[116] = (T)(img)(_n4##x,_p8##y,z,c), I[117] = (T)(img)(_n5##x,_p8##y,z,c), I[118] = (T)(img)(_n6##x,_p8##y,z,c), I[119] = (T)(img)(_n7##x,_p8##y,z,c), I[120] = (T)(img)(_n8##x,_p8##y,z,c), I[121] = (T)(img)(_n9##x,_p8##y,z,c), I[122] = (T)(img)(_n10##x,_p8##y,z,c), I[123] = (T)(img)(_n11##x,_p8##y,z,c), I[124] = (T)(img)(_n12##x,_p8##y,z,c), \ - I[125] = (T)(img)(_p12##x,_p7##y,z,c), I[126] = (T)(img)(_p11##x,_p7##y,z,c), I[127] = (T)(img)(_p10##x,_p7##y,z,c), I[128] = (T)(img)(_p9##x,_p7##y,z,c), I[129] = (T)(img)(_p8##x,_p7##y,z,c), I[130] = (T)(img)(_p7##x,_p7##y,z,c), I[131] = (T)(img)(_p6##x,_p7##y,z,c), I[132] = (T)(img)(_p5##x,_p7##y,z,c), I[133] = (T)(img)(_p4##x,_p7##y,z,c), I[134] = (T)(img)(_p3##x,_p7##y,z,c), I[135] = (T)(img)(_p2##x,_p7##y,z,c), I[136] = (T)(img)(_p1##x,_p7##y,z,c), I[137] = (T)(img)(x,_p7##y,z,c), I[138] = (T)(img)(_n1##x,_p7##y,z,c), I[139] = (T)(img)(_n2##x,_p7##y,z,c), I[140] = (T)(img)(_n3##x,_p7##y,z,c), I[141] = (T)(img)(_n4##x,_p7##y,z,c), I[142] = (T)(img)(_n5##x,_p7##y,z,c), I[143] = (T)(img)(_n6##x,_p7##y,z,c), I[144] = (T)(img)(_n7##x,_p7##y,z,c), I[145] = (T)(img)(_n8##x,_p7##y,z,c), I[146] = (T)(img)(_n9##x,_p7##y,z,c), I[147] = (T)(img)(_n10##x,_p7##y,z,c), I[148] = (T)(img)(_n11##x,_p7##y,z,c), I[149] = (T)(img)(_n12##x,_p7##y,z,c), \ - I[150] = (T)(img)(_p12##x,_p6##y,z,c), I[151] = (T)(img)(_p11##x,_p6##y,z,c), I[152] = (T)(img)(_p10##x,_p6##y,z,c), I[153] = (T)(img)(_p9##x,_p6##y,z,c), I[154] = (T)(img)(_p8##x,_p6##y,z,c), I[155] = (T)(img)(_p7##x,_p6##y,z,c), I[156] = (T)(img)(_p6##x,_p6##y,z,c), I[157] = (T)(img)(_p5##x,_p6##y,z,c), I[158] = (T)(img)(_p4##x,_p6##y,z,c), I[159] = (T)(img)(_p3##x,_p6##y,z,c), I[160] = (T)(img)(_p2##x,_p6##y,z,c), I[161] = (T)(img)(_p1##x,_p6##y,z,c), I[162] = (T)(img)(x,_p6##y,z,c), I[163] = (T)(img)(_n1##x,_p6##y,z,c), I[164] = (T)(img)(_n2##x,_p6##y,z,c), I[165] = (T)(img)(_n3##x,_p6##y,z,c), I[166] = (T)(img)(_n4##x,_p6##y,z,c), I[167] = (T)(img)(_n5##x,_p6##y,z,c), I[168] = (T)(img)(_n6##x,_p6##y,z,c), I[169] = (T)(img)(_n7##x,_p6##y,z,c), I[170] = (T)(img)(_n8##x,_p6##y,z,c), I[171] = (T)(img)(_n9##x,_p6##y,z,c), I[172] = (T)(img)(_n10##x,_p6##y,z,c), I[173] = (T)(img)(_n11##x,_p6##y,z,c), I[174] = (T)(img)(_n12##x,_p6##y,z,c), \ - I[175] = (T)(img)(_p12##x,_p5##y,z,c), I[176] = (T)(img)(_p11##x,_p5##y,z,c), I[177] = (T)(img)(_p10##x,_p5##y,z,c), I[178] = (T)(img)(_p9##x,_p5##y,z,c), I[179] = (T)(img)(_p8##x,_p5##y,z,c), I[180] = (T)(img)(_p7##x,_p5##y,z,c), I[181] = (T)(img)(_p6##x,_p5##y,z,c), I[182] = (T)(img)(_p5##x,_p5##y,z,c), I[183] = (T)(img)(_p4##x,_p5##y,z,c), I[184] = (T)(img)(_p3##x,_p5##y,z,c), I[185] = (T)(img)(_p2##x,_p5##y,z,c), I[186] = (T)(img)(_p1##x,_p5##y,z,c), I[187] = (T)(img)(x,_p5##y,z,c), I[188] = (T)(img)(_n1##x,_p5##y,z,c), I[189] = (T)(img)(_n2##x,_p5##y,z,c), I[190] = (T)(img)(_n3##x,_p5##y,z,c), I[191] = (T)(img)(_n4##x,_p5##y,z,c), I[192] = (T)(img)(_n5##x,_p5##y,z,c), I[193] = (T)(img)(_n6##x,_p5##y,z,c), I[194] = (T)(img)(_n7##x,_p5##y,z,c), I[195] = (T)(img)(_n8##x,_p5##y,z,c), I[196] = (T)(img)(_n9##x,_p5##y,z,c), I[197] = (T)(img)(_n10##x,_p5##y,z,c), I[198] = (T)(img)(_n11##x,_p5##y,z,c), I[199] = (T)(img)(_n12##x,_p5##y,z,c), \ - I[200] = (T)(img)(_p12##x,_p4##y,z,c), I[201] = (T)(img)(_p11##x,_p4##y,z,c), I[202] = (T)(img)(_p10##x,_p4##y,z,c), I[203] = (T)(img)(_p9##x,_p4##y,z,c), I[204] = (T)(img)(_p8##x,_p4##y,z,c), I[205] = (T)(img)(_p7##x,_p4##y,z,c), I[206] = (T)(img)(_p6##x,_p4##y,z,c), I[207] = (T)(img)(_p5##x,_p4##y,z,c), I[208] = (T)(img)(_p4##x,_p4##y,z,c), I[209] = (T)(img)(_p3##x,_p4##y,z,c), I[210] = (T)(img)(_p2##x,_p4##y,z,c), I[211] = (T)(img)(_p1##x,_p4##y,z,c), I[212] = (T)(img)(x,_p4##y,z,c), I[213] = (T)(img)(_n1##x,_p4##y,z,c), I[214] = (T)(img)(_n2##x,_p4##y,z,c), I[215] = (T)(img)(_n3##x,_p4##y,z,c), I[216] = (T)(img)(_n4##x,_p4##y,z,c), I[217] = (T)(img)(_n5##x,_p4##y,z,c), I[218] = (T)(img)(_n6##x,_p4##y,z,c), I[219] = (T)(img)(_n7##x,_p4##y,z,c), I[220] = (T)(img)(_n8##x,_p4##y,z,c), I[221] = (T)(img)(_n9##x,_p4##y,z,c), I[222] = (T)(img)(_n10##x,_p4##y,z,c), I[223] = (T)(img)(_n11##x,_p4##y,z,c), I[224] = (T)(img)(_n12##x,_p4##y,z,c), \ - I[225] = (T)(img)(_p12##x,_p3##y,z,c), I[226] = (T)(img)(_p11##x,_p3##y,z,c), I[227] = (T)(img)(_p10##x,_p3##y,z,c), I[228] = (T)(img)(_p9##x,_p3##y,z,c), I[229] = (T)(img)(_p8##x,_p3##y,z,c), I[230] = (T)(img)(_p7##x,_p3##y,z,c), I[231] = (T)(img)(_p6##x,_p3##y,z,c), I[232] = (T)(img)(_p5##x,_p3##y,z,c), I[233] = (T)(img)(_p4##x,_p3##y,z,c), I[234] = (T)(img)(_p3##x,_p3##y,z,c), I[235] = (T)(img)(_p2##x,_p3##y,z,c), I[236] = (T)(img)(_p1##x,_p3##y,z,c), I[237] = (T)(img)(x,_p3##y,z,c), I[238] = (T)(img)(_n1##x,_p3##y,z,c), I[239] = (T)(img)(_n2##x,_p3##y,z,c), I[240] = (T)(img)(_n3##x,_p3##y,z,c), I[241] = (T)(img)(_n4##x,_p3##y,z,c), I[242] = (T)(img)(_n5##x,_p3##y,z,c), I[243] = (T)(img)(_n6##x,_p3##y,z,c), I[244] = (T)(img)(_n7##x,_p3##y,z,c), I[245] = (T)(img)(_n8##x,_p3##y,z,c), I[246] = (T)(img)(_n9##x,_p3##y,z,c), I[247] = (T)(img)(_n10##x,_p3##y,z,c), I[248] = (T)(img)(_n11##x,_p3##y,z,c), I[249] = (T)(img)(_n12##x,_p3##y,z,c), \ - I[250] = (T)(img)(_p12##x,_p2##y,z,c), I[251] = (T)(img)(_p11##x,_p2##y,z,c), I[252] = (T)(img)(_p10##x,_p2##y,z,c), I[253] = (T)(img)(_p9##x,_p2##y,z,c), I[254] = (T)(img)(_p8##x,_p2##y,z,c), I[255] = (T)(img)(_p7##x,_p2##y,z,c), I[256] = (T)(img)(_p6##x,_p2##y,z,c), I[257] = (T)(img)(_p5##x,_p2##y,z,c), I[258] = (T)(img)(_p4##x,_p2##y,z,c), I[259] = (T)(img)(_p3##x,_p2##y,z,c), I[260] = (T)(img)(_p2##x,_p2##y,z,c), I[261] = (T)(img)(_p1##x,_p2##y,z,c), I[262] = (T)(img)(x,_p2##y,z,c), I[263] = (T)(img)(_n1##x,_p2##y,z,c), I[264] = (T)(img)(_n2##x,_p2##y,z,c), I[265] = (T)(img)(_n3##x,_p2##y,z,c), I[266] = (T)(img)(_n4##x,_p2##y,z,c), I[267] = (T)(img)(_n5##x,_p2##y,z,c), I[268] = (T)(img)(_n6##x,_p2##y,z,c), I[269] = (T)(img)(_n7##x,_p2##y,z,c), I[270] = (T)(img)(_n8##x,_p2##y,z,c), I[271] = (T)(img)(_n9##x,_p2##y,z,c), I[272] = (T)(img)(_n10##x,_p2##y,z,c), I[273] = (T)(img)(_n11##x,_p2##y,z,c), I[274] = (T)(img)(_n12##x,_p2##y,z,c), \ - I[275] = (T)(img)(_p12##x,_p1##y,z,c), I[276] = (T)(img)(_p11##x,_p1##y,z,c), I[277] = (T)(img)(_p10##x,_p1##y,z,c), I[278] = (T)(img)(_p9##x,_p1##y,z,c), I[279] = (T)(img)(_p8##x,_p1##y,z,c), I[280] = (T)(img)(_p7##x,_p1##y,z,c), I[281] = (T)(img)(_p6##x,_p1##y,z,c), I[282] = (T)(img)(_p5##x,_p1##y,z,c), I[283] = (T)(img)(_p4##x,_p1##y,z,c), I[284] = (T)(img)(_p3##x,_p1##y,z,c), I[285] = (T)(img)(_p2##x,_p1##y,z,c), I[286] = (T)(img)(_p1##x,_p1##y,z,c), I[287] = (T)(img)(x,_p1##y,z,c), I[288] = (T)(img)(_n1##x,_p1##y,z,c), I[289] = (T)(img)(_n2##x,_p1##y,z,c), I[290] = (T)(img)(_n3##x,_p1##y,z,c), I[291] = (T)(img)(_n4##x,_p1##y,z,c), I[292] = (T)(img)(_n5##x,_p1##y,z,c), I[293] = (T)(img)(_n6##x,_p1##y,z,c), I[294] = (T)(img)(_n7##x,_p1##y,z,c), I[295] = (T)(img)(_n8##x,_p1##y,z,c), I[296] = (T)(img)(_n9##x,_p1##y,z,c), I[297] = (T)(img)(_n10##x,_p1##y,z,c), I[298] = (T)(img)(_n11##x,_p1##y,z,c), I[299] = (T)(img)(_n12##x,_p1##y,z,c), \ - I[300] = (T)(img)(_p12##x,y,z,c), I[301] = (T)(img)(_p11##x,y,z,c), I[302] = (T)(img)(_p10##x,y,z,c), I[303] = (T)(img)(_p9##x,y,z,c), I[304] = (T)(img)(_p8##x,y,z,c), I[305] = (T)(img)(_p7##x,y,z,c), I[306] = (T)(img)(_p6##x,y,z,c), I[307] = (T)(img)(_p5##x,y,z,c), I[308] = (T)(img)(_p4##x,y,z,c), I[309] = (T)(img)(_p3##x,y,z,c), I[310] = (T)(img)(_p2##x,y,z,c), I[311] = (T)(img)(_p1##x,y,z,c), I[312] = (T)(img)(x,y,z,c), I[313] = (T)(img)(_n1##x,y,z,c), I[314] = (T)(img)(_n2##x,y,z,c), I[315] = (T)(img)(_n3##x,y,z,c), I[316] = (T)(img)(_n4##x,y,z,c), I[317] = (T)(img)(_n5##x,y,z,c), I[318] = (T)(img)(_n6##x,y,z,c), I[319] = (T)(img)(_n7##x,y,z,c), I[320] = (T)(img)(_n8##x,y,z,c), I[321] = (T)(img)(_n9##x,y,z,c), I[322] = (T)(img)(_n10##x,y,z,c), I[323] = (T)(img)(_n11##x,y,z,c), I[324] = (T)(img)(_n12##x,y,z,c), \ - I[325] = (T)(img)(_p12##x,_n1##y,z,c), I[326] = (T)(img)(_p11##x,_n1##y,z,c), I[327] = (T)(img)(_p10##x,_n1##y,z,c), I[328] = (T)(img)(_p9##x,_n1##y,z,c), I[329] = (T)(img)(_p8##x,_n1##y,z,c), I[330] = (T)(img)(_p7##x,_n1##y,z,c), I[331] = (T)(img)(_p6##x,_n1##y,z,c), I[332] = (T)(img)(_p5##x,_n1##y,z,c), I[333] = (T)(img)(_p4##x,_n1##y,z,c), I[334] = (T)(img)(_p3##x,_n1##y,z,c), I[335] = (T)(img)(_p2##x,_n1##y,z,c), I[336] = (T)(img)(_p1##x,_n1##y,z,c), I[337] = (T)(img)(x,_n1##y,z,c), I[338] = (T)(img)(_n1##x,_n1##y,z,c), I[339] = (T)(img)(_n2##x,_n1##y,z,c), I[340] = (T)(img)(_n3##x,_n1##y,z,c), I[341] = (T)(img)(_n4##x,_n1##y,z,c), I[342] = (T)(img)(_n5##x,_n1##y,z,c), I[343] = (T)(img)(_n6##x,_n1##y,z,c), I[344] = (T)(img)(_n7##x,_n1##y,z,c), I[345] = (T)(img)(_n8##x,_n1##y,z,c), I[346] = (T)(img)(_n9##x,_n1##y,z,c), I[347] = (T)(img)(_n10##x,_n1##y,z,c), I[348] = (T)(img)(_n11##x,_n1##y,z,c), I[349] = (T)(img)(_n12##x,_n1##y,z,c), \ - I[350] = (T)(img)(_p12##x,_n2##y,z,c), I[351] = (T)(img)(_p11##x,_n2##y,z,c), I[352] = (T)(img)(_p10##x,_n2##y,z,c), I[353] = (T)(img)(_p9##x,_n2##y,z,c), I[354] = (T)(img)(_p8##x,_n2##y,z,c), I[355] = (T)(img)(_p7##x,_n2##y,z,c), I[356] = (T)(img)(_p6##x,_n2##y,z,c), I[357] = (T)(img)(_p5##x,_n2##y,z,c), I[358] = (T)(img)(_p4##x,_n2##y,z,c), I[359] = (T)(img)(_p3##x,_n2##y,z,c), I[360] = (T)(img)(_p2##x,_n2##y,z,c), I[361] = (T)(img)(_p1##x,_n2##y,z,c), I[362] = (T)(img)(x,_n2##y,z,c), I[363] = (T)(img)(_n1##x,_n2##y,z,c), I[364] = (T)(img)(_n2##x,_n2##y,z,c), I[365] = (T)(img)(_n3##x,_n2##y,z,c), I[366] = (T)(img)(_n4##x,_n2##y,z,c), I[367] = (T)(img)(_n5##x,_n2##y,z,c), I[368] = (T)(img)(_n6##x,_n2##y,z,c), I[369] = (T)(img)(_n7##x,_n2##y,z,c), I[370] = (T)(img)(_n8##x,_n2##y,z,c), I[371] = (T)(img)(_n9##x,_n2##y,z,c), I[372] = (T)(img)(_n10##x,_n2##y,z,c), I[373] = (T)(img)(_n11##x,_n2##y,z,c), I[374] = (T)(img)(_n12##x,_n2##y,z,c), \ - I[375] = (T)(img)(_p12##x,_n3##y,z,c), I[376] = (T)(img)(_p11##x,_n3##y,z,c), I[377] = (T)(img)(_p10##x,_n3##y,z,c), I[378] = (T)(img)(_p9##x,_n3##y,z,c), I[379] = (T)(img)(_p8##x,_n3##y,z,c), I[380] = (T)(img)(_p7##x,_n3##y,z,c), I[381] = (T)(img)(_p6##x,_n3##y,z,c), I[382] = (T)(img)(_p5##x,_n3##y,z,c), I[383] = (T)(img)(_p4##x,_n3##y,z,c), I[384] = (T)(img)(_p3##x,_n3##y,z,c), I[385] = (T)(img)(_p2##x,_n3##y,z,c), I[386] = (T)(img)(_p1##x,_n3##y,z,c), I[387] = (T)(img)(x,_n3##y,z,c), I[388] = (T)(img)(_n1##x,_n3##y,z,c), I[389] = (T)(img)(_n2##x,_n3##y,z,c), I[390] = (T)(img)(_n3##x,_n3##y,z,c), I[391] = (T)(img)(_n4##x,_n3##y,z,c), I[392] = (T)(img)(_n5##x,_n3##y,z,c), I[393] = (T)(img)(_n6##x,_n3##y,z,c), I[394] = (T)(img)(_n7##x,_n3##y,z,c), I[395] = (T)(img)(_n8##x,_n3##y,z,c), I[396] = (T)(img)(_n9##x,_n3##y,z,c), I[397] = (T)(img)(_n10##x,_n3##y,z,c), I[398] = (T)(img)(_n11##x,_n3##y,z,c), I[399] = (T)(img)(_n12##x,_n3##y,z,c), \ - I[400] = (T)(img)(_p12##x,_n4##y,z,c), I[401] = (T)(img)(_p11##x,_n4##y,z,c), I[402] = (T)(img)(_p10##x,_n4##y,z,c), I[403] = (T)(img)(_p9##x,_n4##y,z,c), I[404] = (T)(img)(_p8##x,_n4##y,z,c), I[405] = (T)(img)(_p7##x,_n4##y,z,c), I[406] = (T)(img)(_p6##x,_n4##y,z,c), I[407] = (T)(img)(_p5##x,_n4##y,z,c), I[408] = (T)(img)(_p4##x,_n4##y,z,c), I[409] = (T)(img)(_p3##x,_n4##y,z,c), I[410] = (T)(img)(_p2##x,_n4##y,z,c), I[411] = (T)(img)(_p1##x,_n4##y,z,c), I[412] = (T)(img)(x,_n4##y,z,c), I[413] = (T)(img)(_n1##x,_n4##y,z,c), I[414] = (T)(img)(_n2##x,_n4##y,z,c), I[415] = (T)(img)(_n3##x,_n4##y,z,c), I[416] = (T)(img)(_n4##x,_n4##y,z,c), I[417] = (T)(img)(_n5##x,_n4##y,z,c), I[418] = (T)(img)(_n6##x,_n4##y,z,c), I[419] = (T)(img)(_n7##x,_n4##y,z,c), I[420] = (T)(img)(_n8##x,_n4##y,z,c), I[421] = (T)(img)(_n9##x,_n4##y,z,c), I[422] = (T)(img)(_n10##x,_n4##y,z,c), I[423] = (T)(img)(_n11##x,_n4##y,z,c), I[424] = (T)(img)(_n12##x,_n4##y,z,c), \ - I[425] = (T)(img)(_p12##x,_n5##y,z,c), I[426] = (T)(img)(_p11##x,_n5##y,z,c), I[427] = (T)(img)(_p10##x,_n5##y,z,c), I[428] = (T)(img)(_p9##x,_n5##y,z,c), I[429] = (T)(img)(_p8##x,_n5##y,z,c), I[430] = (T)(img)(_p7##x,_n5##y,z,c), I[431] = (T)(img)(_p6##x,_n5##y,z,c), I[432] = (T)(img)(_p5##x,_n5##y,z,c), I[433] = (T)(img)(_p4##x,_n5##y,z,c), I[434] = (T)(img)(_p3##x,_n5##y,z,c), I[435] = (T)(img)(_p2##x,_n5##y,z,c), I[436] = (T)(img)(_p1##x,_n5##y,z,c), I[437] = (T)(img)(x,_n5##y,z,c), I[438] = (T)(img)(_n1##x,_n5##y,z,c), I[439] = (T)(img)(_n2##x,_n5##y,z,c), I[440] = (T)(img)(_n3##x,_n5##y,z,c), I[441] = (T)(img)(_n4##x,_n5##y,z,c), I[442] = (T)(img)(_n5##x,_n5##y,z,c), I[443] = (T)(img)(_n6##x,_n5##y,z,c), I[444] = (T)(img)(_n7##x,_n5##y,z,c), I[445] = (T)(img)(_n8##x,_n5##y,z,c), I[446] = (T)(img)(_n9##x,_n5##y,z,c), I[447] = (T)(img)(_n10##x,_n5##y,z,c), I[448] = (T)(img)(_n11##x,_n5##y,z,c), I[449] = (T)(img)(_n12##x,_n5##y,z,c), \ - I[450] = (T)(img)(_p12##x,_n6##y,z,c), I[451] = (T)(img)(_p11##x,_n6##y,z,c), I[452] = (T)(img)(_p10##x,_n6##y,z,c), I[453] = (T)(img)(_p9##x,_n6##y,z,c), I[454] = (T)(img)(_p8##x,_n6##y,z,c), I[455] = (T)(img)(_p7##x,_n6##y,z,c), I[456] = (T)(img)(_p6##x,_n6##y,z,c), I[457] = (T)(img)(_p5##x,_n6##y,z,c), I[458] = (T)(img)(_p4##x,_n6##y,z,c), I[459] = (T)(img)(_p3##x,_n6##y,z,c), I[460] = (T)(img)(_p2##x,_n6##y,z,c), I[461] = (T)(img)(_p1##x,_n6##y,z,c), I[462] = (T)(img)(x,_n6##y,z,c), I[463] = (T)(img)(_n1##x,_n6##y,z,c), I[464] = (T)(img)(_n2##x,_n6##y,z,c), I[465] = (T)(img)(_n3##x,_n6##y,z,c), I[466] = (T)(img)(_n4##x,_n6##y,z,c), I[467] = (T)(img)(_n5##x,_n6##y,z,c), I[468] = (T)(img)(_n6##x,_n6##y,z,c), I[469] = (T)(img)(_n7##x,_n6##y,z,c), I[470] = (T)(img)(_n8##x,_n6##y,z,c), I[471] = (T)(img)(_n9##x,_n6##y,z,c), I[472] = (T)(img)(_n10##x,_n6##y,z,c), I[473] = (T)(img)(_n11##x,_n6##y,z,c), I[474] = (T)(img)(_n12##x,_n6##y,z,c), \ - I[475] = (T)(img)(_p12##x,_n7##y,z,c), I[476] = (T)(img)(_p11##x,_n7##y,z,c), I[477] = (T)(img)(_p10##x,_n7##y,z,c), I[478] = (T)(img)(_p9##x,_n7##y,z,c), I[479] = (T)(img)(_p8##x,_n7##y,z,c), I[480] = (T)(img)(_p7##x,_n7##y,z,c), I[481] = (T)(img)(_p6##x,_n7##y,z,c), I[482] = (T)(img)(_p5##x,_n7##y,z,c), I[483] = (T)(img)(_p4##x,_n7##y,z,c), I[484] = (T)(img)(_p3##x,_n7##y,z,c), I[485] = (T)(img)(_p2##x,_n7##y,z,c), I[486] = (T)(img)(_p1##x,_n7##y,z,c), I[487] = (T)(img)(x,_n7##y,z,c), I[488] = (T)(img)(_n1##x,_n7##y,z,c), I[489] = (T)(img)(_n2##x,_n7##y,z,c), I[490] = (T)(img)(_n3##x,_n7##y,z,c), I[491] = (T)(img)(_n4##x,_n7##y,z,c), I[492] = (T)(img)(_n5##x,_n7##y,z,c), I[493] = (T)(img)(_n6##x,_n7##y,z,c), I[494] = (T)(img)(_n7##x,_n7##y,z,c), I[495] = (T)(img)(_n8##x,_n7##y,z,c), I[496] = (T)(img)(_n9##x,_n7##y,z,c), I[497] = (T)(img)(_n10##x,_n7##y,z,c), I[498] = (T)(img)(_n11##x,_n7##y,z,c), I[499] = (T)(img)(_n12##x,_n7##y,z,c), \ - I[500] = (T)(img)(_p12##x,_n8##y,z,c), I[501] = (T)(img)(_p11##x,_n8##y,z,c), I[502] = (T)(img)(_p10##x,_n8##y,z,c), I[503] = (T)(img)(_p9##x,_n8##y,z,c), I[504] = (T)(img)(_p8##x,_n8##y,z,c), I[505] = (T)(img)(_p7##x,_n8##y,z,c), I[506] = (T)(img)(_p6##x,_n8##y,z,c), I[507] = (T)(img)(_p5##x,_n8##y,z,c), I[508] = (T)(img)(_p4##x,_n8##y,z,c), I[509] = (T)(img)(_p3##x,_n8##y,z,c), I[510] = (T)(img)(_p2##x,_n8##y,z,c), I[511] = (T)(img)(_p1##x,_n8##y,z,c), I[512] = (T)(img)(x,_n8##y,z,c), I[513] = (T)(img)(_n1##x,_n8##y,z,c), I[514] = (T)(img)(_n2##x,_n8##y,z,c), I[515] = (T)(img)(_n3##x,_n8##y,z,c), I[516] = (T)(img)(_n4##x,_n8##y,z,c), I[517] = (T)(img)(_n5##x,_n8##y,z,c), I[518] = (T)(img)(_n6##x,_n8##y,z,c), I[519] = (T)(img)(_n7##x,_n8##y,z,c), I[520] = (T)(img)(_n8##x,_n8##y,z,c), I[521] = (T)(img)(_n9##x,_n8##y,z,c), I[522] = (T)(img)(_n10##x,_n8##y,z,c), I[523] = (T)(img)(_n11##x,_n8##y,z,c), I[524] = (T)(img)(_n12##x,_n8##y,z,c), \ - I[525] = (T)(img)(_p12##x,_n9##y,z,c), I[526] = (T)(img)(_p11##x,_n9##y,z,c), I[527] = (T)(img)(_p10##x,_n9##y,z,c), I[528] = (T)(img)(_p9##x,_n9##y,z,c), I[529] = (T)(img)(_p8##x,_n9##y,z,c), I[530] = (T)(img)(_p7##x,_n9##y,z,c), I[531] = (T)(img)(_p6##x,_n9##y,z,c), I[532] = (T)(img)(_p5##x,_n9##y,z,c), I[533] = (T)(img)(_p4##x,_n9##y,z,c), I[534] = (T)(img)(_p3##x,_n9##y,z,c), I[535] = (T)(img)(_p2##x,_n9##y,z,c), I[536] = (T)(img)(_p1##x,_n9##y,z,c), I[537] = (T)(img)(x,_n9##y,z,c), I[538] = (T)(img)(_n1##x,_n9##y,z,c), I[539] = (T)(img)(_n2##x,_n9##y,z,c), I[540] = (T)(img)(_n3##x,_n9##y,z,c), I[541] = (T)(img)(_n4##x,_n9##y,z,c), I[542] = (T)(img)(_n5##x,_n9##y,z,c), I[543] = (T)(img)(_n6##x,_n9##y,z,c), I[544] = (T)(img)(_n7##x,_n9##y,z,c), I[545] = (T)(img)(_n8##x,_n9##y,z,c), I[546] = (T)(img)(_n9##x,_n9##y,z,c), I[547] = (T)(img)(_n10##x,_n9##y,z,c), I[548] = (T)(img)(_n11##x,_n9##y,z,c), I[549] = (T)(img)(_n12##x,_n9##y,z,c), \ - I[550] = (T)(img)(_p12##x,_n10##y,z,c), I[551] = (T)(img)(_p11##x,_n10##y,z,c), I[552] = (T)(img)(_p10##x,_n10##y,z,c), I[553] = (T)(img)(_p9##x,_n10##y,z,c), I[554] = (T)(img)(_p8##x,_n10##y,z,c), I[555] = (T)(img)(_p7##x,_n10##y,z,c), I[556] = (T)(img)(_p6##x,_n10##y,z,c), I[557] = (T)(img)(_p5##x,_n10##y,z,c), I[558] = (T)(img)(_p4##x,_n10##y,z,c), I[559] = (T)(img)(_p3##x,_n10##y,z,c), I[560] = (T)(img)(_p2##x,_n10##y,z,c), I[561] = (T)(img)(_p1##x,_n10##y,z,c), I[562] = (T)(img)(x,_n10##y,z,c), I[563] = (T)(img)(_n1##x,_n10##y,z,c), I[564] = (T)(img)(_n2##x,_n10##y,z,c), I[565] = (T)(img)(_n3##x,_n10##y,z,c), I[566] = (T)(img)(_n4##x,_n10##y,z,c), I[567] = (T)(img)(_n5##x,_n10##y,z,c), I[568] = (T)(img)(_n6##x,_n10##y,z,c), I[569] = (T)(img)(_n7##x,_n10##y,z,c), I[570] = (T)(img)(_n8##x,_n10##y,z,c), I[571] = (T)(img)(_n9##x,_n10##y,z,c), I[572] = (T)(img)(_n10##x,_n10##y,z,c), I[573] = (T)(img)(_n11##x,_n10##y,z,c), I[574] = (T)(img)(_n12##x,_n10##y,z,c), \ - I[575] = (T)(img)(_p12##x,_n11##y,z,c), I[576] = (T)(img)(_p11##x,_n11##y,z,c), I[577] = (T)(img)(_p10##x,_n11##y,z,c), I[578] = (T)(img)(_p9##x,_n11##y,z,c), I[579] = (T)(img)(_p8##x,_n11##y,z,c), I[580] = (T)(img)(_p7##x,_n11##y,z,c), I[581] = (T)(img)(_p6##x,_n11##y,z,c), I[582] = (T)(img)(_p5##x,_n11##y,z,c), I[583] = (T)(img)(_p4##x,_n11##y,z,c), I[584] = (T)(img)(_p3##x,_n11##y,z,c), I[585] = (T)(img)(_p2##x,_n11##y,z,c), I[586] = (T)(img)(_p1##x,_n11##y,z,c), I[587] = (T)(img)(x,_n11##y,z,c), I[588] = (T)(img)(_n1##x,_n11##y,z,c), I[589] = (T)(img)(_n2##x,_n11##y,z,c), I[590] = (T)(img)(_n3##x,_n11##y,z,c), I[591] = (T)(img)(_n4##x,_n11##y,z,c), I[592] = (T)(img)(_n5##x,_n11##y,z,c), I[593] = (T)(img)(_n6##x,_n11##y,z,c), I[594] = (T)(img)(_n7##x,_n11##y,z,c), I[595] = (T)(img)(_n8##x,_n11##y,z,c), I[596] = (T)(img)(_n9##x,_n11##y,z,c), I[597] = (T)(img)(_n10##x,_n11##y,z,c), I[598] = (T)(img)(_n11##x,_n11##y,z,c), I[599] = (T)(img)(_n12##x,_n11##y,z,c), \ - I[600] = (T)(img)(_p12##x,_n12##y,z,c), I[601] = (T)(img)(_p11##x,_n12##y,z,c), I[602] = (T)(img)(_p10##x,_n12##y,z,c), I[603] = (T)(img)(_p9##x,_n12##y,z,c), I[604] = (T)(img)(_p8##x,_n12##y,z,c), I[605] = (T)(img)(_p7##x,_n12##y,z,c), I[606] = (T)(img)(_p6##x,_n12##y,z,c), I[607] = (T)(img)(_p5##x,_n12##y,z,c), I[608] = (T)(img)(_p4##x,_n12##y,z,c), I[609] = (T)(img)(_p3##x,_n12##y,z,c), I[610] = (T)(img)(_p2##x,_n12##y,z,c), I[611] = (T)(img)(_p1##x,_n12##y,z,c), I[612] = (T)(img)(x,_n12##y,z,c), I[613] = (T)(img)(_n1##x,_n12##y,z,c), I[614] = (T)(img)(_n2##x,_n12##y,z,c), I[615] = (T)(img)(_n3##x,_n12##y,z,c), I[616] = (T)(img)(_n4##x,_n12##y,z,c), I[617] = (T)(img)(_n5##x,_n12##y,z,c), I[618] = (T)(img)(_n6##x,_n12##y,z,c), I[619] = (T)(img)(_n7##x,_n12##y,z,c), I[620] = (T)(img)(_n8##x,_n12##y,z,c), I[621] = (T)(img)(_n9##x,_n12##y,z,c), I[622] = (T)(img)(_n10##x,_n12##y,z,c), I[623] = (T)(img)(_n11##x,_n12##y,z,c), I[624] = (T)(img)(_n12##x,_n12##y,z,c); - -// Define 26x26 loop macros -//------------------------- -#define cimg_for26(bound,i) for (int i = 0, \ - _p12##i = 0, _p11##i = 0, _p10##i = 0, _p9##i = 0, _p8##i = 0, _p7##i = 0, _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6, \ - _n7##i = 7>=(int)(bound)?(int)(bound) - 1:7, \ - _n8##i = 8>=(int)(bound)?(int)(bound) - 1:8, \ - _n9##i = 9>=(int)(bound)?(int)(bound) - 1:9, \ - _n10##i = 10>=(int)(bound)?(int)(bound) - 1:10, \ - _n11##i = 11>=(int)(bound)?(int)(bound) - 1:11, \ - _n12##i = 12>=(int)(bound)?(int)(bound) - 1:12, \ - _n13##i = 13>=(int)(bound)?(int)(bound) - 1:13; \ - _n13##i<(int)(bound) || _n12##i==--_n13##i || _n11##i==--_n12##i || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n13##i = _n12##i = _n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p12##i = _p11##i, _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i, ++_n12##i, ++_n13##i) - -#define cimg_for26X(img,x) cimg_for26((img)._width,x) -#define cimg_for26Y(img,y) cimg_for26((img)._height,y) -#define cimg_for26Z(img,z) cimg_for26((img)._depth,z) -#define cimg_for26C(img,c) cimg_for26((img)._spectrum,c) -#define cimg_for26XY(img,x,y) cimg_for26Y(img,y) cimg_for26X(img,x) -#define cimg_for26XZ(img,x,z) cimg_for26Z(img,z) cimg_for26X(img,x) -#define cimg_for26XC(img,x,c) cimg_for26C(img,c) cimg_for26X(img,x) -#define cimg_for26YZ(img,y,z) cimg_for26Z(img,z) cimg_for26Y(img,y) -#define cimg_for26YC(img,y,c) cimg_for26C(img,c) cimg_for26Y(img,y) -#define cimg_for26ZC(img,z,c) cimg_for26C(img,c) cimg_for26Z(img,z) -#define cimg_for26XYZ(img,x,y,z) cimg_for26Z(img,z) cimg_for26XY(img,x,y) -#define cimg_for26XZC(img,x,z,c) cimg_for26C(img,c) cimg_for26XZ(img,x,z) -#define cimg_for26YZC(img,y,z,c) cimg_for26C(img,c) cimg_for26YZ(img,y,z) -#define cimg_for26XYZC(img,x,y,z,c) cimg_for26C(img,c) cimg_for26XYZ(img,x,y,z) - -#define cimg_for_in26(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p12##i = i - 12<0?0:i - 12, \ - _p11##i = i - 11<0?0:i - 11, \ - _p10##i = i - 10<0?0:i - 10, \ - _p9##i = i - 9<0?0:i - 9, \ - _p8##i = i - 8<0?0:i - 8, \ - _p7##i = i - 7<0?0:i - 7, \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6, \ - _n7##i = i + 7>=(int)(bound)?(int)(bound) - 1:i + 7, \ - _n8##i = i + 8>=(int)(bound)?(int)(bound) - 1:i + 8, \ - _n9##i = i + 9>=(int)(bound)?(int)(bound) - 1:i + 9, \ - _n10##i = i + 10>=(int)(bound)?(int)(bound) - 1:i + 10, \ - _n11##i = i + 11>=(int)(bound)?(int)(bound) - 1:i + 11, \ - _n12##i = i + 12>=(int)(bound)?(int)(bound) - 1:i + 12, \ - _n13##i = i + 13>=(int)(bound)?(int)(bound) - 1:i + 13; \ - i<=(int)(i1) && (_n13##i<(int)(bound) || _n12##i==--_n13##i || _n11##i==--_n12##i || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n13##i = _n12##i = _n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p12##i = _p11##i, _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i, ++_n12##i, ++_n13##i) - -#define cimg_for_in26X(img,x0,x1,x) cimg_for_in26((img)._width,x0,x1,x) -#define cimg_for_in26Y(img,y0,y1,y) cimg_for_in26((img)._height,y0,y1,y) -#define cimg_for_in26Z(img,z0,z1,z) cimg_for_in26((img)._depth,z0,z1,z) -#define cimg_for_in26C(img,c0,c1,c) cimg_for_in26((img)._spectrum,c0,c1,c) -#define cimg_for_in26XY(img,x0,y0,x1,y1,x,y) cimg_for_in26Y(img,y0,y1,y) cimg_for_in26X(img,x0,x1,x) -#define cimg_for_in26XZ(img,x0,z0,x1,z1,x,z) cimg_for_in26Z(img,z0,z1,z) cimg_for_in26X(img,x0,x1,x) -#define cimg_for_in26XC(img,x0,c0,x1,c1,x,c) cimg_for_in26C(img,c0,c1,c) cimg_for_in26X(img,x0,x1,x) -#define cimg_for_in26YZ(img,y0,z0,y1,z1,y,z) cimg_for_in26Z(img,z0,z1,z) cimg_for_in26Y(img,y0,y1,y) -#define cimg_for_in26YC(img,y0,c0,y1,c1,y,c) cimg_for_in26C(img,c0,c1,c) cimg_for_in26Y(img,y0,y1,y) -#define cimg_for_in26ZC(img,z0,c0,z1,c1,z,c) cimg_for_in26C(img,c0,c1,c) cimg_for_in26Z(img,z0,z1,z) -#define cimg_for_in26XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in26Z(img,z0,z1,z) cimg_for_in26XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in26XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in26C(img,c0,c1,c) cimg_for_in26XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in26YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in26C(img,c0,c1,c) cimg_for_in26YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in26XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in26C(img,c0,c1,c) cimg_for_in26XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for26x26(img,x,y,z,c,I,T) \ - cimg_for26((img)._height,y) for (int x = 0, \ - _p12##x = 0, _p11##x = 0, _p10##x = 0, _p9##x = 0, _p8##x = 0, _p7##x = 0, _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = 6>=((img)._width)?(img).width() - 1:6, \ - _n7##x = 7>=((img)._width)?(img).width() - 1:7, \ - _n8##x = 8>=((img)._width)?(img).width() - 1:8, \ - _n9##x = 9>=((img)._width)?(img).width() - 1:9, \ - _n10##x = 10>=((img)._width)?(img).width() - 1:10, \ - _n11##x = 11>=((img)._width)?(img).width() - 1:11, \ - _n12##x = 12>=((img)._width)?(img).width() - 1:12, \ - _n13##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = I[7] = I[8] = I[9] = I[10] = I[11] = I[12] = (T)(img)(0,_p12##y,z,c)), \ - (I[26] = I[27] = I[28] = I[29] = I[30] = I[31] = I[32] = I[33] = I[34] = I[35] = I[36] = I[37] = I[38] = (T)(img)(0,_p11##y,z,c)), \ - (I[52] = I[53] = I[54] = I[55] = I[56] = I[57] = I[58] = I[59] = I[60] = I[61] = I[62] = I[63] = I[64] = (T)(img)(0,_p10##y,z,c)), \ - (I[78] = I[79] = I[80] = I[81] = I[82] = I[83] = I[84] = I[85] = I[86] = I[87] = I[88] = I[89] = I[90] = (T)(img)(0,_p9##y,z,c)), \ - (I[104] = I[105] = I[106] = I[107] = I[108] = I[109] = I[110] = I[111] = I[112] = I[113] = I[114] = I[115] = I[116] = (T)(img)(0,_p8##y,z,c)), \ - (I[130] = I[131] = I[132] = I[133] = I[134] = I[135] = I[136] = I[137] = I[138] = I[139] = I[140] = I[141] = I[142] = (T)(img)(0,_p7##y,z,c)), \ - (I[156] = I[157] = I[158] = I[159] = I[160] = I[161] = I[162] = I[163] = I[164] = I[165] = I[166] = I[167] = I[168] = (T)(img)(0,_p6##y,z,c)), \ - (I[182] = I[183] = I[184] = I[185] = I[186] = I[187] = I[188] = I[189] = I[190] = I[191] = I[192] = I[193] = I[194] = (T)(img)(0,_p5##y,z,c)), \ - (I[208] = I[209] = I[210] = I[211] = I[212] = I[213] = I[214] = I[215] = I[216] = I[217] = I[218] = I[219] = I[220] = (T)(img)(0,_p4##y,z,c)), \ - (I[234] = I[235] = I[236] = I[237] = I[238] = I[239] = I[240] = I[241] = I[242] = I[243] = I[244] = I[245] = I[246] = (T)(img)(0,_p3##y,z,c)), \ - (I[260] = I[261] = I[262] = I[263] = I[264] = I[265] = I[266] = I[267] = I[268] = I[269] = I[270] = I[271] = I[272] = (T)(img)(0,_p2##y,z,c)), \ - (I[286] = I[287] = I[288] = I[289] = I[290] = I[291] = I[292] = I[293] = I[294] = I[295] = I[296] = I[297] = I[298] = (T)(img)(0,_p1##y,z,c)), \ - (I[312] = I[313] = I[314] = I[315] = I[316] = I[317] = I[318] = I[319] = I[320] = I[321] = I[322] = I[323] = I[324] = (T)(img)(0,y,z,c)), \ - (I[338] = I[339] = I[340] = I[341] = I[342] = I[343] = I[344] = I[345] = I[346] = I[347] = I[348] = I[349] = I[350] = (T)(img)(0,_n1##y,z,c)), \ - (I[364] = I[365] = I[366] = I[367] = I[368] = I[369] = I[370] = I[371] = I[372] = I[373] = I[374] = I[375] = I[376] = (T)(img)(0,_n2##y,z,c)), \ - (I[390] = I[391] = I[392] = I[393] = I[394] = I[395] = I[396] = I[397] = I[398] = I[399] = I[400] = I[401] = I[402] = (T)(img)(0,_n3##y,z,c)), \ - (I[416] = I[417] = I[418] = I[419] = I[420] = I[421] = I[422] = I[423] = I[424] = I[425] = I[426] = I[427] = I[428] = (T)(img)(0,_n4##y,z,c)), \ - (I[442] = I[443] = I[444] = I[445] = I[446] = I[447] = I[448] = I[449] = I[450] = I[451] = I[452] = I[453] = I[454] = (T)(img)(0,_n5##y,z,c)), \ - (I[468] = I[469] = I[470] = I[471] = I[472] = I[473] = I[474] = I[475] = I[476] = I[477] = I[478] = I[479] = I[480] = (T)(img)(0,_n6##y,z,c)), \ - (I[494] = I[495] = I[496] = I[497] = I[498] = I[499] = I[500] = I[501] = I[502] = I[503] = I[504] = I[505] = I[506] = (T)(img)(0,_n7##y,z,c)), \ - (I[520] = I[521] = I[522] = I[523] = I[524] = I[525] = I[526] = I[527] = I[528] = I[529] = I[530] = I[531] = I[532] = (T)(img)(0,_n8##y,z,c)), \ - (I[546] = I[547] = I[548] = I[549] = I[550] = I[551] = I[552] = I[553] = I[554] = I[555] = I[556] = I[557] = I[558] = (T)(img)(0,_n9##y,z,c)), \ - (I[572] = I[573] = I[574] = I[575] = I[576] = I[577] = I[578] = I[579] = I[580] = I[581] = I[582] = I[583] = I[584] = (T)(img)(0,_n10##y,z,c)), \ - (I[598] = I[599] = I[600] = I[601] = I[602] = I[603] = I[604] = I[605] = I[606] = I[607] = I[608] = I[609] = I[610] = (T)(img)(0,_n11##y,z,c)), \ - (I[624] = I[625] = I[626] = I[627] = I[628] = I[629] = I[630] = I[631] = I[632] = I[633] = I[634] = I[635] = I[636] = (T)(img)(0,_n12##y,z,c)), \ - (I[650] = I[651] = I[652] = I[653] = I[654] = I[655] = I[656] = I[657] = I[658] = I[659] = I[660] = I[661] = I[662] = (T)(img)(0,_n13##y,z,c)), \ - (I[13] = (T)(img)(_n1##x,_p12##y,z,c)), \ - (I[39] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[65] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[91] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[117] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[143] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[169] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[195] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[221] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[247] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[273] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[299] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[325] = (T)(img)(_n1##x,y,z,c)), \ - (I[351] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[377] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[403] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[429] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[455] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[481] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[507] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[533] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[559] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[585] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[611] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[637] = (T)(img)(_n1##x,_n12##y,z,c)), \ - (I[663] = (T)(img)(_n1##x,_n13##y,z,c)), \ - (I[14] = (T)(img)(_n2##x,_p12##y,z,c)), \ - (I[40] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[66] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[92] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[118] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[144] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[170] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[196] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[222] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[248] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[274] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[300] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[326] = (T)(img)(_n2##x,y,z,c)), \ - (I[352] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[378] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[404] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[430] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[456] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[482] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[508] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[534] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[560] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[586] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[612] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[638] = (T)(img)(_n2##x,_n12##y,z,c)), \ - (I[664] = (T)(img)(_n2##x,_n13##y,z,c)), \ - (I[15] = (T)(img)(_n3##x,_p12##y,z,c)), \ - (I[41] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[67] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[93] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[119] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[145] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[171] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[197] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[223] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[249] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[275] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[301] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[327] = (T)(img)(_n3##x,y,z,c)), \ - (I[353] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[379] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[405] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[431] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[457] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[483] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[509] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[535] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[561] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[587] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[613] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[639] = (T)(img)(_n3##x,_n12##y,z,c)), \ - (I[665] = (T)(img)(_n3##x,_n13##y,z,c)), \ - (I[16] = (T)(img)(_n4##x,_p12##y,z,c)), \ - (I[42] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[68] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[94] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[120] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[146] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[172] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[198] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[224] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[250] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[276] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[302] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[328] = (T)(img)(_n4##x,y,z,c)), \ - (I[354] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[380] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[406] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[432] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[458] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[484] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[510] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[536] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[562] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[588] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[614] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[640] = (T)(img)(_n4##x,_n12##y,z,c)), \ - (I[666] = (T)(img)(_n4##x,_n13##y,z,c)), \ - (I[17] = (T)(img)(_n5##x,_p12##y,z,c)), \ - (I[43] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[69] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[95] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[121] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[147] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[173] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[199] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[225] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[251] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[277] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[303] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[329] = (T)(img)(_n5##x,y,z,c)), \ - (I[355] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[381] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[407] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[433] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[459] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[485] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[511] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[537] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[563] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[589] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[615] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[641] = (T)(img)(_n5##x,_n12##y,z,c)), \ - (I[667] = (T)(img)(_n5##x,_n13##y,z,c)), \ - (I[18] = (T)(img)(_n6##x,_p12##y,z,c)), \ - (I[44] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[70] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[96] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[122] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[148] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[174] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[200] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[226] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[252] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[278] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[304] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[330] = (T)(img)(_n6##x,y,z,c)), \ - (I[356] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[382] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[408] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[434] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[460] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[486] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[512] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[538] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[564] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[590] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[616] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[642] = (T)(img)(_n6##x,_n12##y,z,c)), \ - (I[668] = (T)(img)(_n6##x,_n13##y,z,c)), \ - (I[19] = (T)(img)(_n7##x,_p12##y,z,c)), \ - (I[45] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[71] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[97] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[123] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[149] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[175] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[201] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[227] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[253] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[279] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[305] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[331] = (T)(img)(_n7##x,y,z,c)), \ - (I[357] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[383] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[409] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[435] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[461] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[487] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[513] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[539] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[565] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[591] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[617] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[643] = (T)(img)(_n7##x,_n12##y,z,c)), \ - (I[669] = (T)(img)(_n7##x,_n13##y,z,c)), \ - (I[20] = (T)(img)(_n8##x,_p12##y,z,c)), \ - (I[46] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[72] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[98] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[124] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[150] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[176] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[202] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[228] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[254] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[280] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[306] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[332] = (T)(img)(_n8##x,y,z,c)), \ - (I[358] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[384] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[410] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[436] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[462] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[488] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[514] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[540] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[566] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[592] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[618] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[644] = (T)(img)(_n8##x,_n12##y,z,c)), \ - (I[670] = (T)(img)(_n8##x,_n13##y,z,c)), \ - (I[21] = (T)(img)(_n9##x,_p12##y,z,c)), \ - (I[47] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[73] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[99] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[125] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[151] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[177] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[203] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[229] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[255] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[281] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[307] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[333] = (T)(img)(_n9##x,y,z,c)), \ - (I[359] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[385] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[411] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[437] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[463] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[489] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[515] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[541] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[567] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[593] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[619] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[645] = (T)(img)(_n9##x,_n12##y,z,c)), \ - (I[671] = (T)(img)(_n9##x,_n13##y,z,c)), \ - (I[22] = (T)(img)(_n10##x,_p12##y,z,c)), \ - (I[48] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[74] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[100] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[126] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[152] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[178] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[204] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[230] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[256] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[282] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[308] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[334] = (T)(img)(_n10##x,y,z,c)), \ - (I[360] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[386] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[412] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[438] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[464] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[490] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[516] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[542] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[568] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[594] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[620] = (T)(img)(_n10##x,_n11##y,z,c)), \ - (I[646] = (T)(img)(_n10##x,_n12##y,z,c)), \ - (I[672] = (T)(img)(_n10##x,_n13##y,z,c)), \ - (I[23] = (T)(img)(_n11##x,_p12##y,z,c)), \ - (I[49] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[75] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[101] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[127] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[153] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[179] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[205] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[231] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[257] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[283] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[309] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[335] = (T)(img)(_n11##x,y,z,c)), \ - (I[361] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[387] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[413] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[439] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[465] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[491] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[517] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[543] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[569] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[595] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[621] = (T)(img)(_n11##x,_n11##y,z,c)), \ - (I[647] = (T)(img)(_n11##x,_n12##y,z,c)), \ - (I[673] = (T)(img)(_n11##x,_n13##y,z,c)), \ - (I[24] = (T)(img)(_n12##x,_p12##y,z,c)), \ - (I[50] = (T)(img)(_n12##x,_p11##y,z,c)), \ - (I[76] = (T)(img)(_n12##x,_p10##y,z,c)), \ - (I[102] = (T)(img)(_n12##x,_p9##y,z,c)), \ - (I[128] = (T)(img)(_n12##x,_p8##y,z,c)), \ - (I[154] = (T)(img)(_n12##x,_p7##y,z,c)), \ - (I[180] = (T)(img)(_n12##x,_p6##y,z,c)), \ - (I[206] = (T)(img)(_n12##x,_p5##y,z,c)), \ - (I[232] = (T)(img)(_n12##x,_p4##y,z,c)), \ - (I[258] = (T)(img)(_n12##x,_p3##y,z,c)), \ - (I[284] = (T)(img)(_n12##x,_p2##y,z,c)), \ - (I[310] = (T)(img)(_n12##x,_p1##y,z,c)), \ - (I[336] = (T)(img)(_n12##x,y,z,c)), \ - (I[362] = (T)(img)(_n12##x,_n1##y,z,c)), \ - (I[388] = (T)(img)(_n12##x,_n2##y,z,c)), \ - (I[414] = (T)(img)(_n12##x,_n3##y,z,c)), \ - (I[440] = (T)(img)(_n12##x,_n4##y,z,c)), \ - (I[466] = (T)(img)(_n12##x,_n5##y,z,c)), \ - (I[492] = (T)(img)(_n12##x,_n6##y,z,c)), \ - (I[518] = (T)(img)(_n12##x,_n7##y,z,c)), \ - (I[544] = (T)(img)(_n12##x,_n8##y,z,c)), \ - (I[570] = (T)(img)(_n12##x,_n9##y,z,c)), \ - (I[596] = (T)(img)(_n12##x,_n10##y,z,c)), \ - (I[622] = (T)(img)(_n12##x,_n11##y,z,c)), \ - (I[648] = (T)(img)(_n12##x,_n12##y,z,c)), \ - (I[674] = (T)(img)(_n12##x,_n13##y,z,c)), \ - 13>=((img)._width)?(img).width() - 1:13); \ - (_n13##x<(img).width() && ( \ - (I[25] = (T)(img)(_n13##x,_p12##y,z,c)), \ - (I[51] = (T)(img)(_n13##x,_p11##y,z,c)), \ - (I[77] = (T)(img)(_n13##x,_p10##y,z,c)), \ - (I[103] = (T)(img)(_n13##x,_p9##y,z,c)), \ - (I[129] = (T)(img)(_n13##x,_p8##y,z,c)), \ - (I[155] = (T)(img)(_n13##x,_p7##y,z,c)), \ - (I[181] = (T)(img)(_n13##x,_p6##y,z,c)), \ - (I[207] = (T)(img)(_n13##x,_p5##y,z,c)), \ - (I[233] = (T)(img)(_n13##x,_p4##y,z,c)), \ - (I[259] = (T)(img)(_n13##x,_p3##y,z,c)), \ - (I[285] = (T)(img)(_n13##x,_p2##y,z,c)), \ - (I[311] = (T)(img)(_n13##x,_p1##y,z,c)), \ - (I[337] = (T)(img)(_n13##x,y,z,c)), \ - (I[363] = (T)(img)(_n13##x,_n1##y,z,c)), \ - (I[389] = (T)(img)(_n13##x,_n2##y,z,c)), \ - (I[415] = (T)(img)(_n13##x,_n3##y,z,c)), \ - (I[441] = (T)(img)(_n13##x,_n4##y,z,c)), \ - (I[467] = (T)(img)(_n13##x,_n5##y,z,c)), \ - (I[493] = (T)(img)(_n13##x,_n6##y,z,c)), \ - (I[519] = (T)(img)(_n13##x,_n7##y,z,c)), \ - (I[545] = (T)(img)(_n13##x,_n8##y,z,c)), \ - (I[571] = (T)(img)(_n13##x,_n9##y,z,c)), \ - (I[597] = (T)(img)(_n13##x,_n10##y,z,c)), \ - (I[623] = (T)(img)(_n13##x,_n11##y,z,c)), \ - (I[649] = (T)(img)(_n13##x,_n12##y,z,c)), \ - (I[675] = (T)(img)(_n13##x,_n13##y,z,c)),1)) || \ - _n12##x==--_n13##x || _n11##x==--_n12##x || _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n13##x = _n12##x = _n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], \ - I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], \ - I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], \ - I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], \ - I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], \ - I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], \ - I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], \ - I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], \ - I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], \ - I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], \ - I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], \ - I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], \ - I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], \ - I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], \ - I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], \ - I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], \ - I[416] = I[417], I[417] = I[418], I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], \ - I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], I[447] = I[448], I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], I[463] = I[464], I[464] = I[465], I[465] = I[466], I[466] = I[467], \ - I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], I[479] = I[480], I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], \ - I[494] = I[495], I[495] = I[496], I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], I[503] = I[504], I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], I[511] = I[512], I[512] = I[513], I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], \ - I[520] = I[521], I[521] = I[522], I[522] = I[523], I[523] = I[524], I[524] = I[525], I[525] = I[526], I[526] = I[527], I[527] = I[528], I[528] = I[529], I[529] = I[530], I[530] = I[531], I[531] = I[532], I[532] = I[533], I[533] = I[534], I[534] = I[535], I[535] = I[536], I[536] = I[537], I[537] = I[538], I[538] = I[539], I[539] = I[540], I[540] = I[541], I[541] = I[542], I[542] = I[543], I[543] = I[544], I[544] = I[545], \ - I[546] = I[547], I[547] = I[548], I[548] = I[549], I[549] = I[550], I[550] = I[551], I[551] = I[552], I[552] = I[553], I[553] = I[554], I[554] = I[555], I[555] = I[556], I[556] = I[557], I[557] = I[558], I[558] = I[559], I[559] = I[560], I[560] = I[561], I[561] = I[562], I[562] = I[563], I[563] = I[564], I[564] = I[565], I[565] = I[566], I[566] = I[567], I[567] = I[568], I[568] = I[569], I[569] = I[570], I[570] = I[571], \ - I[572] = I[573], I[573] = I[574], I[574] = I[575], I[575] = I[576], I[576] = I[577], I[577] = I[578], I[578] = I[579], I[579] = I[580], I[580] = I[581], I[581] = I[582], I[582] = I[583], I[583] = I[584], I[584] = I[585], I[585] = I[586], I[586] = I[587], I[587] = I[588], I[588] = I[589], I[589] = I[590], I[590] = I[591], I[591] = I[592], I[592] = I[593], I[593] = I[594], I[594] = I[595], I[595] = I[596], I[596] = I[597], \ - I[598] = I[599], I[599] = I[600], I[600] = I[601], I[601] = I[602], I[602] = I[603], I[603] = I[604], I[604] = I[605], I[605] = I[606], I[606] = I[607], I[607] = I[608], I[608] = I[609], I[609] = I[610], I[610] = I[611], I[611] = I[612], I[612] = I[613], I[613] = I[614], I[614] = I[615], I[615] = I[616], I[616] = I[617], I[617] = I[618], I[618] = I[619], I[619] = I[620], I[620] = I[621], I[621] = I[622], I[622] = I[623], \ - I[624] = I[625], I[625] = I[626], I[626] = I[627], I[627] = I[628], I[628] = I[629], I[629] = I[630], I[630] = I[631], I[631] = I[632], I[632] = I[633], I[633] = I[634], I[634] = I[635], I[635] = I[636], I[636] = I[637], I[637] = I[638], I[638] = I[639], I[639] = I[640], I[640] = I[641], I[641] = I[642], I[642] = I[643], I[643] = I[644], I[644] = I[645], I[645] = I[646], I[646] = I[647], I[647] = I[648], I[648] = I[649], \ - I[650] = I[651], I[651] = I[652], I[652] = I[653], I[653] = I[654], I[654] = I[655], I[655] = I[656], I[656] = I[657], I[657] = I[658], I[658] = I[659], I[659] = I[660], I[660] = I[661], I[661] = I[662], I[662] = I[663], I[663] = I[664], I[664] = I[665], I[665] = I[666], I[666] = I[667], I[667] = I[668], I[668] = I[669], I[669] = I[670], I[670] = I[671], I[671] = I[672], I[672] = I[673], I[673] = I[674], I[674] = I[675], \ - _p12##x = _p11##x, _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x, ++_n12##x, ++_n13##x) - -#define cimg_for_in26x26(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in26((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p12##x = x - 12<0?0:x - 12, \ - _p11##x = x - 11<0?0:x - 11, \ - _p10##x = x - 10<0?0:x - 10, \ - _p9##x = x - 9<0?0:x - 9, \ - _p8##x = x - 8<0?0:x - 8, \ - _p7##x = x - 7<0?0:x - 7, \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = x + 6>=(img).width()?(img).width() - 1:x + 6, \ - _n7##x = x + 7>=(img).width()?(img).width() - 1:x + 7, \ - _n8##x = x + 8>=(img).width()?(img).width() - 1:x + 8, \ - _n9##x = x + 9>=(img).width()?(img).width() - 1:x + 9, \ - _n10##x = x + 10>=(img).width()?(img).width() - 1:x + 10, \ - _n11##x = x + 11>=(img).width()?(img).width() - 1:x + 11, \ - _n12##x = x + 12>=(img).width()?(img).width() - 1:x + 12, \ - _n13##x = (int)( \ - (I[0] = (T)(img)(_p12##x,_p12##y,z,c)), \ - (I[26] = (T)(img)(_p12##x,_p11##y,z,c)), \ - (I[52] = (T)(img)(_p12##x,_p10##y,z,c)), \ - (I[78] = (T)(img)(_p12##x,_p9##y,z,c)), \ - (I[104] = (T)(img)(_p12##x,_p8##y,z,c)), \ - (I[130] = (T)(img)(_p12##x,_p7##y,z,c)), \ - (I[156] = (T)(img)(_p12##x,_p6##y,z,c)), \ - (I[182] = (T)(img)(_p12##x,_p5##y,z,c)), \ - (I[208] = (T)(img)(_p12##x,_p4##y,z,c)), \ - (I[234] = (T)(img)(_p12##x,_p3##y,z,c)), \ - (I[260] = (T)(img)(_p12##x,_p2##y,z,c)), \ - (I[286] = (T)(img)(_p12##x,_p1##y,z,c)), \ - (I[312] = (T)(img)(_p12##x,y,z,c)), \ - (I[338] = (T)(img)(_p12##x,_n1##y,z,c)), \ - (I[364] = (T)(img)(_p12##x,_n2##y,z,c)), \ - (I[390] = (T)(img)(_p12##x,_n3##y,z,c)), \ - (I[416] = (T)(img)(_p12##x,_n4##y,z,c)), \ - (I[442] = (T)(img)(_p12##x,_n5##y,z,c)), \ - (I[468] = (T)(img)(_p12##x,_n6##y,z,c)), \ - (I[494] = (T)(img)(_p12##x,_n7##y,z,c)), \ - (I[520] = (T)(img)(_p12##x,_n8##y,z,c)), \ - (I[546] = (T)(img)(_p12##x,_n9##y,z,c)), \ - (I[572] = (T)(img)(_p12##x,_n10##y,z,c)), \ - (I[598] = (T)(img)(_p12##x,_n11##y,z,c)), \ - (I[624] = (T)(img)(_p12##x,_n12##y,z,c)), \ - (I[650] = (T)(img)(_p12##x,_n13##y,z,c)), \ - (I[1] = (T)(img)(_p11##x,_p12##y,z,c)), \ - (I[27] = (T)(img)(_p11##x,_p11##y,z,c)), \ - (I[53] = (T)(img)(_p11##x,_p10##y,z,c)), \ - (I[79] = (T)(img)(_p11##x,_p9##y,z,c)), \ - (I[105] = (T)(img)(_p11##x,_p8##y,z,c)), \ - (I[131] = (T)(img)(_p11##x,_p7##y,z,c)), \ - (I[157] = (T)(img)(_p11##x,_p6##y,z,c)), \ - (I[183] = (T)(img)(_p11##x,_p5##y,z,c)), \ - (I[209] = (T)(img)(_p11##x,_p4##y,z,c)), \ - (I[235] = (T)(img)(_p11##x,_p3##y,z,c)), \ - (I[261] = (T)(img)(_p11##x,_p2##y,z,c)), \ - (I[287] = (T)(img)(_p11##x,_p1##y,z,c)), \ - (I[313] = (T)(img)(_p11##x,y,z,c)), \ - (I[339] = (T)(img)(_p11##x,_n1##y,z,c)), \ - (I[365] = (T)(img)(_p11##x,_n2##y,z,c)), \ - (I[391] = (T)(img)(_p11##x,_n3##y,z,c)), \ - (I[417] = (T)(img)(_p11##x,_n4##y,z,c)), \ - (I[443] = (T)(img)(_p11##x,_n5##y,z,c)), \ - (I[469] = (T)(img)(_p11##x,_n6##y,z,c)), \ - (I[495] = (T)(img)(_p11##x,_n7##y,z,c)), \ - (I[521] = (T)(img)(_p11##x,_n8##y,z,c)), \ - (I[547] = (T)(img)(_p11##x,_n9##y,z,c)), \ - (I[573] = (T)(img)(_p11##x,_n10##y,z,c)), \ - (I[599] = (T)(img)(_p11##x,_n11##y,z,c)), \ - (I[625] = (T)(img)(_p11##x,_n12##y,z,c)), \ - (I[651] = (T)(img)(_p11##x,_n13##y,z,c)), \ - (I[2] = (T)(img)(_p10##x,_p12##y,z,c)), \ - (I[28] = (T)(img)(_p10##x,_p11##y,z,c)), \ - (I[54] = (T)(img)(_p10##x,_p10##y,z,c)), \ - (I[80] = (T)(img)(_p10##x,_p9##y,z,c)), \ - (I[106] = (T)(img)(_p10##x,_p8##y,z,c)), \ - (I[132] = (T)(img)(_p10##x,_p7##y,z,c)), \ - (I[158] = (T)(img)(_p10##x,_p6##y,z,c)), \ - (I[184] = (T)(img)(_p10##x,_p5##y,z,c)), \ - (I[210] = (T)(img)(_p10##x,_p4##y,z,c)), \ - (I[236] = (T)(img)(_p10##x,_p3##y,z,c)), \ - (I[262] = (T)(img)(_p10##x,_p2##y,z,c)), \ - (I[288] = (T)(img)(_p10##x,_p1##y,z,c)), \ - (I[314] = (T)(img)(_p10##x,y,z,c)), \ - (I[340] = (T)(img)(_p10##x,_n1##y,z,c)), \ - (I[366] = (T)(img)(_p10##x,_n2##y,z,c)), \ - (I[392] = (T)(img)(_p10##x,_n3##y,z,c)), \ - (I[418] = (T)(img)(_p10##x,_n4##y,z,c)), \ - (I[444] = (T)(img)(_p10##x,_n5##y,z,c)), \ - (I[470] = (T)(img)(_p10##x,_n6##y,z,c)), \ - (I[496] = (T)(img)(_p10##x,_n7##y,z,c)), \ - (I[522] = (T)(img)(_p10##x,_n8##y,z,c)), \ - (I[548] = (T)(img)(_p10##x,_n9##y,z,c)), \ - (I[574] = (T)(img)(_p10##x,_n10##y,z,c)), \ - (I[600] = (T)(img)(_p10##x,_n11##y,z,c)), \ - (I[626] = (T)(img)(_p10##x,_n12##y,z,c)), \ - (I[652] = (T)(img)(_p10##x,_n13##y,z,c)), \ - (I[3] = (T)(img)(_p9##x,_p12##y,z,c)), \ - (I[29] = (T)(img)(_p9##x,_p11##y,z,c)), \ - (I[55] = (T)(img)(_p9##x,_p10##y,z,c)), \ - (I[81] = (T)(img)(_p9##x,_p9##y,z,c)), \ - (I[107] = (T)(img)(_p9##x,_p8##y,z,c)), \ - (I[133] = (T)(img)(_p9##x,_p7##y,z,c)), \ - (I[159] = (T)(img)(_p9##x,_p6##y,z,c)), \ - (I[185] = (T)(img)(_p9##x,_p5##y,z,c)), \ - (I[211] = (T)(img)(_p9##x,_p4##y,z,c)), \ - (I[237] = (T)(img)(_p9##x,_p3##y,z,c)), \ - (I[263] = (T)(img)(_p9##x,_p2##y,z,c)), \ - (I[289] = (T)(img)(_p9##x,_p1##y,z,c)), \ - (I[315] = (T)(img)(_p9##x,y,z,c)), \ - (I[341] = (T)(img)(_p9##x,_n1##y,z,c)), \ - (I[367] = (T)(img)(_p9##x,_n2##y,z,c)), \ - (I[393] = (T)(img)(_p9##x,_n3##y,z,c)), \ - (I[419] = (T)(img)(_p9##x,_n4##y,z,c)), \ - (I[445] = (T)(img)(_p9##x,_n5##y,z,c)), \ - (I[471] = (T)(img)(_p9##x,_n6##y,z,c)), \ - (I[497] = (T)(img)(_p9##x,_n7##y,z,c)), \ - (I[523] = (T)(img)(_p9##x,_n8##y,z,c)), \ - (I[549] = (T)(img)(_p9##x,_n9##y,z,c)), \ - (I[575] = (T)(img)(_p9##x,_n10##y,z,c)), \ - (I[601] = (T)(img)(_p9##x,_n11##y,z,c)), \ - (I[627] = (T)(img)(_p9##x,_n12##y,z,c)), \ - (I[653] = (T)(img)(_p9##x,_n13##y,z,c)), \ - (I[4] = (T)(img)(_p8##x,_p12##y,z,c)), \ - (I[30] = (T)(img)(_p8##x,_p11##y,z,c)), \ - (I[56] = (T)(img)(_p8##x,_p10##y,z,c)), \ - (I[82] = (T)(img)(_p8##x,_p9##y,z,c)), \ - (I[108] = (T)(img)(_p8##x,_p8##y,z,c)), \ - (I[134] = (T)(img)(_p8##x,_p7##y,z,c)), \ - (I[160] = (T)(img)(_p8##x,_p6##y,z,c)), \ - (I[186] = (T)(img)(_p8##x,_p5##y,z,c)), \ - (I[212] = (T)(img)(_p8##x,_p4##y,z,c)), \ - (I[238] = (T)(img)(_p8##x,_p3##y,z,c)), \ - (I[264] = (T)(img)(_p8##x,_p2##y,z,c)), \ - (I[290] = (T)(img)(_p8##x,_p1##y,z,c)), \ - (I[316] = (T)(img)(_p8##x,y,z,c)), \ - (I[342] = (T)(img)(_p8##x,_n1##y,z,c)), \ - (I[368] = (T)(img)(_p8##x,_n2##y,z,c)), \ - (I[394] = (T)(img)(_p8##x,_n3##y,z,c)), \ - (I[420] = (T)(img)(_p8##x,_n4##y,z,c)), \ - (I[446] = (T)(img)(_p8##x,_n5##y,z,c)), \ - (I[472] = (T)(img)(_p8##x,_n6##y,z,c)), \ - (I[498] = (T)(img)(_p8##x,_n7##y,z,c)), \ - (I[524] = (T)(img)(_p8##x,_n8##y,z,c)), \ - (I[550] = (T)(img)(_p8##x,_n9##y,z,c)), \ - (I[576] = (T)(img)(_p8##x,_n10##y,z,c)), \ - (I[602] = (T)(img)(_p8##x,_n11##y,z,c)), \ - (I[628] = (T)(img)(_p8##x,_n12##y,z,c)), \ - (I[654] = (T)(img)(_p8##x,_n13##y,z,c)), \ - (I[5] = (T)(img)(_p7##x,_p12##y,z,c)), \ - (I[31] = (T)(img)(_p7##x,_p11##y,z,c)), \ - (I[57] = (T)(img)(_p7##x,_p10##y,z,c)), \ - (I[83] = (T)(img)(_p7##x,_p9##y,z,c)), \ - (I[109] = (T)(img)(_p7##x,_p8##y,z,c)), \ - (I[135] = (T)(img)(_p7##x,_p7##y,z,c)), \ - (I[161] = (T)(img)(_p7##x,_p6##y,z,c)), \ - (I[187] = (T)(img)(_p7##x,_p5##y,z,c)), \ - (I[213] = (T)(img)(_p7##x,_p4##y,z,c)), \ - (I[239] = (T)(img)(_p7##x,_p3##y,z,c)), \ - (I[265] = (T)(img)(_p7##x,_p2##y,z,c)), \ - (I[291] = (T)(img)(_p7##x,_p1##y,z,c)), \ - (I[317] = (T)(img)(_p7##x,y,z,c)), \ - (I[343] = (T)(img)(_p7##x,_n1##y,z,c)), \ - (I[369] = (T)(img)(_p7##x,_n2##y,z,c)), \ - (I[395] = (T)(img)(_p7##x,_n3##y,z,c)), \ - (I[421] = (T)(img)(_p7##x,_n4##y,z,c)), \ - (I[447] = (T)(img)(_p7##x,_n5##y,z,c)), \ - (I[473] = (T)(img)(_p7##x,_n6##y,z,c)), \ - (I[499] = (T)(img)(_p7##x,_n7##y,z,c)), \ - (I[525] = (T)(img)(_p7##x,_n8##y,z,c)), \ - (I[551] = (T)(img)(_p7##x,_n9##y,z,c)), \ - (I[577] = (T)(img)(_p7##x,_n10##y,z,c)), \ - (I[603] = (T)(img)(_p7##x,_n11##y,z,c)), \ - (I[629] = (T)(img)(_p7##x,_n12##y,z,c)), \ - (I[655] = (T)(img)(_p7##x,_n13##y,z,c)), \ - (I[6] = (T)(img)(_p6##x,_p12##y,z,c)), \ - (I[32] = (T)(img)(_p6##x,_p11##y,z,c)), \ - (I[58] = (T)(img)(_p6##x,_p10##y,z,c)), \ - (I[84] = (T)(img)(_p6##x,_p9##y,z,c)), \ - (I[110] = (T)(img)(_p6##x,_p8##y,z,c)), \ - (I[136] = (T)(img)(_p6##x,_p7##y,z,c)), \ - (I[162] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[188] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[214] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[240] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[266] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[292] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[318] = (T)(img)(_p6##x,y,z,c)), \ - (I[344] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[370] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[396] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[422] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[448] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[474] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[500] = (T)(img)(_p6##x,_n7##y,z,c)), \ - (I[526] = (T)(img)(_p6##x,_n8##y,z,c)), \ - (I[552] = (T)(img)(_p6##x,_n9##y,z,c)), \ - (I[578] = (T)(img)(_p6##x,_n10##y,z,c)), \ - (I[604] = (T)(img)(_p6##x,_n11##y,z,c)), \ - (I[630] = (T)(img)(_p6##x,_n12##y,z,c)), \ - (I[656] = (T)(img)(_p6##x,_n13##y,z,c)), \ - (I[7] = (T)(img)(_p5##x,_p12##y,z,c)), \ - (I[33] = (T)(img)(_p5##x,_p11##y,z,c)), \ - (I[59] = (T)(img)(_p5##x,_p10##y,z,c)), \ - (I[85] = (T)(img)(_p5##x,_p9##y,z,c)), \ - (I[111] = (T)(img)(_p5##x,_p8##y,z,c)), \ - (I[137] = (T)(img)(_p5##x,_p7##y,z,c)), \ - (I[163] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[189] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[215] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[241] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[267] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[293] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[319] = (T)(img)(_p5##x,y,z,c)), \ - (I[345] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[371] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[397] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[423] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[449] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[475] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[501] = (T)(img)(_p5##x,_n7##y,z,c)), \ - (I[527] = (T)(img)(_p5##x,_n8##y,z,c)), \ - (I[553] = (T)(img)(_p5##x,_n9##y,z,c)), \ - (I[579] = (T)(img)(_p5##x,_n10##y,z,c)), \ - (I[605] = (T)(img)(_p5##x,_n11##y,z,c)), \ - (I[631] = (T)(img)(_p5##x,_n12##y,z,c)), \ - (I[657] = (T)(img)(_p5##x,_n13##y,z,c)), \ - (I[8] = (T)(img)(_p4##x,_p12##y,z,c)), \ - (I[34] = (T)(img)(_p4##x,_p11##y,z,c)), \ - (I[60] = (T)(img)(_p4##x,_p10##y,z,c)), \ - (I[86] = (T)(img)(_p4##x,_p9##y,z,c)), \ - (I[112] = (T)(img)(_p4##x,_p8##y,z,c)), \ - (I[138] = (T)(img)(_p4##x,_p7##y,z,c)), \ - (I[164] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[190] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[216] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[242] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[268] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[294] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[320] = (T)(img)(_p4##x,y,z,c)), \ - (I[346] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[372] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[398] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[424] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[450] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[476] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[502] = (T)(img)(_p4##x,_n7##y,z,c)), \ - (I[528] = (T)(img)(_p4##x,_n8##y,z,c)), \ - (I[554] = (T)(img)(_p4##x,_n9##y,z,c)), \ - (I[580] = (T)(img)(_p4##x,_n10##y,z,c)), \ - (I[606] = (T)(img)(_p4##x,_n11##y,z,c)), \ - (I[632] = (T)(img)(_p4##x,_n12##y,z,c)), \ - (I[658] = (T)(img)(_p4##x,_n13##y,z,c)), \ - (I[9] = (T)(img)(_p3##x,_p12##y,z,c)), \ - (I[35] = (T)(img)(_p3##x,_p11##y,z,c)), \ - (I[61] = (T)(img)(_p3##x,_p10##y,z,c)), \ - (I[87] = (T)(img)(_p3##x,_p9##y,z,c)), \ - (I[113] = (T)(img)(_p3##x,_p8##y,z,c)), \ - (I[139] = (T)(img)(_p3##x,_p7##y,z,c)), \ - (I[165] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[191] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[217] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[243] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[269] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[295] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[321] = (T)(img)(_p3##x,y,z,c)), \ - (I[347] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[373] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[399] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[425] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[451] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[477] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[503] = (T)(img)(_p3##x,_n7##y,z,c)), \ - (I[529] = (T)(img)(_p3##x,_n8##y,z,c)), \ - (I[555] = (T)(img)(_p3##x,_n9##y,z,c)), \ - (I[581] = (T)(img)(_p3##x,_n10##y,z,c)), \ - (I[607] = (T)(img)(_p3##x,_n11##y,z,c)), \ - (I[633] = (T)(img)(_p3##x,_n12##y,z,c)), \ - (I[659] = (T)(img)(_p3##x,_n13##y,z,c)), \ - (I[10] = (T)(img)(_p2##x,_p12##y,z,c)), \ - (I[36] = (T)(img)(_p2##x,_p11##y,z,c)), \ - (I[62] = (T)(img)(_p2##x,_p10##y,z,c)), \ - (I[88] = (T)(img)(_p2##x,_p9##y,z,c)), \ - (I[114] = (T)(img)(_p2##x,_p8##y,z,c)), \ - (I[140] = (T)(img)(_p2##x,_p7##y,z,c)), \ - (I[166] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[192] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[218] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[244] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[270] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[296] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[322] = (T)(img)(_p2##x,y,z,c)), \ - (I[348] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[374] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[400] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[426] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[452] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[478] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[504] = (T)(img)(_p2##x,_n7##y,z,c)), \ - (I[530] = (T)(img)(_p2##x,_n8##y,z,c)), \ - (I[556] = (T)(img)(_p2##x,_n9##y,z,c)), \ - (I[582] = (T)(img)(_p2##x,_n10##y,z,c)), \ - (I[608] = (T)(img)(_p2##x,_n11##y,z,c)), \ - (I[634] = (T)(img)(_p2##x,_n12##y,z,c)), \ - (I[660] = (T)(img)(_p2##x,_n13##y,z,c)), \ - (I[11] = (T)(img)(_p1##x,_p12##y,z,c)), \ - (I[37] = (T)(img)(_p1##x,_p11##y,z,c)), \ - (I[63] = (T)(img)(_p1##x,_p10##y,z,c)), \ - (I[89] = (T)(img)(_p1##x,_p9##y,z,c)), \ - (I[115] = (T)(img)(_p1##x,_p8##y,z,c)), \ - (I[141] = (T)(img)(_p1##x,_p7##y,z,c)), \ - (I[167] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[193] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[219] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[245] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[271] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[297] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[323] = (T)(img)(_p1##x,y,z,c)), \ - (I[349] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[375] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[401] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[427] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[453] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[479] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[505] = (T)(img)(_p1##x,_n7##y,z,c)), \ - (I[531] = (T)(img)(_p1##x,_n8##y,z,c)), \ - (I[557] = (T)(img)(_p1##x,_n9##y,z,c)), \ - (I[583] = (T)(img)(_p1##x,_n10##y,z,c)), \ - (I[609] = (T)(img)(_p1##x,_n11##y,z,c)), \ - (I[635] = (T)(img)(_p1##x,_n12##y,z,c)), \ - (I[661] = (T)(img)(_p1##x,_n13##y,z,c)), \ - (I[12] = (T)(img)(x,_p12##y,z,c)), \ - (I[38] = (T)(img)(x,_p11##y,z,c)), \ - (I[64] = (T)(img)(x,_p10##y,z,c)), \ - (I[90] = (T)(img)(x,_p9##y,z,c)), \ - (I[116] = (T)(img)(x,_p8##y,z,c)), \ - (I[142] = (T)(img)(x,_p7##y,z,c)), \ - (I[168] = (T)(img)(x,_p6##y,z,c)), \ - (I[194] = (T)(img)(x,_p5##y,z,c)), \ - (I[220] = (T)(img)(x,_p4##y,z,c)), \ - (I[246] = (T)(img)(x,_p3##y,z,c)), \ - (I[272] = (T)(img)(x,_p2##y,z,c)), \ - (I[298] = (T)(img)(x,_p1##y,z,c)), \ - (I[324] = (T)(img)(x,y,z,c)), \ - (I[350] = (T)(img)(x,_n1##y,z,c)), \ - (I[376] = (T)(img)(x,_n2##y,z,c)), \ - (I[402] = (T)(img)(x,_n3##y,z,c)), \ - (I[428] = (T)(img)(x,_n4##y,z,c)), \ - (I[454] = (T)(img)(x,_n5##y,z,c)), \ - (I[480] = (T)(img)(x,_n6##y,z,c)), \ - (I[506] = (T)(img)(x,_n7##y,z,c)), \ - (I[532] = (T)(img)(x,_n8##y,z,c)), \ - (I[558] = (T)(img)(x,_n9##y,z,c)), \ - (I[584] = (T)(img)(x,_n10##y,z,c)), \ - (I[610] = (T)(img)(x,_n11##y,z,c)), \ - (I[636] = (T)(img)(x,_n12##y,z,c)), \ - (I[662] = (T)(img)(x,_n13##y,z,c)), \ - (I[13] = (T)(img)(_n1##x,_p12##y,z,c)), \ - (I[39] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[65] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[91] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[117] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[143] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[169] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[195] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[221] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[247] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[273] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[299] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[325] = (T)(img)(_n1##x,y,z,c)), \ - (I[351] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[377] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[403] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[429] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[455] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[481] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[507] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[533] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[559] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[585] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[611] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[637] = (T)(img)(_n1##x,_n12##y,z,c)), \ - (I[663] = (T)(img)(_n1##x,_n13##y,z,c)), \ - (I[14] = (T)(img)(_n2##x,_p12##y,z,c)), \ - (I[40] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[66] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[92] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[118] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[144] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[170] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[196] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[222] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[248] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[274] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[300] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[326] = (T)(img)(_n2##x,y,z,c)), \ - (I[352] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[378] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[404] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[430] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[456] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[482] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[508] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[534] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[560] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[586] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[612] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[638] = (T)(img)(_n2##x,_n12##y,z,c)), \ - (I[664] = (T)(img)(_n2##x,_n13##y,z,c)), \ - (I[15] = (T)(img)(_n3##x,_p12##y,z,c)), \ - (I[41] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[67] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[93] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[119] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[145] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[171] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[197] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[223] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[249] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[275] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[301] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[327] = (T)(img)(_n3##x,y,z,c)), \ - (I[353] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[379] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[405] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[431] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[457] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[483] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[509] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[535] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[561] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[587] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[613] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[639] = (T)(img)(_n3##x,_n12##y,z,c)), \ - (I[665] = (T)(img)(_n3##x,_n13##y,z,c)), \ - (I[16] = (T)(img)(_n4##x,_p12##y,z,c)), \ - (I[42] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[68] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[94] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[120] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[146] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[172] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[198] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[224] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[250] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[276] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[302] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[328] = (T)(img)(_n4##x,y,z,c)), \ - (I[354] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[380] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[406] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[432] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[458] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[484] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[510] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[536] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[562] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[588] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[614] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[640] = (T)(img)(_n4##x,_n12##y,z,c)), \ - (I[666] = (T)(img)(_n4##x,_n13##y,z,c)), \ - (I[17] = (T)(img)(_n5##x,_p12##y,z,c)), \ - (I[43] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[69] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[95] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[121] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[147] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[173] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[199] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[225] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[251] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[277] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[303] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[329] = (T)(img)(_n5##x,y,z,c)), \ - (I[355] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[381] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[407] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[433] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[459] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[485] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[511] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[537] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[563] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[589] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[615] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[641] = (T)(img)(_n5##x,_n12##y,z,c)), \ - (I[667] = (T)(img)(_n5##x,_n13##y,z,c)), \ - (I[18] = (T)(img)(_n6##x,_p12##y,z,c)), \ - (I[44] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[70] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[96] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[122] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[148] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[174] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[200] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[226] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[252] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[278] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[304] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[330] = (T)(img)(_n6##x,y,z,c)), \ - (I[356] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[382] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[408] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[434] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[460] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[486] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[512] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[538] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[564] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[590] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[616] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[642] = (T)(img)(_n6##x,_n12##y,z,c)), \ - (I[668] = (T)(img)(_n6##x,_n13##y,z,c)), \ - (I[19] = (T)(img)(_n7##x,_p12##y,z,c)), \ - (I[45] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[71] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[97] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[123] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[149] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[175] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[201] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[227] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[253] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[279] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[305] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[331] = (T)(img)(_n7##x,y,z,c)), \ - (I[357] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[383] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[409] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[435] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[461] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[487] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[513] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[539] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[565] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[591] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[617] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[643] = (T)(img)(_n7##x,_n12##y,z,c)), \ - (I[669] = (T)(img)(_n7##x,_n13##y,z,c)), \ - (I[20] = (T)(img)(_n8##x,_p12##y,z,c)), \ - (I[46] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[72] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[98] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[124] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[150] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[176] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[202] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[228] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[254] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[280] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[306] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[332] = (T)(img)(_n8##x,y,z,c)), \ - (I[358] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[384] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[410] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[436] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[462] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[488] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[514] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[540] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[566] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[592] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[618] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[644] = (T)(img)(_n8##x,_n12##y,z,c)), \ - (I[670] = (T)(img)(_n8##x,_n13##y,z,c)), \ - (I[21] = (T)(img)(_n9##x,_p12##y,z,c)), \ - (I[47] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[73] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[99] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[125] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[151] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[177] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[203] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[229] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[255] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[281] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[307] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[333] = (T)(img)(_n9##x,y,z,c)), \ - (I[359] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[385] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[411] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[437] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[463] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[489] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[515] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[541] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[567] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[593] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[619] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[645] = (T)(img)(_n9##x,_n12##y,z,c)), \ - (I[671] = (T)(img)(_n9##x,_n13##y,z,c)), \ - (I[22] = (T)(img)(_n10##x,_p12##y,z,c)), \ - (I[48] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[74] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[100] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[126] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[152] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[178] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[204] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[230] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[256] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[282] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[308] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[334] = (T)(img)(_n10##x,y,z,c)), \ - (I[360] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[386] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[412] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[438] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[464] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[490] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[516] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[542] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[568] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[594] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[620] = (T)(img)(_n10##x,_n11##y,z,c)), \ - (I[646] = (T)(img)(_n10##x,_n12##y,z,c)), \ - (I[672] = (T)(img)(_n10##x,_n13##y,z,c)), \ - (I[23] = (T)(img)(_n11##x,_p12##y,z,c)), \ - (I[49] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[75] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[101] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[127] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[153] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[179] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[205] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[231] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[257] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[283] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[309] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[335] = (T)(img)(_n11##x,y,z,c)), \ - (I[361] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[387] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[413] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[439] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[465] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[491] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[517] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[543] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[569] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[595] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[621] = (T)(img)(_n11##x,_n11##y,z,c)), \ - (I[647] = (T)(img)(_n11##x,_n12##y,z,c)), \ - (I[673] = (T)(img)(_n11##x,_n13##y,z,c)), \ - (I[24] = (T)(img)(_n12##x,_p12##y,z,c)), \ - (I[50] = (T)(img)(_n12##x,_p11##y,z,c)), \ - (I[76] = (T)(img)(_n12##x,_p10##y,z,c)), \ - (I[102] = (T)(img)(_n12##x,_p9##y,z,c)), \ - (I[128] = (T)(img)(_n12##x,_p8##y,z,c)), \ - (I[154] = (T)(img)(_n12##x,_p7##y,z,c)), \ - (I[180] = (T)(img)(_n12##x,_p6##y,z,c)), \ - (I[206] = (T)(img)(_n12##x,_p5##y,z,c)), \ - (I[232] = (T)(img)(_n12##x,_p4##y,z,c)), \ - (I[258] = (T)(img)(_n12##x,_p3##y,z,c)), \ - (I[284] = (T)(img)(_n12##x,_p2##y,z,c)), \ - (I[310] = (T)(img)(_n12##x,_p1##y,z,c)), \ - (I[336] = (T)(img)(_n12##x,y,z,c)), \ - (I[362] = (T)(img)(_n12##x,_n1##y,z,c)), \ - (I[388] = (T)(img)(_n12##x,_n2##y,z,c)), \ - (I[414] = (T)(img)(_n12##x,_n3##y,z,c)), \ - (I[440] = (T)(img)(_n12##x,_n4##y,z,c)), \ - (I[466] = (T)(img)(_n12##x,_n5##y,z,c)), \ - (I[492] = (T)(img)(_n12##x,_n6##y,z,c)), \ - (I[518] = (T)(img)(_n12##x,_n7##y,z,c)), \ - (I[544] = (T)(img)(_n12##x,_n8##y,z,c)), \ - (I[570] = (T)(img)(_n12##x,_n9##y,z,c)), \ - (I[596] = (T)(img)(_n12##x,_n10##y,z,c)), \ - (I[622] = (T)(img)(_n12##x,_n11##y,z,c)), \ - (I[648] = (T)(img)(_n12##x,_n12##y,z,c)), \ - (I[674] = (T)(img)(_n12##x,_n13##y,z,c)), \ - x + 13>=(img).width()?(img).width() - 1:x + 13); \ - x<=(int)(x1) && ((_n13##x<(img).width() && ( \ - (I[25] = (T)(img)(_n13##x,_p12##y,z,c)), \ - (I[51] = (T)(img)(_n13##x,_p11##y,z,c)), \ - (I[77] = (T)(img)(_n13##x,_p10##y,z,c)), \ - (I[103] = (T)(img)(_n13##x,_p9##y,z,c)), \ - (I[129] = (T)(img)(_n13##x,_p8##y,z,c)), \ - (I[155] = (T)(img)(_n13##x,_p7##y,z,c)), \ - (I[181] = (T)(img)(_n13##x,_p6##y,z,c)), \ - (I[207] = (T)(img)(_n13##x,_p5##y,z,c)), \ - (I[233] = (T)(img)(_n13##x,_p4##y,z,c)), \ - (I[259] = (T)(img)(_n13##x,_p3##y,z,c)), \ - (I[285] = (T)(img)(_n13##x,_p2##y,z,c)), \ - (I[311] = (T)(img)(_n13##x,_p1##y,z,c)), \ - (I[337] = (T)(img)(_n13##x,y,z,c)), \ - (I[363] = (T)(img)(_n13##x,_n1##y,z,c)), \ - (I[389] = (T)(img)(_n13##x,_n2##y,z,c)), \ - (I[415] = (T)(img)(_n13##x,_n3##y,z,c)), \ - (I[441] = (T)(img)(_n13##x,_n4##y,z,c)), \ - (I[467] = (T)(img)(_n13##x,_n5##y,z,c)), \ - (I[493] = (T)(img)(_n13##x,_n6##y,z,c)), \ - (I[519] = (T)(img)(_n13##x,_n7##y,z,c)), \ - (I[545] = (T)(img)(_n13##x,_n8##y,z,c)), \ - (I[571] = (T)(img)(_n13##x,_n9##y,z,c)), \ - (I[597] = (T)(img)(_n13##x,_n10##y,z,c)), \ - (I[623] = (T)(img)(_n13##x,_n11##y,z,c)), \ - (I[649] = (T)(img)(_n13##x,_n12##y,z,c)), \ - (I[675] = (T)(img)(_n13##x,_n13##y,z,c)),1)) || \ - _n12##x==--_n13##x || _n11##x==--_n12##x || _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n13##x = _n12##x = _n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], \ - I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], \ - I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], \ - I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], \ - I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], \ - I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], \ - I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], \ - I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], \ - I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], \ - I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], \ - I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], \ - I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], \ - I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], \ - I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], \ - I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], \ - I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], \ - I[416] = I[417], I[417] = I[418], I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], \ - I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], I[447] = I[448], I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], I[463] = I[464], I[464] = I[465], I[465] = I[466], I[466] = I[467], \ - I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], I[479] = I[480], I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], \ - I[494] = I[495], I[495] = I[496], I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], I[503] = I[504], I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], I[511] = I[512], I[512] = I[513], I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], \ - I[520] = I[521], I[521] = I[522], I[522] = I[523], I[523] = I[524], I[524] = I[525], I[525] = I[526], I[526] = I[527], I[527] = I[528], I[528] = I[529], I[529] = I[530], I[530] = I[531], I[531] = I[532], I[532] = I[533], I[533] = I[534], I[534] = I[535], I[535] = I[536], I[536] = I[537], I[537] = I[538], I[538] = I[539], I[539] = I[540], I[540] = I[541], I[541] = I[542], I[542] = I[543], I[543] = I[544], I[544] = I[545], \ - I[546] = I[547], I[547] = I[548], I[548] = I[549], I[549] = I[550], I[550] = I[551], I[551] = I[552], I[552] = I[553], I[553] = I[554], I[554] = I[555], I[555] = I[556], I[556] = I[557], I[557] = I[558], I[558] = I[559], I[559] = I[560], I[560] = I[561], I[561] = I[562], I[562] = I[563], I[563] = I[564], I[564] = I[565], I[565] = I[566], I[566] = I[567], I[567] = I[568], I[568] = I[569], I[569] = I[570], I[570] = I[571], \ - I[572] = I[573], I[573] = I[574], I[574] = I[575], I[575] = I[576], I[576] = I[577], I[577] = I[578], I[578] = I[579], I[579] = I[580], I[580] = I[581], I[581] = I[582], I[582] = I[583], I[583] = I[584], I[584] = I[585], I[585] = I[586], I[586] = I[587], I[587] = I[588], I[588] = I[589], I[589] = I[590], I[590] = I[591], I[591] = I[592], I[592] = I[593], I[593] = I[594], I[594] = I[595], I[595] = I[596], I[596] = I[597], \ - I[598] = I[599], I[599] = I[600], I[600] = I[601], I[601] = I[602], I[602] = I[603], I[603] = I[604], I[604] = I[605], I[605] = I[606], I[606] = I[607], I[607] = I[608], I[608] = I[609], I[609] = I[610], I[610] = I[611], I[611] = I[612], I[612] = I[613], I[613] = I[614], I[614] = I[615], I[615] = I[616], I[616] = I[617], I[617] = I[618], I[618] = I[619], I[619] = I[620], I[620] = I[621], I[621] = I[622], I[622] = I[623], \ - I[624] = I[625], I[625] = I[626], I[626] = I[627], I[627] = I[628], I[628] = I[629], I[629] = I[630], I[630] = I[631], I[631] = I[632], I[632] = I[633], I[633] = I[634], I[634] = I[635], I[635] = I[636], I[636] = I[637], I[637] = I[638], I[638] = I[639], I[639] = I[640], I[640] = I[641], I[641] = I[642], I[642] = I[643], I[643] = I[644], I[644] = I[645], I[645] = I[646], I[646] = I[647], I[647] = I[648], I[648] = I[649], \ - I[650] = I[651], I[651] = I[652], I[652] = I[653], I[653] = I[654], I[654] = I[655], I[655] = I[656], I[656] = I[657], I[657] = I[658], I[658] = I[659], I[659] = I[660], I[660] = I[661], I[661] = I[662], I[662] = I[663], I[663] = I[664], I[664] = I[665], I[665] = I[666], I[666] = I[667], I[667] = I[668], I[668] = I[669], I[669] = I[670], I[670] = I[671], I[671] = I[672], I[672] = I[673], I[673] = I[674], I[674] = I[675], \ - _p12##x = _p11##x, _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x, ++_n12##x, ++_n13##x) - -#define cimg_get26x26(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p12##x,_p12##y,z,c), I[1] = (T)(img)(_p11##x,_p12##y,z,c), I[2] = (T)(img)(_p10##x,_p12##y,z,c), I[3] = (T)(img)(_p9##x,_p12##y,z,c), I[4] = (T)(img)(_p8##x,_p12##y,z,c), I[5] = (T)(img)(_p7##x,_p12##y,z,c), I[6] = (T)(img)(_p6##x,_p12##y,z,c), I[7] = (T)(img)(_p5##x,_p12##y,z,c), I[8] = (T)(img)(_p4##x,_p12##y,z,c), I[9] = (T)(img)(_p3##x,_p12##y,z,c), I[10] = (T)(img)(_p2##x,_p12##y,z,c), I[11] = (T)(img)(_p1##x,_p12##y,z,c), I[12] = (T)(img)(x,_p12##y,z,c), I[13] = (T)(img)(_n1##x,_p12##y,z,c), I[14] = (T)(img)(_n2##x,_p12##y,z,c), I[15] = (T)(img)(_n3##x,_p12##y,z,c), I[16] = (T)(img)(_n4##x,_p12##y,z,c), I[17] = (T)(img)(_n5##x,_p12##y,z,c), I[18] = (T)(img)(_n6##x,_p12##y,z,c), I[19] = (T)(img)(_n7##x,_p12##y,z,c), I[20] = (T)(img)(_n8##x,_p12##y,z,c), I[21] = (T)(img)(_n9##x,_p12##y,z,c), I[22] = (T)(img)(_n10##x,_p12##y,z,c), I[23] = (T)(img)(_n11##x,_p12##y,z,c), I[24] = (T)(img)(_n12##x,_p12##y,z,c), I[25] = (T)(img)(_n13##x,_p12##y,z,c), \ - I[26] = (T)(img)(_p12##x,_p11##y,z,c), I[27] = (T)(img)(_p11##x,_p11##y,z,c), I[28] = (T)(img)(_p10##x,_p11##y,z,c), I[29] = (T)(img)(_p9##x,_p11##y,z,c), I[30] = (T)(img)(_p8##x,_p11##y,z,c), I[31] = (T)(img)(_p7##x,_p11##y,z,c), I[32] = (T)(img)(_p6##x,_p11##y,z,c), I[33] = (T)(img)(_p5##x,_p11##y,z,c), I[34] = (T)(img)(_p4##x,_p11##y,z,c), I[35] = (T)(img)(_p3##x,_p11##y,z,c), I[36] = (T)(img)(_p2##x,_p11##y,z,c), I[37] = (T)(img)(_p1##x,_p11##y,z,c), I[38] = (T)(img)(x,_p11##y,z,c), I[39] = (T)(img)(_n1##x,_p11##y,z,c), I[40] = (T)(img)(_n2##x,_p11##y,z,c), I[41] = (T)(img)(_n3##x,_p11##y,z,c), I[42] = (T)(img)(_n4##x,_p11##y,z,c), I[43] = (T)(img)(_n5##x,_p11##y,z,c), I[44] = (T)(img)(_n6##x,_p11##y,z,c), I[45] = (T)(img)(_n7##x,_p11##y,z,c), I[46] = (T)(img)(_n8##x,_p11##y,z,c), I[47] = (T)(img)(_n9##x,_p11##y,z,c), I[48] = (T)(img)(_n10##x,_p11##y,z,c), I[49] = (T)(img)(_n11##x,_p11##y,z,c), I[50] = (T)(img)(_n12##x,_p11##y,z,c), I[51] = (T)(img)(_n13##x,_p11##y,z,c), \ - I[52] = (T)(img)(_p12##x,_p10##y,z,c), I[53] = (T)(img)(_p11##x,_p10##y,z,c), I[54] = (T)(img)(_p10##x,_p10##y,z,c), I[55] = (T)(img)(_p9##x,_p10##y,z,c), I[56] = (T)(img)(_p8##x,_p10##y,z,c), I[57] = (T)(img)(_p7##x,_p10##y,z,c), I[58] = (T)(img)(_p6##x,_p10##y,z,c), I[59] = (T)(img)(_p5##x,_p10##y,z,c), I[60] = (T)(img)(_p4##x,_p10##y,z,c), I[61] = (T)(img)(_p3##x,_p10##y,z,c), I[62] = (T)(img)(_p2##x,_p10##y,z,c), I[63] = (T)(img)(_p1##x,_p10##y,z,c), I[64] = (T)(img)(x,_p10##y,z,c), I[65] = (T)(img)(_n1##x,_p10##y,z,c), I[66] = (T)(img)(_n2##x,_p10##y,z,c), I[67] = (T)(img)(_n3##x,_p10##y,z,c), I[68] = (T)(img)(_n4##x,_p10##y,z,c), I[69] = (T)(img)(_n5##x,_p10##y,z,c), I[70] = (T)(img)(_n6##x,_p10##y,z,c), I[71] = (T)(img)(_n7##x,_p10##y,z,c), I[72] = (T)(img)(_n8##x,_p10##y,z,c), I[73] = (T)(img)(_n9##x,_p10##y,z,c), I[74] = (T)(img)(_n10##x,_p10##y,z,c), I[75] = (T)(img)(_n11##x,_p10##y,z,c), I[76] = (T)(img)(_n12##x,_p10##y,z,c), I[77] = (T)(img)(_n13##x,_p10##y,z,c), \ - I[78] = (T)(img)(_p12##x,_p9##y,z,c), I[79] = (T)(img)(_p11##x,_p9##y,z,c), I[80] = (T)(img)(_p10##x,_p9##y,z,c), I[81] = (T)(img)(_p9##x,_p9##y,z,c), I[82] = (T)(img)(_p8##x,_p9##y,z,c), I[83] = (T)(img)(_p7##x,_p9##y,z,c), I[84] = (T)(img)(_p6##x,_p9##y,z,c), I[85] = (T)(img)(_p5##x,_p9##y,z,c), I[86] = (T)(img)(_p4##x,_p9##y,z,c), I[87] = (T)(img)(_p3##x,_p9##y,z,c), I[88] = (T)(img)(_p2##x,_p9##y,z,c), I[89] = (T)(img)(_p1##x,_p9##y,z,c), I[90] = (T)(img)(x,_p9##y,z,c), I[91] = (T)(img)(_n1##x,_p9##y,z,c), I[92] = (T)(img)(_n2##x,_p9##y,z,c), I[93] = (T)(img)(_n3##x,_p9##y,z,c), I[94] = (T)(img)(_n4##x,_p9##y,z,c), I[95] = (T)(img)(_n5##x,_p9##y,z,c), I[96] = (T)(img)(_n6##x,_p9##y,z,c), I[97] = (T)(img)(_n7##x,_p9##y,z,c), I[98] = (T)(img)(_n8##x,_p9##y,z,c), I[99] = (T)(img)(_n9##x,_p9##y,z,c), I[100] = (T)(img)(_n10##x,_p9##y,z,c), I[101] = (T)(img)(_n11##x,_p9##y,z,c), I[102] = (T)(img)(_n12##x,_p9##y,z,c), I[103] = (T)(img)(_n13##x,_p9##y,z,c), \ - I[104] = (T)(img)(_p12##x,_p8##y,z,c), I[105] = (T)(img)(_p11##x,_p8##y,z,c), I[106] = (T)(img)(_p10##x,_p8##y,z,c), I[107] = (T)(img)(_p9##x,_p8##y,z,c), I[108] = (T)(img)(_p8##x,_p8##y,z,c), I[109] = (T)(img)(_p7##x,_p8##y,z,c), I[110] = (T)(img)(_p6##x,_p8##y,z,c), I[111] = (T)(img)(_p5##x,_p8##y,z,c), I[112] = (T)(img)(_p4##x,_p8##y,z,c), I[113] = (T)(img)(_p3##x,_p8##y,z,c), I[114] = (T)(img)(_p2##x,_p8##y,z,c), I[115] = (T)(img)(_p1##x,_p8##y,z,c), I[116] = (T)(img)(x,_p8##y,z,c), I[117] = (T)(img)(_n1##x,_p8##y,z,c), I[118] = (T)(img)(_n2##x,_p8##y,z,c), I[119] = (T)(img)(_n3##x,_p8##y,z,c), I[120] = (T)(img)(_n4##x,_p8##y,z,c), I[121] = (T)(img)(_n5##x,_p8##y,z,c), I[122] = (T)(img)(_n6##x,_p8##y,z,c), I[123] = (T)(img)(_n7##x,_p8##y,z,c), I[124] = (T)(img)(_n8##x,_p8##y,z,c), I[125] = (T)(img)(_n9##x,_p8##y,z,c), I[126] = (T)(img)(_n10##x,_p8##y,z,c), I[127] = (T)(img)(_n11##x,_p8##y,z,c), I[128] = (T)(img)(_n12##x,_p8##y,z,c), I[129] = (T)(img)(_n13##x,_p8##y,z,c), \ - I[130] = (T)(img)(_p12##x,_p7##y,z,c), I[131] = (T)(img)(_p11##x,_p7##y,z,c), I[132] = (T)(img)(_p10##x,_p7##y,z,c), I[133] = (T)(img)(_p9##x,_p7##y,z,c), I[134] = (T)(img)(_p8##x,_p7##y,z,c), I[135] = (T)(img)(_p7##x,_p7##y,z,c), I[136] = (T)(img)(_p6##x,_p7##y,z,c), I[137] = (T)(img)(_p5##x,_p7##y,z,c), I[138] = (T)(img)(_p4##x,_p7##y,z,c), I[139] = (T)(img)(_p3##x,_p7##y,z,c), I[140] = (T)(img)(_p2##x,_p7##y,z,c), I[141] = (T)(img)(_p1##x,_p7##y,z,c), I[142] = (T)(img)(x,_p7##y,z,c), I[143] = (T)(img)(_n1##x,_p7##y,z,c), I[144] = (T)(img)(_n2##x,_p7##y,z,c), I[145] = (T)(img)(_n3##x,_p7##y,z,c), I[146] = (T)(img)(_n4##x,_p7##y,z,c), I[147] = (T)(img)(_n5##x,_p7##y,z,c), I[148] = (T)(img)(_n6##x,_p7##y,z,c), I[149] = (T)(img)(_n7##x,_p7##y,z,c), I[150] = (T)(img)(_n8##x,_p7##y,z,c), I[151] = (T)(img)(_n9##x,_p7##y,z,c), I[152] = (T)(img)(_n10##x,_p7##y,z,c), I[153] = (T)(img)(_n11##x,_p7##y,z,c), I[154] = (T)(img)(_n12##x,_p7##y,z,c), I[155] = (T)(img)(_n13##x,_p7##y,z,c), \ - I[156] = (T)(img)(_p12##x,_p6##y,z,c), I[157] = (T)(img)(_p11##x,_p6##y,z,c), I[158] = (T)(img)(_p10##x,_p6##y,z,c), I[159] = (T)(img)(_p9##x,_p6##y,z,c), I[160] = (T)(img)(_p8##x,_p6##y,z,c), I[161] = (T)(img)(_p7##x,_p6##y,z,c), I[162] = (T)(img)(_p6##x,_p6##y,z,c), I[163] = (T)(img)(_p5##x,_p6##y,z,c), I[164] = (T)(img)(_p4##x,_p6##y,z,c), I[165] = (T)(img)(_p3##x,_p6##y,z,c), I[166] = (T)(img)(_p2##x,_p6##y,z,c), I[167] = (T)(img)(_p1##x,_p6##y,z,c), I[168] = (T)(img)(x,_p6##y,z,c), I[169] = (T)(img)(_n1##x,_p6##y,z,c), I[170] = (T)(img)(_n2##x,_p6##y,z,c), I[171] = (T)(img)(_n3##x,_p6##y,z,c), I[172] = (T)(img)(_n4##x,_p6##y,z,c), I[173] = (T)(img)(_n5##x,_p6##y,z,c), I[174] = (T)(img)(_n6##x,_p6##y,z,c), I[175] = (T)(img)(_n7##x,_p6##y,z,c), I[176] = (T)(img)(_n8##x,_p6##y,z,c), I[177] = (T)(img)(_n9##x,_p6##y,z,c), I[178] = (T)(img)(_n10##x,_p6##y,z,c), I[179] = (T)(img)(_n11##x,_p6##y,z,c), I[180] = (T)(img)(_n12##x,_p6##y,z,c), I[181] = (T)(img)(_n13##x,_p6##y,z,c), \ - I[182] = (T)(img)(_p12##x,_p5##y,z,c), I[183] = (T)(img)(_p11##x,_p5##y,z,c), I[184] = (T)(img)(_p10##x,_p5##y,z,c), I[185] = (T)(img)(_p9##x,_p5##y,z,c), I[186] = (T)(img)(_p8##x,_p5##y,z,c), I[187] = (T)(img)(_p7##x,_p5##y,z,c), I[188] = (T)(img)(_p6##x,_p5##y,z,c), I[189] = (T)(img)(_p5##x,_p5##y,z,c), I[190] = (T)(img)(_p4##x,_p5##y,z,c), I[191] = (T)(img)(_p3##x,_p5##y,z,c), I[192] = (T)(img)(_p2##x,_p5##y,z,c), I[193] = (T)(img)(_p1##x,_p5##y,z,c), I[194] = (T)(img)(x,_p5##y,z,c), I[195] = (T)(img)(_n1##x,_p5##y,z,c), I[196] = (T)(img)(_n2##x,_p5##y,z,c), I[197] = (T)(img)(_n3##x,_p5##y,z,c), I[198] = (T)(img)(_n4##x,_p5##y,z,c), I[199] = (T)(img)(_n5##x,_p5##y,z,c), I[200] = (T)(img)(_n6##x,_p5##y,z,c), I[201] = (T)(img)(_n7##x,_p5##y,z,c), I[202] = (T)(img)(_n8##x,_p5##y,z,c), I[203] = (T)(img)(_n9##x,_p5##y,z,c), I[204] = (T)(img)(_n10##x,_p5##y,z,c), I[205] = (T)(img)(_n11##x,_p5##y,z,c), I[206] = (T)(img)(_n12##x,_p5##y,z,c), I[207] = (T)(img)(_n13##x,_p5##y,z,c), \ - I[208] = (T)(img)(_p12##x,_p4##y,z,c), I[209] = (T)(img)(_p11##x,_p4##y,z,c), I[210] = (T)(img)(_p10##x,_p4##y,z,c), I[211] = (T)(img)(_p9##x,_p4##y,z,c), I[212] = (T)(img)(_p8##x,_p4##y,z,c), I[213] = (T)(img)(_p7##x,_p4##y,z,c), I[214] = (T)(img)(_p6##x,_p4##y,z,c), I[215] = (T)(img)(_p5##x,_p4##y,z,c), I[216] = (T)(img)(_p4##x,_p4##y,z,c), I[217] = (T)(img)(_p3##x,_p4##y,z,c), I[218] = (T)(img)(_p2##x,_p4##y,z,c), I[219] = (T)(img)(_p1##x,_p4##y,z,c), I[220] = (T)(img)(x,_p4##y,z,c), I[221] = (T)(img)(_n1##x,_p4##y,z,c), I[222] = (T)(img)(_n2##x,_p4##y,z,c), I[223] = (T)(img)(_n3##x,_p4##y,z,c), I[224] = (T)(img)(_n4##x,_p4##y,z,c), I[225] = (T)(img)(_n5##x,_p4##y,z,c), I[226] = (T)(img)(_n6##x,_p4##y,z,c), I[227] = (T)(img)(_n7##x,_p4##y,z,c), I[228] = (T)(img)(_n8##x,_p4##y,z,c), I[229] = (T)(img)(_n9##x,_p4##y,z,c), I[230] = (T)(img)(_n10##x,_p4##y,z,c), I[231] = (T)(img)(_n11##x,_p4##y,z,c), I[232] = (T)(img)(_n12##x,_p4##y,z,c), I[233] = (T)(img)(_n13##x,_p4##y,z,c), \ - I[234] = (T)(img)(_p12##x,_p3##y,z,c), I[235] = (T)(img)(_p11##x,_p3##y,z,c), I[236] = (T)(img)(_p10##x,_p3##y,z,c), I[237] = (T)(img)(_p9##x,_p3##y,z,c), I[238] = (T)(img)(_p8##x,_p3##y,z,c), I[239] = (T)(img)(_p7##x,_p3##y,z,c), I[240] = (T)(img)(_p6##x,_p3##y,z,c), I[241] = (T)(img)(_p5##x,_p3##y,z,c), I[242] = (T)(img)(_p4##x,_p3##y,z,c), I[243] = (T)(img)(_p3##x,_p3##y,z,c), I[244] = (T)(img)(_p2##x,_p3##y,z,c), I[245] = (T)(img)(_p1##x,_p3##y,z,c), I[246] = (T)(img)(x,_p3##y,z,c), I[247] = (T)(img)(_n1##x,_p3##y,z,c), I[248] = (T)(img)(_n2##x,_p3##y,z,c), I[249] = (T)(img)(_n3##x,_p3##y,z,c), I[250] = (T)(img)(_n4##x,_p3##y,z,c), I[251] = (T)(img)(_n5##x,_p3##y,z,c), I[252] = (T)(img)(_n6##x,_p3##y,z,c), I[253] = (T)(img)(_n7##x,_p3##y,z,c), I[254] = (T)(img)(_n8##x,_p3##y,z,c), I[255] = (T)(img)(_n9##x,_p3##y,z,c), I[256] = (T)(img)(_n10##x,_p3##y,z,c), I[257] = (T)(img)(_n11##x,_p3##y,z,c), I[258] = (T)(img)(_n12##x,_p3##y,z,c), I[259] = (T)(img)(_n13##x,_p3##y,z,c), \ - I[260] = (T)(img)(_p12##x,_p2##y,z,c), I[261] = (T)(img)(_p11##x,_p2##y,z,c), I[262] = (T)(img)(_p10##x,_p2##y,z,c), I[263] = (T)(img)(_p9##x,_p2##y,z,c), I[264] = (T)(img)(_p8##x,_p2##y,z,c), I[265] = (T)(img)(_p7##x,_p2##y,z,c), I[266] = (T)(img)(_p6##x,_p2##y,z,c), I[267] = (T)(img)(_p5##x,_p2##y,z,c), I[268] = (T)(img)(_p4##x,_p2##y,z,c), I[269] = (T)(img)(_p3##x,_p2##y,z,c), I[270] = (T)(img)(_p2##x,_p2##y,z,c), I[271] = (T)(img)(_p1##x,_p2##y,z,c), I[272] = (T)(img)(x,_p2##y,z,c), I[273] = (T)(img)(_n1##x,_p2##y,z,c), I[274] = (T)(img)(_n2##x,_p2##y,z,c), I[275] = (T)(img)(_n3##x,_p2##y,z,c), I[276] = (T)(img)(_n4##x,_p2##y,z,c), I[277] = (T)(img)(_n5##x,_p2##y,z,c), I[278] = (T)(img)(_n6##x,_p2##y,z,c), I[279] = (T)(img)(_n7##x,_p2##y,z,c), I[280] = (T)(img)(_n8##x,_p2##y,z,c), I[281] = (T)(img)(_n9##x,_p2##y,z,c), I[282] = (T)(img)(_n10##x,_p2##y,z,c), I[283] = (T)(img)(_n11##x,_p2##y,z,c), I[284] = (T)(img)(_n12##x,_p2##y,z,c), I[285] = (T)(img)(_n13##x,_p2##y,z,c), \ - I[286] = (T)(img)(_p12##x,_p1##y,z,c), I[287] = (T)(img)(_p11##x,_p1##y,z,c), I[288] = (T)(img)(_p10##x,_p1##y,z,c), I[289] = (T)(img)(_p9##x,_p1##y,z,c), I[290] = (T)(img)(_p8##x,_p1##y,z,c), I[291] = (T)(img)(_p7##x,_p1##y,z,c), I[292] = (T)(img)(_p6##x,_p1##y,z,c), I[293] = (T)(img)(_p5##x,_p1##y,z,c), I[294] = (T)(img)(_p4##x,_p1##y,z,c), I[295] = (T)(img)(_p3##x,_p1##y,z,c), I[296] = (T)(img)(_p2##x,_p1##y,z,c), I[297] = (T)(img)(_p1##x,_p1##y,z,c), I[298] = (T)(img)(x,_p1##y,z,c), I[299] = (T)(img)(_n1##x,_p1##y,z,c), I[300] = (T)(img)(_n2##x,_p1##y,z,c), I[301] = (T)(img)(_n3##x,_p1##y,z,c), I[302] = (T)(img)(_n4##x,_p1##y,z,c), I[303] = (T)(img)(_n5##x,_p1##y,z,c), I[304] = (T)(img)(_n6##x,_p1##y,z,c), I[305] = (T)(img)(_n7##x,_p1##y,z,c), I[306] = (T)(img)(_n8##x,_p1##y,z,c), I[307] = (T)(img)(_n9##x,_p1##y,z,c), I[308] = (T)(img)(_n10##x,_p1##y,z,c), I[309] = (T)(img)(_n11##x,_p1##y,z,c), I[310] = (T)(img)(_n12##x,_p1##y,z,c), I[311] = (T)(img)(_n13##x,_p1##y,z,c), \ - I[312] = (T)(img)(_p12##x,y,z,c), I[313] = (T)(img)(_p11##x,y,z,c), I[314] = (T)(img)(_p10##x,y,z,c), I[315] = (T)(img)(_p9##x,y,z,c), I[316] = (T)(img)(_p8##x,y,z,c), I[317] = (T)(img)(_p7##x,y,z,c), I[318] = (T)(img)(_p6##x,y,z,c), I[319] = (T)(img)(_p5##x,y,z,c), I[320] = (T)(img)(_p4##x,y,z,c), I[321] = (T)(img)(_p3##x,y,z,c), I[322] = (T)(img)(_p2##x,y,z,c), I[323] = (T)(img)(_p1##x,y,z,c), I[324] = (T)(img)(x,y,z,c), I[325] = (T)(img)(_n1##x,y,z,c), I[326] = (T)(img)(_n2##x,y,z,c), I[327] = (T)(img)(_n3##x,y,z,c), I[328] = (T)(img)(_n4##x,y,z,c), I[329] = (T)(img)(_n5##x,y,z,c), I[330] = (T)(img)(_n6##x,y,z,c), I[331] = (T)(img)(_n7##x,y,z,c), I[332] = (T)(img)(_n8##x,y,z,c), I[333] = (T)(img)(_n9##x,y,z,c), I[334] = (T)(img)(_n10##x,y,z,c), I[335] = (T)(img)(_n11##x,y,z,c), I[336] = (T)(img)(_n12##x,y,z,c), I[337] = (T)(img)(_n13##x,y,z,c), \ - I[338] = (T)(img)(_p12##x,_n1##y,z,c), I[339] = (T)(img)(_p11##x,_n1##y,z,c), I[340] = (T)(img)(_p10##x,_n1##y,z,c), I[341] = (T)(img)(_p9##x,_n1##y,z,c), I[342] = (T)(img)(_p8##x,_n1##y,z,c), I[343] = (T)(img)(_p7##x,_n1##y,z,c), I[344] = (T)(img)(_p6##x,_n1##y,z,c), I[345] = (T)(img)(_p5##x,_n1##y,z,c), I[346] = (T)(img)(_p4##x,_n1##y,z,c), I[347] = (T)(img)(_p3##x,_n1##y,z,c), I[348] = (T)(img)(_p2##x,_n1##y,z,c), I[349] = (T)(img)(_p1##x,_n1##y,z,c), I[350] = (T)(img)(x,_n1##y,z,c), I[351] = (T)(img)(_n1##x,_n1##y,z,c), I[352] = (T)(img)(_n2##x,_n1##y,z,c), I[353] = (T)(img)(_n3##x,_n1##y,z,c), I[354] = (T)(img)(_n4##x,_n1##y,z,c), I[355] = (T)(img)(_n5##x,_n1##y,z,c), I[356] = (T)(img)(_n6##x,_n1##y,z,c), I[357] = (T)(img)(_n7##x,_n1##y,z,c), I[358] = (T)(img)(_n8##x,_n1##y,z,c), I[359] = (T)(img)(_n9##x,_n1##y,z,c), I[360] = (T)(img)(_n10##x,_n1##y,z,c), I[361] = (T)(img)(_n11##x,_n1##y,z,c), I[362] = (T)(img)(_n12##x,_n1##y,z,c), I[363] = (T)(img)(_n13##x,_n1##y,z,c), \ - I[364] = (T)(img)(_p12##x,_n2##y,z,c), I[365] = (T)(img)(_p11##x,_n2##y,z,c), I[366] = (T)(img)(_p10##x,_n2##y,z,c), I[367] = (T)(img)(_p9##x,_n2##y,z,c), I[368] = (T)(img)(_p8##x,_n2##y,z,c), I[369] = (T)(img)(_p7##x,_n2##y,z,c), I[370] = (T)(img)(_p6##x,_n2##y,z,c), I[371] = (T)(img)(_p5##x,_n2##y,z,c), I[372] = (T)(img)(_p4##x,_n2##y,z,c), I[373] = (T)(img)(_p3##x,_n2##y,z,c), I[374] = (T)(img)(_p2##x,_n2##y,z,c), I[375] = (T)(img)(_p1##x,_n2##y,z,c), I[376] = (T)(img)(x,_n2##y,z,c), I[377] = (T)(img)(_n1##x,_n2##y,z,c), I[378] = (T)(img)(_n2##x,_n2##y,z,c), I[379] = (T)(img)(_n3##x,_n2##y,z,c), I[380] = (T)(img)(_n4##x,_n2##y,z,c), I[381] = (T)(img)(_n5##x,_n2##y,z,c), I[382] = (T)(img)(_n6##x,_n2##y,z,c), I[383] = (T)(img)(_n7##x,_n2##y,z,c), I[384] = (T)(img)(_n8##x,_n2##y,z,c), I[385] = (T)(img)(_n9##x,_n2##y,z,c), I[386] = (T)(img)(_n10##x,_n2##y,z,c), I[387] = (T)(img)(_n11##x,_n2##y,z,c), I[388] = (T)(img)(_n12##x,_n2##y,z,c), I[389] = (T)(img)(_n13##x,_n2##y,z,c), \ - I[390] = (T)(img)(_p12##x,_n3##y,z,c), I[391] = (T)(img)(_p11##x,_n3##y,z,c), I[392] = (T)(img)(_p10##x,_n3##y,z,c), I[393] = (T)(img)(_p9##x,_n3##y,z,c), I[394] = (T)(img)(_p8##x,_n3##y,z,c), I[395] = (T)(img)(_p7##x,_n3##y,z,c), I[396] = (T)(img)(_p6##x,_n3##y,z,c), I[397] = (T)(img)(_p5##x,_n3##y,z,c), I[398] = (T)(img)(_p4##x,_n3##y,z,c), I[399] = (T)(img)(_p3##x,_n3##y,z,c), I[400] = (T)(img)(_p2##x,_n3##y,z,c), I[401] = (T)(img)(_p1##x,_n3##y,z,c), I[402] = (T)(img)(x,_n3##y,z,c), I[403] = (T)(img)(_n1##x,_n3##y,z,c), I[404] = (T)(img)(_n2##x,_n3##y,z,c), I[405] = (T)(img)(_n3##x,_n3##y,z,c), I[406] = (T)(img)(_n4##x,_n3##y,z,c), I[407] = (T)(img)(_n5##x,_n3##y,z,c), I[408] = (T)(img)(_n6##x,_n3##y,z,c), I[409] = (T)(img)(_n7##x,_n3##y,z,c), I[410] = (T)(img)(_n8##x,_n3##y,z,c), I[411] = (T)(img)(_n9##x,_n3##y,z,c), I[412] = (T)(img)(_n10##x,_n3##y,z,c), I[413] = (T)(img)(_n11##x,_n3##y,z,c), I[414] = (T)(img)(_n12##x,_n3##y,z,c), I[415] = (T)(img)(_n13##x,_n3##y,z,c), \ - I[416] = (T)(img)(_p12##x,_n4##y,z,c), I[417] = (T)(img)(_p11##x,_n4##y,z,c), I[418] = (T)(img)(_p10##x,_n4##y,z,c), I[419] = (T)(img)(_p9##x,_n4##y,z,c), I[420] = (T)(img)(_p8##x,_n4##y,z,c), I[421] = (T)(img)(_p7##x,_n4##y,z,c), I[422] = (T)(img)(_p6##x,_n4##y,z,c), I[423] = (T)(img)(_p5##x,_n4##y,z,c), I[424] = (T)(img)(_p4##x,_n4##y,z,c), I[425] = (T)(img)(_p3##x,_n4##y,z,c), I[426] = (T)(img)(_p2##x,_n4##y,z,c), I[427] = (T)(img)(_p1##x,_n4##y,z,c), I[428] = (T)(img)(x,_n4##y,z,c), I[429] = (T)(img)(_n1##x,_n4##y,z,c), I[430] = (T)(img)(_n2##x,_n4##y,z,c), I[431] = (T)(img)(_n3##x,_n4##y,z,c), I[432] = (T)(img)(_n4##x,_n4##y,z,c), I[433] = (T)(img)(_n5##x,_n4##y,z,c), I[434] = (T)(img)(_n6##x,_n4##y,z,c), I[435] = (T)(img)(_n7##x,_n4##y,z,c), I[436] = (T)(img)(_n8##x,_n4##y,z,c), I[437] = (T)(img)(_n9##x,_n4##y,z,c), I[438] = (T)(img)(_n10##x,_n4##y,z,c), I[439] = (T)(img)(_n11##x,_n4##y,z,c), I[440] = (T)(img)(_n12##x,_n4##y,z,c), I[441] = (T)(img)(_n13##x,_n4##y,z,c), \ - I[442] = (T)(img)(_p12##x,_n5##y,z,c), I[443] = (T)(img)(_p11##x,_n5##y,z,c), I[444] = (T)(img)(_p10##x,_n5##y,z,c), I[445] = (T)(img)(_p9##x,_n5##y,z,c), I[446] = (T)(img)(_p8##x,_n5##y,z,c), I[447] = (T)(img)(_p7##x,_n5##y,z,c), I[448] = (T)(img)(_p6##x,_n5##y,z,c), I[449] = (T)(img)(_p5##x,_n5##y,z,c), I[450] = (T)(img)(_p4##x,_n5##y,z,c), I[451] = (T)(img)(_p3##x,_n5##y,z,c), I[452] = (T)(img)(_p2##x,_n5##y,z,c), I[453] = (T)(img)(_p1##x,_n5##y,z,c), I[454] = (T)(img)(x,_n5##y,z,c), I[455] = (T)(img)(_n1##x,_n5##y,z,c), I[456] = (T)(img)(_n2##x,_n5##y,z,c), I[457] = (T)(img)(_n3##x,_n5##y,z,c), I[458] = (T)(img)(_n4##x,_n5##y,z,c), I[459] = (T)(img)(_n5##x,_n5##y,z,c), I[460] = (T)(img)(_n6##x,_n5##y,z,c), I[461] = (T)(img)(_n7##x,_n5##y,z,c), I[462] = (T)(img)(_n8##x,_n5##y,z,c), I[463] = (T)(img)(_n9##x,_n5##y,z,c), I[464] = (T)(img)(_n10##x,_n5##y,z,c), I[465] = (T)(img)(_n11##x,_n5##y,z,c), I[466] = (T)(img)(_n12##x,_n5##y,z,c), I[467] = (T)(img)(_n13##x,_n5##y,z,c), \ - I[468] = (T)(img)(_p12##x,_n6##y,z,c), I[469] = (T)(img)(_p11##x,_n6##y,z,c), I[470] = (T)(img)(_p10##x,_n6##y,z,c), I[471] = (T)(img)(_p9##x,_n6##y,z,c), I[472] = (T)(img)(_p8##x,_n6##y,z,c), I[473] = (T)(img)(_p7##x,_n6##y,z,c), I[474] = (T)(img)(_p6##x,_n6##y,z,c), I[475] = (T)(img)(_p5##x,_n6##y,z,c), I[476] = (T)(img)(_p4##x,_n6##y,z,c), I[477] = (T)(img)(_p3##x,_n6##y,z,c), I[478] = (T)(img)(_p2##x,_n6##y,z,c), I[479] = (T)(img)(_p1##x,_n6##y,z,c), I[480] = (T)(img)(x,_n6##y,z,c), I[481] = (T)(img)(_n1##x,_n6##y,z,c), I[482] = (T)(img)(_n2##x,_n6##y,z,c), I[483] = (T)(img)(_n3##x,_n6##y,z,c), I[484] = (T)(img)(_n4##x,_n6##y,z,c), I[485] = (T)(img)(_n5##x,_n6##y,z,c), I[486] = (T)(img)(_n6##x,_n6##y,z,c), I[487] = (T)(img)(_n7##x,_n6##y,z,c), I[488] = (T)(img)(_n8##x,_n6##y,z,c), I[489] = (T)(img)(_n9##x,_n6##y,z,c), I[490] = (T)(img)(_n10##x,_n6##y,z,c), I[491] = (T)(img)(_n11##x,_n6##y,z,c), I[492] = (T)(img)(_n12##x,_n6##y,z,c), I[493] = (T)(img)(_n13##x,_n6##y,z,c), \ - I[494] = (T)(img)(_p12##x,_n7##y,z,c), I[495] = (T)(img)(_p11##x,_n7##y,z,c), I[496] = (T)(img)(_p10##x,_n7##y,z,c), I[497] = (T)(img)(_p9##x,_n7##y,z,c), I[498] = (T)(img)(_p8##x,_n7##y,z,c), I[499] = (T)(img)(_p7##x,_n7##y,z,c), I[500] = (T)(img)(_p6##x,_n7##y,z,c), I[501] = (T)(img)(_p5##x,_n7##y,z,c), I[502] = (T)(img)(_p4##x,_n7##y,z,c), I[503] = (T)(img)(_p3##x,_n7##y,z,c), I[504] = (T)(img)(_p2##x,_n7##y,z,c), I[505] = (T)(img)(_p1##x,_n7##y,z,c), I[506] = (T)(img)(x,_n7##y,z,c), I[507] = (T)(img)(_n1##x,_n7##y,z,c), I[508] = (T)(img)(_n2##x,_n7##y,z,c), I[509] = (T)(img)(_n3##x,_n7##y,z,c), I[510] = (T)(img)(_n4##x,_n7##y,z,c), I[511] = (T)(img)(_n5##x,_n7##y,z,c), I[512] = (T)(img)(_n6##x,_n7##y,z,c), I[513] = (T)(img)(_n7##x,_n7##y,z,c), I[514] = (T)(img)(_n8##x,_n7##y,z,c), I[515] = (T)(img)(_n9##x,_n7##y,z,c), I[516] = (T)(img)(_n10##x,_n7##y,z,c), I[517] = (T)(img)(_n11##x,_n7##y,z,c), I[518] = (T)(img)(_n12##x,_n7##y,z,c), I[519] = (T)(img)(_n13##x,_n7##y,z,c), \ - I[520] = (T)(img)(_p12##x,_n8##y,z,c), I[521] = (T)(img)(_p11##x,_n8##y,z,c), I[522] = (T)(img)(_p10##x,_n8##y,z,c), I[523] = (T)(img)(_p9##x,_n8##y,z,c), I[524] = (T)(img)(_p8##x,_n8##y,z,c), I[525] = (T)(img)(_p7##x,_n8##y,z,c), I[526] = (T)(img)(_p6##x,_n8##y,z,c), I[527] = (T)(img)(_p5##x,_n8##y,z,c), I[528] = (T)(img)(_p4##x,_n8##y,z,c), I[529] = (T)(img)(_p3##x,_n8##y,z,c), I[530] = (T)(img)(_p2##x,_n8##y,z,c), I[531] = (T)(img)(_p1##x,_n8##y,z,c), I[532] = (T)(img)(x,_n8##y,z,c), I[533] = (T)(img)(_n1##x,_n8##y,z,c), I[534] = (T)(img)(_n2##x,_n8##y,z,c), I[535] = (T)(img)(_n3##x,_n8##y,z,c), I[536] = (T)(img)(_n4##x,_n8##y,z,c), I[537] = (T)(img)(_n5##x,_n8##y,z,c), I[538] = (T)(img)(_n6##x,_n8##y,z,c), I[539] = (T)(img)(_n7##x,_n8##y,z,c), I[540] = (T)(img)(_n8##x,_n8##y,z,c), I[541] = (T)(img)(_n9##x,_n8##y,z,c), I[542] = (T)(img)(_n10##x,_n8##y,z,c), I[543] = (T)(img)(_n11##x,_n8##y,z,c), I[544] = (T)(img)(_n12##x,_n8##y,z,c), I[545] = (T)(img)(_n13##x,_n8##y,z,c), \ - I[546] = (T)(img)(_p12##x,_n9##y,z,c), I[547] = (T)(img)(_p11##x,_n9##y,z,c), I[548] = (T)(img)(_p10##x,_n9##y,z,c), I[549] = (T)(img)(_p9##x,_n9##y,z,c), I[550] = (T)(img)(_p8##x,_n9##y,z,c), I[551] = (T)(img)(_p7##x,_n9##y,z,c), I[552] = (T)(img)(_p6##x,_n9##y,z,c), I[553] = (T)(img)(_p5##x,_n9##y,z,c), I[554] = (T)(img)(_p4##x,_n9##y,z,c), I[555] = (T)(img)(_p3##x,_n9##y,z,c), I[556] = (T)(img)(_p2##x,_n9##y,z,c), I[557] = (T)(img)(_p1##x,_n9##y,z,c), I[558] = (T)(img)(x,_n9##y,z,c), I[559] = (T)(img)(_n1##x,_n9##y,z,c), I[560] = (T)(img)(_n2##x,_n9##y,z,c), I[561] = (T)(img)(_n3##x,_n9##y,z,c), I[562] = (T)(img)(_n4##x,_n9##y,z,c), I[563] = (T)(img)(_n5##x,_n9##y,z,c), I[564] = (T)(img)(_n6##x,_n9##y,z,c), I[565] = (T)(img)(_n7##x,_n9##y,z,c), I[566] = (T)(img)(_n8##x,_n9##y,z,c), I[567] = (T)(img)(_n9##x,_n9##y,z,c), I[568] = (T)(img)(_n10##x,_n9##y,z,c), I[569] = (T)(img)(_n11##x,_n9##y,z,c), I[570] = (T)(img)(_n12##x,_n9##y,z,c), I[571] = (T)(img)(_n13##x,_n9##y,z,c), \ - I[572] = (T)(img)(_p12##x,_n10##y,z,c), I[573] = (T)(img)(_p11##x,_n10##y,z,c), I[574] = (T)(img)(_p10##x,_n10##y,z,c), I[575] = (T)(img)(_p9##x,_n10##y,z,c), I[576] = (T)(img)(_p8##x,_n10##y,z,c), I[577] = (T)(img)(_p7##x,_n10##y,z,c), I[578] = (T)(img)(_p6##x,_n10##y,z,c), I[579] = (T)(img)(_p5##x,_n10##y,z,c), I[580] = (T)(img)(_p4##x,_n10##y,z,c), I[581] = (T)(img)(_p3##x,_n10##y,z,c), I[582] = (T)(img)(_p2##x,_n10##y,z,c), I[583] = (T)(img)(_p1##x,_n10##y,z,c), I[584] = (T)(img)(x,_n10##y,z,c), I[585] = (T)(img)(_n1##x,_n10##y,z,c), I[586] = (T)(img)(_n2##x,_n10##y,z,c), I[587] = (T)(img)(_n3##x,_n10##y,z,c), I[588] = (T)(img)(_n4##x,_n10##y,z,c), I[589] = (T)(img)(_n5##x,_n10##y,z,c), I[590] = (T)(img)(_n6##x,_n10##y,z,c), I[591] = (T)(img)(_n7##x,_n10##y,z,c), I[592] = (T)(img)(_n8##x,_n10##y,z,c), I[593] = (T)(img)(_n9##x,_n10##y,z,c), I[594] = (T)(img)(_n10##x,_n10##y,z,c), I[595] = (T)(img)(_n11##x,_n10##y,z,c), I[596] = (T)(img)(_n12##x,_n10##y,z,c), I[597] = (T)(img)(_n13##x,_n10##y,z,c), \ - I[598] = (T)(img)(_p12##x,_n11##y,z,c), I[599] = (T)(img)(_p11##x,_n11##y,z,c), I[600] = (T)(img)(_p10##x,_n11##y,z,c), I[601] = (T)(img)(_p9##x,_n11##y,z,c), I[602] = (T)(img)(_p8##x,_n11##y,z,c), I[603] = (T)(img)(_p7##x,_n11##y,z,c), I[604] = (T)(img)(_p6##x,_n11##y,z,c), I[605] = (T)(img)(_p5##x,_n11##y,z,c), I[606] = (T)(img)(_p4##x,_n11##y,z,c), I[607] = (T)(img)(_p3##x,_n11##y,z,c), I[608] = (T)(img)(_p2##x,_n11##y,z,c), I[609] = (T)(img)(_p1##x,_n11##y,z,c), I[610] = (T)(img)(x,_n11##y,z,c), I[611] = (T)(img)(_n1##x,_n11##y,z,c), I[612] = (T)(img)(_n2##x,_n11##y,z,c), I[613] = (T)(img)(_n3##x,_n11##y,z,c), I[614] = (T)(img)(_n4##x,_n11##y,z,c), I[615] = (T)(img)(_n5##x,_n11##y,z,c), I[616] = (T)(img)(_n6##x,_n11##y,z,c), I[617] = (T)(img)(_n7##x,_n11##y,z,c), I[618] = (T)(img)(_n8##x,_n11##y,z,c), I[619] = (T)(img)(_n9##x,_n11##y,z,c), I[620] = (T)(img)(_n10##x,_n11##y,z,c), I[621] = (T)(img)(_n11##x,_n11##y,z,c), I[622] = (T)(img)(_n12##x,_n11##y,z,c), I[623] = (T)(img)(_n13##x,_n11##y,z,c), \ - I[624] = (T)(img)(_p12##x,_n12##y,z,c), I[625] = (T)(img)(_p11##x,_n12##y,z,c), I[626] = (T)(img)(_p10##x,_n12##y,z,c), I[627] = (T)(img)(_p9##x,_n12##y,z,c), I[628] = (T)(img)(_p8##x,_n12##y,z,c), I[629] = (T)(img)(_p7##x,_n12##y,z,c), I[630] = (T)(img)(_p6##x,_n12##y,z,c), I[631] = (T)(img)(_p5##x,_n12##y,z,c), I[632] = (T)(img)(_p4##x,_n12##y,z,c), I[633] = (T)(img)(_p3##x,_n12##y,z,c), I[634] = (T)(img)(_p2##x,_n12##y,z,c), I[635] = (T)(img)(_p1##x,_n12##y,z,c), I[636] = (T)(img)(x,_n12##y,z,c), I[637] = (T)(img)(_n1##x,_n12##y,z,c), I[638] = (T)(img)(_n2##x,_n12##y,z,c), I[639] = (T)(img)(_n3##x,_n12##y,z,c), I[640] = (T)(img)(_n4##x,_n12##y,z,c), I[641] = (T)(img)(_n5##x,_n12##y,z,c), I[642] = (T)(img)(_n6##x,_n12##y,z,c), I[643] = (T)(img)(_n7##x,_n12##y,z,c), I[644] = (T)(img)(_n8##x,_n12##y,z,c), I[645] = (T)(img)(_n9##x,_n12##y,z,c), I[646] = (T)(img)(_n10##x,_n12##y,z,c), I[647] = (T)(img)(_n11##x,_n12##y,z,c), I[648] = (T)(img)(_n12##x,_n12##y,z,c), I[649] = (T)(img)(_n13##x,_n12##y,z,c), \ - I[650] = (T)(img)(_p12##x,_n13##y,z,c), I[651] = (T)(img)(_p11##x,_n13##y,z,c), I[652] = (T)(img)(_p10##x,_n13##y,z,c), I[653] = (T)(img)(_p9##x,_n13##y,z,c), I[654] = (T)(img)(_p8##x,_n13##y,z,c), I[655] = (T)(img)(_p7##x,_n13##y,z,c), I[656] = (T)(img)(_p6##x,_n13##y,z,c), I[657] = (T)(img)(_p5##x,_n13##y,z,c), I[658] = (T)(img)(_p4##x,_n13##y,z,c), I[659] = (T)(img)(_p3##x,_n13##y,z,c), I[660] = (T)(img)(_p2##x,_n13##y,z,c), I[661] = (T)(img)(_p1##x,_n13##y,z,c), I[662] = (T)(img)(x,_n13##y,z,c), I[663] = (T)(img)(_n1##x,_n13##y,z,c), I[664] = (T)(img)(_n2##x,_n13##y,z,c), I[665] = (T)(img)(_n3##x,_n13##y,z,c), I[666] = (T)(img)(_n4##x,_n13##y,z,c), I[667] = (T)(img)(_n5##x,_n13##y,z,c), I[668] = (T)(img)(_n6##x,_n13##y,z,c), I[669] = (T)(img)(_n7##x,_n13##y,z,c), I[670] = (T)(img)(_n8##x,_n13##y,z,c), I[671] = (T)(img)(_n9##x,_n13##y,z,c), I[672] = (T)(img)(_n10##x,_n13##y,z,c), I[673] = (T)(img)(_n11##x,_n13##y,z,c), I[674] = (T)(img)(_n12##x,_n13##y,z,c), I[675] = (T)(img)(_n13##x,_n13##y,z,c); - -// Define 27x27 loop macros -//------------------------- -#define cimg_for27(bound,i) for (int i = 0, \ - _p13##i = 0, _p12##i = 0, _p11##i = 0, _p10##i = 0, _p9##i = 0, _p8##i = 0, _p7##i = 0, _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6, \ - _n7##i = 7>=(int)(bound)?(int)(bound) - 1:7, \ - _n8##i = 8>=(int)(bound)?(int)(bound) - 1:8, \ - _n9##i = 9>=(int)(bound)?(int)(bound) - 1:9, \ - _n10##i = 10>=(int)(bound)?(int)(bound) - 1:10, \ - _n11##i = 11>=(int)(bound)?(int)(bound) - 1:11, \ - _n12##i = 12>=(int)(bound)?(int)(bound) - 1:12, \ - _n13##i = 13>=(int)(bound)?(int)(bound) - 1:13; \ - _n13##i<(int)(bound) || _n12##i==--_n13##i || _n11##i==--_n12##i || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n13##i = _n12##i = _n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p13##i = _p12##i, _p12##i = _p11##i, _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i, ++_n12##i, ++_n13##i) - -#define cimg_for27X(img,x) cimg_for27((img)._width,x) -#define cimg_for27Y(img,y) cimg_for27((img)._height,y) -#define cimg_for27Z(img,z) cimg_for27((img)._depth,z) -#define cimg_for27C(img,c) cimg_for27((img)._spectrum,c) -#define cimg_for27XY(img,x,y) cimg_for27Y(img,y) cimg_for27X(img,x) -#define cimg_for27XZ(img,x,z) cimg_for27Z(img,z) cimg_for27X(img,x) -#define cimg_for27XC(img,x,c) cimg_for27C(img,c) cimg_for27X(img,x) -#define cimg_for27YZ(img,y,z) cimg_for27Z(img,z) cimg_for27Y(img,y) -#define cimg_for27YC(img,y,c) cimg_for27C(img,c) cimg_for27Y(img,y) -#define cimg_for27ZC(img,z,c) cimg_for27C(img,c) cimg_for27Z(img,z) -#define cimg_for27XYZ(img,x,y,z) cimg_for27Z(img,z) cimg_for27XY(img,x,y) -#define cimg_for27XZC(img,x,z,c) cimg_for27C(img,c) cimg_for27XZ(img,x,z) -#define cimg_for27YZC(img,y,z,c) cimg_for27C(img,c) cimg_for27YZ(img,y,z) -#define cimg_for27XYZC(img,x,y,z,c) cimg_for27C(img,c) cimg_for27XYZ(img,x,y,z) - -#define cimg_for_in27(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p13##i = i - 13<0?0:i - 13, \ - _p12##i = i - 12<0?0:i - 12, \ - _p11##i = i - 11<0?0:i - 11, \ - _p10##i = i - 10<0?0:i - 10, \ - _p9##i = i - 9<0?0:i - 9, \ - _p8##i = i - 8<0?0:i - 8, \ - _p7##i = i - 7<0?0:i - 7, \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6, \ - _n7##i = i + 7>=(int)(bound)?(int)(bound) - 1:i + 7, \ - _n8##i = i + 8>=(int)(bound)?(int)(bound) - 1:i + 8, \ - _n9##i = i + 9>=(int)(bound)?(int)(bound) - 1:i + 9, \ - _n10##i = i + 10>=(int)(bound)?(int)(bound) - 1:i + 10, \ - _n11##i = i + 11>=(int)(bound)?(int)(bound) - 1:i + 11, \ - _n12##i = i + 12>=(int)(bound)?(int)(bound) - 1:i + 12, \ - _n13##i = i + 13>=(int)(bound)?(int)(bound) - 1:i + 13; \ - i<=(int)(i1) && (_n13##i<(int)(bound) || _n12##i==--_n13##i || _n11##i==--_n12##i || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n13##i = _n12##i = _n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p13##i = _p12##i, _p12##i = _p11##i, _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i, ++_n12##i, ++_n13##i) - -#define cimg_for_in27X(img,x0,x1,x) cimg_for_in27((img)._width,x0,x1,x) -#define cimg_for_in27Y(img,y0,y1,y) cimg_for_in27((img)._height,y0,y1,y) -#define cimg_for_in27Z(img,z0,z1,z) cimg_for_in27((img)._depth,z0,z1,z) -#define cimg_for_in27C(img,c0,c1,c) cimg_for_in27((img)._spectrum,c0,c1,c) -#define cimg_for_in27XY(img,x0,y0,x1,y1,x,y) cimg_for_in27Y(img,y0,y1,y) cimg_for_in27X(img,x0,x1,x) -#define cimg_for_in27XZ(img,x0,z0,x1,z1,x,z) cimg_for_in27Z(img,z0,z1,z) cimg_for_in27X(img,x0,x1,x) -#define cimg_for_in27XC(img,x0,c0,x1,c1,x,c) cimg_for_in27C(img,c0,c1,c) cimg_for_in27X(img,x0,x1,x) -#define cimg_for_in27YZ(img,y0,z0,y1,z1,y,z) cimg_for_in27Z(img,z0,z1,z) cimg_for_in27Y(img,y0,y1,y) -#define cimg_for_in27YC(img,y0,c0,y1,c1,y,c) cimg_for_in27C(img,c0,c1,c) cimg_for_in27Y(img,y0,y1,y) -#define cimg_for_in27ZC(img,z0,c0,z1,c1,z,c) cimg_for_in27C(img,c0,c1,c) cimg_for_in27Z(img,z0,z1,z) -#define cimg_for_in27XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in27Z(img,z0,z1,z) cimg_for_in27XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in27XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in27C(img,c0,c1,c) cimg_for_in27XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in27YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in27C(img,c0,c1,c) cimg_for_in27YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in27XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in27C(img,c0,c1,c) cimg_for_in27XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for27x27(img,x,y,z,c,I,T) \ - cimg_for27((img)._height,y) for (int x = 0, \ - _p13##x = 0, _p12##x = 0, _p11##x = 0, _p10##x = 0, _p9##x = 0, _p8##x = 0, _p7##x = 0, _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = 6>=((img)._width)?(img).width() - 1:6, \ - _n7##x = 7>=((img)._width)?(img).width() - 1:7, \ - _n8##x = 8>=((img)._width)?(img).width() - 1:8, \ - _n9##x = 9>=((img)._width)?(img).width() - 1:9, \ - _n10##x = 10>=((img)._width)?(img).width() - 1:10, \ - _n11##x = 11>=((img)._width)?(img).width() - 1:11, \ - _n12##x = 12>=((img)._width)?(img).width() - 1:12, \ - _n13##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = I[7] = I[8] = I[9] = I[10] = I[11] = I[12] = I[13] = (T)(img)(0,_p13##y,z,c)), \ - (I[27] = I[28] = I[29] = I[30] = I[31] = I[32] = I[33] = I[34] = I[35] = I[36] = I[37] = I[38] = I[39] = I[40] = (T)(img)(0,_p12##y,z,c)), \ - (I[54] = I[55] = I[56] = I[57] = I[58] = I[59] = I[60] = I[61] = I[62] = I[63] = I[64] = I[65] = I[66] = I[67] = (T)(img)(0,_p11##y,z,c)), \ - (I[81] = I[82] = I[83] = I[84] = I[85] = I[86] = I[87] = I[88] = I[89] = I[90] = I[91] = I[92] = I[93] = I[94] = (T)(img)(0,_p10##y,z,c)), \ - (I[108] = I[109] = I[110] = I[111] = I[112] = I[113] = I[114] = I[115] = I[116] = I[117] = I[118] = I[119] = I[120] = I[121] = (T)(img)(0,_p9##y,z,c)), \ - (I[135] = I[136] = I[137] = I[138] = I[139] = I[140] = I[141] = I[142] = I[143] = I[144] = I[145] = I[146] = I[147] = I[148] = (T)(img)(0,_p8##y,z,c)), \ - (I[162] = I[163] = I[164] = I[165] = I[166] = I[167] = I[168] = I[169] = I[170] = I[171] = I[172] = I[173] = I[174] = I[175] = (T)(img)(0,_p7##y,z,c)), \ - (I[189] = I[190] = I[191] = I[192] = I[193] = I[194] = I[195] = I[196] = I[197] = I[198] = I[199] = I[200] = I[201] = I[202] = (T)(img)(0,_p6##y,z,c)), \ - (I[216] = I[217] = I[218] = I[219] = I[220] = I[221] = I[222] = I[223] = I[224] = I[225] = I[226] = I[227] = I[228] = I[229] = (T)(img)(0,_p5##y,z,c)), \ - (I[243] = I[244] = I[245] = I[246] = I[247] = I[248] = I[249] = I[250] = I[251] = I[252] = I[253] = I[254] = I[255] = I[256] = (T)(img)(0,_p4##y,z,c)), \ - (I[270] = I[271] = I[272] = I[273] = I[274] = I[275] = I[276] = I[277] = I[278] = I[279] = I[280] = I[281] = I[282] = I[283] = (T)(img)(0,_p3##y,z,c)), \ - (I[297] = I[298] = I[299] = I[300] = I[301] = I[302] = I[303] = I[304] = I[305] = I[306] = I[307] = I[308] = I[309] = I[310] = (T)(img)(0,_p2##y,z,c)), \ - (I[324] = I[325] = I[326] = I[327] = I[328] = I[329] = I[330] = I[331] = I[332] = I[333] = I[334] = I[335] = I[336] = I[337] = (T)(img)(0,_p1##y,z,c)), \ - (I[351] = I[352] = I[353] = I[354] = I[355] = I[356] = I[357] = I[358] = I[359] = I[360] = I[361] = I[362] = I[363] = I[364] = (T)(img)(0,y,z,c)), \ - (I[378] = I[379] = I[380] = I[381] = I[382] = I[383] = I[384] = I[385] = I[386] = I[387] = I[388] = I[389] = I[390] = I[391] = (T)(img)(0,_n1##y,z,c)), \ - (I[405] = I[406] = I[407] = I[408] = I[409] = I[410] = I[411] = I[412] = I[413] = I[414] = I[415] = I[416] = I[417] = I[418] = (T)(img)(0,_n2##y,z,c)), \ - (I[432] = I[433] = I[434] = I[435] = I[436] = I[437] = I[438] = I[439] = I[440] = I[441] = I[442] = I[443] = I[444] = I[445] = (T)(img)(0,_n3##y,z,c)), \ - (I[459] = I[460] = I[461] = I[462] = I[463] = I[464] = I[465] = I[466] = I[467] = I[468] = I[469] = I[470] = I[471] = I[472] = (T)(img)(0,_n4##y,z,c)), \ - (I[486] = I[487] = I[488] = I[489] = I[490] = I[491] = I[492] = I[493] = I[494] = I[495] = I[496] = I[497] = I[498] = I[499] = (T)(img)(0,_n5##y,z,c)), \ - (I[513] = I[514] = I[515] = I[516] = I[517] = I[518] = I[519] = I[520] = I[521] = I[522] = I[523] = I[524] = I[525] = I[526] = (T)(img)(0,_n6##y,z,c)), \ - (I[540] = I[541] = I[542] = I[543] = I[544] = I[545] = I[546] = I[547] = I[548] = I[549] = I[550] = I[551] = I[552] = I[553] = (T)(img)(0,_n7##y,z,c)), \ - (I[567] = I[568] = I[569] = I[570] = I[571] = I[572] = I[573] = I[574] = I[575] = I[576] = I[577] = I[578] = I[579] = I[580] = (T)(img)(0,_n8##y,z,c)), \ - (I[594] = I[595] = I[596] = I[597] = I[598] = I[599] = I[600] = I[601] = I[602] = I[603] = I[604] = I[605] = I[606] = I[607] = (T)(img)(0,_n9##y,z,c)), \ - (I[621] = I[622] = I[623] = I[624] = I[625] = I[626] = I[627] = I[628] = I[629] = I[630] = I[631] = I[632] = I[633] = I[634] = (T)(img)(0,_n10##y,z,c)), \ - (I[648] = I[649] = I[650] = I[651] = I[652] = I[653] = I[654] = I[655] = I[656] = I[657] = I[658] = I[659] = I[660] = I[661] = (T)(img)(0,_n11##y,z,c)), \ - (I[675] = I[676] = I[677] = I[678] = I[679] = I[680] = I[681] = I[682] = I[683] = I[684] = I[685] = I[686] = I[687] = I[688] = (T)(img)(0,_n12##y,z,c)), \ - (I[702] = I[703] = I[704] = I[705] = I[706] = I[707] = I[708] = I[709] = I[710] = I[711] = I[712] = I[713] = I[714] = I[715] = (T)(img)(0,_n13##y,z,c)), \ - (I[14] = (T)(img)(_n1##x,_p13##y,z,c)), \ - (I[41] = (T)(img)(_n1##x,_p12##y,z,c)), \ - (I[68] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[95] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[122] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[149] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[176] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[203] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[230] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[257] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[284] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[311] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[338] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[365] = (T)(img)(_n1##x,y,z,c)), \ - (I[392] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[419] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[446] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[473] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[500] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[527] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[554] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[581] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[608] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[635] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[662] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[689] = (T)(img)(_n1##x,_n12##y,z,c)), \ - (I[716] = (T)(img)(_n1##x,_n13##y,z,c)), \ - (I[15] = (T)(img)(_n2##x,_p13##y,z,c)), \ - (I[42] = (T)(img)(_n2##x,_p12##y,z,c)), \ - (I[69] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[96] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[123] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[150] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[177] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[204] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[231] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[258] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[285] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[312] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[339] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[366] = (T)(img)(_n2##x,y,z,c)), \ - (I[393] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[420] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[447] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[474] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[501] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[528] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[555] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[582] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[609] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[636] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[663] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[690] = (T)(img)(_n2##x,_n12##y,z,c)), \ - (I[717] = (T)(img)(_n2##x,_n13##y,z,c)), \ - (I[16] = (T)(img)(_n3##x,_p13##y,z,c)), \ - (I[43] = (T)(img)(_n3##x,_p12##y,z,c)), \ - (I[70] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[97] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[124] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[151] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[178] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[205] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[232] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[259] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[286] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[313] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[340] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[367] = (T)(img)(_n3##x,y,z,c)), \ - (I[394] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[421] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[448] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[475] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[502] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[529] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[556] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[583] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[610] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[637] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[664] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[691] = (T)(img)(_n3##x,_n12##y,z,c)), \ - (I[718] = (T)(img)(_n3##x,_n13##y,z,c)), \ - (I[17] = (T)(img)(_n4##x,_p13##y,z,c)), \ - (I[44] = (T)(img)(_n4##x,_p12##y,z,c)), \ - (I[71] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[98] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[125] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[152] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[179] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[206] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[233] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[260] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[287] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[314] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[341] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[368] = (T)(img)(_n4##x,y,z,c)), \ - (I[395] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[422] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[449] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[476] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[503] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[530] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[557] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[584] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[611] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[638] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[665] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[692] = (T)(img)(_n4##x,_n12##y,z,c)), \ - (I[719] = (T)(img)(_n4##x,_n13##y,z,c)), \ - (I[18] = (T)(img)(_n5##x,_p13##y,z,c)), \ - (I[45] = (T)(img)(_n5##x,_p12##y,z,c)), \ - (I[72] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[99] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[126] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[153] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[180] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[207] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[234] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[261] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[288] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[315] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[342] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[369] = (T)(img)(_n5##x,y,z,c)), \ - (I[396] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[423] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[450] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[477] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[504] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[531] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[558] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[585] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[612] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[639] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[666] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[693] = (T)(img)(_n5##x,_n12##y,z,c)), \ - (I[720] = (T)(img)(_n5##x,_n13##y,z,c)), \ - (I[19] = (T)(img)(_n6##x,_p13##y,z,c)), \ - (I[46] = (T)(img)(_n6##x,_p12##y,z,c)), \ - (I[73] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[100] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[127] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[154] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[181] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[208] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[235] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[262] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[289] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[316] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[343] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[370] = (T)(img)(_n6##x,y,z,c)), \ - (I[397] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[424] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[451] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[478] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[505] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[532] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[559] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[586] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[613] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[640] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[667] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[694] = (T)(img)(_n6##x,_n12##y,z,c)), \ - (I[721] = (T)(img)(_n6##x,_n13##y,z,c)), \ - (I[20] = (T)(img)(_n7##x,_p13##y,z,c)), \ - (I[47] = (T)(img)(_n7##x,_p12##y,z,c)), \ - (I[74] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[101] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[128] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[155] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[182] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[209] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[236] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[263] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[290] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[317] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[344] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[371] = (T)(img)(_n7##x,y,z,c)), \ - (I[398] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[425] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[452] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[479] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[506] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[533] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[560] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[587] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[614] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[641] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[668] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[695] = (T)(img)(_n7##x,_n12##y,z,c)), \ - (I[722] = (T)(img)(_n7##x,_n13##y,z,c)), \ - (I[21] = (T)(img)(_n8##x,_p13##y,z,c)), \ - (I[48] = (T)(img)(_n8##x,_p12##y,z,c)), \ - (I[75] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[102] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[129] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[156] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[183] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[210] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[237] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[264] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[291] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[318] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[345] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[372] = (T)(img)(_n8##x,y,z,c)), \ - (I[399] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[426] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[453] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[480] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[507] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[534] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[561] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[588] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[615] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[642] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[669] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[696] = (T)(img)(_n8##x,_n12##y,z,c)), \ - (I[723] = (T)(img)(_n8##x,_n13##y,z,c)), \ - (I[22] = (T)(img)(_n9##x,_p13##y,z,c)), \ - (I[49] = (T)(img)(_n9##x,_p12##y,z,c)), \ - (I[76] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[103] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[130] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[157] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[184] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[211] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[238] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[265] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[292] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[319] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[346] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[373] = (T)(img)(_n9##x,y,z,c)), \ - (I[400] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[427] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[454] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[481] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[508] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[535] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[562] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[589] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[616] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[643] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[670] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[697] = (T)(img)(_n9##x,_n12##y,z,c)), \ - (I[724] = (T)(img)(_n9##x,_n13##y,z,c)), \ - (I[23] = (T)(img)(_n10##x,_p13##y,z,c)), \ - (I[50] = (T)(img)(_n10##x,_p12##y,z,c)), \ - (I[77] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[104] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[131] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[158] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[185] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[212] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[239] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[266] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[293] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[320] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[347] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[374] = (T)(img)(_n10##x,y,z,c)), \ - (I[401] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[428] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[455] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[482] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[509] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[536] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[563] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[590] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[617] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[644] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[671] = (T)(img)(_n10##x,_n11##y,z,c)), \ - (I[698] = (T)(img)(_n10##x,_n12##y,z,c)), \ - (I[725] = (T)(img)(_n10##x,_n13##y,z,c)), \ - (I[24] = (T)(img)(_n11##x,_p13##y,z,c)), \ - (I[51] = (T)(img)(_n11##x,_p12##y,z,c)), \ - (I[78] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[105] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[132] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[159] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[186] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[213] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[240] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[267] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[294] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[321] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[348] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[375] = (T)(img)(_n11##x,y,z,c)), \ - (I[402] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[429] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[456] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[483] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[510] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[537] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[564] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[591] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[618] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[645] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[672] = (T)(img)(_n11##x,_n11##y,z,c)), \ - (I[699] = (T)(img)(_n11##x,_n12##y,z,c)), \ - (I[726] = (T)(img)(_n11##x,_n13##y,z,c)), \ - (I[25] = (T)(img)(_n12##x,_p13##y,z,c)), \ - (I[52] = (T)(img)(_n12##x,_p12##y,z,c)), \ - (I[79] = (T)(img)(_n12##x,_p11##y,z,c)), \ - (I[106] = (T)(img)(_n12##x,_p10##y,z,c)), \ - (I[133] = (T)(img)(_n12##x,_p9##y,z,c)), \ - (I[160] = (T)(img)(_n12##x,_p8##y,z,c)), \ - (I[187] = (T)(img)(_n12##x,_p7##y,z,c)), \ - (I[214] = (T)(img)(_n12##x,_p6##y,z,c)), \ - (I[241] = (T)(img)(_n12##x,_p5##y,z,c)), \ - (I[268] = (T)(img)(_n12##x,_p4##y,z,c)), \ - (I[295] = (T)(img)(_n12##x,_p3##y,z,c)), \ - (I[322] = (T)(img)(_n12##x,_p2##y,z,c)), \ - (I[349] = (T)(img)(_n12##x,_p1##y,z,c)), \ - (I[376] = (T)(img)(_n12##x,y,z,c)), \ - (I[403] = (T)(img)(_n12##x,_n1##y,z,c)), \ - (I[430] = (T)(img)(_n12##x,_n2##y,z,c)), \ - (I[457] = (T)(img)(_n12##x,_n3##y,z,c)), \ - (I[484] = (T)(img)(_n12##x,_n4##y,z,c)), \ - (I[511] = (T)(img)(_n12##x,_n5##y,z,c)), \ - (I[538] = (T)(img)(_n12##x,_n6##y,z,c)), \ - (I[565] = (T)(img)(_n12##x,_n7##y,z,c)), \ - (I[592] = (T)(img)(_n12##x,_n8##y,z,c)), \ - (I[619] = (T)(img)(_n12##x,_n9##y,z,c)), \ - (I[646] = (T)(img)(_n12##x,_n10##y,z,c)), \ - (I[673] = (T)(img)(_n12##x,_n11##y,z,c)), \ - (I[700] = (T)(img)(_n12##x,_n12##y,z,c)), \ - (I[727] = (T)(img)(_n12##x,_n13##y,z,c)), \ - 13>=((img)._width)?(img).width() - 1:13); \ - (_n13##x<(img).width() && ( \ - (I[26] = (T)(img)(_n13##x,_p13##y,z,c)), \ - (I[53] = (T)(img)(_n13##x,_p12##y,z,c)), \ - (I[80] = (T)(img)(_n13##x,_p11##y,z,c)), \ - (I[107] = (T)(img)(_n13##x,_p10##y,z,c)), \ - (I[134] = (T)(img)(_n13##x,_p9##y,z,c)), \ - (I[161] = (T)(img)(_n13##x,_p8##y,z,c)), \ - (I[188] = (T)(img)(_n13##x,_p7##y,z,c)), \ - (I[215] = (T)(img)(_n13##x,_p6##y,z,c)), \ - (I[242] = (T)(img)(_n13##x,_p5##y,z,c)), \ - (I[269] = (T)(img)(_n13##x,_p4##y,z,c)), \ - (I[296] = (T)(img)(_n13##x,_p3##y,z,c)), \ - (I[323] = (T)(img)(_n13##x,_p2##y,z,c)), \ - (I[350] = (T)(img)(_n13##x,_p1##y,z,c)), \ - (I[377] = (T)(img)(_n13##x,y,z,c)), \ - (I[404] = (T)(img)(_n13##x,_n1##y,z,c)), \ - (I[431] = (T)(img)(_n13##x,_n2##y,z,c)), \ - (I[458] = (T)(img)(_n13##x,_n3##y,z,c)), \ - (I[485] = (T)(img)(_n13##x,_n4##y,z,c)), \ - (I[512] = (T)(img)(_n13##x,_n5##y,z,c)), \ - (I[539] = (T)(img)(_n13##x,_n6##y,z,c)), \ - (I[566] = (T)(img)(_n13##x,_n7##y,z,c)), \ - (I[593] = (T)(img)(_n13##x,_n8##y,z,c)), \ - (I[620] = (T)(img)(_n13##x,_n9##y,z,c)), \ - (I[647] = (T)(img)(_n13##x,_n10##y,z,c)), \ - (I[674] = (T)(img)(_n13##x,_n11##y,z,c)), \ - (I[701] = (T)(img)(_n13##x,_n12##y,z,c)), \ - (I[728] = (T)(img)(_n13##x,_n13##y,z,c)),1)) || \ - _n12##x==--_n13##x || _n11##x==--_n12##x || _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n13##x = _n12##x = _n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], \ - I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], \ - I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], \ - I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], \ - I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], \ - I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], \ - I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], \ - I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], \ - I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], \ - I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], \ - I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], \ - I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], \ - I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], \ - I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], \ - I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], \ - I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], I[415] = I[416], I[416] = I[417], I[417] = I[418], I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], \ - I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], I[447] = I[448], I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], \ - I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], I[463] = I[464], I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], I[479] = I[480], I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], \ - I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], I[493] = I[494], I[494] = I[495], I[495] = I[496], I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], I[503] = I[504], I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], I[511] = I[512], \ - I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], I[519] = I[520], I[520] = I[521], I[521] = I[522], I[522] = I[523], I[523] = I[524], I[524] = I[525], I[525] = I[526], I[526] = I[527], I[527] = I[528], I[528] = I[529], I[529] = I[530], I[530] = I[531], I[531] = I[532], I[532] = I[533], I[533] = I[534], I[534] = I[535], I[535] = I[536], I[536] = I[537], I[537] = I[538], I[538] = I[539], \ - I[540] = I[541], I[541] = I[542], I[542] = I[543], I[543] = I[544], I[544] = I[545], I[545] = I[546], I[546] = I[547], I[547] = I[548], I[548] = I[549], I[549] = I[550], I[550] = I[551], I[551] = I[552], I[552] = I[553], I[553] = I[554], I[554] = I[555], I[555] = I[556], I[556] = I[557], I[557] = I[558], I[558] = I[559], I[559] = I[560], I[560] = I[561], I[561] = I[562], I[562] = I[563], I[563] = I[564], I[564] = I[565], I[565] = I[566], \ - I[567] = I[568], I[568] = I[569], I[569] = I[570], I[570] = I[571], I[571] = I[572], I[572] = I[573], I[573] = I[574], I[574] = I[575], I[575] = I[576], I[576] = I[577], I[577] = I[578], I[578] = I[579], I[579] = I[580], I[580] = I[581], I[581] = I[582], I[582] = I[583], I[583] = I[584], I[584] = I[585], I[585] = I[586], I[586] = I[587], I[587] = I[588], I[588] = I[589], I[589] = I[590], I[590] = I[591], I[591] = I[592], I[592] = I[593], \ - I[594] = I[595], I[595] = I[596], I[596] = I[597], I[597] = I[598], I[598] = I[599], I[599] = I[600], I[600] = I[601], I[601] = I[602], I[602] = I[603], I[603] = I[604], I[604] = I[605], I[605] = I[606], I[606] = I[607], I[607] = I[608], I[608] = I[609], I[609] = I[610], I[610] = I[611], I[611] = I[612], I[612] = I[613], I[613] = I[614], I[614] = I[615], I[615] = I[616], I[616] = I[617], I[617] = I[618], I[618] = I[619], I[619] = I[620], \ - I[621] = I[622], I[622] = I[623], I[623] = I[624], I[624] = I[625], I[625] = I[626], I[626] = I[627], I[627] = I[628], I[628] = I[629], I[629] = I[630], I[630] = I[631], I[631] = I[632], I[632] = I[633], I[633] = I[634], I[634] = I[635], I[635] = I[636], I[636] = I[637], I[637] = I[638], I[638] = I[639], I[639] = I[640], I[640] = I[641], I[641] = I[642], I[642] = I[643], I[643] = I[644], I[644] = I[645], I[645] = I[646], I[646] = I[647], \ - I[648] = I[649], I[649] = I[650], I[650] = I[651], I[651] = I[652], I[652] = I[653], I[653] = I[654], I[654] = I[655], I[655] = I[656], I[656] = I[657], I[657] = I[658], I[658] = I[659], I[659] = I[660], I[660] = I[661], I[661] = I[662], I[662] = I[663], I[663] = I[664], I[664] = I[665], I[665] = I[666], I[666] = I[667], I[667] = I[668], I[668] = I[669], I[669] = I[670], I[670] = I[671], I[671] = I[672], I[672] = I[673], I[673] = I[674], \ - I[675] = I[676], I[676] = I[677], I[677] = I[678], I[678] = I[679], I[679] = I[680], I[680] = I[681], I[681] = I[682], I[682] = I[683], I[683] = I[684], I[684] = I[685], I[685] = I[686], I[686] = I[687], I[687] = I[688], I[688] = I[689], I[689] = I[690], I[690] = I[691], I[691] = I[692], I[692] = I[693], I[693] = I[694], I[694] = I[695], I[695] = I[696], I[696] = I[697], I[697] = I[698], I[698] = I[699], I[699] = I[700], I[700] = I[701], \ - I[702] = I[703], I[703] = I[704], I[704] = I[705], I[705] = I[706], I[706] = I[707], I[707] = I[708], I[708] = I[709], I[709] = I[710], I[710] = I[711], I[711] = I[712], I[712] = I[713], I[713] = I[714], I[714] = I[715], I[715] = I[716], I[716] = I[717], I[717] = I[718], I[718] = I[719], I[719] = I[720], I[720] = I[721], I[721] = I[722], I[722] = I[723], I[723] = I[724], I[724] = I[725], I[725] = I[726], I[726] = I[727], I[727] = I[728], \ - _p13##x = _p12##x, _p12##x = _p11##x, _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x, ++_n12##x, ++_n13##x) - -#define cimg_for_in27x27(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in27((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p13##x = x - 13<0?0:x - 13, \ - _p12##x = x - 12<0?0:x - 12, \ - _p11##x = x - 11<0?0:x - 11, \ - _p10##x = x - 10<0?0:x - 10, \ - _p9##x = x - 9<0?0:x - 9, \ - _p8##x = x - 8<0?0:x - 8, \ - _p7##x = x - 7<0?0:x - 7, \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = x + 6>=(img).width()?(img).width() - 1:x + 6, \ - _n7##x = x + 7>=(img).width()?(img).width() - 1:x + 7, \ - _n8##x = x + 8>=(img).width()?(img).width() - 1:x + 8, \ - _n9##x = x + 9>=(img).width()?(img).width() - 1:x + 9, \ - _n10##x = x + 10>=(img).width()?(img).width() - 1:x + 10, \ - _n11##x = x + 11>=(img).width()?(img).width() - 1:x + 11, \ - _n12##x = x + 12>=(img).width()?(img).width() - 1:x + 12, \ - _n13##x = (int)( \ - (I[0] = (T)(img)(_p13##x,_p13##y,z,c)), \ - (I[27] = (T)(img)(_p13##x,_p12##y,z,c)), \ - (I[54] = (T)(img)(_p13##x,_p11##y,z,c)), \ - (I[81] = (T)(img)(_p13##x,_p10##y,z,c)), \ - (I[108] = (T)(img)(_p13##x,_p9##y,z,c)), \ - (I[135] = (T)(img)(_p13##x,_p8##y,z,c)), \ - (I[162] = (T)(img)(_p13##x,_p7##y,z,c)), \ - (I[189] = (T)(img)(_p13##x,_p6##y,z,c)), \ - (I[216] = (T)(img)(_p13##x,_p5##y,z,c)), \ - (I[243] = (T)(img)(_p13##x,_p4##y,z,c)), \ - (I[270] = (T)(img)(_p13##x,_p3##y,z,c)), \ - (I[297] = (T)(img)(_p13##x,_p2##y,z,c)), \ - (I[324] = (T)(img)(_p13##x,_p1##y,z,c)), \ - (I[351] = (T)(img)(_p13##x,y,z,c)), \ - (I[378] = (T)(img)(_p13##x,_n1##y,z,c)), \ - (I[405] = (T)(img)(_p13##x,_n2##y,z,c)), \ - (I[432] = (T)(img)(_p13##x,_n3##y,z,c)), \ - (I[459] = (T)(img)(_p13##x,_n4##y,z,c)), \ - (I[486] = (T)(img)(_p13##x,_n5##y,z,c)), \ - (I[513] = (T)(img)(_p13##x,_n6##y,z,c)), \ - (I[540] = (T)(img)(_p13##x,_n7##y,z,c)), \ - (I[567] = (T)(img)(_p13##x,_n8##y,z,c)), \ - (I[594] = (T)(img)(_p13##x,_n9##y,z,c)), \ - (I[621] = (T)(img)(_p13##x,_n10##y,z,c)), \ - (I[648] = (T)(img)(_p13##x,_n11##y,z,c)), \ - (I[675] = (T)(img)(_p13##x,_n12##y,z,c)), \ - (I[702] = (T)(img)(_p13##x,_n13##y,z,c)), \ - (I[1] = (T)(img)(_p12##x,_p13##y,z,c)), \ - (I[28] = (T)(img)(_p12##x,_p12##y,z,c)), \ - (I[55] = (T)(img)(_p12##x,_p11##y,z,c)), \ - (I[82] = (T)(img)(_p12##x,_p10##y,z,c)), \ - (I[109] = (T)(img)(_p12##x,_p9##y,z,c)), \ - (I[136] = (T)(img)(_p12##x,_p8##y,z,c)), \ - (I[163] = (T)(img)(_p12##x,_p7##y,z,c)), \ - (I[190] = (T)(img)(_p12##x,_p6##y,z,c)), \ - (I[217] = (T)(img)(_p12##x,_p5##y,z,c)), \ - (I[244] = (T)(img)(_p12##x,_p4##y,z,c)), \ - (I[271] = (T)(img)(_p12##x,_p3##y,z,c)), \ - (I[298] = (T)(img)(_p12##x,_p2##y,z,c)), \ - (I[325] = (T)(img)(_p12##x,_p1##y,z,c)), \ - (I[352] = (T)(img)(_p12##x,y,z,c)), \ - (I[379] = (T)(img)(_p12##x,_n1##y,z,c)), \ - (I[406] = (T)(img)(_p12##x,_n2##y,z,c)), \ - (I[433] = (T)(img)(_p12##x,_n3##y,z,c)), \ - (I[460] = (T)(img)(_p12##x,_n4##y,z,c)), \ - (I[487] = (T)(img)(_p12##x,_n5##y,z,c)), \ - (I[514] = (T)(img)(_p12##x,_n6##y,z,c)), \ - (I[541] = (T)(img)(_p12##x,_n7##y,z,c)), \ - (I[568] = (T)(img)(_p12##x,_n8##y,z,c)), \ - (I[595] = (T)(img)(_p12##x,_n9##y,z,c)), \ - (I[622] = (T)(img)(_p12##x,_n10##y,z,c)), \ - (I[649] = (T)(img)(_p12##x,_n11##y,z,c)), \ - (I[676] = (T)(img)(_p12##x,_n12##y,z,c)), \ - (I[703] = (T)(img)(_p12##x,_n13##y,z,c)), \ - (I[2] = (T)(img)(_p11##x,_p13##y,z,c)), \ - (I[29] = (T)(img)(_p11##x,_p12##y,z,c)), \ - (I[56] = (T)(img)(_p11##x,_p11##y,z,c)), \ - (I[83] = (T)(img)(_p11##x,_p10##y,z,c)), \ - (I[110] = (T)(img)(_p11##x,_p9##y,z,c)), \ - (I[137] = (T)(img)(_p11##x,_p8##y,z,c)), \ - (I[164] = (T)(img)(_p11##x,_p7##y,z,c)), \ - (I[191] = (T)(img)(_p11##x,_p6##y,z,c)), \ - (I[218] = (T)(img)(_p11##x,_p5##y,z,c)), \ - (I[245] = (T)(img)(_p11##x,_p4##y,z,c)), \ - (I[272] = (T)(img)(_p11##x,_p3##y,z,c)), \ - (I[299] = (T)(img)(_p11##x,_p2##y,z,c)), \ - (I[326] = (T)(img)(_p11##x,_p1##y,z,c)), \ - (I[353] = (T)(img)(_p11##x,y,z,c)), \ - (I[380] = (T)(img)(_p11##x,_n1##y,z,c)), \ - (I[407] = (T)(img)(_p11##x,_n2##y,z,c)), \ - (I[434] = (T)(img)(_p11##x,_n3##y,z,c)), \ - (I[461] = (T)(img)(_p11##x,_n4##y,z,c)), \ - (I[488] = (T)(img)(_p11##x,_n5##y,z,c)), \ - (I[515] = (T)(img)(_p11##x,_n6##y,z,c)), \ - (I[542] = (T)(img)(_p11##x,_n7##y,z,c)), \ - (I[569] = (T)(img)(_p11##x,_n8##y,z,c)), \ - (I[596] = (T)(img)(_p11##x,_n9##y,z,c)), \ - (I[623] = (T)(img)(_p11##x,_n10##y,z,c)), \ - (I[650] = (T)(img)(_p11##x,_n11##y,z,c)), \ - (I[677] = (T)(img)(_p11##x,_n12##y,z,c)), \ - (I[704] = (T)(img)(_p11##x,_n13##y,z,c)), \ - (I[3] = (T)(img)(_p10##x,_p13##y,z,c)), \ - (I[30] = (T)(img)(_p10##x,_p12##y,z,c)), \ - (I[57] = (T)(img)(_p10##x,_p11##y,z,c)), \ - (I[84] = (T)(img)(_p10##x,_p10##y,z,c)), \ - (I[111] = (T)(img)(_p10##x,_p9##y,z,c)), \ - (I[138] = (T)(img)(_p10##x,_p8##y,z,c)), \ - (I[165] = (T)(img)(_p10##x,_p7##y,z,c)), \ - (I[192] = (T)(img)(_p10##x,_p6##y,z,c)), \ - (I[219] = (T)(img)(_p10##x,_p5##y,z,c)), \ - (I[246] = (T)(img)(_p10##x,_p4##y,z,c)), \ - (I[273] = (T)(img)(_p10##x,_p3##y,z,c)), \ - (I[300] = (T)(img)(_p10##x,_p2##y,z,c)), \ - (I[327] = (T)(img)(_p10##x,_p1##y,z,c)), \ - (I[354] = (T)(img)(_p10##x,y,z,c)), \ - (I[381] = (T)(img)(_p10##x,_n1##y,z,c)), \ - (I[408] = (T)(img)(_p10##x,_n2##y,z,c)), \ - (I[435] = (T)(img)(_p10##x,_n3##y,z,c)), \ - (I[462] = (T)(img)(_p10##x,_n4##y,z,c)), \ - (I[489] = (T)(img)(_p10##x,_n5##y,z,c)), \ - (I[516] = (T)(img)(_p10##x,_n6##y,z,c)), \ - (I[543] = (T)(img)(_p10##x,_n7##y,z,c)), \ - (I[570] = (T)(img)(_p10##x,_n8##y,z,c)), \ - (I[597] = (T)(img)(_p10##x,_n9##y,z,c)), \ - (I[624] = (T)(img)(_p10##x,_n10##y,z,c)), \ - (I[651] = (T)(img)(_p10##x,_n11##y,z,c)), \ - (I[678] = (T)(img)(_p10##x,_n12##y,z,c)), \ - (I[705] = (T)(img)(_p10##x,_n13##y,z,c)), \ - (I[4] = (T)(img)(_p9##x,_p13##y,z,c)), \ - (I[31] = (T)(img)(_p9##x,_p12##y,z,c)), \ - (I[58] = (T)(img)(_p9##x,_p11##y,z,c)), \ - (I[85] = (T)(img)(_p9##x,_p10##y,z,c)), \ - (I[112] = (T)(img)(_p9##x,_p9##y,z,c)), \ - (I[139] = (T)(img)(_p9##x,_p8##y,z,c)), \ - (I[166] = (T)(img)(_p9##x,_p7##y,z,c)), \ - (I[193] = (T)(img)(_p9##x,_p6##y,z,c)), \ - (I[220] = (T)(img)(_p9##x,_p5##y,z,c)), \ - (I[247] = (T)(img)(_p9##x,_p4##y,z,c)), \ - (I[274] = (T)(img)(_p9##x,_p3##y,z,c)), \ - (I[301] = (T)(img)(_p9##x,_p2##y,z,c)), \ - (I[328] = (T)(img)(_p9##x,_p1##y,z,c)), \ - (I[355] = (T)(img)(_p9##x,y,z,c)), \ - (I[382] = (T)(img)(_p9##x,_n1##y,z,c)), \ - (I[409] = (T)(img)(_p9##x,_n2##y,z,c)), \ - (I[436] = (T)(img)(_p9##x,_n3##y,z,c)), \ - (I[463] = (T)(img)(_p9##x,_n4##y,z,c)), \ - (I[490] = (T)(img)(_p9##x,_n5##y,z,c)), \ - (I[517] = (T)(img)(_p9##x,_n6##y,z,c)), \ - (I[544] = (T)(img)(_p9##x,_n7##y,z,c)), \ - (I[571] = (T)(img)(_p9##x,_n8##y,z,c)), \ - (I[598] = (T)(img)(_p9##x,_n9##y,z,c)), \ - (I[625] = (T)(img)(_p9##x,_n10##y,z,c)), \ - (I[652] = (T)(img)(_p9##x,_n11##y,z,c)), \ - (I[679] = (T)(img)(_p9##x,_n12##y,z,c)), \ - (I[706] = (T)(img)(_p9##x,_n13##y,z,c)), \ - (I[5] = (T)(img)(_p8##x,_p13##y,z,c)), \ - (I[32] = (T)(img)(_p8##x,_p12##y,z,c)), \ - (I[59] = (T)(img)(_p8##x,_p11##y,z,c)), \ - (I[86] = (T)(img)(_p8##x,_p10##y,z,c)), \ - (I[113] = (T)(img)(_p8##x,_p9##y,z,c)), \ - (I[140] = (T)(img)(_p8##x,_p8##y,z,c)), \ - (I[167] = (T)(img)(_p8##x,_p7##y,z,c)), \ - (I[194] = (T)(img)(_p8##x,_p6##y,z,c)), \ - (I[221] = (T)(img)(_p8##x,_p5##y,z,c)), \ - (I[248] = (T)(img)(_p8##x,_p4##y,z,c)), \ - (I[275] = (T)(img)(_p8##x,_p3##y,z,c)), \ - (I[302] = (T)(img)(_p8##x,_p2##y,z,c)), \ - (I[329] = (T)(img)(_p8##x,_p1##y,z,c)), \ - (I[356] = (T)(img)(_p8##x,y,z,c)), \ - (I[383] = (T)(img)(_p8##x,_n1##y,z,c)), \ - (I[410] = (T)(img)(_p8##x,_n2##y,z,c)), \ - (I[437] = (T)(img)(_p8##x,_n3##y,z,c)), \ - (I[464] = (T)(img)(_p8##x,_n4##y,z,c)), \ - (I[491] = (T)(img)(_p8##x,_n5##y,z,c)), \ - (I[518] = (T)(img)(_p8##x,_n6##y,z,c)), \ - (I[545] = (T)(img)(_p8##x,_n7##y,z,c)), \ - (I[572] = (T)(img)(_p8##x,_n8##y,z,c)), \ - (I[599] = (T)(img)(_p8##x,_n9##y,z,c)), \ - (I[626] = (T)(img)(_p8##x,_n10##y,z,c)), \ - (I[653] = (T)(img)(_p8##x,_n11##y,z,c)), \ - (I[680] = (T)(img)(_p8##x,_n12##y,z,c)), \ - (I[707] = (T)(img)(_p8##x,_n13##y,z,c)), \ - (I[6] = (T)(img)(_p7##x,_p13##y,z,c)), \ - (I[33] = (T)(img)(_p7##x,_p12##y,z,c)), \ - (I[60] = (T)(img)(_p7##x,_p11##y,z,c)), \ - (I[87] = (T)(img)(_p7##x,_p10##y,z,c)), \ - (I[114] = (T)(img)(_p7##x,_p9##y,z,c)), \ - (I[141] = (T)(img)(_p7##x,_p8##y,z,c)), \ - (I[168] = (T)(img)(_p7##x,_p7##y,z,c)), \ - (I[195] = (T)(img)(_p7##x,_p6##y,z,c)), \ - (I[222] = (T)(img)(_p7##x,_p5##y,z,c)), \ - (I[249] = (T)(img)(_p7##x,_p4##y,z,c)), \ - (I[276] = (T)(img)(_p7##x,_p3##y,z,c)), \ - (I[303] = (T)(img)(_p7##x,_p2##y,z,c)), \ - (I[330] = (T)(img)(_p7##x,_p1##y,z,c)), \ - (I[357] = (T)(img)(_p7##x,y,z,c)), \ - (I[384] = (T)(img)(_p7##x,_n1##y,z,c)), \ - (I[411] = (T)(img)(_p7##x,_n2##y,z,c)), \ - (I[438] = (T)(img)(_p7##x,_n3##y,z,c)), \ - (I[465] = (T)(img)(_p7##x,_n4##y,z,c)), \ - (I[492] = (T)(img)(_p7##x,_n5##y,z,c)), \ - (I[519] = (T)(img)(_p7##x,_n6##y,z,c)), \ - (I[546] = (T)(img)(_p7##x,_n7##y,z,c)), \ - (I[573] = (T)(img)(_p7##x,_n8##y,z,c)), \ - (I[600] = (T)(img)(_p7##x,_n9##y,z,c)), \ - (I[627] = (T)(img)(_p7##x,_n10##y,z,c)), \ - (I[654] = (T)(img)(_p7##x,_n11##y,z,c)), \ - (I[681] = (T)(img)(_p7##x,_n12##y,z,c)), \ - (I[708] = (T)(img)(_p7##x,_n13##y,z,c)), \ - (I[7] = (T)(img)(_p6##x,_p13##y,z,c)), \ - (I[34] = (T)(img)(_p6##x,_p12##y,z,c)), \ - (I[61] = (T)(img)(_p6##x,_p11##y,z,c)), \ - (I[88] = (T)(img)(_p6##x,_p10##y,z,c)), \ - (I[115] = (T)(img)(_p6##x,_p9##y,z,c)), \ - (I[142] = (T)(img)(_p6##x,_p8##y,z,c)), \ - (I[169] = (T)(img)(_p6##x,_p7##y,z,c)), \ - (I[196] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[223] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[250] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[277] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[304] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[331] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[358] = (T)(img)(_p6##x,y,z,c)), \ - (I[385] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[412] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[439] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[466] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[493] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[520] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[547] = (T)(img)(_p6##x,_n7##y,z,c)), \ - (I[574] = (T)(img)(_p6##x,_n8##y,z,c)), \ - (I[601] = (T)(img)(_p6##x,_n9##y,z,c)), \ - (I[628] = (T)(img)(_p6##x,_n10##y,z,c)), \ - (I[655] = (T)(img)(_p6##x,_n11##y,z,c)), \ - (I[682] = (T)(img)(_p6##x,_n12##y,z,c)), \ - (I[709] = (T)(img)(_p6##x,_n13##y,z,c)), \ - (I[8] = (T)(img)(_p5##x,_p13##y,z,c)), \ - (I[35] = (T)(img)(_p5##x,_p12##y,z,c)), \ - (I[62] = (T)(img)(_p5##x,_p11##y,z,c)), \ - (I[89] = (T)(img)(_p5##x,_p10##y,z,c)), \ - (I[116] = (T)(img)(_p5##x,_p9##y,z,c)), \ - (I[143] = (T)(img)(_p5##x,_p8##y,z,c)), \ - (I[170] = (T)(img)(_p5##x,_p7##y,z,c)), \ - (I[197] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[224] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[251] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[278] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[305] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[332] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[359] = (T)(img)(_p5##x,y,z,c)), \ - (I[386] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[413] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[440] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[467] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[494] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[521] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[548] = (T)(img)(_p5##x,_n7##y,z,c)), \ - (I[575] = (T)(img)(_p5##x,_n8##y,z,c)), \ - (I[602] = (T)(img)(_p5##x,_n9##y,z,c)), \ - (I[629] = (T)(img)(_p5##x,_n10##y,z,c)), \ - (I[656] = (T)(img)(_p5##x,_n11##y,z,c)), \ - (I[683] = (T)(img)(_p5##x,_n12##y,z,c)), \ - (I[710] = (T)(img)(_p5##x,_n13##y,z,c)), \ - (I[9] = (T)(img)(_p4##x,_p13##y,z,c)), \ - (I[36] = (T)(img)(_p4##x,_p12##y,z,c)), \ - (I[63] = (T)(img)(_p4##x,_p11##y,z,c)), \ - (I[90] = (T)(img)(_p4##x,_p10##y,z,c)), \ - (I[117] = (T)(img)(_p4##x,_p9##y,z,c)), \ - (I[144] = (T)(img)(_p4##x,_p8##y,z,c)), \ - (I[171] = (T)(img)(_p4##x,_p7##y,z,c)), \ - (I[198] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[225] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[252] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[279] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[306] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[333] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[360] = (T)(img)(_p4##x,y,z,c)), \ - (I[387] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[414] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[441] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[468] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[495] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[522] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[549] = (T)(img)(_p4##x,_n7##y,z,c)), \ - (I[576] = (T)(img)(_p4##x,_n8##y,z,c)), \ - (I[603] = (T)(img)(_p4##x,_n9##y,z,c)), \ - (I[630] = (T)(img)(_p4##x,_n10##y,z,c)), \ - (I[657] = (T)(img)(_p4##x,_n11##y,z,c)), \ - (I[684] = (T)(img)(_p4##x,_n12##y,z,c)), \ - (I[711] = (T)(img)(_p4##x,_n13##y,z,c)), \ - (I[10] = (T)(img)(_p3##x,_p13##y,z,c)), \ - (I[37] = (T)(img)(_p3##x,_p12##y,z,c)), \ - (I[64] = (T)(img)(_p3##x,_p11##y,z,c)), \ - (I[91] = (T)(img)(_p3##x,_p10##y,z,c)), \ - (I[118] = (T)(img)(_p3##x,_p9##y,z,c)), \ - (I[145] = (T)(img)(_p3##x,_p8##y,z,c)), \ - (I[172] = (T)(img)(_p3##x,_p7##y,z,c)), \ - (I[199] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[226] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[253] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[280] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[307] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[334] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[361] = (T)(img)(_p3##x,y,z,c)), \ - (I[388] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[415] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[442] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[469] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[496] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[523] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[550] = (T)(img)(_p3##x,_n7##y,z,c)), \ - (I[577] = (T)(img)(_p3##x,_n8##y,z,c)), \ - (I[604] = (T)(img)(_p3##x,_n9##y,z,c)), \ - (I[631] = (T)(img)(_p3##x,_n10##y,z,c)), \ - (I[658] = (T)(img)(_p3##x,_n11##y,z,c)), \ - (I[685] = (T)(img)(_p3##x,_n12##y,z,c)), \ - (I[712] = (T)(img)(_p3##x,_n13##y,z,c)), \ - (I[11] = (T)(img)(_p2##x,_p13##y,z,c)), \ - (I[38] = (T)(img)(_p2##x,_p12##y,z,c)), \ - (I[65] = (T)(img)(_p2##x,_p11##y,z,c)), \ - (I[92] = (T)(img)(_p2##x,_p10##y,z,c)), \ - (I[119] = (T)(img)(_p2##x,_p9##y,z,c)), \ - (I[146] = (T)(img)(_p2##x,_p8##y,z,c)), \ - (I[173] = (T)(img)(_p2##x,_p7##y,z,c)), \ - (I[200] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[227] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[254] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[281] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[308] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[335] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[362] = (T)(img)(_p2##x,y,z,c)), \ - (I[389] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[416] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[443] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[470] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[497] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[524] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[551] = (T)(img)(_p2##x,_n7##y,z,c)), \ - (I[578] = (T)(img)(_p2##x,_n8##y,z,c)), \ - (I[605] = (T)(img)(_p2##x,_n9##y,z,c)), \ - (I[632] = (T)(img)(_p2##x,_n10##y,z,c)), \ - (I[659] = (T)(img)(_p2##x,_n11##y,z,c)), \ - (I[686] = (T)(img)(_p2##x,_n12##y,z,c)), \ - (I[713] = (T)(img)(_p2##x,_n13##y,z,c)), \ - (I[12] = (T)(img)(_p1##x,_p13##y,z,c)), \ - (I[39] = (T)(img)(_p1##x,_p12##y,z,c)), \ - (I[66] = (T)(img)(_p1##x,_p11##y,z,c)), \ - (I[93] = (T)(img)(_p1##x,_p10##y,z,c)), \ - (I[120] = (T)(img)(_p1##x,_p9##y,z,c)), \ - (I[147] = (T)(img)(_p1##x,_p8##y,z,c)), \ - (I[174] = (T)(img)(_p1##x,_p7##y,z,c)), \ - (I[201] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[228] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[255] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[282] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[309] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[336] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[363] = (T)(img)(_p1##x,y,z,c)), \ - (I[390] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[417] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[444] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[471] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[498] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[525] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[552] = (T)(img)(_p1##x,_n7##y,z,c)), \ - (I[579] = (T)(img)(_p1##x,_n8##y,z,c)), \ - (I[606] = (T)(img)(_p1##x,_n9##y,z,c)), \ - (I[633] = (T)(img)(_p1##x,_n10##y,z,c)), \ - (I[660] = (T)(img)(_p1##x,_n11##y,z,c)), \ - (I[687] = (T)(img)(_p1##x,_n12##y,z,c)), \ - (I[714] = (T)(img)(_p1##x,_n13##y,z,c)), \ - (I[13] = (T)(img)(x,_p13##y,z,c)), \ - (I[40] = (T)(img)(x,_p12##y,z,c)), \ - (I[67] = (T)(img)(x,_p11##y,z,c)), \ - (I[94] = (T)(img)(x,_p10##y,z,c)), \ - (I[121] = (T)(img)(x,_p9##y,z,c)), \ - (I[148] = (T)(img)(x,_p8##y,z,c)), \ - (I[175] = (T)(img)(x,_p7##y,z,c)), \ - (I[202] = (T)(img)(x,_p6##y,z,c)), \ - (I[229] = (T)(img)(x,_p5##y,z,c)), \ - (I[256] = (T)(img)(x,_p4##y,z,c)), \ - (I[283] = (T)(img)(x,_p3##y,z,c)), \ - (I[310] = (T)(img)(x,_p2##y,z,c)), \ - (I[337] = (T)(img)(x,_p1##y,z,c)), \ - (I[364] = (T)(img)(x,y,z,c)), \ - (I[391] = (T)(img)(x,_n1##y,z,c)), \ - (I[418] = (T)(img)(x,_n2##y,z,c)), \ - (I[445] = (T)(img)(x,_n3##y,z,c)), \ - (I[472] = (T)(img)(x,_n4##y,z,c)), \ - (I[499] = (T)(img)(x,_n5##y,z,c)), \ - (I[526] = (T)(img)(x,_n6##y,z,c)), \ - (I[553] = (T)(img)(x,_n7##y,z,c)), \ - (I[580] = (T)(img)(x,_n8##y,z,c)), \ - (I[607] = (T)(img)(x,_n9##y,z,c)), \ - (I[634] = (T)(img)(x,_n10##y,z,c)), \ - (I[661] = (T)(img)(x,_n11##y,z,c)), \ - (I[688] = (T)(img)(x,_n12##y,z,c)), \ - (I[715] = (T)(img)(x,_n13##y,z,c)), \ - (I[14] = (T)(img)(_n1##x,_p13##y,z,c)), \ - (I[41] = (T)(img)(_n1##x,_p12##y,z,c)), \ - (I[68] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[95] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[122] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[149] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[176] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[203] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[230] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[257] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[284] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[311] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[338] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[365] = (T)(img)(_n1##x,y,z,c)), \ - (I[392] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[419] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[446] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[473] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[500] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[527] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[554] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[581] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[608] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[635] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[662] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[689] = (T)(img)(_n1##x,_n12##y,z,c)), \ - (I[716] = (T)(img)(_n1##x,_n13##y,z,c)), \ - (I[15] = (T)(img)(_n2##x,_p13##y,z,c)), \ - (I[42] = (T)(img)(_n2##x,_p12##y,z,c)), \ - (I[69] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[96] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[123] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[150] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[177] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[204] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[231] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[258] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[285] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[312] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[339] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[366] = (T)(img)(_n2##x,y,z,c)), \ - (I[393] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[420] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[447] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[474] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[501] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[528] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[555] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[582] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[609] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[636] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[663] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[690] = (T)(img)(_n2##x,_n12##y,z,c)), \ - (I[717] = (T)(img)(_n2##x,_n13##y,z,c)), \ - (I[16] = (T)(img)(_n3##x,_p13##y,z,c)), \ - (I[43] = (T)(img)(_n3##x,_p12##y,z,c)), \ - (I[70] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[97] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[124] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[151] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[178] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[205] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[232] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[259] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[286] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[313] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[340] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[367] = (T)(img)(_n3##x,y,z,c)), \ - (I[394] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[421] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[448] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[475] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[502] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[529] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[556] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[583] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[610] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[637] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[664] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[691] = (T)(img)(_n3##x,_n12##y,z,c)), \ - (I[718] = (T)(img)(_n3##x,_n13##y,z,c)), \ - (I[17] = (T)(img)(_n4##x,_p13##y,z,c)), \ - (I[44] = (T)(img)(_n4##x,_p12##y,z,c)), \ - (I[71] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[98] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[125] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[152] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[179] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[206] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[233] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[260] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[287] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[314] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[341] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[368] = (T)(img)(_n4##x,y,z,c)), \ - (I[395] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[422] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[449] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[476] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[503] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[530] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[557] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[584] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[611] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[638] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[665] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[692] = (T)(img)(_n4##x,_n12##y,z,c)), \ - (I[719] = (T)(img)(_n4##x,_n13##y,z,c)), \ - (I[18] = (T)(img)(_n5##x,_p13##y,z,c)), \ - (I[45] = (T)(img)(_n5##x,_p12##y,z,c)), \ - (I[72] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[99] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[126] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[153] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[180] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[207] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[234] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[261] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[288] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[315] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[342] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[369] = (T)(img)(_n5##x,y,z,c)), \ - (I[396] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[423] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[450] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[477] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[504] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[531] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[558] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[585] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[612] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[639] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[666] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[693] = (T)(img)(_n5##x,_n12##y,z,c)), \ - (I[720] = (T)(img)(_n5##x,_n13##y,z,c)), \ - (I[19] = (T)(img)(_n6##x,_p13##y,z,c)), \ - (I[46] = (T)(img)(_n6##x,_p12##y,z,c)), \ - (I[73] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[100] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[127] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[154] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[181] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[208] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[235] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[262] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[289] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[316] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[343] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[370] = (T)(img)(_n6##x,y,z,c)), \ - (I[397] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[424] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[451] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[478] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[505] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[532] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[559] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[586] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[613] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[640] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[667] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[694] = (T)(img)(_n6##x,_n12##y,z,c)), \ - (I[721] = (T)(img)(_n6##x,_n13##y,z,c)), \ - (I[20] = (T)(img)(_n7##x,_p13##y,z,c)), \ - (I[47] = (T)(img)(_n7##x,_p12##y,z,c)), \ - (I[74] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[101] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[128] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[155] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[182] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[209] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[236] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[263] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[290] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[317] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[344] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[371] = (T)(img)(_n7##x,y,z,c)), \ - (I[398] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[425] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[452] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[479] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[506] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[533] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[560] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[587] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[614] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[641] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[668] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[695] = (T)(img)(_n7##x,_n12##y,z,c)), \ - (I[722] = (T)(img)(_n7##x,_n13##y,z,c)), \ - (I[21] = (T)(img)(_n8##x,_p13##y,z,c)), \ - (I[48] = (T)(img)(_n8##x,_p12##y,z,c)), \ - (I[75] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[102] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[129] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[156] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[183] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[210] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[237] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[264] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[291] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[318] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[345] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[372] = (T)(img)(_n8##x,y,z,c)), \ - (I[399] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[426] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[453] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[480] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[507] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[534] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[561] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[588] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[615] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[642] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[669] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[696] = (T)(img)(_n8##x,_n12##y,z,c)), \ - (I[723] = (T)(img)(_n8##x,_n13##y,z,c)), \ - (I[22] = (T)(img)(_n9##x,_p13##y,z,c)), \ - (I[49] = (T)(img)(_n9##x,_p12##y,z,c)), \ - (I[76] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[103] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[130] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[157] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[184] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[211] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[238] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[265] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[292] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[319] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[346] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[373] = (T)(img)(_n9##x,y,z,c)), \ - (I[400] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[427] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[454] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[481] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[508] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[535] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[562] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[589] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[616] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[643] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[670] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[697] = (T)(img)(_n9##x,_n12##y,z,c)), \ - (I[724] = (T)(img)(_n9##x,_n13##y,z,c)), \ - (I[23] = (T)(img)(_n10##x,_p13##y,z,c)), \ - (I[50] = (T)(img)(_n10##x,_p12##y,z,c)), \ - (I[77] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[104] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[131] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[158] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[185] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[212] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[239] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[266] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[293] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[320] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[347] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[374] = (T)(img)(_n10##x,y,z,c)), \ - (I[401] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[428] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[455] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[482] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[509] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[536] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[563] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[590] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[617] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[644] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[671] = (T)(img)(_n10##x,_n11##y,z,c)), \ - (I[698] = (T)(img)(_n10##x,_n12##y,z,c)), \ - (I[725] = (T)(img)(_n10##x,_n13##y,z,c)), \ - (I[24] = (T)(img)(_n11##x,_p13##y,z,c)), \ - (I[51] = (T)(img)(_n11##x,_p12##y,z,c)), \ - (I[78] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[105] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[132] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[159] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[186] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[213] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[240] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[267] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[294] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[321] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[348] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[375] = (T)(img)(_n11##x,y,z,c)), \ - (I[402] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[429] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[456] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[483] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[510] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[537] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[564] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[591] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[618] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[645] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[672] = (T)(img)(_n11##x,_n11##y,z,c)), \ - (I[699] = (T)(img)(_n11##x,_n12##y,z,c)), \ - (I[726] = (T)(img)(_n11##x,_n13##y,z,c)), \ - (I[25] = (T)(img)(_n12##x,_p13##y,z,c)), \ - (I[52] = (T)(img)(_n12##x,_p12##y,z,c)), \ - (I[79] = (T)(img)(_n12##x,_p11##y,z,c)), \ - (I[106] = (T)(img)(_n12##x,_p10##y,z,c)), \ - (I[133] = (T)(img)(_n12##x,_p9##y,z,c)), \ - (I[160] = (T)(img)(_n12##x,_p8##y,z,c)), \ - (I[187] = (T)(img)(_n12##x,_p7##y,z,c)), \ - (I[214] = (T)(img)(_n12##x,_p6##y,z,c)), \ - (I[241] = (T)(img)(_n12##x,_p5##y,z,c)), \ - (I[268] = (T)(img)(_n12##x,_p4##y,z,c)), \ - (I[295] = (T)(img)(_n12##x,_p3##y,z,c)), \ - (I[322] = (T)(img)(_n12##x,_p2##y,z,c)), \ - (I[349] = (T)(img)(_n12##x,_p1##y,z,c)), \ - (I[376] = (T)(img)(_n12##x,y,z,c)), \ - (I[403] = (T)(img)(_n12##x,_n1##y,z,c)), \ - (I[430] = (T)(img)(_n12##x,_n2##y,z,c)), \ - (I[457] = (T)(img)(_n12##x,_n3##y,z,c)), \ - (I[484] = (T)(img)(_n12##x,_n4##y,z,c)), \ - (I[511] = (T)(img)(_n12##x,_n5##y,z,c)), \ - (I[538] = (T)(img)(_n12##x,_n6##y,z,c)), \ - (I[565] = (T)(img)(_n12##x,_n7##y,z,c)), \ - (I[592] = (T)(img)(_n12##x,_n8##y,z,c)), \ - (I[619] = (T)(img)(_n12##x,_n9##y,z,c)), \ - (I[646] = (T)(img)(_n12##x,_n10##y,z,c)), \ - (I[673] = (T)(img)(_n12##x,_n11##y,z,c)), \ - (I[700] = (T)(img)(_n12##x,_n12##y,z,c)), \ - (I[727] = (T)(img)(_n12##x,_n13##y,z,c)), \ - x + 13>=(img).width()?(img).width() - 1:x + 13); \ - x<=(int)(x1) && ((_n13##x<(img).width() && ( \ - (I[26] = (T)(img)(_n13##x,_p13##y,z,c)), \ - (I[53] = (T)(img)(_n13##x,_p12##y,z,c)), \ - (I[80] = (T)(img)(_n13##x,_p11##y,z,c)), \ - (I[107] = (T)(img)(_n13##x,_p10##y,z,c)), \ - (I[134] = (T)(img)(_n13##x,_p9##y,z,c)), \ - (I[161] = (T)(img)(_n13##x,_p8##y,z,c)), \ - (I[188] = (T)(img)(_n13##x,_p7##y,z,c)), \ - (I[215] = (T)(img)(_n13##x,_p6##y,z,c)), \ - (I[242] = (T)(img)(_n13##x,_p5##y,z,c)), \ - (I[269] = (T)(img)(_n13##x,_p4##y,z,c)), \ - (I[296] = (T)(img)(_n13##x,_p3##y,z,c)), \ - (I[323] = (T)(img)(_n13##x,_p2##y,z,c)), \ - (I[350] = (T)(img)(_n13##x,_p1##y,z,c)), \ - (I[377] = (T)(img)(_n13##x,y,z,c)), \ - (I[404] = (T)(img)(_n13##x,_n1##y,z,c)), \ - (I[431] = (T)(img)(_n13##x,_n2##y,z,c)), \ - (I[458] = (T)(img)(_n13##x,_n3##y,z,c)), \ - (I[485] = (T)(img)(_n13##x,_n4##y,z,c)), \ - (I[512] = (T)(img)(_n13##x,_n5##y,z,c)), \ - (I[539] = (T)(img)(_n13##x,_n6##y,z,c)), \ - (I[566] = (T)(img)(_n13##x,_n7##y,z,c)), \ - (I[593] = (T)(img)(_n13##x,_n8##y,z,c)), \ - (I[620] = (T)(img)(_n13##x,_n9##y,z,c)), \ - (I[647] = (T)(img)(_n13##x,_n10##y,z,c)), \ - (I[674] = (T)(img)(_n13##x,_n11##y,z,c)), \ - (I[701] = (T)(img)(_n13##x,_n12##y,z,c)), \ - (I[728] = (T)(img)(_n13##x,_n13##y,z,c)),1)) || \ - _n12##x==--_n13##x || _n11##x==--_n12##x || _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n13##x = _n12##x = _n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], \ - I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], \ - I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], \ - I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], \ - I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], \ - I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], \ - I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], \ - I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], \ - I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], \ - I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], \ - I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], \ - I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], \ - I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], \ - I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], \ - I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], \ - I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], I[415] = I[416], I[416] = I[417], I[417] = I[418], I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], \ - I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], I[447] = I[448], I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], \ - I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], I[463] = I[464], I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], I[479] = I[480], I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], \ - I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], I[493] = I[494], I[494] = I[495], I[495] = I[496], I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], I[503] = I[504], I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], I[511] = I[512], \ - I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], I[519] = I[520], I[520] = I[521], I[521] = I[522], I[522] = I[523], I[523] = I[524], I[524] = I[525], I[525] = I[526], I[526] = I[527], I[527] = I[528], I[528] = I[529], I[529] = I[530], I[530] = I[531], I[531] = I[532], I[532] = I[533], I[533] = I[534], I[534] = I[535], I[535] = I[536], I[536] = I[537], I[537] = I[538], I[538] = I[539], \ - I[540] = I[541], I[541] = I[542], I[542] = I[543], I[543] = I[544], I[544] = I[545], I[545] = I[546], I[546] = I[547], I[547] = I[548], I[548] = I[549], I[549] = I[550], I[550] = I[551], I[551] = I[552], I[552] = I[553], I[553] = I[554], I[554] = I[555], I[555] = I[556], I[556] = I[557], I[557] = I[558], I[558] = I[559], I[559] = I[560], I[560] = I[561], I[561] = I[562], I[562] = I[563], I[563] = I[564], I[564] = I[565], I[565] = I[566], \ - I[567] = I[568], I[568] = I[569], I[569] = I[570], I[570] = I[571], I[571] = I[572], I[572] = I[573], I[573] = I[574], I[574] = I[575], I[575] = I[576], I[576] = I[577], I[577] = I[578], I[578] = I[579], I[579] = I[580], I[580] = I[581], I[581] = I[582], I[582] = I[583], I[583] = I[584], I[584] = I[585], I[585] = I[586], I[586] = I[587], I[587] = I[588], I[588] = I[589], I[589] = I[590], I[590] = I[591], I[591] = I[592], I[592] = I[593], \ - I[594] = I[595], I[595] = I[596], I[596] = I[597], I[597] = I[598], I[598] = I[599], I[599] = I[600], I[600] = I[601], I[601] = I[602], I[602] = I[603], I[603] = I[604], I[604] = I[605], I[605] = I[606], I[606] = I[607], I[607] = I[608], I[608] = I[609], I[609] = I[610], I[610] = I[611], I[611] = I[612], I[612] = I[613], I[613] = I[614], I[614] = I[615], I[615] = I[616], I[616] = I[617], I[617] = I[618], I[618] = I[619], I[619] = I[620], \ - I[621] = I[622], I[622] = I[623], I[623] = I[624], I[624] = I[625], I[625] = I[626], I[626] = I[627], I[627] = I[628], I[628] = I[629], I[629] = I[630], I[630] = I[631], I[631] = I[632], I[632] = I[633], I[633] = I[634], I[634] = I[635], I[635] = I[636], I[636] = I[637], I[637] = I[638], I[638] = I[639], I[639] = I[640], I[640] = I[641], I[641] = I[642], I[642] = I[643], I[643] = I[644], I[644] = I[645], I[645] = I[646], I[646] = I[647], \ - I[648] = I[649], I[649] = I[650], I[650] = I[651], I[651] = I[652], I[652] = I[653], I[653] = I[654], I[654] = I[655], I[655] = I[656], I[656] = I[657], I[657] = I[658], I[658] = I[659], I[659] = I[660], I[660] = I[661], I[661] = I[662], I[662] = I[663], I[663] = I[664], I[664] = I[665], I[665] = I[666], I[666] = I[667], I[667] = I[668], I[668] = I[669], I[669] = I[670], I[670] = I[671], I[671] = I[672], I[672] = I[673], I[673] = I[674], \ - I[675] = I[676], I[676] = I[677], I[677] = I[678], I[678] = I[679], I[679] = I[680], I[680] = I[681], I[681] = I[682], I[682] = I[683], I[683] = I[684], I[684] = I[685], I[685] = I[686], I[686] = I[687], I[687] = I[688], I[688] = I[689], I[689] = I[690], I[690] = I[691], I[691] = I[692], I[692] = I[693], I[693] = I[694], I[694] = I[695], I[695] = I[696], I[696] = I[697], I[697] = I[698], I[698] = I[699], I[699] = I[700], I[700] = I[701], \ - I[702] = I[703], I[703] = I[704], I[704] = I[705], I[705] = I[706], I[706] = I[707], I[707] = I[708], I[708] = I[709], I[709] = I[710], I[710] = I[711], I[711] = I[712], I[712] = I[713], I[713] = I[714], I[714] = I[715], I[715] = I[716], I[716] = I[717], I[717] = I[718], I[718] = I[719], I[719] = I[720], I[720] = I[721], I[721] = I[722], I[722] = I[723], I[723] = I[724], I[724] = I[725], I[725] = I[726], I[726] = I[727], I[727] = I[728], \ - _p13##x = _p12##x, _p12##x = _p11##x, _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x, ++_n12##x, ++_n13##x) - -#define cimg_get27x27(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p13##x,_p13##y,z,c), I[1] = (T)(img)(_p12##x,_p13##y,z,c), I[2] = (T)(img)(_p11##x,_p13##y,z,c), I[3] = (T)(img)(_p10##x,_p13##y,z,c), I[4] = (T)(img)(_p9##x,_p13##y,z,c), I[5] = (T)(img)(_p8##x,_p13##y,z,c), I[6] = (T)(img)(_p7##x,_p13##y,z,c), I[7] = (T)(img)(_p6##x,_p13##y,z,c), I[8] = (T)(img)(_p5##x,_p13##y,z,c), I[9] = (T)(img)(_p4##x,_p13##y,z,c), I[10] = (T)(img)(_p3##x,_p13##y,z,c), I[11] = (T)(img)(_p2##x,_p13##y,z,c), I[12] = (T)(img)(_p1##x,_p13##y,z,c), I[13] = (T)(img)(x,_p13##y,z,c), I[14] = (T)(img)(_n1##x,_p13##y,z,c), I[15] = (T)(img)(_n2##x,_p13##y,z,c), I[16] = (T)(img)(_n3##x,_p13##y,z,c), I[17] = (T)(img)(_n4##x,_p13##y,z,c), I[18] = (T)(img)(_n5##x,_p13##y,z,c), I[19] = (T)(img)(_n6##x,_p13##y,z,c), I[20] = (T)(img)(_n7##x,_p13##y,z,c), I[21] = (T)(img)(_n8##x,_p13##y,z,c), I[22] = (T)(img)(_n9##x,_p13##y,z,c), I[23] = (T)(img)(_n10##x,_p13##y,z,c), I[24] = (T)(img)(_n11##x,_p13##y,z,c), I[25] = (T)(img)(_n12##x,_p13##y,z,c), I[26] = (T)(img)(_n13##x,_p13##y,z,c), \ - I[27] = (T)(img)(_p13##x,_p12##y,z,c), I[28] = (T)(img)(_p12##x,_p12##y,z,c), I[29] = (T)(img)(_p11##x,_p12##y,z,c), I[30] = (T)(img)(_p10##x,_p12##y,z,c), I[31] = (T)(img)(_p9##x,_p12##y,z,c), I[32] = (T)(img)(_p8##x,_p12##y,z,c), I[33] = (T)(img)(_p7##x,_p12##y,z,c), I[34] = (T)(img)(_p6##x,_p12##y,z,c), I[35] = (T)(img)(_p5##x,_p12##y,z,c), I[36] = (T)(img)(_p4##x,_p12##y,z,c), I[37] = (T)(img)(_p3##x,_p12##y,z,c), I[38] = (T)(img)(_p2##x,_p12##y,z,c), I[39] = (T)(img)(_p1##x,_p12##y,z,c), I[40] = (T)(img)(x,_p12##y,z,c), I[41] = (T)(img)(_n1##x,_p12##y,z,c), I[42] = (T)(img)(_n2##x,_p12##y,z,c), I[43] = (T)(img)(_n3##x,_p12##y,z,c), I[44] = (T)(img)(_n4##x,_p12##y,z,c), I[45] = (T)(img)(_n5##x,_p12##y,z,c), I[46] = (T)(img)(_n6##x,_p12##y,z,c), I[47] = (T)(img)(_n7##x,_p12##y,z,c), I[48] = (T)(img)(_n8##x,_p12##y,z,c), I[49] = (T)(img)(_n9##x,_p12##y,z,c), I[50] = (T)(img)(_n10##x,_p12##y,z,c), I[51] = (T)(img)(_n11##x,_p12##y,z,c), I[52] = (T)(img)(_n12##x,_p12##y,z,c), I[53] = (T)(img)(_n13##x,_p12##y,z,c), \ - I[54] = (T)(img)(_p13##x,_p11##y,z,c), I[55] = (T)(img)(_p12##x,_p11##y,z,c), I[56] = (T)(img)(_p11##x,_p11##y,z,c), I[57] = (T)(img)(_p10##x,_p11##y,z,c), I[58] = (T)(img)(_p9##x,_p11##y,z,c), I[59] = (T)(img)(_p8##x,_p11##y,z,c), I[60] = (T)(img)(_p7##x,_p11##y,z,c), I[61] = (T)(img)(_p6##x,_p11##y,z,c), I[62] = (T)(img)(_p5##x,_p11##y,z,c), I[63] = (T)(img)(_p4##x,_p11##y,z,c), I[64] = (T)(img)(_p3##x,_p11##y,z,c), I[65] = (T)(img)(_p2##x,_p11##y,z,c), I[66] = (T)(img)(_p1##x,_p11##y,z,c), I[67] = (T)(img)(x,_p11##y,z,c), I[68] = (T)(img)(_n1##x,_p11##y,z,c), I[69] = (T)(img)(_n2##x,_p11##y,z,c), I[70] = (T)(img)(_n3##x,_p11##y,z,c), I[71] = (T)(img)(_n4##x,_p11##y,z,c), I[72] = (T)(img)(_n5##x,_p11##y,z,c), I[73] = (T)(img)(_n6##x,_p11##y,z,c), I[74] = (T)(img)(_n7##x,_p11##y,z,c), I[75] = (T)(img)(_n8##x,_p11##y,z,c), I[76] = (T)(img)(_n9##x,_p11##y,z,c), I[77] = (T)(img)(_n10##x,_p11##y,z,c), I[78] = (T)(img)(_n11##x,_p11##y,z,c), I[79] = (T)(img)(_n12##x,_p11##y,z,c), I[80] = (T)(img)(_n13##x,_p11##y,z,c), \ - I[81] = (T)(img)(_p13##x,_p10##y,z,c), I[82] = (T)(img)(_p12##x,_p10##y,z,c), I[83] = (T)(img)(_p11##x,_p10##y,z,c), I[84] = (T)(img)(_p10##x,_p10##y,z,c), I[85] = (T)(img)(_p9##x,_p10##y,z,c), I[86] = (T)(img)(_p8##x,_p10##y,z,c), I[87] = (T)(img)(_p7##x,_p10##y,z,c), I[88] = (T)(img)(_p6##x,_p10##y,z,c), I[89] = (T)(img)(_p5##x,_p10##y,z,c), I[90] = (T)(img)(_p4##x,_p10##y,z,c), I[91] = (T)(img)(_p3##x,_p10##y,z,c), I[92] = (T)(img)(_p2##x,_p10##y,z,c), I[93] = (T)(img)(_p1##x,_p10##y,z,c), I[94] = (T)(img)(x,_p10##y,z,c), I[95] = (T)(img)(_n1##x,_p10##y,z,c), I[96] = (T)(img)(_n2##x,_p10##y,z,c), I[97] = (T)(img)(_n3##x,_p10##y,z,c), I[98] = (T)(img)(_n4##x,_p10##y,z,c), I[99] = (T)(img)(_n5##x,_p10##y,z,c), I[100] = (T)(img)(_n6##x,_p10##y,z,c), I[101] = (T)(img)(_n7##x,_p10##y,z,c), I[102] = (T)(img)(_n8##x,_p10##y,z,c), I[103] = (T)(img)(_n9##x,_p10##y,z,c), I[104] = (T)(img)(_n10##x,_p10##y,z,c), I[105] = (T)(img)(_n11##x,_p10##y,z,c), I[106] = (T)(img)(_n12##x,_p10##y,z,c), I[107] = (T)(img)(_n13##x,_p10##y,z,c), \ - I[108] = (T)(img)(_p13##x,_p9##y,z,c), I[109] = (T)(img)(_p12##x,_p9##y,z,c), I[110] = (T)(img)(_p11##x,_p9##y,z,c), I[111] = (T)(img)(_p10##x,_p9##y,z,c), I[112] = (T)(img)(_p9##x,_p9##y,z,c), I[113] = (T)(img)(_p8##x,_p9##y,z,c), I[114] = (T)(img)(_p7##x,_p9##y,z,c), I[115] = (T)(img)(_p6##x,_p9##y,z,c), I[116] = (T)(img)(_p5##x,_p9##y,z,c), I[117] = (T)(img)(_p4##x,_p9##y,z,c), I[118] = (T)(img)(_p3##x,_p9##y,z,c), I[119] = (T)(img)(_p2##x,_p9##y,z,c), I[120] = (T)(img)(_p1##x,_p9##y,z,c), I[121] = (T)(img)(x,_p9##y,z,c), I[122] = (T)(img)(_n1##x,_p9##y,z,c), I[123] = (T)(img)(_n2##x,_p9##y,z,c), I[124] = (T)(img)(_n3##x,_p9##y,z,c), I[125] = (T)(img)(_n4##x,_p9##y,z,c), I[126] = (T)(img)(_n5##x,_p9##y,z,c), I[127] = (T)(img)(_n6##x,_p9##y,z,c), I[128] = (T)(img)(_n7##x,_p9##y,z,c), I[129] = (T)(img)(_n8##x,_p9##y,z,c), I[130] = (T)(img)(_n9##x,_p9##y,z,c), I[131] = (T)(img)(_n10##x,_p9##y,z,c), I[132] = (T)(img)(_n11##x,_p9##y,z,c), I[133] = (T)(img)(_n12##x,_p9##y,z,c), I[134] = (T)(img)(_n13##x,_p9##y,z,c), \ - I[135] = (T)(img)(_p13##x,_p8##y,z,c), I[136] = (T)(img)(_p12##x,_p8##y,z,c), I[137] = (T)(img)(_p11##x,_p8##y,z,c), I[138] = (T)(img)(_p10##x,_p8##y,z,c), I[139] = (T)(img)(_p9##x,_p8##y,z,c), I[140] = (T)(img)(_p8##x,_p8##y,z,c), I[141] = (T)(img)(_p7##x,_p8##y,z,c), I[142] = (T)(img)(_p6##x,_p8##y,z,c), I[143] = (T)(img)(_p5##x,_p8##y,z,c), I[144] = (T)(img)(_p4##x,_p8##y,z,c), I[145] = (T)(img)(_p3##x,_p8##y,z,c), I[146] = (T)(img)(_p2##x,_p8##y,z,c), I[147] = (T)(img)(_p1##x,_p8##y,z,c), I[148] = (T)(img)(x,_p8##y,z,c), I[149] = (T)(img)(_n1##x,_p8##y,z,c), I[150] = (T)(img)(_n2##x,_p8##y,z,c), I[151] = (T)(img)(_n3##x,_p8##y,z,c), I[152] = (T)(img)(_n4##x,_p8##y,z,c), I[153] = (T)(img)(_n5##x,_p8##y,z,c), I[154] = (T)(img)(_n6##x,_p8##y,z,c), I[155] = (T)(img)(_n7##x,_p8##y,z,c), I[156] = (T)(img)(_n8##x,_p8##y,z,c), I[157] = (T)(img)(_n9##x,_p8##y,z,c), I[158] = (T)(img)(_n10##x,_p8##y,z,c), I[159] = (T)(img)(_n11##x,_p8##y,z,c), I[160] = (T)(img)(_n12##x,_p8##y,z,c), I[161] = (T)(img)(_n13##x,_p8##y,z,c), \ - I[162] = (T)(img)(_p13##x,_p7##y,z,c), I[163] = (T)(img)(_p12##x,_p7##y,z,c), I[164] = (T)(img)(_p11##x,_p7##y,z,c), I[165] = (T)(img)(_p10##x,_p7##y,z,c), I[166] = (T)(img)(_p9##x,_p7##y,z,c), I[167] = (T)(img)(_p8##x,_p7##y,z,c), I[168] = (T)(img)(_p7##x,_p7##y,z,c), I[169] = (T)(img)(_p6##x,_p7##y,z,c), I[170] = (T)(img)(_p5##x,_p7##y,z,c), I[171] = (T)(img)(_p4##x,_p7##y,z,c), I[172] = (T)(img)(_p3##x,_p7##y,z,c), I[173] = (T)(img)(_p2##x,_p7##y,z,c), I[174] = (T)(img)(_p1##x,_p7##y,z,c), I[175] = (T)(img)(x,_p7##y,z,c), I[176] = (T)(img)(_n1##x,_p7##y,z,c), I[177] = (T)(img)(_n2##x,_p7##y,z,c), I[178] = (T)(img)(_n3##x,_p7##y,z,c), I[179] = (T)(img)(_n4##x,_p7##y,z,c), I[180] = (T)(img)(_n5##x,_p7##y,z,c), I[181] = (T)(img)(_n6##x,_p7##y,z,c), I[182] = (T)(img)(_n7##x,_p7##y,z,c), I[183] = (T)(img)(_n8##x,_p7##y,z,c), I[184] = (T)(img)(_n9##x,_p7##y,z,c), I[185] = (T)(img)(_n10##x,_p7##y,z,c), I[186] = (T)(img)(_n11##x,_p7##y,z,c), I[187] = (T)(img)(_n12##x,_p7##y,z,c), I[188] = (T)(img)(_n13##x,_p7##y,z,c), \ - I[189] = (T)(img)(_p13##x,_p6##y,z,c), I[190] = (T)(img)(_p12##x,_p6##y,z,c), I[191] = (T)(img)(_p11##x,_p6##y,z,c), I[192] = (T)(img)(_p10##x,_p6##y,z,c), I[193] = (T)(img)(_p9##x,_p6##y,z,c), I[194] = (T)(img)(_p8##x,_p6##y,z,c), I[195] = (T)(img)(_p7##x,_p6##y,z,c), I[196] = (T)(img)(_p6##x,_p6##y,z,c), I[197] = (T)(img)(_p5##x,_p6##y,z,c), I[198] = (T)(img)(_p4##x,_p6##y,z,c), I[199] = (T)(img)(_p3##x,_p6##y,z,c), I[200] = (T)(img)(_p2##x,_p6##y,z,c), I[201] = (T)(img)(_p1##x,_p6##y,z,c), I[202] = (T)(img)(x,_p6##y,z,c), I[203] = (T)(img)(_n1##x,_p6##y,z,c), I[204] = (T)(img)(_n2##x,_p6##y,z,c), I[205] = (T)(img)(_n3##x,_p6##y,z,c), I[206] = (T)(img)(_n4##x,_p6##y,z,c), I[207] = (T)(img)(_n5##x,_p6##y,z,c), I[208] = (T)(img)(_n6##x,_p6##y,z,c), I[209] = (T)(img)(_n7##x,_p6##y,z,c), I[210] = (T)(img)(_n8##x,_p6##y,z,c), I[211] = (T)(img)(_n9##x,_p6##y,z,c), I[212] = (T)(img)(_n10##x,_p6##y,z,c), I[213] = (T)(img)(_n11##x,_p6##y,z,c), I[214] = (T)(img)(_n12##x,_p6##y,z,c), I[215] = (T)(img)(_n13##x,_p6##y,z,c), \ - I[216] = (T)(img)(_p13##x,_p5##y,z,c), I[217] = (T)(img)(_p12##x,_p5##y,z,c), I[218] = (T)(img)(_p11##x,_p5##y,z,c), I[219] = (T)(img)(_p10##x,_p5##y,z,c), I[220] = (T)(img)(_p9##x,_p5##y,z,c), I[221] = (T)(img)(_p8##x,_p5##y,z,c), I[222] = (T)(img)(_p7##x,_p5##y,z,c), I[223] = (T)(img)(_p6##x,_p5##y,z,c), I[224] = (T)(img)(_p5##x,_p5##y,z,c), I[225] = (T)(img)(_p4##x,_p5##y,z,c), I[226] = (T)(img)(_p3##x,_p5##y,z,c), I[227] = (T)(img)(_p2##x,_p5##y,z,c), I[228] = (T)(img)(_p1##x,_p5##y,z,c), I[229] = (T)(img)(x,_p5##y,z,c), I[230] = (T)(img)(_n1##x,_p5##y,z,c), I[231] = (T)(img)(_n2##x,_p5##y,z,c), I[232] = (T)(img)(_n3##x,_p5##y,z,c), I[233] = (T)(img)(_n4##x,_p5##y,z,c), I[234] = (T)(img)(_n5##x,_p5##y,z,c), I[235] = (T)(img)(_n6##x,_p5##y,z,c), I[236] = (T)(img)(_n7##x,_p5##y,z,c), I[237] = (T)(img)(_n8##x,_p5##y,z,c), I[238] = (T)(img)(_n9##x,_p5##y,z,c), I[239] = (T)(img)(_n10##x,_p5##y,z,c), I[240] = (T)(img)(_n11##x,_p5##y,z,c), I[241] = (T)(img)(_n12##x,_p5##y,z,c), I[242] = (T)(img)(_n13##x,_p5##y,z,c), \ - I[243] = (T)(img)(_p13##x,_p4##y,z,c), I[244] = (T)(img)(_p12##x,_p4##y,z,c), I[245] = (T)(img)(_p11##x,_p4##y,z,c), I[246] = (T)(img)(_p10##x,_p4##y,z,c), I[247] = (T)(img)(_p9##x,_p4##y,z,c), I[248] = (T)(img)(_p8##x,_p4##y,z,c), I[249] = (T)(img)(_p7##x,_p4##y,z,c), I[250] = (T)(img)(_p6##x,_p4##y,z,c), I[251] = (T)(img)(_p5##x,_p4##y,z,c), I[252] = (T)(img)(_p4##x,_p4##y,z,c), I[253] = (T)(img)(_p3##x,_p4##y,z,c), I[254] = (T)(img)(_p2##x,_p4##y,z,c), I[255] = (T)(img)(_p1##x,_p4##y,z,c), I[256] = (T)(img)(x,_p4##y,z,c), I[257] = (T)(img)(_n1##x,_p4##y,z,c), I[258] = (T)(img)(_n2##x,_p4##y,z,c), I[259] = (T)(img)(_n3##x,_p4##y,z,c), I[260] = (T)(img)(_n4##x,_p4##y,z,c), I[261] = (T)(img)(_n5##x,_p4##y,z,c), I[262] = (T)(img)(_n6##x,_p4##y,z,c), I[263] = (T)(img)(_n7##x,_p4##y,z,c), I[264] = (T)(img)(_n8##x,_p4##y,z,c), I[265] = (T)(img)(_n9##x,_p4##y,z,c), I[266] = (T)(img)(_n10##x,_p4##y,z,c), I[267] = (T)(img)(_n11##x,_p4##y,z,c), I[268] = (T)(img)(_n12##x,_p4##y,z,c), I[269] = (T)(img)(_n13##x,_p4##y,z,c), \ - I[270] = (T)(img)(_p13##x,_p3##y,z,c), I[271] = (T)(img)(_p12##x,_p3##y,z,c), I[272] = (T)(img)(_p11##x,_p3##y,z,c), I[273] = (T)(img)(_p10##x,_p3##y,z,c), I[274] = (T)(img)(_p9##x,_p3##y,z,c), I[275] = (T)(img)(_p8##x,_p3##y,z,c), I[276] = (T)(img)(_p7##x,_p3##y,z,c), I[277] = (T)(img)(_p6##x,_p3##y,z,c), I[278] = (T)(img)(_p5##x,_p3##y,z,c), I[279] = (T)(img)(_p4##x,_p3##y,z,c), I[280] = (T)(img)(_p3##x,_p3##y,z,c), I[281] = (T)(img)(_p2##x,_p3##y,z,c), I[282] = (T)(img)(_p1##x,_p3##y,z,c), I[283] = (T)(img)(x,_p3##y,z,c), I[284] = (T)(img)(_n1##x,_p3##y,z,c), I[285] = (T)(img)(_n2##x,_p3##y,z,c), I[286] = (T)(img)(_n3##x,_p3##y,z,c), I[287] = (T)(img)(_n4##x,_p3##y,z,c), I[288] = (T)(img)(_n5##x,_p3##y,z,c), I[289] = (T)(img)(_n6##x,_p3##y,z,c), I[290] = (T)(img)(_n7##x,_p3##y,z,c), I[291] = (T)(img)(_n8##x,_p3##y,z,c), I[292] = (T)(img)(_n9##x,_p3##y,z,c), I[293] = (T)(img)(_n10##x,_p3##y,z,c), I[294] = (T)(img)(_n11##x,_p3##y,z,c), I[295] = (T)(img)(_n12##x,_p3##y,z,c), I[296] = (T)(img)(_n13##x,_p3##y,z,c), \ - I[297] = (T)(img)(_p13##x,_p2##y,z,c), I[298] = (T)(img)(_p12##x,_p2##y,z,c), I[299] = (T)(img)(_p11##x,_p2##y,z,c), I[300] = (T)(img)(_p10##x,_p2##y,z,c), I[301] = (T)(img)(_p9##x,_p2##y,z,c), I[302] = (T)(img)(_p8##x,_p2##y,z,c), I[303] = (T)(img)(_p7##x,_p2##y,z,c), I[304] = (T)(img)(_p6##x,_p2##y,z,c), I[305] = (T)(img)(_p5##x,_p2##y,z,c), I[306] = (T)(img)(_p4##x,_p2##y,z,c), I[307] = (T)(img)(_p3##x,_p2##y,z,c), I[308] = (T)(img)(_p2##x,_p2##y,z,c), I[309] = (T)(img)(_p1##x,_p2##y,z,c), I[310] = (T)(img)(x,_p2##y,z,c), I[311] = (T)(img)(_n1##x,_p2##y,z,c), I[312] = (T)(img)(_n2##x,_p2##y,z,c), I[313] = (T)(img)(_n3##x,_p2##y,z,c), I[314] = (T)(img)(_n4##x,_p2##y,z,c), I[315] = (T)(img)(_n5##x,_p2##y,z,c), I[316] = (T)(img)(_n6##x,_p2##y,z,c), I[317] = (T)(img)(_n7##x,_p2##y,z,c), I[318] = (T)(img)(_n8##x,_p2##y,z,c), I[319] = (T)(img)(_n9##x,_p2##y,z,c), I[320] = (T)(img)(_n10##x,_p2##y,z,c), I[321] = (T)(img)(_n11##x,_p2##y,z,c), I[322] = (T)(img)(_n12##x,_p2##y,z,c), I[323] = (T)(img)(_n13##x,_p2##y,z,c), \ - I[324] = (T)(img)(_p13##x,_p1##y,z,c), I[325] = (T)(img)(_p12##x,_p1##y,z,c), I[326] = (T)(img)(_p11##x,_p1##y,z,c), I[327] = (T)(img)(_p10##x,_p1##y,z,c), I[328] = (T)(img)(_p9##x,_p1##y,z,c), I[329] = (T)(img)(_p8##x,_p1##y,z,c), I[330] = (T)(img)(_p7##x,_p1##y,z,c), I[331] = (T)(img)(_p6##x,_p1##y,z,c), I[332] = (T)(img)(_p5##x,_p1##y,z,c), I[333] = (T)(img)(_p4##x,_p1##y,z,c), I[334] = (T)(img)(_p3##x,_p1##y,z,c), I[335] = (T)(img)(_p2##x,_p1##y,z,c), I[336] = (T)(img)(_p1##x,_p1##y,z,c), I[337] = (T)(img)(x,_p1##y,z,c), I[338] = (T)(img)(_n1##x,_p1##y,z,c), I[339] = (T)(img)(_n2##x,_p1##y,z,c), I[340] = (T)(img)(_n3##x,_p1##y,z,c), I[341] = (T)(img)(_n4##x,_p1##y,z,c), I[342] = (T)(img)(_n5##x,_p1##y,z,c), I[343] = (T)(img)(_n6##x,_p1##y,z,c), I[344] = (T)(img)(_n7##x,_p1##y,z,c), I[345] = (T)(img)(_n8##x,_p1##y,z,c), I[346] = (T)(img)(_n9##x,_p1##y,z,c), I[347] = (T)(img)(_n10##x,_p1##y,z,c), I[348] = (T)(img)(_n11##x,_p1##y,z,c), I[349] = (T)(img)(_n12##x,_p1##y,z,c), I[350] = (T)(img)(_n13##x,_p1##y,z,c), \ - I[351] = (T)(img)(_p13##x,y,z,c), I[352] = (T)(img)(_p12##x,y,z,c), I[353] = (T)(img)(_p11##x,y,z,c), I[354] = (T)(img)(_p10##x,y,z,c), I[355] = (T)(img)(_p9##x,y,z,c), I[356] = (T)(img)(_p8##x,y,z,c), I[357] = (T)(img)(_p7##x,y,z,c), I[358] = (T)(img)(_p6##x,y,z,c), I[359] = (T)(img)(_p5##x,y,z,c), I[360] = (T)(img)(_p4##x,y,z,c), I[361] = (T)(img)(_p3##x,y,z,c), I[362] = (T)(img)(_p2##x,y,z,c), I[363] = (T)(img)(_p1##x,y,z,c), I[364] = (T)(img)(x,y,z,c), I[365] = (T)(img)(_n1##x,y,z,c), I[366] = (T)(img)(_n2##x,y,z,c), I[367] = (T)(img)(_n3##x,y,z,c), I[368] = (T)(img)(_n4##x,y,z,c), I[369] = (T)(img)(_n5##x,y,z,c), I[370] = (T)(img)(_n6##x,y,z,c), I[371] = (T)(img)(_n7##x,y,z,c), I[372] = (T)(img)(_n8##x,y,z,c), I[373] = (T)(img)(_n9##x,y,z,c), I[374] = (T)(img)(_n10##x,y,z,c), I[375] = (T)(img)(_n11##x,y,z,c), I[376] = (T)(img)(_n12##x,y,z,c), I[377] = (T)(img)(_n13##x,y,z,c), \ - I[378] = (T)(img)(_p13##x,_n1##y,z,c), I[379] = (T)(img)(_p12##x,_n1##y,z,c), I[380] = (T)(img)(_p11##x,_n1##y,z,c), I[381] = (T)(img)(_p10##x,_n1##y,z,c), I[382] = (T)(img)(_p9##x,_n1##y,z,c), I[383] = (T)(img)(_p8##x,_n1##y,z,c), I[384] = (T)(img)(_p7##x,_n1##y,z,c), I[385] = (T)(img)(_p6##x,_n1##y,z,c), I[386] = (T)(img)(_p5##x,_n1##y,z,c), I[387] = (T)(img)(_p4##x,_n1##y,z,c), I[388] = (T)(img)(_p3##x,_n1##y,z,c), I[389] = (T)(img)(_p2##x,_n1##y,z,c), I[390] = (T)(img)(_p1##x,_n1##y,z,c), I[391] = (T)(img)(x,_n1##y,z,c), I[392] = (T)(img)(_n1##x,_n1##y,z,c), I[393] = (T)(img)(_n2##x,_n1##y,z,c), I[394] = (T)(img)(_n3##x,_n1##y,z,c), I[395] = (T)(img)(_n4##x,_n1##y,z,c), I[396] = (T)(img)(_n5##x,_n1##y,z,c), I[397] = (T)(img)(_n6##x,_n1##y,z,c), I[398] = (T)(img)(_n7##x,_n1##y,z,c), I[399] = (T)(img)(_n8##x,_n1##y,z,c), I[400] = (T)(img)(_n9##x,_n1##y,z,c), I[401] = (T)(img)(_n10##x,_n1##y,z,c), I[402] = (T)(img)(_n11##x,_n1##y,z,c), I[403] = (T)(img)(_n12##x,_n1##y,z,c), I[404] = (T)(img)(_n13##x,_n1##y,z,c), \ - I[405] = (T)(img)(_p13##x,_n2##y,z,c), I[406] = (T)(img)(_p12##x,_n2##y,z,c), I[407] = (T)(img)(_p11##x,_n2##y,z,c), I[408] = (T)(img)(_p10##x,_n2##y,z,c), I[409] = (T)(img)(_p9##x,_n2##y,z,c), I[410] = (T)(img)(_p8##x,_n2##y,z,c), I[411] = (T)(img)(_p7##x,_n2##y,z,c), I[412] = (T)(img)(_p6##x,_n2##y,z,c), I[413] = (T)(img)(_p5##x,_n2##y,z,c), I[414] = (T)(img)(_p4##x,_n2##y,z,c), I[415] = (T)(img)(_p3##x,_n2##y,z,c), I[416] = (T)(img)(_p2##x,_n2##y,z,c), I[417] = (T)(img)(_p1##x,_n2##y,z,c), I[418] = (T)(img)(x,_n2##y,z,c), I[419] = (T)(img)(_n1##x,_n2##y,z,c), I[420] = (T)(img)(_n2##x,_n2##y,z,c), I[421] = (T)(img)(_n3##x,_n2##y,z,c), I[422] = (T)(img)(_n4##x,_n2##y,z,c), I[423] = (T)(img)(_n5##x,_n2##y,z,c), I[424] = (T)(img)(_n6##x,_n2##y,z,c), I[425] = (T)(img)(_n7##x,_n2##y,z,c), I[426] = (T)(img)(_n8##x,_n2##y,z,c), I[427] = (T)(img)(_n9##x,_n2##y,z,c), I[428] = (T)(img)(_n10##x,_n2##y,z,c), I[429] = (T)(img)(_n11##x,_n2##y,z,c), I[430] = (T)(img)(_n12##x,_n2##y,z,c), I[431] = (T)(img)(_n13##x,_n2##y,z,c), \ - I[432] = (T)(img)(_p13##x,_n3##y,z,c), I[433] = (T)(img)(_p12##x,_n3##y,z,c), I[434] = (T)(img)(_p11##x,_n3##y,z,c), I[435] = (T)(img)(_p10##x,_n3##y,z,c), I[436] = (T)(img)(_p9##x,_n3##y,z,c), I[437] = (T)(img)(_p8##x,_n3##y,z,c), I[438] = (T)(img)(_p7##x,_n3##y,z,c), I[439] = (T)(img)(_p6##x,_n3##y,z,c), I[440] = (T)(img)(_p5##x,_n3##y,z,c), I[441] = (T)(img)(_p4##x,_n3##y,z,c), I[442] = (T)(img)(_p3##x,_n3##y,z,c), I[443] = (T)(img)(_p2##x,_n3##y,z,c), I[444] = (T)(img)(_p1##x,_n3##y,z,c), I[445] = (T)(img)(x,_n3##y,z,c), I[446] = (T)(img)(_n1##x,_n3##y,z,c), I[447] = (T)(img)(_n2##x,_n3##y,z,c), I[448] = (T)(img)(_n3##x,_n3##y,z,c), I[449] = (T)(img)(_n4##x,_n3##y,z,c), I[450] = (T)(img)(_n5##x,_n3##y,z,c), I[451] = (T)(img)(_n6##x,_n3##y,z,c), I[452] = (T)(img)(_n7##x,_n3##y,z,c), I[453] = (T)(img)(_n8##x,_n3##y,z,c), I[454] = (T)(img)(_n9##x,_n3##y,z,c), I[455] = (T)(img)(_n10##x,_n3##y,z,c), I[456] = (T)(img)(_n11##x,_n3##y,z,c), I[457] = (T)(img)(_n12##x,_n3##y,z,c), I[458] = (T)(img)(_n13##x,_n3##y,z,c), \ - I[459] = (T)(img)(_p13##x,_n4##y,z,c), I[460] = (T)(img)(_p12##x,_n4##y,z,c), I[461] = (T)(img)(_p11##x,_n4##y,z,c), I[462] = (T)(img)(_p10##x,_n4##y,z,c), I[463] = (T)(img)(_p9##x,_n4##y,z,c), I[464] = (T)(img)(_p8##x,_n4##y,z,c), I[465] = (T)(img)(_p7##x,_n4##y,z,c), I[466] = (T)(img)(_p6##x,_n4##y,z,c), I[467] = (T)(img)(_p5##x,_n4##y,z,c), I[468] = (T)(img)(_p4##x,_n4##y,z,c), I[469] = (T)(img)(_p3##x,_n4##y,z,c), I[470] = (T)(img)(_p2##x,_n4##y,z,c), I[471] = (T)(img)(_p1##x,_n4##y,z,c), I[472] = (T)(img)(x,_n4##y,z,c), I[473] = (T)(img)(_n1##x,_n4##y,z,c), I[474] = (T)(img)(_n2##x,_n4##y,z,c), I[475] = (T)(img)(_n3##x,_n4##y,z,c), I[476] = (T)(img)(_n4##x,_n4##y,z,c), I[477] = (T)(img)(_n5##x,_n4##y,z,c), I[478] = (T)(img)(_n6##x,_n4##y,z,c), I[479] = (T)(img)(_n7##x,_n4##y,z,c), I[480] = (T)(img)(_n8##x,_n4##y,z,c), I[481] = (T)(img)(_n9##x,_n4##y,z,c), I[482] = (T)(img)(_n10##x,_n4##y,z,c), I[483] = (T)(img)(_n11##x,_n4##y,z,c), I[484] = (T)(img)(_n12##x,_n4##y,z,c), I[485] = (T)(img)(_n13##x,_n4##y,z,c), \ - I[486] = (T)(img)(_p13##x,_n5##y,z,c), I[487] = (T)(img)(_p12##x,_n5##y,z,c), I[488] = (T)(img)(_p11##x,_n5##y,z,c), I[489] = (T)(img)(_p10##x,_n5##y,z,c), I[490] = (T)(img)(_p9##x,_n5##y,z,c), I[491] = (T)(img)(_p8##x,_n5##y,z,c), I[492] = (T)(img)(_p7##x,_n5##y,z,c), I[493] = (T)(img)(_p6##x,_n5##y,z,c), I[494] = (T)(img)(_p5##x,_n5##y,z,c), I[495] = (T)(img)(_p4##x,_n5##y,z,c), I[496] = (T)(img)(_p3##x,_n5##y,z,c), I[497] = (T)(img)(_p2##x,_n5##y,z,c), I[498] = (T)(img)(_p1##x,_n5##y,z,c), I[499] = (T)(img)(x,_n5##y,z,c), I[500] = (T)(img)(_n1##x,_n5##y,z,c), I[501] = (T)(img)(_n2##x,_n5##y,z,c), I[502] = (T)(img)(_n3##x,_n5##y,z,c), I[503] = (T)(img)(_n4##x,_n5##y,z,c), I[504] = (T)(img)(_n5##x,_n5##y,z,c), I[505] = (T)(img)(_n6##x,_n5##y,z,c), I[506] = (T)(img)(_n7##x,_n5##y,z,c), I[507] = (T)(img)(_n8##x,_n5##y,z,c), I[508] = (T)(img)(_n9##x,_n5##y,z,c), I[509] = (T)(img)(_n10##x,_n5##y,z,c), I[510] = (T)(img)(_n11##x,_n5##y,z,c), I[511] = (T)(img)(_n12##x,_n5##y,z,c), I[512] = (T)(img)(_n13##x,_n5##y,z,c), \ - I[513] = (T)(img)(_p13##x,_n6##y,z,c), I[514] = (T)(img)(_p12##x,_n6##y,z,c), I[515] = (T)(img)(_p11##x,_n6##y,z,c), I[516] = (T)(img)(_p10##x,_n6##y,z,c), I[517] = (T)(img)(_p9##x,_n6##y,z,c), I[518] = (T)(img)(_p8##x,_n6##y,z,c), I[519] = (T)(img)(_p7##x,_n6##y,z,c), I[520] = (T)(img)(_p6##x,_n6##y,z,c), I[521] = (T)(img)(_p5##x,_n6##y,z,c), I[522] = (T)(img)(_p4##x,_n6##y,z,c), I[523] = (T)(img)(_p3##x,_n6##y,z,c), I[524] = (T)(img)(_p2##x,_n6##y,z,c), I[525] = (T)(img)(_p1##x,_n6##y,z,c), I[526] = (T)(img)(x,_n6##y,z,c), I[527] = (T)(img)(_n1##x,_n6##y,z,c), I[528] = (T)(img)(_n2##x,_n6##y,z,c), I[529] = (T)(img)(_n3##x,_n6##y,z,c), I[530] = (T)(img)(_n4##x,_n6##y,z,c), I[531] = (T)(img)(_n5##x,_n6##y,z,c), I[532] = (T)(img)(_n6##x,_n6##y,z,c), I[533] = (T)(img)(_n7##x,_n6##y,z,c), I[534] = (T)(img)(_n8##x,_n6##y,z,c), I[535] = (T)(img)(_n9##x,_n6##y,z,c), I[536] = (T)(img)(_n10##x,_n6##y,z,c), I[537] = (T)(img)(_n11##x,_n6##y,z,c), I[538] = (T)(img)(_n12##x,_n6##y,z,c), I[539] = (T)(img)(_n13##x,_n6##y,z,c), \ - I[540] = (T)(img)(_p13##x,_n7##y,z,c), I[541] = (T)(img)(_p12##x,_n7##y,z,c), I[542] = (T)(img)(_p11##x,_n7##y,z,c), I[543] = (T)(img)(_p10##x,_n7##y,z,c), I[544] = (T)(img)(_p9##x,_n7##y,z,c), I[545] = (T)(img)(_p8##x,_n7##y,z,c), I[546] = (T)(img)(_p7##x,_n7##y,z,c), I[547] = (T)(img)(_p6##x,_n7##y,z,c), I[548] = (T)(img)(_p5##x,_n7##y,z,c), I[549] = (T)(img)(_p4##x,_n7##y,z,c), I[550] = (T)(img)(_p3##x,_n7##y,z,c), I[551] = (T)(img)(_p2##x,_n7##y,z,c), I[552] = (T)(img)(_p1##x,_n7##y,z,c), I[553] = (T)(img)(x,_n7##y,z,c), I[554] = (T)(img)(_n1##x,_n7##y,z,c), I[555] = (T)(img)(_n2##x,_n7##y,z,c), I[556] = (T)(img)(_n3##x,_n7##y,z,c), I[557] = (T)(img)(_n4##x,_n7##y,z,c), I[558] = (T)(img)(_n5##x,_n7##y,z,c), I[559] = (T)(img)(_n6##x,_n7##y,z,c), I[560] = (T)(img)(_n7##x,_n7##y,z,c), I[561] = (T)(img)(_n8##x,_n7##y,z,c), I[562] = (T)(img)(_n9##x,_n7##y,z,c), I[563] = (T)(img)(_n10##x,_n7##y,z,c), I[564] = (T)(img)(_n11##x,_n7##y,z,c), I[565] = (T)(img)(_n12##x,_n7##y,z,c), I[566] = (T)(img)(_n13##x,_n7##y,z,c), \ - I[567] = (T)(img)(_p13##x,_n8##y,z,c), I[568] = (T)(img)(_p12##x,_n8##y,z,c), I[569] = (T)(img)(_p11##x,_n8##y,z,c), I[570] = (T)(img)(_p10##x,_n8##y,z,c), I[571] = (T)(img)(_p9##x,_n8##y,z,c), I[572] = (T)(img)(_p8##x,_n8##y,z,c), I[573] = (T)(img)(_p7##x,_n8##y,z,c), I[574] = (T)(img)(_p6##x,_n8##y,z,c), I[575] = (T)(img)(_p5##x,_n8##y,z,c), I[576] = (T)(img)(_p4##x,_n8##y,z,c), I[577] = (T)(img)(_p3##x,_n8##y,z,c), I[578] = (T)(img)(_p2##x,_n8##y,z,c), I[579] = (T)(img)(_p1##x,_n8##y,z,c), I[580] = (T)(img)(x,_n8##y,z,c), I[581] = (T)(img)(_n1##x,_n8##y,z,c), I[582] = (T)(img)(_n2##x,_n8##y,z,c), I[583] = (T)(img)(_n3##x,_n8##y,z,c), I[584] = (T)(img)(_n4##x,_n8##y,z,c), I[585] = (T)(img)(_n5##x,_n8##y,z,c), I[586] = (T)(img)(_n6##x,_n8##y,z,c), I[587] = (T)(img)(_n7##x,_n8##y,z,c), I[588] = (T)(img)(_n8##x,_n8##y,z,c), I[589] = (T)(img)(_n9##x,_n8##y,z,c), I[590] = (T)(img)(_n10##x,_n8##y,z,c), I[591] = (T)(img)(_n11##x,_n8##y,z,c), I[592] = (T)(img)(_n12##x,_n8##y,z,c), I[593] = (T)(img)(_n13##x,_n8##y,z,c), \ - I[594] = (T)(img)(_p13##x,_n9##y,z,c), I[595] = (T)(img)(_p12##x,_n9##y,z,c), I[596] = (T)(img)(_p11##x,_n9##y,z,c), I[597] = (T)(img)(_p10##x,_n9##y,z,c), I[598] = (T)(img)(_p9##x,_n9##y,z,c), I[599] = (T)(img)(_p8##x,_n9##y,z,c), I[600] = (T)(img)(_p7##x,_n9##y,z,c), I[601] = (T)(img)(_p6##x,_n9##y,z,c), I[602] = (T)(img)(_p5##x,_n9##y,z,c), I[603] = (T)(img)(_p4##x,_n9##y,z,c), I[604] = (T)(img)(_p3##x,_n9##y,z,c), I[605] = (T)(img)(_p2##x,_n9##y,z,c), I[606] = (T)(img)(_p1##x,_n9##y,z,c), I[607] = (T)(img)(x,_n9##y,z,c), I[608] = (T)(img)(_n1##x,_n9##y,z,c), I[609] = (T)(img)(_n2##x,_n9##y,z,c), I[610] = (T)(img)(_n3##x,_n9##y,z,c), I[611] = (T)(img)(_n4##x,_n9##y,z,c), I[612] = (T)(img)(_n5##x,_n9##y,z,c), I[613] = (T)(img)(_n6##x,_n9##y,z,c), I[614] = (T)(img)(_n7##x,_n9##y,z,c), I[615] = (T)(img)(_n8##x,_n9##y,z,c), I[616] = (T)(img)(_n9##x,_n9##y,z,c), I[617] = (T)(img)(_n10##x,_n9##y,z,c), I[618] = (T)(img)(_n11##x,_n9##y,z,c), I[619] = (T)(img)(_n12##x,_n9##y,z,c), I[620] = (T)(img)(_n13##x,_n9##y,z,c), \ - I[621] = (T)(img)(_p13##x,_n10##y,z,c), I[622] = (T)(img)(_p12##x,_n10##y,z,c), I[623] = (T)(img)(_p11##x,_n10##y,z,c), I[624] = (T)(img)(_p10##x,_n10##y,z,c), I[625] = (T)(img)(_p9##x,_n10##y,z,c), I[626] = (T)(img)(_p8##x,_n10##y,z,c), I[627] = (T)(img)(_p7##x,_n10##y,z,c), I[628] = (T)(img)(_p6##x,_n10##y,z,c), I[629] = (T)(img)(_p5##x,_n10##y,z,c), I[630] = (T)(img)(_p4##x,_n10##y,z,c), I[631] = (T)(img)(_p3##x,_n10##y,z,c), I[632] = (T)(img)(_p2##x,_n10##y,z,c), I[633] = (T)(img)(_p1##x,_n10##y,z,c), I[634] = (T)(img)(x,_n10##y,z,c), I[635] = (T)(img)(_n1##x,_n10##y,z,c), I[636] = (T)(img)(_n2##x,_n10##y,z,c), I[637] = (T)(img)(_n3##x,_n10##y,z,c), I[638] = (T)(img)(_n4##x,_n10##y,z,c), I[639] = (T)(img)(_n5##x,_n10##y,z,c), I[640] = (T)(img)(_n6##x,_n10##y,z,c), I[641] = (T)(img)(_n7##x,_n10##y,z,c), I[642] = (T)(img)(_n8##x,_n10##y,z,c), I[643] = (T)(img)(_n9##x,_n10##y,z,c), I[644] = (T)(img)(_n10##x,_n10##y,z,c), I[645] = (T)(img)(_n11##x,_n10##y,z,c), I[646] = (T)(img)(_n12##x,_n10##y,z,c), I[647] = (T)(img)(_n13##x,_n10##y,z,c), \ - I[648] = (T)(img)(_p13##x,_n11##y,z,c), I[649] = (T)(img)(_p12##x,_n11##y,z,c), I[650] = (T)(img)(_p11##x,_n11##y,z,c), I[651] = (T)(img)(_p10##x,_n11##y,z,c), I[652] = (T)(img)(_p9##x,_n11##y,z,c), I[653] = (T)(img)(_p8##x,_n11##y,z,c), I[654] = (T)(img)(_p7##x,_n11##y,z,c), I[655] = (T)(img)(_p6##x,_n11##y,z,c), I[656] = (T)(img)(_p5##x,_n11##y,z,c), I[657] = (T)(img)(_p4##x,_n11##y,z,c), I[658] = (T)(img)(_p3##x,_n11##y,z,c), I[659] = (T)(img)(_p2##x,_n11##y,z,c), I[660] = (T)(img)(_p1##x,_n11##y,z,c), I[661] = (T)(img)(x,_n11##y,z,c), I[662] = (T)(img)(_n1##x,_n11##y,z,c), I[663] = (T)(img)(_n2##x,_n11##y,z,c), I[664] = (T)(img)(_n3##x,_n11##y,z,c), I[665] = (T)(img)(_n4##x,_n11##y,z,c), I[666] = (T)(img)(_n5##x,_n11##y,z,c), I[667] = (T)(img)(_n6##x,_n11##y,z,c), I[668] = (T)(img)(_n7##x,_n11##y,z,c), I[669] = (T)(img)(_n8##x,_n11##y,z,c), I[670] = (T)(img)(_n9##x,_n11##y,z,c), I[671] = (T)(img)(_n10##x,_n11##y,z,c), I[672] = (T)(img)(_n11##x,_n11##y,z,c), I[673] = (T)(img)(_n12##x,_n11##y,z,c), I[674] = (T)(img)(_n13##x,_n11##y,z,c), \ - I[675] = (T)(img)(_p13##x,_n12##y,z,c), I[676] = (T)(img)(_p12##x,_n12##y,z,c), I[677] = (T)(img)(_p11##x,_n12##y,z,c), I[678] = (T)(img)(_p10##x,_n12##y,z,c), I[679] = (T)(img)(_p9##x,_n12##y,z,c), I[680] = (T)(img)(_p8##x,_n12##y,z,c), I[681] = (T)(img)(_p7##x,_n12##y,z,c), I[682] = (T)(img)(_p6##x,_n12##y,z,c), I[683] = (T)(img)(_p5##x,_n12##y,z,c), I[684] = (T)(img)(_p4##x,_n12##y,z,c), I[685] = (T)(img)(_p3##x,_n12##y,z,c), I[686] = (T)(img)(_p2##x,_n12##y,z,c), I[687] = (T)(img)(_p1##x,_n12##y,z,c), I[688] = (T)(img)(x,_n12##y,z,c), I[689] = (T)(img)(_n1##x,_n12##y,z,c), I[690] = (T)(img)(_n2##x,_n12##y,z,c), I[691] = (T)(img)(_n3##x,_n12##y,z,c), I[692] = (T)(img)(_n4##x,_n12##y,z,c), I[693] = (T)(img)(_n5##x,_n12##y,z,c), I[694] = (T)(img)(_n6##x,_n12##y,z,c), I[695] = (T)(img)(_n7##x,_n12##y,z,c), I[696] = (T)(img)(_n8##x,_n12##y,z,c), I[697] = (T)(img)(_n9##x,_n12##y,z,c), I[698] = (T)(img)(_n10##x,_n12##y,z,c), I[699] = (T)(img)(_n11##x,_n12##y,z,c), I[700] = (T)(img)(_n12##x,_n12##y,z,c), I[701] = (T)(img)(_n13##x,_n12##y,z,c), \ - I[702] = (T)(img)(_p13##x,_n13##y,z,c), I[703] = (T)(img)(_p12##x,_n13##y,z,c), I[704] = (T)(img)(_p11##x,_n13##y,z,c), I[705] = (T)(img)(_p10##x,_n13##y,z,c), I[706] = (T)(img)(_p9##x,_n13##y,z,c), I[707] = (T)(img)(_p8##x,_n13##y,z,c), I[708] = (T)(img)(_p7##x,_n13##y,z,c), I[709] = (T)(img)(_p6##x,_n13##y,z,c), I[710] = (T)(img)(_p5##x,_n13##y,z,c), I[711] = (T)(img)(_p4##x,_n13##y,z,c), I[712] = (T)(img)(_p3##x,_n13##y,z,c), I[713] = (T)(img)(_p2##x,_n13##y,z,c), I[714] = (T)(img)(_p1##x,_n13##y,z,c), I[715] = (T)(img)(x,_n13##y,z,c), I[716] = (T)(img)(_n1##x,_n13##y,z,c), I[717] = (T)(img)(_n2##x,_n13##y,z,c), I[718] = (T)(img)(_n3##x,_n13##y,z,c), I[719] = (T)(img)(_n4##x,_n13##y,z,c), I[720] = (T)(img)(_n5##x,_n13##y,z,c), I[721] = (T)(img)(_n6##x,_n13##y,z,c), I[722] = (T)(img)(_n7##x,_n13##y,z,c), I[723] = (T)(img)(_n8##x,_n13##y,z,c), I[724] = (T)(img)(_n9##x,_n13##y,z,c), I[725] = (T)(img)(_n10##x,_n13##y,z,c), I[726] = (T)(img)(_n11##x,_n13##y,z,c), I[727] = (T)(img)(_n12##x,_n13##y,z,c), I[728] = (T)(img)(_n13##x,_n13##y,z,c); - -// Define 28x28 loop macros -//------------------------- -#define cimg_for28(bound,i) for (int i = 0, \ - _p13##i = 0, _p12##i = 0, _p11##i = 0, _p10##i = 0, _p9##i = 0, _p8##i = 0, _p7##i = 0, _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6, \ - _n7##i = 7>=(int)(bound)?(int)(bound) - 1:7, \ - _n8##i = 8>=(int)(bound)?(int)(bound) - 1:8, \ - _n9##i = 9>=(int)(bound)?(int)(bound) - 1:9, \ - _n10##i = 10>=(int)(bound)?(int)(bound) - 1:10, \ - _n11##i = 11>=(int)(bound)?(int)(bound) - 1:11, \ - _n12##i = 12>=(int)(bound)?(int)(bound) - 1:12, \ - _n13##i = 13>=(int)(bound)?(int)(bound) - 1:13, \ - _n14##i = 14>=(int)(bound)?(int)(bound) - 1:14; \ - _n14##i<(int)(bound) || _n13##i==--_n14##i || _n12##i==--_n13##i || _n11##i==--_n12##i || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n14##i = _n13##i = _n12##i = _n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p13##i = _p12##i, _p12##i = _p11##i, _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i, ++_n12##i, ++_n13##i, ++_n14##i) - -#define cimg_for28X(img,x) cimg_for28((img)._width,x) -#define cimg_for28Y(img,y) cimg_for28((img)._height,y) -#define cimg_for28Z(img,z) cimg_for28((img)._depth,z) -#define cimg_for28C(img,c) cimg_for28((img)._spectrum,c) -#define cimg_for28XY(img,x,y) cimg_for28Y(img,y) cimg_for28X(img,x) -#define cimg_for28XZ(img,x,z) cimg_for28Z(img,z) cimg_for28X(img,x) -#define cimg_for28XC(img,x,c) cimg_for28C(img,c) cimg_for28X(img,x) -#define cimg_for28YZ(img,y,z) cimg_for28Z(img,z) cimg_for28Y(img,y) -#define cimg_for28YC(img,y,c) cimg_for28C(img,c) cimg_for28Y(img,y) -#define cimg_for28ZC(img,z,c) cimg_for28C(img,c) cimg_for28Z(img,z) -#define cimg_for28XYZ(img,x,y,z) cimg_for28Z(img,z) cimg_for28XY(img,x,y) -#define cimg_for28XZC(img,x,z,c) cimg_for28C(img,c) cimg_for28XZ(img,x,z) -#define cimg_for28YZC(img,y,z,c) cimg_for28C(img,c) cimg_for28YZ(img,y,z) -#define cimg_for28XYZC(img,x,y,z,c) cimg_for28C(img,c) cimg_for28XYZ(img,x,y,z) - -#define cimg_for_in28(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p13##i = i - 13<0?0:i - 13, \ - _p12##i = i - 12<0?0:i - 12, \ - _p11##i = i - 11<0?0:i - 11, \ - _p10##i = i - 10<0?0:i - 10, \ - _p9##i = i - 9<0?0:i - 9, \ - _p8##i = i - 8<0?0:i - 8, \ - _p7##i = i - 7<0?0:i - 7, \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6, \ - _n7##i = i + 7>=(int)(bound)?(int)(bound) - 1:i + 7, \ - _n8##i = i + 8>=(int)(bound)?(int)(bound) - 1:i + 8, \ - _n9##i = i + 9>=(int)(bound)?(int)(bound) - 1:i + 9, \ - _n10##i = i + 10>=(int)(bound)?(int)(bound) - 1:i + 10, \ - _n11##i = i + 11>=(int)(bound)?(int)(bound) - 1:i + 11, \ - _n12##i = i + 12>=(int)(bound)?(int)(bound) - 1:i + 12, \ - _n13##i = i + 13>=(int)(bound)?(int)(bound) - 1:i + 13, \ - _n14##i = i + 14>=(int)(bound)?(int)(bound) - 1:i + 14; \ - i<=(int)(i1) && (_n14##i<(int)(bound) || _n13##i==--_n14##i || _n12##i==--_n13##i || _n11##i==--_n12##i || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n14##i = _n13##i = _n12##i = _n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p13##i = _p12##i, _p12##i = _p11##i, _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i, ++_n12##i, ++_n13##i, ++_n14##i) - -#define cimg_for_in28X(img,x0,x1,x) cimg_for_in28((img)._width,x0,x1,x) -#define cimg_for_in28Y(img,y0,y1,y) cimg_for_in28((img)._height,y0,y1,y) -#define cimg_for_in28Z(img,z0,z1,z) cimg_for_in28((img)._depth,z0,z1,z) -#define cimg_for_in28C(img,c0,c1,c) cimg_for_in28((img)._spectrum,c0,c1,c) -#define cimg_for_in28XY(img,x0,y0,x1,y1,x,y) cimg_for_in28Y(img,y0,y1,y) cimg_for_in28X(img,x0,x1,x) -#define cimg_for_in28XZ(img,x0,z0,x1,z1,x,z) cimg_for_in28Z(img,z0,z1,z) cimg_for_in28X(img,x0,x1,x) -#define cimg_for_in28XC(img,x0,c0,x1,c1,x,c) cimg_for_in28C(img,c0,c1,c) cimg_for_in28X(img,x0,x1,x) -#define cimg_for_in28YZ(img,y0,z0,y1,z1,y,z) cimg_for_in28Z(img,z0,z1,z) cimg_for_in28Y(img,y0,y1,y) -#define cimg_for_in28YC(img,y0,c0,y1,c1,y,c) cimg_for_in28C(img,c0,c1,c) cimg_for_in28Y(img,y0,y1,y) -#define cimg_for_in28ZC(img,z0,c0,z1,c1,z,c) cimg_for_in28C(img,c0,c1,c) cimg_for_in28Z(img,z0,z1,z) -#define cimg_for_in28XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in28Z(img,z0,z1,z) cimg_for_in28XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in28XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in28C(img,c0,c1,c) cimg_for_in28XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in28YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in28C(img,c0,c1,c) cimg_for_in28YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in28XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in28C(img,c0,c1,c) cimg_for_in28XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for28x28(img,x,y,z,c,I,T) \ - cimg_for28((img)._height,y) for (int x = 0, \ - _p13##x = 0, _p12##x = 0, _p11##x = 0, _p10##x = 0, _p9##x = 0, _p8##x = 0, _p7##x = 0, _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = 6>=((img)._width)?(img).width() - 1:6, \ - _n7##x = 7>=((img)._width)?(img).width() - 1:7, \ - _n8##x = 8>=((img)._width)?(img).width() - 1:8, \ - _n9##x = 9>=((img)._width)?(img).width() - 1:9, \ - _n10##x = 10>=((img)._width)?(img).width() - 1:10, \ - _n11##x = 11>=((img)._width)?(img).width() - 1:11, \ - _n12##x = 12>=((img)._width)?(img).width() - 1:12, \ - _n13##x = 13>=((img)._width)?(img).width() - 1:13, \ - _n14##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = I[7] = I[8] = I[9] = I[10] = I[11] = I[12] = I[13] = (T)(img)(0,_p13##y,z,c)), \ - (I[28] = I[29] = I[30] = I[31] = I[32] = I[33] = I[34] = I[35] = I[36] = I[37] = I[38] = I[39] = I[40] = I[41] = (T)(img)(0,_p12##y,z,c)), \ - (I[56] = I[57] = I[58] = I[59] = I[60] = I[61] = I[62] = I[63] = I[64] = I[65] = I[66] = I[67] = I[68] = I[69] = (T)(img)(0,_p11##y,z,c)), \ - (I[84] = I[85] = I[86] = I[87] = I[88] = I[89] = I[90] = I[91] = I[92] = I[93] = I[94] = I[95] = I[96] = I[97] = (T)(img)(0,_p10##y,z,c)), \ - (I[112] = I[113] = I[114] = I[115] = I[116] = I[117] = I[118] = I[119] = I[120] = I[121] = I[122] = I[123] = I[124] = I[125] = (T)(img)(0,_p9##y,z,c)), \ - (I[140] = I[141] = I[142] = I[143] = I[144] = I[145] = I[146] = I[147] = I[148] = I[149] = I[150] = I[151] = I[152] = I[153] = (T)(img)(0,_p8##y,z,c)), \ - (I[168] = I[169] = I[170] = I[171] = I[172] = I[173] = I[174] = I[175] = I[176] = I[177] = I[178] = I[179] = I[180] = I[181] = (T)(img)(0,_p7##y,z,c)), \ - (I[196] = I[197] = I[198] = I[199] = I[200] = I[201] = I[202] = I[203] = I[204] = I[205] = I[206] = I[207] = I[208] = I[209] = (T)(img)(0,_p6##y,z,c)), \ - (I[224] = I[225] = I[226] = I[227] = I[228] = I[229] = I[230] = I[231] = I[232] = I[233] = I[234] = I[235] = I[236] = I[237] = (T)(img)(0,_p5##y,z,c)), \ - (I[252] = I[253] = I[254] = I[255] = I[256] = I[257] = I[258] = I[259] = I[260] = I[261] = I[262] = I[263] = I[264] = I[265] = (T)(img)(0,_p4##y,z,c)), \ - (I[280] = I[281] = I[282] = I[283] = I[284] = I[285] = I[286] = I[287] = I[288] = I[289] = I[290] = I[291] = I[292] = I[293] = (T)(img)(0,_p3##y,z,c)), \ - (I[308] = I[309] = I[310] = I[311] = I[312] = I[313] = I[314] = I[315] = I[316] = I[317] = I[318] = I[319] = I[320] = I[321] = (T)(img)(0,_p2##y,z,c)), \ - (I[336] = I[337] = I[338] = I[339] = I[340] = I[341] = I[342] = I[343] = I[344] = I[345] = I[346] = I[347] = I[348] = I[349] = (T)(img)(0,_p1##y,z,c)), \ - (I[364] = I[365] = I[366] = I[367] = I[368] = I[369] = I[370] = I[371] = I[372] = I[373] = I[374] = I[375] = I[376] = I[377] = (T)(img)(0,y,z,c)), \ - (I[392] = I[393] = I[394] = I[395] = I[396] = I[397] = I[398] = I[399] = I[400] = I[401] = I[402] = I[403] = I[404] = I[405] = (T)(img)(0,_n1##y,z,c)), \ - (I[420] = I[421] = I[422] = I[423] = I[424] = I[425] = I[426] = I[427] = I[428] = I[429] = I[430] = I[431] = I[432] = I[433] = (T)(img)(0,_n2##y,z,c)), \ - (I[448] = I[449] = I[450] = I[451] = I[452] = I[453] = I[454] = I[455] = I[456] = I[457] = I[458] = I[459] = I[460] = I[461] = (T)(img)(0,_n3##y,z,c)), \ - (I[476] = I[477] = I[478] = I[479] = I[480] = I[481] = I[482] = I[483] = I[484] = I[485] = I[486] = I[487] = I[488] = I[489] = (T)(img)(0,_n4##y,z,c)), \ - (I[504] = I[505] = I[506] = I[507] = I[508] = I[509] = I[510] = I[511] = I[512] = I[513] = I[514] = I[515] = I[516] = I[517] = (T)(img)(0,_n5##y,z,c)), \ - (I[532] = I[533] = I[534] = I[535] = I[536] = I[537] = I[538] = I[539] = I[540] = I[541] = I[542] = I[543] = I[544] = I[545] = (T)(img)(0,_n6##y,z,c)), \ - (I[560] = I[561] = I[562] = I[563] = I[564] = I[565] = I[566] = I[567] = I[568] = I[569] = I[570] = I[571] = I[572] = I[573] = (T)(img)(0,_n7##y,z,c)), \ - (I[588] = I[589] = I[590] = I[591] = I[592] = I[593] = I[594] = I[595] = I[596] = I[597] = I[598] = I[599] = I[600] = I[601] = (T)(img)(0,_n8##y,z,c)), \ - (I[616] = I[617] = I[618] = I[619] = I[620] = I[621] = I[622] = I[623] = I[624] = I[625] = I[626] = I[627] = I[628] = I[629] = (T)(img)(0,_n9##y,z,c)), \ - (I[644] = I[645] = I[646] = I[647] = I[648] = I[649] = I[650] = I[651] = I[652] = I[653] = I[654] = I[655] = I[656] = I[657] = (T)(img)(0,_n10##y,z,c)), \ - (I[672] = I[673] = I[674] = I[675] = I[676] = I[677] = I[678] = I[679] = I[680] = I[681] = I[682] = I[683] = I[684] = I[685] = (T)(img)(0,_n11##y,z,c)), \ - (I[700] = I[701] = I[702] = I[703] = I[704] = I[705] = I[706] = I[707] = I[708] = I[709] = I[710] = I[711] = I[712] = I[713] = (T)(img)(0,_n12##y,z,c)), \ - (I[728] = I[729] = I[730] = I[731] = I[732] = I[733] = I[734] = I[735] = I[736] = I[737] = I[738] = I[739] = I[740] = I[741] = (T)(img)(0,_n13##y,z,c)), \ - (I[756] = I[757] = I[758] = I[759] = I[760] = I[761] = I[762] = I[763] = I[764] = I[765] = I[766] = I[767] = I[768] = I[769] = (T)(img)(0,_n14##y,z,c)), \ - (I[14] = (T)(img)(_n1##x,_p13##y,z,c)), \ - (I[42] = (T)(img)(_n1##x,_p12##y,z,c)), \ - (I[70] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[98] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[126] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[154] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[182] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[210] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[238] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[266] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[294] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[322] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[350] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[378] = (T)(img)(_n1##x,y,z,c)), \ - (I[406] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[434] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[462] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[490] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[518] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[546] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[574] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[602] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[630] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[658] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[686] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[714] = (T)(img)(_n1##x,_n12##y,z,c)), \ - (I[742] = (T)(img)(_n1##x,_n13##y,z,c)), \ - (I[770] = (T)(img)(_n1##x,_n14##y,z,c)), \ - (I[15] = (T)(img)(_n2##x,_p13##y,z,c)), \ - (I[43] = (T)(img)(_n2##x,_p12##y,z,c)), \ - (I[71] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[99] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[127] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[155] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[183] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[211] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[239] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[267] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[295] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[323] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[351] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[379] = (T)(img)(_n2##x,y,z,c)), \ - (I[407] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[435] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[463] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[491] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[519] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[547] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[575] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[603] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[631] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[659] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[687] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[715] = (T)(img)(_n2##x,_n12##y,z,c)), \ - (I[743] = (T)(img)(_n2##x,_n13##y,z,c)), \ - (I[771] = (T)(img)(_n2##x,_n14##y,z,c)), \ - (I[16] = (T)(img)(_n3##x,_p13##y,z,c)), \ - (I[44] = (T)(img)(_n3##x,_p12##y,z,c)), \ - (I[72] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[100] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[128] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[156] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[184] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[212] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[240] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[268] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[296] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[324] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[352] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[380] = (T)(img)(_n3##x,y,z,c)), \ - (I[408] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[436] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[464] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[492] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[520] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[548] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[576] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[604] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[632] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[660] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[688] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[716] = (T)(img)(_n3##x,_n12##y,z,c)), \ - (I[744] = (T)(img)(_n3##x,_n13##y,z,c)), \ - (I[772] = (T)(img)(_n3##x,_n14##y,z,c)), \ - (I[17] = (T)(img)(_n4##x,_p13##y,z,c)), \ - (I[45] = (T)(img)(_n4##x,_p12##y,z,c)), \ - (I[73] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[101] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[129] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[157] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[185] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[213] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[241] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[269] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[297] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[325] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[353] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[381] = (T)(img)(_n4##x,y,z,c)), \ - (I[409] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[437] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[465] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[493] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[521] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[549] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[577] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[605] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[633] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[661] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[689] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[717] = (T)(img)(_n4##x,_n12##y,z,c)), \ - (I[745] = (T)(img)(_n4##x,_n13##y,z,c)), \ - (I[773] = (T)(img)(_n4##x,_n14##y,z,c)), \ - (I[18] = (T)(img)(_n5##x,_p13##y,z,c)), \ - (I[46] = (T)(img)(_n5##x,_p12##y,z,c)), \ - (I[74] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[102] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[130] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[158] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[186] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[214] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[242] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[270] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[298] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[326] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[354] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[382] = (T)(img)(_n5##x,y,z,c)), \ - (I[410] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[438] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[466] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[494] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[522] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[550] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[578] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[606] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[634] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[662] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[690] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[718] = (T)(img)(_n5##x,_n12##y,z,c)), \ - (I[746] = (T)(img)(_n5##x,_n13##y,z,c)), \ - (I[774] = (T)(img)(_n5##x,_n14##y,z,c)), \ - (I[19] = (T)(img)(_n6##x,_p13##y,z,c)), \ - (I[47] = (T)(img)(_n6##x,_p12##y,z,c)), \ - (I[75] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[103] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[131] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[159] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[187] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[215] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[243] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[271] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[299] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[327] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[355] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[383] = (T)(img)(_n6##x,y,z,c)), \ - (I[411] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[439] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[467] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[495] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[523] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[551] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[579] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[607] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[635] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[663] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[691] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[719] = (T)(img)(_n6##x,_n12##y,z,c)), \ - (I[747] = (T)(img)(_n6##x,_n13##y,z,c)), \ - (I[775] = (T)(img)(_n6##x,_n14##y,z,c)), \ - (I[20] = (T)(img)(_n7##x,_p13##y,z,c)), \ - (I[48] = (T)(img)(_n7##x,_p12##y,z,c)), \ - (I[76] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[104] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[132] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[160] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[188] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[216] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[244] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[272] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[300] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[328] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[356] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[384] = (T)(img)(_n7##x,y,z,c)), \ - (I[412] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[440] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[468] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[496] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[524] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[552] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[580] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[608] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[636] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[664] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[692] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[720] = (T)(img)(_n7##x,_n12##y,z,c)), \ - (I[748] = (T)(img)(_n7##x,_n13##y,z,c)), \ - (I[776] = (T)(img)(_n7##x,_n14##y,z,c)), \ - (I[21] = (T)(img)(_n8##x,_p13##y,z,c)), \ - (I[49] = (T)(img)(_n8##x,_p12##y,z,c)), \ - (I[77] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[105] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[133] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[161] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[189] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[217] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[245] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[273] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[301] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[329] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[357] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[385] = (T)(img)(_n8##x,y,z,c)), \ - (I[413] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[441] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[469] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[497] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[525] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[553] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[581] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[609] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[637] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[665] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[693] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[721] = (T)(img)(_n8##x,_n12##y,z,c)), \ - (I[749] = (T)(img)(_n8##x,_n13##y,z,c)), \ - (I[777] = (T)(img)(_n8##x,_n14##y,z,c)), \ - (I[22] = (T)(img)(_n9##x,_p13##y,z,c)), \ - (I[50] = (T)(img)(_n9##x,_p12##y,z,c)), \ - (I[78] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[106] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[134] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[162] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[190] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[218] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[246] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[274] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[302] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[330] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[358] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[386] = (T)(img)(_n9##x,y,z,c)), \ - (I[414] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[442] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[470] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[498] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[526] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[554] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[582] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[610] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[638] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[666] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[694] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[722] = (T)(img)(_n9##x,_n12##y,z,c)), \ - (I[750] = (T)(img)(_n9##x,_n13##y,z,c)), \ - (I[778] = (T)(img)(_n9##x,_n14##y,z,c)), \ - (I[23] = (T)(img)(_n10##x,_p13##y,z,c)), \ - (I[51] = (T)(img)(_n10##x,_p12##y,z,c)), \ - (I[79] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[107] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[135] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[163] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[191] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[219] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[247] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[275] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[303] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[331] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[359] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[387] = (T)(img)(_n10##x,y,z,c)), \ - (I[415] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[443] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[471] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[499] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[527] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[555] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[583] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[611] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[639] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[667] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[695] = (T)(img)(_n10##x,_n11##y,z,c)), \ - (I[723] = (T)(img)(_n10##x,_n12##y,z,c)), \ - (I[751] = (T)(img)(_n10##x,_n13##y,z,c)), \ - (I[779] = (T)(img)(_n10##x,_n14##y,z,c)), \ - (I[24] = (T)(img)(_n11##x,_p13##y,z,c)), \ - (I[52] = (T)(img)(_n11##x,_p12##y,z,c)), \ - (I[80] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[108] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[136] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[164] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[192] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[220] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[248] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[276] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[304] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[332] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[360] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[388] = (T)(img)(_n11##x,y,z,c)), \ - (I[416] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[444] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[472] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[500] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[528] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[556] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[584] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[612] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[640] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[668] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[696] = (T)(img)(_n11##x,_n11##y,z,c)), \ - (I[724] = (T)(img)(_n11##x,_n12##y,z,c)), \ - (I[752] = (T)(img)(_n11##x,_n13##y,z,c)), \ - (I[780] = (T)(img)(_n11##x,_n14##y,z,c)), \ - (I[25] = (T)(img)(_n12##x,_p13##y,z,c)), \ - (I[53] = (T)(img)(_n12##x,_p12##y,z,c)), \ - (I[81] = (T)(img)(_n12##x,_p11##y,z,c)), \ - (I[109] = (T)(img)(_n12##x,_p10##y,z,c)), \ - (I[137] = (T)(img)(_n12##x,_p9##y,z,c)), \ - (I[165] = (T)(img)(_n12##x,_p8##y,z,c)), \ - (I[193] = (T)(img)(_n12##x,_p7##y,z,c)), \ - (I[221] = (T)(img)(_n12##x,_p6##y,z,c)), \ - (I[249] = (T)(img)(_n12##x,_p5##y,z,c)), \ - (I[277] = (T)(img)(_n12##x,_p4##y,z,c)), \ - (I[305] = (T)(img)(_n12##x,_p3##y,z,c)), \ - (I[333] = (T)(img)(_n12##x,_p2##y,z,c)), \ - (I[361] = (T)(img)(_n12##x,_p1##y,z,c)), \ - (I[389] = (T)(img)(_n12##x,y,z,c)), \ - (I[417] = (T)(img)(_n12##x,_n1##y,z,c)), \ - (I[445] = (T)(img)(_n12##x,_n2##y,z,c)), \ - (I[473] = (T)(img)(_n12##x,_n3##y,z,c)), \ - (I[501] = (T)(img)(_n12##x,_n4##y,z,c)), \ - (I[529] = (T)(img)(_n12##x,_n5##y,z,c)), \ - (I[557] = (T)(img)(_n12##x,_n6##y,z,c)), \ - (I[585] = (T)(img)(_n12##x,_n7##y,z,c)), \ - (I[613] = (T)(img)(_n12##x,_n8##y,z,c)), \ - (I[641] = (T)(img)(_n12##x,_n9##y,z,c)), \ - (I[669] = (T)(img)(_n12##x,_n10##y,z,c)), \ - (I[697] = (T)(img)(_n12##x,_n11##y,z,c)), \ - (I[725] = (T)(img)(_n12##x,_n12##y,z,c)), \ - (I[753] = (T)(img)(_n12##x,_n13##y,z,c)), \ - (I[781] = (T)(img)(_n12##x,_n14##y,z,c)), \ - (I[26] = (T)(img)(_n13##x,_p13##y,z,c)), \ - (I[54] = (T)(img)(_n13##x,_p12##y,z,c)), \ - (I[82] = (T)(img)(_n13##x,_p11##y,z,c)), \ - (I[110] = (T)(img)(_n13##x,_p10##y,z,c)), \ - (I[138] = (T)(img)(_n13##x,_p9##y,z,c)), \ - (I[166] = (T)(img)(_n13##x,_p8##y,z,c)), \ - (I[194] = (T)(img)(_n13##x,_p7##y,z,c)), \ - (I[222] = (T)(img)(_n13##x,_p6##y,z,c)), \ - (I[250] = (T)(img)(_n13##x,_p5##y,z,c)), \ - (I[278] = (T)(img)(_n13##x,_p4##y,z,c)), \ - (I[306] = (T)(img)(_n13##x,_p3##y,z,c)), \ - (I[334] = (T)(img)(_n13##x,_p2##y,z,c)), \ - (I[362] = (T)(img)(_n13##x,_p1##y,z,c)), \ - (I[390] = (T)(img)(_n13##x,y,z,c)), \ - (I[418] = (T)(img)(_n13##x,_n1##y,z,c)), \ - (I[446] = (T)(img)(_n13##x,_n2##y,z,c)), \ - (I[474] = (T)(img)(_n13##x,_n3##y,z,c)), \ - (I[502] = (T)(img)(_n13##x,_n4##y,z,c)), \ - (I[530] = (T)(img)(_n13##x,_n5##y,z,c)), \ - (I[558] = (T)(img)(_n13##x,_n6##y,z,c)), \ - (I[586] = (T)(img)(_n13##x,_n7##y,z,c)), \ - (I[614] = (T)(img)(_n13##x,_n8##y,z,c)), \ - (I[642] = (T)(img)(_n13##x,_n9##y,z,c)), \ - (I[670] = (T)(img)(_n13##x,_n10##y,z,c)), \ - (I[698] = (T)(img)(_n13##x,_n11##y,z,c)), \ - (I[726] = (T)(img)(_n13##x,_n12##y,z,c)), \ - (I[754] = (T)(img)(_n13##x,_n13##y,z,c)), \ - (I[782] = (T)(img)(_n13##x,_n14##y,z,c)), \ - 14>=((img)._width)?(img).width() - 1:14); \ - (_n14##x<(img).width() && ( \ - (I[27] = (T)(img)(_n14##x,_p13##y,z,c)), \ - (I[55] = (T)(img)(_n14##x,_p12##y,z,c)), \ - (I[83] = (T)(img)(_n14##x,_p11##y,z,c)), \ - (I[111] = (T)(img)(_n14##x,_p10##y,z,c)), \ - (I[139] = (T)(img)(_n14##x,_p9##y,z,c)), \ - (I[167] = (T)(img)(_n14##x,_p8##y,z,c)), \ - (I[195] = (T)(img)(_n14##x,_p7##y,z,c)), \ - (I[223] = (T)(img)(_n14##x,_p6##y,z,c)), \ - (I[251] = (T)(img)(_n14##x,_p5##y,z,c)), \ - (I[279] = (T)(img)(_n14##x,_p4##y,z,c)), \ - (I[307] = (T)(img)(_n14##x,_p3##y,z,c)), \ - (I[335] = (T)(img)(_n14##x,_p2##y,z,c)), \ - (I[363] = (T)(img)(_n14##x,_p1##y,z,c)), \ - (I[391] = (T)(img)(_n14##x,y,z,c)), \ - (I[419] = (T)(img)(_n14##x,_n1##y,z,c)), \ - (I[447] = (T)(img)(_n14##x,_n2##y,z,c)), \ - (I[475] = (T)(img)(_n14##x,_n3##y,z,c)), \ - (I[503] = (T)(img)(_n14##x,_n4##y,z,c)), \ - (I[531] = (T)(img)(_n14##x,_n5##y,z,c)), \ - (I[559] = (T)(img)(_n14##x,_n6##y,z,c)), \ - (I[587] = (T)(img)(_n14##x,_n7##y,z,c)), \ - (I[615] = (T)(img)(_n14##x,_n8##y,z,c)), \ - (I[643] = (T)(img)(_n14##x,_n9##y,z,c)), \ - (I[671] = (T)(img)(_n14##x,_n10##y,z,c)), \ - (I[699] = (T)(img)(_n14##x,_n11##y,z,c)), \ - (I[727] = (T)(img)(_n14##x,_n12##y,z,c)), \ - (I[755] = (T)(img)(_n14##x,_n13##y,z,c)), \ - (I[783] = (T)(img)(_n14##x,_n14##y,z,c)),1)) || \ - _n13##x==--_n14##x || _n12##x==--_n13##x || _n11##x==--_n12##x || _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n14##x = _n13##x = _n12##x = _n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], \ - I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], \ - I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], \ - I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], \ - I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], \ - I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], \ - I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], \ - I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], \ - I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], \ - I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], \ - I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], \ - I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], \ - I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], \ - I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], \ - I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], I[415] = I[416], I[416] = I[417], I[417] = I[418], I[418] = I[419], \ - I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], \ - I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], I[463] = I[464], I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], \ - I[476] = I[477], I[477] = I[478], I[478] = I[479], I[479] = I[480], I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], I[493] = I[494], I[494] = I[495], I[495] = I[496], I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], \ - I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], I[511] = I[512], I[512] = I[513], I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], I[519] = I[520], I[520] = I[521], I[521] = I[522], I[522] = I[523], I[523] = I[524], I[524] = I[525], I[525] = I[526], I[526] = I[527], I[527] = I[528], I[528] = I[529], I[529] = I[530], I[530] = I[531], \ - I[532] = I[533], I[533] = I[534], I[534] = I[535], I[535] = I[536], I[536] = I[537], I[537] = I[538], I[538] = I[539], I[539] = I[540], I[540] = I[541], I[541] = I[542], I[542] = I[543], I[543] = I[544], I[544] = I[545], I[545] = I[546], I[546] = I[547], I[547] = I[548], I[548] = I[549], I[549] = I[550], I[550] = I[551], I[551] = I[552], I[552] = I[553], I[553] = I[554], I[554] = I[555], I[555] = I[556], I[556] = I[557], I[557] = I[558], I[558] = I[559], \ - I[560] = I[561], I[561] = I[562], I[562] = I[563], I[563] = I[564], I[564] = I[565], I[565] = I[566], I[566] = I[567], I[567] = I[568], I[568] = I[569], I[569] = I[570], I[570] = I[571], I[571] = I[572], I[572] = I[573], I[573] = I[574], I[574] = I[575], I[575] = I[576], I[576] = I[577], I[577] = I[578], I[578] = I[579], I[579] = I[580], I[580] = I[581], I[581] = I[582], I[582] = I[583], I[583] = I[584], I[584] = I[585], I[585] = I[586], I[586] = I[587], \ - I[588] = I[589], I[589] = I[590], I[590] = I[591], I[591] = I[592], I[592] = I[593], I[593] = I[594], I[594] = I[595], I[595] = I[596], I[596] = I[597], I[597] = I[598], I[598] = I[599], I[599] = I[600], I[600] = I[601], I[601] = I[602], I[602] = I[603], I[603] = I[604], I[604] = I[605], I[605] = I[606], I[606] = I[607], I[607] = I[608], I[608] = I[609], I[609] = I[610], I[610] = I[611], I[611] = I[612], I[612] = I[613], I[613] = I[614], I[614] = I[615], \ - I[616] = I[617], I[617] = I[618], I[618] = I[619], I[619] = I[620], I[620] = I[621], I[621] = I[622], I[622] = I[623], I[623] = I[624], I[624] = I[625], I[625] = I[626], I[626] = I[627], I[627] = I[628], I[628] = I[629], I[629] = I[630], I[630] = I[631], I[631] = I[632], I[632] = I[633], I[633] = I[634], I[634] = I[635], I[635] = I[636], I[636] = I[637], I[637] = I[638], I[638] = I[639], I[639] = I[640], I[640] = I[641], I[641] = I[642], I[642] = I[643], \ - I[644] = I[645], I[645] = I[646], I[646] = I[647], I[647] = I[648], I[648] = I[649], I[649] = I[650], I[650] = I[651], I[651] = I[652], I[652] = I[653], I[653] = I[654], I[654] = I[655], I[655] = I[656], I[656] = I[657], I[657] = I[658], I[658] = I[659], I[659] = I[660], I[660] = I[661], I[661] = I[662], I[662] = I[663], I[663] = I[664], I[664] = I[665], I[665] = I[666], I[666] = I[667], I[667] = I[668], I[668] = I[669], I[669] = I[670], I[670] = I[671], \ - I[672] = I[673], I[673] = I[674], I[674] = I[675], I[675] = I[676], I[676] = I[677], I[677] = I[678], I[678] = I[679], I[679] = I[680], I[680] = I[681], I[681] = I[682], I[682] = I[683], I[683] = I[684], I[684] = I[685], I[685] = I[686], I[686] = I[687], I[687] = I[688], I[688] = I[689], I[689] = I[690], I[690] = I[691], I[691] = I[692], I[692] = I[693], I[693] = I[694], I[694] = I[695], I[695] = I[696], I[696] = I[697], I[697] = I[698], I[698] = I[699], \ - I[700] = I[701], I[701] = I[702], I[702] = I[703], I[703] = I[704], I[704] = I[705], I[705] = I[706], I[706] = I[707], I[707] = I[708], I[708] = I[709], I[709] = I[710], I[710] = I[711], I[711] = I[712], I[712] = I[713], I[713] = I[714], I[714] = I[715], I[715] = I[716], I[716] = I[717], I[717] = I[718], I[718] = I[719], I[719] = I[720], I[720] = I[721], I[721] = I[722], I[722] = I[723], I[723] = I[724], I[724] = I[725], I[725] = I[726], I[726] = I[727], \ - I[728] = I[729], I[729] = I[730], I[730] = I[731], I[731] = I[732], I[732] = I[733], I[733] = I[734], I[734] = I[735], I[735] = I[736], I[736] = I[737], I[737] = I[738], I[738] = I[739], I[739] = I[740], I[740] = I[741], I[741] = I[742], I[742] = I[743], I[743] = I[744], I[744] = I[745], I[745] = I[746], I[746] = I[747], I[747] = I[748], I[748] = I[749], I[749] = I[750], I[750] = I[751], I[751] = I[752], I[752] = I[753], I[753] = I[754], I[754] = I[755], \ - I[756] = I[757], I[757] = I[758], I[758] = I[759], I[759] = I[760], I[760] = I[761], I[761] = I[762], I[762] = I[763], I[763] = I[764], I[764] = I[765], I[765] = I[766], I[766] = I[767], I[767] = I[768], I[768] = I[769], I[769] = I[770], I[770] = I[771], I[771] = I[772], I[772] = I[773], I[773] = I[774], I[774] = I[775], I[775] = I[776], I[776] = I[777], I[777] = I[778], I[778] = I[779], I[779] = I[780], I[780] = I[781], I[781] = I[782], I[782] = I[783], \ - _p13##x = _p12##x, _p12##x = _p11##x, _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x, ++_n12##x, ++_n13##x, ++_n14##x) - -#define cimg_for_in28x28(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in28((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p13##x = x - 13<0?0:x - 13, \ - _p12##x = x - 12<0?0:x - 12, \ - _p11##x = x - 11<0?0:x - 11, \ - _p10##x = x - 10<0?0:x - 10, \ - _p9##x = x - 9<0?0:x - 9, \ - _p8##x = x - 8<0?0:x - 8, \ - _p7##x = x - 7<0?0:x - 7, \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = x + 6>=(img).width()?(img).width() - 1:x + 6, \ - _n7##x = x + 7>=(img).width()?(img).width() - 1:x + 7, \ - _n8##x = x + 8>=(img).width()?(img).width() - 1:x + 8, \ - _n9##x = x + 9>=(img).width()?(img).width() - 1:x + 9, \ - _n10##x = x + 10>=(img).width()?(img).width() - 1:x + 10, \ - _n11##x = x + 11>=(img).width()?(img).width() - 1:x + 11, \ - _n12##x = x + 12>=(img).width()?(img).width() - 1:x + 12, \ - _n13##x = x + 13>=(img).width()?(img).width() - 1:x + 13, \ - _n14##x = (int)( \ - (I[0] = (T)(img)(_p13##x,_p13##y,z,c)), \ - (I[28] = (T)(img)(_p13##x,_p12##y,z,c)), \ - (I[56] = (T)(img)(_p13##x,_p11##y,z,c)), \ - (I[84] = (T)(img)(_p13##x,_p10##y,z,c)), \ - (I[112] = (T)(img)(_p13##x,_p9##y,z,c)), \ - (I[140] = (T)(img)(_p13##x,_p8##y,z,c)), \ - (I[168] = (T)(img)(_p13##x,_p7##y,z,c)), \ - (I[196] = (T)(img)(_p13##x,_p6##y,z,c)), \ - (I[224] = (T)(img)(_p13##x,_p5##y,z,c)), \ - (I[252] = (T)(img)(_p13##x,_p4##y,z,c)), \ - (I[280] = (T)(img)(_p13##x,_p3##y,z,c)), \ - (I[308] = (T)(img)(_p13##x,_p2##y,z,c)), \ - (I[336] = (T)(img)(_p13##x,_p1##y,z,c)), \ - (I[364] = (T)(img)(_p13##x,y,z,c)), \ - (I[392] = (T)(img)(_p13##x,_n1##y,z,c)), \ - (I[420] = (T)(img)(_p13##x,_n2##y,z,c)), \ - (I[448] = (T)(img)(_p13##x,_n3##y,z,c)), \ - (I[476] = (T)(img)(_p13##x,_n4##y,z,c)), \ - (I[504] = (T)(img)(_p13##x,_n5##y,z,c)), \ - (I[532] = (T)(img)(_p13##x,_n6##y,z,c)), \ - (I[560] = (T)(img)(_p13##x,_n7##y,z,c)), \ - (I[588] = (T)(img)(_p13##x,_n8##y,z,c)), \ - (I[616] = (T)(img)(_p13##x,_n9##y,z,c)), \ - (I[644] = (T)(img)(_p13##x,_n10##y,z,c)), \ - (I[672] = (T)(img)(_p13##x,_n11##y,z,c)), \ - (I[700] = (T)(img)(_p13##x,_n12##y,z,c)), \ - (I[728] = (T)(img)(_p13##x,_n13##y,z,c)), \ - (I[756] = (T)(img)(_p13##x,_n14##y,z,c)), \ - (I[1] = (T)(img)(_p12##x,_p13##y,z,c)), \ - (I[29] = (T)(img)(_p12##x,_p12##y,z,c)), \ - (I[57] = (T)(img)(_p12##x,_p11##y,z,c)), \ - (I[85] = (T)(img)(_p12##x,_p10##y,z,c)), \ - (I[113] = (T)(img)(_p12##x,_p9##y,z,c)), \ - (I[141] = (T)(img)(_p12##x,_p8##y,z,c)), \ - (I[169] = (T)(img)(_p12##x,_p7##y,z,c)), \ - (I[197] = (T)(img)(_p12##x,_p6##y,z,c)), \ - (I[225] = (T)(img)(_p12##x,_p5##y,z,c)), \ - (I[253] = (T)(img)(_p12##x,_p4##y,z,c)), \ - (I[281] = (T)(img)(_p12##x,_p3##y,z,c)), \ - (I[309] = (T)(img)(_p12##x,_p2##y,z,c)), \ - (I[337] = (T)(img)(_p12##x,_p1##y,z,c)), \ - (I[365] = (T)(img)(_p12##x,y,z,c)), \ - (I[393] = (T)(img)(_p12##x,_n1##y,z,c)), \ - (I[421] = (T)(img)(_p12##x,_n2##y,z,c)), \ - (I[449] = (T)(img)(_p12##x,_n3##y,z,c)), \ - (I[477] = (T)(img)(_p12##x,_n4##y,z,c)), \ - (I[505] = (T)(img)(_p12##x,_n5##y,z,c)), \ - (I[533] = (T)(img)(_p12##x,_n6##y,z,c)), \ - (I[561] = (T)(img)(_p12##x,_n7##y,z,c)), \ - (I[589] = (T)(img)(_p12##x,_n8##y,z,c)), \ - (I[617] = (T)(img)(_p12##x,_n9##y,z,c)), \ - (I[645] = (T)(img)(_p12##x,_n10##y,z,c)), \ - (I[673] = (T)(img)(_p12##x,_n11##y,z,c)), \ - (I[701] = (T)(img)(_p12##x,_n12##y,z,c)), \ - (I[729] = (T)(img)(_p12##x,_n13##y,z,c)), \ - (I[757] = (T)(img)(_p12##x,_n14##y,z,c)), \ - (I[2] = (T)(img)(_p11##x,_p13##y,z,c)), \ - (I[30] = (T)(img)(_p11##x,_p12##y,z,c)), \ - (I[58] = (T)(img)(_p11##x,_p11##y,z,c)), \ - (I[86] = (T)(img)(_p11##x,_p10##y,z,c)), \ - (I[114] = (T)(img)(_p11##x,_p9##y,z,c)), \ - (I[142] = (T)(img)(_p11##x,_p8##y,z,c)), \ - (I[170] = (T)(img)(_p11##x,_p7##y,z,c)), \ - (I[198] = (T)(img)(_p11##x,_p6##y,z,c)), \ - (I[226] = (T)(img)(_p11##x,_p5##y,z,c)), \ - (I[254] = (T)(img)(_p11##x,_p4##y,z,c)), \ - (I[282] = (T)(img)(_p11##x,_p3##y,z,c)), \ - (I[310] = (T)(img)(_p11##x,_p2##y,z,c)), \ - (I[338] = (T)(img)(_p11##x,_p1##y,z,c)), \ - (I[366] = (T)(img)(_p11##x,y,z,c)), \ - (I[394] = (T)(img)(_p11##x,_n1##y,z,c)), \ - (I[422] = (T)(img)(_p11##x,_n2##y,z,c)), \ - (I[450] = (T)(img)(_p11##x,_n3##y,z,c)), \ - (I[478] = (T)(img)(_p11##x,_n4##y,z,c)), \ - (I[506] = (T)(img)(_p11##x,_n5##y,z,c)), \ - (I[534] = (T)(img)(_p11##x,_n6##y,z,c)), \ - (I[562] = (T)(img)(_p11##x,_n7##y,z,c)), \ - (I[590] = (T)(img)(_p11##x,_n8##y,z,c)), \ - (I[618] = (T)(img)(_p11##x,_n9##y,z,c)), \ - (I[646] = (T)(img)(_p11##x,_n10##y,z,c)), \ - (I[674] = (T)(img)(_p11##x,_n11##y,z,c)), \ - (I[702] = (T)(img)(_p11##x,_n12##y,z,c)), \ - (I[730] = (T)(img)(_p11##x,_n13##y,z,c)), \ - (I[758] = (T)(img)(_p11##x,_n14##y,z,c)), \ - (I[3] = (T)(img)(_p10##x,_p13##y,z,c)), \ - (I[31] = (T)(img)(_p10##x,_p12##y,z,c)), \ - (I[59] = (T)(img)(_p10##x,_p11##y,z,c)), \ - (I[87] = (T)(img)(_p10##x,_p10##y,z,c)), \ - (I[115] = (T)(img)(_p10##x,_p9##y,z,c)), \ - (I[143] = (T)(img)(_p10##x,_p8##y,z,c)), \ - (I[171] = (T)(img)(_p10##x,_p7##y,z,c)), \ - (I[199] = (T)(img)(_p10##x,_p6##y,z,c)), \ - (I[227] = (T)(img)(_p10##x,_p5##y,z,c)), \ - (I[255] = (T)(img)(_p10##x,_p4##y,z,c)), \ - (I[283] = (T)(img)(_p10##x,_p3##y,z,c)), \ - (I[311] = (T)(img)(_p10##x,_p2##y,z,c)), \ - (I[339] = (T)(img)(_p10##x,_p1##y,z,c)), \ - (I[367] = (T)(img)(_p10##x,y,z,c)), \ - (I[395] = (T)(img)(_p10##x,_n1##y,z,c)), \ - (I[423] = (T)(img)(_p10##x,_n2##y,z,c)), \ - (I[451] = (T)(img)(_p10##x,_n3##y,z,c)), \ - (I[479] = (T)(img)(_p10##x,_n4##y,z,c)), \ - (I[507] = (T)(img)(_p10##x,_n5##y,z,c)), \ - (I[535] = (T)(img)(_p10##x,_n6##y,z,c)), \ - (I[563] = (T)(img)(_p10##x,_n7##y,z,c)), \ - (I[591] = (T)(img)(_p10##x,_n8##y,z,c)), \ - (I[619] = (T)(img)(_p10##x,_n9##y,z,c)), \ - (I[647] = (T)(img)(_p10##x,_n10##y,z,c)), \ - (I[675] = (T)(img)(_p10##x,_n11##y,z,c)), \ - (I[703] = (T)(img)(_p10##x,_n12##y,z,c)), \ - (I[731] = (T)(img)(_p10##x,_n13##y,z,c)), \ - (I[759] = (T)(img)(_p10##x,_n14##y,z,c)), \ - (I[4] = (T)(img)(_p9##x,_p13##y,z,c)), \ - (I[32] = (T)(img)(_p9##x,_p12##y,z,c)), \ - (I[60] = (T)(img)(_p9##x,_p11##y,z,c)), \ - (I[88] = (T)(img)(_p9##x,_p10##y,z,c)), \ - (I[116] = (T)(img)(_p9##x,_p9##y,z,c)), \ - (I[144] = (T)(img)(_p9##x,_p8##y,z,c)), \ - (I[172] = (T)(img)(_p9##x,_p7##y,z,c)), \ - (I[200] = (T)(img)(_p9##x,_p6##y,z,c)), \ - (I[228] = (T)(img)(_p9##x,_p5##y,z,c)), \ - (I[256] = (T)(img)(_p9##x,_p4##y,z,c)), \ - (I[284] = (T)(img)(_p9##x,_p3##y,z,c)), \ - (I[312] = (T)(img)(_p9##x,_p2##y,z,c)), \ - (I[340] = (T)(img)(_p9##x,_p1##y,z,c)), \ - (I[368] = (T)(img)(_p9##x,y,z,c)), \ - (I[396] = (T)(img)(_p9##x,_n1##y,z,c)), \ - (I[424] = (T)(img)(_p9##x,_n2##y,z,c)), \ - (I[452] = (T)(img)(_p9##x,_n3##y,z,c)), \ - (I[480] = (T)(img)(_p9##x,_n4##y,z,c)), \ - (I[508] = (T)(img)(_p9##x,_n5##y,z,c)), \ - (I[536] = (T)(img)(_p9##x,_n6##y,z,c)), \ - (I[564] = (T)(img)(_p9##x,_n7##y,z,c)), \ - (I[592] = (T)(img)(_p9##x,_n8##y,z,c)), \ - (I[620] = (T)(img)(_p9##x,_n9##y,z,c)), \ - (I[648] = (T)(img)(_p9##x,_n10##y,z,c)), \ - (I[676] = (T)(img)(_p9##x,_n11##y,z,c)), \ - (I[704] = (T)(img)(_p9##x,_n12##y,z,c)), \ - (I[732] = (T)(img)(_p9##x,_n13##y,z,c)), \ - (I[760] = (T)(img)(_p9##x,_n14##y,z,c)), \ - (I[5] = (T)(img)(_p8##x,_p13##y,z,c)), \ - (I[33] = (T)(img)(_p8##x,_p12##y,z,c)), \ - (I[61] = (T)(img)(_p8##x,_p11##y,z,c)), \ - (I[89] = (T)(img)(_p8##x,_p10##y,z,c)), \ - (I[117] = (T)(img)(_p8##x,_p9##y,z,c)), \ - (I[145] = (T)(img)(_p8##x,_p8##y,z,c)), \ - (I[173] = (T)(img)(_p8##x,_p7##y,z,c)), \ - (I[201] = (T)(img)(_p8##x,_p6##y,z,c)), \ - (I[229] = (T)(img)(_p8##x,_p5##y,z,c)), \ - (I[257] = (T)(img)(_p8##x,_p4##y,z,c)), \ - (I[285] = (T)(img)(_p8##x,_p3##y,z,c)), \ - (I[313] = (T)(img)(_p8##x,_p2##y,z,c)), \ - (I[341] = (T)(img)(_p8##x,_p1##y,z,c)), \ - (I[369] = (T)(img)(_p8##x,y,z,c)), \ - (I[397] = (T)(img)(_p8##x,_n1##y,z,c)), \ - (I[425] = (T)(img)(_p8##x,_n2##y,z,c)), \ - (I[453] = (T)(img)(_p8##x,_n3##y,z,c)), \ - (I[481] = (T)(img)(_p8##x,_n4##y,z,c)), \ - (I[509] = (T)(img)(_p8##x,_n5##y,z,c)), \ - (I[537] = (T)(img)(_p8##x,_n6##y,z,c)), \ - (I[565] = (T)(img)(_p8##x,_n7##y,z,c)), \ - (I[593] = (T)(img)(_p8##x,_n8##y,z,c)), \ - (I[621] = (T)(img)(_p8##x,_n9##y,z,c)), \ - (I[649] = (T)(img)(_p8##x,_n10##y,z,c)), \ - (I[677] = (T)(img)(_p8##x,_n11##y,z,c)), \ - (I[705] = (T)(img)(_p8##x,_n12##y,z,c)), \ - (I[733] = (T)(img)(_p8##x,_n13##y,z,c)), \ - (I[761] = (T)(img)(_p8##x,_n14##y,z,c)), \ - (I[6] = (T)(img)(_p7##x,_p13##y,z,c)), \ - (I[34] = (T)(img)(_p7##x,_p12##y,z,c)), \ - (I[62] = (T)(img)(_p7##x,_p11##y,z,c)), \ - (I[90] = (T)(img)(_p7##x,_p10##y,z,c)), \ - (I[118] = (T)(img)(_p7##x,_p9##y,z,c)), \ - (I[146] = (T)(img)(_p7##x,_p8##y,z,c)), \ - (I[174] = (T)(img)(_p7##x,_p7##y,z,c)), \ - (I[202] = (T)(img)(_p7##x,_p6##y,z,c)), \ - (I[230] = (T)(img)(_p7##x,_p5##y,z,c)), \ - (I[258] = (T)(img)(_p7##x,_p4##y,z,c)), \ - (I[286] = (T)(img)(_p7##x,_p3##y,z,c)), \ - (I[314] = (T)(img)(_p7##x,_p2##y,z,c)), \ - (I[342] = (T)(img)(_p7##x,_p1##y,z,c)), \ - (I[370] = (T)(img)(_p7##x,y,z,c)), \ - (I[398] = (T)(img)(_p7##x,_n1##y,z,c)), \ - (I[426] = (T)(img)(_p7##x,_n2##y,z,c)), \ - (I[454] = (T)(img)(_p7##x,_n3##y,z,c)), \ - (I[482] = (T)(img)(_p7##x,_n4##y,z,c)), \ - (I[510] = (T)(img)(_p7##x,_n5##y,z,c)), \ - (I[538] = (T)(img)(_p7##x,_n6##y,z,c)), \ - (I[566] = (T)(img)(_p7##x,_n7##y,z,c)), \ - (I[594] = (T)(img)(_p7##x,_n8##y,z,c)), \ - (I[622] = (T)(img)(_p7##x,_n9##y,z,c)), \ - (I[650] = (T)(img)(_p7##x,_n10##y,z,c)), \ - (I[678] = (T)(img)(_p7##x,_n11##y,z,c)), \ - (I[706] = (T)(img)(_p7##x,_n12##y,z,c)), \ - (I[734] = (T)(img)(_p7##x,_n13##y,z,c)), \ - (I[762] = (T)(img)(_p7##x,_n14##y,z,c)), \ - (I[7] = (T)(img)(_p6##x,_p13##y,z,c)), \ - (I[35] = (T)(img)(_p6##x,_p12##y,z,c)), \ - (I[63] = (T)(img)(_p6##x,_p11##y,z,c)), \ - (I[91] = (T)(img)(_p6##x,_p10##y,z,c)), \ - (I[119] = (T)(img)(_p6##x,_p9##y,z,c)), \ - (I[147] = (T)(img)(_p6##x,_p8##y,z,c)), \ - (I[175] = (T)(img)(_p6##x,_p7##y,z,c)), \ - (I[203] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[231] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[259] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[287] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[315] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[343] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[371] = (T)(img)(_p6##x,y,z,c)), \ - (I[399] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[427] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[455] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[483] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[511] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[539] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[567] = (T)(img)(_p6##x,_n7##y,z,c)), \ - (I[595] = (T)(img)(_p6##x,_n8##y,z,c)), \ - (I[623] = (T)(img)(_p6##x,_n9##y,z,c)), \ - (I[651] = (T)(img)(_p6##x,_n10##y,z,c)), \ - (I[679] = (T)(img)(_p6##x,_n11##y,z,c)), \ - (I[707] = (T)(img)(_p6##x,_n12##y,z,c)), \ - (I[735] = (T)(img)(_p6##x,_n13##y,z,c)), \ - (I[763] = (T)(img)(_p6##x,_n14##y,z,c)), \ - (I[8] = (T)(img)(_p5##x,_p13##y,z,c)), \ - (I[36] = (T)(img)(_p5##x,_p12##y,z,c)), \ - (I[64] = (T)(img)(_p5##x,_p11##y,z,c)), \ - (I[92] = (T)(img)(_p5##x,_p10##y,z,c)), \ - (I[120] = (T)(img)(_p5##x,_p9##y,z,c)), \ - (I[148] = (T)(img)(_p5##x,_p8##y,z,c)), \ - (I[176] = (T)(img)(_p5##x,_p7##y,z,c)), \ - (I[204] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[232] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[260] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[288] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[316] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[344] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[372] = (T)(img)(_p5##x,y,z,c)), \ - (I[400] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[428] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[456] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[484] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[512] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[540] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[568] = (T)(img)(_p5##x,_n7##y,z,c)), \ - (I[596] = (T)(img)(_p5##x,_n8##y,z,c)), \ - (I[624] = (T)(img)(_p5##x,_n9##y,z,c)), \ - (I[652] = (T)(img)(_p5##x,_n10##y,z,c)), \ - (I[680] = (T)(img)(_p5##x,_n11##y,z,c)), \ - (I[708] = (T)(img)(_p5##x,_n12##y,z,c)), \ - (I[736] = (T)(img)(_p5##x,_n13##y,z,c)), \ - (I[764] = (T)(img)(_p5##x,_n14##y,z,c)), \ - (I[9] = (T)(img)(_p4##x,_p13##y,z,c)), \ - (I[37] = (T)(img)(_p4##x,_p12##y,z,c)), \ - (I[65] = (T)(img)(_p4##x,_p11##y,z,c)), \ - (I[93] = (T)(img)(_p4##x,_p10##y,z,c)), \ - (I[121] = (T)(img)(_p4##x,_p9##y,z,c)), \ - (I[149] = (T)(img)(_p4##x,_p8##y,z,c)), \ - (I[177] = (T)(img)(_p4##x,_p7##y,z,c)), \ - (I[205] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[233] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[261] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[289] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[317] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[345] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[373] = (T)(img)(_p4##x,y,z,c)), \ - (I[401] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[429] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[457] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[485] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[513] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[541] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[569] = (T)(img)(_p4##x,_n7##y,z,c)), \ - (I[597] = (T)(img)(_p4##x,_n8##y,z,c)), \ - (I[625] = (T)(img)(_p4##x,_n9##y,z,c)), \ - (I[653] = (T)(img)(_p4##x,_n10##y,z,c)), \ - (I[681] = (T)(img)(_p4##x,_n11##y,z,c)), \ - (I[709] = (T)(img)(_p4##x,_n12##y,z,c)), \ - (I[737] = (T)(img)(_p4##x,_n13##y,z,c)), \ - (I[765] = (T)(img)(_p4##x,_n14##y,z,c)), \ - (I[10] = (T)(img)(_p3##x,_p13##y,z,c)), \ - (I[38] = (T)(img)(_p3##x,_p12##y,z,c)), \ - (I[66] = (T)(img)(_p3##x,_p11##y,z,c)), \ - (I[94] = (T)(img)(_p3##x,_p10##y,z,c)), \ - (I[122] = (T)(img)(_p3##x,_p9##y,z,c)), \ - (I[150] = (T)(img)(_p3##x,_p8##y,z,c)), \ - (I[178] = (T)(img)(_p3##x,_p7##y,z,c)), \ - (I[206] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[234] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[262] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[290] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[318] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[346] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[374] = (T)(img)(_p3##x,y,z,c)), \ - (I[402] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[430] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[458] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[486] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[514] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[542] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[570] = (T)(img)(_p3##x,_n7##y,z,c)), \ - (I[598] = (T)(img)(_p3##x,_n8##y,z,c)), \ - (I[626] = (T)(img)(_p3##x,_n9##y,z,c)), \ - (I[654] = (T)(img)(_p3##x,_n10##y,z,c)), \ - (I[682] = (T)(img)(_p3##x,_n11##y,z,c)), \ - (I[710] = (T)(img)(_p3##x,_n12##y,z,c)), \ - (I[738] = (T)(img)(_p3##x,_n13##y,z,c)), \ - (I[766] = (T)(img)(_p3##x,_n14##y,z,c)), \ - (I[11] = (T)(img)(_p2##x,_p13##y,z,c)), \ - (I[39] = (T)(img)(_p2##x,_p12##y,z,c)), \ - (I[67] = (T)(img)(_p2##x,_p11##y,z,c)), \ - (I[95] = (T)(img)(_p2##x,_p10##y,z,c)), \ - (I[123] = (T)(img)(_p2##x,_p9##y,z,c)), \ - (I[151] = (T)(img)(_p2##x,_p8##y,z,c)), \ - (I[179] = (T)(img)(_p2##x,_p7##y,z,c)), \ - (I[207] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[235] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[263] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[291] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[319] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[347] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[375] = (T)(img)(_p2##x,y,z,c)), \ - (I[403] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[431] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[459] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[487] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[515] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[543] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[571] = (T)(img)(_p2##x,_n7##y,z,c)), \ - (I[599] = (T)(img)(_p2##x,_n8##y,z,c)), \ - (I[627] = (T)(img)(_p2##x,_n9##y,z,c)), \ - (I[655] = (T)(img)(_p2##x,_n10##y,z,c)), \ - (I[683] = (T)(img)(_p2##x,_n11##y,z,c)), \ - (I[711] = (T)(img)(_p2##x,_n12##y,z,c)), \ - (I[739] = (T)(img)(_p2##x,_n13##y,z,c)), \ - (I[767] = (T)(img)(_p2##x,_n14##y,z,c)), \ - (I[12] = (T)(img)(_p1##x,_p13##y,z,c)), \ - (I[40] = (T)(img)(_p1##x,_p12##y,z,c)), \ - (I[68] = (T)(img)(_p1##x,_p11##y,z,c)), \ - (I[96] = (T)(img)(_p1##x,_p10##y,z,c)), \ - (I[124] = (T)(img)(_p1##x,_p9##y,z,c)), \ - (I[152] = (T)(img)(_p1##x,_p8##y,z,c)), \ - (I[180] = (T)(img)(_p1##x,_p7##y,z,c)), \ - (I[208] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[236] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[264] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[292] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[320] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[348] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[376] = (T)(img)(_p1##x,y,z,c)), \ - (I[404] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[432] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[460] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[488] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[516] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[544] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[572] = (T)(img)(_p1##x,_n7##y,z,c)), \ - (I[600] = (T)(img)(_p1##x,_n8##y,z,c)), \ - (I[628] = (T)(img)(_p1##x,_n9##y,z,c)), \ - (I[656] = (T)(img)(_p1##x,_n10##y,z,c)), \ - (I[684] = (T)(img)(_p1##x,_n11##y,z,c)), \ - (I[712] = (T)(img)(_p1##x,_n12##y,z,c)), \ - (I[740] = (T)(img)(_p1##x,_n13##y,z,c)), \ - (I[768] = (T)(img)(_p1##x,_n14##y,z,c)), \ - (I[13] = (T)(img)(x,_p13##y,z,c)), \ - (I[41] = (T)(img)(x,_p12##y,z,c)), \ - (I[69] = (T)(img)(x,_p11##y,z,c)), \ - (I[97] = (T)(img)(x,_p10##y,z,c)), \ - (I[125] = (T)(img)(x,_p9##y,z,c)), \ - (I[153] = (T)(img)(x,_p8##y,z,c)), \ - (I[181] = (T)(img)(x,_p7##y,z,c)), \ - (I[209] = (T)(img)(x,_p6##y,z,c)), \ - (I[237] = (T)(img)(x,_p5##y,z,c)), \ - (I[265] = (T)(img)(x,_p4##y,z,c)), \ - (I[293] = (T)(img)(x,_p3##y,z,c)), \ - (I[321] = (T)(img)(x,_p2##y,z,c)), \ - (I[349] = (T)(img)(x,_p1##y,z,c)), \ - (I[377] = (T)(img)(x,y,z,c)), \ - (I[405] = (T)(img)(x,_n1##y,z,c)), \ - (I[433] = (T)(img)(x,_n2##y,z,c)), \ - (I[461] = (T)(img)(x,_n3##y,z,c)), \ - (I[489] = (T)(img)(x,_n4##y,z,c)), \ - (I[517] = (T)(img)(x,_n5##y,z,c)), \ - (I[545] = (T)(img)(x,_n6##y,z,c)), \ - (I[573] = (T)(img)(x,_n7##y,z,c)), \ - (I[601] = (T)(img)(x,_n8##y,z,c)), \ - (I[629] = (T)(img)(x,_n9##y,z,c)), \ - (I[657] = (T)(img)(x,_n10##y,z,c)), \ - (I[685] = (T)(img)(x,_n11##y,z,c)), \ - (I[713] = (T)(img)(x,_n12##y,z,c)), \ - (I[741] = (T)(img)(x,_n13##y,z,c)), \ - (I[769] = (T)(img)(x,_n14##y,z,c)), \ - (I[14] = (T)(img)(_n1##x,_p13##y,z,c)), \ - (I[42] = (T)(img)(_n1##x,_p12##y,z,c)), \ - (I[70] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[98] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[126] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[154] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[182] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[210] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[238] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[266] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[294] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[322] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[350] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[378] = (T)(img)(_n1##x,y,z,c)), \ - (I[406] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[434] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[462] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[490] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[518] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[546] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[574] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[602] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[630] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[658] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[686] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[714] = (T)(img)(_n1##x,_n12##y,z,c)), \ - (I[742] = (T)(img)(_n1##x,_n13##y,z,c)), \ - (I[770] = (T)(img)(_n1##x,_n14##y,z,c)), \ - (I[15] = (T)(img)(_n2##x,_p13##y,z,c)), \ - (I[43] = (T)(img)(_n2##x,_p12##y,z,c)), \ - (I[71] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[99] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[127] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[155] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[183] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[211] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[239] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[267] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[295] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[323] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[351] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[379] = (T)(img)(_n2##x,y,z,c)), \ - (I[407] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[435] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[463] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[491] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[519] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[547] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[575] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[603] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[631] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[659] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[687] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[715] = (T)(img)(_n2##x,_n12##y,z,c)), \ - (I[743] = (T)(img)(_n2##x,_n13##y,z,c)), \ - (I[771] = (T)(img)(_n2##x,_n14##y,z,c)), \ - (I[16] = (T)(img)(_n3##x,_p13##y,z,c)), \ - (I[44] = (T)(img)(_n3##x,_p12##y,z,c)), \ - (I[72] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[100] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[128] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[156] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[184] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[212] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[240] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[268] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[296] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[324] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[352] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[380] = (T)(img)(_n3##x,y,z,c)), \ - (I[408] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[436] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[464] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[492] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[520] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[548] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[576] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[604] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[632] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[660] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[688] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[716] = (T)(img)(_n3##x,_n12##y,z,c)), \ - (I[744] = (T)(img)(_n3##x,_n13##y,z,c)), \ - (I[772] = (T)(img)(_n3##x,_n14##y,z,c)), \ - (I[17] = (T)(img)(_n4##x,_p13##y,z,c)), \ - (I[45] = (T)(img)(_n4##x,_p12##y,z,c)), \ - (I[73] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[101] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[129] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[157] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[185] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[213] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[241] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[269] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[297] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[325] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[353] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[381] = (T)(img)(_n4##x,y,z,c)), \ - (I[409] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[437] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[465] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[493] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[521] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[549] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[577] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[605] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[633] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[661] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[689] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[717] = (T)(img)(_n4##x,_n12##y,z,c)), \ - (I[745] = (T)(img)(_n4##x,_n13##y,z,c)), \ - (I[773] = (T)(img)(_n4##x,_n14##y,z,c)), \ - (I[18] = (T)(img)(_n5##x,_p13##y,z,c)), \ - (I[46] = (T)(img)(_n5##x,_p12##y,z,c)), \ - (I[74] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[102] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[130] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[158] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[186] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[214] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[242] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[270] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[298] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[326] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[354] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[382] = (T)(img)(_n5##x,y,z,c)), \ - (I[410] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[438] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[466] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[494] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[522] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[550] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[578] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[606] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[634] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[662] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[690] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[718] = (T)(img)(_n5##x,_n12##y,z,c)), \ - (I[746] = (T)(img)(_n5##x,_n13##y,z,c)), \ - (I[774] = (T)(img)(_n5##x,_n14##y,z,c)), \ - (I[19] = (T)(img)(_n6##x,_p13##y,z,c)), \ - (I[47] = (T)(img)(_n6##x,_p12##y,z,c)), \ - (I[75] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[103] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[131] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[159] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[187] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[215] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[243] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[271] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[299] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[327] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[355] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[383] = (T)(img)(_n6##x,y,z,c)), \ - (I[411] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[439] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[467] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[495] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[523] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[551] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[579] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[607] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[635] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[663] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[691] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[719] = (T)(img)(_n6##x,_n12##y,z,c)), \ - (I[747] = (T)(img)(_n6##x,_n13##y,z,c)), \ - (I[775] = (T)(img)(_n6##x,_n14##y,z,c)), \ - (I[20] = (T)(img)(_n7##x,_p13##y,z,c)), \ - (I[48] = (T)(img)(_n7##x,_p12##y,z,c)), \ - (I[76] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[104] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[132] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[160] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[188] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[216] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[244] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[272] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[300] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[328] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[356] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[384] = (T)(img)(_n7##x,y,z,c)), \ - (I[412] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[440] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[468] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[496] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[524] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[552] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[580] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[608] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[636] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[664] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[692] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[720] = (T)(img)(_n7##x,_n12##y,z,c)), \ - (I[748] = (T)(img)(_n7##x,_n13##y,z,c)), \ - (I[776] = (T)(img)(_n7##x,_n14##y,z,c)), \ - (I[21] = (T)(img)(_n8##x,_p13##y,z,c)), \ - (I[49] = (T)(img)(_n8##x,_p12##y,z,c)), \ - (I[77] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[105] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[133] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[161] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[189] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[217] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[245] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[273] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[301] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[329] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[357] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[385] = (T)(img)(_n8##x,y,z,c)), \ - (I[413] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[441] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[469] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[497] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[525] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[553] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[581] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[609] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[637] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[665] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[693] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[721] = (T)(img)(_n8##x,_n12##y,z,c)), \ - (I[749] = (T)(img)(_n8##x,_n13##y,z,c)), \ - (I[777] = (T)(img)(_n8##x,_n14##y,z,c)), \ - (I[22] = (T)(img)(_n9##x,_p13##y,z,c)), \ - (I[50] = (T)(img)(_n9##x,_p12##y,z,c)), \ - (I[78] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[106] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[134] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[162] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[190] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[218] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[246] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[274] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[302] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[330] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[358] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[386] = (T)(img)(_n9##x,y,z,c)), \ - (I[414] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[442] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[470] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[498] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[526] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[554] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[582] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[610] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[638] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[666] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[694] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[722] = (T)(img)(_n9##x,_n12##y,z,c)), \ - (I[750] = (T)(img)(_n9##x,_n13##y,z,c)), \ - (I[778] = (T)(img)(_n9##x,_n14##y,z,c)), \ - (I[23] = (T)(img)(_n10##x,_p13##y,z,c)), \ - (I[51] = (T)(img)(_n10##x,_p12##y,z,c)), \ - (I[79] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[107] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[135] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[163] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[191] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[219] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[247] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[275] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[303] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[331] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[359] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[387] = (T)(img)(_n10##x,y,z,c)), \ - (I[415] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[443] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[471] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[499] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[527] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[555] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[583] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[611] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[639] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[667] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[695] = (T)(img)(_n10##x,_n11##y,z,c)), \ - (I[723] = (T)(img)(_n10##x,_n12##y,z,c)), \ - (I[751] = (T)(img)(_n10##x,_n13##y,z,c)), \ - (I[779] = (T)(img)(_n10##x,_n14##y,z,c)), \ - (I[24] = (T)(img)(_n11##x,_p13##y,z,c)), \ - (I[52] = (T)(img)(_n11##x,_p12##y,z,c)), \ - (I[80] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[108] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[136] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[164] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[192] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[220] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[248] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[276] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[304] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[332] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[360] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[388] = (T)(img)(_n11##x,y,z,c)), \ - (I[416] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[444] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[472] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[500] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[528] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[556] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[584] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[612] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[640] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[668] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[696] = (T)(img)(_n11##x,_n11##y,z,c)), \ - (I[724] = (T)(img)(_n11##x,_n12##y,z,c)), \ - (I[752] = (T)(img)(_n11##x,_n13##y,z,c)), \ - (I[780] = (T)(img)(_n11##x,_n14##y,z,c)), \ - (I[25] = (T)(img)(_n12##x,_p13##y,z,c)), \ - (I[53] = (T)(img)(_n12##x,_p12##y,z,c)), \ - (I[81] = (T)(img)(_n12##x,_p11##y,z,c)), \ - (I[109] = (T)(img)(_n12##x,_p10##y,z,c)), \ - (I[137] = (T)(img)(_n12##x,_p9##y,z,c)), \ - (I[165] = (T)(img)(_n12##x,_p8##y,z,c)), \ - (I[193] = (T)(img)(_n12##x,_p7##y,z,c)), \ - (I[221] = (T)(img)(_n12##x,_p6##y,z,c)), \ - (I[249] = (T)(img)(_n12##x,_p5##y,z,c)), \ - (I[277] = (T)(img)(_n12##x,_p4##y,z,c)), \ - (I[305] = (T)(img)(_n12##x,_p3##y,z,c)), \ - (I[333] = (T)(img)(_n12##x,_p2##y,z,c)), \ - (I[361] = (T)(img)(_n12##x,_p1##y,z,c)), \ - (I[389] = (T)(img)(_n12##x,y,z,c)), \ - (I[417] = (T)(img)(_n12##x,_n1##y,z,c)), \ - (I[445] = (T)(img)(_n12##x,_n2##y,z,c)), \ - (I[473] = (T)(img)(_n12##x,_n3##y,z,c)), \ - (I[501] = (T)(img)(_n12##x,_n4##y,z,c)), \ - (I[529] = (T)(img)(_n12##x,_n5##y,z,c)), \ - (I[557] = (T)(img)(_n12##x,_n6##y,z,c)), \ - (I[585] = (T)(img)(_n12##x,_n7##y,z,c)), \ - (I[613] = (T)(img)(_n12##x,_n8##y,z,c)), \ - (I[641] = (T)(img)(_n12##x,_n9##y,z,c)), \ - (I[669] = (T)(img)(_n12##x,_n10##y,z,c)), \ - (I[697] = (T)(img)(_n12##x,_n11##y,z,c)), \ - (I[725] = (T)(img)(_n12##x,_n12##y,z,c)), \ - (I[753] = (T)(img)(_n12##x,_n13##y,z,c)), \ - (I[781] = (T)(img)(_n12##x,_n14##y,z,c)), \ - (I[26] = (T)(img)(_n13##x,_p13##y,z,c)), \ - (I[54] = (T)(img)(_n13##x,_p12##y,z,c)), \ - (I[82] = (T)(img)(_n13##x,_p11##y,z,c)), \ - (I[110] = (T)(img)(_n13##x,_p10##y,z,c)), \ - (I[138] = (T)(img)(_n13##x,_p9##y,z,c)), \ - (I[166] = (T)(img)(_n13##x,_p8##y,z,c)), \ - (I[194] = (T)(img)(_n13##x,_p7##y,z,c)), \ - (I[222] = (T)(img)(_n13##x,_p6##y,z,c)), \ - (I[250] = (T)(img)(_n13##x,_p5##y,z,c)), \ - (I[278] = (T)(img)(_n13##x,_p4##y,z,c)), \ - (I[306] = (T)(img)(_n13##x,_p3##y,z,c)), \ - (I[334] = (T)(img)(_n13##x,_p2##y,z,c)), \ - (I[362] = (T)(img)(_n13##x,_p1##y,z,c)), \ - (I[390] = (T)(img)(_n13##x,y,z,c)), \ - (I[418] = (T)(img)(_n13##x,_n1##y,z,c)), \ - (I[446] = (T)(img)(_n13##x,_n2##y,z,c)), \ - (I[474] = (T)(img)(_n13##x,_n3##y,z,c)), \ - (I[502] = (T)(img)(_n13##x,_n4##y,z,c)), \ - (I[530] = (T)(img)(_n13##x,_n5##y,z,c)), \ - (I[558] = (T)(img)(_n13##x,_n6##y,z,c)), \ - (I[586] = (T)(img)(_n13##x,_n7##y,z,c)), \ - (I[614] = (T)(img)(_n13##x,_n8##y,z,c)), \ - (I[642] = (T)(img)(_n13##x,_n9##y,z,c)), \ - (I[670] = (T)(img)(_n13##x,_n10##y,z,c)), \ - (I[698] = (T)(img)(_n13##x,_n11##y,z,c)), \ - (I[726] = (T)(img)(_n13##x,_n12##y,z,c)), \ - (I[754] = (T)(img)(_n13##x,_n13##y,z,c)), \ - (I[782] = (T)(img)(_n13##x,_n14##y,z,c)), \ - x + 14>=(img).width()?(img).width() - 1:x + 14); \ - x<=(int)(x1) && ((_n14##x<(img).width() && ( \ - (I[27] = (T)(img)(_n14##x,_p13##y,z,c)), \ - (I[55] = (T)(img)(_n14##x,_p12##y,z,c)), \ - (I[83] = (T)(img)(_n14##x,_p11##y,z,c)), \ - (I[111] = (T)(img)(_n14##x,_p10##y,z,c)), \ - (I[139] = (T)(img)(_n14##x,_p9##y,z,c)), \ - (I[167] = (T)(img)(_n14##x,_p8##y,z,c)), \ - (I[195] = (T)(img)(_n14##x,_p7##y,z,c)), \ - (I[223] = (T)(img)(_n14##x,_p6##y,z,c)), \ - (I[251] = (T)(img)(_n14##x,_p5##y,z,c)), \ - (I[279] = (T)(img)(_n14##x,_p4##y,z,c)), \ - (I[307] = (T)(img)(_n14##x,_p3##y,z,c)), \ - (I[335] = (T)(img)(_n14##x,_p2##y,z,c)), \ - (I[363] = (T)(img)(_n14##x,_p1##y,z,c)), \ - (I[391] = (T)(img)(_n14##x,y,z,c)), \ - (I[419] = (T)(img)(_n14##x,_n1##y,z,c)), \ - (I[447] = (T)(img)(_n14##x,_n2##y,z,c)), \ - (I[475] = (T)(img)(_n14##x,_n3##y,z,c)), \ - (I[503] = (T)(img)(_n14##x,_n4##y,z,c)), \ - (I[531] = (T)(img)(_n14##x,_n5##y,z,c)), \ - (I[559] = (T)(img)(_n14##x,_n6##y,z,c)), \ - (I[587] = (T)(img)(_n14##x,_n7##y,z,c)), \ - (I[615] = (T)(img)(_n14##x,_n8##y,z,c)), \ - (I[643] = (T)(img)(_n14##x,_n9##y,z,c)), \ - (I[671] = (T)(img)(_n14##x,_n10##y,z,c)), \ - (I[699] = (T)(img)(_n14##x,_n11##y,z,c)), \ - (I[727] = (T)(img)(_n14##x,_n12##y,z,c)), \ - (I[755] = (T)(img)(_n14##x,_n13##y,z,c)), \ - (I[783] = (T)(img)(_n14##x,_n14##y,z,c)),1)) || \ - _n13##x==--_n14##x || _n12##x==--_n13##x || _n11##x==--_n12##x || _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n14##x = _n13##x = _n12##x = _n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], \ - I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], \ - I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], \ - I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], \ - I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], \ - I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], \ - I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], \ - I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], \ - I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], \ - I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], \ - I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], \ - I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], \ - I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], \ - I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], \ - I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], I[415] = I[416], I[416] = I[417], I[417] = I[418], I[418] = I[419], \ - I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], \ - I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], I[463] = I[464], I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], \ - I[476] = I[477], I[477] = I[478], I[478] = I[479], I[479] = I[480], I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], I[493] = I[494], I[494] = I[495], I[495] = I[496], I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], \ - I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], I[511] = I[512], I[512] = I[513], I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], I[519] = I[520], I[520] = I[521], I[521] = I[522], I[522] = I[523], I[523] = I[524], I[524] = I[525], I[525] = I[526], I[526] = I[527], I[527] = I[528], I[528] = I[529], I[529] = I[530], I[530] = I[531], \ - I[532] = I[533], I[533] = I[534], I[534] = I[535], I[535] = I[536], I[536] = I[537], I[537] = I[538], I[538] = I[539], I[539] = I[540], I[540] = I[541], I[541] = I[542], I[542] = I[543], I[543] = I[544], I[544] = I[545], I[545] = I[546], I[546] = I[547], I[547] = I[548], I[548] = I[549], I[549] = I[550], I[550] = I[551], I[551] = I[552], I[552] = I[553], I[553] = I[554], I[554] = I[555], I[555] = I[556], I[556] = I[557], I[557] = I[558], I[558] = I[559], \ - I[560] = I[561], I[561] = I[562], I[562] = I[563], I[563] = I[564], I[564] = I[565], I[565] = I[566], I[566] = I[567], I[567] = I[568], I[568] = I[569], I[569] = I[570], I[570] = I[571], I[571] = I[572], I[572] = I[573], I[573] = I[574], I[574] = I[575], I[575] = I[576], I[576] = I[577], I[577] = I[578], I[578] = I[579], I[579] = I[580], I[580] = I[581], I[581] = I[582], I[582] = I[583], I[583] = I[584], I[584] = I[585], I[585] = I[586], I[586] = I[587], \ - I[588] = I[589], I[589] = I[590], I[590] = I[591], I[591] = I[592], I[592] = I[593], I[593] = I[594], I[594] = I[595], I[595] = I[596], I[596] = I[597], I[597] = I[598], I[598] = I[599], I[599] = I[600], I[600] = I[601], I[601] = I[602], I[602] = I[603], I[603] = I[604], I[604] = I[605], I[605] = I[606], I[606] = I[607], I[607] = I[608], I[608] = I[609], I[609] = I[610], I[610] = I[611], I[611] = I[612], I[612] = I[613], I[613] = I[614], I[614] = I[615], \ - I[616] = I[617], I[617] = I[618], I[618] = I[619], I[619] = I[620], I[620] = I[621], I[621] = I[622], I[622] = I[623], I[623] = I[624], I[624] = I[625], I[625] = I[626], I[626] = I[627], I[627] = I[628], I[628] = I[629], I[629] = I[630], I[630] = I[631], I[631] = I[632], I[632] = I[633], I[633] = I[634], I[634] = I[635], I[635] = I[636], I[636] = I[637], I[637] = I[638], I[638] = I[639], I[639] = I[640], I[640] = I[641], I[641] = I[642], I[642] = I[643], \ - I[644] = I[645], I[645] = I[646], I[646] = I[647], I[647] = I[648], I[648] = I[649], I[649] = I[650], I[650] = I[651], I[651] = I[652], I[652] = I[653], I[653] = I[654], I[654] = I[655], I[655] = I[656], I[656] = I[657], I[657] = I[658], I[658] = I[659], I[659] = I[660], I[660] = I[661], I[661] = I[662], I[662] = I[663], I[663] = I[664], I[664] = I[665], I[665] = I[666], I[666] = I[667], I[667] = I[668], I[668] = I[669], I[669] = I[670], I[670] = I[671], \ - I[672] = I[673], I[673] = I[674], I[674] = I[675], I[675] = I[676], I[676] = I[677], I[677] = I[678], I[678] = I[679], I[679] = I[680], I[680] = I[681], I[681] = I[682], I[682] = I[683], I[683] = I[684], I[684] = I[685], I[685] = I[686], I[686] = I[687], I[687] = I[688], I[688] = I[689], I[689] = I[690], I[690] = I[691], I[691] = I[692], I[692] = I[693], I[693] = I[694], I[694] = I[695], I[695] = I[696], I[696] = I[697], I[697] = I[698], I[698] = I[699], \ - I[700] = I[701], I[701] = I[702], I[702] = I[703], I[703] = I[704], I[704] = I[705], I[705] = I[706], I[706] = I[707], I[707] = I[708], I[708] = I[709], I[709] = I[710], I[710] = I[711], I[711] = I[712], I[712] = I[713], I[713] = I[714], I[714] = I[715], I[715] = I[716], I[716] = I[717], I[717] = I[718], I[718] = I[719], I[719] = I[720], I[720] = I[721], I[721] = I[722], I[722] = I[723], I[723] = I[724], I[724] = I[725], I[725] = I[726], I[726] = I[727], \ - I[728] = I[729], I[729] = I[730], I[730] = I[731], I[731] = I[732], I[732] = I[733], I[733] = I[734], I[734] = I[735], I[735] = I[736], I[736] = I[737], I[737] = I[738], I[738] = I[739], I[739] = I[740], I[740] = I[741], I[741] = I[742], I[742] = I[743], I[743] = I[744], I[744] = I[745], I[745] = I[746], I[746] = I[747], I[747] = I[748], I[748] = I[749], I[749] = I[750], I[750] = I[751], I[751] = I[752], I[752] = I[753], I[753] = I[754], I[754] = I[755], \ - I[756] = I[757], I[757] = I[758], I[758] = I[759], I[759] = I[760], I[760] = I[761], I[761] = I[762], I[762] = I[763], I[763] = I[764], I[764] = I[765], I[765] = I[766], I[766] = I[767], I[767] = I[768], I[768] = I[769], I[769] = I[770], I[770] = I[771], I[771] = I[772], I[772] = I[773], I[773] = I[774], I[774] = I[775], I[775] = I[776], I[776] = I[777], I[777] = I[778], I[778] = I[779], I[779] = I[780], I[780] = I[781], I[781] = I[782], I[782] = I[783], \ - _p13##x = _p12##x, _p12##x = _p11##x, _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x, ++_n12##x, ++_n13##x, ++_n14##x) - -#define cimg_get28x28(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p13##x,_p13##y,z,c), I[1] = (T)(img)(_p12##x,_p13##y,z,c), I[2] = (T)(img)(_p11##x,_p13##y,z,c), I[3] = (T)(img)(_p10##x,_p13##y,z,c), I[4] = (T)(img)(_p9##x,_p13##y,z,c), I[5] = (T)(img)(_p8##x,_p13##y,z,c), I[6] = (T)(img)(_p7##x,_p13##y,z,c), I[7] = (T)(img)(_p6##x,_p13##y,z,c), I[8] = (T)(img)(_p5##x,_p13##y,z,c), I[9] = (T)(img)(_p4##x,_p13##y,z,c), I[10] = (T)(img)(_p3##x,_p13##y,z,c), I[11] = (T)(img)(_p2##x,_p13##y,z,c), I[12] = (T)(img)(_p1##x,_p13##y,z,c), I[13] = (T)(img)(x,_p13##y,z,c), I[14] = (T)(img)(_n1##x,_p13##y,z,c), I[15] = (T)(img)(_n2##x,_p13##y,z,c), I[16] = (T)(img)(_n3##x,_p13##y,z,c), I[17] = (T)(img)(_n4##x,_p13##y,z,c), I[18] = (T)(img)(_n5##x,_p13##y,z,c), I[19] = (T)(img)(_n6##x,_p13##y,z,c), I[20] = (T)(img)(_n7##x,_p13##y,z,c), I[21] = (T)(img)(_n8##x,_p13##y,z,c), I[22] = (T)(img)(_n9##x,_p13##y,z,c), I[23] = (T)(img)(_n10##x,_p13##y,z,c), I[24] = (T)(img)(_n11##x,_p13##y,z,c), I[25] = (T)(img)(_n12##x,_p13##y,z,c), I[26] = (T)(img)(_n13##x,_p13##y,z,c), I[27] = (T)(img)(_n14##x,_p13##y,z,c), \ - I[28] = (T)(img)(_p13##x,_p12##y,z,c), I[29] = (T)(img)(_p12##x,_p12##y,z,c), I[30] = (T)(img)(_p11##x,_p12##y,z,c), I[31] = (T)(img)(_p10##x,_p12##y,z,c), I[32] = (T)(img)(_p9##x,_p12##y,z,c), I[33] = (T)(img)(_p8##x,_p12##y,z,c), I[34] = (T)(img)(_p7##x,_p12##y,z,c), I[35] = (T)(img)(_p6##x,_p12##y,z,c), I[36] = (T)(img)(_p5##x,_p12##y,z,c), I[37] = (T)(img)(_p4##x,_p12##y,z,c), I[38] = (T)(img)(_p3##x,_p12##y,z,c), I[39] = (T)(img)(_p2##x,_p12##y,z,c), I[40] = (T)(img)(_p1##x,_p12##y,z,c), I[41] = (T)(img)(x,_p12##y,z,c), I[42] = (T)(img)(_n1##x,_p12##y,z,c), I[43] = (T)(img)(_n2##x,_p12##y,z,c), I[44] = (T)(img)(_n3##x,_p12##y,z,c), I[45] = (T)(img)(_n4##x,_p12##y,z,c), I[46] = (T)(img)(_n5##x,_p12##y,z,c), I[47] = (T)(img)(_n6##x,_p12##y,z,c), I[48] = (T)(img)(_n7##x,_p12##y,z,c), I[49] = (T)(img)(_n8##x,_p12##y,z,c), I[50] = (T)(img)(_n9##x,_p12##y,z,c), I[51] = (T)(img)(_n10##x,_p12##y,z,c), I[52] = (T)(img)(_n11##x,_p12##y,z,c), I[53] = (T)(img)(_n12##x,_p12##y,z,c), I[54] = (T)(img)(_n13##x,_p12##y,z,c), I[55] = (T)(img)(_n14##x,_p12##y,z,c), \ - I[56] = (T)(img)(_p13##x,_p11##y,z,c), I[57] = (T)(img)(_p12##x,_p11##y,z,c), I[58] = (T)(img)(_p11##x,_p11##y,z,c), I[59] = (T)(img)(_p10##x,_p11##y,z,c), I[60] = (T)(img)(_p9##x,_p11##y,z,c), I[61] = (T)(img)(_p8##x,_p11##y,z,c), I[62] = (T)(img)(_p7##x,_p11##y,z,c), I[63] = (T)(img)(_p6##x,_p11##y,z,c), I[64] = (T)(img)(_p5##x,_p11##y,z,c), I[65] = (T)(img)(_p4##x,_p11##y,z,c), I[66] = (T)(img)(_p3##x,_p11##y,z,c), I[67] = (T)(img)(_p2##x,_p11##y,z,c), I[68] = (T)(img)(_p1##x,_p11##y,z,c), I[69] = (T)(img)(x,_p11##y,z,c), I[70] = (T)(img)(_n1##x,_p11##y,z,c), I[71] = (T)(img)(_n2##x,_p11##y,z,c), I[72] = (T)(img)(_n3##x,_p11##y,z,c), I[73] = (T)(img)(_n4##x,_p11##y,z,c), I[74] = (T)(img)(_n5##x,_p11##y,z,c), I[75] = (T)(img)(_n6##x,_p11##y,z,c), I[76] = (T)(img)(_n7##x,_p11##y,z,c), I[77] = (T)(img)(_n8##x,_p11##y,z,c), I[78] = (T)(img)(_n9##x,_p11##y,z,c), I[79] = (T)(img)(_n10##x,_p11##y,z,c), I[80] = (T)(img)(_n11##x,_p11##y,z,c), I[81] = (T)(img)(_n12##x,_p11##y,z,c), I[82] = (T)(img)(_n13##x,_p11##y,z,c), I[83] = (T)(img)(_n14##x,_p11##y,z,c), \ - I[84] = (T)(img)(_p13##x,_p10##y,z,c), I[85] = (T)(img)(_p12##x,_p10##y,z,c), I[86] = (T)(img)(_p11##x,_p10##y,z,c), I[87] = (T)(img)(_p10##x,_p10##y,z,c), I[88] = (T)(img)(_p9##x,_p10##y,z,c), I[89] = (T)(img)(_p8##x,_p10##y,z,c), I[90] = (T)(img)(_p7##x,_p10##y,z,c), I[91] = (T)(img)(_p6##x,_p10##y,z,c), I[92] = (T)(img)(_p5##x,_p10##y,z,c), I[93] = (T)(img)(_p4##x,_p10##y,z,c), I[94] = (T)(img)(_p3##x,_p10##y,z,c), I[95] = (T)(img)(_p2##x,_p10##y,z,c), I[96] = (T)(img)(_p1##x,_p10##y,z,c), I[97] = (T)(img)(x,_p10##y,z,c), I[98] = (T)(img)(_n1##x,_p10##y,z,c), I[99] = (T)(img)(_n2##x,_p10##y,z,c), I[100] = (T)(img)(_n3##x,_p10##y,z,c), I[101] = (T)(img)(_n4##x,_p10##y,z,c), I[102] = (T)(img)(_n5##x,_p10##y,z,c), I[103] = (T)(img)(_n6##x,_p10##y,z,c), I[104] = (T)(img)(_n7##x,_p10##y,z,c), I[105] = (T)(img)(_n8##x,_p10##y,z,c), I[106] = (T)(img)(_n9##x,_p10##y,z,c), I[107] = (T)(img)(_n10##x,_p10##y,z,c), I[108] = (T)(img)(_n11##x,_p10##y,z,c), I[109] = (T)(img)(_n12##x,_p10##y,z,c), I[110] = (T)(img)(_n13##x,_p10##y,z,c), I[111] = (T)(img)(_n14##x,_p10##y,z,c), \ - I[112] = (T)(img)(_p13##x,_p9##y,z,c), I[113] = (T)(img)(_p12##x,_p9##y,z,c), I[114] = (T)(img)(_p11##x,_p9##y,z,c), I[115] = (T)(img)(_p10##x,_p9##y,z,c), I[116] = (T)(img)(_p9##x,_p9##y,z,c), I[117] = (T)(img)(_p8##x,_p9##y,z,c), I[118] = (T)(img)(_p7##x,_p9##y,z,c), I[119] = (T)(img)(_p6##x,_p9##y,z,c), I[120] = (T)(img)(_p5##x,_p9##y,z,c), I[121] = (T)(img)(_p4##x,_p9##y,z,c), I[122] = (T)(img)(_p3##x,_p9##y,z,c), I[123] = (T)(img)(_p2##x,_p9##y,z,c), I[124] = (T)(img)(_p1##x,_p9##y,z,c), I[125] = (T)(img)(x,_p9##y,z,c), I[126] = (T)(img)(_n1##x,_p9##y,z,c), I[127] = (T)(img)(_n2##x,_p9##y,z,c), I[128] = (T)(img)(_n3##x,_p9##y,z,c), I[129] = (T)(img)(_n4##x,_p9##y,z,c), I[130] = (T)(img)(_n5##x,_p9##y,z,c), I[131] = (T)(img)(_n6##x,_p9##y,z,c), I[132] = (T)(img)(_n7##x,_p9##y,z,c), I[133] = (T)(img)(_n8##x,_p9##y,z,c), I[134] = (T)(img)(_n9##x,_p9##y,z,c), I[135] = (T)(img)(_n10##x,_p9##y,z,c), I[136] = (T)(img)(_n11##x,_p9##y,z,c), I[137] = (T)(img)(_n12##x,_p9##y,z,c), I[138] = (T)(img)(_n13##x,_p9##y,z,c), I[139] = (T)(img)(_n14##x,_p9##y,z,c), \ - I[140] = (T)(img)(_p13##x,_p8##y,z,c), I[141] = (T)(img)(_p12##x,_p8##y,z,c), I[142] = (T)(img)(_p11##x,_p8##y,z,c), I[143] = (T)(img)(_p10##x,_p8##y,z,c), I[144] = (T)(img)(_p9##x,_p8##y,z,c), I[145] = (T)(img)(_p8##x,_p8##y,z,c), I[146] = (T)(img)(_p7##x,_p8##y,z,c), I[147] = (T)(img)(_p6##x,_p8##y,z,c), I[148] = (T)(img)(_p5##x,_p8##y,z,c), I[149] = (T)(img)(_p4##x,_p8##y,z,c), I[150] = (T)(img)(_p3##x,_p8##y,z,c), I[151] = (T)(img)(_p2##x,_p8##y,z,c), I[152] = (T)(img)(_p1##x,_p8##y,z,c), I[153] = (T)(img)(x,_p8##y,z,c), I[154] = (T)(img)(_n1##x,_p8##y,z,c), I[155] = (T)(img)(_n2##x,_p8##y,z,c), I[156] = (T)(img)(_n3##x,_p8##y,z,c), I[157] = (T)(img)(_n4##x,_p8##y,z,c), I[158] = (T)(img)(_n5##x,_p8##y,z,c), I[159] = (T)(img)(_n6##x,_p8##y,z,c), I[160] = (T)(img)(_n7##x,_p8##y,z,c), I[161] = (T)(img)(_n8##x,_p8##y,z,c), I[162] = (T)(img)(_n9##x,_p8##y,z,c), I[163] = (T)(img)(_n10##x,_p8##y,z,c), I[164] = (T)(img)(_n11##x,_p8##y,z,c), I[165] = (T)(img)(_n12##x,_p8##y,z,c), I[166] = (T)(img)(_n13##x,_p8##y,z,c), I[167] = (T)(img)(_n14##x,_p8##y,z,c), \ - I[168] = (T)(img)(_p13##x,_p7##y,z,c), I[169] = (T)(img)(_p12##x,_p7##y,z,c), I[170] = (T)(img)(_p11##x,_p7##y,z,c), I[171] = (T)(img)(_p10##x,_p7##y,z,c), I[172] = (T)(img)(_p9##x,_p7##y,z,c), I[173] = (T)(img)(_p8##x,_p7##y,z,c), I[174] = (T)(img)(_p7##x,_p7##y,z,c), I[175] = (T)(img)(_p6##x,_p7##y,z,c), I[176] = (T)(img)(_p5##x,_p7##y,z,c), I[177] = (T)(img)(_p4##x,_p7##y,z,c), I[178] = (T)(img)(_p3##x,_p7##y,z,c), I[179] = (T)(img)(_p2##x,_p7##y,z,c), I[180] = (T)(img)(_p1##x,_p7##y,z,c), I[181] = (T)(img)(x,_p7##y,z,c), I[182] = (T)(img)(_n1##x,_p7##y,z,c), I[183] = (T)(img)(_n2##x,_p7##y,z,c), I[184] = (T)(img)(_n3##x,_p7##y,z,c), I[185] = (T)(img)(_n4##x,_p7##y,z,c), I[186] = (T)(img)(_n5##x,_p7##y,z,c), I[187] = (T)(img)(_n6##x,_p7##y,z,c), I[188] = (T)(img)(_n7##x,_p7##y,z,c), I[189] = (T)(img)(_n8##x,_p7##y,z,c), I[190] = (T)(img)(_n9##x,_p7##y,z,c), I[191] = (T)(img)(_n10##x,_p7##y,z,c), I[192] = (T)(img)(_n11##x,_p7##y,z,c), I[193] = (T)(img)(_n12##x,_p7##y,z,c), I[194] = (T)(img)(_n13##x,_p7##y,z,c), I[195] = (T)(img)(_n14##x,_p7##y,z,c), \ - I[196] = (T)(img)(_p13##x,_p6##y,z,c), I[197] = (T)(img)(_p12##x,_p6##y,z,c), I[198] = (T)(img)(_p11##x,_p6##y,z,c), I[199] = (T)(img)(_p10##x,_p6##y,z,c), I[200] = (T)(img)(_p9##x,_p6##y,z,c), I[201] = (T)(img)(_p8##x,_p6##y,z,c), I[202] = (T)(img)(_p7##x,_p6##y,z,c), I[203] = (T)(img)(_p6##x,_p6##y,z,c), I[204] = (T)(img)(_p5##x,_p6##y,z,c), I[205] = (T)(img)(_p4##x,_p6##y,z,c), I[206] = (T)(img)(_p3##x,_p6##y,z,c), I[207] = (T)(img)(_p2##x,_p6##y,z,c), I[208] = (T)(img)(_p1##x,_p6##y,z,c), I[209] = (T)(img)(x,_p6##y,z,c), I[210] = (T)(img)(_n1##x,_p6##y,z,c), I[211] = (T)(img)(_n2##x,_p6##y,z,c), I[212] = (T)(img)(_n3##x,_p6##y,z,c), I[213] = (T)(img)(_n4##x,_p6##y,z,c), I[214] = (T)(img)(_n5##x,_p6##y,z,c), I[215] = (T)(img)(_n6##x,_p6##y,z,c), I[216] = (T)(img)(_n7##x,_p6##y,z,c), I[217] = (T)(img)(_n8##x,_p6##y,z,c), I[218] = (T)(img)(_n9##x,_p6##y,z,c), I[219] = (T)(img)(_n10##x,_p6##y,z,c), I[220] = (T)(img)(_n11##x,_p6##y,z,c), I[221] = (T)(img)(_n12##x,_p6##y,z,c), I[222] = (T)(img)(_n13##x,_p6##y,z,c), I[223] = (T)(img)(_n14##x,_p6##y,z,c), \ - I[224] = (T)(img)(_p13##x,_p5##y,z,c), I[225] = (T)(img)(_p12##x,_p5##y,z,c), I[226] = (T)(img)(_p11##x,_p5##y,z,c), I[227] = (T)(img)(_p10##x,_p5##y,z,c), I[228] = (T)(img)(_p9##x,_p5##y,z,c), I[229] = (T)(img)(_p8##x,_p5##y,z,c), I[230] = (T)(img)(_p7##x,_p5##y,z,c), I[231] = (T)(img)(_p6##x,_p5##y,z,c), I[232] = (T)(img)(_p5##x,_p5##y,z,c), I[233] = (T)(img)(_p4##x,_p5##y,z,c), I[234] = (T)(img)(_p3##x,_p5##y,z,c), I[235] = (T)(img)(_p2##x,_p5##y,z,c), I[236] = (T)(img)(_p1##x,_p5##y,z,c), I[237] = (T)(img)(x,_p5##y,z,c), I[238] = (T)(img)(_n1##x,_p5##y,z,c), I[239] = (T)(img)(_n2##x,_p5##y,z,c), I[240] = (T)(img)(_n3##x,_p5##y,z,c), I[241] = (T)(img)(_n4##x,_p5##y,z,c), I[242] = (T)(img)(_n5##x,_p5##y,z,c), I[243] = (T)(img)(_n6##x,_p5##y,z,c), I[244] = (T)(img)(_n7##x,_p5##y,z,c), I[245] = (T)(img)(_n8##x,_p5##y,z,c), I[246] = (T)(img)(_n9##x,_p5##y,z,c), I[247] = (T)(img)(_n10##x,_p5##y,z,c), I[248] = (T)(img)(_n11##x,_p5##y,z,c), I[249] = (T)(img)(_n12##x,_p5##y,z,c), I[250] = (T)(img)(_n13##x,_p5##y,z,c), I[251] = (T)(img)(_n14##x,_p5##y,z,c), \ - I[252] = (T)(img)(_p13##x,_p4##y,z,c), I[253] = (T)(img)(_p12##x,_p4##y,z,c), I[254] = (T)(img)(_p11##x,_p4##y,z,c), I[255] = (T)(img)(_p10##x,_p4##y,z,c), I[256] = (T)(img)(_p9##x,_p4##y,z,c), I[257] = (T)(img)(_p8##x,_p4##y,z,c), I[258] = (T)(img)(_p7##x,_p4##y,z,c), I[259] = (T)(img)(_p6##x,_p4##y,z,c), I[260] = (T)(img)(_p5##x,_p4##y,z,c), I[261] = (T)(img)(_p4##x,_p4##y,z,c), I[262] = (T)(img)(_p3##x,_p4##y,z,c), I[263] = (T)(img)(_p2##x,_p4##y,z,c), I[264] = (T)(img)(_p1##x,_p4##y,z,c), I[265] = (T)(img)(x,_p4##y,z,c), I[266] = (T)(img)(_n1##x,_p4##y,z,c), I[267] = (T)(img)(_n2##x,_p4##y,z,c), I[268] = (T)(img)(_n3##x,_p4##y,z,c), I[269] = (T)(img)(_n4##x,_p4##y,z,c), I[270] = (T)(img)(_n5##x,_p4##y,z,c), I[271] = (T)(img)(_n6##x,_p4##y,z,c), I[272] = (T)(img)(_n7##x,_p4##y,z,c), I[273] = (T)(img)(_n8##x,_p4##y,z,c), I[274] = (T)(img)(_n9##x,_p4##y,z,c), I[275] = (T)(img)(_n10##x,_p4##y,z,c), I[276] = (T)(img)(_n11##x,_p4##y,z,c), I[277] = (T)(img)(_n12##x,_p4##y,z,c), I[278] = (T)(img)(_n13##x,_p4##y,z,c), I[279] = (T)(img)(_n14##x,_p4##y,z,c), \ - I[280] = (T)(img)(_p13##x,_p3##y,z,c), I[281] = (T)(img)(_p12##x,_p3##y,z,c), I[282] = (T)(img)(_p11##x,_p3##y,z,c), I[283] = (T)(img)(_p10##x,_p3##y,z,c), I[284] = (T)(img)(_p9##x,_p3##y,z,c), I[285] = (T)(img)(_p8##x,_p3##y,z,c), I[286] = (T)(img)(_p7##x,_p3##y,z,c), I[287] = (T)(img)(_p6##x,_p3##y,z,c), I[288] = (T)(img)(_p5##x,_p3##y,z,c), I[289] = (T)(img)(_p4##x,_p3##y,z,c), I[290] = (T)(img)(_p3##x,_p3##y,z,c), I[291] = (T)(img)(_p2##x,_p3##y,z,c), I[292] = (T)(img)(_p1##x,_p3##y,z,c), I[293] = (T)(img)(x,_p3##y,z,c), I[294] = (T)(img)(_n1##x,_p3##y,z,c), I[295] = (T)(img)(_n2##x,_p3##y,z,c), I[296] = (T)(img)(_n3##x,_p3##y,z,c), I[297] = (T)(img)(_n4##x,_p3##y,z,c), I[298] = (T)(img)(_n5##x,_p3##y,z,c), I[299] = (T)(img)(_n6##x,_p3##y,z,c), I[300] = (T)(img)(_n7##x,_p3##y,z,c), I[301] = (T)(img)(_n8##x,_p3##y,z,c), I[302] = (T)(img)(_n9##x,_p3##y,z,c), I[303] = (T)(img)(_n10##x,_p3##y,z,c), I[304] = (T)(img)(_n11##x,_p3##y,z,c), I[305] = (T)(img)(_n12##x,_p3##y,z,c), I[306] = (T)(img)(_n13##x,_p3##y,z,c), I[307] = (T)(img)(_n14##x,_p3##y,z,c), \ - I[308] = (T)(img)(_p13##x,_p2##y,z,c), I[309] = (T)(img)(_p12##x,_p2##y,z,c), I[310] = (T)(img)(_p11##x,_p2##y,z,c), I[311] = (T)(img)(_p10##x,_p2##y,z,c), I[312] = (T)(img)(_p9##x,_p2##y,z,c), I[313] = (T)(img)(_p8##x,_p2##y,z,c), I[314] = (T)(img)(_p7##x,_p2##y,z,c), I[315] = (T)(img)(_p6##x,_p2##y,z,c), I[316] = (T)(img)(_p5##x,_p2##y,z,c), I[317] = (T)(img)(_p4##x,_p2##y,z,c), I[318] = (T)(img)(_p3##x,_p2##y,z,c), I[319] = (T)(img)(_p2##x,_p2##y,z,c), I[320] = (T)(img)(_p1##x,_p2##y,z,c), I[321] = (T)(img)(x,_p2##y,z,c), I[322] = (T)(img)(_n1##x,_p2##y,z,c), I[323] = (T)(img)(_n2##x,_p2##y,z,c), I[324] = (T)(img)(_n3##x,_p2##y,z,c), I[325] = (T)(img)(_n4##x,_p2##y,z,c), I[326] = (T)(img)(_n5##x,_p2##y,z,c), I[327] = (T)(img)(_n6##x,_p2##y,z,c), I[328] = (T)(img)(_n7##x,_p2##y,z,c), I[329] = (T)(img)(_n8##x,_p2##y,z,c), I[330] = (T)(img)(_n9##x,_p2##y,z,c), I[331] = (T)(img)(_n10##x,_p2##y,z,c), I[332] = (T)(img)(_n11##x,_p2##y,z,c), I[333] = (T)(img)(_n12##x,_p2##y,z,c), I[334] = (T)(img)(_n13##x,_p2##y,z,c), I[335] = (T)(img)(_n14##x,_p2##y,z,c), \ - I[336] = (T)(img)(_p13##x,_p1##y,z,c), I[337] = (T)(img)(_p12##x,_p1##y,z,c), I[338] = (T)(img)(_p11##x,_p1##y,z,c), I[339] = (T)(img)(_p10##x,_p1##y,z,c), I[340] = (T)(img)(_p9##x,_p1##y,z,c), I[341] = (T)(img)(_p8##x,_p1##y,z,c), I[342] = (T)(img)(_p7##x,_p1##y,z,c), I[343] = (T)(img)(_p6##x,_p1##y,z,c), I[344] = (T)(img)(_p5##x,_p1##y,z,c), I[345] = (T)(img)(_p4##x,_p1##y,z,c), I[346] = (T)(img)(_p3##x,_p1##y,z,c), I[347] = (T)(img)(_p2##x,_p1##y,z,c), I[348] = (T)(img)(_p1##x,_p1##y,z,c), I[349] = (T)(img)(x,_p1##y,z,c), I[350] = (T)(img)(_n1##x,_p1##y,z,c), I[351] = (T)(img)(_n2##x,_p1##y,z,c), I[352] = (T)(img)(_n3##x,_p1##y,z,c), I[353] = (T)(img)(_n4##x,_p1##y,z,c), I[354] = (T)(img)(_n5##x,_p1##y,z,c), I[355] = (T)(img)(_n6##x,_p1##y,z,c), I[356] = (T)(img)(_n7##x,_p1##y,z,c), I[357] = (T)(img)(_n8##x,_p1##y,z,c), I[358] = (T)(img)(_n9##x,_p1##y,z,c), I[359] = (T)(img)(_n10##x,_p1##y,z,c), I[360] = (T)(img)(_n11##x,_p1##y,z,c), I[361] = (T)(img)(_n12##x,_p1##y,z,c), I[362] = (T)(img)(_n13##x,_p1##y,z,c), I[363] = (T)(img)(_n14##x,_p1##y,z,c), \ - I[364] = (T)(img)(_p13##x,y,z,c), I[365] = (T)(img)(_p12##x,y,z,c), I[366] = (T)(img)(_p11##x,y,z,c), I[367] = (T)(img)(_p10##x,y,z,c), I[368] = (T)(img)(_p9##x,y,z,c), I[369] = (T)(img)(_p8##x,y,z,c), I[370] = (T)(img)(_p7##x,y,z,c), I[371] = (T)(img)(_p6##x,y,z,c), I[372] = (T)(img)(_p5##x,y,z,c), I[373] = (T)(img)(_p4##x,y,z,c), I[374] = (T)(img)(_p3##x,y,z,c), I[375] = (T)(img)(_p2##x,y,z,c), I[376] = (T)(img)(_p1##x,y,z,c), I[377] = (T)(img)(x,y,z,c), I[378] = (T)(img)(_n1##x,y,z,c), I[379] = (T)(img)(_n2##x,y,z,c), I[380] = (T)(img)(_n3##x,y,z,c), I[381] = (T)(img)(_n4##x,y,z,c), I[382] = (T)(img)(_n5##x,y,z,c), I[383] = (T)(img)(_n6##x,y,z,c), I[384] = (T)(img)(_n7##x,y,z,c), I[385] = (T)(img)(_n8##x,y,z,c), I[386] = (T)(img)(_n9##x,y,z,c), I[387] = (T)(img)(_n10##x,y,z,c), I[388] = (T)(img)(_n11##x,y,z,c), I[389] = (T)(img)(_n12##x,y,z,c), I[390] = (T)(img)(_n13##x,y,z,c), I[391] = (T)(img)(_n14##x,y,z,c), \ - I[392] = (T)(img)(_p13##x,_n1##y,z,c), I[393] = (T)(img)(_p12##x,_n1##y,z,c), I[394] = (T)(img)(_p11##x,_n1##y,z,c), I[395] = (T)(img)(_p10##x,_n1##y,z,c), I[396] = (T)(img)(_p9##x,_n1##y,z,c), I[397] = (T)(img)(_p8##x,_n1##y,z,c), I[398] = (T)(img)(_p7##x,_n1##y,z,c), I[399] = (T)(img)(_p6##x,_n1##y,z,c), I[400] = (T)(img)(_p5##x,_n1##y,z,c), I[401] = (T)(img)(_p4##x,_n1##y,z,c), I[402] = (T)(img)(_p3##x,_n1##y,z,c), I[403] = (T)(img)(_p2##x,_n1##y,z,c), I[404] = (T)(img)(_p1##x,_n1##y,z,c), I[405] = (T)(img)(x,_n1##y,z,c), I[406] = (T)(img)(_n1##x,_n1##y,z,c), I[407] = (T)(img)(_n2##x,_n1##y,z,c), I[408] = (T)(img)(_n3##x,_n1##y,z,c), I[409] = (T)(img)(_n4##x,_n1##y,z,c), I[410] = (T)(img)(_n5##x,_n1##y,z,c), I[411] = (T)(img)(_n6##x,_n1##y,z,c), I[412] = (T)(img)(_n7##x,_n1##y,z,c), I[413] = (T)(img)(_n8##x,_n1##y,z,c), I[414] = (T)(img)(_n9##x,_n1##y,z,c), I[415] = (T)(img)(_n10##x,_n1##y,z,c), I[416] = (T)(img)(_n11##x,_n1##y,z,c), I[417] = (T)(img)(_n12##x,_n1##y,z,c), I[418] = (T)(img)(_n13##x,_n1##y,z,c), I[419] = (T)(img)(_n14##x,_n1##y,z,c), \ - I[420] = (T)(img)(_p13##x,_n2##y,z,c), I[421] = (T)(img)(_p12##x,_n2##y,z,c), I[422] = (T)(img)(_p11##x,_n2##y,z,c), I[423] = (T)(img)(_p10##x,_n2##y,z,c), I[424] = (T)(img)(_p9##x,_n2##y,z,c), I[425] = (T)(img)(_p8##x,_n2##y,z,c), I[426] = (T)(img)(_p7##x,_n2##y,z,c), I[427] = (T)(img)(_p6##x,_n2##y,z,c), I[428] = (T)(img)(_p5##x,_n2##y,z,c), I[429] = (T)(img)(_p4##x,_n2##y,z,c), I[430] = (T)(img)(_p3##x,_n2##y,z,c), I[431] = (T)(img)(_p2##x,_n2##y,z,c), I[432] = (T)(img)(_p1##x,_n2##y,z,c), I[433] = (T)(img)(x,_n2##y,z,c), I[434] = (T)(img)(_n1##x,_n2##y,z,c), I[435] = (T)(img)(_n2##x,_n2##y,z,c), I[436] = (T)(img)(_n3##x,_n2##y,z,c), I[437] = (T)(img)(_n4##x,_n2##y,z,c), I[438] = (T)(img)(_n5##x,_n2##y,z,c), I[439] = (T)(img)(_n6##x,_n2##y,z,c), I[440] = (T)(img)(_n7##x,_n2##y,z,c), I[441] = (T)(img)(_n8##x,_n2##y,z,c), I[442] = (T)(img)(_n9##x,_n2##y,z,c), I[443] = (T)(img)(_n10##x,_n2##y,z,c), I[444] = (T)(img)(_n11##x,_n2##y,z,c), I[445] = (T)(img)(_n12##x,_n2##y,z,c), I[446] = (T)(img)(_n13##x,_n2##y,z,c), I[447] = (T)(img)(_n14##x,_n2##y,z,c), \ - I[448] = (T)(img)(_p13##x,_n3##y,z,c), I[449] = (T)(img)(_p12##x,_n3##y,z,c), I[450] = (T)(img)(_p11##x,_n3##y,z,c), I[451] = (T)(img)(_p10##x,_n3##y,z,c), I[452] = (T)(img)(_p9##x,_n3##y,z,c), I[453] = (T)(img)(_p8##x,_n3##y,z,c), I[454] = (T)(img)(_p7##x,_n3##y,z,c), I[455] = (T)(img)(_p6##x,_n3##y,z,c), I[456] = (T)(img)(_p5##x,_n3##y,z,c), I[457] = (T)(img)(_p4##x,_n3##y,z,c), I[458] = (T)(img)(_p3##x,_n3##y,z,c), I[459] = (T)(img)(_p2##x,_n3##y,z,c), I[460] = (T)(img)(_p1##x,_n3##y,z,c), I[461] = (T)(img)(x,_n3##y,z,c), I[462] = (T)(img)(_n1##x,_n3##y,z,c), I[463] = (T)(img)(_n2##x,_n3##y,z,c), I[464] = (T)(img)(_n3##x,_n3##y,z,c), I[465] = (T)(img)(_n4##x,_n3##y,z,c), I[466] = (T)(img)(_n5##x,_n3##y,z,c), I[467] = (T)(img)(_n6##x,_n3##y,z,c), I[468] = (T)(img)(_n7##x,_n3##y,z,c), I[469] = (T)(img)(_n8##x,_n3##y,z,c), I[470] = (T)(img)(_n9##x,_n3##y,z,c), I[471] = (T)(img)(_n10##x,_n3##y,z,c), I[472] = (T)(img)(_n11##x,_n3##y,z,c), I[473] = (T)(img)(_n12##x,_n3##y,z,c), I[474] = (T)(img)(_n13##x,_n3##y,z,c), I[475] = (T)(img)(_n14##x,_n3##y,z,c), \ - I[476] = (T)(img)(_p13##x,_n4##y,z,c), I[477] = (T)(img)(_p12##x,_n4##y,z,c), I[478] = (T)(img)(_p11##x,_n4##y,z,c), I[479] = (T)(img)(_p10##x,_n4##y,z,c), I[480] = (T)(img)(_p9##x,_n4##y,z,c), I[481] = (T)(img)(_p8##x,_n4##y,z,c), I[482] = (T)(img)(_p7##x,_n4##y,z,c), I[483] = (T)(img)(_p6##x,_n4##y,z,c), I[484] = (T)(img)(_p5##x,_n4##y,z,c), I[485] = (T)(img)(_p4##x,_n4##y,z,c), I[486] = (T)(img)(_p3##x,_n4##y,z,c), I[487] = (T)(img)(_p2##x,_n4##y,z,c), I[488] = (T)(img)(_p1##x,_n4##y,z,c), I[489] = (T)(img)(x,_n4##y,z,c), I[490] = (T)(img)(_n1##x,_n4##y,z,c), I[491] = (T)(img)(_n2##x,_n4##y,z,c), I[492] = (T)(img)(_n3##x,_n4##y,z,c), I[493] = (T)(img)(_n4##x,_n4##y,z,c), I[494] = (T)(img)(_n5##x,_n4##y,z,c), I[495] = (T)(img)(_n6##x,_n4##y,z,c), I[496] = (T)(img)(_n7##x,_n4##y,z,c), I[497] = (T)(img)(_n8##x,_n4##y,z,c), I[498] = (T)(img)(_n9##x,_n4##y,z,c), I[499] = (T)(img)(_n10##x,_n4##y,z,c), I[500] = (T)(img)(_n11##x,_n4##y,z,c), I[501] = (T)(img)(_n12##x,_n4##y,z,c), I[502] = (T)(img)(_n13##x,_n4##y,z,c), I[503] = (T)(img)(_n14##x,_n4##y,z,c), \ - I[504] = (T)(img)(_p13##x,_n5##y,z,c), I[505] = (T)(img)(_p12##x,_n5##y,z,c), I[506] = (T)(img)(_p11##x,_n5##y,z,c), I[507] = (T)(img)(_p10##x,_n5##y,z,c), I[508] = (T)(img)(_p9##x,_n5##y,z,c), I[509] = (T)(img)(_p8##x,_n5##y,z,c), I[510] = (T)(img)(_p7##x,_n5##y,z,c), I[511] = (T)(img)(_p6##x,_n5##y,z,c), I[512] = (T)(img)(_p5##x,_n5##y,z,c), I[513] = (T)(img)(_p4##x,_n5##y,z,c), I[514] = (T)(img)(_p3##x,_n5##y,z,c), I[515] = (T)(img)(_p2##x,_n5##y,z,c), I[516] = (T)(img)(_p1##x,_n5##y,z,c), I[517] = (T)(img)(x,_n5##y,z,c), I[518] = (T)(img)(_n1##x,_n5##y,z,c), I[519] = (T)(img)(_n2##x,_n5##y,z,c), I[520] = (T)(img)(_n3##x,_n5##y,z,c), I[521] = (T)(img)(_n4##x,_n5##y,z,c), I[522] = (T)(img)(_n5##x,_n5##y,z,c), I[523] = (T)(img)(_n6##x,_n5##y,z,c), I[524] = (T)(img)(_n7##x,_n5##y,z,c), I[525] = (T)(img)(_n8##x,_n5##y,z,c), I[526] = (T)(img)(_n9##x,_n5##y,z,c), I[527] = (T)(img)(_n10##x,_n5##y,z,c), I[528] = (T)(img)(_n11##x,_n5##y,z,c), I[529] = (T)(img)(_n12##x,_n5##y,z,c), I[530] = (T)(img)(_n13##x,_n5##y,z,c), I[531] = (T)(img)(_n14##x,_n5##y,z,c), \ - I[532] = (T)(img)(_p13##x,_n6##y,z,c), I[533] = (T)(img)(_p12##x,_n6##y,z,c), I[534] = (T)(img)(_p11##x,_n6##y,z,c), I[535] = (T)(img)(_p10##x,_n6##y,z,c), I[536] = (T)(img)(_p9##x,_n6##y,z,c), I[537] = (T)(img)(_p8##x,_n6##y,z,c), I[538] = (T)(img)(_p7##x,_n6##y,z,c), I[539] = (T)(img)(_p6##x,_n6##y,z,c), I[540] = (T)(img)(_p5##x,_n6##y,z,c), I[541] = (T)(img)(_p4##x,_n6##y,z,c), I[542] = (T)(img)(_p3##x,_n6##y,z,c), I[543] = (T)(img)(_p2##x,_n6##y,z,c), I[544] = (T)(img)(_p1##x,_n6##y,z,c), I[545] = (T)(img)(x,_n6##y,z,c), I[546] = (T)(img)(_n1##x,_n6##y,z,c), I[547] = (T)(img)(_n2##x,_n6##y,z,c), I[548] = (T)(img)(_n3##x,_n6##y,z,c), I[549] = (T)(img)(_n4##x,_n6##y,z,c), I[550] = (T)(img)(_n5##x,_n6##y,z,c), I[551] = (T)(img)(_n6##x,_n6##y,z,c), I[552] = (T)(img)(_n7##x,_n6##y,z,c), I[553] = (T)(img)(_n8##x,_n6##y,z,c), I[554] = (T)(img)(_n9##x,_n6##y,z,c), I[555] = (T)(img)(_n10##x,_n6##y,z,c), I[556] = (T)(img)(_n11##x,_n6##y,z,c), I[557] = (T)(img)(_n12##x,_n6##y,z,c), I[558] = (T)(img)(_n13##x,_n6##y,z,c), I[559] = (T)(img)(_n14##x,_n6##y,z,c), \ - I[560] = (T)(img)(_p13##x,_n7##y,z,c), I[561] = (T)(img)(_p12##x,_n7##y,z,c), I[562] = (T)(img)(_p11##x,_n7##y,z,c), I[563] = (T)(img)(_p10##x,_n7##y,z,c), I[564] = (T)(img)(_p9##x,_n7##y,z,c), I[565] = (T)(img)(_p8##x,_n7##y,z,c), I[566] = (T)(img)(_p7##x,_n7##y,z,c), I[567] = (T)(img)(_p6##x,_n7##y,z,c), I[568] = (T)(img)(_p5##x,_n7##y,z,c), I[569] = (T)(img)(_p4##x,_n7##y,z,c), I[570] = (T)(img)(_p3##x,_n7##y,z,c), I[571] = (T)(img)(_p2##x,_n7##y,z,c), I[572] = (T)(img)(_p1##x,_n7##y,z,c), I[573] = (T)(img)(x,_n7##y,z,c), I[574] = (T)(img)(_n1##x,_n7##y,z,c), I[575] = (T)(img)(_n2##x,_n7##y,z,c), I[576] = (T)(img)(_n3##x,_n7##y,z,c), I[577] = (T)(img)(_n4##x,_n7##y,z,c), I[578] = (T)(img)(_n5##x,_n7##y,z,c), I[579] = (T)(img)(_n6##x,_n7##y,z,c), I[580] = (T)(img)(_n7##x,_n7##y,z,c), I[581] = (T)(img)(_n8##x,_n7##y,z,c), I[582] = (T)(img)(_n9##x,_n7##y,z,c), I[583] = (T)(img)(_n10##x,_n7##y,z,c), I[584] = (T)(img)(_n11##x,_n7##y,z,c), I[585] = (T)(img)(_n12##x,_n7##y,z,c), I[586] = (T)(img)(_n13##x,_n7##y,z,c), I[587] = (T)(img)(_n14##x,_n7##y,z,c), \ - I[588] = (T)(img)(_p13##x,_n8##y,z,c), I[589] = (T)(img)(_p12##x,_n8##y,z,c), I[590] = (T)(img)(_p11##x,_n8##y,z,c), I[591] = (T)(img)(_p10##x,_n8##y,z,c), I[592] = (T)(img)(_p9##x,_n8##y,z,c), I[593] = (T)(img)(_p8##x,_n8##y,z,c), I[594] = (T)(img)(_p7##x,_n8##y,z,c), I[595] = (T)(img)(_p6##x,_n8##y,z,c), I[596] = (T)(img)(_p5##x,_n8##y,z,c), I[597] = (T)(img)(_p4##x,_n8##y,z,c), I[598] = (T)(img)(_p3##x,_n8##y,z,c), I[599] = (T)(img)(_p2##x,_n8##y,z,c), I[600] = (T)(img)(_p1##x,_n8##y,z,c), I[601] = (T)(img)(x,_n8##y,z,c), I[602] = (T)(img)(_n1##x,_n8##y,z,c), I[603] = (T)(img)(_n2##x,_n8##y,z,c), I[604] = (T)(img)(_n3##x,_n8##y,z,c), I[605] = (T)(img)(_n4##x,_n8##y,z,c), I[606] = (T)(img)(_n5##x,_n8##y,z,c), I[607] = (T)(img)(_n6##x,_n8##y,z,c), I[608] = (T)(img)(_n7##x,_n8##y,z,c), I[609] = (T)(img)(_n8##x,_n8##y,z,c), I[610] = (T)(img)(_n9##x,_n8##y,z,c), I[611] = (T)(img)(_n10##x,_n8##y,z,c), I[612] = (T)(img)(_n11##x,_n8##y,z,c), I[613] = (T)(img)(_n12##x,_n8##y,z,c), I[614] = (T)(img)(_n13##x,_n8##y,z,c), I[615] = (T)(img)(_n14##x,_n8##y,z,c), \ - I[616] = (T)(img)(_p13##x,_n9##y,z,c), I[617] = (T)(img)(_p12##x,_n9##y,z,c), I[618] = (T)(img)(_p11##x,_n9##y,z,c), I[619] = (T)(img)(_p10##x,_n9##y,z,c), I[620] = (T)(img)(_p9##x,_n9##y,z,c), I[621] = (T)(img)(_p8##x,_n9##y,z,c), I[622] = (T)(img)(_p7##x,_n9##y,z,c), I[623] = (T)(img)(_p6##x,_n9##y,z,c), I[624] = (T)(img)(_p5##x,_n9##y,z,c), I[625] = (T)(img)(_p4##x,_n9##y,z,c), I[626] = (T)(img)(_p3##x,_n9##y,z,c), I[627] = (T)(img)(_p2##x,_n9##y,z,c), I[628] = (T)(img)(_p1##x,_n9##y,z,c), I[629] = (T)(img)(x,_n9##y,z,c), I[630] = (T)(img)(_n1##x,_n9##y,z,c), I[631] = (T)(img)(_n2##x,_n9##y,z,c), I[632] = (T)(img)(_n3##x,_n9##y,z,c), I[633] = (T)(img)(_n4##x,_n9##y,z,c), I[634] = (T)(img)(_n5##x,_n9##y,z,c), I[635] = (T)(img)(_n6##x,_n9##y,z,c), I[636] = (T)(img)(_n7##x,_n9##y,z,c), I[637] = (T)(img)(_n8##x,_n9##y,z,c), I[638] = (T)(img)(_n9##x,_n9##y,z,c), I[639] = (T)(img)(_n10##x,_n9##y,z,c), I[640] = (T)(img)(_n11##x,_n9##y,z,c), I[641] = (T)(img)(_n12##x,_n9##y,z,c), I[642] = (T)(img)(_n13##x,_n9##y,z,c), I[643] = (T)(img)(_n14##x,_n9##y,z,c), \ - I[644] = (T)(img)(_p13##x,_n10##y,z,c), I[645] = (T)(img)(_p12##x,_n10##y,z,c), I[646] = (T)(img)(_p11##x,_n10##y,z,c), I[647] = (T)(img)(_p10##x,_n10##y,z,c), I[648] = (T)(img)(_p9##x,_n10##y,z,c), I[649] = (T)(img)(_p8##x,_n10##y,z,c), I[650] = (T)(img)(_p7##x,_n10##y,z,c), I[651] = (T)(img)(_p6##x,_n10##y,z,c), I[652] = (T)(img)(_p5##x,_n10##y,z,c), I[653] = (T)(img)(_p4##x,_n10##y,z,c), I[654] = (T)(img)(_p3##x,_n10##y,z,c), I[655] = (T)(img)(_p2##x,_n10##y,z,c), I[656] = (T)(img)(_p1##x,_n10##y,z,c), I[657] = (T)(img)(x,_n10##y,z,c), I[658] = (T)(img)(_n1##x,_n10##y,z,c), I[659] = (T)(img)(_n2##x,_n10##y,z,c), I[660] = (T)(img)(_n3##x,_n10##y,z,c), I[661] = (T)(img)(_n4##x,_n10##y,z,c), I[662] = (T)(img)(_n5##x,_n10##y,z,c), I[663] = (T)(img)(_n6##x,_n10##y,z,c), I[664] = (T)(img)(_n7##x,_n10##y,z,c), I[665] = (T)(img)(_n8##x,_n10##y,z,c), I[666] = (T)(img)(_n9##x,_n10##y,z,c), I[667] = (T)(img)(_n10##x,_n10##y,z,c), I[668] = (T)(img)(_n11##x,_n10##y,z,c), I[669] = (T)(img)(_n12##x,_n10##y,z,c), I[670] = (T)(img)(_n13##x,_n10##y,z,c), I[671] = (T)(img)(_n14##x,_n10##y,z,c), \ - I[672] = (T)(img)(_p13##x,_n11##y,z,c), I[673] = (T)(img)(_p12##x,_n11##y,z,c), I[674] = (T)(img)(_p11##x,_n11##y,z,c), I[675] = (T)(img)(_p10##x,_n11##y,z,c), I[676] = (T)(img)(_p9##x,_n11##y,z,c), I[677] = (T)(img)(_p8##x,_n11##y,z,c), I[678] = (T)(img)(_p7##x,_n11##y,z,c), I[679] = (T)(img)(_p6##x,_n11##y,z,c), I[680] = (T)(img)(_p5##x,_n11##y,z,c), I[681] = (T)(img)(_p4##x,_n11##y,z,c), I[682] = (T)(img)(_p3##x,_n11##y,z,c), I[683] = (T)(img)(_p2##x,_n11##y,z,c), I[684] = (T)(img)(_p1##x,_n11##y,z,c), I[685] = (T)(img)(x,_n11##y,z,c), I[686] = (T)(img)(_n1##x,_n11##y,z,c), I[687] = (T)(img)(_n2##x,_n11##y,z,c), I[688] = (T)(img)(_n3##x,_n11##y,z,c), I[689] = (T)(img)(_n4##x,_n11##y,z,c), I[690] = (T)(img)(_n5##x,_n11##y,z,c), I[691] = (T)(img)(_n6##x,_n11##y,z,c), I[692] = (T)(img)(_n7##x,_n11##y,z,c), I[693] = (T)(img)(_n8##x,_n11##y,z,c), I[694] = (T)(img)(_n9##x,_n11##y,z,c), I[695] = (T)(img)(_n10##x,_n11##y,z,c), I[696] = (T)(img)(_n11##x,_n11##y,z,c), I[697] = (T)(img)(_n12##x,_n11##y,z,c), I[698] = (T)(img)(_n13##x,_n11##y,z,c), I[699] = (T)(img)(_n14##x,_n11##y,z,c), \ - I[700] = (T)(img)(_p13##x,_n12##y,z,c), I[701] = (T)(img)(_p12##x,_n12##y,z,c), I[702] = (T)(img)(_p11##x,_n12##y,z,c), I[703] = (T)(img)(_p10##x,_n12##y,z,c), I[704] = (T)(img)(_p9##x,_n12##y,z,c), I[705] = (T)(img)(_p8##x,_n12##y,z,c), I[706] = (T)(img)(_p7##x,_n12##y,z,c), I[707] = (T)(img)(_p6##x,_n12##y,z,c), I[708] = (T)(img)(_p5##x,_n12##y,z,c), I[709] = (T)(img)(_p4##x,_n12##y,z,c), I[710] = (T)(img)(_p3##x,_n12##y,z,c), I[711] = (T)(img)(_p2##x,_n12##y,z,c), I[712] = (T)(img)(_p1##x,_n12##y,z,c), I[713] = (T)(img)(x,_n12##y,z,c), I[714] = (T)(img)(_n1##x,_n12##y,z,c), I[715] = (T)(img)(_n2##x,_n12##y,z,c), I[716] = (T)(img)(_n3##x,_n12##y,z,c), I[717] = (T)(img)(_n4##x,_n12##y,z,c), I[718] = (T)(img)(_n5##x,_n12##y,z,c), I[719] = (T)(img)(_n6##x,_n12##y,z,c), I[720] = (T)(img)(_n7##x,_n12##y,z,c), I[721] = (T)(img)(_n8##x,_n12##y,z,c), I[722] = (T)(img)(_n9##x,_n12##y,z,c), I[723] = (T)(img)(_n10##x,_n12##y,z,c), I[724] = (T)(img)(_n11##x,_n12##y,z,c), I[725] = (T)(img)(_n12##x,_n12##y,z,c), I[726] = (T)(img)(_n13##x,_n12##y,z,c), I[727] = (T)(img)(_n14##x,_n12##y,z,c), \ - I[728] = (T)(img)(_p13##x,_n13##y,z,c), I[729] = (T)(img)(_p12##x,_n13##y,z,c), I[730] = (T)(img)(_p11##x,_n13##y,z,c), I[731] = (T)(img)(_p10##x,_n13##y,z,c), I[732] = (T)(img)(_p9##x,_n13##y,z,c), I[733] = (T)(img)(_p8##x,_n13##y,z,c), I[734] = (T)(img)(_p7##x,_n13##y,z,c), I[735] = (T)(img)(_p6##x,_n13##y,z,c), I[736] = (T)(img)(_p5##x,_n13##y,z,c), I[737] = (T)(img)(_p4##x,_n13##y,z,c), I[738] = (T)(img)(_p3##x,_n13##y,z,c), I[739] = (T)(img)(_p2##x,_n13##y,z,c), I[740] = (T)(img)(_p1##x,_n13##y,z,c), I[741] = (T)(img)(x,_n13##y,z,c), I[742] = (T)(img)(_n1##x,_n13##y,z,c), I[743] = (T)(img)(_n2##x,_n13##y,z,c), I[744] = (T)(img)(_n3##x,_n13##y,z,c), I[745] = (T)(img)(_n4##x,_n13##y,z,c), I[746] = (T)(img)(_n5##x,_n13##y,z,c), I[747] = (T)(img)(_n6##x,_n13##y,z,c), I[748] = (T)(img)(_n7##x,_n13##y,z,c), I[749] = (T)(img)(_n8##x,_n13##y,z,c), I[750] = (T)(img)(_n9##x,_n13##y,z,c), I[751] = (T)(img)(_n10##x,_n13##y,z,c), I[752] = (T)(img)(_n11##x,_n13##y,z,c), I[753] = (T)(img)(_n12##x,_n13##y,z,c), I[754] = (T)(img)(_n13##x,_n13##y,z,c), I[755] = (T)(img)(_n14##x,_n13##y,z,c), \ - I[756] = (T)(img)(_p13##x,_n14##y,z,c), I[757] = (T)(img)(_p12##x,_n14##y,z,c), I[758] = (T)(img)(_p11##x,_n14##y,z,c), I[759] = (T)(img)(_p10##x,_n14##y,z,c), I[760] = (T)(img)(_p9##x,_n14##y,z,c), I[761] = (T)(img)(_p8##x,_n14##y,z,c), I[762] = (T)(img)(_p7##x,_n14##y,z,c), I[763] = (T)(img)(_p6##x,_n14##y,z,c), I[764] = (T)(img)(_p5##x,_n14##y,z,c), I[765] = (T)(img)(_p4##x,_n14##y,z,c), I[766] = (T)(img)(_p3##x,_n14##y,z,c), I[767] = (T)(img)(_p2##x,_n14##y,z,c), I[768] = (T)(img)(_p1##x,_n14##y,z,c), I[769] = (T)(img)(x,_n14##y,z,c), I[770] = (T)(img)(_n1##x,_n14##y,z,c), I[771] = (T)(img)(_n2##x,_n14##y,z,c), I[772] = (T)(img)(_n3##x,_n14##y,z,c), I[773] = (T)(img)(_n4##x,_n14##y,z,c), I[774] = (T)(img)(_n5##x,_n14##y,z,c), I[775] = (T)(img)(_n6##x,_n14##y,z,c), I[776] = (T)(img)(_n7##x,_n14##y,z,c), I[777] = (T)(img)(_n8##x,_n14##y,z,c), I[778] = (T)(img)(_n9##x,_n14##y,z,c), I[779] = (T)(img)(_n10##x,_n14##y,z,c), I[780] = (T)(img)(_n11##x,_n14##y,z,c), I[781] = (T)(img)(_n12##x,_n14##y,z,c), I[782] = (T)(img)(_n13##x,_n14##y,z,c), I[783] = (T)(img)(_n14##x,_n14##y,z,c); - -// Define 29x29 loop macros -//------------------------- -#define cimg_for29(bound,i) for (int i = 0, \ - _p14##i = 0, _p13##i = 0, _p12##i = 0, _p11##i = 0, _p10##i = 0, _p9##i = 0, _p8##i = 0, _p7##i = 0, _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6, \ - _n7##i = 7>=(int)(bound)?(int)(bound) - 1:7, \ - _n8##i = 8>=(int)(bound)?(int)(bound) - 1:8, \ - _n9##i = 9>=(int)(bound)?(int)(bound) - 1:9, \ - _n10##i = 10>=(int)(bound)?(int)(bound) - 1:10, \ - _n11##i = 11>=(int)(bound)?(int)(bound) - 1:11, \ - _n12##i = 12>=(int)(bound)?(int)(bound) - 1:12, \ - _n13##i = 13>=(int)(bound)?(int)(bound) - 1:13, \ - _n14##i = 14>=(int)(bound)?(int)(bound) - 1:14; \ - _n14##i<(int)(bound) || _n13##i==--_n14##i || _n12##i==--_n13##i || _n11##i==--_n12##i || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n14##i = _n13##i = _n12##i = _n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p14##i = _p13##i, _p13##i = _p12##i, _p12##i = _p11##i, _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i, ++_n12##i, ++_n13##i, ++_n14##i) - -#define cimg_for29X(img,x) cimg_for29((img)._width,x) -#define cimg_for29Y(img,y) cimg_for29((img)._height,y) -#define cimg_for29Z(img,z) cimg_for29((img)._depth,z) -#define cimg_for29C(img,c) cimg_for29((img)._spectrum,c) -#define cimg_for29XY(img,x,y) cimg_for29Y(img,y) cimg_for29X(img,x) -#define cimg_for29XZ(img,x,z) cimg_for29Z(img,z) cimg_for29X(img,x) -#define cimg_for29XC(img,x,c) cimg_for29C(img,c) cimg_for29X(img,x) -#define cimg_for29YZ(img,y,z) cimg_for29Z(img,z) cimg_for29Y(img,y) -#define cimg_for29YC(img,y,c) cimg_for29C(img,c) cimg_for29Y(img,y) -#define cimg_for29ZC(img,z,c) cimg_for29C(img,c) cimg_for29Z(img,z) -#define cimg_for29XYZ(img,x,y,z) cimg_for29Z(img,z) cimg_for29XY(img,x,y) -#define cimg_for29XZC(img,x,z,c) cimg_for29C(img,c) cimg_for29XZ(img,x,z) -#define cimg_for29YZC(img,y,z,c) cimg_for29C(img,c) cimg_for29YZ(img,y,z) -#define cimg_for29XYZC(img,x,y,z,c) cimg_for29C(img,c) cimg_for29XYZ(img,x,y,z) - -#define cimg_for_in29(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p14##i = i - 14<0?0:i - 14, \ - _p13##i = i - 13<0?0:i - 13, \ - _p12##i = i - 12<0?0:i - 12, \ - _p11##i = i - 11<0?0:i - 11, \ - _p10##i = i - 10<0?0:i - 10, \ - _p9##i = i - 9<0?0:i - 9, \ - _p8##i = i - 8<0?0:i - 8, \ - _p7##i = i - 7<0?0:i - 7, \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6, \ - _n7##i = i + 7>=(int)(bound)?(int)(bound) - 1:i + 7, \ - _n8##i = i + 8>=(int)(bound)?(int)(bound) - 1:i + 8, \ - _n9##i = i + 9>=(int)(bound)?(int)(bound) - 1:i + 9, \ - _n10##i = i + 10>=(int)(bound)?(int)(bound) - 1:i + 10, \ - _n11##i = i + 11>=(int)(bound)?(int)(bound) - 1:i + 11, \ - _n12##i = i + 12>=(int)(bound)?(int)(bound) - 1:i + 12, \ - _n13##i = i + 13>=(int)(bound)?(int)(bound) - 1:i + 13, \ - _n14##i = i + 14>=(int)(bound)?(int)(bound) - 1:i + 14; \ - i<=(int)(i1) && (_n14##i<(int)(bound) || _n13##i==--_n14##i || _n12##i==--_n13##i || _n11##i==--_n12##i || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n14##i = _n13##i = _n12##i = _n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p14##i = _p13##i, _p13##i = _p12##i, _p12##i = _p11##i, _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i, ++_n12##i, ++_n13##i, ++_n14##i) - -#define cimg_for_in29X(img,x0,x1,x) cimg_for_in29((img)._width,x0,x1,x) -#define cimg_for_in29Y(img,y0,y1,y) cimg_for_in29((img)._height,y0,y1,y) -#define cimg_for_in29Z(img,z0,z1,z) cimg_for_in29((img)._depth,z0,z1,z) -#define cimg_for_in29C(img,c0,c1,c) cimg_for_in29((img)._spectrum,c0,c1,c) -#define cimg_for_in29XY(img,x0,y0,x1,y1,x,y) cimg_for_in29Y(img,y0,y1,y) cimg_for_in29X(img,x0,x1,x) -#define cimg_for_in29XZ(img,x0,z0,x1,z1,x,z) cimg_for_in29Z(img,z0,z1,z) cimg_for_in29X(img,x0,x1,x) -#define cimg_for_in29XC(img,x0,c0,x1,c1,x,c) cimg_for_in29C(img,c0,c1,c) cimg_for_in29X(img,x0,x1,x) -#define cimg_for_in29YZ(img,y0,z0,y1,z1,y,z) cimg_for_in29Z(img,z0,z1,z) cimg_for_in29Y(img,y0,y1,y) -#define cimg_for_in29YC(img,y0,c0,y1,c1,y,c) cimg_for_in29C(img,c0,c1,c) cimg_for_in29Y(img,y0,y1,y) -#define cimg_for_in29ZC(img,z0,c0,z1,c1,z,c) cimg_for_in29C(img,c0,c1,c) cimg_for_in29Z(img,z0,z1,z) -#define cimg_for_in29XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in29Z(img,z0,z1,z) cimg_for_in29XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in29XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in29C(img,c0,c1,c) cimg_for_in29XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in29YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in29C(img,c0,c1,c) cimg_for_in29YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in29XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in29C(img,c0,c1,c) cimg_for_in29XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for29x29(img,x,y,z,c,I,T) \ - cimg_for29((img)._height,y) for (int x = 0, \ - _p14##x = 0, _p13##x = 0, _p12##x = 0, _p11##x = 0, _p10##x = 0, _p9##x = 0, _p8##x = 0, _p7##x = 0, _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = 6>=((img)._width)?(img).width() - 1:6, \ - _n7##x = 7>=((img)._width)?(img).width() - 1:7, \ - _n8##x = 8>=((img)._width)?(img).width() - 1:8, \ - _n9##x = 9>=((img)._width)?(img).width() - 1:9, \ - _n10##x = 10>=((img)._width)?(img).width() - 1:10, \ - _n11##x = 11>=((img)._width)?(img).width() - 1:11, \ - _n12##x = 12>=((img)._width)?(img).width() - 1:12, \ - _n13##x = 13>=((img)._width)?(img).width() - 1:13, \ - _n14##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = I[7] = I[8] = I[9] = I[10] = I[11] = I[12] = I[13] = I[14] = (T)(img)(0,_p14##y,z,c)), \ - (I[29] = I[30] = I[31] = I[32] = I[33] = I[34] = I[35] = I[36] = I[37] = I[38] = I[39] = I[40] = I[41] = I[42] = I[43] = (T)(img)(0,_p13##y,z,c)), \ - (I[58] = I[59] = I[60] = I[61] = I[62] = I[63] = I[64] = I[65] = I[66] = I[67] = I[68] = I[69] = I[70] = I[71] = I[72] = (T)(img)(0,_p12##y,z,c)), \ - (I[87] = I[88] = I[89] = I[90] = I[91] = I[92] = I[93] = I[94] = I[95] = I[96] = I[97] = I[98] = I[99] = I[100] = I[101] = (T)(img)(0,_p11##y,z,c)), \ - (I[116] = I[117] = I[118] = I[119] = I[120] = I[121] = I[122] = I[123] = I[124] = I[125] = I[126] = I[127] = I[128] = I[129] = I[130] = (T)(img)(0,_p10##y,z,c)), \ - (I[145] = I[146] = I[147] = I[148] = I[149] = I[150] = I[151] = I[152] = I[153] = I[154] = I[155] = I[156] = I[157] = I[158] = I[159] = (T)(img)(0,_p9##y,z,c)), \ - (I[174] = I[175] = I[176] = I[177] = I[178] = I[179] = I[180] = I[181] = I[182] = I[183] = I[184] = I[185] = I[186] = I[187] = I[188] = (T)(img)(0,_p8##y,z,c)), \ - (I[203] = I[204] = I[205] = I[206] = I[207] = I[208] = I[209] = I[210] = I[211] = I[212] = I[213] = I[214] = I[215] = I[216] = I[217] = (T)(img)(0,_p7##y,z,c)), \ - (I[232] = I[233] = I[234] = I[235] = I[236] = I[237] = I[238] = I[239] = I[240] = I[241] = I[242] = I[243] = I[244] = I[245] = I[246] = (T)(img)(0,_p6##y,z,c)), \ - (I[261] = I[262] = I[263] = I[264] = I[265] = I[266] = I[267] = I[268] = I[269] = I[270] = I[271] = I[272] = I[273] = I[274] = I[275] = (T)(img)(0,_p5##y,z,c)), \ - (I[290] = I[291] = I[292] = I[293] = I[294] = I[295] = I[296] = I[297] = I[298] = I[299] = I[300] = I[301] = I[302] = I[303] = I[304] = (T)(img)(0,_p4##y,z,c)), \ - (I[319] = I[320] = I[321] = I[322] = I[323] = I[324] = I[325] = I[326] = I[327] = I[328] = I[329] = I[330] = I[331] = I[332] = I[333] = (T)(img)(0,_p3##y,z,c)), \ - (I[348] = I[349] = I[350] = I[351] = I[352] = I[353] = I[354] = I[355] = I[356] = I[357] = I[358] = I[359] = I[360] = I[361] = I[362] = (T)(img)(0,_p2##y,z,c)), \ - (I[377] = I[378] = I[379] = I[380] = I[381] = I[382] = I[383] = I[384] = I[385] = I[386] = I[387] = I[388] = I[389] = I[390] = I[391] = (T)(img)(0,_p1##y,z,c)), \ - (I[406] = I[407] = I[408] = I[409] = I[410] = I[411] = I[412] = I[413] = I[414] = I[415] = I[416] = I[417] = I[418] = I[419] = I[420] = (T)(img)(0,y,z,c)), \ - (I[435] = I[436] = I[437] = I[438] = I[439] = I[440] = I[441] = I[442] = I[443] = I[444] = I[445] = I[446] = I[447] = I[448] = I[449] = (T)(img)(0,_n1##y,z,c)), \ - (I[464] = I[465] = I[466] = I[467] = I[468] = I[469] = I[470] = I[471] = I[472] = I[473] = I[474] = I[475] = I[476] = I[477] = I[478] = (T)(img)(0,_n2##y,z,c)), \ - (I[493] = I[494] = I[495] = I[496] = I[497] = I[498] = I[499] = I[500] = I[501] = I[502] = I[503] = I[504] = I[505] = I[506] = I[507] = (T)(img)(0,_n3##y,z,c)), \ - (I[522] = I[523] = I[524] = I[525] = I[526] = I[527] = I[528] = I[529] = I[530] = I[531] = I[532] = I[533] = I[534] = I[535] = I[536] = (T)(img)(0,_n4##y,z,c)), \ - (I[551] = I[552] = I[553] = I[554] = I[555] = I[556] = I[557] = I[558] = I[559] = I[560] = I[561] = I[562] = I[563] = I[564] = I[565] = (T)(img)(0,_n5##y,z,c)), \ - (I[580] = I[581] = I[582] = I[583] = I[584] = I[585] = I[586] = I[587] = I[588] = I[589] = I[590] = I[591] = I[592] = I[593] = I[594] = (T)(img)(0,_n6##y,z,c)), \ - (I[609] = I[610] = I[611] = I[612] = I[613] = I[614] = I[615] = I[616] = I[617] = I[618] = I[619] = I[620] = I[621] = I[622] = I[623] = (T)(img)(0,_n7##y,z,c)), \ - (I[638] = I[639] = I[640] = I[641] = I[642] = I[643] = I[644] = I[645] = I[646] = I[647] = I[648] = I[649] = I[650] = I[651] = I[652] = (T)(img)(0,_n8##y,z,c)), \ - (I[667] = I[668] = I[669] = I[670] = I[671] = I[672] = I[673] = I[674] = I[675] = I[676] = I[677] = I[678] = I[679] = I[680] = I[681] = (T)(img)(0,_n9##y,z,c)), \ - (I[696] = I[697] = I[698] = I[699] = I[700] = I[701] = I[702] = I[703] = I[704] = I[705] = I[706] = I[707] = I[708] = I[709] = I[710] = (T)(img)(0,_n10##y,z,c)), \ - (I[725] = I[726] = I[727] = I[728] = I[729] = I[730] = I[731] = I[732] = I[733] = I[734] = I[735] = I[736] = I[737] = I[738] = I[739] = (T)(img)(0,_n11##y,z,c)), \ - (I[754] = I[755] = I[756] = I[757] = I[758] = I[759] = I[760] = I[761] = I[762] = I[763] = I[764] = I[765] = I[766] = I[767] = I[768] = (T)(img)(0,_n12##y,z,c)), \ - (I[783] = I[784] = I[785] = I[786] = I[787] = I[788] = I[789] = I[790] = I[791] = I[792] = I[793] = I[794] = I[795] = I[796] = I[797] = (T)(img)(0,_n13##y,z,c)), \ - (I[812] = I[813] = I[814] = I[815] = I[816] = I[817] = I[818] = I[819] = I[820] = I[821] = I[822] = I[823] = I[824] = I[825] = I[826] = (T)(img)(0,_n14##y,z,c)), \ - (I[15] = (T)(img)(_n1##x,_p14##y,z,c)), \ - (I[44] = (T)(img)(_n1##x,_p13##y,z,c)), \ - (I[73] = (T)(img)(_n1##x,_p12##y,z,c)), \ - (I[102] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[131] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[160] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[189] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[218] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[247] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[276] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[305] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[334] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[363] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[392] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[421] = (T)(img)(_n1##x,y,z,c)), \ - (I[450] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[479] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[508] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[537] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[566] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[595] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[624] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[653] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[682] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[711] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[740] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[769] = (T)(img)(_n1##x,_n12##y,z,c)), \ - (I[798] = (T)(img)(_n1##x,_n13##y,z,c)), \ - (I[827] = (T)(img)(_n1##x,_n14##y,z,c)), \ - (I[16] = (T)(img)(_n2##x,_p14##y,z,c)), \ - (I[45] = (T)(img)(_n2##x,_p13##y,z,c)), \ - (I[74] = (T)(img)(_n2##x,_p12##y,z,c)), \ - (I[103] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[132] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[161] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[190] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[219] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[248] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[277] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[306] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[335] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[364] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[393] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[422] = (T)(img)(_n2##x,y,z,c)), \ - (I[451] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[480] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[509] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[538] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[567] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[596] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[625] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[654] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[683] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[712] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[741] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[770] = (T)(img)(_n2##x,_n12##y,z,c)), \ - (I[799] = (T)(img)(_n2##x,_n13##y,z,c)), \ - (I[828] = (T)(img)(_n2##x,_n14##y,z,c)), \ - (I[17] = (T)(img)(_n3##x,_p14##y,z,c)), \ - (I[46] = (T)(img)(_n3##x,_p13##y,z,c)), \ - (I[75] = (T)(img)(_n3##x,_p12##y,z,c)), \ - (I[104] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[133] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[162] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[191] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[220] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[249] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[278] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[307] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[336] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[365] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[394] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[423] = (T)(img)(_n3##x,y,z,c)), \ - (I[452] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[481] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[510] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[539] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[568] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[597] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[626] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[655] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[684] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[713] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[742] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[771] = (T)(img)(_n3##x,_n12##y,z,c)), \ - (I[800] = (T)(img)(_n3##x,_n13##y,z,c)), \ - (I[829] = (T)(img)(_n3##x,_n14##y,z,c)), \ - (I[18] = (T)(img)(_n4##x,_p14##y,z,c)), \ - (I[47] = (T)(img)(_n4##x,_p13##y,z,c)), \ - (I[76] = (T)(img)(_n4##x,_p12##y,z,c)), \ - (I[105] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[134] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[163] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[192] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[221] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[250] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[279] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[308] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[337] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[366] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[395] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[424] = (T)(img)(_n4##x,y,z,c)), \ - (I[453] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[482] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[511] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[540] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[569] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[598] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[627] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[656] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[685] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[714] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[743] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[772] = (T)(img)(_n4##x,_n12##y,z,c)), \ - (I[801] = (T)(img)(_n4##x,_n13##y,z,c)), \ - (I[830] = (T)(img)(_n4##x,_n14##y,z,c)), \ - (I[19] = (T)(img)(_n5##x,_p14##y,z,c)), \ - (I[48] = (T)(img)(_n5##x,_p13##y,z,c)), \ - (I[77] = (T)(img)(_n5##x,_p12##y,z,c)), \ - (I[106] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[135] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[164] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[193] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[222] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[251] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[280] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[309] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[338] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[367] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[396] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[425] = (T)(img)(_n5##x,y,z,c)), \ - (I[454] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[483] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[512] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[541] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[570] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[599] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[628] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[657] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[686] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[715] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[744] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[773] = (T)(img)(_n5##x,_n12##y,z,c)), \ - (I[802] = (T)(img)(_n5##x,_n13##y,z,c)), \ - (I[831] = (T)(img)(_n5##x,_n14##y,z,c)), \ - (I[20] = (T)(img)(_n6##x,_p14##y,z,c)), \ - (I[49] = (T)(img)(_n6##x,_p13##y,z,c)), \ - (I[78] = (T)(img)(_n6##x,_p12##y,z,c)), \ - (I[107] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[136] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[165] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[194] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[223] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[252] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[281] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[310] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[339] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[368] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[397] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[426] = (T)(img)(_n6##x,y,z,c)), \ - (I[455] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[484] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[513] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[542] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[571] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[600] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[629] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[658] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[687] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[716] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[745] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[774] = (T)(img)(_n6##x,_n12##y,z,c)), \ - (I[803] = (T)(img)(_n6##x,_n13##y,z,c)), \ - (I[832] = (T)(img)(_n6##x,_n14##y,z,c)), \ - (I[21] = (T)(img)(_n7##x,_p14##y,z,c)), \ - (I[50] = (T)(img)(_n7##x,_p13##y,z,c)), \ - (I[79] = (T)(img)(_n7##x,_p12##y,z,c)), \ - (I[108] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[137] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[166] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[195] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[224] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[253] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[282] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[311] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[340] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[369] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[398] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[427] = (T)(img)(_n7##x,y,z,c)), \ - (I[456] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[485] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[514] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[543] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[572] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[601] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[630] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[659] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[688] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[717] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[746] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[775] = (T)(img)(_n7##x,_n12##y,z,c)), \ - (I[804] = (T)(img)(_n7##x,_n13##y,z,c)), \ - (I[833] = (T)(img)(_n7##x,_n14##y,z,c)), \ - (I[22] = (T)(img)(_n8##x,_p14##y,z,c)), \ - (I[51] = (T)(img)(_n8##x,_p13##y,z,c)), \ - (I[80] = (T)(img)(_n8##x,_p12##y,z,c)), \ - (I[109] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[138] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[167] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[196] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[225] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[254] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[283] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[312] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[341] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[370] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[399] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[428] = (T)(img)(_n8##x,y,z,c)), \ - (I[457] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[486] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[515] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[544] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[573] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[602] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[631] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[660] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[689] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[718] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[747] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[776] = (T)(img)(_n8##x,_n12##y,z,c)), \ - (I[805] = (T)(img)(_n8##x,_n13##y,z,c)), \ - (I[834] = (T)(img)(_n8##x,_n14##y,z,c)), \ - (I[23] = (T)(img)(_n9##x,_p14##y,z,c)), \ - (I[52] = (T)(img)(_n9##x,_p13##y,z,c)), \ - (I[81] = (T)(img)(_n9##x,_p12##y,z,c)), \ - (I[110] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[139] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[168] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[197] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[226] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[255] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[284] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[313] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[342] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[371] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[400] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[429] = (T)(img)(_n9##x,y,z,c)), \ - (I[458] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[487] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[516] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[545] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[574] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[603] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[632] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[661] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[690] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[719] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[748] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[777] = (T)(img)(_n9##x,_n12##y,z,c)), \ - (I[806] = (T)(img)(_n9##x,_n13##y,z,c)), \ - (I[835] = (T)(img)(_n9##x,_n14##y,z,c)), \ - (I[24] = (T)(img)(_n10##x,_p14##y,z,c)), \ - (I[53] = (T)(img)(_n10##x,_p13##y,z,c)), \ - (I[82] = (T)(img)(_n10##x,_p12##y,z,c)), \ - (I[111] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[140] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[169] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[198] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[227] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[256] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[285] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[314] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[343] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[372] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[401] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[430] = (T)(img)(_n10##x,y,z,c)), \ - (I[459] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[488] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[517] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[546] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[575] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[604] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[633] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[662] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[691] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[720] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[749] = (T)(img)(_n10##x,_n11##y,z,c)), \ - (I[778] = (T)(img)(_n10##x,_n12##y,z,c)), \ - (I[807] = (T)(img)(_n10##x,_n13##y,z,c)), \ - (I[836] = (T)(img)(_n10##x,_n14##y,z,c)), \ - (I[25] = (T)(img)(_n11##x,_p14##y,z,c)), \ - (I[54] = (T)(img)(_n11##x,_p13##y,z,c)), \ - (I[83] = (T)(img)(_n11##x,_p12##y,z,c)), \ - (I[112] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[141] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[170] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[199] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[228] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[257] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[286] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[315] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[344] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[373] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[402] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[431] = (T)(img)(_n11##x,y,z,c)), \ - (I[460] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[489] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[518] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[547] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[576] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[605] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[634] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[663] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[692] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[721] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[750] = (T)(img)(_n11##x,_n11##y,z,c)), \ - (I[779] = (T)(img)(_n11##x,_n12##y,z,c)), \ - (I[808] = (T)(img)(_n11##x,_n13##y,z,c)), \ - (I[837] = (T)(img)(_n11##x,_n14##y,z,c)), \ - (I[26] = (T)(img)(_n12##x,_p14##y,z,c)), \ - (I[55] = (T)(img)(_n12##x,_p13##y,z,c)), \ - (I[84] = (T)(img)(_n12##x,_p12##y,z,c)), \ - (I[113] = (T)(img)(_n12##x,_p11##y,z,c)), \ - (I[142] = (T)(img)(_n12##x,_p10##y,z,c)), \ - (I[171] = (T)(img)(_n12##x,_p9##y,z,c)), \ - (I[200] = (T)(img)(_n12##x,_p8##y,z,c)), \ - (I[229] = (T)(img)(_n12##x,_p7##y,z,c)), \ - (I[258] = (T)(img)(_n12##x,_p6##y,z,c)), \ - (I[287] = (T)(img)(_n12##x,_p5##y,z,c)), \ - (I[316] = (T)(img)(_n12##x,_p4##y,z,c)), \ - (I[345] = (T)(img)(_n12##x,_p3##y,z,c)), \ - (I[374] = (T)(img)(_n12##x,_p2##y,z,c)), \ - (I[403] = (T)(img)(_n12##x,_p1##y,z,c)), \ - (I[432] = (T)(img)(_n12##x,y,z,c)), \ - (I[461] = (T)(img)(_n12##x,_n1##y,z,c)), \ - (I[490] = (T)(img)(_n12##x,_n2##y,z,c)), \ - (I[519] = (T)(img)(_n12##x,_n3##y,z,c)), \ - (I[548] = (T)(img)(_n12##x,_n4##y,z,c)), \ - (I[577] = (T)(img)(_n12##x,_n5##y,z,c)), \ - (I[606] = (T)(img)(_n12##x,_n6##y,z,c)), \ - (I[635] = (T)(img)(_n12##x,_n7##y,z,c)), \ - (I[664] = (T)(img)(_n12##x,_n8##y,z,c)), \ - (I[693] = (T)(img)(_n12##x,_n9##y,z,c)), \ - (I[722] = (T)(img)(_n12##x,_n10##y,z,c)), \ - (I[751] = (T)(img)(_n12##x,_n11##y,z,c)), \ - (I[780] = (T)(img)(_n12##x,_n12##y,z,c)), \ - (I[809] = (T)(img)(_n12##x,_n13##y,z,c)), \ - (I[838] = (T)(img)(_n12##x,_n14##y,z,c)), \ - (I[27] = (T)(img)(_n13##x,_p14##y,z,c)), \ - (I[56] = (T)(img)(_n13##x,_p13##y,z,c)), \ - (I[85] = (T)(img)(_n13##x,_p12##y,z,c)), \ - (I[114] = (T)(img)(_n13##x,_p11##y,z,c)), \ - (I[143] = (T)(img)(_n13##x,_p10##y,z,c)), \ - (I[172] = (T)(img)(_n13##x,_p9##y,z,c)), \ - (I[201] = (T)(img)(_n13##x,_p8##y,z,c)), \ - (I[230] = (T)(img)(_n13##x,_p7##y,z,c)), \ - (I[259] = (T)(img)(_n13##x,_p6##y,z,c)), \ - (I[288] = (T)(img)(_n13##x,_p5##y,z,c)), \ - (I[317] = (T)(img)(_n13##x,_p4##y,z,c)), \ - (I[346] = (T)(img)(_n13##x,_p3##y,z,c)), \ - (I[375] = (T)(img)(_n13##x,_p2##y,z,c)), \ - (I[404] = (T)(img)(_n13##x,_p1##y,z,c)), \ - (I[433] = (T)(img)(_n13##x,y,z,c)), \ - (I[462] = (T)(img)(_n13##x,_n1##y,z,c)), \ - (I[491] = (T)(img)(_n13##x,_n2##y,z,c)), \ - (I[520] = (T)(img)(_n13##x,_n3##y,z,c)), \ - (I[549] = (T)(img)(_n13##x,_n4##y,z,c)), \ - (I[578] = (T)(img)(_n13##x,_n5##y,z,c)), \ - (I[607] = (T)(img)(_n13##x,_n6##y,z,c)), \ - (I[636] = (T)(img)(_n13##x,_n7##y,z,c)), \ - (I[665] = (T)(img)(_n13##x,_n8##y,z,c)), \ - (I[694] = (T)(img)(_n13##x,_n9##y,z,c)), \ - (I[723] = (T)(img)(_n13##x,_n10##y,z,c)), \ - (I[752] = (T)(img)(_n13##x,_n11##y,z,c)), \ - (I[781] = (T)(img)(_n13##x,_n12##y,z,c)), \ - (I[810] = (T)(img)(_n13##x,_n13##y,z,c)), \ - (I[839] = (T)(img)(_n13##x,_n14##y,z,c)), \ - 14>=((img)._width)?(img).width() - 1:14); \ - (_n14##x<(img).width() && ( \ - (I[28] = (T)(img)(_n14##x,_p14##y,z,c)), \ - (I[57] = (T)(img)(_n14##x,_p13##y,z,c)), \ - (I[86] = (T)(img)(_n14##x,_p12##y,z,c)), \ - (I[115] = (T)(img)(_n14##x,_p11##y,z,c)), \ - (I[144] = (T)(img)(_n14##x,_p10##y,z,c)), \ - (I[173] = (T)(img)(_n14##x,_p9##y,z,c)), \ - (I[202] = (T)(img)(_n14##x,_p8##y,z,c)), \ - (I[231] = (T)(img)(_n14##x,_p7##y,z,c)), \ - (I[260] = (T)(img)(_n14##x,_p6##y,z,c)), \ - (I[289] = (T)(img)(_n14##x,_p5##y,z,c)), \ - (I[318] = (T)(img)(_n14##x,_p4##y,z,c)), \ - (I[347] = (T)(img)(_n14##x,_p3##y,z,c)), \ - (I[376] = (T)(img)(_n14##x,_p2##y,z,c)), \ - (I[405] = (T)(img)(_n14##x,_p1##y,z,c)), \ - (I[434] = (T)(img)(_n14##x,y,z,c)), \ - (I[463] = (T)(img)(_n14##x,_n1##y,z,c)), \ - (I[492] = (T)(img)(_n14##x,_n2##y,z,c)), \ - (I[521] = (T)(img)(_n14##x,_n3##y,z,c)), \ - (I[550] = (T)(img)(_n14##x,_n4##y,z,c)), \ - (I[579] = (T)(img)(_n14##x,_n5##y,z,c)), \ - (I[608] = (T)(img)(_n14##x,_n6##y,z,c)), \ - (I[637] = (T)(img)(_n14##x,_n7##y,z,c)), \ - (I[666] = (T)(img)(_n14##x,_n8##y,z,c)), \ - (I[695] = (T)(img)(_n14##x,_n9##y,z,c)), \ - (I[724] = (T)(img)(_n14##x,_n10##y,z,c)), \ - (I[753] = (T)(img)(_n14##x,_n11##y,z,c)), \ - (I[782] = (T)(img)(_n14##x,_n12##y,z,c)), \ - (I[811] = (T)(img)(_n14##x,_n13##y,z,c)), \ - (I[840] = (T)(img)(_n14##x,_n14##y,z,c)),1)) || \ - _n13##x==--_n14##x || _n12##x==--_n13##x || _n11##x==--_n12##x || _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n14##x = _n13##x = _n12##x = _n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], \ - I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], \ - I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], \ - I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], \ - I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], \ - I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], \ - I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], \ - I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], \ - I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], \ - I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], \ - I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], \ - I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], \ - I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], \ - I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], \ - I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], I[415] = I[416], I[416] = I[417], I[417] = I[418], I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], I[433] = I[434], \ - I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], I[447] = I[448], I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], \ - I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], I[479] = I[480], I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], \ - I[493] = I[494], I[494] = I[495], I[495] = I[496], I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], I[503] = I[504], I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], I[511] = I[512], I[512] = I[513], I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], I[519] = I[520], I[520] = I[521], \ - I[522] = I[523], I[523] = I[524], I[524] = I[525], I[525] = I[526], I[526] = I[527], I[527] = I[528], I[528] = I[529], I[529] = I[530], I[530] = I[531], I[531] = I[532], I[532] = I[533], I[533] = I[534], I[534] = I[535], I[535] = I[536], I[536] = I[537], I[537] = I[538], I[538] = I[539], I[539] = I[540], I[540] = I[541], I[541] = I[542], I[542] = I[543], I[543] = I[544], I[544] = I[545], I[545] = I[546], I[546] = I[547], I[547] = I[548], I[548] = I[549], I[549] = I[550], \ - I[551] = I[552], I[552] = I[553], I[553] = I[554], I[554] = I[555], I[555] = I[556], I[556] = I[557], I[557] = I[558], I[558] = I[559], I[559] = I[560], I[560] = I[561], I[561] = I[562], I[562] = I[563], I[563] = I[564], I[564] = I[565], I[565] = I[566], I[566] = I[567], I[567] = I[568], I[568] = I[569], I[569] = I[570], I[570] = I[571], I[571] = I[572], I[572] = I[573], I[573] = I[574], I[574] = I[575], I[575] = I[576], I[576] = I[577], I[577] = I[578], I[578] = I[579], \ - I[580] = I[581], I[581] = I[582], I[582] = I[583], I[583] = I[584], I[584] = I[585], I[585] = I[586], I[586] = I[587], I[587] = I[588], I[588] = I[589], I[589] = I[590], I[590] = I[591], I[591] = I[592], I[592] = I[593], I[593] = I[594], I[594] = I[595], I[595] = I[596], I[596] = I[597], I[597] = I[598], I[598] = I[599], I[599] = I[600], I[600] = I[601], I[601] = I[602], I[602] = I[603], I[603] = I[604], I[604] = I[605], I[605] = I[606], I[606] = I[607], I[607] = I[608], \ - I[609] = I[610], I[610] = I[611], I[611] = I[612], I[612] = I[613], I[613] = I[614], I[614] = I[615], I[615] = I[616], I[616] = I[617], I[617] = I[618], I[618] = I[619], I[619] = I[620], I[620] = I[621], I[621] = I[622], I[622] = I[623], I[623] = I[624], I[624] = I[625], I[625] = I[626], I[626] = I[627], I[627] = I[628], I[628] = I[629], I[629] = I[630], I[630] = I[631], I[631] = I[632], I[632] = I[633], I[633] = I[634], I[634] = I[635], I[635] = I[636], I[636] = I[637], \ - I[638] = I[639], I[639] = I[640], I[640] = I[641], I[641] = I[642], I[642] = I[643], I[643] = I[644], I[644] = I[645], I[645] = I[646], I[646] = I[647], I[647] = I[648], I[648] = I[649], I[649] = I[650], I[650] = I[651], I[651] = I[652], I[652] = I[653], I[653] = I[654], I[654] = I[655], I[655] = I[656], I[656] = I[657], I[657] = I[658], I[658] = I[659], I[659] = I[660], I[660] = I[661], I[661] = I[662], I[662] = I[663], I[663] = I[664], I[664] = I[665], I[665] = I[666], \ - I[667] = I[668], I[668] = I[669], I[669] = I[670], I[670] = I[671], I[671] = I[672], I[672] = I[673], I[673] = I[674], I[674] = I[675], I[675] = I[676], I[676] = I[677], I[677] = I[678], I[678] = I[679], I[679] = I[680], I[680] = I[681], I[681] = I[682], I[682] = I[683], I[683] = I[684], I[684] = I[685], I[685] = I[686], I[686] = I[687], I[687] = I[688], I[688] = I[689], I[689] = I[690], I[690] = I[691], I[691] = I[692], I[692] = I[693], I[693] = I[694], I[694] = I[695], \ - I[696] = I[697], I[697] = I[698], I[698] = I[699], I[699] = I[700], I[700] = I[701], I[701] = I[702], I[702] = I[703], I[703] = I[704], I[704] = I[705], I[705] = I[706], I[706] = I[707], I[707] = I[708], I[708] = I[709], I[709] = I[710], I[710] = I[711], I[711] = I[712], I[712] = I[713], I[713] = I[714], I[714] = I[715], I[715] = I[716], I[716] = I[717], I[717] = I[718], I[718] = I[719], I[719] = I[720], I[720] = I[721], I[721] = I[722], I[722] = I[723], I[723] = I[724], \ - I[725] = I[726], I[726] = I[727], I[727] = I[728], I[728] = I[729], I[729] = I[730], I[730] = I[731], I[731] = I[732], I[732] = I[733], I[733] = I[734], I[734] = I[735], I[735] = I[736], I[736] = I[737], I[737] = I[738], I[738] = I[739], I[739] = I[740], I[740] = I[741], I[741] = I[742], I[742] = I[743], I[743] = I[744], I[744] = I[745], I[745] = I[746], I[746] = I[747], I[747] = I[748], I[748] = I[749], I[749] = I[750], I[750] = I[751], I[751] = I[752], I[752] = I[753], \ - I[754] = I[755], I[755] = I[756], I[756] = I[757], I[757] = I[758], I[758] = I[759], I[759] = I[760], I[760] = I[761], I[761] = I[762], I[762] = I[763], I[763] = I[764], I[764] = I[765], I[765] = I[766], I[766] = I[767], I[767] = I[768], I[768] = I[769], I[769] = I[770], I[770] = I[771], I[771] = I[772], I[772] = I[773], I[773] = I[774], I[774] = I[775], I[775] = I[776], I[776] = I[777], I[777] = I[778], I[778] = I[779], I[779] = I[780], I[780] = I[781], I[781] = I[782], \ - I[783] = I[784], I[784] = I[785], I[785] = I[786], I[786] = I[787], I[787] = I[788], I[788] = I[789], I[789] = I[790], I[790] = I[791], I[791] = I[792], I[792] = I[793], I[793] = I[794], I[794] = I[795], I[795] = I[796], I[796] = I[797], I[797] = I[798], I[798] = I[799], I[799] = I[800], I[800] = I[801], I[801] = I[802], I[802] = I[803], I[803] = I[804], I[804] = I[805], I[805] = I[806], I[806] = I[807], I[807] = I[808], I[808] = I[809], I[809] = I[810], I[810] = I[811], \ - I[812] = I[813], I[813] = I[814], I[814] = I[815], I[815] = I[816], I[816] = I[817], I[817] = I[818], I[818] = I[819], I[819] = I[820], I[820] = I[821], I[821] = I[822], I[822] = I[823], I[823] = I[824], I[824] = I[825], I[825] = I[826], I[826] = I[827], I[827] = I[828], I[828] = I[829], I[829] = I[830], I[830] = I[831], I[831] = I[832], I[832] = I[833], I[833] = I[834], I[834] = I[835], I[835] = I[836], I[836] = I[837], I[837] = I[838], I[838] = I[839], I[839] = I[840], \ - _p14##x = _p13##x, _p13##x = _p12##x, _p12##x = _p11##x, _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x, ++_n12##x, ++_n13##x, ++_n14##x) - -#define cimg_for_in29x29(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in29((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p14##x = x - 14<0?0:x - 14, \ - _p13##x = x - 13<0?0:x - 13, \ - _p12##x = x - 12<0?0:x - 12, \ - _p11##x = x - 11<0?0:x - 11, \ - _p10##x = x - 10<0?0:x - 10, \ - _p9##x = x - 9<0?0:x - 9, \ - _p8##x = x - 8<0?0:x - 8, \ - _p7##x = x - 7<0?0:x - 7, \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = x + 6>=(img).width()?(img).width() - 1:x + 6, \ - _n7##x = x + 7>=(img).width()?(img).width() - 1:x + 7, \ - _n8##x = x + 8>=(img).width()?(img).width() - 1:x + 8, \ - _n9##x = x + 9>=(img).width()?(img).width() - 1:x + 9, \ - _n10##x = x + 10>=(img).width()?(img).width() - 1:x + 10, \ - _n11##x = x + 11>=(img).width()?(img).width() - 1:x + 11, \ - _n12##x = x + 12>=(img).width()?(img).width() - 1:x + 12, \ - _n13##x = x + 13>=(img).width()?(img).width() - 1:x + 13, \ - _n14##x = (int)( \ - (I[0] = (T)(img)(_p14##x,_p14##y,z,c)), \ - (I[29] = (T)(img)(_p14##x,_p13##y,z,c)), \ - (I[58] = (T)(img)(_p14##x,_p12##y,z,c)), \ - (I[87] = (T)(img)(_p14##x,_p11##y,z,c)), \ - (I[116] = (T)(img)(_p14##x,_p10##y,z,c)), \ - (I[145] = (T)(img)(_p14##x,_p9##y,z,c)), \ - (I[174] = (T)(img)(_p14##x,_p8##y,z,c)), \ - (I[203] = (T)(img)(_p14##x,_p7##y,z,c)), \ - (I[232] = (T)(img)(_p14##x,_p6##y,z,c)), \ - (I[261] = (T)(img)(_p14##x,_p5##y,z,c)), \ - (I[290] = (T)(img)(_p14##x,_p4##y,z,c)), \ - (I[319] = (T)(img)(_p14##x,_p3##y,z,c)), \ - (I[348] = (T)(img)(_p14##x,_p2##y,z,c)), \ - (I[377] = (T)(img)(_p14##x,_p1##y,z,c)), \ - (I[406] = (T)(img)(_p14##x,y,z,c)), \ - (I[435] = (T)(img)(_p14##x,_n1##y,z,c)), \ - (I[464] = (T)(img)(_p14##x,_n2##y,z,c)), \ - (I[493] = (T)(img)(_p14##x,_n3##y,z,c)), \ - (I[522] = (T)(img)(_p14##x,_n4##y,z,c)), \ - (I[551] = (T)(img)(_p14##x,_n5##y,z,c)), \ - (I[580] = (T)(img)(_p14##x,_n6##y,z,c)), \ - (I[609] = (T)(img)(_p14##x,_n7##y,z,c)), \ - (I[638] = (T)(img)(_p14##x,_n8##y,z,c)), \ - (I[667] = (T)(img)(_p14##x,_n9##y,z,c)), \ - (I[696] = (T)(img)(_p14##x,_n10##y,z,c)), \ - (I[725] = (T)(img)(_p14##x,_n11##y,z,c)), \ - (I[754] = (T)(img)(_p14##x,_n12##y,z,c)), \ - (I[783] = (T)(img)(_p14##x,_n13##y,z,c)), \ - (I[812] = (T)(img)(_p14##x,_n14##y,z,c)), \ - (I[1] = (T)(img)(_p13##x,_p14##y,z,c)), \ - (I[30] = (T)(img)(_p13##x,_p13##y,z,c)), \ - (I[59] = (T)(img)(_p13##x,_p12##y,z,c)), \ - (I[88] = (T)(img)(_p13##x,_p11##y,z,c)), \ - (I[117] = (T)(img)(_p13##x,_p10##y,z,c)), \ - (I[146] = (T)(img)(_p13##x,_p9##y,z,c)), \ - (I[175] = (T)(img)(_p13##x,_p8##y,z,c)), \ - (I[204] = (T)(img)(_p13##x,_p7##y,z,c)), \ - (I[233] = (T)(img)(_p13##x,_p6##y,z,c)), \ - (I[262] = (T)(img)(_p13##x,_p5##y,z,c)), \ - (I[291] = (T)(img)(_p13##x,_p4##y,z,c)), \ - (I[320] = (T)(img)(_p13##x,_p3##y,z,c)), \ - (I[349] = (T)(img)(_p13##x,_p2##y,z,c)), \ - (I[378] = (T)(img)(_p13##x,_p1##y,z,c)), \ - (I[407] = (T)(img)(_p13##x,y,z,c)), \ - (I[436] = (T)(img)(_p13##x,_n1##y,z,c)), \ - (I[465] = (T)(img)(_p13##x,_n2##y,z,c)), \ - (I[494] = (T)(img)(_p13##x,_n3##y,z,c)), \ - (I[523] = (T)(img)(_p13##x,_n4##y,z,c)), \ - (I[552] = (T)(img)(_p13##x,_n5##y,z,c)), \ - (I[581] = (T)(img)(_p13##x,_n6##y,z,c)), \ - (I[610] = (T)(img)(_p13##x,_n7##y,z,c)), \ - (I[639] = (T)(img)(_p13##x,_n8##y,z,c)), \ - (I[668] = (T)(img)(_p13##x,_n9##y,z,c)), \ - (I[697] = (T)(img)(_p13##x,_n10##y,z,c)), \ - (I[726] = (T)(img)(_p13##x,_n11##y,z,c)), \ - (I[755] = (T)(img)(_p13##x,_n12##y,z,c)), \ - (I[784] = (T)(img)(_p13##x,_n13##y,z,c)), \ - (I[813] = (T)(img)(_p13##x,_n14##y,z,c)), \ - (I[2] = (T)(img)(_p12##x,_p14##y,z,c)), \ - (I[31] = (T)(img)(_p12##x,_p13##y,z,c)), \ - (I[60] = (T)(img)(_p12##x,_p12##y,z,c)), \ - (I[89] = (T)(img)(_p12##x,_p11##y,z,c)), \ - (I[118] = (T)(img)(_p12##x,_p10##y,z,c)), \ - (I[147] = (T)(img)(_p12##x,_p9##y,z,c)), \ - (I[176] = (T)(img)(_p12##x,_p8##y,z,c)), \ - (I[205] = (T)(img)(_p12##x,_p7##y,z,c)), \ - (I[234] = (T)(img)(_p12##x,_p6##y,z,c)), \ - (I[263] = (T)(img)(_p12##x,_p5##y,z,c)), \ - (I[292] = (T)(img)(_p12##x,_p4##y,z,c)), \ - (I[321] = (T)(img)(_p12##x,_p3##y,z,c)), \ - (I[350] = (T)(img)(_p12##x,_p2##y,z,c)), \ - (I[379] = (T)(img)(_p12##x,_p1##y,z,c)), \ - (I[408] = (T)(img)(_p12##x,y,z,c)), \ - (I[437] = (T)(img)(_p12##x,_n1##y,z,c)), \ - (I[466] = (T)(img)(_p12##x,_n2##y,z,c)), \ - (I[495] = (T)(img)(_p12##x,_n3##y,z,c)), \ - (I[524] = (T)(img)(_p12##x,_n4##y,z,c)), \ - (I[553] = (T)(img)(_p12##x,_n5##y,z,c)), \ - (I[582] = (T)(img)(_p12##x,_n6##y,z,c)), \ - (I[611] = (T)(img)(_p12##x,_n7##y,z,c)), \ - (I[640] = (T)(img)(_p12##x,_n8##y,z,c)), \ - (I[669] = (T)(img)(_p12##x,_n9##y,z,c)), \ - (I[698] = (T)(img)(_p12##x,_n10##y,z,c)), \ - (I[727] = (T)(img)(_p12##x,_n11##y,z,c)), \ - (I[756] = (T)(img)(_p12##x,_n12##y,z,c)), \ - (I[785] = (T)(img)(_p12##x,_n13##y,z,c)), \ - (I[814] = (T)(img)(_p12##x,_n14##y,z,c)), \ - (I[3] = (T)(img)(_p11##x,_p14##y,z,c)), \ - (I[32] = (T)(img)(_p11##x,_p13##y,z,c)), \ - (I[61] = (T)(img)(_p11##x,_p12##y,z,c)), \ - (I[90] = (T)(img)(_p11##x,_p11##y,z,c)), \ - (I[119] = (T)(img)(_p11##x,_p10##y,z,c)), \ - (I[148] = (T)(img)(_p11##x,_p9##y,z,c)), \ - (I[177] = (T)(img)(_p11##x,_p8##y,z,c)), \ - (I[206] = (T)(img)(_p11##x,_p7##y,z,c)), \ - (I[235] = (T)(img)(_p11##x,_p6##y,z,c)), \ - (I[264] = (T)(img)(_p11##x,_p5##y,z,c)), \ - (I[293] = (T)(img)(_p11##x,_p4##y,z,c)), \ - (I[322] = (T)(img)(_p11##x,_p3##y,z,c)), \ - (I[351] = (T)(img)(_p11##x,_p2##y,z,c)), \ - (I[380] = (T)(img)(_p11##x,_p1##y,z,c)), \ - (I[409] = (T)(img)(_p11##x,y,z,c)), \ - (I[438] = (T)(img)(_p11##x,_n1##y,z,c)), \ - (I[467] = (T)(img)(_p11##x,_n2##y,z,c)), \ - (I[496] = (T)(img)(_p11##x,_n3##y,z,c)), \ - (I[525] = (T)(img)(_p11##x,_n4##y,z,c)), \ - (I[554] = (T)(img)(_p11##x,_n5##y,z,c)), \ - (I[583] = (T)(img)(_p11##x,_n6##y,z,c)), \ - (I[612] = (T)(img)(_p11##x,_n7##y,z,c)), \ - (I[641] = (T)(img)(_p11##x,_n8##y,z,c)), \ - (I[670] = (T)(img)(_p11##x,_n9##y,z,c)), \ - (I[699] = (T)(img)(_p11##x,_n10##y,z,c)), \ - (I[728] = (T)(img)(_p11##x,_n11##y,z,c)), \ - (I[757] = (T)(img)(_p11##x,_n12##y,z,c)), \ - (I[786] = (T)(img)(_p11##x,_n13##y,z,c)), \ - (I[815] = (T)(img)(_p11##x,_n14##y,z,c)), \ - (I[4] = (T)(img)(_p10##x,_p14##y,z,c)), \ - (I[33] = (T)(img)(_p10##x,_p13##y,z,c)), \ - (I[62] = (T)(img)(_p10##x,_p12##y,z,c)), \ - (I[91] = (T)(img)(_p10##x,_p11##y,z,c)), \ - (I[120] = (T)(img)(_p10##x,_p10##y,z,c)), \ - (I[149] = (T)(img)(_p10##x,_p9##y,z,c)), \ - (I[178] = (T)(img)(_p10##x,_p8##y,z,c)), \ - (I[207] = (T)(img)(_p10##x,_p7##y,z,c)), \ - (I[236] = (T)(img)(_p10##x,_p6##y,z,c)), \ - (I[265] = (T)(img)(_p10##x,_p5##y,z,c)), \ - (I[294] = (T)(img)(_p10##x,_p4##y,z,c)), \ - (I[323] = (T)(img)(_p10##x,_p3##y,z,c)), \ - (I[352] = (T)(img)(_p10##x,_p2##y,z,c)), \ - (I[381] = (T)(img)(_p10##x,_p1##y,z,c)), \ - (I[410] = (T)(img)(_p10##x,y,z,c)), \ - (I[439] = (T)(img)(_p10##x,_n1##y,z,c)), \ - (I[468] = (T)(img)(_p10##x,_n2##y,z,c)), \ - (I[497] = (T)(img)(_p10##x,_n3##y,z,c)), \ - (I[526] = (T)(img)(_p10##x,_n4##y,z,c)), \ - (I[555] = (T)(img)(_p10##x,_n5##y,z,c)), \ - (I[584] = (T)(img)(_p10##x,_n6##y,z,c)), \ - (I[613] = (T)(img)(_p10##x,_n7##y,z,c)), \ - (I[642] = (T)(img)(_p10##x,_n8##y,z,c)), \ - (I[671] = (T)(img)(_p10##x,_n9##y,z,c)), \ - (I[700] = (T)(img)(_p10##x,_n10##y,z,c)), \ - (I[729] = (T)(img)(_p10##x,_n11##y,z,c)), \ - (I[758] = (T)(img)(_p10##x,_n12##y,z,c)), \ - (I[787] = (T)(img)(_p10##x,_n13##y,z,c)), \ - (I[816] = (T)(img)(_p10##x,_n14##y,z,c)), \ - (I[5] = (T)(img)(_p9##x,_p14##y,z,c)), \ - (I[34] = (T)(img)(_p9##x,_p13##y,z,c)), \ - (I[63] = (T)(img)(_p9##x,_p12##y,z,c)), \ - (I[92] = (T)(img)(_p9##x,_p11##y,z,c)), \ - (I[121] = (T)(img)(_p9##x,_p10##y,z,c)), \ - (I[150] = (T)(img)(_p9##x,_p9##y,z,c)), \ - (I[179] = (T)(img)(_p9##x,_p8##y,z,c)), \ - (I[208] = (T)(img)(_p9##x,_p7##y,z,c)), \ - (I[237] = (T)(img)(_p9##x,_p6##y,z,c)), \ - (I[266] = (T)(img)(_p9##x,_p5##y,z,c)), \ - (I[295] = (T)(img)(_p9##x,_p4##y,z,c)), \ - (I[324] = (T)(img)(_p9##x,_p3##y,z,c)), \ - (I[353] = (T)(img)(_p9##x,_p2##y,z,c)), \ - (I[382] = (T)(img)(_p9##x,_p1##y,z,c)), \ - (I[411] = (T)(img)(_p9##x,y,z,c)), \ - (I[440] = (T)(img)(_p9##x,_n1##y,z,c)), \ - (I[469] = (T)(img)(_p9##x,_n2##y,z,c)), \ - (I[498] = (T)(img)(_p9##x,_n3##y,z,c)), \ - (I[527] = (T)(img)(_p9##x,_n4##y,z,c)), \ - (I[556] = (T)(img)(_p9##x,_n5##y,z,c)), \ - (I[585] = (T)(img)(_p9##x,_n6##y,z,c)), \ - (I[614] = (T)(img)(_p9##x,_n7##y,z,c)), \ - (I[643] = (T)(img)(_p9##x,_n8##y,z,c)), \ - (I[672] = (T)(img)(_p9##x,_n9##y,z,c)), \ - (I[701] = (T)(img)(_p9##x,_n10##y,z,c)), \ - (I[730] = (T)(img)(_p9##x,_n11##y,z,c)), \ - (I[759] = (T)(img)(_p9##x,_n12##y,z,c)), \ - (I[788] = (T)(img)(_p9##x,_n13##y,z,c)), \ - (I[817] = (T)(img)(_p9##x,_n14##y,z,c)), \ - (I[6] = (T)(img)(_p8##x,_p14##y,z,c)), \ - (I[35] = (T)(img)(_p8##x,_p13##y,z,c)), \ - (I[64] = (T)(img)(_p8##x,_p12##y,z,c)), \ - (I[93] = (T)(img)(_p8##x,_p11##y,z,c)), \ - (I[122] = (T)(img)(_p8##x,_p10##y,z,c)), \ - (I[151] = (T)(img)(_p8##x,_p9##y,z,c)), \ - (I[180] = (T)(img)(_p8##x,_p8##y,z,c)), \ - (I[209] = (T)(img)(_p8##x,_p7##y,z,c)), \ - (I[238] = (T)(img)(_p8##x,_p6##y,z,c)), \ - (I[267] = (T)(img)(_p8##x,_p5##y,z,c)), \ - (I[296] = (T)(img)(_p8##x,_p4##y,z,c)), \ - (I[325] = (T)(img)(_p8##x,_p3##y,z,c)), \ - (I[354] = (T)(img)(_p8##x,_p2##y,z,c)), \ - (I[383] = (T)(img)(_p8##x,_p1##y,z,c)), \ - (I[412] = (T)(img)(_p8##x,y,z,c)), \ - (I[441] = (T)(img)(_p8##x,_n1##y,z,c)), \ - (I[470] = (T)(img)(_p8##x,_n2##y,z,c)), \ - (I[499] = (T)(img)(_p8##x,_n3##y,z,c)), \ - (I[528] = (T)(img)(_p8##x,_n4##y,z,c)), \ - (I[557] = (T)(img)(_p8##x,_n5##y,z,c)), \ - (I[586] = (T)(img)(_p8##x,_n6##y,z,c)), \ - (I[615] = (T)(img)(_p8##x,_n7##y,z,c)), \ - (I[644] = (T)(img)(_p8##x,_n8##y,z,c)), \ - (I[673] = (T)(img)(_p8##x,_n9##y,z,c)), \ - (I[702] = (T)(img)(_p8##x,_n10##y,z,c)), \ - (I[731] = (T)(img)(_p8##x,_n11##y,z,c)), \ - (I[760] = (T)(img)(_p8##x,_n12##y,z,c)), \ - (I[789] = (T)(img)(_p8##x,_n13##y,z,c)), \ - (I[818] = (T)(img)(_p8##x,_n14##y,z,c)), \ - (I[7] = (T)(img)(_p7##x,_p14##y,z,c)), \ - (I[36] = (T)(img)(_p7##x,_p13##y,z,c)), \ - (I[65] = (T)(img)(_p7##x,_p12##y,z,c)), \ - (I[94] = (T)(img)(_p7##x,_p11##y,z,c)), \ - (I[123] = (T)(img)(_p7##x,_p10##y,z,c)), \ - (I[152] = (T)(img)(_p7##x,_p9##y,z,c)), \ - (I[181] = (T)(img)(_p7##x,_p8##y,z,c)), \ - (I[210] = (T)(img)(_p7##x,_p7##y,z,c)), \ - (I[239] = (T)(img)(_p7##x,_p6##y,z,c)), \ - (I[268] = (T)(img)(_p7##x,_p5##y,z,c)), \ - (I[297] = (T)(img)(_p7##x,_p4##y,z,c)), \ - (I[326] = (T)(img)(_p7##x,_p3##y,z,c)), \ - (I[355] = (T)(img)(_p7##x,_p2##y,z,c)), \ - (I[384] = (T)(img)(_p7##x,_p1##y,z,c)), \ - (I[413] = (T)(img)(_p7##x,y,z,c)), \ - (I[442] = (T)(img)(_p7##x,_n1##y,z,c)), \ - (I[471] = (T)(img)(_p7##x,_n2##y,z,c)), \ - (I[500] = (T)(img)(_p7##x,_n3##y,z,c)), \ - (I[529] = (T)(img)(_p7##x,_n4##y,z,c)), \ - (I[558] = (T)(img)(_p7##x,_n5##y,z,c)), \ - (I[587] = (T)(img)(_p7##x,_n6##y,z,c)), \ - (I[616] = (T)(img)(_p7##x,_n7##y,z,c)), \ - (I[645] = (T)(img)(_p7##x,_n8##y,z,c)), \ - (I[674] = (T)(img)(_p7##x,_n9##y,z,c)), \ - (I[703] = (T)(img)(_p7##x,_n10##y,z,c)), \ - (I[732] = (T)(img)(_p7##x,_n11##y,z,c)), \ - (I[761] = (T)(img)(_p7##x,_n12##y,z,c)), \ - (I[790] = (T)(img)(_p7##x,_n13##y,z,c)), \ - (I[819] = (T)(img)(_p7##x,_n14##y,z,c)), \ - (I[8] = (T)(img)(_p6##x,_p14##y,z,c)), \ - (I[37] = (T)(img)(_p6##x,_p13##y,z,c)), \ - (I[66] = (T)(img)(_p6##x,_p12##y,z,c)), \ - (I[95] = (T)(img)(_p6##x,_p11##y,z,c)), \ - (I[124] = (T)(img)(_p6##x,_p10##y,z,c)), \ - (I[153] = (T)(img)(_p6##x,_p9##y,z,c)), \ - (I[182] = (T)(img)(_p6##x,_p8##y,z,c)), \ - (I[211] = (T)(img)(_p6##x,_p7##y,z,c)), \ - (I[240] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[269] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[298] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[327] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[356] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[385] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[414] = (T)(img)(_p6##x,y,z,c)), \ - (I[443] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[472] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[501] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[530] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[559] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[588] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[617] = (T)(img)(_p6##x,_n7##y,z,c)), \ - (I[646] = (T)(img)(_p6##x,_n8##y,z,c)), \ - (I[675] = (T)(img)(_p6##x,_n9##y,z,c)), \ - (I[704] = (T)(img)(_p6##x,_n10##y,z,c)), \ - (I[733] = (T)(img)(_p6##x,_n11##y,z,c)), \ - (I[762] = (T)(img)(_p6##x,_n12##y,z,c)), \ - (I[791] = (T)(img)(_p6##x,_n13##y,z,c)), \ - (I[820] = (T)(img)(_p6##x,_n14##y,z,c)), \ - (I[9] = (T)(img)(_p5##x,_p14##y,z,c)), \ - (I[38] = (T)(img)(_p5##x,_p13##y,z,c)), \ - (I[67] = (T)(img)(_p5##x,_p12##y,z,c)), \ - (I[96] = (T)(img)(_p5##x,_p11##y,z,c)), \ - (I[125] = (T)(img)(_p5##x,_p10##y,z,c)), \ - (I[154] = (T)(img)(_p5##x,_p9##y,z,c)), \ - (I[183] = (T)(img)(_p5##x,_p8##y,z,c)), \ - (I[212] = (T)(img)(_p5##x,_p7##y,z,c)), \ - (I[241] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[270] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[299] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[328] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[357] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[386] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[415] = (T)(img)(_p5##x,y,z,c)), \ - (I[444] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[473] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[502] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[531] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[560] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[589] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[618] = (T)(img)(_p5##x,_n7##y,z,c)), \ - (I[647] = (T)(img)(_p5##x,_n8##y,z,c)), \ - (I[676] = (T)(img)(_p5##x,_n9##y,z,c)), \ - (I[705] = (T)(img)(_p5##x,_n10##y,z,c)), \ - (I[734] = (T)(img)(_p5##x,_n11##y,z,c)), \ - (I[763] = (T)(img)(_p5##x,_n12##y,z,c)), \ - (I[792] = (T)(img)(_p5##x,_n13##y,z,c)), \ - (I[821] = (T)(img)(_p5##x,_n14##y,z,c)), \ - (I[10] = (T)(img)(_p4##x,_p14##y,z,c)), \ - (I[39] = (T)(img)(_p4##x,_p13##y,z,c)), \ - (I[68] = (T)(img)(_p4##x,_p12##y,z,c)), \ - (I[97] = (T)(img)(_p4##x,_p11##y,z,c)), \ - (I[126] = (T)(img)(_p4##x,_p10##y,z,c)), \ - (I[155] = (T)(img)(_p4##x,_p9##y,z,c)), \ - (I[184] = (T)(img)(_p4##x,_p8##y,z,c)), \ - (I[213] = (T)(img)(_p4##x,_p7##y,z,c)), \ - (I[242] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[271] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[300] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[329] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[358] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[387] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[416] = (T)(img)(_p4##x,y,z,c)), \ - (I[445] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[474] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[503] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[532] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[561] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[590] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[619] = (T)(img)(_p4##x,_n7##y,z,c)), \ - (I[648] = (T)(img)(_p4##x,_n8##y,z,c)), \ - (I[677] = (T)(img)(_p4##x,_n9##y,z,c)), \ - (I[706] = (T)(img)(_p4##x,_n10##y,z,c)), \ - (I[735] = (T)(img)(_p4##x,_n11##y,z,c)), \ - (I[764] = (T)(img)(_p4##x,_n12##y,z,c)), \ - (I[793] = (T)(img)(_p4##x,_n13##y,z,c)), \ - (I[822] = (T)(img)(_p4##x,_n14##y,z,c)), \ - (I[11] = (T)(img)(_p3##x,_p14##y,z,c)), \ - (I[40] = (T)(img)(_p3##x,_p13##y,z,c)), \ - (I[69] = (T)(img)(_p3##x,_p12##y,z,c)), \ - (I[98] = (T)(img)(_p3##x,_p11##y,z,c)), \ - (I[127] = (T)(img)(_p3##x,_p10##y,z,c)), \ - (I[156] = (T)(img)(_p3##x,_p9##y,z,c)), \ - (I[185] = (T)(img)(_p3##x,_p8##y,z,c)), \ - (I[214] = (T)(img)(_p3##x,_p7##y,z,c)), \ - (I[243] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[272] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[301] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[330] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[359] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[388] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[417] = (T)(img)(_p3##x,y,z,c)), \ - (I[446] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[475] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[504] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[533] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[562] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[591] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[620] = (T)(img)(_p3##x,_n7##y,z,c)), \ - (I[649] = (T)(img)(_p3##x,_n8##y,z,c)), \ - (I[678] = (T)(img)(_p3##x,_n9##y,z,c)), \ - (I[707] = (T)(img)(_p3##x,_n10##y,z,c)), \ - (I[736] = (T)(img)(_p3##x,_n11##y,z,c)), \ - (I[765] = (T)(img)(_p3##x,_n12##y,z,c)), \ - (I[794] = (T)(img)(_p3##x,_n13##y,z,c)), \ - (I[823] = (T)(img)(_p3##x,_n14##y,z,c)), \ - (I[12] = (T)(img)(_p2##x,_p14##y,z,c)), \ - (I[41] = (T)(img)(_p2##x,_p13##y,z,c)), \ - (I[70] = (T)(img)(_p2##x,_p12##y,z,c)), \ - (I[99] = (T)(img)(_p2##x,_p11##y,z,c)), \ - (I[128] = (T)(img)(_p2##x,_p10##y,z,c)), \ - (I[157] = (T)(img)(_p2##x,_p9##y,z,c)), \ - (I[186] = (T)(img)(_p2##x,_p8##y,z,c)), \ - (I[215] = (T)(img)(_p2##x,_p7##y,z,c)), \ - (I[244] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[273] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[302] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[331] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[360] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[389] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[418] = (T)(img)(_p2##x,y,z,c)), \ - (I[447] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[476] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[505] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[534] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[563] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[592] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[621] = (T)(img)(_p2##x,_n7##y,z,c)), \ - (I[650] = (T)(img)(_p2##x,_n8##y,z,c)), \ - (I[679] = (T)(img)(_p2##x,_n9##y,z,c)), \ - (I[708] = (T)(img)(_p2##x,_n10##y,z,c)), \ - (I[737] = (T)(img)(_p2##x,_n11##y,z,c)), \ - (I[766] = (T)(img)(_p2##x,_n12##y,z,c)), \ - (I[795] = (T)(img)(_p2##x,_n13##y,z,c)), \ - (I[824] = (T)(img)(_p2##x,_n14##y,z,c)), \ - (I[13] = (T)(img)(_p1##x,_p14##y,z,c)), \ - (I[42] = (T)(img)(_p1##x,_p13##y,z,c)), \ - (I[71] = (T)(img)(_p1##x,_p12##y,z,c)), \ - (I[100] = (T)(img)(_p1##x,_p11##y,z,c)), \ - (I[129] = (T)(img)(_p1##x,_p10##y,z,c)), \ - (I[158] = (T)(img)(_p1##x,_p9##y,z,c)), \ - (I[187] = (T)(img)(_p1##x,_p8##y,z,c)), \ - (I[216] = (T)(img)(_p1##x,_p7##y,z,c)), \ - (I[245] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[274] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[303] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[332] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[361] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[390] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[419] = (T)(img)(_p1##x,y,z,c)), \ - (I[448] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[477] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[506] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[535] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[564] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[593] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[622] = (T)(img)(_p1##x,_n7##y,z,c)), \ - (I[651] = (T)(img)(_p1##x,_n8##y,z,c)), \ - (I[680] = (T)(img)(_p1##x,_n9##y,z,c)), \ - (I[709] = (T)(img)(_p1##x,_n10##y,z,c)), \ - (I[738] = (T)(img)(_p1##x,_n11##y,z,c)), \ - (I[767] = (T)(img)(_p1##x,_n12##y,z,c)), \ - (I[796] = (T)(img)(_p1##x,_n13##y,z,c)), \ - (I[825] = (T)(img)(_p1##x,_n14##y,z,c)), \ - (I[14] = (T)(img)(x,_p14##y,z,c)), \ - (I[43] = (T)(img)(x,_p13##y,z,c)), \ - (I[72] = (T)(img)(x,_p12##y,z,c)), \ - (I[101] = (T)(img)(x,_p11##y,z,c)), \ - (I[130] = (T)(img)(x,_p10##y,z,c)), \ - (I[159] = (T)(img)(x,_p9##y,z,c)), \ - (I[188] = (T)(img)(x,_p8##y,z,c)), \ - (I[217] = (T)(img)(x,_p7##y,z,c)), \ - (I[246] = (T)(img)(x,_p6##y,z,c)), \ - (I[275] = (T)(img)(x,_p5##y,z,c)), \ - (I[304] = (T)(img)(x,_p4##y,z,c)), \ - (I[333] = (T)(img)(x,_p3##y,z,c)), \ - (I[362] = (T)(img)(x,_p2##y,z,c)), \ - (I[391] = (T)(img)(x,_p1##y,z,c)), \ - (I[420] = (T)(img)(x,y,z,c)), \ - (I[449] = (T)(img)(x,_n1##y,z,c)), \ - (I[478] = (T)(img)(x,_n2##y,z,c)), \ - (I[507] = (T)(img)(x,_n3##y,z,c)), \ - (I[536] = (T)(img)(x,_n4##y,z,c)), \ - (I[565] = (T)(img)(x,_n5##y,z,c)), \ - (I[594] = (T)(img)(x,_n6##y,z,c)), \ - (I[623] = (T)(img)(x,_n7##y,z,c)), \ - (I[652] = (T)(img)(x,_n8##y,z,c)), \ - (I[681] = (T)(img)(x,_n9##y,z,c)), \ - (I[710] = (T)(img)(x,_n10##y,z,c)), \ - (I[739] = (T)(img)(x,_n11##y,z,c)), \ - (I[768] = (T)(img)(x,_n12##y,z,c)), \ - (I[797] = (T)(img)(x,_n13##y,z,c)), \ - (I[826] = (T)(img)(x,_n14##y,z,c)), \ - (I[15] = (T)(img)(_n1##x,_p14##y,z,c)), \ - (I[44] = (T)(img)(_n1##x,_p13##y,z,c)), \ - (I[73] = (T)(img)(_n1##x,_p12##y,z,c)), \ - (I[102] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[131] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[160] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[189] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[218] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[247] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[276] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[305] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[334] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[363] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[392] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[421] = (T)(img)(_n1##x,y,z,c)), \ - (I[450] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[479] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[508] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[537] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[566] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[595] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[624] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[653] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[682] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[711] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[740] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[769] = (T)(img)(_n1##x,_n12##y,z,c)), \ - (I[798] = (T)(img)(_n1##x,_n13##y,z,c)), \ - (I[827] = (T)(img)(_n1##x,_n14##y,z,c)), \ - (I[16] = (T)(img)(_n2##x,_p14##y,z,c)), \ - (I[45] = (T)(img)(_n2##x,_p13##y,z,c)), \ - (I[74] = (T)(img)(_n2##x,_p12##y,z,c)), \ - (I[103] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[132] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[161] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[190] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[219] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[248] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[277] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[306] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[335] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[364] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[393] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[422] = (T)(img)(_n2##x,y,z,c)), \ - (I[451] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[480] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[509] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[538] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[567] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[596] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[625] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[654] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[683] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[712] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[741] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[770] = (T)(img)(_n2##x,_n12##y,z,c)), \ - (I[799] = (T)(img)(_n2##x,_n13##y,z,c)), \ - (I[828] = (T)(img)(_n2##x,_n14##y,z,c)), \ - (I[17] = (T)(img)(_n3##x,_p14##y,z,c)), \ - (I[46] = (T)(img)(_n3##x,_p13##y,z,c)), \ - (I[75] = (T)(img)(_n3##x,_p12##y,z,c)), \ - (I[104] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[133] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[162] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[191] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[220] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[249] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[278] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[307] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[336] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[365] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[394] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[423] = (T)(img)(_n3##x,y,z,c)), \ - (I[452] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[481] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[510] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[539] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[568] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[597] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[626] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[655] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[684] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[713] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[742] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[771] = (T)(img)(_n3##x,_n12##y,z,c)), \ - (I[800] = (T)(img)(_n3##x,_n13##y,z,c)), \ - (I[829] = (T)(img)(_n3##x,_n14##y,z,c)), \ - (I[18] = (T)(img)(_n4##x,_p14##y,z,c)), \ - (I[47] = (T)(img)(_n4##x,_p13##y,z,c)), \ - (I[76] = (T)(img)(_n4##x,_p12##y,z,c)), \ - (I[105] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[134] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[163] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[192] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[221] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[250] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[279] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[308] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[337] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[366] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[395] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[424] = (T)(img)(_n4##x,y,z,c)), \ - (I[453] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[482] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[511] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[540] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[569] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[598] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[627] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[656] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[685] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[714] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[743] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[772] = (T)(img)(_n4##x,_n12##y,z,c)), \ - (I[801] = (T)(img)(_n4##x,_n13##y,z,c)), \ - (I[830] = (T)(img)(_n4##x,_n14##y,z,c)), \ - (I[19] = (T)(img)(_n5##x,_p14##y,z,c)), \ - (I[48] = (T)(img)(_n5##x,_p13##y,z,c)), \ - (I[77] = (T)(img)(_n5##x,_p12##y,z,c)), \ - (I[106] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[135] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[164] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[193] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[222] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[251] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[280] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[309] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[338] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[367] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[396] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[425] = (T)(img)(_n5##x,y,z,c)), \ - (I[454] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[483] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[512] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[541] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[570] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[599] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[628] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[657] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[686] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[715] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[744] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[773] = (T)(img)(_n5##x,_n12##y,z,c)), \ - (I[802] = (T)(img)(_n5##x,_n13##y,z,c)), \ - (I[831] = (T)(img)(_n5##x,_n14##y,z,c)), \ - (I[20] = (T)(img)(_n6##x,_p14##y,z,c)), \ - (I[49] = (T)(img)(_n6##x,_p13##y,z,c)), \ - (I[78] = (T)(img)(_n6##x,_p12##y,z,c)), \ - (I[107] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[136] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[165] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[194] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[223] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[252] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[281] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[310] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[339] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[368] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[397] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[426] = (T)(img)(_n6##x,y,z,c)), \ - (I[455] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[484] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[513] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[542] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[571] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[600] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[629] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[658] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[687] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[716] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[745] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[774] = (T)(img)(_n6##x,_n12##y,z,c)), \ - (I[803] = (T)(img)(_n6##x,_n13##y,z,c)), \ - (I[832] = (T)(img)(_n6##x,_n14##y,z,c)), \ - (I[21] = (T)(img)(_n7##x,_p14##y,z,c)), \ - (I[50] = (T)(img)(_n7##x,_p13##y,z,c)), \ - (I[79] = (T)(img)(_n7##x,_p12##y,z,c)), \ - (I[108] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[137] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[166] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[195] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[224] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[253] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[282] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[311] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[340] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[369] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[398] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[427] = (T)(img)(_n7##x,y,z,c)), \ - (I[456] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[485] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[514] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[543] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[572] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[601] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[630] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[659] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[688] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[717] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[746] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[775] = (T)(img)(_n7##x,_n12##y,z,c)), \ - (I[804] = (T)(img)(_n7##x,_n13##y,z,c)), \ - (I[833] = (T)(img)(_n7##x,_n14##y,z,c)), \ - (I[22] = (T)(img)(_n8##x,_p14##y,z,c)), \ - (I[51] = (T)(img)(_n8##x,_p13##y,z,c)), \ - (I[80] = (T)(img)(_n8##x,_p12##y,z,c)), \ - (I[109] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[138] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[167] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[196] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[225] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[254] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[283] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[312] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[341] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[370] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[399] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[428] = (T)(img)(_n8##x,y,z,c)), \ - (I[457] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[486] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[515] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[544] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[573] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[602] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[631] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[660] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[689] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[718] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[747] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[776] = (T)(img)(_n8##x,_n12##y,z,c)), \ - (I[805] = (T)(img)(_n8##x,_n13##y,z,c)), \ - (I[834] = (T)(img)(_n8##x,_n14##y,z,c)), \ - (I[23] = (T)(img)(_n9##x,_p14##y,z,c)), \ - (I[52] = (T)(img)(_n9##x,_p13##y,z,c)), \ - (I[81] = (T)(img)(_n9##x,_p12##y,z,c)), \ - (I[110] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[139] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[168] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[197] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[226] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[255] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[284] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[313] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[342] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[371] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[400] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[429] = (T)(img)(_n9##x,y,z,c)), \ - (I[458] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[487] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[516] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[545] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[574] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[603] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[632] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[661] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[690] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[719] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[748] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[777] = (T)(img)(_n9##x,_n12##y,z,c)), \ - (I[806] = (T)(img)(_n9##x,_n13##y,z,c)), \ - (I[835] = (T)(img)(_n9##x,_n14##y,z,c)), \ - (I[24] = (T)(img)(_n10##x,_p14##y,z,c)), \ - (I[53] = (T)(img)(_n10##x,_p13##y,z,c)), \ - (I[82] = (T)(img)(_n10##x,_p12##y,z,c)), \ - (I[111] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[140] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[169] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[198] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[227] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[256] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[285] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[314] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[343] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[372] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[401] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[430] = (T)(img)(_n10##x,y,z,c)), \ - (I[459] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[488] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[517] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[546] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[575] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[604] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[633] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[662] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[691] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[720] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[749] = (T)(img)(_n10##x,_n11##y,z,c)), \ - (I[778] = (T)(img)(_n10##x,_n12##y,z,c)), \ - (I[807] = (T)(img)(_n10##x,_n13##y,z,c)), \ - (I[836] = (T)(img)(_n10##x,_n14##y,z,c)), \ - (I[25] = (T)(img)(_n11##x,_p14##y,z,c)), \ - (I[54] = (T)(img)(_n11##x,_p13##y,z,c)), \ - (I[83] = (T)(img)(_n11##x,_p12##y,z,c)), \ - (I[112] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[141] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[170] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[199] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[228] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[257] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[286] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[315] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[344] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[373] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[402] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[431] = (T)(img)(_n11##x,y,z,c)), \ - (I[460] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[489] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[518] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[547] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[576] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[605] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[634] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[663] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[692] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[721] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[750] = (T)(img)(_n11##x,_n11##y,z,c)), \ - (I[779] = (T)(img)(_n11##x,_n12##y,z,c)), \ - (I[808] = (T)(img)(_n11##x,_n13##y,z,c)), \ - (I[837] = (T)(img)(_n11##x,_n14##y,z,c)), \ - (I[26] = (T)(img)(_n12##x,_p14##y,z,c)), \ - (I[55] = (T)(img)(_n12##x,_p13##y,z,c)), \ - (I[84] = (T)(img)(_n12##x,_p12##y,z,c)), \ - (I[113] = (T)(img)(_n12##x,_p11##y,z,c)), \ - (I[142] = (T)(img)(_n12##x,_p10##y,z,c)), \ - (I[171] = (T)(img)(_n12##x,_p9##y,z,c)), \ - (I[200] = (T)(img)(_n12##x,_p8##y,z,c)), \ - (I[229] = (T)(img)(_n12##x,_p7##y,z,c)), \ - (I[258] = (T)(img)(_n12##x,_p6##y,z,c)), \ - (I[287] = (T)(img)(_n12##x,_p5##y,z,c)), \ - (I[316] = (T)(img)(_n12##x,_p4##y,z,c)), \ - (I[345] = (T)(img)(_n12##x,_p3##y,z,c)), \ - (I[374] = (T)(img)(_n12##x,_p2##y,z,c)), \ - (I[403] = (T)(img)(_n12##x,_p1##y,z,c)), \ - (I[432] = (T)(img)(_n12##x,y,z,c)), \ - (I[461] = (T)(img)(_n12##x,_n1##y,z,c)), \ - (I[490] = (T)(img)(_n12##x,_n2##y,z,c)), \ - (I[519] = (T)(img)(_n12##x,_n3##y,z,c)), \ - (I[548] = (T)(img)(_n12##x,_n4##y,z,c)), \ - (I[577] = (T)(img)(_n12##x,_n5##y,z,c)), \ - (I[606] = (T)(img)(_n12##x,_n6##y,z,c)), \ - (I[635] = (T)(img)(_n12##x,_n7##y,z,c)), \ - (I[664] = (T)(img)(_n12##x,_n8##y,z,c)), \ - (I[693] = (T)(img)(_n12##x,_n9##y,z,c)), \ - (I[722] = (T)(img)(_n12##x,_n10##y,z,c)), \ - (I[751] = (T)(img)(_n12##x,_n11##y,z,c)), \ - (I[780] = (T)(img)(_n12##x,_n12##y,z,c)), \ - (I[809] = (T)(img)(_n12##x,_n13##y,z,c)), \ - (I[838] = (T)(img)(_n12##x,_n14##y,z,c)), \ - (I[27] = (T)(img)(_n13##x,_p14##y,z,c)), \ - (I[56] = (T)(img)(_n13##x,_p13##y,z,c)), \ - (I[85] = (T)(img)(_n13##x,_p12##y,z,c)), \ - (I[114] = (T)(img)(_n13##x,_p11##y,z,c)), \ - (I[143] = (T)(img)(_n13##x,_p10##y,z,c)), \ - (I[172] = (T)(img)(_n13##x,_p9##y,z,c)), \ - (I[201] = (T)(img)(_n13##x,_p8##y,z,c)), \ - (I[230] = (T)(img)(_n13##x,_p7##y,z,c)), \ - (I[259] = (T)(img)(_n13##x,_p6##y,z,c)), \ - (I[288] = (T)(img)(_n13##x,_p5##y,z,c)), \ - (I[317] = (T)(img)(_n13##x,_p4##y,z,c)), \ - (I[346] = (T)(img)(_n13##x,_p3##y,z,c)), \ - (I[375] = (T)(img)(_n13##x,_p2##y,z,c)), \ - (I[404] = (T)(img)(_n13##x,_p1##y,z,c)), \ - (I[433] = (T)(img)(_n13##x,y,z,c)), \ - (I[462] = (T)(img)(_n13##x,_n1##y,z,c)), \ - (I[491] = (T)(img)(_n13##x,_n2##y,z,c)), \ - (I[520] = (T)(img)(_n13##x,_n3##y,z,c)), \ - (I[549] = (T)(img)(_n13##x,_n4##y,z,c)), \ - (I[578] = (T)(img)(_n13##x,_n5##y,z,c)), \ - (I[607] = (T)(img)(_n13##x,_n6##y,z,c)), \ - (I[636] = (T)(img)(_n13##x,_n7##y,z,c)), \ - (I[665] = (T)(img)(_n13##x,_n8##y,z,c)), \ - (I[694] = (T)(img)(_n13##x,_n9##y,z,c)), \ - (I[723] = (T)(img)(_n13##x,_n10##y,z,c)), \ - (I[752] = (T)(img)(_n13##x,_n11##y,z,c)), \ - (I[781] = (T)(img)(_n13##x,_n12##y,z,c)), \ - (I[810] = (T)(img)(_n13##x,_n13##y,z,c)), \ - (I[839] = (T)(img)(_n13##x,_n14##y,z,c)), \ - x + 14>=(img).width()?(img).width() - 1:x + 14); \ - x<=(int)(x1) && ((_n14##x<(img).width() && ( \ - (I[28] = (T)(img)(_n14##x,_p14##y,z,c)), \ - (I[57] = (T)(img)(_n14##x,_p13##y,z,c)), \ - (I[86] = (T)(img)(_n14##x,_p12##y,z,c)), \ - (I[115] = (T)(img)(_n14##x,_p11##y,z,c)), \ - (I[144] = (T)(img)(_n14##x,_p10##y,z,c)), \ - (I[173] = (T)(img)(_n14##x,_p9##y,z,c)), \ - (I[202] = (T)(img)(_n14##x,_p8##y,z,c)), \ - (I[231] = (T)(img)(_n14##x,_p7##y,z,c)), \ - (I[260] = (T)(img)(_n14##x,_p6##y,z,c)), \ - (I[289] = (T)(img)(_n14##x,_p5##y,z,c)), \ - (I[318] = (T)(img)(_n14##x,_p4##y,z,c)), \ - (I[347] = (T)(img)(_n14##x,_p3##y,z,c)), \ - (I[376] = (T)(img)(_n14##x,_p2##y,z,c)), \ - (I[405] = (T)(img)(_n14##x,_p1##y,z,c)), \ - (I[434] = (T)(img)(_n14##x,y,z,c)), \ - (I[463] = (T)(img)(_n14##x,_n1##y,z,c)), \ - (I[492] = (T)(img)(_n14##x,_n2##y,z,c)), \ - (I[521] = (T)(img)(_n14##x,_n3##y,z,c)), \ - (I[550] = (T)(img)(_n14##x,_n4##y,z,c)), \ - (I[579] = (T)(img)(_n14##x,_n5##y,z,c)), \ - (I[608] = (T)(img)(_n14##x,_n6##y,z,c)), \ - (I[637] = (T)(img)(_n14##x,_n7##y,z,c)), \ - (I[666] = (T)(img)(_n14##x,_n8##y,z,c)), \ - (I[695] = (T)(img)(_n14##x,_n9##y,z,c)), \ - (I[724] = (T)(img)(_n14##x,_n10##y,z,c)), \ - (I[753] = (T)(img)(_n14##x,_n11##y,z,c)), \ - (I[782] = (T)(img)(_n14##x,_n12##y,z,c)), \ - (I[811] = (T)(img)(_n14##x,_n13##y,z,c)), \ - (I[840] = (T)(img)(_n14##x,_n14##y,z,c)),1)) || \ - _n13##x==--_n14##x || _n12##x==--_n13##x || _n11##x==--_n12##x || _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n14##x = _n13##x = _n12##x = _n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], \ - I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], \ - I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], \ - I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], \ - I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], \ - I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], \ - I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], \ - I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], \ - I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], \ - I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], \ - I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], \ - I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], \ - I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], \ - I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], \ - I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], I[415] = I[416], I[416] = I[417], I[417] = I[418], I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], I[433] = I[434], \ - I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], I[447] = I[448], I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], \ - I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], I[479] = I[480], I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], \ - I[493] = I[494], I[494] = I[495], I[495] = I[496], I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], I[503] = I[504], I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], I[511] = I[512], I[512] = I[513], I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], I[519] = I[520], I[520] = I[521], \ - I[522] = I[523], I[523] = I[524], I[524] = I[525], I[525] = I[526], I[526] = I[527], I[527] = I[528], I[528] = I[529], I[529] = I[530], I[530] = I[531], I[531] = I[532], I[532] = I[533], I[533] = I[534], I[534] = I[535], I[535] = I[536], I[536] = I[537], I[537] = I[538], I[538] = I[539], I[539] = I[540], I[540] = I[541], I[541] = I[542], I[542] = I[543], I[543] = I[544], I[544] = I[545], I[545] = I[546], I[546] = I[547], I[547] = I[548], I[548] = I[549], I[549] = I[550], \ - I[551] = I[552], I[552] = I[553], I[553] = I[554], I[554] = I[555], I[555] = I[556], I[556] = I[557], I[557] = I[558], I[558] = I[559], I[559] = I[560], I[560] = I[561], I[561] = I[562], I[562] = I[563], I[563] = I[564], I[564] = I[565], I[565] = I[566], I[566] = I[567], I[567] = I[568], I[568] = I[569], I[569] = I[570], I[570] = I[571], I[571] = I[572], I[572] = I[573], I[573] = I[574], I[574] = I[575], I[575] = I[576], I[576] = I[577], I[577] = I[578], I[578] = I[579], \ - I[580] = I[581], I[581] = I[582], I[582] = I[583], I[583] = I[584], I[584] = I[585], I[585] = I[586], I[586] = I[587], I[587] = I[588], I[588] = I[589], I[589] = I[590], I[590] = I[591], I[591] = I[592], I[592] = I[593], I[593] = I[594], I[594] = I[595], I[595] = I[596], I[596] = I[597], I[597] = I[598], I[598] = I[599], I[599] = I[600], I[600] = I[601], I[601] = I[602], I[602] = I[603], I[603] = I[604], I[604] = I[605], I[605] = I[606], I[606] = I[607], I[607] = I[608], \ - I[609] = I[610], I[610] = I[611], I[611] = I[612], I[612] = I[613], I[613] = I[614], I[614] = I[615], I[615] = I[616], I[616] = I[617], I[617] = I[618], I[618] = I[619], I[619] = I[620], I[620] = I[621], I[621] = I[622], I[622] = I[623], I[623] = I[624], I[624] = I[625], I[625] = I[626], I[626] = I[627], I[627] = I[628], I[628] = I[629], I[629] = I[630], I[630] = I[631], I[631] = I[632], I[632] = I[633], I[633] = I[634], I[634] = I[635], I[635] = I[636], I[636] = I[637], \ - I[638] = I[639], I[639] = I[640], I[640] = I[641], I[641] = I[642], I[642] = I[643], I[643] = I[644], I[644] = I[645], I[645] = I[646], I[646] = I[647], I[647] = I[648], I[648] = I[649], I[649] = I[650], I[650] = I[651], I[651] = I[652], I[652] = I[653], I[653] = I[654], I[654] = I[655], I[655] = I[656], I[656] = I[657], I[657] = I[658], I[658] = I[659], I[659] = I[660], I[660] = I[661], I[661] = I[662], I[662] = I[663], I[663] = I[664], I[664] = I[665], I[665] = I[666], \ - I[667] = I[668], I[668] = I[669], I[669] = I[670], I[670] = I[671], I[671] = I[672], I[672] = I[673], I[673] = I[674], I[674] = I[675], I[675] = I[676], I[676] = I[677], I[677] = I[678], I[678] = I[679], I[679] = I[680], I[680] = I[681], I[681] = I[682], I[682] = I[683], I[683] = I[684], I[684] = I[685], I[685] = I[686], I[686] = I[687], I[687] = I[688], I[688] = I[689], I[689] = I[690], I[690] = I[691], I[691] = I[692], I[692] = I[693], I[693] = I[694], I[694] = I[695], \ - I[696] = I[697], I[697] = I[698], I[698] = I[699], I[699] = I[700], I[700] = I[701], I[701] = I[702], I[702] = I[703], I[703] = I[704], I[704] = I[705], I[705] = I[706], I[706] = I[707], I[707] = I[708], I[708] = I[709], I[709] = I[710], I[710] = I[711], I[711] = I[712], I[712] = I[713], I[713] = I[714], I[714] = I[715], I[715] = I[716], I[716] = I[717], I[717] = I[718], I[718] = I[719], I[719] = I[720], I[720] = I[721], I[721] = I[722], I[722] = I[723], I[723] = I[724], \ - I[725] = I[726], I[726] = I[727], I[727] = I[728], I[728] = I[729], I[729] = I[730], I[730] = I[731], I[731] = I[732], I[732] = I[733], I[733] = I[734], I[734] = I[735], I[735] = I[736], I[736] = I[737], I[737] = I[738], I[738] = I[739], I[739] = I[740], I[740] = I[741], I[741] = I[742], I[742] = I[743], I[743] = I[744], I[744] = I[745], I[745] = I[746], I[746] = I[747], I[747] = I[748], I[748] = I[749], I[749] = I[750], I[750] = I[751], I[751] = I[752], I[752] = I[753], \ - I[754] = I[755], I[755] = I[756], I[756] = I[757], I[757] = I[758], I[758] = I[759], I[759] = I[760], I[760] = I[761], I[761] = I[762], I[762] = I[763], I[763] = I[764], I[764] = I[765], I[765] = I[766], I[766] = I[767], I[767] = I[768], I[768] = I[769], I[769] = I[770], I[770] = I[771], I[771] = I[772], I[772] = I[773], I[773] = I[774], I[774] = I[775], I[775] = I[776], I[776] = I[777], I[777] = I[778], I[778] = I[779], I[779] = I[780], I[780] = I[781], I[781] = I[782], \ - I[783] = I[784], I[784] = I[785], I[785] = I[786], I[786] = I[787], I[787] = I[788], I[788] = I[789], I[789] = I[790], I[790] = I[791], I[791] = I[792], I[792] = I[793], I[793] = I[794], I[794] = I[795], I[795] = I[796], I[796] = I[797], I[797] = I[798], I[798] = I[799], I[799] = I[800], I[800] = I[801], I[801] = I[802], I[802] = I[803], I[803] = I[804], I[804] = I[805], I[805] = I[806], I[806] = I[807], I[807] = I[808], I[808] = I[809], I[809] = I[810], I[810] = I[811], \ - I[812] = I[813], I[813] = I[814], I[814] = I[815], I[815] = I[816], I[816] = I[817], I[817] = I[818], I[818] = I[819], I[819] = I[820], I[820] = I[821], I[821] = I[822], I[822] = I[823], I[823] = I[824], I[824] = I[825], I[825] = I[826], I[826] = I[827], I[827] = I[828], I[828] = I[829], I[829] = I[830], I[830] = I[831], I[831] = I[832], I[832] = I[833], I[833] = I[834], I[834] = I[835], I[835] = I[836], I[836] = I[837], I[837] = I[838], I[838] = I[839], I[839] = I[840], \ - _p14##x = _p13##x, _p13##x = _p12##x, _p12##x = _p11##x, _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x, ++_n12##x, ++_n13##x, ++_n14##x) - -#define cimg_get29x29(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p14##x,_p14##y,z,c), I[1] = (T)(img)(_p13##x,_p14##y,z,c), I[2] = (T)(img)(_p12##x,_p14##y,z,c), I[3] = (T)(img)(_p11##x,_p14##y,z,c), I[4] = (T)(img)(_p10##x,_p14##y,z,c), I[5] = (T)(img)(_p9##x,_p14##y,z,c), I[6] = (T)(img)(_p8##x,_p14##y,z,c), I[7] = (T)(img)(_p7##x,_p14##y,z,c), I[8] = (T)(img)(_p6##x,_p14##y,z,c), I[9] = (T)(img)(_p5##x,_p14##y,z,c), I[10] = (T)(img)(_p4##x,_p14##y,z,c), I[11] = (T)(img)(_p3##x,_p14##y,z,c), I[12] = (T)(img)(_p2##x,_p14##y,z,c), I[13] = (T)(img)(_p1##x,_p14##y,z,c), I[14] = (T)(img)(x,_p14##y,z,c), I[15] = (T)(img)(_n1##x,_p14##y,z,c), I[16] = (T)(img)(_n2##x,_p14##y,z,c), I[17] = (T)(img)(_n3##x,_p14##y,z,c), I[18] = (T)(img)(_n4##x,_p14##y,z,c), I[19] = (T)(img)(_n5##x,_p14##y,z,c), I[20] = (T)(img)(_n6##x,_p14##y,z,c), I[21] = (T)(img)(_n7##x,_p14##y,z,c), I[22] = (T)(img)(_n8##x,_p14##y,z,c), I[23] = (T)(img)(_n9##x,_p14##y,z,c), I[24] = (T)(img)(_n10##x,_p14##y,z,c), I[25] = (T)(img)(_n11##x,_p14##y,z,c), I[26] = (T)(img)(_n12##x,_p14##y,z,c), I[27] = (T)(img)(_n13##x,_p14##y,z,c), I[28] = (T)(img)(_n14##x,_p14##y,z,c), \ - I[29] = (T)(img)(_p14##x,_p13##y,z,c), I[30] = (T)(img)(_p13##x,_p13##y,z,c), I[31] = (T)(img)(_p12##x,_p13##y,z,c), I[32] = (T)(img)(_p11##x,_p13##y,z,c), I[33] = (T)(img)(_p10##x,_p13##y,z,c), I[34] = (T)(img)(_p9##x,_p13##y,z,c), I[35] = (T)(img)(_p8##x,_p13##y,z,c), I[36] = (T)(img)(_p7##x,_p13##y,z,c), I[37] = (T)(img)(_p6##x,_p13##y,z,c), I[38] = (T)(img)(_p5##x,_p13##y,z,c), I[39] = (T)(img)(_p4##x,_p13##y,z,c), I[40] = (T)(img)(_p3##x,_p13##y,z,c), I[41] = (T)(img)(_p2##x,_p13##y,z,c), I[42] = (T)(img)(_p1##x,_p13##y,z,c), I[43] = (T)(img)(x,_p13##y,z,c), I[44] = (T)(img)(_n1##x,_p13##y,z,c), I[45] = (T)(img)(_n2##x,_p13##y,z,c), I[46] = (T)(img)(_n3##x,_p13##y,z,c), I[47] = (T)(img)(_n4##x,_p13##y,z,c), I[48] = (T)(img)(_n5##x,_p13##y,z,c), I[49] = (T)(img)(_n6##x,_p13##y,z,c), I[50] = (T)(img)(_n7##x,_p13##y,z,c), I[51] = (T)(img)(_n8##x,_p13##y,z,c), I[52] = (T)(img)(_n9##x,_p13##y,z,c), I[53] = (T)(img)(_n10##x,_p13##y,z,c), I[54] = (T)(img)(_n11##x,_p13##y,z,c), I[55] = (T)(img)(_n12##x,_p13##y,z,c), I[56] = (T)(img)(_n13##x,_p13##y,z,c), I[57] = (T)(img)(_n14##x,_p13##y,z,c), \ - I[58] = (T)(img)(_p14##x,_p12##y,z,c), I[59] = (T)(img)(_p13##x,_p12##y,z,c), I[60] = (T)(img)(_p12##x,_p12##y,z,c), I[61] = (T)(img)(_p11##x,_p12##y,z,c), I[62] = (T)(img)(_p10##x,_p12##y,z,c), I[63] = (T)(img)(_p9##x,_p12##y,z,c), I[64] = (T)(img)(_p8##x,_p12##y,z,c), I[65] = (T)(img)(_p7##x,_p12##y,z,c), I[66] = (T)(img)(_p6##x,_p12##y,z,c), I[67] = (T)(img)(_p5##x,_p12##y,z,c), I[68] = (T)(img)(_p4##x,_p12##y,z,c), I[69] = (T)(img)(_p3##x,_p12##y,z,c), I[70] = (T)(img)(_p2##x,_p12##y,z,c), I[71] = (T)(img)(_p1##x,_p12##y,z,c), I[72] = (T)(img)(x,_p12##y,z,c), I[73] = (T)(img)(_n1##x,_p12##y,z,c), I[74] = (T)(img)(_n2##x,_p12##y,z,c), I[75] = (T)(img)(_n3##x,_p12##y,z,c), I[76] = (T)(img)(_n4##x,_p12##y,z,c), I[77] = (T)(img)(_n5##x,_p12##y,z,c), I[78] = (T)(img)(_n6##x,_p12##y,z,c), I[79] = (T)(img)(_n7##x,_p12##y,z,c), I[80] = (T)(img)(_n8##x,_p12##y,z,c), I[81] = (T)(img)(_n9##x,_p12##y,z,c), I[82] = (T)(img)(_n10##x,_p12##y,z,c), I[83] = (T)(img)(_n11##x,_p12##y,z,c), I[84] = (T)(img)(_n12##x,_p12##y,z,c), I[85] = (T)(img)(_n13##x,_p12##y,z,c), I[86] = (T)(img)(_n14##x,_p12##y,z,c), \ - I[87] = (T)(img)(_p14##x,_p11##y,z,c), I[88] = (T)(img)(_p13##x,_p11##y,z,c), I[89] = (T)(img)(_p12##x,_p11##y,z,c), I[90] = (T)(img)(_p11##x,_p11##y,z,c), I[91] = (T)(img)(_p10##x,_p11##y,z,c), I[92] = (T)(img)(_p9##x,_p11##y,z,c), I[93] = (T)(img)(_p8##x,_p11##y,z,c), I[94] = (T)(img)(_p7##x,_p11##y,z,c), I[95] = (T)(img)(_p6##x,_p11##y,z,c), I[96] = (T)(img)(_p5##x,_p11##y,z,c), I[97] = (T)(img)(_p4##x,_p11##y,z,c), I[98] = (T)(img)(_p3##x,_p11##y,z,c), I[99] = (T)(img)(_p2##x,_p11##y,z,c), I[100] = (T)(img)(_p1##x,_p11##y,z,c), I[101] = (T)(img)(x,_p11##y,z,c), I[102] = (T)(img)(_n1##x,_p11##y,z,c), I[103] = (T)(img)(_n2##x,_p11##y,z,c), I[104] = (T)(img)(_n3##x,_p11##y,z,c), I[105] = (T)(img)(_n4##x,_p11##y,z,c), I[106] = (T)(img)(_n5##x,_p11##y,z,c), I[107] = (T)(img)(_n6##x,_p11##y,z,c), I[108] = (T)(img)(_n7##x,_p11##y,z,c), I[109] = (T)(img)(_n8##x,_p11##y,z,c), I[110] = (T)(img)(_n9##x,_p11##y,z,c), I[111] = (T)(img)(_n10##x,_p11##y,z,c), I[112] = (T)(img)(_n11##x,_p11##y,z,c), I[113] = (T)(img)(_n12##x,_p11##y,z,c), I[114] = (T)(img)(_n13##x,_p11##y,z,c), I[115] = (T)(img)(_n14##x,_p11##y,z,c), \ - I[116] = (T)(img)(_p14##x,_p10##y,z,c), I[117] = (T)(img)(_p13##x,_p10##y,z,c), I[118] = (T)(img)(_p12##x,_p10##y,z,c), I[119] = (T)(img)(_p11##x,_p10##y,z,c), I[120] = (T)(img)(_p10##x,_p10##y,z,c), I[121] = (T)(img)(_p9##x,_p10##y,z,c), I[122] = (T)(img)(_p8##x,_p10##y,z,c), I[123] = (T)(img)(_p7##x,_p10##y,z,c), I[124] = (T)(img)(_p6##x,_p10##y,z,c), I[125] = (T)(img)(_p5##x,_p10##y,z,c), I[126] = (T)(img)(_p4##x,_p10##y,z,c), I[127] = (T)(img)(_p3##x,_p10##y,z,c), I[128] = (T)(img)(_p2##x,_p10##y,z,c), I[129] = (T)(img)(_p1##x,_p10##y,z,c), I[130] = (T)(img)(x,_p10##y,z,c), I[131] = (T)(img)(_n1##x,_p10##y,z,c), I[132] = (T)(img)(_n2##x,_p10##y,z,c), I[133] = (T)(img)(_n3##x,_p10##y,z,c), I[134] = (T)(img)(_n4##x,_p10##y,z,c), I[135] = (T)(img)(_n5##x,_p10##y,z,c), I[136] = (T)(img)(_n6##x,_p10##y,z,c), I[137] = (T)(img)(_n7##x,_p10##y,z,c), I[138] = (T)(img)(_n8##x,_p10##y,z,c), I[139] = (T)(img)(_n9##x,_p10##y,z,c), I[140] = (T)(img)(_n10##x,_p10##y,z,c), I[141] = (T)(img)(_n11##x,_p10##y,z,c), I[142] = (T)(img)(_n12##x,_p10##y,z,c), I[143] = (T)(img)(_n13##x,_p10##y,z,c), I[144] = (T)(img)(_n14##x,_p10##y,z,c), \ - I[145] = (T)(img)(_p14##x,_p9##y,z,c), I[146] = (T)(img)(_p13##x,_p9##y,z,c), I[147] = (T)(img)(_p12##x,_p9##y,z,c), I[148] = (T)(img)(_p11##x,_p9##y,z,c), I[149] = (T)(img)(_p10##x,_p9##y,z,c), I[150] = (T)(img)(_p9##x,_p9##y,z,c), I[151] = (T)(img)(_p8##x,_p9##y,z,c), I[152] = (T)(img)(_p7##x,_p9##y,z,c), I[153] = (T)(img)(_p6##x,_p9##y,z,c), I[154] = (T)(img)(_p5##x,_p9##y,z,c), I[155] = (T)(img)(_p4##x,_p9##y,z,c), I[156] = (T)(img)(_p3##x,_p9##y,z,c), I[157] = (T)(img)(_p2##x,_p9##y,z,c), I[158] = (T)(img)(_p1##x,_p9##y,z,c), I[159] = (T)(img)(x,_p9##y,z,c), I[160] = (T)(img)(_n1##x,_p9##y,z,c), I[161] = (T)(img)(_n2##x,_p9##y,z,c), I[162] = (T)(img)(_n3##x,_p9##y,z,c), I[163] = (T)(img)(_n4##x,_p9##y,z,c), I[164] = (T)(img)(_n5##x,_p9##y,z,c), I[165] = (T)(img)(_n6##x,_p9##y,z,c), I[166] = (T)(img)(_n7##x,_p9##y,z,c), I[167] = (T)(img)(_n8##x,_p9##y,z,c), I[168] = (T)(img)(_n9##x,_p9##y,z,c), I[169] = (T)(img)(_n10##x,_p9##y,z,c), I[170] = (T)(img)(_n11##x,_p9##y,z,c), I[171] = (T)(img)(_n12##x,_p9##y,z,c), I[172] = (T)(img)(_n13##x,_p9##y,z,c), I[173] = (T)(img)(_n14##x,_p9##y,z,c), \ - I[174] = (T)(img)(_p14##x,_p8##y,z,c), I[175] = (T)(img)(_p13##x,_p8##y,z,c), I[176] = (T)(img)(_p12##x,_p8##y,z,c), I[177] = (T)(img)(_p11##x,_p8##y,z,c), I[178] = (T)(img)(_p10##x,_p8##y,z,c), I[179] = (T)(img)(_p9##x,_p8##y,z,c), I[180] = (T)(img)(_p8##x,_p8##y,z,c), I[181] = (T)(img)(_p7##x,_p8##y,z,c), I[182] = (T)(img)(_p6##x,_p8##y,z,c), I[183] = (T)(img)(_p5##x,_p8##y,z,c), I[184] = (T)(img)(_p4##x,_p8##y,z,c), I[185] = (T)(img)(_p3##x,_p8##y,z,c), I[186] = (T)(img)(_p2##x,_p8##y,z,c), I[187] = (T)(img)(_p1##x,_p8##y,z,c), I[188] = (T)(img)(x,_p8##y,z,c), I[189] = (T)(img)(_n1##x,_p8##y,z,c), I[190] = (T)(img)(_n2##x,_p8##y,z,c), I[191] = (T)(img)(_n3##x,_p8##y,z,c), I[192] = (T)(img)(_n4##x,_p8##y,z,c), I[193] = (T)(img)(_n5##x,_p8##y,z,c), I[194] = (T)(img)(_n6##x,_p8##y,z,c), I[195] = (T)(img)(_n7##x,_p8##y,z,c), I[196] = (T)(img)(_n8##x,_p8##y,z,c), I[197] = (T)(img)(_n9##x,_p8##y,z,c), I[198] = (T)(img)(_n10##x,_p8##y,z,c), I[199] = (T)(img)(_n11##x,_p8##y,z,c), I[200] = (T)(img)(_n12##x,_p8##y,z,c), I[201] = (T)(img)(_n13##x,_p8##y,z,c), I[202] = (T)(img)(_n14##x,_p8##y,z,c), \ - I[203] = (T)(img)(_p14##x,_p7##y,z,c), I[204] = (T)(img)(_p13##x,_p7##y,z,c), I[205] = (T)(img)(_p12##x,_p7##y,z,c), I[206] = (T)(img)(_p11##x,_p7##y,z,c), I[207] = (T)(img)(_p10##x,_p7##y,z,c), I[208] = (T)(img)(_p9##x,_p7##y,z,c), I[209] = (T)(img)(_p8##x,_p7##y,z,c), I[210] = (T)(img)(_p7##x,_p7##y,z,c), I[211] = (T)(img)(_p6##x,_p7##y,z,c), I[212] = (T)(img)(_p5##x,_p7##y,z,c), I[213] = (T)(img)(_p4##x,_p7##y,z,c), I[214] = (T)(img)(_p3##x,_p7##y,z,c), I[215] = (T)(img)(_p2##x,_p7##y,z,c), I[216] = (T)(img)(_p1##x,_p7##y,z,c), I[217] = (T)(img)(x,_p7##y,z,c), I[218] = (T)(img)(_n1##x,_p7##y,z,c), I[219] = (T)(img)(_n2##x,_p7##y,z,c), I[220] = (T)(img)(_n3##x,_p7##y,z,c), I[221] = (T)(img)(_n4##x,_p7##y,z,c), I[222] = (T)(img)(_n5##x,_p7##y,z,c), I[223] = (T)(img)(_n6##x,_p7##y,z,c), I[224] = (T)(img)(_n7##x,_p7##y,z,c), I[225] = (T)(img)(_n8##x,_p7##y,z,c), I[226] = (T)(img)(_n9##x,_p7##y,z,c), I[227] = (T)(img)(_n10##x,_p7##y,z,c), I[228] = (T)(img)(_n11##x,_p7##y,z,c), I[229] = (T)(img)(_n12##x,_p7##y,z,c), I[230] = (T)(img)(_n13##x,_p7##y,z,c), I[231] = (T)(img)(_n14##x,_p7##y,z,c), \ - I[232] = (T)(img)(_p14##x,_p6##y,z,c), I[233] = (T)(img)(_p13##x,_p6##y,z,c), I[234] = (T)(img)(_p12##x,_p6##y,z,c), I[235] = (T)(img)(_p11##x,_p6##y,z,c), I[236] = (T)(img)(_p10##x,_p6##y,z,c), I[237] = (T)(img)(_p9##x,_p6##y,z,c), I[238] = (T)(img)(_p8##x,_p6##y,z,c), I[239] = (T)(img)(_p7##x,_p6##y,z,c), I[240] = (T)(img)(_p6##x,_p6##y,z,c), I[241] = (T)(img)(_p5##x,_p6##y,z,c), I[242] = (T)(img)(_p4##x,_p6##y,z,c), I[243] = (T)(img)(_p3##x,_p6##y,z,c), I[244] = (T)(img)(_p2##x,_p6##y,z,c), I[245] = (T)(img)(_p1##x,_p6##y,z,c), I[246] = (T)(img)(x,_p6##y,z,c), I[247] = (T)(img)(_n1##x,_p6##y,z,c), I[248] = (T)(img)(_n2##x,_p6##y,z,c), I[249] = (T)(img)(_n3##x,_p6##y,z,c), I[250] = (T)(img)(_n4##x,_p6##y,z,c), I[251] = (T)(img)(_n5##x,_p6##y,z,c), I[252] = (T)(img)(_n6##x,_p6##y,z,c), I[253] = (T)(img)(_n7##x,_p6##y,z,c), I[254] = (T)(img)(_n8##x,_p6##y,z,c), I[255] = (T)(img)(_n9##x,_p6##y,z,c), I[256] = (T)(img)(_n10##x,_p6##y,z,c), I[257] = (T)(img)(_n11##x,_p6##y,z,c), I[258] = (T)(img)(_n12##x,_p6##y,z,c), I[259] = (T)(img)(_n13##x,_p6##y,z,c), I[260] = (T)(img)(_n14##x,_p6##y,z,c), \ - I[261] = (T)(img)(_p14##x,_p5##y,z,c), I[262] = (T)(img)(_p13##x,_p5##y,z,c), I[263] = (T)(img)(_p12##x,_p5##y,z,c), I[264] = (T)(img)(_p11##x,_p5##y,z,c), I[265] = (T)(img)(_p10##x,_p5##y,z,c), I[266] = (T)(img)(_p9##x,_p5##y,z,c), I[267] = (T)(img)(_p8##x,_p5##y,z,c), I[268] = (T)(img)(_p7##x,_p5##y,z,c), I[269] = (T)(img)(_p6##x,_p5##y,z,c), I[270] = (T)(img)(_p5##x,_p5##y,z,c), I[271] = (T)(img)(_p4##x,_p5##y,z,c), I[272] = (T)(img)(_p3##x,_p5##y,z,c), I[273] = (T)(img)(_p2##x,_p5##y,z,c), I[274] = (T)(img)(_p1##x,_p5##y,z,c), I[275] = (T)(img)(x,_p5##y,z,c), I[276] = (T)(img)(_n1##x,_p5##y,z,c), I[277] = (T)(img)(_n2##x,_p5##y,z,c), I[278] = (T)(img)(_n3##x,_p5##y,z,c), I[279] = (T)(img)(_n4##x,_p5##y,z,c), I[280] = (T)(img)(_n5##x,_p5##y,z,c), I[281] = (T)(img)(_n6##x,_p5##y,z,c), I[282] = (T)(img)(_n7##x,_p5##y,z,c), I[283] = (T)(img)(_n8##x,_p5##y,z,c), I[284] = (T)(img)(_n9##x,_p5##y,z,c), I[285] = (T)(img)(_n10##x,_p5##y,z,c), I[286] = (T)(img)(_n11##x,_p5##y,z,c), I[287] = (T)(img)(_n12##x,_p5##y,z,c), I[288] = (T)(img)(_n13##x,_p5##y,z,c), I[289] = (T)(img)(_n14##x,_p5##y,z,c), \ - I[290] = (T)(img)(_p14##x,_p4##y,z,c), I[291] = (T)(img)(_p13##x,_p4##y,z,c), I[292] = (T)(img)(_p12##x,_p4##y,z,c), I[293] = (T)(img)(_p11##x,_p4##y,z,c), I[294] = (T)(img)(_p10##x,_p4##y,z,c), I[295] = (T)(img)(_p9##x,_p4##y,z,c), I[296] = (T)(img)(_p8##x,_p4##y,z,c), I[297] = (T)(img)(_p7##x,_p4##y,z,c), I[298] = (T)(img)(_p6##x,_p4##y,z,c), I[299] = (T)(img)(_p5##x,_p4##y,z,c), I[300] = (T)(img)(_p4##x,_p4##y,z,c), I[301] = (T)(img)(_p3##x,_p4##y,z,c), I[302] = (T)(img)(_p2##x,_p4##y,z,c), I[303] = (T)(img)(_p1##x,_p4##y,z,c), I[304] = (T)(img)(x,_p4##y,z,c), I[305] = (T)(img)(_n1##x,_p4##y,z,c), I[306] = (T)(img)(_n2##x,_p4##y,z,c), I[307] = (T)(img)(_n3##x,_p4##y,z,c), I[308] = (T)(img)(_n4##x,_p4##y,z,c), I[309] = (T)(img)(_n5##x,_p4##y,z,c), I[310] = (T)(img)(_n6##x,_p4##y,z,c), I[311] = (T)(img)(_n7##x,_p4##y,z,c), I[312] = (T)(img)(_n8##x,_p4##y,z,c), I[313] = (T)(img)(_n9##x,_p4##y,z,c), I[314] = (T)(img)(_n10##x,_p4##y,z,c), I[315] = (T)(img)(_n11##x,_p4##y,z,c), I[316] = (T)(img)(_n12##x,_p4##y,z,c), I[317] = (T)(img)(_n13##x,_p4##y,z,c), I[318] = (T)(img)(_n14##x,_p4##y,z,c), \ - I[319] = (T)(img)(_p14##x,_p3##y,z,c), I[320] = (T)(img)(_p13##x,_p3##y,z,c), I[321] = (T)(img)(_p12##x,_p3##y,z,c), I[322] = (T)(img)(_p11##x,_p3##y,z,c), I[323] = (T)(img)(_p10##x,_p3##y,z,c), I[324] = (T)(img)(_p9##x,_p3##y,z,c), I[325] = (T)(img)(_p8##x,_p3##y,z,c), I[326] = (T)(img)(_p7##x,_p3##y,z,c), I[327] = (T)(img)(_p6##x,_p3##y,z,c), I[328] = (T)(img)(_p5##x,_p3##y,z,c), I[329] = (T)(img)(_p4##x,_p3##y,z,c), I[330] = (T)(img)(_p3##x,_p3##y,z,c), I[331] = (T)(img)(_p2##x,_p3##y,z,c), I[332] = (T)(img)(_p1##x,_p3##y,z,c), I[333] = (T)(img)(x,_p3##y,z,c), I[334] = (T)(img)(_n1##x,_p3##y,z,c), I[335] = (T)(img)(_n2##x,_p3##y,z,c), I[336] = (T)(img)(_n3##x,_p3##y,z,c), I[337] = (T)(img)(_n4##x,_p3##y,z,c), I[338] = (T)(img)(_n5##x,_p3##y,z,c), I[339] = (T)(img)(_n6##x,_p3##y,z,c), I[340] = (T)(img)(_n7##x,_p3##y,z,c), I[341] = (T)(img)(_n8##x,_p3##y,z,c), I[342] = (T)(img)(_n9##x,_p3##y,z,c), I[343] = (T)(img)(_n10##x,_p3##y,z,c), I[344] = (T)(img)(_n11##x,_p3##y,z,c), I[345] = (T)(img)(_n12##x,_p3##y,z,c), I[346] = (T)(img)(_n13##x,_p3##y,z,c), I[347] = (T)(img)(_n14##x,_p3##y,z,c), \ - I[348] = (T)(img)(_p14##x,_p2##y,z,c), I[349] = (T)(img)(_p13##x,_p2##y,z,c), I[350] = (T)(img)(_p12##x,_p2##y,z,c), I[351] = (T)(img)(_p11##x,_p2##y,z,c), I[352] = (T)(img)(_p10##x,_p2##y,z,c), I[353] = (T)(img)(_p9##x,_p2##y,z,c), I[354] = (T)(img)(_p8##x,_p2##y,z,c), I[355] = (T)(img)(_p7##x,_p2##y,z,c), I[356] = (T)(img)(_p6##x,_p2##y,z,c), I[357] = (T)(img)(_p5##x,_p2##y,z,c), I[358] = (T)(img)(_p4##x,_p2##y,z,c), I[359] = (T)(img)(_p3##x,_p2##y,z,c), I[360] = (T)(img)(_p2##x,_p2##y,z,c), I[361] = (T)(img)(_p1##x,_p2##y,z,c), I[362] = (T)(img)(x,_p2##y,z,c), I[363] = (T)(img)(_n1##x,_p2##y,z,c), I[364] = (T)(img)(_n2##x,_p2##y,z,c), I[365] = (T)(img)(_n3##x,_p2##y,z,c), I[366] = (T)(img)(_n4##x,_p2##y,z,c), I[367] = (T)(img)(_n5##x,_p2##y,z,c), I[368] = (T)(img)(_n6##x,_p2##y,z,c), I[369] = (T)(img)(_n7##x,_p2##y,z,c), I[370] = (T)(img)(_n8##x,_p2##y,z,c), I[371] = (T)(img)(_n9##x,_p2##y,z,c), I[372] = (T)(img)(_n10##x,_p2##y,z,c), I[373] = (T)(img)(_n11##x,_p2##y,z,c), I[374] = (T)(img)(_n12##x,_p2##y,z,c), I[375] = (T)(img)(_n13##x,_p2##y,z,c), I[376] = (T)(img)(_n14##x,_p2##y,z,c), \ - I[377] = (T)(img)(_p14##x,_p1##y,z,c), I[378] = (T)(img)(_p13##x,_p1##y,z,c), I[379] = (T)(img)(_p12##x,_p1##y,z,c), I[380] = (T)(img)(_p11##x,_p1##y,z,c), I[381] = (T)(img)(_p10##x,_p1##y,z,c), I[382] = (T)(img)(_p9##x,_p1##y,z,c), I[383] = (T)(img)(_p8##x,_p1##y,z,c), I[384] = (T)(img)(_p7##x,_p1##y,z,c), I[385] = (T)(img)(_p6##x,_p1##y,z,c), I[386] = (T)(img)(_p5##x,_p1##y,z,c), I[387] = (T)(img)(_p4##x,_p1##y,z,c), I[388] = (T)(img)(_p3##x,_p1##y,z,c), I[389] = (T)(img)(_p2##x,_p1##y,z,c), I[390] = (T)(img)(_p1##x,_p1##y,z,c), I[391] = (T)(img)(x,_p1##y,z,c), I[392] = (T)(img)(_n1##x,_p1##y,z,c), I[393] = (T)(img)(_n2##x,_p1##y,z,c), I[394] = (T)(img)(_n3##x,_p1##y,z,c), I[395] = (T)(img)(_n4##x,_p1##y,z,c), I[396] = (T)(img)(_n5##x,_p1##y,z,c), I[397] = (T)(img)(_n6##x,_p1##y,z,c), I[398] = (T)(img)(_n7##x,_p1##y,z,c), I[399] = (T)(img)(_n8##x,_p1##y,z,c), I[400] = (T)(img)(_n9##x,_p1##y,z,c), I[401] = (T)(img)(_n10##x,_p1##y,z,c), I[402] = (T)(img)(_n11##x,_p1##y,z,c), I[403] = (T)(img)(_n12##x,_p1##y,z,c), I[404] = (T)(img)(_n13##x,_p1##y,z,c), I[405] = (T)(img)(_n14##x,_p1##y,z,c), \ - I[406] = (T)(img)(_p14##x,y,z,c), I[407] = (T)(img)(_p13##x,y,z,c), I[408] = (T)(img)(_p12##x,y,z,c), I[409] = (T)(img)(_p11##x,y,z,c), I[410] = (T)(img)(_p10##x,y,z,c), I[411] = (T)(img)(_p9##x,y,z,c), I[412] = (T)(img)(_p8##x,y,z,c), I[413] = (T)(img)(_p7##x,y,z,c), I[414] = (T)(img)(_p6##x,y,z,c), I[415] = (T)(img)(_p5##x,y,z,c), I[416] = (T)(img)(_p4##x,y,z,c), I[417] = (T)(img)(_p3##x,y,z,c), I[418] = (T)(img)(_p2##x,y,z,c), I[419] = (T)(img)(_p1##x,y,z,c), I[420] = (T)(img)(x,y,z,c), I[421] = (T)(img)(_n1##x,y,z,c), I[422] = (T)(img)(_n2##x,y,z,c), I[423] = (T)(img)(_n3##x,y,z,c), I[424] = (T)(img)(_n4##x,y,z,c), I[425] = (T)(img)(_n5##x,y,z,c), I[426] = (T)(img)(_n6##x,y,z,c), I[427] = (T)(img)(_n7##x,y,z,c), I[428] = (T)(img)(_n8##x,y,z,c), I[429] = (T)(img)(_n9##x,y,z,c), I[430] = (T)(img)(_n10##x,y,z,c), I[431] = (T)(img)(_n11##x,y,z,c), I[432] = (T)(img)(_n12##x,y,z,c), I[433] = (T)(img)(_n13##x,y,z,c), I[434] = (T)(img)(_n14##x,y,z,c), \ - I[435] = (T)(img)(_p14##x,_n1##y,z,c), I[436] = (T)(img)(_p13##x,_n1##y,z,c), I[437] = (T)(img)(_p12##x,_n1##y,z,c), I[438] = (T)(img)(_p11##x,_n1##y,z,c), I[439] = (T)(img)(_p10##x,_n1##y,z,c), I[440] = (T)(img)(_p9##x,_n1##y,z,c), I[441] = (T)(img)(_p8##x,_n1##y,z,c), I[442] = (T)(img)(_p7##x,_n1##y,z,c), I[443] = (T)(img)(_p6##x,_n1##y,z,c), I[444] = (T)(img)(_p5##x,_n1##y,z,c), I[445] = (T)(img)(_p4##x,_n1##y,z,c), I[446] = (T)(img)(_p3##x,_n1##y,z,c), I[447] = (T)(img)(_p2##x,_n1##y,z,c), I[448] = (T)(img)(_p1##x,_n1##y,z,c), I[449] = (T)(img)(x,_n1##y,z,c), I[450] = (T)(img)(_n1##x,_n1##y,z,c), I[451] = (T)(img)(_n2##x,_n1##y,z,c), I[452] = (T)(img)(_n3##x,_n1##y,z,c), I[453] = (T)(img)(_n4##x,_n1##y,z,c), I[454] = (T)(img)(_n5##x,_n1##y,z,c), I[455] = (T)(img)(_n6##x,_n1##y,z,c), I[456] = (T)(img)(_n7##x,_n1##y,z,c), I[457] = (T)(img)(_n8##x,_n1##y,z,c), I[458] = (T)(img)(_n9##x,_n1##y,z,c), I[459] = (T)(img)(_n10##x,_n1##y,z,c), I[460] = (T)(img)(_n11##x,_n1##y,z,c), I[461] = (T)(img)(_n12##x,_n1##y,z,c), I[462] = (T)(img)(_n13##x,_n1##y,z,c), I[463] = (T)(img)(_n14##x,_n1##y,z,c), \ - I[464] = (T)(img)(_p14##x,_n2##y,z,c), I[465] = (T)(img)(_p13##x,_n2##y,z,c), I[466] = (T)(img)(_p12##x,_n2##y,z,c), I[467] = (T)(img)(_p11##x,_n2##y,z,c), I[468] = (T)(img)(_p10##x,_n2##y,z,c), I[469] = (T)(img)(_p9##x,_n2##y,z,c), I[470] = (T)(img)(_p8##x,_n2##y,z,c), I[471] = (T)(img)(_p7##x,_n2##y,z,c), I[472] = (T)(img)(_p6##x,_n2##y,z,c), I[473] = (T)(img)(_p5##x,_n2##y,z,c), I[474] = (T)(img)(_p4##x,_n2##y,z,c), I[475] = (T)(img)(_p3##x,_n2##y,z,c), I[476] = (T)(img)(_p2##x,_n2##y,z,c), I[477] = (T)(img)(_p1##x,_n2##y,z,c), I[478] = (T)(img)(x,_n2##y,z,c), I[479] = (T)(img)(_n1##x,_n2##y,z,c), I[480] = (T)(img)(_n2##x,_n2##y,z,c), I[481] = (T)(img)(_n3##x,_n2##y,z,c), I[482] = (T)(img)(_n4##x,_n2##y,z,c), I[483] = (T)(img)(_n5##x,_n2##y,z,c), I[484] = (T)(img)(_n6##x,_n2##y,z,c), I[485] = (T)(img)(_n7##x,_n2##y,z,c), I[486] = (T)(img)(_n8##x,_n2##y,z,c), I[487] = (T)(img)(_n9##x,_n2##y,z,c), I[488] = (T)(img)(_n10##x,_n2##y,z,c), I[489] = (T)(img)(_n11##x,_n2##y,z,c), I[490] = (T)(img)(_n12##x,_n2##y,z,c), I[491] = (T)(img)(_n13##x,_n2##y,z,c), I[492] = (T)(img)(_n14##x,_n2##y,z,c), \ - I[493] = (T)(img)(_p14##x,_n3##y,z,c), I[494] = (T)(img)(_p13##x,_n3##y,z,c), I[495] = (T)(img)(_p12##x,_n3##y,z,c), I[496] = (T)(img)(_p11##x,_n3##y,z,c), I[497] = (T)(img)(_p10##x,_n3##y,z,c), I[498] = (T)(img)(_p9##x,_n3##y,z,c), I[499] = (T)(img)(_p8##x,_n3##y,z,c), I[500] = (T)(img)(_p7##x,_n3##y,z,c), I[501] = (T)(img)(_p6##x,_n3##y,z,c), I[502] = (T)(img)(_p5##x,_n3##y,z,c), I[503] = (T)(img)(_p4##x,_n3##y,z,c), I[504] = (T)(img)(_p3##x,_n3##y,z,c), I[505] = (T)(img)(_p2##x,_n3##y,z,c), I[506] = (T)(img)(_p1##x,_n3##y,z,c), I[507] = (T)(img)(x,_n3##y,z,c), I[508] = (T)(img)(_n1##x,_n3##y,z,c), I[509] = (T)(img)(_n2##x,_n3##y,z,c), I[510] = (T)(img)(_n3##x,_n3##y,z,c), I[511] = (T)(img)(_n4##x,_n3##y,z,c), I[512] = (T)(img)(_n5##x,_n3##y,z,c), I[513] = (T)(img)(_n6##x,_n3##y,z,c), I[514] = (T)(img)(_n7##x,_n3##y,z,c), I[515] = (T)(img)(_n8##x,_n3##y,z,c), I[516] = (T)(img)(_n9##x,_n3##y,z,c), I[517] = (T)(img)(_n10##x,_n3##y,z,c), I[518] = (T)(img)(_n11##x,_n3##y,z,c), I[519] = (T)(img)(_n12##x,_n3##y,z,c), I[520] = (T)(img)(_n13##x,_n3##y,z,c), I[521] = (T)(img)(_n14##x,_n3##y,z,c), \ - I[522] = (T)(img)(_p14##x,_n4##y,z,c), I[523] = (T)(img)(_p13##x,_n4##y,z,c), I[524] = (T)(img)(_p12##x,_n4##y,z,c), I[525] = (T)(img)(_p11##x,_n4##y,z,c), I[526] = (T)(img)(_p10##x,_n4##y,z,c), I[527] = (T)(img)(_p9##x,_n4##y,z,c), I[528] = (T)(img)(_p8##x,_n4##y,z,c), I[529] = (T)(img)(_p7##x,_n4##y,z,c), I[530] = (T)(img)(_p6##x,_n4##y,z,c), I[531] = (T)(img)(_p5##x,_n4##y,z,c), I[532] = (T)(img)(_p4##x,_n4##y,z,c), I[533] = (T)(img)(_p3##x,_n4##y,z,c), I[534] = (T)(img)(_p2##x,_n4##y,z,c), I[535] = (T)(img)(_p1##x,_n4##y,z,c), I[536] = (T)(img)(x,_n4##y,z,c), I[537] = (T)(img)(_n1##x,_n4##y,z,c), I[538] = (T)(img)(_n2##x,_n4##y,z,c), I[539] = (T)(img)(_n3##x,_n4##y,z,c), I[540] = (T)(img)(_n4##x,_n4##y,z,c), I[541] = (T)(img)(_n5##x,_n4##y,z,c), I[542] = (T)(img)(_n6##x,_n4##y,z,c), I[543] = (T)(img)(_n7##x,_n4##y,z,c), I[544] = (T)(img)(_n8##x,_n4##y,z,c), I[545] = (T)(img)(_n9##x,_n4##y,z,c), I[546] = (T)(img)(_n10##x,_n4##y,z,c), I[547] = (T)(img)(_n11##x,_n4##y,z,c), I[548] = (T)(img)(_n12##x,_n4##y,z,c), I[549] = (T)(img)(_n13##x,_n4##y,z,c), I[550] = (T)(img)(_n14##x,_n4##y,z,c), \ - I[551] = (T)(img)(_p14##x,_n5##y,z,c), I[552] = (T)(img)(_p13##x,_n5##y,z,c), I[553] = (T)(img)(_p12##x,_n5##y,z,c), I[554] = (T)(img)(_p11##x,_n5##y,z,c), I[555] = (T)(img)(_p10##x,_n5##y,z,c), I[556] = (T)(img)(_p9##x,_n5##y,z,c), I[557] = (T)(img)(_p8##x,_n5##y,z,c), I[558] = (T)(img)(_p7##x,_n5##y,z,c), I[559] = (T)(img)(_p6##x,_n5##y,z,c), I[560] = (T)(img)(_p5##x,_n5##y,z,c), I[561] = (T)(img)(_p4##x,_n5##y,z,c), I[562] = (T)(img)(_p3##x,_n5##y,z,c), I[563] = (T)(img)(_p2##x,_n5##y,z,c), I[564] = (T)(img)(_p1##x,_n5##y,z,c), I[565] = (T)(img)(x,_n5##y,z,c), I[566] = (T)(img)(_n1##x,_n5##y,z,c), I[567] = (T)(img)(_n2##x,_n5##y,z,c), I[568] = (T)(img)(_n3##x,_n5##y,z,c), I[569] = (T)(img)(_n4##x,_n5##y,z,c), I[570] = (T)(img)(_n5##x,_n5##y,z,c), I[571] = (T)(img)(_n6##x,_n5##y,z,c), I[572] = (T)(img)(_n7##x,_n5##y,z,c), I[573] = (T)(img)(_n8##x,_n5##y,z,c), I[574] = (T)(img)(_n9##x,_n5##y,z,c), I[575] = (T)(img)(_n10##x,_n5##y,z,c), I[576] = (T)(img)(_n11##x,_n5##y,z,c), I[577] = (T)(img)(_n12##x,_n5##y,z,c), I[578] = (T)(img)(_n13##x,_n5##y,z,c), I[579] = (T)(img)(_n14##x,_n5##y,z,c), \ - I[580] = (T)(img)(_p14##x,_n6##y,z,c), I[581] = (T)(img)(_p13##x,_n6##y,z,c), I[582] = (T)(img)(_p12##x,_n6##y,z,c), I[583] = (T)(img)(_p11##x,_n6##y,z,c), I[584] = (T)(img)(_p10##x,_n6##y,z,c), I[585] = (T)(img)(_p9##x,_n6##y,z,c), I[586] = (T)(img)(_p8##x,_n6##y,z,c), I[587] = (T)(img)(_p7##x,_n6##y,z,c), I[588] = (T)(img)(_p6##x,_n6##y,z,c), I[589] = (T)(img)(_p5##x,_n6##y,z,c), I[590] = (T)(img)(_p4##x,_n6##y,z,c), I[591] = (T)(img)(_p3##x,_n6##y,z,c), I[592] = (T)(img)(_p2##x,_n6##y,z,c), I[593] = (T)(img)(_p1##x,_n6##y,z,c), I[594] = (T)(img)(x,_n6##y,z,c), I[595] = (T)(img)(_n1##x,_n6##y,z,c), I[596] = (T)(img)(_n2##x,_n6##y,z,c), I[597] = (T)(img)(_n3##x,_n6##y,z,c), I[598] = (T)(img)(_n4##x,_n6##y,z,c), I[599] = (T)(img)(_n5##x,_n6##y,z,c), I[600] = (T)(img)(_n6##x,_n6##y,z,c), I[601] = (T)(img)(_n7##x,_n6##y,z,c), I[602] = (T)(img)(_n8##x,_n6##y,z,c), I[603] = (T)(img)(_n9##x,_n6##y,z,c), I[604] = (T)(img)(_n10##x,_n6##y,z,c), I[605] = (T)(img)(_n11##x,_n6##y,z,c), I[606] = (T)(img)(_n12##x,_n6##y,z,c), I[607] = (T)(img)(_n13##x,_n6##y,z,c), I[608] = (T)(img)(_n14##x,_n6##y,z,c), \ - I[609] = (T)(img)(_p14##x,_n7##y,z,c), I[610] = (T)(img)(_p13##x,_n7##y,z,c), I[611] = (T)(img)(_p12##x,_n7##y,z,c), I[612] = (T)(img)(_p11##x,_n7##y,z,c), I[613] = (T)(img)(_p10##x,_n7##y,z,c), I[614] = (T)(img)(_p9##x,_n7##y,z,c), I[615] = (T)(img)(_p8##x,_n7##y,z,c), I[616] = (T)(img)(_p7##x,_n7##y,z,c), I[617] = (T)(img)(_p6##x,_n7##y,z,c), I[618] = (T)(img)(_p5##x,_n7##y,z,c), I[619] = (T)(img)(_p4##x,_n7##y,z,c), I[620] = (T)(img)(_p3##x,_n7##y,z,c), I[621] = (T)(img)(_p2##x,_n7##y,z,c), I[622] = (T)(img)(_p1##x,_n7##y,z,c), I[623] = (T)(img)(x,_n7##y,z,c), I[624] = (T)(img)(_n1##x,_n7##y,z,c), I[625] = (T)(img)(_n2##x,_n7##y,z,c), I[626] = (T)(img)(_n3##x,_n7##y,z,c), I[627] = (T)(img)(_n4##x,_n7##y,z,c), I[628] = (T)(img)(_n5##x,_n7##y,z,c), I[629] = (T)(img)(_n6##x,_n7##y,z,c), I[630] = (T)(img)(_n7##x,_n7##y,z,c), I[631] = (T)(img)(_n8##x,_n7##y,z,c), I[632] = (T)(img)(_n9##x,_n7##y,z,c), I[633] = (T)(img)(_n10##x,_n7##y,z,c), I[634] = (T)(img)(_n11##x,_n7##y,z,c), I[635] = (T)(img)(_n12##x,_n7##y,z,c), I[636] = (T)(img)(_n13##x,_n7##y,z,c), I[637] = (T)(img)(_n14##x,_n7##y,z,c), \ - I[638] = (T)(img)(_p14##x,_n8##y,z,c), I[639] = (T)(img)(_p13##x,_n8##y,z,c), I[640] = (T)(img)(_p12##x,_n8##y,z,c), I[641] = (T)(img)(_p11##x,_n8##y,z,c), I[642] = (T)(img)(_p10##x,_n8##y,z,c), I[643] = (T)(img)(_p9##x,_n8##y,z,c), I[644] = (T)(img)(_p8##x,_n8##y,z,c), I[645] = (T)(img)(_p7##x,_n8##y,z,c), I[646] = (T)(img)(_p6##x,_n8##y,z,c), I[647] = (T)(img)(_p5##x,_n8##y,z,c), I[648] = (T)(img)(_p4##x,_n8##y,z,c), I[649] = (T)(img)(_p3##x,_n8##y,z,c), I[650] = (T)(img)(_p2##x,_n8##y,z,c), I[651] = (T)(img)(_p1##x,_n8##y,z,c), I[652] = (T)(img)(x,_n8##y,z,c), I[653] = (T)(img)(_n1##x,_n8##y,z,c), I[654] = (T)(img)(_n2##x,_n8##y,z,c), I[655] = (T)(img)(_n3##x,_n8##y,z,c), I[656] = (T)(img)(_n4##x,_n8##y,z,c), I[657] = (T)(img)(_n5##x,_n8##y,z,c), I[658] = (T)(img)(_n6##x,_n8##y,z,c), I[659] = (T)(img)(_n7##x,_n8##y,z,c), I[660] = (T)(img)(_n8##x,_n8##y,z,c), I[661] = (T)(img)(_n9##x,_n8##y,z,c), I[662] = (T)(img)(_n10##x,_n8##y,z,c), I[663] = (T)(img)(_n11##x,_n8##y,z,c), I[664] = (T)(img)(_n12##x,_n8##y,z,c), I[665] = (T)(img)(_n13##x,_n8##y,z,c), I[666] = (T)(img)(_n14##x,_n8##y,z,c), \ - I[667] = (T)(img)(_p14##x,_n9##y,z,c), I[668] = (T)(img)(_p13##x,_n9##y,z,c), I[669] = (T)(img)(_p12##x,_n9##y,z,c), I[670] = (T)(img)(_p11##x,_n9##y,z,c), I[671] = (T)(img)(_p10##x,_n9##y,z,c), I[672] = (T)(img)(_p9##x,_n9##y,z,c), I[673] = (T)(img)(_p8##x,_n9##y,z,c), I[674] = (T)(img)(_p7##x,_n9##y,z,c), I[675] = (T)(img)(_p6##x,_n9##y,z,c), I[676] = (T)(img)(_p5##x,_n9##y,z,c), I[677] = (T)(img)(_p4##x,_n9##y,z,c), I[678] = (T)(img)(_p3##x,_n9##y,z,c), I[679] = (T)(img)(_p2##x,_n9##y,z,c), I[680] = (T)(img)(_p1##x,_n9##y,z,c), I[681] = (T)(img)(x,_n9##y,z,c), I[682] = (T)(img)(_n1##x,_n9##y,z,c), I[683] = (T)(img)(_n2##x,_n9##y,z,c), I[684] = (T)(img)(_n3##x,_n9##y,z,c), I[685] = (T)(img)(_n4##x,_n9##y,z,c), I[686] = (T)(img)(_n5##x,_n9##y,z,c), I[687] = (T)(img)(_n6##x,_n9##y,z,c), I[688] = (T)(img)(_n7##x,_n9##y,z,c), I[689] = (T)(img)(_n8##x,_n9##y,z,c), I[690] = (T)(img)(_n9##x,_n9##y,z,c), I[691] = (T)(img)(_n10##x,_n9##y,z,c), I[692] = (T)(img)(_n11##x,_n9##y,z,c), I[693] = (T)(img)(_n12##x,_n9##y,z,c), I[694] = (T)(img)(_n13##x,_n9##y,z,c), I[695] = (T)(img)(_n14##x,_n9##y,z,c), \ - I[696] = (T)(img)(_p14##x,_n10##y,z,c), I[697] = (T)(img)(_p13##x,_n10##y,z,c), I[698] = (T)(img)(_p12##x,_n10##y,z,c), I[699] = (T)(img)(_p11##x,_n10##y,z,c), I[700] = (T)(img)(_p10##x,_n10##y,z,c), I[701] = (T)(img)(_p9##x,_n10##y,z,c), I[702] = (T)(img)(_p8##x,_n10##y,z,c), I[703] = (T)(img)(_p7##x,_n10##y,z,c), I[704] = (T)(img)(_p6##x,_n10##y,z,c), I[705] = (T)(img)(_p5##x,_n10##y,z,c), I[706] = (T)(img)(_p4##x,_n10##y,z,c), I[707] = (T)(img)(_p3##x,_n10##y,z,c), I[708] = (T)(img)(_p2##x,_n10##y,z,c), I[709] = (T)(img)(_p1##x,_n10##y,z,c), I[710] = (T)(img)(x,_n10##y,z,c), I[711] = (T)(img)(_n1##x,_n10##y,z,c), I[712] = (T)(img)(_n2##x,_n10##y,z,c), I[713] = (T)(img)(_n3##x,_n10##y,z,c), I[714] = (T)(img)(_n4##x,_n10##y,z,c), I[715] = (T)(img)(_n5##x,_n10##y,z,c), I[716] = (T)(img)(_n6##x,_n10##y,z,c), I[717] = (T)(img)(_n7##x,_n10##y,z,c), I[718] = (T)(img)(_n8##x,_n10##y,z,c), I[719] = (T)(img)(_n9##x,_n10##y,z,c), I[720] = (T)(img)(_n10##x,_n10##y,z,c), I[721] = (T)(img)(_n11##x,_n10##y,z,c), I[722] = (T)(img)(_n12##x,_n10##y,z,c), I[723] = (T)(img)(_n13##x,_n10##y,z,c), I[724] = (T)(img)(_n14##x,_n10##y,z,c), \ - I[725] = (T)(img)(_p14##x,_n11##y,z,c), I[726] = (T)(img)(_p13##x,_n11##y,z,c), I[727] = (T)(img)(_p12##x,_n11##y,z,c), I[728] = (T)(img)(_p11##x,_n11##y,z,c), I[729] = (T)(img)(_p10##x,_n11##y,z,c), I[730] = (T)(img)(_p9##x,_n11##y,z,c), I[731] = (T)(img)(_p8##x,_n11##y,z,c), I[732] = (T)(img)(_p7##x,_n11##y,z,c), I[733] = (T)(img)(_p6##x,_n11##y,z,c), I[734] = (T)(img)(_p5##x,_n11##y,z,c), I[735] = (T)(img)(_p4##x,_n11##y,z,c), I[736] = (T)(img)(_p3##x,_n11##y,z,c), I[737] = (T)(img)(_p2##x,_n11##y,z,c), I[738] = (T)(img)(_p1##x,_n11##y,z,c), I[739] = (T)(img)(x,_n11##y,z,c), I[740] = (T)(img)(_n1##x,_n11##y,z,c), I[741] = (T)(img)(_n2##x,_n11##y,z,c), I[742] = (T)(img)(_n3##x,_n11##y,z,c), I[743] = (T)(img)(_n4##x,_n11##y,z,c), I[744] = (T)(img)(_n5##x,_n11##y,z,c), I[745] = (T)(img)(_n6##x,_n11##y,z,c), I[746] = (T)(img)(_n7##x,_n11##y,z,c), I[747] = (T)(img)(_n8##x,_n11##y,z,c), I[748] = (T)(img)(_n9##x,_n11##y,z,c), I[749] = (T)(img)(_n10##x,_n11##y,z,c), I[750] = (T)(img)(_n11##x,_n11##y,z,c), I[751] = (T)(img)(_n12##x,_n11##y,z,c), I[752] = (T)(img)(_n13##x,_n11##y,z,c), I[753] = (T)(img)(_n14##x,_n11##y,z,c), \ - I[754] = (T)(img)(_p14##x,_n12##y,z,c), I[755] = (T)(img)(_p13##x,_n12##y,z,c), I[756] = (T)(img)(_p12##x,_n12##y,z,c), I[757] = (T)(img)(_p11##x,_n12##y,z,c), I[758] = (T)(img)(_p10##x,_n12##y,z,c), I[759] = (T)(img)(_p9##x,_n12##y,z,c), I[760] = (T)(img)(_p8##x,_n12##y,z,c), I[761] = (T)(img)(_p7##x,_n12##y,z,c), I[762] = (T)(img)(_p6##x,_n12##y,z,c), I[763] = (T)(img)(_p5##x,_n12##y,z,c), I[764] = (T)(img)(_p4##x,_n12##y,z,c), I[765] = (T)(img)(_p3##x,_n12##y,z,c), I[766] = (T)(img)(_p2##x,_n12##y,z,c), I[767] = (T)(img)(_p1##x,_n12##y,z,c), I[768] = (T)(img)(x,_n12##y,z,c), I[769] = (T)(img)(_n1##x,_n12##y,z,c), I[770] = (T)(img)(_n2##x,_n12##y,z,c), I[771] = (T)(img)(_n3##x,_n12##y,z,c), I[772] = (T)(img)(_n4##x,_n12##y,z,c), I[773] = (T)(img)(_n5##x,_n12##y,z,c), I[774] = (T)(img)(_n6##x,_n12##y,z,c), I[775] = (T)(img)(_n7##x,_n12##y,z,c), I[776] = (T)(img)(_n8##x,_n12##y,z,c), I[777] = (T)(img)(_n9##x,_n12##y,z,c), I[778] = (T)(img)(_n10##x,_n12##y,z,c), I[779] = (T)(img)(_n11##x,_n12##y,z,c), I[780] = (T)(img)(_n12##x,_n12##y,z,c), I[781] = (T)(img)(_n13##x,_n12##y,z,c), I[782] = (T)(img)(_n14##x,_n12##y,z,c), \ - I[783] = (T)(img)(_p14##x,_n13##y,z,c), I[784] = (T)(img)(_p13##x,_n13##y,z,c), I[785] = (T)(img)(_p12##x,_n13##y,z,c), I[786] = (T)(img)(_p11##x,_n13##y,z,c), I[787] = (T)(img)(_p10##x,_n13##y,z,c), I[788] = (T)(img)(_p9##x,_n13##y,z,c), I[789] = (T)(img)(_p8##x,_n13##y,z,c), I[790] = (T)(img)(_p7##x,_n13##y,z,c), I[791] = (T)(img)(_p6##x,_n13##y,z,c), I[792] = (T)(img)(_p5##x,_n13##y,z,c), I[793] = (T)(img)(_p4##x,_n13##y,z,c), I[794] = (T)(img)(_p3##x,_n13##y,z,c), I[795] = (T)(img)(_p2##x,_n13##y,z,c), I[796] = (T)(img)(_p1##x,_n13##y,z,c), I[797] = (T)(img)(x,_n13##y,z,c), I[798] = (T)(img)(_n1##x,_n13##y,z,c), I[799] = (T)(img)(_n2##x,_n13##y,z,c), I[800] = (T)(img)(_n3##x,_n13##y,z,c), I[801] = (T)(img)(_n4##x,_n13##y,z,c), I[802] = (T)(img)(_n5##x,_n13##y,z,c), I[803] = (T)(img)(_n6##x,_n13##y,z,c), I[804] = (T)(img)(_n7##x,_n13##y,z,c), I[805] = (T)(img)(_n8##x,_n13##y,z,c), I[806] = (T)(img)(_n9##x,_n13##y,z,c), I[807] = (T)(img)(_n10##x,_n13##y,z,c), I[808] = (T)(img)(_n11##x,_n13##y,z,c), I[809] = (T)(img)(_n12##x,_n13##y,z,c), I[810] = (T)(img)(_n13##x,_n13##y,z,c), I[811] = (T)(img)(_n14##x,_n13##y,z,c), \ - I[812] = (T)(img)(_p14##x,_n14##y,z,c), I[813] = (T)(img)(_p13##x,_n14##y,z,c), I[814] = (T)(img)(_p12##x,_n14##y,z,c), I[815] = (T)(img)(_p11##x,_n14##y,z,c), I[816] = (T)(img)(_p10##x,_n14##y,z,c), I[817] = (T)(img)(_p9##x,_n14##y,z,c), I[818] = (T)(img)(_p8##x,_n14##y,z,c), I[819] = (T)(img)(_p7##x,_n14##y,z,c), I[820] = (T)(img)(_p6##x,_n14##y,z,c), I[821] = (T)(img)(_p5##x,_n14##y,z,c), I[822] = (T)(img)(_p4##x,_n14##y,z,c), I[823] = (T)(img)(_p3##x,_n14##y,z,c), I[824] = (T)(img)(_p2##x,_n14##y,z,c), I[825] = (T)(img)(_p1##x,_n14##y,z,c), I[826] = (T)(img)(x,_n14##y,z,c), I[827] = (T)(img)(_n1##x,_n14##y,z,c), I[828] = (T)(img)(_n2##x,_n14##y,z,c), I[829] = (T)(img)(_n3##x,_n14##y,z,c), I[830] = (T)(img)(_n4##x,_n14##y,z,c), I[831] = (T)(img)(_n5##x,_n14##y,z,c), I[832] = (T)(img)(_n6##x,_n14##y,z,c), I[833] = (T)(img)(_n7##x,_n14##y,z,c), I[834] = (T)(img)(_n8##x,_n14##y,z,c), I[835] = (T)(img)(_n9##x,_n14##y,z,c), I[836] = (T)(img)(_n10##x,_n14##y,z,c), I[837] = (T)(img)(_n11##x,_n14##y,z,c), I[838] = (T)(img)(_n12##x,_n14##y,z,c), I[839] = (T)(img)(_n13##x,_n14##y,z,c), I[840] = (T)(img)(_n14##x,_n14##y,z,c); - -// Define 30x30 loop macros -//------------------------- -#define cimg_for30(bound,i) for (int i = 0, \ - _p14##i = 0, _p13##i = 0, _p12##i = 0, _p11##i = 0, _p10##i = 0, _p9##i = 0, _p8##i = 0, _p7##i = 0, _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6, \ - _n7##i = 7>=(int)(bound)?(int)(bound) - 1:7, \ - _n8##i = 8>=(int)(bound)?(int)(bound) - 1:8, \ - _n9##i = 9>=(int)(bound)?(int)(bound) - 1:9, \ - _n10##i = 10>=(int)(bound)?(int)(bound) - 1:10, \ - _n11##i = 11>=(int)(bound)?(int)(bound) - 1:11, \ - _n12##i = 12>=(int)(bound)?(int)(bound) - 1:12, \ - _n13##i = 13>=(int)(bound)?(int)(bound) - 1:13, \ - _n14##i = 14>=(int)(bound)?(int)(bound) - 1:14, \ - _n15##i = 15>=(int)(bound)?(int)(bound) - 1:15; \ - _n15##i<(int)(bound) || _n14##i==--_n15##i || _n13##i==--_n14##i || _n12##i==--_n13##i || _n11##i==--_n12##i || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n15##i = _n14##i = _n13##i = _n12##i = _n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p14##i = _p13##i, _p13##i = _p12##i, _p12##i = _p11##i, _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i, ++_n12##i, ++_n13##i, ++_n14##i, ++_n15##i) - -#define cimg_for30X(img,x) cimg_for30((img)._width,x) -#define cimg_for30Y(img,y) cimg_for30((img)._height,y) -#define cimg_for30Z(img,z) cimg_for30((img)._depth,z) -#define cimg_for30C(img,c) cimg_for30((img)._spectrum,c) -#define cimg_for30XY(img,x,y) cimg_for30Y(img,y) cimg_for30X(img,x) -#define cimg_for30XZ(img,x,z) cimg_for30Z(img,z) cimg_for30X(img,x) -#define cimg_for30XC(img,x,c) cimg_for30C(img,c) cimg_for30X(img,x) -#define cimg_for30YZ(img,y,z) cimg_for30Z(img,z) cimg_for30Y(img,y) -#define cimg_for30YC(img,y,c) cimg_for30C(img,c) cimg_for30Y(img,y) -#define cimg_for30ZC(img,z,c) cimg_for30C(img,c) cimg_for30Z(img,z) -#define cimg_for30XYZ(img,x,y,z) cimg_for30Z(img,z) cimg_for30XY(img,x,y) -#define cimg_for30XZC(img,x,z,c) cimg_for30C(img,c) cimg_for30XZ(img,x,z) -#define cimg_for30YZC(img,y,z,c) cimg_for30C(img,c) cimg_for30YZ(img,y,z) -#define cimg_for30XYZC(img,x,y,z,c) cimg_for30C(img,c) cimg_for30XYZ(img,x,y,z) - -#define cimg_for_in30(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p14##i = i - 14<0?0:i - 14, \ - _p13##i = i - 13<0?0:i - 13, \ - _p12##i = i - 12<0?0:i - 12, \ - _p11##i = i - 11<0?0:i - 11, \ - _p10##i = i - 10<0?0:i - 10, \ - _p9##i = i - 9<0?0:i - 9, \ - _p8##i = i - 8<0?0:i - 8, \ - _p7##i = i - 7<0?0:i - 7, \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6, \ - _n7##i = i + 7>=(int)(bound)?(int)(bound) - 1:i + 7, \ - _n8##i = i + 8>=(int)(bound)?(int)(bound) - 1:i + 8, \ - _n9##i = i + 9>=(int)(bound)?(int)(bound) - 1:i + 9, \ - _n10##i = i + 10>=(int)(bound)?(int)(bound) - 1:i + 10, \ - _n11##i = i + 11>=(int)(bound)?(int)(bound) - 1:i + 11, \ - _n12##i = i + 12>=(int)(bound)?(int)(bound) - 1:i + 12, \ - _n13##i = i + 13>=(int)(bound)?(int)(bound) - 1:i + 13, \ - _n14##i = i + 14>=(int)(bound)?(int)(bound) - 1:i + 14, \ - _n15##i = i + 15>=(int)(bound)?(int)(bound) - 1:i + 15; \ - i<=(int)(i1) && (_n15##i<(int)(bound) || _n14##i==--_n15##i || _n13##i==--_n14##i || _n12##i==--_n13##i || _n11##i==--_n12##i || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n15##i = _n14##i = _n13##i = _n12##i = _n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p14##i = _p13##i, _p13##i = _p12##i, _p12##i = _p11##i, _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i, ++_n12##i, ++_n13##i, ++_n14##i, ++_n15##i) - -#define cimg_for_in30X(img,x0,x1,x) cimg_for_in30((img)._width,x0,x1,x) -#define cimg_for_in30Y(img,y0,y1,y) cimg_for_in30((img)._height,y0,y1,y) -#define cimg_for_in30Z(img,z0,z1,z) cimg_for_in30((img)._depth,z0,z1,z) -#define cimg_for_in30C(img,c0,c1,c) cimg_for_in30((img)._spectrum,c0,c1,c) -#define cimg_for_in30XY(img,x0,y0,x1,y1,x,y) cimg_for_in30Y(img,y0,y1,y) cimg_for_in30X(img,x0,x1,x) -#define cimg_for_in30XZ(img,x0,z0,x1,z1,x,z) cimg_for_in30Z(img,z0,z1,z) cimg_for_in30X(img,x0,x1,x) -#define cimg_for_in30XC(img,x0,c0,x1,c1,x,c) cimg_for_in30C(img,c0,c1,c) cimg_for_in30X(img,x0,x1,x) -#define cimg_for_in30YZ(img,y0,z0,y1,z1,y,z) cimg_for_in30Z(img,z0,z1,z) cimg_for_in30Y(img,y0,y1,y) -#define cimg_for_in30YC(img,y0,c0,y1,c1,y,c) cimg_for_in30C(img,c0,c1,c) cimg_for_in30Y(img,y0,y1,y) -#define cimg_for_in30ZC(img,z0,c0,z1,c1,z,c) cimg_for_in30C(img,c0,c1,c) cimg_for_in30Z(img,z0,z1,z) -#define cimg_for_in30XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in30Z(img,z0,z1,z) cimg_for_in30XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in30XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in30C(img,c0,c1,c) cimg_for_in30XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in30YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in30C(img,c0,c1,c) cimg_for_in30YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in30XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in30C(img,c0,c1,c) cimg_for_in30XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for30x30(img,x,y,z,c,I,T) \ - cimg_for30((img)._height,y) for (int x = 0, \ - _p14##x = 0, _p13##x = 0, _p12##x = 0, _p11##x = 0, _p10##x = 0, _p9##x = 0, _p8##x = 0, _p7##x = 0, _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = 6>=((img)._width)?(img).width() - 1:6, \ - _n7##x = 7>=((img)._width)?(img).width() - 1:7, \ - _n8##x = 8>=((img)._width)?(img).width() - 1:8, \ - _n9##x = 9>=((img)._width)?(img).width() - 1:9, \ - _n10##x = 10>=((img)._width)?(img).width() - 1:10, \ - _n11##x = 11>=((img)._width)?(img).width() - 1:11, \ - _n12##x = 12>=((img)._width)?(img).width() - 1:12, \ - _n13##x = 13>=((img)._width)?(img).width() - 1:13, \ - _n14##x = 14>=((img)._width)?(img).width() - 1:14, \ - _n15##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = I[7] = I[8] = I[9] = I[10] = I[11] = I[12] = I[13] = I[14] = (T)(img)(0,_p14##y,z,c)), \ - (I[30] = I[31] = I[32] = I[33] = I[34] = I[35] = I[36] = I[37] = I[38] = I[39] = I[40] = I[41] = I[42] = I[43] = I[44] = (T)(img)(0,_p13##y,z,c)), \ - (I[60] = I[61] = I[62] = I[63] = I[64] = I[65] = I[66] = I[67] = I[68] = I[69] = I[70] = I[71] = I[72] = I[73] = I[74] = (T)(img)(0,_p12##y,z,c)), \ - (I[90] = I[91] = I[92] = I[93] = I[94] = I[95] = I[96] = I[97] = I[98] = I[99] = I[100] = I[101] = I[102] = I[103] = I[104] = (T)(img)(0,_p11##y,z,c)), \ - (I[120] = I[121] = I[122] = I[123] = I[124] = I[125] = I[126] = I[127] = I[128] = I[129] = I[130] = I[131] = I[132] = I[133] = I[134] = (T)(img)(0,_p10##y,z,c)), \ - (I[150] = I[151] = I[152] = I[153] = I[154] = I[155] = I[156] = I[157] = I[158] = I[159] = I[160] = I[161] = I[162] = I[163] = I[164] = (T)(img)(0,_p9##y,z,c)), \ - (I[180] = I[181] = I[182] = I[183] = I[184] = I[185] = I[186] = I[187] = I[188] = I[189] = I[190] = I[191] = I[192] = I[193] = I[194] = (T)(img)(0,_p8##y,z,c)), \ - (I[210] = I[211] = I[212] = I[213] = I[214] = I[215] = I[216] = I[217] = I[218] = I[219] = I[220] = I[221] = I[222] = I[223] = I[224] = (T)(img)(0,_p7##y,z,c)), \ - (I[240] = I[241] = I[242] = I[243] = I[244] = I[245] = I[246] = I[247] = I[248] = I[249] = I[250] = I[251] = I[252] = I[253] = I[254] = (T)(img)(0,_p6##y,z,c)), \ - (I[270] = I[271] = I[272] = I[273] = I[274] = I[275] = I[276] = I[277] = I[278] = I[279] = I[280] = I[281] = I[282] = I[283] = I[284] = (T)(img)(0,_p5##y,z,c)), \ - (I[300] = I[301] = I[302] = I[303] = I[304] = I[305] = I[306] = I[307] = I[308] = I[309] = I[310] = I[311] = I[312] = I[313] = I[314] = (T)(img)(0,_p4##y,z,c)), \ - (I[330] = I[331] = I[332] = I[333] = I[334] = I[335] = I[336] = I[337] = I[338] = I[339] = I[340] = I[341] = I[342] = I[343] = I[344] = (T)(img)(0,_p3##y,z,c)), \ - (I[360] = I[361] = I[362] = I[363] = I[364] = I[365] = I[366] = I[367] = I[368] = I[369] = I[370] = I[371] = I[372] = I[373] = I[374] = (T)(img)(0,_p2##y,z,c)), \ - (I[390] = I[391] = I[392] = I[393] = I[394] = I[395] = I[396] = I[397] = I[398] = I[399] = I[400] = I[401] = I[402] = I[403] = I[404] = (T)(img)(0,_p1##y,z,c)), \ - (I[420] = I[421] = I[422] = I[423] = I[424] = I[425] = I[426] = I[427] = I[428] = I[429] = I[430] = I[431] = I[432] = I[433] = I[434] = (T)(img)(0,y,z,c)), \ - (I[450] = I[451] = I[452] = I[453] = I[454] = I[455] = I[456] = I[457] = I[458] = I[459] = I[460] = I[461] = I[462] = I[463] = I[464] = (T)(img)(0,_n1##y,z,c)), \ - (I[480] = I[481] = I[482] = I[483] = I[484] = I[485] = I[486] = I[487] = I[488] = I[489] = I[490] = I[491] = I[492] = I[493] = I[494] = (T)(img)(0,_n2##y,z,c)), \ - (I[510] = I[511] = I[512] = I[513] = I[514] = I[515] = I[516] = I[517] = I[518] = I[519] = I[520] = I[521] = I[522] = I[523] = I[524] = (T)(img)(0,_n3##y,z,c)), \ - (I[540] = I[541] = I[542] = I[543] = I[544] = I[545] = I[546] = I[547] = I[548] = I[549] = I[550] = I[551] = I[552] = I[553] = I[554] = (T)(img)(0,_n4##y,z,c)), \ - (I[570] = I[571] = I[572] = I[573] = I[574] = I[575] = I[576] = I[577] = I[578] = I[579] = I[580] = I[581] = I[582] = I[583] = I[584] = (T)(img)(0,_n5##y,z,c)), \ - (I[600] = I[601] = I[602] = I[603] = I[604] = I[605] = I[606] = I[607] = I[608] = I[609] = I[610] = I[611] = I[612] = I[613] = I[614] = (T)(img)(0,_n6##y,z,c)), \ - (I[630] = I[631] = I[632] = I[633] = I[634] = I[635] = I[636] = I[637] = I[638] = I[639] = I[640] = I[641] = I[642] = I[643] = I[644] = (T)(img)(0,_n7##y,z,c)), \ - (I[660] = I[661] = I[662] = I[663] = I[664] = I[665] = I[666] = I[667] = I[668] = I[669] = I[670] = I[671] = I[672] = I[673] = I[674] = (T)(img)(0,_n8##y,z,c)), \ - (I[690] = I[691] = I[692] = I[693] = I[694] = I[695] = I[696] = I[697] = I[698] = I[699] = I[700] = I[701] = I[702] = I[703] = I[704] = (T)(img)(0,_n9##y,z,c)), \ - (I[720] = I[721] = I[722] = I[723] = I[724] = I[725] = I[726] = I[727] = I[728] = I[729] = I[730] = I[731] = I[732] = I[733] = I[734] = (T)(img)(0,_n10##y,z,c)), \ - (I[750] = I[751] = I[752] = I[753] = I[754] = I[755] = I[756] = I[757] = I[758] = I[759] = I[760] = I[761] = I[762] = I[763] = I[764] = (T)(img)(0,_n11##y,z,c)), \ - (I[780] = I[781] = I[782] = I[783] = I[784] = I[785] = I[786] = I[787] = I[788] = I[789] = I[790] = I[791] = I[792] = I[793] = I[794] = (T)(img)(0,_n12##y,z,c)), \ - (I[810] = I[811] = I[812] = I[813] = I[814] = I[815] = I[816] = I[817] = I[818] = I[819] = I[820] = I[821] = I[822] = I[823] = I[824] = (T)(img)(0,_n13##y,z,c)), \ - (I[840] = I[841] = I[842] = I[843] = I[844] = I[845] = I[846] = I[847] = I[848] = I[849] = I[850] = I[851] = I[852] = I[853] = I[854] = (T)(img)(0,_n14##y,z,c)), \ - (I[870] = I[871] = I[872] = I[873] = I[874] = I[875] = I[876] = I[877] = I[878] = I[879] = I[880] = I[881] = I[882] = I[883] = I[884] = (T)(img)(0,_n15##y,z,c)), \ - (I[15] = (T)(img)(_n1##x,_p14##y,z,c)), \ - (I[45] = (T)(img)(_n1##x,_p13##y,z,c)), \ - (I[75] = (T)(img)(_n1##x,_p12##y,z,c)), \ - (I[105] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[135] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[165] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[195] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[225] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[255] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[285] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[315] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[345] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[375] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[405] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[435] = (T)(img)(_n1##x,y,z,c)), \ - (I[465] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[495] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[525] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[555] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[585] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[615] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[645] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[675] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[705] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[735] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[765] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[795] = (T)(img)(_n1##x,_n12##y,z,c)), \ - (I[825] = (T)(img)(_n1##x,_n13##y,z,c)), \ - (I[855] = (T)(img)(_n1##x,_n14##y,z,c)), \ - (I[885] = (T)(img)(_n1##x,_n15##y,z,c)), \ - (I[16] = (T)(img)(_n2##x,_p14##y,z,c)), \ - (I[46] = (T)(img)(_n2##x,_p13##y,z,c)), \ - (I[76] = (T)(img)(_n2##x,_p12##y,z,c)), \ - (I[106] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[136] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[166] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[196] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[226] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[256] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[286] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[316] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[346] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[376] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[406] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[436] = (T)(img)(_n2##x,y,z,c)), \ - (I[466] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[496] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[526] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[556] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[586] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[616] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[646] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[676] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[706] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[736] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[766] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[796] = (T)(img)(_n2##x,_n12##y,z,c)), \ - (I[826] = (T)(img)(_n2##x,_n13##y,z,c)), \ - (I[856] = (T)(img)(_n2##x,_n14##y,z,c)), \ - (I[886] = (T)(img)(_n2##x,_n15##y,z,c)), \ - (I[17] = (T)(img)(_n3##x,_p14##y,z,c)), \ - (I[47] = (T)(img)(_n3##x,_p13##y,z,c)), \ - (I[77] = (T)(img)(_n3##x,_p12##y,z,c)), \ - (I[107] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[137] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[167] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[197] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[227] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[257] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[287] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[317] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[347] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[377] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[407] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[437] = (T)(img)(_n3##x,y,z,c)), \ - (I[467] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[497] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[527] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[557] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[587] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[617] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[647] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[677] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[707] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[737] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[767] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[797] = (T)(img)(_n3##x,_n12##y,z,c)), \ - (I[827] = (T)(img)(_n3##x,_n13##y,z,c)), \ - (I[857] = (T)(img)(_n3##x,_n14##y,z,c)), \ - (I[887] = (T)(img)(_n3##x,_n15##y,z,c)), \ - (I[18] = (T)(img)(_n4##x,_p14##y,z,c)), \ - (I[48] = (T)(img)(_n4##x,_p13##y,z,c)), \ - (I[78] = (T)(img)(_n4##x,_p12##y,z,c)), \ - (I[108] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[138] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[168] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[198] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[228] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[258] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[288] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[318] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[348] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[378] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[408] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[438] = (T)(img)(_n4##x,y,z,c)), \ - (I[468] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[498] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[528] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[558] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[588] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[618] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[648] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[678] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[708] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[738] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[768] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[798] = (T)(img)(_n4##x,_n12##y,z,c)), \ - (I[828] = (T)(img)(_n4##x,_n13##y,z,c)), \ - (I[858] = (T)(img)(_n4##x,_n14##y,z,c)), \ - (I[888] = (T)(img)(_n4##x,_n15##y,z,c)), \ - (I[19] = (T)(img)(_n5##x,_p14##y,z,c)), \ - (I[49] = (T)(img)(_n5##x,_p13##y,z,c)), \ - (I[79] = (T)(img)(_n5##x,_p12##y,z,c)), \ - (I[109] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[139] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[169] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[199] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[229] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[259] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[289] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[319] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[349] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[379] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[409] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[439] = (T)(img)(_n5##x,y,z,c)), \ - (I[469] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[499] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[529] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[559] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[589] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[619] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[649] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[679] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[709] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[739] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[769] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[799] = (T)(img)(_n5##x,_n12##y,z,c)), \ - (I[829] = (T)(img)(_n5##x,_n13##y,z,c)), \ - (I[859] = (T)(img)(_n5##x,_n14##y,z,c)), \ - (I[889] = (T)(img)(_n5##x,_n15##y,z,c)), \ - (I[20] = (T)(img)(_n6##x,_p14##y,z,c)), \ - (I[50] = (T)(img)(_n6##x,_p13##y,z,c)), \ - (I[80] = (T)(img)(_n6##x,_p12##y,z,c)), \ - (I[110] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[140] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[170] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[200] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[230] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[260] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[290] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[320] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[350] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[380] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[410] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[440] = (T)(img)(_n6##x,y,z,c)), \ - (I[470] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[500] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[530] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[560] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[590] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[620] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[650] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[680] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[710] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[740] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[770] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[800] = (T)(img)(_n6##x,_n12##y,z,c)), \ - (I[830] = (T)(img)(_n6##x,_n13##y,z,c)), \ - (I[860] = (T)(img)(_n6##x,_n14##y,z,c)), \ - (I[890] = (T)(img)(_n6##x,_n15##y,z,c)), \ - (I[21] = (T)(img)(_n7##x,_p14##y,z,c)), \ - (I[51] = (T)(img)(_n7##x,_p13##y,z,c)), \ - (I[81] = (T)(img)(_n7##x,_p12##y,z,c)), \ - (I[111] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[141] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[171] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[201] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[231] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[261] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[291] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[321] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[351] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[381] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[411] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[441] = (T)(img)(_n7##x,y,z,c)), \ - (I[471] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[501] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[531] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[561] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[591] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[621] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[651] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[681] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[711] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[741] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[771] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[801] = (T)(img)(_n7##x,_n12##y,z,c)), \ - (I[831] = (T)(img)(_n7##x,_n13##y,z,c)), \ - (I[861] = (T)(img)(_n7##x,_n14##y,z,c)), \ - (I[891] = (T)(img)(_n7##x,_n15##y,z,c)), \ - (I[22] = (T)(img)(_n8##x,_p14##y,z,c)), \ - (I[52] = (T)(img)(_n8##x,_p13##y,z,c)), \ - (I[82] = (T)(img)(_n8##x,_p12##y,z,c)), \ - (I[112] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[142] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[172] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[202] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[232] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[262] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[292] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[322] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[352] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[382] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[412] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[442] = (T)(img)(_n8##x,y,z,c)), \ - (I[472] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[502] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[532] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[562] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[592] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[622] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[652] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[682] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[712] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[742] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[772] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[802] = (T)(img)(_n8##x,_n12##y,z,c)), \ - (I[832] = (T)(img)(_n8##x,_n13##y,z,c)), \ - (I[862] = (T)(img)(_n8##x,_n14##y,z,c)), \ - (I[892] = (T)(img)(_n8##x,_n15##y,z,c)), \ - (I[23] = (T)(img)(_n9##x,_p14##y,z,c)), \ - (I[53] = (T)(img)(_n9##x,_p13##y,z,c)), \ - (I[83] = (T)(img)(_n9##x,_p12##y,z,c)), \ - (I[113] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[143] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[173] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[203] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[233] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[263] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[293] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[323] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[353] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[383] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[413] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[443] = (T)(img)(_n9##x,y,z,c)), \ - (I[473] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[503] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[533] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[563] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[593] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[623] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[653] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[683] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[713] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[743] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[773] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[803] = (T)(img)(_n9##x,_n12##y,z,c)), \ - (I[833] = (T)(img)(_n9##x,_n13##y,z,c)), \ - (I[863] = (T)(img)(_n9##x,_n14##y,z,c)), \ - (I[893] = (T)(img)(_n9##x,_n15##y,z,c)), \ - (I[24] = (T)(img)(_n10##x,_p14##y,z,c)), \ - (I[54] = (T)(img)(_n10##x,_p13##y,z,c)), \ - (I[84] = (T)(img)(_n10##x,_p12##y,z,c)), \ - (I[114] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[144] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[174] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[204] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[234] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[264] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[294] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[324] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[354] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[384] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[414] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[444] = (T)(img)(_n10##x,y,z,c)), \ - (I[474] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[504] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[534] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[564] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[594] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[624] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[654] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[684] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[714] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[744] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[774] = (T)(img)(_n10##x,_n11##y,z,c)), \ - (I[804] = (T)(img)(_n10##x,_n12##y,z,c)), \ - (I[834] = (T)(img)(_n10##x,_n13##y,z,c)), \ - (I[864] = (T)(img)(_n10##x,_n14##y,z,c)), \ - (I[894] = (T)(img)(_n10##x,_n15##y,z,c)), \ - (I[25] = (T)(img)(_n11##x,_p14##y,z,c)), \ - (I[55] = (T)(img)(_n11##x,_p13##y,z,c)), \ - (I[85] = (T)(img)(_n11##x,_p12##y,z,c)), \ - (I[115] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[145] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[175] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[205] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[235] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[265] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[295] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[325] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[355] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[385] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[415] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[445] = (T)(img)(_n11##x,y,z,c)), \ - (I[475] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[505] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[535] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[565] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[595] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[625] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[655] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[685] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[715] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[745] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[775] = (T)(img)(_n11##x,_n11##y,z,c)), \ - (I[805] = (T)(img)(_n11##x,_n12##y,z,c)), \ - (I[835] = (T)(img)(_n11##x,_n13##y,z,c)), \ - (I[865] = (T)(img)(_n11##x,_n14##y,z,c)), \ - (I[895] = (T)(img)(_n11##x,_n15##y,z,c)), \ - (I[26] = (T)(img)(_n12##x,_p14##y,z,c)), \ - (I[56] = (T)(img)(_n12##x,_p13##y,z,c)), \ - (I[86] = (T)(img)(_n12##x,_p12##y,z,c)), \ - (I[116] = (T)(img)(_n12##x,_p11##y,z,c)), \ - (I[146] = (T)(img)(_n12##x,_p10##y,z,c)), \ - (I[176] = (T)(img)(_n12##x,_p9##y,z,c)), \ - (I[206] = (T)(img)(_n12##x,_p8##y,z,c)), \ - (I[236] = (T)(img)(_n12##x,_p7##y,z,c)), \ - (I[266] = (T)(img)(_n12##x,_p6##y,z,c)), \ - (I[296] = (T)(img)(_n12##x,_p5##y,z,c)), \ - (I[326] = (T)(img)(_n12##x,_p4##y,z,c)), \ - (I[356] = (T)(img)(_n12##x,_p3##y,z,c)), \ - (I[386] = (T)(img)(_n12##x,_p2##y,z,c)), \ - (I[416] = (T)(img)(_n12##x,_p1##y,z,c)), \ - (I[446] = (T)(img)(_n12##x,y,z,c)), \ - (I[476] = (T)(img)(_n12##x,_n1##y,z,c)), \ - (I[506] = (T)(img)(_n12##x,_n2##y,z,c)), \ - (I[536] = (T)(img)(_n12##x,_n3##y,z,c)), \ - (I[566] = (T)(img)(_n12##x,_n4##y,z,c)), \ - (I[596] = (T)(img)(_n12##x,_n5##y,z,c)), \ - (I[626] = (T)(img)(_n12##x,_n6##y,z,c)), \ - (I[656] = (T)(img)(_n12##x,_n7##y,z,c)), \ - (I[686] = (T)(img)(_n12##x,_n8##y,z,c)), \ - (I[716] = (T)(img)(_n12##x,_n9##y,z,c)), \ - (I[746] = (T)(img)(_n12##x,_n10##y,z,c)), \ - (I[776] = (T)(img)(_n12##x,_n11##y,z,c)), \ - (I[806] = (T)(img)(_n12##x,_n12##y,z,c)), \ - (I[836] = (T)(img)(_n12##x,_n13##y,z,c)), \ - (I[866] = (T)(img)(_n12##x,_n14##y,z,c)), \ - (I[896] = (T)(img)(_n12##x,_n15##y,z,c)), \ - (I[27] = (T)(img)(_n13##x,_p14##y,z,c)), \ - (I[57] = (T)(img)(_n13##x,_p13##y,z,c)), \ - (I[87] = (T)(img)(_n13##x,_p12##y,z,c)), \ - (I[117] = (T)(img)(_n13##x,_p11##y,z,c)), \ - (I[147] = (T)(img)(_n13##x,_p10##y,z,c)), \ - (I[177] = (T)(img)(_n13##x,_p9##y,z,c)), \ - (I[207] = (T)(img)(_n13##x,_p8##y,z,c)), \ - (I[237] = (T)(img)(_n13##x,_p7##y,z,c)), \ - (I[267] = (T)(img)(_n13##x,_p6##y,z,c)), \ - (I[297] = (T)(img)(_n13##x,_p5##y,z,c)), \ - (I[327] = (T)(img)(_n13##x,_p4##y,z,c)), \ - (I[357] = (T)(img)(_n13##x,_p3##y,z,c)), \ - (I[387] = (T)(img)(_n13##x,_p2##y,z,c)), \ - (I[417] = (T)(img)(_n13##x,_p1##y,z,c)), \ - (I[447] = (T)(img)(_n13##x,y,z,c)), \ - (I[477] = (T)(img)(_n13##x,_n1##y,z,c)), \ - (I[507] = (T)(img)(_n13##x,_n2##y,z,c)), \ - (I[537] = (T)(img)(_n13##x,_n3##y,z,c)), \ - (I[567] = (T)(img)(_n13##x,_n4##y,z,c)), \ - (I[597] = (T)(img)(_n13##x,_n5##y,z,c)), \ - (I[627] = (T)(img)(_n13##x,_n6##y,z,c)), \ - (I[657] = (T)(img)(_n13##x,_n7##y,z,c)), \ - (I[687] = (T)(img)(_n13##x,_n8##y,z,c)), \ - (I[717] = (T)(img)(_n13##x,_n9##y,z,c)), \ - (I[747] = (T)(img)(_n13##x,_n10##y,z,c)), \ - (I[777] = (T)(img)(_n13##x,_n11##y,z,c)), \ - (I[807] = (T)(img)(_n13##x,_n12##y,z,c)), \ - (I[837] = (T)(img)(_n13##x,_n13##y,z,c)), \ - (I[867] = (T)(img)(_n13##x,_n14##y,z,c)), \ - (I[897] = (T)(img)(_n13##x,_n15##y,z,c)), \ - (I[28] = (T)(img)(_n14##x,_p14##y,z,c)), \ - (I[58] = (T)(img)(_n14##x,_p13##y,z,c)), \ - (I[88] = (T)(img)(_n14##x,_p12##y,z,c)), \ - (I[118] = (T)(img)(_n14##x,_p11##y,z,c)), \ - (I[148] = (T)(img)(_n14##x,_p10##y,z,c)), \ - (I[178] = (T)(img)(_n14##x,_p9##y,z,c)), \ - (I[208] = (T)(img)(_n14##x,_p8##y,z,c)), \ - (I[238] = (T)(img)(_n14##x,_p7##y,z,c)), \ - (I[268] = (T)(img)(_n14##x,_p6##y,z,c)), \ - (I[298] = (T)(img)(_n14##x,_p5##y,z,c)), \ - (I[328] = (T)(img)(_n14##x,_p4##y,z,c)), \ - (I[358] = (T)(img)(_n14##x,_p3##y,z,c)), \ - (I[388] = (T)(img)(_n14##x,_p2##y,z,c)), \ - (I[418] = (T)(img)(_n14##x,_p1##y,z,c)), \ - (I[448] = (T)(img)(_n14##x,y,z,c)), \ - (I[478] = (T)(img)(_n14##x,_n1##y,z,c)), \ - (I[508] = (T)(img)(_n14##x,_n2##y,z,c)), \ - (I[538] = (T)(img)(_n14##x,_n3##y,z,c)), \ - (I[568] = (T)(img)(_n14##x,_n4##y,z,c)), \ - (I[598] = (T)(img)(_n14##x,_n5##y,z,c)), \ - (I[628] = (T)(img)(_n14##x,_n6##y,z,c)), \ - (I[658] = (T)(img)(_n14##x,_n7##y,z,c)), \ - (I[688] = (T)(img)(_n14##x,_n8##y,z,c)), \ - (I[718] = (T)(img)(_n14##x,_n9##y,z,c)), \ - (I[748] = (T)(img)(_n14##x,_n10##y,z,c)), \ - (I[778] = (T)(img)(_n14##x,_n11##y,z,c)), \ - (I[808] = (T)(img)(_n14##x,_n12##y,z,c)), \ - (I[838] = (T)(img)(_n14##x,_n13##y,z,c)), \ - (I[868] = (T)(img)(_n14##x,_n14##y,z,c)), \ - (I[898] = (T)(img)(_n14##x,_n15##y,z,c)), \ - 15>=((img)._width)?(img).width() - 1:15); \ - (_n15##x<(img).width() && ( \ - (I[29] = (T)(img)(_n15##x,_p14##y,z,c)), \ - (I[59] = (T)(img)(_n15##x,_p13##y,z,c)), \ - (I[89] = (T)(img)(_n15##x,_p12##y,z,c)), \ - (I[119] = (T)(img)(_n15##x,_p11##y,z,c)), \ - (I[149] = (T)(img)(_n15##x,_p10##y,z,c)), \ - (I[179] = (T)(img)(_n15##x,_p9##y,z,c)), \ - (I[209] = (T)(img)(_n15##x,_p8##y,z,c)), \ - (I[239] = (T)(img)(_n15##x,_p7##y,z,c)), \ - (I[269] = (T)(img)(_n15##x,_p6##y,z,c)), \ - (I[299] = (T)(img)(_n15##x,_p5##y,z,c)), \ - (I[329] = (T)(img)(_n15##x,_p4##y,z,c)), \ - (I[359] = (T)(img)(_n15##x,_p3##y,z,c)), \ - (I[389] = (T)(img)(_n15##x,_p2##y,z,c)), \ - (I[419] = (T)(img)(_n15##x,_p1##y,z,c)), \ - (I[449] = (T)(img)(_n15##x,y,z,c)), \ - (I[479] = (T)(img)(_n15##x,_n1##y,z,c)), \ - (I[509] = (T)(img)(_n15##x,_n2##y,z,c)), \ - (I[539] = (T)(img)(_n15##x,_n3##y,z,c)), \ - (I[569] = (T)(img)(_n15##x,_n4##y,z,c)), \ - (I[599] = (T)(img)(_n15##x,_n5##y,z,c)), \ - (I[629] = (T)(img)(_n15##x,_n6##y,z,c)), \ - (I[659] = (T)(img)(_n15##x,_n7##y,z,c)), \ - (I[689] = (T)(img)(_n15##x,_n8##y,z,c)), \ - (I[719] = (T)(img)(_n15##x,_n9##y,z,c)), \ - (I[749] = (T)(img)(_n15##x,_n10##y,z,c)), \ - (I[779] = (T)(img)(_n15##x,_n11##y,z,c)), \ - (I[809] = (T)(img)(_n15##x,_n12##y,z,c)), \ - (I[839] = (T)(img)(_n15##x,_n13##y,z,c)), \ - (I[869] = (T)(img)(_n15##x,_n14##y,z,c)), \ - (I[899] = (T)(img)(_n15##x,_n15##y,z,c)),1)) || \ - _n14##x==--_n15##x || _n13##x==--_n14##x || _n12##x==--_n13##x || _n11##x==--_n12##x || _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n15##x = _n14##x = _n13##x = _n12##x = _n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], \ - I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], \ - I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], \ - I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], \ - I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], \ - I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], \ - I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], \ - I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], \ - I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], \ - I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], \ - I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], \ - I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], \ - I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], \ - I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], I[415] = I[416], I[416] = I[417], I[417] = I[418], I[418] = I[419], \ - I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], I[447] = I[448], I[448] = I[449], \ - I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], I[463] = I[464], I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], \ - I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], I[493] = I[494], I[494] = I[495], I[495] = I[496], I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], I[503] = I[504], I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], \ - I[510] = I[511], I[511] = I[512], I[512] = I[513], I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], I[519] = I[520], I[520] = I[521], I[521] = I[522], I[522] = I[523], I[523] = I[524], I[524] = I[525], I[525] = I[526], I[526] = I[527], I[527] = I[528], I[528] = I[529], I[529] = I[530], I[530] = I[531], I[531] = I[532], I[532] = I[533], I[533] = I[534], I[534] = I[535], I[535] = I[536], I[536] = I[537], I[537] = I[538], I[538] = I[539], \ - I[540] = I[541], I[541] = I[542], I[542] = I[543], I[543] = I[544], I[544] = I[545], I[545] = I[546], I[546] = I[547], I[547] = I[548], I[548] = I[549], I[549] = I[550], I[550] = I[551], I[551] = I[552], I[552] = I[553], I[553] = I[554], I[554] = I[555], I[555] = I[556], I[556] = I[557], I[557] = I[558], I[558] = I[559], I[559] = I[560], I[560] = I[561], I[561] = I[562], I[562] = I[563], I[563] = I[564], I[564] = I[565], I[565] = I[566], I[566] = I[567], I[567] = I[568], I[568] = I[569], \ - I[570] = I[571], I[571] = I[572], I[572] = I[573], I[573] = I[574], I[574] = I[575], I[575] = I[576], I[576] = I[577], I[577] = I[578], I[578] = I[579], I[579] = I[580], I[580] = I[581], I[581] = I[582], I[582] = I[583], I[583] = I[584], I[584] = I[585], I[585] = I[586], I[586] = I[587], I[587] = I[588], I[588] = I[589], I[589] = I[590], I[590] = I[591], I[591] = I[592], I[592] = I[593], I[593] = I[594], I[594] = I[595], I[595] = I[596], I[596] = I[597], I[597] = I[598], I[598] = I[599], \ - I[600] = I[601], I[601] = I[602], I[602] = I[603], I[603] = I[604], I[604] = I[605], I[605] = I[606], I[606] = I[607], I[607] = I[608], I[608] = I[609], I[609] = I[610], I[610] = I[611], I[611] = I[612], I[612] = I[613], I[613] = I[614], I[614] = I[615], I[615] = I[616], I[616] = I[617], I[617] = I[618], I[618] = I[619], I[619] = I[620], I[620] = I[621], I[621] = I[622], I[622] = I[623], I[623] = I[624], I[624] = I[625], I[625] = I[626], I[626] = I[627], I[627] = I[628], I[628] = I[629], \ - I[630] = I[631], I[631] = I[632], I[632] = I[633], I[633] = I[634], I[634] = I[635], I[635] = I[636], I[636] = I[637], I[637] = I[638], I[638] = I[639], I[639] = I[640], I[640] = I[641], I[641] = I[642], I[642] = I[643], I[643] = I[644], I[644] = I[645], I[645] = I[646], I[646] = I[647], I[647] = I[648], I[648] = I[649], I[649] = I[650], I[650] = I[651], I[651] = I[652], I[652] = I[653], I[653] = I[654], I[654] = I[655], I[655] = I[656], I[656] = I[657], I[657] = I[658], I[658] = I[659], \ - I[660] = I[661], I[661] = I[662], I[662] = I[663], I[663] = I[664], I[664] = I[665], I[665] = I[666], I[666] = I[667], I[667] = I[668], I[668] = I[669], I[669] = I[670], I[670] = I[671], I[671] = I[672], I[672] = I[673], I[673] = I[674], I[674] = I[675], I[675] = I[676], I[676] = I[677], I[677] = I[678], I[678] = I[679], I[679] = I[680], I[680] = I[681], I[681] = I[682], I[682] = I[683], I[683] = I[684], I[684] = I[685], I[685] = I[686], I[686] = I[687], I[687] = I[688], I[688] = I[689], \ - I[690] = I[691], I[691] = I[692], I[692] = I[693], I[693] = I[694], I[694] = I[695], I[695] = I[696], I[696] = I[697], I[697] = I[698], I[698] = I[699], I[699] = I[700], I[700] = I[701], I[701] = I[702], I[702] = I[703], I[703] = I[704], I[704] = I[705], I[705] = I[706], I[706] = I[707], I[707] = I[708], I[708] = I[709], I[709] = I[710], I[710] = I[711], I[711] = I[712], I[712] = I[713], I[713] = I[714], I[714] = I[715], I[715] = I[716], I[716] = I[717], I[717] = I[718], I[718] = I[719], \ - I[720] = I[721], I[721] = I[722], I[722] = I[723], I[723] = I[724], I[724] = I[725], I[725] = I[726], I[726] = I[727], I[727] = I[728], I[728] = I[729], I[729] = I[730], I[730] = I[731], I[731] = I[732], I[732] = I[733], I[733] = I[734], I[734] = I[735], I[735] = I[736], I[736] = I[737], I[737] = I[738], I[738] = I[739], I[739] = I[740], I[740] = I[741], I[741] = I[742], I[742] = I[743], I[743] = I[744], I[744] = I[745], I[745] = I[746], I[746] = I[747], I[747] = I[748], I[748] = I[749], \ - I[750] = I[751], I[751] = I[752], I[752] = I[753], I[753] = I[754], I[754] = I[755], I[755] = I[756], I[756] = I[757], I[757] = I[758], I[758] = I[759], I[759] = I[760], I[760] = I[761], I[761] = I[762], I[762] = I[763], I[763] = I[764], I[764] = I[765], I[765] = I[766], I[766] = I[767], I[767] = I[768], I[768] = I[769], I[769] = I[770], I[770] = I[771], I[771] = I[772], I[772] = I[773], I[773] = I[774], I[774] = I[775], I[775] = I[776], I[776] = I[777], I[777] = I[778], I[778] = I[779], \ - I[780] = I[781], I[781] = I[782], I[782] = I[783], I[783] = I[784], I[784] = I[785], I[785] = I[786], I[786] = I[787], I[787] = I[788], I[788] = I[789], I[789] = I[790], I[790] = I[791], I[791] = I[792], I[792] = I[793], I[793] = I[794], I[794] = I[795], I[795] = I[796], I[796] = I[797], I[797] = I[798], I[798] = I[799], I[799] = I[800], I[800] = I[801], I[801] = I[802], I[802] = I[803], I[803] = I[804], I[804] = I[805], I[805] = I[806], I[806] = I[807], I[807] = I[808], I[808] = I[809], \ - I[810] = I[811], I[811] = I[812], I[812] = I[813], I[813] = I[814], I[814] = I[815], I[815] = I[816], I[816] = I[817], I[817] = I[818], I[818] = I[819], I[819] = I[820], I[820] = I[821], I[821] = I[822], I[822] = I[823], I[823] = I[824], I[824] = I[825], I[825] = I[826], I[826] = I[827], I[827] = I[828], I[828] = I[829], I[829] = I[830], I[830] = I[831], I[831] = I[832], I[832] = I[833], I[833] = I[834], I[834] = I[835], I[835] = I[836], I[836] = I[837], I[837] = I[838], I[838] = I[839], \ - I[840] = I[841], I[841] = I[842], I[842] = I[843], I[843] = I[844], I[844] = I[845], I[845] = I[846], I[846] = I[847], I[847] = I[848], I[848] = I[849], I[849] = I[850], I[850] = I[851], I[851] = I[852], I[852] = I[853], I[853] = I[854], I[854] = I[855], I[855] = I[856], I[856] = I[857], I[857] = I[858], I[858] = I[859], I[859] = I[860], I[860] = I[861], I[861] = I[862], I[862] = I[863], I[863] = I[864], I[864] = I[865], I[865] = I[866], I[866] = I[867], I[867] = I[868], I[868] = I[869], \ - I[870] = I[871], I[871] = I[872], I[872] = I[873], I[873] = I[874], I[874] = I[875], I[875] = I[876], I[876] = I[877], I[877] = I[878], I[878] = I[879], I[879] = I[880], I[880] = I[881], I[881] = I[882], I[882] = I[883], I[883] = I[884], I[884] = I[885], I[885] = I[886], I[886] = I[887], I[887] = I[888], I[888] = I[889], I[889] = I[890], I[890] = I[891], I[891] = I[892], I[892] = I[893], I[893] = I[894], I[894] = I[895], I[895] = I[896], I[896] = I[897], I[897] = I[898], I[898] = I[899], \ - _p14##x = _p13##x, _p13##x = _p12##x, _p12##x = _p11##x, _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x, ++_n12##x, ++_n13##x, ++_n14##x, ++_n15##x) - -#define cimg_for_in30x30(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in30((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p14##x = x - 14<0?0:x - 14, \ - _p13##x = x - 13<0?0:x - 13, \ - _p12##x = x - 12<0?0:x - 12, \ - _p11##x = x - 11<0?0:x - 11, \ - _p10##x = x - 10<0?0:x - 10, \ - _p9##x = x - 9<0?0:x - 9, \ - _p8##x = x - 8<0?0:x - 8, \ - _p7##x = x - 7<0?0:x - 7, \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = x + 6>=(img).width()?(img).width() - 1:x + 6, \ - _n7##x = x + 7>=(img).width()?(img).width() - 1:x + 7, \ - _n8##x = x + 8>=(img).width()?(img).width() - 1:x + 8, \ - _n9##x = x + 9>=(img).width()?(img).width() - 1:x + 9, \ - _n10##x = x + 10>=(img).width()?(img).width() - 1:x + 10, \ - _n11##x = x + 11>=(img).width()?(img).width() - 1:x + 11, \ - _n12##x = x + 12>=(img).width()?(img).width() - 1:x + 12, \ - _n13##x = x + 13>=(img).width()?(img).width() - 1:x + 13, \ - _n14##x = x + 14>=(img).width()?(img).width() - 1:x + 14, \ - _n15##x = (int)( \ - (I[0] = (T)(img)(_p14##x,_p14##y,z,c)), \ - (I[30] = (T)(img)(_p14##x,_p13##y,z,c)), \ - (I[60] = (T)(img)(_p14##x,_p12##y,z,c)), \ - (I[90] = (T)(img)(_p14##x,_p11##y,z,c)), \ - (I[120] = (T)(img)(_p14##x,_p10##y,z,c)), \ - (I[150] = (T)(img)(_p14##x,_p9##y,z,c)), \ - (I[180] = (T)(img)(_p14##x,_p8##y,z,c)), \ - (I[210] = (T)(img)(_p14##x,_p7##y,z,c)), \ - (I[240] = (T)(img)(_p14##x,_p6##y,z,c)), \ - (I[270] = (T)(img)(_p14##x,_p5##y,z,c)), \ - (I[300] = (T)(img)(_p14##x,_p4##y,z,c)), \ - (I[330] = (T)(img)(_p14##x,_p3##y,z,c)), \ - (I[360] = (T)(img)(_p14##x,_p2##y,z,c)), \ - (I[390] = (T)(img)(_p14##x,_p1##y,z,c)), \ - (I[420] = (T)(img)(_p14##x,y,z,c)), \ - (I[450] = (T)(img)(_p14##x,_n1##y,z,c)), \ - (I[480] = (T)(img)(_p14##x,_n2##y,z,c)), \ - (I[510] = (T)(img)(_p14##x,_n3##y,z,c)), \ - (I[540] = (T)(img)(_p14##x,_n4##y,z,c)), \ - (I[570] = (T)(img)(_p14##x,_n5##y,z,c)), \ - (I[600] = (T)(img)(_p14##x,_n6##y,z,c)), \ - (I[630] = (T)(img)(_p14##x,_n7##y,z,c)), \ - (I[660] = (T)(img)(_p14##x,_n8##y,z,c)), \ - (I[690] = (T)(img)(_p14##x,_n9##y,z,c)), \ - (I[720] = (T)(img)(_p14##x,_n10##y,z,c)), \ - (I[750] = (T)(img)(_p14##x,_n11##y,z,c)), \ - (I[780] = (T)(img)(_p14##x,_n12##y,z,c)), \ - (I[810] = (T)(img)(_p14##x,_n13##y,z,c)), \ - (I[840] = (T)(img)(_p14##x,_n14##y,z,c)), \ - (I[870] = (T)(img)(_p14##x,_n15##y,z,c)), \ - (I[1] = (T)(img)(_p13##x,_p14##y,z,c)), \ - (I[31] = (T)(img)(_p13##x,_p13##y,z,c)), \ - (I[61] = (T)(img)(_p13##x,_p12##y,z,c)), \ - (I[91] = (T)(img)(_p13##x,_p11##y,z,c)), \ - (I[121] = (T)(img)(_p13##x,_p10##y,z,c)), \ - (I[151] = (T)(img)(_p13##x,_p9##y,z,c)), \ - (I[181] = (T)(img)(_p13##x,_p8##y,z,c)), \ - (I[211] = (T)(img)(_p13##x,_p7##y,z,c)), \ - (I[241] = (T)(img)(_p13##x,_p6##y,z,c)), \ - (I[271] = (T)(img)(_p13##x,_p5##y,z,c)), \ - (I[301] = (T)(img)(_p13##x,_p4##y,z,c)), \ - (I[331] = (T)(img)(_p13##x,_p3##y,z,c)), \ - (I[361] = (T)(img)(_p13##x,_p2##y,z,c)), \ - (I[391] = (T)(img)(_p13##x,_p1##y,z,c)), \ - (I[421] = (T)(img)(_p13##x,y,z,c)), \ - (I[451] = (T)(img)(_p13##x,_n1##y,z,c)), \ - (I[481] = (T)(img)(_p13##x,_n2##y,z,c)), \ - (I[511] = (T)(img)(_p13##x,_n3##y,z,c)), \ - (I[541] = (T)(img)(_p13##x,_n4##y,z,c)), \ - (I[571] = (T)(img)(_p13##x,_n5##y,z,c)), \ - (I[601] = (T)(img)(_p13##x,_n6##y,z,c)), \ - (I[631] = (T)(img)(_p13##x,_n7##y,z,c)), \ - (I[661] = (T)(img)(_p13##x,_n8##y,z,c)), \ - (I[691] = (T)(img)(_p13##x,_n9##y,z,c)), \ - (I[721] = (T)(img)(_p13##x,_n10##y,z,c)), \ - (I[751] = (T)(img)(_p13##x,_n11##y,z,c)), \ - (I[781] = (T)(img)(_p13##x,_n12##y,z,c)), \ - (I[811] = (T)(img)(_p13##x,_n13##y,z,c)), \ - (I[841] = (T)(img)(_p13##x,_n14##y,z,c)), \ - (I[871] = (T)(img)(_p13##x,_n15##y,z,c)), \ - (I[2] = (T)(img)(_p12##x,_p14##y,z,c)), \ - (I[32] = (T)(img)(_p12##x,_p13##y,z,c)), \ - (I[62] = (T)(img)(_p12##x,_p12##y,z,c)), \ - (I[92] = (T)(img)(_p12##x,_p11##y,z,c)), \ - (I[122] = (T)(img)(_p12##x,_p10##y,z,c)), \ - (I[152] = (T)(img)(_p12##x,_p9##y,z,c)), \ - (I[182] = (T)(img)(_p12##x,_p8##y,z,c)), \ - (I[212] = (T)(img)(_p12##x,_p7##y,z,c)), \ - (I[242] = (T)(img)(_p12##x,_p6##y,z,c)), \ - (I[272] = (T)(img)(_p12##x,_p5##y,z,c)), \ - (I[302] = (T)(img)(_p12##x,_p4##y,z,c)), \ - (I[332] = (T)(img)(_p12##x,_p3##y,z,c)), \ - (I[362] = (T)(img)(_p12##x,_p2##y,z,c)), \ - (I[392] = (T)(img)(_p12##x,_p1##y,z,c)), \ - (I[422] = (T)(img)(_p12##x,y,z,c)), \ - (I[452] = (T)(img)(_p12##x,_n1##y,z,c)), \ - (I[482] = (T)(img)(_p12##x,_n2##y,z,c)), \ - (I[512] = (T)(img)(_p12##x,_n3##y,z,c)), \ - (I[542] = (T)(img)(_p12##x,_n4##y,z,c)), \ - (I[572] = (T)(img)(_p12##x,_n5##y,z,c)), \ - (I[602] = (T)(img)(_p12##x,_n6##y,z,c)), \ - (I[632] = (T)(img)(_p12##x,_n7##y,z,c)), \ - (I[662] = (T)(img)(_p12##x,_n8##y,z,c)), \ - (I[692] = (T)(img)(_p12##x,_n9##y,z,c)), \ - (I[722] = (T)(img)(_p12##x,_n10##y,z,c)), \ - (I[752] = (T)(img)(_p12##x,_n11##y,z,c)), \ - (I[782] = (T)(img)(_p12##x,_n12##y,z,c)), \ - (I[812] = (T)(img)(_p12##x,_n13##y,z,c)), \ - (I[842] = (T)(img)(_p12##x,_n14##y,z,c)), \ - (I[872] = (T)(img)(_p12##x,_n15##y,z,c)), \ - (I[3] = (T)(img)(_p11##x,_p14##y,z,c)), \ - (I[33] = (T)(img)(_p11##x,_p13##y,z,c)), \ - (I[63] = (T)(img)(_p11##x,_p12##y,z,c)), \ - (I[93] = (T)(img)(_p11##x,_p11##y,z,c)), \ - (I[123] = (T)(img)(_p11##x,_p10##y,z,c)), \ - (I[153] = (T)(img)(_p11##x,_p9##y,z,c)), \ - (I[183] = (T)(img)(_p11##x,_p8##y,z,c)), \ - (I[213] = (T)(img)(_p11##x,_p7##y,z,c)), \ - (I[243] = (T)(img)(_p11##x,_p6##y,z,c)), \ - (I[273] = (T)(img)(_p11##x,_p5##y,z,c)), \ - (I[303] = (T)(img)(_p11##x,_p4##y,z,c)), \ - (I[333] = (T)(img)(_p11##x,_p3##y,z,c)), \ - (I[363] = (T)(img)(_p11##x,_p2##y,z,c)), \ - (I[393] = (T)(img)(_p11##x,_p1##y,z,c)), \ - (I[423] = (T)(img)(_p11##x,y,z,c)), \ - (I[453] = (T)(img)(_p11##x,_n1##y,z,c)), \ - (I[483] = (T)(img)(_p11##x,_n2##y,z,c)), \ - (I[513] = (T)(img)(_p11##x,_n3##y,z,c)), \ - (I[543] = (T)(img)(_p11##x,_n4##y,z,c)), \ - (I[573] = (T)(img)(_p11##x,_n5##y,z,c)), \ - (I[603] = (T)(img)(_p11##x,_n6##y,z,c)), \ - (I[633] = (T)(img)(_p11##x,_n7##y,z,c)), \ - (I[663] = (T)(img)(_p11##x,_n8##y,z,c)), \ - (I[693] = (T)(img)(_p11##x,_n9##y,z,c)), \ - (I[723] = (T)(img)(_p11##x,_n10##y,z,c)), \ - (I[753] = (T)(img)(_p11##x,_n11##y,z,c)), \ - (I[783] = (T)(img)(_p11##x,_n12##y,z,c)), \ - (I[813] = (T)(img)(_p11##x,_n13##y,z,c)), \ - (I[843] = (T)(img)(_p11##x,_n14##y,z,c)), \ - (I[873] = (T)(img)(_p11##x,_n15##y,z,c)), \ - (I[4] = (T)(img)(_p10##x,_p14##y,z,c)), \ - (I[34] = (T)(img)(_p10##x,_p13##y,z,c)), \ - (I[64] = (T)(img)(_p10##x,_p12##y,z,c)), \ - (I[94] = (T)(img)(_p10##x,_p11##y,z,c)), \ - (I[124] = (T)(img)(_p10##x,_p10##y,z,c)), \ - (I[154] = (T)(img)(_p10##x,_p9##y,z,c)), \ - (I[184] = (T)(img)(_p10##x,_p8##y,z,c)), \ - (I[214] = (T)(img)(_p10##x,_p7##y,z,c)), \ - (I[244] = (T)(img)(_p10##x,_p6##y,z,c)), \ - (I[274] = (T)(img)(_p10##x,_p5##y,z,c)), \ - (I[304] = (T)(img)(_p10##x,_p4##y,z,c)), \ - (I[334] = (T)(img)(_p10##x,_p3##y,z,c)), \ - (I[364] = (T)(img)(_p10##x,_p2##y,z,c)), \ - (I[394] = (T)(img)(_p10##x,_p1##y,z,c)), \ - (I[424] = (T)(img)(_p10##x,y,z,c)), \ - (I[454] = (T)(img)(_p10##x,_n1##y,z,c)), \ - (I[484] = (T)(img)(_p10##x,_n2##y,z,c)), \ - (I[514] = (T)(img)(_p10##x,_n3##y,z,c)), \ - (I[544] = (T)(img)(_p10##x,_n4##y,z,c)), \ - (I[574] = (T)(img)(_p10##x,_n5##y,z,c)), \ - (I[604] = (T)(img)(_p10##x,_n6##y,z,c)), \ - (I[634] = (T)(img)(_p10##x,_n7##y,z,c)), \ - (I[664] = (T)(img)(_p10##x,_n8##y,z,c)), \ - (I[694] = (T)(img)(_p10##x,_n9##y,z,c)), \ - (I[724] = (T)(img)(_p10##x,_n10##y,z,c)), \ - (I[754] = (T)(img)(_p10##x,_n11##y,z,c)), \ - (I[784] = (T)(img)(_p10##x,_n12##y,z,c)), \ - (I[814] = (T)(img)(_p10##x,_n13##y,z,c)), \ - (I[844] = (T)(img)(_p10##x,_n14##y,z,c)), \ - (I[874] = (T)(img)(_p10##x,_n15##y,z,c)), \ - (I[5] = (T)(img)(_p9##x,_p14##y,z,c)), \ - (I[35] = (T)(img)(_p9##x,_p13##y,z,c)), \ - (I[65] = (T)(img)(_p9##x,_p12##y,z,c)), \ - (I[95] = (T)(img)(_p9##x,_p11##y,z,c)), \ - (I[125] = (T)(img)(_p9##x,_p10##y,z,c)), \ - (I[155] = (T)(img)(_p9##x,_p9##y,z,c)), \ - (I[185] = (T)(img)(_p9##x,_p8##y,z,c)), \ - (I[215] = (T)(img)(_p9##x,_p7##y,z,c)), \ - (I[245] = (T)(img)(_p9##x,_p6##y,z,c)), \ - (I[275] = (T)(img)(_p9##x,_p5##y,z,c)), \ - (I[305] = (T)(img)(_p9##x,_p4##y,z,c)), \ - (I[335] = (T)(img)(_p9##x,_p3##y,z,c)), \ - (I[365] = (T)(img)(_p9##x,_p2##y,z,c)), \ - (I[395] = (T)(img)(_p9##x,_p1##y,z,c)), \ - (I[425] = (T)(img)(_p9##x,y,z,c)), \ - (I[455] = (T)(img)(_p9##x,_n1##y,z,c)), \ - (I[485] = (T)(img)(_p9##x,_n2##y,z,c)), \ - (I[515] = (T)(img)(_p9##x,_n3##y,z,c)), \ - (I[545] = (T)(img)(_p9##x,_n4##y,z,c)), \ - (I[575] = (T)(img)(_p9##x,_n5##y,z,c)), \ - (I[605] = (T)(img)(_p9##x,_n6##y,z,c)), \ - (I[635] = (T)(img)(_p9##x,_n7##y,z,c)), \ - (I[665] = (T)(img)(_p9##x,_n8##y,z,c)), \ - (I[695] = (T)(img)(_p9##x,_n9##y,z,c)), \ - (I[725] = (T)(img)(_p9##x,_n10##y,z,c)), \ - (I[755] = (T)(img)(_p9##x,_n11##y,z,c)), \ - (I[785] = (T)(img)(_p9##x,_n12##y,z,c)), \ - (I[815] = (T)(img)(_p9##x,_n13##y,z,c)), \ - (I[845] = (T)(img)(_p9##x,_n14##y,z,c)), \ - (I[875] = (T)(img)(_p9##x,_n15##y,z,c)), \ - (I[6] = (T)(img)(_p8##x,_p14##y,z,c)), \ - (I[36] = (T)(img)(_p8##x,_p13##y,z,c)), \ - (I[66] = (T)(img)(_p8##x,_p12##y,z,c)), \ - (I[96] = (T)(img)(_p8##x,_p11##y,z,c)), \ - (I[126] = (T)(img)(_p8##x,_p10##y,z,c)), \ - (I[156] = (T)(img)(_p8##x,_p9##y,z,c)), \ - (I[186] = (T)(img)(_p8##x,_p8##y,z,c)), \ - (I[216] = (T)(img)(_p8##x,_p7##y,z,c)), \ - (I[246] = (T)(img)(_p8##x,_p6##y,z,c)), \ - (I[276] = (T)(img)(_p8##x,_p5##y,z,c)), \ - (I[306] = (T)(img)(_p8##x,_p4##y,z,c)), \ - (I[336] = (T)(img)(_p8##x,_p3##y,z,c)), \ - (I[366] = (T)(img)(_p8##x,_p2##y,z,c)), \ - (I[396] = (T)(img)(_p8##x,_p1##y,z,c)), \ - (I[426] = (T)(img)(_p8##x,y,z,c)), \ - (I[456] = (T)(img)(_p8##x,_n1##y,z,c)), \ - (I[486] = (T)(img)(_p8##x,_n2##y,z,c)), \ - (I[516] = (T)(img)(_p8##x,_n3##y,z,c)), \ - (I[546] = (T)(img)(_p8##x,_n4##y,z,c)), \ - (I[576] = (T)(img)(_p8##x,_n5##y,z,c)), \ - (I[606] = (T)(img)(_p8##x,_n6##y,z,c)), \ - (I[636] = (T)(img)(_p8##x,_n7##y,z,c)), \ - (I[666] = (T)(img)(_p8##x,_n8##y,z,c)), \ - (I[696] = (T)(img)(_p8##x,_n9##y,z,c)), \ - (I[726] = (T)(img)(_p8##x,_n10##y,z,c)), \ - (I[756] = (T)(img)(_p8##x,_n11##y,z,c)), \ - (I[786] = (T)(img)(_p8##x,_n12##y,z,c)), \ - (I[816] = (T)(img)(_p8##x,_n13##y,z,c)), \ - (I[846] = (T)(img)(_p8##x,_n14##y,z,c)), \ - (I[876] = (T)(img)(_p8##x,_n15##y,z,c)), \ - (I[7] = (T)(img)(_p7##x,_p14##y,z,c)), \ - (I[37] = (T)(img)(_p7##x,_p13##y,z,c)), \ - (I[67] = (T)(img)(_p7##x,_p12##y,z,c)), \ - (I[97] = (T)(img)(_p7##x,_p11##y,z,c)), \ - (I[127] = (T)(img)(_p7##x,_p10##y,z,c)), \ - (I[157] = (T)(img)(_p7##x,_p9##y,z,c)), \ - (I[187] = (T)(img)(_p7##x,_p8##y,z,c)), \ - (I[217] = (T)(img)(_p7##x,_p7##y,z,c)), \ - (I[247] = (T)(img)(_p7##x,_p6##y,z,c)), \ - (I[277] = (T)(img)(_p7##x,_p5##y,z,c)), \ - (I[307] = (T)(img)(_p7##x,_p4##y,z,c)), \ - (I[337] = (T)(img)(_p7##x,_p3##y,z,c)), \ - (I[367] = (T)(img)(_p7##x,_p2##y,z,c)), \ - (I[397] = (T)(img)(_p7##x,_p1##y,z,c)), \ - (I[427] = (T)(img)(_p7##x,y,z,c)), \ - (I[457] = (T)(img)(_p7##x,_n1##y,z,c)), \ - (I[487] = (T)(img)(_p7##x,_n2##y,z,c)), \ - (I[517] = (T)(img)(_p7##x,_n3##y,z,c)), \ - (I[547] = (T)(img)(_p7##x,_n4##y,z,c)), \ - (I[577] = (T)(img)(_p7##x,_n5##y,z,c)), \ - (I[607] = (T)(img)(_p7##x,_n6##y,z,c)), \ - (I[637] = (T)(img)(_p7##x,_n7##y,z,c)), \ - (I[667] = (T)(img)(_p7##x,_n8##y,z,c)), \ - (I[697] = (T)(img)(_p7##x,_n9##y,z,c)), \ - (I[727] = (T)(img)(_p7##x,_n10##y,z,c)), \ - (I[757] = (T)(img)(_p7##x,_n11##y,z,c)), \ - (I[787] = (T)(img)(_p7##x,_n12##y,z,c)), \ - (I[817] = (T)(img)(_p7##x,_n13##y,z,c)), \ - (I[847] = (T)(img)(_p7##x,_n14##y,z,c)), \ - (I[877] = (T)(img)(_p7##x,_n15##y,z,c)), \ - (I[8] = (T)(img)(_p6##x,_p14##y,z,c)), \ - (I[38] = (T)(img)(_p6##x,_p13##y,z,c)), \ - (I[68] = (T)(img)(_p6##x,_p12##y,z,c)), \ - (I[98] = (T)(img)(_p6##x,_p11##y,z,c)), \ - (I[128] = (T)(img)(_p6##x,_p10##y,z,c)), \ - (I[158] = (T)(img)(_p6##x,_p9##y,z,c)), \ - (I[188] = (T)(img)(_p6##x,_p8##y,z,c)), \ - (I[218] = (T)(img)(_p6##x,_p7##y,z,c)), \ - (I[248] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[278] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[308] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[338] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[368] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[398] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[428] = (T)(img)(_p6##x,y,z,c)), \ - (I[458] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[488] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[518] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[548] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[578] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[608] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[638] = (T)(img)(_p6##x,_n7##y,z,c)), \ - (I[668] = (T)(img)(_p6##x,_n8##y,z,c)), \ - (I[698] = (T)(img)(_p6##x,_n9##y,z,c)), \ - (I[728] = (T)(img)(_p6##x,_n10##y,z,c)), \ - (I[758] = (T)(img)(_p6##x,_n11##y,z,c)), \ - (I[788] = (T)(img)(_p6##x,_n12##y,z,c)), \ - (I[818] = (T)(img)(_p6##x,_n13##y,z,c)), \ - (I[848] = (T)(img)(_p6##x,_n14##y,z,c)), \ - (I[878] = (T)(img)(_p6##x,_n15##y,z,c)), \ - (I[9] = (T)(img)(_p5##x,_p14##y,z,c)), \ - (I[39] = (T)(img)(_p5##x,_p13##y,z,c)), \ - (I[69] = (T)(img)(_p5##x,_p12##y,z,c)), \ - (I[99] = (T)(img)(_p5##x,_p11##y,z,c)), \ - (I[129] = (T)(img)(_p5##x,_p10##y,z,c)), \ - (I[159] = (T)(img)(_p5##x,_p9##y,z,c)), \ - (I[189] = (T)(img)(_p5##x,_p8##y,z,c)), \ - (I[219] = (T)(img)(_p5##x,_p7##y,z,c)), \ - (I[249] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[279] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[309] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[339] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[369] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[399] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[429] = (T)(img)(_p5##x,y,z,c)), \ - (I[459] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[489] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[519] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[549] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[579] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[609] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[639] = (T)(img)(_p5##x,_n7##y,z,c)), \ - (I[669] = (T)(img)(_p5##x,_n8##y,z,c)), \ - (I[699] = (T)(img)(_p5##x,_n9##y,z,c)), \ - (I[729] = (T)(img)(_p5##x,_n10##y,z,c)), \ - (I[759] = (T)(img)(_p5##x,_n11##y,z,c)), \ - (I[789] = (T)(img)(_p5##x,_n12##y,z,c)), \ - (I[819] = (T)(img)(_p5##x,_n13##y,z,c)), \ - (I[849] = (T)(img)(_p5##x,_n14##y,z,c)), \ - (I[879] = (T)(img)(_p5##x,_n15##y,z,c)), \ - (I[10] = (T)(img)(_p4##x,_p14##y,z,c)), \ - (I[40] = (T)(img)(_p4##x,_p13##y,z,c)), \ - (I[70] = (T)(img)(_p4##x,_p12##y,z,c)), \ - (I[100] = (T)(img)(_p4##x,_p11##y,z,c)), \ - (I[130] = (T)(img)(_p4##x,_p10##y,z,c)), \ - (I[160] = (T)(img)(_p4##x,_p9##y,z,c)), \ - (I[190] = (T)(img)(_p4##x,_p8##y,z,c)), \ - (I[220] = (T)(img)(_p4##x,_p7##y,z,c)), \ - (I[250] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[280] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[310] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[340] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[370] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[400] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[430] = (T)(img)(_p4##x,y,z,c)), \ - (I[460] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[490] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[520] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[550] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[580] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[610] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[640] = (T)(img)(_p4##x,_n7##y,z,c)), \ - (I[670] = (T)(img)(_p4##x,_n8##y,z,c)), \ - (I[700] = (T)(img)(_p4##x,_n9##y,z,c)), \ - (I[730] = (T)(img)(_p4##x,_n10##y,z,c)), \ - (I[760] = (T)(img)(_p4##x,_n11##y,z,c)), \ - (I[790] = (T)(img)(_p4##x,_n12##y,z,c)), \ - (I[820] = (T)(img)(_p4##x,_n13##y,z,c)), \ - (I[850] = (T)(img)(_p4##x,_n14##y,z,c)), \ - (I[880] = (T)(img)(_p4##x,_n15##y,z,c)), \ - (I[11] = (T)(img)(_p3##x,_p14##y,z,c)), \ - (I[41] = (T)(img)(_p3##x,_p13##y,z,c)), \ - (I[71] = (T)(img)(_p3##x,_p12##y,z,c)), \ - (I[101] = (T)(img)(_p3##x,_p11##y,z,c)), \ - (I[131] = (T)(img)(_p3##x,_p10##y,z,c)), \ - (I[161] = (T)(img)(_p3##x,_p9##y,z,c)), \ - (I[191] = (T)(img)(_p3##x,_p8##y,z,c)), \ - (I[221] = (T)(img)(_p3##x,_p7##y,z,c)), \ - (I[251] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[281] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[311] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[341] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[371] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[401] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[431] = (T)(img)(_p3##x,y,z,c)), \ - (I[461] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[491] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[521] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[551] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[581] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[611] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[641] = (T)(img)(_p3##x,_n7##y,z,c)), \ - (I[671] = (T)(img)(_p3##x,_n8##y,z,c)), \ - (I[701] = (T)(img)(_p3##x,_n9##y,z,c)), \ - (I[731] = (T)(img)(_p3##x,_n10##y,z,c)), \ - (I[761] = (T)(img)(_p3##x,_n11##y,z,c)), \ - (I[791] = (T)(img)(_p3##x,_n12##y,z,c)), \ - (I[821] = (T)(img)(_p3##x,_n13##y,z,c)), \ - (I[851] = (T)(img)(_p3##x,_n14##y,z,c)), \ - (I[881] = (T)(img)(_p3##x,_n15##y,z,c)), \ - (I[12] = (T)(img)(_p2##x,_p14##y,z,c)), \ - (I[42] = (T)(img)(_p2##x,_p13##y,z,c)), \ - (I[72] = (T)(img)(_p2##x,_p12##y,z,c)), \ - (I[102] = (T)(img)(_p2##x,_p11##y,z,c)), \ - (I[132] = (T)(img)(_p2##x,_p10##y,z,c)), \ - (I[162] = (T)(img)(_p2##x,_p9##y,z,c)), \ - (I[192] = (T)(img)(_p2##x,_p8##y,z,c)), \ - (I[222] = (T)(img)(_p2##x,_p7##y,z,c)), \ - (I[252] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[282] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[312] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[342] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[372] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[402] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[432] = (T)(img)(_p2##x,y,z,c)), \ - (I[462] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[492] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[522] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[552] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[582] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[612] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[642] = (T)(img)(_p2##x,_n7##y,z,c)), \ - (I[672] = (T)(img)(_p2##x,_n8##y,z,c)), \ - (I[702] = (T)(img)(_p2##x,_n9##y,z,c)), \ - (I[732] = (T)(img)(_p2##x,_n10##y,z,c)), \ - (I[762] = (T)(img)(_p2##x,_n11##y,z,c)), \ - (I[792] = (T)(img)(_p2##x,_n12##y,z,c)), \ - (I[822] = (T)(img)(_p2##x,_n13##y,z,c)), \ - (I[852] = (T)(img)(_p2##x,_n14##y,z,c)), \ - (I[882] = (T)(img)(_p2##x,_n15##y,z,c)), \ - (I[13] = (T)(img)(_p1##x,_p14##y,z,c)), \ - (I[43] = (T)(img)(_p1##x,_p13##y,z,c)), \ - (I[73] = (T)(img)(_p1##x,_p12##y,z,c)), \ - (I[103] = (T)(img)(_p1##x,_p11##y,z,c)), \ - (I[133] = (T)(img)(_p1##x,_p10##y,z,c)), \ - (I[163] = (T)(img)(_p1##x,_p9##y,z,c)), \ - (I[193] = (T)(img)(_p1##x,_p8##y,z,c)), \ - (I[223] = (T)(img)(_p1##x,_p7##y,z,c)), \ - (I[253] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[283] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[313] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[343] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[373] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[403] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[433] = (T)(img)(_p1##x,y,z,c)), \ - (I[463] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[493] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[523] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[553] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[583] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[613] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[643] = (T)(img)(_p1##x,_n7##y,z,c)), \ - (I[673] = (T)(img)(_p1##x,_n8##y,z,c)), \ - (I[703] = (T)(img)(_p1##x,_n9##y,z,c)), \ - (I[733] = (T)(img)(_p1##x,_n10##y,z,c)), \ - (I[763] = (T)(img)(_p1##x,_n11##y,z,c)), \ - (I[793] = (T)(img)(_p1##x,_n12##y,z,c)), \ - (I[823] = (T)(img)(_p1##x,_n13##y,z,c)), \ - (I[853] = (T)(img)(_p1##x,_n14##y,z,c)), \ - (I[883] = (T)(img)(_p1##x,_n15##y,z,c)), \ - (I[14] = (T)(img)(x,_p14##y,z,c)), \ - (I[44] = (T)(img)(x,_p13##y,z,c)), \ - (I[74] = (T)(img)(x,_p12##y,z,c)), \ - (I[104] = (T)(img)(x,_p11##y,z,c)), \ - (I[134] = (T)(img)(x,_p10##y,z,c)), \ - (I[164] = (T)(img)(x,_p9##y,z,c)), \ - (I[194] = (T)(img)(x,_p8##y,z,c)), \ - (I[224] = (T)(img)(x,_p7##y,z,c)), \ - (I[254] = (T)(img)(x,_p6##y,z,c)), \ - (I[284] = (T)(img)(x,_p5##y,z,c)), \ - (I[314] = (T)(img)(x,_p4##y,z,c)), \ - (I[344] = (T)(img)(x,_p3##y,z,c)), \ - (I[374] = (T)(img)(x,_p2##y,z,c)), \ - (I[404] = (T)(img)(x,_p1##y,z,c)), \ - (I[434] = (T)(img)(x,y,z,c)), \ - (I[464] = (T)(img)(x,_n1##y,z,c)), \ - (I[494] = (T)(img)(x,_n2##y,z,c)), \ - (I[524] = (T)(img)(x,_n3##y,z,c)), \ - (I[554] = (T)(img)(x,_n4##y,z,c)), \ - (I[584] = (T)(img)(x,_n5##y,z,c)), \ - (I[614] = (T)(img)(x,_n6##y,z,c)), \ - (I[644] = (T)(img)(x,_n7##y,z,c)), \ - (I[674] = (T)(img)(x,_n8##y,z,c)), \ - (I[704] = (T)(img)(x,_n9##y,z,c)), \ - (I[734] = (T)(img)(x,_n10##y,z,c)), \ - (I[764] = (T)(img)(x,_n11##y,z,c)), \ - (I[794] = (T)(img)(x,_n12##y,z,c)), \ - (I[824] = (T)(img)(x,_n13##y,z,c)), \ - (I[854] = (T)(img)(x,_n14##y,z,c)), \ - (I[884] = (T)(img)(x,_n15##y,z,c)), \ - (I[15] = (T)(img)(_n1##x,_p14##y,z,c)), \ - (I[45] = (T)(img)(_n1##x,_p13##y,z,c)), \ - (I[75] = (T)(img)(_n1##x,_p12##y,z,c)), \ - (I[105] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[135] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[165] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[195] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[225] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[255] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[285] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[315] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[345] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[375] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[405] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[435] = (T)(img)(_n1##x,y,z,c)), \ - (I[465] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[495] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[525] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[555] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[585] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[615] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[645] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[675] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[705] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[735] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[765] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[795] = (T)(img)(_n1##x,_n12##y,z,c)), \ - (I[825] = (T)(img)(_n1##x,_n13##y,z,c)), \ - (I[855] = (T)(img)(_n1##x,_n14##y,z,c)), \ - (I[885] = (T)(img)(_n1##x,_n15##y,z,c)), \ - (I[16] = (T)(img)(_n2##x,_p14##y,z,c)), \ - (I[46] = (T)(img)(_n2##x,_p13##y,z,c)), \ - (I[76] = (T)(img)(_n2##x,_p12##y,z,c)), \ - (I[106] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[136] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[166] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[196] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[226] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[256] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[286] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[316] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[346] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[376] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[406] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[436] = (T)(img)(_n2##x,y,z,c)), \ - (I[466] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[496] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[526] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[556] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[586] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[616] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[646] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[676] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[706] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[736] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[766] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[796] = (T)(img)(_n2##x,_n12##y,z,c)), \ - (I[826] = (T)(img)(_n2##x,_n13##y,z,c)), \ - (I[856] = (T)(img)(_n2##x,_n14##y,z,c)), \ - (I[886] = (T)(img)(_n2##x,_n15##y,z,c)), \ - (I[17] = (T)(img)(_n3##x,_p14##y,z,c)), \ - (I[47] = (T)(img)(_n3##x,_p13##y,z,c)), \ - (I[77] = (T)(img)(_n3##x,_p12##y,z,c)), \ - (I[107] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[137] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[167] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[197] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[227] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[257] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[287] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[317] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[347] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[377] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[407] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[437] = (T)(img)(_n3##x,y,z,c)), \ - (I[467] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[497] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[527] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[557] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[587] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[617] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[647] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[677] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[707] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[737] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[767] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[797] = (T)(img)(_n3##x,_n12##y,z,c)), \ - (I[827] = (T)(img)(_n3##x,_n13##y,z,c)), \ - (I[857] = (T)(img)(_n3##x,_n14##y,z,c)), \ - (I[887] = (T)(img)(_n3##x,_n15##y,z,c)), \ - (I[18] = (T)(img)(_n4##x,_p14##y,z,c)), \ - (I[48] = (T)(img)(_n4##x,_p13##y,z,c)), \ - (I[78] = (T)(img)(_n4##x,_p12##y,z,c)), \ - (I[108] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[138] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[168] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[198] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[228] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[258] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[288] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[318] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[348] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[378] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[408] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[438] = (T)(img)(_n4##x,y,z,c)), \ - (I[468] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[498] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[528] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[558] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[588] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[618] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[648] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[678] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[708] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[738] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[768] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[798] = (T)(img)(_n4##x,_n12##y,z,c)), \ - (I[828] = (T)(img)(_n4##x,_n13##y,z,c)), \ - (I[858] = (T)(img)(_n4##x,_n14##y,z,c)), \ - (I[888] = (T)(img)(_n4##x,_n15##y,z,c)), \ - (I[19] = (T)(img)(_n5##x,_p14##y,z,c)), \ - (I[49] = (T)(img)(_n5##x,_p13##y,z,c)), \ - (I[79] = (T)(img)(_n5##x,_p12##y,z,c)), \ - (I[109] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[139] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[169] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[199] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[229] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[259] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[289] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[319] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[349] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[379] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[409] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[439] = (T)(img)(_n5##x,y,z,c)), \ - (I[469] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[499] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[529] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[559] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[589] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[619] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[649] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[679] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[709] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[739] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[769] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[799] = (T)(img)(_n5##x,_n12##y,z,c)), \ - (I[829] = (T)(img)(_n5##x,_n13##y,z,c)), \ - (I[859] = (T)(img)(_n5##x,_n14##y,z,c)), \ - (I[889] = (T)(img)(_n5##x,_n15##y,z,c)), \ - (I[20] = (T)(img)(_n6##x,_p14##y,z,c)), \ - (I[50] = (T)(img)(_n6##x,_p13##y,z,c)), \ - (I[80] = (T)(img)(_n6##x,_p12##y,z,c)), \ - (I[110] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[140] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[170] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[200] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[230] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[260] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[290] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[320] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[350] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[380] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[410] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[440] = (T)(img)(_n6##x,y,z,c)), \ - (I[470] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[500] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[530] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[560] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[590] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[620] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[650] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[680] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[710] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[740] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[770] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[800] = (T)(img)(_n6##x,_n12##y,z,c)), \ - (I[830] = (T)(img)(_n6##x,_n13##y,z,c)), \ - (I[860] = (T)(img)(_n6##x,_n14##y,z,c)), \ - (I[890] = (T)(img)(_n6##x,_n15##y,z,c)), \ - (I[21] = (T)(img)(_n7##x,_p14##y,z,c)), \ - (I[51] = (T)(img)(_n7##x,_p13##y,z,c)), \ - (I[81] = (T)(img)(_n7##x,_p12##y,z,c)), \ - (I[111] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[141] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[171] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[201] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[231] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[261] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[291] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[321] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[351] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[381] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[411] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[441] = (T)(img)(_n7##x,y,z,c)), \ - (I[471] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[501] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[531] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[561] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[591] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[621] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[651] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[681] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[711] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[741] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[771] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[801] = (T)(img)(_n7##x,_n12##y,z,c)), \ - (I[831] = (T)(img)(_n7##x,_n13##y,z,c)), \ - (I[861] = (T)(img)(_n7##x,_n14##y,z,c)), \ - (I[891] = (T)(img)(_n7##x,_n15##y,z,c)), \ - (I[22] = (T)(img)(_n8##x,_p14##y,z,c)), \ - (I[52] = (T)(img)(_n8##x,_p13##y,z,c)), \ - (I[82] = (T)(img)(_n8##x,_p12##y,z,c)), \ - (I[112] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[142] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[172] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[202] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[232] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[262] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[292] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[322] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[352] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[382] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[412] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[442] = (T)(img)(_n8##x,y,z,c)), \ - (I[472] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[502] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[532] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[562] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[592] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[622] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[652] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[682] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[712] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[742] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[772] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[802] = (T)(img)(_n8##x,_n12##y,z,c)), \ - (I[832] = (T)(img)(_n8##x,_n13##y,z,c)), \ - (I[862] = (T)(img)(_n8##x,_n14##y,z,c)), \ - (I[892] = (T)(img)(_n8##x,_n15##y,z,c)), \ - (I[23] = (T)(img)(_n9##x,_p14##y,z,c)), \ - (I[53] = (T)(img)(_n9##x,_p13##y,z,c)), \ - (I[83] = (T)(img)(_n9##x,_p12##y,z,c)), \ - (I[113] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[143] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[173] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[203] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[233] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[263] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[293] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[323] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[353] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[383] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[413] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[443] = (T)(img)(_n9##x,y,z,c)), \ - (I[473] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[503] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[533] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[563] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[593] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[623] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[653] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[683] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[713] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[743] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[773] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[803] = (T)(img)(_n9##x,_n12##y,z,c)), \ - (I[833] = (T)(img)(_n9##x,_n13##y,z,c)), \ - (I[863] = (T)(img)(_n9##x,_n14##y,z,c)), \ - (I[893] = (T)(img)(_n9##x,_n15##y,z,c)), \ - (I[24] = (T)(img)(_n10##x,_p14##y,z,c)), \ - (I[54] = (T)(img)(_n10##x,_p13##y,z,c)), \ - (I[84] = (T)(img)(_n10##x,_p12##y,z,c)), \ - (I[114] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[144] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[174] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[204] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[234] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[264] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[294] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[324] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[354] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[384] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[414] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[444] = (T)(img)(_n10##x,y,z,c)), \ - (I[474] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[504] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[534] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[564] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[594] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[624] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[654] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[684] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[714] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[744] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[774] = (T)(img)(_n10##x,_n11##y,z,c)), \ - (I[804] = (T)(img)(_n10##x,_n12##y,z,c)), \ - (I[834] = (T)(img)(_n10##x,_n13##y,z,c)), \ - (I[864] = (T)(img)(_n10##x,_n14##y,z,c)), \ - (I[894] = (T)(img)(_n10##x,_n15##y,z,c)), \ - (I[25] = (T)(img)(_n11##x,_p14##y,z,c)), \ - (I[55] = (T)(img)(_n11##x,_p13##y,z,c)), \ - (I[85] = (T)(img)(_n11##x,_p12##y,z,c)), \ - (I[115] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[145] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[175] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[205] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[235] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[265] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[295] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[325] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[355] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[385] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[415] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[445] = (T)(img)(_n11##x,y,z,c)), \ - (I[475] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[505] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[535] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[565] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[595] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[625] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[655] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[685] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[715] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[745] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[775] = (T)(img)(_n11##x,_n11##y,z,c)), \ - (I[805] = (T)(img)(_n11##x,_n12##y,z,c)), \ - (I[835] = (T)(img)(_n11##x,_n13##y,z,c)), \ - (I[865] = (T)(img)(_n11##x,_n14##y,z,c)), \ - (I[895] = (T)(img)(_n11##x,_n15##y,z,c)), \ - (I[26] = (T)(img)(_n12##x,_p14##y,z,c)), \ - (I[56] = (T)(img)(_n12##x,_p13##y,z,c)), \ - (I[86] = (T)(img)(_n12##x,_p12##y,z,c)), \ - (I[116] = (T)(img)(_n12##x,_p11##y,z,c)), \ - (I[146] = (T)(img)(_n12##x,_p10##y,z,c)), \ - (I[176] = (T)(img)(_n12##x,_p9##y,z,c)), \ - (I[206] = (T)(img)(_n12##x,_p8##y,z,c)), \ - (I[236] = (T)(img)(_n12##x,_p7##y,z,c)), \ - (I[266] = (T)(img)(_n12##x,_p6##y,z,c)), \ - (I[296] = (T)(img)(_n12##x,_p5##y,z,c)), \ - (I[326] = (T)(img)(_n12##x,_p4##y,z,c)), \ - (I[356] = (T)(img)(_n12##x,_p3##y,z,c)), \ - (I[386] = (T)(img)(_n12##x,_p2##y,z,c)), \ - (I[416] = (T)(img)(_n12##x,_p1##y,z,c)), \ - (I[446] = (T)(img)(_n12##x,y,z,c)), \ - (I[476] = (T)(img)(_n12##x,_n1##y,z,c)), \ - (I[506] = (T)(img)(_n12##x,_n2##y,z,c)), \ - (I[536] = (T)(img)(_n12##x,_n3##y,z,c)), \ - (I[566] = (T)(img)(_n12##x,_n4##y,z,c)), \ - (I[596] = (T)(img)(_n12##x,_n5##y,z,c)), \ - (I[626] = (T)(img)(_n12##x,_n6##y,z,c)), \ - (I[656] = (T)(img)(_n12##x,_n7##y,z,c)), \ - (I[686] = (T)(img)(_n12##x,_n8##y,z,c)), \ - (I[716] = (T)(img)(_n12##x,_n9##y,z,c)), \ - (I[746] = (T)(img)(_n12##x,_n10##y,z,c)), \ - (I[776] = (T)(img)(_n12##x,_n11##y,z,c)), \ - (I[806] = (T)(img)(_n12##x,_n12##y,z,c)), \ - (I[836] = (T)(img)(_n12##x,_n13##y,z,c)), \ - (I[866] = (T)(img)(_n12##x,_n14##y,z,c)), \ - (I[896] = (T)(img)(_n12##x,_n15##y,z,c)), \ - (I[27] = (T)(img)(_n13##x,_p14##y,z,c)), \ - (I[57] = (T)(img)(_n13##x,_p13##y,z,c)), \ - (I[87] = (T)(img)(_n13##x,_p12##y,z,c)), \ - (I[117] = (T)(img)(_n13##x,_p11##y,z,c)), \ - (I[147] = (T)(img)(_n13##x,_p10##y,z,c)), \ - (I[177] = (T)(img)(_n13##x,_p9##y,z,c)), \ - (I[207] = (T)(img)(_n13##x,_p8##y,z,c)), \ - (I[237] = (T)(img)(_n13##x,_p7##y,z,c)), \ - (I[267] = (T)(img)(_n13##x,_p6##y,z,c)), \ - (I[297] = (T)(img)(_n13##x,_p5##y,z,c)), \ - (I[327] = (T)(img)(_n13##x,_p4##y,z,c)), \ - (I[357] = (T)(img)(_n13##x,_p3##y,z,c)), \ - (I[387] = (T)(img)(_n13##x,_p2##y,z,c)), \ - (I[417] = (T)(img)(_n13##x,_p1##y,z,c)), \ - (I[447] = (T)(img)(_n13##x,y,z,c)), \ - (I[477] = (T)(img)(_n13##x,_n1##y,z,c)), \ - (I[507] = (T)(img)(_n13##x,_n2##y,z,c)), \ - (I[537] = (T)(img)(_n13##x,_n3##y,z,c)), \ - (I[567] = (T)(img)(_n13##x,_n4##y,z,c)), \ - (I[597] = (T)(img)(_n13##x,_n5##y,z,c)), \ - (I[627] = (T)(img)(_n13##x,_n6##y,z,c)), \ - (I[657] = (T)(img)(_n13##x,_n7##y,z,c)), \ - (I[687] = (T)(img)(_n13##x,_n8##y,z,c)), \ - (I[717] = (T)(img)(_n13##x,_n9##y,z,c)), \ - (I[747] = (T)(img)(_n13##x,_n10##y,z,c)), \ - (I[777] = (T)(img)(_n13##x,_n11##y,z,c)), \ - (I[807] = (T)(img)(_n13##x,_n12##y,z,c)), \ - (I[837] = (T)(img)(_n13##x,_n13##y,z,c)), \ - (I[867] = (T)(img)(_n13##x,_n14##y,z,c)), \ - (I[897] = (T)(img)(_n13##x,_n15##y,z,c)), \ - (I[28] = (T)(img)(_n14##x,_p14##y,z,c)), \ - (I[58] = (T)(img)(_n14##x,_p13##y,z,c)), \ - (I[88] = (T)(img)(_n14##x,_p12##y,z,c)), \ - (I[118] = (T)(img)(_n14##x,_p11##y,z,c)), \ - (I[148] = (T)(img)(_n14##x,_p10##y,z,c)), \ - (I[178] = (T)(img)(_n14##x,_p9##y,z,c)), \ - (I[208] = (T)(img)(_n14##x,_p8##y,z,c)), \ - (I[238] = (T)(img)(_n14##x,_p7##y,z,c)), \ - (I[268] = (T)(img)(_n14##x,_p6##y,z,c)), \ - (I[298] = (T)(img)(_n14##x,_p5##y,z,c)), \ - (I[328] = (T)(img)(_n14##x,_p4##y,z,c)), \ - (I[358] = (T)(img)(_n14##x,_p3##y,z,c)), \ - (I[388] = (T)(img)(_n14##x,_p2##y,z,c)), \ - (I[418] = (T)(img)(_n14##x,_p1##y,z,c)), \ - (I[448] = (T)(img)(_n14##x,y,z,c)), \ - (I[478] = (T)(img)(_n14##x,_n1##y,z,c)), \ - (I[508] = (T)(img)(_n14##x,_n2##y,z,c)), \ - (I[538] = (T)(img)(_n14##x,_n3##y,z,c)), \ - (I[568] = (T)(img)(_n14##x,_n4##y,z,c)), \ - (I[598] = (T)(img)(_n14##x,_n5##y,z,c)), \ - (I[628] = (T)(img)(_n14##x,_n6##y,z,c)), \ - (I[658] = (T)(img)(_n14##x,_n7##y,z,c)), \ - (I[688] = (T)(img)(_n14##x,_n8##y,z,c)), \ - (I[718] = (T)(img)(_n14##x,_n9##y,z,c)), \ - (I[748] = (T)(img)(_n14##x,_n10##y,z,c)), \ - (I[778] = (T)(img)(_n14##x,_n11##y,z,c)), \ - (I[808] = (T)(img)(_n14##x,_n12##y,z,c)), \ - (I[838] = (T)(img)(_n14##x,_n13##y,z,c)), \ - (I[868] = (T)(img)(_n14##x,_n14##y,z,c)), \ - (I[898] = (T)(img)(_n14##x,_n15##y,z,c)), \ - x + 15>=(img).width()?(img).width() - 1:x + 15); \ - x<=(int)(x1) && ((_n15##x<(img).width() && ( \ - (I[29] = (T)(img)(_n15##x,_p14##y,z,c)), \ - (I[59] = (T)(img)(_n15##x,_p13##y,z,c)), \ - (I[89] = (T)(img)(_n15##x,_p12##y,z,c)), \ - (I[119] = (T)(img)(_n15##x,_p11##y,z,c)), \ - (I[149] = (T)(img)(_n15##x,_p10##y,z,c)), \ - (I[179] = (T)(img)(_n15##x,_p9##y,z,c)), \ - (I[209] = (T)(img)(_n15##x,_p8##y,z,c)), \ - (I[239] = (T)(img)(_n15##x,_p7##y,z,c)), \ - (I[269] = (T)(img)(_n15##x,_p6##y,z,c)), \ - (I[299] = (T)(img)(_n15##x,_p5##y,z,c)), \ - (I[329] = (T)(img)(_n15##x,_p4##y,z,c)), \ - (I[359] = (T)(img)(_n15##x,_p3##y,z,c)), \ - (I[389] = (T)(img)(_n15##x,_p2##y,z,c)), \ - (I[419] = (T)(img)(_n15##x,_p1##y,z,c)), \ - (I[449] = (T)(img)(_n15##x,y,z,c)), \ - (I[479] = (T)(img)(_n15##x,_n1##y,z,c)), \ - (I[509] = (T)(img)(_n15##x,_n2##y,z,c)), \ - (I[539] = (T)(img)(_n15##x,_n3##y,z,c)), \ - (I[569] = (T)(img)(_n15##x,_n4##y,z,c)), \ - (I[599] = (T)(img)(_n15##x,_n5##y,z,c)), \ - (I[629] = (T)(img)(_n15##x,_n6##y,z,c)), \ - (I[659] = (T)(img)(_n15##x,_n7##y,z,c)), \ - (I[689] = (T)(img)(_n15##x,_n8##y,z,c)), \ - (I[719] = (T)(img)(_n15##x,_n9##y,z,c)), \ - (I[749] = (T)(img)(_n15##x,_n10##y,z,c)), \ - (I[779] = (T)(img)(_n15##x,_n11##y,z,c)), \ - (I[809] = (T)(img)(_n15##x,_n12##y,z,c)), \ - (I[839] = (T)(img)(_n15##x,_n13##y,z,c)), \ - (I[869] = (T)(img)(_n15##x,_n14##y,z,c)), \ - (I[899] = (T)(img)(_n15##x,_n15##y,z,c)),1)) || \ - _n14##x==--_n15##x || _n13##x==--_n14##x || _n12##x==--_n13##x || _n11##x==--_n12##x || _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n15##x = _n14##x = _n13##x = _n12##x = _n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], \ - I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], \ - I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], \ - I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], \ - I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], \ - I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], \ - I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], \ - I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], \ - I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], \ - I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], \ - I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], \ - I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], \ - I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], \ - I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], I[415] = I[416], I[416] = I[417], I[417] = I[418], I[418] = I[419], \ - I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], I[447] = I[448], I[448] = I[449], \ - I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], I[463] = I[464], I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], \ - I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], I[493] = I[494], I[494] = I[495], I[495] = I[496], I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], I[503] = I[504], I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], \ - I[510] = I[511], I[511] = I[512], I[512] = I[513], I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], I[519] = I[520], I[520] = I[521], I[521] = I[522], I[522] = I[523], I[523] = I[524], I[524] = I[525], I[525] = I[526], I[526] = I[527], I[527] = I[528], I[528] = I[529], I[529] = I[530], I[530] = I[531], I[531] = I[532], I[532] = I[533], I[533] = I[534], I[534] = I[535], I[535] = I[536], I[536] = I[537], I[537] = I[538], I[538] = I[539], \ - I[540] = I[541], I[541] = I[542], I[542] = I[543], I[543] = I[544], I[544] = I[545], I[545] = I[546], I[546] = I[547], I[547] = I[548], I[548] = I[549], I[549] = I[550], I[550] = I[551], I[551] = I[552], I[552] = I[553], I[553] = I[554], I[554] = I[555], I[555] = I[556], I[556] = I[557], I[557] = I[558], I[558] = I[559], I[559] = I[560], I[560] = I[561], I[561] = I[562], I[562] = I[563], I[563] = I[564], I[564] = I[565], I[565] = I[566], I[566] = I[567], I[567] = I[568], I[568] = I[569], \ - I[570] = I[571], I[571] = I[572], I[572] = I[573], I[573] = I[574], I[574] = I[575], I[575] = I[576], I[576] = I[577], I[577] = I[578], I[578] = I[579], I[579] = I[580], I[580] = I[581], I[581] = I[582], I[582] = I[583], I[583] = I[584], I[584] = I[585], I[585] = I[586], I[586] = I[587], I[587] = I[588], I[588] = I[589], I[589] = I[590], I[590] = I[591], I[591] = I[592], I[592] = I[593], I[593] = I[594], I[594] = I[595], I[595] = I[596], I[596] = I[597], I[597] = I[598], I[598] = I[599], \ - I[600] = I[601], I[601] = I[602], I[602] = I[603], I[603] = I[604], I[604] = I[605], I[605] = I[606], I[606] = I[607], I[607] = I[608], I[608] = I[609], I[609] = I[610], I[610] = I[611], I[611] = I[612], I[612] = I[613], I[613] = I[614], I[614] = I[615], I[615] = I[616], I[616] = I[617], I[617] = I[618], I[618] = I[619], I[619] = I[620], I[620] = I[621], I[621] = I[622], I[622] = I[623], I[623] = I[624], I[624] = I[625], I[625] = I[626], I[626] = I[627], I[627] = I[628], I[628] = I[629], \ - I[630] = I[631], I[631] = I[632], I[632] = I[633], I[633] = I[634], I[634] = I[635], I[635] = I[636], I[636] = I[637], I[637] = I[638], I[638] = I[639], I[639] = I[640], I[640] = I[641], I[641] = I[642], I[642] = I[643], I[643] = I[644], I[644] = I[645], I[645] = I[646], I[646] = I[647], I[647] = I[648], I[648] = I[649], I[649] = I[650], I[650] = I[651], I[651] = I[652], I[652] = I[653], I[653] = I[654], I[654] = I[655], I[655] = I[656], I[656] = I[657], I[657] = I[658], I[658] = I[659], \ - I[660] = I[661], I[661] = I[662], I[662] = I[663], I[663] = I[664], I[664] = I[665], I[665] = I[666], I[666] = I[667], I[667] = I[668], I[668] = I[669], I[669] = I[670], I[670] = I[671], I[671] = I[672], I[672] = I[673], I[673] = I[674], I[674] = I[675], I[675] = I[676], I[676] = I[677], I[677] = I[678], I[678] = I[679], I[679] = I[680], I[680] = I[681], I[681] = I[682], I[682] = I[683], I[683] = I[684], I[684] = I[685], I[685] = I[686], I[686] = I[687], I[687] = I[688], I[688] = I[689], \ - I[690] = I[691], I[691] = I[692], I[692] = I[693], I[693] = I[694], I[694] = I[695], I[695] = I[696], I[696] = I[697], I[697] = I[698], I[698] = I[699], I[699] = I[700], I[700] = I[701], I[701] = I[702], I[702] = I[703], I[703] = I[704], I[704] = I[705], I[705] = I[706], I[706] = I[707], I[707] = I[708], I[708] = I[709], I[709] = I[710], I[710] = I[711], I[711] = I[712], I[712] = I[713], I[713] = I[714], I[714] = I[715], I[715] = I[716], I[716] = I[717], I[717] = I[718], I[718] = I[719], \ - I[720] = I[721], I[721] = I[722], I[722] = I[723], I[723] = I[724], I[724] = I[725], I[725] = I[726], I[726] = I[727], I[727] = I[728], I[728] = I[729], I[729] = I[730], I[730] = I[731], I[731] = I[732], I[732] = I[733], I[733] = I[734], I[734] = I[735], I[735] = I[736], I[736] = I[737], I[737] = I[738], I[738] = I[739], I[739] = I[740], I[740] = I[741], I[741] = I[742], I[742] = I[743], I[743] = I[744], I[744] = I[745], I[745] = I[746], I[746] = I[747], I[747] = I[748], I[748] = I[749], \ - I[750] = I[751], I[751] = I[752], I[752] = I[753], I[753] = I[754], I[754] = I[755], I[755] = I[756], I[756] = I[757], I[757] = I[758], I[758] = I[759], I[759] = I[760], I[760] = I[761], I[761] = I[762], I[762] = I[763], I[763] = I[764], I[764] = I[765], I[765] = I[766], I[766] = I[767], I[767] = I[768], I[768] = I[769], I[769] = I[770], I[770] = I[771], I[771] = I[772], I[772] = I[773], I[773] = I[774], I[774] = I[775], I[775] = I[776], I[776] = I[777], I[777] = I[778], I[778] = I[779], \ - I[780] = I[781], I[781] = I[782], I[782] = I[783], I[783] = I[784], I[784] = I[785], I[785] = I[786], I[786] = I[787], I[787] = I[788], I[788] = I[789], I[789] = I[790], I[790] = I[791], I[791] = I[792], I[792] = I[793], I[793] = I[794], I[794] = I[795], I[795] = I[796], I[796] = I[797], I[797] = I[798], I[798] = I[799], I[799] = I[800], I[800] = I[801], I[801] = I[802], I[802] = I[803], I[803] = I[804], I[804] = I[805], I[805] = I[806], I[806] = I[807], I[807] = I[808], I[808] = I[809], \ - I[810] = I[811], I[811] = I[812], I[812] = I[813], I[813] = I[814], I[814] = I[815], I[815] = I[816], I[816] = I[817], I[817] = I[818], I[818] = I[819], I[819] = I[820], I[820] = I[821], I[821] = I[822], I[822] = I[823], I[823] = I[824], I[824] = I[825], I[825] = I[826], I[826] = I[827], I[827] = I[828], I[828] = I[829], I[829] = I[830], I[830] = I[831], I[831] = I[832], I[832] = I[833], I[833] = I[834], I[834] = I[835], I[835] = I[836], I[836] = I[837], I[837] = I[838], I[838] = I[839], \ - I[840] = I[841], I[841] = I[842], I[842] = I[843], I[843] = I[844], I[844] = I[845], I[845] = I[846], I[846] = I[847], I[847] = I[848], I[848] = I[849], I[849] = I[850], I[850] = I[851], I[851] = I[852], I[852] = I[853], I[853] = I[854], I[854] = I[855], I[855] = I[856], I[856] = I[857], I[857] = I[858], I[858] = I[859], I[859] = I[860], I[860] = I[861], I[861] = I[862], I[862] = I[863], I[863] = I[864], I[864] = I[865], I[865] = I[866], I[866] = I[867], I[867] = I[868], I[868] = I[869], \ - I[870] = I[871], I[871] = I[872], I[872] = I[873], I[873] = I[874], I[874] = I[875], I[875] = I[876], I[876] = I[877], I[877] = I[878], I[878] = I[879], I[879] = I[880], I[880] = I[881], I[881] = I[882], I[882] = I[883], I[883] = I[884], I[884] = I[885], I[885] = I[886], I[886] = I[887], I[887] = I[888], I[888] = I[889], I[889] = I[890], I[890] = I[891], I[891] = I[892], I[892] = I[893], I[893] = I[894], I[894] = I[895], I[895] = I[896], I[896] = I[897], I[897] = I[898], I[898] = I[899], \ - _p14##x = _p13##x, _p13##x = _p12##x, _p12##x = _p11##x, _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x, ++_n12##x, ++_n13##x, ++_n14##x, ++_n15##x) - -#define cimg_get30x30(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p14##x,_p14##y,z,c), I[1] = (T)(img)(_p13##x,_p14##y,z,c), I[2] = (T)(img)(_p12##x,_p14##y,z,c), I[3] = (T)(img)(_p11##x,_p14##y,z,c), I[4] = (T)(img)(_p10##x,_p14##y,z,c), I[5] = (T)(img)(_p9##x,_p14##y,z,c), I[6] = (T)(img)(_p8##x,_p14##y,z,c), I[7] = (T)(img)(_p7##x,_p14##y,z,c), I[8] = (T)(img)(_p6##x,_p14##y,z,c), I[9] = (T)(img)(_p5##x,_p14##y,z,c), I[10] = (T)(img)(_p4##x,_p14##y,z,c), I[11] = (T)(img)(_p3##x,_p14##y,z,c), I[12] = (T)(img)(_p2##x,_p14##y,z,c), I[13] = (T)(img)(_p1##x,_p14##y,z,c), I[14] = (T)(img)(x,_p14##y,z,c), I[15] = (T)(img)(_n1##x,_p14##y,z,c), I[16] = (T)(img)(_n2##x,_p14##y,z,c), I[17] = (T)(img)(_n3##x,_p14##y,z,c), I[18] = (T)(img)(_n4##x,_p14##y,z,c), I[19] = (T)(img)(_n5##x,_p14##y,z,c), I[20] = (T)(img)(_n6##x,_p14##y,z,c), I[21] = (T)(img)(_n7##x,_p14##y,z,c), I[22] = (T)(img)(_n8##x,_p14##y,z,c), I[23] = (T)(img)(_n9##x,_p14##y,z,c), I[24] = (T)(img)(_n10##x,_p14##y,z,c), I[25] = (T)(img)(_n11##x,_p14##y,z,c), I[26] = (T)(img)(_n12##x,_p14##y,z,c), I[27] = (T)(img)(_n13##x,_p14##y,z,c), I[28] = (T)(img)(_n14##x,_p14##y,z,c), I[29] = (T)(img)(_n15##x,_p14##y,z,c), \ - I[30] = (T)(img)(_p14##x,_p13##y,z,c), I[31] = (T)(img)(_p13##x,_p13##y,z,c), I[32] = (T)(img)(_p12##x,_p13##y,z,c), I[33] = (T)(img)(_p11##x,_p13##y,z,c), I[34] = (T)(img)(_p10##x,_p13##y,z,c), I[35] = (T)(img)(_p9##x,_p13##y,z,c), I[36] = (T)(img)(_p8##x,_p13##y,z,c), I[37] = (T)(img)(_p7##x,_p13##y,z,c), I[38] = (T)(img)(_p6##x,_p13##y,z,c), I[39] = (T)(img)(_p5##x,_p13##y,z,c), I[40] = (T)(img)(_p4##x,_p13##y,z,c), I[41] = (T)(img)(_p3##x,_p13##y,z,c), I[42] = (T)(img)(_p2##x,_p13##y,z,c), I[43] = (T)(img)(_p1##x,_p13##y,z,c), I[44] = (T)(img)(x,_p13##y,z,c), I[45] = (T)(img)(_n1##x,_p13##y,z,c), I[46] = (T)(img)(_n2##x,_p13##y,z,c), I[47] = (T)(img)(_n3##x,_p13##y,z,c), I[48] = (T)(img)(_n4##x,_p13##y,z,c), I[49] = (T)(img)(_n5##x,_p13##y,z,c), I[50] = (T)(img)(_n6##x,_p13##y,z,c), I[51] = (T)(img)(_n7##x,_p13##y,z,c), I[52] = (T)(img)(_n8##x,_p13##y,z,c), I[53] = (T)(img)(_n9##x,_p13##y,z,c), I[54] = (T)(img)(_n10##x,_p13##y,z,c), I[55] = (T)(img)(_n11##x,_p13##y,z,c), I[56] = (T)(img)(_n12##x,_p13##y,z,c), I[57] = (T)(img)(_n13##x,_p13##y,z,c), I[58] = (T)(img)(_n14##x,_p13##y,z,c), I[59] = (T)(img)(_n15##x,_p13##y,z,c), \ - I[60] = (T)(img)(_p14##x,_p12##y,z,c), I[61] = (T)(img)(_p13##x,_p12##y,z,c), I[62] = (T)(img)(_p12##x,_p12##y,z,c), I[63] = (T)(img)(_p11##x,_p12##y,z,c), I[64] = (T)(img)(_p10##x,_p12##y,z,c), I[65] = (T)(img)(_p9##x,_p12##y,z,c), I[66] = (T)(img)(_p8##x,_p12##y,z,c), I[67] = (T)(img)(_p7##x,_p12##y,z,c), I[68] = (T)(img)(_p6##x,_p12##y,z,c), I[69] = (T)(img)(_p5##x,_p12##y,z,c), I[70] = (T)(img)(_p4##x,_p12##y,z,c), I[71] = (T)(img)(_p3##x,_p12##y,z,c), I[72] = (T)(img)(_p2##x,_p12##y,z,c), I[73] = (T)(img)(_p1##x,_p12##y,z,c), I[74] = (T)(img)(x,_p12##y,z,c), I[75] = (T)(img)(_n1##x,_p12##y,z,c), I[76] = (T)(img)(_n2##x,_p12##y,z,c), I[77] = (T)(img)(_n3##x,_p12##y,z,c), I[78] = (T)(img)(_n4##x,_p12##y,z,c), I[79] = (T)(img)(_n5##x,_p12##y,z,c), I[80] = (T)(img)(_n6##x,_p12##y,z,c), I[81] = (T)(img)(_n7##x,_p12##y,z,c), I[82] = (T)(img)(_n8##x,_p12##y,z,c), I[83] = (T)(img)(_n9##x,_p12##y,z,c), I[84] = (T)(img)(_n10##x,_p12##y,z,c), I[85] = (T)(img)(_n11##x,_p12##y,z,c), I[86] = (T)(img)(_n12##x,_p12##y,z,c), I[87] = (T)(img)(_n13##x,_p12##y,z,c), I[88] = (T)(img)(_n14##x,_p12##y,z,c), I[89] = (T)(img)(_n15##x,_p12##y,z,c), \ - I[90] = (T)(img)(_p14##x,_p11##y,z,c), I[91] = (T)(img)(_p13##x,_p11##y,z,c), I[92] = (T)(img)(_p12##x,_p11##y,z,c), I[93] = (T)(img)(_p11##x,_p11##y,z,c), I[94] = (T)(img)(_p10##x,_p11##y,z,c), I[95] = (T)(img)(_p9##x,_p11##y,z,c), I[96] = (T)(img)(_p8##x,_p11##y,z,c), I[97] = (T)(img)(_p7##x,_p11##y,z,c), I[98] = (T)(img)(_p6##x,_p11##y,z,c), I[99] = (T)(img)(_p5##x,_p11##y,z,c), I[100] = (T)(img)(_p4##x,_p11##y,z,c), I[101] = (T)(img)(_p3##x,_p11##y,z,c), I[102] = (T)(img)(_p2##x,_p11##y,z,c), I[103] = (T)(img)(_p1##x,_p11##y,z,c), I[104] = (T)(img)(x,_p11##y,z,c), I[105] = (T)(img)(_n1##x,_p11##y,z,c), I[106] = (T)(img)(_n2##x,_p11##y,z,c), I[107] = (T)(img)(_n3##x,_p11##y,z,c), I[108] = (T)(img)(_n4##x,_p11##y,z,c), I[109] = (T)(img)(_n5##x,_p11##y,z,c), I[110] = (T)(img)(_n6##x,_p11##y,z,c), I[111] = (T)(img)(_n7##x,_p11##y,z,c), I[112] = (T)(img)(_n8##x,_p11##y,z,c), I[113] = (T)(img)(_n9##x,_p11##y,z,c), I[114] = (T)(img)(_n10##x,_p11##y,z,c), I[115] = (T)(img)(_n11##x,_p11##y,z,c), I[116] = (T)(img)(_n12##x,_p11##y,z,c), I[117] = (T)(img)(_n13##x,_p11##y,z,c), I[118] = (T)(img)(_n14##x,_p11##y,z,c), I[119] = (T)(img)(_n15##x,_p11##y,z,c), \ - I[120] = (T)(img)(_p14##x,_p10##y,z,c), I[121] = (T)(img)(_p13##x,_p10##y,z,c), I[122] = (T)(img)(_p12##x,_p10##y,z,c), I[123] = (T)(img)(_p11##x,_p10##y,z,c), I[124] = (T)(img)(_p10##x,_p10##y,z,c), I[125] = (T)(img)(_p9##x,_p10##y,z,c), I[126] = (T)(img)(_p8##x,_p10##y,z,c), I[127] = (T)(img)(_p7##x,_p10##y,z,c), I[128] = (T)(img)(_p6##x,_p10##y,z,c), I[129] = (T)(img)(_p5##x,_p10##y,z,c), I[130] = (T)(img)(_p4##x,_p10##y,z,c), I[131] = (T)(img)(_p3##x,_p10##y,z,c), I[132] = (T)(img)(_p2##x,_p10##y,z,c), I[133] = (T)(img)(_p1##x,_p10##y,z,c), I[134] = (T)(img)(x,_p10##y,z,c), I[135] = (T)(img)(_n1##x,_p10##y,z,c), I[136] = (T)(img)(_n2##x,_p10##y,z,c), I[137] = (T)(img)(_n3##x,_p10##y,z,c), I[138] = (T)(img)(_n4##x,_p10##y,z,c), I[139] = (T)(img)(_n5##x,_p10##y,z,c), I[140] = (T)(img)(_n6##x,_p10##y,z,c), I[141] = (T)(img)(_n7##x,_p10##y,z,c), I[142] = (T)(img)(_n8##x,_p10##y,z,c), I[143] = (T)(img)(_n9##x,_p10##y,z,c), I[144] = (T)(img)(_n10##x,_p10##y,z,c), I[145] = (T)(img)(_n11##x,_p10##y,z,c), I[146] = (T)(img)(_n12##x,_p10##y,z,c), I[147] = (T)(img)(_n13##x,_p10##y,z,c), I[148] = (T)(img)(_n14##x,_p10##y,z,c), I[149] = (T)(img)(_n15##x,_p10##y,z,c), \ - I[150] = (T)(img)(_p14##x,_p9##y,z,c), I[151] = (T)(img)(_p13##x,_p9##y,z,c), I[152] = (T)(img)(_p12##x,_p9##y,z,c), I[153] = (T)(img)(_p11##x,_p9##y,z,c), I[154] = (T)(img)(_p10##x,_p9##y,z,c), I[155] = (T)(img)(_p9##x,_p9##y,z,c), I[156] = (T)(img)(_p8##x,_p9##y,z,c), I[157] = (T)(img)(_p7##x,_p9##y,z,c), I[158] = (T)(img)(_p6##x,_p9##y,z,c), I[159] = (T)(img)(_p5##x,_p9##y,z,c), I[160] = (T)(img)(_p4##x,_p9##y,z,c), I[161] = (T)(img)(_p3##x,_p9##y,z,c), I[162] = (T)(img)(_p2##x,_p9##y,z,c), I[163] = (T)(img)(_p1##x,_p9##y,z,c), I[164] = (T)(img)(x,_p9##y,z,c), I[165] = (T)(img)(_n1##x,_p9##y,z,c), I[166] = (T)(img)(_n2##x,_p9##y,z,c), I[167] = (T)(img)(_n3##x,_p9##y,z,c), I[168] = (T)(img)(_n4##x,_p9##y,z,c), I[169] = (T)(img)(_n5##x,_p9##y,z,c), I[170] = (T)(img)(_n6##x,_p9##y,z,c), I[171] = (T)(img)(_n7##x,_p9##y,z,c), I[172] = (T)(img)(_n8##x,_p9##y,z,c), I[173] = (T)(img)(_n9##x,_p9##y,z,c), I[174] = (T)(img)(_n10##x,_p9##y,z,c), I[175] = (T)(img)(_n11##x,_p9##y,z,c), I[176] = (T)(img)(_n12##x,_p9##y,z,c), I[177] = (T)(img)(_n13##x,_p9##y,z,c), I[178] = (T)(img)(_n14##x,_p9##y,z,c), I[179] = (T)(img)(_n15##x,_p9##y,z,c), \ - I[180] = (T)(img)(_p14##x,_p8##y,z,c), I[181] = (T)(img)(_p13##x,_p8##y,z,c), I[182] = (T)(img)(_p12##x,_p8##y,z,c), I[183] = (T)(img)(_p11##x,_p8##y,z,c), I[184] = (T)(img)(_p10##x,_p8##y,z,c), I[185] = (T)(img)(_p9##x,_p8##y,z,c), I[186] = (T)(img)(_p8##x,_p8##y,z,c), I[187] = (T)(img)(_p7##x,_p8##y,z,c), I[188] = (T)(img)(_p6##x,_p8##y,z,c), I[189] = (T)(img)(_p5##x,_p8##y,z,c), I[190] = (T)(img)(_p4##x,_p8##y,z,c), I[191] = (T)(img)(_p3##x,_p8##y,z,c), I[192] = (T)(img)(_p2##x,_p8##y,z,c), I[193] = (T)(img)(_p1##x,_p8##y,z,c), I[194] = (T)(img)(x,_p8##y,z,c), I[195] = (T)(img)(_n1##x,_p8##y,z,c), I[196] = (T)(img)(_n2##x,_p8##y,z,c), I[197] = (T)(img)(_n3##x,_p8##y,z,c), I[198] = (T)(img)(_n4##x,_p8##y,z,c), I[199] = (T)(img)(_n5##x,_p8##y,z,c), I[200] = (T)(img)(_n6##x,_p8##y,z,c), I[201] = (T)(img)(_n7##x,_p8##y,z,c), I[202] = (T)(img)(_n8##x,_p8##y,z,c), I[203] = (T)(img)(_n9##x,_p8##y,z,c), I[204] = (T)(img)(_n10##x,_p8##y,z,c), I[205] = (T)(img)(_n11##x,_p8##y,z,c), I[206] = (T)(img)(_n12##x,_p8##y,z,c), I[207] = (T)(img)(_n13##x,_p8##y,z,c), I[208] = (T)(img)(_n14##x,_p8##y,z,c), I[209] = (T)(img)(_n15##x,_p8##y,z,c), \ - I[210] = (T)(img)(_p14##x,_p7##y,z,c), I[211] = (T)(img)(_p13##x,_p7##y,z,c), I[212] = (T)(img)(_p12##x,_p7##y,z,c), I[213] = (T)(img)(_p11##x,_p7##y,z,c), I[214] = (T)(img)(_p10##x,_p7##y,z,c), I[215] = (T)(img)(_p9##x,_p7##y,z,c), I[216] = (T)(img)(_p8##x,_p7##y,z,c), I[217] = (T)(img)(_p7##x,_p7##y,z,c), I[218] = (T)(img)(_p6##x,_p7##y,z,c), I[219] = (T)(img)(_p5##x,_p7##y,z,c), I[220] = (T)(img)(_p4##x,_p7##y,z,c), I[221] = (T)(img)(_p3##x,_p7##y,z,c), I[222] = (T)(img)(_p2##x,_p7##y,z,c), I[223] = (T)(img)(_p1##x,_p7##y,z,c), I[224] = (T)(img)(x,_p7##y,z,c), I[225] = (T)(img)(_n1##x,_p7##y,z,c), I[226] = (T)(img)(_n2##x,_p7##y,z,c), I[227] = (T)(img)(_n3##x,_p7##y,z,c), I[228] = (T)(img)(_n4##x,_p7##y,z,c), I[229] = (T)(img)(_n5##x,_p7##y,z,c), I[230] = (T)(img)(_n6##x,_p7##y,z,c), I[231] = (T)(img)(_n7##x,_p7##y,z,c), I[232] = (T)(img)(_n8##x,_p7##y,z,c), I[233] = (T)(img)(_n9##x,_p7##y,z,c), I[234] = (T)(img)(_n10##x,_p7##y,z,c), I[235] = (T)(img)(_n11##x,_p7##y,z,c), I[236] = (T)(img)(_n12##x,_p7##y,z,c), I[237] = (T)(img)(_n13##x,_p7##y,z,c), I[238] = (T)(img)(_n14##x,_p7##y,z,c), I[239] = (T)(img)(_n15##x,_p7##y,z,c), \ - I[240] = (T)(img)(_p14##x,_p6##y,z,c), I[241] = (T)(img)(_p13##x,_p6##y,z,c), I[242] = (T)(img)(_p12##x,_p6##y,z,c), I[243] = (T)(img)(_p11##x,_p6##y,z,c), I[244] = (T)(img)(_p10##x,_p6##y,z,c), I[245] = (T)(img)(_p9##x,_p6##y,z,c), I[246] = (T)(img)(_p8##x,_p6##y,z,c), I[247] = (T)(img)(_p7##x,_p6##y,z,c), I[248] = (T)(img)(_p6##x,_p6##y,z,c), I[249] = (T)(img)(_p5##x,_p6##y,z,c), I[250] = (T)(img)(_p4##x,_p6##y,z,c), I[251] = (T)(img)(_p3##x,_p6##y,z,c), I[252] = (T)(img)(_p2##x,_p6##y,z,c), I[253] = (T)(img)(_p1##x,_p6##y,z,c), I[254] = (T)(img)(x,_p6##y,z,c), I[255] = (T)(img)(_n1##x,_p6##y,z,c), I[256] = (T)(img)(_n2##x,_p6##y,z,c), I[257] = (T)(img)(_n3##x,_p6##y,z,c), I[258] = (T)(img)(_n4##x,_p6##y,z,c), I[259] = (T)(img)(_n5##x,_p6##y,z,c), I[260] = (T)(img)(_n6##x,_p6##y,z,c), I[261] = (T)(img)(_n7##x,_p6##y,z,c), I[262] = (T)(img)(_n8##x,_p6##y,z,c), I[263] = (T)(img)(_n9##x,_p6##y,z,c), I[264] = (T)(img)(_n10##x,_p6##y,z,c), I[265] = (T)(img)(_n11##x,_p6##y,z,c), I[266] = (T)(img)(_n12##x,_p6##y,z,c), I[267] = (T)(img)(_n13##x,_p6##y,z,c), I[268] = (T)(img)(_n14##x,_p6##y,z,c), I[269] = (T)(img)(_n15##x,_p6##y,z,c), \ - I[270] = (T)(img)(_p14##x,_p5##y,z,c), I[271] = (T)(img)(_p13##x,_p5##y,z,c), I[272] = (T)(img)(_p12##x,_p5##y,z,c), I[273] = (T)(img)(_p11##x,_p5##y,z,c), I[274] = (T)(img)(_p10##x,_p5##y,z,c), I[275] = (T)(img)(_p9##x,_p5##y,z,c), I[276] = (T)(img)(_p8##x,_p5##y,z,c), I[277] = (T)(img)(_p7##x,_p5##y,z,c), I[278] = (T)(img)(_p6##x,_p5##y,z,c), I[279] = (T)(img)(_p5##x,_p5##y,z,c), I[280] = (T)(img)(_p4##x,_p5##y,z,c), I[281] = (T)(img)(_p3##x,_p5##y,z,c), I[282] = (T)(img)(_p2##x,_p5##y,z,c), I[283] = (T)(img)(_p1##x,_p5##y,z,c), I[284] = (T)(img)(x,_p5##y,z,c), I[285] = (T)(img)(_n1##x,_p5##y,z,c), I[286] = (T)(img)(_n2##x,_p5##y,z,c), I[287] = (T)(img)(_n3##x,_p5##y,z,c), I[288] = (T)(img)(_n4##x,_p5##y,z,c), I[289] = (T)(img)(_n5##x,_p5##y,z,c), I[290] = (T)(img)(_n6##x,_p5##y,z,c), I[291] = (T)(img)(_n7##x,_p5##y,z,c), I[292] = (T)(img)(_n8##x,_p5##y,z,c), I[293] = (T)(img)(_n9##x,_p5##y,z,c), I[294] = (T)(img)(_n10##x,_p5##y,z,c), I[295] = (T)(img)(_n11##x,_p5##y,z,c), I[296] = (T)(img)(_n12##x,_p5##y,z,c), I[297] = (T)(img)(_n13##x,_p5##y,z,c), I[298] = (T)(img)(_n14##x,_p5##y,z,c), I[299] = (T)(img)(_n15##x,_p5##y,z,c), \ - I[300] = (T)(img)(_p14##x,_p4##y,z,c), I[301] = (T)(img)(_p13##x,_p4##y,z,c), I[302] = (T)(img)(_p12##x,_p4##y,z,c), I[303] = (T)(img)(_p11##x,_p4##y,z,c), I[304] = (T)(img)(_p10##x,_p4##y,z,c), I[305] = (T)(img)(_p9##x,_p4##y,z,c), I[306] = (T)(img)(_p8##x,_p4##y,z,c), I[307] = (T)(img)(_p7##x,_p4##y,z,c), I[308] = (T)(img)(_p6##x,_p4##y,z,c), I[309] = (T)(img)(_p5##x,_p4##y,z,c), I[310] = (T)(img)(_p4##x,_p4##y,z,c), I[311] = (T)(img)(_p3##x,_p4##y,z,c), I[312] = (T)(img)(_p2##x,_p4##y,z,c), I[313] = (T)(img)(_p1##x,_p4##y,z,c), I[314] = (T)(img)(x,_p4##y,z,c), I[315] = (T)(img)(_n1##x,_p4##y,z,c), I[316] = (T)(img)(_n2##x,_p4##y,z,c), I[317] = (T)(img)(_n3##x,_p4##y,z,c), I[318] = (T)(img)(_n4##x,_p4##y,z,c), I[319] = (T)(img)(_n5##x,_p4##y,z,c), I[320] = (T)(img)(_n6##x,_p4##y,z,c), I[321] = (T)(img)(_n7##x,_p4##y,z,c), I[322] = (T)(img)(_n8##x,_p4##y,z,c), I[323] = (T)(img)(_n9##x,_p4##y,z,c), I[324] = (T)(img)(_n10##x,_p4##y,z,c), I[325] = (T)(img)(_n11##x,_p4##y,z,c), I[326] = (T)(img)(_n12##x,_p4##y,z,c), I[327] = (T)(img)(_n13##x,_p4##y,z,c), I[328] = (T)(img)(_n14##x,_p4##y,z,c), I[329] = (T)(img)(_n15##x,_p4##y,z,c), \ - I[330] = (T)(img)(_p14##x,_p3##y,z,c), I[331] = (T)(img)(_p13##x,_p3##y,z,c), I[332] = (T)(img)(_p12##x,_p3##y,z,c), I[333] = (T)(img)(_p11##x,_p3##y,z,c), I[334] = (T)(img)(_p10##x,_p3##y,z,c), I[335] = (T)(img)(_p9##x,_p3##y,z,c), I[336] = (T)(img)(_p8##x,_p3##y,z,c), I[337] = (T)(img)(_p7##x,_p3##y,z,c), I[338] = (T)(img)(_p6##x,_p3##y,z,c), I[339] = (T)(img)(_p5##x,_p3##y,z,c), I[340] = (T)(img)(_p4##x,_p3##y,z,c), I[341] = (T)(img)(_p3##x,_p3##y,z,c), I[342] = (T)(img)(_p2##x,_p3##y,z,c), I[343] = (T)(img)(_p1##x,_p3##y,z,c), I[344] = (T)(img)(x,_p3##y,z,c), I[345] = (T)(img)(_n1##x,_p3##y,z,c), I[346] = (T)(img)(_n2##x,_p3##y,z,c), I[347] = (T)(img)(_n3##x,_p3##y,z,c), I[348] = (T)(img)(_n4##x,_p3##y,z,c), I[349] = (T)(img)(_n5##x,_p3##y,z,c), I[350] = (T)(img)(_n6##x,_p3##y,z,c), I[351] = (T)(img)(_n7##x,_p3##y,z,c), I[352] = (T)(img)(_n8##x,_p3##y,z,c), I[353] = (T)(img)(_n9##x,_p3##y,z,c), I[354] = (T)(img)(_n10##x,_p3##y,z,c), I[355] = (T)(img)(_n11##x,_p3##y,z,c), I[356] = (T)(img)(_n12##x,_p3##y,z,c), I[357] = (T)(img)(_n13##x,_p3##y,z,c), I[358] = (T)(img)(_n14##x,_p3##y,z,c), I[359] = (T)(img)(_n15##x,_p3##y,z,c), \ - I[360] = (T)(img)(_p14##x,_p2##y,z,c), I[361] = (T)(img)(_p13##x,_p2##y,z,c), I[362] = (T)(img)(_p12##x,_p2##y,z,c), I[363] = (T)(img)(_p11##x,_p2##y,z,c), I[364] = (T)(img)(_p10##x,_p2##y,z,c), I[365] = (T)(img)(_p9##x,_p2##y,z,c), I[366] = (T)(img)(_p8##x,_p2##y,z,c), I[367] = (T)(img)(_p7##x,_p2##y,z,c), I[368] = (T)(img)(_p6##x,_p2##y,z,c), I[369] = (T)(img)(_p5##x,_p2##y,z,c), I[370] = (T)(img)(_p4##x,_p2##y,z,c), I[371] = (T)(img)(_p3##x,_p2##y,z,c), I[372] = (T)(img)(_p2##x,_p2##y,z,c), I[373] = (T)(img)(_p1##x,_p2##y,z,c), I[374] = (T)(img)(x,_p2##y,z,c), I[375] = (T)(img)(_n1##x,_p2##y,z,c), I[376] = (T)(img)(_n2##x,_p2##y,z,c), I[377] = (T)(img)(_n3##x,_p2##y,z,c), I[378] = (T)(img)(_n4##x,_p2##y,z,c), I[379] = (T)(img)(_n5##x,_p2##y,z,c), I[380] = (T)(img)(_n6##x,_p2##y,z,c), I[381] = (T)(img)(_n7##x,_p2##y,z,c), I[382] = (T)(img)(_n8##x,_p2##y,z,c), I[383] = (T)(img)(_n9##x,_p2##y,z,c), I[384] = (T)(img)(_n10##x,_p2##y,z,c), I[385] = (T)(img)(_n11##x,_p2##y,z,c), I[386] = (T)(img)(_n12##x,_p2##y,z,c), I[387] = (T)(img)(_n13##x,_p2##y,z,c), I[388] = (T)(img)(_n14##x,_p2##y,z,c), I[389] = (T)(img)(_n15##x,_p2##y,z,c), \ - I[390] = (T)(img)(_p14##x,_p1##y,z,c), I[391] = (T)(img)(_p13##x,_p1##y,z,c), I[392] = (T)(img)(_p12##x,_p1##y,z,c), I[393] = (T)(img)(_p11##x,_p1##y,z,c), I[394] = (T)(img)(_p10##x,_p1##y,z,c), I[395] = (T)(img)(_p9##x,_p1##y,z,c), I[396] = (T)(img)(_p8##x,_p1##y,z,c), I[397] = (T)(img)(_p7##x,_p1##y,z,c), I[398] = (T)(img)(_p6##x,_p1##y,z,c), I[399] = (T)(img)(_p5##x,_p1##y,z,c), I[400] = (T)(img)(_p4##x,_p1##y,z,c), I[401] = (T)(img)(_p3##x,_p1##y,z,c), I[402] = (T)(img)(_p2##x,_p1##y,z,c), I[403] = (T)(img)(_p1##x,_p1##y,z,c), I[404] = (T)(img)(x,_p1##y,z,c), I[405] = (T)(img)(_n1##x,_p1##y,z,c), I[406] = (T)(img)(_n2##x,_p1##y,z,c), I[407] = (T)(img)(_n3##x,_p1##y,z,c), I[408] = (T)(img)(_n4##x,_p1##y,z,c), I[409] = (T)(img)(_n5##x,_p1##y,z,c), I[410] = (T)(img)(_n6##x,_p1##y,z,c), I[411] = (T)(img)(_n7##x,_p1##y,z,c), I[412] = (T)(img)(_n8##x,_p1##y,z,c), I[413] = (T)(img)(_n9##x,_p1##y,z,c), I[414] = (T)(img)(_n10##x,_p1##y,z,c), I[415] = (T)(img)(_n11##x,_p1##y,z,c), I[416] = (T)(img)(_n12##x,_p1##y,z,c), I[417] = (T)(img)(_n13##x,_p1##y,z,c), I[418] = (T)(img)(_n14##x,_p1##y,z,c), I[419] = (T)(img)(_n15##x,_p1##y,z,c), \ - I[420] = (T)(img)(_p14##x,y,z,c), I[421] = (T)(img)(_p13##x,y,z,c), I[422] = (T)(img)(_p12##x,y,z,c), I[423] = (T)(img)(_p11##x,y,z,c), I[424] = (T)(img)(_p10##x,y,z,c), I[425] = (T)(img)(_p9##x,y,z,c), I[426] = (T)(img)(_p8##x,y,z,c), I[427] = (T)(img)(_p7##x,y,z,c), I[428] = (T)(img)(_p6##x,y,z,c), I[429] = (T)(img)(_p5##x,y,z,c), I[430] = (T)(img)(_p4##x,y,z,c), I[431] = (T)(img)(_p3##x,y,z,c), I[432] = (T)(img)(_p2##x,y,z,c), I[433] = (T)(img)(_p1##x,y,z,c), I[434] = (T)(img)(x,y,z,c), I[435] = (T)(img)(_n1##x,y,z,c), I[436] = (T)(img)(_n2##x,y,z,c), I[437] = (T)(img)(_n3##x,y,z,c), I[438] = (T)(img)(_n4##x,y,z,c), I[439] = (T)(img)(_n5##x,y,z,c), I[440] = (T)(img)(_n6##x,y,z,c), I[441] = (T)(img)(_n7##x,y,z,c), I[442] = (T)(img)(_n8##x,y,z,c), I[443] = (T)(img)(_n9##x,y,z,c), I[444] = (T)(img)(_n10##x,y,z,c), I[445] = (T)(img)(_n11##x,y,z,c), I[446] = (T)(img)(_n12##x,y,z,c), I[447] = (T)(img)(_n13##x,y,z,c), I[448] = (T)(img)(_n14##x,y,z,c), I[449] = (T)(img)(_n15##x,y,z,c), \ - I[450] = (T)(img)(_p14##x,_n1##y,z,c), I[451] = (T)(img)(_p13##x,_n1##y,z,c), I[452] = (T)(img)(_p12##x,_n1##y,z,c), I[453] = (T)(img)(_p11##x,_n1##y,z,c), I[454] = (T)(img)(_p10##x,_n1##y,z,c), I[455] = (T)(img)(_p9##x,_n1##y,z,c), I[456] = (T)(img)(_p8##x,_n1##y,z,c), I[457] = (T)(img)(_p7##x,_n1##y,z,c), I[458] = (T)(img)(_p6##x,_n1##y,z,c), I[459] = (T)(img)(_p5##x,_n1##y,z,c), I[460] = (T)(img)(_p4##x,_n1##y,z,c), I[461] = (T)(img)(_p3##x,_n1##y,z,c), I[462] = (T)(img)(_p2##x,_n1##y,z,c), I[463] = (T)(img)(_p1##x,_n1##y,z,c), I[464] = (T)(img)(x,_n1##y,z,c), I[465] = (T)(img)(_n1##x,_n1##y,z,c), I[466] = (T)(img)(_n2##x,_n1##y,z,c), I[467] = (T)(img)(_n3##x,_n1##y,z,c), I[468] = (T)(img)(_n4##x,_n1##y,z,c), I[469] = (T)(img)(_n5##x,_n1##y,z,c), I[470] = (T)(img)(_n6##x,_n1##y,z,c), I[471] = (T)(img)(_n7##x,_n1##y,z,c), I[472] = (T)(img)(_n8##x,_n1##y,z,c), I[473] = (T)(img)(_n9##x,_n1##y,z,c), I[474] = (T)(img)(_n10##x,_n1##y,z,c), I[475] = (T)(img)(_n11##x,_n1##y,z,c), I[476] = (T)(img)(_n12##x,_n1##y,z,c), I[477] = (T)(img)(_n13##x,_n1##y,z,c), I[478] = (T)(img)(_n14##x,_n1##y,z,c), I[479] = (T)(img)(_n15##x,_n1##y,z,c), \ - I[480] = (T)(img)(_p14##x,_n2##y,z,c), I[481] = (T)(img)(_p13##x,_n2##y,z,c), I[482] = (T)(img)(_p12##x,_n2##y,z,c), I[483] = (T)(img)(_p11##x,_n2##y,z,c), I[484] = (T)(img)(_p10##x,_n2##y,z,c), I[485] = (T)(img)(_p9##x,_n2##y,z,c), I[486] = (T)(img)(_p8##x,_n2##y,z,c), I[487] = (T)(img)(_p7##x,_n2##y,z,c), I[488] = (T)(img)(_p6##x,_n2##y,z,c), I[489] = (T)(img)(_p5##x,_n2##y,z,c), I[490] = (T)(img)(_p4##x,_n2##y,z,c), I[491] = (T)(img)(_p3##x,_n2##y,z,c), I[492] = (T)(img)(_p2##x,_n2##y,z,c), I[493] = (T)(img)(_p1##x,_n2##y,z,c), I[494] = (T)(img)(x,_n2##y,z,c), I[495] = (T)(img)(_n1##x,_n2##y,z,c), I[496] = (T)(img)(_n2##x,_n2##y,z,c), I[497] = (T)(img)(_n3##x,_n2##y,z,c), I[498] = (T)(img)(_n4##x,_n2##y,z,c), I[499] = (T)(img)(_n5##x,_n2##y,z,c), I[500] = (T)(img)(_n6##x,_n2##y,z,c), I[501] = (T)(img)(_n7##x,_n2##y,z,c), I[502] = (T)(img)(_n8##x,_n2##y,z,c), I[503] = (T)(img)(_n9##x,_n2##y,z,c), I[504] = (T)(img)(_n10##x,_n2##y,z,c), I[505] = (T)(img)(_n11##x,_n2##y,z,c), I[506] = (T)(img)(_n12##x,_n2##y,z,c), I[507] = (T)(img)(_n13##x,_n2##y,z,c), I[508] = (T)(img)(_n14##x,_n2##y,z,c), I[509] = (T)(img)(_n15##x,_n2##y,z,c), \ - I[510] = (T)(img)(_p14##x,_n3##y,z,c), I[511] = (T)(img)(_p13##x,_n3##y,z,c), I[512] = (T)(img)(_p12##x,_n3##y,z,c), I[513] = (T)(img)(_p11##x,_n3##y,z,c), I[514] = (T)(img)(_p10##x,_n3##y,z,c), I[515] = (T)(img)(_p9##x,_n3##y,z,c), I[516] = (T)(img)(_p8##x,_n3##y,z,c), I[517] = (T)(img)(_p7##x,_n3##y,z,c), I[518] = (T)(img)(_p6##x,_n3##y,z,c), I[519] = (T)(img)(_p5##x,_n3##y,z,c), I[520] = (T)(img)(_p4##x,_n3##y,z,c), I[521] = (T)(img)(_p3##x,_n3##y,z,c), I[522] = (T)(img)(_p2##x,_n3##y,z,c), I[523] = (T)(img)(_p1##x,_n3##y,z,c), I[524] = (T)(img)(x,_n3##y,z,c), I[525] = (T)(img)(_n1##x,_n3##y,z,c), I[526] = (T)(img)(_n2##x,_n3##y,z,c), I[527] = (T)(img)(_n3##x,_n3##y,z,c), I[528] = (T)(img)(_n4##x,_n3##y,z,c), I[529] = (T)(img)(_n5##x,_n3##y,z,c), I[530] = (T)(img)(_n6##x,_n3##y,z,c), I[531] = (T)(img)(_n7##x,_n3##y,z,c), I[532] = (T)(img)(_n8##x,_n3##y,z,c), I[533] = (T)(img)(_n9##x,_n3##y,z,c), I[534] = (T)(img)(_n10##x,_n3##y,z,c), I[535] = (T)(img)(_n11##x,_n3##y,z,c), I[536] = (T)(img)(_n12##x,_n3##y,z,c), I[537] = (T)(img)(_n13##x,_n3##y,z,c), I[538] = (T)(img)(_n14##x,_n3##y,z,c), I[539] = (T)(img)(_n15##x,_n3##y,z,c), \ - I[540] = (T)(img)(_p14##x,_n4##y,z,c), I[541] = (T)(img)(_p13##x,_n4##y,z,c), I[542] = (T)(img)(_p12##x,_n4##y,z,c), I[543] = (T)(img)(_p11##x,_n4##y,z,c), I[544] = (T)(img)(_p10##x,_n4##y,z,c), I[545] = (T)(img)(_p9##x,_n4##y,z,c), I[546] = (T)(img)(_p8##x,_n4##y,z,c), I[547] = (T)(img)(_p7##x,_n4##y,z,c), I[548] = (T)(img)(_p6##x,_n4##y,z,c), I[549] = (T)(img)(_p5##x,_n4##y,z,c), I[550] = (T)(img)(_p4##x,_n4##y,z,c), I[551] = (T)(img)(_p3##x,_n4##y,z,c), I[552] = (T)(img)(_p2##x,_n4##y,z,c), I[553] = (T)(img)(_p1##x,_n4##y,z,c), I[554] = (T)(img)(x,_n4##y,z,c), I[555] = (T)(img)(_n1##x,_n4##y,z,c), I[556] = (T)(img)(_n2##x,_n4##y,z,c), I[557] = (T)(img)(_n3##x,_n4##y,z,c), I[558] = (T)(img)(_n4##x,_n4##y,z,c), I[559] = (T)(img)(_n5##x,_n4##y,z,c), I[560] = (T)(img)(_n6##x,_n4##y,z,c), I[561] = (T)(img)(_n7##x,_n4##y,z,c), I[562] = (T)(img)(_n8##x,_n4##y,z,c), I[563] = (T)(img)(_n9##x,_n4##y,z,c), I[564] = (T)(img)(_n10##x,_n4##y,z,c), I[565] = (T)(img)(_n11##x,_n4##y,z,c), I[566] = (T)(img)(_n12##x,_n4##y,z,c), I[567] = (T)(img)(_n13##x,_n4##y,z,c), I[568] = (T)(img)(_n14##x,_n4##y,z,c), I[569] = (T)(img)(_n15##x,_n4##y,z,c), \ - I[570] = (T)(img)(_p14##x,_n5##y,z,c), I[571] = (T)(img)(_p13##x,_n5##y,z,c), I[572] = (T)(img)(_p12##x,_n5##y,z,c), I[573] = (T)(img)(_p11##x,_n5##y,z,c), I[574] = (T)(img)(_p10##x,_n5##y,z,c), I[575] = (T)(img)(_p9##x,_n5##y,z,c), I[576] = (T)(img)(_p8##x,_n5##y,z,c), I[577] = (T)(img)(_p7##x,_n5##y,z,c), I[578] = (T)(img)(_p6##x,_n5##y,z,c), I[579] = (T)(img)(_p5##x,_n5##y,z,c), I[580] = (T)(img)(_p4##x,_n5##y,z,c), I[581] = (T)(img)(_p3##x,_n5##y,z,c), I[582] = (T)(img)(_p2##x,_n5##y,z,c), I[583] = (T)(img)(_p1##x,_n5##y,z,c), I[584] = (T)(img)(x,_n5##y,z,c), I[585] = (T)(img)(_n1##x,_n5##y,z,c), I[586] = (T)(img)(_n2##x,_n5##y,z,c), I[587] = (T)(img)(_n3##x,_n5##y,z,c), I[588] = (T)(img)(_n4##x,_n5##y,z,c), I[589] = (T)(img)(_n5##x,_n5##y,z,c), I[590] = (T)(img)(_n6##x,_n5##y,z,c), I[591] = (T)(img)(_n7##x,_n5##y,z,c), I[592] = (T)(img)(_n8##x,_n5##y,z,c), I[593] = (T)(img)(_n9##x,_n5##y,z,c), I[594] = (T)(img)(_n10##x,_n5##y,z,c), I[595] = (T)(img)(_n11##x,_n5##y,z,c), I[596] = (T)(img)(_n12##x,_n5##y,z,c), I[597] = (T)(img)(_n13##x,_n5##y,z,c), I[598] = (T)(img)(_n14##x,_n5##y,z,c), I[599] = (T)(img)(_n15##x,_n5##y,z,c), \ - I[600] = (T)(img)(_p14##x,_n6##y,z,c), I[601] = (T)(img)(_p13##x,_n6##y,z,c), I[602] = (T)(img)(_p12##x,_n6##y,z,c), I[603] = (T)(img)(_p11##x,_n6##y,z,c), I[604] = (T)(img)(_p10##x,_n6##y,z,c), I[605] = (T)(img)(_p9##x,_n6##y,z,c), I[606] = (T)(img)(_p8##x,_n6##y,z,c), I[607] = (T)(img)(_p7##x,_n6##y,z,c), I[608] = (T)(img)(_p6##x,_n6##y,z,c), I[609] = (T)(img)(_p5##x,_n6##y,z,c), I[610] = (T)(img)(_p4##x,_n6##y,z,c), I[611] = (T)(img)(_p3##x,_n6##y,z,c), I[612] = (T)(img)(_p2##x,_n6##y,z,c), I[613] = (T)(img)(_p1##x,_n6##y,z,c), I[614] = (T)(img)(x,_n6##y,z,c), I[615] = (T)(img)(_n1##x,_n6##y,z,c), I[616] = (T)(img)(_n2##x,_n6##y,z,c), I[617] = (T)(img)(_n3##x,_n6##y,z,c), I[618] = (T)(img)(_n4##x,_n6##y,z,c), I[619] = (T)(img)(_n5##x,_n6##y,z,c), I[620] = (T)(img)(_n6##x,_n6##y,z,c), I[621] = (T)(img)(_n7##x,_n6##y,z,c), I[622] = (T)(img)(_n8##x,_n6##y,z,c), I[623] = (T)(img)(_n9##x,_n6##y,z,c), I[624] = (T)(img)(_n10##x,_n6##y,z,c), I[625] = (T)(img)(_n11##x,_n6##y,z,c), I[626] = (T)(img)(_n12##x,_n6##y,z,c), I[627] = (T)(img)(_n13##x,_n6##y,z,c), I[628] = (T)(img)(_n14##x,_n6##y,z,c), I[629] = (T)(img)(_n15##x,_n6##y,z,c), \ - I[630] = (T)(img)(_p14##x,_n7##y,z,c), I[631] = (T)(img)(_p13##x,_n7##y,z,c), I[632] = (T)(img)(_p12##x,_n7##y,z,c), I[633] = (T)(img)(_p11##x,_n7##y,z,c), I[634] = (T)(img)(_p10##x,_n7##y,z,c), I[635] = (T)(img)(_p9##x,_n7##y,z,c), I[636] = (T)(img)(_p8##x,_n7##y,z,c), I[637] = (T)(img)(_p7##x,_n7##y,z,c), I[638] = (T)(img)(_p6##x,_n7##y,z,c), I[639] = (T)(img)(_p5##x,_n7##y,z,c), I[640] = (T)(img)(_p4##x,_n7##y,z,c), I[641] = (T)(img)(_p3##x,_n7##y,z,c), I[642] = (T)(img)(_p2##x,_n7##y,z,c), I[643] = (T)(img)(_p1##x,_n7##y,z,c), I[644] = (T)(img)(x,_n7##y,z,c), I[645] = (T)(img)(_n1##x,_n7##y,z,c), I[646] = (T)(img)(_n2##x,_n7##y,z,c), I[647] = (T)(img)(_n3##x,_n7##y,z,c), I[648] = (T)(img)(_n4##x,_n7##y,z,c), I[649] = (T)(img)(_n5##x,_n7##y,z,c), I[650] = (T)(img)(_n6##x,_n7##y,z,c), I[651] = (T)(img)(_n7##x,_n7##y,z,c), I[652] = (T)(img)(_n8##x,_n7##y,z,c), I[653] = (T)(img)(_n9##x,_n7##y,z,c), I[654] = (T)(img)(_n10##x,_n7##y,z,c), I[655] = (T)(img)(_n11##x,_n7##y,z,c), I[656] = (T)(img)(_n12##x,_n7##y,z,c), I[657] = (T)(img)(_n13##x,_n7##y,z,c), I[658] = (T)(img)(_n14##x,_n7##y,z,c), I[659] = (T)(img)(_n15##x,_n7##y,z,c), \ - I[660] = (T)(img)(_p14##x,_n8##y,z,c), I[661] = (T)(img)(_p13##x,_n8##y,z,c), I[662] = (T)(img)(_p12##x,_n8##y,z,c), I[663] = (T)(img)(_p11##x,_n8##y,z,c), I[664] = (T)(img)(_p10##x,_n8##y,z,c), I[665] = (T)(img)(_p9##x,_n8##y,z,c), I[666] = (T)(img)(_p8##x,_n8##y,z,c), I[667] = (T)(img)(_p7##x,_n8##y,z,c), I[668] = (T)(img)(_p6##x,_n8##y,z,c), I[669] = (T)(img)(_p5##x,_n8##y,z,c), I[670] = (T)(img)(_p4##x,_n8##y,z,c), I[671] = (T)(img)(_p3##x,_n8##y,z,c), I[672] = (T)(img)(_p2##x,_n8##y,z,c), I[673] = (T)(img)(_p1##x,_n8##y,z,c), I[674] = (T)(img)(x,_n8##y,z,c), I[675] = (T)(img)(_n1##x,_n8##y,z,c), I[676] = (T)(img)(_n2##x,_n8##y,z,c), I[677] = (T)(img)(_n3##x,_n8##y,z,c), I[678] = (T)(img)(_n4##x,_n8##y,z,c), I[679] = (T)(img)(_n5##x,_n8##y,z,c), I[680] = (T)(img)(_n6##x,_n8##y,z,c), I[681] = (T)(img)(_n7##x,_n8##y,z,c), I[682] = (T)(img)(_n8##x,_n8##y,z,c), I[683] = (T)(img)(_n9##x,_n8##y,z,c), I[684] = (T)(img)(_n10##x,_n8##y,z,c), I[685] = (T)(img)(_n11##x,_n8##y,z,c), I[686] = (T)(img)(_n12##x,_n8##y,z,c), I[687] = (T)(img)(_n13##x,_n8##y,z,c), I[688] = (T)(img)(_n14##x,_n8##y,z,c), I[689] = (T)(img)(_n15##x,_n8##y,z,c), \ - I[690] = (T)(img)(_p14##x,_n9##y,z,c), I[691] = (T)(img)(_p13##x,_n9##y,z,c), I[692] = (T)(img)(_p12##x,_n9##y,z,c), I[693] = (T)(img)(_p11##x,_n9##y,z,c), I[694] = (T)(img)(_p10##x,_n9##y,z,c), I[695] = (T)(img)(_p9##x,_n9##y,z,c), I[696] = (T)(img)(_p8##x,_n9##y,z,c), I[697] = (T)(img)(_p7##x,_n9##y,z,c), I[698] = (T)(img)(_p6##x,_n9##y,z,c), I[699] = (T)(img)(_p5##x,_n9##y,z,c), I[700] = (T)(img)(_p4##x,_n9##y,z,c), I[701] = (T)(img)(_p3##x,_n9##y,z,c), I[702] = (T)(img)(_p2##x,_n9##y,z,c), I[703] = (T)(img)(_p1##x,_n9##y,z,c), I[704] = (T)(img)(x,_n9##y,z,c), I[705] = (T)(img)(_n1##x,_n9##y,z,c), I[706] = (T)(img)(_n2##x,_n9##y,z,c), I[707] = (T)(img)(_n3##x,_n9##y,z,c), I[708] = (T)(img)(_n4##x,_n9##y,z,c), I[709] = (T)(img)(_n5##x,_n9##y,z,c), I[710] = (T)(img)(_n6##x,_n9##y,z,c), I[711] = (T)(img)(_n7##x,_n9##y,z,c), I[712] = (T)(img)(_n8##x,_n9##y,z,c), I[713] = (T)(img)(_n9##x,_n9##y,z,c), I[714] = (T)(img)(_n10##x,_n9##y,z,c), I[715] = (T)(img)(_n11##x,_n9##y,z,c), I[716] = (T)(img)(_n12##x,_n9##y,z,c), I[717] = (T)(img)(_n13##x,_n9##y,z,c), I[718] = (T)(img)(_n14##x,_n9##y,z,c), I[719] = (T)(img)(_n15##x,_n9##y,z,c), \ - I[720] = (T)(img)(_p14##x,_n10##y,z,c), I[721] = (T)(img)(_p13##x,_n10##y,z,c), I[722] = (T)(img)(_p12##x,_n10##y,z,c), I[723] = (T)(img)(_p11##x,_n10##y,z,c), I[724] = (T)(img)(_p10##x,_n10##y,z,c), I[725] = (T)(img)(_p9##x,_n10##y,z,c), I[726] = (T)(img)(_p8##x,_n10##y,z,c), I[727] = (T)(img)(_p7##x,_n10##y,z,c), I[728] = (T)(img)(_p6##x,_n10##y,z,c), I[729] = (T)(img)(_p5##x,_n10##y,z,c), I[730] = (T)(img)(_p4##x,_n10##y,z,c), I[731] = (T)(img)(_p3##x,_n10##y,z,c), I[732] = (T)(img)(_p2##x,_n10##y,z,c), I[733] = (T)(img)(_p1##x,_n10##y,z,c), I[734] = (T)(img)(x,_n10##y,z,c), I[735] = (T)(img)(_n1##x,_n10##y,z,c), I[736] = (T)(img)(_n2##x,_n10##y,z,c), I[737] = (T)(img)(_n3##x,_n10##y,z,c), I[738] = (T)(img)(_n4##x,_n10##y,z,c), I[739] = (T)(img)(_n5##x,_n10##y,z,c), I[740] = (T)(img)(_n6##x,_n10##y,z,c), I[741] = (T)(img)(_n7##x,_n10##y,z,c), I[742] = (T)(img)(_n8##x,_n10##y,z,c), I[743] = (T)(img)(_n9##x,_n10##y,z,c), I[744] = (T)(img)(_n10##x,_n10##y,z,c), I[745] = (T)(img)(_n11##x,_n10##y,z,c), I[746] = (T)(img)(_n12##x,_n10##y,z,c), I[747] = (T)(img)(_n13##x,_n10##y,z,c), I[748] = (T)(img)(_n14##x,_n10##y,z,c), I[749] = (T)(img)(_n15##x,_n10##y,z,c), \ - I[750] = (T)(img)(_p14##x,_n11##y,z,c), I[751] = (T)(img)(_p13##x,_n11##y,z,c), I[752] = (T)(img)(_p12##x,_n11##y,z,c), I[753] = (T)(img)(_p11##x,_n11##y,z,c), I[754] = (T)(img)(_p10##x,_n11##y,z,c), I[755] = (T)(img)(_p9##x,_n11##y,z,c), I[756] = (T)(img)(_p8##x,_n11##y,z,c), I[757] = (T)(img)(_p7##x,_n11##y,z,c), I[758] = (T)(img)(_p6##x,_n11##y,z,c), I[759] = (T)(img)(_p5##x,_n11##y,z,c), I[760] = (T)(img)(_p4##x,_n11##y,z,c), I[761] = (T)(img)(_p3##x,_n11##y,z,c), I[762] = (T)(img)(_p2##x,_n11##y,z,c), I[763] = (T)(img)(_p1##x,_n11##y,z,c), I[764] = (T)(img)(x,_n11##y,z,c), I[765] = (T)(img)(_n1##x,_n11##y,z,c), I[766] = (T)(img)(_n2##x,_n11##y,z,c), I[767] = (T)(img)(_n3##x,_n11##y,z,c), I[768] = (T)(img)(_n4##x,_n11##y,z,c), I[769] = (T)(img)(_n5##x,_n11##y,z,c), I[770] = (T)(img)(_n6##x,_n11##y,z,c), I[771] = (T)(img)(_n7##x,_n11##y,z,c), I[772] = (T)(img)(_n8##x,_n11##y,z,c), I[773] = (T)(img)(_n9##x,_n11##y,z,c), I[774] = (T)(img)(_n10##x,_n11##y,z,c), I[775] = (T)(img)(_n11##x,_n11##y,z,c), I[776] = (T)(img)(_n12##x,_n11##y,z,c), I[777] = (T)(img)(_n13##x,_n11##y,z,c), I[778] = (T)(img)(_n14##x,_n11##y,z,c), I[779] = (T)(img)(_n15##x,_n11##y,z,c), \ - I[780] = (T)(img)(_p14##x,_n12##y,z,c), I[781] = (T)(img)(_p13##x,_n12##y,z,c), I[782] = (T)(img)(_p12##x,_n12##y,z,c), I[783] = (T)(img)(_p11##x,_n12##y,z,c), I[784] = (T)(img)(_p10##x,_n12##y,z,c), I[785] = (T)(img)(_p9##x,_n12##y,z,c), I[786] = (T)(img)(_p8##x,_n12##y,z,c), I[787] = (T)(img)(_p7##x,_n12##y,z,c), I[788] = (T)(img)(_p6##x,_n12##y,z,c), I[789] = (T)(img)(_p5##x,_n12##y,z,c), I[790] = (T)(img)(_p4##x,_n12##y,z,c), I[791] = (T)(img)(_p3##x,_n12##y,z,c), I[792] = (T)(img)(_p2##x,_n12##y,z,c), I[793] = (T)(img)(_p1##x,_n12##y,z,c), I[794] = (T)(img)(x,_n12##y,z,c), I[795] = (T)(img)(_n1##x,_n12##y,z,c), I[796] = (T)(img)(_n2##x,_n12##y,z,c), I[797] = (T)(img)(_n3##x,_n12##y,z,c), I[798] = (T)(img)(_n4##x,_n12##y,z,c), I[799] = (T)(img)(_n5##x,_n12##y,z,c), I[800] = (T)(img)(_n6##x,_n12##y,z,c), I[801] = (T)(img)(_n7##x,_n12##y,z,c), I[802] = (T)(img)(_n8##x,_n12##y,z,c), I[803] = (T)(img)(_n9##x,_n12##y,z,c), I[804] = (T)(img)(_n10##x,_n12##y,z,c), I[805] = (T)(img)(_n11##x,_n12##y,z,c), I[806] = (T)(img)(_n12##x,_n12##y,z,c), I[807] = (T)(img)(_n13##x,_n12##y,z,c), I[808] = (T)(img)(_n14##x,_n12##y,z,c), I[809] = (T)(img)(_n15##x,_n12##y,z,c), \ - I[810] = (T)(img)(_p14##x,_n13##y,z,c), I[811] = (T)(img)(_p13##x,_n13##y,z,c), I[812] = (T)(img)(_p12##x,_n13##y,z,c), I[813] = (T)(img)(_p11##x,_n13##y,z,c), I[814] = (T)(img)(_p10##x,_n13##y,z,c), I[815] = (T)(img)(_p9##x,_n13##y,z,c), I[816] = (T)(img)(_p8##x,_n13##y,z,c), I[817] = (T)(img)(_p7##x,_n13##y,z,c), I[818] = (T)(img)(_p6##x,_n13##y,z,c), I[819] = (T)(img)(_p5##x,_n13##y,z,c), I[820] = (T)(img)(_p4##x,_n13##y,z,c), I[821] = (T)(img)(_p3##x,_n13##y,z,c), I[822] = (T)(img)(_p2##x,_n13##y,z,c), I[823] = (T)(img)(_p1##x,_n13##y,z,c), I[824] = (T)(img)(x,_n13##y,z,c), I[825] = (T)(img)(_n1##x,_n13##y,z,c), I[826] = (T)(img)(_n2##x,_n13##y,z,c), I[827] = (T)(img)(_n3##x,_n13##y,z,c), I[828] = (T)(img)(_n4##x,_n13##y,z,c), I[829] = (T)(img)(_n5##x,_n13##y,z,c), I[830] = (T)(img)(_n6##x,_n13##y,z,c), I[831] = (T)(img)(_n7##x,_n13##y,z,c), I[832] = (T)(img)(_n8##x,_n13##y,z,c), I[833] = (T)(img)(_n9##x,_n13##y,z,c), I[834] = (T)(img)(_n10##x,_n13##y,z,c), I[835] = (T)(img)(_n11##x,_n13##y,z,c), I[836] = (T)(img)(_n12##x,_n13##y,z,c), I[837] = (T)(img)(_n13##x,_n13##y,z,c), I[838] = (T)(img)(_n14##x,_n13##y,z,c), I[839] = (T)(img)(_n15##x,_n13##y,z,c), \ - I[840] = (T)(img)(_p14##x,_n14##y,z,c), I[841] = (T)(img)(_p13##x,_n14##y,z,c), I[842] = (T)(img)(_p12##x,_n14##y,z,c), I[843] = (T)(img)(_p11##x,_n14##y,z,c), I[844] = (T)(img)(_p10##x,_n14##y,z,c), I[845] = (T)(img)(_p9##x,_n14##y,z,c), I[846] = (T)(img)(_p8##x,_n14##y,z,c), I[847] = (T)(img)(_p7##x,_n14##y,z,c), I[848] = (T)(img)(_p6##x,_n14##y,z,c), I[849] = (T)(img)(_p5##x,_n14##y,z,c), I[850] = (T)(img)(_p4##x,_n14##y,z,c), I[851] = (T)(img)(_p3##x,_n14##y,z,c), I[852] = (T)(img)(_p2##x,_n14##y,z,c), I[853] = (T)(img)(_p1##x,_n14##y,z,c), I[854] = (T)(img)(x,_n14##y,z,c), I[855] = (T)(img)(_n1##x,_n14##y,z,c), I[856] = (T)(img)(_n2##x,_n14##y,z,c), I[857] = (T)(img)(_n3##x,_n14##y,z,c), I[858] = (T)(img)(_n4##x,_n14##y,z,c), I[859] = (T)(img)(_n5##x,_n14##y,z,c), I[860] = (T)(img)(_n6##x,_n14##y,z,c), I[861] = (T)(img)(_n7##x,_n14##y,z,c), I[862] = (T)(img)(_n8##x,_n14##y,z,c), I[863] = (T)(img)(_n9##x,_n14##y,z,c), I[864] = (T)(img)(_n10##x,_n14##y,z,c), I[865] = (T)(img)(_n11##x,_n14##y,z,c), I[866] = (T)(img)(_n12##x,_n14##y,z,c), I[867] = (T)(img)(_n13##x,_n14##y,z,c), I[868] = (T)(img)(_n14##x,_n14##y,z,c), I[869] = (T)(img)(_n15##x,_n14##y,z,c), \ - I[870] = (T)(img)(_p14##x,_n15##y,z,c), I[871] = (T)(img)(_p13##x,_n15##y,z,c), I[872] = (T)(img)(_p12##x,_n15##y,z,c), I[873] = (T)(img)(_p11##x,_n15##y,z,c), I[874] = (T)(img)(_p10##x,_n15##y,z,c), I[875] = (T)(img)(_p9##x,_n15##y,z,c), I[876] = (T)(img)(_p8##x,_n15##y,z,c), I[877] = (T)(img)(_p7##x,_n15##y,z,c), I[878] = (T)(img)(_p6##x,_n15##y,z,c), I[879] = (T)(img)(_p5##x,_n15##y,z,c), I[880] = (T)(img)(_p4##x,_n15##y,z,c), I[881] = (T)(img)(_p3##x,_n15##y,z,c), I[882] = (T)(img)(_p2##x,_n15##y,z,c), I[883] = (T)(img)(_p1##x,_n15##y,z,c), I[884] = (T)(img)(x,_n15##y,z,c), I[885] = (T)(img)(_n1##x,_n15##y,z,c), I[886] = (T)(img)(_n2##x,_n15##y,z,c), I[887] = (T)(img)(_n3##x,_n15##y,z,c), I[888] = (T)(img)(_n4##x,_n15##y,z,c), I[889] = (T)(img)(_n5##x,_n15##y,z,c), I[890] = (T)(img)(_n6##x,_n15##y,z,c), I[891] = (T)(img)(_n7##x,_n15##y,z,c), I[892] = (T)(img)(_n8##x,_n15##y,z,c), I[893] = (T)(img)(_n9##x,_n15##y,z,c), I[894] = (T)(img)(_n10##x,_n15##y,z,c), I[895] = (T)(img)(_n11##x,_n15##y,z,c), I[896] = (T)(img)(_n12##x,_n15##y,z,c), I[897] = (T)(img)(_n13##x,_n15##y,z,c), I[898] = (T)(img)(_n14##x,_n15##y,z,c), I[899] = (T)(img)(_n15##x,_n15##y,z,c); - -// Define 31x31 loop macros -//------------------------- -#define cimg_for31(bound,i) for (int i = 0, \ - _p15##i = 0, _p14##i = 0, _p13##i = 0, _p12##i = 0, _p11##i = 0, _p10##i = 0, _p9##i = 0, _p8##i = 0, _p7##i = 0, _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6, \ - _n7##i = 7>=(int)(bound)?(int)(bound) - 1:7, \ - _n8##i = 8>=(int)(bound)?(int)(bound) - 1:8, \ - _n9##i = 9>=(int)(bound)?(int)(bound) - 1:9, \ - _n10##i = 10>=(int)(bound)?(int)(bound) - 1:10, \ - _n11##i = 11>=(int)(bound)?(int)(bound) - 1:11, \ - _n12##i = 12>=(int)(bound)?(int)(bound) - 1:12, \ - _n13##i = 13>=(int)(bound)?(int)(bound) - 1:13, \ - _n14##i = 14>=(int)(bound)?(int)(bound) - 1:14, \ - _n15##i = 15>=(int)(bound)?(int)(bound) - 1:15; \ - _n15##i<(int)(bound) || _n14##i==--_n15##i || _n13##i==--_n14##i || _n12##i==--_n13##i || _n11##i==--_n12##i || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n15##i = _n14##i = _n13##i = _n12##i = _n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p15##i = _p14##i, _p14##i = _p13##i, _p13##i = _p12##i, _p12##i = _p11##i, _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i, ++_n12##i, ++_n13##i, ++_n14##i, ++_n15##i) - -#define cimg_for31X(img,x) cimg_for31((img)._width,x) -#define cimg_for31Y(img,y) cimg_for31((img)._height,y) -#define cimg_for31Z(img,z) cimg_for31((img)._depth,z) -#define cimg_for31C(img,c) cimg_for31((img)._spectrum,c) -#define cimg_for31XY(img,x,y) cimg_for31Y(img,y) cimg_for31X(img,x) -#define cimg_for31XZ(img,x,z) cimg_for31Z(img,z) cimg_for31X(img,x) -#define cimg_for31XC(img,x,c) cimg_for31C(img,c) cimg_for31X(img,x) -#define cimg_for31YZ(img,y,z) cimg_for31Z(img,z) cimg_for31Y(img,y) -#define cimg_for31YC(img,y,c) cimg_for31C(img,c) cimg_for31Y(img,y) -#define cimg_for31ZC(img,z,c) cimg_for31C(img,c) cimg_for31Z(img,z) -#define cimg_for31XYZ(img,x,y,z) cimg_for31Z(img,z) cimg_for31XY(img,x,y) -#define cimg_for31XZC(img,x,z,c) cimg_for31C(img,c) cimg_for31XZ(img,x,z) -#define cimg_for31YZC(img,y,z,c) cimg_for31C(img,c) cimg_for31YZ(img,y,z) -#define cimg_for31XYZC(img,x,y,z,c) cimg_for31C(img,c) cimg_for31XYZ(img,x,y,z) - -#define cimg_for_in31(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p15##i = i - 15<0?0:i - 15, \ - _p14##i = i - 14<0?0:i - 14, \ - _p13##i = i - 13<0?0:i - 13, \ - _p12##i = i - 12<0?0:i - 12, \ - _p11##i = i - 11<0?0:i - 11, \ - _p10##i = i - 10<0?0:i - 10, \ - _p9##i = i - 9<0?0:i - 9, \ - _p8##i = i - 8<0?0:i - 8, \ - _p7##i = i - 7<0?0:i - 7, \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6, \ - _n7##i = i + 7>=(int)(bound)?(int)(bound) - 1:i + 7, \ - _n8##i = i + 8>=(int)(bound)?(int)(bound) - 1:i + 8, \ - _n9##i = i + 9>=(int)(bound)?(int)(bound) - 1:i + 9, \ - _n10##i = i + 10>=(int)(bound)?(int)(bound) - 1:i + 10, \ - _n11##i = i + 11>=(int)(bound)?(int)(bound) - 1:i + 11, \ - _n12##i = i + 12>=(int)(bound)?(int)(bound) - 1:i + 12, \ - _n13##i = i + 13>=(int)(bound)?(int)(bound) - 1:i + 13, \ - _n14##i = i + 14>=(int)(bound)?(int)(bound) - 1:i + 14, \ - _n15##i = i + 15>=(int)(bound)?(int)(bound) - 1:i + 15; \ - i<=(int)(i1) && (_n15##i<(int)(bound) || _n14##i==--_n15##i || _n13##i==--_n14##i || _n12##i==--_n13##i || _n11##i==--_n12##i || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n15##i = _n14##i = _n13##i = _n12##i = _n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p15##i = _p14##i, _p14##i = _p13##i, _p13##i = _p12##i, _p12##i = _p11##i, _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i, ++_n12##i, ++_n13##i, ++_n14##i, ++_n15##i) - -#define cimg_for_in31X(img,x0,x1,x) cimg_for_in31((img)._width,x0,x1,x) -#define cimg_for_in31Y(img,y0,y1,y) cimg_for_in31((img)._height,y0,y1,y) -#define cimg_for_in31Z(img,z0,z1,z) cimg_for_in31((img)._depth,z0,z1,z) -#define cimg_for_in31C(img,c0,c1,c) cimg_for_in31((img)._spectrum,c0,c1,c) -#define cimg_for_in31XY(img,x0,y0,x1,y1,x,y) cimg_for_in31Y(img,y0,y1,y) cimg_for_in31X(img,x0,x1,x) -#define cimg_for_in31XZ(img,x0,z0,x1,z1,x,z) cimg_for_in31Z(img,z0,z1,z) cimg_for_in31X(img,x0,x1,x) -#define cimg_for_in31XC(img,x0,c0,x1,c1,x,c) cimg_for_in31C(img,c0,c1,c) cimg_for_in31X(img,x0,x1,x) -#define cimg_for_in31YZ(img,y0,z0,y1,z1,y,z) cimg_for_in31Z(img,z0,z1,z) cimg_for_in31Y(img,y0,y1,y) -#define cimg_for_in31YC(img,y0,c0,y1,c1,y,c) cimg_for_in31C(img,c0,c1,c) cimg_for_in31Y(img,y0,y1,y) -#define cimg_for_in31ZC(img,z0,c0,z1,c1,z,c) cimg_for_in31C(img,c0,c1,c) cimg_for_in31Z(img,z0,z1,z) -#define cimg_for_in31XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in31Z(img,z0,z1,z) cimg_for_in31XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in31XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in31C(img,c0,c1,c) cimg_for_in31XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in31YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in31C(img,c0,c1,c) cimg_for_in31YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in31XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in31C(img,c0,c1,c) cimg_for_in31XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for31x31(img,x,y,z,c,I,T) \ - cimg_for31((img)._height,y) for (int x = 0, \ - _p15##x = 0, _p14##x = 0, _p13##x = 0, _p12##x = 0, _p11##x = 0, _p10##x = 0, _p9##x = 0, _p8##x = 0, _p7##x = 0, _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = 6>=((img)._width)?(img).width() - 1:6, \ - _n7##x = 7>=((img)._width)?(img).width() - 1:7, \ - _n8##x = 8>=((img)._width)?(img).width() - 1:8, \ - _n9##x = 9>=((img)._width)?(img).width() - 1:9, \ - _n10##x = 10>=((img)._width)?(img).width() - 1:10, \ - _n11##x = 11>=((img)._width)?(img).width() - 1:11, \ - _n12##x = 12>=((img)._width)?(img).width() - 1:12, \ - _n13##x = 13>=((img)._width)?(img).width() - 1:13, \ - _n14##x = 14>=((img)._width)?(img).width() - 1:14, \ - _n15##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = I[7] = I[8] = I[9] = I[10] = I[11] = I[12] = I[13] = I[14] = I[15] = (T)(img)(0,_p15##y,z,c)), \ - (I[31] = I[32] = I[33] = I[34] = I[35] = I[36] = I[37] = I[38] = I[39] = I[40] = I[41] = I[42] = I[43] = I[44] = I[45] = I[46] = (T)(img)(0,_p14##y,z,c)), \ - (I[62] = I[63] = I[64] = I[65] = I[66] = I[67] = I[68] = I[69] = I[70] = I[71] = I[72] = I[73] = I[74] = I[75] = I[76] = I[77] = (T)(img)(0,_p13##y,z,c)), \ - (I[93] = I[94] = I[95] = I[96] = I[97] = I[98] = I[99] = I[100] = I[101] = I[102] = I[103] = I[104] = I[105] = I[106] = I[107] = I[108] = (T)(img)(0,_p12##y,z,c)), \ - (I[124] = I[125] = I[126] = I[127] = I[128] = I[129] = I[130] = I[131] = I[132] = I[133] = I[134] = I[135] = I[136] = I[137] = I[138] = I[139] = (T)(img)(0,_p11##y,z,c)), \ - (I[155] = I[156] = I[157] = I[158] = I[159] = I[160] = I[161] = I[162] = I[163] = I[164] = I[165] = I[166] = I[167] = I[168] = I[169] = I[170] = (T)(img)(0,_p10##y,z,c)), \ - (I[186] = I[187] = I[188] = I[189] = I[190] = I[191] = I[192] = I[193] = I[194] = I[195] = I[196] = I[197] = I[198] = I[199] = I[200] = I[201] = (T)(img)(0,_p9##y,z,c)), \ - (I[217] = I[218] = I[219] = I[220] = I[221] = I[222] = I[223] = I[224] = I[225] = I[226] = I[227] = I[228] = I[229] = I[230] = I[231] = I[232] = (T)(img)(0,_p8##y,z,c)), \ - (I[248] = I[249] = I[250] = I[251] = I[252] = I[253] = I[254] = I[255] = I[256] = I[257] = I[258] = I[259] = I[260] = I[261] = I[262] = I[263] = (T)(img)(0,_p7##y,z,c)), \ - (I[279] = I[280] = I[281] = I[282] = I[283] = I[284] = I[285] = I[286] = I[287] = I[288] = I[289] = I[290] = I[291] = I[292] = I[293] = I[294] = (T)(img)(0,_p6##y,z,c)), \ - (I[310] = I[311] = I[312] = I[313] = I[314] = I[315] = I[316] = I[317] = I[318] = I[319] = I[320] = I[321] = I[322] = I[323] = I[324] = I[325] = (T)(img)(0,_p5##y,z,c)), \ - (I[341] = I[342] = I[343] = I[344] = I[345] = I[346] = I[347] = I[348] = I[349] = I[350] = I[351] = I[352] = I[353] = I[354] = I[355] = I[356] = (T)(img)(0,_p4##y,z,c)), \ - (I[372] = I[373] = I[374] = I[375] = I[376] = I[377] = I[378] = I[379] = I[380] = I[381] = I[382] = I[383] = I[384] = I[385] = I[386] = I[387] = (T)(img)(0,_p3##y,z,c)), \ - (I[403] = I[404] = I[405] = I[406] = I[407] = I[408] = I[409] = I[410] = I[411] = I[412] = I[413] = I[414] = I[415] = I[416] = I[417] = I[418] = (T)(img)(0,_p2##y,z,c)), \ - (I[434] = I[435] = I[436] = I[437] = I[438] = I[439] = I[440] = I[441] = I[442] = I[443] = I[444] = I[445] = I[446] = I[447] = I[448] = I[449] = (T)(img)(0,_p1##y,z,c)), \ - (I[465] = I[466] = I[467] = I[468] = I[469] = I[470] = I[471] = I[472] = I[473] = I[474] = I[475] = I[476] = I[477] = I[478] = I[479] = I[480] = (T)(img)(0,y,z,c)), \ - (I[496] = I[497] = I[498] = I[499] = I[500] = I[501] = I[502] = I[503] = I[504] = I[505] = I[506] = I[507] = I[508] = I[509] = I[510] = I[511] = (T)(img)(0,_n1##y,z,c)), \ - (I[527] = I[528] = I[529] = I[530] = I[531] = I[532] = I[533] = I[534] = I[535] = I[536] = I[537] = I[538] = I[539] = I[540] = I[541] = I[542] = (T)(img)(0,_n2##y,z,c)), \ - (I[558] = I[559] = I[560] = I[561] = I[562] = I[563] = I[564] = I[565] = I[566] = I[567] = I[568] = I[569] = I[570] = I[571] = I[572] = I[573] = (T)(img)(0,_n3##y,z,c)), \ - (I[589] = I[590] = I[591] = I[592] = I[593] = I[594] = I[595] = I[596] = I[597] = I[598] = I[599] = I[600] = I[601] = I[602] = I[603] = I[604] = (T)(img)(0,_n4##y,z,c)), \ - (I[620] = I[621] = I[622] = I[623] = I[624] = I[625] = I[626] = I[627] = I[628] = I[629] = I[630] = I[631] = I[632] = I[633] = I[634] = I[635] = (T)(img)(0,_n5##y,z,c)), \ - (I[651] = I[652] = I[653] = I[654] = I[655] = I[656] = I[657] = I[658] = I[659] = I[660] = I[661] = I[662] = I[663] = I[664] = I[665] = I[666] = (T)(img)(0,_n6##y,z,c)), \ - (I[682] = I[683] = I[684] = I[685] = I[686] = I[687] = I[688] = I[689] = I[690] = I[691] = I[692] = I[693] = I[694] = I[695] = I[696] = I[697] = (T)(img)(0,_n7##y,z,c)), \ - (I[713] = I[714] = I[715] = I[716] = I[717] = I[718] = I[719] = I[720] = I[721] = I[722] = I[723] = I[724] = I[725] = I[726] = I[727] = I[728] = (T)(img)(0,_n8##y,z,c)), \ - (I[744] = I[745] = I[746] = I[747] = I[748] = I[749] = I[750] = I[751] = I[752] = I[753] = I[754] = I[755] = I[756] = I[757] = I[758] = I[759] = (T)(img)(0,_n9##y,z,c)), \ - (I[775] = I[776] = I[777] = I[778] = I[779] = I[780] = I[781] = I[782] = I[783] = I[784] = I[785] = I[786] = I[787] = I[788] = I[789] = I[790] = (T)(img)(0,_n10##y,z,c)), \ - (I[806] = I[807] = I[808] = I[809] = I[810] = I[811] = I[812] = I[813] = I[814] = I[815] = I[816] = I[817] = I[818] = I[819] = I[820] = I[821] = (T)(img)(0,_n11##y,z,c)), \ - (I[837] = I[838] = I[839] = I[840] = I[841] = I[842] = I[843] = I[844] = I[845] = I[846] = I[847] = I[848] = I[849] = I[850] = I[851] = I[852] = (T)(img)(0,_n12##y,z,c)), \ - (I[868] = I[869] = I[870] = I[871] = I[872] = I[873] = I[874] = I[875] = I[876] = I[877] = I[878] = I[879] = I[880] = I[881] = I[882] = I[883] = (T)(img)(0,_n13##y,z,c)), \ - (I[899] = I[900] = I[901] = I[902] = I[903] = I[904] = I[905] = I[906] = I[907] = I[908] = I[909] = I[910] = I[911] = I[912] = I[913] = I[914] = (T)(img)(0,_n14##y,z,c)), \ - (I[930] = I[931] = I[932] = I[933] = I[934] = I[935] = I[936] = I[937] = I[938] = I[939] = I[940] = I[941] = I[942] = I[943] = I[944] = I[945] = (T)(img)(0,_n15##y,z,c)), \ - (I[16] = (T)(img)(_n1##x,_p15##y,z,c)), \ - (I[47] = (T)(img)(_n1##x,_p14##y,z,c)), \ - (I[78] = (T)(img)(_n1##x,_p13##y,z,c)), \ - (I[109] = (T)(img)(_n1##x,_p12##y,z,c)), \ - (I[140] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[171] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[202] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[233] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[264] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[295] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[326] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[357] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[388] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[419] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[450] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[481] = (T)(img)(_n1##x,y,z,c)), \ - (I[512] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[543] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[574] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[605] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[636] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[667] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[698] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[729] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[760] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[791] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[822] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[853] = (T)(img)(_n1##x,_n12##y,z,c)), \ - (I[884] = (T)(img)(_n1##x,_n13##y,z,c)), \ - (I[915] = (T)(img)(_n1##x,_n14##y,z,c)), \ - (I[946] = (T)(img)(_n1##x,_n15##y,z,c)), \ - (I[17] = (T)(img)(_n2##x,_p15##y,z,c)), \ - (I[48] = (T)(img)(_n2##x,_p14##y,z,c)), \ - (I[79] = (T)(img)(_n2##x,_p13##y,z,c)), \ - (I[110] = (T)(img)(_n2##x,_p12##y,z,c)), \ - (I[141] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[172] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[203] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[234] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[265] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[296] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[327] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[358] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[389] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[420] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[451] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[482] = (T)(img)(_n2##x,y,z,c)), \ - (I[513] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[544] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[575] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[606] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[637] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[668] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[699] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[730] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[761] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[792] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[823] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[854] = (T)(img)(_n2##x,_n12##y,z,c)), \ - (I[885] = (T)(img)(_n2##x,_n13##y,z,c)), \ - (I[916] = (T)(img)(_n2##x,_n14##y,z,c)), \ - (I[947] = (T)(img)(_n2##x,_n15##y,z,c)), \ - (I[18] = (T)(img)(_n3##x,_p15##y,z,c)), \ - (I[49] = (T)(img)(_n3##x,_p14##y,z,c)), \ - (I[80] = (T)(img)(_n3##x,_p13##y,z,c)), \ - (I[111] = (T)(img)(_n3##x,_p12##y,z,c)), \ - (I[142] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[173] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[204] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[235] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[266] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[297] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[328] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[359] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[390] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[421] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[452] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[483] = (T)(img)(_n3##x,y,z,c)), \ - (I[514] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[545] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[576] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[607] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[638] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[669] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[700] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[731] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[762] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[793] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[824] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[855] = (T)(img)(_n3##x,_n12##y,z,c)), \ - (I[886] = (T)(img)(_n3##x,_n13##y,z,c)), \ - (I[917] = (T)(img)(_n3##x,_n14##y,z,c)), \ - (I[948] = (T)(img)(_n3##x,_n15##y,z,c)), \ - (I[19] = (T)(img)(_n4##x,_p15##y,z,c)), \ - (I[50] = (T)(img)(_n4##x,_p14##y,z,c)), \ - (I[81] = (T)(img)(_n4##x,_p13##y,z,c)), \ - (I[112] = (T)(img)(_n4##x,_p12##y,z,c)), \ - (I[143] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[174] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[205] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[236] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[267] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[298] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[329] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[360] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[391] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[422] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[453] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[484] = (T)(img)(_n4##x,y,z,c)), \ - (I[515] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[546] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[577] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[608] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[639] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[670] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[701] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[732] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[763] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[794] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[825] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[856] = (T)(img)(_n4##x,_n12##y,z,c)), \ - (I[887] = (T)(img)(_n4##x,_n13##y,z,c)), \ - (I[918] = (T)(img)(_n4##x,_n14##y,z,c)), \ - (I[949] = (T)(img)(_n4##x,_n15##y,z,c)), \ - (I[20] = (T)(img)(_n5##x,_p15##y,z,c)), \ - (I[51] = (T)(img)(_n5##x,_p14##y,z,c)), \ - (I[82] = (T)(img)(_n5##x,_p13##y,z,c)), \ - (I[113] = (T)(img)(_n5##x,_p12##y,z,c)), \ - (I[144] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[175] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[206] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[237] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[268] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[299] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[330] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[361] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[392] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[423] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[454] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[485] = (T)(img)(_n5##x,y,z,c)), \ - (I[516] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[547] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[578] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[609] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[640] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[671] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[702] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[733] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[764] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[795] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[826] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[857] = (T)(img)(_n5##x,_n12##y,z,c)), \ - (I[888] = (T)(img)(_n5##x,_n13##y,z,c)), \ - (I[919] = (T)(img)(_n5##x,_n14##y,z,c)), \ - (I[950] = (T)(img)(_n5##x,_n15##y,z,c)), \ - (I[21] = (T)(img)(_n6##x,_p15##y,z,c)), \ - (I[52] = (T)(img)(_n6##x,_p14##y,z,c)), \ - (I[83] = (T)(img)(_n6##x,_p13##y,z,c)), \ - (I[114] = (T)(img)(_n6##x,_p12##y,z,c)), \ - (I[145] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[176] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[207] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[238] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[269] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[300] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[331] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[362] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[393] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[424] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[455] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[486] = (T)(img)(_n6##x,y,z,c)), \ - (I[517] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[548] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[579] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[610] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[641] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[672] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[703] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[734] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[765] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[796] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[827] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[858] = (T)(img)(_n6##x,_n12##y,z,c)), \ - (I[889] = (T)(img)(_n6##x,_n13##y,z,c)), \ - (I[920] = (T)(img)(_n6##x,_n14##y,z,c)), \ - (I[951] = (T)(img)(_n6##x,_n15##y,z,c)), \ - (I[22] = (T)(img)(_n7##x,_p15##y,z,c)), \ - (I[53] = (T)(img)(_n7##x,_p14##y,z,c)), \ - (I[84] = (T)(img)(_n7##x,_p13##y,z,c)), \ - (I[115] = (T)(img)(_n7##x,_p12##y,z,c)), \ - (I[146] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[177] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[208] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[239] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[270] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[301] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[332] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[363] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[394] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[425] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[456] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[487] = (T)(img)(_n7##x,y,z,c)), \ - (I[518] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[549] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[580] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[611] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[642] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[673] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[704] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[735] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[766] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[797] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[828] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[859] = (T)(img)(_n7##x,_n12##y,z,c)), \ - (I[890] = (T)(img)(_n7##x,_n13##y,z,c)), \ - (I[921] = (T)(img)(_n7##x,_n14##y,z,c)), \ - (I[952] = (T)(img)(_n7##x,_n15##y,z,c)), \ - (I[23] = (T)(img)(_n8##x,_p15##y,z,c)), \ - (I[54] = (T)(img)(_n8##x,_p14##y,z,c)), \ - (I[85] = (T)(img)(_n8##x,_p13##y,z,c)), \ - (I[116] = (T)(img)(_n8##x,_p12##y,z,c)), \ - (I[147] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[178] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[209] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[240] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[271] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[302] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[333] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[364] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[395] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[426] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[457] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[488] = (T)(img)(_n8##x,y,z,c)), \ - (I[519] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[550] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[581] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[612] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[643] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[674] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[705] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[736] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[767] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[798] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[829] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[860] = (T)(img)(_n8##x,_n12##y,z,c)), \ - (I[891] = (T)(img)(_n8##x,_n13##y,z,c)), \ - (I[922] = (T)(img)(_n8##x,_n14##y,z,c)), \ - (I[953] = (T)(img)(_n8##x,_n15##y,z,c)), \ - (I[24] = (T)(img)(_n9##x,_p15##y,z,c)), \ - (I[55] = (T)(img)(_n9##x,_p14##y,z,c)), \ - (I[86] = (T)(img)(_n9##x,_p13##y,z,c)), \ - (I[117] = (T)(img)(_n9##x,_p12##y,z,c)), \ - (I[148] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[179] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[210] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[241] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[272] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[303] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[334] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[365] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[396] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[427] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[458] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[489] = (T)(img)(_n9##x,y,z,c)), \ - (I[520] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[551] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[582] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[613] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[644] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[675] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[706] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[737] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[768] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[799] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[830] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[861] = (T)(img)(_n9##x,_n12##y,z,c)), \ - (I[892] = (T)(img)(_n9##x,_n13##y,z,c)), \ - (I[923] = (T)(img)(_n9##x,_n14##y,z,c)), \ - (I[954] = (T)(img)(_n9##x,_n15##y,z,c)), \ - (I[25] = (T)(img)(_n10##x,_p15##y,z,c)), \ - (I[56] = (T)(img)(_n10##x,_p14##y,z,c)), \ - (I[87] = (T)(img)(_n10##x,_p13##y,z,c)), \ - (I[118] = (T)(img)(_n10##x,_p12##y,z,c)), \ - (I[149] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[180] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[211] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[242] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[273] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[304] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[335] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[366] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[397] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[428] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[459] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[490] = (T)(img)(_n10##x,y,z,c)), \ - (I[521] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[552] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[583] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[614] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[645] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[676] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[707] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[738] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[769] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[800] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[831] = (T)(img)(_n10##x,_n11##y,z,c)), \ - (I[862] = (T)(img)(_n10##x,_n12##y,z,c)), \ - (I[893] = (T)(img)(_n10##x,_n13##y,z,c)), \ - (I[924] = (T)(img)(_n10##x,_n14##y,z,c)), \ - (I[955] = (T)(img)(_n10##x,_n15##y,z,c)), \ - (I[26] = (T)(img)(_n11##x,_p15##y,z,c)), \ - (I[57] = (T)(img)(_n11##x,_p14##y,z,c)), \ - (I[88] = (T)(img)(_n11##x,_p13##y,z,c)), \ - (I[119] = (T)(img)(_n11##x,_p12##y,z,c)), \ - (I[150] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[181] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[212] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[243] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[274] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[305] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[336] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[367] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[398] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[429] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[460] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[491] = (T)(img)(_n11##x,y,z,c)), \ - (I[522] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[553] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[584] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[615] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[646] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[677] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[708] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[739] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[770] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[801] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[832] = (T)(img)(_n11##x,_n11##y,z,c)), \ - (I[863] = (T)(img)(_n11##x,_n12##y,z,c)), \ - (I[894] = (T)(img)(_n11##x,_n13##y,z,c)), \ - (I[925] = (T)(img)(_n11##x,_n14##y,z,c)), \ - (I[956] = (T)(img)(_n11##x,_n15##y,z,c)), \ - (I[27] = (T)(img)(_n12##x,_p15##y,z,c)), \ - (I[58] = (T)(img)(_n12##x,_p14##y,z,c)), \ - (I[89] = (T)(img)(_n12##x,_p13##y,z,c)), \ - (I[120] = (T)(img)(_n12##x,_p12##y,z,c)), \ - (I[151] = (T)(img)(_n12##x,_p11##y,z,c)), \ - (I[182] = (T)(img)(_n12##x,_p10##y,z,c)), \ - (I[213] = (T)(img)(_n12##x,_p9##y,z,c)), \ - (I[244] = (T)(img)(_n12##x,_p8##y,z,c)), \ - (I[275] = (T)(img)(_n12##x,_p7##y,z,c)), \ - (I[306] = (T)(img)(_n12##x,_p6##y,z,c)), \ - (I[337] = (T)(img)(_n12##x,_p5##y,z,c)), \ - (I[368] = (T)(img)(_n12##x,_p4##y,z,c)), \ - (I[399] = (T)(img)(_n12##x,_p3##y,z,c)), \ - (I[430] = (T)(img)(_n12##x,_p2##y,z,c)), \ - (I[461] = (T)(img)(_n12##x,_p1##y,z,c)), \ - (I[492] = (T)(img)(_n12##x,y,z,c)), \ - (I[523] = (T)(img)(_n12##x,_n1##y,z,c)), \ - (I[554] = (T)(img)(_n12##x,_n2##y,z,c)), \ - (I[585] = (T)(img)(_n12##x,_n3##y,z,c)), \ - (I[616] = (T)(img)(_n12##x,_n4##y,z,c)), \ - (I[647] = (T)(img)(_n12##x,_n5##y,z,c)), \ - (I[678] = (T)(img)(_n12##x,_n6##y,z,c)), \ - (I[709] = (T)(img)(_n12##x,_n7##y,z,c)), \ - (I[740] = (T)(img)(_n12##x,_n8##y,z,c)), \ - (I[771] = (T)(img)(_n12##x,_n9##y,z,c)), \ - (I[802] = (T)(img)(_n12##x,_n10##y,z,c)), \ - (I[833] = (T)(img)(_n12##x,_n11##y,z,c)), \ - (I[864] = (T)(img)(_n12##x,_n12##y,z,c)), \ - (I[895] = (T)(img)(_n12##x,_n13##y,z,c)), \ - (I[926] = (T)(img)(_n12##x,_n14##y,z,c)), \ - (I[957] = (T)(img)(_n12##x,_n15##y,z,c)), \ - (I[28] = (T)(img)(_n13##x,_p15##y,z,c)), \ - (I[59] = (T)(img)(_n13##x,_p14##y,z,c)), \ - (I[90] = (T)(img)(_n13##x,_p13##y,z,c)), \ - (I[121] = (T)(img)(_n13##x,_p12##y,z,c)), \ - (I[152] = (T)(img)(_n13##x,_p11##y,z,c)), \ - (I[183] = (T)(img)(_n13##x,_p10##y,z,c)), \ - (I[214] = (T)(img)(_n13##x,_p9##y,z,c)), \ - (I[245] = (T)(img)(_n13##x,_p8##y,z,c)), \ - (I[276] = (T)(img)(_n13##x,_p7##y,z,c)), \ - (I[307] = (T)(img)(_n13##x,_p6##y,z,c)), \ - (I[338] = (T)(img)(_n13##x,_p5##y,z,c)), \ - (I[369] = (T)(img)(_n13##x,_p4##y,z,c)), \ - (I[400] = (T)(img)(_n13##x,_p3##y,z,c)), \ - (I[431] = (T)(img)(_n13##x,_p2##y,z,c)), \ - (I[462] = (T)(img)(_n13##x,_p1##y,z,c)), \ - (I[493] = (T)(img)(_n13##x,y,z,c)), \ - (I[524] = (T)(img)(_n13##x,_n1##y,z,c)), \ - (I[555] = (T)(img)(_n13##x,_n2##y,z,c)), \ - (I[586] = (T)(img)(_n13##x,_n3##y,z,c)), \ - (I[617] = (T)(img)(_n13##x,_n4##y,z,c)), \ - (I[648] = (T)(img)(_n13##x,_n5##y,z,c)), \ - (I[679] = (T)(img)(_n13##x,_n6##y,z,c)), \ - (I[710] = (T)(img)(_n13##x,_n7##y,z,c)), \ - (I[741] = (T)(img)(_n13##x,_n8##y,z,c)), \ - (I[772] = (T)(img)(_n13##x,_n9##y,z,c)), \ - (I[803] = (T)(img)(_n13##x,_n10##y,z,c)), \ - (I[834] = (T)(img)(_n13##x,_n11##y,z,c)), \ - (I[865] = (T)(img)(_n13##x,_n12##y,z,c)), \ - (I[896] = (T)(img)(_n13##x,_n13##y,z,c)), \ - (I[927] = (T)(img)(_n13##x,_n14##y,z,c)), \ - (I[958] = (T)(img)(_n13##x,_n15##y,z,c)), \ - (I[29] = (T)(img)(_n14##x,_p15##y,z,c)), \ - (I[60] = (T)(img)(_n14##x,_p14##y,z,c)), \ - (I[91] = (T)(img)(_n14##x,_p13##y,z,c)), \ - (I[122] = (T)(img)(_n14##x,_p12##y,z,c)), \ - (I[153] = (T)(img)(_n14##x,_p11##y,z,c)), \ - (I[184] = (T)(img)(_n14##x,_p10##y,z,c)), \ - (I[215] = (T)(img)(_n14##x,_p9##y,z,c)), \ - (I[246] = (T)(img)(_n14##x,_p8##y,z,c)), \ - (I[277] = (T)(img)(_n14##x,_p7##y,z,c)), \ - (I[308] = (T)(img)(_n14##x,_p6##y,z,c)), \ - (I[339] = (T)(img)(_n14##x,_p5##y,z,c)), \ - (I[370] = (T)(img)(_n14##x,_p4##y,z,c)), \ - (I[401] = (T)(img)(_n14##x,_p3##y,z,c)), \ - (I[432] = (T)(img)(_n14##x,_p2##y,z,c)), \ - (I[463] = (T)(img)(_n14##x,_p1##y,z,c)), \ - (I[494] = (T)(img)(_n14##x,y,z,c)), \ - (I[525] = (T)(img)(_n14##x,_n1##y,z,c)), \ - (I[556] = (T)(img)(_n14##x,_n2##y,z,c)), \ - (I[587] = (T)(img)(_n14##x,_n3##y,z,c)), \ - (I[618] = (T)(img)(_n14##x,_n4##y,z,c)), \ - (I[649] = (T)(img)(_n14##x,_n5##y,z,c)), \ - (I[680] = (T)(img)(_n14##x,_n6##y,z,c)), \ - (I[711] = (T)(img)(_n14##x,_n7##y,z,c)), \ - (I[742] = (T)(img)(_n14##x,_n8##y,z,c)), \ - (I[773] = (T)(img)(_n14##x,_n9##y,z,c)), \ - (I[804] = (T)(img)(_n14##x,_n10##y,z,c)), \ - (I[835] = (T)(img)(_n14##x,_n11##y,z,c)), \ - (I[866] = (T)(img)(_n14##x,_n12##y,z,c)), \ - (I[897] = (T)(img)(_n14##x,_n13##y,z,c)), \ - (I[928] = (T)(img)(_n14##x,_n14##y,z,c)), \ - (I[959] = (T)(img)(_n14##x,_n15##y,z,c)), \ - 15>=((img)._width)?(img).width() - 1:15); \ - (_n15##x<(img).width() && ( \ - (I[30] = (T)(img)(_n15##x,_p15##y,z,c)), \ - (I[61] = (T)(img)(_n15##x,_p14##y,z,c)), \ - (I[92] = (T)(img)(_n15##x,_p13##y,z,c)), \ - (I[123] = (T)(img)(_n15##x,_p12##y,z,c)), \ - (I[154] = (T)(img)(_n15##x,_p11##y,z,c)), \ - (I[185] = (T)(img)(_n15##x,_p10##y,z,c)), \ - (I[216] = (T)(img)(_n15##x,_p9##y,z,c)), \ - (I[247] = (T)(img)(_n15##x,_p8##y,z,c)), \ - (I[278] = (T)(img)(_n15##x,_p7##y,z,c)), \ - (I[309] = (T)(img)(_n15##x,_p6##y,z,c)), \ - (I[340] = (T)(img)(_n15##x,_p5##y,z,c)), \ - (I[371] = (T)(img)(_n15##x,_p4##y,z,c)), \ - (I[402] = (T)(img)(_n15##x,_p3##y,z,c)), \ - (I[433] = (T)(img)(_n15##x,_p2##y,z,c)), \ - (I[464] = (T)(img)(_n15##x,_p1##y,z,c)), \ - (I[495] = (T)(img)(_n15##x,y,z,c)), \ - (I[526] = (T)(img)(_n15##x,_n1##y,z,c)), \ - (I[557] = (T)(img)(_n15##x,_n2##y,z,c)), \ - (I[588] = (T)(img)(_n15##x,_n3##y,z,c)), \ - (I[619] = (T)(img)(_n15##x,_n4##y,z,c)), \ - (I[650] = (T)(img)(_n15##x,_n5##y,z,c)), \ - (I[681] = (T)(img)(_n15##x,_n6##y,z,c)), \ - (I[712] = (T)(img)(_n15##x,_n7##y,z,c)), \ - (I[743] = (T)(img)(_n15##x,_n8##y,z,c)), \ - (I[774] = (T)(img)(_n15##x,_n9##y,z,c)), \ - (I[805] = (T)(img)(_n15##x,_n10##y,z,c)), \ - (I[836] = (T)(img)(_n15##x,_n11##y,z,c)), \ - (I[867] = (T)(img)(_n15##x,_n12##y,z,c)), \ - (I[898] = (T)(img)(_n15##x,_n13##y,z,c)), \ - (I[929] = (T)(img)(_n15##x,_n14##y,z,c)), \ - (I[960] = (T)(img)(_n15##x,_n15##y,z,c)),1)) || \ - _n14##x==--_n15##x || _n13##x==--_n14##x || _n12##x==--_n13##x || _n11##x==--_n12##x || _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n15##x = _n14##x = _n13##x = _n12##x = _n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], \ - I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], \ - I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], \ - I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], \ - I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], \ - I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], \ - I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], \ - I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], \ - I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], \ - I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], \ - I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], \ - I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], \ - I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], \ - I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], I[415] = I[416], I[416] = I[417], I[417] = I[418], I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], \ - I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], I[447] = I[448], I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], I[463] = I[464], \ - I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], I[479] = I[480], I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], I[493] = I[494], I[494] = I[495], \ - I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], I[503] = I[504], I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], I[511] = I[512], I[512] = I[513], I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], I[519] = I[520], I[520] = I[521], I[521] = I[522], I[522] = I[523], I[523] = I[524], I[524] = I[525], I[525] = I[526], \ - I[527] = I[528], I[528] = I[529], I[529] = I[530], I[530] = I[531], I[531] = I[532], I[532] = I[533], I[533] = I[534], I[534] = I[535], I[535] = I[536], I[536] = I[537], I[537] = I[538], I[538] = I[539], I[539] = I[540], I[540] = I[541], I[541] = I[542], I[542] = I[543], I[543] = I[544], I[544] = I[545], I[545] = I[546], I[546] = I[547], I[547] = I[548], I[548] = I[549], I[549] = I[550], I[550] = I[551], I[551] = I[552], I[552] = I[553], I[553] = I[554], I[554] = I[555], I[555] = I[556], I[556] = I[557], \ - I[558] = I[559], I[559] = I[560], I[560] = I[561], I[561] = I[562], I[562] = I[563], I[563] = I[564], I[564] = I[565], I[565] = I[566], I[566] = I[567], I[567] = I[568], I[568] = I[569], I[569] = I[570], I[570] = I[571], I[571] = I[572], I[572] = I[573], I[573] = I[574], I[574] = I[575], I[575] = I[576], I[576] = I[577], I[577] = I[578], I[578] = I[579], I[579] = I[580], I[580] = I[581], I[581] = I[582], I[582] = I[583], I[583] = I[584], I[584] = I[585], I[585] = I[586], I[586] = I[587], I[587] = I[588], \ - I[589] = I[590], I[590] = I[591], I[591] = I[592], I[592] = I[593], I[593] = I[594], I[594] = I[595], I[595] = I[596], I[596] = I[597], I[597] = I[598], I[598] = I[599], I[599] = I[600], I[600] = I[601], I[601] = I[602], I[602] = I[603], I[603] = I[604], I[604] = I[605], I[605] = I[606], I[606] = I[607], I[607] = I[608], I[608] = I[609], I[609] = I[610], I[610] = I[611], I[611] = I[612], I[612] = I[613], I[613] = I[614], I[614] = I[615], I[615] = I[616], I[616] = I[617], I[617] = I[618], I[618] = I[619], \ - I[620] = I[621], I[621] = I[622], I[622] = I[623], I[623] = I[624], I[624] = I[625], I[625] = I[626], I[626] = I[627], I[627] = I[628], I[628] = I[629], I[629] = I[630], I[630] = I[631], I[631] = I[632], I[632] = I[633], I[633] = I[634], I[634] = I[635], I[635] = I[636], I[636] = I[637], I[637] = I[638], I[638] = I[639], I[639] = I[640], I[640] = I[641], I[641] = I[642], I[642] = I[643], I[643] = I[644], I[644] = I[645], I[645] = I[646], I[646] = I[647], I[647] = I[648], I[648] = I[649], I[649] = I[650], \ - I[651] = I[652], I[652] = I[653], I[653] = I[654], I[654] = I[655], I[655] = I[656], I[656] = I[657], I[657] = I[658], I[658] = I[659], I[659] = I[660], I[660] = I[661], I[661] = I[662], I[662] = I[663], I[663] = I[664], I[664] = I[665], I[665] = I[666], I[666] = I[667], I[667] = I[668], I[668] = I[669], I[669] = I[670], I[670] = I[671], I[671] = I[672], I[672] = I[673], I[673] = I[674], I[674] = I[675], I[675] = I[676], I[676] = I[677], I[677] = I[678], I[678] = I[679], I[679] = I[680], I[680] = I[681], \ - I[682] = I[683], I[683] = I[684], I[684] = I[685], I[685] = I[686], I[686] = I[687], I[687] = I[688], I[688] = I[689], I[689] = I[690], I[690] = I[691], I[691] = I[692], I[692] = I[693], I[693] = I[694], I[694] = I[695], I[695] = I[696], I[696] = I[697], I[697] = I[698], I[698] = I[699], I[699] = I[700], I[700] = I[701], I[701] = I[702], I[702] = I[703], I[703] = I[704], I[704] = I[705], I[705] = I[706], I[706] = I[707], I[707] = I[708], I[708] = I[709], I[709] = I[710], I[710] = I[711], I[711] = I[712], \ - I[713] = I[714], I[714] = I[715], I[715] = I[716], I[716] = I[717], I[717] = I[718], I[718] = I[719], I[719] = I[720], I[720] = I[721], I[721] = I[722], I[722] = I[723], I[723] = I[724], I[724] = I[725], I[725] = I[726], I[726] = I[727], I[727] = I[728], I[728] = I[729], I[729] = I[730], I[730] = I[731], I[731] = I[732], I[732] = I[733], I[733] = I[734], I[734] = I[735], I[735] = I[736], I[736] = I[737], I[737] = I[738], I[738] = I[739], I[739] = I[740], I[740] = I[741], I[741] = I[742], I[742] = I[743], \ - I[744] = I[745], I[745] = I[746], I[746] = I[747], I[747] = I[748], I[748] = I[749], I[749] = I[750], I[750] = I[751], I[751] = I[752], I[752] = I[753], I[753] = I[754], I[754] = I[755], I[755] = I[756], I[756] = I[757], I[757] = I[758], I[758] = I[759], I[759] = I[760], I[760] = I[761], I[761] = I[762], I[762] = I[763], I[763] = I[764], I[764] = I[765], I[765] = I[766], I[766] = I[767], I[767] = I[768], I[768] = I[769], I[769] = I[770], I[770] = I[771], I[771] = I[772], I[772] = I[773], I[773] = I[774], \ - I[775] = I[776], I[776] = I[777], I[777] = I[778], I[778] = I[779], I[779] = I[780], I[780] = I[781], I[781] = I[782], I[782] = I[783], I[783] = I[784], I[784] = I[785], I[785] = I[786], I[786] = I[787], I[787] = I[788], I[788] = I[789], I[789] = I[790], I[790] = I[791], I[791] = I[792], I[792] = I[793], I[793] = I[794], I[794] = I[795], I[795] = I[796], I[796] = I[797], I[797] = I[798], I[798] = I[799], I[799] = I[800], I[800] = I[801], I[801] = I[802], I[802] = I[803], I[803] = I[804], I[804] = I[805], \ - I[806] = I[807], I[807] = I[808], I[808] = I[809], I[809] = I[810], I[810] = I[811], I[811] = I[812], I[812] = I[813], I[813] = I[814], I[814] = I[815], I[815] = I[816], I[816] = I[817], I[817] = I[818], I[818] = I[819], I[819] = I[820], I[820] = I[821], I[821] = I[822], I[822] = I[823], I[823] = I[824], I[824] = I[825], I[825] = I[826], I[826] = I[827], I[827] = I[828], I[828] = I[829], I[829] = I[830], I[830] = I[831], I[831] = I[832], I[832] = I[833], I[833] = I[834], I[834] = I[835], I[835] = I[836], \ - I[837] = I[838], I[838] = I[839], I[839] = I[840], I[840] = I[841], I[841] = I[842], I[842] = I[843], I[843] = I[844], I[844] = I[845], I[845] = I[846], I[846] = I[847], I[847] = I[848], I[848] = I[849], I[849] = I[850], I[850] = I[851], I[851] = I[852], I[852] = I[853], I[853] = I[854], I[854] = I[855], I[855] = I[856], I[856] = I[857], I[857] = I[858], I[858] = I[859], I[859] = I[860], I[860] = I[861], I[861] = I[862], I[862] = I[863], I[863] = I[864], I[864] = I[865], I[865] = I[866], I[866] = I[867], \ - I[868] = I[869], I[869] = I[870], I[870] = I[871], I[871] = I[872], I[872] = I[873], I[873] = I[874], I[874] = I[875], I[875] = I[876], I[876] = I[877], I[877] = I[878], I[878] = I[879], I[879] = I[880], I[880] = I[881], I[881] = I[882], I[882] = I[883], I[883] = I[884], I[884] = I[885], I[885] = I[886], I[886] = I[887], I[887] = I[888], I[888] = I[889], I[889] = I[890], I[890] = I[891], I[891] = I[892], I[892] = I[893], I[893] = I[894], I[894] = I[895], I[895] = I[896], I[896] = I[897], I[897] = I[898], \ - I[899] = I[900], I[900] = I[901], I[901] = I[902], I[902] = I[903], I[903] = I[904], I[904] = I[905], I[905] = I[906], I[906] = I[907], I[907] = I[908], I[908] = I[909], I[909] = I[910], I[910] = I[911], I[911] = I[912], I[912] = I[913], I[913] = I[914], I[914] = I[915], I[915] = I[916], I[916] = I[917], I[917] = I[918], I[918] = I[919], I[919] = I[920], I[920] = I[921], I[921] = I[922], I[922] = I[923], I[923] = I[924], I[924] = I[925], I[925] = I[926], I[926] = I[927], I[927] = I[928], I[928] = I[929], \ - I[930] = I[931], I[931] = I[932], I[932] = I[933], I[933] = I[934], I[934] = I[935], I[935] = I[936], I[936] = I[937], I[937] = I[938], I[938] = I[939], I[939] = I[940], I[940] = I[941], I[941] = I[942], I[942] = I[943], I[943] = I[944], I[944] = I[945], I[945] = I[946], I[946] = I[947], I[947] = I[948], I[948] = I[949], I[949] = I[950], I[950] = I[951], I[951] = I[952], I[952] = I[953], I[953] = I[954], I[954] = I[955], I[955] = I[956], I[956] = I[957], I[957] = I[958], I[958] = I[959], I[959] = I[960], \ - _p15##x = _p14##x, _p14##x = _p13##x, _p13##x = _p12##x, _p12##x = _p11##x, _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x, ++_n12##x, ++_n13##x, ++_n14##x, ++_n15##x) - -#define cimg_for_in31x31(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in31((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p15##x = x - 15<0?0:x - 15, \ - _p14##x = x - 14<0?0:x - 14, \ - _p13##x = x - 13<0?0:x - 13, \ - _p12##x = x - 12<0?0:x - 12, \ - _p11##x = x - 11<0?0:x - 11, \ - _p10##x = x - 10<0?0:x - 10, \ - _p9##x = x - 9<0?0:x - 9, \ - _p8##x = x - 8<0?0:x - 8, \ - _p7##x = x - 7<0?0:x - 7, \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = x + 6>=(img).width()?(img).width() - 1:x + 6, \ - _n7##x = x + 7>=(img).width()?(img).width() - 1:x + 7, \ - _n8##x = x + 8>=(img).width()?(img).width() - 1:x + 8, \ - _n9##x = x + 9>=(img).width()?(img).width() - 1:x + 9, \ - _n10##x = x + 10>=(img).width()?(img).width() - 1:x + 10, \ - _n11##x = x + 11>=(img).width()?(img).width() - 1:x + 11, \ - _n12##x = x + 12>=(img).width()?(img).width() - 1:x + 12, \ - _n13##x = x + 13>=(img).width()?(img).width() - 1:x + 13, \ - _n14##x = x + 14>=(img).width()?(img).width() - 1:x + 14, \ - _n15##x = (int)( \ - (I[0] = (T)(img)(_p15##x,_p15##y,z,c)), \ - (I[31] = (T)(img)(_p15##x,_p14##y,z,c)), \ - (I[62] = (T)(img)(_p15##x,_p13##y,z,c)), \ - (I[93] = (T)(img)(_p15##x,_p12##y,z,c)), \ - (I[124] = (T)(img)(_p15##x,_p11##y,z,c)), \ - (I[155] = (T)(img)(_p15##x,_p10##y,z,c)), \ - (I[186] = (T)(img)(_p15##x,_p9##y,z,c)), \ - (I[217] = (T)(img)(_p15##x,_p8##y,z,c)), \ - (I[248] = (T)(img)(_p15##x,_p7##y,z,c)), \ - (I[279] = (T)(img)(_p15##x,_p6##y,z,c)), \ - (I[310] = (T)(img)(_p15##x,_p5##y,z,c)), \ - (I[341] = (T)(img)(_p15##x,_p4##y,z,c)), \ - (I[372] = (T)(img)(_p15##x,_p3##y,z,c)), \ - (I[403] = (T)(img)(_p15##x,_p2##y,z,c)), \ - (I[434] = (T)(img)(_p15##x,_p1##y,z,c)), \ - (I[465] = (T)(img)(_p15##x,y,z,c)), \ - (I[496] = (T)(img)(_p15##x,_n1##y,z,c)), \ - (I[527] = (T)(img)(_p15##x,_n2##y,z,c)), \ - (I[558] = (T)(img)(_p15##x,_n3##y,z,c)), \ - (I[589] = (T)(img)(_p15##x,_n4##y,z,c)), \ - (I[620] = (T)(img)(_p15##x,_n5##y,z,c)), \ - (I[651] = (T)(img)(_p15##x,_n6##y,z,c)), \ - (I[682] = (T)(img)(_p15##x,_n7##y,z,c)), \ - (I[713] = (T)(img)(_p15##x,_n8##y,z,c)), \ - (I[744] = (T)(img)(_p15##x,_n9##y,z,c)), \ - (I[775] = (T)(img)(_p15##x,_n10##y,z,c)), \ - (I[806] = (T)(img)(_p15##x,_n11##y,z,c)), \ - (I[837] = (T)(img)(_p15##x,_n12##y,z,c)), \ - (I[868] = (T)(img)(_p15##x,_n13##y,z,c)), \ - (I[899] = (T)(img)(_p15##x,_n14##y,z,c)), \ - (I[930] = (T)(img)(_p15##x,_n15##y,z,c)), \ - (I[1] = (T)(img)(_p14##x,_p15##y,z,c)), \ - (I[32] = (T)(img)(_p14##x,_p14##y,z,c)), \ - (I[63] = (T)(img)(_p14##x,_p13##y,z,c)), \ - (I[94] = (T)(img)(_p14##x,_p12##y,z,c)), \ - (I[125] = (T)(img)(_p14##x,_p11##y,z,c)), \ - (I[156] = (T)(img)(_p14##x,_p10##y,z,c)), \ - (I[187] = (T)(img)(_p14##x,_p9##y,z,c)), \ - (I[218] = (T)(img)(_p14##x,_p8##y,z,c)), \ - (I[249] = (T)(img)(_p14##x,_p7##y,z,c)), \ - (I[280] = (T)(img)(_p14##x,_p6##y,z,c)), \ - (I[311] = (T)(img)(_p14##x,_p5##y,z,c)), \ - (I[342] = (T)(img)(_p14##x,_p4##y,z,c)), \ - (I[373] = (T)(img)(_p14##x,_p3##y,z,c)), \ - (I[404] = (T)(img)(_p14##x,_p2##y,z,c)), \ - (I[435] = (T)(img)(_p14##x,_p1##y,z,c)), \ - (I[466] = (T)(img)(_p14##x,y,z,c)), \ - (I[497] = (T)(img)(_p14##x,_n1##y,z,c)), \ - (I[528] = (T)(img)(_p14##x,_n2##y,z,c)), \ - (I[559] = (T)(img)(_p14##x,_n3##y,z,c)), \ - (I[590] = (T)(img)(_p14##x,_n4##y,z,c)), \ - (I[621] = (T)(img)(_p14##x,_n5##y,z,c)), \ - (I[652] = (T)(img)(_p14##x,_n6##y,z,c)), \ - (I[683] = (T)(img)(_p14##x,_n7##y,z,c)), \ - (I[714] = (T)(img)(_p14##x,_n8##y,z,c)), \ - (I[745] = (T)(img)(_p14##x,_n9##y,z,c)), \ - (I[776] = (T)(img)(_p14##x,_n10##y,z,c)), \ - (I[807] = (T)(img)(_p14##x,_n11##y,z,c)), \ - (I[838] = (T)(img)(_p14##x,_n12##y,z,c)), \ - (I[869] = (T)(img)(_p14##x,_n13##y,z,c)), \ - (I[900] = (T)(img)(_p14##x,_n14##y,z,c)), \ - (I[931] = (T)(img)(_p14##x,_n15##y,z,c)), \ - (I[2] = (T)(img)(_p13##x,_p15##y,z,c)), \ - (I[33] = (T)(img)(_p13##x,_p14##y,z,c)), \ - (I[64] = (T)(img)(_p13##x,_p13##y,z,c)), \ - (I[95] = (T)(img)(_p13##x,_p12##y,z,c)), \ - (I[126] = (T)(img)(_p13##x,_p11##y,z,c)), \ - (I[157] = (T)(img)(_p13##x,_p10##y,z,c)), \ - (I[188] = (T)(img)(_p13##x,_p9##y,z,c)), \ - (I[219] = (T)(img)(_p13##x,_p8##y,z,c)), \ - (I[250] = (T)(img)(_p13##x,_p7##y,z,c)), \ - (I[281] = (T)(img)(_p13##x,_p6##y,z,c)), \ - (I[312] = (T)(img)(_p13##x,_p5##y,z,c)), \ - (I[343] = (T)(img)(_p13##x,_p4##y,z,c)), \ - (I[374] = (T)(img)(_p13##x,_p3##y,z,c)), \ - (I[405] = (T)(img)(_p13##x,_p2##y,z,c)), \ - (I[436] = (T)(img)(_p13##x,_p1##y,z,c)), \ - (I[467] = (T)(img)(_p13##x,y,z,c)), \ - (I[498] = (T)(img)(_p13##x,_n1##y,z,c)), \ - (I[529] = (T)(img)(_p13##x,_n2##y,z,c)), \ - (I[560] = (T)(img)(_p13##x,_n3##y,z,c)), \ - (I[591] = (T)(img)(_p13##x,_n4##y,z,c)), \ - (I[622] = (T)(img)(_p13##x,_n5##y,z,c)), \ - (I[653] = (T)(img)(_p13##x,_n6##y,z,c)), \ - (I[684] = (T)(img)(_p13##x,_n7##y,z,c)), \ - (I[715] = (T)(img)(_p13##x,_n8##y,z,c)), \ - (I[746] = (T)(img)(_p13##x,_n9##y,z,c)), \ - (I[777] = (T)(img)(_p13##x,_n10##y,z,c)), \ - (I[808] = (T)(img)(_p13##x,_n11##y,z,c)), \ - (I[839] = (T)(img)(_p13##x,_n12##y,z,c)), \ - (I[870] = (T)(img)(_p13##x,_n13##y,z,c)), \ - (I[901] = (T)(img)(_p13##x,_n14##y,z,c)), \ - (I[932] = (T)(img)(_p13##x,_n15##y,z,c)), \ - (I[3] = (T)(img)(_p12##x,_p15##y,z,c)), \ - (I[34] = (T)(img)(_p12##x,_p14##y,z,c)), \ - (I[65] = (T)(img)(_p12##x,_p13##y,z,c)), \ - (I[96] = (T)(img)(_p12##x,_p12##y,z,c)), \ - (I[127] = (T)(img)(_p12##x,_p11##y,z,c)), \ - (I[158] = (T)(img)(_p12##x,_p10##y,z,c)), \ - (I[189] = (T)(img)(_p12##x,_p9##y,z,c)), \ - (I[220] = (T)(img)(_p12##x,_p8##y,z,c)), \ - (I[251] = (T)(img)(_p12##x,_p7##y,z,c)), \ - (I[282] = (T)(img)(_p12##x,_p6##y,z,c)), \ - (I[313] = (T)(img)(_p12##x,_p5##y,z,c)), \ - (I[344] = (T)(img)(_p12##x,_p4##y,z,c)), \ - (I[375] = (T)(img)(_p12##x,_p3##y,z,c)), \ - (I[406] = (T)(img)(_p12##x,_p2##y,z,c)), \ - (I[437] = (T)(img)(_p12##x,_p1##y,z,c)), \ - (I[468] = (T)(img)(_p12##x,y,z,c)), \ - (I[499] = (T)(img)(_p12##x,_n1##y,z,c)), \ - (I[530] = (T)(img)(_p12##x,_n2##y,z,c)), \ - (I[561] = (T)(img)(_p12##x,_n3##y,z,c)), \ - (I[592] = (T)(img)(_p12##x,_n4##y,z,c)), \ - (I[623] = (T)(img)(_p12##x,_n5##y,z,c)), \ - (I[654] = (T)(img)(_p12##x,_n6##y,z,c)), \ - (I[685] = (T)(img)(_p12##x,_n7##y,z,c)), \ - (I[716] = (T)(img)(_p12##x,_n8##y,z,c)), \ - (I[747] = (T)(img)(_p12##x,_n9##y,z,c)), \ - (I[778] = (T)(img)(_p12##x,_n10##y,z,c)), \ - (I[809] = (T)(img)(_p12##x,_n11##y,z,c)), \ - (I[840] = (T)(img)(_p12##x,_n12##y,z,c)), \ - (I[871] = (T)(img)(_p12##x,_n13##y,z,c)), \ - (I[902] = (T)(img)(_p12##x,_n14##y,z,c)), \ - (I[933] = (T)(img)(_p12##x,_n15##y,z,c)), \ - (I[4] = (T)(img)(_p11##x,_p15##y,z,c)), \ - (I[35] = (T)(img)(_p11##x,_p14##y,z,c)), \ - (I[66] = (T)(img)(_p11##x,_p13##y,z,c)), \ - (I[97] = (T)(img)(_p11##x,_p12##y,z,c)), \ - (I[128] = (T)(img)(_p11##x,_p11##y,z,c)), \ - (I[159] = (T)(img)(_p11##x,_p10##y,z,c)), \ - (I[190] = (T)(img)(_p11##x,_p9##y,z,c)), \ - (I[221] = (T)(img)(_p11##x,_p8##y,z,c)), \ - (I[252] = (T)(img)(_p11##x,_p7##y,z,c)), \ - (I[283] = (T)(img)(_p11##x,_p6##y,z,c)), \ - (I[314] = (T)(img)(_p11##x,_p5##y,z,c)), \ - (I[345] = (T)(img)(_p11##x,_p4##y,z,c)), \ - (I[376] = (T)(img)(_p11##x,_p3##y,z,c)), \ - (I[407] = (T)(img)(_p11##x,_p2##y,z,c)), \ - (I[438] = (T)(img)(_p11##x,_p1##y,z,c)), \ - (I[469] = (T)(img)(_p11##x,y,z,c)), \ - (I[500] = (T)(img)(_p11##x,_n1##y,z,c)), \ - (I[531] = (T)(img)(_p11##x,_n2##y,z,c)), \ - (I[562] = (T)(img)(_p11##x,_n3##y,z,c)), \ - (I[593] = (T)(img)(_p11##x,_n4##y,z,c)), \ - (I[624] = (T)(img)(_p11##x,_n5##y,z,c)), \ - (I[655] = (T)(img)(_p11##x,_n6##y,z,c)), \ - (I[686] = (T)(img)(_p11##x,_n7##y,z,c)), \ - (I[717] = (T)(img)(_p11##x,_n8##y,z,c)), \ - (I[748] = (T)(img)(_p11##x,_n9##y,z,c)), \ - (I[779] = (T)(img)(_p11##x,_n10##y,z,c)), \ - (I[810] = (T)(img)(_p11##x,_n11##y,z,c)), \ - (I[841] = (T)(img)(_p11##x,_n12##y,z,c)), \ - (I[872] = (T)(img)(_p11##x,_n13##y,z,c)), \ - (I[903] = (T)(img)(_p11##x,_n14##y,z,c)), \ - (I[934] = (T)(img)(_p11##x,_n15##y,z,c)), \ - (I[5] = (T)(img)(_p10##x,_p15##y,z,c)), \ - (I[36] = (T)(img)(_p10##x,_p14##y,z,c)), \ - (I[67] = (T)(img)(_p10##x,_p13##y,z,c)), \ - (I[98] = (T)(img)(_p10##x,_p12##y,z,c)), \ - (I[129] = (T)(img)(_p10##x,_p11##y,z,c)), \ - (I[160] = (T)(img)(_p10##x,_p10##y,z,c)), \ - (I[191] = (T)(img)(_p10##x,_p9##y,z,c)), \ - (I[222] = (T)(img)(_p10##x,_p8##y,z,c)), \ - (I[253] = (T)(img)(_p10##x,_p7##y,z,c)), \ - (I[284] = (T)(img)(_p10##x,_p6##y,z,c)), \ - (I[315] = (T)(img)(_p10##x,_p5##y,z,c)), \ - (I[346] = (T)(img)(_p10##x,_p4##y,z,c)), \ - (I[377] = (T)(img)(_p10##x,_p3##y,z,c)), \ - (I[408] = (T)(img)(_p10##x,_p2##y,z,c)), \ - (I[439] = (T)(img)(_p10##x,_p1##y,z,c)), \ - (I[470] = (T)(img)(_p10##x,y,z,c)), \ - (I[501] = (T)(img)(_p10##x,_n1##y,z,c)), \ - (I[532] = (T)(img)(_p10##x,_n2##y,z,c)), \ - (I[563] = (T)(img)(_p10##x,_n3##y,z,c)), \ - (I[594] = (T)(img)(_p10##x,_n4##y,z,c)), \ - (I[625] = (T)(img)(_p10##x,_n5##y,z,c)), \ - (I[656] = (T)(img)(_p10##x,_n6##y,z,c)), \ - (I[687] = (T)(img)(_p10##x,_n7##y,z,c)), \ - (I[718] = (T)(img)(_p10##x,_n8##y,z,c)), \ - (I[749] = (T)(img)(_p10##x,_n9##y,z,c)), \ - (I[780] = (T)(img)(_p10##x,_n10##y,z,c)), \ - (I[811] = (T)(img)(_p10##x,_n11##y,z,c)), \ - (I[842] = (T)(img)(_p10##x,_n12##y,z,c)), \ - (I[873] = (T)(img)(_p10##x,_n13##y,z,c)), \ - (I[904] = (T)(img)(_p10##x,_n14##y,z,c)), \ - (I[935] = (T)(img)(_p10##x,_n15##y,z,c)), \ - (I[6] = (T)(img)(_p9##x,_p15##y,z,c)), \ - (I[37] = (T)(img)(_p9##x,_p14##y,z,c)), \ - (I[68] = (T)(img)(_p9##x,_p13##y,z,c)), \ - (I[99] = (T)(img)(_p9##x,_p12##y,z,c)), \ - (I[130] = (T)(img)(_p9##x,_p11##y,z,c)), \ - (I[161] = (T)(img)(_p9##x,_p10##y,z,c)), \ - (I[192] = (T)(img)(_p9##x,_p9##y,z,c)), \ - (I[223] = (T)(img)(_p9##x,_p8##y,z,c)), \ - (I[254] = (T)(img)(_p9##x,_p7##y,z,c)), \ - (I[285] = (T)(img)(_p9##x,_p6##y,z,c)), \ - (I[316] = (T)(img)(_p9##x,_p5##y,z,c)), \ - (I[347] = (T)(img)(_p9##x,_p4##y,z,c)), \ - (I[378] = (T)(img)(_p9##x,_p3##y,z,c)), \ - (I[409] = (T)(img)(_p9##x,_p2##y,z,c)), \ - (I[440] = (T)(img)(_p9##x,_p1##y,z,c)), \ - (I[471] = (T)(img)(_p9##x,y,z,c)), \ - (I[502] = (T)(img)(_p9##x,_n1##y,z,c)), \ - (I[533] = (T)(img)(_p9##x,_n2##y,z,c)), \ - (I[564] = (T)(img)(_p9##x,_n3##y,z,c)), \ - (I[595] = (T)(img)(_p9##x,_n4##y,z,c)), \ - (I[626] = (T)(img)(_p9##x,_n5##y,z,c)), \ - (I[657] = (T)(img)(_p9##x,_n6##y,z,c)), \ - (I[688] = (T)(img)(_p9##x,_n7##y,z,c)), \ - (I[719] = (T)(img)(_p9##x,_n8##y,z,c)), \ - (I[750] = (T)(img)(_p9##x,_n9##y,z,c)), \ - (I[781] = (T)(img)(_p9##x,_n10##y,z,c)), \ - (I[812] = (T)(img)(_p9##x,_n11##y,z,c)), \ - (I[843] = (T)(img)(_p9##x,_n12##y,z,c)), \ - (I[874] = (T)(img)(_p9##x,_n13##y,z,c)), \ - (I[905] = (T)(img)(_p9##x,_n14##y,z,c)), \ - (I[936] = (T)(img)(_p9##x,_n15##y,z,c)), \ - (I[7] = (T)(img)(_p8##x,_p15##y,z,c)), \ - (I[38] = (T)(img)(_p8##x,_p14##y,z,c)), \ - (I[69] = (T)(img)(_p8##x,_p13##y,z,c)), \ - (I[100] = (T)(img)(_p8##x,_p12##y,z,c)), \ - (I[131] = (T)(img)(_p8##x,_p11##y,z,c)), \ - (I[162] = (T)(img)(_p8##x,_p10##y,z,c)), \ - (I[193] = (T)(img)(_p8##x,_p9##y,z,c)), \ - (I[224] = (T)(img)(_p8##x,_p8##y,z,c)), \ - (I[255] = (T)(img)(_p8##x,_p7##y,z,c)), \ - (I[286] = (T)(img)(_p8##x,_p6##y,z,c)), \ - (I[317] = (T)(img)(_p8##x,_p5##y,z,c)), \ - (I[348] = (T)(img)(_p8##x,_p4##y,z,c)), \ - (I[379] = (T)(img)(_p8##x,_p3##y,z,c)), \ - (I[410] = (T)(img)(_p8##x,_p2##y,z,c)), \ - (I[441] = (T)(img)(_p8##x,_p1##y,z,c)), \ - (I[472] = (T)(img)(_p8##x,y,z,c)), \ - (I[503] = (T)(img)(_p8##x,_n1##y,z,c)), \ - (I[534] = (T)(img)(_p8##x,_n2##y,z,c)), \ - (I[565] = (T)(img)(_p8##x,_n3##y,z,c)), \ - (I[596] = (T)(img)(_p8##x,_n4##y,z,c)), \ - (I[627] = (T)(img)(_p8##x,_n5##y,z,c)), \ - (I[658] = (T)(img)(_p8##x,_n6##y,z,c)), \ - (I[689] = (T)(img)(_p8##x,_n7##y,z,c)), \ - (I[720] = (T)(img)(_p8##x,_n8##y,z,c)), \ - (I[751] = (T)(img)(_p8##x,_n9##y,z,c)), \ - (I[782] = (T)(img)(_p8##x,_n10##y,z,c)), \ - (I[813] = (T)(img)(_p8##x,_n11##y,z,c)), \ - (I[844] = (T)(img)(_p8##x,_n12##y,z,c)), \ - (I[875] = (T)(img)(_p8##x,_n13##y,z,c)), \ - (I[906] = (T)(img)(_p8##x,_n14##y,z,c)), \ - (I[937] = (T)(img)(_p8##x,_n15##y,z,c)), \ - (I[8] = (T)(img)(_p7##x,_p15##y,z,c)), \ - (I[39] = (T)(img)(_p7##x,_p14##y,z,c)), \ - (I[70] = (T)(img)(_p7##x,_p13##y,z,c)), \ - (I[101] = (T)(img)(_p7##x,_p12##y,z,c)), \ - (I[132] = (T)(img)(_p7##x,_p11##y,z,c)), \ - (I[163] = (T)(img)(_p7##x,_p10##y,z,c)), \ - (I[194] = (T)(img)(_p7##x,_p9##y,z,c)), \ - (I[225] = (T)(img)(_p7##x,_p8##y,z,c)), \ - (I[256] = (T)(img)(_p7##x,_p7##y,z,c)), \ - (I[287] = (T)(img)(_p7##x,_p6##y,z,c)), \ - (I[318] = (T)(img)(_p7##x,_p5##y,z,c)), \ - (I[349] = (T)(img)(_p7##x,_p4##y,z,c)), \ - (I[380] = (T)(img)(_p7##x,_p3##y,z,c)), \ - (I[411] = (T)(img)(_p7##x,_p2##y,z,c)), \ - (I[442] = (T)(img)(_p7##x,_p1##y,z,c)), \ - (I[473] = (T)(img)(_p7##x,y,z,c)), \ - (I[504] = (T)(img)(_p7##x,_n1##y,z,c)), \ - (I[535] = (T)(img)(_p7##x,_n2##y,z,c)), \ - (I[566] = (T)(img)(_p7##x,_n3##y,z,c)), \ - (I[597] = (T)(img)(_p7##x,_n4##y,z,c)), \ - (I[628] = (T)(img)(_p7##x,_n5##y,z,c)), \ - (I[659] = (T)(img)(_p7##x,_n6##y,z,c)), \ - (I[690] = (T)(img)(_p7##x,_n7##y,z,c)), \ - (I[721] = (T)(img)(_p7##x,_n8##y,z,c)), \ - (I[752] = (T)(img)(_p7##x,_n9##y,z,c)), \ - (I[783] = (T)(img)(_p7##x,_n10##y,z,c)), \ - (I[814] = (T)(img)(_p7##x,_n11##y,z,c)), \ - (I[845] = (T)(img)(_p7##x,_n12##y,z,c)), \ - (I[876] = (T)(img)(_p7##x,_n13##y,z,c)), \ - (I[907] = (T)(img)(_p7##x,_n14##y,z,c)), \ - (I[938] = (T)(img)(_p7##x,_n15##y,z,c)), \ - (I[9] = (T)(img)(_p6##x,_p15##y,z,c)), \ - (I[40] = (T)(img)(_p6##x,_p14##y,z,c)), \ - (I[71] = (T)(img)(_p6##x,_p13##y,z,c)), \ - (I[102] = (T)(img)(_p6##x,_p12##y,z,c)), \ - (I[133] = (T)(img)(_p6##x,_p11##y,z,c)), \ - (I[164] = (T)(img)(_p6##x,_p10##y,z,c)), \ - (I[195] = (T)(img)(_p6##x,_p9##y,z,c)), \ - (I[226] = (T)(img)(_p6##x,_p8##y,z,c)), \ - (I[257] = (T)(img)(_p6##x,_p7##y,z,c)), \ - (I[288] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[319] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[350] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[381] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[412] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[443] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[474] = (T)(img)(_p6##x,y,z,c)), \ - (I[505] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[536] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[567] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[598] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[629] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[660] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[691] = (T)(img)(_p6##x,_n7##y,z,c)), \ - (I[722] = (T)(img)(_p6##x,_n8##y,z,c)), \ - (I[753] = (T)(img)(_p6##x,_n9##y,z,c)), \ - (I[784] = (T)(img)(_p6##x,_n10##y,z,c)), \ - (I[815] = (T)(img)(_p6##x,_n11##y,z,c)), \ - (I[846] = (T)(img)(_p6##x,_n12##y,z,c)), \ - (I[877] = (T)(img)(_p6##x,_n13##y,z,c)), \ - (I[908] = (T)(img)(_p6##x,_n14##y,z,c)), \ - (I[939] = (T)(img)(_p6##x,_n15##y,z,c)), \ - (I[10] = (T)(img)(_p5##x,_p15##y,z,c)), \ - (I[41] = (T)(img)(_p5##x,_p14##y,z,c)), \ - (I[72] = (T)(img)(_p5##x,_p13##y,z,c)), \ - (I[103] = (T)(img)(_p5##x,_p12##y,z,c)), \ - (I[134] = (T)(img)(_p5##x,_p11##y,z,c)), \ - (I[165] = (T)(img)(_p5##x,_p10##y,z,c)), \ - (I[196] = (T)(img)(_p5##x,_p9##y,z,c)), \ - (I[227] = (T)(img)(_p5##x,_p8##y,z,c)), \ - (I[258] = (T)(img)(_p5##x,_p7##y,z,c)), \ - (I[289] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[320] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[351] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[382] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[413] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[444] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[475] = (T)(img)(_p5##x,y,z,c)), \ - (I[506] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[537] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[568] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[599] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[630] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[661] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[692] = (T)(img)(_p5##x,_n7##y,z,c)), \ - (I[723] = (T)(img)(_p5##x,_n8##y,z,c)), \ - (I[754] = (T)(img)(_p5##x,_n9##y,z,c)), \ - (I[785] = (T)(img)(_p5##x,_n10##y,z,c)), \ - (I[816] = (T)(img)(_p5##x,_n11##y,z,c)), \ - (I[847] = (T)(img)(_p5##x,_n12##y,z,c)), \ - (I[878] = (T)(img)(_p5##x,_n13##y,z,c)), \ - (I[909] = (T)(img)(_p5##x,_n14##y,z,c)), \ - (I[940] = (T)(img)(_p5##x,_n15##y,z,c)), \ - (I[11] = (T)(img)(_p4##x,_p15##y,z,c)), \ - (I[42] = (T)(img)(_p4##x,_p14##y,z,c)), \ - (I[73] = (T)(img)(_p4##x,_p13##y,z,c)), \ - (I[104] = (T)(img)(_p4##x,_p12##y,z,c)), \ - (I[135] = (T)(img)(_p4##x,_p11##y,z,c)), \ - (I[166] = (T)(img)(_p4##x,_p10##y,z,c)), \ - (I[197] = (T)(img)(_p4##x,_p9##y,z,c)), \ - (I[228] = (T)(img)(_p4##x,_p8##y,z,c)), \ - (I[259] = (T)(img)(_p4##x,_p7##y,z,c)), \ - (I[290] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[321] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[352] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[383] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[414] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[445] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[476] = (T)(img)(_p4##x,y,z,c)), \ - (I[507] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[538] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[569] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[600] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[631] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[662] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[693] = (T)(img)(_p4##x,_n7##y,z,c)), \ - (I[724] = (T)(img)(_p4##x,_n8##y,z,c)), \ - (I[755] = (T)(img)(_p4##x,_n9##y,z,c)), \ - (I[786] = (T)(img)(_p4##x,_n10##y,z,c)), \ - (I[817] = (T)(img)(_p4##x,_n11##y,z,c)), \ - (I[848] = (T)(img)(_p4##x,_n12##y,z,c)), \ - (I[879] = (T)(img)(_p4##x,_n13##y,z,c)), \ - (I[910] = (T)(img)(_p4##x,_n14##y,z,c)), \ - (I[941] = (T)(img)(_p4##x,_n15##y,z,c)), \ - (I[12] = (T)(img)(_p3##x,_p15##y,z,c)), \ - (I[43] = (T)(img)(_p3##x,_p14##y,z,c)), \ - (I[74] = (T)(img)(_p3##x,_p13##y,z,c)), \ - (I[105] = (T)(img)(_p3##x,_p12##y,z,c)), \ - (I[136] = (T)(img)(_p3##x,_p11##y,z,c)), \ - (I[167] = (T)(img)(_p3##x,_p10##y,z,c)), \ - (I[198] = (T)(img)(_p3##x,_p9##y,z,c)), \ - (I[229] = (T)(img)(_p3##x,_p8##y,z,c)), \ - (I[260] = (T)(img)(_p3##x,_p7##y,z,c)), \ - (I[291] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[322] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[353] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[384] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[415] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[446] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[477] = (T)(img)(_p3##x,y,z,c)), \ - (I[508] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[539] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[570] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[601] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[632] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[663] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[694] = (T)(img)(_p3##x,_n7##y,z,c)), \ - (I[725] = (T)(img)(_p3##x,_n8##y,z,c)), \ - (I[756] = (T)(img)(_p3##x,_n9##y,z,c)), \ - (I[787] = (T)(img)(_p3##x,_n10##y,z,c)), \ - (I[818] = (T)(img)(_p3##x,_n11##y,z,c)), \ - (I[849] = (T)(img)(_p3##x,_n12##y,z,c)), \ - (I[880] = (T)(img)(_p3##x,_n13##y,z,c)), \ - (I[911] = (T)(img)(_p3##x,_n14##y,z,c)), \ - (I[942] = (T)(img)(_p3##x,_n15##y,z,c)), \ - (I[13] = (T)(img)(_p2##x,_p15##y,z,c)), \ - (I[44] = (T)(img)(_p2##x,_p14##y,z,c)), \ - (I[75] = (T)(img)(_p2##x,_p13##y,z,c)), \ - (I[106] = (T)(img)(_p2##x,_p12##y,z,c)), \ - (I[137] = (T)(img)(_p2##x,_p11##y,z,c)), \ - (I[168] = (T)(img)(_p2##x,_p10##y,z,c)), \ - (I[199] = (T)(img)(_p2##x,_p9##y,z,c)), \ - (I[230] = (T)(img)(_p2##x,_p8##y,z,c)), \ - (I[261] = (T)(img)(_p2##x,_p7##y,z,c)), \ - (I[292] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[323] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[354] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[385] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[416] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[447] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[478] = (T)(img)(_p2##x,y,z,c)), \ - (I[509] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[540] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[571] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[602] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[633] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[664] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[695] = (T)(img)(_p2##x,_n7##y,z,c)), \ - (I[726] = (T)(img)(_p2##x,_n8##y,z,c)), \ - (I[757] = (T)(img)(_p2##x,_n9##y,z,c)), \ - (I[788] = (T)(img)(_p2##x,_n10##y,z,c)), \ - (I[819] = (T)(img)(_p2##x,_n11##y,z,c)), \ - (I[850] = (T)(img)(_p2##x,_n12##y,z,c)), \ - (I[881] = (T)(img)(_p2##x,_n13##y,z,c)), \ - (I[912] = (T)(img)(_p2##x,_n14##y,z,c)), \ - (I[943] = (T)(img)(_p2##x,_n15##y,z,c)), \ - (I[14] = (T)(img)(_p1##x,_p15##y,z,c)), \ - (I[45] = (T)(img)(_p1##x,_p14##y,z,c)), \ - (I[76] = (T)(img)(_p1##x,_p13##y,z,c)), \ - (I[107] = (T)(img)(_p1##x,_p12##y,z,c)), \ - (I[138] = (T)(img)(_p1##x,_p11##y,z,c)), \ - (I[169] = (T)(img)(_p1##x,_p10##y,z,c)), \ - (I[200] = (T)(img)(_p1##x,_p9##y,z,c)), \ - (I[231] = (T)(img)(_p1##x,_p8##y,z,c)), \ - (I[262] = (T)(img)(_p1##x,_p7##y,z,c)), \ - (I[293] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[324] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[355] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[386] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[417] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[448] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[479] = (T)(img)(_p1##x,y,z,c)), \ - (I[510] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[541] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[572] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[603] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[634] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[665] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[696] = (T)(img)(_p1##x,_n7##y,z,c)), \ - (I[727] = (T)(img)(_p1##x,_n8##y,z,c)), \ - (I[758] = (T)(img)(_p1##x,_n9##y,z,c)), \ - (I[789] = (T)(img)(_p1##x,_n10##y,z,c)), \ - (I[820] = (T)(img)(_p1##x,_n11##y,z,c)), \ - (I[851] = (T)(img)(_p1##x,_n12##y,z,c)), \ - (I[882] = (T)(img)(_p1##x,_n13##y,z,c)), \ - (I[913] = (T)(img)(_p1##x,_n14##y,z,c)), \ - (I[944] = (T)(img)(_p1##x,_n15##y,z,c)), \ - (I[15] = (T)(img)(x,_p15##y,z,c)), \ - (I[46] = (T)(img)(x,_p14##y,z,c)), \ - (I[77] = (T)(img)(x,_p13##y,z,c)), \ - (I[108] = (T)(img)(x,_p12##y,z,c)), \ - (I[139] = (T)(img)(x,_p11##y,z,c)), \ - (I[170] = (T)(img)(x,_p10##y,z,c)), \ - (I[201] = (T)(img)(x,_p9##y,z,c)), \ - (I[232] = (T)(img)(x,_p8##y,z,c)), \ - (I[263] = (T)(img)(x,_p7##y,z,c)), \ - (I[294] = (T)(img)(x,_p6##y,z,c)), \ - (I[325] = (T)(img)(x,_p5##y,z,c)), \ - (I[356] = (T)(img)(x,_p4##y,z,c)), \ - (I[387] = (T)(img)(x,_p3##y,z,c)), \ - (I[418] = (T)(img)(x,_p2##y,z,c)), \ - (I[449] = (T)(img)(x,_p1##y,z,c)), \ - (I[480] = (T)(img)(x,y,z,c)), \ - (I[511] = (T)(img)(x,_n1##y,z,c)), \ - (I[542] = (T)(img)(x,_n2##y,z,c)), \ - (I[573] = (T)(img)(x,_n3##y,z,c)), \ - (I[604] = (T)(img)(x,_n4##y,z,c)), \ - (I[635] = (T)(img)(x,_n5##y,z,c)), \ - (I[666] = (T)(img)(x,_n6##y,z,c)), \ - (I[697] = (T)(img)(x,_n7##y,z,c)), \ - (I[728] = (T)(img)(x,_n8##y,z,c)), \ - (I[759] = (T)(img)(x,_n9##y,z,c)), \ - (I[790] = (T)(img)(x,_n10##y,z,c)), \ - (I[821] = (T)(img)(x,_n11##y,z,c)), \ - (I[852] = (T)(img)(x,_n12##y,z,c)), \ - (I[883] = (T)(img)(x,_n13##y,z,c)), \ - (I[914] = (T)(img)(x,_n14##y,z,c)), \ - (I[945] = (T)(img)(x,_n15##y,z,c)), \ - (I[16] = (T)(img)(_n1##x,_p15##y,z,c)), \ - (I[47] = (T)(img)(_n1##x,_p14##y,z,c)), \ - (I[78] = (T)(img)(_n1##x,_p13##y,z,c)), \ - (I[109] = (T)(img)(_n1##x,_p12##y,z,c)), \ - (I[140] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[171] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[202] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[233] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[264] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[295] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[326] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[357] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[388] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[419] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[450] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[481] = (T)(img)(_n1##x,y,z,c)), \ - (I[512] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[543] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[574] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[605] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[636] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[667] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[698] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[729] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[760] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[791] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[822] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[853] = (T)(img)(_n1##x,_n12##y,z,c)), \ - (I[884] = (T)(img)(_n1##x,_n13##y,z,c)), \ - (I[915] = (T)(img)(_n1##x,_n14##y,z,c)), \ - (I[946] = (T)(img)(_n1##x,_n15##y,z,c)), \ - (I[17] = (T)(img)(_n2##x,_p15##y,z,c)), \ - (I[48] = (T)(img)(_n2##x,_p14##y,z,c)), \ - (I[79] = (T)(img)(_n2##x,_p13##y,z,c)), \ - (I[110] = (T)(img)(_n2##x,_p12##y,z,c)), \ - (I[141] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[172] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[203] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[234] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[265] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[296] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[327] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[358] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[389] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[420] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[451] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[482] = (T)(img)(_n2##x,y,z,c)), \ - (I[513] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[544] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[575] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[606] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[637] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[668] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[699] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[730] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[761] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[792] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[823] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[854] = (T)(img)(_n2##x,_n12##y,z,c)), \ - (I[885] = (T)(img)(_n2##x,_n13##y,z,c)), \ - (I[916] = (T)(img)(_n2##x,_n14##y,z,c)), \ - (I[947] = (T)(img)(_n2##x,_n15##y,z,c)), \ - (I[18] = (T)(img)(_n3##x,_p15##y,z,c)), \ - (I[49] = (T)(img)(_n3##x,_p14##y,z,c)), \ - (I[80] = (T)(img)(_n3##x,_p13##y,z,c)), \ - (I[111] = (T)(img)(_n3##x,_p12##y,z,c)), \ - (I[142] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[173] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[204] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[235] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[266] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[297] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[328] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[359] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[390] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[421] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[452] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[483] = (T)(img)(_n3##x,y,z,c)), \ - (I[514] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[545] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[576] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[607] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[638] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[669] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[700] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[731] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[762] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[793] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[824] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[855] = (T)(img)(_n3##x,_n12##y,z,c)), \ - (I[886] = (T)(img)(_n3##x,_n13##y,z,c)), \ - (I[917] = (T)(img)(_n3##x,_n14##y,z,c)), \ - (I[948] = (T)(img)(_n3##x,_n15##y,z,c)), \ - (I[19] = (T)(img)(_n4##x,_p15##y,z,c)), \ - (I[50] = (T)(img)(_n4##x,_p14##y,z,c)), \ - (I[81] = (T)(img)(_n4##x,_p13##y,z,c)), \ - (I[112] = (T)(img)(_n4##x,_p12##y,z,c)), \ - (I[143] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[174] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[205] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[236] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[267] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[298] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[329] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[360] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[391] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[422] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[453] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[484] = (T)(img)(_n4##x,y,z,c)), \ - (I[515] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[546] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[577] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[608] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[639] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[670] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[701] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[732] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[763] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[794] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[825] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[856] = (T)(img)(_n4##x,_n12##y,z,c)), \ - (I[887] = (T)(img)(_n4##x,_n13##y,z,c)), \ - (I[918] = (T)(img)(_n4##x,_n14##y,z,c)), \ - (I[949] = (T)(img)(_n4##x,_n15##y,z,c)), \ - (I[20] = (T)(img)(_n5##x,_p15##y,z,c)), \ - (I[51] = (T)(img)(_n5##x,_p14##y,z,c)), \ - (I[82] = (T)(img)(_n5##x,_p13##y,z,c)), \ - (I[113] = (T)(img)(_n5##x,_p12##y,z,c)), \ - (I[144] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[175] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[206] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[237] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[268] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[299] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[330] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[361] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[392] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[423] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[454] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[485] = (T)(img)(_n5##x,y,z,c)), \ - (I[516] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[547] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[578] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[609] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[640] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[671] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[702] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[733] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[764] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[795] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[826] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[857] = (T)(img)(_n5##x,_n12##y,z,c)), \ - (I[888] = (T)(img)(_n5##x,_n13##y,z,c)), \ - (I[919] = (T)(img)(_n5##x,_n14##y,z,c)), \ - (I[950] = (T)(img)(_n5##x,_n15##y,z,c)), \ - (I[21] = (T)(img)(_n6##x,_p15##y,z,c)), \ - (I[52] = (T)(img)(_n6##x,_p14##y,z,c)), \ - (I[83] = (T)(img)(_n6##x,_p13##y,z,c)), \ - (I[114] = (T)(img)(_n6##x,_p12##y,z,c)), \ - (I[145] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[176] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[207] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[238] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[269] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[300] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[331] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[362] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[393] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[424] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[455] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[486] = (T)(img)(_n6##x,y,z,c)), \ - (I[517] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[548] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[579] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[610] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[641] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[672] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[703] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[734] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[765] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[796] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[827] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[858] = (T)(img)(_n6##x,_n12##y,z,c)), \ - (I[889] = (T)(img)(_n6##x,_n13##y,z,c)), \ - (I[920] = (T)(img)(_n6##x,_n14##y,z,c)), \ - (I[951] = (T)(img)(_n6##x,_n15##y,z,c)), \ - (I[22] = (T)(img)(_n7##x,_p15##y,z,c)), \ - (I[53] = (T)(img)(_n7##x,_p14##y,z,c)), \ - (I[84] = (T)(img)(_n7##x,_p13##y,z,c)), \ - (I[115] = (T)(img)(_n7##x,_p12##y,z,c)), \ - (I[146] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[177] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[208] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[239] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[270] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[301] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[332] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[363] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[394] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[425] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[456] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[487] = (T)(img)(_n7##x,y,z,c)), \ - (I[518] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[549] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[580] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[611] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[642] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[673] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[704] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[735] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[766] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[797] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[828] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[859] = (T)(img)(_n7##x,_n12##y,z,c)), \ - (I[890] = (T)(img)(_n7##x,_n13##y,z,c)), \ - (I[921] = (T)(img)(_n7##x,_n14##y,z,c)), \ - (I[952] = (T)(img)(_n7##x,_n15##y,z,c)), \ - (I[23] = (T)(img)(_n8##x,_p15##y,z,c)), \ - (I[54] = (T)(img)(_n8##x,_p14##y,z,c)), \ - (I[85] = (T)(img)(_n8##x,_p13##y,z,c)), \ - (I[116] = (T)(img)(_n8##x,_p12##y,z,c)), \ - (I[147] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[178] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[209] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[240] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[271] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[302] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[333] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[364] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[395] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[426] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[457] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[488] = (T)(img)(_n8##x,y,z,c)), \ - (I[519] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[550] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[581] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[612] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[643] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[674] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[705] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[736] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[767] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[798] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[829] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[860] = (T)(img)(_n8##x,_n12##y,z,c)), \ - (I[891] = (T)(img)(_n8##x,_n13##y,z,c)), \ - (I[922] = (T)(img)(_n8##x,_n14##y,z,c)), \ - (I[953] = (T)(img)(_n8##x,_n15##y,z,c)), \ - (I[24] = (T)(img)(_n9##x,_p15##y,z,c)), \ - (I[55] = (T)(img)(_n9##x,_p14##y,z,c)), \ - (I[86] = (T)(img)(_n9##x,_p13##y,z,c)), \ - (I[117] = (T)(img)(_n9##x,_p12##y,z,c)), \ - (I[148] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[179] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[210] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[241] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[272] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[303] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[334] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[365] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[396] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[427] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[458] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[489] = (T)(img)(_n9##x,y,z,c)), \ - (I[520] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[551] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[582] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[613] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[644] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[675] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[706] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[737] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[768] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[799] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[830] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[861] = (T)(img)(_n9##x,_n12##y,z,c)), \ - (I[892] = (T)(img)(_n9##x,_n13##y,z,c)), \ - (I[923] = (T)(img)(_n9##x,_n14##y,z,c)), \ - (I[954] = (T)(img)(_n9##x,_n15##y,z,c)), \ - (I[25] = (T)(img)(_n10##x,_p15##y,z,c)), \ - (I[56] = (T)(img)(_n10##x,_p14##y,z,c)), \ - (I[87] = (T)(img)(_n10##x,_p13##y,z,c)), \ - (I[118] = (T)(img)(_n10##x,_p12##y,z,c)), \ - (I[149] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[180] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[211] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[242] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[273] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[304] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[335] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[366] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[397] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[428] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[459] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[490] = (T)(img)(_n10##x,y,z,c)), \ - (I[521] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[552] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[583] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[614] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[645] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[676] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[707] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[738] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[769] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[800] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[831] = (T)(img)(_n10##x,_n11##y,z,c)), \ - (I[862] = (T)(img)(_n10##x,_n12##y,z,c)), \ - (I[893] = (T)(img)(_n10##x,_n13##y,z,c)), \ - (I[924] = (T)(img)(_n10##x,_n14##y,z,c)), \ - (I[955] = (T)(img)(_n10##x,_n15##y,z,c)), \ - (I[26] = (T)(img)(_n11##x,_p15##y,z,c)), \ - (I[57] = (T)(img)(_n11##x,_p14##y,z,c)), \ - (I[88] = (T)(img)(_n11##x,_p13##y,z,c)), \ - (I[119] = (T)(img)(_n11##x,_p12##y,z,c)), \ - (I[150] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[181] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[212] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[243] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[274] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[305] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[336] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[367] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[398] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[429] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[460] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[491] = (T)(img)(_n11##x,y,z,c)), \ - (I[522] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[553] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[584] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[615] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[646] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[677] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[708] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[739] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[770] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[801] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[832] = (T)(img)(_n11##x,_n11##y,z,c)), \ - (I[863] = (T)(img)(_n11##x,_n12##y,z,c)), \ - (I[894] = (T)(img)(_n11##x,_n13##y,z,c)), \ - (I[925] = (T)(img)(_n11##x,_n14##y,z,c)), \ - (I[956] = (T)(img)(_n11##x,_n15##y,z,c)), \ - (I[27] = (T)(img)(_n12##x,_p15##y,z,c)), \ - (I[58] = (T)(img)(_n12##x,_p14##y,z,c)), \ - (I[89] = (T)(img)(_n12##x,_p13##y,z,c)), \ - (I[120] = (T)(img)(_n12##x,_p12##y,z,c)), \ - (I[151] = (T)(img)(_n12##x,_p11##y,z,c)), \ - (I[182] = (T)(img)(_n12##x,_p10##y,z,c)), \ - (I[213] = (T)(img)(_n12##x,_p9##y,z,c)), \ - (I[244] = (T)(img)(_n12##x,_p8##y,z,c)), \ - (I[275] = (T)(img)(_n12##x,_p7##y,z,c)), \ - (I[306] = (T)(img)(_n12##x,_p6##y,z,c)), \ - (I[337] = (T)(img)(_n12##x,_p5##y,z,c)), \ - (I[368] = (T)(img)(_n12##x,_p4##y,z,c)), \ - (I[399] = (T)(img)(_n12##x,_p3##y,z,c)), \ - (I[430] = (T)(img)(_n12##x,_p2##y,z,c)), \ - (I[461] = (T)(img)(_n12##x,_p1##y,z,c)), \ - (I[492] = (T)(img)(_n12##x,y,z,c)), \ - (I[523] = (T)(img)(_n12##x,_n1##y,z,c)), \ - (I[554] = (T)(img)(_n12##x,_n2##y,z,c)), \ - (I[585] = (T)(img)(_n12##x,_n3##y,z,c)), \ - (I[616] = (T)(img)(_n12##x,_n4##y,z,c)), \ - (I[647] = (T)(img)(_n12##x,_n5##y,z,c)), \ - (I[678] = (T)(img)(_n12##x,_n6##y,z,c)), \ - (I[709] = (T)(img)(_n12##x,_n7##y,z,c)), \ - (I[740] = (T)(img)(_n12##x,_n8##y,z,c)), \ - (I[771] = (T)(img)(_n12##x,_n9##y,z,c)), \ - (I[802] = (T)(img)(_n12##x,_n10##y,z,c)), \ - (I[833] = (T)(img)(_n12##x,_n11##y,z,c)), \ - (I[864] = (T)(img)(_n12##x,_n12##y,z,c)), \ - (I[895] = (T)(img)(_n12##x,_n13##y,z,c)), \ - (I[926] = (T)(img)(_n12##x,_n14##y,z,c)), \ - (I[957] = (T)(img)(_n12##x,_n15##y,z,c)), \ - (I[28] = (T)(img)(_n13##x,_p15##y,z,c)), \ - (I[59] = (T)(img)(_n13##x,_p14##y,z,c)), \ - (I[90] = (T)(img)(_n13##x,_p13##y,z,c)), \ - (I[121] = (T)(img)(_n13##x,_p12##y,z,c)), \ - (I[152] = (T)(img)(_n13##x,_p11##y,z,c)), \ - (I[183] = (T)(img)(_n13##x,_p10##y,z,c)), \ - (I[214] = (T)(img)(_n13##x,_p9##y,z,c)), \ - (I[245] = (T)(img)(_n13##x,_p8##y,z,c)), \ - (I[276] = (T)(img)(_n13##x,_p7##y,z,c)), \ - (I[307] = (T)(img)(_n13##x,_p6##y,z,c)), \ - (I[338] = (T)(img)(_n13##x,_p5##y,z,c)), \ - (I[369] = (T)(img)(_n13##x,_p4##y,z,c)), \ - (I[400] = (T)(img)(_n13##x,_p3##y,z,c)), \ - (I[431] = (T)(img)(_n13##x,_p2##y,z,c)), \ - (I[462] = (T)(img)(_n13##x,_p1##y,z,c)), \ - (I[493] = (T)(img)(_n13##x,y,z,c)), \ - (I[524] = (T)(img)(_n13##x,_n1##y,z,c)), \ - (I[555] = (T)(img)(_n13##x,_n2##y,z,c)), \ - (I[586] = (T)(img)(_n13##x,_n3##y,z,c)), \ - (I[617] = (T)(img)(_n13##x,_n4##y,z,c)), \ - (I[648] = (T)(img)(_n13##x,_n5##y,z,c)), \ - (I[679] = (T)(img)(_n13##x,_n6##y,z,c)), \ - (I[710] = (T)(img)(_n13##x,_n7##y,z,c)), \ - (I[741] = (T)(img)(_n13##x,_n8##y,z,c)), \ - (I[772] = (T)(img)(_n13##x,_n9##y,z,c)), \ - (I[803] = (T)(img)(_n13##x,_n10##y,z,c)), \ - (I[834] = (T)(img)(_n13##x,_n11##y,z,c)), \ - (I[865] = (T)(img)(_n13##x,_n12##y,z,c)), \ - (I[896] = (T)(img)(_n13##x,_n13##y,z,c)), \ - (I[927] = (T)(img)(_n13##x,_n14##y,z,c)), \ - (I[958] = (T)(img)(_n13##x,_n15##y,z,c)), \ - (I[29] = (T)(img)(_n14##x,_p15##y,z,c)), \ - (I[60] = (T)(img)(_n14##x,_p14##y,z,c)), \ - (I[91] = (T)(img)(_n14##x,_p13##y,z,c)), \ - (I[122] = (T)(img)(_n14##x,_p12##y,z,c)), \ - (I[153] = (T)(img)(_n14##x,_p11##y,z,c)), \ - (I[184] = (T)(img)(_n14##x,_p10##y,z,c)), \ - (I[215] = (T)(img)(_n14##x,_p9##y,z,c)), \ - (I[246] = (T)(img)(_n14##x,_p8##y,z,c)), \ - (I[277] = (T)(img)(_n14##x,_p7##y,z,c)), \ - (I[308] = (T)(img)(_n14##x,_p6##y,z,c)), \ - (I[339] = (T)(img)(_n14##x,_p5##y,z,c)), \ - (I[370] = (T)(img)(_n14##x,_p4##y,z,c)), \ - (I[401] = (T)(img)(_n14##x,_p3##y,z,c)), \ - (I[432] = (T)(img)(_n14##x,_p2##y,z,c)), \ - (I[463] = (T)(img)(_n14##x,_p1##y,z,c)), \ - (I[494] = (T)(img)(_n14##x,y,z,c)), \ - (I[525] = (T)(img)(_n14##x,_n1##y,z,c)), \ - (I[556] = (T)(img)(_n14##x,_n2##y,z,c)), \ - (I[587] = (T)(img)(_n14##x,_n3##y,z,c)), \ - (I[618] = (T)(img)(_n14##x,_n4##y,z,c)), \ - (I[649] = (T)(img)(_n14##x,_n5##y,z,c)), \ - (I[680] = (T)(img)(_n14##x,_n6##y,z,c)), \ - (I[711] = (T)(img)(_n14##x,_n7##y,z,c)), \ - (I[742] = (T)(img)(_n14##x,_n8##y,z,c)), \ - (I[773] = (T)(img)(_n14##x,_n9##y,z,c)), \ - (I[804] = (T)(img)(_n14##x,_n10##y,z,c)), \ - (I[835] = (T)(img)(_n14##x,_n11##y,z,c)), \ - (I[866] = (T)(img)(_n14##x,_n12##y,z,c)), \ - (I[897] = (T)(img)(_n14##x,_n13##y,z,c)), \ - (I[928] = (T)(img)(_n14##x,_n14##y,z,c)), \ - (I[959] = (T)(img)(_n14##x,_n15##y,z,c)), \ - x + 15>=(img).width()?(img).width() - 1:x + 15); \ - x<=(int)(x1) && ((_n15##x<(img).width() && ( \ - (I[30] = (T)(img)(_n15##x,_p15##y,z,c)), \ - (I[61] = (T)(img)(_n15##x,_p14##y,z,c)), \ - (I[92] = (T)(img)(_n15##x,_p13##y,z,c)), \ - (I[123] = (T)(img)(_n15##x,_p12##y,z,c)), \ - (I[154] = (T)(img)(_n15##x,_p11##y,z,c)), \ - (I[185] = (T)(img)(_n15##x,_p10##y,z,c)), \ - (I[216] = (T)(img)(_n15##x,_p9##y,z,c)), \ - (I[247] = (T)(img)(_n15##x,_p8##y,z,c)), \ - (I[278] = (T)(img)(_n15##x,_p7##y,z,c)), \ - (I[309] = (T)(img)(_n15##x,_p6##y,z,c)), \ - (I[340] = (T)(img)(_n15##x,_p5##y,z,c)), \ - (I[371] = (T)(img)(_n15##x,_p4##y,z,c)), \ - (I[402] = (T)(img)(_n15##x,_p3##y,z,c)), \ - (I[433] = (T)(img)(_n15##x,_p2##y,z,c)), \ - (I[464] = (T)(img)(_n15##x,_p1##y,z,c)), \ - (I[495] = (T)(img)(_n15##x,y,z,c)), \ - (I[526] = (T)(img)(_n15##x,_n1##y,z,c)), \ - (I[557] = (T)(img)(_n15##x,_n2##y,z,c)), \ - (I[588] = (T)(img)(_n15##x,_n3##y,z,c)), \ - (I[619] = (T)(img)(_n15##x,_n4##y,z,c)), \ - (I[650] = (T)(img)(_n15##x,_n5##y,z,c)), \ - (I[681] = (T)(img)(_n15##x,_n6##y,z,c)), \ - (I[712] = (T)(img)(_n15##x,_n7##y,z,c)), \ - (I[743] = (T)(img)(_n15##x,_n8##y,z,c)), \ - (I[774] = (T)(img)(_n15##x,_n9##y,z,c)), \ - (I[805] = (T)(img)(_n15##x,_n10##y,z,c)), \ - (I[836] = (T)(img)(_n15##x,_n11##y,z,c)), \ - (I[867] = (T)(img)(_n15##x,_n12##y,z,c)), \ - (I[898] = (T)(img)(_n15##x,_n13##y,z,c)), \ - (I[929] = (T)(img)(_n15##x,_n14##y,z,c)), \ - (I[960] = (T)(img)(_n15##x,_n15##y,z,c)),1)) || \ - _n14##x==--_n15##x || _n13##x==--_n14##x || _n12##x==--_n13##x || _n11##x==--_n12##x || _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n15##x = _n14##x = _n13##x = _n12##x = _n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], \ - I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], \ - I[62] = I[63], I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], \ - I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], \ - I[124] = I[125], I[125] = I[126], I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], \ - I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], \ - I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], \ - I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], I[223] = I[224], I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], \ - I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], \ - I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], \ - I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], \ - I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], I[351] = I[352], I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], \ - I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], I[383] = I[384], I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], \ - I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], I[415] = I[416], I[416] = I[417], I[417] = I[418], I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], \ - I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], I[447] = I[448], I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], I[463] = I[464], \ - I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], I[479] = I[480], I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], I[493] = I[494], I[494] = I[495], \ - I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], I[503] = I[504], I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], I[511] = I[512], I[512] = I[513], I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], I[519] = I[520], I[520] = I[521], I[521] = I[522], I[522] = I[523], I[523] = I[524], I[524] = I[525], I[525] = I[526], \ - I[527] = I[528], I[528] = I[529], I[529] = I[530], I[530] = I[531], I[531] = I[532], I[532] = I[533], I[533] = I[534], I[534] = I[535], I[535] = I[536], I[536] = I[537], I[537] = I[538], I[538] = I[539], I[539] = I[540], I[540] = I[541], I[541] = I[542], I[542] = I[543], I[543] = I[544], I[544] = I[545], I[545] = I[546], I[546] = I[547], I[547] = I[548], I[548] = I[549], I[549] = I[550], I[550] = I[551], I[551] = I[552], I[552] = I[553], I[553] = I[554], I[554] = I[555], I[555] = I[556], I[556] = I[557], \ - I[558] = I[559], I[559] = I[560], I[560] = I[561], I[561] = I[562], I[562] = I[563], I[563] = I[564], I[564] = I[565], I[565] = I[566], I[566] = I[567], I[567] = I[568], I[568] = I[569], I[569] = I[570], I[570] = I[571], I[571] = I[572], I[572] = I[573], I[573] = I[574], I[574] = I[575], I[575] = I[576], I[576] = I[577], I[577] = I[578], I[578] = I[579], I[579] = I[580], I[580] = I[581], I[581] = I[582], I[582] = I[583], I[583] = I[584], I[584] = I[585], I[585] = I[586], I[586] = I[587], I[587] = I[588], \ - I[589] = I[590], I[590] = I[591], I[591] = I[592], I[592] = I[593], I[593] = I[594], I[594] = I[595], I[595] = I[596], I[596] = I[597], I[597] = I[598], I[598] = I[599], I[599] = I[600], I[600] = I[601], I[601] = I[602], I[602] = I[603], I[603] = I[604], I[604] = I[605], I[605] = I[606], I[606] = I[607], I[607] = I[608], I[608] = I[609], I[609] = I[610], I[610] = I[611], I[611] = I[612], I[612] = I[613], I[613] = I[614], I[614] = I[615], I[615] = I[616], I[616] = I[617], I[617] = I[618], I[618] = I[619], \ - I[620] = I[621], I[621] = I[622], I[622] = I[623], I[623] = I[624], I[624] = I[625], I[625] = I[626], I[626] = I[627], I[627] = I[628], I[628] = I[629], I[629] = I[630], I[630] = I[631], I[631] = I[632], I[632] = I[633], I[633] = I[634], I[634] = I[635], I[635] = I[636], I[636] = I[637], I[637] = I[638], I[638] = I[639], I[639] = I[640], I[640] = I[641], I[641] = I[642], I[642] = I[643], I[643] = I[644], I[644] = I[645], I[645] = I[646], I[646] = I[647], I[647] = I[648], I[648] = I[649], I[649] = I[650], \ - I[651] = I[652], I[652] = I[653], I[653] = I[654], I[654] = I[655], I[655] = I[656], I[656] = I[657], I[657] = I[658], I[658] = I[659], I[659] = I[660], I[660] = I[661], I[661] = I[662], I[662] = I[663], I[663] = I[664], I[664] = I[665], I[665] = I[666], I[666] = I[667], I[667] = I[668], I[668] = I[669], I[669] = I[670], I[670] = I[671], I[671] = I[672], I[672] = I[673], I[673] = I[674], I[674] = I[675], I[675] = I[676], I[676] = I[677], I[677] = I[678], I[678] = I[679], I[679] = I[680], I[680] = I[681], \ - I[682] = I[683], I[683] = I[684], I[684] = I[685], I[685] = I[686], I[686] = I[687], I[687] = I[688], I[688] = I[689], I[689] = I[690], I[690] = I[691], I[691] = I[692], I[692] = I[693], I[693] = I[694], I[694] = I[695], I[695] = I[696], I[696] = I[697], I[697] = I[698], I[698] = I[699], I[699] = I[700], I[700] = I[701], I[701] = I[702], I[702] = I[703], I[703] = I[704], I[704] = I[705], I[705] = I[706], I[706] = I[707], I[707] = I[708], I[708] = I[709], I[709] = I[710], I[710] = I[711], I[711] = I[712], \ - I[713] = I[714], I[714] = I[715], I[715] = I[716], I[716] = I[717], I[717] = I[718], I[718] = I[719], I[719] = I[720], I[720] = I[721], I[721] = I[722], I[722] = I[723], I[723] = I[724], I[724] = I[725], I[725] = I[726], I[726] = I[727], I[727] = I[728], I[728] = I[729], I[729] = I[730], I[730] = I[731], I[731] = I[732], I[732] = I[733], I[733] = I[734], I[734] = I[735], I[735] = I[736], I[736] = I[737], I[737] = I[738], I[738] = I[739], I[739] = I[740], I[740] = I[741], I[741] = I[742], I[742] = I[743], \ - I[744] = I[745], I[745] = I[746], I[746] = I[747], I[747] = I[748], I[748] = I[749], I[749] = I[750], I[750] = I[751], I[751] = I[752], I[752] = I[753], I[753] = I[754], I[754] = I[755], I[755] = I[756], I[756] = I[757], I[757] = I[758], I[758] = I[759], I[759] = I[760], I[760] = I[761], I[761] = I[762], I[762] = I[763], I[763] = I[764], I[764] = I[765], I[765] = I[766], I[766] = I[767], I[767] = I[768], I[768] = I[769], I[769] = I[770], I[770] = I[771], I[771] = I[772], I[772] = I[773], I[773] = I[774], \ - I[775] = I[776], I[776] = I[777], I[777] = I[778], I[778] = I[779], I[779] = I[780], I[780] = I[781], I[781] = I[782], I[782] = I[783], I[783] = I[784], I[784] = I[785], I[785] = I[786], I[786] = I[787], I[787] = I[788], I[788] = I[789], I[789] = I[790], I[790] = I[791], I[791] = I[792], I[792] = I[793], I[793] = I[794], I[794] = I[795], I[795] = I[796], I[796] = I[797], I[797] = I[798], I[798] = I[799], I[799] = I[800], I[800] = I[801], I[801] = I[802], I[802] = I[803], I[803] = I[804], I[804] = I[805], \ - I[806] = I[807], I[807] = I[808], I[808] = I[809], I[809] = I[810], I[810] = I[811], I[811] = I[812], I[812] = I[813], I[813] = I[814], I[814] = I[815], I[815] = I[816], I[816] = I[817], I[817] = I[818], I[818] = I[819], I[819] = I[820], I[820] = I[821], I[821] = I[822], I[822] = I[823], I[823] = I[824], I[824] = I[825], I[825] = I[826], I[826] = I[827], I[827] = I[828], I[828] = I[829], I[829] = I[830], I[830] = I[831], I[831] = I[832], I[832] = I[833], I[833] = I[834], I[834] = I[835], I[835] = I[836], \ - I[837] = I[838], I[838] = I[839], I[839] = I[840], I[840] = I[841], I[841] = I[842], I[842] = I[843], I[843] = I[844], I[844] = I[845], I[845] = I[846], I[846] = I[847], I[847] = I[848], I[848] = I[849], I[849] = I[850], I[850] = I[851], I[851] = I[852], I[852] = I[853], I[853] = I[854], I[854] = I[855], I[855] = I[856], I[856] = I[857], I[857] = I[858], I[858] = I[859], I[859] = I[860], I[860] = I[861], I[861] = I[862], I[862] = I[863], I[863] = I[864], I[864] = I[865], I[865] = I[866], I[866] = I[867], \ - I[868] = I[869], I[869] = I[870], I[870] = I[871], I[871] = I[872], I[872] = I[873], I[873] = I[874], I[874] = I[875], I[875] = I[876], I[876] = I[877], I[877] = I[878], I[878] = I[879], I[879] = I[880], I[880] = I[881], I[881] = I[882], I[882] = I[883], I[883] = I[884], I[884] = I[885], I[885] = I[886], I[886] = I[887], I[887] = I[888], I[888] = I[889], I[889] = I[890], I[890] = I[891], I[891] = I[892], I[892] = I[893], I[893] = I[894], I[894] = I[895], I[895] = I[896], I[896] = I[897], I[897] = I[898], \ - I[899] = I[900], I[900] = I[901], I[901] = I[902], I[902] = I[903], I[903] = I[904], I[904] = I[905], I[905] = I[906], I[906] = I[907], I[907] = I[908], I[908] = I[909], I[909] = I[910], I[910] = I[911], I[911] = I[912], I[912] = I[913], I[913] = I[914], I[914] = I[915], I[915] = I[916], I[916] = I[917], I[917] = I[918], I[918] = I[919], I[919] = I[920], I[920] = I[921], I[921] = I[922], I[922] = I[923], I[923] = I[924], I[924] = I[925], I[925] = I[926], I[926] = I[927], I[927] = I[928], I[928] = I[929], \ - I[930] = I[931], I[931] = I[932], I[932] = I[933], I[933] = I[934], I[934] = I[935], I[935] = I[936], I[936] = I[937], I[937] = I[938], I[938] = I[939], I[939] = I[940], I[940] = I[941], I[941] = I[942], I[942] = I[943], I[943] = I[944], I[944] = I[945], I[945] = I[946], I[946] = I[947], I[947] = I[948], I[948] = I[949], I[949] = I[950], I[950] = I[951], I[951] = I[952], I[952] = I[953], I[953] = I[954], I[954] = I[955], I[955] = I[956], I[956] = I[957], I[957] = I[958], I[958] = I[959], I[959] = I[960], \ - _p15##x = _p14##x, _p14##x = _p13##x, _p13##x = _p12##x, _p12##x = _p11##x, _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x, ++_n12##x, ++_n13##x, ++_n14##x, ++_n15##x) - -#define cimg_get31x31(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p15##x,_p15##y,z,c), I[1] = (T)(img)(_p14##x,_p15##y,z,c), I[2] = (T)(img)(_p13##x,_p15##y,z,c), I[3] = (T)(img)(_p12##x,_p15##y,z,c), I[4] = (T)(img)(_p11##x,_p15##y,z,c), I[5] = (T)(img)(_p10##x,_p15##y,z,c), I[6] = (T)(img)(_p9##x,_p15##y,z,c), I[7] = (T)(img)(_p8##x,_p15##y,z,c), I[8] = (T)(img)(_p7##x,_p15##y,z,c), I[9] = (T)(img)(_p6##x,_p15##y,z,c), I[10] = (T)(img)(_p5##x,_p15##y,z,c), I[11] = (T)(img)(_p4##x,_p15##y,z,c), I[12] = (T)(img)(_p3##x,_p15##y,z,c), I[13] = (T)(img)(_p2##x,_p15##y,z,c), I[14] = (T)(img)(_p1##x,_p15##y,z,c), I[15] = (T)(img)(x,_p15##y,z,c), I[16] = (T)(img)(_n1##x,_p15##y,z,c), I[17] = (T)(img)(_n2##x,_p15##y,z,c), I[18] = (T)(img)(_n3##x,_p15##y,z,c), I[19] = (T)(img)(_n4##x,_p15##y,z,c), I[20] = (T)(img)(_n5##x,_p15##y,z,c), I[21] = (T)(img)(_n6##x,_p15##y,z,c), I[22] = (T)(img)(_n7##x,_p15##y,z,c), I[23] = (T)(img)(_n8##x,_p15##y,z,c), I[24] = (T)(img)(_n9##x,_p15##y,z,c), I[25] = (T)(img)(_n10##x,_p15##y,z,c), I[26] = (T)(img)(_n11##x,_p15##y,z,c), I[27] = (T)(img)(_n12##x,_p15##y,z,c), I[28] = (T)(img)(_n13##x,_p15##y,z,c), I[29] = (T)(img)(_n14##x,_p15##y,z,c), I[30] = (T)(img)(_n15##x,_p15##y,z,c), \ - I[31] = (T)(img)(_p15##x,_p14##y,z,c), I[32] = (T)(img)(_p14##x,_p14##y,z,c), I[33] = (T)(img)(_p13##x,_p14##y,z,c), I[34] = (T)(img)(_p12##x,_p14##y,z,c), I[35] = (T)(img)(_p11##x,_p14##y,z,c), I[36] = (T)(img)(_p10##x,_p14##y,z,c), I[37] = (T)(img)(_p9##x,_p14##y,z,c), I[38] = (T)(img)(_p8##x,_p14##y,z,c), I[39] = (T)(img)(_p7##x,_p14##y,z,c), I[40] = (T)(img)(_p6##x,_p14##y,z,c), I[41] = (T)(img)(_p5##x,_p14##y,z,c), I[42] = (T)(img)(_p4##x,_p14##y,z,c), I[43] = (T)(img)(_p3##x,_p14##y,z,c), I[44] = (T)(img)(_p2##x,_p14##y,z,c), I[45] = (T)(img)(_p1##x,_p14##y,z,c), I[46] = (T)(img)(x,_p14##y,z,c), I[47] = (T)(img)(_n1##x,_p14##y,z,c), I[48] = (T)(img)(_n2##x,_p14##y,z,c), I[49] = (T)(img)(_n3##x,_p14##y,z,c), I[50] = (T)(img)(_n4##x,_p14##y,z,c), I[51] = (T)(img)(_n5##x,_p14##y,z,c), I[52] = (T)(img)(_n6##x,_p14##y,z,c), I[53] = (T)(img)(_n7##x,_p14##y,z,c), I[54] = (T)(img)(_n8##x,_p14##y,z,c), I[55] = (T)(img)(_n9##x,_p14##y,z,c), I[56] = (T)(img)(_n10##x,_p14##y,z,c), I[57] = (T)(img)(_n11##x,_p14##y,z,c), I[58] = (T)(img)(_n12##x,_p14##y,z,c), I[59] = (T)(img)(_n13##x,_p14##y,z,c), I[60] = (T)(img)(_n14##x,_p14##y,z,c), I[61] = (T)(img)(_n15##x,_p14##y,z,c), \ - I[62] = (T)(img)(_p15##x,_p13##y,z,c), I[63] = (T)(img)(_p14##x,_p13##y,z,c), I[64] = (T)(img)(_p13##x,_p13##y,z,c), I[65] = (T)(img)(_p12##x,_p13##y,z,c), I[66] = (T)(img)(_p11##x,_p13##y,z,c), I[67] = (T)(img)(_p10##x,_p13##y,z,c), I[68] = (T)(img)(_p9##x,_p13##y,z,c), I[69] = (T)(img)(_p8##x,_p13##y,z,c), I[70] = (T)(img)(_p7##x,_p13##y,z,c), I[71] = (T)(img)(_p6##x,_p13##y,z,c), I[72] = (T)(img)(_p5##x,_p13##y,z,c), I[73] = (T)(img)(_p4##x,_p13##y,z,c), I[74] = (T)(img)(_p3##x,_p13##y,z,c), I[75] = (T)(img)(_p2##x,_p13##y,z,c), I[76] = (T)(img)(_p1##x,_p13##y,z,c), I[77] = (T)(img)(x,_p13##y,z,c), I[78] = (T)(img)(_n1##x,_p13##y,z,c), I[79] = (T)(img)(_n2##x,_p13##y,z,c), I[80] = (T)(img)(_n3##x,_p13##y,z,c), I[81] = (T)(img)(_n4##x,_p13##y,z,c), I[82] = (T)(img)(_n5##x,_p13##y,z,c), I[83] = (T)(img)(_n6##x,_p13##y,z,c), I[84] = (T)(img)(_n7##x,_p13##y,z,c), I[85] = (T)(img)(_n8##x,_p13##y,z,c), I[86] = (T)(img)(_n9##x,_p13##y,z,c), I[87] = (T)(img)(_n10##x,_p13##y,z,c), I[88] = (T)(img)(_n11##x,_p13##y,z,c), I[89] = (T)(img)(_n12##x,_p13##y,z,c), I[90] = (T)(img)(_n13##x,_p13##y,z,c), I[91] = (T)(img)(_n14##x,_p13##y,z,c), I[92] = (T)(img)(_n15##x,_p13##y,z,c), \ - I[93] = (T)(img)(_p15##x,_p12##y,z,c), I[94] = (T)(img)(_p14##x,_p12##y,z,c), I[95] = (T)(img)(_p13##x,_p12##y,z,c), I[96] = (T)(img)(_p12##x,_p12##y,z,c), I[97] = (T)(img)(_p11##x,_p12##y,z,c), I[98] = (T)(img)(_p10##x,_p12##y,z,c), I[99] = (T)(img)(_p9##x,_p12##y,z,c), I[100] = (T)(img)(_p8##x,_p12##y,z,c), I[101] = (T)(img)(_p7##x,_p12##y,z,c), I[102] = (T)(img)(_p6##x,_p12##y,z,c), I[103] = (T)(img)(_p5##x,_p12##y,z,c), I[104] = (T)(img)(_p4##x,_p12##y,z,c), I[105] = (T)(img)(_p3##x,_p12##y,z,c), I[106] = (T)(img)(_p2##x,_p12##y,z,c), I[107] = (T)(img)(_p1##x,_p12##y,z,c), I[108] = (T)(img)(x,_p12##y,z,c), I[109] = (T)(img)(_n1##x,_p12##y,z,c), I[110] = (T)(img)(_n2##x,_p12##y,z,c), I[111] = (T)(img)(_n3##x,_p12##y,z,c), I[112] = (T)(img)(_n4##x,_p12##y,z,c), I[113] = (T)(img)(_n5##x,_p12##y,z,c), I[114] = (T)(img)(_n6##x,_p12##y,z,c), I[115] = (T)(img)(_n7##x,_p12##y,z,c), I[116] = (T)(img)(_n8##x,_p12##y,z,c), I[117] = (T)(img)(_n9##x,_p12##y,z,c), I[118] = (T)(img)(_n10##x,_p12##y,z,c), I[119] = (T)(img)(_n11##x,_p12##y,z,c), I[120] = (T)(img)(_n12##x,_p12##y,z,c), I[121] = (T)(img)(_n13##x,_p12##y,z,c), I[122] = (T)(img)(_n14##x,_p12##y,z,c), I[123] = (T)(img)(_n15##x,_p12##y,z,c), \ - I[124] = (T)(img)(_p15##x,_p11##y,z,c), I[125] = (T)(img)(_p14##x,_p11##y,z,c), I[126] = (T)(img)(_p13##x,_p11##y,z,c), I[127] = (T)(img)(_p12##x,_p11##y,z,c), I[128] = (T)(img)(_p11##x,_p11##y,z,c), I[129] = (T)(img)(_p10##x,_p11##y,z,c), I[130] = (T)(img)(_p9##x,_p11##y,z,c), I[131] = (T)(img)(_p8##x,_p11##y,z,c), I[132] = (T)(img)(_p7##x,_p11##y,z,c), I[133] = (T)(img)(_p6##x,_p11##y,z,c), I[134] = (T)(img)(_p5##x,_p11##y,z,c), I[135] = (T)(img)(_p4##x,_p11##y,z,c), I[136] = (T)(img)(_p3##x,_p11##y,z,c), I[137] = (T)(img)(_p2##x,_p11##y,z,c), I[138] = (T)(img)(_p1##x,_p11##y,z,c), I[139] = (T)(img)(x,_p11##y,z,c), I[140] = (T)(img)(_n1##x,_p11##y,z,c), I[141] = (T)(img)(_n2##x,_p11##y,z,c), I[142] = (T)(img)(_n3##x,_p11##y,z,c), I[143] = (T)(img)(_n4##x,_p11##y,z,c), I[144] = (T)(img)(_n5##x,_p11##y,z,c), I[145] = (T)(img)(_n6##x,_p11##y,z,c), I[146] = (T)(img)(_n7##x,_p11##y,z,c), I[147] = (T)(img)(_n8##x,_p11##y,z,c), I[148] = (T)(img)(_n9##x,_p11##y,z,c), I[149] = (T)(img)(_n10##x,_p11##y,z,c), I[150] = (T)(img)(_n11##x,_p11##y,z,c), I[151] = (T)(img)(_n12##x,_p11##y,z,c), I[152] = (T)(img)(_n13##x,_p11##y,z,c), I[153] = (T)(img)(_n14##x,_p11##y,z,c), I[154] = (T)(img)(_n15##x,_p11##y,z,c), \ - I[155] = (T)(img)(_p15##x,_p10##y,z,c), I[156] = (T)(img)(_p14##x,_p10##y,z,c), I[157] = (T)(img)(_p13##x,_p10##y,z,c), I[158] = (T)(img)(_p12##x,_p10##y,z,c), I[159] = (T)(img)(_p11##x,_p10##y,z,c), I[160] = (T)(img)(_p10##x,_p10##y,z,c), I[161] = (T)(img)(_p9##x,_p10##y,z,c), I[162] = (T)(img)(_p8##x,_p10##y,z,c), I[163] = (T)(img)(_p7##x,_p10##y,z,c), I[164] = (T)(img)(_p6##x,_p10##y,z,c), I[165] = (T)(img)(_p5##x,_p10##y,z,c), I[166] = (T)(img)(_p4##x,_p10##y,z,c), I[167] = (T)(img)(_p3##x,_p10##y,z,c), I[168] = (T)(img)(_p2##x,_p10##y,z,c), I[169] = (T)(img)(_p1##x,_p10##y,z,c), I[170] = (T)(img)(x,_p10##y,z,c), I[171] = (T)(img)(_n1##x,_p10##y,z,c), I[172] = (T)(img)(_n2##x,_p10##y,z,c), I[173] = (T)(img)(_n3##x,_p10##y,z,c), I[174] = (T)(img)(_n4##x,_p10##y,z,c), I[175] = (T)(img)(_n5##x,_p10##y,z,c), I[176] = (T)(img)(_n6##x,_p10##y,z,c), I[177] = (T)(img)(_n7##x,_p10##y,z,c), I[178] = (T)(img)(_n8##x,_p10##y,z,c), I[179] = (T)(img)(_n9##x,_p10##y,z,c), I[180] = (T)(img)(_n10##x,_p10##y,z,c), I[181] = (T)(img)(_n11##x,_p10##y,z,c), I[182] = (T)(img)(_n12##x,_p10##y,z,c), I[183] = (T)(img)(_n13##x,_p10##y,z,c), I[184] = (T)(img)(_n14##x,_p10##y,z,c), I[185] = (T)(img)(_n15##x,_p10##y,z,c), \ - I[186] = (T)(img)(_p15##x,_p9##y,z,c), I[187] = (T)(img)(_p14##x,_p9##y,z,c), I[188] = (T)(img)(_p13##x,_p9##y,z,c), I[189] = (T)(img)(_p12##x,_p9##y,z,c), I[190] = (T)(img)(_p11##x,_p9##y,z,c), I[191] = (T)(img)(_p10##x,_p9##y,z,c), I[192] = (T)(img)(_p9##x,_p9##y,z,c), I[193] = (T)(img)(_p8##x,_p9##y,z,c), I[194] = (T)(img)(_p7##x,_p9##y,z,c), I[195] = (T)(img)(_p6##x,_p9##y,z,c), I[196] = (T)(img)(_p5##x,_p9##y,z,c), I[197] = (T)(img)(_p4##x,_p9##y,z,c), I[198] = (T)(img)(_p3##x,_p9##y,z,c), I[199] = (T)(img)(_p2##x,_p9##y,z,c), I[200] = (T)(img)(_p1##x,_p9##y,z,c), I[201] = (T)(img)(x,_p9##y,z,c), I[202] = (T)(img)(_n1##x,_p9##y,z,c), I[203] = (T)(img)(_n2##x,_p9##y,z,c), I[204] = (T)(img)(_n3##x,_p9##y,z,c), I[205] = (T)(img)(_n4##x,_p9##y,z,c), I[206] = (T)(img)(_n5##x,_p9##y,z,c), I[207] = (T)(img)(_n6##x,_p9##y,z,c), I[208] = (T)(img)(_n7##x,_p9##y,z,c), I[209] = (T)(img)(_n8##x,_p9##y,z,c), I[210] = (T)(img)(_n9##x,_p9##y,z,c), I[211] = (T)(img)(_n10##x,_p9##y,z,c), I[212] = (T)(img)(_n11##x,_p9##y,z,c), I[213] = (T)(img)(_n12##x,_p9##y,z,c), I[214] = (T)(img)(_n13##x,_p9##y,z,c), I[215] = (T)(img)(_n14##x,_p9##y,z,c), I[216] = (T)(img)(_n15##x,_p9##y,z,c), \ - I[217] = (T)(img)(_p15##x,_p8##y,z,c), I[218] = (T)(img)(_p14##x,_p8##y,z,c), I[219] = (T)(img)(_p13##x,_p8##y,z,c), I[220] = (T)(img)(_p12##x,_p8##y,z,c), I[221] = (T)(img)(_p11##x,_p8##y,z,c), I[222] = (T)(img)(_p10##x,_p8##y,z,c), I[223] = (T)(img)(_p9##x,_p8##y,z,c), I[224] = (T)(img)(_p8##x,_p8##y,z,c), I[225] = (T)(img)(_p7##x,_p8##y,z,c), I[226] = (T)(img)(_p6##x,_p8##y,z,c), I[227] = (T)(img)(_p5##x,_p8##y,z,c), I[228] = (T)(img)(_p4##x,_p8##y,z,c), I[229] = (T)(img)(_p3##x,_p8##y,z,c), I[230] = (T)(img)(_p2##x,_p8##y,z,c), I[231] = (T)(img)(_p1##x,_p8##y,z,c), I[232] = (T)(img)(x,_p8##y,z,c), I[233] = (T)(img)(_n1##x,_p8##y,z,c), I[234] = (T)(img)(_n2##x,_p8##y,z,c), I[235] = (T)(img)(_n3##x,_p8##y,z,c), I[236] = (T)(img)(_n4##x,_p8##y,z,c), I[237] = (T)(img)(_n5##x,_p8##y,z,c), I[238] = (T)(img)(_n6##x,_p8##y,z,c), I[239] = (T)(img)(_n7##x,_p8##y,z,c), I[240] = (T)(img)(_n8##x,_p8##y,z,c), I[241] = (T)(img)(_n9##x,_p8##y,z,c), I[242] = (T)(img)(_n10##x,_p8##y,z,c), I[243] = (T)(img)(_n11##x,_p8##y,z,c), I[244] = (T)(img)(_n12##x,_p8##y,z,c), I[245] = (T)(img)(_n13##x,_p8##y,z,c), I[246] = (T)(img)(_n14##x,_p8##y,z,c), I[247] = (T)(img)(_n15##x,_p8##y,z,c), \ - I[248] = (T)(img)(_p15##x,_p7##y,z,c), I[249] = (T)(img)(_p14##x,_p7##y,z,c), I[250] = (T)(img)(_p13##x,_p7##y,z,c), I[251] = (T)(img)(_p12##x,_p7##y,z,c), I[252] = (T)(img)(_p11##x,_p7##y,z,c), I[253] = (T)(img)(_p10##x,_p7##y,z,c), I[254] = (T)(img)(_p9##x,_p7##y,z,c), I[255] = (T)(img)(_p8##x,_p7##y,z,c), I[256] = (T)(img)(_p7##x,_p7##y,z,c), I[257] = (T)(img)(_p6##x,_p7##y,z,c), I[258] = (T)(img)(_p5##x,_p7##y,z,c), I[259] = (T)(img)(_p4##x,_p7##y,z,c), I[260] = (T)(img)(_p3##x,_p7##y,z,c), I[261] = (T)(img)(_p2##x,_p7##y,z,c), I[262] = (T)(img)(_p1##x,_p7##y,z,c), I[263] = (T)(img)(x,_p7##y,z,c), I[264] = (T)(img)(_n1##x,_p7##y,z,c), I[265] = (T)(img)(_n2##x,_p7##y,z,c), I[266] = (T)(img)(_n3##x,_p7##y,z,c), I[267] = (T)(img)(_n4##x,_p7##y,z,c), I[268] = (T)(img)(_n5##x,_p7##y,z,c), I[269] = (T)(img)(_n6##x,_p7##y,z,c), I[270] = (T)(img)(_n7##x,_p7##y,z,c), I[271] = (T)(img)(_n8##x,_p7##y,z,c), I[272] = (T)(img)(_n9##x,_p7##y,z,c), I[273] = (T)(img)(_n10##x,_p7##y,z,c), I[274] = (T)(img)(_n11##x,_p7##y,z,c), I[275] = (T)(img)(_n12##x,_p7##y,z,c), I[276] = (T)(img)(_n13##x,_p7##y,z,c), I[277] = (T)(img)(_n14##x,_p7##y,z,c), I[278] = (T)(img)(_n15##x,_p7##y,z,c), \ - I[279] = (T)(img)(_p15##x,_p6##y,z,c), I[280] = (T)(img)(_p14##x,_p6##y,z,c), I[281] = (T)(img)(_p13##x,_p6##y,z,c), I[282] = (T)(img)(_p12##x,_p6##y,z,c), I[283] = (T)(img)(_p11##x,_p6##y,z,c), I[284] = (T)(img)(_p10##x,_p6##y,z,c), I[285] = (T)(img)(_p9##x,_p6##y,z,c), I[286] = (T)(img)(_p8##x,_p6##y,z,c), I[287] = (T)(img)(_p7##x,_p6##y,z,c), I[288] = (T)(img)(_p6##x,_p6##y,z,c), I[289] = (T)(img)(_p5##x,_p6##y,z,c), I[290] = (T)(img)(_p4##x,_p6##y,z,c), I[291] = (T)(img)(_p3##x,_p6##y,z,c), I[292] = (T)(img)(_p2##x,_p6##y,z,c), I[293] = (T)(img)(_p1##x,_p6##y,z,c), I[294] = (T)(img)(x,_p6##y,z,c), I[295] = (T)(img)(_n1##x,_p6##y,z,c), I[296] = (T)(img)(_n2##x,_p6##y,z,c), I[297] = (T)(img)(_n3##x,_p6##y,z,c), I[298] = (T)(img)(_n4##x,_p6##y,z,c), I[299] = (T)(img)(_n5##x,_p6##y,z,c), I[300] = (T)(img)(_n6##x,_p6##y,z,c), I[301] = (T)(img)(_n7##x,_p6##y,z,c), I[302] = (T)(img)(_n8##x,_p6##y,z,c), I[303] = (T)(img)(_n9##x,_p6##y,z,c), I[304] = (T)(img)(_n10##x,_p6##y,z,c), I[305] = (T)(img)(_n11##x,_p6##y,z,c), I[306] = (T)(img)(_n12##x,_p6##y,z,c), I[307] = (T)(img)(_n13##x,_p6##y,z,c), I[308] = (T)(img)(_n14##x,_p6##y,z,c), I[309] = (T)(img)(_n15##x,_p6##y,z,c), \ - I[310] = (T)(img)(_p15##x,_p5##y,z,c), I[311] = (T)(img)(_p14##x,_p5##y,z,c), I[312] = (T)(img)(_p13##x,_p5##y,z,c), I[313] = (T)(img)(_p12##x,_p5##y,z,c), I[314] = (T)(img)(_p11##x,_p5##y,z,c), I[315] = (T)(img)(_p10##x,_p5##y,z,c), I[316] = (T)(img)(_p9##x,_p5##y,z,c), I[317] = (T)(img)(_p8##x,_p5##y,z,c), I[318] = (T)(img)(_p7##x,_p5##y,z,c), I[319] = (T)(img)(_p6##x,_p5##y,z,c), I[320] = (T)(img)(_p5##x,_p5##y,z,c), I[321] = (T)(img)(_p4##x,_p5##y,z,c), I[322] = (T)(img)(_p3##x,_p5##y,z,c), I[323] = (T)(img)(_p2##x,_p5##y,z,c), I[324] = (T)(img)(_p1##x,_p5##y,z,c), I[325] = (T)(img)(x,_p5##y,z,c), I[326] = (T)(img)(_n1##x,_p5##y,z,c), I[327] = (T)(img)(_n2##x,_p5##y,z,c), I[328] = (T)(img)(_n3##x,_p5##y,z,c), I[329] = (T)(img)(_n4##x,_p5##y,z,c), I[330] = (T)(img)(_n5##x,_p5##y,z,c), I[331] = (T)(img)(_n6##x,_p5##y,z,c), I[332] = (T)(img)(_n7##x,_p5##y,z,c), I[333] = (T)(img)(_n8##x,_p5##y,z,c), I[334] = (T)(img)(_n9##x,_p5##y,z,c), I[335] = (T)(img)(_n10##x,_p5##y,z,c), I[336] = (T)(img)(_n11##x,_p5##y,z,c), I[337] = (T)(img)(_n12##x,_p5##y,z,c), I[338] = (T)(img)(_n13##x,_p5##y,z,c), I[339] = (T)(img)(_n14##x,_p5##y,z,c), I[340] = (T)(img)(_n15##x,_p5##y,z,c), \ - I[341] = (T)(img)(_p15##x,_p4##y,z,c), I[342] = (T)(img)(_p14##x,_p4##y,z,c), I[343] = (T)(img)(_p13##x,_p4##y,z,c), I[344] = (T)(img)(_p12##x,_p4##y,z,c), I[345] = (T)(img)(_p11##x,_p4##y,z,c), I[346] = (T)(img)(_p10##x,_p4##y,z,c), I[347] = (T)(img)(_p9##x,_p4##y,z,c), I[348] = (T)(img)(_p8##x,_p4##y,z,c), I[349] = (T)(img)(_p7##x,_p4##y,z,c), I[350] = (T)(img)(_p6##x,_p4##y,z,c), I[351] = (T)(img)(_p5##x,_p4##y,z,c), I[352] = (T)(img)(_p4##x,_p4##y,z,c), I[353] = (T)(img)(_p3##x,_p4##y,z,c), I[354] = (T)(img)(_p2##x,_p4##y,z,c), I[355] = (T)(img)(_p1##x,_p4##y,z,c), I[356] = (T)(img)(x,_p4##y,z,c), I[357] = (T)(img)(_n1##x,_p4##y,z,c), I[358] = (T)(img)(_n2##x,_p4##y,z,c), I[359] = (T)(img)(_n3##x,_p4##y,z,c), I[360] = (T)(img)(_n4##x,_p4##y,z,c), I[361] = (T)(img)(_n5##x,_p4##y,z,c), I[362] = (T)(img)(_n6##x,_p4##y,z,c), I[363] = (T)(img)(_n7##x,_p4##y,z,c), I[364] = (T)(img)(_n8##x,_p4##y,z,c), I[365] = (T)(img)(_n9##x,_p4##y,z,c), I[366] = (T)(img)(_n10##x,_p4##y,z,c), I[367] = (T)(img)(_n11##x,_p4##y,z,c), I[368] = (T)(img)(_n12##x,_p4##y,z,c), I[369] = (T)(img)(_n13##x,_p4##y,z,c), I[370] = (T)(img)(_n14##x,_p4##y,z,c), I[371] = (T)(img)(_n15##x,_p4##y,z,c), \ - I[372] = (T)(img)(_p15##x,_p3##y,z,c), I[373] = (T)(img)(_p14##x,_p3##y,z,c), I[374] = (T)(img)(_p13##x,_p3##y,z,c), I[375] = (T)(img)(_p12##x,_p3##y,z,c), I[376] = (T)(img)(_p11##x,_p3##y,z,c), I[377] = (T)(img)(_p10##x,_p3##y,z,c), I[378] = (T)(img)(_p9##x,_p3##y,z,c), I[379] = (T)(img)(_p8##x,_p3##y,z,c), I[380] = (T)(img)(_p7##x,_p3##y,z,c), I[381] = (T)(img)(_p6##x,_p3##y,z,c), I[382] = (T)(img)(_p5##x,_p3##y,z,c), I[383] = (T)(img)(_p4##x,_p3##y,z,c), I[384] = (T)(img)(_p3##x,_p3##y,z,c), I[385] = (T)(img)(_p2##x,_p3##y,z,c), I[386] = (T)(img)(_p1##x,_p3##y,z,c), I[387] = (T)(img)(x,_p3##y,z,c), I[388] = (T)(img)(_n1##x,_p3##y,z,c), I[389] = (T)(img)(_n2##x,_p3##y,z,c), I[390] = (T)(img)(_n3##x,_p3##y,z,c), I[391] = (T)(img)(_n4##x,_p3##y,z,c), I[392] = (T)(img)(_n5##x,_p3##y,z,c), I[393] = (T)(img)(_n6##x,_p3##y,z,c), I[394] = (T)(img)(_n7##x,_p3##y,z,c), I[395] = (T)(img)(_n8##x,_p3##y,z,c), I[396] = (T)(img)(_n9##x,_p3##y,z,c), I[397] = (T)(img)(_n10##x,_p3##y,z,c), I[398] = (T)(img)(_n11##x,_p3##y,z,c), I[399] = (T)(img)(_n12##x,_p3##y,z,c), I[400] = (T)(img)(_n13##x,_p3##y,z,c), I[401] = (T)(img)(_n14##x,_p3##y,z,c), I[402] = (T)(img)(_n15##x,_p3##y,z,c), \ - I[403] = (T)(img)(_p15##x,_p2##y,z,c), I[404] = (T)(img)(_p14##x,_p2##y,z,c), I[405] = (T)(img)(_p13##x,_p2##y,z,c), I[406] = (T)(img)(_p12##x,_p2##y,z,c), I[407] = (T)(img)(_p11##x,_p2##y,z,c), I[408] = (T)(img)(_p10##x,_p2##y,z,c), I[409] = (T)(img)(_p9##x,_p2##y,z,c), I[410] = (T)(img)(_p8##x,_p2##y,z,c), I[411] = (T)(img)(_p7##x,_p2##y,z,c), I[412] = (T)(img)(_p6##x,_p2##y,z,c), I[413] = (T)(img)(_p5##x,_p2##y,z,c), I[414] = (T)(img)(_p4##x,_p2##y,z,c), I[415] = (T)(img)(_p3##x,_p2##y,z,c), I[416] = (T)(img)(_p2##x,_p2##y,z,c), I[417] = (T)(img)(_p1##x,_p2##y,z,c), I[418] = (T)(img)(x,_p2##y,z,c), I[419] = (T)(img)(_n1##x,_p2##y,z,c), I[420] = (T)(img)(_n2##x,_p2##y,z,c), I[421] = (T)(img)(_n3##x,_p2##y,z,c), I[422] = (T)(img)(_n4##x,_p2##y,z,c), I[423] = (T)(img)(_n5##x,_p2##y,z,c), I[424] = (T)(img)(_n6##x,_p2##y,z,c), I[425] = (T)(img)(_n7##x,_p2##y,z,c), I[426] = (T)(img)(_n8##x,_p2##y,z,c), I[427] = (T)(img)(_n9##x,_p2##y,z,c), I[428] = (T)(img)(_n10##x,_p2##y,z,c), I[429] = (T)(img)(_n11##x,_p2##y,z,c), I[430] = (T)(img)(_n12##x,_p2##y,z,c), I[431] = (T)(img)(_n13##x,_p2##y,z,c), I[432] = (T)(img)(_n14##x,_p2##y,z,c), I[433] = (T)(img)(_n15##x,_p2##y,z,c), \ - I[434] = (T)(img)(_p15##x,_p1##y,z,c), I[435] = (T)(img)(_p14##x,_p1##y,z,c), I[436] = (T)(img)(_p13##x,_p1##y,z,c), I[437] = (T)(img)(_p12##x,_p1##y,z,c), I[438] = (T)(img)(_p11##x,_p1##y,z,c), I[439] = (T)(img)(_p10##x,_p1##y,z,c), I[440] = (T)(img)(_p9##x,_p1##y,z,c), I[441] = (T)(img)(_p8##x,_p1##y,z,c), I[442] = (T)(img)(_p7##x,_p1##y,z,c), I[443] = (T)(img)(_p6##x,_p1##y,z,c), I[444] = (T)(img)(_p5##x,_p1##y,z,c), I[445] = (T)(img)(_p4##x,_p1##y,z,c), I[446] = (T)(img)(_p3##x,_p1##y,z,c), I[447] = (T)(img)(_p2##x,_p1##y,z,c), I[448] = (T)(img)(_p1##x,_p1##y,z,c), I[449] = (T)(img)(x,_p1##y,z,c), I[450] = (T)(img)(_n1##x,_p1##y,z,c), I[451] = (T)(img)(_n2##x,_p1##y,z,c), I[452] = (T)(img)(_n3##x,_p1##y,z,c), I[453] = (T)(img)(_n4##x,_p1##y,z,c), I[454] = (T)(img)(_n5##x,_p1##y,z,c), I[455] = (T)(img)(_n6##x,_p1##y,z,c), I[456] = (T)(img)(_n7##x,_p1##y,z,c), I[457] = (T)(img)(_n8##x,_p1##y,z,c), I[458] = (T)(img)(_n9##x,_p1##y,z,c), I[459] = (T)(img)(_n10##x,_p1##y,z,c), I[460] = (T)(img)(_n11##x,_p1##y,z,c), I[461] = (T)(img)(_n12##x,_p1##y,z,c), I[462] = (T)(img)(_n13##x,_p1##y,z,c), I[463] = (T)(img)(_n14##x,_p1##y,z,c), I[464] = (T)(img)(_n15##x,_p1##y,z,c), \ - I[465] = (T)(img)(_p15##x,y,z,c), I[466] = (T)(img)(_p14##x,y,z,c), I[467] = (T)(img)(_p13##x,y,z,c), I[468] = (T)(img)(_p12##x,y,z,c), I[469] = (T)(img)(_p11##x,y,z,c), I[470] = (T)(img)(_p10##x,y,z,c), I[471] = (T)(img)(_p9##x,y,z,c), I[472] = (T)(img)(_p8##x,y,z,c), I[473] = (T)(img)(_p7##x,y,z,c), I[474] = (T)(img)(_p6##x,y,z,c), I[475] = (T)(img)(_p5##x,y,z,c), I[476] = (T)(img)(_p4##x,y,z,c), I[477] = (T)(img)(_p3##x,y,z,c), I[478] = (T)(img)(_p2##x,y,z,c), I[479] = (T)(img)(_p1##x,y,z,c), I[480] = (T)(img)(x,y,z,c), I[481] = (T)(img)(_n1##x,y,z,c), I[482] = (T)(img)(_n2##x,y,z,c), I[483] = (T)(img)(_n3##x,y,z,c), I[484] = (T)(img)(_n4##x,y,z,c), I[485] = (T)(img)(_n5##x,y,z,c), I[486] = (T)(img)(_n6##x,y,z,c), I[487] = (T)(img)(_n7##x,y,z,c), I[488] = (T)(img)(_n8##x,y,z,c), I[489] = (T)(img)(_n9##x,y,z,c), I[490] = (T)(img)(_n10##x,y,z,c), I[491] = (T)(img)(_n11##x,y,z,c), I[492] = (T)(img)(_n12##x,y,z,c), I[493] = (T)(img)(_n13##x,y,z,c), I[494] = (T)(img)(_n14##x,y,z,c), I[495] = (T)(img)(_n15##x,y,z,c), \ - I[496] = (T)(img)(_p15##x,_n1##y,z,c), I[497] = (T)(img)(_p14##x,_n1##y,z,c), I[498] = (T)(img)(_p13##x,_n1##y,z,c), I[499] = (T)(img)(_p12##x,_n1##y,z,c), I[500] = (T)(img)(_p11##x,_n1##y,z,c), I[501] = (T)(img)(_p10##x,_n1##y,z,c), I[502] = (T)(img)(_p9##x,_n1##y,z,c), I[503] = (T)(img)(_p8##x,_n1##y,z,c), I[504] = (T)(img)(_p7##x,_n1##y,z,c), I[505] = (T)(img)(_p6##x,_n1##y,z,c), I[506] = (T)(img)(_p5##x,_n1##y,z,c), I[507] = (T)(img)(_p4##x,_n1##y,z,c), I[508] = (T)(img)(_p3##x,_n1##y,z,c), I[509] = (T)(img)(_p2##x,_n1##y,z,c), I[510] = (T)(img)(_p1##x,_n1##y,z,c), I[511] = (T)(img)(x,_n1##y,z,c), I[512] = (T)(img)(_n1##x,_n1##y,z,c), I[513] = (T)(img)(_n2##x,_n1##y,z,c), I[514] = (T)(img)(_n3##x,_n1##y,z,c), I[515] = (T)(img)(_n4##x,_n1##y,z,c), I[516] = (T)(img)(_n5##x,_n1##y,z,c), I[517] = (T)(img)(_n6##x,_n1##y,z,c), I[518] = (T)(img)(_n7##x,_n1##y,z,c), I[519] = (T)(img)(_n8##x,_n1##y,z,c), I[520] = (T)(img)(_n9##x,_n1##y,z,c), I[521] = (T)(img)(_n10##x,_n1##y,z,c), I[522] = (T)(img)(_n11##x,_n1##y,z,c), I[523] = (T)(img)(_n12##x,_n1##y,z,c), I[524] = (T)(img)(_n13##x,_n1##y,z,c), I[525] = (T)(img)(_n14##x,_n1##y,z,c), I[526] = (T)(img)(_n15##x,_n1##y,z,c), \ - I[527] = (T)(img)(_p15##x,_n2##y,z,c), I[528] = (T)(img)(_p14##x,_n2##y,z,c), I[529] = (T)(img)(_p13##x,_n2##y,z,c), I[530] = (T)(img)(_p12##x,_n2##y,z,c), I[531] = (T)(img)(_p11##x,_n2##y,z,c), I[532] = (T)(img)(_p10##x,_n2##y,z,c), I[533] = (T)(img)(_p9##x,_n2##y,z,c), I[534] = (T)(img)(_p8##x,_n2##y,z,c), I[535] = (T)(img)(_p7##x,_n2##y,z,c), I[536] = (T)(img)(_p6##x,_n2##y,z,c), I[537] = (T)(img)(_p5##x,_n2##y,z,c), I[538] = (T)(img)(_p4##x,_n2##y,z,c), I[539] = (T)(img)(_p3##x,_n2##y,z,c), I[540] = (T)(img)(_p2##x,_n2##y,z,c), I[541] = (T)(img)(_p1##x,_n2##y,z,c), I[542] = (T)(img)(x,_n2##y,z,c), I[543] = (T)(img)(_n1##x,_n2##y,z,c), I[544] = (T)(img)(_n2##x,_n2##y,z,c), I[545] = (T)(img)(_n3##x,_n2##y,z,c), I[546] = (T)(img)(_n4##x,_n2##y,z,c), I[547] = (T)(img)(_n5##x,_n2##y,z,c), I[548] = (T)(img)(_n6##x,_n2##y,z,c), I[549] = (T)(img)(_n7##x,_n2##y,z,c), I[550] = (T)(img)(_n8##x,_n2##y,z,c), I[551] = (T)(img)(_n9##x,_n2##y,z,c), I[552] = (T)(img)(_n10##x,_n2##y,z,c), I[553] = (T)(img)(_n11##x,_n2##y,z,c), I[554] = (T)(img)(_n12##x,_n2##y,z,c), I[555] = (T)(img)(_n13##x,_n2##y,z,c), I[556] = (T)(img)(_n14##x,_n2##y,z,c), I[557] = (T)(img)(_n15##x,_n2##y,z,c), \ - I[558] = (T)(img)(_p15##x,_n3##y,z,c), I[559] = (T)(img)(_p14##x,_n3##y,z,c), I[560] = (T)(img)(_p13##x,_n3##y,z,c), I[561] = (T)(img)(_p12##x,_n3##y,z,c), I[562] = (T)(img)(_p11##x,_n3##y,z,c), I[563] = (T)(img)(_p10##x,_n3##y,z,c), I[564] = (T)(img)(_p9##x,_n3##y,z,c), I[565] = (T)(img)(_p8##x,_n3##y,z,c), I[566] = (T)(img)(_p7##x,_n3##y,z,c), I[567] = (T)(img)(_p6##x,_n3##y,z,c), I[568] = (T)(img)(_p5##x,_n3##y,z,c), I[569] = (T)(img)(_p4##x,_n3##y,z,c), I[570] = (T)(img)(_p3##x,_n3##y,z,c), I[571] = (T)(img)(_p2##x,_n3##y,z,c), I[572] = (T)(img)(_p1##x,_n3##y,z,c), I[573] = (T)(img)(x,_n3##y,z,c), I[574] = (T)(img)(_n1##x,_n3##y,z,c), I[575] = (T)(img)(_n2##x,_n3##y,z,c), I[576] = (T)(img)(_n3##x,_n3##y,z,c), I[577] = (T)(img)(_n4##x,_n3##y,z,c), I[578] = (T)(img)(_n5##x,_n3##y,z,c), I[579] = (T)(img)(_n6##x,_n3##y,z,c), I[580] = (T)(img)(_n7##x,_n3##y,z,c), I[581] = (T)(img)(_n8##x,_n3##y,z,c), I[582] = (T)(img)(_n9##x,_n3##y,z,c), I[583] = (T)(img)(_n10##x,_n3##y,z,c), I[584] = (T)(img)(_n11##x,_n3##y,z,c), I[585] = (T)(img)(_n12##x,_n3##y,z,c), I[586] = (T)(img)(_n13##x,_n3##y,z,c), I[587] = (T)(img)(_n14##x,_n3##y,z,c), I[588] = (T)(img)(_n15##x,_n3##y,z,c), \ - I[589] = (T)(img)(_p15##x,_n4##y,z,c), I[590] = (T)(img)(_p14##x,_n4##y,z,c), I[591] = (T)(img)(_p13##x,_n4##y,z,c), I[592] = (T)(img)(_p12##x,_n4##y,z,c), I[593] = (T)(img)(_p11##x,_n4##y,z,c), I[594] = (T)(img)(_p10##x,_n4##y,z,c), I[595] = (T)(img)(_p9##x,_n4##y,z,c), I[596] = (T)(img)(_p8##x,_n4##y,z,c), I[597] = (T)(img)(_p7##x,_n4##y,z,c), I[598] = (T)(img)(_p6##x,_n4##y,z,c), I[599] = (T)(img)(_p5##x,_n4##y,z,c), I[600] = (T)(img)(_p4##x,_n4##y,z,c), I[601] = (T)(img)(_p3##x,_n4##y,z,c), I[602] = (T)(img)(_p2##x,_n4##y,z,c), I[603] = (T)(img)(_p1##x,_n4##y,z,c), I[604] = (T)(img)(x,_n4##y,z,c), I[605] = (T)(img)(_n1##x,_n4##y,z,c), I[606] = (T)(img)(_n2##x,_n4##y,z,c), I[607] = (T)(img)(_n3##x,_n4##y,z,c), I[608] = (T)(img)(_n4##x,_n4##y,z,c), I[609] = (T)(img)(_n5##x,_n4##y,z,c), I[610] = (T)(img)(_n6##x,_n4##y,z,c), I[611] = (T)(img)(_n7##x,_n4##y,z,c), I[612] = (T)(img)(_n8##x,_n4##y,z,c), I[613] = (T)(img)(_n9##x,_n4##y,z,c), I[614] = (T)(img)(_n10##x,_n4##y,z,c), I[615] = (T)(img)(_n11##x,_n4##y,z,c), I[616] = (T)(img)(_n12##x,_n4##y,z,c), I[617] = (T)(img)(_n13##x,_n4##y,z,c), I[618] = (T)(img)(_n14##x,_n4##y,z,c), I[619] = (T)(img)(_n15##x,_n4##y,z,c), \ - I[620] = (T)(img)(_p15##x,_n5##y,z,c), I[621] = (T)(img)(_p14##x,_n5##y,z,c), I[622] = (T)(img)(_p13##x,_n5##y,z,c), I[623] = (T)(img)(_p12##x,_n5##y,z,c), I[624] = (T)(img)(_p11##x,_n5##y,z,c), I[625] = (T)(img)(_p10##x,_n5##y,z,c), I[626] = (T)(img)(_p9##x,_n5##y,z,c), I[627] = (T)(img)(_p8##x,_n5##y,z,c), I[628] = (T)(img)(_p7##x,_n5##y,z,c), I[629] = (T)(img)(_p6##x,_n5##y,z,c), I[630] = (T)(img)(_p5##x,_n5##y,z,c), I[631] = (T)(img)(_p4##x,_n5##y,z,c), I[632] = (T)(img)(_p3##x,_n5##y,z,c), I[633] = (T)(img)(_p2##x,_n5##y,z,c), I[634] = (T)(img)(_p1##x,_n5##y,z,c), I[635] = (T)(img)(x,_n5##y,z,c), I[636] = (T)(img)(_n1##x,_n5##y,z,c), I[637] = (T)(img)(_n2##x,_n5##y,z,c), I[638] = (T)(img)(_n3##x,_n5##y,z,c), I[639] = (T)(img)(_n4##x,_n5##y,z,c), I[640] = (T)(img)(_n5##x,_n5##y,z,c), I[641] = (T)(img)(_n6##x,_n5##y,z,c), I[642] = (T)(img)(_n7##x,_n5##y,z,c), I[643] = (T)(img)(_n8##x,_n5##y,z,c), I[644] = (T)(img)(_n9##x,_n5##y,z,c), I[645] = (T)(img)(_n10##x,_n5##y,z,c), I[646] = (T)(img)(_n11##x,_n5##y,z,c), I[647] = (T)(img)(_n12##x,_n5##y,z,c), I[648] = (T)(img)(_n13##x,_n5##y,z,c), I[649] = (T)(img)(_n14##x,_n5##y,z,c), I[650] = (T)(img)(_n15##x,_n5##y,z,c), \ - I[651] = (T)(img)(_p15##x,_n6##y,z,c), I[652] = (T)(img)(_p14##x,_n6##y,z,c), I[653] = (T)(img)(_p13##x,_n6##y,z,c), I[654] = (T)(img)(_p12##x,_n6##y,z,c), I[655] = (T)(img)(_p11##x,_n6##y,z,c), I[656] = (T)(img)(_p10##x,_n6##y,z,c), I[657] = (T)(img)(_p9##x,_n6##y,z,c), I[658] = (T)(img)(_p8##x,_n6##y,z,c), I[659] = (T)(img)(_p7##x,_n6##y,z,c), I[660] = (T)(img)(_p6##x,_n6##y,z,c), I[661] = (T)(img)(_p5##x,_n6##y,z,c), I[662] = (T)(img)(_p4##x,_n6##y,z,c), I[663] = (T)(img)(_p3##x,_n6##y,z,c), I[664] = (T)(img)(_p2##x,_n6##y,z,c), I[665] = (T)(img)(_p1##x,_n6##y,z,c), I[666] = (T)(img)(x,_n6##y,z,c), I[667] = (T)(img)(_n1##x,_n6##y,z,c), I[668] = (T)(img)(_n2##x,_n6##y,z,c), I[669] = (T)(img)(_n3##x,_n6##y,z,c), I[670] = (T)(img)(_n4##x,_n6##y,z,c), I[671] = (T)(img)(_n5##x,_n6##y,z,c), I[672] = (T)(img)(_n6##x,_n6##y,z,c), I[673] = (T)(img)(_n7##x,_n6##y,z,c), I[674] = (T)(img)(_n8##x,_n6##y,z,c), I[675] = (T)(img)(_n9##x,_n6##y,z,c), I[676] = (T)(img)(_n10##x,_n6##y,z,c), I[677] = (T)(img)(_n11##x,_n6##y,z,c), I[678] = (T)(img)(_n12##x,_n6##y,z,c), I[679] = (T)(img)(_n13##x,_n6##y,z,c), I[680] = (T)(img)(_n14##x,_n6##y,z,c), I[681] = (T)(img)(_n15##x,_n6##y,z,c), \ - I[682] = (T)(img)(_p15##x,_n7##y,z,c), I[683] = (T)(img)(_p14##x,_n7##y,z,c), I[684] = (T)(img)(_p13##x,_n7##y,z,c), I[685] = (T)(img)(_p12##x,_n7##y,z,c), I[686] = (T)(img)(_p11##x,_n7##y,z,c), I[687] = (T)(img)(_p10##x,_n7##y,z,c), I[688] = (T)(img)(_p9##x,_n7##y,z,c), I[689] = (T)(img)(_p8##x,_n7##y,z,c), I[690] = (T)(img)(_p7##x,_n7##y,z,c), I[691] = (T)(img)(_p6##x,_n7##y,z,c), I[692] = (T)(img)(_p5##x,_n7##y,z,c), I[693] = (T)(img)(_p4##x,_n7##y,z,c), I[694] = (T)(img)(_p3##x,_n7##y,z,c), I[695] = (T)(img)(_p2##x,_n7##y,z,c), I[696] = (T)(img)(_p1##x,_n7##y,z,c), I[697] = (T)(img)(x,_n7##y,z,c), I[698] = (T)(img)(_n1##x,_n7##y,z,c), I[699] = (T)(img)(_n2##x,_n7##y,z,c), I[700] = (T)(img)(_n3##x,_n7##y,z,c), I[701] = (T)(img)(_n4##x,_n7##y,z,c), I[702] = (T)(img)(_n5##x,_n7##y,z,c), I[703] = (T)(img)(_n6##x,_n7##y,z,c), I[704] = (T)(img)(_n7##x,_n7##y,z,c), I[705] = (T)(img)(_n8##x,_n7##y,z,c), I[706] = (T)(img)(_n9##x,_n7##y,z,c), I[707] = (T)(img)(_n10##x,_n7##y,z,c), I[708] = (T)(img)(_n11##x,_n7##y,z,c), I[709] = (T)(img)(_n12##x,_n7##y,z,c), I[710] = (T)(img)(_n13##x,_n7##y,z,c), I[711] = (T)(img)(_n14##x,_n7##y,z,c), I[712] = (T)(img)(_n15##x,_n7##y,z,c), \ - I[713] = (T)(img)(_p15##x,_n8##y,z,c), I[714] = (T)(img)(_p14##x,_n8##y,z,c), I[715] = (T)(img)(_p13##x,_n8##y,z,c), I[716] = (T)(img)(_p12##x,_n8##y,z,c), I[717] = (T)(img)(_p11##x,_n8##y,z,c), I[718] = (T)(img)(_p10##x,_n8##y,z,c), I[719] = (T)(img)(_p9##x,_n8##y,z,c), I[720] = (T)(img)(_p8##x,_n8##y,z,c), I[721] = (T)(img)(_p7##x,_n8##y,z,c), I[722] = (T)(img)(_p6##x,_n8##y,z,c), I[723] = (T)(img)(_p5##x,_n8##y,z,c), I[724] = (T)(img)(_p4##x,_n8##y,z,c), I[725] = (T)(img)(_p3##x,_n8##y,z,c), I[726] = (T)(img)(_p2##x,_n8##y,z,c), I[727] = (T)(img)(_p1##x,_n8##y,z,c), I[728] = (T)(img)(x,_n8##y,z,c), I[729] = (T)(img)(_n1##x,_n8##y,z,c), I[730] = (T)(img)(_n2##x,_n8##y,z,c), I[731] = (T)(img)(_n3##x,_n8##y,z,c), I[732] = (T)(img)(_n4##x,_n8##y,z,c), I[733] = (T)(img)(_n5##x,_n8##y,z,c), I[734] = (T)(img)(_n6##x,_n8##y,z,c), I[735] = (T)(img)(_n7##x,_n8##y,z,c), I[736] = (T)(img)(_n8##x,_n8##y,z,c), I[737] = (T)(img)(_n9##x,_n8##y,z,c), I[738] = (T)(img)(_n10##x,_n8##y,z,c), I[739] = (T)(img)(_n11##x,_n8##y,z,c), I[740] = (T)(img)(_n12##x,_n8##y,z,c), I[741] = (T)(img)(_n13##x,_n8##y,z,c), I[742] = (T)(img)(_n14##x,_n8##y,z,c), I[743] = (T)(img)(_n15##x,_n8##y,z,c), \ - I[744] = (T)(img)(_p15##x,_n9##y,z,c), I[745] = (T)(img)(_p14##x,_n9##y,z,c), I[746] = (T)(img)(_p13##x,_n9##y,z,c), I[747] = (T)(img)(_p12##x,_n9##y,z,c), I[748] = (T)(img)(_p11##x,_n9##y,z,c), I[749] = (T)(img)(_p10##x,_n9##y,z,c), I[750] = (T)(img)(_p9##x,_n9##y,z,c), I[751] = (T)(img)(_p8##x,_n9##y,z,c), I[752] = (T)(img)(_p7##x,_n9##y,z,c), I[753] = (T)(img)(_p6##x,_n9##y,z,c), I[754] = (T)(img)(_p5##x,_n9##y,z,c), I[755] = (T)(img)(_p4##x,_n9##y,z,c), I[756] = (T)(img)(_p3##x,_n9##y,z,c), I[757] = (T)(img)(_p2##x,_n9##y,z,c), I[758] = (T)(img)(_p1##x,_n9##y,z,c), I[759] = (T)(img)(x,_n9##y,z,c), I[760] = (T)(img)(_n1##x,_n9##y,z,c), I[761] = (T)(img)(_n2##x,_n9##y,z,c), I[762] = (T)(img)(_n3##x,_n9##y,z,c), I[763] = (T)(img)(_n4##x,_n9##y,z,c), I[764] = (T)(img)(_n5##x,_n9##y,z,c), I[765] = (T)(img)(_n6##x,_n9##y,z,c), I[766] = (T)(img)(_n7##x,_n9##y,z,c), I[767] = (T)(img)(_n8##x,_n9##y,z,c), I[768] = (T)(img)(_n9##x,_n9##y,z,c), I[769] = (T)(img)(_n10##x,_n9##y,z,c), I[770] = (T)(img)(_n11##x,_n9##y,z,c), I[771] = (T)(img)(_n12##x,_n9##y,z,c), I[772] = (T)(img)(_n13##x,_n9##y,z,c), I[773] = (T)(img)(_n14##x,_n9##y,z,c), I[774] = (T)(img)(_n15##x,_n9##y,z,c), \ - I[775] = (T)(img)(_p15##x,_n10##y,z,c), I[776] = (T)(img)(_p14##x,_n10##y,z,c), I[777] = (T)(img)(_p13##x,_n10##y,z,c), I[778] = (T)(img)(_p12##x,_n10##y,z,c), I[779] = (T)(img)(_p11##x,_n10##y,z,c), I[780] = (T)(img)(_p10##x,_n10##y,z,c), I[781] = (T)(img)(_p9##x,_n10##y,z,c), I[782] = (T)(img)(_p8##x,_n10##y,z,c), I[783] = (T)(img)(_p7##x,_n10##y,z,c), I[784] = (T)(img)(_p6##x,_n10##y,z,c), I[785] = (T)(img)(_p5##x,_n10##y,z,c), I[786] = (T)(img)(_p4##x,_n10##y,z,c), I[787] = (T)(img)(_p3##x,_n10##y,z,c), I[788] = (T)(img)(_p2##x,_n10##y,z,c), I[789] = (T)(img)(_p1##x,_n10##y,z,c), I[790] = (T)(img)(x,_n10##y,z,c), I[791] = (T)(img)(_n1##x,_n10##y,z,c), I[792] = (T)(img)(_n2##x,_n10##y,z,c), I[793] = (T)(img)(_n3##x,_n10##y,z,c), I[794] = (T)(img)(_n4##x,_n10##y,z,c), I[795] = (T)(img)(_n5##x,_n10##y,z,c), I[796] = (T)(img)(_n6##x,_n10##y,z,c), I[797] = (T)(img)(_n7##x,_n10##y,z,c), I[798] = (T)(img)(_n8##x,_n10##y,z,c), I[799] = (T)(img)(_n9##x,_n10##y,z,c), I[800] = (T)(img)(_n10##x,_n10##y,z,c), I[801] = (T)(img)(_n11##x,_n10##y,z,c), I[802] = (T)(img)(_n12##x,_n10##y,z,c), I[803] = (T)(img)(_n13##x,_n10##y,z,c), I[804] = (T)(img)(_n14##x,_n10##y,z,c), I[805] = (T)(img)(_n15##x,_n10##y,z,c), \ - I[806] = (T)(img)(_p15##x,_n11##y,z,c), I[807] = (T)(img)(_p14##x,_n11##y,z,c), I[808] = (T)(img)(_p13##x,_n11##y,z,c), I[809] = (T)(img)(_p12##x,_n11##y,z,c), I[810] = (T)(img)(_p11##x,_n11##y,z,c), I[811] = (T)(img)(_p10##x,_n11##y,z,c), I[812] = (T)(img)(_p9##x,_n11##y,z,c), I[813] = (T)(img)(_p8##x,_n11##y,z,c), I[814] = (T)(img)(_p7##x,_n11##y,z,c), I[815] = (T)(img)(_p6##x,_n11##y,z,c), I[816] = (T)(img)(_p5##x,_n11##y,z,c), I[817] = (T)(img)(_p4##x,_n11##y,z,c), I[818] = (T)(img)(_p3##x,_n11##y,z,c), I[819] = (T)(img)(_p2##x,_n11##y,z,c), I[820] = (T)(img)(_p1##x,_n11##y,z,c), I[821] = (T)(img)(x,_n11##y,z,c), I[822] = (T)(img)(_n1##x,_n11##y,z,c), I[823] = (T)(img)(_n2##x,_n11##y,z,c), I[824] = (T)(img)(_n3##x,_n11##y,z,c), I[825] = (T)(img)(_n4##x,_n11##y,z,c), I[826] = (T)(img)(_n5##x,_n11##y,z,c), I[827] = (T)(img)(_n6##x,_n11##y,z,c), I[828] = (T)(img)(_n7##x,_n11##y,z,c), I[829] = (T)(img)(_n8##x,_n11##y,z,c), I[830] = (T)(img)(_n9##x,_n11##y,z,c), I[831] = (T)(img)(_n10##x,_n11##y,z,c), I[832] = (T)(img)(_n11##x,_n11##y,z,c), I[833] = (T)(img)(_n12##x,_n11##y,z,c), I[834] = (T)(img)(_n13##x,_n11##y,z,c), I[835] = (T)(img)(_n14##x,_n11##y,z,c), I[836] = (T)(img)(_n15##x,_n11##y,z,c), \ - I[837] = (T)(img)(_p15##x,_n12##y,z,c), I[838] = (T)(img)(_p14##x,_n12##y,z,c), I[839] = (T)(img)(_p13##x,_n12##y,z,c), I[840] = (T)(img)(_p12##x,_n12##y,z,c), I[841] = (T)(img)(_p11##x,_n12##y,z,c), I[842] = (T)(img)(_p10##x,_n12##y,z,c), I[843] = (T)(img)(_p9##x,_n12##y,z,c), I[844] = (T)(img)(_p8##x,_n12##y,z,c), I[845] = (T)(img)(_p7##x,_n12##y,z,c), I[846] = (T)(img)(_p6##x,_n12##y,z,c), I[847] = (T)(img)(_p5##x,_n12##y,z,c), I[848] = (T)(img)(_p4##x,_n12##y,z,c), I[849] = (T)(img)(_p3##x,_n12##y,z,c), I[850] = (T)(img)(_p2##x,_n12##y,z,c), I[851] = (T)(img)(_p1##x,_n12##y,z,c), I[852] = (T)(img)(x,_n12##y,z,c), I[853] = (T)(img)(_n1##x,_n12##y,z,c), I[854] = (T)(img)(_n2##x,_n12##y,z,c), I[855] = (T)(img)(_n3##x,_n12##y,z,c), I[856] = (T)(img)(_n4##x,_n12##y,z,c), I[857] = (T)(img)(_n5##x,_n12##y,z,c), I[858] = (T)(img)(_n6##x,_n12##y,z,c), I[859] = (T)(img)(_n7##x,_n12##y,z,c), I[860] = (T)(img)(_n8##x,_n12##y,z,c), I[861] = (T)(img)(_n9##x,_n12##y,z,c), I[862] = (T)(img)(_n10##x,_n12##y,z,c), I[863] = (T)(img)(_n11##x,_n12##y,z,c), I[864] = (T)(img)(_n12##x,_n12##y,z,c), I[865] = (T)(img)(_n13##x,_n12##y,z,c), I[866] = (T)(img)(_n14##x,_n12##y,z,c), I[867] = (T)(img)(_n15##x,_n12##y,z,c), \ - I[868] = (T)(img)(_p15##x,_n13##y,z,c), I[869] = (T)(img)(_p14##x,_n13##y,z,c), I[870] = (T)(img)(_p13##x,_n13##y,z,c), I[871] = (T)(img)(_p12##x,_n13##y,z,c), I[872] = (T)(img)(_p11##x,_n13##y,z,c), I[873] = (T)(img)(_p10##x,_n13##y,z,c), I[874] = (T)(img)(_p9##x,_n13##y,z,c), I[875] = (T)(img)(_p8##x,_n13##y,z,c), I[876] = (T)(img)(_p7##x,_n13##y,z,c), I[877] = (T)(img)(_p6##x,_n13##y,z,c), I[878] = (T)(img)(_p5##x,_n13##y,z,c), I[879] = (T)(img)(_p4##x,_n13##y,z,c), I[880] = (T)(img)(_p3##x,_n13##y,z,c), I[881] = (T)(img)(_p2##x,_n13##y,z,c), I[882] = (T)(img)(_p1##x,_n13##y,z,c), I[883] = (T)(img)(x,_n13##y,z,c), I[884] = (T)(img)(_n1##x,_n13##y,z,c), I[885] = (T)(img)(_n2##x,_n13##y,z,c), I[886] = (T)(img)(_n3##x,_n13##y,z,c), I[887] = (T)(img)(_n4##x,_n13##y,z,c), I[888] = (T)(img)(_n5##x,_n13##y,z,c), I[889] = (T)(img)(_n6##x,_n13##y,z,c), I[890] = (T)(img)(_n7##x,_n13##y,z,c), I[891] = (T)(img)(_n8##x,_n13##y,z,c), I[892] = (T)(img)(_n9##x,_n13##y,z,c), I[893] = (T)(img)(_n10##x,_n13##y,z,c), I[894] = (T)(img)(_n11##x,_n13##y,z,c), I[895] = (T)(img)(_n12##x,_n13##y,z,c), I[896] = (T)(img)(_n13##x,_n13##y,z,c), I[897] = (T)(img)(_n14##x,_n13##y,z,c), I[898] = (T)(img)(_n15##x,_n13##y,z,c), \ - I[899] = (T)(img)(_p15##x,_n14##y,z,c), I[900] = (T)(img)(_p14##x,_n14##y,z,c), I[901] = (T)(img)(_p13##x,_n14##y,z,c), I[902] = (T)(img)(_p12##x,_n14##y,z,c), I[903] = (T)(img)(_p11##x,_n14##y,z,c), I[904] = (T)(img)(_p10##x,_n14##y,z,c), I[905] = (T)(img)(_p9##x,_n14##y,z,c), I[906] = (T)(img)(_p8##x,_n14##y,z,c), I[907] = (T)(img)(_p7##x,_n14##y,z,c), I[908] = (T)(img)(_p6##x,_n14##y,z,c), I[909] = (T)(img)(_p5##x,_n14##y,z,c), I[910] = (T)(img)(_p4##x,_n14##y,z,c), I[911] = (T)(img)(_p3##x,_n14##y,z,c), I[912] = (T)(img)(_p2##x,_n14##y,z,c), I[913] = (T)(img)(_p1##x,_n14##y,z,c), I[914] = (T)(img)(x,_n14##y,z,c), I[915] = (T)(img)(_n1##x,_n14##y,z,c), I[916] = (T)(img)(_n2##x,_n14##y,z,c), I[917] = (T)(img)(_n3##x,_n14##y,z,c), I[918] = (T)(img)(_n4##x,_n14##y,z,c), I[919] = (T)(img)(_n5##x,_n14##y,z,c), I[920] = (T)(img)(_n6##x,_n14##y,z,c), I[921] = (T)(img)(_n7##x,_n14##y,z,c), I[922] = (T)(img)(_n8##x,_n14##y,z,c), I[923] = (T)(img)(_n9##x,_n14##y,z,c), I[924] = (T)(img)(_n10##x,_n14##y,z,c), I[925] = (T)(img)(_n11##x,_n14##y,z,c), I[926] = (T)(img)(_n12##x,_n14##y,z,c), I[927] = (T)(img)(_n13##x,_n14##y,z,c), I[928] = (T)(img)(_n14##x,_n14##y,z,c), I[929] = (T)(img)(_n15##x,_n14##y,z,c), \ - I[930] = (T)(img)(_p15##x,_n15##y,z,c), I[931] = (T)(img)(_p14##x,_n15##y,z,c), I[932] = (T)(img)(_p13##x,_n15##y,z,c), I[933] = (T)(img)(_p12##x,_n15##y,z,c), I[934] = (T)(img)(_p11##x,_n15##y,z,c), I[935] = (T)(img)(_p10##x,_n15##y,z,c), I[936] = (T)(img)(_p9##x,_n15##y,z,c), I[937] = (T)(img)(_p8##x,_n15##y,z,c), I[938] = (T)(img)(_p7##x,_n15##y,z,c), I[939] = (T)(img)(_p6##x,_n15##y,z,c), I[940] = (T)(img)(_p5##x,_n15##y,z,c), I[941] = (T)(img)(_p4##x,_n15##y,z,c), I[942] = (T)(img)(_p3##x,_n15##y,z,c), I[943] = (T)(img)(_p2##x,_n15##y,z,c), I[944] = (T)(img)(_p1##x,_n15##y,z,c), I[945] = (T)(img)(x,_n15##y,z,c), I[946] = (T)(img)(_n1##x,_n15##y,z,c), I[947] = (T)(img)(_n2##x,_n15##y,z,c), I[948] = (T)(img)(_n3##x,_n15##y,z,c), I[949] = (T)(img)(_n4##x,_n15##y,z,c), I[950] = (T)(img)(_n5##x,_n15##y,z,c), I[951] = (T)(img)(_n6##x,_n15##y,z,c), I[952] = (T)(img)(_n7##x,_n15##y,z,c), I[953] = (T)(img)(_n8##x,_n15##y,z,c), I[954] = (T)(img)(_n9##x,_n15##y,z,c), I[955] = (T)(img)(_n10##x,_n15##y,z,c), I[956] = (T)(img)(_n11##x,_n15##y,z,c), I[957] = (T)(img)(_n12##x,_n15##y,z,c), I[958] = (T)(img)(_n13##x,_n15##y,z,c), I[959] = (T)(img)(_n14##x,_n15##y,z,c), I[960] = (T)(img)(_n15##x,_n15##y,z,c); - -// Define 32x32 loop macros -//------------------------- -#define cimg_for32(bound,i) for (int i = 0, \ - _p15##i = 0, _p14##i = 0, _p13##i = 0, _p12##i = 0, _p11##i = 0, _p10##i = 0, _p9##i = 0, _p8##i = 0, _p7##i = 0, _p6##i = 0, _p5##i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \ - _n1##i = 1>=(int)(bound)?(int)(bound) - 1:1, \ - _n2##i = 2>=(int)(bound)?(int)(bound) - 1:2, \ - _n3##i = 3>=(int)(bound)?(int)(bound) - 1:3, \ - _n4##i = 4>=(int)(bound)?(int)(bound) - 1:4, \ - _n5##i = 5>=(int)(bound)?(int)(bound) - 1:5, \ - _n6##i = 6>=(int)(bound)?(int)(bound) - 1:6, \ - _n7##i = 7>=(int)(bound)?(int)(bound) - 1:7, \ - _n8##i = 8>=(int)(bound)?(int)(bound) - 1:8, \ - _n9##i = 9>=(int)(bound)?(int)(bound) - 1:9, \ - _n10##i = 10>=(int)(bound)?(int)(bound) - 1:10, \ - _n11##i = 11>=(int)(bound)?(int)(bound) - 1:11, \ - _n12##i = 12>=(int)(bound)?(int)(bound) - 1:12, \ - _n13##i = 13>=(int)(bound)?(int)(bound) - 1:13, \ - _n14##i = 14>=(int)(bound)?(int)(bound) - 1:14, \ - _n15##i = 15>=(int)(bound)?(int)(bound) - 1:15, \ - _n16##i = 16>=(int)(bound)?(int)(bound) - 1:16; \ - _n16##i<(int)(bound) || _n15##i==--_n16##i || _n14##i==--_n15##i || _n13##i==--_n14##i || _n12##i==--_n13##i || _n11##i==--_n12##i || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n16##i = _n15##i = _n14##i = _n13##i = _n12##i = _n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i); \ - _p15##i = _p14##i, _p14##i = _p13##i, _p13##i = _p12##i, _p12##i = _p11##i, _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i, ++_n12##i, ++_n13##i, ++_n14##i, ++_n15##i, ++_n16##i) - -#define cimg_for32X(img,x) cimg_for32((img)._width,x) -#define cimg_for32Y(img,y) cimg_for32((img)._height,y) -#define cimg_for32Z(img,z) cimg_for32((img)._depth,z) -#define cimg_for32C(img,c) cimg_for32((img)._spectrum,c) -#define cimg_for32XY(img,x,y) cimg_for32Y(img,y) cimg_for32X(img,x) -#define cimg_for32XZ(img,x,z) cimg_for32Z(img,z) cimg_for32X(img,x) -#define cimg_for32XC(img,x,c) cimg_for32C(img,c) cimg_for32X(img,x) -#define cimg_for32YZ(img,y,z) cimg_for32Z(img,z) cimg_for32Y(img,y) -#define cimg_for32YC(img,y,c) cimg_for32C(img,c) cimg_for32Y(img,y) -#define cimg_for32ZC(img,z,c) cimg_for32C(img,c) cimg_for32Z(img,z) -#define cimg_for32XYZ(img,x,y,z) cimg_for32Z(img,z) cimg_for32XY(img,x,y) -#define cimg_for32XZC(img,x,z,c) cimg_for32C(img,c) cimg_for32XZ(img,x,z) -#define cimg_for32YZC(img,y,z,c) cimg_for32C(img,c) cimg_for32YZ(img,y,z) -#define cimg_for32XYZC(img,x,y,z,c) cimg_for32C(img,c) cimg_for32XYZ(img,x,y,z) - -#define cimg_for_in32(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \ - _p15##i = i - 15<0?0:i - 15, \ - _p14##i = i - 14<0?0:i - 14, \ - _p13##i = i - 13<0?0:i - 13, \ - _p12##i = i - 12<0?0:i - 12, \ - _p11##i = i - 11<0?0:i - 11, \ - _p10##i = i - 10<0?0:i - 10, \ - _p9##i = i - 9<0?0:i - 9, \ - _p8##i = i - 8<0?0:i - 8, \ - _p7##i = i - 7<0?0:i - 7, \ - _p6##i = i - 6<0?0:i - 6, \ - _p5##i = i - 5<0?0:i - 5, \ - _p4##i = i - 4<0?0:i - 4, \ - _p3##i = i - 3<0?0:i - 3, \ - _p2##i = i - 2<0?0:i - 2, \ - _p1##i = i - 1<0?0:i - 1, \ - _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1, \ - _n2##i = i + 2>=(int)(bound)?(int)(bound) - 1:i + 2, \ - _n3##i = i + 3>=(int)(bound)?(int)(bound) - 1:i + 3, \ - _n4##i = i + 4>=(int)(bound)?(int)(bound) - 1:i + 4, \ - _n5##i = i + 5>=(int)(bound)?(int)(bound) - 1:i + 5, \ - _n6##i = i + 6>=(int)(bound)?(int)(bound) - 1:i + 6, \ - _n7##i = i + 7>=(int)(bound)?(int)(bound) - 1:i + 7, \ - _n8##i = i + 8>=(int)(bound)?(int)(bound) - 1:i + 8, \ - _n9##i = i + 9>=(int)(bound)?(int)(bound) - 1:i + 9, \ - _n10##i = i + 10>=(int)(bound)?(int)(bound) - 1:i + 10, \ - _n11##i = i + 11>=(int)(bound)?(int)(bound) - 1:i + 11, \ - _n12##i = i + 12>=(int)(bound)?(int)(bound) - 1:i + 12, \ - _n13##i = i + 13>=(int)(bound)?(int)(bound) - 1:i + 13, \ - _n14##i = i + 14>=(int)(bound)?(int)(bound) - 1:i + 14, \ - _n15##i = i + 15>=(int)(bound)?(int)(bound) - 1:i + 15, \ - _n16##i = i + 16>=(int)(bound)?(int)(bound) - 1:i + 16; \ - i<=(int)(i1) && (_n16##i<(int)(bound) || _n15##i==--_n16##i || _n14##i==--_n15##i || _n13##i==--_n14##i || _n12##i==--_n13##i || _n11##i==--_n12##i || _n10##i==--_n11##i || _n9##i==--_n10##i || _n8##i==--_n9##i || _n7##i==--_n8##i || _n6##i==--_n7##i || _n5##i==--_n6##i || _n4##i==--_n5##i || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \ - i==(_n16##i = _n15##i = _n14##i = _n13##i = _n12##i = _n11##i = _n10##i = _n9##i = _n8##i = _n7##i = _n6##i = _n5##i = _n4##i = _n3##i = _n2##i = --_n1##i)); \ - _p15##i = _p14##i, _p14##i = _p13##i, _p13##i = _p12##i, _p12##i = _p11##i, _p11##i = _p10##i, _p10##i = _p9##i, _p9##i = _p8##i, _p8##i = _p7##i, _p7##i = _p6##i, _p6##i = _p5##i, _p5##i = _p4##i, _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, \ - ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i, ++_n5##i, ++_n6##i, ++_n7##i, ++_n8##i, ++_n9##i, ++_n10##i, ++_n11##i, ++_n12##i, ++_n13##i, ++_n14##i, ++_n15##i, ++_n16##i) - -#define cimg_for_in32X(img,x0,x1,x) cimg_for_in32((img)._width,x0,x1,x) -#define cimg_for_in32Y(img,y0,y1,y) cimg_for_in32((img)._height,y0,y1,y) -#define cimg_for_in32Z(img,z0,z1,z) cimg_for_in32((img)._depth,z0,z1,z) -#define cimg_for_in32C(img,c0,c1,c) cimg_for_in32((img)._spectrum,c0,c1,c) -#define cimg_for_in32XY(img,x0,y0,x1,y1,x,y) cimg_for_in32Y(img,y0,y1,y) cimg_for_in32X(img,x0,x1,x) -#define cimg_for_in32XZ(img,x0,z0,x1,z1,x,z) cimg_for_in32Z(img,z0,z1,z) cimg_for_in32X(img,x0,x1,x) -#define cimg_for_in32XC(img,x0,c0,x1,c1,x,c) cimg_for_in32C(img,c0,c1,c) cimg_for_in32X(img,x0,x1,x) -#define cimg_for_in32YZ(img,y0,z0,y1,z1,y,z) cimg_for_in32Z(img,z0,z1,z) cimg_for_in32Y(img,y0,y1,y) -#define cimg_for_in32YC(img,y0,c0,y1,c1,y,c) cimg_for_in32C(img,c0,c1,c) cimg_for_in32Y(img,y0,y1,y) -#define cimg_for_in32ZC(img,z0,c0,z1,c1,z,c) cimg_for_in32C(img,c0,c1,c) cimg_for_in32Z(img,z0,z1,z) -#define cimg_for_in32XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in32Z(img,z0,z1,z) cimg_for_in32XY(img,x0,y0,x1,y1,x,y) -#define cimg_for_in32XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in32C(img,c0,c1,c) cimg_for_in32XZ(img,x0,y0,x1,y1,x,z) -#define cimg_for_in32YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in32C(img,c0,c1,c) cimg_for_in32YZ(img,y0,z0,y1,z1,y,z) -#define cimg_for_in32XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in32C(img,c0,c1,c) cimg_for_in32XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) - -#define cimg_for32x32(img,x,y,z,c,I,T) \ - cimg_for32((img)._height,y) for (int x = 0, \ - _p15##x = 0, _p14##x = 0, _p13##x = 0, _p12##x = 0, _p11##x = 0, _p10##x = 0, _p9##x = 0, _p8##x = 0, _p7##x = 0, _p6##x = 0, _p5##x = 0, _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = 4>=((img)._width)?(img).width() - 1:4, \ - _n5##x = 5>=((img)._width)?(img).width() - 1:5, \ - _n6##x = 6>=((img)._width)?(img).width() - 1:6, \ - _n7##x = 7>=((img)._width)?(img).width() - 1:7, \ - _n8##x = 8>=((img)._width)?(img).width() - 1:8, \ - _n9##x = 9>=((img)._width)?(img).width() - 1:9, \ - _n10##x = 10>=((img)._width)?(img).width() - 1:10, \ - _n11##x = 11>=((img)._width)?(img).width() - 1:11, \ - _n12##x = 12>=((img)._width)?(img).width() - 1:12, \ - _n13##x = 13>=((img)._width)?(img).width() - 1:13, \ - _n14##x = 14>=((img)._width)?(img).width() - 1:14, \ - _n15##x = 15>=((img)._width)?(img).width() - 1:15, \ - _n16##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = I[4] = I[5] = I[6] = I[7] = I[8] = I[9] = I[10] = I[11] = I[12] = I[13] = I[14] = I[15] = (T)(img)(0,_p15##y,z,c)), \ - (I[32] = I[33] = I[34] = I[35] = I[36] = I[37] = I[38] = I[39] = I[40] = I[41] = I[42] = I[43] = I[44] = I[45] = I[46] = I[47] = (T)(img)(0,_p14##y,z,c)), \ - (I[64] = I[65] = I[66] = I[67] = I[68] = I[69] = I[70] = I[71] = I[72] = I[73] = I[74] = I[75] = I[76] = I[77] = I[78] = I[79] = (T)(img)(0,_p13##y,z,c)), \ - (I[96] = I[97] = I[98] = I[99] = I[100] = I[101] = I[102] = I[103] = I[104] = I[105] = I[106] = I[107] = I[108] = I[109] = I[110] = I[111] = (T)(img)(0,_p12##y,z,c)), \ - (I[128] = I[129] = I[130] = I[131] = I[132] = I[133] = I[134] = I[135] = I[136] = I[137] = I[138] = I[139] = I[140] = I[141] = I[142] = I[143] = (T)(img)(0,_p11##y,z,c)), \ - (I[160] = I[161] = I[162] = I[163] = I[164] = I[165] = I[166] = I[167] = I[168] = I[169] = I[170] = I[171] = I[172] = I[173] = I[174] = I[175] = (T)(img)(0,_p10##y,z,c)), \ - (I[192] = I[193] = I[194] = I[195] = I[196] = I[197] = I[198] = I[199] = I[200] = I[201] = I[202] = I[203] = I[204] = I[205] = I[206] = I[207] = (T)(img)(0,_p9##y,z,c)), \ - (I[224] = I[225] = I[226] = I[227] = I[228] = I[229] = I[230] = I[231] = I[232] = I[233] = I[234] = I[235] = I[236] = I[237] = I[238] = I[239] = (T)(img)(0,_p8##y,z,c)), \ - (I[256] = I[257] = I[258] = I[259] = I[260] = I[261] = I[262] = I[263] = I[264] = I[265] = I[266] = I[267] = I[268] = I[269] = I[270] = I[271] = (T)(img)(0,_p7##y,z,c)), \ - (I[288] = I[289] = I[290] = I[291] = I[292] = I[293] = I[294] = I[295] = I[296] = I[297] = I[298] = I[299] = I[300] = I[301] = I[302] = I[303] = (T)(img)(0,_p6##y,z,c)), \ - (I[320] = I[321] = I[322] = I[323] = I[324] = I[325] = I[326] = I[327] = I[328] = I[329] = I[330] = I[331] = I[332] = I[333] = I[334] = I[335] = (T)(img)(0,_p5##y,z,c)), \ - (I[352] = I[353] = I[354] = I[355] = I[356] = I[357] = I[358] = I[359] = I[360] = I[361] = I[362] = I[363] = I[364] = I[365] = I[366] = I[367] = (T)(img)(0,_p4##y,z,c)), \ - (I[384] = I[385] = I[386] = I[387] = I[388] = I[389] = I[390] = I[391] = I[392] = I[393] = I[394] = I[395] = I[396] = I[397] = I[398] = I[399] = (T)(img)(0,_p3##y,z,c)), \ - (I[416] = I[417] = I[418] = I[419] = I[420] = I[421] = I[422] = I[423] = I[424] = I[425] = I[426] = I[427] = I[428] = I[429] = I[430] = I[431] = (T)(img)(0,_p2##y,z,c)), \ - (I[448] = I[449] = I[450] = I[451] = I[452] = I[453] = I[454] = I[455] = I[456] = I[457] = I[458] = I[459] = I[460] = I[461] = I[462] = I[463] = (T)(img)(0,_p1##y,z,c)), \ - (I[480] = I[481] = I[482] = I[483] = I[484] = I[485] = I[486] = I[487] = I[488] = I[489] = I[490] = I[491] = I[492] = I[493] = I[494] = I[495] = (T)(img)(0,y,z,c)), \ - (I[512] = I[513] = I[514] = I[515] = I[516] = I[517] = I[518] = I[519] = I[520] = I[521] = I[522] = I[523] = I[524] = I[525] = I[526] = I[527] = (T)(img)(0,_n1##y,z,c)), \ - (I[544] = I[545] = I[546] = I[547] = I[548] = I[549] = I[550] = I[551] = I[552] = I[553] = I[554] = I[555] = I[556] = I[557] = I[558] = I[559] = (T)(img)(0,_n2##y,z,c)), \ - (I[576] = I[577] = I[578] = I[579] = I[580] = I[581] = I[582] = I[583] = I[584] = I[585] = I[586] = I[587] = I[588] = I[589] = I[590] = I[591] = (T)(img)(0,_n3##y,z,c)), \ - (I[608] = I[609] = I[610] = I[611] = I[612] = I[613] = I[614] = I[615] = I[616] = I[617] = I[618] = I[619] = I[620] = I[621] = I[622] = I[623] = (T)(img)(0,_n4##y,z,c)), \ - (I[640] = I[641] = I[642] = I[643] = I[644] = I[645] = I[646] = I[647] = I[648] = I[649] = I[650] = I[651] = I[652] = I[653] = I[654] = I[655] = (T)(img)(0,_n5##y,z,c)), \ - (I[672] = I[673] = I[674] = I[675] = I[676] = I[677] = I[678] = I[679] = I[680] = I[681] = I[682] = I[683] = I[684] = I[685] = I[686] = I[687] = (T)(img)(0,_n6##y,z,c)), \ - (I[704] = I[705] = I[706] = I[707] = I[708] = I[709] = I[710] = I[711] = I[712] = I[713] = I[714] = I[715] = I[716] = I[717] = I[718] = I[719] = (T)(img)(0,_n7##y,z,c)), \ - (I[736] = I[737] = I[738] = I[739] = I[740] = I[741] = I[742] = I[743] = I[744] = I[745] = I[746] = I[747] = I[748] = I[749] = I[750] = I[751] = (T)(img)(0,_n8##y,z,c)), \ - (I[768] = I[769] = I[770] = I[771] = I[772] = I[773] = I[774] = I[775] = I[776] = I[777] = I[778] = I[779] = I[780] = I[781] = I[782] = I[783] = (T)(img)(0,_n9##y,z,c)), \ - (I[800] = I[801] = I[802] = I[803] = I[804] = I[805] = I[806] = I[807] = I[808] = I[809] = I[810] = I[811] = I[812] = I[813] = I[814] = I[815] = (T)(img)(0,_n10##y,z,c)), \ - (I[832] = I[833] = I[834] = I[835] = I[836] = I[837] = I[838] = I[839] = I[840] = I[841] = I[842] = I[843] = I[844] = I[845] = I[846] = I[847] = (T)(img)(0,_n11##y,z,c)), \ - (I[864] = I[865] = I[866] = I[867] = I[868] = I[869] = I[870] = I[871] = I[872] = I[873] = I[874] = I[875] = I[876] = I[877] = I[878] = I[879] = (T)(img)(0,_n12##y,z,c)), \ - (I[896] = I[897] = I[898] = I[899] = I[900] = I[901] = I[902] = I[903] = I[904] = I[905] = I[906] = I[907] = I[908] = I[909] = I[910] = I[911] = (T)(img)(0,_n13##y,z,c)), \ - (I[928] = I[929] = I[930] = I[931] = I[932] = I[933] = I[934] = I[935] = I[936] = I[937] = I[938] = I[939] = I[940] = I[941] = I[942] = I[943] = (T)(img)(0,_n14##y,z,c)), \ - (I[960] = I[961] = I[962] = I[963] = I[964] = I[965] = I[966] = I[967] = I[968] = I[969] = I[970] = I[971] = I[972] = I[973] = I[974] = I[975] = (T)(img)(0,_n15##y,z,c)), \ - (I[992] = I[993] = I[994] = I[995] = I[996] = I[997] = I[998] = I[999] = I[1000] = I[1001] = I[1002] = I[1003] = I[1004] = I[1005] = I[1006] = I[1007] = (T)(img)(0,_n16##y,z,c)), \ - (I[16] = (T)(img)(_n1##x,_p15##y,z,c)), \ - (I[48] = (T)(img)(_n1##x,_p14##y,z,c)), \ - (I[80] = (T)(img)(_n1##x,_p13##y,z,c)), \ - (I[112] = (T)(img)(_n1##x,_p12##y,z,c)), \ - (I[144] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[176] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[208] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[240] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[272] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[304] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[336] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[368] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[400] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[432] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[464] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[496] = (T)(img)(_n1##x,y,z,c)), \ - (I[528] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[560] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[592] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[624] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[656] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[688] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[720] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[752] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[784] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[816] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[848] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[880] = (T)(img)(_n1##x,_n12##y,z,c)), \ - (I[912] = (T)(img)(_n1##x,_n13##y,z,c)), \ - (I[944] = (T)(img)(_n1##x,_n14##y,z,c)), \ - (I[976] = (T)(img)(_n1##x,_n15##y,z,c)), \ - (I[1008] = (T)(img)(_n1##x,_n16##y,z,c)), \ - (I[17] = (T)(img)(_n2##x,_p15##y,z,c)), \ - (I[49] = (T)(img)(_n2##x,_p14##y,z,c)), \ - (I[81] = (T)(img)(_n2##x,_p13##y,z,c)), \ - (I[113] = (T)(img)(_n2##x,_p12##y,z,c)), \ - (I[145] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[177] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[209] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[241] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[273] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[305] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[337] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[369] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[401] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[433] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[465] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[497] = (T)(img)(_n2##x,y,z,c)), \ - (I[529] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[561] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[593] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[625] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[657] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[689] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[721] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[753] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[785] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[817] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[849] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[881] = (T)(img)(_n2##x,_n12##y,z,c)), \ - (I[913] = (T)(img)(_n2##x,_n13##y,z,c)), \ - (I[945] = (T)(img)(_n2##x,_n14##y,z,c)), \ - (I[977] = (T)(img)(_n2##x,_n15##y,z,c)), \ - (I[1009] = (T)(img)(_n2##x,_n16##y,z,c)), \ - (I[18] = (T)(img)(_n3##x,_p15##y,z,c)), \ - (I[50] = (T)(img)(_n3##x,_p14##y,z,c)), \ - (I[82] = (T)(img)(_n3##x,_p13##y,z,c)), \ - (I[114] = (T)(img)(_n3##x,_p12##y,z,c)), \ - (I[146] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[178] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[210] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[242] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[274] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[306] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[338] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[370] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[402] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[434] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[466] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[498] = (T)(img)(_n3##x,y,z,c)), \ - (I[530] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[562] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[594] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[626] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[658] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[690] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[722] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[754] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[786] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[818] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[850] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[882] = (T)(img)(_n3##x,_n12##y,z,c)), \ - (I[914] = (T)(img)(_n3##x,_n13##y,z,c)), \ - (I[946] = (T)(img)(_n3##x,_n14##y,z,c)), \ - (I[978] = (T)(img)(_n3##x,_n15##y,z,c)), \ - (I[1010] = (T)(img)(_n3##x,_n16##y,z,c)), \ - (I[19] = (T)(img)(_n4##x,_p15##y,z,c)), \ - (I[51] = (T)(img)(_n4##x,_p14##y,z,c)), \ - (I[83] = (T)(img)(_n4##x,_p13##y,z,c)), \ - (I[115] = (T)(img)(_n4##x,_p12##y,z,c)), \ - (I[147] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[179] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[211] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[243] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[275] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[307] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[339] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[371] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[403] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[435] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[467] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[499] = (T)(img)(_n4##x,y,z,c)), \ - (I[531] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[563] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[595] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[627] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[659] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[691] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[723] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[755] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[787] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[819] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[851] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[883] = (T)(img)(_n4##x,_n12##y,z,c)), \ - (I[915] = (T)(img)(_n4##x,_n13##y,z,c)), \ - (I[947] = (T)(img)(_n4##x,_n14##y,z,c)), \ - (I[979] = (T)(img)(_n4##x,_n15##y,z,c)), \ - (I[1011] = (T)(img)(_n4##x,_n16##y,z,c)), \ - (I[20] = (T)(img)(_n5##x,_p15##y,z,c)), \ - (I[52] = (T)(img)(_n5##x,_p14##y,z,c)), \ - (I[84] = (T)(img)(_n5##x,_p13##y,z,c)), \ - (I[116] = (T)(img)(_n5##x,_p12##y,z,c)), \ - (I[148] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[180] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[212] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[244] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[276] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[308] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[340] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[372] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[404] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[436] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[468] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[500] = (T)(img)(_n5##x,y,z,c)), \ - (I[532] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[564] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[596] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[628] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[660] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[692] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[724] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[756] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[788] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[820] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[852] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[884] = (T)(img)(_n5##x,_n12##y,z,c)), \ - (I[916] = (T)(img)(_n5##x,_n13##y,z,c)), \ - (I[948] = (T)(img)(_n5##x,_n14##y,z,c)), \ - (I[980] = (T)(img)(_n5##x,_n15##y,z,c)), \ - (I[1012] = (T)(img)(_n5##x,_n16##y,z,c)), \ - (I[21] = (T)(img)(_n6##x,_p15##y,z,c)), \ - (I[53] = (T)(img)(_n6##x,_p14##y,z,c)), \ - (I[85] = (T)(img)(_n6##x,_p13##y,z,c)), \ - (I[117] = (T)(img)(_n6##x,_p12##y,z,c)), \ - (I[149] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[181] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[213] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[245] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[277] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[309] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[341] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[373] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[405] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[437] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[469] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[501] = (T)(img)(_n6##x,y,z,c)), \ - (I[533] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[565] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[597] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[629] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[661] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[693] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[725] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[757] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[789] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[821] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[853] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[885] = (T)(img)(_n6##x,_n12##y,z,c)), \ - (I[917] = (T)(img)(_n6##x,_n13##y,z,c)), \ - (I[949] = (T)(img)(_n6##x,_n14##y,z,c)), \ - (I[981] = (T)(img)(_n6##x,_n15##y,z,c)), \ - (I[1013] = (T)(img)(_n6##x,_n16##y,z,c)), \ - (I[22] = (T)(img)(_n7##x,_p15##y,z,c)), \ - (I[54] = (T)(img)(_n7##x,_p14##y,z,c)), \ - (I[86] = (T)(img)(_n7##x,_p13##y,z,c)), \ - (I[118] = (T)(img)(_n7##x,_p12##y,z,c)), \ - (I[150] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[182] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[214] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[246] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[278] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[310] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[342] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[374] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[406] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[438] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[470] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[502] = (T)(img)(_n7##x,y,z,c)), \ - (I[534] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[566] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[598] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[630] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[662] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[694] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[726] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[758] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[790] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[822] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[854] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[886] = (T)(img)(_n7##x,_n12##y,z,c)), \ - (I[918] = (T)(img)(_n7##x,_n13##y,z,c)), \ - (I[950] = (T)(img)(_n7##x,_n14##y,z,c)), \ - (I[982] = (T)(img)(_n7##x,_n15##y,z,c)), \ - (I[1014] = (T)(img)(_n7##x,_n16##y,z,c)), \ - (I[23] = (T)(img)(_n8##x,_p15##y,z,c)), \ - (I[55] = (T)(img)(_n8##x,_p14##y,z,c)), \ - (I[87] = (T)(img)(_n8##x,_p13##y,z,c)), \ - (I[119] = (T)(img)(_n8##x,_p12##y,z,c)), \ - (I[151] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[183] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[215] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[247] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[279] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[311] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[343] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[375] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[407] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[439] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[471] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[503] = (T)(img)(_n8##x,y,z,c)), \ - (I[535] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[567] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[599] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[631] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[663] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[695] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[727] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[759] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[791] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[823] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[855] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[887] = (T)(img)(_n8##x,_n12##y,z,c)), \ - (I[919] = (T)(img)(_n8##x,_n13##y,z,c)), \ - (I[951] = (T)(img)(_n8##x,_n14##y,z,c)), \ - (I[983] = (T)(img)(_n8##x,_n15##y,z,c)), \ - (I[1015] = (T)(img)(_n8##x,_n16##y,z,c)), \ - (I[24] = (T)(img)(_n9##x,_p15##y,z,c)), \ - (I[56] = (T)(img)(_n9##x,_p14##y,z,c)), \ - (I[88] = (T)(img)(_n9##x,_p13##y,z,c)), \ - (I[120] = (T)(img)(_n9##x,_p12##y,z,c)), \ - (I[152] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[184] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[216] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[248] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[280] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[312] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[344] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[376] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[408] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[440] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[472] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[504] = (T)(img)(_n9##x,y,z,c)), \ - (I[536] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[568] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[600] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[632] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[664] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[696] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[728] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[760] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[792] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[824] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[856] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[888] = (T)(img)(_n9##x,_n12##y,z,c)), \ - (I[920] = (T)(img)(_n9##x,_n13##y,z,c)), \ - (I[952] = (T)(img)(_n9##x,_n14##y,z,c)), \ - (I[984] = (T)(img)(_n9##x,_n15##y,z,c)), \ - (I[1016] = (T)(img)(_n9##x,_n16##y,z,c)), \ - (I[25] = (T)(img)(_n10##x,_p15##y,z,c)), \ - (I[57] = (T)(img)(_n10##x,_p14##y,z,c)), \ - (I[89] = (T)(img)(_n10##x,_p13##y,z,c)), \ - (I[121] = (T)(img)(_n10##x,_p12##y,z,c)), \ - (I[153] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[185] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[217] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[249] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[281] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[313] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[345] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[377] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[409] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[441] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[473] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[505] = (T)(img)(_n10##x,y,z,c)), \ - (I[537] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[569] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[601] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[633] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[665] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[697] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[729] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[761] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[793] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[825] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[857] = (T)(img)(_n10##x,_n11##y,z,c)), \ - (I[889] = (T)(img)(_n10##x,_n12##y,z,c)), \ - (I[921] = (T)(img)(_n10##x,_n13##y,z,c)), \ - (I[953] = (T)(img)(_n10##x,_n14##y,z,c)), \ - (I[985] = (T)(img)(_n10##x,_n15##y,z,c)), \ - (I[1017] = (T)(img)(_n10##x,_n16##y,z,c)), \ - (I[26] = (T)(img)(_n11##x,_p15##y,z,c)), \ - (I[58] = (T)(img)(_n11##x,_p14##y,z,c)), \ - (I[90] = (T)(img)(_n11##x,_p13##y,z,c)), \ - (I[122] = (T)(img)(_n11##x,_p12##y,z,c)), \ - (I[154] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[186] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[218] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[250] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[282] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[314] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[346] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[378] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[410] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[442] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[474] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[506] = (T)(img)(_n11##x,y,z,c)), \ - (I[538] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[570] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[602] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[634] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[666] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[698] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[730] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[762] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[794] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[826] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[858] = (T)(img)(_n11##x,_n11##y,z,c)), \ - (I[890] = (T)(img)(_n11##x,_n12##y,z,c)), \ - (I[922] = (T)(img)(_n11##x,_n13##y,z,c)), \ - (I[954] = (T)(img)(_n11##x,_n14##y,z,c)), \ - (I[986] = (T)(img)(_n11##x,_n15##y,z,c)), \ - (I[1018] = (T)(img)(_n11##x,_n16##y,z,c)), \ - (I[27] = (T)(img)(_n12##x,_p15##y,z,c)), \ - (I[59] = (T)(img)(_n12##x,_p14##y,z,c)), \ - (I[91] = (T)(img)(_n12##x,_p13##y,z,c)), \ - (I[123] = (T)(img)(_n12##x,_p12##y,z,c)), \ - (I[155] = (T)(img)(_n12##x,_p11##y,z,c)), \ - (I[187] = (T)(img)(_n12##x,_p10##y,z,c)), \ - (I[219] = (T)(img)(_n12##x,_p9##y,z,c)), \ - (I[251] = (T)(img)(_n12##x,_p8##y,z,c)), \ - (I[283] = (T)(img)(_n12##x,_p7##y,z,c)), \ - (I[315] = (T)(img)(_n12##x,_p6##y,z,c)), \ - (I[347] = (T)(img)(_n12##x,_p5##y,z,c)), \ - (I[379] = (T)(img)(_n12##x,_p4##y,z,c)), \ - (I[411] = (T)(img)(_n12##x,_p3##y,z,c)), \ - (I[443] = (T)(img)(_n12##x,_p2##y,z,c)), \ - (I[475] = (T)(img)(_n12##x,_p1##y,z,c)), \ - (I[507] = (T)(img)(_n12##x,y,z,c)), \ - (I[539] = (T)(img)(_n12##x,_n1##y,z,c)), \ - (I[571] = (T)(img)(_n12##x,_n2##y,z,c)), \ - (I[603] = (T)(img)(_n12##x,_n3##y,z,c)), \ - (I[635] = (T)(img)(_n12##x,_n4##y,z,c)), \ - (I[667] = (T)(img)(_n12##x,_n5##y,z,c)), \ - (I[699] = (T)(img)(_n12##x,_n6##y,z,c)), \ - (I[731] = (T)(img)(_n12##x,_n7##y,z,c)), \ - (I[763] = (T)(img)(_n12##x,_n8##y,z,c)), \ - (I[795] = (T)(img)(_n12##x,_n9##y,z,c)), \ - (I[827] = (T)(img)(_n12##x,_n10##y,z,c)), \ - (I[859] = (T)(img)(_n12##x,_n11##y,z,c)), \ - (I[891] = (T)(img)(_n12##x,_n12##y,z,c)), \ - (I[923] = (T)(img)(_n12##x,_n13##y,z,c)), \ - (I[955] = (T)(img)(_n12##x,_n14##y,z,c)), \ - (I[987] = (T)(img)(_n12##x,_n15##y,z,c)), \ - (I[1019] = (T)(img)(_n12##x,_n16##y,z,c)), \ - (I[28] = (T)(img)(_n13##x,_p15##y,z,c)), \ - (I[60] = (T)(img)(_n13##x,_p14##y,z,c)), \ - (I[92] = (T)(img)(_n13##x,_p13##y,z,c)), \ - (I[124] = (T)(img)(_n13##x,_p12##y,z,c)), \ - (I[156] = (T)(img)(_n13##x,_p11##y,z,c)), \ - (I[188] = (T)(img)(_n13##x,_p10##y,z,c)), \ - (I[220] = (T)(img)(_n13##x,_p9##y,z,c)), \ - (I[252] = (T)(img)(_n13##x,_p8##y,z,c)), \ - (I[284] = (T)(img)(_n13##x,_p7##y,z,c)), \ - (I[316] = (T)(img)(_n13##x,_p6##y,z,c)), \ - (I[348] = (T)(img)(_n13##x,_p5##y,z,c)), \ - (I[380] = (T)(img)(_n13##x,_p4##y,z,c)), \ - (I[412] = (T)(img)(_n13##x,_p3##y,z,c)), \ - (I[444] = (T)(img)(_n13##x,_p2##y,z,c)), \ - (I[476] = (T)(img)(_n13##x,_p1##y,z,c)), \ - (I[508] = (T)(img)(_n13##x,y,z,c)), \ - (I[540] = (T)(img)(_n13##x,_n1##y,z,c)), \ - (I[572] = (T)(img)(_n13##x,_n2##y,z,c)), \ - (I[604] = (T)(img)(_n13##x,_n3##y,z,c)), \ - (I[636] = (T)(img)(_n13##x,_n4##y,z,c)), \ - (I[668] = (T)(img)(_n13##x,_n5##y,z,c)), \ - (I[700] = (T)(img)(_n13##x,_n6##y,z,c)), \ - (I[732] = (T)(img)(_n13##x,_n7##y,z,c)), \ - (I[764] = (T)(img)(_n13##x,_n8##y,z,c)), \ - (I[796] = (T)(img)(_n13##x,_n9##y,z,c)), \ - (I[828] = (T)(img)(_n13##x,_n10##y,z,c)), \ - (I[860] = (T)(img)(_n13##x,_n11##y,z,c)), \ - (I[892] = (T)(img)(_n13##x,_n12##y,z,c)), \ - (I[924] = (T)(img)(_n13##x,_n13##y,z,c)), \ - (I[956] = (T)(img)(_n13##x,_n14##y,z,c)), \ - (I[988] = (T)(img)(_n13##x,_n15##y,z,c)), \ - (I[1020] = (T)(img)(_n13##x,_n16##y,z,c)), \ - (I[29] = (T)(img)(_n14##x,_p15##y,z,c)), \ - (I[61] = (T)(img)(_n14##x,_p14##y,z,c)), \ - (I[93] = (T)(img)(_n14##x,_p13##y,z,c)), \ - (I[125] = (T)(img)(_n14##x,_p12##y,z,c)), \ - (I[157] = (T)(img)(_n14##x,_p11##y,z,c)), \ - (I[189] = (T)(img)(_n14##x,_p10##y,z,c)), \ - (I[221] = (T)(img)(_n14##x,_p9##y,z,c)), \ - (I[253] = (T)(img)(_n14##x,_p8##y,z,c)), \ - (I[285] = (T)(img)(_n14##x,_p7##y,z,c)), \ - (I[317] = (T)(img)(_n14##x,_p6##y,z,c)), \ - (I[349] = (T)(img)(_n14##x,_p5##y,z,c)), \ - (I[381] = (T)(img)(_n14##x,_p4##y,z,c)), \ - (I[413] = (T)(img)(_n14##x,_p3##y,z,c)), \ - (I[445] = (T)(img)(_n14##x,_p2##y,z,c)), \ - (I[477] = (T)(img)(_n14##x,_p1##y,z,c)), \ - (I[509] = (T)(img)(_n14##x,y,z,c)), \ - (I[541] = (T)(img)(_n14##x,_n1##y,z,c)), \ - (I[573] = (T)(img)(_n14##x,_n2##y,z,c)), \ - (I[605] = (T)(img)(_n14##x,_n3##y,z,c)), \ - (I[637] = (T)(img)(_n14##x,_n4##y,z,c)), \ - (I[669] = (T)(img)(_n14##x,_n5##y,z,c)), \ - (I[701] = (T)(img)(_n14##x,_n6##y,z,c)), \ - (I[733] = (T)(img)(_n14##x,_n7##y,z,c)), \ - (I[765] = (T)(img)(_n14##x,_n8##y,z,c)), \ - (I[797] = (T)(img)(_n14##x,_n9##y,z,c)), \ - (I[829] = (T)(img)(_n14##x,_n10##y,z,c)), \ - (I[861] = (T)(img)(_n14##x,_n11##y,z,c)), \ - (I[893] = (T)(img)(_n14##x,_n12##y,z,c)), \ - (I[925] = (T)(img)(_n14##x,_n13##y,z,c)), \ - (I[957] = (T)(img)(_n14##x,_n14##y,z,c)), \ - (I[989] = (T)(img)(_n14##x,_n15##y,z,c)), \ - (I[1021] = (T)(img)(_n14##x,_n16##y,z,c)), \ - (I[30] = (T)(img)(_n15##x,_p15##y,z,c)), \ - (I[62] = (T)(img)(_n15##x,_p14##y,z,c)), \ - (I[94] = (T)(img)(_n15##x,_p13##y,z,c)), \ - (I[126] = (T)(img)(_n15##x,_p12##y,z,c)), \ - (I[158] = (T)(img)(_n15##x,_p11##y,z,c)), \ - (I[190] = (T)(img)(_n15##x,_p10##y,z,c)), \ - (I[222] = (T)(img)(_n15##x,_p9##y,z,c)), \ - (I[254] = (T)(img)(_n15##x,_p8##y,z,c)), \ - (I[286] = (T)(img)(_n15##x,_p7##y,z,c)), \ - (I[318] = (T)(img)(_n15##x,_p6##y,z,c)), \ - (I[350] = (T)(img)(_n15##x,_p5##y,z,c)), \ - (I[382] = (T)(img)(_n15##x,_p4##y,z,c)), \ - (I[414] = (T)(img)(_n15##x,_p3##y,z,c)), \ - (I[446] = (T)(img)(_n15##x,_p2##y,z,c)), \ - (I[478] = (T)(img)(_n15##x,_p1##y,z,c)), \ - (I[510] = (T)(img)(_n15##x,y,z,c)), \ - (I[542] = (T)(img)(_n15##x,_n1##y,z,c)), \ - (I[574] = (T)(img)(_n15##x,_n2##y,z,c)), \ - (I[606] = (T)(img)(_n15##x,_n3##y,z,c)), \ - (I[638] = (T)(img)(_n15##x,_n4##y,z,c)), \ - (I[670] = (T)(img)(_n15##x,_n5##y,z,c)), \ - (I[702] = (T)(img)(_n15##x,_n6##y,z,c)), \ - (I[734] = (T)(img)(_n15##x,_n7##y,z,c)), \ - (I[766] = (T)(img)(_n15##x,_n8##y,z,c)), \ - (I[798] = (T)(img)(_n15##x,_n9##y,z,c)), \ - (I[830] = (T)(img)(_n15##x,_n10##y,z,c)), \ - (I[862] = (T)(img)(_n15##x,_n11##y,z,c)), \ - (I[894] = (T)(img)(_n15##x,_n12##y,z,c)), \ - (I[926] = (T)(img)(_n15##x,_n13##y,z,c)), \ - (I[958] = (T)(img)(_n15##x,_n14##y,z,c)), \ - (I[990] = (T)(img)(_n15##x,_n15##y,z,c)), \ - (I[1022] = (T)(img)(_n15##x,_n16##y,z,c)), \ - 16>=((img)._width)?(img).width() - 1:16); \ - (_n16##x<(img).width() && ( \ - (I[31] = (T)(img)(_n16##x,_p15##y,z,c)), \ - (I[63] = (T)(img)(_n16##x,_p14##y,z,c)), \ - (I[95] = (T)(img)(_n16##x,_p13##y,z,c)), \ - (I[127] = (T)(img)(_n16##x,_p12##y,z,c)), \ - (I[159] = (T)(img)(_n16##x,_p11##y,z,c)), \ - (I[191] = (T)(img)(_n16##x,_p10##y,z,c)), \ - (I[223] = (T)(img)(_n16##x,_p9##y,z,c)), \ - (I[255] = (T)(img)(_n16##x,_p8##y,z,c)), \ - (I[287] = (T)(img)(_n16##x,_p7##y,z,c)), \ - (I[319] = (T)(img)(_n16##x,_p6##y,z,c)), \ - (I[351] = (T)(img)(_n16##x,_p5##y,z,c)), \ - (I[383] = (T)(img)(_n16##x,_p4##y,z,c)), \ - (I[415] = (T)(img)(_n16##x,_p3##y,z,c)), \ - (I[447] = (T)(img)(_n16##x,_p2##y,z,c)), \ - (I[479] = (T)(img)(_n16##x,_p1##y,z,c)), \ - (I[511] = (T)(img)(_n16##x,y,z,c)), \ - (I[543] = (T)(img)(_n16##x,_n1##y,z,c)), \ - (I[575] = (T)(img)(_n16##x,_n2##y,z,c)), \ - (I[607] = (T)(img)(_n16##x,_n3##y,z,c)), \ - (I[639] = (T)(img)(_n16##x,_n4##y,z,c)), \ - (I[671] = (T)(img)(_n16##x,_n5##y,z,c)), \ - (I[703] = (T)(img)(_n16##x,_n6##y,z,c)), \ - (I[735] = (T)(img)(_n16##x,_n7##y,z,c)), \ - (I[767] = (T)(img)(_n16##x,_n8##y,z,c)), \ - (I[799] = (T)(img)(_n16##x,_n9##y,z,c)), \ - (I[831] = (T)(img)(_n16##x,_n10##y,z,c)), \ - (I[863] = (T)(img)(_n16##x,_n11##y,z,c)), \ - (I[895] = (T)(img)(_n16##x,_n12##y,z,c)), \ - (I[927] = (T)(img)(_n16##x,_n13##y,z,c)), \ - (I[959] = (T)(img)(_n16##x,_n14##y,z,c)), \ - (I[991] = (T)(img)(_n16##x,_n15##y,z,c)), \ - (I[1023] = (T)(img)(_n16##x,_n16##y,z,c)),1)) || \ - _n15##x==--_n16##x || _n14##x==--_n15##x || _n13##x==--_n14##x || _n12##x==--_n13##x || _n11##x==--_n12##x || _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n16##x = _n15##x = _n14##x = _n13##x = _n12##x = _n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], \ - I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], \ - I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], \ - I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], \ - I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], \ - I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], \ - I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], \ - I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], \ - I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], \ - I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], \ - I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], \ - I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], \ - I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], \ - I[416] = I[417], I[417] = I[418], I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], \ - I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], I[463] = I[464], I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], \ - I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], I[493] = I[494], I[494] = I[495], I[495] = I[496], I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], I[503] = I[504], I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], \ - I[512] = I[513], I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], I[519] = I[520], I[520] = I[521], I[521] = I[522], I[522] = I[523], I[523] = I[524], I[524] = I[525], I[525] = I[526], I[526] = I[527], I[527] = I[528], I[528] = I[529], I[529] = I[530], I[530] = I[531], I[531] = I[532], I[532] = I[533], I[533] = I[534], I[534] = I[535], I[535] = I[536], I[536] = I[537], I[537] = I[538], I[538] = I[539], I[539] = I[540], I[540] = I[541], I[541] = I[542], I[542] = I[543], \ - I[544] = I[545], I[545] = I[546], I[546] = I[547], I[547] = I[548], I[548] = I[549], I[549] = I[550], I[550] = I[551], I[551] = I[552], I[552] = I[553], I[553] = I[554], I[554] = I[555], I[555] = I[556], I[556] = I[557], I[557] = I[558], I[558] = I[559], I[559] = I[560], I[560] = I[561], I[561] = I[562], I[562] = I[563], I[563] = I[564], I[564] = I[565], I[565] = I[566], I[566] = I[567], I[567] = I[568], I[568] = I[569], I[569] = I[570], I[570] = I[571], I[571] = I[572], I[572] = I[573], I[573] = I[574], I[574] = I[575], \ - I[576] = I[577], I[577] = I[578], I[578] = I[579], I[579] = I[580], I[580] = I[581], I[581] = I[582], I[582] = I[583], I[583] = I[584], I[584] = I[585], I[585] = I[586], I[586] = I[587], I[587] = I[588], I[588] = I[589], I[589] = I[590], I[590] = I[591], I[591] = I[592], I[592] = I[593], I[593] = I[594], I[594] = I[595], I[595] = I[596], I[596] = I[597], I[597] = I[598], I[598] = I[599], I[599] = I[600], I[600] = I[601], I[601] = I[602], I[602] = I[603], I[603] = I[604], I[604] = I[605], I[605] = I[606], I[606] = I[607], \ - I[608] = I[609], I[609] = I[610], I[610] = I[611], I[611] = I[612], I[612] = I[613], I[613] = I[614], I[614] = I[615], I[615] = I[616], I[616] = I[617], I[617] = I[618], I[618] = I[619], I[619] = I[620], I[620] = I[621], I[621] = I[622], I[622] = I[623], I[623] = I[624], I[624] = I[625], I[625] = I[626], I[626] = I[627], I[627] = I[628], I[628] = I[629], I[629] = I[630], I[630] = I[631], I[631] = I[632], I[632] = I[633], I[633] = I[634], I[634] = I[635], I[635] = I[636], I[636] = I[637], I[637] = I[638], I[638] = I[639], \ - I[640] = I[641], I[641] = I[642], I[642] = I[643], I[643] = I[644], I[644] = I[645], I[645] = I[646], I[646] = I[647], I[647] = I[648], I[648] = I[649], I[649] = I[650], I[650] = I[651], I[651] = I[652], I[652] = I[653], I[653] = I[654], I[654] = I[655], I[655] = I[656], I[656] = I[657], I[657] = I[658], I[658] = I[659], I[659] = I[660], I[660] = I[661], I[661] = I[662], I[662] = I[663], I[663] = I[664], I[664] = I[665], I[665] = I[666], I[666] = I[667], I[667] = I[668], I[668] = I[669], I[669] = I[670], I[670] = I[671], \ - I[672] = I[673], I[673] = I[674], I[674] = I[675], I[675] = I[676], I[676] = I[677], I[677] = I[678], I[678] = I[679], I[679] = I[680], I[680] = I[681], I[681] = I[682], I[682] = I[683], I[683] = I[684], I[684] = I[685], I[685] = I[686], I[686] = I[687], I[687] = I[688], I[688] = I[689], I[689] = I[690], I[690] = I[691], I[691] = I[692], I[692] = I[693], I[693] = I[694], I[694] = I[695], I[695] = I[696], I[696] = I[697], I[697] = I[698], I[698] = I[699], I[699] = I[700], I[700] = I[701], I[701] = I[702], I[702] = I[703], \ - I[704] = I[705], I[705] = I[706], I[706] = I[707], I[707] = I[708], I[708] = I[709], I[709] = I[710], I[710] = I[711], I[711] = I[712], I[712] = I[713], I[713] = I[714], I[714] = I[715], I[715] = I[716], I[716] = I[717], I[717] = I[718], I[718] = I[719], I[719] = I[720], I[720] = I[721], I[721] = I[722], I[722] = I[723], I[723] = I[724], I[724] = I[725], I[725] = I[726], I[726] = I[727], I[727] = I[728], I[728] = I[729], I[729] = I[730], I[730] = I[731], I[731] = I[732], I[732] = I[733], I[733] = I[734], I[734] = I[735], \ - I[736] = I[737], I[737] = I[738], I[738] = I[739], I[739] = I[740], I[740] = I[741], I[741] = I[742], I[742] = I[743], I[743] = I[744], I[744] = I[745], I[745] = I[746], I[746] = I[747], I[747] = I[748], I[748] = I[749], I[749] = I[750], I[750] = I[751], I[751] = I[752], I[752] = I[753], I[753] = I[754], I[754] = I[755], I[755] = I[756], I[756] = I[757], I[757] = I[758], I[758] = I[759], I[759] = I[760], I[760] = I[761], I[761] = I[762], I[762] = I[763], I[763] = I[764], I[764] = I[765], I[765] = I[766], I[766] = I[767], \ - I[768] = I[769], I[769] = I[770], I[770] = I[771], I[771] = I[772], I[772] = I[773], I[773] = I[774], I[774] = I[775], I[775] = I[776], I[776] = I[777], I[777] = I[778], I[778] = I[779], I[779] = I[780], I[780] = I[781], I[781] = I[782], I[782] = I[783], I[783] = I[784], I[784] = I[785], I[785] = I[786], I[786] = I[787], I[787] = I[788], I[788] = I[789], I[789] = I[790], I[790] = I[791], I[791] = I[792], I[792] = I[793], I[793] = I[794], I[794] = I[795], I[795] = I[796], I[796] = I[797], I[797] = I[798], I[798] = I[799], \ - I[800] = I[801], I[801] = I[802], I[802] = I[803], I[803] = I[804], I[804] = I[805], I[805] = I[806], I[806] = I[807], I[807] = I[808], I[808] = I[809], I[809] = I[810], I[810] = I[811], I[811] = I[812], I[812] = I[813], I[813] = I[814], I[814] = I[815], I[815] = I[816], I[816] = I[817], I[817] = I[818], I[818] = I[819], I[819] = I[820], I[820] = I[821], I[821] = I[822], I[822] = I[823], I[823] = I[824], I[824] = I[825], I[825] = I[826], I[826] = I[827], I[827] = I[828], I[828] = I[829], I[829] = I[830], I[830] = I[831], \ - I[832] = I[833], I[833] = I[834], I[834] = I[835], I[835] = I[836], I[836] = I[837], I[837] = I[838], I[838] = I[839], I[839] = I[840], I[840] = I[841], I[841] = I[842], I[842] = I[843], I[843] = I[844], I[844] = I[845], I[845] = I[846], I[846] = I[847], I[847] = I[848], I[848] = I[849], I[849] = I[850], I[850] = I[851], I[851] = I[852], I[852] = I[853], I[853] = I[854], I[854] = I[855], I[855] = I[856], I[856] = I[857], I[857] = I[858], I[858] = I[859], I[859] = I[860], I[860] = I[861], I[861] = I[862], I[862] = I[863], \ - I[864] = I[865], I[865] = I[866], I[866] = I[867], I[867] = I[868], I[868] = I[869], I[869] = I[870], I[870] = I[871], I[871] = I[872], I[872] = I[873], I[873] = I[874], I[874] = I[875], I[875] = I[876], I[876] = I[877], I[877] = I[878], I[878] = I[879], I[879] = I[880], I[880] = I[881], I[881] = I[882], I[882] = I[883], I[883] = I[884], I[884] = I[885], I[885] = I[886], I[886] = I[887], I[887] = I[888], I[888] = I[889], I[889] = I[890], I[890] = I[891], I[891] = I[892], I[892] = I[893], I[893] = I[894], I[894] = I[895], \ - I[896] = I[897], I[897] = I[898], I[898] = I[899], I[899] = I[900], I[900] = I[901], I[901] = I[902], I[902] = I[903], I[903] = I[904], I[904] = I[905], I[905] = I[906], I[906] = I[907], I[907] = I[908], I[908] = I[909], I[909] = I[910], I[910] = I[911], I[911] = I[912], I[912] = I[913], I[913] = I[914], I[914] = I[915], I[915] = I[916], I[916] = I[917], I[917] = I[918], I[918] = I[919], I[919] = I[920], I[920] = I[921], I[921] = I[922], I[922] = I[923], I[923] = I[924], I[924] = I[925], I[925] = I[926], I[926] = I[927], \ - I[928] = I[929], I[929] = I[930], I[930] = I[931], I[931] = I[932], I[932] = I[933], I[933] = I[934], I[934] = I[935], I[935] = I[936], I[936] = I[937], I[937] = I[938], I[938] = I[939], I[939] = I[940], I[940] = I[941], I[941] = I[942], I[942] = I[943], I[943] = I[944], I[944] = I[945], I[945] = I[946], I[946] = I[947], I[947] = I[948], I[948] = I[949], I[949] = I[950], I[950] = I[951], I[951] = I[952], I[952] = I[953], I[953] = I[954], I[954] = I[955], I[955] = I[956], I[956] = I[957], I[957] = I[958], I[958] = I[959], \ - I[960] = I[961], I[961] = I[962], I[962] = I[963], I[963] = I[964], I[964] = I[965], I[965] = I[966], I[966] = I[967], I[967] = I[968], I[968] = I[969], I[969] = I[970], I[970] = I[971], I[971] = I[972], I[972] = I[973], I[973] = I[974], I[974] = I[975], I[975] = I[976], I[976] = I[977], I[977] = I[978], I[978] = I[979], I[979] = I[980], I[980] = I[981], I[981] = I[982], I[982] = I[983], I[983] = I[984], I[984] = I[985], I[985] = I[986], I[986] = I[987], I[987] = I[988], I[988] = I[989], I[989] = I[990], I[990] = I[991], \ - I[992] = I[993], I[993] = I[994], I[994] = I[995], I[995] = I[996], I[996] = I[997], I[997] = I[998], I[998] = I[999], I[999] = I[1000], I[1000] = I[1001], I[1001] = I[1002], I[1002] = I[1003], I[1003] = I[1004], I[1004] = I[1005], I[1005] = I[1006], I[1006] = I[1007], I[1007] = I[1008], I[1008] = I[1009], I[1009] = I[1010], I[1010] = I[1011], I[1011] = I[1012], I[1012] = I[1013], I[1013] = I[1014], I[1014] = I[1015], I[1015] = I[1016], I[1016] = I[1017], I[1017] = I[1018], I[1018] = I[1019], I[1019] = I[1020], I[1020] = I[1021], I[1021] = I[1022], I[1022] = I[1023], \ - _p15##x = _p14##x, _p14##x = _p13##x, _p13##x = _p12##x, _p12##x = _p11##x, _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x, ++_n12##x, ++_n13##x, ++_n14##x, ++_n15##x, ++_n16##x) - -#define cimg_for_in32x32(img,x0,y0,x1,y1,x,y,z,c,I,T) \ - cimg_for_in32((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p15##x = x - 15<0?0:x - 15, \ - _p14##x = x - 14<0?0:x - 14, \ - _p13##x = x - 13<0?0:x - 13, \ - _p12##x = x - 12<0?0:x - 12, \ - _p11##x = x - 11<0?0:x - 11, \ - _p10##x = x - 10<0?0:x - 10, \ - _p9##x = x - 9<0?0:x - 9, \ - _p8##x = x - 8<0?0:x - 8, \ - _p7##x = x - 7<0?0:x - 7, \ - _p6##x = x - 6<0?0:x - 6, \ - _p5##x = x - 5<0?0:x - 5, \ - _p4##x = x - 4<0?0:x - 4, \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = x + 4>=(img).width()?(img).width() - 1:x + 4, \ - _n5##x = x + 5>=(img).width()?(img).width() - 1:x + 5, \ - _n6##x = x + 6>=(img).width()?(img).width() - 1:x + 6, \ - _n7##x = x + 7>=(img).width()?(img).width() - 1:x + 7, \ - _n8##x = x + 8>=(img).width()?(img).width() - 1:x + 8, \ - _n9##x = x + 9>=(img).width()?(img).width() - 1:x + 9, \ - _n10##x = x + 10>=(img).width()?(img).width() - 1:x + 10, \ - _n11##x = x + 11>=(img).width()?(img).width() - 1:x + 11, \ - _n12##x = x + 12>=(img).width()?(img).width() - 1:x + 12, \ - _n13##x = x + 13>=(img).width()?(img).width() - 1:x + 13, \ - _n14##x = x + 14>=(img).width()?(img).width() - 1:x + 14, \ - _n15##x = x + 15>=(img).width()?(img).width() - 1:x + 15, \ - _n16##x = (int)( \ - (I[0] = (T)(img)(_p15##x,_p15##y,z,c)), \ - (I[32] = (T)(img)(_p15##x,_p14##y,z,c)), \ - (I[64] = (T)(img)(_p15##x,_p13##y,z,c)), \ - (I[96] = (T)(img)(_p15##x,_p12##y,z,c)), \ - (I[128] = (T)(img)(_p15##x,_p11##y,z,c)), \ - (I[160] = (T)(img)(_p15##x,_p10##y,z,c)), \ - (I[192] = (T)(img)(_p15##x,_p9##y,z,c)), \ - (I[224] = (T)(img)(_p15##x,_p8##y,z,c)), \ - (I[256] = (T)(img)(_p15##x,_p7##y,z,c)), \ - (I[288] = (T)(img)(_p15##x,_p6##y,z,c)), \ - (I[320] = (T)(img)(_p15##x,_p5##y,z,c)), \ - (I[352] = (T)(img)(_p15##x,_p4##y,z,c)), \ - (I[384] = (T)(img)(_p15##x,_p3##y,z,c)), \ - (I[416] = (T)(img)(_p15##x,_p2##y,z,c)), \ - (I[448] = (T)(img)(_p15##x,_p1##y,z,c)), \ - (I[480] = (T)(img)(_p15##x,y,z,c)), \ - (I[512] = (T)(img)(_p15##x,_n1##y,z,c)), \ - (I[544] = (T)(img)(_p15##x,_n2##y,z,c)), \ - (I[576] = (T)(img)(_p15##x,_n3##y,z,c)), \ - (I[608] = (T)(img)(_p15##x,_n4##y,z,c)), \ - (I[640] = (T)(img)(_p15##x,_n5##y,z,c)), \ - (I[672] = (T)(img)(_p15##x,_n6##y,z,c)), \ - (I[704] = (T)(img)(_p15##x,_n7##y,z,c)), \ - (I[736] = (T)(img)(_p15##x,_n8##y,z,c)), \ - (I[768] = (T)(img)(_p15##x,_n9##y,z,c)), \ - (I[800] = (T)(img)(_p15##x,_n10##y,z,c)), \ - (I[832] = (T)(img)(_p15##x,_n11##y,z,c)), \ - (I[864] = (T)(img)(_p15##x,_n12##y,z,c)), \ - (I[896] = (T)(img)(_p15##x,_n13##y,z,c)), \ - (I[928] = (T)(img)(_p15##x,_n14##y,z,c)), \ - (I[960] = (T)(img)(_p15##x,_n15##y,z,c)), \ - (I[992] = (T)(img)(_p15##x,_n16##y,z,c)), \ - (I[1] = (T)(img)(_p14##x,_p15##y,z,c)), \ - (I[33] = (T)(img)(_p14##x,_p14##y,z,c)), \ - (I[65] = (T)(img)(_p14##x,_p13##y,z,c)), \ - (I[97] = (T)(img)(_p14##x,_p12##y,z,c)), \ - (I[129] = (T)(img)(_p14##x,_p11##y,z,c)), \ - (I[161] = (T)(img)(_p14##x,_p10##y,z,c)), \ - (I[193] = (T)(img)(_p14##x,_p9##y,z,c)), \ - (I[225] = (T)(img)(_p14##x,_p8##y,z,c)), \ - (I[257] = (T)(img)(_p14##x,_p7##y,z,c)), \ - (I[289] = (T)(img)(_p14##x,_p6##y,z,c)), \ - (I[321] = (T)(img)(_p14##x,_p5##y,z,c)), \ - (I[353] = (T)(img)(_p14##x,_p4##y,z,c)), \ - (I[385] = (T)(img)(_p14##x,_p3##y,z,c)), \ - (I[417] = (T)(img)(_p14##x,_p2##y,z,c)), \ - (I[449] = (T)(img)(_p14##x,_p1##y,z,c)), \ - (I[481] = (T)(img)(_p14##x,y,z,c)), \ - (I[513] = (T)(img)(_p14##x,_n1##y,z,c)), \ - (I[545] = (T)(img)(_p14##x,_n2##y,z,c)), \ - (I[577] = (T)(img)(_p14##x,_n3##y,z,c)), \ - (I[609] = (T)(img)(_p14##x,_n4##y,z,c)), \ - (I[641] = (T)(img)(_p14##x,_n5##y,z,c)), \ - (I[673] = (T)(img)(_p14##x,_n6##y,z,c)), \ - (I[705] = (T)(img)(_p14##x,_n7##y,z,c)), \ - (I[737] = (T)(img)(_p14##x,_n8##y,z,c)), \ - (I[769] = (T)(img)(_p14##x,_n9##y,z,c)), \ - (I[801] = (T)(img)(_p14##x,_n10##y,z,c)), \ - (I[833] = (T)(img)(_p14##x,_n11##y,z,c)), \ - (I[865] = (T)(img)(_p14##x,_n12##y,z,c)), \ - (I[897] = (T)(img)(_p14##x,_n13##y,z,c)), \ - (I[929] = (T)(img)(_p14##x,_n14##y,z,c)), \ - (I[961] = (T)(img)(_p14##x,_n15##y,z,c)), \ - (I[993] = (T)(img)(_p14##x,_n16##y,z,c)), \ - (I[2] = (T)(img)(_p13##x,_p15##y,z,c)), \ - (I[34] = (T)(img)(_p13##x,_p14##y,z,c)), \ - (I[66] = (T)(img)(_p13##x,_p13##y,z,c)), \ - (I[98] = (T)(img)(_p13##x,_p12##y,z,c)), \ - (I[130] = (T)(img)(_p13##x,_p11##y,z,c)), \ - (I[162] = (T)(img)(_p13##x,_p10##y,z,c)), \ - (I[194] = (T)(img)(_p13##x,_p9##y,z,c)), \ - (I[226] = (T)(img)(_p13##x,_p8##y,z,c)), \ - (I[258] = (T)(img)(_p13##x,_p7##y,z,c)), \ - (I[290] = (T)(img)(_p13##x,_p6##y,z,c)), \ - (I[322] = (T)(img)(_p13##x,_p5##y,z,c)), \ - (I[354] = (T)(img)(_p13##x,_p4##y,z,c)), \ - (I[386] = (T)(img)(_p13##x,_p3##y,z,c)), \ - (I[418] = (T)(img)(_p13##x,_p2##y,z,c)), \ - (I[450] = (T)(img)(_p13##x,_p1##y,z,c)), \ - (I[482] = (T)(img)(_p13##x,y,z,c)), \ - (I[514] = (T)(img)(_p13##x,_n1##y,z,c)), \ - (I[546] = (T)(img)(_p13##x,_n2##y,z,c)), \ - (I[578] = (T)(img)(_p13##x,_n3##y,z,c)), \ - (I[610] = (T)(img)(_p13##x,_n4##y,z,c)), \ - (I[642] = (T)(img)(_p13##x,_n5##y,z,c)), \ - (I[674] = (T)(img)(_p13##x,_n6##y,z,c)), \ - (I[706] = (T)(img)(_p13##x,_n7##y,z,c)), \ - (I[738] = (T)(img)(_p13##x,_n8##y,z,c)), \ - (I[770] = (T)(img)(_p13##x,_n9##y,z,c)), \ - (I[802] = (T)(img)(_p13##x,_n10##y,z,c)), \ - (I[834] = (T)(img)(_p13##x,_n11##y,z,c)), \ - (I[866] = (T)(img)(_p13##x,_n12##y,z,c)), \ - (I[898] = (T)(img)(_p13##x,_n13##y,z,c)), \ - (I[930] = (T)(img)(_p13##x,_n14##y,z,c)), \ - (I[962] = (T)(img)(_p13##x,_n15##y,z,c)), \ - (I[994] = (T)(img)(_p13##x,_n16##y,z,c)), \ - (I[3] = (T)(img)(_p12##x,_p15##y,z,c)), \ - (I[35] = (T)(img)(_p12##x,_p14##y,z,c)), \ - (I[67] = (T)(img)(_p12##x,_p13##y,z,c)), \ - (I[99] = (T)(img)(_p12##x,_p12##y,z,c)), \ - (I[131] = (T)(img)(_p12##x,_p11##y,z,c)), \ - (I[163] = (T)(img)(_p12##x,_p10##y,z,c)), \ - (I[195] = (T)(img)(_p12##x,_p9##y,z,c)), \ - (I[227] = (T)(img)(_p12##x,_p8##y,z,c)), \ - (I[259] = (T)(img)(_p12##x,_p7##y,z,c)), \ - (I[291] = (T)(img)(_p12##x,_p6##y,z,c)), \ - (I[323] = (T)(img)(_p12##x,_p5##y,z,c)), \ - (I[355] = (T)(img)(_p12##x,_p4##y,z,c)), \ - (I[387] = (T)(img)(_p12##x,_p3##y,z,c)), \ - (I[419] = (T)(img)(_p12##x,_p2##y,z,c)), \ - (I[451] = (T)(img)(_p12##x,_p1##y,z,c)), \ - (I[483] = (T)(img)(_p12##x,y,z,c)), \ - (I[515] = (T)(img)(_p12##x,_n1##y,z,c)), \ - (I[547] = (T)(img)(_p12##x,_n2##y,z,c)), \ - (I[579] = (T)(img)(_p12##x,_n3##y,z,c)), \ - (I[611] = (T)(img)(_p12##x,_n4##y,z,c)), \ - (I[643] = (T)(img)(_p12##x,_n5##y,z,c)), \ - (I[675] = (T)(img)(_p12##x,_n6##y,z,c)), \ - (I[707] = (T)(img)(_p12##x,_n7##y,z,c)), \ - (I[739] = (T)(img)(_p12##x,_n8##y,z,c)), \ - (I[771] = (T)(img)(_p12##x,_n9##y,z,c)), \ - (I[803] = (T)(img)(_p12##x,_n10##y,z,c)), \ - (I[835] = (T)(img)(_p12##x,_n11##y,z,c)), \ - (I[867] = (T)(img)(_p12##x,_n12##y,z,c)), \ - (I[899] = (T)(img)(_p12##x,_n13##y,z,c)), \ - (I[931] = (T)(img)(_p12##x,_n14##y,z,c)), \ - (I[963] = (T)(img)(_p12##x,_n15##y,z,c)), \ - (I[995] = (T)(img)(_p12##x,_n16##y,z,c)), \ - (I[4] = (T)(img)(_p11##x,_p15##y,z,c)), \ - (I[36] = (T)(img)(_p11##x,_p14##y,z,c)), \ - (I[68] = (T)(img)(_p11##x,_p13##y,z,c)), \ - (I[100] = (T)(img)(_p11##x,_p12##y,z,c)), \ - (I[132] = (T)(img)(_p11##x,_p11##y,z,c)), \ - (I[164] = (T)(img)(_p11##x,_p10##y,z,c)), \ - (I[196] = (T)(img)(_p11##x,_p9##y,z,c)), \ - (I[228] = (T)(img)(_p11##x,_p8##y,z,c)), \ - (I[260] = (T)(img)(_p11##x,_p7##y,z,c)), \ - (I[292] = (T)(img)(_p11##x,_p6##y,z,c)), \ - (I[324] = (T)(img)(_p11##x,_p5##y,z,c)), \ - (I[356] = (T)(img)(_p11##x,_p4##y,z,c)), \ - (I[388] = (T)(img)(_p11##x,_p3##y,z,c)), \ - (I[420] = (T)(img)(_p11##x,_p2##y,z,c)), \ - (I[452] = (T)(img)(_p11##x,_p1##y,z,c)), \ - (I[484] = (T)(img)(_p11##x,y,z,c)), \ - (I[516] = (T)(img)(_p11##x,_n1##y,z,c)), \ - (I[548] = (T)(img)(_p11##x,_n2##y,z,c)), \ - (I[580] = (T)(img)(_p11##x,_n3##y,z,c)), \ - (I[612] = (T)(img)(_p11##x,_n4##y,z,c)), \ - (I[644] = (T)(img)(_p11##x,_n5##y,z,c)), \ - (I[676] = (T)(img)(_p11##x,_n6##y,z,c)), \ - (I[708] = (T)(img)(_p11##x,_n7##y,z,c)), \ - (I[740] = (T)(img)(_p11##x,_n8##y,z,c)), \ - (I[772] = (T)(img)(_p11##x,_n9##y,z,c)), \ - (I[804] = (T)(img)(_p11##x,_n10##y,z,c)), \ - (I[836] = (T)(img)(_p11##x,_n11##y,z,c)), \ - (I[868] = (T)(img)(_p11##x,_n12##y,z,c)), \ - (I[900] = (T)(img)(_p11##x,_n13##y,z,c)), \ - (I[932] = (T)(img)(_p11##x,_n14##y,z,c)), \ - (I[964] = (T)(img)(_p11##x,_n15##y,z,c)), \ - (I[996] = (T)(img)(_p11##x,_n16##y,z,c)), \ - (I[5] = (T)(img)(_p10##x,_p15##y,z,c)), \ - (I[37] = (T)(img)(_p10##x,_p14##y,z,c)), \ - (I[69] = (T)(img)(_p10##x,_p13##y,z,c)), \ - (I[101] = (T)(img)(_p10##x,_p12##y,z,c)), \ - (I[133] = (T)(img)(_p10##x,_p11##y,z,c)), \ - (I[165] = (T)(img)(_p10##x,_p10##y,z,c)), \ - (I[197] = (T)(img)(_p10##x,_p9##y,z,c)), \ - (I[229] = (T)(img)(_p10##x,_p8##y,z,c)), \ - (I[261] = (T)(img)(_p10##x,_p7##y,z,c)), \ - (I[293] = (T)(img)(_p10##x,_p6##y,z,c)), \ - (I[325] = (T)(img)(_p10##x,_p5##y,z,c)), \ - (I[357] = (T)(img)(_p10##x,_p4##y,z,c)), \ - (I[389] = (T)(img)(_p10##x,_p3##y,z,c)), \ - (I[421] = (T)(img)(_p10##x,_p2##y,z,c)), \ - (I[453] = (T)(img)(_p10##x,_p1##y,z,c)), \ - (I[485] = (T)(img)(_p10##x,y,z,c)), \ - (I[517] = (T)(img)(_p10##x,_n1##y,z,c)), \ - (I[549] = (T)(img)(_p10##x,_n2##y,z,c)), \ - (I[581] = (T)(img)(_p10##x,_n3##y,z,c)), \ - (I[613] = (T)(img)(_p10##x,_n4##y,z,c)), \ - (I[645] = (T)(img)(_p10##x,_n5##y,z,c)), \ - (I[677] = (T)(img)(_p10##x,_n6##y,z,c)), \ - (I[709] = (T)(img)(_p10##x,_n7##y,z,c)), \ - (I[741] = (T)(img)(_p10##x,_n8##y,z,c)), \ - (I[773] = (T)(img)(_p10##x,_n9##y,z,c)), \ - (I[805] = (T)(img)(_p10##x,_n10##y,z,c)), \ - (I[837] = (T)(img)(_p10##x,_n11##y,z,c)), \ - (I[869] = (T)(img)(_p10##x,_n12##y,z,c)), \ - (I[901] = (T)(img)(_p10##x,_n13##y,z,c)), \ - (I[933] = (T)(img)(_p10##x,_n14##y,z,c)), \ - (I[965] = (T)(img)(_p10##x,_n15##y,z,c)), \ - (I[997] = (T)(img)(_p10##x,_n16##y,z,c)), \ - (I[6] = (T)(img)(_p9##x,_p15##y,z,c)), \ - (I[38] = (T)(img)(_p9##x,_p14##y,z,c)), \ - (I[70] = (T)(img)(_p9##x,_p13##y,z,c)), \ - (I[102] = (T)(img)(_p9##x,_p12##y,z,c)), \ - (I[134] = (T)(img)(_p9##x,_p11##y,z,c)), \ - (I[166] = (T)(img)(_p9##x,_p10##y,z,c)), \ - (I[198] = (T)(img)(_p9##x,_p9##y,z,c)), \ - (I[230] = (T)(img)(_p9##x,_p8##y,z,c)), \ - (I[262] = (T)(img)(_p9##x,_p7##y,z,c)), \ - (I[294] = (T)(img)(_p9##x,_p6##y,z,c)), \ - (I[326] = (T)(img)(_p9##x,_p5##y,z,c)), \ - (I[358] = (T)(img)(_p9##x,_p4##y,z,c)), \ - (I[390] = (T)(img)(_p9##x,_p3##y,z,c)), \ - (I[422] = (T)(img)(_p9##x,_p2##y,z,c)), \ - (I[454] = (T)(img)(_p9##x,_p1##y,z,c)), \ - (I[486] = (T)(img)(_p9##x,y,z,c)), \ - (I[518] = (T)(img)(_p9##x,_n1##y,z,c)), \ - (I[550] = (T)(img)(_p9##x,_n2##y,z,c)), \ - (I[582] = (T)(img)(_p9##x,_n3##y,z,c)), \ - (I[614] = (T)(img)(_p9##x,_n4##y,z,c)), \ - (I[646] = (T)(img)(_p9##x,_n5##y,z,c)), \ - (I[678] = (T)(img)(_p9##x,_n6##y,z,c)), \ - (I[710] = (T)(img)(_p9##x,_n7##y,z,c)), \ - (I[742] = (T)(img)(_p9##x,_n8##y,z,c)), \ - (I[774] = (T)(img)(_p9##x,_n9##y,z,c)), \ - (I[806] = (T)(img)(_p9##x,_n10##y,z,c)), \ - (I[838] = (T)(img)(_p9##x,_n11##y,z,c)), \ - (I[870] = (T)(img)(_p9##x,_n12##y,z,c)), \ - (I[902] = (T)(img)(_p9##x,_n13##y,z,c)), \ - (I[934] = (T)(img)(_p9##x,_n14##y,z,c)), \ - (I[966] = (T)(img)(_p9##x,_n15##y,z,c)), \ - (I[998] = (T)(img)(_p9##x,_n16##y,z,c)), \ - (I[7] = (T)(img)(_p8##x,_p15##y,z,c)), \ - (I[39] = (T)(img)(_p8##x,_p14##y,z,c)), \ - (I[71] = (T)(img)(_p8##x,_p13##y,z,c)), \ - (I[103] = (T)(img)(_p8##x,_p12##y,z,c)), \ - (I[135] = (T)(img)(_p8##x,_p11##y,z,c)), \ - (I[167] = (T)(img)(_p8##x,_p10##y,z,c)), \ - (I[199] = (T)(img)(_p8##x,_p9##y,z,c)), \ - (I[231] = (T)(img)(_p8##x,_p8##y,z,c)), \ - (I[263] = (T)(img)(_p8##x,_p7##y,z,c)), \ - (I[295] = (T)(img)(_p8##x,_p6##y,z,c)), \ - (I[327] = (T)(img)(_p8##x,_p5##y,z,c)), \ - (I[359] = (T)(img)(_p8##x,_p4##y,z,c)), \ - (I[391] = (T)(img)(_p8##x,_p3##y,z,c)), \ - (I[423] = (T)(img)(_p8##x,_p2##y,z,c)), \ - (I[455] = (T)(img)(_p8##x,_p1##y,z,c)), \ - (I[487] = (T)(img)(_p8##x,y,z,c)), \ - (I[519] = (T)(img)(_p8##x,_n1##y,z,c)), \ - (I[551] = (T)(img)(_p8##x,_n2##y,z,c)), \ - (I[583] = (T)(img)(_p8##x,_n3##y,z,c)), \ - (I[615] = (T)(img)(_p8##x,_n4##y,z,c)), \ - (I[647] = (T)(img)(_p8##x,_n5##y,z,c)), \ - (I[679] = (T)(img)(_p8##x,_n6##y,z,c)), \ - (I[711] = (T)(img)(_p8##x,_n7##y,z,c)), \ - (I[743] = (T)(img)(_p8##x,_n8##y,z,c)), \ - (I[775] = (T)(img)(_p8##x,_n9##y,z,c)), \ - (I[807] = (T)(img)(_p8##x,_n10##y,z,c)), \ - (I[839] = (T)(img)(_p8##x,_n11##y,z,c)), \ - (I[871] = (T)(img)(_p8##x,_n12##y,z,c)), \ - (I[903] = (T)(img)(_p8##x,_n13##y,z,c)), \ - (I[935] = (T)(img)(_p8##x,_n14##y,z,c)), \ - (I[967] = (T)(img)(_p8##x,_n15##y,z,c)), \ - (I[999] = (T)(img)(_p8##x,_n16##y,z,c)), \ - (I[8] = (T)(img)(_p7##x,_p15##y,z,c)), \ - (I[40] = (T)(img)(_p7##x,_p14##y,z,c)), \ - (I[72] = (T)(img)(_p7##x,_p13##y,z,c)), \ - (I[104] = (T)(img)(_p7##x,_p12##y,z,c)), \ - (I[136] = (T)(img)(_p7##x,_p11##y,z,c)), \ - (I[168] = (T)(img)(_p7##x,_p10##y,z,c)), \ - (I[200] = (T)(img)(_p7##x,_p9##y,z,c)), \ - (I[232] = (T)(img)(_p7##x,_p8##y,z,c)), \ - (I[264] = (T)(img)(_p7##x,_p7##y,z,c)), \ - (I[296] = (T)(img)(_p7##x,_p6##y,z,c)), \ - (I[328] = (T)(img)(_p7##x,_p5##y,z,c)), \ - (I[360] = (T)(img)(_p7##x,_p4##y,z,c)), \ - (I[392] = (T)(img)(_p7##x,_p3##y,z,c)), \ - (I[424] = (T)(img)(_p7##x,_p2##y,z,c)), \ - (I[456] = (T)(img)(_p7##x,_p1##y,z,c)), \ - (I[488] = (T)(img)(_p7##x,y,z,c)), \ - (I[520] = (T)(img)(_p7##x,_n1##y,z,c)), \ - (I[552] = (T)(img)(_p7##x,_n2##y,z,c)), \ - (I[584] = (T)(img)(_p7##x,_n3##y,z,c)), \ - (I[616] = (T)(img)(_p7##x,_n4##y,z,c)), \ - (I[648] = (T)(img)(_p7##x,_n5##y,z,c)), \ - (I[680] = (T)(img)(_p7##x,_n6##y,z,c)), \ - (I[712] = (T)(img)(_p7##x,_n7##y,z,c)), \ - (I[744] = (T)(img)(_p7##x,_n8##y,z,c)), \ - (I[776] = (T)(img)(_p7##x,_n9##y,z,c)), \ - (I[808] = (T)(img)(_p7##x,_n10##y,z,c)), \ - (I[840] = (T)(img)(_p7##x,_n11##y,z,c)), \ - (I[872] = (T)(img)(_p7##x,_n12##y,z,c)), \ - (I[904] = (T)(img)(_p7##x,_n13##y,z,c)), \ - (I[936] = (T)(img)(_p7##x,_n14##y,z,c)), \ - (I[968] = (T)(img)(_p7##x,_n15##y,z,c)), \ - (I[1000] = (T)(img)(_p7##x,_n16##y,z,c)), \ - (I[9] = (T)(img)(_p6##x,_p15##y,z,c)), \ - (I[41] = (T)(img)(_p6##x,_p14##y,z,c)), \ - (I[73] = (T)(img)(_p6##x,_p13##y,z,c)), \ - (I[105] = (T)(img)(_p6##x,_p12##y,z,c)), \ - (I[137] = (T)(img)(_p6##x,_p11##y,z,c)), \ - (I[169] = (T)(img)(_p6##x,_p10##y,z,c)), \ - (I[201] = (T)(img)(_p6##x,_p9##y,z,c)), \ - (I[233] = (T)(img)(_p6##x,_p8##y,z,c)), \ - (I[265] = (T)(img)(_p6##x,_p7##y,z,c)), \ - (I[297] = (T)(img)(_p6##x,_p6##y,z,c)), \ - (I[329] = (T)(img)(_p6##x,_p5##y,z,c)), \ - (I[361] = (T)(img)(_p6##x,_p4##y,z,c)), \ - (I[393] = (T)(img)(_p6##x,_p3##y,z,c)), \ - (I[425] = (T)(img)(_p6##x,_p2##y,z,c)), \ - (I[457] = (T)(img)(_p6##x,_p1##y,z,c)), \ - (I[489] = (T)(img)(_p6##x,y,z,c)), \ - (I[521] = (T)(img)(_p6##x,_n1##y,z,c)), \ - (I[553] = (T)(img)(_p6##x,_n2##y,z,c)), \ - (I[585] = (T)(img)(_p6##x,_n3##y,z,c)), \ - (I[617] = (T)(img)(_p6##x,_n4##y,z,c)), \ - (I[649] = (T)(img)(_p6##x,_n5##y,z,c)), \ - (I[681] = (T)(img)(_p6##x,_n6##y,z,c)), \ - (I[713] = (T)(img)(_p6##x,_n7##y,z,c)), \ - (I[745] = (T)(img)(_p6##x,_n8##y,z,c)), \ - (I[777] = (T)(img)(_p6##x,_n9##y,z,c)), \ - (I[809] = (T)(img)(_p6##x,_n10##y,z,c)), \ - (I[841] = (T)(img)(_p6##x,_n11##y,z,c)), \ - (I[873] = (T)(img)(_p6##x,_n12##y,z,c)), \ - (I[905] = (T)(img)(_p6##x,_n13##y,z,c)), \ - (I[937] = (T)(img)(_p6##x,_n14##y,z,c)), \ - (I[969] = (T)(img)(_p6##x,_n15##y,z,c)), \ - (I[1001] = (T)(img)(_p6##x,_n16##y,z,c)), \ - (I[10] = (T)(img)(_p5##x,_p15##y,z,c)), \ - (I[42] = (T)(img)(_p5##x,_p14##y,z,c)), \ - (I[74] = (T)(img)(_p5##x,_p13##y,z,c)), \ - (I[106] = (T)(img)(_p5##x,_p12##y,z,c)), \ - (I[138] = (T)(img)(_p5##x,_p11##y,z,c)), \ - (I[170] = (T)(img)(_p5##x,_p10##y,z,c)), \ - (I[202] = (T)(img)(_p5##x,_p9##y,z,c)), \ - (I[234] = (T)(img)(_p5##x,_p8##y,z,c)), \ - (I[266] = (T)(img)(_p5##x,_p7##y,z,c)), \ - (I[298] = (T)(img)(_p5##x,_p6##y,z,c)), \ - (I[330] = (T)(img)(_p5##x,_p5##y,z,c)), \ - (I[362] = (T)(img)(_p5##x,_p4##y,z,c)), \ - (I[394] = (T)(img)(_p5##x,_p3##y,z,c)), \ - (I[426] = (T)(img)(_p5##x,_p2##y,z,c)), \ - (I[458] = (T)(img)(_p5##x,_p1##y,z,c)), \ - (I[490] = (T)(img)(_p5##x,y,z,c)), \ - (I[522] = (T)(img)(_p5##x,_n1##y,z,c)), \ - (I[554] = (T)(img)(_p5##x,_n2##y,z,c)), \ - (I[586] = (T)(img)(_p5##x,_n3##y,z,c)), \ - (I[618] = (T)(img)(_p5##x,_n4##y,z,c)), \ - (I[650] = (T)(img)(_p5##x,_n5##y,z,c)), \ - (I[682] = (T)(img)(_p5##x,_n6##y,z,c)), \ - (I[714] = (T)(img)(_p5##x,_n7##y,z,c)), \ - (I[746] = (T)(img)(_p5##x,_n8##y,z,c)), \ - (I[778] = (T)(img)(_p5##x,_n9##y,z,c)), \ - (I[810] = (T)(img)(_p5##x,_n10##y,z,c)), \ - (I[842] = (T)(img)(_p5##x,_n11##y,z,c)), \ - (I[874] = (T)(img)(_p5##x,_n12##y,z,c)), \ - (I[906] = (T)(img)(_p5##x,_n13##y,z,c)), \ - (I[938] = (T)(img)(_p5##x,_n14##y,z,c)), \ - (I[970] = (T)(img)(_p5##x,_n15##y,z,c)), \ - (I[1002] = (T)(img)(_p5##x,_n16##y,z,c)), \ - (I[11] = (T)(img)(_p4##x,_p15##y,z,c)), \ - (I[43] = (T)(img)(_p4##x,_p14##y,z,c)), \ - (I[75] = (T)(img)(_p4##x,_p13##y,z,c)), \ - (I[107] = (T)(img)(_p4##x,_p12##y,z,c)), \ - (I[139] = (T)(img)(_p4##x,_p11##y,z,c)), \ - (I[171] = (T)(img)(_p4##x,_p10##y,z,c)), \ - (I[203] = (T)(img)(_p4##x,_p9##y,z,c)), \ - (I[235] = (T)(img)(_p4##x,_p8##y,z,c)), \ - (I[267] = (T)(img)(_p4##x,_p7##y,z,c)), \ - (I[299] = (T)(img)(_p4##x,_p6##y,z,c)), \ - (I[331] = (T)(img)(_p4##x,_p5##y,z,c)), \ - (I[363] = (T)(img)(_p4##x,_p4##y,z,c)), \ - (I[395] = (T)(img)(_p4##x,_p3##y,z,c)), \ - (I[427] = (T)(img)(_p4##x,_p2##y,z,c)), \ - (I[459] = (T)(img)(_p4##x,_p1##y,z,c)), \ - (I[491] = (T)(img)(_p4##x,y,z,c)), \ - (I[523] = (T)(img)(_p4##x,_n1##y,z,c)), \ - (I[555] = (T)(img)(_p4##x,_n2##y,z,c)), \ - (I[587] = (T)(img)(_p4##x,_n3##y,z,c)), \ - (I[619] = (T)(img)(_p4##x,_n4##y,z,c)), \ - (I[651] = (T)(img)(_p4##x,_n5##y,z,c)), \ - (I[683] = (T)(img)(_p4##x,_n6##y,z,c)), \ - (I[715] = (T)(img)(_p4##x,_n7##y,z,c)), \ - (I[747] = (T)(img)(_p4##x,_n8##y,z,c)), \ - (I[779] = (T)(img)(_p4##x,_n9##y,z,c)), \ - (I[811] = (T)(img)(_p4##x,_n10##y,z,c)), \ - (I[843] = (T)(img)(_p4##x,_n11##y,z,c)), \ - (I[875] = (T)(img)(_p4##x,_n12##y,z,c)), \ - (I[907] = (T)(img)(_p4##x,_n13##y,z,c)), \ - (I[939] = (T)(img)(_p4##x,_n14##y,z,c)), \ - (I[971] = (T)(img)(_p4##x,_n15##y,z,c)), \ - (I[1003] = (T)(img)(_p4##x,_n16##y,z,c)), \ - (I[12] = (T)(img)(_p3##x,_p15##y,z,c)), \ - (I[44] = (T)(img)(_p3##x,_p14##y,z,c)), \ - (I[76] = (T)(img)(_p3##x,_p13##y,z,c)), \ - (I[108] = (T)(img)(_p3##x,_p12##y,z,c)), \ - (I[140] = (T)(img)(_p3##x,_p11##y,z,c)), \ - (I[172] = (T)(img)(_p3##x,_p10##y,z,c)), \ - (I[204] = (T)(img)(_p3##x,_p9##y,z,c)), \ - (I[236] = (T)(img)(_p3##x,_p8##y,z,c)), \ - (I[268] = (T)(img)(_p3##x,_p7##y,z,c)), \ - (I[300] = (T)(img)(_p3##x,_p6##y,z,c)), \ - (I[332] = (T)(img)(_p3##x,_p5##y,z,c)), \ - (I[364] = (T)(img)(_p3##x,_p4##y,z,c)), \ - (I[396] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[428] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[460] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[492] = (T)(img)(_p3##x,y,z,c)), \ - (I[524] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[556] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[588] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[620] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[652] = (T)(img)(_p3##x,_n5##y,z,c)), \ - (I[684] = (T)(img)(_p3##x,_n6##y,z,c)), \ - (I[716] = (T)(img)(_p3##x,_n7##y,z,c)), \ - (I[748] = (T)(img)(_p3##x,_n8##y,z,c)), \ - (I[780] = (T)(img)(_p3##x,_n9##y,z,c)), \ - (I[812] = (T)(img)(_p3##x,_n10##y,z,c)), \ - (I[844] = (T)(img)(_p3##x,_n11##y,z,c)), \ - (I[876] = (T)(img)(_p3##x,_n12##y,z,c)), \ - (I[908] = (T)(img)(_p3##x,_n13##y,z,c)), \ - (I[940] = (T)(img)(_p3##x,_n14##y,z,c)), \ - (I[972] = (T)(img)(_p3##x,_n15##y,z,c)), \ - (I[1004] = (T)(img)(_p3##x,_n16##y,z,c)), \ - (I[13] = (T)(img)(_p2##x,_p15##y,z,c)), \ - (I[45] = (T)(img)(_p2##x,_p14##y,z,c)), \ - (I[77] = (T)(img)(_p2##x,_p13##y,z,c)), \ - (I[109] = (T)(img)(_p2##x,_p12##y,z,c)), \ - (I[141] = (T)(img)(_p2##x,_p11##y,z,c)), \ - (I[173] = (T)(img)(_p2##x,_p10##y,z,c)), \ - (I[205] = (T)(img)(_p2##x,_p9##y,z,c)), \ - (I[237] = (T)(img)(_p2##x,_p8##y,z,c)), \ - (I[269] = (T)(img)(_p2##x,_p7##y,z,c)), \ - (I[301] = (T)(img)(_p2##x,_p6##y,z,c)), \ - (I[333] = (T)(img)(_p2##x,_p5##y,z,c)), \ - (I[365] = (T)(img)(_p2##x,_p4##y,z,c)), \ - (I[397] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[429] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[461] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[493] = (T)(img)(_p2##x,y,z,c)), \ - (I[525] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[557] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[589] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[621] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[653] = (T)(img)(_p2##x,_n5##y,z,c)), \ - (I[685] = (T)(img)(_p2##x,_n6##y,z,c)), \ - (I[717] = (T)(img)(_p2##x,_n7##y,z,c)), \ - (I[749] = (T)(img)(_p2##x,_n8##y,z,c)), \ - (I[781] = (T)(img)(_p2##x,_n9##y,z,c)), \ - (I[813] = (T)(img)(_p2##x,_n10##y,z,c)), \ - (I[845] = (T)(img)(_p2##x,_n11##y,z,c)), \ - (I[877] = (T)(img)(_p2##x,_n12##y,z,c)), \ - (I[909] = (T)(img)(_p2##x,_n13##y,z,c)), \ - (I[941] = (T)(img)(_p2##x,_n14##y,z,c)), \ - (I[973] = (T)(img)(_p2##x,_n15##y,z,c)), \ - (I[1005] = (T)(img)(_p2##x,_n16##y,z,c)), \ - (I[14] = (T)(img)(_p1##x,_p15##y,z,c)), \ - (I[46] = (T)(img)(_p1##x,_p14##y,z,c)), \ - (I[78] = (T)(img)(_p1##x,_p13##y,z,c)), \ - (I[110] = (T)(img)(_p1##x,_p12##y,z,c)), \ - (I[142] = (T)(img)(_p1##x,_p11##y,z,c)), \ - (I[174] = (T)(img)(_p1##x,_p10##y,z,c)), \ - (I[206] = (T)(img)(_p1##x,_p9##y,z,c)), \ - (I[238] = (T)(img)(_p1##x,_p8##y,z,c)), \ - (I[270] = (T)(img)(_p1##x,_p7##y,z,c)), \ - (I[302] = (T)(img)(_p1##x,_p6##y,z,c)), \ - (I[334] = (T)(img)(_p1##x,_p5##y,z,c)), \ - (I[366] = (T)(img)(_p1##x,_p4##y,z,c)), \ - (I[398] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[430] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[462] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[494] = (T)(img)(_p1##x,y,z,c)), \ - (I[526] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[558] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[590] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[622] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[654] = (T)(img)(_p1##x,_n5##y,z,c)), \ - (I[686] = (T)(img)(_p1##x,_n6##y,z,c)), \ - (I[718] = (T)(img)(_p1##x,_n7##y,z,c)), \ - (I[750] = (T)(img)(_p1##x,_n8##y,z,c)), \ - (I[782] = (T)(img)(_p1##x,_n9##y,z,c)), \ - (I[814] = (T)(img)(_p1##x,_n10##y,z,c)), \ - (I[846] = (T)(img)(_p1##x,_n11##y,z,c)), \ - (I[878] = (T)(img)(_p1##x,_n12##y,z,c)), \ - (I[910] = (T)(img)(_p1##x,_n13##y,z,c)), \ - (I[942] = (T)(img)(_p1##x,_n14##y,z,c)), \ - (I[974] = (T)(img)(_p1##x,_n15##y,z,c)), \ - (I[1006] = (T)(img)(_p1##x,_n16##y,z,c)), \ - (I[15] = (T)(img)(x,_p15##y,z,c)), \ - (I[47] = (T)(img)(x,_p14##y,z,c)), \ - (I[79] = (T)(img)(x,_p13##y,z,c)), \ - (I[111] = (T)(img)(x,_p12##y,z,c)), \ - (I[143] = (T)(img)(x,_p11##y,z,c)), \ - (I[175] = (T)(img)(x,_p10##y,z,c)), \ - (I[207] = (T)(img)(x,_p9##y,z,c)), \ - (I[239] = (T)(img)(x,_p8##y,z,c)), \ - (I[271] = (T)(img)(x,_p7##y,z,c)), \ - (I[303] = (T)(img)(x,_p6##y,z,c)), \ - (I[335] = (T)(img)(x,_p5##y,z,c)), \ - (I[367] = (T)(img)(x,_p4##y,z,c)), \ - (I[399] = (T)(img)(x,_p3##y,z,c)), \ - (I[431] = (T)(img)(x,_p2##y,z,c)), \ - (I[463] = (T)(img)(x,_p1##y,z,c)), \ - (I[495] = (T)(img)(x,y,z,c)), \ - (I[527] = (T)(img)(x,_n1##y,z,c)), \ - (I[559] = (T)(img)(x,_n2##y,z,c)), \ - (I[591] = (T)(img)(x,_n3##y,z,c)), \ - (I[623] = (T)(img)(x,_n4##y,z,c)), \ - (I[655] = (T)(img)(x,_n5##y,z,c)), \ - (I[687] = (T)(img)(x,_n6##y,z,c)), \ - (I[719] = (T)(img)(x,_n7##y,z,c)), \ - (I[751] = (T)(img)(x,_n8##y,z,c)), \ - (I[783] = (T)(img)(x,_n9##y,z,c)), \ - (I[815] = (T)(img)(x,_n10##y,z,c)), \ - (I[847] = (T)(img)(x,_n11##y,z,c)), \ - (I[879] = (T)(img)(x,_n12##y,z,c)), \ - (I[911] = (T)(img)(x,_n13##y,z,c)), \ - (I[943] = (T)(img)(x,_n14##y,z,c)), \ - (I[975] = (T)(img)(x,_n15##y,z,c)), \ - (I[1007] = (T)(img)(x,_n16##y,z,c)), \ - (I[16] = (T)(img)(_n1##x,_p15##y,z,c)), \ - (I[48] = (T)(img)(_n1##x,_p14##y,z,c)), \ - (I[80] = (T)(img)(_n1##x,_p13##y,z,c)), \ - (I[112] = (T)(img)(_n1##x,_p12##y,z,c)), \ - (I[144] = (T)(img)(_n1##x,_p11##y,z,c)), \ - (I[176] = (T)(img)(_n1##x,_p10##y,z,c)), \ - (I[208] = (T)(img)(_n1##x,_p9##y,z,c)), \ - (I[240] = (T)(img)(_n1##x,_p8##y,z,c)), \ - (I[272] = (T)(img)(_n1##x,_p7##y,z,c)), \ - (I[304] = (T)(img)(_n1##x,_p6##y,z,c)), \ - (I[336] = (T)(img)(_n1##x,_p5##y,z,c)), \ - (I[368] = (T)(img)(_n1##x,_p4##y,z,c)), \ - (I[400] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[432] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[464] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[496] = (T)(img)(_n1##x,y,z,c)), \ - (I[528] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[560] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[592] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[624] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[656] = (T)(img)(_n1##x,_n5##y,z,c)), \ - (I[688] = (T)(img)(_n1##x,_n6##y,z,c)), \ - (I[720] = (T)(img)(_n1##x,_n7##y,z,c)), \ - (I[752] = (T)(img)(_n1##x,_n8##y,z,c)), \ - (I[784] = (T)(img)(_n1##x,_n9##y,z,c)), \ - (I[816] = (T)(img)(_n1##x,_n10##y,z,c)), \ - (I[848] = (T)(img)(_n1##x,_n11##y,z,c)), \ - (I[880] = (T)(img)(_n1##x,_n12##y,z,c)), \ - (I[912] = (T)(img)(_n1##x,_n13##y,z,c)), \ - (I[944] = (T)(img)(_n1##x,_n14##y,z,c)), \ - (I[976] = (T)(img)(_n1##x,_n15##y,z,c)), \ - (I[1008] = (T)(img)(_n1##x,_n16##y,z,c)), \ - (I[17] = (T)(img)(_n2##x,_p15##y,z,c)), \ - (I[49] = (T)(img)(_n2##x,_p14##y,z,c)), \ - (I[81] = (T)(img)(_n2##x,_p13##y,z,c)), \ - (I[113] = (T)(img)(_n2##x,_p12##y,z,c)), \ - (I[145] = (T)(img)(_n2##x,_p11##y,z,c)), \ - (I[177] = (T)(img)(_n2##x,_p10##y,z,c)), \ - (I[209] = (T)(img)(_n2##x,_p9##y,z,c)), \ - (I[241] = (T)(img)(_n2##x,_p8##y,z,c)), \ - (I[273] = (T)(img)(_n2##x,_p7##y,z,c)), \ - (I[305] = (T)(img)(_n2##x,_p6##y,z,c)), \ - (I[337] = (T)(img)(_n2##x,_p5##y,z,c)), \ - (I[369] = (T)(img)(_n2##x,_p4##y,z,c)), \ - (I[401] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[433] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[465] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[497] = (T)(img)(_n2##x,y,z,c)), \ - (I[529] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[561] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[593] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[625] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[657] = (T)(img)(_n2##x,_n5##y,z,c)), \ - (I[689] = (T)(img)(_n2##x,_n6##y,z,c)), \ - (I[721] = (T)(img)(_n2##x,_n7##y,z,c)), \ - (I[753] = (T)(img)(_n2##x,_n8##y,z,c)), \ - (I[785] = (T)(img)(_n2##x,_n9##y,z,c)), \ - (I[817] = (T)(img)(_n2##x,_n10##y,z,c)), \ - (I[849] = (T)(img)(_n2##x,_n11##y,z,c)), \ - (I[881] = (T)(img)(_n2##x,_n12##y,z,c)), \ - (I[913] = (T)(img)(_n2##x,_n13##y,z,c)), \ - (I[945] = (T)(img)(_n2##x,_n14##y,z,c)), \ - (I[977] = (T)(img)(_n2##x,_n15##y,z,c)), \ - (I[1009] = (T)(img)(_n2##x,_n16##y,z,c)), \ - (I[18] = (T)(img)(_n3##x,_p15##y,z,c)), \ - (I[50] = (T)(img)(_n3##x,_p14##y,z,c)), \ - (I[82] = (T)(img)(_n3##x,_p13##y,z,c)), \ - (I[114] = (T)(img)(_n3##x,_p12##y,z,c)), \ - (I[146] = (T)(img)(_n3##x,_p11##y,z,c)), \ - (I[178] = (T)(img)(_n3##x,_p10##y,z,c)), \ - (I[210] = (T)(img)(_n3##x,_p9##y,z,c)), \ - (I[242] = (T)(img)(_n3##x,_p8##y,z,c)), \ - (I[274] = (T)(img)(_n3##x,_p7##y,z,c)), \ - (I[306] = (T)(img)(_n3##x,_p6##y,z,c)), \ - (I[338] = (T)(img)(_n3##x,_p5##y,z,c)), \ - (I[370] = (T)(img)(_n3##x,_p4##y,z,c)), \ - (I[402] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[434] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[466] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[498] = (T)(img)(_n3##x,y,z,c)), \ - (I[530] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[562] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[594] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[626] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[658] = (T)(img)(_n3##x,_n5##y,z,c)), \ - (I[690] = (T)(img)(_n3##x,_n6##y,z,c)), \ - (I[722] = (T)(img)(_n3##x,_n7##y,z,c)), \ - (I[754] = (T)(img)(_n3##x,_n8##y,z,c)), \ - (I[786] = (T)(img)(_n3##x,_n9##y,z,c)), \ - (I[818] = (T)(img)(_n3##x,_n10##y,z,c)), \ - (I[850] = (T)(img)(_n3##x,_n11##y,z,c)), \ - (I[882] = (T)(img)(_n3##x,_n12##y,z,c)), \ - (I[914] = (T)(img)(_n3##x,_n13##y,z,c)), \ - (I[946] = (T)(img)(_n3##x,_n14##y,z,c)), \ - (I[978] = (T)(img)(_n3##x,_n15##y,z,c)), \ - (I[1010] = (T)(img)(_n3##x,_n16##y,z,c)), \ - (I[19] = (T)(img)(_n4##x,_p15##y,z,c)), \ - (I[51] = (T)(img)(_n4##x,_p14##y,z,c)), \ - (I[83] = (T)(img)(_n4##x,_p13##y,z,c)), \ - (I[115] = (T)(img)(_n4##x,_p12##y,z,c)), \ - (I[147] = (T)(img)(_n4##x,_p11##y,z,c)), \ - (I[179] = (T)(img)(_n4##x,_p10##y,z,c)), \ - (I[211] = (T)(img)(_n4##x,_p9##y,z,c)), \ - (I[243] = (T)(img)(_n4##x,_p8##y,z,c)), \ - (I[275] = (T)(img)(_n4##x,_p7##y,z,c)), \ - (I[307] = (T)(img)(_n4##x,_p6##y,z,c)), \ - (I[339] = (T)(img)(_n4##x,_p5##y,z,c)), \ - (I[371] = (T)(img)(_n4##x,_p4##y,z,c)), \ - (I[403] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[435] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[467] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[499] = (T)(img)(_n4##x,y,z,c)), \ - (I[531] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[563] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[595] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[627] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[659] = (T)(img)(_n4##x,_n5##y,z,c)), \ - (I[691] = (T)(img)(_n4##x,_n6##y,z,c)), \ - (I[723] = (T)(img)(_n4##x,_n7##y,z,c)), \ - (I[755] = (T)(img)(_n4##x,_n8##y,z,c)), \ - (I[787] = (T)(img)(_n4##x,_n9##y,z,c)), \ - (I[819] = (T)(img)(_n4##x,_n10##y,z,c)), \ - (I[851] = (T)(img)(_n4##x,_n11##y,z,c)), \ - (I[883] = (T)(img)(_n4##x,_n12##y,z,c)), \ - (I[915] = (T)(img)(_n4##x,_n13##y,z,c)), \ - (I[947] = (T)(img)(_n4##x,_n14##y,z,c)), \ - (I[979] = (T)(img)(_n4##x,_n15##y,z,c)), \ - (I[1011] = (T)(img)(_n4##x,_n16##y,z,c)), \ - (I[20] = (T)(img)(_n5##x,_p15##y,z,c)), \ - (I[52] = (T)(img)(_n5##x,_p14##y,z,c)), \ - (I[84] = (T)(img)(_n5##x,_p13##y,z,c)), \ - (I[116] = (T)(img)(_n5##x,_p12##y,z,c)), \ - (I[148] = (T)(img)(_n5##x,_p11##y,z,c)), \ - (I[180] = (T)(img)(_n5##x,_p10##y,z,c)), \ - (I[212] = (T)(img)(_n5##x,_p9##y,z,c)), \ - (I[244] = (T)(img)(_n5##x,_p8##y,z,c)), \ - (I[276] = (T)(img)(_n5##x,_p7##y,z,c)), \ - (I[308] = (T)(img)(_n5##x,_p6##y,z,c)), \ - (I[340] = (T)(img)(_n5##x,_p5##y,z,c)), \ - (I[372] = (T)(img)(_n5##x,_p4##y,z,c)), \ - (I[404] = (T)(img)(_n5##x,_p3##y,z,c)), \ - (I[436] = (T)(img)(_n5##x,_p2##y,z,c)), \ - (I[468] = (T)(img)(_n5##x,_p1##y,z,c)), \ - (I[500] = (T)(img)(_n5##x,y,z,c)), \ - (I[532] = (T)(img)(_n5##x,_n1##y,z,c)), \ - (I[564] = (T)(img)(_n5##x,_n2##y,z,c)), \ - (I[596] = (T)(img)(_n5##x,_n3##y,z,c)), \ - (I[628] = (T)(img)(_n5##x,_n4##y,z,c)), \ - (I[660] = (T)(img)(_n5##x,_n5##y,z,c)), \ - (I[692] = (T)(img)(_n5##x,_n6##y,z,c)), \ - (I[724] = (T)(img)(_n5##x,_n7##y,z,c)), \ - (I[756] = (T)(img)(_n5##x,_n8##y,z,c)), \ - (I[788] = (T)(img)(_n5##x,_n9##y,z,c)), \ - (I[820] = (T)(img)(_n5##x,_n10##y,z,c)), \ - (I[852] = (T)(img)(_n5##x,_n11##y,z,c)), \ - (I[884] = (T)(img)(_n5##x,_n12##y,z,c)), \ - (I[916] = (T)(img)(_n5##x,_n13##y,z,c)), \ - (I[948] = (T)(img)(_n5##x,_n14##y,z,c)), \ - (I[980] = (T)(img)(_n5##x,_n15##y,z,c)), \ - (I[1012] = (T)(img)(_n5##x,_n16##y,z,c)), \ - (I[21] = (T)(img)(_n6##x,_p15##y,z,c)), \ - (I[53] = (T)(img)(_n6##x,_p14##y,z,c)), \ - (I[85] = (T)(img)(_n6##x,_p13##y,z,c)), \ - (I[117] = (T)(img)(_n6##x,_p12##y,z,c)), \ - (I[149] = (T)(img)(_n6##x,_p11##y,z,c)), \ - (I[181] = (T)(img)(_n6##x,_p10##y,z,c)), \ - (I[213] = (T)(img)(_n6##x,_p9##y,z,c)), \ - (I[245] = (T)(img)(_n6##x,_p8##y,z,c)), \ - (I[277] = (T)(img)(_n6##x,_p7##y,z,c)), \ - (I[309] = (T)(img)(_n6##x,_p6##y,z,c)), \ - (I[341] = (T)(img)(_n6##x,_p5##y,z,c)), \ - (I[373] = (T)(img)(_n6##x,_p4##y,z,c)), \ - (I[405] = (T)(img)(_n6##x,_p3##y,z,c)), \ - (I[437] = (T)(img)(_n6##x,_p2##y,z,c)), \ - (I[469] = (T)(img)(_n6##x,_p1##y,z,c)), \ - (I[501] = (T)(img)(_n6##x,y,z,c)), \ - (I[533] = (T)(img)(_n6##x,_n1##y,z,c)), \ - (I[565] = (T)(img)(_n6##x,_n2##y,z,c)), \ - (I[597] = (T)(img)(_n6##x,_n3##y,z,c)), \ - (I[629] = (T)(img)(_n6##x,_n4##y,z,c)), \ - (I[661] = (T)(img)(_n6##x,_n5##y,z,c)), \ - (I[693] = (T)(img)(_n6##x,_n6##y,z,c)), \ - (I[725] = (T)(img)(_n6##x,_n7##y,z,c)), \ - (I[757] = (T)(img)(_n6##x,_n8##y,z,c)), \ - (I[789] = (T)(img)(_n6##x,_n9##y,z,c)), \ - (I[821] = (T)(img)(_n6##x,_n10##y,z,c)), \ - (I[853] = (T)(img)(_n6##x,_n11##y,z,c)), \ - (I[885] = (T)(img)(_n6##x,_n12##y,z,c)), \ - (I[917] = (T)(img)(_n6##x,_n13##y,z,c)), \ - (I[949] = (T)(img)(_n6##x,_n14##y,z,c)), \ - (I[981] = (T)(img)(_n6##x,_n15##y,z,c)), \ - (I[1013] = (T)(img)(_n6##x,_n16##y,z,c)), \ - (I[22] = (T)(img)(_n7##x,_p15##y,z,c)), \ - (I[54] = (T)(img)(_n7##x,_p14##y,z,c)), \ - (I[86] = (T)(img)(_n7##x,_p13##y,z,c)), \ - (I[118] = (T)(img)(_n7##x,_p12##y,z,c)), \ - (I[150] = (T)(img)(_n7##x,_p11##y,z,c)), \ - (I[182] = (T)(img)(_n7##x,_p10##y,z,c)), \ - (I[214] = (T)(img)(_n7##x,_p9##y,z,c)), \ - (I[246] = (T)(img)(_n7##x,_p8##y,z,c)), \ - (I[278] = (T)(img)(_n7##x,_p7##y,z,c)), \ - (I[310] = (T)(img)(_n7##x,_p6##y,z,c)), \ - (I[342] = (T)(img)(_n7##x,_p5##y,z,c)), \ - (I[374] = (T)(img)(_n7##x,_p4##y,z,c)), \ - (I[406] = (T)(img)(_n7##x,_p3##y,z,c)), \ - (I[438] = (T)(img)(_n7##x,_p2##y,z,c)), \ - (I[470] = (T)(img)(_n7##x,_p1##y,z,c)), \ - (I[502] = (T)(img)(_n7##x,y,z,c)), \ - (I[534] = (T)(img)(_n7##x,_n1##y,z,c)), \ - (I[566] = (T)(img)(_n7##x,_n2##y,z,c)), \ - (I[598] = (T)(img)(_n7##x,_n3##y,z,c)), \ - (I[630] = (T)(img)(_n7##x,_n4##y,z,c)), \ - (I[662] = (T)(img)(_n7##x,_n5##y,z,c)), \ - (I[694] = (T)(img)(_n7##x,_n6##y,z,c)), \ - (I[726] = (T)(img)(_n7##x,_n7##y,z,c)), \ - (I[758] = (T)(img)(_n7##x,_n8##y,z,c)), \ - (I[790] = (T)(img)(_n7##x,_n9##y,z,c)), \ - (I[822] = (T)(img)(_n7##x,_n10##y,z,c)), \ - (I[854] = (T)(img)(_n7##x,_n11##y,z,c)), \ - (I[886] = (T)(img)(_n7##x,_n12##y,z,c)), \ - (I[918] = (T)(img)(_n7##x,_n13##y,z,c)), \ - (I[950] = (T)(img)(_n7##x,_n14##y,z,c)), \ - (I[982] = (T)(img)(_n7##x,_n15##y,z,c)), \ - (I[1014] = (T)(img)(_n7##x,_n16##y,z,c)), \ - (I[23] = (T)(img)(_n8##x,_p15##y,z,c)), \ - (I[55] = (T)(img)(_n8##x,_p14##y,z,c)), \ - (I[87] = (T)(img)(_n8##x,_p13##y,z,c)), \ - (I[119] = (T)(img)(_n8##x,_p12##y,z,c)), \ - (I[151] = (T)(img)(_n8##x,_p11##y,z,c)), \ - (I[183] = (T)(img)(_n8##x,_p10##y,z,c)), \ - (I[215] = (T)(img)(_n8##x,_p9##y,z,c)), \ - (I[247] = (T)(img)(_n8##x,_p8##y,z,c)), \ - (I[279] = (T)(img)(_n8##x,_p7##y,z,c)), \ - (I[311] = (T)(img)(_n8##x,_p6##y,z,c)), \ - (I[343] = (T)(img)(_n8##x,_p5##y,z,c)), \ - (I[375] = (T)(img)(_n8##x,_p4##y,z,c)), \ - (I[407] = (T)(img)(_n8##x,_p3##y,z,c)), \ - (I[439] = (T)(img)(_n8##x,_p2##y,z,c)), \ - (I[471] = (T)(img)(_n8##x,_p1##y,z,c)), \ - (I[503] = (T)(img)(_n8##x,y,z,c)), \ - (I[535] = (T)(img)(_n8##x,_n1##y,z,c)), \ - (I[567] = (T)(img)(_n8##x,_n2##y,z,c)), \ - (I[599] = (T)(img)(_n8##x,_n3##y,z,c)), \ - (I[631] = (T)(img)(_n8##x,_n4##y,z,c)), \ - (I[663] = (T)(img)(_n8##x,_n5##y,z,c)), \ - (I[695] = (T)(img)(_n8##x,_n6##y,z,c)), \ - (I[727] = (T)(img)(_n8##x,_n7##y,z,c)), \ - (I[759] = (T)(img)(_n8##x,_n8##y,z,c)), \ - (I[791] = (T)(img)(_n8##x,_n9##y,z,c)), \ - (I[823] = (T)(img)(_n8##x,_n10##y,z,c)), \ - (I[855] = (T)(img)(_n8##x,_n11##y,z,c)), \ - (I[887] = (T)(img)(_n8##x,_n12##y,z,c)), \ - (I[919] = (T)(img)(_n8##x,_n13##y,z,c)), \ - (I[951] = (T)(img)(_n8##x,_n14##y,z,c)), \ - (I[983] = (T)(img)(_n8##x,_n15##y,z,c)), \ - (I[1015] = (T)(img)(_n8##x,_n16##y,z,c)), \ - (I[24] = (T)(img)(_n9##x,_p15##y,z,c)), \ - (I[56] = (T)(img)(_n9##x,_p14##y,z,c)), \ - (I[88] = (T)(img)(_n9##x,_p13##y,z,c)), \ - (I[120] = (T)(img)(_n9##x,_p12##y,z,c)), \ - (I[152] = (T)(img)(_n9##x,_p11##y,z,c)), \ - (I[184] = (T)(img)(_n9##x,_p10##y,z,c)), \ - (I[216] = (T)(img)(_n9##x,_p9##y,z,c)), \ - (I[248] = (T)(img)(_n9##x,_p8##y,z,c)), \ - (I[280] = (T)(img)(_n9##x,_p7##y,z,c)), \ - (I[312] = (T)(img)(_n9##x,_p6##y,z,c)), \ - (I[344] = (T)(img)(_n9##x,_p5##y,z,c)), \ - (I[376] = (T)(img)(_n9##x,_p4##y,z,c)), \ - (I[408] = (T)(img)(_n9##x,_p3##y,z,c)), \ - (I[440] = (T)(img)(_n9##x,_p2##y,z,c)), \ - (I[472] = (T)(img)(_n9##x,_p1##y,z,c)), \ - (I[504] = (T)(img)(_n9##x,y,z,c)), \ - (I[536] = (T)(img)(_n9##x,_n1##y,z,c)), \ - (I[568] = (T)(img)(_n9##x,_n2##y,z,c)), \ - (I[600] = (T)(img)(_n9##x,_n3##y,z,c)), \ - (I[632] = (T)(img)(_n9##x,_n4##y,z,c)), \ - (I[664] = (T)(img)(_n9##x,_n5##y,z,c)), \ - (I[696] = (T)(img)(_n9##x,_n6##y,z,c)), \ - (I[728] = (T)(img)(_n9##x,_n7##y,z,c)), \ - (I[760] = (T)(img)(_n9##x,_n8##y,z,c)), \ - (I[792] = (T)(img)(_n9##x,_n9##y,z,c)), \ - (I[824] = (T)(img)(_n9##x,_n10##y,z,c)), \ - (I[856] = (T)(img)(_n9##x,_n11##y,z,c)), \ - (I[888] = (T)(img)(_n9##x,_n12##y,z,c)), \ - (I[920] = (T)(img)(_n9##x,_n13##y,z,c)), \ - (I[952] = (T)(img)(_n9##x,_n14##y,z,c)), \ - (I[984] = (T)(img)(_n9##x,_n15##y,z,c)), \ - (I[1016] = (T)(img)(_n9##x,_n16##y,z,c)), \ - (I[25] = (T)(img)(_n10##x,_p15##y,z,c)), \ - (I[57] = (T)(img)(_n10##x,_p14##y,z,c)), \ - (I[89] = (T)(img)(_n10##x,_p13##y,z,c)), \ - (I[121] = (T)(img)(_n10##x,_p12##y,z,c)), \ - (I[153] = (T)(img)(_n10##x,_p11##y,z,c)), \ - (I[185] = (T)(img)(_n10##x,_p10##y,z,c)), \ - (I[217] = (T)(img)(_n10##x,_p9##y,z,c)), \ - (I[249] = (T)(img)(_n10##x,_p8##y,z,c)), \ - (I[281] = (T)(img)(_n10##x,_p7##y,z,c)), \ - (I[313] = (T)(img)(_n10##x,_p6##y,z,c)), \ - (I[345] = (T)(img)(_n10##x,_p5##y,z,c)), \ - (I[377] = (T)(img)(_n10##x,_p4##y,z,c)), \ - (I[409] = (T)(img)(_n10##x,_p3##y,z,c)), \ - (I[441] = (T)(img)(_n10##x,_p2##y,z,c)), \ - (I[473] = (T)(img)(_n10##x,_p1##y,z,c)), \ - (I[505] = (T)(img)(_n10##x,y,z,c)), \ - (I[537] = (T)(img)(_n10##x,_n1##y,z,c)), \ - (I[569] = (T)(img)(_n10##x,_n2##y,z,c)), \ - (I[601] = (T)(img)(_n10##x,_n3##y,z,c)), \ - (I[633] = (T)(img)(_n10##x,_n4##y,z,c)), \ - (I[665] = (T)(img)(_n10##x,_n5##y,z,c)), \ - (I[697] = (T)(img)(_n10##x,_n6##y,z,c)), \ - (I[729] = (T)(img)(_n10##x,_n7##y,z,c)), \ - (I[761] = (T)(img)(_n10##x,_n8##y,z,c)), \ - (I[793] = (T)(img)(_n10##x,_n9##y,z,c)), \ - (I[825] = (T)(img)(_n10##x,_n10##y,z,c)), \ - (I[857] = (T)(img)(_n10##x,_n11##y,z,c)), \ - (I[889] = (T)(img)(_n10##x,_n12##y,z,c)), \ - (I[921] = (T)(img)(_n10##x,_n13##y,z,c)), \ - (I[953] = (T)(img)(_n10##x,_n14##y,z,c)), \ - (I[985] = (T)(img)(_n10##x,_n15##y,z,c)), \ - (I[1017] = (T)(img)(_n10##x,_n16##y,z,c)), \ - (I[26] = (T)(img)(_n11##x,_p15##y,z,c)), \ - (I[58] = (T)(img)(_n11##x,_p14##y,z,c)), \ - (I[90] = (T)(img)(_n11##x,_p13##y,z,c)), \ - (I[122] = (T)(img)(_n11##x,_p12##y,z,c)), \ - (I[154] = (T)(img)(_n11##x,_p11##y,z,c)), \ - (I[186] = (T)(img)(_n11##x,_p10##y,z,c)), \ - (I[218] = (T)(img)(_n11##x,_p9##y,z,c)), \ - (I[250] = (T)(img)(_n11##x,_p8##y,z,c)), \ - (I[282] = (T)(img)(_n11##x,_p7##y,z,c)), \ - (I[314] = (T)(img)(_n11##x,_p6##y,z,c)), \ - (I[346] = (T)(img)(_n11##x,_p5##y,z,c)), \ - (I[378] = (T)(img)(_n11##x,_p4##y,z,c)), \ - (I[410] = (T)(img)(_n11##x,_p3##y,z,c)), \ - (I[442] = (T)(img)(_n11##x,_p2##y,z,c)), \ - (I[474] = (T)(img)(_n11##x,_p1##y,z,c)), \ - (I[506] = (T)(img)(_n11##x,y,z,c)), \ - (I[538] = (T)(img)(_n11##x,_n1##y,z,c)), \ - (I[570] = (T)(img)(_n11##x,_n2##y,z,c)), \ - (I[602] = (T)(img)(_n11##x,_n3##y,z,c)), \ - (I[634] = (T)(img)(_n11##x,_n4##y,z,c)), \ - (I[666] = (T)(img)(_n11##x,_n5##y,z,c)), \ - (I[698] = (T)(img)(_n11##x,_n6##y,z,c)), \ - (I[730] = (T)(img)(_n11##x,_n7##y,z,c)), \ - (I[762] = (T)(img)(_n11##x,_n8##y,z,c)), \ - (I[794] = (T)(img)(_n11##x,_n9##y,z,c)), \ - (I[826] = (T)(img)(_n11##x,_n10##y,z,c)), \ - (I[858] = (T)(img)(_n11##x,_n11##y,z,c)), \ - (I[890] = (T)(img)(_n11##x,_n12##y,z,c)), \ - (I[922] = (T)(img)(_n11##x,_n13##y,z,c)), \ - (I[954] = (T)(img)(_n11##x,_n14##y,z,c)), \ - (I[986] = (T)(img)(_n11##x,_n15##y,z,c)), \ - (I[1018] = (T)(img)(_n11##x,_n16##y,z,c)), \ - (I[27] = (T)(img)(_n12##x,_p15##y,z,c)), \ - (I[59] = (T)(img)(_n12##x,_p14##y,z,c)), \ - (I[91] = (T)(img)(_n12##x,_p13##y,z,c)), \ - (I[123] = (T)(img)(_n12##x,_p12##y,z,c)), \ - (I[155] = (T)(img)(_n12##x,_p11##y,z,c)), \ - (I[187] = (T)(img)(_n12##x,_p10##y,z,c)), \ - (I[219] = (T)(img)(_n12##x,_p9##y,z,c)), \ - (I[251] = (T)(img)(_n12##x,_p8##y,z,c)), \ - (I[283] = (T)(img)(_n12##x,_p7##y,z,c)), \ - (I[315] = (T)(img)(_n12##x,_p6##y,z,c)), \ - (I[347] = (T)(img)(_n12##x,_p5##y,z,c)), \ - (I[379] = (T)(img)(_n12##x,_p4##y,z,c)), \ - (I[411] = (T)(img)(_n12##x,_p3##y,z,c)), \ - (I[443] = (T)(img)(_n12##x,_p2##y,z,c)), \ - (I[475] = (T)(img)(_n12##x,_p1##y,z,c)), \ - (I[507] = (T)(img)(_n12##x,y,z,c)), \ - (I[539] = (T)(img)(_n12##x,_n1##y,z,c)), \ - (I[571] = (T)(img)(_n12##x,_n2##y,z,c)), \ - (I[603] = (T)(img)(_n12##x,_n3##y,z,c)), \ - (I[635] = (T)(img)(_n12##x,_n4##y,z,c)), \ - (I[667] = (T)(img)(_n12##x,_n5##y,z,c)), \ - (I[699] = (T)(img)(_n12##x,_n6##y,z,c)), \ - (I[731] = (T)(img)(_n12##x,_n7##y,z,c)), \ - (I[763] = (T)(img)(_n12##x,_n8##y,z,c)), \ - (I[795] = (T)(img)(_n12##x,_n9##y,z,c)), \ - (I[827] = (T)(img)(_n12##x,_n10##y,z,c)), \ - (I[859] = (T)(img)(_n12##x,_n11##y,z,c)), \ - (I[891] = (T)(img)(_n12##x,_n12##y,z,c)), \ - (I[923] = (T)(img)(_n12##x,_n13##y,z,c)), \ - (I[955] = (T)(img)(_n12##x,_n14##y,z,c)), \ - (I[987] = (T)(img)(_n12##x,_n15##y,z,c)), \ - (I[1019] = (T)(img)(_n12##x,_n16##y,z,c)), \ - (I[28] = (T)(img)(_n13##x,_p15##y,z,c)), \ - (I[60] = (T)(img)(_n13##x,_p14##y,z,c)), \ - (I[92] = (T)(img)(_n13##x,_p13##y,z,c)), \ - (I[124] = (T)(img)(_n13##x,_p12##y,z,c)), \ - (I[156] = (T)(img)(_n13##x,_p11##y,z,c)), \ - (I[188] = (T)(img)(_n13##x,_p10##y,z,c)), \ - (I[220] = (T)(img)(_n13##x,_p9##y,z,c)), \ - (I[252] = (T)(img)(_n13##x,_p8##y,z,c)), \ - (I[284] = (T)(img)(_n13##x,_p7##y,z,c)), \ - (I[316] = (T)(img)(_n13##x,_p6##y,z,c)), \ - (I[348] = (T)(img)(_n13##x,_p5##y,z,c)), \ - (I[380] = (T)(img)(_n13##x,_p4##y,z,c)), \ - (I[412] = (T)(img)(_n13##x,_p3##y,z,c)), \ - (I[444] = (T)(img)(_n13##x,_p2##y,z,c)), \ - (I[476] = (T)(img)(_n13##x,_p1##y,z,c)), \ - (I[508] = (T)(img)(_n13##x,y,z,c)), \ - (I[540] = (T)(img)(_n13##x,_n1##y,z,c)), \ - (I[572] = (T)(img)(_n13##x,_n2##y,z,c)), \ - (I[604] = (T)(img)(_n13##x,_n3##y,z,c)), \ - (I[636] = (T)(img)(_n13##x,_n4##y,z,c)), \ - (I[668] = (T)(img)(_n13##x,_n5##y,z,c)), \ - (I[700] = (T)(img)(_n13##x,_n6##y,z,c)), \ - (I[732] = (T)(img)(_n13##x,_n7##y,z,c)), \ - (I[764] = (T)(img)(_n13##x,_n8##y,z,c)), \ - (I[796] = (T)(img)(_n13##x,_n9##y,z,c)), \ - (I[828] = (T)(img)(_n13##x,_n10##y,z,c)), \ - (I[860] = (T)(img)(_n13##x,_n11##y,z,c)), \ - (I[892] = (T)(img)(_n13##x,_n12##y,z,c)), \ - (I[924] = (T)(img)(_n13##x,_n13##y,z,c)), \ - (I[956] = (T)(img)(_n13##x,_n14##y,z,c)), \ - (I[988] = (T)(img)(_n13##x,_n15##y,z,c)), \ - (I[1020] = (T)(img)(_n13##x,_n16##y,z,c)), \ - (I[29] = (T)(img)(_n14##x,_p15##y,z,c)), \ - (I[61] = (T)(img)(_n14##x,_p14##y,z,c)), \ - (I[93] = (T)(img)(_n14##x,_p13##y,z,c)), \ - (I[125] = (T)(img)(_n14##x,_p12##y,z,c)), \ - (I[157] = (T)(img)(_n14##x,_p11##y,z,c)), \ - (I[189] = (T)(img)(_n14##x,_p10##y,z,c)), \ - (I[221] = (T)(img)(_n14##x,_p9##y,z,c)), \ - (I[253] = (T)(img)(_n14##x,_p8##y,z,c)), \ - (I[285] = (T)(img)(_n14##x,_p7##y,z,c)), \ - (I[317] = (T)(img)(_n14##x,_p6##y,z,c)), \ - (I[349] = (T)(img)(_n14##x,_p5##y,z,c)), \ - (I[381] = (T)(img)(_n14##x,_p4##y,z,c)), \ - (I[413] = (T)(img)(_n14##x,_p3##y,z,c)), \ - (I[445] = (T)(img)(_n14##x,_p2##y,z,c)), \ - (I[477] = (T)(img)(_n14##x,_p1##y,z,c)), \ - (I[509] = (T)(img)(_n14##x,y,z,c)), \ - (I[541] = (T)(img)(_n14##x,_n1##y,z,c)), \ - (I[573] = (T)(img)(_n14##x,_n2##y,z,c)), \ - (I[605] = (T)(img)(_n14##x,_n3##y,z,c)), \ - (I[637] = (T)(img)(_n14##x,_n4##y,z,c)), \ - (I[669] = (T)(img)(_n14##x,_n5##y,z,c)), \ - (I[701] = (T)(img)(_n14##x,_n6##y,z,c)), \ - (I[733] = (T)(img)(_n14##x,_n7##y,z,c)), \ - (I[765] = (T)(img)(_n14##x,_n8##y,z,c)), \ - (I[797] = (T)(img)(_n14##x,_n9##y,z,c)), \ - (I[829] = (T)(img)(_n14##x,_n10##y,z,c)), \ - (I[861] = (T)(img)(_n14##x,_n11##y,z,c)), \ - (I[893] = (T)(img)(_n14##x,_n12##y,z,c)), \ - (I[925] = (T)(img)(_n14##x,_n13##y,z,c)), \ - (I[957] = (T)(img)(_n14##x,_n14##y,z,c)), \ - (I[989] = (T)(img)(_n14##x,_n15##y,z,c)), \ - (I[1021] = (T)(img)(_n14##x,_n16##y,z,c)), \ - (I[30] = (T)(img)(_n15##x,_p15##y,z,c)), \ - (I[62] = (T)(img)(_n15##x,_p14##y,z,c)), \ - (I[94] = (T)(img)(_n15##x,_p13##y,z,c)), \ - (I[126] = (T)(img)(_n15##x,_p12##y,z,c)), \ - (I[158] = (T)(img)(_n15##x,_p11##y,z,c)), \ - (I[190] = (T)(img)(_n15##x,_p10##y,z,c)), \ - (I[222] = (T)(img)(_n15##x,_p9##y,z,c)), \ - (I[254] = (T)(img)(_n15##x,_p8##y,z,c)), \ - (I[286] = (T)(img)(_n15##x,_p7##y,z,c)), \ - (I[318] = (T)(img)(_n15##x,_p6##y,z,c)), \ - (I[350] = (T)(img)(_n15##x,_p5##y,z,c)), \ - (I[382] = (T)(img)(_n15##x,_p4##y,z,c)), \ - (I[414] = (T)(img)(_n15##x,_p3##y,z,c)), \ - (I[446] = (T)(img)(_n15##x,_p2##y,z,c)), \ - (I[478] = (T)(img)(_n15##x,_p1##y,z,c)), \ - (I[510] = (T)(img)(_n15##x,y,z,c)), \ - (I[542] = (T)(img)(_n15##x,_n1##y,z,c)), \ - (I[574] = (T)(img)(_n15##x,_n2##y,z,c)), \ - (I[606] = (T)(img)(_n15##x,_n3##y,z,c)), \ - (I[638] = (T)(img)(_n15##x,_n4##y,z,c)), \ - (I[670] = (T)(img)(_n15##x,_n5##y,z,c)), \ - (I[702] = (T)(img)(_n15##x,_n6##y,z,c)), \ - (I[734] = (T)(img)(_n15##x,_n7##y,z,c)), \ - (I[766] = (T)(img)(_n15##x,_n8##y,z,c)), \ - (I[798] = (T)(img)(_n15##x,_n9##y,z,c)), \ - (I[830] = (T)(img)(_n15##x,_n10##y,z,c)), \ - (I[862] = (T)(img)(_n15##x,_n11##y,z,c)), \ - (I[894] = (T)(img)(_n15##x,_n12##y,z,c)), \ - (I[926] = (T)(img)(_n15##x,_n13##y,z,c)), \ - (I[958] = (T)(img)(_n15##x,_n14##y,z,c)), \ - (I[990] = (T)(img)(_n15##x,_n15##y,z,c)), \ - (I[1022] = (T)(img)(_n15##x,_n16##y,z,c)), \ - x + 16>=(img).width()?(img).width() - 1:x + 16); \ - x<=(int)(x1) && ((_n16##x<(img).width() && ( \ - (I[31] = (T)(img)(_n16##x,_p15##y,z,c)), \ - (I[63] = (T)(img)(_n16##x,_p14##y,z,c)), \ - (I[95] = (T)(img)(_n16##x,_p13##y,z,c)), \ - (I[127] = (T)(img)(_n16##x,_p12##y,z,c)), \ - (I[159] = (T)(img)(_n16##x,_p11##y,z,c)), \ - (I[191] = (T)(img)(_n16##x,_p10##y,z,c)), \ - (I[223] = (T)(img)(_n16##x,_p9##y,z,c)), \ - (I[255] = (T)(img)(_n16##x,_p8##y,z,c)), \ - (I[287] = (T)(img)(_n16##x,_p7##y,z,c)), \ - (I[319] = (T)(img)(_n16##x,_p6##y,z,c)), \ - (I[351] = (T)(img)(_n16##x,_p5##y,z,c)), \ - (I[383] = (T)(img)(_n16##x,_p4##y,z,c)), \ - (I[415] = (T)(img)(_n16##x,_p3##y,z,c)), \ - (I[447] = (T)(img)(_n16##x,_p2##y,z,c)), \ - (I[479] = (T)(img)(_n16##x,_p1##y,z,c)), \ - (I[511] = (T)(img)(_n16##x,y,z,c)), \ - (I[543] = (T)(img)(_n16##x,_n1##y,z,c)), \ - (I[575] = (T)(img)(_n16##x,_n2##y,z,c)), \ - (I[607] = (T)(img)(_n16##x,_n3##y,z,c)), \ - (I[639] = (T)(img)(_n16##x,_n4##y,z,c)), \ - (I[671] = (T)(img)(_n16##x,_n5##y,z,c)), \ - (I[703] = (T)(img)(_n16##x,_n6##y,z,c)), \ - (I[735] = (T)(img)(_n16##x,_n7##y,z,c)), \ - (I[767] = (T)(img)(_n16##x,_n8##y,z,c)), \ - (I[799] = (T)(img)(_n16##x,_n9##y,z,c)), \ - (I[831] = (T)(img)(_n16##x,_n10##y,z,c)), \ - (I[863] = (T)(img)(_n16##x,_n11##y,z,c)), \ - (I[895] = (T)(img)(_n16##x,_n12##y,z,c)), \ - (I[927] = (T)(img)(_n16##x,_n13##y,z,c)), \ - (I[959] = (T)(img)(_n16##x,_n14##y,z,c)), \ - (I[991] = (T)(img)(_n16##x,_n15##y,z,c)), \ - (I[1023] = (T)(img)(_n16##x,_n16##y,z,c)),1)) || \ - _n15##x==--_n16##x || _n14##x==--_n15##x || _n13##x==--_n14##x || _n12##x==--_n13##x || _n11##x==--_n12##x || _n10##x==--_n11##x || _n9##x==--_n10##x || _n8##x==--_n9##x || _n7##x==--_n8##x || _n6##x==--_n7##x || _n5##x==--_n6##x || _n4##x==--_n5##x || _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n16##x = _n15##x = _n14##x = _n13##x = _n12##x = _n11##x = _n10##x = _n9##x = _n8##x = _n7##x = _n6##x = _n5##x = _n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], \ - I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], \ - I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], \ - I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], \ - I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], \ - I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], I[167] = I[168], I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], \ - I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], \ - I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], \ - I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], I[279] = I[280], I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], \ - I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], \ - I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], I[335] = I[336], I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], I[343] = I[344], I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], \ - I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], I[359] = I[360], I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], I[367] = I[368], I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], I[375] = I[376], I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], \ - I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], I[391] = I[392], I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], I[399] = I[400], I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], I[407] = I[408], I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], \ - I[416] = I[417], I[417] = I[418], I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], I[423] = I[424], I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], I[431] = I[432], I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], I[439] = I[440], I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], \ - I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], I[455] = I[456], I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], I[463] = I[464], I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], I[471] = I[472], I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], \ - I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], I[487] = I[488], I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], I[493] = I[494], I[494] = I[495], I[495] = I[496], I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], I[503] = I[504], I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], \ - I[512] = I[513], I[513] = I[514], I[514] = I[515], I[515] = I[516], I[516] = I[517], I[517] = I[518], I[518] = I[519], I[519] = I[520], I[520] = I[521], I[521] = I[522], I[522] = I[523], I[523] = I[524], I[524] = I[525], I[525] = I[526], I[526] = I[527], I[527] = I[528], I[528] = I[529], I[529] = I[530], I[530] = I[531], I[531] = I[532], I[532] = I[533], I[533] = I[534], I[534] = I[535], I[535] = I[536], I[536] = I[537], I[537] = I[538], I[538] = I[539], I[539] = I[540], I[540] = I[541], I[541] = I[542], I[542] = I[543], \ - I[544] = I[545], I[545] = I[546], I[546] = I[547], I[547] = I[548], I[548] = I[549], I[549] = I[550], I[550] = I[551], I[551] = I[552], I[552] = I[553], I[553] = I[554], I[554] = I[555], I[555] = I[556], I[556] = I[557], I[557] = I[558], I[558] = I[559], I[559] = I[560], I[560] = I[561], I[561] = I[562], I[562] = I[563], I[563] = I[564], I[564] = I[565], I[565] = I[566], I[566] = I[567], I[567] = I[568], I[568] = I[569], I[569] = I[570], I[570] = I[571], I[571] = I[572], I[572] = I[573], I[573] = I[574], I[574] = I[575], \ - I[576] = I[577], I[577] = I[578], I[578] = I[579], I[579] = I[580], I[580] = I[581], I[581] = I[582], I[582] = I[583], I[583] = I[584], I[584] = I[585], I[585] = I[586], I[586] = I[587], I[587] = I[588], I[588] = I[589], I[589] = I[590], I[590] = I[591], I[591] = I[592], I[592] = I[593], I[593] = I[594], I[594] = I[595], I[595] = I[596], I[596] = I[597], I[597] = I[598], I[598] = I[599], I[599] = I[600], I[600] = I[601], I[601] = I[602], I[602] = I[603], I[603] = I[604], I[604] = I[605], I[605] = I[606], I[606] = I[607], \ - I[608] = I[609], I[609] = I[610], I[610] = I[611], I[611] = I[612], I[612] = I[613], I[613] = I[614], I[614] = I[615], I[615] = I[616], I[616] = I[617], I[617] = I[618], I[618] = I[619], I[619] = I[620], I[620] = I[621], I[621] = I[622], I[622] = I[623], I[623] = I[624], I[624] = I[625], I[625] = I[626], I[626] = I[627], I[627] = I[628], I[628] = I[629], I[629] = I[630], I[630] = I[631], I[631] = I[632], I[632] = I[633], I[633] = I[634], I[634] = I[635], I[635] = I[636], I[636] = I[637], I[637] = I[638], I[638] = I[639], \ - I[640] = I[641], I[641] = I[642], I[642] = I[643], I[643] = I[644], I[644] = I[645], I[645] = I[646], I[646] = I[647], I[647] = I[648], I[648] = I[649], I[649] = I[650], I[650] = I[651], I[651] = I[652], I[652] = I[653], I[653] = I[654], I[654] = I[655], I[655] = I[656], I[656] = I[657], I[657] = I[658], I[658] = I[659], I[659] = I[660], I[660] = I[661], I[661] = I[662], I[662] = I[663], I[663] = I[664], I[664] = I[665], I[665] = I[666], I[666] = I[667], I[667] = I[668], I[668] = I[669], I[669] = I[670], I[670] = I[671], \ - I[672] = I[673], I[673] = I[674], I[674] = I[675], I[675] = I[676], I[676] = I[677], I[677] = I[678], I[678] = I[679], I[679] = I[680], I[680] = I[681], I[681] = I[682], I[682] = I[683], I[683] = I[684], I[684] = I[685], I[685] = I[686], I[686] = I[687], I[687] = I[688], I[688] = I[689], I[689] = I[690], I[690] = I[691], I[691] = I[692], I[692] = I[693], I[693] = I[694], I[694] = I[695], I[695] = I[696], I[696] = I[697], I[697] = I[698], I[698] = I[699], I[699] = I[700], I[700] = I[701], I[701] = I[702], I[702] = I[703], \ - I[704] = I[705], I[705] = I[706], I[706] = I[707], I[707] = I[708], I[708] = I[709], I[709] = I[710], I[710] = I[711], I[711] = I[712], I[712] = I[713], I[713] = I[714], I[714] = I[715], I[715] = I[716], I[716] = I[717], I[717] = I[718], I[718] = I[719], I[719] = I[720], I[720] = I[721], I[721] = I[722], I[722] = I[723], I[723] = I[724], I[724] = I[725], I[725] = I[726], I[726] = I[727], I[727] = I[728], I[728] = I[729], I[729] = I[730], I[730] = I[731], I[731] = I[732], I[732] = I[733], I[733] = I[734], I[734] = I[735], \ - I[736] = I[737], I[737] = I[738], I[738] = I[739], I[739] = I[740], I[740] = I[741], I[741] = I[742], I[742] = I[743], I[743] = I[744], I[744] = I[745], I[745] = I[746], I[746] = I[747], I[747] = I[748], I[748] = I[749], I[749] = I[750], I[750] = I[751], I[751] = I[752], I[752] = I[753], I[753] = I[754], I[754] = I[755], I[755] = I[756], I[756] = I[757], I[757] = I[758], I[758] = I[759], I[759] = I[760], I[760] = I[761], I[761] = I[762], I[762] = I[763], I[763] = I[764], I[764] = I[765], I[765] = I[766], I[766] = I[767], \ - I[768] = I[769], I[769] = I[770], I[770] = I[771], I[771] = I[772], I[772] = I[773], I[773] = I[774], I[774] = I[775], I[775] = I[776], I[776] = I[777], I[777] = I[778], I[778] = I[779], I[779] = I[780], I[780] = I[781], I[781] = I[782], I[782] = I[783], I[783] = I[784], I[784] = I[785], I[785] = I[786], I[786] = I[787], I[787] = I[788], I[788] = I[789], I[789] = I[790], I[790] = I[791], I[791] = I[792], I[792] = I[793], I[793] = I[794], I[794] = I[795], I[795] = I[796], I[796] = I[797], I[797] = I[798], I[798] = I[799], \ - I[800] = I[801], I[801] = I[802], I[802] = I[803], I[803] = I[804], I[804] = I[805], I[805] = I[806], I[806] = I[807], I[807] = I[808], I[808] = I[809], I[809] = I[810], I[810] = I[811], I[811] = I[812], I[812] = I[813], I[813] = I[814], I[814] = I[815], I[815] = I[816], I[816] = I[817], I[817] = I[818], I[818] = I[819], I[819] = I[820], I[820] = I[821], I[821] = I[822], I[822] = I[823], I[823] = I[824], I[824] = I[825], I[825] = I[826], I[826] = I[827], I[827] = I[828], I[828] = I[829], I[829] = I[830], I[830] = I[831], \ - I[832] = I[833], I[833] = I[834], I[834] = I[835], I[835] = I[836], I[836] = I[837], I[837] = I[838], I[838] = I[839], I[839] = I[840], I[840] = I[841], I[841] = I[842], I[842] = I[843], I[843] = I[844], I[844] = I[845], I[845] = I[846], I[846] = I[847], I[847] = I[848], I[848] = I[849], I[849] = I[850], I[850] = I[851], I[851] = I[852], I[852] = I[853], I[853] = I[854], I[854] = I[855], I[855] = I[856], I[856] = I[857], I[857] = I[858], I[858] = I[859], I[859] = I[860], I[860] = I[861], I[861] = I[862], I[862] = I[863], \ - I[864] = I[865], I[865] = I[866], I[866] = I[867], I[867] = I[868], I[868] = I[869], I[869] = I[870], I[870] = I[871], I[871] = I[872], I[872] = I[873], I[873] = I[874], I[874] = I[875], I[875] = I[876], I[876] = I[877], I[877] = I[878], I[878] = I[879], I[879] = I[880], I[880] = I[881], I[881] = I[882], I[882] = I[883], I[883] = I[884], I[884] = I[885], I[885] = I[886], I[886] = I[887], I[887] = I[888], I[888] = I[889], I[889] = I[890], I[890] = I[891], I[891] = I[892], I[892] = I[893], I[893] = I[894], I[894] = I[895], \ - I[896] = I[897], I[897] = I[898], I[898] = I[899], I[899] = I[900], I[900] = I[901], I[901] = I[902], I[902] = I[903], I[903] = I[904], I[904] = I[905], I[905] = I[906], I[906] = I[907], I[907] = I[908], I[908] = I[909], I[909] = I[910], I[910] = I[911], I[911] = I[912], I[912] = I[913], I[913] = I[914], I[914] = I[915], I[915] = I[916], I[916] = I[917], I[917] = I[918], I[918] = I[919], I[919] = I[920], I[920] = I[921], I[921] = I[922], I[922] = I[923], I[923] = I[924], I[924] = I[925], I[925] = I[926], I[926] = I[927], \ - I[928] = I[929], I[929] = I[930], I[930] = I[931], I[931] = I[932], I[932] = I[933], I[933] = I[934], I[934] = I[935], I[935] = I[936], I[936] = I[937], I[937] = I[938], I[938] = I[939], I[939] = I[940], I[940] = I[941], I[941] = I[942], I[942] = I[943], I[943] = I[944], I[944] = I[945], I[945] = I[946], I[946] = I[947], I[947] = I[948], I[948] = I[949], I[949] = I[950], I[950] = I[951], I[951] = I[952], I[952] = I[953], I[953] = I[954], I[954] = I[955], I[955] = I[956], I[956] = I[957], I[957] = I[958], I[958] = I[959], \ - I[960] = I[961], I[961] = I[962], I[962] = I[963], I[963] = I[964], I[964] = I[965], I[965] = I[966], I[966] = I[967], I[967] = I[968], I[968] = I[969], I[969] = I[970], I[970] = I[971], I[971] = I[972], I[972] = I[973], I[973] = I[974], I[974] = I[975], I[975] = I[976], I[976] = I[977], I[977] = I[978], I[978] = I[979], I[979] = I[980], I[980] = I[981], I[981] = I[982], I[982] = I[983], I[983] = I[984], I[984] = I[985], I[985] = I[986], I[986] = I[987], I[987] = I[988], I[988] = I[989], I[989] = I[990], I[990] = I[991], \ - I[992] = I[993], I[993] = I[994], I[994] = I[995], I[995] = I[996], I[996] = I[997], I[997] = I[998], I[998] = I[999], I[999] = I[1000], I[1000] = I[1001], I[1001] = I[1002], I[1002] = I[1003], I[1003] = I[1004], I[1004] = I[1005], I[1005] = I[1006], I[1006] = I[1007], I[1007] = I[1008], I[1008] = I[1009], I[1009] = I[1010], I[1010] = I[1011], I[1011] = I[1012], I[1012] = I[1013], I[1013] = I[1014], I[1014] = I[1015], I[1015] = I[1016], I[1016] = I[1017], I[1017] = I[1018], I[1018] = I[1019], I[1019] = I[1020], I[1020] = I[1021], I[1021] = I[1022], I[1022] = I[1023], \ - _p15##x = _p14##x, _p14##x = _p13##x, _p13##x = _p12##x, _p12##x = _p11##x, _p11##x = _p10##x, _p10##x = _p9##x, _p9##x = _p8##x, _p8##x = _p7##x, _p7##x = _p6##x, _p6##x = _p5##x, _p5##x = _p4##x, _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x, ++_n5##x, ++_n6##x, ++_n7##x, ++_n8##x, ++_n9##x, ++_n10##x, ++_n11##x, ++_n12##x, ++_n13##x, ++_n14##x, ++_n15##x, ++_n16##x) - -#define cimg_get32x32(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p15##x,_p15##y,z,c), I[1] = (T)(img)(_p14##x,_p15##y,z,c), I[2] = (T)(img)(_p13##x,_p15##y,z,c), I[3] = (T)(img)(_p12##x,_p15##y,z,c), I[4] = (T)(img)(_p11##x,_p15##y,z,c), I[5] = (T)(img)(_p10##x,_p15##y,z,c), I[6] = (T)(img)(_p9##x,_p15##y,z,c), I[7] = (T)(img)(_p8##x,_p15##y,z,c), I[8] = (T)(img)(_p7##x,_p15##y,z,c), I[9] = (T)(img)(_p6##x,_p15##y,z,c), I[10] = (T)(img)(_p5##x,_p15##y,z,c), I[11] = (T)(img)(_p4##x,_p15##y,z,c), I[12] = (T)(img)(_p3##x,_p15##y,z,c), I[13] = (T)(img)(_p2##x,_p15##y,z,c), I[14] = (T)(img)(_p1##x,_p15##y,z,c), I[15] = (T)(img)(x,_p15##y,z,c), I[16] = (T)(img)(_n1##x,_p15##y,z,c), I[17] = (T)(img)(_n2##x,_p15##y,z,c), I[18] = (T)(img)(_n3##x,_p15##y,z,c), I[19] = (T)(img)(_n4##x,_p15##y,z,c), I[20] = (T)(img)(_n5##x,_p15##y,z,c), I[21] = (T)(img)(_n6##x,_p15##y,z,c), I[22] = (T)(img)(_n7##x,_p15##y,z,c), I[23] = (T)(img)(_n8##x,_p15##y,z,c), I[24] = (T)(img)(_n9##x,_p15##y,z,c), I[25] = (T)(img)(_n10##x,_p15##y,z,c), I[26] = (T)(img)(_n11##x,_p15##y,z,c), I[27] = (T)(img)(_n12##x,_p15##y,z,c), I[28] = (T)(img)(_n13##x,_p15##y,z,c), I[29] = (T)(img)(_n14##x,_p15##y,z,c), I[30] = (T)(img)(_n15##x,_p15##y,z,c), I[31] = (T)(img)(_n16##x,_p15##y,z,c), \ - I[32] = (T)(img)(_p15##x,_p14##y,z,c), I[33] = (T)(img)(_p14##x,_p14##y,z,c), I[34] = (T)(img)(_p13##x,_p14##y,z,c), I[35] = (T)(img)(_p12##x,_p14##y,z,c), I[36] = (T)(img)(_p11##x,_p14##y,z,c), I[37] = (T)(img)(_p10##x,_p14##y,z,c), I[38] = (T)(img)(_p9##x,_p14##y,z,c), I[39] = (T)(img)(_p8##x,_p14##y,z,c), I[40] = (T)(img)(_p7##x,_p14##y,z,c), I[41] = (T)(img)(_p6##x,_p14##y,z,c), I[42] = (T)(img)(_p5##x,_p14##y,z,c), I[43] = (T)(img)(_p4##x,_p14##y,z,c), I[44] = (T)(img)(_p3##x,_p14##y,z,c), I[45] = (T)(img)(_p2##x,_p14##y,z,c), I[46] = (T)(img)(_p1##x,_p14##y,z,c), I[47] = (T)(img)(x,_p14##y,z,c), I[48] = (T)(img)(_n1##x,_p14##y,z,c), I[49] = (T)(img)(_n2##x,_p14##y,z,c), I[50] = (T)(img)(_n3##x,_p14##y,z,c), I[51] = (T)(img)(_n4##x,_p14##y,z,c), I[52] = (T)(img)(_n5##x,_p14##y,z,c), I[53] = (T)(img)(_n6##x,_p14##y,z,c), I[54] = (T)(img)(_n7##x,_p14##y,z,c), I[55] = (T)(img)(_n8##x,_p14##y,z,c), I[56] = (T)(img)(_n9##x,_p14##y,z,c), I[57] = (T)(img)(_n10##x,_p14##y,z,c), I[58] = (T)(img)(_n11##x,_p14##y,z,c), I[59] = (T)(img)(_n12##x,_p14##y,z,c), I[60] = (T)(img)(_n13##x,_p14##y,z,c), I[61] = (T)(img)(_n14##x,_p14##y,z,c), I[62] = (T)(img)(_n15##x,_p14##y,z,c), I[63] = (T)(img)(_n16##x,_p14##y,z,c), \ - I[64] = (T)(img)(_p15##x,_p13##y,z,c), I[65] = (T)(img)(_p14##x,_p13##y,z,c), I[66] = (T)(img)(_p13##x,_p13##y,z,c), I[67] = (T)(img)(_p12##x,_p13##y,z,c), I[68] = (T)(img)(_p11##x,_p13##y,z,c), I[69] = (T)(img)(_p10##x,_p13##y,z,c), I[70] = (T)(img)(_p9##x,_p13##y,z,c), I[71] = (T)(img)(_p8##x,_p13##y,z,c), I[72] = (T)(img)(_p7##x,_p13##y,z,c), I[73] = (T)(img)(_p6##x,_p13##y,z,c), I[74] = (T)(img)(_p5##x,_p13##y,z,c), I[75] = (T)(img)(_p4##x,_p13##y,z,c), I[76] = (T)(img)(_p3##x,_p13##y,z,c), I[77] = (T)(img)(_p2##x,_p13##y,z,c), I[78] = (T)(img)(_p1##x,_p13##y,z,c), I[79] = (T)(img)(x,_p13##y,z,c), I[80] = (T)(img)(_n1##x,_p13##y,z,c), I[81] = (T)(img)(_n2##x,_p13##y,z,c), I[82] = (T)(img)(_n3##x,_p13##y,z,c), I[83] = (T)(img)(_n4##x,_p13##y,z,c), I[84] = (T)(img)(_n5##x,_p13##y,z,c), I[85] = (T)(img)(_n6##x,_p13##y,z,c), I[86] = (T)(img)(_n7##x,_p13##y,z,c), I[87] = (T)(img)(_n8##x,_p13##y,z,c), I[88] = (T)(img)(_n9##x,_p13##y,z,c), I[89] = (T)(img)(_n10##x,_p13##y,z,c), I[90] = (T)(img)(_n11##x,_p13##y,z,c), I[91] = (T)(img)(_n12##x,_p13##y,z,c), I[92] = (T)(img)(_n13##x,_p13##y,z,c), I[93] = (T)(img)(_n14##x,_p13##y,z,c), I[94] = (T)(img)(_n15##x,_p13##y,z,c), I[95] = (T)(img)(_n16##x,_p13##y,z,c), \ - I[96] = (T)(img)(_p15##x,_p12##y,z,c), I[97] = (T)(img)(_p14##x,_p12##y,z,c), I[98] = (T)(img)(_p13##x,_p12##y,z,c), I[99] = (T)(img)(_p12##x,_p12##y,z,c), I[100] = (T)(img)(_p11##x,_p12##y,z,c), I[101] = (T)(img)(_p10##x,_p12##y,z,c), I[102] = (T)(img)(_p9##x,_p12##y,z,c), I[103] = (T)(img)(_p8##x,_p12##y,z,c), I[104] = (T)(img)(_p7##x,_p12##y,z,c), I[105] = (T)(img)(_p6##x,_p12##y,z,c), I[106] = (T)(img)(_p5##x,_p12##y,z,c), I[107] = (T)(img)(_p4##x,_p12##y,z,c), I[108] = (T)(img)(_p3##x,_p12##y,z,c), I[109] = (T)(img)(_p2##x,_p12##y,z,c), I[110] = (T)(img)(_p1##x,_p12##y,z,c), I[111] = (T)(img)(x,_p12##y,z,c), I[112] = (T)(img)(_n1##x,_p12##y,z,c), I[113] = (T)(img)(_n2##x,_p12##y,z,c), I[114] = (T)(img)(_n3##x,_p12##y,z,c), I[115] = (T)(img)(_n4##x,_p12##y,z,c), I[116] = (T)(img)(_n5##x,_p12##y,z,c), I[117] = (T)(img)(_n6##x,_p12##y,z,c), I[118] = (T)(img)(_n7##x,_p12##y,z,c), I[119] = (T)(img)(_n8##x,_p12##y,z,c), I[120] = (T)(img)(_n9##x,_p12##y,z,c), I[121] = (T)(img)(_n10##x,_p12##y,z,c), I[122] = (T)(img)(_n11##x,_p12##y,z,c), I[123] = (T)(img)(_n12##x,_p12##y,z,c), I[124] = (T)(img)(_n13##x,_p12##y,z,c), I[125] = (T)(img)(_n14##x,_p12##y,z,c), I[126] = (T)(img)(_n15##x,_p12##y,z,c), I[127] = (T)(img)(_n16##x,_p12##y,z,c), \ - I[128] = (T)(img)(_p15##x,_p11##y,z,c), I[129] = (T)(img)(_p14##x,_p11##y,z,c), I[130] = (T)(img)(_p13##x,_p11##y,z,c), I[131] = (T)(img)(_p12##x,_p11##y,z,c), I[132] = (T)(img)(_p11##x,_p11##y,z,c), I[133] = (T)(img)(_p10##x,_p11##y,z,c), I[134] = (T)(img)(_p9##x,_p11##y,z,c), I[135] = (T)(img)(_p8##x,_p11##y,z,c), I[136] = (T)(img)(_p7##x,_p11##y,z,c), I[137] = (T)(img)(_p6##x,_p11##y,z,c), I[138] = (T)(img)(_p5##x,_p11##y,z,c), I[139] = (T)(img)(_p4##x,_p11##y,z,c), I[140] = (T)(img)(_p3##x,_p11##y,z,c), I[141] = (T)(img)(_p2##x,_p11##y,z,c), I[142] = (T)(img)(_p1##x,_p11##y,z,c), I[143] = (T)(img)(x,_p11##y,z,c), I[144] = (T)(img)(_n1##x,_p11##y,z,c), I[145] = (T)(img)(_n2##x,_p11##y,z,c), I[146] = (T)(img)(_n3##x,_p11##y,z,c), I[147] = (T)(img)(_n4##x,_p11##y,z,c), I[148] = (T)(img)(_n5##x,_p11##y,z,c), I[149] = (T)(img)(_n6##x,_p11##y,z,c), I[150] = (T)(img)(_n7##x,_p11##y,z,c), I[151] = (T)(img)(_n8##x,_p11##y,z,c), I[152] = (T)(img)(_n9##x,_p11##y,z,c), I[153] = (T)(img)(_n10##x,_p11##y,z,c), I[154] = (T)(img)(_n11##x,_p11##y,z,c), I[155] = (T)(img)(_n12##x,_p11##y,z,c), I[156] = (T)(img)(_n13##x,_p11##y,z,c), I[157] = (T)(img)(_n14##x,_p11##y,z,c), I[158] = (T)(img)(_n15##x,_p11##y,z,c), I[159] = (T)(img)(_n16##x,_p11##y,z,c), \ - I[160] = (T)(img)(_p15##x,_p10##y,z,c), I[161] = (T)(img)(_p14##x,_p10##y,z,c), I[162] = (T)(img)(_p13##x,_p10##y,z,c), I[163] = (T)(img)(_p12##x,_p10##y,z,c), I[164] = (T)(img)(_p11##x,_p10##y,z,c), I[165] = (T)(img)(_p10##x,_p10##y,z,c), I[166] = (T)(img)(_p9##x,_p10##y,z,c), I[167] = (T)(img)(_p8##x,_p10##y,z,c), I[168] = (T)(img)(_p7##x,_p10##y,z,c), I[169] = (T)(img)(_p6##x,_p10##y,z,c), I[170] = (T)(img)(_p5##x,_p10##y,z,c), I[171] = (T)(img)(_p4##x,_p10##y,z,c), I[172] = (T)(img)(_p3##x,_p10##y,z,c), I[173] = (T)(img)(_p2##x,_p10##y,z,c), I[174] = (T)(img)(_p1##x,_p10##y,z,c), I[175] = (T)(img)(x,_p10##y,z,c), I[176] = (T)(img)(_n1##x,_p10##y,z,c), I[177] = (T)(img)(_n2##x,_p10##y,z,c), I[178] = (T)(img)(_n3##x,_p10##y,z,c), I[179] = (T)(img)(_n4##x,_p10##y,z,c), I[180] = (T)(img)(_n5##x,_p10##y,z,c), I[181] = (T)(img)(_n6##x,_p10##y,z,c), I[182] = (T)(img)(_n7##x,_p10##y,z,c), I[183] = (T)(img)(_n8##x,_p10##y,z,c), I[184] = (T)(img)(_n9##x,_p10##y,z,c), I[185] = (T)(img)(_n10##x,_p10##y,z,c), I[186] = (T)(img)(_n11##x,_p10##y,z,c), I[187] = (T)(img)(_n12##x,_p10##y,z,c), I[188] = (T)(img)(_n13##x,_p10##y,z,c), I[189] = (T)(img)(_n14##x,_p10##y,z,c), I[190] = (T)(img)(_n15##x,_p10##y,z,c), I[191] = (T)(img)(_n16##x,_p10##y,z,c), \ - I[192] = (T)(img)(_p15##x,_p9##y,z,c), I[193] = (T)(img)(_p14##x,_p9##y,z,c), I[194] = (T)(img)(_p13##x,_p9##y,z,c), I[195] = (T)(img)(_p12##x,_p9##y,z,c), I[196] = (T)(img)(_p11##x,_p9##y,z,c), I[197] = (T)(img)(_p10##x,_p9##y,z,c), I[198] = (T)(img)(_p9##x,_p9##y,z,c), I[199] = (T)(img)(_p8##x,_p9##y,z,c), I[200] = (T)(img)(_p7##x,_p9##y,z,c), I[201] = (T)(img)(_p6##x,_p9##y,z,c), I[202] = (T)(img)(_p5##x,_p9##y,z,c), I[203] = (T)(img)(_p4##x,_p9##y,z,c), I[204] = (T)(img)(_p3##x,_p9##y,z,c), I[205] = (T)(img)(_p2##x,_p9##y,z,c), I[206] = (T)(img)(_p1##x,_p9##y,z,c), I[207] = (T)(img)(x,_p9##y,z,c), I[208] = (T)(img)(_n1##x,_p9##y,z,c), I[209] = (T)(img)(_n2##x,_p9##y,z,c), I[210] = (T)(img)(_n3##x,_p9##y,z,c), I[211] = (T)(img)(_n4##x,_p9##y,z,c), I[212] = (T)(img)(_n5##x,_p9##y,z,c), I[213] = (T)(img)(_n6##x,_p9##y,z,c), I[214] = (T)(img)(_n7##x,_p9##y,z,c), I[215] = (T)(img)(_n8##x,_p9##y,z,c), I[216] = (T)(img)(_n9##x,_p9##y,z,c), I[217] = (T)(img)(_n10##x,_p9##y,z,c), I[218] = (T)(img)(_n11##x,_p9##y,z,c), I[219] = (T)(img)(_n12##x,_p9##y,z,c), I[220] = (T)(img)(_n13##x,_p9##y,z,c), I[221] = (T)(img)(_n14##x,_p9##y,z,c), I[222] = (T)(img)(_n15##x,_p9##y,z,c), I[223] = (T)(img)(_n16##x,_p9##y,z,c), \ - I[224] = (T)(img)(_p15##x,_p8##y,z,c), I[225] = (T)(img)(_p14##x,_p8##y,z,c), I[226] = (T)(img)(_p13##x,_p8##y,z,c), I[227] = (T)(img)(_p12##x,_p8##y,z,c), I[228] = (T)(img)(_p11##x,_p8##y,z,c), I[229] = (T)(img)(_p10##x,_p8##y,z,c), I[230] = (T)(img)(_p9##x,_p8##y,z,c), I[231] = (T)(img)(_p8##x,_p8##y,z,c), I[232] = (T)(img)(_p7##x,_p8##y,z,c), I[233] = (T)(img)(_p6##x,_p8##y,z,c), I[234] = (T)(img)(_p5##x,_p8##y,z,c), I[235] = (T)(img)(_p4##x,_p8##y,z,c), I[236] = (T)(img)(_p3##x,_p8##y,z,c), I[237] = (T)(img)(_p2##x,_p8##y,z,c), I[238] = (T)(img)(_p1##x,_p8##y,z,c), I[239] = (T)(img)(x,_p8##y,z,c), I[240] = (T)(img)(_n1##x,_p8##y,z,c), I[241] = (T)(img)(_n2##x,_p8##y,z,c), I[242] = (T)(img)(_n3##x,_p8##y,z,c), I[243] = (T)(img)(_n4##x,_p8##y,z,c), I[244] = (T)(img)(_n5##x,_p8##y,z,c), I[245] = (T)(img)(_n6##x,_p8##y,z,c), I[246] = (T)(img)(_n7##x,_p8##y,z,c), I[247] = (T)(img)(_n8##x,_p8##y,z,c), I[248] = (T)(img)(_n9##x,_p8##y,z,c), I[249] = (T)(img)(_n10##x,_p8##y,z,c), I[250] = (T)(img)(_n11##x,_p8##y,z,c), I[251] = (T)(img)(_n12##x,_p8##y,z,c), I[252] = (T)(img)(_n13##x,_p8##y,z,c), I[253] = (T)(img)(_n14##x,_p8##y,z,c), I[254] = (T)(img)(_n15##x,_p8##y,z,c), I[255] = (T)(img)(_n16##x,_p8##y,z,c), \ - I[256] = (T)(img)(_p15##x,_p7##y,z,c), I[257] = (T)(img)(_p14##x,_p7##y,z,c), I[258] = (T)(img)(_p13##x,_p7##y,z,c), I[259] = (T)(img)(_p12##x,_p7##y,z,c), I[260] = (T)(img)(_p11##x,_p7##y,z,c), I[261] = (T)(img)(_p10##x,_p7##y,z,c), I[262] = (T)(img)(_p9##x,_p7##y,z,c), I[263] = (T)(img)(_p8##x,_p7##y,z,c), I[264] = (T)(img)(_p7##x,_p7##y,z,c), I[265] = (T)(img)(_p6##x,_p7##y,z,c), I[266] = (T)(img)(_p5##x,_p7##y,z,c), I[267] = (T)(img)(_p4##x,_p7##y,z,c), I[268] = (T)(img)(_p3##x,_p7##y,z,c), I[269] = (T)(img)(_p2##x,_p7##y,z,c), I[270] = (T)(img)(_p1##x,_p7##y,z,c), I[271] = (T)(img)(x,_p7##y,z,c), I[272] = (T)(img)(_n1##x,_p7##y,z,c), I[273] = (T)(img)(_n2##x,_p7##y,z,c), I[274] = (T)(img)(_n3##x,_p7##y,z,c), I[275] = (T)(img)(_n4##x,_p7##y,z,c), I[276] = (T)(img)(_n5##x,_p7##y,z,c), I[277] = (T)(img)(_n6##x,_p7##y,z,c), I[278] = (T)(img)(_n7##x,_p7##y,z,c), I[279] = (T)(img)(_n8##x,_p7##y,z,c), I[280] = (T)(img)(_n9##x,_p7##y,z,c), I[281] = (T)(img)(_n10##x,_p7##y,z,c), I[282] = (T)(img)(_n11##x,_p7##y,z,c), I[283] = (T)(img)(_n12##x,_p7##y,z,c), I[284] = (T)(img)(_n13##x,_p7##y,z,c), I[285] = (T)(img)(_n14##x,_p7##y,z,c), I[286] = (T)(img)(_n15##x,_p7##y,z,c), I[287] = (T)(img)(_n16##x,_p7##y,z,c), \ - I[288] = (T)(img)(_p15##x,_p6##y,z,c), I[289] = (T)(img)(_p14##x,_p6##y,z,c), I[290] = (T)(img)(_p13##x,_p6##y,z,c), I[291] = (T)(img)(_p12##x,_p6##y,z,c), I[292] = (T)(img)(_p11##x,_p6##y,z,c), I[293] = (T)(img)(_p10##x,_p6##y,z,c), I[294] = (T)(img)(_p9##x,_p6##y,z,c), I[295] = (T)(img)(_p8##x,_p6##y,z,c), I[296] = (T)(img)(_p7##x,_p6##y,z,c), I[297] = (T)(img)(_p6##x,_p6##y,z,c), I[298] = (T)(img)(_p5##x,_p6##y,z,c), I[299] = (T)(img)(_p4##x,_p6##y,z,c), I[300] = (T)(img)(_p3##x,_p6##y,z,c), I[301] = (T)(img)(_p2##x,_p6##y,z,c), I[302] = (T)(img)(_p1##x,_p6##y,z,c), I[303] = (T)(img)(x,_p6##y,z,c), I[304] = (T)(img)(_n1##x,_p6##y,z,c), I[305] = (T)(img)(_n2##x,_p6##y,z,c), I[306] = (T)(img)(_n3##x,_p6##y,z,c), I[307] = (T)(img)(_n4##x,_p6##y,z,c), I[308] = (T)(img)(_n5##x,_p6##y,z,c), I[309] = (T)(img)(_n6##x,_p6##y,z,c), I[310] = (T)(img)(_n7##x,_p6##y,z,c), I[311] = (T)(img)(_n8##x,_p6##y,z,c), I[312] = (T)(img)(_n9##x,_p6##y,z,c), I[313] = (T)(img)(_n10##x,_p6##y,z,c), I[314] = (T)(img)(_n11##x,_p6##y,z,c), I[315] = (T)(img)(_n12##x,_p6##y,z,c), I[316] = (T)(img)(_n13##x,_p6##y,z,c), I[317] = (T)(img)(_n14##x,_p6##y,z,c), I[318] = (T)(img)(_n15##x,_p6##y,z,c), I[319] = (T)(img)(_n16##x,_p6##y,z,c), \ - I[320] = (T)(img)(_p15##x,_p5##y,z,c), I[321] = (T)(img)(_p14##x,_p5##y,z,c), I[322] = (T)(img)(_p13##x,_p5##y,z,c), I[323] = (T)(img)(_p12##x,_p5##y,z,c), I[324] = (T)(img)(_p11##x,_p5##y,z,c), I[325] = (T)(img)(_p10##x,_p5##y,z,c), I[326] = (T)(img)(_p9##x,_p5##y,z,c), I[327] = (T)(img)(_p8##x,_p5##y,z,c), I[328] = (T)(img)(_p7##x,_p5##y,z,c), I[329] = (T)(img)(_p6##x,_p5##y,z,c), I[330] = (T)(img)(_p5##x,_p5##y,z,c), I[331] = (T)(img)(_p4##x,_p5##y,z,c), I[332] = (T)(img)(_p3##x,_p5##y,z,c), I[333] = (T)(img)(_p2##x,_p5##y,z,c), I[334] = (T)(img)(_p1##x,_p5##y,z,c), I[335] = (T)(img)(x,_p5##y,z,c), I[336] = (T)(img)(_n1##x,_p5##y,z,c), I[337] = (T)(img)(_n2##x,_p5##y,z,c), I[338] = (T)(img)(_n3##x,_p5##y,z,c), I[339] = (T)(img)(_n4##x,_p5##y,z,c), I[340] = (T)(img)(_n5##x,_p5##y,z,c), I[341] = (T)(img)(_n6##x,_p5##y,z,c), I[342] = (T)(img)(_n7##x,_p5##y,z,c), I[343] = (T)(img)(_n8##x,_p5##y,z,c), I[344] = (T)(img)(_n9##x,_p5##y,z,c), I[345] = (T)(img)(_n10##x,_p5##y,z,c), I[346] = (T)(img)(_n11##x,_p5##y,z,c), I[347] = (T)(img)(_n12##x,_p5##y,z,c), I[348] = (T)(img)(_n13##x,_p5##y,z,c), I[349] = (T)(img)(_n14##x,_p5##y,z,c), I[350] = (T)(img)(_n15##x,_p5##y,z,c), I[351] = (T)(img)(_n16##x,_p5##y,z,c), \ - I[352] = (T)(img)(_p15##x,_p4##y,z,c), I[353] = (T)(img)(_p14##x,_p4##y,z,c), I[354] = (T)(img)(_p13##x,_p4##y,z,c), I[355] = (T)(img)(_p12##x,_p4##y,z,c), I[356] = (T)(img)(_p11##x,_p4##y,z,c), I[357] = (T)(img)(_p10##x,_p4##y,z,c), I[358] = (T)(img)(_p9##x,_p4##y,z,c), I[359] = (T)(img)(_p8##x,_p4##y,z,c), I[360] = (T)(img)(_p7##x,_p4##y,z,c), I[361] = (T)(img)(_p6##x,_p4##y,z,c), I[362] = (T)(img)(_p5##x,_p4##y,z,c), I[363] = (T)(img)(_p4##x,_p4##y,z,c), I[364] = (T)(img)(_p3##x,_p4##y,z,c), I[365] = (T)(img)(_p2##x,_p4##y,z,c), I[366] = (T)(img)(_p1##x,_p4##y,z,c), I[367] = (T)(img)(x,_p4##y,z,c), I[368] = (T)(img)(_n1##x,_p4##y,z,c), I[369] = (T)(img)(_n2##x,_p4##y,z,c), I[370] = (T)(img)(_n3##x,_p4##y,z,c), I[371] = (T)(img)(_n4##x,_p4##y,z,c), I[372] = (T)(img)(_n5##x,_p4##y,z,c), I[373] = (T)(img)(_n6##x,_p4##y,z,c), I[374] = (T)(img)(_n7##x,_p4##y,z,c), I[375] = (T)(img)(_n8##x,_p4##y,z,c), I[376] = (T)(img)(_n9##x,_p4##y,z,c), I[377] = (T)(img)(_n10##x,_p4##y,z,c), I[378] = (T)(img)(_n11##x,_p4##y,z,c), I[379] = (T)(img)(_n12##x,_p4##y,z,c), I[380] = (T)(img)(_n13##x,_p4##y,z,c), I[381] = (T)(img)(_n14##x,_p4##y,z,c), I[382] = (T)(img)(_n15##x,_p4##y,z,c), I[383] = (T)(img)(_n16##x,_p4##y,z,c), \ - I[384] = (T)(img)(_p15##x,_p3##y,z,c), I[385] = (T)(img)(_p14##x,_p3##y,z,c), I[386] = (T)(img)(_p13##x,_p3##y,z,c), I[387] = (T)(img)(_p12##x,_p3##y,z,c), I[388] = (T)(img)(_p11##x,_p3##y,z,c), I[389] = (T)(img)(_p10##x,_p3##y,z,c), I[390] = (T)(img)(_p9##x,_p3##y,z,c), I[391] = (T)(img)(_p8##x,_p3##y,z,c), I[392] = (T)(img)(_p7##x,_p3##y,z,c), I[393] = (T)(img)(_p6##x,_p3##y,z,c), I[394] = (T)(img)(_p5##x,_p3##y,z,c), I[395] = (T)(img)(_p4##x,_p3##y,z,c), I[396] = (T)(img)(_p3##x,_p3##y,z,c), I[397] = (T)(img)(_p2##x,_p3##y,z,c), I[398] = (T)(img)(_p1##x,_p3##y,z,c), I[399] = (T)(img)(x,_p3##y,z,c), I[400] = (T)(img)(_n1##x,_p3##y,z,c), I[401] = (T)(img)(_n2##x,_p3##y,z,c), I[402] = (T)(img)(_n3##x,_p3##y,z,c), I[403] = (T)(img)(_n4##x,_p3##y,z,c), I[404] = (T)(img)(_n5##x,_p3##y,z,c), I[405] = (T)(img)(_n6##x,_p3##y,z,c), I[406] = (T)(img)(_n7##x,_p3##y,z,c), I[407] = (T)(img)(_n8##x,_p3##y,z,c), I[408] = (T)(img)(_n9##x,_p3##y,z,c), I[409] = (T)(img)(_n10##x,_p3##y,z,c), I[410] = (T)(img)(_n11##x,_p3##y,z,c), I[411] = (T)(img)(_n12##x,_p3##y,z,c), I[412] = (T)(img)(_n13##x,_p3##y,z,c), I[413] = (T)(img)(_n14##x,_p3##y,z,c), I[414] = (T)(img)(_n15##x,_p3##y,z,c), I[415] = (T)(img)(_n16##x,_p3##y,z,c), \ - I[416] = (T)(img)(_p15##x,_p2##y,z,c), I[417] = (T)(img)(_p14##x,_p2##y,z,c), I[418] = (T)(img)(_p13##x,_p2##y,z,c), I[419] = (T)(img)(_p12##x,_p2##y,z,c), I[420] = (T)(img)(_p11##x,_p2##y,z,c), I[421] = (T)(img)(_p10##x,_p2##y,z,c), I[422] = (T)(img)(_p9##x,_p2##y,z,c), I[423] = (T)(img)(_p8##x,_p2##y,z,c), I[424] = (T)(img)(_p7##x,_p2##y,z,c), I[425] = (T)(img)(_p6##x,_p2##y,z,c), I[426] = (T)(img)(_p5##x,_p2##y,z,c), I[427] = (T)(img)(_p4##x,_p2##y,z,c), I[428] = (T)(img)(_p3##x,_p2##y,z,c), I[429] = (T)(img)(_p2##x,_p2##y,z,c), I[430] = (T)(img)(_p1##x,_p2##y,z,c), I[431] = (T)(img)(x,_p2##y,z,c), I[432] = (T)(img)(_n1##x,_p2##y,z,c), I[433] = (T)(img)(_n2##x,_p2##y,z,c), I[434] = (T)(img)(_n3##x,_p2##y,z,c), I[435] = (T)(img)(_n4##x,_p2##y,z,c), I[436] = (T)(img)(_n5##x,_p2##y,z,c), I[437] = (T)(img)(_n6##x,_p2##y,z,c), I[438] = (T)(img)(_n7##x,_p2##y,z,c), I[439] = (T)(img)(_n8##x,_p2##y,z,c), I[440] = (T)(img)(_n9##x,_p2##y,z,c), I[441] = (T)(img)(_n10##x,_p2##y,z,c), I[442] = (T)(img)(_n11##x,_p2##y,z,c), I[443] = (T)(img)(_n12##x,_p2##y,z,c), I[444] = (T)(img)(_n13##x,_p2##y,z,c), I[445] = (T)(img)(_n14##x,_p2##y,z,c), I[446] = (T)(img)(_n15##x,_p2##y,z,c), I[447] = (T)(img)(_n16##x,_p2##y,z,c), \ - I[448] = (T)(img)(_p15##x,_p1##y,z,c), I[449] = (T)(img)(_p14##x,_p1##y,z,c), I[450] = (T)(img)(_p13##x,_p1##y,z,c), I[451] = (T)(img)(_p12##x,_p1##y,z,c), I[452] = (T)(img)(_p11##x,_p1##y,z,c), I[453] = (T)(img)(_p10##x,_p1##y,z,c), I[454] = (T)(img)(_p9##x,_p1##y,z,c), I[455] = (T)(img)(_p8##x,_p1##y,z,c), I[456] = (T)(img)(_p7##x,_p1##y,z,c), I[457] = (T)(img)(_p6##x,_p1##y,z,c), I[458] = (T)(img)(_p5##x,_p1##y,z,c), I[459] = (T)(img)(_p4##x,_p1##y,z,c), I[460] = (T)(img)(_p3##x,_p1##y,z,c), I[461] = (T)(img)(_p2##x,_p1##y,z,c), I[462] = (T)(img)(_p1##x,_p1##y,z,c), I[463] = (T)(img)(x,_p1##y,z,c), I[464] = (T)(img)(_n1##x,_p1##y,z,c), I[465] = (T)(img)(_n2##x,_p1##y,z,c), I[466] = (T)(img)(_n3##x,_p1##y,z,c), I[467] = (T)(img)(_n4##x,_p1##y,z,c), I[468] = (T)(img)(_n5##x,_p1##y,z,c), I[469] = (T)(img)(_n6##x,_p1##y,z,c), I[470] = (T)(img)(_n7##x,_p1##y,z,c), I[471] = (T)(img)(_n8##x,_p1##y,z,c), I[472] = (T)(img)(_n9##x,_p1##y,z,c), I[473] = (T)(img)(_n10##x,_p1##y,z,c), I[474] = (T)(img)(_n11##x,_p1##y,z,c), I[475] = (T)(img)(_n12##x,_p1##y,z,c), I[476] = (T)(img)(_n13##x,_p1##y,z,c), I[477] = (T)(img)(_n14##x,_p1##y,z,c), I[478] = (T)(img)(_n15##x,_p1##y,z,c), I[479] = (T)(img)(_n16##x,_p1##y,z,c), \ - I[480] = (T)(img)(_p15##x,y,z,c), I[481] = (T)(img)(_p14##x,y,z,c), I[482] = (T)(img)(_p13##x,y,z,c), I[483] = (T)(img)(_p12##x,y,z,c), I[484] = (T)(img)(_p11##x,y,z,c), I[485] = (T)(img)(_p10##x,y,z,c), I[486] = (T)(img)(_p9##x,y,z,c), I[487] = (T)(img)(_p8##x,y,z,c), I[488] = (T)(img)(_p7##x,y,z,c), I[489] = (T)(img)(_p6##x,y,z,c), I[490] = (T)(img)(_p5##x,y,z,c), I[491] = (T)(img)(_p4##x,y,z,c), I[492] = (T)(img)(_p3##x,y,z,c), I[493] = (T)(img)(_p2##x,y,z,c), I[494] = (T)(img)(_p1##x,y,z,c), I[495] = (T)(img)(x,y,z,c), I[496] = (T)(img)(_n1##x,y,z,c), I[497] = (T)(img)(_n2##x,y,z,c), I[498] = (T)(img)(_n3##x,y,z,c), I[499] = (T)(img)(_n4##x,y,z,c), I[500] = (T)(img)(_n5##x,y,z,c), I[501] = (T)(img)(_n6##x,y,z,c), I[502] = (T)(img)(_n7##x,y,z,c), I[503] = (T)(img)(_n8##x,y,z,c), I[504] = (T)(img)(_n9##x,y,z,c), I[505] = (T)(img)(_n10##x,y,z,c), I[506] = (T)(img)(_n11##x,y,z,c), I[507] = (T)(img)(_n12##x,y,z,c), I[508] = (T)(img)(_n13##x,y,z,c), I[509] = (T)(img)(_n14##x,y,z,c), I[510] = (T)(img)(_n15##x,y,z,c), I[511] = (T)(img)(_n16##x,y,z,c), \ - I[512] = (T)(img)(_p15##x,_n1##y,z,c), I[513] = (T)(img)(_p14##x,_n1##y,z,c), I[514] = (T)(img)(_p13##x,_n1##y,z,c), I[515] = (T)(img)(_p12##x,_n1##y,z,c), I[516] = (T)(img)(_p11##x,_n1##y,z,c), I[517] = (T)(img)(_p10##x,_n1##y,z,c), I[518] = (T)(img)(_p9##x,_n1##y,z,c), I[519] = (T)(img)(_p8##x,_n1##y,z,c), I[520] = (T)(img)(_p7##x,_n1##y,z,c), I[521] = (T)(img)(_p6##x,_n1##y,z,c), I[522] = (T)(img)(_p5##x,_n1##y,z,c), I[523] = (T)(img)(_p4##x,_n1##y,z,c), I[524] = (T)(img)(_p3##x,_n1##y,z,c), I[525] = (T)(img)(_p2##x,_n1##y,z,c), I[526] = (T)(img)(_p1##x,_n1##y,z,c), I[527] = (T)(img)(x,_n1##y,z,c), I[528] = (T)(img)(_n1##x,_n1##y,z,c), I[529] = (T)(img)(_n2##x,_n1##y,z,c), I[530] = (T)(img)(_n3##x,_n1##y,z,c), I[531] = (T)(img)(_n4##x,_n1##y,z,c), I[532] = (T)(img)(_n5##x,_n1##y,z,c), I[533] = (T)(img)(_n6##x,_n1##y,z,c), I[534] = (T)(img)(_n7##x,_n1##y,z,c), I[535] = (T)(img)(_n8##x,_n1##y,z,c), I[536] = (T)(img)(_n9##x,_n1##y,z,c), I[537] = (T)(img)(_n10##x,_n1##y,z,c), I[538] = (T)(img)(_n11##x,_n1##y,z,c), I[539] = (T)(img)(_n12##x,_n1##y,z,c), I[540] = (T)(img)(_n13##x,_n1##y,z,c), I[541] = (T)(img)(_n14##x,_n1##y,z,c), I[542] = (T)(img)(_n15##x,_n1##y,z,c), I[543] = (T)(img)(_n16##x,_n1##y,z,c), \ - I[544] = (T)(img)(_p15##x,_n2##y,z,c), I[545] = (T)(img)(_p14##x,_n2##y,z,c), I[546] = (T)(img)(_p13##x,_n2##y,z,c), I[547] = (T)(img)(_p12##x,_n2##y,z,c), I[548] = (T)(img)(_p11##x,_n2##y,z,c), I[549] = (T)(img)(_p10##x,_n2##y,z,c), I[550] = (T)(img)(_p9##x,_n2##y,z,c), I[551] = (T)(img)(_p8##x,_n2##y,z,c), I[552] = (T)(img)(_p7##x,_n2##y,z,c), I[553] = (T)(img)(_p6##x,_n2##y,z,c), I[554] = (T)(img)(_p5##x,_n2##y,z,c), I[555] = (T)(img)(_p4##x,_n2##y,z,c), I[556] = (T)(img)(_p3##x,_n2##y,z,c), I[557] = (T)(img)(_p2##x,_n2##y,z,c), I[558] = (T)(img)(_p1##x,_n2##y,z,c), I[559] = (T)(img)(x,_n2##y,z,c), I[560] = (T)(img)(_n1##x,_n2##y,z,c), I[561] = (T)(img)(_n2##x,_n2##y,z,c), I[562] = (T)(img)(_n3##x,_n2##y,z,c), I[563] = (T)(img)(_n4##x,_n2##y,z,c), I[564] = (T)(img)(_n5##x,_n2##y,z,c), I[565] = (T)(img)(_n6##x,_n2##y,z,c), I[566] = (T)(img)(_n7##x,_n2##y,z,c), I[567] = (T)(img)(_n8##x,_n2##y,z,c), I[568] = (T)(img)(_n9##x,_n2##y,z,c), I[569] = (T)(img)(_n10##x,_n2##y,z,c), I[570] = (T)(img)(_n11##x,_n2##y,z,c), I[571] = (T)(img)(_n12##x,_n2##y,z,c), I[572] = (T)(img)(_n13##x,_n2##y,z,c), I[573] = (T)(img)(_n14##x,_n2##y,z,c), I[574] = (T)(img)(_n15##x,_n2##y,z,c), I[575] = (T)(img)(_n16##x,_n2##y,z,c), \ - I[576] = (T)(img)(_p15##x,_n3##y,z,c), I[577] = (T)(img)(_p14##x,_n3##y,z,c), I[578] = (T)(img)(_p13##x,_n3##y,z,c), I[579] = (T)(img)(_p12##x,_n3##y,z,c), I[580] = (T)(img)(_p11##x,_n3##y,z,c), I[581] = (T)(img)(_p10##x,_n3##y,z,c), I[582] = (T)(img)(_p9##x,_n3##y,z,c), I[583] = (T)(img)(_p8##x,_n3##y,z,c), I[584] = (T)(img)(_p7##x,_n3##y,z,c), I[585] = (T)(img)(_p6##x,_n3##y,z,c), I[586] = (T)(img)(_p5##x,_n3##y,z,c), I[587] = (T)(img)(_p4##x,_n3##y,z,c), I[588] = (T)(img)(_p3##x,_n3##y,z,c), I[589] = (T)(img)(_p2##x,_n3##y,z,c), I[590] = (T)(img)(_p1##x,_n3##y,z,c), I[591] = (T)(img)(x,_n3##y,z,c), I[592] = (T)(img)(_n1##x,_n3##y,z,c), I[593] = (T)(img)(_n2##x,_n3##y,z,c), I[594] = (T)(img)(_n3##x,_n3##y,z,c), I[595] = (T)(img)(_n4##x,_n3##y,z,c), I[596] = (T)(img)(_n5##x,_n3##y,z,c), I[597] = (T)(img)(_n6##x,_n3##y,z,c), I[598] = (T)(img)(_n7##x,_n3##y,z,c), I[599] = (T)(img)(_n8##x,_n3##y,z,c), I[600] = (T)(img)(_n9##x,_n3##y,z,c), I[601] = (T)(img)(_n10##x,_n3##y,z,c), I[602] = (T)(img)(_n11##x,_n3##y,z,c), I[603] = (T)(img)(_n12##x,_n3##y,z,c), I[604] = (T)(img)(_n13##x,_n3##y,z,c), I[605] = (T)(img)(_n14##x,_n3##y,z,c), I[606] = (T)(img)(_n15##x,_n3##y,z,c), I[607] = (T)(img)(_n16##x,_n3##y,z,c), \ - I[608] = (T)(img)(_p15##x,_n4##y,z,c), I[609] = (T)(img)(_p14##x,_n4##y,z,c), I[610] = (T)(img)(_p13##x,_n4##y,z,c), I[611] = (T)(img)(_p12##x,_n4##y,z,c), I[612] = (T)(img)(_p11##x,_n4##y,z,c), I[613] = (T)(img)(_p10##x,_n4##y,z,c), I[614] = (T)(img)(_p9##x,_n4##y,z,c), I[615] = (T)(img)(_p8##x,_n4##y,z,c), I[616] = (T)(img)(_p7##x,_n4##y,z,c), I[617] = (T)(img)(_p6##x,_n4##y,z,c), I[618] = (T)(img)(_p5##x,_n4##y,z,c), I[619] = (T)(img)(_p4##x,_n4##y,z,c), I[620] = (T)(img)(_p3##x,_n4##y,z,c), I[621] = (T)(img)(_p2##x,_n4##y,z,c), I[622] = (T)(img)(_p1##x,_n4##y,z,c), I[623] = (T)(img)(x,_n4##y,z,c), I[624] = (T)(img)(_n1##x,_n4##y,z,c), I[625] = (T)(img)(_n2##x,_n4##y,z,c), I[626] = (T)(img)(_n3##x,_n4##y,z,c), I[627] = (T)(img)(_n4##x,_n4##y,z,c), I[628] = (T)(img)(_n5##x,_n4##y,z,c), I[629] = (T)(img)(_n6##x,_n4##y,z,c), I[630] = (T)(img)(_n7##x,_n4##y,z,c), I[631] = (T)(img)(_n8##x,_n4##y,z,c), I[632] = (T)(img)(_n9##x,_n4##y,z,c), I[633] = (T)(img)(_n10##x,_n4##y,z,c), I[634] = (T)(img)(_n11##x,_n4##y,z,c), I[635] = (T)(img)(_n12##x,_n4##y,z,c), I[636] = (T)(img)(_n13##x,_n4##y,z,c), I[637] = (T)(img)(_n14##x,_n4##y,z,c), I[638] = (T)(img)(_n15##x,_n4##y,z,c), I[639] = (T)(img)(_n16##x,_n4##y,z,c), \ - I[640] = (T)(img)(_p15##x,_n5##y,z,c), I[641] = (T)(img)(_p14##x,_n5##y,z,c), I[642] = (T)(img)(_p13##x,_n5##y,z,c), I[643] = (T)(img)(_p12##x,_n5##y,z,c), I[644] = (T)(img)(_p11##x,_n5##y,z,c), I[645] = (T)(img)(_p10##x,_n5##y,z,c), I[646] = (T)(img)(_p9##x,_n5##y,z,c), I[647] = (T)(img)(_p8##x,_n5##y,z,c), I[648] = (T)(img)(_p7##x,_n5##y,z,c), I[649] = (T)(img)(_p6##x,_n5##y,z,c), I[650] = (T)(img)(_p5##x,_n5##y,z,c), I[651] = (T)(img)(_p4##x,_n5##y,z,c), I[652] = (T)(img)(_p3##x,_n5##y,z,c), I[653] = (T)(img)(_p2##x,_n5##y,z,c), I[654] = (T)(img)(_p1##x,_n5##y,z,c), I[655] = (T)(img)(x,_n5##y,z,c), I[656] = (T)(img)(_n1##x,_n5##y,z,c), I[657] = (T)(img)(_n2##x,_n5##y,z,c), I[658] = (T)(img)(_n3##x,_n5##y,z,c), I[659] = (T)(img)(_n4##x,_n5##y,z,c), I[660] = (T)(img)(_n5##x,_n5##y,z,c), I[661] = (T)(img)(_n6##x,_n5##y,z,c), I[662] = (T)(img)(_n7##x,_n5##y,z,c), I[663] = (T)(img)(_n8##x,_n5##y,z,c), I[664] = (T)(img)(_n9##x,_n5##y,z,c), I[665] = (T)(img)(_n10##x,_n5##y,z,c), I[666] = (T)(img)(_n11##x,_n5##y,z,c), I[667] = (T)(img)(_n12##x,_n5##y,z,c), I[668] = (T)(img)(_n13##x,_n5##y,z,c), I[669] = (T)(img)(_n14##x,_n5##y,z,c), I[670] = (T)(img)(_n15##x,_n5##y,z,c), I[671] = (T)(img)(_n16##x,_n5##y,z,c), \ - I[672] = (T)(img)(_p15##x,_n6##y,z,c), I[673] = (T)(img)(_p14##x,_n6##y,z,c), I[674] = (T)(img)(_p13##x,_n6##y,z,c), I[675] = (T)(img)(_p12##x,_n6##y,z,c), I[676] = (T)(img)(_p11##x,_n6##y,z,c), I[677] = (T)(img)(_p10##x,_n6##y,z,c), I[678] = (T)(img)(_p9##x,_n6##y,z,c), I[679] = (T)(img)(_p8##x,_n6##y,z,c), I[680] = (T)(img)(_p7##x,_n6##y,z,c), I[681] = (T)(img)(_p6##x,_n6##y,z,c), I[682] = (T)(img)(_p5##x,_n6##y,z,c), I[683] = (T)(img)(_p4##x,_n6##y,z,c), I[684] = (T)(img)(_p3##x,_n6##y,z,c), I[685] = (T)(img)(_p2##x,_n6##y,z,c), I[686] = (T)(img)(_p1##x,_n6##y,z,c), I[687] = (T)(img)(x,_n6##y,z,c), I[688] = (T)(img)(_n1##x,_n6##y,z,c), I[689] = (T)(img)(_n2##x,_n6##y,z,c), I[690] = (T)(img)(_n3##x,_n6##y,z,c), I[691] = (T)(img)(_n4##x,_n6##y,z,c), I[692] = (T)(img)(_n5##x,_n6##y,z,c), I[693] = (T)(img)(_n6##x,_n6##y,z,c), I[694] = (T)(img)(_n7##x,_n6##y,z,c), I[695] = (T)(img)(_n8##x,_n6##y,z,c), I[696] = (T)(img)(_n9##x,_n6##y,z,c), I[697] = (T)(img)(_n10##x,_n6##y,z,c), I[698] = (T)(img)(_n11##x,_n6##y,z,c), I[699] = (T)(img)(_n12##x,_n6##y,z,c), I[700] = (T)(img)(_n13##x,_n6##y,z,c), I[701] = (T)(img)(_n14##x,_n6##y,z,c), I[702] = (T)(img)(_n15##x,_n6##y,z,c), I[703] = (T)(img)(_n16##x,_n6##y,z,c), \ - I[704] = (T)(img)(_p15##x,_n7##y,z,c), I[705] = (T)(img)(_p14##x,_n7##y,z,c), I[706] = (T)(img)(_p13##x,_n7##y,z,c), I[707] = (T)(img)(_p12##x,_n7##y,z,c), I[708] = (T)(img)(_p11##x,_n7##y,z,c), I[709] = (T)(img)(_p10##x,_n7##y,z,c), I[710] = (T)(img)(_p9##x,_n7##y,z,c), I[711] = (T)(img)(_p8##x,_n7##y,z,c), I[712] = (T)(img)(_p7##x,_n7##y,z,c), I[713] = (T)(img)(_p6##x,_n7##y,z,c), I[714] = (T)(img)(_p5##x,_n7##y,z,c), I[715] = (T)(img)(_p4##x,_n7##y,z,c), I[716] = (T)(img)(_p3##x,_n7##y,z,c), I[717] = (T)(img)(_p2##x,_n7##y,z,c), I[718] = (T)(img)(_p1##x,_n7##y,z,c), I[719] = (T)(img)(x,_n7##y,z,c), I[720] = (T)(img)(_n1##x,_n7##y,z,c), I[721] = (T)(img)(_n2##x,_n7##y,z,c), I[722] = (T)(img)(_n3##x,_n7##y,z,c), I[723] = (T)(img)(_n4##x,_n7##y,z,c), I[724] = (T)(img)(_n5##x,_n7##y,z,c), I[725] = (T)(img)(_n6##x,_n7##y,z,c), I[726] = (T)(img)(_n7##x,_n7##y,z,c), I[727] = (T)(img)(_n8##x,_n7##y,z,c), I[728] = (T)(img)(_n9##x,_n7##y,z,c), I[729] = (T)(img)(_n10##x,_n7##y,z,c), I[730] = (T)(img)(_n11##x,_n7##y,z,c), I[731] = (T)(img)(_n12##x,_n7##y,z,c), I[732] = (T)(img)(_n13##x,_n7##y,z,c), I[733] = (T)(img)(_n14##x,_n7##y,z,c), I[734] = (T)(img)(_n15##x,_n7##y,z,c), I[735] = (T)(img)(_n16##x,_n7##y,z,c), \ - I[736] = (T)(img)(_p15##x,_n8##y,z,c), I[737] = (T)(img)(_p14##x,_n8##y,z,c), I[738] = (T)(img)(_p13##x,_n8##y,z,c), I[739] = (T)(img)(_p12##x,_n8##y,z,c), I[740] = (T)(img)(_p11##x,_n8##y,z,c), I[741] = (T)(img)(_p10##x,_n8##y,z,c), I[742] = (T)(img)(_p9##x,_n8##y,z,c), I[743] = (T)(img)(_p8##x,_n8##y,z,c), I[744] = (T)(img)(_p7##x,_n8##y,z,c), I[745] = (T)(img)(_p6##x,_n8##y,z,c), I[746] = (T)(img)(_p5##x,_n8##y,z,c), I[747] = (T)(img)(_p4##x,_n8##y,z,c), I[748] = (T)(img)(_p3##x,_n8##y,z,c), I[749] = (T)(img)(_p2##x,_n8##y,z,c), I[750] = (T)(img)(_p1##x,_n8##y,z,c), I[751] = (T)(img)(x,_n8##y,z,c), I[752] = (T)(img)(_n1##x,_n8##y,z,c), I[753] = (T)(img)(_n2##x,_n8##y,z,c), I[754] = (T)(img)(_n3##x,_n8##y,z,c), I[755] = (T)(img)(_n4##x,_n8##y,z,c), I[756] = (T)(img)(_n5##x,_n8##y,z,c), I[757] = (T)(img)(_n6##x,_n8##y,z,c), I[758] = (T)(img)(_n7##x,_n8##y,z,c), I[759] = (T)(img)(_n8##x,_n8##y,z,c), I[760] = (T)(img)(_n9##x,_n8##y,z,c), I[761] = (T)(img)(_n10##x,_n8##y,z,c), I[762] = (T)(img)(_n11##x,_n8##y,z,c), I[763] = (T)(img)(_n12##x,_n8##y,z,c), I[764] = (T)(img)(_n13##x,_n8##y,z,c), I[765] = (T)(img)(_n14##x,_n8##y,z,c), I[766] = (T)(img)(_n15##x,_n8##y,z,c), I[767] = (T)(img)(_n16##x,_n8##y,z,c), \ - I[768] = (T)(img)(_p15##x,_n9##y,z,c), I[769] = (T)(img)(_p14##x,_n9##y,z,c), I[770] = (T)(img)(_p13##x,_n9##y,z,c), I[771] = (T)(img)(_p12##x,_n9##y,z,c), I[772] = (T)(img)(_p11##x,_n9##y,z,c), I[773] = (T)(img)(_p10##x,_n9##y,z,c), I[774] = (T)(img)(_p9##x,_n9##y,z,c), I[775] = (T)(img)(_p8##x,_n9##y,z,c), I[776] = (T)(img)(_p7##x,_n9##y,z,c), I[777] = (T)(img)(_p6##x,_n9##y,z,c), I[778] = (T)(img)(_p5##x,_n9##y,z,c), I[779] = (T)(img)(_p4##x,_n9##y,z,c), I[780] = (T)(img)(_p3##x,_n9##y,z,c), I[781] = (T)(img)(_p2##x,_n9##y,z,c), I[782] = (T)(img)(_p1##x,_n9##y,z,c), I[783] = (T)(img)(x,_n9##y,z,c), I[784] = (T)(img)(_n1##x,_n9##y,z,c), I[785] = (T)(img)(_n2##x,_n9##y,z,c), I[786] = (T)(img)(_n3##x,_n9##y,z,c), I[787] = (T)(img)(_n4##x,_n9##y,z,c), I[788] = (T)(img)(_n5##x,_n9##y,z,c), I[789] = (T)(img)(_n6##x,_n9##y,z,c), I[790] = (T)(img)(_n7##x,_n9##y,z,c), I[791] = (T)(img)(_n8##x,_n9##y,z,c), I[792] = (T)(img)(_n9##x,_n9##y,z,c), I[793] = (T)(img)(_n10##x,_n9##y,z,c), I[794] = (T)(img)(_n11##x,_n9##y,z,c), I[795] = (T)(img)(_n12##x,_n9##y,z,c), I[796] = (T)(img)(_n13##x,_n9##y,z,c), I[797] = (T)(img)(_n14##x,_n9##y,z,c), I[798] = (T)(img)(_n15##x,_n9##y,z,c), I[799] = (T)(img)(_n16##x,_n9##y,z,c), \ - I[800] = (T)(img)(_p15##x,_n10##y,z,c), I[801] = (T)(img)(_p14##x,_n10##y,z,c), I[802] = (T)(img)(_p13##x,_n10##y,z,c), I[803] = (T)(img)(_p12##x,_n10##y,z,c), I[804] = (T)(img)(_p11##x,_n10##y,z,c), I[805] = (T)(img)(_p10##x,_n10##y,z,c), I[806] = (T)(img)(_p9##x,_n10##y,z,c), I[807] = (T)(img)(_p8##x,_n10##y,z,c), I[808] = (T)(img)(_p7##x,_n10##y,z,c), I[809] = (T)(img)(_p6##x,_n10##y,z,c), I[810] = (T)(img)(_p5##x,_n10##y,z,c), I[811] = (T)(img)(_p4##x,_n10##y,z,c), I[812] = (T)(img)(_p3##x,_n10##y,z,c), I[813] = (T)(img)(_p2##x,_n10##y,z,c), I[814] = (T)(img)(_p1##x,_n10##y,z,c), I[815] = (T)(img)(x,_n10##y,z,c), I[816] = (T)(img)(_n1##x,_n10##y,z,c), I[817] = (T)(img)(_n2##x,_n10##y,z,c), I[818] = (T)(img)(_n3##x,_n10##y,z,c), I[819] = (T)(img)(_n4##x,_n10##y,z,c), I[820] = (T)(img)(_n5##x,_n10##y,z,c), I[821] = (T)(img)(_n6##x,_n10##y,z,c), I[822] = (T)(img)(_n7##x,_n10##y,z,c), I[823] = (T)(img)(_n8##x,_n10##y,z,c), I[824] = (T)(img)(_n9##x,_n10##y,z,c), I[825] = (T)(img)(_n10##x,_n10##y,z,c), I[826] = (T)(img)(_n11##x,_n10##y,z,c), I[827] = (T)(img)(_n12##x,_n10##y,z,c), I[828] = (T)(img)(_n13##x,_n10##y,z,c), I[829] = (T)(img)(_n14##x,_n10##y,z,c), I[830] = (T)(img)(_n15##x,_n10##y,z,c), I[831] = (T)(img)(_n16##x,_n10##y,z,c), \ - I[832] = (T)(img)(_p15##x,_n11##y,z,c), I[833] = (T)(img)(_p14##x,_n11##y,z,c), I[834] = (T)(img)(_p13##x,_n11##y,z,c), I[835] = (T)(img)(_p12##x,_n11##y,z,c), I[836] = (T)(img)(_p11##x,_n11##y,z,c), I[837] = (T)(img)(_p10##x,_n11##y,z,c), I[838] = (T)(img)(_p9##x,_n11##y,z,c), I[839] = (T)(img)(_p8##x,_n11##y,z,c), I[840] = (T)(img)(_p7##x,_n11##y,z,c), I[841] = (T)(img)(_p6##x,_n11##y,z,c), I[842] = (T)(img)(_p5##x,_n11##y,z,c), I[843] = (T)(img)(_p4##x,_n11##y,z,c), I[844] = (T)(img)(_p3##x,_n11##y,z,c), I[845] = (T)(img)(_p2##x,_n11##y,z,c), I[846] = (T)(img)(_p1##x,_n11##y,z,c), I[847] = (T)(img)(x,_n11##y,z,c), I[848] = (T)(img)(_n1##x,_n11##y,z,c), I[849] = (T)(img)(_n2##x,_n11##y,z,c), I[850] = (T)(img)(_n3##x,_n11##y,z,c), I[851] = (T)(img)(_n4##x,_n11##y,z,c), I[852] = (T)(img)(_n5##x,_n11##y,z,c), I[853] = (T)(img)(_n6##x,_n11##y,z,c), I[854] = (T)(img)(_n7##x,_n11##y,z,c), I[855] = (T)(img)(_n8##x,_n11##y,z,c), I[856] = (T)(img)(_n9##x,_n11##y,z,c), I[857] = (T)(img)(_n10##x,_n11##y,z,c), I[858] = (T)(img)(_n11##x,_n11##y,z,c), I[859] = (T)(img)(_n12##x,_n11##y,z,c), I[860] = (T)(img)(_n13##x,_n11##y,z,c), I[861] = (T)(img)(_n14##x,_n11##y,z,c), I[862] = (T)(img)(_n15##x,_n11##y,z,c), I[863] = (T)(img)(_n16##x,_n11##y,z,c), \ - I[864] = (T)(img)(_p15##x,_n12##y,z,c), I[865] = (T)(img)(_p14##x,_n12##y,z,c), I[866] = (T)(img)(_p13##x,_n12##y,z,c), I[867] = (T)(img)(_p12##x,_n12##y,z,c), I[868] = (T)(img)(_p11##x,_n12##y,z,c), I[869] = (T)(img)(_p10##x,_n12##y,z,c), I[870] = (T)(img)(_p9##x,_n12##y,z,c), I[871] = (T)(img)(_p8##x,_n12##y,z,c), I[872] = (T)(img)(_p7##x,_n12##y,z,c), I[873] = (T)(img)(_p6##x,_n12##y,z,c), I[874] = (T)(img)(_p5##x,_n12##y,z,c), I[875] = (T)(img)(_p4##x,_n12##y,z,c), I[876] = (T)(img)(_p3##x,_n12##y,z,c), I[877] = (T)(img)(_p2##x,_n12##y,z,c), I[878] = (T)(img)(_p1##x,_n12##y,z,c), I[879] = (T)(img)(x,_n12##y,z,c), I[880] = (T)(img)(_n1##x,_n12##y,z,c), I[881] = (T)(img)(_n2##x,_n12##y,z,c), I[882] = (T)(img)(_n3##x,_n12##y,z,c), I[883] = (T)(img)(_n4##x,_n12##y,z,c), I[884] = (T)(img)(_n5##x,_n12##y,z,c), I[885] = (T)(img)(_n6##x,_n12##y,z,c), I[886] = (T)(img)(_n7##x,_n12##y,z,c), I[887] = (T)(img)(_n8##x,_n12##y,z,c), I[888] = (T)(img)(_n9##x,_n12##y,z,c), I[889] = (T)(img)(_n10##x,_n12##y,z,c), I[890] = (T)(img)(_n11##x,_n12##y,z,c), I[891] = (T)(img)(_n12##x,_n12##y,z,c), I[892] = (T)(img)(_n13##x,_n12##y,z,c), I[893] = (T)(img)(_n14##x,_n12##y,z,c), I[894] = (T)(img)(_n15##x,_n12##y,z,c), I[895] = (T)(img)(_n16##x,_n12##y,z,c), \ - I[896] = (T)(img)(_p15##x,_n13##y,z,c), I[897] = (T)(img)(_p14##x,_n13##y,z,c), I[898] = (T)(img)(_p13##x,_n13##y,z,c), I[899] = (T)(img)(_p12##x,_n13##y,z,c), I[900] = (T)(img)(_p11##x,_n13##y,z,c), I[901] = (T)(img)(_p10##x,_n13##y,z,c), I[902] = (T)(img)(_p9##x,_n13##y,z,c), I[903] = (T)(img)(_p8##x,_n13##y,z,c), I[904] = (T)(img)(_p7##x,_n13##y,z,c), I[905] = (T)(img)(_p6##x,_n13##y,z,c), I[906] = (T)(img)(_p5##x,_n13##y,z,c), I[907] = (T)(img)(_p4##x,_n13##y,z,c), I[908] = (T)(img)(_p3##x,_n13##y,z,c), I[909] = (T)(img)(_p2##x,_n13##y,z,c), I[910] = (T)(img)(_p1##x,_n13##y,z,c), I[911] = (T)(img)(x,_n13##y,z,c), I[912] = (T)(img)(_n1##x,_n13##y,z,c), I[913] = (T)(img)(_n2##x,_n13##y,z,c), I[914] = (T)(img)(_n3##x,_n13##y,z,c), I[915] = (T)(img)(_n4##x,_n13##y,z,c), I[916] = (T)(img)(_n5##x,_n13##y,z,c), I[917] = (T)(img)(_n6##x,_n13##y,z,c), I[918] = (T)(img)(_n7##x,_n13##y,z,c), I[919] = (T)(img)(_n8##x,_n13##y,z,c), I[920] = (T)(img)(_n9##x,_n13##y,z,c), I[921] = (T)(img)(_n10##x,_n13##y,z,c), I[922] = (T)(img)(_n11##x,_n13##y,z,c), I[923] = (T)(img)(_n12##x,_n13##y,z,c), I[924] = (T)(img)(_n13##x,_n13##y,z,c), I[925] = (T)(img)(_n14##x,_n13##y,z,c), I[926] = (T)(img)(_n15##x,_n13##y,z,c), I[927] = (T)(img)(_n16##x,_n13##y,z,c), \ - I[928] = (T)(img)(_p15##x,_n14##y,z,c), I[929] = (T)(img)(_p14##x,_n14##y,z,c), I[930] = (T)(img)(_p13##x,_n14##y,z,c), I[931] = (T)(img)(_p12##x,_n14##y,z,c), I[932] = (T)(img)(_p11##x,_n14##y,z,c), I[933] = (T)(img)(_p10##x,_n14##y,z,c), I[934] = (T)(img)(_p9##x,_n14##y,z,c), I[935] = (T)(img)(_p8##x,_n14##y,z,c), I[936] = (T)(img)(_p7##x,_n14##y,z,c), I[937] = (T)(img)(_p6##x,_n14##y,z,c), I[938] = (T)(img)(_p5##x,_n14##y,z,c), I[939] = (T)(img)(_p4##x,_n14##y,z,c), I[940] = (T)(img)(_p3##x,_n14##y,z,c), I[941] = (T)(img)(_p2##x,_n14##y,z,c), I[942] = (T)(img)(_p1##x,_n14##y,z,c), I[943] = (T)(img)(x,_n14##y,z,c), I[944] = (T)(img)(_n1##x,_n14##y,z,c), I[945] = (T)(img)(_n2##x,_n14##y,z,c), I[946] = (T)(img)(_n3##x,_n14##y,z,c), I[947] = (T)(img)(_n4##x,_n14##y,z,c), I[948] = (T)(img)(_n5##x,_n14##y,z,c), I[949] = (T)(img)(_n6##x,_n14##y,z,c), I[950] = (T)(img)(_n7##x,_n14##y,z,c), I[951] = (T)(img)(_n8##x,_n14##y,z,c), I[952] = (T)(img)(_n9##x,_n14##y,z,c), I[953] = (T)(img)(_n10##x,_n14##y,z,c), I[954] = (T)(img)(_n11##x,_n14##y,z,c), I[955] = (T)(img)(_n12##x,_n14##y,z,c), I[956] = (T)(img)(_n13##x,_n14##y,z,c), I[957] = (T)(img)(_n14##x,_n14##y,z,c), I[958] = (T)(img)(_n15##x,_n14##y,z,c), I[959] = (T)(img)(_n16##x,_n14##y,z,c), \ - I[960] = (T)(img)(_p15##x,_n15##y,z,c), I[961] = (T)(img)(_p14##x,_n15##y,z,c), I[962] = (T)(img)(_p13##x,_n15##y,z,c), I[963] = (T)(img)(_p12##x,_n15##y,z,c), I[964] = (T)(img)(_p11##x,_n15##y,z,c), I[965] = (T)(img)(_p10##x,_n15##y,z,c), I[966] = (T)(img)(_p9##x,_n15##y,z,c), I[967] = (T)(img)(_p8##x,_n15##y,z,c), I[968] = (T)(img)(_p7##x,_n15##y,z,c), I[969] = (T)(img)(_p6##x,_n15##y,z,c), I[970] = (T)(img)(_p5##x,_n15##y,z,c), I[971] = (T)(img)(_p4##x,_n15##y,z,c), I[972] = (T)(img)(_p3##x,_n15##y,z,c), I[973] = (T)(img)(_p2##x,_n15##y,z,c), I[974] = (T)(img)(_p1##x,_n15##y,z,c), I[975] = (T)(img)(x,_n15##y,z,c), I[976] = (T)(img)(_n1##x,_n15##y,z,c), I[977] = (T)(img)(_n2##x,_n15##y,z,c), I[978] = (T)(img)(_n3##x,_n15##y,z,c), I[979] = (T)(img)(_n4##x,_n15##y,z,c), I[980] = (T)(img)(_n5##x,_n15##y,z,c), I[981] = (T)(img)(_n6##x,_n15##y,z,c), I[982] = (T)(img)(_n7##x,_n15##y,z,c), I[983] = (T)(img)(_n8##x,_n15##y,z,c), I[984] = (T)(img)(_n9##x,_n15##y,z,c), I[985] = (T)(img)(_n10##x,_n15##y,z,c), I[986] = (T)(img)(_n11##x,_n15##y,z,c), I[987] = (T)(img)(_n12##x,_n15##y,z,c), I[988] = (T)(img)(_n13##x,_n15##y,z,c), I[989] = (T)(img)(_n14##x,_n15##y,z,c), I[990] = (T)(img)(_n15##x,_n15##y,z,c), I[991] = (T)(img)(_n16##x,_n15##y,z,c), \ - I[992] = (T)(img)(_p15##x,_n16##y,z,c), I[993] = (T)(img)(_p14##x,_n16##y,z,c), I[994] = (T)(img)(_p13##x,_n16##y,z,c), I[995] = (T)(img)(_p12##x,_n16##y,z,c), I[996] = (T)(img)(_p11##x,_n16##y,z,c), I[997] = (T)(img)(_p10##x,_n16##y,z,c), I[998] = (T)(img)(_p9##x,_n16##y,z,c), I[999] = (T)(img)(_p8##x,_n16##y,z,c), I[1000] = (T)(img)(_p7##x,_n16##y,z,c), I[1001] = (T)(img)(_p6##x,_n16##y,z,c), I[1002] = (T)(img)(_p5##x,_n16##y,z,c), I[1003] = (T)(img)(_p4##x,_n16##y,z,c), I[1004] = (T)(img)(_p3##x,_n16##y,z,c), I[1005] = (T)(img)(_p2##x,_n16##y,z,c), I[1006] = (T)(img)(_p1##x,_n16##y,z,c), I[1007] = (T)(img)(x,_n16##y,z,c), I[1008] = (T)(img)(_n1##x,_n16##y,z,c), I[1009] = (T)(img)(_n2##x,_n16##y,z,c), I[1010] = (T)(img)(_n3##x,_n16##y,z,c), I[1011] = (T)(img)(_n4##x,_n16##y,z,c), I[1012] = (T)(img)(_n5##x,_n16##y,z,c), I[1013] = (T)(img)(_n6##x,_n16##y,z,c), I[1014] = (T)(img)(_n7##x,_n16##y,z,c), I[1015] = (T)(img)(_n8##x,_n16##y,z,c), I[1016] = (T)(img)(_n9##x,_n16##y,z,c), I[1017] = (T)(img)(_n10##x,_n16##y,z,c), I[1018] = (T)(img)(_n11##x,_n16##y,z,c), I[1019] = (T)(img)(_n12##x,_n16##y,z,c), I[1020] = (T)(img)(_n13##x,_n16##y,z,c), I[1021] = (T)(img)(_n14##x,_n16##y,z,c), I[1022] = (T)(img)(_n15##x,_n16##y,z,c), I[1023] = (T)(img)(_n16##x,_n16##y,z,c); - -// Define 4x4x4 loop macros -//---------------------------- -#define cimg_for4x4x4(img,x,y,z,c,I,T) \ - cimg_for4((img)._depth,z) cimg_for4((img)._height,y) for (int x = 0, \ - _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = (int)( \ - (I[0] = I[1] = (T)(img)(0,_p1##y,_p1##z,c)), \ - (I[4] = I[5] = (T)(img)(0,y,_p1##z,c)), \ - (I[8] = I[9] = (T)(img)(0,_n1##y,_p1##z,c)), \ - (I[12] = I[13] = (T)(img)(0,_n2##y,_p1##z,c)), \ - (I[16] = I[17] = (T)(img)(0,_p1##y,z,c)), \ - (I[20] = I[21] = (T)(img)(0,y,z,c)), \ - (I[24] = I[25] = (T)(img)(0,_n1##y,z,c)), \ - (I[28] = I[29] = (T)(img)(0,_n2##y,z,c)), \ - (I[32] = I[33] = (T)(img)(0,_p1##y,_n1##z,c)), \ - (I[36] = I[37] = (T)(img)(0,y,_n1##z,c)), \ - (I[40] = I[41] = (T)(img)(0,_n1##y,_n1##z,c)), \ - (I[44] = I[45] = (T)(img)(0,_n2##y,_n1##z,c)), \ - (I[48] = I[49] = (T)(img)(0,_p1##y,_n2##z,c)), \ - (I[52] = I[53] = (T)(img)(0,y,_n2##z,c)), \ - (I[56] = I[57] = (T)(img)(0,_n1##y,_n2##z,c)), \ - (I[60] = I[61] = (T)(img)(0,_n2##y,_n2##z,c)), \ - (I[2] = (T)(img)(_n1##x,_p1##y,_p1##z,c)), \ - (I[6] = (T)(img)(_n1##x,y,_p1##z,c)), \ - (I[10] = (T)(img)(_n1##x,_n1##y,_p1##z,c)), \ - (I[14] = (T)(img)(_n1##x,_n2##y,_p1##z,c)), \ - (I[18] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[22] = (T)(img)(_n1##x,y,z,c)), \ - (I[26] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[30] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[34] = (T)(img)(_n1##x,_p1##y,_n1##z,c)), \ - (I[38] = (T)(img)(_n1##x,y,_n1##z,c)), \ - (I[42] = (T)(img)(_n1##x,_n1##y,_n1##z,c)), \ - (I[46] = (T)(img)(_n1##x,_n2##y,_n1##z,c)), \ - (I[50] = (T)(img)(_n1##x,_p1##y,_n2##z,c)), \ - (I[54] = (T)(img)(_n1##x,y,_n2##z,c)), \ - (I[58] = (T)(img)(_n1##x,_n1##y,_n2##z,c)), \ - (I[62] = (T)(img)(_n1##x,_n2##y,_n2##z,c)), \ - 2>=((img)._width)?(img).width() - 1:2); \ - (_n2##x<(img).width() && ( \ - (I[3] = (T)(img)(_n2##x,_p1##y,_p1##z,c)), \ - (I[7] = (T)(img)(_n2##x,y,_p1##z,c)), \ - (I[11] = (T)(img)(_n2##x,_n1##y,_p1##z,c)), \ - (I[15] = (T)(img)(_n2##x,_n2##y,_p1##z,c)), \ - (I[19] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[23] = (T)(img)(_n2##x,y,z,c)), \ - (I[27] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[31] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[35] = (T)(img)(_n2##x,_p1##y,_n1##z,c)), \ - (I[39] = (T)(img)(_n2##x,y,_n1##z,c)), \ - (I[43] = (T)(img)(_n2##x,_n1##y,_n1##z,c)), \ - (I[47] = (T)(img)(_n2##x,_n2##y,_n1##z,c)), \ - (I[51] = (T)(img)(_n2##x,_p1##y,_n2##z,c)), \ - (I[55] = (T)(img)(_n2##x,y,_n2##z,c)), \ - (I[59] = (T)(img)(_n2##x,_n1##y,_n2##z,c)), \ - (I[63] = (T)(img)(_n2##x,_n2##y,_n2##z,c)),1)) || \ - _n1##x==--_n2##x || x==(_n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], \ - I[4] = I[5], I[5] = I[6], I[6] = I[7], \ - I[8] = I[9], I[9] = I[10], I[10] = I[11], \ - I[12] = I[13], I[13] = I[14], I[14] = I[15], \ - I[16] = I[17], I[17] = I[18], I[18] = I[19], \ - I[20] = I[21], I[21] = I[22], I[22] = I[23], \ - I[24] = I[25], I[25] = I[26], I[26] = I[27], \ - I[28] = I[29], I[29] = I[30], I[30] = I[31], \ - I[32] = I[33], I[33] = I[34], I[34] = I[35], \ - I[36] = I[37], I[37] = I[38], I[38] = I[39], \ - I[40] = I[41], I[41] = I[42], I[42] = I[43], \ - I[44] = I[45], I[45] = I[46], I[46] = I[47], \ - I[48] = I[49], I[49] = I[50], I[50] = I[51], \ - I[52] = I[53], I[53] = I[54], I[54] = I[55], \ - I[56] = I[57], I[57] = I[58], I[58] = I[59], \ - I[60] = I[61], I[61] = I[62], I[62] = I[63], \ - _p1##x = x++, ++_n1##x, ++_n2##x) - -#define cimg_for_in4x4x4(img,x0,y0,z0,x1,y1,z1,x,y,z,c,I,T) \ - cimg_for_in4((img)._depth,z0,z1,z) cimg_for_in4((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = (int)( \ - (I[0] = (T)(img)(_p1##x,_p1##y,_p1##z,c)), \ - (I[4] = (T)(img)(_p1##x,y,_p1##z,c)), \ - (I[8] = (T)(img)(_p1##x,_n1##y,_p1##z,c)), \ - (I[12] = (T)(img)(_p1##x,_n2##y,_p1##z,c)), \ - (I[16] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[20] = (T)(img)(_p1##x,y,z,c)), \ - (I[24] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[28] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[32] = (T)(img)(_p1##x,_p1##y,_n1##z,c)), \ - (I[36] = (T)(img)(_p1##x,y,_n1##z,c)), \ - (I[40] = (T)(img)(_p1##x,_n1##y,_n1##z,c)), \ - (I[44] = (T)(img)(_p1##x,_n2##y,_n1##z,c)), \ - (I[48] = (T)(img)(_p1##x,_p1##y,_n2##z,c)), \ - (I[52] = (T)(img)(_p1##x,y,_n2##z,c)), \ - (I[56] = (T)(img)(_p1##x,_n1##y,_n2##z,c)), \ - (I[60] = (T)(img)(_p1##x,_n2##y,_n2##z,c)), \ - (I[1] = (T)(img)(x,_p1##y,_p1##z,c)), \ - (I[5] = (T)(img)(x,y,_p1##z,c)), \ - (I[9] = (T)(img)(x,_n1##y,_p1##z,c)), \ - (I[13] = (T)(img)(x,_n2##y,_p1##z,c)), \ - (I[17] = (T)(img)(x,_p1##y,z,c)), \ - (I[21] = (T)(img)(x,y,z,c)), \ - (I[25] = (T)(img)(x,_n1##y,z,c)), \ - (I[29] = (T)(img)(x,_n2##y,z,c)), \ - (I[33] = (T)(img)(x,_p1##y,_n1##z,c)), \ - (I[37] = (T)(img)(x,y,_n1##z,c)), \ - (I[41] = (T)(img)(x,_n1##y,_n1##z,c)), \ - (I[45] = (T)(img)(x,_n2##y,_n1##z,c)), \ - (I[49] = (T)(img)(x,_p1##y,_n2##z,c)), \ - (I[53] = (T)(img)(x,y,_n2##z,c)), \ - (I[57] = (T)(img)(x,_n1##y,_n2##z,c)), \ - (I[61] = (T)(img)(x,_n2##y,_n2##z,c)), \ - (I[2] = (T)(img)(_n1##x,_p1##y,_p1##z,c)), \ - (I[6] = (T)(img)(_n1##x,y,_p1##z,c)), \ - (I[10] = (T)(img)(_n1##x,_n1##y,_p1##z,c)), \ - (I[14] = (T)(img)(_n1##x,_n2##y,_p1##z,c)), \ - (I[18] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[22] = (T)(img)(_n1##x,y,z,c)), \ - (I[26] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[30] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[34] = (T)(img)(_n1##x,_p1##y,_n1##z,c)), \ - (I[38] = (T)(img)(_n1##x,y,_n1##z,c)), \ - (I[42] = (T)(img)(_n1##x,_n1##y,_n1##z,c)), \ - (I[46] = (T)(img)(_n1##x,_n2##y,_n1##z,c)), \ - (I[50] = (T)(img)(_n1##x,_p1##y,_n2##z,c)), \ - (I[54] = (T)(img)(_n1##x,y,_n2##z,c)), \ - (I[58] = (T)(img)(_n1##x,_n1##y,_n2##z,c)), \ - (I[62] = (T)(img)(_n1##x,_n2##y,_n2##z,c)), \ - x + 2>=(img).width()?(img).width() - 1:x + 2); \ - x<=(int)(x1) && ((_n2##x<(img).width() && ( \ - (I[3] = (T)(img)(_n2##x,_p1##y,_p1##z,c)), \ - (I[7] = (T)(img)(_n2##x,y,_p1##z,c)), \ - (I[11] = (T)(img)(_n2##x,_n1##y,_p1##z,c)), \ - (I[15] = (T)(img)(_n2##x,_n2##y,_p1##z,c)), \ - (I[19] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[23] = (T)(img)(_n2##x,y,z,c)), \ - (I[27] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[31] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[35] = (T)(img)(_n2##x,_p1##y,_n1##z,c)), \ - (I[39] = (T)(img)(_n2##x,y,_n1##z,c)), \ - (I[43] = (T)(img)(_n2##x,_n1##y,_n1##z,c)), \ - (I[47] = (T)(img)(_n2##x,_n2##y,_n1##z,c)), \ - (I[51] = (T)(img)(_n2##x,_p1##y,_n2##z,c)), \ - (I[55] = (T)(img)(_n2##x,y,_n2##z,c)), \ - (I[59] = (T)(img)(_n2##x,_n1##y,_n2##z,c)), \ - (I[63] = (T)(img)(_n2##x,_n2##y,_n2##z,c)),1)) || \ - _n1##x==--_n2##x || x==(_n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], \ - I[4] = I[5], I[5] = I[6], I[6] = I[7], \ - I[8] = I[9], I[9] = I[10], I[10] = I[11], \ - I[12] = I[13], I[13] = I[14], I[14] = I[15], \ - I[16] = I[17], I[17] = I[18], I[18] = I[19], \ - I[20] = I[21], I[21] = I[22], I[22] = I[23], \ - I[24] = I[25], I[25] = I[26], I[26] = I[27], \ - I[28] = I[29], I[29] = I[30], I[30] = I[31], \ - I[32] = I[33], I[33] = I[34], I[34] = I[35], \ - I[36] = I[37], I[37] = I[38], I[38] = I[39], \ - I[40] = I[41], I[41] = I[42], I[42] = I[43], \ - I[44] = I[45], I[45] = I[46], I[46] = I[47], \ - I[48] = I[49], I[49] = I[50], I[50] = I[51], \ - I[52] = I[53], I[53] = I[54], I[54] = I[55], \ - I[56] = I[57], I[57] = I[58], I[58] = I[59], \ - I[60] = I[61], I[61] = I[62], I[62] = I[63], \ - _p1##x = x++, ++_n1##x, ++_n2##x) - -#define cimg_get4x4x4(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p1##x,_p1##y,_p1##z,c), I[1] = (T)(img)(x,_p1##y,_p1##z,c), I[2] = (T)(img)(_n1##x,_p1##y,_p1##z,c), I[3] = (T)(img)(_n2##x,_p1##y,_p1##z,c), \ - I[4] = (T)(img)(_p1##x,y,_p1##z,c), I[5] = (T)(img)(x,y,_p1##z,c), I[6] = (T)(img)(_n1##x,y,_p1##z,c), I[7] = (T)(img)(_n2##x,y,_p1##z,c), \ - I[8] = (T)(img)(_p1##x,_n1##y,_p1##z,c), I[9] = (T)(img)(x,_n1##y,_p1##z,c), I[10] = (T)(img)(_n1##x,_n1##y,_p1##z,c), I[11] = (T)(img)(_n2##x,_n1##y,_p1##z,c), \ - I[12] = (T)(img)(_p1##x,_n2##y,_p1##z,c), I[13] = (T)(img)(x,_n2##y,_p1##z,c), I[14] = (T)(img)(_n1##x,_n2##y,_p1##z,c), I[15] = (T)(img)(_n2##x,_n2##y,_p1##z,c), \ - I[16] = (T)(img)(_p1##x,_p1##y,z,c), I[17] = (T)(img)(x,_p1##y,z,c), I[18] = (T)(img)(_n1##x,_p1##y,z,c), I[19] = (T)(img)(_n2##x,_p1##y,z,c), \ - I[20] = (T)(img)(_p1##x,y,z,c), I[21] = (T)(img)(x,y,z,c), I[22] = (T)(img)(_n1##x,y,z,c), I[23] = (T)(img)(_n2##x,y,z,c), \ - I[24] = (T)(img)(_p1##x,_n1##y,z,c), I[25] = (T)(img)(x,_n1##y,z,c), I[26] = (T)(img)(_n1##x,_n1##y,z,c), I[27] = (T)(img)(_n2##x,_n1##y,z,c), \ - I[28] = (T)(img)(_p1##x,_n2##y,z,c), I[29] = (T)(img)(x,_n2##y,z,c), I[30] = (T)(img)(_n1##x,_n2##y,z,c), I[31] = (T)(img)(_n2##x,_n2##y,z,c), \ - I[32] = (T)(img)(_p1##x,_p1##y,_n1##z,c), I[33] = (T)(img)(x,_p1##y,_n1##z,c), I[34] = (T)(img)(_n1##x,_p1##y,_n1##z,c), I[35] = (T)(img)(_n2##x,_p1##y,_n1##z,c), \ - I[36] = (T)(img)(_p1##x,y,_n1##z,c), I[37] = (T)(img)(x,y,_n1##z,c), I[38] = (T)(img)(_n1##x,y,_n1##z,c), I[39] = (T)(img)(_n2##x,y,_n1##z,c), \ - I[40] = (T)(img)(_p1##x,_n1##y,_n1##z,c), I[41] = (T)(img)(x,_n1##y,_n1##z,c), I[42] = (T)(img)(_n1##x,_n1##y,_n1##z,c), I[43] = (T)(img)(_n2##x,_n1##y,_n1##z,c), \ - I[44] = (T)(img)(_p1##x,_n2##y,_n1##z,c), I[45] = (T)(img)(x,_n2##y,_n1##z,c), I[46] = (T)(img)(_n1##x,_n2##y,_n1##z,c), I[47] = (T)(img)(_n2##x,_n2##y,_n1##z,c), \ - I[48] = (T)(img)(_p1##x,_p1##y,_n2##z,c), I[49] = (T)(img)(x,_p1##y,_n2##z,c), I[50] = (T)(img)(_n1##x,_p1##y,_n2##z,c), I[51] = (T)(img)(_n2##x,_p1##y,_n2##z,c), \ - I[52] = (T)(img)(_p1##x,y,_n2##z,c), I[53] = (T)(img)(x,y,_n2##z,c), I[54] = (T)(img)(_n1##x,y,_n2##z,c), I[55] = (T)(img)(_n2##x,y,_n2##z,c), \ - I[56] = (T)(img)(_p1##x,_n1##y,_n2##z,c), I[57] = (T)(img)(x,_n1##y,_n2##z,c), I[58] = (T)(img)(_n1##x,_n1##y,_n2##z,c), I[59] = (T)(img)(_n2##x,_n1##y,_n2##z,c), \ - I[60] = (T)(img)(_p1##x,_n2##y,_n2##z,c), I[61] = (T)(img)(x,_n2##y,_n2##z,c), I[62] = (T)(img)(_n1##x,_n2##y,_n2##z,c), I[63] = (T)(img)(_n2##x,_n2##y,_n2##z,c); - -// Define 5x5x5 loop macros -//---------------------------- -#define cimg_for5x5x5(img,x,y,z,c,I,T) \ - cimg_for5((img)._depth,z) cimg_for5((img)._height,y) for (int x = 0, \ - _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = (int)( \ - (I[0] = I[1] = I[2] = (T)(img)(0,_p2##y,_p2##z,c)), \ - (I[5] = I[6] = I[7] = (T)(img)(0,_p1##y,_p2##z,c)), \ - (I[10] = I[11] = I[12] = (T)(img)(0,y,_p2##z,c)), \ - (I[15] = I[16] = I[17] = (T)(img)(0,_n1##y,_p2##z,c)), \ - (I[20] = I[21] = I[22] = (T)(img)(0,_n2##y,_p2##z,c)), \ - (I[25] = I[26] = I[27] = (T)(img)(0,_p2##y,_p1##z,c)), \ - (I[30] = I[31] = I[32] = (T)(img)(0,_p1##y,_p1##z,c)), \ - (I[35] = I[36] = I[37] = (T)(img)(0,y,_p1##z,c)), \ - (I[40] = I[41] = I[42] = (T)(img)(0,_n1##y,_p1##z,c)), \ - (I[45] = I[46] = I[47] = (T)(img)(0,_n2##y,_p1##z,c)), \ - (I[50] = I[51] = I[52] = (T)(img)(0,_p2##y,z,c)), \ - (I[55] = I[56] = I[57] = (T)(img)(0,_p1##y,z,c)), \ - (I[60] = I[61] = I[62] = (T)(img)(0,y,z,c)), \ - (I[65] = I[66] = I[67] = (T)(img)(0,_n1##y,z,c)), \ - (I[70] = I[71] = I[72] = (T)(img)(0,_n2##y,z,c)), \ - (I[75] = I[76] = I[77] = (T)(img)(0,_p2##y,_n1##z,c)), \ - (I[80] = I[81] = I[82] = (T)(img)(0,_p1##y,_n1##z,c)), \ - (I[85] = I[86] = I[87] = (T)(img)(0,y,_n1##z,c)), \ - (I[90] = I[91] = I[92] = (T)(img)(0,_n1##y,_n1##z,c)), \ - (I[95] = I[96] = I[97] = (T)(img)(0,_n2##y,_n1##z,c)), \ - (I[100] = I[101] = I[102] = (T)(img)(0,_p2##y,_n2##z,c)), \ - (I[105] = I[106] = I[107] = (T)(img)(0,_p1##y,_n2##z,c)), \ - (I[110] = I[111] = I[112] = (T)(img)(0,y,_n2##z,c)), \ - (I[115] = I[116] = I[117] = (T)(img)(0,_n1##y,_n2##z,c)), \ - (I[120] = I[121] = I[122] = (T)(img)(0,_n2##y,_n2##z,c)), \ - (I[3] = (T)(img)(_n1##x,_p2##y,_p2##z,c)), \ - (I[8] = (T)(img)(_n1##x,_p1##y,_p2##z,c)), \ - (I[13] = (T)(img)(_n1##x,y,_p2##z,c)), \ - (I[18] = (T)(img)(_n1##x,_n1##y,_p2##z,c)), \ - (I[23] = (T)(img)(_n1##x,_n2##y,_p2##z,c)), \ - (I[28] = (T)(img)(_n1##x,_p2##y,_p1##z,c)), \ - (I[33] = (T)(img)(_n1##x,_p1##y,_p1##z,c)), \ - (I[38] = (T)(img)(_n1##x,y,_p1##z,c)), \ - (I[43] = (T)(img)(_n1##x,_n1##y,_p1##z,c)), \ - (I[48] = (T)(img)(_n1##x,_n2##y,_p1##z,c)), \ - (I[53] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[58] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[63] = (T)(img)(_n1##x,y,z,c)), \ - (I[68] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[73] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[78] = (T)(img)(_n1##x,_p2##y,_n1##z,c)), \ - (I[83] = (T)(img)(_n1##x,_p1##y,_n1##z,c)), \ - (I[88] = (T)(img)(_n1##x,y,_n1##z,c)), \ - (I[93] = (T)(img)(_n1##x,_n1##y,_n1##z,c)), \ - (I[98] = (T)(img)(_n1##x,_n2##y,_n1##z,c)), \ - (I[103] = (T)(img)(_n1##x,_p2##y,_n2##z,c)), \ - (I[108] = (T)(img)(_n1##x,_p1##y,_n2##z,c)), \ - (I[113] = (T)(img)(_n1##x,y,_n2##z,c)), \ - (I[118] = (T)(img)(_n1##x,_n1##y,_n2##z,c)), \ - (I[123] = (T)(img)(_n1##x,_n2##y,_n2##z,c)), \ - 2>=((img)._width)?(img).width() - 1:2); \ - (_n2##x<(img).width() && ( \ - (I[4] = (T)(img)(_n2##x,_p2##y,_p2##z,c)), \ - (I[9] = (T)(img)(_n2##x,_p1##y,_p2##z,c)), \ - (I[14] = (T)(img)(_n2##x,y,_p2##z,c)), \ - (I[19] = (T)(img)(_n2##x,_n1##y,_p2##z,c)), \ - (I[24] = (T)(img)(_n2##x,_n2##y,_p2##z,c)), \ - (I[29] = (T)(img)(_n2##x,_p2##y,_p1##z,c)), \ - (I[34] = (T)(img)(_n2##x,_p1##y,_p1##z,c)), \ - (I[39] = (T)(img)(_n2##x,y,_p1##z,c)), \ - (I[44] = (T)(img)(_n2##x,_n1##y,_p1##z,c)), \ - (I[49] = (T)(img)(_n2##x,_n2##y,_p1##z,c)), \ - (I[54] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[59] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[64] = (T)(img)(_n2##x,y,z,c)), \ - (I[69] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[74] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[79] = (T)(img)(_n2##x,_p2##y,_n1##z,c)), \ - (I[84] = (T)(img)(_n2##x,_p1##y,_n1##z,c)), \ - (I[89] = (T)(img)(_n2##x,y,_n1##z,c)), \ - (I[94] = (T)(img)(_n2##x,_n1##y,_n1##z,c)), \ - (I[99] = (T)(img)(_n2##x,_n2##y,_n1##z,c)), \ - (I[104] = (T)(img)(_n2##x,_p2##y,_n2##z,c)), \ - (I[109] = (T)(img)(_n2##x,_p1##y,_n2##z,c)), \ - (I[114] = (T)(img)(_n2##x,y,_n2##z,c)), \ - (I[119] = (T)(img)(_n2##x,_n1##y,_n2##z,c)), \ - (I[124] = (T)(img)(_n2##x,_n2##y,_n2##z,c)),1)) || \ - _n1##x==--_n2##x || x==(_n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], \ - I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], \ - I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], \ - I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], \ - I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], \ - I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], \ - I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], \ - I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], \ - I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], \ - I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], \ - I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], \ - I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], \ - I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], \ - I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], \ - I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], \ - I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], \ - I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], \ - I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], \ - I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], \ - I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], \ - I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], \ - I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], \ - I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], \ - I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], \ - I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], \ - _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x) - -#define cimg_for_in5x5x5(img,x0,y0,z0,x1,y1,z1,x,y,z,c,I,T) \ - cimg_for_in5((img)._depth,z0,z1,z) cimg_for_in5((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = (int)( \ - (I[0] = (T)(img)(_p2##x,_p2##y,_p2##z,c)), \ - (I[5] = (T)(img)(_p2##x,_p1##y,_p2##z,c)), \ - (I[10] = (T)(img)(_p2##x,y,_p2##z,c)), \ - (I[15] = (T)(img)(_p2##x,_n1##y,_p2##z,c)), \ - (I[20] = (T)(img)(_p2##x,_n2##y,_p2##z,c)), \ - (I[25] = (T)(img)(_p2##x,_p2##y,_p1##z,c)), \ - (I[30] = (T)(img)(_p2##x,_p1##y,_p1##z,c)), \ - (I[35] = (T)(img)(_p2##x,y,_p1##z,c)), \ - (I[40] = (T)(img)(_p2##x,_n1##y,_p1##z,c)), \ - (I[45] = (T)(img)(_p2##x,_n2##y,_p1##z,c)), \ - (I[50] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[55] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[60] = (T)(img)(_p2##x,y,z,c)), \ - (I[65] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[70] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[75] = (T)(img)(_p2##x,_p2##y,_n1##z,c)), \ - (I[80] = (T)(img)(_p2##x,_p1##y,_n1##z,c)), \ - (I[85] = (T)(img)(_p2##x,y,_n1##z,c)), \ - (I[90] = (T)(img)(_p2##x,_n1##y,_n1##z,c)), \ - (I[95] = (T)(img)(_p2##x,_n2##y,_n1##z,c)), \ - (I[100] = (T)(img)(_p2##x,_p2##y,_n2##z,c)), \ - (I[105] = (T)(img)(_p2##x,_p1##y,_n2##z,c)), \ - (I[110] = (T)(img)(_p2##x,y,_n2##z,c)), \ - (I[115] = (T)(img)(_p2##x,_n1##y,_n2##z,c)), \ - (I[120] = (T)(img)(_p2##x,_n2##y,_n2##z,c)), \ - (I[1] = (T)(img)(_p1##x,_p2##y,_p2##z,c)), \ - (I[6] = (T)(img)(_p1##x,_p1##y,_p2##z,c)), \ - (I[11] = (T)(img)(_p1##x,y,_p2##z,c)), \ - (I[16] = (T)(img)(_p1##x,_n1##y,_p2##z,c)), \ - (I[21] = (T)(img)(_p1##x,_n2##y,_p2##z,c)), \ - (I[26] = (T)(img)(_p1##x,_p2##y,_p1##z,c)), \ - (I[31] = (T)(img)(_p1##x,_p1##y,_p1##z,c)), \ - (I[36] = (T)(img)(_p1##x,y,_p1##z,c)), \ - (I[41] = (T)(img)(_p1##x,_n1##y,_p1##z,c)), \ - (I[46] = (T)(img)(_p1##x,_n2##y,_p1##z,c)), \ - (I[51] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[56] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[61] = (T)(img)(_p1##x,y,z,c)), \ - (I[66] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[71] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[76] = (T)(img)(_p1##x,_p2##y,_n1##z,c)), \ - (I[81] = (T)(img)(_p1##x,_p1##y,_n1##z,c)), \ - (I[86] = (T)(img)(_p1##x,y,_n1##z,c)), \ - (I[91] = (T)(img)(_p1##x,_n1##y,_n1##z,c)), \ - (I[96] = (T)(img)(_p1##x,_n2##y,_n1##z,c)), \ - (I[101] = (T)(img)(_p1##x,_p2##y,_n2##z,c)), \ - (I[106] = (T)(img)(_p1##x,_p1##y,_n2##z,c)), \ - (I[111] = (T)(img)(_p1##x,y,_n2##z,c)), \ - (I[116] = (T)(img)(_p1##x,_n1##y,_n2##z,c)), \ - (I[121] = (T)(img)(_p1##x,_n2##y,_n2##z,c)), \ - (I[2] = (T)(img)(x,_p2##y,_p2##z,c)), \ - (I[7] = (T)(img)(x,_p1##y,_p2##z,c)), \ - (I[12] = (T)(img)(x,y,_p2##z,c)), \ - (I[17] = (T)(img)(x,_n1##y,_p2##z,c)), \ - (I[22] = (T)(img)(x,_n2##y,_p2##z,c)), \ - (I[27] = (T)(img)(x,_p2##y,_p1##z,c)), \ - (I[32] = (T)(img)(x,_p1##y,_p1##z,c)), \ - (I[37] = (T)(img)(x,y,_p1##z,c)), \ - (I[42] = (T)(img)(x,_n1##y,_p1##z,c)), \ - (I[47] = (T)(img)(x,_n2##y,_p1##z,c)), \ - (I[52] = (T)(img)(x,_p2##y,z,c)), \ - (I[57] = (T)(img)(x,_p1##y,z,c)), \ - (I[62] = (T)(img)(x,y,z,c)), \ - (I[67] = (T)(img)(x,_n1##y,z,c)), \ - (I[72] = (T)(img)(x,_n2##y,z,c)), \ - (I[77] = (T)(img)(x,_p2##y,_n1##z,c)), \ - (I[82] = (T)(img)(x,_p1##y,_n1##z,c)), \ - (I[87] = (T)(img)(x,y,_n1##z,c)), \ - (I[92] = (T)(img)(x,_n1##y,_n1##z,c)), \ - (I[97] = (T)(img)(x,_n2##y,_n1##z,c)), \ - (I[102] = (T)(img)(x,_p2##y,_n2##z,c)), \ - (I[107] = (T)(img)(x,_p1##y,_n2##z,c)), \ - (I[112] = (T)(img)(x,y,_n2##z,c)), \ - (I[117] = (T)(img)(x,_n1##y,_n2##z,c)), \ - (I[122] = (T)(img)(x,_n2##y,_n2##z,c)), \ - (I[3] = (T)(img)(_n1##x,_p2##y,_p2##z,c)), \ - (I[8] = (T)(img)(_n1##x,_p1##y,_p2##z,c)), \ - (I[13] = (T)(img)(_n1##x,y,_p2##z,c)), \ - (I[18] = (T)(img)(_n1##x,_n1##y,_p2##z,c)), \ - (I[23] = (T)(img)(_n1##x,_n2##y,_p2##z,c)), \ - (I[28] = (T)(img)(_n1##x,_p2##y,_p1##z,c)), \ - (I[33] = (T)(img)(_n1##x,_p1##y,_p1##z,c)), \ - (I[38] = (T)(img)(_n1##x,y,_p1##z,c)), \ - (I[43] = (T)(img)(_n1##x,_n1##y,_p1##z,c)), \ - (I[48] = (T)(img)(_n1##x,_n2##y,_p1##z,c)), \ - (I[53] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[58] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[63] = (T)(img)(_n1##x,y,z,c)), \ - (I[68] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[73] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[78] = (T)(img)(_n1##x,_p2##y,_n1##z,c)), \ - (I[83] = (T)(img)(_n1##x,_p1##y,_n1##z,c)), \ - (I[88] = (T)(img)(_n1##x,y,_n1##z,c)), \ - (I[93] = (T)(img)(_n1##x,_n1##y,_n1##z,c)), \ - (I[98] = (T)(img)(_n1##x,_n2##y,_n1##z,c)), \ - (I[103] = (T)(img)(_n1##x,_p2##y,_n2##z,c)), \ - (I[108] = (T)(img)(_n1##x,_p1##y,_n2##z,c)), \ - (I[113] = (T)(img)(_n1##x,y,_n2##z,c)), \ - (I[118] = (T)(img)(_n1##x,_n1##y,_n2##z,c)), \ - (I[123] = (T)(img)(_n1##x,_n2##y,_n2##z,c)), \ - x + 2>=(img).width()?(img).width() - 1:x + 2); \ - x<=(int)(x1) && ((_n2##x<(img).width() && ( \ - (I[4] = (T)(img)(_n2##x,_p2##y,_p2##z,c)), \ - (I[9] = (T)(img)(_n2##x,_p1##y,_p2##z,c)), \ - (I[14] = (T)(img)(_n2##x,y,_p2##z,c)), \ - (I[19] = (T)(img)(_n2##x,_n1##y,_p2##z,c)), \ - (I[24] = (T)(img)(_n2##x,_n2##y,_p2##z,c)), \ - (I[29] = (T)(img)(_n2##x,_p2##y,_p1##z,c)), \ - (I[34] = (T)(img)(_n2##x,_p1##y,_p1##z,c)), \ - (I[39] = (T)(img)(_n2##x,y,_p1##z,c)), \ - (I[44] = (T)(img)(_n2##x,_n1##y,_p1##z,c)), \ - (I[49] = (T)(img)(_n2##x,_n2##y,_p1##z,c)), \ - (I[54] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[59] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[64] = (T)(img)(_n2##x,y,z,c)), \ - (I[69] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[74] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[79] = (T)(img)(_n2##x,_p2##y,_n1##z,c)), \ - (I[84] = (T)(img)(_n2##x,_p1##y,_n1##z,c)), \ - (I[89] = (T)(img)(_n2##x,y,_n1##z,c)), \ - (I[94] = (T)(img)(_n2##x,_n1##y,_n1##z,c)), \ - (I[99] = (T)(img)(_n2##x,_n2##y,_n1##z,c)), \ - (I[104] = (T)(img)(_n2##x,_p2##y,_n2##z,c)), \ - (I[109] = (T)(img)(_n2##x,_p1##y,_n2##z,c)), \ - (I[114] = (T)(img)(_n2##x,y,_n2##z,c)), \ - (I[119] = (T)(img)(_n2##x,_n1##y,_n2##z,c)), \ - (I[124] = (T)(img)(_n2##x,_n2##y,_n2##z,c)),1)) || \ - _n1##x==--_n2##x || x==(_n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], \ - I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], \ - I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], \ - I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], \ - I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], \ - I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], \ - I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], \ - I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], \ - I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], \ - I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], \ - I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], \ - I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], \ - I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], \ - I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], \ - I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], \ - I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], \ - I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], \ - I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], \ - I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], \ - I[95] = I[96], I[96] = I[97], I[97] = I[98], I[98] = I[99], \ - I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], \ - I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], \ - I[110] = I[111], I[111] = I[112], I[112] = I[113], I[113] = I[114], \ - I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], \ - I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], \ - _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x) - -#define cimg_get5x5x5(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p2##x,_p2##y,_p2##z,c), I[1] = (T)(img)(_p1##x,_p2##y,_p2##z,c), I[2] = (T)(img)(x,_p2##y,_p2##z,c), I[3] = (T)(img)(_n1##x,_p2##y,_p2##z,c), I[4] = (T)(img)(_n2##x,_p2##y,_p2##z,c), \ - I[5] = (T)(img)(_p2##x,_p1##y,_p2##z,c), I[6] = (T)(img)(_p1##x,_p1##y,_p2##z,c), I[7] = (T)(img)(x,_p1##y,_p2##z,c), I[8] = (T)(img)(_n1##x,_p1##y,_p2##z,c), I[9] = (T)(img)(_n2##x,_p1##y,_p2##z,c), \ - I[10] = (T)(img)(_p2##x,y,_p2##z,c), I[11] = (T)(img)(_p1##x,y,_p2##z,c), I[12] = (T)(img)(x,y,_p2##z,c), I[13] = (T)(img)(_n1##x,y,_p2##z,c), I[14] = (T)(img)(_n2##x,y,_p2##z,c), \ - I[15] = (T)(img)(_p2##x,_n1##y,_p2##z,c), I[16] = (T)(img)(_p1##x,_n1##y,_p2##z,c), I[17] = (T)(img)(x,_n1##y,_p2##z,c), I[18] = (T)(img)(_n1##x,_n1##y,_p2##z,c), I[19] = (T)(img)(_n2##x,_n1##y,_p2##z,c), \ - I[20] = (T)(img)(_p2##x,_n2##y,_p2##z,c), I[21] = (T)(img)(_p1##x,_n2##y,_p2##z,c), I[22] = (T)(img)(x,_n2##y,_p2##z,c), I[23] = (T)(img)(_n1##x,_n2##y,_p2##z,c), I[24] = (T)(img)(_n2##x,_n2##y,_p2##z,c), \ - I[25] = (T)(img)(_p2##x,_p2##y,_p1##z,c), I[26] = (T)(img)(_p1##x,_p2##y,_p1##z,c), I[27] = (T)(img)(x,_p2##y,_p1##z,c), I[28] = (T)(img)(_n1##x,_p2##y,_p1##z,c), I[29] = (T)(img)(_n2##x,_p2##y,_p1##z,c), \ - I[30] = (T)(img)(_p2##x,_p1##y,_p1##z,c), I[31] = (T)(img)(_p1##x,_p1##y,_p1##z,c), I[32] = (T)(img)(x,_p1##y,_p1##z,c), I[33] = (T)(img)(_n1##x,_p1##y,_p1##z,c), I[34] = (T)(img)(_n2##x,_p1##y,_p1##z,c), \ - I[35] = (T)(img)(_p2##x,y,_p1##z,c), I[36] = (T)(img)(_p1##x,y,_p1##z,c), I[37] = (T)(img)(x,y,_p1##z,c), I[38] = (T)(img)(_n1##x,y,_p1##z,c), I[39] = (T)(img)(_n2##x,y,_p1##z,c), \ - I[40] = (T)(img)(_p2##x,_n1##y,_p1##z,c), I[41] = (T)(img)(_p1##x,_n1##y,_p1##z,c), I[42] = (T)(img)(x,_n1##y,_p1##z,c), I[43] = (T)(img)(_n1##x,_n1##y,_p1##z,c), I[44] = (T)(img)(_n2##x,_n1##y,_p1##z,c), \ - I[45] = (T)(img)(_p2##x,_n2##y,_p1##z,c), I[46] = (T)(img)(_p1##x,_n2##y,_p1##z,c), I[47] = (T)(img)(x,_n2##y,_p1##z,c), I[48] = (T)(img)(_n1##x,_n2##y,_p1##z,c), I[49] = (T)(img)(_n2##x,_n2##y,_p1##z,c), \ - I[50] = (T)(img)(_p2##x,_p2##y,z,c), I[51] = (T)(img)(_p1##x,_p2##y,z,c), I[52] = (T)(img)(x,_p2##y,z,c), I[53] = (T)(img)(_n1##x,_p2##y,z,c), I[54] = (T)(img)(_n2##x,_p2##y,z,c), \ - I[55] = (T)(img)(_p2##x,_p1##y,z,c), I[56] = (T)(img)(_p1##x,_p1##y,z,c), I[57] = (T)(img)(x,_p1##y,z,c), I[58] = (T)(img)(_n1##x,_p1##y,z,c), I[59] = (T)(img)(_n2##x,_p1##y,z,c), \ - I[60] = (T)(img)(_p2##x,y,z,c), I[61] = (T)(img)(_p1##x,y,z,c), I[62] = (T)(img)(x,y,z,c), I[63] = (T)(img)(_n1##x,y,z,c), I[64] = (T)(img)(_n2##x,y,z,c), \ - I[65] = (T)(img)(_p2##x,_n1##y,z,c), I[66] = (T)(img)(_p1##x,_n1##y,z,c), I[67] = (T)(img)(x,_n1##y,z,c), I[68] = (T)(img)(_n1##x,_n1##y,z,c), I[69] = (T)(img)(_n2##x,_n1##y,z,c), \ - I[70] = (T)(img)(_p2##x,_n2##y,z,c), I[71] = (T)(img)(_p1##x,_n2##y,z,c), I[72] = (T)(img)(x,_n2##y,z,c), I[73] = (T)(img)(_n1##x,_n2##y,z,c), I[74] = (T)(img)(_n2##x,_n2##y,z,c), \ - I[75] = (T)(img)(_p2##x,_p2##y,_n1##z,c), I[76] = (T)(img)(_p1##x,_p2##y,_n1##z,c), I[77] = (T)(img)(x,_p2##y,_n1##z,c), I[78] = (T)(img)(_n1##x,_p2##y,_n1##z,c), I[79] = (T)(img)(_n2##x,_p2##y,_n1##z,c), \ - I[80] = (T)(img)(_p2##x,_p1##y,_n1##z,c), I[81] = (T)(img)(_p1##x,_p1##y,_n1##z,c), I[82] = (T)(img)(x,_p1##y,_n1##z,c), I[83] = (T)(img)(_n1##x,_p1##y,_n1##z,c), I[84] = (T)(img)(_n2##x,_p1##y,_n1##z,c), \ - I[85] = (T)(img)(_p2##x,y,_n1##z,c), I[86] = (T)(img)(_p1##x,y,_n1##z,c), I[87] = (T)(img)(x,y,_n1##z,c), I[88] = (T)(img)(_n1##x,y,_n1##z,c), I[89] = (T)(img)(_n2##x,y,_n1##z,c), \ - I[90] = (T)(img)(_p2##x,_n1##y,_n1##z,c), I[91] = (T)(img)(_p1##x,_n1##y,_n1##z,c), I[92] = (T)(img)(x,_n1##y,_n1##z,c), I[93] = (T)(img)(_n1##x,_n1##y,_n1##z,c), I[94] = (T)(img)(_n2##x,_n1##y,_n1##z,c), \ - I[95] = (T)(img)(_p2##x,_n2##y,_n1##z,c), I[96] = (T)(img)(_p1##x,_n2##y,_n1##z,c), I[97] = (T)(img)(x,_n2##y,_n1##z,c), I[98] = (T)(img)(_n1##x,_n2##y,_n1##z,c), I[99] = (T)(img)(_n2##x,_n2##y,_n1##z,c), \ - I[100] = (T)(img)(_p2##x,_p2##y,_n2##z,c), I[101] = (T)(img)(_p1##x,_p2##y,_n2##z,c), I[102] = (T)(img)(x,_p2##y,_n2##z,c), I[103] = (T)(img)(_n1##x,_p2##y,_n2##z,c), I[104] = (T)(img)(_n2##x,_p2##y,_n2##z,c), \ - I[105] = (T)(img)(_p2##x,_p1##y,_n2##z,c), I[106] = (T)(img)(_p1##x,_p1##y,_n2##z,c), I[107] = (T)(img)(x,_p1##y,_n2##z,c), I[108] = (T)(img)(_n1##x,_p1##y,_n2##z,c), I[109] = (T)(img)(_n2##x,_p1##y,_n2##z,c), \ - I[110] = (T)(img)(_p2##x,y,_n2##z,c), I[111] = (T)(img)(_p1##x,y,_n2##z,c), I[112] = (T)(img)(x,y,_n2##z,c), I[113] = (T)(img)(_n1##x,y,_n2##z,c), I[114] = (T)(img)(_n2##x,y,_n2##z,c), \ - I[115] = (T)(img)(_p2##x,_n1##y,_n2##z,c), I[116] = (T)(img)(_p1##x,_n1##y,_n2##z,c), I[117] = (T)(img)(x,_n1##y,_n2##z,c), I[118] = (T)(img)(_n1##x,_n1##y,_n2##z,c), I[119] = (T)(img)(_n2##x,_n1##y,_n2##z,c), \ - I[120] = (T)(img)(_p2##x,_n2##y,_n2##z,c), I[121] = (T)(img)(_p1##x,_n2##y,_n2##z,c), I[122] = (T)(img)(x,_n2##y,_n2##z,c), I[123] = (T)(img)(_n1##x,_n2##y,_n2##z,c), I[124] = (T)(img)(_n2##x,_n2##y,_n2##z,c); - -// Define 6x6x6 loop macros -//---------------------------- -#define cimg_for6x6x6(img,x,y,z,c,I,T) \ - cimg_for6((img)._depth,z) cimg_for6((img)._height,y) for (int x = 0, \ - _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = (int)( \ - (I[0] = I[1] = I[2] = (T)(img)(0,_p2##y,_p2##z,c)), \ - (I[6] = I[7] = I[8] = (T)(img)(0,_p1##y,_p2##z,c)), \ - (I[12] = I[13] = I[14] = (T)(img)(0,y,_p2##z,c)), \ - (I[18] = I[19] = I[20] = (T)(img)(0,_n1##y,_p2##z,c)), \ - (I[24] = I[25] = I[26] = (T)(img)(0,_n2##y,_p2##z,c)), \ - (I[30] = I[31] = I[32] = (T)(img)(0,_n3##y,_p2##z,c)), \ - (I[36] = I[37] = I[38] = (T)(img)(0,_p2##y,_p1##z,c)), \ - (I[42] = I[43] = I[44] = (T)(img)(0,_p1##y,_p1##z,c)), \ - (I[48] = I[49] = I[50] = (T)(img)(0,y,_p1##z,c)), \ - (I[54] = I[55] = I[56] = (T)(img)(0,_n1##y,_p1##z,c)), \ - (I[60] = I[61] = I[62] = (T)(img)(0,_n2##y,_p1##z,c)), \ - (I[66] = I[67] = I[68] = (T)(img)(0,_n3##y,_p1##z,c)), \ - (I[72] = I[73] = I[74] = (T)(img)(0,_p2##y,z,c)), \ - (I[78] = I[79] = I[80] = (T)(img)(0,_p1##y,z,c)), \ - (I[84] = I[85] = I[86] = (T)(img)(0,y,z,c)), \ - (I[90] = I[91] = I[92] = (T)(img)(0,_n1##y,z,c)), \ - (I[96] = I[97] = I[98] = (T)(img)(0,_n2##y,z,c)), \ - (I[102] = I[103] = I[104] = (T)(img)(0,_n3##y,z,c)), \ - (I[108] = I[109] = I[110] = (T)(img)(0,_p2##y,_n1##z,c)), \ - (I[114] = I[115] = I[116] = (T)(img)(0,_p1##y,_n1##z,c)), \ - (I[120] = I[121] = I[122] = (T)(img)(0,y,_n1##z,c)), \ - (I[126] = I[127] = I[128] = (T)(img)(0,_n1##y,_n1##z,c)), \ - (I[132] = I[133] = I[134] = (T)(img)(0,_n2##y,_n1##z,c)), \ - (I[138] = I[139] = I[140] = (T)(img)(0,_n3##y,_n1##z,c)), \ - (I[144] = I[145] = I[146] = (T)(img)(0,_p2##y,_n2##z,c)), \ - (I[150] = I[151] = I[152] = (T)(img)(0,_p1##y,_n2##z,c)), \ - (I[156] = I[157] = I[158] = (T)(img)(0,y,_n2##z,c)), \ - (I[162] = I[163] = I[164] = (T)(img)(0,_n1##y,_n2##z,c)), \ - (I[168] = I[169] = I[170] = (T)(img)(0,_n2##y,_n2##z,c)), \ - (I[174] = I[175] = I[176] = (T)(img)(0,_n3##y,_n2##z,c)), \ - (I[180] = I[181] = I[182] = (T)(img)(0,_p2##y,_n3##z,c)), \ - (I[186] = I[187] = I[188] = (T)(img)(0,_p1##y,_n3##z,c)), \ - (I[192] = I[193] = I[194] = (T)(img)(0,y,_n3##z,c)), \ - (I[198] = I[199] = I[200] = (T)(img)(0,_n1##y,_n3##z,c)), \ - (I[204] = I[205] = I[206] = (T)(img)(0,_n2##y,_n3##z,c)), \ - (I[210] = I[211] = I[212] = (T)(img)(0,_n3##y,_n3##z,c)), \ - (I[3] = (T)(img)(_n1##x,_p2##y,_p2##z,c)), \ - (I[9] = (T)(img)(_n1##x,_p1##y,_p2##z,c)), \ - (I[15] = (T)(img)(_n1##x,y,_p2##z,c)), \ - (I[21] = (T)(img)(_n1##x,_n1##y,_p2##z,c)), \ - (I[27] = (T)(img)(_n1##x,_n2##y,_p2##z,c)), \ - (I[33] = (T)(img)(_n1##x,_n3##y,_p2##z,c)), \ - (I[39] = (T)(img)(_n1##x,_p2##y,_p1##z,c)), \ - (I[45] = (T)(img)(_n1##x,_p1##y,_p1##z,c)), \ - (I[51] = (T)(img)(_n1##x,y,_p1##z,c)), \ - (I[57] = (T)(img)(_n1##x,_n1##y,_p1##z,c)), \ - (I[63] = (T)(img)(_n1##x,_n2##y,_p1##z,c)), \ - (I[69] = (T)(img)(_n1##x,_n3##y,_p1##z,c)), \ - (I[75] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[81] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[87] = (T)(img)(_n1##x,y,z,c)), \ - (I[93] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[99] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[105] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[111] = (T)(img)(_n1##x,_p2##y,_n1##z,c)), \ - (I[117] = (T)(img)(_n1##x,_p1##y,_n1##z,c)), \ - (I[123] = (T)(img)(_n1##x,y,_n1##z,c)), \ - (I[129] = (T)(img)(_n1##x,_n1##y,_n1##z,c)), \ - (I[135] = (T)(img)(_n1##x,_n2##y,_n1##z,c)), \ - (I[141] = (T)(img)(_n1##x,_n3##y,_n1##z,c)), \ - (I[147] = (T)(img)(_n1##x,_p2##y,_n2##z,c)), \ - (I[153] = (T)(img)(_n1##x,_p1##y,_n2##z,c)), \ - (I[159] = (T)(img)(_n1##x,y,_n2##z,c)), \ - (I[165] = (T)(img)(_n1##x,_n1##y,_n2##z,c)), \ - (I[171] = (T)(img)(_n1##x,_n2##y,_n2##z,c)), \ - (I[177] = (T)(img)(_n1##x,_n3##y,_n2##z,c)), \ - (I[183] = (T)(img)(_n1##x,_p2##y,_n3##z,c)), \ - (I[189] = (T)(img)(_n1##x,_p1##y,_n3##z,c)), \ - (I[195] = (T)(img)(_n1##x,y,_n3##z,c)), \ - (I[201] = (T)(img)(_n1##x,_n1##y,_n3##z,c)), \ - (I[207] = (T)(img)(_n1##x,_n2##y,_n3##z,c)), \ - (I[213] = (T)(img)(_n1##x,_n3##y,_n3##z,c)), \ - (I[4] = (T)(img)(_n2##x,_p2##y,_p2##z,c)), \ - (I[10] = (T)(img)(_n2##x,_p1##y,_p2##z,c)), \ - (I[16] = (T)(img)(_n2##x,y,_p2##z,c)), \ - (I[22] = (T)(img)(_n2##x,_n1##y,_p2##z,c)), \ - (I[28] = (T)(img)(_n2##x,_n2##y,_p2##z,c)), \ - (I[34] = (T)(img)(_n2##x,_n3##y,_p2##z,c)), \ - (I[40] = (T)(img)(_n2##x,_p2##y,_p1##z,c)), \ - (I[46] = (T)(img)(_n2##x,_p1##y,_p1##z,c)), \ - (I[52] = (T)(img)(_n2##x,y,_p1##z,c)), \ - (I[58] = (T)(img)(_n2##x,_n1##y,_p1##z,c)), \ - (I[64] = (T)(img)(_n2##x,_n2##y,_p1##z,c)), \ - (I[70] = (T)(img)(_n2##x,_n3##y,_p1##z,c)), \ - (I[76] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[82] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[88] = (T)(img)(_n2##x,y,z,c)), \ - (I[94] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[100] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[106] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[112] = (T)(img)(_n2##x,_p2##y,_n1##z,c)), \ - (I[118] = (T)(img)(_n2##x,_p1##y,_n1##z,c)), \ - (I[124] = (T)(img)(_n2##x,y,_n1##z,c)), \ - (I[130] = (T)(img)(_n2##x,_n1##y,_n1##z,c)), \ - (I[136] = (T)(img)(_n2##x,_n2##y,_n1##z,c)), \ - (I[142] = (T)(img)(_n2##x,_n3##y,_n1##z,c)), \ - (I[148] = (T)(img)(_n2##x,_p2##y,_n2##z,c)), \ - (I[154] = (T)(img)(_n2##x,_p1##y,_n2##z,c)), \ - (I[160] = (T)(img)(_n2##x,y,_n2##z,c)), \ - (I[166] = (T)(img)(_n2##x,_n1##y,_n2##z,c)), \ - (I[172] = (T)(img)(_n2##x,_n2##y,_n2##z,c)), \ - (I[178] = (T)(img)(_n2##x,_n3##y,_n2##z,c)), \ - (I[184] = (T)(img)(_n2##x,_p2##y,_n3##z,c)), \ - (I[190] = (T)(img)(_n2##x,_p1##y,_n3##z,c)), \ - (I[196] = (T)(img)(_n2##x,y,_n3##z,c)), \ - (I[202] = (T)(img)(_n2##x,_n1##y,_n3##z,c)), \ - (I[208] = (T)(img)(_n2##x,_n2##y,_n3##z,c)), \ - (I[214] = (T)(img)(_n2##x,_n3##y,_n3##z,c)), \ - 3>=((img)._width)?(img).width() - 1:3); \ - (_n3##x<(img).width() && ( \ - (I[5] = (T)(img)(_n3##x,_p2##y,_p2##z,c)), \ - (I[11] = (T)(img)(_n3##x,_p1##y,_p2##z,c)), \ - (I[17] = (T)(img)(_n3##x,y,_p2##z,c)), \ - (I[23] = (T)(img)(_n3##x,_n1##y,_p2##z,c)), \ - (I[29] = (T)(img)(_n3##x,_n2##y,_p2##z,c)), \ - (I[35] = (T)(img)(_n3##x,_n3##y,_p2##z,c)), \ - (I[41] = (T)(img)(_n3##x,_p2##y,_p1##z,c)), \ - (I[47] = (T)(img)(_n3##x,_p1##y,_p1##z,c)), \ - (I[53] = (T)(img)(_n3##x,y,_p1##z,c)), \ - (I[59] = (T)(img)(_n3##x,_n1##y,_p1##z,c)), \ - (I[65] = (T)(img)(_n3##x,_n2##y,_p1##z,c)), \ - (I[71] = (T)(img)(_n3##x,_n3##y,_p1##z,c)), \ - (I[77] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[83] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[89] = (T)(img)(_n3##x,y,z,c)), \ - (I[95] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[101] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[107] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[113] = (T)(img)(_n3##x,_p2##y,_n1##z,c)), \ - (I[119] = (T)(img)(_n3##x,_p1##y,_n1##z,c)), \ - (I[125] = (T)(img)(_n3##x,y,_n1##z,c)), \ - (I[131] = (T)(img)(_n3##x,_n1##y,_n1##z,c)), \ - (I[137] = (T)(img)(_n3##x,_n2##y,_n1##z,c)), \ - (I[143] = (T)(img)(_n3##x,_n3##y,_n1##z,c)), \ - (I[149] = (T)(img)(_n3##x,_p2##y,_n2##z,c)), \ - (I[155] = (T)(img)(_n3##x,_p1##y,_n2##z,c)), \ - (I[161] = (T)(img)(_n3##x,y,_n2##z,c)), \ - (I[167] = (T)(img)(_n3##x,_n1##y,_n2##z,c)), \ - (I[173] = (T)(img)(_n3##x,_n2##y,_n2##z,c)), \ - (I[179] = (T)(img)(_n3##x,_n3##y,_n2##z,c)), \ - (I[185] = (T)(img)(_n3##x,_p2##y,_n3##z,c)), \ - (I[191] = (T)(img)(_n3##x,_p1##y,_n3##z,c)), \ - (I[197] = (T)(img)(_n3##x,y,_n3##z,c)), \ - (I[203] = (T)(img)(_n3##x,_n1##y,_n3##z,c)), \ - (I[209] = (T)(img)(_n3##x,_n2##y,_n3##z,c)), \ - (I[215] = (T)(img)(_n3##x,_n3##y,_n3##z,c)),1)) || \ - _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], \ - I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], \ - I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], \ - I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \ - I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], \ - I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], \ - I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], \ - I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], \ - I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], \ - I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], \ - I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], \ - I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], \ - I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], \ - I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], \ - I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], \ - I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], \ - I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], \ - I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], \ - I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], \ - I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], \ - I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], \ - I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], \ - I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], \ - I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], \ - I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], \ - I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], \ - I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], \ - I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], \ - I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], \ - I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], \ - I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], \ - I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], \ - I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], \ - I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], \ - I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], \ - I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], \ - _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x) - -#define cimg_for_in6x6x6(img,x0,y0,z0,x1,y1,z1,x,y,z,c,I,T) \ - cimg_for_in6((img)._depth,z0,z1,z) cimg_for_in6((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = (int)( \ - (I[0] = (T)(img)(_p2##x,_p2##y,_p2##z,c)), \ - (I[6] = (T)(img)(_p2##x,_p1##y,_p2##z,c)), \ - (I[12] = (T)(img)(_p2##x,y,_p2##z,c)), \ - (I[18] = (T)(img)(_p2##x,_n1##y,_p2##z,c)), \ - (I[24] = (T)(img)(_p2##x,_n2##y,_p2##z,c)), \ - (I[30] = (T)(img)(_p2##x,_n3##y,_p2##z,c)), \ - (I[36] = (T)(img)(_p2##x,_p2##y,_p1##z,c)), \ - (I[42] = (T)(img)(_p2##x,_p1##y,_p1##z,c)), \ - (I[48] = (T)(img)(_p2##x,y,_p1##z,c)), \ - (I[54] = (T)(img)(_p2##x,_n1##y,_p1##z,c)), \ - (I[60] = (T)(img)(_p2##x,_n2##y,_p1##z,c)), \ - (I[66] = (T)(img)(_p2##x,_n3##y,_p1##z,c)), \ - (I[72] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[78] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[84] = (T)(img)(_p2##x,y,z,c)), \ - (I[90] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[96] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[102] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[108] = (T)(img)(_p2##x,_p2##y,_n1##z,c)), \ - (I[114] = (T)(img)(_p2##x,_p1##y,_n1##z,c)), \ - (I[120] = (T)(img)(_p2##x,y,_n1##z,c)), \ - (I[126] = (T)(img)(_p2##x,_n1##y,_n1##z,c)), \ - (I[132] = (T)(img)(_p2##x,_n2##y,_n1##z,c)), \ - (I[138] = (T)(img)(_p2##x,_n3##y,_n1##z,c)), \ - (I[144] = (T)(img)(_p2##x,_p2##y,_n2##z,c)), \ - (I[150] = (T)(img)(_p2##x,_p1##y,_n2##z,c)), \ - (I[156] = (T)(img)(_p2##x,y,_n2##z,c)), \ - (I[162] = (T)(img)(_p2##x,_n1##y,_n2##z,c)), \ - (I[168] = (T)(img)(_p2##x,_n2##y,_n2##z,c)), \ - (I[174] = (T)(img)(_p2##x,_n3##y,_n2##z,c)), \ - (I[180] = (T)(img)(_p2##x,_p2##y,_n3##z,c)), \ - (I[186] = (T)(img)(_p2##x,_p1##y,_n3##z,c)), \ - (I[192] = (T)(img)(_p2##x,y,_n3##z,c)), \ - (I[198] = (T)(img)(_p2##x,_n1##y,_n3##z,c)), \ - (I[204] = (T)(img)(_p2##x,_n2##y,_n3##z,c)), \ - (I[210] = (T)(img)(_p2##x,_n3##y,_n3##z,c)), \ - (I[1] = (T)(img)(_p1##x,_p2##y,_p2##z,c)), \ - (I[7] = (T)(img)(_p1##x,_p1##y,_p2##z,c)), \ - (I[13] = (T)(img)(_p1##x,y,_p2##z,c)), \ - (I[19] = (T)(img)(_p1##x,_n1##y,_p2##z,c)), \ - (I[25] = (T)(img)(_p1##x,_n2##y,_p2##z,c)), \ - (I[31] = (T)(img)(_p1##x,_n3##y,_p2##z,c)), \ - (I[37] = (T)(img)(_p1##x,_p2##y,_p1##z,c)), \ - (I[43] = (T)(img)(_p1##x,_p1##y,_p1##z,c)), \ - (I[49] = (T)(img)(_p1##x,y,_p1##z,c)), \ - (I[55] = (T)(img)(_p1##x,_n1##y,_p1##z,c)), \ - (I[61] = (T)(img)(_p1##x,_n2##y,_p1##z,c)), \ - (I[67] = (T)(img)(_p1##x,_n3##y,_p1##z,c)), \ - (I[73] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[79] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[85] = (T)(img)(_p1##x,y,z,c)), \ - (I[91] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[97] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[103] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[109] = (T)(img)(_p1##x,_p2##y,_n1##z,c)), \ - (I[115] = (T)(img)(_p1##x,_p1##y,_n1##z,c)), \ - (I[121] = (T)(img)(_p1##x,y,_n1##z,c)), \ - (I[127] = (T)(img)(_p1##x,_n1##y,_n1##z,c)), \ - (I[133] = (T)(img)(_p1##x,_n2##y,_n1##z,c)), \ - (I[139] = (T)(img)(_p1##x,_n3##y,_n1##z,c)), \ - (I[145] = (T)(img)(_p1##x,_p2##y,_n2##z,c)), \ - (I[151] = (T)(img)(_p1##x,_p1##y,_n2##z,c)), \ - (I[157] = (T)(img)(_p1##x,y,_n2##z,c)), \ - (I[163] = (T)(img)(_p1##x,_n1##y,_n2##z,c)), \ - (I[169] = (T)(img)(_p1##x,_n2##y,_n2##z,c)), \ - (I[175] = (T)(img)(_p1##x,_n3##y,_n2##z,c)), \ - (I[181] = (T)(img)(_p1##x,_p2##y,_n3##z,c)), \ - (I[187] = (T)(img)(_p1##x,_p1##y,_n3##z,c)), \ - (I[193] = (T)(img)(_p1##x,y,_n3##z,c)), \ - (I[199] = (T)(img)(_p1##x,_n1##y,_n3##z,c)), \ - (I[205] = (T)(img)(_p1##x,_n2##y,_n3##z,c)), \ - (I[211] = (T)(img)(_p1##x,_n3##y,_n3##z,c)), \ - (I[2] = (T)(img)(x,_p2##y,_p2##z,c)), \ - (I[8] = (T)(img)(x,_p1##y,_p2##z,c)), \ - (I[14] = (T)(img)(x,y,_p2##z,c)), \ - (I[20] = (T)(img)(x,_n1##y,_p2##z,c)), \ - (I[26] = (T)(img)(x,_n2##y,_p2##z,c)), \ - (I[32] = (T)(img)(x,_n3##y,_p2##z,c)), \ - (I[38] = (T)(img)(x,_p2##y,_p1##z,c)), \ - (I[44] = (T)(img)(x,_p1##y,_p1##z,c)), \ - (I[50] = (T)(img)(x,y,_p1##z,c)), \ - (I[56] = (T)(img)(x,_n1##y,_p1##z,c)), \ - (I[62] = (T)(img)(x,_n2##y,_p1##z,c)), \ - (I[68] = (T)(img)(x,_n3##y,_p1##z,c)), \ - (I[74] = (T)(img)(x,_p2##y,z,c)), \ - (I[80] = (T)(img)(x,_p1##y,z,c)), \ - (I[86] = (T)(img)(x,y,z,c)), \ - (I[92] = (T)(img)(x,_n1##y,z,c)), \ - (I[98] = (T)(img)(x,_n2##y,z,c)), \ - (I[104] = (T)(img)(x,_n3##y,z,c)), \ - (I[110] = (T)(img)(x,_p2##y,_n1##z,c)), \ - (I[116] = (T)(img)(x,_p1##y,_n1##z,c)), \ - (I[122] = (T)(img)(x,y,_n1##z,c)), \ - (I[128] = (T)(img)(x,_n1##y,_n1##z,c)), \ - (I[134] = (T)(img)(x,_n2##y,_n1##z,c)), \ - (I[140] = (T)(img)(x,_n3##y,_n1##z,c)), \ - (I[146] = (T)(img)(x,_p2##y,_n2##z,c)), \ - (I[152] = (T)(img)(x,_p1##y,_n2##z,c)), \ - (I[158] = (T)(img)(x,y,_n2##z,c)), \ - (I[164] = (T)(img)(x,_n1##y,_n2##z,c)), \ - (I[170] = (T)(img)(x,_n2##y,_n2##z,c)), \ - (I[176] = (T)(img)(x,_n3##y,_n2##z,c)), \ - (I[182] = (T)(img)(x,_p2##y,_n3##z,c)), \ - (I[188] = (T)(img)(x,_p1##y,_n3##z,c)), \ - (I[194] = (T)(img)(x,y,_n3##z,c)), \ - (I[200] = (T)(img)(x,_n1##y,_n3##z,c)), \ - (I[206] = (T)(img)(x,_n2##y,_n3##z,c)), \ - (I[212] = (T)(img)(x,_n3##y,_n3##z,c)), \ - (I[3] = (T)(img)(_n1##x,_p2##y,_p2##z,c)), \ - (I[9] = (T)(img)(_n1##x,_p1##y,_p2##z,c)), \ - (I[15] = (T)(img)(_n1##x,y,_p2##z,c)), \ - (I[21] = (T)(img)(_n1##x,_n1##y,_p2##z,c)), \ - (I[27] = (T)(img)(_n1##x,_n2##y,_p2##z,c)), \ - (I[33] = (T)(img)(_n1##x,_n3##y,_p2##z,c)), \ - (I[39] = (T)(img)(_n1##x,_p2##y,_p1##z,c)), \ - (I[45] = (T)(img)(_n1##x,_p1##y,_p1##z,c)), \ - (I[51] = (T)(img)(_n1##x,y,_p1##z,c)), \ - (I[57] = (T)(img)(_n1##x,_n1##y,_p1##z,c)), \ - (I[63] = (T)(img)(_n1##x,_n2##y,_p1##z,c)), \ - (I[69] = (T)(img)(_n1##x,_n3##y,_p1##z,c)), \ - (I[75] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[81] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[87] = (T)(img)(_n1##x,y,z,c)), \ - (I[93] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[99] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[105] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[111] = (T)(img)(_n1##x,_p2##y,_n1##z,c)), \ - (I[117] = (T)(img)(_n1##x,_p1##y,_n1##z,c)), \ - (I[123] = (T)(img)(_n1##x,y,_n1##z,c)), \ - (I[129] = (T)(img)(_n1##x,_n1##y,_n1##z,c)), \ - (I[135] = (T)(img)(_n1##x,_n2##y,_n1##z,c)), \ - (I[141] = (T)(img)(_n1##x,_n3##y,_n1##z,c)), \ - (I[147] = (T)(img)(_n1##x,_p2##y,_n2##z,c)), \ - (I[153] = (T)(img)(_n1##x,_p1##y,_n2##z,c)), \ - (I[159] = (T)(img)(_n1##x,y,_n2##z,c)), \ - (I[165] = (T)(img)(_n1##x,_n1##y,_n2##z,c)), \ - (I[171] = (T)(img)(_n1##x,_n2##y,_n2##z,c)), \ - (I[177] = (T)(img)(_n1##x,_n3##y,_n2##z,c)), \ - (I[183] = (T)(img)(_n1##x,_p2##y,_n3##z,c)), \ - (I[189] = (T)(img)(_n1##x,_p1##y,_n3##z,c)), \ - (I[195] = (T)(img)(_n1##x,y,_n3##z,c)), \ - (I[201] = (T)(img)(_n1##x,_n1##y,_n3##z,c)), \ - (I[207] = (T)(img)(_n1##x,_n2##y,_n3##z,c)), \ - (I[213] = (T)(img)(_n1##x,_n3##y,_n3##z,c)), \ - (I[4] = (T)(img)(_n2##x,_p2##y,_p2##z,c)), \ - (I[10] = (T)(img)(_n2##x,_p1##y,_p2##z,c)), \ - (I[16] = (T)(img)(_n2##x,y,_p2##z,c)), \ - (I[22] = (T)(img)(_n2##x,_n1##y,_p2##z,c)), \ - (I[28] = (T)(img)(_n2##x,_n2##y,_p2##z,c)), \ - (I[34] = (T)(img)(_n2##x,_n3##y,_p2##z,c)), \ - (I[40] = (T)(img)(_n2##x,_p2##y,_p1##z,c)), \ - (I[46] = (T)(img)(_n2##x,_p1##y,_p1##z,c)), \ - (I[52] = (T)(img)(_n2##x,y,_p1##z,c)), \ - (I[58] = (T)(img)(_n2##x,_n1##y,_p1##z,c)), \ - (I[64] = (T)(img)(_n2##x,_n2##y,_p1##z,c)), \ - (I[70] = (T)(img)(_n2##x,_n3##y,_p1##z,c)), \ - (I[76] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[82] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[88] = (T)(img)(_n2##x,y,z,c)), \ - (I[94] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[100] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[106] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[112] = (T)(img)(_n2##x,_p2##y,_n1##z,c)), \ - (I[118] = (T)(img)(_n2##x,_p1##y,_n1##z,c)), \ - (I[124] = (T)(img)(_n2##x,y,_n1##z,c)), \ - (I[130] = (T)(img)(_n2##x,_n1##y,_n1##z,c)), \ - (I[136] = (T)(img)(_n2##x,_n2##y,_n1##z,c)), \ - (I[142] = (T)(img)(_n2##x,_n3##y,_n1##z,c)), \ - (I[148] = (T)(img)(_n2##x,_p2##y,_n2##z,c)), \ - (I[154] = (T)(img)(_n2##x,_p1##y,_n2##z,c)), \ - (I[160] = (T)(img)(_n2##x,y,_n2##z,c)), \ - (I[166] = (T)(img)(_n2##x,_n1##y,_n2##z,c)), \ - (I[172] = (T)(img)(_n2##x,_n2##y,_n2##z,c)), \ - (I[178] = (T)(img)(_n2##x,_n3##y,_n2##z,c)), \ - (I[184] = (T)(img)(_n2##x,_p2##y,_n3##z,c)), \ - (I[190] = (T)(img)(_n2##x,_p1##y,_n3##z,c)), \ - (I[196] = (T)(img)(_n2##x,y,_n3##z,c)), \ - (I[202] = (T)(img)(_n2##x,_n1##y,_n3##z,c)), \ - (I[208] = (T)(img)(_n2##x,_n2##y,_n3##z,c)), \ - (I[214] = (T)(img)(_n2##x,_n3##y,_n3##z,c)), \ - x + 3>=(img).width()?(img).width() - 1:x + 3); \ - x<=(int)(x1) && ((_n3##x<(img).width() && ( \ - (I[5] = (T)(img)(_n3##x,_p2##y,_p2##z,c)), \ - (I[11] = (T)(img)(_n3##x,_p1##y,_p2##z,c)), \ - (I[17] = (T)(img)(_n3##x,y,_p2##z,c)), \ - (I[23] = (T)(img)(_n3##x,_n1##y,_p2##z,c)), \ - (I[29] = (T)(img)(_n3##x,_n2##y,_p2##z,c)), \ - (I[35] = (T)(img)(_n3##x,_n3##y,_p2##z,c)), \ - (I[41] = (T)(img)(_n3##x,_p2##y,_p1##z,c)), \ - (I[47] = (T)(img)(_n3##x,_p1##y,_p1##z,c)), \ - (I[53] = (T)(img)(_n3##x,y,_p1##z,c)), \ - (I[59] = (T)(img)(_n3##x,_n1##y,_p1##z,c)), \ - (I[65] = (T)(img)(_n3##x,_n2##y,_p1##z,c)), \ - (I[71] = (T)(img)(_n3##x,_n3##y,_p1##z,c)), \ - (I[77] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[83] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[89] = (T)(img)(_n3##x,y,z,c)), \ - (I[95] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[101] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[107] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[113] = (T)(img)(_n3##x,_p2##y,_n1##z,c)), \ - (I[119] = (T)(img)(_n3##x,_p1##y,_n1##z,c)), \ - (I[125] = (T)(img)(_n3##x,y,_n1##z,c)), \ - (I[131] = (T)(img)(_n3##x,_n1##y,_n1##z,c)), \ - (I[137] = (T)(img)(_n3##x,_n2##y,_n1##z,c)), \ - (I[143] = (T)(img)(_n3##x,_n3##y,_n1##z,c)), \ - (I[149] = (T)(img)(_n3##x,_p2##y,_n2##z,c)), \ - (I[155] = (T)(img)(_n3##x,_p1##y,_n2##z,c)), \ - (I[161] = (T)(img)(_n3##x,y,_n2##z,c)), \ - (I[167] = (T)(img)(_n3##x,_n1##y,_n2##z,c)), \ - (I[173] = (T)(img)(_n3##x,_n2##y,_n2##z,c)), \ - (I[179] = (T)(img)(_n3##x,_n3##y,_n2##z,c)), \ - (I[185] = (T)(img)(_n3##x,_p2##y,_n3##z,c)), \ - (I[191] = (T)(img)(_n3##x,_p1##y,_n3##z,c)), \ - (I[197] = (T)(img)(_n3##x,y,_n3##z,c)), \ - (I[203] = (T)(img)(_n3##x,_n1##y,_n3##z,c)), \ - (I[209] = (T)(img)(_n3##x,_n2##y,_n3##z,c)), \ - (I[215] = (T)(img)(_n3##x,_n3##y,_n3##z,c)),1)) || \ - _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], \ - I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], \ - I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], \ - I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \ - I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], \ - I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], \ - I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], \ - I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], \ - I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], \ - I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], \ - I[60] = I[61], I[61] = I[62], I[62] = I[63], I[63] = I[64], I[64] = I[65], \ - I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], \ - I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], \ - I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], \ - I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], \ - I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], \ - I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], \ - I[102] = I[103], I[103] = I[104], I[104] = I[105], I[105] = I[106], I[106] = I[107], \ - I[108] = I[109], I[109] = I[110], I[110] = I[111], I[111] = I[112], I[112] = I[113], \ - I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], \ - I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], \ - I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], \ - I[132] = I[133], I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], \ - I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], \ - I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], \ - I[150] = I[151], I[151] = I[152], I[152] = I[153], I[153] = I[154], I[154] = I[155], \ - I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], I[160] = I[161], \ - I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], \ - I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], \ - I[174] = I[175], I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], \ - I[180] = I[181], I[181] = I[182], I[182] = I[183], I[183] = I[184], I[184] = I[185], \ - I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], \ - I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], \ - I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], I[202] = I[203], \ - I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], \ - I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], \ - _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x) - -#define cimg_get6x6x6(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p2##x,_p2##y,_p2##z,c), I[1] = (T)(img)(_p1##x,_p2##y,_p2##z,c), I[2] = (T)(img)(x,_p2##y,_p2##z,c), I[3] = (T)(img)(_n1##x,_p2##y,_p2##z,c), I[4] = (T)(img)(_n2##x,_p2##y,_p2##z,c), I[5] = (T)(img)(_n3##x,_p2##y,_p2##z,c), \ - I[6] = (T)(img)(_p2##x,_p1##y,_p2##z,c), I[7] = (T)(img)(_p1##x,_p1##y,_p2##z,c), I[8] = (T)(img)(x,_p1##y,_p2##z,c), I[9] = (T)(img)(_n1##x,_p1##y,_p2##z,c), I[10] = (T)(img)(_n2##x,_p1##y,_p2##z,c), I[11] = (T)(img)(_n3##x,_p1##y,_p2##z,c), \ - I[12] = (T)(img)(_p2##x,y,_p2##z,c), I[13] = (T)(img)(_p1##x,y,_p2##z,c), I[14] = (T)(img)(x,y,_p2##z,c), I[15] = (T)(img)(_n1##x,y,_p2##z,c), I[16] = (T)(img)(_n2##x,y,_p2##z,c), I[17] = (T)(img)(_n3##x,y,_p2##z,c), \ - I[18] = (T)(img)(_p2##x,_n1##y,_p2##z,c), I[19] = (T)(img)(_p1##x,_n1##y,_p2##z,c), I[20] = (T)(img)(x,_n1##y,_p2##z,c), I[21] = (T)(img)(_n1##x,_n1##y,_p2##z,c), I[22] = (T)(img)(_n2##x,_n1##y,_p2##z,c), I[23] = (T)(img)(_n3##x,_n1##y,_p2##z,c), \ - I[24] = (T)(img)(_p2##x,_n2##y,_p2##z,c), I[25] = (T)(img)(_p1##x,_n2##y,_p2##z,c), I[26] = (T)(img)(x,_n2##y,_p2##z,c), I[27] = (T)(img)(_n1##x,_n2##y,_p2##z,c), I[28] = (T)(img)(_n2##x,_n2##y,_p2##z,c), I[29] = (T)(img)(_n3##x,_n2##y,_p2##z,c), \ - I[30] = (T)(img)(_p2##x,_n3##y,_p2##z,c), I[31] = (T)(img)(_p1##x,_n3##y,_p2##z,c), I[32] = (T)(img)(x,_n3##y,_p2##z,c), I[33] = (T)(img)(_n1##x,_n3##y,_p2##z,c), I[34] = (T)(img)(_n2##x,_n3##y,_p2##z,c), I[35] = (T)(img)(_n3##x,_n3##y,_p2##z,c), \ - I[36] = (T)(img)(_p2##x,_p2##y,_p1##z,c), I[37] = (T)(img)(_p1##x,_p2##y,_p1##z,c), I[38] = (T)(img)(x,_p2##y,_p1##z,c), I[39] = (T)(img)(_n1##x,_p2##y,_p1##z,c), I[40] = (T)(img)(_n2##x,_p2##y,_p1##z,c), I[41] = (T)(img)(_n3##x,_p2##y,_p1##z,c), \ - I[42] = (T)(img)(_p2##x,_p1##y,_p1##z,c), I[43] = (T)(img)(_p1##x,_p1##y,_p1##z,c), I[44] = (T)(img)(x,_p1##y,_p1##z,c), I[45] = (T)(img)(_n1##x,_p1##y,_p1##z,c), I[46] = (T)(img)(_n2##x,_p1##y,_p1##z,c), I[47] = (T)(img)(_n3##x,_p1##y,_p1##z,c), \ - I[48] = (T)(img)(_p2##x,y,_p1##z,c), I[49] = (T)(img)(_p1##x,y,_p1##z,c), I[50] = (T)(img)(x,y,_p1##z,c), I[51] = (T)(img)(_n1##x,y,_p1##z,c), I[52] = (T)(img)(_n2##x,y,_p1##z,c), I[53] = (T)(img)(_n3##x,y,_p1##z,c), \ - I[54] = (T)(img)(_p2##x,_n1##y,_p1##z,c), I[55] = (T)(img)(_p1##x,_n1##y,_p1##z,c), I[56] = (T)(img)(x,_n1##y,_p1##z,c), I[57] = (T)(img)(_n1##x,_n1##y,_p1##z,c), I[58] = (T)(img)(_n2##x,_n1##y,_p1##z,c), I[59] = (T)(img)(_n3##x,_n1##y,_p1##z,c), \ - I[60] = (T)(img)(_p2##x,_n2##y,_p1##z,c), I[61] = (T)(img)(_p1##x,_n2##y,_p1##z,c), I[62] = (T)(img)(x,_n2##y,_p1##z,c), I[63] = (T)(img)(_n1##x,_n2##y,_p1##z,c), I[64] = (T)(img)(_n2##x,_n2##y,_p1##z,c), I[65] = (T)(img)(_n3##x,_n2##y,_p1##z,c), \ - I[66] = (T)(img)(_p2##x,_n3##y,_p1##z,c), I[67] = (T)(img)(_p1##x,_n3##y,_p1##z,c), I[68] = (T)(img)(x,_n3##y,_p1##z,c), I[69] = (T)(img)(_n1##x,_n3##y,_p1##z,c), I[70] = (T)(img)(_n2##x,_n3##y,_p1##z,c), I[71] = (T)(img)(_n3##x,_n3##y,_p1##z,c), \ - I[72] = (T)(img)(_p2##x,_p2##y,z,c), I[73] = (T)(img)(_p1##x,_p2##y,z,c), I[74] = (T)(img)(x,_p2##y,z,c), I[75] = (T)(img)(_n1##x,_p2##y,z,c), I[76] = (T)(img)(_n2##x,_p2##y,z,c), I[77] = (T)(img)(_n3##x,_p2##y,z,c), \ - I[78] = (T)(img)(_p2##x,_p1##y,z,c), I[79] = (T)(img)(_p1##x,_p1##y,z,c), I[80] = (T)(img)(x,_p1##y,z,c), I[81] = (T)(img)(_n1##x,_p1##y,z,c), I[82] = (T)(img)(_n2##x,_p1##y,z,c), I[83] = (T)(img)(_n3##x,_p1##y,z,c), \ - I[84] = (T)(img)(_p2##x,y,z,c), I[85] = (T)(img)(_p1##x,y,z,c), I[86] = (T)(img)(x,y,z,c), I[87] = (T)(img)(_n1##x,y,z,c), I[88] = (T)(img)(_n2##x,y,z,c), I[89] = (T)(img)(_n3##x,y,z,c), \ - I[90] = (T)(img)(_p2##x,_n1##y,z,c), I[91] = (T)(img)(_p1##x,_n1##y,z,c), I[92] = (T)(img)(x,_n1##y,z,c), I[93] = (T)(img)(_n1##x,_n1##y,z,c), I[94] = (T)(img)(_n2##x,_n1##y,z,c), I[95] = (T)(img)(_n3##x,_n1##y,z,c), \ - I[96] = (T)(img)(_p2##x,_n2##y,z,c), I[97] = (T)(img)(_p1##x,_n2##y,z,c), I[98] = (T)(img)(x,_n2##y,z,c), I[99] = (T)(img)(_n1##x,_n2##y,z,c), I[100] = (T)(img)(_n2##x,_n2##y,z,c), I[101] = (T)(img)(_n3##x,_n2##y,z,c), \ - I[102] = (T)(img)(_p2##x,_n3##y,z,c), I[103] = (T)(img)(_p1##x,_n3##y,z,c), I[104] = (T)(img)(x,_n3##y,z,c), I[105] = (T)(img)(_n1##x,_n3##y,z,c), I[106] = (T)(img)(_n2##x,_n3##y,z,c), I[107] = (T)(img)(_n3##x,_n3##y,z,c), \ - I[108] = (T)(img)(_p2##x,_p2##y,_n1##z,c), I[109] = (T)(img)(_p1##x,_p2##y,_n1##z,c), I[110] = (T)(img)(x,_p2##y,_n1##z,c), I[111] = (T)(img)(_n1##x,_p2##y,_n1##z,c), I[112] = (T)(img)(_n2##x,_p2##y,_n1##z,c), I[113] = (T)(img)(_n3##x,_p2##y,_n1##z,c), \ - I[114] = (T)(img)(_p2##x,_p1##y,_n1##z,c), I[115] = (T)(img)(_p1##x,_p1##y,_n1##z,c), I[116] = (T)(img)(x,_p1##y,_n1##z,c), I[117] = (T)(img)(_n1##x,_p1##y,_n1##z,c), I[118] = (T)(img)(_n2##x,_p1##y,_n1##z,c), I[119] = (T)(img)(_n3##x,_p1##y,_n1##z,c), \ - I[120] = (T)(img)(_p2##x,y,_n1##z,c), I[121] = (T)(img)(_p1##x,y,_n1##z,c), I[122] = (T)(img)(x,y,_n1##z,c), I[123] = (T)(img)(_n1##x,y,_n1##z,c), I[124] = (T)(img)(_n2##x,y,_n1##z,c), I[125] = (T)(img)(_n3##x,y,_n1##z,c), \ - I[126] = (T)(img)(_p2##x,_n1##y,_n1##z,c), I[127] = (T)(img)(_p1##x,_n1##y,_n1##z,c), I[128] = (T)(img)(x,_n1##y,_n1##z,c), I[129] = (T)(img)(_n1##x,_n1##y,_n1##z,c), I[130] = (T)(img)(_n2##x,_n1##y,_n1##z,c), I[131] = (T)(img)(_n3##x,_n1##y,_n1##z,c), \ - I[132] = (T)(img)(_p2##x,_n2##y,_n1##z,c), I[133] = (T)(img)(_p1##x,_n2##y,_n1##z,c), I[134] = (T)(img)(x,_n2##y,_n1##z,c), I[135] = (T)(img)(_n1##x,_n2##y,_n1##z,c), I[136] = (T)(img)(_n2##x,_n2##y,_n1##z,c), I[137] = (T)(img)(_n3##x,_n2##y,_n1##z,c), \ - I[138] = (T)(img)(_p2##x,_n3##y,_n1##z,c), I[139] = (T)(img)(_p1##x,_n3##y,_n1##z,c), I[140] = (T)(img)(x,_n3##y,_n1##z,c), I[141] = (T)(img)(_n1##x,_n3##y,_n1##z,c), I[142] = (T)(img)(_n2##x,_n3##y,_n1##z,c), I[143] = (T)(img)(_n3##x,_n3##y,_n1##z,c), \ - I[144] = (T)(img)(_p2##x,_p2##y,_n2##z,c), I[145] = (T)(img)(_p1##x,_p2##y,_n2##z,c), I[146] = (T)(img)(x,_p2##y,_n2##z,c), I[147] = (T)(img)(_n1##x,_p2##y,_n2##z,c), I[148] = (T)(img)(_n2##x,_p2##y,_n2##z,c), I[149] = (T)(img)(_n3##x,_p2##y,_n2##z,c), \ - I[150] = (T)(img)(_p2##x,_p1##y,_n2##z,c), I[151] = (T)(img)(_p1##x,_p1##y,_n2##z,c), I[152] = (T)(img)(x,_p1##y,_n2##z,c), I[153] = (T)(img)(_n1##x,_p1##y,_n2##z,c), I[154] = (T)(img)(_n2##x,_p1##y,_n2##z,c), I[155] = (T)(img)(_n3##x,_p1##y,_n2##z,c), \ - I[156] = (T)(img)(_p2##x,y,_n2##z,c), I[157] = (T)(img)(_p1##x,y,_n2##z,c), I[158] = (T)(img)(x,y,_n2##z,c), I[159] = (T)(img)(_n1##x,y,_n2##z,c), I[160] = (T)(img)(_n2##x,y,_n2##z,c), I[161] = (T)(img)(_n3##x,y,_n2##z,c), \ - I[162] = (T)(img)(_p2##x,_n1##y,_n2##z,c), I[163] = (T)(img)(_p1##x,_n1##y,_n2##z,c), I[164] = (T)(img)(x,_n1##y,_n2##z,c), I[165] = (T)(img)(_n1##x,_n1##y,_n2##z,c), I[166] = (T)(img)(_n2##x,_n1##y,_n2##z,c), I[167] = (T)(img)(_n3##x,_n1##y,_n2##z,c), \ - I[168] = (T)(img)(_p2##x,_n2##y,_n2##z,c), I[169] = (T)(img)(_p1##x,_n2##y,_n2##z,c), I[170] = (T)(img)(x,_n2##y,_n2##z,c), I[171] = (T)(img)(_n1##x,_n2##y,_n2##z,c), I[172] = (T)(img)(_n2##x,_n2##y,_n2##z,c), I[173] = (T)(img)(_n3##x,_n2##y,_n2##z,c), \ - I[174] = (T)(img)(_p2##x,_n3##y,_n2##z,c), I[175] = (T)(img)(_p1##x,_n3##y,_n2##z,c), I[176] = (T)(img)(x,_n3##y,_n2##z,c), I[177] = (T)(img)(_n1##x,_n3##y,_n2##z,c), I[178] = (T)(img)(_n2##x,_n3##y,_n2##z,c), I[179] = (T)(img)(_n3##x,_n3##y,_n2##z,c), \ - I[180] = (T)(img)(_p2##x,_p2##y,_n3##z,c), I[181] = (T)(img)(_p1##x,_p2##y,_n3##z,c), I[182] = (T)(img)(x,_p2##y,_n3##z,c), I[183] = (T)(img)(_n1##x,_p2##y,_n3##z,c), I[184] = (T)(img)(_n2##x,_p2##y,_n3##z,c), I[185] = (T)(img)(_n3##x,_p2##y,_n3##z,c), \ - I[186] = (T)(img)(_p2##x,_p1##y,_n3##z,c), I[187] = (T)(img)(_p1##x,_p1##y,_n3##z,c), I[188] = (T)(img)(x,_p1##y,_n3##z,c), I[189] = (T)(img)(_n1##x,_p1##y,_n3##z,c), I[190] = (T)(img)(_n2##x,_p1##y,_n3##z,c), I[191] = (T)(img)(_n3##x,_p1##y,_n3##z,c), \ - I[192] = (T)(img)(_p2##x,y,_n3##z,c), I[193] = (T)(img)(_p1##x,y,_n3##z,c), I[194] = (T)(img)(x,y,_n3##z,c), I[195] = (T)(img)(_n1##x,y,_n3##z,c), I[196] = (T)(img)(_n2##x,y,_n3##z,c), I[197] = (T)(img)(_n3##x,y,_n3##z,c), \ - I[198] = (T)(img)(_p2##x,_n1##y,_n3##z,c), I[199] = (T)(img)(_p1##x,_n1##y,_n3##z,c), I[200] = (T)(img)(x,_n1##y,_n3##z,c), I[201] = (T)(img)(_n1##x,_n1##y,_n3##z,c), I[202] = (T)(img)(_n2##x,_n1##y,_n3##z,c), I[203] = (T)(img)(_n3##x,_n1##y,_n3##z,c), \ - I[204] = (T)(img)(_p2##x,_n2##y,_n3##z,c), I[205] = (T)(img)(_p1##x,_n2##y,_n3##z,c), I[206] = (T)(img)(x,_n2##y,_n3##z,c), I[207] = (T)(img)(_n1##x,_n2##y,_n3##z,c), I[208] = (T)(img)(_n2##x,_n2##y,_n3##z,c), I[209] = (T)(img)(_n3##x,_n2##y,_n3##z,c), \ - I[210] = (T)(img)(_p2##x,_n3##y,_n3##z,c), I[211] = (T)(img)(_p1##x,_n3##y,_n3##z,c), I[212] = (T)(img)(x,_n3##y,_n3##z,c), I[213] = (T)(img)(_n1##x,_n3##y,_n3##z,c), I[214] = (T)(img)(_n2##x,_n3##y,_n3##z,c), I[215] = (T)(img)(_n3##x,_n3##y,_n3##z,c); - -// Define 7x7x7 loop macros -//---------------------------- -#define cimg_for7x7x7(img,x,y,z,c,I,T) \ - cimg_for7((img)._depth,z) cimg_for7((img)._height,y) for (int x = 0, \ - _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = (T)(img)(0,_p3##y,_p3##z,c)), \ - (I[7] = I[8] = I[9] = I[10] = (T)(img)(0,_p2##y,_p3##z,c)), \ - (I[14] = I[15] = I[16] = I[17] = (T)(img)(0,_p1##y,_p3##z,c)), \ - (I[21] = I[22] = I[23] = I[24] = (T)(img)(0,y,_p3##z,c)), \ - (I[28] = I[29] = I[30] = I[31] = (T)(img)(0,_n1##y,_p3##z,c)), \ - (I[35] = I[36] = I[37] = I[38] = (T)(img)(0,_n2##y,_p3##z,c)), \ - (I[42] = I[43] = I[44] = I[45] = (T)(img)(0,_n3##y,_p3##z,c)), \ - (I[49] = I[50] = I[51] = I[52] = (T)(img)(0,_p3##y,_p2##z,c)), \ - (I[56] = I[57] = I[58] = I[59] = (T)(img)(0,_p2##y,_p2##z,c)), \ - (I[63] = I[64] = I[65] = I[66] = (T)(img)(0,_p1##y,_p2##z,c)), \ - (I[70] = I[71] = I[72] = I[73] = (T)(img)(0,y,_p2##z,c)), \ - (I[77] = I[78] = I[79] = I[80] = (T)(img)(0,_n1##y,_p2##z,c)), \ - (I[84] = I[85] = I[86] = I[87] = (T)(img)(0,_n2##y,_p2##z,c)), \ - (I[91] = I[92] = I[93] = I[94] = (T)(img)(0,_n3##y,_p2##z,c)), \ - (I[98] = I[99] = I[100] = I[101] = (T)(img)(0,_p3##y,_p1##z,c)), \ - (I[105] = I[106] = I[107] = I[108] = (T)(img)(0,_p2##y,_p1##z,c)), \ - (I[112] = I[113] = I[114] = I[115] = (T)(img)(0,_p1##y,_p1##z,c)), \ - (I[119] = I[120] = I[121] = I[122] = (T)(img)(0,y,_p1##z,c)), \ - (I[126] = I[127] = I[128] = I[129] = (T)(img)(0,_n1##y,_p1##z,c)), \ - (I[133] = I[134] = I[135] = I[136] = (T)(img)(0,_n2##y,_p1##z,c)), \ - (I[140] = I[141] = I[142] = I[143] = (T)(img)(0,_n3##y,_p1##z,c)), \ - (I[147] = I[148] = I[149] = I[150] = (T)(img)(0,_p3##y,z,c)), \ - (I[154] = I[155] = I[156] = I[157] = (T)(img)(0,_p2##y,z,c)), \ - (I[161] = I[162] = I[163] = I[164] = (T)(img)(0,_p1##y,z,c)), \ - (I[168] = I[169] = I[170] = I[171] = (T)(img)(0,y,z,c)), \ - (I[175] = I[176] = I[177] = I[178] = (T)(img)(0,_n1##y,z,c)), \ - (I[182] = I[183] = I[184] = I[185] = (T)(img)(0,_n2##y,z,c)), \ - (I[189] = I[190] = I[191] = I[192] = (T)(img)(0,_n3##y,z,c)), \ - (I[196] = I[197] = I[198] = I[199] = (T)(img)(0,_p3##y,_n1##z,c)), \ - (I[203] = I[204] = I[205] = I[206] = (T)(img)(0,_p2##y,_n1##z,c)), \ - (I[210] = I[211] = I[212] = I[213] = (T)(img)(0,_p1##y,_n1##z,c)), \ - (I[217] = I[218] = I[219] = I[220] = (T)(img)(0,y,_n1##z,c)), \ - (I[224] = I[225] = I[226] = I[227] = (T)(img)(0,_n1##y,_n1##z,c)), \ - (I[231] = I[232] = I[233] = I[234] = (T)(img)(0,_n2##y,_n1##z,c)), \ - (I[238] = I[239] = I[240] = I[241] = (T)(img)(0,_n3##y,_n1##z,c)), \ - (I[245] = I[246] = I[247] = I[248] = (T)(img)(0,_p3##y,_n2##z,c)), \ - (I[252] = I[253] = I[254] = I[255] = (T)(img)(0,_p2##y,_n2##z,c)), \ - (I[259] = I[260] = I[261] = I[262] = (T)(img)(0,_p1##y,_n2##z,c)), \ - (I[266] = I[267] = I[268] = I[269] = (T)(img)(0,y,_n2##z,c)), \ - (I[273] = I[274] = I[275] = I[276] = (T)(img)(0,_n1##y,_n2##z,c)), \ - (I[280] = I[281] = I[282] = I[283] = (T)(img)(0,_n2##y,_n2##z,c)), \ - (I[287] = I[288] = I[289] = I[290] = (T)(img)(0,_n3##y,_n2##z,c)), \ - (I[294] = I[295] = I[296] = I[297] = (T)(img)(0,_p3##y,_n3##z,c)), \ - (I[301] = I[302] = I[303] = I[304] = (T)(img)(0,_p2##y,_n3##z,c)), \ - (I[308] = I[309] = I[310] = I[311] = (T)(img)(0,_p1##y,_n3##z,c)), \ - (I[315] = I[316] = I[317] = I[318] = (T)(img)(0,y,_n3##z,c)), \ - (I[322] = I[323] = I[324] = I[325] = (T)(img)(0,_n1##y,_n3##z,c)), \ - (I[329] = I[330] = I[331] = I[332] = (T)(img)(0,_n2##y,_n3##z,c)), \ - (I[336] = I[337] = I[338] = I[339] = (T)(img)(0,_n3##y,_n3##z,c)), \ - (I[4] = (T)(img)(_n1##x,_p3##y,_p3##z,c)), \ - (I[11] = (T)(img)(_n1##x,_p2##y,_p3##z,c)), \ - (I[18] = (T)(img)(_n1##x,_p1##y,_p3##z,c)), \ - (I[25] = (T)(img)(_n1##x,y,_p3##z,c)), \ - (I[32] = (T)(img)(_n1##x,_n1##y,_p3##z,c)), \ - (I[39] = (T)(img)(_n1##x,_n2##y,_p3##z,c)), \ - (I[46] = (T)(img)(_n1##x,_n3##y,_p3##z,c)), \ - (I[53] = (T)(img)(_n1##x,_p3##y,_p2##z,c)), \ - (I[60] = (T)(img)(_n1##x,_p2##y,_p2##z,c)), \ - (I[67] = (T)(img)(_n1##x,_p1##y,_p2##z,c)), \ - (I[74] = (T)(img)(_n1##x,y,_p2##z,c)), \ - (I[81] = (T)(img)(_n1##x,_n1##y,_p2##z,c)), \ - (I[88] = (T)(img)(_n1##x,_n2##y,_p2##z,c)), \ - (I[95] = (T)(img)(_n1##x,_n3##y,_p2##z,c)), \ - (I[102] = (T)(img)(_n1##x,_p3##y,_p1##z,c)), \ - (I[109] = (T)(img)(_n1##x,_p2##y,_p1##z,c)), \ - (I[116] = (T)(img)(_n1##x,_p1##y,_p1##z,c)), \ - (I[123] = (T)(img)(_n1##x,y,_p1##z,c)), \ - (I[130] = (T)(img)(_n1##x,_n1##y,_p1##z,c)), \ - (I[137] = (T)(img)(_n1##x,_n2##y,_p1##z,c)), \ - (I[144] = (T)(img)(_n1##x,_n3##y,_p1##z,c)), \ - (I[151] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[158] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[165] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[172] = (T)(img)(_n1##x,y,z,c)), \ - (I[179] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[186] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[193] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[200] = (T)(img)(_n1##x,_p3##y,_n1##z,c)), \ - (I[207] = (T)(img)(_n1##x,_p2##y,_n1##z,c)), \ - (I[214] = (T)(img)(_n1##x,_p1##y,_n1##z,c)), \ - (I[221] = (T)(img)(_n1##x,y,_n1##z,c)), \ - (I[228] = (T)(img)(_n1##x,_n1##y,_n1##z,c)), \ - (I[235] = (T)(img)(_n1##x,_n2##y,_n1##z,c)), \ - (I[242] = (T)(img)(_n1##x,_n3##y,_n1##z,c)), \ - (I[249] = (T)(img)(_n1##x,_p3##y,_n2##z,c)), \ - (I[256] = (T)(img)(_n1##x,_p2##y,_n2##z,c)), \ - (I[263] = (T)(img)(_n1##x,_p1##y,_n2##z,c)), \ - (I[270] = (T)(img)(_n1##x,y,_n2##z,c)), \ - (I[277] = (T)(img)(_n1##x,_n1##y,_n2##z,c)), \ - (I[284] = (T)(img)(_n1##x,_n2##y,_n2##z,c)), \ - (I[291] = (T)(img)(_n1##x,_n3##y,_n2##z,c)), \ - (I[298] = (T)(img)(_n1##x,_p3##y,_n3##z,c)), \ - (I[305] = (T)(img)(_n1##x,_p2##y,_n3##z,c)), \ - (I[312] = (T)(img)(_n1##x,_p1##y,_n3##z,c)), \ - (I[319] = (T)(img)(_n1##x,y,_n3##z,c)), \ - (I[326] = (T)(img)(_n1##x,_n1##y,_n3##z,c)), \ - (I[333] = (T)(img)(_n1##x,_n2##y,_n3##z,c)), \ - (I[340] = (T)(img)(_n1##x,_n3##y,_n3##z,c)), \ - (I[5] = (T)(img)(_n2##x,_p3##y,_p3##z,c)), \ - (I[12] = (T)(img)(_n2##x,_p2##y,_p3##z,c)), \ - (I[19] = (T)(img)(_n2##x,_p1##y,_p3##z,c)), \ - (I[26] = (T)(img)(_n2##x,y,_p3##z,c)), \ - (I[33] = (T)(img)(_n2##x,_n1##y,_p3##z,c)), \ - (I[40] = (T)(img)(_n2##x,_n2##y,_p3##z,c)), \ - (I[47] = (T)(img)(_n2##x,_n3##y,_p3##z,c)), \ - (I[54] = (T)(img)(_n2##x,_p3##y,_p2##z,c)), \ - (I[61] = (T)(img)(_n2##x,_p2##y,_p2##z,c)), \ - (I[68] = (T)(img)(_n2##x,_p1##y,_p2##z,c)), \ - (I[75] = (T)(img)(_n2##x,y,_p2##z,c)), \ - (I[82] = (T)(img)(_n2##x,_n1##y,_p2##z,c)), \ - (I[89] = (T)(img)(_n2##x,_n2##y,_p2##z,c)), \ - (I[96] = (T)(img)(_n2##x,_n3##y,_p2##z,c)), \ - (I[103] = (T)(img)(_n2##x,_p3##y,_p1##z,c)), \ - (I[110] = (T)(img)(_n2##x,_p2##y,_p1##z,c)), \ - (I[117] = (T)(img)(_n2##x,_p1##y,_p1##z,c)), \ - (I[124] = (T)(img)(_n2##x,y,_p1##z,c)), \ - (I[131] = (T)(img)(_n2##x,_n1##y,_p1##z,c)), \ - (I[138] = (T)(img)(_n2##x,_n2##y,_p1##z,c)), \ - (I[145] = (T)(img)(_n2##x,_n3##y,_p1##z,c)), \ - (I[152] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[159] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[166] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[173] = (T)(img)(_n2##x,y,z,c)), \ - (I[180] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[187] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[194] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[201] = (T)(img)(_n2##x,_p3##y,_n1##z,c)), \ - (I[208] = (T)(img)(_n2##x,_p2##y,_n1##z,c)), \ - (I[215] = (T)(img)(_n2##x,_p1##y,_n1##z,c)), \ - (I[222] = (T)(img)(_n2##x,y,_n1##z,c)), \ - (I[229] = (T)(img)(_n2##x,_n1##y,_n1##z,c)), \ - (I[236] = (T)(img)(_n2##x,_n2##y,_n1##z,c)), \ - (I[243] = (T)(img)(_n2##x,_n3##y,_n1##z,c)), \ - (I[250] = (T)(img)(_n2##x,_p3##y,_n2##z,c)), \ - (I[257] = (T)(img)(_n2##x,_p2##y,_n2##z,c)), \ - (I[264] = (T)(img)(_n2##x,_p1##y,_n2##z,c)), \ - (I[271] = (T)(img)(_n2##x,y,_n2##z,c)), \ - (I[278] = (T)(img)(_n2##x,_n1##y,_n2##z,c)), \ - (I[285] = (T)(img)(_n2##x,_n2##y,_n2##z,c)), \ - (I[292] = (T)(img)(_n2##x,_n3##y,_n2##z,c)), \ - (I[299] = (T)(img)(_n2##x,_p3##y,_n3##z,c)), \ - (I[306] = (T)(img)(_n2##x,_p2##y,_n3##z,c)), \ - (I[313] = (T)(img)(_n2##x,_p1##y,_n3##z,c)), \ - (I[320] = (T)(img)(_n2##x,y,_n3##z,c)), \ - (I[327] = (T)(img)(_n2##x,_n1##y,_n3##z,c)), \ - (I[334] = (T)(img)(_n2##x,_n2##y,_n3##z,c)), \ - (I[341] = (T)(img)(_n2##x,_n3##y,_n3##z,c)), \ - 3>=((img)._width)?(img).width() - 1:3); \ - (_n3##x<(img).width() && ( \ - (I[6] = (T)(img)(_n3##x,_p3##y,_p3##z,c)), \ - (I[13] = (T)(img)(_n3##x,_p2##y,_p3##z,c)), \ - (I[20] = (T)(img)(_n3##x,_p1##y,_p3##z,c)), \ - (I[27] = (T)(img)(_n3##x,y,_p3##z,c)), \ - (I[34] = (T)(img)(_n3##x,_n1##y,_p3##z,c)), \ - (I[41] = (T)(img)(_n3##x,_n2##y,_p3##z,c)), \ - (I[48] = (T)(img)(_n3##x,_n3##y,_p3##z,c)), \ - (I[55] = (T)(img)(_n3##x,_p3##y,_p2##z,c)), \ - (I[62] = (T)(img)(_n3##x,_p2##y,_p2##z,c)), \ - (I[69] = (T)(img)(_n3##x,_p1##y,_p2##z,c)), \ - (I[76] = (T)(img)(_n3##x,y,_p2##z,c)), \ - (I[83] = (T)(img)(_n3##x,_n1##y,_p2##z,c)), \ - (I[90] = (T)(img)(_n3##x,_n2##y,_p2##z,c)), \ - (I[97] = (T)(img)(_n3##x,_n3##y,_p2##z,c)), \ - (I[104] = (T)(img)(_n3##x,_p3##y,_p1##z,c)), \ - (I[111] = (T)(img)(_n3##x,_p2##y,_p1##z,c)), \ - (I[118] = (T)(img)(_n3##x,_p1##y,_p1##z,c)), \ - (I[125] = (T)(img)(_n3##x,y,_p1##z,c)), \ - (I[132] = (T)(img)(_n3##x,_n1##y,_p1##z,c)), \ - (I[139] = (T)(img)(_n3##x,_n2##y,_p1##z,c)), \ - (I[146] = (T)(img)(_n3##x,_n3##y,_p1##z,c)), \ - (I[153] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[160] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[167] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[174] = (T)(img)(_n3##x,y,z,c)), \ - (I[181] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[188] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[195] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[202] = (T)(img)(_n3##x,_p3##y,_n1##z,c)), \ - (I[209] = (T)(img)(_n3##x,_p2##y,_n1##z,c)), \ - (I[216] = (T)(img)(_n3##x,_p1##y,_n1##z,c)), \ - (I[223] = (T)(img)(_n3##x,y,_n1##z,c)), \ - (I[230] = (T)(img)(_n3##x,_n1##y,_n1##z,c)), \ - (I[237] = (T)(img)(_n3##x,_n2##y,_n1##z,c)), \ - (I[244] = (T)(img)(_n3##x,_n3##y,_n1##z,c)), \ - (I[251] = (T)(img)(_n3##x,_p3##y,_n2##z,c)), \ - (I[258] = (T)(img)(_n3##x,_p2##y,_n2##z,c)), \ - (I[265] = (T)(img)(_n3##x,_p1##y,_n2##z,c)), \ - (I[272] = (T)(img)(_n3##x,y,_n2##z,c)), \ - (I[279] = (T)(img)(_n3##x,_n1##y,_n2##z,c)), \ - (I[286] = (T)(img)(_n3##x,_n2##y,_n2##z,c)), \ - (I[293] = (T)(img)(_n3##x,_n3##y,_n2##z,c)), \ - (I[300] = (T)(img)(_n3##x,_p3##y,_n3##z,c)), \ - (I[307] = (T)(img)(_n3##x,_p2##y,_n3##z,c)), \ - (I[314] = (T)(img)(_n3##x,_p1##y,_n3##z,c)), \ - (I[321] = (T)(img)(_n3##x,y,_n3##z,c)), \ - (I[328] = (T)(img)(_n3##x,_n1##y,_n3##z,c)), \ - (I[335] = (T)(img)(_n3##x,_n2##y,_n3##z,c)), \ - (I[342] = (T)(img)(_n3##x,_n3##y,_n3##z,c)),1)) || \ - _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], \ - I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], \ - I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], \ - I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], \ - I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], \ - I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], \ - I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], \ - I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], \ - I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], \ - I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], \ - I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], \ - I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], \ - I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], \ - I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], \ - I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], \ - I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], \ - I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], \ - I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], \ - I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], \ - I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], \ - I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], \ - I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], \ - I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], \ - I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], \ - I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], \ - I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], \ - I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], \ - I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], \ - I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], \ - I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], \ - I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], \ - I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], \ - I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], \ - I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], \ - I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], \ - I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], \ - I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], \ - I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], \ - I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], \ - I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], \ - I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], \ - I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], \ - I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], \ - I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], \ - I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], \ - I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], \ - I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], \ - I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], \ - I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], \ - _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x) - -#define cimg_for_in7x7x7(img,x0,y0,z0,x1,y1,z1,x,y,z,c,I,T) \ - cimg_for_in7((img)._depth,z0,z1,z) cimg_for_in7((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = (int)( \ - (I[0] = (T)(img)(_p3##x,_p3##y,_p3##z,c)), \ - (I[7] = (T)(img)(_p3##x,_p2##y,_p3##z,c)), \ - (I[14] = (T)(img)(_p3##x,_p1##y,_p3##z,c)), \ - (I[21] = (T)(img)(_p3##x,y,_p3##z,c)), \ - (I[28] = (T)(img)(_p3##x,_n1##y,_p3##z,c)), \ - (I[35] = (T)(img)(_p3##x,_n2##y,_p3##z,c)), \ - (I[42] = (T)(img)(_p3##x,_n3##y,_p3##z,c)), \ - (I[49] = (T)(img)(_p3##x,_p3##y,_p2##z,c)), \ - (I[56] = (T)(img)(_p3##x,_p2##y,_p2##z,c)), \ - (I[63] = (T)(img)(_p3##x,_p1##y,_p2##z,c)), \ - (I[70] = (T)(img)(_p3##x,y,_p2##z,c)), \ - (I[77] = (T)(img)(_p3##x,_n1##y,_p2##z,c)), \ - (I[84] = (T)(img)(_p3##x,_n2##y,_p2##z,c)), \ - (I[91] = (T)(img)(_p3##x,_n3##y,_p2##z,c)), \ - (I[98] = (T)(img)(_p3##x,_p3##y,_p1##z,c)), \ - (I[105] = (T)(img)(_p3##x,_p2##y,_p1##z,c)), \ - (I[112] = (T)(img)(_p3##x,_p1##y,_p1##z,c)), \ - (I[119] = (T)(img)(_p3##x,y,_p1##z,c)), \ - (I[126] = (T)(img)(_p3##x,_n1##y,_p1##z,c)), \ - (I[133] = (T)(img)(_p3##x,_n2##y,_p1##z,c)), \ - (I[140] = (T)(img)(_p3##x,_n3##y,_p1##z,c)), \ - (I[147] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[154] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[161] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[168] = (T)(img)(_p3##x,y,z,c)), \ - (I[175] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[182] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[189] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[196] = (T)(img)(_p3##x,_p3##y,_n1##z,c)), \ - (I[203] = (T)(img)(_p3##x,_p2##y,_n1##z,c)), \ - (I[210] = (T)(img)(_p3##x,_p1##y,_n1##z,c)), \ - (I[217] = (T)(img)(_p3##x,y,_n1##z,c)), \ - (I[224] = (T)(img)(_p3##x,_n1##y,_n1##z,c)), \ - (I[231] = (T)(img)(_p3##x,_n2##y,_n1##z,c)), \ - (I[238] = (T)(img)(_p3##x,_n3##y,_n1##z,c)), \ - (I[245] = (T)(img)(_p3##x,_p3##y,_n2##z,c)), \ - (I[252] = (T)(img)(_p3##x,_p2##y,_n2##z,c)), \ - (I[259] = (T)(img)(_p3##x,_p1##y,_n2##z,c)), \ - (I[266] = (T)(img)(_p3##x,y,_n2##z,c)), \ - (I[273] = (T)(img)(_p3##x,_n1##y,_n2##z,c)), \ - (I[280] = (T)(img)(_p3##x,_n2##y,_n2##z,c)), \ - (I[287] = (T)(img)(_p3##x,_n3##y,_n2##z,c)), \ - (I[294] = (T)(img)(_p3##x,_p3##y,_n3##z,c)), \ - (I[301] = (T)(img)(_p3##x,_p2##y,_n3##z,c)), \ - (I[308] = (T)(img)(_p3##x,_p1##y,_n3##z,c)), \ - (I[315] = (T)(img)(_p3##x,y,_n3##z,c)), \ - (I[322] = (T)(img)(_p3##x,_n1##y,_n3##z,c)), \ - (I[329] = (T)(img)(_p3##x,_n2##y,_n3##z,c)), \ - (I[336] = (T)(img)(_p3##x,_n3##y,_n3##z,c)), \ - (I[1] = (T)(img)(_p2##x,_p3##y,_p3##z,c)), \ - (I[8] = (T)(img)(_p2##x,_p2##y,_p3##z,c)), \ - (I[15] = (T)(img)(_p2##x,_p1##y,_p3##z,c)), \ - (I[22] = (T)(img)(_p2##x,y,_p3##z,c)), \ - (I[29] = (T)(img)(_p2##x,_n1##y,_p3##z,c)), \ - (I[36] = (T)(img)(_p2##x,_n2##y,_p3##z,c)), \ - (I[43] = (T)(img)(_p2##x,_n3##y,_p3##z,c)), \ - (I[50] = (T)(img)(_p2##x,_p3##y,_p2##z,c)), \ - (I[57] = (T)(img)(_p2##x,_p2##y,_p2##z,c)), \ - (I[64] = (T)(img)(_p2##x,_p1##y,_p2##z,c)), \ - (I[71] = (T)(img)(_p2##x,y,_p2##z,c)), \ - (I[78] = (T)(img)(_p2##x,_n1##y,_p2##z,c)), \ - (I[85] = (T)(img)(_p2##x,_n2##y,_p2##z,c)), \ - (I[92] = (T)(img)(_p2##x,_n3##y,_p2##z,c)), \ - (I[99] = (T)(img)(_p2##x,_p3##y,_p1##z,c)), \ - (I[106] = (T)(img)(_p2##x,_p2##y,_p1##z,c)), \ - (I[113] = (T)(img)(_p2##x,_p1##y,_p1##z,c)), \ - (I[120] = (T)(img)(_p2##x,y,_p1##z,c)), \ - (I[127] = (T)(img)(_p2##x,_n1##y,_p1##z,c)), \ - (I[134] = (T)(img)(_p2##x,_n2##y,_p1##z,c)), \ - (I[141] = (T)(img)(_p2##x,_n3##y,_p1##z,c)), \ - (I[148] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[155] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[162] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[169] = (T)(img)(_p2##x,y,z,c)), \ - (I[176] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[183] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[190] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[197] = (T)(img)(_p2##x,_p3##y,_n1##z,c)), \ - (I[204] = (T)(img)(_p2##x,_p2##y,_n1##z,c)), \ - (I[211] = (T)(img)(_p2##x,_p1##y,_n1##z,c)), \ - (I[218] = (T)(img)(_p2##x,y,_n1##z,c)), \ - (I[225] = (T)(img)(_p2##x,_n1##y,_n1##z,c)), \ - (I[232] = (T)(img)(_p2##x,_n2##y,_n1##z,c)), \ - (I[239] = (T)(img)(_p2##x,_n3##y,_n1##z,c)), \ - (I[246] = (T)(img)(_p2##x,_p3##y,_n2##z,c)), \ - (I[253] = (T)(img)(_p2##x,_p2##y,_n2##z,c)), \ - (I[260] = (T)(img)(_p2##x,_p1##y,_n2##z,c)), \ - (I[267] = (T)(img)(_p2##x,y,_n2##z,c)), \ - (I[274] = (T)(img)(_p2##x,_n1##y,_n2##z,c)), \ - (I[281] = (T)(img)(_p2##x,_n2##y,_n2##z,c)), \ - (I[288] = (T)(img)(_p2##x,_n3##y,_n2##z,c)), \ - (I[295] = (T)(img)(_p2##x,_p3##y,_n3##z,c)), \ - (I[302] = (T)(img)(_p2##x,_p2##y,_n3##z,c)), \ - (I[309] = (T)(img)(_p2##x,_p1##y,_n3##z,c)), \ - (I[316] = (T)(img)(_p2##x,y,_n3##z,c)), \ - (I[323] = (T)(img)(_p2##x,_n1##y,_n3##z,c)), \ - (I[330] = (T)(img)(_p2##x,_n2##y,_n3##z,c)), \ - (I[337] = (T)(img)(_p2##x,_n3##y,_n3##z,c)), \ - (I[2] = (T)(img)(_p1##x,_p3##y,_p3##z,c)), \ - (I[9] = (T)(img)(_p1##x,_p2##y,_p3##z,c)), \ - (I[16] = (T)(img)(_p1##x,_p1##y,_p3##z,c)), \ - (I[23] = (T)(img)(_p1##x,y,_p3##z,c)), \ - (I[30] = (T)(img)(_p1##x,_n1##y,_p3##z,c)), \ - (I[37] = (T)(img)(_p1##x,_n2##y,_p3##z,c)), \ - (I[44] = (T)(img)(_p1##x,_n3##y,_p3##z,c)), \ - (I[51] = (T)(img)(_p1##x,_p3##y,_p2##z,c)), \ - (I[58] = (T)(img)(_p1##x,_p2##y,_p2##z,c)), \ - (I[65] = (T)(img)(_p1##x,_p1##y,_p2##z,c)), \ - (I[72] = (T)(img)(_p1##x,y,_p2##z,c)), \ - (I[79] = (T)(img)(_p1##x,_n1##y,_p2##z,c)), \ - (I[86] = (T)(img)(_p1##x,_n2##y,_p2##z,c)), \ - (I[93] = (T)(img)(_p1##x,_n3##y,_p2##z,c)), \ - (I[100] = (T)(img)(_p1##x,_p3##y,_p1##z,c)), \ - (I[107] = (T)(img)(_p1##x,_p2##y,_p1##z,c)), \ - (I[114] = (T)(img)(_p1##x,_p1##y,_p1##z,c)), \ - (I[121] = (T)(img)(_p1##x,y,_p1##z,c)), \ - (I[128] = (T)(img)(_p1##x,_n1##y,_p1##z,c)), \ - (I[135] = (T)(img)(_p1##x,_n2##y,_p1##z,c)), \ - (I[142] = (T)(img)(_p1##x,_n3##y,_p1##z,c)), \ - (I[149] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[156] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[163] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[170] = (T)(img)(_p1##x,y,z,c)), \ - (I[177] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[184] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[191] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[198] = (T)(img)(_p1##x,_p3##y,_n1##z,c)), \ - (I[205] = (T)(img)(_p1##x,_p2##y,_n1##z,c)), \ - (I[212] = (T)(img)(_p1##x,_p1##y,_n1##z,c)), \ - (I[219] = (T)(img)(_p1##x,y,_n1##z,c)), \ - (I[226] = (T)(img)(_p1##x,_n1##y,_n1##z,c)), \ - (I[233] = (T)(img)(_p1##x,_n2##y,_n1##z,c)), \ - (I[240] = (T)(img)(_p1##x,_n3##y,_n1##z,c)), \ - (I[247] = (T)(img)(_p1##x,_p3##y,_n2##z,c)), \ - (I[254] = (T)(img)(_p1##x,_p2##y,_n2##z,c)), \ - (I[261] = (T)(img)(_p1##x,_p1##y,_n2##z,c)), \ - (I[268] = (T)(img)(_p1##x,y,_n2##z,c)), \ - (I[275] = (T)(img)(_p1##x,_n1##y,_n2##z,c)), \ - (I[282] = (T)(img)(_p1##x,_n2##y,_n2##z,c)), \ - (I[289] = (T)(img)(_p1##x,_n3##y,_n2##z,c)), \ - (I[296] = (T)(img)(_p1##x,_p3##y,_n3##z,c)), \ - (I[303] = (T)(img)(_p1##x,_p2##y,_n3##z,c)), \ - (I[310] = (T)(img)(_p1##x,_p1##y,_n3##z,c)), \ - (I[317] = (T)(img)(_p1##x,y,_n3##z,c)), \ - (I[324] = (T)(img)(_p1##x,_n1##y,_n3##z,c)), \ - (I[331] = (T)(img)(_p1##x,_n2##y,_n3##z,c)), \ - (I[338] = (T)(img)(_p1##x,_n3##y,_n3##z,c)), \ - (I[3] = (T)(img)(x,_p3##y,_p3##z,c)), \ - (I[10] = (T)(img)(x,_p2##y,_p3##z,c)), \ - (I[17] = (T)(img)(x,_p1##y,_p3##z,c)), \ - (I[24] = (T)(img)(x,y,_p3##z,c)), \ - (I[31] = (T)(img)(x,_n1##y,_p3##z,c)), \ - (I[38] = (T)(img)(x,_n2##y,_p3##z,c)), \ - (I[45] = (T)(img)(x,_n3##y,_p3##z,c)), \ - (I[52] = (T)(img)(x,_p3##y,_p2##z,c)), \ - (I[59] = (T)(img)(x,_p2##y,_p2##z,c)), \ - (I[66] = (T)(img)(x,_p1##y,_p2##z,c)), \ - (I[73] = (T)(img)(x,y,_p2##z,c)), \ - (I[80] = (T)(img)(x,_n1##y,_p2##z,c)), \ - (I[87] = (T)(img)(x,_n2##y,_p2##z,c)), \ - (I[94] = (T)(img)(x,_n3##y,_p2##z,c)), \ - (I[101] = (T)(img)(x,_p3##y,_p1##z,c)), \ - (I[108] = (T)(img)(x,_p2##y,_p1##z,c)), \ - (I[115] = (T)(img)(x,_p1##y,_p1##z,c)), \ - (I[122] = (T)(img)(x,y,_p1##z,c)), \ - (I[129] = (T)(img)(x,_n1##y,_p1##z,c)), \ - (I[136] = (T)(img)(x,_n2##y,_p1##z,c)), \ - (I[143] = (T)(img)(x,_n3##y,_p1##z,c)), \ - (I[150] = (T)(img)(x,_p3##y,z,c)), \ - (I[157] = (T)(img)(x,_p2##y,z,c)), \ - (I[164] = (T)(img)(x,_p1##y,z,c)), \ - (I[171] = (T)(img)(x,y,z,c)), \ - (I[178] = (T)(img)(x,_n1##y,z,c)), \ - (I[185] = (T)(img)(x,_n2##y,z,c)), \ - (I[192] = (T)(img)(x,_n3##y,z,c)), \ - (I[199] = (T)(img)(x,_p3##y,_n1##z,c)), \ - (I[206] = (T)(img)(x,_p2##y,_n1##z,c)), \ - (I[213] = (T)(img)(x,_p1##y,_n1##z,c)), \ - (I[220] = (T)(img)(x,y,_n1##z,c)), \ - (I[227] = (T)(img)(x,_n1##y,_n1##z,c)), \ - (I[234] = (T)(img)(x,_n2##y,_n1##z,c)), \ - (I[241] = (T)(img)(x,_n3##y,_n1##z,c)), \ - (I[248] = (T)(img)(x,_p3##y,_n2##z,c)), \ - (I[255] = (T)(img)(x,_p2##y,_n2##z,c)), \ - (I[262] = (T)(img)(x,_p1##y,_n2##z,c)), \ - (I[269] = (T)(img)(x,y,_n2##z,c)), \ - (I[276] = (T)(img)(x,_n1##y,_n2##z,c)), \ - (I[283] = (T)(img)(x,_n2##y,_n2##z,c)), \ - (I[290] = (T)(img)(x,_n3##y,_n2##z,c)), \ - (I[297] = (T)(img)(x,_p3##y,_n3##z,c)), \ - (I[304] = (T)(img)(x,_p2##y,_n3##z,c)), \ - (I[311] = (T)(img)(x,_p1##y,_n3##z,c)), \ - (I[318] = (T)(img)(x,y,_n3##z,c)), \ - (I[325] = (T)(img)(x,_n1##y,_n3##z,c)), \ - (I[332] = (T)(img)(x,_n2##y,_n3##z,c)), \ - (I[339] = (T)(img)(x,_n3##y,_n3##z,c)), \ - (I[4] = (T)(img)(_n1##x,_p3##y,_p3##z,c)), \ - (I[11] = (T)(img)(_n1##x,_p2##y,_p3##z,c)), \ - (I[18] = (T)(img)(_n1##x,_p1##y,_p3##z,c)), \ - (I[25] = (T)(img)(_n1##x,y,_p3##z,c)), \ - (I[32] = (T)(img)(_n1##x,_n1##y,_p3##z,c)), \ - (I[39] = (T)(img)(_n1##x,_n2##y,_p3##z,c)), \ - (I[46] = (T)(img)(_n1##x,_n3##y,_p3##z,c)), \ - (I[53] = (T)(img)(_n1##x,_p3##y,_p2##z,c)), \ - (I[60] = (T)(img)(_n1##x,_p2##y,_p2##z,c)), \ - (I[67] = (T)(img)(_n1##x,_p1##y,_p2##z,c)), \ - (I[74] = (T)(img)(_n1##x,y,_p2##z,c)), \ - (I[81] = (T)(img)(_n1##x,_n1##y,_p2##z,c)), \ - (I[88] = (T)(img)(_n1##x,_n2##y,_p2##z,c)), \ - (I[95] = (T)(img)(_n1##x,_n3##y,_p2##z,c)), \ - (I[102] = (T)(img)(_n1##x,_p3##y,_p1##z,c)), \ - (I[109] = (T)(img)(_n1##x,_p2##y,_p1##z,c)), \ - (I[116] = (T)(img)(_n1##x,_p1##y,_p1##z,c)), \ - (I[123] = (T)(img)(_n1##x,y,_p1##z,c)), \ - (I[130] = (T)(img)(_n1##x,_n1##y,_p1##z,c)), \ - (I[137] = (T)(img)(_n1##x,_n2##y,_p1##z,c)), \ - (I[144] = (T)(img)(_n1##x,_n3##y,_p1##z,c)), \ - (I[151] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[158] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[165] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[172] = (T)(img)(_n1##x,y,z,c)), \ - (I[179] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[186] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[193] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[200] = (T)(img)(_n1##x,_p3##y,_n1##z,c)), \ - (I[207] = (T)(img)(_n1##x,_p2##y,_n1##z,c)), \ - (I[214] = (T)(img)(_n1##x,_p1##y,_n1##z,c)), \ - (I[221] = (T)(img)(_n1##x,y,_n1##z,c)), \ - (I[228] = (T)(img)(_n1##x,_n1##y,_n1##z,c)), \ - (I[235] = (T)(img)(_n1##x,_n2##y,_n1##z,c)), \ - (I[242] = (T)(img)(_n1##x,_n3##y,_n1##z,c)), \ - (I[249] = (T)(img)(_n1##x,_p3##y,_n2##z,c)), \ - (I[256] = (T)(img)(_n1##x,_p2##y,_n2##z,c)), \ - (I[263] = (T)(img)(_n1##x,_p1##y,_n2##z,c)), \ - (I[270] = (T)(img)(_n1##x,y,_n2##z,c)), \ - (I[277] = (T)(img)(_n1##x,_n1##y,_n2##z,c)), \ - (I[284] = (T)(img)(_n1##x,_n2##y,_n2##z,c)), \ - (I[291] = (T)(img)(_n1##x,_n3##y,_n2##z,c)), \ - (I[298] = (T)(img)(_n1##x,_p3##y,_n3##z,c)), \ - (I[305] = (T)(img)(_n1##x,_p2##y,_n3##z,c)), \ - (I[312] = (T)(img)(_n1##x,_p1##y,_n3##z,c)), \ - (I[319] = (T)(img)(_n1##x,y,_n3##z,c)), \ - (I[326] = (T)(img)(_n1##x,_n1##y,_n3##z,c)), \ - (I[333] = (T)(img)(_n1##x,_n2##y,_n3##z,c)), \ - (I[340] = (T)(img)(_n1##x,_n3##y,_n3##z,c)), \ - (I[5] = (T)(img)(_n2##x,_p3##y,_p3##z,c)), \ - (I[12] = (T)(img)(_n2##x,_p2##y,_p3##z,c)), \ - (I[19] = (T)(img)(_n2##x,_p1##y,_p3##z,c)), \ - (I[26] = (T)(img)(_n2##x,y,_p3##z,c)), \ - (I[33] = (T)(img)(_n2##x,_n1##y,_p3##z,c)), \ - (I[40] = (T)(img)(_n2##x,_n2##y,_p3##z,c)), \ - (I[47] = (T)(img)(_n2##x,_n3##y,_p3##z,c)), \ - (I[54] = (T)(img)(_n2##x,_p3##y,_p2##z,c)), \ - (I[61] = (T)(img)(_n2##x,_p2##y,_p2##z,c)), \ - (I[68] = (T)(img)(_n2##x,_p1##y,_p2##z,c)), \ - (I[75] = (T)(img)(_n2##x,y,_p2##z,c)), \ - (I[82] = (T)(img)(_n2##x,_n1##y,_p2##z,c)), \ - (I[89] = (T)(img)(_n2##x,_n2##y,_p2##z,c)), \ - (I[96] = (T)(img)(_n2##x,_n3##y,_p2##z,c)), \ - (I[103] = (T)(img)(_n2##x,_p3##y,_p1##z,c)), \ - (I[110] = (T)(img)(_n2##x,_p2##y,_p1##z,c)), \ - (I[117] = (T)(img)(_n2##x,_p1##y,_p1##z,c)), \ - (I[124] = (T)(img)(_n2##x,y,_p1##z,c)), \ - (I[131] = (T)(img)(_n2##x,_n1##y,_p1##z,c)), \ - (I[138] = (T)(img)(_n2##x,_n2##y,_p1##z,c)), \ - (I[145] = (T)(img)(_n2##x,_n3##y,_p1##z,c)), \ - (I[152] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[159] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[166] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[173] = (T)(img)(_n2##x,y,z,c)), \ - (I[180] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[187] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[194] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[201] = (T)(img)(_n2##x,_p3##y,_n1##z,c)), \ - (I[208] = (T)(img)(_n2##x,_p2##y,_n1##z,c)), \ - (I[215] = (T)(img)(_n2##x,_p1##y,_n1##z,c)), \ - (I[222] = (T)(img)(_n2##x,y,_n1##z,c)), \ - (I[229] = (T)(img)(_n2##x,_n1##y,_n1##z,c)), \ - (I[236] = (T)(img)(_n2##x,_n2##y,_n1##z,c)), \ - (I[243] = (T)(img)(_n2##x,_n3##y,_n1##z,c)), \ - (I[250] = (T)(img)(_n2##x,_p3##y,_n2##z,c)), \ - (I[257] = (T)(img)(_n2##x,_p2##y,_n2##z,c)), \ - (I[264] = (T)(img)(_n2##x,_p1##y,_n2##z,c)), \ - (I[271] = (T)(img)(_n2##x,y,_n2##z,c)), \ - (I[278] = (T)(img)(_n2##x,_n1##y,_n2##z,c)), \ - (I[285] = (T)(img)(_n2##x,_n2##y,_n2##z,c)), \ - (I[292] = (T)(img)(_n2##x,_n3##y,_n2##z,c)), \ - (I[299] = (T)(img)(_n2##x,_p3##y,_n3##z,c)), \ - (I[306] = (T)(img)(_n2##x,_p2##y,_n3##z,c)), \ - (I[313] = (T)(img)(_n2##x,_p1##y,_n3##z,c)), \ - (I[320] = (T)(img)(_n2##x,y,_n3##z,c)), \ - (I[327] = (T)(img)(_n2##x,_n1##y,_n3##z,c)), \ - (I[334] = (T)(img)(_n2##x,_n2##y,_n3##z,c)), \ - (I[341] = (T)(img)(_n2##x,_n3##y,_n3##z,c)), \ - x + 3>=(img).width()?(img).width() - 1:x + 3); \ - x<=(int)(x1) && ((_n3##x<(img).width() && ( \ - (I[6] = (T)(img)(_n3##x,_p3##y,_p3##z,c)), \ - (I[13] = (T)(img)(_n3##x,_p2##y,_p3##z,c)), \ - (I[20] = (T)(img)(_n3##x,_p1##y,_p3##z,c)), \ - (I[27] = (T)(img)(_n3##x,y,_p3##z,c)), \ - (I[34] = (T)(img)(_n3##x,_n1##y,_p3##z,c)), \ - (I[41] = (T)(img)(_n3##x,_n2##y,_p3##z,c)), \ - (I[48] = (T)(img)(_n3##x,_n3##y,_p3##z,c)), \ - (I[55] = (T)(img)(_n3##x,_p3##y,_p2##z,c)), \ - (I[62] = (T)(img)(_n3##x,_p2##y,_p2##z,c)), \ - (I[69] = (T)(img)(_n3##x,_p1##y,_p2##z,c)), \ - (I[76] = (T)(img)(_n3##x,y,_p2##z,c)), \ - (I[83] = (T)(img)(_n3##x,_n1##y,_p2##z,c)), \ - (I[90] = (T)(img)(_n3##x,_n2##y,_p2##z,c)), \ - (I[97] = (T)(img)(_n3##x,_n3##y,_p2##z,c)), \ - (I[104] = (T)(img)(_n3##x,_p3##y,_p1##z,c)), \ - (I[111] = (T)(img)(_n3##x,_p2##y,_p1##z,c)), \ - (I[118] = (T)(img)(_n3##x,_p1##y,_p1##z,c)), \ - (I[125] = (T)(img)(_n3##x,y,_p1##z,c)), \ - (I[132] = (T)(img)(_n3##x,_n1##y,_p1##z,c)), \ - (I[139] = (T)(img)(_n3##x,_n2##y,_p1##z,c)), \ - (I[146] = (T)(img)(_n3##x,_n3##y,_p1##z,c)), \ - (I[153] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[160] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[167] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[174] = (T)(img)(_n3##x,y,z,c)), \ - (I[181] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[188] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[195] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[202] = (T)(img)(_n3##x,_p3##y,_n1##z,c)), \ - (I[209] = (T)(img)(_n3##x,_p2##y,_n1##z,c)), \ - (I[216] = (T)(img)(_n3##x,_p1##y,_n1##z,c)), \ - (I[223] = (T)(img)(_n3##x,y,_n1##z,c)), \ - (I[230] = (T)(img)(_n3##x,_n1##y,_n1##z,c)), \ - (I[237] = (T)(img)(_n3##x,_n2##y,_n1##z,c)), \ - (I[244] = (T)(img)(_n3##x,_n3##y,_n1##z,c)), \ - (I[251] = (T)(img)(_n3##x,_p3##y,_n2##z,c)), \ - (I[258] = (T)(img)(_n3##x,_p2##y,_n2##z,c)), \ - (I[265] = (T)(img)(_n3##x,_p1##y,_n2##z,c)), \ - (I[272] = (T)(img)(_n3##x,y,_n2##z,c)), \ - (I[279] = (T)(img)(_n3##x,_n1##y,_n2##z,c)), \ - (I[286] = (T)(img)(_n3##x,_n2##y,_n2##z,c)), \ - (I[293] = (T)(img)(_n3##x,_n3##y,_n2##z,c)), \ - (I[300] = (T)(img)(_n3##x,_p3##y,_n3##z,c)), \ - (I[307] = (T)(img)(_n3##x,_p2##y,_n3##z,c)), \ - (I[314] = (T)(img)(_n3##x,_p1##y,_n3##z,c)), \ - (I[321] = (T)(img)(_n3##x,y,_n3##z,c)), \ - (I[328] = (T)(img)(_n3##x,_n1##y,_n3##z,c)), \ - (I[335] = (T)(img)(_n3##x,_n2##y,_n3##z,c)), \ - (I[342] = (T)(img)(_n3##x,_n3##y,_n3##z,c)),1)) || \ - _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], \ - I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], \ - I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], \ - I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], \ - I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], \ - I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], \ - I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], \ - I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], \ - I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], \ - I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], \ - I[70] = I[71], I[71] = I[72], I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], \ - I[77] = I[78], I[78] = I[79], I[79] = I[80], I[80] = I[81], I[81] = I[82], I[82] = I[83], \ - I[84] = I[85], I[85] = I[86], I[86] = I[87], I[87] = I[88], I[88] = I[89], I[89] = I[90], \ - I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], I[95] = I[96], I[96] = I[97], \ - I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], I[103] = I[104], \ - I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], \ - I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], \ - I[119] = I[120], I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], \ - I[126] = I[127], I[127] = I[128], I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], \ - I[133] = I[134], I[134] = I[135], I[135] = I[136], I[136] = I[137], I[137] = I[138], I[138] = I[139], \ - I[140] = I[141], I[141] = I[142], I[142] = I[143], I[143] = I[144], I[144] = I[145], I[145] = I[146], \ - I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], I[151] = I[152], I[152] = I[153], \ - I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], I[159] = I[160], \ - I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], \ - I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], \ - I[175] = I[176], I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], \ - I[182] = I[183], I[183] = I[184], I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], \ - I[189] = I[190], I[190] = I[191], I[191] = I[192], I[192] = I[193], I[193] = I[194], I[194] = I[195], \ - I[196] = I[197], I[197] = I[198], I[198] = I[199], I[199] = I[200], I[200] = I[201], I[201] = I[202], \ - I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], I[207] = I[208], I[208] = I[209], \ - I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], I[215] = I[216], \ - I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], \ - I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], \ - I[231] = I[232], I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], \ - I[238] = I[239], I[239] = I[240], I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], \ - I[245] = I[246], I[246] = I[247], I[247] = I[248], I[248] = I[249], I[249] = I[250], I[250] = I[251], \ - I[252] = I[253], I[253] = I[254], I[254] = I[255], I[255] = I[256], I[256] = I[257], I[257] = I[258], \ - I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], I[263] = I[264], I[264] = I[265], \ - I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], I[271] = I[272], \ - I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], \ - I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], \ - I[287] = I[288], I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], \ - I[294] = I[295], I[295] = I[296], I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], \ - I[301] = I[302], I[302] = I[303], I[303] = I[304], I[304] = I[305], I[305] = I[306], I[306] = I[307], \ - I[308] = I[309], I[309] = I[310], I[310] = I[311], I[311] = I[312], I[312] = I[313], I[313] = I[314], \ - I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], I[319] = I[320], I[320] = I[321], \ - I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], I[327] = I[328], \ - I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], \ - I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], \ - _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x) - -#define cimg_get7x7x7(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p3##x,_p3##y,_p3##z,c), I[1] = (T)(img)(_p2##x,_p3##y,_p3##z,c), I[2] = (T)(img)(_p1##x,_p3##y,_p3##z,c), I[3] = (T)(img)(x,_p3##y,_p3##z,c), I[4] = (T)(img)(_n1##x,_p3##y,_p3##z,c), I[5] = (T)(img)(_n2##x,_p3##y,_p3##z,c), I[6] = (T)(img)(_n3##x,_p3##y,_p3##z,c), \ - I[7] = (T)(img)(_p3##x,_p2##y,_p3##z,c), I[8] = (T)(img)(_p2##x,_p2##y,_p3##z,c), I[9] = (T)(img)(_p1##x,_p2##y,_p3##z,c), I[10] = (T)(img)(x,_p2##y,_p3##z,c), I[11] = (T)(img)(_n1##x,_p2##y,_p3##z,c), I[12] = (T)(img)(_n2##x,_p2##y,_p3##z,c), I[13] = (T)(img)(_n3##x,_p2##y,_p3##z,c), \ - I[14] = (T)(img)(_p3##x,_p1##y,_p3##z,c), I[15] = (T)(img)(_p2##x,_p1##y,_p3##z,c), I[16] = (T)(img)(_p1##x,_p1##y,_p3##z,c), I[17] = (T)(img)(x,_p1##y,_p3##z,c), I[18] = (T)(img)(_n1##x,_p1##y,_p3##z,c), I[19] = (T)(img)(_n2##x,_p1##y,_p3##z,c), I[20] = (T)(img)(_n3##x,_p1##y,_p3##z,c), \ - I[21] = (T)(img)(_p3##x,y,_p3##z,c), I[22] = (T)(img)(_p2##x,y,_p3##z,c), I[23] = (T)(img)(_p1##x,y,_p3##z,c), I[24] = (T)(img)(x,y,_p3##z,c), I[25] = (T)(img)(_n1##x,y,_p3##z,c), I[26] = (T)(img)(_n2##x,y,_p3##z,c), I[27] = (T)(img)(_n3##x,y,_p3##z,c), \ - I[28] = (T)(img)(_p3##x,_n1##y,_p3##z,c), I[29] = (T)(img)(_p2##x,_n1##y,_p3##z,c), I[30] = (T)(img)(_p1##x,_n1##y,_p3##z,c), I[31] = (T)(img)(x,_n1##y,_p3##z,c), I[32] = (T)(img)(_n1##x,_n1##y,_p3##z,c), I[33] = (T)(img)(_n2##x,_n1##y,_p3##z,c), I[34] = (T)(img)(_n3##x,_n1##y,_p3##z,c), \ - I[35] = (T)(img)(_p3##x,_n2##y,_p3##z,c), I[36] = (T)(img)(_p2##x,_n2##y,_p3##z,c), I[37] = (T)(img)(_p1##x,_n2##y,_p3##z,c), I[38] = (T)(img)(x,_n2##y,_p3##z,c), I[39] = (T)(img)(_n1##x,_n2##y,_p3##z,c), I[40] = (T)(img)(_n2##x,_n2##y,_p3##z,c), I[41] = (T)(img)(_n3##x,_n2##y,_p3##z,c), \ - I[42] = (T)(img)(_p3##x,_n3##y,_p3##z,c), I[43] = (T)(img)(_p2##x,_n3##y,_p3##z,c), I[44] = (T)(img)(_p1##x,_n3##y,_p3##z,c), I[45] = (T)(img)(x,_n3##y,_p3##z,c), I[46] = (T)(img)(_n1##x,_n3##y,_p3##z,c), I[47] = (T)(img)(_n2##x,_n3##y,_p3##z,c), I[48] = (T)(img)(_n3##x,_n3##y,_p3##z,c), \ - I[49] = (T)(img)(_p3##x,_p3##y,_p2##z,c), I[50] = (T)(img)(_p2##x,_p3##y,_p2##z,c), I[51] = (T)(img)(_p1##x,_p3##y,_p2##z,c), I[52] = (T)(img)(x,_p3##y,_p2##z,c), I[53] = (T)(img)(_n1##x,_p3##y,_p2##z,c), I[54] = (T)(img)(_n2##x,_p3##y,_p2##z,c), I[55] = (T)(img)(_n3##x,_p3##y,_p2##z,c), \ - I[56] = (T)(img)(_p3##x,_p2##y,_p2##z,c), I[57] = (T)(img)(_p2##x,_p2##y,_p2##z,c), I[58] = (T)(img)(_p1##x,_p2##y,_p2##z,c), I[59] = (T)(img)(x,_p2##y,_p2##z,c), I[60] = (T)(img)(_n1##x,_p2##y,_p2##z,c), I[61] = (T)(img)(_n2##x,_p2##y,_p2##z,c), I[62] = (T)(img)(_n3##x,_p2##y,_p2##z,c), \ - I[63] = (T)(img)(_p3##x,_p1##y,_p2##z,c), I[64] = (T)(img)(_p2##x,_p1##y,_p2##z,c), I[65] = (T)(img)(_p1##x,_p1##y,_p2##z,c), I[66] = (T)(img)(x,_p1##y,_p2##z,c), I[67] = (T)(img)(_n1##x,_p1##y,_p2##z,c), I[68] = (T)(img)(_n2##x,_p1##y,_p2##z,c), I[69] = (T)(img)(_n3##x,_p1##y,_p2##z,c), \ - I[70] = (T)(img)(_p3##x,y,_p2##z,c), I[71] = (T)(img)(_p2##x,y,_p2##z,c), I[72] = (T)(img)(_p1##x,y,_p2##z,c), I[73] = (T)(img)(x,y,_p2##z,c), I[74] = (T)(img)(_n1##x,y,_p2##z,c), I[75] = (T)(img)(_n2##x,y,_p2##z,c), I[76] = (T)(img)(_n3##x,y,_p2##z,c), \ - I[77] = (T)(img)(_p3##x,_n1##y,_p2##z,c), I[78] = (T)(img)(_p2##x,_n1##y,_p2##z,c), I[79] = (T)(img)(_p1##x,_n1##y,_p2##z,c), I[80] = (T)(img)(x,_n1##y,_p2##z,c), I[81] = (T)(img)(_n1##x,_n1##y,_p2##z,c), I[82] = (T)(img)(_n2##x,_n1##y,_p2##z,c), I[83] = (T)(img)(_n3##x,_n1##y,_p2##z,c), \ - I[84] = (T)(img)(_p3##x,_n2##y,_p2##z,c), I[85] = (T)(img)(_p2##x,_n2##y,_p2##z,c), I[86] = (T)(img)(_p1##x,_n2##y,_p2##z,c), I[87] = (T)(img)(x,_n2##y,_p2##z,c), I[88] = (T)(img)(_n1##x,_n2##y,_p2##z,c), I[89] = (T)(img)(_n2##x,_n2##y,_p2##z,c), I[90] = (T)(img)(_n3##x,_n2##y,_p2##z,c), \ - I[91] = (T)(img)(_p3##x,_n3##y,_p2##z,c), I[92] = (T)(img)(_p2##x,_n3##y,_p2##z,c), I[93] = (T)(img)(_p1##x,_n3##y,_p2##z,c), I[94] = (T)(img)(x,_n3##y,_p2##z,c), I[95] = (T)(img)(_n1##x,_n3##y,_p2##z,c), I[96] = (T)(img)(_n2##x,_n3##y,_p2##z,c), I[97] = (T)(img)(_n3##x,_n3##y,_p2##z,c), \ - I[98] = (T)(img)(_p3##x,_p3##y,_p1##z,c), I[99] = (T)(img)(_p2##x,_p3##y,_p1##z,c), I[100] = (T)(img)(_p1##x,_p3##y,_p1##z,c), I[101] = (T)(img)(x,_p3##y,_p1##z,c), I[102] = (T)(img)(_n1##x,_p3##y,_p1##z,c), I[103] = (T)(img)(_n2##x,_p3##y,_p1##z,c), I[104] = (T)(img)(_n3##x,_p3##y,_p1##z,c), \ - I[105] = (T)(img)(_p3##x,_p2##y,_p1##z,c), I[106] = (T)(img)(_p2##x,_p2##y,_p1##z,c), I[107] = (T)(img)(_p1##x,_p2##y,_p1##z,c), I[108] = (T)(img)(x,_p2##y,_p1##z,c), I[109] = (T)(img)(_n1##x,_p2##y,_p1##z,c), I[110] = (T)(img)(_n2##x,_p2##y,_p1##z,c), I[111] = (T)(img)(_n3##x,_p2##y,_p1##z,c), \ - I[112] = (T)(img)(_p3##x,_p1##y,_p1##z,c), I[113] = (T)(img)(_p2##x,_p1##y,_p1##z,c), I[114] = (T)(img)(_p1##x,_p1##y,_p1##z,c), I[115] = (T)(img)(x,_p1##y,_p1##z,c), I[116] = (T)(img)(_n1##x,_p1##y,_p1##z,c), I[117] = (T)(img)(_n2##x,_p1##y,_p1##z,c), I[118] = (T)(img)(_n3##x,_p1##y,_p1##z,c), \ - I[119] = (T)(img)(_p3##x,y,_p1##z,c), I[120] = (T)(img)(_p2##x,y,_p1##z,c), I[121] = (T)(img)(_p1##x,y,_p1##z,c), I[122] = (T)(img)(x,y,_p1##z,c), I[123] = (T)(img)(_n1##x,y,_p1##z,c), I[124] = (T)(img)(_n2##x,y,_p1##z,c), I[125] = (T)(img)(_n3##x,y,_p1##z,c), \ - I[126] = (T)(img)(_p3##x,_n1##y,_p1##z,c), I[127] = (T)(img)(_p2##x,_n1##y,_p1##z,c), I[128] = (T)(img)(_p1##x,_n1##y,_p1##z,c), I[129] = (T)(img)(x,_n1##y,_p1##z,c), I[130] = (T)(img)(_n1##x,_n1##y,_p1##z,c), I[131] = (T)(img)(_n2##x,_n1##y,_p1##z,c), I[132] = (T)(img)(_n3##x,_n1##y,_p1##z,c), \ - I[133] = (T)(img)(_p3##x,_n2##y,_p1##z,c), I[134] = (T)(img)(_p2##x,_n2##y,_p1##z,c), I[135] = (T)(img)(_p1##x,_n2##y,_p1##z,c), I[136] = (T)(img)(x,_n2##y,_p1##z,c), I[137] = (T)(img)(_n1##x,_n2##y,_p1##z,c), I[138] = (T)(img)(_n2##x,_n2##y,_p1##z,c), I[139] = (T)(img)(_n3##x,_n2##y,_p1##z,c), \ - I[140] = (T)(img)(_p3##x,_n3##y,_p1##z,c), I[141] = (T)(img)(_p2##x,_n3##y,_p1##z,c), I[142] = (T)(img)(_p1##x,_n3##y,_p1##z,c), I[143] = (T)(img)(x,_n3##y,_p1##z,c), I[144] = (T)(img)(_n1##x,_n3##y,_p1##z,c), I[145] = (T)(img)(_n2##x,_n3##y,_p1##z,c), I[146] = (T)(img)(_n3##x,_n3##y,_p1##z,c), \ - I[147] = (T)(img)(_p3##x,_p3##y,z,c), I[148] = (T)(img)(_p2##x,_p3##y,z,c), I[149] = (T)(img)(_p1##x,_p3##y,z,c), I[150] = (T)(img)(x,_p3##y,z,c), I[151] = (T)(img)(_n1##x,_p3##y,z,c), I[152] = (T)(img)(_n2##x,_p3##y,z,c), I[153] = (T)(img)(_n3##x,_p3##y,z,c), \ - I[154] = (T)(img)(_p3##x,_p2##y,z,c), I[155] = (T)(img)(_p2##x,_p2##y,z,c), I[156] = (T)(img)(_p1##x,_p2##y,z,c), I[157] = (T)(img)(x,_p2##y,z,c), I[158] = (T)(img)(_n1##x,_p2##y,z,c), I[159] = (T)(img)(_n2##x,_p2##y,z,c), I[160] = (T)(img)(_n3##x,_p2##y,z,c), \ - I[161] = (T)(img)(_p3##x,_p1##y,z,c), I[162] = (T)(img)(_p2##x,_p1##y,z,c), I[163] = (T)(img)(_p1##x,_p1##y,z,c), I[164] = (T)(img)(x,_p1##y,z,c), I[165] = (T)(img)(_n1##x,_p1##y,z,c), I[166] = (T)(img)(_n2##x,_p1##y,z,c), I[167] = (T)(img)(_n3##x,_p1##y,z,c), \ - I[168] = (T)(img)(_p3##x,y,z,c), I[169] = (T)(img)(_p2##x,y,z,c), I[170] = (T)(img)(_p1##x,y,z,c), I[171] = (T)(img)(x,y,z,c), I[172] = (T)(img)(_n1##x,y,z,c), I[173] = (T)(img)(_n2##x,y,z,c), I[174] = (T)(img)(_n3##x,y,z,c), \ - I[175] = (T)(img)(_p3##x,_n1##y,z,c), I[176] = (T)(img)(_p2##x,_n1##y,z,c), I[177] = (T)(img)(_p1##x,_n1##y,z,c), I[178] = (T)(img)(x,_n1##y,z,c), I[179] = (T)(img)(_n1##x,_n1##y,z,c), I[180] = (T)(img)(_n2##x,_n1##y,z,c), I[181] = (T)(img)(_n3##x,_n1##y,z,c), \ - I[182] = (T)(img)(_p3##x,_n2##y,z,c), I[183] = (T)(img)(_p2##x,_n2##y,z,c), I[184] = (T)(img)(_p1##x,_n2##y,z,c), I[185] = (T)(img)(x,_n2##y,z,c), I[186] = (T)(img)(_n1##x,_n2##y,z,c), I[187] = (T)(img)(_n2##x,_n2##y,z,c), I[188] = (T)(img)(_n3##x,_n2##y,z,c), \ - I[189] = (T)(img)(_p3##x,_n3##y,z,c), I[190] = (T)(img)(_p2##x,_n3##y,z,c), I[191] = (T)(img)(_p1##x,_n3##y,z,c), I[192] = (T)(img)(x,_n3##y,z,c), I[193] = (T)(img)(_n1##x,_n3##y,z,c), I[194] = (T)(img)(_n2##x,_n3##y,z,c), I[195] = (T)(img)(_n3##x,_n3##y,z,c), \ - I[196] = (T)(img)(_p3##x,_p3##y,_n1##z,c), I[197] = (T)(img)(_p2##x,_p3##y,_n1##z,c), I[198] = (T)(img)(_p1##x,_p3##y,_n1##z,c), I[199] = (T)(img)(x,_p3##y,_n1##z,c), I[200] = (T)(img)(_n1##x,_p3##y,_n1##z,c), I[201] = (T)(img)(_n2##x,_p3##y,_n1##z,c), I[202] = (T)(img)(_n3##x,_p3##y,_n1##z,c), \ - I[203] = (T)(img)(_p3##x,_p2##y,_n1##z,c), I[204] = (T)(img)(_p2##x,_p2##y,_n1##z,c), I[205] = (T)(img)(_p1##x,_p2##y,_n1##z,c), I[206] = (T)(img)(x,_p2##y,_n1##z,c), I[207] = (T)(img)(_n1##x,_p2##y,_n1##z,c), I[208] = (T)(img)(_n2##x,_p2##y,_n1##z,c), I[209] = (T)(img)(_n3##x,_p2##y,_n1##z,c), \ - I[210] = (T)(img)(_p3##x,_p1##y,_n1##z,c), I[211] = (T)(img)(_p2##x,_p1##y,_n1##z,c), I[212] = (T)(img)(_p1##x,_p1##y,_n1##z,c), I[213] = (T)(img)(x,_p1##y,_n1##z,c), I[214] = (T)(img)(_n1##x,_p1##y,_n1##z,c), I[215] = (T)(img)(_n2##x,_p1##y,_n1##z,c), I[216] = (T)(img)(_n3##x,_p1##y,_n1##z,c), \ - I[217] = (T)(img)(_p3##x,y,_n1##z,c), I[218] = (T)(img)(_p2##x,y,_n1##z,c), I[219] = (T)(img)(_p1##x,y,_n1##z,c), I[220] = (T)(img)(x,y,_n1##z,c), I[221] = (T)(img)(_n1##x,y,_n1##z,c), I[222] = (T)(img)(_n2##x,y,_n1##z,c), I[223] = (T)(img)(_n3##x,y,_n1##z,c), \ - I[224] = (T)(img)(_p3##x,_n1##y,_n1##z,c), I[225] = (T)(img)(_p2##x,_n1##y,_n1##z,c), I[226] = (T)(img)(_p1##x,_n1##y,_n1##z,c), I[227] = (T)(img)(x,_n1##y,_n1##z,c), I[228] = (T)(img)(_n1##x,_n1##y,_n1##z,c), I[229] = (T)(img)(_n2##x,_n1##y,_n1##z,c), I[230] = (T)(img)(_n3##x,_n1##y,_n1##z,c), \ - I[231] = (T)(img)(_p3##x,_n2##y,_n1##z,c), I[232] = (T)(img)(_p2##x,_n2##y,_n1##z,c), I[233] = (T)(img)(_p1##x,_n2##y,_n1##z,c), I[234] = (T)(img)(x,_n2##y,_n1##z,c), I[235] = (T)(img)(_n1##x,_n2##y,_n1##z,c), I[236] = (T)(img)(_n2##x,_n2##y,_n1##z,c), I[237] = (T)(img)(_n3##x,_n2##y,_n1##z,c), \ - I[238] = (T)(img)(_p3##x,_n3##y,_n1##z,c), I[239] = (T)(img)(_p2##x,_n3##y,_n1##z,c), I[240] = (T)(img)(_p1##x,_n3##y,_n1##z,c), I[241] = (T)(img)(x,_n3##y,_n1##z,c), I[242] = (T)(img)(_n1##x,_n3##y,_n1##z,c), I[243] = (T)(img)(_n2##x,_n3##y,_n1##z,c), I[244] = (T)(img)(_n3##x,_n3##y,_n1##z,c), \ - I[245] = (T)(img)(_p3##x,_p3##y,_n2##z,c), I[246] = (T)(img)(_p2##x,_p3##y,_n2##z,c), I[247] = (T)(img)(_p1##x,_p3##y,_n2##z,c), I[248] = (T)(img)(x,_p3##y,_n2##z,c), I[249] = (T)(img)(_n1##x,_p3##y,_n2##z,c), I[250] = (T)(img)(_n2##x,_p3##y,_n2##z,c), I[251] = (T)(img)(_n3##x,_p3##y,_n2##z,c), \ - I[252] = (T)(img)(_p3##x,_p2##y,_n2##z,c), I[253] = (T)(img)(_p2##x,_p2##y,_n2##z,c), I[254] = (T)(img)(_p1##x,_p2##y,_n2##z,c), I[255] = (T)(img)(x,_p2##y,_n2##z,c), I[256] = (T)(img)(_n1##x,_p2##y,_n2##z,c), I[257] = (T)(img)(_n2##x,_p2##y,_n2##z,c), I[258] = (T)(img)(_n3##x,_p2##y,_n2##z,c), \ - I[259] = (T)(img)(_p3##x,_p1##y,_n2##z,c), I[260] = (T)(img)(_p2##x,_p1##y,_n2##z,c), I[261] = (T)(img)(_p1##x,_p1##y,_n2##z,c), I[262] = (T)(img)(x,_p1##y,_n2##z,c), I[263] = (T)(img)(_n1##x,_p1##y,_n2##z,c), I[264] = (T)(img)(_n2##x,_p1##y,_n2##z,c), I[265] = (T)(img)(_n3##x,_p1##y,_n2##z,c), \ - I[266] = (T)(img)(_p3##x,y,_n2##z,c), I[267] = (T)(img)(_p2##x,y,_n2##z,c), I[268] = (T)(img)(_p1##x,y,_n2##z,c), I[269] = (T)(img)(x,y,_n2##z,c), I[270] = (T)(img)(_n1##x,y,_n2##z,c), I[271] = (T)(img)(_n2##x,y,_n2##z,c), I[272] = (T)(img)(_n3##x,y,_n2##z,c), \ - I[273] = (T)(img)(_p3##x,_n1##y,_n2##z,c), I[274] = (T)(img)(_p2##x,_n1##y,_n2##z,c), I[275] = (T)(img)(_p1##x,_n1##y,_n2##z,c), I[276] = (T)(img)(x,_n1##y,_n2##z,c), I[277] = (T)(img)(_n1##x,_n1##y,_n2##z,c), I[278] = (T)(img)(_n2##x,_n1##y,_n2##z,c), I[279] = (T)(img)(_n3##x,_n1##y,_n2##z,c), \ - I[280] = (T)(img)(_p3##x,_n2##y,_n2##z,c), I[281] = (T)(img)(_p2##x,_n2##y,_n2##z,c), I[282] = (T)(img)(_p1##x,_n2##y,_n2##z,c), I[283] = (T)(img)(x,_n2##y,_n2##z,c), I[284] = (T)(img)(_n1##x,_n2##y,_n2##z,c), I[285] = (T)(img)(_n2##x,_n2##y,_n2##z,c), I[286] = (T)(img)(_n3##x,_n2##y,_n2##z,c), \ - I[287] = (T)(img)(_p3##x,_n3##y,_n2##z,c), I[288] = (T)(img)(_p2##x,_n3##y,_n2##z,c), I[289] = (T)(img)(_p1##x,_n3##y,_n2##z,c), I[290] = (T)(img)(x,_n3##y,_n2##z,c), I[291] = (T)(img)(_n1##x,_n3##y,_n2##z,c), I[292] = (T)(img)(_n2##x,_n3##y,_n2##z,c), I[293] = (T)(img)(_n3##x,_n3##y,_n2##z,c), \ - I[294] = (T)(img)(_p3##x,_p3##y,_n3##z,c), I[295] = (T)(img)(_p2##x,_p3##y,_n3##z,c), I[296] = (T)(img)(_p1##x,_p3##y,_n3##z,c), I[297] = (T)(img)(x,_p3##y,_n3##z,c), I[298] = (T)(img)(_n1##x,_p3##y,_n3##z,c), I[299] = (T)(img)(_n2##x,_p3##y,_n3##z,c), I[300] = (T)(img)(_n3##x,_p3##y,_n3##z,c), \ - I[301] = (T)(img)(_p3##x,_p2##y,_n3##z,c), I[302] = (T)(img)(_p2##x,_p2##y,_n3##z,c), I[303] = (T)(img)(_p1##x,_p2##y,_n3##z,c), I[304] = (T)(img)(x,_p2##y,_n3##z,c), I[305] = (T)(img)(_n1##x,_p2##y,_n3##z,c), I[306] = (T)(img)(_n2##x,_p2##y,_n3##z,c), I[307] = (T)(img)(_n3##x,_p2##y,_n3##z,c), \ - I[308] = (T)(img)(_p3##x,_p1##y,_n3##z,c), I[309] = (T)(img)(_p2##x,_p1##y,_n3##z,c), I[310] = (T)(img)(_p1##x,_p1##y,_n3##z,c), I[311] = (T)(img)(x,_p1##y,_n3##z,c), I[312] = (T)(img)(_n1##x,_p1##y,_n3##z,c), I[313] = (T)(img)(_n2##x,_p1##y,_n3##z,c), I[314] = (T)(img)(_n3##x,_p1##y,_n3##z,c), \ - I[315] = (T)(img)(_p3##x,y,_n3##z,c), I[316] = (T)(img)(_p2##x,y,_n3##z,c), I[317] = (T)(img)(_p1##x,y,_n3##z,c), I[318] = (T)(img)(x,y,_n3##z,c), I[319] = (T)(img)(_n1##x,y,_n3##z,c), I[320] = (T)(img)(_n2##x,y,_n3##z,c), I[321] = (T)(img)(_n3##x,y,_n3##z,c), \ - I[322] = (T)(img)(_p3##x,_n1##y,_n3##z,c), I[323] = (T)(img)(_p2##x,_n1##y,_n3##z,c), I[324] = (T)(img)(_p1##x,_n1##y,_n3##z,c), I[325] = (T)(img)(x,_n1##y,_n3##z,c), I[326] = (T)(img)(_n1##x,_n1##y,_n3##z,c), I[327] = (T)(img)(_n2##x,_n1##y,_n3##z,c), I[328] = (T)(img)(_n3##x,_n1##y,_n3##z,c), \ - I[329] = (T)(img)(_p3##x,_n2##y,_n3##z,c), I[330] = (T)(img)(_p2##x,_n2##y,_n3##z,c), I[331] = (T)(img)(_p1##x,_n2##y,_n3##z,c), I[332] = (T)(img)(x,_n2##y,_n3##z,c), I[333] = (T)(img)(_n1##x,_n2##y,_n3##z,c), I[334] = (T)(img)(_n2##x,_n2##y,_n3##z,c), I[335] = (T)(img)(_n3##x,_n2##y,_n3##z,c), \ - I[336] = (T)(img)(_p3##x,_n3##y,_n3##z,c), I[337] = (T)(img)(_p2##x,_n3##y,_n3##z,c), I[338] = (T)(img)(_p1##x,_n3##y,_n3##z,c), I[339] = (T)(img)(x,_n3##y,_n3##z,c), I[340] = (T)(img)(_n1##x,_n3##y,_n3##z,c), I[341] = (T)(img)(_n2##x,_n3##y,_n3##z,c), I[342] = (T)(img)(_n3##x,_n3##y,_n3##z,c); - -// Define 8x8x8 loop macros -//---------------------------- -#define cimg_for8x8x8(img,x,y,z,c,I,T) \ - cimg_for8((img)._depth,z) cimg_for8((img)._height,y) for (int x = 0, \ - _p3##x = 0, _p2##x = 0, _p1##x = 0, \ - _n1##x = 1>=((img)._width)?(img).width() - 1:1, \ - _n2##x = 2>=((img)._width)?(img).width() - 1:2, \ - _n3##x = 3>=((img)._width)?(img).width() - 1:3, \ - _n4##x = (int)( \ - (I[0] = I[1] = I[2] = I[3] = (T)(img)(0,_p3##y,_p3##z,c)), \ - (I[8] = I[9] = I[10] = I[11] = (T)(img)(0,_p2##y,_p3##z,c)), \ - (I[16] = I[17] = I[18] = I[19] = (T)(img)(0,_p1##y,_p3##z,c)), \ - (I[24] = I[25] = I[26] = I[27] = (T)(img)(0,y,_p3##z,c)), \ - (I[32] = I[33] = I[34] = I[35] = (T)(img)(0,_n1##y,_p3##z,c)), \ - (I[40] = I[41] = I[42] = I[43] = (T)(img)(0,_n2##y,_p3##z,c)), \ - (I[48] = I[49] = I[50] = I[51] = (T)(img)(0,_n3##y,_p3##z,c)), \ - (I[56] = I[57] = I[58] = I[59] = (T)(img)(0,_n4##y,_p3##z,c)), \ - (I[64] = I[65] = I[66] = I[67] = (T)(img)(0,_p3##y,_p2##z,c)), \ - (I[72] = I[73] = I[74] = I[75] = (T)(img)(0,_p2##y,_p2##z,c)), \ - (I[80] = I[81] = I[82] = I[83] = (T)(img)(0,_p1##y,_p2##z,c)), \ - (I[88] = I[89] = I[90] = I[91] = (T)(img)(0,y,_p2##z,c)), \ - (I[96] = I[97] = I[98] = I[99] = (T)(img)(0,_n1##y,_p2##z,c)), \ - (I[104] = I[105] = I[106] = I[107] = (T)(img)(0,_n2##y,_p2##z,c)), \ - (I[112] = I[113] = I[114] = I[115] = (T)(img)(0,_n3##y,_p2##z,c)), \ - (I[120] = I[121] = I[122] = I[123] = (T)(img)(0,_n4##y,_p2##z,c)), \ - (I[128] = I[129] = I[130] = I[131] = (T)(img)(0,_p3##y,_p1##z,c)), \ - (I[136] = I[137] = I[138] = I[139] = (T)(img)(0,_p2##y,_p1##z,c)), \ - (I[144] = I[145] = I[146] = I[147] = (T)(img)(0,_p1##y,_p1##z,c)), \ - (I[152] = I[153] = I[154] = I[155] = (T)(img)(0,y,_p1##z,c)), \ - (I[160] = I[161] = I[162] = I[163] = (T)(img)(0,_n1##y,_p1##z,c)), \ - (I[168] = I[169] = I[170] = I[171] = (T)(img)(0,_n2##y,_p1##z,c)), \ - (I[176] = I[177] = I[178] = I[179] = (T)(img)(0,_n3##y,_p1##z,c)), \ - (I[184] = I[185] = I[186] = I[187] = (T)(img)(0,_n4##y,_p1##z,c)), \ - (I[192] = I[193] = I[194] = I[195] = (T)(img)(0,_p3##y,z,c)), \ - (I[200] = I[201] = I[202] = I[203] = (T)(img)(0,_p2##y,z,c)), \ - (I[208] = I[209] = I[210] = I[211] = (T)(img)(0,_p1##y,z,c)), \ - (I[216] = I[217] = I[218] = I[219] = (T)(img)(0,y,z,c)), \ - (I[224] = I[225] = I[226] = I[227] = (T)(img)(0,_n1##y,z,c)), \ - (I[232] = I[233] = I[234] = I[235] = (T)(img)(0,_n2##y,z,c)), \ - (I[240] = I[241] = I[242] = I[243] = (T)(img)(0,_n3##y,z,c)), \ - (I[248] = I[249] = I[250] = I[251] = (T)(img)(0,_n4##y,z,c)), \ - (I[256] = I[257] = I[258] = I[259] = (T)(img)(0,_p3##y,_n1##z,c)), \ - (I[264] = I[265] = I[266] = I[267] = (T)(img)(0,_p2##y,_n1##z,c)), \ - (I[272] = I[273] = I[274] = I[275] = (T)(img)(0,_p1##y,_n1##z,c)), \ - (I[280] = I[281] = I[282] = I[283] = (T)(img)(0,y,_n1##z,c)), \ - (I[288] = I[289] = I[290] = I[291] = (T)(img)(0,_n1##y,_n1##z,c)), \ - (I[296] = I[297] = I[298] = I[299] = (T)(img)(0,_n2##y,_n1##z,c)), \ - (I[304] = I[305] = I[306] = I[307] = (T)(img)(0,_n3##y,_n1##z,c)), \ - (I[312] = I[313] = I[314] = I[315] = (T)(img)(0,_n4##y,_n1##z,c)), \ - (I[320] = I[321] = I[322] = I[323] = (T)(img)(0,_p3##y,_n2##z,c)), \ - (I[328] = I[329] = I[330] = I[331] = (T)(img)(0,_p2##y,_n2##z,c)), \ - (I[336] = I[337] = I[338] = I[339] = (T)(img)(0,_p1##y,_n2##z,c)), \ - (I[344] = I[345] = I[346] = I[347] = (T)(img)(0,y,_n2##z,c)), \ - (I[352] = I[353] = I[354] = I[355] = (T)(img)(0,_n1##y,_n2##z,c)), \ - (I[360] = I[361] = I[362] = I[363] = (T)(img)(0,_n2##y,_n2##z,c)), \ - (I[368] = I[369] = I[370] = I[371] = (T)(img)(0,_n3##y,_n2##z,c)), \ - (I[376] = I[377] = I[378] = I[379] = (T)(img)(0,_n4##y,_n2##z,c)), \ - (I[384] = I[385] = I[386] = I[387] = (T)(img)(0,_p3##y,_n3##z,c)), \ - (I[392] = I[393] = I[394] = I[395] = (T)(img)(0,_p2##y,_n3##z,c)), \ - (I[400] = I[401] = I[402] = I[403] = (T)(img)(0,_p1##y,_n3##z,c)), \ - (I[408] = I[409] = I[410] = I[411] = (T)(img)(0,y,_n3##z,c)), \ - (I[416] = I[417] = I[418] = I[419] = (T)(img)(0,_n1##y,_n3##z,c)), \ - (I[424] = I[425] = I[426] = I[427] = (T)(img)(0,_n2##y,_n3##z,c)), \ - (I[432] = I[433] = I[434] = I[435] = (T)(img)(0,_n3##y,_n3##z,c)), \ - (I[440] = I[441] = I[442] = I[443] = (T)(img)(0,_n4##y,_n3##z,c)), \ - (I[448] = I[449] = I[450] = I[451] = (T)(img)(0,_p3##y,_n4##z,c)), \ - (I[456] = I[457] = I[458] = I[459] = (T)(img)(0,_p2##y,_n4##z,c)), \ - (I[464] = I[465] = I[466] = I[467] = (T)(img)(0,_p1##y,_n4##z,c)), \ - (I[472] = I[473] = I[474] = I[475] = (T)(img)(0,y,_n4##z,c)), \ - (I[480] = I[481] = I[482] = I[483] = (T)(img)(0,_n1##y,_n4##z,c)), \ - (I[488] = I[489] = I[490] = I[491] = (T)(img)(0,_n2##y,_n4##z,c)), \ - (I[496] = I[497] = I[498] = I[499] = (T)(img)(0,_n3##y,_n4##z,c)), \ - (I[504] = I[505] = I[506] = I[507] = (T)(img)(0,_n4##y,_n4##z,c)), \ - (I[4] = (T)(img)(_n1##x,_p3##y,_p3##z,c)), \ - (I[12] = (T)(img)(_n1##x,_p2##y,_p3##z,c)), \ - (I[20] = (T)(img)(_n1##x,_p1##y,_p3##z,c)), \ - (I[28] = (T)(img)(_n1##x,y,_p3##z,c)), \ - (I[36] = (T)(img)(_n1##x,_n1##y,_p3##z,c)), \ - (I[44] = (T)(img)(_n1##x,_n2##y,_p3##z,c)), \ - (I[52] = (T)(img)(_n1##x,_n3##y,_p3##z,c)), \ - (I[60] = (T)(img)(_n1##x,_n4##y,_p3##z,c)), \ - (I[68] = (T)(img)(_n1##x,_p3##y,_p2##z,c)), \ - (I[76] = (T)(img)(_n1##x,_p2##y,_p2##z,c)), \ - (I[84] = (T)(img)(_n1##x,_p1##y,_p2##z,c)), \ - (I[92] = (T)(img)(_n1##x,y,_p2##z,c)), \ - (I[100] = (T)(img)(_n1##x,_n1##y,_p2##z,c)), \ - (I[108] = (T)(img)(_n1##x,_n2##y,_p2##z,c)), \ - (I[116] = (T)(img)(_n1##x,_n3##y,_p2##z,c)), \ - (I[124] = (T)(img)(_n1##x,_n4##y,_p2##z,c)), \ - (I[132] = (T)(img)(_n1##x,_p3##y,_p1##z,c)), \ - (I[140] = (T)(img)(_n1##x,_p2##y,_p1##z,c)), \ - (I[148] = (T)(img)(_n1##x,_p1##y,_p1##z,c)), \ - (I[156] = (T)(img)(_n1##x,y,_p1##z,c)), \ - (I[164] = (T)(img)(_n1##x,_n1##y,_p1##z,c)), \ - (I[172] = (T)(img)(_n1##x,_n2##y,_p1##z,c)), \ - (I[180] = (T)(img)(_n1##x,_n3##y,_p1##z,c)), \ - (I[188] = (T)(img)(_n1##x,_n4##y,_p1##z,c)), \ - (I[196] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[204] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[212] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[220] = (T)(img)(_n1##x,y,z,c)), \ - (I[228] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[236] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[244] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[252] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[260] = (T)(img)(_n1##x,_p3##y,_n1##z,c)), \ - (I[268] = (T)(img)(_n1##x,_p2##y,_n1##z,c)), \ - (I[276] = (T)(img)(_n1##x,_p1##y,_n1##z,c)), \ - (I[284] = (T)(img)(_n1##x,y,_n1##z,c)), \ - (I[292] = (T)(img)(_n1##x,_n1##y,_n1##z,c)), \ - (I[300] = (T)(img)(_n1##x,_n2##y,_n1##z,c)), \ - (I[308] = (T)(img)(_n1##x,_n3##y,_n1##z,c)), \ - (I[316] = (T)(img)(_n1##x,_n4##y,_n1##z,c)), \ - (I[324] = (T)(img)(_n1##x,_p3##y,_n2##z,c)), \ - (I[332] = (T)(img)(_n1##x,_p2##y,_n2##z,c)), \ - (I[340] = (T)(img)(_n1##x,_p1##y,_n2##z,c)), \ - (I[348] = (T)(img)(_n1##x,y,_n2##z,c)), \ - (I[356] = (T)(img)(_n1##x,_n1##y,_n2##z,c)), \ - (I[364] = (T)(img)(_n1##x,_n2##y,_n2##z,c)), \ - (I[372] = (T)(img)(_n1##x,_n3##y,_n2##z,c)), \ - (I[380] = (T)(img)(_n1##x,_n4##y,_n2##z,c)), \ - (I[388] = (T)(img)(_n1##x,_p3##y,_n3##z,c)), \ - (I[396] = (T)(img)(_n1##x,_p2##y,_n3##z,c)), \ - (I[404] = (T)(img)(_n1##x,_p1##y,_n3##z,c)), \ - (I[412] = (T)(img)(_n1##x,y,_n3##z,c)), \ - (I[420] = (T)(img)(_n1##x,_n1##y,_n3##z,c)), \ - (I[428] = (T)(img)(_n1##x,_n2##y,_n3##z,c)), \ - (I[436] = (T)(img)(_n1##x,_n3##y,_n3##z,c)), \ - (I[444] = (T)(img)(_n1##x,_n4##y,_n3##z,c)), \ - (I[452] = (T)(img)(_n1##x,_p3##y,_n4##z,c)), \ - (I[460] = (T)(img)(_n1##x,_p2##y,_n4##z,c)), \ - (I[468] = (T)(img)(_n1##x,_p1##y,_n4##z,c)), \ - (I[476] = (T)(img)(_n1##x,y,_n4##z,c)), \ - (I[484] = (T)(img)(_n1##x,_n1##y,_n4##z,c)), \ - (I[492] = (T)(img)(_n1##x,_n2##y,_n4##z,c)), \ - (I[500] = (T)(img)(_n1##x,_n3##y,_n4##z,c)), \ - (I[508] = (T)(img)(_n1##x,_n4##y,_n4##z,c)), \ - (I[5] = (T)(img)(_n2##x,_p3##y,_p3##z,c)), \ - (I[13] = (T)(img)(_n2##x,_p2##y,_p3##z,c)), \ - (I[21] = (T)(img)(_n2##x,_p1##y,_p3##z,c)), \ - (I[29] = (T)(img)(_n2##x,y,_p3##z,c)), \ - (I[37] = (T)(img)(_n2##x,_n1##y,_p3##z,c)), \ - (I[45] = (T)(img)(_n2##x,_n2##y,_p3##z,c)), \ - (I[53] = (T)(img)(_n2##x,_n3##y,_p3##z,c)), \ - (I[61] = (T)(img)(_n2##x,_n4##y,_p3##z,c)), \ - (I[69] = (T)(img)(_n2##x,_p3##y,_p2##z,c)), \ - (I[77] = (T)(img)(_n2##x,_p2##y,_p2##z,c)), \ - (I[85] = (T)(img)(_n2##x,_p1##y,_p2##z,c)), \ - (I[93] = (T)(img)(_n2##x,y,_p2##z,c)), \ - (I[101] = (T)(img)(_n2##x,_n1##y,_p2##z,c)), \ - (I[109] = (T)(img)(_n2##x,_n2##y,_p2##z,c)), \ - (I[117] = (T)(img)(_n2##x,_n3##y,_p2##z,c)), \ - (I[125] = (T)(img)(_n2##x,_n4##y,_p2##z,c)), \ - (I[133] = (T)(img)(_n2##x,_p3##y,_p1##z,c)), \ - (I[141] = (T)(img)(_n2##x,_p2##y,_p1##z,c)), \ - (I[149] = (T)(img)(_n2##x,_p1##y,_p1##z,c)), \ - (I[157] = (T)(img)(_n2##x,y,_p1##z,c)), \ - (I[165] = (T)(img)(_n2##x,_n1##y,_p1##z,c)), \ - (I[173] = (T)(img)(_n2##x,_n2##y,_p1##z,c)), \ - (I[181] = (T)(img)(_n2##x,_n3##y,_p1##z,c)), \ - (I[189] = (T)(img)(_n2##x,_n4##y,_p1##z,c)), \ - (I[197] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[205] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[213] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[221] = (T)(img)(_n2##x,y,z,c)), \ - (I[229] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[237] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[245] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[253] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[261] = (T)(img)(_n2##x,_p3##y,_n1##z,c)), \ - (I[269] = (T)(img)(_n2##x,_p2##y,_n1##z,c)), \ - (I[277] = (T)(img)(_n2##x,_p1##y,_n1##z,c)), \ - (I[285] = (T)(img)(_n2##x,y,_n1##z,c)), \ - (I[293] = (T)(img)(_n2##x,_n1##y,_n1##z,c)), \ - (I[301] = (T)(img)(_n2##x,_n2##y,_n1##z,c)), \ - (I[309] = (T)(img)(_n2##x,_n3##y,_n1##z,c)), \ - (I[317] = (T)(img)(_n2##x,_n4##y,_n1##z,c)), \ - (I[325] = (T)(img)(_n2##x,_p3##y,_n2##z,c)), \ - (I[333] = (T)(img)(_n2##x,_p2##y,_n2##z,c)), \ - (I[341] = (T)(img)(_n2##x,_p1##y,_n2##z,c)), \ - (I[349] = (T)(img)(_n2##x,y,_n2##z,c)), \ - (I[357] = (T)(img)(_n2##x,_n1##y,_n2##z,c)), \ - (I[365] = (T)(img)(_n2##x,_n2##y,_n2##z,c)), \ - (I[373] = (T)(img)(_n2##x,_n3##y,_n2##z,c)), \ - (I[381] = (T)(img)(_n2##x,_n4##y,_n2##z,c)), \ - (I[389] = (T)(img)(_n2##x,_p3##y,_n3##z,c)), \ - (I[397] = (T)(img)(_n2##x,_p2##y,_n3##z,c)), \ - (I[405] = (T)(img)(_n2##x,_p1##y,_n3##z,c)), \ - (I[413] = (T)(img)(_n2##x,y,_n3##z,c)), \ - (I[421] = (T)(img)(_n2##x,_n1##y,_n3##z,c)), \ - (I[429] = (T)(img)(_n2##x,_n2##y,_n3##z,c)), \ - (I[437] = (T)(img)(_n2##x,_n3##y,_n3##z,c)), \ - (I[445] = (T)(img)(_n2##x,_n4##y,_n3##z,c)), \ - (I[453] = (T)(img)(_n2##x,_p3##y,_n4##z,c)), \ - (I[461] = (T)(img)(_n2##x,_p2##y,_n4##z,c)), \ - (I[469] = (T)(img)(_n2##x,_p1##y,_n4##z,c)), \ - (I[477] = (T)(img)(_n2##x,y,_n4##z,c)), \ - (I[485] = (T)(img)(_n2##x,_n1##y,_n4##z,c)), \ - (I[493] = (T)(img)(_n2##x,_n2##y,_n4##z,c)), \ - (I[501] = (T)(img)(_n2##x,_n3##y,_n4##z,c)), \ - (I[509] = (T)(img)(_n2##x,_n4##y,_n4##z,c)), \ - (I[6] = (T)(img)(_n3##x,_p3##y,_p3##z,c)), \ - (I[14] = (T)(img)(_n3##x,_p2##y,_p3##z,c)), \ - (I[22] = (T)(img)(_n3##x,_p1##y,_p3##z,c)), \ - (I[30] = (T)(img)(_n3##x,y,_p3##z,c)), \ - (I[38] = (T)(img)(_n3##x,_n1##y,_p3##z,c)), \ - (I[46] = (T)(img)(_n3##x,_n2##y,_p3##z,c)), \ - (I[54] = (T)(img)(_n3##x,_n3##y,_p3##z,c)), \ - (I[62] = (T)(img)(_n3##x,_n4##y,_p3##z,c)), \ - (I[70] = (T)(img)(_n3##x,_p3##y,_p2##z,c)), \ - (I[78] = (T)(img)(_n3##x,_p2##y,_p2##z,c)), \ - (I[86] = (T)(img)(_n3##x,_p1##y,_p2##z,c)), \ - (I[94] = (T)(img)(_n3##x,y,_p2##z,c)), \ - (I[102] = (T)(img)(_n3##x,_n1##y,_p2##z,c)), \ - (I[110] = (T)(img)(_n3##x,_n2##y,_p2##z,c)), \ - (I[118] = (T)(img)(_n3##x,_n3##y,_p2##z,c)), \ - (I[126] = (T)(img)(_n3##x,_n4##y,_p2##z,c)), \ - (I[134] = (T)(img)(_n3##x,_p3##y,_p1##z,c)), \ - (I[142] = (T)(img)(_n3##x,_p2##y,_p1##z,c)), \ - (I[150] = (T)(img)(_n3##x,_p1##y,_p1##z,c)), \ - (I[158] = (T)(img)(_n3##x,y,_p1##z,c)), \ - (I[166] = (T)(img)(_n3##x,_n1##y,_p1##z,c)), \ - (I[174] = (T)(img)(_n3##x,_n2##y,_p1##z,c)), \ - (I[182] = (T)(img)(_n3##x,_n3##y,_p1##z,c)), \ - (I[190] = (T)(img)(_n3##x,_n4##y,_p1##z,c)), \ - (I[198] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[206] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[214] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[222] = (T)(img)(_n3##x,y,z,c)), \ - (I[230] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[238] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[246] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[254] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[262] = (T)(img)(_n3##x,_p3##y,_n1##z,c)), \ - (I[270] = (T)(img)(_n3##x,_p2##y,_n1##z,c)), \ - (I[278] = (T)(img)(_n3##x,_p1##y,_n1##z,c)), \ - (I[286] = (T)(img)(_n3##x,y,_n1##z,c)), \ - (I[294] = (T)(img)(_n3##x,_n1##y,_n1##z,c)), \ - (I[302] = (T)(img)(_n3##x,_n2##y,_n1##z,c)), \ - (I[310] = (T)(img)(_n3##x,_n3##y,_n1##z,c)), \ - (I[318] = (T)(img)(_n3##x,_n4##y,_n1##z,c)), \ - (I[326] = (T)(img)(_n3##x,_p3##y,_n2##z,c)), \ - (I[334] = (T)(img)(_n3##x,_p2##y,_n2##z,c)), \ - (I[342] = (T)(img)(_n3##x,_p1##y,_n2##z,c)), \ - (I[350] = (T)(img)(_n3##x,y,_n2##z,c)), \ - (I[358] = (T)(img)(_n3##x,_n1##y,_n2##z,c)), \ - (I[366] = (T)(img)(_n3##x,_n2##y,_n2##z,c)), \ - (I[374] = (T)(img)(_n3##x,_n3##y,_n2##z,c)), \ - (I[382] = (T)(img)(_n3##x,_n4##y,_n2##z,c)), \ - (I[390] = (T)(img)(_n3##x,_p3##y,_n3##z,c)), \ - (I[398] = (T)(img)(_n3##x,_p2##y,_n3##z,c)), \ - (I[406] = (T)(img)(_n3##x,_p1##y,_n3##z,c)), \ - (I[414] = (T)(img)(_n3##x,y,_n3##z,c)), \ - (I[422] = (T)(img)(_n3##x,_n1##y,_n3##z,c)), \ - (I[430] = (T)(img)(_n3##x,_n2##y,_n3##z,c)), \ - (I[438] = (T)(img)(_n3##x,_n3##y,_n3##z,c)), \ - (I[446] = (T)(img)(_n3##x,_n4##y,_n3##z,c)), \ - (I[454] = (T)(img)(_n3##x,_p3##y,_n4##z,c)), \ - (I[462] = (T)(img)(_n3##x,_p2##y,_n4##z,c)), \ - (I[470] = (T)(img)(_n3##x,_p1##y,_n4##z,c)), \ - (I[478] = (T)(img)(_n3##x,y,_n4##z,c)), \ - (I[486] = (T)(img)(_n3##x,_n1##y,_n4##z,c)), \ - (I[494] = (T)(img)(_n3##x,_n2##y,_n4##z,c)), \ - (I[502] = (T)(img)(_n3##x,_n3##y,_n4##z,c)), \ - (I[510] = (T)(img)(_n3##x,_n4##y,_n4##z,c)), \ - 4>=((img)._width)?(img).width() - 1:4); \ - (_n4##x<(img).width() && ( \ - (I[7] = (T)(img)(_n4##x,_p3##y,_p3##z,c)), \ - (I[15] = (T)(img)(_n4##x,_p2##y,_p3##z,c)), \ - (I[23] = (T)(img)(_n4##x,_p1##y,_p3##z,c)), \ - (I[31] = (T)(img)(_n4##x,y,_p3##z,c)), \ - (I[39] = (T)(img)(_n4##x,_n1##y,_p3##z,c)), \ - (I[47] = (T)(img)(_n4##x,_n2##y,_p3##z,c)), \ - (I[55] = (T)(img)(_n4##x,_n3##y,_p3##z,c)), \ - (I[63] = (T)(img)(_n4##x,_n4##y,_p3##z,c)), \ - (I[71] = (T)(img)(_n4##x,_p3##y,_p2##z,c)), \ - (I[79] = (T)(img)(_n4##x,_p2##y,_p2##z,c)), \ - (I[87] = (T)(img)(_n4##x,_p1##y,_p2##z,c)), \ - (I[95] = (T)(img)(_n4##x,y,_p2##z,c)), \ - (I[103] = (T)(img)(_n4##x,_n1##y,_p2##z,c)), \ - (I[111] = (T)(img)(_n4##x,_n2##y,_p2##z,c)), \ - (I[119] = (T)(img)(_n4##x,_n3##y,_p2##z,c)), \ - (I[127] = (T)(img)(_n4##x,_n4##y,_p2##z,c)), \ - (I[135] = (T)(img)(_n4##x,_p3##y,_p1##z,c)), \ - (I[143] = (T)(img)(_n4##x,_p2##y,_p1##z,c)), \ - (I[151] = (T)(img)(_n4##x,_p1##y,_p1##z,c)), \ - (I[159] = (T)(img)(_n4##x,y,_p1##z,c)), \ - (I[167] = (T)(img)(_n4##x,_n1##y,_p1##z,c)), \ - (I[175] = (T)(img)(_n4##x,_n2##y,_p1##z,c)), \ - (I[183] = (T)(img)(_n4##x,_n3##y,_p1##z,c)), \ - (I[191] = (T)(img)(_n4##x,_n4##y,_p1##z,c)), \ - (I[199] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[207] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[215] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[223] = (T)(img)(_n4##x,y,z,c)), \ - (I[231] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[239] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[247] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[255] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[263] = (T)(img)(_n4##x,_p3##y,_n1##z,c)), \ - (I[271] = (T)(img)(_n4##x,_p2##y,_n1##z,c)), \ - (I[279] = (T)(img)(_n4##x,_p1##y,_n1##z,c)), \ - (I[287] = (T)(img)(_n4##x,y,_n1##z,c)), \ - (I[295] = (T)(img)(_n4##x,_n1##y,_n1##z,c)), \ - (I[303] = (T)(img)(_n4##x,_n2##y,_n1##z,c)), \ - (I[311] = (T)(img)(_n4##x,_n3##y,_n1##z,c)), \ - (I[319] = (T)(img)(_n4##x,_n4##y,_n1##z,c)), \ - (I[327] = (T)(img)(_n4##x,_p3##y,_n2##z,c)), \ - (I[335] = (T)(img)(_n4##x,_p2##y,_n2##z,c)), \ - (I[343] = (T)(img)(_n4##x,_p1##y,_n2##z,c)), \ - (I[351] = (T)(img)(_n4##x,y,_n2##z,c)), \ - (I[359] = (T)(img)(_n4##x,_n1##y,_n2##z,c)), \ - (I[367] = (T)(img)(_n4##x,_n2##y,_n2##z,c)), \ - (I[375] = (T)(img)(_n4##x,_n3##y,_n2##z,c)), \ - (I[383] = (T)(img)(_n4##x,_n4##y,_n2##z,c)), \ - (I[391] = (T)(img)(_n4##x,_p3##y,_n3##z,c)), \ - (I[399] = (T)(img)(_n4##x,_p2##y,_n3##z,c)), \ - (I[407] = (T)(img)(_n4##x,_p1##y,_n3##z,c)), \ - (I[415] = (T)(img)(_n4##x,y,_n3##z,c)), \ - (I[423] = (T)(img)(_n4##x,_n1##y,_n3##z,c)), \ - (I[431] = (T)(img)(_n4##x,_n2##y,_n3##z,c)), \ - (I[439] = (T)(img)(_n4##x,_n3##y,_n3##z,c)), \ - (I[447] = (T)(img)(_n4##x,_n4##y,_n3##z,c)), \ - (I[455] = (T)(img)(_n4##x,_p3##y,_n4##z,c)), \ - (I[463] = (T)(img)(_n4##x,_p2##y,_n4##z,c)), \ - (I[471] = (T)(img)(_n4##x,_p1##y,_n4##z,c)), \ - (I[479] = (T)(img)(_n4##x,y,_n4##z,c)), \ - (I[487] = (T)(img)(_n4##x,_n1##y,_n4##z,c)), \ - (I[495] = (T)(img)(_n4##x,_n2##y,_n4##z,c)), \ - (I[503] = (T)(img)(_n4##x,_n3##y,_n4##z,c)), \ - (I[511] = (T)(img)(_n4##x,_n4##y,_n4##z,c)),1)) || \ - _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n4##x = _n3##x = _n2##x = --_n1##x); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], \ - I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], \ - I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \ - I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], \ - I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], \ - I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], \ - I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], \ - I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], \ - I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], \ - I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], \ - I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], \ - I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], \ - I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], \ - I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], \ - I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], \ - I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], \ - I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], \ - I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], \ - I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], \ - I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], \ - I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], \ - I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], \ - I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], \ - I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], \ - I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], \ - I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], \ - I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], \ - I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], \ - I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], \ - I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], \ - I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], \ - I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], \ - I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], \ - I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], \ - I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], \ - I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], \ - I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], \ - I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], \ - I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], \ - I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], \ - I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], \ - I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], \ - I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], \ - I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], \ - I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], \ - I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], \ - I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], \ - I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], \ - I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], \ - I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], \ - I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], \ - I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], \ - I[416] = I[417], I[417] = I[418], I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], \ - I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], \ - I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], \ - I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], \ - I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], \ - I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], \ - I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], \ - I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], \ - I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], \ - I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], I[493] = I[494], I[494] = I[495], \ - I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], \ - I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], \ - _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x) - -#define cimg_for_in8x8x8(img,x0,y0,z0,x1,y1,z1,x,y,z,c,I,T) \ - cimg_for_in8((img)._depth,z0,z1,z) cimg_for_in8((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \ - _p3##x = x - 3<0?0:x - 3, \ - _p2##x = x - 2<0?0:x - 2, \ - _p1##x = x - 1<0?0:x - 1, \ - _n1##x = x + 1>=(img).width()?(img).width() - 1:x + 1, \ - _n2##x = x + 2>=(img).width()?(img).width() - 1:x + 2, \ - _n3##x = x + 3>=(img).width()?(img).width() - 1:x + 3, \ - _n4##x = (int)( \ - (I[0] = (T)(img)(_p3##x,_p3##y,_p3##z,c)), \ - (I[8] = (T)(img)(_p3##x,_p2##y,_p3##z,c)), \ - (I[16] = (T)(img)(_p3##x,_p1##y,_p3##z,c)), \ - (I[24] = (T)(img)(_p3##x,y,_p3##z,c)), \ - (I[32] = (T)(img)(_p3##x,_n1##y,_p3##z,c)), \ - (I[40] = (T)(img)(_p3##x,_n2##y,_p3##z,c)), \ - (I[48] = (T)(img)(_p3##x,_n3##y,_p3##z,c)), \ - (I[56] = (T)(img)(_p3##x,_n4##y,_p3##z,c)), \ - (I[64] = (T)(img)(_p3##x,_p3##y,_p2##z,c)), \ - (I[72] = (T)(img)(_p3##x,_p2##y,_p2##z,c)), \ - (I[80] = (T)(img)(_p3##x,_p1##y,_p2##z,c)), \ - (I[88] = (T)(img)(_p3##x,y,_p2##z,c)), \ - (I[96] = (T)(img)(_p3##x,_n1##y,_p2##z,c)), \ - (I[104] = (T)(img)(_p3##x,_n2##y,_p2##z,c)), \ - (I[112] = (T)(img)(_p3##x,_n3##y,_p2##z,c)), \ - (I[120] = (T)(img)(_p3##x,_n4##y,_p2##z,c)), \ - (I[128] = (T)(img)(_p3##x,_p3##y,_p1##z,c)), \ - (I[136] = (T)(img)(_p3##x,_p2##y,_p1##z,c)), \ - (I[144] = (T)(img)(_p3##x,_p1##y,_p1##z,c)), \ - (I[152] = (T)(img)(_p3##x,y,_p1##z,c)), \ - (I[160] = (T)(img)(_p3##x,_n1##y,_p1##z,c)), \ - (I[168] = (T)(img)(_p3##x,_n2##y,_p1##z,c)), \ - (I[176] = (T)(img)(_p3##x,_n3##y,_p1##z,c)), \ - (I[184] = (T)(img)(_p3##x,_n4##y,_p1##z,c)), \ - (I[192] = (T)(img)(_p3##x,_p3##y,z,c)), \ - (I[200] = (T)(img)(_p3##x,_p2##y,z,c)), \ - (I[208] = (T)(img)(_p3##x,_p1##y,z,c)), \ - (I[216] = (T)(img)(_p3##x,y,z,c)), \ - (I[224] = (T)(img)(_p3##x,_n1##y,z,c)), \ - (I[232] = (T)(img)(_p3##x,_n2##y,z,c)), \ - (I[240] = (T)(img)(_p3##x,_n3##y,z,c)), \ - (I[248] = (T)(img)(_p3##x,_n4##y,z,c)), \ - (I[256] = (T)(img)(_p3##x,_p3##y,_n1##z,c)), \ - (I[264] = (T)(img)(_p3##x,_p2##y,_n1##z,c)), \ - (I[272] = (T)(img)(_p3##x,_p1##y,_n1##z,c)), \ - (I[280] = (T)(img)(_p3##x,y,_n1##z,c)), \ - (I[288] = (T)(img)(_p3##x,_n1##y,_n1##z,c)), \ - (I[296] = (T)(img)(_p3##x,_n2##y,_n1##z,c)), \ - (I[304] = (T)(img)(_p3##x,_n3##y,_n1##z,c)), \ - (I[312] = (T)(img)(_p3##x,_n4##y,_n1##z,c)), \ - (I[320] = (T)(img)(_p3##x,_p3##y,_n2##z,c)), \ - (I[328] = (T)(img)(_p3##x,_p2##y,_n2##z,c)), \ - (I[336] = (T)(img)(_p3##x,_p1##y,_n2##z,c)), \ - (I[344] = (T)(img)(_p3##x,y,_n2##z,c)), \ - (I[352] = (T)(img)(_p3##x,_n1##y,_n2##z,c)), \ - (I[360] = (T)(img)(_p3##x,_n2##y,_n2##z,c)), \ - (I[368] = (T)(img)(_p3##x,_n3##y,_n2##z,c)), \ - (I[376] = (T)(img)(_p3##x,_n4##y,_n2##z,c)), \ - (I[384] = (T)(img)(_p3##x,_p3##y,_n3##z,c)), \ - (I[392] = (T)(img)(_p3##x,_p2##y,_n3##z,c)), \ - (I[400] = (T)(img)(_p3##x,_p1##y,_n3##z,c)), \ - (I[408] = (T)(img)(_p3##x,y,_n3##z,c)), \ - (I[416] = (T)(img)(_p3##x,_n1##y,_n3##z,c)), \ - (I[424] = (T)(img)(_p3##x,_n2##y,_n3##z,c)), \ - (I[432] = (T)(img)(_p3##x,_n3##y,_n3##z,c)), \ - (I[440] = (T)(img)(_p3##x,_n4##y,_n3##z,c)), \ - (I[448] = (T)(img)(_p3##x,_p3##y,_n4##z,c)), \ - (I[456] = (T)(img)(_p3##x,_p2##y,_n4##z,c)), \ - (I[464] = (T)(img)(_p3##x,_p1##y,_n4##z,c)), \ - (I[472] = (T)(img)(_p3##x,y,_n4##z,c)), \ - (I[480] = (T)(img)(_p3##x,_n1##y,_n4##z,c)), \ - (I[488] = (T)(img)(_p3##x,_n2##y,_n4##z,c)), \ - (I[496] = (T)(img)(_p3##x,_n3##y,_n4##z,c)), \ - (I[504] = (T)(img)(_p3##x,_n4##y,_n4##z,c)), \ - (I[1] = (T)(img)(_p2##x,_p3##y,_p3##z,c)), \ - (I[9] = (T)(img)(_p2##x,_p2##y,_p3##z,c)), \ - (I[17] = (T)(img)(_p2##x,_p1##y,_p3##z,c)), \ - (I[25] = (T)(img)(_p2##x,y,_p3##z,c)), \ - (I[33] = (T)(img)(_p2##x,_n1##y,_p3##z,c)), \ - (I[41] = (T)(img)(_p2##x,_n2##y,_p3##z,c)), \ - (I[49] = (T)(img)(_p2##x,_n3##y,_p3##z,c)), \ - (I[57] = (T)(img)(_p2##x,_n4##y,_p3##z,c)), \ - (I[65] = (T)(img)(_p2##x,_p3##y,_p2##z,c)), \ - (I[73] = (T)(img)(_p2##x,_p2##y,_p2##z,c)), \ - (I[81] = (T)(img)(_p2##x,_p1##y,_p2##z,c)), \ - (I[89] = (T)(img)(_p2##x,y,_p2##z,c)), \ - (I[97] = (T)(img)(_p2##x,_n1##y,_p2##z,c)), \ - (I[105] = (T)(img)(_p2##x,_n2##y,_p2##z,c)), \ - (I[113] = (T)(img)(_p2##x,_n3##y,_p2##z,c)), \ - (I[121] = (T)(img)(_p2##x,_n4##y,_p2##z,c)), \ - (I[129] = (T)(img)(_p2##x,_p3##y,_p1##z,c)), \ - (I[137] = (T)(img)(_p2##x,_p2##y,_p1##z,c)), \ - (I[145] = (T)(img)(_p2##x,_p1##y,_p1##z,c)), \ - (I[153] = (T)(img)(_p2##x,y,_p1##z,c)), \ - (I[161] = (T)(img)(_p2##x,_n1##y,_p1##z,c)), \ - (I[169] = (T)(img)(_p2##x,_n2##y,_p1##z,c)), \ - (I[177] = (T)(img)(_p2##x,_n3##y,_p1##z,c)), \ - (I[185] = (T)(img)(_p2##x,_n4##y,_p1##z,c)), \ - (I[193] = (T)(img)(_p2##x,_p3##y,z,c)), \ - (I[201] = (T)(img)(_p2##x,_p2##y,z,c)), \ - (I[209] = (T)(img)(_p2##x,_p1##y,z,c)), \ - (I[217] = (T)(img)(_p2##x,y,z,c)), \ - (I[225] = (T)(img)(_p2##x,_n1##y,z,c)), \ - (I[233] = (T)(img)(_p2##x,_n2##y,z,c)), \ - (I[241] = (T)(img)(_p2##x,_n3##y,z,c)), \ - (I[249] = (T)(img)(_p2##x,_n4##y,z,c)), \ - (I[257] = (T)(img)(_p2##x,_p3##y,_n1##z,c)), \ - (I[265] = (T)(img)(_p2##x,_p2##y,_n1##z,c)), \ - (I[273] = (T)(img)(_p2##x,_p1##y,_n1##z,c)), \ - (I[281] = (T)(img)(_p2##x,y,_n1##z,c)), \ - (I[289] = (T)(img)(_p2##x,_n1##y,_n1##z,c)), \ - (I[297] = (T)(img)(_p2##x,_n2##y,_n1##z,c)), \ - (I[305] = (T)(img)(_p2##x,_n3##y,_n1##z,c)), \ - (I[313] = (T)(img)(_p2##x,_n4##y,_n1##z,c)), \ - (I[321] = (T)(img)(_p2##x,_p3##y,_n2##z,c)), \ - (I[329] = (T)(img)(_p2##x,_p2##y,_n2##z,c)), \ - (I[337] = (T)(img)(_p2##x,_p1##y,_n2##z,c)), \ - (I[345] = (T)(img)(_p2##x,y,_n2##z,c)), \ - (I[353] = (T)(img)(_p2##x,_n1##y,_n2##z,c)), \ - (I[361] = (T)(img)(_p2##x,_n2##y,_n2##z,c)), \ - (I[369] = (T)(img)(_p2##x,_n3##y,_n2##z,c)), \ - (I[377] = (T)(img)(_p2##x,_n4##y,_n2##z,c)), \ - (I[385] = (T)(img)(_p2##x,_p3##y,_n3##z,c)), \ - (I[393] = (T)(img)(_p2##x,_p2##y,_n3##z,c)), \ - (I[401] = (T)(img)(_p2##x,_p1##y,_n3##z,c)), \ - (I[409] = (T)(img)(_p2##x,y,_n3##z,c)), \ - (I[417] = (T)(img)(_p2##x,_n1##y,_n3##z,c)), \ - (I[425] = (T)(img)(_p2##x,_n2##y,_n3##z,c)), \ - (I[433] = (T)(img)(_p2##x,_n3##y,_n3##z,c)), \ - (I[441] = (T)(img)(_p2##x,_n4##y,_n3##z,c)), \ - (I[449] = (T)(img)(_p2##x,_p3##y,_n4##z,c)), \ - (I[457] = (T)(img)(_p2##x,_p2##y,_n4##z,c)), \ - (I[465] = (T)(img)(_p2##x,_p1##y,_n4##z,c)), \ - (I[473] = (T)(img)(_p2##x,y,_n4##z,c)), \ - (I[481] = (T)(img)(_p2##x,_n1##y,_n4##z,c)), \ - (I[489] = (T)(img)(_p2##x,_n2##y,_n4##z,c)), \ - (I[497] = (T)(img)(_p2##x,_n3##y,_n4##z,c)), \ - (I[505] = (T)(img)(_p2##x,_n4##y,_n4##z,c)), \ - (I[2] = (T)(img)(_p1##x,_p3##y,_p3##z,c)), \ - (I[10] = (T)(img)(_p1##x,_p2##y,_p3##z,c)), \ - (I[18] = (T)(img)(_p1##x,_p1##y,_p3##z,c)), \ - (I[26] = (T)(img)(_p1##x,y,_p3##z,c)), \ - (I[34] = (T)(img)(_p1##x,_n1##y,_p3##z,c)), \ - (I[42] = (T)(img)(_p1##x,_n2##y,_p3##z,c)), \ - (I[50] = (T)(img)(_p1##x,_n3##y,_p3##z,c)), \ - (I[58] = (T)(img)(_p1##x,_n4##y,_p3##z,c)), \ - (I[66] = (T)(img)(_p1##x,_p3##y,_p2##z,c)), \ - (I[74] = (T)(img)(_p1##x,_p2##y,_p2##z,c)), \ - (I[82] = (T)(img)(_p1##x,_p1##y,_p2##z,c)), \ - (I[90] = (T)(img)(_p1##x,y,_p2##z,c)), \ - (I[98] = (T)(img)(_p1##x,_n1##y,_p2##z,c)), \ - (I[106] = (T)(img)(_p1##x,_n2##y,_p2##z,c)), \ - (I[114] = (T)(img)(_p1##x,_n3##y,_p2##z,c)), \ - (I[122] = (T)(img)(_p1##x,_n4##y,_p2##z,c)), \ - (I[130] = (T)(img)(_p1##x,_p3##y,_p1##z,c)), \ - (I[138] = (T)(img)(_p1##x,_p2##y,_p1##z,c)), \ - (I[146] = (T)(img)(_p1##x,_p1##y,_p1##z,c)), \ - (I[154] = (T)(img)(_p1##x,y,_p1##z,c)), \ - (I[162] = (T)(img)(_p1##x,_n1##y,_p1##z,c)), \ - (I[170] = (T)(img)(_p1##x,_n2##y,_p1##z,c)), \ - (I[178] = (T)(img)(_p1##x,_n3##y,_p1##z,c)), \ - (I[186] = (T)(img)(_p1##x,_n4##y,_p1##z,c)), \ - (I[194] = (T)(img)(_p1##x,_p3##y,z,c)), \ - (I[202] = (T)(img)(_p1##x,_p2##y,z,c)), \ - (I[210] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[218] = (T)(img)(_p1##x,y,z,c)), \ - (I[226] = (T)(img)(_p1##x,_n1##y,z,c)), \ - (I[234] = (T)(img)(_p1##x,_n2##y,z,c)), \ - (I[242] = (T)(img)(_p1##x,_n3##y,z,c)), \ - (I[250] = (T)(img)(_p1##x,_n4##y,z,c)), \ - (I[258] = (T)(img)(_p1##x,_p3##y,_n1##z,c)), \ - (I[266] = (T)(img)(_p1##x,_p2##y,_n1##z,c)), \ - (I[274] = (T)(img)(_p1##x,_p1##y,_n1##z,c)), \ - (I[282] = (T)(img)(_p1##x,y,_n1##z,c)), \ - (I[290] = (T)(img)(_p1##x,_n1##y,_n1##z,c)), \ - (I[298] = (T)(img)(_p1##x,_n2##y,_n1##z,c)), \ - (I[306] = (T)(img)(_p1##x,_n3##y,_n1##z,c)), \ - (I[314] = (T)(img)(_p1##x,_n4##y,_n1##z,c)), \ - (I[322] = (T)(img)(_p1##x,_p3##y,_n2##z,c)), \ - (I[330] = (T)(img)(_p1##x,_p2##y,_n2##z,c)), \ - (I[338] = (T)(img)(_p1##x,_p1##y,_n2##z,c)), \ - (I[346] = (T)(img)(_p1##x,y,_n2##z,c)), \ - (I[354] = (T)(img)(_p1##x,_n1##y,_n2##z,c)), \ - (I[362] = (T)(img)(_p1##x,_n2##y,_n2##z,c)), \ - (I[370] = (T)(img)(_p1##x,_n3##y,_n2##z,c)), \ - (I[378] = (T)(img)(_p1##x,_n4##y,_n2##z,c)), \ - (I[386] = (T)(img)(_p1##x,_p3##y,_n3##z,c)), \ - (I[394] = (T)(img)(_p1##x,_p2##y,_n3##z,c)), \ - (I[402] = (T)(img)(_p1##x,_p1##y,_n3##z,c)), \ - (I[410] = (T)(img)(_p1##x,y,_n3##z,c)), \ - (I[418] = (T)(img)(_p1##x,_n1##y,_n3##z,c)), \ - (I[426] = (T)(img)(_p1##x,_n2##y,_n3##z,c)), \ - (I[434] = (T)(img)(_p1##x,_n3##y,_n3##z,c)), \ - (I[442] = (T)(img)(_p1##x,_n4##y,_n3##z,c)), \ - (I[450] = (T)(img)(_p1##x,_p3##y,_n4##z,c)), \ - (I[458] = (T)(img)(_p1##x,_p2##y,_n4##z,c)), \ - (I[466] = (T)(img)(_p1##x,_p1##y,_n4##z,c)), \ - (I[474] = (T)(img)(_p1##x,y,_n4##z,c)), \ - (I[482] = (T)(img)(_p1##x,_n1##y,_n4##z,c)), \ - (I[490] = (T)(img)(_p1##x,_n2##y,_n4##z,c)), \ - (I[498] = (T)(img)(_p1##x,_n3##y,_n4##z,c)), \ - (I[506] = (T)(img)(_p1##x,_n4##y,_n4##z,c)), \ - (I[3] = (T)(img)(x,_p3##y,_p3##z,c)), \ - (I[11] = (T)(img)(x,_p2##y,_p3##z,c)), \ - (I[19] = (T)(img)(x,_p1##y,_p3##z,c)), \ - (I[27] = (T)(img)(x,y,_p3##z,c)), \ - (I[35] = (T)(img)(x,_n1##y,_p3##z,c)), \ - (I[43] = (T)(img)(x,_n2##y,_p3##z,c)), \ - (I[51] = (T)(img)(x,_n3##y,_p3##z,c)), \ - (I[59] = (T)(img)(x,_n4##y,_p3##z,c)), \ - (I[67] = (T)(img)(x,_p3##y,_p2##z,c)), \ - (I[75] = (T)(img)(x,_p2##y,_p2##z,c)), \ - (I[83] = (T)(img)(x,_p1##y,_p2##z,c)), \ - (I[91] = (T)(img)(x,y,_p2##z,c)), \ - (I[99] = (T)(img)(x,_n1##y,_p2##z,c)), \ - (I[107] = (T)(img)(x,_n2##y,_p2##z,c)), \ - (I[115] = (T)(img)(x,_n3##y,_p2##z,c)), \ - (I[123] = (T)(img)(x,_n4##y,_p2##z,c)), \ - (I[131] = (T)(img)(x,_p3##y,_p1##z,c)), \ - (I[139] = (T)(img)(x,_p2##y,_p1##z,c)), \ - (I[147] = (T)(img)(x,_p1##y,_p1##z,c)), \ - (I[155] = (T)(img)(x,y,_p1##z,c)), \ - (I[163] = (T)(img)(x,_n1##y,_p1##z,c)), \ - (I[171] = (T)(img)(x,_n2##y,_p1##z,c)), \ - (I[179] = (T)(img)(x,_n3##y,_p1##z,c)), \ - (I[187] = (T)(img)(x,_n4##y,_p1##z,c)), \ - (I[195] = (T)(img)(x,_p3##y,z,c)), \ - (I[203] = (T)(img)(x,_p2##y,z,c)), \ - (I[211] = (T)(img)(x,_p1##y,z,c)), \ - (I[219] = (T)(img)(x,y,z,c)), \ - (I[227] = (T)(img)(x,_n1##y,z,c)), \ - (I[235] = (T)(img)(x,_n2##y,z,c)), \ - (I[243] = (T)(img)(x,_n3##y,z,c)), \ - (I[251] = (T)(img)(x,_n4##y,z,c)), \ - (I[259] = (T)(img)(x,_p3##y,_n1##z,c)), \ - (I[267] = (T)(img)(x,_p2##y,_n1##z,c)), \ - (I[275] = (T)(img)(x,_p1##y,_n1##z,c)), \ - (I[283] = (T)(img)(x,y,_n1##z,c)), \ - (I[291] = (T)(img)(x,_n1##y,_n1##z,c)), \ - (I[299] = (T)(img)(x,_n2##y,_n1##z,c)), \ - (I[307] = (T)(img)(x,_n3##y,_n1##z,c)), \ - (I[315] = (T)(img)(x,_n4##y,_n1##z,c)), \ - (I[323] = (T)(img)(x,_p3##y,_n2##z,c)), \ - (I[331] = (T)(img)(x,_p2##y,_n2##z,c)), \ - (I[339] = (T)(img)(x,_p1##y,_n2##z,c)), \ - (I[347] = (T)(img)(x,y,_n2##z,c)), \ - (I[355] = (T)(img)(x,_n1##y,_n2##z,c)), \ - (I[363] = (T)(img)(x,_n2##y,_n2##z,c)), \ - (I[371] = (T)(img)(x,_n3##y,_n2##z,c)), \ - (I[379] = (T)(img)(x,_n4##y,_n2##z,c)), \ - (I[387] = (T)(img)(x,_p3##y,_n3##z,c)), \ - (I[395] = (T)(img)(x,_p2##y,_n3##z,c)), \ - (I[403] = (T)(img)(x,_p1##y,_n3##z,c)), \ - (I[411] = (T)(img)(x,y,_n3##z,c)), \ - (I[419] = (T)(img)(x,_n1##y,_n3##z,c)), \ - (I[427] = (T)(img)(x,_n2##y,_n3##z,c)), \ - (I[435] = (T)(img)(x,_n3##y,_n3##z,c)), \ - (I[443] = (T)(img)(x,_n4##y,_n3##z,c)), \ - (I[451] = (T)(img)(x,_p3##y,_n4##z,c)), \ - (I[459] = (T)(img)(x,_p2##y,_n4##z,c)), \ - (I[467] = (T)(img)(x,_p1##y,_n4##z,c)), \ - (I[475] = (T)(img)(x,y,_n4##z,c)), \ - (I[483] = (T)(img)(x,_n1##y,_n4##z,c)), \ - (I[491] = (T)(img)(x,_n2##y,_n4##z,c)), \ - (I[499] = (T)(img)(x,_n3##y,_n4##z,c)), \ - (I[507] = (T)(img)(x,_n4##y,_n4##z,c)), \ - (I[4] = (T)(img)(_n1##x,_p3##y,_p3##z,c)), \ - (I[12] = (T)(img)(_n1##x,_p2##y,_p3##z,c)), \ - (I[20] = (T)(img)(_n1##x,_p1##y,_p3##z,c)), \ - (I[28] = (T)(img)(_n1##x,y,_p3##z,c)), \ - (I[36] = (T)(img)(_n1##x,_n1##y,_p3##z,c)), \ - (I[44] = (T)(img)(_n1##x,_n2##y,_p3##z,c)), \ - (I[52] = (T)(img)(_n1##x,_n3##y,_p3##z,c)), \ - (I[60] = (T)(img)(_n1##x,_n4##y,_p3##z,c)), \ - (I[68] = (T)(img)(_n1##x,_p3##y,_p2##z,c)), \ - (I[76] = (T)(img)(_n1##x,_p2##y,_p2##z,c)), \ - (I[84] = (T)(img)(_n1##x,_p1##y,_p2##z,c)), \ - (I[92] = (T)(img)(_n1##x,y,_p2##z,c)), \ - (I[100] = (T)(img)(_n1##x,_n1##y,_p2##z,c)), \ - (I[108] = (T)(img)(_n1##x,_n2##y,_p2##z,c)), \ - (I[116] = (T)(img)(_n1##x,_n3##y,_p2##z,c)), \ - (I[124] = (T)(img)(_n1##x,_n4##y,_p2##z,c)), \ - (I[132] = (T)(img)(_n1##x,_p3##y,_p1##z,c)), \ - (I[140] = (T)(img)(_n1##x,_p2##y,_p1##z,c)), \ - (I[148] = (T)(img)(_n1##x,_p1##y,_p1##z,c)), \ - (I[156] = (T)(img)(_n1##x,y,_p1##z,c)), \ - (I[164] = (T)(img)(_n1##x,_n1##y,_p1##z,c)), \ - (I[172] = (T)(img)(_n1##x,_n2##y,_p1##z,c)), \ - (I[180] = (T)(img)(_n1##x,_n3##y,_p1##z,c)), \ - (I[188] = (T)(img)(_n1##x,_n4##y,_p1##z,c)), \ - (I[196] = (T)(img)(_n1##x,_p3##y,z,c)), \ - (I[204] = (T)(img)(_n1##x,_p2##y,z,c)), \ - (I[212] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[220] = (T)(img)(_n1##x,y,z,c)), \ - (I[228] = (T)(img)(_n1##x,_n1##y,z,c)), \ - (I[236] = (T)(img)(_n1##x,_n2##y,z,c)), \ - (I[244] = (T)(img)(_n1##x,_n3##y,z,c)), \ - (I[252] = (T)(img)(_n1##x,_n4##y,z,c)), \ - (I[260] = (T)(img)(_n1##x,_p3##y,_n1##z,c)), \ - (I[268] = (T)(img)(_n1##x,_p2##y,_n1##z,c)), \ - (I[276] = (T)(img)(_n1##x,_p1##y,_n1##z,c)), \ - (I[284] = (T)(img)(_n1##x,y,_n1##z,c)), \ - (I[292] = (T)(img)(_n1##x,_n1##y,_n1##z,c)), \ - (I[300] = (T)(img)(_n1##x,_n2##y,_n1##z,c)), \ - (I[308] = (T)(img)(_n1##x,_n3##y,_n1##z,c)), \ - (I[316] = (T)(img)(_n1##x,_n4##y,_n1##z,c)), \ - (I[324] = (T)(img)(_n1##x,_p3##y,_n2##z,c)), \ - (I[332] = (T)(img)(_n1##x,_p2##y,_n2##z,c)), \ - (I[340] = (T)(img)(_n1##x,_p1##y,_n2##z,c)), \ - (I[348] = (T)(img)(_n1##x,y,_n2##z,c)), \ - (I[356] = (T)(img)(_n1##x,_n1##y,_n2##z,c)), \ - (I[364] = (T)(img)(_n1##x,_n2##y,_n2##z,c)), \ - (I[372] = (T)(img)(_n1##x,_n3##y,_n2##z,c)), \ - (I[380] = (T)(img)(_n1##x,_n4##y,_n2##z,c)), \ - (I[388] = (T)(img)(_n1##x,_p3##y,_n3##z,c)), \ - (I[396] = (T)(img)(_n1##x,_p2##y,_n3##z,c)), \ - (I[404] = (T)(img)(_n1##x,_p1##y,_n3##z,c)), \ - (I[412] = (T)(img)(_n1##x,y,_n3##z,c)), \ - (I[420] = (T)(img)(_n1##x,_n1##y,_n3##z,c)), \ - (I[428] = (T)(img)(_n1##x,_n2##y,_n3##z,c)), \ - (I[436] = (T)(img)(_n1##x,_n3##y,_n3##z,c)), \ - (I[444] = (T)(img)(_n1##x,_n4##y,_n3##z,c)), \ - (I[452] = (T)(img)(_n1##x,_p3##y,_n4##z,c)), \ - (I[460] = (T)(img)(_n1##x,_p2##y,_n4##z,c)), \ - (I[468] = (T)(img)(_n1##x,_p1##y,_n4##z,c)), \ - (I[476] = (T)(img)(_n1##x,y,_n4##z,c)), \ - (I[484] = (T)(img)(_n1##x,_n1##y,_n4##z,c)), \ - (I[492] = (T)(img)(_n1##x,_n2##y,_n4##z,c)), \ - (I[500] = (T)(img)(_n1##x,_n3##y,_n4##z,c)), \ - (I[508] = (T)(img)(_n1##x,_n4##y,_n4##z,c)), \ - (I[5] = (T)(img)(_n2##x,_p3##y,_p3##z,c)), \ - (I[13] = (T)(img)(_n2##x,_p2##y,_p3##z,c)), \ - (I[21] = (T)(img)(_n2##x,_p1##y,_p3##z,c)), \ - (I[29] = (T)(img)(_n2##x,y,_p3##z,c)), \ - (I[37] = (T)(img)(_n2##x,_n1##y,_p3##z,c)), \ - (I[45] = (T)(img)(_n2##x,_n2##y,_p3##z,c)), \ - (I[53] = (T)(img)(_n2##x,_n3##y,_p3##z,c)), \ - (I[61] = (T)(img)(_n2##x,_n4##y,_p3##z,c)), \ - (I[69] = (T)(img)(_n2##x,_p3##y,_p2##z,c)), \ - (I[77] = (T)(img)(_n2##x,_p2##y,_p2##z,c)), \ - (I[85] = (T)(img)(_n2##x,_p1##y,_p2##z,c)), \ - (I[93] = (T)(img)(_n2##x,y,_p2##z,c)), \ - (I[101] = (T)(img)(_n2##x,_n1##y,_p2##z,c)), \ - (I[109] = (T)(img)(_n2##x,_n2##y,_p2##z,c)), \ - (I[117] = (T)(img)(_n2##x,_n3##y,_p2##z,c)), \ - (I[125] = (T)(img)(_n2##x,_n4##y,_p2##z,c)), \ - (I[133] = (T)(img)(_n2##x,_p3##y,_p1##z,c)), \ - (I[141] = (T)(img)(_n2##x,_p2##y,_p1##z,c)), \ - (I[149] = (T)(img)(_n2##x,_p1##y,_p1##z,c)), \ - (I[157] = (T)(img)(_n2##x,y,_p1##z,c)), \ - (I[165] = (T)(img)(_n2##x,_n1##y,_p1##z,c)), \ - (I[173] = (T)(img)(_n2##x,_n2##y,_p1##z,c)), \ - (I[181] = (T)(img)(_n2##x,_n3##y,_p1##z,c)), \ - (I[189] = (T)(img)(_n2##x,_n4##y,_p1##z,c)), \ - (I[197] = (T)(img)(_n2##x,_p3##y,z,c)), \ - (I[205] = (T)(img)(_n2##x,_p2##y,z,c)), \ - (I[213] = (T)(img)(_n2##x,_p1##y,z,c)), \ - (I[221] = (T)(img)(_n2##x,y,z,c)), \ - (I[229] = (T)(img)(_n2##x,_n1##y,z,c)), \ - (I[237] = (T)(img)(_n2##x,_n2##y,z,c)), \ - (I[245] = (T)(img)(_n2##x,_n3##y,z,c)), \ - (I[253] = (T)(img)(_n2##x,_n4##y,z,c)), \ - (I[261] = (T)(img)(_n2##x,_p3##y,_n1##z,c)), \ - (I[269] = (T)(img)(_n2##x,_p2##y,_n1##z,c)), \ - (I[277] = (T)(img)(_n2##x,_p1##y,_n1##z,c)), \ - (I[285] = (T)(img)(_n2##x,y,_n1##z,c)), \ - (I[293] = (T)(img)(_n2##x,_n1##y,_n1##z,c)), \ - (I[301] = (T)(img)(_n2##x,_n2##y,_n1##z,c)), \ - (I[309] = (T)(img)(_n2##x,_n3##y,_n1##z,c)), \ - (I[317] = (T)(img)(_n2##x,_n4##y,_n1##z,c)), \ - (I[325] = (T)(img)(_n2##x,_p3##y,_n2##z,c)), \ - (I[333] = (T)(img)(_n2##x,_p2##y,_n2##z,c)), \ - (I[341] = (T)(img)(_n2##x,_p1##y,_n2##z,c)), \ - (I[349] = (T)(img)(_n2##x,y,_n2##z,c)), \ - (I[357] = (T)(img)(_n2##x,_n1##y,_n2##z,c)), \ - (I[365] = (T)(img)(_n2##x,_n2##y,_n2##z,c)), \ - (I[373] = (T)(img)(_n2##x,_n3##y,_n2##z,c)), \ - (I[381] = (T)(img)(_n2##x,_n4##y,_n2##z,c)), \ - (I[389] = (T)(img)(_n2##x,_p3##y,_n3##z,c)), \ - (I[397] = (T)(img)(_n2##x,_p2##y,_n3##z,c)), \ - (I[405] = (T)(img)(_n2##x,_p1##y,_n3##z,c)), \ - (I[413] = (T)(img)(_n2##x,y,_n3##z,c)), \ - (I[421] = (T)(img)(_n2##x,_n1##y,_n3##z,c)), \ - (I[429] = (T)(img)(_n2##x,_n2##y,_n3##z,c)), \ - (I[437] = (T)(img)(_n2##x,_n3##y,_n3##z,c)), \ - (I[445] = (T)(img)(_n2##x,_n4##y,_n3##z,c)), \ - (I[453] = (T)(img)(_n2##x,_p3##y,_n4##z,c)), \ - (I[461] = (T)(img)(_n2##x,_p2##y,_n4##z,c)), \ - (I[469] = (T)(img)(_n2##x,_p1##y,_n4##z,c)), \ - (I[477] = (T)(img)(_n2##x,y,_n4##z,c)), \ - (I[485] = (T)(img)(_n2##x,_n1##y,_n4##z,c)), \ - (I[493] = (T)(img)(_n2##x,_n2##y,_n4##z,c)), \ - (I[501] = (T)(img)(_n2##x,_n3##y,_n4##z,c)), \ - (I[509] = (T)(img)(_n2##x,_n4##y,_n4##z,c)), \ - (I[6] = (T)(img)(_n3##x,_p3##y,_p3##z,c)), \ - (I[14] = (T)(img)(_n3##x,_p2##y,_p3##z,c)), \ - (I[22] = (T)(img)(_n3##x,_p1##y,_p3##z,c)), \ - (I[30] = (T)(img)(_n3##x,y,_p3##z,c)), \ - (I[38] = (T)(img)(_n3##x,_n1##y,_p3##z,c)), \ - (I[46] = (T)(img)(_n3##x,_n2##y,_p3##z,c)), \ - (I[54] = (T)(img)(_n3##x,_n3##y,_p3##z,c)), \ - (I[62] = (T)(img)(_n3##x,_n4##y,_p3##z,c)), \ - (I[70] = (T)(img)(_n3##x,_p3##y,_p2##z,c)), \ - (I[78] = (T)(img)(_n3##x,_p2##y,_p2##z,c)), \ - (I[86] = (T)(img)(_n3##x,_p1##y,_p2##z,c)), \ - (I[94] = (T)(img)(_n3##x,y,_p2##z,c)), \ - (I[102] = (T)(img)(_n3##x,_n1##y,_p2##z,c)), \ - (I[110] = (T)(img)(_n3##x,_n2##y,_p2##z,c)), \ - (I[118] = (T)(img)(_n3##x,_n3##y,_p2##z,c)), \ - (I[126] = (T)(img)(_n3##x,_n4##y,_p2##z,c)), \ - (I[134] = (T)(img)(_n3##x,_p3##y,_p1##z,c)), \ - (I[142] = (T)(img)(_n3##x,_p2##y,_p1##z,c)), \ - (I[150] = (T)(img)(_n3##x,_p1##y,_p1##z,c)), \ - (I[158] = (T)(img)(_n3##x,y,_p1##z,c)), \ - (I[166] = (T)(img)(_n3##x,_n1##y,_p1##z,c)), \ - (I[174] = (T)(img)(_n3##x,_n2##y,_p1##z,c)), \ - (I[182] = (T)(img)(_n3##x,_n3##y,_p1##z,c)), \ - (I[190] = (T)(img)(_n3##x,_n4##y,_p1##z,c)), \ - (I[198] = (T)(img)(_n3##x,_p3##y,z,c)), \ - (I[206] = (T)(img)(_n3##x,_p2##y,z,c)), \ - (I[214] = (T)(img)(_n3##x,_p1##y,z,c)), \ - (I[222] = (T)(img)(_n3##x,y,z,c)), \ - (I[230] = (T)(img)(_n3##x,_n1##y,z,c)), \ - (I[238] = (T)(img)(_n3##x,_n2##y,z,c)), \ - (I[246] = (T)(img)(_n3##x,_n3##y,z,c)), \ - (I[254] = (T)(img)(_n3##x,_n4##y,z,c)), \ - (I[262] = (T)(img)(_n3##x,_p3##y,_n1##z,c)), \ - (I[270] = (T)(img)(_n3##x,_p2##y,_n1##z,c)), \ - (I[278] = (T)(img)(_n3##x,_p1##y,_n1##z,c)), \ - (I[286] = (T)(img)(_n3##x,y,_n1##z,c)), \ - (I[294] = (T)(img)(_n3##x,_n1##y,_n1##z,c)), \ - (I[302] = (T)(img)(_n3##x,_n2##y,_n1##z,c)), \ - (I[310] = (T)(img)(_n3##x,_n3##y,_n1##z,c)), \ - (I[318] = (T)(img)(_n3##x,_n4##y,_n1##z,c)), \ - (I[326] = (T)(img)(_n3##x,_p3##y,_n2##z,c)), \ - (I[334] = (T)(img)(_n3##x,_p2##y,_n2##z,c)), \ - (I[342] = (T)(img)(_n3##x,_p1##y,_n2##z,c)), \ - (I[350] = (T)(img)(_n3##x,y,_n2##z,c)), \ - (I[358] = (T)(img)(_n3##x,_n1##y,_n2##z,c)), \ - (I[366] = (T)(img)(_n3##x,_n2##y,_n2##z,c)), \ - (I[374] = (T)(img)(_n3##x,_n3##y,_n2##z,c)), \ - (I[382] = (T)(img)(_n3##x,_n4##y,_n2##z,c)), \ - (I[390] = (T)(img)(_n3##x,_p3##y,_n3##z,c)), \ - (I[398] = (T)(img)(_n3##x,_p2##y,_n3##z,c)), \ - (I[406] = (T)(img)(_n3##x,_p1##y,_n3##z,c)), \ - (I[414] = (T)(img)(_n3##x,y,_n3##z,c)), \ - (I[422] = (T)(img)(_n3##x,_n1##y,_n3##z,c)), \ - (I[430] = (T)(img)(_n3##x,_n2##y,_n3##z,c)), \ - (I[438] = (T)(img)(_n3##x,_n3##y,_n3##z,c)), \ - (I[446] = (T)(img)(_n3##x,_n4##y,_n3##z,c)), \ - (I[454] = (T)(img)(_n3##x,_p3##y,_n4##z,c)), \ - (I[462] = (T)(img)(_n3##x,_p2##y,_n4##z,c)), \ - (I[470] = (T)(img)(_n3##x,_p1##y,_n4##z,c)), \ - (I[478] = (T)(img)(_n3##x,y,_n4##z,c)), \ - (I[486] = (T)(img)(_n3##x,_n1##y,_n4##z,c)), \ - (I[494] = (T)(img)(_n3##x,_n2##y,_n4##z,c)), \ - (I[502] = (T)(img)(_n3##x,_n3##y,_n4##z,c)), \ - (I[510] = (T)(img)(_n3##x,_n4##y,_n4##z,c)), \ - x + 4>=(img).width()?(img).width() - 1:x + 4); \ - x<=(int)(x1) && ((_n4##x<(img).width() && ( \ - (I[7] = (T)(img)(_n4##x,_p3##y,_p3##z,c)), \ - (I[15] = (T)(img)(_n4##x,_p2##y,_p3##z,c)), \ - (I[23] = (T)(img)(_n4##x,_p1##y,_p3##z,c)), \ - (I[31] = (T)(img)(_n4##x,y,_p3##z,c)), \ - (I[39] = (T)(img)(_n4##x,_n1##y,_p3##z,c)), \ - (I[47] = (T)(img)(_n4##x,_n2##y,_p3##z,c)), \ - (I[55] = (T)(img)(_n4##x,_n3##y,_p3##z,c)), \ - (I[63] = (T)(img)(_n4##x,_n4##y,_p3##z,c)), \ - (I[71] = (T)(img)(_n4##x,_p3##y,_p2##z,c)), \ - (I[79] = (T)(img)(_n4##x,_p2##y,_p2##z,c)), \ - (I[87] = (T)(img)(_n4##x,_p1##y,_p2##z,c)), \ - (I[95] = (T)(img)(_n4##x,y,_p2##z,c)), \ - (I[103] = (T)(img)(_n4##x,_n1##y,_p2##z,c)), \ - (I[111] = (T)(img)(_n4##x,_n2##y,_p2##z,c)), \ - (I[119] = (T)(img)(_n4##x,_n3##y,_p2##z,c)), \ - (I[127] = (T)(img)(_n4##x,_n4##y,_p2##z,c)), \ - (I[135] = (T)(img)(_n4##x,_p3##y,_p1##z,c)), \ - (I[143] = (T)(img)(_n4##x,_p2##y,_p1##z,c)), \ - (I[151] = (T)(img)(_n4##x,_p1##y,_p1##z,c)), \ - (I[159] = (T)(img)(_n4##x,y,_p1##z,c)), \ - (I[167] = (T)(img)(_n4##x,_n1##y,_p1##z,c)), \ - (I[175] = (T)(img)(_n4##x,_n2##y,_p1##z,c)), \ - (I[183] = (T)(img)(_n4##x,_n3##y,_p1##z,c)), \ - (I[191] = (T)(img)(_n4##x,_n4##y,_p1##z,c)), \ - (I[199] = (T)(img)(_n4##x,_p3##y,z,c)), \ - (I[207] = (T)(img)(_n4##x,_p2##y,z,c)), \ - (I[215] = (T)(img)(_n4##x,_p1##y,z,c)), \ - (I[223] = (T)(img)(_n4##x,y,z,c)), \ - (I[231] = (T)(img)(_n4##x,_n1##y,z,c)), \ - (I[239] = (T)(img)(_n4##x,_n2##y,z,c)), \ - (I[247] = (T)(img)(_n4##x,_n3##y,z,c)), \ - (I[255] = (T)(img)(_n4##x,_n4##y,z,c)), \ - (I[263] = (T)(img)(_n4##x,_p3##y,_n1##z,c)), \ - (I[271] = (T)(img)(_n4##x,_p2##y,_n1##z,c)), \ - (I[279] = (T)(img)(_n4##x,_p1##y,_n1##z,c)), \ - (I[287] = (T)(img)(_n4##x,y,_n1##z,c)), \ - (I[295] = (T)(img)(_n4##x,_n1##y,_n1##z,c)), \ - (I[303] = (T)(img)(_n4##x,_n2##y,_n1##z,c)), \ - (I[311] = (T)(img)(_n4##x,_n3##y,_n1##z,c)), \ - (I[319] = (T)(img)(_n4##x,_n4##y,_n1##z,c)), \ - (I[327] = (T)(img)(_n4##x,_p3##y,_n2##z,c)), \ - (I[335] = (T)(img)(_n4##x,_p2##y,_n2##z,c)), \ - (I[343] = (T)(img)(_n4##x,_p1##y,_n2##z,c)), \ - (I[351] = (T)(img)(_n4##x,y,_n2##z,c)), \ - (I[359] = (T)(img)(_n4##x,_n1##y,_n2##z,c)), \ - (I[367] = (T)(img)(_n4##x,_n2##y,_n2##z,c)), \ - (I[375] = (T)(img)(_n4##x,_n3##y,_n2##z,c)), \ - (I[383] = (T)(img)(_n4##x,_n4##y,_n2##z,c)), \ - (I[391] = (T)(img)(_n4##x,_p3##y,_n3##z,c)), \ - (I[399] = (T)(img)(_n4##x,_p2##y,_n3##z,c)), \ - (I[407] = (T)(img)(_n4##x,_p1##y,_n3##z,c)), \ - (I[415] = (T)(img)(_n4##x,y,_n3##z,c)), \ - (I[423] = (T)(img)(_n4##x,_n1##y,_n3##z,c)), \ - (I[431] = (T)(img)(_n4##x,_n2##y,_n3##z,c)), \ - (I[439] = (T)(img)(_n4##x,_n3##y,_n3##z,c)), \ - (I[447] = (T)(img)(_n4##x,_n4##y,_n3##z,c)), \ - (I[455] = (T)(img)(_n4##x,_p3##y,_n4##z,c)), \ - (I[463] = (T)(img)(_n4##x,_p2##y,_n4##z,c)), \ - (I[471] = (T)(img)(_n4##x,_p1##y,_n4##z,c)), \ - (I[479] = (T)(img)(_n4##x,y,_n4##z,c)), \ - (I[487] = (T)(img)(_n4##x,_n1##y,_n4##z,c)), \ - (I[495] = (T)(img)(_n4##x,_n2##y,_n4##z,c)), \ - (I[503] = (T)(img)(_n4##x,_n3##y,_n4##z,c)), \ - (I[511] = (T)(img)(_n4##x,_n4##y,_n4##z,c)),1)) || \ - _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n4##x = _n3##x = _n2##x = --_n1##x)); \ - I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], \ - I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], \ - I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \ - I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], \ - I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], \ - I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], \ - I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], \ - I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], \ - I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], \ - I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], \ - I[80] = I[81], I[81] = I[82], I[82] = I[83], I[83] = I[84], I[84] = I[85], I[85] = I[86], I[86] = I[87], \ - I[88] = I[89], I[89] = I[90], I[90] = I[91], I[91] = I[92], I[92] = I[93], I[93] = I[94], I[94] = I[95], \ - I[96] = I[97], I[97] = I[98], I[98] = I[99], I[99] = I[100], I[100] = I[101], I[101] = I[102], I[102] = I[103], \ - I[104] = I[105], I[105] = I[106], I[106] = I[107], I[107] = I[108], I[108] = I[109], I[109] = I[110], I[110] = I[111], \ - I[112] = I[113], I[113] = I[114], I[114] = I[115], I[115] = I[116], I[116] = I[117], I[117] = I[118], I[118] = I[119], \ - I[120] = I[121], I[121] = I[122], I[122] = I[123], I[123] = I[124], I[124] = I[125], I[125] = I[126], I[126] = I[127], \ - I[128] = I[129], I[129] = I[130], I[130] = I[131], I[131] = I[132], I[132] = I[133], I[133] = I[134], I[134] = I[135], \ - I[136] = I[137], I[137] = I[138], I[138] = I[139], I[139] = I[140], I[140] = I[141], I[141] = I[142], I[142] = I[143], \ - I[144] = I[145], I[145] = I[146], I[146] = I[147], I[147] = I[148], I[148] = I[149], I[149] = I[150], I[150] = I[151], \ - I[152] = I[153], I[153] = I[154], I[154] = I[155], I[155] = I[156], I[156] = I[157], I[157] = I[158], I[158] = I[159], \ - I[160] = I[161], I[161] = I[162], I[162] = I[163], I[163] = I[164], I[164] = I[165], I[165] = I[166], I[166] = I[167], \ - I[168] = I[169], I[169] = I[170], I[170] = I[171], I[171] = I[172], I[172] = I[173], I[173] = I[174], I[174] = I[175], \ - I[176] = I[177], I[177] = I[178], I[178] = I[179], I[179] = I[180], I[180] = I[181], I[181] = I[182], I[182] = I[183], \ - I[184] = I[185], I[185] = I[186], I[186] = I[187], I[187] = I[188], I[188] = I[189], I[189] = I[190], I[190] = I[191], \ - I[192] = I[193], I[193] = I[194], I[194] = I[195], I[195] = I[196], I[196] = I[197], I[197] = I[198], I[198] = I[199], \ - I[200] = I[201], I[201] = I[202], I[202] = I[203], I[203] = I[204], I[204] = I[205], I[205] = I[206], I[206] = I[207], \ - I[208] = I[209], I[209] = I[210], I[210] = I[211], I[211] = I[212], I[212] = I[213], I[213] = I[214], I[214] = I[215], \ - I[216] = I[217], I[217] = I[218], I[218] = I[219], I[219] = I[220], I[220] = I[221], I[221] = I[222], I[222] = I[223], \ - I[224] = I[225], I[225] = I[226], I[226] = I[227], I[227] = I[228], I[228] = I[229], I[229] = I[230], I[230] = I[231], \ - I[232] = I[233], I[233] = I[234], I[234] = I[235], I[235] = I[236], I[236] = I[237], I[237] = I[238], I[238] = I[239], \ - I[240] = I[241], I[241] = I[242], I[242] = I[243], I[243] = I[244], I[244] = I[245], I[245] = I[246], I[246] = I[247], \ - I[248] = I[249], I[249] = I[250], I[250] = I[251], I[251] = I[252], I[252] = I[253], I[253] = I[254], I[254] = I[255], \ - I[256] = I[257], I[257] = I[258], I[258] = I[259], I[259] = I[260], I[260] = I[261], I[261] = I[262], I[262] = I[263], \ - I[264] = I[265], I[265] = I[266], I[266] = I[267], I[267] = I[268], I[268] = I[269], I[269] = I[270], I[270] = I[271], \ - I[272] = I[273], I[273] = I[274], I[274] = I[275], I[275] = I[276], I[276] = I[277], I[277] = I[278], I[278] = I[279], \ - I[280] = I[281], I[281] = I[282], I[282] = I[283], I[283] = I[284], I[284] = I[285], I[285] = I[286], I[286] = I[287], \ - I[288] = I[289], I[289] = I[290], I[290] = I[291], I[291] = I[292], I[292] = I[293], I[293] = I[294], I[294] = I[295], \ - I[296] = I[297], I[297] = I[298], I[298] = I[299], I[299] = I[300], I[300] = I[301], I[301] = I[302], I[302] = I[303], \ - I[304] = I[305], I[305] = I[306], I[306] = I[307], I[307] = I[308], I[308] = I[309], I[309] = I[310], I[310] = I[311], \ - I[312] = I[313], I[313] = I[314], I[314] = I[315], I[315] = I[316], I[316] = I[317], I[317] = I[318], I[318] = I[319], \ - I[320] = I[321], I[321] = I[322], I[322] = I[323], I[323] = I[324], I[324] = I[325], I[325] = I[326], I[326] = I[327], \ - I[328] = I[329], I[329] = I[330], I[330] = I[331], I[331] = I[332], I[332] = I[333], I[333] = I[334], I[334] = I[335], \ - I[336] = I[337], I[337] = I[338], I[338] = I[339], I[339] = I[340], I[340] = I[341], I[341] = I[342], I[342] = I[343], \ - I[344] = I[345], I[345] = I[346], I[346] = I[347], I[347] = I[348], I[348] = I[349], I[349] = I[350], I[350] = I[351], \ - I[352] = I[353], I[353] = I[354], I[354] = I[355], I[355] = I[356], I[356] = I[357], I[357] = I[358], I[358] = I[359], \ - I[360] = I[361], I[361] = I[362], I[362] = I[363], I[363] = I[364], I[364] = I[365], I[365] = I[366], I[366] = I[367], \ - I[368] = I[369], I[369] = I[370], I[370] = I[371], I[371] = I[372], I[372] = I[373], I[373] = I[374], I[374] = I[375], \ - I[376] = I[377], I[377] = I[378], I[378] = I[379], I[379] = I[380], I[380] = I[381], I[381] = I[382], I[382] = I[383], \ - I[384] = I[385], I[385] = I[386], I[386] = I[387], I[387] = I[388], I[388] = I[389], I[389] = I[390], I[390] = I[391], \ - I[392] = I[393], I[393] = I[394], I[394] = I[395], I[395] = I[396], I[396] = I[397], I[397] = I[398], I[398] = I[399], \ - I[400] = I[401], I[401] = I[402], I[402] = I[403], I[403] = I[404], I[404] = I[405], I[405] = I[406], I[406] = I[407], \ - I[408] = I[409], I[409] = I[410], I[410] = I[411], I[411] = I[412], I[412] = I[413], I[413] = I[414], I[414] = I[415], \ - I[416] = I[417], I[417] = I[418], I[418] = I[419], I[419] = I[420], I[420] = I[421], I[421] = I[422], I[422] = I[423], \ - I[424] = I[425], I[425] = I[426], I[426] = I[427], I[427] = I[428], I[428] = I[429], I[429] = I[430], I[430] = I[431], \ - I[432] = I[433], I[433] = I[434], I[434] = I[435], I[435] = I[436], I[436] = I[437], I[437] = I[438], I[438] = I[439], \ - I[440] = I[441], I[441] = I[442], I[442] = I[443], I[443] = I[444], I[444] = I[445], I[445] = I[446], I[446] = I[447], \ - I[448] = I[449], I[449] = I[450], I[450] = I[451], I[451] = I[452], I[452] = I[453], I[453] = I[454], I[454] = I[455], \ - I[456] = I[457], I[457] = I[458], I[458] = I[459], I[459] = I[460], I[460] = I[461], I[461] = I[462], I[462] = I[463], \ - I[464] = I[465], I[465] = I[466], I[466] = I[467], I[467] = I[468], I[468] = I[469], I[469] = I[470], I[470] = I[471], \ - I[472] = I[473], I[473] = I[474], I[474] = I[475], I[475] = I[476], I[476] = I[477], I[477] = I[478], I[478] = I[479], \ - I[480] = I[481], I[481] = I[482], I[482] = I[483], I[483] = I[484], I[484] = I[485], I[485] = I[486], I[486] = I[487], \ - I[488] = I[489], I[489] = I[490], I[490] = I[491], I[491] = I[492], I[492] = I[493], I[493] = I[494], I[494] = I[495], \ - I[496] = I[497], I[497] = I[498], I[498] = I[499], I[499] = I[500], I[500] = I[501], I[501] = I[502], I[502] = I[503], \ - I[504] = I[505], I[505] = I[506], I[506] = I[507], I[507] = I[508], I[508] = I[509], I[509] = I[510], I[510] = I[511], \ - _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x) - -#define cimg_get8x8x8(img,x,y,z,c,I,T) \ - I[0] = (T)(img)(_p3##x,_p3##y,_p3##z,c), I[1] = (T)(img)(_p2##x,_p3##y,_p3##z,c), I[2] = (T)(img)(_p1##x,_p3##y,_p3##z,c), I[3] = (T)(img)(x,_p3##y,_p3##z,c), I[4] = (T)(img)(_n1##x,_p3##y,_p3##z,c), I[5] = (T)(img)(_n2##x,_p3##y,_p3##z,c), I[6] = (T)(img)(_n3##x,_p3##y,_p3##z,c), I[7] = (T)(img)(_n4##x,_p3##y,_p3##z,c), \ - I[8] = (T)(img)(_p3##x,_p2##y,_p3##z,c), I[9] = (T)(img)(_p2##x,_p2##y,_p3##z,c), I[10] = (T)(img)(_p1##x,_p2##y,_p3##z,c), I[11] = (T)(img)(x,_p2##y,_p3##z,c), I[12] = (T)(img)(_n1##x,_p2##y,_p3##z,c), I[13] = (T)(img)(_n2##x,_p2##y,_p3##z,c), I[14] = (T)(img)(_n3##x,_p2##y,_p3##z,c), I[15] = (T)(img)(_n4##x,_p2##y,_p3##z,c), \ - I[16] = (T)(img)(_p3##x,_p1##y,_p3##z,c), I[17] = (T)(img)(_p2##x,_p1##y,_p3##z,c), I[18] = (T)(img)(_p1##x,_p1##y,_p3##z,c), I[19] = (T)(img)(x,_p1##y,_p3##z,c), I[20] = (T)(img)(_n1##x,_p1##y,_p3##z,c), I[21] = (T)(img)(_n2##x,_p1##y,_p3##z,c), I[22] = (T)(img)(_n3##x,_p1##y,_p3##z,c), I[23] = (T)(img)(_n4##x,_p1##y,_p3##z,c), \ - I[24] = (T)(img)(_p3##x,y,_p3##z,c), I[25] = (T)(img)(_p2##x,y,_p3##z,c), I[26] = (T)(img)(_p1##x,y,_p3##z,c), I[27] = (T)(img)(x,y,_p3##z,c), I[28] = (T)(img)(_n1##x,y,_p3##z,c), I[29] = (T)(img)(_n2##x,y,_p3##z,c), I[30] = (T)(img)(_n3##x,y,_p3##z,c), I[31] = (T)(img)(_n4##x,y,_p3##z,c), \ - I[32] = (T)(img)(_p3##x,_n1##y,_p3##z,c), I[33] = (T)(img)(_p2##x,_n1##y,_p3##z,c), I[34] = (T)(img)(_p1##x,_n1##y,_p3##z,c), I[35] = (T)(img)(x,_n1##y,_p3##z,c), I[36] = (T)(img)(_n1##x,_n1##y,_p3##z,c), I[37] = (T)(img)(_n2##x,_n1##y,_p3##z,c), I[38] = (T)(img)(_n3##x,_n1##y,_p3##z,c), I[39] = (T)(img)(_n4##x,_n1##y,_p3##z,c), \ - I[40] = (T)(img)(_p3##x,_n2##y,_p3##z,c), I[41] = (T)(img)(_p2##x,_n2##y,_p3##z,c), I[42] = (T)(img)(_p1##x,_n2##y,_p3##z,c), I[43] = (T)(img)(x,_n2##y,_p3##z,c), I[44] = (T)(img)(_n1##x,_n2##y,_p3##z,c), I[45] = (T)(img)(_n2##x,_n2##y,_p3##z,c), I[46] = (T)(img)(_n3##x,_n2##y,_p3##z,c), I[47] = (T)(img)(_n4##x,_n2##y,_p3##z,c), \ - I[48] = (T)(img)(_p3##x,_n3##y,_p3##z,c), I[49] = (T)(img)(_p2##x,_n3##y,_p3##z,c), I[50] = (T)(img)(_p1##x,_n3##y,_p3##z,c), I[51] = (T)(img)(x,_n3##y,_p3##z,c), I[52] = (T)(img)(_n1##x,_n3##y,_p3##z,c), I[53] = (T)(img)(_n2##x,_n3##y,_p3##z,c), I[54] = (T)(img)(_n3##x,_n3##y,_p3##z,c), I[55] = (T)(img)(_n4##x,_n3##y,_p3##z,c), \ - I[56] = (T)(img)(_p3##x,_n4##y,_p3##z,c), I[57] = (T)(img)(_p2##x,_n4##y,_p3##z,c), I[58] = (T)(img)(_p1##x,_n4##y,_p3##z,c), I[59] = (T)(img)(x,_n4##y,_p3##z,c), I[60] = (T)(img)(_n1##x,_n4##y,_p3##z,c), I[61] = (T)(img)(_n2##x,_n4##y,_p3##z,c), I[62] = (T)(img)(_n3##x,_n4##y,_p3##z,c), I[63] = (T)(img)(_n4##x,_n4##y,_p3##z,c), \ - I[64] = (T)(img)(_p3##x,_p3##y,_p2##z,c), I[65] = (T)(img)(_p2##x,_p3##y,_p2##z,c), I[66] = (T)(img)(_p1##x,_p3##y,_p2##z,c), I[67] = (T)(img)(x,_p3##y,_p2##z,c), I[68] = (T)(img)(_n1##x,_p3##y,_p2##z,c), I[69] = (T)(img)(_n2##x,_p3##y,_p2##z,c), I[70] = (T)(img)(_n3##x,_p3##y,_p2##z,c), I[71] = (T)(img)(_n4##x,_p3##y,_p2##z,c), \ - I[72] = (T)(img)(_p3##x,_p2##y,_p2##z,c), I[73] = (T)(img)(_p2##x,_p2##y,_p2##z,c), I[74] = (T)(img)(_p1##x,_p2##y,_p2##z,c), I[75] = (T)(img)(x,_p2##y,_p2##z,c), I[76] = (T)(img)(_n1##x,_p2##y,_p2##z,c), I[77] = (T)(img)(_n2##x,_p2##y,_p2##z,c), I[78] = (T)(img)(_n3##x,_p2##y,_p2##z,c), I[79] = (T)(img)(_n4##x,_p2##y,_p2##z,c), \ - I[80] = (T)(img)(_p3##x,_p1##y,_p2##z,c), I[81] = (T)(img)(_p2##x,_p1##y,_p2##z,c), I[82] = (T)(img)(_p1##x,_p1##y,_p2##z,c), I[83] = (T)(img)(x,_p1##y,_p2##z,c), I[84] = (T)(img)(_n1##x,_p1##y,_p2##z,c), I[85] = (T)(img)(_n2##x,_p1##y,_p2##z,c), I[86] = (T)(img)(_n3##x,_p1##y,_p2##z,c), I[87] = (T)(img)(_n4##x,_p1##y,_p2##z,c), \ - I[88] = (T)(img)(_p3##x,y,_p2##z,c), I[89] = (T)(img)(_p2##x,y,_p2##z,c), I[90] = (T)(img)(_p1##x,y,_p2##z,c), I[91] = (T)(img)(x,y,_p2##z,c), I[92] = (T)(img)(_n1##x,y,_p2##z,c), I[93] = (T)(img)(_n2##x,y,_p2##z,c), I[94] = (T)(img)(_n3##x,y,_p2##z,c), I[95] = (T)(img)(_n4##x,y,_p2##z,c), \ - I[96] = (T)(img)(_p3##x,_n1##y,_p2##z,c), I[97] = (T)(img)(_p2##x,_n1##y,_p2##z,c), I[98] = (T)(img)(_p1##x,_n1##y,_p2##z,c), I[99] = (T)(img)(x,_n1##y,_p2##z,c), I[100] = (T)(img)(_n1##x,_n1##y,_p2##z,c), I[101] = (T)(img)(_n2##x,_n1##y,_p2##z,c), I[102] = (T)(img)(_n3##x,_n1##y,_p2##z,c), I[103] = (T)(img)(_n4##x,_n1##y,_p2##z,c), \ - I[104] = (T)(img)(_p3##x,_n2##y,_p2##z,c), I[105] = (T)(img)(_p2##x,_n2##y,_p2##z,c), I[106] = (T)(img)(_p1##x,_n2##y,_p2##z,c), I[107] = (T)(img)(x,_n2##y,_p2##z,c), I[108] = (T)(img)(_n1##x,_n2##y,_p2##z,c), I[109] = (T)(img)(_n2##x,_n2##y,_p2##z,c), I[110] = (T)(img)(_n3##x,_n2##y,_p2##z,c), I[111] = (T)(img)(_n4##x,_n2##y,_p2##z,c), \ - I[112] = (T)(img)(_p3##x,_n3##y,_p2##z,c), I[113] = (T)(img)(_p2##x,_n3##y,_p2##z,c), I[114] = (T)(img)(_p1##x,_n3##y,_p2##z,c), I[115] = (T)(img)(x,_n3##y,_p2##z,c), I[116] = (T)(img)(_n1##x,_n3##y,_p2##z,c), I[117] = (T)(img)(_n2##x,_n3##y,_p2##z,c), I[118] = (T)(img)(_n3##x,_n3##y,_p2##z,c), I[119] = (T)(img)(_n4##x,_n3##y,_p2##z,c), \ - I[120] = (T)(img)(_p3##x,_n4##y,_p2##z,c), I[121] = (T)(img)(_p2##x,_n4##y,_p2##z,c), I[122] = (T)(img)(_p1##x,_n4##y,_p2##z,c), I[123] = (T)(img)(x,_n4##y,_p2##z,c), I[124] = (T)(img)(_n1##x,_n4##y,_p2##z,c), I[125] = (T)(img)(_n2##x,_n4##y,_p2##z,c), I[126] = (T)(img)(_n3##x,_n4##y,_p2##z,c), I[127] = (T)(img)(_n4##x,_n4##y,_p2##z,c), \ - I[128] = (T)(img)(_p3##x,_p3##y,_p1##z,c), I[129] = (T)(img)(_p2##x,_p3##y,_p1##z,c), I[130] = (T)(img)(_p1##x,_p3##y,_p1##z,c), I[131] = (T)(img)(x,_p3##y,_p1##z,c), I[132] = (T)(img)(_n1##x,_p3##y,_p1##z,c), I[133] = (T)(img)(_n2##x,_p3##y,_p1##z,c), I[134] = (T)(img)(_n3##x,_p3##y,_p1##z,c), I[135] = (T)(img)(_n4##x,_p3##y,_p1##z,c), \ - I[136] = (T)(img)(_p3##x,_p2##y,_p1##z,c), I[137] = (T)(img)(_p2##x,_p2##y,_p1##z,c), I[138] = (T)(img)(_p1##x,_p2##y,_p1##z,c), I[139] = (T)(img)(x,_p2##y,_p1##z,c), I[140] = (T)(img)(_n1##x,_p2##y,_p1##z,c), I[141] = (T)(img)(_n2##x,_p2##y,_p1##z,c), I[142] = (T)(img)(_n3##x,_p2##y,_p1##z,c), I[143] = (T)(img)(_n4##x,_p2##y,_p1##z,c), \ - I[144] = (T)(img)(_p3##x,_p1##y,_p1##z,c), I[145] = (T)(img)(_p2##x,_p1##y,_p1##z,c), I[146] = (T)(img)(_p1##x,_p1##y,_p1##z,c), I[147] = (T)(img)(x,_p1##y,_p1##z,c), I[148] = (T)(img)(_n1##x,_p1##y,_p1##z,c), I[149] = (T)(img)(_n2##x,_p1##y,_p1##z,c), I[150] = (T)(img)(_n3##x,_p1##y,_p1##z,c), I[151] = (T)(img)(_n4##x,_p1##y,_p1##z,c), \ - I[152] = (T)(img)(_p3##x,y,_p1##z,c), I[153] = (T)(img)(_p2##x,y,_p1##z,c), I[154] = (T)(img)(_p1##x,y,_p1##z,c), I[155] = (T)(img)(x,y,_p1##z,c), I[156] = (T)(img)(_n1##x,y,_p1##z,c), I[157] = (T)(img)(_n2##x,y,_p1##z,c), I[158] = (T)(img)(_n3##x,y,_p1##z,c), I[159] = (T)(img)(_n4##x,y,_p1##z,c), \ - I[160] = (T)(img)(_p3##x,_n1##y,_p1##z,c), I[161] = (T)(img)(_p2##x,_n1##y,_p1##z,c), I[162] = (T)(img)(_p1##x,_n1##y,_p1##z,c), I[163] = (T)(img)(x,_n1##y,_p1##z,c), I[164] = (T)(img)(_n1##x,_n1##y,_p1##z,c), I[165] = (T)(img)(_n2##x,_n1##y,_p1##z,c), I[166] = (T)(img)(_n3##x,_n1##y,_p1##z,c), I[167] = (T)(img)(_n4##x,_n1##y,_p1##z,c), \ - I[168] = (T)(img)(_p3##x,_n2##y,_p1##z,c), I[169] = (T)(img)(_p2##x,_n2##y,_p1##z,c), I[170] = (T)(img)(_p1##x,_n2##y,_p1##z,c), I[171] = (T)(img)(x,_n2##y,_p1##z,c), I[172] = (T)(img)(_n1##x,_n2##y,_p1##z,c), I[173] = (T)(img)(_n2##x,_n2##y,_p1##z,c), I[174] = (T)(img)(_n3##x,_n2##y,_p1##z,c), I[175] = (T)(img)(_n4##x,_n2##y,_p1##z,c), \ - I[176] = (T)(img)(_p3##x,_n3##y,_p1##z,c), I[177] = (T)(img)(_p2##x,_n3##y,_p1##z,c), I[178] = (T)(img)(_p1##x,_n3##y,_p1##z,c), I[179] = (T)(img)(x,_n3##y,_p1##z,c), I[180] = (T)(img)(_n1##x,_n3##y,_p1##z,c), I[181] = (T)(img)(_n2##x,_n3##y,_p1##z,c), I[182] = (T)(img)(_n3##x,_n3##y,_p1##z,c), I[183] = (T)(img)(_n4##x,_n3##y,_p1##z,c), \ - I[184] = (T)(img)(_p3##x,_n4##y,_p1##z,c), I[185] = (T)(img)(_p2##x,_n4##y,_p1##z,c), I[186] = (T)(img)(_p1##x,_n4##y,_p1##z,c), I[187] = (T)(img)(x,_n4##y,_p1##z,c), I[188] = (T)(img)(_n1##x,_n4##y,_p1##z,c), I[189] = (T)(img)(_n2##x,_n4##y,_p1##z,c), I[190] = (T)(img)(_n3##x,_n4##y,_p1##z,c), I[191] = (T)(img)(_n4##x,_n4##y,_p1##z,c), \ - I[192] = (T)(img)(_p3##x,_p3##y,z,c), I[193] = (T)(img)(_p2##x,_p3##y,z,c), I[194] = (T)(img)(_p1##x,_p3##y,z,c), I[195] = (T)(img)(x,_p3##y,z,c), I[196] = (T)(img)(_n1##x,_p3##y,z,c), I[197] = (T)(img)(_n2##x,_p3##y,z,c), I[198] = (T)(img)(_n3##x,_p3##y,z,c), I[199] = (T)(img)(_n4##x,_p3##y,z,c), \ - I[200] = (T)(img)(_p3##x,_p2##y,z,c), I[201] = (T)(img)(_p2##x,_p2##y,z,c), I[202] = (T)(img)(_p1##x,_p2##y,z,c), I[203] = (T)(img)(x,_p2##y,z,c), I[204] = (T)(img)(_n1##x,_p2##y,z,c), I[205] = (T)(img)(_n2##x,_p2##y,z,c), I[206] = (T)(img)(_n3##x,_p2##y,z,c), I[207] = (T)(img)(_n4##x,_p2##y,z,c), \ - I[208] = (T)(img)(_p3##x,_p1##y,z,c), I[209] = (T)(img)(_p2##x,_p1##y,z,c), I[210] = (T)(img)(_p1##x,_p1##y,z,c), I[211] = (T)(img)(x,_p1##y,z,c), I[212] = (T)(img)(_n1##x,_p1##y,z,c), I[213] = (T)(img)(_n2##x,_p1##y,z,c), I[214] = (T)(img)(_n3##x,_p1##y,z,c), I[215] = (T)(img)(_n4##x,_p1##y,z,c), \ - I[216] = (T)(img)(_p3##x,y,z,c), I[217] = (T)(img)(_p2##x,y,z,c), I[218] = (T)(img)(_p1##x,y,z,c), I[219] = (T)(img)(x,y,z,c), I[220] = (T)(img)(_n1##x,y,z,c), I[221] = (T)(img)(_n2##x,y,z,c), I[222] = (T)(img)(_n3##x,y,z,c), I[223] = (T)(img)(_n4##x,y,z,c), \ - I[224] = (T)(img)(_p3##x,_n1##y,z,c), I[225] = (T)(img)(_p2##x,_n1##y,z,c), I[226] = (T)(img)(_p1##x,_n1##y,z,c), I[227] = (T)(img)(x,_n1##y,z,c), I[228] = (T)(img)(_n1##x,_n1##y,z,c), I[229] = (T)(img)(_n2##x,_n1##y,z,c), I[230] = (T)(img)(_n3##x,_n1##y,z,c), I[231] = (T)(img)(_n4##x,_n1##y,z,c), \ - I[232] = (T)(img)(_p3##x,_n2##y,z,c), I[233] = (T)(img)(_p2##x,_n2##y,z,c), I[234] = (T)(img)(_p1##x,_n2##y,z,c), I[235] = (T)(img)(x,_n2##y,z,c), I[236] = (T)(img)(_n1##x,_n2##y,z,c), I[237] = (T)(img)(_n2##x,_n2##y,z,c), I[238] = (T)(img)(_n3##x,_n2##y,z,c), I[239] = (T)(img)(_n4##x,_n2##y,z,c), \ - I[240] = (T)(img)(_p3##x,_n3##y,z,c), I[241] = (T)(img)(_p2##x,_n3##y,z,c), I[242] = (T)(img)(_p1##x,_n3##y,z,c), I[243] = (T)(img)(x,_n3##y,z,c), I[244] = (T)(img)(_n1##x,_n3##y,z,c), I[245] = (T)(img)(_n2##x,_n3##y,z,c), I[246] = (T)(img)(_n3##x,_n3##y,z,c), I[247] = (T)(img)(_n4##x,_n3##y,z,c), \ - I[248] = (T)(img)(_p3##x,_n4##y,z,c), I[249] = (T)(img)(_p2##x,_n4##y,z,c), I[250] = (T)(img)(_p1##x,_n4##y,z,c), I[251] = (T)(img)(x,_n4##y,z,c), I[252] = (T)(img)(_n1##x,_n4##y,z,c), I[253] = (T)(img)(_n2##x,_n4##y,z,c), I[254] = (T)(img)(_n3##x,_n4##y,z,c), I[255] = (T)(img)(_n4##x,_n4##y,z,c), \ - I[256] = (T)(img)(_p3##x,_p3##y,_n1##z,c), I[257] = (T)(img)(_p2##x,_p3##y,_n1##z,c), I[258] = (T)(img)(_p1##x,_p3##y,_n1##z,c), I[259] = (T)(img)(x,_p3##y,_n1##z,c), I[260] = (T)(img)(_n1##x,_p3##y,_n1##z,c), I[261] = (T)(img)(_n2##x,_p3##y,_n1##z,c), I[262] = (T)(img)(_n3##x,_p3##y,_n1##z,c), I[263] = (T)(img)(_n4##x,_p3##y,_n1##z,c), \ - I[264] = (T)(img)(_p3##x,_p2##y,_n1##z,c), I[265] = (T)(img)(_p2##x,_p2##y,_n1##z,c), I[266] = (T)(img)(_p1##x,_p2##y,_n1##z,c), I[267] = (T)(img)(x,_p2##y,_n1##z,c), I[268] = (T)(img)(_n1##x,_p2##y,_n1##z,c), I[269] = (T)(img)(_n2##x,_p2##y,_n1##z,c), I[270] = (T)(img)(_n3##x,_p2##y,_n1##z,c), I[271] = (T)(img)(_n4##x,_p2##y,_n1##z,c), \ - I[272] = (T)(img)(_p3##x,_p1##y,_n1##z,c), I[273] = (T)(img)(_p2##x,_p1##y,_n1##z,c), I[274] = (T)(img)(_p1##x,_p1##y,_n1##z,c), I[275] = (T)(img)(x,_p1##y,_n1##z,c), I[276] = (T)(img)(_n1##x,_p1##y,_n1##z,c), I[277] = (T)(img)(_n2##x,_p1##y,_n1##z,c), I[278] = (T)(img)(_n3##x,_p1##y,_n1##z,c), I[279] = (T)(img)(_n4##x,_p1##y,_n1##z,c), \ - I[280] = (T)(img)(_p3##x,y,_n1##z,c), I[281] = (T)(img)(_p2##x,y,_n1##z,c), I[282] = (T)(img)(_p1##x,y,_n1##z,c), I[283] = (T)(img)(x,y,_n1##z,c), I[284] = (T)(img)(_n1##x,y,_n1##z,c), I[285] = (T)(img)(_n2##x,y,_n1##z,c), I[286] = (T)(img)(_n3##x,y,_n1##z,c), I[287] = (T)(img)(_n4##x,y,_n1##z,c), \ - I[288] = (T)(img)(_p3##x,_n1##y,_n1##z,c), I[289] = (T)(img)(_p2##x,_n1##y,_n1##z,c), I[290] = (T)(img)(_p1##x,_n1##y,_n1##z,c), I[291] = (T)(img)(x,_n1##y,_n1##z,c), I[292] = (T)(img)(_n1##x,_n1##y,_n1##z,c), I[293] = (T)(img)(_n2##x,_n1##y,_n1##z,c), I[294] = (T)(img)(_n3##x,_n1##y,_n1##z,c), I[295] = (T)(img)(_n4##x,_n1##y,_n1##z,c), \ - I[296] = (T)(img)(_p3##x,_n2##y,_n1##z,c), I[297] = (T)(img)(_p2##x,_n2##y,_n1##z,c), I[298] = (T)(img)(_p1##x,_n2##y,_n1##z,c), I[299] = (T)(img)(x,_n2##y,_n1##z,c), I[300] = (T)(img)(_n1##x,_n2##y,_n1##z,c), I[301] = (T)(img)(_n2##x,_n2##y,_n1##z,c), I[302] = (T)(img)(_n3##x,_n2##y,_n1##z,c), I[303] = (T)(img)(_n4##x,_n2##y,_n1##z,c), \ - I[304] = (T)(img)(_p3##x,_n3##y,_n1##z,c), I[305] = (T)(img)(_p2##x,_n3##y,_n1##z,c), I[306] = (T)(img)(_p1##x,_n3##y,_n1##z,c), I[307] = (T)(img)(x,_n3##y,_n1##z,c), I[308] = (T)(img)(_n1##x,_n3##y,_n1##z,c), I[309] = (T)(img)(_n2##x,_n3##y,_n1##z,c), I[310] = (T)(img)(_n3##x,_n3##y,_n1##z,c), I[311] = (T)(img)(_n4##x,_n3##y,_n1##z,c), \ - I[312] = (T)(img)(_p3##x,_n4##y,_n1##z,c), I[313] = (T)(img)(_p2##x,_n4##y,_n1##z,c), I[314] = (T)(img)(_p1##x,_n4##y,_n1##z,c), I[315] = (T)(img)(x,_n4##y,_n1##z,c), I[316] = (T)(img)(_n1##x,_n4##y,_n1##z,c), I[317] = (T)(img)(_n2##x,_n4##y,_n1##z,c), I[318] = (T)(img)(_n3##x,_n4##y,_n1##z,c), I[319] = (T)(img)(_n4##x,_n4##y,_n1##z,c), \ - I[320] = (T)(img)(_p3##x,_p3##y,_n2##z,c), I[321] = (T)(img)(_p2##x,_p3##y,_n2##z,c), I[322] = (T)(img)(_p1##x,_p3##y,_n2##z,c), I[323] = (T)(img)(x,_p3##y,_n2##z,c), I[324] = (T)(img)(_n1##x,_p3##y,_n2##z,c), I[325] = (T)(img)(_n2##x,_p3##y,_n2##z,c), I[326] = (T)(img)(_n3##x,_p3##y,_n2##z,c), I[327] = (T)(img)(_n4##x,_p3##y,_n2##z,c), \ - I[328] = (T)(img)(_p3##x,_p2##y,_n2##z,c), I[329] = (T)(img)(_p2##x,_p2##y,_n2##z,c), I[330] = (T)(img)(_p1##x,_p2##y,_n2##z,c), I[331] = (T)(img)(x,_p2##y,_n2##z,c), I[332] = (T)(img)(_n1##x,_p2##y,_n2##z,c), I[333] = (T)(img)(_n2##x,_p2##y,_n2##z,c), I[334] = (T)(img)(_n3##x,_p2##y,_n2##z,c), I[335] = (T)(img)(_n4##x,_p2##y,_n2##z,c), \ - I[336] = (T)(img)(_p3##x,_p1##y,_n2##z,c), I[337] = (T)(img)(_p2##x,_p1##y,_n2##z,c), I[338] = (T)(img)(_p1##x,_p1##y,_n2##z,c), I[339] = (T)(img)(x,_p1##y,_n2##z,c), I[340] = (T)(img)(_n1##x,_p1##y,_n2##z,c), I[341] = (T)(img)(_n2##x,_p1##y,_n2##z,c), I[342] = (T)(img)(_n3##x,_p1##y,_n2##z,c), I[343] = (T)(img)(_n4##x,_p1##y,_n2##z,c), \ - I[344] = (T)(img)(_p3##x,y,_n2##z,c), I[345] = (T)(img)(_p2##x,y,_n2##z,c), I[346] = (T)(img)(_p1##x,y,_n2##z,c), I[347] = (T)(img)(x,y,_n2##z,c), I[348] = (T)(img)(_n1##x,y,_n2##z,c), I[349] = (T)(img)(_n2##x,y,_n2##z,c), I[350] = (T)(img)(_n3##x,y,_n2##z,c), I[351] = (T)(img)(_n4##x,y,_n2##z,c), \ - I[352] = (T)(img)(_p3##x,_n1##y,_n2##z,c), I[353] = (T)(img)(_p2##x,_n1##y,_n2##z,c), I[354] = (T)(img)(_p1##x,_n1##y,_n2##z,c), I[355] = (T)(img)(x,_n1##y,_n2##z,c), I[356] = (T)(img)(_n1##x,_n1##y,_n2##z,c), I[357] = (T)(img)(_n2##x,_n1##y,_n2##z,c), I[358] = (T)(img)(_n3##x,_n1##y,_n2##z,c), I[359] = (T)(img)(_n4##x,_n1##y,_n2##z,c), \ - I[360] = (T)(img)(_p3##x,_n2##y,_n2##z,c), I[361] = (T)(img)(_p2##x,_n2##y,_n2##z,c), I[362] = (T)(img)(_p1##x,_n2##y,_n2##z,c), I[363] = (T)(img)(x,_n2##y,_n2##z,c), I[364] = (T)(img)(_n1##x,_n2##y,_n2##z,c), I[365] = (T)(img)(_n2##x,_n2##y,_n2##z,c), I[366] = (T)(img)(_n3##x,_n2##y,_n2##z,c), I[367] = (T)(img)(_n4##x,_n2##y,_n2##z,c), \ - I[368] = (T)(img)(_p3##x,_n3##y,_n2##z,c), I[369] = (T)(img)(_p2##x,_n3##y,_n2##z,c), I[370] = (T)(img)(_p1##x,_n3##y,_n2##z,c), I[371] = (T)(img)(x,_n3##y,_n2##z,c), I[372] = (T)(img)(_n1##x,_n3##y,_n2##z,c), I[373] = (T)(img)(_n2##x,_n3##y,_n2##z,c), I[374] = (T)(img)(_n3##x,_n3##y,_n2##z,c), I[375] = (T)(img)(_n4##x,_n3##y,_n2##z,c), \ - I[376] = (T)(img)(_p3##x,_n4##y,_n2##z,c), I[377] = (T)(img)(_p2##x,_n4##y,_n2##z,c), I[378] = (T)(img)(_p1##x,_n4##y,_n2##z,c), I[379] = (T)(img)(x,_n4##y,_n2##z,c), I[380] = (T)(img)(_n1##x,_n4##y,_n2##z,c), I[381] = (T)(img)(_n2##x,_n4##y,_n2##z,c), I[382] = (T)(img)(_n3##x,_n4##y,_n2##z,c), I[383] = (T)(img)(_n4##x,_n4##y,_n2##z,c), \ - I[384] = (T)(img)(_p3##x,_p3##y,_n3##z,c), I[385] = (T)(img)(_p2##x,_p3##y,_n3##z,c), I[386] = (T)(img)(_p1##x,_p3##y,_n3##z,c), I[387] = (T)(img)(x,_p3##y,_n3##z,c), I[388] = (T)(img)(_n1##x,_p3##y,_n3##z,c), I[389] = (T)(img)(_n2##x,_p3##y,_n3##z,c), I[390] = (T)(img)(_n3##x,_p3##y,_n3##z,c), I[391] = (T)(img)(_n4##x,_p3##y,_n3##z,c), \ - I[392] = (T)(img)(_p3##x,_p2##y,_n3##z,c), I[393] = (T)(img)(_p2##x,_p2##y,_n3##z,c), I[394] = (T)(img)(_p1##x,_p2##y,_n3##z,c), I[395] = (T)(img)(x,_p2##y,_n3##z,c), I[396] = (T)(img)(_n1##x,_p2##y,_n3##z,c), I[397] = (T)(img)(_n2##x,_p2##y,_n3##z,c), I[398] = (T)(img)(_n3##x,_p2##y,_n3##z,c), I[399] = (T)(img)(_n4##x,_p2##y,_n3##z,c), \ - I[400] = (T)(img)(_p3##x,_p1##y,_n3##z,c), I[401] = (T)(img)(_p2##x,_p1##y,_n3##z,c), I[402] = (T)(img)(_p1##x,_p1##y,_n3##z,c), I[403] = (T)(img)(x,_p1##y,_n3##z,c), I[404] = (T)(img)(_n1##x,_p1##y,_n3##z,c), I[405] = (T)(img)(_n2##x,_p1##y,_n3##z,c), I[406] = (T)(img)(_n3##x,_p1##y,_n3##z,c), I[407] = (T)(img)(_n4##x,_p1##y,_n3##z,c), \ - I[408] = (T)(img)(_p3##x,y,_n3##z,c), I[409] = (T)(img)(_p2##x,y,_n3##z,c), I[410] = (T)(img)(_p1##x,y,_n3##z,c), I[411] = (T)(img)(x,y,_n3##z,c), I[412] = (T)(img)(_n1##x,y,_n3##z,c), I[413] = (T)(img)(_n2##x,y,_n3##z,c), I[414] = (T)(img)(_n3##x,y,_n3##z,c), I[415] = (T)(img)(_n4##x,y,_n3##z,c), \ - I[416] = (T)(img)(_p3##x,_n1##y,_n3##z,c), I[417] = (T)(img)(_p2##x,_n1##y,_n3##z,c), I[418] = (T)(img)(_p1##x,_n1##y,_n3##z,c), I[419] = (T)(img)(x,_n1##y,_n3##z,c), I[420] = (T)(img)(_n1##x,_n1##y,_n3##z,c), I[421] = (T)(img)(_n2##x,_n1##y,_n3##z,c), I[422] = (T)(img)(_n3##x,_n1##y,_n3##z,c), I[423] = (T)(img)(_n4##x,_n1##y,_n3##z,c), \ - I[424] = (T)(img)(_p3##x,_n2##y,_n3##z,c), I[425] = (T)(img)(_p2##x,_n2##y,_n3##z,c), I[426] = (T)(img)(_p1##x,_n2##y,_n3##z,c), I[427] = (T)(img)(x,_n2##y,_n3##z,c), I[428] = (T)(img)(_n1##x,_n2##y,_n3##z,c), I[429] = (T)(img)(_n2##x,_n2##y,_n3##z,c), I[430] = (T)(img)(_n3##x,_n2##y,_n3##z,c), I[431] = (T)(img)(_n4##x,_n2##y,_n3##z,c), \ - I[432] = (T)(img)(_p3##x,_n3##y,_n3##z,c), I[433] = (T)(img)(_p2##x,_n3##y,_n3##z,c), I[434] = (T)(img)(_p1##x,_n3##y,_n3##z,c), I[435] = (T)(img)(x,_n3##y,_n3##z,c), I[436] = (T)(img)(_n1##x,_n3##y,_n3##z,c), I[437] = (T)(img)(_n2##x,_n3##y,_n3##z,c), I[438] = (T)(img)(_n3##x,_n3##y,_n3##z,c), I[439] = (T)(img)(_n4##x,_n3##y,_n3##z,c), \ - I[440] = (T)(img)(_p3##x,_n4##y,_n3##z,c), I[441] = (T)(img)(_p2##x,_n4##y,_n3##z,c), I[442] = (T)(img)(_p1##x,_n4##y,_n3##z,c), I[443] = (T)(img)(x,_n4##y,_n3##z,c), I[444] = (T)(img)(_n1##x,_n4##y,_n3##z,c), I[445] = (T)(img)(_n2##x,_n4##y,_n3##z,c), I[446] = (T)(img)(_n3##x,_n4##y,_n3##z,c), I[447] = (T)(img)(_n4##x,_n4##y,_n3##z,c), \ - I[448] = (T)(img)(_p3##x,_p3##y,_n4##z,c), I[449] = (T)(img)(_p2##x,_p3##y,_n4##z,c), I[450] = (T)(img)(_p1##x,_p3##y,_n4##z,c), I[451] = (T)(img)(x,_p3##y,_n4##z,c), I[452] = (T)(img)(_n1##x,_p3##y,_n4##z,c), I[453] = (T)(img)(_n2##x,_p3##y,_n4##z,c), I[454] = (T)(img)(_n3##x,_p3##y,_n4##z,c), I[455] = (T)(img)(_n4##x,_p3##y,_n4##z,c), \ - I[456] = (T)(img)(_p3##x,_p2##y,_n4##z,c), I[457] = (T)(img)(_p2##x,_p2##y,_n4##z,c), I[458] = (T)(img)(_p1##x,_p2##y,_n4##z,c), I[459] = (T)(img)(x,_p2##y,_n4##z,c), I[460] = (T)(img)(_n1##x,_p2##y,_n4##z,c), I[461] = (T)(img)(_n2##x,_p2##y,_n4##z,c), I[462] = (T)(img)(_n3##x,_p2##y,_n4##z,c), I[463] = (T)(img)(_n4##x,_p2##y,_n4##z,c), \ - I[464] = (T)(img)(_p3##x,_p1##y,_n4##z,c), I[465] = (T)(img)(_p2##x,_p1##y,_n4##z,c), I[466] = (T)(img)(_p1##x,_p1##y,_n4##z,c), I[467] = (T)(img)(x,_p1##y,_n4##z,c), I[468] = (T)(img)(_n1##x,_p1##y,_n4##z,c), I[469] = (T)(img)(_n2##x,_p1##y,_n4##z,c), I[470] = (T)(img)(_n3##x,_p1##y,_n4##z,c), I[471] = (T)(img)(_n4##x,_p1##y,_n4##z,c), \ - I[472] = (T)(img)(_p3##x,y,_n4##z,c), I[473] = (T)(img)(_p2##x,y,_n4##z,c), I[474] = (T)(img)(_p1##x,y,_n4##z,c), I[475] = (T)(img)(x,y,_n4##z,c), I[476] = (T)(img)(_n1##x,y,_n4##z,c), I[477] = (T)(img)(_n2##x,y,_n4##z,c), I[478] = (T)(img)(_n3##x,y,_n4##z,c), I[479] = (T)(img)(_n4##x,y,_n4##z,c), \ - I[480] = (T)(img)(_p3##x,_n1##y,_n4##z,c), I[481] = (T)(img)(_p2##x,_n1##y,_n4##z,c), I[482] = (T)(img)(_p1##x,_n1##y,_n4##z,c), I[483] = (T)(img)(x,_n1##y,_n4##z,c), I[484] = (T)(img)(_n1##x,_n1##y,_n4##z,c), I[485] = (T)(img)(_n2##x,_n1##y,_n4##z,c), I[486] = (T)(img)(_n3##x,_n1##y,_n4##z,c), I[487] = (T)(img)(_n4##x,_n1##y,_n4##z,c), \ - I[488] = (T)(img)(_p3##x,_n2##y,_n4##z,c), I[489] = (T)(img)(_p2##x,_n2##y,_n4##z,c), I[490] = (T)(img)(_p1##x,_n2##y,_n4##z,c), I[491] = (T)(img)(x,_n2##y,_n4##z,c), I[492] = (T)(img)(_n1##x,_n2##y,_n4##z,c), I[493] = (T)(img)(_n2##x,_n2##y,_n4##z,c), I[494] = (T)(img)(_n3##x,_n2##y,_n4##z,c), I[495] = (T)(img)(_n4##x,_n2##y,_n4##z,c), \ - I[496] = (T)(img)(_p3##x,_n3##y,_n4##z,c), I[497] = (T)(img)(_p2##x,_n3##y,_n4##z,c), I[498] = (T)(img)(_p1##x,_n3##y,_n4##z,c), I[499] = (T)(img)(x,_n3##y,_n4##z,c), I[500] = (T)(img)(_n1##x,_n3##y,_n4##z,c), I[501] = (T)(img)(_n2##x,_n3##y,_n4##z,c), I[502] = (T)(img)(_n3##x,_n3##y,_n4##z,c), I[503] = (T)(img)(_n4##x,_n3##y,_n4##z,c), \ - I[504] = (T)(img)(_p3##x,_n4##y,_n4##z,c), I[505] = (T)(img)(_p2##x,_n4##y,_n4##z,c), I[506] = (T)(img)(_p1##x,_n4##y,_n4##z,c), I[507] = (T)(img)(x,_n4##y,_n4##z,c), I[508] = (T)(img)(_n1##x,_n4##y,_n4##z,c), I[509] = (T)(img)(_n2##x,_n4##y,_n4##z,c), I[510] = (T)(img)(_n3##x,_n4##y,_n4##z,c), I[511] = (T)(img)(_n4##x,_n4##y,_n4##z,c); - -// End of the plug-in -#endif /* cimg_plugin_loop_macros */ diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/matlab.h b/applications/plugins/CImgPlugin/extlibs/CImg/plugins/matlab.h deleted file mode 100644 index c4cbb34a555..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/matlab.h +++ /dev/null @@ -1,287 +0,0 @@ -/************************************************************************* - * matlab.h - * --------- - * - * matlab.h is a "plugin" for the CImg library that allows to convert - * CImg images from/to MATLAB arrays, so that CImg can be used to write - * MATLAB mex files. It also swaps the "x" and "y" coordinates when going - * from / to MATLAB array, i.e. the usual image-processing annoying MATLAB - * behaviour of considering images as matrices. - * - * Added to the CImg class are: - * - * - a constructor : CImg(const mxArray *matlabArray, bool vdata = false) - * the vdata serves to decide whether a 3D matlab array should give - * rise to a 3D CImg object or a "2D vectorial" one. - * - * - a assignment operator : CImg & operator=(const mxArray *matlabArray) - * (I use myself extremely seldom and might remove it in the future). - * - * - a routine converting a CImg image to a matlab array: - * mxArray *toMatlab(mxClassID classID = mxDOUBLE_CLASS, - * bool squeeze = false) const - * the squeeze argument serves the opposite purpose than the vdata from - * the constructor. - * - * For a bit more documentation, the manual is this header, see the more - * detailed comments in the source code (i.e. RTFM) - * - * - * Its usage should be straightforward: - * - * - file matlab.h must be in a directory that the compiler can locate. - * - prior to include CImg.h, mex.h must be included first, else it will - * result in a compiler error. - * - after the inclusion of mex.h, one must define the macro cimg_plugin as - * "matlab.h" or or or - * a variation that matches your local installation of CImg package and - * plugins probably via the appropriate specification of the include path - * "-Ipath/to/cimg/and/plugins" at mex cmdline. - * - * You would probably have this kind of declaration: - * - * // The begining of my fantastic mex file code... - * #include - * ... - * #define cimg_plugin - * #include - * ... - * // and now I can implement my new killer MATLAB function! - * .... - * - * - * Copyright (c) 2004-2008 Francois Lauze - * Licence: the Gnu Lesser General Public License - * http://www.gnu.org/licenses/lgpl.html - * - * MATLAB is copyright of The MathWorks, Inc, http://www.mathworks.com - * - * Any comments, improvements and potential bug corrections are welcome, so - * write to me at francois@diku.dk, or use CImg forums, I promise I'll try - * to read them once in a while. BTW who modified the cpMatlabData with the - * cimg::type::is_float() test (good idea!) - * - ***************************************************************************/ - -#ifndef cimg_plugin_matlab -#define cimg_plugin_matlab - -#define CIMGMATLAB_VER 0102 -#ifndef mex_h -#error the file mex.h must be included prior to inclusion of matlab.h -#endif -#ifndef cimg_version -#error matlab.h requires that CImg.h is included! -#endif - -/********************************************************** - * introduction of mwSize and mwIndex types in relatively * - * recent versions of matlab, 7.3.0 from what I gathered. * - * here is hopefully a needed fix for older versions * - **********************************************************/ -#if !defined(MX_API_VER) || MX_API_VER < 0x7030000 -typedef int mwSize; -#endif - -/********************************************************* - * begin of included methods * - * They are just added as member functions / constructor * - * for the CImg class. * - *********************************************************/ - -private: - -/********************************************************************** - * internally used to transfer MATLAB array values to CImg<> objects, - * check wether the array type is a "numerical" one (including logical) - */ -static int isNumericalClassID(mxClassID id) { - // all these constants are defined in matrix.h included by mex.h - switch (id) { - case mxLOGICAL_CLASS: - case mxDOUBLE_CLASS: - case mxSINGLE_CLASS: - case mxINT8_CLASS: - case mxUINT8_CLASS: - case mxINT16_CLASS: - case mxUINT16_CLASS: - case mxINT32_CLASS: - case mxUINT32_CLASS: - case mxINT64_CLASS: - case mxUINT64_CLASS: return 1; - default: return 0; - } -} - -/*************************************************** - * driving routine that will copy the content of - * a MATLAB array to this->_data - * The type names used are defined in matlab c/c++ - * header file tmwtypes.h - */ -void makeImageFromMatlabData(const mxArray *matlabArray, mxClassID classID) { - if (classID==mxLOGICAL_CLASS) { - // logical type works a bit differently than the numerical types - mxLogical *mdata = mxGetLogicals(matlabArray); - cpMatlabData((const mxLogical *)mdata); - } else { - void *mdata = (void*)mxGetPr(matlabArray); - switch (classID) { - case mxDOUBLE_CLASS : cpMatlabData((const real64_T*)mdata); break; - case mxSINGLE_CLASS : cpMatlabData((const real32_T*)mdata); break; - case mxINT8_CLASS : cpMatlabData((const int8_T*)mdata); break; - case mxUINT8_CLASS : cpMatlabData((const uint8_T*)mdata); break; - case mxINT16_CLASS : cpMatlabData((const int16_T*)mdata); break; - case mxUINT16_CLASS : cpMatlabData((const uint16_T*)mdata); break; - case mxINT32_CLASS : cpMatlabData((const int32_T*)mdata); break; - case mxUINT32_CLASS : cpMatlabData((const uint32_T*)mdata); break; - case mxINT64_CLASS : cpMatlabData((const int64_T*)mdata); break; - case mxUINT64_CLASS : cpMatlabData((const uint64_T*)mdata); break; - } - } -} - -/*********************************************************** - * the actual memory copy and base type conversion is then - * performed by this routine that handles the annoying x-y - * problem of MATLAB when dealing with images: we switch - * line and column storage: the MATLAB A(x,y) becomes the - * CImg img(y,x) - */ -template void cpMatlabData(const t* mdata) { - if (cimg::type::is_float()) { - cimg_forXYZC(*this,x,y,z,v) (*this)(x,y,z,v) = (T)(mdata[((v*_depth + z)*_width + x)*_height + y]); - } else { - cimg_forXYZC(*this,x,y,z,v) (*this)(x,y,z,v) = (T)(int)(mdata[((v*_depth + z)*_width + x)*_height + y]); - } -} - -public: - -/****************************************************************** - * Consruct a CImg object from a MATLAB mxArray. - * The MATLAB array must be AT MOST 4-dimensional. The boolean - * argument vdata is employed in the case the the input mxArray - * has dimension 3, say M x N x K. In that case, if vdata is true, - * the last dimension is assumed to be "vectorial" and the - * resulting CImg object has dimension N x M x 1 x K. Otherwise, - * the resulting object has dimension N x M x K x 1. - * When MATLAB array has dimension 2 or 4, vdata has no effects. - * No shared memory mechanisms are used, it would be the easiest - * to crash Matlab (from my own experience...) - */ -CImg(const mxArray *matlabArray, const bool vdata = false) - : _is_shared(false) { - mwSize nbdims = mxGetNumberOfDimensions(matlabArray); - mxClassID classID = mxGetClassID(matlabArray); - if (nbdims>4 || !isNumericalClassID(classID)) { - _data = 0; _width = _height = _depth = _spectrum = 0; -#if cimg_debug>1 - cimg::warn("MATLAB array is more than 4D or/and not numerical, returning an empty image."); -#endif - } else { - const mwSize *dims = mxGetDimensions(matlabArray); - _depth = _spectrum = 1; - _width = (unsigned)dims[1]; - _height = (unsigned)dims[0]; - if (nbdims==4) { _depth = (unsigned)dims[2]; _spectrum = (unsigned)dims[3]; } - else if (nbdims==3) { - if (vdata) _spectrum = (unsigned)dims[2]; else _depth = (unsigned)dims[2]; - } - _data = new T[size()]; - makeImageFromMatlabData(matlabArray,classID); - } -} - -/******************************************************************* - * operator=(). Copy mxMarray data mArray into the current image - * Works as the previous constructor, but without the vdata stuff. - * don't know if it is of any use... - */ -CImg & operator=(const mxArray *matlabArray) { - int - nbdims = (int)mxGetNumberOfDimensions(matlabArray), - classID = mxGetClassID(matlabArray); - if (nbdims>4 || !isNumericalClassID(classID)) { - delete [] _data; _data = 0; - _width = _height = _depth = _spectrum = 0; -#if cimg_debug>1 - cimg::warn("MATLAB array is more than 4D or/and not numerical, returning an empty image."); -#endif - } else { - const mwSize *dims = mxGetDimensions(matlabArray); - _depth = _spectrum = 1; - _width = (unsigned)dims[1]; - _height = (unsigned)dims[0]; - if (nbdims>2) _depth = (unsigned)dims[2]; - else if (nbdims>3) _spectrum = (unsigned)dims[3]; - delete [] _data; - _data = new T[size()]; - makeImageFromMatlabData(matlabArray,classID); - } -} - -private: - -/***************************************************************** - * private routines used for transfering a CImg to a mxArray - * here also, we have to exchange the x and y dims so we get the - * expected MATLAB array. - */ -template void populate_maltlab_array(c *const mdata) const { - cimg_forXYZC(*this,x,y,z,v) mdata[((v*_depth + z)*_width + x)*_height + y] = (c)(*this)(x,y,z,v); -} - -/************************************************* - * the specialized version for "logical" entries - */ -void populate_maltlab_array(mxLogical *const mdata) const { - cimg_forXYZC(*this,x,y,z,v) mdata[((v*_depth + z)*_width + x)*_height + y] = (mxLogical)((*this)(x,y,z,v)!=0); -} - -public: - -/****************************************** - * export a CImg image to a MATLAB array. - **/ -mxArray *toMatlab(mxClassID classID=mxDOUBLE_CLASS, const bool squeeze=false) const { - if (!isNumericalClassID(classID)) { -#if cimg_debug>1 - cimg::warn("Invalid MATLAB Class Id Specified."); -#endif - return 0; - } - mwSize dims[4]; - dims[0] = (mwSize)_height; - dims[1] = (mwSize)_width; - dims[2] = (mwSize)_depth; - dims[3] = (mwSize)_spectrum; - - if (squeeze && _depth == 1) { - dims[2] = (mwSize)_spectrum; - dims[3] = (mwSize)1; - } - mxArray *matlabArray = mxCreateNumericArray((mwSize)4,dims,classID,mxREAL); - if (classID==mxLOGICAL_CLASS) { - mxLogical *mdata = mxGetLogicals(matlabArray); - populate_maltlab_array(mdata); - } else { - void *mdata = mxGetPr(matlabArray); - switch (classID) { - case mxDOUBLE_CLASS : populate_maltlab_array((real64_T*)mdata); break; - case mxSINGLE_CLASS : populate_maltlab_array((real32_T*)mdata); break; - case mxINT8_CLASS : populate_maltlab_array((int8_T*)mdata); break; - case mxUINT8_CLASS : populate_maltlab_array((uint8_T*)mdata); break; - case mxINT16_CLASS : populate_maltlab_array((int16_T*)mdata); break; - case mxUINT16_CLASS : populate_maltlab_array((uint16_T*)mdata); break; - case mxINT32_CLASS : populate_maltlab_array((int32_T*)mdata); break; - case mxUINT32_CLASS : populate_maltlab_array((uint32_T*)mdata); break; - case mxINT64_CLASS : populate_maltlab_array((int64_T*)mdata); break; - case mxUINT64_CLASS : populate_maltlab_array((uint64_T*)mdata); break; - } - } - return matlabArray; -} - -// end of matlab.h -#endif /* cimg_plugin_matlab */ diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/nlmeans.h b/applications/plugins/CImgPlugin/extlibs/CImg/plugins/nlmeans.h deleted file mode 100644 index dbec11e8c44..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/nlmeans.h +++ /dev/null @@ -1,242 +0,0 @@ -/* - # - # File : nlmeans.h - # ( C++ header file - CImg plug-in ) - # - # Description : CImg plugin that implements the non-local mean filter. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # [1] Buades, A.; Coll, B.; Morel, J.-M.: A non-local algorithm for image denoising - # IEEE Computer Society Conference on Computer Vision and Pattern Recognition, 2005. CVPR 2005. - # Volume 2, 20-25 June 2005 Page(s):60 - 65 vol. 2 - # - # [2] Buades, A. Coll, B. and Morel, J.: A review of image denoising algorithms, with a new one. - # Multiscale Modeling and Simulation: A SIAM Interdisciplinary Journal 4 (2004) 490-530 - # - # [3] Gasser, T. Sroka,L. Jennen Steinmetz,C. Residual variance and residual pattern nonlinear regression. - # Biometrika 73 (1986) 625-659 - # - # Copyright : Jerome Boulanger - # ( http://www.irisa.fr/vista/Equipe/People/Jerome.Boulanger.html ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#ifndef cimg_plugin_nlmeans -#define cimg_plugin_nlmeans - -//! NL-Means denoising algorithm. -/** - This is the in-place version of get_nlmean(). -**/ -CImg& nlmeans(int patch_size=1, double lambda=-1, double alpha=3, double sigma=-1, int sampling=1){ - if (!is_empty()){ - if (sigma<0) sigma = std::sqrt(variance_noise()); // noise variance estimation - const double np = (2*patch_size + 1)*(2*patch_size + 1)*spectrum()/(double)sampling; - if (lambda<0) {// Bandwidth estimation - if (np<100) - lambda = ((((((1.1785e-12*np - 5.1827e-10)*np + 9.5946e-08)*np - - 9.7798e-06)*np + 6.0756e-04)*np - 0.0248)*np + 1.9203)*np + 7.9599; - else - lambda = (-7.2611e-04*np + 1.3213)*np + 15.2726; - } -#if cimg_debug>=1 - std::fprintf(stderr,"Size of the patch : %dx%d \n", - 2*patch_size + 1,2*patch_size + 1); - std::fprintf(stderr,"Size of window where similar patch are looked for : %dx%d \n", - (int)(alpha*(2*patch_size + 1)),(int)(alpha*(2*patch_size + 1))); - std::fprintf(stderr,"Bandwidth of the kernel : %fx%f^2 \n", - lambda,sigma); - std::fprintf(stderr,"Noise standard deviation estimated to : %f \n", - sigma); -#endif - - CImg dest(width(),height(),depth(),spectrum(),0); - double *uhat = new double[spectrum()]; - const double h2 = -.5/(lambda*sigma*sigma); // [Kervrann] notations - if (depth()!=1){ // 3D case - const CImg<> P = (*this).get_blur(1); // inspired from Mahmoudi&Sapiro SPletter dec 05 - const int n_simu = 64; - CImg<> tmp(n_simu,n_simu,n_simu); - const double sig = std::sqrt(tmp.fill(0.f).noise(sigma).blur(1).pow(2.).sum()/(n_simu*n_simu*n_simu)); - const int - patch_size_z = 0, - pxi = (int)(alpha*patch_size), - pyi = (int)(alpha*patch_size), - pzi = 2; //Define the size of the neighborhood in z - for (int zi = 0; zi=1 - std::fprintf(stderr,"\rProcessing : %3d %%",(int)((float)zi/(float)depth()*100.));fflush(stdout); -#endif - for (int yi = 0; yi=0 && zj_=0 && zi_=0 && yj_=0 && yi_=0 && xj_=0 && xi_wmax?w:wmax; - cimg_forC(*this,v) uhat[v]+=w*(*this)(xj,yj,zj,v); - sw+=w; - } - } - // add the central pixel - cimg_forC(*this,v) uhat[v]+=wmax*(*this)(xi,yi,zi,v); - sw+=wmax; - if (sw) cimg_forC(*this,v) dest(xi,yi,zi,v) = (T)(uhat[v]/=sw); - else cimg_forC(*this,v) dest(xi,yi,zi,v) = (*this)(xi,yi,zi,v); - } - } - } - else { // 2D case - const CImg<> P = (*this).get_blur(1); // inspired from Mahmoudi&Sapiro SPletter dec 05 - const int n_simu = 512; - CImg<> tmp(n_simu,n_simu); - const double sig = std::sqrt(tmp.fill(0.f).noise(sigma).blur(1).pow(2.).sum()/(n_simu*n_simu)); - const int - pxi = (int)(alpha*patch_size), - pyi = (int)(alpha*patch_size); //Define the size of the neighborhood - for (int yi = 0; yi=1 - std::fprintf(stderr,"\rProcessing : %3d %%",(int)((float)yi/(float)height()*100.));fflush(stdout); -#endif - for (int xi = 0; xi=0 && yj_=0 && yi_=0 && xj_=0 && xi_wmax?w:wmax; // Store the maximum of the weights - sw+=w; // Compute the sum of the weights - } - } - // add the central pixel with the maximum weight - cimg_forC(*this,v) uhat[v]+=wmax*(*this)(xi,yi,v); - sw+=wmax; - - // Compute the estimate for the current pixel - if (sw) cimg_forC(*this,v) dest(xi,yi,v) = (T)(uhat[v]/=sw); - else cimg_forC(*this,v) dest(xi,yi,v) = (*this)(xi,yi,v); - } - } // main loop - } // 2d - delete [] uhat; - dest.move_to(*this); -#if cimg_debug>=1 - std::fprintf(stderr,"\n"); // make a new line -#endif - } // is empty - return *this; -} - -//! Get the result of the NL-Means denoising algorithm. -/** - \param patch_size = radius of the patch (1=3x3 by default) - \param lambda = bandwidth ( -1 by default : automatic selection) - \param alpha = size of the region where similar patch are searched (3 x patch_size = 9x9 by default) - \param sigma = noise standard deviation (-1 = estimation) - \param sampling = sampling of the patch (1 = uses all point, 2 = uses one point on 4, etc) - If the image has three dimensions then the patch is only in 2D and the neighborhood extent in time is only 5. - If the image has several channel (color images), the distance between the two patch is computed using - all the channels. - The greater the patch is the best is the result. - Lambda parameter is function of the size of the patch size. The automatic Lambda parameter is taken - in the Chi2 table at a significiance level of 0.01. This diffear from the original paper [1]. - The weighted average becomes then: - \f$$ \hat{f}(x,y) = \sum_{x',y'} \frac{1}{Z} exp(\frac{P(x,y)-P(x',y')}{2 \lambda \sigma^2}) f(x',y') $$\f - where \f$ P(x,y) $\f denotes the patch in (x,y) location. - - An a priori is also used to increase the speed of the algorithm in the spirit of Sapiro et al. SPletter dec 05 - - This very basic version of the Non-Local Means algorithm provides an output image which contains - some residual noise with a relatively small variance (\f$\sigma<5$\f). - - [1] A non-local algorithm for image denoising - Buades, A.; Coll, B.; Morel, J.-M.; - Computer Vision and Pattern Recognition, 2005. CVPR 2005. IEEE Computer Society Conference on - Volume 2, 20-25 June 2005 Page(s):60 - 65 vol. 2 -**/ -CImg get_nlmeans( int patch_size=1, double lambda=-1, double alpha=3 ,double sigma=-1, int sampling=1) const { - return CImg(*this).nlmeans(patch_size,lambda,alpha,sigma,sampling); -} - -#endif /* cimg_plugin_nlmeans */ diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/patchmatch.h b/applications/plugins/CImgPlugin/extlibs/CImg/plugins/patchmatch.h deleted file mode 100644 index 1ef229a26ca..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/patchmatch.h +++ /dev/null @@ -1,227 +0,0 @@ -/* - # - # File : PatchMatch_plugin.h - # ( C++ header file - CImg plug-in ) - # - # Description : Plugin implementing the Patch Match algorithm to use - # with the CImg library. - # ( http://cimg.eu ) - # - # Copyright : Olivier D'Hondt - # (https://sites.google.com/site/dhondtolivier/) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#ifndef cimg_plugin_patchmatch -#define cimg_plugin_patchmatch - -// Visualize optical flow maps with HSV color coding. -CImg get_vizFlow(const float cutVal = 0) const { - CImg res(width(),height(),1,3); - - // Normalizing offset magnitude - CImg mag = get_norm(); - if (cutVal) mag.cut(0,cutVal); - mag/=mag.max(); - - // Filling HSV values - cimg_forXY(*this,x,y) { - const float - xx = (float)(-(*this)(x,y,0)), - yy = (float)(-(*this)(x,y,1)), - H = (float)cimg::max(180*((std::atan2(yy,xx)/cimg::PI) + 1.0),0.0), - S = mag(x,y), - V = 1.0f; - res(x,y,0) = H; - res(x,y,1) = S; - res(x,y,2) = V; - } - - return res.HSVtoRGB(); -} - -// Distance between two patches -static T distPatch(const CImg &img0, const CImg &img1, - const int x0, const int y0, - const int x1, const int y1, - const int pSize) { - T d2 = 0; - cimg_forC(img0,c) for (int y = 0; y < pSize; ++y) for (int x = 0; x < pSize; ++x) { - const T d = (img0(x0 + x, y0 + y, c) - img1(x1 + x, y1 + y, c)); - d2 += d*d; - } - return d2; -} - -// Patch match algorithm -template -CImg& patchMatch(const CImg &img0, const CImg &img1, - int patchSize, const int nIter = 2, - CImgDisplay *const disp=0) { - if (img0.spectrum() != img1.spectrum()) - throw CImgInstanceException("Images must have the same number of channels."); - - if (!patchSize % 2){ - ++patchSize; - cimg::warn("Input patch size is even, adding 1."); - } - const int - w0 = img0.width(), - h0 = img0.height(), - w1 = img1.width(), - h1 = img1.height(), - nChannels = img0.spectrum(); - - CImg imgrec, visu0, visu1; // used only for display purpose - if (disp) { - imgrec.assign(img0.width(),img0.height(),1,img0.spectrum(),0); - visu0 = img0.get_resize(-100,-100,1,3); - visu1 = img1.get_resize(-100,-100,1,3); - } - - const int P = patchSize, H = P/2; - - // Zero padding borders - CImg img0big(w0 + 2*H, h0 + 2*H, 1, nChannels, 0); - CImg img1big(w1 + 2*H, h1 + 2*H, 1, nChannels, 0); - - // Try to penalize border patches - img0big.rand(0,255); - img1big.rand(0,255); - - img0big.draw_image(H, H, 0, 0, img0); - img1big.draw_image(H, H, 0, 0, img1); - - CImg off(w0, h0, 1, 2, 0); - CImg minDist(w0, h0, 1, 1, 0); - - // Initialize with random offsets - cimg_forXY(off, x0, y0){ - int x1 = (int)((w1 - 1) * cimg::rand()); - int y1 = (int)((h1 - 1) * cimg::rand()); - off(x0, y0, 0) = x1 - x0; - off(x0, y0, 1) = y1 - y0; - minDist(x0, y0) = distPatch(img0big, img1big, x0, y0, x1, y1, P); - } - - int xStart, yStart, xFinish, yFinish, inc; - for (int n = 0; n < nIter; ++n) { - std::fprintf(stderr,"Iteration %d\n",n + 1); - - // at odd iterations, reverse scan order - if (!(n%2)) { xStart = yStart = inc = 1; xFinish = w0; yFinish = h0; } - else { xStart = w0 - 2; yStart = h0 - 2; xFinish = yFinish = inc = -1; } - - for (int y = yStart; y != yFinish; y=y+inc) - for (int x = xStart; x != xFinish; x=x+inc) { - // Propagation - Tt d2 = (Tt)0; - int x1 = x + off(x - inc,y,0), y1 = y + off(x - inc,y,1); - if(x1 >= 0 && x1 < w1 && y1 >= 0 && y1 < h1){ // propagate only if inside img1 bounds - d2 = distPatch(img0big, img1big, x, y, x1, y1, P); - if (d2= 0 && x1 < w1 && y1 >= 0 && y1 < h1) { // propagate only if inside img1 bounds - d2 = distPatch(img0big, img1big, x, y, x1, y1, P); - if (d2= 1 && wSizY >= 1); - // If a pointer to a CImgDisplay is passed as the last argument - // the output of the algorithm is displayed as an animation - // !! It slows down the algorithm a lot !! - if (disp) { - if (x%(w0 - 1)==0) - disp->display((visu0, - imgrec.reconstruct(img1, off).get_normalize(0,255).resize(-100,-100,1,3), - off.get_vizFlow(100), - visu1)).set_title("Iteration %d",n + 1); - if (disp->is_resized()) disp->resize(); - } - } - } - return off.move_to(*this); -} - -// Reconstruct an image from an offset map and a query image -template -CImg & reconstruct(const CImg &qimg, const CImg &off) { - if(spectrum() != qimg.spectrum()) - throw CImgInstanceException("Images must have the same number of channels."); - if(width() != off.width() || height() != off.height()) - throw CImgInstanceException("Offset map must have the same dimensions as input image."); - cimg_forXY(off,x,y) { - int qx = x + off(x, y, 0); - int qy = y + off(x, y, 1); - cimg_forC(qimg,c) (*this)(x,y,c) = qimg(qx,qy, c); - } - return (*this); -} - -template -CImg get_reconstruct(const CImg &qimg, const CImg &off) const { - return CImg(*this, false).reconstruct(qimg, off); -} - -#endif /* cimg_plugin_patchmatch */ diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/skeleton.h b/applications/plugins/CImgPlugin/extlibs/CImg/plugins/skeleton.h deleted file mode 100644 index ba90a4b352a..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/skeleton.h +++ /dev/null @@ -1,587 +0,0 @@ -/* - # - # File : skeleton.h - # ( C++ header file - CImg plug-in ) - # - # Description : CImg plugin that implements the computation of the Hamilton-Jacobi skeletons - # using Siddiqi algorithm with the correction proposed by Torsello, - # as described in : - # - # [SBTZ02] K. Siddiqi, S. Bouix, A. Tannenbaum and S.W. Zucker. Hamilton-Jacobi Skeletons - # International Journal of Computer Vision, 48(3):215-231, 2002 - # - # [TH03] A. Torsello and E. R. Hancock. Curvature Correction of the Hamilton-Jacobi Skeleton - # IEEE Computer Vision and Pattern Recognition, 2003 - # - # [BST05] S. Bouix, K. Siddiqi and A. Tannenbaum. Flux driven automatic centerline - # extraction. Medical Image Analysis, 9:209-221, 2005 - # - # IMPORTANT WARNING : You must include STL's before plugin inclusion to make it working ! - # - # Copyright : Francois-Xavier Dupe - # ( http://www.greyc.ensicaen.fr/~fdupe/ ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ -#ifndef cimg_plugin_skeleton -#define cimg_plugin_skeleton - -/** - * Compute the flux of the gradient - * @param grad the gradient of the distance function - * @param sY the sampling size in Y - * @param sZ the sampling size in Z - * @return the flux - */ -CImg get_flux(const CImgList & grad, - const float sY=1.0f, const float sZ=1.0f) const { - - int stop = 0; // Stop flag - float f = 0; // The current flux - int count = 0; // Counter - CImg flux(width(),height(),depth(),1,0); - - cimg_forXYZ((*this),x,y,z) { - if (!(*this)(x,y,z)) continue; // If the point is the background - - // Look at the neigthboorhound and compute the flux - stop = 0; - f = 0; - count = 0; - - for (int k = -1; k<=1; ++k) - for (int l = -1; l<= 1; ++l) - for (int m = -1; m<= 1; ++m) { - if (stop==1) continue; - - // Protection - if ((x + k<0) || (x + k>=width()) || (y + l<0) || (y + l>=height()) || - (z + m<0) || (z + m>=depth()) || (k==0 && l==0 && m==0)) continue; - ++count; - - // Test if the point is in the interior - if ((*this)(x + k,y + l,z + m)==0) { stop = 1; continue; } - - // Compute the flux - f+=(grad(0,x + k,y + l,z + m)*k + grad(1,x + k,y + l,z + m)*l/sY + grad(2,x + k,y + l,z + m)*m/sZ)/ - std::sqrt((float)(k*k + l*l + m*m)); - } - - // Update - if (stop==1 || count==0) flux(x,y,z) = 0; - else flux(x,y,z) = f/count; - } - - return flux; -} - -/** - * Definition of a point with his flux value - */ -struct _PointFlux { - int pos [3]; - float flux; - float dist; -}; - -/** - * Class for the priority queue - */ -class _compare_point { - /** - * Create medial curves - */ - bool curve; - - public: - _compare_point(const bool curve=false) { this->curve = curve; } - - bool operator()(const _PointFlux & p1, const _PointFlux & p2) const { - if (curve) { - if (p1.dist>p2.dist) return true; - else if (p1.dist==p2.dist && p1.fluxp2.dist) return true; - } - return false; - } -}; - -/** - * Compute the log-density using the algorithm from Torsello - * @param dist the distance map - * @param grad the gradient of the distance map, e.g. the flux - * @param flux the divergence map - * @param delta the threshold for the division - * @return the logdensity \rho - */ -CImg get_logdensity(const CImg & dist, - const CImgList & grad, - const CImg & flux, float delta = 0.1) const { - std::priority_queue< _PointFlux, std::vector<_PointFlux>, _compare_point > pqueue(true); - CImg logdensity(width(),height(),depth(),1,0); - - // 1 - Put all the pixel inside the priority queue - cimg_forXYZ(dist,x,y,z) if (dist(x,y,z)!=0) { - _PointFlux p; - p.pos[0] = x; - p.pos[1] = y; - p.pos[2] = z; - p.flux = 0; - p.dist = dist(x,y,z); - pqueue.push(p); - } - - // 2 - Compute the logdensity - while (!pqueue.empty()) { - _PointFlux p = pqueue.top(); - pqueue.pop(); - - const float - Fx = grad(0,p.pos[0],p.pos[1],p.pos[2]), - Fy = grad(1,p.pos[0],p.pos[1],p.pos[2]), - Fz = grad(2,p.pos[0],p.pos[1],p.pos[2]); - - logdensity(p.pos[0],p.pos[1],p.pos[2]) = logdensity.linear_atXYZ(p.pos[0] - Fx,p.pos[1] - Fy,p.pos[2] - Fz) - - 0.5f * (flux(p.pos[0],p.pos[1],p.pos[2]) + flux.linear_atXYZ(p.pos[0] - Fx,p.pos[1] - Fy,p.pos[2] - Fz)); - - const float tmp = 1.0f - (1.0f - std::fabs(Fx)) * (1.0f - std::fabs(Fy)) * (1.0f - std::fabs(Fz)); - if (tmp>delta) logdensity(p.pos[0],p.pos[1],p.pos[2])/=tmp; - else if (delta<1) logdensity(p.pos[0],p.pos[1],p.pos[2]) = 0; - } - - return logdensity; -} - -/** - * Computed the corrected divergence map using Torsello formula and idea - * @param logdensity the log density map - * @param grad the gradient of the distance map - * @param flux the flux using siddiqi formula - * @param delta the discrete step - * @return the corrected divergence map - */ -CImg get_corrected_flux(const CImg & logdensity, - const CImgList & grad, - const CImg & flux, - float delta = 1.0) const { - - CImg corr_map(width(),height(),depth(),1,0); - cimg_forXYZ(corr_map,x,y,z) { - const float - Fx = grad(0,x,y,z), - Fy = grad(1,x,y,z), - Fz = grad(2,x,y,z); - corr_map(x,y,z) = - (logdensity(x,y,z) - - logdensity.linear_atXYZ(x - Fx,y - Fy,z - Fz)) * expf(logdensity(x,y,z) - 0.5f * delta) + - 0.5f * ( flux.linear_atXYZ(x - Fx,y - Fy,z - Fz)*expf(logdensity.linear_atXYZ(x - Fx,y - Fy,z - Fz)) + - flux(x,y,z)*expf(logdensity(x,y,z))); - } - - return corr_map; -} - -/** - * Test if a point is simple using Euler number for 2D case - * or using Malandain criterion for 3D case - * @param img the image - * @param x the x coordinate - * @param y the y coordinate - * @param z the z coordinate - * @return true if simple - */ -bool _isSimple (const CImg & img, int x, int y, int z ) const { - if (img.depth()==1) { // 2D case - int V = 0, E = 0; // Number of vertices and edges - - for (int k = -1; k<=1; ++k) - for (int l = -1; l<=1; ++l) { - // Protection - if (x+k<0 || x+k>=img.width() || y+l<0 || y+l>=img.height()) continue; - - // Count the number of vertices - if (img(x + k,y + l)!=0 && !(k==0 && l==0)) { - ++V; - - // Count the number of edges - for (int k1 = -1; k1<=1; ++k1) - for (int l1 = -1; l1<=1; ++l1) { - // Protection - if (x + k + k1<0 || x + k + k1>=img.width() || y + l + l1<0 || y + l + l1>=img.height()) continue; - - if (!(k1==0 && l1==0) && img(x + k + k1,y + l + l1)!=0 && k + k1>-2 && l + l1>-2 && - k + k1<2 && l + l1<2 && !(k + k1==0 && l + l1==0)) - ++E; - } - } - } - - // Remove the corner if exists - if (x - 1>=0 && y - 1>=0 && img(x - 1,y - 1)!=0 && img(x,y - 1)!=0 && img(x - 1,y)!=0) E-=2; - if (x - 1>=0 && y + 1=0 && img(x + 1,y - 1)!=0 && img(x,y - 1)!=0 && img(x + 1,y)!=0) E-=2; - if (x + 1 visit(3,3,3,1,0); // Visitor table - int C_asterix = 0, C_bar = 0, count = 0; - visit(1,1,1) = -1; - - // Compute C^* - - // Seeking for a component - for (int k = -1; k<=1; ++k) - for (int l = -1; l<=1; ++l) - for (int m = -1; m<=1; ++m) { - int label = 0; - - // Protection - if (x + k<0 || x + k>=img.width() || - y + l<0 || y + l>=img.height() || - z + m<0 || z + m>=img.depth() || - (k==0 && l==0 && m==0)) continue; - - if (visit(1 + k,1 + l,1 + m)==0 && img(x + k,y + l,z + m)!=0) { - // Look after the neightbor - for (int k1 = -1; k1<=1; ++k1) - for (int l1 = -1; l1<=1; ++l1) - for (int m1 = -1; m1<=1; ++m1) { - // Protection - if (x + k + k1<0 || x + k + k1>=img.width() || - y + l + l1<0 || y + l + l1>=img.height() || - z + m + m1<0 || z + m + m1>=img.depth() || - k + k1>1 || k + k1<-1 || - l + l1>1 || l + l1<-1 || - m + m1>1 || m + m1<-1 ) continue; - - // Search for a already knew component - if (visit(1 + k + k1,1 + l + l1,1 + m + m1)>0 && - img(x + k + k1,y + l + l1,z + m + m1)!=0) { - if (label==0) label = visit(1 + k + k1,1 + l + l1,1 + m + m1); - else if (label!=visit(1 + k + k1,1 + l + l1,1 + m + m1)) { - // Meld component - --C_asterix; - - int C = visit(1 + k + k1,1 + l + l1,1 + m + m1); - cimg_forXYZ(visit,a,b,c) if (visit(a,b,c)==C) visit(a,b,c) = label; - } - } - } - - // Label the point - if (label==0) { - // Find a new component - ++C_asterix; - ++count; - visit(1 + k ,1 + l,1 + m) = count; - } else visit(1 + k,1 + l,1 + m) = label; - } - } - - if (C_asterix!=1) return false; - - // Compute \bar{C} - - // Reinit visit - visit.fill(0); - visit(1,1,1) = -1; - - // Seeking for a component - - // Look at X-axis - for (int k = -1; k<=1; ++k) { - if (x + k<0 || x + k>=img.width()) continue; - - if (img(x + k,y,z)==0 && visit(1 + k,1,1)==0) { - ++C_bar; - ++count; - visit(1 + k,1,1) = count; - - // Follow component - for (int l = -1; l<=1; ++l) { - if (y + l=0 && img(x + k,y + l,z)==0 && visit(1 + k,1 + l,1)==0) - visit(1 + k,1 + l,1) = count; - if (z + l=0 && img(x + k,y,z + l)==0 && visit(1 + k,1,1 + l)==0) - visit(1 + k,1,1 + l) = count; - } - } - } - - // Look at Y-axis - for (int k = -1; k<=1; ++k) { - if (y + k<0 || y + k>=img.height()) continue; - - if (img(x,y + k,z)==0 && visit(1,1 + k,1)==0) { - int label = 0; - ++C_bar; - ++count; - visit(1,1 + k,1) = count; - label = count; - - // Follow component - for (int l = -1; l<=1; ++l) { - if (l==0) continue; - - if (x + l=0 && img(x + l,y + k,z)==0) { - if (visit(1 + l,1 + k,1)!=0) { - if (label!=visit(1 + l,1 + k,1)) { - // Meld component - --C_bar; - - int C = visit(1 + l,1 + k,1); - cimg_forXYZ(visit,a,b,c) - if (visit(a,b,c)==C) visit(a,b,c) = label; - } - } else visit(1 + l,1 + k,1) = label; - } - - if (z + l=0 && img(x,y + k,z + l)==0) { - if (visit(1,1 + k,1 + l)!=0) { - if (label!=visit(1,1 + k,1 + l)) { - // Meld component - --C_bar; - - int C = visit(1,1 + k,1 + l); - cimg_forXYZ(visit,a,b,c) - if (visit(a,b,c)==C) visit(a,b,c) = label; - } - } else visit(1,1 + k,1 + l) = label; - } - } - } - } - - // Look at Z-axis - for (int k = -1; k<=1; ++k) { - if (z + k<0 || z + k>=img.depth()) continue; - - if (img(x,y,z + k)==0 && visit(1,1,1 + k)==0) { - int label = 0; - ++C_bar; - ++count; - visit(1,1,1 + k) = count; - label = count; - - // Follow component - for (int l = -1; l<=1; ++l) { - if (l==0) continue; - - if (x + l=0 && img(x + l,y,z + k)==0) { - if (visit(1 + l,1,1 + k)!=0) { - if (label!=visit(1 + l,1,1 + k)) { - // Meld component - --C_bar; - - int C = visit(1 + l,1,1 + k); - cimg_forXYZ(visit,a,b,c) - if (visit(a,b,c)==C) visit(a,b,c) = label; - } - } else visit(1 + l,1,1 + k) = label; - } - - if (y + l=0 && img(x,y + l,z + k)==0) { - if (visit(1,1 + l,1 + k)!=0) { - if (label!=visit(1,1 + l,1 + k)) { - // Meld component - --C_bar; - - int C = visit(1,1 + l,1 + k); - cimg_forXYZ(visit,a,b,c) - if (visit(a,b,c)==C) visit(a,b,c) = label; - } - } else visit(1,1 + l,1 + k) = label; - } - } - } - } - if (C_bar==1) return true; - } - - return false; -} - -/** - * Test if a point is a end point - * @param img the image - * @param label the table of labels - * @param curve set it to true for having medial curve - * @param x the x coordinate - * @param y the y coordinate - * @param z the z coordinate - * @return true if simple - */ -bool _isEndPoint(const CImg & img, const CImg & label, - const bool curve, const int x, const int y, const int z) const { - if (label(x,y,z)==1) return true; - - if ((!curve) && (img.depth()!=1)) { // 3D case with medial surface - // Use Pudney specification with the 9 plans - const int plan9 [9][8][3] = - { { {-1,0,-1}, {0,0,-1}, {1,0,-1}, {-1,0,0}, {1,0,0}, {-1,0,1}, {0,0,1}, {1,0,1} }, // Plan 1 - { {-1,1,0}, {0,1,0}, {1,1,0}, {-1,0,0}, {1,0,0}, {-1,-1,0}, {0,-1,0}, {1,-1,0} }, // Plan 2 - { {0,-1,-1}, {0,0,-1}, {0,1,-1}, {0,-1,0}, {0,1,0}, {0,-1,1}, {0,0,1}, {0,1,1} }, // Plan 3 - { {1,1,1}, {0,1,0}, {-1,1,-1}, {1,0,1}, {-1,0,-1}, {-1,-1,-1}, {0,-1,0}, {1,-1,1} }, // Plan 4 - { {-1,1,1}, {0,1,0}, {1,1,-1}, {-1,0,1}, {1,0,-1}, {-1,-1,1}, {0,-1,0}, {1,-1,-1} }, // Plan 5 - { {-1,1,1}, {0,1,1}, {1,1,1}, {-1,0,0}, {1,0,0}, {-1,-1,-1}, {0,-1,-1}, {1,-1,-1} }, // Plan 6 - { {-1,1,-1}, {0,1,-1}, {1,1,-1}, {-1,0,0}, {1,0,0}, {-1,-1,1}, {0,-1,1}, {1,-1,1} }, // Plan 7 - { {-1,1,-1}, {-1,1,0}, {-1,1,1}, {0,0,-1}, {0,0,1}, {1,-1,-1}, {1,-1,0}, {1,-1,1} }, // Plan 8 - { {1,1,-1}, {1,1,0}, {1,1,1}, {0,0,-1}, {0,0,1}, {-1,-1,-1}, {-1,-1,0}, {-1,-1,1} } // Plan 9 - }; - - // Count the number of neighbors on each plan - for (int k = 0; k<9; ++k) { - int count = 0; - - for (int l = 0; l<8; ++l) { - if (x + plan9[k][l][0]<0 || x + plan9[k][l][0]>=img.width() || - y + plan9[k][l][1]<0 || y + plan9[k][l][1]>=img.height() || - z + plan9[k][l][2]<0 || z + plan9[k][l][2]>=img.depth()) continue; - - if (img(x + plan9[k][l][0],y + plan9[k][l][1],z + plan9[k][l][2])!=0) ++count; - } - - if (count<2) return true; - } - } else { // 2D or 3D case with medial curve - int isb = 0; - - for (int k = -1; k<=1; ++k) - for (int l = -1; l<=1; ++l) - for (int m = -1; m<=1; ++m) { - // Protection - if (x + k<0 || x + k>=img.width() || - y + l<0 || y + l>=img.height() || - z + m<0 || z + m>=img.depth()) continue; - - if (img(x + k,y + l,z + m)!=0) ++isb; - } - - if (isb==2) return true; // The pixel with one neighbor - } - - // Else it's not... - return false; -} - -/** - * Compute the skeleton of the shape using Hamilton-Jacobi scheme - * @param flux the flux of the distance gradient - * @param dist the euclidean distance of the object - * @param curve create or not medial curve - * @param thres the threshold on the flux - * @return the skeleton - */ -CImg get_skeleton (const CImg & flux, - const CImg & dist, const bool curve, const float thres) const { - CImg - skeleton(*this), // The skeleton - label(width(),height(),depth(),1,0), // Save label - count(width(),height(),depth(),1,0); // A counter for the queue - std::priority_queue< _PointFlux, std::vector<_PointFlux>, _compare_point > pqueue(curve); - int isb = 0; - - // 1 - Init get the bound points - cimg_forXYZ(*this,x,y,z) { - if (skeleton(x,y,z)==0) continue; - - // Test bound condition - isb = 0; - for (int k = -1; k<=1; ++k) - for (int l = -1; l<=1; ++l) - for (int m = -1; m<=1; ++m) { - // Protection - if (x + k<0 || x + k>=width() || - y + l<0 || y + l>=height() || - z + m<0 || z + m>=depth()) continue; - if (skeleton(x + k,y + l,z + m)==0) isb = 1; - } - - if (isb==1 && _isSimple(skeleton,x,y,z)) { - _PointFlux p; - p.pos[0] = x; - p.pos[1] = y; - p.pos[2] = z; - p.flux = flux(x,y,z); - p.dist = dist(x,y,z); - pqueue.push(p); - count(x,y,z) = 1; - } - } - - // 2 - Compute the skeleton - while (!pqueue.empty()) { - _PointFlux p = pqueue.top(); // Get the point with the max flux - pqueue.pop(); // Remove the point from the queue - count(p.pos[0],p.pos[1],p.pos[2]) = 0; // Reinit counter - - // Test if the point is simple - if (_isSimple(skeleton,p.pos[0],p.pos[1],p.pos[2])) { - if ((! _isEndPoint(skeleton,label,curve,p.pos[0],p.pos[1],p.pos[2])) || p.flux>thres) { - skeleton(p.pos[0],p.pos[1],p.pos[2]) = 0; // Remove the point - - for (int k = -1; k<=1; ++k) - for (int l = -1; l<=1; ++l) - for (int m = -1; m<=1; ++m) { - // Protection - if (p.pos[0] + k<0 || p.pos[0] + k>= width() || - p.pos[1] + l<0 || p.pos[1] + l>= height() || - p.pos[2] + m<0 || p.pos[2] + m>= depth()) continue; - if (skeleton(p.pos[0] + k,p.pos[1] + l,p.pos[2] + m)!=0 && - count(p.pos[0] + k,p.pos[1] + l,p.pos[2] + m)<1 && - _isSimple(skeleton,p.pos[0] + k,p.pos[1] + l,p.pos[2] + m)) { - _PointFlux p1; - p1.pos[0] = p.pos[0] + k; - p1.pos[1] = p.pos[1] + l; - p1.pos[2] = p.pos[2] + m; - p1.flux = flux(p.pos[0] + k,p.pos[1] + l,p.pos[2] + m); - p1.dist = dist(p.pos[0] + k,p.pos[1] + l,p.pos[2] + m); - pqueue.push(p1); - count(p.pos[0] + k,p.pos[1] + l,p.pos[2] + m) = 1; - } - } - } else label(p.pos[0],p.pos[1],p.pos[2]) = 1; // Mark the point as skeletal - } - } - - return skeleton; -} - -/** - * In place version of get_skeleton - */ -CImg skeleton(const CImg & flux, - const CImg & dist, bool curve ,float thres) { - return get_skeleton(flux,dist,curve,thres).move_to(*this); -} - -#endif /* cimg_plugin_skeleton */ diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/tiff_stream.h b/applications/plugins/CImgPlugin/extlibs/CImg/plugins/tiff_stream.h deleted file mode 100644 index d7ab07c8eb7..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/tiff_stream.h +++ /dev/null @@ -1,192 +0,0 @@ -/* -# -# File : tiff_stream.h -# ( C++ header file - CImg plug-in ) -# -# Description : This CImg plug-in provide functions to load and save tiff images -# from std::istream/ to std::ostream -# This file is a part of the CImg Library project. -# ( http://cimg.eu ) -# -# Copyright : Wolf Blecher -# ( Wolf.Blecher(at)sirona.com ) -# -# License : CeCILL v2.0 -# ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) -# -# This software is governed by the CeCILL license under French law and -# abiding by the rules of distribution of free software. You can use, -# modify and/ or redistribute the software under the terms of the CeCILL -# license as circulated by CEA, CNRS and INRIA at the following URL -# "http://www.cecill.info". -# -# As a counterpart to the access to the source code and rights to copy, -# modify and redistribute granted by the license, users are provided only -# with a limited warranty and the software's author, the holder of the -# economic rights, and the successive licensors have only limited -# liability. -# -# In this respect, the user's attention is drawn to the risks associated -# with loading, using, modifying and/or developing or reproducing the -# software by the user in light of its specific status of free software, -# that may mean that it is complicated to manipulate, and that also -# therefore means that it is reserved for developers and experienced -# professionals having in-depth computer knowledge. Users are therefore -# encouraged to load and test the software's suitability as regards their -# requirements in conditions enabling the security of their systems and/or -# data to be ensured and, more generally, to use and operate it in the -# same conditions as regards security. -# -# The fact that you are presently reading this means that you have had -# knowledge of the CeCILL license and that you accept its terms. -# -*/ - -/*----------------------------------------------------------------------------------- - -IMPORTANT NOTE : - -You *need* to include the following lines in your own code to use this plugin: - -#include "tiffio.h" -#include "tiffio.hxx" - -You *need* to link your code with the libtiff and libtiffxx libraries as well. - -------------------------------------------------------------------------------------*/ - -#ifndef cimg_use_tiff -#error cimg_use_tiff not defined -#endif - -#ifndef cimg_plugin_tiff_stream -#define cimg_plugin_tiff_stream - -#include - -///////////////////////////////////////////////////////////////// -// -// Define main CImg plugin functions. -// (you should use these functions only in your own code) -// -///////////////////////////////////////////////////////////////// - -//! Save image as a TIFF file. -/** - \param tiffOutStream std::ostream, where to write the image to - \param compression_type Type of data compression. - Can be { 1=None | 2=CCITTRLE | 3=CCITTFAX3 | 4=CCITTFAX4 | 5=LZW | 6=JPEG }. - \note - - libtiff support is enabled by defining the precompilation - directive \c cimg_use_tiff. - - When libtiff is enabled, 2D and 3D (multipage) several - channel per pixel are supported for - char,uchar,short,ushort,float and \c double pixel types. -**/ -const CImg& save_tiff(std::ostream *tiffOutStream, const unsigned int compression_type=0) const { - if (!tiffOutStream->good()) - { - throw CImgArgumentException(_cimg_instance - "save_tiff(): tiffstream is not good!", - cimg_instance); - } - - if (is_empty()) - { - throw CImgArgumentException(_cimg_instance - "Not allowed to write empty images to stream", - cimg_instance - ); - } - - TIFF *tif = TIFFStreamOpen("MemTiff", tiffOutStream); - if (tif) - { - cimg_forZ(*this,z) get_slice(z)._save_tiff(tif,z,z,compression_type,0,0); - tiffOutStream->flush(); - TIFFClose(tif); - } - else - { - throw CImgIOException(_cimg_instance - "save_tiff(): Failed to stream for writing.", - cimg_instance); - } - - return *this; -} - -//! Load images from a TIFF file. -/** - \param tiffInStream std::istream to read data from. - \param first_frame Index of first image frame to read. - \param last_frame Index of last image frame to read. - \param step_frame Step applied between each frame. -**/ -CImg& load_tiff(std::istream* tiffInStream, - const unsigned int first_frame=0, const unsigned int last_frame=~0U, - const unsigned int step_frame=1) -{ - const unsigned int - nfirst_frame = first_frame=nb_images || (nlast_frame!=~0U && nlast_frame>=nb_images)) - { - cimg::warn("load_tiff(): Invalid specified frame range is [%u,%u] (step %u) " - "since stream contains %u image(s).", - nfirst_frame,nlast_frame,nstep_frame,nb_images); - } - - if (nfirst_frame>=nb_images) - { - return assign(); - } - - if (nlast_frame>=nb_images) - { - nlast_frame = nb_images - 1; - } - TIFFSetDirectory(tif,0); - CImg frame; - for (unsigned int l = nfirst_frame; l<=nlast_frame; l+=nstep_frame) { - frame._load_tiff(tif,l,0,0); - if (l==nfirst_frame) - assign(frame._width,frame._height,1 + (nlast_frame - nfirst_frame)/nstep_frame,frame._spectrum); - if (frame._width>_width || frame._height>_height || frame._spectrum>_spectrum) - resize(cimg::max(frame._width,_width),cimg::max(frame._height,_height), - -100,cimg::max(frame._spectrum,_spectrum),0); - draw_image(0,0,(l - nfirst_frame)/nstep_frame,frame); - } - TIFFClose(tif); - } - else - { - throw CImgIOException(_cimg_instance - "load_tiff(): Failed to read data from stream", - cimg_instance); - } - - return *this; -} - -//! Load a multi-page TIFF file \newinstance. -static CImg get_load_tiff(std::istream* tiffInStream, - const unsigned int first_frame=0, const unsigned int last_frame=~0U, - const unsigned int step_frame=1) -{ - return CImg().load_tiff(tiffInStream,first_frame,last_frame,step_frame); -} - -// End of the plug-in -//------------------- -#endif /* cimg_plugin_tiff_stream */ diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/tinymatwriter.h b/applications/plugins/CImgPlugin/extlibs/CImg/plugins/tinymatwriter.h deleted file mode 100644 index 34547209cd0..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/tinymatwriter.h +++ /dev/null @@ -1,109 +0,0 @@ -/* -# -# File : tinymatwriter.h -# ( C++ header file - CImg plug-in ) -# -# Description : This CImg plug-in provide functions to write image as -# Matlab MAT files -# ( http://cimg.eu ) -# -# Copyright : Jan W. Krieger -# ( j.krieger(at)dkfz.de jan(at)jkrieger.de ) -# -# License : CeCILL v2.0 -# ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) -# -# This software is governed by the CeCILL license under French law and -# abiding by the rules of distribution of free software. You can use, -# modify and/ or redistribute the software under the terms of the CeCILL -# license as circulated by CEA, CNRS and INRIA at the following URL -# "http://www.cecill.info". -# -# As a counterpart to the access to the source code and rights to copy, -# modify and redistribute granted by the license, users are provided only -# with a limited warranty and the software's author, the holder of the -# economic rights, and the successive licensors have only limited -# liability. -# -# In this respect, the user's attention is drawn to the risks associated -# with loading, using, modifying and/or developing or reproducing the -# software by the user in light of its specific status of free software, -# that may mean that it is complicated to manipulate, and that also -# therefore means that it is reserved for developers and experienced -# professionals having in-depth computer knowledge. Users are therefore -# encouraged to load and test the software's suitability as regards their -# requirements in conditions enabling the security of their systems and/or -# data to be ensured and, more generally, to use and operate it in the -# same conditions as regards security. -# -# The fact that you are presently reading this means that you have had -# knowledge of the CeCILL license and that you accept its terms. -# -*/ - -/*----------------------------------------------------------------------------------- - -IMPORTANT NOTE : - -You *need* to compile tinymatwriter.cpp and link the result to your project and -include "tinymatwriter.h" berfore inclusing CIMg or this plugin! - -This library is available from: - https://github.com/jkriege2/TinyMAT -------------------------------------------------------------------------------------*/ - - - -#ifndef cimg_plugin_tinymatwriter -#define cimg_plugin_tinymatwriter - -#include - -///////////////////////////////////////////////////////////////// -// -// Define main CImg plugin functions. -// (you should use these functions only in your own code) -// -///////////////////////////////////////////////////////////////// - -//! Save image as a MAT file. -/** - \param filename filename of the output file - \note TinyMATWriter supports signed/unsigned int with 8/16/32/64 bits, double, float and bool as pixel types! -**/ -const CImg& save_tinymat(const char *filename) const { - - TinyMATWriterFile* mat=TinyMATWriter_open(filename); - if (mat) { - int32_t size_x=width(); - int32_t size_y=height(); - int32_t size_z=depth(); - int32_t size_c=spectrum(); - - int32_t sizes[4]={size_x, size_y, size_z, size_c}; - uint32_t dims=4; - if (size_c==1) { - dims=3; - if (size_z==1) { - dims=2; - if (size_y==1) { - dims=1; - } - } - } - - TinyMATWriter_writeMatrixND_rowmajor(mat, "CImg_image", data(), sizes, dims); - TinyMATWriter_close(mat); - } else { - throw CImgIOException(_cimg_instance - "save_tinymat(): Failed to open file.", - cimg_instance); - } - - return *this; -} - - -// End of the plug-in -//------------------- -#endif /* cimg_plugin_tinymatwriter */ diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/vrml.h b/applications/plugins/CImgPlugin/extlibs/CImg/plugins/vrml.h deleted file mode 100644 index f5c6b936b97..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/vrml.h +++ /dev/null @@ -1,894 +0,0 @@ -/* - # - # File : vrml.h - # ( C++ header file - CImg plug-in ) - # - # Description : CImg plugin that provide functions to load/save VRML files. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : Greg Rami - # ( greg.rami36 (at) gmail.com ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -/*----------------------------------------------------------------------------------- - - IMPORTANT NOTE : - - You *need* to include the following lines in your own code to use this plugin : - - #include - #include - #include - #include - -------------------------------------------------------------------------------------*/ - -#ifndef cimg_plugin_vrml -#define cimg_plugin_vrml - -//! Load a 3d object from a .VRML file. -template -CImg& load_vrml(const char *const filename, CImgList& primitives, CImgList& colors) { - return _load_vrml(0,filename,primitives,colors); -} - -//! Load a 3d object from a .VRML file. -template -static CImg get_load_vrml(const char *const filename, CImgList& primitives, CImgList& colors) { - return CImg().load_vrml(filename,primitives,colors); -} - -//! Load a 3d object from a .VRML file. -template -CImg& load_vrml(std::FILE *const file, CImgList& primitives, CImgList& colors) { - return _load_vrml(file,0,primitives,colors); -} - -//! Load a 3d object from a .VRML file. -template -static CImg get_load_vrml(std::FILE *const file, CImgList& primitives, CImgList& colors) { - return CImg().load_vrml(file,primitives,colors); -} - -//! Load a 3d object from a .VRML file (internal). -template -CImg& _load_vrml(std::FILE *const file, const char *const filename,CImgList& primitives, CImgList& colors) { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "load_vrml() : Specified filename is (null).", - cimg_instance); - std::FILE *const nfile = file?file:cimg::fopen(filename,"r"); - - char line[1024] = { 0 }; - int err; - - // Skip comments, and read the first node. - do { err = std::fscanf(nfile,"%65535[^\n] ",line); } while (!err || (err==1 && *line=='#')); - - // Check for a first valid vrml valid node. - if (cimg::strncasecmp(line,"Shape",5) && - cimg::strncasecmp(line,"Transform",9) && - cimg::strncasecmp(line,"NavigationInfo",14) && - cimg::strncasecmp(line,"Billboard",9)) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : VRML nodes not found in file '%s'.", - cimg_instance,filename?filename:"(FILE*)"); - } - - // Look for the Shape node (as we do not manage the treatment for the other nodes yet). - if (cimg::strncasecmp(line,"Shape",5)) { - while (cimg::strncasecmp(line,"Shape",5) && !std::feof(nfile)) err = std::fscanf(nfile,"%1023[^\n] ",line); - if (std::feof(nfile)) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : Shape node not found in file '%s'.", - cimg_instance,filename?filename:"(FILE*)"); - } - } - - // Look for either geometry or appearance node. - while (cimg::strncasecmp(line,"geometry",8) && cimg::strncasecmp(line,"appearance",10) && !std::feof(nfile)) - err = std::fscanf(nfile,"%1023[^\n] ",line); - if (std::feof(nfile)) { // If none of these nodes are defined. - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : Geometry and appearance nodes not found in file '%s'.", - cimg_instance,filename?filename:"(FILE*)"); - } - - std::vector listePoints; // Intermediate list containing the points of the whole object. - primitives.assign(); - colors.assign(); - // Count the number of points of the whole object and the number of primitives. - int nbPointsTotal = 0, nbPrimitives = 0; - float r = 0.78f, g = 0.78f, b = 0.78f; // RGB level of the object, the object is gray by default. - // Boolean used to know if a color is defined for an object, - // if this object has multiple colors or if the object has a texture - bool colorDefined = true, multipleColors = false, textureTest = false; - char textureFile[1024] = { 0 }; // Variable containing the name of the image used as a texture - - while (!std::feof(nfile)) { - char type[1024] = { 0 }, textureFileTemp[1024] = { 0 }; - colorDefined = true; - if (!cimg::strncasecmp(line,"geometry",8)) { // We are at the geometry node - std::sscanf(line,"geometry %s",type); // We are looking for the type of geometry to draw - const CImg coords = CImg::empty(); // CImg used for the texturization of an object - CImgList colorsTextured; // CImgList used for the texturization of the color of an object - CImgList primitivesTemp; // Intermediate CImgList used to update the primitives of the whole object - - if (!cimg::strncasecmp(type,"Box",3)) { // If the object to draw is a box - while (cimg::strncasecmp(line,"size",4) && !std::feof(nfile)) // We are looking for the size of the box - err = std::fscanf(nfile,"%1023[^\n] ",line); - - if (std::feof(nfile)) { // If no size is specified - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : size of box not defined in file '%s'.", - cimg_instance, filename?filename:"(FILE*)"); - } - - float X = 0, Y = 0, Z = 0; // The width, height and depth of the box - if ((err = std::sscanf(line,"size %f %f %f[^\n] ",&X,&Y,&Z))!=3 && - (err = std::sscanf(line,"size %f,%f,%f[^\n] ",&X,&Y,&Z))!=3) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : Failed to read box size in file '%s'.", - cimg_instance,filename?filename:"(FILE*)"); - } - // We generate the primitives and the points of the box - const CImg pointsTemp = CImg::box3d(primitivesTemp,(T)X,(T)Y,(T)Z); - - nbPrimitives = primitivesTemp.size(); // We save the number of primitives of the object - - if (textureTest) { // If the object has a texture - // We put the image used as a texture into a CImg object - const CImg texture(textureFile); - // We initialize the colorsTextured list - colorsTextured.insert(primitivesTemp.size(),CImg::vector(0,50,250)); - // We texturize the object - pointsTemp.texturize_object3d(primitivesTemp,colorsTextured,texture,coords); - nbPrimitives = 0; - } - - if(nbPointsTotal) { // If there are already some objects in the scene - for (int j=0;j<(int)primitivesTemp.size();j++) { - for(int i=0;i<4;i++) - // We shift the indices in the primitives to designate the right points - primitivesTemp(j).at(i) += (tf)nbPointsTotal; - } - } - primitives.push_back(primitivesTemp); // We add the primitives of the box to the general primitives variable - for(int i=0;i<(int)pointsTemp.size()/3;++i) { // We add the points into the temporary list in the right order - listePoints.push_back((T)pointsTemp.at(i)); - listePoints.push_back((T)pointsTemp.at(i + 8)); - listePoints.push_back((T)pointsTemp.at(i + 16)); - } - nbPointsTotal += pointsTemp.size()/3; // We increase the number of points of the whole object - } - else if(!cimg::strncasecmp(type,"Sphere",6)) { // If the object to draw is a sphere - while(cimg::strncasecmp(line,"radius",6) && !std::feof(nfile)) - err = std::fscanf(nfile,"%1023[^\n] ",line); - - if(std::feof(nfile)) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : radius of sphere not defined in file '%s'.", - cimg_instance, filename?filename:"(FILE*)"); - } - - float R = 0; - if ((err = std::sscanf(line,"radius %f[^\n] ",&R))!=1) { // We get the radius of the sphere - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : Failed to read sphere radius in file '%s'.", - cimg_instance,filename?filename:"(FILE*)"); - } - // Compute the necessary points and primitives for a sphere of radius R - const CImg pointsTemp = CImg::sphere3d(primitivesTemp,(T)R); - // We get the number of primitives to used on the attribution of a color, in case no specific color is defined - nbPrimitives = primitivesTemp.size(); - - if(textureTest) { // If the object has a texture - // We put the image used as a texture into a CImg object - const CImg texture(textureFile); - // We initialize the colorsTextured list - colorsTextured.insert(primitivesTemp.size(),CImg::vector(0,50,250)); - pointsTemp.texturize_object3d(primitivesTemp,colorsTextured,texture,coords); // We texturize the object - nbPrimitives = 0; // We set to 0 because there is no color to use - } - - if(nbPointsTotal) { // If there are already some objects in the scene - for (int j=0;j<(int)primitivesTemp.size();j++) { - for(int i=0;i<3;i++) - primitivesTemp(j).at(i) += (tf)nbPointsTotal; - } - } - - primitives.push_back(primitivesTemp); - for(int i=0;i<(int)pointsTemp.size()/3;++i) { - listePoints.push_back((T)pointsTemp.at(i)); - listePoints.push_back((T)pointsTemp.at(i + pointsTemp.size()/3)); - listePoints.push_back((T)pointsTemp.at(i + 2*pointsTemp.size()/3)); - } - nbPointsTotal += pointsTemp.size()/3; - } - else if(!cimg::strncasecmp(type,"Cone",4)) { // If the object to draw is a cone - while(cimg::strncasecmp(line,"bottomRadius",12) && !std::feof(nfile) && cimg::strncasecmp(line,"height",6)) - err = std::fscanf(nfile,"%1023[^\n] ",line); - float R = 0, H = 0; - if(std::feof(nfile)) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : bottom radius and height of cone not defined in file '%s'.", - cimg_instance, filename?filename:"(FILE*)"); - } - else if(!cimg::strncasecmp(line,"bottomRadius",12)) { // We find the bottom radius of the cone first - if ((err = std::sscanf(line,"bottomRadius %f[^\n] ",&R))!=1) { // We get the radius into the variable R - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : Failed to read cone bottomRadius in file '%s'.", - cimg_instance,filename?filename:"(FILE*)"); - } - while(!std::feof(nfile) && cimg::strncasecmp(line,"height",6)) // We look for the height of the cone - err = std::fscanf(nfile,"%1023[^\n] ",line); - - if(std::feof(nfile)) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : height of cone not defined in file '%s'.", - cimg_instance, filename?filename:"(FILE*)"); - } - - if ((err = std::sscanf(line,"height %f[^\n] ",&H))!=1) { // We get the height into the variable H - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : Failed to read cone height in file '%s'.", - cimg_instance,filename?filename:"(FILE*)"); - } - } - else { // We find the height of the cone first - if ((err = std::sscanf(line,"height %f[^\n] ",&H))!=1) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : Failed to read cone height in file '%s'.", - cimg_instance,filename?filename:"(FILE*)"); - } - while(!std::feof(nfile) && cimg::strncasecmp(line,"bottomRadius",12)) - err = std::fscanf(nfile,"%1023[^\n] ",line); - - if(std::feof(nfile)) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : bottom radius of cone not defined in file '%s'.", - cimg_instance, filename?filename:"(FILE*)"); - } - - if ((err = std::sscanf(line,"bottomRadius %f[^\n] ",&R))!=1) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : Failed to read cone bottom radius in file '%s'.", - cimg_instance,filename?filename:"(FILE*)"); - } - } - // Compute the necessary points and primitives for a cone of radius R and height H - const CImg pointsTemp = CImg::cone3d(primitivesTemp,(T)R,(T)H); - - nbPrimitives = primitivesTemp.size(); - - if(textureTest) { // If the object has a texture - // We put the image used as a texture into a CImg object - const CImg texture(textureFile); - // We initialize the colorsTextured list - colorsTextured.insert(primitivesTemp.size(),CImg::vector(0,50,250)); - pointsTemp.texturize_object3d(primitivesTemp,colorsTextured,texture,coords); // We texturize the object - nbPrimitives = 0; - } - - if(nbPointsTotal) { - for (int j=0;j<(int)primitivesTemp.size();j++) { - for(int i=0;i<3;i++) - primitivesTemp(j).at(i) += (tf)nbPointsTotal; - } - } - - primitives.push_back(primitivesTemp); - for(int i=0;i<(int)pointsTemp.size()/3;++i) { - listePoints.push_back((T)pointsTemp.at(i)); - listePoints.push_back((T)pointsTemp.at(i + pointsTemp.size()/3)); - listePoints.push_back((T)pointsTemp.at(i + 2*pointsTemp.size()/3)); - } - nbPointsTotal += pointsTemp.size()/3; - } - else if(!cimg::strncasecmp(type,"Cylinder",8)) { // If the object to draw is a cylinder - while(cimg::strncasecmp(line,"radius",6) && !std::feof(nfile) && cimg::strncasecmp(line,"height",6)) - err = std::fscanf(nfile,"%1023[^\n] ",line); - float R = 0, H = 0; - if(std::feof(nfile)) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : radius or height of cylinder not defined in file '%s'.", - cimg_instance, filename?filename:"(FILE*)"); - } - else if(!cimg::strncasecmp(line,"radius",6)) { // If we find the radius first - if ((err = std::sscanf(line,"radius %f[^\n] ",&R))!=1) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : Failed to read cylinder radius in file '%s'.", - cimg_instance,filename?filename:"(FILE*)"); - } - while(!std::feof(nfile) && cimg::strncasecmp(line,"height",6)) // We now look for the height of the cylinder - err = std::fscanf(nfile,"%1023[^\n] ",line); - - if(std::feof(nfile)) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : height of cylinder not defined in file '%s'.", - cimg_instance, filename?filename:"(FILE*)"); - } - - if ((err = std::sscanf(line,"height %f[^\n] ",&H))!=1) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : Failed to read cylinder height in file '%s'.", - cimg_instance,filename?filename:"(FILE*)"); - } - } - else { // If we find the height first - if ((err = std::sscanf(line,"height %f[^\n] ",&H))!=1) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : Failed to read cylinder height in file '%s'.", - cimg_instance,filename?filename:"(FILE*)"); - } - while(!std::feof(nfile) && cimg::strncasecmp(line,"radius",6))// We now look for the radius of the cylinder - err = std::fscanf(nfile,"%1023[^\n] ",line); - - if(std::feof(nfile)) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : radius of cylinder not defined in file '%s'.", - cimg_instance, filename?filename:"(FILE*)"); - } - - if ((err = std::sscanf(line,"radius %f[^\n] ",&R))!=1) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : Failed to read cylinder radius in file '%s'.", - cimg_instance,filename?filename:"(FILE*)"); - } - } - // Compute the necessary points and primitives for a cylinder of radius R and height H - const CImg pointsTemp = CImg::cylinder3d(primitivesTemp,(T)R,(T)H); - - if(textureTest) { // If the object has a texture - // We put the image used as a texture into a CImg object - const CImg texture(textureFile); - // We initialize the colorsTextured list - colorsTextured.insert(primitivesTemp.size(),CImg::vector(0,50,250)); - pointsTemp.texturize_object3d(primitivesTemp,colorsTextured,texture,coords); // We texturize the object - nbPrimitives = 0; - } - - nbPrimitives = primitivesTemp.size(); - - if(nbPointsTotal) { - for (int j=0;j<(int)primitivesTemp.size();j++) { - for(int i=0;i<3;i++) - primitivesTemp(j).at(i) += (tf)nbPointsTotal; - } - } - - primitives.push_back(primitivesTemp); - for(int i=0;i<(int)pointsTemp.size()/3;++i) { - listePoints.push_back((T)pointsTemp.at(i)); - listePoints.push_back((T)pointsTemp.at(i + pointsTemp.size()/3)); - listePoints.push_back((T)pointsTemp.at(i + 2*pointsTemp.size()/3)); - } - nbPointsTotal += pointsTemp.size()/3; - } - else if(!cimg::strncasecmp(type,"PointSet",8)) { // If the object to draw is a set of points - while(cimg::strncasecmp(line,"point [",7) && !std::feof(nfile)) - err = std::fscanf(nfile,"%1023[^\n] ",line); - - if(std::feof(nfile)) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : points of pointSet node not defined in file '%s'.", - cimg_instance, filename?filename:"(FILE*)"); - } - - err = std::fscanf(nfile,"%1023[^\n] ",line); - int nbPoints = 0; - - while(cimg::strncasecmp(line,"]",1) && !std::feof(nfile)) { - // while we did not get all the points and while we are not at the end of the file - float X = 0, Y = 0, Z = 0; - if ((err = std::sscanf(line,"%f %f %f,[^\n] ",&X,&Y,&Z))==3 || - (err = std::sscanf(line,"%f,%f,%f,[^\n] ",&X,&Y,&Z))==3) { - // We get the coordinates of all the points and store them into a list of points - listePoints.push_back((T)X); - listePoints.push_back((T)Y); - listePoints.push_back((T)Z); - ++nbPoints; - } - err = std::fscanf(nfile,"%1023[^\n] ",line); - } - if(std::feof(nfile)) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : bad structure of pointSet node in file '%s'.", - cimg_instance, filename?filename:"(FILE*)"); - } - primitivesTemp.assign(); - - for(int i=0;i temp(1,1,1,1,(tf)i); - primitivesTemp.push_back(temp); - } - - if(nbPointsTotal) { - for (int j=0;j<(int)primitivesTemp.size();j++) { - for(int i=0;i<(int)primitivesTemp(j).size();i++) - primitivesTemp(j).at(i) += (tf)nbPointsTotal; - } - } - nbPrimitives = primitivesTemp.size(); - - primitives.push_back(primitivesTemp); - - nbPointsTotal += nbPoints; - } - else if(!cimg::strncasecmp(type,"IndexedLineSet",14) || - !cimg::strncasecmp(type,"IndexedFaceSet",14)) { - // If the object to draw is a set of lines or a set of faces - while(cimg::strncasecmp(line,"point [",7) && !std::feof(nfile)) - err = std::fscanf(nfile,"%1023[^\n] ",line); - if(std::feof(nfile)) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : points of IndexedSet node not defined in file '%s'.", - cimg_instance, filename?filename:"(FILE*)"); - } - - err = std::fscanf(nfile,"%1023[^\n] ",line); - int nbPoints = 0; - while(cimg::strncasecmp(line,"]",1) && !std::feof(nfile)) { - // As long as there are points defined we add them to the list - float X=0,Y=0,Z=0; - if ((err = std::sscanf(line,"%f %f %f,[^\n] ",&X,&Y,&Z))==3 || - (err = std::sscanf(line,"%f,%f,%f,[^\n] ",&X,&Y,&Z))==3) { - // We get the coordinates of the points into a list of points - listePoints.push_back((T)X); - listePoints.push_back((T)Y); - listePoints.push_back((T)Z); - ++nbPoints; - } - err = std::fscanf(nfile,"%1023[^\n] ",line); - } - if(std::feof(nfile)) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : bad structure of point vector node in file '%s'.", - cimg_instance, filename?filename:"(FILE*)"); - } - - primitivesTemp.assign(); - - while(cimg::strncasecmp(line,"coordIndex [",12) && !std::feof(nfile)) - // We are looking for the index of the points - err = std::fscanf(nfile,"%1023[^\n] ",line); - if(std::feof(nfile)) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : coordIndex not furnished for IndexedSet node in file '%s'.", - cimg_instance, filename?filename:"(FILE*)"); - } - - err = std::fscanf(nfile,"%1023[^\n] ",line); - - while(cimg::strncasecmp(line,"]",1) && !std::feof(nfile)) { // As long as there are indices - if(*line!='#') { - std::vector primitiveComponents; - char * pch; - pch = std::strtok (line,","); - - while (pch != NULL && std::atof(pch)!=-1) { // We extract the list of indices and store them into a vector - if(!(int)count(primitiveComponents.begin(),primitiveComponents.end(),(tf)std::atof(pch))) - primitiveComponents.push_back((tf)std::atof(pch)); - pch = std::strtok (NULL, ","); - } - CImg temp(1,primitiveComponents.size(),1,1); - - for(int i=0;i<(int)primitiveComponents.size();++i) - temp(0,i) = primitiveComponents.at(i); - primitivesTemp.push_back(temp); - } - err = std::fscanf(nfile,"%1023[^\n] ",line); - } - - if(std::feof(nfile)) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : bad structure of coordIndex in file '%s'.", - cimg_instance, filename?filename:"(FILE*)"); - } - - if(nbPointsTotal) { - for (int j=0;j<(int)primitivesTemp.size();j++) { - for(int i=0;i<(int)primitivesTemp(j).size();i++) - primitivesTemp(j).at(i) += (tf)nbPointsTotal; - } - } - - nbPrimitives = primitivesTemp.size(); - primitives.push_back(primitivesTemp); - nbPointsTotal += nbPoints; - - while(cimg::strncasecmp(line,"color [",7) && cimg::strncasecmp(line,"}",1) && !std::feof(nfile)) - err = std::fscanf(nfile,"%1023[^\n] ",line); - if(std::feof(nfile)) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : bad structure of coordIndex in file '%s'.", - cimg_instance, filename?filename:"(FILE*)"); - } - else if(!cimg::strncasecmp(line,"color [",7)) { // If there are different colors defined for each faces - multipleColors = true; - std::vector > listColors; - err = std::fscanf(nfile,"%1023[^\n] ",line); - while(cimg::strncasecmp(line,"]",1) && !std::feof(nfile)) { - // We add the list of all colors defined into the vector listColors - if(*line!='#') { - if ((err = std::sscanf(line,"%f %f %f[^\n] ",&r,&g,&b))!=3) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : wrong number of color furnished in file '%s'.", - cimg_instance,filename?filename:"(FILE*)"); - } - CImg img(3,1,1,1,(tc)(r*255),(tc)(g*255),(tc)(b*255)); - listColors.push_back(img); - } - err = std::fscanf(nfile,"%1023[^\n] ",line); - } - if(std::feof(nfile)) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : bad structure of color in file '%s'.", - cimg_instance, filename?filename:"(FILE*)"); - } - else { - while(cimg::strncasecmp(line,"colorIndex [",12) && !std::feof(nfile)) - err = std::fscanf(nfile,"%1023[^\n] ",line); - if(std::feof(nfile)) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : colorIndex not furnished for Color node in file '%s'.", - cimg_instance, filename?filename:"(FILE*)"); - } - err = std::fscanf(nfile,"%1023[^\n] ",line); - while(cimg::strncasecmp(line,"]",1) && !std::feof(nfile)) { - // We add the colors at the right index into the vector colors - if(*line!='#') { - char * pch; - pch = std::strtok (line," "); - while (pch != NULL) { - int indice = std::atoi(pch); - colors.insert(CImg::vector((tc)(listColors[indice])[0], - (tc)(listColors[indice])[1], - (tc)(listColors[indice])[2])); - pch = std::strtok (NULL, " "); - } - } - err = std::fscanf(nfile,"%1023[^\n] ",line); - } - } - } - } - else // If none of the known type of shape is defined - cimg::warn(_cimg_instance - "load_vrml() : Failed to read type of geometry to draw from file '%s'.", - cimg_instance,filename?filename:"(FILE*)"); - - if(textureTest) { // If the object considered is texturized - colors.push_back(colorsTextured); - *textureFile = 0; - } - while(cimg::strncasecmp(line,"appearance",10) && - cimg::strncasecmp(line,"Shape",5) && !std::feof(nfile)) - // We look for the node appearance or for another shape - err = std::fscanf(nfile,"%1023[^\n] ",line); - } - if(!cimg::strncasecmp(line,"appearance",10)) { // We are at the appearance node - while(cimg::strncasecmp(line,"texture ImageTexture",20) && - cimg::strncasecmp(line,"diffuseColor",12) && !std::feof(nfile)) - // We are looking for a valid appearance node - err = std::fscanf(nfile,"%1023[^\n] ",line); - if(!cimg::strncasecmp(line,"diffuseColor",12)) { // If the object as a unique diffuse color - if ((err = std::sscanf(line,"diffuseColor %f,%f,%f[^\n] ",&r,&g,&b))!=3 && - (err = std::sscanf(line,"diffuseColor %f %f %f[^\n] ",&r,&g,&b))!=3) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : wrong number of color furnished in file '%s'.", - cimg_instance,filename?filename:"(FILE*)"); - } - } - else if(!cimg::strncasecmp(line,"texture ImageTexture",20)) { // If there is a texture defined in the VRML file - textureTest = true; - colorDefined = false; - while(cimg::strncasecmp(line,"url",3) && !std::feof(nfile)) - err = std::fscanf(nfile,"%1023[^\n] ",line); - if(std::feof(nfile)) { - if (!file) - cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_vrml() : texture not defined in file '%s'.", - cimg_instance, filename?filename:"(FILE*)"); - } - // We temporary put the name of the texture image into textureFileTemp - std::sscanf(line,"url [%s][^\n] ",textureFileTemp); - char * pch; - pch = std::strtok (textureFileTemp,"\""); - strcpy(textureFile,pch); // We put the url of the texture image into textureFile - } - } - else if(!cimg::strncasecmp(line,"Shape",5)) // We have another shape node - textureTest = false; // We reinitialize the texture boolean - - if(nbPrimitives && colorDefined && !multipleColors && !textureTest) { - // If there is only one color defined we add it to the colors CImgList or if no color - // is defined for an object, we add the default color - CImgList colorsTemp; - colorsTemp.insert(nbPrimitives,CImg::vector((tc)(r*255),(tc)(g*255),(tc)(b*255))); - colors.push_back(colorsTemp); - nbPrimitives = 0; - r = 0.7f; - g = 0.7f; - b = 0.7f; - } - err = std::fscanf(nfile,"%1023[^\n] ",line); - } - - assign(listePoints.size()/3,3); - cimg_forX(*this,l) { // We add the points coordinates to the calling object - (*this)(l,0) = (T)(listePoints.at(l*3)); - (*this)(l,1) = (T)(listePoints.at(l*3 + 1)); - (*this)(l,2) = (T)(listePoints.at(l*3 + 2)); - } - - if (!file) - cimg::fclose(nfile); - - return *this; -} - -//! Save VRML files. -template -const CImg& save_vrml(const char *const filename,const CImgList& primitives, - const CImgList& colors, const char *const texturefile = 0) const { - return _save_vrml(0,filename,primitives,colors,texturefile); -} - -//! Save VRML files. -template -const CImg& save_vrml(std::FILE *const file,const CImgList& primitives, - const CImgList& colors, const char *const texturefile = 0) const { - return _save_vrml(file,0,primitives,colors,texturefile); -} - -// Save VRML files (internal). -template -const CImg& _save_vrml(std::FILE *const file, const char *const filename, const CImgList& primitives, - const CImgList& colors, const char *const texturefile) const { - - // Check that the user furnished a file to save the object and that the object is not empty. - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "save_vrml() : Specified filename is (null).", - cimg_instance); - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "save_vrml() : Empty instance, for file '%s'.", - cimg_instance,filename?filename:"(FILE*)"); - - // Check that the object we want to save is a 3D object. - CImgList opacities; - char error_message[1024] = {0}; - if (!is_object3d(primitives,colors,opacities,true,error_message)) - throw CImgInstanceException(_cimg_instance - "save_vrml() : Invalid specified 3d object, for file '%s' (%s).", - cimg_instance,filename?filename:"(FILE*)",error_message); - const CImg default_color(1,3,1,1,200); - - // We open the file in which we will save the 3D object. - std::FILE * nfile; - if(file) nfile = file; - else nfile = cimg::fopen(filename,"w"); - - // We use the version 2.0 of VRML to represent the object in UTF8 - std::fprintf(nfile,"#VRML V2.0 utf8\n"); - - // We copy the coordinates of all the points - std::fprintf(nfile,"Shape {\n\tgeometry IndexedFaceSet {\n\t\tcoord Coordinate {\n\t\t\tpoint [\n"); - cimg_forX(*this,i) - std::fprintf(nfile,"\t\t\t\t%f %f %f,\n",(float)((*this)(i,0)),(float)((*this)(i,1)),(float)((*this)(i,2))); - std::fprintf(nfile,"\t\t\t]\n\t\t}\n\t\tcoordIndex [\n"); - bool sameColor = true; - - float r = colors[0][0]/255.0f; - float g = colors[0][1]/255.0f; - float b = colors[0][2]/255.0f; - - std::vector listColor; - std::string listColorPerFace(""); - for(int i=0;i<(int)colors.size();++i) {// Test if the object is composed of only one color - float valR = (colors[i][0])/255.0f; - float valG = (colors[i][1])/255.0f; - float valB = (colors[i][2])/255.0f; - - if (r!=valR || g!=valG || b!=valB) { // If the object has different colors - sameColor = false; - i = colors.size(); - } - } - - cimglist_for(primitives,l) { // For each primitive - const CImg& color = l 1) g = color[1]/255.0f; - else g = r/255.0f; - if (csiz > 2) b = color[2]/255.0f; - else b = g/255.0f; - - switch (psiz) { - case 1 : - std::fprintf(nfile,"\t\t\t%u,-1\n",(unsigned int)primitives(l,0)); - break; - case 2 : - std::fprintf(nfile,"\t\t\t%u,%u,-1\n",(unsigned int)primitives(l,0),(unsigned int)primitives(l,1)); - break; - case 3 : - std::fprintf(nfile,"\t\t\t%u,%u,%u,-1\n",(unsigned int)primitives(l,0),(unsigned int)primitives(l,2), - (unsigned int)primitives(l,1)); - break; - case 4 : - std::fprintf(nfile,"\t\t\t%u,%u,%u,%u,-1\n",(unsigned int)primitives(l,0),(unsigned int)primitives(l,3), - (unsigned int)primitives(l,2),(unsigned int)primitives(l,1)); - break; - case 6 : { - const unsigned int xt = (unsigned int)primitives(l,2), yt = (unsigned int)primitives(l,3); - r = color.atXY(xt,yt,0)/255.0f; - g = (csiz>1?color.atXY(xt,yt,1):r)/255.0f; - b = (csiz>2?color.atXY(xt,yt,2):g)/255.0f; - std::fprintf(nfile,"\t\t\t%u,%u,-1\n",(unsigned int)primitives(l,0),(unsigned int)primitives(l,1)); - } break; - case 9 : { - const unsigned int xt = (unsigned int)primitives(l,3), yt = (unsigned int)primitives(l,4); - r = color.atXY(xt,yt,0)/255.0f; - g = (csiz>1?color.atXY(xt,yt,1):r)/255.0f; - b = (csiz>2?color.atXY(xt,yt,2):g)/255.0f; - std::fprintf(nfile,"\t\t\t%u,%u,%u,-1\n",(unsigned int)primitives(l,0),(unsigned int)primitives(l,2), - (unsigned int)primitives(l,1)); - } break; - case 12 : { - const unsigned int xt = (unsigned int)primitives(l,4), yt = (unsigned int)primitives(l,5); - r = color.atXY(xt,yt,0)/255.0f; - g = (csiz>1?color.atXY(xt,yt,1):r)/255.0f; - b = (csiz>2?color.atXY(xt,yt,2):g)/255.0f; - std::fprintf(nfile,"\t\t\t%u,%u,%u,%u,-1\n",(unsigned int)primitives(l,0),(unsigned int)primitives(l,3), - (unsigned int)primitives(l,2),(unsigned int)primitives(l,1)); - } break; - } - if (!sameColor) { // If there are different colors we store on every loop the RGB values into the vector listColor - std::ostringstream oss; - oss << r << " " << g << " " << b << "\n"; - if (listColor.size() == 0) { - listColor.push_back(oss.str()); - listColorPerFace += "0"; // We store the indice of the color - } - else { - std::vector::iterator it; - it = find (listColor.begin(), listColor.end(), oss.str()); - std::ostringstream oss2; - if(it==listColor.end()) { - oss2 << " " << listColor.size(); - listColorPerFace += oss2.str(); - listColor.push_back(oss.str()); - } - else { - int n = 0; - for (std::vector::iterator iter = listColor.begin(); iter != it; iter++) ++n; - oss2 << " " << n; - listColorPerFace += oss2.str(); - } - } - } - } - std::fprintf(nfile,"\t\t]\n"); - - if (texturefile) // If we have a texture instead of a color - std::fprintf(nfile,"\n\t}\n\tappearance DEF theTexture Appearance " - "{\n\t\ttexture ImageTexture {\n\t\t\turl [\"%s\"]\n\t\t}\n\t}\n}", - texturefile); - else { - if(!sameColor) { // If there are different colors we add all of them - std::fprintf(nfile,"\tcolorPerVertex FALSE\n\tcolor Color {\n\t\tcolor [\n"); - while(!listColor.empty()) { - std::fprintf(nfile,"\t\t\t%s",(listColor.back()).c_str()); - listColor.pop_back(); - } - std::fprintf(nfile,"\t\t]\n\t}\n\tcolorIndex [\n\t\t"); - std::fprintf(nfile,"%s",listColorPerFace.c_str()); - std::fprintf(nfile,"\n\t]\n\t}\n}"); - } - else { // If there is only one color we add it with the Material node - std::fprintf(nfile,"\t}\n\tappearance Appearance " - "{\n\t\tmaterial Material {\n\t\t\tdiffuseColor %f,%f,%f\n\t\t}\n\t}\n}", - colors[0][0]/255.0f,colors[0][1]/255.0f,colors[0][2]/255.0f); - } - } - if (!file) cimg::fclose(nfile); - return *this; -} - -#endif /* cimg_plugin_vrml */ diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/vtk.h b/applications/plugins/CImgPlugin/extlibs/CImg/plugins/vtk.h deleted file mode 100644 index 032b73f185d..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/plugins/vtk.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - # - # File : vtk.h - # ( C++ header file - CImg plug-in ) - # - # Description : CImg plugin that implements a way to save 3d scene as TK legacy file format. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : Haz-Edine Assemlal - # ( http://www.cim.mcgill.ca/~assemlal/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#ifndef cimg_plugin_vtk -#define cimg_plugin_vtk - -// Save 3D scene in legacy VTK format -/* *this: CImgList of points - * faces: CImgList of faces - * colors: CImgList of colors, - * opacities: CImgList of opacities - */ -template - CImgList& save_vtk(const char* const filename, - const CImgList& faces, - const CImgList& colors, - const CImgList::max(); - cimglist_for(colors,t) - std::fprintf(nfile,"%f %f %f %f\n", - (float)colors[t](0)/tcmax, - (float)colors[t](1)/tcmax, - (float)colors[t](2)/tcmax, - opacities[t](0)); - std::fprintf(nfile,"\n"); - - // Close file - cimg::fclose(nfile); - - return *this; -} - -#endif /* cimg_plugin_vtk */ diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/resources/compile_win_icl.bat b/applications/plugins/CImgPlugin/extlibs/CImg/resources/compile_win_icl.bat deleted file mode 100644 index 37f508301c1..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/resources/compile_win_icl.bat +++ /dev/null @@ -1,15 +0,0 @@ -REM ---------------------------------------------------------------- -REM -REM Script to compile CImg examples, using Intel ICL C++ Compiler. -REM -REM Copy this script into 'CImg/examples/' and run it to compile -REM all examples. -REM -REM ---------------------------------------------------------------- - -CD ..\examples\ -SET CPPFILE=CImg_demo captcha curve_editor2d dtmri_view3d edge_explorer2d fade_images gaussian_fit1d generate_loop_macros hough_transform2d image2ascii image_registration2d image_surface3d jawbreaker mcf_levelsets2d mcf_levelsets3d odykill pde_heatflow2d pde_TschumperleDeriche2d plotter1d radon_transform2d scene3d spherical_function3d tetris tron tutorial wavelet_atrous use_chlpca use_draw_gradient use_nlmeans use_patchmatch use_RGBclass use_skeleton - -FOR %%F IN (%CPPFILE%) DO ( - icl /I.. /GX /Ox %%F.cpp gdi32.lib user32.lib -) diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/resources/compile_win_visualcpp.bat b/applications/plugins/CImgPlugin/extlibs/CImg/resources/compile_win_visualcpp.bat deleted file mode 100644 index 13086eb387e..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/resources/compile_win_visualcpp.bat +++ /dev/null @@ -1,15 +0,0 @@ -REM ---------------------------------------------------------------- -REM -REM Script to compile CImg examples, using Microsoft Visual C++. -REM -REM Copy this script into 'CImg/examples/' and run it to compile -REM all examples. -REM -REM ---------------------------------------------------------------- - -CD ..\examples\ -SET CPPFILE=CImg_demo captcha curve_editor2d dtmri_view3d edge_explorer2d fade_images gaussian_fit1d generate_loop_macros hough_transform2d image2ascii image_registration2d image_surface3d jawbreaker mcf_levelsets2d mcf_levelsets3d odykill pde_heatflow2d pde_TschumperleDeriche2d plotter1d radon_transform2d scene3d spherical_function3d tetris tron tutorial wavelet_atrous use_chlpca use_draw_gradient use_nlmeans use_patchmatch use_RGBclass use_skeleton -FOR %%F IN (%CPPFILE%) DO ( - cl /W4 /wd"4127" /wd"4311" /wd"4312" /wd"4512" /wd"4571" /wd"4640" /wd"4706" /wd"4710" /wd"4800" /wd"4804" /wd"4820" /wd"4996" /Ox /Ob2 /Oi /Ot /c /EHsc /D "_CRT_SECURE_NO_WARNINGS" /I"%SDKPATH%\Include" /I"..\\" %%F.cpp - link /LIBPATH:"%SDKPATH%\Lib" %%F.obj user32.lib gdi32.lib shell32.lib -) diff --git a/applications/plugins/CImgPlugin/src/CImgPlugin/ImageCImg.cpp b/applications/plugins/CImgPlugin/src/CImgPlugin/ImageCImg.cpp index f0ba0896d2a..f9d787188f2 100644 --- a/applications/plugins/CImgPlugin/src/CImgPlugin/ImageCImg.cpp +++ b/applications/plugins/CImgPlugin/src/CImgPlugin/ImageCImg.cpp @@ -81,7 +81,7 @@ bool ImageCImg::load(std::string filename) Image::DataType dataType; Image::ChannelFormat channelFormat; - if (!cimg_library::cimg::strcasecmp(cimgImage.pixel_type(),"unsigned char")) + if (!cimg_library::cimg::strcasecmp(cimgImage.pixel_type(),"uint8")) { dataType = Image::UNORM8; } diff --git a/applications/plugins/CImgPlugin/src/CImgPlugin/SOFACImg.h b/applications/plugins/CImgPlugin/src/CImgPlugin/SOFACImg.h index 86d170ca85d..3cd28794efc 100644 --- a/applications/plugins/CImgPlugin/src/CImgPlugin/SOFACImg.h +++ b/applications/plugins/CImgPlugin/src/CImgPlugin/SOFACImg.h @@ -52,7 +52,11 @@ #undef cimg_main #define cimg_module +#if __has_include() +#include +#elif __has_include() #include +#endif #undef cimg_module #undef cimg_main diff --git a/applications/plugins/CImgPlugin/src/CImgPlugin/initCImgPlugin.cpp b/applications/plugins/CImgPlugin/src/CImgPlugin/initCImgPlugin.cpp index 7e327b102cb..0f80a46d514 100644 --- a/applications/plugins/CImgPlugin/src/CImgPlugin/initCImgPlugin.cpp +++ b/applications/plugins/CImgPlugin/src/CImgPlugin/initCImgPlugin.cpp @@ -18,9 +18,7 @@ /// and export it. namespace cimg_library::cimg { - extern "C" { - SOFA_CIMGPLUGIN_API Mutex_info& Mutex_attr() { static Mutex_info val; return val; } - } + Mutex_static& Mutex_attr() { static Mutex_static val; return val; } } @@ -29,7 +27,7 @@ namespace sofa::component extern "C" { - cimg_library::cimg::Mutex_info& tmp = cimg_library::cimg::Mutex_attr() ; + cimg_library::cimg::Mutex_static& tmp = cimg_library::cimg::Mutex_attr() ; SOFA_CIMGPLUGIN_API void initExternalModule(); SOFA_CIMGPLUGIN_API const char* getModuleName(); diff --git a/applications/plugins/image/ImageCoordValuesFromPositions.h b/applications/plugins/image/ImageCoordValuesFromPositions.h index c446a1834d5..d9510f6aa84 100644 --- a/applications/plugins/image/ImageCoordValuesFromPositions.h +++ b/applications/plugins/image/ImageCoordValuesFromPositions.h @@ -95,9 +95,9 @@ struct ImageCoordValuesFromPositionsSpecialization> Coord Tp = inT->toImage(pos[i]); if(!in->isInside(Tp[0],Tp[1],Tp[2])) val[i] = outval; else val[i] += Coord( - (Real)img.cubic_atXYZ(Tp[0],Tp[1],Tp[2],0,(T)outval[0],cimg_library::cimg::type::min(),cimg_library::cimg::type::max()), - (Real)img.cubic_atXYZ(Tp[0],Tp[1],Tp[2],1,(T)outval[0],cimg_library::cimg::type::min(),cimg_library::cimg::type::max()), - (Real)img.cubic_atXYZ(Tp[0],Tp[1],Tp[2],2,(T)outval[0],cimg_library::cimg::type::min(),cimg_library::cimg::type::max()) + (Real)img.cubic_atXYZ(Tp[0],Tp[1],Tp[2],0,(T)outval[0]), + (Real)img.cubic_atXYZ(Tp[0],Tp[1],Tp[2],1,(T)outval[0]), + (Real)img.cubic_atXYZ(Tp[0],Tp[1],Tp[2],2,(T)outval[0]) ); } } diff --git a/applications/plugins/image/ImageFilter.h b/applications/plugins/image/ImageFilter.h index 172681c4533..995e2d7ff1a 100644 --- a/applications/plugins/image/ImageFilter.h +++ b/applications/plugins/image/ImageFilter.h @@ -466,7 +466,7 @@ class ImageFilter : public core::DataEngine { if(interpolation==0) for(unsigned int k=0; k::min(),cimg_library::cimg::type::max()); + else if(interpolation==2) for(unsigned int k=0; k> { Coord Tp = inT->toImage(pos[i]); if(!in->isInside(Tp[0],Tp[1],Tp[2])) val[i] = outval; - else val[i] = (Real)img.cubic_atXYZ(Tp[0],Tp[1],Tp[2],0,(T)outval,cimg_library::cimg::type::min(),cimg_library::cimg::type::max()); + else val[i] = (Real)img.cubic_atXYZ(Tp[0],Tp[1],Tp[2],0,(T)outval); } } break; diff --git a/applications/plugins/image/image_gui/HistogramWidget.h b/applications/plugins/image/image_gui/HistogramWidget.h index 78e523a06da..e06a437e339 100644 --- a/applications/plugins/image/image_gui/HistogramWidget.h +++ b/applications/plugins/image/image_gui/HistogramWidget.h @@ -163,7 +163,7 @@ class THistogramSetting: public HistogramSetting .draw_rectangle(i,cmax,0,i,this->cimg.height(),this->cimg.depth(),col+i,opacity); const unsigned char currentcol[]= {200,100,0}; - for(unsigned int i=0; i<3; i++) this->cimg.draw_line(i,cpos,0,i,cpos,this->cimg.depth(),currentcol+i); + for(unsigned int i=0; i<3; i++) this->cimg.draw_line(i,cpos,i,cpos,currentcol+i); } From 7a56c190fb8d293b1943006673ea43bb14844e65 Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Thu, 21 Dec 2023 01:39:31 +0100 Subject: [PATCH 33/45] [Core] BaseMapping: link mapConstraints to the "meta-alias" isMechanical (#4360) add mapConstraints to the meta-alias isMechanical --- Sofa/framework/Core/src/sofa/core/BaseMapping.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Sofa/framework/Core/src/sofa/core/BaseMapping.cpp b/Sofa/framework/Core/src/sofa/core/BaseMapping.cpp index ba80f8ab071..b70661fdcec 100644 --- a/Sofa/framework/Core/src/sofa/core/BaseMapping.cpp +++ b/Sofa/framework/Core/src/sofa/core/BaseMapping.cpp @@ -36,6 +36,7 @@ BaseMapping::BaseMapping() , f_mapMatrices(initData(&f_mapMatrices, false, "mapMatrices", "Are matrix explicit mapped?")) { this->addAlias(&f_mapForces, "isMechanical"); + this->addAlias(&f_mapConstraints, "isMechanical"); this->addAlias(&f_mapMasses, "isMechanical"); } From 42a96f915ede03a2026ed9a913c24521398fbf17 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Thu, 21 Dec 2023 08:17:41 +0100 Subject: [PATCH 34/45] [SofaSimpleGUI] Fix calls to deprecated functions (#4390) --- applications/plugins/SofaSimpleGUI/SofaGL.cpp | 10 +++- .../plugins/SofaSimpleGUI/SofaScene.cpp | 47 +++++++++---------- .../plugins/SofaSimpleGUI/SofaScene.h | 5 +- 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/applications/plugins/SofaSimpleGUI/SofaGL.cpp b/applications/plugins/SofaSimpleGUI/SofaGL.cpp index 57af6801880..24903830b67 100644 --- a/applications/plugins/SofaSimpleGUI/SofaGL.cpp +++ b/applications/plugins/SofaSimpleGUI/SofaGL.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include using sofa::simulation::mechanicalvisitor::MechanicalPickParticlesVisitor; @@ -276,8 +277,13 @@ void SofaGL::getSceneBBox( float* xmin, float* ymin, float* zmin, float* xmax, f { SReal xm, xM, ym, yM, zm, zM; _sofaScene->getBoundingBox(&xm,&xM,&ym,&yM,&zm,&zM); - // cerr << "SofaGL::getSceneBBox, xm=" << xm <<", xM=" << xM << endl; - *xmin=xm, *xmax=xM, *ymin=ym, *ymax=yM, *zmin=zm, *zmax=zM; + + *xmin = helper::narrow_cast(xm); + *xmax = helper::narrow_cast(xM); + *ymin = helper::narrow_cast(ym); + *ymax = helper::narrow_cast(yM); + *zmin = helper::narrow_cast(zm); + *zmax = helper::narrow_cast(zM); } diff --git a/applications/plugins/SofaSimpleGUI/SofaScene.cpp b/applications/plugins/SofaSimpleGUI/SofaScene.cpp index 70c7184782d..8cbf2a7abdc 100644 --- a/applications/plugins/SofaSimpleGUI/SofaScene.cpp +++ b/applications/plugins/SofaSimpleGUI/SofaScene.cpp @@ -17,8 +17,8 @@ using std::endl; typedef sofa::simulation::graph::DAGSimulation SofaSimulation; -namespace sofa { -namespace simplegui { +namespace sofa::simplegui +{ typedef sofa::type::Vec3 Vec3; @@ -27,29 +27,29 @@ typedef sofa::component::statecontainer::MechanicalObject< defaulttype::Vec3Type SofaScene::SofaScene() { - _groot = _iroot = NULL; + _groot = _iroot = nullptr; std::shared_ptr classVisualModel;// = NULL; sofa::core::ObjectFactory::AddAlias("VisualModel", "OglModel", true, &classVisualModel); - sofaSimulation = sofa::simulation::getSimulation(); // creates one if it is not already created sofa::component::init(); } void SofaScene::step( SReal dt) { - sofaSimulation->animate(_groot.get(),dt); + sofa::simulation::node::animate(_groot.get(),dt); } void SofaScene::printGraph() { - sofaSimulation->print(_groot.get()); + sofa::simulation::node::print(_groot.get()); } -void SofaScene::loadPlugins( std::vector plugins ) +void SofaScene::loadPlugins( const std::vector& plugins ) { - for (unsigned int i=0; iunload (_groot); - _groot = sofaSimulation->load( fileName.c_str() ).get(); + if(_groot) sofa::simulation::node::unload (_groot); + _groot = sofa::simulation::node::load( fileName.c_str() ).get(); if(!_groot) { cerr << "loading failed" << endl; @@ -72,7 +72,7 @@ void SofaScene::open(const std::string& fileName ) // _currentFileName = fileName; - sofaSimulation->init(_groot.get()); + sofa::simulation::node::init(_groot.get()); printGraph(); SReal xm,xM,ym,yM,zm,zM; @@ -83,16 +83,16 @@ void SofaScene::open(const std::string& fileName ) void SofaScene::setScene(simulation::Node *node ) { - if(_groot) sofaSimulation->unload (_groot); - _groot = sofaSimulation->createNewGraph("root").get(); + if(_groot) sofa::simulation::node::unload (_groot); + _groot = sofa::simulation::getSimulation()->createNewGraph("root").get(); _groot->addChild(node); _iroot = _groot->createChild("iroot").get(); - sofaSimulation->init(_groot.get()); + sofa::simulation::node::init(_groot.get()); } void SofaScene::reset() { - sofaSimulation->reset(_groot.get()); + sofa::simulation::node::reset(_groot.get()); } //void SofaScene::open(const char *filename) @@ -110,7 +110,7 @@ void SofaScene::reset() // _currentFileName = filename; -// sofaSimulation->::init(_groot); +// sofa::simulation::node::::init(_groot); //// cout<<"SofaScene::init, scene loaded" << endl; //// printGraph(); //} @@ -118,7 +118,7 @@ void SofaScene::reset() void SofaScene::getBoundingBox( SReal* xmin, SReal* xmax, SReal* ymin, SReal* ymax, SReal* zmin, SReal* zmax ) { SReal pmin[3], pmax[3]; - sofaSimulation->computeBBox( _groot.get(), pmin, pmax ); + sofa::simulation::node::computeBBox( _groot.get(), pmin, pmax ); *xmin = pmin[0]; *xmax = pmax[0]; *ymin = pmin[1]; *ymax = pmax[1]; *zmin = pmin[2]; *zmax = pmax[2]; @@ -133,12 +133,12 @@ void SofaScene::insertInteractor( Interactor * interactor ) simulation::Node* SofaScene::groot() { return _groot.get(); } void SofaScene::initVisual(){ - sofaSimulation->initTextures(_groot.get()); + sofa::simulation::node::initTextures(_groot.get()); } void SofaScene::updateVisual() { - sofaSimulation->updateVisual(_groot.get()); // needed to update normals and VBOs ! (i think it should be better if updateVisual() was called from draw(), why it is not already the case ?) + sofa::simulation::node::updateVisual(_groot.get()); // needed to update normals and VBOs ! (i think it should be better if updateVisual() was called from draw(), why it is not already the case ?) } //void SofaScene::draw( sofa::core::visual::VisualParams* v) @@ -147,9 +147,8 @@ void SofaScene::updateVisual() // { // // } -// sofaSimulation->draw(_vparams, groot() ); +// sofa::simulation::node::draw(_vparams, groot() ); //} -}// newgui -}// sofa +} diff --git a/applications/plugins/SofaSimpleGUI/SofaScene.h b/applications/plugins/SofaSimpleGUI/SofaScene.h index 0d10d28a339..11565dbbb5e 100644 --- a/applications/plugins/SofaSimpleGUI/SofaScene.h +++ b/applications/plugins/SofaSimpleGUI/SofaScene.h @@ -44,9 +44,9 @@ class SOFA_SOFASIMPLEGUI_API SofaScene /** * @brief load the given plugin - * @param pluginName name of the plugin + * @param plugins names of the plugins */ - void loadPlugins( std::vector pluginName ); + void loadPlugins( const std::vector& plugins ); /** * @brief Load a scene file. The previous scene graph, if any, is deleted. * @param fileName Scene file to load @@ -110,7 +110,6 @@ class SOFA_SOFASIMPLEGUI_API SofaScene protected: simulation::Node::SPtr _groot; ///< root of the scene simulation::Node* _iroot; ///< root of the interactors, child of _groot - simulation::Simulation* sofaSimulation; }; From ed5b29c3ab7a5002bdf43c09b30b804a60b16f7e Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Wed, 27 Dec 2023 09:19:32 +0100 Subject: [PATCH 35/45] [Helper] Fix Colormap when using HSV to RGB (#4408) fix hue value when calling fromHSV --- .../Helper/src/sofa/helper/ColorMap.cpp | 36 ++++++------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/Sofa/framework/Helper/src/sofa/helper/ColorMap.cpp b/Sofa/framework/Helper/src/sofa/helper/ColorMap.cpp index 60cb9448ea3..0fc914d5518 100644 --- a/Sofa/framework/Helper/src/sofa/helper/ColorMap.cpp +++ b/Sofa/framework/Helper/src/sofa/helper/ColorMap.cpp @@ -174,28 +174,32 @@ void ColorMap::reinit() const float step = (2.0f/3.0f)/(nColors-1); for (unsigned int i=0; i Date: Wed, 27 Dec 2023 11:19:23 +0100 Subject: [PATCH 36/45] [Topology.Mapping] Edge2QuadTopologicalMapping: use Links for required QuadSet components (#4361) * use links for quad container/modifier * cleaning --------- Co-authored-by: Paul Baksic <30337881+bakpaul@users.noreply.github.com> Co-authored-by: erik pernod --- .../mapping/Edge2QuadTopologicalMapping.cpp | 132 ++++++++++-------- .../mapping/Edge2QuadTopologicalMapping.h | 10 ++ 2 files changed, 82 insertions(+), 60 deletions(-) diff --git a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Edge2QuadTopologicalMapping.cpp b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Edge2QuadTopologicalMapping.cpp index a96c23cc22f..1ed5049c5cb 100644 --- a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Edge2QuadTopologicalMapping.cpp +++ b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Edge2QuadTopologicalMapping.cpp @@ -63,6 +63,8 @@ Edge2QuadTopologicalMapping::Edge2QuadTopologicalMapping() , d_focalAxis( initData(&d_focalAxis, Vec3(0_sreal, 0_sreal, 1_sreal), "focalAxis", "In case of ellipses")) , d_edgeList(initData(&d_edgeList, "edgeList", "list of input edges for the topological mapping: by default, all considered")) , d_flipNormals(initData(&d_flipNormals, bool(false), "flipNormals", "Flip Normal ? (Inverse point order when creating quad)")) + , l_toQuadContainer(initLink("toQuadContainer", "Output container storing Quads")) + , l_toQuadModifier(initLink("toQuadModifier", "Output modifier handling Quads")) { m_inputType = geometry::ElementType::EDGE; m_outputType = geometry::ElementType::QUAD; @@ -83,6 +85,7 @@ void Edge2QuadTopologicalMapping::init() msg_error() << "Radius is zero or negative"; return; } + if (d_radiusFocal.isSet() && d_radiusFocal.getValue() < std::numeric_limits::min()) { msg_warning() << "Focal Radius is zero or negative"; @@ -98,7 +101,7 @@ void Edge2QuadTopologicalMapping::init() rhoFocal = d_radiusFocal.getValue(); } - const unsigned int N = d_nbPointsOnEachCircle.getValue(); + const auto N = d_nbPointsOnEachCircle.getValue(); // Check input/output topology if (!this->checkTopologyInputTypes()) // method will display error message if false @@ -120,11 +123,35 @@ void Edge2QuadTopologicalMapping::init() { msg_info() << "Edge2QuadTopologicalMapping - to = quad"; - container::dynamic::QuadSetTopologyModifier *to_modifier; - toModel->getContext()->get(to_modifier); + if (l_toQuadContainer.empty()) + { + msg_info() << "Quad container \'" << l_toQuadContainer.getName() << "\' has not been set. A quad container found in the current context will be used, if it exists."; + + container::dynamic::QuadSetTopologyContainer* to_container; + toModel->getContext()->get(to_container); + l_toQuadContainer.set(to_container); + } + + if (!l_toQuadContainer.get()) + { + msg_error() << "The necessary quad container has not been set (or could not be found)."; + return; + } - container::dynamic::QuadSetTopologyContainer *to_container; - toModel->getContext()->get(to_container); + if (l_toQuadModifier.empty()) + { + msg_info() << "Quad modifier \'" << l_toQuadModifier.getName() << "\' has not been set. A quad modifier found in the current context will be used, if it exists."; + + container::dynamic::QuadSetTopologyModifier* to_modifier; + toModel->getContext()->get(to_modifier); + l_toQuadModifier.set(to_modifier); + } + + if (!l_toQuadModifier.get()) + { + msg_error() << "The necessary quad modifier has not been set (or could not be found)."; + return; + } const sofa::type::vector& edgeArray = fromModel->getEdges(); @@ -134,7 +161,7 @@ void Edge2QuadTopologicalMapping::init() // CREATION of the points (new DOFs for the output topology) along the circles around each point of the input topology - const Vec3 X0(1.,0.,0.); + constexpr Vec3 X0(1.,0.,0.); Vec3 Y0; Vec3 Z0; @@ -152,7 +179,7 @@ void Edge2QuadTopologicalMapping::init() to_mstate->resize(fromModel->getNbPoints() * N); } - to_container->clear(); + l_toQuadContainer->clear(); toModel->setNbPoints(fromModel->getNbPoints() * N); @@ -195,34 +222,30 @@ void Edge2QuadTopologicalMapping::init() sofa::type::vector< Index > quadsIndexList; if(d_edgeList.getValue().size()==0) { - - unsigned int nb_elems = (unsigned int)toModel->getNbQuads(); + auto nb_elems = toModel->getNbQuads(); for (unsigned int i=0; i out_info; for(unsigned int j=0; jaddQuadProcess(Quad(q0, q3, q2, q1)); + l_toQuadModifier->addQuadProcess(Quad(q0, q3, q2, q1)); else - to_modifier->addQuadProcess(Quad(q0, q1, q2, q3)); + l_toQuadModifier->addQuadProcess(Quad(q0, q1, q2, q3)); Loc2GlobVec.push_back(i); - out_info.push_back((unsigned int)Loc2GlobVec.size()-1); + out_info.push_back((Index)Loc2GlobVec.size()-1); } In2OutMap[i]=out_info; @@ -265,10 +288,10 @@ void Edge2QuadTopologicalMapping::init() } - to_modifier->addQuads(quads_to_create); + l_toQuadModifier->addQuads(quads_to_create); // Need to fully init the target topology - to_modifier->init(); + l_toQuadModifier->init(); d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); } @@ -293,16 +316,12 @@ void Edge2QuadTopologicalMapping::updateTopologicalMappingTopDown() if (d_componentState.getValue() != sofa::core::objectmodel::ComponentState::Valid) return; - unsigned int N = d_nbPointsOnEachCircle.getValue(); + const auto N = d_nbPointsOnEachCircle.getValue(); // INITIALISATION of QUADULAR mesh from EDGE mesh : if (fromModel) { - - container::dynamic::QuadSetTopologyModifier *to_modifier; - toModel->getContext()->get(to_modifier); - if (toModel) { @@ -312,14 +331,14 @@ void Edge2QuadTopologicalMapping::updateTopologicalMappingTopDown() while( itBegin != itEnd ) { - TopologyChangeType changeType = (*itBegin)->getChangeType(); + const TopologyChangeType changeType = (*itBegin)->getChangeType(); switch( changeType ) { case core::topology::ENDING_EVENT: { - to_modifier->notifyEndingEvent(); + l_toQuadModifier->notifyEndingEvent(); break; } @@ -334,46 +353,36 @@ void Edge2QuadTopologicalMapping::updateTopologicalMappingTopDown() sofa::type::vector< Quad > quads_to_create; sofa::type::vector< Index > quadsIndexList; - std::size_t nb_elems = toModel->getNbQuads(); + sofa::Size nb_elems = toModel->getNbQuads(); for (unsigned int i = 0; i < tab.size(); ++i) { - unsigned int k = tab[i]; + Index k = tab[i]; - unsigned int p0 = edgeArray[k][0]; - unsigned int p1 = edgeArray[k][1]; + const Index p0 = edgeArray[k][0]; + const Index p1 = edgeArray[k][1]; sofa::type::vector out_info; for(unsigned int j=0; jaddQuadsProcess(quads_to_create) ; - //to_modifier->addQuadsWarning(quads_to_create.size(), quads_to_create, quadsIndexList) ; - //to_modifier->propagateTopologicalChanges(); + out_info.push_back((Index)Loc2GlobVec.size()-1); } In2OutMap[k]=out_info; } - to_modifier->addQuads(quads_to_create); + l_toQuadModifier->addQuads(quads_to_create); } break; } @@ -383,7 +392,7 @@ void Edge2QuadTopologicalMapping::updateTopologicalMappingTopDown() { const auto &tab = ( static_cast< const EdgesRemoved *>( *itBegin ) )->getArray(); - unsigned int last = (unsigned int)fromModel->getNbEdges() - 1; + Index last = (Index)fromModel->getNbEdges() - 1; Index ind_tmp; @@ -392,10 +401,10 @@ void Edge2QuadTopologicalMapping::updateTopologicalMappingTopDown() for (unsigned int i = 0; i < tab.size(); ++i) { - unsigned int k = tab[i]; + const unsigned int k = tab[i]; sofa::type::vector ind_k; - auto iter_1 = In2OutMap.find(k); + const auto iter_1 = In2OutMap.find(k); if(iter_1 != In2OutMap.end()) { @@ -410,7 +419,7 @@ void Edge2QuadTopologicalMapping::updateTopologicalMappingTopDown() ind_k = In2OutMap[k]; ind_real_last = ind_k; - auto iter_2 = In2OutMap.find(last); + const auto iter_2 = In2OutMap.find(last); if(iter_2 != In2OutMap.end()) { @@ -484,7 +493,7 @@ void Edge2QuadTopologicalMapping::updateTopologicalMappingTopDown() quads_to_remove.push_back(ind_list[j]); } - to_modifier->removeQuads(quads_to_remove, true, true); + l_toQuadModifier->removeQuads(quads_to_remove, true, true); } else @@ -507,6 +516,9 @@ void Edge2QuadTopologicalMapping::updateTopologicalMappingTopDown() sofa::type::vector indices; sofa::type::vector inv_indices; + indices.reserve(tab.size() * N); + inv_indices.reserve(tab.size()* N); + for(unsigned int i = 0; i < tab.size(); ++i) { @@ -520,7 +532,7 @@ void Edge2QuadTopologicalMapping::updateTopologicalMappingTopDown() sofa::type::vector& tab_indices = indices; sofa::type::vector& inv_tab_indices = inv_indices; - to_modifier->renumberPoints(tab_indices, inv_tab_indices, true); + l_toQuadModifier->renumberPoints(tab_indices, inv_tab_indices, true); break; } @@ -554,7 +566,7 @@ void Edge2QuadTopologicalMapping::updateTopologicalMappingTopDown() } } - to_modifier->addPoints(to_nVertices, to_ancestorsList, to_coefs, true); + l_toQuadModifier->addPoints(to_nVertices, to_ancestorsList, to_coefs, true); break; } diff --git a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Edge2QuadTopologicalMapping.h b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Edge2QuadTopologicalMapping.h index 50e987674e2..7d85f56a145 100644 --- a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Edge2QuadTopologicalMapping.h +++ b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Edge2QuadTopologicalMapping.h @@ -31,6 +31,13 @@ #include #include + +namespace sofa::component::topology::container::dynamic +{ + class QuadSetTopologyContainer; + class QuadSetTopologyModifier; +} + namespace sofa::component::topology::mapping { @@ -94,6 +101,9 @@ class SOFA_COMPONENT_TOPOLOGY_MAPPING_API Edge2QuadTopologicalMapping : public s Data d_edgeList; ///< list of input edges for the topological mapping: by default, all considered Data d_flipNormals; ///< Flip Normal ? (Inverse point order when creating quad) + + SingleLink l_toQuadContainer; ///< Output container storing Quads + SingleLink l_toQuadModifier; ///< Output modifier handling Quads }; } //namespace sofa::component::topology::mapping From d04ef4b50c52d85aa3cd0525dfdbb7676881d5b6 Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Wed, 27 Dec 2023 13:14:33 +0100 Subject: [PATCH 37/45] [Topology.Container.Dynamic] GeometryAlgorithms: support generic State (#4362) --- .../DynamicSparseGridGeometryAlgorithms.h | 3 +-- .../dynamic/PointSetGeometryAlgorithms.h | 16 +++++++++------- .../dynamic/PointSetGeometryAlgorithms.inl | 7 +++---- .../dynamic/TriangleSetGeometryAlgorithms.inl | 2 +- .../utility/TopologicalChangeProcessor.cpp | 7 ++++--- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/DynamicSparseGridGeometryAlgorithms.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/DynamicSparseGridGeometryAlgorithms.h index 3aea8ce9a7f..8b557aebee7 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/DynamicSparseGridGeometryAlgorithms.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/DynamicSparseGridGeometryAlgorithms.h @@ -25,7 +25,6 @@ #include #include -#include namespace sofa::component::topology::container::dynamic { @@ -42,7 +41,7 @@ class DynamicSparseGridGeometryAlgorithms : public HexahedronSetGeometryAlgorith typedef typename DataTypes::VecCoord VecCoord; typedef typename DataTypes::Real Real; typedef typename DataTypes::Coord Coord; - typedef sofa::core::behavior::MechanicalState MObject; + typedef sofa::core::State MObject; protected: DynamicSparseGridGeometryAlgorithms() : HexahedronSetGeometryAlgorithms() diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/PointSetGeometryAlgorithms.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/PointSetGeometryAlgorithms.h index bb8e4fd7105..1be126bdaa8 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/PointSetGeometryAlgorithms.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/PointSetGeometryAlgorithms.h @@ -24,10 +24,12 @@ #include #include -#include +#include + #include #include + namespace sofa::component::topology::container::dynamic { @@ -84,8 +86,8 @@ class PointSetGeometryAlgorithms : public core::topology::GeometryAlgorithms const Coord& getPointRestPosition(const PointID pointId) const; - /** \brief Returns the object where the mechanical DOFs are stored */ - sofa::core::behavior::MechanicalState *getDOF() const { return object; } + /** \brief Returns the object where the DOFs are stored */ + sofa::core::State *getDOF() const { return object; } //float PointIndicesScale; float getIndicesScale() const; @@ -93,16 +95,16 @@ class PointSetGeometryAlgorithms : public core::topology::GeometryAlgorithms template static bool canCreate(T*& obj, core::objectmodel::BaseContext* context, core::objectmodel::BaseObjectDescription* arg) { - if (context->getMechanicalState() && dynamic_cast*>(context->getMechanicalState()) == nullptr) + if (context->getState() && dynamic_cast*>(context->getState()) == nullptr) { - arg->logError(std::string("No mechanical state with the datatype '") + DataTypes::Name() + + arg->logError(std::string("No state with the datatype '") + DataTypes::Name() + "' found in the context node."); return false; } return BaseObject::canCreate(obj, context, arg); } - /** \brief Called by the MechanicalObject state change callback to initialize added + /** \brief Called by the state change callback to initialize added * points according to the topology (topology element & local coordinates) */ void initPointsAdded(const type::vector< sofa::Index > &indices, const type::vector< core::topology::PointAncestorElem > &ancestorElems @@ -114,7 +116,7 @@ class PointSetGeometryAlgorithms : public core::topology::GeometryAlgorithms protected: /** the object where the mechanical DOFs are stored */ - sofa::core::behavior::MechanicalState *object; + sofa::core::State *object; sofa::core::topology::BaseMeshTopology* m_topology; Data d_showIndicesScale; ///< Debug : scale for view topology indices Data d_showPointIndices; ///< Debug : view Point indices diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/PointSetGeometryAlgorithms.inl b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/PointSetGeometryAlgorithms.inl index e5664ddd632..d3abf8ff63f 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/PointSetGeometryAlgorithms.inl +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/PointSetGeometryAlgorithms.inl @@ -22,7 +22,6 @@ #pragma once #include #include -#include #include #include #include @@ -48,9 +47,9 @@ void PointSetGeometryAlgorithms< DataTypes >::init() this->d_componentState.setValue(ComponentState::Invalid); if ( this->d_tagMechanics.getValue().size()>0) { const sofa::core::objectmodel::Tag mechanicalTag(this->d_tagMechanics.getValue()); - object = this->getContext()->core::objectmodel::BaseContext::template get< core::behavior::MechanicalState< DataTypes > >(mechanicalTag,sofa::core::objectmodel::BaseContext::SearchUp); + object = this->getContext()->core::objectmodel::BaseContext::template get< core::State< DataTypes > >(mechanicalTag,sofa::core::objectmodel::BaseContext::SearchUp); } else { - object = this->getContext()->core::objectmodel::BaseContext::template get< core::behavior::MechanicalState< DataTypes > >(); + object = this->getContext()->core::objectmodel::BaseContext::template get< core::State< DataTypes > >(); } core::topology::GeometryAlgorithms::init(); @@ -72,7 +71,7 @@ void PointSetGeometryAlgorithms< DataTypes >::init() if(this->object ==nullptr) { - msg_error() << "Unable to get a valid mechanical object from the context"; + msg_error() << "Unable to get a valid state from the context"; return; } this->d_componentState.setValue(ComponentState::Valid); diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.inl b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.inl index 2061c94a1a1..9da33c5bf4f 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.inl +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.inl @@ -2646,7 +2646,7 @@ bool TriangleSetGeometryAlgorithms< DataTypes >::Suture2Points(TriangleID ind_ta x_created.push_back((Real)point_created[1]); x_created.push_back((Real)point_created[2]); - core::behavior::MechanicalState* state = this->getDOF(); + auto* state = this->getDOF(); sofa::helper::WriteAccessor< Data > x_wA = *state->write(core::VecCoordId::position()); sofa::helper::WriteAccessor< Data > v_wA = *state->write(core::VecDerivId::velocity()); diff --git a/Sofa/Component/Topology/Utility/src/sofa/component/topology/utility/TopologicalChangeProcessor.cpp b/Sofa/Component/Topology/Utility/src/sofa/component/topology/utility/TopologicalChangeProcessor.cpp index 942d50f3d66..955e923c041 100644 --- a/Sofa/Component/Topology/Utility/src/sofa/component/topology/utility/TopologicalChangeProcessor.cpp +++ b/Sofa/Component/Topology/Utility/src/sofa/component/topology/utility/TopologicalChangeProcessor.cpp @@ -20,11 +20,13 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #include + #include #include - -#include #include +#include +#include +#include #include #include @@ -33,7 +35,6 @@ #include #include #include -#include #include From 32d5e2960ebb030afe8074203c576fdf0f6916c2 Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Wed, 27 Dec 2023 16:15:36 +0100 Subject: [PATCH 38/45] [Topology.Mapping] Edge2QuadTopologicalMapping: use States directly (#4388) * use directly states for edge2quad * apply to example scene * clean/format includes --- .../mapping/Edge2QuadTopologicalMapping.cpp | 23 ++++++------------- .../mapping/Edge2QuadTopologicalMapping.h | 12 +++------- .../Mapping/Edge2QuadTopologicalMapping.scn | 6 +---- 3 files changed, 11 insertions(+), 30 deletions(-) diff --git a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Edge2QuadTopologicalMapping.cpp b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Edge2QuadTopologicalMapping.cpp index 1ed5049c5cb..2f5bcfe4a2a 100644 --- a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Edge2QuadTopologicalMapping.cpp +++ b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Edge2QuadTopologicalMapping.cpp @@ -20,25 +20,16 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #include -#include #include - -#include -#include - #include -#include -#include #include - -#include - -#include - #include +#include +#include + namespace sofa::component::topology::mapping { @@ -112,8 +103,8 @@ void Edge2QuadTopologicalMapping::init() // INITIALISATION of QUADULAR mesh from EDGE mesh : - const core::behavior::MechanicalState* from_mstate = dynamic_cast*>(fromModel->getContext()->getMechanicalState()); - core::behavior::MechanicalState* to_mstate = dynamic_cast*>(toModel->getContext()->getMechanicalState()); + const core::State* from_mstate = dynamic_cast*>(fromModel->getContext()->getState()); + core::State* to_mstate = dynamic_cast*>(toModel->getContext()->getState()); if (fromModel) { @@ -299,8 +290,8 @@ void Edge2QuadTopologicalMapping::init() } else { - // Check type Rigid3 of input mechanical object (required) - msg_error() << "Mechanical object associated with the input is not of type Rigid. Edge2QuadTopologicalMapping only supports Rigid3Types to Vec3Types"; + // Check type Rigid3 of input state object (required) + msg_error() << "State object associated with the input is not of type Rigid. Edge2QuadTopologicalMapping only supports Rigid3Types to Vec3Types"; d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); } } diff --git a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Edge2QuadTopologicalMapping.h b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Edge2QuadTopologicalMapping.h index 7d85f56a145..cf838710074 100644 --- a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Edge2QuadTopologicalMapping.h +++ b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Edge2QuadTopologicalMapping.h @@ -22,14 +22,11 @@ #pragma once #include -#include #include -#include -#include +#include +#include -#include -#include namespace sofa::component::topology::container::dynamic @@ -54,10 +51,7 @@ class SOFA_COMPONENT_TOPOLOGY_MAPPING_API Edge2QuadTopologicalMapping : public s { public: SOFA_CLASS(Edge2QuadTopologicalMapping,sofa::core::topology::TopologicalMapping); - - using RigidCoord = sofa::core::State::Coord; - using Vec3Coord = sofa::core::State::Coord; - + using Index = sofa::core::topology::BaseMeshTopology::Index; using Edge = sofa::core::topology::BaseMeshTopology::Edge; using Quad = sofa::core::topology::BaseMeshTopology::Quad; diff --git a/examples/Component/Topology/Mapping/Edge2QuadTopologicalMapping.scn b/examples/Component/Topology/Mapping/Edge2QuadTopologicalMapping.scn index 0c855327e74..d118ca24937 100644 --- a/examples/Component/Topology/Mapping/Edge2QuadTopologicalMapping.scn +++ b/examples/Component/Topology/Mapping/Edge2QuadTopologicalMapping.scn @@ -36,17 +36,13 @@ - + - - - - From 9a107f7f68193a97905c9357e6a5365af2ca201c Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Fri, 5 Jan 2024 11:34:29 +0100 Subject: [PATCH 39/45] [VolumetricRendering] Fix the compilation (#4398) * [VolumetricRendering] Fix the compilation But scenes crash * reflect changes from datatype change for vec3state (#6) * fix lots of stuff (#7) --------- Co-authored-by: Frederick Roy Co-authored-by: Hugo --- .../gpu/cuda/CudaTetrahedralVisualModel.inl | 4 +- .../VolumetricRendering/CMakeLists.txt | 17 ++--- .../examples/OglTetrahedralModel.scn | 32 +++++---- .../examples/OglVolumetricModel_hexa.scn | 27 ++++--- .../examples/OglVolumetricModel_hexa_link.scn | 24 +++---- .../examples/share/shaders/tetra.frag | 2 + .../examples/share/shaders/tetra.vert | 2 +- .../share/shaders/tetra_triangles.geo | 2 +- .../VolumetricRendering/OglTetrahedralModel.h | 16 +---- .../OglTetrahedralModel.inl | 20 ++++-- .../OglVolumetricModel.cpp | 71 +++++++++++-------- .../VolumetricRendering/OglVolumetricModel.h | 6 +- .../src/VolumetricRendering/config.h.in | 6 ++ .../initVolumetricRendering.cpp | 21 +++--- .../initVolumetricRendering.h | 29 ++++++++ 15 files changed, 171 insertions(+), 108 deletions(-) create mode 100644 applications/plugins/VolumetricRendering/src/VolumetricRendering/initVolumetricRendering.h diff --git a/applications/plugins/SofaCUDA/sofa/gpu/cuda/CudaTetrahedralVisualModel.inl b/applications/plugins/SofaCUDA/sofa/gpu/cuda/CudaTetrahedralVisualModel.inl index e5e866f3b1e..db7a13e0020 100644 --- a/applications/plugins/SofaCUDA/sofa/gpu/cuda/CudaTetrahedralVisualModel.inl +++ b/applications/plugins/SofaCUDA/sofa/gpu/cuda/CudaTetrahedralVisualModel.inl @@ -59,13 +59,13 @@ void OglTetrahedralModel< gpu::cuda::CudaVectorTypes >::ini if (!nodes) { - serr << "No mecha." << sendl; + msg_error() << "No mecha."; return; } if (!topo) { - serr << "No topo." << sendl; + msg_error() << "No topo."; return; } diff --git a/applications/plugins/VolumetricRendering/CMakeLists.txt b/applications/plugins/VolumetricRendering/CMakeLists.txt index 0f13f8e0ee6..b02f7146d1f 100644 --- a/applications/plugins/VolumetricRendering/CMakeLists.txt +++ b/applications/plugins/VolumetricRendering/CMakeLists.txt @@ -1,11 +1,12 @@ cmake_minimum_required(VERSION 3.12) -project(VolumetricRendering VERSION 0.1) +project(VolumetricRendering) -find_package(Sofa.Helper REQUIRED) +find_package(Sofa.Config REQUIRED) sofa_find_package(Sofa.GL.Component REQUIRED) set(HEADER_FILES src/VolumetricRendering/config.h.in + src/VolumetricRendering/initVolumetricRendering.cpp src/VolumetricRendering/OglTetrahedralModel.h src/VolumetricRendering/OglTetrahedralModel.inl src/VolumetricRendering/OglVolumetricModel.h @@ -19,17 +20,13 @@ set(SOURCE_FILES add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES}) -target_link_libraries(${PROJECT_NAME} Sofa.Helper Sofa.GL.Component) - -# Add the include DIR from OpenHaptics to target -target_include_directories(${PROJECT_NAME} PUBLIC "$") +target_link_libraries(${PROJECT_NAME} Sofa.GL.Component) # Install rules for the library and the headers; CMake package configurations files sofa_create_package_with_targets( PACKAGE_NAME ${PROJECT_NAME} + PACKAGE_VERSION ${Sofa_VERSION} TARGETS ${PROJECT_NAME} AUTO_SET_TARGET_PROPERTIES - PACKAGE_VERSION ${PROJECT_VERSION} INCLUDE_SOURCE_DIR "src" - INCLUDE_INSTALL_DIR "VolumetricRendering" - RELOCATABLE "plugins" - ) + INCLUDE_INSTALL_DIR "${PROJECT_NAME}" +) diff --git a/applications/plugins/VolumetricRendering/examples/OglTetrahedralModel.scn b/applications/plugins/VolumetricRendering/examples/OglTetrahedralModel.scn index d0e0e6dbe73..2584b9a2401 100644 --- a/applications/plugins/VolumetricRendering/examples/OglTetrahedralModel.scn +++ b/applications/plugins/VolumetricRendering/examples/OglTetrahedralModel.scn @@ -1,16 +1,24 @@ - - - - - - - - - - - + + + + + + - \ No newline at end of file + + + + + + + + + + + + + + diff --git a/applications/plugins/VolumetricRendering/examples/OglVolumetricModel_hexa.scn b/applications/plugins/VolumetricRendering/examples/OglVolumetricModel_hexa.scn index 6947acd4725..7ddea1884d8 100644 --- a/applications/plugins/VolumetricRendering/examples/OglVolumetricModel_hexa.scn +++ b/applications/plugins/VolumetricRendering/examples/OglVolumetricModel_hexa.scn @@ -1,18 +1,23 @@ + + + + - + + - - + + - - - - - - + + + + + + - \ No newline at end of file + diff --git a/applications/plugins/VolumetricRendering/examples/OglVolumetricModel_hexa_link.scn b/applications/plugins/VolumetricRendering/examples/OglVolumetricModel_hexa_link.scn index e6a93625208..34048c30a8b 100644 --- a/applications/plugins/VolumetricRendering/examples/OglVolumetricModel_hexa_link.scn +++ b/applications/plugins/VolumetricRendering/examples/OglVolumetricModel_hexa_link.scn @@ -3,18 +3,18 @@ - + - - - + + + - - - - - - + + + + + + - \ No newline at end of file + diff --git a/applications/plugins/VolumetricRendering/examples/share/shaders/tetra.frag b/applications/plugins/VolumetricRendering/examples/share/shaders/tetra.frag index 8ac26097cb3..c4a64b8d353 100644 --- a/applications/plugins/VolumetricRendering/examples/share/shaders/tetra.frag +++ b/applications/plugins/VolumetricRendering/examples/share/shaders/tetra.frag @@ -1,3 +1,5 @@ +#version 140 + uniform float u_enableLight; //GLSL >= 130 diff --git a/applications/plugins/VolumetricRendering/examples/share/shaders/tetra.vert b/applications/plugins/VolumetricRendering/examples/share/shaders/tetra.vert index f853623ad1d..823e83e4def 100644 --- a/applications/plugins/VolumetricRendering/examples/share/shaders/tetra.vert +++ b/applications/plugins/VolumetricRendering/examples/share/shaders/tetra.vert @@ -1,4 +1,4 @@ -#version 130 +#version 140 // uniform vec4 vertexColor; in vec4 a_vertexColor; diff --git a/applications/plugins/VolumetricRendering/examples/share/shaders/tetra_triangles.geo b/applications/plugins/VolumetricRendering/examples/share/shaders/tetra_triangles.geo index 2d9940dfb09..472c534595a 100644 --- a/applications/plugins/VolumetricRendering/examples/share/shaders/tetra_triangles.geo +++ b/applications/plugins/VolumetricRendering/examples/share/shaders/tetra_triangles.geo @@ -1,4 +1,4 @@ -#version 130 +#version 140 #extension GL_EXT_geometry_shader4: enable //GLSL >= 130 diff --git a/applications/plugins/VolumetricRendering/src/VolumetricRendering/OglTetrahedralModel.h b/applications/plugins/VolumetricRendering/src/VolumetricRendering/OglTetrahedralModel.h index 43b29a359af..0fd1ca8244a 100644 --- a/applications/plugins/VolumetricRendering/src/VolumetricRendering/OglTetrahedralModel.h +++ b/applications/plugins/VolumetricRendering/src/VolumetricRendering/OglTetrahedralModel.h @@ -30,7 +30,7 @@ #include #include #include -#include +#include namespace sofa { @@ -76,8 +76,8 @@ class OglTetrahedralModel : public core::visual::VisualModel void updateVertexBuffer(); //Tables - sofa::component::visual::OglFloatVector4Variable::SPtr m_mappingTableValues; - sofa::component::visual::OglFloatVector4Variable::SPtr m_runSelectTableValues; + sofa::gl::component::shader::OglFloatVector4Variable::SPtr m_mappingTableValues; + sofa::gl::component::shader::OglFloatVector4Variable::SPtr m_runSelectTableValues; protected: OglTetrahedralModel(); @@ -90,16 +90,6 @@ class OglTetrahedralModel : public core::visual::VisualModel void updateVisual() override; virtual void computeMesh(); - - virtual std::string getTemplateName() const - { - return templateName(this); - } - - static std::string templateName(const OglTetrahedralModel* = NULL) - { - return DataTypes::Name(); - } }; #if !defined(SOFA_COMPONENT_VISUALMODEL_OGLTETRAHEDRALMODEL_CPP) diff --git a/applications/plugins/VolumetricRendering/src/VolumetricRendering/OglTetrahedralModel.inl b/applications/plugins/VolumetricRendering/src/VolumetricRendering/OglTetrahedralModel.inl index 6d8f5216bb1..a2c4849bfa0 100644 --- a/applications/plugins/VolumetricRendering/src/VolumetricRendering/OglTetrahedralModel.inl +++ b/applications/plugins/VolumetricRendering/src/VolumetricRendering/OglTetrahedralModel.inl @@ -28,7 +28,6 @@ #include #include #include -#include #include namespace sofa @@ -63,8 +62,8 @@ void OglTetrahedralModel::init() //instanciate the mapping tables //Useful for the PT algorithm only - sofa::type::vector listVec4Variables; - this->getContext()->core::objectmodel::BaseContext::template get > + sofa::type::vector listVec4Variables; + this->getContext()->core::objectmodel::BaseContext::template get > (&listVec4Variables, core::objectmodel::BaseContext::Local); for (unsigned int i = 0; i::init() if (!m_mappingTableValues) { msg_info() << "No MappingTable found, instanciating one"; - m_mappingTableValues = sofa::core::objectmodel::New(); + m_mappingTableValues = sofa::core::objectmodel::New(); m_mappingTableValues->setName("MappingTable"); m_mappingTableValues->setID("MappingTable"); @@ -109,7 +108,7 @@ void OglTetrahedralModel::init() { msg_info() << "No RunSelectTable found, instanciating one"; - m_runSelectTableValues = sofa::core::objectmodel::New(); + m_runSelectTableValues = sofa::core::objectmodel::New(); m_runSelectTableValues->setName("RunSelectTable"); m_runSelectTableValues->setID("RunSelectTable"); @@ -255,7 +254,6 @@ void OglTetrahedralModel::computeMesh() template void OglTetrahedralModel::drawTransparent(const core::visual::VisualParams* vparams) { - using sofa::component::topology::TetrahedronSetTopologyContainer; if (!vparams->displayFlags().getShowVisualModels()) return; if (m_topology == NULL) return; if (m_topology->getNbTetrahedra() < 1) return; @@ -288,7 +286,15 @@ void OglTetrahedralModel::drawTransparent(const core::visual::VisualP glBindBufferARB(GL_ARRAY_BUFFER, m_vbo); - glVertexPointer(3, GL_FLOAT, 0, (char*)NULL + 0); + int gltype = GL_FLOAT; + + if constexpr (std::is_same_v) + { + gltype = GL_DOUBLE; + } + + glVertexPointer(3, gltype, 0, nullptr); + glBindBufferARB(GL_ARRAY_BUFFER, 0); glEnableClientState(GL_VERTEX_ARRAY); diff --git a/applications/plugins/VolumetricRendering/src/VolumetricRendering/OglVolumetricModel.cpp b/applications/plugins/VolumetricRendering/src/VolumetricRendering/OglVolumetricModel.cpp index a966e904856..36605896fa4 100644 --- a/applications/plugins/VolumetricRendering/src/VolumetricRendering/OglVolumetricModel.cpp +++ b/applications/plugins/VolumetricRendering/src/VolumetricRendering/OglVolumetricModel.cpp @@ -28,9 +28,8 @@ #include #include -#include #include -#include +#include namespace sofa::component::visualmodel { @@ -74,8 +73,8 @@ void OglVolumetricModel::init() //instanciate the mapping tables //Useful for the PT algorithm only - sofa::type::vector listVec4Variables; - this->getContext()->core::objectmodel::BaseContext::template get > + sofa::type::vector listVec4Variables; + this->getContext()->core::objectmodel::BaseContext::template get > (&listVec4Variables, core::objectmodel::BaseContext::Local); for (unsigned int i = 0; i(); + m_mappingTableValues = sofa::core::objectmodel::New(); m_mappingTableValues->setName("MappingTable"); m_mappingTableValues->setID("MappingTable"); @@ -118,7 +117,7 @@ void OglVolumetricModel::init() { msg_info() << "No RunSelectTable found, instanciating one"; - m_runSelectTableValues = sofa::core::objectmodel::New(); + m_runSelectTableValues = sofa::core::objectmodel::New(); m_runSelectTableValues->setName("RunSelectTable"); m_runSelectTableValues->setID("RunSelectTable"); @@ -156,7 +155,6 @@ void OglVolumetricModel::init() if (b_useTopology) computeMeshFromTopology(); - updateVisual(); } @@ -185,8 +183,8 @@ void OglVolumetricModel::initVisual() glBindBufferARB(GL_ARRAY_BUFFER, 0); //Check attributes - sofa::type::vector listVec4Attributes; - this->getContext()->core::objectmodel::BaseContext::template get > + sofa::type::vector listVec4Attributes; + this->getContext()->core::objectmodel::BaseContext::template get > (&listVec4Attributes, core::objectmodel::BaseContext::Local); for (unsigned int i = 0; i < listVec4Attributes.size(); i++) { @@ -201,7 +199,7 @@ void OglVolumetricModel::initVisual() if (!m_vertexColors) { msg_error() << "No attributes called a_vertexColor found, instanciating one with a default color"; - m_vertexColors = sofa::core::objectmodel::New(); + m_vertexColors = sofa::core::objectmodel::New(); m_vertexColors->setName("a_vertexColor"); m_vertexColors->setID("a_vertexColor"); m_vertexColors->setIndexShader(0); @@ -222,7 +220,6 @@ void OglVolumetricModel::initVisual() m_vertexColors->init(); m_vertexColors->initVisual(); - } void OglVolumetricModel::updateVisual() @@ -358,27 +355,38 @@ void OglVolumetricModel::computeBarycenters() if (!b_tboCreated) { //Texture buffer objects + if (m_tetraBarycenters.size() > 0) + { + glGenBuffers(1, &m_tetraBarycentersTbo); + glBindBuffer(GL_TEXTURE_BUFFER, m_tetraBarycentersTbo); + glBufferData(GL_TEXTURE_BUFFER, tetraBarycentersBufferSize, &(m_tetraBarycenters[0]), GL_DYNAMIC_COPY); + glGenTextures(1, &m_tetraBarycentersTboTexture); + glBindBuffer(GL_TEXTURE_BUFFER, 0); + b_tboCreated = true; + } + if (m_hexaBarycenters.size() > 0) + { + glGenBuffers(1, &m_hexaBarycentersTbo); + glBindBuffer(GL_TEXTURE_BUFFER, m_hexaBarycentersTbo); + glBufferData(GL_TEXTURE_BUFFER, hexaBarycentersBufferSize, &(m_hexaBarycenters[0]), GL_DYNAMIC_COPY); + glGenTextures(1, &m_hexaBarycentersTboTexture); + glBindBuffer(GL_TEXTURE_BUFFER, 0); + b_tboCreated = true; + } + } - glGenBuffers(1, &m_tetraBarycentersTbo); + if (m_tetraBarycenters.size() > 0) + { glBindBuffer(GL_TEXTURE_BUFFER, m_tetraBarycentersTbo); - glBufferData(GL_TEXTURE_BUFFER, tetraBarycentersBufferSize, &(m_tetraBarycenters[0]), GL_DYNAMIC_COPY); - glGenTextures(1, &m_tetraBarycentersTboTexture); + glBufferSubData(GL_TEXTURE_BUFFER, 0, tetraBarycentersBufferSize, &(m_tetraBarycenters[0])); glBindBuffer(GL_TEXTURE_BUFFER, 0); - - glGenBuffers(1, &m_hexaBarycentersTbo); + } + if (m_hexaBarycenters.size() > 0) + { glBindBuffer(GL_TEXTURE_BUFFER, m_hexaBarycentersTbo); - glBufferData(GL_TEXTURE_BUFFER, hexaBarycentersBufferSize, &(m_hexaBarycenters[0]), GL_DYNAMIC_COPY); - glGenTextures(1, &m_hexaBarycentersTboTexture); + glBufferSubData(GL_TEXTURE_BUFFER, 0, hexaBarycentersBufferSize, &(m_hexaBarycenters[0])); glBindBuffer(GL_TEXTURE_BUFFER, 0); - - b_tboCreated = true; } - - glBindBuffer(GL_TEXTURE_BUFFER, m_tetraBarycentersTbo); - glBufferSubData(GL_TEXTURE_BUFFER, 0, tetraBarycentersBufferSize, &(m_tetraBarycenters[0])); - glBindBuffer(GL_TEXTURE_BUFFER, m_hexaBarycentersTbo); - glBufferSubData(GL_TEXTURE_BUFFER, 0, hexaBarycentersBufferSize, &(m_hexaBarycenters[0])); - glBindBuffer(GL_TEXTURE_BUFFER, 0); } void OglVolumetricModel::handleTopologyChange() @@ -399,7 +407,6 @@ void OglVolumetricModel::handleTopologyChange() void OglVolumetricModel::drawTransparent(const core::visual::VisualParams* vparams) { - using sofa::component::topology::TetrahedronSetTopologyContainer; if (!vparams->displayFlags().getShowVisualModels()) return; glPushAttrib(GL_ALL_ATTRIB_BITS); @@ -426,7 +433,14 @@ void OglVolumetricModel::drawTransparent(const core::visual::VisualParams* vpara #ifdef GL_LINES_ADJACENCY_EXT glBindBufferARB(GL_ARRAY_BUFFER, m_vbo); - glVertexPointer(3, GL_FLOAT, 0, (char*)NULL + 0); + int gltype = GL_FLOAT; + + if constexpr (std::is_same_v) + { + gltype = GL_DOUBLE; + } + + glVertexPointer(3, gltype, 0, nullptr); glBindBufferARB(GL_ARRAY_BUFFER, 0); glEnableClientState(GL_VERTEX_ARRAY); @@ -435,6 +449,7 @@ void OglVolumetricModel::drawTransparent(const core::visual::VisualParams* vpara const type::vector& hexahedra = d_hexahedra.getValue(); //glEnable(GL_CLIP_DISTANCE0); + if (tetrahedra.size() > 0) { glBindTexture(GL_TEXTURE_BUFFER, m_tetraBarycentersTboTexture); diff --git a/applications/plugins/VolumetricRendering/src/VolumetricRendering/OglVolumetricModel.h b/applications/plugins/VolumetricRendering/src/VolumetricRendering/OglVolumetricModel.h index 84f9b2ae64f..7fc4034afad 100644 --- a/applications/plugins/VolumetricRendering/src/VolumetricRendering/OglVolumetricModel.h +++ b/applications/plugins/VolumetricRendering/src/VolumetricRendering/OglVolumetricModel.h @@ -49,7 +49,7 @@ namespace visualmodel class SOFA_VOLUMETRICRENDERING_API OglVolumetricModel : public core::visual::VisualModel, public component::visual::Vec3State { public: - SOFA_CLASS2(OglVolumetricModel, core::visual::VisualModel, Vec3State); + SOFA_CLASS2(OglVolumetricModel, core::visual::VisualModel, component::visual::Vec3State); typedef sofa::core::topology::Tetrahedron Tetrahedron; typedef sofa::core::topology::Hexahedron Hexahedron; @@ -94,8 +94,8 @@ class SOFA_VOLUMETRICRENDERING_API OglVolumetricModel : public core::visual::Vis sofa::type::vector m_hexaToTetrahedra; - sofa::type::vector m_tetraBarycenters; - sofa::type::vector m_hexaBarycenters; + sofa::type::vector m_tetraBarycenters; + sofa::type::vector m_hexaBarycenters; public: void init() override; diff --git a/applications/plugins/VolumetricRendering/src/VolumetricRendering/config.h.in b/applications/plugins/VolumetricRendering/src/VolumetricRendering/config.h.in index 40f6cac6c86..bb9fb08d30a 100644 --- a/applications/plugins/VolumetricRendering/src/VolumetricRendering/config.h.in +++ b/applications/plugins/VolumetricRendering/src/VolumetricRendering/config.h.in @@ -33,4 +33,10 @@ # define SOFA_VOLUMETRICRENDERING_API SOFA_IMPORT_DYNAMIC_LIBRARY #endif +namespace volumetricrendering +{ + constexpr const char* MODULE_NAME = "@PROJECT_NAME@"; + constexpr const char* MODULE_VERSION = "@PROJECT_VERSION@"; +} + #endif diff --git a/applications/plugins/VolumetricRendering/src/VolumetricRendering/initVolumetricRendering.cpp b/applications/plugins/VolumetricRendering/src/VolumetricRendering/initVolumetricRendering.cpp index 3008b366634..de1556a8deb 100644 --- a/applications/plugins/VolumetricRendering/src/VolumetricRendering/initVolumetricRendering.cpp +++ b/applications/plugins/VolumetricRendering/src/VolumetricRendering/initVolumetricRendering.cpp @@ -19,10 +19,10 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ +#include +#include -#include - -namespace sofa::component +namespace volumetricrendering { //Here are just several convenient functions to help user to know what contains the plugin @@ -36,6 +36,11 @@ extern "C" { SOFA_VOLUMETRICRENDERING_API const char* getModuleComponentList(); } +void init() +{ + initExternalModule(); +} + void initExternalModule() { static bool first = true; @@ -47,12 +52,12 @@ void initExternalModule() const char* getModuleName() { - return "VolumetricRendering"; + return volumetricrendering::MODULE_NAME; } const char* getModuleVersion() { - return "0.1"; + return volumetricrendering::MODULE_VERSION; } const char* getModuleLicense() @@ -68,9 +73,9 @@ const char* getModuleDescription() const char* getModuleComponentList() { - return "OglTetrahedralModel"; + static std::string classes = sofa::core::ObjectFactory::getInstance()->listClassesFromTarget(volumetricrendering::MODULE_NAME); + return classes.c_str(); } -} // namespace sofa::component - +} // namespace volumetricrendering diff --git a/applications/plugins/VolumetricRendering/src/VolumetricRendering/initVolumetricRendering.h b/applications/plugins/VolumetricRendering/src/VolumetricRendering/initVolumetricRendering.h new file mode 100644 index 00000000000..fb505e5a842 --- /dev/null +++ b/applications/plugins/VolumetricRendering/src/VolumetricRendering/initVolumetricRendering.h @@ -0,0 +1,29 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include + +namespace volumetricrendering +{ +SOFA_VOLUMETRICRENDERING_API void init(); +} From ff2753f380f80015cced6eb0abf1628cfb3782f6 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Sat, 6 Jan 2024 15:08:16 +0100 Subject: [PATCH 40/45] [Constraint.Lagrangian.Solver] Fix assert in GenericConstraintSolver (#4389) * [Constraint.Lagrangian.Solver] Fix assert in GenericConstraintSolver The construction of xId caused an assert when `cParams->constOrder() == sofa::core::ConstraintOrder::VEL`. It happens only in debug, and it had no consequence because it was not used. * Simpler solution * Remove unnecessary include --------- Co-authored-by: Paul Baksic <30337881+bakpaul@users.noreply.github.com> --- .../lagrangian/solver/GenericConstraintSolver.cpp | 14 +++++--------- .../lagrangian/solver/GenericConstraintSolver.h | 3 +-- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.cpp b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.cpp index 16d1e17e832..ec22b4defdb 100644 --- a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.cpp +++ b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.cpp @@ -496,21 +496,20 @@ sofa::type::vector GenericConstraintS void GenericConstraintSolver::applyMotionCorrection( const core::ConstraintParams* cParams, - const core::MultiVecCoordId xId, - const core::MultiVecDerivId vId, + MultiVecId res1, MultiVecId res2, core::behavior::BaseConstraintCorrection* constraintCorrection) const { if (cParams->constOrder() == sofa::core::ConstraintOrder::POS_AND_VEL) { - constraintCorrection->applyMotionCorrection(cParams, xId, vId, cParams->dx(), this->getDx() ); + constraintCorrection->applyMotionCorrection(cParams, core::MultiVecCoordId{res1}, core::MultiVecDerivId{res2}, cParams->dx(), this->getDx() ); } else if (cParams->constOrder() == sofa::core::ConstraintOrder::POS) { - constraintCorrection->applyPositionCorrection(cParams, xId, cParams->dx(), this->getDx()); + constraintCorrection->applyPositionCorrection(cParams, core::MultiVecCoordId{res1}, cParams->dx(), this->getDx()); } else if (cParams->constOrder() == sofa::core::ConstraintOrder::VEL) { - constraintCorrection->applyVelocityCorrection(cParams, vId, cParams->dx(), this->getDx() ); + constraintCorrection->applyVelocityCorrection(cParams, core::MultiVecDerivId{res1}, cParams->dx(), this->getDx() ); } } @@ -526,9 +525,6 @@ void GenericConstraintSolver::computeAndApplyMotionCorrection(const core::Constr if (std::find(supportedCorrections.begin(), supportedCorrections.end(), cParams->constOrder()) != supportedCorrections.end()) { - const core::MultiVecCoordId xId(res1); - const core::MultiVecDerivId vId(cParams->constOrder() == sofa::core::ConstraintOrder::VEL ? res1 : res2); - for (const auto& constraintCorrection : filteredConstraintCorrections()) { { @@ -537,7 +533,7 @@ void GenericConstraintSolver::computeAndApplyMotionCorrection(const core::Constr } SCOPED_TIMER("ApplyCorrection"); - applyMotionCorrection(cParams, xId, vId, constraintCorrection); + applyMotionCorrection(cParams, res1, res2, constraintCorrection); } } } diff --git a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.h b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.h index 0a6189bfddf..4a43b34a841 100644 --- a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.h +++ b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.h @@ -141,8 +141,7 @@ class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_SOLVER_API GenericConstraintSolver : void computeAndApplyMotionCorrection(const core::ConstraintParams* cParams, GenericConstraintSolver::MultiVecId res1, GenericConstraintSolver::MultiVecId res2) const; void applyMotionCorrection( const core::ConstraintParams* cParams, - const core::MultiVecCoordId xId, - const core::MultiVecDerivId vId, + MultiVecId res1, MultiVecId res2, core::behavior::BaseConstraintCorrection* constraintCorrection) const; void storeConstraintLambdas(const core::ConstraintParams* cParams); From 821f8ed0e22a10081a5bd873ff379099eca39232 Mon Sep 17 00:00:00 2001 From: Hugo Date: Mon, 8 Jan 2024 02:20:47 +0100 Subject: [PATCH 41/45] [README] Minor update badges (#4417) * [README] Minor update badges * Add FEM to the description --------- Co-authored-by: Paul Baksic <30337881+bakpaul@users.noreply.github.com> --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index dfcfc493607..d918f536042 100644 --- a/README.md +++ b/README.md @@ -2,15 +2,17 @@
    -[![Documentation](https://img.shields.io/badge/doc-on_website-green.svg)](https://www.sofa-framework.org/community/doc/) -[![Support](https://img.shields.io/badge/support-on_GitHub_Discussions-blue.svg)](https://github.com/sofa-framework/sofa/discussions) -[![Gitter](https://img.shields.io/badge/chat-on_Gitter-ff69b4.svg)](https://gitter.im/sofa-framework/sofa) -[![Contact](https://img.shields.io/badge/contact-on_website-orange.svg)](https://www.sofa-framework.org/consortium/contact/) +[![Documentation](https://img.shields.io/badge/doc-on_website-brightgreen.svg)](https://www.sofa-framework.org/community/doc/) +[![Support](https://img.shields.io/badge/support-on_GitHub_Discussions-orange.svg)](https://github.com/sofa-framework/sofa/discussions) +[![Gitter](https://img.shields.io/badge/chat-on_Gitter-darkred.svg)](https://gitter.im/sofa-framework/sofa) +
    +[![Contact](https://img.shields.io/badge/contact-on_website-brightgreen.svg)](https://www.sofa-framework.org/consortium/contact/) +[![we're hiring](https://img.shields.io/badge/we're%20hiring!-join%20us-orange)](https://www.sofa-framework.org/about/jobs/) ## What is SOFA -SOFA is an open source framework targeted at interactive physics simulation, with an emphasis on medical simulation and robotics. +SOFA is an open source framework targeted at interactive physics simulation based on the Finite Element Method (FEM), with an emphasis on medical simulation and robotics. It is mainly intended for the research community to help foster newer algorithms, but can also be used as an efficient prototyping tool. SOFA's advanced software architecture allows: - the creation of complex and evolving simulations by combining new algorithms with existing algorithms From 3af47db8305407e00062838c02ba881370e2eb57 Mon Sep 17 00:00:00 2001 From: Hugo Date: Wed, 10 Jan 2024 11:05:14 +0100 Subject: [PATCH 42/45] [Lagrangian.Correction] Add callbacks to check zero compliance (#4205) * Create one single callback checking non-zero values for compliance * add info message in rigid case * test compliance vector only if non-rigid using boiler plate snippet * move in a dedicated file the boiler plate code * fix compil * add checks for zero compliance vector in case of rigid body * minor formatting * Add comment on rigid compliance vector * Update Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/UncoupledConstraintCorrection.inl --------- Co-authored-by: Paul Baksic <30337881+bakpaul@users.noreply.github.com> --- .../UncoupledConstraintCorrection.cpp | 3 +- .../UncoupledConstraintCorrection.inl | 93 ++++++++++++++++++- .../spring/RestShapeSpringsForceField.inl | 35 ++----- Sofa/framework/Type/CMakeLists.txt | 1 + .../Type/src/sofa/type/isRigidType.h | 31 +++++++ 5 files changed, 132 insertions(+), 31 deletions(-) create mode 100644 Sofa/framework/Type/src/sofa/type/isRigidType.h diff --git a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/UncoupledConstraintCorrection.cpp b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/UncoupledConstraintCorrection.cpp index 6f079c4bb42..035f24bba07 100644 --- a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/UncoupledConstraintCorrection.cpp +++ b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/UncoupledConstraintCorrection.cpp @@ -89,7 +89,6 @@ SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_CORRECTION_API void UncoupledConstraintCorr massValue = um->getVertexMass(); usedComp.push_back(odeFactor / massValue.mass); msg_info() << "Compliance matrix is evaluated using the UniformMass"; - } else { @@ -109,6 +108,8 @@ SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_CORRECTION_API void UncoupledConstraintCorr usedComp.push_back( odeFactor * massValue.invInertiaMassMatrix[1][2]); usedComp.push_back( odeFactor * massValue.invInertiaMassMatrix[2][2]); compliance.setValue(usedComp); + + msg_info() << "\'compliance\' equals: " << compliance.getValue(); } else { diff --git a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/UncoupledConstraintCorrection.inl b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/UncoupledConstraintCorrection.inl index ef53af25c24..f8a90d10a3f 100644 --- a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/UncoupledConstraintCorrection.inl +++ b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/UncoupledConstraintCorrection.inl @@ -28,6 +28,7 @@ #include #include #include +#include namespace sofa::component::constraint::lagrangian::correction { @@ -110,6 +111,68 @@ UncoupledConstraintCorrection::UncoupledConstraintCorrection(sofa::co , l_topology(initLink("topology", "link to the topology container")) , m_pOdeSolver(nullptr) { + // Check defaultCompliance and entries of the compliance vector are not zero + core::objectmodel::Base::addUpdateCallback("checkNonZeroComplianceInput", {&defaultCompliance, &compliance}, [this](const core::DataTracker& t) + { + // Update of the defaultCompliance data + if(t.hasChanged(defaultCompliance)) + { + if(defaultCompliance.getValue() == 0.0) + { + msg_error() << "Zero defaultCompliance is set: this will cause the constraint resolution to diverge"; + return sofa::core::objectmodel::ComponentState::Invalid; + } + return sofa::core::objectmodel::ComponentState::Valid; + } + // Update of the compliance data + else + { + // Case: soft body + if constexpr (!sofa::type::isRigidType()) + { + const VecReal &comp = compliance.getValue(); + if (std::any_of(comp.begin(), comp.end(), [](const Real c) { return c == 0; })) + { + msg_error() << "Zero values set in the compliance vector: this will cause the constraint resolution to diverge"; + return sofa::core::objectmodel::ComponentState::Invalid; + } + } + // Case: rigid body + else + { + const VecReal &comp = compliance.getValue(); + sofa::Size compSize = comp.size(); + + if (compSize % 7 != 0) + { + msg_error() << "Compliance vector should be a multiple of 7 in rigid case (1 for translation dofs, and 6 for the rotation matrix)"; + return sofa::core::objectmodel::ComponentState::Invalid; + } + + for(auto i = 0; i < comp.size() ; i += 7) + { + if(comp[i] == 0.) + { + msg_error() << "Zero compliance set on translation dofs: this will cause the constraint resolution to diverge (compliance[" << i << "])"; + return sofa::core::objectmodel::ComponentState::Invalid; + } + // Check if the translational compliance and the diagonal values of the rotation compliance matrix are non zero + // In Rigid case, the inertia matrix generates this 3x3 rotation compliance matrix + // In the compliance vector comp, SOFA stores: + // - the translational compliance (comp[0]) + // - the triangular part of the rotation compliance matrix: r[0,0]=comp[1],r[0,1],r[0,2],r[1,1]=comp[4],r[1,2],r[2,2]=comp[6] + if(comp[i+1] == 0. || comp[i+4] == 0. || comp[i+6] == 0.) + { + msg_error() << "Zero compliance set on rotation dofs (matrix diagonal): this will cause the constraint resolution to diverge (compliance[" << i << "])"; + return sofa::core::objectmodel::ComponentState::Invalid; + } + } + } + return sofa::core::objectmodel::ComponentState::Valid; + } + + }, {} + ); } template @@ -123,7 +186,7 @@ void UncoupledConstraintCorrection::init() { Inherit::init(); - if( !defaultCompliance.isSet() && !compliance.isSet() ) + if (!defaultCompliance.isSet() && !compliance.isSet()) { msg_warning() << "Neither the \'defaultCompliance\' nor the \'compliance\' data is set, please set one to define your compliance matrix"; } @@ -205,6 +268,8 @@ void UncoupledConstraintCorrection::init() } d_useOdeSolverIntegrationFactors.setReadOnly(true); } + + this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); } template @@ -216,6 +281,9 @@ void UncoupledConstraintCorrection::reinit() template void UncoupledConstraintCorrection::getComplianceWithConstraintMerge(linearalgebra::BaseMatrix* Wmerged, std::vector &constraint_merge) { + if(!this->isComponentStateValid()) + return; + helper::WriteAccessor > constraintsData = *this->mstate->write(core::MatrixDerivId::constraintJacobian()); MatrixDeriv& constraints = constraintsData.wref(); @@ -286,6 +354,9 @@ void UncoupledConstraintCorrection::getComplianceWithConstraintMerge( template void UncoupledConstraintCorrection::addComplianceInConstraintSpace(const sofa::core::ConstraintParams * cparams, sofa::linearalgebra::BaseMatrix *W) { + if(!this->isComponentStateValid()) + return; + const MatrixDeriv& constraints = cparams->readJ(this->mstate)->getValue() ; VecReal comp = compliance.getValue(); Real comp0 = defaultCompliance.getValue(); @@ -402,6 +473,9 @@ void UncoupledConstraintCorrection::addComplianceInConstraintSpace(co template void UncoupledConstraintCorrection::getComplianceMatrix(linearalgebra::BaseMatrix *m) const { + if(!this->isComponentStateValid()) + return; + const VecReal& comp = compliance.getValue(); const Real comp0 = defaultCompliance.getValue(); const unsigned int s = this->mstate->getSize(); // comp.size(); @@ -438,6 +512,9 @@ void UncoupledConstraintCorrection::computeMotionCorrection(const cor { SOFA_UNUSED(cparams); + if(!this->isComponentStateValid()) + return; + auto writeDx = sofa::helper::getWriteAccessor( *dx[this->getMState()].write() ); const Data& f_d = *f[this->getMState()].read(); computeDx(f_d, writeDx.wref()); @@ -447,6 +524,8 @@ void UncoupledConstraintCorrection::computeMotionCorrection(const cor template void UncoupledConstraintCorrection::applyMotionCorrection(const core::ConstraintParams *cparams, Data< VecCoord > &x_d, Data< VecDeriv > &v_d, Data& dx_d, const Data< VecDeriv > &correction_d) { + if(!this->isComponentStateValid()) + return; auto dx = sofa::helper::getWriteAccessor(dx_d); auto correction = sofa::helper::getReadAccessor(correction_d); @@ -479,6 +558,9 @@ void UncoupledConstraintCorrection::applyMotionCorrection(const core: template void UncoupledConstraintCorrection::applyPositionCorrection(const core::ConstraintParams *cparams, Data< VecCoord > &x_d, Data< VecDeriv >& dx_d, const Data< VecDeriv > &correction_d) { + if(!this->isComponentStateValid()) + return; + auto dx = sofa::helper::getWriteAccessor(dx_d); auto correction = sofa::helper::getReadAccessor(correction_d); @@ -504,6 +586,9 @@ void UncoupledConstraintCorrection::applyPositionCorrection(const cor template void UncoupledConstraintCorrection::applyVelocityCorrection(const core::ConstraintParams *cparams, Data< VecDeriv > &v_d, Data& dv_d, const Data< VecDeriv > &correction_d) { + if(!this->isComponentStateValid()) + return; + auto dx = sofa::helper::getWriteAccessor(dv_d); auto correction = sofa::helper::getReadAccessor(correction_d); @@ -529,6 +614,9 @@ void UncoupledConstraintCorrection::applyVelocityCorrection(const cor template void UncoupledConstraintCorrection::applyContactForce(const linearalgebra::BaseVector *f) { + if(!this->isComponentStateValid()) + return; + helper::WriteAccessor > forceData = *this->mstate->write(core::VecDerivId::externalForce()); VecDeriv& force = forceData.wref(); const MatrixDeriv& constraints = this->mstate->read(core::ConstMatrixDerivId::constraintJacobian())->getValue(); @@ -657,6 +745,9 @@ void UncoupledConstraintCorrection::addConstraintDisplacement(SReal * /// constraint_force contains the force applied on dof involved with the contact /// TODO : compute a constraint_disp that is updated each time a new force is provided ! + if(!this->isComponentStateValid()) + return; + const MatrixDeriv& constraints = this->mstate->read(core::ConstMatrixDerivId::constraintJacobian())->getValue(); for (int id = begin; id <= end; id++) diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/RestShapeSpringsForceField.inl b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/RestShapeSpringsForceField.inl index 021b704a5ff..8f3ece6a311 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/RestShapeSpringsForceField.inl +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/RestShapeSpringsForceField.inl @@ -28,34 +28,11 @@ #include #include #include +#include #include #include -namespace // anonymous -{ - // Boiler-plate code to test if a type implements a method - // explanation https://stackoverflow.com/a/30848101 - - template - using void_t = void; - - // Primary template handles all types not supporting the operation. - template class, typename = void_t<>> - struct detect : std::false_type {}; - - // Specialization recognizes/validates only types supporting the archetype. - template class Op> - struct detect>> : std::true_type {}; - - // Actual test if DataType::Coord implements getOrientation() (hence is a RigidType) - template - using isRigid_t = decltype(std::declval().getOrientation()); - - template - using isRigidType = detect; -} // anonymous - namespace sofa::component::solidmechanics::spring { @@ -170,7 +147,7 @@ void RestShapeSpringsForceField::bwdInit() /// Compile time condition to check if we are working with a Rigid3Types or a type that does not /// need the Angular Stiffness parameters. //if constexpr (isRigid()) - if constexpr (isRigidType()) + if constexpr (sofa::type::isRigidType()) { sofa::helper::ReadAccessor> s = d_stiffness; sofa::helper::WriteOnlyAccessor> as = d_angularStiffness; @@ -392,7 +369,7 @@ void RestShapeSpringsForceField::addForce(const MechanicalParams* mp const auto activeDirections = d_activeDirections.getValue(); // rigid case - if constexpr (isRigidType()) + if constexpr (sofa::type::isRigidType()) { // translation if (i >= m_pivots.size()) @@ -475,7 +452,7 @@ void RestShapeSpringsForceField::addDForce(const MechanicalParams* mp const sofa::Index curIndex = m_indices[i]; const auto stiffness = k[static_cast(i < k.size()) * i]; - if constexpr (isRigidType()) + if constexpr (sofa::type::isRigidType()) { const auto angularStiffness = k_a[static_cast(i < k_a.size()) * i]; @@ -597,7 +574,7 @@ void RestShapeSpringsForceField::addKToMatrix(const MechanicalParams* } // rotation (if applicable) - if constexpr (isRigidType()) + if constexpr (sofa::type::isRigidType()) { const auto vr = -kFact * k_a[(index < k_a.size()) * index]; for (sofa::Size i = space_size; i < total_size; i++) @@ -634,7 +611,7 @@ void RestShapeSpringsForceField::buildStiffnessMatrix(core::behavior: } // rotation (if applicable) - if constexpr (isRigidType()) + if constexpr (sofa::type::isRigidType()) { const auto vr = -k_a[(index < k_a.size()) * index]; for (sofa::Size i = space_size; i < total_size; ++i) diff --git a/Sofa/framework/Type/CMakeLists.txt b/Sofa/framework/Type/CMakeLists.txt index e0195bf9071..9371b860db3 100644 --- a/Sofa/framework/Type/CMakeLists.txt +++ b/Sofa/framework/Type/CMakeLists.txt @@ -60,6 +60,7 @@ set(SOURCE_FILES ${SOFATYPESRC_ROOT}/vector_Integral.cpp ${SOFATYPESRC_ROOT}/vector_String.cpp ${SOFATYPESRC_ROOT}/SVector.cpp + ${SOFATYPESRC_ROOT}/isRigidType.h ) sofa_find_package(Sofa.Config REQUIRED) diff --git a/Sofa/framework/Type/src/sofa/type/isRigidType.h b/Sofa/framework/Type/src/sofa/type/isRigidType.h new file mode 100644 index 00000000000..41e17b5f9de --- /dev/null +++ b/Sofa/framework/Type/src/sofa/type/isRigidType.h @@ -0,0 +1,31 @@ +// +// Created by hugo on 28/11/23. +// + +#ifndef SOFA_ISRIGIDTYPE_H +#define SOFA_ISRIGIDTYPE_H + +namespace sofa::type +{ + // Boiler-plate code to test if a type implements a method + // explanation https://stackoverflow.com/a/30848101 + + template + using void_t = void; + + // Primary template handles all types not supporting the operation. + template class, typename = void_t<>> + struct detect : std::false_type {}; + + // Specialization recognizes/validates only types supporting the archetype. + template class Op> + struct detect>> : std::true_type {}; + + // Actual test if DataType::Coord implements getOrientation() (hence is a RigidType) + template + using isRigid_t = decltype(std::declval().getOrientation()); + + template + using isRigidType = detect; +} +#endif //SOFA_ISRIGIDTYPE_H From 42cc4d4e96781e8dc873a9975764839a6f230295 Mon Sep 17 00:00:00 2001 From: Paul Baksic <30337881+bakpaul@users.noreply.github.com> Date: Wed, 10 Jan 2024 11:06:04 +0100 Subject: [PATCH 43/45] [All] Fix subplugin regression tests (#4420) * Add relative path to references files into regression-tests files * fix typo --- applications/plugins/RegressionStateScenes.regression-tests | 3 +++ examples/RegressionStateScenes.regression-tests | 3 +++ examples/RegressionTopologyScenes.regression-tests | 3 +++ 3 files changed, 9 insertions(+) diff --git a/applications/plugins/RegressionStateScenes.regression-tests b/applications/plugins/RegressionStateScenes.regression-tests index f89599f5330..fe2d67684b1 100644 --- a/applications/plugins/RegressionStateScenes.regression-tests +++ b/applications/plugins/RegressionStateScenes.regression-tests @@ -2,6 +2,9 @@ # REGRESSION_TEST DOES NOT SUPPORT DASHES ("-") IN SCENE NAMES. # USE UNDERSCORES ("_") INSTEAD. +### References relative path ### +../projects/Regression/references/applications/plugins + ### Sph Plugin ### SofaSphFluid/examples/SPHFluidForceField.scn 100 1e-4 1 1 SofaSphFluid/examples/SPHFluidForceField_benchmarks.scn 100 1e-4 1 1 diff --git a/examples/RegressionStateScenes.regression-tests b/examples/RegressionStateScenes.regression-tests index 7ac5834edf8..de108be75b9 100644 --- a/examples/RegressionStateScenes.regression-tests +++ b/examples/RegressionStateScenes.regression-tests @@ -8,6 +8,9 @@ # REGRESSION_TEST DOES NOT SUPPORT DASHES ("-") IN SCENE NAMES. # USE UNDERSCORES ("_") INSTEAD. +### References relative path ### +../applications/projects/Regression/references/examples + ### Demo scenes ### Demos/TriangleSurfaceCutting.scn 100 1e-4 1 1 Demos/chainAll.scn 100 1e-2 1 1 diff --git a/examples/RegressionTopologyScenes.regression-tests b/examples/RegressionTopologyScenes.regression-tests index 379dd0b5c59..a789f64974a 100644 --- a/examples/RegressionTopologyScenes.regression-tests +++ b/examples/RegressionTopologyScenes.regression-tests @@ -2,6 +2,9 @@ # REGRESSION_TEST DOES NOT SUPPORT DASHES ("-") IN SCENE NAMES. # USE UNDERSCORES ("_") INSTEAD. +### References relative path ### +../applications/projects/Regression/references/examples + ### Topology scenes ### Component/Topology/Mapping/Tetra2TriangleTopologicalMapping.scn 30 1e-4 1 From 44ad5193836c77b810eb305debb81af62a7929fe Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Wed, 10 Jan 2024 13:14:25 +0100 Subject: [PATCH 44/45] [Type] Refactor Mat (#4396) remove inheritance and use std::array Co-authored-by: Paul Baksic <30337881+bakpaul@users.noreply.github.com> --- Sofa/framework/Type/src/sofa/type/Mat.h | 72 ++++++++++++++++--- .../ParallelTetrahedronFEMForceField.inl | 8 ++- 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/Sofa/framework/Type/src/sofa/type/Mat.h b/Sofa/framework/Type/src/sofa/type/Mat.h index 06262ce7e62..cf1ca2a5ead 100644 --- a/Sofa/framework/Type/src/sofa/type/Mat.h +++ b/Sofa/framework/Type/src/sofa/type/Mat.h @@ -57,26 +57,38 @@ constexpr Mat multTranspose(const Mat& m1, const Mat -class Mat : public fixed_array, L> +class Mat { public: - static constexpr sofa::Size N = L * C; - typedef typename fixed_array::size_type Size; + typedef VecNoInit LineNoInit; + using ArrayLineType = std::array; typedef real Real; typedef Vec Line; - typedef VecNoInit LineNoInit; typedef Vec Col; + typedef sofa::Size Size; static constexpr Size nbLines = L; static constexpr Size nbCols = C; - constexpr Mat() noexcept - { - clear(); - } + typedef sofa::Size size_type; + typedef Line value_type; + typedef typename ArrayLineType::iterator iterator; + typedef typename ArrayLineType::const_iterator const_iterator; + typedef typename ArrayLineType::reference reference; + typedef typename ArrayLineType::const_reference const_reference; + typedef std::ptrdiff_t difference_type; + + static constexpr sofa::Size static_size = L; + static constexpr sofa::Size total_size = L; + + static constexpr sofa::Size size() { return static_size; } + + ArrayLineType elems{}; + + constexpr Mat() noexcept = default; explicit constexpr Mat(NoInit) noexcept { @@ -138,7 +150,7 @@ class Mat : public fixed_array, L> typename = std::enable_if_t< (sizeof...(ArgsT) == L && sizeof...(ArgsT) > 1) > > constexpr Mat(ArgsT&&... r) noexcept - : sofa::type::fixed_array(std::forward(r)...) + : elems{ std::forward(r)... } {} /// Constructor from an element @@ -796,6 +808,48 @@ class Mat : public fixed_array, L> this->elems[l][c] = this->elems[c][l] = ( this->elems[l][c] + this->elems[c][l] ) * 0.5f; } + + // direct access to data + constexpr const real* data() const noexcept + { + return elems.data(); + } + + constexpr typename ArrayLineType::iterator begin() noexcept + { + return elems.begin(); + } + constexpr typename ArrayLineType::const_iterator begin() const noexcept + { + return elems.begin(); + } + + constexpr typename ArrayLineType::iterator end() noexcept + { + return elems.end(); + } + constexpr typename ArrayLineType::const_iterator end() const noexcept + { + return elems.end(); + } + + constexpr reference front() + { + return elems[0]; + } + constexpr const_reference front() const + { + return elems[0]; + } + constexpr reference back() + { + return elems[N - 1]; + } + constexpr const_reference back() const + { + return elems[N - 1]; + } + }; diff --git a/applications/plugins/MultiThreading/src/MultiThreading/component/solidmechanics/fem/elastic/ParallelTetrahedronFEMForceField.inl b/applications/plugins/MultiThreading/src/MultiThreading/component/solidmechanics/fem/elastic/ParallelTetrahedronFEMForceField.inl index b272d51a066..e144a95b764 100644 --- a/applications/plugins/MultiThreading/src/MultiThreading/component/solidmechanics/fem/elastic/ParallelTetrahedronFEMForceField.inl +++ b/applications/plugins/MultiThreading/src/MultiThreading/component/solidmechanics/fem/elastic/ParallelTetrahedronFEMForceField.inl @@ -154,17 +154,19 @@ void ParallelTetrahedronFEMForceField::addKToMatrix(sofa::linearalgeb std::mutex mutex; + static constexpr auto S = DataTypes::deriv_total_size; // size of node blocks + static constexpr auto N = Element::size(); + using Block = sofa::type::fixed_array, 4>, 4>; + sofa::simulation::parallelForEachRange(*m_taskScheduler, indexedElements.begin(), indexedElements.end(), [&indexedElements, m, &Rot, this, &offset, mat, &mutex, kFactor](const auto& range) { - constexpr auto S = DataTypes::deriv_total_size; // size of node blocks - constexpr auto N = Element::size(); + StiffnessMatrix JKJt,tmp; auto elementId = std::distance(indexedElements.begin(), range.start); - using Block = sofa::type::fixed_array, 4>, 4>; sofa::type::vector blocks; blocks.reserve(std::distance(range.start, range.end)); From 4abcbe6af05cbc8183df5663e0e6b231a8d69280 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Wed, 10 Jan 2024 17:08:48 +0100 Subject: [PATCH 45/45] [sofaInfo] Fix compilation and behavior (#4422) Co-authored-by: Paul Baksic <30337881+bakpaul@users.noreply.github.com> --- applications/projects/CMakeLists.txt | 1 + applications/projects/sofaInfo/CMakeLists.txt | 9 ++-- applications/projects/sofaInfo/sofaInfo.cpp | 54 ++++++++----------- 3 files changed, 27 insertions(+), 37 deletions(-) diff --git a/applications/projects/CMakeLists.txt b/applications/projects/CMakeLists.txt index 48eebc64ff8..8669b0a1415 100644 --- a/applications/projects/CMakeLists.txt +++ b/applications/projects/CMakeLists.txt @@ -16,3 +16,4 @@ sofa_add_subdirectory(application sofaOPENCL sofaOPENCL OFF) sofa_add_subdirectory(directory Regression Regression EXTERNAL) sofa_add_subdirectory(directory SofaGLFW SofaGLFW EXTERNAL) sofa_add_subdirectory(application sofaProjectExample sofaProjectExample) +sofa_add_subdirectory(application sofaInfo sofaInfo) diff --git a/applications/projects/sofaInfo/CMakeLists.txt b/applications/projects/sofaInfo/CMakeLists.txt index d3fe466de1b..6a8724633f7 100644 --- a/applications/projects/sofaInfo/CMakeLists.txt +++ b/applications/projects/sofaInfo/CMakeLists.txt @@ -1,10 +1,9 @@ cmake_minimum_required(VERSION 3.12) project(sofaInfo) -find_package(SofaGeneral) -find_package(SofaMisc) -find_package(SofaBase) -find_package(SofaCommon) +find_package(Sofa.Config) +sofa_find_package(Sofa.Component) +sofa_find_package(Sofa.Simulation.Graph) add_executable(${PROJECT_NAME} sofaInfo.cpp) -target_link_libraries(${PROJECT_NAME} SofaGeneral SofaBase SofaCommon SofaMisc) +target_link_libraries(${PROJECT_NAME} Sofa.Component Sofa.Simulation.Graph) diff --git a/applications/projects/sofaInfo/sofaInfo.cpp b/applications/projects/sofaInfo/sofaInfo.cpp index 0f816ec632d..0433fb89bad 100644 --- a/applications/projects/sofaInfo/sofaInfo.cpp +++ b/applications/projects/sofaInfo/sofaInfo.cpp @@ -19,32 +19,31 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#include -#include -#include #include +#include +#include +#include +#include +#include // --------------------------------------------------------------------- // --- // --------------------------------------------------------------------- int main(int /*argc*/, char** argv) { - sofa::simulation::tree::init(); - sofa::component::initSofaBase(); - sofa::component::initSofaCommon(); - sofa::component::initSofaGeneral(); + sofa::simulation::common::init(); + sofa::simulation::graph::init(); + sofa::component::init(); - if (argv[1] == NULL) + if (argv[1] == nullptr) { std::cout << "Usage: sofaInfo FILE" << std::endl; return -1; } - sofa::simulation::setSimulation(new sofa::simulation::tree::TreeSimulation()); + sofa::simulation::Node::SPtr groot = sofa::simulation::node::load(argv[1]); - sofa::simulation::Node::SPtr groot = sofa::core::objectmodel::SPtr_dynamic_cast( sofa::simulation::getSimulation()->load(argv[1])); - - if (groot==NULL) + if (groot == nullptr) { groot = sofa::simulation::getSimulation()->createNewGraph(""); } @@ -56,14 +55,14 @@ int main(int /*argc*/, char** argv) groot->getTreeObjects(&objects); // get the classes and targets of the scene - for (unsigned int i=0; igetEntry(objects[i]->getClassName()); - if (entry.creatorMap.empty()) + sofa::core::ObjectFactory::ClassEntry& entry = sofa::core::ObjectFactory::getInstance()->getEntry(object->getClassName()); + if (!entry.creatorMap.empty()) { classNames.insert(entry.className); - sofa::core::ObjectFactory::CreatorMap::iterator it = entry.creatorMap.find(objects[i]->getTemplateName()); + const auto it = entry.creatorMap.find(object->getTemplateName()); if (it != entry.creatorMap.end() && *it->second->getTarget()) { targets.insert(it->second->getTarget()); @@ -71,27 +70,18 @@ int main(int /*argc*/, char** argv) } } - std::set::const_iterator it = classNames.begin(); - std::set::const_iterator end = classNames.end(); std::cout << "=== CLASSES ===" << std::endl; - while (it != end) - { - std::cout << (*it) << std::endl; - it++; - } + std::cout << sofa::helper::join(classNames, "\n"); - it = targets.begin(); - end = targets.end(); std::cout << std::endl << "=== TARGETS ===" << std::endl; - while (it != end) + std::cout << sofa::helper::join(targets, "\n"); + + if (groot != nullptr) { - std::cout << (*it) << std::endl; - it++; + sofa::simulation::node::unload(groot); } - if (groot!=NULL) - sofa::simulation::getSimulation()->unload(groot); - - sofa::simulation::tree::cleanup(); + sofa::simulation::common::cleanup(); + sofa::simulation::graph::cleanup(); return 0; }

  • W W " -" 2W 4W ,W HW 3W :V MW KWU.U 4VAV &V 5U *U 2V 6gGU KU 5W?W =U/V\"U/V IU7V LX ,WNW 5WNW 5WNW 5WNW 5WNW 5WNW 4XHX H[4U&X -X -" -"X -X -X -X -X -X ,X6]&`8X\"Z7Z#Z7Z#Z7Z#Z7Z#Z7Z 'Z8['X/X'X/X'X/X'X/X)Y8Y MX ,W:W 9V 0V 3U@U ?[ 1V 0V 3U@V GV 0V 3U?U 8h 1V 0V 2U@U " -" CV 0V 1U@U >V 7W *`L` I`L` I`L` I`L` I`L` JV =X,X >T 6] 9k\"lKl K_ #\\ 'Y8S MX 2VFV %VBV Nk IVAV=V$X 1V %V +V " -"6YHTHY -V EW 5Y>Y :X ?R5Z .Y ;VMX DX +Y DX IYW W 2W 4W ,W HW 3W :V MW KW;W De =W " -" -X *W:W V$X 1V &W +W 5XITIX +V EV 4X[ JX -XNW8WNX0a9X#Y3Y(X9Y JY3Y(X9Y NX LX W W 2W 4W ,W HW " -" 3W :V MW LX;W Df >W ,W +W8W >WLW @Y 2X +Z3Z!t\"X0X)X?X?X*Y3Y Kj 9V 9j AS 5X 8W:W HV /W #T)T KV " -" @T(T 6U?U &V 5T +V AhGU KU 5V=V =U0V!U0V JV7V WLW 7WLW 7WLW 7WLW 7WLW 7XNX 6XGX IY.R&X -X -X -X -X -X -X -X ,X2Z'a9X#Y3Y%Y3Y%Y3Y%Y3Y%Y3" -"Y )Y3Z)X/X'X/X'X/X'X/X'X:X Ki >W8V *XHZ FW ,ZW W " -" 2W 4W ,W HW 3W :V MW LW:W Dg ?W ,X ,W8W >WLW ?Y 3X +Y1Y\"v#X0X)X?X?X+Y1Y MYNVNY :V :" -"YNVNY BS 5X 8XU1V U1V KW7V NWLW 7WLW 7WLW 7WLW 7WLW 7WLW 6XGX JY,Q&X -X " -"-X -X -X -X -X -X ,X1Z(XNX:X$Y1Y'Y1Y'Y1Y'Y1Y'Y1Y P)P$Y3[)X/X'X/X'X/X'X/X'YVKX DX -X BX IX8X NX7W KP 1P =X Y *Z W 0W MW +ZAZ 0W >W W 2W 4W ,W HW 3W :V MW LW:W DSF[ @X -X " -" -X8W ?WJW ?Y 4X ,Y/Y%z%X0X)X?X?X,Y/Y YMVMY ;V ;YMVMY CS 5X 5P*Q JWU2V NU2V$_7V NXLX 9XLX 9XLX 9XLX 9XLX 8WLW 6XGX KY*P&X -X -X -X -X -X -X -X ,X0Z)XNX:X%Y/Y)Y/Y)Y/Y)Y/Y)Y/Y\"R+R&Y3]*X/X'X/X'X/X'X/X&Y>Y Jp EW:Y " -" +R@Y 7Q 2W .XEVFY\"X5Y\"X5Y\"X5Y\"X5Y NV ;X/X 0V 5T 8c ^ AW4W ?Z >W6W KY " -" \"Y 0X 2VFV &VCW#[LSKZ KV?V@V\"W 0V 'W )W 1XNTNX &V FW 6Y:Y X *Z NW 0W MW ,Z?Z 1W >W W 2W 4W ,W H" -"W 3W :V MW LW:W DPAY ?Y .W -W6W @WJW >Y 5X ,X-X&_MXM_&X0X)X?X?X,Y/Y !YLVLY " -"W FV /X 'TCfFT2i CUGfBT 9U?U &V 7U 5] >iGU KU 6V;V >U2V NU2V$]5V NWJW 9WJW 9WJW 9WJW 9WJW 9WJW 8XFX KY /X -X -X -X -X -X -X -X ,X" -"/Y)XMX;X%Y/Y)Y/Y)Y/Y)Y/Y)Y/Y#T-T'Y3]*X/X'X/X'X/X'X/X%X>X Ir GW=\\ GY 9S 3W /XDVDX$X2X$X2X$X" -"2X$X2X V ;X0X 0X 7T 8d X$X-WJW EX6X Y .X.Y)X -X -Y .X/X'X -X -XBZ EX -XLV:VLX0XMX;X&Y-Y+X7X NY-Y+X7X!X KX Z W FV .X (TDgFT3j CTFhDT 9U?U &V 8U 4\\ =iGU KU 6V" -";V >U3V MU3V#\\5V MWJW 9WJW 9WJW 9WJW 9WJW 9WJW 8XFX LY .X -X -X -X -X -X -X -X ,X.Y*XMX;X&Y-Y+Y-Y+Y-Y+Y-Y+Y-Y%V/V)Y3_+X/X'X/X'X/X'X/X%Y@Y Is HW?^ " -"?Z /Z /Z /Z /Z /Z /Z6Y NZ 0Z /Z /Z /Z 8Y 1Y 3Z /Z /Z /Z /Z 3ZCV 5WDX DXCVCW%X0W%X0W%X0W%X0W V :X1X 0X 7T 9f =k#~`\"h Cf " -"EW4W @\\ ?X8X LX !Y /X 2VFV 'VBV#XHSET KV?VAV!W 0V (W 'W .` \"V GW 5X8X W\"W.XJX" -" FX6X X -X.Y)X -X -X -X/X'X -X -XCZ DX -XLV:VLX0XLX^4WG_ 9` @WG^ 9^GW MWG\\ ;f Gm ^BV\"W:W 3X ?^ 0e AWG_ KV.X ?X Z 7X -X+X)\\HXH\\(X0X)X?X?X-X+X $YJVJY >V >YJVJY Ma =X 7V0V JW@W EV .Y *TEiET5k DTEiDT :VAV &V 9U 3_ ;W6W NiGU " -"KU 6V;V >U3V MU3V#_8V NXJX ;XJX ;XJX ;XJX ;XJX ;XJX :XEX LX -X -X -X -X -X -X -X -X ,X.Y*XLXa'b 7` 5` 5` 5` AW ,W ,W ,W DY EWG_ 9` 5` 5` 5` 5` (Z <`GV W6W MW6W MW6W MW6W#W1X NWG^ HW1X NWBVBW&W.W&WJP:PJW&W4PJW&W." -"W!V :X2X 0X 6S 8g >k#~`#j Fj GW4W @\\ >W8W LX X .X 2VFV 'VBV$XGSCR KV?VBV X 1V (W 'W ,\\ V GW 5X8X f CWIb =bIW MWI^ =j Im U4V LU4V\"`:V GX /WHW ;WHW ;WHW ;WHW ;WHW ;WHW :XEX MY -X -X -X -X -X -X -X -X ,X-Y+XKWf ;f ;f ;f ;f +Z >eJU NW6W MW6W MW6W MW6W\"W" -"2W MWIb IW2W NWAVAW(W,W(WJRU5V KU5V GXTKW)W4TKW)W+W\"V 9X3X 2X 5T :k ?i\"~`$m Jn IW4W A^ ?X:X MW " -" NY .X 2VFV 7~X2XFS VIV>X2YIY DYFY +Z JW .V NW 1Y3Y 1n DWLh Bm ChLW Gk Ll 6hLW MWKg HW ,W ,W;Y JW " -",WKfGg8WKg Cl FWLh ChLW MWK` @m Im Y =W6W JW-W&YJb }!WCWCW Hk Dx&{ W4W CWFW P JSCVAVDS :WEV $V W6W NiGU KU 6V" -";V BP>P /U5V KU5V EW=V FX 0XHX =XHX =XHX =XHX =XHX =XHX W:X MW NX -X 2VFV 7~X2WES WKX0XJX>X(Y)X,X7X!Y)X,X7X!Y LX VIV>X1YKY BXFX +Z IW .W " -" W 2Y1Y 2o EWMj Dn DjMW Hn Nl 7jMW MWLi IW ,W ,WW6W NiGU KU 6V;V BQ?Q 0U6V JU6V BU>V EX 0WFW =WFW =WFW =WFW =WFW =WFW X(Y)X.Y)X.Y)X.Y)X.Y)X%Z9Z*Y6WJX,X/X'X/X'X/X'X/X!XFX EX;Z LWDX ?o Do Do Do Do Do DoKn4n Cn Cn Cn Cn HW ,W ,W ,W %l HWLi En Cn Cn Cn Cn /Z Cs LW6W MW6" -"W MW6W MW6W!W4W LWMj LW4W W?V?V+W(V+WKXBXKV+W5XKV+W(V$W 8W4X 2X 5T ;n ?g!~_%p LZDZ JW4W A^ >W:W MW MX -X 2VFV 7~X2WES VJX0XIW>X(X" -"'X-X7X!X'X-X7X!Y LX VIV>X1YKY AXHX +Z HW -V W 3Y/Y 3p FWMk Fo EkMW Io Nl 8kMW MWMk JW ,W ,W=Y HW ,WMjJj:WMk Gp HWMk GkMW MWMb Bo Im \\>W0X=X LW5X u 6W :V MW EkJV Wj Fn CWMk\"\\6X =Z >W6W KW+W)[Ke\"}!WCWCW Jo Hz&{ W4W DWDW ;Y ;X /X'X.YBXBY+X0X)X?X?X/X'X#T HV IT " -":V ;T3T :V CV +o BX 6ZM`MZ GXFX CV *\\ 3SFW,S:V>V 0R@R KSBV@VDS 9e #V ?W \"V ?W6W NiGU KU 6V;V BR@R 1U6V JU6V BV?V EX 1XFX ?XFX ?XFX ?XFX" -" ?XFX ?XFW =XCX NX +X -X -X -X -X -X -X -X ,X+X,XIW>X(X'X/X'X/X'X/X'X/X'X%Z;Z)X5VHX-X/X'X/X'X/X'X/X XHX DX:Y LWEX >p Ep Ep Ep Ep Ep EpMp6o Do Do Do Do" -" HW ,W ,W ,W 'o IWMk Gp Ep Ep Ep Ep 0Z Ds KW6W MW6W MW6W MW6W!W5X LWMk MW5X V>V?W,V'W,VKZDYKW,V5YKW,V'W%W 8X5W 2X 4T ;o @g ~^%q NY@Y KW4W B`" -" ?XX -XJW@WJX0XIX?X(X'X-X7X!X'X-X8Y Y MX W/YMY @YJY +Y GW -V W 4X+X 4YE\\ FWNXG\\ H]EX F\\GXNW J\\F[ " -"GW ,\\GXNW MWNXG[ JW ,W ,W?Z GW ,WNXH[KXH[:WNXG[ H]H] IWNXG\\ I\\GXNW MWNXFQ C\\CW CW ,W6W!X6X NW?\\?W.X?X JW6W 1X 6W :V MW 9X=X\"[IZKW W=Y /W @m H]DV " -"CWNXG[\"\\6W =[ >W6W LW)W*ZJWKY\"}!WCWCW K\\H] J{&{ V3W DWDW :Y XCX NX +X -X -X -X -X -X -X -X ,X+X,XIX?" -"X(X'X/X'X/X'X/X'X/X'X$Z=Z(X6WHX-X/X'X/X'X/X'X/X YJY DX9Y MWEW =YE\\ EYE\\ EYE\\ EYE\\ EYE\\ EYE\\ EYE]N\\G[7]EX E\\F[ F\\F[ F\\F[ F\\F[ IW ,W ,W ,W (p IWNXG[ H]H" -"] G]H] G]H] G]H] G]H] 1Z E]H^ JW6W MW6W MW6W MW6W W6W KWNXG\\ MW6W NV>V>V,V&V,VJZFYIV,V6YIV,V&V%W 7W6X 3X LR:T ;q @e N~^&s!Y>Y LW4W B` >WXJX +Z GW -W !W 5X)X 5U>Z G_CZ I[>T FZC_ KZAZ HW -ZB_ " -"M^BZ KW ,W ,W@Z FW ,^CZMVCZ;^BZ IZBZ I_CZ IZC_ M^ 5YY .W AXJa IZW2W EWDW 9Y =X /X'X/YAXAY,X0X)X?X?X/X'X%X JV KX Z FU>Z FU>Z FU>Z FU>Z FU>Z FU>eBZ9[>T FZAZ HZAZ HZAZ HZAZ JW ,W ,W ,W )r J^BZ IZBZ GZBZ GZBZ GZBZ" -" GZBZ 1Z EZB[ JW6W MW6W MW6W MW6W W6W K_CZ MW6W V=V>V-V%V-VHZHYHV-V6YHV-V%V%W 7X7X 4X NU:T WX !Y 0Y BVDX Dk CXJc -X BX>X LX5Y MX -X Ee Le 3Z ?U=bKUCU6XDX IX9Y X +X+X+X -X /X +X/X" -"'X -X -XL[ Y J]?Y KY?] M] 4X8P CW ,W6W X8X MW?\\?W-XAX IW7X 3Y 5W :V MW =_C_(YBXLV NW?Z -W CXC\\ KY ,]@Y LW8X >] ?W6W LW)W,YHWHY MW=W JWCWCW MY>Y " -"L[B[ ;W >W2W FWBW 9Y >X 0X%X0X@X@X,X0X)X?X?X/X'X&Y JV KY =V >Y7Y =V CV .[HSFR BX 3t BWHW AV .WN\\ 9SFV)S;V?W 3UCU LSAV@VCS 7_ V BV LU ?W" -"6W MhGU KU 5W?W AUCU 4U8V HU8V ?UAV CX 2XDX AXDX AXDX AXDX AXDX AXDX @XBX NX +X -X -X -X -X -X -X -X ,X+X,XHX@X(X'X/X'X/X'X/X'X/X'X\"ZAZ&X8WFX-X/X'" -"X/X'X/X'X/X MXLX BX8X MWFW Y;Z:R GY=Y JY=Y JY=Y JY=Y KW ,W ,W ,W *]E[ J]@Y JY>Y IY>Y IY>Y IY>Y IY>Y 2Z FY>Y JW6W MW" -"6W MW6W MW6W W7X K]?Y NW7X V=V=U-V$U-VGZJYFU-V7YFU-V$U%W 7X8X &~X/X:T =t @c L~\\'v\"W:W LW4W CXNX ?X>X MV $x EX 2~X2WES :VDW" -"EV FZ :W #W 7XKTKX )V IV 4X4X >X !X 0Y BWDX Dm FXKf /Y AYBY KX5Y MX -X Gd ~X d 5Y ?V>dLUCU6WBW IX;Z Y +X+Y,X -X 0Y +X/X'X -X -XM[ ;X -XIWBWIX" -"0XGW@X)Y'Y.X8X!Y'Y.X9Y M] #X aEa)X@XNW NWA[ ,W DW?[ LX +[=X KW:X =] ?W6W MW'W-XGWGX MW=W JWCWCW MXZ W2W FWBW 9Z ?X" -" 0X%X0X@X@X,X0X(X@X@X/Y'Y(Y IV JY >V ?Y5Y >V CV .YFSDP BX 2q @XJX AV /WK[ :SFV)S;V@X 4VDV LSAV@VCS 6\\ MV CV KU ?W6W MhGU KU 4V?V @V" -"DV 5U9V GU9V >UBV BX 2WBW AWBW AWBW AWBW AWBW AXDX @XBX Y +X -X -X -X -X -X -X -X ,X+Y-XGW@X)Y'Y1Y'Y1Y'Y1Y'Y1Y'Y\"ZCZ&Y9WEY.X/X'X/X'X/X'X/X MYNY BX8Y N" -"WFW X NW $w DX $VBV#XFS :WFXEV H] ;W #W 9XITIX" -" +V JW 4X4X >X \"Y 3[ BWCX Dn GXLi 1X ?ZFZ JY7Z MX -X Je M~X Me 9Y >U?gMUCV7WBW IX>\\ NX *X*X,X -X 0X *X/X'X -X -XNZ 9X -XHVBVHX0XGXAX)X%X.X9Y!X%" -"X.X:Y La 'X _ @W6W MW'W.YGWFX NW=W JWCWCW NX:X NYW2W FWBW 8Z @X 0X%X0X@X@X,X0X(X@X@X" -"/X%X)Y HV IY ?V @Y3Y ?V CV /YES 6X 1\\H[ JcJc LV 0WI\\ =TFV)S;WAX 5WEW MTAVAWCS 3W 4~W.W KV ?W6W LgGU KU 4WAW @WEW 6U9V GU9V ?VBV BX 2" -"WBW AWBW AWBW AWBW AWBW AWBW AXAX X *X -X -X -X -X -X -X -X ,X*X-XGXAX)X%X1X%X1X%X1X%X1X%X!ZEZ%X9WCX.X/X'X/X'X/X'X/X LXNX AX7X NWFW !W ,W ,W ,W ,W ,W " -",]:X=Y .X9X LX9X LX9X LX9X LW ,W ,W ,W +Z=X K[x A` J~\\(y%W8W MW4W CXMW >W>W MV $x DX $VCV\"XFS 9XIXEV H_ X #Y ?g AVBX Do HXM" -"k 3Y >l HX7Z MX -X Me J~X Je =Y >V?hNUBU8XBX Ju MX *X*X,w Lq IX *~R'X -X -c 8X -XHVBVHX0XFWAX)X%X.X9Y!X%X.X;Z Ke ,X WNV MW" -"Ib +W EW;Y MW *Z;X KV:W =_ @W6W NW%W/XFWFX NW=W JWCWCW NW8X!Y:Y =W >| GW@W 8Y @X 0X%X1Y@X@Y-X0X(X@X@X/XImIX*Y GV HY @V AY1Y @V CV /XDS 6X 0YDY JdL" -"d LV 1WF[ >SFV'SW6W LgGU KU 3WCW ?XFX 7U:V FU:V >UBV AX 3XBX CXBX CXBX CXBX CXBX CXBX BXAw?X *w Lw Lw Lw " -"LX -X -X -X ,X*X-XFWAX)X%X1X%X1X%X1X%X1X%X ZGZ$X:WBX.X/X'X/X'X/X'X/X K` @X7X NWFW W ,W ,W ,W ,W ,W ,[8W=X -W7W LW7W LW7W LW7W LW ,W ,W ,W ,Y:X LZ;X M" -"Y:Y MY:Y MY:Y MY:Y MY:Y \"Y=\\ LW6W MW6W MW6W MW6W MW:W IZ9X NW:W NVV&V 4W:X %~X2TNVW \"W ;WFTFW -V JV 3X4X >X #Y ?f AWBX Dp IXNm 4X ` @W6W NW%W/WEWEW NW=W JW" -"CWCW X8X!X8X =W >| GW@W 7Y AX 0X%X1X?X?X-X0X(X@X@X/XImIX+Y FV GY AV BY/Y AV DX 1XCS 6X 0W@X KdLd LV 1VCZ ?SFV'S;WE[ 7XFX G~X .S@VBWAS @~W0W " -".P>W >W6W KfGU KU 3XEX >XFX 8U;V:W3U;VCZ9P>WCV:W/Y 3W@W CW@W CW@W CW@W CW@W CXBX CX@w?X *w Lw Lw Lw LX -X -X -X 5p9X-XFXBX)X%X1X%X1X%X1X%X1X%X N" -"ZIZ#X:VAX.X/X'X/X'X/X'X/X K` @X7X NWFW W ,W ,W ,W ,W ,W ,[8X?X -X7X NX7X NX7X NX7X MW ,W ,W ,W ,X9X LY9W MX8X MX8X MX8X MX8X MX8X \"X=] LW6W MW6W MW6" -"W MW6W MW:W IZ9X NW:W NVLuKU/VLuKU/VBaAU/V:YAU/V=X=U&V 4X;X %~X2RLW>T >{!z'~Z)}(W6W NW4W DXLX ?X@X MV KX ,X %VBV!YHS 8eEV" -" Ic ?W !W ;UETEU ,V KW 3X4X >X $Y >c ?WAX DWD^ JbG] 5X 9d DY9[ MX -X #d D~X Dd DY a AW6W NW%W0XEWEX W=W JWCWCW W6W!X8X =W >| HX@X 7Y BX 0X%X1X?X?X-X0" -"X(X@X@X/XImIX,Y EV FY BV CY-Y BV DX 1XCS 6X 1W>W KeNe LV 1VB[ ASFV'S;YI] 9YGY F~X .S@VDX@S @~W1V ,TEZ >W6W JeGU IX +U 2YIY T ?|\"}(~X)~(W6W NW4W DXKW >W@X MV KX ,X %VBV!ZIS 7cEV IYNZ8W 0W !W :RCTCR +V KW 3X4X >X %Y" -" =b >V@X DS=\\ K`C[ 6Y 8b BX9[ Nd A~X Ad HY W ,X8X8W=X8X X6X MY7X\"X7Y MX 0W )W ,W6W MXXMW AW6W NW%W0XEWDW W=W JWCWCW!X6X#X6X >W >| HW>W 6Y CX 0X%X1X?X?X-X0X'XAXAX.XImIX-Y DV EY CV DY+Y CV DX 2X" -"BS 6X 1Vh =W6W JeGU IX 4g :g :YFX DgEV:XhCV:X/X 3X?W EX?W EX?W EX?W EX?W EX@X EX?w?" -"X *w Lw Lw Lw LX -X -X -X 5p9X-XEXCX)X%X1X%X1X%X1X%X1X%X LZMZ!XX7X NWFY !V +V +V +V +V +V +Y6W@X ,W5W NW5W NW5W NW5W MW ,W ,W" -" ,W -X7X MX8X X6X X6X X6X X6X X6X $X=_ MW6W MW6W MW6W MW6W LWS >}%~R)~V(~P)W6W NW4W" -" DWJX ?XAW L~^ $X ,X %VCV N\\LS 6aDVAW0XLZ9W 0W !W :PATAP +V KV 2X4X >X &Z =e BW@X DP8[ L^?Z 7X :h EY;\\ \"d >~X ?e LY ;U@W>Y" -"AU:W>W Ks KX *X*X,w Lq IX6f+~R'X -X -b 7X -XGWFWGX0XDWCX)X%X.X@^ NX%X.s Bl 8X X IXDVCVDX)[ 4\\ -Z @W *V #W $W JX5W\"X -W5X W4W KW 0W5X MX7W" -" MW ,W ,WIZ =W ,X8X8W=X7W W4W MX5W\"W5X MX 0X *W ,W6W LWX >XMX BW6W W#W1WD" -"WDW W=W JWCWCW!W4W#X6X >W >| HW>W 7Y BX 0X%X1X?X?X-X0X'XAXAX.XImIX.Y CV DY DV EY)Y DV DX 2XBS 6X 2WY BSFV'S9bMV ;XFY D~X .S@h>S " -"@~W2i >g W EW>W EW>W EW>W EW>W EW>W EX?w?X *w Lw Lw Lw LX -X -X -X 5p9X-XDWCX)X%X1X%X1X%X1X%X1X%X " -"Ke X=W?X.X/X'X/X'X/X'X/X I\\ >X7X NWEY \"W ,W ,W ,W ,W ,W ,X5W@X -W4W W4W W4W W4W MW ,W ,W ,W -W6X MX7W W4W W4W W4W W4W W4W $W=VMW MW6W MW6W MW6W MW6W " -"LW=X HX5W NW=X MVLuKU/VLuKU/V?[>U/V=Y>U/V=X=U&V 3X=W 7X FW@T ?~&~T*~V)~R*W5V NW4W EXJX ?XBX L~^ $X ,X &VBV Mb 4]CVC]4XJZ:W" -" 0W !W +T KV KV 2X4X >X 'Z X Lu MX *X*X,w Lq IX6f+~R'X -X -c 8X -XFVFVFX0XDXDX)X%X.u MX%X.r" -" ?l :X X IXDVCVDX)\\ 4Z ,Y ?W *V #W $W JX5W\"W ,W5X W3W LW 0W5X MX7W MW ,W ,WJY ;W ,X8X8W=X7W W4W MX5W\"W5X MX 0X *W ,W6W LWW 6Y 0X 9V LX 5`3R 0T?[?T/W:[ KWId DbKW HW5X NW +X7W JV>W =WLX BW6W W#W1WDWDW W=W JWCWCW!W4W#W4W >W >| IX>X 9Y AX 0X%X1X?X?X-X0X'XAXAX.XImIX/Y B" -"V CY EV FY'Y EV DX 2WAS ?r CV:V =^ =V 2V=Y CSFV'S8`LV e :W6W GbGU IX 4g 8c 5XFX FgFV:YX GX>X GX>" -"X GX>X GX>X GX>X FX?w?X *w Lw Lw Lw LX -X -X -X 5p9X-XDXDX)X%X1X%X1X%X1X%X1X%X Jc NX>W>X.X/X'X/X'X/X'X/X HZ =X7X NWEZ #W ,W ,W ,W ,W ,W ,X4WAW ,W3W!W3" -"W!W3W!W3W NW ,W ,W ,W .X5W MX7W W4W W4W W4W W4W W4W $W>VLW MW6W MW6W MW6W MW6W KW>W GX5W MW>W LVLuKU/VLuKU/V>Z>U/V>Y=U/V=X=U&V 2W>X 8Y FW@T " -" ?~P(~V*~T(~Q)V4V NW4W EXJX >WBX L~^ $X ,X &VBV Ld 4WAVD`6XHZ;W 0W !W +T KV LW 2X4X >X 'Y ;i GV>X *Z M\\;Y 9X =p HZ?^ 'd " -" Id$Y 9UAWX GWEVJVEW#a >W>W 7Y 1Y 8V KY 9e8T 0T?Z>T0X:[ KWIf GdLW HW4W MW ,W6W JV?X >XKW BW6" -"W W#W2XDWDX!W=W JWCWCW!W4W#W4W >W >| IWX GX>w?X *w Lw Lw Lw LX -X -X -X 5p9X-XCWDX)X%X1X%X1X%", -// Start of second string. -"X1X%X1X%X Ia MX?W=X.X/X'X/X'X/X'X/X GX W GX5W MW>W LVLuKU/VLuKU/V?\\?U/V?YX 8X DWBT ?~Q)~W)~R&~(V4V NW4W EWHW >WBW K~^ $X ,X &VBV Kg \"" -"VEc8WFZ=W /W !W +T 4~W 5V 1X4X >X (Y -] IW>X )Y M[9X 9X >\\F\\ H[C` 'a Ca$Y 9UAV:WAU;WW )V $W 6i JX5X$X -X5X V2W LW 1W3W MW6W MW ,W ,WLY 9W ,W7W7W=W6W!X4X NX5X$X5X MW .[ .W ,W6W KW>" -"W FWEVJVEW#a >W?X 8Z 4\\ 8V K[ =iW2W IWX X *X -X -X -X -X -X -X -X ,X*X-XCXEX)X%X1X%X1X%X1X%X1X%X H_ LX@Wi >i >i >i" -" >i >i3WBX ,V2W!V2W!V2W!V2W NW ,W ,W ,W .W4W MW6W!X4X\"X4X\"X4X\"X4X\"X4X M~Y2X@VIW NW6W MW6W MW6W MW6W KW?X GX5X NW?X LVLuKU/VLuKU/V@^@U/V@Y;U/V=X=U&" -"V 2X?W 8X CWBT ?~R*~X)~Q%}(V4W W4W FXHX ?XDX K~^ $X ,X 'WCV Ii &VEe:XEZ>W /W !W +T 4~W 5V 1X4X >X )Y )[ KW=X (Y N[9Y ;Y " -"?Z@Z I]Gb '^ =^$X 9U@V:WAUXIW CW6W!W!W3WCWCW!W=W JWCWCW\"W2W%W3X ?W >W2W JW;X ~R+~Z*~P#{'V4W W4W FXHX ?XDX K~^ $X " -" ,X 'VBV Gi (VFg;WCZ?W /W !W +T 4~W 6W 1X4X >X *Y &Z LW=X (Y NZ7X ;X ?Z>Z ImNX '[ 8\\%Y 9UAW:WAUX XIW CW6W!W!W3WCWCW!W=W JWCWCW\"W2W%W2W ?W >W2W JW:W =Y >X 0Y'" -"X0X?X?X-X0X%XCXCX,X%X2~a GV H~a HV I~b HV DX 3W@S ?r DV8V V&V 1XAW 9" -"X @WDT ?~S+~Z)}!y'W4W W4W FWFW >WDW J~^ *r ?V &VBV Eh *VEXIXX +Y $Z NWXHX DW6W!WW2W KX:X ?Y =X /X'X0Y@X@Y-X0X%YDXDY,X%X2~a GV H~a HV I~b HV DX 3W@S ?r DV8V ;X DW;V DSFV'S >XFX " -" ;V .S@VFW=S (V \"W6W :UGU IX 0XFX -V;TLU MV0U!V;TLU6Y 0X:X KX:X KX:X KX:X KX:X KX:X JWV&V 1XBX :X ?WDT ?~S,~[({ x&W4W W4W FWFX ?XFX JV \"q >V &VBV Af -VEXGX=W@ZB" -"W .W !W +T 4~W 5f 8V 0X4X >X ,Y \"Y W;X 'X NZ7X X -XDVJVDX0XAXGX)X%X.i" -" AX%X.X>Z ,\\ ?X XGW DW6W!WW2W KW9X ?Y =X /X'X/X@X@X,X0X$YEXEY" -"+X%X2~a GV H~a HV I~b HV DX 3W@S 6X 3V8V ;X DXWEW :V .TAVEW?T (V \"W6W :UGU IX /WEW .V;TKU NV/U\"V;TKU7Y /X:X KX:X KX:" -"X KX:X KX:X KX:X KXWDS >~T-~\\(y" -" Mw&W4W W4W GXFX ?XFX JV #r >V 'WCV X -Y Y!W;X 'Y Y5X =X @Y8Y HgKX 'a Ca%X 8UAV8" -"VAU=W8W NX4X%X *X+Y,X -X 0X(X+X/X'X -X -XI[ ?X -XDWLWDX0X@WGX)X&Y.X 0X&Y.X=Y *[ @X XFX EW6W!WW2W KW8W @Y ] Jt It It It It It I~iBW ,|\"|\"|\"| NW ,W ,W ,W /W2W NW6W!W2W\"W2W\"W2W\"W2W\"W2W M~Y2WCVEW NW6W MW6W MW6W MW6W IWCX EW3W L" -"WCX IV=V=V.V$V.VFYKZFV.VFY7V.V$V&V 0XCW ;Y =WFT >~T-~\\'w Ku%W4W W4W GXEW >WFW IV #q =V 6~X JSN^ /VEWCW?W=ZDW .W !W :~W" -" 5f 9V /X4X >X .Y MX\"W:X &X Y5X >Y @X6X FcJX &d Id%X 8UAV8VAU>X8X X4X$X +X+X+X -X /X)X+X/X'X -X -XH[ @X -XCVLVCX0X@XHX(X'X-X /X'X-XXFX EW6W!WV-V%V-VGYIZHV-VGY7V-V%V%V /WDX ;X ~T-~\\'v Is" -"$W4W W4W GWDX ?XGW HV %r =V 6~X JSJ[ 0VEVAV?WX ?X6X D`IX $d Ne#X 8UAV8" -"VBU=x X4X$X +X+X+X -X /X)X+X/X'X -X -XG[ AX -XCVLVCX0X?WHX(X'X-X /X'X-X;Y *Y @X WDW EW6W!WV>V,V&V,VIYGZIV,VIY6V,V&V&W /XEW N~X'VGT =~T-~\\&u Ir#W4W NV4W HXDX ?XHX HV KX ,V 6~X JSHZ 2VDVAV?W;ZGW -W !W \"V " -"Lf :W .X6X =X 0Z LY#~ /X NX5X >X @X5Y AYFX !d >~X >d X 8UAV8VBU>z!X3X%X +X+X+X -X /X)X+X/X'X -X -XF[ BX -XCWNWCX0X?XIX(X'X-X /X'X-X:X )Y AX XDX FW6W!WV?W,V'W,VJYEZKW,VJY6W,V'W&W /XFX N~X'WHT =~T-~\\%s Gp\"W4W NV4V GXCW >WH" -"X HW LX ,V 6~X JSGY 3VDWAW@W:ZIW ,W !W \"V Lf :W .X6X =X 1Z JX#~ /X NX5X ?Y @X4X .X Md A~X Ad LX 8UAV8VBU>z!X3X%X +X+X+" -"X -X /X)X+X/X'X -X -XE[ CX -XBVNVBX0X>WIX(X'X-X /X'X-X9X *Y AX Q.X $T>Z?T0W8W HW5W\"WWCX FW6W!WXFX >V ,SBVBWCS &V \"W6W :U" -"GU *m 8XFX .VWIX(X'X/X'X/X'X/X'X/X'X KZMZ XHW6X-X/X'X/X'X/X'X/X GX XIW GW LX ;~X JSFX 3VDV?V@W9ZJW +V \"W !V V -X6X =X 2Z IX#" -"~ /X NX5X ?X ?X4X .X Jd D~X Dd IX 8UAV8VCV>z!X3X%Y ,X,Y+X -X /Y*X+X/X'X -X -XD[ DX -XBVNVBX0X>XJX(Y)X,X /Y)X,X9Y *X AX XBW FW6W!WXJX" -"(Y)X.Y)X.Y)X.Y)X.Y)X KZKZ!YJW6X,X/X'X/X'X/X'X/X GX |\"X3X$X ,X,X*X -X .X*X+X/X'X -X -XC[ EX" -" -XA\\AX0X=WJX'X)X,X .X)X,X8X *X AX XBX GW6W!WW 9X =\\KW >SEWWJX FW LX <~X JSEX 6WCV?V@W7ZMW *W #W !V !W -X6X =X 4Z GX#~ /X NX5X @X >X4X " -"/X De J~X Je DX 8U@V:WDV>|\"X3X$X ,X-Y*X -X .X*X+X/X'X -X -XB[ FX -XA\\AX0X=XKX'X*Y,X .X*Y,X8Y +X AX W WJW DW MX .VCV" -" :SDW 6VBV?V@W6b )W #W !V !V +X8X X4X /X Ad L~X Ld AX 8VAV:WDU=|\"X3X$Y -X-Y*X -X .Y+X+X/X'X -X -XA[ GX -XA\\AX0XWKVDVKW\"XLX 9WJW =Z #X :V MX AUEVKVDU/X:Y IW5W#WX@W GW6W!W=Y=W2WDWDW W=W JWCWCW\"X4W#W4W >W X4X 0X =d ~X" -" d LUAWX2X#X3X#X -X.Y)X -X -X+X+X/X'X -X -X@[ HX -X@Z@X0XW ,W7W7W=W6W W4W MX5W\"W5X MW BX FW ,W7X FWHW >WLVBVLW#YKX :WJW =Y !W :V MW @VHXJWHV-W:Y IW5W#WY>W1WDWDW W=W JWCWCW\"X4W#W4W >W W MW7X MW7X " -"MW7X MW7X EWJW AX5W GWJW AXCVCW%X0W%X0W%X0W%X0W\"V +WJX ?X 2WLT 9bKQKb)gLQMh Mi =g MW4W MV6W IX@X ?XLX CW MX 0VBV :SDW " -"7VAV?V@X5_ (W #W !V \"W +X8X XLV;VLX1Y?Y >X 9Z 2W %W )W EW7X JX5W\"X -W5X X )W 0X7Y MW6W MW ,W ,WFY ?W ,W7W7W=W6W W4W MX5W\"W5X MW AW FW ,W7X FXJX" -" =WMVBVMW#YJY ;WKX >Y W :V MW ?dId,W;Z IW5W#W=W DW4W!W )W6W DVKW >X>W HW6W W>Y>W1WDWDW W=W JWCWDX\"X4W#W4W >W ;V7W LX2X LY 4X *X1X%]JXJ]'X0X Hj L" -"Y-Y%Y IV JY LYKVKY MY5Y MYJVJY $X 2XBS 6X 2q 9X :V #\\ 7TDgFT /XFX EV )TFV>VJT #V \"W6W :UGU +XFX *V=TCU%V1V!V=TCU=X ,X1W$X1W$X1W" -"$X1W$X1W$X2X%X7X LY .X -X -X -X -X -X -X -X ,X.Y*X;XMX&Y-Y+Y-Y+Y-Y+Y-Y+Y-Y ZAZ$_3Y*X1X%X1X%X1X%X1X FX W3W$W7X MW7X MW7X MW7X MW7X MW7X MW7Z NX -X " -"-X -X -X +W ,W ,W ,W .W4W MW6W W4W W4W W4W W4W W4W 5Z IWMV=W MW7X MW7X MW7X MW7X EWKX AX5W GWKX @XDVDX$X2X$X2X$X2X$X2X\"V +XKW ?X 1WMT 7`JQKa" -"'fLQLf Kg W >WLW BX NY 1VBV :SDW 8V@V?V?W4] &V $W V \"V *Y:Y YGW>X0X$X4Y\"Y /X/Y(X -X ,Y-X+X/X'X -X -X>[ JX -X@Z@X0X;XMX%Y/Y*X ,Y/Y*X6Y -X AX ;Y3Y IXLX =WLV;VLW0X=Y ?X :Z 1W $V )W EW8Y JY7X\"X -X7Y X " -")W 0X7Y MW6W MW ,W ,WEY @W ,W7W7W=W6W X6X MY7X\"X7Y MW AW FW ,X8X EWJW Y NW :V MW >bGc,W;[ JW6X#W=W DX6X!W )W6W DVLX >W=X IW7" -"X W>Y>W1XEWEX W=W IWDWDW!Y6X#X6X >W ;W8W MX0X MY 4X *Y3Y$^LXL^&X0X Ff IY/Y#Y JV KY JYLVLY KY7Y KYKVKY #X 2XBS 6X 3t ;X :V ![ 8TCfFT .XFX FV )U" -"GV>WKT MW7X :UGU ,XFX *V=TBU&V2W!V=TBU=X -X0X&X0X&X0X&X0X&X0X&X0W%X7X KY /X -X -X -X -X -X -X -X ,X/Y)X;XMX%Y/Y)Y/Y)Y/Y)Y/Y)Y/Y Z?Z$" -"^4Y)Y3Y%Y3Y%Y3Y%Y3Y FX XEVFY\"X5Y\"X5Y\"X5Y\"X5Y!V *WLX @X /WNT 7`JQJ_&eKQKe Je :d KW4W MW8W HW>X ?XNX AX Y 1VCV 9SDW 9V?V?V?X4\\ " -" &W %W V \"V )X:X ;X 9Z CX 4X (Y KW7X AX W BW6W W )W6W DWMX ?X=X IX8X W?[?W0WEWEW NW=W IWDWDW!Y6W!W6W =W ;W8W MX0X NY 3X )Y5Y\"z%X0X C` FY/Y\"X JV " -"KX HYMVMY IX7X IYLVLY \"X 1XCS 6X 4v X ?XNX AY Y4P VBV 9SDW 9V?V?V?Y4Z %W %W V #W )X:X ;X :Z CY 4X (Y KX9Y AX ;X6X 1Y 1e /e @U@XB[JXW BX8X W )W6W CVNX >W;W IX8X X@[@X0XFWEW " -"NW=W IWDWEX!Z8X!X8X =W :W:W LX0X Y 2X (Y7Y Nv#X0X ?X AY1Y V IV JV FYNVNY GV5V GYMVMY !X 1XCS 6X 5x =X :V MZ 8T?ZBT *VDV FV 'T&T KX" -"8X :UGU ,VDV )VWNX @Y !Z6Q VBV KP>SEW 9V>WAW>X3Z &W %W V " -" #V 'XU?ZH^MZ\\ JX8X\"W?W AX9Y X *W6W CVNX ?X;X JX9Y NW@[@W/XFWFX NW=W IXEWEX!Z8X!X8W ;W ;W;X MX.X\"Y 1X 'Y9Y Lt\"X0X ?X @Y3Y MT HV IT Dj ET3T EYNVN" -"Y X 0XDS 6X 6ZM`LY >X :V LY 7T)T (UCU ET(T JX9Y :UGU ,UCU )V;m.V3V NV;mCY7P HX.X(X.X(X.X(X.X(X.X(X.X(X6X IY.R&X -X -X -X -" -"X -X -X -X ,X2Z'X9a$Z3Y&Z3Y&Z3Y&Z3Y&Z3Y!Z9Z&Z3Y&Y5Y#Y5Y#Y5Y#Y5Y EX `" -" >Y !Y8S MX +VBV KQ?SFX 9V=VAV=Y6] &V &W NV BX 1X 1V 'Y>Y :X X:W JY;Z NXB]BX.XGWGX MW=W H" -"XFWFX [:X NX:X ;W :WX HXX 9X =Z 1P2Z 3X GQ5Z GX=Y @X 9Y:Y KP8Z GX -X 4^ 1^ +X 5U?gM_9W,W%X7Z L[4U&X6]%X -X )[2X+X/X'X -X -X9[ X -X&X0X8`\"Z7Z'X )Z7Z'X3X%T2Y ?X 9Z9Z E` :" -"_9_3Y7Y BX >Z -W #W +W DX=\\ J\\=Y LY7P HY=\\ LY5R JW -Y?] MW6W MW ,W ,W@Y EW ,W7W7W=W6W MYX LX.X#Y 0X %Y=Z Gl MX0X ?X ?Z7Z JP FV GP @f AP/P Ah MX " -"/YFSDP BX 8ZFVEY @X :V JX 7V.U %SAS CU.U HZ\\=Y B^ 7r Gr Gr Gr Gr KV (_ BX )Y S 8RBSCR <] 2\\ GW4W KZBZ HX;W >_ <[ " -" $[=U MX ,VBV JUCSHY :V;WCW<[Z 0R5Z 2X GT9[ GY?Z AY 9[>[ KR;Z FX -X 1[ 1[ (X 5V>dL^9X,X&X9[ J[7W&X9_$X " -"-X (\\6Z+X/X'X -X -X8[!X -X&X0X8`![;[&X ([;[&X3Y&W7[ ?X 8Z;Z D` :^7^3X5Y CX ?Z ,W #W +W DY?] J]?Y KZ:R GY?] LZ8T JW -ZA^ MW6W MW ,W ,W?Y FW ,W7W7" -"W=W6W LY>Y J]?Y KY?] MW /T9X DX ,Y@] CWNW 9]>]'Y@Y =^ AY IW :V MW HYCXNW L\\>Y VAX >Y>Y LY ,W6W B] >X9X K[>[ MXDVMVDX,YIWIY LW=W GYHWHY N]>Y LY" -">Y :X :X@X LX,X%Y /X $ZAZ Ch KX0X ?X >[;[ ?V 6d >f LX /[HSFR BX 9Z3Y AX :V IX 7V1V #R@R BU0U G[>[ :UGU ,R@R 'V(U)V6W" -" LV(UU IX,X*X,X*X,X*X,X*X,X*X,X*W4X G[7W&X -X -X -X -X -X -X -X ,X9_%X8`![;[![;[![;[![;[![;[\"Z3Z(];[\"Z;Z NZ;Z NZ;Z NZ;Z CX Y JW6W LY>Y IY>Y IY>Y IY>Y IY>Y 2Z FY>Y HY@] KY@] KY@] KY@] B^ >]?Y A^ 6o Do Do Do " -"Do IV (_ CX (Y S (S ,[ 0[ GW4W J\\H\\ GW:W >^ :\\ %[@W MX ,VBV JXFSIZ :V:WEW:\\@e (V 'V MV BX 1X 2V $ZDZ 8X ?Z /U;] 2X GV=" -"\\ EZC[ @X 7[@[ JT?[ EX -X /Y 1Y &X 5V=bK\\7X,X&X<^ I]=Z&X=b#X -X ']:\\+X/X'X -X -X7[\"X -X&X0X7_ \\?\\%X '\\?\\%X2X&Z<\\ >X 7[?[ B^ 9^7^4Y5Y CX ?Y +W \"V +W " -" DZB_ J_CZ I[>T G[C_ K[=W JW ,\\GXNW MW6W MW ,W ,W>Y GW ,W7W7W=W6W KZBZ I_CZ J[C_ MW /W>Z DZ .ZB^ C` 8\\>\\&X>Y =\\ AY HW :V MW GZFYNY N]AZ N" -"WCX _ FX0X ?X =\\?\\ >V 5b W;[>T F[=W J[=W J[=W J[=W LW ,W ,W ,W *ZBZ IW6W KZBZ GZBZ " -"GZBZ GZBZ GZBZ 1Z F[BZ GZB^ KZB^ KZB^ KZB^ A\\ =_CZ ?\\ 3l Al Al Al Al HV (^ BX (X NS (S ,Z .Y FW4W In GX:X ?^ 9_ (]FZ MX " -",VBV J[ISL\\ :V9XGX9^Fi )W )W MV BX 1X 3W #[H[ Et Mx MZC_ 1X GZD^ C[G\\ @Y 7^F] IXF] DX -X ,V 1V #X 4V<^IY5X*X'y G_D^&{!y NX &`B`+X/X'X -X -X6[#" -"w LX&X0X7_ N^E^$X &^E^$X2Y'^C^ =X 7^E^ B^ 8]7]4Y3Y DX @~U&W \"W ,W C\\HYNW JWNXG\\ H]EX F\\GXNW J]D[ JW +kMW MW6W MW ,W ,W=Y HW ,W7W7W=W6W K]H] IWNX" -"G\\ I\\GXNW MW /[E\\ Be 9[GXNW B^ 7\\>\\'XP @W8W 3~W :_GaKP @UGU ,P>P 'V&U+V6V KV&" -"U;]GZ JX*X,X*X,X*X,X*X,X*X,Y,Y,X4y7_D^&y Ny Ny Ny NX -X -X -X ,{\"X7_ N^E^ L^E^ L^E^ L^E^ L^E^ MV/V(dE^ N^E^ L^E^ L^E^ L^E^ BX \\ Av 6W :V MW FkL]$u LXGX 9p Hp EW6W A[ ?X6X LpN\\#" -"hKh)s JW<] Lu LWNm Hp 6` Bl K~W'x MX 1iEi HX CX0X ?X ;u X :V HW 3X=X )X\\ /c 8c 8c 8c 8c CV '\\ ?T %W U *T *W ,V DW4W Gj EW8W " -">\\ 5~P In LX -VBV Is 9V7g6qJZ *V )V LV BX 1X 3V !l Dt Mx Mt /X Gr ?m ?X 4r Hm BX -X &P 1P LX 3V 3X*X'w Cv%x My NX #x(X/X'X" -" -X -X4[%w LX&X0X5] Ls\"X $s\"X1Y(w ;X 5s ?\\ 7\\5\\5Y1Y EX @~U&W !V ,W BjLW JWMj Dn DjMW Hr JW )hLW MW6W MW ,W ,W;Y JW ,W7W7W=W6W In GWMj EjMW MW /p" -" ?d 8iLW B^ 6Z<[)Y:Y >Z @v 6W :V MW EiK]$t JYLZ 7n Fo EW6W A[ ?X5W LWNfM\\\"gKg'q IW<] Ks KWMk Fn 5` Aj J~W'x MX 1iEi HX CX0X ?X :s ;V 2\\ 6" -"^ HX +n Lz MR,R =X :V HW 1ZEZ %ZDZ 0~W :WNfM\\ @UGU !V%U,V6i/V%U9n JX*X,X*X,X*X,X*X,X*X,X*X-X3y5v%y Ny Ny Ny NX -X -X -X ," -"x NX5] Ls Hs Hs Hs Hs IR+R(WMs Js Hs Hs Hs @X R $V NU *U *U *U DW4W Fh DW8X ?\\ 4~ Hl KX -VBV Hp 8V5e4nGZ +W +W LV BX" -" 1X 3V j Ct Mx Mr -X Gq =j >Y 3p Gl AX -X 2X 3W 5X(X(u ?s$v Ky NX \"v'X/X'X -X -X3[&w LX&X0X5] Kq!X #p X0X(v :X 4p =\\ 7\\5\\6Y/Y FX @~U&W !V ,W " -" AhKW JWLh Bm ChLW Gq JW (eJW MW6W MW ,W ,W:Y KW ,W7W7W=W6W Hl FWLh ChLW MW /o >d 7gKW A\\ 5ZZ @v 6W :V MW DgI\\$s He 5l Dn EW6W @Y " -">W4X MWMeM\\!eIe%o HW<] Jq JWLi Dk 2_ @h J~Y(x MX 1iEi HX CX0X ?X 9q :V 1Z 4\\ GX *m Lz LP*P X X ?v 6W :V MW CeG[$r Fc 2h Am EW6W @Y ?X3W MWMdL\\ cGc#m GW;\\ Hm HWKg Ah /] ?f I~Y(x MX 1iEi HX CX0X ?X 7m 8V 0" -"X 2Z FX (j Kz AX :V HW -g Lh ,~W :WMdL\\ @UGU \"V$U-V5i0V$U7i HX(X.X(X.X(X.X(X.X(X.X(X/X2y1o\"y Ny Ny Ny NX -X -X -X ,t" -" JX4\\ Im Bm Bm Bm Bm %VHm Dm Bm Bm Bm =X eJW GeJW" -" GeJW GeJW ?X ;WJe 9X MW &Z =U W ,W *R &Q BW4W B` AW6W >[ /y Dd GX -VCV Af 5V2a.gBZ ,W -W KV CX 0X 4V " -" Kd @t Mx Km *X Ek 6d ;X .h Bh >X .X 1X 1W 7X(X(q 7j Np Ey NX Mm\"X/X'X -X -X1[(w LX&X0X4\\ Gi LX Ni LX/X$n 7X 0i 9Z 5[5[6Y-Y GX @~U&W V -W " -" >cIW JWIb k EW6W @Y ?" -"W2W MWK`I[ NaEa i EW;\\ Fi FWIc >e ,\\ =b G~Y(x MX 1iEi HX CX0X ?X 5i 6V /V 0X EX &f Iz AX :V /P;W *c Gb )~W :WK`I[ @UGU " -" #V#U.V4i1V#U6f FX(X.X(X.X(X.X(X.X(X.X(X/X2y/j Ny Ny Ny Ny NX -X -X -X ,p FX4\\ Gi >i >i >i >i $VEi @i >i >i >i ;X i0g ;i >i >i >i HW ,W ,W ,W #d BW6W Ef ;f ;f ;f ;f JUJe ;cIW FcIW FcIW FcIW ?X ;WIb 7X MW %Y =T X -X )P %P AW4W ?Z" -" >W6X ?Z ,w B` EX .VBV <] 1V0]*b?[ -W -W KV CW /X 4V I` >t Mx Hg 'X Bf 2` :X +d =b ;X .W 0X 1X 9X&X)m 0d Kj ?y NX Jg " -"NX/X'X -X -X0[)w LX&X0X3[ Dc IX Kf LX/Y!g 4X .e 7Z 5Z3Z7Y+Y HX @~U&W V -W =`GW JWG^ 7b 9^GW Ad CW \"YDW MW6W MW ,W ,W7Y NW ,W7W7W=W6W B` @WG^ 9" -"^GW MW (c 2] 3_GW @Z 3X:X*Y4Y @X ?v 6W :V MW ?_AW$WKb @^ +` 9g CW6W ?W ?X2X NWJ^GY K]B^ Ke CW:[ Dd CWG_ 9` 'Y ;^ F~[)x MX 1iEi HX CX0X ?X 2c " -"3V .T .V DX $b Gz AX :V /R>X &[ ?Z %~W :WJ^GY ?UGU #V +V +V 1b EX&X0X&X0X&X0X&X0X&X0Y'X1X1y,d Ky Ny Ny Ny NX -X -X " -"-X ,j @X3[ Dc 8c 8c 8c 8c !VBc ;e :e :e :e 9X Y BS .V,W#Z ;V -V 7W ;W EX ;\\ 6] " -"+Z 5\\ 5Z WGXBU FX=X E` \"W >] @WDY 3Z 2X C[ >T :[ KV /TAY " -" EWGXBU =UGU BT 6V +V +V ,Y ?\\ +[ 0[ 0[ 0[ 0[ KT=[ 2[ 0[ 0[ 0[ 7Z ;Y .Y .Y .Y .Y .Y -" -"Y2\\\"Z /\\ 1\\ 1\\ 1\\ CZ 3Z /Z /Z /Z /Z FVCZ 1Y .Y .Y .Y ,W :WDX 2W LW 7R #S" -" >W /W 8W :V \"W 5X )X &Z CW NV .W :W %W" -" @W :W -X -W :V MW LW FW ?W >W NW 0W =W 3S GV /XGZ " -" DW HUGU AT %T 'R JT " -" #T (X :W NX LW 7S =V /V 7W :V \"W" -" 4X'Q &Y %Z DW NV .W :W %W @W :W -W ,W :V MW " -" LW FW ?W >W NW 0W =W 3S GV /j CW HUGU @T " -" %T 'P HT \"Q 'W 9W NW KW " -" 7S =W 1W 7V :W \"V 2X)R &X #Z " -" EW NW /W :W %W @W :W -W ,X ;V NX LW FW ?W >W NW 0W =W " -" 3S GV /j CW HUGU @U &U " -" U \"P 'W 9W NW KV 6S " -" W NW 0W =W 3S GV /h " -" AW HUGU ?T %T NT " -" )X 9W X KV 6S W NW 0W =W 3S GV .f @W HUGU ?U &" -"U U *W 8W W JV " -" 6S ;V 3V 6V :W \"V .[5[ *Y Z " -" Ha (W :a W NW 0W =W " -" 3S GV +a >W HUGU >T %T " -" NT +X 8W !X (VIV 6S :V 5V 5U" -" 9W \"U +\\;] )X MZ Ia (W :a =Y %W ?W :W " -" /W )[ ?V #[ KW FW ?W >W NW 0W =W 3S GV 'Z ;W " -" HUGU >U &U U ,W 7W !" -"W 'VIV 6S :V 6W 6V 4V *_C` " -" )Y LZ Ja :a (P7Y $W ?W :W 0X (b GV +b JW FW ?W >W " -" NW 0W =W 3S GV 7W HUGU >U &U " -" U -X 7W \"X 'VJW " -" 6S 9V 7V 5U 3U 'x (Z KZ Ka :a " -" (R:Z $W ?W :W 0X (b GV +b JW FW ?W >W NW 0W =W 3S " -" GV 7W #U &U U " -" -X 7W \"X &UJW 6S 9W 9W " -" Bu ([ IZ La :a (T>[ $X ?W :W 1X &a GV +a " -" IW FW ?W >W NW 0W =W 3S GV 7W $V " -" 'V !V .X 6W #X %VLW " -" 5S 2p -a " -" 8XE] %Y >W :W 3Z $_ GV +_ GW FW ?W >W NW 0W =W " -" 3S GV 7W /QGW 2QGW ,QG" -"W 0Z 6W %Z %a 5S " -" 0l +a 8p +_ >W :W ;a !] G" -"V +] EW FW ?W >W NW 0W =W 3S GV 7W /` " -" 1` +` 7a 5W -a #` " -" >e '` " -" 7o *^ =W :W ;` KY GV +Y AW FW ?W >W NW 0W =W " -" 3S GV 7W /` 1` +` " -" 7` 4W -` \"_ " -" 8\\ #_ \"} 3n )^ =W :W ;` 9V " -" BW FW ?W >W NW 0W =W 'V 7W /_ " -" 0_ *_ 6` 4W -` !] " -" -] " -" } 3l '] W NW 0W =W " -" 'V 7W /^ /^ )^ " -" 5_ 3W -_ N[ " -" ,[ M} 2j &\\ ;W :W ;^ 7V BW " -" FW ?W >W NW 0W =W 7W -Y *Y " -" $Y 2^ 2W -^ LX " -" *X J} " -" /d #Z 9W :W ;\\ 5V BW FW ?W >W NW 0W =W " -" 7W " -" /\\ 0W HT " -" I} *[ NW 6W :W ;Z 3V BW FW ?W >W" -" NW 0W =W 7W " -" /Z .W " -" =} " -" " -" D" }; - - // Define a 40x38 'danger' color logo (used by cimg::dialog()). - static const unsigned char logo40x38[4576] = { - 177,200,200,200,3,123,123,0,36,200,200,200,1,123,123,0,2,255,255,0,1,189,189,189,1,0,0,0,34,200,200,200, - 1,123,123,0,4,255,255,0,1,189,189,189,1,0,0,0,1,123,123,123,32,200,200,200,1,123,123,0,5,255,255,0,1,0,0, - 0,2,123,123,123,30,200,200,200,1,123,123,0,6,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,29,200,200,200, - 1,123,123,0,7,255,255,0,1,0,0,0,2,123,123,123,28,200,200,200,1,123,123,0,8,255,255,0,1,189,189,189,1,0,0,0, - 2,123,123,123,27,200,200,200,1,123,123,0,9,255,255,0,1,0,0,0,2,123,123,123,26,200,200,200,1,123,123,0,10,255, - 255,0,1,189,189,189,1,0,0,0,2,123,123,123,25,200,200,200,1,123,123,0,3,255,255,0,1,189,189,189,3,0,0,0,1,189, - 189,189,3,255,255,0,1,0,0,0,2,123,123,123,24,200,200,200,1,123,123,0,4,255,255,0,5,0,0,0,3,255,255,0,1,189, - 189,189,1,0,0,0,2,123,123,123,23,200,200,200,1,123,123,0,4,255,255,0,5,0,0,0,4,255,255,0,1,0,0,0,2,123,123,123, - 22,200,200,200,1,123,123,0,5,255,255,0,5,0,0,0,4,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,21,200,200,200, - 1,123,123,0,5,255,255,0,5,0,0,0,5,255,255,0,1,0,0,0,2,123,123,123,20,200,200,200,1,123,123,0,6,255,255,0,5,0,0, - 0,5,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,19,200,200,200,1,123,123,0,6,255,255,0,1,123,123,0,3,0,0,0,1, - 123,123,0,6,255,255,0,1,0,0,0,2,123,123,123,18,200,200,200,1,123,123,0,7,255,255,0,1,189,189,189,3,0,0,0,1,189, - 189,189,6,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,17,200,200,200,1,123,123,0,8,255,255,0,3,0,0,0,8,255,255, - 0,1,0,0,0,2,123,123,123,16,200,200,200,1,123,123,0,9,255,255,0,1,123,123,0,1,0,0,0,1,123,123,0,8,255,255,0,1,189, - 189,189,1,0,0,0,2,123,123,123,15,200,200,200,1,123,123,0,9,255,255,0,1,189,189,189,1,0,0,0,1,189,189,189,9,255, - 255,0,1,0,0,0,2,123,123,123,14,200,200,200,1,123,123,0,11,255,255,0,1,0,0,0,10,255,255,0,1,189,189,189,1,0,0,0,2, - 123,123,123,13,200,200,200,1,123,123,0,23,255,255,0,1,0,0,0,2,123,123,123,12,200,200,200,1,123,123,0,11,255,255,0, - 1,189,189,189,2,0,0,0,1,189,189,189,9,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,11,200,200,200,1,123,123,0,11, - 255,255,0,4,0,0,0,10,255,255,0,1,0,0,0,2,123,123,123,10,200,200,200,1,123,123,0,12,255,255,0,4,0,0,0,10,255,255,0, - 1,189,189,189,1,0,0,0,2,123,123,123,9,200,200,200,1,123,123,0,12,255,255,0,1,189,189,189,2,0,0,0,1,189,189,189,11, - 255,255,0,1,0,0,0,2,123,123,123,9,200,200,200,1,123,123,0,27,255,255,0,1,0,0,0,3,123,123,123,8,200,200,200,1,123, - 123,0,26,255,255,0,1,189,189,189,1,0,0,0,3,123,123,123,9,200,200,200,1,123,123,0,24,255,255,0,1,189,189,189,1,0,0, - 0,4,123,123,123,10,200,200,200,1,123,123,0,24,0,0,0,5,123,123,123,12,200,200,200,27,123,123,123,14,200,200,200,25, - 123,123,123,86,200,200,200,91,49,124,118,124,71,32,124,95,49,56,114,52,82,121,0 }; - - //! Get/set default output stream for the \CImg library messages. - /** - \param file Desired output stream. Set to \c 0 to get the currently used output stream only. - \return Currently used output stream. - **/ - inline std::FILE* output(std::FILE *file) { - cimg::mutex(1); - static std::FILE *res = stderr; - if (file) res = file; - cimg::mutex(1,0); - return res; - } - - // Return number of available CPU cores. - inline unsigned int nb_cpus() { - unsigned int res = 1; -#if cimg_OS==2 - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); - res = (unsigned int)sysinfo.dwNumberOfProcessors; -#else - res = (unsigned int)sysconf(_SC_NPROCESSORS_ONLN); -#endif - return res?res:1U; - } - - // Lock/unlock mutex for CImg multi-thread programming. - inline int mutex(const unsigned int n, const int lock_mode) { - switch (lock_mode) { - case 0 : cimg::Mutex_attr().unlock(n); return 0; - case 1 : cimg::Mutex_attr().lock(n); return 0; - default : return cimg::Mutex_attr().trylock(n); - } - } - - //! Display a warning message on the default output stream. - /** - \param format C-string containing the format of the message, as with std::printf(). - \note If configuration macro \c cimg_strict_warnings is set, this function throws a - \c CImgWarningException instead. - \warning As the first argument is a format string, it is highly recommended to write - \code - cimg::warn("%s",warning_message); - \endcode - instead of - \code - cimg::warn(warning_message); - \endcode - if \c warning_message can be arbitrary, to prevent nasty memory access. - **/ - inline void warn(const char *const format, ...) { - if (cimg::exception_mode()>=1) { - char *const message = new char[16384]; - std::va_list ap; - va_start(ap,format); - cimg_vsnprintf(message,16384,format,ap); - va_end(ap); -#ifdef cimg_strict_warnings - throw CImgWarningException(message); -#else - std::fprintf(cimg::output(),"\n%s[CImg] *** Warning ***%s%s\n",cimg::t_red,cimg::t_normal,message); -#endif - delete[] message; - } - } - - // Execute an external system command. - /** - \param command C-string containing the command line to execute. - \param module_name Module name. - \return Status value of the executed command, whose meaning is OS-dependent. - \note This function is similar to std::system() - but it does not open an extra console windows - on Windows-based systems. - **/ - inline int system(const char *const -#ifndef cimg_no_system_calls - command -#endif - , const char *const module_name=0) { - cimg::unused(module_name); -#ifdef cimg_no_system_calls - return -1; -#else -#if cimg_OS==1 - const unsigned int l = (unsigned int)std::strlen(command); - if (l) { - char *const ncommand = new char[l + 16]; - std::strncpy(ncommand,command,l); - std::strcpy(ncommand + l," 2> /dev/null"); // Make command silent. - const int out_val = std::system(ncommand); - delete[] ncommand; - return out_val; - } else return -1; -#elif cimg_OS==2 - PROCESS_INFORMATION pi; - STARTUPINFO si; - std::memset(&pi,0,sizeof(PROCESS_INFORMATION)); - std::memset(&si,0,sizeof(STARTUPINFO)); - GetStartupInfo(&si); - si.cb = sizeof(si); - si.wShowWindow = SW_HIDE; - si.dwFlags |= SW_HIDE | STARTF_USESHOWWINDOW; - const BOOL res = CreateProcess((LPCTSTR)module_name,(LPTSTR)command,0,0,FALSE,0,0,0,&si,&pi); - if (res) { - WaitForSingleObject(pi.hProcess,INFINITE); - CloseHandle(pi.hThread); - CloseHandle(pi.hProcess); - return 0; - } else return std::system(command); -#endif -#endif - } - - //! Return a reference to a temporary variable of type T. - template - inline T& temporary(const T&) { - static T temp; - return temp; - } - - //! Exchange values of variables \c a and \c b. - template - inline void swap(T& a, T& b) { T t = a; a = b; b = t; } - - //! Exchange values of variables (\c a1,\c a2) and (\c b1,\c b2). - template - inline void swap(T1& a1, T1& b1, T2& a2, T2& b2) { - cimg::swap(a1,b1); cimg::swap(a2,b2); - } - - //! Exchange values of variables (\c a1,\c a2,\c a3) and (\c b1,\c b2,\c b3). - template - inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3) { - cimg::swap(a1,b1,a2,b2); cimg::swap(a3,b3); - } - - //! Exchange values of variables (\c a1,\c a2,...,\c a4) and (\c b1,\c b2,...,\c b4). - template - inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3, T4& a4, T4& b4) { - cimg::swap(a1,b1,a2,b2,a3,b3); cimg::swap(a4,b4); - } - - //! Exchange values of variables (\c a1,\c a2,...,\c a5) and (\c b1,\c b2,...,\c b5). - template - inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3, T4& a4, T4& b4, T5& a5, T5& b5) { - cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4); cimg::swap(a5,b5); - } - - //! Exchange values of variables (\c a1,\c a2,...,\c a6) and (\c b1,\c b2,...,\c b6). - template - inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3, T4& a4, T4& b4, T5& a5, T5& b5, T6& a6, T6& b6) { - cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4,a5,b5); cimg::swap(a6,b6); - } - - //! Exchange values of variables (\c a1,\c a2,...,\c a7) and (\c b1,\c b2,...,\c b7). - template - inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3, T4& a4, T4& b4, T5& a5, T5& b5, T6& a6, T6& b6, - T7& a7, T7& b7) { - cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4,a5,b5,a6,b6); cimg::swap(a7,b7); - } - - //! Exchange values of variables (\c a1,\c a2,...,\c a8) and (\c b1,\c b2,...,\c b8). - template - inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3, T4& a4, T4& b4, T5& a5, T5& b5, T6& a6, T6& b6, - T7& a7, T7& b7, T8& a8, T8& b8) { - cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4,a5,b5,a6,b6,a7,b7); cimg::swap(a8,b8); - } - - //! Return the endianness of the current architecture. - /** - \return \c false for Little Endian or \c true for Big Endian. - **/ - inline bool endianness() { - const int x = 1; - return ((unsigned char*)&x)[0]?false:true; - } - - //! Reverse endianness of all elements in a memory buffer. - /** - \param[in,out] buffer Memory buffer whose endianness must be reversed. - \param size Number of buffer elements to reverse. - **/ - template - inline void invert_endianness(T* const buffer, const cimg_ulong size) { - if (size) switch (sizeof(T)) { - case 1 : break; - case 2 : { for (unsigned short *ptr = (unsigned short*)buffer + size; ptr>(unsigned short*)buffer; ) { - const unsigned short val = *(--ptr); - *ptr = (unsigned short)((val>>8)|((val<<8))); - } - } break; - case 4 : { for (unsigned int *ptr = (unsigned int*)buffer + size; ptr>(unsigned int*)buffer; ) { - const unsigned int val = *(--ptr); - *ptr = (val>>24)|((val>>8)&0xff00)|((val<<8)&0xff0000)|(val<<24); - } - } break; - default : { for (T* ptr = buffer + size; ptr>buffer; ) { - unsigned char *pb = (unsigned char*)(--ptr), *pe = pb + sizeof(T); - for (int i = 0; i<(int)sizeof(T)/2; ++i) swap(*(pb++),*(--pe)); - } - } - } - } - - //! Reverse endianness of a single variable. - /** - \param[in,out] a Variable to reverse. - \return Reference to reversed variable. - **/ - template - inline T& invert_endianness(T& a) { - invert_endianness(&a,1); - return a; - } - - // Conversion functions to get more precision when trying to store unsigned ints values as floats. - inline unsigned int float2uint(const float f) { - int tmp = 0; - std::memcpy(&tmp,&f,sizeof(float)); - if (tmp>=0) return (unsigned int)f; - unsigned int u; - // use memcpy instead of assignment to avoid undesired optimizations by C++-compiler. - std::memcpy(&u,&f,sizeof(float)); - return ((u)<<1)>>1; // set sign bit to 0. - } - - inline float uint2float(const unsigned int u) { - if (u<(1U<<19)) return (float)u; // Consider safe storage of unsigned int as floats until 19bits (i.e 524287). - float f; - const unsigned int v = u|(1U<<(8*sizeof(unsigned int)-1)); // set sign bit to 1. - // use memcpy instead of simple assignment to avoid undesired optimizations by C++-compiler. - std::memcpy(&f,&v,sizeof(float)); - return f; - } - - //! Return the value of a system timer, with a millisecond precision. - /** - \note The timer does not necessarily starts from \c 0. - **/ - inline cimg_ulong time() { -#if cimg_OS==1 - struct timeval st_time; - gettimeofday(&st_time,0); - return (cimg_ulong)(st_time.tv_usec/1000 + st_time.tv_sec*1000); -#elif cimg_OS==2 - SYSTEMTIME st_time; - GetLocalTime(&st_time); - return (cimg_ulong)(st_time.wMilliseconds + 1000*(st_time.wSecond + 60*(st_time.wMinute + 60*st_time.wHour))); -#else - return 0; -#endif - } - - // Implement a tic/toc mechanism to display elapsed time of algorithms. - inline cimg_ulong tictoc(const bool is_tic); - - //! Start tic/toc timer for time measurement between code instructions. - /** - \return Current value of the timer (same value as time()). - **/ - inline cimg_ulong tic() { - return cimg::tictoc(true); - } - - //! End tic/toc timer and displays elapsed time from last call to tic(). - /** - \return Time elapsed (in ms) since last call to tic(). - **/ - inline cimg_ulong toc() { - return cimg::tictoc(false); - } - - //! Sleep for a given numbers of milliseconds. - /** - \param milliseconds Number of milliseconds to wait for. - \note This function frees the CPU ressources during the sleeping time. - It can be used to temporize your program properly, without wasting CPU time. - **/ - inline void sleep(const unsigned int milliseconds) { -#if cimg_OS==1 - struct timespec tv; - tv.tv_sec = milliseconds/1000; - tv.tv_nsec = (milliseconds%1000)*1000000; - nanosleep(&tv,0); -#elif cimg_OS==2 - Sleep(milliseconds); -#endif - } - - inline unsigned int _wait(const unsigned int milliseconds, cimg_ulong& timer) { - if (!timer) timer = cimg::time(); - const cimg_ulong current_time = cimg::time(); - if (current_time>=timer + milliseconds) { timer = current_time; return 0; } - const unsigned int time_diff = (unsigned int)(timer + milliseconds - current_time); - timer = current_time + time_diff; - cimg::sleep(time_diff); - return time_diff; - } - - //! Wait for a given number of milliseconds since the last call to wait(). - /** - \param milliseconds Number of milliseconds to wait for. - \return Number of milliseconds elapsed since the last call to wait(). - \note Same as sleep() with a waiting time computed with regard to the last call - of wait(). It may be used to temporize your program properly, without wasting CPU time. - **/ - inline cimg_long wait(const unsigned int milliseconds) { - cimg::mutex(3); - static cimg_ulong timer = 0; - if (!timer) timer = cimg::time(); - cimg::mutex(3,0); - return _wait(milliseconds,timer); - } - - // Random number generators. - // CImg may use its own Random Number Generator (RNG) if configuration macro 'cimg_use_rng' is set. - // Use it for instance when you have to deal with concurrent threads trying to call std::srand() - // at the same time! -#ifdef cimg_use_rng - -#include - - // Use a custom RNG. - inline unsigned int _rand(const unsigned int seed=0, const bool set_seed=false) { - static cimg_ulong next = 0xB16B00B5; - cimg::mutex(4); - if (set_seed) next = (cimg_ulong)seed; - next = next*1103515245 + 12345U; - cimg::mutex(4,0); - return (unsigned int)(next&0xFFFFFFU); - } - - inline void srand() { - const unsigned int t = (unsigned int)cimg::time(); -#if cimg_OS==1 - cimg::_rand(t + (unsigned int)getpid(),true); -#elif cimg_OS==2 - cimg::_rand(t + (unsigned int)_getpid(),true); -#else - cimg::_rand(t,true); -#endif - } - - inline void srand(const unsigned int seed) { - _rand(seed,true); - } - - inline double rand(const double val_min, const double val_max) { - const double val = cimg::_rand()/16777215.; - return val_min + (val_max - val_min)*val; - } - -#else - - // Use the system RNG. - inline void srand() { - const unsigned int t = (unsigned int)cimg::time(); -#if cimg_OS==1 - std::srand(t + (unsigned int)getpid()); -#elif cimg_OS==2 - std::srand(t + (unsigned int)_getpid()); -#else - std::srand(t); -#endif - } - - inline void srand(const unsigned int seed) { - std::srand(seed); - } - - //! Return a random variable uniformely distributed between [val_min,val_max]. - /** - **/ - inline double rand(const double val_min, const double val_max) { - const double val = (double)std::rand()/RAND_MAX; - return val_min + (val_max - val_min)*val; - } -#endif - - //! Return a random variable uniformely distributed between [0,val_max]. - /** - **/ - inline double rand(const double val_max=1) { - return cimg::rand(0,val_max); - } - - //! Return a random variable following a gaussian distribution and a standard deviation of 1. - /** - **/ - inline double grand() { - double x1, w; - do { - const double x2 = cimg::rand(-1,1); - x1 = cimg::rand(-1,1); - w = x1*x1 + x2*x2; - } while (w<=0 || w>=1.0); - return x1*std::sqrt((-2*std::log(w))/w); - } - - //! Return a random variable following a Poisson distribution of parameter z. - /** - **/ - inline unsigned int prand(const double z) { - if (z<=1.0e-10) return 0; - if (z>100) return (unsigned int)((std::sqrt(z) * cimg::grand()) + z); - unsigned int k = 0; - const double y = std::exp(-z); - for (double s = 1.0; s>=y; ++k) s*=cimg::rand(); - return k - 1; - } - - //! Bitwise-rotate value on the left. - template - inline T rol(const T& a, const unsigned int n=1) { - return n?(T)((a<>((sizeof(T)<<3) - n))):a; - } - - inline float rol(const float a, const unsigned int n=1) { - return (float)rol((int)a,n); - } - - inline double rol(const double a, const unsigned int n=1) { - return (double)rol((cimg_long)a,n); - } - - inline double rol(const long double a, const unsigned int n=1) { - return (double)rol((cimg_long)a,n); - } - - //! Bitwise-rotate value on the right. - template - inline T ror(const T& a, const unsigned int n=1) { - return n?(T)((a>>n)|(a<<((sizeof(T)<<3) - n))):a; - } - - inline float ror(const float a, const unsigned int n=1) { - return (float)ror((int)a,n); - } - - inline double ror(const double a, const unsigned int n=1) { - return (double)ror((cimg_long)a,n); - } - - inline double ror(const long double a, const unsigned int n=1) { - return (double)ror((cimg_long)a,n); - } - - //! Return absolute value of a value. - template - inline T abs(const T& a) { - return a>=0?a:-a; - } - inline bool abs(const bool a) { - return a; - } - inline int abs(const unsigned char a) { - return (int)a; - } - inline int abs(const unsigned short a) { - return (int)a; - } - inline int abs(const unsigned int a) { - return (int)a; - } - inline int abs(const int a) { - return std::abs(a); - } - inline cimg_int64 abs(const cimg_uint64 a) { - return (cimg_int64)a; - } - inline double abs(const double a) { - return std::fabs(a); - } - inline float abs(const float a) { - return (float)std::fabs((double)a); - } - - //! Return square of a value. - template - inline T sqr(const T& val) { - return val*val; - } - - //! Return 1 + log_10(x) of a value \c x. - inline int xln(const int x) { - return x>0?(int)(1 + std::log10((double)x)):1; - } - - //! Return the minimum between two values. - template - inline typename cimg::superset::type min(const t1& a, const t2& b) { - typedef typename cimg::superset::type t1t2; - return (t1t2)(a<=b?a:b); - } - - //! Return the minimum between three values. - template - inline typename cimg::superset2::type min(const t1& a, const t2& b, const t3& c) { - typedef typename cimg::superset2::type t1t2t3; - return (t1t2t3)cimg::min(cimg::min(a,b),c); - } - - //! Return the minimum between four values. - template - inline typename cimg::superset3::type min(const t1& a, const t2& b, const t3& c, const t4& d) { - typedef typename cimg::superset3::type t1t2t3t4; - return (t1t2t3t4)cimg::min(cimg::min(a,b,c),d); - } - - //! Return the maximum between two values. - template - inline typename cimg::superset::type max(const t1& a, const t2& b) { - typedef typename cimg::superset::type t1t2; - return (t1t2)(a>=b?a:b); - } - - //! Return the maximum between three values. - template - inline typename cimg::superset2::type max(const t1& a, const t2& b, const t3& c) { - typedef typename cimg::superset2::type t1t2t3; - return (t1t2t3)cimg::max(cimg::max(a,b),c); - } - - //! Return the maximum between four values. - template - inline typename cimg::superset3::type max(const t1& a, const t2& b, const t3& c, const t4& d) { - typedef typename cimg::superset3::type t1t2t3t4; - return (t1t2t3t4)cimg::max(cimg::max(a,b,c),d); - } - - //! Return the sign of a value. - template - inline T sign(const T& x) { - return (x<0)?(T)(-1):(x==0?(T)0:(T)1); - } - - //! Return the nearest power of 2 higher than given value. - template - inline cimg_ulong nearest_pow2(const T& x) { - cimg_ulong i = 1; - while (x>i) i<<=1; - return i; - } - - //! Return the sinc of a given value. - inline double sinc(const double x) { - return x?std::sin(x)/x:1; - } - - //! Return the modulo of a value. - /** - \param x Input value. - \param m Modulo value. - \note This modulo function accepts negative and floating-points modulo numbers, as well as variables of any type. - **/ - template - inline T mod(const T& x, const T& m) { - const double dx = (double)x, dm = (double)m; - return (T)(dx - dm * std::floor(dx / dm)); - } - inline int mod(const bool x, const bool m) { - return m?(x?1:0):0; - } - inline int mod(const unsigned char x, const unsigned char m) { - return x%m; - } - inline int mod(const char x, const char m) { -#if defined(CHAR_MAX) && CHAR_MAX==255 - return x%m; -#else - return x>=0?x%m:(x%m?m + x%m:0); -#endif - } - inline int mod(const unsigned short x, const unsigned short m) { - return x%m; - } - inline int mod(const short x, const short m) { - return x>=0?x%m:(x%m?m + x%m:0); - } - inline int mod(const unsigned int x, const unsigned int m) { - return (int)(x%m); - } - inline int mod(const int x, const int m) { - return x>=0?x%m:(x%m?m + x%m:0); - } - inline cimg_int64 mod(const cimg_uint64 x, const cimg_uint64 m) { - return x%m; - } - inline cimg_int64 mod(const cimg_int64 x, const cimg_int64 m) { - return x>=0?x%m:(x%m?m + x%m:0); - } - - //! Return the min-mod of two values. - /** - \note minmod(\p a,\p b) is defined to be: - - minmod(\p a,\p b) = min(\p a,\p b), if \p a and \p b have the same sign. - - minmod(\p a,\p b) = 0, if \p a and \p b have different signs. - **/ - template - inline T minmod(const T& a, const T& b) { - return a*b<=0?0:(a>0?(a - inline T round(const T& x, const double y=1, const int rounding_type=0) { - if (y<=0) return x; - const double sx = (double)x/y, floor = std::floor(sx), delta = sx - floor; - return (T)(y*(rounding_type<0?floor:rounding_type>0?std::ceil(sx):delta<0.5?floor:std::ceil(sx))); - } - - inline double _pythagore(double a, double b) { - const double absa = cimg::abs(a), absb = cimg::abs(b); - if (absa>absb) { const double tmp = absb/absa; return absa*std::sqrt(1.0 + tmp*tmp); } - else { const double tmp = absa/absb; return absb==0?0:absb*std::sqrt(1.0 + tmp*tmp); } - } - - //! Return sqrt(x^2 + y^2). - inline double hypot(const double x, const double y) { - double nx = cimg::abs(x), ny = cimg::abs(y), t; - if (nx0) { t/=nx; return nx*std::sqrt(1+t*t); } - return 0; - } - - //! Return the factorial of n - inline double factorial(const int n) { - if (n<0) return cimg::type::nan(); - if (n<2) return 1; - double res = 2; - for (int i = 3; i<=n; ++i) res*=i; - return res; - } - - //! Return the number of permutations of k objects in a set of n objects. - inline double permutations(const int k, const int n, const bool with_order) { - if (n<0 || k<0) return cimg::type::nan(); - if (k>n) return 0; - double res = 1; - for (int i = n; i>=n - k + 1; --i) res*=i; - return with_order?res:res/cimg::factorial(k); - } - - //! Return fibonacci number. - inline double fibonacci(const int n) { - if (n<0) return cimg::type::nan(); - if (n<3) return 1; - cimg_long fn1 = 1, fn2 = 1, fn = 2; - for (int i = 3; i<=n; ++i) { fn = fn1 + fn2; fn2 = fn1; fn1 = fn; } - return (double)fn; - } - - //! Convert ascii character to lower case. - inline char lowercase(const char x) { - return (char)((x<'A'||x>'Z')?x:x - 'A' + 'a'); - } - inline double lowercase(const double x) { - return (double)((x<'A'||x>'Z')?x:x - 'A' + 'a'); - } - - //! Convert C-string to lower case. - inline void lowercase(char *const str) { - if (str) for (char *ptr = str; *ptr; ++ptr) *ptr = lowercase(*ptr); - } - - //! Convert ascii character to upper case. - inline char uppercase(const char x) { - return (char)((x<'a'||x>'z')?x:x - 'a' + 'A'); - } - - inline double uppercase(const double x) { - return (double)((x<'a'||x>'z')?x:x - 'a' + 'A'); - } - - //! Convert C-string to upper case. - inline void uppercase(char *const str) { - if (str) for (char *ptr = str; *ptr; ++ptr) *ptr = uppercase(*ptr); - } - - //! Read value in a C-string. - /** - \param str C-string containing the float value to read. - \return Read value. - \note Same as std::atof() extended to manage the retrieval of fractions from C-strings, - as in "1/2". - **/ - inline double atof(const char *const str) { - double x = 0, y = 1; - return str && cimg_sscanf(str,"%lf/%lf",&x,&y)>0?x/y:0; - } - - //! Compare the first \p l characters of two C-strings, ignoring the case. - /** - \param str1 C-string. - \param str2 C-string. - \param l Number of characters to compare. - \return \c 0 if the two strings are equal, something else otherwise. - \note This function has to be defined since it is not provided by all C++-compilers (not ANSI). - **/ - inline int strncasecmp(const char *const str1, const char *const str2, const int l) { - if (!l) return 0; - if (!str1) return str2?-1:0; - const char *nstr1 = str1, *nstr2 = str2; - int k, diff = 0; for (k = 0; kp && str[q]==delimiter; ) { --q; if (!is_iterative) break; } - } - const int n = q - p + 1; - if (n!=l) { std::memmove(str,str + p,(unsigned int)n); str[n] = 0; return true; } - return false; - } - - //! Replace reserved characters (for Windows filename) by another character. - /** - \param[in,out] str C-string to work with (modified at output). - \param[in] c Replacement character. - **/ - inline void strwindows_reserved(char *const str, const char c='_') { - for (char *s = str; *s; ++s) { - const char i = *s; - if (i=='<' || i=='>' || i==':' || i=='\"' || i=='/' || i=='\\' || i=='|' || i=='?' || i=='*') *s = c; - } - } - - //! Replace escape sequences in C-strings by their binary ascii values. - /** - \param[in,out] str C-string to work with (modified at output). - **/ - inline void strunescape(char *const str) { -#define cimg_strunescape(ci,co) case ci : *nd = co; ++ns; break; - unsigned int val = 0; - for (char *ns = str, *nd = str; *ns || (bool)(*nd=0); ++nd) if (*ns=='\\') switch (*(++ns)) { - cimg_strunescape('a','\a'); - cimg_strunescape('b','\b'); - cimg_strunescape('e',0x1B); - cimg_strunescape('f','\f'); - cimg_strunescape('n','\n'); - cimg_strunescape('r','\r'); - cimg_strunescape('t','\t'); - cimg_strunescape('v','\v'); - cimg_strunescape('\\','\\'); - cimg_strunescape('\'','\''); - cimg_strunescape('\"','\"'); - cimg_strunescape('\?','\?'); - case 0 : *nd = 0; break; - case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : - cimg_sscanf(ns,"%o",&val); while (*ns>='0' && *ns<='7') ++ns; - *nd = (char)val; break; - case 'x' : - cimg_sscanf(++ns,"%x",&val); - while ((*ns>='0' && *ns<='9') || (*ns>='a' && *ns<='f') || (*ns>='A' && *ns<='F')) ++ns; - *nd = (char)val; break; - default : *nd = *(ns++); - } else *nd = *(ns++); - } - - // Return a temporary string describing the size of a memory buffer. - inline const char *strbuffersize(const cimg_ulong size); - - // Return string that identifies the running OS. - inline const char *stros() { -#if defined(linux) || defined(__linux) || defined(__linux__) - static const char *const str = "Linux"; -#elif defined(sun) || defined(__sun) - static const char *const str = "Sun OS"; -#elif defined(BSD) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined (__DragonFly__) - static const char *const str = "BSD"; -#elif defined(sgi) || defined(__sgi) - static const char *const str = "Irix"; -#elif defined(__MACOSX__) || defined(__APPLE__) - static const char *const str = "Mac OS"; -#elif defined(unix) || defined(__unix) || defined(__unix__) - static const char *const str = "Generic Unix"; -#elif defined(_MSC_VER) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || \ - defined(WIN64) || defined(_WIN64) || defined(__WIN64__) - static const char *const str = "Windows"; -#else - const char - *const _str1 = std::getenv("OSTYPE"), - *const _str2 = _str1?_str1:std::getenv("OS"), - *const str = _str2?_str2:"Unknown OS"; -#endif - return str; - } - - //! Return the basename of a filename. - inline const char* basename(const char *const s, const char separator=cimg_file_separator) { - const char *p = 0, *np = s; - while (np>=s && (p=np)) np = std::strchr(np,separator) + 1; - return p; - } - - // Return a random filename. - inline const char* filenamerand() { - cimg::mutex(6); - static char randomid[9]; - cimg::srand(); - for (unsigned int k = 0; k<8; ++k) { - const int v = (int)cimg::rand(65535)%3; - randomid[k] = (char)(v==0?('0' + ((int)cimg::rand(65535)%10)): - (v==1?('a' + ((int)cimg::rand(65535)%26)):('A' + ((int)cimg::rand(65535)%26)))); - } - cimg::mutex(6,0); - return randomid; - } - - // Convert filename as a Windows-style filename (short path name). - inline void winformat_string(char *const str) { - if (str && *str) { -#if cimg_OS==2 - char *const nstr = new char[MAX_PATH]; - if (GetShortPathNameA(str,nstr,MAX_PATH)) std::strcpy(str,nstr); - delete[] nstr; -#endif - } - } - - // Open a file (with wide character support on Windows). - inline std::FILE *win_fopen(const char *const path, const char *const mode); - - //! Open a file. - /** - \param path Path of the filename to open. - \param mode C-string describing the opening mode. - \return Opened file. - \note Same as std::fopen() but throw a \c CImgIOException when - the specified file cannot be opened, instead of returning \c 0. - **/ - inline std::FILE *fopen(const char *const path, const char *const mode) { - if (!path) - throw CImgArgumentException("cimg::fopen(): Specified file path is (null)."); - if (!mode) - throw CImgArgumentException("cimg::fopen(): File '%s', specified mode is (null).", - path); - std::FILE *res = 0; - if (*path=='-' && (!path[1] || path[1]=='.')) { - res = (*mode=='r')?stdin:stdout; -#if cimg_OS==2 - if (*mode && mode[1]=='b') { // Force stdin/stdout to be in binary mode. - if (_setmode(_fileno(res),0x8000)==-1) res = 0; - } -#endif - } else res = std_fopen(path,mode); - if (!res) throw CImgIOException("cimg::fopen(): Failed to open file '%s' with mode '%s'.", - path,mode); - return res; - } - - //! Close a file. - /** - \param file File to close. - \return \c 0 if file has been closed properly, something else otherwise. - \note Same as std::fclose() but display a warning message if - the file has not been closed properly. - **/ - inline int fclose(std::FILE *file) { - if (!file) warn("cimg::fclose(): Specified file is (null)."); - if (!file || file==stdin || file==stdout) return 0; - const int errn = std::fclose(file); - if (errn!=0) warn("cimg::fclose(): Error code %d returned during file closing.", - errn); - return errn; - } - - //! Version of 'fseek()' that supports >=64bits offsets everywhere (for Windows). - inline int fseek(FILE *stream, cimg_long offset, int origin) { -#if cimg_OS==2 - return _fseeki64(stream,(__int64)offset,origin); -#else - return std::fseek(stream,offset,origin); -#endif - } - - //! Version of 'ftell()' that supports >=64bits offsets everywhere (for Windows). - inline cimg_long ftell(FILE *stream) { -#if cimg_OS==2 - return (cimg_long)_ftelli64(stream); -#else - return (cimg_long)std::ftell(stream); -#endif - } - - //! Check if a path is a directory. - /** - \param path Specified path to test. - **/ - inline bool is_directory(const char *const path) { - if (!path || !*path) return false; -#if cimg_OS==1 - struct stat st_buf; - return (!stat(path,&st_buf) && S_ISDIR(st_buf.st_mode)); -#elif cimg_OS==2 - const unsigned int res = (unsigned int)GetFileAttributesA(path); - return res==INVALID_FILE_ATTRIBUTES?false:(res&16); -#endif - } - - //! Check if a path is a file. - /** - \param path Specified path to test. - **/ - inline bool is_file(const char *const path) { - if (!path || !*path) return false; - std::FILE *const file = std_fopen(path,"rb"); - if (!file) return false; - std::fclose(file); - return !is_directory(path); - } - - //! Get last write time of a given file or directory. - /** - \param path Specified path to get attributes from. - \param attr Type of requested time attribute. - Can be { 0=year | 1=month | 2=day | 3=day of week | 4=hour | 5=minute | 6=second } - \return -1 if requested attribute could not be read. - **/ - inline int fdate(const char *const path, const unsigned int attr) { - int res = -1; - if (!path || !*path || attr>6) return -1; - cimg::mutex(6); -#if cimg_OS==2 - HANDLE file = CreateFileA(path,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); - if (file!=INVALID_HANDLE_VALUE) { - FILETIME _ft; - SYSTEMTIME ft; - if (GetFileTime(file,0,0,&_ft) && FileTimeToSystemTime(&_ft,&ft)) - res = (int)(attr==0?ft.wYear:attr==1?ft.wMonth:attr==2?ft.wDay:attr==3?ft.wDayOfWeek: - attr==4?ft.wHour:attr==5?ft.wMinute:ft.wSecond); - CloseHandle(file); - } -#else - struct stat st_buf; - if (!stat(path,&st_buf)) { - const time_t _ft = st_buf.st_mtime; - const struct tm& ft = *std::localtime(&_ft); - res = (int)(attr==0?ft.tm_year + 1900:attr==1?ft.tm_mon + 1:attr==2?ft.tm_mday:attr==3?ft.tm_wday: - attr==4?ft.tm_hour:attr==5?ft.tm_min:ft.tm_sec); - } -#endif - cimg::mutex(6,0); - return res; - } - - //! Get current local time. - /** - \param attr Type of requested time attribute. - Can be { 0=year | 1=month | 2=day | 3=day of week | 4=hour | 5=minute | 6=second } - **/ - inline int date(const unsigned int attr) { - int res; - cimg::mutex(6); -#if cimg_OS==2 - SYSTEMTIME st; - GetLocalTime(&st); - res = (int)(attr==0?st.wYear:attr==1?st.wMonth:attr==2?st.wDay:attr==3?st.wDayOfWeek: - attr==4?st.wHour:attr==5?st.wMinute:st.wSecond); -#else - time_t _st; - std::time(&_st); - struct tm *st = std::localtime(&_st); - res = (int)(attr==0?st->tm_year + 1900:attr==1?st->tm_mon + 1:attr==2?st->tm_mday:attr==3?st->tm_wday: - attr==4?st->tm_hour:attr==5?st->tm_min:st->tm_sec); -#endif - cimg::mutex(6,0); - return res; - } - - // Get/set path to store temporary files. - inline const char* temporary_path(const char *const user_path=0, const bool reinit_path=false); - - // Get/set path to the Program Files/ directory (Windows only). -#if cimg_OS==2 - inline const char* programfiles_path(const char *const user_path=0, const bool reinit_path=false); -#endif - - // Get/set path to the ImageMagick's \c convert binary. - inline const char* imagemagick_path(const char *const user_path=0, const bool reinit_path=false); - - // Get/set path to the GraphicsMagick's \c gm binary. - inline const char* graphicsmagick_path(const char *const user_path=0, const bool reinit_path=false); - - // Get/set path to the XMedcon's \c medcon binary. - inline const char* medcon_path(const char *const user_path=0, const bool reinit_path=false); - - // Get/set path to the FFMPEG's \c ffmpeg binary. - inline const char *ffmpeg_path(const char *const user_path=0, const bool reinit_path=false); - - // Get/set path to the \c gzip binary. - inline const char *gzip_path(const char *const user_path=0, const bool reinit_path=false); - - // Get/set path to the \c gunzip binary. - inline const char *gunzip_path(const char *const user_path=0, const bool reinit_path=false); - - // Get/set path to the \c dcraw binary. - inline const char *dcraw_path(const char *const user_path=0, const bool reinit_path=false); - - // Get/set path to the \c wget binary. - inline const char *wget_path(const char *const user_path=0, const bool reinit_path=false); - - // Get/set path to the \c curl binary. - inline const char *curl_path(const char *const user_path=0, const bool reinit_path=false); - - //! Split filename into two C-strings \c body and \c extension. - /** - filename and body must not overlap! - **/ - inline const char *split_filename(const char *const filename, char *const body=0) { - if (!filename) { if (body) *body = 0; return 0; } - const char *p = 0; for (const char *np = filename; np>=filename && (p=np); np = std::strchr(np,'.') + 1) {} - if (p==filename) { - if (body) std::strcpy(body,filename); - return filename + std::strlen(filename); - } - const unsigned int l = (unsigned int)(p - filename - 1); - if (body) { if (l) std::memcpy(body,filename,l); body[l] = 0; } - return p; - } - - //! Generate a numbered version of a filename. - inline char* number_filename(const char *const filename, const int number, - const unsigned int digits, char *const str) { - if (!filename) { if (str) *str = 0; return 0; } - char *const format = new char[1024], *const body = new char[1024]; - const char *const ext = cimg::split_filename(filename,body); - if (*ext) cimg_snprintf(format,1024,"%%s_%%.%ud.%%s",digits); - else cimg_snprintf(format,1024,"%%s_%%.%ud",digits); - cimg_sprintf(str,format,body,number,ext); - delete[] format; delete[] body; - return str; - } - - //! Read data from file. - /** - \param[out] ptr Pointer to memory buffer that will contain the binary data read from file. - \param nmemb Number of elements to read. - \param stream File to read data from. - \return Number of read elements. - \note Same as std::fread() but may display warning message if all elements could not be read. - **/ - template - inline size_t fread(T *const ptr, const size_t nmemb, std::FILE *stream) { - if (!ptr || !stream) - throw CImgArgumentException("cimg::fread(): Invalid reading request of %u %s%s from file %p to buffer %p.", - nmemb,cimg::type::string(),nmemb>1?"s":"",stream,ptr); - if (!nmemb) return 0; - const size_t wlimitT = 63*1024*1024, wlimit = wlimitT/sizeof(T); - size_t to_read = nmemb, al_read = 0, l_to_read = 0, l_al_read = 0; - do { - l_to_read = (to_read*sizeof(T))0); - if (to_read>0) - warn("cimg::fread(): Only %lu/%lu elements could be read from file.", - (unsigned long)al_read,(unsigned long)nmemb); - return al_read; - } - - //! Write data to file. - /** - \param ptr Pointer to memory buffer containing the binary data to write on file. - \param nmemb Number of elements to write. - \param[out] stream File to write data on. - \return Number of written elements. - \note Similar to std::fwrite but may display warning messages if all elements could not be written. - **/ - template - inline size_t fwrite(const T *ptr, const size_t nmemb, std::FILE *stream) { - if (!ptr || !stream) - throw CImgArgumentException("cimg::fwrite(): Invalid writing request of %u %s%s from buffer %p to file %p.", - nmemb,cimg::type::string(),nmemb>1?"s":"",ptr,stream); - if (!nmemb) return 0; - const size_t wlimitT = 63*1024*1024, wlimit = wlimitT/sizeof(T); - size_t to_write = nmemb, al_write = 0, l_to_write = 0, l_al_write = 0; - do { - l_to_write = (to_write*sizeof(T))0); - if (to_write>0) - warn("cimg::fwrite(): Only %lu/%lu elements could be written in file.", - (unsigned long)al_write,(unsigned long)nmemb); - return al_write; - } - - //! Create an empty file. - /** - \param file Input file (can be \c 0 if \c filename is set). - \param filename Filename, as a C-string (can be \c 0 if \c file is set). - **/ - inline void fempty(std::FILE *const file, const char *const filename) { - if (!file && !filename) - throw CImgArgumentException("cimg::fempty(): Specified filename is (null)."); - std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); - if (!file) cimg::fclose(nfile); - } - - // Try to guess format from an image file. - inline const char *ftype(std::FILE *const file, const char *const filename); - - // Load file from network as a local temporary file. - inline char *load_network(const char *const url, char *const filename_local, - const unsigned int timeout=0, const bool try_fallback=false, - const char *const referer=0); - - //! Return options specified on the command line. - inline const char* option(const char *const name, const int argc, const char *const *const argv, - const char *const defaut, const char *const usage, const bool reset_static) { - static bool first = true, visu = false; - if (reset_static) { first = true; return 0; } - const char *res = 0; - if (first) { - first = false; - visu = cimg::option("-h",argc,argv,(char*)0,(char*)0,false)!=0; - visu |= cimg::option("-help",argc,argv,(char*)0,(char*)0,false)!=0; - visu |= cimg::option("--help",argc,argv,(char*)0,(char*)0,false)!=0; - } - if (!name && visu) { - if (usage) { - std::fprintf(cimg::output(),"\n %s%s%s",cimg::t_red,cimg::basename(argv[0]),cimg::t_normal); - std::fprintf(cimg::output(),": %s",usage); - std::fprintf(cimg::output()," (%s, %s)\n\n",cimg_date,cimg_time); - } - if (defaut) std::fprintf(cimg::output(),"%s\n",defaut); - } - if (name) { - if (argc>0) { - int k = 0; - while (k Operating System: %s%-13s%s %s('cimg_OS'=%d)%s\n", - cimg::t_bold, - cimg_OS==1?"Unix":(cimg_OS==2?"Windows":"Unknow"), - cimg::t_normal,cimg::t_green, - cimg_OS, - cimg::t_normal); - - std::fprintf(cimg::output()," > CPU endianness: %s%s Endian%s\n", - cimg::t_bold, - cimg::endianness()?"Big":"Little", - cimg::t_normal); - - std::fprintf(cimg::output()," > Verbosity mode: %s%-13s%s %s('cimg_verbosity'=%d)%s\n", - cimg::t_bold, - cimg_verbosity==0?"Quiet": - cimg_verbosity==1?"Console": - cimg_verbosity==2?"Dialog": - cimg_verbosity==3?"Console+Warnings":"Dialog+Warnings", - cimg::t_normal,cimg::t_green, - cimg_verbosity, - cimg::t_normal); - - std::fprintf(cimg::output()," > Stricts warnings: %s%-13s%s %s('cimg_strict_warnings' %s)%s\n", - cimg::t_bold, -#ifdef cimg_strict_warnings - "Yes",cimg::t_normal,cimg::t_green,"defined", -#else - "No",cimg::t_normal,cimg::t_green,"undefined", -#endif - cimg::t_normal); - - std::fprintf(cimg::output()," > Using VT100 messages: %s%-13s%s %s('cimg_use_vt100' %s)%s\n", - cimg::t_bold, -#ifdef cimg_use_vt100 - "Yes",cimg::t_normal,cimg::t_green,"defined", -#else - "No",cimg::t_normal,cimg::t_green,"undefined", -#endif - cimg::t_normal); - - std::fprintf(cimg::output()," > Display type: %s%-13s%s %s('cimg_display'=%d)%s\n", - cimg::t_bold, - cimg_display==0?"No display":cimg_display==1?"X11":cimg_display==2?"Windows GDI":"Unknown", - cimg::t_normal,cimg::t_green, - cimg_display, - cimg::t_normal); - -#if cimg_display==1 - std::fprintf(cimg::output()," > Using XShm for X11: %s%-13s%s %s('cimg_use_xshm' %s)%s\n", - cimg::t_bold, -#ifdef cimg_use_xshm - "Yes",cimg::t_normal,cimg::t_green,"defined", -#else - "No",cimg::t_normal,cimg::t_green,"undefined", -#endif - cimg::t_normal); - - std::fprintf(cimg::output()," > Using XRand for X11: %s%-13s%s %s('cimg_use_xrandr' %s)%s\n", - cimg::t_bold, -#ifdef cimg_use_xrandr - "Yes",cimg::t_normal,cimg::t_green,"defined", -#else - "No",cimg::t_normal,cimg::t_green,"undefined", -#endif - cimg::t_normal); -#endif - std::fprintf(cimg::output()," > Using OpenMP: %s%-13s%s %s('cimg_use_openmp' %s)%s\n", - cimg::t_bold, -#ifdef cimg_use_openmp - "Yes",cimg::t_normal,cimg::t_green,"defined", -#else - "No",cimg::t_normal,cimg::t_green,"undefined", -#endif - cimg::t_normal); - std::fprintf(cimg::output()," > Using PNG library: %s%-13s%s %s('cimg_use_png' %s)%s\n", - cimg::t_bold, -#ifdef cimg_use_png - "Yes",cimg::t_normal,cimg::t_green,"defined", -#else - "No",cimg::t_normal,cimg::t_green,"undefined", -#endif - cimg::t_normal); - std::fprintf(cimg::output()," > Using JPEG library: %s%-13s%s %s('cimg_use_jpeg' %s)%s\n", - cimg::t_bold, -#ifdef cimg_use_jpeg - "Yes",cimg::t_normal,cimg::t_green,"defined", -#else - "No",cimg::t_normal,cimg::t_green,"undefined", -#endif - cimg::t_normal); - - std::fprintf(cimg::output()," > Using TIFF library: %s%-13s%s %s('cimg_use_tiff' %s)%s\n", - cimg::t_bold, -#ifdef cimg_use_tiff - "Yes",cimg::t_normal,cimg::t_green,"defined", -#else - "No",cimg::t_normal,cimg::t_green,"undefined", -#endif - cimg::t_normal); - - std::fprintf(cimg::output()," > Using Magick++ library: %s%-13s%s %s('cimg_use_magick' %s)%s\n", - cimg::t_bold, -#ifdef cimg_use_magick - "Yes",cimg::t_normal,cimg::t_green,"defined", -#else - "No",cimg::t_normal,cimg::t_green,"undefined", -#endif - cimg::t_normal); - - std::fprintf(cimg::output()," > Using FFTW3 library: %s%-13s%s %s('cimg_use_fftw3' %s)%s\n", - cimg::t_bold, -#ifdef cimg_use_fftw3 - "Yes",cimg::t_normal,cimg::t_green,"defined", -#else - "No",cimg::t_normal,cimg::t_green,"undefined", -#endif - cimg::t_normal); - - std::fprintf(cimg::output()," > Using LAPACK library: %s%-13s%s %s('cimg_use_lapack' %s)%s\n", - cimg::t_bold, -#ifdef cimg_use_lapack - "Yes",cimg::t_normal,cimg::t_green,"defined", -#else - "No",cimg::t_normal,cimg::t_green,"undefined", -#endif - cimg::t_normal); - - char *const tmp = new char[1024]; - cimg_snprintf(tmp,1024,"\"%.1020s\"",cimg::imagemagick_path()); - std::fprintf(cimg::output()," > Path of ImageMagick: %s%-13s%s\n", - cimg::t_bold, - tmp, - cimg::t_normal); - - cimg_snprintf(tmp,1024,"\"%.1020s\"",cimg::graphicsmagick_path()); - std::fprintf(cimg::output()," > Path of GraphicsMagick: %s%-13s%s\n", - cimg::t_bold, - tmp, - cimg::t_normal); - - cimg_snprintf(tmp,1024,"\"%.1020s\"",cimg::medcon_path()); - std::fprintf(cimg::output()," > Path of 'medcon': %s%-13s%s\n", - cimg::t_bold, - tmp, - cimg::t_normal); - - cimg_snprintf(tmp,1024,"\"%.1020s\"",cimg::temporary_path()); - std::fprintf(cimg::output()," > Temporary path: %s%-13s%s\n", - cimg::t_bold, - tmp, - cimg::t_normal); - - std::fprintf(cimg::output(),"\n"); - delete[] tmp; - } - - // Declare LAPACK function signatures if LAPACK support is enabled. -#ifdef cimg_use_lapack - template - inline void getrf(int &N, T *lapA, int *IPIV, int &INFO) { - dgetrf_(&N,&N,lapA,&N,IPIV,&INFO); - } - - inline void getrf(int &N, float *lapA, int *IPIV, int &INFO) { - sgetrf_(&N,&N,lapA,&N,IPIV,&INFO); - } - - template - inline void getri(int &N, T *lapA, int *IPIV, T* WORK, int &LWORK, int &INFO) { - dgetri_(&N,lapA,&N,IPIV,WORK,&LWORK,&INFO); - } - - inline void getri(int &N, float *lapA, int *IPIV, float* WORK, int &LWORK, int &INFO) { - sgetri_(&N,lapA,&N,IPIV,WORK,&LWORK,&INFO); - } - - template - inline void gesvd(char &JOB, int &M, int &N, T *lapA, int &MN, - T *lapS, T *lapU, T *lapV, T *WORK, int &LWORK, int &INFO) { - dgesvd_(&JOB,&JOB,&M,&N,lapA,&MN,lapS,lapU,&M,lapV,&N,WORK,&LWORK,&INFO); - } - - inline void gesvd(char &JOB, int &M, int &N, float *lapA, int &MN, - float *lapS, float *lapU, float *lapV, float *WORK, int &LWORK, int &INFO) { - sgesvd_(&JOB,&JOB,&M,&N,lapA,&MN,lapS,lapU,&M,lapV,&N,WORK,&LWORK,&INFO); - } - - template - inline void getrs(char &TRANS, int &N, T *lapA, int *IPIV, T *lapB, int &INFO) { - int one = 1; - dgetrs_(&TRANS,&N,&one,lapA,&N,IPIV,lapB,&N,&INFO); - } - - inline void getrs(char &TRANS, int &N, float *lapA, int *IPIV, float *lapB, int &INFO) { - int one = 1; - sgetrs_(&TRANS,&N,&one,lapA,&N,IPIV,lapB,&N,&INFO); - } - - template - inline void syev(char &JOB, char &UPLO, int &N, T *lapA, T *lapW, T *WORK, int &LWORK, int &INFO) { - dsyev_(&JOB,&UPLO,&N,lapA,&N,lapW,WORK,&LWORK,&INFO); - } - - inline void syev(char &JOB, char &UPLO, int &N, float *lapA, float *lapW, float *WORK, int &LWORK, int &INFO) { - ssyev_(&JOB,&UPLO,&N,lapA,&N,lapW,WORK,&LWORK,&INFO); - } - - template - inline void sgels(char & TRANS, int &M, int &N, int &NRHS, T* lapA, int &LDA, - T* lapB, int &LDB, T* WORK, int &LWORK, int &INFO){ - dgels_(&TRANS, &M, &N, &NRHS, lapA, &LDA, lapB, &LDB, WORK, &LWORK, &INFO); - } - - inline void sgels(char & TRANS, int &M, int &N, int &NRHS, float* lapA, int &LDA, - float* lapB, int &LDB, float* WORK, int &LWORK, int &INFO){ - sgels_(&TRANS, &M, &N, &NRHS, lapA, &LDA, lapB, &LDB, WORK, &LWORK, &INFO); - } - -#endif - - // End of the 'cimg' namespace - } - - /*------------------------------------------------ - # - # - # Definition of mathematical operators and - # external functions. - # - # - -------------------------------------------------*/ - -#define _cimg_create_ext_operators(typ) \ - template \ - inline CImg::type> operator+(const typ val, const CImg& img) { \ - return img + val; \ - } \ - template \ - inline CImg::type> operator-(const typ val, const CImg& img) { \ - typedef typename cimg::superset::type Tt; \ - return CImg(img._width,img._height,img._depth,img._spectrum,val)-=img; \ - } \ - template \ - inline CImg::type> operator*(const typ val, const CImg& img) { \ - return img*val; \ - } \ - template \ - inline CImg::type> operator/(const typ val, const CImg& img) { \ - return val*img.get_invert(); \ - } \ - template \ - inline CImg::type> operator&(const typ val, const CImg& img) { \ - return img & val; \ - } \ - template \ - inline CImg::type> operator|(const typ val, const CImg& img) { \ - return img | val; \ - } \ - template \ - inline CImg::type> operator^(const typ val, const CImg& img) { \ - return img ^ val; \ - } \ - template \ - inline bool operator==(const typ val, const CImg& img) { \ - return img == val; \ - } \ - template \ - inline bool operator!=(const typ val, const CImg& img) { \ - return img != val; \ - } - - _cimg_create_ext_operators(bool) - _cimg_create_ext_operators(unsigned char) - _cimg_create_ext_operators(char) - _cimg_create_ext_operators(signed char) - _cimg_create_ext_operators(unsigned short) - _cimg_create_ext_operators(short) - _cimg_create_ext_operators(unsigned int) - _cimg_create_ext_operators(int) - _cimg_create_ext_operators(cimg_uint64) - _cimg_create_ext_operators(cimg_int64) - _cimg_create_ext_operators(float) - _cimg_create_ext_operators(double) - _cimg_create_ext_operators(long double) - - template - inline CImg<_cimg_Tfloat> operator+(const char *const expression, const CImg& img) { - return img + expression; - } - - template - inline CImg<_cimg_Tfloat> operator-(const char *const expression, const CImg& img) { - return CImg<_cimg_Tfloat>(img,false).fill(expression,true)-=img; - } - - template - inline CImg<_cimg_Tfloat> operator*(const char *const expression, const CImg& img) { - return img*expression; - } - - template - inline CImg<_cimg_Tfloat> operator/(const char *const expression, const CImg& img) { - return expression*img.get_invert(); - } - - template - inline CImg operator&(const char *const expression, const CImg& img) { - return img & expression; - } - - template - inline CImg operator|(const char *const expression, const CImg& img) { - return img | expression; - } - - template - inline CImg operator^(const char *const expression, const CImg& img) { - return img ^ expression; - } - - template - inline bool operator==(const char *const expression, const CImg& img) { - return img==expression; - } - - template - inline bool operator!=(const char *const expression, const CImg& img) { - return img!=expression; - } - - template - inline CImg<_cimg_Tfloat> sqr(const CImg& instance) { - return instance.get_sqr(); - } - - template - inline CImg<_cimg_Tfloat> sqrt(const CImg& instance) { - return instance.get_sqrt(); - } - - template - inline CImg<_cimg_Tfloat> exp(const CImg& instance) { - return instance.get_exp(); - } - - template - inline CImg<_cimg_Tfloat> log(const CImg& instance) { - return instance.get_log(); - } - - template - inline CImg<_cimg_Tfloat> log2(const CImg& instance) { - return instance.get_log2(); - } - - template - inline CImg<_cimg_Tfloat> log10(const CImg& instance) { - return instance.get_log10(); - } - - template - inline CImg<_cimg_Tfloat> abs(const CImg& instance) { - return instance.get_abs(); - } - - template - inline CImg<_cimg_Tfloat> sign(const CImg& instance) { - return instance.get_sign(); - } - - template - inline CImg<_cimg_Tfloat> cos(const CImg& instance) { - return instance.get_cos(); - } - - template - inline CImg<_cimg_Tfloat> sin(const CImg& instance) { - return instance.get_sin(); - } - - template - inline CImg<_cimg_Tfloat> sinc(const CImg& instance) { - return instance.get_sinc(); - } - - template - inline CImg<_cimg_Tfloat> tan(const CImg& instance) { - return instance.get_tan(); - } - - template - inline CImg<_cimg_Tfloat> acos(const CImg& instance) { - return instance.get_acos(); - } - - template - inline CImg<_cimg_Tfloat> asin(const CImg& instance) { - return instance.get_asin(); - } - - template - inline CImg<_cimg_Tfloat> atan(const CImg& instance) { - return instance.get_atan(); - } - - template - inline CImg<_cimg_Tfloat> cosh(const CImg& instance) { - return instance.get_cosh(); - } - - template - inline CImg<_cimg_Tfloat> sinh(const CImg& instance) { - return instance.get_sinh(); - } - - template - inline CImg<_cimg_Tfloat> tanh(const CImg& instance) { - return instance.get_tanh(); - } - - template - inline CImg transpose(const CImg& instance) { - return instance.get_transpose(); - } - - template - inline CImg<_cimg_Tfloat> invert(const CImg& instance) { - return instance.get_invert(); - } - - template - inline CImg<_cimg_Tfloat> pseudoinvert(const CImg& instance) { - return instance.get_pseudoinvert(); - } - - /*----------------------------------- - # - # Define the CImgDisplay structure - # - ----------------------------------*/ - //! Allow the creation of windows, display images on them and manage user events (keyboard, mouse and windows events). - /** - CImgDisplay methods rely on a low-level graphic library to perform: it can be either \b X-Window - (X11, for Unix-based systems) or \b GDI32 (for Windows-based systems). - If both libraries are missing, CImgDisplay will not be able to display images on screen, and will enter - a minimal mode where warning messages will be outputed each time the program is trying to call one of the - CImgDisplay method. - - The configuration variable \c cimg_display tells about the graphic library used. - It is set automatically by \CImg when one of these graphic libraries has been detected. - But, you can override its value if necessary. Valid choices are: - - 0: Disable display capabilities. - - 1: Use \b X-Window (X11) library. - - 2: Use \b GDI32 library. - - Remember to link your program against \b X11 or \b GDI32 libraries if you use CImgDisplay. - **/ - struct CImgDisplay { - cimg_ulong _timer, _fps_frames, _fps_timer; - unsigned int _width, _height, _normalization; - float _fps_fps, _min, _max; - bool _is_fullscreen; - char *_title; - unsigned int _window_width, _window_height, _button, *_keys, *_released_keys; - int _window_x, _window_y, _mouse_x, _mouse_y, _wheel; - bool _is_closed, _is_resized, _is_moved, _is_event, - _is_keyESC, _is_keyF1, _is_keyF2, _is_keyF3, _is_keyF4, _is_keyF5, _is_keyF6, _is_keyF7, - _is_keyF8, _is_keyF9, _is_keyF10, _is_keyF11, _is_keyF12, _is_keyPAUSE, _is_key1, _is_key2, - _is_key3, _is_key4, _is_key5, _is_key6, _is_key7, _is_key8, _is_key9, _is_key0, - _is_keyBACKSPACE, _is_keyINSERT, _is_keyHOME, _is_keyPAGEUP, _is_keyTAB, _is_keyQ, _is_keyW, _is_keyE, - _is_keyR, _is_keyT, _is_keyY, _is_keyU, _is_keyI, _is_keyO, _is_keyP, _is_keyDELETE, - _is_keyEND, _is_keyPAGEDOWN, _is_keyCAPSLOCK, _is_keyA, _is_keyS, _is_keyD, _is_keyF, _is_keyG, - _is_keyH, _is_keyJ, _is_keyK, _is_keyL, _is_keyENTER, _is_keySHIFTLEFT, _is_keyZ, _is_keyX, - _is_keyC, _is_keyV, _is_keyB, _is_keyN, _is_keyM, _is_keySHIFTRIGHT, _is_keyARROWUP, _is_keyCTRLLEFT, - _is_keyAPPLEFT, _is_keyALT, _is_keySPACE, _is_keyALTGR, _is_keyAPPRIGHT, _is_keyMENU, _is_keyCTRLRIGHT, - _is_keyARROWLEFT, _is_keyARROWDOWN, _is_keyARROWRIGHT, _is_keyPAD0, _is_keyPAD1, _is_keyPAD2, _is_keyPAD3, - _is_keyPAD4, _is_keyPAD5, _is_keyPAD6, _is_keyPAD7, _is_keyPAD8, _is_keyPAD9, _is_keyPADADD, _is_keyPADSUB, - _is_keyPADMUL, _is_keyPADDIV; - - //@} - //--------------------------- - // - //! \name Plugins - //@{ - //--------------------------- - -#ifdef cimgdisplay_plugin -#include cimgdisplay_plugin -#endif -#ifdef cimgdisplay_plugin1 -#include cimgdisplay_plugin1 -#endif -#ifdef cimgdisplay_plugin2 -#include cimgdisplay_plugin2 -#endif -#ifdef cimgdisplay_plugin3 -#include cimgdisplay_plugin3 -#endif -#ifdef cimgdisplay_plugin4 -#include cimgdisplay_plugin4 -#endif -#ifdef cimgdisplay_plugin5 -#include cimgdisplay_plugin5 -#endif -#ifdef cimgdisplay_plugin6 -#include cimgdisplay_plugin6 -#endif -#ifdef cimgdisplay_plugin7 -#include cimgdisplay_plugin7 -#endif -#ifdef cimgdisplay_plugin8 -#include cimgdisplay_plugin8 -#endif - - //@} - //-------------------------------------------------------- - // - //! \name Constructors / Destructor / Instance Management - //@{ - //-------------------------------------------------------- - - //! Destructor. - /** - \note If the associated window is visible on the screen, it is closed by the call to the destructor. - **/ - ~CImgDisplay() { - assign(); - delete[] _keys; - delete[] _released_keys; - } - - //! Construct an empty display. - /** - \note Constructing an empty CImgDisplay instance does not make a window appearing on the screen, until - display of valid data is performed. - \par Example - \code - CImgDisplay disp; // Does actually nothing. - ... - disp.display(img); // Construct new window and display image in it. - \endcode - **/ - CImgDisplay(): - _width(0),_height(0),_normalization(0), - _min(0),_max(0), - _is_fullscreen(false), - _title(0), - _window_width(0),_window_height(0),_button(0), - _keys(new unsigned int[128]),_released_keys(new unsigned int[128]), - _window_x(0),_window_y(0),_mouse_x(-1),_mouse_y(-1),_wheel(0), - _is_closed(true),_is_resized(false),_is_moved(false),_is_event(false) { - assign(); - } - - //! Construct a display with specified dimensions. - /** \param width Window width. - \param height Window height. - \param title Window title. - \param normalization Normalization type - (0=none, 1=always, 2=once, 3=pixel type-dependent, see normalization()). - \param is_fullscreen Tells if fullscreen mode is enabled. - \param is_closed Tells if associated window is initially visible or not. - \note A black background is initially displayed on the associated window. - **/ - CImgDisplay(const unsigned int width, const unsigned int height, - const char *const title=0, const unsigned int normalization=3, - const bool is_fullscreen=false, const bool is_closed=false): - _width(0),_height(0),_normalization(0), - _min(0),_max(0), - _is_fullscreen(false), - _title(0), - _window_width(0),_window_height(0),_button(0), - _keys(new unsigned int[128]),_released_keys(new unsigned int[128]), - _window_x(0),_window_y(0),_mouse_x(-1),_mouse_y(-1),_wheel(0), - _is_closed(true),_is_resized(false),_is_moved(false),_is_event(false) { - assign(width,height,title,normalization,is_fullscreen,is_closed); - } - - //! Construct a display from an image. - /** \param img Image used as a model to create the window. - \param title Window title. - \param normalization Normalization type - (0=none, 1=always, 2=once, 3=pixel type-dependent, see normalization()). - \param is_fullscreen Tells if fullscreen mode is enabled. - \param is_closed Tells if associated window is initially visible or not. - \note The pixels of the input image are initially displayed on the associated window. - **/ - template - explicit CImgDisplay(const CImg& img, - const char *const title=0, const unsigned int normalization=3, - const bool is_fullscreen=false, const bool is_closed=false): - _width(0),_height(0),_normalization(0), - _min(0),_max(0), - _is_fullscreen(false), - _title(0), - _window_width(0),_window_height(0),_button(0), - _keys(new unsigned int[128]),_released_keys(new unsigned int[128]), - _window_x(0),_window_y(0),_mouse_x(-1),_mouse_y(-1),_wheel(0), - _is_closed(true),_is_resized(false),_is_moved(false),_is_event(false) { - assign(img,title,normalization,is_fullscreen,is_closed); - } - - //! Construct a display from an image list. - /** \param list The images list to display. - \param title Window title. - \param normalization Normalization type - (0=none, 1=always, 2=once, 3=pixel type-dependent, see normalization()). - \param is_fullscreen Tells if fullscreen mode is enabled. - \param is_closed Tells if associated window is initially visible or not. - \note All images of the list, appended along the X-axis, are initially displayed on the associated window. - **/ - template - explicit CImgDisplay(const CImgList& list, - const char *const title=0, const unsigned int normalization=3, - const bool is_fullscreen=false, const bool is_closed=false): - _width(0),_height(0),_normalization(0), - _min(0),_max(0), - _is_fullscreen(false), - _title(0), - _window_width(0),_window_height(0),_button(0), - _keys(new unsigned int[128]),_released_keys(new unsigned int[128]), - _window_x(0),_window_y(0),_mouse_x(-1),_mouse_y(-1),_wheel(0), - _is_closed(true),_is_resized(false),_is_moved(false),_is_event(false) { - assign(list,title,normalization,is_fullscreen,is_closed); - } - - //! Construct a display as a copy of an existing one. - /** - \param disp Display instance to copy. - \note The pixel buffer of the input window is initially displayed on the associated window. - **/ - CImgDisplay(const CImgDisplay& disp): - _width(0),_height(0),_normalization(0), - _min(0),_max(0), - _is_fullscreen(false), - _title(0), - _window_width(0),_window_height(0),_button(0), - _keys(new unsigned int[128]),_released_keys(new unsigned int[128]), - _window_x(0),_window_y(0),_mouse_x(-1),_mouse_y(-1),_wheel(0), - _is_closed(true),_is_resized(false),_is_moved(false),_is_event(false) { - assign(disp); - } - -#if cimg_display==0 - - static void _no_display_exception() { - throw CImgDisplayException("CImgDisplay(): No display available."); - } - - //! Destructor - Empty constructor \inplace. - /** - \note Replace the current instance by an empty display. - **/ - CImgDisplay& assign() { - return flush(); - } - - //! Construct a display with specified dimensions \inplace. - /** - **/ - CImgDisplay& assign(const unsigned int width, const unsigned int height, - const char *const title=0, const unsigned int normalization=3, - const bool is_fullscreen=false, const bool is_closed=false) { - cimg::unused(width,height,title,normalization,is_fullscreen,is_closed); - _no_display_exception(); - return assign(); - } - - //! Construct a display from an image \inplace. - /** - **/ - template - CImgDisplay& assign(const CImg& img, - const char *const title=0, const unsigned int normalization=3, - const bool is_fullscreen=false, const bool is_closed=false) { - _no_display_exception(); - return assign(img._width,img._height,title,normalization,is_fullscreen,is_closed); - } - - //! Construct a display from an image list \inplace. - /** - **/ - template - CImgDisplay& assign(const CImgList& list, - const char *const title=0, const unsigned int normalization=3, - const bool is_fullscreen=false, const bool is_closed=false) { - _no_display_exception(); - return assign(list._width,list._width,title,normalization,is_fullscreen,is_closed); - } - - //! Construct a display as a copy of another one \inplace. - /** - **/ - CImgDisplay& assign(const CImgDisplay &disp) { - _no_display_exception(); - return assign(disp._width,disp._height); - } - -#endif - - //! Return a reference to an empty display. - /** - \note Can be useful for writing function prototypes where one of the argument (of type CImgDisplay&) - must have a default value. - \par Example - \code - void foo(CImgDisplay& disp=CImgDisplay::empty()); - \endcode - **/ - static CImgDisplay& empty() { - static CImgDisplay _empty; - return _empty.assign(); - } - - //! Return a reference to an empty display \const. - static const CImgDisplay& const_empty() { - static const CImgDisplay _empty; - return _empty; - } - -#define cimg_fitscreen(dx,dy,dz) CImgDisplay::_fitscreen(dx,dy,dz,128,-85,false), \ - CImgDisplay::_fitscreen(dx,dy,dz,128,-85,true) - static unsigned int _fitscreen(const unsigned int dx, const unsigned int dy, const unsigned int dz, - const int dmin, const int dmax,const bool return_y) { - const unsigned int _nw = dx + (dz>1?dz:0), _nh = dy + (dz>1?dz:0); - unsigned int nw = _nw?_nw:1, nh = _nh?_nh:1; - const unsigned int - sw = (unsigned int)CImgDisplay::screen_width(), - sh = (unsigned int)CImgDisplay::screen_height(), - mw = dmin<0?(unsigned int)(sw*-dmin/100):(unsigned int)dmin, - mh = dmin<0?(unsigned int)(sh*-dmin/100):(unsigned int)dmin, - Mw = dmax<0?(unsigned int)(sw*-dmax/100):(unsigned int)dmax, - Mh = dmax<0?(unsigned int)(sh*-dmax/100):(unsigned int)dmax; - if (nwMw) { nh = nh*Mw/nw; nh+=(nh==0); nw = Mw; } - if (nh>Mh) { nw = nw*Mh/nh; nw+=(nw==0); nh = Mh; } - if (nwdisp = img is equivalent to disp.display(img). - **/ - template - CImgDisplay& operator=(const CImg& img) { - return display(img); - } - - //! Display list of images on associated window. - /** - \note disp = list is equivalent to disp.display(list). - **/ - template - CImgDisplay& operator=(const CImgList& list) { - return display(list); - } - - //! Construct a display as a copy of another one \inplace. - /** - \note Equivalent to assign(const CImgDisplay&). - **/ - CImgDisplay& operator=(const CImgDisplay& disp) { - return assign(disp); - } - - //! Return \c false if display is empty, \c true otherwise. - /** - \note if (disp) { ... } is equivalent to if (!disp.is_empty()) { ... }. - **/ - operator bool() const { - return !is_empty(); - } - - //@} - //------------------------------------------ - // - //! \name Instance Checking - //@{ - //------------------------------------------ - - //! Return \c true if display is empty, \c false otherwise. - /** - **/ - bool is_empty() const { - return !(_width && _height); - } - - //! Return \c true if display is closed (i.e. not visible on the screen), \c false otherwise. - /** - \note - - When a user physically closes the associated window, the display is set to closed. - - A closed display is not destroyed. Its associated window can be show again on the screen using show(). - **/ - bool is_closed() const { - return _is_closed; - } - - //! Return \c true if associated window has been resized on the screen, \c false otherwise. - /** - **/ - bool is_resized() const { - return _is_resized; - } - - //! Return \c true if associated window has been moved on the screen, \c false otherwise. - /** - **/ - bool is_moved() const { - return _is_moved; - } - - //! Return \c true if any event has occured on the associated window, \c false otherwise. - /** - **/ - bool is_event() const { - return _is_event; - } - - //! Return \c true if current display is in fullscreen mode, \c false otherwise. - /** - **/ - bool is_fullscreen() const { - return _is_fullscreen; - } - - //! Return \c true if any key is being pressed on the associated window, \c false otherwise. - /** - \note The methods below do the same only for specific keys. - **/ - bool is_key() const { - return _is_keyESC || _is_keyF1 || _is_keyF2 || _is_keyF3 || - _is_keyF4 || _is_keyF5 || _is_keyF6 || _is_keyF7 || - _is_keyF8 || _is_keyF9 || _is_keyF10 || _is_keyF11 || - _is_keyF12 || _is_keyPAUSE || _is_key1 || _is_key2 || - _is_key3 || _is_key4 || _is_key5 || _is_key6 || - _is_key7 || _is_key8 || _is_key9 || _is_key0 || - _is_keyBACKSPACE || _is_keyINSERT || _is_keyHOME || - _is_keyPAGEUP || _is_keyTAB || _is_keyQ || _is_keyW || - _is_keyE || _is_keyR || _is_keyT || _is_keyY || - _is_keyU || _is_keyI || _is_keyO || _is_keyP || - _is_keyDELETE || _is_keyEND || _is_keyPAGEDOWN || - _is_keyCAPSLOCK || _is_keyA || _is_keyS || _is_keyD || - _is_keyF || _is_keyG || _is_keyH || _is_keyJ || - _is_keyK || _is_keyL || _is_keyENTER || - _is_keySHIFTLEFT || _is_keyZ || _is_keyX || _is_keyC || - _is_keyV || _is_keyB || _is_keyN || _is_keyM || - _is_keySHIFTRIGHT || _is_keyARROWUP || _is_keyCTRLLEFT || - _is_keyAPPLEFT || _is_keyALT || _is_keySPACE || _is_keyALTGR || - _is_keyAPPRIGHT || _is_keyMENU || _is_keyCTRLRIGHT || - _is_keyARROWLEFT || _is_keyARROWDOWN || _is_keyARROWRIGHT || - _is_keyPAD0 || _is_keyPAD1 || _is_keyPAD2 || - _is_keyPAD3 || _is_keyPAD4 || _is_keyPAD5 || - _is_keyPAD6 || _is_keyPAD7 || _is_keyPAD8 || - _is_keyPAD9 || _is_keyPADADD || _is_keyPADSUB || - _is_keyPADMUL || _is_keyPADDIV; - } - - //! Return \c true if key specified by given keycode is being pressed on the associated window, \c false otherwise. - /** - \param keycode Keycode to test. - \note Keycode constants are defined in the cimg namespace and are architecture-dependent. Use them to ensure - your code stay portable (see cimg::keyESC). - \par Example - \code - CImgDisplay disp(400,400); - while (!disp.is_closed()) { - if (disp.key(cimg::keyTAB)) { ... } // Equivalent to 'if (disp.is_keyTAB())'. - disp.wait(); - } - \endcode - **/ - bool is_key(const unsigned int keycode) const { -#define _cimg_iskey_test(k) if (keycode==cimg::key##k) return _is_key##k; - _cimg_iskey_test(ESC); _cimg_iskey_test(F1); _cimg_iskey_test(F2); _cimg_iskey_test(F3); - _cimg_iskey_test(F4); _cimg_iskey_test(F5); _cimg_iskey_test(F6); _cimg_iskey_test(F7); - _cimg_iskey_test(F8); _cimg_iskey_test(F9); _cimg_iskey_test(F10); _cimg_iskey_test(F11); - _cimg_iskey_test(F12); _cimg_iskey_test(PAUSE); _cimg_iskey_test(1); _cimg_iskey_test(2); - _cimg_iskey_test(3); _cimg_iskey_test(4); _cimg_iskey_test(5); _cimg_iskey_test(6); - _cimg_iskey_test(7); _cimg_iskey_test(8); _cimg_iskey_test(9); _cimg_iskey_test(0); - _cimg_iskey_test(BACKSPACE); _cimg_iskey_test(INSERT); _cimg_iskey_test(HOME); - _cimg_iskey_test(PAGEUP); _cimg_iskey_test(TAB); _cimg_iskey_test(Q); _cimg_iskey_test(W); - _cimg_iskey_test(E); _cimg_iskey_test(R); _cimg_iskey_test(T); _cimg_iskey_test(Y); - _cimg_iskey_test(U); _cimg_iskey_test(I); _cimg_iskey_test(O); _cimg_iskey_test(P); - _cimg_iskey_test(DELETE); _cimg_iskey_test(END); _cimg_iskey_test(PAGEDOWN); - _cimg_iskey_test(CAPSLOCK); _cimg_iskey_test(A); _cimg_iskey_test(S); _cimg_iskey_test(D); - _cimg_iskey_test(F); _cimg_iskey_test(G); _cimg_iskey_test(H); _cimg_iskey_test(J); - _cimg_iskey_test(K); _cimg_iskey_test(L); _cimg_iskey_test(ENTER); - _cimg_iskey_test(SHIFTLEFT); _cimg_iskey_test(Z); _cimg_iskey_test(X); _cimg_iskey_test(C); - _cimg_iskey_test(V); _cimg_iskey_test(B); _cimg_iskey_test(N); _cimg_iskey_test(M); - _cimg_iskey_test(SHIFTRIGHT); _cimg_iskey_test(ARROWUP); _cimg_iskey_test(CTRLLEFT); - _cimg_iskey_test(APPLEFT); _cimg_iskey_test(ALT); _cimg_iskey_test(SPACE); _cimg_iskey_test(ALTGR); - _cimg_iskey_test(APPRIGHT); _cimg_iskey_test(MENU); _cimg_iskey_test(CTRLRIGHT); - _cimg_iskey_test(ARROWLEFT); _cimg_iskey_test(ARROWDOWN); _cimg_iskey_test(ARROWRIGHT); - _cimg_iskey_test(PAD0); _cimg_iskey_test(PAD1); _cimg_iskey_test(PAD2); - _cimg_iskey_test(PAD3); _cimg_iskey_test(PAD4); _cimg_iskey_test(PAD5); - _cimg_iskey_test(PAD6); _cimg_iskey_test(PAD7); _cimg_iskey_test(PAD8); - _cimg_iskey_test(PAD9); _cimg_iskey_test(PADADD); _cimg_iskey_test(PADSUB); - _cimg_iskey_test(PADMUL); _cimg_iskey_test(PADDIV); - return false; - } - - //! Return \c true if key specified by given keycode is being pressed on the associated window, \c false otherwise. - /** - \param keycode C-string containing the keycode label of the key to test. - \note Use it when the key you want to test can be dynamically set by the user. - \par Example - \code - CImgDisplay disp(400,400); - const char *const keycode = "TAB"; - while (!disp.is_closed()) { - if (disp.is_key(keycode)) { ... } // Equivalent to 'if (disp.is_keyTAB())'. - disp.wait(); - } - \endcode - **/ - bool& is_key(const char *const keycode) { - static bool f = false; - f = false; -#define _cimg_iskey_test2(k) if (!cimg::strcasecmp(keycode,#k)) return _is_key##k; - _cimg_iskey_test2(ESC); _cimg_iskey_test2(F1); _cimg_iskey_test2(F2); _cimg_iskey_test2(F3); - _cimg_iskey_test2(F4); _cimg_iskey_test2(F5); _cimg_iskey_test2(F6); _cimg_iskey_test2(F7); - _cimg_iskey_test2(F8); _cimg_iskey_test2(F9); _cimg_iskey_test2(F10); _cimg_iskey_test2(F11); - _cimg_iskey_test2(F12); _cimg_iskey_test2(PAUSE); _cimg_iskey_test2(1); _cimg_iskey_test2(2); - _cimg_iskey_test2(3); _cimg_iskey_test2(4); _cimg_iskey_test2(5); _cimg_iskey_test2(6); - _cimg_iskey_test2(7); _cimg_iskey_test2(8); _cimg_iskey_test2(9); _cimg_iskey_test2(0); - _cimg_iskey_test2(BACKSPACE); _cimg_iskey_test2(INSERT); _cimg_iskey_test2(HOME); - _cimg_iskey_test2(PAGEUP); _cimg_iskey_test2(TAB); _cimg_iskey_test2(Q); _cimg_iskey_test2(W); - _cimg_iskey_test2(E); _cimg_iskey_test2(R); _cimg_iskey_test2(T); _cimg_iskey_test2(Y); - _cimg_iskey_test2(U); _cimg_iskey_test2(I); _cimg_iskey_test2(O); _cimg_iskey_test2(P); - _cimg_iskey_test2(DELETE); _cimg_iskey_test2(END); _cimg_iskey_test2(PAGEDOWN); - _cimg_iskey_test2(CAPSLOCK); _cimg_iskey_test2(A); _cimg_iskey_test2(S); _cimg_iskey_test2(D); - _cimg_iskey_test2(F); _cimg_iskey_test2(G); _cimg_iskey_test2(H); _cimg_iskey_test2(J); - _cimg_iskey_test2(K); _cimg_iskey_test2(L); _cimg_iskey_test2(ENTER); - _cimg_iskey_test2(SHIFTLEFT); _cimg_iskey_test2(Z); _cimg_iskey_test2(X); _cimg_iskey_test2(C); - _cimg_iskey_test2(V); _cimg_iskey_test2(B); _cimg_iskey_test2(N); _cimg_iskey_test2(M); - _cimg_iskey_test2(SHIFTRIGHT); _cimg_iskey_test2(ARROWUP); _cimg_iskey_test2(CTRLLEFT); - _cimg_iskey_test2(APPLEFT); _cimg_iskey_test2(ALT); _cimg_iskey_test2(SPACE); _cimg_iskey_test2(ALTGR); - _cimg_iskey_test2(APPRIGHT); _cimg_iskey_test2(MENU); _cimg_iskey_test2(CTRLRIGHT); - _cimg_iskey_test2(ARROWLEFT); _cimg_iskey_test2(ARROWDOWN); _cimg_iskey_test2(ARROWRIGHT); - _cimg_iskey_test2(PAD0); _cimg_iskey_test2(PAD1); _cimg_iskey_test2(PAD2); - _cimg_iskey_test2(PAD3); _cimg_iskey_test2(PAD4); _cimg_iskey_test2(PAD5); - _cimg_iskey_test2(PAD6); _cimg_iskey_test2(PAD7); _cimg_iskey_test2(PAD8); - _cimg_iskey_test2(PAD9); _cimg_iskey_test2(PADADD); _cimg_iskey_test2(PADSUB); - _cimg_iskey_test2(PADMUL); _cimg_iskey_test2(PADDIV); - return f; - } - - //! Return \c true if specified key sequence has been typed on the associated window, \c false otherwise. - /** - \param keycodes_sequence Buffer of keycodes to test. - \param length Number of keys in the \c keycodes_sequence buffer. - \param remove_sequence Tells if the key sequence must be removed from the key history, if found. - \note Keycode constants are defined in the cimg namespace and are architecture-dependent. Use them to ensure - your code stay portable (see cimg::keyESC). - \par Example - \code - CImgDisplay disp(400,400); - const unsigned int key_seq[] = { cimg::keyCTRLLEFT, cimg::keyD }; - while (!disp.is_closed()) { - if (disp.is_key_sequence(key_seq,2)) { ... } // Test for the 'CTRL+D' keyboard event. - disp.wait(); - } - \endcode - **/ - bool is_key_sequence(const unsigned int *const keycodes_sequence, const unsigned int length, - const bool remove_sequence=false) { - if (keycodes_sequence && length) { - const unsigned int - *const ps_end = keycodes_sequence + length - 1, - *const pk_end = (unsigned int*)_keys + 1 + 128 - length, - k = *ps_end; - for (unsigned int *pk = (unsigned int*)_keys; pk[0,255]. - If the range of values of the data to display is different, a normalization may be required for displaying - the data in a correct way. The normalization type can be one of: - - \c 0: Value normalization is disabled. It is then assumed that all input data to be displayed by the - CImgDisplay instance have values in range [0,255]. - - \c 1: Value normalization is always performed (this is the default behavior). - Before displaying an input image, its values will be (virtually) stretched - in range [0,255], so that the contrast of the displayed pixels will be maximum. - Use this mode for images whose minimum and maximum values are not prescribed to known values - (e.g. float-valued images). - Note that when normalized versions of images are computed for display purposes, the actual values of these - images are not modified. - - \c 2: Value normalization is performed once (on the first image display), then the same normalization - coefficients are kept for next displayed frames. - - \c 3: Value normalization depends on the pixel type of the data to display. For integer pixel types, - the normalization is done regarding the minimum/maximum values of the type (no normalization occurs then - for unsigned char). - For float-valued pixel types, the normalization is done regarding the minimum/maximum value of the image - data instead. - **/ - unsigned int normalization() const { - return _normalization; - } - - //! Return title of the associated window as a C-string. - /** - \note Window title may be not visible, depending on the used window manager or if the current display is - in fullscreen mode. - **/ - const char *title() const { - return _title?_title:""; - } - - //! Return width of the associated window. - /** - \note The width of the display (i.e. the width of the pixel data buffer associated to the CImgDisplay instance) - may be different from the actual width of the associated window. - **/ - int window_width() const { - return (int)_window_width; - } - - //! Return height of the associated window. - /** - \note The height of the display (i.e. the height of the pixel data buffer associated to the CImgDisplay instance) - may be different from the actual height of the associated window. - **/ - int window_height() const { - return (int)_window_height; - } - - //! Return X-coordinate of the associated window. - /** - \note The returned coordinate corresponds to the location of the upper-left corner of the associated window. - **/ - int window_x() const { - return _window_x; - } - - //! Return Y-coordinate of the associated window. - /** - \note The returned coordinate corresponds to the location of the upper-left corner of the associated window. - **/ - int window_y() const { - return _window_y; - } - - //! Return X-coordinate of the mouse pointer. - /** - \note - - If the mouse pointer is outside window area, \c -1 is returned. - - Otherwise, the returned value is in the range [0,width()-1]. - **/ - int mouse_x() const { - return _mouse_x; - } - - //! Return Y-coordinate of the mouse pointer. - /** - \note - - If the mouse pointer is outside window area, \c -1 is returned. - - Otherwise, the returned value is in the range [0,height()-1]. - **/ - int mouse_y() const { - return _mouse_y; - } - - //! Return current state of the mouse buttons. - /** - \note Three mouse buttons can be managed. If one button is pressed, its corresponding bit in the returned - value is set: - - bit \c 0 (value \c 0x1): State of the left mouse button. - - bit \c 1 (value \c 0x2): State of the right mouse button. - - bit \c 2 (value \c 0x4): State of the middle mouse button. - - Several bits can be activated if more than one button are pressed at the same time. - \par Example - \code - CImgDisplay disp(400,400); - while (!disp.is_closed()) { - if (disp.button()&1) { // Left button clicked. - ... - } - if (disp.button()&2) { // Right button clicked. - ... - } - if (disp.button()&4) { // Middle button clicked. - ... - } - disp.wait(); - } - \endcode - **/ - unsigned int button() const { - return _button; - } - - //! Return current state of the mouse wheel. - /** - \note - - The returned value can be positive or negative depending on whether the mouse wheel has been scrolled - forward or backward. - - Scrolling the wheel forward add \c 1 to the wheel value. - - Scrolling the wheel backward substract \c 1 to the wheel value. - - The returned value cumulates the number of forward of backward scrolls since the creation of the display, - or since the last reset of the wheel value (using set_wheel()). It is strongly recommended to quickly reset - the wheel counter when an action has been performed regarding the current wheel value. - Otherwise, the returned wheel value may be for instance \c 0 despite the fact that many scrolls have been done - (as many in forward as in backward directions). - \par Example - \code - CImgDisplay disp(400,400); - while (!disp.is_closed()) { - if (disp.wheel()) { - int counter = disp.wheel(); // Read the state of the mouse wheel. - ... // Do what you want with 'counter'. - disp.set_wheel(); // Reset the wheel value to 0. - } - disp.wait(); - } - \endcode - **/ - int wheel() const { - return _wheel; - } - - //! Return one entry from the pressed keys history. - /** - \param pos Indice to read from the pressed keys history (indice \c 0 corresponds to latest entry). - \return Keycode of a pressed key or \c 0 for a released key. - \note - - Each CImgDisplay stores a history of the pressed keys in a buffer of size \c 128. When a new key is pressed, - its keycode is stored in the pressed keys history. When a key is released, \c 0 is put instead. - This means that up to the 64 last pressed keys may be read from the pressed keys history. - When a new value is stored, the pressed keys history is shifted so that the latest entry is always - stored at position \c 0. - - Keycode constants are defined in the cimg namespace and are architecture-dependent. Use them to ensure - your code stay portable (see cimg::keyESC). - **/ - unsigned int key(const unsigned int pos=0) const { - return pos<128?_keys[pos]:0; - } - - //! Return one entry from the released keys history. - /** - \param pos Indice to read from the released keys history (indice \c 0 corresponds to latest entry). - \return Keycode of a released key or \c 0 for a pressed key. - \note - - Each CImgDisplay stores a history of the released keys in a buffer of size \c 128. When a new key is released, - its keycode is stored in the pressed keys history. When a key is pressed, \c 0 is put instead. - This means that up to the 64 last released keys may be read from the released keys history. - When a new value is stored, the released keys history is shifted so that the latest entry is always - stored at position \c 0. - - Keycode constants are defined in the cimg namespace and are architecture-dependent. Use them to ensure - your code stay portable (see cimg::keyESC). - **/ - unsigned int released_key(const unsigned int pos=0) const { - return pos<128?_released_keys[pos]:0; - } - - //! Return keycode corresponding to the specified string. - /** - \note Keycode constants are defined in the cimg namespace and are architecture-dependent. Use them to ensure - your code stay portable (see cimg::keyESC). - \par Example - \code - const unsigned int keyTAB = CImgDisplay::keycode("TAB"); // Return cimg::keyTAB. - \endcode - **/ - static unsigned int keycode(const char *const keycode) { -#define _cimg_keycode(k) if (!cimg::strcasecmp(keycode,#k)) return cimg::key##k; - _cimg_keycode(ESC); _cimg_keycode(F1); _cimg_keycode(F2); _cimg_keycode(F3); - _cimg_keycode(F4); _cimg_keycode(F5); _cimg_keycode(F6); _cimg_keycode(F7); - _cimg_keycode(F8); _cimg_keycode(F9); _cimg_keycode(F10); _cimg_keycode(F11); - _cimg_keycode(F12); _cimg_keycode(PAUSE); _cimg_keycode(1); _cimg_keycode(2); - _cimg_keycode(3); _cimg_keycode(4); _cimg_keycode(5); _cimg_keycode(6); - _cimg_keycode(7); _cimg_keycode(8); _cimg_keycode(9); _cimg_keycode(0); - _cimg_keycode(BACKSPACE); _cimg_keycode(INSERT); _cimg_keycode(HOME); - _cimg_keycode(PAGEUP); _cimg_keycode(TAB); _cimg_keycode(Q); _cimg_keycode(W); - _cimg_keycode(E); _cimg_keycode(R); _cimg_keycode(T); _cimg_keycode(Y); - _cimg_keycode(U); _cimg_keycode(I); _cimg_keycode(O); _cimg_keycode(P); - _cimg_keycode(DELETE); _cimg_keycode(END); _cimg_keycode(PAGEDOWN); - _cimg_keycode(CAPSLOCK); _cimg_keycode(A); _cimg_keycode(S); _cimg_keycode(D); - _cimg_keycode(F); _cimg_keycode(G); _cimg_keycode(H); _cimg_keycode(J); - _cimg_keycode(K); _cimg_keycode(L); _cimg_keycode(ENTER); - _cimg_keycode(SHIFTLEFT); _cimg_keycode(Z); _cimg_keycode(X); _cimg_keycode(C); - _cimg_keycode(V); _cimg_keycode(B); _cimg_keycode(N); _cimg_keycode(M); - _cimg_keycode(SHIFTRIGHT); _cimg_keycode(ARROWUP); _cimg_keycode(CTRLLEFT); - _cimg_keycode(APPLEFT); _cimg_keycode(ALT); _cimg_keycode(SPACE); _cimg_keycode(ALTGR); - _cimg_keycode(APPRIGHT); _cimg_keycode(MENU); _cimg_keycode(CTRLRIGHT); - _cimg_keycode(ARROWLEFT); _cimg_keycode(ARROWDOWN); _cimg_keycode(ARROWRIGHT); - _cimg_keycode(PAD0); _cimg_keycode(PAD1); _cimg_keycode(PAD2); - _cimg_keycode(PAD3); _cimg_keycode(PAD4); _cimg_keycode(PAD5); - _cimg_keycode(PAD6); _cimg_keycode(PAD7); _cimg_keycode(PAD8); - _cimg_keycode(PAD9); _cimg_keycode(PADADD); _cimg_keycode(PADSUB); - _cimg_keycode(PADMUL); _cimg_keycode(PADDIV); - return 0; - } - - //! Return the current refresh rate, in frames per second. - /** - \note Returns a significant value when the current instance is used to display successive frames. - It measures the delay between successive calls to frames_per_second(). - **/ - float frames_per_second() { - if (!_fps_timer) _fps_timer = cimg::time(); - const float delta = (cimg::time() - _fps_timer)/1000.0f; - ++_fps_frames; - if (delta>=1) { - _fps_fps = _fps_frames/delta; - _fps_frames = 0; - _fps_timer = cimg::time(); - } - return _fps_fps; - } - - //@} - //--------------------------------------- - // - //! \name Window Manipulation - //@{ - //--------------------------------------- - -#if cimg_display==0 - - //! Display image on associated window. - /** - \param img Input image to display. - \note This method returns immediately. - **/ - template - CImgDisplay& display(const CImg& img) { - return assign(img); - } - -#endif - - //! Display list of images on associated window. - /** - \param list List of images to display. - \param axis Axis used to append the images along, for the visualization (can be \c x, \c y, \c z or \c c). - \param align Relative position of aligned images when displaying lists with images of different sizes - (\c 0 for upper-left, \c 0.5 for centering and \c 1 for lower-right). - \note This method returns immediately. - **/ - template - CImgDisplay& display(const CImgList& list, const char axis='x', const float align=0) { - if (list._width==1) { - const CImg& img = list[0]; - if (img._depth==1 && (img._spectrum==1 || img._spectrum>=3) && _normalization!=1) return display(img); - } - CImgList::ucharT> visu(list._width); - unsigned int dims = 0; - cimglist_for(list,l) { - const CImg& img = list._data[l]; - img.__get_select(*this,_normalization,(img._width - 1)/2,(img._height - 1)/2, - (img._depth - 1)/2).move_to(visu[l]); - dims = cimg::max(dims,visu[l]._spectrum); - } - cimglist_for(list,l) if (visu[l]._spectrumimg.width() become equal, as well as height() and - img.height(). - - The associated window is also resized to specified dimensions. - **/ - template - CImgDisplay& resize(const CImg& img, const bool force_redraw=true) { - return resize(img._width,img._height,force_redraw); - } - - //! Resize display to the size of another CImgDisplay instance. - /** - \param disp Input display to take size from. - \param force_redraw Tells if the previous window content must be resized and updated as well. - \note - - Calling this method ensures that width() and disp.width() become equal, as well as height() and - disp.height(). - - The associated window is also resized to specified dimensions. - **/ - CImgDisplay& resize(const CImgDisplay& disp, const bool force_redraw=true) { - return resize(disp.width(),disp.height(),force_redraw); - } - - // [internal] Render pixel buffer with size (wd,hd) from source buffer of size (ws,hs). - template - static void _render_resize(const T *ptrs, const unsigned int ws, const unsigned int hs, - t *ptrd, const unsigned int wd, const unsigned int hd) { - unsigned int *const offx = new unsigned int[wd], *const offy = new unsigned int[hd + 1], *poffx, *poffy; - float s, curr, old; - s = (float)ws/wd; - poffx = offx; curr = 0; for (unsigned int x = 0; xstd::printf(). - \warning As the first argument is a format string, it is highly recommended to write - \code - disp.set_title("%s",window_title); - \endcode - instead of - \code - disp.set_title(window_title); - \endcode - if \c window_title can be arbitrary, to prevent nasty memory access. - **/ - CImgDisplay& set_title(const char *const format, ...) { - return assign(0,0,format); - } - -#endif - - //! Enable or disable fullscreen mode. - /** - \param is_fullscreen Tells is the fullscreen mode must be activated or not. - \param force_redraw Tells if the previous window content must be displayed as well. - \note - - When the fullscreen mode is enabled, the associated window fills the entire screen but the size of the - current display is not modified. - - The screen resolution may be switched to fit the associated window size and ensure it appears the largest - as possible. - For X-Window (X11) users, the configuration flag \c cimg_use_xrandr has to be set to allow the screen - resolution change (requires the X11 extensions to be enabled). - **/ - CImgDisplay& set_fullscreen(const bool is_fullscreen, const bool force_redraw=true) { - if (is_empty() || _is_fullscreen==is_fullscreen) return *this; - return toggle_fullscreen(force_redraw); - } - -#if cimg_display==0 - - //! Toggle fullscreen mode. - /** - \param force_redraw Tells if the previous window content must be displayed as well. - \note Enable fullscreen mode if it was not enabled, and disable it otherwise. - **/ - CImgDisplay& toggle_fullscreen(const bool force_redraw=true) { - return assign(_width,_height,0,3,force_redraw); - } - - //! Show mouse pointer. - /** - \note Depending on the window manager behavior, this method may not succeed - (no exceptions are thrown nevertheless). - **/ - CImgDisplay& show_mouse() { - return assign(); - } - - //! Hide mouse pointer. - /** - \note Depending on the window manager behavior, this method may not succeed - (no exceptions are thrown nevertheless). - **/ - CImgDisplay& hide_mouse() { - return assign(); - } - - //! Move mouse pointer to a specified location. - /** - \note Depending on the window manager behavior, this method may not succeed - (no exceptions are thrown nevertheless). - **/ - CImgDisplay& set_mouse(const int pos_x, const int pos_y) { - return assign(pos_x,pos_y); - } - -#endif - - //! Simulate a mouse button release event. - /** - \note All mouse buttons are considered released at the same time. - **/ - CImgDisplay& set_button() { - _button = 0; - _is_event = true; -#if cimg_display==1 - pthread_cond_broadcast(&cimg::X11_attr().wait_event); -#elif cimg_display==2 - SetEvent(cimg::Win32_attr().wait_event); -#endif - return *this; - } - - //! Simulate a mouse button press or release event. - /** - \param button Buttons event code, where each button is associated to a single bit. - \param is_pressed Tells if the mouse button is considered as pressed or released. - **/ - CImgDisplay& set_button(const unsigned int button, const bool is_pressed=true) { - const unsigned int buttoncode = button==1U?1U:button==2U?2U:button==3U?4U:0U; - if (is_pressed) _button |= buttoncode; else _button &= ~buttoncode; - _is_event = buttoncode?true:false; - if (buttoncode) { -#if cimg_display==1 - pthread_cond_broadcast(&cimg::X11_attr().wait_event); -#elif cimg_display==2 - SetEvent(cimg::Win32_attr().wait_event); -#endif - } - return *this; - } - - //! Flush all mouse wheel events. - /** - \note Make wheel() to return \c 0, if called afterwards. - **/ - CImgDisplay& set_wheel() { - _wheel = 0; - _is_event = true; -#if cimg_display==1 - pthread_cond_broadcast(&cimg::X11_attr().wait_event); -#elif cimg_display==2 - SetEvent(cimg::Win32_attr().wait_event); -#endif - return *this; - } - - //! Simulate a wheel event. - /** - \param amplitude Amplitude of the wheel scrolling to simulate. - \note Make wheel() to return \c amplitude, if called afterwards. - **/ - CImgDisplay& set_wheel(const int amplitude) { - _wheel+=amplitude; - _is_event = amplitude?true:false; - if (amplitude) { -#if cimg_display==1 - pthread_cond_broadcast(&cimg::X11_attr().wait_event); -#elif cimg_display==2 - SetEvent(cimg::Win32_attr().wait_event); -#endif - } - return *this; - } - - //! Flush all key events. - /** - \note Make key() to return \c 0, if called afterwards. - **/ - CImgDisplay& set_key() { - std::memset((void*)_keys,0,128*sizeof(unsigned int)); - std::memset((void*)_released_keys,0,128*sizeof(unsigned int)); - _is_keyESC = _is_keyF1 = _is_keyF2 = _is_keyF3 = _is_keyF4 = _is_keyF5 = _is_keyF6 = _is_keyF7 = _is_keyF8 = - _is_keyF9 = _is_keyF10 = _is_keyF11 = _is_keyF12 = _is_keyPAUSE = _is_key1 = _is_key2 = _is_key3 = _is_key4 = - _is_key5 = _is_key6 = _is_key7 = _is_key8 = _is_key9 = _is_key0 = _is_keyBACKSPACE = _is_keyINSERT = - _is_keyHOME = _is_keyPAGEUP = _is_keyTAB = _is_keyQ = _is_keyW = _is_keyE = _is_keyR = _is_keyT = _is_keyY = - _is_keyU = _is_keyI = _is_keyO = _is_keyP = _is_keyDELETE = _is_keyEND = _is_keyPAGEDOWN = _is_keyCAPSLOCK = - _is_keyA = _is_keyS = _is_keyD = _is_keyF = _is_keyG = _is_keyH = _is_keyJ = _is_keyK = _is_keyL = - _is_keyENTER = _is_keySHIFTLEFT = _is_keyZ = _is_keyX = _is_keyC = _is_keyV = _is_keyB = _is_keyN = - _is_keyM = _is_keySHIFTRIGHT = _is_keyARROWUP = _is_keyCTRLLEFT = _is_keyAPPLEFT = _is_keyALT = _is_keySPACE = - _is_keyALTGR = _is_keyAPPRIGHT = _is_keyMENU = _is_keyCTRLRIGHT = _is_keyARROWLEFT = _is_keyARROWDOWN = - _is_keyARROWRIGHT = _is_keyPAD0 = _is_keyPAD1 = _is_keyPAD2 = _is_keyPAD3 = _is_keyPAD4 = _is_keyPAD5 = - _is_keyPAD6 = _is_keyPAD7 = _is_keyPAD8 = _is_keyPAD9 = _is_keyPADADD = _is_keyPADSUB = _is_keyPADMUL = - _is_keyPADDIV = false; - _is_event = true; -#if cimg_display==1 - pthread_cond_broadcast(&cimg::X11_attr().wait_event); -#elif cimg_display==2 - SetEvent(cimg::Win32_attr().wait_event); -#endif - return *this; - } - - //! Simulate a keyboard press/release event. - /** - \param keycode Keycode of the associated key. - \param is_pressed Tells if the key is considered as pressed or released. - \note Keycode constants are defined in the cimg namespace and are architecture-dependent. Use them to ensure - your code stay portable (see cimg::keyESC). - **/ - CImgDisplay& set_key(const unsigned int keycode, const bool is_pressed=true) { -#define _cimg_set_key(k) if (keycode==cimg::key##k) _is_key##k = is_pressed; - _cimg_set_key(ESC); _cimg_set_key(F1); _cimg_set_key(F2); _cimg_set_key(F3); - _cimg_set_key(F4); _cimg_set_key(F5); _cimg_set_key(F6); _cimg_set_key(F7); - _cimg_set_key(F8); _cimg_set_key(F9); _cimg_set_key(F10); _cimg_set_key(F11); - _cimg_set_key(F12); _cimg_set_key(PAUSE); _cimg_set_key(1); _cimg_set_key(2); - _cimg_set_key(3); _cimg_set_key(4); _cimg_set_key(5); _cimg_set_key(6); - _cimg_set_key(7); _cimg_set_key(8); _cimg_set_key(9); _cimg_set_key(0); - _cimg_set_key(BACKSPACE); _cimg_set_key(INSERT); _cimg_set_key(HOME); - _cimg_set_key(PAGEUP); _cimg_set_key(TAB); _cimg_set_key(Q); _cimg_set_key(W); - _cimg_set_key(E); _cimg_set_key(R); _cimg_set_key(T); _cimg_set_key(Y); - _cimg_set_key(U); _cimg_set_key(I); _cimg_set_key(O); _cimg_set_key(P); - _cimg_set_key(DELETE); _cimg_set_key(END); _cimg_set_key(PAGEDOWN); - _cimg_set_key(CAPSLOCK); _cimg_set_key(A); _cimg_set_key(S); _cimg_set_key(D); - _cimg_set_key(F); _cimg_set_key(G); _cimg_set_key(H); _cimg_set_key(J); - _cimg_set_key(K); _cimg_set_key(L); _cimg_set_key(ENTER); - _cimg_set_key(SHIFTLEFT); _cimg_set_key(Z); _cimg_set_key(X); _cimg_set_key(C); - _cimg_set_key(V); _cimg_set_key(B); _cimg_set_key(N); _cimg_set_key(M); - _cimg_set_key(SHIFTRIGHT); _cimg_set_key(ARROWUP); _cimg_set_key(CTRLLEFT); - _cimg_set_key(APPLEFT); _cimg_set_key(ALT); _cimg_set_key(SPACE); _cimg_set_key(ALTGR); - _cimg_set_key(APPRIGHT); _cimg_set_key(MENU); _cimg_set_key(CTRLRIGHT); - _cimg_set_key(ARROWLEFT); _cimg_set_key(ARROWDOWN); _cimg_set_key(ARROWRIGHT); - _cimg_set_key(PAD0); _cimg_set_key(PAD1); _cimg_set_key(PAD2); - _cimg_set_key(PAD3); _cimg_set_key(PAD4); _cimg_set_key(PAD5); - _cimg_set_key(PAD6); _cimg_set_key(PAD7); _cimg_set_key(PAD8); - _cimg_set_key(PAD9); _cimg_set_key(PADADD); _cimg_set_key(PADSUB); - _cimg_set_key(PADMUL); _cimg_set_key(PADDIV); - if (is_pressed) { - if (*_keys) - std::memmove((void*)(_keys + 1),(void*)_keys,127*sizeof(unsigned int)); - *_keys = keycode; - if (*_released_keys) { - std::memmove((void*)(_released_keys + 1),(void*)_released_keys,127*sizeof(unsigned int)); - *_released_keys = 0; - } - } else { - if (*_keys) { - std::memmove((void*)(_keys + 1),(void*)_keys,127*sizeof(unsigned int)); - *_keys = 0; - } - if (*_released_keys) - std::memmove((void*)(_released_keys + 1),(void*)_released_keys,127*sizeof(unsigned int)); - *_released_keys = keycode; - } - _is_event = keycode?true:false; - if (keycode) { -#if cimg_display==1 - pthread_cond_broadcast(&cimg::X11_attr().wait_event); -#elif cimg_display==2 - SetEvent(cimg::Win32_attr().wait_event); -#endif - } - return *this; - } - - //! Flush all display events. - /** - \note Remove all passed events from the current display. - **/ - CImgDisplay& flush() { - set_key().set_button().set_wheel(); - _is_resized = _is_moved = _is_event = false; - _fps_timer = _fps_frames = _timer = 0; - _fps_fps = 0; - return *this; - } - - //! Wait for any user event occuring on the current display. - CImgDisplay& wait() { - wait(*this); - return *this; - } - - //! Wait for a given number of milliseconds since the last call to wait(). - /** - \param milliseconds Number of milliseconds to wait for. - \note Similar to cimg::wait(). - **/ - CImgDisplay& wait(const unsigned int milliseconds) { - cimg::_wait(milliseconds,_timer); - return *this; - } - - //! Wait for any event occuring on the display \c disp1. - static void wait(CImgDisplay& disp1) { - disp1._is_event = false; - while (!disp1._is_closed && !disp1._is_event) wait_all(); - } - - //! Wait for any event occuring either on the display \c disp1 or \c disp2. - static void wait(CImgDisplay& disp1, CImgDisplay& disp2) { - disp1._is_event = disp2._is_event = false; - while ((!disp1._is_closed || !disp2._is_closed) && - !disp1._is_event && !disp2._is_event) wait_all(); - } - - //! Wait for any event occuring either on the display \c disp1, \c disp2 or \c disp3. - static void wait(CImgDisplay& disp1, CImgDisplay& disp2, CImgDisplay& disp3) { - disp1._is_event = disp2._is_event = disp3._is_event = false; - while ((!disp1._is_closed || !disp2._is_closed || !disp3._is_closed) && - !disp1._is_event && !disp2._is_event && !disp3._is_event) wait_all(); - } - - //! Wait for any event occuring either on the display \c disp1, \c disp2, \c disp3 or \c disp4. - static void wait(CImgDisplay& disp1, CImgDisplay& disp2, CImgDisplay& disp3, CImgDisplay& disp4) { - disp1._is_event = disp2._is_event = disp3._is_event = disp4._is_event = false; - while ((!disp1._is_closed || !disp2._is_closed || !disp3._is_closed || !disp4._is_closed) && - !disp1._is_event && !disp2._is_event && !disp3._is_event && !disp4._is_event) wait_all(); - } - - //! Wait for any event occuring either on the display \c disp1, \c disp2, \c disp3, \c disp4 or \c disp5. - static void wait(CImgDisplay& disp1, CImgDisplay& disp2, CImgDisplay& disp3, CImgDisplay& disp4, - CImgDisplay& disp5) { - disp1._is_event = disp2._is_event = disp3._is_event = disp4._is_event = disp5._is_event = false; - while ((!disp1._is_closed || !disp2._is_closed || !disp3._is_closed || !disp4._is_closed || !disp5._is_closed) && - !disp1._is_event && !disp2._is_event && !disp3._is_event && !disp4._is_event && !disp5._is_event) - wait_all(); - } - - //! Wait for any event occuring either on the display \c disp1, \c disp2, \c disp3, \c disp4, ... \c disp6. - static void wait(CImgDisplay& disp1, CImgDisplay& disp2, CImgDisplay& disp3, CImgDisplay& disp4, CImgDisplay& disp5, - CImgDisplay& disp6) { - disp1._is_event = disp2._is_event = disp3._is_event = disp4._is_event = disp5._is_event = - disp6._is_event = false; - while ((!disp1._is_closed || !disp2._is_closed || !disp3._is_closed || !disp4._is_closed || !disp5._is_closed || - !disp6._is_closed) && - !disp1._is_event && !disp2._is_event && !disp3._is_event && !disp4._is_event && !disp5._is_event && - !disp6._is_event) wait_all(); - } - - //! Wait for any event occuring either on the display \c disp1, \c disp2, \c disp3, \c disp4, ... \c disp7. - static void wait(CImgDisplay& disp1, CImgDisplay& disp2, CImgDisplay& disp3, CImgDisplay& disp4, CImgDisplay& disp5, - CImgDisplay& disp6, CImgDisplay& disp7) { - disp1._is_event = disp2._is_event = disp3._is_event = disp4._is_event = disp5._is_event = - disp6._is_event = disp7._is_event = false; - while ((!disp1._is_closed || !disp2._is_closed || !disp3._is_closed || !disp4._is_closed || !disp5._is_closed || - !disp6._is_closed || !disp7._is_closed) && - !disp1._is_event && !disp2._is_event && !disp3._is_event && !disp4._is_event && !disp5._is_event && - !disp6._is_event && !disp7._is_event) wait_all(); - } - - //! Wait for any event occuring either on the display \c disp1, \c disp2, \c disp3, \c disp4, ... \c disp8. - static void wait(CImgDisplay& disp1, CImgDisplay& disp2, CImgDisplay& disp3, CImgDisplay& disp4, CImgDisplay& disp5, - CImgDisplay& disp6, CImgDisplay& disp7, CImgDisplay& disp8) { - disp1._is_event = disp2._is_event = disp3._is_event = disp4._is_event = disp5._is_event = - disp6._is_event = disp7._is_event = disp8._is_event = false; - while ((!disp1._is_closed || !disp2._is_closed || !disp3._is_closed || !disp4._is_closed || !disp5._is_closed || - !disp6._is_closed || !disp7._is_closed || !disp8._is_closed) && - !disp1._is_event && !disp2._is_event && !disp3._is_event && !disp4._is_event && !disp5._is_event && - !disp6._is_event && !disp7._is_event && !disp8._is_event) wait_all(); - } - - //! Wait for any event occuring either on the display \c disp1, \c disp2, \c disp3, \c disp4, ... \c disp9. - static void wait(CImgDisplay& disp1, CImgDisplay& disp2, CImgDisplay& disp3, CImgDisplay& disp4, CImgDisplay& disp5, - CImgDisplay& disp6, CImgDisplay& disp7, CImgDisplay& disp8, CImgDisplay& disp9) { - disp1._is_event = disp2._is_event = disp3._is_event = disp4._is_event = disp5._is_event = - disp6._is_event = disp7._is_event = disp8._is_event = disp9._is_event = false; - while ((!disp1._is_closed || !disp2._is_closed || !disp3._is_closed || !disp4._is_closed || !disp5._is_closed || - !disp6._is_closed || !disp7._is_closed || !disp8._is_closed || !disp9._is_closed) && - !disp1._is_event && !disp2._is_event && !disp3._is_event && !disp4._is_event && !disp5._is_event && - !disp6._is_event && !disp7._is_event && !disp8._is_event && !disp9._is_event) wait_all(); - } - - //! Wait for any event occuring either on the display \c disp1, \c disp2, \c disp3, \c disp4, ... \c disp10. - static void wait(CImgDisplay& disp1, CImgDisplay& disp2, CImgDisplay& disp3, CImgDisplay& disp4, CImgDisplay& disp5, - CImgDisplay& disp6, CImgDisplay& disp7, CImgDisplay& disp8, CImgDisplay& disp9, - CImgDisplay& disp10) { - disp1._is_event = disp2._is_event = disp3._is_event = disp4._is_event = disp5._is_event = - disp6._is_event = disp7._is_event = disp8._is_event = disp9._is_event = disp10._is_event = false; - while ((!disp1._is_closed || !disp2._is_closed || !disp3._is_closed || !disp4._is_closed || !disp5._is_closed || - !disp6._is_closed || !disp7._is_closed || !disp8._is_closed || !disp9._is_closed || !disp10._is_closed) && - !disp1._is_event && !disp2._is_event && !disp3._is_event && !disp4._is_event && !disp5._is_event && - !disp6._is_event && !disp7._is_event && !disp8._is_event && !disp9._is_event && !disp10._is_event) - wait_all(); - } - -#if cimg_display==0 - - //! Wait for any window event occuring in any opened CImgDisplay. - static void wait_all() { - return _no_display_exception(); - } - - //! Render image into internal display buffer. - /** - \param img Input image data to render. - \note - - Convert image data representation into the internal display buffer (architecture-dependent structure). - - The content of the associated window is not modified, until paint() is called. - - Should not be used for common CImgDisplay uses, since display() is more useful. - **/ - template - CImgDisplay& render(const CImg& img) { - return assign(img); - } - - //! Paint internal display buffer on associated window. - /** - \note - - Update the content of the associated window with the internal display buffer, e.g. after a render() call. - - Should not be used for common CImgDisplay uses, since display() is more useful. - **/ - CImgDisplay& paint() { - return assign(); - } - - //! Take a snapshot of the associated window content. - /** - \param[out] img Output snapshot. Can be empty on input. - **/ - template - const CImgDisplay& snapshot(CImg& img) const { - cimg::unused(img); - _no_display_exception(); - return *this; - } -#endif - - // X11-based implementation - //-------------------------- -#if cimg_display==1 - - Atom _wm_window_atom, _wm_protocol_atom; - Window _window, _background_window; - Colormap _colormap; - XImage *_image; - void *_data; -#ifdef cimg_use_xshm - XShmSegmentInfo *_shminfo; -#endif - - static int screen_width() { - Display *const dpy = cimg::X11_attr().display; - int res = 0; - if (!dpy) { - Display *const _dpy = XOpenDisplay(0); - if (!_dpy) - throw CImgDisplayException("CImgDisplay::screen_width(): Failed to open X11 display."); - res = DisplayWidth(_dpy,DefaultScreen(_dpy)); - XCloseDisplay(_dpy); - } else { -#ifdef cimg_use_xrandr - if (cimg::X11_attr().resolutions && cimg::X11_attr().curr_resolution) - res = cimg::X11_attr().resolutions[cimg::X11_attr().curr_resolution].width; - else res = DisplayWidth(dpy,DefaultScreen(dpy)); -#else - res = DisplayWidth(dpy,DefaultScreen(dpy)); -#endif - } - return res; - } - - static int screen_height() { - Display *const dpy = cimg::X11_attr().display; - int res = 0; - if (!dpy) { - Display *const _dpy = XOpenDisplay(0); - if (!_dpy) - throw CImgDisplayException("CImgDisplay::screen_height(): Failed to open X11 display."); - res = DisplayHeight(_dpy,DefaultScreen(_dpy)); - XCloseDisplay(_dpy); - } else { -#ifdef cimg_use_xrandr - if (cimg::X11_attr().resolutions && cimg::X11_attr().curr_resolution) - res = cimg::X11_attr().resolutions[cimg::X11_attr().curr_resolution].height; - else res = DisplayHeight(dpy,DefaultScreen(dpy)); -#else - res = DisplayHeight(dpy,DefaultScreen(dpy)); -#endif - } - return res; - } - - static void wait_all() { - if (!cimg::X11_attr().display) return; - pthread_mutex_lock(&cimg::X11_attr().wait_event_mutex); - pthread_cond_wait(&cimg::X11_attr().wait_event,&cimg::X11_attr().wait_event_mutex); - pthread_mutex_unlock(&cimg::X11_attr().wait_event_mutex); - } - - void _handle_events(const XEvent *const pevent) { - Display *const dpy = cimg::X11_attr().display; - XEvent event = *pevent; - switch (event.type) { - case ClientMessage : { - if ((int)event.xclient.message_type==(int)_wm_protocol_atom && - (int)event.xclient.data.l[0]==(int)_wm_window_atom) { - XUnmapWindow(cimg::X11_attr().display,_window); - _is_closed = _is_event = true; - pthread_cond_broadcast(&cimg::X11_attr().wait_event); - } - } break; - case ConfigureNotify : { - while (XCheckWindowEvent(dpy,_window,StructureNotifyMask,&event)) {} - const unsigned int nw = event.xconfigure.width, nh = event.xconfigure.height; - const int nx = event.xconfigure.x, ny = event.xconfigure.y; - if (nw && nh && (nw!=_window_width || nh!=_window_height)) { - _window_width = nw; _window_height = nh; _mouse_x = _mouse_y = -1; - XResizeWindow(dpy,_window,_window_width,_window_height); - _is_resized = _is_event = true; - pthread_cond_broadcast(&cimg::X11_attr().wait_event); - } - if (nx!=_window_x || ny!=_window_y) { - _window_x = nx; _window_y = ny; _is_moved = _is_event = true; - pthread_cond_broadcast(&cimg::X11_attr().wait_event); - } - } break; - case Expose : { - while (XCheckWindowEvent(dpy,_window,ExposureMask,&event)) {} - _paint(false); - if (_is_fullscreen) { - XWindowAttributes attr; - XGetWindowAttributes(dpy,_window,&attr); - while (attr.map_state!=IsViewable) XSync(dpy,0); - XSetInputFocus(dpy,_window,RevertToParent,CurrentTime); - } - } break; - case ButtonPress : { - do { - _mouse_x = event.xmotion.x; _mouse_y = event.xmotion.y; - if (_mouse_x<0 || _mouse_y<0 || _mouse_x>=width() || _mouse_y>=height()) _mouse_x = _mouse_y = -1; - switch (event.xbutton.button) { - case 1 : set_button(1); break; - case 3 : set_button(2); break; - case 2 : set_button(3); break; - } - } while (XCheckWindowEvent(dpy,_window,ButtonPressMask,&event)); - } break; - case ButtonRelease : { - do { - _mouse_x = event.xmotion.x; _mouse_y = event.xmotion.y; - if (_mouse_x<0 || _mouse_y<0 || _mouse_x>=width() || _mouse_y>=height()) _mouse_x = _mouse_y = -1; - switch (event.xbutton.button) { - case 1 : set_button(1,false); break; - case 3 : set_button(2,false); break; - case 2 : set_button(3,false); break; - case 4 : set_wheel(1); break; - case 5 : set_wheel(-1); break; - } - } while (XCheckWindowEvent(dpy,_window,ButtonReleaseMask,&event)); - } break; - case KeyPress : { - char tmp = 0; KeySym ksym; - XLookupString(&event.xkey,&tmp,1,&ksym,0); - set_key((unsigned int)ksym,true); - } break; - case KeyRelease : { - char keys_return[32]; // Check that the key has been physically unpressed. - XQueryKeymap(dpy,keys_return); - const unsigned int kc = event.xkey.keycode, kc1 = kc/8, kc2 = kc%8; - const bool is_key_pressed = kc1>=32?false:(keys_return[kc1]>>kc2)&1; - if (!is_key_pressed) { - char tmp = 0; KeySym ksym; - XLookupString(&event.xkey,&tmp,1,&ksym,0); - set_key((unsigned int)ksym,false); - } - } break; - case EnterNotify: { - while (XCheckWindowEvent(dpy,_window,EnterWindowMask,&event)) {} - _mouse_x = event.xmotion.x; - _mouse_y = event.xmotion.y; - if (_mouse_x<0 || _mouse_y<0 || _mouse_x>=width() || _mouse_y>=height()) _mouse_x = _mouse_y = -1; - } break; - case LeaveNotify : { - while (XCheckWindowEvent(dpy,_window,LeaveWindowMask,&event)) {} - _mouse_x = _mouse_y = -1; _is_event = true; - pthread_cond_broadcast(&cimg::X11_attr().wait_event); - } break; - case MotionNotify : { - while (XCheckWindowEvent(dpy,_window,PointerMotionMask,&event)) {} - _mouse_x = event.xmotion.x; - _mouse_y = event.xmotion.y; - if (_mouse_x<0 || _mouse_y<0 || _mouse_x>=width() || _mouse_y>=height()) _mouse_x = _mouse_y = -1; - _is_event = true; - pthread_cond_broadcast(&cimg::X11_attr().wait_event); - } break; - } - } - - static void* _events_thread(void *arg) { // Thread to manage events for all opened display windows. - Display *const dpy = cimg::X11_attr().display; - XEvent event; - pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,0); - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,0); - if (!arg) for ( ; ; ) { - cimg_lock_display(); - bool event_flag = XCheckTypedEvent(dpy,ClientMessage,&event); - if (!event_flag) event_flag = XCheckMaskEvent(dpy, - ExposureMask | StructureNotifyMask | ButtonPressMask | - KeyPressMask | PointerMotionMask | EnterWindowMask | - LeaveWindowMask | ButtonReleaseMask | KeyReleaseMask,&event); - if (event_flag) - for (unsigned int i = 0; i_is_closed && event.xany.window==cimg::X11_attr().wins[i]->_window) - cimg::X11_attr().wins[i]->_handle_events(&event); - cimg_unlock_display(); - pthread_testcancel(); - cimg::sleep(8); - } - return 0; - } - - void _set_colormap(Colormap& _colormap, const unsigned int dim) { - XColor *const colormap = new XColor[256]; - switch (dim) { - case 1 : { // colormap for greyscale images - for (unsigned int index = 0; index<256; ++index) { - colormap[index].pixel = index; - colormap[index].red = colormap[index].green = colormap[index].blue = (unsigned short)(index<<8); - colormap[index].flags = DoRed | DoGreen | DoBlue; - } - } break; - case 2 : { // colormap for RG images - for (unsigned int index = 0, r = 8; r<256; r+=16) - for (unsigned int g = 8; g<256; g+=16) { - colormap[index].pixel = index; - colormap[index].red = colormap[index].blue = (unsigned short)(r<<8); - colormap[index].green = (unsigned short)(g<<8); - colormap[index++].flags = DoRed | DoGreen | DoBlue; - } - } break; - default : { // colormap for RGB images - for (unsigned int index = 0, r = 16; r<256; r+=32) - for (unsigned int g = 16; g<256; g+=32) - for (unsigned int b = 32; b<256; b+=64) { - colormap[index].pixel = index; - colormap[index].red = (unsigned short)(r<<8); - colormap[index].green = (unsigned short)(g<<8); - colormap[index].blue = (unsigned short)(b<<8); - colormap[index++].flags = DoRed | DoGreen | DoBlue; - } - } - } - XStoreColors(cimg::X11_attr().display,_colormap,colormap,256); - delete[] colormap; - } - - void _map_window() { - Display *const dpy = cimg::X11_attr().display; - bool is_exposed = false, is_mapped = false; - XWindowAttributes attr; - XEvent event; - XMapRaised(dpy,_window); - do { // Wait for the window to be mapped. - XWindowEvent(dpy,_window,StructureNotifyMask | ExposureMask,&event); - switch (event.type) { - case MapNotify : is_mapped = true; break; - case Expose : is_exposed = true; break; - } - } while (!is_exposed || !is_mapped); - do { // Wait for the window to be visible. - XGetWindowAttributes(dpy,_window,&attr); - if (attr.map_state!=IsViewable) { XSync(dpy,0); cimg::sleep(10); } - } while (attr.map_state!=IsViewable); - _window_x = attr.x; - _window_y = attr.y; - } - - void _paint(const bool wait_expose=true) { - if (_is_closed || !_image) return; - Display *const dpy = cimg::X11_attr().display; - if (wait_expose) { // Send an expose event sticked to display window to force repaint. - XEvent event; - event.xexpose.type = Expose; - event.xexpose.serial = 0; - event.xexpose.send_event = 1; - event.xexpose.display = dpy; - event.xexpose.window = _window; - event.xexpose.x = 0; - event.xexpose.y = 0; - event.xexpose.width = width(); - event.xexpose.height = height(); - event.xexpose.count = 0; - XSendEvent(dpy,_window,0,0,&event); - } else { // Repaint directly (may be called from the expose event). - GC gc = DefaultGC(dpy,DefaultScreen(dpy)); -#ifdef cimg_use_xshm - if (_shminfo) XShmPutImage(dpy,_window,gc,_image,0,0,0,0,_width,_height,1); - else XPutImage(dpy,_window,gc,_image,0,0,0,0,_width,_height); -#else - XPutImage(dpy,_window,gc,_image,0,0,0,0,_width,_height); -#endif - } - } - - template - void _resize(T pixel_type, const unsigned int ndimx, const unsigned int ndimy, const bool force_redraw) { - Display *const dpy = cimg::X11_attr().display; - cimg::unused(pixel_type); - -#ifdef cimg_use_xshm - if (_shminfo) { - XShmSegmentInfo *const nshminfo = new XShmSegmentInfo; - XImage *const nimage = XShmCreateImage(dpy,DefaultVisual(dpy,DefaultScreen(dpy)), - cimg::X11_attr().nb_bits,ZPixmap,0,nshminfo,ndimx,ndimy); - if (!nimage) { delete nshminfo; return; } - else { - nshminfo->shmid = shmget(IPC_PRIVATE,ndimx*ndimy*sizeof(T),IPC_CREAT | 0777); - if (nshminfo->shmid==-1) { XDestroyImage(nimage); delete nshminfo; return; } - else { - nshminfo->shmaddr = nimage->data = (char*)shmat(nshminfo->shmid,0,0); - if (nshminfo->shmaddr==(char*)-1) { - shmctl(nshminfo->shmid,IPC_RMID,0); XDestroyImage(nimage); delete nshminfo; return; - } else { - nshminfo->readOnly = 0; - cimg::X11_attr().is_shm_enabled = true; - XErrorHandler oldXErrorHandler = XSetErrorHandler(_assign_xshm); - XShmAttach(dpy,nshminfo); - XFlush(dpy); - XSetErrorHandler(oldXErrorHandler); - if (!cimg::X11_attr().is_shm_enabled) { - shmdt(nshminfo->shmaddr); - shmctl(nshminfo->shmid,IPC_RMID,0); - XDestroyImage(nimage); - delete nshminfo; - return; - } else { - T *const ndata = (T*)nimage->data; - if (force_redraw) _render_resize((T*)_data,_width,_height,ndata,ndimx,ndimy); - else std::memset(ndata,0,sizeof(T)*ndimx*ndimy); - XShmDetach(dpy,_shminfo); - XDestroyImage(_image); - shmdt(_shminfo->shmaddr); - shmctl(_shminfo->shmid,IPC_RMID,0); - delete _shminfo; - _shminfo = nshminfo; - _image = nimage; - _data = (void*)ndata; - } - } - } - } - } else -#endif - { - T *ndata = (T*)std::malloc(ndimx*ndimy*sizeof(T)); - if (force_redraw) _render_resize((T*)_data,_width,_height,ndata,ndimx,ndimy); - else std::memset(ndata,0,sizeof(T)*ndimx*ndimy); - _data = (void*)ndata; - XDestroyImage(_image); - _image = XCreateImage(dpy,DefaultVisual(dpy,DefaultScreen(dpy)), - cimg::X11_attr().nb_bits,ZPixmap,0,(char*)_data,ndimx,ndimy,8,0); - } - } - - void _init_fullscreen() { - if (!_is_fullscreen || _is_closed) return; - Display *const dpy = cimg::X11_attr().display; - _background_window = 0; - -#ifdef cimg_use_xrandr - int foo; - if (XRRQueryExtension(dpy,&foo,&foo)) { - XRRRotations(dpy,DefaultScreen(dpy),&cimg::X11_attr().curr_rotation); - if (!cimg::X11_attr().resolutions) { - cimg::X11_attr().resolutions = XRRSizes(dpy,DefaultScreen(dpy),&foo); - cimg::X11_attr().nb_resolutions = (unsigned int)foo; - } - if (cimg::X11_attr().resolutions) { - cimg::X11_attr().curr_resolution = 0; - for (unsigned int i = 0; i=_width && nh>=_height && - nw<=(unsigned int)(cimg::X11_attr().resolutions[cimg::X11_attr().curr_resolution].width) && - nh<=(unsigned int)(cimg::X11_attr().resolutions[cimg::X11_attr().curr_resolution].height)) - cimg::X11_attr().curr_resolution = i; - } - if (cimg::X11_attr().curr_resolution>0) { - XRRScreenConfiguration *config = XRRGetScreenInfo(dpy,DefaultRootWindow(dpy)); - XRRSetScreenConfig(dpy,config,DefaultRootWindow(dpy), - cimg::X11_attr().curr_resolution,cimg::X11_attr().curr_rotation,CurrentTime); - XRRFreeScreenConfigInfo(config); - XSync(dpy,0); - } - } - } - if (!cimg::X11_attr().resolutions) - cimg::warn(_cimgdisplay_instance - "init_fullscreen(): Xrandr extension not supported by the X server.", - cimgdisplay_instance); -#endif - - const unsigned int sx = screen_width(), sy = screen_height(); - if (sx==_width && sy==_height) return; - XSetWindowAttributes winattr; - winattr.override_redirect = 1; - _background_window = XCreateWindow(dpy,DefaultRootWindow(dpy),0,0,sx,sy,0,0, - InputOutput,CopyFromParent,CWOverrideRedirect,&winattr); - const cimg_ulong buf_size = (cimg_ulong)sx*sy*(cimg::X11_attr().nb_bits==8?1: - (cimg::X11_attr().nb_bits==16?2:4)); - void *background_data = std::malloc(buf_size); - std::memset(background_data,0,buf_size); - XImage *background_image = XCreateImage(dpy,DefaultVisual(dpy,DefaultScreen(dpy)),cimg::X11_attr().nb_bits, - ZPixmap,0,(char*)background_data,sx,sy,8,0); - XEvent event; - XSelectInput(dpy,_background_window,StructureNotifyMask); - XMapRaised(dpy,_background_window); - do XWindowEvent(dpy,_background_window,StructureNotifyMask,&event); - while (event.type!=MapNotify); - GC gc = DefaultGC(dpy,DefaultScreen(dpy)); -#ifdef cimg_use_xshm - if (_shminfo) XShmPutImage(dpy,_background_window,gc,background_image,0,0,0,0,sx,sy,0); - else XPutImage(dpy,_background_window,gc,background_image,0,0,0,0,sx,sy); -#else - XPutImage(dpy,_background_window,gc,background_image,0,0,0,0,sx,sy); -#endif - XWindowAttributes attr; - XGetWindowAttributes(dpy,_background_window,&attr); - while (attr.map_state!=IsViewable) XSync(dpy,0); - XDestroyImage(background_image); - } - - void _desinit_fullscreen() { - if (!_is_fullscreen) return; - Display *const dpy = cimg::X11_attr().display; - XUngrabKeyboard(dpy,CurrentTime); -#ifdef cimg_use_xrandr - if (cimg::X11_attr().resolutions && cimg::X11_attr().curr_resolution) { - XRRScreenConfiguration *config = XRRGetScreenInfo(dpy,DefaultRootWindow(dpy)); - XRRSetScreenConfig(dpy,config,DefaultRootWindow(dpy),0,cimg::X11_attr().curr_rotation,CurrentTime); - XRRFreeScreenConfigInfo(config); - XSync(dpy,0); - cimg::X11_attr().curr_resolution = 0; - } -#endif - if (_background_window) XDestroyWindow(dpy,_background_window); - _background_window = 0; - _is_fullscreen = false; - } - - static int _assign_xshm(Display *dpy, XErrorEvent *error) { - cimg::unused(dpy,error); - cimg::X11_attr().is_shm_enabled = false; - return 0; - } - - void _assign(const unsigned int dimw, const unsigned int dimh, const char *const ptitle=0, - const unsigned int normalization_type=3, - const bool fullscreen_flag=false, const bool closed_flag=false) { - cimg::mutex(14); - - // Allocate space for window title - const char *const nptitle = ptitle?ptitle:""; - const unsigned int s = (unsigned int)std::strlen(nptitle) + 1; - char *const tmp_title = s?new char[s]:0; - if (s) std::memcpy(tmp_title,nptitle,s*sizeof(char)); - - // Destroy previous display window if existing - if (!is_empty()) assign(); - - // Open X11 display and retrieve graphical properties. - Display* &dpy = cimg::X11_attr().display; - if (!dpy) { - dpy = XOpenDisplay(0); - if (!dpy) - throw CImgDisplayException(_cimgdisplay_instance - "assign(): Failed to open X11 display.", - cimgdisplay_instance); - - cimg::X11_attr().nb_bits = DefaultDepth(dpy,DefaultScreen(dpy)); - if (cimg::X11_attr().nb_bits!=8 && cimg::X11_attr().nb_bits!=16 && - cimg::X11_attr().nb_bits!=24 && cimg::X11_attr().nb_bits!=32) - throw CImgDisplayException(_cimgdisplay_instance - "assign(): Invalid %u bits screen mode detected " - "(only 8, 16, 24 and 32 bits modes are managed).", - cimgdisplay_instance, - cimg::X11_attr().nb_bits); - XVisualInfo vtemplate; - vtemplate.visualid = XVisualIDFromVisual(DefaultVisual(dpy,DefaultScreen(dpy))); - int nb_visuals; - XVisualInfo *vinfo = XGetVisualInfo(dpy,VisualIDMask,&vtemplate,&nb_visuals); - if (vinfo && vinfo->red_maskblue_mask) cimg::X11_attr().is_blue_first = true; - cimg::X11_attr().byte_order = ImageByteOrder(dpy); - XFree(vinfo); - - cimg_lock_display(); - cimg::X11_attr().events_thread = new pthread_t; - pthread_create(cimg::X11_attr().events_thread,0,_events_thread,0); - } else cimg_lock_display(); - - // Set display variables. - _width = cimg::min(dimw,(unsigned int)screen_width()); - _height = cimg::min(dimh,(unsigned int)screen_height()); - _normalization = normalization_type<4?normalization_type:3; - _is_fullscreen = fullscreen_flag; - _window_x = _window_y = 0; - _is_closed = closed_flag; - _title = tmp_title; - flush(); - - // Create X11 window (and LUT, if 8bits display) - if (_is_fullscreen) { - if (!_is_closed) _init_fullscreen(); - const unsigned int sx = screen_width(), sy = screen_height(); - XSetWindowAttributes winattr; - winattr.override_redirect = 1; - _window = XCreateWindow(dpy,DefaultRootWindow(dpy),(sx - _width)/2,(sy - _height)/2,_width,_height,0,0, - InputOutput,CopyFromParent,CWOverrideRedirect,&winattr); - } else - _window = XCreateSimpleWindow(dpy,DefaultRootWindow(dpy),0,0,_width,_height,0,0L,0L); - - XSelectInput(dpy,_window, - ExposureMask | StructureNotifyMask | ButtonPressMask | KeyPressMask | PointerMotionMask | - EnterWindowMask | LeaveWindowMask | ButtonReleaseMask | KeyReleaseMask); - - XStoreName(dpy,_window,_title?_title:" "); - if (cimg::X11_attr().nb_bits==8) { - _colormap = XCreateColormap(dpy,_window,DefaultVisual(dpy,DefaultScreen(dpy)),AllocAll); - _set_colormap(_colormap,3); - XSetWindowColormap(dpy,_window,_colormap); - } - - static const char *const _window_class = cimg_appname; - XClassHint *const window_class = XAllocClassHint(); - window_class->res_name = (char*)_window_class; - window_class->res_class = (char*)_window_class; - XSetClassHint(dpy,_window,window_class); - XFree(window_class); - - _window_width = _width; - _window_height = _height; - - // Create XImage -#ifdef cimg_use_xshm - _shminfo = 0; - if (XShmQueryExtension(dpy)) { - _shminfo = new XShmSegmentInfo; - _image = XShmCreateImage(dpy,DefaultVisual(dpy,DefaultScreen(dpy)),cimg::X11_attr().nb_bits, - ZPixmap,0,_shminfo,_width,_height); - if (!_image) { delete _shminfo; _shminfo = 0; } - else { - _shminfo->shmid = shmget(IPC_PRIVATE,_image->bytes_per_line*_image->height,IPC_CREAT|0777); - if (_shminfo->shmid==-1) { XDestroyImage(_image); delete _shminfo; _shminfo = 0; } - else { - _shminfo->shmaddr = _image->data = (char*)(_data = shmat(_shminfo->shmid,0,0)); - if (_shminfo->shmaddr==(char*)-1) { - shmctl(_shminfo->shmid,IPC_RMID,0); XDestroyImage(_image); delete _shminfo; _shminfo = 0; - } else { - _shminfo->readOnly = 0; - cimg::X11_attr().is_shm_enabled = true; - XErrorHandler oldXErrorHandler = XSetErrorHandler(_assign_xshm); - XShmAttach(dpy,_shminfo); - XSync(dpy,0); - XSetErrorHandler(oldXErrorHandler); - if (!cimg::X11_attr().is_shm_enabled) { - shmdt(_shminfo->shmaddr); shmctl(_shminfo->shmid,IPC_RMID,0); XDestroyImage(_image); - delete _shminfo; _shminfo = 0; - } - } - } - } - } - if (!_shminfo) -#endif - { - const cimg_ulong buf_size = (cimg_ulong)_width*_height*(cimg::X11_attr().nb_bits==8?1: - (cimg::X11_attr().nb_bits==16?2:4)); - _data = std::malloc(buf_size); - _image = XCreateImage(dpy,DefaultVisual(dpy,DefaultScreen(dpy)),cimg::X11_attr().nb_bits, - ZPixmap,0,(char*)_data,_width,_height,8,0); - } - - _wm_window_atom = XInternAtom(dpy,"WM_DELETE_WINDOW",0); - _wm_protocol_atom = XInternAtom(dpy,"WM_PROTOCOLS",0); - XSetWMProtocols(dpy,_window,&_wm_window_atom,1); - - if (_is_fullscreen) XGrabKeyboard(dpy,_window,1,GrabModeAsync,GrabModeAsync,CurrentTime); - cimg::X11_attr().wins[cimg::X11_attr().nb_wins++]=this; - if (!_is_closed) _map_window(); else { _window_x = _window_y = cimg::type::min(); } - cimg_unlock_display(); - cimg::mutex(14,0); - } - - CImgDisplay& assign() { - if (is_empty()) return flush(); - Display *const dpy = cimg::X11_attr().display; - cimg_lock_display(); - - // Remove display window from event thread list. - unsigned int i; - for (i = 0; ishmaddr); - shmctl(_shminfo->shmid,IPC_RMID,0); - delete _shminfo; - _shminfo = 0; - } else -#endif - XDestroyImage(_image); - _data = 0; _image = 0; - if (cimg::X11_attr().nb_bits==8) XFreeColormap(dpy,_colormap); - _colormap = 0; - XSync(dpy,0); - - // Reset display variables. - delete[] _title; - _width = _height = _normalization = _window_width = _window_height = 0; - _window_x = _window_y = 0; - _is_fullscreen = false; - _is_closed = true; - _min = _max = 0; - _title = 0; - flush(); - - cimg_unlock_display(); - return *this; - } - - CImgDisplay& assign(const unsigned int dimw, const unsigned int dimh, const char *const title=0, - const unsigned int normalization_type=3, - const bool fullscreen_flag=false, const bool closed_flag=false) { - if (!dimw || !dimh) return assign(); - _assign(dimw,dimh,title,normalization_type,fullscreen_flag,closed_flag); - _min = _max = 0; - std::memset(_data,0,(cimg::X11_attr().nb_bits==8?sizeof(unsigned char): - (cimg::X11_attr().nb_bits==16?sizeof(unsigned short):sizeof(unsigned int)))* - (size_t)_width*_height); - return paint(); - } - - template - CImgDisplay& assign(const CImg& img, const char *const title=0, - const unsigned int normalization_type=3, - const bool fullscreen_flag=false, const bool closed_flag=false) { - if (!img) return assign(); - CImg tmp; - const CImg& nimg = (img._depth==1)?img:(tmp=img.get_projections2d((img._width - 1)/2, - (img._height - 1)/2, - (img._depth - 1)/2)); - _assign(nimg._width,nimg._height,title,normalization_type,fullscreen_flag,closed_flag); - if (_normalization==2) _min = (float)nimg.min_max(_max); - return render(nimg).paint(); - } - - template - CImgDisplay& assign(const CImgList& list, const char *const title=0, - const unsigned int normalization_type=3, - const bool fullscreen_flag=false, const bool closed_flag=false) { - if (!list) return assign(); - CImg tmp; - const CImg img = list>'x', &nimg = (img._depth==1)?img:(tmp=img.get_projections2d((img._width - 1)/2, - (img._height - 1)/2, - (img._depth - 1)/2)); - _assign(nimg._width,nimg._height,title,normalization_type,fullscreen_flag,closed_flag); - if (_normalization==2) _min = (float)nimg.min_max(_max); - return render(nimg).paint(); - } - - CImgDisplay& assign(const CImgDisplay& disp) { - if (!disp) return assign(); - _assign(disp._width,disp._height,disp._title,disp._normalization,disp._is_fullscreen,disp._is_closed); - std::memcpy(_data,disp._data,(cimg::X11_attr().nb_bits==8?sizeof(unsigned char): - cimg::X11_attr().nb_bits==16?sizeof(unsigned short): - sizeof(unsigned int))*(size_t)_width*_height); - return paint(); - } - - CImgDisplay& resize(const int nwidth, const int nheight, const bool force_redraw=true) { - if (!nwidth || !nheight || (is_empty() && (nwidth<0 || nheight<0))) return assign(); - if (is_empty()) return assign(nwidth,nheight); - Display *const dpy = cimg::X11_attr().display; - const unsigned int - tmpdimx = (nwidth>0)?nwidth:(-nwidth*width()/100), - tmpdimy = (nheight>0)?nheight:(-nheight*height()/100), - dimx = tmpdimx?tmpdimx:1, - dimy = tmpdimy?tmpdimy:1; - if (_width!=dimx || _height!=dimy || _window_width!=dimx || _window_height!=dimy) { - show(); - cimg_lock_display(); - if (_window_width!=dimx || _window_height!=dimy) { - XWindowAttributes attr; - for (unsigned int i = 0; i<10; ++i) { - XResizeWindow(dpy,_window,dimx,dimy); - XGetWindowAttributes(dpy,_window,&attr); - if (attr.width==(int)dimx && attr.height==(int)dimy) break; - cimg::wait(5); - } - } - if (_width!=dimx || _height!=dimy) switch (cimg::X11_attr().nb_bits) { - case 8 : { unsigned char pixel_type = 0; _resize(pixel_type,dimx,dimy,force_redraw); } break; - case 16 : { unsigned short pixel_type = 0; _resize(pixel_type,dimx,dimy,force_redraw); } break; - default : { unsigned int pixel_type = 0; _resize(pixel_type,dimx,dimy,force_redraw); } - } - _window_width = _width = dimx; _window_height = _height = dimy; - cimg_unlock_display(); - } - _is_resized = false; - if (_is_fullscreen) move((screen_width() - _width)/2,(screen_height() - _height)/2); - if (force_redraw) return paint(); - return *this; - } - - CImgDisplay& toggle_fullscreen(const bool force_redraw=true) { - if (is_empty()) return *this; - if (force_redraw) { - const cimg_ulong buf_size = (cimg_ulong)_width*_height* - (cimg::X11_attr().nb_bits==8?1:(cimg::X11_attr().nb_bits==16?2:4)); - void *image_data = std::malloc(buf_size); - std::memcpy(image_data,_data,buf_size); - assign(_width,_height,_title,_normalization,!_is_fullscreen,false); - std::memcpy(_data,image_data,buf_size); - std::free(image_data); - return paint(); - } - return assign(_width,_height,_title,_normalization,!_is_fullscreen,false); - } - - CImgDisplay& show() { - if (is_empty() || !_is_closed) return *this; - cimg_lock_display(); - if (_is_fullscreen) _init_fullscreen(); - _map_window(); - _is_closed = false; - cimg_unlock_display(); - return paint(); - } - - CImgDisplay& close() { - if (is_empty() || _is_closed) return *this; - Display *const dpy = cimg::X11_attr().display; - cimg_lock_display(); - if (_is_fullscreen) _desinit_fullscreen(); - XUnmapWindow(dpy,_window); - _window_x = _window_y = -1; - _is_closed = true; - cimg_unlock_display(); - return *this; - } - - CImgDisplay& move(const int posx, const int posy) { - if (is_empty()) return *this; - if (_window_x!=posx || _window_y!=posy) { - show(); - Display *const dpy = cimg::X11_attr().display; - cimg_lock_display(); - XMoveWindow(dpy,_window,posx,posy); - _window_x = posx; _window_y = posy; - cimg_unlock_display(); - } - _is_moved = false; - return paint(); - } - - CImgDisplay& show_mouse() { - if (is_empty()) return *this; - Display *const dpy = cimg::X11_attr().display; - cimg_lock_display(); - XUndefineCursor(dpy,_window); - cimg_unlock_display(); - return *this; - } - - CImgDisplay& hide_mouse() { - if (is_empty()) return *this; - Display *const dpy = cimg::X11_attr().display; - cimg_lock_display(); - static const char pix_data[8] = { 0 }; - XColor col; - col.red = col.green = col.blue = 0; - Pixmap pix = XCreateBitmapFromData(dpy,_window,pix_data,8,8); - Cursor cur = XCreatePixmapCursor(dpy,pix,pix,&col,&col,0,0); - XFreePixmap(dpy,pix); - XDefineCursor(dpy,_window,cur); - cimg_unlock_display(); - return *this; - } - - CImgDisplay& set_mouse(const int posx, const int posy) { - if (is_empty() || _is_closed) return *this; - Display *const dpy = cimg::X11_attr().display; - cimg_lock_display(); - XWarpPointer(dpy,0L,_window,0,0,0,0,posx,posy); - _mouse_x = posx; _mouse_y = posy; - _is_moved = false; - XSync(dpy,0); - cimg_unlock_display(); - return *this; - } - - CImgDisplay& set_title(const char *const format, ...) { - if (is_empty()) return *this; - char *const tmp = new char[1024]; - va_list ap; - va_start(ap, format); - cimg_vsnprintf(tmp,1024,format,ap); - va_end(ap); - if (!std::strcmp(_title,tmp)) { delete[] tmp; return *this; } - delete[] _title; - const unsigned int s = (unsigned int)std::strlen(tmp) + 1; - _title = new char[s]; - std::memcpy(_title,tmp,s*sizeof(char)); - Display *const dpy = cimg::X11_attr().display; - cimg_lock_display(); - XStoreName(dpy,_window,tmp); - cimg_unlock_display(); - delete[] tmp; - return *this; - } - - template - CImgDisplay& display(const CImg& img) { - if (!img) - throw CImgArgumentException(_cimgdisplay_instance - "display(): Empty specified image.", - cimgdisplay_instance); - if (is_empty()) return assign(img); - return render(img).paint(false); - } - - CImgDisplay& paint(const bool wait_expose=true) { - if (is_empty()) return *this; - cimg_lock_display(); - _paint(wait_expose); - cimg_unlock_display(); - return *this; - } - - template - CImgDisplay& render(const CImg& img, const bool flag8=false) { - if (!img) - throw CImgArgumentException(_cimgdisplay_instance - "render(): Empty specified image.", - cimgdisplay_instance); - if (is_empty()) return *this; - if (img._depth!=1) return render(img.get_projections2d((img._width - 1)/2,(img._height - 1)/2, - (img._depth - 1)/2)); - if (cimg::X11_attr().nb_bits==8 && (img._width!=_width || img._height!=_height)) - return render(img.get_resize(_width,_height,1,-100,1)); - if (cimg::X11_attr().nb_bits==8 && !flag8 && img._spectrum==3) { - static const CImg::ucharT> default_colormap = CImg::ucharT>::default_LUT256(); - return render(img.get_index(default_colormap,1,false)); - } - - const T - *data1 = img._data, - *data2 = (img._spectrum>1)?img.data(0,0,0,1):data1, - *data3 = (img._spectrum>2)?img.data(0,0,0,2):data1; - - if (cimg::X11_attr().is_blue_first) cimg::swap(data1,data3); - cimg_lock_display(); - - if (!_normalization || (_normalization==3 && cimg::type::string()==cimg::type::string())) { - _min = _max = 0; - switch (cimg::X11_attr().nb_bits) { - case 8 : { // 256 colormap, no normalization - _set_colormap(_colormap,img._spectrum); - unsigned char - *const ndata = (img._width==_width && img._height==_height)?(unsigned char*)_data: - new unsigned char[(size_t)img._width*img._height], - *ptrd = (unsigned char*)ndata; - switch (img._spectrum) { - case 1 : - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) - (*ptrd++) = (unsigned char)*(data1++); - break; - case 2 : for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char R = (unsigned char)*(data1++), G = (unsigned char)*(data2++); - (*ptrd++) = (R&0xf0) | (G>>4); - } break; - default : for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char - R = (unsigned char)*(data1++), - G = (unsigned char)*(data2++), - B = (unsigned char)*(data3++); - (*ptrd++) = (R&0xe0) | ((G>>5)<<2) | (B>>6); - } - } - if (ndata!=_data) { - _render_resize(ndata,img._width,img._height,(unsigned char*)_data,_width,_height); - delete[] ndata; - } - } break; - case 16 : { // 16 bits colors, no normalization - unsigned short *const ndata = (img._width==_width && img._height==_height)?(unsigned short*)_data: - new unsigned short[(size_t)img._width*img._height]; - unsigned char *ptrd = (unsigned char*)ndata; - const unsigned int M = 248; - switch (img._spectrum) { - case 1 : - if (cimg::X11_attr().byte_order) - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char val = (unsigned char)*(data1++), G = val>>2; - *(ptrd++) = (val&M) | (G>>3); - *(ptrd++) = (G<<5) | (G>>1); - } else for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char val = (unsigned char)*(data1++), G = val>>2; - *(ptrd++) = (G<<5) | (G>>1); - *(ptrd++) = (val&M) | (G>>3); - } - break; - case 2 : - if (cimg::X11_attr().byte_order) - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char G = (unsigned char)*(data2++)>>2; - *(ptrd++) = ((unsigned char)*(data1++)&M) | (G>>3); - *(ptrd++) = (G<<5); - } else for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char G = (unsigned char)*(data2++)>>2; - *(ptrd++) = (G<<5); - *(ptrd++) = ((unsigned char)*(data1++)&M) | (G>>3); - } - break; - default : - if (cimg::X11_attr().byte_order) - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char G = (unsigned char)*(data2++)>>2; - *(ptrd++) = ((unsigned char)*(data1++)&M) | (G>>3); - *(ptrd++) = (G<<5) | ((unsigned char)*(data3++)>>3); - } else for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char G = (unsigned char)*(data2++)>>2; - *(ptrd++) = (G<<5) | ((unsigned char)*(data3++)>>3); - *(ptrd++) = ((unsigned char)*(data1++)&M) | (G>>3); - } - } - if (ndata!=_data) { - _render_resize(ndata,img._width,img._height,(unsigned short*)_data,_width,_height); - delete[] ndata; - } - } break; - default : { // 24 bits colors, no normalization - unsigned int *const ndata = (img._width==_width && img._height==_height)?(unsigned int*)_data: - new unsigned int[(size_t)img._width*img._height]; - if (sizeof(int)==4) { // 32 bits int uses optimized version - unsigned int *ptrd = ndata; - switch (img._spectrum) { - case 1 : - if (cimg::X11_attr().byte_order==cimg::endianness()) - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char val = (unsigned char)*(data1++); - *(ptrd++) = (val<<16) | (val<<8) | val; - } - else - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char val = (unsigned char)*(data1++); - *(ptrd++) = (val<<16) | (val<<8) | val; - } - break; - case 2 : - if (cimg::X11_attr().byte_order==cimg::endianness()) - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) - *(ptrd++) = ((unsigned char)*(data1++)<<16) | ((unsigned char)*(data2++)<<8); - else - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) - *(ptrd++) = ((unsigned char)*(data2++)<<16) | ((unsigned char)*(data1++)<<8); - break; - default : - if (cimg::X11_attr().byte_order==cimg::endianness()) - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) - *(ptrd++) = ((unsigned char)*(data1++)<<16) | ((unsigned char)*(data2++)<<8) | - (unsigned char)*(data3++); - else - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) - *(ptrd++) = ((unsigned char)*(data3++)<<24) | ((unsigned char)*(data2++)<<16) | - ((unsigned char)*(data1++)<<8); - } - } else { - unsigned char *ptrd = (unsigned char*)ndata; - switch (img._spectrum) { - case 1 : - if (cimg::X11_attr().byte_order) - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - *(ptrd++) = 0; - *(ptrd++) = (unsigned char)*(data1++); - *(ptrd++) = 0; - *(ptrd++) = 0; - } else for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - *(ptrd++) = 0; - *(ptrd++) = 0; - *(ptrd++) = (unsigned char)*(data1++); - *(ptrd++) = 0; - } - break; - case 2 : - if (cimg::X11_attr().byte_order) cimg::swap(data1,data2); - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - *(ptrd++) = 0; - *(ptrd++) = (unsigned char)*(data2++); - *(ptrd++) = (unsigned char)*(data1++); - *(ptrd++) = 0; - } - break; - default : - if (cimg::X11_attr().byte_order) - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - *(ptrd++) = 0; - *(ptrd++) = (unsigned char)*(data1++); - *(ptrd++) = (unsigned char)*(data2++); - *(ptrd++) = (unsigned char)*(data3++); - } else for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - *(ptrd++) = (unsigned char)*(data3++); - *(ptrd++) = (unsigned char)*(data2++); - *(ptrd++) = (unsigned char)*(data1++); - *(ptrd++) = 0; - } - } - } - if (ndata!=_data) { - _render_resize(ndata,img._width,img._height,(unsigned int*)_data,_width,_height); - delete[] ndata; - } - } - } - } else { - if (_normalization==3) { - if (cimg::type::is_float()) _min = (float)img.min_max(_max); - else { _min = (float)cimg::type::min(); _max = (float)cimg::type::max(); } - } else if ((_min>_max) || _normalization==1) _min = (float)img.min_max(_max); - const float delta = _max - _min, mm = 255/(delta?delta:1.0f); - switch (cimg::X11_attr().nb_bits) { - case 8 : { // 256 colormap, with normalization - _set_colormap(_colormap,img._spectrum); - unsigned char *const ndata = (img._width==_width && img._height==_height)?(unsigned char*)_data: - new unsigned char[(size_t)img._width*img._height]; - unsigned char *ptrd = (unsigned char*)ndata; - switch (img._spectrum) { - case 1 : for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char R = (unsigned char)((*(data1++) - _min)*mm); - *(ptrd++) = R; - } break; - case 2 : for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char - R = (unsigned char)((*(data1++) - _min)*mm), - G = (unsigned char)((*(data2++) - _min)*mm); - (*ptrd++) = (R&0xf0) | (G>>4); - } break; - default : - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char - R = (unsigned char)((*(data1++) - _min)*mm), - G = (unsigned char)((*(data2++) - _min)*mm), - B = (unsigned char)((*(data3++) - _min)*mm); - *(ptrd++) = (R&0xe0) | ((G>>5)<<2) | (B>>6); - } - } - if (ndata!=_data) { - _render_resize(ndata,img._width,img._height,(unsigned char*)_data,_width,_height); - delete[] ndata; - } - } break; - case 16 : { // 16 bits colors, with normalization - unsigned short *const ndata = (img._width==_width && img._height==_height)?(unsigned short*)_data: - new unsigned short[(size_t)img._width*img._height]; - unsigned char *ptrd = (unsigned char*)ndata; - const unsigned int M = 248; - switch (img._spectrum) { - case 1 : - if (cimg::X11_attr().byte_order) - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char val = (unsigned char)((*(data1++) - _min)*mm), G = val>>2; - *(ptrd++) = (val&M) | (G>>3); - *(ptrd++) = (G<<5) | (val>>3); - } else for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char val = (unsigned char)((*(data1++) - _min)*mm), G = val>>2; - *(ptrd++) = (G<<5) | (val>>3); - *(ptrd++) = (val&M) | (G>>3); - } - break; - case 2 : - if (cimg::X11_attr().byte_order) - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char G = (unsigned char)((*(data2++) - _min)*mm)>>2; - *(ptrd++) = ((unsigned char)((*(data1++) - _min)*mm)&M) | (G>>3); - *(ptrd++) = (G<<5); - } else for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char G = (unsigned char)((*(data2++) - _min)*mm)>>2; - *(ptrd++) = (G<<5); - *(ptrd++) = ((unsigned char)((*(data1++) - _min)*mm)&M) | (G>>3); - } - break; - default : - if (cimg::X11_attr().byte_order) - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char G = (unsigned char)((*(data2++) - _min)*mm)>>2; - *(ptrd++) = ((unsigned char)((*(data1++) - _min)*mm)&M) | (G>>3); - *(ptrd++) = (G<<5) | ((unsigned char)((*(data3++) - _min)*mm)>>3); - } else for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char G = (unsigned char)((*(data2++) - _min)*mm)>>2; - *(ptrd++) = (G<<5) | ((unsigned char)((*(data3++) - _min)*mm)>>3); - *(ptrd++) = ((unsigned char)((*(data1++) - _min)*mm)&M) | (G>>3); - } - } - if (ndata!=_data) { - _render_resize(ndata,img._width,img._height,(unsigned short*)_data,_width,_height); - delete[] ndata; - } - } break; - default : { // 24 bits colors, with normalization - unsigned int *const ndata = (img._width==_width && img._height==_height)?(unsigned int*)_data: - new unsigned int[(size_t)img._width*img._height]; - if (sizeof(int)==4) { // 32 bits int uses optimized version - unsigned int *ptrd = ndata; - switch (img._spectrum) { - case 1 : - if (cimg::X11_attr().byte_order==cimg::endianness()) - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char val = (unsigned char)((*(data1++) - _min)*mm); - *(ptrd++) = (val<<16) | (val<<8) | val; - } - else - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char val = (unsigned char)((*(data1++) - _min)*mm); - *(ptrd++) = (val<<24) | (val<<16) | (val<<8); - } - break; - case 2 : - if (cimg::X11_attr().byte_order==cimg::endianness()) - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) - *(ptrd++) = - ((unsigned char)((*(data1++) - _min)*mm)<<16) | - ((unsigned char)((*(data2++) - _min)*mm)<<8); - else - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) - *(ptrd++) = - ((unsigned char)((*(data2++) - _min)*mm)<<16) | - ((unsigned char)((*(data1++) - _min)*mm)<<8); - break; - default : - if (cimg::X11_attr().byte_order==cimg::endianness()) - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) - *(ptrd++) = - ((unsigned char)((*(data1++) - _min)*mm)<<16) | - ((unsigned char)((*(data2++) - _min)*mm)<<8) | - (unsigned char)((*(data3++) - _min)*mm); - else - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) - *(ptrd++) = - ((unsigned char)((*(data3++) - _min)*mm)<<24) | - ((unsigned char)((*(data2++) - _min)*mm)<<16) | - ((unsigned char)((*(data1++) - _min)*mm)<<8); - } - } else { - unsigned char *ptrd = (unsigned char*)ndata; - switch (img._spectrum) { - case 1 : - if (cimg::X11_attr().byte_order) - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char val = (unsigned char)((*(data1++) - _min)*mm); - (*ptrd++) = 0; - (*ptrd++) = val; - (*ptrd++) = val; - (*ptrd++) = val; - } else for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char val = (unsigned char)((*(data1++) - _min)*mm); - (*ptrd++) = val; - (*ptrd++) = val; - (*ptrd++) = val; - (*ptrd++) = 0; - } - break; - case 2 : - if (cimg::X11_attr().byte_order) cimg::swap(data1,data2); - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - (*ptrd++) = 0; - (*ptrd++) = (unsigned char)((*(data2++) - _min)*mm); - (*ptrd++) = (unsigned char)((*(data1++) - _min)*mm); - (*ptrd++) = 0; - } - break; - default : - if (cimg::X11_attr().byte_order) - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - (*ptrd++) = 0; - (*ptrd++) = (unsigned char)((*(data1++) - _min)*mm); - (*ptrd++) = (unsigned char)((*(data2++) - _min)*mm); - (*ptrd++) = (unsigned char)((*(data3++) - _min)*mm); - } else for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - (*ptrd++) = (unsigned char)((*(data3++) - _min)*mm); - (*ptrd++) = (unsigned char)((*(data2++) - _min)*mm); - (*ptrd++) = (unsigned char)((*(data1++) - _min)*mm); - (*ptrd++) = 0; - } - } - } - if (ndata!=_data) { - _render_resize(ndata,img._width,img._height,(unsigned int*)_data,_width,_height); - delete[] ndata; - } - } - } - } - cimg_unlock_display(); - return *this; - } - - template - const CImgDisplay& snapshot(CImg& img) const { - if (is_empty()) { img.assign(); return *this; } - const unsigned char *ptrs = (unsigned char*)_data; - img.assign(_width,_height,1,3); - T - *data1 = img.data(0,0,0,0), - *data2 = img.data(0,0,0,1), - *data3 = img.data(0,0,0,2); - if (cimg::X11_attr().is_blue_first) cimg::swap(data1,data3); - switch (cimg::X11_attr().nb_bits) { - case 8 : { - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char val = *(ptrs++); - *(data1++) = (T)(val&0xe0); - *(data2++) = (T)((val&0x1c)<<3); - *(data3++) = (T)(val<<6); - } - } break; - case 16 : { - if (cimg::X11_attr().byte_order) for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char val0 = *(ptrs++), val1 = *(ptrs++); - *(data1++) = (T)(val0&0xf8); - *(data2++) = (T)((val0<<5) | ((val1&0xe0)>>5)); - *(data3++) = (T)(val1<<3); - } else for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned short val0 = *(ptrs++), val1 = *(ptrs++); - *(data1++) = (T)(val1&0xf8); - *(data2++) = (T)((val1<<5) | ((val0&0xe0)>>5)); - *(data3++) = (T)(val0<<3); - } - } break; - default : { - if (cimg::X11_attr().byte_order) for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - ++ptrs; - *(data1++) = (T)*(ptrs++); - *(data2++) = (T)*(ptrs++); - *(data3++) = (T)*(ptrs++); - } else for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - *(data3++) = (T)*(ptrs++); - *(data2++) = (T)*(ptrs++); - *(data1++) = (T)*(ptrs++); - ++ptrs; - } - } - } - return *this; - } - - // Windows-based implementation. - //------------------------------- -#elif cimg_display==2 - - bool _is_mouse_tracked, _is_cursor_visible; - HANDLE _thread, _is_created, _mutex; - HWND _window, _background_window; - CLIENTCREATESTRUCT _ccs; - unsigned int *_data; - DEVMODE _curr_mode; - BITMAPINFO _bmi; - HDC _hdc; - - static int screen_width() { - DEVMODE mode; - mode.dmSize = sizeof(DEVMODE); - mode.dmDriverExtra = 0; - EnumDisplaySettings(0,ENUM_CURRENT_SETTINGS,&mode); - return (int)mode.dmPelsWidth; - } - - static int screen_height() { - DEVMODE mode; - mode.dmSize = sizeof(DEVMODE); - mode.dmDriverExtra = 0; - EnumDisplaySettings(0,ENUM_CURRENT_SETTINGS,&mode); - return (int)mode.dmPelsHeight; - } - - static void wait_all() { - WaitForSingleObject(cimg::Win32_attr().wait_event,INFINITE); - } - - static LRESULT APIENTRY _handle_events(HWND window, UINT msg, WPARAM wParam, LPARAM lParam) { -#ifdef _WIN64 - CImgDisplay *const disp = (CImgDisplay*)GetWindowLongPtr(window,GWLP_USERDATA); -#else - CImgDisplay *const disp = (CImgDisplay*)GetWindowLong(window,GWL_USERDATA); -#endif - MSG st_msg; - switch (msg) { - case WM_CLOSE : - disp->_mouse_x = disp->_mouse_y = -1; - disp->_window_x = disp->_window_y = 0; - disp->set_button().set_key(0).set_key(0,false)._is_closed = true; - ReleaseMutex(disp->_mutex); - ShowWindow(disp->_window,SW_HIDE); - disp->_is_event = true; - SetEvent(cimg::Win32_attr().wait_event); - return 0; - case WM_SIZE : { - while (PeekMessage(&st_msg,window,WM_SIZE,WM_SIZE,PM_REMOVE)) {} - WaitForSingleObject(disp->_mutex,INFINITE); - const unsigned int nw = LOWORD(lParam),nh = HIWORD(lParam); - if (nw && nh && (nw!=disp->_width || nh!=disp->_height)) { - disp->_window_width = nw; - disp->_window_height = nh; - disp->_mouse_x = disp->_mouse_y = -1; - disp->_is_resized = disp->_is_event = true; - SetEvent(cimg::Win32_attr().wait_event); - } - ReleaseMutex(disp->_mutex); - } break; - case WM_MOVE : { - while (PeekMessage(&st_msg,window,WM_SIZE,WM_SIZE,PM_REMOVE)) {} - WaitForSingleObject(disp->_mutex,INFINITE); - const int nx = (int)(short)(LOWORD(lParam)), ny = (int)(short)(HIWORD(lParam)); - if (nx!=disp->_window_x || ny!=disp->_window_y) { - disp->_window_x = nx; - disp->_window_y = ny; - disp->_is_moved = disp->_is_event = true; - SetEvent(cimg::Win32_attr().wait_event); - } - ReleaseMutex(disp->_mutex); - } break; - case WM_PAINT : - disp->paint(); - cimg::mutex(15); - if (disp->_is_cursor_visible) while (ShowCursor(TRUE)<0); else while (ShowCursor(FALSE)>=0); - cimg::mutex(15,0); - break; - case WM_ERASEBKGND : - // return 0; - break; - case WM_KEYDOWN : - disp->set_key((unsigned int)wParam); - SetEvent(cimg::Win32_attr().wait_event); - break; - case WM_KEYUP : - disp->set_key((unsigned int)wParam,false); - SetEvent(cimg::Win32_attr().wait_event); - break; - case WM_MOUSEMOVE : { - while (PeekMessage(&st_msg,window,WM_MOUSEMOVE,WM_MOUSEMOVE,PM_REMOVE)) {} - disp->_mouse_x = LOWORD(lParam); - disp->_mouse_y = HIWORD(lParam); -#if (_WIN32_WINNT>=0x0400) && !defined(NOTRACKMOUSEEVENT) - if (!disp->_is_mouse_tracked) { - TRACKMOUSEEVENT tme; - tme.cbSize = sizeof(TRACKMOUSEEVENT); - tme.dwFlags = TME_LEAVE; - tme.hwndTrack = disp->_window; - if (TrackMouseEvent(&tme)) disp->_is_mouse_tracked = true; - } -#endif - if (disp->_mouse_x<0 || disp->_mouse_y<0 || disp->_mouse_x>=disp->width() || disp->_mouse_y>=disp->height()) - disp->_mouse_x = disp->_mouse_y = -1; - disp->_is_event = true; - SetEvent(cimg::Win32_attr().wait_event); - cimg::mutex(15); - if (disp->_is_cursor_visible) while (ShowCursor(TRUE)<0); else while (ShowCursor(FALSE)>=0); - cimg::mutex(15,0); - } break; - case WM_MOUSELEAVE : { - disp->_mouse_x = disp->_mouse_y = -1; - disp->_is_mouse_tracked = false; - cimg::mutex(15); - while (ShowCursor(TRUE)<0); - cimg::mutex(15,0); - } break; - case WM_LBUTTONDOWN : - disp->set_button(1); - SetEvent(cimg::Win32_attr().wait_event); - break; - case WM_RBUTTONDOWN : - disp->set_button(2); - SetEvent(cimg::Win32_attr().wait_event); - break; - case WM_MBUTTONDOWN : - disp->set_button(3); - SetEvent(cimg::Win32_attr().wait_event); - break; - case WM_LBUTTONUP : - disp->set_button(1,false); - SetEvent(cimg::Win32_attr().wait_event); - break; - case WM_RBUTTONUP : - disp->set_button(2,false); - SetEvent(cimg::Win32_attr().wait_event); - break; - case WM_MBUTTONUP : - disp->set_button(3,false); - SetEvent(cimg::Win32_attr().wait_event); - break; - case 0x020A : // WM_MOUSEWHEEL: - disp->set_wheel((int)((short)HIWORD(wParam))/120); - SetEvent(cimg::Win32_attr().wait_event); - } - return DefWindowProc(window,msg,wParam,lParam); - } - - static DWORD WINAPI _events_thread(void* arg) { - CImgDisplay *const disp = (CImgDisplay*)(((void**)arg)[0]); - const char *const title = (const char*)(((void**)arg)[1]); - MSG msg; - delete[] (void**)arg; - disp->_bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - disp->_bmi.bmiHeader.biWidth = disp->width(); - disp->_bmi.bmiHeader.biHeight = -disp->height(); - disp->_bmi.bmiHeader.biPlanes = 1; - disp->_bmi.bmiHeader.biBitCount = 32; - disp->_bmi.bmiHeader.biCompression = BI_RGB; - disp->_bmi.bmiHeader.biSizeImage = 0; - disp->_bmi.bmiHeader.biXPelsPerMeter = 1; - disp->_bmi.bmiHeader.biYPelsPerMeter = 1; - disp->_bmi.bmiHeader.biClrUsed = 0; - disp->_bmi.bmiHeader.biClrImportant = 0; - disp->_data = new unsigned int[(size_t)disp->_width*disp->_height]; - if (!disp->_is_fullscreen) { // Normal window - RECT rect; - rect.left = rect.top = 0; rect.right = (LONG)disp->_width - 1; rect.bottom = (LONG)disp->_height - 1; - AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,false); - const int - border1 = (int)((rect.right - rect.left + 1 - disp->_width)/2), - border2 = (int)(rect.bottom - rect.top + 1 - disp->_height - border1); - disp->_window = CreateWindowA("MDICLIENT",title?title:" ", - WS_OVERLAPPEDWINDOW | (disp->_is_closed?0:WS_VISIBLE), CW_USEDEFAULT,CW_USEDEFAULT, - disp->_width + 2*border1, disp->_height + border1 + border2, - 0,0,0,&(disp->_ccs)); - if (!disp->_is_closed) { - GetWindowRect(disp->_window,&rect); - disp->_window_x = rect.left + border1; - disp->_window_y = rect.top + border2; - } else disp->_window_x = disp->_window_y = 0; - } else { // Fullscreen window - const unsigned int - sx = (unsigned int)screen_width(), - sy = (unsigned int)screen_height(); - disp->_window = CreateWindowA("MDICLIENT",title?title:" ", - WS_POPUP | (disp->_is_closed?0:WS_VISIBLE), - (sx - disp->_width)/2, - (sy - disp->_height)/2, - disp->_width,disp->_height,0,0,0,&(disp->_ccs)); - disp->_window_x = disp->_window_y = 0; - } - SetForegroundWindow(disp->_window); - disp->_hdc = GetDC(disp->_window); - disp->_window_width = disp->_width; - disp->_window_height = disp->_height; - disp->flush(); -#ifdef _WIN64 - SetWindowLongPtr(disp->_window,GWLP_USERDATA,(LONG_PTR)disp); - SetWindowLongPtr(disp->_window,GWLP_WNDPROC,(LONG_PTR)_handle_events); -#else - SetWindowLong(disp->_window,GWL_USERDATA,(LONG)disp); - SetWindowLong(disp->_window,GWL_WNDPROC,(LONG)_handle_events); -#endif - SetEvent(disp->_is_created); - while (GetMessage(&msg,0,0,0)) DispatchMessage(&msg); - return 0; - } - - CImgDisplay& _update_window_pos() { - if (_is_closed) _window_x = _window_y = -1; - else { - RECT rect; - rect.left = rect.top = 0; rect.right = (LONG)_width - 1; rect.bottom = (LONG)_height - 1; - AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,false); - const int - border1 = (int)((rect.right - rect.left + 1 - _width)/2), - border2 = (int)(rect.bottom - rect.top + 1 - _height - border1); - GetWindowRect(_window,&rect); - _window_x = rect.left + border1; - _window_y = rect.top + border2; - } - return *this; - } - - void _init_fullscreen() { - _background_window = 0; - if (!_is_fullscreen || _is_closed) _curr_mode.dmSize = 0; - else { - DEVMODE mode; - unsigned int imode = 0, ibest = 0, bestbpp = 0, bw = ~0U, bh = ~0U; - for (mode.dmSize = sizeof(DEVMODE), mode.dmDriverExtra = 0; EnumDisplaySettings(0,imode,&mode); ++imode) { - const unsigned int nw = mode.dmPelsWidth, nh = mode.dmPelsHeight; - if (nw>=_width && nh>=_height && mode.dmBitsPerPel>=bestbpp && nw<=bw && nh<=bh) { - bestbpp = mode.dmBitsPerPel; - ibest = imode; - bw = nw; bh = nh; - } - } - if (bestbpp) { - _curr_mode.dmSize = sizeof(DEVMODE); _curr_mode.dmDriverExtra = 0; - EnumDisplaySettings(0,ENUM_CURRENT_SETTINGS,&_curr_mode); - EnumDisplaySettings(0,ibest,&mode); - ChangeDisplaySettings(&mode,0); - } else _curr_mode.dmSize = 0; - - const unsigned int - sx = (unsigned int)screen_width(), - sy = (unsigned int)screen_height(); - if (sx!=_width || sy!=_height) { - CLIENTCREATESTRUCT background_ccs; - _background_window = CreateWindowA("MDICLIENT","",WS_POPUP | WS_VISIBLE, 0,0,sx,sy,0,0,0,&background_ccs); - SetForegroundWindow(_background_window); - } - } - } - - void _desinit_fullscreen() { - if (!_is_fullscreen) return; - if (_background_window) DestroyWindow(_background_window); - _background_window = 0; - if (_curr_mode.dmSize) ChangeDisplaySettings(&_curr_mode,0); - _is_fullscreen = false; - } - - CImgDisplay& _assign(const unsigned int dimw, const unsigned int dimh, const char *const ptitle=0, - const unsigned int normalization_type=3, - const bool fullscreen_flag=false, const bool closed_flag=false) { - - // Allocate space for window title - const char *const nptitle = ptitle?ptitle:""; - const unsigned int s = (unsigned int)std::strlen(nptitle) + 1; - char *const tmp_title = s?new char[s]:0; - if (s) std::memcpy(tmp_title,nptitle,s*sizeof(char)); - - // Destroy previous window if existing - if (!is_empty()) assign(); - - // Set display variables - _width = cimg::min(dimw,(unsigned int)screen_width()); - _height = cimg::min(dimh,(unsigned int)screen_height()); - _normalization = normalization_type<4?normalization_type:3; - _is_fullscreen = fullscreen_flag; - _window_x = _window_y = 0; - _is_closed = closed_flag; - _is_cursor_visible = true; - _is_mouse_tracked = false; - _title = tmp_title; - flush(); - if (_is_fullscreen) _init_fullscreen(); - - // Create event thread - void *const arg = (void*)(new void*[2]); - ((void**)arg)[0] = (void*)this; - ((void**)arg)[1] = (void*)_title; - _mutex = CreateMutex(0,FALSE,0); - _is_created = CreateEvent(0,FALSE,FALSE,0); - _thread = CreateThread(0,0,_events_thread,arg,0,0); - WaitForSingleObject(_is_created,INFINITE); - return *this; - } - - CImgDisplay& assign() { - if (is_empty()) return flush(); - DestroyWindow(_window); - TerminateThread(_thread,0); - delete[] _data; - delete[] _title; - _data = 0; - _title = 0; - if (_is_fullscreen) _desinit_fullscreen(); - _width = _height = _normalization = _window_width = _window_height = 0; - _window_x = _window_y = 0; - _is_fullscreen = false; - _is_closed = true; - _min = _max = 0; - _title = 0; - flush(); - return *this; - } - - CImgDisplay& assign(const unsigned int dimw, const unsigned int dimh, const char *const title=0, - const unsigned int normalization_type=3, - const bool fullscreen_flag=false, const bool closed_flag=false) { - if (!dimw || !dimh) return assign(); - _assign(dimw,dimh,title,normalization_type,fullscreen_flag,closed_flag); - _min = _max = 0; - std::memset(_data,0,sizeof(unsigned int)*_width*_height); - return paint(); - } - - template - CImgDisplay& assign(const CImg& img, const char *const title=0, - const unsigned int normalization_type=3, - const bool fullscreen_flag=false, const bool closed_flag=false) { - if (!img) return assign(); - CImg tmp; - const CImg& nimg = (img._depth==1)?img:(tmp=img.get_projections2d((img._width - 1)/2, - (img._height - 1)/2, - (img._depth - 1)/2)); - _assign(nimg._width,nimg._height,title,normalization_type,fullscreen_flag,closed_flag); - if (_normalization==2) _min = (float)nimg.min_max(_max); - return display(nimg); - } - - template - CImgDisplay& assign(const CImgList& list, const char *const title=0, - const unsigned int normalization_type=3, - const bool fullscreen_flag=false, const bool closed_flag=false) { - if (!list) return assign(); - CImg tmp; - const CImg img = list>'x', &nimg = (img._depth==1)?img:(tmp=img.get_projections2d((img._width - 1)/2, - (img._height - 1)/2, - (img._depth - 1)/2)); - _assign(nimg._width,nimg._height,title,normalization_type,fullscreen_flag,closed_flag); - if (_normalization==2) _min = (float)nimg.min_max(_max); - return display(nimg); - } - - CImgDisplay& assign(const CImgDisplay& disp) { - if (!disp) return assign(); - _assign(disp._width,disp._height,disp._title,disp._normalization,disp._is_fullscreen,disp._is_closed); - std::memcpy(_data,disp._data,sizeof(unsigned int)*_width*_height); - return paint(); - } - - CImgDisplay& resize(const int nwidth, const int nheight, const bool force_redraw=true) { - if (!nwidth || !nheight || (is_empty() && (nwidth<0 || nheight<0))) return assign(); - if (is_empty()) return assign(nwidth,nheight); - const unsigned int - tmpdimx = (nwidth>0)?nwidth:(-nwidth*_width/100), - tmpdimy = (nheight>0)?nheight:(-nheight*_height/100), - dimx = tmpdimx?tmpdimx:1, - dimy = tmpdimy?tmpdimy:1; - if (_width!=dimx || _height!=dimy || _window_width!=dimx || _window_height!=dimy) { - if (_window_width!=dimx || _window_height!=dimy) { - RECT rect; rect.left = rect.top = 0; rect.right = (LONG)dimx - 1; rect.bottom = (LONG)dimy - 1; - AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,false); - const int cwidth = rect.right - rect.left + 1, cheight = rect.bottom - rect.top + 1; - SetWindowPos(_window,0,0,0,cwidth,cheight,SWP_NOMOVE | SWP_NOZORDER | SWP_NOCOPYBITS); - } - if (_width!=dimx || _height!=dimy) { - unsigned int *const ndata = new unsigned int[dimx*dimy]; - if (force_redraw) _render_resize(_data,_width,_height,ndata,dimx,dimy); - else std::memset(ndata,0x80,sizeof(unsigned int)*dimx*dimy); - delete[] _data; - _data = ndata; - _bmi.bmiHeader.biWidth = (LONG)dimx; - _bmi.bmiHeader.biHeight = -(int)dimy; - _width = dimx; - _height = dimy; - } - _window_width = dimx; _window_height = dimy; - show(); - } - _is_resized = false; - if (_is_fullscreen) move((screen_width() - width())/2,(screen_height() - height())/2); - if (force_redraw) return paint(); - return *this; - } - - CImgDisplay& toggle_fullscreen(const bool force_redraw=true) { - if (is_empty()) return *this; - if (force_redraw) { - const cimg_ulong buf_size = (cimg_ulong)_width*_height*4; - void *odata = std::malloc(buf_size); - if (odata) { - std::memcpy(odata,_data,buf_size); - assign(_width,_height,_title,_normalization,!_is_fullscreen,false); - std::memcpy(_data,odata,buf_size); - std::free(odata); - } - return paint(); - } - return assign(_width,_height,_title,_normalization,!_is_fullscreen,false); - } - - CImgDisplay& show() { - if (is_empty() || !_is_closed) return *this; - _is_closed = false; - if (_is_fullscreen) _init_fullscreen(); - ShowWindow(_window,SW_SHOW); - _update_window_pos(); - return paint(); - } - - CImgDisplay& close() { - if (is_empty() || _is_closed) return *this; - _is_closed = true; - if (_is_fullscreen) _desinit_fullscreen(); - ShowWindow(_window,SW_HIDE); - _window_x = _window_y = 0; - return *this; - } - - CImgDisplay& move(const int posx, const int posy) { - if (is_empty()) return *this; - if (_window_x!=posx || _window_y!=posy) { - if (!_is_fullscreen) { - RECT rect; - rect.left = rect.top = 0; rect.right = (LONG)_window_width - 1; rect.bottom = (LONG)_window_height - 1; - AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,false); - const int - border1 = (int)((rect.right - rect.left + 1 -_width)/2), - border2 = (int)(rect.bottom - rect.top + 1 - _height - border1); - SetWindowPos(_window,0,posx - border1,posy - border2,0,0,SWP_NOSIZE | SWP_NOZORDER); - } else SetWindowPos(_window,0,posx,posy,0,0,SWP_NOSIZE | SWP_NOZORDER); - _window_x = posx; - _window_y = posy; - show(); - } - _is_moved = false; - return *this; - } - - CImgDisplay& show_mouse() { - if (is_empty()) return *this; - _is_cursor_visible = true; - return *this; - } - - CImgDisplay& hide_mouse() { - if (is_empty()) return *this; - _is_cursor_visible = false; - return *this; - } - - CImgDisplay& set_mouse(const int posx, const int posy) { - if (is_empty() || _is_closed || posx<0 || posy<0) return *this; - _update_window_pos(); - const int res = (int)SetCursorPos(_window_x + posx,_window_y + posy); - if (res) { _mouse_x = posx; _mouse_y = posy; } - return *this; - } - - CImgDisplay& set_title(const char *const format, ...) { - if (is_empty()) return *this; - char *const tmp = new char[1024]; - va_list ap; - va_start(ap, format); - cimg_vsnprintf(tmp,1024,format,ap); - va_end(ap); - if (!std::strcmp(_title,tmp)) { delete[] tmp; return *this; } - delete[] _title; - const unsigned int s = (unsigned int)std::strlen(tmp) + 1; - _title = new char[s]; - std::memcpy(_title,tmp,s*sizeof(char)); - SetWindowTextA(_window, tmp); - delete[] tmp; - return *this; - } - - template - CImgDisplay& display(const CImg& img) { - if (!img) - throw CImgArgumentException(_cimgdisplay_instance - "display(): Empty specified image.", - cimgdisplay_instance); - if (is_empty()) return assign(img); - return render(img).paint(); - } - - CImgDisplay& paint() { - if (_is_closed) return *this; - WaitForSingleObject(_mutex,INFINITE); - SetDIBitsToDevice(_hdc,0,0,_width,_height,0,0,0,_height,_data,&_bmi,DIB_RGB_COLORS); - ReleaseMutex(_mutex); - return *this; - } - - template - CImgDisplay& render(const CImg& img) { - if (!img) - throw CImgArgumentException(_cimgdisplay_instance - "render(): Empty specified image.", - cimgdisplay_instance); - - if (is_empty()) return *this; - if (img._depth!=1) return render(img.get_projections2d((img._width - 1)/2,(img._height - 1)/2, - (img._depth - 1)/2)); - - const T - *data1 = img._data, - *data2 = (img._spectrum>=2)?img.data(0,0,0,1):data1, - *data3 = (img._spectrum>=3)?img.data(0,0,0,2):data1; - - WaitForSingleObject(_mutex,INFINITE); - unsigned int - *const ndata = (img._width==_width && img._height==_height)?_data: - new unsigned int[(size_t)img._width*img._height], - *ptrd = ndata; - - if (!_normalization || (_normalization==3 && cimg::type::string()==cimg::type::string())) { - _min = _max = 0; - switch (img._spectrum) { - case 1 : { - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char val = (unsigned char)*(data1++); - *(ptrd++) = (unsigned int)((val<<16) | (val<<8) | val); - } - } break; - case 2 : { - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char - R = (unsigned char)*(data1++), - G = (unsigned char)*(data2++); - *(ptrd++) = (unsigned int)((R<<16) | (G<<8)); - } - } break; - default : { - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char - R = (unsigned char)*(data1++), - G = (unsigned char)*(data2++), - B = (unsigned char)*(data3++); - *(ptrd++) = (unsigned int)((R<<16) | (G<<8) | B); - } - } - } - } else { - if (_normalization==3) { - if (cimg::type::is_float()) _min = (float)img.min_max(_max); - else { _min = (float)cimg::type::min(); _max = (float)cimg::type::max(); } - } else if ((_min>_max) || _normalization==1) _min = (float)img.min_max(_max); - const float delta = _max - _min, mm = 255/(delta?delta:1.0f); - switch (img._spectrum) { - case 1 : { - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char val = (unsigned char)((*(data1++) - _min)*mm); - *(ptrd++) = (unsigned int)((val<<16) | (val<<8) | val); - } - } break; - case 2 : { - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char - R = (unsigned char)((*(data1++) - _min)*mm), - G = (unsigned char)((*(data2++) - _min)*mm); - *(ptrd++) = (unsigned int)((R<<16) | (G<<8)); - } - } break; - default : { - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned char - R = (unsigned char)((*(data1++) - _min)*mm), - G = (unsigned char)((*(data2++) - _min)*mm), - B = (unsigned char)((*(data3++) - _min)*mm); - *(ptrd++) = (unsigned int)((R<<16) | (G<<8) | B); - } - } - } - } - if (ndata!=_data) { _render_resize(ndata,img._width,img._height,_data,_width,_height); delete[] ndata; } - ReleaseMutex(_mutex); - return *this; - } - - template - const CImgDisplay& snapshot(CImg& img) const { - if (is_empty()) { img.assign(); return *this; } - const unsigned int *ptrs = _data; - img.assign(_width,_height,1,3); - T - *data1 = img.data(0,0,0,0), - *data2 = img.data(0,0,0,1), - *data3 = img.data(0,0,0,2); - for (cimg_ulong xy = (cimg_ulong)img._width*img._height; xy>0; --xy) { - const unsigned int val = *(ptrs++); - *(data1++) = (T)(unsigned char)(val>>16); - *(data2++) = (T)(unsigned char)((val>>8)&0xFF); - *(data3++) = (T)(unsigned char)(val&0xFF); - } - return *this; - } -#endif - - //@} - }; - - /* - #-------------------------------------- - # - # - # - # Definition of the CImg structure - # - # - # - #-------------------------------------- - */ - - //! Class representing an image (up to 4 dimensions wide), each pixel being of type \c T. - /** - This is the main class of the %CImg Library. It declares and constructs - an image, allows access to its pixel values, and is able to perform various image operations. - - \par Image representation - - A %CImg image is defined as an instance of the container \c CImg, which contains a regular grid of pixels, - each pixel value being of type \c T. The image grid can have up to 4 dimensions: width, height, depth - and number of channels. - Usually, the three first dimensions are used to describe spatial coordinates (x,y,z), - while the number of channels is rather used as a vector-valued dimension - (it may describe the R,G,B color channels for instance). - If you need a fifth dimension, you can use image lists \c CImgList rather than simple images \c CImg. - - Thus, the \c CImg class is able to represent volumetric images of vector-valued pixels, - as well as images with less dimensions (1d scalar signal, 2d color images, ...). - Most member functions of the class CImg<\c T> are designed to handle this maximum case of (3+1) dimensions. - - Concerning the pixel value type \c T: - fully supported template types are the basic C++ types: unsigned char, char, short, unsigned int, int, - unsigned long, long, float, double, ... . - Typically, fast image display can be done using CImg images, - while complex image processing algorithms may be rather coded using CImg or CImg - images that have floating-point pixel values. The default value for the template T is \c float. - Using your own template types may be possible. However, you will certainly have to define the complete set - of arithmetic and logical operators for your class. - - \par Image structure - - The \c CImg structure contains \e six fields: - - \c _width defines the number of \a columns of the image (size along the X-axis). - - \c _height defines the number of \a rows of the image (size along the Y-axis). - - \c _depth defines the number of \a slices of the image (size along the Z-axis). - - \c _spectrum defines the number of \a channels of the image (size along the C-axis). - - \c _data defines a \a pointer to the \a pixel \a data (of type \c T). - - \c _is_shared is a boolean that tells if the memory buffer \c data is shared with - another image. - - You can access these fields publicly although it is recommended to use the dedicated functions - width(), height(), depth(), spectrum() and ptr() to do so. - Image dimensions are not limited to a specific range (as long as you got enough available memory). - A value of \e 1 usually means that the corresponding dimension is \a flat. - If one of the dimensions is \e 0, or if the data pointer is null, the image is considered as \e empty. - Empty images should not contain any pixel data and thus, will not be processed by CImg member functions - (a CImgInstanceException will be thrown instead). - Pixel data are stored in memory, in a non interlaced mode (See \ref cimg_storage). - - \par Image declaration and construction - - Declaring an image can be done by using one of the several available constructors. - Here is a list of the most used: - - - Construct images from arbitrary dimensions: - - CImg img; declares an empty image. - - CImg img(128,128); declares a 128x128 greyscale image with - \c unsigned \c char pixel values. - - CImg img(3,3); declares a 3x3 matrix with \c double coefficients. - - CImg img(256,256,1,3); declares a 256x256x1x3 (color) image - (colors are stored as an image with three channels). - - CImg img(128,128,128); declares a 128x128x128 volumetric and greyscale image - (with \c double pixel values). - - CImg<> img(128,128,128,3); declares a 128x128x128 volumetric color image - (with \c float pixels, which is the default value of the template parameter \c T). - - \b Note: images pixels are not automatically initialized to 0. You may use the function \c fill() to - do it, or use the specific constructor taking 5 parameters like this: - CImg<> img(128,128,128,3,0); declares a 128x128x128 volumetric color image with all pixel values to 0. - - - Construct images from filenames: - - CImg img("image.jpg"); reads a JPEG color image from the file "image.jpg". - - CImg img("analyze.hdr"); reads a volumetric image (ANALYZE7.5 format) from the - file "analyze.hdr". - - \b Note: You need to install ImageMagick - to be able to read common compressed image formats (JPG,PNG, ...) (See \ref cimg_files_io). - - - Construct images from C-style arrays: - - CImg img(data_buffer,256,256); constructs a 256x256 greyscale image from a \c int* buffer - \c data_buffer (of size 256x256=65536). - - CImg img(data_buffer,256,256,1,3); constructs a 256x256 color image - from a \c unsigned \c char* buffer \c data_buffer (where R,G,B channels follow each others). - - The complete list of constructors can be found here. - - \par Most useful functions - - The \c CImg class contains a lot of functions that operates on images. - Some of the most useful are: - - - operator()(): Read or write pixel values. - - display(): displays the image in a new window. - **/ - template - struct CImg { - - unsigned int _width, _height, _depth, _spectrum; - bool _is_shared; - T *_data; - - //! Simple iterator type, to loop through each pixel value of an image instance. - /** - \note - - The \c CImg::iterator type is defined to be a T*. - - You will seldom have to use iterators in %CImg, most classical operations - being achieved (often in a faster way) using methods of \c CImg. - \par Example - \code - CImg img("reference.jpg"); // Load image from file. - for (CImg::iterator it = img.begin(), it::const_iterator type is defined to be a \c const \c T*. - - You will seldom have to use iterators in %CImg, most classical operations - being achieved (often in a faster way) using methods of \c CImg. - \par Example - \code - const CImg img("reference.jpg"); // Load image from file. - float sum = 0; - for (CImg::iterator it = img.begin(), it::value_type type of a \c CImg is defined to be a \c T. - - \c CImg::value_type is actually not used in %CImg methods. It has been mainly defined for - compatibility with STL naming conventions. - **/ - typedef T value_type; - - // Define common types related to template type T. - typedef typename cimg::superset::type Tbool; - typedef typename cimg::superset::type Tuchar; - typedef typename cimg::superset::type Tchar; - typedef typename cimg::superset::type Tushort; - typedef typename cimg::superset::type Tshort; - typedef typename cimg::superset::type Tuint; - typedef typename cimg::superset::type Tint; - typedef typename cimg::superset::type Tulong; - typedef typename cimg::superset::type Tlong; - typedef typename cimg::superset::type Tfloat; - typedef typename cimg::superset::type Tdouble; - typedef typename cimg::last::type boolT; - typedef typename cimg::last::type ucharT; - typedef typename cimg::last::type charT; - typedef typename cimg::last::type ushortT; - typedef typename cimg::last::type shortT; - typedef typename cimg::last::type uintT; - typedef typename cimg::last::type intT; - typedef typename cimg::last::type ulongT; - typedef typename cimg::last::type longT; - typedef typename cimg::last::type uint64T; - typedef typename cimg::last::type int64T; - typedef typename cimg::last::type floatT; - typedef typename cimg::last::type doubleT; - - //@} - //--------------------------- - // - //! \name Plugins - //@{ - //--------------------------- -#ifdef cimg_plugin -#include cimg_plugin -#endif -#ifdef cimg_plugin1 -#include cimg_plugin1 -#endif -#ifdef cimg_plugin2 -#include cimg_plugin2 -#endif -#ifdef cimg_plugin3 -#include cimg_plugin3 -#endif -#ifdef cimg_plugin4 -#include cimg_plugin4 -#endif -#ifdef cimg_plugin5 -#include cimg_plugin5 -#endif -#ifdef cimg_plugin6 -#include cimg_plugin6 -#endif -#ifdef cimg_plugin7 -#include cimg_plugin7 -#endif -#ifdef cimg_plugin8 -#include cimg_plugin8 -#endif - - //@} - //--------------------------------------------------------- - // - //! \name Constructors / Destructor / Instance Management - //@{ - //--------------------------------------------------------- - - //! Destroy image. - /** - \note - - The pixel buffer data() is deallocated if necessary, e.g. for non-empty and non-shared image instances. - - Destroying an empty or shared image does nothing actually. - \warning - - When destroying a non-shared image, make sure that you will \e not operate on a remaining shared image - that shares its buffer with the destroyed instance, in order to avoid further invalid memory access - (to a deallocated buffer). - **/ - ~CImg() { - if (!_is_shared) delete[] _data; - } - - //! Construct empty image. - /** - \note - - An empty image has no pixel data and all of its dimensions width(), height(), depth(), spectrum() - are set to \c 0, as well as its pixel buffer pointer data(). - - An empty image may be re-assigned afterwards, e.g. with the family of - assign(unsigned int,unsigned int,unsigned int,unsigned int) methods, - or by operator=(const CImg&). In all cases, the type of pixels stays \c T. - - An empty image is never shared. - \par Example - \code - CImg img1, img2; // Construct two empty images. - img1.assign(256,256,1,3); // Re-assign 'img1' to be a 256x256x1x3 (color) image. - img2 = img1.get_rand(0,255); // Re-assign 'img2' to be a random-valued version of 'img1'. - img2.assign(); // Re-assign 'img2' to be an empty image again. - \endcode - **/ - CImg():_width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) {} - - //! Construct image with specified size. - /** - \param size_x Image width(). - \param size_y Image height(). - \param size_z Image depth(). - \param size_c Image spectrum() (number of channels). - \note - - It is able to create only \e non-shared images, and allocates thus a pixel buffer data() - for each constructed image instance. - - Setting one dimension \c size_x,\c size_y,\c size_z or \c size_c to \c 0 leads to the construction of - an \e empty image. - - A \c CImgInstanceException is thrown when the pixel buffer cannot be allocated - (e.g. when requested size is too big for available memory). - \warning - - The allocated pixel buffer is \e not filled with a default value, and is likely to contain garbage values. - In order to initialize pixel values during construction (e.g. with \c 0), use constructor - CImg(unsigned int,unsigned int,unsigned int,unsigned int,T) instead. - \par Example - \code - CImg img1(256,256,1,3); // Construct a 256x256x1x3 (color) image, filled with garbage values. - CImg img2(256,256,1,3,0); // Construct a 256x256x1x3 (color) image, filled with value '0'. - \endcode - **/ - explicit CImg(const unsigned int size_x, const unsigned int size_y=1, - const unsigned int size_z=1, const unsigned int size_c=1): - _is_shared(false) { - size_t siz = (size_t)size_x*size_y*size_z*size_c; - if (siz) { - _width = size_x; _height = size_y; _depth = size_z; _spectrum = size_c; - try { _data = new T[siz]; } catch (...) { - _width = _height = _depth = _spectrum = 0; _data = 0; - throw CImgInstanceException(_cimg_instance - "CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).", - cimg_instance, - cimg::strbuffersize(sizeof(T)*size_x*size_y*size_z*size_c), - size_x,size_y,size_z,size_c); - } - } else { _width = _height = _depth = _spectrum = 0; _data = 0; } - } - - //! Construct image with specified size and initialize pixel values. - /** - \param size_x Image width(). - \param size_y Image height(). - \param size_z Image depth(). - \param size_c Image spectrum() (number of channels). - \param value Initialization value. - \note - - Similar to CImg(unsigned int,unsigned int,unsigned int,unsigned int), - but it also fills the pixel buffer with the specified \c value. - \warning - - It cannot be used to construct a vector-valued image and initialize it with \e vector-valued pixels - (e.g. RGB vector, for color images). - For this task, you may use fillC() after construction. - **/ - CImg(const unsigned int size_x, const unsigned int size_y, - const unsigned int size_z, const unsigned int size_c, const T& value): - _is_shared(false) { - const size_t siz = (size_t)size_x*size_y*size_z*size_c; - if (siz) { - _width = size_x; _height = size_y; _depth = size_z; _spectrum = size_c; - try { _data = new T[siz]; } catch (...) { - _width = _height = _depth = _spectrum = 0; _data = 0; - throw CImgInstanceException(_cimg_instance - "CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).", - cimg_instance, - cimg::strbuffersize(sizeof(T)*size_x*size_y*size_z*size_c), - size_x,size_y,size_z,size_c); - } - fill(value); - } else { _width = _height = _depth = _spectrum = 0; _data = 0; } - } - - //! Construct image with specified size and initialize pixel values from a sequence of integers. - /** - Construct a new image instance of size \c size_x x \c size_y x \c size_z x \c size_c, - with pixels of type \c T, and initialize pixel - values from the specified sequence of integers \c value0,\c value1,\c ... - \param size_x Image width(). - \param size_y Image height(). - \param size_z Image depth(). - \param size_c Image spectrum() (number of channels). - \param value0 First value of the initialization sequence (must be an \e integer). - \param value1 Second value of the initialization sequence (must be an \e integer). - \param ... - \note - - Similar to CImg(unsigned int,unsigned int,unsigned int,unsigned int), but it also fills - the pixel buffer with a sequence of specified integer values. - \warning - - You must specify \e exactly \c size_x*\c size_y*\c size_z*\c size_c integers in the initialization sequence. - Otherwise, the constructor may crash or fill your image pixels with garbage. - \par Example - \code - const CImg img(2,2,1,3, // Construct a 2x2 color (RGB) image. - 0,255,0,255, // Set the 4 values for the red component. - 0,0,255,255, // Set the 4 values for the green component. - 64,64,64,64); // Set the 4 values for the blue component. - img.resize(150,150).display(); - \endcode - \image html ref_constructor1.jpg - **/ - CImg(const unsigned int size_x, const unsigned int size_y, const unsigned int size_z, const unsigned int size_c, - const int value0, const int value1, ...): - _width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) { -#define _CImg_stdarg(img,a0,a1,N,t) { \ - size_t _siz = (size_t)N; \ - if (_siz--) { \ - va_list ap; \ - va_start(ap,a1); \ - T *ptrd = (img)._data; \ - *(ptrd++) = (T)a0; \ - if (_siz--) { \ - *(ptrd++) = (T)a1; \ - for ( ; _siz; --_siz) *(ptrd++) = (T)va_arg(ap,t); \ - } \ - va_end(ap); \ - } \ - } - assign(size_x,size_y,size_z,size_c); - _CImg_stdarg(*this,value0,value1,(size_t)size_x*size_y*size_z*size_c,int); - } - -#if defined(cimg_use_cpp11) && cimg_use_cpp11!=0 - //! Construct image with specified size and initialize pixel values from an initializer list of integers. - /** - Construct a new image instance of size \c size_x x \c size_y x \c size_z x \c size_c, - with pixels of type \c T, and initialize pixel - values from the specified initializer list of integers { \c value0,\c value1,\c ... } - \param size_x Image width(). - \param size_y Image height(). - \param size_z Image depth(). - \param size_c Image spectrum() (number of channels). - \param { value0, value1, ... } Initialization list - \param repeat_values Tells if the value filling process is repeated over the image. - - \note - - Similar to CImg(unsigned int,unsigned int,unsigned int,unsigned int), but it also fills - the pixel buffer with a sequence of specified integer values. - \par Example - \code - const CImg img(2,2,1,3, // Construct a 2x2 color (RGB) image. - { 0,255,0,255, // Set the 4 values for the red component. - 0,0,255,255, // Set the 4 values for the green component. - 64,64,64,64 }); // Set the 4 values for the blue component. - img.resize(150,150).display(); - \endcode - \image html ref_constructor1.jpg - **/ - template - CImg(const unsigned int size_x, const unsigned int size_y, const unsigned int size_z, const unsigned int size_c, - const std::initializer_list values, - const bool repeat_values=true): - _width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) { -#define _cimg_constructor_cpp11(repeat_values) \ - auto it = values.begin(); \ - size_t siz = size(); \ - if (repeat_values) for (T *ptrd = _data; siz--; ) { \ - *(ptrd++) = (T)(*(it++)); if (it==values.end()) it = values.begin(); } \ - else { siz = cimg::min(siz,values.size()); for (T *ptrd = _data; siz--; ) *(ptrd++) = (T)(*(it++)); } - assign(size_x,size_y,size_z,size_c); - _cimg_constructor_cpp11(repeat_values); - } - - template - CImg(const unsigned int size_x, const unsigned int size_y, const unsigned int size_z, - std::initializer_list values, - const bool repeat_values=true): - _width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) { - assign(size_x,size_y,size_z); - _cimg_constructor_cpp11(repeat_values); - } - - template - CImg(const unsigned int size_x, const unsigned int size_y, - std::initializer_list values, - const bool repeat_values=true): - _width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) { - assign(size_x,size_y); - _cimg_constructor_cpp11(repeat_values); - } - - template - CImg(const unsigned int size_x, - std::initializer_list values, - const bool repeat_values=true):_width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) { - assign(size_x); - _cimg_constructor_cpp11(repeat_values); - } - - //! Construct single channel 1D image with pixel values and width obtained from an initializer list of integers. - /** - Construct a new image instance of size \c width x \c 1 x \c 1 x \c 1, - with pixels of type \c T, and initialize pixel - values from the specified initializer list of integers { \c value0,\c value1,\c ... }. Image width is - given by the size of the initializer list. - \param { value0, value1, ... } Initialization list - \note - - Similar to CImg(unsigned int,unsigned int,unsigned int,unsigned int) with height=1, depth=1, and spectrum=1, - but it also fills the pixel buffer with a sequence of specified integer values. - \par Example - \code - const CImg img = {10,20,30,20,10 }; // Construct a 5x1 image with one channel, and set its pixel values. - img.resize(150,150).display(); - \endcode - \image html ref_constructor1.jpg - **/ - template - CImg(const std::initializer_list values): - _width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) { - assign(values.size(),1,1,1); - auto it = values.begin(); - unsigned int siz = _width; - for (T *ptrd = _data; siz--; ) *(ptrd++) = (T)(*(it++)); - } - - template - CImg & operator=(std::initializer_list values) { - _cimg_constructor_cpp11(siz>values.size()); - return *this; - } -#endif - - //! Construct image with specified size and initialize pixel values from a sequence of doubles. - /** - Construct a new image instance of size \c size_x x \c size_y x \c size_z x \c size_c, with pixels of type \c T, - and initialize pixel values from the specified sequence of doubles \c value0,\c value1,\c ... - \param size_x Image width(). - \param size_y Image height(). - \param size_z Image depth(). - \param size_c Image spectrum() (number of channels). - \param value0 First value of the initialization sequence (must be a \e double). - \param value1 Second value of the initialization sequence (must be a \e double). - \param ... - \note - - Similar to CImg(unsigned int,unsigned int,unsigned int,unsigned int,int,int,...), but - takes a sequence of double values instead of integers. - \warning - - You must specify \e exactly \c dx*\c dy*\c dz*\c dc doubles in the initialization sequence. - Otherwise, the constructor may crash or fill your image with garbage. - For instance, the code below will probably crash on most platforms: - \code - const CImg img(2,2,1,1, 0.5,0.5,255,255); // FAIL: The two last arguments are 'int', not 'double'! - \endcode - **/ - CImg(const unsigned int size_x, const unsigned int size_y, const unsigned int size_z, const unsigned int size_c, - const double value0, const double value1, ...): - _width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) { - assign(size_x,size_y,size_z,size_c); - _CImg_stdarg(*this,value0,value1,(size_t)size_x*size_y*size_z*size_c,double); - } - - //! Construct image with specified size and initialize pixel values from a value string. - /** - Construct a new image instance of size \c size_x x \c size_y x \c size_z x \c size_c, with pixels of type \c T, - and initializes pixel values from the specified string \c values. - \param size_x Image width(). - \param size_y Image height(). - \param size_z Image depth(). - \param size_c Image spectrum() (number of channels). - \param values Value string describing the way pixel values are set. - \param repeat_values Tells if the value filling process is repeated over the image. - \note - - Similar to CImg(unsigned int,unsigned int,unsigned int,unsigned int), but it also fills - the pixel buffer with values described in the value string \c values. - - Value string \c values may describe two different filling processes: - - Either \c values is a sequences of values assigned to the image pixels, as in "1,2,3,7,8,2". - In this case, set \c repeat_values to \c true to periodically fill the image with the value sequence. - - Either, \c values is a formula, as in "cos(x/10)*sin(y/20)". - In this case, parameter \c repeat_values is pointless. - - For both cases, specifying \c repeat_values is mandatory. - It disambiguates the possible overloading of constructor - CImg(unsigned int,unsigned int,unsigned int,unsigned int,T) with \c T being a const char*. - - A \c CImgArgumentException is thrown when an invalid value string \c values is specified. - \par Example - \code - const CImg img1(129,129,1,3,"0,64,128,192,255",true), // Construct image filled from a value sequence. - img2(129,129,1,3,"if(c==0,255*abs(cos(x/10)),1.8*y)",false); // Construct image filled from a formula. - (img1,img2).display(); - \endcode - \image html ref_constructor2.jpg - **/ - CImg(const unsigned int size_x, const unsigned int size_y, const unsigned int size_z, const unsigned int size_c, - const char *const values, const bool repeat_values):_is_shared(false) { - const size_t siz = (size_t)size_x*size_y*size_z*size_c; - if (siz) { - _width = size_x; _height = size_y; _depth = size_z; _spectrum = size_c; - try { _data = new T[siz]; } catch (...) { - _width = _height = _depth = _spectrum = 0; _data = 0; - throw CImgInstanceException(_cimg_instance - "CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).", - cimg_instance, - cimg::strbuffersize(sizeof(T)*size_x*size_y*size_z*size_c), - size_x,size_y,size_z,size_c); - } - fill(values,repeat_values); - } else { _width = _height = _depth = _spectrum = 0; _data = 0; } - } - - //! Construct image with specified size and initialize pixel values from a memory buffer. - /** - Construct a new image instance of size \c size_x x \c size_y x \c size_z x \c size_c, with pixels of type \c T, - and initializes pixel values from the specified \c t* memory buffer. - \param values Pointer to the input memory buffer. - \param size_x Image width(). - \param size_y Image height(). - \param size_z Image depth(). - \param size_c Image spectrum() (number of channels). - \param is_shared Tells if input memory buffer must be shared by the current instance. - \note - - If \c is_shared is \c false, the image instance allocates its own pixel buffer, - and values from the specified input buffer are copied to the instance buffer. - If buffer types \c T and \c t are different, a regular static cast is performed during buffer copy. - - Otherwise, the image instance does \e not allocate a new buffer, and uses the input memory buffer as its - own pixel buffer. This case requires that types \c T and \c t are the same. Later, destroying such a shared - image will not deallocate the pixel buffer, this task being obviously charged to the initial buffer allocator. - - A \c CImgInstanceException is thrown when the pixel buffer cannot be allocated - (e.g. when requested size is too big for available memory). - \warning - - You must take care when operating on a shared image, since it may have an invalid pixel buffer pointer data() - (e.g. already deallocated). - \par Example - \code - unsigned char tab[256*256] = { 0 }; - CImg img1(tab,256,256,1,1,false), // Construct new non-shared image from buffer 'tab'. - img2(tab,256,256,1,1,true); // Construct new shared-image from buffer 'tab'. - tab[1024] = 255; // Here, 'img2' is indirectly modified, but not 'img1'. - \endcode - **/ - template - CImg(const t *const values, const unsigned int size_x, const unsigned int size_y=1, - const unsigned int size_z=1, const unsigned int size_c=1, const bool is_shared=false):_is_shared(false) { - if (is_shared) { - _width = _height = _depth = _spectrum = 0; _data = 0; - throw CImgArgumentException(_cimg_instance - "CImg(): Invalid construction request of a (%u,%u,%u,%u) shared instance " - "from a (%s*) buffer (pixel types are different).", - cimg_instance, - size_x,size_y,size_z,size_c,CImg::pixel_type()); - } - const size_t siz = (size_t)size_x*size_y*size_z*size_c; - if (values && siz) { - _width = size_x; _height = size_y; _depth = size_z; _spectrum = size_c; - try { _data = new T[siz]; } catch (...) { - _width = _height = _depth = _spectrum = 0; _data = 0; - throw CImgInstanceException(_cimg_instance - "CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).", - cimg_instance, - cimg::strbuffersize(sizeof(T)*size_x*size_y*size_z*size_c), - size_x,size_y,size_z,size_c); - - } - const t *ptrs = values; cimg_for(*this,ptrd,T) *ptrd = (T)*(ptrs++); - } else { _width = _height = _depth = _spectrum = 0; _data = 0; } - } - - //! Construct image with specified size and initialize pixel values from a memory buffer \specialization. - CImg(const T *const values, const unsigned int size_x, const unsigned int size_y=1, - const unsigned int size_z=1, const unsigned int size_c=1, const bool is_shared=false) { - const size_t siz = (size_t)size_x*size_y*size_z*size_c; - if (values && siz) { - _width = size_x; _height = size_y; _depth = size_z; _spectrum = size_c; _is_shared = is_shared; - if (_is_shared) _data = const_cast(values); - else { - try { _data = new T[siz]; } catch (...) { - _width = _height = _depth = _spectrum = 0; _data = 0; - throw CImgInstanceException(_cimg_instance - "CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).", - cimg_instance, - cimg::strbuffersize(sizeof(T)*size_x*size_y*size_z*size_c), - size_x,size_y,size_z,size_c); - } - std::memcpy(_data,values,siz*sizeof(T)); - } - } else { _width = _height = _depth = _spectrum = 0; _is_shared = false; _data = 0; } - } - - //! Construct image from reading an image file. - /** - Construct a new image instance with pixels of type \c T, and initialize pixel values with the data read from - an image file. - \param filename Filename, as a C-string. - \note - - Similar to CImg(unsigned int,unsigned int,unsigned int,unsigned int), but it reads the image - dimensions and pixel values from the specified image file. - - The recognition of the image file format by %CImg higly depends on the tools installed on your system - and on the external libraries you used to link your code against. - - Considered pixel type \c T should better fit the file format specification, or data loss may occur during - file load (e.g. constructing a \c CImg from a float-valued image file). - - A \c CImgIOException is thrown when the specified \c filename cannot be read, or if the file format is not - recognized. - \par Example - \code - const CImg img("reference.jpg"); - img.display(); - \endcode - \image html ref_image.jpg - **/ - explicit CImg(const char *const filename):_width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) { - assign(filename); - } - - //! Construct image copy. - /** - Construct a new image instance with pixels of type \c T, as a copy of an existing \c CImg instance. - \param img Input image to copy. - \note - - Constructed copy has the same size width() x height() x depth() x spectrum() and pixel values as the - input image \c img. - - If input image \c img is \e shared and if types \c T and \c t are the same, the constructed copy is also - \e shared, and shares its pixel buffer with \c img. - Modifying a pixel value in the constructed copy will thus also modifies it in the input image \c img. - This behavior is needful to allow functions to return shared images. - - Otherwise, the constructed copy allocates its own pixel buffer, and copies pixel values from the input - image \c img into its buffer. The copied pixel values may be eventually statically casted if types \c T and - \c t are different. - - Constructing a copy from an image \c img when types \c t and \c T are the same is significantly faster than - with different types. - - A \c CImgInstanceException is thrown when the pixel buffer cannot be allocated - (e.g. not enough available memory). - **/ - template - CImg(const CImg& img):_is_shared(false) { - const size_t siz = (size_t)img.size(); - if (img._data && siz) { - _width = img._width; _height = img._height; _depth = img._depth; _spectrum = img._spectrum; - try { _data = new T[siz]; } catch (...) { - _width = _height = _depth = _spectrum = 0; _data = 0; - throw CImgInstanceException(_cimg_instance - "CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).", - cimg_instance, - cimg::strbuffersize(sizeof(T)*img._width*img._height*img._depth*img._spectrum), - img._width,img._height,img._depth,img._spectrum); - } - const t *ptrs = img._data; cimg_for(*this,ptrd,T) *ptrd = (T)*(ptrs++); - } else { _width = _height = _depth = _spectrum = 0; _data = 0; } - } - - //! Construct image copy \specialization. - CImg(const CImg& img) { - const size_t siz = (size_t)img.size(); - if (img._data && siz) { - _width = img._width; _height = img._height; _depth = img._depth; _spectrum = img._spectrum; - _is_shared = img._is_shared; - if (_is_shared) _data = const_cast(img._data); - else { - try { _data = new T[siz]; } catch (...) { - _width = _height = _depth = _spectrum = 0; _data = 0; - throw CImgInstanceException(_cimg_instance - "CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).", - cimg_instance, - cimg::strbuffersize(sizeof(T)*img._width*img._height*img._depth*img._spectrum), - img._width,img._height,img._depth,img._spectrum); - - } - std::memcpy(_data,img._data,siz*sizeof(T)); - } - } else { _width = _height = _depth = _spectrum = 0; _is_shared = false; _data = 0; } - } - - //! Advanced copy constructor. - /** - Construct a new image instance with pixels of type \c T, as a copy of an existing \c CImg instance, - while forcing the shared state of the constructed copy. - \param img Input image to copy. - \param is_shared Tells about the shared state of the constructed copy. - \note - - Similar to CImg(const CImg&), except that it allows to decide the shared state of - the constructed image, which does not depend anymore on the shared state of the input image \c img: - - If \c is_shared is \c true, the constructed copy will share its pixel buffer with the input image \c img. - For that case, the pixel types \c T and \c t \e must be the same. - - If \c is_shared is \c false, the constructed copy will allocate its own pixel buffer, whether the input - image \c img is shared or not. - - A \c CImgArgumentException is thrown when a shared copy is requested with different pixel types \c T and \c t. - **/ - template - CImg(const CImg& img, const bool is_shared):_is_shared(false) { - if (is_shared) { - _width = _height = _depth = _spectrum = 0; _data = 0; - throw CImgArgumentException(_cimg_instance - "CImg(): Invalid construction request of a shared instance from a " - "CImg<%s> image (%u,%u,%u,%u,%p) (pixel types are different).", - cimg_instance, - CImg::pixel_type(),img._width,img._height,img._depth,img._spectrum,img._data); - } - const size_t siz = (size_t)img.size(); - if (img._data && siz) { - _width = img._width; _height = img._height; _depth = img._depth; _spectrum = img._spectrum; - try { _data = new T[siz]; } catch (...) { - _width = _height = _depth = _spectrum = 0; _data = 0; - throw CImgInstanceException(_cimg_instance - "CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).", - cimg_instance, - cimg::strbuffersize(sizeof(T)*img._width*img._height*img._depth*img._spectrum), - img._width,img._height,img._depth,img._spectrum); - } - const t *ptrs = img._data; cimg_for(*this,ptrd,T) *ptrd = (T)*(ptrs++); - } else { _width = _height = _depth = _spectrum = 0; _data = 0; } - } - - //! Advanced copy constructor \specialization. - CImg(const CImg& img, const bool is_shared) { - const size_t siz = (size_t)img.size(); - if (img._data && siz) { - _width = img._width; _height = img._height; _depth = img._depth; _spectrum = img._spectrum; - _is_shared = is_shared; - if (_is_shared) _data = const_cast(img._data); - else { - try { _data = new T[siz]; } catch (...) { - _width = _height = _depth = _spectrum = 0; _data = 0; - throw CImgInstanceException(_cimg_instance - "CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).", - cimg_instance, - cimg::strbuffersize(sizeof(T)*img._width*img._height*img._depth*img._spectrum), - img._width,img._height,img._depth,img._spectrum); - } - std::memcpy(_data,img._data,siz*sizeof(T)); - } - } else { _width = _height = _depth = _spectrum = 0; _is_shared = false; _data = 0; } - } - - //! Construct image with dimensions borrowed from another image. - /** - Construct a new image instance with pixels of type \c T, and size get from some dimensions of an existing - \c CImg instance. - \param img Input image from which dimensions are borrowed. - \param dimensions C-string describing the image size along the X,Y,Z and C-dimensions. - \note - - Similar to CImg(unsigned int,unsigned int,unsigned int,unsigned int), but it takes the image dimensions - (\e not its pixel values) from an existing \c CImg instance. - - The allocated pixel buffer is \e not filled with a default value, and is likely to contain garbage values. - In order to initialize pixel values (e.g. with \c 0), use constructor CImg(const CImg&,const char*,T) - instead. - \par Example - \code - const CImg img1(256,128,1,3), // 'img1' is a 256x128x1x3 image. - img2(img1,"xyzc"), // 'img2' is a 256x128x1x3 image. - img3(img1,"y,x,z,c"), // 'img3' is a 128x256x1x3 image. - img4(img1,"c,x,y,3",0), // 'img4' is a 3x128x256x3 image (with pixels initialized to '0'). - \endcode - **/ - template - CImg(const CImg& img, const char *const dimensions): - _width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) { - assign(img,dimensions); - } - - //! Construct image with dimensions borrowed from another image and initialize pixel values. - /** - Construct a new image instance with pixels of type \c T, and size get from the dimensions of an existing - \c CImg instance, and set all pixel values to specified \c value. - \param img Input image from which dimensions are borrowed. - \param dimensions String describing the image size along the X,Y,Z and V-dimensions. - \param value Value used for initialization. - \note - - Similar to CImg(const CImg&,const char*), but it also fills the pixel buffer with the specified \c value. - **/ - template - CImg(const CImg& img, const char *const dimensions, const T& value): - _width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) { - assign(img,dimensions).fill(value); - } - - //! Construct image from a display window. - /** - Construct a new image instance with pixels of type \c T, as a snapshot of an existing \c CImgDisplay instance. - \param disp Input display window. - \note - - The width() and height() of the constructed image instance are the same as the specified \c CImgDisplay. - - The depth() and spectrum() of the constructed image instance are respectively set to \c 1 and \c 3 - (i.e. a 2d color image). - - The image pixels are read as 8-bits RGB values. - **/ - explicit CImg(const CImgDisplay &disp):_width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) { - disp.snapshot(*this); - } - - // Constructor and assignment operator for rvalue references (c++11). - // This avoids an additional image copy for methods returning new images. Can save RAM for big images ! -#if defined(cimg_use_cpp11) && cimg_use_cpp11!=0 - CImg(CImg&& img):_width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) { - swap(img); - } - CImg& operator=(CImg&& img) { - if (_is_shared) return assign(img); - return img.swap(*this); - } -#endif - - //! Construct empty image \inplace. - /** - In-place version of the default constructor CImg(). It simply resets the instance to an empty image. - **/ - CImg& assign() { - if (!_is_shared) delete[] _data; - _width = _height = _depth = _spectrum = 0; _is_shared = false; _data = 0; - return *this; - } - - //! Construct image with specified size \inplace. - /** - In-place version of the constructor CImg(unsigned int,unsigned int,unsigned int,unsigned int). - **/ - CImg& assign(const unsigned int size_x, const unsigned int size_y=1, - const unsigned int size_z=1, const unsigned int size_c=1) { - const size_t siz = (size_t)size_x*size_y*size_z*size_c; - if (!siz) return assign(); - const size_t curr_siz = (size_t)size(); - if (siz!=curr_siz) { - if (_is_shared) - throw CImgArgumentException(_cimg_instance - "assign(): Invalid assignement request of shared instance from specified " - "image (%u,%u,%u,%u).", - cimg_instance, - size_x,size_y,size_z,size_c); - else { - delete[] _data; - try { _data = new T[siz]; } catch (...) { - _width = _height = _depth = _spectrum = 0; _data = 0; - throw CImgInstanceException(_cimg_instance - "assign(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).", - cimg_instance, - cimg::strbuffersize(sizeof(T)*size_x*size_y*size_z*size_c), - size_x,size_y,size_z,size_c); - } - } - } - _width = size_x; _height = size_y; _depth = size_z; _spectrum = size_c; - return *this; - } - - //! Construct image with specified size and initialize pixel values \inplace. - /** - In-place version of the constructor CImg(unsigned int,unsigned int,unsigned int,unsigned int,T). - **/ - CImg& assign(const unsigned int size_x, const unsigned int size_y, - const unsigned int size_z, const unsigned int size_c, const T& value) { - return assign(size_x,size_y,size_z,size_c).fill(value); - } - - //! Construct image with specified size and initialize pixel values from a sequence of integers \inplace. - /** - In-place version of the constructor CImg(unsigned int,unsigned int,unsigned int,unsigned int,int,int,...). - **/ - CImg& assign(const unsigned int size_x, const unsigned int size_y, - const unsigned int size_z, const unsigned int size_c, - const int value0, const int value1, ...) { - assign(size_x,size_y,size_z,size_c); - _CImg_stdarg(*this,value0,value1,(size_t)size_x*size_y*size_z*size_c,int); - return *this; - } - - //! Construct image with specified size and initialize pixel values from a sequence of doubles \inplace. - /** - In-place version of the constructor CImg(unsigned int,unsigned int,unsigned int,unsigned int,double,double,...). - **/ - CImg& assign(const unsigned int size_x, const unsigned int size_y, - const unsigned int size_z, const unsigned int size_c, - const double value0, const double value1, ...) { - assign(size_x,size_y,size_z,size_c); - _CImg_stdarg(*this,value0,value1,(size_t)size_x*size_y*size_z*size_c,double); - return *this; - } - - //! Construct image with specified size and initialize pixel values from a value string \inplace. - /** - In-place version of the constructor CImg(unsigned int,unsigned int,unsigned int,unsigned int,const char*,bool). - **/ - CImg& assign(const unsigned int size_x, const unsigned int size_y, - const unsigned int size_z, const unsigned int size_c, - const char *const values, const bool repeat_values) { - return assign(size_x,size_y,size_z,size_c).fill(values,repeat_values); - } - - //! Construct image with specified size and initialize pixel values from a memory buffer \inplace. - /** - In-place version of the constructor CImg(const t*,unsigned int,unsigned int,unsigned int,unsigned int). - **/ - template - CImg& assign(const t *const values, const unsigned int size_x, const unsigned int size_y=1, - const unsigned int size_z=1, const unsigned int size_c=1) { - const size_t siz = (size_t)size_x*size_y*size_z*size_c; - if (!values || !siz) return assign(); - assign(size_x,size_y,size_z,size_c); - const t *ptrs = values; cimg_for(*this,ptrd,T) *ptrd = (T)*(ptrs++); - return *this; - } - - //! Construct image with specified size and initialize pixel values from a memory buffer \specialization. - CImg& assign(const T *const values, const unsigned int size_x, const unsigned int size_y=1, - const unsigned int size_z=1, const unsigned int size_c=1) { - const size_t siz = (size_t)size_x*size_y*size_z*size_c; - if (!values || !siz) return assign(); - const size_t curr_siz = (size_t)size(); - if (values==_data && siz==curr_siz) return assign(size_x,size_y,size_z,size_c); - if (_is_shared || values + siz<_data || values>=_data + size()) { - assign(size_x,size_y,size_z,size_c); - if (_is_shared) std::memmove(_data,values,siz*sizeof(T)); - else std::memcpy(_data,values,siz*sizeof(T)); - } else { - T *new_data = 0; - try { new_data = new T[siz]; } catch (...) { - _width = _height = _depth = _spectrum = 0; _data = 0; - throw CImgInstanceException(_cimg_instance - "assign(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).", - cimg_instance, - cimg::strbuffersize(sizeof(T)*size_x*size_y*size_z*size_c), - size_x,size_y,size_z,size_c); - } - std::memcpy(new_data,values,siz*sizeof(T)); - delete[] _data; _data = new_data; _width = size_x; _height = size_y; _depth = size_z; _spectrum = size_c; - } - return *this; - } - - //! Construct image with specified size and initialize pixel values from a memory buffer \overloading. - template - CImg& assign(const t *const values, const unsigned int size_x, const unsigned int size_y, - const unsigned int size_z, const unsigned int size_c, const bool is_shared) { - if (is_shared) - throw CImgArgumentException(_cimg_instance - "assign(): Invalid assignment request of shared instance from (%s*) buffer" - "(pixel types are different).", - cimg_instance, - CImg::pixel_type()); - return assign(values,size_x,size_y,size_z,size_c); - } - - //! Construct image with specified size and initialize pixel values from a memory buffer \overloading. - CImg& assign(const T *const values, const unsigned int size_x, const unsigned int size_y, - const unsigned int size_z, const unsigned int size_c, const bool is_shared) { - const size_t siz = (size_t)size_x*size_y*size_z*size_c; - if (!values || !siz) return assign(); - if (!is_shared) { if (_is_shared) assign(); assign(values,size_x,size_y,size_z,size_c); } - else { - if (!_is_shared) { - if (values + siz<_data || values>=_data + size()) assign(); - else cimg::warn(_cimg_instance - "assign(): Shared image instance has overlapping memory.", - cimg_instance); - } - _width = size_x; _height = size_y; _depth = size_z; _spectrum = size_c; _is_shared = true; - _data = const_cast(values); - } - return *this; - } - - //! Construct image from reading an image file \inplace. - /** - In-place version of the constructor CImg(const char*). - **/ - CImg& assign(const char *const filename) { - return load(filename); - } - - //! Construct image copy \inplace. - /** - In-place version of the constructor CImg(const CImg&). - **/ - template - CImg& assign(const CImg& img) { - return assign(img._data,img._width,img._height,img._depth,img._spectrum); - } - - //! In-place version of the advanced copy constructor. - /** - In-place version of the constructor CImg(const CImg&,bool). - **/ - template - CImg& assign(const CImg& img, const bool is_shared) { - return assign(img._data,img._width,img._height,img._depth,img._spectrum,is_shared); - } - - //! Construct image with dimensions borrowed from another image \inplace. - /** - In-place version of the constructor CImg(const CImg&,const char*). - **/ - template - CImg& assign(const CImg& img, const char *const dimensions) { - if (!dimensions || !*dimensions) return assign(img._width,img._height,img._depth,img._spectrum); - unsigned int siz[4] = { 0,1,1,1 }, k = 0; - CImg item(256); - for (const char *s = dimensions; *s && k<4; ++k) { - if (cimg_sscanf(s,"%255[^0-9%xyzvwhdcXYZVWHDC]",item._data)>0) s+=std::strlen(item); - if (*s) { - unsigned int val = 0; char sep = 0; - if (cimg_sscanf(s,"%u%c",&val,&sep)>0) { - if (sep=='%') siz[k] = val*(k==0?_width:k==1?_height:k==2?_depth:_spectrum)/100; - else siz[k] = val; - while (*s>='0' && *s<='9') ++s; if (sep=='%') ++s; - } else switch (cimg::lowercase(*s)) { - case 'x' : case 'w' : siz[k] = img._width; ++s; break; - case 'y' : case 'h' : siz[k] = img._height; ++s; break; - case 'z' : case 'd' : siz[k] = img._depth; ++s; break; - case 'c' : case 's' : siz[k] = img._spectrum; ++s; break; - default : - throw CImgArgumentException(_cimg_instance - "assign(): Invalid character '%c' detected in specified dimension string '%s'.", - cimg_instance, - *s,dimensions); - } - } - } - return assign(siz[0],siz[1],siz[2],siz[3]); - } - - //! Construct image with dimensions borrowed from another image and initialize pixel values \inplace. - /** - In-place version of the constructor CImg(const CImg&,const char*,T). - **/ - template - CImg& assign(const CImg& img, const char *const dimensions, const T& value) { - return assign(img,dimensions).fill(value); - } - - //! Construct image from a display window \inplace. - /** - In-place version of the constructor CImg(const CImgDisplay&). - **/ - CImg& assign(const CImgDisplay &disp) { - disp.snapshot(*this); - return *this; - } - - //! Construct empty image \inplace. - /** - Equivalent to assign(). - \note - - It has been defined for compatibility with STL naming conventions. - **/ - CImg& clear() { - return assign(); - } - - //! Transfer content of an image instance into another one. - /** - Transfer the dimensions and the pixel buffer content of an image instance into another one, - and replace instance by an empty image. It avoids the copy of the pixel buffer - when possible. - \param img Destination image. - \note - - Pixel types \c T and \c t of source and destination images can be different, though the process is - designed to be instantaneous when \c T and \c t are the same. - \par Example - \code - CImg src(256,256,1,3,0), // Construct a 256x256x1x3 (color) image filled with value '0'. - dest(16,16); // Construct a 16x16x1x1 (scalar) image. - src.move_to(dest); // Now, 'src' is empty and 'dest' is the 256x256x1x3 image. - \endcode - **/ - template - CImg& move_to(CImg& img) { - img.assign(*this); - assign(); - return img; - } - - //! Transfer content of an image instance into another one \specialization. - CImg& move_to(CImg& img) { - if (_is_shared || img._is_shared) img.assign(*this); - else swap(img); - assign(); - return img; - } - - //! Transfer content of an image instance into a new image in an image list. - /** - Transfer the dimensions and the pixel buffer content of an image instance - into a newly inserted image at position \c pos in specified \c CImgList instance. - \param list Destination list. - \param pos Position of the newly inserted image in the list. - \note - - When optionnal parameter \c pos is ommited, the image instance is transfered as a new - image at the end of the specified \c list. - - It is convenient to sequentially insert new images into image lists, with no - additional copies of memory buffer. - \par Example - \code - CImgList list; // Construct an empty image list. - CImg img("reference.jpg"); // Read image from filename. - img.move_to(list); // Transfer image content as a new item in the list (no buffer copy). - \endcode - **/ - template - CImgList& move_to(CImgList& list, const unsigned int pos=~0U) { - const unsigned int npos = pos>list._width?list._width:pos; - move_to(list.insert(1,npos)[npos]); - return list; - } - - //! Swap fields of two image instances. - /** - \param img Image to swap fields with. - \note - - It can be used to interchange the content of two images in a very fast way. Can be convenient when dealing - with algorithms requiring two swapping buffers. - \par Example - \code - CImg img1("lena.jpg"), - img2("milla.jpg"); - img1.swap(img2); // Now, 'img1' is 'milla' and 'img2' is 'lena'. - \endcode - **/ - CImg& swap(CImg& img) { - cimg::swap(_width,img._width,_height,img._height,_depth,img._depth,_spectrum,img._spectrum); - cimg::swap(_data,img._data); - cimg::swap(_is_shared,img._is_shared); - return img; - } - - //! Return a reference to an empty image. - /** - \note - This function is useful mainly to declare optional parameters having type \c CImg in functions prototypes, - e.g. - \code - void f(const int x=0, const int y=0, const CImg& img=CImg::empty()); - \endcode - **/ - static CImg& empty() { - static CImg _empty; - return _empty.assign(); - } - - //! Return a reference to an empty image \const. - static const CImg& const_empty() { - static const CImg _empty; - return _empty; - } - - //@} - //------------------------------------------ - // - //! \name Overloaded Operators - //@{ - //------------------------------------------ - - //! Access to a pixel value. - /** - Return a reference to a located pixel value of the image instance, - being possibly \e const, whether the image instance is \e const or not. - This is the standard method to get/set pixel values in \c CImg images. - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \note - - Range of pixel coordinates start from (0,0,0,0) to - (width() - 1,height() - 1,depth() - 1,spectrum() - 1). - - Due to the particular arrangement of the pixel buffers defined in %CImg, you can omit one coordinate if the - corresponding dimension is equal to \c 1. - For instance, pixels of a 2d image (depth() equal to \c 1) can be accessed by img(x,y,c) instead of - img(x,y,0,c). - \warning - - There is \e no boundary checking done in this operator, to make it as fast as possible. - You \e must take care of out-of-bounds access by yourself, if necessary. - For debuging purposes, you may want to define macro \c 'cimg_verbosity'>=3 to enable additional boundary - checking operations in this operator. In that case, warning messages will be printed on the error output - when accessing out-of-bounds pixels. - \par Example - \code - CImg img(100,100,1,3,0); // Construct a 100x100x1x3 (color) image with pixels set to '0'. - const float - valR = img(10,10,0,0), // Read red value at coordinates (10,10). - valG = img(10,10,0,1), // Read green value at coordinates (10,10) - valB = img(10,10,2), // Read blue value at coordinates (10,10) (Z-coordinate can be omitted). - avg = (valR + valG + valB)/3; // Compute average pixel value. - img(10,10,0) = img(10,10,1) = img(10,10,2) = avg; // Replace the color pixel (10,10) by the average grey value. - \endcode - **/ -#if cimg_verbosity>=3 - T& operator()(const unsigned int x, const unsigned int y=0, - const unsigned int z=0, const unsigned int c=0) { - const ulongT off = (ulongT)offset(x,y,z,c); - if (!_data || off>=size()) { - cimg::warn(_cimg_instance - "operator(): Invalid pixel request, at coordinates (%d,%d,%d,%d) [offset=%u].", - cimg_instance, - (int)x,(int)y,(int)z,(int)c,off); - return *_data; - } - else return _data[off]; - } - - //! Access to a pixel value \const. - const T& operator()(const unsigned int x, const unsigned int y=0, - const unsigned int z=0, const unsigned int c=0) const { - return const_cast*>(this)->operator()(x,y,z,c); - } - - //! Access to a pixel value. - /** - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \param wh Precomputed offset, must be equal to width()*\ref height(). - \param whd Precomputed offset, must be equal to width()*\ref height()*\ref depth(). - \note - - Similar to (but faster than) operator()(). - It uses precomputed offsets to optimize memory access. You may use it to optimize - the reading/writing of several pixel values in the same image (e.g. in a loop). - **/ - T& operator()(const unsigned int x, const unsigned int y, const unsigned int z, const unsigned int c, - const ulongT wh, const ulongT whd=0) { - cimg::unused(wh,whd); - return (*this)(x,y,z,c); - } - - //! Access to a pixel value \const. - const T& operator()(const unsigned int x, const unsigned int y, const unsigned int z, const unsigned int c, - const ulongT wh, const ulongT whd=0) const { - cimg::unused(wh,whd); - return (*this)(x,y,z,c); - } -#else - T& operator()(const unsigned int x) { - return _data[x]; - } - - const T& operator()(const unsigned int x) const { - return _data[x]; - } - - T& operator()(const unsigned int x, const unsigned int y) { - return _data[x + y*_width]; - } - - const T& operator()(const unsigned int x, const unsigned int y) const { - return _data[x + y*_width]; - } - - T& operator()(const unsigned int x, const unsigned int y, const unsigned int z) { - return _data[x + y*(ulongT)_width + z*(ulongT)_width*_height]; - } - - const T& operator()(const unsigned int x, const unsigned int y, const unsigned int z) const { - return _data[x + y*(ulongT)_width + z*(ulongT)_width*_height]; - } - - T& operator()(const unsigned int x, const unsigned int y, const unsigned int z, const unsigned int c) { - return _data[x + y*(ulongT)_width + z*(ulongT)_width*_height + c*(ulongT)_width*_height*_depth]; - } - - const T& operator()(const unsigned int x, const unsigned int y, const unsigned int z, const unsigned int c) const { - return _data[x + y*(ulongT)_width + z*(ulongT)_width*_height + c*(ulongT)_width*_height*_depth]; - } - - T& operator()(const unsigned int x, const unsigned int y, const unsigned int z, const unsigned int, - const ulongT wh) { - return _data[x + y*_width + z*wh]; - } - - const T& operator()(const unsigned int x, const unsigned int y, const unsigned int z, const unsigned int, - const ulongT wh) const { - return _data[x + y*_width + z*wh]; - } - - T& operator()(const unsigned int x, const unsigned int y, const unsigned int z, const unsigned int c, - const ulongT wh, const ulongT whd) { - return _data[x + y*_width + z*wh + c*whd]; - } - - const T& operator()(const unsigned int x, const unsigned int y, const unsigned int z, const unsigned int c, - const ulongT wh, const ulongT whd) const { - return _data[x + y*_width + z*wh + c*whd]; - } -#endif - - //! Implicitely cast an image into a \c T*. - /** - Implicitely cast a \c CImg instance into a \c T* or \c const \c T* pointer, whether the image instance - is \e const or not. The returned pointer points on the first value of the image pixel buffer. - \note - - It simply returns the pointer data() to the pixel buffer. - - This implicit conversion is convenient to test the empty state of images (data() being \c 0 in this case), e.g. - \code - CImg img1(100,100), img2; // 'img1' is a 100x100 image, 'img2' is an empty image. - if (img1) { // Test succeeds, 'img1' is not an empty image. - if (!img2) { // Test succeeds, 'img2' is an empty image. - std::printf("'img1' is not empty, 'img2' is empty."); - } - } - \endcode - - It also allows to use brackets to access pixel values, without need for a \c CImg::operator[](), e.g. - \code - CImg img(100,100); - const float value = img[99]; // Access to value of the last pixel on the first row. - img[510] = 255; // Set pixel value at (10,5). - \endcode - **/ - operator T*() { - return _data; - } - - //! Implicitely cast an image into a \c T* \const. - operator const T*() const { - return _data; - } - - //! Assign a value to all image pixels. - /** - Assign specified \c value to each pixel value of the image instance. - \param value Value that will be assigned to image pixels. - \note - - The image size is never modified. - - The \c value may be casted to pixel type \c T if necessary. - \par Example - \code - CImg img(100,100); // Declare image (with garbage values). - img = 0; // Set all pixel values to '0'. - img = 1.2; // Set all pixel values to '1' (cast of '1.2' as a 'char'). - \endcode - **/ - CImg& operator=(const T& value) { - return fill(value); - } - - //! Assign pixels values from a specified expression. - /** - Initialize all pixel values from the specified string \c expression. - \param expression Value string describing the way pixel values are set. - \note - - String parameter \c expression may describe different things: - - If \c expression is a list of values (as in \c "1,2,3,8,3,2"), or a formula (as in \c "(x*y)%255"), - the pixel values are set from specified \c expression and the image size is not modified. - - If \c expression is a filename (as in \c "reference.jpg"), the corresponding image file is loaded and - replace the image instance. The image size is modified if necessary. - \par Example - \code - CImg img1(100,100), img2(img1), img3(img1); // Declare three 100x100 scalar images with unitialized pixel values. - img1 = "0,50,100,150,200,250,200,150,100,50"; // Set pixel values of 'img1' from a value sequence. - img2 = "10*((x*y)%25)"; // Set pixel values of 'img2' from a formula. - img3 = "reference.jpg"; // Set pixel values of 'img3' from a file (image size is modified). - (img1,img2,img3).display(); - \endcode - \image html ref_operator_eq.jpg - **/ - CImg& operator=(const char *const expression) { - const unsigned int omode = cimg::exception_mode(); - cimg::exception_mode(0); - try { - _fill(expression,true,true,0,0,"operator=",0); - } catch (CImgException&) { - cimg::exception_mode(omode); - load(expression); - } - cimg::exception_mode(omode); - return *this; - } - - //! Copy an image into the current image instance. - /** - Similar to the in-place copy constructor assign(const CImg&). - **/ - template - CImg& operator=(const CImg& img) { - return assign(img); - } - - //! Copy an image into the current image instance \specialization. - CImg& operator=(const CImg& img) { - return assign(img); - } - - //! Copy the content of a display window to the current image instance. - /** - Similar to assign(const CImgDisplay&). - **/ - CImg& operator=(const CImgDisplay& disp) { - disp.snapshot(*this); - return *this; - } - - //! In-place addition operator. - /** - Add specified \c value to all pixels of an image instance. - \param value Value to add. - \note - - Resulting pixel values are casted to fit the pixel type \c T. - For instance, adding \c 0.2 to a \c CImg is possible but does nothing indeed. - - Overflow values are treated as with standard C++ numeric types. For instance, - \code - CImg img(100,100,1,1,255); // Construct a 100x100 image with pixel values '255'. - img+=1; // Add '1' to each pixels -> Overflow. - // here all pixels of image 'img' are equal to '0'. - \endcode - - To prevent value overflow, you may want to consider pixel type \c T as \c float or \c double, - and use cut() after addition. - \par Example - \code - CImg img1("reference.jpg"); // Load a 8-bits RGB image (values in [0,255]). - CImg img2(img1); // Construct a float-valued copy of 'img1'. - img2+=100; // Add '100' to pixel values -> goes out of [0,255] but no problems with floats. - img2.cut(0,255); // Cut values in [0,255] to fit the 'unsigned char' constraint. - img1 = img2; // Rewrite safe result in 'unsigned char' version 'img1'. - const CImg img3 = (img1 + 100).cut(0,255); // Do the same in a more simple and elegant way. - (img1,img2,img3).display(); - \endcode - \image html ref_operator_plus.jpg - **/ - template - CImg& operator+=(const t value) { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=524288)) - cimg_rof(*this,ptrd,T) *ptrd = (T)(*ptrd + value); - return *this; - } - - //! In-place addition operator. - /** - Add values to image pixels, according to the specified string \c expression. - \param expression Value string describing the way pixel values are added. - \note - - Similar to operator=(const char*), except that it adds values to the pixels of the current image instance, - instead of assigning them. - **/ - CImg& operator+=(const char *const expression) { - return *this+=(+*this)._fill(expression,true,true,0,0,"operator+=",this); - } - - //! In-place addition operator. - /** - Add values to image pixels, according to the values of the input image \c img. - \param img Input image to add. - \note - - The size of the image instance is never modified. - - It is not mandatory that input image \c img has the same size as the image instance. - If less values are available in \c img, then the values are added periodically. For instance, adding one - WxH scalar image (spectrum() equal to \c 1) to one WxH color image (spectrum() equal to \c 3) - means each color channel will be incremented with the same values at the same locations. - \par Example - \code - CImg img1("reference.jpg"); // Load a RGB color image (img1.spectrum()==3) - const CImg img2(img1.width(),img.height(),1,1,"255*(x/w)^2"); // Construct a scalar shading (img2.spectrum()==1). - img1+=img2; // Add shading to each channel of 'img1'. - img1.cut(0,255); // Prevent [0,255] overflow. - (img2,img1).display(); - \endcode - \image html ref_operator_plus1.jpg - **/ - template - CImg& operator+=(const CImg& img) { - const ulongT siz = size(), isiz = img.size(); - if (siz && isiz) { - if (is_overlapped(img)) return *this+=+img; - T *ptrd = _data, *const ptre = _data + siz; - if (siz>isiz) for (ulongT n = siz/isiz; n; --n) - for (const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs& operator++() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=524288)) - cimg_rof(*this,ptrd,T) ++*ptrd; - return *this; - } - - //! In-place increment operator (postfix). - /** - Add \c 1 to all image pixels, and return a new copy of the initial (pre-incremented) image instance. - \note - - Use the prefixed version operator++() if you don't need a copy of the initial - (pre-incremented) image instance, since a useless image copy may be expensive in terms of memory usage. - **/ - CImg operator++(int) { - const CImg copy(*this,false); - ++*this; - return copy; - } - - //! Return a non-shared copy of the image instance. - /** - \note - - Use this operator to ensure you get a non-shared copy of an image instance with same pixel type \c T. - Indeed, the usual copy constructor CImg(const CImg&) returns a shared copy of a shared input image, - and it may be not desirable to work on a regular copy (e.g. for a resize operation) if you have no - information about the shared state of the input image. - - Writing \c (+img) is equivalent to \c CImg(img,false). - **/ - CImg operator+() const { - return CImg(*this,false); - } - - //! Addition operator. - /** - Similar to operator+=(const t), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image may be a superset of the initial pixel type \c T, if necessary. - **/ - template - CImg<_cimg_Tt> operator+(const t value) const { - return CImg<_cimg_Tt>(*this,false)+=value; - } - - //! Addition operator. - /** - Similar to operator+=(const char*), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image may be a superset of the initial pixel type \c T, if necessary. - **/ - CImg operator+(const char *const expression) const { - return CImg(*this,false)+=expression; - } - - //! Addition operator. - /** - Similar to operator+=(const CImg&), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image may be a superset of the initial pixel type \c T, if necessary. - **/ - template - CImg<_cimg_Tt> operator+(const CImg& img) const { - return CImg<_cimg_Tt>(*this,false)+=img; - } - - //! In-place substraction operator. - /** - Similar to operator+=(const t), except that it performs a substraction instead of an addition. - **/ - template - CImg& operator-=(const t value) { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=524288)) - cimg_rof(*this,ptrd,T) *ptrd = (T)(*ptrd - value); - return *this; - } - - //! In-place substraction operator. - /** - Similar to operator+=(const char*), except that it performs a substraction instead of an addition. - **/ - CImg& operator-=(const char *const expression) { - return *this-=(+*this)._fill(expression,true,true,0,0,"operator-=",this); - } - - //! In-place substraction operator. - /** - Similar to operator+=(const CImg&), except that it performs a substraction instead of an addition. - **/ - template - CImg& operator-=(const CImg& img) { - const ulongT siz = size(), isiz = img.size(); - if (siz && isiz) { - if (is_overlapped(img)) return *this-=+img; - T *ptrd = _data, *const ptre = _data + siz; - if (siz>isiz) for (ulongT n = siz/isiz; n; --n) - for (const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs& operator--() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=524288)) - cimg_rof(*this,ptrd,T) *ptrd = *ptrd - (T)1; - return *this; - } - - //! In-place decrement operator (postfix). - /** - Similar to operator++(int), except that it performs a decrement instead of an increment. - **/ - CImg operator--(int) { - const CImg copy(*this,false); - --*this; - return copy; - } - - //! Replace each pixel by its opposite value. - /** - \note - - If the computed opposite values are out-of-range, they are treated as with standard C++ numeric types. - For instance, the \c unsigned \c char opposite of \c 1 is \c 255. - \par Example - \code - const CImg - img1("reference.jpg"), // Load a RGB color image. - img2 = -img1; // Compute its opposite (in 'unsigned char'). - (img1,img2).display(); - \endcode - \image html ref_operator_minus.jpg - **/ - CImg operator-() const { - return CImg(_width,_height,_depth,_spectrum,(T)0)-=*this; - } - - //! Substraction operator. - /** - Similar to operator-=(const t), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image may be a superset of the initial pixel type \c T, if necessary. - **/ - template - CImg<_cimg_Tt> operator-(const t value) const { - return CImg<_cimg_Tt>(*this,false)-=value; - } - - //! Substraction operator. - /** - Similar to operator-=(const char*), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image may be a superset of the initial pixel type \c T, if necessary. - **/ - CImg operator-(const char *const expression) const { - return CImg(*this,false)-=expression; - } - - //! Substraction operator. - /** - Similar to operator-=(const CImg&), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image may be a superset of the initial pixel type \c T, if necessary. - **/ - template - CImg<_cimg_Tt> operator-(const CImg& img) const { - return CImg<_cimg_Tt>(*this,false)-=img; - } - - //! In-place multiplication operator. - /** - Similar to operator+=(const t), except that it performs a multiplication instead of an addition. - **/ - template - CImg& operator*=(const t value) { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=262144)) - cimg_rof(*this,ptrd,T) *ptrd = (T)(*ptrd * value); - return *this; - } - - //! In-place multiplication operator. - /** - Similar to operator+=(const char*), except that it performs a multiplication instead of an addition. - **/ - CImg& operator*=(const char *const expression) { - return mul((+*this)._fill(expression,true,true,0,0,"operator*=",this)); - } - - //! In-place multiplication operator. - /** - Replace the image instance by the matrix multiplication between the image instance and the specified matrix - \c img. - \param img Second operand of the matrix multiplication. - \note - - It does \e not compute a pointwise multiplication between two images. For this purpose, use - mul(const CImg&) instead. - - The size of the image instance can be modified by this operator. - \par Example - \code - CImg A(2,2,1,1, 1,2,3,4); // Construct 2x2 matrix A = [1,2;3,4]. - const CImg X(1,2,1,1, 1,2); // Construct 1x2 vector X = [1;2]. - A*=X; // Assign matrix multiplication A*X to 'A'. - // 'A' is now a 1x2 vector whose values are [5;11]. - \endcode - **/ - template - CImg& operator*=(const CImg& img) { - return ((*this)*img).move_to(*this); - } - - //! Multiplication operator. - /** - Similar to operator*=(const t), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image may be a superset of the initial pixel type \c T, if necessary. - **/ - template - CImg<_cimg_Tt> operator*(const t value) const { - return CImg<_cimg_Tt>(*this,false)*=value; - } - - //! Multiplication operator. - /** - Similar to operator*=(const char*), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image may be a superset of the initial pixel type \c T, if necessary. - **/ - CImg operator*(const char *const expression) const { - return CImg(*this,false)*=expression; - } - - //! Multiplication operator. - /** - Similar to operator*=(const CImg&), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image may be a superset of the initial pixel type \c T, if necessary. - **/ - template - CImg<_cimg_Tt> operator*(const CImg& img) const { - if (_width!=img._height || _depth!=1 || _spectrum!=1) - throw CImgArgumentException(_cimg_instance - "operator*(): Invalid multiplication of instance by specified " - "matrix (%u,%u,%u,%u,%p)", - cimg_instance, - img._width,img._height,img._depth,img._spectrum,img._data); - CImg<_cimg_Tt> res(img._width,_height); -#ifdef cimg_use_openmp - cimg_pragma_openmp(parallel for collapse(2) cimg_openmp_if(size()>1024 && img.size()>1024)) - cimg_forXY(res,i,j) { - _cimg_Ttdouble value = 0; cimg_forX(*this,k) value+=(*this)(k,j)*img(i,k); res(i,j) = (_cimg_Tt)value; - } -#else - _cimg_Tt *ptrd = res._data; - cimg_forXY(res,i,j) { - _cimg_Ttdouble value = 0; cimg_forX(*this,k) value+=(*this)(k,j)*img(i,k); *(ptrd++) = (_cimg_Tt)value; - } -#endif - return res; - } - - //! In-place division operator. - /** - Similar to operator+=(const t), except that it performs a division instead of an addition. - **/ - template - CImg& operator/=(const t value) { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=32768)) - cimg_rof(*this,ptrd,T) *ptrd = (T)(*ptrd / value); - return *this; - } - - //! In-place division operator. - /** - Similar to operator+=(const char*), except that it performs a division instead of an addition. - **/ - CImg& operator/=(const char *const expression) { - return div((+*this)._fill(expression,true,true,0,0,"operator/=",this)); - } - - //! In-place division operator. - /** - Replace the image instance by the (right) matrix division between the image instance and the specified - matrix \c img. - \param img Second operand of the matrix division. - \note - - It does \e not compute a pointwise division between two images. For this purpose, use - div(const CImg&) instead. - - It returns the matrix operation \c A*inverse(img). - - The size of the image instance can be modified by this operator. - **/ - template - CImg& operator/=(const CImg& img) { - return (*this*img.get_invert()).move_to(*this); - } - - //! Division operator. - /** - Similar to operator/=(const t), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image may be a superset of the initial pixel type \c T, if necessary. - **/ - template - CImg<_cimg_Tt> operator/(const t value) const { - return CImg<_cimg_Tt>(*this,false)/=value; - } - - //! Division operator. - /** - Similar to operator/=(const char*), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image may be a superset of the initial pixel type \c T, if necessary. - **/ - CImg operator/(const char *const expression) const { - return CImg(*this,false)/=expression; - } - - //! Division operator. - /** - Similar to operator/=(const CImg&), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image may be a superset of the initial pixel type \c T, if necessary. - **/ - template - CImg<_cimg_Tt> operator/(const CImg& img) const { - return (*this)*img.get_invert(); - } - - //! In-place modulo operator. - /** - Similar to operator+=(const t), except that it performs a modulo operation instead of an addition. - **/ - template - CImg& operator%=(const t value) { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=16384)) - cimg_rof(*this,ptrd,T) *ptrd = (T)cimg::mod(*ptrd,(T)value); - return *this; - } - - //! In-place modulo operator. - /** - Similar to operator+=(const char*), except that it performs a modulo operation instead of an addition. - **/ - CImg& operator%=(const char *const expression) { - return *this%=(+*this)._fill(expression,true,true,0,0,"operator%=",this); - } - - //! In-place modulo operator. - /** - Similar to operator+=(const CImg&), except that it performs a modulo operation instead of an addition. - **/ - template - CImg& operator%=(const CImg& img) { - const ulongT siz = size(), isiz = img.size(); - if (siz && isiz) { - if (is_overlapped(img)) return *this%=+img; - T *ptrd = _data, *const ptre = _data + siz; - if (siz>isiz) for (ulongT n = siz/isiz; n; --n) - for (const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs - CImg<_cimg_Tt> operator%(const t value) const { - return CImg<_cimg_Tt>(*this,false)%=value; - } - - //! Modulo operator. - /** - Similar to operator%=(const char*), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image may be a superset of the initial pixel type \c T, if necessary. - **/ - CImg operator%(const char *const expression) const { - return CImg(*this,false)%=expression; - } - - //! Modulo operator. - /** - Similar to operator%=(const CImg&), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image may be a superset of the initial pixel type \c T, if necessary. - **/ - template - CImg<_cimg_Tt> operator%(const CImg& img) const { - return CImg<_cimg_Tt>(*this,false)%=img; - } - - //! In-place bitwise AND operator. - /** - Similar to operator+=(const t), except that it performs a bitwise AND operation instead of an addition. - **/ - template - CImg& operator&=(const t value) { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=32768)) - cimg_rof(*this,ptrd,T) *ptrd = (T)((ulongT)*ptrd & (ulongT)value); - return *this; - } - - //! In-place bitwise AND operator. - /** - Similar to operator+=(const char*), except that it performs a bitwise AND operation instead of an addition. - **/ - CImg& operator&=(const char *const expression) { - return *this&=(+*this)._fill(expression,true,true,0,0,"operator&=",this); - } - - //! In-place bitwise AND operator. - /** - Similar to operator+=(const CImg&), except that it performs a bitwise AND operation instead of an addition. - **/ - template - CImg& operator&=(const CImg& img) { - const ulongT siz = size(), isiz = img.size(); - if (siz && isiz) { - if (is_overlapped(img)) return *this&=+img; - T *ptrd = _data, *const ptre = _data + siz; - if (siz>isiz) for (ulongT n = siz/isiz; n; --n) - for (const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs - CImg operator&(const t value) const { - return (+*this)&=value; - } - - //! Bitwise AND operator. - /** - Similar to operator&=(const char*), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image is \c T. - **/ - CImg operator&(const char *const expression) const { - return (+*this)&=expression; - } - - //! Bitwise AND operator. - /** - Similar to operator&=(const CImg&), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image is \c T. - **/ - template - CImg operator&(const CImg& img) const { - return (+*this)&=img; - } - - //! In-place bitwise OR operator. - /** - Similar to operator+=(const t), except that it performs a bitwise OR operation instead of an addition. - **/ - template - CImg& operator|=(const t value) { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=32768)) - cimg_rof(*this,ptrd,T) *ptrd = (T)((ulongT)*ptrd | (ulongT)value); - return *this; - } - - //! In-place bitwise OR operator. - /** - Similar to operator+=(const char*), except that it performs a bitwise OR operation instead of an addition. - **/ - CImg& operator|=(const char *const expression) { - return *this|=(+*this)._fill(expression,true,true,0,0,"operator|=",this); - } - - //! In-place bitwise OR operator. - /** - Similar to operator+=(const CImg&), except that it performs a bitwise OR operation instead of an addition. - **/ - template - CImg& operator|=(const CImg& img) { - const ulongT siz = size(), isiz = img.size(); - if (siz && isiz) { - if (is_overlapped(img)) return *this|=+img; - T *ptrd = _data, *const ptre = _data + siz; - if (siz>isiz) for (ulongT n = siz/isiz; n; --n) - for (const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs - CImg operator|(const t value) const { - return (+*this)|=value; - } - - //! Bitwise OR operator. - /** - Similar to operator|=(const char*), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image is \c T. - **/ - CImg operator|(const char *const expression) const { - return (+*this)|=expression; - } - - //! Bitwise OR operator. - /** - Similar to operator|=(const CImg&), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image is \c T. - **/ - template - CImg operator|(const CImg& img) const { - return (+*this)|=img; - } - - //! In-place bitwise XOR operator. - /** - Similar to operator+=(const t), except that it performs a bitwise XOR operation instead of an addition. - \warning - - It does \e not compute the \e power of pixel values. For this purpose, use pow(const t) instead. - **/ - template - CImg& operator^=(const t value) { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=32768)) - cimg_rof(*this,ptrd,T) *ptrd = (T)((ulongT)*ptrd ^ (ulongT)value); - return *this; - } - - //! In-place bitwise XOR operator. - /** - Similar to operator+=(const char*), except that it performs a bitwise XOR operation instead of an addition. - \warning - - It does \e not compute the \e power of pixel values. For this purpose, use pow(const char*) instead. - **/ - CImg& operator^=(const char *const expression) { - return *this^=(+*this)._fill(expression,true,true,0,0,"operator^=",this); - } - - //! In-place bitwise XOR operator. - /** - Similar to operator+=(const CImg&), except that it performs a bitwise XOR operation instead of an addition. - \warning - - It does \e not compute the \e power of pixel values. For this purpose, use pow(const CImg&) instead. - **/ - template - CImg& operator^=(const CImg& img) { - const ulongT siz = size(), isiz = img.size(); - if (siz && isiz) { - if (is_overlapped(img)) return *this^=+img; - T *ptrd = _data, *const ptre = _data + siz; - if (siz>isiz) for (ulongT n = siz/isiz; n; --n) - for (const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs - CImg operator^(const t value) const { - return (+*this)^=value; - } - - //! Bitwise XOR operator. - /** - Similar to operator^=(const char*), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image is \c T. - **/ - CImg operator^(const char *const expression) const { - return (+*this)^=expression; - } - - //! Bitwise XOR operator. - /** - Similar to operator^=(const CImg&), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image is \c T. - **/ - template - CImg operator^(const CImg& img) const { - return (+*this)^=img; - } - - //! In-place bitwise left shift operator. - /** - Similar to operator+=(const t), except that it performs a bitwise left shift instead of an addition. - **/ - template - CImg& operator<<=(const t value) { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=65536)) - cimg_rof(*this,ptrd,T) *ptrd = (T)(((longT)*ptrd) << (int)value); - return *this; - } - - //! In-place bitwise left shift operator. - /** - Similar to operator+=(const char*), except that it performs a bitwise left shift instead of an addition. - **/ - CImg& operator<<=(const char *const expression) { - return *this<<=(+*this)._fill(expression,true,true,0,0,"operator<<=",this); - } - - //! In-place bitwise left shift operator. - /** - Similar to operator+=(const CImg&), except that it performs a bitwise left shift instead of an addition. - **/ - template - CImg& operator<<=(const CImg& img) { - const ulongT siz = size(), isiz = img.size(); - if (siz && isiz) { - if (is_overlapped(img)) return *this^=+img; - T *ptrd = _data, *const ptre = _data + siz; - if (siz>isiz) for (ulongT n = siz/isiz; n; --n) - for (const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs - CImg operator<<(const t value) const { - return (+*this)<<=value; - } - - //! Bitwise left shift operator. - /** - Similar to operator<<=(const char*), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image is \c T. - **/ - CImg operator<<(const char *const expression) const { - return (+*this)<<=expression; - } - - //! Bitwise left shift operator. - /** - Similar to operator<<=(const CImg&), except that it returns a new image instance instead of - operating in-place. - The pixel type of the returned image is \c T. - **/ - template - CImg operator<<(const CImg& img) const { - return (+*this)<<=img; - } - - //! In-place bitwise right shift operator. - /** - Similar to operator+=(const t), except that it performs a bitwise right shift instead of an addition. - **/ - template - CImg& operator>>=(const t value) { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=65536)) - cimg_rof(*this,ptrd,T) *ptrd = (T)(((longT)*ptrd) >> (int)value); - return *this; - } - - //! In-place bitwise right shift operator. - /** - Similar to operator+=(const char*), except that it performs a bitwise right shift instead of an addition. - **/ - CImg& operator>>=(const char *const expression) { - return *this>>=(+*this)._fill(expression,true,true,0,0,"operator>>=",this); - } - - //! In-place bitwise right shift operator. - /** - Similar to operator+=(const CImg&), except that it performs a bitwise right shift instead of an addition. - **/ - template - CImg& operator>>=(const CImg& img) { - const ulongT siz = size(), isiz = img.size(); - if (siz && isiz) { - if (is_overlapped(img)) return *this^=+img; - T *ptrd = _data, *const ptre = _data + siz; - if (siz>isiz) for (ulongT n = siz/isiz; n; --n) - for (const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs> (int)*(ptrs++)); - for (const t *ptrs = img._data; ptrd> (int)*(ptrs++)); - } - return *this; - } - - //! Bitwise right shift operator. - /** - Similar to operator>>=(const t), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image is \c T. - **/ - template - CImg operator>>(const t value) const { - return (+*this)>>=value; - } - - //! Bitwise right shift operator. - /** - Similar to operator>>=(const char*), except that it returns a new image instance instead of operating in-place. - The pixel type of the returned image is \c T. - **/ - CImg operator>>(const char *const expression) const { - return (+*this)>>=expression; - } - - //! Bitwise right shift operator. - /** - Similar to operator>>=(const CImg&), except that it returns a new image instance instead of - operating in-place. - The pixel type of the returned image is \c T. - **/ - template - CImg operator>>(const CImg& img) const { - return (+*this)>>=img; - } - - //! Bitwise inversion operator. - /** - Similar to operator-(), except that it compute the bitwise inverse instead of the opposite value. - **/ - CImg operator~() const { - CImg res(_width,_height,_depth,_spectrum); - const T *ptrs = _data; - cimg_for(res,ptrd,T) { const ulongT value = (ulongT)*(ptrs++); *ptrd = (T)~value; } - return res; - } - - //! Test if all pixels of an image have the same value. - /** - Return \c true is all pixels of the image instance are equal to the specified \c value. - \param value Reference value to compare with. - **/ - template - bool operator==(const t value) const { - if (is_empty()) return false; - typedef _cimg_Tt Tt; - bool is_equal = true; - for (T *ptrd = _data + size(); is_equal && ptrd>_data; is_equal = ((Tt)*(--ptrd)==(Tt)value)) {} - return is_equal; - } - - //! Test if all pixel values of an image follow a specified expression. - /** - Return \c true is all pixels of the image instance are equal to the specified \c expression. - \param expression Value string describing the way pixel values are compared. - **/ - bool operator==(const char *const expression) const { - return *this==(+*this)._fill(expression,true,true,0,0,"operator==",this); - } - - //! Test if two images have the same size and values. - /** - Return \c true if the image instance and the input image \c img have the same dimensions and pixel values, - and \c false otherwise. - \param img Input image to compare with. - \note - - The pixel buffer pointers data() of the two compared images do not have to be the same for operator==() - to return \c true. - Only the dimensions and the pixel values matter. Thus, the comparison can be \c true even for different - pixel types \c T and \c t. - \par Example - \code - const CImg img1(1,3,1,1, 0,1,2); // Construct a 1x3 vector [0;1;2] (with 'float' pixel values). - const CImg img2(1,3,1,1, 0,1,2); // Construct a 1x3 vector [0;1;2] (with 'char' pixel values). - if (img1==img2) { // Test succeeds, image dimensions and values are the same. - std::printf("'img1' and 'img2' have same dimensions and values."); - } - \endcode - **/ - template - bool operator==(const CImg& img) const { - typedef _cimg_Tt Tt; - const ulongT siz = size(); - bool is_equal = true; - if (siz!=img.size()) return false; - t *ptrs = img._data + siz; - for (T *ptrd = _data + siz; is_equal && ptrd>_data; is_equal = ((Tt)*(--ptrd)==(Tt)*(--ptrs))) {} - return is_equal; - } - - //! Test if pixels of an image are all different from a value. - /** - Return \c true is all pixels of the image instance are different than the specified \c value. - \param value Reference value to compare with. - **/ - template - bool operator!=(const t value) const { - return !((*this)==value); - } - - //! Test if all pixel values of an image are different from a specified expression. - /** - Return \c true is all pixels of the image instance are different to the specified \c expression. - \param expression Value string describing the way pixel values are compared. - **/ - bool operator!=(const char *const expression) const { - return !((*this)==expression); - } - - //! Test if two images have different sizes or values. - /** - Return \c true if the image instance and the input image \c img have different dimensions or pixel values, - and \c false otherwise. - \param img Input image to compare with. - \note - - Writing \c img1!=img2 is equivalent to \c !(img1==img2). - **/ - template - bool operator!=(const CImg& img) const { - return !((*this)==img); - } - - //! Construct an image list from two images. - /** - Return a new list of image (\c CImgList instance) containing exactly two elements: - - A copy of the image instance, at position [\c 0]. - - A copy of the specified image \c img, at position [\c 1]. - - \param img Input image that will be the second image of the resulting list. - \note - - The family of operator,() is convenient to easily create list of images, but it is also \e quite \e slow - in practice (see warning below). - - Constructed lists contain no shared images. If image instance or input image \c img are shared, they are - inserted as new non-shared copies in the resulting list. - - The pixel type of the returned list may be a superset of the initial pixel type \c T, if necessary. - \warning - - Pipelining operator,() \c N times will perform \c N copies of the entire content of a (growing) image list. - This may become very expensive in terms of speed and used memory. You should avoid using this technique to - build a new CImgList instance from several images, if you are seeking for performance. - Fast insertions of images in an image list are possible with - CImgList::insert(const CImg&,unsigned int,bool) or move_to(CImgList&,unsigned int). - \par Example - \code - const CImg - img1("reference.jpg"), - img2 = img1.get_mirror('x'), - img3 = img2.get_blur(5); - const CImgList list = (img1,img2); // Create list of two elements from 'img1' and 'img2'. - (list,img3).display(); // Display image list containing copies of 'img1','img2' and 'img3'. - \endcode - \image html ref_operator_comma.jpg - **/ - template - CImgList<_cimg_Tt> operator,(const CImg& img) const { - return CImgList<_cimg_Tt>(*this,img); - } - - //! Construct an image list from image instance and an input image list. - /** - Return a new list of images (\c CImgList instance) containing exactly \c list.size() \c + \c 1 elements: - - A copy of the image instance, at position [\c 0]. - - A copy of the specified image list \c list, from positions [\c 1] to [\c list.size()]. - - \param list Input image list that will be appended to the image instance. - \note - - Similar to operator,(const CImg&) const, except that it takes an image list as an argument. - **/ - template - CImgList<_cimg_Tt> operator,(const CImgList& list) const { - return CImgList<_cimg_Tt>(list,false).insert(*this,0); - } - - //! Split image along specified axis. - /** - Return a new list of images (\c CImgList instance) containing the splitted components - of the instance image along the specified axis. - \param axis Splitting axis (can be '\c x','\c y','\c z' or '\c c') - \note - - Similar to get_split(char,int) const, with default second argument. - \par Example - \code - const CImg img("reference.jpg"); // Load a RGB color image. - const CImgList list = (img<'c'); // Get a list of its three R,G,B channels. - (img,list).display(); - \endcode - \image html ref_operator_less.jpg - **/ - CImgList operator<(const char axis) const { - return get_split(axis); - } - - //@} - //------------------------------------- - // - //! \name Instance Characteristics - //@{ - //------------------------------------- - - //! Return the type of image pixel values as a C string. - /** - Return a \c char* string containing the usual type name of the image pixel values - (i.e. a stringified version of the template parameter \c T). - \note - - The returned string may contain spaces (as in \c "unsigned char"). - - If the pixel type \c T does not correspond to a registered type, the string "unknown" is returned. - **/ - static const char* pixel_type() { - return cimg::type::string(); - } - - //! Return the number of image columns. - /** - Return the image width, i.e. the image dimension along the X-axis. - \note - - The width() of an empty image is equal to \c 0. - - width() is typically equal to \c 1 when considering images as \e vectors for matrix calculations. - - width() returns an \c int, although the image width is internally stored as an \c unsigned \c int. - Using an \c int is safer and prevents arithmetic traps possibly encountered when doing calculations involving - \c unsigned \c int variables. - Access to the initial \c unsigned \c int variable is possible (though not recommended) by - (*this)._width. - **/ - int width() const { - return (int)_width; - } - - //! Return the number of image rows. - /** - Return the image height, i.e. the image dimension along the Y-axis. - \note - - The height() of an empty image is equal to \c 0. - - height() returns an \c int, although the image height is internally stored as an \c unsigned \c int. - Using an \c int is safer and prevents arithmetic traps possibly encountered when doing calculations involving - \c unsigned \c int variables. - Access to the initial \c unsigned \c int variable is possible (though not recommended) by - (*this)._height. - **/ - int height() const { - return (int)_height; - } - - //! Return the number of image slices. - /** - Return the image depth, i.e. the image dimension along the Z-axis. - \note - - The depth() of an empty image is equal to \c 0. - - depth() is typically equal to \c 1 when considering usual 2d images. When depth()\c > \c 1, the image - is said to be \e volumetric. - - depth() returns an \c int, although the image depth is internally stored as an \c unsigned \c int. - Using an \c int is safer and prevents arithmetic traps possibly encountered when doing calculations involving - \c unsigned \c int variables. - Access to the initial \c unsigned \c int variable is possible (though not recommended) by - (*this)._depth. - **/ - int depth() const { - return (int)_depth; - } - - //! Return the number of image channels. - /** - Return the number of image channels, i.e. the image dimension along the C-axis. - \note - - The spectrum() of an empty image is equal to \c 0. - - spectrum() is typically equal to \c 1 when considering scalar-valued images, to \c 3 - for RGB-coded color images, and to \c 4 for RGBA-coded color images (with alpha-channel). - The number of channels of an image instance is not limited. The meaning of the pixel values is not linked - up to the number of channels (e.g. a 4-channel image may indifferently stands for a RGBA or CMYK color image). - - spectrum() returns an \c int, although the image spectrum is internally stored as an \c unsigned \c int. - Using an \c int is safer and prevents arithmetic traps possibly encountered when doing calculations involving - \c unsigned \c int variables. - Access to the initial \c unsigned \c int variable is possible (though not recommended) by - (*this)._spectrum. - **/ - int spectrum() const { - return (int)_spectrum; - } - - //! Return the total number of pixel values. - /** - Return width()*\ref height()*\ref depth()*\ref spectrum(), - i.e. the total number of values of type \c T in the pixel buffer of the image instance. - \note - - The size() of an empty image is equal to \c 0. - - The allocated memory size for a pixel buffer of a non-shared \c CImg instance is equal to - size()*sizeof(T). - \par Example - \code - const CImg img(100,100,1,3); // Construct new 100x100 color image. - if (img.size()==30000) // Test succeeds. - std::printf("Pixel buffer uses %lu bytes", - img.size()*sizeof(float)); - \endcode - **/ - ulongT size() const { - return (ulongT)_width*_height*_depth*_spectrum; - } - - //! Return a pointer to the first pixel value. - /** - Return a \c T*, or a \c const \c T* pointer to the first value in the pixel buffer of the image instance, - whether the instance is \c const or not. - \note - - The data() of an empty image is equal to \c 0 (null pointer). - - The allocated pixel buffer for the image instance starts from \c data() - and goes to data()+\ref size() - 1 (included). - - To get the pointer to one particular location of the pixel buffer, use - data(unsigned int,unsigned int,unsigned int,unsigned int) instead. - **/ - T* data() { - return _data; - } - - //! Return a pointer to the first pixel value \const. - const T* data() const { - return _data; - } - - //! Return a pointer to a located pixel value. - /** - Return a \c T*, or a \c const \c T* pointer to the value located at (\c x,\c y,\c z,\c c) in the pixel buffer - of the image instance, - whether the instance is \c const or not. - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \note - - Writing \c img.data(x,y,z,c) is equivalent to &(img(x,y,z,c)). Thus, this method has the same - properties as operator()(unsigned int,unsigned int,unsigned int,unsigned int). - **/ -#if cimg_verbosity>=3 - T *data(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int c=0) { - const ulongT off = (ulongT)offset(x,y,z,c); - if (off>=size()) - cimg::warn(_cimg_instance - "data(): Invalid pointer request, at coordinates (%u,%u,%u,%u) [offset=%u].", - cimg_instance, - x,y,z,c,off); - return _data + off; - } - - //! Return a pointer to a located pixel value \const. - const T* data(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int c=0) const { - return const_cast*>(this)->data(x,y,z,c); - } -#else - T* data(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int c=0) { - return _data + x + (ulongT)y*_width + (ulongT)z*_width*_height + (ulongT)c*_width*_height*_depth; - } - - const T* data(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int c=0) const { - return _data + x + (ulongT)y*_width + (ulongT)z*_width*_height + (ulongT)c*_width*_height*_depth; - } -#endif - - //! Return the offset to a located pixel value, with respect to the beginning of the pixel buffer. - /** - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \note - - Writing \c img.data(x,y,z,c) is equivalent to &(img(x,y,z,c)) - img.data(). - Thus, this method has the same properties as operator()(unsigned int,unsigned int,unsigned int,unsigned int). - \par Example - \code - const CImg img(100,100,1,3); // Define a 100x100 RGB-color image. - const long off = img.offset(10,10,0,2); // Get the offset of the blue value of the pixel located at (10,10). - const float val = img[off]; // Get the blue value of this pixel. - \endcode - **/ - longT offset(const int x, const int y=0, const int z=0, const int c=0) const { - return x + (longT)y*_width + (longT)z*_width*_height + (longT)c*_width*_height*_depth; - } - - //! Return a CImg::iterator pointing to the first pixel value. - /** - \note - - Equivalent to data(). - - It has been mainly defined for compatibility with STL naming conventions. - **/ - iterator begin() { - return _data; - } - - //! Return a CImg::iterator pointing to the first value of the pixel buffer \const. - const_iterator begin() const { - return _data; - } - - //! Return a CImg::iterator pointing next to the last pixel value. - /** - \note - - Writing \c img.end() is equivalent to img.data() + img.size(). - - It has been mainly defined for compatibility with STL naming conventions. - \warning - - The returned iterator actually points to a value located \e outside the acceptable bounds of the pixel buffer. - Trying to read or write the content of the returned iterator will probably result in a crash. - Use it mainly as a strict upper bound for a CImg::iterator. - \par Example - \code - CImg img(100,100,1,3); // Define a 100x100 RGB color image. - for (CImg::iterator it = img.begin(); it::iterator pointing next to the last pixel value \const. - const_iterator end() const { - return _data + size(); - } - - //! Return a reference to the first pixel value. - /** - \note - - Writing \c img.front() is equivalent to img[0], or img(0,0,0,0). - - It has been mainly defined for compatibility with STL naming conventions. - **/ - T& front() { - return *_data; - } - - //! Return a reference to the first pixel value \const. - const T& front() const { - return *_data; - } - - //! Return a reference to the last pixel value. - /** - \note - - Writing \c img.end() is equivalent to img[img.size() - 1], or - img(img.width() - 1,img.height() - 1,img.depth() - 1,img.spectrum() - 1). - - It has been mainly defined for compatibility with STL naming conventions. - **/ - T& back() { - return *(_data + size() - 1); - } - - //! Return a reference to the last pixel value \const. - const T& back() const { - return *(_data + size() - 1); - } - - //! Access to a pixel value at a specified offset, using Dirichlet boundary conditions. - /** - Return a reference to the pixel value of the image instance located at a specified \c offset, - or to a specified default value in case of out-of-bounds access. - \param offset Offset to the desired pixel value. - \param out_value Default value returned if \c offset is outside image bounds. - \note - - Writing \c img.at(offset,out_value) is similar to img[offset], except that if \c offset - is outside bounds (e.g. \c offset<0 or \c offset>=img.size()), a reference to a value \c out_value - is safely returned instead. - - Due to the additional boundary checking operation, this method is slower than operator()(). Use it when - you are \e not sure about the validity of the specified pixel offset. - **/ - T& at(const int offset, const T& out_value) { - return (offset<0 || offset>=(int)size())?(cimg::temporary(out_value)=out_value):(*this)[offset]; - } - - //! Access to a pixel value at a specified offset, using Dirichlet boundary conditions \const. - T at(const int offset, const T& out_value) const { - return (offset<0 || offset>=(int)size())?out_value:(*this)[offset]; - } - - //! Access to a pixel value at a specified offset, using Neumann boundary conditions. - /** - Return a reference to the pixel value of the image instance located at a specified \c offset, - or to the nearest pixel location in the image instance in case of out-of-bounds access. - \param offset Offset to the desired pixel value. - \note - - Similar to at(int,const T), except that an out-of-bounds access returns the value of the - nearest pixel in the image instance, regarding the specified offset, i.e. - - If \c offset<0, then \c img[0] is returned. - - If \c offset>=img.size(), then \c img[img.size() - 1] is returned. - - Due to the additional boundary checking operation, this method is slower than operator()(). Use it when - you are \e not sure about the validity of the specified pixel offset. - - If you know your image instance is \e not empty, you may rather use the slightly faster method \c _at(int). - **/ - T& at(const int offset) { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "at(): Empty instance.", - cimg_instance); - return _at(offset); - } - - T& _at(const int offset) { - const unsigned int siz = (unsigned int)size(); - return (*this)[offset<0?0:(unsigned int)offset>=siz?siz - 1:offset]; - } - - //! Access to a pixel value at a specified offset, using Neumann boundary conditions \const. - const T& at(const int offset) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "at(): Empty instance.", - cimg_instance); - return _at(offset); - } - - const T& _at(const int offset) const { - const unsigned int siz = (unsigned int)size(); - return (*this)[offset<0?0:(unsigned int)offset>=siz?siz - 1:offset]; - } - - //! Access to a pixel value, using Dirichlet boundary conditions for the X-coordinate. - /** - Return a reference to the pixel value of the image instance located at (\c x,\c y,\c z,\c c), - or to a specified default value in case of out-of-bounds access along the X-axis. - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \param out_value Default value returned if \c (\c x,\c y,\c z,\c c) is outside image bounds. - \note - - Similar to operator()(), except that an out-of-bounds access along the X-axis returns the specified value - \c out_value. - - Due to the additional boundary checking operation, this method is slower than operator()(). Use it when - you are \e not sure about the validity of the specified pixel coordinates. - \warning - - There is \e no boundary checking performed for the Y,Z and C-coordinates, so they must be inside image bounds. - **/ - T& atX(const int x, const int y, const int z, const int c, const T& out_value) { - return (x<0 || x>=width())?(cimg::temporary(out_value)=out_value):(*this)(x,y,z,c); - } - - //! Access to a pixel value, using Dirichlet boundary conditions for the X-coordinate \const. - T atX(const int x, const int y, const int z, const int c, const T& out_value) const { - return (x<0 || x>=width())?out_value:(*this)(x,y,z,c); - } - - //! Access to a pixel value, using Neumann boundary conditions for the X-coordinate. - /** - Return a reference to the pixel value of the image instance located at (\c x,\c y,\c z,\c c), - or to the nearest pixel location in the image instance in case of out-of-bounds access along the X-axis. - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \note - - Similar to at(int,int,int,int,const T), except that an out-of-bounds access returns the value of the - nearest pixel in the image instance, regarding the specified X-coordinate. - - Due to the additional boundary checking operation, this method is slower than operator()(). Use it when - you are \e not sure about the validity of the specified pixel coordinates. - - If you know your image instance is \e not empty, you may rather use the slightly faster method - \c _at(int,int,int,int). - \warning - - There is \e no boundary checking performed for the Y,Z and C-coordinates, so they must be inside image bounds. - **/ - T& atX(const int x, const int y=0, const int z=0, const int c=0) { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "atX(): Empty instance.", - cimg_instance); - return _atX(x,y,z,c); - } - - T& _atX(const int x, const int y=0, const int z=0, const int c=0) { - return (*this)(x<0?0:(x>=width()?width() - 1:x),y,z,c); - } - - //! Access to a pixel value, using Neumann boundary conditions for the X-coordinate \const. - const T& atX(const int x, const int y=0, const int z=0, const int c=0) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "atX(): Empty instance.", - cimg_instance); - return _atX(x,y,z,c); - } - - const T& _atX(const int x, const int y=0, const int z=0, const int c=0) const { - return (*this)(x<0?0:(x>=width()?width() - 1:x),y,z,c); - } - - //! Access to a pixel value, using Dirichlet boundary conditions for the X and Y-coordinates. - /** - Similar to atX(int,int,int,int,const T), except that boundary checking is performed both on X and Y-coordinates. - **/ - T& atXY(const int x, const int y, const int z, const int c, const T& out_value) { - return (x<0 || y<0 || x>=width() || y>=height())?(cimg::temporary(out_value)=out_value):(*this)(x,y,z,c); - } - - //! Access to a pixel value, using Dirichlet boundary conditions for the X and Y coordinates \const. - T atXY(const int x, const int y, const int z, const int c, const T& out_value) const { - return (x<0 || y<0 || x>=width() || y>=height())?out_value:(*this)(x,y,z,c); - } - - //! Access to a pixel value, using Neumann boundary conditions for the X and Y-coordinates. - /** - Similar to atX(int,int,int,int), except that boundary checking is performed both on X and Y-coordinates. - \note - - If you know your image instance is \e not empty, you may rather use the slightly faster method - \c _atXY(int,int,int,int). - **/ - T& atXY(const int x, const int y, const int z=0, const int c=0) { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "atXY(): Empty instance.", - cimg_instance); - return _atXY(x,y,z,c); - } - - T& _atXY(const int x, const int y, const int z=0, const int c=0) { - return (*this)(x<0?0:(x>=width()?width() - 1:x), y<0?0:(y>=height()?height() - 1:y),z,c); - } - - //! Access to a pixel value, using Neumann boundary conditions for the X and Y-coordinates \const. - const T& atXY(const int x, const int y, const int z=0, const int c=0) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "atXY(): Empty instance.", - cimg_instance); - return _atXY(x,y,z,c); - } - - const T& _atXY(const int x, const int y, const int z=0, const int c=0) const { - return (*this)(x<0?0:(x>=width()?width() - 1:x), y<0?0:(y>=height()?height() - 1:y),z,c); - } - - //! Access to a pixel value, using Dirichlet boundary conditions for the X,Y and Z-coordinates. - /** - Similar to atX(int,int,int,int,const T), except that boundary checking is performed both on - X,Y and Z-coordinates. - **/ - T& atXYZ(const int x, const int y, const int z, const int c, const T& out_value) { - return (x<0 || y<0 || z<0 || x>=width() || y>=height() || z>=depth())? - (cimg::temporary(out_value)=out_value):(*this)(x,y,z,c); - } - - //! Access to a pixel value, using Dirichlet boundary conditions for the X,Y and Z-coordinates \const. - T atXYZ(const int x, const int y, const int z, const int c, const T& out_value) const { - return (x<0 || y<0 || z<0 || x>=width() || y>=height() || z>=depth())?out_value:(*this)(x,y,z,c); - } - - //! Access to a pixel value, using Neumann boundary conditions for the X,Y and Z-coordinates. - /** - Similar to atX(int,int,int,int), except that boundary checking is performed both on X,Y and Z-coordinates. - \note - - If you know your image instance is \e not empty, you may rather use the slightly faster method - \c _atXYZ(int,int,int,int). - **/ - T& atXYZ(const int x, const int y, const int z, const int c=0) { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "atXYZ(): Empty instance.", - cimg_instance); - return _atXYZ(x,y,z,c); - } - - T& _atXYZ(const int x, const int y, const int z, const int c=0) { - return (*this)(x<0?0:x>=width()?width() - 1:x,y<0?0:y>=height()?height() - 1:y, - z<0?0:z>=depth()?depth() - 1:z,c); - } - - //! Access to a pixel value, using Neumann boundary conditions for the X,Y and Z-coordinates \const. - const T& atXYZ(const int x, const int y, const int z, const int c=0) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "atXYZ(): Empty instance.", - cimg_instance); - return _atXYZ(x,y,z,c); - } - - const T& _atXYZ(const int x, const int y, const int z, const int c=0) const { - return (*this)(x<0?0:(x>=width()?width() - 1:x),y<0?0:(y>=height()?height() - 1:y), - z<0?0:(z>=depth()?depth() - 1:z),c); - } - - //! Access to a pixel value, using Dirichlet boundary conditions. - /** - Similar to atX(int,int,int,int,const T), except that boundary checking is performed on all - X,Y,Z and C-coordinates. - **/ - T& atXYZC(const int x, const int y, const int z, const int c, const T& out_value) { - return (x<0 || y<0 || z<0 || c<0 || x>=width() || y>=height() || z>=depth() || c>=spectrum())? - (cimg::temporary(out_value)=out_value):(*this)(x,y,z,c); - } - - //! Access to a pixel value, using Dirichlet boundary conditions \const. - T atXYZC(const int x, const int y, const int z, const int c, const T& out_value) const { - return (x<0 || y<0 || z<0 || c<0 || x>=width() || y>=height() || z>=depth() || c>=spectrum())?out_value: - (*this)(x,y,z,c); - } - - //! Access to a pixel value, using Neumann boundary conditions. - /** - Similar to atX(int,int,int,int), except that boundary checking is performed on all X,Y,Z and C-coordinates. - \note - - If you know your image instance is \e not empty, you may rather use the slightly faster method - \c _atXYZC(int,int,int,int). - **/ - T& atXYZC(const int x, const int y, const int z, const int c) { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "atXYZC(): Empty instance.", - cimg_instance); - return _atXYZC(x,y,z,c); - } - - T& _atXYZC(const int x, const int y, const int z, const int c) { - return (*this)(x<0?0:(x>=width()?width() - 1:x), y<0?0:(y>=height()?height() - 1:y), - z<0?0:(z>=depth()?depth() - 1:z), c<0?0:(c>=spectrum()?spectrum() - 1:c)); - } - - //! Access to a pixel value, using Neumann boundary conditions \const. - const T& atXYZC(const int x, const int y, const int z, const int c) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "atXYZC(): Empty instance.", - cimg_instance); - return _atXYZC(x,y,z,c); - } - - const T& _atXYZC(const int x, const int y, const int z, const int c) const { - return (*this)(x<0?0:(x>=width()?width() - 1:x), y<0?0:(y>=height()?height() - 1:y), - z<0?0:(z>=depth()?depth() - 1:z), c<0?0:(c>=spectrum()?spectrum() - 1:c)); - } - - //! Return pixel value, using linear interpolation and Dirichlet boundary conditions for the X-coordinate. - /** - Return a linearly-interpolated pixel value of the image instance located at (\c fx,\c y,\c z,\c c), - or a specified default value in case of out-of-bounds access along the X-axis. - \param fx X-coordinate of the pixel value (float-valued). - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \param out_value Default value returned if \c (\c fx,\c y,\c z,\c c) is outside image bounds. - \note - - Similar to atX(int,int,int,int,const T), except that the returned pixel value is approximated by - a linear interpolation along the X-axis, if corresponding coordinates are not integers. - - The type of the returned pixel value is extended to \c float, if the pixel type \c T is not float-valued. - \warning - - There is \e no boundary checking performed for the Y,Z and C-coordinates, so they must be inside image bounds. - **/ - Tfloat linear_atX(const float fx, const int y, const int z, const int c, const T& out_value) const { - const int - x = (int)fx - (fx>=0?0:1), nx = x + 1; - const float - dx = fx - x; - const Tfloat - Ic = (Tfloat)atX(x,y,z,c,out_value), In = (Tfloat)atXY(nx,y,z,c,out_value); - return Ic + dx*(In - Ic); - } - - //! Return pixel value, using linear interpolation and Neumann boundary conditions for the X-coordinate. - /** - Return a linearly-interpolated pixel value of the image instance located at (\c fx,\c y,\c z,\c c), - or the value of the nearest pixel location in the image instance in case of out-of-bounds access along - the X-axis. - \param fx X-coordinate of the pixel value (float-valued). - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \note - - Similar to linear_atX(float,int,int,int,const T) const, except that an out-of-bounds access returns - the value of the nearest pixel in the image instance, regarding the specified X-coordinate. - - If you know your image instance is \e not empty, you may rather use the slightly faster method - \c _linear_atX(float,int,int,int). - \warning - - There is \e no boundary checking performed for the Y,Z and C-coordinates, so they must be inside image bounds. - **/ - Tfloat linear_atX(const float fx, const int y=0, const int z=0, const int c=0) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "linear_atX(): Empty instance.", - cimg_instance); - - return _linear_atX(fx,y,z,c); - } - - Tfloat _linear_atX(const float fx, const int y=0, const int z=0, const int c=0) const { - const float - nfx = fx<0?0:(fx>_width - 1?_width - 1:fx); - const unsigned int - x = (unsigned int)nfx; - const float - dx = nfx - x; - const unsigned int - nx = dx>0?x + 1:x; - const Tfloat - Ic = (Tfloat)(*this)(x,y,z,c), In = (Tfloat)(*this)(nx,y,z,c); - return Ic + dx*(In - Ic); - } - - //! Return pixel value, using linear interpolation and Dirichlet boundary conditions for the X and Y-coordinates. - /** - Similar to linear_atX(float,int,int,int,const T) const, except that the linear interpolation and the - boundary checking are achieved both for X and Y-coordinates. - **/ - Tfloat linear_atXY(const float fx, const float fy, const int z, const int c, const T& out_value) const { - const int - x = (int)fx - (fx>=0?0:1), nx = x + 1, - y = (int)fy - (fy>=0?0:1), ny = y + 1; - const float - dx = fx - x, - dy = fy - y; - const Tfloat - Icc = (Tfloat)atXY(x,y,z,c,out_value), Inc = (Tfloat)atXY(nx,y,z,c,out_value), - Icn = (Tfloat)atXY(x,ny,z,c,out_value), Inn = (Tfloat)atXY(nx,ny,z,c,out_value); - return Icc + dx*(Inc - Icc + dy*(Icc + Inn - Icn - Inc)) + dy*(Icn - Icc); - } - - //! Return pixel value, using linear interpolation and Neumann boundary conditions for the X and Y-coordinates. - /** - Similar to linear_atX(float,int,int,int) const, except that the linear interpolation and the boundary checking - are achieved both for X and Y-coordinates. - \note - - If you know your image instance is \e not empty, you may rather use the slightly faster method - \c _linear_atXY(float,float,int,int). - **/ - Tfloat linear_atXY(const float fx, const float fy, const int z=0, const int c=0) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "linear_atXY(): Empty instance.", - cimg_instance); - - return _linear_atXY(fx,fy,z,c); - } - - Tfloat _linear_atXY(const float fx, const float fy, const int z=0, const int c=0) const { - const float - nfx = fx<0?0:(fx>_width - 1?_width - 1:fx), - nfy = fy<0?0:(fy>_height - 1?_height - 1:fy); - const unsigned int - x = (unsigned int)nfx, - y = (unsigned int)nfy; - const float - dx = nfx - x, - dy = nfy - y; - const unsigned int - nx = dx>0?x + 1:x, - ny = dy>0?y + 1:y; - const Tfloat - Icc = (Tfloat)(*this)(x,y,z,c), Inc = (Tfloat)(*this)(nx,y,z,c), - Icn = (Tfloat)(*this)(x,ny,z,c), Inn = (Tfloat)(*this)(nx,ny,z,c); - return Icc + dx*(Inc - Icc + dy*(Icc + Inn - Icn - Inc)) + dy*(Icn - Icc); - } - - //! Return pixel value, using linear interpolation and Dirichlet boundary conditions for the X,Y and Z-coordinates. - /** - Similar to linear_atX(float,int,int,int,const T) const, except that the linear interpolation and the - boundary checking are achieved both for X,Y and Z-coordinates. - **/ - Tfloat linear_atXYZ(const float fx, const float fy, const float fz, const int c, const T& out_value) const { - const int - x = (int)fx - (fx>=0?0:1), nx = x + 1, - y = (int)fy - (fy>=0?0:1), ny = y + 1, - z = (int)fz - (fz>=0?0:1), nz = z + 1; - const float - dx = fx - x, - dy = fy - y, - dz = fz - z; - const Tfloat - Iccc = (Tfloat)atXYZ(x,y,z,c,out_value), Incc = (Tfloat)atXYZ(nx,y,z,c,out_value), - Icnc = (Tfloat)atXYZ(x,ny,z,c,out_value), Innc = (Tfloat)atXYZ(nx,ny,z,c,out_value), - Iccn = (Tfloat)atXYZ(x,y,nz,c,out_value), Incn = (Tfloat)atXYZ(nx,y,nz,c,out_value), - Icnn = (Tfloat)atXYZ(x,ny,nz,c,out_value), Innn = (Tfloat)atXYZ(nx,ny,nz,c,out_value); - return Iccc + - dx*(Incc - Iccc + - dy*(Iccc + Innc - Icnc - Incc + - dz*(Iccn + Innn + Icnc + Incc - Icnn - Incn - Iccc - Innc)) + - dz*(Iccc + Incn - Iccn - Incc)) + - dy*(Icnc - Iccc + - dz*(Iccc + Icnn - Iccn - Icnc)) + - dz*(Iccn - Iccc); - } - - //! Return pixel value, using linear interpolation and Neumann boundary conditions for the X,Y and Z-coordinates. - /** - Similar to linear_atX(float,int,int,int) const, except that the linear interpolation and the boundary checking - are achieved both for X,Y and Z-coordinates. - \note - - If you know your image instance is \e not empty, you may rather use the slightly faster method - \c _linear_atXYZ(float,float,float,int). - **/ - Tfloat linear_atXYZ(const float fx, const float fy=0, const float fz=0, const int c=0) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "linear_atXYZ(): Empty instance.", - cimg_instance); - - return _linear_atXYZ(fx,fy,fz,c); - } - - Tfloat _linear_atXYZ(const float fx, const float fy=0, const float fz=0, const int c=0) const { - const float - nfx = fx<0?0:(fx>_width - 1?_width - 1:fx), - nfy = fy<0?0:(fy>_height - 1?_height - 1:fy), - nfz = fz<0?0:(fz>_depth - 1?_depth - 1:fz); - const unsigned int - x = (unsigned int)nfx, - y = (unsigned int)nfy, - z = (unsigned int)nfz; - const float - dx = nfx - x, - dy = nfy - y, - dz = nfz - z; - const unsigned int - nx = dx>0?x + 1:x, - ny = dy>0?y + 1:y, - nz = dz>0?z + 1:z; - const Tfloat - Iccc = (Tfloat)(*this)(x,y,z,c), Incc = (Tfloat)(*this)(nx,y,z,c), - Icnc = (Tfloat)(*this)(x,ny,z,c), Innc = (Tfloat)(*this)(nx,ny,z,c), - Iccn = (Tfloat)(*this)(x,y,nz,c), Incn = (Tfloat)(*this)(nx,y,nz,c), - Icnn = (Tfloat)(*this)(x,ny,nz,c), Innn = (Tfloat)(*this)(nx,ny,nz,c); - return Iccc + - dx*(Incc - Iccc + - dy*(Iccc + Innc - Icnc - Incc + - dz*(Iccn + Innn + Icnc + Incc - Icnn - Incn - Iccc - Innc)) + - dz*(Iccc + Incn - Iccn - Incc)) + - dy*(Icnc - Iccc + - dz*(Iccc + Icnn - Iccn - Icnc)) + - dz*(Iccn - Iccc); - } - - //! Return pixel value, using linear interpolation and Dirichlet boundary conditions for all X,Y,Z,C-coordinates. - /** - Similar to linear_atX(float,int,int,int,const T) const, except that the linear interpolation and the - boundary checking are achieved for all X,Y,Z and C-coordinates. - **/ - Tfloat linear_atXYZC(const float fx, const float fy, const float fz, const float fc, const T& out_value) const { - const int - x = (int)fx - (fx>=0?0:1), nx = x + 1, - y = (int)fy - (fy>=0?0:1), ny = y + 1, - z = (int)fz - (fz>=0?0:1), nz = z + 1, - c = (int)fc - (fc>=0?0:1), nc = c + 1; - const float - dx = fx - x, - dy = fy - y, - dz = fz - z, - dc = fc - c; - const Tfloat - Icccc = (Tfloat)atXYZC(x,y,z,c,out_value), Inccc = (Tfloat)atXYZC(nx,y,z,c,out_value), - Icncc = (Tfloat)atXYZC(x,ny,z,c,out_value), Inncc = (Tfloat)atXYZC(nx,ny,z,c,out_value), - Iccnc = (Tfloat)atXYZC(x,y,nz,c,out_value), Incnc = (Tfloat)atXYZC(nx,y,nz,c,out_value), - Icnnc = (Tfloat)atXYZC(x,ny,nz,c,out_value), Innnc = (Tfloat)atXYZC(nx,ny,nz,c,out_value), - Icccn = (Tfloat)atXYZC(x,y,z,nc,out_value), Inccn = (Tfloat)atXYZC(nx,y,z,nc,out_value), - Icncn = (Tfloat)atXYZC(x,ny,z,nc,out_value), Inncn = (Tfloat)atXYZC(nx,ny,z,nc,out_value), - Iccnn = (Tfloat)atXYZC(x,y,nz,nc,out_value), Incnn = (Tfloat)atXYZC(nx,y,nz,nc,out_value), - Icnnn = (Tfloat)atXYZC(x,ny,nz,nc,out_value), Innnn = (Tfloat)atXYZC(nx,ny,nz,nc,out_value); - return Icccc + - dx*(Inccc - Icccc + - dy*(Icccc + Inncc - Icncc - Inccc + - dz*(Iccnc + Innnc + Icncc + Inccc - Icnnc - Incnc - Icccc - Inncc + - dc*(Iccnn + Innnn + Icncn + Inccn + Icnnc + Incnc + Icccc + Inncc - - Icnnn - Incnn - Icccn - Inncn - Iccnc - Innnc - Icncc - Inccc)) + - dc*(Icccn + Inncn + Icncc + Inccc - Icncn - Inccn - Icccc - Inncc)) + - dz*(Icccc + Incnc - Iccnc - Inccc + - dc*(Icccn + Incnn + Iccnc + Inccc - Iccnn - Inccn - Icccc - Incnc)) + - dc*(Icccc + Inccn - Inccc - Icccn)) + - dy*(Icncc - Icccc + - dz*(Icccc + Icnnc - Iccnc - Icncc + - dc*(Icccn + Icnnn + Iccnc + Icncc - Iccnn - Icncn - Icccc - Icnnc)) + - dc*(Icccc + Icncn - Icncc - Icccn)) + - dz*(Iccnc - Icccc + - dc*(Icccc + Iccnn - Iccnc - Icccn)) + - dc*(Icccn -Icccc); - } - - //! Return pixel value, using linear interpolation and Neumann boundary conditions for all X,Y,Z and C-coordinates. - /** - Similar to linear_atX(float,int,int,int) const, except that the linear interpolation and the boundary checking - are achieved for all X,Y,Z and C-coordinates. - \note - - If you know your image instance is \e not empty, you may rather use the slightly faster method - \c _linear_atXYZC(float,float,float,float). - **/ - Tfloat linear_atXYZC(const float fx, const float fy=0, const float fz=0, const float fc=0) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "linear_atXYZC(): Empty instance.", - cimg_instance); - - return _linear_atXYZC(fx,fy,fz,fc); - } - - Tfloat _linear_atXYZC(const float fx, const float fy=0, const float fz=0, const float fc=0) const { - const float - nfx = fx<0?0:(fx>_width - 1?_width - 1:fx), - nfy = fy<0?0:(fy>_height - 1?_height - 1:fy), - nfz = fz<0?0:(fz>_depth - 1?_depth - 1:fz), - nfc = fc<0?0:(fc>_spectrum - 1?_spectrum - 1:fc); - const unsigned int - x = (unsigned int)nfx, - y = (unsigned int)nfy, - z = (unsigned int)nfz, - c = (unsigned int)nfc; - const float - dx = nfx - x, - dy = nfy - y, - dz = nfz - z, - dc = nfc - c; - const unsigned int - nx = dx>0?x + 1:x, - ny = dy>0?y + 1:y, - nz = dz>0?z + 1:z, - nc = dc>0?c + 1:c; - const Tfloat - Icccc = (Tfloat)(*this)(x,y,z,c), Inccc = (Tfloat)(*this)(nx,y,z,c), - Icncc = (Tfloat)(*this)(x,ny,z,c), Inncc = (Tfloat)(*this)(nx,ny,z,c), - Iccnc = (Tfloat)(*this)(x,y,nz,c), Incnc = (Tfloat)(*this)(nx,y,nz,c), - Icnnc = (Tfloat)(*this)(x,ny,nz,c), Innnc = (Tfloat)(*this)(nx,ny,nz,c), - Icccn = (Tfloat)(*this)(x,y,z,nc), Inccn = (Tfloat)(*this)(nx,y,z,nc), - Icncn = (Tfloat)(*this)(x,ny,z,nc), Inncn = (Tfloat)(*this)(nx,ny,z,nc), - Iccnn = (Tfloat)(*this)(x,y,nz,nc), Incnn = (Tfloat)(*this)(nx,y,nz,nc), - Icnnn = (Tfloat)(*this)(x,ny,nz,nc), Innnn = (Tfloat)(*this)(nx,ny,nz,nc); - return Icccc + - dx*(Inccc - Icccc + - dy*(Icccc + Inncc - Icncc - Inccc + - dz*(Iccnc + Innnc + Icncc + Inccc - Icnnc - Incnc - Icccc - Inncc + - dc*(Iccnn + Innnn + Icncn + Inccn + Icnnc + Incnc + Icccc + Inncc - - Icnnn - Incnn - Icccn - Inncn - Iccnc - Innnc - Icncc - Inccc)) + - dc*(Icccn + Inncn + Icncc + Inccc - Icncn - Inccn - Icccc - Inncc)) + - dz*(Icccc + Incnc - Iccnc - Inccc + - dc*(Icccn + Incnn + Iccnc + Inccc - Iccnn - Inccn - Icccc - Incnc)) + - dc*(Icccc + Inccn - Inccc - Icccn)) + - dy*(Icncc - Icccc + - dz*(Icccc + Icnnc - Iccnc - Icncc + - dc*(Icccn + Icnnn + Iccnc + Icncc - Iccnn - Icncn - Icccc - Icnnc)) + - dc*(Icccc + Icncn - Icncc - Icccn)) + - dz*(Iccnc - Icccc + - dc*(Icccc + Iccnn - Iccnc - Icccn)) + - dc*(Icccn - Icccc); - } - - //! Return pixel value, using cubic interpolation and Dirichlet boundary conditions for the X-coordinate. - /** - Return a cubicly-interpolated pixel value of the image instance located at (\c fx,\c y,\c z,\c c), - or a specified default value in case of out-of-bounds access along the X-axis. - The cubic interpolation uses Hermite splines. - \param fx d X-coordinate of the pixel value (float-valued). - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \param out_value Default value returned if \c (\c fx,\c y,\c z,\c c) is outside image bounds. - \note - - Similar to linear_atX(float,int,int,int,const T) const, except that the returned pixel value is - approximated by a \e cubic interpolation along the X-axis. - - The type of the returned pixel value is extended to \c float, if the pixel type \c T is not float-valued. - \warning - - There is \e no boundary checking performed for the Y,Z and C-coordinates, so they must be inside image bounds. - **/ - Tfloat cubic_atX(const float fx, const int y, const int z, const int c, const T& out_value) const { - const int - x = (int)fx - (fx>=0?0:1), px = x - 1, nx = x + 1, ax = x + 2; - const float - dx = fx - x; - const Tfloat - Ip = (Tfloat)atX(px,y,z,c,out_value), Ic = (Tfloat)atX(x,y,z,c,out_value), - In = (Tfloat)atX(nx,y,z,c,out_value), Ia = (Tfloat)atX(ax,y,z,c,out_value); - return Ic + 0.5f*(dx*(-Ip + In) + dx*dx*(2*Ip - 5*Ic + 4*In - Ia) + dx*dx*dx*(-Ip + 3*Ic - 3*In + Ia)); - } - - //! Return damped pixel value, using cubic interpolation and Dirichlet boundary conditions for the X-coordinate. - /** - Similar to cubic_atX(float,int,int,int,const T) const, except that you can specify the authorized minimum - and maximum of the returned value. - **/ - Tfloat cubic_atX(const float fx, const int y, const int z, const int c, const T& out_value, - const Tfloat min_value, const Tfloat max_value) const { - const Tfloat val = cubic_atX(fx,y,z,c,out_value); - return valmax_value?max_value:val; - } - - //! Return pixel value, using cubic interpolation and Neumann boundary conditions for the X-coordinate. - /** - Return a cubicly-interpolated pixel value of the image instance located at (\c fx,\c y,\c z,\c c), - or the value of the nearest pixel location in the image instance in case of out-of-bounds access - along the X-axis. The cubic interpolation uses Hermite splines. - \param fx X-coordinate of the pixel value (float-valued). - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \note - - Similar to cubic_atX(float,int,int,int,const T) const, except that the returned pixel value is - approximated by a cubic interpolation along the X-axis. - - If you know your image instance is \e not empty, you may rather use the slightly faster method - \c _cubic_atX(float,int,int,int). - \warning - - There is \e no boundary checking performed for the Y,Z and C-coordinates, so they must be inside image bounds. - **/ - Tfloat cubic_atX(const float fx, const int y=0, const int z=0, const int c=0) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "cubic_atX(): Empty instance.", - cimg_instance); - return _cubic_atX(fx,y,z,c); - } - - Tfloat _cubic_atX(const float fx, const int y=0, const int z=0, const int c=0) const { - const float - nfx = fx<0?0:(fx>_width - 1?_width - 1:fx); - const int - x = (int)nfx; - const float - dx = nfx - x; - const int - px = x - 1<0?0:x - 1, nx = dx>0?x + 1:x, ax = x + 2>=width()?width() - 1:x + 2; - const Tfloat - Ip = (Tfloat)(*this)(px,y,z,c), Ic = (Tfloat)(*this)(x,y,z,c), - In = (Tfloat)(*this)(nx,y,z,c), Ia = (Tfloat)(*this)(ax,y,z,c); - return Ic + 0.5f*(dx*(-Ip + In) + dx*dx*(2*Ip - 5*Ic + 4*In - Ia) + dx*dx*dx*(-Ip + 3*Ic - 3*In + Ia)); - } - - //! Return damped pixel value, using cubic interpolation and Neumann boundary conditions for the X-coordinate. - /** - Similar to cubic_atX(float,int,int,int) const, except that you can specify the authorized minimum and maximum - of the returned value. - **/ - Tfloat cubic_atX(const float fx, const int y, const int z, const int c, - const Tfloat min_value, const Tfloat max_value) const { - const Tfloat val = cubic_atX(fx,y,z,c); - return valmax_value?max_value:val; - } - - Tfloat _cubic_atX(const float fx, const int y, const int z, const int c, - const Tfloat min_value, const Tfloat max_value) const { - const Tfloat val = _cubic_atX(fx,y,z,c); - return valmax_value?max_value:val; - } - - //! Return pixel value, using cubic interpolation and Dirichlet boundary conditions for the X and Y-coordinates. - /** - Similar to cubic_atX(float,int,int,int,const T) const, except that the cubic interpolation and boundary checking - are achieved both for X and Y-coordinates. - **/ - Tfloat cubic_atXY(const float fx, const float fy, const int z, const int c, const T& out_value) const { - const int - x = (int)fx - (fx>=0?0:1), px = x - 1, nx = x + 1, ax = x + 2, - y = (int)fy - (fy>=0?0:1), py = y - 1, ny = y + 1, ay = y + 2; - const float dx = fx - x, dy = fy - y; - const Tfloat - Ipp = (Tfloat)atXY(px,py,z,c,out_value), Icp = (Tfloat)atXY(x,py,z,c,out_value), - Inp = (Tfloat)atXY(nx,py,z,c,out_value), Iap = (Tfloat)atXY(ax,py,z,c,out_value), - Ip = Icp + 0.5f*(dx*(-Ipp + Inp) + dx*dx*(2*Ipp - 5*Icp + 4*Inp - Iap) + dx*dx*dx*(-Ipp + 3*Icp - 3*Inp + Iap)), - Ipc = (Tfloat)atXY(px,y,z,c,out_value), Icc = (Tfloat)atXY(x, y,z,c,out_value), - Inc = (Tfloat)atXY(nx,y,z,c,out_value), Iac = (Tfloat)atXY(ax,y,z,c,out_value), - Ic = Icc + 0.5f*(dx*(-Ipc + Inc) + dx*dx*(2*Ipc - 5*Icc + 4*Inc - Iac) + dx*dx*dx*(-Ipc + 3*Icc - 3*Inc + Iac)), - Ipn = (Tfloat)atXY(px,ny,z,c,out_value), Icn = (Tfloat)atXY(x,ny,z,c,out_value), - Inn = (Tfloat)atXY(nx,ny,z,c,out_value), Ian = (Tfloat)atXY(ax,ny,z,c,out_value), - In = Icn + 0.5f*(dx*(-Ipn + Inn) + dx*dx*(2*Ipn - 5*Icn + 4*Inn - Ian) + dx*dx*dx*(-Ipn + 3*Icn - 3*Inn + Ian)), - Ipa = (Tfloat)atXY(px,ay,z,c,out_value), Ica = (Tfloat)atXY(x,ay,z,c,out_value), - Ina = (Tfloat)atXY(nx,ay,z,c,out_value), Iaa = (Tfloat)atXY(ax,ay,z,c,out_value), - Ia = Ica + 0.5f*(dx*(-Ipa + Ina) + dx*dx*(2*Ipa - 5*Ica + 4*Ina - Iaa) + dx*dx*dx*(-Ipa + 3*Ica - 3*Ina + Iaa)); - return Ic + 0.5f*(dy*(-Ip + In) + dy*dy*(2*Ip - 5*Ic + 4*In - Ia) + dy*dy*dy*(-Ip + 3*Ic - 3*In + Ia)); - } - - //! Return damped pixel value, using cubic interpolation and Dirichlet boundary conditions for the X,Y-coordinates. - /** - Similar to cubic_atXY(float,float,int,int,const T) const, except that you can specify the authorized - minimum and maximum of the returned value. - **/ - Tfloat cubic_atXY(const float fx, const float fy, const int z, const int c, const T& out_value, - const Tfloat min_value, const Tfloat max_value) const { - const Tfloat val = cubic_atXY(fx,fy,z,c,out_value); - return valmax_value?max_value:val; - } - - //! Return pixel value, using cubic interpolation and Neumann boundary conditions for the X and Y-coordinates. - /** - Similar to cubic_atX(float,int,int,int) const, except that the cubic interpolation and boundary checking - are achieved for both X and Y-coordinates. - \note - - If you know your image instance is \e not empty, you may rather use the slightly faster method - \c _cubic_atXY(float,float,int,int). - **/ - Tfloat cubic_atXY(const float fx, const float fy, const int z=0, const int c=0) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "cubic_atXY(): Empty instance.", - cimg_instance); - return _cubic_atXY(fx,fy,z,c); - } - - Tfloat _cubic_atXY(const float fx, const float fy, const int z=0, const int c=0) const { - const float - nfx = fx<0?0:(fx>_width - 1?_width - 1:fx), - nfy = fy<0?0:(fy>_height - 1?_height - 1:fy); - const int x = (int)nfx, y = (int)nfy; - const float dx = nfx - x, dy = nfy - y; - const int - px = x - 1<0?0:x - 1, nx = dx>0?x + 1:x, ax = x + 2>=width()?width() - 1:x + 2, - py = y - 1<0?0:y - 1, ny = dy>0?y + 1:y, ay = y + 2>=height()?height() - 1:y + 2; - const Tfloat - Ipp = (Tfloat)(*this)(px,py,z,c), Icp = (Tfloat)(*this)(x,py,z,c), Inp = (Tfloat)(*this)(nx,py,z,c), - Iap = (Tfloat)(*this)(ax,py,z,c), - Ip = Icp + 0.5f*(dx*(-Ipp + Inp) + dx*dx*(2*Ipp - 5*Icp + 4*Inp - Iap) + dx*dx*dx*(-Ipp + 3*Icp - 3*Inp + Iap)), - Ipc = (Tfloat)(*this)(px,y,z,c), Icc = (Tfloat)(*this)(x, y,z,c), Inc = (Tfloat)(*this)(nx,y,z,c), - Iac = (Tfloat)(*this)(ax,y,z,c), - Ic = Icc + 0.5f*(dx*(-Ipc + Inc) + dx*dx*(2*Ipc - 5*Icc + 4*Inc - Iac) + dx*dx*dx*(-Ipc + 3*Icc - 3*Inc + Iac)), - Ipn = (Tfloat)(*this)(px,ny,z,c), Icn = (Tfloat)(*this)(x,ny,z,c), Inn = (Tfloat)(*this)(nx,ny,z,c), - Ian = (Tfloat)(*this)(ax,ny,z,c), - In = Icn + 0.5f*(dx*(-Ipn + Inn) + dx*dx*(2*Ipn - 5*Icn + 4*Inn - Ian) + dx*dx*dx*(-Ipn + 3*Icn - 3*Inn + Ian)), - Ipa = (Tfloat)(*this)(px,ay,z,c), Ica = (Tfloat)(*this)(x,ay,z,c), Ina = (Tfloat)(*this)(nx,ay,z,c), - Iaa = (Tfloat)(*this)(ax,ay,z,c), - Ia = Ica + 0.5f*(dx*(-Ipa + Ina) + dx*dx*(2*Ipa - 5*Ica + 4*Ina - Iaa) + dx*dx*dx*(-Ipa + 3*Ica - 3*Ina + Iaa)); - return Ic + 0.5f*(dy*(-Ip + In) + dy*dy*(2*Ip - 5*Ic + 4*In - Ia) + dy*dy*dy*(-Ip + 3*Ic - 3*In + Ia)); - } - - //! Return damped pixel value, using cubic interpolation and Neumann boundary conditions for the X,Y-coordinates. - /** - Similar to cubic_atXY(float,float,int,int) const, except that you can specify the authorized minimum and - maximum of the returned value. - **/ - Tfloat cubic_atXY(const float fx, const float fy, const int z, const int c, - const Tfloat min_value, const Tfloat max_value) const { - const Tfloat val = cubic_atXY(fx,fy,z,c); - return valmax_value?max_value:val; - } - - Tfloat _cubic_atXY(const float fx, const float fy, const int z, const int c, - const Tfloat min_value, const Tfloat max_value) const { - const Tfloat val = _cubic_atXY(fx,fy,z,c); - return valmax_value?max_value:val; - } - - //! Return pixel value, using cubic interpolation and Dirichlet boundary conditions for the X,Y and Z-coordinates. - /** - Similar to cubic_atX(float,int,int,int,const T) const, except that the cubic interpolation and boundary checking - are achieved both for X,Y and Z-coordinates. - **/ - Tfloat cubic_atXYZ(const float fx, const float fy, const float fz, const int c, const T& out_value) const { - const int - x = (int)fx - (fx>=0?0:1), px = x - 1, nx = x + 1, ax = x + 2, - y = (int)fy - (fy>=0?0:1), py = y - 1, ny = y + 1, ay = y + 2, - z = (int)fz - (fz>=0?0:1), pz = z - 1, nz = z + 1, az = z + 2; - const float dx = fx - x, dy = fy - y, dz = fz - z; - const Tfloat - Ippp = (Tfloat)atXYZ(px,py,pz,c,out_value), Icpp = (Tfloat)atXYZ(x,py,pz,c,out_value), - Inpp = (Tfloat)atXYZ(nx,py,pz,c,out_value), Iapp = (Tfloat)atXYZ(ax,py,pz,c,out_value), - Ipp = Icpp + 0.5f*(dx*(-Ippp + Inpp) + dx*dx*(2*Ippp - 5*Icpp + 4*Inpp - Iapp) + - dx*dx*dx*(-Ippp + 3*Icpp - 3*Inpp + Iapp)), - Ipcp = (Tfloat)atXYZ(px,y,pz,c,out_value), Iccp = (Tfloat)atXYZ(x, y,pz,c,out_value), - Incp = (Tfloat)atXYZ(nx,y,pz,c,out_value), Iacp = (Tfloat)atXYZ(ax,y,pz,c,out_value), - Icp = Iccp + 0.5f*(dx*(-Ipcp + Incp) + dx*dx*(2*Ipcp - 5*Iccp + 4*Incp - Iacp) + - dx*dx*dx*(-Ipcp + 3*Iccp - 3*Incp + Iacp)), - Ipnp = (Tfloat)atXYZ(px,ny,pz,c,out_value), Icnp = (Tfloat)atXYZ(x,ny,pz,c,out_value), - Innp = (Tfloat)atXYZ(nx,ny,pz,c,out_value), Ianp = (Tfloat)atXYZ(ax,ny,pz,c,out_value), - Inp = Icnp + 0.5f*(dx*(-Ipnp + Innp) + dx*dx*(2*Ipnp - 5*Icnp + 4*Innp - Ianp) + - dx*dx*dx*(-Ipnp + 3*Icnp - 3*Innp + Ianp)), - Ipap = (Tfloat)atXYZ(px,ay,pz,c,out_value), Icap = (Tfloat)atXYZ(x,ay,pz,c,out_value), - Inap = (Tfloat)atXYZ(nx,ay,pz,c,out_value), Iaap = (Tfloat)atXYZ(ax,ay,pz,c,out_value), - Iap = Icap + 0.5f*(dx*(-Ipap + Inap) + dx*dx*(2*Ipap - 5*Icap + 4*Inap - Iaap) + - dx*dx*dx*(-Ipap + 3*Icap - 3*Inap + Iaap)), - Ip = Icp + 0.5f*(dy*(-Ipp + Inp) + dy*dy*(2*Ipp - 5*Icp + 4*Inp - Iap) + - dy*dy*dy*(-Ipp + 3*Icp - 3*Inp + Iap)), - Ippc = (Tfloat)atXYZ(px,py,z,c,out_value), Icpc = (Tfloat)atXYZ(x,py,z,c,out_value), - Inpc = (Tfloat)atXYZ(nx,py,z,c,out_value), Iapc = (Tfloat)atXYZ(ax,py,z,c,out_value), - Ipc = Icpc + 0.5f*(dx*(-Ippc + Inpc) + dx*dx*(2*Ippc - 5*Icpc + 4*Inpc - Iapc) + - dx*dx*dx*(-Ippc + 3*Icpc - 3*Inpc + Iapc)), - Ipcc = (Tfloat)atXYZ(px,y,z,c,out_value), Iccc = (Tfloat)atXYZ(x, y,z,c,out_value), - Incc = (Tfloat)atXYZ(nx,y,z,c,out_value), Iacc = (Tfloat)atXYZ(ax,y,z,c,out_value), - Icc = Iccc + 0.5f*(dx*(-Ipcc + Incc) + dx*dx*(2*Ipcc - 5*Iccc + 4*Incc - Iacc) + - dx*dx*dx*(-Ipcc + 3*Iccc - 3*Incc + Iacc)), - Ipnc = (Tfloat)atXYZ(px,ny,z,c,out_value), Icnc = (Tfloat)atXYZ(x,ny,z,c,out_value), - Innc = (Tfloat)atXYZ(nx,ny,z,c,out_value), Ianc = (Tfloat)atXYZ(ax,ny,z,c,out_value), - Inc = Icnc + 0.5f*(dx*(-Ipnc + Innc) + dx*dx*(2*Ipnc - 5*Icnc + 4*Innc - Ianc) + - dx*dx*dx*(-Ipnc + 3*Icnc - 3*Innc + Ianc)), - Ipac = (Tfloat)atXYZ(px,ay,z,c,out_value), Icac = (Tfloat)atXYZ(x,ay,z,c,out_value), - Inac = (Tfloat)atXYZ(nx,ay,z,c,out_value), Iaac = (Tfloat)atXYZ(ax,ay,z,c,out_value), - Iac = Icac + 0.5f*(dx*(-Ipac + Inac) + dx*dx*(2*Ipac - 5*Icac + 4*Inac - Iaac) + - dx*dx*dx*(-Ipac + 3*Icac - 3*Inac + Iaac)), - Ic = Icc + 0.5f*(dy*(-Ipc + Inc) + dy*dy*(2*Ipc - 5*Icc + 4*Inc - Iac) + - dy*dy*dy*(-Ipc + 3*Icc - 3*Inc + Iac)), - Ippn = (Tfloat)atXYZ(px,py,nz,c,out_value), Icpn = (Tfloat)atXYZ(x,py,nz,c,out_value), - Inpn = (Tfloat)atXYZ(nx,py,nz,c,out_value), Iapn = (Tfloat)atXYZ(ax,py,nz,c,out_value), - Ipn = Icpn + 0.5f*(dx*(-Ippn + Inpn) + dx*dx*(2*Ippn - 5*Icpn + 4*Inpn - Iapn) + - dx*dx*dx*(-Ippn + 3*Icpn - 3*Inpn + Iapn)), - Ipcn = (Tfloat)atXYZ(px,y,nz,c,out_value), Iccn = (Tfloat)atXYZ(x, y,nz,c,out_value), - Incn = (Tfloat)atXYZ(nx,y,nz,c,out_value), Iacn = (Tfloat)atXYZ(ax,y,nz,c,out_value), - Icn = Iccn + 0.5f*(dx*(-Ipcn + Incn) + dx*dx*(2*Ipcn - 5*Iccn + 4*Incn - Iacn) + - dx*dx*dx*(-Ipcn + 3*Iccn - 3*Incn + Iacn)), - Ipnn = (Tfloat)atXYZ(px,ny,nz,c,out_value), Icnn = (Tfloat)atXYZ(x,ny,nz,c,out_value), - Innn = (Tfloat)atXYZ(nx,ny,nz,c,out_value), Iann = (Tfloat)atXYZ(ax,ny,nz,c,out_value), - Inn = Icnn + 0.5f*(dx*(-Ipnn + Innn) + dx*dx*(2*Ipnn - 5*Icnn + 4*Innn - Iann) + - dx*dx*dx*(-Ipnn + 3*Icnn - 3*Innn + Iann)), - Ipan = (Tfloat)atXYZ(px,ay,nz,c,out_value), Ican = (Tfloat)atXYZ(x,ay,nz,c,out_value), - Inan = (Tfloat)atXYZ(nx,ay,nz,c,out_value), Iaan = (Tfloat)atXYZ(ax,ay,nz,c,out_value), - Ian = Ican + 0.5f*(dx*(-Ipan + Inan) + dx*dx*(2*Ipan - 5*Ican + 4*Inan - Iaan) + - dx*dx*dx*(-Ipan + 3*Ican - 3*Inan + Iaan)), - In = Icn + 0.5f*(dy*(-Ipn + Inn) + dy*dy*(2*Ipn - 5*Icn + 4*Inn - Ian) + - dy*dy*dy*(-Ipn + 3*Icn - 3*Inn + Ian)), - Ippa = (Tfloat)atXYZ(px,py,az,c,out_value), Icpa = (Tfloat)atXYZ(x,py,az,c,out_value), - Inpa = (Tfloat)atXYZ(nx,py,az,c,out_value), Iapa = (Tfloat)atXYZ(ax,py,az,c,out_value), - Ipa = Icpa + 0.5f*(dx*(-Ippa + Inpa) + dx*dx*(2*Ippa - 5*Icpa + 4*Inpa - Iapa) + - dx*dx*dx*(-Ippa + 3*Icpa - 3*Inpa + Iapa)), - Ipca = (Tfloat)atXYZ(px,y,az,c,out_value), Icca = (Tfloat)atXYZ(x, y,az,c,out_value), - Inca = (Tfloat)atXYZ(nx,y,az,c,out_value), Iaca = (Tfloat)atXYZ(ax,y,az,c,out_value), - Ica = Icca + 0.5f*(dx*(-Ipca + Inca) + dx*dx*(2*Ipca - 5*Icca + 4*Inca - Iaca) + - dx*dx*dx*(-Ipca + 3*Icca - 3*Inca + Iaca)), - Ipna = (Tfloat)atXYZ(px,ny,az,c,out_value), Icna = (Tfloat)atXYZ(x,ny,az,c,out_value), - Inna = (Tfloat)atXYZ(nx,ny,az,c,out_value), Iana = (Tfloat)atXYZ(ax,ny,az,c,out_value), - Ina = Icna + 0.5f*(dx*(-Ipna + Inna) + dx*dx*(2*Ipna - 5*Icna + 4*Inna - Iana) + - dx*dx*dx*(-Ipna + 3*Icna - 3*Inna + Iana)), - Ipaa = (Tfloat)atXYZ(px,ay,az,c,out_value), Icaa = (Tfloat)atXYZ(x,ay,az,c,out_value), - Inaa = (Tfloat)atXYZ(nx,ay,az,c,out_value), Iaaa = (Tfloat)atXYZ(ax,ay,az,c,out_value), - Iaa = Icaa + 0.5f*(dx*(-Ipaa + Inaa) + dx*dx*(2*Ipaa - 5*Icaa + 4*Inaa - Iaaa) + - dx*dx*dx*(-Ipaa + 3*Icaa - 3*Inaa + Iaaa)), - Ia = Ica + 0.5f*(dy*(-Ipa + Ina) + dy*dy*(2*Ipa - 5*Ica + 4*Ina - Iaa) + - dy*dy*dy*(-Ipa + 3*Ica - 3*Ina + Iaa)); - return Ic + 0.5f*(dz*(-Ip + In) + dz*dz*(2*Ip - 5*Ic + 4*In - Ia) + dz*dz*dz*(-Ip + 3*Ic - 3*In + Ia)); - } - - //! Return damped pixel value, using cubic interpolation and Dirichlet boundary conditions for the XYZ-coordinates. - /** - Similar to cubic_atXYZ(float,float,float,int,const T) const, except that you can specify the authorized - minimum and maximum of the returned value. - **/ - Tfloat cubic_atXYZ(const float fx, const float fy, const float fz, const int c, const T& out_value, - const Tfloat min_value, const Tfloat max_value) const { - const Tfloat val = cubic_atXYZ(fx,fy,fz,c,out_value); - return valmax_value?max_value:val; - } - - //! Return pixel value, using cubic interpolation and Neumann boundary conditions for the X,Y and Z-coordinates. - /** - Similar to cubic_atX(float,int,int,int) const, except that the cubic interpolation and boundary checking - are achieved both for X,Y and Z-coordinates. - \note - - If you know your image instance is \e not empty, you may rather use the slightly faster method - \c _cubic_atXYZ(float,float,float,int). - **/ - Tfloat cubic_atXYZ(const float fx, const float fy, const float fz, const int c=0) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "cubic_atXYZ(): Empty instance.", - cimg_instance); - return _cubic_atXYZ(fx,fy,fz,c); - } - - Tfloat _cubic_atXYZ(const float fx, const float fy, const float fz, const int c=0) const { - const float - nfx = fx<0?0:(fx>_width - 1?_width - 1:fx), - nfy = fy<0?0:(fy>_height - 1?_height - 1:fy), - nfz = fz<0?0:(fz>_depth - 1?_depth - 1:fz); - const int x = (int)nfx, y = (int)nfy, z = (int)nfz; - const float dx = nfx - x, dy = nfy - y, dz = nfz - z; - const int - px = x - 1<0?0:x - 1, nx = dx>0?x + 1:x, ax = x + 2>=width()?width() - 1:x + 2, - py = y - 1<0?0:y - 1, ny = dy>0?y + 1:y, ay = y + 2>=height()?height() - 1:y + 2, - pz = z - 1<0?0:z - 1, nz = dz>0?z + 1:z, az = z + 2>=depth()?depth() - 1:z + 2; - const Tfloat - Ippp = (Tfloat)(*this)(px,py,pz,c), Icpp = (Tfloat)(*this)(x,py,pz,c), - Inpp = (Tfloat)(*this)(nx,py,pz,c), Iapp = (Tfloat)(*this)(ax,py,pz,c), - Ipp = Icpp + 0.5f*(dx*(-Ippp + Inpp) + dx*dx*(2*Ippp - 5*Icpp + 4*Inpp - Iapp) + - dx*dx*dx*(-Ippp + 3*Icpp - 3*Inpp + Iapp)), - Ipcp = (Tfloat)(*this)(px,y,pz,c), Iccp = (Tfloat)(*this)(x, y,pz,c), - Incp = (Tfloat)(*this)(nx,y,pz,c), Iacp = (Tfloat)(*this)(ax,y,pz,c), - Icp = Iccp + 0.5f*(dx*(-Ipcp + Incp) + dx*dx*(2*Ipcp - 5*Iccp + 4*Incp - Iacp) + - dx*dx*dx*(-Ipcp + 3*Iccp - 3*Incp + Iacp)), - Ipnp = (Tfloat)(*this)(px,ny,pz,c), Icnp = (Tfloat)(*this)(x,ny,pz,c), - Innp = (Tfloat)(*this)(nx,ny,pz,c), Ianp = (Tfloat)(*this)(ax,ny,pz,c), - Inp = Icnp + 0.5f*(dx*(-Ipnp + Innp) + dx*dx*(2*Ipnp - 5*Icnp + 4*Innp - Ianp) + - dx*dx*dx*(-Ipnp + 3*Icnp - 3*Innp + Ianp)), - Ipap = (Tfloat)(*this)(px,ay,pz,c), Icap = (Tfloat)(*this)(x,ay,pz,c), - Inap = (Tfloat)(*this)(nx,ay,pz,c), Iaap = (Tfloat)(*this)(ax,ay,pz,c), - Iap = Icap + 0.5f*(dx*(-Ipap + Inap) + dx*dx*(2*Ipap - 5*Icap + 4*Inap - Iaap) + - dx*dx*dx*(-Ipap + 3*Icap - 3*Inap + Iaap)), - Ip = Icp + 0.5f*(dy*(-Ipp + Inp) + dy*dy*(2*Ipp - 5*Icp + 4*Inp - Iap) + - dy*dy*dy*(-Ipp + 3*Icp - 3*Inp + Iap)), - Ippc = (Tfloat)(*this)(px,py,z,c), Icpc = (Tfloat)(*this)(x,py,z,c), - Inpc = (Tfloat)(*this)(nx,py,z,c), Iapc = (Tfloat)(*this)(ax,py,z,c), - Ipc = Icpc + 0.5f*(dx*(-Ippc + Inpc) + dx*dx*(2*Ippc - 5*Icpc + 4*Inpc - Iapc) + - dx*dx*dx*(-Ippc + 3*Icpc - 3*Inpc + Iapc)), - Ipcc = (Tfloat)(*this)(px,y,z,c), Iccc = (Tfloat)(*this)(x, y,z,c), - Incc = (Tfloat)(*this)(nx,y,z,c), Iacc = (Tfloat)(*this)(ax,y,z,c), - Icc = Iccc + 0.5f*(dx*(-Ipcc + Incc) + dx*dx*(2*Ipcc - 5*Iccc + 4*Incc - Iacc) + - dx*dx*dx*(-Ipcc + 3*Iccc - 3*Incc + Iacc)), - Ipnc = (Tfloat)(*this)(px,ny,z,c), Icnc = (Tfloat)(*this)(x,ny,z,c), - Innc = (Tfloat)(*this)(nx,ny,z,c), Ianc = (Tfloat)(*this)(ax,ny,z,c), - Inc = Icnc + 0.5f*(dx*(-Ipnc + Innc) + dx*dx*(2*Ipnc - 5*Icnc + 4*Innc - Ianc) + - dx*dx*dx*(-Ipnc + 3*Icnc - 3*Innc + Ianc)), - Ipac = (Tfloat)(*this)(px,ay,z,c), Icac = (Tfloat)(*this)(x,ay,z,c), - Inac = (Tfloat)(*this)(nx,ay,z,c), Iaac = (Tfloat)(*this)(ax,ay,z,c), - Iac = Icac + 0.5f*(dx*(-Ipac + Inac) + dx*dx*(2*Ipac - 5*Icac + 4*Inac - Iaac) + - dx*dx*dx*(-Ipac + 3*Icac - 3*Inac + Iaac)), - Ic = Icc + 0.5f*(dy*(-Ipc + Inc) + dy*dy*(2*Ipc - 5*Icc + 4*Inc - Iac) + - dy*dy*dy*(-Ipc + 3*Icc - 3*Inc + Iac)), - Ippn = (Tfloat)(*this)(px,py,nz,c), Icpn = (Tfloat)(*this)(x,py,nz,c), - Inpn = (Tfloat)(*this)(nx,py,nz,c), Iapn = (Tfloat)(*this)(ax,py,nz,c), - Ipn = Icpn + 0.5f*(dx*(-Ippn + Inpn) + dx*dx*(2*Ippn - 5*Icpn + 4*Inpn - Iapn) + - dx*dx*dx*(-Ippn + 3*Icpn - 3*Inpn + Iapn)), - Ipcn = (Tfloat)(*this)(px,y,nz,c), Iccn = (Tfloat)(*this)(x, y,nz,c), - Incn = (Tfloat)(*this)(nx,y,nz,c), Iacn = (Tfloat)(*this)(ax,y,nz,c), - Icn = Iccn + 0.5f*(dx*(-Ipcn + Incn) + dx*dx*(2*Ipcn - 5*Iccn + 4*Incn - Iacn) + - dx*dx*dx*(-Ipcn + 3*Iccn - 3*Incn + Iacn)), - Ipnn = (Tfloat)(*this)(px,ny,nz,c), Icnn = (Tfloat)(*this)(x,ny,nz,c), - Innn = (Tfloat)(*this)(nx,ny,nz,c), Iann = (Tfloat)(*this)(ax,ny,nz,c), - Inn = Icnn + 0.5f*(dx*(-Ipnn + Innn) + dx*dx*(2*Ipnn - 5*Icnn + 4*Innn - Iann) + - dx*dx*dx*(-Ipnn + 3*Icnn - 3*Innn + Iann)), - Ipan = (Tfloat)(*this)(px,ay,nz,c), Ican = (Tfloat)(*this)(x,ay,nz,c), - Inan = (Tfloat)(*this)(nx,ay,nz,c), Iaan = (Tfloat)(*this)(ax,ay,nz,c), - Ian = Ican + 0.5f*(dx*(-Ipan + Inan) + dx*dx*(2*Ipan - 5*Ican + 4*Inan - Iaan) + - dx*dx*dx*(-Ipan + 3*Ican - 3*Inan + Iaan)), - In = Icn + 0.5f*(dy*(-Ipn + Inn) + dy*dy*(2*Ipn - 5*Icn + 4*Inn - Ian) + - dy*dy*dy*(-Ipn + 3*Icn - 3*Inn + Ian)), - Ippa = (Tfloat)(*this)(px,py,az,c), Icpa = (Tfloat)(*this)(x,py,az,c), - Inpa = (Tfloat)(*this)(nx,py,az,c), Iapa = (Tfloat)(*this)(ax,py,az,c), - Ipa = Icpa + 0.5f*(dx*(-Ippa + Inpa) + dx*dx*(2*Ippa - 5*Icpa + 4*Inpa - Iapa) + - dx*dx*dx*(-Ippa + 3*Icpa - 3*Inpa + Iapa)), - Ipca = (Tfloat)(*this)(px,y,az,c), Icca = (Tfloat)(*this)(x, y,az,c), - Inca = (Tfloat)(*this)(nx,y,az,c), Iaca = (Tfloat)(*this)(ax,y,az,c), - Ica = Icca + 0.5f*(dx*(-Ipca + Inca) + dx*dx*(2*Ipca - 5*Icca + 4*Inca - Iaca) + - dx*dx*dx*(-Ipca + 3*Icca - 3*Inca + Iaca)), - Ipna = (Tfloat)(*this)(px,ny,az,c), Icna = (Tfloat)(*this)(x,ny,az,c), - Inna = (Tfloat)(*this)(nx,ny,az,c), Iana = (Tfloat)(*this)(ax,ny,az,c), - Ina = Icna + 0.5f*(dx*(-Ipna + Inna) + dx*dx*(2*Ipna - 5*Icna + 4*Inna - Iana) + - dx*dx*dx*(-Ipna + 3*Icna - 3*Inna + Iana)), - Ipaa = (Tfloat)(*this)(px,ay,az,c), Icaa = (Tfloat)(*this)(x,ay,az,c), - Inaa = (Tfloat)(*this)(nx,ay,az,c), Iaaa = (Tfloat)(*this)(ax,ay,az,c), - Iaa = Icaa + 0.5f*(dx*(-Ipaa + Inaa) + dx*dx*(2*Ipaa - 5*Icaa + 4*Inaa - Iaaa) + - dx*dx*dx*(-Ipaa + 3*Icaa - 3*Inaa + Iaaa)), - Ia = Ica + 0.5f*(dy*(-Ipa + Ina) + dy*dy*(2*Ipa - 5*Ica + 4*Ina - Iaa) + - dy*dy*dy*(-Ipa + 3*Ica - 3*Ina + Iaa)); - return Ic + 0.5f*(dz*(-Ip + In) + dz*dz*(2*Ip - 5*Ic + 4*In - Ia) + dz*dz*dz*(-Ip + 3*Ic - 3*In + Ia)); - } - - //! Return damped pixel value, using cubic interpolation and Neumann boundary conditions for the XYZ-coordinates. - /** - Similar to cubic_atXYZ(float,float,float,int) const, except that you can specify the authorized minimum and - maximum of the returned value. - **/ - Tfloat cubic_atXYZ(const float fx, const float fy, const float fz, const int c, - const Tfloat min_value, const Tfloat max_value) const { - const Tfloat val = cubic_atXYZ(fx,fy,fz,c); - return valmax_value?max_value:val; - } - - Tfloat _cubic_atXYZ(const float fx, const float fy, const float fz, const int c, - const Tfloat min_value, const Tfloat max_value) const { - const Tfloat val = _cubic_atXYZ(fx,fy,fz,c); - return valmax_value?max_value:val; - } - - //! Set pixel value, using linear interpolation for the X-coordinates. - /** - Set pixel value at specified coordinates (\c fx,\c y,\c z,\c c) in the image instance, in a way that - the value is spread amongst several neighbors if the pixel coordinates are float-valued. - \param value Pixel value to set. - \param fx X-coordinate of the pixel value (float-valued). - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \param is_added Tells if the pixel value is added to (\c true), or simply replace (\c false) the current image - pixel(s). - \return A reference to the current image instance. - \note - - Calling this method with out-of-bounds coordinates does nothing. - **/ - CImg& set_linear_atX(const T& value, const float fx, const int y=0, const int z=0, const int c=0, - const bool is_added=false) { - const int - x = (int)fx - (fx>=0?0:1), nx = x + 1; - const float - dx = fx - x; - if (y>=0 && y=0 && z=0 && c=0 && x=0 && nx& set_linear_atXY(const T& value, const float fx, const float fy=0, const int z=0, const int c=0, - const bool is_added=false) { - const int - x = (int)fx - (fx>=0?0:1), nx = x + 1, - y = (int)fy - (fy>=0?0:1), ny = y + 1; - const float - dx = fx - x, - dy = fy - y; - if (z>=0 && z=0 && c=0 && y=0 && x=0 && nx=0 && ny=0 && x=0 && nx& set_linear_atXYZ(const T& value, const float fx, const float fy=0, const float fz=0, const int c=0, - const bool is_added=false) { - const int - x = (int)fx - (fx>=0?0:1), nx = x + 1, - y = (int)fy - (fy>=0?0:1), ny = y + 1, - z = (int)fz - (fz>=0?0:1), nz = z + 1; - const float - dx = fx - x, - dy = fy - y, - dz = fz - z; - if (c>=0 && c=0 && z=0 && y=0 && x=0 && nx=0 && ny=0 && x=0 && nx=0 && nz=0 && y=0 && x=0 && nx=0 && ny=0 && x=0 && nx image whose buffer data() is a \c char* string describing the list of all pixel values - of the image instance (written in base 10), separated by specified \c separator character. - \param separator A \c char character which specifies the separator between values in the returned C-string. - \param max_size Maximum size of the returned image. - \param format For float-values, tell the printf format used to generate the ascii representation of the numbers. - (or \c 0 for default representation). - \note - - The returned image is never empty. - - For an empty image instance, the returned string is "". - - If \c max_size is equal to \c 0, there are no limits on the size of the returned string. - - Otherwise, if the maximum number of string characters is exceeded, the value string is cut off - and terminated by character \c '\0'. In that case, the returned image size is max_size + 1. - **/ - CImg value_string(const char separator=',', const unsigned int max_size=0, - const char *const format=0) const { - if (is_empty()) return CImg::string(""); - CImgList items; - CImg s_item(256); *s_item = 0; - const T *ptrs = _data; - unsigned int string_size = 0; - const char *const _format = format?format:cimg::type::format(); - - for (ulongT off = 0, siz = size(); off::format(*(ptrs++))); - CImg item(s_item._data,printed_size); - item[printed_size - 1] = separator; - item.move_to(items); - if (max_size) string_size+=printed_size; - } - CImg res; - (items>'x').move_to(res); - if (max_size && res._width>max_size) res.crop(0,max_size); - res.back() = 0; - return res; - } - - //@} - //------------------------------------- - // - //! \name Instance Checking - //@{ - //------------------------------------- - - //! Test shared state of the pixel buffer. - /** - Return \c true if image instance has a shared memory buffer, and \c false otherwise. - \note - - A shared image do not own his pixel buffer data() and will not deallocate it on destruction. - - Most of the time, a \c CImg image instance will \e not be shared. - - A shared image can only be obtained by a limited set of constructors and methods (see list below). - **/ - bool is_shared() const { - return _is_shared; - } - - //! Test if image instance is empty. - /** - Return \c true, if image instance is empty, i.e. does \e not contain any pixel values, has dimensions - \c 0 x \c 0 x \c 0 x \c 0 and a pixel buffer pointer set to \c 0 (null pointer), and \c false otherwise. - **/ - bool is_empty() const { - return !(_data && _width && _height && _depth && _spectrum); - } - - //! Test if image instance contains a 'inf' value. - /** - Return \c true, if image instance contains a 'inf' value, and \c false otherwise. - **/ - bool is_inf() const { - if (cimg::type::is_float()) cimg_for(*this,p,T) if (cimg::type::is_inf((float)*p)) return true; - return false; - } - - //! Test if image instance contains a NaN value. - /** - Return \c true, if image instance contains a NaN value, and \c false otherwise. - **/ - bool is_nan() const { - if (cimg::type::is_float()) cimg_for(*this,p,T) if (cimg::type::is_nan((float)*p)) return true; - return false; - } - - //! Test if image width is equal to specified value. - bool is_sameX(const unsigned int size_x) const { - return _width==size_x; - } - - //! Test if image width is equal to specified value. - template - bool is_sameX(const CImg& img) const { - return is_sameX(img._width); - } - - //! Test if image width is equal to specified value. - bool is_sameX(const CImgDisplay& disp) const { - return is_sameX(disp._width); - } - - //! Test if image height is equal to specified value. - bool is_sameY(const unsigned int size_y) const { - return _height==size_y; - } - - //! Test if image height is equal to specified value. - template - bool is_sameY(const CImg& img) const { - return is_sameY(img._height); - } - - //! Test if image height is equal to specified value. - bool is_sameY(const CImgDisplay& disp) const { - return is_sameY(disp._height); - } - - //! Test if image depth is equal to specified value. - bool is_sameZ(const unsigned int size_z) const { - return _depth==size_z; - } - - //! Test if image depth is equal to specified value. - template - bool is_sameZ(const CImg& img) const { - return is_sameZ(img._depth); - } - - //! Test if image spectrum is equal to specified value. - bool is_sameC(const unsigned int size_c) const { - return _spectrum==size_c; - } - - //! Test if image spectrum is equal to specified value. - template - bool is_sameC(const CImg& img) const { - return is_sameC(img._spectrum); - } - - //! Test if image width and height are equal to specified values. - /** - Test if is_sameX(unsigned int) const and is_sameY(unsigned int) const are both verified. - **/ - bool is_sameXY(const unsigned int size_x, const unsigned int size_y) const { - return _width==size_x && _height==size_y; - } - - //! Test if image width and height are the same as that of another image. - /** - Test if is_sameX(const CImg&) const and is_sameY(const CImg&) const are both verified. - **/ - template - bool is_sameXY(const CImg& img) const { - return is_sameXY(img._width,img._height); - } - - //! Test if image width and height are the same as that of an existing display window. - /** - Test if is_sameX(const CImgDisplay&) const and is_sameY(const CImgDisplay&) const are both verified. - **/ - bool is_sameXY(const CImgDisplay& disp) const { - return is_sameXY(disp._width,disp._height); - } - - //! Test if image width and depth are equal to specified values. - /** - Test if is_sameX(unsigned int) const and is_sameZ(unsigned int) const are both verified. - **/ - bool is_sameXZ(const unsigned int size_x, const unsigned int size_z) const { - return _width==size_x && _depth==size_z; - } - - //! Test if image width and depth are the same as that of another image. - /** - Test if is_sameX(const CImg&) const and is_sameZ(const CImg&) const are both verified. - **/ - template - bool is_sameXZ(const CImg& img) const { - return is_sameXZ(img._width,img._depth); - } - - //! Test if image width and spectrum are equal to specified values. - /** - Test if is_sameX(unsigned int) const and is_sameC(unsigned int) const are both verified. - **/ - bool is_sameXC(const unsigned int size_x, const unsigned int size_c) const { - return _width==size_x && _spectrum==size_c; - } - - //! Test if image width and spectrum are the same as that of another image. - /** - Test if is_sameX(const CImg&) const and is_sameC(const CImg&) const are both verified. - **/ - template - bool is_sameXC(const CImg& img) const { - return is_sameXC(img._width,img._spectrum); - } - - //! Test if image height and depth are equal to specified values. - /** - Test if is_sameY(unsigned int) const and is_sameZ(unsigned int) const are both verified. - **/ - bool is_sameYZ(const unsigned int size_y, const unsigned int size_z) const { - return _height==size_y && _depth==size_z; - } - - //! Test if image height and depth are the same as that of another image. - /** - Test if is_sameY(const CImg&) const and is_sameZ(const CImg&) const are both verified. - **/ - template - bool is_sameYZ(const CImg& img) const { - return is_sameYZ(img._height,img._depth); - } - - //! Test if image height and spectrum are equal to specified values. - /** - Test if is_sameY(unsigned int) const and is_sameC(unsigned int) const are both verified. - **/ - bool is_sameYC(const unsigned int size_y, const unsigned int size_c) const { - return _height==size_y && _spectrum==size_c; - } - - //! Test if image height and spectrum are the same as that of another image. - /** - Test if is_sameY(const CImg&) const and is_sameC(const CImg&) const are both verified. - **/ - template - bool is_sameYC(const CImg& img) const { - return is_sameYC(img._height,img._spectrum); - } - - //! Test if image depth and spectrum are equal to specified values. - /** - Test if is_sameZ(unsigned int) const and is_sameC(unsigned int) const are both verified. - **/ - bool is_sameZC(const unsigned int size_z, const unsigned int size_c) const { - return _depth==size_z && _spectrum==size_c; - } - - //! Test if image depth and spectrum are the same as that of another image. - /** - Test if is_sameZ(const CImg&) const and is_sameC(const CImg&) const are both verified. - **/ - template - bool is_sameZC(const CImg& img) const { - return is_sameZC(img._depth,img._spectrum); - } - - //! Test if image width, height and depth are equal to specified values. - /** - Test if is_sameXY(unsigned int,unsigned int) const and is_sameZ(unsigned int) const are both verified. - **/ - bool is_sameXYZ(const unsigned int size_x, const unsigned int size_y, const unsigned int size_z) const { - return is_sameXY(size_x,size_y) && _depth==size_z; - } - - //! Test if image width, height and depth are the same as that of another image. - /** - Test if is_sameXY(const CImg&) const and is_sameZ(const CImg&) const are both verified. - **/ - template - bool is_sameXYZ(const CImg& img) const { - return is_sameXYZ(img._width,img._height,img._depth); - } - - //! Test if image width, height and spectrum are equal to specified values. - /** - Test if is_sameXY(unsigned int,unsigned int) const and is_sameC(unsigned int) const are both verified. - **/ - bool is_sameXYC(const unsigned int size_x, const unsigned int size_y, const unsigned int size_c) const { - return is_sameXY(size_x,size_y) && _spectrum==size_c; - } - - //! Test if image width, height and spectrum are the same as that of another image. - /** - Test if is_sameXY(const CImg&) const and is_sameC(const CImg&) const are both verified. - **/ - template - bool is_sameXYC(const CImg& img) const { - return is_sameXYC(img._width,img._height,img._spectrum); - } - - //! Test if image width, depth and spectrum are equal to specified values. - /** - Test if is_sameXZ(unsigned int,unsigned int) const and is_sameC(unsigned int) const are both verified. - **/ - bool is_sameXZC(const unsigned int size_x, const unsigned int size_z, const unsigned int size_c) const { - return is_sameXZ(size_x,size_z) && _spectrum==size_c; - } - - //! Test if image width, depth and spectrum are the same as that of another image. - /** - Test if is_sameXZ(const CImg&) const and is_sameC(const CImg&) const are both verified. - **/ - template - bool is_sameXZC(const CImg& img) const { - return is_sameXZC(img._width,img._depth,img._spectrum); - } - - //! Test if image height, depth and spectrum are equal to specified values. - /** - Test if is_sameYZ(unsigned int,unsigned int) const and is_sameC(unsigned int) const are both verified. - **/ - bool is_sameYZC(const unsigned int size_y, const unsigned int size_z, const unsigned int size_c) const { - return is_sameYZ(size_y,size_z) && _spectrum==size_c; - } - - //! Test if image height, depth and spectrum are the same as that of another image. - /** - Test if is_sameYZ(const CImg&) const and is_sameC(const CImg&) const are both verified. - **/ - template - bool is_sameYZC(const CImg& img) const { - return is_sameYZC(img._height,img._depth,img._spectrum); - } - - //! Test if image width, height, depth and spectrum are equal to specified values. - /** - Test if is_sameXYZ(unsigned int,unsigned int,unsigned int) const and is_sameC(unsigned int) const are both - verified. - **/ - bool is_sameXYZC(const unsigned int size_x, const unsigned int size_y, - const unsigned int size_z, const unsigned int size_c) const { - return is_sameXYZ(size_x,size_y,size_z) && _spectrum==size_c; - } - - //! Test if image width, height, depth and spectrum are the same as that of another image. - /** - Test if is_sameXYZ(const CImg&) const and is_sameC(const CImg&) const are both verified. - **/ - template - bool is_sameXYZC(const CImg& img) const { - return is_sameXYZC(img._width,img._height,img._depth,img._spectrum); - } - - //! Test if specified coordinates are inside image bounds. - /** - Return \c true if pixel located at (\c x,\c y,\c z,\c c) is inside bounds of the image instance, - and \c false otherwise. - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \note - - Return \c true only if all these conditions are verified: - - The image instance is \e not empty. - - 0<=x<=\ref width() - 1. - - 0<=y<=\ref height() - 1. - - 0<=z<=\ref depth() - 1. - - 0<=c<=\ref spectrum() - 1. - **/ - bool containsXYZC(const int x, const int y=0, const int z=0, const int c=0) const { - return !is_empty() && x>=0 && x=0 && y=0 && z=0 && c img(100,100,1,3); // Construct a 100x100 RGB color image. - const unsigned long offset = 1249; // Offset to the pixel (49,12,0,0). - unsigned int x,y,z,c; - if (img.contains(img[offset],x,y,z,c)) { // Convert offset to (x,y,z,c) coordinates. - std::printf("Offset %u refers to pixel located at (%u,%u,%u,%u).\n", - offset,x,y,z,c); - } - \endcode - **/ - template - bool contains(const T& pixel, t& x, t& y, t& z, t& c) const { - const ulongT wh = (ulongT)_width*_height, whd = wh*_depth, siz = whd*_spectrum; - const T *const ppixel = &pixel; - if (is_empty() || ppixel<_data || ppixel>=_data + siz) return false; - ulongT off = (ulongT)(ppixel - _data); - const ulongT nc = off/whd; - off%=whd; - const ulongT nz = off/wh; - off%=wh; - const ulongT ny = off/_width, nx = off%_width; - x = (t)nx; y = (t)ny; z = (t)nz; c = (t)nc; - return true; - } - - //! Test if pixel value is inside image bounds and get its X,Y and Z-coordinates. - /** - Similar to contains(const T&,t&,t&,t&,t&) const, except that only the X,Y and Z-coordinates are set. - **/ - template - bool contains(const T& pixel, t& x, t& y, t& z) const { - const ulongT wh = (ulongT)_width*_height, whd = wh*_depth, siz = whd*_spectrum; - const T *const ppixel = &pixel; - if (is_empty() || ppixel<_data || ppixel>=_data + siz) return false; - ulongT off = ((ulongT)(ppixel - _data))%whd; - const ulongT nz = off/wh; - off%=wh; - const ulongT ny = off/_width, nx = off%_width; - x = (t)nx; y = (t)ny; z = (t)nz; - return true; - } - - //! Test if pixel value is inside image bounds and get its X and Y-coordinates. - /** - Similar to contains(const T&,t&,t&,t&,t&) const, except that only the X and Y-coordinates are set. - **/ - template - bool contains(const T& pixel, t& x, t& y) const { - const ulongT wh = (ulongT)_width*_height, siz = wh*_depth*_spectrum; - const T *const ppixel = &pixel; - if (is_empty() || ppixel<_data || ppixel>=_data + siz) return false; - ulongT off = ((unsigned int)(ppixel - _data))%wh; - const ulongT ny = off/_width, nx = off%_width; - x = (t)nx; y = (t)ny; - return true; - } - - //! Test if pixel value is inside image bounds and get its X-coordinate. - /** - Similar to contains(const T&,t&,t&,t&,t&) const, except that only the X-coordinate is set. - **/ - template - bool contains(const T& pixel, t& x) const { - const T *const ppixel = &pixel; - if (is_empty() || ppixel<_data || ppixel>=_data + size()) return false; - x = (t)(((ulongT)(ppixel - _data))%_width); - return true; - } - - //! Test if pixel value is inside image bounds. - /** - Similar to contains(const T&,t&,t&,t&,t&) const, except that no pixel coordinates are set. - **/ - bool contains(const T& pixel) const { - const T *const ppixel = &pixel; - return !is_empty() && ppixel>=_data && ppixel<_data + size(); - } - - //! Test if pixel buffers of instance and input images overlap. - /** - Return \c true, if pixel buffers attached to image instance and input image \c img overlap, - and \c false otherwise. - \param img Input image to compare with. - \note - - Buffer overlapping may happen when manipulating \e shared images. - - If two image buffers overlap, operating on one of the image will probably modify the other one. - - Most of the time, \c CImg instances are \e non-shared and do not overlap between each others. - \par Example - \code - const CImg - img1("reference.jpg"), // Load RGB-color image. - img2 = img1.get_shared_channel(1); // Get shared version of the green channel. - if (img1.is_overlapped(img2)) { // Test succeeds, 'img1' and 'img2' overlaps. - std::printf("Buffers overlap!\n"); - } - \endcode - **/ - template - bool is_overlapped(const CImg& img) const { - const ulongT csiz = size(), isiz = img.size(); - return !((void*)(_data + csiz)<=(void*)img._data || (void*)_data>=(void*)(img._data + isiz)); - } - - //! Test if the set {\c *this,\c primitives,\c colors,\c opacities} defines a valid 3d object. - /** - Return \c true is the 3d object represented by the set {\c *this,\c primitives,\c colors,\c opacities} defines a - valid 3d object, and \c false otherwise. The vertex coordinates are defined by the instance image. - \param primitives List of primitives of the 3d object. - \param colors List of colors of the 3d object. - \param opacities List (or image) of opacities of the 3d object. - \param full_check Tells if full checking of the 3d object must be performed. - \param[out] error_message C-string to contain the error message, if the test does not succeed. - \note - - Set \c full_checking to \c false to speed-up the 3d object checking. In this case, only the size of - each 3d object component is checked. - - Size of the string \c error_message should be at least 128-bytes long, to be able to contain the error message. - **/ - template - bool is_object3d(const CImgList& primitives, - const CImgList& colors, - const to& opacities, - const bool full_check=true, - char *const error_message=0) const { - if (error_message) *error_message = 0; - - // Check consistency for the particular case of an empty 3d object. - if (is_empty()) { - if (primitives || colors || opacities) { - if (error_message) cimg_sprintf(error_message, - "3d object (%u,%u) defines no vertices but %u primitives, " - "%u colors and %lu opacities", - _width,primitives._width,primitives._width, - colors._width,(unsigned long)opacities.size()); - return false; - } - return true; - } - - // Check consistency of vertices. - if (_height!=3 || _depth>1 || _spectrum>1) { // Check vertices dimensions. - if (error_message) cimg_sprintf(error_message, - "3d object (%u,%u) has invalid vertex dimensions (%u,%u,%u,%u)", - _width,primitives._width,_width,_height,_depth,_spectrum); - return false; - } - if (colors._width>primitives._width + 1) { - if (error_message) cimg_sprintf(error_message, - "3d object (%u,%u) defines %u colors", - _width,primitives._width,colors._width); - return false; - } - if (opacities.size()>primitives._width) { - if (error_message) cimg_sprintf(error_message, - "3d object (%u,%u) defines %lu opacities", - _width,primitives._width,(unsigned long)opacities.size()); - return false; - } - if (!full_check) return true; - - // Check consistency of primitives. - cimglist_for(primitives,l) { - const CImg& primitive = primitives[l]; - const unsigned int psiz = (unsigned int)primitive.size(); - switch (psiz) { - case 1 : { // Point. - const unsigned int i0 = (unsigned int)primitive(0); - if (i0>=_width) { - if (error_message) cimg_sprintf(error_message, - "3d object (%u,%u) refers to invalid vertex indice %u in " - "point primitive [%u]", - _width,primitives._width,i0,l); - return false; - } - } break; - case 5 : { // Sphere. - const unsigned int - i0 = (unsigned int)primitive(0), - i1 = (unsigned int)primitive(1); - if (i0>=_width || i1>=_width) { - if (error_message) cimg_sprintf(error_message, - "3d object (%u,%u) refers to invalid vertex indices (%u,%u) in " - "sphere primitive [%u]", - _width,primitives._width,i0,i1,l); - return false; - } - } break; - case 2 : // Segment. - case 6 : { - const unsigned int - i0 = (unsigned int)primitive(0), - i1 = (unsigned int)primitive(1); - if (i0>=_width || i1>=_width) { - if (error_message) cimg_sprintf(error_message, - "3d object (%u,%u) refers to invalid vertex indices (%u,%u) in " - "segment primitive [%u]", - _width,primitives._width,i0,i1,l); - return false; - } - } break; - case 3 : // Triangle. - case 9 : { - const unsigned int - i0 = (unsigned int)primitive(0), - i1 = (unsigned int)primitive(1), - i2 = (unsigned int)primitive(2); - if (i0>=_width || i1>=_width || i2>=_width) { - if (error_message) cimg_sprintf(error_message, - "3d object (%u,%u) refers to invalid vertex indices (%u,%u,%u) in " - "triangle primitive [%u]", - _width,primitives._width,i0,i1,i2,l); - return false; - } - } break; - case 4 : // Quadrangle. - case 12 : { - const unsigned int - i0 = (unsigned int)primitive(0), - i1 = (unsigned int)primitive(1), - i2 = (unsigned int)primitive(2), - i3 = (unsigned int)primitive(3); - if (i0>=_width || i1>=_width || i2>=_width || i3>=_width) { - if (error_message) cimg_sprintf(error_message, - "3d object (%u,%u) refers to invalid vertex indices (%u,%u,%u,%u) in " - "quadrangle primitive [%u]", - _width,primitives._width,i0,i1,i2,i3,l); - return false; - } - } break; - default : - if (error_message) cimg_sprintf(error_message, - "3d object (%u,%u) defines an invalid primitive [%u] of size %u", - _width,primitives._width,l,(unsigned int)psiz); - return false; - } - } - - // Check consistency of colors. - cimglist_for(colors,c) { - const CImg& color = colors[c]; - if (!color) { - if (error_message) cimg_sprintf(error_message, - "3d object (%u,%u) defines no color for primitive [%u]", - _width,primitives._width,c); - return false; - } - } - - // Check consistency of light texture. - if (colors._width>primitives._width) { - const CImg &light = colors.back(); - if (!light || light._depth>1) { - if (error_message) cimg_sprintf(error_message, - "3d object (%u,%u) defines an invalid light texture (%u,%u,%u,%u)", - _width,primitives._width,light._width, - light._height,light._depth,light._spectrum); - return false; - } - } - - return true; - } - - //! Test if image instance represents a valid serialization of a 3d object. - /** - Return \c true if the image instance represents a valid serialization of a 3d object, and \c false otherwise. - \param full_check Tells if full checking of the instance must be performed. - \param[out] error_message C-string to contain the error message, if the test does not succeed. - \note - - Set \c full_check to \c false to speed-up the 3d object checking. In this case, only the size of - each 3d object component is checked. - - Size of the string \c error_message should be at least 128-bytes long, to be able to contain the error message. - **/ - bool is_CImg3d(const bool full_check=true, char *const error_message=0) const { - if (error_message) *error_message = 0; - - // Check instance dimension and header. - if (_width!=1 || _height<8 || _depth!=1 || _spectrum!=1) { - if (error_message) cimg_sprintf(error_message, - "CImg3d has invalid dimensions (%u,%u,%u,%u)", - _width,_height,_depth,_spectrum); - return false; - } - const T *ptrs = _data, *const ptre = end(); - if (!_is_CImg3d(*(ptrs++),'C') || !_is_CImg3d(*(ptrs++),'I') || !_is_CImg3d(*(ptrs++),'m') || - !_is_CImg3d(*(ptrs++),'g') || !_is_CImg3d(*(ptrs++),'3') || !_is_CImg3d(*(ptrs++),'d')) { - if (error_message) cimg_sprintf(error_message, - "CImg3d header not found"); - return false; - } - const unsigned int - nb_points = cimg::float2uint((float)*(ptrs++)), - nb_primitives = cimg::float2uint((float)*(ptrs++)); - - // Check consistency of number of vertices / primitives. - if (!full_check) { - const ulongT minimal_size = 8UL + 3*nb_points + 6*nb_primitives; - if (_data + minimal_size>ptre) { - if (error_message) cimg_sprintf(error_message, - "CImg3d (%u,%u) has only %lu values, while at least %lu values were expected", - nb_points,nb_primitives,size(),minimal_size); - return false; - } - } - - // Check consistency of vertex data. - if (!nb_points) { - if (nb_primitives) { - if (error_message) cimg_sprintf(error_message, - "CImg3d (%u,%u) defines no vertices but %u primitives", - nb_points,nb_primitives,nb_primitives); - return false; - } - if (ptrs!=ptre) { - if (error_message) cimg_sprintf(error_message, - "CImg3d (%u,%u) is an empty object but contains %u value%s " - "more than expected", - nb_points,nb_primitives,(unsigned int)(ptre - ptrs),(ptre - ptrs)>1?"s":""); - return false; - } - return true; - } - if (ptrs + 3*nb_points>ptre) { - if (error_message) cimg_sprintf(error_message, - "CImg3d (%u,%u) defines only %u vertices data", - nb_points,nb_primitives,(unsigned int)(ptre - ptrs)/3); - return false; - } - ptrs+=3*nb_points; - - // Check consistency of primitive data. - if (ptrs==ptre) { - if (error_message) cimg_sprintf(error_message, - "CImg3d (%u,%u) defines %u vertices but no primitive", - nb_points,nb_primitives,nb_points); - return false; - } - - if (!full_check) return true; - - for (unsigned int p = 0; p=nb_points) { - if (error_message) cimg_sprintf(error_message, - "CImg3d (%u,%u) refers to invalid vertex indice %u in point primitive [%u]", - nb_points,nb_primitives,i0,p); - return false; - } - } break; - case 5 : { // Sphere. - const unsigned int - i0 = cimg::float2uint((float)*(ptrs++)), - i1 = cimg::float2uint((float)*(ptrs++)); - ptrs+=3; - if (i0>=nb_points || i1>=nb_points) { - if (error_message) cimg_sprintf(error_message, - "CImg3d (%u,%u) refers to invalid vertex indices (%u,%u) in " - "sphere primitive [%u]", - nb_points,nb_primitives,i0,i1,p); - return false; - } - } break; - case 2 : case 6 : { // Segment. - const unsigned int - i0 = cimg::float2uint((float)*(ptrs++)), - i1 = cimg::float2uint((float)*(ptrs++)); - if (nb_inds==6) ptrs+=4; - if (i0>=nb_points || i1>=nb_points) { - if (error_message) cimg_sprintf(error_message, - "CImg3d (%u,%u) refers to invalid vertex indices (%u,%u) in " - "segment primitive [%u]", - nb_points,nb_primitives,i0,i1,p); - return false; - } - } break; - case 3 : case 9 : { // Triangle. - const unsigned int - i0 = cimg::float2uint((float)*(ptrs++)), - i1 = cimg::float2uint((float)*(ptrs++)), - i2 = cimg::float2uint((float)*(ptrs++)); - if (nb_inds==9) ptrs+=6; - if (i0>=nb_points || i1>=nb_points || i2>=nb_points) { - if (error_message) cimg_sprintf(error_message, - "CImg3d (%u,%u) refers to invalid vertex indices (%u,%u,%u) in " - "triangle primitive [%u]", - nb_points,nb_primitives,i0,i1,i2,p); - return false; - } - } break; - case 4 : case 12 : { // Quadrangle. - const unsigned int - i0 = cimg::float2uint((float)*(ptrs++)), - i1 = cimg::float2uint((float)*(ptrs++)), - i2 = cimg::float2uint((float)*(ptrs++)), - i3 = cimg::float2uint((float)*(ptrs++)); - if (nb_inds==12) ptrs+=8; - if (i0>=nb_points || i1>=nb_points || i2>=nb_points || i3>=nb_points) { - if (error_message) cimg_sprintf(error_message, - "CImg3d (%u,%u) refers to invalid vertex indices (%u,%u,%u,%u) in " - "quadrangle primitive [%u]", - nb_points,nb_primitives,i0,i1,i2,i3,p); - return false; - } - } break; - default : - if (error_message) cimg_sprintf(error_message, - "CImg3d (%u,%u) defines an invalid primitive [%u] of size %u", - nb_points,nb_primitives,p,nb_inds); - return false; - } - if (ptrs>ptre) { - if (error_message) cimg_sprintf(error_message, - "CImg3d (%u,%u) has incomplete primitive data for primitive [%u], " - "%u values missing", - nb_points,nb_primitives,p,(unsigned int)(ptrs - ptre)); - return false; - } - } - - // Check consistency of color data. - if (ptrs==ptre) { - if (error_message) cimg_sprintf(error_message, - "CImg3d (%u,%u) defines no color/texture data", - nb_points,nb_primitives); - return false; - } - for (unsigned int c = 0; c=c) { - if (error_message) cimg_sprintf(error_message, - "CImg3d (%u,%u) refers to invalid shared sprite/texture indice %u " - "for primitive [%u]", - nb_points,nb_primitives,w,c); - return false; - } - } else ptrs+=w*h*s; - } - if (ptrs>ptre) { - if (error_message) cimg_sprintf(error_message, - "CImg3d (%u,%u) has incomplete color/texture data for primitive [%u], " - "%u values missing", - nb_points,nb_primitives,c,(unsigned int)(ptrs - ptre)); - return false; - } - } - - // Check consistency of opacity data. - if (ptrs==ptre) { - if (error_message) cimg_sprintf(error_message, - "CImg3d (%u,%u) defines no opacity data", - nb_points,nb_primitives); - return false; - } - for (unsigned int o = 0; o=o) { - if (error_message) cimg_sprintf(error_message, - "CImg3d (%u,%u) refers to invalid shared opacity indice %u " - "for primitive [%u]", - nb_points,nb_primitives,w,o); - return false; - } - } else ptrs+=w*h*s; - } - if (ptrs>ptre) { - if (error_message) cimg_sprintf(error_message, - "CImg3d (%u,%u) has incomplete opacity data for primitive [%u]", - nb_points,nb_primitives,o); - return false; - } - } - - // Check end of data. - if (ptrs1?"s":""); - return false; - } - return true; - } - - static bool _is_CImg3d(const T val, const char c) { - return val>=(T)c && val<(T)(c + 1); - } - - //@} - //------------------------------------- - // - //! \name Mathematical Functions - //@{ - //------------------------------------- - - // Define the math formula parser/compiler and expression evaluator. - struct _cimg_math_parser { - CImg mem; - CImg memtype; - CImgList _code, &code; - CImg opcode; - const CImg *p_code_begin, *p_code_end, *p_code; - - CImg expr, pexpr; - const CImg& imgin; - const CImgList& listin; - CImg &imgout; - CImgList& listout; - - CImg _img_stats, &img_stats; - CImgList _list_stats, &list_stats, _list_median, &list_median; - CImg mem_img_stats; - - CImg level, variable_pos, reserved_label; - CImgList variable_def, function_def, function_body; - CImgList function_body_is_string; - char *user_function; - - unsigned int mempos, mem_img_median, debug_indent, init_size, result_dim; - bool is_parallelizable, need_input_copy; - double *result; - const char *const calling_function, *s_op, *ss_op; - typedef double (*mp_func)(_cimg_math_parser&); - -#define _cimg_mp_is_constant(arg) (memtype[arg]==1) // Is constant? -#define _cimg_mp_is_scalar(arg) (memtype[arg]<2) // Is scalar? -#define _cimg_mp_is_temp(arg) (!memtype[arg]) // Is temporary scalar? -#define _cimg_mp_is_variable(arg) (memtype[arg]==-1) // Is scalar variable? -#define _cimg_mp_is_vector(arg) (memtype[arg]>1) // Is vector? -#define _cimg_mp_vector_size(arg) (_cimg_mp_is_scalar(arg)?0U:(unsigned int)memtype[arg] - 1) // Vector size -#define _cimg_mp_calling_function calling_function_s()._data -#define _cimg_mp_op(s) s_op = s; ss_op = ss -#define _cimg_mp_check_type(arg,n_arg,mode,N) check_type(arg,n_arg,mode,N,ss,se,saved_char) -#define _cimg_mp_check_constant(arg,n_arg,mode) check_constant(arg,n_arg,mode,ss,se,saved_char) -#define _cimg_mp_check_matrix_square(arg,n_arg) check_matrix_square(arg,n_arg,ss,se,saved_char) -#define _cimg_mp_check_vector0(dim) check_vector0(dim,ss,se,saved_char) -#define _cimg_mp_check_list(is_out) check_list(is_out,ss,se,saved_char) -#define _cimg_mp_defunc(mp) (*(mp_func)(*(mp).opcode))(mp) -#define _cimg_mp_return(x) { *se = saved_char; s_op = previous_s_op; ss_op = previous_ss_op; return x; } -#define _cimg_mp_constant(val) _cimg_mp_return(constant((double)(val))) -#define _cimg_mp_scalar0(op) _cimg_mp_return(scalar0(op)) -#define _cimg_mp_scalar1(op,i1) _cimg_mp_return(scalar1(op,i1)) -#define _cimg_mp_scalar2(op,i1,i2) _cimg_mp_return(scalar2(op,i1,i2)) -#define _cimg_mp_scalar3(op,i1,i2,i3) _cimg_mp_return(scalar3(op,i1,i2,i3)) -#define _cimg_mp_scalar4(op,i1,i2,i3,i4) _cimg_mp_return(scalar4(op,i1,i2,i3,i4)) -#define _cimg_mp_scalar5(op,i1,i2,i3,i4,i5) _cimg_mp_return(scalar5(op,i1,i2,i3,i4,i5)) -#define _cimg_mp_scalar6(op,i1,i2,i3,i4,i5,i6) _cimg_mp_return(scalar6(op,i1,i2,i3,i4,i5,i6)) -#define _cimg_mp_scalar7(op,i1,i2,i3,i4,i5,i6,i7) _cimg_mp_return(scalar7(op,i1,i2,i3,i4,i5,i6,i7)) -#define _cimg_mp_vector1_v(op,i1) _cimg_mp_return(vector1_v(op,i1)) -#define _cimg_mp_vector2_sv(op,i1,i2) _cimg_mp_return(vector2_sv(op,i1,i2)) -#define _cimg_mp_vector2_vs(op,i1,i2) _cimg_mp_return(vector2_vs(op,i1,i2)) -#define _cimg_mp_vector2_vv(op,i1,i2) _cimg_mp_return(vector2_vv(op,i1,i2)) -#define _cimg_mp_vector3_vss(op,i1,i2,i3) _cimg_mp_return(vector3_vss(op,i1,i2,i3)) - - // Constructors. - _cimg_math_parser(const char *const expression, const char *const funcname=0, - const CImg& img_input=CImg::const_empty(), CImg *const img_output=0, - const CImgList *const list_input=0, CImgList *const list_output=0): - code(_code),imgin(img_input),listin(list_input?*list_input:CImgList::const_empty()), - imgout(img_output?*img_output:CImg::empty()),listout(list_output?*list_output:CImgList::empty()), - img_stats(_img_stats),list_stats(_list_stats),list_median(_list_median),user_function(0), - mem_img_median(~0U),debug_indent(0),init_size(0),result_dim(0),is_parallelizable(true), - need_input_copy(false),calling_function(funcname?funcname:"cimg_math_parser") { - if (!expression || !*expression) - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: Empty expression.", - pixel_type(),_cimg_mp_calling_function); - const char *_expression = expression; - while (*_expression && (*_expression<=' ' || *_expression==';')) ++_expression; - CImg::string(_expression).move_to(expr); - char *ps = &expr.back() - 1; - while (ps>expr._data && (*ps==' ' || *ps==';')) --ps; - *(++ps) = 0; expr._width = (unsigned int)(ps - expr._data + 1); - - // Ease the retrieval of previous non-space characters afterwards. - pexpr.assign(expr._width); - char c, *pe = pexpr._data; - for (ps = expr._data, c = ' '; *ps; ++ps) { - if (*ps!=' ') c = *ps; - *(pe++) = c; - } - *pe = 0; - level = get_level(expr); - - // Init constant values. - mem.assign(96); - memtype.assign(96); - double *p_mem = mem._data; - for (unsigned int i = 0; i<=10; ++i) *(p_mem++) = (double)i; // mem[0-10] - for (unsigned int i = 1; i<=5; ++i) *(p_mem++) = -(double)i; // mem[11-15] - *(p_mem++) = 0.5; // mem[16] - *(p_mem++) = 0; // mem[17] = thread_id - *(p_mem++) = (double)imgin._width; // mem[18] - *(p_mem++) = (double)imgin._height; // mem[19] - *(p_mem++) = (double)imgin._depth; // mem[20] - *(p_mem++) = (double)imgin._spectrum; // mem[21] - *(p_mem++) = (double)imgin._is_shared; // mem[22] - *(p_mem++) = (double)imgin._width*imgin._height; // mem[23] - *(p_mem++) = (double)imgin._width*imgin._height*imgin._depth; // mem[24] - *(p_mem++) = (double)imgin._width*imgin._height*imgin._depth*imgin._spectrum; // mem[25] - *(p_mem++) = (double)listin._width; // mem[26] - *(p_mem++) = std::exp(1.0); // mem[27] - *(p_mem++) = cimg::PI; // mem[28] - *(p_mem++) = cimg::type::nan(); // mem[29] - - // Then, [30] = x, [31] = y, [32] = z and [33] = c. -#define _cimg_mp_nan 29 -#define _cimg_mp_x 30 -#define _cimg_mp_y 31 -#define _cimg_mp_z 32 -#define _cimg_mp_c 33 - - // Set value property : - // { -1 = variable | 0 = regular value | 1 = compile time constant | N>1 = constant ptr to vector[N-1] }. - std::memset(memtype._data,0,sizeof(int)*memtype._width); - int *p_memtype = memtype._data; for (unsigned int i = 0; i<_cimg_mp_x; ++i) *(p_memtype++) = 1; - memtype[17] = 0; - - mempos = _cimg_mp_c + 1; - variable_pos.assign(8); - reserved_label.assign(128,1,1,1,~0U); - reserved_label['t'] = 17; - reserved_label['w'] = 18; - reserved_label['h'] = 19; - reserved_label['d'] = 20; - reserved_label['s'] = 21; - reserved_label['r'] = 22; - reserved_label[0] = 23; // wh - reserved_label[1] = 24; // whd - reserved_label[2] = 25; // whds - reserved_label['l'] = 26; - reserved_label['e'] = 27; - reserved_label[3] = 28; // pi - reserved_label[29] = 0; // interpolation - reserved_label[30] = 0; // boundary - reserved_label['x'] = _cimg_mp_x; - reserved_label['y'] = _cimg_mp_y; - reserved_label['z'] = _cimg_mp_z; - reserved_label['c'] = _cimg_mp_c; - // reserved_label[4-28] store also two-char variables: - // [4] = im, [5] = iM, [6] = ia, [7] = iv, [8] = is, [9] = ip, [10] = ic, - // [11] = xm, [12] = ym, [13] = zm, [14] = cm, [15] = xM, [16] = yM, [17] = zM, [18]=cM, [19]=i0...[28]=i9, - - // Compile expression into a serie of opcodes. - s_op = ""; ss_op = expr._data; - const unsigned int ind_result = compile(expr._data,expr._data + expr._width - 1,0,0); - p_code_end = code.end(); - - // Free resources used for parsing and prepare for evaluation. - if (_cimg_mp_is_vector(ind_result)) result_dim = _cimg_mp_vector_size(ind_result); - mem.resize(mempos,1,1,1,-1); - result = mem._data + ind_result; - memtype.assign(); - level.assign(); - variable_pos.assign(); - reserved_label.assign(); - expr.assign(); - pexpr.assign(); - opcode.assign(); - opcode._width = opcode._depth = opcode._spectrum = 1; - opcode._is_shared = true; - - // Execute init() function if any specified. - p_code_begin = code._data + init_size; - if (init_size) { - mem[_cimg_mp_x] = mem[_cimg_mp_y] = mem[_cimg_mp_z] = mem[_cimg_mp_c] = 0; - for (p_code = code._data; p_code &op = *p_code; - opcode._data = op._data; opcode._height = op._height; - const ulongT target = opcode[1]; - mem[target] = _cimg_mp_defunc(*this); - } - } - } - - _cimg_math_parser(): - code(_code),p_code_begin(0),p_code_end(0), - imgin(CImg::const_empty()),listin(CImgList::const_empty()), - imgout(CImg::empty()),listout(CImgList::empty()), - img_stats(_img_stats),list_stats(_list_stats),list_median(_list_median),debug_indent(0), - result_dim(0),is_parallelizable(true),need_input_copy(false),calling_function(0) { - mem.assign(1 + _cimg_mp_c,1,1,1,0); // Allow to skip 'is_empty?' test in operator()() - result = mem._data; - } - - _cimg_math_parser(const _cimg_math_parser& mp): - mem(mp.mem),code(mp.code),p_code_begin(mp.p_code_begin),p_code_end(mp.p_code_end), - imgin(mp.imgin),listin(mp.listin),imgout(mp.imgout),listout(mp.listout),img_stats(mp.img_stats), - list_stats(mp.list_stats),list_median(mp.list_median),debug_indent(0),result_dim(mp.result_dim), - is_parallelizable(mp.is_parallelizable), need_input_copy(mp.need_input_copy), - result(mem._data + (mp.result - mp.mem._data)),calling_function(0) { -#ifdef cimg_use_openmp - mem[17] = omp_get_thread_num(); -#endif - opcode._width = opcode._depth = opcode._spectrum = 1; - opcode._is_shared = true; - } - - // Count parentheses/brackets level of each character of the expression. - CImg get_level(CImg& expr) const { - bool is_escaped = false, next_is_escaped = false; - unsigned int mode = 0, next_mode = 0; // { 0=normal | 1=char-string | 2=vector-string - CImg res(expr._width - 1); - unsigned int *pd = res._data; - int lv = 0; - for (const char *ps = expr._data; *ps && lv>=0; ++ps) { - if (!next_is_escaped && *ps=='\\') next_is_escaped = true; - if (!is_escaped && *ps=='\'') { // Non-escaped character - if (!mode && ps>expr._data && *(ps - 1)=='[') next_mode = mode = 2; // Start vector-string - else if (mode==2 && *(ps + 1)==']') next_mode = !mode; // End vector-string - else if (mode<2) next_mode = mode?(mode = 0):1; // Start/end char-string - } - *(pd++) = (unsigned int)(mode>=1 || is_escaped?lv + (mode==1): - *ps=='(' || *ps=='['?lv++: - *ps==')' || *ps==']'?--lv: - lv); - mode = next_mode; - is_escaped = next_is_escaped; - next_is_escaped = false; - } - if (mode) { - cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: Unterminated string literal, in expression '%s'.", - pixel_type(),_cimg_mp_calling_function, - expr._data); - } - if (lv!=0) { - cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: Unbalanced parentheses/brackets, in expression '%s'.", - pixel_type(),_cimg_mp_calling_function, - expr._data); - } - return res; - } - - // Tell for each character of an expression if it is inside a string or not. - CImg is_inside_string(CImg& expr) const { - bool is_escaped = false, next_is_escaped = false; - unsigned int mode = 0, next_mode = 0; // { 0=normal | 1=char-string | 2=vector-string - CImg res = CImg::string(expr); - bool *pd = res._data; - for (const char *ps = expr._data; *ps; ++ps) { - if (!next_is_escaped && *ps=='\\') next_is_escaped = true; - if (!is_escaped && *ps=='\'') { // Non-escaped character - if (!mode && ps>expr._data && *(ps - 1)=='[') next_mode = mode = 2; // Start vector-string - else if (mode==2 && *(ps + 1)==']') next_mode = !mode; // End vector-string - else if (mode<2) next_mode = mode?(mode = 0):1; // Start/end char-string - } - *(pd++) = mode>=1 || is_escaped; - mode = next_mode; - is_escaped = next_is_escaped; - next_is_escaped = false; - } - return res; - } - - // Compilation procedure. - unsigned int compile(char *ss, char *se, const unsigned int depth, unsigned int *const p_ref) { - if (depth>256) { - cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: Call stack overflow (infinite recursion?), " - "in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - - const char *const ss0 = ss; - char c1, c2, c3, c4; - - if (ssss && (c1=*(se - 1))>0 && (c1<=' ' || c1==';')) --se; - } - if (se>ss && *(se - 1)==';') --se; - while (*ss=='(' && *(se - 1)==')' && std::strchr(ss,')')==se - 1) { // Detect simple content around parentheses. - ++ss; --se; - } - if (se<=ss || !*ss) { - cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: %s%s Missing %s, in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op,*s_op?":":"", - *s_op=='F'?"argument":"item", - (ss_op - 4)>expr._data?"...":"", - (ss_op - 4)>expr._data?ss_op - 4:expr._data, - ss_op + std::strlen(ss_op)<&expr.back()?"...":""); - } - - const char *const previous_s_op = s_op, *const previous_ss_op = ss_op; - const unsigned int depth1 = depth + 1; - unsigned int pos, p1, p2, p3, arg1, arg2, arg3, arg4, arg5, arg6; - char - *const se1 = se - 1, *const se2 = se - 2, *const se3 = se - 3, - *const ss1 = ss + 1, *const ss2 = ss + 2, *const ss3 = ss + 3, *const ss4 = ss + 4, - *const ss5 = ss + 5, *const ss6 = ss + 6, *const ss7 = ss + 7, *const ss8 = ss + 8, - *s, *ps, *ns, *s0, *s1, *s2, *s3, sep = 0, end = 0; - double val, val1, val2; - mp_func op; - - // 'p_ref' is a 'unsigned int[7]' used to return a reference to an image or vector value - // linked to the returned memory slot (reference that cannot be determined at compile time). - // p_ref[0] can be { 0 = scalar (unlinked) | 1 = vector value | 2 = image value (offset) | - // 3 = image value (coordinates) | 4 = image value as a vector (offsets) | - // 5 = image value as a vector (coordinates) }. - // Depending on p_ref[0], the remaining p_ref[k] have the following meaning: - // When p_ref[0]==0, p_ref is actually unlinked. - // When p_ref[0]==1, p_ref = [ 1, vector_ind, offset ]. - // When p_ref[0]==2, p_ref = [ 2, image_ind (or ~0U), is_relative, offset ]. - // When p_ref[0]==3, p_ref = [ 3, image_ind (or ~0U), is_relative, x, y, z, c ]. - // When p_ref[0]==4, p_ref = [ 4, image_ind (or ~0U), is_relative, offset ]. - // When p_ref[0]==5, p_ref = [ 5, image_ind (or ~0U), is_relative, x, y, z ]. - if (p_ref) { *p_ref = 0; p_ref[1] = p_ref[2] = p_ref[3] = p_ref[4] = p_ref[5] = p_ref[6] = ~0U; } - - const char saved_char = *se; *se = 0; - const unsigned int clevel = level[ss - expr._data], clevel1 = clevel + 1; - bool is_sth, is_relative; - CImg ref; - CImgList _opcode; - CImg variable_name; - - // Look for a single value or a pre-defined variable. - int nb = cimg_sscanf(ss,"%lf%c%c",&val,&(sep=0),&(end=0)); - -#if cimg_OS==2 - // Check for +/-NaN and +/-inf as Microsoft's sscanf() version is not able - // to read those particular values. - if (!nb && (*ss=='+' || *ss=='-' || *ss=='i' || *ss=='I' || *ss=='n' || *ss=='N')) { - is_sth = true; - s = ss; - if (*s=='+') ++s; else if (*s=='-') { ++s; is_sth = false; } - if (!cimg::strcasecmp(s,"inf")) { val = cimg::type::inf(); nb = 1; } - else if (!cimg::strcasecmp(s,"nan")) { val = cimg::type::nan(); nb = 1; } - if (nb==1 && !is_sth) val = -val; - } -#endif - if (nb==1) _cimg_mp_constant(val); - if (nb==2 && sep=='%') _cimg_mp_constant(val/100); - - if (ss1==se) switch (*ss) { // One-char variable - case 'c' : case 'd' : case 'e' : case 'h' : case 'l' : case 'r' : - case 's' : case 't' : case 'w' : case 'x' : case 'y' : case 'z' : - _cimg_mp_return(reserved_label[*ss]); - case 'u' : - if (reserved_label['u']!=~0U) _cimg_mp_return(reserved_label['u']); - _cimg_mp_scalar2(mp_u,0,1); - case 'g' : - if (reserved_label['g']!=~0U) _cimg_mp_return(reserved_label['g']); - _cimg_mp_scalar0(mp_g); - case 'i' : - if (reserved_label['i']!=~0U) _cimg_mp_return(reserved_label['i']); - _cimg_mp_scalar0(mp_i); - case 'I' : - _cimg_mp_op("Variable 'I'"); - if (reserved_label['I']!=~0U) _cimg_mp_return(reserved_label['I']); - _cimg_mp_check_vector0(imgin._spectrum); - need_input_copy = true; - pos = vector(imgin._spectrum); - CImg::vector((ulongT)mp_Joff,pos,0,0).move_to(code); - _cimg_mp_return(pos); - case 'R' : - if (reserved_label['R']!=~0U) _cimg_mp_return(reserved_label['R']); - need_input_copy = true; - _cimg_mp_scalar6(mp_ixyzc,_cimg_mp_x,_cimg_mp_y,_cimg_mp_z,0,0,0); - case 'G' : - if (reserved_label['G']!=~0U) _cimg_mp_return(reserved_label['G']); - need_input_copy = true; - _cimg_mp_scalar6(mp_ixyzc,_cimg_mp_x,_cimg_mp_y,_cimg_mp_z,1,0,0); - case 'B' : - if (reserved_label['B']!=~0U) _cimg_mp_return(reserved_label['B']); - need_input_copy = true; - _cimg_mp_scalar6(mp_ixyzc,_cimg_mp_x,_cimg_mp_y,_cimg_mp_z,2,0,0); - case 'A' : - if (reserved_label['A']!=~0U) _cimg_mp_return(reserved_label['A']); - need_input_copy = true; - _cimg_mp_scalar6(mp_ixyzc,_cimg_mp_x,_cimg_mp_y,_cimg_mp_z,3,0,0); - } - else if (ss2==se) { // Two-chars variable - arg1 = arg2 = ~0U; - if (*ss=='w' && *ss1=='h') _cimg_mp_return(reserved_label[0]); // wh - if (*ss=='p' && *ss1=='i') _cimg_mp_return(reserved_label[3]); // pi - if (*ss=='i') { - if (*ss1>='0' && *ss1<='9') { // i0...i9 - pos = 19 + *ss1 - '0'; - if (reserved_label[pos]!=~0U) _cimg_mp_return(reserved_label[pos]); - need_input_copy = true; - _cimg_mp_scalar6(mp_ixyzc,_cimg_mp_x,_cimg_mp_y,_cimg_mp_z,pos - 19,0,0); - } - switch (*ss1) { - case 'm' : arg1 = 4; arg2 = 0; break; // im - case 'M' : arg1 = 5; arg2 = 1; break; // iM - case 'a' : arg1 = 6; arg2 = 2; break; // ia - case 'v' : arg1 = 7; arg2 = 3; break; // iv - case 's' : arg1 = 8; arg2 = 12; break; // is - case 'p' : arg1 = 9; arg2 = 13; break; // is - case 'c' : // ic - if (reserved_label[10]!=~0U) _cimg_mp_return(reserved_label[10]); - if (mem_img_median==~0U) mem_img_median = imgin?constant(imgin.median()):0; - _cimg_mp_return(mem_img_median); - break; - } - } - else if (*ss1=='m') switch (*ss) { - case 'x' : arg1 = 11; arg2 = 4; break; // xm - case 'y' : arg1 = 12; arg2 = 5; break; // ym - case 'z' : arg1 = 13; arg2 = 6; break; // zm - case 'c' : arg1 = 14; arg2 = 7; break; // cm - } - else if (*ss1=='M') switch (*ss) { - case 'x' : arg1 = 15; arg2 = 8; break; // xM - case 'y' : arg1 = 16; arg2 = 9; break; // yM - case 'z' : arg1 = 17; arg2 = 10; break; // zM - case 'c' : arg1 = 18; arg2 = 11; break; // cM - } - if (arg1!=~0U) { - if (reserved_label[arg1]!=~0U) _cimg_mp_return(reserved_label[arg1]); - if (!img_stats) { - img_stats.assign(1,14,1,1,0).fill(imgin.get_stats(),false); - mem_img_stats.assign(1,14,1,1,~0U); - } - if (mem_img_stats[arg2]==~0U) mem_img_stats[arg2] = constant(img_stats[arg2]); - _cimg_mp_return(mem_img_stats[arg2]); - } - } else if (ss3==se) { // Three-chars variable - if (*ss=='w' && *ss1=='h' && *ss2=='d') _cimg_mp_return(reserved_label[1]); // whd - } else if (ss4==se) { // Four-chars variable - if (*ss=='w' && *ss1=='h' && *ss2=='d' && *ss3=='s') _cimg_mp_return(reserved_label[2]); // whds - } - - pos = ~0U; - for (s0 = ss, s = ss1; s='i'?1:3,p2); - - if (p_ref) { - *p_ref = _cimg_mp_is_vector(arg2)?4:2; - p_ref[1] = p1; - p_ref[2] = (unsigned int)is_relative; - p_ref[3] = arg1; - if (_cimg_mp_is_vector(arg2)) - set_variable_vector(arg2); // Prevent from being used in further optimization - else if (_cimg_mp_is_temp(arg2)) memtype[arg2] = -1; - if (p1!=~0U && _cimg_mp_is_temp(p1)) memtype[p1] = -1; - if (_cimg_mp_is_temp(arg1)) memtype[arg1] = -1; - } - if (p1!=~0U) { - if (!listout) _cimg_mp_return(arg2); - if (*ss>='i') - CImg::vector((ulongT)(is_relative?mp_list_set_joff:mp_list_set_ioff), - arg2,p1,arg1).move_to(code); - else if (_cimg_mp_is_scalar(arg2)) - CImg::vector((ulongT)(is_relative?mp_list_set_Joff_s:mp_list_set_Ioff_s), - arg2,p1,arg1).move_to(code); - else - CImg::vector((ulongT)(is_relative?mp_list_set_Joff_v:mp_list_set_Ioff_v), - arg2,p1,arg1).move_to(code); - } else { - if (!imgout) _cimg_mp_return(arg2); - if (*ss>='i') - CImg::vector((ulongT)(is_relative?mp_set_joff:mp_set_ioff), - arg2,arg1).move_to(code); - else if (_cimg_mp_is_scalar(arg2)) - CImg::vector((ulongT)(is_relative?mp_set_Joff_s:mp_set_Ioff_s), - arg2,arg1).move_to(code); - else - CImg::vector((ulongT)(is_relative?mp_set_Joff_v:mp_set_Ioff_v), - arg2,arg1).move_to(code); - } - _cimg_mp_return(arg2); - } - - if (*ss1=='(' && *ve1==')') { // i/j/I/J(_#ind,_x,_y,_z,_c) = value - is_parallelizable = false; - if (*ss2=='#') { // Index specified - s0 = ss3; while (s01) { - arg2 = arg1 + 1; - if (p2>2) { - arg3 = arg2 + 1; - if (p2>3) arg4 = arg3 + 1; - } - } - } else if (s1='i'?1:3,p2); - - if (p_ref) { - *p_ref = _cimg_mp_is_vector(arg5)?5:3; - p_ref[1] = p1; - p_ref[2] = (unsigned int)is_relative; - p_ref[3] = arg1; - p_ref[4] = arg2; - p_ref[5] = arg3; - p_ref[6] = arg4; - if (_cimg_mp_is_vector(arg5)) - set_variable_vector(arg5); // Prevent from being used in further optimization - else if (_cimg_mp_is_temp(arg5)) memtype[arg5] = -1; - if (p1!=~0U && _cimg_mp_is_temp(p1)) memtype[p1] = -1; - if (_cimg_mp_is_temp(arg1)) memtype[arg1] = -1; - if (_cimg_mp_is_temp(arg2)) memtype[arg2] = -1; - if (_cimg_mp_is_temp(arg3)) memtype[arg3] = -1; - if (_cimg_mp_is_temp(arg4)) memtype[arg4] = -1; - } - if (p1!=~0U) { - if (!listout) _cimg_mp_return(arg5); - if (*ss>='i') - CImg::vector((ulongT)(is_relative?mp_list_set_jxyzc:mp_list_set_ixyzc), - arg5,p1,arg1,arg2,arg3,arg4).move_to(code); - else if (_cimg_mp_is_scalar(arg5)) - CImg::vector((ulongT)(is_relative?mp_list_set_Jxyz_s:mp_list_set_Ixyz_s), - arg5,p1,arg1,arg2,arg3).move_to(code); - else - CImg::vector((ulongT)(is_relative?mp_list_set_Jxyz_v:mp_list_set_Ixyz_v), - arg5,p1,arg1,arg2,arg3).move_to(code); - } else { - if (!imgout) _cimg_mp_return(arg5); - if (*ss>='i') - CImg::vector((ulongT)(is_relative?mp_set_jxyzc:mp_set_ixyzc), - arg5,arg1,arg2,arg3,arg4).move_to(code); - else if (_cimg_mp_is_scalar(arg5)) - CImg::vector((ulongT)(is_relative?mp_set_Jxyz_s:mp_set_Ixyz_s), - arg5,arg1,arg2,arg3).move_to(code); - else - CImg::vector((ulongT)(is_relative?mp_set_Jxyz_v:mp_set_Ixyz_v), - arg5,arg1,arg2,arg3).move_to(code); - } - _cimg_mp_return(arg5); - } - } - - // Assign vector value (direct). - if (l_variable_name>3 && *ve1==']' && *ss!='[') { - s0 = ve1; while (s0>ss && *s0!='[') --s0; - is_sth = true; // is_valid_variable_name? - if (*ss>='0' && *ss<='9') is_sth = false; - else for (ns = ss; nsss) { - variable_name[s0 - ss] = 0; // Remove brackets in variable name - arg1 = ~0U; // Vector slot - arg2 = compile(++s0,ve1,depth1,0); // Index - arg3 = compile(s + 1,se,depth1,0); // Value to assign - _cimg_mp_check_type(arg3,2,1,0); - - if (variable_name[1]) { // Multi-char variable - cimglist_for(variable_def,i) if (!std::strcmp(variable_name,variable_def[i])) { - arg1 = variable_pos[i]; break; - } - } else arg1 = reserved_label[*variable_name]; // Single-char variable - if (arg1==~0U) compile(ss,s0 - 1,depth1,0); // Variable does not exist -> error - else { // Variable already exists - if (_cimg_mp_is_scalar(arg1)) compile(ss,s,depth1,0); // Variable is not a vector -> error - if _cimg_mp_is_constant(arg2) { // Constant index -> return corresponding variable slot directly - nb = (int)mem[arg2]; - if (nb>=0 && nb<(int)_cimg_mp_vector_size(arg1)) { - arg1+=nb + 1; - CImg::vector((ulongT)mp_copy,arg1,arg3).move_to(code); - _cimg_mp_return(arg1); - } - compile(ss,s,depth1,0); // Out-of-bounds reference -> error - } - - // Case of non-constant index -> return assigned value + linked reference - if (p_ref) { - *p_ref = 1; - p_ref[1] = arg1; - p_ref[2] = arg2; - if (_cimg_mp_is_temp(arg3)) memtype[arg3] = -1; // Prevent from being used in further optimization - if (_cimg_mp_is_temp(arg2)) memtype[arg2] = -1; - } - CImg::vector((ulongT)mp_vector_set_off,arg3,arg1,_cimg_mp_vector_size(arg1),arg2,arg3). - move_to(code); - _cimg_mp_return(arg3); - } - } - } - - // Assign user-defined macro. - if (l_variable_name>2 && *ve1==')' && *ss!='(') { - s0 = ve1; while (s0>ss && *s0!='(') --s0; - is_sth = std::strncmp(variable_name,"debug(",6) && - std::strncmp(variable_name,"print(",6); // is_valid_function_name? - if (*ss>='0' && *ss<='9') is_sth = false; - else for (ns = ss; nsss) { // Looks like a valid function declaration - s0 = variable_name._data + (s0 - ss); - *s0 = 0; - s1 = variable_name._data + l_variable_name - 1; // Pointer to closing parenthesis - CImg(variable_name._data,(unsigned int)(s0 - variable_name._data + 1)).move_to(function_def,0); - ++s; while (*s && *s<=' ') ++s; - CImg(s,(unsigned int)(se - s + 1)).move_to(function_body,0); - - p1 = 1; // Indice of current parsed argument - for (s = s0 + 1; s<=s1; ++p1, s = ns + 1) { // Parse function arguments - if (p1>24) { - *se = saved_char; cimg::strellipsize(variable_name,64); cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: %s: Too much specified arguments (>24) when defining " - "function '%s()', in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op, - variable_name._data, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - while (*s && *s<=' ') ++s; - if (*s==')' && p1==1) break; // Function has no arguments - - s2 = s; // Start of the argument name - is_sth = true; // is_valid_argument_name? - if (*s>='0' && *s<='9') is_sth = false; - else for (ns = s; ns' '; ++ns) - if (!is_varchar(*ns)) { is_sth = false; break; } - s3 = ns; // End of the argument name - while (*ns && *ns<=' ') ++ns; - if (!is_sth || s2==s3 || (*ns!=',' && ns!=s1)) { - *se = saved_char; cimg::strellipsize(variable_name,64); cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: %s: %s name specified for argument %u when defining " - "function '%s()', in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op, - is_sth?"Empty":"Invalid",p1, - variable_name._data, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - if (ns==s1 || *ns==',') { // New argument found - *s3 = 0; - p2 = (unsigned int)(s3 - s2); // Argument length - p3 = function_body[0]._width - p2 + 1; // Related to copy length - for (ps = std::strstr(function_body[0],s2); ps; ps = std::strstr(ps,s2)) { // Replace by arg number - if (!((ps>function_body[0]._data && is_varchar(*(ps - 1))) || - (ps + p21) { - std::memmove(ps,ps + p2 - 1,function_body[0]._data + p3 - ps); - function_body[0]._width-=p2 - 1; - } - } else ++ps; - } - } - } - // Store number of arguments - function_def[0].resize(function_def[0]._width + 1,1,1,1,0).back() = (char)(p1 - 1); - - // Detect parts of function body inside a string. - is_inside_string(function_body[0]).move_to(function_body_is_string,0); - _cimg_mp_return(_cimg_mp_nan); - } - } - - // Check if the variable name could be valid. If not, this is probably an lvalue assignment. - is_sth = true; // is_valid_variable_name? - if (*variable_name>='0' && *variable_name<='9') is_sth = false; - else for (ns = variable_name._data; *ns; ++ns) - if (!is_varchar(*ns)) { is_sth = false; break; } - - // Assign variable (direct). - if (is_sth) { - if (variable_name[1] && !variable_name[2]) { // Two-chars variable - c1 = variable_name[0]; - c2 = variable_name[1]; - if (c1=='w' && c2=='h') variable_name.fill((char)0,(char)0); // wh - else if (c1=='p' && c2=='i') variable_name.fill(3,0); // pi - else if (c1=='i') { - if (c2>='0' && c2<='9') variable_name.fill(19 + c2 - '0',0); // i0...i9 - else if (c2=='m') variable_name.fill(4,0); // im - else if (c2=='M') variable_name.fill(5,0); // iM - else if (c2=='a') variable_name.fill(6,0); // ia - else if (c2=='v') variable_name.fill(7,0); // iv - else if (c2=='s') variable_name.fill(8,0); // is - else if (c2=='p') variable_name.fill(9,0); // ip - else if (c2=='c') variable_name.fill(10,0); // ic - } else if (c2=='m') { - if (c1=='x') variable_name.fill(11,0); // xm - else if (c1=='y') variable_name.fill(12,0); // ym - else if (c1=='z') variable_name.fill(13,0); // zm - else if (c1=='c') variable_name.fill(14,0); // cm - } else if (c2=='M') { - if (c1=='x') variable_name.fill(15,0); // xM - else if (c1=='y') variable_name.fill(16,0); // yM - else if (c1=='z') variable_name.fill(17,0); // zM - else if (c1=='c') variable_name.fill(18,0); // cM - } - } else if (variable_name[1] && variable_name[2] && !variable_name[3]) { // Three-chars variable - c1 = variable_name[0]; - c2 = variable_name[1]; - c3 = variable_name[2]; - if (c1=='w' && c2=='h' && c3=='d') variable_name.fill(1,0); // whd - } else if (variable_name[1] && variable_name[2] && variable_name[3] && - !variable_name[4]) { // Four-chars variable - c1 = variable_name[0]; - c2 = variable_name[1]; - c3 = variable_name[2]; - c4 = variable_name[3]; - if (c1=='w' && c2=='h' && c3=='d' && c4=='s') variable_name.fill(2,0); // whds - } else if (!std::strcmp(variable_name,"interpolation")) variable_name.fill(29,0); - else if (!std::strcmp(variable_name,"boundary")) variable_name.fill(30,0); - - arg1 = ~0U; - arg2 = compile(s + 1,se,depth1,0); - if (!variable_name[1]) // One-char variable, or variable in reserved_labels - arg1 = reserved_label[*variable_name]; - else // Multi-char variable name : check for existing variable with same name - cimglist_for(variable_def,i) - if (!std::strcmp(variable_name,variable_def[i])) { arg1 = variable_pos[i]; break; } - - if (arg1==~0U || arg1<=_cimg_mp_c) { // Create new variable - if (_cimg_mp_is_vector(arg2)) { // Vector variable - arg1 = vector_copy(arg2); - set_variable_vector(arg1); - } else { // Scalar variable - arg1 = scalar1(mp_copy,arg2); - memtype[arg1] = -1; - } - - if (!variable_name[1]) reserved_label[*variable_name] = arg1; - else { - if (variable_def._width>=variable_pos._width) variable_pos.resize(-200,1,1,1,0); - variable_pos[variable_def._width] = arg1; - variable_name.move_to(variable_def); - } - - } else { // Variable already exists -> assign a new value - _cimg_mp_check_type(arg2,2,_cimg_mp_is_vector(arg1)?3:1,_cimg_mp_vector_size(arg1)); - if (_cimg_mp_is_vector(arg1)) { // Vector - if (_cimg_mp_is_vector(arg2)) // From vector - CImg::vector((ulongT)mp_vector_copy,arg1,arg2,(ulongT)_cimg_mp_vector_size(arg1)). - move_to(code); - else // From scalar - CImg::vector((ulongT)mp_vector_init,arg1,(ulongT)_cimg_mp_vector_size(arg1),arg2). - move_to(code); - } else // Scalar - CImg::vector((ulongT)mp_copy,arg1,arg2).move_to(code); - } - _cimg_mp_return(arg1); - } - - // Assign lvalue (variable name was not valid). - is_sth = (bool)std::strchr(variable_name,'?'); // Contains_ternary_operator? - if (is_sth) break; // Do nothing and make ternary operator prioritary over assignment - - if (l_variable_name>2 && (std::strchr(variable_name,'(') || std::strchr(variable_name,'['))) { - ref.assign(7); - arg1 = compile(ss,s,depth1,ref); // Lvalue slot - arg2 = compile(s + 1,se,depth1,0); // Value to assign - - if (*ref==1) { // Vector value (scalar): V[k] = scalar - _cimg_mp_check_type(arg2,2,1,0); - arg3 = ref[1]; // Vector slot - arg4 = ref[2]; // Index - if (p_ref) std::memcpy(p_ref,ref,ref._width*sizeof(unsigned int)); - CImg::vector((ulongT)mp_vector_set_off,arg2,arg3,(ulongT)_cimg_mp_vector_size(arg3),arg4,arg2). - move_to(code); - _cimg_mp_return(arg2); - } - - if (*ref==2) { // Image value (scalar): i/j[_#ind,off] = scalar - _cimg_mp_check_type(arg2,2,1,0); - is_parallelizable = false; - p1 = ref[1]; // Index - is_relative = (bool)ref[2]; - arg3 = ref[3]; // Offset - if (p_ref) std::memcpy(p_ref,ref,ref._width*sizeof(unsigned int)); - if (p1!=~0U) { - if (!listout) _cimg_mp_return(arg2); - CImg::vector((ulongT)(is_relative?mp_list_set_joff:mp_list_set_ioff), - arg2,p1,arg3).move_to(code); - } else { - if (!imgout) _cimg_mp_return(arg2); - CImg::vector((ulongT)(is_relative?mp_set_joff:mp_set_ioff), - arg2,arg3).move_to(code); - } - _cimg_mp_return(arg2); - } - - if (*ref==3) { // Image value (scalar): i/j(_#ind,_x,_y,_z,_c) = scalar - _cimg_mp_check_type(arg2,2,1,0); - is_parallelizable = false; - p1 = ref[1]; // Index - is_relative = (bool)ref[2]; - arg3 = ref[3]; // X - arg4 = ref[4]; // Y - arg5 = ref[5]; // Z - arg6 = ref[6]; // C - if (p_ref) std::memcpy(p_ref,ref,ref._width*sizeof(unsigned int)); - if (p1!=~0U) { - if (!listout) _cimg_mp_return(arg2); - CImg::vector((ulongT)(is_relative?mp_list_set_jxyzc:mp_list_set_ixyzc), - arg2,p1,arg3,arg4,arg5,arg6).move_to(code); - } else { - if (!imgout) _cimg_mp_return(arg2); - CImg::vector((ulongT)(is_relative?mp_set_jxyzc:mp_set_ixyzc), - arg2,arg3,arg4,arg5,arg6).move_to(code); - } - _cimg_mp_return(arg2); - } - - if (*ref==4) { // Image value (vector): I/J[_#ind,off] = value - _cimg_mp_check_type(arg2,2,3,_cimg_mp_vector_size(arg1)); - is_parallelizable = false; - p1 = ref[1]; // Index - is_relative = (bool)ref[2]; - arg3 = ref[3]; // Offset - if (p_ref) std::memcpy(p_ref,ref,ref._width*sizeof(unsigned int)); - if (p1!=~0U) { - if (!listout) _cimg_mp_return(arg2); - if (_cimg_mp_is_scalar(arg2)) - CImg::vector((ulongT)(is_relative?mp_list_set_Joff_s:mp_list_set_Ioff_s), - arg2,p1,arg3).move_to(code); - else - CImg::vector((ulongT)(is_relative?mp_list_set_Joff_v:mp_list_set_Ioff_v), - arg2,p1,arg3).move_to(code); - } else { - if (!imgout) _cimg_mp_return(arg2); - if (_cimg_mp_is_scalar(arg2)) - CImg::vector((ulongT)(is_relative?mp_set_Joff_s:mp_set_Ioff_s), - arg2,arg3).move_to(code); - else - CImg::vector((ulongT)(is_relative?mp_set_Joff_v:mp_set_Ioff_v), - arg2,arg3).move_to(code); - } - _cimg_mp_return(arg2); - } - - if (*ref==5) { // Image value (vector): I/J(_#ind,_x,_y,_z,_c) = value - _cimg_mp_check_type(arg2,2,3,_cimg_mp_vector_size(arg1)); - is_parallelizable = false; - p1 = ref[1]; // Index - is_relative = (bool)ref[2]; - arg3 = ref[3]; // X - arg4 = ref[4]; // Y - arg5 = ref[5]; // Z - if (p_ref) std::memcpy(p_ref,ref,ref._width*sizeof(unsigned int)); - if (p1!=~0U) { - if (!listout) _cimg_mp_return(arg2); - if (_cimg_mp_is_scalar(arg2)) - CImg::vector((ulongT)(is_relative?mp_list_set_Jxyz_s:mp_list_set_Ixyz_s), - arg2,p1,arg3,arg4,arg5).move_to(code); - else - CImg::vector((ulongT)(is_relative?mp_list_set_Jxyz_v:mp_list_set_Ixyz_v), - arg2,p1,arg3,arg4,arg5).move_to(code); - } else { - if (!imgout) _cimg_mp_return(arg2); - if (_cimg_mp_is_scalar(arg2)) - CImg::vector((ulongT)(is_relative?mp_set_Jxyz_s:mp_set_Ixyz_s), - arg2,arg3,arg4,arg5).move_to(code); - else - CImg::vector((ulongT)(is_relative?mp_set_Jxyz_v:mp_set_Ixyz_v), - arg2,arg3,arg4,arg5).move_to(code); - } - _cimg_mp_return(arg2); - } - - if (_cimg_mp_is_vector(arg1)) { // Vector variable: V = value - _cimg_mp_check_type(arg2,2,1,0); - if (_cimg_mp_is_vector(arg2)) // From vector - CImg::vector((ulongT)mp_vector_copy,arg1,arg2,(ulongT)_cimg_mp_vector_size(arg1)). - move_to(code); - else // From scalar - CImg::vector((ulongT)mp_vector_init,arg1,(ulongT)_cimg_mp_vector_size(arg1),arg2). - move_to(code); - _cimg_mp_return(arg1); - } - - if _cimg_mp_is_variable(arg1) { // Scalar variable: s = scalar - _cimg_mp_check_type(arg2,2,1,0); - CImg::vector((ulongT)mp_copy,arg1,arg2).move_to(code); - _cimg_mp_return(arg1); - - } - } - - // No assignment expressions match -> error - *se = saved_char; cimg::strellipsize(variable_name,64); cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: %s: Invalid left-hand operand '%s', " - "in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op, - variable_name._data, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - - // Apply unary/binary/ternary operators. The operator precedences should be roughly the same as in C++. - for (s = se2, ps = se3, ns = ps - 1; s>ss1; --s, --ps, --ns) // Here, ns = ps - 1 - if (*s=='=' && (*ps=='*' || *ps=='/' || *ps=='^') && *ns==*ps && - level[s - expr._data]==clevel) { // Self-operators for complex numbers only (**=,//=,^^=) - _cimg_mp_op(*ps=='*'?"Operator '**='":*ps=='/'?"Operator '//='":"Operator '^^='"); - - ref.assign(7); - arg1 = compile(ss,ns,depth1,ref); // Vector slot - arg2 = compile(s + 1,se,depth1,0); // Right operand - if (*ps!='*') { - _cimg_mp_check_type(arg1,2,2,2); - _cimg_mp_check_type(arg2,2,2,2); - } - if (_cimg_mp_is_vector(arg2)) { // Complex **= complex or Matrix **= matrix - if (*ps=='*') { - if (_cimg_mp_vector_size(arg1)==2 && _cimg_mp_vector_size(arg2)==2) - CImg::vector((ulongT)mp_complex_mul,arg1,arg1,arg2).move_to(code); - else { - _cimg_mp_check_matrix_square(arg2,2); - p3 = _cimg_mp_vector_size(arg1); - p2 = (unsigned int)std::sqrt((float)_cimg_mp_vector_size(arg2)); - p1 = p3/p2; - if (p1*p2!=p3) { - *se = saved_char; cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: %s: Types of left-hand and right-hand operands " - "('%s' and '%s') do not match, in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op, - s_type(arg1)._data,s_type(arg2)._data, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - CImg::vector((ulongT)mp_matrix_mul,arg1,arg1,arg2,p1,p2,p2).move_to(code); - } - } else if (*ps=='/') - CImg::vector((ulongT)mp_complex_div_vv,arg1,arg1,arg2).move_to(code); - else - CImg::vector((ulongT)mp_complex_pow_vv,arg1,arg1,arg2).move_to(code); - } else { // Complex **= scalar - if (*ps=='*') self_vector_s(arg1,mp_self_mul,arg2); - else if (*ps=='/') self_vector_s(arg1,mp_self_div,arg2); - else CImg::vector((ulongT)mp_complex_pow_vs,arg1,arg1,arg2).move_to(code); - } - - // Write computed value back in image if necessary. - if (*ref==4) { // Image value (vector): I/J[_#ind,off] **= value - is_parallelizable = false; - p1 = ref[1]; // Index - is_relative = (bool)ref[2]; - arg3 = ref[3]; // Offset - if (p_ref) std::memcpy(p_ref,ref,ref._width*sizeof(unsigned int)); - if (p1!=~0U) { - if (!listout) _cimg_mp_return(arg1); - CImg::vector((ulongT)(is_relative?mp_list_set_Joff_v:mp_list_set_Ioff_v), - arg1,p1,arg3).move_to(code); - } else { - if (!imgout) _cimg_mp_return(arg1); - CImg::vector((ulongT)(is_relative?mp_set_Joff_v:mp_set_Ioff_v), - arg1,arg3).move_to(code); - } - - } else if (*ref==5) { // Image value (vector): I/J(_#ind,_x,_y,_z,_c) **= value - is_parallelizable = false; - p1 = ref[1]; // Index - is_relative = (bool)ref[2]; - arg3 = ref[3]; // X - arg4 = ref[4]; // Y - arg5 = ref[5]; // Z - if (p_ref) std::memcpy(p_ref,ref,ref._width*sizeof(unsigned int)); - if (p1!=~0U) { - if (!listout) _cimg_mp_return(arg1); - CImg::vector((ulongT)(is_relative?mp_list_set_Jxyz_v:mp_list_set_Ixyz_v), - arg1,p1,arg3,arg4,arg5).move_to(code); - } else { - if (!imgout) _cimg_mp_return(arg1); - CImg::vector((ulongT)(is_relative?mp_set_Jxyz_v:mp_set_Ixyz_v), - arg1,arg3,arg4,arg5).move_to(code); - } - } - - _cimg_mp_return(arg1); - } - - for (s = se2, ps = se3, ns = ps - 1; s>ss1; --s, --ps, --ns) // Here, ns = ps - 1 - if (*s=='=' && (*ps=='+' || *ps=='-' || *ps=='*' || *ps=='/' || *ps=='%' || - *ps=='&' || *ps=='^' || *ps=='|' || - (*ps=='>' && *ns=='>') || (*ps=='<' && *ns=='<')) && - level[s - expr._data]==clevel) { // Self-operators (+=,-=,*=,/=,%=,>>=,<<=,&=,^=,|=) - switch (*ps) { - case '+' : op = mp_self_add; _cimg_mp_op("Operator '+='"); break; - case '-' : op = mp_self_sub; _cimg_mp_op("Operator '-='"); break; - case '*' : op = mp_self_mul; _cimg_mp_op("Operator '*='"); break; - case '/' : op = mp_self_div; _cimg_mp_op("Operator '/='"); break; - case '%' : op = mp_self_modulo; _cimg_mp_op("Operator '%='"); break; - case '<' : op = mp_self_bitwise_left_shift; _cimg_mp_op("Operator '<<='"); break; - case '>' : op = mp_self_bitwise_right_shift; _cimg_mp_op("Operator '>>='"); break; - case '&' : op = mp_self_bitwise_and; _cimg_mp_op("Operator '&='"); break; - case '|' : op = mp_self_bitwise_or; _cimg_mp_op("Operator '|='"); break; - default : op = mp_self_pow; _cimg_mp_op("Operator '^='"); break; - } - s1 = *ps=='>' || *ps=='<'?ns:ps; - - ref.assign(7); - arg1 = compile(ss,s1,depth1,ref); // Variable slot - arg2 = compile(s + 1,se,depth1,0); // Value to apply - - if (*ref>0 && !_cimg_mp_is_temp(arg1)) { // Apply operator on a copy if necessary. - if (_cimg_mp_is_vector(arg1)) arg1 = vector_copy(arg1); - else arg1 = scalar1(mp_copy,arg1); - } - - if (*ref==1) { // Vector value (scalar): V[k] += scalar - _cimg_mp_check_type(arg2,2,1,0); - arg3 = ref[1]; // Vector slot - arg4 = ref[2]; // Index - if (p_ref) std::memcpy(p_ref,ref,ref._width*sizeof(unsigned int)); - CImg::vector((ulongT)op,arg1,arg2).move_to(code); - CImg::vector((ulongT)mp_vector_set_off,arg1,arg3,(ulongT)_cimg_mp_vector_size(arg3),arg4,arg1). - move_to(code); - _cimg_mp_return(arg1); - } - - if (*ref==2) { // Image value (scalar): i/j[_#ind,off] += scalar - _cimg_mp_check_type(arg2,2,1,0); - is_parallelizable = false; - p1 = ref[1]; // Index - is_relative = (bool)ref[2]; - arg3 = ref[3]; // Offset - if (p_ref) std::memcpy(p_ref,ref,ref._width*sizeof(unsigned int)); - CImg::vector((ulongT)op,arg1,arg2).move_to(code); - if (p1!=~0U) { - if (!listout) _cimg_mp_return(arg1); - CImg::vector((ulongT)(is_relative?mp_list_set_joff:mp_list_set_ioff), - arg1,p1,arg3).move_to(code); - } else { - if (!imgout) _cimg_mp_return(arg1); - CImg::vector((ulongT)(is_relative?mp_set_joff:mp_set_ioff), - arg1,arg3).move_to(code); - } - _cimg_mp_return(arg1); - } - - if (*ref==3) { // Image value (scalar): i/j(_#ind,_x,_y,_z,_c) += scalar - _cimg_mp_check_type(arg2,2,1,0); - is_parallelizable = false; - p1 = ref[1]; // Index - is_relative = (bool)ref[2]; - arg3 = ref[3]; // X - arg4 = ref[4]; // Y - arg5 = ref[5]; // Z - arg6 = ref[6]; // C - if (p_ref) std::memcpy(p_ref,ref,ref._width*sizeof(unsigned int)); - CImg::vector((ulongT)op,arg1,arg2).move_to(code); - if (p1!=~0U) { - if (!listout) _cimg_mp_return(arg1); - CImg::vector((ulongT)(is_relative?mp_list_set_jxyzc:mp_list_set_ixyzc), - arg1,p1,arg3,arg4,arg5,arg6).move_to(code); - } else { - if (!imgout) _cimg_mp_return(arg1); - CImg::vector((ulongT)(is_relative?mp_set_jxyzc:mp_set_ixyzc), - arg1,arg3,arg4,arg5,arg6).move_to(code); - } - _cimg_mp_return(arg1); - } - - if (*ref==4) { // Image value (vector): I/J[_#ind,off] += value - _cimg_mp_check_type(arg2,2,3,_cimg_mp_vector_size(arg1)); - is_parallelizable = false; - p1 = ref[1]; // Index - is_relative = (bool)ref[2]; - arg3 = ref[3]; // Offset - if (p_ref) std::memcpy(p_ref,ref,ref._width*sizeof(unsigned int)); - if (_cimg_mp_is_scalar(arg2)) self_vector_s(arg1,op,arg2); else self_vector_v(arg1,op,arg2); - if (p1!=~0U) { - if (!listout) _cimg_mp_return(arg1); - CImg::vector((ulongT)(is_relative?mp_list_set_Joff_v:mp_list_set_Ioff_v), - arg1,p1,arg3).move_to(code); - } else { - if (!imgout) _cimg_mp_return(arg1); - CImg::vector((ulongT)(is_relative?mp_set_Joff_v:mp_set_Ioff_v), - arg1,arg3).move_to(code); - } - _cimg_mp_return(arg1); - } - - if (*ref==5) { // Image value (vector): I/J(_#ind,_x,_y,_z,_c) += value - _cimg_mp_check_type(arg2,2,3,_cimg_mp_vector_size(arg1)); - is_parallelizable = false; - p1 = ref[1]; // Index - is_relative = (bool)ref[2]; - arg3 = ref[3]; // X - arg4 = ref[4]; // Y - arg5 = ref[5]; // Z - if (p_ref) std::memcpy(p_ref,ref,ref._width*sizeof(unsigned int)); - if (_cimg_mp_is_scalar(arg2)) self_vector_s(arg1,op,arg2); else self_vector_v(arg1,op,arg2); - if (p1!=~0U) { - if (!listout) _cimg_mp_return(arg1); - CImg::vector((ulongT)(is_relative?mp_list_set_Jxyz_v:mp_list_set_Ixyz_v), - arg1,p1,arg3,arg4,arg5).move_to(code); - } else { - if (!imgout) _cimg_mp_return(arg1); - CImg::vector((ulongT)(is_relative?mp_set_Jxyz_v:mp_set_Ixyz_v), - arg1,arg3,arg4,arg5).move_to(code); - } - _cimg_mp_return(arg1); - } - - if (_cimg_mp_is_vector(arg1)) { // Vector variable: V += value - _cimg_mp_check_type(arg2,2,3,_cimg_mp_vector_size(arg1)); - if (_cimg_mp_is_vector(arg2)) self_vector_v(arg1,op,arg2); // Vector += vector - else self_vector_s(arg1,op,arg2); // Vector += scalar - _cimg_mp_return(arg1); - } - - if _cimg_mp_is_variable(arg1) { // Scalar variable: s += scalar - _cimg_mp_check_type(arg2,2,1,0); - CImg::vector((ulongT)op,arg1,arg2).move_to(code); - _cimg_mp_return(arg1); - } - - variable_name.assign(ss,(unsigned int)(s - ss)).back() = 0; - *se = saved_char; cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: %s: Invalid left-hand operand '%s', " - "in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op, - variable_name._data, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - - for (s = ss1; s::vector((ulongT)mp_if,pos,arg1,arg2,arg3, - p3 - p2,code._width - p3,arg4).move_to(code,p2); - _cimg_mp_return(pos); - } - - for (s = se3, ns = se2; s>ss; --s, --ns) - if (*s=='|' && *ns=='|' && level[s - expr._data]==clevel) { // Logical or ('||') - _cimg_mp_op("Operator '||'"); - arg1 = compile(ss,s,depth1,0); - p2 = code._width; - arg2 = compile(s + 2,se,depth1,0); - _cimg_mp_check_type(arg1,1,1,0); - _cimg_mp_check_type(arg2,2,1,0); - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) - _cimg_mp_constant(mem[arg1] || mem[arg2]); - pos = scalar(); - CImg::vector((ulongT)mp_logical_or,pos,arg1,arg2,code._width - p2). - move_to(code,p2); - _cimg_mp_return(pos); - } - - for (s = se3, ns = se2; s>ss; --s, --ns) - if (*s=='&' && *ns=='&' && level[s - expr._data]==clevel) { // Logical and ('&&') - _cimg_mp_op("Operator '&&'"); - arg1 = compile(ss,s,depth1,0); - p2 = code._width; - arg2 = compile(s + 2,se,depth1,0); - _cimg_mp_check_type(arg1,1,1,0); - _cimg_mp_check_type(arg2,2,1,0); - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) - _cimg_mp_constant(mem[arg1] && mem[arg2]); - pos = scalar(); - CImg::vector((ulongT)mp_logical_and,pos,arg1,arg2,code._width - p2). - move_to(code,p2); - _cimg_mp_return(pos); - } - - for (s = se2; s>ss; --s) - if (*s=='|' && level[s - expr._data]==clevel) { // Bitwise or ('|') - _cimg_mp_op("Operator '|'"); - arg1 = compile(ss,s,depth1,0); - arg2 = compile(s + 1,se,depth1,0); - _cimg_mp_check_type(arg2,2,3,_cimg_mp_vector_size(arg1)); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_bitwise_or,arg1,arg2); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) _cimg_mp_vector2_vs(mp_bitwise_or,arg1,arg2); - if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_sv(mp_bitwise_or,arg1,arg2); - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) - _cimg_mp_constant((ulongT)mem[arg1] | (ulongT)mem[arg2]); - _cimg_mp_scalar2(mp_bitwise_or,arg1,arg2); - } - - for (s = se2; s>ss; --s) - if (*s=='&' && level[s - expr._data]==clevel) { // Bitwise and ('&') - _cimg_mp_op("Operator '&'"); - arg1 = compile(ss,s,depth1,0); - arg2 = compile(s + 1,se,depth1,0); - _cimg_mp_check_type(arg2,2,3,_cimg_mp_vector_size(arg1)); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_bitwise_and,arg1,arg2); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) _cimg_mp_vector2_vs(mp_bitwise_and,arg1,arg2); - if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_sv(mp_bitwise_and,arg1,arg2); - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) - _cimg_mp_constant((ulongT)mem[arg1] & (ulongT)mem[arg2]); - _cimg_mp_scalar2(mp_bitwise_and,arg1,arg2); - } - - for (s = se3, ns = se2; s>ss; --s, --ns) - if (*s=='!' && *ns=='=' && level[s - expr._data]==clevel) { // Not equal to ('!=') - _cimg_mp_op("Operator '!='"); - arg1 = compile(ss,s,depth1,0); - arg2 = compile(s + 2,se,depth1,0); - p1 = _cimg_mp_vector_size(arg1); - p2 = _cimg_mp_vector_size(arg2); - if (p1 || p2) { - if (p1 && p2 && p1!=p2) _cimg_mp_return(1); - _cimg_mp_scalar6(mp_vector_neq,arg1,p1,arg2,p2,11,1); - } - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) _cimg_mp_constant(mem[arg1]!=mem[arg2]); - _cimg_mp_scalar2(mp_neq,arg1,arg2); - } - - for (s = se3, ns = se2; s>ss; --s, --ns) - if (*s=='=' && *ns=='=' && level[s - expr._data]==clevel) { // Equal to ('==') - _cimg_mp_op("Operator '=='"); - arg1 = compile(ss,s,depth1,0); - arg2 = compile(s + 2,se,depth1,0); - p1 = _cimg_mp_vector_size(arg1); - p2 = _cimg_mp_vector_size(arg2); - if (p1 || p2) { - if (p1 && p2 && p1!=p2) _cimg_mp_return(0); - _cimg_mp_scalar6(mp_vector_eq,arg1,p1,arg2,p2,11,1); - } - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) _cimg_mp_constant(mem[arg1]==mem[arg2]); - _cimg_mp_scalar2(mp_eq,arg1,arg2); - } - - for (s = se3, ns = se2; s>ss; --s, --ns) - if (*s=='<' && *ns=='=' && level[s - expr._data]==clevel) { // Less or equal than ('<=') - _cimg_mp_op("Operator '<='"); - arg1 = compile(ss,s,depth1,0); - arg2 = compile(s + 2,se,depth1,0); - _cimg_mp_check_type(arg2,2,3,_cimg_mp_vector_size(arg1)); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_lte,arg1,arg2); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) _cimg_mp_vector2_vs(mp_lte,arg1,arg2); - if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_sv(mp_lte,arg1,arg2); - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) _cimg_mp_constant(mem[arg1]<=mem[arg2]); - _cimg_mp_scalar2(mp_lte,arg1,arg2); - } - - for (s = se3, ns = se2; s>ss; --s, --ns) - if (*s=='>' && *ns=='=' && level[s - expr._data]==clevel) { // Greater or equal than ('>=') - _cimg_mp_op("Operator '>='"); - arg1 = compile(ss,s,depth1,0); - arg2 = compile(s + 2,se,depth1,0); - _cimg_mp_check_type(arg2,2,3,_cimg_mp_vector_size(arg1)); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_gte,arg1,arg2); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) _cimg_mp_vector2_vs(mp_gte,arg1,arg2); - if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_sv(mp_gte,arg1,arg2); - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) _cimg_mp_constant(mem[arg1]>=mem[arg2]); - _cimg_mp_scalar2(mp_gte,arg1,arg2); - } - - for (s = se2, ns = se1, ps = se3; s>ss; --s, --ns, --ps) - if (*s=='<' && *ns!='<' && *ps!='<' && level[s - expr._data]==clevel) { // Less than ('<') - _cimg_mp_op("Operator '<'"); - arg1 = compile(ss,s,depth1,0); - arg2 = compile(s + 1,se,depth1,0); - _cimg_mp_check_type(arg2,2,3,_cimg_mp_vector_size(arg1)); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_lt,arg1,arg2); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) _cimg_mp_vector2_vs(mp_lt,arg1,arg2); - if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_sv(mp_lt,arg1,arg2); - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) _cimg_mp_constant(mem[arg1]ss; --s, --ns, --ps) - if (*s=='>' && *ns!='>' && *ps!='>' && level[s - expr._data]==clevel) { // Greather than ('>') - _cimg_mp_op("Operator '>'"); - arg1 = compile(ss,s,depth1,0); - arg2 = compile(s + 1,se,depth1,0); - _cimg_mp_check_type(arg2,2,3,_cimg_mp_vector_size(arg1)); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_gt,arg1,arg2); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) _cimg_mp_vector2_vs(mp_gt,arg1,arg2); - if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_sv(mp_gt,arg1,arg2); - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) _cimg_mp_constant(mem[arg1]>mem[arg2]); - _cimg_mp_scalar2(mp_gt,arg1,arg2); - } - - for (s = se3, ns = se2; s>ss; --s, --ns) - if (*s=='<' && *ns=='<' && level[s - expr._data]==clevel) { // Left bit shift ('<<') - _cimg_mp_op("Operator '<<'"); - arg1 = compile(ss,s,depth1,0); - arg2 = compile(s + 2,se,depth1,0); - _cimg_mp_check_type(arg2,2,3,_cimg_mp_vector_size(arg1)); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) - _cimg_mp_vector2_vv(mp_bitwise_left_shift,arg1,arg2); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) - _cimg_mp_vector2_vs(mp_bitwise_left_shift,arg1,arg2); - if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) - _cimg_mp_vector2_sv(mp_bitwise_left_shift,arg1,arg2); - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) - _cimg_mp_constant((longT)mem[arg1]<<(unsigned int)mem[arg2]); - _cimg_mp_scalar2(mp_bitwise_left_shift,arg1,arg2); - } - - for (s = se3, ns = se2; s>ss; --s, --ns) - if (*s=='>' && *ns=='>' && level[s - expr._data]==clevel) { // Right bit shift ('>>') - _cimg_mp_op("Operator '>>'"); - arg1 = compile(ss,s,depth1,0); - arg2 = compile(s + 2,se,depth1,0); - _cimg_mp_check_type(arg2,2,3,_cimg_mp_vector_size(arg1)); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) - _cimg_mp_vector2_vv(mp_bitwise_right_shift,arg1,arg2); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) - _cimg_mp_vector2_vs(mp_bitwise_right_shift,arg1,arg2); - if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) - _cimg_mp_vector2_sv(mp_bitwise_right_shift,arg1,arg2); - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) - _cimg_mp_constant((longT)mem[arg1]>>(unsigned int)mem[arg2]); - _cimg_mp_scalar2(mp_bitwise_right_shift,arg1,arg2); - } - - for (ns = se1, s = se2, ps = pexpr._data + (se3 - expr._data); s>ss; --ns, --s, --ps) - if (*s=='+' && (*ns!='+' || ns!=se1) && *ps!='-' && *ps!='+' && *ps!='*' && *ps!='/' && *ps!='%' && - *ps!='&' && *ps!='|' && *ps!='^' && *ps!='!' && *ps!='~' && *ps!='#' && - (*ps!='e' || !(ps - pexpr._data>ss - expr._data && (*(ps - 1)=='.' || (*(ps - 1)>='0' && - *(ps - 1)<='9')))) && - level[s - expr._data]==clevel) { // Addition ('+') - _cimg_mp_op("Operator '+'"); - arg1 = compile(ss,s,depth1,0); - arg2 = compile(s + 1,se,depth1,0); - _cimg_mp_check_type(arg2,2,3,_cimg_mp_vector_size(arg1)); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_add,arg1,arg2); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) _cimg_mp_vector2_vs(mp_add,arg1,arg2); - if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_sv(mp_add,arg1,arg2); - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) _cimg_mp_constant(mem[arg1] + mem[arg2]); - if (arg2==1) _cimg_mp_scalar1(mp_increment,arg1); - if (arg1==1) _cimg_mp_scalar1(mp_increment,arg2); - _cimg_mp_scalar2(mp_add,arg1,arg2); - } - - for (ns = se1, s = se2, ps = pexpr._data + (se3 - expr._data); s>ss; --ns, --s, --ps) - if (*s=='-' && (*ns!='-' || ns!=se1) && *ps!='-' && *ps!='+' && *ps!='*' && *ps!='/' && *ps!='%' && - *ps!='&' && *ps!='|' && *ps!='^' && *ps!='!' && *ps!='~' && *ps!='#' && - (*ps!='e' || !(ps - pexpr._data>ss - expr._data && (*(ps - 1)=='.' || (*(ps - 1)>='0' && - *(ps - 1)<='9')))) && - level[s - expr._data]==clevel) { // Subtraction ('-') - _cimg_mp_op("Operator '-'"); - arg1 = compile(ss,s,depth1,0); - arg2 = compile(s + 1,se,depth1,0); - _cimg_mp_check_type(arg2,2,3,_cimg_mp_vector_size(arg1)); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_sub,arg1,arg2); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) _cimg_mp_vector2_vs(mp_sub,arg1,arg2); - if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_sv(mp_sub,arg1,arg2); - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) _cimg_mp_constant(mem[arg1] - mem[arg2]); - if (arg2==1) _cimg_mp_scalar1(mp_decrement,arg1); - _cimg_mp_scalar2(mp_sub,arg1,arg2); - } - - for (s = se3, ns = se2; s>ss; --s, --ns) - if (*s=='*' && *ns=='*' && level[s - expr._data]==clevel) { // Complex/matrix multiplication ('**') - _cimg_mp_op("Operator '**'"); - arg1 = compile(ss,s,depth1,0); - arg2 = compile(s + 2,se,depth1,0); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) { - if (_cimg_mp_vector_size(arg1)==2 && _cimg_mp_vector_size(arg2)==2) { // Complex multiplication - pos = vector(2); - CImg::vector((ulongT)mp_complex_mul,pos,arg1,arg2).move_to(code); - _cimg_mp_return(pos); - } else { // Matrix multiplication - p1 = _cimg_mp_vector_size(arg1); - p2 = _cimg_mp_vector_size(arg2); - arg4 = p1/p2; - if (arg4*p2!=p1) { - *se = saved_char; cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: %s: Types of left-hand and right-hand operands " - "('%s' and '%s') do not match, in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op, - s_type(arg1)._data,s_type(arg2)._data, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - pos = vector(arg4); - CImg::vector((ulongT)mp_matrix_mul,pos,arg1,arg2,arg4,p2,1).move_to(code); - _cimg_mp_return(pos); - } - } - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) _cimg_mp_vector2_vs(mp_mul,arg1,arg2); - if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_sv(mp_mul,arg1,arg2); - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) _cimg_mp_constant(mem[arg1]*mem[arg2]); - _cimg_mp_scalar2(mp_mul,arg1,arg2); - } - - for (s = se3, ns = se2; s>ss; --s, --ns) - if (*s=='/' && *ns=='/' && level[s - expr._data]==clevel) { // Complex division ('//') - _cimg_mp_op("Operator '//'"); - arg1 = compile(ss,s,depth1,0); - arg2 = compile(s + 2,se,depth1,0); - _cimg_mp_check_type(arg1,1,3,2); - _cimg_mp_check_type(arg2,2,3,2); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) { - pos = vector(2); - CImg::vector((ulongT)mp_complex_div_vv,pos,arg1,arg2).move_to(code); - _cimg_mp_return(pos); - } - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) _cimg_mp_vector2_vs(mp_div,arg1,arg2); - if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) { - pos = vector(2); - CImg::vector((ulongT)mp_complex_div_sv,pos,arg1,arg2).move_to(code); - _cimg_mp_return(pos); - } - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) _cimg_mp_constant(mem[arg1]/mem[arg2]); - _cimg_mp_scalar2(mp_div,arg1,arg2); - } - - for (s = se2; s>ss; --s) if (*s=='*' && level[s - expr._data]==clevel) { // Multiplication ('*') - _cimg_mp_op("Operator '*'"); - arg1 = compile(ss,s,depth1,0); - arg2 = compile(s + 1,se,depth1,0); - _cimg_mp_check_type(arg2,2,3,_cimg_mp_vector_size(arg1)); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_mul,arg1,arg2); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) _cimg_mp_vector2_vs(mp_mul,arg1,arg2); - if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_sv(mp_mul,arg1,arg2); - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) _cimg_mp_constant(mem[arg1]*mem[arg2]); - _cimg_mp_scalar2(mp_mul,arg1,arg2); - } - - - for (s = se2; s>ss; --s) if (*s=='/' && level[s - expr._data]==clevel) { // Division ('/') - _cimg_mp_op("Operator '/'"); - arg1 = compile(ss,s,depth1,0); - arg2 = compile(s + 1,se,depth1,0); - _cimg_mp_check_type(arg2,2,3,_cimg_mp_vector_size(arg1)); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_div,arg1,arg2); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) _cimg_mp_vector2_vs(mp_div,arg1,arg2); - if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_sv(mp_div,arg1,arg2); - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) _cimg_mp_constant(mem[arg1]/mem[arg2]); - _cimg_mp_scalar2(mp_div,arg1,arg2); - } - - for (s = se2, ns = se1; s>ss; --s, --ns) - if (*s=='%' && *ns!='^' && level[s - expr._data]==clevel) { // Modulo ('%') - _cimg_mp_op("Operator '%'"); - arg1 = compile(ss,s,depth1,0); - arg2 = compile(s + 1,se,depth1,0); - _cimg_mp_check_type(arg2,2,3,_cimg_mp_vector_size(arg1)); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_modulo,arg1,arg2); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) _cimg_mp_vector2_vs(mp_modulo,arg1,arg2); - if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_sv(mp_modulo,arg1,arg2); - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) - _cimg_mp_constant(cimg::mod(mem[arg1],mem[arg2])); - _cimg_mp_scalar2(mp_modulo,arg1,arg2); - } - - if (se1>ss) { - if (*ss=='+' && (*ss1!='+' || (ss2='0' && *ss2<='9'))) { // Unary plus ('+') - _cimg_mp_op("Operator '+'"); - _cimg_mp_return(compile(ss1,se,depth1,0)); - } - - if (*ss=='-' && (*ss1!='-' || (ss2='0' && *ss2<='9'))) { // Unary minus ('-') - _cimg_mp_op("Operator '-'"); - arg1 = compile(ss1,se,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_minus,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_constant(-mem[arg1]); - _cimg_mp_scalar1(mp_minus,arg1); - } - - if (*ss=='!') { // Logical not ('!') - _cimg_mp_op("Operator '!'"); - arg1 = compile(ss1,se,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_logical_not,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_constant(!mem[arg1]); - _cimg_mp_scalar1(mp_logical_not,arg1); - } - - if (*ss=='~') { // Bitwise not ('~') - _cimg_mp_op("Operator '~'"); - arg1 = compile(ss1,se,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_bitwise_not,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_constant(~(ulongT)mem[arg1]); - _cimg_mp_scalar1(mp_bitwise_not,arg1); - } - } - - for (s = se3, ns = se2; s>ss; --s, --ns) - if (*s=='^' && *ns=='^' && level[s - expr._data]==clevel) { // Complex power ('^^') - _cimg_mp_op("Operator '^^'"); - arg1 = compile(ss,s,depth1,0); - arg2 = compile(s + 2,se,depth1,0); - _cimg_mp_check_type(arg1,1,3,2); - _cimg_mp_check_type(arg2,2,3,2); - pos = (_cimg_mp_is_vector(arg1) || _cimg_mp_is_vector(arg2))?vector(2):0; - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) { - CImg::vector((ulongT)mp_complex_pow_vv,pos,arg1,arg2).move_to(code); - _cimg_mp_return(pos); - } - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) { - CImg::vector((ulongT)mp_complex_pow_vs,pos,arg1,arg2).move_to(code); - _cimg_mp_return(pos); - } - if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) { - CImg::vector((ulongT)mp_complex_pow_sv,pos,arg1,arg2).move_to(code); - _cimg_mp_return(pos); - } - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) - _cimg_mp_constant(std::pow(mem[arg1],mem[arg2])); - switch (arg2) { - case 0 : _cimg_mp_return(1); - case 1 : _cimg_mp_return(arg1); - case 2 : _cimg_mp_scalar1(mp_sqr,arg1); - case 3 : _cimg_mp_scalar1(mp_pow3,arg1); - case 4 : _cimg_mp_scalar1(mp_pow4,arg1); - default : _cimg_mp_scalar2(mp_pow,arg1,arg2); - } - } - - for (s = se2; s>ss; --s) - if (*s=='^' && level[s - expr._data]==clevel) { // Power ('^') - _cimg_mp_op("Operator '^'"); - arg1 = compile(ss,s,depth1,0); - arg2 = compile(s + 1,se,depth1,0); - _cimg_mp_check_type(arg2,2,3,_cimg_mp_vector_size(arg1)); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_pow,arg1,arg2); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) _cimg_mp_vector2_vs(mp_pow,arg1,arg2); - if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_sv(mp_pow,arg1,arg2); - if (_cimg_mp_is_constant(arg1) && _cimg_mp_is_constant(arg2)) - _cimg_mp_constant(std::pow(mem[arg1],mem[arg2])); - switch (arg2) { - case 0 : _cimg_mp_return(1); - case 1 : _cimg_mp_return(arg1); - case 2 : _cimg_mp_scalar1(mp_sqr,arg1); - case 3 : _cimg_mp_scalar1(mp_pow3,arg1); - case 4 : _cimg_mp_scalar1(mp_pow4,arg1); - default : _cimg_mp_scalar2(mp_pow,arg1,arg2); - } - } - - is_sth = ss1ss && (*se1=='+' || *se1=='-') && *se2==*se1)) { // Pre/post-decrement and increment - if ((is_sth && *ss=='+') || (!is_sth && *se1=='+')) { - _cimg_mp_op("Operator '++'"); - op = mp_self_increment; - } else { - _cimg_mp_op("Operator '--'"); - op = mp_self_decrement; - } - ref.assign(7); - arg1 = is_sth?compile(ss2,se,depth1,ref):compile(ss,se2,depth1,ref); // Variable slot - - if (*ref>0 && !_cimg_mp_is_temp(arg1)) { // Apply operator on a copy if necessary. - if (_cimg_mp_is_vector(arg1)) arg1 = vector_copy(arg1); - else arg1 = scalar1(mp_copy,arg1); - } - - if (is_sth) pos = arg1; // Determine return indice, depending on pre/post action - else { - if (_cimg_mp_is_vector(arg1)) pos = vector_copy(arg1); - else pos = scalar1(mp_copy,arg1); - } - - if (*ref==1) { // Vector value (scalar): V[k]++ - arg3 = ref[1]; // Vector slot - arg4 = ref[2]; // Index - if (p_ref) std::memcpy(p_ref,ref,ref._width*sizeof(unsigned int)); - CImg::vector((ulongT)op,arg1,1).move_to(code); - CImg::vector((ulongT)mp_vector_set_off,arg1,arg3,(ulongT)_cimg_mp_vector_size(arg3),arg4,arg1). - move_to(code); - _cimg_mp_return(pos); - } - - if (*ref==2) { // Image value (scalar): i/j[_#ind,off]++ - is_parallelizable = false; - p1 = ref[1]; // Index - is_relative = (bool)ref[2]; - arg3 = ref[3]; // Offset - if (p_ref) std::memcpy(p_ref,ref,ref._width*sizeof(unsigned int)); - CImg::vector((ulongT)op,arg1).move_to(code); - if (p1!=~0U) { - if (!listout) _cimg_mp_return(pos); - CImg::vector((ulongT)(is_relative?mp_list_set_joff:mp_list_set_ioff), - arg1,p1,arg3).move_to(code); - } else { - if (!imgout) _cimg_mp_return(pos); - CImg::vector((ulongT)(is_relative?mp_set_joff:mp_set_ioff), - arg1,arg3).move_to(code); - } - _cimg_mp_return(pos); - } - - if (*ref==3) { // Image value (scalar): i/j(_#ind,_x,_y,_z,_c)++ - is_parallelizable = false; - p1 = ref[1]; // Index - is_relative = (bool)ref[2]; - arg3 = ref[3]; // X - arg4 = ref[4]; // Y - arg5 = ref[5]; // Z - arg6 = ref[6]; // C - if (p_ref) std::memcpy(p_ref,ref,ref._width*sizeof(unsigned int)); - CImg::vector((ulongT)op,arg1).move_to(code); - if (p1!=~0U) { - if (!listout) _cimg_mp_return(pos); - CImg::vector((ulongT)(is_relative?mp_list_set_jxyzc:mp_list_set_ixyzc), - arg1,p1,arg3,arg4,arg5,arg6).move_to(code); - } else { - if (!imgout) _cimg_mp_return(pos); - CImg::vector((ulongT)(is_relative?mp_set_jxyzc:mp_set_ixyzc), - arg1,arg3,arg4,arg5,arg6).move_to(code); - } - _cimg_mp_return(pos); - } - - if (*ref==4) { // Image value (vector): I/J[_#ind,off]++ - is_parallelizable = false; - p1 = ref[1]; // Index - is_relative = (bool)ref[2]; - arg3 = ref[3]; // Offset - if (p_ref) std::memcpy(p_ref,ref,ref._width*sizeof(unsigned int)); - self_vector_s(arg1,op==mp_self_increment?mp_self_add:mp_self_sub,1); - if (p1!=~0U) { - if (!listout) _cimg_mp_return(pos); - CImg::vector((ulongT)(is_relative?mp_list_set_Joff_v:mp_list_set_Ioff_v), - arg1,p1,arg3).move_to(code); - } else { - if (!imgout) _cimg_mp_return(pos); - CImg::vector((ulongT)(is_relative?mp_set_Joff_v:mp_set_Ioff_v), - arg1,arg3).move_to(code); - } - _cimg_mp_return(pos); - } - - if (*ref==5) { // Image value (vector): I/J(_#ind,_x,_y,_z,_c)++ - is_parallelizable = false; - p1 = ref[1]; // Index - is_relative = (bool)ref[2]; - arg3 = ref[3]; // X - arg4 = ref[4]; // Y - arg5 = ref[5]; // Z - if (p_ref) std::memcpy(p_ref,ref,ref._width*sizeof(unsigned int)); - self_vector_s(arg1,op==mp_self_increment?mp_self_add:mp_self_sub,1); - if (p1!=~0U) { - if (!listout) _cimg_mp_return(pos); - CImg::vector((ulongT)(is_relative?mp_list_set_Jxyz_v:mp_list_set_Ixyz_v), - arg1,p1,arg3,arg4,arg5).move_to(code); - } else { - if (!imgout) _cimg_mp_return(pos); - CImg::vector((ulongT)(is_relative?mp_set_Jxyz_v:mp_set_Ixyz_v), - arg1,arg3,arg4,arg5).move_to(code); - } - _cimg_mp_return(pos); - } - - if (_cimg_mp_is_vector(arg1)) { // Vector variable: V++ - self_vector_s(arg1,op==mp_self_increment?mp_self_add:mp_self_sub,1); - _cimg_mp_return(pos); - } - - if _cimg_mp_is_variable(arg1) { // Scalar variable: s++ - CImg::vector((ulongT)op,arg1).move_to(code); - _cimg_mp_return(pos); - } - - if (is_sth) variable_name.assign(ss2,(unsigned int)(se - ss1)); - else variable_name.assign(ss,(unsigned int)(se1 - ss)); - variable_name.back() = 0; - *se = saved_char; cimg::strellipsize(variable_name,64); cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: %s: Invalid operand '%s', " - "in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op, - variable_name._data, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - - // Array-like access to vectors and image values 'i/j/I/J[_#ind,offset,_boundary]' and 'vector[offset]'. - if (*se1==']' && *ss!='[') { - _cimg_mp_op("Value accessor '[]'"); - is_relative = *ss=='j' || *ss=='J'; - - if ((*ss=='I' || *ss=='J') && *ss1=='[' && - (reserved_label[*ss]==~0U || !_cimg_mp_is_vector(reserved_label[*ss]))) { // Image value as a vector - if (*ss2=='#') { // Index specified - s0 = ss3; while (s0::vector((ulongT)(is_relative?mp_list_Joff:mp_list_Ioff), - pos,p1,arg1,arg2==~0U?reserved_label[30]:arg2).move_to(code); - } else { - need_input_copy = true; - CImg::vector((ulongT)(is_relative?mp_Joff:mp_Ioff), - pos,arg1,arg2==~0U?reserved_label[30]:arg2).move_to(code); - } - _cimg_mp_return(pos); - } - - if ((*ss=='i' || *ss=='j') && *ss1=='[' && - (reserved_label[*ss]==~0U || !_cimg_mp_is_vector(reserved_label[*ss]))) { // Image value as a scalar - if (*ss2=='#') { // Index specified - s0 = ss3; while (s0ss && *s0!='[') --s0; - if (s0>ss) { // Vector value - arg1 = compile(ss,s0,depth1,0); - s1 = s0 + 1; while (s1 sub-vector extraction - arg2 = compile(++s0,s1,depth1,0); - arg3 = compile(++s1,se1,depth1,0); - _cimg_mp_check_constant(arg2,1,1); - _cimg_mp_check_constant(arg3,2,1); - p1 = (unsigned int)mem[arg2]; - p2 = (unsigned int)mem[arg3]; - p3 = _cimg_mp_vector_size(arg1); - if (p1>=p3 || p2>=p3) { - variable_name.assign(ss,(unsigned int)(s0 - ss)).back() = 0; - *se = saved_char; cimg::strellipsize(variable_name,64); cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: %s: Out-of-bounds request for sub-vector '%s[%d,%d]' " - "(vector '%s' has dimension %u), " - "in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op, - variable_name._data,(int)mem[arg2],(int)mem[arg3], - variable_name._data,p3, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - if (p1>p2) cimg::swap(p1,p2); - (p2-=p1)++; - pos = vector(p2); - CImg::vector((ulongT)mp_vector_crop,pos,arg1,p1,p2).move_to(code); - _cimg_mp_return(pos); - } - - // One argument -> vector value reference - if (_cimg_mp_is_scalar(arg1)) { - variable_name.assign(ss,(unsigned int)(s0 - ss)).back() = 0; - *se = saved_char; cimg::strellipsize(variable_name,64); cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: %s: Array brackets used on non-vector variable '%s', " - "in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op, - variable_name._data, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - - arg2 = compile(++s0,se1,depth1,0); - if _cimg_mp_is_constant(arg2) { // Constant index - nb = (int)mem[arg2]; - if (nb>=0 && nb<(int)_cimg_mp_vector_size(arg1)) _cimg_mp_return(arg1 + 1 + nb); - variable_name.assign(ss,(unsigned int)(s0 - ss)).back() = 0; - *se = saved_char; cimg::strellipsize(variable_name,64); cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: Out-of-bounds reference '%s[%d]' " - "(vector '%s' has dimension %u), " - "in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function, - variable_name._data,nb, - variable_name._data,_cimg_mp_vector_size(arg1), - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - if (p_ref) { - *p_ref = 1; - p_ref[1] = arg1; - p_ref[2] = arg2; - if (_cimg_mp_is_temp(arg2)) memtype[arg2] = -1; // Prevent from being used in further optimization - } - pos = scalar3(mp_vector_off,arg1,_cimg_mp_vector_size(arg1),arg2); - memtype[pos] = -1; // Create it as a variable to prevent from being used in further optimization - _cimg_mp_return(pos); - } - } - - // Look for a function call, an access to image value, or a parenthesis. - if (*se1==')') { - if (*ss=='(') _cimg_mp_return(compile(ss1,se1,depth1,p_ref)); // Simple parentheses - is_relative = *ss=='j' || *ss=='J'; - _cimg_mp_op("Value accessor '()'"); - - // I/J(_#ind,_x,_y,_z,_interpolation,_boundary) - if ((*ss=='I' || *ss=='J') && *ss1=='(') { // Image value as scalar - if (*ss2=='#') { // Index specified - s0 = ss3; while (s01) { - arg2 = arg1 + 1; - if (p2>2) arg3 = arg2 + 1; - } - if (s1::vector((ulongT)(is_relative?mp_list_Jxyz:mp_list_Ixyz), - pos,p1,arg1,arg2,arg3, - arg4==~0U?reserved_label[29]:arg4, - arg5==~0U?reserved_label[30]:arg5).move_to(code); - else { - need_input_copy = true; - CImg::vector((ulongT)(is_relative?mp_Jxyz:mp_Ixyz), - pos,arg1,arg2,arg3, - arg4==~0U?reserved_label[29]:arg4, - arg5==~0U?reserved_label[30]:arg5).move_to(code); - } - _cimg_mp_return(pos); - } - - // i/j(_#ind,_x,_y,_z,_c,_interpolation,_boundary) - if ((*ss=='i' || *ss=='j') && *ss1=='(') { // Image value as scalar - if (*ss2=='#') { // Index specified - s0 = ss3; while (s01) { - arg2 = arg1 + 1; - if (p2>2) { - arg3 = arg2 + 1; - if (p2>3) arg4 = arg3 + 1; - } - } - if (s1::vector((ulongT)mp_complex_conj,pos,arg1).move_to(code); - _cimg_mp_return(pos); - } - - if (!std::strncmp(ss,"cexp(",5)) { // Complex exponential - _cimg_mp_op("Function 'cexp()'"); - arg1 = compile(ss5,se1,depth1,0); - _cimg_mp_check_type(arg1,0,2,2); - pos = vector(2); - CImg::vector((ulongT)mp_complex_exp,pos,arg1).move_to(code); - _cimg_mp_return(pos); - } - - if (!std::strncmp(ss,"clog(",5)) { // Complex logarithm - _cimg_mp_op("Function 'clog()'"); - arg1 = compile(ss5,se1,depth1,0); - _cimg_mp_check_type(arg1,0,2,2); - pos = vector(2); - CImg::vector((ulongT)mp_complex_log,pos,arg1).move_to(code); - _cimg_mp_return(pos); - } - - if (!std::strncmp(ss,"copy(",5)) { // Memory copy - _cimg_mp_op("Function 'copy()'"); - ref.assign(14); - s1 = ss5; while (s1(1,21).move_to(code); - code.back().get_shared_rows(0,6).fill((ulongT)mp_memcopy,p1,arg1,arg2,arg3,arg4,arg5); - code.back().get_shared_rows(7,20).fill(ref); - _cimg_mp_return(p1); - } - - if (!std::strncmp(ss,"cos(",4)) { // Cosine - _cimg_mp_op("Function 'cos()'"); - arg1 = compile(ss4,se1,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_cos,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_constant(std::cos(mem[arg1])); - _cimg_mp_scalar1(mp_cos,arg1); - } - - if (!std::strncmp(ss,"cosh(",5)) { // Hyperbolic cosine - _cimg_mp_op("Function 'cosh()'"); - arg1 = compile(ss5,se1,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_cosh,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_constant(std::cosh(mem[arg1])); - _cimg_mp_scalar1(mp_cosh,arg1); - } - - if (!std::strncmp(ss,"crop(",5)) { // Image crop - _cimg_mp_op("Function 'crop()'"); - if (*ss5=='#') { // Index specified - s0 = ss6; while (s0::sequence(_cimg_mp_vector_size(arg1),arg1 + 1, - arg1 + (ulongT)_cimg_mp_vector_size(arg1)); - opcode.resize(1,cimg::min(opcode._height,4U),1,1,0).move_to(_opcode); - is_sth = true; - } else { - _cimg_mp_check_type(arg1,pos + 1,1,0); - CImg::vector(arg1).move_to(_opcode); - } - s = ns; - } - (_opcode>'y').move_to(opcode); - - arg1 = 0; arg2 = (p1!=~0U); - switch (opcode._height) { - case 0 : case 1 : - CImg::vector(0,0,0,0,~0U,~0U,~0U,~0U,0).move_to(opcode); - break; - case 2 : - CImg::vector(*opcode,0,0,0,opcode[1],~0U,~0U,~0U,reserved_label[30]).move_to(opcode); - arg1 = arg2?3:2; - break; - case 3 : - CImg::vector(*opcode,0,0,0,opcode[1],~0U,~0U,~0U,opcode[2]).move_to(opcode); - arg1 = arg2?3:2; - break; - case 4 : - CImg::vector(*opcode,opcode[1],0,0,opcode[2],opcode[3],~0U,~0U,reserved_label[30]). - move_to(opcode); - arg1 = (is_sth?2:1) + arg2; - break; - case 5 : - CImg::vector(*opcode,opcode[1],0,0,opcode[2],opcode[3],~0U,~0U,opcode[4]). - move_to(opcode); - arg1 = (is_sth?2:1) + arg2; - break; - case 6 : - CImg::vector(*opcode,opcode[1],opcode[2],0,opcode[3],opcode[4],opcode[5],~0U, - reserved_label[30]).move_to(opcode); - arg1 = (is_sth?2:4) + arg2; - break; - case 7 : - CImg::vector(*opcode,opcode[1],opcode[2],0,opcode[3],opcode[4],opcode[5],~0U, - opcode[6]).move_to(opcode); - arg1 = (is_sth?2:4) + arg2; - break; - case 8 : - CImg::vector(*opcode,opcode[1],opcode[2],opcode[3],opcode[4],opcode[5],opcode[6], - opcode[7],reserved_label[30]).move_to(opcode); - arg1 = (is_sth?2:5) + arg2; - break; - case 9 : - arg1 = (is_sth?2:5) + arg2; - break; - default : // Error -> too much arguments - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: %s: Too much arguments specified, " - "in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - - _cimg_mp_check_type((unsigned int)*opcode,arg2 + 1,1,0); - _cimg_mp_check_type((unsigned int)opcode[1],arg2 + 1 + (is_sth?0:1),1,0); - _cimg_mp_check_type((unsigned int)opcode[2],arg2 + 1 + (is_sth?0:2),1,0); - _cimg_mp_check_type((unsigned int)opcode[3],arg2 + 1 + (is_sth?0:3),1,0); - if (opcode[4]!=(ulongT)~0U) { - _cimg_mp_check_constant((unsigned int)opcode[4],arg1,2); - opcode[4] = (ulongT)mem[opcode[4]]; - } - if (opcode[5]!=(ulongT)~0U) { - _cimg_mp_check_constant((unsigned int)opcode[5],arg1 + 1,2); - opcode[5] = (ulongT)mem[opcode[5]]; - } - if (opcode[6]!=(ulongT)~0U) { - _cimg_mp_check_constant((unsigned int)opcode[6],arg1 + 2,2); - opcode[6] = (ulongT)mem[opcode[6]]; - } - if (opcode[7]!=(ulongT)~0U) { - _cimg_mp_check_constant((unsigned int)opcode[7],arg1 + 3,2); - opcode[7] = (ulongT)mem[opcode[7]]; - } - _cimg_mp_check_type((unsigned int)opcode[8],arg1 + 4,1,0); - - if (opcode[4]==(ulongT)~0U || opcode[5]==(ulongT)~0U || - opcode[6]==(ulongT)~0U || opcode[7]==(ulongT)~0U) { - if (p1!=~0U) { - _cimg_mp_check_constant(p1,1,0); - p1 = (unsigned int)cimg::mod((int)mem[p1],listin.width()); - } - const CImg &img = p1!=~0U?listin[p1]:imgin; - if (!img) - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: %s: Cannot crop empty image when " - "some xyzc-coordinates are unspecified, in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - if (opcode[4]==(ulongT)~0U) opcode[4] = (ulongT)img._width; - if (opcode[5]==(ulongT)~0U) opcode[5] = (ulongT)img._height; - if (opcode[6]==(ulongT)~0U) opcode[6] = (ulongT)img._depth; - if (opcode[7]==(ulongT)~0U) opcode[7] = (ulongT)img._spectrum; - } - - pos = vector((unsigned int)(opcode[4]*opcode[5]*opcode[6]*opcode[7])); - CImg::vector((ulongT)mp_crop, - pos,p1, - *opcode,opcode[1],opcode[2],opcode[3], - opcode[4],opcode[5],opcode[6],opcode[7], - opcode[8]).move_to(code); - _cimg_mp_return(pos); - } - - if (!std::strncmp(ss,"cross(",6)) { // Cross product - _cimg_mp_op("Function 'cross()'"); - s1 = ss6; while (s1::vector((ulongT)mp_cross,pos,arg1,arg2).move_to(code); - _cimg_mp_return(pos); - } - - if (!std::strncmp(ss,"cut(",4)) { // Cut - _cimg_mp_op("Function 'cut()'"); - s1 = ss4; while (s1val2?val2:val); - } - _cimg_mp_scalar3(mp_cut,arg1,arg2,arg3); - } - break; - - case 'd' : - if (!std::strncmp(ss,"date(",5)) { // Date and file date - _cimg_mp_op("Function 'date()'"); - s1 = ss5; while (s1::vector((ulongT)mp_debug,arg1,code._width - p1), - CImg::string(ss6).unroll('y'))>'y').move_to(code,p1); - *se1 = ')'; - _cimg_mp_return(arg1); - } - - if (!std::strncmp(ss,"debugm(",7)) { // View memory (for debug) - _cimg_mp_scalar0(mp_debug_memory); - } - - if (!std::strncmp(ss,"det(",4)) { // Matrix determinant - _cimg_mp_op("Function 'det()'"); - arg1 = compile(ss4,se1,depth1,0); - _cimg_mp_check_matrix_square(arg1,1); - p1 = (unsigned int)std::sqrt((float)_cimg_mp_vector_size(arg1)); - _cimg_mp_scalar2(mp_det,arg1,p1); - } - - if (!std::strncmp(ss,"diag(",5)) { // Diagonal matrix - _cimg_mp_op("Function 'diag()'"); - arg1 = compile(ss5,se1,depth1,0); - _cimg_mp_check_type(arg1,1,2,0); - p1 = _cimg_mp_vector_size(arg1); - pos = vector(p1*p1); - CImg::vector((ulongT)mp_diag,pos,arg1,p1).move_to(code); - _cimg_mp_return(pos); - } - - if (!std::strncmp(ss,"dot(",4)) { // Dot product - _cimg_mp_op("Function 'dot()'"); - s1 = ss4; while (s1::vector((ulongT)mp_dowhile,arg1,arg2,code._width - p1).move_to(code,p1); - _cimg_mp_return(arg1); - } - - if (!std::strncmp(ss,"draw(",5)) { // Draw image - _cimg_mp_op("Function 'draw()'"); - is_parallelizable = false; - if (*ss5=='#') { // Index specified - s0 = ss6; while (s01) { - arg3 = arg2 + 1; - if (p2>2) { - arg4 = arg3 + 1; - if (p2>3) arg5 = arg4 + 1; - } - } - ++s0; - is_sth = true; - } else { - if (s0::vector((ulongT)mp_draw,arg1,p1,arg2,arg3,arg4,arg5,0,0,0,0,1,(ulongT)-1,0,1). - move_to(opcode); - - arg2 = arg3 = arg4 = arg5 = ~0U; - p2 = p1!=~0U?0:1; - if (s0 &img = p1!=~0U?listout[p1]:imgout; - if (arg2==~0U) arg2 = img._width; - if (arg3==~0U) arg3 = img._height; - if (arg4==~0U) arg4 = img._depth; - if (arg5==~0U) arg5 = img._spectrum; - } - if (arg2*arg3*arg4*arg5!=_cimg_mp_vector_size(arg1)) { - *se = saved_char; cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: %s: Type of %s argument ('%s') and specified size " - "(%u,%u,%u,%u) do not match, in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op, - p1==~0U?"first":"second",s_type(arg1)._data, - arg2,arg3,arg4,arg5, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - opcode[7] = (ulongT)arg2; - opcode[8] = (ulongT)arg3; - opcode[9] = (ulongT)arg4; - opcode[10] = (ulongT)arg5; - - if (s0::%s: %s: Type of opacity mask ('%s') and specified size " - "(%u,%u,%u,%u) do not match, in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op, - s_type(p2)._data, - arg2,arg3,arg4,arg5, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - opcode[12] = p2; - opcode[13] = _cimg_mp_vector_size(p2)/(arg2*arg3*arg4); - p3 = s0::vector((ulongT)mp_eig,pos,arg1,p1).move_to(code); - _cimg_mp_return(pos); - } - - if (!std::strncmp(ss,"exp(",4)) { // Exponential - _cimg_mp_op("Function 'exp()'"); - arg1 = compile(ss4,se1,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_exp,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_constant(std::exp(mem[arg1])); - _cimg_mp_scalar1(mp_exp,arg1); - } - - if (!std::strncmp(ss,"eye(",4)) { // Identity matrix - _cimg_mp_op("Function 'eye()'"); - arg1 = compile(ss4,se1,depth1,0); - _cimg_mp_check_constant(arg1,1,2); - p1 = (unsigned int)mem[arg1]; - pos = vector(p1*p1); - CImg::vector((ulongT)mp_eye,pos,p1).move_to(code); - _cimg_mp_return(pos); - } - break; - - case 'f' : - if (!std::strncmp(ss,"fact(",5)) { // Factorial - _cimg_mp_op("Function 'fact()'"); - arg1 = compile(ss5,se1,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_factorial,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_constant(cimg::factorial(mem[arg1])); - _cimg_mp_scalar1(mp_factorial,arg1); - } - - if (!std::strncmp(ss,"fibo(",5)) { // Fibonacci - _cimg_mp_op("Function 'fibo()'"); - arg1 = compile(ss5,se1,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_fibonacci,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_constant(cimg::fibonacci(mem[arg1])); - _cimg_mp_scalar1(mp_fibonacci,arg1); - } - - if (!std::strncmp(ss,"find(",5)) { // Find - _cimg_mp_op("Function 'find()'"); - - // First argument: data to look at. - s0 = ss5; while (s0::vector((ulongT)mp_whiledo,pos,arg1,p2 - p1,code._width - p2,arg2,pos>=p3).move_to(code,p1); - _cimg_mp_return(pos); - } - break; - - case 'g' : - if (!std::strncmp(ss,"gauss(",6)) { // Gaussian function - _cimg_mp_op("Function 'gauss()'"); - s1 = ss6; while (s10) { val/=val1; _cimg_mp_constant(val1*std::sqrt(1+val*val)); } - _cimg_mp_constant(0); - } - _cimg_mp_scalar2(mp_hypot,arg1,arg2); - } - break; - - case 'i' : - if (*ss1=='f' && (*ss2=='(' || (*ss2 && *ss2<=' ' && *ss3=='('))) { // If..then[..else.] - _cimg_mp_op("Function 'if()'"); - if (*ss2<=' ') cimg::swap(*ss2,*ss3); // Allow space before opening brace - s1 = ss3; while (s1::vector((ulongT)mp_if,pos,arg1,arg2,arg3, - p3 - p2,code._width - p3,arg4).move_to(code,p2); - _cimg_mp_return(pos); - } - - if (!std::strncmp(ss,"init(",5)) { // Init - _cimg_mp_op("Function 'init()'"); - if (ss0!=expr._data || code.width()) { // (only allowed as the first instruction) - *se = saved_char; cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: %s: Init invokation not done at the " - "beginning of expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - arg1 = compile(ss5,se1,depth1,p_ref); - init_size = code.width(); - _cimg_mp_return(arg1); - } - - if (!std::strncmp(ss,"int(",4)) { // Integer cast - _cimg_mp_op("Function 'int()'"); - arg1 = compile(ss4,se1,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_int,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_constant((longT)mem[arg1]); - _cimg_mp_scalar1(mp_int,arg1); - } - - if (!std::strncmp(ss,"inv(",4)) { // Matrix/scalar inversion - _cimg_mp_op("Function 'inv()'"); - arg1 = compile(ss4,se1,depth1,0); - _cimg_mp_check_matrix_square(arg1,1); - p1 = (unsigned int)std::sqrt((float)_cimg_mp_vector_size(arg1)); - pos = vector(p1*p1); - CImg::vector((ulongT)mp_inv,pos,arg1,p1).move_to(code); - _cimg_mp_return(pos); - } - - if (*ss1=='s') { // Family of 'is_?()' functions - - if (!std::strncmp(ss,"isbool(",7)) { // Is boolean? - _cimg_mp_op("Function 'isbool()'"); - if (ss7==se1) _cimg_mp_return(0); - arg1 = compile(ss7,se1,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_isbool,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_return(mem[arg1]==0.0 || mem[arg1]==1.0); - _cimg_mp_scalar1(mp_isbool,arg1); - } - - if (!std::strncmp(ss,"isdir(",6)) { // Is directory? - _cimg_mp_op("Function 'isdir()'"); - *se1 = 0; - is_sth = cimg::is_directory(ss6); - *se1 = ')'; - _cimg_mp_return(is_sth?1U:0U); - } - - if (!std::strncmp(ss,"isfile(",7)) { // Is file? - _cimg_mp_op("Function 'isfile()'"); - *se1 = 0; - is_sth = cimg::is_file(ss7); - *se1 = ')'; - _cimg_mp_return(is_sth?1U:0U); - } - - if (!std::strncmp(ss,"isin(",5)) { // Is in sequence/vector? - if (ss5>=se1) _cimg_mp_return(0); - _cimg_mp_op("Function 'isin()'"); - pos = scalar(); - CImg::vector((ulongT)mp_isin,pos).move_to(_opcode); - for (s = ss5; s::sequence(_cimg_mp_vector_size(arg1),arg1 + 1, - arg1 + (ulongT)_cimg_mp_vector_size(arg1)). - move_to(_opcode); - else CImg::vector(arg1).move_to(_opcode); - s = ns; - } - (_opcode>'y').move_to(code); - _cimg_mp_return(pos); - } - - if (!std::strncmp(ss,"isinf(",6)) { // Is infinite? - _cimg_mp_op("Function 'isinf()'"); - if (ss6==se1) _cimg_mp_return(0); - arg1 = compile(ss6,se1,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_isinf,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_return((unsigned int)cimg::type::is_inf(mem[arg1])); - _cimg_mp_scalar1(mp_isinf,arg1); - } - - if (!std::strncmp(ss,"isint(",6)) { // Is integer? - _cimg_mp_op("Function 'isint()'"); - if (ss6==se1) _cimg_mp_return(0); - arg1 = compile(ss6,se1,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_isint,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_return((unsigned int)(cimg::mod(mem[arg1],1.0)==0)); - _cimg_mp_scalar1(mp_isint,arg1); - } - - if (!std::strncmp(ss,"isnan(",6)) { // Is NaN? - _cimg_mp_op("Function 'isnan()'"); - if (ss6==se1) _cimg_mp_return(0); - arg1 = compile(ss6,se1,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_isnan,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_return((unsigned int)cimg::type::is_nan(mem[arg1])); - _cimg_mp_scalar1(mp_isnan,arg1); - } - - if (!std::strncmp(ss,"isval(",6)) { // Is value? - _cimg_mp_op("Function 'isval()'"); - val = 0; - if (cimg_sscanf(ss6,"%lf%c%c",&val,&sep,&end)==2 && sep==')') _cimg_mp_return(1); - _cimg_mp_return(0); - } - - } - break; - - case 'l' : - if (!std::strncmp(ss,"log(",4)) { // Natural logarithm - _cimg_mp_op("Function 'log()'"); - arg1 = compile(ss4,se1,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_log,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_constant(std::log(mem[arg1])); - _cimg_mp_scalar1(mp_log,arg1); - } - - if (!std::strncmp(ss,"log2(",5)) { // Base-2 logarithm - _cimg_mp_op("Function 'log2()'"); - arg1 = compile(ss5,se1,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_log2,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_constant(cimg::log2(mem[arg1])); - _cimg_mp_scalar1(mp_log2,arg1); - } - - if (!std::strncmp(ss,"log10(",6)) { // Base-10 logarithm - _cimg_mp_op("Function 'log10()'"); - arg1 = compile(ss6,se1,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_log10,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_constant(std::log10(mem[arg1])); - _cimg_mp_scalar1(mp_log10,arg1); - } - - if (!std::strncmp(ss,"lowercase(",10)) { // Lower case - _cimg_mp_op("Function 'lowercase()'"); - arg1 = compile(ss + 10,se1,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_lowercase,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_constant(cimg::lowercase(mem[arg1])); - _cimg_mp_scalar1(mp_lowercase,arg1); - } - break; - - case 'm' : - if (!std::strncmp(ss,"mul(",4)) { // Matrix multiplication - _cimg_mp_op("Function 'mul()'"); - s1 = ss4; while (s1::%s: %s: Types of first and second arguments ('%s' and '%s') " - "do not match for third argument 'nb_colsB=%u', " - "in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op, - s_type(arg1)._data,s_type(arg2)._data,p3, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - pos = vector(arg4*p3); - CImg::vector((ulongT)mp_matrix_mul,pos,arg1,arg2,arg4,arg5,p3).move_to(code); - _cimg_mp_return(pos); - } - break; - - case 'n' : - if (!std::strncmp(ss,"narg(",5)) { // Number of arguments - _cimg_mp_op("Function 'narg()'"); - if (ss5>=se1) _cimg_mp_return(0); - arg1 = 0; - for (s = ss5; s::vector((ulongT)mp_norm0,pos).move_to(_opcode); break; - case 1 : CImg::vector((ulongT)mp_norm1,pos).move_to(_opcode); break; - case 2 : CImg::vector((ulongT)mp_norm2,pos).move_to(_opcode); break; - case ~0U : CImg::vector((ulongT)mp_norminf,pos).move_to(_opcode); break; - default : - CImg::vector((ulongT)mp_normp,pos,(ulongT)(arg1==~0U?-1:(int)arg1)). - move_to(_opcode); - } - for (s = std::strchr(ss5,'(') + 1; s::sequence(_cimg_mp_vector_size(arg2),arg2 + 1, - arg2 + (ulongT)_cimg_mp_vector_size(arg2)). - move_to(_opcode); - else CImg::vector(arg2).move_to(_opcode); - s = ns; - } - (_opcode>'y').move_to(code); - _cimg_mp_return(pos); - } - break; - - case 'p' : - if (!std::strncmp(ss,"permut(",7)) { // Number of permutations - _cimg_mp_op("Function 'permut()'"); - s1 = ss7; while (s1::vector((ulongT)mp_vector_print,pos,(ulongT)_cimg_mp_vector_size(pos)), - CImg::string(ss6).unroll('y'))>'y').move_to(code); - else // Scalar - ((CImg::vector((ulongT)mp_print,pos), - CImg::string(ss6).unroll('y'))>'y').move_to(code); - *se1 = ')'; - _cimg_mp_return(pos); - } - break; - - case 'r' : - if (!std::strncmp(ss,"resize(",7)) { // Vector resize - _cimg_mp_op("Function 'resize()'"); - s1 = ss7; while (s1::vector((ulongT)mp_vector_resize,pos,arg2,arg1,_cimg_mp_vector_size(arg1),arg3). - move_to(code); - _cimg_mp_return(pos); - } - - if (!std::strncmp(ss,"reverse(",8)) { // Vector reverse - _cimg_mp_op("Function 'reverse()'"); - arg1 = compile(ss8,se1,depth1,0); - if (!_cimg_mp_is_vector(arg1)) _cimg_mp_return(arg1); - p1 = _cimg_mp_vector_size(arg1); - pos = vector(p1); - CImg::vector((ulongT)mp_vector_reverse,pos,arg1,p1).move_to(code); - _cimg_mp_return(pos); - } - - if (!std::strncmp(ss,"rol(",4) || !std::strncmp(ss,"ror(",4)) { // Bitwise rotation - _cimg_mp_op(ss[2]=='l'?"Function 'rol()'":"Function 'ror()'"); - s1 = ss4; while (s11) { - arg2 = arg1 + 1; - if (p2>2) arg3 = arg2 + 1; - } - arg4 = compile(++s1,se1,depth1,0); - } else { - s2 = s1 + 1; while (s2::vector((ulongT)mp_rot3d,pos,arg1,arg2,arg3,arg4).move_to(code); - } else { // 2d rotation - _cimg_mp_check_type(arg1,1,1,0); - pos = vector(4); - CImg::vector((ulongT)mp_rot2d,pos,arg1).move_to(code); - } - _cimg_mp_return(pos); - } - - if (!std::strncmp(ss,"round(",6)) { // Value rounding - _cimg_mp_op("Function 'round()'"); - s1 = ss6; while (s1::vector((ulongT)mp_single,arg1,code._width - p1).move_to(code,p1); - _cimg_mp_return(arg1); - } - - if (!std::strncmp(ss,"sinh(",5)) { // Hyperbolic sine - _cimg_mp_op("Function 'sinh()'"); - arg1 = compile(ss5,se1,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_sinh,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_constant(std::sinh(mem[arg1])); - _cimg_mp_scalar1(mp_sinh,arg1); - } - - if (!std::strncmp(ss,"size(",5)) { // Vector size. - _cimg_mp_op("Function 'size()'"); - arg1 = compile(ss5,se1,depth1,0); - _cimg_mp_constant(_cimg_mp_is_scalar(arg1)?0:_cimg_mp_vector_size(arg1)); - } - - if (!std::strncmp(ss,"solve(",6)) { // Solve linear system - _cimg_mp_op("Function 'solve()'"); - s1 = ss6; while (s1::%s: %s: Types of first and second arguments ('%s' and '%s') " - "do not match for third argument 'nb_colsB=%u', " - "in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op, - s_type(arg1)._data,s_type(arg2)._data,p3, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - pos = vector(arg4*p3); - CImg::vector((ulongT)mp_solve,pos,arg1,arg2,arg4,arg5,p3).move_to(code); - _cimg_mp_return(pos); - } - - if (!std::strncmp(ss,"sort(",5)) { // Sort vector - _cimg_mp_op("Function 'sort()'"); - s1 = ss6; while (s1::%s: %s: Invalid specified chunk size (%u) for first argument " - "('%s'), in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op, - arg3,s_type(arg1)._data, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - pos = vector(p1); - CImg::vector((ulongT)mp_sort,pos,arg1,p1,arg2,arg3).move_to(code); - _cimg_mp_return(pos); - } - - if (!std::strncmp(ss,"sqr(",4)) { // Square - _cimg_mp_op("Function 'sqr()'"); - arg1 = compile(ss4,se1,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_sqr,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_constant(cimg::sqr(mem[arg1])); - _cimg_mp_scalar1(mp_sqr,arg1); - } - - if (!std::strncmp(ss,"sqrt(",5)) { // Square root - _cimg_mp_op("Function 'sqrt()'"); - arg1 = compile(ss5,se1,depth1,0); - if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_sqrt,arg1); - if _cimg_mp_is_constant(arg1) _cimg_mp_constant(std::sqrt(mem[arg1])); - _cimg_mp_scalar1(mp_sqrt,arg1); - } - - if (!std::strncmp(ss,"stod(",5)) { // String to double - _cimg_mp_op("Function 'stod()'"); - s1 = ss5; while (s1::%s: %s: Size of first argument ('%s') does not match" - "for second specified argument 'nb_cols=%u', " - "in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op, - s_type(arg1)._data,p2, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - pos = vector(p3*p2); - CImg::vector((ulongT)mp_transp,pos,arg1,p2,p3).move_to(code); - _cimg_mp_return(pos); - } - break; - - case 'u' : - if (*ss1=='(') { // Random value with uniform distribution - _cimg_mp_op("Function 'u()'"); - if (*ss2==')') _cimg_mp_scalar2(mp_u,0,1); - s1 = ss2; while (s10) || - !std::strncmp(ss,"vector(",7)) { // Vector - _cimg_mp_op("Function 'vector()'"); - arg2 = 0; // Number of specified values. - s = std::strchr(ss6,'(') + 1; - if (s::sequence(arg4,arg3 + 1,arg3 + arg4).move_to(_opcode); - arg2+=arg4; - } else { CImg::vector(arg3).move_to(_opcode); ++arg2; } - s = ns; - } - if (arg1==~0U) arg1 = arg2; - _cimg_mp_check_vector0(arg1); - pos = vector(arg1); - _opcode.insert(CImg::vector((ulongT)mp_vector_init,pos,arg1),0); - (_opcode>'y').move_to(code); - _cimg_mp_return(pos); - } - break; - - case 'w' : - if (!std::strncmp(ss,"whiledo",7) && (*ss7=='(' || (*ss7 && *ss7<=' ' && *ss8=='('))) { // While...do - _cimg_mp_op("Function 'whiledo()'"); - if (*ss7<=' ') cimg::swap(*ss7,*ss8); // Allow space before opening brace - s1 = ss8; while (s1::vector((ulongT)mp_whiledo,pos,arg1,p2 - p1,code._width - p2,arg2,pos>=p3).move_to(code,p1); - _cimg_mp_return(pos); - } - break; - } - - if (!std::strncmp(ss,"min(",4) || !std::strncmp(ss,"max(",4) || - !std::strncmp(ss,"med(",4) || !std::strncmp(ss,"kth(",4) || - !std::strncmp(ss,"arg(",4) || !std::strncmp(ss,"sum(",4) || - !std::strncmp(ss,"std(",4) || !std::strncmp(ss,"variance(",9) || - !std::strncmp(ss,"prod(",5) || !std::strncmp(ss,"mean(",5) || - !std::strncmp(ss,"argmin(",7) || !std::strncmp(ss,"argmax(",7)) { // Multi-argument functions - _cimg_mp_op(*ss=='a'?(ss[3]=='('?"Function 'arg()'":ss[4]=='i'?"Function 'argmin()'": - "Function 'argmax()'"): - *ss=='s'?(ss[1]=='u'?"Function 'sum()'":"Function 'std()'"): - *ss=='k'?"Function 'kth()'": - *ss=='p'?"Function 'prod()'": - *ss=='v'?"Function 'variance()'": - ss[1]=='i'?"Function 'min()'": - ss[1]=='a'?"Function 'max()'": - ss[2]=='a'?"Function 'mean()'":"Function 'med()'"); - pos = scalar(); - CImg::vector((ulongT)(*ss=='a'?(ss[3]=='('?mp_arg:ss[4]=='i'?mp_argmin:mp_argmax): - *ss=='s'?(ss[1]=='u'?mp_sum:mp_std): - *ss=='k'?mp_kth: - *ss=='p'?mp_prod: - *ss=='v'?mp_variance: - ss[1]=='i'?mp_min: - ss[1]=='a'?mp_max: - ss[2]=='a'?mp_mean: - mp_med),pos). - move_to(_opcode); - for (s = std::strchr(ss,'(') + 1; s::sequence(_cimg_mp_vector_size(arg2),arg2 + 1, - arg2 + (ulongT)_cimg_mp_vector_size(arg2)). - move_to(_opcode); - else CImg::vector(arg2).move_to(_opcode); - s = ns; - } - (_opcode>'y').move_to(code); - _cimg_mp_return(pos); - } - - // No corresponding built-in function -> Look for a user-defined macro. - s0 = strchr(ss,'('); - if (s0) { - variable_name.assign(ss,(unsigned int)(s0 - ss + 1)).back() = 0; - cimglist_for(function_def,l) if (!std::strcmp(function_def[l],variable_name)) { - p2 = (unsigned int)function_def[l].back(); // Number of required arguments - CImg _expr = function_body[l]; // Expression to be substituted - - p1 = 1; // Indice of current parsed argument - for (s = s0 + 1; s<=se1; ++p1, s = ns + 1) { // Parse function arguments - while (*s && *s<=' ') ++s; - if (*s==')' && p1==1) break; // Function has no arguments - if (p1>p2) { ++p1; break; } - ns = s; while (ns::%s: Function '%s()': Number of specified arguments does not " - "match function declaration (%u argument%s required), " - "in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,variable_name._data, - p2,p2!=1?"s":"", - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - - // Recompute 'pexpr' and 'level' for evaluating substituted expression. - CImg _pexpr(_expr._width); - ns = _pexpr._data; - for (ps = _expr._data, c1 = ' '; *ps; ++ps) { - if (*ps!=' ') c1 = *ps; - *(ns++) = c1; - } - *ns = 0; - - CImg _level = get_level(_expr); - expr.swap(_expr); pexpr.swap(_pexpr); level.swap(_level); - s0 = user_function; - user_function = function_def[l]; - pos = compile(expr._data,expr._data + expr._width - 1,depth1,p_ref); - user_function = s0; - expr.swap(_expr); pexpr.swap(_pexpr); level.swap(_level); - _cimg_mp_return(pos); - } - } - } // if (se1==')') - - // Char / string initializer. - if (*se1=='\'' && - ((se1>ss && *ss=='\'') || - (se1>ss1 && *ss=='_' && *ss1=='\''))) { - if (*ss=='_') { _cimg_mp_op("Char initializer"); s1 = ss2; } - else { _cimg_mp_op("String initializer"); s1 = ss1; } - arg1 = (unsigned int)(se1 - s1); // Original string length. - if (arg1) { - CImg(s1,arg1 + 1).move_to(variable_name).back() = 0; - cimg::strunescape(variable_name); - arg1 = (unsigned int)std::strlen(variable_name); - } - if (!arg1) _cimg_mp_return(0); // Empty string -> 0 - if (*ss=='_') { - if (arg1==1) _cimg_mp_constant(*variable_name); - *se = saved_char; cimg::strellipsize(variable_name,64); cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: %s: Literal %s contains more than one character, " - "in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op, - ss1, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - pos = vector(arg1); - CImg::vector((ulongT)mp_string_init,pos,arg1).move_to(_opcode); - CImg(1,arg1/sizeof(ulongT) + (arg1%sizeof(ulongT)?1:0)).move_to(_opcode); - std::memcpy((char*)_opcode[1]._data,variable_name,arg1); - (_opcode>'y').move_to(code); - _cimg_mp_return(pos); - } - - // Vector initializer [ ... ]. - if (*ss=='[' && *se1==']') { - _cimg_mp_op("Vector initializer"); - s1 = ss1; while (s1s1 && *s2<=' ') --s2; - if (s2>s1 && *s1=='\'' && *s2=='\'') { // Vector values provided as a string - arg1 = (unsigned int)(s2 - s1 - 1); // Original string length. - if (arg1) { - CImg(s1 + 1,arg1 + 1).move_to(variable_name).back() = 0; - cimg::strunescape(variable_name); - arg1 = (unsigned int)std::strlen(variable_name); - } - if (!arg1) _cimg_mp_return(0); // Empty string -> 0 - pos = vector(arg1); - CImg::vector((ulongT)mp_string_init,pos,arg1).move_to(_opcode); - CImg(1,arg1/sizeof(ulongT) + (arg1%sizeof(ulongT)?1:0)).move_to(_opcode); - std::memcpy((char*)_opcode[1]._data,variable_name,arg1); - } else { // Vector values provided as list of items - arg1 = 0; // Number of specified values. - if (*ss1!=']') for (s = ss1; s::sequence(arg3,arg2 + 1,arg2 + arg3).move_to(_opcode); - arg1+=arg3; - } else { CImg::vector(arg2).move_to(_opcode); ++arg1; } - s = ns; - } - _cimg_mp_check_vector0(arg1); - pos = vector(arg1); - _opcode.insert(CImg::vector((ulongT)mp_vector_init,pos,arg1),0); - } - (_opcode>'y').move_to(code); - _cimg_mp_return(pos); - } - - // Variables related to the input list of images. - if (*ss1=='#' && ss2::vector(listin[p1].median()).move_to(list_median[p1]); - _cimg_mp_constant(*list_median[p1]); - } - _cimg_mp_scalar1(mp_list_median,arg1); - } - if (*ss1>='0' && *ss1<='9') { // i0#ind...i9#ind - if (!listin) _cimg_mp_return(0); - _cimg_mp_scalar7(mp_list_ixyzc,arg1,_cimg_mp_x,_cimg_mp_y,_cimg_mp_z,*ss1 - '0', - reserved_label[29],reserved_label[30]); - } - switch (*ss1) { - case 'm' : arg2 = 0; break; // im#ind - case 'M' : arg2 = 1; break; // iM#ind - case 'a' : arg2 = 2; break; // ia#ind - case 'v' : arg2 = 3; break; // iv#ind - case 's' : arg2 = 12; break; // is#ind - case 'p' : arg2 = 13; break; // ip#ind - } - } else if (*ss1=='m') switch (*ss) { - case 'x' : arg2 = 4; break; // xm#ind - case 'y' : arg2 = 5; break; // ym#ind - case 'z' : arg2 = 6; break; // zm#ind - case 'c' : arg2 = 7; break; // cm#ind - } else if (*ss1=='M') switch (*ss) { - case 'x' : arg2 = 8; break; // xM#ind - case 'y' : arg2 = 9; break; // yM#ind - case 'z' : arg2 = 10; break; // zM#ind - case 'c' : arg2 = 11; break; // cM#ind - } - if (arg2!=~0U) { - if (!listin) _cimg_mp_return(0); - if _cimg_mp_is_constant(arg1) { - if (!list_stats) list_stats.assign(listin._width); - if (!list_stats[p1]) list_stats[p1].assign(1,14,1,1,0).fill(listin[p1].get_stats(),false); - _cimg_mp_constant(list_stats(p1,arg2)); - } - _cimg_mp_scalar2(mp_list_stats,arg1,arg2); - } - } - - if (*ss=='w' && *ss1=='h' && *ss2=='d' && *ss3=='#' && ss4 error. - is_sth = true; // is_valid_variable_name - if (*variable_name>='0' && *variable_name<='9') is_sth = false; - else for (ns = variable_name._data; *ns; ++ns) - if (!is_varchar(*ns)) { is_sth = false; break; } - - *se = saved_char; cimg::strellipsize(variable_name,64); cimg::strellipsize(expr,64); - if (is_sth) - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: Undefined variable '%s' in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function, - variable_name._data, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - s0 = std::strchr(ss,'('); - if (s0 && *se1==')') s_op = "function call"; else s_op = "item"; - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s: Unrecognized %s '%s' in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function, - s_op,variable_name._data, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - - // Evaluation procedure. - double operator()(const double x, const double y, const double z, const double c) { - mem[_cimg_mp_x] = x; mem[_cimg_mp_y] = y; mem[_cimg_mp_z] = z; mem[_cimg_mp_c] = c; - for (p_code = p_code_begin; p_code &op = *p_code; - opcode._data = op._data; opcode._height = op._height; - const ulongT target = opcode[1]; - mem[target] = _cimg_mp_defunc(*this); - } - return *result; - } - - // Evaluation procedure (return output values in vector 'output'). - template - void operator()(const double x, const double y, const double z, const double c, t *const output) { - mem[_cimg_mp_x] = x; mem[_cimg_mp_y] = y; mem[_cimg_mp_z] = z; mem[_cimg_mp_c] = c; - for (p_code = p_code_begin; p_code &op = *p_code; - opcode._data = op._data; opcode._height = op._height; - const ulongT target = opcode[1]; - mem[target] = _cimg_mp_defunc(*this); - } - if (result_dim) { - const double *ptrs = result + 1; - t *ptrd = output; - for (unsigned int k = 0; k s_type(const unsigned int arg) const { - CImg res; - if (_cimg_mp_is_vector(arg)) { // Vector - CImg::string("vectorXXXXXXXXXXXXXXXX").move_to(res); - std::sprintf(res._data + 6,"%u",_cimg_mp_vector_size(arg)); - } else CImg::string("scalar").move_to(res); - return res; - } - - // Insert constant value in memory. - unsigned int constant(const double val) { - if (val==(double)(int)val) { - if (val>=0 && val<=10) return (unsigned int)val; - if (val<0 && val>=-5) return (unsigned int)(10 - val); - } - if (val==0.5) return 16; - if (cimg::type::is_nan(val)) return _cimg_mp_nan; - if (mempos>=mem._width) { mem.resize(-200,1,1,1,0); memtype.resize(-200,1,1,1,0); } - const unsigned int pos = mempos++; - mem[pos] = val; - memtype[pos] = 1; // Set constant property - return pos; - } - - // Insert code instructions for processing scalars. - unsigned int scalar() { // Insert new scalar in memory. - if (mempos>=mem._width) { mem.resize(-200,1,1,1,0); memtype.resize(mem._width,1,1,1,0); } - return mempos++; - } - - unsigned int scalar0(const mp_func op) { - const unsigned int pos = scalar(); - CImg::vector((ulongT)op,pos).move_to(code); - return pos; - } - - unsigned int scalar1(const mp_func op, const unsigned int arg1) { - const unsigned int pos = - arg1>_cimg_mp_c && _cimg_mp_is_temp(arg1)?arg1:scalar(); - CImg::vector((ulongT)op,pos,arg1).move_to(code); - return pos; - } - - unsigned int scalar2(const mp_func op, const unsigned int arg1, const unsigned int arg2) { - const unsigned int pos = - arg1>_cimg_mp_c && _cimg_mp_is_temp(arg1)?arg1: - arg2>_cimg_mp_c && _cimg_mp_is_temp(arg2)?arg2:scalar(); - CImg::vector((ulongT)op,pos,arg1,arg2).move_to(code); - return pos; - } - - unsigned int scalar3(const mp_func op, - const unsigned int arg1, const unsigned int arg2, const unsigned int arg3) { - const unsigned int pos = - arg1>_cimg_mp_c && _cimg_mp_is_temp(arg1)?arg1: - arg2>_cimg_mp_c && _cimg_mp_is_temp(arg2)?arg2: - arg3>_cimg_mp_c && _cimg_mp_is_temp(arg3)?arg3:scalar(); - CImg::vector((ulongT)op,pos,arg1,arg2,arg3).move_to(code); - return pos; - } - - unsigned int scalar4(const mp_func op, - const unsigned int arg1, const unsigned int arg2, const unsigned int arg3, - const unsigned int arg4) { - const unsigned int pos = - arg1>_cimg_mp_c && _cimg_mp_is_temp(arg1)?arg1: - arg2>_cimg_mp_c && _cimg_mp_is_temp(arg2)?arg2: - arg3>_cimg_mp_c && _cimg_mp_is_temp(arg3)?arg3: - arg4>_cimg_mp_c && _cimg_mp_is_temp(arg4)?arg4:scalar(); - CImg::vector((ulongT)op,pos,arg1,arg2,arg3,arg4).move_to(code); - return pos; - } - - unsigned int scalar5(const mp_func op, - const unsigned int arg1, const unsigned int arg2, const unsigned int arg3, - const unsigned int arg4, const unsigned int arg5) { - const unsigned int pos = - arg1>_cimg_mp_c && _cimg_mp_is_temp(arg1)?arg1: - arg2>_cimg_mp_c && _cimg_mp_is_temp(arg2)?arg2: - arg3>_cimg_mp_c && _cimg_mp_is_temp(arg3)?arg3: - arg4>_cimg_mp_c && _cimg_mp_is_temp(arg4)?arg4: - arg5>_cimg_mp_c && _cimg_mp_is_temp(arg5)?arg5:scalar(); - CImg::vector((ulongT)op,pos,arg1,arg2,arg3,arg4,arg5).move_to(code); - return pos; - } - - unsigned int scalar6(const mp_func op, - const unsigned int arg1, const unsigned int arg2, const unsigned int arg3, - const unsigned int arg4, const unsigned int arg5, const unsigned int arg6) { - const unsigned int pos = - arg1>_cimg_mp_c && _cimg_mp_is_temp(arg1)?arg1: - arg2>_cimg_mp_c && _cimg_mp_is_temp(arg2)?arg2: - arg3>_cimg_mp_c && _cimg_mp_is_temp(arg3)?arg3: - arg4>_cimg_mp_c && _cimg_mp_is_temp(arg4)?arg4: - arg5>_cimg_mp_c && _cimg_mp_is_temp(arg5)?arg5: - arg6>_cimg_mp_c && _cimg_mp_is_temp(arg6)?arg6:scalar(); - CImg::vector((ulongT)op,pos,arg1,arg2,arg3,arg4,arg5,arg6).move_to(code); - return pos; - } - - unsigned int scalar7(const mp_func op, - const unsigned int arg1, const unsigned int arg2, const unsigned int arg3, - const unsigned int arg4, const unsigned int arg5, const unsigned int arg6, - const unsigned int arg7) { - const unsigned int pos = - arg1>_cimg_mp_c && _cimg_mp_is_temp(arg1)?arg1: - arg2>_cimg_mp_c && _cimg_mp_is_temp(arg2)?arg2: - arg3>_cimg_mp_c && _cimg_mp_is_temp(arg3)?arg3: - arg4>_cimg_mp_c && _cimg_mp_is_temp(arg4)?arg4: - arg5>_cimg_mp_c && _cimg_mp_is_temp(arg5)?arg5: - arg6>_cimg_mp_c && _cimg_mp_is_temp(arg6)?arg6: - arg7>_cimg_mp_c && _cimg_mp_is_temp(arg7)?arg7:scalar(); - CImg::vector((ulongT)op,pos,arg1,arg2,arg3,arg4,arg5,arg6,arg7).move_to(code); - return pos; - } - - // Return a string that defines the calling function + the user-defined function scope. - CImg calling_function_s() const { - CImg res; - const unsigned int - l1 = calling_function?(unsigned int)std::strlen(calling_function):0U, - l2 = user_function?(unsigned int)std::strlen(user_function):0U; - if (l2) { - res.assign(l1 + l2 + 48); - cimg_snprintf(res,res._width,"%s(): When substituting function '%s()'",calling_function,user_function); - } else { - res.assign(l1 + l2 + 4); - cimg_snprintf(res,res._width,"%s()",calling_function); - } - return res; - } - - // Return true if specified argument can be a part of an allowed variable name. - bool is_varchar(const char c) const { - return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || c=='_'; - } - - // Insert code instructions for processing vectors. - bool is_tmp_vector(const unsigned int arg) const { - unsigned int siz = _cimg_mp_vector_size(arg); - if (siz>8) return false; - const int *ptr = memtype.data(arg + 1); - bool is_tmp = true; - while (siz-->0) if (*(ptr++)) { is_tmp = false; break; } - return is_tmp; - } - - void set_variable_vector(const unsigned int arg) { - unsigned int siz = _cimg_mp_vector_size(arg); - int *ptr = memtype.data(arg + 1); - while (siz-->0) *(ptr++) = -1; - } - - unsigned int vector(const unsigned int siz) { // Insert new vector of specified size in memory - if (mempos + siz>=mem._width) { - mem.resize(2*mem._width + siz,1,1,1,0); - memtype.resize(mem._width,1,1,1,0); - } - const unsigned int pos = mempos++; - mem[pos] = cimg::type::nan(); - memtype[pos] = siz + 1; - mempos+=siz; - return pos; - } - - unsigned int vector(const unsigned int siz, const double value) { // Insert new initialized vector - const unsigned int pos = vector(siz); - double *ptr = &mem[pos] + 1; - for (unsigned int i = 0; i::vector((ulongT)mp_vector_copy,pos,arg,siz).move_to(code); - return pos; - } - - void self_vector_s(const unsigned int pos, const mp_func op, const unsigned int arg1) { - const unsigned int siz = _cimg_mp_vector_size(pos); - if (siz>24) CImg::vector((ulongT)mp_self_map_vector_s,pos,siz,(ulongT)op,arg1).move_to(code); - else { - code.insert(siz); - for (unsigned int k = 1; k<=siz; ++k) - CImg::vector((ulongT)op,pos + k,arg1).move_to(code[code._width - 1 - siz + k]); - } - } - - void self_vector_v(const unsigned int pos, const mp_func op, const unsigned int arg1) { - const unsigned int siz = _cimg_mp_vector_size(pos); - if (siz>24) CImg::vector((ulongT)mp_self_map_vector_v,pos,siz,(ulongT)op,arg1).move_to(code); - else { - code.insert(siz); - for (unsigned int k = 1; k<=siz; ++k) - CImg::vector((ulongT)op,pos + k,arg1 + k).move_to(code[code._width - 1 - siz + k]); - } - } - - unsigned int vector1_v(const mp_func op, const unsigned int arg1) { - const unsigned int - siz = _cimg_mp_vector_size(arg1), - pos = is_tmp_vector(arg1)?arg1:vector(siz); - if (siz>24) CImg::vector((ulongT)mp_vector_map_v,pos,siz,(ulongT)op,arg1).move_to(code); - else { - code.insert(siz); - for (unsigned int k = 1; k<=siz; ++k) - CImg::vector((ulongT)op,pos + k,arg1 + k).move_to(code[code._width - 1 - siz + k]); - } - return pos; - } - - unsigned int vector2_vv(const mp_func op, const unsigned int arg1, const unsigned int arg2) { - const unsigned int - siz = _cimg_mp_vector_size(arg1), - pos = is_tmp_vector(arg1)?arg1:is_tmp_vector(arg2)?arg2:vector(siz); - if (siz>24) CImg::vector((ulongT)mp_vector_map_vv,pos,siz,(ulongT)op,arg1,arg2).move_to(code); - else { - code.insert(siz); - for (unsigned int k = 1; k<=siz; ++k) - CImg::vector((ulongT)op,pos + k,arg1 + k,arg2 + k).move_to(code[code._width - 1 - siz + k]); - } - return pos; - } - - unsigned int vector2_vs(const mp_func op, const unsigned int arg1, const unsigned int arg2) { - const unsigned int - siz = _cimg_mp_vector_size(arg1), - pos = is_tmp_vector(arg1)?arg1:vector(siz); - if (siz>24) CImg::vector((ulongT)mp_vector_map_vs,pos,siz,(ulongT)op,arg1,arg2).move_to(code); - else { - code.insert(siz); - for (unsigned int k = 1; k<=siz; ++k) - CImg::vector((ulongT)op,pos + k,arg1 + k,arg2).move_to(code[code._width - 1 - siz + k]); - } - return pos; - } - - unsigned int vector2_sv(const mp_func op, const unsigned int arg1, const unsigned int arg2) { - const unsigned int - siz = _cimg_mp_vector_size(arg2), - pos = is_tmp_vector(arg2)?arg2:vector(siz); - if (siz>24) CImg::vector((ulongT)mp_vector_map_sv,pos,siz,(ulongT)op,arg1,arg2).move_to(code); - else { - code.insert(siz); - for (unsigned int k = 1; k<=siz; ++k) - CImg::vector((ulongT)op,pos + k,arg1,arg2 + k).move_to(code[code._width - 1 - siz + k]); - } - return pos; - } - - unsigned int vector3_vss(const mp_func op, const unsigned int arg1, const unsigned int arg2, - const unsigned int arg3) { - const unsigned int - siz = _cimg_mp_vector_size(arg1), - pos = is_tmp_vector(arg1)?arg1:vector(siz); - if (siz>24) CImg::vector((ulongT)mp_vector_map_vss,pos,siz,(ulongT)op,arg1,arg2,arg3).move_to(code); - else { - code.insert(siz); - for (unsigned int k = 1; k<=siz; ++k) - CImg::vector((ulongT)op,pos + k,arg1 + k,arg2,arg3).move_to(code[code._width - 1 - siz + k]); - } - return pos; - } - - // Check if a memory slot is a positive integer constant scalar value. - // 'mode' can be { 0=constant | 1=positive constant | 2=strictly positive constant } - void check_constant(const unsigned int arg, const unsigned int n_arg, - const unsigned int mode, - const char *const ss, char *const se, const char saved_char) { - _cimg_mp_check_type(arg,n_arg,1,0); - if (!_cimg_mp_is_constant(arg) || mode==0?false:mem[arg]<(mode==2) || (double)(int)mem[arg]!=mem[arg]) { - const char *s_arg = !n_arg?"":n_arg==1?"First ":n_arg==2?"Second ":n_arg==3?"Third ": - n_arg==4?"Fourth ":n_arg==5?"Fifth ":n_arg==6?"Sixth ":n_arg==7?"Seventh ":n_arg==8?"Eighth ": - n_arg==9?"Ninth ":"One of the "; - *se = saved_char; cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s(): %s%s %s%s (of type '%s') is not a%s integer constant, " - "in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op,*s_op?":":"", - s_arg,*s_arg?"argument":"Argument",s_type(arg)._data, - !mode?"n":mode==1?" positive":" stricty positive", - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - } - - // Check a matrix is square. - void check_matrix_square(const unsigned int arg, const unsigned int n_arg, - const char *const ss, char *const se, const char saved_char) { - _cimg_mp_check_type(arg,n_arg,2,0); - const unsigned int - siz = _cimg_mp_vector_size(arg), - n = (unsigned int)std::sqrt((float)siz); - if (n*n!=siz) { - const char *s_arg; - if (*s_op!='F') s_arg = !n_arg?"":n_arg==1?"Left-hand ":"Right-hand "; - else s_arg = !n_arg?"":n_arg==1?"First ":n_arg==2?"Second ":n_arg==3?"Third ":"One "; - *se = saved_char; cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s(): %s%s %s%s (of type '%s') " - "cannot be considered as a square matrix, in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op,*s_op?":":"", - s_arg,*s_op=='F'?(*s_arg?"argument":"Argument"):(*s_arg?"operand":"Operand"), - s_type(arg)._data, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - } - - // Check type compatibility for one argument. - // Bits of 'mode' tells what types are allowed: - // { 1 = scalar | 2 = vectorN }. - // If 'N' is not zero, it also restricts the vectors to be of size N only. - void check_type(const unsigned int arg, const unsigned int n_arg, - const unsigned int mode, const unsigned int N, - const char *const ss, char *const se, const char saved_char) { - const bool - is_scalar = _cimg_mp_is_scalar(arg), - is_vector = _cimg_mp_is_vector(arg) && (!N || _cimg_mp_vector_size(arg)==N); - bool cond = false; - if (mode&1) cond|=is_scalar; - if (mode&2) cond|=is_vector; - if (!cond) { - const char *s_arg; - if (*s_op!='F') s_arg = !n_arg?"":n_arg==1?"Left-hand ":"Right-hand "; - else s_arg = !n_arg?"":n_arg==1?"First ":n_arg==2?"Second ":n_arg==3?"Third ": - n_arg==4?"Fourth ":n_arg==5?"Fifth ":n_arg==6?"Sixth ":n_arg==7?"Seventh ":n_arg==8?"Eighth": - n_arg==9?"Ninth":"One of the "; - CImg sb_type(32); - if (mode==1) cimg_snprintf(sb_type,sb_type._width,"'scalar'"); - else if (mode==2) { - if (N) cimg_snprintf(sb_type,sb_type._width,"'vector%u'",N); - else cimg_snprintf(sb_type,sb_type._width,"'vector'"); - } else { - if (N) cimg_snprintf(sb_type,sb_type._width,"'scalar' or 'vector%u'",N); - else cimg_snprintf(sb_type,sb_type._width,"'scalar' or 'vector'"); - } - *se = saved_char; cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s(): %s%s %s%s has invalid type '%s' (should be %s), " - "in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op,*s_op?":":"", - s_arg,*s_op=='F'?(*s_arg?"argument":"Argument"):(*s_arg?"operand":"Operand"), - s_type(arg)._data,sb_type._data, - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - } - - // Check is listin is not empty. - void check_list(const bool is_out, - const char *const ss, char *const se, const char saved_char) { - if ((!is_out && !listin) || (is_out && !listout)) { - *se = saved_char; cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s(): %s%s Invalid call with an empty image list, " - "in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op,*s_op?":":"", - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - } - - // Check a vector is not 0-dimensional, or with unknown dimension at compile time. - void check_vector0(const unsigned int dim, - const char *const ss, char *const se, const char saved_char) { - if (!dim) { - *se = saved_char; cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s(): %s%s Invalid construction of a 0-dimensional vector, " - "in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op,*s_op?":":"", - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } else if (dim==~0U) { - *se = saved_char; cimg::strellipsize(expr,64); - throw CImgArgumentException("[_cimg_math_parser] " - "CImg<%s>::%s(): %s%s Invalid construction of a vector with dynamic size, " - "in expression '%s%s%s'.", - pixel_type(),_cimg_mp_calling_function,s_op,*s_op?":":"", - (ss - 4)>expr._data?"...":"", - (ss - 4)>expr._data?ss - 4:expr._data, - se<&expr.back()?"...":""); - } - } - - // Evaluation functions, known by the parser. - // Defining these functions 'static' ensures that sizeof(mp_func)==sizeof(ulongT), - // so we can store pointers to them directly in the opcode vectors. -#ifdef _mp_arg -#undef _mp_arg -#endif -#define _mp_arg(x) mp.mem[mp.opcode[x]] - - static double mp_abs(_cimg_math_parser& mp) { - return cimg::abs(_mp_arg(2)); - } - - static double mp_add(_cimg_math_parser& mp) { - return _mp_arg(2) + _mp_arg(3); - } - - static double mp_acos(_cimg_math_parser& mp) { - return std::acos(_mp_arg(2)); - } - - static double mp_arg(_cimg_math_parser& mp) { - const int _ind = (int)_mp_arg(2); - const unsigned int nb_args = mp.opcode._height - 2, ind = _ind<0?_ind + nb_args:(unsigned int)_ind; - if (ind>=nb_args) return 0; - return _mp_arg(ind + 2); - } - - static double mp_argmin(_cimg_math_parser& mp) { - double val = _mp_arg(2); - unsigned int argval = 0; - for (unsigned int i = 3; ival) { val = _val; argval = i - 2; } - } - return (double)argval; - } - - static double mp_asin(_cimg_math_parser& mp) { - return std::asin(_mp_arg(2)); - } - - static double mp_atan(_cimg_math_parser& mp) { - return std::atan(_mp_arg(2)); - } - - static double mp_atan2(_cimg_math_parser& mp) { - return std::atan2(_mp_arg(2),_mp_arg(3)); - } - - static double mp_bitwise_and(_cimg_math_parser& mp) { - return (double)((ulongT)_mp_arg(2) & (ulongT)_mp_arg(3)); - } - - static double mp_bitwise_left_shift(_cimg_math_parser& mp) { - return (double)((longT)_mp_arg(2)<<(unsigned int)_mp_arg(3)); - } - - static double mp_bitwise_not(_cimg_math_parser& mp) { - return (double)~(ulongT)_mp_arg(2); - } - - static double mp_bitwise_or(_cimg_math_parser& mp) { - return (double)((ulongT)_mp_arg(2) | (ulongT)_mp_arg(3)); - } - - static double mp_bitwise_right_shift(_cimg_math_parser& mp) { - return (double)((longT)_mp_arg(2)>>(unsigned int)_mp_arg(3)); - } - - static double mp_cbrt(_cimg_math_parser& mp) { - return std::pow(_mp_arg(2),1.0/3); - } - - static double mp_complex_conj(_cimg_math_parser& mp) { - const double *ptrs = &_mp_arg(2) + 1; - double *ptrd = &_mp_arg(1) + 1; - *(ptrd++) = *(ptrs++); - *ptrd = -*(ptrs); - return cimg::type::nan(); - } - - static double mp_complex_div_sv(_cimg_math_parser& mp) { - const double - *ptr2 = &_mp_arg(3) + 1, - r1 = _mp_arg(2), - r2 = *(ptr2++), i2 = *ptr2; - double *ptrd = &_mp_arg(1) + 1; - const double denom = r2*r2 + i2*i2; - *(ptrd++) = r1*r2/denom; - *ptrd = -r1*i2/denom; - return cimg::type::nan(); - } - - static double mp_complex_div_vv(_cimg_math_parser& mp) { - const double - *ptr1 = &_mp_arg(2) + 1, *ptr2 = &_mp_arg(3) + 1, - r1 = *(ptr1++), i1 = *ptr1, - r2 = *(ptr2++), i2 = *ptr2; - double *ptrd = &_mp_arg(1) + 1; - const double denom = r2*r2 + i2*i2; - *(ptrd++) = (r1*r2 + i1*i2)/denom; - *ptrd = (r2*i1 - r1*i2)/denom; - return cimg::type::nan(); - } - - static double mp_complex_exp(_cimg_math_parser& mp) { - double *ptrd = &_mp_arg(1) + 1; - const double *ptrs = &_mp_arg(2) + 1, r = *(ptrs++), i = *(ptrs), er = std::exp(r); - *(ptrd++) = er*std::cos(i); - *(ptrd++) = er*std::sin(i); - return cimg::type::nan(); - } - - static double mp_complex_log(_cimg_math_parser& mp) { - double *ptrd = &_mp_arg(1) + 1; - const double *ptrs = &_mp_arg(2) + 1, r = *(ptrs++), i = *(ptrs); - *(ptrd++) = std::log(std::sqrt(r*r + i*i)); - *(ptrd++) = std::atan2(i,r); - return cimg::type::nan(); - } - - static double mp_complex_mul(_cimg_math_parser& mp) { - const double - *ptr1 = &_mp_arg(2) + 1, *ptr2 = &_mp_arg(3) + 1, - r1 = *(ptr1++), i1 = *ptr1, - r2 = *(ptr2++), i2 = *ptr2; - double *ptrd = &_mp_arg(1) + 1; - *(ptrd++) = r1*r2 - i1*i2; - *(ptrd++) = r1*i2 + r2*i1; - return cimg::type::nan(); - } - - static void _mp_complex_pow(const double r1, const double i1, - const double r2, const double i2, - double *ptrd) { - double ro, io; - if (cimg::abs(i2)<1e-15) { // Exponent is real - if (cimg::abs(r1)<1e-15 && cimg::abs(i1)<1e-15) { - if (cimg::abs(r2)<1e-15) { ro = 1; io = 0; } - else ro = io = 0; - } else { - const double - mod1_2 = r1*r1 + i1*i1, - phi1 = std::atan2(i1,r1), - modo = std::pow(mod1_2,0.5*r2), - phio = r2*phi1; - ro = modo*std::cos(phio); - io = modo*std::sin(phio); - } - } else { // Exponent is complex - if (cimg::abs(r1)<1e-15 && cimg::abs(i1)<1e-15) ro = io = 0; - const double - mod1_2 = r1*r1 + i1*i1, - phi1 = std::atan2(i1,r1), - modo = std::pow(mod1_2,0.5*r2)*std::exp(-i2*phi1), - phio = r2*phi1 + 0.5*i2*std::log(mod1_2); - ro = modo*std::cos(phio); - io = modo*std::sin(phio); - } - *(ptrd++) = ro; - *ptrd = io; - } - - static double mp_complex_pow_sv(_cimg_math_parser& mp) { - const double val1 = _mp_arg(2), *ptr2 = &_mp_arg(3) + 1; - double *ptrd = &_mp_arg(1) + 1; - _mp_complex_pow(val1,0,ptr2[0],ptr2[1],ptrd); - return cimg::type::nan(); - } - - static double mp_complex_pow_vs(_cimg_math_parser& mp) { - const double *ptr1 = &_mp_arg(2) + 1, val2 = _mp_arg(3); - double *ptrd = &_mp_arg(1) + 1; - _mp_complex_pow(ptr1[0],ptr1[1],val2,0,ptrd); - return cimg::type::nan(); - } - - static double mp_complex_pow_vv(_cimg_math_parser& mp) { - const double *ptr1 = &_mp_arg(2) + 1, *ptr2 = &_mp_arg(3) + 1; - double *ptrd = &_mp_arg(1) + 1; - _mp_complex_pow(ptr1[0],ptr1[1],ptr2[0],ptr2[1],ptrd); - return cimg::type::nan(); - } - - static double mp_cos(_cimg_math_parser& mp) { - return std::cos(_mp_arg(2)); - } - - static double mp_cosh(_cimg_math_parser& mp) { - return std::cosh(_mp_arg(2)); - } - - static double mp_crop(_cimg_math_parser& mp) { - double *ptrd = &_mp_arg(1) + 1; - const int x = (int)_mp_arg(3), y = (int)_mp_arg(4), z = (int)_mp_arg(5), c = (int)_mp_arg(6); - const unsigned int - dx = (unsigned int)mp.opcode[7], - dy = (unsigned int)mp.opcode[8], - dz = (unsigned int)mp.opcode[9], - dc = (unsigned int)mp.opcode[10]; - const bool boundary_conditions = (bool)_mp_arg(11); - unsigned int ind = (unsigned int)mp.opcode[2]; - if (ind!=~0U) ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()); - const CImg &img = ind==~0U?mp.imgin:mp.listin[ind]; - if (!img) std::memset(ptrd,0,dx*dy*dz*dc*sizeof(double)); - else CImg(ptrd,dx,dy,dz,dc,true) = img.get_crop(x,y,z,c, - x + dx - 1,y + dy - 1, - z + dz - 1,c + dc - 1, - boundary_conditions); - return cimg::type::nan(); - } - - static double mp_cross(_cimg_math_parser& mp) { - CImg - vout(&_mp_arg(1) + 1,1,3,1,1,true), - v1(&_mp_arg(2) + 1,1,3,1,1,true), - v2(&_mp_arg(3) + 1,1,3,1,1,true); - (vout = v1).cross(v2); - return cimg::type::nan(); - } - - static double mp_cut(_cimg_math_parser& mp) { - double val = _mp_arg(2), cmin = _mp_arg(3), cmax = _mp_arg(4); - return valcmax?cmax:val; - } - - static double mp_debug(_cimg_math_parser& mp) { - CImg expr(mp.opcode._height - 3); - const ulongT *ptrs = mp.opcode._data + 3; - cimg_for(expr,ptrd,char) *ptrd = (char)*(ptrs++); - cimg::strellipsize(expr); - const ulongT g_target = mp.opcode[1]; - -#ifndef cimg_use_openmp - const unsigned int n_thread = 0; -#else - const unsigned int n_thread = omp_get_thread_num(); -#endif - cimg_pragma_openmp(critical) - { - std::fprintf(cimg::output(), - "\n[_cimg_math_parser] %p[thread #%u]:%*c" - "Start debugging expression '%s', code length %u -> mem[%u] (memsize: %u)", - (void*)&mp,n_thread,mp.debug_indent,' ', - expr._data,(unsigned int)mp.opcode[2],(unsigned int)g_target,mp.mem._width); - std::fflush(cimg::output()); - mp.debug_indent+=3; - } - const CImg *const p_end = (++mp.p_code) + mp.opcode[2]; - CImg _op; - for ( ; mp.p_code &op = *mp.p_code; - mp.opcode._data = op._data; mp.opcode._height = op._height; - - _op.assign(1,op._height - 1); - const ulongT *ptrs = op._data + 1; - for (ulongT *ptrd = _op._data, *const ptrde = _op._data + _op._height; ptrd mem[%u] = %g", - (void*)&mp,n_thread,mp.debug_indent,' ', - (void*)mp.opcode._data,(void*)*mp.opcode,_op.value_string().data(), - (unsigned int)target,mp.mem[target]); - std::fflush(cimg::output()); - } - } - cimg_pragma_openmp(critical) - { - mp.debug_indent-=3; - std::fprintf(cimg::output(), - "\n[_cimg_math_parser] %p[thread #%u]:%*c" - "End debugging expression '%s' -> mem[%u] = %g (memsize: %u)", - (void*)&mp,n_thread,mp.debug_indent,' ', - expr._data,(unsigned int)g_target,mp.mem[g_target],mp.mem._width); - std::fflush(cimg::output()); - } - --mp.p_code; - return mp.mem[g_target]; - } - - static double mp_debug_memory(_cimg_math_parser& mp) { - cimg::unused(mp); - std::fputc('\n',cimg::output()); - mp.mem.display("[_cimg_math_parser] Memory snapshot"); - return cimg::type::nan(); - } - - static double mp_decrement(_cimg_math_parser& mp) { - return _mp_arg(2) - 1; - } - - static double mp_det(_cimg_math_parser& mp) { - const double *ptrs = &_mp_arg(2) + 1; - const unsigned int k = (unsigned int)mp.opcode(3); - return CImg(ptrs,k,k,1,1,true).det(); - } - - static double mp_diag(_cimg_math_parser& mp) { - double *ptrd = &_mp_arg(1) + 1; - const double *ptrs = &_mp_arg(2) + 1; - const unsigned int k = (unsigned int)mp.opcode(3); - CImg(ptrd,k,k,1,1,true) = CImg(ptrs,1,k,1,1,true).get_diagonal(); - return cimg::type::nan(); - } - - static double mp_div(_cimg_math_parser& mp) { - return _mp_arg(2)/_mp_arg(3); - } - - static double mp_dot(_cimg_math_parser& mp) { - const unsigned int siz = (unsigned int)mp.opcode[4]; - return CImg(&_mp_arg(2) + 1,1,siz,1,1,true). - dot(CImg(&_mp_arg(3) + 1,1,siz,1,1,true)); - } - - static double mp_dowhile(_cimg_math_parser& mp) { - const ulongT - mem_proc = mp.opcode[1], - mem_cond = mp.opcode[2]; - const CImg - *const p_proc = ++mp.p_code, - *const p_end = p_proc + mp.opcode[3]; - do { - for (mp.p_code = p_proc; mp.p_code &op = *mp.p_code; - mp.opcode._data = op._data; mp.opcode._height = op._height; - const ulongT target = mp.opcode[1]; - mp.mem[target] = _cimg_mp_defunc(mp); - } - } while (mp.mem[mem_cond]); - --mp.p_code; - return mp.mem[mem_proc]; - } - - static double mp_draw(_cimg_math_parser& mp) { - const int x = (int)_mp_arg(3), y = (int)_mp_arg(4), z = (int)_mp_arg(5), c = (int)_mp_arg(6); - const unsigned int - dx = (unsigned int)mp.opcode[7], - dy = (unsigned int)mp.opcode[8], - dz = (unsigned int)mp.opcode[9], - dc = (unsigned int)mp.opcode[10]; - const CImg S(&_mp_arg(1) + 1,dx,dy,dz,dc,true); - const float opacity = (float)_mp_arg(11); - unsigned int ind = (unsigned int)mp.opcode[2]; - if (ind!=~0U) ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()); - CImg &img = ind==~0U?mp.imgout:mp.listout[ind]; - if (img) { - if (mp.opcode[12]!=(ulongT)-1) { - const CImg M(&_mp_arg(12) + 1,dx,dy,dz,(unsigned int)mp.opcode[13],true); - img.draw_image(x,y,z,c,S,M,opacity,(float)_mp_arg(14)); - } else img.draw_image(x,y,z,c,S,opacity); - } - return cimg::type::nan(); - } - - static double mp_eig(_cimg_math_parser& mp) { - double *ptrd = &_mp_arg(1) + 1; - const double *ptr1 = &_mp_arg(2) + 1; - const unsigned int k = (unsigned int)mp.opcode(3); - CImg val, vec; - CImg(ptr1,k,k,1,1,true).symmetric_eigen(val,vec); - CImg(ptrd,k,1,1,1,true) = val.unroll('x'); - CImg(ptrd + k,k,k,1,1,true) = vec.get_transpose(); - return cimg::type::nan(); - } - - static double mp_eq(_cimg_math_parser& mp) { - return (double)(_mp_arg(2)==_mp_arg(3)); - } - - static double mp_exp(_cimg_math_parser& mp) { - return std::exp(_mp_arg(2)); - } - - static double mp_eye(_cimg_math_parser& mp) { - double *ptrd = &_mp_arg(1) + 1; - const unsigned int k = (unsigned int)mp.opcode(2); - CImg(ptrd,k,k,1,1,true).identity_matrix(); - return cimg::type::nan(); - } - - static double mp_factorial(_cimg_math_parser& mp) { - return cimg::factorial(_mp_arg(2)); - } - - static double mp_fibonacci(_cimg_math_parser& mp) { - return cimg::fibonacci((int)_mp_arg(2)); - } - - static double mp_find(_cimg_math_parser& mp) { - const bool is_forward = (bool)_mp_arg(5); - const ulongT siz = (ulongT)mp.opcode[3]; - longT ind = (longT)(mp.opcode[6]!=_cimg_mp_nan?_mp_arg(6):is_forward?0:siz - 1); - if (ind<0 || ind>=(longT)siz) return -1.; - const double - *const ptrb = &_mp_arg(2) + 1, - *const ptre = ptrb + siz, - val = _mp_arg(4), - *ptr = ptrb + ind; - - // Forward search - if (is_forward) { - while (ptr=ptrb && *ptr!=val) --ptr; - return ptr=(longT)siz1) return -1.; - const double - *const ptr1b = &_mp_arg(2) + 1, - *const ptr1e = ptr1b + siz1, - *const ptr2b = &_mp_arg(4) + 1, - *const ptr2e = ptr2b + siz2, - *ptr1 = ptr1b + ind, - *p1 = 0, - *p2 = 0; - - // Forward search. - if (is_forward) { - do { - while (ptr1=ptr1b && *ptr1!=*ptr2b) --ptr1; - p1 = ptr1 + 1; - p2 = ptr2b + 1; - while (p1=ptr1b); - return p2_mp_arg(3)); - } - - static double mp_gte(_cimg_math_parser& mp) { - return (double)(_mp_arg(2)>=_mp_arg(3)); - } - - static double mp_hypot(_cimg_math_parser& mp) { - return cimg::hypot(_mp_arg(2),_mp_arg(3)); - } - - static double mp_i(_cimg_math_parser& mp) { - return (double)mp.imgin.atXYZC((int)mp.mem[_cimg_mp_x],(int)mp.mem[_cimg_mp_y], - (int)mp.mem[_cimg_mp_z],(int)mp.mem[_cimg_mp_c],0); - } - - static double mp_if(_cimg_math_parser& mp) { - const bool is_cond = (bool)_mp_arg(2); - const ulongT - mem_left = mp.opcode[3], - mem_right = mp.opcode[4]; - const CImg - *const p_right = ++mp.p_code + mp.opcode[5], - *const p_end = p_right + mp.opcode[6]; - const unsigned int vtarget = (unsigned int)mp.opcode[1], vsiz = (unsigned int)mp.opcode[7]; - if (is_cond) { - for ( ; mp.p_code &op = *mp.p_code; - mp.opcode._data = op._data; mp.opcode._height = op._height; - const ulongT target = mp.opcode[1]; - mp.mem[target] = _cimg_mp_defunc(mp); - } - mp.p_code = p_end - 1; - if (vsiz) std::memcpy(&mp.mem[vtarget] + 1,&mp.mem[mem_left] + 1,sizeof(double)*vsiz); - return mp.mem[mem_left]; - } - for (mp.p_code = p_right; mp.p_code &op = *mp.p_code; - mp.opcode._data = op._data; mp.opcode._height = op._height; - const ulongT target = mp.opcode[1]; - mp.mem[target] = _cimg_mp_defunc(mp); - } - --mp.p_code; - if (vsiz) std::memcpy(&mp.mem[vtarget] + 1,&mp.mem[mem_right] + 1,sizeof(double)*vsiz); - return mp.mem[mem_right]; - } - - static double mp_increment(_cimg_math_parser& mp) { - return _mp_arg(2) + 1; - } - - static double mp_int(_cimg_math_parser& mp) { - return (double)(longT)_mp_arg(2); - } - - static double mp_inv(_cimg_math_parser& mp) { - double *ptrd = &_mp_arg(1) + 1; - const double *ptr1 = &_mp_arg(2) + 1; - const unsigned int k = (unsigned int)mp.opcode(3); - CImg(ptrd,k,k,1,1,true) = CImg(ptr1,k,k,1,1,true).get_invert(); - return cimg::type::nan(); - } - - static double mp_ioff(_cimg_math_parser& mp) { - const unsigned int - boundary_conditions = (unsigned int)_mp_arg(3); - const CImg &img = mp.imgin; - const longT - off = (longT)_mp_arg(2), - whds = (longT)img.size(); - if (off<0 || off>=whds) - switch (boundary_conditions) { - case 2 : // Periodic boundary - if (img) return (double)img[cimg::mod(off,whds)]; - return 0; - case 1 : // Neumann boundary - if (img) return (double)(off<0?*img:img.back()); - return 0; - default : // Dirichet boundary - return 0; - } - return (double)img[off]; - } - - static double mp_isbool(_cimg_math_parser& mp) { - const double val = _mp_arg(2); - return (double)(val==0.0 || val==1.0); - } - - static double mp_isin(_cimg_math_parser& mp) { - const double val = _mp_arg(2); - for (unsigned int i = 3; i::is_inf(_mp_arg(2)); - } - - static double mp_isint(_cimg_math_parser& mp) { - return (double)(cimg::mod(_mp_arg(2),1.0)==0); - } - - static double mp_isnan(_cimg_math_parser& mp) { - return (double)cimg::type::is_nan(_mp_arg(2)); - } - - static double mp_ixyzc(_cimg_math_parser& mp) { - const unsigned int - interpolation = (unsigned int)_mp_arg(6), - boundary_conditions = (unsigned int)_mp_arg(7); - const CImg &img = mp.imgin; - const double - x = _mp_arg(2), y = _mp_arg(3), - z = _mp_arg(4), c = _mp_arg(5); - if (interpolation==0) { // Nearest neighbor interpolation - if (boundary_conditions==2) - return (double)img.atXYZC(cimg::mod((int)x,img.width()), - cimg::mod((int)y,img.height()), - cimg::mod((int)z,img.depth()), - cimg::mod((int)c,img.spectrum())); - if (boundary_conditions==1) - return (double)img.atXYZC((int)x,(int)y,(int)z,(int)c); - return (double)img.atXYZC((int)x,(int)y,(int)z,(int)c,0); - } else { // Linear interpolation - if (boundary_conditions==2) - return (double)img.linear_atXYZC(cimg::mod((float)x,(float)img.width()), - cimg::mod((float)y,(float)img.height()), - cimg::mod((float)z,(float)img.depth()), - cimg::mod((float)c,(float)img.spectrum())); - if (boundary_conditions==1) - return (double)img.linear_atXYZC((float)x,(float)y,(float)z,(float)c); - return (double)img.linear_atXYZC((float)x,(float)y,(float)z,(float)c,0); - } - } - - static double mp_joff(_cimg_math_parser& mp) { - const unsigned int - boundary_conditions = (unsigned int)_mp_arg(3); - const int - ox = (int)mp.mem[_cimg_mp_x], oy = (int)mp.mem[_cimg_mp_y], - oz = (int)mp.mem[_cimg_mp_z], oc = (int)mp.mem[_cimg_mp_c]; - const CImg &img = mp.imgin; - const longT - off = img.offset(ox,oy,oz,oc) + (longT)_mp_arg(2), - whds = (longT)img.size(); - if (off<0 || off>=whds) - switch (boundary_conditions) { - case 2 : // Periodic boundary - if (img) return (double)img[cimg::mod(off,whds)]; - return 0; - case 1 : // Neumann boundary - if (img) return (double)(off<0?*img:img.back()); - return 0; - default : // Dirichet boundary - return 0; - } - return (double)img[off]; - } - - static double mp_jxyzc(_cimg_math_parser& mp) { - const unsigned int - interpolation = (unsigned int)_mp_arg(6), - boundary_conditions = (unsigned int)_mp_arg(7); - const CImg &img = mp.imgin; - const double - ox = mp.mem[_cimg_mp_x], oy = mp.mem[_cimg_mp_y], - oz = mp.mem[_cimg_mp_z], oc = mp.mem[_cimg_mp_c], - x = ox + _mp_arg(2), y = oy + _mp_arg(3), - z = oz + _mp_arg(4), c = oc + _mp_arg(5); - if (interpolation==0) { // Nearest neighbor interpolation - if (boundary_conditions==2) - return (double)img.atXYZC(cimg::mod((int)x,img.width()), - cimg::mod((int)y,img.height()), - cimg::mod((int)z,img.depth()), - cimg::mod((int)c,img.spectrum())); - if (boundary_conditions==1) - return (double)img.atXYZC((int)x,(int)y,(int)z,(int)c); - return (double)img.atXYZC((int)x,(int)y,(int)z,(int)c,0); - } else { // Linear interpolation - if (boundary_conditions==2) - return (double)img.linear_atXYZC(cimg::mod((float)x,(float)img.width()), - cimg::mod((float)y,(float)img.height()), - cimg::mod((float)z,(float)img.depth()), - cimg::mod((float)c,(float)img.spectrum())); - if (boundary_conditions==1) - return (double)img.linear_atXYZC((float)x,(float)y,(float)z,(float)c); - return (double)img.linear_atXYZC((float)x,(float)y,(float)z,(float)c,0); - } - } - - static double mp_kth(_cimg_math_parser& mp) { - CImg vals(mp.opcode._height - 3); - double *p = vals.data(); - for (unsigned int i = 3; i &img = mp.listin[indi]; - const bool is_forward = (bool)_mp_arg(4); - const ulongT siz = (ulongT)img.size(); - longT ind = (longT)(mp.opcode[5]!=_cimg_mp_nan?_mp_arg(5):is_forward?0:siz - 1); - if (ind<0 || ind>=(longT)siz) return -1.; - const T - *const ptrb = img.data(), - *const ptre = img.end(), - *ptr = ptrb + ind; - const double val = _mp_arg(3); - - // Forward search - if (is_forward) { - while (ptr=ptrb && (double)*ptr!=val) --ptr; - return ptr &img = mp.listin[indi]; - const bool is_forward = (bool)_mp_arg(5); - const ulongT - siz1 = (ulongT)img.size(), - siz2 = (ulongT)mp.opcode[4]; - longT ind = (longT)(mp.opcode[6]!=_cimg_mp_nan?_mp_arg(6):is_forward?0:siz1 - 1); - if (ind<0 || ind>=(longT)siz1) return -1.; - const T - *const ptr1b = img.data(), - *const ptr1e = ptr1b + siz1, - *ptr1 = ptr1b + ind, - *p1 = 0; - const double - *const ptr2b = &_mp_arg(3) + 1, - *const ptr2e = ptr2b + siz2, - *p2 = 0; - - // Forward search. - if (is_forward) { - do { - while (ptr1=ptr1b && *ptr1!=*ptr2b) --ptr1; - p1 = ptr1 + 1; - p2 = ptr2b + 1; - while (p1=ptr1b); - return p2 &img = mp.listin[ind]; - const longT - off = (longT)_mp_arg(3), - whds = (longT)img.size(); - if (off<0 || off>=whds) - switch (boundary_conditions) { - case 2 : // Periodic boundary - if (img) return (double)img[cimg::mod(off,whds)]; - return 0; - case 1 : // Neumann boundary - if (img) return (double)(off<0?*img:img.back()); - return 0; - default : // Dirichet boundary - return 0; - } - return (double)img[off]; - } - - static double mp_list_is_shared(_cimg_math_parser& mp) { - const unsigned int ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()); - return (double)mp.listin[ind]._is_shared; - } - - static double mp_list_ixyzc(_cimg_math_parser& mp) { - const unsigned int - ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()), - interpolation = (unsigned int)_mp_arg(7), - boundary_conditions = (unsigned int)_mp_arg(8); - const CImg &img = mp.listin[ind]; - const double - x = _mp_arg(3), y = _mp_arg(4), - z = _mp_arg(5), c = _mp_arg(6); - if (interpolation==0) { // Nearest neighbor interpolation - if (boundary_conditions==2) - return (double)img.atXYZC(cimg::mod((int)x,img.width()), - cimg::mod((int)y,img.height()), - cimg::mod((int)z,img.depth()), - cimg::mod((int)c,img.spectrum())); - if (boundary_conditions==1) - return (double)img.atXYZC((int)x,(int)y,(int)z,(int)c); - return (double)img.atXYZC((int)x,(int)y,(int)z,(int)c,0); - } else { // Linear interpolation - if (boundary_conditions==2) - return (double)img.linear_atXYZC(cimg::mod((float)x,(float)img.width()), - cimg::mod((float)y,(float)img.height()), - cimg::mod((float)z,(float)img.depth()), - cimg::mod((float)c,(float)img.spectrum())); - if (boundary_conditions==1) - return (double)img.linear_atXYZC((float)x,(float)y,(float)z,(float)c); - return (double)img.linear_atXYZC((float)x,(float)y,(float)z,(float)c,0); - } - } - - static double mp_list_joff(_cimg_math_parser& mp) { - const unsigned int - ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()), - boundary_conditions = (unsigned int)_mp_arg(4); - const int - ox = (int)mp.mem[_cimg_mp_x], oy = (int)mp.mem[_cimg_mp_y], - oz = (int)mp.mem[_cimg_mp_z], oc = (int)mp.mem[_cimg_mp_c]; - const CImg &img = mp.listin[ind]; - const longT - off = img.offset(ox,oy,oz,oc) + (longT)_mp_arg(3), - whds = (longT)img.size(); - if (off<0 || off>=whds) - switch (boundary_conditions) { - case 2 : // Periodic boundary - if (img) return (double)img[cimg::mod(off,whds)]; - return 0; - case 1 : // Neumann boundary - if (img) return (double)(off<0?*img:img.back()); - return 0; - default : // Dirichet boundary - return 0; - } - return (double)img[off]; - } - - static double mp_list_jxyzc(_cimg_math_parser& mp) { - const unsigned int - ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()), - interpolation = (unsigned int)_mp_arg(7), - boundary_conditions = (unsigned int)_mp_arg(8); - const CImg &img = mp.listin[ind]; - const double - ox = mp.mem[_cimg_mp_x], oy = mp.mem[_cimg_mp_y], - oz = mp.mem[_cimg_mp_z], oc = mp.mem[_cimg_mp_c], - x = ox + _mp_arg(3), y = oy + _mp_arg(4), - z = oz + _mp_arg(5), c = oc + _mp_arg(6); - if (interpolation==0) { // Nearest neighbor interpolation - if (boundary_conditions==2) - return (double)img.atXYZC(cimg::mod((int)x,img.width()), - cimg::mod((int)y,img.height()), - cimg::mod((int)z,img.depth()), - cimg::mod((int)c,img.spectrum())); - if (boundary_conditions==1) - return (double)img.atXYZC((int)x,(int)y,(int)z,(int)c); - return (double)img.atXYZC((int)x,(int)y,(int)z,(int)c,0); - } else { // Linear interpolation - if (boundary_conditions==2) - return (double)img.linear_atXYZC(cimg::mod((float)x,(float)img.width()), - cimg::mod((float)y,(float)img.height()), - cimg::mod((float)z,(float)img.depth()), - cimg::mod((float)c,(float)img.spectrum())); - if (boundary_conditions==1) - return (double)img.linear_atXYZC((float)x,(float)y,(float)z,(float)c); - return (double)img.linear_atXYZC((float)x,(float)y,(float)z,(float)c,0); - } - } - - static double mp_list_median(_cimg_math_parser& mp) { - const unsigned int ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()); - if (!mp.list_median) mp.list_median.assign(mp.listin._width); - if (!mp.list_median[ind]) CImg::vector(mp.listin[ind].median()).move_to(mp.list_median[ind]); - return *mp.list_median[ind]; - } - - static double mp_list_set_ioff(_cimg_math_parser& mp) { - const unsigned int ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()); - CImg &img = mp.listout[ind]; - const longT - off = (longT)_mp_arg(3), - whds = (longT)img.size(); - const double val = _mp_arg(1); - if (off>=0 && off &img = mp.listout[ind]; - const int - x = (int)_mp_arg(3), y = (int)_mp_arg(4), - z = (int)_mp_arg(5), c = (int)_mp_arg(6); - const double val = _mp_arg(1); - if (x>=0 && x=0 && y=0 && z=0 && c &img = mp.listout[ind]; - const int - ox = (int)mp.mem[_cimg_mp_x], oy = (int)mp.mem[_cimg_mp_y], - oz = (int)mp.mem[_cimg_mp_z], oc = (int)mp.mem[_cimg_mp_c]; - const longT - off = img.offset(ox,oy,oz,oc) + (longT)_mp_arg(3), - whds = (longT)img.size(); - const double val = _mp_arg(1); - if (off>=0 && off &img = mp.listout[ind]; - const double - ox = mp.mem[_cimg_mp_x], oy = mp.mem[_cimg_mp_y], - oz = mp.mem[_cimg_mp_z], oc = mp.mem[_cimg_mp_c]; - const int - x = (int)(ox + _mp_arg(3)), y = (int)(oy + _mp_arg(4)), - z = (int)(oz + _mp_arg(5)), c = (int)(oc + _mp_arg(6)); - const double val = _mp_arg(1); - if (x>=0 && x=0 && y=0 && z=0 && c &img = mp.listout[ind]; - const longT - off = (longT)_mp_arg(3), - whd = (longT)img.width()*img.height()*img.depth(); - const T val = (T)_mp_arg(1); - if (off>=0 && off &img = mp.listout[ind]; - const longT - off = (longT)_mp_arg(3), - whd = (longT)img.width()*img.height()*img.depth(); - const double *ptrs = &_mp_arg(1) + 1; - if (off>=0 && off::nan(); - } - - static double mp_list_set_Ixyz_s(_cimg_math_parser& mp) { - const unsigned int ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()); - CImg &img = mp.listout[ind]; - const int x = (int)_mp_arg(3), y = (int)_mp_arg(4), z = (int)_mp_arg(5); - const T val = (T)_mp_arg(1); - if (x>=0 && x=0 && y=0 && z &img = mp.listout[ind]; - const int x = (int)_mp_arg(3), y = (int)_mp_arg(4), z = (int)_mp_arg(5); - const double *ptrs = &_mp_arg(1) + 1; - if (x>=0 && x=0 && y=0 && z::nan(); - } - - static double mp_list_set_Joff_s(_cimg_math_parser& mp) { - const unsigned int ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()); - CImg &img = mp.listout[ind]; - const int - ox = (int)mp.mem[_cimg_mp_x], oy = (int)mp.mem[_cimg_mp_y], - oz = (int)mp.mem[_cimg_mp_z], oc = (int)mp.mem[_cimg_mp_c]; - const longT - off = img.offset(ox,oy,oz,oc) + (longT)_mp_arg(3), - whd = (longT)img.width()*img.height()*img.depth(); - const T val = (T)_mp_arg(1); - if (off>=0 && off &img = mp.listout[ind]; - const int - ox = (int)mp.mem[_cimg_mp_x], oy = (int)mp.mem[_cimg_mp_y], - oz = (int)mp.mem[_cimg_mp_z], oc = (int)mp.mem[_cimg_mp_c]; - const longT - off = img.offset(ox,oy,oz,oc) + (longT)_mp_arg(3), - whd = (longT)img.width()*img.height()*img.depth(); - const double *ptrs = &_mp_arg(1) + 1; - if (off>=0 && off::nan(); - } - - static double mp_list_set_Jxyz_s(_cimg_math_parser& mp) { - const unsigned int ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()); - CImg &img = mp.listout[ind]; - const double ox = mp.mem[_cimg_mp_x], oy = mp.mem[_cimg_mp_y], oz = mp.mem[_cimg_mp_z]; - const int x = (int)(ox + _mp_arg(3)), y = (int)(oy + _mp_arg(4)), z = (int)(oz + _mp_arg(5)); - const T val = (T)_mp_arg(1); - if (x>=0 && x=0 && y=0 && z &img = mp.listout[ind]; - const double ox = mp.mem[_cimg_mp_x], oy = mp.mem[_cimg_mp_y], oz = mp.mem[_cimg_mp_z]; - const int x = (int)(ox + _mp_arg(3)), y = (int)(oy + _mp_arg(4)), z = (int)(oz + _mp_arg(5)); - const double *ptrs = &_mp_arg(1) + 1; - if (x>=0 && x=0 && y=0 && z::nan(); - } - - static double mp_list_spectrum(_cimg_math_parser& mp) { - const unsigned int ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()); - return (double)mp.listin[ind]._spectrum; - } - - static double mp_list_stats(_cimg_math_parser& mp) { - const unsigned int - ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()), - k = (unsigned int)_mp_arg(3); - if (!mp.list_stats) mp.list_stats.assign(mp.listin._width); - if (!mp.list_stats[ind]) mp.list_stats[ind].assign(1,14,1,1,0).fill(mp.listin[ind].get_stats(),false); - return mp.list_stats(ind,k); - } - - static double mp_list_wh(_cimg_math_parser& mp) { - const unsigned int ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()); - return (double)mp.listin[ind]._width*mp.listin[ind]._height; - } - - static double mp_list_whd(_cimg_math_parser& mp) { - const unsigned int ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()); - return (double)mp.listin[ind]._width*mp.listin[ind]._height*mp.listin[ind]._depth; - } - - static double mp_list_whds(_cimg_math_parser& mp) { - const unsigned int ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()); - return (double)mp.listin[ind]._width*mp.listin[ind]._height*mp.listin[ind]._depth*mp.listin[ind]._spectrum; - } - - static double mp_list_width(_cimg_math_parser& mp) { - const unsigned int ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()); - return (double)mp.listin[ind]._width; - } - - static double mp_list_Ioff(_cimg_math_parser& mp) { - double *ptrd = &_mp_arg(1) + 1; - const unsigned int - ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()), - boundary_conditions = (unsigned int)_mp_arg(4); - const CImg &img = mp.listin[ind]; - const longT - off = (longT)_mp_arg(3), - whd = (longT)img.width()*img.height()*img.depth(); - const T *ptrs; - if (off<0 || off>=whd) - switch (boundary_conditions) { - case 2 : // Periodic boundary - if (img) { - ptrs = &img[cimg::mod(off,whd)]; - cimg_forC(img,c) { *(ptrd++) = *ptrs; ptrs+=whd; } - } else std::memset(ptrd,0,img._spectrum*sizeof(double)); - return cimg::type::nan(); - case 1 : // Neumann boundary - if (img) { - ptrs = off<0?img._data:&img.back(); - cimg_forC(img,c) { *(ptrd++) = *ptrs; ptrs+=whd; } - } else std::memset(ptrd,0,img._spectrum*sizeof(double)); - return cimg::type::nan(); - default : // Dirichet boundary - std::memset(ptrd,0,img._spectrum*sizeof(double)); - return cimg::type::nan(); - } - ptrs = &img[off]; - cimg_forC(img,c) { *(ptrd++) = *ptrs; ptrs+=whd; } - return cimg::type::nan(); - } - - static double mp_list_Ixyz(_cimg_math_parser& mp) { - double *ptrd = &_mp_arg(1) + 1; - const unsigned int - ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()), - interpolation = (unsigned int)_mp_arg(6), - boundary_conditions = (unsigned int)_mp_arg(7); - const CImg &img = mp.listin[ind]; - const double x = _mp_arg(3), y = _mp_arg(4), z = _mp_arg(5); - if (interpolation==0) { // Nearest neighbor interpolation - if (boundary_conditions==2) - cimg_forC(img,c) - *(ptrd++) = (double)img.atXYZ(cimg::mod((int)x,img.width()), - cimg::mod((int)y,img.height()), - cimg::mod((int)z,img.depth()), - c); - else if (boundary_conditions==1) - cimg_forC(img,c) - *(ptrd++) = (double)img.atXYZ((int)x,(int)y,(int)z,c); - else - cimg_forC(img,c) - *(ptrd++) = (double)img.atXYZ((int)x,(int)y,(int)z,c,0); - } else { // Linear interpolation - if (boundary_conditions==2) - cimg_forC(img,c) - *(ptrd++) = (double)img.linear_atXYZ(cimg::mod((float)x,(float)img.width()), - cimg::mod((float)y,(float)img.height()), - cimg::mod((float)z,(float)img.depth()),c); - else if (boundary_conditions==1) - cimg_forC(img,c) - *(ptrd++) = (double)img.linear_atXYZ((float)x,(float)y,(float)z,c); - else - cimg_forC(img,c) - *(ptrd++) = (double)img.linear_atXYZ((float)x,(float)y,(float)z,c,0); - } - return cimg::type::nan(); - } - - static double mp_list_Joff(_cimg_math_parser& mp) { - double *ptrd = &_mp_arg(1) + 1; - const unsigned int - ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()), - boundary_conditions = (unsigned int)_mp_arg(4); - const int - ox = (int)mp.mem[_cimg_mp_x], oy = (int)mp.mem[_cimg_mp_y], oz = (int)mp.mem[_cimg_mp_z]; - const CImg &img = mp.listin[ind]; - const longT - off = img.offset(ox,oy,oz) + (longT)_mp_arg(3), - whd = (longT)img.width()*img.height()*img.depth(); - const T *ptrs; - if (off<0 || off>=whd) - switch (boundary_conditions) { - case 2 : // Periodic boundary - if (img) { - ptrs = &img[cimg::mod(off,whd)]; - cimg_forC(img,c) { *(ptrd++) = *ptrs; ptrs+=whd; } - } else std::memset(ptrd,0,img._spectrum*sizeof(double)); - return cimg::type::nan(); - case 1 : // Neumann boundary - if (img) { - ptrs = off<0?img._data:&img.back(); - cimg_forC(img,c) { *(ptrd++) = *ptrs; ptrs+=whd; } - } else std::memset(ptrd,0,img._spectrum*sizeof(double)); - return cimg::type::nan(); - default : // Dirichet boundary - std::memset(ptrd,0,img._spectrum*sizeof(double)); - return cimg::type::nan(); - } - ptrs = &img[off]; - cimg_forC(img,c) { *(ptrd++) = *ptrs; ptrs+=whd; } - return cimg::type::nan(); - } - - static double mp_list_Jxyz(_cimg_math_parser& mp) { - double *ptrd = &_mp_arg(1) + 1; - const unsigned int - ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.listin.width()), - interpolation = (unsigned int)_mp_arg(6), - boundary_conditions = (unsigned int)_mp_arg(7); - const CImg &img = mp.listin[ind]; - const double - ox = mp.mem[_cimg_mp_x], oy = mp.mem[_cimg_mp_y], oz = mp.mem[_cimg_mp_z], - x = ox + _mp_arg(3), y = oy + _mp_arg(4), z = oz + _mp_arg(5); - if (interpolation==0) { // Nearest neighbor interpolation - if (boundary_conditions==2) - cimg_forC(img,c) - *(ptrd++) = (double)img.atXYZ(cimg::mod((int)x,img.width()), - cimg::mod((int)y,img.height()), - cimg::mod((int)z,img.depth()), - c); - else if (boundary_conditions==1) - cimg_forC(img,c) - *(ptrd++) = (double)img.atXYZ((int)x,(int)y,(int)z,c); - else - cimg_forC(img,c) - *(ptrd++) = (double)img.atXYZ((int)x,(int)y,(int)z,c,0); - } else { // Linear interpolation - if (boundary_conditions==2) - cimg_forC(img,c) - *(ptrd++) = (double)img.linear_atXYZ(cimg::mod((float)x,(float)img.width()), - cimg::mod((float)y,(float)img.height()), - cimg::mod((float)z,(float)img.depth()),c); - else if (boundary_conditions==1) - cimg_forC(img,c) - *(ptrd++) = (double)img.linear_atXYZ((float)x,(float)y,(float)z,c); - else - cimg_forC(img,c) - *(ptrd++) = (double)img.linear_atXYZ((float)x,(float)y,(float)z,c,0); - } - return cimg::type::nan(); - } - - static double mp_log(_cimg_math_parser& mp) { - return std::log(_mp_arg(2)); - } - - static double mp_log10(_cimg_math_parser& mp) { - return std::log10(_mp_arg(2)); - } - - static double mp_log2(_cimg_math_parser& mp) { - return cimg::log2(_mp_arg(2)); - } - - static double mp_logical_and(_cimg_math_parser& mp) { - const bool val_left = (bool)_mp_arg(2); - const CImg *const p_end = ++mp.p_code + mp.opcode[4]; - if (!val_left) { mp.p_code = p_end - 1; return 0; } - const ulongT mem_right = mp.opcode[3]; - for ( ; mp.p_code &op = *mp.p_code; - mp.opcode._data = op._data; mp.opcode._height = op._height; - const ulongT target = mp.opcode[1]; - mp.mem[target] = _cimg_mp_defunc(mp); - } - --mp.p_code; - return (double)(bool)mp.mem[mem_right]; - } - - static double mp_logical_not(_cimg_math_parser& mp) { - return (double)!_mp_arg(2); - } - - static double mp_logical_or(_cimg_math_parser& mp) { - const bool val_left = (bool)_mp_arg(2); - const CImg *const p_end = ++mp.p_code + mp.opcode[4]; - if (val_left) { mp.p_code = p_end - 1; return 1; } - const ulongT mem_right = mp.opcode[3]; - for ( ; mp.p_code &op = *mp.p_code; - mp.opcode._data = op._data; mp.opcode._height = op._height; - const ulongT target = mp.opcode[1]; - mp.mem[target] = _cimg_mp_defunc(mp); - } - --mp.p_code; - return (double)(bool)mp.mem[mem_right]; - } - - static double mp_lowercase(_cimg_math_parser& mp) { - return cimg::lowercase(_mp_arg(2)); - } - - static double mp_lt(_cimg_math_parser& mp) { - return (double)(_mp_arg(2)<_mp_arg(3)); - } - - static double mp_lte(_cimg_math_parser& mp) { - return (double)(_mp_arg(2)<=_mp_arg(3)); - } - - static double mp_matrix_mul(_cimg_math_parser& mp) { - double *ptrd = &_mp_arg(1) + 1; - const double - *ptr1 = &_mp_arg(2) + 1, - *ptr2 = &_mp_arg(3) + 1; - const unsigned int - k = (unsigned int)mp.opcode(4), - l = (unsigned int)mp.opcode(5), - m = (unsigned int)mp.opcode(6); - CImg(ptrd,m,k,1,1,true) = CImg(ptr1,l,k,1,1,true)*CImg(ptr2,m,l,1,1,true); - return cimg::type::nan(); - } - - static double mp_max(_cimg_math_parser& mp) { - double val = _mp_arg(2); - for (unsigned int i = 3; i=mp.mem.width()) - throw CImgArgumentException("[_cimg_math_parser] CImg<%s>: Function 'copy()': " - "Out-of-bounds variable pointer " - "(length: %ld, increment: %ld, offset start: %ld, " - "offset end: %ld, offset max: %u).", - mp.imgin.pixel_type(),siz,inc,off,eoff,mp.mem._width - 1); - return &mp.mem[off]; - } - - static float* _mp_memcopy_float(_cimg_math_parser& mp, const ulongT *const p_ref, - const longT siz, const long inc) { - const unsigned ind = (unsigned int)p_ref[1]; - const CImg &img = ind==~0U?mp.imgin:mp.listin[cimg::mod((int)mp.mem[ind],mp.listin.width())]; - const bool is_relative = (bool)p_ref[2]; - int ox, oy, oz, oc; - longT off = 0; - if (is_relative) { - ox = (int)mp.mem[_cimg_mp_x]; - oy = (int)mp.mem[_cimg_mp_y]; - oz = (int)mp.mem[_cimg_mp_z]; - oc = (int)mp.mem[_cimg_mp_c]; - off = img.offset(ox,oy,oz,oc); - } - if ((*p_ref)%2) { - const int - x = (int)mp.mem[p_ref[3]], - y = (int)mp.mem[p_ref[4]], - z = (int)mp.mem[p_ref[5]], - c = *p_ref==5?0:(int)mp.mem[p_ref[6]]; - off+=img.offset(x,y,z,c); - } else off+=(longT)mp.mem[p_ref[3]]; - const longT eoff = off + (siz - 1)*inc; - if (off<0 || eoff>=(longT)img.size()) - throw CImgArgumentException("[_cimg_math_parser] CImg<%s>: Function 'copy()': " - "Out-of-bounds image pointer " - "(length: %ld, increment: %ld, offset start: %ld, " - "offset end: %ld, offset max: %lu).", - mp.imgin.pixel_type(),siz,inc,off,eoff,img.size() - 1); - return (float*)&img[off]; - } - - static double mp_memcopy(_cimg_math_parser& mp) { - longT siz = (longT)_mp_arg(4); - const longT inc_d = (longT)_mp_arg(5), inc_s = (longT)_mp_arg(6); - if (siz>0) { - const bool - is_doubled = mp.opcode[7]<=1, - is_doubles = mp.opcode[14]<=1; - if (is_doubled && is_doubles) { // (double*) <- (double*) - double *ptrd = _mp_memcopy_double(mp,(unsigned int)mp.opcode[2],&mp.opcode[7],siz,inc_d); - const double *ptrs = _mp_memcopy_double(mp,(unsigned int)mp.opcode[3],&mp.opcode[14],siz,inc_s); - if (inc_d==1 && inc_s==1) { - if (ptrs + siz - 1ptrd + siz - 1) std::memcpy(ptrd,ptrs,siz*sizeof(double)); - else std::memmove(ptrd,ptrs,siz*sizeof(double)); - } else { - if (ptrs + (siz - 1)*inc_sptrd + (siz - 1)*inc_d) - while (siz-->0) { *ptrd = (double)*ptrs; ptrd+=inc_d; ptrs+=inc_s; } - else { // Overlapping buffers - CImg buf((unsigned int)siz); - cimg_for(buf,ptr,double) { *ptr = *ptrs; ptrs+=inc_s; } - ptrs = buf; - while (siz-->0) { *ptrd = *(ptrs++); ptrd+=inc_d; } - } - } - } else if (is_doubled && !is_doubles) { // (double*) <- (float*) - double *ptrd = _mp_memcopy_double(mp,(unsigned int)mp.opcode[2],&mp.opcode[7],siz,inc_d); - const float *ptrs = _mp_memcopy_float(mp,&mp.opcode[14],siz,inc_s); - while (siz-->0) { *ptrd = (double)*ptrs; ptrd+=inc_d; ptrs+=inc_s; } - } else if (!is_doubled && is_doubles) { // (float*) <- (double*) - float *ptrd = _mp_memcopy_float(mp,&mp.opcode[7],siz,inc_d); - const double *ptrs = _mp_memcopy_double(mp,(unsigned int)mp.opcode[3],&mp.opcode[14],siz,inc_s); - while (siz-->0) { *ptrd = (float)*ptrs; ptrd+=inc_d; ptrs+=inc_s; } - } else { // (float*) <- (float*) - float *ptrd = _mp_memcopy_float(mp,&mp.opcode[7],siz,inc_d); - const float *ptrs = _mp_memcopy_float(mp,&mp.opcode[14],siz,inc_s); - if (inc_d==1 && inc_s==1) { - if (ptrs + siz - 1ptrd + siz - 1) std::memcpy(ptrd,ptrs,siz*sizeof(float)); - else std::memmove(ptrd,ptrs,siz*sizeof(float)); - } else { - if (ptrs + (siz - 1)*inc_sptrd + (siz - 1)*inc_d) - while (siz-->0) { *ptrd = (float)*ptrs; ptrd+=inc_d; ptrs+=inc_s; } - else { // Overlapping buffers - CImg buf((unsigned int)siz); - cimg_for(buf,ptr,float) { *ptr = *ptrs; ptrs+=inc_s; } - ptrs = buf; - while (siz-->0) { *ptrd = *(ptrs++); ptrd+=inc_d; } - } - } - } - } - return _mp_arg(1); - } - - static double mp_min(_cimg_math_parser& mp) { - double val = _mp_arg(2); - for (unsigned int i = 3; i vals(mp.opcode._height - 2); - double *p = vals.data(); - for (unsigned int i = 2; ires) res = val; - } - return res; - } - - static double mp_normp(_cimg_math_parser& mp) { - const double p = (double)mp.opcode[2]; - double res = 0; - for (unsigned int i = 3; i0?res:0.0; - } - - static double mp_permutations(_cimg_math_parser& mp) { - return cimg::permutations(_mp_arg(2),_mp_arg(3),(bool)_mp_arg(4)); - } - - static double mp_pow(_cimg_math_parser& mp) { - const double v = _mp_arg(2), p = _mp_arg(3); - return std::pow(v,p); - } - - static double mp_pow3(_cimg_math_parser& mp) { - const double val = _mp_arg(2); - return val*val*val; - } - - static double mp_pow4(_cimg_math_parser& mp) { - const double val = _mp_arg(2); - return val*val*val*val; - } - - static double mp_print(_cimg_math_parser& mp) { - const double val = _mp_arg(1); - cimg_pragma_openmp(critical) - { - CImg expr(mp.opcode._height - 2); - const ulongT *ptrs = mp.opcode._data + 2; - cimg_for(expr,ptrd,char) *ptrd = (char)*(ptrs++); - cimg::strellipsize(expr); - cimg::mutex(6); - std::fprintf(cimg::output(),"\n[_cimg_math_parser] %s = %g",expr._data,val); - std::fflush(cimg::output()); - cimg::mutex(6,0); - } - return val; - } - - static double mp_prod(_cimg_math_parser& mp) { - double val = _mp_arg(2); - for (unsigned int i = 3; i::nan(); - } - - static double mp_rot3d(_cimg_math_parser& mp) { - double *ptrd = &_mp_arg(1) + 1; - const float x = (float)_mp_arg(2), y = (float)_mp_arg(3), z = (float)_mp_arg(4), theta = (float)_mp_arg(5); - CImg(ptrd,3,3,1,1,true) = CImg::rotation_matrix(x,y,z,theta); - return cimg::type::nan(); - } - - static double mp_round(_cimg_math_parser& mp) { - return cimg::round(_mp_arg(2),_mp_arg(3),(int)_mp_arg(4)); - } - - static double mp_self_add(_cimg_math_parser& mp) { - return _mp_arg(1)+=_mp_arg(2); - } - - static double mp_self_bitwise_and(_cimg_math_parser& mp) { - double &val = _mp_arg(1); - return val = (double)((ulongT)val & (ulongT)_mp_arg(2)); - } - - static double mp_self_bitwise_left_shift(_cimg_math_parser& mp) { - double &val = _mp_arg(1); - return val = (double)((longT)val<<(unsigned int)_mp_arg(2)); - } - - static double mp_self_bitwise_or(_cimg_math_parser& mp) { - double &val = _mp_arg(1); - return val = (double)((ulongT)val | (ulongT)_mp_arg(2)); - } - - static double mp_self_bitwise_right_shift(_cimg_math_parser& mp) { - double &val = _mp_arg(1); - return val = (double)((longT)val>>(unsigned int)_mp_arg(2)); - } - - static double mp_self_decrement(_cimg_math_parser& mp) { - return --_mp_arg(1); - } - - static double mp_self_increment(_cimg_math_parser& mp) { - return ++_mp_arg(1); - } - - static double mp_self_map_vector_s(_cimg_math_parser& mp) { // Vector += scalar - unsigned int - ptrd = (unsigned int)mp.opcode[1] + 1, - siz = (unsigned int)mp.opcode[2]; - mp_func op = (mp_func)mp.opcode[3]; - CImg l_opcode(1,3); - l_opcode[2] = mp.opcode[4]; // Scalar argument. - l_opcode.swap(mp.opcode); - ulongT &target = mp.opcode[1]; - while (siz-->0) { target = ptrd++; (*op)(mp); } - l_opcode.swap(mp.opcode); - return cimg::type::nan(); - } - - static double mp_self_map_vector_v(_cimg_math_parser& mp) { // Vector += vector - unsigned int - ptrd = (unsigned int)mp.opcode[1] + 1, - siz = (unsigned int)mp.opcode[2], - ptrs = (unsigned int)mp.opcode[4] + 1; - mp_func op = (mp_func)mp.opcode[3]; - CImg l_opcode(1,4); - l_opcode.swap(mp.opcode); - ulongT &target = mp.opcode[1], &argument = mp.opcode[2]; - while (siz-->0) { target = ptrd++; argument = ptrs++; (*op)(mp); } - l_opcode.swap(mp.opcode); - return cimg::type::nan(); - } - - static double mp_self_mul(_cimg_math_parser& mp) { - return _mp_arg(1)*=_mp_arg(2); - } - - static double mp_self_div(_cimg_math_parser& mp) { - return _mp_arg(1)/=_mp_arg(2); - } - - static double mp_self_modulo(_cimg_math_parser& mp) { - double &val = _mp_arg(1); - return val = cimg::mod(val,_mp_arg(2)); - } - - static double mp_self_pow(_cimg_math_parser& mp) { - double &val = _mp_arg(1); - return val = std::pow(val,_mp_arg(2)); - } - - static double mp_self_sub(_cimg_math_parser& mp) { - return _mp_arg(1)-=_mp_arg(2); - } - - static double mp_set_ioff(_cimg_math_parser& mp) { - CImg &img = mp.imgout; - const longT - off = (longT)_mp_arg(2), - whds = (longT)img.size(); - const double val = _mp_arg(1); - if (off>=0 && off &img = mp.imgout; - const int - x = (int)_mp_arg(2), y = (int)_mp_arg(3), - z = (int)_mp_arg(4), c = (int)_mp_arg(5); - const double val = _mp_arg(1); - if (x>=0 && x=0 && y=0 && z=0 && c &img = mp.imgout; - const int - ox = (int)mp.mem[_cimg_mp_x], oy = (int)mp.mem[_cimg_mp_y], - oz = (int)mp.mem[_cimg_mp_z], oc = (int)mp.mem[_cimg_mp_c]; - const longT - off = img.offset(ox,oy,oz,oc) + (longT)_mp_arg(2), - whds = (longT)img.size(); - const double val = _mp_arg(1); - if (off>=0 && off &img = mp.imgout; - const double - ox = mp.mem[_cimg_mp_x], oy = mp.mem[_cimg_mp_y], - oz = mp.mem[_cimg_mp_z], oc = mp.mem[_cimg_mp_c]; - const int - x = (int)(ox + _mp_arg(2)), y = (int)(oy + _mp_arg(3)), - z = (int)(oz + _mp_arg(4)), c = (int)(oc + _mp_arg(5)); - const double val = _mp_arg(1); - if (x>=0 && x=0 && y=0 && z=0 && c &img = mp.imgout; - const longT - off = (longT)_mp_arg(2), - whd = (longT)img.width()*img.height()*img.depth(); - const T val = (T)_mp_arg(1); - if (off>=0 && off &img = mp.imgout; - const longT - off = (longT)_mp_arg(2), - whd = (longT)img.width()*img.height()*img.depth(); - const double *ptrs = &_mp_arg(1) + 1; - if (off>=0 && off::nan(); - } - - static double mp_set_Ixyz_s(_cimg_math_parser& mp) { - CImg &img = mp.imgout; - const int x = (int)_mp_arg(2), y = (int)_mp_arg(3), z = (int)_mp_arg(4); - const T val = (T)_mp_arg(1); - if (x>=0 && x=0 && y=0 && z &img = mp.imgout; - const int x = (int)_mp_arg(2), y = (int)_mp_arg(3), z = (int)_mp_arg(4); - const double *ptrs = &_mp_arg(1) + 1; - if (x>=0 && x=0 && y=0 && z::nan(); - } - - static double mp_set_Joff_s(_cimg_math_parser& mp) { - CImg &img = mp.imgout; - const int - ox = (int)mp.mem[_cimg_mp_x], oy = (int)mp.mem[_cimg_mp_y], - oz = (int)mp.mem[_cimg_mp_z], oc = (int)mp.mem[_cimg_mp_c]; - const longT - off = img.offset(ox,oy,oz,oc) + (longT)_mp_arg(2), - whd = (longT)img.width()*img.height()*img.depth(); - const T val = (T)_mp_arg(1); - if (off>=0 && off &img = mp.imgout; - const int - ox = (int)mp.mem[_cimg_mp_x], oy = (int)mp.mem[_cimg_mp_y], - oz = (int)mp.mem[_cimg_mp_z], oc = (int)mp.mem[_cimg_mp_c]; - const longT - off = img.offset(ox,oy,oz,oc) + (longT)_mp_arg(2), - whd = (longT)img.width()*img.height()*img.depth(); - const double *ptrs = &_mp_arg(1) + 1; - if (off>=0 && off::nan(); - } - - static double mp_set_Jxyz_s(_cimg_math_parser& mp) { - CImg &img = mp.imgout; - const double ox = mp.mem[_cimg_mp_x], oy = mp.mem[_cimg_mp_y], oz = mp.mem[_cimg_mp_z]; - const int x = (int)(ox + _mp_arg(2)), y = (int)(oy + _mp_arg(3)), z = (int)(oz + _mp_arg(4)); - const T val = (T)_mp_arg(1); - if (x>=0 && x=0 && y=0 && z &img = mp.imgout; - const double ox = mp.mem[_cimg_mp_x], oy = mp.mem[_cimg_mp_y], oz = mp.mem[_cimg_mp_z]; - const int x = (int)(ox + _mp_arg(2)), y = (int)(oy + _mp_arg(3)), z = (int)(oz + _mp_arg(4)); - const double *ptrs = &_mp_arg(1) + 1; - if (x>=0 && x=0 && y=0 && z::nan(); - } - - static double mp_sign(_cimg_math_parser& mp) { - return cimg::sign(_mp_arg(2)); - } - - static double mp_sin(_cimg_math_parser& mp) { - return std::sin(_mp_arg(2)); - } - - static double mp_sinc(_cimg_math_parser& mp) { - return cimg::sinc(_mp_arg(2)); - } - - static double mp_single(_cimg_math_parser& mp) { - const double res = _mp_arg(1); - cimg_pragma_openmp(critical) - { - for (const CImg *const p_end = ++mp.p_code + mp.opcode[2]; - mp.p_code &op = *mp.p_code; - mp.opcode._data = op._data; mp.opcode._height = op._height; - const ulongT target = mp.opcode[1]; - mp.mem[target] = _cimg_mp_defunc(mp); - } - } - --mp.p_code; - return res; - } - - static double mp_sinh(_cimg_math_parser& mp) { - return std::sinh(_mp_arg(2)); - } - - static double mp_solve(_cimg_math_parser& mp) { - double *ptrd = &_mp_arg(1) + 1; - const double - *ptr1 = &_mp_arg(2) + 1, - *ptr2 = &_mp_arg(3) + 1; - const unsigned int - k = (unsigned int)mp.opcode(4), - l = (unsigned int)mp.opcode(5), - m = (unsigned int)mp.opcode(6); - CImg(ptrd,m,k,1,1,true) = CImg(ptr2,m,l,1,1,true).get_solve(CImg(ptr1,k,l,1,1,true)); - return cimg::type::nan(); - } - - static double mp_sort(_cimg_math_parser& mp) { - double *const ptrd = &_mp_arg(1) + 1; - const double *const ptrs = &_mp_arg(2) + 1; - const unsigned int - siz = (unsigned int)mp.opcode[3], - chunk_siz = (unsigned int)mp.opcode[5]; - const bool is_increasing = (bool)_mp_arg(4); - CImg(ptrd,chunk_siz,siz/chunk_siz,1,1,true) = CImg(ptrs,chunk_siz,siz/chunk_siz,1,1,true). - get_sort(is_increasing,chunk_siz>1?'y':0); - return cimg::type::nan(); - } - - static double mp_sqr(_cimg_math_parser& mp) { - return cimg::sqr(_mp_arg(2)); - } - - static double mp_sqrt(_cimg_math_parser& mp) { - return std::sqrt(_mp_arg(2)); - } - - static double mp_std(_cimg_math_parser& mp) { - CImg vals(mp.opcode._height - 2); - double *p = vals.data(); - for (unsigned int i = 2; i0) mp.mem[ptrd++] = (double)*(ptrs++); - return cimg::type::nan(); - } - - static double mp_stod(_cimg_math_parser& mp) { - const double *ptrs = &_mp_arg(2); - const unsigned int siz = (unsigned int)_mp_arg(3); - const bool is_strict = (bool)_mp_arg(4); - if (!siz) return *ptrs>='0' && *ptrs<='9'?*ptrs - '0':cimg::type::nan(); - CImg ss(siz + 1); - double val = cimg::type::nan(); - char sep; - for (unsigned i = 0; i::inf(); err = 1; } - else if (!cimg::strcasecmp(s,"nan")) { val = cimg::type::nan(); err = 1; } - if (err==1 && !is_positive) val = -val; - } -#endif - if (is_strict && err!=1) return cimg::type::nan(); - return val; - } - - static double mp_sub(_cimg_math_parser& mp) { - return _mp_arg(2) - _mp_arg(3); - } - - static double mp_sum(_cimg_math_parser& mp) { - double val = _mp_arg(2); - for (unsigned int i = 3; i(ptrs,k,k,1,1,true).trace(); - } - - static double mp_transp(_cimg_math_parser& mp) { - double *ptrd = &_mp_arg(1) + 1; - const double *ptrs = &_mp_arg(2) + 1; - const unsigned int - k = (unsigned int)mp.opcode(3), - l = (unsigned int)mp.opcode(4); - CImg(ptrd,l,k,1,1,true) = CImg(ptrs,k,l,1,1,true).get_transpose(); - return cimg::type::nan(); - } - - static double mp_u(_cimg_math_parser& mp) { - return cimg::rand(_mp_arg(2),_mp_arg(3)); - } - - static double mp_uppercase(_cimg_math_parser& mp) { - return cimg::uppercase(_mp_arg(2)); - } - - static double mp_variance(_cimg_math_parser& mp) { - CImg vals(mp.opcode._height - 2); - double *p = vals.data(); - for (unsigned int i = 2; i::nan(); - } - - static double mp_vector_crop(_cimg_math_parser& mp) { - double *const ptrd = &_mp_arg(1) + 1; - const double *const ptrs = &_mp_arg(2) + 1; - const unsigned int p1 = (unsigned int)mp.opcode[3], p2 = (unsigned int)mp.opcode[4]; - std::memcpy(ptrd,ptrs + p1,p2*sizeof(double)); - return cimg::type::nan(); - } - - static double mp_vector_init(_cimg_math_parser& mp) { - unsigned int - ptrs = 3U, - ptrd = (unsigned int)mp.opcode[1] + 1, - siz = (unsigned int)mp.opcode[2]; - switch (mp.opcode._height) { - case 3 : std::memset(mp.mem._data + ptrd,0,siz*sizeof(double)); break; // 0 values given - case 4 : { const double val = _mp_arg(ptrs); while (siz-->0) mp.mem[ptrd++] = val; } break; - default : while (siz-->0) { mp.mem[ptrd++] = _mp_arg(ptrs++); if (ptrs>=mp.opcode._height) ptrs = 3U; } - } - return cimg::type::nan(); - } - - static double mp_vector_eq(_cimg_math_parser& mp) { - const double - *ptr1 = &_mp_arg(2) + 1, - *ptr2 = &_mp_arg(4) + 1; - unsigned int p1 = (unsigned int)mp.opcode[3], p2 = (unsigned int)mp.opcode[5], n; - const int N = (int)_mp_arg(6); - const bool case_sensitive = (bool)_mp_arg(7); - bool still_equal = true; - double value; - if (!N) return true; - - // Compare all values. - if (N<0) { - if (p1>0 && p2>0) { // Vector == vector - if (p1!=p2) return false; - if (case_sensitive) - while (still_equal && p1--) still_equal = *(ptr1++)==*(ptr2++); - else - while (still_equal && p1--) - still_equal = cimg::lowercase(*(ptr1++))==cimg::lowercase(*(ptr2++)); - return still_equal; - } else if (p1>0 && !p2) { // Vector == scalar - value = _mp_arg(4); - if (!case_sensitive) value = cimg::lowercase(value); - while (still_equal && p1--) still_equal = *(ptr1++)==value; - return still_equal; - } else if (!p1 && p2>0) { // Scalar == vector - value = _mp_arg(2); - if (!case_sensitive) value = cimg::lowercase(value); - while (still_equal && p2--) still_equal = *(ptr2++)==value; - return still_equal; - } else { // Scalar == scalar - if (case_sensitive) return _mp_arg(2)==_mp_arg(4); - else return cimg::lowercase(_mp_arg(2))==cimg::lowercase(_mp_arg(4)); - } - } - - // Compare only first N values. - if (p1>0 && p2>0) { // Vector == vector - n = cimg::min((unsigned int)N,p1,p2); - if (case_sensitive) - while (still_equal && n--) still_equal = *(ptr1++)==(*ptr2++); - else - while (still_equal && n--) still_equal = cimg::lowercase(*(ptr1++))==cimg::lowercase(*(ptr2++)); - return still_equal; - } else if (p1>0 && !p2) { // Vector == scalar - n = cimg::min((unsigned int)N,p1); - value = _mp_arg(4); - if (!case_sensitive) value = cimg::lowercase(value); - while (still_equal && n--) still_equal = *(ptr1++)==value; - return still_equal; - } else if (!p1 && p2>0) { // Scalar == vector - n = cimg::min((unsigned int)N,p2); - value = _mp_arg(2); - if (!case_sensitive) value = cimg::lowercase(value); - while (still_equal && n--) still_equal = *(ptr2++)==value; - return still_equal; - } // Scalar == scalar - if (case_sensitive) return _mp_arg(2)==_mp_arg(4); - return cimg::lowercase(_mp_arg(2))==cimg::lowercase(_mp_arg(4)); - } - - static double mp_vector_off(_cimg_math_parser& mp) { - const unsigned int - ptr = (unsigned int)mp.opcode[2] + 1, - siz = (unsigned int)mp.opcode[3]; - const int off = (int)_mp_arg(4); - return off>=0 && off<(int)siz?mp.mem[ptr + off]:cimg::type::nan(); - } - - static double mp_vector_map_sv(_cimg_math_parser& mp) { // Operator(scalar,vector) - unsigned int - siz = (unsigned int)mp.opcode[2], - ptrs = (unsigned int)mp.opcode[5] + 1; - double *ptrd = &_mp_arg(1) + 1; - mp_func op = (mp_func)mp.opcode[3]; - CImg l_opcode(4); - l_opcode[2] = mp.opcode[4]; // Scalar argument1 - l_opcode.swap(mp.opcode); - ulongT &argument2 = mp.opcode[3]; - while (siz-->0) { argument2 = ptrs++; *(ptrd++) = (*op)(mp); } - l_opcode.swap(mp.opcode); - return cimg::type::nan(); - } - - static double mp_vector_map_v(_cimg_math_parser& mp) { // Operator(vector) - unsigned int - siz = (unsigned int)mp.opcode[2], - ptrs = (unsigned int)mp.opcode[4] + 1; - double *ptrd = &_mp_arg(1) + 1; - mp_func op = (mp_func)mp.opcode[3]; - CImg l_opcode(1,3); - l_opcode.swap(mp.opcode); - ulongT &argument = mp.opcode[2]; - while (siz-->0) { argument = ptrs++; *(ptrd++) = (*op)(mp); } - l_opcode.swap(mp.opcode); - return cimg::type::nan(); - } - - static double mp_vector_map_vs(_cimg_math_parser& mp) { // Operator(vector,scalar) - unsigned int - siz = (unsigned int)mp.opcode[2], - ptrs = (unsigned int)mp.opcode[4] + 1; - double *ptrd = &_mp_arg(1) + 1; - mp_func op = (mp_func)mp.opcode[3]; - CImg l_opcode(1,4); - l_opcode[3] = mp.opcode[5]; // Scalar argument2 - l_opcode.swap(mp.opcode); - ulongT &argument1 = mp.opcode[2]; - while (siz-->0) { argument1 = ptrs++; *(ptrd++) = (*op)(mp); } - l_opcode.swap(mp.opcode); - return cimg::type::nan(); - } - - static double mp_vector_map_vss(_cimg_math_parser& mp) { // Operator(vector,scalar,scalar) - unsigned int - siz = (unsigned int)mp.opcode[2], - ptrs = (unsigned int)mp.opcode[4] + 1; - double *ptrd = &_mp_arg(1) + 1; - mp_func op = (mp_func)mp.opcode[3]; - CImg l_opcode(1,5); - l_opcode[3] = mp.opcode[5]; // Scalar argument2 - l_opcode[4] = mp.opcode[6]; // Scalar argument3 - l_opcode.swap(mp.opcode); - ulongT &argument1 = mp.opcode[2]; - while (siz-->0) { argument1 = ptrs++; *(ptrd++) = (*op)(mp); } - l_opcode.swap(mp.opcode); - return cimg::type::nan(); - } - - static double mp_vector_map_vv(_cimg_math_parser& mp) { // Operator(vector,vector) - unsigned int - siz = (unsigned int)mp.opcode[2], - ptrs1 = (unsigned int)mp.opcode[4] + 1, - ptrs2 = (unsigned int)mp.opcode[5] + 1; - double *ptrd = &_mp_arg(1) + 1; - mp_func op = (mp_func)mp.opcode[3]; - CImg l_opcode(1,4); - l_opcode.swap(mp.opcode); - ulongT &argument1 = mp.opcode[2], &argument2 = mp.opcode[3]; - while (siz-->0) { argument1 = ptrs1++; argument2 = ptrs2++; *(ptrd++) = (*op)(mp); } - l_opcode.swap(mp.opcode); - return cimg::type::nan(); - } - - static double mp_vector_neq(_cimg_math_parser& mp) { - return !mp_vector_eq(mp); - } - - static double mp_vector_print(_cimg_math_parser& mp) { - cimg_pragma_openmp(critical) - { - CImg expr(mp.opcode._height - 3); - const ulongT *ptrs = mp.opcode._data + 3; - cimg_for(expr,ptrd,char) *ptrd = (char)*(ptrs++); - cimg::strellipsize(expr); - unsigned int - ptr = (unsigned int)mp.opcode[1] + 1, - siz0 = (unsigned int)mp.opcode[2], - siz = siz0; - cimg::mutex(6); - std::fprintf(cimg::output(),"\n[_cimg_math_parser] %s = [",expr._data); - while (siz-->0) std::fprintf(cimg::output(),"%g%s",mp.mem[ptr++],siz?",":""); - std::fprintf(cimg::output(),"] (size: %u)",siz0); - std::fflush(cimg::output()); - cimg::mutex(6,0); - } - return cimg::type::nan(); - } - - static double mp_vector_resize(_cimg_math_parser& mp) { - double *const ptrd = &_mp_arg(1) + 1; - const unsigned int p1 = (unsigned int)mp.opcode[2], p2 = (unsigned int)mp.opcode[4]; - const int interpolation = (int)_mp_arg(5); - if (p2) { // Resize vector - const double *const ptrs = &_mp_arg(3) + 1; - CImg(ptrd,p1,1,1,1,true) = CImg(ptrs,p2,1,1,1,true).get_resize(p1,1,1,1,interpolation); - } else { // Resize scalar - const double value = _mp_arg(3); - CImg(ptrd,p1,1,1,1,true) = CImg(1,1,1,1,value).resize(p1,1,1,1,interpolation); - } - return cimg::type::nan(); - } - - static double mp_vector_reverse(_cimg_math_parser& mp) { - double *const ptrd = &_mp_arg(1) + 1; - const double *const ptrs = &_mp_arg(2) + 1; - const unsigned int p1 = (unsigned int)mp.opcode[3]; - CImg(ptrd,p1,1,1,1,true) = CImg(ptrs,p1,1,1,1,true).get_mirror('x'); - return cimg::type::nan(); - } - - static double mp_vector_set_off(_cimg_math_parser& mp) { - const unsigned int - ptr = (unsigned int)mp.opcode[2] + 1, - siz = (unsigned int)mp.opcode[3]; - const int off = (int)_mp_arg(4); - if (off>=0 && off<(int)siz) mp.mem[ptr + off] = _mp_arg(5); - return _mp_arg(5); - } - - static double mp_whiledo(_cimg_math_parser& mp) { // Used also by 'for()' - const ulongT - mem_proc = mp.opcode[1], - mem_cond = mp.opcode[2]; - const CImg - *const p_cond = ++mp.p_code, - *const p_proc = p_cond + mp.opcode[3], - *const p_end = p_proc + mp.opcode[4]; - const unsigned int vsiz = (unsigned int)mp.opcode[5]; - bool is_cond = false; - if (mp.opcode[6]) { // Set default result if inner memory slot and possibly no iterations - if (vsiz) CImg(&mp.mem[mem_proc] + 1,vsiz,1,1,1,true).fill(cimg::type::nan()); - else _mp_arg(1) = cimg::type::nan(); - } - do { - for (mp.p_code = p_cond; mp.p_code &op = *mp.p_code; - mp.opcode._data = op._data; mp.opcode._height = op._height; - const ulongT target = mp.opcode[1]; - mp.mem[target] = _cimg_mp_defunc(mp); - } - is_cond = (bool)mp.mem[mem_cond]; - if (is_cond) { // Evaluate loop iteration - for ( ; mp.p_code &op = *mp.p_code; - mp.opcode._data = op._data; mp.opcode._height = op._height; - const ulongT target = mp.opcode[1]; - mp.mem[target] = _cimg_mp_defunc(mp); - } - } - } while (is_cond); - mp.p_code = p_end - 1; - return mp.mem[mem_proc]; - } - - static double mp_Ioff(_cimg_math_parser& mp) { - double *ptrd = &_mp_arg(1) + 1; - const unsigned int boundary_conditions = (unsigned int)_mp_arg(3); - const CImg &img = mp.imgin; - const longT - off = (longT)_mp_arg(2), - whd = (longT)img.width()*img.height()*img.depth(); - const T *ptrs; - if (off<0 || off>=whd) - switch (boundary_conditions) { - case 2 : // Periodic boundary - if (img) { - ptrs = &img[cimg::mod(off,whd)]; - cimg_forC(img,c) { *(ptrd++) = *ptrs; ptrs+=whd; } - } else std::memset(ptrd,0,img._spectrum*sizeof(double)); - return cimg::type::nan(); - case 1 : // Neumann boundary - if (img) { - ptrs = off<0?img._data:&img[whd - 1]; - cimg_forC(img,c) { *(ptrd++) = *ptrs; ptrs+=whd; } - } else std::memset(ptrd,0,img._spectrum*sizeof(double)); - return cimg::type::nan(); - default : // Dirichet boundary - std::memset(ptrd,0,img._spectrum*sizeof(double)); - return cimg::type::nan(); - } - ptrs = &img[off]; - cimg_forC(img,c) { *(ptrd++) = *ptrs; ptrs+=whd; } - return cimg::type::nan(); - } - - static double mp_Ixyz(_cimg_math_parser& mp) { - double *ptrd = &_mp_arg(1) + 1; - const unsigned int - interpolation = (unsigned int)_mp_arg(5), - boundary_conditions = (unsigned int)_mp_arg(6); - const CImg &img = mp.imgin; - const double x = _mp_arg(2), y = _mp_arg(3), z = _mp_arg(4); - if (interpolation==0) { // Nearest neighbor interpolation - if (boundary_conditions==2) - cimg_forC(img,c) - *(ptrd++) = (double)img.atXYZ(cimg::mod((int)x,img.width()), - cimg::mod((int)y,img.height()), - cimg::mod((int)z,img.depth()), - c); - else if (boundary_conditions==1) - cimg_forC(img,c) - *(ptrd++) = (double)img.atXYZ((int)x,(int)y,(int)z,c); - else - cimg_forC(img,c) - *(ptrd++) = (double)img.atXYZ((int)x,(int)y,(int)z,c,0); - } else { // Linear interpolation - if (boundary_conditions==2) - cimg_forC(img,c) - *(ptrd++) = (double)img.linear_atXYZ(cimg::mod((float)x,(float)img.width()), - cimg::mod((float)y,(float)img.height()), - cimg::mod((float)z,(float)img.depth()),c); - else if (boundary_conditions==1) - cimg_forC(img,c) - *(ptrd++) = (double)img.linear_atXYZ((float)x,(float)y,(float)z,c); - else - cimg_forC(img,c) - *(ptrd++) = (double)img.linear_atXYZ((float)x,(float)y,(float)z,c,0); - } - return cimg::type::nan(); - } - - static double mp_Joff(_cimg_math_parser& mp) { - double *ptrd = &_mp_arg(1) + 1; - const unsigned int boundary_conditions = (unsigned int)_mp_arg(3); - const CImg &img = mp.imgin; - const int ox = (int)mp.mem[_cimg_mp_x], oy = (int)mp.mem[_cimg_mp_y], oz = (int)mp.mem[_cimg_mp_z]; - const longT - off = img.offset(ox,oy,oz) + (longT)_mp_arg(2), - whd = (longT)img.width()*img.height()*img.depth(); - const T *ptrs; - if (off<0 || off>=whd) - switch (boundary_conditions) { - case 2 : // Periodic boundary - if (img) { - ptrs = &img[cimg::mod(off,whd)]; - cimg_forC(img,c) { *(ptrd++) = *ptrs; ptrs+=whd; } - } else std::memset(ptrd,0,img._spectrum*sizeof(double)); - return cimg::type::nan(); - case 1 : // Neumann boundary - if (img) { - ptrs = off<0?img._data:&img[whd - 1]; - cimg_forC(img,c) { *(ptrd++) = *ptrs; ptrs+=whd; } - } else std::memset(ptrd,0,img._spectrum*sizeof(double)); - return cimg::type::nan(); - default : // Dirichet boundary - std::memset(ptrd,0,img._spectrum*sizeof(double)); - return cimg::type::nan(); - } - ptrs = &img[off]; - cimg_forC(img,c) { *(ptrd++) = *ptrs; ptrs+=whd; } - return cimg::type::nan(); - } - - static double mp_Jxyz(_cimg_math_parser& mp) { - double *ptrd = &_mp_arg(1) + 1; - const unsigned int - interpolation = (unsigned int)_mp_arg(5), - boundary_conditions = (unsigned int)_mp_arg(6); - const CImg &img = mp.imgin; - const double - ox = mp.mem[_cimg_mp_x], oy = mp.mem[_cimg_mp_y], oz = mp.mem[_cimg_mp_z], - x = ox + _mp_arg(2), y = oy + _mp_arg(3), z = oz + _mp_arg(4); - if (interpolation==0) { // Nearest neighbor interpolation - if (boundary_conditions==2) - cimg_forC(img,c) - *(ptrd++) = (double)img.atXYZ(cimg::mod((int)x,img.width()), - cimg::mod((int)y,img.height()), - cimg::mod((int)z,img.depth()), - c); - else if (boundary_conditions==1) - cimg_forC(img,c) - *(ptrd++) = (double)img.atXYZ((int)x,(int)y,(int)z,c); - else - cimg_forC(img,c) - *(ptrd++) = (double)img.atXYZ((int)x,(int)y,(int)z,c,0); - } else { // Linear interpolation - if (boundary_conditions==2) - cimg_forC(img,c) - *(ptrd++) = (double)img.linear_atXYZ(cimg::mod((float)x,(float)img.width()), - cimg::mod((float)y,(float)img.height()), - cimg::mod((float)z,(float)img.depth()),c); - else if (boundary_conditions==1) - cimg_forC(img,c) - *(ptrd++) = (double)img.linear_atXYZ((float)x,(float)y,(float)z,c); - else - cimg_forC(img,c) - *(ptrd++) = (double)img.linear_atXYZ((float)x,(float)y,(float)z,c,0); - } - return cimg::type::nan(); - } - -#undef _mp_arg - - }; // struct _cimg_math_parser {} - - //! Compute the square value of each pixel value. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its square value \f$I_{(x,y,z,c)}^2\f$. - \note - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - \par Example - \code - const CImg img("reference.jpg"); - (img,img.get_sqr().normalize(0,255)).display(); - \endcode - \image html ref_sqr.jpg - **/ - CImg& sqr() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=524288)) - cimg_rof(*this,ptrd,T) { const T val = *ptrd; *ptrd = (T)(val*val); }; - return *this; - } - - //! Compute the square value of each pixel value \newinstance. - CImg get_sqr() const { - return CImg(*this,false).sqr(); - } - - //! Compute the square root of each pixel value. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its square root \f$\sqrt{I_{(x,y,z,c)}}\f$. - \note - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - \par Example - \code - const CImg img("reference.jpg"); - (img,img.get_sqrt().normalize(0,255)).display(); - \endcode - \image html ref_sqrt.jpg - **/ - CImg& sqrt() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=8192)) - cimg_rof(*this,ptrd,T) *ptrd = (T)std::sqrt((double)*ptrd); - return *this; - } - - //! Compute the square root of each pixel value \newinstance. - CImg get_sqrt() const { - return CImg(*this,false).sqrt(); - } - - //! Compute the exponential of each pixel value. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its exponential \f$e^{I_{(x,y,z,c)}}\f$. - \note - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - **/ - CImg& exp() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=4096)) - cimg_rof(*this,ptrd,T) *ptrd = (T)std::exp((double)*ptrd); - return *this; - } - - //! Compute the exponential of each pixel value \newinstance. - CImg get_exp() const { - return CImg(*this,false).exp(); - } - - //! Compute the logarithm of each pixel value. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its logarithm - \f$\mathrm{log}_{e}(I_{(x,y,z,c)})\f$. - \note - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - **/ - CImg& log() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=262144)) - cimg_rof(*this,ptrd,T) *ptrd = (T)std::log((double)*ptrd); - return *this; - } - - //! Compute the logarithm of each pixel value \newinstance. - CImg get_log() const { - return CImg(*this,false).log(); - } - - //! Compute the base-2 logarithm of each pixel value. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its base-2 logarithm - \f$\mathrm{log}_{2}(I_{(x,y,z,c)})\f$. - \note - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - **/ - CImg& log2() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=4096)) - cimg_rof(*this,ptrd,T) *ptrd = (T)cimg::log2((double)*ptrd); - return *this; - } - - //! Compute the base-10 logarithm of each pixel value \newinstance. - CImg get_log2() const { - return CImg(*this,false).log2(); - } - - //! Compute the base-10 logarithm of each pixel value. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its base-10 logarithm - \f$\mathrm{log}_{10}(I_{(x,y,z,c)})\f$. - \note - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - **/ - CImg& log10() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=4096)) - cimg_rof(*this,ptrd,T) *ptrd = (T)std::log10((double)*ptrd); - return *this; - } - - //! Compute the base-10 logarithm of each pixel value \newinstance. - CImg get_log10() const { - return CImg(*this,false).log10(); - } - - //! Compute the absolute value of each pixel value. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its absolute value \f$|I_{(x,y,z,c)}|\f$. - \note - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - **/ - CImg& abs() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=524288)) - cimg_rof(*this,ptrd,T) *ptrd = cimg::abs(*ptrd); - return *this; - } - - //! Compute the absolute value of each pixel value \newinstance. - CImg get_abs() const { - return CImg(*this,false).abs(); - } - - //! Compute the sign of each pixel value. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its sign - \f$\mathrm{sign}(I_{(x,y,z,c)})\f$. - \note - - The sign is set to: - - \c 1 if pixel value is strictly positive. - - \c -1 if pixel value is strictly negative. - - \c 0 if pixel value is equal to \c 0. - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - **/ - CImg& sign() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=32768)) - cimg_rof(*this,ptrd,T) *ptrd = cimg::sign(*ptrd); - return *this; - } - - //! Compute the sign of each pixel value \newinstance. - CImg get_sign() const { - return CImg(*this,false).sign(); - } - - //! Compute the cosine of each pixel value. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its cosine \f$\cos(I_{(x,y,z,c)})\f$. - \note - - Pixel values are regarded as being in \e radian. - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - **/ - CImg& cos() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=8192)) - cimg_rof(*this,ptrd,T) *ptrd = (T)std::cos((double)*ptrd); - return *this; - } - - //! Compute the cosine of each pixel value \newinstance. - CImg get_cos() const { - return CImg(*this,false).cos(); - } - - //! Compute the sine of each pixel value. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its sine \f$\sin(I_{(x,y,z,c)})\f$. - \note - - Pixel values are regarded as being in \e radian. - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - **/ - CImg& sin() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=8192)) - cimg_rof(*this,ptrd,T) *ptrd = (T)std::sin((double)*ptrd); - return *this; - } - - //! Compute the sine of each pixel value \newinstance. - CImg get_sin() const { - return CImg(*this,false).sin(); - } - - //! Compute the sinc of each pixel value. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its sinc - \f$\mathrm{sinc}(I_{(x,y,z,c)})\f$. - \note - - Pixel values are regarded as being exin \e radian. - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - **/ - CImg& sinc() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=2048)) - cimg_rof(*this,ptrd,T) *ptrd = (T)cimg::sinc((double)*ptrd); - return *this; - } - - //! Compute the sinc of each pixel value \newinstance. - CImg get_sinc() const { - return CImg(*this,false).sinc(); - } - - //! Compute the tangent of each pixel value. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its tangent \f$\tan(I_{(x,y,z,c)})\f$. - \note - - Pixel values are regarded as being exin \e radian. - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - **/ - CImg& tan() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=2048)) - cimg_rof(*this,ptrd,T) *ptrd = (T)std::tan((double)*ptrd); - return *this; - } - - //! Compute the tangent of each pixel value \newinstance. - CImg get_tan() const { - return CImg(*this,false).tan(); - } - - //! Compute the hyperbolic cosine of each pixel value. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its hyperbolic cosine - \f$\mathrm{cosh}(I_{(x,y,z,c)})\f$. - \note - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - **/ - CImg& cosh() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=2048)) - cimg_rof(*this,ptrd,T) *ptrd = (T)std::cosh((double)*ptrd); - return *this; - } - - //! Compute the hyperbolic cosine of each pixel value \newinstance. - CImg get_cosh() const { - return CImg(*this,false).cosh(); - } - - //! Compute the hyperbolic sine of each pixel value. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its hyperbolic sine - \f$\mathrm{sinh}(I_{(x,y,z,c)})\f$. - \note - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - **/ - CImg& sinh() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=2048)) - cimg_rof(*this,ptrd,T) *ptrd = (T)std::sinh((double)*ptrd); - return *this; - } - - //! Compute the hyperbolic sine of each pixel value \newinstance. - CImg get_sinh() const { - return CImg(*this,false).sinh(); - } - - //! Compute the hyperbolic tangent of each pixel value. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its hyperbolic tangent - \f$\mathrm{tanh}(I_{(x,y,z,c)})\f$. - \note - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - **/ - CImg& tanh() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=2048)) - cimg_rof(*this,ptrd,T) *ptrd = (T)std::tanh((double)*ptrd); - return *this; - } - - //! Compute the hyperbolic tangent of each pixel value \newinstance. - CImg get_tanh() const { - return CImg(*this,false).tanh(); - } - - //! Compute the arccosine of each pixel value. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its arccosine - \f$\mathrm{acos}(I_{(x,y,z,c)})\f$. - \note - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - **/ - CImg& acos() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=8192)) - cimg_rof(*this,ptrd,T) *ptrd = (T)std::acos((double)*ptrd); - return *this; - } - - //! Compute the arccosine of each pixel value \newinstance. - CImg get_acos() const { - return CImg(*this,false).acos(); - } - - //! Compute the arcsine of each pixel value. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its arcsine - \f$\mathrm{asin}(I_{(x,y,z,c)})\f$. - \note - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - **/ - CImg& asin() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=8192)) - cimg_rof(*this,ptrd,T) *ptrd = (T)std::asin((double)*ptrd); - return *this; - } - - //! Compute the arcsine of each pixel value \newinstance. - CImg get_asin() const { - return CImg(*this,false).asin(); - } - - //! Compute the arctangent of each pixel value. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its arctangent - \f$\mathrm{atan}(I_{(x,y,z,c)})\f$. - \note - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - **/ - CImg& atan() { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=8192)) - cimg_rof(*this,ptrd,T) *ptrd = (T)std::atan((double)*ptrd); - return *this; - } - - //! Compute the arctangent of each pixel value \newinstance. - CImg get_atan() const { - return CImg(*this,false).atan(); - } - - //! Compute the arctangent2 of each pixel value. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its arctangent2 - \f$\mathrm{atan2}(I_{(x,y,z,c)})\f$. - \param img Image whose pixel values specify the second argument of the \c atan2() function. - \note - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - \par Example - \code - const CImg - img_x(100,100,1,1,"x-w/2",false), // Define an horizontal centered gradient, from '-width/2' to 'width/2'. - img_y(100,100,1,1,"y-h/2",false), // Define a vertical centered gradient, from '-height/2' to 'height/2'. - img_atan2 = img_y.get_atan2(img_x); // Compute atan2(y,x) for each pixel value. - (img_x,img_y,img_atan2).display(); - \endcode - **/ - template - CImg& atan2(const CImg& img) { - const ulongT siz = size(), isiz = img.size(); - if (siz && isiz) { - if (is_overlapped(img)) return atan2(+img); - T *ptrd = _data, *const ptre = _data + siz; - if (siz>isiz) for (ulongT n = siz/isiz; n; --n) - for (const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs - CImg get_atan2(const CImg& img) const { - return CImg(*this,false).atan2(img); - } - - //! In-place pointwise multiplication. - /** - Compute the pointwise multiplication between the image instance and the specified input image \c img. - \param img Input image, as the second operand of the multiplication. - \note - - Similar to operator+=(const CImg&), except that it performs a pointwise multiplication - instead of an addition. - - It does \e not perform a \e matrix multiplication. For this purpose, use operator*=(const CImg&) instead. - \par Example - \code - CImg - img("reference.jpg"), - shade(img.width,img.height(),1,1,"-(x-w/2)^2-(y-h/2)^2",false); - shade.normalize(0,1); - (img,shade,img.get_mul(shade)).display(); - \endcode - **/ - template - CImg& mul(const CImg& img) { - const ulongT siz = size(), isiz = img.size(); - if (siz && isiz) { - if (is_overlapped(img)) return mul(+img); - T *ptrd = _data, *const ptre = _data + siz; - if (siz>isiz) for (ulongT n = siz/isiz; n; --n) - for (const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs - CImg<_cimg_Tt> get_mul(const CImg& img) const { - return CImg<_cimg_Tt>(*this,false).mul(img); - } - - //! In-place pointwise division. - /** - Similar to mul(const CImg&), except that it performs a pointwise division instead of a multiplication. - **/ - template - CImg& div(const CImg& img) { - const ulongT siz = size(), isiz = img.size(); - if (siz && isiz) { - if (is_overlapped(img)) return div(+img); - T *ptrd = _data, *const ptre = _data + siz; - if (siz>isiz) for (ulongT n = siz/isiz; n; --n) - for (const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs - CImg<_cimg_Tt> get_div(const CImg& img) const { - return CImg<_cimg_Tt>(*this,false).div(img); - } - - //! Raise each pixel value to a specified power. - /** - Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its power \f$I_{(x,y,z,c)}^p\f$. - \param p Exponent value. - \note - - The \inplace of this method statically casts the computed values to the pixel type \c T. - - The \newinstance returns a \c CImg image, if the pixel type \c T is \e not float-valued. - \par Example - \code - const CImg - img0("reference.jpg"), // Load reference color image. - img1 = (img0/255).pow(1.8)*=255, // Compute gamma correction, with gamma = 1.8. - img2 = (img0/255).pow(0.5)*=255; // Compute gamma correction, with gamma = 0.5. - (img0,img1,img2).display(); - \endcode - **/ - CImg& pow(const double p) { - if (is_empty()) return *this; - if (p==-4) { - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=32768)) - cimg_rof(*this,ptrd,T) { const T val = *ptrd; *ptrd = (T)(1.0/(val*val*val*val)); } - return *this; - } - if (p==-3) { - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=32768)) - cimg_rof(*this,ptrd,T) { const T val = *ptrd; *ptrd = (T)(1.0/(val*val*val)); } - return *this; - } - if (p==-2) { - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=32768)) - cimg_rof(*this,ptrd,T) { const T val = *ptrd; *ptrd = (T)(1.0/(val*val)); } - return *this; - } - if (p==-1) { - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=32768)) - cimg_rof(*this,ptrd,T) { const T val = *ptrd; *ptrd = (T)(1.0/val); } - return *this; - } - if (p==-0.5) { - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=8192)) - cimg_rof(*this,ptrd,T) { const T val = *ptrd; *ptrd = (T)(1/std::sqrt((double)val)); } - return *this; - } - if (p==0) return fill(1); - if (p==0.5) return sqrt(); - if (p==1) return *this; - if (p==2) return sqr(); - if (p==3) { - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=262144)) - cimg_rof(*this,ptrd,T) { const T val = *ptrd; *ptrd = val*val*val; } - return *this; - } - if (p==4) { - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=131072)) - cimg_rof(*this,ptrd,T) { const T val = *ptrd; *ptrd = val*val*val*val; } - return *this; - } - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=1024)) - cimg_rof(*this,ptrd,T) *ptrd = (T)std::pow((double)*ptrd,p); - return *this; - } - - //! Raise each pixel value to a specified power \newinstance. - CImg get_pow(const double p) const { - return CImg(*this,false).pow(p); - } - - //! Raise each pixel value to a power, specified from an expression. - /** - Similar to operator+=(const char*), except it performs a pointwise exponentiation instead of an addition. - **/ - CImg& pow(const char *const expression) { - return pow((+*this)._fill(expression,true,true,0,0,"pow",this)); - } - - //! Raise each pixel value to a power, specified from an expression \newinstance. - CImg get_pow(const char *const expression) const { - return CImg(*this,false).pow(expression); - } - - //! Raise each pixel value to a power, pointwisely specified from another image. - /** - Similar to operator+=(const CImg& img), except that it performs an exponentiation instead of an addition. - **/ - template - CImg& pow(const CImg& img) { - const ulongT siz = size(), isiz = img.size(); - if (siz && isiz) { - if (is_overlapped(img)) return pow(+img); - T *ptrd = _data, *const ptre = _data + siz; - if (siz>isiz) for (ulongT n = siz/isiz; n; --n) - for (const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs - CImg get_pow(const CImg& img) const { - return CImg(*this,false).pow(img); - } - - //! Compute the bitwise left rotation of each pixel value. - /** - Similar to operator<<=(unsigned int), except that it performs a left rotation instead of a left shift. - **/ - CImg& rol(const unsigned int n=1) { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=32768)) - cimg_rof(*this,ptrd,T) *ptrd = (T)cimg::rol(*ptrd,n); - return *this; - } - - //! Compute the bitwise left rotation of each pixel value \newinstance. - CImg get_rol(const unsigned int n=1) const { - return (+*this).rol(n); - } - - //! Compute the bitwise left rotation of each pixel value. - /** - Similar to operator<<=(const char*), except that it performs a left rotation instead of a left shift. - **/ - CImg& rol(const char *const expression) { - return rol((+*this)._fill(expression,true,true,0,0,"rol",this)); - } - - //! Compute the bitwise left rotation of each pixel value \newinstance. - CImg get_rol(const char *const expression) const { - return (+*this).rol(expression); - } - - //! Compute the bitwise left rotation of each pixel value. - /** - Similar to operator<<=(const CImg&), except that it performs a left rotation instead of a left shift. - **/ - template - CImg& rol(const CImg& img) { - const ulongT siz = size(), isiz = img.size(); - if (siz && isiz) { - if (is_overlapped(img)) return rol(+img); - T *ptrd = _data, *const ptre = _data + siz; - if (siz>isiz) for (ulongT n = siz/isiz; n; --n) - for (const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs - CImg get_rol(const CImg& img) const { - return (+*this).rol(img); - } - - //! Compute the bitwise right rotation of each pixel value. - /** - Similar to operator>>=(unsigned int), except that it performs a right rotation instead of a right shift. - **/ - CImg& ror(const unsigned int n=1) { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=32768)) - cimg_rof(*this,ptrd,T) *ptrd = (T)cimg::ror(*ptrd,n); - return *this; - } - - //! Compute the bitwise right rotation of each pixel value \newinstance. - CImg get_ror(const unsigned int n=1) const { - return (+*this).ror(n); - } - - //! Compute the bitwise right rotation of each pixel value. - /** - Similar to operator>>=(const char*), except that it performs a right rotation instead of a right shift. - **/ - CImg& ror(const char *const expression) { - return ror((+*this)._fill(expression,true,true,0,0,"ror",this)); - } - - //! Compute the bitwise right rotation of each pixel value \newinstance. - CImg get_ror(const char *const expression) const { - return (+*this).ror(expression); - } - - //! Compute the bitwise right rotation of each pixel value. - /** - Similar to operator>>=(const CImg&), except that it performs a right rotation instead of a right shift. - **/ - template - CImg& ror(const CImg& img) { - const ulongT siz = size(), isiz = img.size(); - if (siz && isiz) { - if (is_overlapped(img)) return ror(+img); - T *ptrd = _data, *const ptre = _data + siz; - if (siz>isiz) for (ulongT n = siz/isiz; n; --n) - for (const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs - CImg get_ror(const CImg& img) const { - return (+*this).ror(img); - } - - //! Pointwise min operator between instance image and a value. - /** - \param val Value used as the reference argument of the min operator. - \note Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by - \f$\mathrm{min}(I_{(x,y,z,c)},\mathrm{val})\f$. - **/ - CImg& min(const T& val) { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=65536)) - cimg_rof(*this,ptrd,T) *ptrd = cimg::min(*ptrd,val); - return *this; - } - - //! Pointwise min operator between instance image and a value \newinstance. - CImg get_min(const T& val) const { - return (+*this).min(val); - } - - //! Pointwise min operator between two images. - /** - \param img Image used as the reference argument of the min operator. - \note Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by - \f$\mathrm{min}(I_{(x,y,z,c)},\mathrm{img}_{(x,y,z,c)})\f$. - **/ - template - CImg& min(const CImg& img) { - const ulongT siz = size(), isiz = img.size(); - if (siz && isiz) { - if (is_overlapped(img)) return min(+img); - T *ptrd = _data, *const ptre = _data + siz; - if (siz>isiz) for (ulongT n = siz/isiz; n; --n) - for (const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs - CImg<_cimg_Tt> get_min(const CImg& img) const { - return CImg<_cimg_Tt>(*this,false).min(img); - } - - //! Pointwise min operator between an image and an expression. - /** - \param expression Math formula as a C-string. - \note Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by - \f$\mathrm{min}(I_{(x,y,z,c)},\mathrm{expr}_{(x,y,z,c)})\f$. - **/ - CImg& min(const char *const expression) { - return min((+*this)._fill(expression,true,true,0,0,"min",this)); - } - - //! Pointwise min operator between an image and an expression \newinstance. - CImg get_min(const char *const expression) const { - return CImg(*this,false).min(expression); - } - - //! Pointwise max operator between instance image and a value. - /** - \param val Value used as the reference argument of the max operator. - \note Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by - \f$\mathrm{max}(I_{(x,y,z,c)},\mathrm{val})\f$. - **/ - CImg& max(const T& val) { - if (is_empty()) return *this; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=65536)) - cimg_rof(*this,ptrd,T) *ptrd = cimg::max(*ptrd,val); - return *this; - } - - //! Pointwise max operator between instance image and a value \newinstance. - CImg get_max(const T& val) const { - return (+*this).max(val); - } - - //! Pointwise max operator between two images. - /** - \param img Image used as the reference argument of the max operator. - \note Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by - \f$\mathrm{max}(I_{(x,y,z,c)},\mathrm{img}_{(x,y,z,c)})\f$. - **/ - template - CImg& max(const CImg& img) { - const ulongT siz = size(), isiz = img.size(); - if (siz && isiz) { - if (is_overlapped(img)) return max(+img); - T *ptrd = _data, *const ptre = _data + siz; - if (siz>isiz) for (ulongT n = siz/isiz; n; --n) - for (const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs - CImg<_cimg_Tt> get_max(const CImg& img) const { - return CImg<_cimg_Tt>(*this,false).max(img); - } - - //! Pointwise max operator between an image and an expression. - /** - \param expression Math formula as a C-string. - \note Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by - \f$\mathrm{max}(I_{(x,y,z,c)},\mathrm{expr}_{(x,y,z,c)})\f$. - **/ - CImg& max(const char *const expression) { - return max((+*this)._fill(expression,true,true,0,0,"max",this)); - } - - //! Pointwise max operator between an image and an expression \newinstance. - CImg get_max(const char *const expression) const { - return CImg(*this,false).max(expression); - } - - //! Return a reference to the minimum pixel value. - /** - **/ - T& min() { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "min(): Empty instance.", - cimg_instance); - T *ptr_min = _data; - T min_value = *ptr_min; - cimg_for(*this,ptrs,T) if (*ptrsmax_value) max_value = *(ptr_max=ptrs); - return *ptr_max; - } - - //! Return a reference to the maximum pixel value \const. - const T& max() const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "max(): Empty instance.", - cimg_instance); - const T *ptr_max = _data; - T max_value = *ptr_max; - cimg_for(*this,ptrs,T) if (*ptrs>max_value) max_value = *(ptr_max=ptrs); - return *ptr_max; - } - - //! Return a reference to the minimum pixel value as well as the maximum pixel value. - /** - \param[out] max_val Maximum pixel value. - **/ - template - T& min_max(t& max_val) { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "min_max(): Empty instance.", - cimg_instance); - T *ptr_min = _data; - T min_value = *ptr_min, max_value = min_value; - cimg_for(*this,ptrs,T) { - const T val = *ptrs; - if (valmax_value) max_value = val; - } - max_val = (t)max_value; - return *ptr_min; - } - - //! Return a reference to the minimum pixel value as well as the maximum pixel value \const. - template - const T& min_max(t& max_val) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "min_max(): Empty instance.", - cimg_instance); - const T *ptr_min = _data; - T min_value = *ptr_min, max_value = min_value; - cimg_for(*this,ptrs,T) { - const T val = *ptrs; - if (valmax_value) max_value = val; - } - max_val = (t)max_value; - return *ptr_min; - } - - //! Return a reference to the maximum pixel value as well as the minimum pixel value. - /** - \param[out] min_val Minimum pixel value. - **/ - template - T& max_min(t& min_val) { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "max_min(): Empty instance.", - cimg_instance); - T *ptr_max = _data; - T max_value = *ptr_max, min_value = max_value; - cimg_for(*this,ptrs,T) { - const T val = *ptrs; - if (val>max_value) { max_value = val; ptr_max = ptrs; } - if (val - const T& max_min(t& min_val) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "max_min(): Empty instance.", - cimg_instance); - const T *ptr_max = _data; - T max_value = *ptr_max, min_value = max_value; - cimg_for(*this,ptrs,T) { - const T val = *ptrs; - if (val>max_value) { max_value = val; ptr_max = ptrs; } - if (val arr(*this); - ulongT l = 0, ir = size() - 1; - for ( ; ; ) { - if (ir<=l + 1) { - if (ir==l + 1 && arr[ir]>1; - cimg::swap(arr[mid],arr[l + 1]); - if (arr[l]>arr[ir]) cimg::swap(arr[l],arr[ir]); - if (arr[l + 1]>arr[ir]) cimg::swap(arr[l + 1],arr[ir]); - if (arr[l]>arr[l + 1]) cimg::swap(arr[l],arr[l + 1]); - ulongT i = l + 1, j = ir; - const T pivot = arr[l + 1]; - for ( ; ; ) { - do ++i; while (arr[i]pivot); - if (j=k) ir = j - 1; - if (j<=k) l = i; - } - } - } - - //! Return the median pixel value. - /** - **/ - T median() const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "median(): Empty instance.", - cimg_instance); - const ulongT s = size(); - const T res = kth_smallest((unsigned int)(s>>1)); - return (s%2)?res:((res + kth_smallest((s>>1) - 1))/2); - } - - //! Return the product of all the pixel values. - /** - **/ - double product() const { - if (is_empty()) return 0; - double res = 1; - cimg_for(*this,ptrs,T) res*=(double)*ptrs; - return res; - } - - //! Return the sum of all the pixel values. - /** - **/ - double sum() const { - double res = 0; - cimg_for(*this,ptrs,T) res+=(double)*ptrs; - return res; - } - - //! Return the average pixel value. - /** - **/ - double mean() const { - double res = 0; - cimg_for(*this,ptrs,T) res+=(double)*ptrs; - return res/size(); - } - - //! Return the variance of the pixel values. - /** - \param variance_method Method used to estimate the variance. Can be: - - \c 0: Second moment, computed as - \f$1/N \sum\limits_{k=1}^{N} (x_k - \bar x)^2 = - 1/N \left( \sum\limits_{k=1}^N x_k^2 - \left( \sum\limits_{k=1}^N x_k \right)^2 / N \right)\f$ - with \f$ \bar x = 1/N \sum\limits_{k=1}^N x_k \f$. - - \c 1: Best unbiased estimator, computed as \f$\frac{1}{N - 1} \sum\limits_{k=1}^{N} (x_k - \bar x)^2 \f$. - - \c 2: Least median of squares. - - \c 3: Least trimmed of squares. - **/ - double variance(const unsigned int variance_method=1) const { - double foo; - return variance_mean(variance_method,foo); - } - - //! Return the variance as well as the average of the pixel values. - /** - \param variance_method Method used to estimate the variance (see variance(const unsigned int) const). - \param[out] mean Average pixel value. - **/ - template - double variance_mean(const unsigned int variance_method, t& mean) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "variance_mean(): Empty instance.", - cimg_instance); - - double variance = 0, average = 0; - const ulongT siz = size(); - switch (variance_method) { - case 0 : { // Least mean square (standard definition) - double S = 0, S2 = 0; - cimg_for(*this,ptrs,T) { const double val = (double)*ptrs; S+=val; S2+=val*val; } - variance = (S2 - S*S/siz)/siz; - average = S; - } break; - case 1 : { // Least mean square (robust definition) - double S = 0, S2 = 0; - cimg_for(*this,ptrs,T) { const double val = (double)*ptrs; S+=val; S2+=val*val; } - variance = siz>1?(S2 - S*S/siz)/(siz - 1):0; - average = S; - } break; - case 2 : { // Least Median of Squares (MAD) - CImg buf(*this,false); - buf.sort(); - const ulongT siz2 = siz>>1; - const double med_i = (double)buf[siz2]; - cimg_for(buf,ptrs,Tfloat) { - const double val = (double)*ptrs; *ptrs = (Tfloat)cimg::abs(val - med_i); average+=val; - } - buf.sort(); - const double sig = (double)(1.4828*buf[siz2]); - variance = sig*sig; - } break; - default : { // Least trimmed of Squares - CImg buf(*this,false); - const ulongT siz2 = siz>>1; - cimg_for(buf,ptrs,Tfloat) { - const double val = (double)*ptrs; (*ptrs)=(Tfloat)((*ptrs)*val); average+=val; - } - buf.sort(); - double a = 0; - const Tfloat *ptrs = buf._data; - for (ulongT j = 0; j0?variance:0; - } - - //! Return estimated variance of the noise. - /** - \param variance_method Method used to compute the variance (see variance(const unsigned int) const). - \note Because of structures such as edges in images it is - recommanded to use a robust variance estimation. The variance of the - noise is estimated by computing the variance of the Laplacian \f$(\Delta - I)^2 \f$ scaled by a factor \f$c\f$ insuring \f$ c E[(\Delta I)^2]= - \sigma^2\f$ where \f$\sigma\f$ is the noise variance. - **/ - double variance_noise(const unsigned int variance_method=2) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "variance_noise(): Empty instance.", - cimg_instance); - - const ulongT siz = size(); - if (!siz || !_data) return 0; - if (variance_method>1) { // Compute a scaled version of the Laplacian. - CImg tmp(*this); - if (_depth==1) { - const double cste = 1.0/std::sqrt(20.0); // Depends on how the Laplacian is computed. - cimg_pragma_openmp(parallel for cimg_openmp_if(_width*_height>=262144 && _spectrum>=2)) - cimg_forC(*this,c) { - CImg_3x3(I,T); - cimg_for3x3(*this,x,y,0,c,I,T) { - tmp(x,y,c) = cste*((double)Inc + (double)Ipc + (double)Icn + - (double)Icp - 4*(double)Icc); - } - } - } else { - const double cste = 1.0/std::sqrt(42.0); // Depends on how the Laplacian is computed. - cimg_pragma_openmp(parallel for cimg_openmp_if(_width*_height*_depth>=262144 && _spectrum>=2)) - cimg_forC(*this,c) { - CImg_3x3x3(I,T); - cimg_for3x3x3(*this,x,y,z,c,I,T) { - tmp(x,y,z,c) = cste*( - (double)Incc + (double)Ipcc + (double)Icnc + (double)Icpc + - (double)Iccn + (double)Iccp - 6*(double)Iccc); - } - } - } - return tmp.variance(variance_method); - } - - // Version that doesn't need intermediate images. - double variance = 0, S = 0, S2 = 0; - if (_depth==1) { - const double cste = 1.0/std::sqrt(20.0); - CImg_3x3(I,T); - cimg_forC(*this,c) cimg_for3x3(*this,x,y,0,c,I,T) { - const double val = cste*((double)Inc + (double)Ipc + - (double)Icn + (double)Icp - 4*(double)Icc); - S+=val; S2+=val*val; - } - } else { - const double cste = 1.0/std::sqrt(42.0); - CImg_3x3x3(I,T); - cimg_forC(*this,c) cimg_for3x3x3(*this,x,y,z,c,I,T) { - const double val = cste * - ((double)Incc + (double)Ipcc + (double)Icnc + - (double)Icpc + - (double)Iccn + (double)Iccp - 6*(double)Iccc); - S+=val; S2+=val*val; - } - } - if (variance_method) variance = siz>1?(S2 - S*S/siz)/(siz - 1):0; - else variance = (S2 - S*S/siz)/siz; - return variance>0?variance:0; - } - - //! Compute the MSE (Mean-Squared Error) between two images. - /** - \param img Image used as the second argument of the MSE operator. - **/ - template - double MSE(const CImg& img) const { - if (img.size()!=size()) - throw CImgArgumentException(_cimg_instance - "MSE(): Instance and specified image (%u,%u,%u,%u,%p) have different dimensions.", - cimg_instance, - img._width,img._height,img._depth,img._spectrum,img._data); - double vMSE = 0; - const t* ptr2 = img._data; - cimg_for(*this,ptr1,T) { - const double diff = (double)*ptr1 - (double)*(ptr2++); - vMSE+=diff*diff; - } - const ulongT siz = img.size(); - if (siz) vMSE/=siz; - return vMSE; - } - - //! Compute the PSNR (Peak Signal-to-Noise Ratio) between two images. - /** - \param img Image used as the second argument of the PSNR operator. - \param max_value Maximum theoretical value of the signal. - **/ - template - double PSNR(const CImg& img, const double max_value=255) const { - const double vMSE = (double)std::sqrt(MSE(img)); - return (vMSE!=0)?(double)(20*std::log10(max_value/vMSE)):(double)(cimg::type::max()); - } - - //! Evaluate math formula. - /** - \param expression Math formula, as a C-string. - \param x Value of the pre-defined variable \c x. - \param y Value of the pre-defined variable \c y. - \param z Value of the pre-defined variable \c z. - \param c Value of the pre-defined variable \c c. - \param list_inputs A list of input images attached to the specified math formula. - \param list_outputs A pointer to a list of output images attached to the specified math formula. - **/ - double eval(const char *const expression, - const double x=0, const double y=0, const double z=0, const double c=0, - const CImgList *const list_inputs=0, CImgList *const list_outputs=0) { - return _eval(this,expression,x,y,z,c,list_inputs,list_outputs); - } - - //! Evaluate math formula \const. - double eval(const char *const expression, - const double x=0, const double y=0, const double z=0, const double c=0, - const CImgList *const list_inputs=0, CImgList *const list_outputs=0) const { - return _eval(0,expression,x,y,z,c,list_inputs,list_outputs); - } - - double _eval(CImg *const img_output, const char *const expression, - const double x, const double y, const double z, const double c, - const CImgList *const list_inputs, CImgList *const list_outputs) const { - if (!expression) return 0; - if (!expression[1]) switch (*expression) { // Single-char optimization. - case 'w' : return (double)_width; - case 'h' : return (double)_height; - case 'd' : return (double)_depth; - case 's' : return (double)_spectrum; - case 'r' : return (double)_is_shared; - } - _cimg_math_parser mp(expression + (*expression=='>' || *expression=='<' || - *expression=='*' || *expression==':'),"eval", - *this,img_output,list_inputs,list_outputs); - return mp(x,y,z,c); - } - - //! Evaluate math formula. - /** - \param[out] output Contains values of output vector returned by the evaluated expression - (or is empty if the returned type is scalar). - \param expression Math formula, as a C-string. - \param x Value of the pre-defined variable \c x. - \param y Value of the pre-defined variable \c y. - \param z Value of the pre-defined variable \c z. - \param c Value of the pre-defined variable \c c. - \param list_inputs A list of input images attached to the specified math formula. - \param list_outputs A pointer to a list of output images attached to the specified math formula. - **/ - template - void eval(CImg &output, const char *const expression, - const double x=0, const double y=0, const double z=0, const double c=0, - const CImgList *const list_inputs=0, CImgList *const list_outputs=0) { - _eval(output,this,expression,x,y,z,c,list_inputs,list_outputs); - } - - //! Evaluate math formula \const. - template - void eval(CImg& output, const char *const expression, - const double x=0, const double y=0, const double z=0, const double c=0, - const CImgList *const list_inputs=0, CImgList *const list_outputs=0) const { - _eval(output,0,expression,x,y,z,c,list_inputs,list_outputs); - } - - template - void _eval(CImg& output, CImg *const img_output, const char *const expression, - const double x, const double y, const double z, const double c, - const CImgList *const list_inputs, CImgList *const list_outputs) const { - if (!expression) { output.assign(1); *output = 0; } - if (!expression[1]) switch (*expression) { // Single-char optimization. - case 'w' : output.assign(1); *output = (t)_width; - case 'h' : output.assign(1); *output = (t)_height; - case 'd' : output.assign(1); *output = (t)_depth; - case 's' : output.assign(1); *output = (t)_spectrum; - case 'r' : output.assign(1); *output = (t)_is_shared; - } - _cimg_math_parser mp(expression + (*expression=='>' || *expression=='<' || - *expression=='*' || *expression==':'),"eval", - *this,img_output,list_inputs,list_outputs); - output.assign(1,cimg::max(1U,mp.result_dim)); - mp(x,y,z,c,output._data); - } - - //! Evaluate math formula on a set of variables. - /** - \param expression Math formula, as a C-string. - \param xyzc Set of values (x,y,z,c) used for the evaluation. - **/ - template - CImg eval(const char *const expression, const CImg& xyzc, - const CImgList *const list_inputs=0, CImgList *const list_outputs=0) { - return _eval(this,expression,xyzc,list_inputs,list_outputs); - } - - //! Evaluate math formula on a set of variables \const. - template - CImg eval(const char *const expression, const CImg& xyzc, - const CImgList *const list_inputs=0, CImgList *const list_outputs=0) const { - return _eval(0,expression,xyzc,list_inputs,list_outputs); - } - - template - CImg _eval(CImg *const output, const char *const expression, const CImg& xyzc, - const CImgList *const list_inputs=0, CImgList *const list_outputs=0) const { - CImg res(1,xyzc.size()/4); - if (!expression) return res.fill(0); - _cimg_math_parser mp(expression,"eval",*this,output,list_inputs,list_outputs); -#ifdef cimg_use_openmp - cimg_pragma_openmp(parallel if (res._height>=512 && std::strlen(expression)>=6)) - { - _cimg_math_parser _mp = omp_get_thread_num()?mp:_cimg_math_parser(), &lmp = omp_get_thread_num()?_mp:mp; - cimg_pragma_openmp(for) - for (unsigned int i = 0; i[min; max; mean; variance; xmin; ymin; zmin; cmin; xmax; ymax; zmax; cmax; sum; product]. - **/ - CImg get_stats(const unsigned int variance_method=1) const { - if (is_empty()) return CImg(); - const ulongT siz = size(); - const T *const odata = _data; - const T *pm = odata, *pM = odata; - double S = 0, S2 = 0, P = _data?1:0; - T m = *pm, M = m; - cimg_for(*this,ptrs,T) { - const T val = *ptrs; - const double _val = (double)val; - if (valM) { M = val; pM = ptrs; } - S+=_val; - S2+=_val*_val; - P*=_val; - } - const double - mean_value = S/siz, - _variance_value = variance_method==0?(S2 - S*S/siz)/siz: - (variance_method==1?(siz>1?(S2 - S*S/siz)/(siz - 1):0): - variance(variance_method)), - variance_value = _variance_value>0?_variance_value:0; - int - xm = 0, ym = 0, zm = 0, cm = 0, - xM = 0, yM = 0, zM = 0, cM = 0; - contains(*pm,xm,ym,zm,cm); - contains(*pM,xM,yM,zM,cM); - return CImg(1,14).fill((double)m,(double)M,mean_value,variance_value, - (double)xm,(double)ym,(double)zm,(double)cm, - (double)xM,(double)yM,(double)zM,(double)cM, - S,P); - } - - //! Compute statistics vector from the pixel values \inplace. - CImg& stats(const unsigned int variance_method=1) { - return get_stats(variance_method).move_to(*this); - } - - //@} - //------------------------------------- - // - //! \name Vector / Matrix Operations - //@{ - //------------------------------------- - - //! Compute norm of the image, viewed as a matrix. - /** - \param magnitude_type Norm type. Can be: - - \c -1: Linf-norm - - \c 0: L2-norm - - \c 1: L1-norm - **/ - double magnitude(const int magnitude_type=2) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "magnitude(): Empty instance.", - cimg_instance); - double res = 0; - switch (magnitude_type) { - case -1 : { - cimg_for(*this,ptrs,T) { const double val = (double)cimg::abs(*ptrs); if (val>res) res = val; } - } break; - case 1 : { - cimg_for(*this,ptrs,T) res+=(double)cimg::abs(*ptrs); - } break; - default : { - cimg_for(*this,ptrs,T) res+=(double)cimg::sqr(*ptrs); - res = (double)std::sqrt(res); - } - } - return res; - } - - //! Compute the trace of the image, viewed as a matrix. - /** - **/ - double trace() const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "trace(): Empty instance.", - cimg_instance); - double res = 0; - cimg_forX(*this,k) res+=(double)(*this)(k,k); - return res; - } - - //! Compute the determinant of the image, viewed as a matrix. - /** - **/ - double det() const { - if (is_empty() || _width!=_height || _depth!=1 || _spectrum!=1) - throw CImgInstanceException(_cimg_instance - "det(): Instance is not a square matrix.", - cimg_instance); - - switch (_width) { - case 1 : return (double)((*this)(0,0)); - case 2 : return (double)((*this)(0,0))*(double)((*this)(1,1)) - (double)((*this)(0,1))*(double)((*this)(1,0)); - case 3 : { - const double - a = (double)_data[0], d = (double)_data[1], g = (double)_data[2], - b = (double)_data[3], e = (double)_data[4], h = (double)_data[5], - c = (double)_data[6], f = (double)_data[7], i = (double)_data[8]; - return i*a*e - a*h*f - i*b*d + b*g*f + c*d*h - c*g*e; - } - default : { - CImg lu(*this); - CImg indx; - bool d; - lu._LU(indx,d); - double res = d?(double)1:(double)-1; - cimg_forX(lu,i) res*=lu(i,i); - return res; - } - } - } - - //! Compute the dot product between instance and argument, viewed as matrices. - /** - \param img Image used as a second argument of the dot product. - **/ - template - double dot(const CImg& img) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "dot(): Empty instance.", - cimg_instance); - if (!img) - throw CImgArgumentException(_cimg_instance - "dot(): Empty specified image.", - cimg_instance); - - const ulongT nb = cimg::min(size(),img.size()); - double res = 0; - for (ulongT off = 0; off get_vector_at(const unsigned int x, const unsigned int y=0, const unsigned int z=0) const { - CImg res; - if (res._height!=_spectrum) res.assign(1,_spectrum); - const ulongT whd = (ulongT)_width*_height*_depth; - const T *ptrs = data(x,y,z); - T *ptrd = res._data; - cimg_forC(*this,c) { *(ptrd++) = *ptrs; ptrs+=whd; } - return res; - } - - //! Get (square) matrix-valued pixel located at specified position. - /** - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \note - The spectrum() of the image must be a square. - **/ - CImg get_matrix_at(const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) const { - const int n = (int)std::sqrt((double)_spectrum); - const T *ptrs = data(x,y,z,0); - const ulongT whd = (ulongT)_width*_height*_depth; - CImg res(n,n); - T *ptrd = res._data; - cimg_forC(*this,c) { *(ptrd++) = *ptrs; ptrs+=whd; } - return res; - } - - //! Get tensor-valued pixel located at specified position. - /** - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - **/ - CImg get_tensor_at(const unsigned int x, const unsigned int y=0, const unsigned int z=0) const { - const T *ptrs = data(x,y,z,0); - const ulongT whd = (ulongT)_width*_height*_depth; - if (_spectrum==6) - return tensor(*ptrs,*(ptrs + whd),*(ptrs + 2*whd),*(ptrs + 3*whd),*(ptrs + 4*whd),*(ptrs + 5*whd)); - if (_spectrum==3) - return tensor(*ptrs,*(ptrs + whd),*(ptrs + 2*whd)); - return tensor(*ptrs); - } - - //! Set vector-valued pixel at specified position. - /** - \param vec Vector to put on the instance image. - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - **/ - template - CImg& set_vector_at(const CImg& vec, const unsigned int x, const unsigned int y=0, const unsigned int z=0) { - if (x<_width && y<_height && z<_depth) { - const t *ptrs = vec._data; - const ulongT whd = (ulongT)_width*_height*_depth; - T *ptrd = data(x,y,z); - for (unsigned int k = cimg::min((unsigned int)vec.size(),_spectrum); k; --k) { - *ptrd = (T)*(ptrs++); ptrd+=whd; - } - } - return *this; - } - - //! Set (square) matrix-valued pixel at specified position. - /** - \param mat Matrix to put on the instance image. - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - **/ - template - CImg& set_matrix_at(const CImg& mat, const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) { - return set_vector_at(mat,x,y,z); - } - - //! Set tensor-valued pixel at specified position. - /** - \param ten Tensor to put on the instance image. - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - **/ - template - CImg& set_tensor_at(const CImg& ten, const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) { - T *ptrd = data(x,y,z,0); - const ulongT siz = (ulongT)_width*_height*_depth; - if (ten._height==2) { - *ptrd = (T)ten[0]; ptrd+=siz; - *ptrd = (T)ten[1]; ptrd+=siz; - *ptrd = (T)ten[3]; - } - else { - *ptrd = (T)ten[0]; ptrd+=siz; - *ptrd = (T)ten[1]; ptrd+=siz; - *ptrd = (T)ten[2]; ptrd+=siz; - *ptrd = (T)ten[4]; ptrd+=siz; - *ptrd = (T)ten[5]; ptrd+=siz; - *ptrd = (T)ten[8]; - } - return *this; - } - - //! Unroll pixel values along axis \c y. - /** - \note Equivalent to \code unroll('y'); \endcode. - **/ - CImg& vector() { - return unroll('y'); - } - - //! Unroll pixel values along axis \c y \newinstance. - CImg get_vector() const { - return get_unroll('y'); - } - - //! Resize image to become a scalar square matrix. - /** - **/ - CImg& matrix() { - const ulongT siz = size(); - switch (siz) { - case 1 : break; - case 4 : _width = _height = 2; break; - case 9 : _width = _height = 3; break; - case 16 : _width = _height = 4; break; - case 25 : _width = _height = 5; break; - case 36 : _width = _height = 6; break; - case 49 : _width = _height = 7; break; - case 64 : _width = _height = 8; break; - case 81 : _width = _height = 9; break; - case 100 : _width = _height = 10; break; - default : { - ulongT i = 11, i2 = i*i; - while (i2 get_matrix() const { - return (+*this).matrix(); - } - - //! Resize image to become a symmetric tensor. - /** - **/ - CImg& tensor() { - return get_tensor().move_to(*this); - } - - //! Resize image to become a symmetric tensor \newinstance. - CImg get_tensor() const { - CImg res; - const ulongT siz = size(); - switch (siz) { - case 1 : break; - case 3 : - res.assign(2,2); - res(0,0) = (*this)(0); - res(1,0) = res(0,1) = (*this)(1); - res(1,1) = (*this)(2); - break; - case 6 : - res.assign(3,3); - res(0,0) = (*this)(0); - res(1,0) = res(0,1) = (*this)(1); - res(2,0) = res(0,2) = (*this)(2); - res(1,1) = (*this)(3); - res(2,1) = res(1,2) = (*this)(4); - res(2,2) = (*this)(5); - break; - default : - throw CImgInstanceException(_cimg_instance - "tensor(): Invalid instance size (does not define a 1x1, 2x2 or 3x3 tensor).", - cimg_instance); - } - return res; - } - - //! Resize image to become a diagonal matrix. - /** - \note Transform the image as a diagonal matrix so that each of its initial value becomes a diagonal coefficient. - **/ - CImg& diagonal() { - return get_diagonal().move_to(*this); - } - - //! Resize image to become a diagonal matrix \newinstance. - CImg get_diagonal() const { - if (is_empty()) return *this; - const unsigned int siz = (unsigned int)size(); - CImg res(siz,siz,1,1,0); - cimg_foroff(*this,off) res((unsigned int)off,(unsigned int)off) = (*this)[off]; - return res; - } - - //! Replace the image by an identity matrix. - /** - \note If the instance image is not square, it is resized to a square matrix using its maximum - dimension as a reference. - **/ - CImg& identity_matrix() { - return identity_matrix(cimg::max(_width,_height)).move_to(*this); - } - - //! Replace the image by an identity matrix \newinstance. - CImg get_identity_matrix() const { - return identity_matrix(cimg::max(_width,_height)); - } - - //! Fill image with a linear sequence of values. - /** - \param a0 Starting value of the sequence. - \param a1 Ending value of the sequence. - **/ - CImg& sequence(const T& a0, const T& a1) { - if (is_empty()) return *this; - const ulongT siz = size() - 1; - T* ptr = _data; - if (siz) { - const double delta = (double)a1 - (double)a0; - cimg_foroff(*this,l) *(ptr++) = (T)(a0 + delta*l/siz); - } else *ptr = a0; - return *this; - } - - //! Fill image with a linear sequence of values \newinstance. - CImg get_sequence(const T& a0, const T& a1) const { - return (+*this).sequence(a0,a1); - } - - //! Transpose the image, viewed as a matrix. - /** - \note Equivalent to \code permute_axes("yxzc"); \endcode - **/ - CImg& transpose() { - if (_width==1) { _width = _height; _height = 1; return *this; } - if (_height==1) { _height = _width; _width = 1; return *this; } - if (_width==_height) { - cimg_forYZC(*this,y,z,c) for (int x = y; x get_transpose() const { - return get_permute_axes("yxzc"); - } - - //! Compute the cross product between two \c 1x3 images, viewed as 3d vectors. - /** - \param img Image used as the second argument of the cross product. - \note The first argument of the cross product is \c *this. - **/ - template - CImg& cross(const CImg& img) { - if (_width!=1 || _height<3 || img._width!=1 || img._height<3) - throw CImgInstanceException(_cimg_instance - "cross(): Instance and/or specified image (%u,%u,%u,%u,%p) are not 3d vectors.", - cimg_instance, - img._width,img._height,img._depth,img._spectrum,img._data); - - const T x = (*this)[0], y = (*this)[1], z = (*this)[2]; - (*this)[0] = (T)(y*img[2] - z*img[1]); - (*this)[1] = (T)(z*img[0] - x*img[2]); - (*this)[2] = (T)(x*img[1] - y*img[0]); - return *this; - } - - //! Compute the cross product between two \c 1x3 images, viewed as 3d vectors \newinstance. - template - CImg<_cimg_Tt> get_cross(const CImg& img) const { - return CImg<_cimg_Tt>(*this).cross(img); - } - - //! Invert the instance image, viewed as a matrix. - /** - \param use_LU Choose the inverting algorithm. Can be: - - \c true: LU-based matrix inversion. - - \c false: SVD-based matrix inversion. - **/ - CImg& invert(const bool use_LU=true) { - if (_width!=_height || _depth!=1 || _spectrum!=1) - throw CImgInstanceException(_cimg_instance - "invert(): Instance is not a square matrix.", - cimg_instance); -#ifdef cimg_use_lapack - int INFO = (int)use_LU, N = _width, LWORK = 4*N, *const IPIV = new int[N]; - Tfloat - *const lapA = new Tfloat[N*N], - *const WORK = new Tfloat[LWORK]; - cimg_forXY(*this,k,l) lapA[k*N + l] = (Tfloat)((*this)(k,l)); - cimg::getrf(N,lapA,IPIV,INFO); - if (INFO) - cimg::warn(_cimg_instance - "invert(): LAPACK function dgetrf_() returned error code %d.", - cimg_instance, - INFO); - else { - cimg::getri(N,lapA,IPIV,WORK,LWORK,INFO); - if (INFO) - cimg::warn(_cimg_instance - "invert(): LAPACK function dgetri_() returned error code %d.", - cimg_instance, - INFO); - } - if (!INFO) cimg_forXY(*this,k,l) (*this)(k,l) = (T)(lapA[k*N + l]); else fill(0); - delete[] IPIV; delete[] lapA; delete[] WORK; -#else - const double dete = _width>3?-1.0:det(); - if (dete!=0.0 && _width==2) { - const double - a = _data[0], c = _data[1], - b = _data[2], d = _data[3]; - _data[0] = (T)(d/dete); _data[1] = (T)(-c/dete); - _data[2] = (T)(-b/dete); _data[3] = (T)(a/dete); - } else if (dete!=0.0 && _width==3) { - const double - a = _data[0], d = _data[1], g = _data[2], - b = _data[3], e = _data[4], h = _data[5], - c = _data[6], f = _data[7], i = _data[8]; - _data[0] = (T)((i*e-f*h)/dete), _data[1] = (T)((g*f-i*d)/dete), _data[2] = (T)((d*h-g*e)/dete); - _data[3] = (T)((h*c-i*b)/dete), _data[4] = (T)((i*a-c*g)/dete), _data[5] = (T)((g*b-a*h)/dete); - _data[6] = (T)((b*f-e*c)/dete), _data[7] = (T)((d*c-a*f)/dete), _data[8] = (T)((a*e-d*b)/dete); - } else { - if (use_LU) { // LU-based inverse computation - CImg A(*this), indx, col(1,_width); - bool d; - A._LU(indx,d); - cimg_forX(*this,j) { - col.fill(0); - col(j) = 1; - col._solve(A,indx); - cimg_forX(*this,i) (*this)(j,i) = (T)col(i); - } - } else { // SVD-based inverse computation - CImg U(_width,_width), S(1,_width), V(_width,_width); - SVD(U,S,V,false); - U.transpose(); - cimg_forY(S,k) if (S[k]!=0) S[k]=1/S[k]; - S.diagonal(); - *this = V*S*U; - } - } -#endif - return *this; - } - - //! Invert the instance image, viewed as a matrix \newinstance. - CImg get_invert(const bool use_LU=true) const { - return CImg(*this,false).invert(use_LU); - } - - //! Compute the Moore-Penrose pseudo-inverse of the instance image, viewed as a matrix. - /** - **/ - CImg& pseudoinvert() { - return get_pseudoinvert().move_to(*this); - } - - //! Compute the Moore-Penrose pseudo-inverse of the instance image, viewed as a matrix \newinstance. - CImg get_pseudoinvert() const { - CImg U, S, V; - SVD(U,S,V); - const Tfloat tolerance = (sizeof(Tfloat)<=4?5.96e-8f:1.11e-16f)*cimg::max(_width,_height)*S.max(); - cimg_forX(V,x) { - const Tfloat s = S(x), invs = s>tolerance?1/s:(Tfloat)0; - cimg_forY(V,y) V(x,y)*=invs; - } - return V*U.transpose(); - } - - //! Solve a system of linear equations. - /** - \param A Matrix of the linear system. - \note Solve \c AX=B where \c B=*this. - **/ - template - CImg& solve(const CImg& A) { - if (_depth!=1 || _spectrum!=1 || _height!=A._height || A._depth!=1 || A._spectrum!=1) - throw CImgArgumentException(_cimg_instance - "solve(): Instance and specified matrix (%u,%u,%u,%u,%p) have " - "incompatible dimensions.", - cimg_instance, - A._width,A._height,A._depth,A._spectrum,A._data); - typedef _cimg_Ttfloat Ttfloat; - if (A._width==A._height) { // Classical linear system - if (_width!=1) { - CImg res(_width,A._width); - cimg_forX(*this,i) res.draw_image(i,get_column(i).solve(A)); - return res.move_to(*this); - } -#ifdef cimg_use_lapack - char TRANS = 'N'; - int INFO, N = _height, LWORK = 4*N, *const IPIV = new int[N]; - Ttfloat - *const lapA = new Ttfloat[N*N], - *const lapB = new Ttfloat[N], - *const WORK = new Ttfloat[LWORK]; - cimg_forXY(A,k,l) lapA[k*N + l] = (Ttfloat)(A(k,l)); - cimg_forY(*this,i) lapB[i] = (Ttfloat)((*this)(i)); - cimg::getrf(N,lapA,IPIV,INFO); - if (INFO) - cimg::warn(_cimg_instance - "solve(): LAPACK library function dgetrf_() returned error code %d.", - cimg_instance, - INFO); - - if (!INFO) { - cimg::getrs(TRANS,N,lapA,IPIV,lapB,INFO); - if (INFO) - cimg::warn(_cimg_instance - "solve(): LAPACK library function dgetrs_() returned error code %d.", - cimg_instance, - INFO); - } - if (!INFO) cimg_forY(*this,i) (*this)(i) = (T)(lapB[i]); else fill(0); - delete[] IPIV; delete[] lapA; delete[] lapB; delete[] WORK; -#else - CImg lu(A,false); - CImg indx; - bool d; - lu._LU(indx,d); - _solve(lu,indx); -#endif - } else { // Least-square solution for non-square systems. -#ifdef cimg_use_lapack - if (_width!=1) { - CImg res(_width,A._width); - cimg_forX(*this,i) res.draw_image(i,get_column(i).solve(A)); - return res.move_to(*this); - } - char TRANS = 'N'; - int INFO, N = A._width, M = A._height, LWORK = -1, LDA = M, LDB = M, NRHS = _width; - Ttfloat WORK_QUERY; - Ttfloat - * const lapA = new Ttfloat[M*N], - * const lapB = new Ttfloat[M*NRHS]; - cimg::sgels(TRANS, M, N, NRHS, lapA, LDA, lapB, LDB, &WORK_QUERY, LWORK, INFO); - LWORK = (int) WORK_QUERY; - Ttfloat *const WORK = new Ttfloat[LWORK]; - cimg_forXY(A,k,l) lapA[k*M + l] = (Ttfloat)(A(k,l)); - cimg_forXY(*this,k,l) lapB[k*M + l] = (Ttfloat)((*this)(k,l)); - cimg::sgels(TRANS, M, N, NRHS, lapA, LDA, lapB, LDB, WORK, LWORK, INFO); - if (INFO != 0) - cimg::warn(_cimg_instance - "solve(): LAPACK library function sgels() returned error code %d.", - cimg_instance, - INFO); - assign(NRHS, N); - if (!INFO) - cimg_forXY(*this,k,l) (*this)(k,l) = (T)lapB[k*M + l]; - else - assign(A.get_pseudoinvert()*(*this)); - delete[] lapA; delete[] lapB; delete[] WORK; -#else - assign(A.get_pseudoinvert()*(*this)); -#endif - } - return *this; - } - - //! Solve a system of linear equations \newinstance. - template - CImg<_cimg_Ttfloat> get_solve(const CImg& A) const { - return CImg<_cimg_Ttfloat>(*this,false).solve(A); - } - - template - CImg& _solve(const CImg& A, const CImg& indx) { - typedef _cimg_Ttfloat Ttfloat; - const int N = (int)size(); - int ii = -1; - Ttfloat sum; - for (int i = 0; i=0) for (int j = ii; j<=i - 1; ++j) sum-=A(j,i)*(*this)(j); - else if (sum!=0) ii = i; - (*this)(i) = (T)sum; - } - for (int i = N - 1; i>=0; --i) { - sum = (*this)(i); - for (int j = i + 1; j - CImg& solve_tridiagonal(const CImg& A) { - const unsigned int siz = (unsigned int)size(); - if (A._width!=3 || A._height!=siz) - throw CImgArgumentException(_cimg_instance - "solve_tridiagonal(): Instance and tridiagonal matrix " - "(%u,%u,%u,%u,%p) have incompatible dimensions.", - cimg_instance, - A._width,A._height,A._depth,A._spectrum,A._data); - typedef _cimg_Ttfloat Ttfloat; - const Ttfloat epsilon = 1e-4f; - CImg B = A.get_column(1), V(*this,false); - for (int i = 1; i<(int)siz; ++i) { - const Ttfloat m = A(0,i)/(B[i - 1]?B[i - 1]:epsilon); - B[i] -= m*A(2,i - 1); - V[i] -= m*V[i - 1]; - } - (*this)[siz - 1] = (T)(V[siz - 1]/(B[siz - 1]?B[siz - 1]:epsilon)); - for (int i = (int)siz - 2; i>=0; --i) (*this)[i] = (T)((V[i] - A(2,i)*(*this)[i + 1])/(B[i]?B[i]:epsilon)); - return *this; - } - - //! Solve a tridiagonal system of linear equations \newinstance. - template - CImg<_cimg_Ttfloat> get_solve_tridiagonal(const CImg& A) const { - return CImg<_cimg_Ttfloat>(*this,false).solve_tridiagonal(A); - } - - //! Compute eigenvalues and eigenvectors of the instance image, viewed as a matrix. - /** - \param[out] val Vector of the estimated eigenvalues, in decreasing order. - \param[out] vec Matrix of the estimated eigenvectors, sorted by columns. - **/ - template - const CImg& eigen(CImg& val, CImg &vec) const { - if (is_empty()) { val.assign(); vec.assign(); } - else { - if (_width!=_height || _depth>1 || _spectrum>1) - throw CImgInstanceException(_cimg_instance - "eigen(): Instance is not a square matrix.", - cimg_instance); - - if (val.size()<(ulongT)_width) val.assign(1,_width); - if (vec.size()<(ulongT)_width*_width) vec.assign(_width,_width); - switch (_width) { - case 1 : { val[0] = (t)(*this)[0]; vec[0] = (t)1; } break; - case 2 : { - const double a = (*this)[0], b = (*this)[1], c = (*this)[2], d = (*this)[3], e = a + d; - double f = e*e - 4*(a*d - b*c); - if (f<0) - cimg::warn(_cimg_instance - "eigen(): Complex eigenvalues found.", - cimg_instance); - - f = std::sqrt(f); - const double l1 = 0.5*(e-f), l2 = 0.5*(e+f); - const double theta1 = std::atan2(l2-a,b), theta2 = std::atan2(l1-a,b); - val[0] = (t)l2; - val[1] = (t)l1; - vec(0,0) = (t)std::cos(theta1); - vec(0,1) = (t)std::sin(theta1); - vec(1,0) = (t)std::cos(theta2); - vec(1,1) = (t)std::sin(theta2); - } break; - default : - throw CImgInstanceException(_cimg_instance - "eigen(): Eigenvalues computation of general matrices is limited " - "to 2x2 matrices.", - cimg_instance); - } - } - return *this; - } - - //! Compute eigenvalues and eigenvectors of the instance image, viewed as a matrix. - /** - \return A list of two images [val; vec], whose meaning is similar as in eigen(CImg&,CImg&) const. - **/ - CImgList get_eigen() const { - CImgList res(2); - eigen(res[0],res[1]); - return res; - } - - //! Compute eigenvalues and eigenvectors of the instance image, viewed as a symmetric matrix. - /** - \param[out] val Vector of the estimated eigenvalues, in decreasing order. - \param[out] vec Matrix of the estimated eigenvectors, sorted by columns. - **/ - template - const CImg& symmetric_eigen(CImg& val, CImg& vec) const { - if (is_empty()) { val.assign(); vec.assign(); } - else { -#ifdef cimg_use_lapack - char JOB = 'V', UPLO = 'U'; - int N = _width, LWORK = 4*N, INFO; - Tfloat - *const lapA = new Tfloat[N*N], - *const lapW = new Tfloat[N], - *const WORK = new Tfloat[LWORK]; - cimg_forXY(*this,k,l) lapA[k*N + l] = (Tfloat)((*this)(k,l)); - cimg::syev(JOB,UPLO,N,lapA,lapW,WORK,LWORK,INFO); - if (INFO) - cimg::warn(_cimg_instance - "symmetric_eigen(): LAPACK library function dsyev_() returned error code %d.", - cimg_instance, - INFO); - - val.assign(1,N); - vec.assign(N,N); - if (!INFO) { - cimg_forY(val,i) val(i) = (T)lapW[N - 1 -i]; - cimg_forXY(vec,k,l) vec(k,l) = (T)(lapA[(N - 1 - k)*N + l]); - } else { val.fill(0); vec.fill(0); } - delete[] lapA; delete[] lapW; delete[] WORK; -#else - if (_width!=_height || _depth>1 || _spectrum>1) - throw CImgInstanceException(_cimg_instance - "eigen(): Instance is not a square matrix.", - cimg_instance); - - val.assign(1,_width); - if (vec._data) vec.assign(_width,_width); - if (_width<3) { - eigen(val,vec); - if (_width==2) { vec[1] = -vec[2]; vec[3] = vec[0]; } // Force orthogonality for 2x2 matrices. - return *this; - } - CImg V(_width,_width); - Tfloat M = 0, m = (Tfloat)min_max(M), maxabs = cimg::max((Tfloat)1.0f,cimg::abs(m),cimg::abs(M)); - (CImg(*this,false)/=maxabs).SVD(vec,val,V,false); - if (maxabs!=1) val*=maxabs; - - bool is_ambiguous = false; - float eig = 0; - cimg_forY(val,p) { // check for ambiguous cases. - if (val[p]>eig) eig = (float)val[p]; - t scal = 0; - cimg_forY(vec,y) scal+=vec(p,y)*V(p,y); - if (cimg::abs(scal)<0.9f) is_ambiguous = true; - if (scal<0) val[p] = -val[p]; - } - if (is_ambiguous) { - ++(eig*=2); - SVD(vec,val,V,false,40,eig); - val-=eig; - } - CImg permutations; // sort eigenvalues in decreasing order - CImg tmp(_width); - val.sort(permutations,false); - cimg_forY(vec,k) { - cimg_forY(permutations,y) tmp(y) = vec(permutations(y),k); - std::memcpy(vec.data(0,k),tmp._data,sizeof(t)*_width); - } -#endif - } - return *this; - } - - //! Compute eigenvalues and eigenvectors of the instance image, viewed as a symmetric matrix. - /** - \return A list of two images [val; vec], whose meaning are similar as in - symmetric_eigen(CImg&,CImg&) const. - **/ - CImgList get_symmetric_eigen() const { - CImgList res(2); - symmetric_eigen(res[0],res[1]); - return res; - } - - //! Sort pixel values and get sorting permutations. - /** - \param[out] permutations Permutation map used for the sorting. - \param is_increasing Tells if pixel values are sorted in an increasing (\c true) or decreasing (\c false) way. - **/ - template - CImg& sort(CImg& permutations, const bool is_increasing=true) { - permutations.assign(_width,_height,_depth,_spectrum); - if (is_empty()) return *this; - cimg_foroff(permutations,off) permutations[off] = (t)off; - return _quicksort(0,size() - 1,permutations,is_increasing,true); - } - - //! Sort pixel values and get sorting permutations \newinstance. - template - CImg get_sort(CImg& permutations, const bool is_increasing=true) const { - return (+*this).sort(permutations,is_increasing); - } - - //! Sort pixel values. - /** - \param is_increasing Tells if pixel values are sorted in an increasing (\c true) or decreasing (\c false) way. - \param axis Tells if the value sorting must be done along a specific axis. Can be: - - \c 0: All pixel values are sorted, independently on their initial position. - - \c 'x': Image columns are sorted, according to the first value in each column. - - \c 'y': Image rows are sorted, according to the first value in each row. - - \c 'z': Image slices are sorted, according to the first value in each slice. - - \c 'c': Image channels are sorted, according to the first value in each channel. - **/ - CImg& sort(const bool is_increasing=true, const char axis=0) { - if (is_empty()) return *this; - CImg perm; - switch (cimg::lowercase(axis)) { - case 0 : - _quicksort(0,size() - 1,perm,is_increasing,false); - break; - case 'x' : { - perm.assign(_width); - get_crop(0,0,0,0,_width - 1,0,0,0).sort(perm,is_increasing); - CImg img(*this,false); - cimg_forXYZC(*this,x,y,z,c) (*this)(x,y,z,c) = img(perm[x],y,z,c); - } break; - case 'y' : { - perm.assign(_height); - get_crop(0,0,0,0,0,_height - 1,0,0).sort(perm,is_increasing); - CImg img(*this,false); - cimg_forXYZC(*this,x,y,z,c) (*this)(x,y,z,c) = img(x,perm[y],z,c); - } break; - case 'z' : { - perm.assign(_depth); - get_crop(0,0,0,0,0,0,_depth - 1,0).sort(perm,is_increasing); - CImg img(*this,false); - cimg_forXYZC(*this,x,y,z,c) (*this)(x,y,z,c) = img(x,y,perm[z],c); - } break; - case 'c' : { - perm.assign(_spectrum); - get_crop(0,0,0,0,0,0,0,_spectrum - 1).sort(perm,is_increasing); - CImg img(*this,false); - cimg_forXYZC(*this,x,y,z,c) (*this)(x,y,z,c) = img(x,y,z,perm[c]); - } break; - default : - throw CImgArgumentException(_cimg_instance - "sort(): Invalid specified axis '%c' " - "(should be { x | y | z | c }).", - cimg_instance,axis); - } - return *this; - } - - //! Sort pixel values \newinstance. - CImg get_sort(const bool is_increasing=true, const char axis=0) const { - return (+*this).sort(is_increasing,axis); - } - - template - CImg& _quicksort(const long indm, const long indM, CImg& permutations, - const bool is_increasing, const bool is_permutations) { - if (indm(*this)[mid]) { - cimg::swap((*this)[indm],(*this)[mid]); - if (is_permutations) cimg::swap(permutations[indm],permutations[mid]); - } - if ((*this)[mid]>(*this)[indM]) { - cimg::swap((*this)[indM],(*this)[mid]); - if (is_permutations) cimg::swap(permutations[indM],permutations[mid]); - } - if ((*this)[indm]>(*this)[mid]) { - cimg::swap((*this)[indm],(*this)[mid]); - if (is_permutations) cimg::swap(permutations[indm],permutations[mid]); - } - } else { - if ((*this)[indm]<(*this)[mid]) { - cimg::swap((*this)[indm],(*this)[mid]); - if (is_permutations) cimg::swap(permutations[indm],permutations[mid]); - } - if ((*this)[mid]<(*this)[indM]) { - cimg::swap((*this)[indM],(*this)[mid]); - if (is_permutations) cimg::swap(permutations[indM],permutations[mid]); - } - if ((*this)[indm]<(*this)[mid]) { - cimg::swap((*this)[indm],(*this)[mid]); - if (is_permutations) cimg::swap(permutations[indm],permutations[mid]); - } - } - if (indM - indm>=3) { - const T pivot = (*this)[mid]; - long i = indm, j = indM; - if (is_increasing) { - do { - while ((*this)[i]pivot) --j; - if (i<=j) { - if (is_permutations) cimg::swap(permutations[i],permutations[j]); - cimg::swap((*this)[i++],(*this)[j--]); - } - } while (i<=j); - } else { - do { - while ((*this)[i]>pivot) ++i; - while ((*this)[j] A; // Input matrix (assumed to contain some values). - CImg<> U,S,V; - A.SVD(U,S,V) - \endcode - **/ - template - const CImg& SVD(CImg& U, CImg& S, CImg& V, const bool sorting=true, - const unsigned int max_iteration=40, const float lambda=0) const { - if (is_empty()) { U.assign(); S.assign(); V.assign(); } - else { - U = *this; - if (lambda!=0) { - const unsigned int delta = cimg::min(U._width,U._height); - for (unsigned int i = 0; i rv1(_width); - t anorm = 0, c, f, g = 0, h, s, scale = 0; - int l = 0, nm = 0; - - cimg_forX(U,i) { - l = i + 1; rv1[i] = scale*g; g = s = scale = 0; - if (i=0?-1:1)*std::sqrt(s)); h=f*g-s; U(i,i) = f-g; - for (int j = l; j=0?-1:1)*std::sqrt(s)); h = f*g-s; U(l,i) = f-g; - for (int k = l; k=0; --i) { - if (i=0; --i) { - l = i + 1; g = S[i]; - for (int j = l; j=0; --k) { - for (unsigned int its = 0; its=1; --l) { - nm = l - 1; - if ((cimg::abs(rv1[l]) + anorm)==anorm) { flag = false; break; } - if ((cimg::abs(S[nm]) + anorm)==anorm) break; - } - if (flag) { - c = 0; s = 1; - for (int i = l; i<=k; ++i) { - f = s*rv1[i]; rv1[i] = c*rv1[i]; - if ((cimg::abs(f) + anorm)==anorm) break; - g = S[i]; h = (t)cimg::_pythagore(f,g); S[i] = h; h = 1/h; c = g*h; s = -f*h; - cimg_forY(U,j) { const t y = U(nm,j), z = U(i,j); U(nm,j) = y*c + z*s; U(i,j) = z*c - y*s; } - } - } - - const t z = S[k]; - if (l==k) { if (z<0) { S[k] = -z; cimg_forX(U,j) V(k,j) = -V(k,j); } break; } - nm = k - 1; - t x = S[l], y = S[nm]; - g = rv1[nm]; h = rv1[k]; - f = ((y - z)*(y + z)+(g - h)*(g + h))/cimg::max((t)1e-25,2*h*y); - g = (t)cimg::_pythagore(f,1.0); - f = ((x - z)*(x + z)+h*((y/(f + (f>=0?g:-g))) - h))/cimg::max((t)1e-25,x); - c = s = 1; - for (int j = l; j<=nm; ++j) { - const int i = j + 1; - g = rv1[i]; h = s*g; g = c*g; - t y = S[i]; - t z = (t)cimg::_pythagore(f,h); - rv1[j] = z; c = f/cimg::max((t)1e-25,z); s = h/cimg::max((t)1e-25,z); - f = x*c + g*s; g = g*c - x*s; h = y*s; y*=c; - cimg_forX(U,jj) { const t x = V(j,jj), z = V(i,jj); V(j,jj) = x*c + z*s; V(i,jj) = z*c - x*s; } - z = (t)cimg::_pythagore(f,h); S[j] = z; - if (z) { z = 1/cimg::max((t)1e-25,z); c = f*z; s = h*z; } - f = c*g + s*y; x = c*y - s*g; - cimg_forY(U,jj) { const t y = U(j,jj); z = U(i,jj); U(j,jj) = y*c + z*s; U(i,jj) = z*c - y*s; } - } - rv1[l] = 0; rv1[k]=f; S[k]=x; - } - } - - if (sorting) { - CImg permutations; - CImg tmp(_width); - S.sort(permutations,false); - cimg_forY(U,k) { - cimg_forY(permutations,y) tmp(y) = U(permutations(y),k); - std::memcpy(U.data(0,k),tmp._data,sizeof(t)*_width); - } - cimg_forY(V,k) { - cimg_forY(permutations,y) tmp(y) = V(permutations(y),k); - std::memcpy(V.data(0,k),tmp._data,sizeof(t)*_width); - } - } - } - return *this; - } - - //! Compute the SVD of the instance image, viewed as a general matrix. - /** - \return A list of three images [U; S; V], whose meaning is similar as in - SVD(CImg&,CImg&,CImg&,bool,unsigned int,float) const. - **/ - CImgList get_SVD(const bool sorting=true, - const unsigned int max_iteration=40, const float lambda=0) const { - CImgList res(3); - SVD(res[0],res[1],res[2],sorting,max_iteration,lambda); - return res; - } - - // [internal] Compute the LU decomposition of a permuted matrix. - template - CImg& _LU(CImg& indx, bool& d) { - const int N = width(); - int imax = 0; - CImg vv(N); - indx.assign(N); - d = true; - cimg_forX(*this,i) { - Tfloat vmax = 0; - cimg_forX(*this,j) { - const Tfloat tmp = cimg::abs((*this)(j,i)); - if (tmp>vmax) vmax = tmp; - } - if (vmax==0) { indx.fill(0); return fill(0); } - vv[i] = 1/vmax; - } - cimg_forX(*this,j) { - for (int i = 0; i=vmax) { vmax=tmp; imax=i; } - } - if (j!=imax) { - cimg_forX(*this,k) cimg::swap((*this)(k,imax),(*this)(k,j)); - d =!d; - vv[imax] = vv[j]; - } - indx[j] = (t)imax; - if ((*this)(j,j)==0) (*this)(j,j) = (T)1e-20; - if (j - static CImg dijkstra(const tf& distance, const unsigned int nb_nodes, - const unsigned int starting_node, const unsigned int ending_node, - CImg& previous_node) { - if (starting_node>=nb_nodes) - throw CImgArgumentException("CImg<%s>::dijkstra(): Specified indice of starting node %u is higher " - "than number of nodes %u.", - pixel_type(),starting_node,nb_nodes); - CImg dist(1,nb_nodes,1,1,cimg::type::max()); - dist(starting_node) = 0; - previous_node.assign(1,nb_nodes,1,1,(t)-1); - previous_node(starting_node) = (t)starting_node; - CImg Q(nb_nodes); - cimg_forX(Q,u) Q(u) = (unsigned int)u; - cimg::swap(Q(starting_node),Q(0)); - unsigned int sizeQ = nb_nodes; - while (sizeQ) { - // Update neighbors from minimal vertex - const unsigned int umin = Q(0); - if (umin==ending_node) sizeQ = 0; - else { - const T dmin = dist(umin); - const T infty = cimg::type::max(); - for (unsigned int q = 1; qdist(Q(left))) || - (rightdist(Q(right)));) { - if (right - static CImg dijkstra(const tf& distance, const unsigned int nb_nodes, - const unsigned int starting_node, const unsigned int ending_node=~0U) { - CImg foo; - return dijkstra(distance,nb_nodes,starting_node,ending_node,foo); - } - - //! Return minimal path in a graph, using the Dijkstra algorithm. - /** - \param starting_node Indice of the starting node. - \param ending_node Indice of the ending node. - \param previous_node Array that gives the previous node indice in the path to the starting node - (optional parameter). - \return Array of distances of each node to the starting node. - \note image instance corresponds to the adjacency matrix of the graph. - **/ - template - CImg& dijkstra(const unsigned int starting_node, const unsigned int ending_node, - CImg& previous_node) { - return get_dijkstra(starting_node,ending_node,previous_node).move_to(*this); - } - - //! Return minimal path in a graph, using the Dijkstra algorithm \newinstance. - template - CImg get_dijkstra(const unsigned int starting_node, const unsigned int ending_node, - CImg& previous_node) const { - if (_width!=_height || _depth!=1 || _spectrum!=1) - throw CImgInstanceException(_cimg_instance - "dijkstra(): Instance is not a graph adjacency matrix.", - cimg_instance); - - return dijkstra(*this,_width,starting_node,ending_node,previous_node); - } - - //! Return minimal path in a graph, using the Dijkstra algorithm. - CImg& dijkstra(const unsigned int starting_node, const unsigned int ending_node=~0U) { - return get_dijkstra(starting_node,ending_node).move_to(*this); - } - - //! Return minimal path in a graph, using the Dijkstra algorithm \newinstance. - CImg get_dijkstra(const unsigned int starting_node, const unsigned int ending_node=~0U) const { - CImg foo; - return get_dijkstra(starting_node,ending_node,foo); - } - - //! Return an image containing the ascii codes of the specified string. - /** - \param str input C-string to encode as an image. - \param is_last_zero Tells if the ending \c '0' character appear in the resulting image. - **/ - static CImg string(const char *const str, const bool is_last_zero=true, const bool is_shared=false) { - if (!str) return CImg(); - return CImg(str,(unsigned int)std::strlen(str) + (is_last_zero?1:0),1,1,1,is_shared); - } - - //! Return a \c 1x1 image containing specified value. - /** - \param a0 First vector value. - **/ - static CImg vector(const T& a0) { - CImg r(1,1); - r[0] = a0; - return r; - } - - //! Return a \c 1x2 image containing specified values. - /** - \param a0 First vector value. - \param a1 Second vector value. - **/ - static CImg vector(const T& a0, const T& a1) { - CImg r(1,2); T *ptr = r._data; - *(ptr++) = a0; *(ptr++) = a1; - return r; - } - - //! Return a \c 1x3 image containing specified values. - /** - \param a0 First vector value. - \param a1 Second vector value. - \param a2 Third vector value. - **/ - static CImg vector(const T& a0, const T& a1, const T& a2) { - CImg r(1,3); T *ptr = r._data; - *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; - return r; - } - - //! Return a \c 1x4 image containing specified values. - /** - \param a0 First vector value. - \param a1 Second vector value. - \param a2 Third vector value. - \param a3 Fourth vector value. - **/ - static CImg vector(const T& a0, const T& a1, const T& a2, const T& a3) { - CImg r(1,4); T *ptr = r._data; - *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; - return r; - } - - //! Return a \c 1x5 image containing specified values. - static CImg vector(const T& a0, const T& a1, const T& a2, const T& a3, const T& a4) { - CImg r(1,5); T *ptr = r._data; - *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; - return r; - } - - //! Return a \c 1x6 image containing specified values. - static CImg vector(const T& a0, const T& a1, const T& a2, const T& a3, const T& a4, const T& a5) { - CImg r(1,6); T *ptr = r._data; - *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; - return r; - } - - //! Return a \c 1x7 image containing specified values. - static CImg vector(const T& a0, const T& a1, const T& a2, const T& a3, - const T& a4, const T& a5, const T& a6) { - CImg r(1,7); T *ptr = r._data; - *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; - *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; - return r; - } - - //! Return a \c 1x8 image containing specified values. - static CImg vector(const T& a0, const T& a1, const T& a2, const T& a3, - const T& a4, const T& a5, const T& a6, const T& a7) { - CImg r(1,8); T *ptr = r._data; - *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; - *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; - return r; - } - - //! Return a \c 1x9 image containing specified values. - static CImg vector(const T& a0, const T& a1, const T& a2, const T& a3, - const T& a4, const T& a5, const T& a6, const T& a7, - const T& a8) { - CImg r(1,9); T *ptr = r._data; - *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; - *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; - *(ptr++) = a8; - return r; - } - - //! Return a \c 1x10 image containing specified values. - static CImg vector(const T& a0, const T& a1, const T& a2, const T& a3, - const T& a4, const T& a5, const T& a6, const T& a7, - const T& a8, const T& a9) { - CImg r(1,10); T *ptr = r._data; - *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; - *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; - *(ptr++) = a8; *(ptr++) = a9; - return r; - } - - //! Return a \c 1x11 image containing specified values. - static CImg vector(const T& a0, const T& a1, const T& a2, const T& a3, - const T& a4, const T& a5, const T& a6, const T& a7, - const T& a8, const T& a9, const T& a10) { - CImg r(1,11); T *ptr = r._data; - *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; - *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; - *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; - return r; - } - - //! Return a \c 1x12 image containing specified values. - static CImg vector(const T& a0, const T& a1, const T& a2, const T& a3, - const T& a4, const T& a5, const T& a6, const T& a7, - const T& a8, const T& a9, const T& a10, const T& a11) { - CImg r(1,12); T *ptr = r._data; - *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; - *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; - *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; - return r; - } - - //! Return a \c 1x13 image containing specified values. - static CImg vector(const T& a0, const T& a1, const T& a2, const T& a3, - const T& a4, const T& a5, const T& a6, const T& a7, - const T& a8, const T& a9, const T& a10, const T& a11, - const T& a12) { - CImg r(1,13); T *ptr = r._data; - *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; - *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; - *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; - *(ptr++) = a12; - return r; - } - - //! Return a \c 1x14 image containing specified values. - static CImg vector(const T& a0, const T& a1, const T& a2, const T& a3, - const T& a4, const T& a5, const T& a6, const T& a7, - const T& a8, const T& a9, const T& a10, const T& a11, - const T& a12, const T& a13) { - CImg r(1,14); T *ptr = r._data; - *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; - *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; - *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; - *(ptr++) = a12; *(ptr++) = a13; - return r; - } - - //! Return a \c 1x15 image containing specified values. - static CImg vector(const T& a0, const T& a1, const T& a2, const T& a3, - const T& a4, const T& a5, const T& a6, const T& a7, - const T& a8, const T& a9, const T& a10, const T& a11, - const T& a12, const T& a13, const T& a14) { - CImg r(1,15); T *ptr = r._data; - *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; - *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; - *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; - *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14; - return r; - } - - //! Return a \c 1x16 image containing specified values. - static CImg vector(const T& a0, const T& a1, const T& a2, const T& a3, - const T& a4, const T& a5, const T& a6, const T& a7, - const T& a8, const T& a9, const T& a10, const T& a11, - const T& a12, const T& a13, const T& a14, const T& a15) { - CImg r(1,16); T *ptr = r._data; - *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; - *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; - *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; - *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14; *(ptr++) = a15; - return r; - } - - //! Return a 1x1 matrix containing specified coefficients. - /** - \param a0 First matrix value. - \note Equivalent to vector(const T&). - **/ - static CImg matrix(const T& a0) { - return vector(a0); - } - - //! Return a 2x2 matrix containing specified coefficients. - /** - \param a0 First matrix value. - \param a1 Second matrix value. - \param a2 Third matrix value. - \param a3 Fourth matrix value. - **/ - static CImg matrix(const T& a0, const T& a1, - const T& a2, const T& a3) { - CImg r(2,2); T *ptr = r._data; - *(ptr++) = a0; *(ptr++) = a1; - *(ptr++) = a2; *(ptr++) = a3; - return r; - } - - //! Return a 3x3 matrix containing specified coefficients. - /** - \param a0 First matrix value. - \param a1 Second matrix value. - \param a2 Third matrix value. - \param a3 Fourth matrix value. - \param a4 Fifth matrix value. - \param a5 Sixth matrix value. - \param a6 Seventh matrix value. - \param a7 Eighth matrix value. - \param a8 Nineth matrix value. - **/ - static CImg matrix(const T& a0, const T& a1, const T& a2, - const T& a3, const T& a4, const T& a5, - const T& a6, const T& a7, const T& a8) { - CImg r(3,3); T *ptr = r._data; - *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; - *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; - *(ptr++) = a6; *(ptr++) = a7; *(ptr++) = a8; - return r; - } - - //! Return a 4x4 matrix containing specified coefficients. - static CImg matrix(const T& a0, const T& a1, const T& a2, const T& a3, - const T& a4, const T& a5, const T& a6, const T& a7, - const T& a8, const T& a9, const T& a10, const T& a11, - const T& a12, const T& a13, const T& a14, const T& a15) { - CImg r(4,4); T *ptr = r._data; - *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; - *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; - *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; - *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14; *(ptr++) = a15; - return r; - } - - //! Return a 5x5 matrix containing specified coefficients. - static CImg matrix(const T& a0, const T& a1, const T& a2, const T& a3, const T& a4, - const T& a5, const T& a6, const T& a7, const T& a8, const T& a9, - const T& a10, const T& a11, const T& a12, const T& a13, const T& a14, - const T& a15, const T& a16, const T& a17, const T& a18, const T& a19, - const T& a20, const T& a21, const T& a22, const T& a23, const T& a24) { - CImg r(5,5); T *ptr = r._data; - *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; - *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; *(ptr++) = a8; *(ptr++) = a9; - *(ptr++) = a10; *(ptr++) = a11; *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14; - *(ptr++) = a15; *(ptr++) = a16; *(ptr++) = a17; *(ptr++) = a18; *(ptr++) = a19; - *(ptr++) = a20; *(ptr++) = a21; *(ptr++) = a22; *(ptr++) = a23; *(ptr++) = a24; - return r; - } - - //! Return a 1x1 symmetric matrix containing specified coefficients. - /** - \param a0 First matrix value. - \note Equivalent to vector(const T&). - **/ - static CImg tensor(const T& a0) { - return matrix(a0); - } - - //! Return a 2x2 symmetric matrix tensor containing specified coefficients. - static CImg tensor(const T& a0, const T& a1, const T& a2) { - return matrix(a0,a1,a1,a2); - } - - //! Return a 3x3 symmetric matrix containing specified coefficients. - static CImg tensor(const T& a0, const T& a1, const T& a2, const T& a3, const T& a4, const T& a5) { - return matrix(a0,a1,a2,a1,a3,a4,a2,a4,a5); - } - - //! Return a 1x1 diagonal matrix containing specified coefficients. - static CImg diagonal(const T& a0) { - return matrix(a0); - } - - //! Return a 2x2 diagonal matrix containing specified coefficients. - static CImg diagonal(const T& a0, const T& a1) { - return matrix(a0,0,0,a1); - } - - //! Return a 3x3 diagonal matrix containing specified coefficients. - static CImg diagonal(const T& a0, const T& a1, const T& a2) { - return matrix(a0,0,0,0,a1,0,0,0,a2); - } - - //! Return a 4x4 diagonal matrix containing specified coefficients. - static CImg diagonal(const T& a0, const T& a1, const T& a2, const T& a3) { - return matrix(a0,0,0,0,0,a1,0,0,0,0,a2,0,0,0,0,a3); - } - - //! Return a 5x5 diagonal matrix containing specified coefficients. - static CImg diagonal(const T& a0, const T& a1, const T& a2, const T& a3, const T& a4) { - return matrix(a0,0,0,0,0,0,a1,0,0,0,0,0,a2,0,0,0,0,0,a3,0,0,0,0,0,a4); - } - - //! Return a NxN identity matrix. - /** - \param N Dimension of the matrix. - **/ - static CImg identity_matrix(const unsigned int N) { - CImg res(N,N,1,1,0); - cimg_forX(res,x) res(x,x) = 1; - return res; - } - - //! Return a N-numbered sequence vector from \p a0 to \p a1. - /** - \param N Size of the resulting vector. - \param a0 Starting value of the sequence. - \param a1 Ending value of the sequence. - **/ - static CImg sequence(const unsigned int N, const T& a0, const T& a1) { - if (N) return CImg(1,N).sequence(a0,a1); - return CImg(); - } - - //! Return a 3x3 rotation matrix along the (x,y,z)-axis with an angle w. - /** - \param x X-coordinate of the rotation axis, or first quaternion coordinate. - \param y Y-coordinate of the rotation axis, or second quaternion coordinate. - \param z Z-coordinate of the rotation axis, or third quaternion coordinate. - \param w Angle of the rotation axis, or fourth quaternion coordinate. - \param is_quaternion Tell is the four arguments denotes a set { axis + angle } or a quaternion. - **/ - static CImg rotation_matrix(const float x, const float y, const float z, const float w, - const bool is_quaternion=false) { - float X,Y,Z,W; - if (!is_quaternion) { - const float norm = (float)std::sqrt(x*x + y*y + z*z), - nx = norm>0?x/norm:0, - ny = norm>0?y/norm:0, - nz = norm>0?z/norm:1, - nw = norm>0?w:0, - sina = (float)std::sin(nw/2), - cosa = (float)std::cos(nw/2); - X = nx*sina; - Y = ny*sina; - Z = nz*sina; - W = cosa; - } else { - const float norm = (float)std::sqrt(x*x + y*y + z*z + w*w); - if (norm>0) { X = x/norm; Y = y/norm; Z = z/norm; W = w/norm; } - else { X = Y = Z = 0; W = 1; } - } - const float xx = X*X, xy = X*Y, xz = X*Z, xw = X*W, yy = Y*Y, yz = Y*Z, yw = Y*W, zz = Z*Z, zw = Z*W; - return CImg::matrix((T)(1 - 2*(yy + zz)), (T)(2*(xy + zw)), (T)(2*(xz - yw)), - (T)(2*(xy - zw)), (T)(1 - 2*(xx + zz)), (T)(2*(yz + xw)), - (T)(2*(xz + yw)), (T)(2*(yz - xw)), (T)(1 - 2*(xx + yy))); - } - - //@} - //----------------------------------- - // - //! \name Value Manipulation - //@{ - //----------------------------------- - - //! Fill all pixel values with specified value. - /** - \param val Fill value. - **/ - CImg& fill(const T& val) { - if (is_empty()) return *this; - if (val && sizeof(T)!=1) cimg_for(*this,ptrd,T) *ptrd = val; - else std::memset(_data,(int)val,sizeof(T)*size()); - return *this; - } - - //! Fill all pixel values with specified value \newinstance. - CImg get_fill(const T& val) const { - return CImg(_width,_height,_depth,_spectrum).fill(val); - } - - //! Fill sequentially all pixel values with specified values. - /** - \param val0 First fill value. - \param val1 Second fill value. - **/ - CImg& fill(const T& val0, const T& val1) { - if (is_empty()) return *this; - T *ptrd, *ptre = end() - 1; - for (ptrd = _data; ptrd get_fill(const T& val0, const T& val1) const { - return CImg(_width,_height,_depth,_spectrum).fill(val0,val1); - } - - //! Fill sequentially all pixel values with specified values \overloading. - CImg& fill(const T& val0, const T& val1, const T& val2) { - if (is_empty()) return *this; - T *ptrd, *ptre = end() - 2; - for (ptrd = _data; ptrd get_fill(const T& val0, const T& val1, const T& val2) const { - return CImg(_width,_height,_depth,_spectrum).fill(val0,val1,val2); - } - - //! Fill sequentially all pixel values with specified values \overloading. - CImg& fill(const T& val0, const T& val1, const T& val2, const T& val3) { - if (is_empty()) return *this; - T *ptrd, *ptre = end() - 3; - for (ptrd = _data; ptrd get_fill(const T& val0, const T& val1, const T& val2, const T& val3) const { - return CImg(_width,_height,_depth,_spectrum).fill(val0,val1,val2,val3); - } - - //! Fill sequentially all pixel values with specified values \overloading. - CImg& fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4) { - if (is_empty()) return *this; - T *ptrd, *ptre = end() - 4; - for (ptrd = _data; ptrd get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4) const { - return CImg(_width,_height,_depth,_spectrum).fill(val0,val1,val2,val3,val4); - } - - //! Fill sequentially all pixel values with specified values \overloading. - CImg& fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5) { - if (is_empty()) return *this; - T *ptrd, *ptre = end() - 5; - for (ptrd = _data; ptrd get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5) const { - return CImg(_width,_height,_depth,_spectrum).fill(val0,val1,val2,val3,val4,val5); - } - - //! Fill sequentially all pixel values with specified values \overloading. - CImg& fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6) { - if (is_empty()) return *this; - T *ptrd, *ptre = end() - 6; - for (ptrd = _data; ptrd get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6) const { - return CImg(_width,_height,_depth,_spectrum).fill(val0,val1,val2,val3,val4,val5,val6); - } - - //! Fill sequentially all pixel values with specified values \overloading. - CImg& fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6, const T& val7) { - if (is_empty()) return *this; - T *ptrd, *ptre = end() - 7; - for (ptrd = _data; ptrd get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6, const T& val7) const { - return CImg(_width,_height,_depth,_spectrum).fill(val0,val1,val2,val3,val4,val5,val6,val7); - } - - //! Fill sequentially all pixel values with specified values \overloading. - CImg& fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6, const T& val7, const T& val8) { - if (is_empty()) return *this; - T *ptrd, *ptre = end() - 8; - for (ptrd = _data; ptrd get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6, const T& val7, const T& val8) const { - return CImg(_width,_height,_depth,_spectrum).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8); - } - - //! Fill sequentially all pixel values with specified values \overloading. - CImg& fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6, const T& val7, const T& val8, const T& val9) { - if (is_empty()) return *this; - T *ptrd, *ptre = end() - 9; - for (ptrd = _data; ptrd get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6, const T& val7, const T& val8, const T& val9) const { - return CImg(_width,_height,_depth,_spectrum).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9); - } - - //! Fill sequentially all pixel values with specified values \overloading. - CImg& fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6, const T& val7, const T& val8, const T& val9, const T& val10) { - if (is_empty()) return *this; - T *ptrd, *ptre = end() - 10; - for (ptrd = _data; ptrd get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6, const T& val7, const T& val8, const T& val9, const T& val10) const { - return CImg(_width,_height,_depth,_spectrum).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10); - } - - //! Fill sequentially all pixel values with specified values \overloading. - CImg& fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6, const T& val7, const T& val8, const T& val9, const T& val10, const T& val11) { - if (is_empty()) return *this; - T *ptrd, *ptre = end() - 11; - for (ptrd = _data; ptrd get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6, const T& val7, const T& val8, const T& val9, const T& val10, const T& val11) const { - return CImg(_width,_height,_depth,_spectrum).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10, - val11); - } - - //! Fill sequentially all pixel values with specified values \overloading. - CImg& fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6, const T& val7, const T& val8, const T& val9, const T& val10, const T& val11, - const T& val12) { - if (is_empty()) return *this; - T *ptrd, *ptre = end() - 12; - for (ptrd = _data; ptrd get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6, const T& val7, const T& val8, const T& val9, const T& val10, const T& val11, - const T& val12) const { - return CImg(_width,_height,_depth,_spectrum).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10, - val11,val12); - } - - //! Fill sequentially all pixel values with specified values \overloading. - CImg& fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6, const T& val7, const T& val8, const T& val9, const T& val10, const T& val11, - const T& val12, const T& val13) { - if (is_empty()) return *this; - T *ptrd, *ptre = end() - 13; - for (ptrd = _data; ptrd get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6, const T& val7, const T& val8, const T& val9, const T& val10, const T& val11, - const T& val12, const T& val13) const { - return CImg(_width,_height,_depth,_spectrum).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10, - val11,val12,val13); - } - - //! Fill sequentially all pixel values with specified values \overloading. - CImg& fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6, const T& val7, const T& val8, const T& val9, const T& val10, const T& val11, - const T& val12, const T& val13, const T& val14) { - if (is_empty()) return *this; - T *ptrd, *ptre = end() - 14; - for (ptrd = _data; ptrd get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6, const T& val7, const T& val8, const T& val9, const T& val10, const T& val11, - const T& val12, const T& val13, const T& val14) const { - return CImg(_width,_height,_depth,_spectrum).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10, - val11,val12,val13,val14); - } - - //! Fill sequentially all pixel values with specified values \overloading. - CImg& fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6, const T& val7, const T& val8, const T& val9, const T& val10, const T& val11, - const T& val12, const T& val13, const T& val14, const T& val15) { - if (is_empty()) return *this; - T *ptrd, *ptre = end() - 15; - for (ptrd = _data; ptrd get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5, - const T& val6, const T& val7, const T& val8, const T& val9, const T& val10, const T& val11, - const T& val12, const T& val13, const T& val14, const T& val15) const { - return CImg(_width,_height,_depth,_spectrum).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10, - val11,val12,val13,val14,val15); - } - - //! Fill sequentially pixel values according to a given expression. - /** - \param expression C-string describing a math formula, or a list of values. - \param repeat_values In case a list of values is provided, tells if this list must be repeated for the filling. - \param allow_formula tells if a formula is allowed or only a list of values. - \param list_inputs In case of a mathematical expression, attach a list of images to the specified expression. - \param list_outputs In case of a mathematical expression, attach a list of images to the specified expression. - **/ - CImg& fill(const char *const expression, const bool repeat_values, const bool allow_formula=true, - const CImgList *const list_inputs=0, CImgList *const list_outputs=0) { - return _fill(expression,repeat_values,allow_formula,list_inputs,list_outputs,"fill",0); - } - - CImg& _fill(const char *const expression, const bool repeat_values, const bool allow_formula, - const CImgList *const list_inputs, CImgList *const list_outputs, - const char *const calling_function, const CImg *provides_copy) { - if (is_empty() || !expression || !*expression) return *this; - const unsigned int omode = cimg::exception_mode(); - cimg::exception_mode(0); - CImg is_error; - cimg_abort_init; - - if (allow_formula) try { // Try to fill values according to a formula - CImg base = provides_copy?provides_copy->get_shared():get_shared(); - _cimg_math_parser mp(expression + (*expression=='>' || *expression=='<' || - *expression=='*' || *expression==':'), - calling_function,base,this,list_inputs,list_outputs); - if (!provides_copy && expression && *expression!='>' && *expression!='<' && *expression!=':' && - mp.need_input_copy) - base.assign().assign(*this); // Needs input copy - - bool do_in_parallel = false; -#ifdef cimg_use_openmp - cimg_openmp_if(*expression=='*' || *expression==':' || - (mp.is_parallelizable && _width>=320 && _height*_depth*_spectrum>=2 && - std::strlen(expression)>=6)) - do_in_parallel = true; -#endif - if (mp.result_dim) { // Vector-valued expression - const unsigned int N = cimg::min(mp.result_dim,_spectrum); - const ulongT whd = (ulongT)_width*_height*_depth; - T *ptrd = *expression=='<'?_data + _width*_height*_depth - 1:_data; - if (*expression=='<') { - CImg res(1,mp.result_dim); - cimg_rofYZ(*this,y,z) { - cimg_abort_test(); - cimg_rofX(*this,x) { - mp(x,y,z,0,res._data); - const double *ptrs = res._data; - T *_ptrd = ptrd--; for (unsigned int n = N; n>0; --n) { *_ptrd = (T)(*ptrs++); _ptrd+=whd; } - } - } - } else if (*expression=='>' || !do_in_parallel) { - CImg res(1,mp.result_dim); - cimg_forYZ(*this,y,z) { - cimg_abort_test(); - cimg_forX(*this,x) { - mp(x,y,z,0,res._data); - const double *ptrs = res._data; - T *_ptrd = ptrd++; for (unsigned int n = N; n>0; --n) { *_ptrd = (T)(*ptrs++); _ptrd+=whd; } - } - } - } else { -#ifdef cimg_use_openmp - cimg_pragma_openmp(parallel) - { - _cimg_math_parser _mp = omp_get_thread_num()?mp:_cimg_math_parser(), &lmp = omp_get_thread_num()?_mp:mp; - cimg_pragma_openmp(for collapse(2)) - cimg_forYZ(*this,y,z) cimg_abort_try { - cimg_abort_test(); - CImg res(1,lmp.result_dim); - T *ptrd = data(0,y,z,0); - cimg_forX(*this,x) { - lmp(x,y,z,0,res._data); - const double *ptrs = res._data; - T *_ptrd = ptrd++; for (unsigned int n = N; n>0; --n) { *_ptrd = (T)(*ptrs++); _ptrd+=whd; } - } - } cimg_abort_catch() - } -#endif - } - - } else { // Scalar-valued expression - T *ptrd = *expression=='<'?end() - 1:_data; - if (*expression=='<') - cimg_rofYZC(*this,y,z,c) { cimg_abort_test(); cimg_rofX(*this,x) *(ptrd--) = (T)mp(x,y,z,c); } - else if (*expression=='>' || !do_in_parallel) - cimg_forYZC(*this,y,z,c) { cimg_abort_test(); cimg_forX(*this,x) *(ptrd++) = (T)mp(x,y,z,c); } - else { -#ifdef cimg_use_openmp - cimg_pragma_openmp(parallel) - { - _cimg_math_parser _mp = omp_get_thread_num()?mp:_cimg_math_parser(), &lmp = omp_get_thread_num()?_mp:mp; - cimg_pragma_openmp(for collapse(3)) - cimg_forYZC(*this,y,z,c) cimg_abort_try { - cimg_abort_test(); - T *ptrd = data(0,y,z,c); - cimg_forX(*this,x) *ptrd++ = (T)lmp(x,y,z,c); - } cimg_abort_catch() - } -#endif - } - } - } catch (CImgException& e) { CImg::string(e._message).move_to(is_error); } - - // If failed, try to recognize a list of values. - if (!allow_formula || is_error) { - char *const item = new char[16384], sep = 0; - const char *nexpression = expression; - ulongT nb = 0; - const ulongT siz = size(); - T *ptrd = _data; - for (double val = 0; *nexpression && nb0 && cimg_sscanf(item,"%lf",&val)==1 && (sep==',' || sep==';' || err==1)) { - nexpression+=std::strlen(item) + (err>1); - *(ptrd++) = (T)val; - } else break; - } - delete[] item; - cimg::exception_mode(omode); - if (nb get_fill(const char *const expression, const bool repeat_values, const bool allow_formula=true, - const CImgList *const list_inputs=0, CImgList *const list_outputs=0) const { - return (+*this).fill(expression,repeat_values,allow_formula,list_inputs,list_outputs); - } - - //! Fill sequentially pixel values according to the values found in another image. - /** - \param values Image containing the values used for the filling. - \param repeat_values In case there are less values than necessary in \c values, tells if these values must be - repeated for the filling. - **/ - template - CImg& fill(const CImg& values, const bool repeat_values=true) { - if (is_empty() || !values) return *this; - T *ptrd = _data, *ptre = ptrd + size(); - for (t *ptrs = values._data, *ptrs_end = ptrs + values.size(); ptrs - CImg get_fill(const CImg& values, const bool repeat_values=true) const { - return repeat_values?CImg(_width,_height,_depth,_spectrum).fill(values,repeat_values): - (+*this).fill(values,repeat_values); - } - - //! Fill pixel values along the X-axis at a specified pixel position. - /** - \param y Y-coordinate of the filled column. - \param z Z-coordinate of the filled column. - \param c C-coordinate of the filled column. - \param a0 First fill value. - **/ - CImg& fillX(const unsigned int y, const unsigned int z, const unsigned int c, const int a0, ...) { -#define _cimg_fill1(x,y,z,c,off,siz,t) { \ - va_list ap; va_start(ap,a0); T *ptrd = data(x,y,z,c); *ptrd = (T)a0; \ - for (unsigned int k = 1; k& fillX(const unsigned int y, const unsigned int z, const unsigned int c, const double a0, ...) { - if (y<_height && z<_depth && c<_spectrum) _cimg_fill1(0,y,z,c,1,_width,double); - return *this; - } - - //! Fill pixel values along the Y-axis at a specified pixel position. - /** - \param x X-coordinate of the filled row. - \param z Z-coordinate of the filled row. - \param c C-coordinate of the filled row. - \param a0 First fill value. - **/ - CImg& fillY(const unsigned int x, const unsigned int z, const unsigned int c, const int a0, ...) { - if (x<_width && z<_depth && c<_spectrum) _cimg_fill1(x,0,z,c,_width,_height,int); - return *this; - } - - //! Fill pixel values along the Y-axis at a specified pixel position \overloading. - CImg& fillY(const unsigned int x, const unsigned int z, const unsigned int c, const double a0, ...) { - if (x<_width && z<_depth && c<_spectrum) _cimg_fill1(x,0,z,c,_width,_height,double); - return *this; - } - - //! Fill pixel values along the Z-axis at a specified pixel position. - /** - \param x X-coordinate of the filled slice. - \param y Y-coordinate of the filled slice. - \param c C-coordinate of the filled slice. - \param a0 First fill value. - **/ - CImg& fillZ(const unsigned int x, const unsigned int y, const unsigned int c, const int a0, ...) { - const ulongT wh = (ulongT)_width*_height; - if (x<_width && y<_height && c<_spectrum) _cimg_fill1(x,y,0,c,wh,_depth,int); - return *this; - } - - //! Fill pixel values along the Z-axis at a specified pixel position \overloading. - CImg& fillZ(const unsigned int x, const unsigned int y, const unsigned int c, const double a0, ...) { - const ulongT wh = (ulongT)_width*_height; - if (x<_width && y<_height && c<_spectrum) _cimg_fill1(x,y,0,c,wh,_depth,double); - return *this; - } - - //! Fill pixel values along the C-axis at a specified pixel position. - /** - \param x X-coordinate of the filled channel. - \param y Y-coordinate of the filled channel. - \param z Z-coordinate of the filled channel. - \param a0 First filling value. - **/ - CImg& fillC(const unsigned int x, const unsigned int y, const unsigned int z, const int a0, ...) { - const ulongT whd = (ulongT)_width*_height*_depth; - if (x<_width && y<_height && z<_depth) _cimg_fill1(x,y,z,0,whd,_spectrum,int); - return *this; - } - - //! Fill pixel values along the C-axis at a specified pixel position \overloading. - CImg& fillC(const unsigned int x, const unsigned int y, const unsigned int z, const double a0, ...) { - const ulongT whd = (ulongT)_width*_height*_depth; - if (x<_width && y<_height && z<_depth) _cimg_fill1(x,y,z,0,whd,_spectrum,double); - return *this; - } - - //! Discard specified sequence of values in the image buffer, along a specific axis. - /** - \param values Sequence of values to discard. - \param axis Axis along which the values are discarded. If set to \c 0 (default value) - the method does it for all the buffer values and returns a one-column vector. - \note Discarded values will change the image geometry, so the resulting image - is returned as a one-column vector. - **/ - template - CImg& discard(const CImg& values, const char axis=0) { - if (is_empty() || !values) return *this; - return get_discard(values,axis).move_to(*this); - } - - template - CImg get_discard(const CImg& values, const char axis=0) const { - CImg res; - if (!values) return +*this; - if (is_empty()) return res; - const ulongT vsiz = values.size(); - const char _axis = cimg::lowercase(axis); - ulongT j = 0; - unsigned int k = 0; - int i0 = 0; - res.assign(width(),height(),depth(),spectrum()); - switch (_axis) { - case 'x' : { - cimg_forX(*this,i) { - if ((*this)(i)!=(T)values[j]) { - if (j) --i; - res.draw_image(k,get_columns(i0,i)); - k+=i - i0 + 1; i0 = i + 1; j = 0; - } else { ++j; if (j>=vsiz) { j = 0; i0 = i + 1; } } - } - if (i0=vsiz) { j = 0; i0 = i + 1; } } - } - if (i0=vsiz) { j = 0; i0 = i + 1; } } - } - if (i0=vsiz) { j = 0; i0 = i + 1; } } - } - if (i0=vsiz) { j = 0; i0 = (int)i + 1; }} - } - const ulongT siz = size(); - if ((ulongT)i0& discard(const char axis=0) { - return get_discard(axis).move_to(*this); - } - - //! Discard neighboring duplicates in the image buffer, along the specified axis \newinstance. - CImg get_discard(const char axis=0) const { - CImg res; - if (is_empty()) return res; - const char _axis = cimg::lowercase(axis); - T current = *_data?0:(T)1; - int j = 0; - res.assign(width(),height(),depth(),spectrum()); - switch (_axis) { - case 'x' : { - cimg_forX(*this,i) - if ((*this)(i)!=current) { res.draw_image(j++,get_column(i)); current = (*this)(i); } - res.resize(j,-100,-100,-100,0); - } break; - case 'y' : { - cimg_forY(*this,i) - if ((*this)(0,i)!=current) { res.draw_image(0,j++,get_row(i)); current = (*this)(0,i); } - res.resize(-100,j,-100,-100,0); - } break; - case 'z' : { - cimg_forZ(*this,i) - if ((*this)(0,0,i)!=current) { res.draw_image(0,0,j++,get_slice(i)); current = (*this)(0,0,i); } - res.resize(-100,-100,j,-100,0); - } break; - case 'c' : { - cimg_forC(*this,i) - if ((*this)(0,0,0,i)!=current) { res.draw_image(0,0,0,j++,get_channel(i)); current = (*this)(0,0,0,i); } - res.resize(-100,-100,-100,j,0); - } break; - default : { - res.unroll('y'); - cimg_foroff(*this,i) - if ((*this)[i]!=current) res[j++] = current = (*this)[i]; - res.resize(-100,j,-100,-100,0); - } - } - return res; - } - - //! Invert endianness of all pixel values. - /** - **/ - CImg& invert_endianness() { - cimg::invert_endianness(_data,size()); - return *this; - } - - //! Invert endianness of all pixel values \newinstance. - CImg get_invert_endianness() const { - return (+*this).invert_endianness(); - } - - //! Fill image with random values in specified range. - /** - \param val_min Minimal authorized random value. - \param val_max Maximal authorized random value. - \note Random variables are uniformely distributed in [val_min,val_max]. - **/ - CImg& rand(const T& val_min, const T& val_max) { - const float delta = (float)val_max - (float)val_min + (cimg::type::is_float()?0:1); - if (cimg::type::is_float()) cimg_for(*this,ptrd,T) *ptrd = (T)(val_min + cimg::rand()*delta); - else cimg_for(*this,ptrd,T) *ptrd = cimg::min(val_max,(T)(val_min + cimg::rand()*delta)); - return *this; - } - - //! Fill image with random values in specified range \newinstance. - CImg get_rand(const T& val_min, const T& val_max) const { - return (+*this).rand(val_min,val_max); - } - - //! Round pixel values. - /** - \param y Rounding precision. - \param rounding_type Rounding type. Can be: - - \c -1: Backward. - - \c 0: Nearest. - - \c 1: Forward. - **/ - CImg& round(const double y=1, const int rounding_type=0) { - if (y>0) - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=8192)) - cimg_rof(*this,ptrd,T) *ptrd = cimg::round(*ptrd,y,rounding_type); - return *this; - } - - //! Round pixel values \newinstance. - CImg get_round(const double y=1, const unsigned int rounding_type=0) const { - return (+*this).round(y,rounding_type); - } - - //! Add random noise to pixel values. - /** - \param sigma Amplitude of the random additive noise. If \p sigma<0, it stands for a percentage of the - global value range. - \param noise_type Type of additive noise (can be \p 0=gaussian, \p 1=uniform, \p 2=Salt and Pepper, - \p 3=Poisson or \p 4=Rician). - \return A reference to the modified image instance. - \note - - For Poisson noise (\p noise_type=3), parameter \p sigma is ignored, as Poisson noise only depends on - the image value itself. - - Function \p CImg::get_noise() is also defined. It returns a non-shared modified copy of the image instance. - \par Example - \code - const CImg img("reference.jpg"), res = img.get_noise(40); - (img,res.normalize(0,255)).display(); - \endcode - \image html ref_noise.jpg - **/ - CImg& noise(const double sigma, const unsigned int noise_type=0) { - if (is_empty()) return *this; - const Tfloat vmin = (Tfloat)cimg::type::min(), vmax = (Tfloat)cimg::type::max(); - Tfloat nsigma = (Tfloat)sigma, m = 0, M = 0; - if (nsigma==0 && noise_type!=3) return *this; - if (nsigma<0 || noise_type==2) m = (Tfloat)min_max(M); - if (nsigma<0) nsigma = (Tfloat)(-nsigma*(M-m)/100.0); - switch (noise_type) { - case 0 : { // Gaussian noise - cimg_rof(*this,ptrd,T) { - Tfloat val = (Tfloat)(*ptrd + nsigma*cimg::grand()); - if (val>vmax) val = vmax; - if (valvmax) val = vmax; - if (val::is_float()?1:cimg::type::max()); } - cimg_rof(*this,ptrd,T) if (cimg::rand(100)vmax) val = vmax; - if (val get_noise(const double sigma, const unsigned int noise_type=0) const { - return (+*this).noise(sigma,noise_type); - } - - //! Linearly normalize pixel values. - /** - \param min_value Minimum desired value of the resulting image. - \param max_value Maximum desired value of the resulting image. - \par Example - \code - const CImg img("reference.jpg"), res = img.get_normalize(160,220); - (img,res).display(); - \endcode - \image html ref_normalize2.jpg - **/ - CImg& normalize(const T& min_value, const T& max_value) { - if (is_empty()) return *this; - const T a = min_value=65536)) - cimg_rof(*this,ptrd,T) *ptrd = (T)((*ptrd - fm)/(fM - fm)*(b - a) + a); - return *this; - } - - //! Linearly normalize pixel values \newinstance. - CImg get_normalize(const T& min_value, const T& max_value) const { - return CImg(*this,false).normalize((Tfloat)min_value,(Tfloat)max_value); - } - - //! Normalize multi-valued pixels of the image instance, with respect to their L2-norm. - /** - \par Example - \code - const CImg img("reference.jpg"), res = img.get_normalize(); - (img,res.normalize(0,255)).display(); - \endcode - \image html ref_normalize.jpg - **/ - CImg& normalize() { - const ulongT whd = (ulongT)_width*_height*_depth; - cimg_pragma_openmp(parallel for collapse(2) if (_width>=512 && _height*_depth>=16)) - cimg_forYZ(*this,y,z) { - T *ptrd = data(0,y,z,0); - cimg_forX(*this,x) { - const T *ptrs = ptrd; - float n = 0; - cimg_forC(*this,c) { n+=cimg::sqr((float)*ptrs); ptrs+=whd; } - n = (float)std::sqrt(n); - T *_ptrd = ptrd++; - if (n>0) cimg_forC(*this,c) { *_ptrd = (T)(*_ptrd/n); _ptrd+=whd; } - else cimg_forC(*this,c) { *_ptrd = (T)0; _ptrd+=whd; } - } - } - return *this; - } - - //! Normalize multi-valued pixels of the image instance, with respect to their L2-norm \newinstance. - CImg get_normalize() const { - return CImg(*this,false).normalize(); - } - - //! Compute Lp-norm of each multi-valued pixel of the image instance. - /** - \param norm_type Type of computed vector norm (can be \p -1=Linf, or \p>=0). - \par Example - \code - const CImg img("reference.jpg"), res = img.get_norm(); - (img,res.normalize(0,255)).display(); - \endcode - \image html ref_norm.jpg - **/ - CImg& norm(const int norm_type=2) { - if (_spectrum==1 && norm_type) return abs(); - return get_norm(norm_type).move_to(*this); - } - - //! Compute L2-norm of each multi-valued pixel of the image instance \newinstance. - CImg get_norm(const int norm_type=2) const { - if (is_empty()) return *this; - if (_spectrum==1 && norm_type) return get_abs(); - const ulongT whd = (ulongT)_width*_height*_depth; - CImg res(_width,_height,_depth); - switch (norm_type) { - case -1 : { // Linf-norm. - cimg_pragma_openmp(parallel for collapse(2) if (_width>=512 && _height*_depth>=16)) - cimg_forYZ(*this,y,z) { - const ulongT off = (ulongT)offset(0,y,z); - const T *ptrs = _data + off; - Tfloat *ptrd = res._data + off; - cimg_forX(*this,x) { - Tfloat n = 0; - const T *_ptrs = ptrs++; - cimg_forC(*this,c) { const Tfloat val = (Tfloat)cimg::abs(*_ptrs); if (val>n) n = val; _ptrs+=whd; } - *(ptrd++) = n; - } - } - } break; - case 0 : { // L0-norm. - cimg_pragma_openmp(parallel for collapse(2) if (_width>=512 && _height*_depth>=16)) - cimg_forYZ(*this,y,z) { - const ulongT off = (ulongT)offset(0,y,z); - const T *ptrs = _data + off; - Tfloat *ptrd = res._data + off; - cimg_forX(*this,x) { - unsigned int n = 0; - const T *_ptrs = ptrs++; - cimg_forC(*this,c) { n+=*_ptrs==0?0:1; _ptrs+=whd; } - *(ptrd++) = (Tfloat)n; - } - } - } break; - case 1 : { // L1-norm. - cimg_pragma_openmp(parallel for collapse(2) if (_width>=512 && _height*_depth>=16)) - cimg_forYZ(*this,y,z) { - const ulongT off = (ulongT)offset(0,y,z); - const T *ptrs = _data + off; - Tfloat *ptrd = res._data + off; - cimg_forX(*this,x) { - Tfloat n = 0; - const T *_ptrs = ptrs++; - cimg_forC(*this,c) { n+=cimg::abs(*_ptrs); _ptrs+=whd; } - *(ptrd++) = n; - } - } - } break; - case 2 : { // L2-norm. - cimg_pragma_openmp(parallel for collapse(2) if (_width>=512 && _height*_depth>=16)) - cimg_forYZ(*this,y,z) { - const ulongT off = (ulongT)offset(0,y,z); - const T *ptrs = _data + off; - Tfloat *ptrd = res._data + off; - cimg_forX(*this,x) { - Tfloat n = 0; - const T *_ptrs = ptrs++; - cimg_forC(*this,c) { n+=cimg::sqr((Tfloat)*_ptrs); _ptrs+=whd; } - *(ptrd++) = (Tfloat)std::sqrt((Tfloat)n); - } - } - } break; - default : { // Linf-norm. - cimg_pragma_openmp(parallel for collapse(2) if (_width>=512 && _height*_depth>=16)) - cimg_forYZ(*this,y,z) { - const ulongT off = (ulongT)offset(0,y,z); - const T *ptrs = _data + off; - Tfloat *ptrd = res._data + off; - cimg_forX(*this,x) { - Tfloat n = 0; - const T *_ptrs = ptrs++; - cimg_forC(*this,c) { n+=std::pow(cimg::abs((Tfloat)*_ptrs),(Tfloat)norm_type); _ptrs+=whd; } - *(ptrd++) = (Tfloat)std::pow((Tfloat)n,1/(Tfloat)norm_type); - } - } - } - } - return res; - } - - //! Cut pixel values in specified range. - /** - \param min_value Minimum desired value of the resulting image. - \param max_value Maximum desired value of the resulting image. - \par Example - \code - const CImg img("reference.jpg"), res = img.get_cut(160,220); - (img,res).display(); - \endcode - \image html ref_cut.jpg - **/ - CImg& cut(const T& min_value, const T& max_value) { - if (is_empty()) return *this; - const T a = min_value=32768)) - cimg_rof(*this,ptrd,T) *ptrd = (*ptrdb)?b:*ptrd); - return *this; - } - - //! Cut pixel values in specified range \newinstance. - CImg get_cut(const T& min_value, const T& max_value) const { - return (+*this).cut(min_value,max_value); - } - - //! Uniformly quantize pixel values. - /** - \param nb_levels Number of quantization levels. - \param keep_range Tells if resulting values keep the same range as the original ones. - \par Example - \code - const CImg img("reference.jpg"), res = img.get_quantize(4); - (img,res).display(); - \endcode - \image html ref_quantize.jpg - **/ - CImg& quantize(const unsigned int nb_levels, const bool keep_range=true) { - if (!nb_levels) - throw CImgArgumentException(_cimg_instance - "quantize(): Invalid quantization request with 0 values.", - cimg_instance); - - if (is_empty()) return *this; - Tfloat m, M = (Tfloat)max_min(m), range = M - m; - if (range>0) { - if (keep_range) - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=32768)) - cimg_rof(*this,ptrd,T) { - const unsigned int val = (unsigned int)((*ptrd-m)*nb_levels/range); - *ptrd = (T)(m + cimg::min(val,nb_levels - 1)*range/nb_levels); - } else - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=32768)) - cimg_rof(*this,ptrd,T) { - const unsigned int val = (unsigned int)((*ptrd-m)*nb_levels/range); - *ptrd = (T)cimg::min(val,nb_levels - 1); - } - } - return *this; - } - - //! Uniformly quantize pixel values \newinstance. - CImg get_quantize(const unsigned int n, const bool keep_range=true) const { - return (+*this).quantize(n,keep_range); - } - - //! Threshold pixel values. - /** - \param value Threshold value - \param soft_threshold Tells if soft thresholding must be applied (instead of hard one). - \param strict_threshold Tells if threshold value is strict. - \par Example - \code - const CImg img("reference.jpg"), res = img.get_threshold(128); - (img,res.normalize(0,255)).display(); - \endcode - \image html ref_threshold.jpg - **/ - CImg& threshold(const T& value, const bool soft_threshold=false, const bool strict_threshold=false) { - if (is_empty()) return *this; - if (strict_threshold) { - if (soft_threshold) - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=32768)) - cimg_rof(*this,ptrd,T) { - const T v = *ptrd; - *ptrd = v>value?(T)(v-value):v<-(float)value?(T)(v + value):(T)0; - } - else - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=65536)) - cimg_rof(*this,ptrd,T) *ptrd = *ptrd>value?(T)1:(T)0; - } else { - if (soft_threshold) - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=32768)) - cimg_rof(*this,ptrd,T) { - const T v = *ptrd; - *ptrd = v>=value?(T)(v-value):v<=-(float)value?(T)(v + value):(T)0; - } - else - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=65536)) - cimg_rof(*this,ptrd,T) *ptrd = *ptrd>=value?(T)1:(T)0; - } - return *this; - } - - //! Threshold pixel values \newinstance. - CImg get_threshold(const T& value, const bool soft_threshold=false, const bool strict_threshold=false) const { - return (+*this).threshold(value,soft_threshold,strict_threshold); - } - - //! Compute the histogram of pixel values. - /** - \param nb_levels Number of desired histogram levels. - \param min_value Minimum pixel value considered for the histogram computation. - All pixel values lower than \p min_value will not be counted. - \param max_value Maximum pixel value considered for the histogram computation. - All pixel values higher than \p max_value will not be counted. - \note - - The histogram H of an image I is the 1d function where H(x) counts the number of occurences of the value x - in the image I. - - The resulting histogram is always defined in 1d. Histograms of multi-valued images are not multi-dimensional. - \par Example - \code - const CImg img = CImg("reference.jpg").histogram(256); - img.display_graph(0,3); - \endcode - \image html ref_histogram.jpg - **/ - CImg& histogram(const unsigned int nb_levels, const T& min_value, const T& max_value) { - return get_histogram(nb_levels,min_value,max_value).move_to(*this); - } - - //! Compute the histogram of pixel values \overloading. - CImg& histogram(const unsigned int nb_levels) { - return get_histogram(nb_levels).move_to(*this); - } - - //! Compute the histogram of pixel values \newinstance. - CImg get_histogram(const unsigned int nb_levels, const T& min_value, const T& max_value) const { - if (!nb_levels || is_empty()) return CImg(); - const double - vmin = (double)(min_value res(nb_levels,1,1,1,0); - cimg_rof(*this,ptrs,T) { - const T val = *ptrs; - if (val>=vmin && val<=vmax) ++res[val==vmax?nb_levels - 1:(unsigned int)((val - vmin)*nb_levels/(vmax - vmin))]; - } - return res; - } - - //! Compute the histogram of pixel values \newinstance. - CImg get_histogram(const unsigned int nb_levels) const { - if (!nb_levels || is_empty()) return CImg(); - T vmax = 0, vmin = min_max(vmax); - return get_histogram(nb_levels,vmin,vmax); - } - - //! Equalize histogram of pixel values. - /** - \param nb_levels Number of histogram levels used for the equalization. - \param min_value Minimum pixel value considered for the histogram computation. - All pixel values lower than \p min_value will not be counted. - \param max_value Maximum pixel value considered for the histogram computation. - All pixel values higher than \p max_value will not be counted. - \par Example - \code - const CImg img("reference.jpg"), res = img.get_equalize(256); - (img,res).display(); - \endcode - \image html ref_equalize.jpg - **/ - CImg& equalize(const unsigned int nb_levels, const T& min_value, const T& max_value) { - if (!nb_levels || is_empty()) return *this; - const T - vmin = min_value hist = get_histogram(nb_levels,vmin,vmax); - ulongT cumul = 0; - cimg_forX(hist,pos) { cumul+=hist[pos]; hist[pos] = cumul; } - if (!cumul) cumul = 1; - cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=1048576)) - cimg_rof(*this,ptrd,T) { - const int pos = (int)((*ptrd-vmin)*(nb_levels - 1.)/(vmax-vmin)); - if (pos>=0 && pos<(int)nb_levels) *ptrd = (T)(vmin + (vmax-vmin)*hist[pos]/cumul); - } - return *this; - } - - //! Equalize histogram of pixel values \overloading. - CImg& equalize(const unsigned int nb_levels) { - if (!nb_levels || is_empty()) return *this; - T vmax = 0, vmin = min_max(vmax); - return equalize(nb_levels,vmin,vmax); - } - - //! Equalize histogram of pixel values \newinstance. - CImg get_equalize(const unsigned int nblevels, const T& val_min, const T& val_max) const { - return (+*this).equalize(nblevels,val_min,val_max); - } - - //! Equalize histogram of pixel values \newinstance. - CImg get_equalize(const unsigned int nblevels) const { - return (+*this).equalize(nblevels); - } - - //! Index multi-valued pixels regarding to a specified colormap. - /** - \param colormap Multi-valued colormap used as the basis for multi-valued pixel indexing. - \param dithering Level of dithering (0=disable, 1=standard level). - \param map_indexes Tell if the values of the resulting image are the colormap indices or the colormap vectors. - \note - - \p img.index(colormap,dithering,1) is equivalent to img.index(colormap,dithering,0).map(colormap). - \par Example - \code - const CImg img("reference.jpg"), colormap(3,1,1,3, 0,128,255, 0,128,255, 0,128,255); - const CImg res = img.get_index(colormap,1,true); - (img,res).display(); - \endcode - \image html ref_index.jpg - **/ - template - CImg& index(const CImg& colormap, const float dithering=1, const bool map_indexes=false) { - return get_index(colormap,dithering,map_indexes).move_to(*this); - } - - //! Index multi-valued pixels regarding to a specified colormap \newinstance. - template - CImg::Tuint> - get_index(const CImg& colormap, const float dithering=1, const bool map_indexes=true) const { - if (colormap._spectrum!=_spectrum) - throw CImgArgumentException(_cimg_instance - "index(): Instance and specified colormap (%u,%u,%u,%u,%p) " - "have incompatible dimensions.", - cimg_instance, - colormap._width,colormap._height,colormap._depth,colormap._spectrum,colormap._data); - - typedef typename CImg::Tuint tuint; - if (is_empty()) return CImg(); - const ulongT - whd = (ulongT)_width*_height*_depth, - pwhd = (ulongT)colormap._width*colormap._height*colormap._depth; - CImg res(_width,_height,_depth,map_indexes?_spectrum:1); - tuint *ptrd = res._data; - if (dithering>0) { // Dithered versions. - const float ndithering = (dithering<0?0:dithering>1?1:dithering)/16; - Tfloat valm = 0, valM = (Tfloat)max_min(valm); - if (valm==valM && valm>=0 && valM<=255) { valm = 0; valM = 255; } - CImg cache = get_crop(-1,0,0,0,_width,1,0,_spectrum - 1); - Tfloat *cache_current = cache.data(1,0,0,0), *cache_next = cache.data(1,1,0,0); - const ulongT cwhd = (ulongT)cache._width*cache._height*cache._depth; - switch (_spectrum) { - case 1 : { // Optimized for scalars. - cimg_forYZ(*this,y,z) { - if (yvalM?valM:_val0; - Tfloat distmin = cimg::type::max(); const t *ptrmin0 = colormap._data; - for (const t *ptrp0 = colormap._data, *ptrp_end = ptrp0 + pwhd; ptrp0valM?valM:_val0, - _val1 = (Tfloat)*ptrs1, val1 = _val1valM?valM:_val1; - Tfloat distmin = cimg::type::max(); const t *ptrmin0 = colormap._data; - for (const t *ptrp0 = colormap._data, *ptrp1 = ptrp0 + pwhd, *ptrp_end = ptrp1; ptrp0valM?valM:_val0, - _val1 = (Tfloat)*ptrs1, val1 = _val1valM?valM:_val1, - _val2 = (Tfloat)*ptrs2, val2 = _val2valM?valM:_val2; - Tfloat distmin = cimg::type::max(); const t *ptrmin0 = colormap._data; - for (const t *ptrp0 = colormap._data, *ptrp1 = ptrp0 + pwhd, *ptrp2 = ptrp1 + pwhd, - *ptrp_end = ptrp1; ptrp0::max(); const t *ptrmin = colormap._data; - for (const t *ptrp = colormap._data, *ptrp_end = ptrp + pwhd; ptrpvalM?valM:_val; - dist+=cimg::sqr((*_ptrs=val) - (Tfloat)*_ptrp); _ptrs+=cwhd; _ptrp+=pwhd; - } - if (dist=64 && _height*_depth>=16 && pwhd>=16)) - cimg_forYZ(*this,y,z) { - tuint *ptrd = res.data(0,y,z); - for (const T *ptrs0 = data(0,y,z), *ptrs_end = ptrs0 + _width; ptrs0::max(); const t *ptrmin0 = colormap._data; - for (const t *ptrp0 = colormap._data, *ptrp_end = ptrp0 + pwhd; ptrp0=64 && _height*_depth>=16 && pwhd>=16)) - cimg_forYZ(*this,y,z) { - tuint *ptrd = res.data(0,y,z), *ptrd1 = ptrd + whd; - for (const T *ptrs0 = data(0,y,z), *ptrs1 = ptrs0 + whd, *ptrs_end = ptrs0 + _width; ptrs0::max(); const t *ptrmin0 = colormap._data; - for (const t *ptrp0 = colormap._data, *ptrp1 = ptrp0 + pwhd, *ptrp_end = ptrp1; ptrp0=64 && _height*_depth>=16 && pwhd>=16)) - cimg_forYZ(*this,y,z) { - tuint *ptrd = res.data(0,y,z), *ptrd1 = ptrd + whd, *ptrd2 = ptrd1 + whd; - for (const T *ptrs0 = data(0,y,z), *ptrs1 = ptrs0 + whd, *ptrs2 = ptrs1 + whd, - *ptrs_end = ptrs0 + _width; ptrs0::max(); const t *ptrmin0 = colormap._data; - for (const t *ptrp0 = colormap._data, *ptrp1 = ptrp0 + pwhd, *ptrp2 = ptrp1 + pwhd, - *ptrp_end = ptrp1; ptrp0=64 && _height*_depth>=16 && pwhd>=16)) - cimg_forYZ(*this,y,z) { - tuint *ptrd = res.data(0,y,z); - for (const T *ptrs = data(0,y,z), *ptrs_end = ptrs + _width; ptrs::max(); const t *ptrmin = colormap._data; - for (const t *ptrp = colormap._data, *ptrp_end = ptrp + pwhd; ptrp img("reference.jpg"), - colormap1(3,1,1,3, 0,128,255, 0,128,255, 0,128,255), - colormap2(3,1,1,3, 255,0,0, 0,255,0, 0,0,255), - res = img.get_index(colormap1,0).map(colormap2); - (img,res).display(); - \endcode - \image html ref_map.jpg - **/ - template - CImg& map(const CImg& colormap, const unsigned int boundary_conditions=0) { - return get_map(colormap,boundary_conditions).move_to(*this); - } - - //! Map predefined colormap on the scalar (indexed) image instance \newinstance. - template - CImg get_map(const CImg& colormap, const unsigned int boundary_conditions=0) const { - if (_spectrum!=1 && colormap._spectrum!=1) - throw CImgArgumentException(_cimg_instance - "map(): Instance and specified colormap (%u,%u,%u,%u,%p) " - "have incompatible dimensions.", - cimg_instance, - colormap._width,colormap._height,colormap._depth,colormap._spectrum,colormap._data); - - const ulongT - whd = (ulongT)_width*_height*_depth, - pwhd = (ulongT)colormap._width*colormap._height*colormap._depth; - CImg res(_width,_height,_depth,colormap._spectrum==1?_spectrum:colormap._spectrum); - switch (colormap._spectrum) { - - case 1 : { // Optimized for scalars. - const T *ptrs = _data; - switch (boundary_conditions) { - case 2 : // Periodic boundaries. - cimg_for(res,ptrd,t) { - const ulongT ind = (ulongT)*(ptrs++); - *ptrd = colormap[ind%pwhd]; - } break; - case 1 : // Neumann boundaries. - cimg_for(res,ptrd,t) { - const longT ind = (longT)*(ptrs++); - *ptrd = colormap[ind<0?0:ind>=(longT)pwhd?pwhd - 1:ind]; - } break; - default : // Dirichlet boundaries. - cimg_for(res,ptrd,t) { - const ulongT ind = (ulongT)*(ptrs++); - *ptrd = ind=(longT)pwhd?(longT)pwhd - 1:_ind; - *(ptrd0++) = ptrp0[ind]; *(ptrd1++) = ptrp1[ind]; - } - } break; - default : { // Dirichlet boundaries. - const t *const ptrp0 = colormap._data, *ptrp1 = ptrp0 + pwhd; - t *ptrd0 = res._data, *ptrd1 = ptrd0 + whd; - for (const T *ptrs = _data, *ptrs_end = ptrs + whd; ptrs=(longT)pwhd?(longT)pwhd - 1:_ind; - *(ptrd0++) = ptrp0[ind]; *(ptrd1++) = ptrp1[ind]; *(ptrd2++) = ptrp2[ind]; - } - } break; - default : { // Dirichlet boundaries. - const t *const ptrp0 = colormap._data, *ptrp1 = ptrp0 + pwhd, *ptrp2 = ptrp1 + pwhd; - t *ptrd0 = res._data, *ptrd1 = ptrd0 + whd, *ptrd2 = ptrd1 + whd; - for (const T *ptrs = _data, *ptrs_end = ptrs + whd; ptrs=(longT)pwhd?(longT)pwhd - 1:_ind; - const t *ptrp = colormap._data + ind; - t *_ptrd = ptrd++; cimg_forC(res,c) { *_ptrd = *ptrp; _ptrd+=whd; ptrp+=pwhd; } - } - } break; - default : { // Dirichlet boundaries. - t *ptrd = res._data; - for (const T *ptrs = _data, *ptrs_end = ptrs + whd; ptrs& label(const bool is_high_connectivity=false, const Tfloat tolerance=0) { - return get_label(is_high_connectivity,tolerance).move_to(*this); - } - - //! Label connected components \newinstance. - CImg get_label(const bool is_high_connectivity=false, - const Tfloat tolerance=0) const { - if (is_empty()) return CImg(); - - // Create neighborhood tables. - int dx[13], dy[13], dz[13], nb = 0; - dx[nb] = 1; dy[nb] = 0; dz[nb++] = 0; - dx[nb] = 0; dy[nb] = 1; dz[nb++] = 0; - if (is_high_connectivity) { - dx[nb] = 1; dy[nb] = 1; dz[nb++] = 0; - dx[nb] = 1; dy[nb] = -1; dz[nb++] = 0; - } - if (_depth>1) { // 3d version. - dx[nb] = 0; dy[nb] = 0; dz[nb++]=1; - if (is_high_connectivity) { - dx[nb] = 1; dy[nb] = 1; dz[nb++] = -1; - dx[nb] = 1; dy[nb] = 0; dz[nb++] = -1; - dx[nb] = 1; dy[nb] = -1; dz[nb++] = -1; - dx[nb] = 0; dy[nb] = 1; dz[nb++] = -1; - - dx[nb] = 0; dy[nb] = 1; dz[nb++] = 1; - dx[nb] = 1; dy[nb] = -1; dz[nb++] = 1; - dx[nb] = 1; dy[nb] = 0; dz[nb++] = 1; - dx[nb] = 1; dy[nb] = 1; dz[nb++] = 1; - } - } - return _get_label(nb,dx,dy,dz,tolerance); - } - - //! Label connected components \overloading. - /** - \param connectivity_mask Mask of the neighboring pixels. - \param tolerance Tolerance used to determine if two neighboring pixels belong to the same region. - **/ - template - CImg& label(const CImg& connectivity_mask, const Tfloat tolerance=0) { - return get_label(connectivity_mask,tolerance).move_to(*this); - } - - //! Label connected components \newinstance. - template - CImg get_label(const CImg& connectivity_mask, - const Tfloat tolerance=0) const { - int nb = 0; - cimg_for(connectivity_mask,ptr,t) if (*ptr) ++nb; - CImg dx(nb,1,1,1,0), dy(nb,1,1,1,0), dz(nb,1,1,1,0); - nb = 0; - cimg_forXYZ(connectivity_mask,x,y,z) if ((x || y || z) && - connectivity_mask(x,y,z)) { - dx[nb] = x; dy[nb] = y; dz[nb++] = z; - } - return _get_label(nb,dx,dy,dz,tolerance); - } - - CImg _get_label(const unsigned int nb, const int - *const dx, const int *const dy, const int *const dz, - const Tfloat tolerance) const { - CImg res(_width,_height,_depth,_spectrum); - cimg_forC(*this,c) { - CImg _res = res.get_shared_channel(c); - - // Init label numbers. - ulongT *ptr = _res.data(); - cimg_foroff(_res,p) *(ptr++) = p; - - // For each neighbour-direction, label. - for (unsigned int n = 0; n& _system_strescape() { -#define cimg_system_strescape(c,s) case c : if (p!=ptrs) CImg(ptrs,(unsigned int)(p-ptrs),1,1,1,false).\ - move_to(list); \ - CImg(s,(unsigned int)std::strlen(s),1,1,1,false).move_to(list); ptrs = p + 1; break - CImgList list; - const T *ptrs = _data; - cimg_for(*this,p,T) switch ((int)*p) { - cimg_system_strescape('\\',"\\\\"); - cimg_system_strescape('\"',"\\\""); - cimg_system_strescape('!',"\"\\!\""); - cimg_system_strescape('`',"\\`"); - cimg_system_strescape('$',"\\$"); - } - if (ptrs(ptrs,(unsigned int)(end()-ptrs),1,1,1,false).move_to(list); - return (list>'x').move_to(*this); - } - - //@} - //--------------------------------- - // - //! \name Color Base Management - //@{ - //--------------------------------- - - //! Return colormap \e "default", containing 256 colors entries in RGB. - /** - \return The following \c 256x1x1x3 colormap is returned: - \image html ref_colormap_default.jpg - **/ - static const CImg& default_LUT256() { - static CImg colormap; - cimg::mutex(8); - if (!colormap) { - colormap.assign(1,256,1,3); - for (unsigned int index = 0, r = 16; r<256; r+=32) - for (unsigned int g = 16; g<256; g+=32) - for (unsigned int b = 32; b<256; b+=64) { - colormap(0,index,0) = (Tuchar)r; - colormap(0,index,1) = (Tuchar)g; - colormap(0,index++,2) = (Tuchar)b; - } - } - cimg::mutex(8,0); - return colormap; - } - - //! Return colormap \e "HSV", containing 256 colors entries in RGB. - /** - \return The following \c 256x1x1x3 colormap is returned: - \image html ref_colormap_hsv.jpg - **/ - static const CImg& HSV_LUT256() { - static CImg colormap; - cimg::mutex(8); - if (!colormap) { - CImg tmp(1,256,1,3,1); - tmp.get_shared_channel(0).sequence(0,359); - colormap = tmp.HSVtoRGB(); - } - cimg::mutex(8,0); - return colormap; - } - - //! Return colormap \e "lines", containing 256 colors entries in RGB. - /** - \return The following \c 256x1x1x3 colormap is returned: - \image html ref_colormap_lines.jpg - **/ - static const CImg& lines_LUT256() { - static const unsigned char pal[] = { - 217,62,88,75,1,237,240,12,56,160,165,116,1,1,204,2,15,248,148,185,133,141,46,246,222,116,16,5,207,226, - 17,114,247,1,214,53,238,0,95,55,233,235,109,0,17,54,33,0,90,30,3,0,94,27,19,0,68,212,166,130,0,15,7,119, - 238,2,246,198,0,3,16,10,13,2,25,28,12,6,2,99,18,141,30,4,3,140,12,4,30,233,7,10,0,136,35,160,168,184,20, - 233,0,1,242,83,90,56,180,44,41,0,6,19,207,5,31,214,4,35,153,180,75,21,76,16,202,218,22,17,2,136,71,74, - 81,251,244,148,222,17,0,234,24,0,200,16,239,15,225,102,230,186,58,230,110,12,0,7,129,249,22,241,37,219, - 1,3,254,210,3,212,113,131,197,162,123,252,90,96,209,60,0,17,0,180,249,12,112,165,43,27,229,77,40,195,12, - 87,1,210,148,47,80,5,9,1,137,2,40,57,205,244,40,8,252,98,0,40,43,206,31,187,0,180,1,69,70,227,131,108,0, - 223,94,228,35,248,243,4,16,0,34,24,2,9,35,73,91,12,199,51,1,249,12,103,131,20,224,2,70,32, - 233,1,165,3,8,154,246,233,196,5,0,6,183,227,247,195,208,36,0,0,226,160,210,198,69,153,210,1,23,8,192,2,4, - 137,1,0,52,2,249,241,129,0,0,234,7,238,71,7,32,15,157,157,252,158,2,250,6,13,30,11,162,0,199,21,11,27,224, - 4,157,20,181,111,187,218,3,0,11,158,230,196,34,223,22,248,135,254,210,157,219,0,117,239,3,255,4,227,5,247, - 11,4,3,188,111,11,105,195,2,0,14,1,21,219,192,0,183,191,113,241,1,12,17,248,0,48,7,19,1,254,212,0,239,246, - 0,23,0,250,165,194,194,17,3,253,0,24,6,0,141,167,221,24,212,2,235,243,0,0,205,1,251,133,204,28,4,6,1,10, - 141,21,74,12,236,254,228,19,1,0,214,1,186,13,13,6,13,16,27,209,6,216,11,207,251,59,32,9,155,23,19,235,143, - 116,6,213,6,75,159,23,6,0,228,4,10,245,249,1,7,44,234,4,102,174,0,19,239,103,16,15,18,8,214,22,4,47,244, - 255,8,0,251,173,1,212,252,250,251,252,6,0,29,29,222,233,246,5,149,0,182,180,13,151,0,203,183,0,35,149,0, - 235,246,254,78,9,17,203,73,11,195,0,3,5,44,0,0,237,5,106,6,130,16,214,20,168,247,168,4,207,11,5,1,232,251, - 129,210,116,231,217,223,214,27,45,38,4,177,186,249,7,215,172,16,214,27,249,230,236,2,34,216,217,0,175,30, - 243,225,244,182,20,212,2,226,21,255,20,0,2,13,62,13,191,14,76,64,20,121,4,118,0,216,1,147,0,2,210,1,215, - 95,210,236,225,184,46,0,248,24,11,1,9,141,250,243,9,221,233,160,11,147,2,55,8,23,12,253,9,0,54,0,231,6,3, - 141,8,2,246,9,180,5,11,8,227,8,43,110,242,1,130,5,97,36,10,6,219,86,133,11,108,6,1,5,244,67,19,28,0,174, - 154,16,127,149,252,188,196,196,228,244,9,249,0,0,0,37,170,32,250,0,73,255,23,3,224,234,38,195,198,0,255,87, - 33,221,174,31,3,0,189,228,6,153,14,144,14,108,197,0,9,206,245,254,3,16,253,178,248,0,95,125,8,0,3,168,21, - 23,168,19,50,240,244,185,0,1,144,10,168,31,82,1,13 }; - static const CImg colormap(pal,1,256,1,3,false); - return colormap; - } - - //! Return colormap \e "hot", containing 256 colors entries in RGB. - /** - \return The following \c 256x1x1x3 colormap is returned: - \image html ref_colormap_hot.jpg - **/ - static const CImg& hot_LUT256() { - static CImg colormap; - cimg::mutex(8); - if (!colormap) { - colormap.assign(1,4,1,3,0); - colormap[1] = colormap[2] = colormap[3] = colormap[6] = colormap[7] = colormap[11] = 255; - colormap.resize(1,256,1,3,3); - } - cimg::mutex(8,0); - return colormap; - } - - //! Return colormap \e "cool", containing 256 colors entries in RGB. - /** - \return The following \c 256x1x1x3 colormap is returned: - \image html ref_colormap_cool.jpg - **/ - static const CImg& cool_LUT256() { - static CImg colormap; - cimg::mutex(8); - if (!colormap) colormap.assign(1,2,1,3).fill(0,255,255,0,255,255).resize(1,256,1,3,3); - cimg::mutex(8,0); - return colormap; - } - - //! Return colormap \e "jet", containing 256 colors entries in RGB. - /** - \return The following \c 256x1x1x3 colormap is returned: - \image html ref_colormap_jet.jpg - **/ - static const CImg& jet_LUT256() { - static CImg colormap; - cimg::mutex(8); - if (!colormap) { - colormap.assign(1,4,1,3,0); - colormap[2] = colormap[3] = colormap[5] = colormap[6] = colormap[8] = colormap[9] = 255; - colormap.resize(1,256,1,3,3); - } - cimg::mutex(8,0); - return colormap; - } - - //! Return colormap \e "flag", containing 256 colors entries in RGB. - /** - \return The following \c 256x1x1x3 colormap is returned: - \image html ref_colormap_flag.jpg - **/ - static const CImg& flag_LUT256() { - static CImg colormap; - cimg::mutex(8); - if (!colormap) { - colormap.assign(1,4,1,3,0); - colormap[0] = colormap[1] = colormap[5] = colormap[9] = colormap[10] = 255; - colormap.resize(1,256,1,3,0,2); - } - cimg::mutex(8,0); - return colormap; - } - - //! Return colormap \e "cube", containing 256 colors entries in RGB. - /** - \return The following \c 256x1x1x3 colormap is returned: - \image html ref_colormap_cube.jpg - **/ - static const CImg& cube_LUT256() { - static CImg colormap; - cimg::mutex(8); - if (!colormap) { - colormap.assign(1,8,1,3,0); - colormap[1] = colormap[3] = colormap[5] = colormap[7] = - colormap[10] = colormap[11] = colormap[12] = colormap[13] = - colormap[20] = colormap[21] = colormap[22] = colormap[23] = 255; - colormap.resize(1,256,1,3,3); - } - cimg::mutex(8,0); - return colormap; - } - - //! Convert pixel values from sRGB to RGB color spaces. - CImg& sRGBtoRGB() { - cimg_for(*this,ptr,T) { - const Tfloat - sval = (Tfloat)*ptr, - nsval = (sval<0?0:sval>255?255:sval)/255, - val = (Tfloat)(nsval<=0.04045f?nsval/12.92f:std::pow((nsval + 0.055f)/(1.055f),2.4f)); - *ptr = (T)(val*255); - } - return *this; - } - - //! Convert pixel values from sRGB to RGB color spaces \newinstance. - CImg get_sRGBtoRGB() const { - return CImg(*this,false).sRGBtoRGB(); - } - - //! Convert pixel values from RGB to sRGB color spaces. - CImg& RGBtosRGB() { - cimg_for(*this,ptr,T) { - const Tfloat - val = (Tfloat)*ptr, - nval = (val<0?0:val>255?255:val)/255, - sval = (Tfloat)(nval<=0.0031308f?nval*12.92f:1.055f*std::pow(nval,0.416667f)-0.055f); - *ptr = (T)(sval*255); - } - return *this; - } - - //! Convert pixel values from RGB to sRGB color spaces \newinstance. - CImg get_RGBtosRGB() const { - return CImg(*this,false).RGBtosRGB(); - } - - //! Convert pixel values from RGB to HSV color spaces. - CImg& RGBtoHSV() { - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "RGBtoHSV(): Instance is not a RGB image.", - cimg_instance); - - T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - const Tfloat - R = (Tfloat)*p1, - G = (Tfloat)*p2, - B = (Tfloat)*p3, - nR = (R<0?0:(R>255?255:R))/255, - nG = (G<0?0:(G>255?255:G))/255, - nB = (B<0?0:(B>255?255:B))/255, - m = cimg::min(nR,nG,nB), - M = cimg::max(nR,nG,nB); - Tfloat H = 0, S = 0; - if (M!=m) { - const Tfloat - f = (nR==m)?(nG-nB):((nG==m)?(nB-nR):(nR-nG)), - i = (Tfloat)((nR==m)?3:((nG==m)?5:1)); - H = (i-f/(M-m)); - if (H>=6) H-=6; - H*=60; - S = (M-m)/M; - } - *(p1++) = (T)H; - *(p2++) = (T)S; - *(p3++) = (T)M; - } - return *this; - } - - //! Convert pixel values from RGB to HSV color spaces \newinstance. - CImg get_RGBtoHSV() const { - return CImg(*this,false).RGBtoHSV(); - } - - //! Convert pixel values from HSV to RGB color spaces. - CImg& HSVtoRGB() { - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "HSVtoRGB(): Instance is not a HSV image.", - cimg_instance); - - T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - Tfloat - H = cimg::mod((Tfloat)*p1,(Tfloat)360), - S = (Tfloat)*p2, - V = (Tfloat)*p3, - R = 0, G = 0, B = 0; - if (H==0 && S==0) R = G = B = V; - else { - H/=60; - const int i = (int)std::floor(H); - const Tfloat - f = (i&1)?(H - i):(1 - H + i), - m = V*(1 - S), - n = V*(1 - S*f); - switch (i) { - case 6 : - case 0 : R = V; G = n; B = m; break; - case 1 : R = n; G = V; B = m; break; - case 2 : R = m; G = V; B = n; break; - case 3 : R = m; G = n; B = V; break; - case 4 : R = n; G = m; B = V; break; - case 5 : R = V; G = m; B = n; break; - } - } - R*=255; G*=255; B*=255; - *(p1++) = (T)(R<0?0:(R>255?255:R)); - *(p2++) = (T)(G<0?0:(G>255?255:G)); - *(p3++) = (T)(B<0?0:(B>255?255:B)); - } - return *this; - } - - //! Convert pixel values from HSV to RGB color spaces \newinstance. - CImg get_HSVtoRGB() const { - return CImg(*this,false).HSVtoRGB(); - } - - //! Convert pixel values from RGB to HSL color spaces. - CImg& RGBtoHSL() { - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "RGBtoHSL(): Instance is not a RGB image.", - cimg_instance); - - T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - const Tfloat - R = (Tfloat)*p1, - G = (Tfloat)*p2, - B = (Tfloat)*p3, - nR = (R<0?0:(R>255?255:R))/255, - nG = (G<0?0:(G>255?255:G))/255, - nB = (B<0?0:(B>255?255:B))/255, - m = cimg::min(nR,nG,nB), - M = cimg::max(nR,nG,nB), - L = (m + M)/2; - Tfloat H = 0, S = 0; - if (M==m) H = S = 0; - else { - const Tfloat - f = (nR==m)?(nG-nB):((nG==m)?(nB-nR):(nR-nG)), - i = (nR==m)?3.0f:((nG==m)?5.0f:1.0f); - H = (i-f/(M-m)); - if (H>=6) H-=6; - H*=60; - S = (2*L<=1)?((M - m)/(M + m)):((M - m)/(2 - M - m)); - } - *(p1++) = (T)H; - *(p2++) = (T)S; - *(p3++) = (T)L; - } - return *this; - } - - //! Convert pixel values from RGB to HSL color spaces \newinstance. - CImg get_RGBtoHSL() const { - return CImg< Tfloat>(*this,false).RGBtoHSL(); - } - - //! Convert pixel values from HSL to RGB color spaces. - CImg& HSLtoRGB() { - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "HSLtoRGB(): Instance is not a HSL image.", - cimg_instance); - - T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - const Tfloat - H = cimg::mod((Tfloat)*p1,(Tfloat)360), - S = (Tfloat)*p2, - L = (Tfloat)*p3, - q = 2*L<1?L*(1 + S):(L + S - L*S), - p = 2*L - q, - h = H/360, - tr = h + 1.0f/3, - tg = h, - tb = h - 1.0f/3, - ntr = tr<0?tr + 1:(tr>1?tr - 1:tr), - ntg = tg<0?tg + 1:(tg>1?tg - 1:tg), - ntb = tb<0?tb + 1:(tb>1?tb - 1:tb), - R = 255*(6*ntr<1?p + (q - p)*6*ntr:(2*ntr<1?q:(3*ntr<2?p + (q - p)*6*(2.0f/3 - ntr):p))), - G = 255*(6*ntg<1?p + (q - p)*6*ntg:(2*ntg<1?q:(3*ntg<2?p + (q - p)*6*(2.0f/3 - ntg):p))), - B = 255*(6*ntb<1?p + (q - p)*6*ntb:(2*ntb<1?q:(3*ntb<2?p + (q - p)*6*(2.0f/3 - ntb):p))); - *(p1++) = (T)(R<0?0:(R>255?255:R)); - *(p2++) = (T)(G<0?0:(G>255?255:G)); - *(p3++) = (T)(B<0?0:(B>255?255:B)); - } - return *this; - } - - //! Convert pixel values from HSL to RGB color spaces \newinstance. - CImg get_HSLtoRGB() const { - return CImg(*this,false).HSLtoRGB(); - } - - //! Convert pixel values from RGB to HSI color spaces. - CImg& RGBtoHSI() { - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "RGBtoHSI(): Instance is not a RGB image.", - cimg_instance); - - T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - const Tfloat - R = (Tfloat)*p1, - G = (Tfloat)*p2, - B = (Tfloat)*p3, - nR = (R<0?0:(R>255?255:R))/255, - nG = (G<0?0:(G>255?255:G))/255, - nB = (B<0?0:(B>255?255:B))/255, - m = cimg::min(nR,nG,nB), - theta = (Tfloat)(std::acos(0.5f*((nR - nG) + (nR - nB))/ - std::sqrt(std::pow(nR - nG,2) + (nR - nB)*(nG - nB)))*180/cimg::PI), - sum = nR + nG + nB; - Tfloat H = 0, S = 0, I = 0; - if (theta>0) H = (nB<=nG)?theta:360 - theta; - if (sum>0) S = 1 - 3/sum*m; - I = sum/3; - *(p1++) = (T)H; - *(p2++) = (T)S; - *(p3++) = (T)I; - } - return *this; - } - - //! Convert pixel values from RGB to HSI color spaces \newinstance. - CImg get_RGBtoHSI() const { - return CImg(*this,false).RGBtoHSI(); - } - - //! Convert pixel values from HSI to RGB color spaces. - CImg& HSItoRGB() { - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "HSItoRGB(): Instance is not a HSI image.", - cimg_instance); - - T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - Tfloat - H = cimg::mod((Tfloat)*p1,(Tfloat)360), - S = (Tfloat)*p2, - I = (Tfloat)*p3, - a = I*(1-S), - R = 0, G = 0, B = 0; - if (H<120) { - B = a; - R = (Tfloat)(I*(1 + S*std::cos(H*cimg::PI/180)/std::cos((60 - H)*cimg::PI/180))); - G = 3*I - (R + B); - } else if (H<240) { - H-=120; - R = a; - G = (Tfloat)(I*(1 + S*std::cos(H*cimg::PI/180)/std::cos((60 - H)*cimg::PI/180))); - B = 3*I - (R + G); - } else { - H-=240; - G = a; - B = (Tfloat)(I*(1 + S*std::cos(H*cimg::PI/180)/std::cos((60 - H)*cimg::PI/180))); - R = 3*I - (G + B); - } - R*=255; G*=255; B*=255; - *(p1++) = (T)(R<0?0:(R>255?255:R)); - *(p2++) = (T)(G<0?0:(G>255?255:G)); - *(p3++) = (T)(B<0?0:(B>255?255:B)); - } - return *this; - } - - //! Convert pixel values from HSI to RGB color spaces \newinstance. - CImg get_HSItoRGB() const { - return CImg< Tuchar>(*this,false).HSItoRGB(); - } - - //! Convert pixel values from RGB to YCbCr color spaces. - CImg& RGBtoYCbCr() { - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "RGBtoYCbCr(): Instance is not a RGB image.", - cimg_instance); - - T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - const Tfloat - R = (Tfloat)*p1, - G = (Tfloat)*p2, - B = (Tfloat)*p3, - Y = (66*R + 129*G + 25*B + 128)/256 + 16, - Cb = (-38*R - 74*G + 112*B + 128)/256 + 128, - Cr = (112*R - 94*G - 18*B + 128)/256 + 128; - *(p1++) = (T)(Y<0?0:(Y>255?255:Y)); - *(p2++) = (T)(Cb<0?0:(Cb>255?255:Cb)); - *(p3++) = (T)(Cr<0?0:(Cr>255?255:Cr)); - } - return *this; - } - - //! Convert pixel values from RGB to YCbCr color spaces \newinstance. - CImg get_RGBtoYCbCr() const { - return CImg(*this,false).RGBtoYCbCr(); - } - - //! Convert pixel values from RGB to YCbCr color spaces. - CImg& YCbCrtoRGB() { - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "YCbCrtoRGB(): Instance is not a YCbCr image.", - cimg_instance); - - T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - const Tfloat - Y = (Tfloat)*p1 - 16, - Cb = (Tfloat)*p2 - 128, - Cr = (Tfloat)*p3 - 128, - R = (298*Y + 409*Cr + 128)/256, - G = (298*Y - 100*Cb - 208*Cr + 128)/256, - B = (298*Y + 516*Cb + 128)/256; - *(p1++) = (T)(R<0?0:(R>255?255:R)); - *(p2++) = (T)(G<0?0:(G>255?255:G)); - *(p3++) = (T)(B<0?0:(B>255?255:B)); - } - return *this; - } - - //! Convert pixel values from RGB to YCbCr color spaces \newinstance. - CImg get_YCbCrtoRGB() const { - return CImg(*this,false).YCbCrtoRGB(); - } - - //! Convert pixel values from RGB to YUV color spaces. - CImg& RGBtoYUV() { - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "RGBtoYUV(): Instance is not a RGB image.", - cimg_instance); - - T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - const Tfloat - R = (Tfloat)*p1/255, - G = (Tfloat)*p2/255, - B = (Tfloat)*p3/255, - Y = 0.299f*R + 0.587f*G + 0.114f*B; - *(p1++) = (T)Y; - *(p2++) = (T)(0.492f*(B-Y)); - *(p3++) = (T)(0.877*(R-Y)); - } - return *this; - } - - //! Convert pixel values from RGB to YUV color spaces \newinstance. - CImg get_RGBtoYUV() const { - return CImg(*this,false).RGBtoYUV(); - } - - //! Convert pixel values from YUV to RGB color spaces. - CImg& YUVtoRGB() { - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "YUVtoRGB(): Instance is not a YUV image.", - cimg_instance); - - T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - const Tfloat - Y = (Tfloat)*p1, - U = (Tfloat)*p2, - V = (Tfloat)*p3, - R = (Y + 1.140f*V)*255, - G = (Y - 0.395f*U - 0.581f*V)*255, - B = (Y + 2.032f*U)*255; - *(p1++) = (T)(R<0?0:(R>255?255:R)); - *(p2++) = (T)(G<0?0:(G>255?255:G)); - *(p3++) = (T)(B<0?0:(B>255?255:B)); - } - return *this; - } - - //! Convert pixel values from YUV to RGB color spaces \newinstance. - CImg get_YUVtoRGB() const { - return CImg< Tuchar>(*this,false).YUVtoRGB(); - } - - //! Convert pixel values from RGB to CMY color spaces. - CImg& RGBtoCMY() { - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "RGBtoCMY(): Instance is not a RGB image.", - cimg_instance); - - T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - const Tfloat - R = (Tfloat)*p1, - G = (Tfloat)*p2, - B = (Tfloat)*p3, - C = 255 - R, - M = 255 - G, - Y = 255 - B; - *(p1++) = (T)(C<0?0:(C>255?255:C)); - *(p2++) = (T)(M<0?0:(M>255?255:M)); - *(p3++) = (T)(Y<0?0:(Y>255?255:Y)); - } - return *this; - } - - //! Convert pixel values from RGB to CMY color spaces \newinstance. - CImg get_RGBtoCMY() const { - return CImg(*this,false).RGBtoCMY(); - } - - //! Convert pixel values from CMY to RGB color spaces. - CImg& CMYtoRGB() { - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "CMYtoRGB(): Instance is not a CMY image.", - cimg_instance); - - T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - const Tfloat - C = (Tfloat)*p1, - M = (Tfloat)*p2, - Y = (Tfloat)*p3, - R = 255 - C, - G = 255 - M, - B = 255 - Y; - *(p1++) = (T)(R<0?0:(R>255?255:R)); - *(p2++) = (T)(G<0?0:(G>255?255:G)); - *(p3++) = (T)(B<0?0:(B>255?255:B)); - } - return *this; - } - - //! Convert pixel values from CMY to RGB color spaces \newinstance. - CImg get_CMYtoRGB() const { - return CImg(*this,false).CMYtoRGB(); - } - - //! Convert pixel values from CMY to CMYK color spaces. - CImg& CMYtoCMYK() { - return get_CMYtoCMYK().move_to(*this); - } - - //! Convert pixel values from CMY to CMYK color spaces \newinstance. - CImg get_CMYtoCMYK() const { - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "CMYtoCMYK(): Instance is not a CMY image.", - cimg_instance); - - CImg res(_width,_height,_depth,4); - const T *ps1 = data(0,0,0,0), *ps2 = data(0,0,0,1), *ps3 = data(0,0,0,2); - Tfloat *pd1 = res.data(0,0,0,0), *pd2 = res.data(0,0,0,1), *pd3 = res.data(0,0,0,2), *pd4 = res.data(0,0,0,3); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - Tfloat - C = (Tfloat)*(ps1++), - M = (Tfloat)*(ps2++), - Y = (Tfloat)*(ps3++), - K = cimg::min(C,M,Y); - if (K>=255) C = M = Y = 0; - else { const Tfloat K1 = 255 - K; C = 255*(C - K)/K1; M = 255*(M - K)/K1; Y = 255*(Y - K)/K1; } - *(pd1++) = (Tfloat)(C<0?0:(C>255?255:C)); - *(pd2++) = (Tfloat)(M<0?0:(M>255?255:M)); - *(pd3++) = (Tfloat)(Y<0?0:(Y>255?255:Y)); - *(pd4++) = (Tfloat)(K<0?0:(K>255?255:K)); - } - return res; - } - - //! Convert pixel values from CMYK to CMY color spaces. - CImg& CMYKtoCMY() { - return get_CMYKtoCMY().move_to(*this); - } - - //! Convert pixel values from CMYK to CMY color spaces \newinstance. - CImg get_CMYKtoCMY() const { - if (_spectrum!=4) - throw CImgInstanceException(_cimg_instance - "CMYKtoCMY(): Instance is not a CMYK image.", - cimg_instance); - - CImg res(_width,_height,_depth,3); - const T *ps1 = data(0,0,0,0), *ps2 = data(0,0,0,1), *ps3 = data(0,0,0,2), *ps4 = data(0,0,0,3); - Tfloat *pd1 = res.data(0,0,0,0), *pd2 = res.data(0,0,0,1), *pd3 = res.data(0,0,0,2); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - const Tfloat - C = (Tfloat)*(ps1++), - M = (Tfloat)*(ps2++), - Y = (Tfloat)*(ps3++), - K = (Tfloat)*(ps4++), - K1 = 1 - K/255, - nC = C*K1 + K, - nM = M*K1 + K, - nY = Y*K1 + K; - *(pd1++) = (Tfloat)(nC<0?0:(nC>255?255:nC)); - *(pd2++) = (Tfloat)(nM<0?0:(nM>255?255:nM)); - *(pd3++) = (Tfloat)(nY<0?0:(nY>255?255:nY)); - } - return res; - } - - //! Convert pixel values from RGB to XYZ_709 color spaces. - /** - \note Uses the standard D65 white point. - **/ - CImg& RGBtoXYZ() { - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "RGBtoXYZ(): Instance is not a RGB image.", - cimg_instance); - - T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - const Tfloat - R = (Tfloat)*p1/255, - G = (Tfloat)*p2/255, - B = (Tfloat)*p3/255; - *(p1++) = (T)(0.412453f*R + 0.357580f*G + 0.180423f*B); - *(p2++) = (T)(0.212671f*R + 0.715160f*G + 0.072169f*B); - *(p3++) = (T)(0.019334f*R + 0.119193f*G + 0.950227f*B); - } - return *this; - } - - //! Convert pixel values from RGB to XYZ_709 color spaces \newinstance. - CImg get_RGBtoXYZ() const { - return CImg(*this,false).RGBtoXYZ(); - } - - //! Convert pixel values from XYZ_709 to RGB color spaces. - CImg& XYZtoRGB() { - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "XYZtoRGB(): Instance is not a XYZ image.", - cimg_instance); - - T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - const Tfloat - X = (Tfloat)*p1*255, - Y = (Tfloat)*p2*255, - Z = (Tfloat)*p3*255, - R = 3.240479f*X - 1.537150f*Y - 0.498535f*Z, - G = -0.969256f*X + 1.875992f*Y + 0.041556f*Z, - B = 0.055648f*X - 0.204043f*Y + 1.057311f*Z; - *(p1++) = (T)(R<0?0:(R>255?255:R)); - *(p2++) = (T)(G<0?0:(G>255?255:G)); - *(p3++) = (T)(B<0?0:(B>255?255:B)); - } - return *this; - } - - //! Convert pixel values from XYZ_709 to RGB color spaces \newinstance. - CImg get_XYZtoRGB() const { - return CImg(*this,false).XYZtoRGB(); - } - - //! Convert pixel values from XYZ_709 to Lab color spaces. - CImg& XYZtoLab() { -#define _cimg_Labf(x) ((x)>=0.008856f?(std::pow(x,(Tfloat)1/3)):(7.787f*(x) + 16.0f/116)) - - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "XYZtoLab(): Instance is not a XYZ image.", - cimg_instance); - - const Tfloat - Xn = (Tfloat)(0.412453f + 0.357580f + 0.180423f), - Yn = (Tfloat)(0.212671f + 0.715160f + 0.072169f), - Zn = (Tfloat)(0.019334f + 0.119193f + 0.950227f); - T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - const Tfloat - X = (Tfloat)*p1, - Y = (Tfloat)*p2, - Z = (Tfloat)*p3, - XXn = X/Xn, YYn = Y/Yn, ZZn = Z/Zn, - fX = (Tfloat)_cimg_Labf(XXn), - fY = (Tfloat)_cimg_Labf(YYn), - fZ = (Tfloat)_cimg_Labf(ZZn); - *(p1++) = (T)cimg::max(0.0f,116*fY - 16); - *(p2++) = (T)(500*(fX - fY)); - *(p3++) = (T)(200*(fY - fZ)); - } - return *this; - } - - //! Convert pixel values from XYZ_709 to Lab color spaces \newinstance. - CImg get_XYZtoLab() const { - return CImg(*this,false).XYZtoLab(); - } - - //! Convert pixel values from Lab to XYZ_709 color spaces. - CImg& LabtoXYZ() { -#define _cimg_Labfi(x) ((x)>=0.206893f?((x)*(x)*(x)):(((x)-16.0f/116)/7.787f)) - - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "LabtoXYZ(): Instance is not a Lab image.", - cimg_instance); - - const Tfloat - Xn = (Tfloat)(0.412453f + 0.357580f + 0.180423f), - Yn = (Tfloat)(0.212671f + 0.715160f + 0.072169f), - Zn = (Tfloat)(0.019334f + 0.119193f + 0.950227f); - T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - const Tfloat - L = (Tfloat)*p1, - a = (Tfloat)*p2, - b = (Tfloat)*p3, - cY = (L + 16)/116, - Y = (Tfloat)(Yn*_cimg_Labfi(cY)), - cX = a/500 + cY, - X = (Tfloat)(Xn*_cimg_Labfi(cX)), - cZ = cY - b/200, - Z = (Tfloat)(Zn*_cimg_Labfi(cZ)); - *(p1++) = (T)(X); - *(p2++) = (T)(Y); - *(p3++) = (T)(Z); - } - return *this; - } - - //! Convert pixel values from Lab to XYZ_709 color spaces \newinstance. - CImg get_LabtoXYZ() const { - return CImg(*this,false).LabtoXYZ(); - } - - //! Convert pixel values from XYZ_709 to xyY color spaces. - CImg& XYZtoxyY() { - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "XYZtoxyY(): Instance is not a XYZ image.", - cimg_instance); - - T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - const Tfloat - X = (Tfloat)*p1, - Y = (Tfloat)*p2, - Z = (Tfloat)*p3, - sum = X + Y + Z, - nsum = sum>0?sum:1; - *(p1++) = (T)(X/nsum); - *(p2++) = (T)(Y/nsum); - *(p3++) = (T)Y; - } - return *this; - } - - //! Convert pixel values from XYZ_709 to xyY color spaces \newinstance. - CImg get_XYZtoxyY() const { - return CImg(*this,false).XYZtoxyY(); - } - - //! Convert pixel values from xyY pixels to XYZ_709 color spaces. - CImg& xyYtoXYZ() { - if (_spectrum!=3) - throw CImgInstanceException(_cimg_instance - "xyYtoXYZ(): Instance is not a xyY image.", - cimg_instance); - - T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2); - for (ulongT N = (ulongT)_width*_height*_depth; N; --N) { - const Tfloat - px = (Tfloat)*p1, - py = (Tfloat)*p2, - Y = (Tfloat)*p3, - ny = py>0?py:1; - *(p1++) = (T)(px*Y/ny); - *(p2++) = (T)Y; - *(p3++) = (T)((1 - px - py)*Y/ny); - } - return *this; - } - - //! Convert pixel values from xyY pixels to XYZ_709 color spaces \newinstance. - CImg get_xyYtoXYZ() const { - return CImg(*this,false).xyYtoXYZ(); - } - - //! Convert pixel values from RGB to Lab color spaces. - CImg& RGBtoLab() { - return RGBtoXYZ().XYZtoLab(); - } - - //! Convert pixel values from RGB to Lab color spaces \newinstance. - CImg get_RGBtoLab() const { - return CImg(*this,false).RGBtoLab(); - } - - //! Convert pixel values from Lab to RGB color spaces. - CImg& LabtoRGB() { - return LabtoXYZ().XYZtoRGB(); - } - - //! Convert pixel values from Lab to RGB color spaces \newinstance. - CImg get_LabtoRGB() const { - return CImg(*this,false).LabtoRGB(); - } - - //! Convert pixel values from RGB to xyY color spaces. - CImg& RGBtoxyY() { - return RGBtoXYZ().XYZtoxyY(); - } - - //! Convert pixel values from RGB to xyY color spaces \newinstance. - CImg get_RGBtoxyY() const { - return CImg(*this,false).RGBtoxyY(); - } - - //! Convert pixel values from xyY to RGB color spaces. - CImg& xyYtoRGB() { - return xyYtoXYZ().XYZtoRGB(); - } - - //! Convert pixel values from xyY to RGB color spaces \newinstance. - CImg get_xyYtoRGB() const { - return CImg(*this,false).xyYtoRGB(); - } - - //! Convert pixel values from RGB to CMYK color spaces. - CImg& RGBtoCMYK() { - return RGBtoCMY().CMYtoCMYK(); - } - - //! Convert pixel values from RGB to CMYK color spaces \newinstance. - CImg get_RGBtoCMYK() const { - return CImg(*this,false).RGBtoCMYK(); - } - - //! Convert pixel values from CMYK to RGB color spaces. - CImg& CMYKtoRGB() { - return CMYKtoCMY().CMYtoRGB(); - } - - //! Convert pixel values from CMYK to RGB color spaces \newinstance. - CImg get_CMYKtoRGB() const { - return CImg(*this,false).CMYKtoRGB(); - } - - //@} - //------------------------------------------ - // - //! \name Geometric / Spatial Manipulation - //@{ - //------------------------------------------ - - static float _cimg_lanczos(const float x) { - if (x<=-2 || x>=2) return 0; - const float a = (float)cimg::PI*x, b = 0.5f*a; - return (float)(x?std::sin(a)*std::sin(b)/(a*b):1); - } - - //! Resize image to new dimensions. - /** - \param size_x Number of columns (new size along the X-axis). - \param size_y Number of rows (new size along the Y-axis). - \param size_z Number of slices (new size along the Z-axis). - \param size_c Number of vector-channels (new size along the C-axis). - \param interpolation_type Method of interpolation: - - -1 = no interpolation: raw memory resizing. - - 0 = no interpolation: additional space is filled according to \p boundary_conditions. - - 1 = nearest-neighbor interpolation. - - 2 = moving average interpolation. - - 3 = linear interpolation. - - 4 = grid interpolation. - - 5 = cubic interpolation. - - 6 = lanczos interpolation. - \param boundary_conditions Border condition type. - \param centering_x Set centering type (only if \p interpolation_type=0). - \param centering_y Set centering type (only if \p interpolation_type=0). - \param centering_z Set centering type (only if \p interpolation_type=0). - \param centering_c Set centering type (only if \p interpolation_type=0). - \note If pd[x,y,z,v]<0, it corresponds to a percentage of the original size (the default value is -100). - **/ - CImg& resize(const int size_x, const int size_y=-100, - const int size_z=-100, const int size_c=-100, - const int interpolation_type=1, const unsigned int boundary_conditions=0, - const float centering_x = 0, const float centering_y = 0, - const float centering_z = 0, const float centering_c = 0) { - if (!size_x || !size_y || !size_z || !size_c) return assign(); - const unsigned int - _sx = (unsigned int)(size_x<0?-size_x*width()/100:size_x), - _sy = (unsigned int)(size_y<0?-size_y*height()/100:size_y), - _sz = (unsigned int)(size_z<0?-size_z*depth()/100:size_z), - _sc = (unsigned int)(size_c<0?-size_c*spectrum()/100:size_c), - sx = _sx?_sx:1, sy = _sy?_sy:1, sz = _sz?_sz:1, sc = _sc?_sc:1; - if (sx==_width && sy==_height && sz==_depth && sc==_spectrum) return *this; - if (is_empty()) return assign(sx,sy,sz,sc,(T)0); - if (interpolation_type==-1 && sx*sy*sz*sc==size()) { - _width = sx; _height = sy; _depth = sz; _spectrum = sc; - return *this; - } - return get_resize(sx,sy,sz,sc,interpolation_type,boundary_conditions, - centering_x,centering_y,centering_z,centering_c).move_to(*this); - } - - //! Resize image to new dimensions \newinstance. - CImg get_resize(const int size_x, const int size_y = -100, - const int size_z = -100, const int size_c = -100, - const int interpolation_type=1, const unsigned int boundary_conditions=0, - const float centering_x = 0, const float centering_y = 0, - const float centering_z = 0, const float centering_c = 0) const { - if (centering_x<0 || centering_x>1 || centering_y<0 || centering_y>1 || - centering_z<0 || centering_z>1 || centering_c<0 || centering_c>1) - throw CImgArgumentException(_cimg_instance - "resize(): Specified centering arguments (%g,%g,%g,%g) are outside range [0,1].", - cimg_instance, - centering_x,centering_y,centering_z,centering_c); - - if (!size_x || !size_y || !size_z || !size_c) return CImg(); - const unsigned int - _sx = (unsigned int)(size_x<0?-size_x*width()/100:size_x), - _sy = (unsigned int)(size_y<0?-size_y*height()/100:size_y), - _sz = (unsigned int)(size_z<0?-size_z*depth()/100:size_z), - _sc = (unsigned int)(size_c<0?-size_c*spectrum()/100:size_c), - sx = _sx?_sx:1, sy = _sy?_sy:1, sz = _sz?_sz:1, sc = _sc?_sc:1; - if (sx==_width && sy==_height && sz==_depth && sc==_spectrum) return +*this; - if (is_empty()) return CImg(sx,sy,sz,sc,0); - CImg res; - switch (interpolation_type) { - - // Raw resizing. - // - case -1 : - std::memcpy(res.assign(sx,sy,sz,sc,0)._data,_data,sizeof(T)*cimg::min(size(),sx*sy*sz*sc)); - break; - - // No interpolation. - // - case 0 : { - const int - xc = (int)(centering_x*((int)sx - width())), - yc = (int)(centering_y*((int)sy - height())), - zc = (int)(centering_z*((int)sz - depth())), - cc = (int)(centering_c*((int)sc - spectrum())); - - switch (boundary_conditions) { - case 2 : { // Periodic boundary. - res.assign(sx,sy,sz,sc); - const int - x0 = ((int)xc%width()) - width(), - y0 = ((int)yc%height()) - height(), - z0 = ((int)zc%depth()) - depth(), - c0 = ((int)cc%spectrum()) - spectrum(); - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=65536)) - for (int c = c0; c<(int)sc; c+=spectrum()) - for (int z = z0; z<(int)sz; z+=depth()) - for (int y = y0; y<(int)sy; y+=height()) - for (int x = x0; x<(int)sx; x+=width()) - res.draw_image(x,y,z,c,*this); - } break; - case 1 : { // Neumann boundary. - res.assign(sx,sy,sz,sc).draw_image(xc,yc,zc,cc,*this); - CImg sprite; - if (xc>0) { // X-backward - res.get_crop(xc,yc,zc,cc,xc,yc + height() - 1,zc + depth() - 1,cc + spectrum() - 1).move_to(sprite); - for (int x = xc - 1; x>=0; --x) res.draw_image(x,yc,zc,cc,sprite); - } - if (xc + width()<(int)sx) { // X-forward - res.get_crop(xc + width() - 1,yc,zc,cc,xc + width() - 1,yc + height() - 1, - zc + depth() - 1,cc + spectrum() - 1).move_to(sprite); - for (int x = xc + width(); x<(int)sx; ++x) res.draw_image(x,yc,zc,cc,sprite); - } - if (yc>0) { // Y-backward - res.get_crop(0,yc,zc,cc,sx - 1,yc,zc + depth() - 1,cc + spectrum() - 1).move_to(sprite); - for (int y = yc - 1; y>=0; --y) res.draw_image(0,y,zc,cc,sprite); - } - if (yc + height()<(int)sy) { // Y-forward - res.get_crop(0,yc + height() - 1,zc,cc,sx - 1,yc + height() - 1, - zc + depth() - 1,cc + spectrum() - 1).move_to(sprite); - for (int y = yc + height(); y<(int)sy; ++y) res.draw_image(0,y,zc,cc,sprite); - } - if (zc>0) { // Z-backward - res.get_crop(0,0,zc,cc,sx - 1,sy - 1,zc,cc + spectrum() - 1).move_to(sprite); - for (int z = zc - 1; z>=0; --z) res.draw_image(0,0,z,cc,sprite); - } - if (zc + depth()<(int)sz) { // Z-forward - res.get_crop(0,0,zc +depth() - 1,cc,sx - 1,sy - 1,zc + depth() - 1,cc + spectrum() - 1).move_to(sprite); - for (int z = zc + depth(); z<(int)sz; ++z) res.draw_image(0,0,z,cc,sprite); - } - if (cc>0) { // C-backward - res.get_crop(0,0,0,cc,sx - 1,sy - 1,sz - 1,cc).move_to(sprite); - for (int c = cc - 1; c>=0; --c) res.draw_image(0,0,0,c,sprite); - } - if (cc + spectrum()<(int)sc) { // C-forward - res.get_crop(0,0,0,cc + spectrum() - 1,sx - 1,sy - 1,sz - 1,cc + spectrum() - 1).move_to(sprite); - for (int c = cc + spectrum(); c<(int)sc; ++c) res.draw_image(0,0,0,c,sprite); - } - } break; - default : // Dirichlet boundary. - res.assign(sx,sy,sz,sc,0).draw_image(xc,yc,zc,cc,*this); - } - break; - } break; - - // Nearest neighbor interpolation. - // - case 1 : { - res.assign(sx,sy,sz,sc); - CImg off_x(sx), off_y(sy + 1), off_z(sz + 1), off_c(sc + 1); - const ulongT - wh = (ulongT)_width*_height, - whd = (ulongT)_width*_height*_depth, - sxy = (ulongT)sx*sy, - sxyz = (ulongT)sx*sy*sz; - if (sx==_width) off_x.fill(1); - else { - ulongT *poff_x = off_x._data, curr = 0; - cimg_forX(res,x) { - const ulongT old = curr; - curr = (ulongT)((x + 1.0)*_width/sx); - *(poff_x++) = curr - old; - } - } - if (sy==_height) off_y.fill(_width); - else { - ulongT *poff_y = off_y._data, curr = 0; - cimg_forY(res,y) { - const ulongT old = curr; - curr = (ulongT)((y + 1.0)*_height/sy); - *(poff_y++) = _width*(curr - old); - } - *poff_y = 0; - } - if (sz==_depth) off_z.fill(wh); - else { - ulongT *poff_z = off_z._data, curr = 0; - cimg_forZ(res,z) { - const ulongT old = curr; - curr = (ulongT)((z + 1.0)*_depth/sz); - *(poff_z++) = wh*(curr - old); - } - *poff_z = 0; - } - if (sc==_spectrum) off_c.fill(whd); - else { - ulongT *poff_c = off_c._data, curr = 0; - cimg_forC(res,c) { - const ulongT old = curr; - curr = (ulongT)((c + 1.0)*_spectrum/sc); - *(poff_c++) = whd*(curr - old); - } - *poff_c = 0; - } - - T *ptrd = res._data; - const T* ptrc = _data; - const ulongT *poff_c = off_c._data; - for (unsigned int c = 0; c tmp(sx,_height,_depth,_spectrum,0); - for (unsigned int a = _width*sx, b = _width, c = sx, s = 0, t = 0; a; ) { - const unsigned int d = cimg::min(b,c); - a-=d; b-=d; c-=d; - cimg_forYZC(tmp,y,z,v) tmp(t,y,z,v)+=(Tfloat)(*this)(s,y,z,v)*d; - if (!b) { - cimg_forYZC(tmp,y,z,v) tmp(t,y,z,v)/=_width; - ++t; - b = _width; - } - if (!c) { ++s; c = sx; } - } - tmp.move_to(res); - instance_first = false; - } - if (sy!=_height) { - CImg tmp(sx,sy,_depth,_spectrum,0); - for (unsigned int a = _height*sy, b = _height, c = sy, s = 0, t = 0; a; ) { - const unsigned int d = cimg::min(b,c); - a-=d; b-=d; c-=d; - if (instance_first) - cimg_forXZC(tmp,x,z,v) tmp(x,t,z,v)+=(Tfloat)(*this)(x,s,z,v)*d; - else - cimg_forXZC(tmp,x,z,v) tmp(x,t,z,v)+=(Tfloat)res(x,s,z,v)*d; - if (!b) { - cimg_forXZC(tmp,x,z,v) tmp(x,t,z,v)/=_height; - ++t; - b = _height; - } - if (!c) { ++s; c = sy; } - } - tmp.move_to(res); - instance_first = false; - } - if (sz!=_depth) { - CImg tmp(sx,sy,sz,_spectrum,0); - for (unsigned int a = _depth*sz, b = _depth, c = sz, s = 0, t = 0; a; ) { - const unsigned int d = cimg::min(b,c); - a-=d; b-=d; c-=d; - if (instance_first) - cimg_forXYC(tmp,x,y,v) tmp(x,y,t,v)+=(Tfloat)(*this)(x,y,s,v)*d; - else - cimg_forXYC(tmp,x,y,v) tmp(x,y,t,v)+=(Tfloat)res(x,y,s,v)*d; - if (!b) { - cimg_forXYC(tmp,x,y,v) tmp(x,y,t,v)/=_depth; - ++t; - b = _depth; - } - if (!c) { ++s; c = sz; } - } - tmp.move_to(res); - instance_first = false; - } - if (sc!=_spectrum) { - CImg tmp(sx,sy,sz,sc,0); - for (unsigned int a = _spectrum*sc, b = _spectrum, c = sc, s = 0, t = 0; a; ) { - const unsigned int d = cimg::min(b,c); - a-=d; b-=d; c-=d; - if (instance_first) - cimg_forXYZ(tmp,x,y,z) tmp(x,y,z,t)+=(Tfloat)(*this)(x,y,z,s)*d; - else - cimg_forXYZ(tmp,x,y,z) tmp(x,y,z,t)+=(Tfloat)res(x,y,z,s)*d; - if (!b) { - cimg_forXYZ(tmp,x,y,z) tmp(x,y,z,t)/=_spectrum; - ++t; - b = _spectrum; - } - if (!c) { ++s; c = sc; } - } - tmp.move_to(res); - instance_first = false; - } - } break; - - // Linear interpolation. - // - case 3 : { - CImg off(cimg::max(sx,sy,sz,sc)); - CImg foff(off._width); - CImg resx, resy, resz, resc; - - if (sx!=_width) { - if (_width==1) get_resize(sx,_height,_depth,_spectrum,1).move_to(resx); - else { - if (_width>sx) get_resize(sx,_height,_depth,_spectrum,2).move_to(resx); - else { - const float fx = (!boundary_conditions && sx>_width)?(sx>1?(_width - 1.0f)/(sx - 1):0):(float)_width/sx; - resx.assign(sx,_height,_depth,_spectrum); - float curr = 0, old = 0; - unsigned int *poff = off._data; - float *pfoff = foff._data; - cimg_forX(resx,x) { - *(pfoff++) = curr - (unsigned int)curr; - old = curr; - curr+=fx; - *(poff++) = (unsigned int)curr - (unsigned int)old; - } - cimg_pragma_openmp(parallel for collapse(3) if (resx.size()>=65536)) - cimg_forYZC(resx,y,z,c) { - const T *ptrs = data(0,y,z,c), *const ptrsmax = ptrs + _width - 1; - T *ptrd = resx.data(0,y,z,c); - const unsigned int *poff = off._data; - const float *pfoff = foff._data; - cimg_forX(resx,x) { - const float alpha = *(pfoff++); - const T val1 = *ptrs, val2 = ptrssy) resx.get_resize(sx,sy,_depth,_spectrum,2).move_to(resy); - else { - const float fy = (!boundary_conditions && sy>_height)?(sy>1?(_height - 1.0f)/(sy - 1):0): - (float)_height/sy; - resy.assign(sx,sy,_depth,_spectrum); - float curr = 0, old = 0; - unsigned int *poff = off._data; - float *pfoff = foff._data; - cimg_forY(resy,y) { - *(pfoff++) = curr - (unsigned int)curr; - old = curr; - curr+=fy; - *(poff++) = sx*((unsigned int)curr-(unsigned int)old); - } - cimg_pragma_openmp(parallel for collapse(3) if (resy.size()>=65536)) - cimg_forXZC(resy,x,z,c) { - const T *ptrs = resx.data(x,0,z,c), *const ptrsmax = ptrs + (_height - 1)*sx; - T *ptrd = resy.data(x,0,z,c); - const unsigned int *poff = off._data; - const float *pfoff = foff._data; - cimg_forY(resy,y) { - const float alpha = *(pfoff++); - const T val1 = *ptrs, val2 = ptrssz) resy.get_resize(sx,sy,sz,_spectrum,2).move_to(resz); - else { - const float fz = (!boundary_conditions && sz>_depth)?(sz>1?(_depth - 1.0f)/(sz - 1):0):(float)_depth/sz; - const unsigned int sxy = sx*sy; - resz.assign(sx,sy,sz,_spectrum); - float curr = 0, old = 0; - unsigned int *poff = off._data; - float *pfoff = foff._data; - cimg_forZ(resz,z) { - *(pfoff++) = curr - (unsigned int)curr; - old = curr; - curr+=fz; - *(poff++) = sxy*((unsigned int)curr - (unsigned int)old); - } - cimg_pragma_openmp(parallel for collapse(3) if (resz.size()>=65536)) - cimg_forXYC(resz,x,y,c) { - const T *ptrs = resy.data(x,y,0,c), *const ptrsmax = ptrs + (_depth - 1)*sxy; - T *ptrd = resz.data(x,y,0,c); - const unsigned int *poff = off._data; - const float *pfoff = foff._data; - cimg_forZ(resz,z) { - const float alpha = *(pfoff++); - const T val1 = *ptrs, val2 = ptrssc) resz.get_resize(sx,sy,sz,sc,2).move_to(resc); - else { - const float fc = (!boundary_conditions && sc>_spectrum)?(sc>1?(_spectrum - 1.0f)/(sc - 1):0): - (float)_spectrum/sc; - const unsigned int sxyz = sx*sy*sz; - resc.assign(sx,sy,sz,sc); - float curr = 0, old = 0; - unsigned int *poff = off._data; - float *pfoff = foff._data; - cimg_forC(resc,c) { - *(pfoff++) = curr - (unsigned int)curr; - old = curr; - curr+=fc; - *(poff++) = sxyz*((unsigned int)curr - (unsigned int)old); - } - cimg_pragma_openmp(parallel for collapse(3) if (resc.size()>=65536)) - cimg_forXYZ(resc,x,y,z) { - const T *ptrs = resz.data(x,y,z,0), *const ptrsmax = ptrs + (_spectrum - 1)*sxyz; - T *ptrd = resc.data(x,y,z,0); - const unsigned int *poff = off._data; - const float *pfoff = foff._data; - cimg_forC(resc,c) { - const float alpha = *(pfoff++); - const T val1 = *ptrs, val2 = ptrs resx, resy, resz, resc; - if (sx!=_width) { - if (sx<_width) get_resize(sx,_height,_depth,_spectrum,1).move_to(resx); - else { - resx.assign(sx,_height,_depth,_spectrum,0); - const int dx = (int)(2*sx), dy = 2*width(); - int err = (int)(dy + centering_x*(sx*dy/width() - dy)), xs = 0; - cimg_forX(resx,x) if ((err-=dy)<=0) { - cimg_forYZC(resx,y,z,c) resx(x,y,z,c) = (*this)(xs,y,z,c); - ++xs; - err+=dx; - } - } - } else resx.assign(*this,true); - - if (sy!=_height) { - if (sy<_height) resx.get_resize(sx,sy,_depth,_spectrum,1).move_to(resy); - else { - resy.assign(sx,sy,_depth,_spectrum,0); - const int dx = (int)(2*sy), dy = 2*height(); - int err = (int)(dy + centering_y*(sy*dy/height() - dy)), ys = 0; - cimg_forY(resy,y) if ((err-=dy)<=0) { - cimg_forXZC(resy,x,z,c) resy(x,y,z,c) = resx(x,ys,z,c); - ++ys; - err+=dx; - } - } - resx.assign(); - } else resy.assign(resx,true); - - if (sz!=_depth) { - if (sz<_depth) resy.get_resize(sx,sy,sz,_spectrum,1).move_to(resz); - else { - resz.assign(sx,sy,sz,_spectrum,0); - const int dx = (int)(2*sz), dy = 2*depth(); - int err = (int)(dy + centering_z*(sz*dy/depth() - dy)), zs = 0; - cimg_forZ(resz,z) if ((err-=dy)<=0) { - cimg_forXYC(resz,x,y,c) resz(x,y,z,c) = resy(x,y,zs,c); - ++zs; - err+=dx; - } - } - resy.assign(); - } else resz.assign(resy,true); - - if (sc!=_spectrum) { - if (sc<_spectrum) resz.get_resize(sx,sy,sz,sc,1).move_to(resc); - else { - resc.assign(sx,sy,sz,sc,0); - const int dx = (int)(2*sc), dy = 2*spectrum(); - int err = (int)(dy + centering_c*(sc*dy/spectrum() - dy)), cs = 0; - cimg_forC(resc,c) if ((err-=dy)<=0) { - cimg_forXYZ(resc,x,y,z) resc(x,y,z,c) = resz(x,y,z,cs); - ++cs; - err+=dx; - } - } - resz.assign(); - } else resc.assign(resz,true); - - return resc._is_shared?(resz._is_shared?(resy._is_shared?(resx._is_shared?(+(*this)):resx):resy):resz):resc; - } break; - - // Cubic interpolation. - // - case 5 : { - const Tfloat vmin = (Tfloat)cimg::type::min(), vmax = (Tfloat)cimg::type::max(); - CImg off(cimg::max(sx,sy,sz,sc)); - CImg foff(off._width); - CImg resx, resy, resz, resc; - - if (sx!=_width) { - if (_width==1) get_resize(sx,_height,_depth,_spectrum,1).move_to(resx); - else { - if (_width>sx) get_resize(sx,_height,_depth,_spectrum,2).move_to(resx); - else { - const float fx = (!boundary_conditions && sx>_width)?(sx>1?(_width - 1.0f)/(sx - 1):0):(float)_width/sx; - resx.assign(sx,_height,_depth,_spectrum); - float curr = 0, old = 0; - unsigned int *poff = off._data; - float *pfoff = foff._data; - cimg_forX(resx,x) { - *(pfoff++) = curr - (unsigned int)curr; - old = curr; - curr+=fx; - *(poff++) = (unsigned int)curr - (unsigned int)old; - } - cimg_pragma_openmp(parallel for collapse(3) if (resx.size()>=65536)) - cimg_forYZC(resx,y,z,c) { - const T *const ptrs0 = data(0,y,z,c), *ptrs = ptrs0, *const ptrsmax = ptrs + (_width - 2); - T *ptrd = resx.data(0,y,z,c); - const unsigned int *poff = off._data; - const float *pfoff = foff._data; - cimg_forX(resx,x) { - const float t = *(pfoff++); - const Tfloat - val1 = (Tfloat)*ptrs, - val0 = ptrs>ptrs0?(Tfloat)*(ptrs - 1):val1, - val2 = ptrs<=ptrsmax?(Tfloat)*(ptrs + 1):val1, - val3 = ptrsvmax?vmax:val); - ptrs+=*(poff++); - } - } - } - } - } else resx.assign(*this,true); - - if (sy!=_height) { - if (_height==1) resx.get_resize(sx,sy,_depth,_spectrum,1).move_to(resy); - else { - if (_height>sy) resx.get_resize(sx,sy,_depth,_spectrum,2).move_to(resy); - else { - const float fy = (!boundary_conditions && sy>_height)?(sy>1?(_height - 1.0f)/(sy - 1):0): - (float)_height/sy; - resy.assign(sx,sy,_depth,_spectrum); - float curr = 0, old = 0; - unsigned int *poff = off._data; - float *pfoff = foff._data; - cimg_forY(resy,y) { - *(pfoff++) = curr - (unsigned int)curr; - old = curr; - curr+=fy; - *(poff++) = sx*((unsigned int)curr - (unsigned int)old); - } - cimg_pragma_openmp(parallel for collapse(3) if (resy.size()>=65536)) - cimg_forXZC(resy,x,z,c) { - const T *const ptrs0 = resx.data(x,0,z,c), *ptrs = ptrs0, *const ptrsmax = ptrs + (_height - 2)*sx; - T *ptrd = resy.data(x,0,z,c); - const unsigned int *poff = off._data; - const float *pfoff = foff._data; - cimg_forY(resy,y) { - const float t = *(pfoff++); - const Tfloat - val1 = (Tfloat)*ptrs, - val0 = ptrs>ptrs0?(Tfloat)*(ptrs - sx):val1, - val2 = ptrs<=ptrsmax?(Tfloat)*(ptrs + sx):val1, - val3 = ptrsvmax?vmax:val); - ptrd+=sx; - ptrs+=*(poff++); - } - } - } - } - resx.assign(); - } else resy.assign(resx,true); - - if (sz!=_depth) { - if (_depth==1) resy.get_resize(sx,sy,sz,_spectrum,1).move_to(resz); - else { - if (_depth>sz) resy.get_resize(sx,sy,sz,_spectrum,2).move_to(resz); - else { - const float fz = (!boundary_conditions && sz>_depth)?(sz>1?(_depth - 1.0f)/(sz - 1):0):(float)_depth/sz; - const unsigned int sxy = sx*sy; - resz.assign(sx,sy,sz,_spectrum); - float curr = 0, old = 0; - unsigned int *poff = off._data; - float *pfoff = foff._data; - cimg_forZ(resz,z) { - *(pfoff++) = curr - (unsigned int)curr; - old = curr; - curr+=fz; - *(poff++) = sxy*((unsigned int)curr - (unsigned int)old); - } - cimg_pragma_openmp(parallel for collapse(3) if (resz.size()>=65536)) - cimg_forXYC(resz,x,y,c) { - const T *const ptrs0 = resy.data(x,y,0,c), *ptrs = ptrs0, *const ptrsmax = ptrs + (_depth - 2)*sxy; - T *ptrd = resz.data(x,y,0,c); - const unsigned int *poff = off._data; - const float *pfoff = foff._data; - cimg_forZ(resz,z) { - const float t = *(pfoff++); - const Tfloat - val1 = (Tfloat)*ptrs, - val0 = ptrs>ptrs0?(Tfloat)*(ptrs - sxy):val1, - val2 = ptrs<=ptrsmax?(Tfloat)*(ptrs + sxy):val1, - val3 = ptrsvmax?vmax:val); - ptrd+=sxy; - ptrs+=*(poff++); - } - } - } - } - resy.assign(); - } else resz.assign(resy,true); - - if (sc!=_spectrum) { - if (_spectrum==1) resz.get_resize(sx,sy,sz,sc,1).move_to(resc); - else { - if (_spectrum>sc) resz.get_resize(sx,sy,sz,sc,2).move_to(resc); - else { - const float fc = (!boundary_conditions && sc>_spectrum)?(sc>1?(_spectrum - 1.0f)/(sc - 1):0): - (float)_spectrum/sc; - const unsigned int sxyz = sx*sy*sz; - resc.assign(sx,sy,sz,sc); - float curr = 0, old = 0; - unsigned int *poff = off._data; - float *pfoff = foff._data; - cimg_forC(resc,c) { - *(pfoff++) = curr - (unsigned int)curr; - old = curr; - curr+=fc; - *(poff++) = sxyz*((unsigned int)curr - (unsigned int)old); - } - cimg_pragma_openmp(parallel for collapse(3) if (resc.size()>=65536)) - cimg_forXYZ(resc,x,y,z) { - const T *const ptrs0 = resz.data(x,y,z,0), *ptrs = ptrs0, *const ptrsmax = ptrs + (_spectrum - 2)*sxyz; - T *ptrd = resc.data(x,y,z,0); - const unsigned int *poff = off._data; - const float *pfoff = foff._data; - cimg_forC(resc,c) { - const float t = *(pfoff++); - const Tfloat - val1 = (Tfloat)*ptrs, - val0 = ptrs>ptrs0?(Tfloat)*(ptrs - sxyz):val1, - val2 = ptrs<=ptrsmax?(Tfloat)*(ptrs + sxyz):val1, - val3 = ptrsvmax?vmax:val); - ptrd+=sxyz; - ptrs+=*(poff++); - } - } - } - } - resz.assign(); - } else resc.assign(resz,true); - - return resc._is_shared?(resz._is_shared?(resy._is_shared?(resx._is_shared?(+(*this)):resx):resy):resz):resc; - } break; - - // Lanczos interpolation. - // - case 6 : { - const Tfloat vmin = (Tfloat)cimg::type::min(), vmax = (Tfloat)cimg::type::max(); - CImg off(cimg::max(sx,sy,sz,sc)); - CImg foff(off._width); - CImg resx, resy, resz, resc; - - if (sx!=_width) { - if (_width==1) get_resize(sx,_height,_depth,_spectrum,1).move_to(resx); - else { - if (_width>sx) get_resize(sx,_height,_depth,_spectrum,2).move_to(resx); - else { - const float fx = (!boundary_conditions && sx>_width)?(sx>1?(_width - 1.0f)/(sx - 1):0):(float)_width/sx; - resx.assign(sx,_height,_depth,_spectrum); - float curr = 0, old = 0; - unsigned int *poff = off._data; - float *pfoff = foff._data; - cimg_forX(resx,x) { - *(pfoff++) = curr - (unsigned int)curr; - old = curr; - curr+=fx; - *(poff++) = (unsigned int)curr - (unsigned int)old; - } - cimg_pragma_openmp(parallel for collapse(3) if (resx.size()>=65536)) - cimg_forYZC(resx,y,z,c) { - const T *const ptrs0 = data(0,y,z,c), *ptrs = ptrs0, *const ptrsmin = ptrs0 + 1, - *const ptrsmax = ptrs0 + (_width - 2); - T *ptrd = resx.data(0,y,z,c); - const unsigned int *poff = off._data; - const float *pfoff = foff._data; - cimg_forX(resx,x) { - const float - t = *(pfoff++), - w0 = _cimg_lanczos(t + 2), - w1 = _cimg_lanczos(t + 1), - w2 = _cimg_lanczos(t), - w3 = _cimg_lanczos(t - 1), - w4 = _cimg_lanczos(t - 2); - const Tfloat - val2 = (Tfloat)*ptrs, - val1 = ptrs>=ptrsmin?(Tfloat)*(ptrs - 1):val2, - val0 = ptrs>ptrsmin?(Tfloat)*(ptrs - 2):val1, - val3 = ptrs<=ptrsmax?(Tfloat)*(ptrs + 1):val2, - val4 = ptrsvmax?vmax:val); - ptrs+=*(poff++); - } - } - } - } - } else resx.assign(*this,true); - - if (sy!=_height) { - if (_height==1) resx.get_resize(sx,sy,_depth,_spectrum,1).move_to(resy); - else { - if (_height>sy) resx.get_resize(sx,sy,_depth,_spectrum,2).move_to(resy); - else { - const float fy = (!boundary_conditions && sy>_height)?(sy>1?(_height - 1.0f)/(sy - 1):0): - (float)_height/sy; - resy.assign(sx,sy,_depth,_spectrum); - float curr = 0, old = 0; - unsigned int *poff = off._data; - float *pfoff = foff._data; - cimg_forY(resy,y) { - *(pfoff++) = curr - (unsigned int)curr; - old = curr; - curr+=fy; - *(poff++) = sx*((unsigned int)curr - (unsigned int)old); - } - cimg_pragma_openmp(parallel for collapse(3) if (resy.size()>=65536)) - cimg_forXZC(resy,x,z,c) { - const T *const ptrs0 = resx.data(x,0,z,c), *ptrs = ptrs0, *const ptrsmin = ptrs0 + sx, - *const ptrsmax = ptrs0 + (_height - 2)*sx; - T *ptrd = resy.data(x,0,z,c); - const unsigned int *poff = off._data; - const float *pfoff = foff._data; - cimg_forY(resy,y) { - const float - t = *(pfoff++), - w0 = _cimg_lanczos(t + 2), - w1 = _cimg_lanczos(t + 1), - w2 = _cimg_lanczos(t), - w3 = _cimg_lanczos(t - 1), - w4 = _cimg_lanczos(t - 2); - const Tfloat - val2 = (Tfloat)*ptrs, - val1 = ptrs>=ptrsmin?(Tfloat)*(ptrs - sx):val2, - val0 = ptrs>ptrsmin?(Tfloat)*(ptrs - 2*sx):val1, - val3 = ptrs<=ptrsmax?(Tfloat)*(ptrs + sx):val2, - val4 = ptrsvmax?vmax:val); - ptrd+=sx; - ptrs+=*(poff++); - } - } - } - } - resx.assign(); - } else resy.assign(resx,true); - - if (sz!=_depth) { - if (_depth==1) resy.get_resize(sx,sy,sz,_spectrum,1).move_to(resz); - else { - if (_depth>sz) resy.get_resize(sx,sy,sz,_spectrum,2).move_to(resz); - else { - const float fz = (!boundary_conditions && sz>_depth)?(sz>1?(_depth - 1.0f)/(sz - 1):0):(float)_depth/sz; - const unsigned int sxy = sx*sy; - resz.assign(sx,sy,sz,_spectrum); - float curr = 0, old = 0; - unsigned int *poff = off._data; - float *pfoff = foff._data; - cimg_forZ(resz,z) { - *(pfoff++) = curr - (unsigned int)curr; - old = curr; - curr+=fz; - *(poff++) = sxy*((unsigned int)curr - (unsigned int)old); - } - cimg_pragma_openmp(parallel for collapse(3) if (resz.size()>=65536)) - cimg_forXYC(resz,x,y,c) { - const T *const ptrs0 = resy.data(x,y,0,c), *ptrs = ptrs0, *const ptrsmin = ptrs0 + sxy, - *const ptrsmax = ptrs0 + (_depth - 2)*sxy; - T *ptrd = resz.data(x,y,0,c); - const unsigned int *poff = off._data; - const float *pfoff = foff._data; - cimg_forZ(resz,z) { - const float - t = *(pfoff++), - w0 = _cimg_lanczos(t + 2), - w1 = _cimg_lanczos(t + 1), - w2 = _cimg_lanczos(t), - w3 = _cimg_lanczos(t - 1), - w4 = _cimg_lanczos(t - 2); - const Tfloat - val2 = (Tfloat)*ptrs, - val1 = ptrs>=ptrsmin?(Tfloat)*(ptrs - sxy):val2, - val0 = ptrs>ptrsmin?(Tfloat)*(ptrs - 2*sxy):val1, - val3 = ptrs<=ptrsmax?(Tfloat)*(ptrs + sxy):val2, - val4 = ptrsvmax?vmax:val); - ptrd+=sxy; - ptrs+=*(poff++); - } - } - } - } - resy.assign(); - } else resz.assign(resy,true); - - if (sc!=_spectrum) { - if (_spectrum==1) resz.get_resize(sx,sy,sz,sc,1).move_to(resc); - else { - if (_spectrum>sc) resz.get_resize(sx,sy,sz,sc,2).move_to(resc); - else { - const float fc = (!boundary_conditions && sc>_spectrum)?(sc>1?(_spectrum - 1.0f)/(sc - 1):0): - (float)_spectrum/sc; - const unsigned int sxyz = sx*sy*sz; - resc.assign(sx,sy,sz,sc); - float curr = 0, old = 0; - unsigned int *poff = off._data; - float *pfoff = foff._data; - cimg_forC(resc,c) { - *(pfoff++) = curr - (unsigned int)curr; - old = curr; - curr+=fc; - *(poff++) = sxyz*((unsigned int)curr - (unsigned int)old); - } - cimg_pragma_openmp(parallel for collapse(3) if (resc.size()>=65536)) - cimg_forXYZ(resc,x,y,z) { - const T *const ptrs0 = resz.data(x,y,z,0), *ptrs = ptrs0, *const ptrsmin = ptrs0 + sxyz, - *const ptrsmax = ptrs + (_spectrum - 2)*sxyz; - T *ptrd = resc.data(x,y,z,0); - const unsigned int *poff = off._data; - const float *pfoff = foff._data; - cimg_forC(resc,c) { - const float - t = *(pfoff++), - w0 = _cimg_lanczos(t + 2), - w1 = _cimg_lanczos(t + 1), - w2 = _cimg_lanczos(t), - w3 = _cimg_lanczos(t - 1), - w4 = _cimg_lanczos(t - 2); - const Tfloat - val2 = (Tfloat)*ptrs, - val1 = ptrs>=ptrsmin?(Tfloat)*(ptrs - sxyz):val2, - val0 = ptrs>ptrsmin?(Tfloat)*(ptrs - 2*sxyz):val1, - val3 = ptrs<=ptrsmax?(Tfloat)*(ptrs + sxyz):val2, - val4 = ptrsvmax?vmax:val); - ptrd+=sxyz; - ptrs+=*(poff++); - } - } - } - } - resz.assign(); - } else resc.assign(resz,true); - - return resc._is_shared?(resz._is_shared?(resy._is_shared?(resx._is_shared?(+(*this)):resx):resy):resz):resc; - } break; - - // Unknow interpolation. - // - default : - throw CImgArgumentException(_cimg_instance - "resize(): Invalid specified interpolation %d " - "(should be { -1=raw | 0=none | 1=nearest | 2=average | 3=linear | 4=grid | " - "5=cubic | 6=lanczos }).", - cimg_instance, - interpolation_type); - } - return res; - } - - //! Resize image to dimensions of another image. - /** - \param src Reference image used for dimensions. - \param interpolation_type Interpolation method. - \param boundary_conditions Boundary conditions. - \param centering_x Set centering type (only if \p interpolation_type=0). - \param centering_y Set centering type (only if \p interpolation_type=0). - \param centering_z Set centering type (only if \p interpolation_type=0). - \param centering_c Set centering type (only if \p interpolation_type=0). - **/ - template - CImg& resize(const CImg& src, - const int interpolation_type=1, const unsigned int boundary_conditions=0, - const float centering_x = 0, const float centering_y = 0, - const float centering_z = 0, const float centering_c = 0) { - return resize(src._width,src._height,src._depth,src._spectrum,interpolation_type,boundary_conditions, - centering_x,centering_y,centering_z,centering_c); - } - - //! Resize image to dimensions of another image \newinstance. - template - CImg get_resize(const CImg& src, - const int interpolation_type=1, const unsigned int boundary_conditions=0, - const float centering_x = 0, const float centering_y = 0, - const float centering_z = 0, const float centering_c = 0) const { - return get_resize(src._width,src._height,src._depth,src._spectrum,interpolation_type,boundary_conditions, - centering_x,centering_y,centering_z,centering_c); - } - - //! Resize image to dimensions of a display window. - /** - \param disp Reference display window used for dimensions. - \param interpolation_type Interpolation method. - \param boundary_conditions Boundary conditions. - \param centering_x Set centering type (only if \p interpolation_type=0). - \param centering_y Set centering type (only if \p interpolation_type=0). - \param centering_z Set centering type (only if \p interpolation_type=0). - \param centering_c Set centering type (only if \p interpolation_type=0). - **/ - CImg& resize(const CImgDisplay& disp, - const int interpolation_type=1, const unsigned int boundary_conditions=0, - const float centering_x = 0, const float centering_y = 0, - const float centering_z = 0, const float centering_c = 0) { - return resize(disp.width(),disp.height(),_depth,_spectrum,interpolation_type,boundary_conditions, - centering_x,centering_y,centering_z,centering_c); - } - - //! Resize image to dimensions of a display window \newinstance. - CImg get_resize(const CImgDisplay& disp, - const int interpolation_type=1, const unsigned int boundary_conditions=0, - const float centering_x = 0, const float centering_y = 0, - const float centering_z = 0, const float centering_c = 0) const { - return get_resize(disp.width(),disp.height(),_depth,_spectrum,interpolation_type,boundary_conditions, - centering_x,centering_y,centering_z,centering_c); - } - - //! Resize image to half-size along XY axes, using an optimized filter. - CImg& resize_halfXY() { - return get_resize_halfXY().move_to(*this); - } - - //! Resize image to half-size along XY axes, using an optimized filter \newinstance. - CImg get_resize_halfXY() const { - if (is_empty()) return *this; - static const Tfloat mask[9] = { 0.07842776544f, 0.1231940459f, 0.07842776544f, - 0.1231940459f, 0.1935127547f, 0.1231940459f, - 0.07842776544f, 0.1231940459f, 0.07842776544f }; - CImg I(9), res(_width/2,_height/2,_depth,_spectrum); - T *ptrd = res._data; - cimg_forZC(*this,z,c) cimg_for3x3(*this,x,y,z,c,I,T) - if (x%2 && y%2) *(ptrd++) = (T) - (I[0]*mask[0] + I[1]*mask[1] + I[2]*mask[2] + - I[3]*mask[3] + I[4]*mask[4] + I[5]*mask[5] + - I[6]*mask[6] + I[7]*mask[7] + I[8]*mask[8]); - return res; - } - - //! Resize image to double-size, using the Scale2X algorithm. - /** - \note Use anisotropic upscaling algorithm - described here. - **/ - CImg& resize_doubleXY() { - return get_resize_doubleXY().move_to(*this); - } - - //! Resize image to double-size, using the Scale2X algorithm \newinstance. - CImg get_resize_doubleXY() const { -#define _cimg_gs2x_for3(bound,i) \ - for (int i = 0, _p1##i = 0, \ - _n1##i = 1>=(bound)?(int)(bound) - 1:1; \ - _n1##i<(int)(bound) || i==--_n1##i; \ - _p1##i = i++, ++_n1##i, ptrd1+=(res)._width, ptrd2+=(res)._width) - -#define _cimg_gs2x_for3x3(img,x,y,z,c,I,T) \ - _cimg_gs2x_for3((img)._height,y) for (int x = 0, \ - _p1##x = 0, \ - _n1##x = (int)( \ - (I[1] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[3] = I[4] = (T)(img)(0,y,z,c)), \ - (I[7] = (T)(img)(0,_n1##y,z,c)), \ - 1>=(img)._width?(img).width() - 1:1); \ - (_n1##x<(img).width() && ( \ - (I[2] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[5] = (T)(img)(_n1##x,y,z,c)), \ - (I[8] = (T)(img)(_n1##x,_n1##y,z,c)),1)) || \ - x==--_n1##x; \ - I[1] = I[2], \ - I[3] = I[4], I[4] = I[5], \ - I[7] = I[8], \ - _p1##x = x++, ++_n1##x) - - if (is_empty()) return *this; - CImg res(_width<<1,_height<<1,_depth,_spectrum); - CImg_3x3(I,T); - cimg_forZC(*this,z,c) { - T - *ptrd1 = res.data(0,0,z,c), - *ptrd2 = ptrd1 + res._width; - _cimg_gs2x_for3x3(*this,x,y,z,c,I,T) { - if (Icp!=Icn && Ipc!=Inc) { - *(ptrd1++) = Ipc==Icp?Ipc:Icc; - *(ptrd1++) = Icp==Inc?Inc:Icc; - *(ptrd2++) = Ipc==Icn?Ipc:Icc; - *(ptrd2++) = Icn==Inc?Inc:Icc; - } else { *(ptrd1++) = Icc; *(ptrd1++) = Icc; *(ptrd2++) = Icc; *(ptrd2++) = Icc; } - } - } - return res; - } - - //! Resize image to triple-size, using the Scale3X algorithm. - /** - \note Use anisotropic upscaling algorithm - described here. - **/ - CImg& resize_tripleXY() { - return get_resize_tripleXY().move_to(*this); - } - - //! Resize image to triple-size, using the Scale3X algorithm \newinstance. - CImg get_resize_tripleXY() const { -#define _cimg_gs3x_for3(bound,i) \ - for (int i = 0, _p1##i = 0, \ - _n1##i = 1>=(bound)?(int)(bound) - 1:1; \ - _n1##i<(int)(bound) || i==--_n1##i; \ - _p1##i = i++, ++_n1##i, ptrd1+=2*(res)._width, ptrd2+=2*(res)._width, ptrd3+=2*(res)._width) - -#define _cimg_gs3x_for3x3(img,x,y,z,c,I,T) \ - _cimg_gs3x_for3((img)._height,y) for (int x = 0, \ - _p1##x = 0, \ - _n1##x = (int)( \ - (I[0] = I[1] = (T)(img)(_p1##x,_p1##y,z,c)), \ - (I[3] = I[4] = (T)(img)(0,y,z,c)), \ - (I[6] = I[7] = (T)(img)(0,_n1##y,z,c)), \ - 1>=(img)._width?(img).width() - 1:1); \ - (_n1##x<(img).width() && ( \ - (I[2] = (T)(img)(_n1##x,_p1##y,z,c)), \ - (I[5] = (T)(img)(_n1##x,y,z,c)), \ - (I[8] = (T)(img)(_n1##x,_n1##y,z,c)),1)) || \ - x==--_n1##x; \ - I[0] = I[1], I[1] = I[2], \ - I[3] = I[4], I[4] = I[5], \ - I[6] = I[7], I[7] = I[8], \ - _p1##x = x++, ++_n1##x) - - if (is_empty()) return *this; - CImg res(3*_width,3*_height,_depth,_spectrum); - CImg_3x3(I,T); - cimg_forZC(*this,z,c) { - T - *ptrd1 = res.data(0,0,z,c), - *ptrd2 = ptrd1 + res._width, - *ptrd3 = ptrd2 + res._width; - _cimg_gs3x_for3x3(*this,x,y,z,c,I,T) { - if (Icp != Icn && Ipc != Inc) { - *(ptrd1++) = Ipc==Icp?Ipc:Icc; - *(ptrd1++) = (Ipc==Icp && Icc!=Inp) || (Icp==Inc && Icc!=Ipp)?Icp:Icc; - *(ptrd1++) = Icp==Inc?Inc:Icc; - *(ptrd2++) = (Ipc==Icp && Icc!=Ipn) || (Ipc==Icn && Icc!=Ipp)?Ipc:Icc; - *(ptrd2++) = Icc; - *(ptrd2++) = (Icp==Inc && Icc!=Inn) || (Icn==Inc && Icc!=Inp)?Inc:Icc; - *(ptrd3++) = Ipc==Icn?Ipc:Icc; - *(ptrd3++) = (Ipc==Icn && Icc!=Inn) || (Icn==Inc && Icc!=Ipn)?Icn:Icc; - *(ptrd3++) = Icn==Inc?Inc:Icc; - } else { - *(ptrd1++) = Icc; *(ptrd1++) = Icc; *(ptrd1++) = Icc; - *(ptrd2++) = Icc; *(ptrd2++) = Icc; *(ptrd2++) = Icc; - *(ptrd3++) = Icc; *(ptrd3++) = Icc; *(ptrd3++) = Icc; - } - } - } - return res; - } - - //! Mirror image content along specified axis. - /** - \param axis Mirror axis - **/ - CImg& mirror(const char axis) { - if (is_empty()) return *this; - T *pf, *pb, *buf = 0; - switch (cimg::lowercase(axis)) { - case 'x' : { - pf = _data; pb = data(_width - 1); - const unsigned int width2 = _width/2; - for (unsigned int yzv = 0; yzv<_height*_depth*_spectrum; ++yzv) { - for (unsigned int x = 0; x get_mirror(const char axis) const { - return (+*this).mirror(axis); - } - - //! Mirror image content along specified axes. - /** - \param axes Mirror axes, as a C-string. - \note \c axes may contains multiple characters, e.g. \c "xyz" - **/ - CImg& mirror(const char *const axes) { - for (const char *s = axes; *s; ++s) mirror(*s); - return *this; - } - - //! Mirror image content along specified axes \newinstance. - CImg get_mirror(const char *const axes) const { - return (+*this).mirror(axes); - } - - //! Shift image content. - /** - \param delta_x Amount of displacement along the X-axis. - \param delta_y Amount of displacement along the Y-axis. - \param delta_z Amount of displacement along the Z-axis. - \param delta_c Amount of displacement along the C-axis. - \param boundary_conditions Border condition. - - - \c boundary_conditions can be: - - 0: Zero border condition (Dirichlet). - - 1: Nearest neighbors (Neumann). - - 2: Repeat Pattern (Fourier style). - **/ - CImg& shift(const int delta_x, const int delta_y=0, const int delta_z=0, const int delta_c=0, - const int boundary_conditions=0) { - if (is_empty()) return *this; - if (delta_x) // Shift along X-axis - switch (boundary_conditions) { - case 0 : - if (cimg::abs(delta_x)>=width()) return fill(0); - if (delta_x<0) cimg_forYZC(*this,y,z,c) { - std::memmove(data(0,y,z,c),data(-delta_x,y,z,c),(_width + delta_x)*sizeof(T)); - std::memset(data(_width + delta_x,y,z,c),0,-delta_x*sizeof(T)); - } else cimg_forYZC(*this,y,z,c) { - std::memmove(data(delta_x,y,z,c),data(0,y,z,c),(_width-delta_x)*sizeof(T)); - std::memset(data(0,y,z,c),0,delta_x*sizeof(T)); - } - break; - case 1 : - if (delta_x<0) { - const int ndelta_x = (-delta_x>=width())?width() - 1:-delta_x; - if (!ndelta_x) return *this; - cimg_forYZC(*this,y,z,c) { - std::memmove(data(0,y,z,c),data(ndelta_x,y,z,c),(_width-ndelta_x)*sizeof(T)); - T *ptrd = data(_width - 1,y,z,c); - const T val = *ptrd; - for (int l = 0; l=width())?width() - 1:delta_x; - if (!ndelta_x) return *this; - cimg_forYZC(*this,y,z,c) { - std::memmove(data(ndelta_x,y,z,c),data(0,y,z,c),(_width-ndelta_x)*sizeof(T)); - T *ptrd = data(0,y,z,c); - const T val = *ptrd; - for (int l = 0; l0) cimg_forYZC(*this,y,z,c) { - std::memcpy(buf,data(0,y,z,c),ndelta_x*sizeof(T)); - std::memmove(data(0,y,z,c),data(ndelta_x,y,z,c),(_width-ndelta_x)*sizeof(T)); - std::memcpy(data(_width-ndelta_x,y,z,c),buf,ndelta_x*sizeof(T)); - } else cimg_forYZC(*this,y,z,c) { - std::memcpy(buf,data(_width + ndelta_x,y,z,c),-ndelta_x*sizeof(T)); - std::memmove(data(-ndelta_x,y,z,c),data(0,y,z,c),(_width + ndelta_x)*sizeof(T)); - std::memcpy(data(0,y,z,c),buf,-ndelta_x*sizeof(T)); - } - delete[] buf; - } - } - - if (delta_y) // Shift along Y-axis - switch (boundary_conditions) { - case 0 : - if (cimg::abs(delta_y)>=height()) return fill(0); - if (delta_y<0) cimg_forZC(*this,z,c) { - std::memmove(data(0,0,z,c),data(0,-delta_y,z,c),_width*(_height + delta_y)*sizeof(T)); - std::memset(data(0,_height + delta_y,z,c),0,-delta_y*_width*sizeof(T)); - } else cimg_forZC(*this,z,c) { - std::memmove(data(0,delta_y,z,c),data(0,0,z,c),_width*(_height-delta_y)*sizeof(T)); - std::memset(data(0,0,z,c),0,delta_y*_width*sizeof(T)); - } - break; - case 1 : - if (delta_y<0) { - const int ndelta_y = (-delta_y>=height())?height() - 1:-delta_y; - if (!ndelta_y) return *this; - cimg_forZC(*this,z,c) { - std::memmove(data(0,0,z,c),data(0,ndelta_y,z,c),_width*(_height-ndelta_y)*sizeof(T)); - T *ptrd = data(0,_height-ndelta_y,z,c), *ptrs = data(0,_height - 1,z,c); - for (int l = 0; l=height())?height() - 1:delta_y; - if (!ndelta_y) return *this; - cimg_forZC(*this,z,c) { - std::memmove(data(0,ndelta_y,z,c),data(0,0,z,c),_width*(_height-ndelta_y)*sizeof(T)); - T *ptrd = data(0,1,z,c), *ptrs = data(0,0,z,c); - for (int l = 0; l0) cimg_forZC(*this,z,c) { - std::memcpy(buf,data(0,0,z,c),_width*ndelta_y*sizeof(T)); - std::memmove(data(0,0,z,c),data(0,ndelta_y,z,c),_width*(_height-ndelta_y)*sizeof(T)); - std::memcpy(data(0,_height-ndelta_y,z,c),buf,_width*ndelta_y*sizeof(T)); - } else cimg_forZC(*this,z,c) { - std::memcpy(buf,data(0,_height + ndelta_y,z,c),-ndelta_y*_width*sizeof(T)); - std::memmove(data(0,-ndelta_y,z,c),data(0,0,z,c),_width*(_height + ndelta_y)*sizeof(T)); - std::memcpy(data(0,0,z,c),buf,-ndelta_y*_width*sizeof(T)); - } - delete[] buf; - } - } - - if (delta_z) // Shift along Z-axis - switch (boundary_conditions) { - case 0 : - if (cimg::abs(delta_z)>=depth()) return fill(0); - if (delta_z<0) cimg_forC(*this,c) { - std::memmove(data(0,0,0,c),data(0,0,-delta_z,c),_width*_height*(_depth + delta_z)*sizeof(T)); - std::memset(data(0,0,_depth + delta_z,c),0,_width*_height*(-delta_z)*sizeof(T)); - } else cimg_forC(*this,c) { - std::memmove(data(0,0,delta_z,c),data(0,0,0,c),_width*_height*(_depth-delta_z)*sizeof(T)); - std::memset(data(0,0,0,c),0,delta_z*_width*_height*sizeof(T)); - } - break; - case 1 : - if (delta_z<0) { - const int ndelta_z = (-delta_z>=depth())?depth() - 1:-delta_z; - if (!ndelta_z) return *this; - cimg_forC(*this,c) { - std::memmove(data(0,0,0,c),data(0,0,ndelta_z,c),_width*_height*(_depth-ndelta_z)*sizeof(T)); - T *ptrd = data(0,0,_depth-ndelta_z,c), *ptrs = data(0,0,_depth - 1,c); - for (int l = 0; l=depth())?depth() - 1:delta_z; - if (!ndelta_z) return *this; - cimg_forC(*this,c) { - std::memmove(data(0,0,ndelta_z,c),data(0,0,0,c),_width*_height*(_depth-ndelta_z)*sizeof(T)); - T *ptrd = data(0,0,1,c), *ptrs = data(0,0,0,c); - for (int l = 0; l0) cimg_forC(*this,c) { - std::memcpy(buf,data(0,0,0,c),_width*_height*ndelta_z*sizeof(T)); - std::memmove(data(0,0,0,c),data(0,0,ndelta_z,c),_width*_height*(_depth-ndelta_z)*sizeof(T)); - std::memcpy(data(0,0,_depth-ndelta_z,c),buf,_width*_height*ndelta_z*sizeof(T)); - } else cimg_forC(*this,c) { - std::memcpy(buf,data(0,0,_depth + ndelta_z,c),-ndelta_z*_width*_height*sizeof(T)); - std::memmove(data(0,0,-ndelta_z,c),data(0,0,0,c),_width*_height*(_depth + ndelta_z)*sizeof(T)); - std::memcpy(data(0,0,0,c),buf,-ndelta_z*_width*_height*sizeof(T)); - } - delete[] buf; - } - } - - if (delta_c) // Shift along C-axis - switch (boundary_conditions) { - case 0 : - if (cimg::abs(delta_c)>=spectrum()) return fill(0); - if (delta_c<0) { - std::memmove(_data,data(0,0,0,-delta_c),_width*_height*_depth*(_spectrum + delta_c)*sizeof(T)); - std::memset(data(0,0,0,_spectrum + delta_c),0,_width*_height*_depth*(-delta_c)*sizeof(T)); - } else { - std::memmove(data(0,0,0,delta_c),_data,_width*_height*_depth*(_spectrum-delta_c)*sizeof(T)); - std::memset(_data,0,delta_c*_width*_height*_depth*sizeof(T)); - } - break; - case 1 : - if (delta_c<0) { - const int ndelta_c = (-delta_c>=spectrum())?spectrum() - 1:-delta_c; - if (!ndelta_c) return *this; - std::memmove(_data,data(0,0,0,ndelta_c),_width*_height*_depth*(_spectrum-ndelta_c)*sizeof(T)); - T *ptrd = data(0,0,0,_spectrum-ndelta_c), *ptrs = data(0,0,0,_spectrum - 1); - for (int l = 0; l=spectrum())?spectrum() - 1:delta_c; - if (!ndelta_c) return *this; - std::memmove(data(0,0,0,ndelta_c),_data,_width*_height*_depth*(_spectrum-ndelta_c)*sizeof(T)); - T *ptrd = data(0,0,0,1); - for (int l = 0; l0) { - std::memcpy(buf,_data,_width*_height*_depth*ndelta_c*sizeof(T)); - std::memmove(_data,data(0,0,0,ndelta_c),_width*_height*_depth*(_spectrum-ndelta_c)*sizeof(T)); - std::memcpy(data(0,0,0,_spectrum-ndelta_c),buf,_width*_height*_depth*ndelta_c*sizeof(T)); - } else { - std::memcpy(buf,data(0,0,0,_spectrum + ndelta_c),-ndelta_c*_width*_height*_depth*sizeof(T)); - std::memmove(data(0,0,0,-ndelta_c),_data,_width*_height*_depth*(_spectrum + ndelta_c)*sizeof(T)); - std::memcpy(_data,buf,-ndelta_c*_width*_height*_depth*sizeof(T)); - } - delete[] buf; - } - } - return *this; - } - - //! Shift image content \newinstance. - CImg get_shift(const int delta_x, const int delta_y=0, const int delta_z=0, const int delta_c=0, - const int boundary_conditions=0) const { - return (+*this).shift(delta_x,delta_y,delta_z,delta_c,boundary_conditions); - } - - //! Permute axes order. - /** - \param order Axes permutations, as a C-string of 4 characters. - This function permutes image content regarding the specified axes permutation. - **/ - CImg& permute_axes(const char *const order) { - return get_permute_axes(order).move_to(*this); - } - - //! Permute axes order \newinstance. - CImg get_permute_axes(const char *const order) const { - const T foo = (T)0; - return _get_permute_axes(order,foo); - } - - template - CImg _get_permute_axes(const char *const permut, const t&) const { - if (is_empty() || !permut) return CImg(*this,false); - CImg res; - const T* ptrs = _data; - unsigned char s_code[4] = { 0,1,2,3 }, n_code[4] = { 0 }; - for (unsigned int l = 0; permut[l]; ++l) { - int c = cimg::lowercase(permut[l]); - if (c!='x' && c!='y' && c!='z' && c!='c') { *s_code = 4; break; } - else { ++n_code[c%=4]; s_code[l] = c; } - } - if (*permut && *s_code<4 && *n_code<=1 && n_code[1]<=1 && n_code[2]<=1 && n_code[3]<=1) { - const unsigned int code = (s_code[0]<<12) | (s_code[1]<<8) | (s_code[2]<<4) | (s_code[3]); - ulongT wh, whd; - switch (code) { - case 0x0123 : // xyzc - return +*this; - case 0x0132 : // xycz - res.assign(_width,_height,_spectrum,_depth); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(x,y,c,z,wh,whd) = (t)*(ptrs++); - break; - case 0x0213 : // xzyc - res.assign(_width,_depth,_height,_spectrum); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(x,z,y,c,wh,whd) = (t)*(ptrs++); - break; - case 0x0231 : // xzcy - res.assign(_width,_depth,_spectrum,_height); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(x,z,c,y,wh,whd) = (t)*(ptrs++); - break; - case 0x0312 : // xcyz - res.assign(_width,_spectrum,_height,_depth); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(x,c,y,z,wh,whd) = (t)*(ptrs++); - break; - case 0x0321 : // xczy - res.assign(_width,_spectrum,_depth,_height); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(x,c,z,y,wh,whd) = (t)*(ptrs++); - break; - case 0x1023 : // yxzc - res.assign(_height,_width,_depth,_spectrum); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(y,x,z,c,wh,whd) = (t)*(ptrs++); - break; - case 0x1032 : // yxcz - res.assign(_height,_width,_spectrum,_depth); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(y,x,c,z,wh,whd) = (t)*(ptrs++); - break; - case 0x1203 : // yzxc - res.assign(_height,_depth,_width,_spectrum); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(y,z,x,c,wh,whd) = (t)*(ptrs++); - break; - case 0x1230 : // yzcx - res.assign(_height,_depth,_spectrum,_width); - switch (_width) { - case 1 : { - t *ptr_r = res.data(0,0,0,0); - for (unsigned int siz = _height*_depth*_spectrum; siz; --siz) { - *(ptr_r++) = (t)*(ptrs++); - } - } break; - case 2 : { - t *ptr_r = res.data(0,0,0,0), *ptr_g = res.data(0,0,0,1); - for (unsigned int siz = _height*_depth*_spectrum; siz; --siz) { - *(ptr_r++) = (t)*(ptrs++); *(ptr_g++) = (t)*(ptrs++); - } - } break; - case 3 : { // Optimization for the classical conversion from interleaved RGB to planar RGB - t *ptr_r = res.data(0,0,0,0), *ptr_g = res.data(0,0,0,1), *ptr_b = res.data(0,0,0,2); - for (unsigned int siz = _height*_depth*_spectrum; siz; --siz) { - *(ptr_r++) = (t)*(ptrs++); *(ptr_g++) = (t)*(ptrs++); *(ptr_b++) = (t)*(ptrs++); - } - } break; - case 4 : { // Optimization for the classical conversion from interleaved RGBA to planar RGBA - t *ptr_r = res.data(0,0,0,0), *ptr_g = res.data(0,0,0,1), *ptr_b = res.data(0,0,0,2), *ptr_a = res.data(0,0,0,3); - for (unsigned int siz = _height*_depth*_spectrum; siz; --siz) { - *(ptr_r++) = (t)*(ptrs++); *(ptr_g++) = (t)*(ptrs++); *(ptr_b++) = (t)*(ptrs++); *(ptr_a++) = (t)*(ptrs++); - } - } break; - default : { - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(y,z,c,x,wh,whd) = *(ptrs++); - return res; - } - } - break; - case 0x1302 : // ycxz - res.assign(_height,_spectrum,_width,_depth); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(y,c,x,z,wh,whd) = (t)*(ptrs++); - break; - case 0x1320 : // yczx - res.assign(_height,_spectrum,_depth,_width); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(y,c,z,x,wh,whd) = (t)*(ptrs++); - break; - case 0x2013 : // zxyc - res.assign(_depth,_width,_height,_spectrum); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(z,x,y,c,wh,whd) = (t)*(ptrs++); - break; - case 0x2031 : // zxcy - res.assign(_depth,_width,_spectrum,_height); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(z,x,c,y,wh,whd) = (t)*(ptrs++); - break; - case 0x2103 : // zyxc - res.assign(_depth,_height,_width,_spectrum); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(z,y,x,c,wh,whd) = (t)*(ptrs++); - break; - case 0x2130 : // zycx - res.assign(_depth,_height,_spectrum,_width); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(z,y,c,x,wh,whd) = (t)*(ptrs++); - break; - case 0x2301 : // zcxy - res.assign(_depth,_spectrum,_width,_height); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(z,c,x,y,wh,whd) = (t)*(ptrs++); - break; - case 0x2310 : // zcyx - res.assign(_depth,_spectrum,_height,_width); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(z,c,y,x,wh,whd) = (t)*(ptrs++); - break; - case 0x3012 : // cxyz - res.assign(_spectrum,_width,_height,_depth); - switch (_spectrum) { - case 1 : { - const T *ptr_r = data(0,0,0,0); - t *ptrd = res._data; - for (ulongT siz = (ulongT)_width*_height*_depth; siz; --siz) *(ptrd++) = (t)*(ptr_r++); - } break; - case 2 : { - const T *ptr_r = data(0,0,0,0), *ptr_g = data(0,0,0,1); - t *ptrd = res._data; - for (ulongT siz = (ulongT)_width*_height*_depth; siz; --siz) { - *(ptrd++) = (t)*(ptr_r++); *(ptrd++) = (t)*(ptr_g++); - } - } break; - case 3 : { // Optimization for the classical conversion from planar RGB to interleaved RGB - const T *ptr_r = data(0,0,0,0), *ptr_g = data(0,0,0,1), *ptr_b = data(0,0,0,2); - t *ptrd = res._data; - for (ulongT siz = (ulongT)_width*_height*_depth; siz; --siz) { - *(ptrd++) = (t)*(ptr_r++); *(ptrd++) = (t)*(ptr_g++); *(ptrd++) = (t)*(ptr_b++); - } - } break; - case 4 : { // Optimization for the classical conversion from planar RGBA to interleaved RGBA - const T *ptr_r = data(0,0,0,0), *ptr_g = data(0,0,0,1), *ptr_b = data(0,0,0,2), *ptr_a = data(0,0,0,3); - t *ptrd = res._data; - for (ulongT siz = (ulongT)_width*_height*_depth; siz; --siz) { - *(ptrd++) = (t)*(ptr_r++); *(ptrd++) = (t)*(ptr_g++); *(ptrd++) = (t)*(ptr_b++); *(ptrd++) = (t)*(ptr_a++); - } - } break; - default : { - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(c,x,y,z,wh,whd) = (t)*(ptrs++); - } - } - break; - case 0x3021 : // cxzy - res.assign(_spectrum,_width,_depth,_height); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(c,x,z,y,wh,whd) = (t)*(ptrs++); - break; - case 0x3102 : // cyxz - res.assign(_spectrum,_height,_width,_depth); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(c,y,x,z,wh,whd) = (t)*(ptrs++); - break; - case 0x3120 : // cyzx - res.assign(_spectrum,_height,_depth,_width); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(c,y,z,x,wh,whd) = (t)*(ptrs++); - break; - case 0x3201 : // czxy - res.assign(_spectrum,_depth,_width,_height); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(c,z,x,y,wh,whd) = (t)*(ptrs++); - break; - case 0x3210 : // czyx - res.assign(_spectrum,_depth,_height,_width); - wh = (ulongT)res._width*res._height; whd = wh*res._depth; - cimg_forXYZC(*this,x,y,z,c) res(c,z,y,x,wh,whd) = (t)*(ptrs++); - break; - } - } - if (!res) - throw CImgArgumentException(_cimg_instance - "permute_axes(): Invalid specified permutation '%s'.", - cimg_instance, - permut); - return res; - } - - //! Unroll pixel values along specified axis. - /** - \param axis Unroll axis (can be \c 'x', \c 'y', \c 'z' or c 'c'). - **/ - CImg& unroll(const char axis) { - const unsigned int siz = (unsigned int)size(); - if (siz) switch (cimg::lowercase(axis)) { - case 'x' : _width = siz; _height = _depth = _spectrum = 1; break; - case 'y' : _height = siz; _width = _depth = _spectrum = 1; break; - case 'z' : _depth = siz; _width = _height = _spectrum = 1; break; - default : _spectrum = siz; _width = _height = _depth = 1; - } - return *this; - } - - //! Unroll pixel values along specified axis \newinstance. - CImg get_unroll(const char axis) const { - return (+*this).unroll(axis); - } - - //! Rotate image with arbitrary angle. - /** - \param angle Rotation angle, in degrees. - \param interpolation Type of interpolation. Can be { 0=nearest | 1=linear | 2=cubic }. - \param boundary Boundary conditions. Can be { 0=dirichlet | 1=neumann | 2=periodic }. - \note Most of the time, size of the image is modified. - **/ - CImg& rotate(const float angle, const unsigned int interpolation=1, - const unsigned int boundary_conditions=0) { - const float nangle = cimg::mod(angle,360.0f); - if (nangle==0.0f) return *this; - return get_rotate(angle,interpolation,boundary_conditions).move_to(*this); - } - - //! Rotate image with arbitrary angle \newinstance. - CImg get_rotate(const float angle, const unsigned int interpolation=1, - const unsigned int boundary_conditions=0) const { - if (is_empty()) return *this; - CImg res; - const float nangle = cimg::mod(angle,360.0f); - if (boundary_conditions!=1 && cimg::mod(nangle,90.0f)==0) { // Optimized version for orthogonal angles. - const int wm1 = width() - 1, hm1 = height() - 1; - const int iangle = (int)nangle/90; - switch (iangle) { - case 1 : { // 90 deg. - res.assign(_height,_width,_depth,_spectrum); - T *ptrd = res._data; - cimg_forXYZC(res,x,y,z,c) *(ptrd++) = (*this)(y,hm1-x,z,c); - } break; - case 2 : { // 180 deg. - res.assign(_width,_height,_depth,_spectrum); - T *ptrd = res._data; - cimg_forXYZC(res,x,y,z,c) *(ptrd++) = (*this)(wm1-x,hm1-y,z,c); - } break; - case 3 : { // 270 deg. - res.assign(_height,_width,_depth,_spectrum); - T *ptrd = res._data; - cimg_forXYZC(res,x,y,z,c) *(ptrd++) = (*this)(wm1-y,x,z,c); - } break; - default : // 0 deg. - return *this; - } - } else { // Generic angle. - const Tfloat vmin = (Tfloat)cimg::type::min(), vmax = (Tfloat)cimg::type::max(); - const float - rad = (float)(nangle*cimg::PI/180.0), - ca = (float)std::cos(rad), - sa = (float)std::sin(rad), - ux = cimg::abs(_width*ca), uy = cimg::abs(_width*sa), - vx = cimg::abs(_height*sa), vy = cimg::abs(_height*ca), - w2 = 0.5f*_width, h2 = 0.5f*_height, - dw2 = 0.5f*(ux + vx), dh2 = 0.5f*(uy + vy); - res.assign((int)(ux + vx),(int)(uy + vy),_depth,_spectrum); - switch (boundary_conditions) { - case 0 : { // Dirichlet boundaries. - switch (interpolation) { - case 2 : { // Cubic interpolation. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=2048)) - cimg_forXYZC(res,x,y,z,c) { - const Tfloat val = cubic_atXY(w2 + (x-dw2)*ca + (y-dh2)*sa,h2 - (x-dw2)*sa + (y-dh2)*ca,z,c,0); - res(x,y,z,c) = (T)(valvmax?vmax:val); - } - } break; - case 1 : { // Linear interpolation. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=2048)) - cimg_forXYZC(res,x,y,z,c) - res(x,y,z,c) = (T)linear_atXY(w2 + (x-dw2)*ca + (y-dh2)*sa,h2 - (x-dw2)*sa + (y-dh2)*ca,z,c,0); - } break; - default : { // Nearest-neighbor interpolation. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=2048)) - cimg_forXYZC(res,x,y,z,c) - res(x,y,z,c) = atXY((int)(w2 + (x-dw2)*ca + (y-dh2)*sa),(int)(h2 - (x-dw2)*sa + (y-dh2)*ca),z,c,0); - } - } - } break; - case 1 : { // Neumann boundaries. - switch (interpolation) { - case 2 : { // Cubic interpolation. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=2048)) - cimg_forXYZC(res,x,y,z,c) { - const Tfloat val = _cubic_atXY(w2 + (x-dw2)*ca + (y-dh2)*sa,h2 - (x-dw2)*sa + (y-dh2)*ca,z,c); - res(x,y,z,c) = (T)(valvmax?vmax:val); - } - } break; - case 1 : { // Linear interpolation. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=2048)) - cimg_forXYZC(res,x,y,z,c) - res(x,y,z,c) = (T)_linear_atXY(w2 + (x-dw2)*ca + (y-dh2)*sa,h2 - (x-dw2)*sa + (y-dh2)*ca,z,c); - } break; - default : { // Nearest-neighbor interpolation. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=2048)) - cimg_forXYZC(res,x,y,z,c) - res(x,y,z,c) = _atXY((int)(w2 + (x-dw2)*ca + (y-dh2)*sa),(int)(h2 - (x-dw2)*sa + (y-dh2)*ca),z,c); - } - } - } break; - case 2 : { // Periodic boundaries. - switch (interpolation) { - case 2 : { // Cubic interpolation. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=2048)) - cimg_forXYZC(res,x,y,z,c) { - const Tfloat val = _cubic_atXY(cimg::mod(w2 + (x-dw2)*ca + (y-dh2)*sa,(float)width()), - cimg::mod(h2 - (x-dw2)*sa + (y-dh2)*ca,(float)height()),z,c); - res(x,y,z,c) = (T)(valvmax?vmax:val); - } - } break; - case 1 : { // Linear interpolation. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=2048)) - cimg_forXYZC(res,x,y,z,c) - res(x,y,z,c) = (T)_linear_atXY(cimg::mod(w2 + (x-dw2)*ca + (y-dh2)*sa,(float)width()), - cimg::mod(h2 - (x-dw2)*sa + (y-dh2)*ca,(float)height()),z,c); - } break; - default : { // Nearest-neighbor interpolation. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=2048)) - cimg_forXYZC(res,x,y,z,c) - res(x,y,z,c) = (*this)(cimg::mod((int)(w2 + (x-dw2)*ca + (y-dh2)*sa),width()), - cimg::mod((int)(h2 - (x-dw2)*sa + (y-dh2)*ca),height()),z,c); - } - } - } break; - default : - throw CImgArgumentException(_cimg_instance - "rotate(): Invalid specified border conditions %d " - "(should be { 0=dirichlet | 1=neumann | 2=periodic }).", - cimg_instance, - boundary_conditions); - } - } - return res; - } - - //! Rotate image with arbitrary angle, around a center point. - /** - \param angle Rotation angle, in degrees. - \param cx X-coordinate of the rotation center. - \param cy Y-coordinate of the rotation center. - \param zoom Zoom factor. - \param boundary_conditions Boundary conditions. Can be { 0=dirichlet | 1=neumann | 2=periodic }. - \param interpolation_type Type of interpolation. Can be { 0=nearest | 1=linear | 2=cubic }. - **/ - CImg& rotate(const float angle, const float cx, const float cy, const float zoom, - const unsigned int interpolation=1, const unsigned int boundary_conditions=0) { - return get_rotate(angle,cx,cy,zoom,interpolation,boundary_conditions).move_to(*this); - } - - //! Rotate image with arbitrary angle, around a center point \newinstance. - CImg get_rotate(const float angle, const float cx, const float cy, const float zoom, - const unsigned int interpolation=1, const unsigned int boundary_conditions=0) const { - if (interpolation>2) - throw CImgArgumentException(_cimg_instance - "rotate(): Invalid specified interpolation type %d " - "(should be { 0=none | 1=linear | 2=cubic }).", - cimg_instance, - interpolation); - if (is_empty()) return *this; - CImg res(_width,_height,_depth,_spectrum); - const Tfloat vmin = (Tfloat)cimg::type::min(), vmax = (Tfloat)cimg::type::max(); - const float - rad = (float)((angle*cimg::PI)/180.0), - ca = (float)std::cos(rad)/zoom, - sa = (float)std::sin(rad)/zoom; - switch (boundary_conditions) { - case 0 : { - switch (interpolation) { - case 2 : { - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=2048)) - cimg_forXYZC(res,x,y,z,c) { - const Tfloat val = cubic_atXY(cx + (x-cx)*ca + (y-cy)*sa,cy - (x-cx)*sa + (y-cy)*ca,z,c,0); - res(x,y,z,c) = (T)(valvmax?vmax:val); - } - } break; - case 1 : { - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=2048)) - cimg_forXYZC(res,x,y,z,c) - res(x,y,z,c) = (T)linear_atXY(cx + (x-cx)*ca + (y-cy)*sa,cy - (x-cx)*sa + (y-cy)*ca,z,c,0); - } break; - default : { - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=2048)) - cimg_forXYZC(res,x,y,z,c) - res(x,y,z,c) = atXY((int)(cx + (x-cx)*ca + (y-cy)*sa),(int)(cy - (x-cx)*sa + (y-cy)*ca),z,c,0); - } - } - } break; - case 1 : { - switch (interpolation) { - case 2 : { - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=2048)) - cimg_forXYZC(res,x,y,z,c) { - const Tfloat val = _cubic_atXY(cx + (x-cx)*ca + (y-cy)*sa,cy - (x-cx)*sa + (y-cy)*ca,z,c); - res(x,y,z,c) = (T)(valvmax?vmax:val); - } - } break; - case 1 : { - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=2048)) - cimg_forXYZC(res,x,y,z,c) - res(x,y,z,c) = (T)_linear_atXY(cx + (x-cx)*ca + (y-cy)*sa,cy - (x-cx)*sa + (y-cy)*ca,z,c); - } break; - default : { - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=2048)) - cimg_forXYZC(res,x,y,z,c) - res(x,y,z,c) = _atXY((int)(cx + (x-cx)*ca + (y-cy)*sa),(int)(cy - (x-cx)*sa + (y-cy)*ca),z,c); - } - } - } break; - case 2 : { - switch (interpolation) { - case 2 : { - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=2048)) - cimg_forXYZC(res,x,y,z,c) { - const Tfloat val = _cubic_atXY(cimg::mod(cx + (x-cx)*ca + (y-cy)*sa,(float)width()), - cimg::mod(cy - (x-cx)*sa + (y-cy)*ca,(float)height()),z,c); - res(x,y,z,c) = (T)(valvmax?vmax:val); - } - } break; - case 1 : { - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=2048)) - cimg_forXYZC(res,x,y,z,c) - res(x,y,z,c) = (T)_linear_atXY(cimg::mod(cx + (x-cx)*ca + (y-cy)*sa,(float)width()), - cimg::mod(cy - (x-cx)*sa + (y-cy)*ca,(float)height()),z,c); - } break; - default : { - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=2048)) - cimg_forXYZC(res,x,y,z,c) - res(x,y,z,c) = (*this)(cimg::mod((int)(cx + (x-cx)*ca + (y-cy)*sa),width()), - cimg::mod((int)(cy - (x-cx)*sa + (y-cy)*ca),height()),z,c); - } - } - } break; - default : - throw CImgArgumentException(_cimg_instance - "rotate(): Invalid specified border conditions %d " - "(should be { 0=dirichlet | 1=neumann | 2=periodic }).", - cimg_instance, - boundary_conditions); - } - return res; - } - - //! Warp image content by a warping field. - /** - \param warp Warping field. - \param mode Can be { 0=backward-absolute | 1=backward-relative | 2=forward-absolute | 3=foward-relative } - \param is_relative Tells if warping field gives absolute or relative warping coordinates. - \param interpolation Can be { 0=nearest | 1=linear | 2=cubic }. - \param boundary_conditions Boundary conditions. Can be { 0=dirichlet | 1=neumann | 2=periodic }. - **/ - template - CImg& warp(const CImg& warp, const unsigned int mode=0, - const unsigned int interpolation=1, const unsigned int boundary_conditions=0) { - return get_warp(warp,mode,interpolation,boundary_conditions).move_to(*this); - } - - //! Warp image content by a warping field \newinstance - template - CImg get_warp(const CImg& warp, const unsigned int mode=0, - const unsigned int interpolation=1, const unsigned int boundary_conditions=0) const { - if (is_empty() || !warp) return *this; - if (mode && !is_sameXYZ(warp)) - throw CImgArgumentException(_cimg_instance - "warp(): Instance and specified relative warping field (%u,%u,%u,%u,%p) " - "have different XYZ dimensions.", - cimg_instance, - warp._width,warp._height,warp._depth,warp._spectrum,warp._data); - - CImg res(warp._width,warp._height,warp._depth,_spectrum); - - if (warp._spectrum==1) { // 1d warping. - if (mode>=3) { // Forward-relative warp. - res.fill(0); - if (interpolation>=1) // Linear interpolation. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); const T *ptrs = data(0,y,z,c); - cimg_forX(res,x) res.set_linear_atX(*(ptrs++),x + (float)*(ptrs0++),y,z,c); - } - else // Nearest-neighbor interpolation. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); const T *ptrs = data(0,y,z,c); - cimg_forX(res,x) { - const int X = x + (int)*(ptrs0++); - if (X>=0 && X=1) // Linear interpolation. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); const T *ptrs = data(0,y,z,c); - cimg_forX(res,x) res.set_linear_atX(*(ptrs++),(float)*(ptrs0++),y,z,c); - } - else // Nearest-neighbor interpolation. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); const T *ptrs = data(0,y,z,c); - cimg_forX(res,x) { - const int X = (int)*(ptrs0++); - if (X>=0 && X=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_cubic_atX(cimg::mod(x - (float)*(ptrs0++),(float)_width),y,z,c); - } - else if (boundary_conditions==1) // Neumann boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_cubic_atX(x - (float)*(ptrs0++),y,z,c); - } - else // Dirichlet boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)cubic_atX(x - (float)*(ptrs0++),y,z,c,0); - } - } else if (interpolation==1) { // Linear interpolation. - if (boundary_conditions==2) // Periodic boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=1048576)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_linear_atX(cimg::mod(x - (float)*(ptrs0++),(float)_width),y,z,c); - } - else if (boundary_conditions==1) // Neumann boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=1048576)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_linear_atX(x - (float)*(ptrs0++),y,z,c); - } - else // Dirichlet boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=1048576)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)linear_atX(x - (float)*(ptrs0++),y,z,c,0); - } - } else { // Nearest-neighbor interpolation. - if (boundary_conditions==2) // Periodic boundaries. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (*this)(cimg::mod(x - (int)*(ptrs0++),(int)_width),y,z,c); - } - else if (boundary_conditions==1) // Neumann boundaries. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = _atX(x - (int)*(ptrs0++),y,z,c); - } - else // Dirichlet boundaries. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = atX(x - (int)*(ptrs0++),y,z,c,0); - } - } - } else { // Backward-absolute warp. - if (interpolation==2) { // Cubic interpolation. - if (boundary_conditions==2) // Periodic boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_cubic_atX(cimg::mod((float)*(ptrs0++),(float)_width),0,0,c); - } - else if (boundary_conditions==1) // Neumann boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_cubic_atX((float)*(ptrs0++),0,0,c); - } - else // Dirichlet boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)cubic_atX((float)*(ptrs0++),0,0,c,0); - } - } else if (interpolation==1) { // Linear interpolation. - if (boundary_conditions==2) // Periodic boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=1048576)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_linear_atX(cimg::mod((float)*(ptrs0++),(float)_width),0,0,c); - } - else if (boundary_conditions==1) // Neumann boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=1048576)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_linear_atX((float)*(ptrs0++),0,0,c); - } - else // Dirichlet boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=1048576)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)linear_atX((float)*(ptrs0++),0,0,c,0); - } - } else { // Nearest-neighbor interpolation. - if (boundary_conditions==2) // Periodic boundaries. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (*this)(cimg::mod((int)*(ptrs0++),(int)_width),0,0,c); - } - else if (boundary_conditions==1) // Neumann boundaries. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = _atX((int)*(ptrs0++),0,0,c); - } - else // Dirichlet boundaries. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = atX((int)*(ptrs0++),0,0,c,0); - } - } - } - - } else if (warp._spectrum==2) { // 2d warping. - if (mode>=3) { // Forward-relative warp. - res.fill(0); - if (interpolation>=1) // Linear interpolation. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); const T *ptrs = data(0,y,z,c); - cimg_forX(res,x) res.set_linear_atXY(*(ptrs++),x + (float)*(ptrs0++),y + (float)*(ptrs1++),z,c); - } - else // Nearest-neighbor interpolation. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); const T *ptrs = data(0,y,z,c); - cimg_forX(res,x) { - const int X = x + (int)*(ptrs0++), Y = y + (int)*(ptrs1++); - if (X>=0 && X=0 && Y=1) // Linear interpolation. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); const T *ptrs = data(0,y,z,c); - cimg_forX(res,x) res.set_linear_atXY(*(ptrs++),(float)*(ptrs0++),(float)*(ptrs1++),z,c); - } - else // Nearest-neighbor interpolation. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); const T *ptrs = data(0,y,z,c); - cimg_forX(res,x) { - const int X = (int)*(ptrs0++), Y = (int)*(ptrs1++); - if (X>=0 && X=0 && Y=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_cubic_atXY(cimg::mod(x - (float)*(ptrs0++),(float)_width), - cimg::mod(y - (float)*(ptrs1++),(float)_height),z,c); - } - else if (boundary_conditions==1) // Neumann boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_cubic_atXY(x - (float)*(ptrs0++),y - (float)*(ptrs1++),z,c); - } - else // Dirichlet boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)cubic_atXY(x - (float)*(ptrs0++),y - (float)*(ptrs1++),z,c,0); - } - } else if (interpolation==1) { // Linear interpolation. - if (boundary_conditions==2) // Periodic boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=1048576)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_linear_atXY(cimg::mod(x - (float)*(ptrs0++),(float)_width), - cimg::mod(y - (float)*(ptrs1++),(float)_height),z,c); - } - else if (boundary_conditions==1) // Neumann boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=1048576)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_linear_atXY(x - (float)*(ptrs0++),y - (float)*(ptrs1++),z,c); - } - else // Dirichlet boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=1048576)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)linear_atXY(x - (float)*(ptrs0++),y - (float)*(ptrs1++),z,c,0); - } - } else { // Nearest-neighbor interpolation. - if (boundary_conditions==2) // Periodic boundaries. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (*this)(cimg::mod(x - (int)*(ptrs0++),(int)_width), - cimg::mod(y - (int)*(ptrs1++),(int)_height),z,c); - } - else if (boundary_conditions==1) // Neumann boundaries. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = _atXY(x - (int)*(ptrs0++),y - (int)*(ptrs1++),z,c); - } - else // Dirichlet boundaries. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = atXY(x - (int)*(ptrs0++),y - (int)*(ptrs1++),z,c,0); - } - } - } else { // Backward-absolute warp. - if (interpolation==2) { // Cubic interpolation. - if (boundary_conditions==2) // Periodic boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_cubic_atXY(cimg::mod((float)*(ptrs0++),(float)_width), - cimg::mod((float)*(ptrs1++),(float)_height),0,c); - } - else if (boundary_conditions==1) // Neumann boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_cubic_atXY((float)*(ptrs0++),(float)*(ptrs1++),0,c); - } - else // Dirichlet boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)cubic_atXY((float)*(ptrs0++),(float)*(ptrs1++),0,c,0); - } - } else if (interpolation==1) { // Linear interpolation. - if (boundary_conditions==2) // Periodic boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=1048576)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_linear_atXY(cimg::mod((float)*(ptrs0++),(float)_width), - cimg::mod((float)*(ptrs1++),(float)_height),0,c); - } - else if (boundary_conditions==1) // Neumann boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=1048576)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_linear_atXY((float)*(ptrs0++),(float)*(ptrs1++),0,c); - } - else // Dirichlet boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=1048576)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)linear_atXY((float)*(ptrs0++),(float)*(ptrs1++),0,c,0); - } - } else { // Nearest-neighbor interpolation. - if (boundary_conditions==2) // Periodic boundaries. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (*this)(cimg::mod((int)*(ptrs0++),(int)_width), - cimg::mod((int)*(ptrs1++),(int)_height),0,c); - } - else if (boundary_conditions==1) // Neumann boundaries. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = _atXY((int)*(ptrs0++),(int)*(ptrs1++),0,c); - } - else // Dirichlet boundaries. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1); T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = atXY((int)*(ptrs0++),(int)*(ptrs1++),0,c,0); - } - } - } - - } else { // 3d warping. - if (mode>=3) { // Forward-relative warp. - res.fill(0); - if (interpolation>=1) // Linear interpolation. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - const T *ptrs = data(0,y,z,c); - cimg_forX(res,x) res.set_linear_atXYZ(*(ptrs++),x + (float)*(ptrs0++),y + (float)*(ptrs1++), - z + (float)*(ptrs2++),c); - } - else // Nearest-neighbor interpolation. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - const T *ptrs = data(0,y,z,c); - cimg_forX(res,x) { - const int X = x + (int)*(ptrs0++), Y = y + (int)*(ptrs1++), Z = z + (int)*(ptrs2++); - if (X>=0 && X=0 && Y=0 && Z=1) // Linear interpolation. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - const T *ptrs = data(0,y,z,c); - cimg_forX(res,x) res.set_linear_atXYZ(*(ptrs++),(float)*(ptrs0++),(float)*(ptrs1++),(float)*(ptrs2++),c); - } - else // Nearest-neighbor interpolation. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - const T *ptrs = data(0,y,z,c); - cimg_forX(res,x) { - const int X = (int)*(ptrs0++), Y = (int)*(ptrs1++), Z = (int)*(ptrs2++); - if (X>=0 && X=0 && Y=0 && Z=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_cubic_atXYZ(cimg::mod(x - (float)*(ptrs0++),(float)_width), - cimg::mod(y - (float)*(ptrs1++),(float)_height), - cimg::mod(z - (float)*(ptrs2++),(float)_depth),c); - } - else if (boundary_conditions==1) // Neumann boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) - *(ptrd++) = (T)_cubic_atXYZ(x - (float)*(ptrs0++),y - (float)*(ptrs1++),z - (float)*(ptrs2++),c); - } - else // Dirichlet boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) - *(ptrd++) = (T)cubic_atXYZ(x - (float)*(ptrs0++),y - (float)*(ptrs1++),z - (float)*(ptrs2++),c,0); - } - } else if (interpolation==1) { // Linear interpolation. - if (boundary_conditions==2) // Periodic boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=1048576)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_linear_atXYZ(cimg::mod(x - (float)*(ptrs0++),(float)_width), - cimg::mod(y - (float)*(ptrs1++),(float)_height), - cimg::mod(z - (float)*(ptrs2++),(float)_depth),c); - } - else if (boundary_conditions==1) // Neumann boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=1048576)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) - *(ptrd++) = (T)_linear_atXYZ(x - (float)*(ptrs0++),y - (float)*(ptrs1++),z - (float)*(ptrs2++),c); - } - else // Dirichlet boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=1048576)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) - *(ptrd++) = (T)linear_atXYZ(x - (float)*(ptrs0++),y - (float)*(ptrs1++),z - (float)*(ptrs2++),c,0); - } - } else { // Nearest neighbor interpolation. - if (boundary_conditions==2) // Periodic boundaries. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (*this)(cimg::mod(x - (int)*(ptrs0++),(int)_width), - cimg::mod(y - (int)*(ptrs1++),(int)_height), - cimg::mod(z - (int)*(ptrs2++),(int)_depth),c); - } - else if (boundary_conditions==1) // Neumann boundaries. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = _atXYZ(x - (int)*(ptrs0++),y - (int)*(ptrs1++),z - (int)*(ptrs2++),c); - } - else // Dirichlet boundaries. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = atXYZ(x - (int)*(ptrs0++),y - (int)*(ptrs1++),z - (int)*(ptrs2++),c,0); - } - } - } else { // Backward-absolute warp. - if (interpolation==2) { // Cubic interpolation. - if (boundary_conditions==2) // Periodic boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_cubic_atXYZ(cimg::mod((float)*(ptrs0++),(float)_width), - cimg::mod((float)*(ptrs1++),(float)_height), - cimg::mod((float)*(ptrs2++),(float)_depth),c); - } - else if (boundary_conditions==1) // Neumann boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_cubic_atXYZ((float)*(ptrs0++),(float)*(ptrs1++),(float)*(ptrs2++),c); - } - else // Dirichlet boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=4096)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)cubic_atXYZ((float)*(ptrs0++),(float)*(ptrs1++),(float)*(ptrs2++),c,0); - } - } else if (interpolation==1) { // Linear interpolation. - if (boundary_conditions==2) // Periodic boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=1048576)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_linear_atXYZ(cimg::mod((float)*(ptrs0++),(float)_width), - cimg::mod((float)*(ptrs1++),(float)_height), - cimg::mod((float)*(ptrs2++),(float)_depth),c); - } - else if (boundary_conditions==1) // Neumann boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=1048576)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)_linear_atXYZ((float)*(ptrs0++),(float)*(ptrs1++),(float)*(ptrs2++),c); - } - else // Dirichlet boundaries. - cimg_pragma_openmp(parallel for collapse(3) if (res.size()>=1048576)) - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (T)linear_atXYZ((float)*(ptrs0++),(float)*(ptrs1++),(float)*(ptrs2++),c,0); - } - } else { // Nearest-neighbor interpolation. - if (boundary_conditions==2) // Periodic boundaries. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = (*this)(cimg::mod((int)*(ptrs0++),(int)_width), - cimg::mod((int)*(ptrs1++),(int)_height), - cimg::mod((int)*(ptrs2++),(int)_depth),c); - } - else if (boundary_conditions==1) // Neumann boundaries. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = _atXYZ((int)*(ptrs0++),(int)*(ptrs1++),(int)*(ptrs2++),c); - } - else // Dirichlet boundaries. - cimg_forYZC(res,y,z,c) { - const t *ptrs0 = warp.data(0,y,z,0), *ptrs1 = warp.data(0,y,z,1), *ptrs2 = warp.data(0,y,z,2); - T *ptrd = res.data(0,y,z,c); - cimg_forX(res,x) *(ptrd++) = atXYZ((int)*(ptrs0++),(int)*(ptrs1++),(int)*(ptrs2++),c,0); - } - } - } - } - return res; - } - - //! Generate a 2d representation of a 3d image, with XY,XZ and YZ views. - /** - \param x0 X-coordinate of the projection point. - \param y0 Y-coordinate of the projection point. - \param z0 Z-coordinate of the projection point. - **/ - CImg get_projections2d(const unsigned int x0, const unsigned int y0, const unsigned int z0) const { - if (is_empty() || _depth<2) return +*this; - const unsigned int - _x0 = (x0>=_width)?_width - 1:x0, - _y0 = (y0>=_height)?_height - 1:y0, - _z0 = (z0>=_depth)?_depth - 1:z0; - const CImg - img_xy = get_crop(0,0,_z0,0,_width - 1,_height - 1,_z0,_spectrum - 1), - img_zy = get_crop(_x0,0,0,0,_x0,_height - 1,_depth - 1,_spectrum - 1).permute_axes("xzyc"). - resize(_depth,_height,1,-100,-1), - img_xz = get_crop(0,_y0,0,0,_width - 1,_y0,_depth - 1,_spectrum - 1).resize(_width,_depth,1,-100,-1); - return CImg(_width + _depth,_height + _depth,1,_spectrum,cimg::min(img_xy.min(),img_zy.min(),img_xz.min())). - draw_image(0,0,img_xy).draw_image(img_xy._width,0,img_zy). - draw_image(0,img_xy._height,img_xz); - } - - //! Construct a 2d representation of a 3d image, with XY,XZ and YZ views \inplace. - CImg& projections2d(const unsigned int x0, const unsigned int y0, const unsigned int z0) { - if (_depth<2) return *this; - return get_projections2d(x0,y0,z0).move_to(*this); - } - - //! Crop image region. - /** - \param x0 = X-coordinate of the upper-left crop rectangle corner. - \param y0 = Y-coordinate of the upper-left crop rectangle corner. - \param z0 = Z-coordinate of the upper-left crop rectangle corner. - \param c0 = C-coordinate of the upper-left crop rectangle corner. - \param x1 = X-coordinate of the lower-right crop rectangle corner. - \param y1 = Y-coordinate of the lower-right crop rectangle corner. - \param z1 = Z-coordinate of the lower-right crop rectangle corner. - \param c1 = C-coordinate of the lower-right crop rectangle corner. - \param boundary_conditions = Dirichlet (false) or Neumann border conditions. - **/ - CImg& crop(const int x0, const int y0, const int z0, const int c0, - const int x1, const int y1, const int z1, const int c1, - const bool boundary_conditions=false) { - return get_crop(x0,y0,z0,c0,x1,y1,z1,c1,boundary_conditions).move_to(*this); - } - - //! Crop image region \newinstance. - CImg get_crop(const int x0, const int y0, const int z0, const int c0, - const int x1, const int y1, const int z1, const int c1, - const bool boundary_conditions=false) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "crop(): Empty instance.", - cimg_instance); - const int - nx0 = x0 res(1U + nx1 - nx0,1U + ny1 - ny0,1U + nz1 - nz0,1U + nc1 - nc0); - if (nx0<0 || nx1>=width() || ny0<0 || ny1>=height() || nz0<0 || nz1>=depth() || nc0<0 || nc1>=spectrum()) { - if (boundary_conditions) cimg_forXYZC(res,x,y,z,c) res(x,y,z,c) = _atXYZC(nx0 + x,ny0 + y,nz0 + z,nc0 + c); - else res.fill(0).draw_image(-nx0,-ny0,-nz0,-nc0,*this); - } else res.draw_image(-nx0,-ny0,-nz0,-nc0,*this); - return res; - } - - //! Crop image region \overloading. - CImg& crop(const int x0, const int y0, const int z0, - const int x1, const int y1, const int z1, - const bool boundary_conditions=false) { - return crop(x0,y0,z0,0,x1,y1,z1,_spectrum - 1,boundary_conditions); - } - - //! Crop image region \newinstance. - CImg get_crop(const int x0, const int y0, const int z0, - const int x1, const int y1, const int z1, - const bool boundary_conditions=false) const { - return get_crop(x0,y0,z0,0,x1,y1,z1,_spectrum - 1,boundary_conditions); - } - - //! Crop image region \overloading. - CImg& crop(const int x0, const int y0, - const int x1, const int y1, - const bool boundary_conditions=false) { - return crop(x0,y0,0,0,x1,y1,_depth - 1,_spectrum - 1,boundary_conditions); - } - - //! Crop image region \newinstance. - CImg get_crop(const int x0, const int y0, - const int x1, const int y1, - const bool boundary_conditions=false) const { - return get_crop(x0,y0,0,0,x1,y1,_depth - 1,_spectrum - 1,boundary_conditions); - } - - //! Crop image region \overloading. - CImg& crop(const int x0, const int x1, const bool boundary_conditions=false) { - return crop(x0,0,0,0,x1,_height - 1,_depth - 1,_spectrum - 1,boundary_conditions); - } - - //! Crop image region \newinstance. - CImg get_crop(const int x0, const int x1, const bool boundary_conditions=false) const { - return get_crop(x0,0,0,0,x1,_height - 1,_depth - 1,_spectrum - 1,boundary_conditions); - } - - //! Autocrop image region, regarding the specified background value. - CImg& autocrop(const T& value, const char *const axes="czyx") { - if (is_empty()) return *this; - for (const char *s = axes; *s; ++s) { - const char axis = cimg::lowercase(*s); - const CImg coords = _autocrop(value,axis); - if (coords[0]==-1 && coords[1]==-1) return assign(); // Image has only 'value' pixels. - else switch (axis) { - case 'x' : { - const int x0 = coords[0], x1 = coords[1]; - if (x0>=0 && x1>=0) crop(x0,x1); - } break; - case 'y' : { - const int y0 = coords[0], y1 = coords[1]; - if (y0>=0 && y1>=0) crop(0,y0,_width - 1,y1); - } break; - case 'z' : { - const int z0 = coords[0], z1 = coords[1]; - if (z0>=0 && z1>=0) crop(0,0,z0,_width - 1,_height - 1,z1); - } break; - default : { - const int c0 = coords[0], c1 = coords[1]; - if (c0>=0 && c1>=0) crop(0,0,0,c0,_width - 1,_height - 1,_depth - 1,c1); - } - } - } - return *this; - } - - //! Autocrop image region, regarding the specified background value \newinstance. - CImg get_autocrop(const T& value, const char *const axes="czyx") const { - return (+*this).autocrop(value,axes); - } - - //! Autocrop image region, regarding the specified background color. - /** - \param color Color used for the crop. If \c 0, color is guessed. - \param axes Axes used for the crop. - **/ - CImg& autocrop(const T *const color=0, const char *const axes="zyx") { - if (is_empty()) return *this; - if (!color) { // Guess color. - const CImg col1 = get_vector_at(0,0,0); - const unsigned int w = _width, h = _height, d = _depth, s = _spectrum; - autocrop(col1,axes); - if (_width==w && _height==h && _depth==d && _spectrum==s) { - const CImg col2 = get_vector_at(w - 1,h - 1,d - 1); - autocrop(col2,axes); - } - return *this; - } - for (const char *s = axes; *s; ++s) { - const char axis = cimg::lowercase(*s); - switch (axis) { - case 'x' : { - int x0 = width(), x1 = -1; - cimg_forC(*this,c) { - const CImg coords = get_shared_channel(c)._autocrop(color[c],'x'); - const int nx0 = coords[0], nx1 = coords[1]; - if (nx0>=0 && nx1>=0) { x0 = cimg::min(x0,nx0); x1 = cimg::max(x1,nx1); } - } - if (x0==width() && x1==-1) return assign(); else crop(x0,x1); - } break; - case 'y' : { - int y0 = height(), y1 = -1; - cimg_forC(*this,c) { - const CImg coords = get_shared_channel(c)._autocrop(color[c],'y'); - const int ny0 = coords[0], ny1 = coords[1]; - if (ny0>=0 && ny1>=0) { y0 = cimg::min(y0,ny0); y1 = cimg::max(y1,ny1); } - } - if (y0==height() && y1==-1) return assign(); else crop(0,y0,_width - 1,y1); - } break; - default : { - int z0 = depth(), z1 = -1; - cimg_forC(*this,c) { - const CImg coords = get_shared_channel(c)._autocrop(color[c],'z'); - const int nz0 = coords[0], nz1 = coords[1]; - if (nz0>=0 && nz1>=0) { z0 = cimg::min(z0,nz0); z1 = cimg::max(z1,nz1); } - } - if (z0==depth() && z1==-1) return assign(); else crop(0,0,z0,_width - 1,_height - 1,z1); - } - } - } - return *this; - } - - //! Autocrop image region, regarding the specified background color \newinstance. - CImg get_autocrop(const T *const color=0, const char *const axes="zyx") const { - return (+*this).autocrop(color,axes); - } - - //! Autocrop image region, regarding the specified background color \overloading. - template CImg& autocrop(const CImg& color, const char *const axes="zyx") { - return get_autocrop(color,axes).move_to(*this); - } - - //! Autocrop image region, regarding the specified background color \newinstance. - template CImg get_autocrop(const CImg& color, const char *const axes="zyx") const { - return get_autocrop(color._data,axes); - } - - CImg _autocrop(const T& value, const char axis) const { - CImg res; - switch (cimg::lowercase(axis)) { - case 'x' : { - int x0 = -1, x1 = -1; - cimg_forX(*this,x) cimg_forYZC(*this,y,z,c) - if ((*this)(x,y,z,c)!=value) { x0 = x; x = width(); y = height(); z = depth(); c = spectrum(); } - if (x0>=0) { - for (int x = width() - 1; x>=0; --x) cimg_forYZC(*this,y,z,c) - if ((*this)(x,y,z,c)!=value) { x1 = x; x = 0; y = height(); z = depth(); c = spectrum(); } - } - res = CImg::vector(x0,x1); - } break; - case 'y' : { - int y0 = -1, y1 = -1; - cimg_forY(*this,y) cimg_forXZC(*this,x,z,c) - if ((*this)(x,y,z,c)!=value) { y0 = y; x = width(); y = height(); z = depth(); c = spectrum(); } - if (y0>=0) { - for (int y = height() - 1; y>=0; --y) cimg_forXZC(*this,x,z,c) - if ((*this)(x,y,z,c)!=value) { y1 = y; x = width(); y = 0; z = depth(); c = spectrum(); } - } - res = CImg::vector(y0,y1); - } break; - case 'z' : { - int z0 = -1, z1 = -1; - cimg_forZ(*this,z) cimg_forXYC(*this,x,y,c) - if ((*this)(x,y,z,c)!=value) { z0 = z; x = width(); y = height(); z = depth(); c = spectrum(); } - if (z0>=0) { - for (int z = depth() - 1; z>=0; --z) cimg_forXYC(*this,x,y,c) - if ((*this)(x,y,z,c)!=value) { z1 = z; x = width(); y = height(); z = 0; c = spectrum(); } - } - res = CImg::vector(z0,z1); - } break; - default : { - int c0 = -1, c1 = -1; - cimg_forC(*this,c) cimg_forXYZ(*this,x,y,z) - if ((*this)(x,y,z,c)!=value) { c0 = c; x = width(); y = height(); z = depth(); c = spectrum(); } - if (c0>=0) { - for (int c = spectrum() - 1; c>=0; --c) cimg_forXYZ(*this,x,y,z) - if ((*this)(x,y,z,c)!=value) { c1 = c; x = width(); y = height(); z = depth(); c = 0; } - } - res = CImg::vector(c0,c1); - } - } - return res; - } - - //! Return specified image column. - /** - \param x0 Image column. - **/ - CImg get_column(const int x0) const { - return get_columns(x0,x0); - } - - //! Return specified image column \inplace. - CImg& column(const int x0) { - return columns(x0,x0); - } - - //! Return specified range of image columns. - /** - \param x0 Starting image column. - \param x1 Ending image column. - **/ - CImg& columns(const int x0, const int x1) { - return get_columns(x0,x1).move_to(*this); - } - - //! Return specified range of image columns \inplace. - CImg get_columns(const int x0, const int x1) const { - return get_crop(x0,0,0,0,x1,height() - 1,depth() - 1,spectrum() - 1); - } - - //! Return specified image row. - CImg get_row(const int y0) const { - return get_rows(y0,y0); - } - - //! Return specified image row \inplace. - /** - \param y0 Image row. - **/ - CImg& row(const int y0) { - return rows(y0,y0); - } - - //! Return specified range of image rows. - /** - \param y0 Starting image row. - \param y1 Ending image row. - **/ - CImg get_rows(const int y0, const int y1) const { - return get_crop(0,y0,0,0,width() - 1,y1,depth() - 1,spectrum() - 1); - } - - //! Return specified range of image rows \inplace. - CImg& rows(const int y0, const int y1) { - return get_rows(y0,y1).move_to(*this); - } - - //! Return specified image slice. - /** - \param z0 Image slice. - **/ - CImg get_slice(const int z0) const { - return get_slices(z0,z0); - } - - //! Return specified image slice \inplace. - CImg& slice(const int z0) { - return slices(z0,z0); - } - - //! Return specified range of image slices. - /** - \param z0 Starting image slice. - \param z1 Ending image slice. - **/ - CImg get_slices(const int z0, const int z1) const { - return get_crop(0,0,z0,0,width() - 1,height() - 1,z1,spectrum() - 1); - } - - //! Return specified range of image slices \inplace. - CImg& slices(const int z0, const int z1) { - return get_slices(z0,z1).move_to(*this); - } - - //! Return specified image channel. - /** - \param c0 Image channel. - **/ - CImg get_channel(const int c0) const { - return get_channels(c0,c0); - } - - //! Return specified image channel \inplace. - CImg& channel(const int c0) { - return channels(c0,c0); - } - - //! Return specified range of image channels. - /** - \param c0 Starting image channel. - \param c1 Ending image channel. - **/ - CImg get_channels(const int c0, const int c1) const { - return get_crop(0,0,0,c0,width() - 1,height() - 1,depth() - 1,c1); - } - - //! Return specified range of image channels \inplace. - CImg& channels(const int c0, const int c1) { - return get_channels(c0,c1).move_to(*this); - } - - //! Return stream line of a 2d or 3d vector field. - CImg get_streamline(const float x, const float y, const float z, - const float L=256, const float dl=0.1f, - const unsigned int interpolation_type=2, const bool is_backward_tracking=false, - const bool is_oriented_only=false) const { - if (_spectrum!=2 && _spectrum!=3) - throw CImgInstanceException(_cimg_instance - "streamline(): Instance is not a 2d or 3d vector field.", - cimg_instance); - if (_spectrum==2) { - if (is_oriented_only) { - typename CImg::_functor4d_streamline2d_oriented func(*this); - return streamline(func,x,y,z,L,dl,interpolation_type,is_backward_tracking,true, - 0,0,0,_width - 1.0f,_height - 1.0f,0.0f); - } else { - typename CImg::_functor4d_streamline2d_directed func(*this); - return streamline(func,x,y,z,L,dl,interpolation_type,is_backward_tracking,false, - 0,0,0,_width - 1.0f,_height - 1.0f,0.0f); - } - } - if (is_oriented_only) { - typename CImg::_functor4d_streamline3d_oriented func(*this); - return streamline(func,x,y,z,L,dl,interpolation_type,is_backward_tracking,true, - 0,0,0,_width - 1.0f,_height - 1.0f,_depth - 1.0f); - } - typename CImg::_functor4d_streamline3d_directed func(*this); - return streamline(func,x,y,z,L,dl,interpolation_type,is_backward_tracking,false, - 0,0,0,_width - 1.0f,_height - 1.0f,_depth - 1.0f); - } - - //! Return stream line of a 3d vector field. - /** - \param func Vector field function. - \param x X-coordinate of the starting point of the streamline. - \param y Y-coordinate of the starting point of the streamline. - \param z Z-coordinate of the starting point of the streamline. - \param L Streamline length. - \param dl Streamline length increment. - \param interpolation_type Type of interpolation. - Can be { 0=nearest int | 1=linear | 2=2nd-order RK | 3=4th-order RK. }. - \param is_backward_tracking Tells if the streamline is estimated forward or backward. - \param is_oriented_only Tells if the direction of the vectors must be ignored. - \param x0 X-coordinate of the first bounding-box vertex. - \param y0 Y-coordinate of the first bounding-box vertex. - \param z0 Z-coordinate of the first bounding-box vertex. - \param x1 X-coordinate of the second bounding-box vertex. - \param y1 Y-coordinate of the second bounding-box vertex. - \param z1 Z-coordinate of the second bounding-box vertex. - **/ - template - static CImg streamline(const tfunc& func, - const float x, const float y, const float z, - const float L=256, const float dl=0.1f, - const unsigned int interpolation_type=2, const bool is_backward_tracking=false, - const bool is_oriented_only=false, - const float x0=0, const float y0=0, const float z0=0, - const float x1=0, const float y1=0, const float z1=0) { - if (dl<=0) - throw CImgArgumentException("CImg<%s>::streamline(): Invalid specified integration length %g " - "(should be >0).", - pixel_type(), - dl); - - const bool is_bounded = (x0!=x1 || y0!=y1 || z0!=z1); - if (L<=0 || (is_bounded && (xx1 || yy1 || zz1))) return CImg(); - const unsigned int size_L = (unsigned int)cimg::round(L/dl + 1); - CImg coordinates(size_L,3); - const float dl2 = dl/2; - float - *ptr_x = coordinates.data(0,0), - *ptr_y = coordinates.data(0,1), - *ptr_z = coordinates.data(0,2), - pu = (float)(dl*func(x,y,z,0)), - pv = (float)(dl*func(x,y,z,1)), - pw = (float)(dl*func(x,y,z,2)), - X = x, Y = y, Z = z; - - switch (interpolation_type) { - case 0 : { // Nearest integer interpolation. - cimg_forX(coordinates,l) { - *(ptr_x++) = X; *(ptr_y++) = Y; *(ptr_z++) = Z; - const int - xi = (int)(X>0?X + 0.5f:X - 0.5f), - yi = (int)(Y>0?Y + 0.5f:Y - 0.5f), - zi = (int)(Z>0?Z + 0.5f:Z - 0.5f); - float - u = (float)(dl*func((float)xi,(float)yi,(float)zi,0)), - v = (float)(dl*func((float)xi,(float)yi,(float)zi,1)), - w = (float)(dl*func((float)xi,(float)yi,(float)zi,2)); - if (is_oriented_only && u*pu + v*pv + w*pw<0) { u = -u; v = -v; w = -w; } - if (is_backward_tracking) { X-=(pu=u); Y-=(pv=v); Z-=(pw=w); } else { X+=(pu=u); Y+=(pv=v); Z+=(pw=w); } - if (is_bounded && (Xx1 || Yy1 || Zz1)) break; - } - } break; - case 1 : { // First-order interpolation. - cimg_forX(coordinates,l) { - *(ptr_x++) = X; *(ptr_y++) = Y; *(ptr_z++) = Z; - float - u = (float)(dl*func(X,Y,Z,0)), - v = (float)(dl*func(X,Y,Z,1)), - w = (float)(dl*func(X,Y,Z,2)); - if (is_oriented_only && u*pu + v*pv + w*pw<0) { u = -u; v = -v; w = -w; } - if (is_backward_tracking) { X-=(pu=u); Y-=(pv=v); Z-=(pw=w); } else { X+=(pu=u); Y+=(pv=v); Z+=(pw=w); } - if (is_bounded && (Xx1 || Yy1 || Zz1)) break; - } - } break; - case 2 : { // Second order interpolation. - cimg_forX(coordinates,l) { - *(ptr_x++) = X; *(ptr_y++) = Y; *(ptr_z++) = Z; - float - u0 = (float)(dl2*func(X,Y,Z,0)), - v0 = (float)(dl2*func(X,Y,Z,1)), - w0 = (float)(dl2*func(X,Y,Z,2)); - if (is_oriented_only && u0*pu + v0*pv + w0*pw<0) { u0 = -u0; v0 = -v0; w0 = -w0; } - float - u = (float)(dl*func(X + u0,Y + v0,Z + w0,0)), - v = (float)(dl*func(X + u0,Y + v0,Z + w0,1)), - w = (float)(dl*func(X + u0,Y + v0,Z + w0,2)); - if (is_oriented_only && u*pu + v*pv + w*pw<0) { u = -u; v = -v; w = -w; } - if (is_backward_tracking) { X-=(pu=u); Y-=(pv=v); Z-=(pw=w); } else { X+=(pu=u); Y+=(pv=v); Z+=(pw=w); } - if (is_bounded && (Xx1 || Yy1 || Zz1)) break; - } - } break; - default : { // Fourth order interpolation. - cimg_forX(coordinates,x) { - *(ptr_x++) = X; *(ptr_y++) = Y; *(ptr_z++) = Z; - float - u0 = (float)(dl2*func(X,Y,Z,0)), - v0 = (float)(dl2*func(X,Y,Z,1)), - w0 = (float)(dl2*func(X,Y,Z,2)); - if (is_oriented_only && u0*pu + v0*pv + w0*pw<0) { u0 = -u0; v0 = -v0; w0 = -w0; } - float - u1 = (float)(dl2*func(X + u0,Y + v0,Z + w0,0)), - v1 = (float)(dl2*func(X + u0,Y + v0,Z + w0,1)), - w1 = (float)(dl2*func(X + u0,Y + v0,Z + w0,2)); - if (is_oriented_only && u1*pu + v1*pv + w1*pw<0) { u1 = -u1; v1 = -v1; w1 = -w1; } - float - u2 = (float)(dl2*func(X + u1,Y + v1,Z + w1,0)), - v2 = (float)(dl2*func(X + u1,Y + v1,Z + w1,1)), - w2 = (float)(dl2*func(X + u1,Y + v1,Z + w1,2)); - if (is_oriented_only && u2*pu + v2*pv + w2*pw<0) { u2 = -u2; v2 = -v2; w2 = -w2; } - float - u3 = (float)(dl2*func(X + u2,Y + v2,Z + w2,0)), - v3 = (float)(dl2*func(X + u2,Y + v2,Z + w2,1)), - w3 = (float)(dl2*func(X + u2,Y + v2,Z + w2,2)); - if (is_oriented_only && u2*pu + v2*pv + w2*pw<0) { u3 = -u3; v3 = -v3; w3 = -w3; } - const float - u = (u0 + u3)/3 + (u1 + u2)/1.5f, - v = (v0 + v3)/3 + (v1 + v2)/1.5f, - w = (w0 + w3)/3 + (w1 + w2)/1.5f; - if (is_backward_tracking) { X-=(pu=u); Y-=(pv=v); Z-=(pw=w); } else { X+=(pu=u); Y+=(pv=v); Z+=(pw=w); } - if (is_bounded && (Xx1 || Yy1 || Zz1)) break; - } - } - } - if (ptr_x!=coordinates.data(0,1)) coordinates.resize((int)(ptr_x-coordinates.data()),3,1,1,0); - return coordinates; - } - - //! Return stream line of a 3d vector field \overloading. - static CImg streamline(const char *const expression, - const float x, const float y, const float z, - const float L=256, const float dl=0.1f, - const unsigned int interpolation_type=2, const bool is_backward_tracking=true, - const bool is_oriented_only=false, - const float x0=0, const float y0=0, const float z0=0, - const float x1=0, const float y1=0, const float z1=0) { - _functor4d_streamline_expr func(expression); - return streamline(func,x,y,z,L,dl,interpolation_type,is_backward_tracking,is_oriented_only,x0,y0,z0,x1,y1,z1); - } - - struct _functor4d_streamline2d_directed { - const CImg& ref; - _functor4d_streamline2d_directed(const CImg& pref):ref(pref) {} - float operator()(const float x, const float y, const float z, const unsigned int c) const { - return c<2?(float)ref._linear_atXY(x,y,(int)z,c):0; - } - }; - - struct _functor4d_streamline3d_directed { - const CImg& ref; - _functor4d_streamline3d_directed(const CImg& pref):ref(pref) {} - float operator()(const float x, const float y, const float z, const unsigned int c) const { - return (float)ref._linear_atXYZ(x,y,z,c); - } - }; - - struct _functor4d_streamline2d_oriented { - const CImg& ref; - CImg *pI; - _functor4d_streamline2d_oriented(const CImg& pref):ref(pref),pI(0) { pI = new CImg(2,2,1,2); } - ~_functor4d_streamline2d_oriented() { delete pI; } - float operator()(const float x, const float y, const float z, const unsigned int c) const { -#define _cimg_vecalign2d(i,j) \ - if (I(i,j,0)*I(0,0,0) + I(i,j,1)*I(0,0,1)<0) { I(i,j,0) = -I(i,j,0); I(i,j,1) = -I(i,j,1); } - int - xi = (int)x - (x>=0?0:1), nxi = xi + 1, - yi = (int)y - (y>=0?0:1), nyi = yi + 1, - zi = (int)z; - const float - dx = x - xi, - dy = y - yi; - if (c==0) { - CImg& I = *pI; - if (xi<0) xi = 0; if (nxi<0) nxi = 0; - if (xi>=ref.width()) xi = ref.width() - 1; if (nxi>=ref.width()) nxi = ref.width() - 1; - if (yi<0) yi = 0; if (nyi<0) nyi = 0; - if (yi>=ref.height()) yi = ref.height() - 1; if (nyi>=ref.height()) nyi = ref.height() - 1; - I(0,0,0) = (float)ref(xi,yi,zi,0); I(0,0,1) = (float)ref(xi,yi,zi,1); - I(1,0,0) = (float)ref(nxi,yi,zi,0); I(1,0,1) = (float)ref(nxi,yi,zi,1); - I(1,1,0) = (float)ref(nxi,nyi,zi,0); I(1,1,1) = (float)ref(nxi,nyi,zi,1); - I(0,1,0) = (float)ref(xi,nyi,zi,0); I(0,1,1) = (float)ref(xi,nyi,zi,1); - _cimg_vecalign2d(1,0); _cimg_vecalign2d(1,1); _cimg_vecalign2d(0,1); - } - return c<2?(float)pI->_linear_atXY(dx,dy,0,c):0; - } - }; - - struct _functor4d_streamline3d_oriented { - const CImg& ref; - CImg *pI; - _functor4d_streamline3d_oriented(const CImg& pref):ref(pref),pI(0) { pI = new CImg(2,2,2,3); } - ~_functor4d_streamline3d_oriented() { delete pI; } - float operator()(const float x, const float y, const float z, const unsigned int c) const { -#define _cimg_vecalign3d(i,j,k) if (I(i,j,k,0)*I(0,0,0,0) + I(i,j,k,1)*I(0,0,0,1) + I(i,j,k,2)*I(0,0,0,2)<0) { \ - I(i,j,k,0) = -I(i,j,k,0); I(i,j,k,1) = -I(i,j,k,1); I(i,j,k,2) = -I(i,j,k,2); } - int - xi = (int)x - (x>=0?0:1), nxi = xi + 1, - yi = (int)y - (y>=0?0:1), nyi = yi + 1, - zi = (int)z - (z>=0?0:1), nzi = zi + 1; - const float - dx = x - xi, - dy = y - yi, - dz = z - zi; - if (c==0) { - CImg& I = *pI; - if (xi<0) xi = 0; if (nxi<0) nxi = 0; - if (xi>=ref.width()) xi = ref.width() - 1; if (nxi>=ref.width()) nxi = ref.width() - 1; - if (yi<0) yi = 0; if (nyi<0) nyi = 0; - if (yi>=ref.height()) yi = ref.height() - 1; if (nyi>=ref.height()) nyi = ref.height() - 1; - if (zi<0) zi = 0; if (nzi<0) nzi = 0; - if (zi>=ref.depth()) zi = ref.depth() - 1; if (nzi>=ref.depth()) nzi = ref.depth() - 1; - I(0,0,0,0) = (float)ref(xi,yi,zi,0); I(0,0,0,1) = (float)ref(xi,yi,zi,1); - I(0,0,0,2) = (float)ref(xi,yi,zi,2); I(1,0,0,0) = (float)ref(nxi,yi,zi,0); - I(1,0,0,1) = (float)ref(nxi,yi,zi,1); I(1,0,0,2) = (float)ref(nxi,yi,zi,2); - I(1,1,0,0) = (float)ref(nxi,nyi,zi,0); I(1,1,0,1) = (float)ref(nxi,nyi,zi,1); - I(1,1,0,2) = (float)ref(nxi,nyi,zi,2); I(0,1,0,0) = (float)ref(xi,nyi,zi,0); - I(0,1,0,1) = (float)ref(xi,nyi,zi,1); I(0,1,0,2) = (float)ref(xi,nyi,zi,2); - I(0,0,1,0) = (float)ref(xi,yi,nzi,0); I(0,0,1,1) = (float)ref(xi,yi,nzi,1); - I(0,0,1,2) = (float)ref(xi,yi,nzi,2); I(1,0,1,0) = (float)ref(nxi,yi,nzi,0); - I(1,0,1,1) = (float)ref(nxi,yi,nzi,1); I(1,0,1,2) = (float)ref(nxi,yi,nzi,2); - I(1,1,1,0) = (float)ref(nxi,nyi,nzi,0); I(1,1,1,1) = (float)ref(nxi,nyi,nzi,1); - I(1,1,1,2) = (float)ref(nxi,nyi,nzi,2); I(0,1,1,0) = (float)ref(xi,nyi,nzi,0); - I(0,1,1,1) = (float)ref(xi,nyi,nzi,1); I(0,1,1,2) = (float)ref(xi,nyi,nzi,2); - _cimg_vecalign3d(1,0,0); _cimg_vecalign3d(1,1,0); _cimg_vecalign3d(0,1,0); - _cimg_vecalign3d(0,0,1); _cimg_vecalign3d(1,0,1); _cimg_vecalign3d(1,1,1); _cimg_vecalign3d(0,1,1); - } - return (float)pI->_linear_atXYZ(dx,dy,dz,c); - } - }; - - struct _functor4d_streamline_expr { - _cimg_math_parser *mp; - ~_functor4d_streamline_expr() { delete mp; } - _functor4d_streamline_expr(const char *const expr):mp(0) { - mp = new _cimg_math_parser(expr,"streamline",CImg::const_empty(),0); - } - float operator()(const float x, const float y, const float z, const unsigned int c) const { - return (float)(*mp)(x,y,z,c); - } - }; - - //! Return a shared-memory image referencing a range of pixels of the image instance. - /** - \param x0 X-coordinate of the starting pixel. - \param x1 X-coordinate of the ending pixel. - \param y0 Y-coordinate. - \param z0 Z-coordinate. - \param c0 C-coordinate. - **/ - CImg get_shared_points(const unsigned int x0, const unsigned int x1, - const unsigned int y0=0, const unsigned int z0=0, const unsigned int c0=0) { - const unsigned int - beg = (unsigned int)offset(x0,y0,z0,c0), - end = (unsigned int)offset(x1,y0,z0,c0); - if (beg>end || beg>=size() || end>=size()) - throw CImgArgumentException(_cimg_instance - "get_shared_points(): Invalid request of a shared-memory subset (%u->%u,%u,%u,%u).", - cimg_instance, - x0,x1,y0,z0,c0); - - return CImg(_data + beg,x1 - x0 + 1,1,1,1,true); - } - - //! Return a shared-memory image referencing a range of pixels of the image instance \const. - const CImg get_shared_points(const unsigned int x0, const unsigned int x1, - const unsigned int y0=0, const unsigned int z0=0, const unsigned int c0=0) const { - const unsigned int - beg = (unsigned int)offset(x0,y0,z0,c0), - end = (unsigned int)offset(x1,y0,z0,c0); - if (beg>end || beg>=size() || end>=size()) - throw CImgArgumentException(_cimg_instance - "get_shared_points(): Invalid request of a shared-memory subset (%u->%u,%u,%u,%u).", - cimg_instance, - x0,x1,y0,z0,c0); - - return CImg(_data + beg,x1 - x0 + 1,1,1,1,true); - } - - //! Return a shared-memory image referencing a range of rows of the image instance. - /** - \param y0 Y-coordinate of the starting row. - \param y1 Y-coordinate of the ending row. - \param z0 Z-coordinate. - \param c0 C-coordinate. - **/ - CImg get_shared_rows(const unsigned int y0, const unsigned int y1, - const unsigned int z0=0, const unsigned int c0=0) { - const unsigned int - beg = (unsigned int)offset(0,y0,z0,c0), - end = (unsigned int)offset(0,y1,z0,c0); - if (beg>end || beg>=size() || end>=size()) - throw CImgArgumentException(_cimg_instance - "get_shared_rows(): Invalid request of a shared-memory subset " - "(0->%u,%u->%u,%u,%u).", - cimg_instance, - _width - 1,y0,y1,z0,c0); - - return CImg(_data + beg,_width,y1 - y0 + 1,1,1,true); - } - - //! Return a shared-memory image referencing a range of rows of the image instance \const. - const CImg get_shared_rows(const unsigned int y0, const unsigned int y1, - const unsigned int z0=0, const unsigned int c0=0) const { - const unsigned int - beg = (unsigned int)offset(0,y0,z0,c0), - end = (unsigned int)offset(0,y1,z0,c0); - if (beg>end || beg>=size() || end>=size()) - throw CImgArgumentException(_cimg_instance - "get_shared_rows(): Invalid request of a shared-memory subset " - "(0->%u,%u->%u,%u,%u).", - cimg_instance, - _width - 1,y0,y1,z0,c0); - - return CImg(_data + beg,_width,y1 - y0 + 1,1,1,true); - } - - //! Return a shared-memory image referencing one row of the image instance. - /** - \param y0 Y-coordinate. - \param z0 Z-coordinate. - \param c0 C-coordinate. - **/ - CImg get_shared_row(const unsigned int y0, const unsigned int z0=0, const unsigned int c0=0) { - return get_shared_rows(y0,y0,z0,c0); - } - - //! Return a shared-memory image referencing one row of the image instance \const. - const CImg get_shared_row(const unsigned int y0, const unsigned int z0=0, const unsigned int c0=0) const { - return get_shared_rows(y0,y0,z0,c0); - } - - //! Return a shared memory image referencing a range of slices of the image instance. - /** - \param z0 Z-coordinate of the starting slice. - \param z1 Z-coordinate of the ending slice. - \param c0 C-coordinate. - **/ - CImg get_shared_slices(const unsigned int z0, const unsigned int z1, const unsigned int c0=0) { - const unsigned int - beg = (unsigned int)offset(0,0,z0,c0), - end = (unsigned int)offset(0,0,z1,c0); - if (beg>end || beg>=size() || end>=size()) - throw CImgArgumentException(_cimg_instance - "get_shared_slices(): Invalid request of a shared-memory subset " - "(0->%u,0->%u,%u->%u,%u).", - cimg_instance, - _width - 1,_height - 1,z0,z1,c0); - - return CImg(_data + beg,_width,_height,z1 - z0 + 1,1,true); - } - - //! Return a shared memory image referencing a range of slices of the image instance \const. - const CImg get_shared_slices(const unsigned int z0, const unsigned int z1, const unsigned int c0=0) const { - const unsigned int - beg = (unsigned int)offset(0,0,z0,c0), - end = (unsigned int)offset(0,0,z1,c0); - if (beg>end || beg>=size() || end>=size()) - throw CImgArgumentException(_cimg_instance - "get_shared_slices(): Invalid request of a shared-memory subset " - "(0->%u,0->%u,%u->%u,%u).", - cimg_instance, - _width - 1,_height - 1,z0,z1,c0); - - return CImg(_data + beg,_width,_height,z1 - z0 + 1,1,true); - } - - //! Return a shared-memory image referencing one slice of the image instance. - /** - \param z0 Z-coordinate. - \param c0 C-coordinate. - **/ - CImg get_shared_slice(const unsigned int z0, const unsigned int c0=0) { - return get_shared_slices(z0,z0,c0); - } - - //! Return a shared-memory image referencing one slice of the image instance \const. - const CImg get_shared_slice(const unsigned int z0, const unsigned int c0=0) const { - return get_shared_slices(z0,z0,c0); - } - - //! Return a shared-memory image referencing a range of channels of the image instance. - /** - \param c0 C-coordinate of the starting channel. - \param c1 C-coordinate of the ending channel. - **/ - CImg get_shared_channels(const unsigned int c0, const unsigned int c1) { - const unsigned int - beg = (unsigned int)offset(0,0,0,c0), - end = (unsigned int)offset(0,0,0,c1); - if (beg>end || beg>=size() || end>=size()) - throw CImgArgumentException(_cimg_instance - "get_shared_channels(): Invalid request of a shared-memory subset " - "(0->%u,0->%u,0->%u,%u->%u).", - cimg_instance, - _width - 1,_height - 1,_depth - 1,c0,c1); - - return CImg(_data + beg,_width,_height,_depth,c1 - c0 + 1,true); - } - - //! Return a shared-memory image referencing a range of channels of the image instance \const. - const CImg get_shared_channels(const unsigned int c0, const unsigned int c1) const { - const unsigned int - beg = (unsigned int)offset(0,0,0,c0), - end = (unsigned int)offset(0,0,0,c1); - if (beg>end || beg>=size() || end>=size()) - throw CImgArgumentException(_cimg_instance - "get_shared_channels(): Invalid request of a shared-memory subset " - "(0->%u,0->%u,0->%u,%u->%u).", - cimg_instance, - _width - 1,_height - 1,_depth - 1,c0,c1); - - return CImg(_data + beg,_width,_height,_depth,c1 - c0 + 1,true); - } - - //! Return a shared-memory image referencing one channel of the image instance. - /** - \param c0 C-coordinate. - **/ - CImg get_shared_channel(const unsigned int c0) { - return get_shared_channels(c0,c0); - } - - //! Return a shared-memory image referencing one channel of the image instance \const. - const CImg get_shared_channel(const unsigned int c0) const { - return get_shared_channels(c0,c0); - } - - //! Return a shared-memory version of the image instance. - CImg get_shared() { - return CImg(_data,_width,_height,_depth,_spectrum,true); - } - - //! Return a shared-memory version of the image instance \const. - const CImg get_shared() const { - return CImg(_data,_width,_height,_depth,_spectrum,true); - } - - //! Split image into a list along specified axis. - /** - \param axis Splitting axis. Can be { 'x' | 'y' | 'z' | 'c' }. - \param nb Number of splitted parts. - \note - - If \c nb==0, instance image is splitted into blocs of egal values along the specified axis. - - If \c nb<=0, instance image is splitted into blocs of -\c nb pixel wide. - - If \c nb>0, instance image is splitted into \c nb blocs. - **/ - CImgList get_split(const char axis, const int nb=-1) const { - CImgList res; - if (is_empty()) return res; - const char _axis = cimg::lowercase(axis); - - if (nb<0) { // Split by bloc size. - const unsigned int dp = (unsigned int)(nb?-nb:1); - switch (_axis) { - case 'x': { - if (_width>dp) { - res.assign(_width/dp + (_width%dp?1:0),1,1); - const unsigned int pe = _width - dp; - cimg_pragma_openmp(parallel for cimg_openmp_if(res._width>=128 && _height*_depth*_spectrum>=128)) - for (unsigned int p = 0; pdp) { - res.assign(_height/dp + (_height%dp?1:0),1,1); - const unsigned int pe = _height - dp; - cimg_pragma_openmp(parallel for cimg_openmp_if(res._width>=128 && _width*_depth*_spectrum>=128)) - for (unsigned int p = 0; pdp) { - res.assign(_depth/dp + (_depth%dp?1:0),1,1); - const unsigned int pe = _depth - dp; - cimg_pragma_openmp(parallel for cimg_openmp_if(res._width>=128 && _width*_height*_spectrum>=128)) - for (unsigned int p = 0; pdp) { - res.assign(_spectrum/dp + (_spectrum%dp?1:0),1,1); - const unsigned int pe = _spectrum - dp; - cimg_pragma_openmp(parallel for cimg_openmp_if(res._width>=128 && _width*_height*_depth>=128)) - for (unsigned int p = 0; p0) { // Split by number of (non-homogeneous) blocs. - const unsigned int siz = _axis=='x'?_width:_axis=='y'?_height:_axis=='z'?_depth:_axis=='c'?_spectrum:0; - if ((unsigned int)nb>siz) - throw CImgArgumentException(_cimg_instance - "get_split(): Instance cannot be split along %c-axis into %u blocs.", - cimg_instance, - axis,nb); - if (nb==1) res.assign(*this); - else { - int err = (int)siz; - unsigned int _p = 0; - switch (_axis) { - case 'x' : { - cimg_forX(*this,p) if ((err-=nb)<=0) { - get_crop(_p,0,0,0,p,_height - 1,_depth - 1,_spectrum - 1).move_to(res); - err+=(int)siz; - _p = p + 1U; - } - } break; - case 'y' : { - cimg_forY(*this,p) if ((err-=nb)<=0) { - get_crop(0,_p,0,0,_width - 1,p,_depth - 1,_spectrum - 1).move_to(res); - err+=(int)siz; - _p = p + 1U; - } - } break; - case 'z' : { - cimg_forZ(*this,p) if ((err-=nb)<=0) { - get_crop(0,0,_p,0,_width - 1,_height - 1,p,_spectrum - 1).move_to(res); - err+=(int)siz; - _p = p + 1U; - } - } break; - case 'c' : { - cimg_forC(*this,p) if ((err-=nb)<=0) { - get_crop(0,0,0,_p,_width - 1,_height - 1,_depth - 1,p).move_to(res); - err+=(int)siz; - _p = p + 1U; - } - } - } - } - } else { // Split by egal values according to specified axis. - T current = *_data; - switch (_axis) { - case 'x' : { - int i0 = 0; - cimg_forX(*this,i) - if ((*this)(i)!=current) { get_columns(i0,i - 1).move_to(res); i0 = i; current = (*this)(i); } - get_columns(i0,width() - 1).move_to(res); - } break; - case 'y' : { - int i0 = 0; - cimg_forY(*this,i) - if ((*this)(0,i)!=current) { get_rows(i0,i - 1).move_to(res); i0 = i; current = (*this)(0,i); } - get_rows(i0,height() - 1).move_to(res); - } break; - case 'z' : { - int i0 = 0; - cimg_forZ(*this,i) - if ((*this)(0,0,i)!=current) { get_slices(i0,i - 1).move_to(res); i0 = i; current = (*this)(0,0,i); } - get_slices(i0,depth() - 1).move_to(res); - } break; - case 'c' : { - int i0 = 0; - cimg_forC(*this,i) - if ((*this)(0,0,0,i)!=current) { get_channels(i0,i - 1).move_to(res); i0 = i; current = (*this)(0,0,0,i); } - get_channels(i0,spectrum() - 1).move_to(res); - } break; - default : { - longT i0 = 0; - cimg_foroff(*this,i) - if ((*this)[i]!=current) { - CImg(_data + i0,1,(unsigned int)(i - i0)).move_to(res); - i0 = (longT)i; current = (*this)[i]; - } - CImg(_data + i0,1,(unsigned int)(size() - i0)).move_to(res); - } - } - } - return res; - } - - //! Split image into a list of sub-images, according to a specified splitting value sequence and optionnally axis. - /** - \param values Splitting value sequence. - \param axis Axis along which the splitting is performed. Can be '0' to ignore axis. - \param keep_values Tells if the splitting sequence must be kept in the splitted blocs. - **/ - template - CImgList get_split(const CImg& values, const char axis=0, const bool keep_values=true) const { - CImgList res; - if (is_empty()) return res; - const ulongT vsiz = values.size(); - const char _axis = cimg::lowercase(axis); - if (!vsiz) return CImgList(*this); - if (vsiz==1) { // Split according to a single value. - const T value = *values; - switch (_axis) { - case 'x' : { - unsigned int i0 = 0, i = 0; - do { - while (i<_width && (*this)(i)==value) ++i; - if (i>i0) { if (keep_values) get_columns(i0,i - 1).move_to(res); i0 = i; } - while (i<_width && (*this)(i)!=value) ++i; - if (i>i0) { get_columns(i0,i - 1).move_to(res); i0 = i; } - } while (i<_width); - } break; - case 'y' : { - unsigned int i0 = 0, i = 0; - do { - while (i<_height && (*this)(0,i)==value) ++i; - if (i>i0) { if (keep_values) get_rows(i0,i - 1).move_to(res); i0 = i; } - while (i<_height && (*this)(0,i)!=value) ++i; - if (i>i0) { get_rows(i0,i - 1).move_to(res); i0 = i; } - } while (i<_height); - } break; - case 'z' : { - unsigned int i0 = 0, i = 0; - do { - while (i<_depth && (*this)(0,0,i)==value) ++i; - if (i>i0) { if (keep_values) get_slices(i0,i - 1).move_to(res); i0 = i; } - while (i<_depth && (*this)(0,0,i)!=value) ++i; - if (i>i0) { get_slices(i0,i - 1).move_to(res); i0 = i; } - } while (i<_depth); - } break; - case 'c' : { - unsigned int i0 = 0, i = 0; - do { - while (i<_spectrum && (*this)(0,0,0,i)==value) ++i; - if (i>i0) { if (keep_values) get_channels(i0,i - 1).move_to(res); i0 = i; } - while (i<_spectrum && (*this)(0,0,0,i)!=value) ++i; - if (i>i0) { get_channels(i0,i - 1).move_to(res); i0 = i; } - } while (i<_spectrum); - } break; - default : { - const ulongT siz = size(); - ulongT i0 = 0, i = 0; - do { - while (ii0) { if (keep_values) CImg(_data + i0,1,(unsigned int)(i - i0)).move_to(res); i0 = i; } - while (ii0) { CImg(_data + i0,1,(unsigned int)(i - i0)).move_to(res); i0 = i; } - } while (i=vsiz) j = 0; } - i-=j; - if (i>i1) { - if (i1>i0) get_columns(i0,i1 - 1).move_to(res); - if (keep_values) get_columns(i1,i - 1).move_to(res); - i0 = i; - } else ++i; - } else ++i; - } while (i<_width); - if (i0<_width) get_columns(i0,width() - 1).move_to(res); - } break; - case 'y' : { - unsigned int i0 = 0, i1 = 0, i = 0; - do { - if ((*this)(0,i)==*values) { - i1 = i; j = 0; - while (i<_height && (*this)(0,i)==values[j]) { ++i; if (++j>=vsiz) j = 0; } - i-=j; - if (i>i1) { - if (i1>i0) get_rows(i0,i1 - 1).move_to(res); - if (keep_values) get_rows(i1,i - 1).move_to(res); - i0 = i; - } else ++i; - } else ++i; - } while (i<_height); - if (i0<_height) get_rows(i0,height() - 1).move_to(res); - } break; - case 'z' : { - unsigned int i0 = 0, i1 = 0, i = 0; - do { - if ((*this)(0,0,i)==*values) { - i1 = i; j = 0; - while (i<_depth && (*this)(0,0,i)==values[j]) { ++i; if (++j>=vsiz) j = 0; } - i-=j; - if (i>i1) { - if (i1>i0) get_slices(i0,i1 - 1).move_to(res); - if (keep_values) get_slices(i1,i - 1).move_to(res); - i0 = i; - } else ++i; - } else ++i; - } while (i<_depth); - if (i0<_depth) get_slices(i0,depth() - 1).move_to(res); - } break; - case 'c' : { - unsigned int i0 = 0, i1 = 0, i = 0; - do { - if ((*this)(0,0,0,i)==*values) { - i1 = i; j = 0; - while (i<_spectrum && (*this)(0,0,0,i)==values[j]) { ++i; if (++j>=vsiz) j = 0; } - i-=j; - if (i>i1) { - if (i1>i0) get_channels(i0,i1 - 1).move_to(res); - if (keep_values) get_channels(i1,i - 1).move_to(res); - i0 = i; - } else ++i; - } else ++i; - } while (i<_spectrum); - if (i0<_spectrum) get_channels(i0,spectrum() - 1).move_to(res); - } break; - default : { - ulongT i0 = 0, i1 = 0, i = 0; - const ulongT siz = size(); - do { - if ((*this)[i]==*values) { - i1 = i; j = 0; - while (i=vsiz) j = 0; } - i-=j; - if (i>i1) { - if (i1>i0) CImg(_data + i0,1,(unsigned int)(i1 - i0)).move_to(res); - if (keep_values) CImg(_data + i1,1,(unsigned int)(i - i1)).move_to(res); - i0 = i; - } else ++i; - } else ++i; - } while (i(_data + i0,1,(unsigned int)(siz - i0)).move_to(res); - } break; - } - } - return res; - } - - //! Append two images along specified axis. - /** - \param img Image to append with instance image. - \param axis Appending axis. Can be { 'x' | 'y' | 'z' | 'c' }. - \param align Append alignment in \c [0,1]. - **/ - template - CImg& append(const CImg& img, const char axis='x', const float align=0) { - if (is_empty()) return assign(img,false); - if (!img) return *this; - return CImgList(*this,true).insert(img).get_append(axis,align).move_to(*this); - } - - //! Append two images along specified axis \specialization. - CImg& append(const CImg& img, const char axis='x', const float align=0) { - if (is_empty()) return assign(img,false); - if (!img) return *this; - return CImgList(*this,img,true).get_append(axis,align).move_to(*this); - } - - //! Append two images along specified axis \const. - template - CImg<_cimg_Tt> get_append(const CImg& img, const char axis='x', const float align=0) const { - if (is_empty()) return +img; - if (!img) return +*this; - return CImgList<_cimg_Tt>(*this,true).insert(img).get_append(axis,align); - } - - //! Append two images along specified axis \specialization. - CImg get_append(const CImg& img, const char axis='x', const float align=0) const { - if (is_empty()) return +img; - if (!img) return +*this; - return CImgList(*this,img,true).get_append(axis,align); - } - - //@} - //--------------------------------------- - // - //! \name Filtering / Transforms - //@{ - //--------------------------------------- - - //! Correlate image by a mask. - /** - \param mask = the correlation kernel. - \param boundary_conditions = the border condition type (0=zero, 1=dirichlet) - \param is_normalized = enable local normalization. - \note - - The correlation of the image instance \p *this by the mask \p mask is defined to be: - res(x,y,z) = sum_{i,j,k} (*this)(x + i,y + j,z + k)*mask(i,j,k). - **/ - template - CImg& correlate(const CImg& mask, const unsigned int boundary_conditions=1, const bool is_normalized=false) { - if (is_empty() || !mask) return *this; - return get_correlate(mask,boundary_conditions,is_normalized).move_to(*this); - } - - //! Correlate image by a mask \newinstance. - template - CImg<_cimg_Ttfloat> get_correlate(const CImg& mask, const unsigned int boundary_conditions=1, - const bool is_normalized=false) const { - if (is_empty() || !mask) return *this; - typedef _cimg_Ttfloat Ttfloat; - CImg res(_width,_height,_depth,cimg::max(_spectrum,mask._spectrum)); - cimg_abort_init; - if (boundary_conditions && mask._width==mask._height && - ((mask._depth==1 && mask._width<=5) || (mask._depth==mask._width && mask._width<=3))) { - // A special optimization is done for 2x2, 3x3, 4x4, 5x5, 2x2x2 and 3x3x3 mask (with boundary_conditions=1) - Ttfloat *ptrd = res._data; - CImg I; - switch (mask._depth) { - case 3 : { - I.assign(27); - cimg_forC(res,c) { - cimg_abort_test(); - const CImg _img = get_shared_channel(c%_spectrum); - const CImg _mask = mask.get_shared_channel(c%mask._spectrum); - if (is_normalized) { - const Ttfloat _M = (Ttfloat)_mask.magnitude(2), M = _M*_M; - cimg_for3x3x3(_img,x,y,z,0,I,T) { - const Ttfloat N = M*(I[ 0]*I[ 0] + I[ 1]*I[ 1] + I[ 2]*I[ 2] + - I[ 3]*I[ 3] + I[ 4]*I[ 4] + I[ 5]*I[ 5] + - I[ 6]*I[ 6] + I[ 7]*I[ 7] + I[ 8]*I[ 8] + - I[ 9]*I[ 9] + I[10]*I[10] + I[11]*I[11] + - I[12]*I[12] + I[13]*I[13] + I[14]*I[14] + - I[15]*I[15] + I[16]*I[16] + I[17]*I[17] + - I[18]*I[18] + I[19]*I[19] + I[20]*I[20] + - I[21]*I[21] + I[22]*I[22] + I[23]*I[23] + - I[24]*I[24] + I[25]*I[25] + I[26]*I[26]); - *(ptrd++) = (Ttfloat)(N?(I[ 0]*_mask[ 0] + I[ 1]*_mask[ 1] + I[ 2]*_mask[ 2] + - I[ 3]*_mask[ 3] + I[ 4]*_mask[ 4] + I[ 5]*_mask[ 5] + - I[ 6]*_mask[ 6] + I[ 7]*_mask[ 7] + I[ 8]*_mask[ 8] + - I[ 9]*_mask[ 9] + I[10]*_mask[10] + I[11]*_mask[11] + - I[12]*_mask[12] + I[13]*_mask[13] + I[14]*_mask[14] + - I[15]*_mask[15] + I[16]*_mask[16] + I[17]*_mask[17] + - I[18]*_mask[18] + I[19]*_mask[19] + I[20]*_mask[20] + - I[21]*_mask[21] + I[22]*_mask[22] + I[23]*_mask[23] + - I[24]*_mask[24] + I[25]*_mask[25] + I[26]*_mask[26])/std::sqrt(N):0); - } - } else cimg_for3x3x3(_img,x,y,z,0,I,T) - *(ptrd++) = (Ttfloat)(I[ 0]*_mask[ 0] + I[ 1]*_mask[ 1] + I[ 2]*_mask[ 2] + - I[ 3]*_mask[ 3] + I[ 4]*_mask[ 4] + I[ 5]*_mask[ 5] + - I[ 6]*_mask[ 6] + I[ 7]*_mask[ 7] + I[ 8]*_mask[ 8] + - I[ 9]*_mask[ 9] + I[10]*_mask[10] + I[11]*_mask[11] + - I[12]*_mask[12] + I[13]*_mask[13] + I[14]*_mask[14] + - I[15]*_mask[15] + I[16]*_mask[16] + I[17]*_mask[17] + - I[18]*_mask[18] + I[19]*_mask[19] + I[20]*_mask[20] + - I[21]*_mask[21] + I[22]*_mask[22] + I[23]*_mask[23] + - I[24]*_mask[24] + I[25]*_mask[25] + I[26]*_mask[26]); - } - } break; - case 2 : { - I.assign(8); - cimg_forC(res,c) { - cimg_abort_test(); - const CImg _img = get_shared_channel(c%_spectrum); - const CImg _mask = mask.get_shared_channel(c%mask._spectrum); - if (is_normalized) { - const Ttfloat _M = (Ttfloat)_mask.magnitude(2), M = _M*_M; - cimg_for2x2x2(_img,x,y,z,0,I,T) { - const Ttfloat N = M*(I[0]*I[0] + I[1]*I[1] + - I[2]*I[2] + I[3]*I[3] + - I[4]*I[4] + I[5]*I[5] + - I[6]*I[6] + I[7]*I[7]); - *(ptrd++) = (Ttfloat)(N?(I[0]*_mask[0] + I[1]*_mask[1] + - I[2]*_mask[2] + I[3]*_mask[3] + - I[4]*_mask[4] + I[5]*_mask[5] + - I[6]*_mask[6] + I[7]*_mask[7])/std::sqrt(N):0); - } - } else cimg_for2x2x2(_img,x,y,z,0,I,T) - *(ptrd++) = (Ttfloat)(I[0]*_mask[0] + I[1]*_mask[1] + - I[2]*_mask[2] + I[3]*_mask[3] + - I[4]*_mask[4] + I[5]*_mask[5] + - I[6]*_mask[6] + I[7]*_mask[7]); - } - } break; - default : - case 1 : - switch (mask._width) { - case 6 : { - I.assign(36); - cimg_forC(res,c) { - cimg_abort_test(); - const CImg _img = get_shared_channel(c%_spectrum); - const CImg _mask = mask.get_shared_channel(c%mask._spectrum); - if (is_normalized) { - const Ttfloat _M = (Ttfloat)_mask.magnitude(2), M = _M*_M; - cimg_forZ(_img,z) cimg_for6x6(_img,x,y,z,0,I,T) { - const Ttfloat N = M*(I[ 0]*I[ 0] + I[ 1]*I[ 1] + I[ 2]*I[ 2] + I[ 3]*I[ 3] + I[ 4]*I[ 4] + - I[ 5]*I[ 5] + I[ 6]*I[ 6] + I[ 7]*I[ 7] + I[ 8]*I[ 8] + I[ 9]*I[ 9] + - I[10]*I[10] + I[11]*I[11] + I[12]*I[12] + I[13]*I[13] + I[14]*I[14] + - I[15]*I[15] + I[16]*I[16] + I[17]*I[17] + I[18]*I[18] + I[19]*I[19] + - I[20]*I[20] + I[21]*I[21] + I[22]*I[22] + I[23]*I[23] + I[24]*I[24] + - I[25]*I[25] + I[26]*I[26] + I[27]*I[27] + I[28]*I[28] + I[29]*I[29] + - I[30]*I[30] + I[31]*I[31] + I[32]*I[32] + I[33]*I[33] + I[34]*I[34] + - I[35]*I[35]); - *(ptrd++) = (Ttfloat)(N?(I[ 0]*_mask[ 0] + I[ 1]*_mask[ 1] + I[ 2]*_mask[ 2] + I[ 3]*_mask[ 3] + - I[ 4]*_mask[ 4] + I[ 5]*_mask[ 5] + I[ 6]*_mask[ 6] + I[ 7]*_mask[ 7] + - I[ 8]*_mask[ 8] + I[ 9]*_mask[ 9] + I[10]*_mask[10] + I[11]*_mask[11] + - I[12]*_mask[12] + I[13]*_mask[13] + I[14]*_mask[14] + I[15]*_mask[15] + - I[16]*_mask[16] + I[17]*_mask[17] + I[18]*_mask[18] + I[19]*_mask[19] + - I[20]*_mask[20] + I[21]*_mask[21] + I[22]*_mask[22] + I[23]*_mask[23] + - I[24]*_mask[24] + I[25]*_mask[25] + I[26]*_mask[26] + I[27]*_mask[27] + - I[28]*_mask[28] + I[29]*_mask[29] + I[30]*_mask[30] + I[31]*_mask[31] + - I[32]*_mask[32] + I[33]*_mask[33] + I[34]*_mask[34] + I[35]*_mask[35])/ - std::sqrt(N):0); - } - } else cimg_forZ(_img,z) cimg_for6x6(_img,x,y,z,0,I,T) - *(ptrd++) = (Ttfloat)(I[ 0]*_mask[ 0] + I[ 1]*_mask[ 1] + I[ 2]*_mask[ 2] + I[ 3]*_mask[ 3] + - I[ 4]*_mask[ 4] + I[ 5]*_mask[ 5] + I[ 6]*_mask[ 6] + I[ 7]*_mask[ 7] + - I[ 8]*_mask[ 8] + I[ 9]*_mask[ 9] + I[10]*_mask[10] + I[11]*_mask[11] + - I[12]*_mask[12] + I[13]*_mask[13] + I[14]*_mask[14] + I[15]*_mask[15] + - I[16]*_mask[16] + I[17]*_mask[17] + I[18]*_mask[18] + I[19]*_mask[19] + - I[20]*_mask[20] + I[21]*_mask[21] + I[22]*_mask[22] + I[23]*_mask[23] + - I[24]*_mask[24] + I[25]*_mask[25] + I[26]*_mask[26] + I[27]*_mask[27] + - I[28]*_mask[28] + I[29]*_mask[29] + I[30]*_mask[30] + I[31]*_mask[31] + - I[32]*_mask[32] + I[33]*_mask[33] + I[34]*_mask[34] + I[35]*_mask[35]); - } - } break; - case 5 : { - I.assign(25); - cimg_forC(res,c) { - cimg_abort_test(); - const CImg _img = get_shared_channel(c%_spectrum); - const CImg _mask = mask.get_shared_channel(c%mask._spectrum); - if (is_normalized) { - const Ttfloat _M = (Ttfloat)_mask.magnitude(2), M = _M*_M; - cimg_forZ(_img,z) cimg_for5x5(_img,x,y,z,0,I,T) { - const Ttfloat N = M*(I[ 0]*I[ 0] + I[ 1]*I[ 1] + I[ 2]*I[ 2] + I[ 3]*I[ 3] + I[ 4]*I[ 4] + - I[ 5]*I[ 5] + I[ 6]*I[ 6] + I[ 7]*I[ 7] + I[ 8]*I[ 8] + I[ 9]*I[ 9] + - I[10]*I[10] + I[11]*I[11] + I[12]*I[12] + I[13]*I[13] + I[14]*I[14] + - I[15]*I[15] + I[16]*I[16] + I[17]*I[17] + I[18]*I[18] + I[19]*I[19] + - I[20]*I[20] + I[21]*I[21] + I[22]*I[22] + I[23]*I[23] + I[24]*I[24]); - *(ptrd++) = (Ttfloat)(N?(I[ 0]*_mask[ 0] + I[ 1]*_mask[ 1] + I[ 2]*_mask[ 2] + I[ 3]*_mask[ 3] + - I[ 4]*_mask[ 4] + I[ 5]*_mask[ 5] + I[ 6]*_mask[ 6] + I[ 7]*_mask[ 7] + - I[ 8]*_mask[ 8] + I[ 9]*_mask[ 9] + I[10]*_mask[10] + I[11]*_mask[11] + - I[12]*_mask[12] + I[13]*_mask[13] + I[14]*_mask[14] + I[15]*_mask[15] + - I[16]*_mask[16] + I[17]*_mask[17] + I[18]*_mask[18] + I[19]*_mask[19] + - I[20]*_mask[20] + I[21]*_mask[21] + I[22]*_mask[22] + I[23]*_mask[23] + - I[24]*_mask[24])/std::sqrt(N):0); - } - } else cimg_forZ(_img,z) cimg_for5x5(_img,x,y,z,0,I,T) - *(ptrd++) = (Ttfloat)(I[ 0]*_mask[ 0] + I[ 1]*_mask[ 1] + I[ 2]*_mask[ 2] + I[ 3]*_mask[ 3] + - I[ 4]*_mask[ 4] + I[ 5]*_mask[ 5] + I[ 6]*_mask[ 6] + I[ 7]*_mask[ 7] + - I[ 8]*_mask[ 8] + I[ 9]*_mask[ 9] + I[10]*_mask[10] + I[11]*_mask[11] + - I[12]*_mask[12] + I[13]*_mask[13] + I[14]*_mask[14] + I[15]*_mask[15] + - I[16]*_mask[16] + I[17]*_mask[17] + I[18]*_mask[18] + I[19]*_mask[19] + - I[20]*_mask[20] + I[21]*_mask[21] + I[22]*_mask[22] + I[23]*_mask[23] + - I[24]*_mask[24]); - } - } break; - case 4 : { - I.assign(16); - cimg_forC(res,c) { - cimg_abort_test(); - const CImg _img = get_shared_channel(c%_spectrum); - const CImg _mask = mask.get_shared_channel(c%mask._spectrum); - if (is_normalized) { - const Ttfloat _M = (Ttfloat)_mask.magnitude(2), M = _M*_M; - cimg_forZ(_img,z) cimg_for4x4(_img,x,y,z,0,I,T) { - const Ttfloat N = M*(I[ 0]*I[ 0] + I[ 1]*I[ 1] + I[ 2]*I[ 2] + I[ 3]*I[ 3] + - I[ 4]*I[ 4] + I[ 5]*I[ 5] + I[ 6]*I[ 6] + I[ 7]*I[ 7] + - I[ 8]*I[ 8] + I[ 9]*I[ 9] + I[10]*I[10] + I[11]*I[11] + - I[12]*I[12] + I[13]*I[13] + I[14]*I[14] + I[15]*I[15]); - *(ptrd++) = (Ttfloat)(N?(I[ 0]*_mask[ 0] + I[ 1]*_mask[ 1] + I[ 2]*_mask[ 2] + I[ 3]*_mask[ 3] + - I[ 4]*_mask[ 4] + I[ 5]*_mask[ 5] + I[ 6]*_mask[ 6] + I[ 7]*_mask[ 7] + - I[ 8]*_mask[ 8] + I[ 9]*_mask[ 9] + I[10]*_mask[10] + I[11]*_mask[11] + - I[12]*_mask[12] + I[13]*_mask[13] + I[14]*_mask[14] + I[15]*_mask[15])/ - std::sqrt(N):0); - } - } else cimg_forZ(_img,z) cimg_for4x4(_img,x,y,z,0,I,T) - *(ptrd++) = (Ttfloat)(I[ 0]*_mask[ 0] + I[ 1]*_mask[ 1] + I[ 2]*_mask[ 2] + I[ 3]*_mask[ 3] + - I[ 4]*_mask[ 4] + I[ 5]*_mask[ 5] + I[ 6]*_mask[ 6] + I[ 7]*_mask[ 7] + - I[ 8]*_mask[ 8] + I[ 9]*_mask[ 9] + I[10]*_mask[10] + I[11]*_mask[11] + - I[12]*_mask[12] + I[13]*_mask[13] + I[14]*_mask[14] + I[15]*_mask[15]); - } - } break; - case 3 : { - I.assign(9); - cimg_forC(res,c) { - cimg_abort_test(); - const CImg _img = get_shared_channel(c%_spectrum); - const CImg _mask = mask.get_shared_channel(c%mask._spectrum); - if (is_normalized) { - const Ttfloat _M = (Ttfloat)_mask.magnitude(2), M = _M*_M; - cimg_forZ(_img,z) cimg_for3x3(_img,x,y,z,0,I,T) { - const Ttfloat N = M*(I[0]*I[0] + I[1]*I[1] + I[2]*I[2] + - I[3]*I[3] + I[4]*I[4] + I[5]*I[5] + - I[6]*I[6] + I[7]*I[7] + I[8]*I[8]); - *(ptrd++) = (Ttfloat)(N?(I[0]*_mask[0] + I[1]*_mask[1] + I[2]*_mask[2] + - I[3]*_mask[3] + I[4]*_mask[4] + I[5]*_mask[5] + - I[6]*_mask[6] + I[7]*_mask[7] + I[8]*_mask[8])/std::sqrt(N):0); - } - } else cimg_forZ(_img,z) cimg_for3x3(_img,x,y,z,0,I,T) - *(ptrd++) = (Ttfloat)(I[0]*_mask[0] + I[1]*_mask[1] + I[2]*_mask[2] + - I[3]*_mask[3] + I[4]*_mask[4] + I[5]*_mask[5] + - I[6]*_mask[6] + I[7]*_mask[7] + I[8]*_mask[8]); - } - } break; - case 2 : { - I.assign(4); - cimg_forC(res,c) { - cimg_abort_test(); - const CImg _img = get_shared_channel(c%_spectrum); - const CImg _mask = mask.get_shared_channel(c%mask._spectrum); - if (is_normalized) { - const Ttfloat _M = (Ttfloat)_mask.magnitude(2), M = _M*_M; - cimg_forZ(_img,z) cimg_for2x2(_img,x,y,z,0,I,T) { - const Ttfloat N = M*(I[0]*I[0] + I[1]*I[1] + - I[2]*I[2] + I[3]*I[3]); - *(ptrd++) = (Ttfloat)(N?(I[0]*_mask[0] + I[1]*_mask[1] + - I[2]*_mask[2] + I[3]*_mask[3])/std::sqrt(N):0); - } - } else cimg_forZ(_img,z) cimg_for2x2(_img,x,y,z,0,I,T) - *(ptrd++) = (Ttfloat)(I[0]*_mask[0] + I[1]*_mask[1] + - I[2]*_mask[2] + I[3]*_mask[3]); - } - } break; - case 1 : - if (is_normalized) res.fill(1); - else cimg_forC(res,c) { - cimg_abort_test(); - const CImg _img = get_shared_channel(c%_spectrum); - const CImg _mask = mask.get_shared_channel(c%mask._spectrum); - res.get_shared_channel(c).assign(_img)*=_mask[0]; - } - break; - } - } - } else { // Generic version for other masks and boundary conditions. - const int - mx2 = mask.width()/2, my2 = mask.height()/2, mz2 = mask.depth()/2, - mx1 = mx2 - 1 + (mask.width()%2), my1 = my2 - 1 + (mask.height()%2), mz1 = mz2 - 1 + (mask.depth()%2), - mxe = width() - mx2, mye = height() - my2, mze = depth() - mz2; - cimg_pragma_openmp(parallel for cimg_openmp_if(res._spectrum>=2)) - cimg_forC(res,c) cimg_abort_try { - cimg_abort_test(); - const CImg _img = get_shared_channel(c%_spectrum); - const CImg _mask = mask.get_shared_channel(c%mask._spectrum); - if (is_normalized) { // Normalized correlation. - const Ttfloat _M = (Ttfloat)_mask.magnitude(2), M = _M*_M; - cimg_pragma_openmp(parallel for collapse(3) if (_width*_height*_depth>=32768)) - for (int z = mz1; z=256 && _height*_depth>=128)) - cimg_forYZ(res,y,z) cimg_abort_try2 { - cimg_abort_test2(); - for (int x = 0; x=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { - Ttfloat val = 0, N = 0; - for (int zm = -mz1; zm<=mz2; ++zm) - for (int ym = -my1; ym<=my2; ++ym) - for (int xm = -mx1; xm<=mx2; ++xm) { - const Ttfloat _val = (Ttfloat)_img._atXYZ(x + xm,y + ym,z + zm); - val+=_val*_mask(mx1 + xm,my1 + ym,mz1 + zm); - N+=_val*_val; - } - N*=M; - res(x,y,z,c) = (Ttfloat)(N?val/std::sqrt(N):0); - } - } cimg_abort_catch2() - else - cimg_pragma_openmp(parallel for collapse(2) if (_width>=256 && _height*_depth>=128)) - cimg_forYZ(res,y,z) cimg_abort_try2 { - cimg_abort_test2(); - for (int x = 0; x=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { - Ttfloat val = 0, N = 0; - for (int zm = -mz1; zm<=mz2; ++zm) - for (int ym = -my1; ym<=my2; ++ym) - for (int xm = -mx1; xm<=mx2; ++xm) { - const Ttfloat _val = (Ttfloat)_img.atXYZ(x + xm,y + ym,z + zm,0,0); - val+=_val*_mask(mx1 + xm,my1 + ym,mz1 + zm); - N+=_val*_val; - } - N*=M; - res(x,y,z,c) = (Ttfloat)(N?val/std::sqrt(N):0); - } - } cimg_abort_catch2() - } else { // Classical correlation. - cimg_pragma_openmp(parallel for collapse(3) if (_width*_height*_depth>=32768)) - for (int z = mz1; z=256 && _height*_depth>=128)) - cimg_forYZ(res,y,z) cimg_abort_try2 { - cimg_abort_test2(); - for (int x = 0; x=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { - Ttfloat val = 0; - for (int zm = -mz1; zm<=mz2; ++zm) - for (int ym = -my1; ym<=my2; ++ym) - for (int xm = -mx1; xm<=mx2; ++xm) - val+=_img._atXYZ(x + xm,y + ym,z + zm)*_mask(mx1 + xm,my1 + ym,mz1 + zm); - res(x,y,z,c) = (Ttfloat)val; - } - } cimg_abort_catch2() - else - cimg_pragma_openmp(parallel for collapse(2) if (_width>=256 && _height*_depth>=128)) - cimg_forYZ(res,y,z) cimg_abort_try2 { - cimg_abort_test2(); - for (int x = 0; x=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { - Ttfloat val = 0; - for (int zm = -mz1; zm<=mz2; ++zm) - for (int ym = -my1; ym<=my2; ++ym) - for (int xm = -mx1; xm<=mx2; ++xm) - val+=_img.atXYZ(x + xm,y + ym,z + zm,0,0)*_mask(mx1 + xm,my1 + ym,mz1 + zm); - res(x,y,z,c) = (Ttfloat)val; - } - } cimg_abort_catch2() - } - } cimg_abort_catch() - } - cimg_abort_test(); - return res; - } - - //! Convolve image by a mask. - /** - \param mask = the correlation kernel. - \param boundary_conditions = the border condition type (0=zero, 1=dirichlet) - \param is_normalized = enable local normalization. - \note - - The result \p res of the convolution of an image \p img by a mask \p mask is defined to be: - res(x,y,z) = sum_{i,j,k} img(x-i,y-j,z-k)*mask(i,j,k) - **/ - template - CImg& convolve(const CImg& mask, const unsigned int boundary_conditions=1, const bool is_normalized=false) { - if (is_empty() || !mask) return *this; - return get_convolve(mask,boundary_conditions,is_normalized).move_to(*this); - } - - //! Cumulate image values, optionally along specified axis. - /** - \param axis Cumulation axis. Set it to 0 to cumulate all values globally without taking axes into account. - **/ - CImg& cumulate(const char axis=0) { - switch (cimg::lowercase(axis)) { - case 'x' : - cimg_pragma_openmp(parallel for collapse(3) if (_width>=512 && _height*_depth*_spectrum>=16)) - cimg_forYZC(*this,y,z,c) { - T *ptrd = data(0,y,z,c); - Tlong cumul = 0; - cimg_forX(*this,x) { cumul+=(Tlong)*ptrd; *(ptrd++) = (T)cumul; } - } - break; - case 'y' : { - const ulongT w = (ulongT)_width; - cimg_pragma_openmp(parallel for collapse(3) if (_height>=512 && _width*_depth*_spectrum>=16)) - cimg_forXZC(*this,x,z,c) { - T *ptrd = data(x,0,z,c); - Tlong cumul = 0; - cimg_forY(*this,y) { cumul+=(Tlong)*ptrd; *ptrd = (T)cumul; ptrd+=w; } - } - } break; - case 'z' : { - const ulongT wh = (ulongT)_width*_height; - cimg_pragma_openmp(parallel for collapse(3) if (_depth>=512 && _width*_depth*_spectrum>=16)) - cimg_forXYC(*this,x,y,c) { - T *ptrd = data(x,y,0,c); - Tlong cumul = 0; - cimg_forZ(*this,z) { cumul+=(Tlong)*ptrd; *ptrd = (T)cumul; ptrd+=wh; } - } - } break; - case 'c' : { - const ulongT whd = (ulongT)_width*_height*_depth; - cimg_pragma_openmp(parallel for collapse(3) if (_spectrum>=512 && _width*_height*_depth>=16)) - cimg_forXYZ(*this,x,y,z) { - T *ptrd = data(x,y,z,0); - Tlong cumul = 0; - cimg_forC(*this,c) { cumul+=(Tlong)*ptrd; *ptrd = (T)cumul; ptrd+=whd; } - } - } break; - default : { // Global cumulation. - Tlong cumul = 0; - cimg_for(*this,ptrd,T) { cumul+=(Tlong)*ptrd; *ptrd = (T)cumul; } - } - } - return *this; - } - - //! Cumulate image values, optionally along specified axis \newinstance. - CImg get_cumulate(const char axis=0) const { - return CImg(*this,false).cumulate(axis); - } - - //! Cumulate image values, along specified axes. - /** - \param axes Cumulation axes, as a C-string. - \note \c axes may contains multiple characters, e.g. \c "xyz" - **/ - CImg& cumulate(const char *const axes) { - for (const char *s = axes; *s; ++s) cumulate(*s); - return *this; - } - - //! Cumulate image values, along specified axes \newintance. - CImg get_cumulate(const char *const axes) const { - return CImg(*this,false).cumulate(axes); - } - - //! Convolve image by a mask \newinstance. - template - CImg<_cimg_Ttfloat> get_convolve(const CImg& mask, const unsigned int boundary_conditions=1, - const bool is_normalized=false) const { - if (is_empty() || !mask) return *this; - return get_correlate(CImg(mask._data,mask.size(),1,1,1,true).get_mirror('x'). - resize(mask,-1),boundary_conditions,is_normalized); - } - - //! Erode image by a structuring element. - /** - \param mask Structuring element. - \param boundary_conditions Boundary conditions. - \param is_normalized Tells if the erosion is locally normalized. - **/ - template - CImg& erode(const CImg& mask, const unsigned int boundary_conditions=1, - const bool is_normalized=false) { - if (is_empty() || !mask) return *this; - return get_erode(mask,boundary_conditions,is_normalized).move_to(*this); - } - - //! Erode image by a structuring element \newinstance. - template - CImg<_cimg_Tt> get_erode(const CImg& mask, const unsigned int boundary_conditions=1, - const bool is_normalized=false) const { - if (is_empty() || !mask) return *this; - typedef _cimg_Tt Tt; - CImg res(_width,_height,_depth,cimg::max(_spectrum,mask._spectrum)); - const int - mx2 = mask.width()/2, my2 = mask.height()/2, mz2 = mask.depth()/2, - mx1 = mx2 - 1 + (mask.width()%2), my1 = my2 - 1 + (mask.height()%2), mz1 = mz2 - 1 + (mask.depth()%2), - mxe = width() - mx2, mye = height() - my2, mze = depth() - mz2; - cimg_abort_init; - cimg_pragma_openmp(parallel for cimg_openmp_if(_spectrum>=2)) - cimg_forC(*this,c) cimg_abort_try { - cimg_abort_test(); - const CImg _img = get_shared_channel(c%_spectrum); - const CImg _mask = mask.get_shared_channel(c%mask._spectrum); - if (is_normalized) { // Normalized erosion. - cimg_pragma_openmp(parallel for collapse(3) if (_width*_height*_depth>=32768)) - for (int z = mz1; z::max(); - for (int zm = -mz1; zm<=mz2; ++zm) - for (int ym = -my1; ym<=my2; ++ym) - for (int xm = -mx1; xm<=mx2; ++xm) { - const t mval = _mask(mx1 + xm,my1 + ym,mz1 + zm); - const Tt cval = (Tt)(_img(x + xm,y + ym,z + zm) + mval); - if (mval && cval=256 && _height*_depth>=128)) - cimg_forYZ(res,y,z) cimg_abort_try2 { - cimg_abort_test2(); - for (int x = 0; x=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { - Tt min_val = cimg::type::max(); - for (int zm = -mz1; zm<=mz2; ++zm) - for (int ym = -my1; ym<=my2; ++ym) - for (int xm = -mx1; xm<=mx2; ++xm) { - const t mval = _mask(mx1 + xm,my1 + ym,mz1 + zm); - const Tt cval = (Tt)(_img._atXYZ(x + xm,y + ym,z + zm) + mval); - if (mval && cval=256 && _height*_depth>=128)) - cimg_forYZ(res,y,z) cimg_abort_try2 { - cimg_abort_test2(); - for (int x = 0; x=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { - Tt min_val = cimg::type::max(); - for (int zm = -mz1; zm<=mz2; ++zm) - for (int ym = -my1; ym<=my2; ++ym) - for (int xm = -mx1; xm<=mx2; ++xm) { - const t mval = _mask(mx1 + xm,my1 + ym,mz1 + zm); - const Tt cval = (Tt)(_img.atXYZ(x + xm,y + ym,z + zm,0,0) + mval); - if (mval && cval=32768)) - for (int z = mz1; z::max(); - for (int zm = -mz1; zm<=mz2; ++zm) - for (int ym = -my1; ym<=my2; ++ym) - for (int xm = -mx1; xm<=mx2; ++xm) { - const Tt cval = (Tt)_img(x + xm,y + ym,z + zm); - if (_mask(mx1 + xm,my1 + ym,mz1 + zm) && cval=256 && _height*_depth>=128)) - cimg_forYZ(res,y,z) cimg_abort_try2 { - cimg_abort_test2(); - for (int x = 0; x=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { - Tt min_val = cimg::type::max(); - for (int zm = -mz1; zm<=mz2; ++zm) - for (int ym = -my1; ym<=my2; ++ym) - for (int xm = -mx1; xm<=mx2; ++xm) { - const T cval = (Tt)_img._atXYZ(x + xm,y + ym,z + zm); - if (_mask(mx1 + xm,my1 + ym,mz1 + zm) && cval=256 && _height*_depth>=128)) - cimg_forYZ(res,y,z) cimg_abort_try2 { - cimg_abort_test2(); - for (int x = 0; x=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { - Tt min_val = cimg::type::max(); - for (int zm = -mz1; zm<=mz2; ++zm) - for (int ym = -my1; ym<=my2; ++ym) - for (int xm = -mx1; xm<=mx2; ++xm) { - const T cval = (Tt)_img.atXYZ(x + xm,y + ym,z + zm,0,0); - if (_mask(mx1 + xm,my1 + ym,mz1 + zm) && cval& erode(const unsigned int sx, const unsigned int sy, const unsigned int sz=1) { - if (is_empty() || (sx==1 && sy==1 && sz==1)) return *this; - if (sx>1 && _width>1) { // Along X-axis. - const int L = width(), off = 1, s = (int)sx, _s1 = s/2, _s2 = s - _s1, s1 = _s1>L?L:_s1, s2 = _s2>L?L:_s2; - CImg buf(L); -#ifdef cimg_use_opemp -#pragma omp parallel for collapse(3) firstprivate(buf) if (size()>524288) -#endif - cimg_forYZC(*this,y,z,c) { - T *const ptrdb = buf._data, *ptrd = buf._data, *const ptrde = buf._data + L - 1; - const T *const ptrsb = data(0,y,z,c), *ptrs = ptrsb, *const ptrse = ptrs + L*off - off; - T cur = *ptrs; ptrs+=off; bool is_first = true; - for (int p = s2 - 1; p>0 && ptrs<=ptrse; --p) { - const T val = *ptrs; ptrs+=off; if (val<=cur) { cur = val; is_first = false; }} - *(ptrd++) = cur; - if (ptrs>=ptrse) { - T *pd = data(0,y,z,c); cur = cimg::min(cur,*ptrse); cimg_forX(buf,x) { *pd = cur; pd+=off; } - } else { - for (int p = s1; p>0 && ptrd<=ptrde; --p) { - const T val = *ptrs; if (ptrs0; --p) { - const T val = *ptrs; ptrs+=off; - if (is_first) { - const T *nptrs = ptrs - off; cur = val; - for (int q = s - 2; q>0; --q) { nptrs-=off; const T nval = *nptrs; if (nval0 && ptrs>=ptrsb; --p) { - const T val = *ptrs; ptrs-=off; if (val0 && ptrd>=ptrdb; --p) { - const T val = *ptrs; if (ptrs>ptrsb) ptrs-=off; if (val1 && _height>1) { // Along Y-axis. - const int L = height(), off = width(), s = (int)sy, _s1 = s/2, _s2 = s - _s1, s1 = _s1>L?L:_s1, - s2 = _s2>L?L:_s2; - CImg buf(L); -#ifdef cimg_use_opemp -#pragma omp parallel for collapse(3) firstprivate(buf) if (size()>524288) -#endif - cimg_forXZC(*this,x,z,c) { - T *const ptrdb = buf._data, *ptrd = ptrdb, *const ptrde = buf._data + L - 1; - const T *const ptrsb = data(x,0,z,c), *ptrs = ptrsb, *const ptrse = ptrs + L*off - off; - T cur = *ptrs; ptrs+=off; bool is_first = true; - for (int p = s2 - 1; p>0 && ptrs<=ptrse; --p) { - const T val = *ptrs; ptrs+=off; if (val<=cur) { cur = val; is_first = false; } - } - *(ptrd++) = cur; - if (ptrs>=ptrse) { - T *pd = data(x,0,z,c); cur = cimg::min(cur,*ptrse); cimg_forX(buf,x) { *pd = cur; pd+=off; } - } else { - for (int p = s1; p>0 && ptrd<=ptrde; --p) { - const T val = *ptrs; if (ptrs0; --p) { - const T val = *ptrs; ptrs+=off; - if (is_first) { - const T *nptrs = ptrs - off; cur = val; - for (int q = s - 2; q>0; --q) { nptrs-=off; const T nval = *nptrs; if (nval0 && ptrs>=ptrsb; --p) { - const T val = *ptrs; ptrs-=off; if (val0 && ptrd>=ptrdb; --p) { - const T val = *ptrs; if (ptrs>ptrsb) ptrs-=off; if (val1 && _depth>1) { // Along Z-axis. - const int L = depth(), off = width()*height(), s = (int)sz, _s1 = s/2, _s2 = s - _s1, s1 = _s1>L?L:_s1, - s2 = _s2>L?L:_s2; - CImg buf(L); -#ifdef cimg_use_opemp -#pragma omp parallel for collapse(3) firstprivate(buf) if (size()>524288) -#endif - cimg_forXYC(*this,x,y,c) { - T *const ptrdb = buf._data, *ptrd = ptrdb, *const ptrde = buf._data + L - 1; - const T *const ptrsb = data(x,y,0,c), *ptrs = ptrsb, *const ptrse = ptrs + L*off - off; - T cur = *ptrs; ptrs+=off; bool is_first = true; - for (int p = s2 - 1; p>0 && ptrs<=ptrse; --p) { - const T val = *ptrs; ptrs+=off; if (val<=cur) { cur = val; is_first = false; } - } - *(ptrd++) = cur; - if (ptrs>=ptrse) { - T *pd = data(x,y,0,c); cur = cimg::min(cur,*ptrse); cimg_forX(buf,x) { *pd = cur; pd+=off; } - } else { - for (int p = s1; p>0 && ptrd<=ptrde; --p) { - const T val = *ptrs; if (ptrs0; --p) { - const T val = *ptrs; ptrs+=off; - if (is_first) { - const T *nptrs = ptrs - off; cur = val; - for (int q = s - 2; q>0; --q) { nptrs-=off; const T nval = *nptrs; if (nval0 && ptrs>=ptrsb; --p) { - const T val = *ptrs; ptrs-=off; if (val0 && ptrd>=ptrdb; --p) { - const T val = *ptrs; if (ptrs>ptrsb) ptrs-=off; if (val get_erode(const unsigned int sx, const unsigned int sy, const unsigned int sz=1) const { - return (+*this).erode(sx,sy,sz); - } - - //! Erode the image by a square structuring element of specified size. - /** - \param s Size of the structuring element. - **/ - CImg& erode(const unsigned int s) { - return erode(s,s,s); - } - - //! Erode the image by a square structuring element of specified size \newinstance. - CImg get_erode(const unsigned int s) const { - return (+*this).erode(s); - } - - //! Dilate image by a structuring element. - /** - \param mask Structuring element. - \param boundary_conditions Boundary conditions. - \param is_normalized Tells if the erosion is locally normalized. - **/ - template - CImg& dilate(const CImg& mask, const unsigned int boundary_conditions=1, - const bool is_normalized=false) { - if (is_empty() || !mask) return *this; - return get_dilate(mask,boundary_conditions,is_normalized).move_to(*this); - } - - //! Dilate image by a structuring element \newinstance. - template - CImg<_cimg_Tt> get_dilate(const CImg& mask, const unsigned int boundary_conditions=1, - const bool is_normalized=false) const { - if (is_empty() || !mask) return *this; - typedef _cimg_Tt Tt; - CImg res(_width,_height,_depth,_spectrum); - const int - mx2 = mask.width()/2, my2 = mask.height()/2, mz2 = mask.depth()/2, - mx1 = mx2 - 1 + (mask.width()%2), my1 = my2 - 1 + (mask.height()%2), mz1 = mz2 - 1 + (mask.depth()%2), - mxe = width() - mx2, mye = height() - my2, mze = depth() - mz2; - cimg_abort_init; - cimg_pragma_openmp(parallel for cimg_openmp_if(_spectrum>=2)) - cimg_forC(*this,c) cimg_abort_try { - cimg_abort_test(); - const CImg _img = get_shared_channel(c%_spectrum); - const CImg _mask = mask.get_shared_channel(c%mask._spectrum); - if (is_normalized) { // Normalized dilation. - cimg_pragma_openmp(parallel for collapse(3) if (_width*_height*_depth>=32768)) - for (int z = mz1; z::min(); - for (int zm = -mz1; zm<=mz2; ++zm) - for (int ym = -my1; ym<=my2; ++ym) - for (int xm = -mx1; xm<=mx2; ++xm) { - const t mval = _mask(mx1 + xm,my1 + ym,mz1 + zm); - const Tt cval = (Tt)(_img(x + xm,y + ym,z + zm) - mval); - if (mval && cval>max_val) max_val = cval; - } - res(x,y,z,c) = max_val; - } cimg_abort_catch2() - if (boundary_conditions) - cimg_pragma_openmp(parallel for collapse(2) if (_width>=256 && _height*_depth>=128)) - cimg_forYZ(res,y,z) cimg_abort_try2 { - cimg_abort_test2(); - for (int x = 0; x=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { - Tt max_val = cimg::type::min(); - for (int zm = -mz1; zm<=mz2; ++zm) - for (int ym = -my1; ym<=my2; ++ym) - for (int xm = -mx1; xm<=mx2; ++xm) { - const t mval = _mask(mx1 + xm,my1 + ym,mz1 + zm); - const Tt cval = (Tt)(_img._atXYZ(x + xm,y + ym,z + zm) - mval); - if (mval && cval>max_val) max_val = cval; - } - res(x,y,z,c) = max_val; - } - } cimg_abort_catch2() - else - cimg_pragma_openmp(parallel for collapse(2) if (_width>=256 && _height*_depth>=128)) - cimg_forYZ(*this,y,z) cimg_abort_try2 { - cimg_abort_test2(); - for (int x = 0; x=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { - Tt max_val = cimg::type::min(); - for (int zm = -mz1; zm<=mz2; ++zm) - for (int ym = -my1; ym<=my2; ++ym) - for (int xm = -mx1; xm<=mx2; ++xm) { - const t mval = _mask(mx1 + xm,my1 + ym,mz1 + zm); - const Tt cval = (Tt)(_img.atXYZ(x + xm,y + ym,z + zm,0,0) - mval); - if (mval && cval>max_val) max_val = cval; - } - res(x,y,z,c) = max_val; - } - } cimg_abort_catch2() - } else { // Classical dilation. - cimg_pragma_openmp(parallel for collapse(3) if (_width>=256 && _height*_depth>=128)) - for (int z = mz1; z::min(); - for (int zm = -mz1; zm<=mz2; ++zm) - for (int ym = -my1; ym<=my2; ++ym) - for (int xm = -mx1; xm<=mx2; ++xm) { - const Tt cval = (Tt)_img(x + xm,y + ym,z + zm); - if (_mask(mx1 + xm,my1 + ym,mz1 + zm) && cval>max_val) max_val = cval; - } - res(x,y,z,c) = max_val; - } cimg_abort_catch2() - if (boundary_conditions) - cimg_pragma_openmp(parallel for collapse(2) if (_width>=256 && _height*_depth>=128)) - cimg_forYZ(res,y,z) cimg_abort_try2 { - cimg_abort_test2(); - for (int x = 0; x=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { - Tt max_val = cimg::type::min(); - for (int zm = -mz1; zm<=mz2; ++zm) - for (int ym = -my1; ym<=my2; ++ym) - for (int xm = -mx1; xm<=mx2; ++xm) { - const T cval = (Tt)_img._atXYZ(x + xm,y + ym,z + zm); - if (_mask(mx1 + xm,my1 + ym,mz1 + zm) && cval>max_val) max_val = cval; - } - res(x,y,z,c) = max_val; - } - } cimg_abort_catch2() - else - cimg_pragma_openmp(parallel for collapse(2) if (_width>=256 && _height*_depth>=128)) - cimg_forYZ(res,y,z) cimg_abort_try2 { - cimg_abort_test2(); - for (int x = 0; x=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { - Tt max_val = cimg::type::min(); - for (int zm = -mz1; zm<=mz2; ++zm) - for (int ym = -my1; ym<=my2; ++ym) - for (int xm = -mx1; xm<=mx2; ++xm) { - const T cval = (Tt)_img.atXYZ(x + xm,y + ym,z + zm,0,0); - if (_mask(mx1 + xm,my1 + ym,mz1 + zm) && cval>max_val) max_val = cval; - } - res(x,y,z,c) = max_val; - } - } cimg_abort_catch2() - } - } cimg_abort_catch() - cimg_abort_test(); - return res; - } - - //! Dilate image by a rectangular structuring element of specified size. - /** - \param sx Width of the structuring element. - \param sy Height of the structuring element. - \param sz Depth of the structuring element. - **/ - CImg& dilate(const unsigned int sx, const unsigned int sy, const unsigned int sz=1) { - if (is_empty() || (sx==1 && sy==1 && sz==1)) return *this; - if (sx>1 && _width>1) { // Along X-axis. - const int L = width(), off = 1, s = (int)sx, _s2 = s/2 + 1, _s1 = s - _s2, s1 = _s1>L?L:_s1, s2 = _s2>L?L:_s2; - CImg buf(L); -#ifdef cimg_use_opemp -#pragma omp parallel for collapse(3) firstprivate(buf) if (size()>524288) -#endif - cimg_forYZC(*this,y,z,c) { - T *const ptrdb = buf._data, *ptrd = ptrdb, *const ptrde = buf._data + L - 1; - const T *const ptrsb = data(0,y,z,c), *ptrs = ptrsb, *const ptrse = ptrs + L*off - off; - T cur = *ptrs; ptrs+=off; bool is_first = true; - for (int p = s2 - 1; p>0 && ptrs<=ptrse; --p) { - const T val = *ptrs; ptrs+=off; if (val>=cur) { cur = val; is_first = false; } - } - *(ptrd++) = cur; - if (ptrs>=ptrse) { - T *pd = data(0,y,z,c); cur = cimg::max(cur,*ptrse); cimg_forX(buf,x) { *pd = cur; pd+=off; } - } else { - for (int p = s1; p>0 && ptrd<=ptrde; --p) { - const T val = *ptrs; if (ptrs=cur) { cur = val; is_first = false; } - *(ptrd++) = cur; - } - for (int p = L - s - 1; p>0; --p) { - const T val = *ptrs; ptrs+=off; - if (is_first) { - const T *nptrs = ptrs - off; cur = val; - for (int q = s - 2; q>0; --q) { nptrs-=off; const T nval = *nptrs; if (nval>cur) cur = nval; } - nptrs-=off; const T nval = *nptrs; if (nval>cur) { cur = nval; is_first = true; } else is_first = false; - } else { if (val>=cur) cur = val; else if (cur==*(ptrs-s*off)) is_first = true; } - *(ptrd++) = cur; - } - ptrd = ptrde; ptrs = ptrse; cur = *ptrs; ptrs-=off; - for (int p = s1; p>0 && ptrs>=ptrsb; --p) { - const T val = *ptrs; ptrs-=off; if (val>cur) cur = val; - } - *(ptrd--) = cur; - for (int p = s2 - 1; p>0 && ptrd>=ptrdb; --p) { - const T val = *ptrs; if (ptrs>ptrsb) ptrs-=off; if (val>cur) cur = val; *(ptrd--) = cur; - } - T *pd = data(0,y,z,c); cimg_for(buf,ps,T) { *pd = *ps; pd+=off; } - } - } - } - - if (sy>1 && _height>1) { // Along Y-axis. - const int L = height(), off = width(), s = (int)sy, _s2 = s/2 + 1, _s1 = s - _s2, s1 = _s1>L?L:_s1, - s2 = _s2>L?L:_s2; - CImg buf(L); -#ifdef cimg_use_opemp -#pragma omp parallel for collapse(3) firstprivate(buf) if (size()>524288) -#endif - cimg_forXZC(*this,x,z,c) { - T *const ptrdb = buf._data, *ptrd = ptrdb, *const ptrde = buf._data + L - 1; - const T *const ptrsb = data(x,0,z,c), *ptrs = ptrsb, *const ptrse = ptrs + L*off - off; - T cur = *ptrs; ptrs+=off; bool is_first = true; - for (int p = s2 - 1; p>0 && ptrs<=ptrse; --p) { - const T val = *ptrs; ptrs+=off; if (val>=cur) { cur = val; is_first = false; } - } - *(ptrd++) = cur; - if (ptrs>=ptrse) { - T *pd = data(x,0,z,c); cur = cimg::max(cur,*ptrse); cimg_forX(buf,x) { *pd = cur; pd+=off; } - } else { - for (int p = s1; p>0 && ptrd<=ptrde; --p) { - const T val = *ptrs; if (ptrs=cur) { cur = val; is_first = false; } - *(ptrd++) = cur; - } - for (int p = L - s - 1; p>0; --p) { - const T val = *ptrs; ptrs+=off; - if (is_first) { - const T *nptrs = ptrs - off; cur = val; - for (int q = s - 2; q>0; --q) { nptrs-=off; const T nval = *nptrs; if (nval>cur) cur = nval; } - nptrs-=off; const T nval = *nptrs; if (nval>cur) { cur = nval; is_first = true; } else is_first = false; - } else { if (val>=cur) cur = val; else if (cur==*(ptrs-s*off)) is_first = true; } - *(ptrd++) = cur; - } - ptrd = ptrde; ptrs = ptrse; cur = *ptrs; ptrs-=off; - for (int p = s1; p>0 && ptrs>=ptrsb; --p) { - const T val = *ptrs; ptrs-=off; if (val>cur) cur = val; - } - *(ptrd--) = cur; - for (int p = s2 - 1; p>0 && ptrd>=ptrdb; --p) { - const T val = *ptrs; if (ptrs>ptrsb) ptrs-=off; if (val>cur) cur = val; *(ptrd--) = cur; - } - T *pd = data(x,0,z,c); cimg_for(buf,ps,T) { *pd = *ps; pd+=off; } - } - } - } - - if (sz>1 && _depth>1) { // Along Z-axis. - const int L = depth(), off = width()*height(), s = (int)sz, _s2 = s/2 + 1, _s1 = s - _s2, s1 = _s1>L?L:_s1, - s2 = _s2>L?L:_s2; - CImg buf(L); -#ifdef cimg_use_opemp -#pragma omp parallel for collapse(3) firstprivate(buf) if (size()>524288) -#endif - cimg_forXYC(*this,x,y,c) { - T *const ptrdb = buf._data, *ptrd = ptrdb, *const ptrde = buf._data + L - 1; - const T *const ptrsb = data(x,y,0,c), *ptrs = ptrsb, *const ptrse = ptrs + L*off - off; - T cur = *ptrs; ptrs+=off; bool is_first = true; - for (int p = s2 - 1; p>0 && ptrs<=ptrse; --p) { - const T val = *ptrs; ptrs+=off; if (val>=cur) { cur = val; is_first = false; } - } - *(ptrd++) = cur; - if (ptrs>=ptrse) { - T *pd = data(x,y,0,c); cur = cimg::max(cur,*ptrse); cimg_forX(buf,x) { *pd = cur; pd+=off; } - } else { - for (int p = s1; p>0 && ptrd<=ptrde; --p) { - const T val = *ptrs; if (ptrs=cur) { cur = val; is_first = false; } - *(ptrd++) = cur; - } - for (int p = L - s - 1; p>0; --p) { - const T val = *ptrs; ptrs+=off; - if (is_first) { - const T *nptrs = ptrs - off; cur = val; - for (int q = s - 2; q>0; --q) { nptrs-=off; const T nval = *nptrs; if (nval>cur) cur = nval; } - nptrs-=off; const T nval = *nptrs; if (nval>cur) { cur = nval; is_first = true; } else is_first = false; - } else { if (val>=cur) cur = val; else if (cur==*(ptrs-s*off)) is_first = true; } - *(ptrd++) = cur; - } - ptrd = ptrde; ptrs = ptrse; cur = *ptrs; ptrs-=off; - for (int p = s1; p>0 && ptrs>=ptrsb; --p) { - const T val = *ptrs; ptrs-=off; if (val>cur) cur = val; - } - *(ptrd--) = cur; - for (int p = s2 - 1; p>0 && ptrd>=ptrdb; --p) { - const T val = *ptrs; if (ptrs>ptrsb) ptrs-=off; if (val>cur) cur = val; *(ptrd--) = cur; - } - T *pd = data(x,y,0,c); cimg_for(buf,ps,T) { *pd = *ps; pd+=off; } - } - } - } - return *this; - } - - //! Dilate image by a rectangular structuring element of specified size \newinstance. - CImg get_dilate(const unsigned int sx, const unsigned int sy, const unsigned int sz=1) const { - return (+*this).dilate(sx,sy,sz); - } - - //! Dilate image by a square structuring element of specified size. - /** - \param s Size of the structuring element. - **/ - CImg& dilate(const unsigned int s) { - return dilate(s,s,s); - } - - //! Dilate image by a square structuring element of specified size \newinstance. - CImg get_dilate(const unsigned int s) const { - return (+*this).dilate(s); - } - - //! Compute watershed transform. - /** - \param priority Priority map. - \param is_high_connectivity Boolean that choose between 4(false)- or 8(true)-connectivity - in 2d case, and between 6(false)- or 26(true)-connectivity in 3d case. - \note Non-zero values of the instance instance are propagated to zero-valued ones according to - specified the priority map. - **/ - template - CImg& watershed(const CImg& priority, const bool is_high_connectivity=false) { -#define _cimg_watershed_init(cond,X,Y,Z) \ - if (cond && !(*this)(X,Y,Z)) Q._priority_queue_insert(labels,sizeQ,priority(X,Y,Z),X,Y,Z,nb_seeds) - -#define _cimg_watershed_propagate(cond,X,Y,Z) \ - if (cond) { \ - if ((*this)(X,Y,Z)) { \ - ns = labels(X,Y,Z) - 1; xs = seeds(ns,0); ys = seeds(ns,1); zs = seeds(ns,2); \ - d = cimg::sqr((float)x - xs) + cimg::sqr((float)y - ys) + cimg::sqr((float)z - zs); \ - if (d labels(_width,_height,_depth,1,0), seeds(64,3); - CImg::type> Q; - unsigned int sizeQ = 0; - int px, nx, py, ny, pz, nz; - bool is_px, is_nx, is_py, is_ny, is_pz, is_nz; - const bool is_3d = _depth>1; - - // Find seed points and insert them in priority queue. - unsigned int nb_seeds = 0; - const T *ptrs = _data; - cimg_forXYZ(*this,x,y,z) if (*(ptrs++)) { // 3d version - if (nb_seeds>=seeds._width) seeds.resize(2*seeds._width,3,1,1,0); - seeds(nb_seeds,0) = x; seeds(nb_seeds,1) = y; seeds(nb_seeds++,2) = z; - px = x - 1; nx = x + 1; - py = y - 1; ny = y + 1; - pz = z - 1; nz = z + 1; - is_px = px>=0; is_nx = nx=0; is_ny = ny=0; is_nz = nz=0; is_nx = nx=0; is_ny = ny=0; is_nz = nz::inf(); - T label = 0; - _cimg_watershed_propagate(is_px,px,y,z); - _cimg_watershed_propagate(is_nx,nx,y,z); - _cimg_watershed_propagate(is_py,x,py,z); - _cimg_watershed_propagate(is_ny,x,ny,z); - if (is_3d) { - _cimg_watershed_propagate(is_pz,x,y,pz); - _cimg_watershed_propagate(is_nz,x,y,nz); - } - if (is_high_connectivity) { - _cimg_watershed_propagate(is_px && is_py,px,py,z); - _cimg_watershed_propagate(is_nx && is_py,nx,py,z); - _cimg_watershed_propagate(is_px && is_ny,px,ny,z); - _cimg_watershed_propagate(is_nx && is_ny,nx,ny,z); - if (is_3d) { - _cimg_watershed_propagate(is_px && is_pz,px,y,pz); - _cimg_watershed_propagate(is_nx && is_pz,nx,y,pz); - _cimg_watershed_propagate(is_px && is_nz,px,y,nz); - _cimg_watershed_propagate(is_nx && is_nz,nx,y,nz); - _cimg_watershed_propagate(is_py && is_pz,x,py,pz); - _cimg_watershed_propagate(is_ny && is_pz,x,ny,pz); - _cimg_watershed_propagate(is_py && is_nz,x,py,nz); - _cimg_watershed_propagate(is_ny && is_nz,x,ny,nz); - _cimg_watershed_propagate(is_px && is_py && is_pz,px,py,pz); - _cimg_watershed_propagate(is_nx && is_py && is_pz,nx,py,pz); - _cimg_watershed_propagate(is_px && is_ny && is_pz,px,ny,pz); - _cimg_watershed_propagate(is_nx && is_ny && is_pz,nx,ny,pz); - _cimg_watershed_propagate(is_px && is_py && is_nz,px,py,nz); - _cimg_watershed_propagate(is_nx && is_py && is_nz,nx,py,nz); - _cimg_watershed_propagate(is_px && is_ny && is_nz,px,ny,nz); - _cimg_watershed_propagate(is_nx && is_ny && is_nz,nx,ny,nz); - } - } - (*this)(x,y,z) = label; - labels(x,y,z) = ++nmin; - } - return *this; - } - - //! Compute watershed transform \newinstance. - template - CImg get_watershed(const CImg& priority, const bool is_high_connectivity=false) const { - return (+*this).watershed(priority,is_high_connectivity); - } - - // [internal] Insert/Remove items in priority queue, for watershed/distance transforms. - template - bool _priority_queue_insert(CImg& is_queued, unsigned int& siz, const tv value, - const unsigned int x, const unsigned int y, const unsigned int z, - const unsigned int n=1) { - if (is_queued(x,y,z)) return false; - is_queued(x,y,z) = (tq)n; - if (++siz>=_width) { if (!is_empty()) resize(_width*2,4,1,1,0); else assign(64,4); } - (*this)(siz - 1,0) = (T)value; - (*this)(siz - 1,1) = (T)x; - (*this)(siz - 1,2) = (T)y; - (*this)(siz - 1,3) = (T)z; - for (unsigned int pos = siz - 1, par = 0; pos && value>(*this)(par=(pos + 1)/2 - 1,0); pos = par) { - cimg::swap((*this)(pos,0),(*this)(par,0)); - cimg::swap((*this)(pos,1),(*this)(par,1)); - cimg::swap((*this)(pos,2),(*this)(par,2)); - cimg::swap((*this)(pos,3),(*this)(par,3)); - } - return true; - } - - CImg& _priority_queue_remove(unsigned int& siz) { - (*this)(0,0) = (*this)(--siz,0); - (*this)(0,1) = (*this)(siz,1); - (*this)(0,2) = (*this)(siz,2); - (*this)(0,3) = (*this)(siz,3); - const float value = (*this)(0,0); - for (unsigned int pos = 0, left = 0, right = 0; - ((right=2*(pos + 1),(left=right - 1))(*this)(right,0)) { - cimg::swap((*this)(pos,0),(*this)(left,0)); - cimg::swap((*this)(pos,1),(*this)(left,1)); - cimg::swap((*this)(pos,2),(*this)(left,2)); - cimg::swap((*this)(pos,3),(*this)(left,3)); - pos = left; - } else { - cimg::swap((*this)(pos,0),(*this)(right,0)); - cimg::swap((*this)(pos,1),(*this)(right,1)); - cimg::swap((*this)(pos,2),(*this)(right,2)); - cimg::swap((*this)(pos,3),(*this)(right,3)); - pos = right; - } - } else { - cimg::swap((*this)(pos,0),(*this)(left,0)); - cimg::swap((*this)(pos,1),(*this)(left,1)); - cimg::swap((*this)(pos,2),(*this)(left,2)); - cimg::swap((*this)(pos,3),(*this)(left,3)); - pos = left; - } - } - return *this; - } - - //! Apply recursive Deriche filter. - /** - \param sigma Standard deviation of the filter. - \param order Order of the filter. Can be { 0=smooth-filter | 1=1st-derivative | 2=2nd-derivative }. - \param axis Axis along which the filter is computed. Can be { 'x' | 'y' | 'z' | 'c' }. - \param boundary_conditions Boundary conditions. Can be { 0=dirichlet | 1=neumann }. - **/ - CImg& deriche(const float sigma, const unsigned int order=0, const char axis='x', - const bool boundary_conditions=true) { -#define _cimg_deriche_apply \ - CImg Y(N); \ - Tfloat *ptrY = Y._data, yb = 0, yp = 0; \ - T xp = (T)0; \ - if (boundary_conditions) { xp = *ptrX; yb = yp = (Tfloat)(coefp*xp); } \ - for (int m = 0; m=0; --n) { \ - const T xc = *(ptrX-=off); \ - const Tfloat yc = (Tfloat)(a2*xn + a3*xa - b1*yn - b2*ya); \ - xa = xn; xn = xc; ya = yn; yn = yc; \ - *ptrX = (T)(*(--ptrY)+yc); \ - } - const char naxis = cimg::lowercase(axis); - const float nsigma = sigma>=0?sigma:-sigma*(naxis=='x'?_width:naxis=='y'?_height:naxis=='z'?_depth:_spectrum)/100; - if (is_empty() || (nsigma<0.1f && !order)) return *this; - const float - nnsigma = nsigma<0.1f?0.1f:nsigma, - alpha = 1.695f/nnsigma, - ema = (float)std::exp(-alpha), - ema2 = (float)std::exp(-2*alpha), - b1 = -2*ema, - b2 = ema2; - float a0 = 0, a1 = 0, a2 = 0, a3 = 0, coefp = 0, coefn = 0; - switch (order) { - case 0 : { - const float k = (1-ema)*(1-ema)/(1 + 2*alpha*ema-ema2); - a0 = k; - a1 = k*(alpha - 1)*ema; - a2 = k*(alpha + 1)*ema; - a3 = -k*ema2; - } break; - case 1 : { - const float k = -(1-ema)*(1-ema)*(1-ema)/(2*(ema + 1)*ema); - a0 = a3 = 0; - a1 = k*ema; - a2 = -a1; - } break; - case 2 : { - const float - ea = (float)std::exp(-alpha), - k = -(ema2 - 1)/(2*alpha*ema), - kn = (-2*(-1 + 3*ea - 3*ea*ea + ea*ea*ea)/(3*ea + 1 + 3*ea*ea + ea*ea*ea)); - a0 = kn; - a1 = -kn*(1 + k*alpha)*ema; - a2 = kn*(1 - k*alpha)*ema; - a3 = -kn*ema2; - } break; - default : - throw CImgArgumentException(_cimg_instance - "deriche(): Invalid specified filter order %u " - "(should be { 0=smoothing | 1=1st-derivative | 2=2nd-derivative }).", - cimg_instance, - order); - } - coefp = (a0 + a1)/(1 + b1 + b2); - coefn = (a2 + a3)/(1 + b1 + b2); - switch (naxis) { - case 'x' : { - const int N = width(); - const ulongT off = 1U; - cimg_pragma_openmp(parallel for collapse(3) if (_width>=256 && _height*_depth*_spectrum>=16)) - cimg_forYZC(*this,y,z,c) { T *ptrX = data(0,y,z,c); _cimg_deriche_apply; } - } break; - case 'y' : { - const int N = height(); - const ulongT off = (ulongT)_width; - cimg_pragma_openmp(parallel for collapse(3) if (_width>=256 && _height*_depth*_spectrum>=16)) - cimg_forXZC(*this,x,z,c) { T *ptrX = data(x,0,z,c); _cimg_deriche_apply; } - } break; - case 'z' : { - const int N = depth(); - const ulongT off = (ulongT)_width*_height; - cimg_pragma_openmp(parallel for collapse(3) if (_width>=256 && _height*_depth*_spectrum>=16)) - cimg_forXYC(*this,x,y,c) { T *ptrX = data(x,y,0,c); _cimg_deriche_apply; } - } break; - default : { - const int N = spectrum(); - const ulongT off = (ulongT)_width*_height*_depth; - cimg_pragma_openmp(parallel for collapse(3) if (_width>=256 && _height*_depth*_spectrum>=16)) - cimg_forXYZ(*this,x,y,z) { T *ptrX = data(x,y,z,0); _cimg_deriche_apply; } - } - } - return *this; - } - - //! Apply recursive Deriche filter \newinstance. - CImg get_deriche(const float sigma, const unsigned int order=0, const char axis='x', - const bool boundary_conditions=true) const { - return CImg(*this,false).deriche(sigma,order,axis,boundary_conditions); - } - - // [internal] Apply a recursive filter (used by CImg::vanvliet()). - /* - \param ptr the pointer of the data - \param filter the coefficient of the filter in the following order [n,n - 1,n - 2,n - 3]. - \param N size of the data - \param off the offset between two data point - \param order the order of the filter 0 (smoothing), 1st derivtive, 2nd derivative, 3rd derivative - \param boundary_conditions Boundary conditions. Can be { 0=dirichlet | 1=neumann }. - \note Boundary condition using B. Triggs method (IEEE trans on Sig Proc 2005). - */ - static void _cimg_recursive_apply(T *data, const double filter[], const int N, const ulongT off, - const unsigned int order, const bool boundary_conditions) { - double val[4] = { 0 }; // res[n,n - 1,n - 2,n - 3,..] or res[n,n + 1,n + 2,n + 3,..] - const double - sumsq = filter[0], sum = sumsq * sumsq, - a1 = filter[1], a2 = filter[2], a3 = filter[3], - scaleM = 1.0 / ( (1.0 + a1 - a2 + a3) * (1.0 - a1 - a2 - a3) * (1.0 + a2 + (a1 - a3) * a3) ); - double M[9]; // Triggs matrix - M[0] = scaleM * (-a3 * a1 + 1.0 - a3 * a3 - a2); - M[1] = scaleM * (a3 + a1) * (a2 + a3 * a1); - M[2] = scaleM * a3 * (a1 + a3 * a2); - M[3] = scaleM * (a1 + a3 * a2); - M[4] = -scaleM * (a2 - 1.0) * (a2 + a3 * a1); - M[5] = -scaleM * a3 * (a3 * a1 + a3 * a3 + a2 - 1.0); - M[6] = scaleM * (a3 * a1 + a2 + a1 * a1 - a2 * a2); - M[7] = scaleM * (a1 * a2 + a3 * a2 * a2 - a1 * a3 * a3 - a3 * a3 * a3 - a3 * a2 + a3); - M[8] = scaleM * a3 * (a1 + a3 * a2); - switch (order) { - case 0 : { - const double iplus = (boundary_conditions?data[(N - 1)*off]:0); - for (int pass = 0; pass<2; ++pass) { - if (!pass) { - for (int k = 1; k<4; ++k) val[k] = (boundary_conditions?*data/sumsq:0); - } else { - /* apply Triggs border condition */ - const double - uplus = iplus/(1.0 - a1 - a2 - a3), vplus = uplus/(1.0 - a1 - a2 - a3), - unp = val[1] - uplus, unp1 = val[2] - uplus, unp2 = val[3] - uplus; - val[0] = (M[0] * unp + M[1] * unp1 + M[2] * unp2 + vplus) * sum; - val[1] = (M[3] * unp + M[4] * unp1 + M[5] * unp2 + vplus) * sum; - val[2] = (M[6] * unp + M[7] * unp1 + M[8] * unp2 + vplus) * sum; - *data = (T)val[0]; - data -= off; - for (int k = 3; k>0; --k) val[k] = val[k - 1]; - } - for (int n = pass; n0; --k) val[k] = val[k - 1]; - } - if (!pass) data -= off; - } - } break; - case 1 : { - double x[3]; // [front,center,back] - for (int pass = 0; pass<2; ++pass) { - if (!pass) { - for (int k = 0; k<3; ++k) x[k] = (boundary_conditions?*data:0); - for (int k = 0; k<4; ++k) val[k] = 0; - } else { - /* apply Triggs border condition */ - const double - unp = val[1], unp1 = val[2], unp2 = val[3]; - val[0] = (M[0] * unp + M[1] * unp1 + M[2] * unp2) * sum; - val[1] = (M[3] * unp + M[4] * unp1 + M[5] * unp2) * sum; - val[2] = (M[6] * unp + M[7] * unp1 + M[8] * unp2) * sum; - *data = (T)val[0]; - data -= off; - for (int k = 3; k>0; --k) val[k] = val[k - 1]; - } - for (int n = pass; n0; --k) x[k] = x[k - 1]; - } else { data-=off;} - for (int k = 3; k>0; --k) val[k] = val[k - 1]; - } - *data = (T)0; - } - } break; - case 2: { - double x[3]; // [front,center,back] - for (int pass = 0; pass<2; ++pass) { - if (!pass) { - for (int k = 0; k<3; ++k) x[k] = (boundary_conditions?*data:0); - for (int k = 0; k<4; ++k) val[k] = 0; - } else { - /* apply Triggs border condition */ - const double - unp = val[1], unp1 = val[2], unp2 = val[3]; - val[0] = (M[0] * unp + M[1] * unp1 + M[2] * unp2) * sum; - val[1] = (M[3] * unp + M[4] * unp1 + M[5] * unp2) * sum; - val[2] = (M[6] * unp + M[7] * unp1 + M[8] * unp2) * sum; - *data = (T)val[0]; - data -= off; - for (int k = 3; k>0; --k) val[k] = val[k - 1]; - } - for (int n = pass; n0; --k) x[k] = x[k - 1]; - for (int k = 3; k>0; --k) val[k] = val[k - 1]; - } - *data = (T)0; - } - } break; - case 3: { - double x[3]; // [front,center,back] - for (int pass = 0; pass<2; ++pass) { - if (!pass) { - for (int k = 0; k<3; ++k) x[k] = (boundary_conditions?*data:0); - for (int k = 0; k<4; ++k) val[k] = 0; - } else { - /* apply Triggs border condition */ - const double - unp = val[1], unp1 = val[2], unp2 = val[3]; - val[0] = (M[0] * unp + M[1] * unp1 + M[2] * unp2) * sum; - val[1] = (M[3] * unp + M[4] * unp1 + M[5] * unp2) * sum; - val[2] = (M[6] * unp + M[7] * unp1 + M[8] * unp2) * sum; - *data = (T)val[0]; - data -= off; - for (int k = 3; k>0; --k) val[k] = val[k - 1]; - } - for (int n = pass; n0; --k) x[k] = x[k - 1]; - for (int k = 3; k>0; --k) val[k] = val[k - 1]; - } - *data = (T)0; - } - } break; - } - } - - //! Van Vliet recursive Gaussian filter. - /** - \param sigma standard deviation of the Gaussian filter - \param order the order of the filter 0,1,2,3 - \param axis Axis along which the filter is computed. Can be { 'x' | 'y' | 'z' | 'c' }. - \param boundary_conditions Boundary conditions. Can be { 0=dirichlet | 1=neumann }. - \note dirichlet boundary condition has a strange behavior - - I.T. Young, L.J. van Vliet, M. van Ginkel, Recursive Gabor filtering. - IEEE Trans. Sig. Proc., vol. 50, pp. 2799-2805, 2002. - - (this is an improvement over Young-Van Vliet, Sig. Proc. 44, 1995) - - Boundary conditions (only for order 0) using Triggs matrix, from - B. Triggs and M. Sdika. Boundary conditions for Young-van Vliet - recursive filtering. IEEE Trans. Signal Processing, - vol. 54, pp. 2365-2367, 2006. - **/ - CImg& vanvliet(const float sigma, const unsigned int order, const char axis='x', - const bool boundary_conditions=true) { - if (is_empty()) return *this; - const char naxis = cimg::lowercase(axis); - const float nsigma = sigma>=0?sigma:-sigma*(naxis=='x'?_width:naxis=='y'?_height:naxis=='z'?_depth:_spectrum)/100; - if (is_empty() || (nsigma<0.5f && !order)) return *this; - const double - nnsigma = nsigma<0.5f?0.5f:nsigma, - m0 = 1.16680, m1 = 1.10783, m2 = 1.40586, - m1sq = m1 * m1, m2sq = m2 * m2, - q = (nnsigma<3.556?-0.2568 + 0.5784*nnsigma + 0.0561*nnsigma*nnsigma:2.5091 + 0.9804*(nnsigma - 3.556)), - qsq = q * q, - scale = (m0 + q) * (m1sq + m2sq + 2 * m1 * q + qsq), - b1 = -q * (2 * m0 * m1 + m1sq + m2sq + (2 * m0 + 4 * m1) * q + 3 * qsq) / scale, - b2 = qsq * (m0 + 2 * m1 + 3 * q) / scale, - b3 = -qsq * q / scale, - B = ( m0 * (m1sq + m2sq) ) / scale; - double filter[4]; - filter[0] = B; filter[1] = -b1; filter[2] = -b2; filter[3] = -b3; - switch (naxis) { - case 'x' : { - cimg_pragma_openmp(parallel for collapse(3) if (_width>=256 && _height*_depth*_spectrum>=16)) - cimg_forYZC(*this,y,z,c) - _cimg_recursive_apply(data(0,y,z,c),filter,_width,1U,order,boundary_conditions); - } break; - case 'y' : { - cimg_pragma_openmp(parallel for collapse(3) if (_width>=256 && _height*_depth*_spectrum>=16)) - cimg_forXZC(*this,x,z,c) - _cimg_recursive_apply(data(x,0,z,c),filter,_height,(ulongT)_width,order,boundary_conditions); - } break; - case 'z' : { - cimg_pragma_openmp(parallel for collapse(3) if (_width>=256 && _height*_depth*_spectrum>=16)) - cimg_forXYC(*this,x,y,c) - _cimg_recursive_apply(data(x,y,0,c),filter,_depth,(ulongT)_width*_height, - order,boundary_conditions); - } break; - default : { - cimg_pragma_openmp(parallel for collapse(3) if (_width>=256 && _height*_depth*_spectrum>=16)) - cimg_forXYZ(*this,x,y,z) - _cimg_recursive_apply(data(x,y,z,0),filter,_spectrum,(ulongT)_width*_height*_depth, - order,boundary_conditions); - } - } - return *this; - } - - //! Blur image using Van Vliet recursive Gaussian filter. \newinstance. - CImg get_vanvliet(const float sigma, const unsigned int order, const char axis='x', - const bool boundary_conditions=true) const { - return CImg(*this,false).vanvliet(sigma,order,axis,boundary_conditions); - } - - //! Blur image. - /** - \param sigma_x Standard deviation of the blur, along the X-axis. - \param sigma_y Standard deviation of the blur, along the Y-axis. - \param sigma_z Standard deviation of the blur, along the Z-axis. - \param boundary_conditions Boundary conditions. Can be { false=dirichlet | true=neumann }. - \param is_gaussian Tells if the blur uses a gaussian (\c true) or quasi-gaussian (\c false) kernel. - \note - - The blur is computed as a 0-order Deriche filter. This is not a gaussian blur. - - This is a recursive algorithm, not depending on the values of the standard deviations. - \see deriche(), vanvliet(). - **/ - CImg& blur(const float sigma_x, const float sigma_y, const float sigma_z, - const bool boundary_conditions=true, const bool is_gaussian=false) { - if (is_empty()) return *this; - if (is_gaussian) { - if (_width>1) vanvliet(sigma_x,0,'x',boundary_conditions); - if (_height>1) vanvliet(sigma_y,0,'y',boundary_conditions); - if (_depth>1) vanvliet(sigma_z,0,'z',boundary_conditions); - } else { - if (_width>1) deriche(sigma_x,0,'x',boundary_conditions); - if (_height>1) deriche(sigma_y,0,'y',boundary_conditions); - if (_depth>1) deriche(sigma_z,0,'z',boundary_conditions); - } - return *this; - } - - //! Blur image \newinstance. - CImg get_blur(const float sigma_x, const float sigma_y, const float sigma_z, - const bool boundary_conditions=true, const bool is_gaussian=false) const { - return CImg(*this,false).blur(sigma_x,sigma_y,sigma_z,boundary_conditions,is_gaussian); - } - - //! Blur image isotropically. - /** - \param sigma Standard deviation of the blur. - \param boundary_conditions Boundary conditions. Can be { 0=dirichlet | 1=neumann }.a - \see deriche(), vanvliet(). - **/ - CImg& blur(const float sigma, const bool boundary_conditions=true, const bool is_gaussian=false) { - const float nsigma = sigma>=0?sigma:-sigma*cimg::max(_width,_height,_depth)/100; - return blur(nsigma,nsigma,nsigma,boundary_conditions,is_gaussian); - } - - //! Blur image isotropically \newinstance. - CImg get_blur(const float sigma, const bool boundary_conditions=true, const bool is_gaussian=false) const { - return CImg(*this,false).blur(sigma,boundary_conditions,is_gaussian); - } - - //! Blur image anisotropically, directed by a field of diffusion tensors. - /** - \param G Field of square roots of diffusion tensors/vectors used to drive the smoothing. - \param amplitude Amplitude of the smoothing. - \param dl Spatial discretization. - \param da Angular discretization. - \param gauss_prec Precision of the diffusion process. - \param interpolation_type Interpolation scheme. - Can be { 0=nearest-neighbor | 1=linear | 2=Runge-Kutta }. - \param is_fast_approx Tells if a fast approximation of the gaussian function is used or not. - **/ - template - CImg& blur_anisotropic(const CImg& G, - const float amplitude=60, const float dl=0.8f, const float da=30, - const float gauss_prec=2, const unsigned int interpolation_type=0, - const bool is_fast_approx=1) { - - // Check arguments and init variables - if (!is_sameXYZ(G) || (G._spectrum!=3 && G._spectrum!=6)) - throw CImgArgumentException(_cimg_instance - "blur_anisotropic(): Invalid specified diffusion tensor field (%u,%u,%u,%u,%p).", - cimg_instance, - G._width,G._height,G._depth,G._spectrum,G._data); - - if (is_empty() || amplitude<=0 || dl<0) return *this; - const bool is_3d = (G._spectrum==6); - T val_min, val_max = max_min(val_min); - cimg_abort_init; - - if (da<=0) { // Iterated oriented Laplacians - CImg velocity(_width,_height,_depth,_spectrum); - for (unsigned int iteration = 0; iteration<(unsigned int)amplitude; ++iteration) { - Tfloat *ptrd = velocity._data, veloc_max = 0; - if (is_3d) // 3d version - cimg_forC(*this,c) { - cimg_abort_test(); - CImg_3x3x3(I,Tfloat); - cimg_for3x3x3(*this,x,y,z,c,I,Tfloat) { - const Tfloat - ixx = Incc + Ipcc - 2*Iccc, - ixy = (Innc + Ippc - Inpc - Ipnc)/4, - ixz = (Incn + Ipcp - Incp - Ipcn)/4, - iyy = Icnc + Icpc - 2*Iccc, - iyz = (Icnn + Icpp - Icnp - Icpn)/4, - izz = Iccn + Iccp - 2*Iccc, - veloc = (Tfloat)(G(x,y,z,0)*ixx + 2*G(x,y,z,1)*ixy + 2*G(x,y,z,2)*ixz + - G(x,y,z,3)*iyy + 2*G(x,y,z,4)*iyz + G(x,y,z,5)*izz); - *(ptrd++) = veloc; - if (veloc>veloc_max) veloc_max = veloc; else if (-veloc>veloc_max) veloc_max = -veloc; - } - } - else // 2d version - cimg_forZC(*this,z,c) { - cimg_abort_test(); - CImg_3x3(I,Tfloat); - cimg_for3x3(*this,x,y,z,c,I,Tfloat) { - const Tfloat - ixx = Inc + Ipc - 2*Icc, - ixy = (Inn + Ipp - Inp - Ipn)/4, - iyy = Icn + Icp - 2*Icc, - veloc = (Tfloat)(G(x,y,0,0)*ixx + 2*G(x,y,0,1)*ixy + G(x,y,0,2)*iyy); - *(ptrd++) = veloc; - if (veloc>veloc_max) veloc_max = veloc; else if (-veloc>veloc_max) veloc_max = -veloc; - } - } - if (veloc_max>0) *this+=(velocity*=dl/veloc_max); - } - } else { // LIC-based smoothing. - const ulongT whd = (ulongT)_width*_height*_depth; - const float sqrt2amplitude = (float)std::sqrt(2*amplitude); - const int dx1 = width() - 1, dy1 = height() - 1, dz1 = depth() - 1; - CImg res(_width,_height,_depth,_spectrum,0), W(_width,_height,_depth,is_3d?4:3), val(_spectrum,1,1,1,0); - int N = 0; - if (is_3d) { // 3d version - for (float phi = (180%(int)da)/2.0f; phi<=180; phi+=da) { - const float phir = (float)(phi*cimg::PI/180), datmp = (float)(da/std::cos(phir)), - da2 = datmp<1?360.0f:datmp; - for (float theta = 0; theta<360; (theta+=da2),++N) { - const float - thetar = (float)(theta*cimg::PI/180), - vx = (float)(std::cos(thetar)*std::cos(phir)), - vy = (float)(std::sin(thetar)*std::cos(phir)), - vz = (float)std::sin(phir); - const t - *pa = G.data(0,0,0,0), *pb = G.data(0,0,0,1), *pc = G.data(0,0,0,2), - *pd = G.data(0,0,0,3), *pe = G.data(0,0,0,4), *pf = G.data(0,0,0,5); - Tfloat *pd0 = W.data(0,0,0,0), *pd1 = W.data(0,0,0,1), *pd2 = W.data(0,0,0,2), *pd3 = W.data(0,0,0,3); - cimg_forXYZ(G,xg,yg,zg) { - const t a = *(pa++), b = *(pb++), c = *(pc++), d = *(pd++), e = *(pe++), f = *(pf++); - const float - u = (float)(a*vx + b*vy + c*vz), - v = (float)(b*vx + d*vy + e*vz), - w = (float)(c*vx + e*vy + f*vz), - n = (float)std::sqrt(1e-5 + u*u + v*v + w*w), - dln = dl/n; - *(pd0++) = (Tfloat)(u*dln); - *(pd1++) = (Tfloat)(v*dln); - *(pd2++) = (Tfloat)(w*dln); - *(pd3++) = (Tfloat)n; - } - - cimg_abort_test(); - cimg_pragma_openmp(parallel for collapse(2) if (_width>=256 && _height*_depth>=2) firstprivate(val)) - cimg_forYZ(*this,y,z) cimg_abort_try2 { - cimg_abort_test2(); - cimg_forX(*this,x) { - val.fill(0); - const float - n = (float)W(x,y,z,3), - fsigma = (float)(n*sqrt2amplitude), - fsigma2 = 2*fsigma*fsigma, - length = gauss_prec*fsigma; - float - S = 0, - X = (float)x, - Y = (float)y, - Z = (float)z; - switch (interpolation_type) { - case 0 : { // Nearest neighbor - for (float l = 0; l=0 && X<=dx1 && Y>=0 && Y<=dy1 && Z>=0 && Z<=dz1; l+=dl) { - const int - cx = (int)(X + 0.5f), - cy = (int)(Y + 0.5f), - cz = (int)(Z + 0.5f); - const float - u = (float)W(cx,cy,cz,0), - v = (float)W(cx,cy,cz,1), - w = (float)W(cx,cy,cz,2); - if (is_fast_approx) { cimg_forC(*this,c) val[c]+=(Tfloat)(*this)(cx,cy,cz,c); ++S; } - else { - const float coef = (float)std::exp(-l*l/fsigma2); - cimg_forC(*this,c) val[c]+=(Tfloat)(coef*(*this)(cx,cy,cz,c)); - S+=coef; - } - X+=u; Y+=v; Z+=w; - } - } break; - case 1 : { // Linear interpolation - for (float l = 0; l=0 && X<=dx1 && Y>=0 && Y<=dy1 && Z>=0 && Z<=dz1; l+=dl) { - const float - u = (float)(W._linear_atXYZ(X,Y,Z,0)), - v = (float)(W._linear_atXYZ(X,Y,Z,1)), - w = (float)(W._linear_atXYZ(X,Y,Z,2)); - if (is_fast_approx) { cimg_forC(*this,c) val[c]+=(Tfloat)_linear_atXYZ(X,Y,Z,c); ++S; } - else { - const float coef = (float)std::exp(-l*l/fsigma2); - cimg_forC(*this,c) val[c]+=(Tfloat)(coef*_linear_atXYZ(X,Y,Z,c)); - S+=coef; - } - X+=u; Y+=v; Z+=w; - } - } break; - default : { // 2nd order Runge Kutta - for (float l = 0; l=0 && X<=dx1 && Y>=0 && Y<=dy1 && Z>=0 && Z<=dz1; l+=dl) { - const float - u0 = (float)(0.5f*W._linear_atXYZ(X,Y,Z,0)), - v0 = (float)(0.5f*W._linear_atXYZ(X,Y,Z,1)), - w0 = (float)(0.5f*W._linear_atXYZ(X,Y,Z,2)), - u = (float)(W._linear_atXYZ(X + u0,Y + v0,Z + w0,0)), - v = (float)(W._linear_atXYZ(X + u0,Y + v0,Z + w0,1)), - w = (float)(W._linear_atXYZ(X + u0,Y + v0,Z + w0,2)); - if (is_fast_approx) { cimg_forC(*this,c) val[c]+=(Tfloat)_linear_atXYZ(X,Y,Z,c); ++S; } - else { - const float coef = (float)std::exp(-l*l/fsigma2); - cimg_forC(*this,c) val[c]+=(Tfloat)(coef*_linear_atXYZ(X,Y,Z,c)); - S+=coef; - } - X+=u; Y+=v; Z+=w; - } - } break; - } - Tfloat *ptrd = res.data(x,y,z); - if (S>0) cimg_forC(res,c) { *ptrd+=val[c]/S; ptrd+=whd; } - else cimg_forC(res,c) { *ptrd+=(Tfloat)((*this)(x,y,z,c)); ptrd+=whd; } - } - } cimg_abort_catch2() - } - } - } else { // 2d LIC algorithm - for (float theta = (360%(int)da)/2.0f; theta<360; (theta+=da),++N) { - const float thetar = (float)(theta*cimg::PI/180), - vx = (float)(std::cos(thetar)), vy = (float)(std::sin(thetar)); - const t *pa = G.data(0,0,0,0), *pb = G.data(0,0,0,1), *pc = G.data(0,0,0,2); - Tfloat *pd0 = W.data(0,0,0,0), *pd1 = W.data(0,0,0,1), *pd2 = W.data(0,0,0,2); - cimg_forXY(G,xg,yg) { - const t a = *(pa++), b = *(pb++), c = *(pc++); - const float - u = (float)(a*vx + b*vy), - v = (float)(b*vx + c*vy), - n = (float)std::sqrt(1e-5 + u*u + v*v), - dln = dl/n; - *(pd0++) = (Tfloat)(u*dln); - *(pd1++) = (Tfloat)(v*dln); - *(pd2++) = (Tfloat)n; - } - - cimg_abort_test(); - cimg_pragma_openmp(parallel for cimg_openmp_if(_width>=256 && _height>=2) firstprivate(val)) - cimg_forY(*this,y) cimg_abort_try2 { - cimg_abort_test2(); - cimg_forX(*this,x) { - val.fill(0); - const float - n = (float)W(x,y,0,2), - fsigma = (float)(n*sqrt2amplitude), - fsigma2 = 2*fsigma*fsigma, - length = gauss_prec*fsigma; - float - S = 0, - X = (float)x, - Y = (float)y; - switch (interpolation_type) { - case 0 : { // Nearest-neighbor - for (float l = 0; l=0 && X<=dx1 && Y>=0 && Y<=dy1; l+=dl) { - const int - cx = (int)(X + 0.5f), - cy = (int)(Y + 0.5f); - const float - u = (float)W(cx,cy,0,0), - v = (float)W(cx,cy,0,1); - if (is_fast_approx) { cimg_forC(*this,c) val[c]+=(Tfloat)(*this)(cx,cy,0,c); ++S; } - else { - const float coef = (float)std::exp(-l*l/fsigma2); - cimg_forC(*this,c) val[c]+=(Tfloat)(coef*(*this)(cx,cy,0,c)); - S+=coef; - } - X+=u; Y+=v; - } - } break; - case 1 : { // Linear interpolation - for (float l = 0; l=0 && X<=dx1 && Y>=0 && Y<=dy1; l+=dl) { - const float - u = (float)(W._linear_atXY(X,Y,0,0)), - v = (float)(W._linear_atXY(X,Y,0,1)); - if (is_fast_approx) { cimg_forC(*this,c) val[c]+=(Tfloat)_linear_atXY(X,Y,0,c); ++S; } - else { - const float coef = (float)std::exp(-l*l/fsigma2); - cimg_forC(*this,c) val[c]+=(Tfloat)(coef*_linear_atXY(X,Y,0,c)); - S+=coef; - } - X+=u; Y+=v; - } - } break; - default : { // 2nd-order Runge-kutta interpolation - for (float l = 0; l=0 && X<=dx1 && Y>=0 && Y<=dy1; l+=dl) { - const float - u0 = (float)(0.5f*W._linear_atXY(X,Y,0,0)), - v0 = (float)(0.5f*W._linear_atXY(X,Y,0,1)), - u = (float)(W._linear_atXY(X + u0,Y + v0,0,0)), - v = (float)(W._linear_atXY(X + u0,Y + v0,0,1)); - if (is_fast_approx) { cimg_forC(*this,c) val[c]+=(Tfloat)_linear_atXY(X,Y,0,c); ++S; } - else { - const float coef = (float)std::exp(-l*l/fsigma2); - cimg_forC(*this,c) val[c]+=(Tfloat)(coef*_linear_atXY(X,Y,0,c)); - S+=coef; - } - X+=u; Y+=v; - } - } - } - Tfloat *ptrd = res.data(x,y); - if (S>0) cimg_forC(res,c) { *ptrd+=val[c]/S; ptrd+=whd; } - else cimg_forC(res,c) { *ptrd+=(Tfloat)((*this)(x,y,0,c)); ptrd+=whd; } - } - } cimg_abort_catch2() - } - } - const Tfloat *ptrs = res._data; - cimg_for(*this,ptrd,T) { - const Tfloat val = *(ptrs++)/N; - *ptrd = valval_max?val_max:(T)val); - } - } - cimg_abort_test(); - return *this; - } - - //! Blur image anisotropically, directed by a field of diffusion tensors \newinstance. - template - CImg get_blur_anisotropic(const CImg& G, - const float amplitude=60, const float dl=0.8f, const float da=30, - const float gauss_prec=2, const unsigned int interpolation_type=0, - const bool is_fast_approx=true) const { - return CImg(*this,false).blur_anisotropic(G,amplitude,dl,da,gauss_prec,interpolation_type,is_fast_approx); - } - - //! Blur image anisotropically, in an edge-preserving way. - /** - \param amplitude Amplitude of the smoothing. - \param sharpness Sharpness. - \param anisotropy Anisotropy. - \param alpha Standard deviation of the gradient blur. - \param sigma Standard deviation of the structure tensor blur. - \param dl Spatial discretization. - \param da Angular discretization. - \param gauss_prec Precision of the diffusion process. - \param interpolation_type Interpolation scheme. - Can be { 0=nearest-neighbor | 1=linear | 2=Runge-Kutta }. - \param is_fast_approx Tells if a fast approximation of the gaussian function is used or not. - **/ - CImg& blur_anisotropic(const float amplitude, const float sharpness=0.7f, const float anisotropy=0.6f, - const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f, const float da=30, - const float gauss_prec=2, const unsigned int interpolation_type=0, - const bool is_fast_approx=true) { - return blur_anisotropic(get_diffusion_tensors(sharpness,anisotropy,alpha,sigma,interpolation_type!=3), - amplitude,dl,da,gauss_prec,interpolation_type,is_fast_approx); - } - - //! Blur image anisotropically, in an edge-preserving way \newinstance. - CImg get_blur_anisotropic(const float amplitude, const float sharpness=0.7f, const float anisotropy=0.6f, - const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f, - const float da=30, const float gauss_prec=2, - const unsigned int interpolation_type=0, - const bool is_fast_approx=true) const { - return CImg(*this,false).blur_anisotropic(amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec, - interpolation_type,is_fast_approx); - } - - //! Blur image, with the joint bilateral filter. - /** - \param guide Image used to model the smoothing weights. - \param sigma_x Amount of blur along the X-axis. - \param sigma_y Amount of blur along the Y-axis. - \param sigma_z Amount of blur along the Z-axis. - \param sigma_r Amount of blur along the value axis. - \param sampling_x Amount of downsampling along the X-axis used for the approximation. - Defaults (0) to sigma_x. - \param sampling_y Amount of downsampling along the Y-axis used for the approximation. - Defaults (0) to sigma_y. - \param sampling_z Amount of downsampling along the Z-axis used for the approximation. - Defaults (0) to sigma_z. - \param sampling_r Amount of downsampling along the value axis used for the approximation. - Defaults (0) to sigma_r. - \note This algorithm uses the optimisation technique proposed by S. Paris and F. Durand, in ECCV'2006 - (extended for 3d volumetric images). - It is based on the reference implementation http://people.csail.mit.edu/jiawen/software/bilateralFilter.m - **/ - template - CImg& blur_bilateral(const CImg& guide, - const float sigma_x, const float sigma_y, - const float sigma_z, const float sigma_r, - const float sampling_x, const float sampling_y, - const float sampling_z, const float sampling_r) { - if (!is_sameXYZ(guide)) - throw CImgArgumentException(_cimg_instance - "blur_bilateral(): Invalid size for specified guide image (%u,%u,%u,%u,%p).", - cimg_instance, - guide._width,guide._height,guide._depth,guide._spectrum,guide._data); - if (is_empty()) return *this; - T edge_min, edge_max = guide.max_min(edge_min); - if (edge_min==edge_max || sigma_r==0) return *this; - const float - edge_delta = (float)(edge_max - edge_min), - _sigma_x = sigma_x>=0?sigma_x:-sigma_x*_width/100, - _sigma_y = sigma_y>=0?sigma_y:-sigma_y*_height/100, - _sigma_z = sigma_z>=0?sigma_z:-sigma_z*_depth/100, - _sigma_r = sigma_r>=0?sigma_r:-sigma_r*(edge_max - edge_min)/100, - _sampling_x = sampling_x?sampling_x:cimg::max(_sigma_x,1.0f), - _sampling_y = sampling_y?sampling_y:cimg::max(_sigma_y,1.0f), - _sampling_z = sampling_z?sampling_z:cimg::max(_sigma_z,1.0f), - _sampling_r = sampling_r?sampling_r:cimg::max(_sigma_r,edge_delta/256), - derived_sigma_x = _sigma_x / _sampling_x, - derived_sigma_y = _sigma_y / _sampling_y, - derived_sigma_z = _sigma_z / _sampling_z, - derived_sigma_r = _sigma_r / _sampling_r; - const int - padding_x = (int)(2*derived_sigma_x) + 1, - padding_y = (int)(2*derived_sigma_y) + 1, - padding_z = (int)(2*derived_sigma_z) + 1, - padding_r = (int)(2*derived_sigma_r) + 1; - const unsigned int - bx = (unsigned int)((_width - 1)/_sampling_x + 1 + 2*padding_x), - by = (unsigned int)((_height - 1)/_sampling_y + 1 + 2*padding_y), - bz = (unsigned int)((_depth - 1)/_sampling_z + 1 + 2*padding_z), - br = (unsigned int)(edge_delta/_sampling_r + 1 + 2*padding_r); - if (bx>0 || by>0 || bz>0 || br>0) { - const bool is_3d = (_depth>1); - if (is_3d) { // 3d version of the algorithm - CImg bgrid(bx,by,bz,br), bgridw(bx,by,bz,br); - cimg_forC(*this,c) { - const CImg _guide = guide.get_shared_channel(c%guide._spectrum); - bgrid.fill(0); bgridw.fill(0); - cimg_forXYZ(*this,x,y,z) { - const T val = (*this)(x,y,z,c); - const float edge = (float)_guide(x,y,z); - const int - X = (int)cimg::round(x/_sampling_x) + padding_x, - Y = (int)cimg::round(y/_sampling_y) + padding_y, - Z = (int)cimg::round(z/_sampling_z) + padding_z, - R = (int)cimg::round((edge-edge_min)/_sampling_r) + padding_r; - bgrid(X,Y,Z,R)+=(float)val; - bgridw(X,Y,Z,R)+=1; - } - bgrid.blur(derived_sigma_x,derived_sigma_y,derived_sigma_z,true).deriche(derived_sigma_r,0,'c',false); - bgridw.blur(derived_sigma_x,derived_sigma_y,derived_sigma_z,true).deriche(derived_sigma_r,0,'c',false); - cimg_forXYZ(*this,x,y,z) { - const float edge = (float)_guide(x,y,z); - const float - X = x/_sampling_x + padding_x, - Y = y/_sampling_y + padding_y, - Z = z/_sampling_z + padding_z, - R = (edge-edge_min)/_sampling_r + padding_r; - const float bval0 = bgrid.linear_atXYZC(X,Y,Z,R), bval1 = bgridw.linear_atXYZC(X,Y,Z,R); - (*this)(x,y,z,c) = (T)(bval0/bval1); - } - } - } else { // 2d version of the algorithm - CImg bgrid(bx,by,br,2); - cimg_forC(*this,c) { - const CImg _guide = guide.get_shared_channel(c%guide._spectrum); - bgrid.fill(0); - cimg_forXY(*this,x,y) { - const T val = (*this)(x,y,c); - const float edge = (float)_guide(x,y); - const int - X = (int)cimg::round(x/_sampling_x) + padding_x, - Y = (int)cimg::round(y/_sampling_y) + padding_y, - R = (int)cimg::round((edge-edge_min)/_sampling_r) + padding_r; - bgrid(X,Y,R,0)+=(float)val; - bgrid(X,Y,R,1)+=1; - } - bgrid.blur(derived_sigma_x,derived_sigma_y,0,true).blur(0,0,derived_sigma_r,false); - cimg_forXY(*this,x,y) { - const float edge = (float)_guide(x,y); - const float - X = x/_sampling_x + padding_x, - Y = y/_sampling_y + padding_y, - R = (edge-edge_min)/_sampling_r + padding_r; - const float bval0 = bgrid.linear_atXYZ(X,Y,R,0), bval1 = bgrid.linear_atXYZ(X,Y,R,1); - (*this)(x,y,c) = (T)(bval0/bval1); - } - } - } - } - return *this; - } - - //! Blur image, with the joint bilateral filter \newinstance. - template - CImg get_blur_bilateral(const CImg& guide, - const float sigma_x, const float sigma_y, - const float sigma_z, const float sigma_r, - const float sampling_x, const float sampling_y, - const float sampling_z, const float sampling_r) const { - return CImg(*this,false).blur_bilateral(guide,sigma_x,sigma_y,sigma_z,sigma_r, - sampling_x,sampling_y,sampling_z,sampling_r); - } - - //! Blur image using the joint bilateral filter. - /** - \param guide Image used to model the smoothing weights. - \param sigma_s Amount of blur along the XYZ-axes. - \param sigma_r Amount of blur along the value axis. - \param sampling_s Amount of downsampling along the XYZ-axes used for the approximation. Defaults to sigma_s. - \param sampling_r Amount of downsampling along the value axis used for the approximation. Defaults to sigma_r. - **/ - template - CImg& blur_bilateral(const CImg& guide, - const float sigma_s, const float sigma_r, - const float sampling_s=0, const float sampling_r=0) { - const float _sigma_s = sigma_s>=0?sigma_s:-sigma_s*cimg::max(_width,_height,_depth)/100; - return blur_bilateral(guide,_sigma_s,_sigma_s,_sigma_s,sigma_r,sampling_s,sampling_s,sampling_s,sampling_r); - } - - //! Blur image using the bilateral filter \newinstance. - template - CImg get_blur_bilateral(const CImg& guide, - const float sigma_s, const float sigma_r, - const float sampling_s=0, const float sampling_r=0) const { - return CImg(*this,false).blur_bilateral(guide,sigma_s,sigma_r,sampling_s,sampling_r); - } - - // [internal] Apply a box filter (used by CImg::boxfilter() and CImg::blur_box()). - /* - \param ptr the pointer of the data - \param N size of the data - \param boxsize Size of the box filter (can be subpixel). - \param off the offset between two data point - \param order the order of the filter 0 (smoothing), 1st derivtive and 2nd derivative. - \param boundary_conditions Boundary conditions. Can be { 0=dirichlet | 1=neumann }. - */ - static void _cimg_blur_box_apply(T *ptr, const float boxsize, const int N, const ulongT off, - const int order, const bool boundary_conditions) { - // Smooth. - if (boxsize>1) { - const int w2 = (int)(boxsize - 1)/2; - const unsigned int winsize = 2*w2 + 1U; - const double frac = (boxsize - winsize)/2.0; - CImg win(winsize); - Tfloat sum = 0; // window sum - for (int x = -w2; x<=w2; ++x) { - win[x + w2] = __cimg_blur_box_apply(ptr,N,off,boundary_conditions,x); - sum+=win[x + w2]; - } - int ifirst = 0, ilast = 2*w2; - Tfloat - prev = __cimg_blur_box_apply(ptr,N,off,boundary_conditions,-w2 - 1), - next = __cimg_blur_box_apply(ptr,N,off,boundary_conditions,w2 + 1); - for (int x = 0; x < N - 1; ++x) { - const double sum2 = sum + frac * (prev + next); - ptr[x*off] = (T)(sum2/boxsize); - prev = win[ifirst]; - sum-=prev; - ifirst = (int)((ifirst + 1)%winsize); - ilast = (int)((ilast + 1)%winsize); - win[ilast] = next; - sum+=next; - next = __cimg_blur_box_apply(ptr,N,off,boundary_conditions,x + w2 + 2); - } - const double sum2 = sum + frac * (prev + next); - ptr[(N - 1)*off] = (T)(sum2/boxsize); - } - - // Derive. - switch (order) { - case 0 : - break; - case 1 : { - Tfloat - p = __cimg_blur_box_apply(ptr,N,off,boundary_conditions,-1), - c = __cimg_blur_box_apply(ptr,N,off,boundary_conditions,0), - n = __cimg_blur_box_apply(ptr,N,off,boundary_conditions,1); - for (int x = 0; x=N) return boundary_conditions?ptr[(N - 1)*off]:T(); - return ptr[x*off]; - } - - // Apply box filter of order 0,1,2. - /** - \param boxsize Size of the box window (can be subpixel) - \param order the order of the filter 0,1 or 2. - \param axis Axis along which the filter is computed. Can be { 'x' | 'y' | 'z' | 'c' }. - \param boundary_conditions Boundary conditions. Can be { 0=dirichlet | 1=neumann }. - **/ - CImg& boxfilter(const float boxsize, const int order, const char axis='x', - const bool boundary_conditions=true) { - if (is_empty() || !boxsize || (boxsize<=1 && !order)) return *this; - const char naxis = cimg::lowercase(axis); - const float nboxsize = boxsize>=0?boxsize:-boxsize* - (naxis=='x'?_width:naxis=='y'?_height:naxis=='z'?_depth:_spectrum)/100; - switch (naxis) { - case 'x' : { - cimg_pragma_openmp(parallel for collapse(3) if (_width>=256 && _height*_depth*_spectrum>=16)) - cimg_forYZC(*this,y,z,c) - _cimg_blur_box_apply(data(0,y,z,c),nboxsize,_width,1U,order,boundary_conditions); - } break; - case 'y' : { - cimg_pragma_openmp(parallel for collapse(3) if (_width>=256 && _height*_depth*_spectrum>=16)) - cimg_forXZC(*this,x,z,c) - _cimg_blur_box_apply(data(x,0,z,c),nboxsize,_height,(ulongT)_width,order,boundary_conditions); - } break; - case 'z' : { - cimg_pragma_openmp(parallel for collapse(3) if (_width>=256 && _height*_depth*_spectrum>=16)) - cimg_forXYC(*this,x,y,c) - _cimg_blur_box_apply(data(x,y,0,c),nboxsize,_depth,(ulongT)_width*_height,order,boundary_conditions); - } break; - default : { - cimg_pragma_openmp(parallel for collapse(3) if (_width>=256 && _height*_depth*_spectrum>=16)) - cimg_forXYZ(*this,x,y,z) - _cimg_blur_box_apply(data(x,y,z,0),nboxsize,_spectrum,(ulongT)_width*_height*_depth, - order,boundary_conditions); - } - } - return *this; - } - - // Apply box filter of order 0,1 or 2 \newinstance. - CImg get_boxfilter(const float boxsize, const int order, const char axis='x', - const bool boundary_conditions=true) const { - return CImg(*this,false).boxfilter(boxsize,order,axis,boundary_conditions); - } - - //! Blur image with a box filter. - /** - \param boxsize_x Size of the box window, along the X-axis (can be subpixel). - \param boxsize_y Size of the box window, along the Y-axis (can be subpixel). - \param boxsize_z Size of the box window, along the Z-axis (can be subpixel). - \param boundary_conditions Boundary conditions. Can be { false=dirichlet | true=neumann }. - \note - - This is a recursive algorithm, not depending on the values of the box kernel size. - \see blur(). - **/ - CImg& blur_box(const float boxsize_x, const float boxsize_y, const float boxsize_z, - const bool boundary_conditions=true) { - if (is_empty()) return *this; - if (_width>1) boxfilter(boxsize_x,0,'x',boundary_conditions); - if (_height>1) boxfilter(boxsize_y,0,'y',boundary_conditions); - if (_depth>1) boxfilter(boxsize_z,0,'z',boundary_conditions); - return *this; - } - - //! Blur image with a box filter \newinstance. - CImg get_blur_box(const float boxsize_x, const float boxsize_y, const float boxsize_z, - const bool boundary_conditions=true) const { - return CImg(*this,false).blur_box(boxsize_x,boxsize_y,boxsize_z,boundary_conditions); - } - - //! Blur image with a box filter. - /** - \param boxsize Size of the box window (can be subpixel). - \param boundary_conditions Boundary conditions. Can be { 0=dirichlet | 1=neumann }.a - \see deriche(), vanvliet(). - **/ - CImg& blur_box(const float boxsize, const bool boundary_conditions=true) { - const float nboxsize = boxsize>=0?boxsize:-boxsize*cimg::max(_width,_height,_depth)/100; - return blur_box(nboxsize,nboxsize,nboxsize,boundary_conditions); - } - - //! Blur image with a box filter \newinstance. - CImg get_blur_box(const float boxsize, const bool boundary_conditions=true) const { - return CImg(*this,false).blur_box(boxsize,boundary_conditions); - } - - //! Blur image, with the image guided filter. - /** - \param guide Image used to guide the smoothing process. - \param radius Spatial radius. If negative, it is expressed as a percentage of the largest image size. - \param regularization Regularization parameter. If negative, it is expressed as a percentage of the guide value range. - \note This method implements the filtering algorithm described in: - He, Kaiming; Sun, Jian; Tang, Xiaoou, "Guided Image Filtering," Pattern Analysis and Machine Intelligence, - IEEE Transactions on , vol.35, no.6, pp.1397,1409, June 2013 - **/ - template - CImg& blur_guided(const CImg& guide, const float radius, const float regularization) { - return get_blur_guided(guide,radius,regularization).move_to(*this); - } - - //! Blur image, with the image guided filter \newinstance. - template - CImg get_blur_guided(const CImg& guide, const float radius, const float regularization) const { - if (!is_sameXYZ(guide)) - throw CImgArgumentException(_cimg_instance - "blur_guided(): Invalid size for specified guide image (%u,%u,%u,%u,%p).", - cimg_instance, - guide._width,guide._height,guide._depth,guide._spectrum,guide._data); - if (is_empty() || !radius || !regularization) return *this; - const int _radius = radius>=0?(int)radius:(int)(-radius*cimg::max(_width,_height,_depth)/100); - float _regularization = regularization; - if (regularization<0) { - T edge_min, edge_max = guide.max_min(edge_min); - if (edge_min==edge_max) return *this; - _regularization = -regularization*(edge_max - edge_min)/100; - } - const unsigned int psize = (unsigned int)(1 + 2*_radius); - const CImg N = CImg(_width,_height,_depth,1,1)._blur_guided(psize); - CImg - mean_I = CImg(guide,false)._blur_guided(psize).div(N), - mean_p = CImg(*this,false)._blur_guided(psize).div(N), - cov_Ip = CImg(*this,false).mul(guide)._blur_guided(psize).div(N)-=mean_p.get_mul(mean_I), - var_I = CImg(guide,false).sqr()._blur_guided(psize).div(N)-=mean_I.get_sqr(), - &a = cov_Ip.div(var_I+=_regularization), - &b = mean_p-=a.get_mul(mean_I); - a._blur_guided(psize).div(N); - b._blur_guided(psize).div(N); - return a.mul(guide)+=b; - } - - // [internal] Perform box filter with dirichlet boundary conditions. - CImg& _blur_guided(const unsigned int psize) { - const int p1 = (int)psize/2, p2 = (int)psize - p1; - if (_depth!=1) { - CImg cumul = get_cumulate('z'), cumul2 = cumul.get_shift(0,0,p2,0,1); - (cumul.shift(0,0,-p1,0,1)-=cumul2).move_to(*this); - } - if (_height!=1) { - CImg cumul = get_cumulate('y'), cumul2 = cumul.get_shift(0,p2,0,0,1); - (cumul.shift(0,-p1,0,0,1)-=cumul2).move_to(*this); - } - if (_width!=1) { - CImg cumul = get_cumulate('x'), cumul2 = cumul.get_shift(p2,0,0,0,1); - (cumul.shift(-p1,0,0,0,1)-=cumul2).move_to(*this); - } - return *this; - } - - //! Blur image using patch-based space. - /** - \param sigma_s Amount of blur along the XYZ-axes. - \param sigma_p Amount of blur along the value axis. - \param patch_size Size of the patchs. - \param lookup_size Size of the window to search similar patchs. - \param smoothness Smoothness for the patch comparison. - \param is_fast_approx Tells if a fast approximation of the gaussian function is used or not. - **/ - CImg& blur_patch(const float sigma_s, const float sigma_p, const unsigned int patch_size=3, - const unsigned int lookup_size=4, const float smoothness=0, const bool is_fast_approx=true) { - if (is_empty() || !patch_size || !lookup_size) return *this; - return get_blur_patch(sigma_s,sigma_p,patch_size,lookup_size,smoothness,is_fast_approx).move_to(*this); - } - - //! Blur image using patch-based space \newinstance. - CImg get_blur_patch(const float sigma_s, const float sigma_p, const unsigned int patch_size=3, - const unsigned int lookup_size=4, const float smoothness=0, - const bool is_fast_approx=true) const { - -#define _cimg_blur_patch3d_fast(N) \ - cimg_for##N##XYZ(res,x,y,z) { \ - T *pP = P._data; cimg_forC(res,c) { cimg_get##N##x##N##x##N(img,x,y,z,c,pP,T); pP+=N3; } \ - const int x0 = x - rsize1, y0 = y - rsize1, z0 = z - rsize1, \ - x1 = x + rsize2, y1 = y + rsize2, z1 = z + rsize2; \ - float sum_weights = 0; \ - cimg_for_in##N##XYZ(res,x0,y0,z0,x1,y1,z1,p,q,r) if (cimg::abs(img(x,y,z,0) - img(p,q,r,0))3?0.0f:1.0f; \ - sum_weights+=weight; \ - cimg_forC(res,c) res(x,y,z,c)+=weight*(*this)(p,q,r,c); \ - } \ - if (sum_weights>0) cimg_forC(res,c) res(x,y,z,c)/=sum_weights; \ - else cimg_forC(res,c) res(x,y,z,c) = (Tfloat)((*this)(x,y,z,c)); \ - } - -#define _cimg_blur_patch3d(N) \ - cimg_for##N##XYZ(res,x,y,z) { \ - T *pP = P._data; cimg_forC(res,c) { cimg_get##N##x##N##x##N(img,x,y,z,c,pP,T); pP+=N3; } \ - const int x0 = x - rsize1, y0 = y - rsize1, z0 = z - rsize1, \ - x1 = x + rsize2, y1 = y + rsize2, z1 = z + rsize2; \ - float sum_weights = 0, weight_max = 0; \ - cimg_for_in##N##XYZ(res,x0,y0,z0,x1,y1,z1,p,q,r) if (p!=x || q!=y || r!=z) { \ - T *pQ = Q._data; cimg_forC(res,c) { cimg_get##N##x##N##x##N(img,p,q,r,c,pQ,T); pQ+=N3; } \ - float distance2 = 0; \ - pQ = Q._data; cimg_for(P,pP,T) { const float dI = (float)*pP - (float)*(pQ++); distance2+=dI*dI; } \ - distance2/=Pnorm; \ - const float dx = (float)p - x, dy = (float)q - y, dz = (float)r - z, \ - alldist = distance2 + (dx*dx + dy*dy + dz*dz)/sigma_s2, weight = (float)std::exp(-alldist); \ - if (weight>weight_max) weight_max = weight; \ - sum_weights+=weight; \ - cimg_forC(res,c) res(x,y,z,c)+=weight*(*this)(p,q,r,c); \ - } \ - sum_weights+=weight_max; cimg_forC(res,c) res(x,y,z,c)+=weight_max*(*this)(x,y,z,c); \ - if (sum_weights>0) cimg_forC(res,c) res(x,y,z,c)/=sum_weights; \ - else cimg_forC(res,c) res(x,y,z,c) = (Tfloat)((*this)(x,y,z,c)); \ - } - -#define _cimg_blur_patch2d_fast(N) \ - cimg_for##N##XY(res,x,y) { \ - T *pP = P._data; cimg_forC(res,c) { cimg_get##N##x##N(img,x,y,0,c,pP,T); pP+=N2; } \ - const int x0 = x - rsize1, y0 = y - rsize1, x1 = x + rsize2, y1 = y + rsize2; \ - float sum_weights = 0; \ - cimg_for_in##N##XY(res,x0,y0,x1,y1,p,q) if (cimg::abs(img(x,y,0,0) - img(p,q,0,0))3?0.0f:1.0f; \ - sum_weights+=weight; \ - cimg_forC(res,c) res(x,y,c)+=weight*(*this)(p,q,c); \ - } \ - if (sum_weights>0) cimg_forC(res,c) res(x,y,c)/=sum_weights; \ - else cimg_forC(res,c) res(x,y,c) = (Tfloat)((*this)(x,y,c)); \ - } - -#define _cimg_blur_patch2d(N) \ - cimg_for##N##XY(res,x,y) { \ - T *pP = P._data; cimg_forC(res,c) { cimg_get##N##x##N(img,x,y,0,c,pP,T); pP+=N2; } \ - const int x0 = x - rsize1, y0 = y - rsize1, x1 = x + rsize2, y1 = y + rsize2; \ - float sum_weights = 0, weight_max = 0; \ - cimg_for_in##N##XY(res,x0,y0,x1,y1,p,q) if (p!=x || q!=y) { \ - T *pQ = Q._data; cimg_forC(res,c) { cimg_get##N##x##N(img,p,q,0,c,pQ,T); pQ+=N2; } \ - float distance2 = 0; \ - pQ = Q._data; cimg_for(P,pP,T) { const float dI = (float)*pP - (float)*(pQ++); distance2+=dI*dI; } \ - distance2/=Pnorm; \ - const float dx = (float)p - x, dy = (float)q - y, \ - alldist = distance2 + (dx*dx+dy*dy)/sigma_s2, weight = (float)std::exp(-alldist); \ - if (weight>weight_max) weight_max = weight; \ - sum_weights+=weight; \ - cimg_forC(res,c) res(x,y,c)+=weight*(*this)(p,q,c); \ - } \ - sum_weights+=weight_max; cimg_forC(res,c) res(x,y,c)+=weight_max*(*this)(x,y,c); \ - if (sum_weights>0) cimg_forC(res,c) res(x,y,c)/=sum_weights; \ - else cimg_forC(res,c) res(x,y,c) = (Tfloat)((*this)(x,y,c)); \ - } - - if (is_empty() || !patch_size || !lookup_size) return +*this; - CImg res(_width,_height,_depth,_spectrum,0); - const CImg _img = smoothness>0?get_blur(smoothness):CImg(),&img = smoothness>0?_img:*this; - CImg P(patch_size*patch_size*_spectrum), Q(P); - const float - nsigma_s = sigma_s>=0?sigma_s:-sigma_s*cimg::max(_width,_height,_depth)/100, - sigma_s2 = nsigma_s*nsigma_s, sigma_p2 = sigma_p*sigma_p, sigma_p3 = 3*sigma_p, - Pnorm = P.size()*sigma_p2; - const int rsize2 = (int)lookup_size/2, rsize1 = (int)lookup_size - rsize2 - 1; - const unsigned int N2 = patch_size*patch_size, N3 = N2*patch_size; - cimg::unused(N2,N3); - if (_depth>1) switch (patch_size) { // 3d - case 2 : if (is_fast_approx) _cimg_blur_patch3d_fast(2) else _cimg_blur_patch3d(2) break; - case 3 : if (is_fast_approx) _cimg_blur_patch3d_fast(3) else _cimg_blur_patch3d(3) break; - default : { - const int psize2 = (int)patch_size/2, psize1 = (int)patch_size - psize2 - 1; - if (is_fast_approx) - cimg_pragma_openmp(parallel for collapse(2) if (res._width>=32 && res._height*res._depth>=4) private(P,Q)) - cimg_forXYZ(res,x,y,z) { // Fast - P = img.get_crop(x - psize1,y - psize1,z - psize1,x + psize2,y + psize2,z + psize2,true); - const int x0 = x - rsize1, y0 = y - rsize1, z0 = z - rsize1, - x1 = x + rsize2, y1 = y + rsize2, z1 = z + rsize2; - float sum_weights = 0; - cimg_for_inXYZ(res,x0,y0,z0,x1,y1,z1,p,q,r) if (cimg::abs(img(x,y,z,0)-img(p,q,r,0))3?0.0f:1.0f; - sum_weights+=weight; - cimg_forC(res,c) res(x,y,z,c)+=weight*(*this)(p,q,r,c); - } - if (sum_weights>0) cimg_forC(res,c) res(x,y,z,c)/=sum_weights; - else cimg_forC(res,c) res(x,y,z,c) = (Tfloat)((*this)(x,y,z,c)); - } else - cimg_pragma_openmp(parallel for collapse(2) - if (res._width>=32 && res._height*res._depth>=4) firstprivate(P,Q)) - cimg_forXYZ(res,x,y,z) { // Exact - P = img.get_crop(x - psize1,y - psize1,z - psize1,x + psize2,y + psize2,z + psize2,true); - const int x0 = x - rsize1, y0 = y - rsize1, z0 = z - rsize1, - x1 = x + rsize2, y1 = y + rsize2, z1 = z + rsize2; - float sum_weights = 0, weight_max = 0; - cimg_for_inXYZ(res,x0,y0,z0,x1,y1,z1,p,q,r) if (p!=x || q!=y || r!=z) { - (Q = img.get_crop(p - psize1,q - psize1,r - psize1,p + psize2,q + psize2,r + psize2,true))-=P; - const float - dx = (float)x - p, dy = (float)y - q, dz = (float)z - r, - distance2 = (float)(Q.pow(2).sum()/Pnorm + (dx*dx + dy*dy + dz*dz)/sigma_s2), - weight = (float)std::exp(-distance2); - if (weight>weight_max) weight_max = weight; - sum_weights+=weight; - cimg_forC(res,c) res(x,y,z,c)+=weight*(*this)(p,q,r,c); - } - sum_weights+=weight_max; cimg_forC(res,c) res(x,y,z,c)+=weight_max*(*this)(x,y,z,c); - if (sum_weights>0) cimg_forC(res,c) res(x,y,z,c)/=sum_weights; - else cimg_forC(res,c) res(x,y,z,c) = (Tfloat)((*this)(x,y,z,c)); - } - } - } else switch (patch_size) { // 2d - case 2 : if (is_fast_approx) _cimg_blur_patch2d_fast(2) else _cimg_blur_patch2d(2) break; - case 3 : if (is_fast_approx) _cimg_blur_patch2d_fast(3) else _cimg_blur_patch2d(3) break; - case 4 : if (is_fast_approx) _cimg_blur_patch2d_fast(4) else _cimg_blur_patch2d(4) break; - case 5 : if (is_fast_approx) _cimg_blur_patch2d_fast(5) else _cimg_blur_patch2d(5) break; - case 6 : if (is_fast_approx) _cimg_blur_patch2d_fast(6) else _cimg_blur_patch2d(6) break; - case 7 : if (is_fast_approx) _cimg_blur_patch2d_fast(7) else _cimg_blur_patch2d(7) break; - case 8 : if (is_fast_approx) _cimg_blur_patch2d_fast(8) else _cimg_blur_patch2d(8) break; - case 9 : if (is_fast_approx) _cimg_blur_patch2d_fast(9) else _cimg_blur_patch2d(9) break; - default : { // Fast - const int psize2 = (int)patch_size/2, psize1 = (int)patch_size - psize2 - 1; - if (is_fast_approx) - cimg_pragma_openmp(parallel for cimg_openmp_if(res._width>=32 && res._height>=4) firstprivate(P,Q)) - cimg_forXY(res,x,y) { // 2d fast approximation. - P = img.get_crop(x - psize1,y - psize1,x + psize2,y + psize2,true); - const int x0 = x - rsize1, y0 = y - rsize1, x1 = x + rsize2, y1 = y + rsize2; - float sum_weights = 0; - cimg_for_inXY(res,x0,y0,x1,y1,p,q) if (cimg::abs(img(x,y,0)-img(p,q,0))3?0.0f:1.0f; - sum_weights+=weight; - cimg_forC(res,c) res(x,y,c)+=weight*(*this)(p,q,c); - } - if (sum_weights>0) cimg_forC(res,c) res(x,y,c)/=sum_weights; - else cimg_forC(res,c) res(x,y,c) = (Tfloat)((*this)(x,y,c)); - } else - cimg_pragma_openmp(parallel for cimg_openmp_if(res._width>=32 && res._height>=4) firstprivate(P,Q)) - cimg_forXY(res,x,y) { // 2d exact algorithm. - P = img.get_crop(x - psize1,y - psize1,x + psize2,y + psize2,true); - const int x0 = x - rsize1, y0 = y - rsize1, x1 = x + rsize2, y1 = y + rsize2; - float sum_weights = 0, weight_max = 0; - cimg_for_inXY(res,x0,y0,x1,y1,p,q) if (p!=x || q!=y) { - (Q = img.get_crop(p - psize1,q - psize1,p + psize2,q + psize2,true))-=P; - const float - dx = (float)x - p, dy = (float)y - q, - distance2 = (float)(Q.pow(2).sum()/Pnorm + (dx*dx + dy*dy)/sigma_s2), - weight = (float)std::exp(-distance2); - if (weight>weight_max) weight_max = weight; - sum_weights+=weight; - cimg_forC(res,c) res(x,y,c)+=weight*(*this)(p,q,c); - } - sum_weights+=weight_max; cimg_forC(res,c) res(x,y,c)+=weight_max*(*this)(x,y,c); - if (sum_weights>0) cimg_forC(res,c) res(x,y,c)/=sum_weights; - else cimg_forC(res,c) res(x,y,0,c) = (Tfloat)((*this)(x,y,c)); - } - } - } - return res; - } - - //! Blur image with the median filter. - /** - \param n Size of the median filter. - \param threshold Threshold used to discard pixels too far from the current pixel value in the median computation. - **/ - CImg& blur_median(const unsigned int n, const float threshold=0) { - if (!n) return *this; - return get_blur_median(n,threshold).move_to(*this); - } - - //! Blur image with the median filter \newinstance. - CImg get_blur_median(const unsigned int n, const float threshold=0) const { - if (is_empty() || n<=1) return +*this; - CImg res(_width,_height,_depth,_spectrum); - T *ptrd = res._data; - cimg::unused(ptrd); - const int hl = (int)n/2, hr = hl - 1 + (int)n%2; - if (res._depth!=1) { // 3d - if (threshold>0) - cimg_pragma_openmp(parallel for collapse(3) if (_width>=16 && _height*_depth*_spectrum>=4)) - cimg_forXYZC(*this,x,y,z,c) { // With threshold. - const int - x0 = x - hl, y0 = y - hl, z0 = z - hl, x1 = x + hr, y1 = y + hr, z1 = z + hr, - nx0 = x0<0?0:x0, ny0 = y0<0?0:y0, nz0 = z0<0?0:z0, - nx1 = x1>=width()?width() - 1:x1, ny1 = y1>=height()?height() - 1:y1, nz1 = z1>=depth()?depth() - 1:z1; - const float val0 = (float)(*this)(x,y,z,c); - CImg values(n*n*n); - unsigned int nb_values = 0; - T *ptrd = values.data(); - cimg_for_inXYZ(*this,nx0,ny0,nz0,nx1,ny1,nz1,p,q,r) - if (cimg::abs((float)(*this)(p,q,r,c)-val0)<=threshold) { *(ptrd++) = (*this)(p,q,r,c); ++nb_values; } - res(x,y,z,c) = values.get_shared_points(0,nb_values - 1).median(); - } - else - cimg_pragma_openmp(parallel for collapse(3) if (_width>=16 && _height*_depth*_spectrum>=4)) - cimg_forXYZC(*this,x,y,z,c) { // Without threshold. - const int - x0 = x - hl, y0 = y - hl, z0 = z - hl, x1 = x + hr, y1 = y + hr, z1 = z + hr, - nx0 = x0<0?0:x0, ny0 = y0<0?0:y0, nz0 = z0<0?0:z0, - nx1 = x1>=width()?width() - 1:x1, ny1 = y1>=height()?height() - 1:y1, nz1 = z1>=depth()?depth() - 1:z1; - res(x,y,z,c) = get_crop(nx0,ny0,nz0,c,nx1,ny1,nz1,c).median(); - } - } else { -#define _cimg_median_sort(a,b) if ((a)>(b)) cimg::swap(a,b) - if (res._height!=1) { // 2d - if (threshold>0) - cimg_pragma_openmp(parallel for collapse(2) if (_width>=16 && _height*_spectrum>=4)) - cimg_forXYC(*this,x,y,c) { // With threshold. - const int - x0 = x - hl, y0 = y - hl, x1 = x + hr, y1 = y + hr, - nx0 = x0<0?0:x0, ny0 = y0<0?0:y0, - nx1 = x1>=width()?width() - 1:x1, ny1 = y1>=height()?height() - 1:y1; - const float val0 = (float)(*this)(x,y,c); - CImg values(n*n); - unsigned int nb_values = 0; - T *ptrd = values.data(); - cimg_for_inXY(*this,nx0,ny0,nx1,ny1,p,q) - if (cimg::abs((float)(*this)(p,q,c)-val0)<=threshold) { *(ptrd++) = (*this)(p,q,c); ++nb_values; } - res(x,y,c) = values.get_shared_points(0,nb_values - 1).median(); - } - else switch (n) { // Without threshold. - case 3 : { - cimg_pragma_openmp(parallel for cimg_openmp_if(_spectrum>=2)) - cimg_forC(*this,c) { - T I[9] = { 0 }; - CImg_3x3(J,T); - cimg_for3x3(*this,x,y,0,c,I,T) { - std::memcpy(J,I,9*sizeof(T)); - _cimg_median_sort(Jcp, Jnp); _cimg_median_sort(Jcc, Jnc); _cimg_median_sort(Jcn, Jnn); - _cimg_median_sort(Jpp, Jcp); _cimg_median_sort(Jpc, Jcc); _cimg_median_sort(Jpn, Jcn); - _cimg_median_sort(Jcp, Jnp); _cimg_median_sort(Jcc, Jnc); _cimg_median_sort(Jcn, Jnn); - _cimg_median_sort(Jpp, Jpc); _cimg_median_sort(Jnc, Jnn); _cimg_median_sort(Jcc, Jcn); - _cimg_median_sort(Jpc, Jpn); _cimg_median_sort(Jcp, Jcc); _cimg_median_sort(Jnp, Jnc); - _cimg_median_sort(Jcc, Jcn); _cimg_median_sort(Jcc, Jnp); _cimg_median_sort(Jpn, Jcc); - _cimg_median_sort(Jcc, Jnp); - res(x,y,c) = Jcc; - } - } - } break; - case 5 : { - cimg_pragma_openmp(parallel for cimg_openmp_if(_spectrum>=2)) - cimg_forC(*this,c) { - T I[25] = { 0 }; - CImg_5x5(J,T); - cimg_for5x5(*this,x,y,0,c,I,T) { - std::memcpy(J,I,25*sizeof(T)); - _cimg_median_sort(Jbb,Jpb); _cimg_median_sort(Jnb,Jab); _cimg_median_sort(Jcb,Jab); - _cimg_median_sort(Jcb,Jnb); _cimg_median_sort(Jpp,Jcp); _cimg_median_sort(Jbp,Jcp); - _cimg_median_sort(Jbp,Jpp); _cimg_median_sort(Jap,Jbc); _cimg_median_sort(Jnp,Jbc); - _cimg_median_sort(Jnp,Jap); _cimg_median_sort(Jcc,Jnc); _cimg_median_sort(Jpc,Jnc); - _cimg_median_sort(Jpc,Jcc); _cimg_median_sort(Jbn,Jpn); _cimg_median_sort(Jac,Jpn); - _cimg_median_sort(Jac,Jbn); _cimg_median_sort(Jnn,Jan); _cimg_median_sort(Jcn,Jan); - _cimg_median_sort(Jcn,Jnn); _cimg_median_sort(Jpa,Jca); _cimg_median_sort(Jba,Jca); - _cimg_median_sort(Jba,Jpa); _cimg_median_sort(Jna,Jaa); _cimg_median_sort(Jcb,Jbp); - _cimg_median_sort(Jnb,Jpp); _cimg_median_sort(Jbb,Jpp); _cimg_median_sort(Jbb,Jnb); - _cimg_median_sort(Jab,Jcp); _cimg_median_sort(Jpb,Jcp); _cimg_median_sort(Jpb,Jab); - _cimg_median_sort(Jpc,Jac); _cimg_median_sort(Jnp,Jac); _cimg_median_sort(Jnp,Jpc); - _cimg_median_sort(Jcc,Jbn); _cimg_median_sort(Jap,Jbn); _cimg_median_sort(Jap,Jcc); - _cimg_median_sort(Jnc,Jpn); _cimg_median_sort(Jbc,Jpn); _cimg_median_sort(Jbc,Jnc); - _cimg_median_sort(Jba,Jna); _cimg_median_sort(Jcn,Jna); _cimg_median_sort(Jcn,Jba); - _cimg_median_sort(Jpa,Jaa); _cimg_median_sort(Jnn,Jaa); _cimg_median_sort(Jnn,Jpa); - _cimg_median_sort(Jan,Jca); _cimg_median_sort(Jnp,Jcn); _cimg_median_sort(Jap,Jnn); - _cimg_median_sort(Jbb,Jnn); _cimg_median_sort(Jbb,Jap); _cimg_median_sort(Jbc,Jan); - _cimg_median_sort(Jpb,Jan); _cimg_median_sort(Jpb,Jbc); _cimg_median_sort(Jpc,Jba); - _cimg_median_sort(Jcb,Jba); _cimg_median_sort(Jcb,Jpc); _cimg_median_sort(Jcc,Jpa); - _cimg_median_sort(Jnb,Jpa); _cimg_median_sort(Jnb,Jcc); _cimg_median_sort(Jnc,Jca); - _cimg_median_sort(Jab,Jca); _cimg_median_sort(Jab,Jnc); _cimg_median_sort(Jac,Jna); - _cimg_median_sort(Jbp,Jna); _cimg_median_sort(Jbp,Jac); _cimg_median_sort(Jbn,Jaa); - _cimg_median_sort(Jpp,Jaa); _cimg_median_sort(Jpp,Jbn); _cimg_median_sort(Jcp,Jpn); - _cimg_median_sort(Jcp,Jan); _cimg_median_sort(Jnc,Jpa); _cimg_median_sort(Jbn,Jna); - _cimg_median_sort(Jcp,Jnc); _cimg_median_sort(Jcp,Jbn); _cimg_median_sort(Jpb,Jap); - _cimg_median_sort(Jnb,Jpc); _cimg_median_sort(Jbp,Jcn); _cimg_median_sort(Jpc,Jcn); - _cimg_median_sort(Jap,Jcn); _cimg_median_sort(Jab,Jbc); _cimg_median_sort(Jpp,Jcc); - _cimg_median_sort(Jcp,Jac); _cimg_median_sort(Jab,Jpp); _cimg_median_sort(Jab,Jcp); - _cimg_median_sort(Jcc,Jac); _cimg_median_sort(Jbc,Jac); _cimg_median_sort(Jpp,Jcp); - _cimg_median_sort(Jbc,Jcc); _cimg_median_sort(Jpp,Jbc); _cimg_median_sort(Jpp,Jcn); - _cimg_median_sort(Jcc,Jcn); _cimg_median_sort(Jcp,Jcn); _cimg_median_sort(Jcp,Jbc); - _cimg_median_sort(Jcc,Jnn); _cimg_median_sort(Jcp,Jcc); _cimg_median_sort(Jbc,Jnn); - _cimg_median_sort(Jcc,Jba); _cimg_median_sort(Jbc,Jba); _cimg_median_sort(Jbc,Jcc); - res(x,y,c) = Jcc; - } - } - } break; - default : { - cimg_pragma_openmp(parallel for collapse(2) if (_width>=16 && _height*_spectrum>=4)) - cimg_forXYC(*this,x,y,c) { - const int - x0 = x - hl, y0 = y - hl, x1 = x + hr, y1 = y + hr, - nx0 = x0<0?0:x0, ny0 = y0<0?0:y0, - nx1 = x1>=width()?width() - 1:x1, ny1 = y1>=height()?height() - 1:y1; - res(x,y,c) = get_crop(nx0,ny0,0,c,nx1,ny1,0,c).median(); - } - } - } - } else { // 1d - - CImg I; - if (threshold>0) - cimg_pragma_openmp(parallel for cimg_openmp_if(_width>=16 && _spectrum>=2)) - cimg_forXC(*this,x,c) { // With threshold. - const int - x0 = x - hl, x1 = x + hr, - nx0 = x0<0?0:x0, nx1 = x1>=width()?width() - 1:x1; - const float val0 = (float)(*this)(x,c); - CImg values(n); - unsigned int nb_values = 0; - T *ptrd = values.data(); - cimg_for_inX(*this,nx0,nx1,p) - if (cimg::abs((float)(*this)(p,c)-val0)<=threshold) { *(ptrd++) = (*this)(p,c); ++nb_values; } - res(x,c) = values.get_shared_points(0,nb_values - 1).median(); - } - else switch (n) { // Without threshold. - case 2 : { - cimg_pragma_openmp(parallel for cimg_openmp_if(_spectrum>=2)) - cimg_forC(*this,c) { - I.assign(4); - cimg_for2x2(*this,x,y,0,c,I,T) res(x,c) = (T)(0.5f*(I[0] + I[1])); - } - } break; - case 3 : { - cimg_pragma_openmp(parallel for cimg_openmp_if(_spectrum>=2)) - cimg_forC(*this,c) { - I.assign(9); - cimg_for3x3(*this,x,y,0,c,I,T) - res(x,c) = I[3]=16 && _spectrum>=2)) - cimg_forXC(*this,x,c) { - const int - x0 = x - hl, x1 = x + hr, - nx0 = x0<0?0:x0, nx1 = x1>=width()?width() - 1:x1; - res(x,c) = get_crop(nx0,0,0,c,nx1,0,0,c).median(); - } - } - } - } - } - return res; - } - - //! Sharpen image. - /** - \param amplitude Sharpening amplitude - \param sharpen_type Select sharpening method. Can be { false=inverse diffusion | true=shock filters }. - \param edge Edge threshold (shock filters only). - \param alpha Gradient smoothness (shock filters only). - \param sigma Tensor smoothness (shock filters only). - **/ - CImg& sharpen(const float amplitude, const bool sharpen_type=false, const float edge=1, - const float alpha=0, const float sigma=0) { - if (is_empty()) return *this; - T val_min, val_max = max_min(val_min); - const float nedge = edge/2; - CImg velocity(_width,_height,_depth,_spectrum), _veloc_max(_spectrum); - - if (_depth>1) { // 3d - if (sharpen_type) { // Shock filters. - CImg G = (alpha>0?get_blur(alpha).get_structure_tensors():get_structure_tensors()); - if (sigma>0) G.blur(sigma); - cimg_pragma_openmp(parallel for collapse(2) if (_width>=32 && _height*_depth>=16)) - cimg_forYZ(G,y,z) { - Tfloat *ptrG0 = G.data(0,y,z,0), *ptrG1 = G.data(0,y,z,1), - *ptrG2 = G.data(0,y,z,2), *ptrG3 = G.data(0,y,z,3); - CImg val, vec; - cimg_forX(G,x) { - G.get_tensor_at(x,y,z).symmetric_eigen(val,vec); - if (val[0]<0) val[0] = 0; - if (val[1]<0) val[1] = 0; - if (val[2]<0) val[2] = 0; - *(ptrG0++) = vec(0,0); - *(ptrG1++) = vec(0,1); - *(ptrG2++) = vec(0,2); - *(ptrG3++) = 1 - (Tfloat)std::pow(1 + val[0] + val[1] + val[2],-(Tfloat)nedge); - } - } - cimg_pragma_openmp(parallel for cimg_openmp_if(_width*_height*_depth>=512 && _spectrum>=2)) - cimg_forC(*this,c) { - Tfloat *ptrd = velocity.data(0,0,0,c), veloc_max = 0; - CImg_3x3x3(I,Tfloat); - cimg_for3x3x3(*this,x,y,z,c,I,Tfloat) { - const Tfloat - u = G(x,y,z,0), - v = G(x,y,z,1), - w = G(x,y,z,2), - amp = G(x,y,z,3), - ixx = Incc + Ipcc - 2*Iccc, - ixy = (Innc + Ippc - Inpc - Ipnc)/4, - ixz = (Incn + Ipcp - Incp - Ipcn)/4, - iyy = Icnc + Icpc - 2*Iccc, - iyz = (Icnn + Icpp - Icnp - Icpn)/4, - izz = Iccn + Iccp - 2*Iccc, - ixf = Incc - Iccc, - ixb = Iccc - Ipcc, - iyf = Icnc - Iccc, - iyb = Iccc - Icpc, - izf = Iccn - Iccc, - izb = Iccc - Iccp, - itt = u*u*ixx + v*v*iyy + w*w*izz + 2*u*v*ixy + 2*u*w*ixz + 2*v*w*iyz, - it = u*cimg::minmod(ixf,ixb) + v*cimg::minmod(iyf,iyb) + w*cimg::minmod(izf,izb), - veloc = -amp*cimg::sign(itt)*cimg::abs(it); - *(ptrd++) = veloc; - if (veloc>veloc_max) veloc_max = veloc; else if (-veloc>veloc_max) veloc_max = -veloc; - } - _veloc_max[c] = veloc_max; - } - } else // Inverse diffusion. - cimg_forC(*this,c) { - Tfloat *ptrd = velocity.data(0,0,0,c), veloc_max = 0; - CImg_3x3x3(I,Tfloat); - cimg_for3x3x3(*this,x,y,z,c,I,Tfloat) { - const Tfloat veloc = -Ipcc - Incc - Icpc - Icnc - Iccp - Iccn + 6*Iccc; - *(ptrd++) = veloc; - if (veloc>veloc_max) veloc_max = veloc; else if (-veloc>veloc_max) veloc_max = -veloc; - } - _veloc_max[c] = veloc_max; - } - } else { // 2d. - if (sharpen_type) { // Shock filters. - CImg G = (alpha>0?get_blur(alpha).get_structure_tensors():get_structure_tensors()); - if (sigma>0) G.blur(sigma); - cimg_pragma_openmp(parallel for cimg_openmp_if(_width>=32 && _height>=16)) - cimg_forY(G,y) { - CImg val, vec; - Tfloat *ptrG0 = G.data(0,y,0,0), *ptrG1 = G.data(0,y,0,1), *ptrG2 = G.data(0,y,0,2); - cimg_forX(G,x) { - G.get_tensor_at(x,y).symmetric_eigen(val,vec); - if (val[0]<0) val[0] = 0; - if (val[1]<0) val[1] = 0; - *(ptrG0++) = vec(0,0); - *(ptrG1++) = vec(0,1); - *(ptrG2++) = 1 - (Tfloat)std::pow(1 + val[0] + val[1],-(Tfloat)nedge); - } - } - cimg_pragma_openmp(parallel for cimg_openmp_if(_width*_height>=512 && _spectrum>=2)) - cimg_forC(*this,c) { - Tfloat *ptrd = velocity.data(0,0,0,c), veloc_max = 0; - CImg_3x3(I,Tfloat); - cimg_for3x3(*this,x,y,0,c,I,Tfloat) { - const Tfloat - u = G(x,y,0), - v = G(x,y,1), - amp = G(x,y,2), - ixx = Inc + Ipc - 2*Icc, - ixy = (Inn + Ipp - Inp - Ipn)/4, - iyy = Icn + Icp - 2*Icc, - ixf = Inc - Icc, - ixb = Icc - Ipc, - iyf = Icn - Icc, - iyb = Icc - Icp, - itt = u*u*ixx + v*v*iyy + 2*u*v*ixy, - it = u*cimg::minmod(ixf,ixb) + v*cimg::minmod(iyf,iyb), - veloc = -amp*cimg::sign(itt)*cimg::abs(it); - *(ptrd++) = veloc; - if (veloc>veloc_max) veloc_max = veloc; else if (-veloc>veloc_max) veloc_max = -veloc; - } - _veloc_max[c] = veloc_max; - } - } else // Inverse diffusion. - cimg_forC(*this,c) { - Tfloat *ptrd = velocity.data(0,0,0,c), veloc_max = 0; - CImg_3x3(I,Tfloat); - cimg_for3x3(*this,x,y,0,c,I,Tfloat) { - const Tfloat veloc = -Ipc - Inc - Icp - Icn + 4*Icc; - *(ptrd++) = veloc; - if (veloc>veloc_max) veloc_max = veloc; else if (-veloc>veloc_max) veloc_max = -veloc; - } - _veloc_max[c] = veloc_max; - } - } - const Tfloat veloc_max = _veloc_max.max(); - if (veloc_max<=0) return *this; - return ((velocity*=amplitude/veloc_max)+=*this).cut(val_min,val_max).move_to(*this); - } - - //! Sharpen image \newinstance. - CImg get_sharpen(const float amplitude, const bool sharpen_type=false, const float edge=1, - const float alpha=0, const float sigma=0) const { - return (+*this).sharpen(amplitude,sharpen_type,edge,alpha,sigma); - } - - //! Return image gradient. - /** - \param axes Axes considered for the gradient computation, as a C-string (e.g "xy"). - \param scheme = Numerical scheme used for the gradient computation: - - -1 = Backward finite differences - - 0 = Centered finite differences - - 1 = Forward finite differences - - 2 = Using Sobel masks - - 3 = Using rotation invariant masks - - 4 = Using Deriche recusrsive filter. - - 5 = Using Van Vliet recusrsive filter. - **/ - CImgList get_gradient(const char *const axes=0, const int scheme=3) const { - CImgList grad(2,_width,_height,_depth,_spectrum); - bool is_3d = false; - if (axes) { - for (unsigned int a = 0; axes[a]; ++a) { - const char axis = cimg::lowercase(axes[a]); - switch (axis) { - case 'x' : case 'y' : break; - case 'z' : is_3d = true; break; - default : - throw CImgArgumentException(_cimg_instance - "get_gradient(): Invalid specified axis '%c'.", - cimg_instance, - axis); - } - } - } else is_3d = (_depth>1); - if (is_3d) { - CImg(_width,_height,_depth,_spectrum).move_to(grad); - switch (scheme) { // 3d. - case -1 : { // Backward finite differences. - cimg_pragma_openmp(parallel for cimg_openmp_if(_width*_height*_depth>=1048576 && _spectrum>=2)) - cimg_forC(*this,c) { - const ulongT off = (ulongT)c*_width*_height*_depth; - Tfloat *ptrd0 = grad[0]._data + off, *ptrd1 = grad[1]._data + off, *ptrd2 = grad[2]._data + off; - CImg_3x3x3(I,Tfloat); - cimg_for3x3x3(*this,x,y,z,c,I,Tfloat) { - *(ptrd0++) = Iccc - Ipcc; - *(ptrd1++) = Iccc - Icpc; - *(ptrd2++) = Iccc - Iccp; - } - } - } break; - case 1 : { // Forward finite differences. - cimg_pragma_openmp(parallel for cimg_openmp_if(_width*_height*_depth>=1048576 && _spectrum>=2)) - cimg_forC(*this,c) { - const ulongT off = (ulongT)c*_width*_height*_depth; - Tfloat *ptrd0 = grad[0]._data + off, *ptrd1 = grad[1]._data + off, *ptrd2 = grad[2]._data + off; - CImg_2x2x2(I,Tfloat); - cimg_for2x2x2(*this,x,y,z,c,I,Tfloat) { - *(ptrd0++) = Incc - Iccc; - *(ptrd1++) = Icnc - Iccc; - *(ptrd2++) = Iccn - Iccc; - } - } - } break; - case 4 : { // Deriche filter with low standard variation. - grad[0] = get_deriche(0,1,'x'); - grad[1] = get_deriche(0,1,'y'); - grad[2] = get_deriche(0,1,'z'); - } break; - case 5 : { // Van Vliet filter with low standard variation. - grad[0] = get_vanvliet(0,1,'x'); - grad[1] = get_vanvliet(0,1,'y'); - grad[2] = get_vanvliet(0,1,'z'); - } break; - default : { // Central finite differences. - cimg_pragma_openmp(parallel for cimg_openmp_if(_width*_height*_depth>=1048576 && _spectrum>=2)) - cimg_forC(*this,c) { - const ulongT off = (ulongT)c*_width*_height*_depth; - Tfloat *ptrd0 = grad[0]._data + off, *ptrd1 = grad[1]._data + off, *ptrd2 = grad[2]._data + off; - CImg_3x3x3(I,Tfloat); - cimg_for3x3x3(*this,x,y,z,c,I,Tfloat) { - *(ptrd0++) = (Incc - Ipcc)/2; - *(ptrd1++) = (Icnc - Icpc)/2; - *(ptrd2++) = (Iccn - Iccp)/2; - } - } - } - } - } else switch (scheme) { // 2d. - case -1 : { // Backward finite differences. - cimg_pragma_openmp(parallel for collapse(2) if (_width*_height>=1048576 && _depth*_spectrum>=2)) - cimg_forZC(*this,z,c) { - const ulongT off = (ulongT)c*_width*_height*_depth + z*_width*_height; - Tfloat *ptrd0 = grad[0]._data + off, *ptrd1 = grad[1]._data + off; - CImg_3x3(I,Tfloat); - cimg_for3x3(*this,x,y,z,c,I,Tfloat) { - *(ptrd0++) = Icc - Ipc; - *(ptrd1++) = Icc - Icp; - } - } - } break; - case 1 : { // Forward finite differences. - cimg_pragma_openmp(parallel for collapse(2) if (_width*_height>=1048576 && _depth*_spectrum>=2)) - cimg_forZC(*this,z,c) { - const ulongT off = (ulongT)c*_width*_height*_depth + z*_width*_height; - Tfloat *ptrd0 = grad[0]._data + off, *ptrd1 = grad[1]._data + off; - CImg_2x2(I,Tfloat); - cimg_for2x2(*this,x,y,z,c,I,Tfloat) { - *(ptrd0++) = Inc - Icc; - *(ptrd1++) = Icn - Icc; - } - } - } break; - case 2 : { // Sobel scheme. - cimg_pragma_openmp(parallel for collapse(2) if (_width*_height>=1048576 && _depth*_spectrum>=2)) - cimg_forZC(*this,z,c) { - const ulongT off = (ulongT)c*_width*_height*_depth + z*_width*_height; - Tfloat *ptrd0 = grad[0]._data + off, *ptrd1 = grad[1]._data + off; - CImg_3x3(I,Tfloat); - cimg_for3x3(*this,x,y,z,c,I,Tfloat) { - *(ptrd0++) = -Ipp - 2*Ipc - Ipn + Inp + 2*Inc + Inn; - *(ptrd1++) = -Ipp - 2*Icp - Inp + Ipn + 2*Icn + Inn; - } - } - } break; - case 3 : { // Rotation invariant mask. - cimg_pragma_openmp(parallel for collapse(2) if (_width*_height>=1048576 && _depth*_spectrum>=2)) - cimg_forZC(*this,z,c) { - const ulongT off = (ulongT)c*_width*_height*_depth + z*_width*_height; - Tfloat *ptrd0 = grad[0]._data + off, *ptrd1 = grad[1]._data + off; - CImg_3x3(I,Tfloat); - const Tfloat a = (Tfloat)(0.25f*(2-std::sqrt(2.0f))), b = (Tfloat)(0.5f*(std::sqrt(2.0f) - 1)); - cimg_for3x3(*this,x,y,z,c,I,Tfloat) { - *(ptrd0++) = -a*Ipp - b*Ipc - a*Ipn + a*Inp + b*Inc + a*Inn; - *(ptrd1++) = -a*Ipp - b*Icp - a*Inp + a*Ipn + b*Icn + a*Inn; - } - } - } break; - case 4 : { // Van Vliet filter with low standard variation - grad[0] = get_deriche(0,1,'x'); - grad[1] = get_deriche(0,1,'y'); - } break; - case 5 : { // Deriche filter with low standard variation - grad[0] = get_vanvliet(0,1,'x'); - grad[1] = get_vanvliet(0,1,'y'); - } break; - default : { // Central finite differences - cimg_pragma_openmp(parallel for collapse(2) if (_width*_height>=1048576 && _depth*_spectrum>=2)) - cimg_forZC(*this,z,c) { - const ulongT off = (ulongT)c*_width*_height*_depth + z*_width*_height; - Tfloat *ptrd0 = grad[0]._data + off, *ptrd1 = grad[1]._data + off; - CImg_3x3(I,Tfloat); - cimg_for3x3(*this,x,y,z,c,I,Tfloat) { - *(ptrd0++) = (Inc - Ipc)/2; - *(ptrd1++) = (Icn - Icp)/2; - } - } - } - } - if (!axes) return grad; - CImgList res; - for (unsigned int l = 0; axes[l]; ++l) { - const char axis = cimg::lowercase(axes[l]); - switch (axis) { - case 'x' : res.insert(grad[0]); break; - case 'y' : res.insert(grad[1]); break; - case 'z' : res.insert(grad[2]); break; - } - } - grad.assign(); - return res; - } - - //! Return image hessian. - /** - \param axes Axes considered for the hessian computation, as a C-string (e.g "xy"). - **/ - CImgList get_hessian(const char *const axes=0) const { - CImgList res; - const char *naxes = axes, *const def_axes2d = "xxxyyy", *const def_axes3d = "xxxyxzyyyzzz"; - if (!axes) naxes = _depth>1?def_axes3d:def_axes2d; - const unsigned int lmax = (unsigned int)std::strlen(naxes); - if (lmax%2) - throw CImgArgumentException(_cimg_instance - "get_hessian(): Invalid specified axes '%s'.", - cimg_instance, - naxes); - - res.assign(lmax/2,_width,_height,_depth,_spectrum); - if (!cimg::strcasecmp(naxes,def_axes3d)) { // 3d - - cimg_pragma_openmp(parallel for cimg_openmp_if(_width*_height*_depth>=1048576 && _spectrum>=2)) - cimg_forC(*this,c) { - const ulongT off = (ulongT)c*_width*_height*_depth; - Tfloat - *ptrd0 = res[0]._data + off, *ptrd1 = res[1]._data + off, *ptrd2 = res[2]._data + off, - *ptrd3 = res[3]._data + off, *ptrd4 = res[4]._data + off, *ptrd5 = res[5]._data + off; - CImg_3x3x3(I,Tfloat); - cimg_for3x3x3(*this,x,y,z,c,I,Tfloat) { - *(ptrd0++) = Ipcc + Incc - 2*Iccc; // Ixx - *(ptrd1++) = (Ippc + Innc - Ipnc - Inpc)/4; // Ixy - *(ptrd2++) = (Ipcp + Incn - Ipcn - Incp)/4; // Ixz - *(ptrd3++) = Icpc + Icnc - 2*Iccc; // Iyy - *(ptrd4++) = (Icpp + Icnn - Icpn - Icnp)/4; // Iyz - *(ptrd5++) = Iccn + Iccp - 2*Iccc; // Izz - } - } - } else if (!cimg::strcasecmp(naxes,def_axes2d)) { // 2d - cimg_pragma_openmp(parallel for collapse(2) if (_width*_height>=1048576 && _depth*_spectrum>=2)) - cimg_forZC(*this,z,c) { - const ulongT off = (ulongT)c*_width*_height*_depth + z*_width*_height; - Tfloat *ptrd0 = res[0]._data + off, *ptrd1 = res[1]._data + off, *ptrd2 = res[2]._data + off; - CImg_3x3(I,Tfloat); - cimg_for3x3(*this,x,y,z,c,I,Tfloat) { - *(ptrd0++) = Ipc + Inc - 2*Icc; // Ixx - *(ptrd1++) = (Ipp + Inn - Ipn - Inp)/4; // Ixy - *(ptrd2++) = Icp + Icn - 2*Icc; // Iyy - } - } - } else for (unsigned int l = 0; laxis2) cimg::swap(axis1,axis2); - bool valid_axis = false; - if (axis1=='x' && axis2=='x') { // Ixx - valid_axis = true; - cimg_pragma_openmp(parallel for collapse(2) if (_width*_height>=1048576 && _depth*_spectrum>=2)) - cimg_forZC(*this,z,c) { - Tfloat *ptrd = res[l2].data(0,0,z,c); - CImg_3x3(I,Tfloat); - cimg_for3x3(*this,x,y,z,c,I,Tfloat) *(ptrd++) = Ipc + Inc - 2*Icc; - } - } - else if (axis1=='x' && axis2=='y') { // Ixy - valid_axis = true; - cimg_pragma_openmp(parallel for collapse(2) if (_width*_height>=1048576 && _depth*_spectrum>=2)) - cimg_forZC(*this,z,c) { - Tfloat *ptrd = res[l2].data(0,0,z,c); - CImg_3x3(I,Tfloat); - cimg_for3x3(*this,x,y,z,c,I,Tfloat) *(ptrd++) = (Ipp + Inn - Ipn - Inp)/4; - } - } - else if (axis1=='x' && axis2=='z') { // Ixz - valid_axis = true; - cimg_pragma_openmp(parallel for cimg_openmp_if(_width*_height*_depth>=1048576 && _spectrum>=2)) - cimg_forC(*this,c) { - Tfloat *ptrd = res[l2].data(0,0,0,c); - CImg_3x3x3(I,Tfloat); - cimg_for3x3x3(*this,x,y,z,c,I,Tfloat) *(ptrd++) = (Ipcp + Incn - Ipcn - Incp)/4; - } - } - else if (axis1=='y' && axis2=='y') { // Iyy - valid_axis = true; - cimg_pragma_openmp(parallel for collapse(2) if (_width*_height>=1048576 && _depth*_spectrum>=2)) - cimg_forZC(*this,z,c) { - Tfloat *ptrd = res[l2].data(0,0,z,c); - CImg_3x3(I,Tfloat); - cimg_for3x3(*this,x,y,z,c,I,Tfloat) *(ptrd++) = Icp + Icn - 2*Icc; - } - } - else if (axis1=='y' && axis2=='z') { // Iyz - valid_axis = true; - cimg_pragma_openmp(parallel for cimg_openmp_if(_width*_height*_depth>=1048576 && _spectrum>=2)) - cimg_forC(*this,c) { - Tfloat *ptrd = res[l2].data(0,0,0,c); - CImg_3x3x3(I,Tfloat); - cimg_forC(*this,c) cimg_for3x3x3(*this,x,y,z,c,I,Tfloat) *(ptrd++) = (Icpp + Icnn - Icpn - Icnp)/4; - } - } - else if (axis1=='z' && axis2=='z') { // Izz - valid_axis = true; - cimg_pragma_openmp(parallel for cimg_openmp_if(_width*_height*_depth>=1048576 && _spectrum>=2)) - cimg_forC(*this,c) { - Tfloat *ptrd = res[l2].data(0,0,0,c); - CImg_3x3x3(I,Tfloat); - cimg_for3x3x3(*this,x,y,z,c,I,Tfloat) *(ptrd++) = Iccn + Iccp - 2*Iccc; - } - } - else if (!valid_axis) - throw CImgArgumentException(_cimg_instance - "get_hessian(): Invalid specified axes '%s'.", - cimg_instance, - naxes); - } - return res; - } - - //! Compute image laplacian. - CImg& laplacian() { - return get_laplacian().move_to(*this); - } - - //! Compute image laplacian \newinstance. - CImg get_laplacian() const { - if (is_empty()) return CImg(); - CImg res(_width,_height,_depth,_spectrum); - if (_depth>1) { // 3d - cimg_pragma_openmp(parallel for cimg_openmp_if(_width*_height*_depth>=1048576 && _spectrum>=2)) - cimg_forC(*this,c) { - Tfloat *ptrd = res.data(0,0,0,c); - CImg_3x3x3(I,Tfloat); - cimg_for3x3x3(*this,x,y,z,c,I,Tfloat) *(ptrd++) = Incc + Ipcc + Icnc + Icpc + Iccn + Iccp - 6*Iccc; - } - } else if (_height>1) { // 2d - cimg_pragma_openmp(parallel for cimg_openmp_if(_width*_height>=1048576 && _depth*_spectrum>=2)) - cimg_forC(*this,c) { - Tfloat *ptrd = res.data(0,0,0,c); - CImg_3x3(I,Tfloat); - cimg_for3x3(*this,x,y,0,c,I,Tfloat) *(ptrd++) = Inc + Ipc + Icn + Icp - 4*Icc; - } - } else { // 1d - cimg_pragma_openmp(parallel for cimg_openmp_if(_width>=1048576 && _height*_depth*_spectrum>=2)) - cimg_forC(*this,c) { - Tfloat *ptrd = res.data(0,0,0,c); - CImg_3x3(I,Tfloat); - cimg_for3x3(*this,x,y,0,c,I,Tfloat) *(ptrd++) = Inc + Ipc - 2*Icc; - } - } - return res; - } - - //! Compute the structure tensor field of an image. - /** - \param is_fwbw_scheme scheme. Can be { false=centered | true=forward-backward } - **/ - CImg& structure_tensors(const bool is_fwbw_scheme=false) { - return get_structure_tensors(is_fwbw_scheme).move_to(*this); - } - - //! Compute the structure tensor field of an image \newinstance. - CImg get_structure_tensors(const bool is_fwbw_scheme=false) const { - if (is_empty()) return *this; - CImg res; - if (_depth>1) { // 3d - res.assign(_width,_height,_depth,6,0); - if (!is_fwbw_scheme) { // Classical central finite differences - cimg_pragma_openmp(parallel for cimg_openmp_if(_width*_height*_depth>=1048576 && _spectrum>=2)) - cimg_forC(*this,c) { - Tfloat - *ptrd0 = res.data(0,0,0,0), *ptrd1 = res.data(0,0,0,1), *ptrd2 = res.data(0,0,0,2), - *ptrd3 = res.data(0,0,0,3), *ptrd4 = res.data(0,0,0,4), *ptrd5 = res.data(0,0,0,5); - CImg_3x3x3(I,Tfloat); - cimg_for3x3x3(*this,x,y,z,c,I,Tfloat) { - const Tfloat - ix = (Incc - Ipcc)/2, - iy = (Icnc - Icpc)/2, - iz = (Iccn - Iccp)/2; - *(ptrd0++)+=ix*ix; - *(ptrd1++)+=ix*iy; - *(ptrd2++)+=ix*iz; - *(ptrd3++)+=iy*iy; - *(ptrd4++)+=iy*iz; - *(ptrd5++)+=iz*iz; - } - } - } else { // Forward/backward finite differences. - cimg_pragma_openmp(parallel for cimg_openmp_if(_width*_height*_depth>=1048576 && _spectrum>=2)) - cimg_forC(*this,c) { - Tfloat - *ptrd0 = res.data(0,0,0,0), *ptrd1 = res.data(0,0,0,1), *ptrd2 = res.data(0,0,0,2), - *ptrd3 = res.data(0,0,0,3), *ptrd4 = res.data(0,0,0,4), *ptrd5 = res.data(0,0,0,5); - CImg_3x3x3(I,Tfloat); - cimg_for3x3x3(*this,x,y,z,c,I,Tfloat) { - const Tfloat - ixf = Incc - Iccc, ixb = Iccc - Ipcc, - iyf = Icnc - Iccc, iyb = Iccc - Icpc, - izf = Iccn - Iccc, izb = Iccc - Iccp; - *(ptrd0++)+=(ixf*ixf + ixb*ixb)/2; - *(ptrd1++)+=(ixf*iyf + ixf*iyb + ixb*iyf + ixb*iyb)/4; - *(ptrd2++)+=(ixf*izf + ixf*izb + ixb*izf + ixb*izb)/4; - *(ptrd3++)+=(iyf*iyf + iyb*iyb)/2; - *(ptrd4++)+=(iyf*izf + iyf*izb + iyb*izf + iyb*izb)/4; - *(ptrd5++)+=(izf*izf + izb*izb)/2; - } - } - } - } else { // 2d - res.assign(_width,_height,_depth,3,0); - if (!is_fwbw_scheme) { // Classical central finite differences - cimg_pragma_openmp(parallel for cimg_openmp_if(_width*_height>=1048576 && _depth*_spectrum>=2)) - cimg_forC(*this,c) { - Tfloat *ptrd0 = res.data(0,0,0,0), *ptrd1 = res.data(0,0,0,1), *ptrd2 = res.data(0,0,0,2); - CImg_3x3(I,Tfloat); - cimg_for3x3(*this,x,y,0,c,I,Tfloat) { - const Tfloat - ix = (Inc - Ipc)/2, - iy = (Icn - Icp)/2; - *(ptrd0++)+=ix*ix; - *(ptrd1++)+=ix*iy; - *(ptrd2++)+=iy*iy; - } - } - } else { // Forward/backward finite differences (version 2). - cimg_pragma_openmp(parallel for cimg_openmp_if(_width*_height>=1048576 && _depth*_spectrum>=2)) - cimg_forC(*this,c) { - Tfloat *ptrd0 = res.data(0,0,0,0), *ptrd1 = res.data(0,0,0,1), *ptrd2 = res.data(0,0,0,2); - CImg_3x3(I,Tfloat); - cimg_for3x3(*this,x,y,0,c,I,Tfloat) { - const Tfloat - ixf = Inc - Icc, ixb = Icc - Ipc, - iyf = Icn - Icc, iyb = Icc - Icp; - *(ptrd0++)+=(ixf*ixf + ixb*ixb)/2; - *(ptrd1++)+=(ixf*iyf + ixf*iyb + ixb*iyf + ixb*iyb)/4; - *(ptrd2++)+=(iyf*iyf + iyb*iyb)/2; - } - } - } - } - return res; - } - - //! Compute field of diffusion tensors for edge-preserving smoothing. - /** - \param sharpness Sharpness - \param anisotropy Anisotropy - \param alpha Standard deviation of the gradient blur. - \param sigma Standard deviation of the structure tensor blur. - \param is_sqrt Tells if the square root of the tensor field is computed instead. - **/ - CImg& diffusion_tensors(const float sharpness=0.7f, const float anisotropy=0.6f, - const float alpha=0.6f, const float sigma=1.1f, const bool is_sqrt=false) { - CImg res; - const float - nsharpness = cimg::max(sharpness,1e-5f), - power1 = (is_sqrt?0.5f:1)*nsharpness, - power2 = power1/(1e-7f + 1 - anisotropy); - blur(alpha).normalize(0,(T)255); - - if (_depth>1) { // 3d - get_structure_tensors().move_to(res).blur(sigma); - cimg_pragma_openmp(parallel for collapse(2) if(_width>=256 && _height*_depth>=256)) - cimg_forYZ(*this,y,z) { - Tfloat - *ptrd0 = res.data(0,y,z,0), *ptrd1 = res.data(0,y,z,1), *ptrd2 = res.data(0,y,z,2), - *ptrd3 = res.data(0,y,z,3), *ptrd4 = res.data(0,y,z,4), *ptrd5 = res.data(0,y,z,5); - CImg val(3), vec(3,3); - cimg_forX(*this,x) { - res.get_tensor_at(x,y,z).symmetric_eigen(val,vec); - const float - _l1 = val[2], _l2 = val[1], _l3 = val[0], - l1 = _l1>0?_l1:0, l2 = _l2>0?_l2:0, l3 = _l3>0?_l3:0, - ux = vec(0,0), uy = vec(0,1), uz = vec(0,2), - vx = vec(1,0), vy = vec(1,1), vz = vec(1,2), - wx = vec(2,0), wy = vec(2,1), wz = vec(2,2), - n1 = (float)std::pow(1 + l1 + l2 + l3,-power1), - n2 = (float)std::pow(1 + l1 + l2 + l3,-power2); - *(ptrd0++) = n1*(ux*ux + vx*vx) + n2*wx*wx; - *(ptrd1++) = n1*(ux*uy + vx*vy) + n2*wx*wy; - *(ptrd2++) = n1*(ux*uz + vx*vz) + n2*wx*wz; - *(ptrd3++) = n1*(uy*uy + vy*vy) + n2*wy*wy; - *(ptrd4++) = n1*(uy*uz + vy*vz) + n2*wy*wz; - *(ptrd5++) = n1*(uz*uz + vz*vz) + n2*wz*wz; - } - } - } else { // for 2d images - get_structure_tensors().move_to(res).blur(sigma); - cimg_pragma_openmp(parallel for if(_width>=256 && _height>=256)) - cimg_forY(*this,y) { - Tfloat *ptrd0 = res.data(0,y,0,0), *ptrd1 = res.data(0,y,0,1), *ptrd2 = res.data(0,y,0,2); - CImg val(2), vec(2,2); - cimg_forX(*this,x) { - res.get_tensor_at(x,y).symmetric_eigen(val,vec); - const float - _l1 = val[1], _l2 = val[0], - l1 = _l1>0?_l1:0, l2 = _l2>0?_l2:0, - ux = vec(1,0), uy = vec(1,1), - vx = vec(0,0), vy = vec(0,1), - n1 = (float)std::pow(1 + l1 + l2,-power1), - n2 = (float)std::pow(1 + l1 + l2,-power2); - *(ptrd0++) = n1*ux*ux + n2*vx*vx; - *(ptrd1++) = n1*ux*uy + n2*vx*vy; - *(ptrd2++) = n1*uy*uy + n2*vy*vy; - } - } - } - return res.move_to(*this); - } - - //! Compute field of diffusion tensors for edge-preserving smoothing \newinstance. - CImg get_diffusion_tensors(const float sharpness=0.7f, const float anisotropy=0.6f, - const float alpha=0.6f, const float sigma=1.1f, const bool is_sqrt=false) const { - return CImg(*this,false).diffusion_tensors(sharpness,anisotropy,alpha,sigma,is_sqrt); - } - - //! Estimate displacement field between two images. - /** - \param source Reference image. - \param smoothness Smoothness of estimated displacement field. - \param precision Precision required for algorithm convergence. - \param nb_scales Number of scales used to estimate the displacement field. - \param iteration_max Maximum number of iterations allowed for one scale. - \param is_backward If false, match I2(X + U(X)) = I1(X), else match I2(X) = I1(X - U(X)). - \param guide Image used as the initial correspondence estimate for the algorithm. - 'guide' may have a last channel with boolean values (0=false | other=true) that - tells for each pixel if its correspondence vector is constrained to its initial value (constraint mask). - **/ - CImg& displacement(const CImg& source, const float smoothness=0.1f, const float precision=5.0f, - const unsigned int nb_scales=0, const unsigned int iteration_max=10000, - const bool is_backward=false, - const CImg& guide=CImg::const_empty()) { - return get_displacement(source,smoothness,precision,nb_scales,iteration_max,is_backward,guide). - move_to(*this); - } - - //! Estimate displacement field between two images \newinstance. - CImg get_displacement(const CImg& source, - const float smoothness=0.1f, const float precision=5.0f, - const unsigned int nb_scales=0, const unsigned int iteration_max=10000, - const bool is_backward=false, - const CImg& guide=CImg::const_empty()) const { - if (is_empty() || !source) return +*this; - if (!is_sameXYZC(source)) - throw CImgArgumentException(_cimg_instance - "displacement(): Instance and source image (%u,%u,%u,%u,%p) have " - "different dimensions.", - cimg_instance, - source._width,source._height,source._depth,source._spectrum,source._data); - if (precision<0) - throw CImgArgumentException(_cimg_instance - "displacement(): Invalid specified precision %g " - "(should be >=0)", - cimg_instance, - precision); - - const bool is_3d = source._depth>1; - const unsigned int constraint = is_3d?3:2; - - if (guide && - (guide._width!=_width || guide._height!=_height || guide._depth!=_depth || guide._spectrum0?nb_scales: - (unsigned int)cimg::round(std::log(mins/8.0)/std::log(1.5),1,1); - - const float _precision = (float)std::pow(10.0,-(double)precision); - float sm, sM = source.max_min(sm), tm, tM = max_min(tm); - const float sdelta = sm==sM?1:(sM - sm), tdelta = tm==tM?1:(tM - tm); - - CImg U, V; - floatT bound = 0; - for (int scale = (int)_nb_scales - 1; scale>=0; --scale) { - const float factor = (float)std::pow(1.5,(double)scale); - const unsigned int - _sw = (unsigned int)(_width/factor), sw = _sw?_sw:1, - _sh = (unsigned int)(_height/factor), sh = _sh?_sh:1, - _sd = (unsigned int)(_depth/factor), sd = _sd?_sd:1; - if (sw<5 && sh<5 && (!is_3d || sd<5)) continue; // skip too small scales. - const CImg - I1 = (source.get_resize(sw,sh,sd,-100,2)-=sm)/=sdelta, - I2 = (get_resize(I1,2)-=tm)/=tdelta; - if (guide._spectrum>constraint) guide.get_resize(I2._width,I2._height,I2._depth,-100,1).move_to(V); - if (U) (U*=1.5f).resize(I2._width,I2._height,I2._depth,-100,3); - else { - if (guide) - guide.get_shared_channels(0,is_3d?2:1).get_resize(I2._width,I2._height,I2._depth,-100,2).move_to(U); - else U.assign(I2._width,I2._height,I2._depth,is_3d?3:2,0); - } - - float dt = 2, energy = cimg::type::max(); - const CImgList dI = is_backward?I1.get_gradient():I2.get_gradient(); - - for (unsigned int iteration = 0; iteration=0) // Isotropic regularization. - cimg_pragma_openmp(parallel for collapse(2) if (_height*_depth>=8 && _width>=16) reduction(+:_energy)) - cimg_forYZ(U,y,z) { - const int - _p1y = y?y - 1:0, _n1y = yx) U(x,y,z,0) = (float)x; - if (U(x,y,z,1)>y) U(x,y,z,1) = (float)y; - if (U(x,y,z,2)>z) U(x,y,z,2) = (float)z; - bound = (float)x - _width; if (U(x,y,z,0)<=bound) U(x,y,z,0) = bound; - bound = (float)y - _height; if (U(x,y,z,1)<=bound) U(x,y,z,1) = bound; - bound = (float)z - _depth; if (U(x,y,z,2)<=bound) U(x,y,z,2) = bound; - } else { - if (U(x,y,z,0)<-x) U(x,y,z,0) = -(float)x; - if (U(x,y,z,1)<-y) U(x,y,z,1) = -(float)y; - if (U(x,y,z,2)<-z) U(x,y,z,2) = -(float)z; - bound = (float)_width - x; if (U(x,y,z,0)>=bound) U(x,y,z,0) = bound; - bound = (float)_height - y; if (U(x,y,z,1)>=bound) U(x,y,z,1) = bound; - bound = (float)_depth - z; if (U(x,y,z,2)>=bound) U(x,y,z,2) = bound; - } - _energy+=delta_I*delta_I + smoothness*_energy_regul; - } - if (V) cimg_forXYZ(V,x,y,z) if (V(x,y,z,3)) { // Apply constraints. - U(x,y,z,0) = V(x,y,z,0)/factor; - U(x,y,z,1) = V(x,y,z,1)/factor; - U(x,y,z,2) = V(x,y,z,2)/factor; - } - } else { // Anisotropic regularization. - const float nsmoothness = -smoothness; - cimg_pragma_openmp(parallel for collapse(2) if (_height*_depth>=8 && _width>=16) reduction(+:_energy)) - cimg_forYZ(U,y,z) { - const int - _p1y = y?y - 1:0, _n1y = yx) U(x,y,z,0) = (float)x; - if (U(x,y,z,1)>y) U(x,y,z,1) = (float)y; - if (U(x,y,z,2)>z) U(x,y,z,2) = (float)z; - bound = (float)x - _width; if (U(x,y,z,0)<=bound) U(x,y,z,0) = bound; - bound = (float)y - _height; if (U(x,y,z,1)<=bound) U(x,y,z,1) = bound; - bound = (float)z - _depth; if (U(x,y,z,2)<=bound) U(x,y,z,2) = bound; - } else { - if (U(x,y,z,0)<-x) U(x,y,z,0) = -(float)x; - if (U(x,y,z,1)<-y) U(x,y,z,1) = -(float)y; - if (U(x,y,z,2)<-z) U(x,y,z,2) = -(float)z; - bound = (float)_width - x; if (U(x,y,z,0)>=bound) U(x,y,z,0) = bound; - bound = (float)_height - y; if (U(x,y,z,1)>=bound) U(x,y,z,1) = bound; - bound = (float)_depth - z; if (U(x,y,z,2)>=bound) U(x,y,z,2) = bound; - } - _energy+=delta_I*delta_I + nsmoothness*_energy_regul; - } - if (V) cimg_forXYZ(V,x,y,z) if (V(x,y,z,3)) { // Apply constraints. - U(x,y,z,0) = V(x,y,z,0)/factor; - U(x,y,z,1) = V(x,y,z,1)/factor; - U(x,y,z,2) = V(x,y,z,2)/factor; - } - } - } - } else { // 2d version. - if (smoothness>=0) // Isotropic regularization. - cimg_pragma_openmp(parallel for cimg_openmp_if(_height>=8 && _width>=16) reduction(+:_energy)) - cimg_forY(U,y) { - const int _p1y = y?y - 1:0, _n1y = yx) U(x,y,0) = (float)x; - if (U(x,y,1)>y) U(x,y,1) = (float)y; - bound = (float)x - _width; if (U(x,y,0)<=bound) U(x,y,0) = bound; - bound = (float)y - _height; if (U(x,y,1)<=bound) U(x,y,1) = bound; - } else { - if (U(x,y,0)<-x) U(x,y,0) = -(float)x; - if (U(x,y,1)<-y) U(x,y,1) = -(float)y; - bound = (float)_width - x; if (U(x,y,0)>=bound) U(x,y,0) = bound; - bound = (float)_height - y; if (U(x,y,1)>=bound) U(x,y,1) = bound; - } - _energy+=delta_I*delta_I + smoothness*_energy_regul; - } - if (V) cimg_forX(V,x) if (V(x,y,2)) { // Apply constraints. - U(x,y,0) = V(x,y,0)/factor; - U(x,y,1) = V(x,y,1)/factor; - } - } else { // Anisotropic regularization. - const float nsmoothness = -smoothness; - cimg_pragma_openmp(parallel for cimg_openmp_if(_height>=8 && _width>=16) reduction(+:_energy)) - cimg_forY(U,y) { - const int _p1y = y?y - 1:0, _n1y = yx) U(x,y,0) = (float)x; - if (U(x,y,1)>y) U(x,y,1) = (float)y; - bound = (float)x - _width; if (U(x,y,0)<=bound) U(x,y,0) = bound; - bound = (float)y - _height; if (U(x,y,1)<=bound) U(x,y,1) = bound; - } else { - if (U(x,y,0)<-x) U(x,y,0) = -(float)x; - if (U(x,y,1)<-y) U(x,y,1) = -(float)y; - bound = (float)_width - x; if (U(x,y,0)>=bound) U(x,y,0) = bound; - bound = (float)_height - y; if (U(x,y,1)>=bound) U(x,y,1) = bound; - } - _energy+=delta_I*delta_I + nsmoothness*_energy_regul; - } - if (V) cimg_forX(V,x) if (V(x,y,2)) { // Apply constraints. - U(x,y,0) = V(x,y,0)/factor; - U(x,y,1) = V(x,y,1)/factor; - } - } - } - } - const float d_energy = (_energy - energy)/(sw*sh*sd); - if (d_energy<=0 && -d_energy<_precision) break; - if (d_energy>0) dt*=0.5f; - energy = _energy; - } - } - return U; - } - - //! Compute correspondence map between two images, using the patch-match algorithm. - /** - \param patch_image The image containing the reference patches to match with the instance image. - \param patch_width Width of the patch used for matching. - \param patch_height Height of the patch used for matching. - \param patch_depth Depth of the patch used for matching. - \param nb_iterations Number of patch-match iterations. - \param nb_randoms Number of randomization attempts (per pixel). - \param guide Image used as the initial correspondence estimate for the algorithm. - 'guide' may have a last channel with boolean values (0=false | other=true) that - tells for each pixel if its correspondence vector is constrained to its initial value (constraint mask). - \param[out] matching_score Returned as the image of matching scores. - \note - The patch-match algorithm is described in this paper: - Connelly Barnes, Eli Shechtman, Adam Finkelstein, Dan B Goldman(2009), - PatchMatch: A Randomized Correspondence Algorithm for Structural Image Editing - **/ - template - CImg& patchmatch(const CImg& patch_image, - const unsigned int patch_width, - const unsigned int patch_height, - const unsigned int patch_depth, - const unsigned int nb_iterations, - const unsigned int nb_randoms, - const CImg &guide, - CImg &matching_score) { - return get_patchmatch(patch_image,patch_width,patch_height,patch_depth, - nb_iterations,nb_randoms,guide,matching_score).move_to(*this); - } - - //! Compute correspondence map between two images, using the patch-match algorithm \newinstance. - template - CImg get_patchmatch(const CImg& patch_image, - const unsigned int patch_width, - const unsigned int patch_height, - const unsigned int patch_depth, - const unsigned int nb_iterations, - const unsigned int nb_randoms, - const CImg &guide, - CImg &matching_score) const { - return _get_patchmatch(patch_image,patch_width,patch_height,patch_depth, - nb_iterations,nb_randoms, - guide,true,matching_score); - } - - //! Compute correspondence map between two images, using the patch-match algorithm \overloading. - template - CImg& patchmatch(const CImg& patch_image, - const unsigned int patch_width, - const unsigned int patch_height, - const unsigned int patch_depth, - const unsigned int nb_iterations, - const unsigned int nb_randoms, - const CImg &guide) { - return get_patchmatch(patch_image,patch_width,patch_height,patch_depth, - nb_iterations,nb_randoms,guide).move_to(*this); - } - - //! Compute correspondence map between two images, using the patch-match algorithm \overloading. - template - CImg get_patchmatch(const CImg& patch_image, - const unsigned int patch_width, - const unsigned int patch_height, - const unsigned int patch_depth, - const unsigned int nb_iterations, - const unsigned int nb_randoms, - const CImg &guide) const { - return _get_patchmatch(patch_image,patch_width,patch_height,patch_depth, - nb_iterations,nb_randoms, - guide,false,CImg::empty()); - } - - //! Compute correspondence map between two images, using the patch-match algorithm \overloading. - CImg& patchmatch(const CImg& patch_image, - const unsigned int patch_width, - const unsigned int patch_height, - const unsigned int patch_depth=1, - const unsigned int nb_iterations=5, - const unsigned int nb_randoms=5) { - return get_patchmatch(patch_image,patch_width,patch_height,patch_depth, - nb_iterations,nb_randoms).move_to(*this); - } - - //! Compute correspondence map between two images, using the patch-match algorithm \overloading. - CImg get_patchmatch(const CImg& patch_image, - const unsigned int patch_width, - const unsigned int patch_height, - const unsigned int patch_depth=1, - const unsigned int nb_iterations=5, - const unsigned int nb_randoms=5) const { - return _get_patchmatch(patch_image,patch_width,patch_height,patch_depth, - nb_iterations,nb_randoms, - CImg::const_empty(), - false,CImg::empty()); - } - - template - CImg _get_patchmatch(const CImg& patch_image, - const unsigned int patch_width, - const unsigned int patch_height, - const unsigned int patch_depth, - const unsigned int nb_iterations, - const unsigned int nb_randoms, - const CImg &guide, - const bool is_matching_score, - CImg &matching_score) const { - if (is_empty()) return CImg::const_empty(); - if (patch_image._spectrum!=_spectrum) - throw CImgArgumentException(_cimg_instance - "patchmatch(): Instance image and specified patch image (%u,%u,%u,%u,%p) " - "have different spectrums.", - cimg_instance, - patch_image._width,patch_image._height,patch_image._depth,patch_image._spectrum, - patch_image._data); - if (patch_width>_width || patch_height>_height || patch_depth>_depth) - throw CImgArgumentException(_cimg_instance - "patchmatch(): Specified patch size %ux%ux%u is bigger than the dimensions " - "of the instance image.", - cimg_instance,patch_width,patch_height,patch_depth); - if (patch_width>patch_image._width || patch_height>patch_image._height || patch_depth>patch_image._depth) - throw CImgArgumentException(_cimg_instance - "patchmatch(): Specified patch size %ux%ux%u is bigger than the dimensions " - "of the patch image image (%u,%u,%u,%u,%p).", - cimg_instance,patch_width,patch_height,patch_depth, - patch_image._width,patch_image._height,patch_image._depth,patch_image._spectrum, - patch_image._data); - const unsigned int - _constraint = patch_image._depth>1?3:2, - constraint = guide._spectrum>_constraint?_constraint:0; - - if (guide && - (guide._width!=_width || guide._height!=_height || guide._depth!=_depth || guide._spectrum<_constraint)) - throw CImgArgumentException(_cimg_instance - "patchmatch(): Specified guide (%u,%u,%u,%u,%p) has invalid dimensions " - "considering instance and patch image image (%u,%u,%u,%u,%p).", - cimg_instance, - guide._width,guide._height,guide._depth,guide._spectrum,guide._data, - patch_image._width,patch_image._height,patch_image._depth,patch_image._spectrum, - patch_image._data); - - CImg map(_width,_height,_depth,patch_image._depth>1?3:2); - CImg score(_width,_height,_depth); - const int - psizew = (int)patch_width, psizew1 = psizew/2, psizew2 = psizew - psizew1 - 1, - psizeh = (int)patch_height, psizeh1 = psizeh/2, psizeh2 = psizeh - psizeh1 - 1, - psized = (int)patch_depth, psized1 = psized/2, psized2 = psized - psized1 - 1; - - if (_depth>1 || patch_image._depth>1) { // 3d version. - - // Initialize correspondence map. - if (guide) cimg_forXYZ(*this,x,y,z) { // User-defined initialization. - const int - cx1 = x<=psizew1?x:(x::inf()); - } else cimg_forXYZ(*this,x,y,z) { // Random initialization. - const int - cx1 = x<=psizew1?x:(x::inf()); - } - - // Start iteration loop. - for (unsigned int iter = 0; iter64 && iter0) { // Compare with left neighbor. - const int u = map(x - 1,y,z,0), v = map(x - 1,y,z,1), w = map(x - 1,y,z,2); - if (u>=cx1 - 1 && u=cy1 && v=cz1 && w0) { // Compare with up neighbor. - const int u = map(x,y - 1,z,0), v = map(x,y - 1,z,1), w = map(x,y - 1,z,2); - if (u>=cx1 && u=cy1 - 1 && v=cz1 && w0) { // Compare with backward neighbor. - const int u = map(x,y,z - 1,0), v = map(x,y,z - 1,1), w = map(x,y,z - 1,2); - if (u>=cx1 && u=cy1 && v=cz1 - 1 && w=cx1 + 1 && u=cy1 && v=cz1 && w=cx1 && u=cy1 + 1 && v=cz1 && w=cx1 && u=cy1 && v=cz1 + 1 && w::inf()); - } else cimg_forXY(*this,x,y) { // Random initialization. - const int - cx1 = x<=psizew1?x:(x::inf()); - } - - // Start iteration loop. - for (unsigned int iter = 0; iter64 && iter0) { // Compare with left neighbor. - const int u = map(x - 1,y,0), v = map(x - 1,y,1); - if (u>=cx1 - 1 && u=cy1 && v0) { // Compare with up neighbor. - const int u = map(x,y - 1,0), v = map(x,y - 1,1); - if (u>=cx1 && u=cy1 - 1 && v=cx1 + 1 && u=cy1 && v=cx1 && u=cy1 + 1 && v& img1, const CImg& img2, - const unsigned int psizew, const unsigned int psizeh, - const int x1, const int y1, - const int x2, const int y2, - const float max_ssd) { // 2d version. - const T *p1 = img1.data(x1,y1), *p2 = img2.data(x2,y2); - const ulongT - offx1 = (ulongT)img1._width - psizew, - offx2 = (ulongT)img2._width - psizew, - offy1 = (ulongT)img1._width*img1._height - psizeh*img1._width, - offy2 = (ulongT)img2._width*img2._height - psizeh*img2._width; - float ssd = 0; - cimg_forC(img1,c) { - for (unsigned int j = 0; jmax_ssd) return max_ssd; - p1+=offx1; p2+=offx2; - } - p1+=offy1; p2+=offy2; - } - return ssd; - } - - static float _patchmatch(const CImg& img1, const CImg& img2, - const unsigned int psizew, const unsigned int psizeh, const unsigned int psized, - const int x1, const int y1, const int z1, - const int x2, const int y2, const int z2, - const float max_ssd) { // 3d version. - const T *p1 = img1.data(x1,y1,z1), *p2 = img2.data(x2,y2,z2); - const ulongT - offx1 = (ulongT)img1._width - psizew, - offx2 = (ulongT)img2._width - psizew, - offy1 = (ulongT)img1._width*img1._height - psizeh*img1._width - psizew, - offy2 = (ulongT)img2._width*img2._height - psizeh*img2._width - psizew, - offz1 = (ulongT)img1._width*img1._height*img1._depth - psized*img1._width*img1._height - - psizeh*img1._width - psizew, - offz2 = (ulongT)img2._width*img2._height*img2._depth - psized*img2._width*img2._height - - psizeh*img2._width - psizew; - float ssd = 0; - cimg_forC(img1,c) { - for (unsigned int k = 0; kmax_ssd) return max_ssd; - p1+=offx1; p2+=offx2; - } - p1+=offy1; p2+=offy2; - } - p1+=offz1; p2+=offz2; - } - return ssd; - } - - //! Compute Euclidean distance function to a specified value. - /** - \param value Reference value. - \param metric Type of metric. Can be { 0=Chebyshev | 1=Manhattan | 2=Euclidean | 3=Squared-euclidean }. - \note - The distance transform implementation has been submitted by A. Meijster, and implements - the article 'W.H. Hesselink, A. Meijster, J.B.T.M. Roerdink, - "A general algorithm for computing distance transforms in linear time.", - In: Mathematical Morphology and its Applications to Image and Signal Processing, - J. Goutsias, L. Vincent, and D.S. Bloomberg (eds.), Kluwer, 2000, pp. 331-340.' - The submitted code has then been modified to fit CImg coding style and constraints. - **/ - CImg& distance(const T& value, const unsigned int metric=2) { - if (is_empty()) return *this; - if (cimg::type::string()!=cimg::type::string()) // For datatype < int. - return CImg(*this,false).distance((Tint)value,metric). - cut((Tint)cimg::type::min(),(Tint)cimg::type::max()).move_to(*this); - bool is_value = false; - cimg_for(*this,ptr,T) *ptr = *ptr==value?is_value=true,0:(T)cimg::max(0,99999999); // Trick to avoid VC++ warning - if (!is_value) return fill(cimg::type::max()); - switch (metric) { - case 0 : return _distance_core(_distance_sep_cdt,_distance_dist_cdt); // Chebyshev. - case 1 : return _distance_core(_distance_sep_mdt,_distance_dist_mdt); // Manhattan. - case 3 : return _distance_core(_distance_sep_edt,_distance_dist_edt); // Squared Euclidean. - default : return _distance_core(_distance_sep_edt,_distance_dist_edt).sqrt(); // Euclidean. - } - return *this; - } - - //! Compute distance to a specified value \newinstance. - CImg get_distance(const T& value, const unsigned int metric=2) const { - return CImg(*this,false).distance((Tfloat)value,metric); - } - - static longT _distance_sep_edt(const longT i, const longT u, const longT *const g) { - return (u*u - i*i + g[u] - g[i])/(2*(u - i)); - } - - static longT _distance_dist_edt(const longT x, const longT i, const longT *const g) { - return (x - i)*(x - i) + g[i]; - } - - static longT _distance_sep_mdt(const longT i, const longT u, const longT *const g) { - return (u - i<=g[u] - g[i]?999999999:(g[u] - g[i] + u + i)/2); - } - - static longT _distance_dist_mdt(const longT x, const longT i, const longT *const g) { - return (x=0) && f(t[q],s[q],g)>f(t[q],u,g)) { --q; } - if (q<0) { q = 0; s[0] = u; } - else { const longT w = 1 + sep(s[q], u, g); if (w<(longT)len) { ++q; s[q] = u; t[q] = w; }} - } - for (int u = (int)len - 1; u>=0; --u) { dt[u] = f(u,s[q],g); if (u==t[q]) --q; } // Backward scan. - } - - CImg& _distance_core(longT (*const sep)(const longT, const longT, const longT *const), - longT (*const f)(const longT, const longT, const longT *const)) { - // Check for g++ 4.9.X, as OpenMP seems to crash for this particular function. I have no clues why. -#define cimg_is_gcc49x (__GNUC__==4 && __GNUC_MINOR__==9) - - const ulongT wh = (ulongT)_width*_height; -#if defined(cimg_use_openmp) && !cimg_is_gcc49x - cimg_pragma_openmp(parallel for cimg_openmp_if(_spectrum>=2)) -#endif - cimg_forC(*this,c) { - CImg g(_width), dt(_width), s(_width), t(_width); - CImg img = get_shared_channel(c); -#if defined(cimg_use_openmp) && !cimg_is_gcc49x - cimg_pragma_openmp(parallel for collapse(2) if (_width>=512 && _height*_depth>=16) firstprivate(g,dt,s,t)) -#endif - cimg_forYZ(*this,y,z) { // Over X-direction. - cimg_forX(*this,x) g[x] = (longT)img(x,y,z,0,wh); - _distance_scan(_width,g,sep,f,s,t,dt); - cimg_forX(*this,x) img(x,y,z,0,wh) = (T)dt[x]; - } - if (_height>1) { - g.assign(_height); dt.assign(_height); s.assign(_height); t.assign(_height); -#if defined(cimg_use_openmp) && !cimg_is_gcc49x - cimg_pragma_openmp(parallel for collapse(2) if (_height>=512 && _width*_depth>=16) firstprivate(g,dt,s,t)) -#endif - cimg_forXZ(*this,x,z) { // Over Y-direction. - cimg_forY(*this,y) g[y] = (longT)img(x,y,z,0,wh); - _distance_scan(_height,g,sep,f,s,t,dt); - cimg_forY(*this,y) img(x,y,z,0,wh) = (T)dt[y]; - } - } - if (_depth>1) { - g.assign(_depth); dt.assign(_depth); s.assign(_depth); t.assign(_depth); -#if defined(cimg_use_openmp) && !cimg_is_gcc49x - cimg_pragma_openmp(parallel for collapse(2) if (_depth>=512 && _width*_height>=16) firstprivate(g,dt,s,t)) -#endif - cimg_forXY(*this,x,y) { // Over Z-direction. - cimg_forZ(*this,z) g[z] = (longT)img(x,y,z,0,wh); - _distance_scan(_depth,g,sep,f,s,t,dt); - cimg_forZ(*this,z) img(x,y,z,0,wh) = (T)dt[z]; - } - } - } - return *this; - } - - //! Compute chamfer distance to a specified value, with a custom metric. - /** - \param value Reference value. - \param metric_mask Metric mask. - \note The algorithm code has been initially proposed by A. Meijster, and modified by D. Tschumperlé. - **/ - template - CImg& distance(const T& value, const CImg& metric_mask) { - if (is_empty()) return *this; - bool is_value = false; - cimg_for(*this,ptr,T) *ptr = *ptr==value?is_value=true,0:(T)999999999; - if (!is_value) return fill(cimg::type::max()); - const ulongT wh = (ulongT)_width*_height; - cimg_pragma_openmp(parallel for cimg_openmp_if(_spectrum>=2)) - cimg_forC(*this,c) { - CImg img = get_shared_channel(c); - cimg_pragma_openmp(parallel for collapse(3) if (_width*_height*_depth>=1024)) - cimg_forXYZ(metric_mask,dx,dy,dz) { - const t weight = metric_mask(dx,dy,dz); - if (weight) { - for (int z = dz, nz = 0; z=0; --z,--nz) { // Backward scan. - for (int y = height() - 1 - dy, ny = height() - 1; y>=0; --y,--ny) { - for (int x = width() - 1 - dx, nx = width() - 1; x>=0; --x,--nx) { - const T dd = img(nx,ny,nz,0,wh) + weight; - if (dd - CImg get_distance(const T& value, const CImg& metric_mask) const { - return CImg(*this,false).distance(value,metric_mask); - } - - //! Compute distance to a specified value, according to a custom metric (use dijkstra algorithm). - /** - \param value Reference value. - \param metric Field of distance potentials. - \param is_high_connectivity Tells if the algorithm uses low or high connectivity. - **/ - template - CImg& distance_dijkstra(const T& value, const CImg& metric, const bool is_high_connectivity, - CImg& return_path) { - return get_distance_dijkstra(value,metric,is_high_connectivity,return_path).move_to(*this); - } - - //! Compute distance map to a specified value, according to a custom metric (use dijkstra algorithm) \newinstance. - template - CImg::type> - get_distance_dijkstra(const T& value, const CImg& metric, const bool is_high_connectivity, - CImg& return_path) const { - if (is_empty()) return return_path.assign(); - if (!is_sameXYZ(metric)) - throw CImgArgumentException(_cimg_instance - "distance_dijkstra(): image instance and metric map (%u,%u,%u,%u) " - "have incompatible dimensions.", - cimg_instance, - metric._width,metric._height,metric._depth,metric._spectrum); - typedef typename cimg::superset::type td; // Type used for computing cumulative distances. - CImg result(_width,_height,_depth,_spectrum), Q; - CImg is_queued(_width,_height,_depth,1); - if (return_path) return_path.assign(_width,_height,_depth,_spectrum); - - cimg_forC(*this,c) { - const CImg img = get_shared_channel(c); - const CImg met = metric.get_shared_channel(c%metric._spectrum); - CImg res = result.get_shared_channel(c); - CImg path = return_path?return_path.get_shared_channel(c):CImg(); - unsigned int sizeQ = 0; - - // Detect initial seeds. - is_queued.fill(0); - cimg_forXYZ(img,x,y,z) if (img(x,y,z)==value) { - Q._priority_queue_insert(is_queued,sizeQ,0,x,y,z); - res(x,y,z) = 0; - if (path) path(x,y,z) = (to)0; - } - - // Start distance propagation. - while (sizeQ) { - - // Get and remove point with minimal potential from the queue. - const int x = (int)Q(0,1), y = (int)Q(0,2), z = (int)Q(0,3); - const td P = (td)-Q(0,0); - Q._priority_queue_remove(sizeQ); - - // Update neighbors. - td npot = 0; - if (x - 1>=0 && Q._priority_queue_insert(is_queued,sizeQ,-(npot=met(x - 1,y,z) + P),x - 1,y,z)) { - res(x - 1,y,z) = npot; if (path) path(x - 1,y,z) = (to)2; - } - if (x + 1=0 && Q._priority_queue_insert(is_queued,sizeQ,-(npot=met(x,y - 1,z) + P),x,y - 1,z)) { - res(x,y - 1,z) = npot; if (path) path(x,y - 1,z) = (to)8; - } - if (y + 1=0 && Q._priority_queue_insert(is_queued,sizeQ,-(npot=met(x,y,z - 1) + P),x,y,z - 1)) { - res(x,y,z - 1) = npot; if (path) path(x,y,z - 1) = (to)32; - } - if (z + 1=0 && y - 1>=0 && - Q._priority_queue_insert(is_queued,sizeQ,-(npot=(td)(sqrt2*met(x - 1,y - 1,z) + P)),x - 1,y - 1,z)) { - res(x - 1,y - 1,z) = npot; if (path) path(x - 1,y - 1,z) = (to)10; - } - if (x + 1=0 && - Q._priority_queue_insert(is_queued,sizeQ,-(npot=(td)(sqrt2*met(x + 1,y - 1,z) + P)),x + 1,y - 1,z)) { - res(x + 1,y - 1,z) = npot; if (path) path(x + 1,y - 1,z) = (to)9; - } - if (x - 1>=0 && y + 1=0) { // Diagonal neighbors on slice z - 1. - if (x - 1>=0 && - Q._priority_queue_insert(is_queued,sizeQ,-(npot=(td)(sqrt2*met(x - 1,y,z - 1) + P)),x - 1,y,z - 1)) { - res(x - 1,y,z - 1) = npot; if (path) path(x - 1,y,z - 1) = (to)34; - } - if (x + 1=0 && - Q._priority_queue_insert(is_queued,sizeQ,-(npot=(td)(sqrt2*met(x,y - 1,z - 1) + P)),x,y - 1,z - 1)) { - res(x,y - 1,z - 1) = npot; if (path) path(x,y - 1,z - 1) = (to)40; - } - if (y + 1=0 && y - 1>=0 && - Q._priority_queue_insert(is_queued,sizeQ,-(npot=(td)(sqrt3*met(x - 1,y - 1,z - 1) + P)), - x - 1,y - 1,z - 1)) { - res(x - 1,y - 1,z - 1) = npot; if (path) path(x - 1,y - 1,z - 1) = (to)42; - } - if (x + 1=0 && - Q._priority_queue_insert(is_queued,sizeQ,-(npot=(td)(sqrt3*met(x + 1,y - 1,z - 1) + P)), - x + 1,y - 1,z - 1)) { - res(x + 1,y - 1,z - 1) = npot; if (path) path(x + 1,y - 1,z - 1) = (to)41; - } - if (x - 1>=0 && y + 1=0 && - Q._priority_queue_insert(is_queued,sizeQ,-(npot=(td)(sqrt2*met(x - 1,y,z + 1) + P)),x - 1,y,z + 1)) { - res(x - 1,y,z + 1) = npot; if (path) path(x - 1,y,z + 1) = (to)18; - } - if (x + 1=0 && - Q._priority_queue_insert(is_queued,sizeQ,-(npot=(td)(sqrt2*met(x,y - 1,z + 1) + P)),x,y - 1,z + 1)) { - res(x,y - 1,z + 1) = npot; if (path) path(x,y - 1,z + 1) = (to)24; - } - if (y + 1=0 && y - 1>=0 && - Q._priority_queue_insert(is_queued,sizeQ,-(npot=(td)(sqrt3*met(x - 1,y - 1,z + 1) + P)), - x - 1,y - 1,z + 1)) { - res(x - 1,y - 1,z + 1) = npot; if (path) path(x - 1,y - 1,z + 1) = (to)26; - } - if (x + 1=0 && - Q._priority_queue_insert(is_queued,sizeQ,-(npot=(td)(sqrt3*met(x + 1,y - 1,z + 1) + P)), - x + 1,y - 1,z + 1)) { - res(x + 1,y - 1,z + 1) = npot; if (path) path(x + 1,y - 1,z + 1) = (to)25; - } - if (x - 1>=0 && y + 1 - CImg& distance_dijkstra(const T& value, const CImg& metric, - const bool is_high_connectivity=false) { - return get_distance_dijkstra(value,metric,is_high_connectivity).move_to(*this); - } - - //! Compute distance map to a specified value, according to a custom metric (use dijkstra algorithm). \newinstance. - template - CImg get_distance_dijkstra(const T& value, const CImg& metric, - const bool is_high_connectivity=false) const { - CImg return_path; - return get_distance_dijkstra(value,metric,is_high_connectivity,return_path); - } - - //! Compute distance map to one source point, according to a custom metric (use fast marching algorithm). - /** - \param value Reference value. - \param metric Field of distance potentials. - **/ - template - CImg& distance_eikonal(const T& value, const CImg& metric) { - return get_distance_eikonal(value,metric).move_to(*this); - } - - //! Compute distance map to one source point, according to a custom metric (use fast marching algorithm). - template - CImg get_distance_eikonal(const T& value, const CImg& metric) const { - if (is_empty()) return *this; - if (!is_sameXYZ(metric)) - throw CImgArgumentException(_cimg_instance - "distance_eikonal(): image instance and metric map (%u,%u,%u,%u) have " - "incompatible dimensions.", - cimg_instance, - metric._width,metric._height,metric._depth,metric._spectrum); - CImg result(_width,_height,_depth,_spectrum,cimg::type::max()), Q; - CImg state(_width,_height,_depth); // -1=far away, 0=narrow, 1=frozen. - - cimg_pragma_openmp(parallel for cimg_openmp_if(_spectrum>=2) firstprivate(Q,state)) - cimg_forC(*this,c) { - const CImg img = get_shared_channel(c); - const CImg met = metric.get_shared_channel(c%metric._spectrum); - CImg res = result.get_shared_channel(c); - unsigned int sizeQ = 0; - state.fill(-1); - - // Detect initial seeds. - Tfloat *ptr1 = res._data; char *ptr2 = state._data; - cimg_for(img,ptr0,T) { if (*ptr0==value) { *ptr1 = 0; *ptr2 = 1; } ++ptr1; ++ptr2; } - - // Initialize seeds neighbors. - ptr2 = state._data; - cimg_forXYZ(img,x,y,z) if (*(ptr2++)==1) { - if (x - 1>=0 && state(x - 1,y,z)==-1) { - const Tfloat dist = res(x - 1,y,z) = __distance_eikonal(res,met(x - 1,y,z),x - 1,y,z); - Q._eik_priority_queue_insert(state,sizeQ,-dist,x - 1,y,z); - } - if (x + 1=0 && state(x,y - 1,z)==-1) { - const Tfloat dist = res(x,y - 1,z) = __distance_eikonal(res,met(x,y - 1,z),x,y - 1,z); - Q._eik_priority_queue_insert(state,sizeQ,-dist,x,y - 1,z); - } - if (y + 1=0 && state(x,y,z - 1)==-1) { - const Tfloat dist = res(x,y,z - 1) = __distance_eikonal(res,met(x,y,z - 1),x,y,z - 1); - Q._eik_priority_queue_insert(state,sizeQ,-dist,x,y,z - 1); - } - if (z + 1=0) { - if (x - 1>=0 && state(x - 1,y,z)!=1) { - const Tfloat dist = __distance_eikonal(res,met(x - 1,y,z),x - 1,y,z); - if (dist=0 && state(x,y - 1,z)!=1) { - const Tfloat dist = __distance_eikonal(res,met(x,y - 1,z),x,y - 1,z); - if (dist=0 && state(x,y,z - 1)!=1) { - const Tfloat dist = __distance_eikonal(res,met(x,y,z - 1),x,y,z - 1); - if (dist& res, const Tfloat P, - const int x=0, const int y=0, const int z=0) const { - const T M = cimg::type::max(); - T T1 = cimg::min(x - 1>=0?res(x - 1,y,z):M,x + 11) { // 3d. - T - T2 = cimg::min(y - 1>=0?res(x,y - 1,z):M,y + 1=0?res(x,y,z - 1):M,z + 1T2) cimg::swap(T1,T2); - if (T2>T3) cimg::swap(T2,T3); - if (T1>T2) cimg::swap(T1,T2); - if (P<=0) return (Tfloat)T1; - if (T31) { // 2d. - T T2 = cimg::min(y - 1>=0?res(x,y - 1,z):M,y + 1T2) cimg::swap(T1,T2); - if (P<=0) return (Tfloat)T1; - if (T2 - void _eik_priority_queue_insert(CImg& state, unsigned int& siz, const t value, - const unsigned int x, const unsigned int y, const unsigned int z) { - if (state(x,y,z)>0) return; - state(x,y,z) = 0; - if (++siz>=_width) { if (!is_empty()) resize(_width*2,4,1,1,0); else assign(64,4); } - (*this)(siz - 1,0) = (T)value; (*this)(siz - 1,1) = (T)x; (*this)(siz - 1,2) = (T)y; (*this)(siz - 1,3) = (T)z; - for (unsigned int pos = siz - 1, par = 0; pos && value>(*this)(par=(pos + 1)/2 - 1,0); pos = par) { - cimg::swap((*this)(pos,0),(*this)(par,0)); cimg::swap((*this)(pos,1),(*this)(par,1)); - cimg::swap((*this)(pos,2),(*this)(par,2)); cimg::swap((*this)(pos,3),(*this)(par,3)); - } - } - - //! Compute distance function to 0-valued isophotes, using the Eikonal PDE. - /** - \param nb_iterations Number of PDE iterations. - \param band_size Size of the narrow band. - \param time_step Time step of the PDE iterations. - **/ - CImg& distance_eikonal(const unsigned int nb_iterations, const float band_size=0, const float time_step=0.5f) { - if (is_empty()) return *this; - CImg velocity(*this); - for (unsigned int iteration = 0; iteration1) { // 3d - CImg_3x3x3(I,Tfloat); - cimg_forC(*this,c) cimg_for3x3x3(*this,x,y,z,c,I,Tfloat) if (band_size<=0 || cimg::abs(Iccc)0?(Incc - Iccc):(Iccc - Ipcc), - iy = gy*sgn>0?(Icnc - Iccc):(Iccc - Icpc), - iz = gz*sgn>0?(Iccn - Iccc):(Iccc - Iccp), - ng = (Tfloat)(1e-5f + std::sqrt(gx*gx + gy*gy + gz*gz)), - ngx = gx/ng, - ngy = gy/ng, - ngz = gz/ng, - veloc = sgn*(ngx*ix + ngy*iy + ngz*iz - 1); - *(ptrd++) = veloc; - if (veloc>veloc_max) veloc_max = veloc; else if (-veloc>veloc_max) veloc_max = -veloc; - } else *(ptrd++) = 0; - } else { // 2d version - CImg_3x3(I,Tfloat); - cimg_forC(*this,c) cimg_for3x3(*this,x,y,0,c,I,Tfloat) if (band_size<=0 || cimg::abs(Icc)0?(Inc - Icc):(Icc - Ipc), - iy = gy*sgn>0?(Icn - Icc):(Icc - Icp), - ng = (Tfloat)(1e-5f + std::sqrt(gx*gx + gy*gy)), - ngx = gx/ng, - ngy = gy/ng, - veloc = sgn*(ngx*ix + ngy*iy - 1); - *(ptrd++) = veloc; - if (veloc>veloc_max) veloc_max = veloc; else if (-veloc>veloc_max) veloc_max = -veloc; - } else *(ptrd++) = 0; - } - if (veloc_max>0) *this+=(velocity*=time_step/veloc_max); - } - return *this; - } - - //! Compute distance function to 0-valued isophotes, using the Eikonal PDE \newinstance. - CImg get_distance_eikonal(const unsigned int nb_iterations, const float band_size=0, - const float time_step=0.5f) const { - return CImg(*this,false).distance_eikonal(nb_iterations,band_size,time_step); - } - - //! Compute Haar multiscale wavelet transform. - /** - \param axis Axis considered for the transform. - \param invert Set inverse of direct transform. - \param nb_scales Number of scales used for the transform. - **/ - CImg& haar(const char axis, const bool invert=false, const unsigned int nb_scales=1) { - return get_haar(axis,invert,nb_scales).move_to(*this); - } - - //! Compute Haar multiscale wavelet transform \newinstance. - CImg get_haar(const char axis, const bool invert=false, const unsigned int nb_scales=1) const { - if (is_empty() || !nb_scales) return +*this; - CImg res; - const Tfloat sqrt2 = std::sqrt(2.0f); - if (nb_scales==1) { - switch (cimg::lowercase(axis)) { // Single scale transform - case 'x' : { - const unsigned int w = _width/2; - if (w) { - if ((w%2) && w!=1) - throw CImgInstanceException(_cimg_instance - "haar(): Sub-image width %u is not even.", - cimg_instance, - w); - - res.assign(_width,_height,_depth,_spectrum); - if (invert) cimg_forYZC(*this,y,z,c) { // Inverse transform along X - for (unsigned int x = 0, xw = w, x2 = 0; x& haar(const bool invert=false, const unsigned int nb_scales=1) { - return get_haar(invert,nb_scales).move_to(*this); - } - - //! Compute Haar multiscale wavelet transform \newinstance. - CImg get_haar(const bool invert=false, const unsigned int nb_scales=1) const { - CImg res; - if (nb_scales==1) { // Single scale transform - if (_width>1) get_haar('x',invert,1).move_to(res); - if (_height>1) { if (res) res.haar('y',invert,1); else get_haar('y',invert,1).move_to(res); } - if (_depth>1) { if (res) res.haar('z',invert,1); else get_haar('z',invert,1).move_to(res); } - if (res) return res; - } else { // Multi-scale transform - if (invert) { // Inverse transform - res.assign(*this); - if (_width>1) { - if (_height>1) { - if (_depth>1) { - unsigned int w = _width, h = _height, d = _depth; - for (unsigned int s = 1; w && h && d && s1) { - unsigned int w = _width, d = _depth; - for (unsigned int s = 1; w && d && s1) { - if (_depth>1) { - unsigned int h = _height, d = _depth; - for (unsigned int s = 1; h && d && s1) { - unsigned int d = _depth; - for (unsigned int s = 1; d && s1) { - if (_height>1) { - if (_depth>1) - for (unsigned int s = 1, w = _width/2, h = _height/2, d = _depth/2; w && h && d && s1) for (unsigned int s = 1, w = _width/2, d = _depth/2; w && d && s1) { - if (_depth>1) - for (unsigned int s = 1, h = _height/2, d = _depth/2; h && d && s1) for (unsigned int s = 1, d = _depth/2; d && s get_FFT(const char axis, const bool is_invert=false) const { - CImgList res(*this,CImg()); - CImg::FFT(res[0],res[1],axis,is_invert); - return res; - } - - //! Compute n-d Fast Fourier Transform. - /* - \param is_invert Tells if the forward (\c false) or inverse (\c true) FFT is computed. - **/ - CImgList get_FFT(const bool is_invert=false) const { - CImgList res(*this,CImg()); - CImg::FFT(res[0],res[1],is_invert); - return res; - } - - //! Compute 1d Fast Fourier Transform, along a specified axis. - /** - \param[in,out] real Real part of the pixel values. - \param[in,out] imag Imaginary part of the pixel values. - \param axis Axis along which the FFT is computed. - \param is_invert Tells if the forward (\c false) or inverse (\c true) FFT is computed. - **/ - static void FFT(CImg& real, CImg& imag, const char axis, const bool is_invert=false) { - if (!real) - throw CImgInstanceException("CImg<%s>::FFT(): Specified real part is empty.", - pixel_type()); - - if (!imag) imag.assign(real._width,real._height,real._depth,real._spectrum,0); - if (!real.is_sameXYZC(imag)) - throw CImgInstanceException("CImg<%s>::FFT(): Specified real part (%u,%u,%u,%u,%p) and " - "imaginary part (%u,%u,%u,%u,%p) have different dimensions.", - pixel_type(), - real._width,real._height,real._depth,real._spectrum,real._data, - imag._width,imag._height,imag._depth,imag._spectrum,imag._data); -#ifdef cimg_use_fftw3 - cimg::mutex(12); - fftw_complex *data_in; - fftw_plan data_plan; - - switch (cimg::lowercase(axis)) { - case 'x' : { // Fourier along X, using FFTW library. - data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*real._width); - if (!data_in) throw CImgInstanceException("CImgList<%s>::FFT(): Failed to allocate memory (%s) " - "for computing FFT of image (%u,%u,%u,%u) along the X-axis.", - pixel_type(), - cimg::strbuffersize(sizeof(fftw_complex)*real._width), - real._width,real._height,real._depth,real._spectrum); - - data_plan = fftw_plan_dft_1d(real._width,data_in,data_in,is_invert?FFTW_BACKWARD:FFTW_FORWARD,FFTW_ESTIMATE); - cimg_forYZC(real,y,z,c) { - T *ptrr = real.data(0,y,z,c), *ptri = imag.data(0,y,z,c); - double *ptrd = (double*)data_in; - cimg_forX(real,x) { *(ptrd++) = (double)*(ptrr++); *(ptrd++) = (double)*(ptri++); } - fftw_execute(data_plan); - const unsigned int fact = real._width; - if (is_invert) cimg_forX(real,x) { *(--ptri) = (T)(*(--ptrd)/fact); *(--ptrr) = (T)(*(--ptrd)/fact); } - else cimg_forX(real,x) { *(--ptri) = (T)*(--ptrd); *(--ptrr) = (T)*(--ptrd); } - } - } break; - case 'y' : { // Fourier along Y, using FFTW library. - data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * real._height); - if (!data_in) throw CImgInstanceException("CImgList<%s>::FFT(): Failed to allocate memory (%s) " - "for computing FFT of image (%u,%u,%u,%u) along the Y-axis.", - pixel_type(), - cimg::strbuffersize(sizeof(fftw_complex)*real._height), - real._width,real._height,real._depth,real._spectrum); - - data_plan = fftw_plan_dft_1d(real._height,data_in,data_in,is_invert?FFTW_BACKWARD:FFTW_FORWARD,FFTW_ESTIMATE); - const unsigned int off = real._width; - cimg_forXZC(real,x,z,c) { - T *ptrr = real.data(x,0,z,c), *ptri = imag.data(x,0,z,c); - double *ptrd = (double*)data_in; - cimg_forY(real,y) { *(ptrd++) = (double)*ptrr; *(ptrd++) = (double)*ptri; ptrr+=off; ptri+=off; } - fftw_execute(data_plan); - const unsigned int fact = real._height; - if (is_invert) - cimg_forY(real,y) { ptrr-=off; ptri-=off; *ptri = (T)(*(--ptrd)/fact); *ptrr = (T)(*(--ptrd)/fact); } - else cimg_forY(real,y) { ptrr-=off; ptri-=off; *ptri = (T)*(--ptrd); *ptrr = (T)*(--ptrd); } - } - } break; - case 'z' : { // Fourier along Z, using FFTW library. - data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * real._depth); - if (!data_in) throw CImgInstanceException("CImgList<%s>::FFT(): Failed to allocate memory (%s) " - "for computing FFT of image (%u,%u,%u,%u) along the Z-axis.", - pixel_type(), - cimg::strbuffersize(sizeof(fftw_complex)*real._depth), - real._width,real._height,real._depth,real._spectrum); - - data_plan = fftw_plan_dft_1d(real._depth,data_in,data_in,is_invert?FFTW_BACKWARD:FFTW_FORWARD,FFTW_ESTIMATE); - const ulongT off = (ulongT)real._width*real._height; - cimg_forXYC(real,x,y,c) { - T *ptrr = real.data(x,y,0,c), *ptri = imag.data(x,y,0,c); - double *ptrd = (double*)data_in; - cimg_forZ(real,z) { *(ptrd++) = (double)*ptrr; *(ptrd++) = (double)*ptri; ptrr+=off; ptri+=off; } - fftw_execute(data_plan); - const unsigned int fact = real._depth; - if (is_invert) - cimg_forZ(real,z) { ptrr-=off; ptri-=off; *ptri = (T)(*(--ptrd)/fact); *ptrr = (T)(*(--ptrd)/fact); } - else cimg_forZ(real,z) { ptrr-=off; ptri-=off; *ptri = (T)*(--ptrd); *ptrr = (T)*(--ptrd); } - } - } break; - default : - throw CImgArgumentException("CImgList<%s>::FFT(): Invalid specified axis '%c' for real and imaginary parts " - "(%u,%u,%u,%u) " - "(should be { x | y | z }).", - pixel_type(),axis, - real._width,real._height,real._depth,real._spectrum); - } - fftw_destroy_plan(data_plan); - fftw_free(data_in); - cimg::mutex(12,0); -#else - switch (cimg::lowercase(axis)) { - case 'x' : { // Fourier along X, using built-in functions. - const unsigned int N = real._width, N2 = N>>1; - if (((N - 1)&N) && N!=1) - throw CImgInstanceException("CImgList<%s>::FFT(): Specified real and imaginary parts (%u,%u,%u,%u) " - "have non 2^N dimension along the X-axis.", - pixel_type(), - real._width,real._height,real._depth,real._spectrum); - - for (unsigned int i = 0, j = 0; ii) cimg_forYZC(real,y,z,c) { - cimg::swap(real(i,y,z,c),real(j,y,z,c)); - cimg::swap(imag(i,y,z,c),imag(j,y,z,c)); - if (j=m; j-=m, m = n, n>>=1) {} - } - for (unsigned int delta = 2; delta<=N; delta<<=1) { - const unsigned int delta2 = delta>>1; - for (unsigned int i = 0; i>1; - if (((N - 1)&N) && N!=1) - throw CImgInstanceException("CImgList<%s>::FFT(): Specified real and imaginary parts (%u,%u,%u,%u) " - "have non 2^N dimension along the Y-axis.", - pixel_type(), - real._width,real._height,real._depth,real._spectrum); - - for (unsigned int i = 0, j = 0; ii) cimg_forXZC(real,x,z,c) { - cimg::swap(real(x,i,z,c),real(x,j,z,c)); - cimg::swap(imag(x,i,z,c),imag(x,j,z,c)); - if (j=m; j-=m, m = n, n>>=1) {} - } - for (unsigned int delta = 2; delta<=N; delta<<=1) { - const unsigned int delta2 = (delta>>1); - for (unsigned int i = 0; i>1; - if (((N - 1)&N) && N!=1) - throw CImgInstanceException("CImgList<%s>::FFT(): Specified real and imaginary parts (%u,%u,%u,%u) " - "have non 2^N dimension along the Z-axis.", - pixel_type(), - real._width,real._height,real._depth,real._spectrum); - - for (unsigned int i = 0, j = 0; ii) cimg_forXYC(real,x,y,c) { - cimg::swap(real(x,y,i,c),real(x,y,j,c)); - cimg::swap(imag(x,y,i,c),imag(x,y,j,c)); - if (j=m; j-=m, m = n, n>>=1) {} - } - for (unsigned int delta = 2; delta<=N; delta<<=1) { - const unsigned int delta2 = (delta>>1); - for (unsigned int i = 0; i::FFT(): Invalid specified axis '%c' for real and imaginary parts " - "(%u,%u,%u,%u) " - "(should be { x | y | z }).", - pixel_type(),axis, - real._width,real._height,real._depth,real._spectrum); - } -#endif - } - - //! Compute n-d Fast Fourier Transform. - /** - \param[in,out] real Real part of the pixel values. - \param[in,out] imag Imaginary part of the pixel values. - \param is_invert Tells if the forward (\c false) or inverse (\c true) FFT is computed. - \param nb_threads Number of parallel threads used for the computation. - Use \c 0 to set this to the number of available cpus. - **/ - static void FFT(CImg& real, CImg& imag, const bool is_invert=false, const unsigned int nb_threads=0) { - if (!real) - throw CImgInstanceException("CImgList<%s>::FFT(): Empty specified real part.", - pixel_type()); - - if (!imag) imag.assign(real._width,real._height,real._depth,real._spectrum,0); - if (!real.is_sameXYZC(imag)) - throw CImgInstanceException("CImgList<%s>::FFT(): Specified real part (%u,%u,%u,%u,%p) and " - "imaginary part (%u,%u,%u,%u,%p) have different dimensions.", - pixel_type(), - real._width,real._height,real._depth,real._spectrum,real._data, - imag._width,imag._height,imag._depth,imag._spectrum,imag._data); - -#ifdef cimg_use_fftw3 - cimg::mutex(12); -#ifndef cimg_use_fftw3_singlethread - const unsigned int _nb_threads = nb_threads?nb_threads:cimg::nb_cpus(); - static int fftw_st = fftw_init_threads(); - cimg::unused(fftw_st); - fftw_plan_with_nthreads(_nb_threads); -#else - cimg::unused(nb_threads); -#endif - fftw_complex *data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*real._width*real._height*real._depth); - if (!data_in) throw CImgInstanceException("CImgList<%s>::FFT(): Failed to allocate memory (%s) " - "for computing FFT of image (%u,%u,%u,%u).", - pixel_type(), - cimg::strbuffersize(sizeof(fftw_complex)*real._width* - real._height*real._depth*real._spectrum), - real._width,real._height,real._depth,real._spectrum); - - fftw_plan data_plan; - const ulongT w = (ulongT)real._width, wh = w*real._height, whd = wh*real._depth; - data_plan = fftw_plan_dft_3d(real._width,real._height,real._depth,data_in,data_in, - is_invert?FFTW_BACKWARD:FFTW_FORWARD,FFTW_ESTIMATE); - cimg_forC(real,c) { - T *ptrr = real.data(0,0,0,c), *ptri = imag.data(0,0,0,c); - double *ptrd = (double*)data_in; - for (unsigned int x = 0; x1) FFT(real,imag,'z',is_invert); - if (real._height>1) FFT(real,imag,'y',is_invert); - if (real._width>1) FFT(real,imag,'x',is_invert); -#endif - } - - //@} - //------------------------------------- - // - //! \name 3d Objects Management - //@{ - //------------------------------------- - - //! Shift 3d object's vertices. - /** - \param tx X-coordinate of the 3d displacement vector. - \param ty Y-coordinate of the 3d displacement vector. - \param tz Z-coordinate of the 3d displacement vector. - **/ - CImg& shift_object3d(const float tx, const float ty=0, const float tz=0) { - if (_height!=3 || _depth>1 || _spectrum>1) - throw CImgInstanceException(_cimg_instance - "shift_object3d(): Instance is not a set of 3d vertices.", - cimg_instance); - - get_shared_row(0)+=tx; get_shared_row(1)+=ty; get_shared_row(2)+=tz; - return *this; - } - - //! Shift 3d object's vertices \newinstance. - CImg get_shift_object3d(const float tx, const float ty=0, const float tz=0) const { - return CImg(*this,false).shift_object3d(tx,ty,tz); - } - - //! Shift 3d object's vertices, so that it becomes centered. - /** - \note The object center is computed as its barycenter. - **/ - CImg& shift_object3d() { - if (_height!=3 || _depth>1 || _spectrum>1) - throw CImgInstanceException(_cimg_instance - "shift_object3d(): Instance is not a set of 3d vertices.", - cimg_instance); - - CImg xcoords = get_shared_row(0), ycoords = get_shared_row(1), zcoords = get_shared_row(2); - float - xm, xM = (float)xcoords.max_min(xm), - ym, yM = (float)ycoords.max_min(ym), - zm, zM = (float)zcoords.max_min(zm); - xcoords-=(xm + xM)/2; ycoords-=(ym + yM)/2; zcoords-=(zm + zM)/2; - return *this; - } - - //! Shift 3d object's vertices, so that it becomes centered \newinstance. - CImg get_shift_object3d() const { - return CImg(*this,false).shift_object3d(); - } - - //! Resize 3d object. - /** - \param sx Width of the 3d object's bounding box. - \param sy Height of the 3d object's bounding box. - \param sz Depth of the 3d object's bounding box. - **/ - CImg& resize_object3d(const float sx, const float sy=-100, const float sz=-100) { - if (_height!=3 || _depth>1 || _spectrum>1) - throw CImgInstanceException(_cimg_instance - "resize_object3d(): Instance is not a set of 3d vertices.", - cimg_instance); - - CImg xcoords = get_shared_row(0), ycoords = get_shared_row(1), zcoords = get_shared_row(2); - float - xm, xM = (float)xcoords.max_min(xm), - ym, yM = (float)ycoords.max_min(ym), - zm, zM = (float)zcoords.max_min(zm); - if (xm0) xcoords*=sx/(xM-xm); else xcoords*=-sx/100; } - if (ym0) ycoords*=sy/(yM-ym); else ycoords*=-sy/100; } - if (zm0) zcoords*=sz/(zM-zm); else zcoords*=-sz/100; } - return *this; - } - - //! Resize 3d object \newinstance. - CImg get_resize_object3d(const float sx, const float sy=-100, const float sz=-100) const { - return CImg(*this,false).resize_object3d(sx,sy,sz); - } - - //! Resize 3d object to unit size. - CImg resize_object3d() { - if (_height!=3 || _depth>1 || _spectrum>1) - throw CImgInstanceException(_cimg_instance - "resize_object3d(): Instance is not a set of 3d vertices.", - cimg_instance); - - CImg xcoords = get_shared_row(0), ycoords = get_shared_row(1), zcoords = get_shared_row(2); - float - xm, xM = (float)xcoords.max_min(xm), - ym, yM = (float)ycoords.max_min(ym), - zm, zM = (float)zcoords.max_min(zm); - const float dx = xM - xm, dy = yM - ym, dz = zM - zm, dmax = cimg::max(dx,dy,dz); - if (dmax>0) { xcoords/=dmax; ycoords/=dmax; zcoords/=dmax; } - return *this; - } - - //! Resize 3d object to unit size \newinstance. - CImg get_resize_object3d() const { - return CImg(*this,false).resize_object3d(); - } - - //! Merge two 3d objects together. - /** - \param[in,out] primitives Primitives data of the current 3d object. - \param obj_vertices Vertices data of the additional 3d object. - \param obj_primitives Primitives data of the additional 3d object. - **/ - template - CImg& append_object3d(CImgList& primitives, const CImg& obj_vertices, - const CImgList& obj_primitives) { - if (!obj_vertices || !obj_primitives) return *this; - if (obj_vertices._height!=3 || obj_vertices._depth>1 || obj_vertices._spectrum>1) - throw CImgInstanceException(_cimg_instance - "append_object3d(): Specified vertice image (%u,%u,%u,%u,%p) is not a " - "set of 3d vertices.", - cimg_instance, - obj_vertices._width,obj_vertices._height, - obj_vertices._depth,obj_vertices._spectrum,obj_vertices._data); - - if (is_empty()) { primitives.assign(obj_primitives); return assign(obj_vertices); } - if (_height!=3 || _depth>1 || _spectrum>1) - throw CImgInstanceException(_cimg_instance - "append_object3d(): Instance is not a set of 3d vertices.", - cimg_instance); - - const unsigned int P = _width; - append(obj_vertices,'x'); - const unsigned int N = primitives._width; - primitives.insert(obj_primitives); - for (unsigned int i = N; i &p = primitives[i]; - switch (p.size()) { - case 1 : p[0]+=P; break; // Point. - case 5 : p[0]+=P; p[1]+=P; break; // Sphere. - case 2 : case 6 : p[0]+=P; p[1]+=P; break; // Segment. - case 3 : case 9 : p[0]+=P; p[1]+=P; p[2]+=P; break; // Triangle. - case 4 : case 12 : p[0]+=P; p[1]+=P; p[2]+=P; p[3]+=P; break; // Rectangle. - } - } - return *this; - } - - //! Texturize primitives of a 3d object. - /** - \param[in,out] primitives Primitives data of the 3d object. - \param[in,out] colors Colors data of the 3d object. - \param texture Texture image to map to 3d object. - \param coords Texture-mapping coordinates. - **/ - template - const CImg& texturize_object3d(CImgList& primitives, CImgList& colors, - const CImg& texture, const CImg& coords=CImg::const_empty()) const { - if (is_empty()) return *this; - if (_height!=3) - throw CImgInstanceException(_cimg_instance - "texturize_object3d(): image instance is not a set of 3d points.", - cimg_instance); - if (coords && (coords._width!=_width || coords._height!=2)) - throw CImgArgumentException(_cimg_instance - "texturize_object3d(): Invalid specified texture coordinates (%u,%u,%u,%u,%p).", - cimg_instance, - coords._width,coords._height,coords._depth,coords._spectrum,coords._data); - CImg _coords; - if (!coords) { // If no texture coordinates specified, do a default XY-projection. - _coords.assign(_width,2); - float - xmin, xmax = (float)get_shared_row(0).max_min(xmin), - ymin, ymax = (float)get_shared_row(1).max_min(ymin), - dx = xmax>xmin?xmax-xmin:1, - dy = ymax>ymin?ymax-ymin:1; - cimg_forX(*this,p) { - _coords(p,0) = (int)(((*this)(p,0) - xmin)*texture._width/dx); - _coords(p,1) = (int)(((*this)(p,1) - ymin)*texture._height/dy); - } - } else _coords = coords; - - int texture_ind = -1; - cimglist_for(primitives,l) { - CImg &p = primitives[l]; - const unsigned int siz = p.size(); - switch (siz) { - case 1 : { // Point. - const unsigned int i0 = (unsigned int)p[0]; - const int x0 = _coords(i0,0), y0 = _coords(i0,1); - texture.get_vector_at(x0<=0?0:x0>=texture.width()?texture.width() - 1:x0, - y0<=0?0:y0>=texture.height()?texture.height() - 1:y0).move_to(colors[l]); - } break; - case 2 : case 6 : { // Line. - const unsigned int i0 = (unsigned int)p[0], i1 = (unsigned int)p[1]; - const int - x0 = _coords(i0,0), y0 = _coords(i0,1), - x1 = _coords(i1,0), y1 = _coords(i1,1); - if (texture_ind<0) colors[texture_ind=l].assign(texture,false); - else colors[l].assign(colors[texture_ind],true); - CImg::vector(i0,i1,x0,y0,x1,y1).move_to(p); - } break; - case 3 : case 9 : { // Triangle. - const unsigned int i0 = (unsigned int)p[0], i1 = (unsigned int)p[1], i2 = (unsigned int)p[2]; - const int - x0 = _coords(i0,0), y0 = _coords(i0,1), - x1 = _coords(i1,0), y1 = _coords(i1,1), - x2 = _coords(i2,0), y2 = _coords(i2,1); - if (texture_ind<0) colors[texture_ind=l].assign(texture,false); - else colors[l].assign(colors[texture_ind],true); - CImg::vector(i0,i1,i2,x0,y0,x1,y1,x2,y2).move_to(p); - } break; - case 4 : case 12 : { // Quadrangle. - const unsigned int - i0 = (unsigned int)p[0], i1 = (unsigned int)p[1], i2 = (unsigned int)p[2], i3 = (unsigned int)p[3]; - const int - x0 = _coords(i0,0), y0 = _coords(i0,1), - x1 = _coords(i1,0), y1 = _coords(i1,1), - x2 = _coords(i2,0), y2 = _coords(i2,1), - x3 = _coords(i3,0), y3 = _coords(i3,1); - if (texture_ind<0) colors[texture_ind=l].assign(texture,false); - else colors[l].assign(colors[texture_ind],true); - CImg::vector(i0,i1,i2,i3,x0,y0,x1,y1,x2,y2,x3,y3).move_to(p); - } break; - } - } - return *this; - } - - //! Generate a 3d elevation of the image instance. - /** - \param[out] primitives The returned list of the 3d object primitives - (template type \e tf should be at least \e unsigned \e int). - \param[out] colors The returned list of the 3d object colors. - \param elevation The input elevation map. - \return The N vertices (xi,yi,zi) of the 3d object as a Nx3 CImg image (0<=i<=N - 1). - \par Example - \code - const CImg img("reference.jpg"); - CImgList faces3d; - CImgList colors3d; - const CImg points3d = img.get_elevation3d(faces3d,colors3d,img.get_norm()*0.2); - CImg().display_object3d("Elevation3d",points3d,faces3d,colors3d); - \endcode - \image html ref_elevation3d.jpg - **/ - template - CImg get_elevation3d(CImgList& primitives, CImgList& colors, const CImg& elevation) const { - if (!is_sameXY(elevation) || elevation._depth>1 || elevation._spectrum>1) - throw CImgArgumentException(_cimg_instance - "get_elevation3d(): Instance and specified elevation (%u,%u,%u,%u,%p) " - "have incompatible dimensions.", - cimg_instance, - elevation._width,elevation._height,elevation._depth, - elevation._spectrum,elevation._data); - if (is_empty()) return *this; - float m, M = (float)max_min(m); - if (M==m) ++M; - colors.assign(); - const unsigned int size_x1 = _width - 1, size_y1 = _height - 1; - for (unsigned int y = 0; y1?((*this)(x,y,1) - m)*255/(M-m):r), - b = (unsigned char)(_spectrum>2?((*this)(x,y,2) - m)*255/(M-m):_spectrum>1?0:r); - CImg::vector((tc)r,(tc)g,(tc)b).move_to(colors); - } - const typename CImg::_functor2d_int func(elevation); - return elevation3d(primitives,func,0,0,_width - 1.0f,_height - 1.0f,_width,_height); - } - - //! Generate the 3d projection planes of the image instance. - /** - \param[out] primitives Primitives data of the returned 3d object. - \param[out] colors Colors data of the returned 3d object. - \param x0 X-coordinate of the projection point. - \param y0 Y-coordinate of the projection point. - \param z0 Z-coordinate of the projection point. - \param normalize_colors Tells if the created textures have normalized colors. - **/ - template - CImg get_projections3d(CImgList& primitives, CImgList& colors, - const unsigned int x0, const unsigned int y0, const unsigned int z0, - const bool normalize_colors=false) const { - float m = 0, M = 0, delta = 1; - if (normalize_colors) { m = (float)min_max(M); delta = 255/(m==M?1:M-m); } - const unsigned int - _x0 = (x0>=_width)?_width - 1:x0, - _y0 = (y0>=_height)?_height - 1:y0, - _z0 = (z0>=_depth)?_depth - 1:z0; - CImg img_xy, img_xz, img_yz; - if (normalize_colors) { - ((get_crop(0,0,_z0,0,_width - 1,_height - 1,_z0,_spectrum - 1)-=m)*=delta).move_to(img_xy); - ((get_crop(0,_y0,0,0,_width - 1,_y0,_depth - 1,_spectrum - 1)-=m)*=delta).resize(_width,_depth,1,-100,-1). - move_to(img_xz); - ((get_crop(_x0,0,0,0,_x0,_height - 1,_depth - 1,_spectrum - 1)-=m)*=delta).resize(_height,_depth,1,-100,-1). - move_to(img_yz); - } else { - get_crop(0,0,_z0,0,_width - 1,_height - 1,_z0,_spectrum - 1).move_to(img_xy); - get_crop(0,_y0,0,0,_width - 1,_y0,_depth - 1,_spectrum - 1).resize(_width,_depth,1,-100,-1).move_to(img_xz); - get_crop(_x0,0,0,0,_x0,_height - 1,_depth - 1,_spectrum - 1).resize(_height,_depth,1,-100,-1).move_to(img_yz); - } - CImg points(12,3,1,1, - 0,_width - 1,_width - 1,0, 0,_width - 1,_width - 1,0, _x0,_x0,_x0,_x0, - 0,0,_height - 1,_height - 1, _y0,_y0,_y0,_y0, 0,_height - 1,_height - 1,0, - _z0,_z0,_z0,_z0, 0,0,_depth - 1,_depth - 1, 0,0,_depth - 1,_depth - 1); - primitives.assign(); - CImg::vector(0,1,2,3,0,0,img_xy._width - 1,0,img_xy._width - 1,img_xy._height - 1,0,img_xy._height - 1). - move_to(primitives); - CImg::vector(4,5,6,7,0,0,img_xz._width - 1,0,img_xz._width - 1,img_xz._height - 1,0,img_xz._height - 1). - move_to(primitives); - CImg::vector(8,9,10,11,0,0,img_yz._width - 1,0,img_yz._width - 1,img_yz._height - 1,0,img_yz._height - 1). - move_to(primitives); - colors.assign(); - img_xy.move_to(colors); - img_xz.move_to(colors); - img_yz.move_to(colors); - return points; - } - - //! Generate a isoline of the image instance as a 3d object. - /** - \param[out] primitives The returned list of the 3d object primitives - (template type \e tf should be at least \e unsigned \e int). - \param isovalue The returned list of the 3d object colors. - \param size_x The number of subdivisions along the X-axis. - \param size_y The number of subdisivions along the Y-axis. - \return The N vertices (xi,yi,zi) of the 3d object as a Nx3 CImg image (0<=i<=N - 1). - \par Example - \code - const CImg img("reference.jpg"); - CImgList faces3d; - const CImg points3d = img.get_isoline3d(faces3d,100); - CImg().display_object3d("Isoline3d",points3d,faces3d,colors3d); - \endcode - \image html ref_isoline3d.jpg - **/ - template - CImg get_isoline3d(CImgList& primitives, const float isovalue, - const int size_x=-100, const int size_y=-100) const { - if (_spectrum>1) - throw CImgInstanceException(_cimg_instance - "get_isoline3d(): Instance is not a scalar image.", - cimg_instance); - if (_depth>1) - throw CImgInstanceException(_cimg_instance - "get_isoline3d(): Instance is not a 2d image.", - cimg_instance); - primitives.assign(); - if (is_empty()) return *this; - CImg vertices; - if ((size_x==-100 && size_y==-100) || (size_x==width() && size_y==height())) { - const _functor2d_int func(*this); - vertices = isoline3d(primitives,func,isovalue,0,0,width() - 1.0f,height() - 1.0f,width(),height()); - } else { - const _functor2d_float func(*this); - vertices = isoline3d(primitives,func,isovalue,0,0,width() - 1.0f,height() - 1.0f,size_x,size_y); - } - return vertices; - } - - //! Generate an isosurface of the image instance as a 3d object. - /** - \param[out] primitives The returned list of the 3d object primitives - (template type \e tf should be at least \e unsigned \e int). - \param isovalue The returned list of the 3d object colors. - \param size_x Number of subdivisions along the X-axis. - \param size_y Number of subdisivions along the Y-axis. - \param size_z Number of subdisivions along the Z-axis. - \return The N vertices (xi,yi,zi) of the 3d object as a Nx3 CImg image (0<=i<=N - 1). - \par Example - \code - const CImg img = CImg("reference.jpg").resize(-100,-100,20); - CImgList faces3d; - const CImg points3d = img.get_isosurface3d(faces3d,100); - CImg().display_object3d("Isosurface3d",points3d,faces3d,colors3d); - \endcode - \image html ref_isosurface3d.jpg - **/ - template - CImg get_isosurface3d(CImgList& primitives, const float isovalue, - const int size_x=-100, const int size_y=-100, const int size_z=-100) const { - if (_spectrum>1) - throw CImgInstanceException(_cimg_instance - "get_isosurface3d(): Instance is not a scalar image.", - cimg_instance); - primitives.assign(); - if (is_empty()) return *this; - CImg vertices; - if ((size_x==-100 && size_y==-100 && size_z==-100) || (size_x==width() && size_y==height() && size_z==depth())) { - const _functor3d_int func(*this); - vertices = isosurface3d(primitives,func,isovalue,0,0,0,width() - 1.0f,height() - 1.0f,depth() - 1.0f, - width(),height(),depth()); - } else { - const _functor3d_float func(*this); - vertices = isosurface3d(primitives,func,isovalue,0,0,0,width() - 1.0f,height() - 1.0f,depth() - 1.0f, - size_x,size_y,size_z); - } - return vertices; - } - - //! Compute 3d elevation of a function as a 3d object. - /** - \param[out] primitives Primitives data of the resulting 3d object. - \param func Elevation function. Is of type float (*func)(const float x,const float y). - \param x0 X-coordinate of the starting point. - \param y0 Y-coordinate of the starting point. - \param x1 X-coordinate of the ending point. - \param y1 Y-coordinate of the ending point. - \param size_x Resolution of the function along the X-axis. - \param size_y Resolution of the function along the Y-axis. - **/ - template - static CImg elevation3d(CImgList& primitives, const tfunc& func, - const float x0, const float y0, const float x1, const float y1, - const int size_x=256, const int size_y=256) { - const float - nx0 = x0=0?size_x:(nx1-nx0)*-size_x/100), - nsize_x = _nsize_x?_nsize_x:1, nsize_x1 = nsize_x - 1, - _nsize_y = (unsigned int)(size_y>=0?size_y:(ny1-ny0)*-size_y/100), - nsize_y = _nsize_y?_nsize_y:1, nsize_y1 = nsize_y - 1; - if (nsize_x<2 || nsize_y<2) - throw CImgArgumentException("CImg<%s>::elevation3d(): Invalid specified size (%d,%d).", - pixel_type(), - nsize_x,nsize_y); - - CImg vertices(nsize_x*nsize_y,3); - floatT *ptr_x = vertices.data(0,0), *ptr_y = vertices.data(0,1), *ptr_z = vertices.data(0,2); - for (unsigned int y = 0; y - static CImg elevation3d(CImgList& primitives, const char *const expression, - const float x0, const float y0, const float x1, const float y1, - const int size_x=256, const int size_y=256) { - const _functor2d_expr func(expression); - return elevation3d(primitives,func,x0,y0,x1,y1,size_x,size_y); - } - - //! Compute 0-isolines of a function, as a 3d object. - /** - \param[out] primitives Primitives data of the resulting 3d object. - \param func Elevation function. Is of type float (*func)(const float x,const float y). - \param isovalue Isovalue to extract from function. - \param x0 X-coordinate of the starting point. - \param y0 Y-coordinate of the starting point. - \param x1 X-coordinate of the ending point. - \param y1 Y-coordinate of the ending point. - \param size_x Resolution of the function along the X-axis. - \param size_y Resolution of the function along the Y-axis. - \note Use the marching squares algorithm for extracting the isolines. - **/ - template - static CImg isoline3d(CImgList& primitives, const tfunc& func, const float isovalue, - const float x0, const float y0, const float x1, const float y1, - const int size_x=256, const int size_y=256) { - static const unsigned int edges[16] = { 0x0, 0x9, 0x3, 0xa, 0x6, 0xf, 0x5, 0xc, 0xc, - 0x5, 0xf, 0x6, 0xa, 0x3, 0x9, 0x0 }; - static const int segments[16][4] = { { -1,-1,-1,-1 }, { 0,3,-1,-1 }, { 0,1,-1,-1 }, { 1,3,-1,-1 }, - { 1,2,-1,-1 }, { 0,1,2,3 }, { 0,2,-1,-1 }, { 2,3,-1,-1 }, - { 2,3,-1,-1 }, { 0,2,-1,-1}, { 0,3,1,2 }, { 1,2,-1,-1 }, - { 1,3,-1,-1 }, { 0,1,-1,-1}, { 0,3,-1,-1}, { -1,-1,-1,-1 } }; - const unsigned int - _nx = (unsigned int)(size_x>=0?size_x:cimg::round((x1-x0)*-size_x/100 + 1)), - _ny = (unsigned int)(size_y>=0?size_y:cimg::round((y1-y0)*-size_y/100 + 1)), - nx = _nx?_nx:1, - ny = _ny?_ny:1, - nxm1 = nx - 1, - nym1 = ny - 1; - primitives.assign(); - if (!nxm1 || !nym1) return CImg(); - const float dx = (x1 - x0)/nxm1, dy = (y1 - y0)/nym1; - CImgList vertices; - CImg indices1(nx,1,1,2,-1), indices2(nx,1,1,2); - CImg values1(nx), values2(nx); - float X = x0, Y = y0, nX = X + dx, nY = Y + dy; - - // Fill first line with values - cimg_forX(values1,x) { values1(x) = (float)func(X,Y); X+=dx; } - - // Run the marching squares algorithm - for (unsigned int yi = 0, nyi = 1; yi::vector(Xi,Y,0).move_to(vertices); - } - if ((edge&2) && indices1(nxi,1)<0) { - const float Yi = Y + (isovalue-val1)*dy/(val2-val1); - indices1(nxi,1) = vertices.width(); - CImg::vector(nX,Yi,0).move_to(vertices); - } - if ((edge&4) && indices2(xi,0)<0) { - const float Xi = X + (isovalue-val3)*dx/(val2-val3); - indices2(xi,0) = vertices.width(); - CImg::vector(Xi,nY,0).move_to(vertices); - } - if ((edge&8) && indices1(xi,1)<0) { - const float Yi = Y + (isovalue-val0)*dy/(val3-val0); - indices1(xi,1) = vertices.width(); - CImg::vector(X,Yi,0).move_to(vertices); - } - - // Create segments - for (const int *segment = segments[configuration]; *segment!=-1; ) { - const unsigned int p0 = (unsigned int)*(segment++), p1 = (unsigned int)*(segment++); - const tf - i0 = (tf)(_isoline3d_indice(p0,indices1,indices2,xi,nxi)), - i1 = (tf)(_isoline3d_indice(p1,indices1,indices2,xi,nxi)); - CImg::vector(i0,i1).move_to(primitives); - } - } - } - values1.swap(values2); - indices1.swap(indices2); - } - return vertices>'x'; - } - - //! Compute isolines of a function, as a 3d object \overloading. - template - static CImg isoline3d(CImgList& primitives, const char *const expression, const float isovalue, - const float x0, const float y0, const float x1, const float y1, - const int size_x=256, const int size_y=256) { - const _functor2d_expr func(expression); - return isoline3d(primitives,func,isovalue,x0,y0,x1,y1,size_x,size_y); - } - - template - static int _isoline3d_indice(const unsigned int edge, const CImg& indices1, const CImg& indices2, - const unsigned int x, const unsigned int nx) { - switch (edge) { - case 0 : return (int)indices1(x,0); - case 1 : return (int)indices1(nx,1); - case 2 : return (int)indices2(x,0); - case 3 : return (int)indices1(x,1); - } - return 0; - } - - //! Compute isosurface of a function, as a 3d object. - /** - \param[out] primitives Primitives data of the resulting 3d object. - \param func Implicit function. Is of type float (*func)(const float x, const float y, const float z). - \param isovalue Isovalue to extract. - \param x0 X-coordinate of the starting point. - \param y0 Y-coordinate of the starting point. - \param z0 Z-coordinate of the starting point. - \param x1 X-coordinate of the ending point. - \param y1 Y-coordinate of the ending point. - \param z1 Z-coordinate of the ending point. - \param size_x Resolution of the elevation function along the X-axis. - \param size_y Resolution of the elevation function along the Y-axis. - \param size_z Resolution of the elevation function along the Z-axis. - \note Use the marching cubes algorithm for extracting the isosurface. - **/ - template - static CImg isosurface3d(CImgList& primitives, const tfunc& func, const float isovalue, - const float x0, const float y0, const float z0, - const float x1, const float y1, const float z1, - const int size_x=32, const int size_y=32, const int size_z=32) { - static const unsigned int edges[256] = { - 0x000, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, - 0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, - 0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, - 0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, - 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60, - 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, - 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, - 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, - 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, - 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, - 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, - 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460, - 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0, - 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230, - 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190, - 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x000 - }; - - static const int triangles[256][16] = { - { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1 }, - { 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1 }, - { 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1 }, - { 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1 }, - { 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1 }, - { 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 }, - { 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1 }, - { 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1 }, - { 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 }, - { 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1 }, - { 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1 }, - { 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1 }, - { 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1 }, - { 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 }, - { 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1 }, - { 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1 }, - { 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 }, - { 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1 }, - { 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1 }, - { 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1 }, - { 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1 }, - { 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1 }, - { 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1 }, - { 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1 }, - { 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1 }, - { 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1 }, - { 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1 }, - { 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1 }, - { 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1 }, - { 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1 }, - { 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1 }, - { 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1 }, - { 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1 }, - { 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1 }, - { 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1 }, - { 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1 }, - { 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 }, - { 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1 }, - { 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1 }, - { 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1 }, - { 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1 }, - { 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 }, - { 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1 }, - { 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1 }, - { 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1 }, - { 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1 }, - { 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 }, - { 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1 }, - { 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1 }, - { 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1 }, - { 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1 }, - { 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1 }, - { 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1 }, - { 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1 }, - { 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1 }, - { 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1 }, - { 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1 }, - { 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1 }, - { 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1 }, - { 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1 }, - { 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1 }, - { 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1 }, - { 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1 }, - { 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1 }, - { 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1 }, - { 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1 }, - { 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1 }, - { 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1 }, - { 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1 }, - { 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1 }, - { 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1 }, - { 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1 }, - { 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1 }, - { 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1 }, - { 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1 }, - { 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1 }, - { 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1 }, - { 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 }, - { 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 }, - { 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 }, - { 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1 }, - { 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1 }, - { 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1 }, - { 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1 }, - { 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1 }, - { 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1 }, - { 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1 }, - { 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1 }, - { 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1 }, - { 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1 }, - { 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1 }, - { 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1 }, - { 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1 }, - { 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1 }, - { 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1 }, - { 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1 }, - { 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1 }, - { 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1 }, - { 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 }, - { 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 }, - { 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1 }, - { 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 }, - { 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1 }, - { 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1 }, - { 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1 }, - { 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1 }, - { 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1 }, - { 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1 }, - { 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1 }, - { 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1 }, - { 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1 }, - { 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1 }, - { 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1 }, - { 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1 }, - { 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1 }, - { 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1 }, - { 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1 }, - { 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1 }, - { 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1 }, - { 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1 }, - { 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1 }, - { 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1 }, - { 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1 }, - { 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1 }, - { 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1 }, - { 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1 }, - { 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1 }, - { 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1 }, - { 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1 }, - { 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1 }, - { 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1 }, - { 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1 }, - { 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1 }, - { 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1 }, - { 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1 }, - { 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1 }, - { 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1 }, - { 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1 }, - { 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1 }, - { 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1 }, - { 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1 }, - { 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1 }, - { 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1 }, - { 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1 }, - { 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1 }, - { 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1 }, - { 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1 }, - { 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1 }, - { 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1 }, - { 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1 }, - { 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1 }, - { 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1 }, - { 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1 }, - { 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1 }, - { 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1 }, - { 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1 }, - { 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1 }, - { 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1 }, - { 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1 }, - { 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1 }, - { 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1 }, - { 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1 }, - { 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1 }, - { 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1 }, - { 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1 }, - { 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } - }; - - const unsigned int - _nx = (unsigned int)(size_x>=0?size_x:cimg::round((x1-x0)*-size_x/100 + 1)), - _ny = (unsigned int)(size_y>=0?size_y:cimg::round((y1-y0)*-size_y/100 + 1)), - _nz = (unsigned int)(size_z>=0?size_z:cimg::round((z1-z0)*-size_z/100 + 1)), - nx = _nx?_nx:1, - ny = _ny?_ny:1, - nz = _nz?_nz:1, - nxm1 = nx - 1, - nym1 = ny - 1, - nzm1 = nz - 1; - primitives.assign(); - if (!nxm1 || !nym1 || !nzm1) return CImg(); - const float dx = (x1 - x0)/nxm1, dy = (y1 - y0)/nym1, dz = (z1 - z0)/nzm1; - CImgList vertices; - CImg indices1(nx,ny,1,3,-1), indices2(indices1); - CImg values1(nx,ny), values2(nx,ny); - float X = 0, Y = 0, Z = 0, nX = 0, nY = 0, nZ = 0; - - // Fill the first plane with function values - Y = y0; - cimg_forY(values1,y) { - X = x0; - cimg_forX(values1,x) { values1(x,y) = (float)func(X,Y,z0); X+=dx; } - Y+=dy; - } - - // Run Marching Cubes algorithm - Z = z0; nZ = Z + dz; - for (unsigned int zi = 0; zi::vector(Xi,Y,Z).move_to(vertices); - } - if ((edge&2) && indices1(nxi,yi,1)<0) { - const float Yi = Y + (isovalue-val1)*dy/(val2-val1); - indices1(nxi,yi,1) = vertices.width(); - CImg::vector(nX,Yi,Z).move_to(vertices); - } - if ((edge&4) && indices1(xi,nyi,0)<0) { - const float Xi = X + (isovalue-val3)*dx/(val2-val3); - indices1(xi,nyi,0) = vertices.width(); - CImg::vector(Xi,nY,Z).move_to(vertices); - } - if ((edge&8) && indices1(xi,yi,1)<0) { - const float Yi = Y + (isovalue-val0)*dy/(val3-val0); - indices1(xi,yi,1) = vertices.width(); - CImg::vector(X,Yi,Z).move_to(vertices); - } - if ((edge&16) && indices2(xi,yi,0)<0) { - const float Xi = X + (isovalue-val4)*dx/(val5-val4); - indices2(xi,yi,0) = vertices.width(); - CImg::vector(Xi,Y,nZ).move_to(vertices); - } - if ((edge&32) && indices2(nxi,yi,1)<0) { - const float Yi = Y + (isovalue-val5)*dy/(val6-val5); - indices2(nxi,yi,1) = vertices.width(); - CImg::vector(nX,Yi,nZ).move_to(vertices); - } - if ((edge&64) && indices2(xi,nyi,0)<0) { - const float Xi = X + (isovalue-val7)*dx/(val6-val7); - indices2(xi,nyi,0) = vertices.width(); - CImg::vector(Xi,nY,nZ).move_to(vertices); - } - if ((edge&128) && indices2(xi,yi,1)<0) { - const float Yi = Y + (isovalue-val4)*dy/(val7-val4); - indices2(xi,yi,1) = vertices.width(); - CImg::vector(X,Yi,nZ).move_to(vertices); - } - if ((edge&256) && indices1(xi,yi,2)<0) { - const float Zi = Z+ (isovalue-val0)*dz/(val4-val0); - indices1(xi,yi,2) = vertices.width(); - CImg::vector(X,Y,Zi).move_to(vertices); - } - if ((edge&512) && indices1(nxi,yi,2)<0) { - const float Zi = Z + (isovalue-val1)*dz/(val5-val1); - indices1(nxi,yi,2) = vertices.width(); - CImg::vector(nX,Y,Zi).move_to(vertices); - } - if ((edge&1024) && indices1(nxi,nyi,2)<0) { - const float Zi = Z + (isovalue-val2)*dz/(val6-val2); - indices1(nxi,nyi,2) = vertices.width(); - CImg::vector(nX,nY,Zi).move_to(vertices); - } - if ((edge&2048) && indices1(xi,nyi,2)<0) { - const float Zi = Z + (isovalue-val3)*dz/(val7-val3); - indices1(xi,nyi,2) = vertices.width(); - CImg::vector(X,nY,Zi).move_to(vertices); - } - - // Create triangles - for (const int *triangle = triangles[configuration]; *triangle!=-1; ) { - const unsigned int - p0 = (unsigned int)*(triangle++), - p1 = (unsigned int)*(triangle++), - p2 = (unsigned int)*(triangle++); - const tf - i0 = (tf)(_isosurface3d_indice(p0,indices1,indices2,xi,yi,nxi,nyi)), - i1 = (tf)(_isosurface3d_indice(p1,indices1,indices2,xi,yi,nxi,nyi)), - i2 = (tf)(_isosurface3d_indice(p2,indices1,indices2,xi,yi,nxi,nyi)); - CImg::vector(i0,i2,i1).move_to(primitives); - } - } - } - } - cimg::swap(values1,values2); - cimg::swap(indices1,indices2); - } - return vertices>'x'; - } - - //! Compute isosurface of a function, as a 3d object \overloading. - template - static CImg isosurface3d(CImgList& primitives, const char *const expression, const float isovalue, - const float x0, const float y0, const float z0, - const float x1, const float y1, const float z1, - const int dx=32, const int dy=32, const int dz=32) { - const _functor3d_expr func(expression); - return isosurface3d(primitives,func,isovalue,x0,y0,z0,x1,y1,z1,dx,dy,dz); - } - - template - static int _isosurface3d_indice(const unsigned int edge, const CImg& indices1, const CImg& indices2, - const unsigned int x, const unsigned int y, - const unsigned int nx, const unsigned int ny) { - switch (edge) { - case 0 : return indices1(x,y,0); - case 1 : return indices1(nx,y,1); - case 2 : return indices1(x,ny,0); - case 3 : return indices1(x,y,1); - case 4 : return indices2(x,y,0); - case 5 : return indices2(nx,y,1); - case 6 : return indices2(x,ny,0); - case 7 : return indices2(x,y,1); - case 8 : return indices1(x,y,2); - case 9 : return indices1(nx,y,2); - case 10 : return indices1(nx,ny,2); - case 11 : return indices1(x,ny,2); - } - return 0; - } - - // Define functors for accessing image values (used in previous functions). - struct _functor2d_int { - const CImg& ref; - _functor2d_int(const CImg& pref):ref(pref) {} - float operator()(const float x, const float y) const { - return (float)ref((int)x,(int)y); - } - }; - - struct _functor2d_float { - const CImg& ref; - _functor2d_float(const CImg& pref):ref(pref) {} - float operator()(const float x, const float y) const { - return (float)ref._linear_atXY(x,y); - } - }; - - struct _functor2d_expr { - _cimg_math_parser *mp; - _functor2d_expr(const char *const expr):mp(0) { - mp = new _cimg_math_parser(expr,0,CImg::const_empty(),0); - } - ~_functor2d_expr() { delete mp; } - float operator()(const float x, const float y) const { - return (float)(*mp)(x,y,0,0); - } - }; - - struct _functor3d_int { - const CImg& ref; - _functor3d_int(const CImg& pref):ref(pref) {} - float operator()(const float x, const float y, const float z) const { - return (float)ref((int)x,(int)y,(int)z); - } - }; - - struct _functor3d_float { - const CImg& ref; - _functor3d_float(const CImg& pref):ref(pref) {} - float operator()(const float x, const float y, const float z) const { - return (float)ref._linear_atXYZ(x,y,z); - } - }; - - struct _functor3d_expr { - _cimg_math_parser *mp; - ~_functor3d_expr() { delete mp; } - _functor3d_expr(const char *const expr):mp(0) { - mp = new _cimg_math_parser(expr,0,CImg::const_empty(),0); - } - float operator()(const float x, const float y, const float z) const { - return (float)(*mp)(x,y,z,0); - } - }; - - struct _functor4d_int { - const CImg& ref; - _functor4d_int(const CImg& pref):ref(pref) {} - float operator()(const float x, const float y, const float z, const unsigned int c) const { - return (float)ref((int)x,(int)y,(int)z,c); - } - }; - - //! Generate a 3d box object. - /** - \param[out] primitives The returned list of the 3d object primitives - (template type \e tf should be at least \e unsigned \e int). - \param size_x The width of the box (dimension along the X-axis). - \param size_y The height of the box (dimension along the Y-axis). - \param size_z The depth of the box (dimension along the Z-axis). - \return The N vertices (xi,yi,zi) of the 3d object as a Nx3 CImg image (0<=i<=N - 1). - \par Example - \code - CImgList faces3d; - const CImg points3d = CImg::box3d(faces3d,10,20,30); - CImg().display_object3d("Box3d",points3d,faces3d); - \endcode - \image html ref_box3d.jpg - **/ - template - static CImg box3d(CImgList& primitives, - const float size_x=200, const float size_y=100, const float size_z=100) { - primitives.assign(6,1,4,1,1, 0,3,2,1, 4,5,6,7, 0,1,5,4, 3,7,6,2, 0,4,7,3, 1,2,6,5); - return CImg(8,3,1,1, - 0.,size_x,size_x, 0., 0.,size_x,size_x, 0., - 0., 0.,size_y,size_y, 0., 0.,size_y,size_y, - 0., 0., 0., 0.,size_z,size_z,size_z,size_z); - } - - //! Generate a 3d cone. - /** - \param[out] primitives The returned list of the 3d object primitives - (template type \e tf should be at least \e unsigned \e int). - \param radius The radius of the cone basis. - \param size_z The cone's height. - \param subdivisions The number of basis angular subdivisions. - \return The N vertices (xi,yi,zi) of the 3d object as a Nx3 CImg image (0<=i<=N - 1). - \par Example - \code - CImgList faces3d; - const CImg points3d = CImg::cone3d(faces3d,50); - CImg().display_object3d("Cone3d",points3d,faces3d); - \endcode - \image html ref_cone3d.jpg - **/ - template - static CImg cone3d(CImgList& primitives, - const float radius=50, const float size_z=100, const unsigned int subdivisions=24) { - primitives.assign(); - if (!subdivisions) return CImg(); - CImgList vertices(2,1,3,1,1, - 0.,0.,size_z, - 0.,0.,0.); - for (float delta = 360.0f/subdivisions, angle = 0; angle<360; angle+=delta) { - const float a = (float)(angle*cimg::PI/180); - CImg::vector((float)(radius*std::cos(a)),(float)(radius*std::sin(a)),0).move_to(vertices); - } - const unsigned int nbr = vertices._width - 2; - for (unsigned int p = 0; p::vector(1,next,curr).move_to(primitives); - CImg::vector(0,curr,next).move_to(primitives); - } - return vertices>'x'; - } - - //! Generate a 3d cylinder. - /** - \param[out] primitives The returned list of the 3d object primitives - (template type \e tf should be at least \e unsigned \e int). - \param radius The radius of the cylinder basis. - \param size_z The cylinder's height. - \param subdivisions The number of basis angular subdivisions. - \return The N vertices (xi,yi,zi) of the 3d object as a Nx3 CImg image (0<=i<=N - 1). - \par Example - \code - CImgList faces3d; - const CImg points3d = CImg::cylinder3d(faces3d,50); - CImg().display_object3d("Cylinder3d",points3d,faces3d); - \endcode - \image html ref_cylinder3d.jpg - **/ - template - static CImg cylinder3d(CImgList& primitives, - const float radius=50, const float size_z=100, const unsigned int subdivisions=24) { - primitives.assign(); - if (!subdivisions) return CImg(); - CImgList vertices(2,1,3,1,1, - 0.,0.,0., - 0.,0.,size_z); - for (float delta = 360.0f/subdivisions, angle = 0; angle<360; angle+=delta) { - const float a = (float)(angle*cimg::PI/180); - CImg::vector((float)(radius*std::cos(a)),(float)(radius*std::sin(a)),0.0f).move_to(vertices); - CImg::vector((float)(radius*std::cos(a)),(float)(radius*std::sin(a)),size_z).move_to(vertices); - } - const unsigned int nbr = (vertices._width - 2)/2; - for (unsigned int p = 0; p::vector(0,next,curr).move_to(primitives); - CImg::vector(1,curr + 1,next + 1).move_to(primitives); - CImg::vector(curr,next,next + 1,curr + 1).move_to(primitives); - } - return vertices>'x'; - } - - //! Generate a 3d torus. - /** - \param[out] primitives The returned list of the 3d object primitives - (template type \e tf should be at least \e unsigned \e int). - \param radius1 The large radius. - \param radius2 The small radius. - \param subdivisions1 The number of angular subdivisions for the large radius. - \param subdivisions2 The number of angular subdivisions for the small radius. - \return The N vertices (xi,yi,zi) of the 3d object as a Nx3 CImg image (0<=i<=N - 1). - \par Example - \code - CImgList faces3d; - const CImg points3d = CImg::torus3d(faces3d,20,4); - CImg().display_object3d("Torus3d",points3d,faces3d); - \endcode - \image html ref_torus3d.jpg - **/ - template - static CImg torus3d(CImgList& primitives, - const float radius1=100, const float radius2=30, - const unsigned int subdivisions1=24, const unsigned int subdivisions2=12) { - primitives.assign(); - if (!subdivisions1 || !subdivisions2) return CImg(); - CImgList vertices; - for (unsigned int v = 0; v::vector(x,y,z).move_to(vertices); - } - } - for (unsigned int vv = 0; vv::vector(svv + nu,svv + uu,snv + uu,snv + nu).move_to(primitives); - } - } - return vertices>'x'; - } - - //! Generate a 3d XY-plane. - /** - \param[out] primitives The returned list of the 3d object primitives - (template type \e tf should be at least \e unsigned \e int). - \param size_x The width of the plane (dimension along the X-axis). - \param size_y The height of the plane (dimensions along the Y-axis). - \param subdivisions_x The number of planar subdivisions along the X-axis. - \param subdivisions_y The number of planar subdivisions along the Y-axis. - \return The N vertices (xi,yi,zi) of the 3d object as a Nx3 CImg image (0<=i<=N - 1). - \par Example - \code - CImgList faces3d; - const CImg points3d = CImg::plane3d(faces3d,100,50); - CImg().display_object3d("Plane3d",points3d,faces3d); - \endcode - \image html ref_plane3d.jpg - **/ - template - static CImg plane3d(CImgList& primitives, - const float size_x=100, const float size_y=100, - const unsigned int subdivisions_x=10, const unsigned int subdivisions_y=10) { - primitives.assign(); - if (!subdivisions_x || !subdivisions_y) return CImg(); - CImgList vertices; - const unsigned int w = subdivisions_x + 1, h = subdivisions_y + 1; - const float fx = (float)size_x/w, fy = (float)size_y/h; - for (unsigned int y = 0; y::vector(fx*x,fy*y,0).move_to(vertices); - for (unsigned int y = 0; y::vector(off1,off4,off3,off2).move_to(primitives); - } - return vertices>'x'; - } - - //! Generate a 3d sphere. - /** - \param[out] primitives The returned list of the 3d object primitives - (template type \e tf should be at least \e unsigned \e int). - \param radius The radius of the sphere (dimension along the X-axis). - \param subdivisions The number of recursive subdivisions from an initial icosahedron. - \return The N vertices (xi,yi,zi) of the 3d object as a Nx3 CImg image (0<=i<=N - 1). - \par Example - \code - CImgList faces3d; - const CImg points3d = CImg::sphere3d(faces3d,100,4); - CImg().display_object3d("Sphere3d",points3d,faces3d); - \endcode - \image html ref_sphere3d.jpg - **/ - template - static CImg sphere3d(CImgList& primitives, - const float radius=50, const unsigned int subdivisions=3) { - - // Create initial icosahedron - primitives.assign(); - const double tmp = (1 + std::sqrt(5.0f))/2, a = 1.0/std::sqrt(1 + tmp*tmp), b = tmp*a; - CImgList vertices(12,1,3,1,1, b,a,0.0, -b,a,0.0, -b,-a,0.0, b,-a,0.0, a,0.0,b, a,0.0,-b, - -a,0.0,-b, -a,0.0,b, 0.0,b,a, 0.0,-b,a, 0.0,-b,-a, 0.0,b,-a); - primitives.assign(20,1,3,1,1, 4,8,7, 4,7,9, 5,6,11, 5,10,6, 0,4,3, 0,3,5, 2,7,1, 2,1,6, - 8,0,11, 8,11,1, 9,10,3, 9,2,10, 8,4,0, 11,0,5, 4,9,3, - 5,3,10, 7,8,1, 6,1,11, 7,2,9, 6,10,2); - // edge - length/2 - float he = (float)a; - - // Recurse subdivisions - for (unsigned int i = 0; i::vector(nx0,ny0,nz0).move_to(vertices); i0 = vertices.width() - 1; } - if (i1<0) { CImg::vector(nx1,ny1,nz1).move_to(vertices); i1 = vertices.width() - 1; } - if (i2<0) { CImg::vector(nx2,ny2,nz2).move_to(vertices); i2 = vertices.width() - 1; } - primitives.remove(0); - CImg::vector(p0,i0,i1).move_to(primitives); - CImg::vector((tf)i0,(tf)p1,(tf)i2).move_to(primitives); - CImg::vector((tf)i1,(tf)i2,(tf)p2).move_to(primitives); - CImg::vector((tf)i1,(tf)i0,(tf)i2).move_to(primitives); - } - } - return (vertices>'x')*=radius; - } - - //! Generate a 3d ellipsoid. - /** - \param[out] primitives The returned list of the 3d object primitives - (template type \e tf should be at least \e unsigned \e int). - \param tensor The tensor which gives the shape and size of the ellipsoid. - \param subdivisions The number of recursive subdivisions from an initial stretched icosahedron. - \return The N vertices (xi,yi,zi) of the 3d object as a Nx3 CImg image (0<=i<=N - 1). - \par Example - \code - CImgList faces3d; - const CImg tensor = CImg::diagonal(10,7,3), - points3d = CImg::ellipsoid3d(faces3d,tensor,4); - CImg().display_object3d("Ellipsoid3d",points3d,faces3d); - \endcode - \image html ref_ellipsoid3d.jpg - **/ - template - static CImg ellipsoid3d(CImgList& primitives, - const CImg& tensor, const unsigned int subdivisions=3) { - primitives.assign(); - if (!subdivisions) return CImg(); - CImg S, V; - tensor.symmetric_eigen(S,V); - const float orient = - (V(0,1)*V(1,2) - V(0,2)*V(1,1))*V(2,0) + - (V(0,2)*V(1,0) - V(0,0)*V(1,2))*V(2,1) + - (V(0,0)*V(1,1) - V(0,1)*V(1,0))*V(2,2); - if (orient<0) { V(2,0) = -V(2,0); V(2,1) = -V(2,1); V(2,2) = -V(2,2); } - const float l0 = S[0], l1 = S[1], l2 = S[2]; - CImg vertices = sphere3d(primitives,1.0,subdivisions); - vertices.get_shared_row(0)*=l0; - vertices.get_shared_row(1)*=l1; - vertices.get_shared_row(2)*=l2; - return V*vertices; - } - - //! Convert 3d object into a CImg3d representation. - /** - \param primitives Primitives data of the 3d object. - \param colors Colors data of the 3d object. - \param opacities Opacities data of the 3d object. - \param full_check Tells if full checking of the 3d object must be performed. - **/ - template - CImg& object3dtoCImg3d(const CImgList& primitives, - const CImgList& colors, - const to& opacities, - const bool full_check=true) { - return get_object3dtoCImg3d(primitives,colors,opacities,full_check).move_to(*this); - } - - //! Convert 3d object into a CImg3d representation \overloading. - template - CImg& object3dtoCImg3d(const CImgList& primitives, - const CImgList& colors, - const bool full_check=true) { - return get_object3dtoCImg3d(primitives,colors,full_check).move_to(*this); - } - - //! Convert 3d object into a CImg3d representation \overloading. - template - CImg& object3dtoCImg3d(const CImgList& primitives, - const bool full_check=true) { - return get_object3dtoCImg3d(primitives,full_check).move_to(*this); - } - - //! Convert 3d object into a CImg3d representation \overloading. - CImg& object3dtoCImg3d(const bool full_check=true) { - return get_object3dtoCImg3d(full_check).move_to(*this); - } - - //! Convert 3d object into a CImg3d representation \newinstance. - template - CImg get_object3dtoCImg3d(const CImgList& primitives, - const CImgList& colors, - const to& opacities, - const bool full_check=true) const { - CImg error_message(1024); - if (!is_object3d(primitives,colors,opacities,full_check,error_message)) - throw CImgInstanceException(_cimg_instance - "object3dtoCImg3d(): Invalid specified 3d object (%u,%u) (%s).", - cimg_instance,_width,primitives._width,error_message.data()); - CImg res(1,_size_object3dtoCImg3d(primitives,colors,opacities)); - float *ptrd = res._data; - - // Put magick number. - *(ptrd++) = 'C' + 0.5f; *(ptrd++) = 'I' + 0.5f; *(ptrd++) = 'm' + 0.5f; - *(ptrd++) = 'g' + 0.5f; *(ptrd++) = '3' + 0.5f; *(ptrd++) = 'd' + 0.5f; - - // Put number of vertices and primitives. - *(ptrd++) = cimg::uint2float(_width); - *(ptrd++) = cimg::uint2float(primitives._width); - - // Put vertex data. - if (is_empty() || !primitives) return res; - const T *ptrx = data(0,0), *ptry = data(0,1), *ptrz = data(0,2); - cimg_forX(*this,p) { - *(ptrd++) = (float)*(ptrx++); - *(ptrd++) = (float)*(ptry++); - *(ptrd++) = (float)*(ptrz++); - } - - // Put primitive data. - cimglist_for(primitives,p) { - *(ptrd++) = (float)primitives[p].size(); - const tp *ptrp = primitives[p]._data; - cimg_foroff(primitives[p],i) *(ptrd++) = cimg::uint2float((unsigned int)*(ptrp++)); - } - - // Put color/texture data. - const unsigned int csiz = cimg::min(colors._width,primitives._width); - for (int c = 0; c<(int)csiz; ++c) { - const CImg& color = colors[c]; - const tc *ptrc = color._data; - if (color.size()==3) { *(ptrd++) = (float)*(ptrc++); *(ptrd++) = (float)*(ptrc++); *(ptrd++) = (float)*ptrc; } - else { - *(ptrd++) = -128.0f; - int shared_ind = -1; - if (color.is_shared()) for (int i = 0; i - float* _object3dtoCImg3d(const CImgList& opacities, float *ptrd) const { - cimglist_for(opacities,o) { - const CImg& opacity = opacities[o]; - const to *ptro = opacity._data; - if (opacity.size()==1) *(ptrd++) = (float)*ptro; - else { - *(ptrd++) = -128.0f; - int shared_ind = -1; - if (opacity.is_shared()) for (int i = 0; i - float* _object3dtoCImg3d(const CImg& opacities, float *ptrd) const { - const to *ptro = opacities._data; - cimg_foroff(opacities,o) *(ptrd++) = (float)*(ptro++); - return ptrd; - } - - template - unsigned int _size_object3dtoCImg3d(const CImgList& primitives, - const CImgList& colors, - const CImgList& opacities) const { - unsigned int siz = 8U + 3*_width; - cimglist_for(primitives,p) siz+=primitives[p].size() + 1; - for (int c = cimg::min(primitives.width(),colors.width()) - 1; c>=0; --c) { - if (colors[c].is_shared()) siz+=4; - else { const unsigned int csiz = colors[c].size(); siz+=(csiz!=3)?4 + csiz:3; } - } - if (colors._width - unsigned int _size_object3dtoCImg3d(const CImgList& primitives, - const CImgList& colors, - const CImg& opacities) const { - unsigned int siz = 8U + 3*_width; - cimglist_for(primitives,p) siz+=primitives[p].size() + 1; - for (int c = cimg::min(primitives.width(),colors.width()) - 1; c>=0; --c) { - const unsigned int csiz = colors[c].size(); siz+=(csiz!=3)?4 + csiz:3; - } - if (colors._width - CImg get_object3dtoCImg3d(const CImgList& primitives, - const CImgList& colors, - const bool full_check=true) const { - CImgList opacities; - return get_object3dtoCImg3d(primitives,colors,opacities,full_check); - } - - //! Convert 3d object into a CImg3d representation \overloading. - template - CImg get_object3dtoCImg3d(const CImgList& primitives, - const bool full_check=true) const { - CImgList colors, opacities; - return get_object3dtoCImg3d(primitives,colors,opacities,full_check); - } - - //! Convert 3d object into a CImg3d representation \overloading. - CImg get_object3dtoCImg3d(const bool full_check=true) const { - CImgList opacities, colors; - CImgList primitives(width(),1,1,1,1); - cimglist_for(primitives,p) primitives(p,0) = p; - return get_object3dtoCImg3d(primitives,colors,opacities,full_check); - } - - //! Convert CImg3d representation into a 3d object. - /** - \param[out] primitives Primitives data of the 3d object. - \param[out] colors Colors data of the 3d object. - \param[out] opacities Opacities data of the 3d object. - \param full_check Tells if full checking of the 3d object must be performed. - **/ - template - CImg& CImg3dtoobject3d(CImgList& primitives, - CImgList& colors, - CImgList& opacities, - const bool full_check=true) { - return get_CImg3dtoobject3d(primitives,colors,opacities,full_check).move_to(*this); - } - - //! Convert CImg3d representation into a 3d object \newinstance. - template - CImg get_CImg3dtoobject3d(CImgList& primitives, - CImgList& colors, - CImgList& opacities, - const bool full_check=true) const { - CImg error_message(1024); - if (!is_CImg3d(full_check,error_message)) - throw CImgInstanceException(_cimg_instance - "CImg3dtoobject3d(): image instance is not a CImg3d (%s).", - cimg_instance,error_message.data()); - const T *ptrs = _data + 6; - const unsigned int - nb_points = cimg::float2uint((float)*(ptrs++)), - nb_primitives = cimg::float2uint((float)*(ptrs++)); - const CImg points = CImg(ptrs,3,nb_points,1,1,true).get_transpose(); - ptrs+=3*nb_points; - primitives.assign(nb_primitives); - cimglist_for(primitives,p) { - const unsigned int nb_inds = (unsigned int)*(ptrs++); - primitives[p].assign(1,nb_inds); - tp *ptrp = primitives[p]._data; - for (unsigned int i = 0; i - CImg& _draw_scanline(const int x0, const int x1, const int y, - const tc *const color, const float opacity, - const float brightness, - const float nopacity, const float copacity, const ulongT whd) { - static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); - const int nx0 = x0>0?x0:0, nx1 = x1=0) { - const tc *col = color; - const ulongT off = whd - dx - 1; - T *ptrd = data(nx0,y); - if (opacity>=1) { // ** Opaque drawing ** - if (brightness==1) { // Brightness==1 - if (sizeof(T)!=1) cimg_forC(*this,c) { - const T val = (T)*(col++); - for (int x = dx; x>=0; --x) *(ptrd++) = val; - ptrd+=off; - } else cimg_forC(*this,c) { - const T val = (T)*(col++); - std::memset(ptrd,(int)val,dx + 1); - ptrd+=whd; - } - } else if (brightness<1) { // Brightness<1 - if (sizeof(T)!=1) cimg_forC(*this,c) { - const T val = (T)(*(col++)*brightness); - for (int x = dx; x>=0; --x) *(ptrd++) = val; - ptrd+=off; - } else cimg_forC(*this,c) { - const T val = (T)(*(col++)*brightness); - std::memset(ptrd,(int)val,dx + 1); - ptrd+=whd; - } - } else { // Brightness>1 - if (sizeof(T)!=1) cimg_forC(*this,c) { - const T val = (T)((2-brightness)**(col++) + (brightness - 1)*maxval); - for (int x = dx; x>=0; --x) *(ptrd++) = val; - ptrd+=off; - } else cimg_forC(*this,c) { - const T val = (T)((2-brightness)**(col++) + (brightness - 1)*maxval); - std::memset(ptrd,(int)val,dx + 1); - ptrd+=whd; - } - } - } else { // ** Transparent drawing ** - if (brightness==1) { // Brightness==1 - cimg_forC(*this,c) { - const T val = (T)*(col++); - for (int x = dx; x>=0; --x) { *ptrd = (T)(val*nopacity + *ptrd*copacity); ++ptrd; } - ptrd+=off; - } - } else if (brightness<=1) { // Brightness<1 - cimg_forC(*this,c) { - const T val = (T)(*(col++)*brightness); - for (int x = dx; x>=0; --x) { *ptrd = (T)(val*nopacity + *ptrd*copacity); ++ptrd; } - ptrd+=off; - } - } else { // Brightness>1 - cimg_forC(*this,c) { - const T val = (T)((2-brightness)**(col++) + (brightness - 1)*maxval); - for (int x = dx; x>=0; --x) { *ptrd = (T)(val*nopacity + *ptrd*copacity); ++ptrd; } - ptrd+=off; - } - } - } - } - return *this; - } - - //! Draw a 3d point. - /** - \param x0 X-coordinate of the point. - \param y0 Y-coordinate of the point. - \param z0 Z-coordinate of the point. - \param color Pointer to \c spectrum() consecutive values, defining the drawing color. - \param opacity Drawing opacity. - \note - - To set pixel values without clipping needs, you should use the faster CImg::operator()() function. - \par Example: - \code - CImg img(100,100,1,3,0); - const unsigned char color[] = { 255,128,64 }; - img.draw_point(50,50,color); - \endcode - **/ - template - CImg& draw_point(const int x0, const int y0, const int z0, - const tc *const color, const float opacity=1) { - if (is_empty()) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_point(): Specified color is (null).", - cimg_instance); - if (x0>=0 && y0>=0 && z0>=0 && x0=1) cimg_forC(*this,c) { *ptrd = (T)*(col++); ptrd+=whd; } - else cimg_forC(*this,c) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whd; } - } - return *this; - } - - //! Draw a 2d point \simplification. - template - CImg& draw_point(const int x0, const int y0, - const tc *const color, const float opacity=1) { - return draw_point(x0,y0,0,color,opacity); - } - - // Draw a points cloud. - /** - \param points Image of vertices coordinates. - \param color Pointer to \c spectrum() consecutive values, defining the drawing color. - \param opacity Drawing opacity. - **/ - template - CImg& draw_point(const CImg& points, - const tc *const color, const float opacity=1) { - if (is_empty() || !points) return *this; - switch (points._height) { - case 0 : case 1 : - throw CImgArgumentException(_cimg_instance - "draw_point(): Invalid specified point set (%u,%u,%u,%u,%p).", - cimg_instance, - points._width,points._height,points._depth,points._spectrum,points._data); - case 2 : { - cimg_forX(points,i) draw_point((int)points(i,0),(int)points(i,1),color,opacity); - } break; - default : { - cimg_forX(points,i) draw_point((int)points(i,0),(int)points(i,1),(int)points(i,2),color,opacity); - } - } - return *this; - } - - //! Draw a 2d line. - /** - \param x0 X-coordinate of the starting line point. - \param y0 Y-coordinate of the starting line point. - \param x1 X-coordinate of the ending line point. - \param y1 Y-coordinate of the ending line point. - \param color Pointer to \c spectrum() consecutive values of type \c T, defining the drawing color. - \param opacity Drawing opacity. - \param pattern An integer whose bits describe the line pattern. - \param init_hatch Tells if a reinitialization of the hash state must be done. - \note - - Line routine uses Bresenham's algorithm. - - Set \p init_hatch = false to draw consecutive hatched segments without breaking the line pattern. - \par Example: - \code - CImg img(100,100,1,3,0); - const unsigned char color[] = { 255,128,64 }; - img.draw_line(40,40,80,70,color); - \endcode - **/ - template - CImg& draw_line(const int x0, const int y0, - const int x1, const int y1, - const tc *const color, const float opacity=1, - const unsigned int pattern=~0U, const bool init_hatch=true) { - if (is_empty()) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_line(): Specified color is (null).", - cimg_instance); - static unsigned int hatch = ~0U - (~0U>>1); - if (init_hatch) hatch = ~0U - (~0U>>1); - const bool xdir = x0=width()) return *this; - if (xleft<0) { yleft-=(int)((float)xleft*((float)yright - yleft)/((float)xright - xleft)); xleft = 0; } - if (xright>=width()) { - yright-=(int)(((float)xright - width())*((float)yright - yleft)/((float)xright - xleft)); - xright = width() - 1; - } - if (ydown<0 || yup>=height()) return *this; - if (yup<0) { xup-=(int)((float)yup*((float)xdown - xup)/((float)ydown - yup)); yup = 0; } - if (ydown>=height()) { - xdown-=(int)(((float)ydown - height())*((float)xdown - xup)/((float)ydown - yup)); - ydown = height() - 1; - } - T *ptrd0 = data(nx0,ny0); - int dx = xright - xleft, dy = ydown - yup; - const bool steep = dy>dx; - if (steep) cimg::swap(nx0,ny0,nx1,ny1,dx,dy); - const longT - offx = (longT)(nx0=1) { - if (~pattern) for (int error = dx>>1, x = 0; x<=dx; ++x) { - if (pattern&hatch) { - T *ptrd = ptrd0; const tc* col = color; - cimg_forC(*this,c) { *ptrd = (T)*(col++); ptrd+=wh; } - } - hatch>>=1; if (!hatch) hatch = ~0U - (~0U>>1); - ptrd0+=offx; - if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } - } else for (int error = dx>>1, x = 0; x<=dx; ++x) { - T *ptrd = ptrd0; const tc* col = color; cimg_forC(*this,c) { *ptrd = (T)*(col++); ptrd+=wh; } - ptrd0+=offx; - if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } - } - } else { - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - if (~pattern) for (int error = dx>>1, x = 0; x<=dx; ++x) { - if (pattern&hatch) { - T *ptrd = ptrd0; const tc* col = color; - cimg_forC(*this,c) { *ptrd = (T)(nopacity**(col++) + *ptrd*copacity); ptrd+=wh; } - } - hatch>>=1; if (!hatch) hatch = ~0U - (~0U>>1); - ptrd0+=offx; - if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } - } else for (int error = dx>>1, x = 0; x<=dx; ++x) { - T *ptrd = ptrd0; const tc* col = color; - cimg_forC(*this,c) { *ptrd = (T)(nopacity**(col++) + *ptrd*copacity); ptrd+=wh; } - ptrd0+=offx; - if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } - } - } - return *this; - } - - //! Draw a 2d line, with z-buffering. - /** - \param zbuffer Zbuffer image. - \param x0 X-coordinate of the starting point. - \param y0 Y-coordinate of the starting point. - \param z0 Z-coordinate of the starting point - \param x1 X-coordinate of the ending point. - \param y1 Y-coordinate of the ending point. - \param z1 Z-coordinate of the ending point. - \param color Pointer to \c spectrum() consecutive values of type \c T, defining the drawing color. - \param opacity Drawing opacity. - \param pattern An integer whose bits describe the line pattern. - \param init_hatch Tells if a reinitialization of the hash state must be done. - **/ - template - CImg& draw_line(CImg& zbuffer, - const int x0, const int y0, const float z0, - const int x1, const int y1, const float z1, - const tc *const color, const float opacity=1, - const unsigned int pattern=~0U, const bool init_hatch=true) { - typedef typename cimg::superset::type tzfloat; - if (is_empty() || z0<=0 || z1<=0) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_line(): Specified color is (null).", - cimg_instance); - if (!is_sameXY(zbuffer)) - throw CImgArgumentException(_cimg_instance - "draw_line(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have " - "different dimensions.", - cimg_instance, - zbuffer._width,zbuffer._height,zbuffer._depth,zbuffer._spectrum,zbuffer._data); - static unsigned int hatch = ~0U - (~0U>>1); - if (init_hatch) hatch = ~0U - (~0U>>1); - const bool xdir = x0=width()) return *this; - if (xleft<0) { - const float D = (float)xright - xleft; - yleft-=(int)((float)xleft*((float)yright - yleft)/D); - zleft-=(tzfloat)xleft*(zright - zleft)/D; - xleft = 0; - } - if (xright>=width()) { - const float d = (float)xright - width(), D = (float)xright - xleft; - yright-=(int)(d*((float)yright - yleft)/D); - zright-=(tzfloat)d*(zright - zleft)/D; - xright = width() - 1; - } - if (ydown<0 || yup>=height()) return *this; - if (yup<0) { - const float D = (float)ydown - yup; - xup-=(int)((float)yup*((float)xdown - xup)/D); - zup-=(tzfloat)yup*(zdown - zup)/D; - yup = 0; - } - if (ydown>=height()) { - const float d = (float)ydown - height(), D = (float)ydown - yup; - xdown-=(int)(d*((float)xdown - xup)/D); - zdown-=(tzfloat)d*(zdown - zup)/D; - ydown = height() - 1; - } - T *ptrd0 = data(nx0,ny0); - tz *ptrz = zbuffer.data(nx0,ny0); - int dx = xright - xleft, dy = ydown - yup; - const bool steep = dy>dx; - if (steep) cimg::swap(nx0,ny0,nx1,ny1,dx,dy); - const longT - offx = (longT)(nx00?dx:1); - if (opacity>=1) { - if (~pattern) for (int error = dx>>1, x = 0; x<=dx; ++x) { - const tzfloat z = Z0 + x*dz/ndx; - if (z>=(tzfloat)*ptrz && pattern&hatch) { - *ptrz = (tz)z; - T *ptrd = ptrd0; const tc *col = color; - cimg_forC(*this,c) { *ptrd = (T)*(col++); ptrd+=wh; } - } - hatch>>=1; if (!hatch) hatch = ~0U - (~0U>>1); - ptrd0+=offx; ptrz+=offx; - if ((error-=dy)<0) { ptrd0+=offy; ptrz+=offy; error+=dx; } - } else for (int error = dx>>1, x = 0; x<=dx; ++x) { - const tzfloat z = Z0 + x*dz/ndx; - if (z>=(tzfloat)*ptrz) { - *ptrz = (tz)z; - T *ptrd = ptrd0; const tc *col = color; - cimg_forC(*this,c) { *ptrd = (T)*(col++); ptrd+=wh; } - } - ptrd0+=offx; ptrz+=offx; - if ((error-=dy)<0) { ptrd0+=offy; ptrz+=offy; error+=dx; } - } - } else { - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - if (~pattern) for (int error = dx>>1, x = 0; x<=dx; ++x) { - const tzfloat z = Z0 + x*dz/ndx; - if (z>=(tzfloat)*ptrz && pattern&hatch) { - *ptrz = (tz)z; - T *ptrd = ptrd0; const tc *col = color; - cimg_forC(*this,c) { *ptrd = (T)(nopacity**(col++) + *ptrd*copacity); ptrd+=wh; } - } - hatch>>=1; if (!hatch) hatch = ~0U - (~0U>>1); - ptrd0+=offx; ptrz+=offx; - if ((error-=dy)<0) { ptrd0+=offy; ptrz+=offy; error+=dx; } - } else for (int error = dx>>1, x = 0; x<=dx; ++x) { - const tzfloat z = Z0 + x*dz/ndx; - if (z>=(tzfloat)*ptrz) { - *ptrz = (tz)z; - T *ptrd = ptrd0; const tc *col = color; - cimg_forC(*this,c) { *ptrd = (T)(nopacity**(col++) + *ptrd*copacity); ptrd+=wh; } - } - ptrd0+=offx; ptrz+=offx; - if ((error-=dy)<0) { ptrd0+=offy; ptrz+=offy; error+=dx; } - } - } - return *this; - } - - //! Draw a 3d line. - /** - \param x0 X-coordinate of the starting point. - \param y0 Y-coordinate of the starting point. - \param z0 Z-coordinate of the starting point - \param x1 X-coordinate of the ending point. - \param y1 Y-coordinate of the ending point. - \param z1 Z-coordinate of the ending point. - \param color Pointer to \c spectrum() consecutive values of type \c T, defining the drawing color. - \param opacity Drawing opacity. - \param pattern An integer whose bits describe the line pattern. - \param init_hatch Tells if a reinitialization of the hash state must be done. - **/ - template - CImg& draw_line(const int x0, const int y0, const int z0, - const int x1, const int y1, const int z1, - const tc *const color, const float opacity=1, - const unsigned int pattern=~0U, const bool init_hatch=true) { - if (is_empty()) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_line(): Specified color is (null).", - cimg_instance); - static unsigned int hatch = ~0U - (~0U>>1); - if (init_hatch) hatch = ~0U - (~0U>>1); - int nx0 = x0, ny0 = y0, nz0 = z0, nx1 = x1, ny1 = y1, nz1 = z1; - if (nx0>nx1) cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1); - if (nx1<0 || nx0>=width()) return *this; - if (nx0<0) { - const float D = 1.0f + nx1 - nx0; - ny0-=(int)((float)nx0*(1.0f + ny1 - ny0)/D); - nz0-=(int)((float)nx0*(1.0f + nz1 - nz0)/D); - nx0 = 0; - } - if (nx1>=width()) { - const float d = (float)nx1 - width(), D = 1.0f + nx1 - nx0; - ny1+=(int)(d*(1.0f + ny0 - ny1)/D); - nz1+=(int)(d*(1.0f + nz0 - nz1)/D); - nx1 = width() - 1; - } - if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1); - if (ny1<0 || ny0>=height()) return *this; - if (ny0<0) { - const float D = 1.0f + ny1 - ny0; - nx0-=(int)((float)ny0*(1.0f + nx1 - nx0)/D); - nz0-=(int)((float)ny0*(1.0f + nz1 - nz0)/D); - ny0 = 0; - } - if (ny1>=height()) { - const float d = (float)ny1 - height(), D = 1.0f + ny1 - ny0; - nx1+=(int)(d*(1.0f + nx0 - nx1)/D); - nz1+=(int)(d*(1.0f + nz0 - nz1)/D); - ny1 = height() - 1; - } - if (nz0>nz1) cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1); - if (nz1<0 || nz0>=depth()) return *this; - if (nz0<0) { - const float D = 1.0f + nz1 - nz0; - nx0-=(int)((float)nz0*(1.0f + nx1 - nx0)/D); - ny0-=(int)((float)nz0*(1.0f + ny1 - ny0)/D); - nz0 = 0; - } - if (nz1>=depth()) { - const float d = (float)nz1 - depth(), D = 1.0f + nz1 - nz0; - nx1+=(int)(d*(1.0f + nx0 - nx1)/D); - ny1+=(int)(d*(1.0f + ny0 - ny1)/D); - nz1 = depth() - 1; - } - const unsigned int dmax = (unsigned int)cimg::max(cimg::abs(nx1 - nx0),cimg::abs(ny1 - ny0),nz1 - nz0); - const ulongT whd = (ulongT)_width*_height*_depth; - const float px = (nx1 - nx0)/(float)dmax, py = (ny1 - ny0)/(float)dmax, pz = (nz1 - nz0)/(float)dmax; - float x = (float)nx0, y = (float)ny0, z = (float)nz0; - if (opacity>=1) for (unsigned int t = 0; t<=dmax; ++t) { - if (!(~pattern) || (~pattern && pattern&hatch)) { - T* ptrd = data((unsigned int)x,(unsigned int)y,(unsigned int)z); - const tc *col = color; cimg_forC(*this,c) { *ptrd = (T)*(col++); ptrd+=whd; } - } - x+=px; y+=py; z+=pz; if (pattern) { hatch>>=1; if (!hatch) hatch = ~0U - (~0U>>1); } - } else { - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - for (unsigned int t = 0; t<=dmax; ++t) { - if (!(~pattern) || (~pattern && pattern&hatch)) { - T* ptrd = data((unsigned int)x,(unsigned int)y,(unsigned int)z); - const tc *col = color; cimg_forC(*this,c) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whd; } - } - x+=px; y+=py; z+=pz; if (pattern) { hatch>>=1; if (!hatch) hatch = ~0U - (~0U>>1); } - } - } - return *this; - } - - //! Draw a textured 2d line. - /** - \param x0 X-coordinate of the starting line point. - \param y0 Y-coordinate of the starting line point. - \param x1 X-coordinate of the ending line point. - \param y1 Y-coordinate of the ending line point. - \param texture Texture image defining the pixel colors. - \param tx0 X-coordinate of the starting texture point. - \param ty0 Y-coordinate of the starting texture point. - \param tx1 X-coordinate of the ending texture point. - \param ty1 Y-coordinate of the ending texture point. - \param opacity Drawing opacity. - \param pattern An integer whose bits describe the line pattern. - \param init_hatch Tells if the hash variable must be reinitialized. - \note - - Line routine uses the well known Bresenham's algorithm. - \par Example: - \code - CImg img(100,100,1,3,0), texture("texture256x256.ppm"); - const unsigned char color[] = { 255,128,64 }; - img.draw_line(40,40,80,70,texture,0,0,255,255); - \endcode - **/ - template - CImg& draw_line(const int x0, const int y0, - const int x1, const int y1, - const CImg& texture, - const int tx0, const int ty0, - const int tx1, const int ty1, - const float opacity=1, - const unsigned int pattern=~0U, const bool init_hatch=true) { - if (is_empty()) return *this; - if (texture._depth>1 || texture._spectrum<_spectrum) - throw CImgArgumentException(_cimg_instance - "draw_line(): Invalid specified texture (%u,%u,%u,%u,%p).", - cimg_instance, - texture._width,texture._height,texture._depth,texture._spectrum,texture._data); - if (is_overlapped(texture)) return draw_line(x0,y0,x1,y1,+texture,tx0,ty0,tx1,ty1,opacity,pattern,init_hatch); - static unsigned int hatch = ~0U - (~0U>>1); - if (init_hatch) hatch = ~0U - (~0U>>1); - const bool xdir = x0=width()) return *this; - if (xleft<0) { - const float D = (float)xright - xleft; - yleft-=(int)((float)xleft*((float)yright - yleft)/D); - txleft-=(int)((float)xleft*((float)txright - txleft)/D); - tyleft-=(int)((float)xleft*((float)tyright - tyleft)/D); - xleft = 0; - } - if (xright>=width()) { - const float d = (float)xright - width(), D = (float)xright - xleft; - yright-=(int)(d*((float)yright - yleft)/D); - txright-=(int)(d*((float)txright - txleft)/D); - tyright-=(int)(d*((float)tyright - tyleft)/D); - xright = width() - 1; - } - if (ydown<0 || yup>=height()) return *this; - if (yup<0) { - const float D = (float)ydown - yup; - xup-=(int)((float)yup*((float)xdown - xup)/D); - txup-=(int)((float)yup*((float)txdown - txup)/D); - tyup-=(int)((float)yup*((float)tydown - tyup)/D); - yup = 0; - } - if (ydown>=height()) { - const float d = (float)ydown - height(), D = (float)ydown - yup; - xdown-=(int)(d*((float)xdown - xup)/D); - txdown-=(int)(d*((float)txdown - txup)/D); - tydown-=(int)(d*((float)tydown - tyup)/D); - ydown = height() - 1; - } - T *ptrd0 = data(nx0,ny0); - int dx = xright - xleft, dy = ydown - yup; - const bool steep = dy>dx; - if (steep) cimg::swap(nx0,ny0,nx1,ny1,dx,dy); - const longT - offx = (longT)(nx00?dx:1); - const ulongT - whd = (ulongT)_width*_height*_depth, - twh = (ulongT)texture._width*texture._height; - - if (opacity>=1) { - if (~pattern) for (int error = dx>>1, x = 0; x<=dx; ++x) { - if (pattern&hatch) { - T *ptrd = ptrd0; - const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx; - const tc *col = &texture._atXY(tx,ty); - cimg_forC(*this,c) { *ptrd = (T)*col; ptrd+=whd; col+=twh; } - } - hatch>>=1; if (!hatch) hatch = ~0U - (~0U>>1); - ptrd0+=offx; - if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } - } else for (int error = dx>>1, x = 0; x<=dx; ++x) { - T *ptrd = ptrd0; - const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx; - const tc *col = &texture._atXY(tx,ty); - cimg_forC(*this,c) { *ptrd = (T)*col; ptrd+=whd; col+=twh; } - ptrd0+=offx; - if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } - } - } else { - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - if (~pattern) for (int error = dx>>1, x = 0; x<=dx; ++x) { - T *ptrd = ptrd0; - if (pattern&hatch) { - const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx; - const tc *col = &texture._atXY(tx,ty); - cimg_forC(*this,c) { *ptrd = (T)(nopacity**col + *ptrd*copacity); ptrd+=whd; col+=twh; } - } - hatch>>=1; if (!hatch) hatch = ~0U - (~0U>>1); - ptrd0+=offx; - if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } - } else for (int error = dx>>1, x = 0; x<=dx; ++x) { - T *ptrd = ptrd0; - const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx; - const tc *col = &texture._atXY(tx,ty); - cimg_forC(*this,c) { *ptrd = (T)(nopacity**col + *ptrd*copacity); ptrd+=whd; col+=twh; } - ptrd0+=offx; - if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } - } - } - return *this; - } - - //! Draw a textured 2d line, with perspective correction. - /** - \param x0 X-coordinate of the starting point. - \param y0 Y-coordinate of the starting point. - \param z0 Z-coordinate of the starting point - \param x1 X-coordinate of the ending point. - \param y1 Y-coordinate of the ending point. - \param z1 Z-coordinate of the ending point. - \param texture Texture image defining the pixel colors. - \param tx0 X-coordinate of the starting texture point. - \param ty0 Y-coordinate of the starting texture point. - \param tx1 X-coordinate of the ending texture point. - \param ty1 Y-coordinate of the ending texture point. - \param opacity Drawing opacity. - \param pattern An integer whose bits describe the line pattern. - \param init_hatch Tells if the hash variable must be reinitialized. - **/ - template - CImg& draw_line(const int x0, const int y0, const float z0, - const int x1, const int y1, const float z1, - const CImg& texture, - const int tx0, const int ty0, - const int tx1, const int ty1, - const float opacity=1, - const unsigned int pattern=~0U, const bool init_hatch=true) { - if (is_empty() && z0<=0 && z1<=0) return *this; - if (texture._depth>1 || texture._spectrum<_spectrum) - throw CImgArgumentException(_cimg_instance - "draw_line(): Invalid specified texture (%u,%u,%u,%u,%p).", - cimg_instance, - texture._width,texture._height,texture._depth,texture._spectrum,texture._data); - if (is_overlapped(texture)) - return draw_line(x0,y0,z0,x1,y1,z1,+texture,tx0,ty0,tx1,ty1,opacity,pattern,init_hatch); - static unsigned int hatch = ~0U - (~0U>>1); - if (init_hatch) hatch = ~0U - (~0U>>1); - const bool xdir = x0=width()) return *this; - if (xleft<0) { - const float D = (float)xright - xleft; - yleft-=(int)((float)xleft*((float)yright - yleft)/D); - zleft-=(float)xleft*(zright - zleft)/D; - txleft-=(float)xleft*(txright - txleft)/D; - tyleft-=(float)xleft*(tyright - tyleft)/D; - xleft = 0; - } - if (xright>=width()) { - const float d = (float)xright - width(), D = (float)xright - xleft; - yright-=(int)(d*((float)yright - yleft)/D); - zright-=d*(zright - zleft)/D; - txright-=d*(txright - txleft)/D; - tyright-=d*(tyright - tyleft)/D; - xright = width() - 1; - } - if (ydown<0 || yup>=height()) return *this; - if (yup<0) { - const float D = (float)ydown - yup; - xup-=(int)((float)yup*((float)xdown - xup)/D); - zup-=(float)yup*(zdown - zup)/D; - txup-=(float)yup*(txdown - txup)/D; - tyup-=(float)yup*(tydown - tyup)/D; - yup = 0; - } - if (ydown>=height()) { - const float d = (float)ydown - height(), D = (float)ydown - yup; - xdown-=(int)(d*((float)xdown - xup)/D); - zdown-=d*(zdown - zup)/D; - txdown-=d*(txdown - txup)/D; - tydown-=d*(tydown - tyup)/D; - ydown = height() - 1; - } - T *ptrd0 = data(nx0,ny0); - int dx = xright - xleft, dy = ydown - yup; - const bool steep = dy>dx; - if (steep) cimg::swap(nx0,ny0,nx1,ny1,dx,dy); - const longT - offx = (longT)(nx00?dx:1); - const ulongT - whd = (ulongT)_width*_height*_depth, - twh = (ulongT)texture._width*texture._height; - - if (opacity>=1) { - if (~pattern) for (int error = dx>>1, x = 0; x<=dx; ++x) { - if (pattern&hatch) { - const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx; - const tc *col = &texture._atXY((int)(tx/z),(int)(ty/z)); - T *ptrd = ptrd0; - cimg_forC(*this,c) { *ptrd = (T)*col; ptrd+=whd; col+=twh; } - } - hatch>>=1; if (!hatch) hatch = ~0U - (~0U>>1); - ptrd0+=offx; - if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } - } else for (int error = dx>>1, x = 0; x<=dx; ++x) { - const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx; - const tc *col = &texture._atXY((int)(tx/z),(int)(ty/z)); - T *ptrd = ptrd0; - cimg_forC(*this,c) { *ptrd = (T)*col; ptrd+=whd; col+=twh; } - ptrd0+=offx; - if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } - } - } else { - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - if (~pattern) for (int error = dx>>1, x = 0; x<=dx; ++x) { - if (pattern&hatch) { - const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx; - const tc *col = &texture._atXY((int)(tx/z),(int)(ty/z)); - T *ptrd = ptrd0; - cimg_forC(*this,c) { *ptrd = (T)(nopacity**col + *ptrd*copacity); ptrd+=whd; col+=twh; } - } - hatch>>=1; if (!hatch) hatch = ~0U - (~0U>>1); - ptrd0+=offx; - if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } - } else for (int error = dx>>1, x = 0; x<=dx; ++x) { - const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx; - const tc *col = &texture._atXY((int)(tx/z),(int)(ty/z)); - T *ptrd = ptrd0; - cimg_forC(*this,c) { *ptrd = (T)(nopacity**col + *ptrd*copacity); ptrd+=whd; col+=twh; } - ptrd0+=offx; - if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } - } - } - return *this; - } - - //! Draw a textured 2d line, with perspective correction and z-buffering. - /** - \param zbuffer Z-buffer image. - \param x0 X-coordinate of the starting point. - \param y0 Y-coordinate of the starting point. - \param z0 Z-coordinate of the starting point - \param x1 X-coordinate of the ending point. - \param y1 Y-coordinate of the ending point. - \param z1 Z-coordinate of the ending point. - \param texture Texture image defining the pixel colors. - \param tx0 X-coordinate of the starting texture point. - \param ty0 Y-coordinate of the starting texture point. - \param tx1 X-coordinate of the ending texture point. - \param ty1 Y-coordinate of the ending texture point. - \param opacity Drawing opacity. - \param pattern An integer whose bits describe the line pattern. - \param init_hatch Tells if the hash variable must be reinitialized. - **/ - template - CImg& draw_line(CImg& zbuffer, - const int x0, const int y0, const float z0, - const int x1, const int y1, const float z1, - const CImg& texture, - const int tx0, const int ty0, - const int tx1, const int ty1, - const float opacity=1, - const unsigned int pattern=~0U, const bool init_hatch=true) { - typedef typename cimg::superset::type tzfloat; - if (is_empty() || z0<=0 || z1<=0) return *this; - if (!is_sameXY(zbuffer)) - throw CImgArgumentException(_cimg_instance - "draw_line(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have " - "different dimensions.", - cimg_instance, - zbuffer._width,zbuffer._height,zbuffer._depth,zbuffer._spectrum,zbuffer._data); - if (texture._depth>1 || texture._spectrum<_spectrum) - throw CImgArgumentException(_cimg_instance - "draw_line(): Invalid specified texture (%u,%u,%u,%u,%p).", - cimg_instance, - texture._width,texture._height,texture._depth,texture._spectrum,texture._data); - if (is_overlapped(texture)) - return draw_line(zbuffer,x0,y0,z0,x1,y1,z1,+texture,tx0,ty0,tx1,ty1,opacity,pattern,init_hatch); - static unsigned int hatch = ~0U - (~0U>>1); - if (init_hatch) hatch = ~0U - (~0U>>1); - const bool xdir = x0=width()) return *this; - if (xleft<0) { - const float D = (float)xright - xleft; - yleft-=(int)((float)xleft*((float)yright - yleft)/D); - zleft-=(float)xleft*(zright - zleft)/D; - txleft-=(float)xleft*(txright - txleft)/D; - tyleft-=(float)xleft*(tyright - tyleft)/D; - xleft = 0; - } - if (xright>=width()) { - const float d = (float)xright - width(), D = (float)xright - xleft; - yright-=(int)(d*((float)yright - yleft)/D); - zright-=d*(zright - zleft)/D; - txright-=d*(txright - txleft)/D; - tyright-=d*(tyright - tyleft)/D; - xright = width() - 1; - } - if (ydown<0 || yup>=height()) return *this; - if (yup<0) { - const float D = (float)ydown - yup; - xup-=(int)((float)yup*((float)xdown - xup)/D); - zup-=yup*(zdown - zup)/D; - txup-=yup*(txdown - txup)/D; - tyup-=yup*(tydown - tyup)/D; - yup = 0; - } - if (ydown>=height()) { - const float d = (float)ydown - height(), D = (float)ydown - yup; - xdown-=(int)(d*((float)xdown - xup)/D); - zdown-=d*(zdown - zup)/D; - txdown-=d*(txdown - txup)/D; - tydown-=d*(tydown - tyup)/D; - ydown = height() - 1; - } - T *ptrd0 = data(nx0,ny0); - tz *ptrz = zbuffer.data(nx0,ny0); - int dx = xright - xleft, dy = ydown - yup; - const bool steep = dy>dx; - if (steep) cimg::swap(nx0,ny0,nx1,ny1,dx,dy); - const longT - offx = (longT)(nx00?dx:1); - const ulongT - whd = (ulongT)_width*_height*_depth, - twh = (ulongT)texture._width*texture._height; - - if (opacity>=1) { - if (~pattern) for (int error = dx>>1, x = 0; x<=dx; ++x) { - if (pattern&hatch) { - const tzfloat z = Z0 + x*dz/ndx; - if (z>=(tzfloat)*ptrz) { - *ptrz = (tz)z; - const float tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx; - const tc *col = &texture._atXY((int)(tx/z),(int)(ty/z)); - T *ptrd = ptrd0; - cimg_forC(*this,c) { *ptrd = (T)*col; ptrd+=whd; col+=twh; } - } - } - hatch>>=1; if (!hatch) hatch = ~0U - (~0U>>1); - ptrd0+=offx; ptrz+=offx; - if ((error-=dy)<0) { ptrd0+=offy; ptrz+=offy; error+=dx; } - } else for (int error = dx>>1, x = 0; x<=dx; ++x) { - const tzfloat z = Z0 + x*dz/ndx; - if (z>=(tzfloat)*ptrz) { - *ptrz = (tz)z; - const float tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx; - const tc *col = &texture._atXY((int)(tx/z),(int)(ty/z)); - T *ptrd = ptrd0; - cimg_forC(*this,c) { *ptrd = (T)*col; ptrd+=whd; col+=twh; } - } - ptrd0+=offx; ptrz+=offx; - if ((error-=dy)<0) { ptrd0+=offy; ptrz+=offy; error+=dx; } - } - } else { - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - if (~pattern) for (int error = dx>>1, x = 0; x<=dx; ++x) { - if (pattern&hatch) { - const tzfloat z = Z0 + x*dz/ndx; - if (z>=(tzfloat)*ptrz) { - *ptrz = (tz)z; - const float tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx; - const tc *col = &texture._atXY((int)(tx/z),(int)(ty/z)); - T *ptrd = ptrd0; - cimg_forC(*this,c) { *ptrd = (T)(nopacity**col + *ptrd*copacity); ptrd+=whd; col+=twh; } - } - } - hatch>>=1; if (!hatch) hatch = ~0U - (~0U>>1); - ptrd0+=offx; ptrz+=offx; - if ((error-=dy)<0) { ptrd0+=offy; ptrz+=offy; error+=dx; } - } else for (int error = dx>>1, x = 0; x<=dx; ++x) { - const tzfloat z = Z0 + x*dz/ndx; - if (z>=(tzfloat)*ptrz) { - *ptrz = (tz)z; - const float tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx; - const tc *col = &texture._atXY((int)(tx/z),(int)(ty/z)); - T *ptrd = ptrd0; - cimg_forC(*this,c) { *ptrd = (T)(nopacity**col + *ptrd*copacity); ptrd+=whd; col+=twh; } - } - ptrd0+=offx; ptrz+=offx; - if ((error-=dy)<0) { ptrd0+=offy; ptrz+=offy; error+=dx; } - } - } - return *this; - } - - //! Draw a set of consecutive lines. - /** - \param points Coordinates of vertices, stored as a list of vectors. - \param color Pointer to \c spectrum() consecutive values of type \c T, defining the drawing color. - \param opacity Drawing opacity. - \param pattern An integer whose bits describe the line pattern. - \param init_hatch If set to true, init hatch motif. - \note - - This function uses several call to the single CImg::draw_line() procedure, - depending on the vectors size in \p points. - **/ - template - CImg& draw_line(const CImg& points, - const tc *const color, const float opacity=1, - const unsigned int pattern=~0U, const bool init_hatch=true) { - if (is_empty() || !points || points._width<2) return *this; - bool ninit_hatch = init_hatch; - switch (points._height) { - case 0 : case 1 : - throw CImgArgumentException(_cimg_instance - "draw_line(): Invalid specified point set (%u,%u,%u,%u,%p).", - cimg_instance, - points._width,points._height,points._depth,points._spectrum,points._data); - - case 2 : { - const int x0 = (int)points(0,0), y0 = (int)points(0,1); - int ox = x0, oy = y0; - for (unsigned int i = 1; i - CImg& draw_arrow(const int x0, const int y0, - const int x1, const int y1, - const tc *const color, const float opacity=1, - const float angle=30, const float length=-10, - const unsigned int pattern=~0U) { - if (is_empty()) return *this; - const float u = (float)(x0 - x1), v = (float)(y0 - y1), sq = u*u + v*v, - deg = (float)(angle*cimg::PI/180), ang = (sq>0)?(float)std::atan2(v,u):0.0f, - l = (length>=0)?length:-length*(float)std::sqrt(sq)/100; - if (sq>0) { - const float - cl = (float)std::cos(ang - deg), sl = (float)std::sin(ang - deg), - cr = (float)std::cos(ang + deg), sr = (float)std::sin(ang + deg); - const int - xl = x1 + (int)(l*cl), yl = y1 + (int)(l*sl), - xr = x1 + (int)(l*cr), yr = y1 + (int)(l*sr), - xc = x1 + (int)((l + 1)*(cl + cr))/2, yc = y1 + (int)((l + 1)*(sl + sr))/2; - draw_line(x0,y0,xc,yc,color,opacity,pattern).draw_triangle(x1,y1,xl,yl,xr,yr,color,opacity); - } else draw_point(x0,y0,color,opacity); - return *this; - } - - //! Draw a 2d spline. - /** - \param x0 X-coordinate of the starting curve point - \param y0 Y-coordinate of the starting curve point - \param u0 X-coordinate of the starting velocity - \param v0 Y-coordinate of the starting velocity - \param x1 X-coordinate of the ending curve point - \param y1 Y-coordinate of the ending curve point - \param u1 X-coordinate of the ending velocity - \param v1 Y-coordinate of the ending velocity - \param color Pointer to \c spectrum() consecutive values of type \c T, defining the drawing color. - \param precision Curve drawing precision. - \param opacity Drawing opacity. - \param pattern An integer whose bits describe the line pattern. - \param init_hatch If \c true, init hatch motif. - \note - - The curve is a 2d cubic Bezier spline, from the set of specified starting/ending points - and corresponding velocity vectors. - - The spline is drawn as a serie of connected segments. The \p precision parameter sets the - average number of pixels in each drawn segment. - - A cubic Bezier curve is sometimes defined by a set of 4 points { (\p x0,\p y0), (\p xa,\p ya), - (\p xb,\p yb), (\p x1,\p y1) } where (\p x0,\p y0) is the starting point, (\p x1,\p y1) is the ending point - and (\p xa,\p ya), (\p xb,\p yb) are two - \e control points. - The starting and ending velocities (\p u0,\p v0) and (\p u1,\p v1) can be deduced easily from - the control points as - \p u0 = (\p xa - \p x0), \p v0 = (\p ya - \p y0), \p u1 = (\p x1 - \p xb) and \p v1 = (\p y1 - \p yb). - \par Example: - \code - CImg img(100,100,1,3,0); - const unsigned char color[] = { 255,255,255 }; - img.draw_spline(30,30,0,100,90,40,0,-100,color); - \endcode - **/ - template - CImg& draw_spline(const int x0, const int y0, const float u0, const float v0, - const int x1, const int y1, const float u1, const float v1, - const tc *const color, const float opacity=1, - const float precision=0.25, const unsigned int pattern=~0U, - const bool init_hatch=true) { - if (is_empty()) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_spline(): Specified color is (null).", - cimg_instance); - if (x0==x1 && y0==y1) return draw_point(x0,y0,color,opacity); - bool ninit_hatch = init_hatch; - const float - ax = u0 + u1 + 2*(x0 - x1), - bx = 3*(x1 - x0) - 2*u0 - u1, - ay = v0 + v1 + 2*(y0 - y1), - by = 3*(y1 - y0) - 2*v0 - v1, - _precision = 1/(std::sqrt(cimg::sqr((float)x0 - x1) + cimg::sqr((float)y0 - y1))*(precision>0?precision:1)); - int ox = x0, oy = y0; - for (float t = 0; t<1; t+=_precision) { - const float t2 = t*t, t3 = t2*t; - const int - nx = (int)(ax*t3 + bx*t2 + u0*t + x0), - ny = (int)(ay*t3 + by*t2 + v0*t + y0); - draw_line(ox,oy,nx,ny,color,opacity,pattern,ninit_hatch); - ninit_hatch = false; - ox = nx; oy = ny; - } - return draw_line(ox,oy,x1,y1,color,opacity,pattern,false); - } - - //! Draw a 3d spline \overloading. - /** - \note - - Similar to CImg::draw_spline() for a 3d spline in a volumetric image. - **/ - template - CImg& draw_spline(const int x0, const int y0, const int z0, const float u0, const float v0, const float w0, - const int x1, const int y1, const int z1, const float u1, const float v1, const float w1, - const tc *const color, const float opacity=1, - const float precision=4, const unsigned int pattern=~0U, - const bool init_hatch=true) { - if (is_empty()) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_spline(): Specified color is (null).", - cimg_instance); - if (x0==x1 && y0==y1 && z0==z1) return draw_point(x0,y0,z0,color,opacity); - bool ninit_hatch = init_hatch; - const float - ax = u0 + u1 + 2*(x0 - x1), - bx = 3*(x1 - x0) - 2*u0 - u1, - ay = v0 + v1 + 2*(y0 - y1), - by = 3*(y1 - y0) - 2*v0 - v1, - az = w0 + w1 + 2*(z0 - z1), - bz = 3*(z1 - z0) - 2*w0 - w1, - _precision = 1/(std::sqrt(cimg::sqr(x0 - x1) + cimg::sqr(y0 - y1))*(precision>0?precision:1)); - int ox = x0, oy = y0, oz = z0; - for (float t = 0; t<1; t+=_precision) { - const float t2 = t*t, t3 = t2*t; - const int - nx = (int)(ax*t3 + bx*t2 + u0*t + x0), - ny = (int)(ay*t3 + by*t2 + v0*t + y0), - nz = (int)(az*t3 + bz*t2 + w0*t + z0); - draw_line(ox,oy,oz,nx,ny,nz,color,opacity,pattern,ninit_hatch); - ninit_hatch = false; - ox = nx; oy = ny; oz = nz; - } - return draw_line(ox,oy,oz,x1,y1,z1,color,opacity,pattern,false); - } - - //! Draw a textured 2d spline. - /** - \param x0 X-coordinate of the starting curve point - \param y0 Y-coordinate of the starting curve point - \param u0 X-coordinate of the starting velocity - \param v0 Y-coordinate of the starting velocity - \param x1 X-coordinate of the ending curve point - \param y1 Y-coordinate of the ending curve point - \param u1 X-coordinate of the ending velocity - \param v1 Y-coordinate of the ending velocity - \param texture Texture image defining line pixel colors. - \param tx0 X-coordinate of the starting texture point. - \param ty0 Y-coordinate of the starting texture point. - \param tx1 X-coordinate of the ending texture point. - \param ty1 Y-coordinate of the ending texture point. - \param precision Curve drawing precision. - \param opacity Drawing opacity. - \param pattern An integer whose bits describe the line pattern. - \param init_hatch if \c true, reinit hatch motif. - **/ - template - CImg& draw_spline(const int x0, const int y0, const float u0, const float v0, - const int x1, const int y1, const float u1, const float v1, - const CImg& texture, - const int tx0, const int ty0, const int tx1, const int ty1, - const float opacity=1, - const float precision=4, const unsigned int pattern=~0U, - const bool init_hatch=true) { - if (texture._depth>1 || texture._spectrum<_spectrum) - throw CImgArgumentException(_cimg_instance - "draw_spline(): Invalid specified texture (%u,%u,%u,%u,%p).", - cimg_instance, - texture._width,texture._height,texture._depth,texture._spectrum,texture._data); - if (is_empty()) return *this; - if (is_overlapped(texture)) - return draw_spline(x0,y0,u0,v0,x1,y1,u1,v1,+texture,tx0,ty0,tx1,ty1,precision,opacity,pattern,init_hatch); - if (x0==x1 && y0==y1) - return draw_point(x0,y0,texture.get_vector_at(x0<=0?0:x0>=texture.width()?texture.width() - 1:x0, - y0<=0?0:y0>=texture.height()?texture.height() - 1:y0),opacity); - bool ninit_hatch = init_hatch; - const float - ax = u0 + u1 + 2*(x0 - x1), - bx = 3*(x1 - x0) - 2*u0 - u1, - ay = v0 + v1 + 2*(y0 - y1), - by = 3*(y1 - y0) - 2*v0 - v1, - _precision = 1/(std::sqrt(cimg::sqr(x0 - x1) + cimg::sqr(y0 - y1))*(precision>0?precision:1)); - int ox = x0, oy = y0, otx = tx0, oty = ty0; - for (float t1 = 0; t1<1; t1+=_precision) { - const float t2 = t1*t1, t3 = t2*t1; - const int - nx = (int)(ax*t3 + bx*t2 + u0*t1 + x0), - ny = (int)(ay*t3 + by*t2 + v0*t1 + y0), - ntx = tx0 + (int)((tx1 - tx0)*t1), - nty = ty0 + (int)((ty1 - ty0)*t1); - draw_line(ox,oy,nx,ny,texture,otx,oty,ntx,nty,opacity,pattern,ninit_hatch); - ninit_hatch = false; - ox = nx; oy = ny; otx = ntx; oty = nty; - } - return draw_line(ox,oy,x1,y1,texture,otx,oty,tx1,ty1,opacity,pattern,false); - } - - //! Draw a set of consecutive splines. - /** - \param points Vertices data. - \param tangents Tangents data. - \param color Pointer to \c spectrum() consecutive values of type \c T, defining the drawing color. - \param opacity Drawing opacity. - \param is_closed_set Tells if the drawn spline set is closed. - \param precision Precision of the drawing. - \param pattern An integer whose bits describe the line pattern. - \param init_hatch If \c true, init hatch motif. - **/ - template - CImg& draw_spline(const CImg& points, const CImg& tangents, - const tc *const color, const float opacity=1, - const bool is_closed_set=false, const float precision=4, - const unsigned int pattern=~0U, const bool init_hatch=true) { - if (is_empty() || !points || !tangents || points._width<2 || tangents._width<2) return *this; - bool ninit_hatch = init_hatch; - switch (points._height) { - case 0 : case 1 : - throw CImgArgumentException(_cimg_instance - "draw_spline(): Invalid specified point set (%u,%u,%u,%u,%p).", - cimg_instance, - points._width,points._height,points._depth,points._spectrum,points._data); - - case 2 : { - const int x0 = (int)points(0,0), y0 = (int)points(0,1); - const float u0 = (float)tangents(0,0), v0 = (float)tangents(0,1); - int ox = x0, oy = y0; - float ou = u0, ov = v0; - for (unsigned int i = 1; i - CImg& draw_spline(const CImg& points, - const tc *const color, const float opacity=1, - const bool is_closed_set=false, const float precision=4, - const unsigned int pattern=~0U, const bool init_hatch=true) { - if (is_empty() || !points || points._width<2) return *this; - CImg tangents; - switch (points._height) { - case 0 : case 1 : - throw CImgArgumentException(_cimg_instance - "draw_spline(): Invalid specified point set (%u,%u,%u,%u,%p).", - cimg_instance, - points._width,points._height,points._depth,points._spectrum,points._data); - case 2 : { - tangents.assign(points._width,points._height); - cimg_forX(points,p) { - const unsigned int - p0 = is_closed_set?(p + points._width - 1)%points._width:(p?p - 1:0), - p1 = is_closed_set?(p + 1)%points._width:(p + 1=0?x0:(x0 - y0*(x2 - x0)/(y2 - y0)), \ - xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0 - y0*(x1 - x0)/(y1 - y0))):(x1 - y1*(x2 - x1)/(y2 - y1)), \ - _sxn=1, \ - _sxr=1, \ - _sxl=1, \ - _dxn = x2>x1?x2-x1:(_sxn=-1,x1 - x2), \ - _dxr = x2>x0?x2-x0:(_sxr=-1,x0 - x2), \ - _dxl = x1>x0?x1-x0:(_sxl=-1,x0 - x1), \ - _dyn = y2-y1, \ - _dyr = y2-y0, \ - _dyl = y1-y0, \ - _counter = (_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \ - _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \ - _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \ - cimg::min((int)(img)._height - y - 1,y2 - y)), \ - _errn = _dyn/2, \ - _errr = _dyr/2, \ - _errl = _dyl/2, \ - _rxn = _dyn?(x2-x1)/_dyn:0, \ - _rxr = _dyr?(x2-x0)/_dyr:0, \ - _rxl = (y0!=y1 && y1>0)?(_dyl?(x1-x0)/_dyl:0): \ - (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn); \ - _counter>=0; --_counter, ++y, \ - xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \ - xl+=(y!=y1)?_rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0): \ - (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1-xl)) - -#define _cimg_for_triangle2(img,xl,cl,xr,cr,y,x0,y0,c0,x1,y1,c1,x2,y2,c2) \ - for (int y = y0<0?0:y0, \ - xr = y0>=0?x0:(x0 - y0*(x2 - x0)/(y2 - y0)), \ - cr = y0>=0?c0:(c0 - y0*(c2 - c0)/(y2 - y0)), \ - xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0 - y0*(x1 - x0)/(y1 - y0))):(x1 - y1*(x2 - x1)/(y2 - y1)), \ - cl = y1>=0?(y0>=0?(y0==y1?c1:c0):(c0 - y0*(c1 - c0)/(y1 - y0))):(c1 - y1*(c2 - c1)/(y2 - y1)), \ - _sxn=1, _scn=1, \ - _sxr=1, _scr=1, \ - _sxl=1, _scl=1, \ - _dxn = x2>x1?x2-x1:(_sxn=-1,x1 - x2), \ - _dxr = x2>x0?x2-x0:(_sxr=-1,x0 - x2), \ - _dxl = x1>x0?x1-x0:(_sxl=-1,x0 - x1), \ - _dcn = c2>c1?c2-c1:(_scn=-1,c1 - c2), \ - _dcr = c2>c0?c2-c0:(_scr=-1,c0 - c2), \ - _dcl = c1>c0?c1-c0:(_scl=-1,c0 - c1), \ - _dyn = y2-y1, \ - _dyr = y2-y0, \ - _dyl = y1-y0, \ - _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \ - _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \ - _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \ - _dcn-=_dyn?_dyn*(_dcn/_dyn):0, \ - _dcr-=_dyr?_dyr*(_dcr/_dyr):0, \ - _dcl-=_dyl?_dyl*(_dcl/_dyl):0, \ - cimg::min((int)(img)._height - y - 1,y2 - y)), \ - _errn = _dyn/2, _errcn = _errn, \ - _errr = _dyr/2, _errcr = _errr, \ - _errl = _dyl/2, _errcl = _errl, \ - _rxn = _dyn?(x2 - x1)/_dyn:0, \ - _rcn = _dyn?(c2 - c1)/_dyn:0, \ - _rxr = _dyr?(x2 - x0)/_dyr:0, \ - _rcr = _dyr?(c2 - c0)/_dyr:0, \ - _rxl = (y0!=y1 && y1>0)?(_dyl?(x1-x0)/_dyl:0): \ - (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), \ - _rcl = (y0!=y1 && y1>0)?(_dyl?(c1-c0)/_dyl:0): \ - (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcn ); \ - _counter>=0; --_counter, ++y, \ - xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \ - cr+=_rcr+((_errcr-=_dcr)<0?_errcr+=_dyr,_scr:0), \ - xl+=(y!=y1)?(cl+=_rcl+((_errcl-=_dcl)<0?(_errcl+=_dyl,_scl):0), \ - _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): \ - (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcl=_rcn, cl=c1, \ - _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1-xl)) - -#define _cimg_for_triangle3(img,xl,txl,tyl,xr,txr,tyr,y,x0,y0,tx0,ty0,x1,y1,tx1,ty1,x2,y2,tx2,ty2) \ - for (int y = y0<0?0:y0, \ - xr = y0>=0?x0:(x0 - y0*(x2 - x0)/(y2 - y0)), \ - txr = y0>=0?tx0:(tx0 - y0*(tx2 - tx0)/(y2 - y0)), \ - tyr = y0>=0?ty0:(ty0 - y0*(ty2 - ty0)/(y2 - y0)), \ - xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0 - y0*(x1 - x0)/(y1 - y0))):(x1 - y1*(x2 - x1)/(y2 - y1)), \ - txl = y1>=0?(y0>=0?(y0==y1?tx1:tx0):(tx0 - y0*(tx1 - tx0)/(y1 - y0))):(tx1 - y1*(tx2 - tx1)/(y2 - y1)), \ - tyl = y1>=0?(y0>=0?(y0==y1?ty1:ty0):(ty0 - y0*(ty1 - ty0)/(y1 - y0))):(ty1 - y1*(ty2 - ty1)/(y2 - y1)), \ - _sxn=1, _stxn=1, _styn=1, \ - _sxr=1, _stxr=1, _styr=1, \ - _sxl=1, _stxl=1, _styl=1, \ - _dxn = x2>x1?x2 - x1:(_sxn=-1,x1 - x2), \ - _dxr = x2>x0?x2 - x0:(_sxr=-1,x0 - x2), \ - _dxl = x1>x0?x1 - x0:(_sxl=-1,x0 - x1), \ - _dtxn = tx2>tx1?tx2 - tx1:(_stxn=-1,tx1 - tx2), \ - _dtxr = tx2>tx0?tx2 - tx0:(_stxr=-1,tx0 - tx2), \ - _dtxl = tx1>tx0?tx1 - tx0:(_stxl=-1,tx0 - tx1), \ - _dtyn = ty2>ty1?ty2 - ty1:(_styn=-1,ty1 - ty2), \ - _dtyr = ty2>ty0?ty2 - ty0:(_styr=-1,ty0 - ty2), \ - _dtyl = ty1>ty0?ty1 - ty0:(_styl=-1,ty0 - ty1), \ - _dyn = y2-y1, \ - _dyr = y2-y0, \ - _dyl = y1-y0, \ - _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \ - _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \ - _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \ - _dtxn-=_dyn?_dyn*(_dtxn/_dyn):0, \ - _dtxr-=_dyr?_dyr*(_dtxr/_dyr):0, \ - _dtxl-=_dyl?_dyl*(_dtxl/_dyl):0, \ - _dtyn-=_dyn?_dyn*(_dtyn/_dyn):0, \ - _dtyr-=_dyr?_dyr*(_dtyr/_dyr):0, \ - _dtyl-=_dyl?_dyl*(_dtyl/_dyl):0, \ - cimg::min((int)(img)._height - y - 1,y2 - y)), \ - _errn = _dyn/2, _errtxn = _errn, _errtyn = _errn, \ - _errr = _dyr/2, _errtxr = _errr, _errtyr = _errr, \ - _errl = _dyl/2, _errtxl = _errl, _errtyl = _errl, \ - _rxn = _dyn?(x2 - x1)/_dyn:0, \ - _rtxn = _dyn?(tx2 - tx1)/_dyn:0, \ - _rtyn = _dyn?(ty2 - ty1)/_dyn:0, \ - _rxr = _dyr?(x2 - x0)/_dyr:0, \ - _rtxr = _dyr?(tx2 - tx0)/_dyr:0, \ - _rtyr = _dyr?(ty2 - ty0)/_dyr:0, \ - _rxl = (y0!=y1 && y1>0)?(_dyl?(x1 - x0)/_dyl:0): \ - (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), \ - _rtxl = (y0!=y1 && y1>0)?(_dyl?(tx1 - tx0)/_dyl:0): \ - (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxn ), \ - _rtyl = (y0!=y1 && y1>0)?(_dyl?(ty1 - ty0)/_dyl:0): \ - (_errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyn ); \ - _counter>=0; --_counter, ++y, \ - xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \ - txr+=_rtxr+((_errtxr-=_dtxr)<0?_errtxr+=_dyr,_stxr:0), \ - tyr+=_rtyr+((_errtyr-=_dtyr)<0?_errtyr+=_dyr,_styr:0), \ - xl+=(y!=y1)?(txl+=_rtxl+((_errtxl-=_dtxl)<0?(_errtxl+=_dyl,_stxl):0), \ - tyl+=_rtyl+((_errtyl-=_dtyl)<0?(_errtyl+=_dyl,_styl):0), \ - _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): \ - (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxl=_rtxn, txl=tx1, \ - _errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyl=_rtyn, tyl=ty1,\ - _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1 - xl)) - -#define _cimg_for_triangle4(img,xl,cl,txl,tyl,xr,cr,txr,tyr,y,x0,y0,c0,tx0,ty0,x1,y1,c1,tx1,ty1,x2,y2,c2,tx2,ty2) \ - for (int y = y0<0?0:y0, \ - xr = y0>=0?x0:(x0 - y0*(x2 - x0)/(y2 - y0)), \ - cr = y0>=0?c0:(c0 - y0*(c2 - c0)/(y2 - y0)), \ - txr = y0>=0?tx0:(tx0 - y0*(tx2 - tx0)/(y2 - y0)), \ - tyr = y0>=0?ty0:(ty0 - y0*(ty2 - ty0)/(y2 - y0)), \ - xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0 - y0*(x1 - x0)/(y1 - y0))):(x1 - y1*(x2 - x1)/(y2 - y1)), \ - cl = y1>=0?(y0>=0?(y0==y1?c1:c0):(c0 - y0*(c1 - c0)/(y1 - y0))):(c1 - y1*(c2 - c1)/(y2 - y1)), \ - txl = y1>=0?(y0>=0?(y0==y1?tx1:tx0):(tx0 - y0*(tx1 - tx0)/(y1 - y0))):(tx1 - y1*(tx2 - tx1)/(y2 - y1)), \ - tyl = y1>=0?(y0>=0?(y0==y1?ty1:ty0):(ty0 - y0*(ty1 - ty0)/(y1 - y0))):(ty1 - y1*(ty2 - ty1)/(y2 - y1)), \ - _sxn=1, _scn=1, _stxn=1, _styn=1, \ - _sxr=1, _scr=1, _stxr=1, _styr=1, \ - _sxl=1, _scl=1, _stxl=1, _styl=1, \ - _dxn = x2>x1?x2 - x1:(_sxn=-1,x1 - x2), \ - _dxr = x2>x0?x2 - x0:(_sxr=-1,x0 - x2), \ - _dxl = x1>x0?x1 - x0:(_sxl=-1,x0 - x1), \ - _dcn = c2>c1?c2 - c1:(_scn=-1,c1 - c2), \ - _dcr = c2>c0?c2 - c0:(_scr=-1,c0 - c2), \ - _dcl = c1>c0?c1 - c0:(_scl=-1,c0 - c1), \ - _dtxn = tx2>tx1?tx2 - tx1:(_stxn=-1,tx1 - tx2), \ - _dtxr = tx2>tx0?tx2 - tx0:(_stxr=-1,tx0 - tx2), \ - _dtxl = tx1>tx0?tx1 - tx0:(_stxl=-1,tx0 - tx1), \ - _dtyn = ty2>ty1?ty2 - ty1:(_styn=-1,ty1 - ty2), \ - _dtyr = ty2>ty0?ty2 - ty0:(_styr=-1,ty0 - ty2), \ - _dtyl = ty1>ty0?ty1 - ty0:(_styl=-1,ty0 - ty1), \ - _dyn = y2 - y1, \ - _dyr = y2 - y0, \ - _dyl = y1 - y0, \ - _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \ - _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \ - _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \ - _dcn-=_dyn?_dyn*(_dcn/_dyn):0, \ - _dcr-=_dyr?_dyr*(_dcr/_dyr):0, \ - _dcl-=_dyl?_dyl*(_dcl/_dyl):0, \ - _dtxn-=_dyn?_dyn*(_dtxn/_dyn):0, \ - _dtxr-=_dyr?_dyr*(_dtxr/_dyr):0, \ - _dtxl-=_dyl?_dyl*(_dtxl/_dyl):0, \ - _dtyn-=_dyn?_dyn*(_dtyn/_dyn):0, \ - _dtyr-=_dyr?_dyr*(_dtyr/_dyr):0, \ - _dtyl-=_dyl?_dyl*(_dtyl/_dyl):0, \ - cimg::min((int)(img)._height - y - 1,y2 - y)), \ - _errn = _dyn/2, _errcn = _errn, _errtxn = _errn, _errtyn = _errn, \ - _errr = _dyr/2, _errcr = _errr, _errtxr = _errr, _errtyr = _errr, \ - _errl = _dyl/2, _errcl = _errl, _errtxl = _errl, _errtyl = _errl, \ - _rxn = _dyn?(x2 - x1)/_dyn:0, \ - _rcn = _dyn?(c2 - c1)/_dyn:0, \ - _rtxn = _dyn?(tx2 - tx1)/_dyn:0, \ - _rtyn = _dyn?(ty2 - ty1)/_dyn:0, \ - _rxr = _dyr?(x2 - x0)/_dyr:0, \ - _rcr = _dyr?(c2 - c0)/_dyr:0, \ - _rtxr = _dyr?(tx2 - tx0)/_dyr:0, \ - _rtyr = _dyr?(ty2 - ty0)/_dyr:0, \ - _rxl = (y0!=y1 && y1>0)?(_dyl?(x1 - x0)/_dyl:0): \ - (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), \ - _rcl = (y0!=y1 && y1>0)?(_dyl?(c1 - c0)/_dyl:0): \ - (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcn ), \ - _rtxl = (y0!=y1 && y1>0)?(_dyl?(tx1 - tx0)/_dyl:0): \ - (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxn ), \ - _rtyl = (y0!=y1 && y1>0)?(_dyl?(ty1 - ty0)/_dyl:0): \ - (_errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyn ); \ - _counter>=0; --_counter, ++y, \ - xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \ - cr+=_rcr+((_errcr-=_dcr)<0?_errcr+=_dyr,_scr:0), \ - txr+=_rtxr+((_errtxr-=_dtxr)<0?_errtxr+=_dyr,_stxr:0), \ - tyr+=_rtyr+((_errtyr-=_dtyr)<0?_errtyr+=_dyr,_styr:0), \ - xl+=(y!=y1)?(cl+=_rcl+((_errcl-=_dcl)<0?(_errcl+=_dyl,_scl):0), \ - txl+=_rtxl+((_errtxl-=_dtxl)<0?(_errtxl+=_dyl,_stxl):0), \ - tyl+=_rtyl+((_errtyl-=_dtyl)<0?(_errtyl+=_dyl,_styl):0), \ - _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): \ - (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcl=_rcn, cl=c1, \ - _errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxl=_rtxn, txl=tx1, \ - _errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyl=_rtyn, tyl=ty1, \ - _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1 - xl)) - -#define _cimg_for_triangle5(img,xl,txl,tyl,lxl,lyl,xr,txr,tyr,lxr,lyr,y,x0,y0,\ - tx0,ty0,lx0,ly0,x1,y1,tx1,ty1,lx1,ly1,x2,y2,tx2,ty2,lx2,ly2) \ - for (int y = y0<0?0:y0, \ - xr = y0>=0?x0:(x0 - y0*(x2 - x0)/(y2 - y0)), \ - txr = y0>=0?tx0:(tx0 - y0*(tx2 - tx0)/(y2 - y0)), \ - tyr = y0>=0?ty0:(ty0 - y0*(ty2 - ty0)/(y2 - y0)), \ - lxr = y0>=0?lx0:(lx0 - y0*(lx2 - lx0)/(y2 - y0)), \ - lyr = y0>=0?ly0:(ly0 - y0*(ly2 - ly0)/(y2 - y0)), \ - xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0 - y0*(x1 - x0)/(y1 - y0))):(x1 - y1*(x2 - x1)/(y2 - y1)), \ - txl = y1>=0?(y0>=0?(y0==y1?tx1:tx0):(tx0 - y0*(tx1 - tx0)/(y1 - y0))):(tx1 - y1*(tx2 - tx1)/(y2 - y1)), \ - tyl = y1>=0?(y0>=0?(y0==y1?ty1:ty0):(ty0 - y0*(ty1 - ty0)/(y1 - y0))):(ty1 - y1*(ty2 - ty1)/(y2 - y1)), \ - lxl = y1>=0?(y0>=0?(y0==y1?lx1:lx0):(lx0 - y0*(lx1 - lx0)/(y1 - y0))):(lx1 - y1*(lx2 - lx1)/(y2 - y1)), \ - lyl = y1>=0?(y0>=0?(y0==y1?ly1:ly0):(ly0 - y0*(ly1 - ly0)/(y1 - y0))):(ly1 - y1*(ly2 - ly1)/(y2 - y1)), \ - _sxn=1, _stxn=1, _styn=1, _slxn=1, _slyn=1, \ - _sxr=1, _stxr=1, _styr=1, _slxr=1, _slyr=1, \ - _sxl=1, _stxl=1, _styl=1, _slxl=1, _slyl=1, \ - _dxn = x2>x1?x2 - x1:(_sxn=-1,x1 - x2), _dyn = y2 - y1, \ - _dxr = x2>x0?x2 - x0:(_sxr=-1,x0 - x2), _dyr = y2 - y0, \ - _dxl = x1>x0?x1 - x0:(_sxl=-1,x0 - x1), _dyl = y1 - y0, \ - _dtxn = tx2>tx1?tx2 - tx1:(_stxn=-1,tx1 - tx2), \ - _dtxr = tx2>tx0?tx2 - tx0:(_stxr=-1,tx0 - tx2), \ - _dtxl = tx1>tx0?tx1 - tx0:(_stxl=-1,tx0 - tx1), \ - _dtyn = ty2>ty1?ty2 - ty1:(_styn=-1,ty1 - ty2), \ - _dtyr = ty2>ty0?ty2 - ty0:(_styr=-1,ty0 - ty2), \ - _dtyl = ty1>ty0?ty1 - ty0:(_styl=-1,ty0 - ty1), \ - _dlxn = lx2>lx1?lx2 - lx1:(_slxn=-1,lx1 - lx2), \ - _dlxr = lx2>lx0?lx2 - lx0:(_slxr=-1,lx0 - lx2), \ - _dlxl = lx1>lx0?lx1 - lx0:(_slxl=-1,lx0 - lx1), \ - _dlyn = ly2>ly1?ly2 - ly1:(_slyn=-1,ly1 - ly2), \ - _dlyr = ly2>ly0?ly2 - ly0:(_slyr=-1,ly0 - ly2), \ - _dlyl = ly1>ly0?ly1 - ly0:(_slyl=-1,ly0 - ly1), \ - _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \ - _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \ - _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \ - _dtxn-=_dyn?_dyn*(_dtxn/_dyn):0, \ - _dtxr-=_dyr?_dyr*(_dtxr/_dyr):0, \ - _dtxl-=_dyl?_dyl*(_dtxl/_dyl):0, \ - _dtyn-=_dyn?_dyn*(_dtyn/_dyn):0, \ - _dtyr-=_dyr?_dyr*(_dtyr/_dyr):0, \ - _dtyl-=_dyl?_dyl*(_dtyl/_dyl):0, \ - _dlxn-=_dyn?_dyn*(_dlxn/_dyn):0, \ - _dlxr-=_dyr?_dyr*(_dlxr/_dyr):0, \ - _dlxl-=_dyl?_dyl*(_dlxl/_dyl):0, \ - _dlyn-=_dyn?_dyn*(_dlyn/_dyn):0, \ - _dlyr-=_dyr?_dyr*(_dlyr/_dyr):0, \ - _dlyl-=_dyl?_dyl*(_dlyl/_dyl):0, \ - cimg::min((int)(img)._height - y - 1,y2 - y)), \ - _errn = _dyn/2, _errtxn = _errn, _errtyn = _errn, _errlxn = _errn, _errlyn = _errn, \ - _errr = _dyr/2, _errtxr = _errr, _errtyr = _errr, _errlxr = _errr, _errlyr = _errr, \ - _errl = _dyl/2, _errtxl = _errl, _errtyl = _errl, _errlxl = _errl, _errlyl = _errl, \ - _rxn = _dyn?(x2 - x1)/_dyn:0, \ - _rtxn = _dyn?(tx2 - tx1)/_dyn:0, \ - _rtyn = _dyn?(ty2 - ty1)/_dyn:0, \ - _rlxn = _dyn?(lx2 - lx1)/_dyn:0, \ - _rlyn = _dyn?(ly2 - ly1)/_dyn:0, \ - _rxr = _dyr?(x2 - x0)/_dyr:0, \ - _rtxr = _dyr?(tx2 - tx0)/_dyr:0, \ - _rtyr = _dyr?(ty2 - ty0)/_dyr:0, \ - _rlxr = _dyr?(lx2 - lx0)/_dyr:0, \ - _rlyr = _dyr?(ly2 - ly0)/_dyr:0, \ - _rxl = (y0!=y1 && y1>0)?(_dyl?(x1 - x0)/_dyl:0): \ - (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), \ - _rtxl = (y0!=y1 && y1>0)?(_dyl?(tx1 - tx0)/_dyl:0): \ - (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxn ), \ - _rtyl = (y0!=y1 && y1>0)?(_dyl?(ty1 - ty0)/_dyl:0): \ - (_errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyn ), \ - _rlxl = (y0!=y1 && y1>0)?(_dyl?(lx1 - lx0)/_dyl:0): \ - (_errlxl=_errlxn, _dlxl=_dlxn, _dyl=_dyn, _slxl=_slxn, _rlxn ), \ - _rlyl = (y0!=y1 && y1>0)?(_dyl?(ly1 - ly0)/_dyl:0): \ - (_errlyl=_errlyn, _dlyl=_dlyn, _dyl=_dyn, _slyl=_slyn, _rlyn ); \ - _counter>=0; --_counter, ++y, \ - xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \ - txr+=_rtxr+((_errtxr-=_dtxr)<0?_errtxr+=_dyr,_stxr:0), \ - tyr+=_rtyr+((_errtyr-=_dtyr)<0?_errtyr+=_dyr,_styr:0), \ - lxr+=_rlxr+((_errlxr-=_dlxr)<0?_errlxr+=_dyr,_slxr:0), \ - lyr+=_rlyr+((_errlyr-=_dlyr)<0?_errlyr+=_dyr,_slyr:0), \ - xl+=(y!=y1)?(txl+=_rtxl+((_errtxl-=_dtxl)<0?(_errtxl+=_dyl,_stxl):0), \ - tyl+=_rtyl+((_errtyl-=_dtyl)<0?(_errtyl+=_dyl,_styl):0), \ - lxl+=_rlxl+((_errlxl-=_dlxl)<0?(_errlxl+=_dyl,_slxl):0), \ - lyl+=_rlyl+((_errlyl-=_dlyl)<0?(_errlyl+=_dyl,_slyl):0), \ - _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): \ - (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxl=_rtxn, txl=tx1, \ - _errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyl=_rtyn, tyl=ty1, \ - _errlxl=_errlxn, _dlxl=_dlxn, _dyl=_dyn, _slxl=_slxn, _rlxl=_rlxn, lxl=lx1, \ - _errlyl=_errlyn, _dlyl=_dlyn, _dyl=_dyn, _slyl=_slyn, _rlyl=_rlyn, lyl=ly1, \ - _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1 - xl)) - - // [internal] Draw a filled triangle. - template - CImg& _draw_triangle(const int x0, const int y0, - const int x1, const int y1, - const int x2, const int y2, - const tc *const color, const float opacity, - const float brightness) { - cimg_init_scanline(color,opacity); - const float nbrightness = brightness<0?0:(brightness>2?2:brightness); - int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2; - if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1); - if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2); - if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2); - if (ny0=0) { - if ((nx1 - nx0)*(ny2 - ny0) - (nx2 - nx0)*(ny1 - ny0)<0) - _cimg_for_triangle1(*this,xl,xr,y,nx0,ny0,nx1,ny1,nx2,ny2) - cimg_draw_scanline(xl,xr,y,color,opacity,nbrightness); - else - _cimg_for_triangle1(*this,xl,xr,y,nx0,ny0,nx1,ny1,nx2,ny2) - cimg_draw_scanline(xr,xl,y,color,opacity,nbrightness); - } - return *this; - } - - //! Draw a filled 2d triangle. - /** - \param x0 X-coordinate of the first vertex. - \param y0 Y-coordinate of the first vertex. - \param x1 X-coordinate of the second vertex. - \param y1 Y-coordinate of the second vertex. - \param x2 X-coordinate of the third vertex. - \param y2 Y-coordinate of the third vertex. - \param color Pointer to \c spectrum() consecutive values of type \c T, defining the drawing color. - \param opacity Drawing opacity. - **/ - template - CImg& draw_triangle(const int x0, const int y0, - const int x1, const int y1, - const int x2, const int y2, - const tc *const color, const float opacity=1) { - if (is_empty()) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Specified color is (null).", - cimg_instance); - _draw_triangle(x0,y0,x1,y1,x2,y2,color,opacity,1); - return *this; - } - - //! Draw a outlined 2d triangle. - /** - \param x0 X-coordinate of the first vertex. - \param y0 Y-coordinate of the first vertex. - \param x1 X-coordinate of the second vertex. - \param y1 Y-coordinate of the second vertex. - \param x2 X-coordinate of the third vertex. - \param y2 Y-coordinate of the third vertex. - \param color Pointer to \c spectrum() consecutive values of type \c T, defining the drawing color. - \param opacity Drawing opacity. - \param pattern An integer whose bits describe the outline pattern. - **/ - template - CImg& draw_triangle(const int x0, const int y0, - const int x1, const int y1, - const int x2, const int y2, - const tc *const color, const float opacity, - const unsigned int pattern) { - if (is_empty()) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Specified color is (null).", - cimg_instance); - draw_line(x0,y0,x1,y1,color,opacity,pattern,true). - draw_line(x1,y1,x2,y2,color,opacity,pattern,false). - draw_line(x2,y2,x0,y0,color,opacity,pattern,false); - return *this; - } - - //! Draw a filled 2d triangle, with z-buffering. - /** - \param zbuffer Z-buffer image. - \param x0 X-coordinate of the first vertex. - \param y0 Y-coordinate of the first vertex. - \param z0 Z-coordinate of the first vertex. - \param x1 X-coordinate of the second vertex. - \param y1 Y-coordinate of the second vertex. - \param z1 Z-coordinate of the second vertex. - \param x2 X-coordinate of the third vertex. - \param y2 Y-coordinate of the third vertex. - \param z2 Z-coordinate of the third vertex. - \param color Pointer to \c spectrum() consecutive values of type \c T, defining the drawing color. - \param opacity Drawing opacity. - \param brightness Brightness factor. - **/ - template - CImg& draw_triangle(CImg& zbuffer, - const int x0, const int y0, const float z0, - const int x1, const int y1, const float z1, - const int x2, const int y2, const float z2, - const tc *const color, const float opacity=1, - const float brightness=1) { - typedef typename cimg::superset::type tzfloat; - if (is_empty() || z0<=0 || z1<=0 || z2<=0) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Specified color is (null).", - cimg_instance); - if (!is_sameXY(zbuffer)) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have " - "different dimensions.", - cimg_instance, - zbuffer._width,zbuffer._height,zbuffer._depth,zbuffer._spectrum,zbuffer._data); - static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); - const float - nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0), - nbrightness = brightness<0?0:(brightness>2?2:brightness); - const longT whd = (longT)width()*height()*depth(), offx = spectrum()*whd; - int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2; - tzfloat nz0 = 1/(tzfloat)z0, nz1 = 1/(tzfloat)z1, nz2 = 1/(tzfloat)z2; - if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1); - if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,nz0,nz2); - if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,nz1,nz2); - if (ny0>=height() || ny2<0) return *this; - tzfloat - pzl = (nz1 - nz0)/(ny1 - ny0), - pzr = (nz2 - nz0)/(ny2 - ny0), - pzn = (nz2 - nz1)/(ny2 - ny1), - zr = ny0>=0?nz0:(nz0 - ny0*(nz2 - nz0)/(ny2 - ny0)), - zl = ny1>=0?(ny0>=0?nz0:(nz0 - ny0*(nz1 - nz0)/(ny1 - ny0))):(pzl=pzn,(nz1 - ny1*(nz2 - nz1)/(ny2 - ny1))); - _cimg_for_triangle1(*this,xleft0,xright0,y,nx0,ny0,nx1,ny1,nx2,ny2) { - if (y==ny1) { zl = nz1; pzl = pzn; } - int xleft = xleft0, xright = xright0; - tzfloat zleft = zl, zright = zr; - if (xright=width() - 1) xright = width() - 1; - T* ptrd = data(xleft,y,0,0); - tz *ptrz = xleft<=xright?zbuffer.data(xleft,y):0; - if (opacity>=1) { - if (nbrightness==1) for (int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tc *col = color; cimg_forC(*this,c) { *ptrd = (T)*(col++); ptrd+=whd; } - ptrd-=offx; - } - zleft+=pentez; - } else if (nbrightness<1) for (int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tc *col = color; cimg_forC(*this,c) { *ptrd = (T)(nbrightness*(*col++)); ptrd+=whd; } - ptrd-=offx; - } - zleft+=pentez; - } else for (int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tc *col = color; - cimg_forC(*this,c) { *ptrd = (T)((2 - nbrightness)**(col++) + (nbrightness - 1)*maxval); ptrd+=whd; } - ptrd-=offx; - } - zleft+=pentez; - } - } else { - if (nbrightness==1) for (int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tc *col = color; cimg_forC(*this,c) { *ptrd = (T)(nopacity**(col++) + *ptrd*copacity); ptrd+=whd; } - ptrd-=offx; - } - zleft+=pentez; - } else if (nbrightness<1) for (int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tc *col = color; - cimg_forC(*this,c) { *ptrd = (T)(nopacity*nbrightness**(col++) + *ptrd*copacity); ptrd+=whd; } - ptrd-=offx; - } - zleft+=pentez; - } else for (int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tc *col = color; - cimg_forC(*this,c) { - const T val = (T)((2 - nbrightness)**(col++) + (nbrightness - 1)*maxval); - *ptrd = (T)(nopacity*val + *ptrd*copacity); - ptrd+=whd; - } - ptrd-=offx; - } - zleft+=pentez; - } - } - zr+=pzr; zl+=pzl; - } - return *this; - } - - //! Draw a Gouraud-shaded 2d triangle. - /** - \param x0 X-coordinate of the first vertex in the image instance. - \param y0 Y-coordinate of the first vertex in the image instance. - \param x1 X-coordinate of the second vertex in the image instance. - \param y1 Y-coordinate of the second vertex in the image instance. - \param x2 X-coordinate of the third vertex in the image instance. - \param y2 Y-coordinate of the third vertex in the image instance. - \param color Pointer to \c spectrum() consecutive values, defining the drawing color. - \param brightness0 Brightness factor of the first vertex (in [0,2]). - \param brightness1 brightness factor of the second vertex (in [0,2]). - \param brightness2 brightness factor of the third vertex (in [0,2]). - \param opacity Drawing opacity. - **/ - template - CImg& draw_triangle(const int x0, const int y0, - const int x1, const int y1, - const int x2, const int y2, - const tc *const color, - const float brightness0, - const float brightness1, - const float brightness2, - const float opacity=1) { - if (is_empty()) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Specified color is (null).", - cimg_instance); - static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - const longT whd = (longT)width()*height()*depth(), offx = spectrum()*whd - 1; - int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2, - nc0 = (int)((brightness0<0.0f?0.0f:(brightness0>2.0f?2.0f:brightness0))*256.0f), - nc1 = (int)((brightness1<0.0f?0.0f:(brightness1>2.0f?2.0f:brightness1))*256.0f), - nc2 = (int)((brightness2<0.0f?0.0f:(brightness2>2.0f?2.0f:brightness2))*256.0f); - if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,nc0,nc1); - if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,nc0,nc2); - if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,nc1,nc2); - if (ny0>=height() || ny2<0) return *this; - _cimg_for_triangle2(*this,xleft0,cleft0,xright0,cright0,y,nx0,ny0,nc0,nx1,ny1,nc1,nx2,ny2,nc2) { - int xleft = xleft0, xright = xright0, cleft = cleft0, cright = cright0; - if (xrightcleft?cright - cleft:cleft - cright, - rc = dx?(cright - cleft)/dx:0, - sc = cright>cleft?1:-1, - ndc = dc - (dx?dx*(dc/dx):0); - int errc = dx>>1; - if (xleft<0 && dx) cleft-=xleft*(cright - cleft)/dx; - if (xleft<0) xleft = 0; - if (xright>=width() - 1) xright = width() - 1; - T* ptrd = data(xleft,y); - if (opacity>=1) for (int x = xleft; x<=xright; ++x) { - const tc *col = color; - cimg_forC(*this,c) { - *ptrd = (T)(cleft<256?cleft**(col++)/256:((512 - cleft)**(col++)+(cleft - 256)*maxval)/256); - ptrd+=whd; - } - ptrd-=offx; - cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0); - } else for (int x = xleft; x<=xright; ++x) { - const tc *col = color; - cimg_forC(*this,c) { - const T val = (T)(cleft<256?cleft**(col++)/256:((512 - cleft)**(col++)+(cleft - 256)*maxval)/256); - *ptrd = (T)(nopacity*val + *ptrd*copacity); - ptrd+=whd; - } - ptrd-=offx; - cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0); - } - } - return *this; - } - - //! Draw a Gouraud-shaded 2d triangle, with z-buffering \overloading. - template - CImg& draw_triangle(CImg& zbuffer, - const int x0, const int y0, const float z0, - const int x1, const int y1, const float z1, - const int x2, const int y2, const float z2, - const tc *const color, - const float brightness0, - const float brightness1, - const float brightness2, - const float opacity=1) { - typedef typename cimg::superset::type tzfloat; - if (is_empty() || z0<=0 || z1<=0 || z2<=0) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Specified color is (null).", - cimg_instance); - if (!is_sameXY(zbuffer)) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have " - "different dimensions.", - cimg_instance, - zbuffer._width,zbuffer._height,zbuffer._depth,zbuffer._spectrum,zbuffer._data); - static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - const longT whd = (longT)width()*height()*depth(), offx = spectrum()*whd; - int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2, - nc0 = (int)((brightness0<0.0f?0.0f:(brightness0>2.0f?2.0f:brightness0))*256.0f), - nc1 = (int)((brightness1<0.0f?0.0f:(brightness1>2.0f?2.0f:brightness1))*256.0f), - nc2 = (int)((brightness2<0.0f?0.0f:(brightness2>2.0f?2.0f:brightness2))*256.0f); - tzfloat nz0 = 1/(tzfloat)z0, nz1 = 1/(tzfloat)z1, nz2 = 1/(tzfloat)z2; - if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1,nc0,nc1); - if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,nz0,nz2,nc0,nc2); - if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,nz1,nz2,nc1,nc2); - if (ny0>=height() || ny2<0) return *this; - tzfloat - pzl = (nz1 - nz0)/(ny1 - ny0), - pzr = (nz2 - nz0)/(ny2 - ny0), - pzn = (nz2 - nz1)/(ny2 - ny1), - zr = ny0>=0?nz0:(nz0 - ny0*(nz2 - nz0)/(ny2 - ny0)), - zl = ny1>=0?(ny0>=0?nz0:(nz0 - ny0*(nz1 - nz0)/(ny1 - ny0))):(pzl=pzn,(nz1 - ny1*(nz2 - nz1)/(ny2 - ny1))); - _cimg_for_triangle2(*this,xleft0,cleft0,xright0,cright0,y,nx0,ny0,nc0,nx1,ny1,nc1,nx2,ny2,nc2) { - if (y==ny1) { zl = nz1; pzl = pzn; } - int xleft = xleft0, xright = xright0, cleft = cleft0, cright = cright0; - tzfloat zleft = zl, zright = zr; - if (xrightcleft?cright - cleft:cleft - cright, - rc = dx?(cright - cleft)/dx:0, - sc = cright>cleft?1:-1, - ndc = dc - (dx?dx*(dc/dx):0); - const tzfloat pentez = (zright - zleft)/dx; - int errc = dx>>1; - if (xleft<0 && dx) { - cleft-=xleft*(cright - cleft)/dx; - zleft-=xleft*(zright - zleft)/dx; - } - if (xleft<0) xleft = 0; - if (xright>=width() - 1) xright = width() - 1; - T *ptrd = data(xleft,y); - tz *ptrz = xleft<=xright?zbuffer.data(xleft,y):0; - if (opacity>=1) for (int x = xleft; x<=xright; ++x, ++ptrd, ++ptrz) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tc *col = color; - cimg_forC(*this,c) { - *ptrd = (T)(cleft<256?cleft**(col++)/256:((512 - cleft)**(col++)+(cleft - 256)*maxval)/256); - ptrd+=whd; - } - ptrd-=offx; - } - zleft+=pentez; - cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0); - } else for (int x = xleft; x<=xright; ++x, ++ptrd, ++ptrz) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tc *col = color; - cimg_forC(*this,c) { - const T val = (T)(cleft<256?cleft**(col++)/256:((512 - cleft)**(col++)+(cleft - 256)*maxval)/256); - *ptrd = (T)(nopacity*val + *ptrd*copacity); - ptrd+=whd; - } - ptrd-=offx; - } - zleft+=pentez; - cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0); - } - zr+=pzr; zl+=pzl; - } - return *this; - } - - //! Draw a color-interpolated 2d triangle. - /** - \param x0 X-coordinate of the first vertex in the image instance. - \param y0 Y-coordinate of the first vertex in the image instance. - \param x1 X-coordinate of the second vertex in the image instance. - \param y1 Y-coordinate of the second vertex in the image instance. - \param x2 X-coordinate of the third vertex in the image instance. - \param y2 Y-coordinate of the third vertex in the image instance. - \param color1 Pointer to \c spectrum() consecutive values of type \c T, defining the color of the first vertex. - \param color2 Pointer to \c spectrum() consecutive values of type \c T, defining the color of the seconf vertex. - \param color3 Pointer to \c spectrum() consecutive values of type \c T, defining the color of the third vertex. - \param opacity Drawing opacity. - **/ - template - CImg& draw_triangle(const int x0, const int y0, - const int x1, const int y1, - const int x2, const int y2, - const tc1 *const color1, - const tc2 *const color2, - const tc3 *const color3, - const float opacity=1) { - const unsigned char one = 1; - cimg_forC(*this,c) - get_shared_channel(c).draw_triangle(x0,y0,x1,y1,x2,y2,&one,color1[c],color2[c],color3[c],opacity); - return *this; - } - - //! Draw a textured 2d triangle. - /** - \param x0 X-coordinate of the first vertex in the image instance. - \param y0 Y-coordinate of the first vertex in the image instance. - \param x1 X-coordinate of the second vertex in the image instance. - \param y1 Y-coordinate of the second vertex in the image instance. - \param x2 X-coordinate of the third vertex in the image instance. - \param y2 Y-coordinate of the third vertex in the image instance. - \param texture Texture image used to fill the triangle. - \param tx0 X-coordinate of the first vertex in the texture image. - \param ty0 Y-coordinate of the first vertex in the texture image. - \param tx1 X-coordinate of the second vertex in the texture image. - \param ty1 Y-coordinate of the second vertex in the texture image. - \param tx2 X-coordinate of the third vertex in the texture image. - \param ty2 Y-coordinate of the third vertex in the texture image. - \param opacity Drawing opacity. - \param brightness Brightness factor of the drawing (in [0,2]). - **/ - template - CImg& draw_triangle(const int x0, const int y0, - const int x1, const int y1, - const int x2, const int y2, - const CImg& texture, - const int tx0, const int ty0, - const int tx1, const int ty1, - const int tx2, const int ty2, - const float opacity=1, - const float brightness=1) { - if (is_empty()) return *this; - if (texture._depth>1 || texture._spectrum<_spectrum) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).", - cimg_instance, - texture._width,texture._height,texture._depth,texture._spectrum,texture._data); - if (is_overlapped(texture)) - return draw_triangle(x0,y0,x1,y1,x2,y2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,opacity,brightness); - static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); - const float - nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0), - nbrightness = brightness<0?0:(brightness>2?2:brightness); - const ulongT - whd = (ulongT)_width*_height*_depth, - twh = (ulongT)texture._width*texture._height, - offx = _spectrum*whd - 1; - int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2, - ntx0 = tx0, nty0 = ty0, ntx1 = tx1, nty1 = ty1, ntx2 = tx2, nty2 = ty2; - if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1); - if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2); - if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2); - if (ny0>=height() || ny2<0) return *this; - _cimg_for_triangle3(*this,xleft0,txleft0,tyleft0,xright0,txright0,tyright0,y, - nx0,ny0,ntx0,nty0,nx1,ny1,ntx1,nty1,nx2,ny2,ntx2,nty2) { - int - xleft = xleft0, xright = xright0, - txleft = txleft0, txright = txright0, - tyleft = tyleft0, tyright = tyright0; - if (xrighttxleft?txright - txleft:txleft - txright, - dty = tyright>tyleft?tyright - tyleft:tyleft - tyright, - rtx = dx?(txright - txleft)/dx:0, - rty = dx?(tyright - tyleft)/dx:0, - stx = txright>txleft?1:-1, - sty = tyright>tyleft?1:-1, - ndtx = dtx - (dx?dx*(dtx/dx):0), - ndty = dty - (dx?dx*(dty/dx):0); - int errtx = dx>>1, errty = errtx; - if (xleft<0 && dx) { - txleft-=xleft*(txright - txleft)/dx; - tyleft-=xleft*(tyright - tyleft)/dx; - } - if (xleft<0) xleft = 0; - if (xright>=width() - 1) xright = width() - 1; - T* ptrd = data(xleft,y,0,0); - if (opacity>=1) { - if (nbrightness==1) for (int x = xleft; x<=xright; ++x) { - const tc *col = &texture._atXY(txleft,tyleft); - cimg_forC(*this,c) { - *ptrd = (T)*col; - ptrd+=whd; col+=twh; - } - ptrd-=offx; - txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); - tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); - } else if (nbrightness<1) for (int x = xleft; x<=xright; ++x) { - const tc *col = &texture._atXY(txleft,tyleft); - cimg_forC(*this,c) { - *ptrd = (T)(nbrightness**col); - ptrd+=whd; col+=twh; - } - ptrd-=offx; - txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); - tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); - } else for (int x = xleft; x<=xright; ++x) { - const tc *col = &texture._atXY(txleft,tyleft); - cimg_forC(*this,c) { - *ptrd = (T)((2 - nbrightness)**(col++) + (nbrightness - 1)*maxval); - ptrd+=whd; col+=twh; - } - ptrd-=offx; - txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); - tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); - } - } else { - if (nbrightness==1) for (int x = xleft; x<=xright; ++x) { - const tc *col = &texture._atXY(txleft,tyleft); - cimg_forC(*this,c) { - *ptrd = (T)(nopacity**col + *ptrd*copacity); - ptrd+=whd; col+=twh; - } - ptrd-=offx; - txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); - tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); - } else if (nbrightness<1) for (int x = xleft; x<=xright; ++x) { - const tc *col = &texture._atXY(txleft,tyleft); - cimg_forC(*this,c) { - *ptrd = (T)(nopacity*nbrightness**col + *ptrd*copacity); - ptrd+=whd; col+=twh; - } - ptrd-=offx; - txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); - tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); - } else for (int x = xleft; x<=xright; ++x) { - const tc *col = &texture._atXY(txleft,tyleft); - cimg_forC(*this,c) { - const T val = (T)((2 - nbrightness)**(col++) + (nbrightness - 1)*maxval); - *ptrd = (T)(nopacity*val + *ptrd*copacity); - ptrd+=whd; col+=twh; - } - ptrd-=offx; - txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); - tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); - } - } - } - return *this; - } - - //! Draw a 2d textured triangle, with perspective correction. - template - CImg& draw_triangle(const int x0, const int y0, const float z0, - const int x1, const int y1, const float z1, - const int x2, const int y2, const float z2, - const CImg& texture, - const int tx0, const int ty0, - const int tx1, const int ty1, - const int tx2, const int ty2, - const float opacity=1, - const float brightness=1) { - if (is_empty() || z0<=0 || z1<=0 || z2<=0) return *this; - if (texture._depth>1 || texture._spectrum<_spectrum) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).", - cimg_instance, - texture._width,texture._height,texture._depth,texture._spectrum,texture._data); - if (is_overlapped(texture)) - return draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,opacity,brightness); - static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); - const float - nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0), - nbrightness = brightness<0?0:(brightness>2?2:brightness); - const ulongT - whd = (ulongT)_width*_height*_depth, - twh = (ulongT)texture._width*texture._height, - offx = _spectrum*whd - 1; - int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2; - float - ntx0 = tx0/z0, nty0 = ty0/z0, - ntx1 = tx1/z1, nty1 = ty1/z1, - ntx2 = tx2/z2, nty2 = ty2/z2, - nz0 = 1/z0, nz1 = 1/z1, nz2 = 1/z2; - if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nz0,nz1); - if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nz0,nz2); - if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nz1,nz2); - if (ny0>=height() || ny2<0) return *this; - float - ptxl = (ntx1 - ntx0)/(ny1 - ny0), - ptxr = (ntx2 - ntx0)/(ny2 - ny0), - ptxn = (ntx2 - ntx1)/(ny2 - ny1), - ptyl = (nty1 - nty0)/(ny1 - ny0), - ptyr = (nty2 - nty0)/(ny2 - ny0), - ptyn = (nty2 - nty1)/(ny2 - ny1), - pzl = (nz1 - nz0)/(ny1 - ny0), - pzr = (nz2 - nz0)/(ny2 - ny0), - pzn = (nz2 - nz1)/(ny2 - ny1), - zr = ny0>=0?nz0:(nz0 - ny0*(nz2 - nz0)/(ny2 - ny0)), - txr = ny0>=0?ntx0:(ntx0 - ny0*(ntx2 - ntx0)/(ny2 - ny0)), - tyr = ny0>=0?nty0:(nty0 - ny0*(nty2 - nty0)/(ny2 - ny0)), - zl = ny1>=0?(ny0>=0?nz0:(nz0 - ny0*(nz1 - nz0)/(ny1 - ny0))):(pzl=pzn,(nz1 - ny1*(nz2 - nz1)/(ny2 - ny1))), - txl = ny1>=0?(ny0>=0?ntx0:(ntx0 - ny0*(ntx1 - ntx0)/(ny1 - ny0))): - (ptxl=ptxn,(ntx1 - ny1*(ntx2 - ntx1)/(ny2 - ny1))), - tyl = ny1>=0?(ny0>=0?nty0:(nty0 - ny0*(nty1 - nty0)/(ny1 - ny0))): - (ptyl=ptyn,(nty1 - ny1*(nty2 - nty1)/(ny2 - ny1))); - _cimg_for_triangle1(*this,xleft0,xright0,y,nx0,ny0,nx1,ny1,nx2,ny2) { - if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; } - int xleft = xleft0, xright = xright0; - float - zleft = zl, zright = zr, - txleft = txl, txright = txr, - tyleft = tyl, tyright = tyr; - if (xright=width() - 1) xright = width() - 1; - T* ptrd = data(xleft,y,0,0); - if (opacity>=1) { - if (nbrightness==1) for (int x = xleft; x<=xright; ++x) { - const float invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - cimg_forC(*this,c) { - *ptrd = (T)*col; - ptrd+=whd; col+=twh; - } - ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - } else if (nbrightness<1) for (int x=xleft; x<=xright; ++x) { - const float invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - cimg_forC(*this,c) { - *ptrd = (T)(nbrightness**col); - ptrd+=whd; col+=twh; - } - ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - } else for (int x = xleft; x<=xright; ++x) { - const float invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - cimg_forC(*this,c) { - *ptrd = (T)((2 - nbrightness)**col + (nbrightness - 1)*maxval); - ptrd+=whd; col+=twh; - } - ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - } - } else { - if (nbrightness==1) for (int x = xleft; x<=xright; ++x) { - const float invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - cimg_forC(*this,c) { - *ptrd = (T)(nopacity**col + *ptrd*copacity); - ptrd+=whd; col+=twh; - } - ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - } else if (nbrightness<1) for (int x = xleft; x<=xright; ++x) { - const float invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - cimg_forC(*this,c) { - *ptrd = (T)(nopacity*nbrightness**col + *ptrd*copacity); - ptrd+=whd; col+=twh; - } - ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - } else for (int x = xleft; x<=xright; ++x) { - const float invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - cimg_forC(*this,c) { - const T val = (T)((2 - nbrightness)**col + (nbrightness - 1)*maxval); - *ptrd = (T)(nopacity*val + *ptrd*copacity); - ptrd+=whd; col+=twh; - } - ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - } - } - zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl; - } - return *this; - } - - //! Draw a textured 2d triangle, with perspective correction and z-buffering. - template - CImg& draw_triangle(CImg& zbuffer, - const int x0, const int y0, const float z0, - const int x1, const int y1, const float z1, - const int x2, const int y2, const float z2, - const CImg& texture, - const int tx0, const int ty0, - const int tx1, const int ty1, - const int tx2, const int ty2, - const float opacity=1, - const float brightness=1) { - typedef typename cimg::superset::type tzfloat; - if (is_empty() || z0<=0 || z1<=0 || z2<=0) return *this; - if (!is_sameXY(zbuffer)) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have " - "different dimensions.", - cimg_instance, - zbuffer._width,zbuffer._height,zbuffer._depth,zbuffer._spectrum,zbuffer._data); - - if (texture._depth>1 || texture._spectrum<_spectrum) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).", - cimg_instance, - texture._width,texture._height,texture._depth,texture._spectrum,texture._data); - if (is_overlapped(texture)) - return draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,opacity,brightness); - static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); - const float - nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0), - nbrightness = brightness<0?0:(brightness>2?2:brightness); - const ulongT - whd = (ulongT)_width*_height*_depth, - twh = (ulongT)texture._width*texture._height, - offx = _spectrum*whd; - int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2; - float - ntx0 = tx0/z0, nty0 = ty0/z0, - ntx1 = tx1/z1, nty1 = ty1/z1, - ntx2 = tx2/z2, nty2 = ty2/z2; - tzfloat nz0 = 1/(tzfloat)z0, nz1 = 1/(tzfloat)z1, nz2 = 1/(tzfloat)z2; - if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nz0,nz1); - if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nz0,nz2); - if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nz1,nz2); - if (ny0>=height() || ny2<0) return *this; - float - ptxl = (ntx1 - ntx0)/(ny1 - ny0), - ptxr = (ntx2 - ntx0)/(ny2 - ny0), - ptxn = (ntx2 - ntx1)/(ny2 - ny1), - ptyl = (nty1 - nty0)/(ny1 - ny0), - ptyr = (nty2 - nty0)/(ny2 - ny0), - ptyn = (nty2 - nty1)/(ny2 - ny1), - txr = ny0>=0?ntx0:(ntx0 - ny0*(ntx2 - ntx0)/(ny2 - ny0)), - tyr = ny0>=0?nty0:(nty0 - ny0*(nty2 - nty0)/(ny2 - ny0)), - txl = ny1>=0?(ny0>=0?ntx0:(ntx0 - ny0*(ntx1 - ntx0)/(ny1 - ny0))): - (ptxl=ptxn,(ntx1 - ny1*(ntx2 - ntx1)/(ny2 - ny1))), - tyl = ny1>=0?(ny0>=0?nty0:(nty0 - ny0*(nty1 - nty0)/(ny1 - ny0))): - (ptyl=ptyn,(nty1 - ny1*(nty2 - nty1)/(ny2 - ny1))); - tzfloat - pzl = (nz1 - nz0)/(ny1 - ny0), - pzr = (nz2 - nz0)/(ny2 - ny0), - pzn = (nz2 - nz1)/(ny2 - ny1), - zr = ny0>=0?nz0:(nz0 - ny0*(nz2 - nz0)/(ny2 - ny0)), - zl = ny1>=0?(ny0>=0?nz0:(nz0 - ny0*(nz1 - nz0)/(ny1 - ny0))):(pzl=pzn,(nz1 - ny1*(nz2 - nz1)/(ny2 - ny1))); - _cimg_for_triangle1(*this,xleft0,xright0,y,nx0,ny0,nx1,ny1,nx2,ny2) { - if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; } - int xleft = xleft0, xright = xright0; - float txleft = txl, txright = txr, tyleft = tyl, tyright = tyr; - tzfloat zleft = zl, zright = zr; - if (xright=width() - 1) xright = width() - 1; - T *ptrd = data(xleft,y,0,0); - tz *ptrz = zbuffer.data(xleft,y); - if (opacity>=1) { - if (nbrightness==1) for (int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tzfloat invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - cimg_forC(*this,c) { - *ptrd = (T)*col; - ptrd+=whd; col+=twh; - } - ptrd-=offx; - } - zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - } else if (nbrightness<1) for (int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tzfloat invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - cimg_forC(*this,c) { - *ptrd = (T)(nbrightness**col); - ptrd+=whd; col+=twh; - } - ptrd-=offx; - } - zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - } else for (int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tzfloat invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - cimg_forC(*this,c) { - *ptrd = (T)((2 - nbrightness)**col + (nbrightness - 1)*maxval); - ptrd+=whd; col+=twh; - } - ptrd-=offx; - } - zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - } - } else { - if (nbrightness==1) for (int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tzfloat invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - cimg_forC(*this,c) { - *ptrd = (T)(nopacity**col + *ptrd*copacity); - ptrd+=whd; col+=twh; - } - ptrd-=offx; - } - zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - } else if (nbrightness<1) for (int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tzfloat invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - cimg_forC(*this,c) { - *ptrd = (T)(nopacity*nbrightness**col + *ptrd*copacity); - ptrd+=whd; col+=twh; - } - ptrd-=offx; - } - zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - } else for (int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tzfloat invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - cimg_forC(*this,c) { - const T val = (T)((2 - nbrightness)**col + (nbrightness - 1)*maxval); - *ptrd = (T)(nopacity*val + *ptrd*copacity); - ptrd+=whd; col+=twh; - } - ptrd-=offx; - } - zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - } - } - zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl; - } - return *this; - } - - //! Draw a Phong-shaded 2d triangle. - /** - \param x0 X-coordinate of the first vertex in the image instance. - \param y0 Y-coordinate of the first vertex in the image instance. - \param x1 X-coordinate of the second vertex in the image instance. - \param y1 Y-coordinate of the second vertex in the image instance. - \param x2 X-coordinate of the third vertex in the image instance. - \param y2 Y-coordinate of the third vertex in the image instance. - \param color Pointer to \c spectrum() consecutive values, defining the drawing color. - \param light Light image. - \param lx0 X-coordinate of the first vertex in the light image. - \param ly0 Y-coordinate of the first vertex in the light image. - \param lx1 X-coordinate of the second vertex in the light image. - \param ly1 Y-coordinate of the second vertex in the light image. - \param lx2 X-coordinate of the third vertex in the light image. - \param ly2 Y-coordinate of the third vertex in the light image. - \param opacity Drawing opacity. - **/ - template - CImg& draw_triangle(const int x0, const int y0, - const int x1, const int y1, - const int x2, const int y2, - const tc *const color, - const CImg& light, - const int lx0, const int ly0, - const int lx1, const int ly1, - const int lx2, const int ly2, - const float opacity=1) { - if (is_empty()) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Specified color is (null).", - cimg_instance); - if (light._depth>1 || light._spectrum<_spectrum) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Invalid specified light texture (%u,%u,%u,%u,%p).", - cimg_instance,light._width,light._height,light._depth,light._spectrum,light._data); - if (is_overlapped(light)) return draw_triangle(x0,y0,x1,y1,x2,y2,color,+light,lx0,ly0,lx1,ly1,lx2,ly2,opacity); - static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2, - nlx0 = lx0, nly0 = ly0, nlx1 = lx1, nly1 = ly1, nlx2 = lx2, nly2 = ly2; - const ulongT - whd = (ulongT)_width*_height*_depth, - lwh = (ulongT)light._width*light._height, - offx = _spectrum*whd - 1; - if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,nlx0,nlx1,nly0,nly1); - if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,nlx0,nlx2,nly0,nly2); - if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,nlx1,nlx2,nly1,nly2); - if (ny0>=height() || ny2<0) return *this; - _cimg_for_triangle3(*this,xleft0,lxleft0,lyleft0,xright0,lxright0,lyright0,y, - nx0,ny0,nlx0,nly0,nx1,ny1,nlx1,nly1,nx2,ny2,nlx2,nly2) { - int - xleft = xleft0, xright = xright0, - lxleft = lxleft0, lxright = lxright0, - lyleft = lyleft0, lyright = lyright0; - if (xrightlxleft?lxright - lxleft:lxleft - lxright, - dly = lyright>lyleft?lyright - lyleft:lyleft - lyright, - rlx = dx?(lxright - lxleft)/dx:0, - rly = dx?(lyright - lyleft)/dx:0, - slx = lxright>lxleft?1:-1, - sly = lyright>lyleft?1:-1, - ndlx = dlx - (dx?dx*(dlx/dx):0), - ndly = dly - (dx?dx*(dly/dx):0); - int errlx = dx>>1, errly = errlx; - if (xleft<0 && dx) { - lxleft-=xleft*(lxright - lxleft)/dx; - lyleft-=xleft*(lyright - lyleft)/dx; - } - if (xleft<0) xleft = 0; - if (xright>=width() - 1) xright = width() - 1; - T* ptrd = data(xleft,y,0,0); - if (opacity>=1) for (int x = xleft; x<=xright; ++x) { - const tc *col = color; - const tl *lig = &light._atXY(lxleft,lyleft); - cimg_forC(*this,c) { - const tl l = *lig; - *ptrd = (T)(l<1?l**(col++):((2 - l)**(col++) + (l - 1)*maxval)); - ptrd+=whd; lig+=lwh; - } - ptrd-=offx; - lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0); - lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0); - } else for (int x = xleft; x<=xright; ++x) { - const tc *col = color; - const tl *lig = &light._atXY(lxleft,lyleft); - cimg_forC(*this,c) { - const tl l = *lig; - const T val = (T)(l<1?l**(col++):((2 - l)**(col++) + (l - 1)*maxval)); - *ptrd = (T)(nopacity*val + *ptrd*copacity); - ptrd+=whd; lig+=lwh; - } - ptrd-=offx; - lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0); - lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0); - } - } - return *this; - } - - //! Draw a Phong-shaded 2d triangle, with z-buffering. - template - CImg& draw_triangle(CImg& zbuffer, - const int x0, const int y0, const float z0, - const int x1, const int y1, const float z1, - const int x2, const int y2, const float z2, - const tc *const color, - const CImg& light, - const int lx0, const int ly0, - const int lx1, const int ly1, - const int lx2, const int ly2, - const float opacity=1) { - typedef typename cimg::superset::type tzfloat; - if (is_empty() || z0<=0 || z1<=0 || z2<=0) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Specified color is (null).", - cimg_instance); - if (light._depth>1 || light._spectrum<_spectrum) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Invalid specified light texture (%u,%u,%u,%u,%p).", - cimg_instance,light._width,light._height,light._depth,light._spectrum,light._data); - if (!is_sameXY(zbuffer)) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have " - "different dimensions.", - cimg_instance, - zbuffer._width,zbuffer._height,zbuffer._depth,zbuffer._spectrum,zbuffer._data); - if (is_overlapped(light)) return draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,color, - +light,lx0,ly0,lx1,ly1,lx2,ly2,opacity); - static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - const ulongT - whd = (ulongT)_width*_height*_depth, - lwh = (ulongT)light._width*light._height, - offx = _spectrum*whd; - int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2, - nlx0 = lx0, nly0 = ly0, nlx1 = lx1, nly1 = ly1, nlx2 = lx2, nly2 = ly2; - tzfloat nz0 = 1/(tzfloat)z0, nz1 = 1/(tzfloat)z1, nz2 = 1/(tzfloat)z2; - if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,nlx0,nlx1,nly0,nly1,nz0,nz1); - if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,nlx0,nlx2,nly0,nly2,nz0,nz2); - if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,nlx1,nlx2,nly1,nly2,nz1,nz2); - if (ny0>=height() || ny2<0) return *this; - tzfloat - pzl = (nz1 - nz0)/(ny1 - ny0), - pzr = (nz2 - nz0)/(ny2 - ny0), - pzn = (nz2 - nz1)/(ny2 - ny1), - zr = ny0>=0?nz0:(nz0 - ny0*(nz2 - nz0)/(ny2 - ny0)), - zl = ny1>=0?(ny0>=0?nz0:(nz0 - ny0*(nz1 - nz0)/(ny1 - ny0))):(pzl=pzn,(nz1 - ny1*(nz2 - nz1)/(ny2 - ny1))); - _cimg_for_triangle3(*this,xleft0,lxleft0,lyleft0,xright0,lxright0,lyright0,y, - nx0,ny0,nlx0,nly0,nx1,ny1,nlx1,nly1,nx2,ny2,nlx2,nly2) { - if (y==ny1) { zl = nz1; pzl = pzn; } - int - xleft = xleft0, xright = xright0, - lxleft = lxleft0, lxright = lxright0, - lyleft = lyleft0, lyright = lyright0; - tzfloat zleft = zl, zright = zr; - if (xrightlxleft?lxright - lxleft:lxleft - lxright, - dly = lyright>lyleft?lyright - lyleft:lyleft - lyright, - rlx = dx?(lxright - lxleft)/dx:0, - rly = dx?(lyright - lyleft)/dx:0, - slx = lxright>lxleft?1:-1, - sly = lyright>lyleft?1:-1, - ndlx = dlx - (dx?dx*(dlx/dx):0), - ndly = dly - (dx?dx*(dly/dx):0); - const tzfloat pentez = (zright - zleft)/dx; - int errlx = dx>>1, errly = errlx; - if (xleft<0 && dx) { - zleft-=xleft*(zright - zleft)/dx; - lxleft-=xleft*(lxright - lxleft)/dx; - lyleft-=xleft*(lyright - lyleft)/dx; - } - if (xleft<0) xleft = 0; - if (xright>=width() - 1) xright = width() - 1; - T *ptrd = data(xleft,y,0,0); - tz *ptrz = xleft<=xright?zbuffer.data(xleft,y):0; - if (opacity>=1) for (int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tc *col = color; - const tl *lig = &light._atXY(lxleft,lyleft); - cimg_forC(*this,c) { - const tl l = *lig; - const tc cval = *(col++); - *ptrd = (T)(l<1?l*cval:(2 - l)*cval + (l - 1)*maxval); - ptrd+=whd; lig+=lwh; - } - ptrd-=offx; - } - zleft+=pentez; - lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0); - lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0); - } else for (int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tc *col = color; - const tl *lig = &light._atXY(lxleft,lyleft); - cimg_forC(*this,c) { - const tl l = *lig; - const tc cval = *(col++); - const T val = (T)(l<1?l*cval:(2 - l)*cval + (l - 1)*maxval); - *ptrd = (T)(nopacity*val + *ptrd*copacity); - ptrd+=whd; lig+=lwh; - } - ptrd-=offx; - } - zleft+=pentez; - lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0); - lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0); - } - zr+=pzr; zl+=pzl; - } - return *this; - } - - //! Draw a textured Gouraud-shaded 2d triangle. - /** - \param x0 X-coordinate of the first vertex in the image instance. - \param y0 Y-coordinate of the first vertex in the image instance. - \param x1 X-coordinate of the second vertex in the image instance. - \param y1 Y-coordinate of the second vertex in the image instance. - \param x2 X-coordinate of the third vertex in the image instance. - \param y2 Y-coordinate of the third vertex in the image instance. - \param texture Texture image used to fill the triangle. - \param tx0 X-coordinate of the first vertex in the texture image. - \param ty0 Y-coordinate of the first vertex in the texture image. - \param tx1 X-coordinate of the second vertex in the texture image. - \param ty1 Y-coordinate of the second vertex in the texture image. - \param tx2 X-coordinate of the third vertex in the texture image. - \param ty2 Y-coordinate of the third vertex in the texture image. - \param brightness0 Brightness factor of the first vertex. - \param brightness1 Brightness factor of the second vertex. - \param brightness2 Brightness factor of the third vertex. - \param opacity Drawing opacity. - **/ - template - CImg& draw_triangle(const int x0, const int y0, - const int x1, const int y1, - const int x2, const int y2, - const CImg& texture, - const int tx0, const int ty0, - const int tx1, const int ty1, - const int tx2, const int ty2, - const float brightness0, - const float brightness1, - const float brightness2, - const float opacity=1) { - if (is_empty()) return *this; - if (texture._depth>1 || texture._spectrum<_spectrum) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).", - cimg_instance, - texture._width,texture._height,texture._depth,texture._spectrum,texture._data); - if (is_overlapped(texture)) - return draw_triangle(x0,y0,x1,y1,x2,y2,+texture,tx0,ty0,tx1,ty1,tx2,ty2, - brightness0,brightness1,brightness2,opacity); - static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - const ulongT - whd = (ulongT)_width*_height*_depth, - twh = (ulongT)texture._width*texture._height, - offx = _spectrum*whd - 1; - int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2, - ntx0 = tx0, nty0 = ty0, ntx1 = tx1, nty1 = ty1, ntx2 = tx2, nty2 = ty2, - nc0 = (int)((brightness0<0.0f?0.0f:(brightness0>2.0f?2.0f:brightness0))*256.0f), - nc1 = (int)((brightness1<0.0f?0.0f:(brightness1>2.0f?2.0f:brightness1))*256.0f), - nc2 = (int)((brightness2<0.0f?0.0f:(brightness2>2.0f?2.0f:brightness2))*256.0f); - if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nc0,nc1); - if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nc0,nc2); - if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nc1,nc2); - if (ny0>=height() || ny2<0) return *this; - _cimg_for_triangle4(*this,xleft0,cleft0,txleft0,tyleft0,xright0,cright0,txright0,tyright0,y, - nx0,ny0,nc0,ntx0,nty0,nx1,ny1,nc1,ntx1,nty1,nx2,ny2,nc2,ntx2,nty2) { - int - xleft = xleft0, xright = xright0, - cleft = cleft0, cright = cright0, - txleft = txleft0, txright = txright0, - tyleft = tyleft0, tyright = tyright0; - if (xrightcleft?cright - cleft:cleft - cright, - dtx = txright>txleft?txright - txleft:txleft - txright, - dty = tyright>tyleft?tyright - tyleft:tyleft - tyright, - rc = dx?(cright - cleft)/dx:0, - rtx = dx?(txright - txleft)/dx:0, - rty = dx?(tyright - tyleft)/dx:0, - sc = cright>cleft?1:-1, - stx = txright>txleft?1:-1, - sty = tyright>tyleft?1:-1, - ndc = dc - (dx?dx*(dc/dx):0), - ndtx = dtx - (dx?dx*(dtx/dx):0), - ndty = dty - (dx?dx*(dty/dx):0); - int errc = dx>>1, errtx = errc, errty = errc; - if (xleft<0 && dx) { - cleft-=xleft*(cright - cleft)/dx; - txleft-=xleft*(txright - txleft)/dx; - tyleft-=xleft*(tyright - tyleft)/dx; - } - if (xleft<0) xleft = 0; - if (xright>=width() - 1) xright = width() - 1; - T* ptrd = data(xleft,y,0,0); - if (opacity>=1) for (int x = xleft; x<=xright; ++x) { - const tc *col = &texture._atXY(txleft,tyleft); - cimg_forC(*this,c) { - *ptrd = (T)(cleft<256?cleft**col/256:((512 - cleft)**col + (cleft - 256)*maxval)/256); - ptrd+=whd; col+=twh; - } - ptrd-=offx; - cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0); - txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); - tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); - } else for (int x = xleft; x<=xright; ++x) { - const tc *col = &texture._atXY(txleft,tyleft); - cimg_forC(*this,c) { - const T val = (T)(cleft<256?cleft**col/256:((512 - cleft)**col + (cleft - 256)*maxval)/256); - *ptrd = (T)(nopacity*val + *ptrd*copacity); - ptrd+=whd; col+=twh; - } - ptrd-=offx; - cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0); - txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); - tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); - } - } - return *this; - } - - //! Draw a textured Gouraud-shaded 2d triangle, with perspective correction \overloading. - template - CImg& draw_triangle(const int x0, const int y0, const float z0, - const int x1, const int y1, const float z1, - const int x2, const int y2, const float z2, - const CImg& texture, - const int tx0, const int ty0, - const int tx1, const int ty1, - const int tx2, const int ty2, - const float brightness0, - const float brightness1, - const float brightness2, - const float opacity=1) { - if (is_empty() || z0<=0 || z1<=0 || z2<=0) return *this; - if (texture._depth>1 || texture._spectrum<_spectrum) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).", - cimg_instance, - texture._width,texture._height,texture._depth,texture._spectrum,texture._data); - if (is_overlapped(texture)) return draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,+texture,tx0,ty0,tx1,ty1,tx2,ty2, - brightness0,brightness1,brightness2,opacity); - static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - const ulongT - whd = (ulongT)_width*_height*_depth, - twh = (ulongT)texture._width*texture._height, - offx = _spectrum*whd - 1; - int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2, - nc0 = (int)((brightness0<0.0f?0.0f:(brightness0>2.0f?2.0f:brightness0))*256.0f), - nc1 = (int)((brightness1<0.0f?0.0f:(brightness1>2.0f?2.0f:brightness1))*256.0f), - nc2 = (int)((brightness2<0.0f?0.0f:(brightness2>2.0f?2.0f:brightness2))*256.0f); - float - ntx0 = tx0/z0, nty0 = ty0/z0, - ntx1 = tx1/z1, nty1 = ty1/z1, - ntx2 = tx2/z2, nty2 = ty2/z2, - nz0 = 1/z0, nz1 = 1/z1, nz2 = 1/z2; - if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nz0,nz1,nc0,nc1); - if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nz0,nz2,nc0,nc2); - if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nz1,nz2,nc1,nc2); - if (ny0>=height() || ny2<0) return *this; - float - ptxl = (ntx1 - ntx0)/(ny1 - ny0), - ptxr = (ntx2 - ntx0)/(ny2 - ny0), - ptxn = (ntx2 - ntx1)/(ny2 - ny1), - ptyl = (nty1 - nty0)/(ny1 - ny0), - ptyr = (nty2 - nty0)/(ny2 - ny0), - ptyn = (nty2 - nty1)/(ny2 - ny1), - pzl = (nz1 - nz0)/(ny1 - ny0), - pzr = (nz2 - nz0)/(ny2 - ny0), - pzn = (nz2 - nz1)/(ny2 - ny1), - zr = ny0>=0?nz0:(nz0 - ny0*(nz2 - nz0)/(ny2 - ny0)), - txr = ny0>=0?ntx0:(ntx0 - ny0*(ntx2 - ntx0)/(ny2 - ny0)), - tyr = ny0>=0?nty0:(nty0 - ny0*(nty2 - nty0)/(ny2 - ny0)), - zl = ny1>=0?(ny0>=0?nz0:(nz0 - ny0*(nz1 - nz0)/(ny1 - ny0))):(pzl=pzn,(nz1 - ny1*(nz2 - nz1)/(ny2 - ny1))), - txl = ny1>=0?(ny0>=0?ntx0:(ntx0 - ny0*(ntx1 - ntx0)/(ny1 - ny0))): - (ptxl=ptxn,(ntx1 - ny1*(ntx2 - ntx1)/(ny2 - ny1))), - tyl = ny1>=0?(ny0>=0?nty0:(nty0 - ny0*(nty1 - nty0)/(ny1 - ny0))): - (ptyl=ptyn,(nty1 - ny1*(nty2 - nty1)/(ny2 - ny1))); - _cimg_for_triangle2(*this,xleft0,cleft0,xright0,cright0,y,nx0,ny0,nc0,nx1,ny1,nc1,nx2,ny2,nc2) { - if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; } - int - xleft = xleft0, xright = xright0, - cleft = cleft0, cright = cright0; - float - zleft = zl, zright = zr, - txleft = txl, txright = txr, - tyleft = tyl, tyright = tyr; - if (xrightcleft?cright - cleft:cleft - cright, - rc = dx?(cright - cleft)/dx:0, - sc = cright>cleft?1:-1, - ndc = dc - (dx?dx*(dc/dx):0); - const float - pentez = (zright - zleft)/dx, - pentetx = (txright - txleft)/dx, - pentety = (tyright - tyleft)/dx; - int errc = dx>>1; - if (xleft<0 && dx) { - cleft-=xleft*(cright - cleft)/dx; - zleft-=xleft*(zright - zleft)/dx; - txleft-=xleft*(txright - txleft)/dx; - tyleft-=xleft*(tyright - tyleft)/dx; - } - if (xleft<0) xleft = 0; - if (xright>=width() - 1) xright = width() - 1; - T* ptrd = data(xleft,y,0,0); - if (opacity>=1) for (int x = xleft; x<=xright; ++x) { - const float invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - cimg_forC(*this,c) { - *ptrd = (T)(cleft<256?cleft**col/256:((512 - cleft)**col + (cleft - 256)*maxval)/256); - ptrd+=whd; col+=twh; - } - ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0); - } else for (int x = xleft; x<=xright; ++x) { - const float invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - cimg_forC(*this,c) { - const T val = (T)(cleft<256?cleft**col/256:((512 - cleft)**col + (cleft - 256)*maxval)/256); - *ptrd = (T)(nopacity*val + *ptrd*copacity); - ptrd+=whd; col+=twh; - } - ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0); - } - zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl; - } - return *this; - } - - //! Draw a textured Gouraud-shaded 2d triangle, with perspective correction and z-buffering \overloading. - template - CImg& draw_triangle(CImg& zbuffer, - const int x0, const int y0, const float z0, - const int x1, const int y1, const float z1, - const int x2, const int y2, const float z2, - const CImg& texture, - const int tx0, const int ty0, - const int tx1, const int ty1, - const int tx2, const int ty2, - const float brightness0, - const float brightness1, - const float brightness2, - const float opacity=1) { - typedef typename cimg::superset::type tzfloat; - if (is_empty() || z0<=0 || z1<=0 || z2<=0) return *this; - if (!is_sameXY(zbuffer)) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have " - "different dimensions.", - cimg_instance, - zbuffer._width,zbuffer._height,zbuffer._depth,zbuffer._spectrum,zbuffer._data); - if (texture._depth>1 || texture._spectrum<_spectrum) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).", - cimg_instance, - texture._width,texture._height,texture._depth,texture._spectrum,texture._data); - if (is_overlapped(texture)) - return draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,+texture,tx0,ty0,tx1,ty1,tx2,ty2, - brightness0,brightness1,brightness2,opacity); - static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - const ulongT - whd = (ulongT)_width*_height*_depth, - twh = (ulongT)texture._width*texture._height, - offx = _spectrum*whd; - int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2, - nc0 = (int)((brightness0<0.0f?0.0f:(brightness0>2.0f?2.0f:brightness0))*256.0f), - nc1 = (int)((brightness1<0.0f?0.0f:(brightness1>2.0f?2.0f:brightness1))*256.0f), - nc2 = (int)((brightness2<0.0f?0.0f:(brightness2>2.0f?2.0f:brightness2))*256.0f); - float - ntx0 = tx0/z0, nty0 = ty0/z0, - ntx1 = tx1/z1, nty1 = ty1/z1, - ntx2 = tx2/z2, nty2 = ty2/z2; - tzfloat nz0 = 1/(tzfloat)z0, nz1 = 1/(tzfloat)z1, nz2 = 1/(tzfloat)z2; - if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nz0,nz1,nc0,nc1); - if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nz0,nz2,nc0,nc2); - if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nz1,nz2,nc1,nc2); - if (ny0>=height() || ny2<0) return *this; - float - ptxl = (ntx1 - ntx0)/(ny1 - ny0), - ptxr = (ntx2 - ntx0)/(ny2 - ny0), - ptxn = (ntx2 - ntx1)/(ny2 - ny1), - ptyl = (nty1 - nty0)/(ny1 - ny0), - ptyr = (nty2 - nty0)/(ny2 - ny0), - ptyn = (nty2 - nty1)/(ny2 - ny1), - txr = ny0>=0?ntx0:(ntx0 - ny0*(ntx2 - ntx0)/(ny2 - ny0)), - tyr = ny0>=0?nty0:(nty0 - ny0*(nty2 - nty0)/(ny2 - ny0)), - txl = ny1>=0?(ny0>=0?ntx0:(ntx0 - ny0*(ntx1 - ntx0)/(ny1 - ny0))): - (ptxl=ptxn,(ntx1 - ny1*(ntx2 - ntx1)/(ny2 - ny1))), - tyl = ny1>=0?(ny0>=0?nty0:(nty0 - ny0*(nty1 - nty0)/(ny1 - ny0))): - (ptyl=ptyn,(nty1 - ny1*(nty2 - nty1)/(ny2 - ny1))); - tzfloat - pzl = (nz1 - nz0)/(ny1 - ny0), - pzr = (nz2 - nz0)/(ny2 - ny0), - pzn = (nz2 - nz1)/(ny2 - ny1), - zr = ny0>=0?nz0:(nz0 - ny0*(nz2 - nz0)/(ny2 - ny0)), - zl = ny1>=0?(ny0>=0?nz0:(nz0 - ny0*(nz1 - nz0)/(ny1 - ny0))):(pzl=pzn,(nz1 - ny1*(nz2 - nz1)/(ny2 - ny1))); - _cimg_for_triangle2(*this,xleft0,cleft0,xright0,cright0,y,nx0,ny0,nc0,nx1,ny1,nc1,nx2,ny2,nc2) { - if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; } - int xleft = xleft0, xright = xright0, cleft = cleft0, cright = cright0; - float txleft = txl, txright = txr, tyleft = tyl, tyright = tyr; - tzfloat zleft = zl, zright = zr; - if (xrightcleft?cright - cleft:cleft - cright, - rc = dx?(cright - cleft)/dx:0, - sc = cright>cleft?1:-1, - ndc = dc - (dx?dx*(dc/dx):0); - float pentetx = (txright - txleft)/dx, pentety = (tyright - tyleft)/dx; - const tzfloat pentez = (zright - zleft)/dx; - int errc = dx>>1; - if (xleft<0 && dx) { - cleft-=xleft*(cright - cleft)/dx; - zleft-=xleft*(zright - zleft)/dx; - txleft-=xleft*(txright - txleft)/dx; - tyleft-=xleft*(tyright - tyleft)/dx; - } - if (xleft<0) xleft = 0; - if (xright>=width() - 1) xright = width() - 1; - T* ptrd = data(xleft,y); - tz *ptrz = zbuffer.data(xleft,y); - if (opacity>=1) for (int x = xleft; x<=xright; ++x, ++ptrd, ++ptrz) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tzfloat invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - cimg_forC(*this,c) { - *ptrd = (T)(cleft<256?cleft**col/256:((512 - cleft)**col + (cleft - 256)*maxval)/256); - ptrd+=whd; col+=twh; - } - ptrd-=offx; - } - zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0); - } else for (int x = xleft; x<=xright; ++x, ++ptrd, ++ptrz) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tzfloat invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - cimg_forC(*this,c) { - const T val = (T)(cleft<256?cleft**col/256:((512 - cleft)**col + (cleft - 256)*maxval)/256); - *ptrd = (T)(nopacity*val + *ptrd*copacity); - ptrd+=whd; col+=twh; - } - ptrd-=offx; - } - zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0); - } - zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl; - } - return *this; - } - - //! Draw a textured Phong-shaded 2d triangle. - /** - \param x0 X-coordinate of the first vertex in the image instance. - \param y0 Y-coordinate of the first vertex in the image instance. - \param x1 X-coordinate of the second vertex in the image instance. - \param y1 Y-coordinate of the second vertex in the image instance. - \param x2 X-coordinate of the third vertex in the image instance. - \param y2 Y-coordinate of the third vertex in the image instance. - \param texture Texture image used to fill the triangle. - \param tx0 X-coordinate of the first vertex in the texture image. - \param ty0 Y-coordinate of the first vertex in the texture image. - \param tx1 X-coordinate of the second vertex in the texture image. - \param ty1 Y-coordinate of the second vertex in the texture image. - \param tx2 X-coordinate of the third vertex in the texture image. - \param ty2 Y-coordinate of the third vertex in the texture image. - \param light Light image. - \param lx0 X-coordinate of the first vertex in the light image. - \param ly0 Y-coordinate of the first vertex in the light image. - \param lx1 X-coordinate of the second vertex in the light image. - \param ly1 Y-coordinate of the second vertex in the light image. - \param lx2 X-coordinate of the third vertex in the light image. - \param ly2 Y-coordinate of the third vertex in the light image. - \param opacity Drawing opacity. - **/ - template - CImg& draw_triangle(const int x0, const int y0, - const int x1, const int y1, - const int x2, const int y2, - const CImg& texture, - const int tx0, const int ty0, - const int tx1, const int ty1, - const int tx2, const int ty2, - const CImg& light, - const int lx0, const int ly0, - const int lx1, const int ly1, - const int lx2, const int ly2, - const float opacity=1) { - if (is_empty()) return *this; - if (texture._depth>1 || texture._spectrum<_spectrum) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).", - cimg_instance, - texture._width,texture._height,texture._depth,texture._spectrum,texture._data); - if (light._depth>1 || light._spectrum<_spectrum) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Invalid specified light texture (%u,%u,%u,%u,%p).", - cimg_instance,light._width,light._height,light._depth,light._spectrum,light._data); - if (is_overlapped(texture)) - return draw_triangle(x0,y0,x1,y1,x2,y2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,light,lx0,ly0,lx1,ly1,lx2,ly2,opacity); - if (is_overlapped(light)) - return draw_triangle(x0,y0,x1,y1,x2,y2,texture,tx0,ty0,tx1,ty1,tx2,ty2,+light,lx0,ly0,lx1,ly1,lx2,ly2,opacity); - static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - const ulongT - whd = (ulongT)_width*_height*_depth, - twh = (ulongT)texture._width*texture._height, - lwh = (ulongT)light._width*light._height, - offx = _spectrum*whd - 1; - int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2, - ntx0 = tx0, nty0 = ty0, ntx1 = tx1, nty1 = ty1, ntx2 = tx2, nty2 = ty2, - nlx0 = lx0, nly0 = ly0, nlx1 = lx1, nly1 = ly1, nlx2 = lx2, nly2 = ly2; - if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nlx0,nlx1,nly0,nly1); - if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nlx0,nlx2,nly0,nly2); - if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nlx1,nlx2,nly1,nly2); - if (ny0>=height() || ny2<0) return *this; - _cimg_for_triangle5(*this,xleft0,lxleft0,lyleft0,txleft0,tyleft0,xright0,lxright0,lyright0,txright0,tyright0,y, - nx0,ny0,nlx0,nly0,ntx0,nty0,nx1,ny1,nlx1,nly1,ntx1,nty1,nx2,ny2,nlx2,nly2,ntx2,nty2) { - int - xleft = xleft0, xright = xright0, - lxleft = lxleft0, lxright = lxright0, - lyleft = lyleft0, lyright = lyright0, - txleft = txleft0, txright = txright0, - tyleft = tyleft0, tyright = tyright0; - if (xrightlxleft?lxright - lxleft:lxleft - lxright, - dly = lyright>lyleft?lyright - lyleft:lyleft - lyright, - dtx = txright>txleft?txright - txleft:txleft - txright, - dty = tyright>tyleft?tyright - tyleft:tyleft - tyright, - rlx = dx?(lxright - lxleft)/dx:0, - rly = dx?(lyright - lyleft)/dx:0, - rtx = dx?(txright - txleft)/dx:0, - rty = dx?(tyright - tyleft)/dx:0, - slx = lxright>lxleft?1:-1, - sly = lyright>lyleft?1:-1, - stx = txright>txleft?1:-1, - sty = tyright>tyleft?1:-1, - ndlx = dlx - (dx?dx*(dlx/dx):0), - ndly = dly - (dx?dx*(dly/dx):0), - ndtx = dtx - (dx?dx*(dtx/dx):0), - ndty = dty - (dx?dx*(dty/dx):0); - int errlx = dx>>1, errly = errlx, errtx = errlx, errty = errlx; - if (xleft<0 && dx) { - lxleft-=xleft*(lxright - lxleft)/dx; - lyleft-=xleft*(lyright - lyleft)/dx; - txleft-=xleft*(txright - txleft)/dx; - tyleft-=xleft*(tyright - tyleft)/dx; - } - if (xleft<0) xleft = 0; - if (xright>=width() - 1) xright = width() - 1; - T* ptrd = data(xleft,y,0,0); - if (opacity>=1) for (int x = xleft; x<=xright; ++x) { - const tc *col = &texture._atXY(txleft,tyleft); - const tl *lig = &light._atXY(lxleft,lyleft); - cimg_forC(*this,c) { - const tl l = *lig; - *ptrd = (T)(l<1?l**col:(2 - l)**col + (l - 1)*maxval); - ptrd+=whd; col+=twh; lig+=lwh; - } - ptrd-=offx; - lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0); - lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0); - txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); - tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); - } else for (int x = xleft; x<=xright; ++x) { - const tc *col = &texture._atXY(txleft,tyleft); - const tl *lig = &light._atXY(lxleft,lyleft); - cimg_forC(*this,c) { - const tl l = *lig; - const T val = (T)(l<1?l**col:(2 - l)**col + (l - 1)*maxval); - *ptrd = (T)(nopacity*val + *ptrd*copacity); - ptrd+=whd; col+=twh; lig+=lwh; - } - ptrd-=offx; - lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0); - lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0); - txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); - tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); - } - } - return *this; - } - - //! Draw a textured Phong-shaded 2d triangle, with perspective correction. - template - CImg& draw_triangle(const int x0, const int y0, const float z0, - const int x1, const int y1, const float z1, - const int x2, const int y2, const float z2, - const CImg& texture, - const int tx0, const int ty0, - const int tx1, const int ty1, - const int tx2, const int ty2, - const CImg& light, - const int lx0, const int ly0, - const int lx1, const int ly1, - const int lx2, const int ly2, - const float opacity=1) { - if (is_empty() || z0<=0 || z1<=0 || z2<=0) return *this; - if (texture._depth>1 || texture._spectrum<_spectrum) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).", - cimg_instance, - texture._width,texture._height,texture._depth,texture._spectrum,texture._data); - if (light._depth>1 || light._spectrum<_spectrum) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Invalid specified light texture (%u,%u,%u,%u,%p).", - cimg_instance,light._width,light._height,light._depth,light._spectrum,light._data); - if (is_overlapped(texture)) - return draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,+texture,tx0,ty0,tx1,ty1,tx2,ty2, - light,lx0,ly0,lx1,ly1,lx2,ly2,opacity); - if (is_overlapped(light)) - return draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,texture,tx0,ty0,tx1,ty1,tx2,ty2, - +light,lx0,ly0,lx1,ly1,lx2,ly2,opacity); - static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - const ulongT - whd = (ulongT)_width*_height*_depth, - twh = (ulongT)texture._width*texture._height, - lwh = (ulongT)light._width*light._height, - offx = _spectrum*whd - 1; - int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2, - nlx0 = lx0, nly0 = ly0, nlx1 = lx1, nly1 = ly1, nlx2 = lx2, nly2 = ly2; - float - ntx0 = tx0/z0, nty0 = ty0/z0, - ntx1 = tx1/z1, nty1 = ty1/z1, - ntx2 = tx2/z2, nty2 = ty2/z2, - nz0 = 1/z0, nz1 = 1/z1, nz2 = 1/z2; - if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nlx0,nlx1,nly0,nly1,nz0,nz1); - if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nlx0,nlx2,nly0,nly2,nz0,nz2); - if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nlx1,nlx2,nly1,nly2,nz1,nz2); - if (ny0>=height() || ny2<0) return *this; - float - ptxl = (ntx1 - ntx0)/(ny1 - ny0), - ptxr = (ntx2 - ntx0)/(ny2 - ny0), - ptxn = (ntx2 - ntx1)/(ny2 - ny1), - ptyl = (nty1 - nty0)/(ny1 - ny0), - ptyr = (nty2 - nty0)/(ny2 - ny0), - ptyn = (nty2 - nty1)/(ny2 - ny1), - pzl = (nz1 - nz0)/(ny1 - ny0), - pzr = (nz2 - nz0)/(ny2 - ny0), - pzn = (nz2 - nz1)/(ny2 - ny1), - zr = ny0>=0?nz0:(nz0 - ny0*(nz2 - nz0)/(ny2 - ny0)), - txr = ny0>=0?ntx0:(ntx0 - ny0*(ntx2 - ntx0)/(ny2 - ny0)), - tyr = ny0>=0?nty0:(nty0 - ny0*(nty2 - nty0)/(ny2 - ny0)), - zl = ny1>=0?(ny0>=0?nz0:(nz0 - ny0*(nz1 - nz0)/(ny1 - ny0))):(pzl=pzn,(nz1 - ny1*(nz2 - nz1)/(ny2 - ny1))), - txl = ny1>=0?(ny0>=0?ntx0:(ntx0 - ny0*(ntx1 - ntx0)/(ny1 - ny0))): - (ptxl=ptxn,(ntx1 - ny1*(ntx2 - ntx1)/(ny2 - ny1))), - tyl = ny1>=0?(ny0>=0?nty0:(nty0 - ny0*(nty1 - nty0)/(ny1 - ny0))): - (ptyl=ptyn,(nty1 - ny1*(nty2 - nty1)/(ny2 - ny1))); - _cimg_for_triangle3(*this,xleft0,lxleft0,lyleft0,xright0,lxright0,lyright0,y, - nx0,ny0,nlx0,nly0,nx1,ny1,nlx1,nly1,nx2,ny2,nlx2,nly2) { - if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; } - int - xleft = xleft0, xright = xright0, - lxleft = lxleft0, lxright = lxright0, - lyleft = lyleft0, lyright = lyright0; - float - zleft = zl, zright = zr, - txleft = txl, txright = txr, - tyleft = tyl, tyright = tyr; - if (xrightlxleft?lxright - lxleft:lxleft - lxright, - dly = lyright>lyleft?lyright - lyleft:lyleft - lyright, - rlx = dx?(lxright - lxleft)/dx:0, - rly = dx?(lyright - lyleft)/dx:0, - slx = lxright>lxleft?1:-1, - sly = lyright>lyleft?1:-1, - ndlx = dlx - (dx?dx*(dlx/dx):0), - ndly = dly - (dx?dx*(dly/dx):0); - const float - pentez = (zright - zleft)/dx, - pentetx = (txright - txleft)/dx, - pentety = (tyright - tyleft)/dx; - int errlx = dx>>1, errly = errlx; - if (xleft<0 && dx) { - zleft-=xleft*(zright - zleft)/dx; - lxleft-=xleft*(lxright - lxleft)/dx; - lyleft-=xleft*(lyright - lyleft)/dx; - txleft-=xleft*(txright - txleft)/dx; - tyleft-=xleft*(tyright - tyleft)/dx; - } - if (xleft<0) xleft = 0; - if (xright>=width() - 1) xright = width() - 1; - T* ptrd = data(xleft,y,0,0); - if (opacity>=1) for (int x = xleft; x<=xright; ++x) { - const float invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - const tl *lig = &light._atXY(lxleft,lyleft); - cimg_forC(*this,c) { - const tl l = *lig; - *ptrd = (T)(l<1?l**col:(2 - l)**col + (l - 1)*maxval); - ptrd+=whd; col+=twh; lig+=lwh; - } - ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0); - lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0); - } else for (int x = xleft; x<=xright; ++x) { - const float invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - const tl *lig = &light._atXY(lxleft,lyleft); - cimg_forC(*this,c) { - const tl l = *lig; - const T val = (T)(l<1?l**col:(2 - l)**col + (l - 1)*maxval); - *ptrd = (T)(nopacity*val + *ptrd*copacity); - ptrd+=whd; col+=twh; lig+=lwh; - } - ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0); - lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0); - } - zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl; - } - return *this; - } - - //! Draw a textured Phong-shaded 2d triangle, with perspective correction and z-buffering. - template - CImg& draw_triangle(CImg& zbuffer, - const int x0, const int y0, const float z0, - const int x1, const int y1, const float z1, - const int x2, const int y2, const float z2, - const CImg& texture, - const int tx0, const int ty0, - const int tx1, const int ty1, - const int tx2, const int ty2, - const CImg& light, - const int lx0, const int ly0, - const int lx1, const int ly1, - const int lx2, const int ly2, - const float opacity=1) { - typedef typename cimg::superset::type tzfloat; - if (is_empty() || z0<=0 || z1<=0 || z2<=0) return *this; - if (!is_sameXY(zbuffer)) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have " - "different dimensions.", - cimg_instance, - zbuffer._width,zbuffer._height,zbuffer._depth,zbuffer._spectrum,zbuffer._data); - if (texture._depth>1 || texture._spectrum<_spectrum) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).", - cimg_instance, - texture._width,texture._height,texture._depth,texture._spectrum,texture._data); - if (light._depth>1 || light._spectrum<_spectrum) - throw CImgArgumentException(_cimg_instance - "draw_triangle(): Invalid specified light texture (%u,%u,%u,%u,%p).", - cimg_instance,light._width,light._height,light._depth,light._spectrum,light._data); - if (is_overlapped(texture)) - return draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2, - +texture,tx0,ty0,tx1,ty1,tx2,ty2,light,lx0,ly0,lx1,ly1,lx2,ly2,opacity); - if (is_overlapped(light)) - return draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2, - texture,tx0,ty0,tx1,ty1,tx2,ty2,+light,lx0,ly0,lx1,ly1,lx2,ly2,opacity); - static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - const ulongT - whd = (ulongT)_width*_height*_depth, - twh = (ulongT)texture._width*texture._height, - lwh = (ulongT)light._width*light._height, - offx = _spectrum*whd; - int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2, - nlx0 = lx0, nly0 = ly0, nlx1 = lx1, nly1 = ly1, nlx2 = lx2, nly2 = ly2; - float - ntx0 = tx0/z0, nty0 = ty0/z0, - ntx1 = tx1/z1, nty1 = ty1/z1, - ntx2 = tx2/z2, nty2 = ty2/z2; - tzfloat nz0 = 1/(tzfloat)z0, nz1 = 1/(tzfloat)z1, nz2 = 1/(tzfloat)z2; - if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nlx0,nlx1,nly0,nly1,nz0,nz1); - if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nlx0,nlx2,nly0,nly2,nz0,nz2); - if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nlx1,nlx2,nly1,nly2,nz1,nz2); - if (ny0>=height() || ny2<0) return *this; - float - ptxl = (ntx1 - ntx0)/(ny1 - ny0), - ptxr = (ntx2 - ntx0)/(ny2 - ny0), - ptxn = (ntx2 - ntx1)/(ny2 - ny1), - ptyl = (nty1 - nty0)/(ny1 - ny0), - ptyr = (nty2 - nty0)/(ny2 - ny0), - ptyn = (nty2 - nty1)/(ny2 - ny1), - txr = ny0>=0?ntx0:(ntx0 - ny0*(ntx2 - ntx0)/(ny2 - ny0)), - tyr = ny0>=0?nty0:(nty0 - ny0*(nty2 - nty0)/(ny2 - ny0)), - txl = ny1>=0?(ny0>=0?ntx0:(ntx0 - ny0*(ntx1 - ntx0)/(ny1 - ny0))): - (ptxl=ptxn,(ntx1 - ny1*(ntx2 - ntx1)/(ny2 - ny1))), - tyl = ny1>=0?(ny0>=0?nty0:(nty0 - ny0*(nty1 - nty0)/(ny1 - ny0))): - (ptyl=ptyn,(nty1 - ny1*(nty2 - nty1)/(ny2 - ny1))); - tzfloat - pzl = (nz1 - nz0)/(ny1 - ny0), - pzr = (nz2 - nz0)/(ny2 - ny0), - pzn = (nz2 - nz1)/(ny2 - ny1), - zr = ny0>=0?nz0:(nz0 - ny0*(nz2 - nz0)/(ny2 - ny0)), - zl = ny1>=0?(ny0>=0?nz0:(nz0 - ny0*(nz1 - nz0)/(ny1 - ny0))):(pzl=pzn,(nz1 - ny1*(nz2 - nz1)/(ny2 - ny1))); - _cimg_for_triangle3(*this,xleft0,lxleft0,lyleft0,xright0,lxright0,lyright0,y, - nx0,ny0,nlx0,nly0,nx1,ny1,nlx1,nly1,nx2,ny2,nlx2,nly2) { - if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; } - int - xleft = xleft0, xright = xright0, - lxleft = lxleft0, lxright = lxright0, - lyleft = lyleft0, lyright = lyright0; - float txleft = txl, txright = txr, tyleft = tyl, tyright = tyr; - tzfloat zleft = zl, zright = zr; - if (xrightlxleft?lxright - lxleft:lxleft - lxright, - dly = lyright>lyleft?lyright - lyleft:lyleft - lyright, - rlx = dx?(lxright - lxleft)/dx:0, - rly = dx?(lyright - lyleft)/dx:0, - slx = lxright>lxleft?1:-1, - sly = lyright>lyleft?1:-1, - ndlx = dlx - (dx?dx*(dlx/dx):0), - ndly = dly - (dx?dx*(dly/dx):0); - float pentetx = (txright - txleft)/dx, pentety = (tyright - tyleft)/dx; - const tzfloat pentez = (zright - zleft)/dx; - int errlx = dx>>1, errly = errlx; - if (xleft<0 && dx) { - zleft-=xleft*(zright - zleft)/dx; - lxleft-=xleft*(lxright - lxleft)/dx; - lyleft-=xleft*(lyright - lyleft)/dx; - txleft-=xleft*(txright - txleft)/dx; - tyleft-=xleft*(tyright - tyleft)/dx; - } - if (xleft<0) xleft = 0; - if (xright>=width() - 1) xright = width() - 1; - T* ptrd = data(xleft,y); - tz *ptrz = zbuffer.data(xleft,y); - if (opacity>=1) for (int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tzfloat invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - const tl *lig = &light._atXY(lxleft,lyleft); - cimg_forC(*this,c) { - const tl l = *lig; - *ptrd = (T)(l<1?l**col:(2 - l)**col + (l - 1)*maxval); - ptrd+=whd; col+=twh; lig+=lwh; - } - ptrd-=offx; - } - zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0); - lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0); - } else for (int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) { - if (zleft>=(tzfloat)*ptrz) { - *ptrz = (tz)zleft; - const tzfloat invz = 1/zleft; - const tc *col = &texture._atXY((int)(txleft*invz),(int)(tyleft*invz)); - const tl *lig = &light._atXY(lxleft,lyleft); - cimg_forC(*this,c) { - const tl l = *lig; - const T val = (T)(l<1?l**col:(2 - l)**col + (l - 1)*maxval); - *ptrd = (T)(nopacity*val + *ptrd*copacity); - ptrd+=whd; col+=twh; lig+=lwh; - } - ptrd-=offx; - } - zleft+=pentez; txleft+=pentetx; tyleft+=pentety; - lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0); - lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0); - } - zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl; - } - return *this; - } - - //! Draw a filled 4d rectangle. - /** - \param x0 X-coordinate of the upper-left rectangle corner. - \param y0 Y-coordinate of the upper-left rectangle corner. - \param z0 Z-coordinate of the upper-left rectangle corner. - \param c0 C-coordinate of the upper-left rectangle corner. - \param x1 X-coordinate of the lower-right rectangle corner. - \param y1 Y-coordinate of the lower-right rectangle corner. - \param z1 Z-coordinate of the lower-right rectangle corner. - \param c1 C-coordinate of the lower-right rectangle corner. - \param val Scalar value used to fill the rectangle area. - \param opacity Drawing opacity. - **/ - CImg& draw_rectangle(const int x0, const int y0, const int z0, const int c0, - const int x1, const int y1, const int z1, const int c1, - const T val, const float opacity=1) { - if (is_empty()) return *this; - const bool bx = (x0=width()?width() - 1 - nx1:0) + (nx0<0?nx0:0), - lY = (1 + ny1 - ny0) + (ny1>=height()?height() - 1 - ny1:0) + (ny0<0?ny0:0), - lZ = (1 + nz1 - nz0) + (nz1>=depth()?depth() - 1 - nz1:0) + (nz0<0?nz0:0), - lC = (1 + nc1 - nc0) + (nc1>=spectrum()?spectrum() - 1 - nc1:0) + (nc0<0?nc0:0); - const ulongT - offX = (ulongT)_width - lX, - offY = (ulongT)_width*(_height - lY), - offZ = (ulongT)_width*_height*(_depth - lZ); - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - T *ptrd = data(nx0<0?0:nx0,ny0<0?0:ny0,nz0<0?0:nz0,nc0<0?0:nc0); - if (lX>0 && lY>0 && lZ>0 && lC>0) - for (int v = 0; v=1) { - if (sizeof(T)!=1) { for (int x = 0; x - CImg& draw_rectangle(const int x0, const int y0, const int z0, - const int x1, const int y1, const int z1, - const tc *const color, const float opacity=1) { - if (is_empty()) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_rectangle(): Specified color is (null).", - cimg_instance); - cimg_forC(*this,c) draw_rectangle(x0,y0,z0,c,x1,y1,z1,c,(T)color[c],opacity); - return *this; - } - - //! Draw an outlined 3d rectangle \overloading. - template - CImg& draw_rectangle(const int x0, const int y0, const int z0, - const int x1, const int y1, const int z1, - const tc *const color, const float opacity, - const unsigned int pattern) { - return draw_line(x0,y0,z0,x1,y0,z0,color,opacity,pattern,true). - draw_line(x1,y0,z0,x1,y1,z0,color,opacity,pattern,false). - draw_line(x1,y1,z0,x0,y1,z0,color,opacity,pattern,false). - draw_line(x0,y1,z0,x0,y0,z0,color,opacity,pattern,false). - draw_line(x0,y0,z1,x1,y0,z1,color,opacity,pattern,true). - draw_line(x1,y0,z1,x1,y1,z1,color,opacity,pattern,false). - draw_line(x1,y1,z1,x0,y1,z1,color,opacity,pattern,false). - draw_line(x0,y1,z1,x0,y0,z1,color,opacity,pattern,false). - draw_line(x0,y0,z0,x0,y0,z1,color,opacity,pattern,true). - draw_line(x1,y0,z0,x1,y0,z1,color,opacity,pattern,true). - draw_line(x1,y1,z0,x1,y1,z1,color,opacity,pattern,true). - draw_line(x0,y1,z0,x0,y1,z1,color,opacity,pattern,true); - } - - //! Draw a filled 2d rectangle. - /** - \param x0 X-coordinate of the upper-left rectangle corner. - \param y0 Y-coordinate of the upper-left rectangle corner. - \param x1 X-coordinate of the lower-right rectangle corner. - \param y1 Y-coordinate of the lower-right rectangle corner. - \param color Pointer to \c spectrum() consecutive values of type \c T, defining the drawing color. - \param opacity Drawing opacity. - **/ - template - CImg& draw_rectangle(const int x0, const int y0, - const int x1, const int y1, - const tc *const color, const float opacity=1) { - return draw_rectangle(x0,y0,0,x1,y1,_depth - 1,color,opacity); - } - - //! Draw a outlined 2d rectangle \overloading. - template - CImg& draw_rectangle(const int x0, const int y0, - const int x1, const int y1, - const tc *const color, const float opacity, - const unsigned int pattern) { - if (is_empty()) return *this; - if (y0==y1) return draw_line(x0,y0,x1,y0,color,opacity,pattern,true); - if (x0==x1) return draw_line(x0,y0,x0,y1,color,opacity,pattern,true); - const bool bx = (x0 - CImg& draw_polygon(const CImg& points, - const tc *const color, const float opacity=1) { - if (is_empty() || !points) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_polygon(): Specified color is (null).", - cimg_instance); - - // Normalize 2d input coordinates (remove adjacent duplicates). - CImg npoints(points._width,2); - unsigned int nb_points = 1, p = 0; - int cx = npoints(0,0) = (int)points(0,0), cy = npoints(0,1) = (int)points(0,1); - const int cx0 = cx, cy0 = cy; - for (p = 1; p npoints_x = npoints.get_shared_row(0), npoints_y = npoints.get_shared_row(1); - int xmax = 0, xmin = (int)npoints_x.min_max(xmax), ymax = 0, ymin = (int)npoints_y.min_max(ymax); - if (xmax<0 || xmin>=width() || ymax<0 || ymin>=height()) return *this; - if (ymin==ymax) return cimg_draw_scanline(xmin,xmax,ymin,color,opacity,1); - const unsigned int - nxmin = xmin<0?0:(unsigned int)xmin, nxmax = xmax>=width()?_width - 1:(unsigned int)xmax, - nymin = ymin<0?0:(unsigned int)ymin, nymax = ymax>=height()?_height - 1:(unsigned int)ymax, - dx = 1 + nxmax - nxmin, - dy = 1 + nymax - nymin; - npoints_x-=nxmin; npoints_y-=nymin; - unsigned char one = 1; - const CImg mask = CImg(dx,dy,1,1,0).draw_polygon(npoints,&one,1); - CImg _color(dx,dy,1,spectrum()); - cimg_forC(_color,c) _color.get_shared_channel(c).fill(color[c]); - return draw_image(nxmin,nymin,0,0,_color,mask,opacity,1); - } - - // Draw polygon segments. - int - xmax = 0, xmin = (int)npoints.get_shared_points(0,nb_points - 1,0).min_max(xmax), - ymax = 0, ymin = (int)npoints.get_shared_points(0,nb_points - 1,1).min_max(ymax); - if (xmax<0 || xmin>=width() || ymax<0 || ymin>=height()) return *this; - if (ymin==ymax) return cimg_draw_scanline(xmin,xmax,ymin,color,1,1); - const unsigned int - nymin = ymin<0?0:(unsigned int)ymin, - nymax = ymax>=height()?_height - 1:(unsigned int)ymax, - dy = 1 + nymax - nymin; - CImg X(1 + 2*nb_points,dy,1,1,0), tmp; - cx = (int)npoints(0,0), cy = (int)npoints(0,1); - unsigned int cp = 0; - for (unsigned int p = 0; pay && cy>ny); - for (int x = cx, y = y0, _sx = 1, _sy = 1, - _dx = nx>cx?nx - cx:((_sx=-1),cx - nx), - _dy = y1>y0?y1 - y0:((_sy=-1),y0 - y1), - _counter = ((_dx-=_dy?_dy*(_dx/_dy):0),_dy), - _err = _dx>>1, - _rx = _dy?(nx - cx)/_dy:0; - _counter>=countermin; - --_counter, y+=_sy, x+=_rx + ((_err-=_dx)<0?_err+=_dy,_sx:0)) - if (y>=0 && y<(int)dy) X(++X(0,y),y) = x; - cp = np; cx = nx; cy = ny; - } else { - const int pp = (int)(cp?cp - 1:nb_points - 1), py = (int)npoints(pp,1); - if (y0>=0 && y0<(int)dy) { - cimg_draw_scanline(cxpy && ay>cy) || (cy - CImg& draw_polygon(const CImg& points, - const tc *const color, const float opacity, const unsigned int pattern) { - if (is_empty() || !points || points._width<3) return *this; - bool ninit_hatch = true; - switch (points._height) { - case 0 : case 1 : - throw CImgArgumentException(_cimg_instance - "draw_polygon(): Invalid specified point set.", - cimg_instance); - case 2 : { // 2d version. - CImg npoints(points._width,2); - int x = npoints(0,0) = (int)points(0,0), y = npoints(0,1) = (int)points(0,1); - unsigned int nb_points = 1; - for (unsigned int p = 1; p npoints(points._width,3); - int - x = npoints(0,0) = (int)points(0,0), - y = npoints(0,1) = (int)points(0,1), - z = npoints(0,2) = (int)points(0,2); - unsigned int nb_points = 1; - for (unsigned int p = 1; p - CImg& draw_ellipse(const int x0, const int y0, const float r1, const float r2, const float angle, - const tc *const color, const float opacity=1) { - return _draw_ellipse(x0,y0,r1,r2,angle,color,opacity,0U); - } - - //! Draw a filled 2d ellipse \overloading. - /** - \param x0 X-coordinate of the ellipse center. - \param y0 Y-coordinate of the ellipse center. - \param tensor Diffusion tensor describing the ellipse. - \param color Pointer to \c spectrum() consecutive values, defining the drawing color. - \param opacity Drawing opacity. - **/ - template - CImg& draw_ellipse(const int x0, const int y0, const CImg &tensor, - const tc *const color, const float opacity=1) { - CImgList eig = tensor.get_symmetric_eigen(); - const CImg &val = eig[0], &vec = eig[1]; - return draw_ellipse(x0,y0,std::sqrt(val(0)),std::sqrt(val(1)), - std::atan2(vec(0,1),vec(0,0))*180/cimg::PI, - color,opacity); - } - - //! Draw an outlined 2d ellipse. - /** - \param x0 X-coordinate of the ellipse center. - \param y0 Y-coordinate of the ellipse center. - \param r1 First radius of the ellipse. - \param r2 Second radius of the ellipse. - \param angle Angle of the first radius. - \param color Pointer to \c spectrum() consecutive values, defining the drawing color. - \param opacity Drawing opacity. - \param pattern An integer whose bits describe the outline pattern. - **/ - template - CImg& draw_ellipse(const int x0, const int y0, const float r1, const float r2, const float angle, - const tc *const color, const float opacity, const unsigned int pattern) { - if (pattern) _draw_ellipse(x0,y0,r1,r2,angle,color,opacity,pattern); - return *this; - } - - //! Draw an outlined 2d ellipse \overloading. - /** - \param x0 X-coordinate of the ellipse center. - \param y0 Y-coordinate of the ellipse center. - \param tensor Diffusion tensor describing the ellipse. - \param color Pointer to \c spectrum() consecutive values, defining the drawing color. - \param opacity Drawing opacity. - \param pattern An integer whose bits describe the outline pattern. - **/ - template - CImg& draw_ellipse(const int x0, const int y0, const CImg &tensor, - const tc *const color, const float opacity, - const unsigned int pattern) { - CImgList eig = tensor.get_symmetric_eigen(); - const CImg &val = eig[0], &vec = eig[1]; - return draw_ellipse(x0,y0,std::sqrt(val(0)),std::sqrt(val(1)), - std::atan2(vec(0,1),vec(0,0))*180/cimg::PI, - color,opacity,pattern); - } - - template - CImg& _draw_ellipse(const int x0, const int y0, const float r1, const float r2, const float angle, - const tc *const color, const float opacity, - const unsigned int pattern) { - if (is_empty()) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_ellipse(): Specified color is (null).", - cimg_instance); - if (r1<=0 || r2<=0) return draw_point(x0,y0,color,opacity); - cimg_init_scanline(color,opacity); - const float - nr1 = cimg::abs(r1), nr2 = cimg::abs(r2), - nangle = (float)(angle*cimg::PI/180), - u = (float)std::cos(nangle), - v = (float)std::sin(nangle), - rmax = cimg::max(nr1,nr2), - l1 = (float)std::pow(rmax/(nr1>0?nr1:1e-6),2), - l2 = (float)std::pow(rmax/(nr2>0?nr2:1e-6),2), - a = l1*u*u + l2*v*v, - b = u*v*(l1 - l2), - c = l1*v*v + l2*u*u; - const int - yb = (int)std::sqrt(a*rmax*rmax/(a*c - b*b)), - tymin = y0 - yb - 1, - tymax = y0 + yb + 1, - ymin = tymin<0?0:tymin, - ymax = tymax>=height()?height() - 1:tymax; - int oxmin = 0, oxmax = 0; - bool first_line = true; - for (int y = ymin; y<=ymax; ++y) { - const float - Y = y - y0 + (y0?(float)std::sqrt(delta)/a:0.0f, - bY = b*Y/a, - fxmin = x0 - 0.5f - bY - sdelta, - fxmax = x0 + 0.5f - bY + sdelta; - const int xmin = (int)fxmin, xmax = (int)fxmax; - if (!pattern) cimg_draw_scanline(xmin,xmax,y,color,opacity,1); - else { - if (first_line) { - if (y0 - yb>=0) cimg_draw_scanline(xmin,xmax,y,color,opacity,1); - else draw_point(xmin,y,color,opacity).draw_point(xmax,y,color,opacity); - first_line = false; - } else { - if (xmin - CImg& draw_circle(const int x0, const int y0, int radius, - const tc *const color, const float opacity=1) { - if (is_empty()) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_circle(): Specified color is (null).", - cimg_instance); - cimg_init_scanline(color,opacity); - if (radius<0 || x0 - radius>=width() || y0 + radius<0 || y0 - radius>=height()) return *this; - if (y0>=0 && y0=0) { - const int x1 = x0 - x, x2 = x0 + x, y1 = y0 - y, y2 = y0 + y; - if (y1>=0 && y1=0 && y2=0 && y1=0 && y2 - CImg& draw_circle(const int x0, const int y0, int radius, - const tc *const color, const float opacity, - const unsigned int pattern) { - cimg::unused(pattern); - if (is_empty()) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_circle(): Specified color is (null).", - cimg_instance); - if (radius<0 || x0 - radius>=width() || y0 + radius<0 || y0 - radius>=height()) return *this; - if (!radius) return draw_point(x0,y0,color,opacity); - draw_point(x0 - radius,y0,color,opacity).draw_point(x0 + radius,y0,color,opacity). - draw_point(x0,y0 - radius,color,opacity).draw_point(x0,y0 + radius,color,opacity); - if (radius==1) return *this; - for (int f = 1 - radius, ddFx = 0, ddFy = -(radius<<1), x = 0, y = radius; x=0) { f+=(ddFy+=2); --y; } - ++x; ++(f+=(ddFx+=2)); - if (x!=y + 1) { - const int x1 = x0 - y, x2 = x0 + y, y1 = y0 - x, y2 = y0 + x, - x3 = x0 - x, x4 = x0 + x, y3 = y0 - y, y4 = y0 + y; - draw_point(x1,y1,color,opacity).draw_point(x1,y2,color,opacity). - draw_point(x2,y1,color,opacity).draw_point(x2,y2,color,opacity); - if (x!=y) - draw_point(x3,y3,color,opacity).draw_point(x4,y4,color,opacity). - draw_point(x4,y3,color,opacity).draw_point(x3,y4,color,opacity); - } - } - return *this; - } - - //! Draw an image. - /** - \param sprite Sprite image. - \param x0 X-coordinate of the sprite position. - \param y0 Y-coordinate of the sprite position. - \param z0 Z-coordinate of the sprite position. - \param c0 C-coordinate of the sprite position. - \param opacity Drawing opacity. - **/ - template - CImg& draw_image(const int x0, const int y0, const int z0, const int c0, - const CImg& sprite, const float opacity=1) { - if (is_empty() || !sprite) return *this; - if (is_overlapped(sprite)) return draw_image(x0,y0,z0,c0,+sprite,opacity); - if (x0==0 && y0==0 && z0==0 && c0==0 && is_sameXYZC(sprite) && opacity>=1 && !is_shared()) - return assign(sprite,false); - const bool bx = (x0<0), by = (y0<0), bz = (z0<0), bc = (c0<0); - const int - lX = sprite.width() - (x0 + sprite.width()>width()?x0 + sprite.width() - width():0) + (bx?x0:0), - lY = sprite.height() - (y0 + sprite.height()>height()?y0 + sprite.height() - height():0) + (by?y0:0), - lZ = sprite.depth() - (z0 + sprite.depth()>depth()?z0 + sprite.depth() - depth():0) + (bz?z0:0), - lC = sprite.spectrum() - (c0 + sprite.spectrum()>spectrum()?c0 + sprite.spectrum() - spectrum():0) + (bc?c0:0); - const t - *ptrs = sprite._data + - (bx?-x0:0) + - (by?-y0*(ulongT)sprite.width():0) + - (bz?-z0*(ulongT)sprite.width()*sprite.height():0) + - (bc?-c0*(ulongT)sprite.width()*sprite.height()*sprite.depth():0); - const ulongT - offX = (ulongT)_width - lX, - soffX = (ulongT)sprite._width - lX, - offY = (ulongT)_width*(_height - lY), - soffY = (ulongT)sprite._width*(sprite._height - lY), - offZ = (ulongT)_width*_height*(_depth - lZ), - soffZ = (ulongT)sprite._width*sprite._height*(sprite._depth - lZ); - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - if (lX>0 && lY>0 && lZ>0 && lC>0) { - T *ptrd = data(x0<0?0:x0,y0<0?0:y0,z0<0?0:z0,c0<0?0:c0); - for (int v = 0; v=1) for (int x = 0; x& draw_image(const int x0, const int y0, const int z0, const int c0, - const CImg& sprite, const float opacity=1) { - if (is_empty() || !sprite) return *this; - if (is_overlapped(sprite)) return draw_image(x0,y0,z0,c0,+sprite,opacity); - if (x0==0 && y0==0 && z0==0 && c0==0 && is_sameXYZC(sprite) && opacity>=1 && !is_shared()) - return assign(sprite,false); - const bool bx = (x0<0), by = (y0<0), bz = (z0<0), bc = (c0<0); - const int - lX = sprite.width() - (x0 + sprite.width()>width()?x0 + sprite.width() - width():0) + (bx?x0:0), - lY = sprite.height() - (y0 + sprite.height()>height()?y0 + sprite.height() - height():0) + (by?y0:0), - lZ = sprite.depth() - (z0 + sprite.depth()>depth()?z0 + sprite.depth() - depth():0) + (bz?z0:0), - lC = sprite.spectrum() - (c0 + sprite.spectrum()>spectrum()?c0 + sprite.spectrum() - spectrum():0) + (bc?c0:0); - const T - *ptrs = sprite._data + - (bx?-x0:0) + - (by?-y0*(ulongT)sprite.width():0) + - (bz?-z0*(ulongT)sprite.width()*sprite.height():0) + - (bc?-c0*(ulongT)sprite.width()*sprite.height()*sprite.depth():0); - const ulongT - offX = (ulongT)_width - lX, - soffX = (ulongT)sprite._width - lX, - offY = (ulongT)_width*(_height - lY), - soffY = (ulongT)sprite._width*(sprite._height - lY), - offZ = (ulongT)_width*_height*(_depth - lZ), - soffZ = (ulongT)sprite._width*sprite._height*(sprite._depth - lZ), - slX = lX*sizeof(T); - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - if (lX>0 && lY>0 && lZ>0 && lC>0) { - T *ptrd = data(x0<0?0:x0,y0<0?0:y0,z0<0?0:z0,c0<0?0:c0); - for (int v = 0; v=1) - for (int y = 0; y - CImg& draw_image(const int x0, const int y0, const int z0, - const CImg& sprite, const float opacity=1) { - return draw_image(x0,y0,z0,0,sprite,opacity); - } - - //! Draw an image \overloading. - template - CImg& draw_image(const int x0, const int y0, - const CImg& sprite, const float opacity=1) { - return draw_image(x0,y0,0,sprite,opacity); - } - - //! Draw an image \overloading. - template - CImg& draw_image(const int x0, - const CImg& sprite, const float opacity=1) { - return draw_image(x0,0,sprite,opacity); - } - - //! Draw an image \overloading. - template - CImg& draw_image(const CImg& sprite, const float opacity=1) { - return draw_image(0,sprite,opacity); - } - - //! Draw a masked image. - /** - \param sprite Sprite image. - \param mask Mask image. - \param x0 X-coordinate of the sprite position in the image instance. - \param y0 Y-coordinate of the sprite position in the image instance. - \param z0 Z-coordinate of the sprite position in the image instance. - \param c0 C-coordinate of the sprite position in the image instance. - \param mask_max_value Maximum pixel value of the mask image \c mask. - \param opacity Drawing opacity. - \note - - Pixel values of \c mask set the opacity of the corresponding pixels in \c sprite. - - Dimensions along x,y and z of \p sprite and \p mask must be the same. - **/ - template - CImg& draw_image(const int x0, const int y0, const int z0, const int c0, - const CImg& sprite, const CImg& mask, const float opacity=1, - const float mask_max_value=1) { - if (is_empty() || !sprite || !mask) return *this; - if (is_overlapped(sprite)) return draw_image(x0,y0,z0,c0,+sprite,mask,opacity,mask_max_value); - if (is_overlapped(mask)) return draw_image(x0,y0,z0,c0,sprite,+mask,opacity,mask_max_value); - if (mask._width!=sprite._width || mask._height!=sprite._height || mask._depth!=sprite._depth) - throw CImgArgumentException(_cimg_instance - "draw_image(): Sprite (%u,%u,%u,%u,%p) and mask (%u,%u,%u,%u,%p) have " - "incompatible dimensions.", - cimg_instance, - sprite._width,sprite._height,sprite._depth,sprite._spectrum,sprite._data, - mask._width,mask._height,mask._depth,mask._spectrum,mask._data); - - const bool bx = (x0<0), by = (y0<0), bz = (z0<0), bc = (c0<0); - const int - lX = sprite.width() - (x0 + sprite.width()>width()?x0 + sprite.width() - width():0) + (bx?x0:0), - lY = sprite.height() - (y0 + sprite.height()>height()?y0 + sprite.height() - height():0) + (by?y0:0), - lZ = sprite.depth() - (z0 + sprite.depth()>depth()?z0 + sprite.depth() - depth():0) + (bz?z0:0), - lC = sprite.spectrum() - (c0 + sprite.spectrum()>spectrum()?c0 + sprite.spectrum() - spectrum():0) + (bc?c0:0); - const ulongT - coff = (bx?-x0:0) + - (by?-y0*(ulongT)mask.width():0) + - (bz?-z0*(ulongT)mask.width()*mask.height():0) + - (bc?-c0*(ulongT)mask.width()*mask.height()*mask.depth():0), - ssize = (ulongT)mask.width()*mask.height()*mask.depth()*mask.spectrum(); - const ti *ptrs = sprite._data + coff; - const tm *ptrm = mask._data + coff; - const ulongT - offX = (ulongT)_width - lX, - soffX = (ulongT)sprite._width - lX, - offY = (ulongT)_width*(_height - lY), - soffY = (ulongT)sprite._width*(sprite._height - lY), - offZ = (ulongT)_width*_height*(_depth - lZ), - soffZ = (ulongT)sprite._width*sprite._height*(sprite._depth - lZ); - if (lX>0 && lY>0 && lZ>0 && lC>0) { - T *ptrd = data(x0<0?0:x0,y0<0?0:y0,z0<0?0:z0,c0<0?0:c0); - for (int c = 0; c - CImg& draw_image(const int x0, const int y0, const int z0, - const CImg& sprite, const CImg& mask, const float opacity=1, - const float mask_max_value=1) { - return draw_image(x0,y0,z0,0,sprite,mask,opacity,mask_max_value); - } - - //! Draw a image \overloading. - template - CImg& draw_image(const int x0, const int y0, - const CImg& sprite, const CImg& mask, const float opacity=1, - const float mask_max_value=1) { - return draw_image(x0,y0,0,sprite,mask,opacity,mask_max_value); - } - - //! Draw a image \overloading. - template - CImg& draw_image(const int x0, - const CImg& sprite, const CImg& mask, const float opacity=1, - const float mask_max_value=1) { - return draw_image(x0,0,sprite,mask,opacity,mask_max_value); - } - - //! Draw an image. - template - CImg& draw_image(const CImg& sprite, const CImg& mask, const float opacity=1, - const float mask_max_value=1) { - return draw_image(0,sprite,mask,opacity,mask_max_value); - } - - //! Draw a text string. - /** - \param x0 X-coordinate of the text in the image instance. - \param y0 Y-coordinate of the text in the image instance. - \param text Format of the text ('printf'-style format string). - \param foreground_color Pointer to \c spectrum() consecutive values, defining the foreground drawing color. - \param background_color Pointer to \c spectrum() consecutive values, defining the background drawing color. - \param opacity Drawing opacity. - \param font Font used for drawing text. - **/ - template - CImg& draw_text(const int x0, const int y0, - const char *const text, - const tc1 *const foreground_color, const tc2 *const background_color, - const float opacity, const CImgList& font, ...) { - if (!font) return *this; - CImg tmp(2048); - std::va_list ap; va_start(ap,font); - cimg_vsnprintf(tmp,tmp._width,text,ap); va_end(ap); - return _draw_text(x0,y0,tmp,foreground_color,background_color,opacity,font,false); - } - - //! Draw a text string \overloading. - /** - \note A transparent background is used for the text. - **/ - template - CImg& draw_text(const int x0, const int y0, - const char *const text, - const tc *const foreground_color, const int, - const float opacity, const CImgList& font, ...) { - if (!font) return *this; - CImg tmp(2048); - std::va_list ap; va_start(ap,font); - cimg_vsnprintf(tmp,tmp._width,text,ap); va_end(ap); - return _draw_text(x0,y0,tmp,foreground_color,(tc*)0,opacity,font,false); - } - - //! Draw a text string \overloading. - /** - \note A transparent foreground is used for the text. - **/ - template - CImg& draw_text(const int x0, const int y0, - const char *const text, - const int, const tc *const background_color, - const float opacity, const CImgList& font, ...) { - if (!font) return *this; - CImg tmp(2048); - std::va_list ap; va_start(ap,font); - cimg_vsnprintf(tmp,tmp._width,text,ap); va_end(ap); - return _draw_text(x0,y0,tmp,(tc*)0,background_color,opacity,font,false); - } - - //! Draw a text string \overloading. - /** - \param x0 X-coordinate of the text in the image instance. - \param y0 Y-coordinate of the text in the image instance. - \param text Format of the text ('printf'-style format string). - \param foreground_color Array of spectrum() values of type \c T, - defining the foreground color (0 means 'transparent'). - \param background_color Array of spectrum() values of type \c T, - defining the background color (0 means 'transparent'). - \param opacity Drawing opacity. - \param font_height Height of the text font (exact match for 13,23,53,103, interpolated otherwise). - **/ - template - CImg& draw_text(const int x0, const int y0, - const char *const text, - const tc1 *const foreground_color, const tc2 *const background_color, - const float opacity=1, const unsigned int font_height=13, ...) { - if (!font_height) return *this; - CImg tmp(2048); - std::va_list ap; va_start(ap,font_height); - cimg_vsnprintf(tmp,tmp._width,text,ap); va_end(ap); - const CImgList& font = CImgList::font(font_height,true); - _draw_text(x0,y0,tmp,foreground_color,background_color,opacity,font,true); - return *this; - } - - //! Draw a text string \overloading. - template - CImg& draw_text(const int x0, const int y0, - const char *const text, - const tc *const foreground_color, const int background_color=0, - const float opacity=1, const unsigned int font_height=13, ...) { - if (!font_height) return *this; - cimg::unused(background_color); - CImg tmp(2048); - std::va_list ap; va_start(ap,font_height); - cimg_vsnprintf(tmp,tmp._width,text,ap); va_end(ap); - return draw_text(x0,y0,"%s",foreground_color,(const tc*)0,opacity,font_height,tmp._data); - } - - //! Draw a text string \overloading. - template - CImg& draw_text(const int x0, const int y0, - const char *const text, - const int, const tc *const background_color, - const float opacity=1, const unsigned int font_height=13, ...) { - if (!font_height) return *this; - CImg tmp(2048); - std::va_list ap; va_start(ap,font_height); - cimg_vsnprintf(tmp,tmp._width,text,ap); va_end(ap); - return draw_text(x0,y0,"%s",(tc*)0,background_color,opacity,font_height,tmp._data); - } - - template - CImg& _draw_text(const int x0, const int y0, - const char *const text, - const tc1 *const foreground_color, const tc2 *const background_color, - const float opacity, const CImgList& font, - const bool is_native_font) { - if (!text) return *this; - if (!font) - throw CImgArgumentException(_cimg_instance - "draw_text(): Empty specified font.", - cimg_instance); - - const unsigned int text_length = (unsigned int)std::strlen(text); - const bool _is_empty = is_empty(); - if (_is_empty) { - // If needed, pre-compute necessary size of the image - int x = 0, y = 0, w = 0; - unsigned char c = 0; - for (unsigned int i = 0; iw) w = x; x = 0; break; - case '\t' : x+=4*font[' ']._width; break; - default : if (cw) w=x; - y+=font[0]._height; - } - assign(x0 + w,y0 + y,1,is_native_font?1:font[0]._spectrum,0); - } - - int x = x0, y = y0; - for (unsigned int i = 0; i letter = font[c]; - if (letter) { - if (is_native_font && _spectrum>letter._spectrum) letter.resize(-100,-100,1,_spectrum,0,2); - const unsigned int cmin = cimg::min(_spectrum,letter._spectrum); - if (foreground_color) - for (unsigned int c = 0; c - CImg& draw_quiver(const CImg& flow, - const t2 *const color, const float opacity=1, - const unsigned int sampling=25, const float factor=-20, - const bool is_arrow=true, const unsigned int pattern=~0U) { - return draw_quiver(flow,CImg(color,_spectrum,1,1,1,true),opacity,sampling,factor,is_arrow,pattern); - } - - //! Draw a 2d vector field, using a field of colors. - /** - \param flow Image of 2d vectors used as input data. - \param color Image of spectrum()-D vectors corresponding to the color of each arrow. - \param opacity Opacity of the drawing. - \param sampling Length (in pixels) between each arrow. - \param factor Length factor of each arrow (if <0, computed as a percentage of the maximum length). - \param is_arrow Tells if arrows must be drawn, instead of oriented segments. - \param pattern Used pattern to draw lines. - \note Clipping is supported. - **/ - template - CImg& draw_quiver(const CImg& flow, - const CImg& color, const float opacity=1, - const unsigned int sampling=25, const float factor=-20, - const bool is_arrow=true, const unsigned int pattern=~0U) { - if (is_empty()) return *this; - if (!flow || flow._spectrum!=2) - throw CImgArgumentException(_cimg_instance - "draw_quiver(): Invalid dimensions of specified flow (%u,%u,%u,%u,%p).", - cimg_instance, - flow._width,flow._height,flow._depth,flow._spectrum,flow._data); - if (sampling<=0) - throw CImgArgumentException(_cimg_instance - "draw_quiver(): Invalid sampling value %g " - "(should be >0)", - cimg_instance, - sampling); - const bool colorfield = (color._width==flow._width && color._height==flow._height && - color._depth==1 && color._spectrum==_spectrum); - if (is_overlapped(flow)) return draw_quiver(+flow,color,opacity,sampling,factor,is_arrow,pattern); - float vmax,fact; - if (factor<=0) { - float m, M = (float)flow.get_norm(2).max_min(m); - vmax = (float)cimg::max(cimg::abs(m),cimg::abs(M)); - if (!vmax) vmax = 1; - fact = -factor; - } else { fact = factor; vmax = 1; } - - for (unsigned int y = sampling/2; y<_height; y+=sampling) - for (unsigned int x = sampling/2; x<_width; x+=sampling) { - const unsigned int X = x*flow._width/_width, Y = y*flow._height/_height; - float u = (float)flow(X,Y,0,0)*fact/vmax, v = (float)flow(X,Y,0,1)*fact/vmax; - if (is_arrow) { - const int xx = (int)(x + u), yy = (int)(y + v); - if (colorfield) draw_arrow(x,y,xx,yy,color.get_vector_at(X,Y)._data,opacity,45,sampling/5.0f,pattern); - else draw_arrow(x,y,xx,yy,color._data,opacity,45,sampling/5.0f,pattern); - } else { - if (colorfield) - draw_line((int)(x - 0.5*u),(int)(y - 0.5*v),(int)(x + 0.5*u),(int)(y + 0.5*v), - color.get_vector_at(X,Y)._data,opacity,pattern); - else draw_line((int)(x - 0.5*u),(int)(y - 0.5*v),(int)(x + 0.5*u),(int)(y + 0.5*v), - color._data,opacity,pattern); - } - } - return *this; - } - - //! Draw a labeled horizontal axis. - /** - \param values_x Values along the horizontal axis. - \param y Y-coordinate of the horizontal axis in the image instance. - \param color Pointer to \c spectrum() consecutive values, defining the drawing color. - \param opacity Drawing opacity. - \param pattern Drawing pattern. - \param font_height Height of the labels (exact match for 13,23,53,103, interpolated otherwise). - \param allow_zero Enable/disable the drawing of label '0' if found. - **/ - template - CImg& draw_axis(const CImg& values_x, const int y, - const tc *const color, const float opacity=1, - const unsigned int pattern=~0U, const unsigned int font_height=13, - const bool allow_zero=true) { - if (is_empty()) return *this; - const int yt = (y + 3 + font_height)<_height?y + 3:y - 2 - (int)font_height; - const int siz = (int)values_x.size() - 1; - CImg txt(32); - CImg label; - if (siz<=0) { // Degenerated case. - draw_line(0,y,_width - 1,y,color,opacity,pattern); - if (!siz) { - cimg_snprintf(txt,txt._width,"%g",(double)*values_x); - label.assign().draw_text(0,0,txt,color,(tc*)0,opacity,font_height); - const int - _xt = (width() - label.width())/2, - xt = _xt<3?3:_xt + label.width()>=width() - 2?width() - 3 - label.width():_xt; - draw_point(width()/2,y - 1,color,opacity).draw_point(width()/2,y + 1,color,opacity); - if (allow_zero || *txt!='0' || txt[1]!=0) - draw_text(xt,yt,txt,color,(tc*)0,opacity,font_height); - } - } else { // Regular case. - if (values_x[0]=width() - 2?width() - 3 - label.width():_xt; - draw_point(xi,y - 1,color,opacity).draw_point(xi,y + 1,color,opacity); - if (allow_zero || *txt!='0' || txt[1]!=0) - draw_text(xt,yt,txt,color,(tc*)0,opacity,font_height); - } - } - return *this; - } - - //! Draw a labeled vertical axis. - /** - \param x X-coordinate of the vertical axis in the image instance. - \param values_y Values along the Y-axis. - \param color Pointer to \c spectrum() consecutive values, defining the drawing color. - \param opacity Drawing opacity. - \param pattern Drawing pattern. - \param font_height Height of the labels (exact match for 13,23,53,103, interpolated otherwise). - \param allow_zero Enable/disable the drawing of label '0' if found. - **/ - template - CImg& draw_axis(const int x, const CImg& values_y, - const tc *const color, const float opacity=1, - const unsigned int pattern=~0U, const unsigned int font_height=13, - const bool allow_zero=true) { - if (is_empty()) return *this; - int siz = (int)values_y.size() - 1; - CImg txt(32); - CImg label; - if (siz<=0) { // Degenerated case. - draw_line(x,0,x,_height - 1,color,opacity,pattern); - if (!siz) { - cimg_snprintf(txt,txt._width,"%g",(double)*values_y); - label.assign().draw_text(0,0,txt,color,(tc*)0,opacity,font_height); - const int - _yt = (height() - label.height())/2, - yt = _yt<0?0:_yt + label.height()>=height()?height() - 1-label.height():_yt, - _xt = x - 2 - label.width(), - xt = _xt>=0?_xt:x + 3; - draw_point(x - 1,height()/2,color,opacity).draw_point(x + 1,height()/2,color,opacity); - if (allow_zero || *txt!='0' || txt[1]!=0) - draw_text(xt,yt,txt,color,(tc*)0,opacity,font_height); - } - } else { // Regular case. - if (values_y[0]=height()?height() - 1-label.height():_yt, - _xt = x - 2 - label.width(), - xt = _xt>=0?_xt:x + 3; - draw_point(x - 1,yi,color,opacity).draw_point(x + 1,yi,color,opacity); - if (allow_zero || *txt!='0' || txt[1]!=0) - draw_text(xt,yt,txt,color,(tc*)0,opacity,font_height); - } - } - return *this; - } - - //! Draw labeled horizontal and vertical axes. - /** - \param values_x Values along the X-axis. - \param values_y Values along the Y-axis. - \param color Pointer to \c spectrum() consecutive values, defining the drawing color. - \param opacity Drawing opacity. - \param pattern_x Drawing pattern for the X-axis. - \param pattern_y Drawing pattern for the Y-axis. - \param font_height Height of the labels (exact match for 13,23,53,103, interpolated otherwise). - \param allow_zero Enable/disable the drawing of label '0' if found. - **/ - template - CImg& draw_axes(const CImg& values_x, const CImg& values_y, - const tc *const color, const float opacity=1, - const unsigned int pattern_x=~0U, const unsigned int pattern_y=~0U, - const unsigned int font_height=13, const bool allow_zero=true) { - if (is_empty()) return *this; - const CImg nvalues_x(values_x._data,values_x.size(),1,1,1,true); - const int sizx = (int)values_x.size() - 1, wm1 = width() - 1; - if (sizx>=0) { - float ox = (float)*nvalues_x; - for (unsigned int x = sizx?1U:0U; x<_width; ++x) { - const float nx = (float)nvalues_x._linear_atX((float)x*sizx/wm1); - if (nx*ox<=0) { draw_axis(nx==0?x:x - 1,values_y,color,opacity,pattern_y,font_height,allow_zero); break; } - ox = nx; - } - } - const CImg nvalues_y(values_y._data,values_y.size(),1,1,1,true); - const int sizy = (int)values_y.size() - 1, hm1 = height() - 1; - if (sizy>0) { - float oy = (float)nvalues_y[0]; - for (unsigned int y = sizy?1U:0U; y<_height; ++y) { - const float ny = (float)nvalues_y._linear_atX((float)y*sizy/hm1); - if (ny*oy<=0) { draw_axis(values_x,ny==0?y:y - 1,color,opacity,pattern_x,font_height,allow_zero); break; } - oy = ny; - } - } - return *this; - } - - //! Draw labeled horizontal and vertical axes \overloading. - template - CImg& draw_axes(const float x0, const float x1, const float y0, const float y1, - const tc *const color, const float opacity=1, - const int subdivisionx=-60, const int subdivisiony=-60, - const float precisionx=0, const float precisiony=0, - const unsigned int pattern_x=~0U, const unsigned int pattern_y=~0U, - const unsigned int font_height=13) { - if (is_empty()) return *this; - const bool allow_zero = (x0*x1>0) || (y0*y1>0); - const float - dx = cimg::abs(x1-x0), dy = cimg::abs(y1-y0), - px = dx<=0?1:precisionx==0?(float)std::pow(10.0,(int)std::log10(dx) - 2.0):precisionx, - py = dy<=0?1:precisiony==0?(float)std::pow(10.0,(int)std::log10(dy) - 2.0):precisiony; - if (x0!=x1 && y0!=y1) - draw_axes(CImg::sequence(subdivisionx>0?subdivisionx:1-width()/subdivisionx,x0,x1).round(px), - CImg::sequence(subdivisiony>0?subdivisiony:1-height()/subdivisiony,y0,y1).round(py), - color,opacity,pattern_x,pattern_y,font_height,allow_zero); - else if (x0==x1 && y0!=y1) - draw_axis((int)x0,CImg::sequence(subdivisiony>0?subdivisiony:1-height()/subdivisiony,y0,y1).round(py), - color,opacity,pattern_y,font_height); - else if (x0!=x1 && y0==y1) - draw_axis(CImg::sequence(subdivisionx>0?subdivisionx:1-width()/subdivisionx,x0,x1).round(px),(int)y0, - color,opacity,pattern_x,font_height); - return *this; - } - - //! Draw 2d grid. - /** - \param values_x X-coordinates of the vertical lines. - \param values_y Y-coordinates of the horizontal lines. - \param color Pointer to \c spectrum() consecutive values, defining the drawing color. - \param opacity Drawing opacity. - \param pattern_x Drawing pattern for vertical lines. - \param pattern_y Drawing pattern for horizontal lines. - **/ - template - CImg& draw_grid(const CImg& values_x, const CImg& values_y, - const tc *const color, const float opacity=1, - const unsigned int pattern_x=~0U, const unsigned int pattern_y=~0U) { - if (is_empty()) return *this; - if (values_x) cimg_foroff(values_x,x) { - const int xi = (int)values_x[x]; - if (xi>=0 && xi=0 && yi - CImg& draw_grid(const float delta_x, const float delta_y, - const float offsetx, const float offsety, - const bool invertx, const bool inverty, - const tc *const color, const float opacity=1, - const unsigned int pattern_x=~0U, const unsigned int pattern_y=~0U) { - if (is_empty()) return *this; - CImg seqx, seqy; - if (delta_x!=0) { - const float dx = delta_x>0?delta_x:_width*-delta_x/100; - const unsigned int nx = (unsigned int)(_width/dx); - seqx = CImg::sequence(1 + nx,0,(unsigned int)(dx*nx)); - if (offsetx) cimg_foroff(seqx,x) seqx(x) = (unsigned int)cimg::mod(seqx(x) + offsetx,(float)_width); - if (invertx) cimg_foroff(seqx,x) seqx(x) = _width - 1 - seqx(x); - } - if (delta_y!=0) { - const float dy = delta_y>0?delta_y:_height*-delta_y/100; - const unsigned int ny = (unsigned int)(_height/dy); - seqy = CImg::sequence(1 + ny,0,(unsigned int)(dy*ny)); - if (offsety) cimg_foroff(seqy,y) seqy(y) = (unsigned int)cimg::mod(seqy(y) + offsety,(float)_height); - if (inverty) cimg_foroff(seqy,y) seqy(y) = _height - 1 - seqy(y); - } - return draw_grid(seqx,seqy,color,opacity,pattern_x,pattern_y); - } - - //! Draw 1d graph. - /** - \param data Image containing the graph values I = f(x). - \param color Pointer to \c spectrum() consecutive values, defining the drawing color. - \param opacity Drawing opacity. - - \param plot_type Define the type of the plot: - - 0 = No plot. - - 1 = Plot using segments. - - 2 = Plot using cubic splines. - - 3 = Plot with bars. - \param vertex_type Define the type of points: - - 0 = No points. - - 1 = Point. - - 2 = Straight cross. - - 3 = Diagonal cross. - - 4 = Filled circle. - - 5 = Outlined circle. - - 6 = Square. - - 7 = Diamond. - \param ymin Lower bound of the y-range. - \param ymax Upper bound of the y-range. - \param pattern Drawing pattern. - \note - - if \c ymin==ymax==0, the y-range is computed automatically from the input samples. - **/ - template - CImg& draw_graph(const CImg& data, - const tc *const color, const float opacity=1, - const unsigned int plot_type=1, const int vertex_type=1, - const double ymin=0, const double ymax=0, const unsigned int pattern=~0U) { - if (is_empty() || _height<=1) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_graph(): Specified color is (null).", - cimg_instance); - - // Create shaded colors for displaying bar plots. - CImg color1, color2; - if (plot_type==3) { - color1.assign(_spectrum); color2.assign(_spectrum); - cimg_forC(*this,c) { - color1[c] = (tc)cimg::min((float)cimg::type::max(),color[c]*1.2f); - color2[c] = (tc)(color[c]*0.4f); - } - } - - // Compute min/max and normalization factors. - const ulongT - siz = data.size(), - _siz1 = siz - (plot_type!=3), - siz1 = _siz1?_siz1:1; - const unsigned int - _width1 = _width - (plot_type!=3), - width1 = _width1?_width1:1; - double m = ymin, M = ymax; - if (ymin==ymax) m = (double)data.max_min(M); - if (m==M) { --m; ++M; } - const float ca = (float)(M-m)/(_height - 1); - bool init_hatch = true; - - // Draw graph edges - switch (plot_type%4) { - case 1 : { // Segments - int oX = 0, oY = (int)((data[0] - m)/ca); - if (siz==1) { - const int Y = (int)((*data - m)/ca); - draw_line(0,Y,width() - 1,Y,color,opacity,pattern); - } else { - const float fx = (float)_width/siz1; - for (ulongT off = 1; off ndata(data._data,siz,1,1,1,true); - int oY = (int)((data[0] - m)/ca); - cimg_forX(*this,x) { - const int Y = (int)((ndata._cubic_atX((float)x*siz1/width1)-m)/ca); - if (x>0) draw_line(x,oY,x + 1,Y,color,opacity,pattern,init_hatch); - init_hatch = false; - oY = Y; - } - } break; - case 3 : { // Bars - const int Y0 = (int)(-m/ca); - const float fx = (float)_width/siz1; - int oX = 0; - cimg_foroff(data,off) { - const int - X = (int)((off + 1)*fx) - 1, - Y = (int)((data[off] - m)/ca); - draw_rectangle(oX,Y0,X,Y,color,opacity). - draw_line(oX,Y,oX,Y0,color2.data(),opacity). - draw_line(oX,Y0,X,Y0,Y<=Y0?color2.data():color1.data(),opacity). - draw_line(X,Y,X,Y0,color1.data(),opacity). - draw_line(oX,Y,X,Y,Y<=Y0?color1.data():color2.data(),opacity); - oX = X + 1; - } - } break; - default : break; // No edges - } - - // Draw graph points - const unsigned int wb2 = plot_type==3?_width1/(2*siz):0; - const float fx = (float)_width1/siz1; - switch (vertex_type%8) { - case 1 : { // Point - cimg_foroff(data,off) { - const int - X = (int)(off*fx + wb2), - Y = (int)((data[off]-m)/ca); - draw_point(X,Y,color,opacity); - } - } break; - case 2 : { // Straight Cross - cimg_foroff(data,off) { - const int - X = (int)(off*fx + wb2), - Y = (int)((data[off]-m)/ca); - draw_line(X - 3,Y,X + 3,Y,color,opacity).draw_line(X,Y - 3,X,Y + 3,color,opacity); - } - } break; - case 3 : { // Diagonal Cross - cimg_foroff(data,off) { - const int - X = (int)(off*fx + wb2), - Y = (int)((data[off]-m)/ca); - draw_line(X - 3,Y - 3,X + 3,Y + 3,color,opacity).draw_line(X - 3,Y + 3,X + 3,Y - 3,color,opacity); - } - } break; - case 4 : { // Filled Circle - cimg_foroff(data,off) { - const int - X = (int)(off*fx + wb2), - Y = (int)((data[off]-m)/ca); - draw_circle(X,Y,3,color,opacity); - } - } break; - case 5 : { // Outlined circle - cimg_foroff(data,off) { - const int - X = (int)(off*fx + wb2), - Y = (int)((data[off]-m)/ca); - draw_circle(X,Y,3,color,opacity,0U); - } - } break; - case 6 : { // Square - cimg_foroff(data,off) { - const int - X = (int)(off*fx + wb2), - Y = (int)((data[off]-m)/ca); - draw_rectangle(X - 3,Y - 3,X + 3,Y + 3,color,opacity,~0U); - } - } break; - case 7 : { // Diamond - cimg_foroff(data,off) { - const int - X = (int)(off*fx + wb2), - Y = (int)((data[off]-m)/ca); - draw_line(X,Y - 4,X + 4,Y,color,opacity). - draw_line(X + 4,Y,X,Y + 4,color,opacity). - draw_line(X,Y + 4,X - 4,Y,color,opacity). - draw_line(X - 4,Y,X,Y - 4,color,opacity); - } - } break; - default : break; // No points - } - return *this; - } - - //! Draw filled 3d region with the flood fill algorithm. - /** - \param x X-coordinate of the starting point of the region to fill. - \param y Y-coordinate of the starting point of the region to fill. - \param z Z-coordinate of the starting point of the region to fill. - \param color Pointer to \c spectrum() consecutive values, defining the drawing color. - \param[out] region Image that will contain the mask of the filled region mask, as an output. - \param sigma Tolerance concerning neighborhood values. - \param opacity Opacity of the drawing. - \param is_high_connexity Tells if 8-connexity must be used (only for 2d images). - \return \c region is initialized with the binary mask of the filled region. - **/ - template - CImg& draw_fill(const int x, const int y, const int z, - const tc *const color, const float opacity, - CImg& region, const float sigma=0, - const bool is_high_connexity=false) { - -#define _cimg_draw_fill_test(x,y,z,res) if (region(x,y,z)) res = false; else { \ - res = true; \ - const T *reference_col = reference_color._data + _spectrum, *ptrs = data(x,y,z) + siz; \ - for (unsigned int i = _spectrum; res && i; --i) { ptrs-=whd; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } \ - region(x,y,z) = (t)(res?1:noregion); \ -} - -#define _cimg_draw_fill_set(x,y,z) { \ - const tc *col = color; \ - T *ptrd = data(x,y,z); \ - if (opacity>=1) cimg_forC(*this,c) { *ptrd = (T)*(col++); ptrd+=whd; } \ - else cimg_forC(*this,c) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whd; } \ -} - -#define _cimg_draw_fill_insert(x,y,z) { \ - if (posr1>=remaining._height) remaining.resize(3,remaining._height<<1,1,1,0); \ - unsigned int *ptrr = remaining.data(0,posr1); \ - *(ptrr++) = x; *(ptrr++) = y; *(ptrr++) = z; ++posr1; \ -} - -#define _cimg_draw_fill_test_neighbor(x,y,z,cond) if (cond) { \ - const unsigned int tx = x, ty = y, tz = z; \ - _cimg_draw_fill_test(tx,ty,tz,res); if (res) _cimg_draw_fill_insert(tx,ty,tz); \ -} - - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_fill(): Specified color is (null).", - cimg_instance); - - region.assign(_width,_height,_depth,1,(t)0); - if (x>=0 && x=0 && y=0 && z1); - const CImg reference_color = get_vector_at(x,y,z); - CImg remaining(3,512,1,1,0); - remaining(0,0) = (unsigned int)x; - remaining(1,0) = (unsigned int)y; - remaining(2,0) = (unsigned int)z; - unsigned int posr0 = 0, posr1 = 1; - region(x,y,z) = (t)1; - const t noregion = ((t)1==(t)2)?(t)0:(t)-1; - if (is_3d) do { // 3d version of the filling algorithm - const unsigned int *pcurr = remaining.data(0,posr0++), xc = *(pcurr++), yc = *(pcurr++), zc = *(pcurr++); - if (posr0>=512) { remaining.shift(0,-(int)posr0); posr1-=posr0; posr0 = 0; } - bool cont, res; - unsigned int nxc = xc; - do { // X-backward - _cimg_draw_fill_set(nxc,yc,zc); - _cimg_draw_fill_test_neighbor(nxc,yc - 1,zc,yc!=0); - _cimg_draw_fill_test_neighbor(nxc,yc + 1,zc,ycposr0); - else do { // 2d version of the filling algorithm - const unsigned int *pcurr = remaining.data(0,posr0++), xc = *(pcurr++), yc = *(pcurr++); - if (posr0>=512) { remaining.shift(0,-(int)posr0); posr1-=posr0; posr0 = 0; } - bool cont, res; - unsigned int nxc = xc; - do { // X-backward - _cimg_draw_fill_set(nxc,yc,0); - _cimg_draw_fill_test_neighbor(nxc,yc - 1,0,yc!=0); - _cimg_draw_fill_test_neighbor(nxc,yc + 1,0,ycposr0); - if (noregion) cimg_for(region,ptrd,t) if (*ptrd==noregion) *ptrd = (t)0; - } - return *this; - } - - //! Draw filled 3d region with the flood fill algorithm \simplification. - template - CImg& draw_fill(const int x, const int y, const int z, - const tc *const color, const float opacity=1, - const float sigma=0, const bool is_high_connexity=false) { - CImg tmp; - return draw_fill(x,y,z,color,opacity,tmp,sigma,is_high_connexity); - } - - //! Draw filled 2d region with the flood fill algorithm \simplification. - template - CImg& draw_fill(const int x, const int y, - const tc *const color, const float opacity=1, - const float sigma=0, const bool is_high_connexity=false) { - CImg tmp; - return draw_fill(x,y,0,color,opacity,tmp,sigma,is_high_connexity); - } - - //! Draw a random plasma texture. - /** - \param alpha Alpha-parameter. - \param beta Beta-parameter. - \param scale Scale-parameter. - \note Use the mid-point algorithm to render. - **/ - CImg& draw_plasma(const float alpha=1, const float beta=0, const unsigned int scale=8) { - if (is_empty()) return *this; - const int w = width(), h = height(); - const Tfloat m = (Tfloat)cimg::type::min(), M = (Tfloat)cimg::type::max(); - cimg_forZC(*this,z,c) { - CImg ref = get_shared_slice(z,c); - for (int delta = 1<1; delta>>=1) { - const int delta2 = delta>>1; - const float r = alpha*delta + beta; - - // Square step. - for (int y0 = 0; y0M?M:val); - } - - // Diamond steps. - for (int y = -delta2; yM?M:val); - } - for (int y0 = 0; y0M?M:val); - } - for (int y = -delta2; yM?M:val); - } - } - } - return *this; - } - - //! Draw a quadratic Mandelbrot or Julia 2d fractal. - /** - \param x0 X-coordinate of the upper-left pixel. - \param y0 Y-coordinate of the upper-left pixel. - \param x1 X-coordinate of the lower-right pixel. - \param y1 Y-coordinate of the lower-right pixel. - \param colormap Colormap. - \param opacity Drawing opacity. - \param z0r Real part of the upper-left fractal vertex. - \param z0i Imaginary part of the upper-left fractal vertex. - \param z1r Real part of the lower-right fractal vertex. - \param z1i Imaginary part of the lower-right fractal vertex. - \param iteration_max Maximum number of iterations for each estimated point. - \param is_normalized_iteration Tells if iterations are normalized. - \param is_julia_set Tells if the Mandelbrot or Julia set is rendered. - \param param_r Real part of the Julia set parameter. - \param param_i Imaginary part of the Julia set parameter. - \note Fractal rendering is done by the Escape Time Algorithm. - **/ - template - CImg& draw_mandelbrot(const int x0, const int y0, const int x1, const int y1, - const CImg& colormap, const float opacity=1, - const double z0r=-2, const double z0i=-2, const double z1r=2, const double z1i=2, - const unsigned int iteration_max=255, - const bool is_normalized_iteration=false, - const bool is_julia_set=false, - const double param_r=0, const double param_i=0) { - if (is_empty()) return *this; - CImg palette; - if (colormap) palette.assign(colormap._data,colormap.size()/colormap._spectrum,1,1,colormap._spectrum,true); - if (palette && palette._spectrum!=_spectrum) - throw CImgArgumentException(_cimg_instance - "draw_mandelbrot(): Instance and specified colormap (%u,%u,%u,%u,%p) have " - "incompatible dimensions.", - cimg_instance, - colormap._width,colormap._height,colormap._depth,colormap._spectrum,colormap._data); - - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0), ln2 = (float)std::log(2.0); - const int - _x0 = x0<0?0:x0>=width()?width() - 1:x0, - _y0 = y0<0?0:y0>=height()?height() - 1:y0, - _x1 = x1<0?1:x1>=width()?width() - 1:x1, - _y1 = y1<0?1:y1>=height()?height() - 1:y1; - - cimg_pragma_openmp(parallel for collapse(2) if ((1 + _x1 - _x0)*(1 + _y1 - _y0)>=2048)) - for (int q = _y0; q<=_y1; ++q) - for (int p = _x0; p<=_x1; ++p) { - unsigned int iteration = 0; - const double x = z0r + p*(z1r-z0r)/_width, y = z0i + q*(z1i-z0i)/_height; - double zr, zi, cr, ci; - if (is_julia_set) { zr = x; zi = y; cr = param_r; ci = param_i; } - else { zr = param_r; zi = param_i; cr = x; ci = y; } - for (iteration=1; zr*zr + zi*zi<=4 && iteration<=iteration_max; ++iteration) { - const double temp = zr*zr - zi*zi + cr; - zi = 2*zr*zi + ci; - zr = temp; - } - if (iteration>iteration_max) { - if (palette) { - if (opacity>=1) cimg_forC(*this,c) (*this)(p,q,0,c) = (T)palette(0,c); - else cimg_forC(*this,c) (*this)(p,q,0,c) = (T)(palette(0,c)*nopacity + (*this)(p,q,0,c)*copacity); - } else { - if (opacity>=1) cimg_forC(*this,c) (*this)(p,q,0,c) = (T)0; - else cimg_forC(*this,c) (*this)(p,q,0,c) = (T)((*this)(p,q,0,c)*copacity); - } - } else if (is_normalized_iteration) { - const float - normz = (float)cimg::abs(zr*zr + zi*zi), - niteration = (float)(iteration + 1 - std::log(std::log(normz))/ln2); - if (palette) { - if (opacity>=1) cimg_forC(*this,c) (*this)(p,q,0,c) = (T)palette._linear_atX(niteration,c); - else cimg_forC(*this,c) - (*this)(p,q,0,c) = (T)(palette._linear_atX(niteration,c)*nopacity + (*this)(p,q,0,c)*copacity); - } else { - if (opacity>=1) cimg_forC(*this,c) (*this)(p,q,0,c) = (T)niteration; - else cimg_forC(*this,c) (*this)(p,q,0,c) = (T)(niteration*nopacity + (*this)(p,q,0,c)*copacity); - } - } else { - if (palette) { - if (opacity>=1) cimg_forC(*this,c) (*this)(p,q,0,c) = (T)palette._atX(iteration,c); - else cimg_forC(*this,c) (*this)(p,q,0,c) = (T)(palette(iteration,c)*nopacity + (*this)(p,q,0,c)*copacity); - } else { - if (opacity>=1) cimg_forC(*this,c) (*this)(p,q,0,c) = (T)iteration; - else cimg_forC(*this,c) (*this)(p,q,0,c) = (T)(iteration*nopacity + (*this)(p,q,0,c)*copacity); - } - } - } - return *this; - } - - //! Draw a quadratic Mandelbrot or Julia 2d fractal \overloading. - template - CImg& draw_mandelbrot(const CImg& colormap, const float opacity=1, - const double z0r=-2, const double z0i=-2, const double z1r=2, const double z1i=2, - const unsigned int iteration_max=255, - const bool is_normalized_iteration=false, - const bool is_julia_set=false, - const double param_r=0, const double param_i=0) { - return draw_mandelbrot(0,0,_width - 1,_height - 1,colormap,opacity, - z0r,z0i,z1r,z1i,iteration_max,is_normalized_iteration,is_julia_set,param_r,param_i); - } - - //! Draw a 1d gaussian function. - /** - \param xc X-coordinate of the gaussian center. - \param sigma Standard variation of the gaussian distribution. - \param color Pointer to \c spectrum() consecutive values, defining the drawing color. - \param opacity Drawing opacity. - **/ - template - CImg& draw_gaussian(const float xc, const float sigma, - const tc *const color, const float opacity=1) { - if (is_empty()) return *this; - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_gaussian(): Specified color is (null).", - cimg_instance); - const float sigma2 = 2*sigma*sigma, nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - const ulongT whd = (ulongT)_width*_height*_depth; - const tc *col = color; - cimg_forX(*this,x) { - const float dx = (x - xc), val = (float)std::exp(-dx*dx/sigma2); - T *ptrd = data(x,0,0,0); - if (opacity>=1) cimg_forC(*this,c) { *ptrd = (T)(val*(*col++)); ptrd+=whd; } - else cimg_forC(*this,c) { *ptrd = (T)(nopacity*val*(*col++) + *ptrd*copacity); ptrd+=whd; } - col-=_spectrum; - } - return *this; - } - - //! Draw a 2d gaussian function. - /** - \param xc X-coordinate of the gaussian center. - \param yc Y-coordinate of the gaussian center. - \param tensor Covariance matrix (must be 2x2). - \param color Pointer to \c spectrum() consecutive values, defining the drawing color. - \param opacity Drawing opacity. - **/ - template - CImg& draw_gaussian(const float xc, const float yc, const CImg& tensor, - const tc *const color, const float opacity=1) { - if (is_empty()) return *this; - if (tensor._width!=2 || tensor._height!=2 || tensor._depth!=1 || tensor._spectrum!=1) - throw CImgArgumentException(_cimg_instance - "draw_gaussian(): Specified tensor (%u,%u,%u,%u,%p) is not a 2x2 matrix.", - cimg_instance, - tensor._width,tensor._height,tensor._depth,tensor._spectrum,tensor._data); - if (!color) - throw CImgArgumentException(_cimg_instance - "draw_gaussian(): Specified color is (null).", - cimg_instance); - typedef typename CImg::Tfloat tfloat; - const CImg invT = tensor.get_invert(), invT2 = (invT*invT)/(-2.0); - const tfloat a = invT2(0,0), b = 2*invT2(1,0), c = invT2(1,1); - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - const ulongT whd = (ulongT)_width*_height*_depth; - const tc *col = color; - float dy = -yc; - cimg_forY(*this,y) { - float dx = -xc; - cimg_forX(*this,x) { - const float val = (float)std::exp(a*dx*dx + b*dx*dy + c*dy*dy); - T *ptrd = data(x,y,0,0); - if (opacity>=1) cimg_forC(*this,c) { *ptrd = (T)(val*(*col++)); ptrd+=whd; } - else cimg_forC(*this,c) { *ptrd = (T)(nopacity*val*(*col++) + *ptrd*copacity); ptrd+=whd; } - col-=_spectrum; - ++dx; - } - ++dy; - } - return *this; - } - - //! Draw a 2d gaussian function \overloading. - template - CImg& draw_gaussian(const int xc, const int yc, const float r1, const float r2, const float ru, const float rv, - const tc *const color, const float opacity=1) { - const double - a = r1*ru*ru + r2*rv*rv, - b = (r1-r2)*ru*rv, - c = r1*rv*rv + r2*ru*ru; - const CImg tensor(2,2,1,1, a,b,b,c); - return draw_gaussian(xc,yc,tensor,color,opacity); - } - - //! Draw a 2d gaussian function \overloading. - template - CImg& draw_gaussian(const float xc, const float yc, const float sigma, - const tc *const color, const float opacity=1) { - return draw_gaussian(xc,yc,CImg::diagonal(sigma,sigma),color,opacity); - } - - //! Draw a 3d gaussian function \overloading. - template - CImg& draw_gaussian(const float xc, const float yc, const float zc, const CImg& tensor, - const tc *const color, const float opacity=1) { - if (is_empty()) return *this; - typedef typename CImg::Tfloat tfloat; - if (tensor._width!=3 || tensor._height!=3 || tensor._depth!=1 || tensor._spectrum!=1) - throw CImgArgumentException(_cimg_instance - "draw_gaussian(): Specified tensor (%u,%u,%u,%u,%p) is not a 3x3 matrix.", - cimg_instance, - tensor._width,tensor._height,tensor._depth,tensor._spectrum,tensor._data); - - const CImg invT = tensor.get_invert(), invT2 = (invT*invT)/(-2.0); - const tfloat a = invT2(0,0), b = 2*invT2(1,0), c = 2*invT2(2,0), d = invT2(1,1), e = 2*invT2(2,1), f = invT2(2,2); - const float nopacity = cimg::abs(opacity), copacity = 1 - cimg::max(opacity,0); - const ulongT whd = (ulongT)_width*_height*_depth; - const tc *col = color; - cimg_forXYZ(*this,x,y,z) { - const float - dx = (x - xc), dy = (y - yc), dz = (z - zc), - val = (float)std::exp(a*dx*dx + b*dx*dy + c*dx*dz + d*dy*dy + e*dy*dz + f*dz*dz); - T *ptrd = data(x,y,z,0); - if (opacity>=1) cimg_forC(*this,c) { *ptrd = (T)(val*(*col++)); ptrd+=whd; } - else cimg_forC(*this,c) { *ptrd = (T)(nopacity*val*(*col++) + *ptrd*copacity); ptrd+=whd; } - col-=_spectrum; - } - return *this; - } - - //! Draw a 3d gaussian function \overloading. - template - CImg& draw_gaussian(const float xc, const float yc, const float zc, const float sigma, - const tc *const color, const float opacity=1) { - return draw_gaussian(xc,yc,zc,CImg::diagonal(sigma,sigma,sigma),color,opacity); - } - - //! Draw a 3d object. - /** - \param x0 X-coordinate of the 3d object position - \param y0 Y-coordinate of the 3d object position - \param z0 Z-coordinate of the 3d object position - \param vertices Image Nx3 describing 3d point coordinates - \param primitives List of P primitives - \param colors List of P color (or textures) - \param opacities Image or list of P opacities - \param render_type d Render type (0=Points, 1=Lines, 2=Faces (no light), 3=Faces (flat), 4=Faces(Gouraud) - \param is_double_sided Tells if object faces have two sides or are oriented. - \param focale length of the focale (0 for parallel projection) - \param lightx X-coordinate of the light - \param lighty Y-coordinate of the light - \param lightz Z-coordinate of the light - \param specular_lightness Amount of specular light. - \param specular_shininess Shininess of the object - **/ - template - CImg& draw_object3d(const float x0, const float y0, const float z0, - const CImg& vertices, const CImgList& primitives, - const CImgList& colors, const CImg& opacities, - const unsigned int render_type=4, - const bool is_double_sided=false, const float focale=700, - const float lightx=0, const float lighty=0, const float lightz=-5e8, - const float specular_lightness=0.2f, const float specular_shininess=0.1f) { - return draw_object3d(x0,y0,z0,vertices,primitives,colors,opacities,render_type, - is_double_sided,focale,lightx,lighty,lightz, - specular_lightness,specular_shininess,CImg::empty()); - } - - //! Draw a 3d object \simplification. - template - CImg& draw_object3d(const float x0, const float y0, const float z0, - const CImg& vertices, const CImgList& primitives, - const CImgList& colors, const CImg& opacities, - const unsigned int render_type, - const bool is_double_sided, const float focale, - const float lightx, const float lighty, const float lightz, - const float specular_lightness, const float specular_shininess, - CImg& zbuffer) { - return _draw_object3d(0,zbuffer,x0,y0,z0,vertices,primitives,colors,opacities, - render_type,is_double_sided,focale,lightx,lighty,lightz, - specular_lightness,specular_shininess,1); - } - -#ifdef cimg_use_board - template - CImg& draw_object3d(LibBoard::Board& board, - const float x0, const float y0, const float z0, - const CImg& vertices, const CImgList& primitives, - const CImgList& colors, const CImg& opacities, - const unsigned int render_type=4, - const bool is_double_sided=false, const float focale=700, - const float lightx=0, const float lighty=0, const float lightz=-5e8, - const float specular_lightness=0.2f, const float specular_shininess=0.1f) { - return draw_object3d(board,x0,y0,z0,vertices,primitives,colors,opacities,render_type, - is_double_sided,focale,lightx,lighty,lightz, - specular_lightness,specular_shininess,CImg::empty()); - } - - template - CImg& draw_object3d(LibBoard::Board& board, - const float x0, const float y0, const float z0, - const CImg& vertices, const CImgList& primitives, - const CImgList& colors, const CImg& opacities, - const unsigned int render_type, - const bool is_double_sided, const float focale, - const float lightx, const float lighty, const float lightz, - const float specular_lightness, const float specular_shininess, - CImg& zbuffer) { - return _draw_object3d((void*)&board,zbuffer,x0,y0,z0,vertices,primitives,colors,opacities, - render_type,is_double_sided,focale,lightx,lighty,lightz, - specular_lightness,specular_shininess,1); - } -#endif - - //! Draw a 3d object \simplification. - template - CImg& draw_object3d(const float x0, const float y0, const float z0, - const CImg& vertices, const CImgList& primitives, - const CImgList& colors, const CImgList& opacities, - const unsigned int render_type=4, - const bool is_double_sided=false, const float focale=700, - const float lightx=0, const float lighty=0, const float lightz=-5e8, - const float specular_lightness=0.2f, const float specular_shininess=0.1f) { - return draw_object3d(x0,y0,z0,vertices,primitives,colors,opacities,render_type, - is_double_sided,focale,lightx,lighty,lightz, - specular_lightness,specular_shininess,CImg::empty()); - } - - //! Draw a 3d object \simplification. - template - CImg& draw_object3d(const float x0, const float y0, const float z0, - const CImg& vertices, const CImgList& primitives, - const CImgList& colors, const CImgList& opacities, - const unsigned int render_type, - const bool is_double_sided, const float focale, - const float lightx, const float lighty, const float lightz, - const float specular_lightness, const float specular_shininess, - CImg& zbuffer) { - return _draw_object3d(0,zbuffer,x0,y0,z0,vertices,primitives,colors,opacities, - render_type,is_double_sided,focale,lightx,lighty,lightz, - specular_lightness,specular_shininess,1); - } - -#ifdef cimg_use_board - template - CImg& draw_object3d(LibBoard::Board& board, - const float x0, const float y0, const float z0, - const CImg& vertices, const CImgList& primitives, - const CImgList& colors, const CImgList& opacities, - const unsigned int render_type=4, - const bool is_double_sided=false, const float focale=700, - const float lightx=0, const float lighty=0, const float lightz=-5e8, - const float specular_lightness=0.2f, const float specular_shininess=0.1f) { - return draw_object3d(board,x0,y0,z0,vertices,primitives,colors,opacities,render_type, - is_double_sided,focale,lightx,lighty,lightz, - specular_lightness,specular_shininess,CImg::empty()); - } - - template - CImg& draw_object3d(LibBoard::Board& board, - const float x0, const float y0, const float z0, - const CImg& vertices, const CImgList& primitives, - const CImgList& colors, const CImgList& opacities, - const unsigned int render_type, - const bool is_double_sided, const float focale, - const float lightx, const float lighty, const float lightz, - const float specular_lightness, const float specular_shininess, - CImg& zbuffer) { - return _draw_object3d((void*)&board,zbuffer,x0,y0,z0,vertices,primitives,colors,opacities, - render_type,is_double_sided,focale,lightx,lighty,lightz, - specular_lightness,specular_shininess,1); - } -#endif - - //! Draw a 3d object \simplification. - template - CImg& draw_object3d(const float x0, const float y0, const float z0, - const CImg& vertices, const CImgList& primitives, - const CImgList& colors, - const unsigned int render_type=4, - const bool is_double_sided=false, const float focale=700, - const float lightx=0, const float lighty=0, const float lightz=-5e8, - const float specular_lightness=0.2f, const float specular_shininess=0.1f) { - return draw_object3d(x0,y0,z0,vertices,primitives,colors,CImg::const_empty(), - render_type,is_double_sided,focale,lightx,lighty,lightz, - specular_lightness,specular_shininess,CImg::empty()); - } - - //! Draw a 3d object \simplification. - template - CImg& draw_object3d(const float x0, const float y0, const float z0, - const CImg& vertices, const CImgList& primitives, - const CImgList& colors, - const unsigned int render_type, - const bool is_double_sided, const float focale, - const float lightx, const float lighty, const float lightz, - const float specular_lightness, const float specular_shininess, - CImg& zbuffer) { - return draw_object3d(x0,y0,z0,vertices,primitives,colors,CImg::const_empty(), - render_type,is_double_sided,focale,lightx,lighty,lightz, - specular_lightness,specular_shininess,zbuffer); - } - -#ifdef cimg_use_board - template - CImg& draw_object3d(LibBoard::Board& board, - const float x0, const float y0, const float z0, - const CImg& vertices, const CImgList& primitives, - const CImgList& colors, - const unsigned int render_type=4, - const bool is_double_sided=false, const float focale=700, - const float lightx=0, const float lighty=0, const float lightz=-5e8, - const float specular_lightness=0.2f, const float specular_shininess=0.1f) { - return draw_object3d(x0,y0,z0,vertices,primitives,colors,CImg::const_empty(), - render_type,is_double_sided,focale,lightx,lighty,lightz, - specular_lightness,specular_shininess,CImg::empty()); - } - - template - CImg& draw_object3d(LibBoard::Board& board, - const float x0, const float y0, const float z0, - const CImg& vertices, const CImgList& primitives, - const CImgList& colors, - const unsigned int render_type, - const bool is_double_sided, const float focale, - const float lightx, const float lighty, const float lightz, - const float specular_lightness, const float specular_shininess, - CImg& zbuffer) { - return draw_object3d(x0,y0,z0,vertices,primitives,colors,CImg::const_empty(), - render_type,is_double_sided,focale,lightx,lighty,lightz, - specular_lightness,specular_shininess,zbuffer); - } -#endif - - template - static float __draw_object3d(const CImgList& opacities, const unsigned int n_primitive, CImg& opacity) { - if (n_primitive>=opacities._width || opacities[n_primitive].is_empty()) { opacity.assign(); return 1; } - if (opacities[n_primitive].size()==1) { opacity.assign(); return opacities(n_primitive,0); } - opacity.assign(opacities[n_primitive],true); - return 1.0f; - } - - template - static float __draw_object3d(const CImg& opacities, const unsigned int n_primitive, CImg& opacity) { - opacity.assign(); - return n_primitive>=opacities._width?1.0f:(float)opacities[n_primitive]; - } - - template - static float ___draw_object3d(const CImgList& opacities, const unsigned int n_primitive) { - return n_primitive - static float ___draw_object3d(const CImg& opacities, const unsigned int n_primitive) { - return n_primitive - CImg& _draw_object3d(void *const pboard, CImg& zbuffer, - const float X, const float Y, const float Z, - const CImg& vertices, - const CImgList& primitives, - const CImgList& colors, - const to& opacities, - const unsigned int render_type, - const bool is_double_sided, const float focale, - const float lightx, const float lighty, const float lightz, - const float specular_lightness, const float specular_shininess, - const float sprite_scale) { - typedef typename cimg::superset2::type tpfloat; - typedef typename to::value_type _to; - if (is_empty() || !vertices || !primitives) return *this; - CImg error_message(1024); - if (!vertices.is_object3d(primitives,colors,opacities,false,error_message)) - throw CImgArgumentException(_cimg_instance - "draw_object3d(): Invalid specified 3d object (%u,%u) (%s).", - cimg_instance,vertices._width,primitives._width,error_message.data()); -#ifndef cimg_use_board - if (pboard) return *this; -#endif - if (render_type==5) cimg::mutex(10); // Static variable used in this case, breaks thread-safety. - - const float - nspec = 1 - (specular_lightness<0.0f?0.0f:(specular_lightness>1.0f?1.0f:specular_lightness)), - nspec2 = 1 + (specular_shininess<0.0f?0.0f:specular_shininess), - nsl1 = (nspec2 - 1)/cimg::sqr(nspec - 1), - nsl2 = 1 - 2*nsl1*nspec, - nsl3 = nspec2 - nsl1 - nsl2; - - // Create light texture for phong-like rendering. - CImg light_texture; - if (render_type==5) { - if (colors._width>primitives._width) { - static CImg default_light_texture; - static const tc *lptr = 0; - static tc ref_values[64] = { 0 }; - const CImg& img = colors.back(); - bool is_same_texture = (lptr==img._data); - if (is_same_texture) - for (unsigned int r = 0, j = 0; j<8; ++j) - for (unsigned int i = 0; i<8; ++i) - if (ref_values[r++]!=img(i*img._width/9,j*img._height/9,0,(i + j)%img._spectrum)) { - is_same_texture = false; break; - } - if (!is_same_texture || default_light_texture._spectrum<_spectrum) { - (default_light_texture.assign(img,false)/=255).resize(-100,-100,1,_spectrum); - lptr = colors.back().data(); - for (unsigned int r = 0, j = 0; j<8; ++j) - for (unsigned int i = 0; i<8; ++i) - ref_values[r++] = img(i*img._width/9,j*img._height/9,0,(i + j)%img._spectrum); - } - light_texture.assign(default_light_texture,true); - } else { - static CImg default_light_texture; - static float olightx = 0, olighty = 0, olightz = 0, ospecular_shininess = 0; - if (!default_light_texture || - lightx!=olightx || lighty!=olighty || lightz!=olightz || - specular_shininess!=ospecular_shininess || default_light_texture._spectrum<_spectrum) { - default_light_texture.assign(512,512); - const float - dlx = lightx - X, - dly = lighty - Y, - dlz = lightz - Z, - nl = (float)std::sqrt(dlx*dlx + dly*dly + dlz*dlz), - nlx = (default_light_texture._width - 1)/2*(1 + dlx/nl), - nly = (default_light_texture._height - 1)/2*(1 + dly/nl), - white[] = { 1 }; - default_light_texture.draw_gaussian(nlx,nly,default_light_texture._width/3.0f,white); - cimg_forXY(default_light_texture,x,y) { - const float factor = default_light_texture(x,y); - if (factor>nspec) default_light_texture(x,y) = cimg::min(2,nsl1*factor*factor + nsl2*factor + nsl3); - } - default_light_texture.resize(-100,-100,1,_spectrum); - olightx = lightx; olighty = lighty; olightz = lightz; ospecular_shininess = specular_shininess; - } - light_texture.assign(default_light_texture,true); - } - } - - // Compute 3d to 2d projection. - CImg projections(vertices._width,2); - tpfloat parallzmin = cimg::type::max(); - const float absfocale = focale?cimg::abs(focale):0; - if (absfocale) { - cimg_pragma_openmp(parallel for cimg_openmp_if(projections.size()>4096)) - cimg_forX(projections,l) { // Perspective projection - const tpfloat - x = (tpfloat)vertices(l,0), - y = (tpfloat)vertices(l,1), - z = (tpfloat)vertices(l,2); - const tpfloat projectedz = z + Z + absfocale; - projections(l,1) = Y + absfocale*y/projectedz; - projections(l,0) = X + absfocale*x/projectedz; - } - - } else { - cimg_pragma_openmp(parallel for cimg_openmp_if(projections.size()>4096)) - cimg_forX(projections,l) { // Parallel projection - const tpfloat - x = (tpfloat)vertices(l,0), - y = (tpfloat)vertices(l,1), - z = (tpfloat)vertices(l,2); - if (z visibles(primitives._width,1,1,1,~0U); - CImg zrange(primitives._width); - const tpfloat zmin = absfocale?(tpfloat)(1.5f - absfocale):cimg::type::min(); - bool is_forward = zbuffer?true:false; - - cimg_pragma_openmp(parallel for cimg_openmp_if(primitives.size()>4096)) - cimglist_for(primitives,l) { - const CImg& primitive = primitives[l]; - switch (primitive.size()) { - case 1 : { // Point - CImg<_to> _opacity; - __draw_object3d(opacities,l,_opacity); - if (l<=colors.width() && (colors[l].size()!=_spectrum || _opacity)) is_forward = false; - const unsigned int i0 = (unsigned int)primitive(0); - const tpfloat z0 = Z + vertices(i0,2); - if (z0>zmin) { - visibles(l) = (unsigned int)l; - zrange(l) = z0; - } - } break; - case 5 : { // Sphere - const unsigned int - i0 = (unsigned int)primitive(0), - i1 = (unsigned int)primitive(1); - const tpfloat - Xc = 0.5f*((float)vertices(i0,0) + (float)vertices(i1,0)), - Yc = 0.5f*((float)vertices(i0,1) + (float)vertices(i1,1)), - Zc = 0.5f*((float)vertices(i0,2) + (float)vertices(i1,2)), - _zc = Z + Zc, - zc = _zc + _focale, - xc = X + Xc*(absfocale?absfocale/zc:1), - yc = Y + Yc*(absfocale?absfocale/zc:1), - radius = 0.5f*std::sqrt(cimg::sqr(vertices(i1,0) - vertices(i0,0)) + - cimg::sqr(vertices(i1,1) - vertices(i0,1)) + - cimg::sqr(vertices(i1,2) - vertices(i0,2)))*(absfocale?absfocale/zc:1), - xm = xc - radius, - ym = yc - radius, - xM = xc + radius, - yM = yc + radius; - if (xM>=0 && xm<_width && yM>=0 && ym<_height && _zc>zmin) { - visibles(l) = (unsigned int)l; - zrange(l) = _zc; - } - is_forward = false; - } break; - case 2 : // Segment - case 6 : { - const unsigned int - i0 = (unsigned int)primitive(0), - i1 = (unsigned int)primitive(1); - const tpfloat - x0 = projections(i0,0), y0 = projections(i0,1), z0 = Z + vertices(i0,2), - x1 = projections(i1,0), y1 = projections(i1,1), z1 = Z + vertices(i1,2); - tpfloat xm, xM, ym, yM; - if (x0=0 && xm<_width && yM>=0 && ym<_height && z0>zmin && z1>zmin) { - visibles(l) = (unsigned int)l; - zrange(l) = (z0 + z1)/2; - } - } break; - case 3 : // Triangle - case 9 : { - const unsigned int - i0 = (unsigned int)primitive(0), - i1 = (unsigned int)primitive(1), - i2 = (unsigned int)primitive(2); - const tpfloat - x0 = projections(i0,0), y0 = projections(i0,1), z0 = Z + vertices(i0,2), - x1 = projections(i1,0), y1 = projections(i1,1), z1 = Z + vertices(i1,2), - x2 = projections(i2,0), y2 = projections(i2,1), z2 = Z + vertices(i2,2); - tpfloat xm, xM, ym, yM; - if (x0xM) xM = x2; - if (y0yM) yM = y2; - if (xM>=0 && xm<_width && yM>=0 && ym<_height && z0>zmin && z1>zmin && z2>zmin) { - const tpfloat d = (x1-x0)*(y2-y0) - (x2-x0)*(y1-y0); - if (is_double_sided || d<0) { - visibles(l) = (unsigned int)l; - zrange(l) = (z0 + z1 + z2)/3; - } - } - } break; - case 4 : // Rectangle - case 12 : { - const unsigned int - i0 = (unsigned int)primitive(0), - i1 = (unsigned int)primitive(1), - i2 = (unsigned int)primitive(2), - i3 = (unsigned int)primitive(3); - const tpfloat - x0 = projections(i0,0), y0 = projections(i0,1), z0 = Z + vertices(i0,2), - x1 = projections(i1,0), y1 = projections(i1,1), z1 = Z + vertices(i1,2), - x2 = projections(i2,0), y2 = projections(i2,1), z2 = Z + vertices(i2,2), - x3 = projections(i3,0), y3 = projections(i3,1), z3 = Z + vertices(i3,2); - tpfloat xm, xM, ym, yM; - if (x0xM) xM = x2; - if (x3xM) xM = x3; - if (y0yM) yM = y2; - if (y3yM) yM = y3; - if (xM>=0 && xm<_width && yM>=0 && ym<_height && z0>zmin && z1>zmin && z2>zmin) { - const float d = (x1 - x0)*(y2 - y0) - (x2 - x0)*(y1 - y0); - if (is_double_sided || d<0) { - visibles(l) = (unsigned int)l; - zrange(l) = (z0 + z1 + z2 + z3)/4; - } - } - } break; - default : - if (render_type==5) cimg::mutex(10,0); - throw CImgArgumentException(_cimg_instance - "draw_object3d(): Invalid primitive[%u] with size %u " - "(should have size 1,2,3,4,5,6,9 or 12).", - cimg_instance, - l,primitive.size()); - } - } - - // Force transparent primitives to be drawn last when zbuffer is activated - // (and if object contains no spheres or sprites). - if (is_forward) - cimglist_for(primitives,l) - if (___draw_object3d(opacities,l)!=1) zrange(l) = 2*zmax - zrange(l); - - // Sort only visibles primitives. - unsigned int *p_visibles = visibles._data; - tpfloat *p_zrange = zrange._data; - const tpfloat *ptrz = p_zrange; - cimg_for(visibles,ptr,unsigned int) { - if (*ptr!=~0U) { *(p_visibles++) = *ptr; *(p_zrange++) = *ptrz; } - ++ptrz; - } - const unsigned int nb_visibles = (unsigned int)(p_zrange - zrange._data); - if (!nb_visibles) { - if (render_type==5) cimg::mutex(10,0); - return *this; - } - CImg permutations; - CImg(zrange._data,nb_visibles,1,1,1,true).sort(permutations,is_forward); - - // Compute light properties - CImg lightprops; - switch (render_type) { - case 3 : { // Flat Shading - lightprops.assign(nb_visibles); - cimg_pragma_openmp(parallel for cimg_openmp_if(nb_visibles>4096)) - cimg_forX(lightprops,l) { - const CImg& primitive = primitives(visibles(permutations(l))); - const unsigned int psize = (unsigned int)primitive.size(); - if (psize==3 || psize==4 || psize==9 || psize==12) { - const unsigned int - i0 = (unsigned int)primitive(0), - i1 = (unsigned int)primitive(1), - i2 = (unsigned int)primitive(2); - const tpfloat - x0 = (tpfloat)vertices(i0,0), y0 = (tpfloat)vertices(i0,1), z0 = (tpfloat)vertices(i0,2), - x1 = (tpfloat)vertices(i1,0), y1 = (tpfloat)vertices(i1,1), z1 = (tpfloat)vertices(i1,2), - x2 = (tpfloat)vertices(i2,0), y2 = (tpfloat)vertices(i2,1), z2 = (tpfloat)vertices(i2,2), - dx1 = x1 - x0, dy1 = y1 - y0, dz1 = z1 - z0, - dx2 = x2 - x0, dy2 = y2 - y0, dz2 = z2 - z0, - nx = dy1*dz2 - dz1*dy2, - ny = dz1*dx2 - dx1*dz2, - nz = dx1*dy2 - dy1*dx2, - norm = (tpfloat)std::sqrt(1e-5f + nx*nx + ny*ny + nz*nz), - lx = X + (x0 + x1 + x2)/3 - lightx, - ly = Y + (y0 + y1 + y2)/3 - lighty, - lz = Z + (z0 + z1 + z2)/3 - lightz, - nl = (tpfloat)std::sqrt(1e-5f + lx*lx + ly*ly + lz*lz), - factor = cimg::max(cimg::abs(-lx*nx-ly*ny-lz*nz)/(norm*nl),0); - lightprops[l] = factor<=nspec?factor:(nsl1*factor*factor + nsl2*factor + nsl3); - } else lightprops[l] = 1; - } - } break; - - case 4 : // Gouraud Shading - case 5 : { // Phong-Shading - CImg vertices_normals(vertices._width,6,1,1,0); - cimg_pragma_openmp(parallel for cimg_openmp_if(nb_visibles>4096)) - for (unsigned int l = 0; l& primitive = primitives[visibles(l)]; - const unsigned int psize = (unsigned int)primitive.size(); - const bool - triangle_flag = (psize==3) || (psize==9), - rectangle_flag = (psize==4) || (psize==12); - if (triangle_flag || rectangle_flag) { - const unsigned int - i0 = (unsigned int)primitive(0), - i1 = (unsigned int)primitive(1), - i2 = (unsigned int)primitive(2), - i3 = rectangle_flag?(unsigned int)primitive(3):0; - const tpfloat - x0 = (tpfloat)vertices(i0,0), y0 = (tpfloat)vertices(i0,1), z0 = (tpfloat)vertices(i0,2), - x1 = (tpfloat)vertices(i1,0), y1 = (tpfloat)vertices(i1,1), z1 = (tpfloat)vertices(i1,2), - x2 = (tpfloat)vertices(i2,0), y2 = (tpfloat)vertices(i2,1), z2 = (tpfloat)vertices(i2,2), - dx1 = x1 - x0, dy1 = y1 - y0, dz1 = z1 - z0, - dx2 = x2 - x0, dy2 = y2 - y0, dz2 = z2 - z0, - nnx = dy1*dz2 - dz1*dy2, - nny = dz1*dx2 - dx1*dz2, - nnz = dx1*dy2 - dy1*dx2, - norm = (tpfloat)(1e-5f + std::sqrt(nnx*nnx + nny*nny + nnz*nnz)), - nx = nnx/norm, - ny = nny/norm, - nz = nnz/norm; - unsigned int ix = 0, iy = 1, iz = 2; - if (is_double_sided && nz>0) { ix = 3; iy = 4; iz = 5; } - vertices_normals(i0,ix)+=nx; vertices_normals(i0,iy)+=ny; vertices_normals(i0,iz)+=nz; - vertices_normals(i1,ix)+=nx; vertices_normals(i1,iy)+=ny; vertices_normals(i1,iz)+=nz; - vertices_normals(i2,ix)+=nx; vertices_normals(i2,iy)+=ny; vertices_normals(i2,iz)+=nz; - if (rectangle_flag) { - vertices_normals(i3,ix)+=nx; vertices_normals(i3,iy)+=ny; vertices_normals(i3,iz)+=nz; - } - } - } - - if (is_double_sided) cimg_forX(vertices_normals,p) { - const float - nx0 = vertices_normals(p,0), ny0 = vertices_normals(p,1), nz0 = vertices_normals(p,2), - nx1 = vertices_normals(p,3), ny1 = vertices_normals(p,4), nz1 = vertices_normals(p,5), - n0 = nx0*nx0 + ny0*ny0 + nz0*nz0, n1 = nx1*nx1 + ny1*ny1 + nz1*nz1; - if (n1>n0) { - vertices_normals(p,0) = -nx1; - vertices_normals(p,1) = -ny1; - vertices_normals(p,2) = -nz1; - } - } - - if (render_type==4) { - lightprops.assign(vertices._width); - cimg_pragma_openmp(parallel for cimg_openmp_if(nb_visibles>4096)) - cimg_forX(lightprops,l) { - const tpfloat - nx = vertices_normals(l,0), - ny = vertices_normals(l,1), - nz = vertices_normals(l,2), - norm = (tpfloat)std::sqrt(1e-5f + nx*nx + ny*ny + nz*nz), - lx = X + vertices(l,0) - lightx, - ly = Y + vertices(l,1) - lighty, - lz = Z + vertices(l,2) - lightz, - nl = (tpfloat)std::sqrt(1e-5f + lx*lx + ly*ly + lz*lz), - factor = cimg::max((-lx*nx-ly*ny-lz*nz)/(norm*nl),0); - lightprops[l] = factor<=nspec?factor:(nsl1*factor*factor + nsl2*factor + nsl3); - } - } else { - const unsigned int - lw2 = light_texture._width/2 - 1, - lh2 = light_texture._height/2 - 1; - lightprops.assign(vertices._width,2); - cimg_pragma_openmp(parallel for cimg_openmp_if(nb_visibles>4096)) - cimg_forX(lightprops,l) { - const tpfloat - nx = vertices_normals(l,0), - ny = vertices_normals(l,1), - nz = vertices_normals(l,2), - norm = (tpfloat)std::sqrt(1e-5f + nx*nx + ny*ny + nz*nz), - nnx = nx/norm, - nny = ny/norm; - lightprops(l,0) = lw2*(1 + nnx); - lightprops(l,1) = lh2*(1 + nny); - } - } - } break; - } - - // Draw visible primitives - const CImg default_color(1,_spectrum,1,1,(tc)200); - CImg<_to> _opacity; - - for (unsigned int l = 0; l& primitive = primitives[n_primitive]; - const CImg - &__color = n_primitive(), - _color = (__color && __color.size()!=_spectrum && __color._spectrum<_spectrum)? - __color.get_resize(-100,-100,-100,_spectrum,0):CImg(), - &color = _color?_color:(__color?__color:default_color); - const tc *const pcolor = color._data; - const float opacity = __draw_object3d(opacities,n_primitive,_opacity); - -#ifdef cimg_use_board - LibBoard::Board &board = *(LibBoard::Board*)pboard; -#endif - - switch (primitive.size()) { - case 1 : { // Colored point or sprite - const unsigned int n0 = (unsigned int)primitive[0]; - const int x0 = (int)projections(n0,0), y0 = (int)projections(n0,1); - - if (_opacity.is_empty()) { // Scalar opacity. - - if (color.size()==_spectrum) { // Colored point. - draw_point(x0,y0,pcolor,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(color[0],color[1],color[2],(unsigned char)(opacity*255)); - board.drawDot((float)x0,height()-(float)y0); - } -#endif - } else { // Sprite. - const tpfloat z = Z + vertices(n0,2); - const float factor = focale<0?1:sprite_scale*(absfocale?absfocale/(z + absfocale):1); - const unsigned int - _sw = (unsigned int)(color._width*factor), - _sh = (unsigned int)(color._height*factor), - sw = _sw?_sw:1, sh = _sh?_sh:1; - const int nx0 = x0 - (int)sw/2, ny0 = y0 - (int)sh/2; - if (sw<=3*_width/2 && sh<=3*_height/2 && - (nx0 + (int)sw/2>=0 || nx0 - (int)sw/2=0 || ny0 - (int)sh/2 - _sprite = (sw!=color._width || sh!=color._height)? - color.get_resize(sw,sh,1,-100,render_type<=3?1:3):CImg(), - &sprite = _sprite?_sprite:color; - draw_image(nx0,ny0,sprite,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(128,128,128); - board.setFillColor(LibBoard::Color::Null); - board.drawRectangle((float)nx0,height() - (float)ny0,sw,sh); - } -#endif - } - } - } else { // Opacity mask. - const tpfloat z = Z + vertices(n0,2); - const float factor = focale<0?1:sprite_scale*(absfocale?absfocale/(z + absfocale):1); - const unsigned int - _sw = (unsigned int)(cimg::max(color._width,_opacity._width)*factor), - _sh = (unsigned int)(cimg::max(color._height,_opacity._height)*factor), - sw = _sw?_sw:1, sh = _sh?_sh:1; - const int nx0 = x0 - (int)sw/2, ny0 = y0 - (int)sh/2; - if (sw<=3*_width/2 && sh<=3*_height/2 && - (nx0 + (int)sw/2>=0 || nx0 - (int)sw/2=0 || ny0 - (int)sh/2 - _sprite = (sw!=color._width || sh!=color._height)? - color.get_resize(sw,sh,1,-100,render_type<=3?1:3):CImg(), - &sprite = _sprite?_sprite:color; - const CImg<_to> - _nopacity = (sw!=_opacity._width || sh!=_opacity._height)? - _opacity.get_resize(sw,sh,1,-100,render_type<=3?1:3):CImg<_to>(), - &nopacity = _nopacity?_nopacity:_opacity; - draw_image(nx0,ny0,sprite,nopacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(128,128,128); - board.setFillColor(LibBoard::Color::Null); - board.drawRectangle((float)nx0,height() - (float)ny0,sw,sh); - } -#endif - } - } - } break; - case 2 : { // Colored line - const unsigned int - n0 = (unsigned int)primitive[0], - n1 = (unsigned int)primitive[1]; - const int - x0 = (int)projections(n0,0), y0 = (int)projections(n0,1), - x1 = (int)projections(n1,0), y1 = (int)projections(n1,1); - const float - z0 = vertices(n0,2) + Z + _focale, - z1 = vertices(n1,2) + Z + _focale; - if (render_type) { - if (zbuffer) draw_line(zbuffer,x0,y0,z0,x1,y1,z1,pcolor,opacity); - else draw_line(x0,y0,x1,y1,pcolor,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(color[0],color[1],color[2],(unsigned char)(opacity*255)); - board.drawLine((float)x0,height() - (float)y0,x1,height() - (float)y1); - } -#endif - } else { - draw_point(x0,y0,pcolor,opacity).draw_point(x1,y1,pcolor,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(color[0],color[1],color[2],(unsigned char)(opacity*255)); - board.drawDot((float)x0,height() - (float)y0); - board.drawDot((float)x1,height() - (float)y1); - } -#endif - } - } break; - case 5 : { // Colored sphere - const unsigned int - n0 = (unsigned int)primitive[0], - n1 = (unsigned int)primitive[1], - is_wireframe = (unsigned int)primitive[2]; - const float - Xc = 0.5f*((float)vertices(n0,0) + (float)vertices(n1,0)), - Yc = 0.5f*((float)vertices(n0,1) + (float)vertices(n1,1)), - Zc = 0.5f*((float)vertices(n0,2) + (float)vertices(n1,2)), - zc = Z + Zc + _focale, - xc = X + Xc*(absfocale?absfocale/zc:1), - yc = Y + Yc*(absfocale?absfocale/zc:1), - radius = 0.5f*std::sqrt(cimg::sqr(vertices(n1,0) - vertices(n0,0)) + - cimg::sqr(vertices(n1,1) - vertices(n0,1)) + - cimg::sqr(vertices(n1,2) - vertices(n0,2)))*(absfocale?absfocale/zc:1); - switch (render_type) { - case 0 : - draw_point((int)xc,(int)yc,pcolor,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(color[0],color[1],color[2],(unsigned char)(opacity*255)); - board.drawDot(xc,height() - yc); - } -#endif - break; - case 1 : - draw_circle((int)xc,(int)yc,(int)radius,pcolor,opacity,~0U); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(color[0],color[1],color[2],(unsigned char)(opacity*255)); - board.setFillColor(LibBoard::Color::Null); - board.drawCircle(xc,height() - yc,radius); - } -#endif - break; - default : - if (is_wireframe) draw_circle((int)xc,(int)yc,(int)radius,pcolor,opacity,~0U); - else draw_circle((int)xc,(int)yc,(int)radius,pcolor,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(color[0],color[1],color[2],(unsigned char)(opacity*255)); - if (!is_wireframe) board.fillCircle(xc,height() - yc,radius); - else { - board.setFillColor(LibBoard::Color::Null); - board.drawCircle(xc,height() - yc,radius); - } - } -#endif - break; - } - } break; - case 6 : { // Textured line - if (!__color) { - if (render_type==5) cimg::mutex(10,0); - throw CImgArgumentException(_cimg_instance - "draw_object3d(): Undefined texture for line primitive [%u].", - cimg_instance,n_primitive); - } - const unsigned int - n0 = (unsigned int)primitive[0], - n1 = (unsigned int)primitive[1]; - const int - tx0 = (int)primitive[2], ty0 = (int)primitive[3], - tx1 = (int)primitive[4], ty1 = (int)primitive[5], - x0 = (int)projections(n0,0), y0 = (int)projections(n0,1), - x1 = (int)projections(n1,0), y1 = (int)projections(n1,1); - const float - z0 = vertices(n0,2) + Z + _focale, - z1 = vertices(n1,2) + Z + _focale; - if (render_type) { - if (zbuffer) draw_line(zbuffer,x0,y0,z0,x1,y1,z1,color,tx0,ty0,tx1,ty1,opacity); - else draw_line(x0,y0,x1,y1,color,tx0,ty0,tx1,ty1,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(128,128,128,(unsigned char)(opacity*255)); - board.drawLine((float)x0,height() - (float)y0,(float)x1,height() - (float)y1); - } -#endif - } else { - draw_point(x0,y0,color.get_vector_at(tx0<=0?0:tx0>=color.width()?color.width() - 1:tx0, - ty0<=0?0:ty0>=color.height()?color.height() - 1:ty0)._data,opacity). - draw_point(x1,y1,color.get_vector_at(tx1<=0?0:tx1>=color.width()?color.width() - 1:tx1, - ty1<=0?0:ty1>=color.height()?color.height() - 1:ty1)._data,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(128,128,128,(unsigned char)(opacity*255)); - board.drawDot((float)x0,height() - (float)y0); - board.drawDot((float)x1,height() - (float)y1); - } -#endif - } - } break; - case 3 : { // Colored triangle - const unsigned int - n0 = (unsigned int)primitive[0], - n1 = (unsigned int)primitive[1], - n2 = (unsigned int)primitive[2]; - const int - x0 = (int)projections(n0,0), y0 = (int)projections(n0,1), - x1 = (int)projections(n1,0), y1 = (int)projections(n1,1), - x2 = (int)projections(n2,0), y2 = (int)projections(n2,1); - const float - z0 = vertices(n0,2) + Z + _focale, - z1 = vertices(n1,2) + Z + _focale, - z2 = vertices(n2,2) + Z + _focale; - switch (render_type) { - case 0 : - draw_point(x0,y0,pcolor,opacity).draw_point(x1,y1,pcolor,opacity).draw_point(x2,y2,pcolor,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(color[0],color[1],color[2],(unsigned char)(opacity*255)); - board.drawDot((float)x0,height() - (float)y0); - board.drawDot((float)x1,height() - (float)y1); - board.drawDot((float)x2,height() - (float)y2); - } -#endif - break; - case 1 : - if (zbuffer) - draw_line(zbuffer,x0,y0,z0,x1,y1,z1,pcolor,opacity).draw_line(zbuffer,x0,y0,z0,x2,y2,z2,pcolor,opacity). - draw_line(zbuffer,x1,y1,z1,x2,y2,z2,pcolor,opacity); - else - draw_line(x0,y0,x1,y1,pcolor,opacity).draw_line(x0,y0,x2,y2,pcolor,opacity). - draw_line(x1,y1,x2,y2,pcolor,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(color[0],color[1],color[2],(unsigned char)(opacity*255)); - board.drawLine((float)x0,height() - (float)y0,(float)x1,height() - (float)y1); - board.drawLine((float)x0,height() - (float)y0,(float)x2,height() - (float)y2); - board.drawLine((float)x1,height() - (float)y1,(float)x2,height() - (float)y2); - } -#endif - break; - case 2 : - if (zbuffer) draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,pcolor,opacity); - else draw_triangle(x0,y0,x1,y1,x2,y2,pcolor,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(color[0],color[1],color[2],(unsigned char)(opacity*255)); - board.fillTriangle((float)x0,height() - (float)y0, - (float)x1,height() - (float)y1, - (float)x2,height() - (float)y2); - } -#endif - break; - case 3 : - if (zbuffer) draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,pcolor,opacity,lightprops(l)); - else _draw_triangle(x0,y0,x1,y1,x2,y2,pcolor,opacity,lightprops(l)); -#ifdef cimg_use_board - if (pboard) { - const float lp = cimg::min(lightprops(l),1); - board.setPenColorRGBi((unsigned char)(color[0]*lp), - (unsigned char)(color[1]*lp), - (unsigned char)(color[2]*lp), - (unsigned char)(opacity*255)); - board.fillTriangle((float)x0,height() - (float)y0, - (float)x1,height() - (float)y1, - (float)x2,height() - (float)y2); - } -#endif - break; - case 4 : - if (zbuffer) - draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,pcolor, - lightprops(n0),lightprops(n1),lightprops(n2),opacity); - else draw_triangle(x0,y0,x1,y1,x2,y2,pcolor,lightprops(n0),lightprops(n1),lightprops(n2),opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi((unsigned char)(color[0]), - (unsigned char)(color[1]), - (unsigned char)(color[2]), - (unsigned char)(opacity*255)); - board.fillGouraudTriangle((float)x0,height() - (float)y0,lightprops(n0), - (float)x1,height() - (float)y1,lightprops(n1), - (float)x2,height() - (float)y2,lightprops(n2)); - } -#endif - break; - case 5 : { - const unsigned int - lx0 = (unsigned int)lightprops(n0,0), ly0 = (unsigned int)lightprops(n0,1), - lx1 = (unsigned int)lightprops(n1,0), ly1 = (unsigned int)lightprops(n1,1), - lx2 = (unsigned int)lightprops(n2,0), ly2 = (unsigned int)lightprops(n2,1); - if (zbuffer) - draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,pcolor,light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opacity); - else draw_triangle(x0,y0,x1,y1,x2,y2,pcolor,light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opacity); -#ifdef cimg_use_board - if (pboard) { - const float - l0 = light_texture((int)(light_texture.width()/2*(1 + lightprops(n0,0))), - (int)(light_texture.height()/2*(1 + lightprops(n0,1)))), - l1 = light_texture((int)(light_texture.width()/2*(1 + lightprops(n1,0))), - (int)(light_texture.height()/2*(1 + lightprops(n1,1)))), - l2 = light_texture((int)(light_texture.width()/2*(1 + lightprops(n2,0))), - (int)(light_texture.height()/2*(1 + lightprops(n2,1)))); - board.setPenColorRGBi((unsigned char)(color[0]), - (unsigned char)(color[1]), - (unsigned char)(color[2]), - (unsigned char)(opacity*255)); - board.fillGouraudTriangle((float)x0,height() - (float)y0,l0, - (float)x1,height() - (float)y1,l1, - (float)x2,height() - (float)y2,l2); - } -#endif - } break; - } - } break; - case 4 : { // Colored rectangle - const unsigned int - n0 = (unsigned int)primitive[0], - n1 = (unsigned int)primitive[1], - n2 = (unsigned int)primitive[2], - n3 = (unsigned int)primitive[3]; - const int - x0 = (int)projections(n0,0), y0 = (int)projections(n0,1), - x1 = (int)projections(n1,0), y1 = (int)projections(n1,1), - x2 = (int)projections(n2,0), y2 = (int)projections(n2,1), - x3 = (int)projections(n3,0), y3 = (int)projections(n3,1); - const float - z0 = vertices(n0,2) + Z + _focale, - z1 = vertices(n1,2) + Z + _focale, - z2 = vertices(n2,2) + Z + _focale, - z3 = vertices(n3,2) + Z + _focale; - - switch (render_type) { - case 0 : - draw_point(x0,y0,pcolor,opacity).draw_point(x1,y1,pcolor,opacity). - draw_point(x2,y2,pcolor,opacity).draw_point(x3,y3,pcolor,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(color[0],color[1],color[2],(unsigned char)(opacity*255)); - board.drawDot((float)x0,height() - (float)y0); - board.drawDot((float)x1,height() - (float)y1); - board.drawDot((float)x2,height() - (float)y2); - board.drawDot((float)x3,height() - (float)y3); - } -#endif - break; - case 1 : - if (zbuffer) - draw_line(zbuffer,x0,y0,z0,x1,y1,z1,pcolor,opacity).draw_line(zbuffer,x1,y1,z1,x2,y2,z2,pcolor,opacity). - draw_line(zbuffer,x2,y2,z2,x3,y3,z3,pcolor,opacity).draw_line(zbuffer,x3,y3,z3,x0,y0,z0,pcolor,opacity); - else - draw_line(x0,y0,x1,y1,pcolor,opacity).draw_line(x1,y1,x2,y2,pcolor,opacity). - draw_line(x2,y2,x3,y3,pcolor,opacity).draw_line(x3,y3,x0,y0,pcolor,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(color[0],color[1],color[2],(unsigned char)(opacity*255)); - board.drawLine((float)x0,height() - (float)y0,(float)x1,height() - (float)y1); - board.drawLine((float)x1,height() - (float)y1,(float)x2,height() - (float)y2); - board.drawLine((float)x2,height() - (float)y2,(float)x3,height() - (float)y3); - board.drawLine((float)x3,height() - (float)y3,(float)x0,height() - (float)y0); - } -#endif - break; - case 2 : - if (zbuffer) - draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,pcolor,opacity). - draw_triangle(zbuffer,x0,y0,z0,x2,y2,z2,x3,y3,z3,pcolor,opacity); - else - draw_triangle(x0,y0,x1,y1,x2,y2,pcolor,opacity).draw_triangle(x0,y0,x2,y2,x3,y3,pcolor,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(color[0],color[1],color[2],(unsigned char)(opacity*255)); - board.fillTriangle((float)x0,height() - (float)y0, - (float)x1,height() - (float)y1, - (float)x2,height() - (float)y2); - board.fillTriangle((float)x0,height() - (float)y0, - (float)x2,height() - (float)y2, - (float)x3,height() - (float)y3); - } -#endif - break; - case 3 : - if (zbuffer) - draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,pcolor,opacity,lightprops(l)). - draw_triangle(zbuffer,x0,y0,z0,x2,y2,z2,x3,y3,z3,pcolor,opacity,lightprops(l)); - else - _draw_triangle(x0,y0,x1,y1,x2,y2,pcolor,opacity,lightprops(l)). - _draw_triangle(x0,y0,x2,y2,x3,y3,pcolor,opacity,lightprops(l)); -#ifdef cimg_use_board - if (pboard) { - const float lp = cimg::min(lightprops(l),1); - board.setPenColorRGBi((unsigned char)(color[0]*lp), - (unsigned char)(color[1]*lp), - (unsigned char)(color[2]*lp),(unsigned char)(opacity*255)); - board.fillTriangle((float)x0,height() - (float)y0, - (float)x1,height() - (float)y1, - (float)x2,height() - (float)y2); - board.fillTriangle((float)x0,height() - (float)y0, - (float)x2,height() - (float)y2, - (float)x3,height() - (float)y3); - } -#endif - break; - case 4 : { - const float - lightprop0 = lightprops(n0), lightprop1 = lightprops(n1), - lightprop2 = lightprops(n2), lightprop3 = lightprops(n3); - if (zbuffer) - draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,pcolor,lightprop0,lightprop1,lightprop2,opacity). - draw_triangle(zbuffer,x0,y0,z0,x2,y2,z2,x3,y3,z3,pcolor,lightprop0,lightprop2,lightprop3,opacity); - else - draw_triangle(x0,y0,x1,y1,x2,y2,pcolor,lightprop0,lightprop1,lightprop2,opacity). - draw_triangle(x0,y0,x2,y2,x3,y3,pcolor,lightprop0,lightprop2,lightprop3,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi((unsigned char)(color[0]), - (unsigned char)(color[1]), - (unsigned char)(color[2]), - (unsigned char)(opacity*255)); - board.fillGouraudTriangle((float)x0,height() - (float)y0,lightprop0, - (float)x1,height() - (float)y1,lightprop1, - (float)x2,height() - (float)y2,lightprop2); - board.fillGouraudTriangle((float)x0,height() - (float)y0,lightprop0, - (float)x2,height() - (float)y2,lightprop2, - (float)x3,height() - (float)y3,lightprop3); - } -#endif - } break; - case 5 : { - const unsigned int - lx0 = (unsigned int)lightprops(n0,0), ly0 = (unsigned int)lightprops(n0,1), - lx1 = (unsigned int)lightprops(n1,0), ly1 = (unsigned int)lightprops(n1,1), - lx2 = (unsigned int)lightprops(n2,0), ly2 = (unsigned int)lightprops(n2,1), - lx3 = (unsigned int)lightprops(n3,0), ly3 = (unsigned int)lightprops(n3,1); - if (zbuffer) - draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,pcolor,light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opacity). - draw_triangle(zbuffer,x0,y0,z0,x2,y2,z2,x3,y3,z3,pcolor,light_texture,lx0,ly0,lx2,ly2,lx3,ly3,opacity); - else - draw_triangle(x0,y0,x1,y1,x2,y2,pcolor,light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opacity). - draw_triangle(x0,y0,x2,y2,x3,y3,pcolor,light_texture,lx0,ly0,lx2,ly2,lx3,ly3,opacity); -#ifdef cimg_use_board - if (pboard) { - const float - l0 = light_texture((int)(light_texture.width()/2*(1 + lx0)), (int)(light_texture.height()/2*(1 + ly0))), - l1 = light_texture((int)(light_texture.width()/2*(1 + lx1)), (int)(light_texture.height()/2*(1 + ly1))), - l2 = light_texture((int)(light_texture.width()/2*(1 + lx2)), (int)(light_texture.height()/2*(1 + ly2))), - l3 = light_texture((int)(light_texture.width()/2*(1 + lx3)), (int)(light_texture.height()/2*(1 + ly3))); - board.setPenColorRGBi((unsigned char)(color[0]), - (unsigned char)(color[1]), - (unsigned char)(color[2]), - (unsigned char)(opacity*255)); - board.fillGouraudTriangle((float)x0,height() - (float)y0,l0, - (float)x1,height() - (float)y1,l1, - (float)x2,height() - (float)y2,l2); - board.fillGouraudTriangle((float)x0,height() - (float)y0,l0, - (float)x2,height() - (float)y2,l2, - (float)x3,height() - (float)y3,l3); - } -#endif - } break; - } - } break; - case 9 : { // Textured triangle - if (!__color) { - if (render_type==5) cimg::mutex(10,0); - throw CImgArgumentException(_cimg_instance - "draw_object3d(): Undefined texture for triangle primitive [%u].", - cimg_instance,n_primitive); - } - const unsigned int - n0 = (unsigned int)primitive[0], - n1 = (unsigned int)primitive[1], - n2 = (unsigned int)primitive[2]; - const int - tx0 = (int)primitive[3], ty0 = (int)primitive[4], - tx1 = (int)primitive[5], ty1 = (int)primitive[6], - tx2 = (int)primitive[7], ty2 = (int)primitive[8], - x0 = (int)projections(n0,0), y0 = (int)projections(n0,1), - x1 = (int)projections(n1,0), y1 = (int)projections(n1,1), - x2 = (int)projections(n2,0), y2 = (int)projections(n2,1); - const float - z0 = vertices(n0,2) + Z + _focale, - z1 = vertices(n1,2) + Z + _focale, - z2 = vertices(n2,2) + Z + _focale; - switch (render_type) { - case 0 : - draw_point(x0,y0,color.get_vector_at(tx0<=0?0:tx0>=color.width()?color.width() - 1:tx0, - ty0<=0?0:ty0>=color.height()?color.height() - 1:ty0)._data,opacity). - draw_point(x1,y1,color.get_vector_at(tx1<=0?0:tx1>=color.width()?color.width() - 1:tx1, - ty1<=0?0:ty1>=color.height()?color.height() - 1:ty1)._data,opacity). - draw_point(x2,y2,color.get_vector_at(tx2<=0?0:tx2>=color.width()?color.width() - 1:tx2, - ty2<=0?0:ty2>=color.height()?color.height() - 1:ty2)._data,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(128,128,128,(unsigned char)(opacity*255)); - board.drawDot((float)x0,height() - (float)y0); - board.drawDot((float)x1,height() - (float)y1); - board.drawDot((float)x2,height() - (float)y2); - } -#endif - break; - case 1 : - if (zbuffer) - draw_line(zbuffer,x0,y0,z0,x1,y1,z1,color,tx0,ty0,tx1,ty1,opacity). - draw_line(zbuffer,x0,y0,z0,x2,y2,z2,color,tx0,ty0,tx2,ty2,opacity). - draw_line(zbuffer,x1,y1,z1,x2,y2,z2,color,tx1,ty1,tx2,ty2,opacity); - else - draw_line(x0,y0,z0,x1,y1,z1,color,tx0,ty0,tx1,ty1,opacity). - draw_line(x0,y0,z0,x2,y2,z2,color,tx0,ty0,tx2,ty2,opacity). - draw_line(x1,y1,z1,x2,y2,z2,color,tx1,ty1,tx2,ty2,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(128,128,128,(unsigned char)(opacity*255)); - board.drawLine((float)x0,height() - (float)y0,(float)x1,height() - (float)y1); - board.drawLine((float)x0,height() - (float)y0,(float)x2,height() - (float)y2); - board.drawLine((float)x1,height() - (float)y1,(float)x2,height() - (float)y2); - } -#endif - break; - case 2 : - if (zbuffer) draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opacity); - else draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(128,128,128,(unsigned char)(opacity*255)); - board.fillTriangle((float)x0,height() - (float)y0, - (float)x1,height() - (float)y1, - (float)x2,height() - (float)y2); - } -#endif - break; - case 3 : - if (zbuffer) - draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opacity,lightprops(l)); - else draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opacity,lightprops(l)); -#ifdef cimg_use_board - if (pboard) { - const float lp = cimg::min(lightprops(l),1); - board.setPenColorRGBi((unsigned char)(128*lp), - (unsigned char)(128*lp), - (unsigned char)(128*lp), - (unsigned char)(opacity*255)); - board.fillTriangle((float)x0,height() - (float)y0, - (float)x1,height() - (float)y1, - (float)x2,height() - (float)y2); - } -#endif - break; - case 4 : - if (zbuffer) - draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2, - lightprops(n0),lightprops(n1),lightprops(n2),opacity); - else - draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2, - lightprops(n0),lightprops(n1),lightprops(n2),opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(128,128,128,(unsigned char)(opacity*255)); - board.fillGouraudTriangle((float)x0,height() - (float)y0,lightprops(n0), - (float)x1,height() - (float)y1,lightprops(n1), - (float)x2,height() - (float)y2,lightprops(n2)); - } -#endif - break; - case 5 : - if (zbuffer) - draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,light_texture, - (unsigned int)lightprops(n0,0),(unsigned int)lightprops(n0,1), - (unsigned int)lightprops(n1,0),(unsigned int)lightprops(n1,1), - (unsigned int)lightprops(n2,0),(unsigned int)lightprops(n2,1), - opacity); - else - draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,light_texture, - (unsigned int)lightprops(n0,0),(unsigned int)lightprops(n0,1), - (unsigned int)lightprops(n1,0),(unsigned int)lightprops(n1,1), - (unsigned int)lightprops(n2,0),(unsigned int)lightprops(n2,1), - opacity); -#ifdef cimg_use_board - if (pboard) { - const float - l0 = light_texture((int)(light_texture.width()/2*(1 + lightprops(n0,0))), - (int)(light_texture.height()/2*(1 + lightprops(n0,1)))), - l1 = light_texture((int)(light_texture.width()/2*(1 + lightprops(n1,0))), - (int)(light_texture.height()/2*(1 + lightprops(n1,1)))), - l2 = light_texture((int)(light_texture.width()/2*(1 + lightprops(n2,0))), - (int)(light_texture.height()/2*(1 + lightprops(n2,1)))); - board.setPenColorRGBi(128,128,128,(unsigned char)(opacity*255)); - board.fillGouraudTriangle((float)x0,height() - (float)y0,l0, - (float)x1,height() - (float)y1,l1, - (float)x2,height() - (float)y2,l2); - } -#endif - break; - } - } break; - case 12 : { // Textured quadrangle - if (!__color) { - if (render_type==5) cimg::mutex(10,0); - throw CImgArgumentException(_cimg_instance - "draw_object3d(): Undefined texture for quadrangle primitive [%u].", - cimg_instance,n_primitive); - } - const unsigned int - n0 = (unsigned int)primitive[0], - n1 = (unsigned int)primitive[1], - n2 = (unsigned int)primitive[2], - n3 = (unsigned int)primitive[3]; - const int - tx0 = (int)primitive[4], ty0 = (int)primitive[5], - tx1 = (int)primitive[6], ty1 = (int)primitive[7], - tx2 = (int)primitive[8], ty2 = (int)primitive[9], - tx3 = (int)primitive[10], ty3 = (int)primitive[11], - x0 = (int)projections(n0,0), y0 = (int)projections(n0,1), - x1 = (int)projections(n1,0), y1 = (int)projections(n1,1), - x2 = (int)projections(n2,0), y2 = (int)projections(n2,1), - x3 = (int)projections(n3,0), y3 = (int)projections(n3,1); - const float - z0 = vertices(n0,2) + Z + _focale, - z1 = vertices(n1,2) + Z + _focale, - z2 = vertices(n2,2) + Z + _focale, - z3 = vertices(n3,2) + Z + _focale; - - switch (render_type) { - case 0 : - draw_point(x0,y0,color.get_vector_at(tx0<=0?0:tx0>=color.width()?color.width() - 1:tx0, - ty0<=0?0:ty0>=color.height()?color.height() - 1:ty0)._data,opacity). - draw_point(x1,y1,color.get_vector_at(tx1<=0?0:tx1>=color.width()?color.width() - 1:tx1, - ty1<=0?0:ty1>=color.height()?color.height() - 1:ty1)._data,opacity). - draw_point(x2,y2,color.get_vector_at(tx2<=0?0:tx2>=color.width()?color.width() - 1:tx2, - ty2<=0?0:ty2>=color.height()?color.height() - 1:ty2)._data,opacity). - draw_point(x3,y3,color.get_vector_at(tx3<=0?0:tx3>=color.width()?color.width() - 1:tx3, - ty3<=0?0:ty3>=color.height()?color.height() - 1:ty3)._data,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(128,128,128,(unsigned char)(opacity*255)); - board.drawDot((float)x0,height() - (float)y0); - board.drawDot((float)x1,height() - (float)y1); - board.drawDot((float)x2,height() - (float)y2); - board.drawDot((float)x3,height() - (float)y3); - } -#endif - break; - case 1 : - if (zbuffer) - draw_line(zbuffer,x0,y0,z0,x1,y1,z1,color,tx0,ty0,tx1,ty1,opacity). - draw_line(zbuffer,x1,y1,z1,x2,y2,z2,color,tx1,ty1,tx2,ty2,opacity). - draw_line(zbuffer,x2,y2,z2,x3,y3,z3,color,tx2,ty2,tx3,ty3,opacity). - draw_line(zbuffer,x3,y3,z3,x0,y0,z0,color,tx3,ty3,tx0,ty0,opacity); - else - draw_line(x0,y0,z0,x1,y1,z1,color,tx0,ty0,tx1,ty1,opacity). - draw_line(x1,y1,z1,x2,y2,z2,color,tx1,ty1,tx2,ty2,opacity). - draw_line(x2,y2,z2,x3,y3,z3,color,tx2,ty2,tx3,ty3,opacity). - draw_line(x3,y3,z3,x0,y0,z0,color,tx3,ty3,tx0,ty0,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(128,128,128,(unsigned char)(opacity*255)); - board.drawLine((float)x0,height() - (float)y0,(float)x1,height() - (float)y1); - board.drawLine((float)x1,height() - (float)y1,(float)x2,height() - (float)y2); - board.drawLine((float)x2,height() - (float)y2,(float)x3,height() - (float)y3); - board.drawLine((float)x3,height() - (float)y3,(float)x0,height() - (float)y0); - } -#endif - break; - case 2 : - if (zbuffer) - draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opacity). - draw_triangle(zbuffer,x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,opacity); - else - draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opacity). - draw_triangle(x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(128,128,128,(unsigned char)(opacity*255)); - board.fillTriangle((float)x0,height() - (float)y0, - (float)x1,height() - (float)y1, - (float)x2,height() - (float)y2); - board.fillTriangle((float)x0,height() - (float)y0, - (float)x2,height() - (float)y2, - (float)x3,height() - (float)y3); - } -#endif - break; - case 3 : - if (zbuffer) - draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opacity,lightprops(l)). - draw_triangle(zbuffer,x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,opacity,lightprops(l)); - else - draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opacity,lightprops(l)). - draw_triangle(x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,opacity,lightprops(l)); -#ifdef cimg_use_board - if (pboard) { - const float lp = cimg::min(lightprops(l),1); - board.setPenColorRGBi((unsigned char)(128*lp), - (unsigned char)(128*lp), - (unsigned char)(128*lp), - (unsigned char)(opacity*255)); - board.fillTriangle((float)x0,height() - (float)y0, - (float)x1,height() - (float)y1, - (float)x2,height() - (float)y2); - board.fillTriangle((float)x0,height() - (float)y0, - (float)x2,height() - (float)y2, - (float)x3,height() - (float)y3); - } -#endif - break; - case 4 : { - const float - lightprop0 = lightprops(n0), lightprop1 = lightprops(n1), - lightprop2 = lightprops(n2), lightprop3 = lightprops(n3); - if (zbuffer) - draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2, - lightprop0,lightprop1,lightprop2,opacity). - draw_triangle(zbuffer,x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3, - lightprop0,lightprop2,lightprop3,opacity); - else - draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2, - lightprop0,lightprop1,lightprop2,opacity). - draw_triangle(x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3, - lightprop0,lightprop2,lightprop3,opacity); -#ifdef cimg_use_board - if (pboard) { - board.setPenColorRGBi(128,128,128,(unsigned char)(opacity*255)); - board.fillGouraudTriangle((float)x0,height() - (float)y0,lightprop0, - (float)x1,height() - (float)y1,lightprop1, - (float)x2,height() - (float)y2,lightprop2); - board.fillGouraudTriangle((float)x0,height() -(float)y0,lightprop0, - (float)x2,height() - (float)y2,lightprop2, - (float)x3,height() - (float)y3,lightprop3); - } -#endif - } break; - case 5 : { - const unsigned int - lx0 = (unsigned int)lightprops(n0,0), ly0 = (unsigned int)lightprops(n0,1), - lx1 = (unsigned int)lightprops(n1,0), ly1 = (unsigned int)lightprops(n1,1), - lx2 = (unsigned int)lightprops(n2,0), ly2 = (unsigned int)lightprops(n2,1), - lx3 = (unsigned int)lightprops(n3,0), ly3 = (unsigned int)lightprops(n3,1); - if (zbuffer) - draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2, - light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opacity). - draw_triangle(zbuffer,x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3, - light_texture,lx0,ly0,lx2,ly2,lx3,ly3,opacity); - else - draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2, - light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opacity). - draw_triangle(x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3, - light_texture,lx0,ly0,lx2,ly2,lx3,ly3,opacity); -#ifdef cimg_use_board - if (pboard) { - const float - l0 = light_texture((int)(light_texture.width()/2*(1 + lx0)), (int)(light_texture.height()/2*(1 + ly0))), - l1 = light_texture((int)(light_texture.width()/2*(1 + lx1)), (int)(light_texture.height()/2*(1 + ly1))), - l2 = light_texture((int)(light_texture.width()/2*(1 + lx2)), (int)(light_texture.height()/2*(1 + ly2))), - l3 = light_texture((int)(light_texture.width()/2*(1 + lx3)), (int)(light_texture.height()/2*(1 + ly3))); - board.setPenColorRGBi(128,128,128,(unsigned char)(opacity*255)); - board.fillGouraudTriangle((float)x0,height() - (float)y0,l0, - (float)x1,height() - (float)y1,l1, - (float)x2,height() - (float)y2,l2); - board.fillGouraudTriangle((float)x0,height() -(float)y0,l0, - (float)x2,height() - (float)y2,l2, - (float)x3,height() - (float)y3,l3); - } -#endif - } break; - } - } break; - } - } - - if (render_type==5) cimg::mutex(10,0); - return *this; - } - - //@} - //--------------------------- - // - //! \name Data Input - //@{ - //--------------------------- - - //! Launch simple interface to select a shape from an image. - /** - \param disp Display window to use. - \param feature_type Type of feature to select. Can be { 0=point | 1=line | 2=rectangle | 3=ellipse }. - \param XYZ Pointer to 3 values X,Y,Z which tells about the projection point coordinates, for volumetric images. - **/ - CImg& select(CImgDisplay &disp, - const unsigned int feature_type=2, unsigned int *const XYZ=0, - const bool exit_on_anykey=false) { - return get_select(disp,feature_type,XYZ,exit_on_anykey).move_to(*this); - } - - //! Simple interface to select a shape from an image \overloading. - CImg& select(const char *const title, - const unsigned int feature_type=2, unsigned int *const XYZ=0, - const bool exit_on_anykey=false) { - return get_select(title,feature_type,XYZ,exit_on_anykey).move_to(*this); - } - - //! Simple interface to select a shape from an image \newinstance. - CImg get_select(CImgDisplay &disp, - const unsigned int feature_type=2, unsigned int *const XYZ=0, - const bool exit_on_anykey=false) const { - return _get_select(disp,0,feature_type,XYZ,0,0,0,exit_on_anykey,true,false); - } - - //! Simple interface to select a shape from an image \newinstance. - CImg get_select(const char *const title, - const unsigned int feature_type=2, unsigned int *const XYZ=0, - const bool exit_on_anykey=false) const { - CImgDisplay disp; - return _get_select(disp,title,feature_type,XYZ,0,0,0,exit_on_anykey,true,false); - } - - CImg _get_select(CImgDisplay &disp, const char *const title, - const unsigned int feature_type, unsigned int *const XYZ, - const int origX, const int origY, const int origZ, - const bool exit_on_anykey, - const bool reset_view3d, - const bool force_display_z_coord) const { - if (is_empty()) return CImg(1,feature_type==0?3:6,1,1,-1); - if (!disp) { - disp.assign(cimg_fitscreen(_width,_height,_depth),title?title:0,1); - if (!title) disp.set_title("CImg<%s> (%ux%ux%ux%u)",pixel_type(),_width,_height,_depth,_spectrum); - } else if (title) disp.set_title("%s",title); - - CImg thumb; - if (width()>disp.screen_width() || height()>disp.screen_height()) - get_resize(cimg_fitscreen(width(),height(),1),1,-100).move_to(thumb); - - const unsigned int old_normalization = disp.normalization(); - bool old_is_resized = disp.is_resized(); - disp._normalization = 0; - disp.show().set_key(0).set_wheel().show_mouse(); - - static const unsigned char foreground_color[] = { 255,255,255 }, background_color[] = { 0,0,0 }; - - int area = 0, starting_area = 0, clicked_area = 0, phase = 0, - X0 = (int)((XYZ?XYZ[0]:(_width - 1)/2)%_width), - Y0 = (int)((XYZ?XYZ[1]:(_height - 1)/2)%_height), - Z0 = (int)((XYZ?XYZ[2]:(_depth - 1)/2)%_depth), - X1 =-1, Y1 = -1, Z1 = -1, - X3d = -1, Y3d = -1, - oX3d = X3d, oY3d = -1, - omx = -1, omy = -1; - float X = -1, Y = -1, Z = -1; - unsigned int old_button = 0, key = 0; - - bool shape_selected = false, text_down = false, visible_cursor = true; - static CImg pose3d; - static bool is_view3d = false, is_axes = true; - if (reset_view3d) { pose3d.assign(); is_view3d = false; } - CImg points3d, opacities3d, sel_opacities3d; - CImgList primitives3d, sel_primitives3d; - CImgList colors3d, sel_colors3d; - CImg visu, visu0, view3d; - CImg text(1024); *text = 0; - - while (!key && !disp.is_closed() && !shape_selected) { - - // Handle mouse motion and selection - int - mx = disp.mouse_x(), - my = disp.mouse_y(); - - const float - mX = mx<0?-1.0f:(float)mx*(width() + (depth()>1?depth():0))/disp.width(), - mY = my<0?-1.0f:(float)my*(height() + (depth()>1?depth():0))/disp.height(); - - area = 0; - if (mX>=0 && mY>=0 && mX=0 && mX=height()) { area = 2; X = mX; Z = mY - _height; Y = (float)(phase?Y1:Y0); } - if (mY>=0 && mX>=width() && mY=width() && mY>=height()) area = 4; - if (disp.button()) { if (!clicked_area) clicked_area = area; } else clicked_area = 0; - - CImg filename(32); - - switch (key = disp.key()) { -#if cimg_OS!=2 - case cimg::keyCTRLRIGHT : -#endif - case 0 : case cimg::keyCTRLLEFT : key = 0; break; - case cimg::keyPAGEUP : - if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { disp.set_wheel(1); key = 0; } break; - case cimg::keyPAGEDOWN : - if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { disp.set_wheel(-1); key = 0; } break; - case cimg::keyA : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - is_axes = !is_axes; disp.set_key(key,false); key = 0; visu0.assign(); - } break; - case cimg::keyD : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - disp.set_fullscreen(false). - resize(CImgDisplay::_fitscreen(3*disp.width()/2,3*disp.height()/2,1,128,-100,false), - CImgDisplay::_fitscreen(3*disp.width()/2,3*disp.height()/2,1,128,-100,true),false). - _is_resized = true; - disp.set_key(key,false); key = 0; visu0.assign(); - } break; - case cimg::keyC : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - disp.set_fullscreen(false). - resize(cimg_fitscreen(2*disp.width()/3,2*disp.height()/3,1),false)._is_resized = true; - disp.set_key(key,false); key = 0; visu0.assign(); - } break; - case cimg::keyR : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - disp.set_fullscreen(false).resize(cimg_fitscreen(_width,_height,_depth),false)._is_resized = true; - disp.set_key(key,false); key = 0; visu0.assign(); - } break; - case cimg::keyF : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - disp.resize(disp.screen_width(),disp.screen_height(),false).toggle_fullscreen()._is_resized = true; - disp.set_key(key,false); key = 0; visu0.assign(); - } break; - case cimg::keyV : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - is_view3d = !is_view3d; disp.set_key(key,false); key = 0; visu0.assign(); - } break; - case cimg::keyS : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - static unsigned int snap_number = 0; - std::FILE *file; - do { - cimg_snprintf(filename,filename._width,cimg_appname "_%.4u.bmp",snap_number++); - if ((file=std_fopen(filename,"r"))!=0) cimg::fclose(file); - } while (file); - if (visu0) { - (+visu0).draw_text(0,0," Saving snapshot... ",foreground_color,background_color,0.7f,13).display(disp); - visu0.save(filename); - (+visu0).draw_text(0,0," Snapshot '%s' saved. ",foreground_color,background_color,0.7f,13,filename._data). - display(disp); - } - disp.set_key(key,false); key = 0; - } break; - case cimg::keyO : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - static unsigned int snap_number = 0; - std::FILE *file; - do { -#ifdef cimg_use_zlib - cimg_snprintf(filename,filename._width,cimg_appname "_%.4u.cimgz",snap_number++); -#else - cimg_snprintf(filename,filename._width,cimg_appname "_%.4u.cimg",snap_number++); -#endif - if ((file=std_fopen(filename,"r"))!=0) cimg::fclose(file); - } while (file); - (+visu0).draw_text(0,0," Saving instance... ",foreground_color,background_color,0.7f,13).display(disp); - save(filename); - (+visu0).draw_text(0,0," Instance '%s' saved. ",foreground_color,background_color,0.7f,13,filename._data). - display(disp); - disp.set_key(key,false); key = 0; - } break; - } - - switch (area) { - - case 0 : // When mouse is out of image range. - mx = my = -1; X = Y = Z = -1; - break; - - case 1 : case 2 : case 3 : // When mouse is over the XY,XZ or YZ projections. - if (disp.button()&1 && phase<2 && clicked_area==area) { // When selection has been started (1st step). - if (_depth>1 && (X1!=(int)X || Y1!=(int)Y || Z1!=(int)Z)) visu0.assign(); - X1 = (int)X; Y1 = (int)Y; Z1 = (int)Z; - } - if (!(disp.button()&1) && phase>=2 && clicked_area!=area) { // When selection is at 2nd step (for volumes). - switch (starting_area) { - case 1 : if (Z1!=(int)Z) visu0.assign(); Z1 = (int)Z; break; - case 2 : if (Y1!=(int)Y) visu0.assign(); Y1 = (int)Y; break; - case 3 : if (X1!=(int)X) visu0.assign(); X1 = (int)X; break; - } - } - if (disp.button()&2 && clicked_area==area) { // When moving through the image/volume. - if (phase) { - if (_depth>1 && (X1!=(int)X || Y1!=(int)Y || Z1!=(int)Z)) visu0.assign(); - X1 = (int)X; Y1 = (int)Y; Z1 = (int)Z; - } else { - if (_depth>1 && (X0!=(int)X || Y0!=(int)Y || Z0!=(int)Z)) visu0.assign(); - X0 = (int)X; Y0 = (int)Y; Z0 = (int)Z; - } - } - if (disp.button()&4) { - X = (float)X0; Y = (float)Y0; Z = (float)Z0; phase = area = clicked_area = starting_area = 0; - visu0.assign(); - } - if (disp.wheel()) { // When moving through the slices of the volume (with mouse wheel). - if (_depth>1 && !disp.is_keyCTRLLEFT() && !disp.is_keyCTRLRIGHT() && - !disp.is_keySHIFTLEFT() && !disp.is_keySHIFTRIGHT() && - !disp.is_keyALT() && !disp.is_keyALTGR()) { - switch (area) { - case 1 : - if (phase) Z = (float)(Z1+=disp.wheel()); else Z = (float)(Z0+=disp.wheel()); - visu0.assign(); break; - case 2 : - if (phase) Y = (float)(Y1+=disp.wheel()); else Y = (float)(Y0+=disp.wheel()); - visu0.assign(); break; - case 3 : - if (phase) X = (float)(X1+=disp.wheel()); else X = (float)(X0+=disp.wheel()); - visu0.assign(); break; - } - disp.set_wheel(); - } else key = ~0U; - } - if ((disp.button()&1)!=old_button) { // When left button has just been pressed or released. - switch (phase) { - case 0 : - if (area==clicked_area) { - X0 = X1 = (int)X; Y0 = Y1 = (int)Y; Z0 = Z1 = (int)Z; starting_area = area; ++phase; - } break; - case 1 : - if (area==starting_area) { - X1 = (int)X; Y1 = (int)Y; Z1 = (int)Z; ++phase; - } else if (!(disp.button()&1)) { X = (float)X0; Y = (float)Y0; Z = (float)Z0; phase = 0; visu0.assign(); } - break; - case 2 : ++phase; break; - } - old_button = disp.button()&1; - } - break; - - case 4 : // When mouse is over the 3d view. - if (is_view3d && points3d) { - X3d = mx - width()*disp.width()/(width() + (depth()>1?depth():0)); - Y3d = my - height()*disp.height()/(height() + (depth()>1?depth():0)); - if (oX3d<0) { oX3d = X3d; oY3d = Y3d; } - // Left + right buttons: reset. - if ((disp.button()&3)==3) { pose3d.assign(); view3d.assign(); oX3d = oY3d = X3d = Y3d = -1; } - else if (disp.button()&1 && pose3d && (oX3d!=X3d || oY3d!=Y3d)) { // Left button: rotate. - const float - R = 0.45f*cimg::min(view3d._width,view3d._height), - R2 = R*R, - u0 = (float)(oX3d - view3d.width()/2), - v0 = (float)(oY3d - view3d.height()/2), - u1 = (float)(X3d - view3d.width()/2), - v1 = (float)(Y3d - view3d.height()/2), - n0 = (float)std::sqrt(u0*u0 + v0*v0), - n1 = (float)std::sqrt(u1*u1 + v1*v1), - nu0 = n0>R?(u0*R/n0):u0, - nv0 = n0>R?(v0*R/n0):v0, - nw0 = (float)std::sqrt(cimg::max(0,R2 - nu0*nu0 - nv0*nv0)), - nu1 = n1>R?(u1*R/n1):u1, - nv1 = n1>R?(v1*R/n1):v1, - nw1 = (float)std::sqrt(cimg::max(0,R2 - nu1*nu1 - nv1*nv1)), - u = nv0*nw1 - nw0*nv1, - v = nw0*nu1 - nu0*nw1, - w = nv0*nu1 - nu0*nv1, - n = (float)std::sqrt(u*u + v*v + w*w), - alpha = (float)std::asin(n/R2); - pose3d.draw_image(CImg::rotation_matrix(u,v,w,alpha)*pose3d.get_crop(0,0,2,2)); - view3d.assign(); - } else if (disp.button()&2 && pose3d && oY3d!=Y3d) { // Right button: zoom. - pose3d(3,2)-=(oY3d - Y3d)*1.5f; view3d.assign(); - } - if (disp.wheel()) { // Wheel: zoom - pose3d(3,2)-=disp.wheel()*15; view3d.assign(); disp.set_wheel(); - } - if (disp.button()&4 && pose3d && (oX3d!=X3d || oY3d!=Y3d)) { // Middle button: shift. - pose3d(3,0)-=oX3d - X3d; pose3d(3,1)-=oY3d - Y3d; view3d.assign(); - } - oX3d = X3d; oY3d = Y3d; - } - mx = my = -1; X = Y = Z = -1; - break; - } - - if (phase) { - if (!feature_type) shape_selected = phase?true:false; - else { - if (_depth>1) shape_selected = (phase==3)?true:false; - else shape_selected = (phase==2)?true:false; - } - } - - if (X0<0) X0 = 0; if (X0>=width()) X0 = width() - 1; - if (Y0<0) Y0 = 0; if (Y0>=height()) Y0 = height() - 1; - if (Z0<0) Z0 = 0; if (Z0>=depth()) Z0 = depth() - 1; - if (X1<1) X1 = 0; if (X1>=width()) X1 = width() - 1; - if (Y1<0) Y1 = 0; if (Y1>=height()) Y1 = height() - 1; - if (Z1<0) Z1 = 0; if (Z1>=depth()) Z1 = depth() - 1; - - // Draw visualization image on the display - if (mx!=omx || my!=omy || !visu0 || (_depth>1 && !view3d)) { - - if (!visu0) { // Create image of projected planes. - if (thumb) thumb.__get_select(disp,old_normalization,phase?X1:X0,phase?Y1:Y0,phase?Z1:Z0).move_to(visu0); - else __get_select(disp,old_normalization,phase?X1:X0,phase?Y1:Y0,phase?Z1:Z0).move_to(visu0); - visu0.resize(disp); - view3d.assign(); - points3d.assign(); - } - - if (is_view3d && _depth>1 && !view3d) { // Create 3d view for volumetric images. - const unsigned int - _x3d = (unsigned int)cimg::round((float)_width*visu0._width/(_width + _depth),1,1), - _y3d = (unsigned int)cimg::round((float)_height*visu0._height/(_height + _depth),1,1), - x3d = _x3d>=visu0._width?visu0._width - 1:_x3d, - y3d = _y3d>=visu0._height?visu0._height - 1:_y3d; - CImg(1,2,1,1,64,128).resize(visu0._width - x3d,visu0._height - y3d,1,visu0._spectrum,3). - move_to(view3d); - if (!points3d) { - get_projections3d(primitives3d,colors3d,phase?X1:X0,phase?Y1:Y0,phase?Z1:Z0,true).move_to(points3d); - points3d.append(CImg(8,3,1,1, - 0,_width - 1,_width - 1,0,0,_width - 1,_width - 1,0, - 0,0,_height - 1,_height - 1,0,0,_height - 1,_height - 1, - 0,0,0,0,_depth - 1,_depth - 1,_depth - 1,_depth - 1),'x'); - CImg::vector(12,13).move_to(primitives3d); CImg::vector(13,14).move_to(primitives3d); - CImg::vector(14,15).move_to(primitives3d); CImg::vector(15,12).move_to(primitives3d); - CImg::vector(16,17).move_to(primitives3d); CImg::vector(17,18).move_to(primitives3d); - CImg::vector(18,19).move_to(primitives3d); CImg::vector(19,16).move_to(primitives3d); - CImg::vector(12,16).move_to(primitives3d); CImg::vector(13,17).move_to(primitives3d); - CImg::vector(14,18).move_to(primitives3d); CImg::vector(15,19).move_to(primitives3d); - colors3d.insert(12,CImg::vector(255,255,255)); - opacities3d.assign(primitives3d.width(),1,1,1,0.5f); - if (!phase) { - opacities3d[0] = opacities3d[1] = opacities3d[2] = 0.8f; - sel_primitives3d.assign(); - sel_colors3d.assign(); - sel_opacities3d.assign(); - } else { - if (feature_type==2) { - points3d.append(CImg(8,3,1,1, - X0,X1,X1,X0,X0,X1,X1,X0, - Y0,Y0,Y1,Y1,Y0,Y0,Y1,Y1, - Z0,Z0,Z0,Z0,Z1,Z1,Z1,Z1),'x'); - sel_primitives3d.assign(); - CImg::vector(20,21).move_to(sel_primitives3d); - CImg::vector(21,22).move_to(sel_primitives3d); - CImg::vector(22,23).move_to(sel_primitives3d); - CImg::vector(23,20).move_to(sel_primitives3d); - CImg::vector(24,25).move_to(sel_primitives3d); - CImg::vector(25,26).move_to(sel_primitives3d); - CImg::vector(26,27).move_to(sel_primitives3d); - CImg::vector(27,24).move_to(sel_primitives3d); - CImg::vector(20,24).move_to(sel_primitives3d); - CImg::vector(21,25).move_to(sel_primitives3d); - CImg::vector(22,26).move_to(sel_primitives3d); - CImg::vector(23,27).move_to(sel_primitives3d); - } else { - points3d.append(CImg(2,3,1,1, - X0,X1, - Y0,Y1, - Z0,Z1),'x'); - sel_primitives3d.assign(CImg::vector(20,21)); - } - sel_colors3d.assign(sel_primitives3d._width,CImg::vector(255,255,255)); - sel_opacities3d.assign(sel_primitives3d._width,1,1,1,0.8f); - } - points3d.shift_object3d(-0.5f*(_width - 1),-0.5f*(_height - 1),-0.5f*(_depth - 1)).resize_object3d(); - points3d*=0.75f*cimg::min(view3d._width,view3d._height); - } - - if (!pose3d) CImg(4,3,1,1, 1,0,0,0, 0,1,0,0, 0,0,1,0).move_to(pose3d); - CImg zbuffer3d(view3d._width,view3d._height,1,1,0); - const CImg rotated_points3d = pose3d.get_crop(0,0,2,2)*points3d; - if (sel_primitives3d) - view3d.draw_object3d(pose3d(3,0) + 0.5f*view3d._width, - pose3d(3,1) + 0.5f*view3d._height, - pose3d(3,2), - rotated_points3d,sel_primitives3d,sel_colors3d,sel_opacities3d, - 2,true,500,0,0,0,0,0,zbuffer3d); - view3d.draw_object3d(pose3d(3,0) + 0.5f*view3d._width, - pose3d(3,1) + 0.5f*view3d._height, - pose3d(3,2), - rotated_points3d,primitives3d,colors3d,opacities3d, - 2,true,500,0,0,0,0,0,zbuffer3d); - visu0.draw_image(x3d,y3d,view3d); - } - visu = visu0; - - if (X<0 || Y<0 || Z<0) { if (!visible_cursor) { disp.show_mouse(); visible_cursor = true; }} - else { - if (is_axes) { if (visible_cursor) { disp.hide_mouse(); visible_cursor = false; }} - else { if (!visible_cursor) { disp.show_mouse(); visible_cursor = true; }} - const int d = (depth()>1)?depth():0; - int - _X = (int)X, _Y = (int)Y, _Z = (int)Z, - w = disp.width(), W = width() + d, - h = disp.height(), H = height() + d, - _xp = (int)(_X*(float)w/W), xp = _xp + ((int)(_xp*(float)W/w)!=_X), - _yp = (int)(_Y*(float)h/H), yp = _yp + ((int)(_yp*(float)H/h)!=_Y), - _xn = (int)((_X + 1.0f)*w/W - 1), xn = _xn + ((int)((_xn + 1.0f)*W/w)!=_X + 1), - _yn = (int)((_Y + 1.0f)*h/H - 1), yn = _yn + ((int)((_yn + 1.0f)*H/h)!=_Y + 1), - _zxp = (int)((_Z + width())*(float)w/W), zxp = _zxp + ((int)(_zxp*(float)W/w)!=_Z + width()), - _zyp = (int)((_Z + height())*(float)h/H), zyp = _zyp + ((int)(_zyp*(float)H/h)!=_Z + height()), - _zxn = (int)((_Z + width() + 1.0f)*w/W - 1), - zxn = _zxn + ((int)((_zxn + 1.0f)*W/w)!=_Z + width() + 1), - _zyn = (int)((_Z + height() + 1.0f)*h/H - 1), - zyn = _zyn + ((int)((_zyn + 1.0f)*H/h)!=_Z + height() + 1), - _xM = (int)(width()*(float)w/W - 1), xM = _xM + ((int)((_xM + 1.0f)*W/w)!=width()), - _yM = (int)(height()*(float)h/H - 1), yM = _yM + ((int)((_yM + 1.0f)*H/h)!=height()), - xc = (xp + xn)/2, - yc = (yp + yn)/2, - zxc = (zxp + zxn)/2, - zyc = (zyp + zyn)/2, - xf = (int)(X*w/W), - yf = (int)(Y*h/H), - zxf = (int)((Z + width())*w/W), - zyf = (int)((Z + height())*h/H); - - if (is_axes) { // Draw axes. - visu.draw_line(0,yf,visu.width() - 1,yf,foreground_color,0.7f,0xFF00FF00). - draw_line(0,yf,visu.width() - 1,yf,background_color,0.7f,0x00FF00FF). - draw_line(xf,0,xf,visu.height() - 1,foreground_color,0.7f,0xFF00FF00). - draw_line(xf,0,xf,visu.height() - 1,background_color,0.7f,0x00FF00FF); - if (_depth>1) - visu.draw_line(zxf,0,zxf,yM,foreground_color,0.7f,0xFF00FF00). - draw_line(zxf,0,zxf,yM,background_color,0.7f,0x00FF00FF). - draw_line(0,zyf,xM,zyf,foreground_color,0.7f,0xFF00FF00). - draw_line(0,zyf,xM,zyf,background_color,0.7f,0x00FF00FF); - } - - // Draw box cursor. - if (xn - xp>=4 && yn - yp>=4) visu.draw_rectangle(xp,yp,xn,yn,foreground_color,0.2f). - draw_rectangle(xp,yp,xn,yn,foreground_color,1,0xAAAAAAAA). - draw_rectangle(xp,yp,xn,yn,background_color,1,0x55555555); - if (_depth>1) { - if (yn - yp>=4 && zxn - zxp>=4) visu.draw_rectangle(zxp,yp,zxn,yn,background_color,0.2f). - draw_rectangle(zxp,yp,zxn,yn,foreground_color,1,0xAAAAAAAA). - draw_rectangle(zxp,yp,zxn,yn,background_color,1,0x55555555); - if (xn - xp>=4 && zyn - zyp>=4) visu.draw_rectangle(xp,zyp,xn,zyn,background_color,0.2f). - draw_rectangle(xp,zyp,xn,zyn,foreground_color,1,0xAAAAAAAA). - draw_rectangle(xp,zyp,xn,zyn,background_color,1,0x55555555); - } - - // Draw selection. - if (phase) { - const int - _xp0 = (int)(X0*(float)w/W), xp0 = _xp0 + ((int)(_xp0*(float)W/w)!=X0), - _yp0 = (int)(Y0*(float)h/H), yp0 = _yp0 + ((int)(_yp0*(float)H/h)!=Y0), - _xn0 = (int)((X0 + 1.0f)*w/W - 1), xn0 = _xn0 + ((int)((_xn0 + 1.0f)*W/w)!=X0 + 1), - _yn0 = (int)((Y0 + 1.0f)*h/H - 1), yn0 = _yn0 + ((int)((_yn0 + 1.0f)*H/h)!=Y0 + 1), - _zxp0 = (int)((Z0 + width())*(float)w/W), zxp0 = _zxp0 + ((int)(_zxp0*(float)W/w)!=Z0 + width()), - _zyp0 = (int)((Z0 + height())*(float)h/H), zyp0 = _zyp0 + ((int)(_zyp0*(float)H/h)!=Z0 + height()), - _zxn0 = (int)((Z0 + width() + 1.0f)*w/W - 1), - zxn0 = _zxn0 + ((int)((_zxn0 + 1.0f)*W/w)!=Z0 + width() + 1), - _zyn0 = (int)((Z0 + height() + 1.0f)*h/H - 1), - zyn0 = _zyn0 + ((int)((_zyn0 + 1.0f)*H/h)!=Z0 + height() + 1), - xc0 = (xp0 + xn0)/2, - yc0 = (yp0 + yn0)/2, - zxc0 = (zxp0 + zxn0)/2, - zyc0 = (zyp0 + zyn0)/2; - - switch (feature_type) { - case 1 : { - visu.draw_arrow(xc0,yc0,xc,yc,background_color,0.9f,30,5,0x55555555). - draw_arrow(xc0,yc0,xc,yc,foreground_color,0.9f,30,5,0xAAAAAAAA); - if (d) { - visu.draw_arrow(zxc0,yc0,zxc,yc,background_color,0.9f,30,5,0x55555555). - draw_arrow(zxc0,yc0,zxc,yc,foreground_color,0.9f,30,5,0xAAAAAAAA). - draw_arrow(xc0,zyc0,xc,zyc,background_color,0.9f,30,5,0x55555555). - draw_arrow(xc0,zyc0,xc,zyc,foreground_color,0.9f,30,5,0xAAAAAAAA); - } - } break; - case 2 : { - visu.draw_rectangle(X0=0 && my<13) text_down = true; else if (my>=visu.height() - 13) text_down = false; - if (!feature_type || !phase) { - if (X>=0 && Y>=0 && Z>=0 && X1 || force_display_z_coord) - cimg_snprintf(text,text._width," Point (%d,%d,%d) = [ ",origX + (int)X,origY + (int)Y,origZ + (int)Z); - else cimg_snprintf(text,text._width," Point (%d,%d) = [ ",origX + (int)X,origY + (int)Y); - char *ctext = text._data + std::strlen(text), *const ltext = text._data + 512; - for (unsigned int c = 0; c<_spectrum && ctext::format(), - cimg::type::format((*this)((int)X,(int)Y,(int)Z,c))); - ctext = text._data + std::strlen(text); - *(ctext++) = ' '; *ctext = 0; - } - std::strcpy(text._data + std::strlen(text),"] "); - } - } else switch (feature_type) { - case 1 : { - const double dX = (double)(X0 - X1), dY = (double)(Y0 - Y1), dZ = (double)(Z0 - Z1), - norm = std::sqrt(dX*dX + dY*dY + dZ*dZ); - if (_depth>1 || force_display_z_coord) - cimg_snprintf(text,text._width," Vect (%d,%d,%d)-(%d,%d,%d), Norm = %g ", - origX + X0,origY + Y0,origZ + Z0,origX + X1,origY + Y1,origZ + Z1,norm); - else cimg_snprintf(text,text._width," Vect (%d,%d)-(%d,%d), Norm = %g ", - origX + X0,origY + Y0,origX + X1,origY + Y1,norm); - } break; - case 2 : - if (_depth>1 || force_display_z_coord) - cimg_snprintf(text,text._width," Box (%d,%d,%d)-(%d,%d,%d), Size = (%d,%d,%d) ", - origX + (X01 || force_display_z_coord) - cimg_snprintf(text,text._width," Ellipse (%d,%d,%d)-(%d,%d,%d), Radii = (%d,%d,%d) ", - origX + X0,origY + Y0,origZ + Z0,origX + X1,origY + Y1,origZ + Z1, - 1 + cimg::abs(X0 - X1),1 + cimg::abs(Y0 - Y1),1 + cimg::abs(Z0 - Z1)); - else cimg_snprintf(text,text._width," Ellipse (%d,%d)-(%d,%d), Radii = (%d,%d) ", - origX + X0,origY + Y0,origX + X1,origY + Y1, - 1 + cimg::abs(X0 - X1),1 + cimg::abs(Y0 - Y1)); - } - if (phase || (mx>=0 && my>=0)) - visu.draw_text(0,text_down?visu.height() - 13:0,text,foreground_color,background_color,0.7f,13); - } - - disp.display(visu).wait(); - } else if (!shape_selected) disp.wait(); - if (disp.is_resized()) { disp.resize(false)._is_resized = false; old_is_resized = true; visu0.assign(); } - omx = mx; omy = my; - if (!exit_on_anykey && key && key!=cimg::keyESC && - (key!=cimg::keyW || (!disp.is_keyCTRLLEFT() && !disp.is_keyCTRLRIGHT()))) { - key = 0; - } - } - - // Return result. - CImg res(1,feature_type==0?3:6,1,1,-1); - if (XYZ) { XYZ[0] = (unsigned int)X0; XYZ[1] = (unsigned int)Y0; XYZ[2] = (unsigned int)Z0; } - if (shape_selected) { - if (feature_type==2) { - if (X0>X1) cimg::swap(X0,X1); - if (Y0>Y1) cimg::swap(Y0,Y1); - if (Z0>Z1) cimg::swap(Z0,Z1); - } - if (X1<0 || Y1<0 || Z1<0) X0 = Y0 = Z0 = X1 = Y1 = Z1 = -1; - switch (feature_type) { - case 1 : case 2 : res[0] = X0; res[1] = Y0; res[2] = Z0; res[3] = X1; res[4] = Y1; res[5] = Z1; break; - case 3 : - res[3] = cimg::abs(X1 - X0); res[4] = cimg::abs(Y1 - Y0); res[5] = cimg::abs(Z1 - Z0); // keep no break here! - default : res[0] = X0; res[1] = Y0; res[2] = Z0; - } - } - if (!exit_on_anykey || !(disp.button()&4)) disp.set_button(); - if (!visible_cursor) disp.show_mouse(); - disp._normalization = old_normalization; - disp._is_resized = old_is_resized; - if (key!=~0U) disp.set_key(key); - return res; - } - - // Return a visualizable uchar8 image for display routines. - CImg __get_select(const CImgDisplay& disp, const int normalization, - const int x, const int y, const int z) const { - if (is_empty()) return CImg(1,1,1,1,0); - const CImg crop = get_shared_channels(0,cimg::min(2,spectrum() - 1)); - CImg img2d; - if (_depth>1) { - const int mdisp = cimg::min(disp.screen_width(),disp.screen_height()); - if (depth()>mdisp) { - crop.get_resize(-100,-100,mdisp,-100,0).move_to(img2d); - img2d.projections2d(x,y,z*img2d._depth/_depth); - } else crop.get_projections2d(x,y,z).move_to(img2d); - } else CImg(crop,false).move_to(img2d); - - // Check for inf and NaN values. - if (cimg::type::is_float() && normalization) { - bool is_inf = false, is_nan = false; - cimg_for(img2d,ptr,Tuchar) - if (cimg::type::is_inf(*ptr)) { is_inf = true; break; } - else if (cimg::type::is_nan(*ptr)) { is_nan = true; break; } - if (is_inf || is_nan) { - Tint m0 = (Tint)cimg::type::max(), M0 = (Tint)cimg::type::min(); - if (!normalization) { m0 = 0; M0 = 255; } - else if (normalization==2) { m0 = (Tint)disp._min; M0 = (Tint)disp._max; } - else - cimg_for(img2d,ptr,Tuchar) - if (!cimg::type::is_inf(*ptr) && !cimg::type::is_nan(*ptr)) { - if (*ptr<(Tuchar)m0) m0 = *ptr; - if (*ptr>(Tuchar)M0) M0 = *ptr; - } - const T - val_minf = (T)(normalization==1 || normalization==3?m0 - (M0 - m0)*20 - 1:m0), - val_pinf = (T)(normalization==1 || normalization==3?M0 + (M0 - m0)*20 + 1:M0); - if (is_nan) - cimg_for(img2d,ptr,Tuchar) - if (cimg::type::is_nan(*ptr)) *ptr = val_minf; // Replace NaN values. - if (is_inf) - cimg_for(img2d,ptr,Tuchar) - if (cimg::type::is_inf(*ptr)) *ptr = (float)*ptr<0?val_minf:val_pinf; // Replace +-inf values. - } - } - - switch (normalization) { - case 1 : img2d.normalize(0,255); break; - case 2 : { - const float m = disp._min, M = disp._max; - (img2d-=m)*=255.0f/(M - m>0?M - m:1); - } break; - case 3 : - if (cimg::type::is_float()) img2d.normalize(0,255); - else { - const float m = (float)cimg::type::min(), M = (float)cimg::type::max(); - (img2d-=m)*=255.0f/(M - m>0?M - m:1); - } break; - } - - if (img2d.spectrum()==2) img2d.channels(0,2); - return img2d; - } - - //! Select sub-graph in a graph. - CImg get_select_graph(CImgDisplay &disp, - const unsigned int plot_type=1, const unsigned int vertex_type=1, - const char *const labelx=0, const double xmin=0, const double xmax=0, - const char *const labely=0, const double ymin=0, const double ymax=0, - const bool exit_on_anykey=false) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "select_graph(): Empty instance.", - cimg_instance); - if (!disp) disp.assign(cimg_fitscreen(CImgDisplay::screen_width()/2,CImgDisplay::screen_height()/2,1),0,0). - set_title("CImg<%s>",pixel_type()); - const ulongT siz = (ulongT)_width*_height*_depth; - const unsigned int old_normalization = disp.normalization(); - disp.show().set_button().set_wheel()._normalization = 0; - - double nymin = ymin, nymax = ymax, nxmin = xmin, nxmax = xmax; - if (nymin==nymax) { nymin = (Tfloat)min_max(nymax); const double dy = nymax - nymin; nymin-=dy/20; nymax+=dy/20; } - if (nymin==nymax) { --nymin; ++nymax; } - if (nxmin==nxmax && nxmin==0) { nxmin = 0; nxmax = siz - 1.0; } - - static const unsigned char black[] = { 0, 0, 0 }, white[] = { 255, 255, 255 }, gray[] = { 220, 220, 220 }; - static const unsigned char gray2[] = { 110, 110, 110 }, ngray[] = { 35, 35, 35 }; - static unsigned int odimv = 0; - static CImg colormap; - if (odimv!=_spectrum) { - odimv = _spectrum; - colormap = CImg(3,_spectrum,1,1,120).noise(70,1); - if (_spectrum==1) { colormap[0] = colormap[1] = 120; colormap[2] = 200; } - else { - colormap(0,0) = 220; colormap(1,0) = 10; colormap(2,0) = 10; - if (_spectrum>1) { colormap(0,1) = 10; colormap(1,1) = 220; colormap(2,1) = 10; } - if (_spectrum>2) { colormap(0,2) = 10; colormap(1,2) = 10; colormap(2,2) = 220; } - } - } - - CImg visu0, visu, graph, text, axes; - int x0 = -1, x1 = -1, y0 = -1, y1 = -1, omouse_x = -2, omouse_y = -2; - const unsigned int one = plot_type==3?0U:1U; - unsigned int okey = 0, obutton = 0; - CImg message(1024); - CImg_3x3(I,unsigned char); - - for (bool selected = false; !selected && !disp.is_closed() && !okey && !disp.wheel(); ) { - const int mouse_x = disp.mouse_x(), mouse_y = disp.mouse_y(); - const unsigned int key = disp.key(), button = disp.button(); - - // Generate graph representation. - if (!visu0) { - visu0.assign(disp.width(),disp.height(),1,3,220); - const int gdimx = disp.width() - 32, gdimy = disp.height() - 32; - if (gdimx>0 && gdimy>0) { - graph.assign(gdimx,gdimy,1,3,255); - if (siz<32) { - if (siz>1) graph.draw_grid(gdimx/(float)(siz - one),gdimy/(float)(siz - one),0,0, - false,true,black,0.2f,0x33333333,0x33333333); - } else graph.draw_grid(-10,-10,0,0,false,true,black,0.2f,0x33333333,0x33333333); - cimg_forC(*this,c) - graph.draw_graph(get_shared_channel(c),&colormap(0,c),(plot_type!=3 || _spectrum==1)?1:0.6f, - plot_type,vertex_type,nymax,nymin); - - axes.assign(gdimx,gdimy,1,1,0); - const float - dx = (float)cimg::abs(nxmax - nxmin), dy = (float)cimg::abs(nymax - nymin), - px = (float)std::pow(10.0,(int)std::log10(dx?dx:1) - 2.0), - py = (float)std::pow(10.0,(int)std::log10(dy?dy:1) - 2.0); - const CImg - seqx = dx<=0?CImg::vector(nxmin): - CImg::sequence(1 + gdimx/60,nxmin,one?nxmax:nxmin + (nxmax - nxmin)*(siz + 1)/siz).round(px), - seqy = CImg::sequence(1 + gdimy/60,nymax,nymin).round(py); - - const bool allow_zero = (nxmin*nxmax>0) || (nymin*nymax>0); - axes.draw_axes(seqx,seqy,white,1,~0U,~0U,13,allow_zero); - if (nymin>0) axes.draw_axis(seqx,gdimy - 1,gray,1,~0U,13,allow_zero); - if (nymax<0) axes.draw_axis(seqx,0,gray,1,~0U,13,allow_zero); - if (nxmin>0) axes.draw_axis(0,seqy,gray,1,~0U,13,allow_zero); - if (nxmax<0) axes.draw_axis(gdimx - 1,seqy,gray,1,~0U,13,allow_zero); - - cimg_for3x3(axes,x,y,0,0,I,unsigned char) - if (Icc) { - if (Icc==255) cimg_forC(graph,c) graph(x,y,c) = 0; - else cimg_forC(graph,c) graph(x,y,c) = (unsigned char)(2*graph(x,y,c)/3); - } - else if (Ipc || Inc || Icp || Icn || Ipp || Inn || Ipn || Inp) - cimg_forC(graph,c) graph(x,y,c) = (unsigned char)((graph(x,y,c) + 511)/3); - - visu0.draw_image(16,16,graph); - visu0.draw_line(15,15,16 + gdimx,15,gray2).draw_line(16 + gdimx,15,16 + gdimx,16 + gdimy,gray2). - draw_line(16 + gdimx,16 + gdimy,15,16 + gdimy,white).draw_line(15,16 + gdimy,15,15,white); - } else graph.assign(); - text.assign().draw_text(0,0,labelx?labelx:"X-axis",white,ngray,1,13).resize(-100,-100,1,3); - visu0.draw_image((visu0.width() - text.width())/2,visu0.height() - 14,~text); - text.assign().draw_text(0,0,labely?labely:"Y-axis",white,ngray,1,13).rotate(-90).resize(-100,-100,1,3); - visu0.draw_image(1,(visu0.height() - text.height())/2,~text); - visu.assign(); - } - - // Generate and display current view. - if (!visu) { - visu.assign(visu0); - if (graph && x0>=0 && x1>=0) { - const int - nx0 = x0<=x1?x0:x1, - nx1 = x0<=x1?x1:x0, - ny0 = y0<=y1?y0:y1, - ny1 = y0<=y1?y1:y0, - sx0 = (int)(16 + nx0*(visu.width() - 32)/cimg::max(1U,siz - one)), - sx1 = (int)(15 + (nx1 + 1)*(visu.width() - 32)/cimg::max(1U,siz - one)), - sy0 = 16 + ny0, - sy1 = 16 + ny1; - if (y0>=0 && y1>=0) - visu.draw_rectangle(sx0,sy0,sx1,sy1,gray,0.5f).draw_rectangle(sx0,sy0,sx1,sy1,black,0.5f,0xCCCCCCCCU); - else visu.draw_rectangle(sx0,0,sx1,visu.height() - 17,gray,0.5f). - draw_line(sx0,16,sx0,visu.height() - 17,black,0.5f,0xCCCCCCCCU). - draw_line(sx1,16,sx1,visu.height() - 17,black,0.5f,0xCCCCCCCCU); - } - if (mouse_x>=16 && mouse_y>=16 && mouse_x=7) - cimg_snprintf(message,message._width,"Value[%u:%g] = ( %g %g %g ... %g %g %g )",x,cx, - (double)(*this)(x,0,0,0),(double)(*this)(x,0,0,1),(double)(*this)(x,0,0,2), - (double)(*this)(x,0,0,_spectrum - 4),(double)(*this)(x,0,0,_spectrum - 3), - (double)(*this)(x,0,0,_spectrum - 1)); - else { - cimg_snprintf(message,message._width,"Value[%u:%g] = ( ",x,cx); - cimg_forC(*this,c) cimg_sprintf(message._data + std::strlen(message),"%g ",(double)(*this)(x,0,0,c)); - cimg_sprintf(message._data + std::strlen(message),")"); - } - if (x0>=0 && x1>=0) { - const unsigned int - nx0 = (unsigned int)(x0<=x1?x0:x1), - nx1 = (unsigned int)(x0<=x1?x1:x0), - ny0 = (unsigned int)(y0<=y1?y0:y1), - ny1 = (unsigned int)(y0<=y1?y1:y0); - const double - cx0 = nxmin + nx0*(nxmax - nxmin)/cimg::max(1U,siz - 1), - cx1 = nxmin + (nx1 + one)*(nxmax - nxmin)/cimg::max(1U,siz - 1), - cy0 = nymax - ny0*(nymax - nymin)/(visu._height - 32), - cy1 = nymax - ny1*(nymax - nymin)/(visu._height - 32); - if (y0>=0 && y1>=0) - cimg_sprintf(message._data + std::strlen(message)," - Range ( %u:%g, %g ) - ( %u:%g, %g )", - x0,cx0,cy0,x1 + one,cx1,cy1); - else - cimg_sprintf(message._data + std::strlen(message)," - Range [ %u:%g - %u:%g ]", - x0,cx0,x1 + one,cx1); - } - text.assign().draw_text(0,0,message,white,ngray,1,13).resize(-100,-100,1,3); - visu.draw_image((visu.width() - text.width())/2,1,~text); - } - visu.display(disp); - } - - // Test keys. - CImg filename(32); - switch (okey = key) { -#if cimg_OS!=2 - case cimg::keyCTRLRIGHT : case cimg::keySHIFTRIGHT : -#endif - case cimg::keyCTRLLEFT : case cimg::keySHIFTLEFT : okey = 0; break; - case cimg::keyD : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - disp.set_fullscreen(false). - resize(CImgDisplay::_fitscreen(3*disp.width()/2,3*disp.height()/2,1,128,-100,false), - CImgDisplay::_fitscreen(3*disp.width()/2,3*disp.height()/2,1,128,-100,true),false). - _is_resized = true; - disp.set_key(key,false); okey = 0; - } break; - case cimg::keyC : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - disp.set_fullscreen(false). - resize(cimg_fitscreen(2*disp.width()/3,2*disp.height()/3,1),false)._is_resized = true; - disp.set_key(key,false); okey = 0; - } break; - case cimg::keyR : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - disp.set_fullscreen(false). - resize(cimg_fitscreen(CImgDisplay::screen_width()/2, - CImgDisplay::screen_height()/2,1),false)._is_resized = true; - disp.set_key(key,false); okey = 0; - } break; - case cimg::keyF : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - disp.resize(disp.screen_width(),disp.screen_height(),false).toggle_fullscreen()._is_resized = true; - disp.set_key(key,false); okey = 0; - } break; - case cimg::keyS : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - static unsigned int snap_number = 0; - if (visu || visu0) { - CImg &screen = visu?visu:visu0; - std::FILE *file; - do { - cimg_snprintf(filename,filename._width,cimg_appname "_%.4u.bmp",snap_number++); - if ((file=std_fopen(filename,"r"))!=0) cimg::fclose(file); - } while (file); - (+screen).draw_text(0,0," Saving snapshot... ",black,gray,1,13).display(disp); - screen.save(filename); - (+screen).draw_text(0,0," Snapshot '%s' saved. ",black,gray,1,13,filename._data).display(disp); - } - disp.set_key(key,false); okey = 0; - } break; - case cimg::keyO : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - static unsigned int snap_number = 0; - if (visu || visu0) { - CImg &screen = visu?visu:visu0; - std::FILE *file; - do { -#ifdef cimg_use_zlib - cimg_snprintf(filename,filename._width,cimg_appname "_%.4u.cimgz",snap_number++); -#else - cimg_snprintf(filename,filename._width,cimg_appname "_%.4u.cimg",snap_number++); -#endif - if ((file=std_fopen(filename,"r"))!=0) cimg::fclose(file); - } while (file); - (+screen).draw_text(0,0," Saving instance... ",black,gray,1,13).display(disp); - save(filename); - (+screen).draw_text(0,0," Instance '%s' saved. ",black,gray,1,13,filename._data).display(disp); - } - disp.set_key(key,false); okey = 0; - } break; - } - - // Handle mouse motion and mouse buttons - if (obutton!=button || omouse_x!=mouse_x || omouse_y!=mouse_y) { - visu.assign(); - if (disp.mouse_x()>=0 && disp.mouse_y()>=0) { - const int - mx = (mouse_x - 16)*(int)(siz - one)/(disp.width() - 32), - cx = mx<0?0:(mx>=(int)(siz - one)?(int)(siz - 1 - one):mx), - my = mouse_y - 16, - cy = my<=0?0:(my>=(disp.height() - 32)?(disp.height() - 32):my); - if (button&1) { - if (!obutton) { x0 = cx; y0 = -1; } else { x1 = cx; y1 = -1; } - } - else if (button&2) { - if (!obutton) { x0 = cx; y0 = cy; } else { x1 = cx; y1 = cy; } - } - else if (obutton) { x1 = x1>=0?cx:-1; y1 = y1>=0?cy:-1; selected = true; } - } else if (!button && obutton) selected = true; - obutton = button; omouse_x = mouse_x; omouse_y = mouse_y; - } - if (disp.is_resized()) { disp.resize(false); visu0.assign(); } - if (visu && visu0) disp.wait(); - if (!exit_on_anykey && okey && okey!=cimg::keyESC && - (okey!=cimg::keyW || (!disp.is_keyCTRLLEFT() && !disp.is_keyCTRLRIGHT()))) { - disp.set_key(key,false); - okey = 0; - } - } - - disp._normalization = old_normalization; - if (x1>=0 && x1(4,1,1,1,x0,y0,x1>=0?x1 + (int)one:-1,y1); - } - - //! Load image from a file. - /** - \param filename Filename, as a C-string. - \note The extension of \c filename defines the file format. If no filename - extension is provided, CImg::get_load() will try to load the file as a .cimg or .cimgz file. - **/ - CImg& load(const char *const filename) { - if (!filename) - throw CImgArgumentException(_cimg_instance - "load(): Specified filename is (null).", - cimg_instance); - - if (!cimg::strncasecmp(filename,"http://",7) || !cimg::strncasecmp(filename,"https://",8)) { - CImg filename_local(256); - load(cimg::load_network(filename,filename_local)); - std::remove(filename_local); - return *this; - } - - const char *const ext = cimg::split_filename(filename); - const unsigned int omode = cimg::exception_mode(); - cimg::exception_mode(0); - try { -#ifdef cimg_load_plugin - cimg_load_plugin(filename); -#endif -#ifdef cimg_load_plugin1 - cimg_load_plugin1(filename); -#endif -#ifdef cimg_load_plugin2 - cimg_load_plugin2(filename); -#endif -#ifdef cimg_load_plugin3 - cimg_load_plugin3(filename); -#endif -#ifdef cimg_load_plugin4 - cimg_load_plugin4(filename); -#endif -#ifdef cimg_load_plugin5 - cimg_load_plugin5(filename); -#endif -#ifdef cimg_load_plugin6 - cimg_load_plugin6(filename); -#endif -#ifdef cimg_load_plugin7 - cimg_load_plugin7(filename); -#endif -#ifdef cimg_load_plugin8 - cimg_load_plugin8(filename); -#endif - // Ascii formats - if (!cimg::strcasecmp(ext,"asc")) load_ascii(filename); - else if (!cimg::strcasecmp(ext,"dlm") || - !cimg::strcasecmp(ext,"txt")) load_dlm(filename); - - // 2d binary formats - else if (!cimg::strcasecmp(ext,"bmp")) load_bmp(filename); - else if (!cimg::strcasecmp(ext,"jpg") || - !cimg::strcasecmp(ext,"jpeg") || - !cimg::strcasecmp(ext,"jpe") || - !cimg::strcasecmp(ext,"jfif") || - !cimg::strcasecmp(ext,"jif")) load_jpeg(filename); - else if (!cimg::strcasecmp(ext,"png")) load_png(filename); - else if (!cimg::strcasecmp(ext,"ppm") || - !cimg::strcasecmp(ext,"pgm") || - !cimg::strcasecmp(ext,"pnm") || - !cimg::strcasecmp(ext,"pbm") || - !cimg::strcasecmp(ext,"pnk")) load_pnm(filename); - else if (!cimg::strcasecmp(ext,"pfm")) load_pfm(filename); - else if (!cimg::strcasecmp(ext,"tif") || - !cimg::strcasecmp(ext,"tiff")) load_tiff(filename); - else if (!cimg::strcasecmp(ext,"exr")) load_exr(filename); - else if (!cimg::strcasecmp(ext,"cr2") || - !cimg::strcasecmp(ext,"crw") || - !cimg::strcasecmp(ext,"dcr") || - !cimg::strcasecmp(ext,"mrw") || - !cimg::strcasecmp(ext,"nef") || - !cimg::strcasecmp(ext,"orf") || - !cimg::strcasecmp(ext,"pix") || - !cimg::strcasecmp(ext,"ptx") || - !cimg::strcasecmp(ext,"raf") || - !cimg::strcasecmp(ext,"srf")) load_dcraw_external(filename); - else if (!cimg::strcasecmp(ext,"gif")) load_gif_external(filename); - - // 3d binary formats - else if (!cimg::strcasecmp(ext,"dcm") || - !cimg::strcasecmp(ext,"dicom")) load_medcon_external(filename); - else if (!cimg::strcasecmp(ext,"hdr") || - !cimg::strcasecmp(ext,"nii")) load_analyze(filename); - else if (!cimg::strcasecmp(ext,"par") || - !cimg::strcasecmp(ext,"rec")) load_parrec(filename); - else if (!cimg::strcasecmp(ext,"mnc")) load_minc2(filename); - else if (!cimg::strcasecmp(ext,"inr")) load_inr(filename); - else if (!cimg::strcasecmp(ext,"pan")) load_pandore(filename); - else if (!cimg::strcasecmp(ext,"cimg") || - !cimg::strcasecmp(ext,"cimgz") || - !*ext) return load_cimg(filename); - - // Archive files - else if (!cimg::strcasecmp(ext,"gz")) load_gzip_external(filename); - - // Image sequences - else if (!cimg::strcasecmp(ext,"avi") || - !cimg::strcasecmp(ext,"mov") || - !cimg::strcasecmp(ext,"asf") || - !cimg::strcasecmp(ext,"divx") || - !cimg::strcasecmp(ext,"flv") || - !cimg::strcasecmp(ext,"mpg") || - !cimg::strcasecmp(ext,"m1v") || - !cimg::strcasecmp(ext,"m2v") || - !cimg::strcasecmp(ext,"m4v") || - !cimg::strcasecmp(ext,"mjp") || - !cimg::strcasecmp(ext,"mp4") || - !cimg::strcasecmp(ext,"mkv") || - !cimg::strcasecmp(ext,"mpe") || - !cimg::strcasecmp(ext,"movie") || - !cimg::strcasecmp(ext,"ogm") || - !cimg::strcasecmp(ext,"ogg") || - !cimg::strcasecmp(ext,"ogv") || - !cimg::strcasecmp(ext,"qt") || - !cimg::strcasecmp(ext,"rm") || - !cimg::strcasecmp(ext,"vob") || - !cimg::strcasecmp(ext,"wmv") || - !cimg::strcasecmp(ext,"xvid") || - !cimg::strcasecmp(ext,"mpeg")) load_video(filename); - else throw CImgIOException("CImg<%s>::load()", - pixel_type()); - } catch (CImgIOException&) { - std::FILE *file = 0; - try { - file = cimg::fopen(filename,"rb"); - } catch (CImgIOException&) { - cimg::exception_mode(omode); - throw CImgIOException(_cimg_instance - "load(): Failed to open file '%s'.", - cimg_instance, - filename); - } - - try { - const char *const f_type = cimg::ftype(file,filename); - std::fclose(file); - if (!cimg::strcasecmp(f_type,"pnm")) load_pnm(filename); - else if (!cimg::strcasecmp(f_type,"pfm")) load_pfm(filename); - else if (!cimg::strcasecmp(f_type,"bmp")) load_bmp(filename); - else if (!cimg::strcasecmp(f_type,"inr")) load_inr(filename); - else if (!cimg::strcasecmp(f_type,"jpg")) load_jpeg(filename); - else if (!cimg::strcasecmp(f_type,"pan")) load_pandore(filename); - else if (!cimg::strcasecmp(f_type,"png")) load_png(filename); - else if (!cimg::strcasecmp(f_type,"tif")) load_tiff(filename); - else if (!cimg::strcasecmp(f_type,"gif")) load_gif_external(filename); - else if (!cimg::strcasecmp(f_type,"dcm")) load_medcon_external(filename); - else throw CImgIOException("CImg<%s>::load()", - pixel_type()); - } catch (CImgIOException&) { - try { - load_other(filename); - } catch (CImgIOException&) { - cimg::exception_mode(omode); - throw CImgIOException(_cimg_instance - "load(): Failed to recognize format of file '%s'.", - cimg_instance, - filename); - } - } - } - cimg::exception_mode(omode); - return *this; - } - - //! Load image from a file \newinstance. - static CImg get_load(const char *const filename) { - return CImg().load(filename); - } - - //! Load image from an ascii file. - /** - \param filename Filename, as a C -string. - **/ - CImg& load_ascii(const char *const filename) { - return _load_ascii(0,filename); - } - - //! Load image from an ascii file \inplace. - static CImg get_load_ascii(const char *const filename) { - return CImg().load_ascii(filename); - } - - //! Load image from an ascii file \overloading. - CImg& load_ascii(std::FILE *const file) { - return _load_ascii(file,0); - } - - //! Loadimage from an ascii file \newinstance. - static CImg get_load_ascii(std::FILE *const file) { - return CImg().load_ascii(file); - } - - CImg& _load_ascii(std::FILE *const file, const char *const filename) { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "load_ascii(): Specified filename is (null).", - cimg_instance); - - std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); - CImg line(256); *line = 0; - int err = std::fscanf(nfile,"%255[^\n]",line._data); - unsigned int dx = 0, dy = 1, dz = 1, dc = 1; - cimg_sscanf(line,"%u%*c%u%*c%u%*c%u",&dx,&dy,&dz,&dc); - err = std::fscanf(nfile,"%*[^0-9.eEinfa+-]"); - if (!dx || !dy || !dz || !dc) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_ascii(): Invalid ascii header in file '%s', image dimensions are set " - "to (%u,%u,%u,%u).", - cimg_instance, - filename?filename:"(FILE*)",dx,dy,dz,dc); - } - assign(dx,dy,dz,dc); - const ulongT siz = size(); - ulongT off = 0; - double val; - T *ptr = _data; - for (err = 1, off = 0; off& load_dlm(const char *const filename) { - return _load_dlm(0,filename); - } - - //! Load image from a DLM file \newinstance. - static CImg get_load_dlm(const char *const filename) { - return CImg().load_dlm(filename); - } - - //! Load image from a DLM file \overloading. - CImg& load_dlm(std::FILE *const file) { - return _load_dlm(file,0); - } - - //! Load image from a DLM file \newinstance. - static CImg get_load_dlm(std::FILE *const file) { - return CImg().load_dlm(file); - } - - CImg& _load_dlm(std::FILE *const file, const char *const filename) { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "load_dlm(): Specified filename is (null).", - cimg_instance); - - std::FILE *const nfile = file?file:cimg::fopen(filename,"r"); - CImg delimiter(256), tmp(256); *delimiter = *tmp = 0; - unsigned int cdx = 0, dx = 0, dy = 0; - int err = 0; - double val; - assign(256,256,1,1,0); - while ((err = std::fscanf(nfile,"%lf%255[^0-9eEinfa.+-]",&val,delimiter._data))>0) { - if (err>0) (*this)(cdx++,dy) = (T)val; - if (cdx>=_width) resize(3*_width/2,_height,1,1,0); - char c = 0; - if (!cimg_sscanf(delimiter,"%255[^\n]%c",tmp._data,&c) || c=='\n') { - dx = cimg::max(cdx,dx); - if (++dy>=_height) resize(_width,3*_height/2,1,1,0); - cdx = 0; - } - } - if (cdx && err==1) { dx = cdx; ++dy; } - if (!dx || !dy) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_dlm(): Invalid DLM file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - } - resize(dx,dy,1,1,0); - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Load image from a BMP file. - /** - \param filename Filename, as a C-string. - **/ - CImg& load_bmp(const char *const filename) { - return _load_bmp(0,filename); - } - - //! Load image from a BMP file \newinstance. - static CImg get_load_bmp(const char *const filename) { - return CImg().load_bmp(filename); - } - - //! Load image from a BMP file \overloading. - CImg& load_bmp(std::FILE *const file) { - return _load_bmp(file,0); - } - - //! Load image from a BMP file \newinstance. - static CImg get_load_bmp(std::FILE *const file) { - return CImg().load_bmp(file); - } - - CImg& _load_bmp(std::FILE *const file, const char *const filename) { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "load_bmp(): Specified filename is (null).", - cimg_instance); - - std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); - CImg header(54); - cimg::fread(header._data,54,nfile); - if (*header!='B' || header[1]!='M') { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_bmp(): Invalid BMP file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - } - - // Read header and pixel buffer - int - file_size = header[0x02] + (header[0x03]<<8) + (header[0x04]<<16) + (header[0x05]<<24), - offset = header[0x0A] + (header[0x0B]<<8) + (header[0x0C]<<16) + (header[0x0D]<<24), - header_size = header[0x0E] + (header[0x0F]<<8) + (header[0x10]<<16) + (header[0x11]<<24), - dx = header[0x12] + (header[0x13]<<8) + (header[0x14]<<16) + (header[0x15]<<24), - dy = header[0x16] + (header[0x17]<<8) + (header[0x18]<<16) + (header[0x19]<<24), - compression = header[0x1E] + (header[0x1F]<<8) + (header[0x20]<<16) + (header[0x21]<<24), - nb_colors = header[0x2E] + (header[0x2F]<<8) + (header[0x30]<<16) + (header[0x31]<<24), - bpp = header[0x1C] + (header[0x1D]<<8); - - if (!file_size || file_size==offset) { - cimg::fseek(nfile,0,SEEK_END); - file_size = (int)cimg::ftell(nfile); - cimg::fseek(nfile,54,SEEK_SET); - } - if (header_size>40) cimg::fseek(nfile,header_size - 40,SEEK_CUR); - - const int - dx_bytes = (bpp==1)?(dx/8 + (dx%8?1:0)):((bpp==4)?(dx/2 + (dx%2?1:0)):(dx*bpp/8)), - align_bytes = (4 - dx_bytes%4)%4; - const longT - cimg_iobuffer = (longT)24*1024*1024, - buf_size = cimg::min((longT)cimg::abs(dy)*(dx_bytes + align_bytes),(longT)file_size - offset); - - CImg colormap; - if (bpp<16) { if (!nb_colors) nb_colors = 1<0) cimg::fseek(nfile,xoffset,SEEK_CUR); - - CImg buffer; - if (buf_size=0; --y) { - if (buf_size>=cimg_iobuffer) { - cimg::fread(ptrs=buffer._data,dx_bytes,nfile); - cimg::fseek(nfile,align_bytes,SEEK_CUR); - } - unsigned char mask = 0x80, val = 0; - cimg_forX(*this,x) { - if (mask==0x80) val = *(ptrs++); - const unsigned char *col = (unsigned char*)(colormap._data + (val&mask?1:0)); - (*this)(x,y,2) = (T)*(col++); - (*this)(x,y,1) = (T)*(col++); - (*this)(x,y,0) = (T)*(col++); - mask = cimg::ror(mask); - } - ptrs+=align_bytes; - } - } break; - case 4 : { // 16 colors - for (int y = height() - 1; y>=0; --y) { - if (buf_size>=cimg_iobuffer) { - cimg::fread(ptrs=buffer._data,dx_bytes,nfile); - cimg::fseek(nfile,align_bytes,SEEK_CUR); - } - unsigned char mask = 0xF0, val = 0; - cimg_forX(*this,x) { - if (mask==0xF0) val = *(ptrs++); - const unsigned char color = (unsigned char)((mask<16)?(val&mask):((val&mask)>>4)); - const unsigned char *col = (unsigned char*)(colormap._data + color); - (*this)(x,y,2) = (T)*(col++); - (*this)(x,y,1) = (T)*(col++); - (*this)(x,y,0) = (T)*(col++); - mask = cimg::ror(mask,4); - } - ptrs+=align_bytes; - } - } break; - case 8 : { // 256 colors - for (int y = height() - 1; y>=0; --y) { - if (buf_size>=cimg_iobuffer) { - cimg::fread(ptrs=buffer._data,dx_bytes,nfile); - cimg::fseek(nfile,align_bytes,SEEK_CUR); - } - cimg_forX(*this,x) { - const unsigned char *col = (unsigned char*)(colormap._data + *(ptrs++)); - (*this)(x,y,2) = (T)*(col++); - (*this)(x,y,1) = (T)*(col++); - (*this)(x,y,0) = (T)*(col++); - } - ptrs+=align_bytes; - } - } break; - case 16 : { // 16 bits colors - for (int y = height() - 1; y>=0; --y) { - if (buf_size>=cimg_iobuffer) { - cimg::fread(ptrs=buffer._data,dx_bytes,nfile); - cimg::fseek(nfile,align_bytes,SEEK_CUR); - } - cimg_forX(*this,x) { - const unsigned char c1 = *(ptrs++), c2 = *(ptrs++); - const unsigned short col = (unsigned short)(c1|(c2<<8)); - (*this)(x,y,2) = (T)(col&0x1F); - (*this)(x,y,1) = (T)((col>>5)&0x1F); - (*this)(x,y,0) = (T)((col>>10)&0x1F); - } - ptrs+=align_bytes; - } - } break; - case 24 : { // 24 bits colors - for (int y = height() - 1; y>=0; --y) { - if (buf_size>=cimg_iobuffer) { - cimg::fread(ptrs=buffer._data,dx_bytes,nfile); - cimg::fseek(nfile,align_bytes,SEEK_CUR); - } - cimg_forX(*this,x) { - (*this)(x,y,2) = (T)*(ptrs++); - (*this)(x,y,1) = (T)*(ptrs++); - (*this)(x,y,0) = (T)*(ptrs++); - } - ptrs+=align_bytes; - } - } break; - case 32 : { // 32 bits colors - for (int y = height() - 1; y>=0; --y) { - if (buf_size>=cimg_iobuffer) { - cimg::fread(ptrs=buffer._data,dx_bytes,nfile); - cimg::fseek(nfile,align_bytes,SEEK_CUR); - } - cimg_forX(*this,x) { - (*this)(x,y,2) = (T)*(ptrs++); - (*this)(x,y,1) = (T)*(ptrs++); - (*this)(x,y,0) = (T)*(ptrs++); - ++ptrs; - } - ptrs+=align_bytes; - } - } break; - } - if (dy<0) mirror('y'); - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Load image from a JPEG file. - /** - \param filename Filename, as a C-string. - **/ - CImg& load_jpeg(const char *const filename) { - return _load_jpeg(0,filename); - } - - //! Load image from a JPEG file \newinstance. - static CImg get_load_jpeg(const char *const filename) { - return CImg().load_jpeg(filename); - } - - //! Load image from a JPEG file \overloading. - CImg& load_jpeg(std::FILE *const file) { - return _load_jpeg(file,0); - } - - //! Load image from a JPEG file \newinstance. - static CImg get_load_jpeg(std::FILE *const file) { - return CImg().load_jpeg(file); - } - - // Custom error handler for libjpeg. -#ifdef cimg_use_jpeg - struct _cimg_error_mgr { - struct jpeg_error_mgr original; - jmp_buf setjmp_buffer; - char message[JMSG_LENGTH_MAX]; - }; - - typedef struct _cimg_error_mgr *_cimg_error_ptr; - - METHODDEF(void) _cimg_jpeg_error_exit(j_common_ptr cinfo) { - _cimg_error_ptr c_err = (_cimg_error_ptr) cinfo->err; // Return control to the setjmp point - (*cinfo->err->format_message)(cinfo,c_err->message); - jpeg_destroy(cinfo); // Clean memory and temp files. - longjmp(c_err->setjmp_buffer,1); - } -#endif - - CImg& _load_jpeg(std::FILE *const file, const char *const filename) { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "load_jpeg(): Specified filename is (null).", - cimg_instance); - -#ifndef cimg_use_jpeg - if (file) - throw CImgIOException(_cimg_instance - "load_jpeg(): Unable to load data from '(FILE*)' unless libjpeg is enabled.", - cimg_instance); - else return load_other(filename); -#else - - std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); - struct jpeg_decompress_struct cinfo; - struct _cimg_error_mgr jerr; - cinfo.err = jpeg_std_error(&jerr.original); - jerr.original.error_exit = _cimg_jpeg_error_exit; - if (setjmp(jerr.setjmp_buffer)) { // JPEG error - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_jpeg(): Error message returned by libjpeg: %s.", - cimg_instance,jerr.message); - } - - jpeg_create_decompress(&cinfo); - jpeg_stdio_src(&cinfo,nfile); - jpeg_read_header(&cinfo,TRUE); - jpeg_start_decompress(&cinfo); - - if (cinfo.output_components!=1 && cinfo.output_components!=3 && cinfo.output_components!=4) { - if (!file) { - cimg::fclose(nfile); - return load_other(filename); - } else - throw CImgIOException(_cimg_instance - "load_jpeg(): Failed to load JPEG data from file '%s'.", - cimg_instance,filename?filename:"(FILE*)"); - } - CImg buffer(cinfo.output_width*cinfo.output_components); - JSAMPROW row_pointer[1]; - try { assign(cinfo.output_width,cinfo.output_height,1,cinfo.output_components); } - catch (...) { if (!file) cimg::fclose(nfile); throw; } - T *ptr_r = _data, *ptr_g = _data + 1UL*_width*_height, *ptr_b = _data + 2UL*_width*_height, - *ptr_a = _data + 3UL*_width*_height; - while (cinfo.output_scanline - // This is experimental code, not much tested, use with care. - CImg& load_magick(const char *const filename) { - if (!filename) - throw CImgArgumentException(_cimg_instance - "load_magick(): Specified filename is (null).", - cimg_instance); -#ifdef cimg_use_magick - Magick::Image image(filename); - const unsigned int W = image.size().width(), H = image.size().height(); - switch (image.type()) { - case Magick::PaletteMatteType : - case Magick::TrueColorMatteType : - case Magick::ColorSeparationType : { - assign(W,H,1,4); - T *ptr_r = data(0,0,0,0), *ptr_g = data(0,0,0,1), *ptr_b = data(0,0,0,2), *ptr_a = data(0,0,0,3); - Magick::PixelPacket *pixels = image.getPixels(0,0,W,H); - for (ulongT off = (ulongT)W*H; off; --off) { - *(ptr_r++) = (T)(pixels->red); - *(ptr_g++) = (T)(pixels->green); - *(ptr_b++) = (T)(pixels->blue); - *(ptr_a++) = (T)(pixels->opacity); - ++pixels; - } - } break; - case Magick::PaletteType : - case Magick::TrueColorType : { - assign(W,H,1,3); - T *ptr_r = data(0,0,0,0), *ptr_g = data(0,0,0,1), *ptr_b = data(0,0,0,2); - Magick::PixelPacket *pixels = image.getPixels(0,0,W,H); - for (ulongT off = (ulongT)W*H; off; --off) { - *(ptr_r++) = (T)(pixels->red); - *(ptr_g++) = (T)(pixels->green); - *(ptr_b++) = (T)(pixels->blue); - ++pixels; - } - } break; - case Magick::GrayscaleMatteType : { - assign(W,H,1,2); - T *ptr_r = data(0,0,0,0), *ptr_a = data(0,0,0,1); - Magick::PixelPacket *pixels = image.getPixels(0,0,W,H); - for (ulongT off = (ulongT)W*H; off; --off) { - *(ptr_r++) = (T)(pixels->red); - *(ptr_a++) = (T)(pixels->opacity); - ++pixels; - } - } break; - default : { - assign(W,H,1,1); - T *ptr_r = data(0,0,0,0); - Magick::PixelPacket *pixels = image.getPixels(0,0,W,H); - for (ulongT off = (ulongT)W*H; off; --off) { - *(ptr_r++) = (T)(pixels->red); - ++pixels; - } - } - } - return *this; -#else - throw CImgIOException(_cimg_instance - "load_magick(): Unable to load file '%s' unless libMagick++ is enabled.", - cimg_instance, - filename); -#endif - } - - //! Load image from a file, using Magick++ library \newinstance. - static CImg get_load_magick(const char *const filename) { - return CImg().load_magick(filename); - } - - //! Load image from a PNG file. - /** - \param filename Filename, as a C-string. - **/ - CImg& load_png(const char *const filename, unsigned int *const bits_per_pixel=0) { - return _load_png(0,filename,bits_per_pixel); - } - - //! Load image from a PNG file \newinstance. - static CImg get_load_png(const char *const filename, unsigned int *const bits_per_pixel=0) { - return CImg().load_png(filename,bits_per_pixel); - } - - //! Load image from a PNG file \overloading. - CImg& load_png(std::FILE *const file, unsigned int *const bits_per_pixel=0) { - return _load_png(file,0,bits_per_pixel); - } - - //! Load image from a PNG file \newinstance. - static CImg get_load_png(std::FILE *const file, unsigned int *const bits_per_pixel=0) { - return CImg().load_png(file,bits_per_pixel); - } - - // (Note: Most of this function has been written by Eric Fausett) - CImg& _load_png(std::FILE *const file, const char *const filename, unsigned int *const bits_per_pixel) { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "load_png(): Specified filename is (null).", - cimg_instance); - -#ifndef cimg_use_png - cimg::unused(bits_per_pixel); - if (file) - throw CImgIOException(_cimg_instance - "load_png(): Unable to load data from '(FILE*)' unless libpng is enabled.", - cimg_instance); - - else return load_other(filename); -#else - // Open file and check for PNG validity - const char *volatile nfilename = filename; // two 'volatile' here to remove a g++ warning due to 'setjmp'. - std::FILE *volatile nfile = file?file:cimg::fopen(nfilename,"rb"); - - unsigned char pngCheck[8] = { 0 }; - cimg::fread(pngCheck,8,(std::FILE*)nfile); - if (png_sig_cmp(pngCheck,0,8)) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_png(): Invalid PNG file '%s'.", - cimg_instance, - nfilename?nfilename:"(FILE*)"); - } - - // Setup PNG structures for read - png_voidp user_error_ptr = 0; - png_error_ptr user_error_fn = 0, user_warning_fn = 0; - png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,user_error_ptr,user_error_fn,user_warning_fn); - if (!png_ptr) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_png(): Failed to initialize 'png_ptr' structure for file '%s'.", - cimg_instance, - nfilename?nfilename:"(FILE*)"); - } - png_infop info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - if (!file) cimg::fclose(nfile); - png_destroy_read_struct(&png_ptr,(png_infopp)0,(png_infopp)0); - throw CImgIOException(_cimg_instance - "load_png(): Failed to initialize 'info_ptr' structure for file '%s'.", - cimg_instance, - nfilename?nfilename:"(FILE*)"); - } - png_infop end_info = png_create_info_struct(png_ptr); - if (!end_info) { - if (!file) cimg::fclose(nfile); - png_destroy_read_struct(&png_ptr,&info_ptr,(png_infopp)0); - throw CImgIOException(_cimg_instance - "load_png(): Failed to initialize 'end_info' structure for file '%s'.", - cimg_instance, - nfilename?nfilename:"(FILE*)"); - } - - // Error handling callback for png file reading - if (setjmp(png_jmpbuf(png_ptr))) { - if (!file) cimg::fclose((std::FILE*)nfile); - png_destroy_read_struct(&png_ptr, &end_info, (png_infopp)0); - throw CImgIOException(_cimg_instance - "load_png(): Encountered unknown fatal error in libpng for file '%s'.", - cimg_instance, - nfilename?nfilename:"(FILE*)"); - } - png_init_io(png_ptr, nfile); - png_set_sig_bytes(png_ptr, 8); - - // Get PNG Header Info up to data block - png_read_info(png_ptr,info_ptr); - png_uint_32 W, H; - int bit_depth, color_type, interlace_type; - bool is_gray = false; - png_get_IHDR(png_ptr,info_ptr,&W,&H,&bit_depth,&color_type,&interlace_type,(int*)0,(int*)0); - if (bits_per_pixel) *bits_per_pixel = (unsigned int)bit_depth; - - // Transforms to unify image data - if (color_type==PNG_COLOR_TYPE_PALETTE) { - png_set_palette_to_rgb(png_ptr); - color_type = PNG_COLOR_TYPE_RGB; - bit_depth = 8; - } - if (color_type==PNG_COLOR_TYPE_GRAY && bit_depth<8) { - png_set_expand_gray_1_2_4_to_8(png_ptr); - is_gray = true; - bit_depth = 8; - } - if (png_get_valid(png_ptr,info_ptr,PNG_INFO_tRNS)) { - png_set_tRNS_to_alpha(png_ptr); - color_type |= PNG_COLOR_MASK_ALPHA; - } - if (color_type==PNG_COLOR_TYPE_GRAY || color_type==PNG_COLOR_TYPE_GRAY_ALPHA) { - png_set_gray_to_rgb(png_ptr); - color_type |= PNG_COLOR_MASK_COLOR; - is_gray = true; - } - if (color_type==PNG_COLOR_TYPE_RGB) - png_set_filler(png_ptr,0xffffU,PNG_FILLER_AFTER); - - png_read_update_info(png_ptr,info_ptr); - if (bit_depth!=8 && bit_depth!=16) { - if (!file) cimg::fclose(nfile); - png_destroy_read_struct(&png_ptr,&end_info,(png_infopp)0); - throw CImgIOException(_cimg_instance - "load_png(): Invalid bit depth %u in file '%s'.", - cimg_instance, - bit_depth,nfilename?nfilename:"(FILE*)"); - } - const int byte_depth = bit_depth>>3; - - // Allocate Memory for Image Read - png_bytep *const imgData = new png_bytep[H]; - for (unsigned int row = 0; row& load_pnm(const char *const filename) { - return _load_pnm(0,filename); - } - - //! Load image from a PNM file \newinstance. - static CImg get_load_pnm(const char *const filename) { - return CImg().load_pnm(filename); - } - - //! Load image from a PNM file \overloading. - CImg& load_pnm(std::FILE *const file) { - return _load_pnm(file,0); - } - - //! Load image from a PNM file \newinstance. - static CImg get_load_pnm(std::FILE *const file) { - return CImg().load_pnm(file); - } - - CImg& _load_pnm(std::FILE *const file, const char *const filename) { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "load_pnm(): Specified filename is (null).", - cimg_instance); - - std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); - unsigned int ppm_type, W, H, D = 1, colormax = 255; - CImg item(16384,1,1,1,0); - int err, rval, gval, bval; - const longT cimg_iobuffer = (longT)24*1024*1024; - while ((err=std::fscanf(nfile,"%16383[^\n]",item.data()))!=EOF && (*item=='#' || !err)) std::fgetc(nfile); - if (cimg_sscanf(item," P%u",&ppm_type)!=1) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_pnm(): PNM header not found in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - } - while ((err=std::fscanf(nfile," %16383[^\n]",item.data()))!=EOF && (*item=='#' || !err)) std::fgetc(nfile); - if ((err=cimg_sscanf(item," %u %u %u %u",&W,&H,&D,&colormax))<2) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_pnm(): WIDTH and HEIGHT fields undefined in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - } - if (ppm_type!=1 && ppm_type!=4) { - if (err==2 || (err==3 && (ppm_type==5 || ppm_type==7 || ppm_type==8 || ppm_type==9))) { - while ((err=std::fscanf(nfile," %16383[^\n]",item.data()))!=EOF && (*item=='#' || !err)) std::fgetc(nfile); - if (cimg_sscanf(item,"%u",&colormax)!=1) - cimg::warn(_cimg_instance - "load_pnm(): COLORMAX field is undefined in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - } else { colormax = D; D = 1; } - } - std::fgetc(nfile); - - switch (ppm_type) { - case 1 : { // 2d b&w ascii. - assign(W,H,1,1); - T* ptrd = _data; - cimg_foroff(*this,off) { if (std::fscanf(nfile,"%d",&rval)>0) *(ptrd++) = (T)(rval?0:255); else break; } - } break; - case 2 : { // 2d grey ascii. - assign(W,H,1,1); - T* ptrd = _data; - cimg_foroff(*this,off) { if (std::fscanf(nfile,"%d",&rval)>0) *(ptrd++) = (T)rval; else break; } - } break; - case 3 : { // 2d color ascii. - assign(W,H,1,3); - T *ptrd = data(0,0,0,0), *ptr_g = data(0,0,0,1), *ptr_b = data(0,0,0,2); - cimg_forXY(*this,x,y) { - if (std::fscanf(nfile,"%d %d %d",&rval,&gval,&bval)==3) { - *(ptrd++) = (T)rval; *(ptr_g++) = (T)gval; *(ptr_b++) = (T)bval; - } else break; - } - } break; - case 4 : { // 2d b&w binary (support 3D PINK extension). - CImg raw; - assign(W,H,D,1); - T *ptrd = data(0,0,0,0); - unsigned int w = 0, h = 0, d = 0; - for (longT to_read = (longT)((W/8 + (W%8?1:0))*H*D); to_read>0; ) { - raw.assign(cimg::min(to_read,cimg_iobuffer)); - cimg::fread(raw._data,raw._width,nfile); - to_read-=raw._width; - const unsigned char *ptrs = raw._data; - unsigned char mask = 0, val = 0; - for (ulongT off = (ulongT)raw._width; off || mask; mask>>=1) { - if (!mask) { if (off--) val = *(ptrs++); mask = 128; } - *(ptrd++) = (T)((val&mask)?0:255); - if (++w==W) { w = 0; mask = 0; if (++h==H) { h = 0; if (++d==D) break; }} - } - } - } break; - case 5 : case 7 : { // 2d/3d grey binary (support 3D PINK extension). - if (colormax<256) { // 8 bits. - CImg raw; - assign(W,H,D,1); - T *ptrd = data(0,0,0,0); - for (longT to_read = (longT)size(); to_read>0; ) { - raw.assign(cimg::min(to_read,cimg_iobuffer)); - cimg::fread(raw._data,raw._width,nfile); - to_read-=raw._width; - const unsigned char *ptrs = raw._data; - for (ulongT off = (ulongT)raw._width; off; --off) *(ptrd++) = (T)*(ptrs++); - } - } else { // 16 bits. - CImg raw; - assign(W,H,D,1); - T *ptrd = data(0,0,0,0); - for (longT to_read = (longT)size(); to_read>0; ) { - raw.assign(cimg::min(to_read,cimg_iobuffer/2)); - cimg::fread(raw._data,raw._width,nfile); - if (!cimg::endianness()) cimg::invert_endianness(raw._data,raw._width); - to_read-=raw._width; - const unsigned short *ptrs = raw._data; - for (ulongT off = (ulongT)raw._width; off; --off) *(ptrd++) = (T)*(ptrs++); - } - } - } break; - case 6 : { // 2d color binary. - if (colormax<256) { // 8 bits. - CImg raw; - assign(W,H,1,3); - T - *ptr_r = data(0,0,0,0), - *ptr_g = data(0,0,0,1), - *ptr_b = data(0,0,0,2); - for (longT to_read = (longT)size(); to_read>0; ) { - raw.assign(cimg::min(to_read,cimg_iobuffer)); - cimg::fread(raw._data,raw._width,nfile); - to_read-=raw._width; - const unsigned char *ptrs = raw._data; - for (ulongT off = (ulongT)raw._width/3; off; --off) { - *(ptr_r++) = (T)*(ptrs++); - *(ptr_g++) = (T)*(ptrs++); - *(ptr_b++) = (T)*(ptrs++); - } - } - } else { // 16 bits. - CImg raw; - assign(W,H,1,3); - T - *ptr_r = data(0,0,0,0), - *ptr_g = data(0,0,0,1), - *ptr_b = data(0,0,0,2); - for (longT to_read = (longT)size(); to_read>0; ) { - raw.assign(cimg::min(to_read,cimg_iobuffer/2)); - cimg::fread(raw._data,raw._width,nfile); - if (!cimg::endianness()) cimg::invert_endianness(raw._data,raw._width); - to_read-=raw._width; - const unsigned short *ptrs = raw._data; - for (ulongT off = (ulongT)raw._width/3; off; --off) { - *(ptr_r++) = (T)*(ptrs++); - *(ptr_g++) = (T)*(ptrs++); - *(ptr_b++) = (T)*(ptrs++); - } - } - } - } break; - case 8 : { // 2d/3d grey binary with int32 integers (PINK extension). - CImg raw; - assign(W,H,D,1); - T *ptrd = data(0,0,0,0); - for (longT to_read = (longT)size(); to_read>0; ) { - raw.assign(cimg::min(to_read,cimg_iobuffer)); - cimg::fread(raw._data,raw._width,nfile); - to_read-=raw._width; - const int *ptrs = raw._data; - for (ulongT off = (ulongT)raw._width; off; --off) *(ptrd++) = (T)*(ptrs++); - } - } break; - case 9 : { // 2d/3d grey binary with float values (PINK extension). - CImg raw; - assign(W,H,D,1); - T *ptrd = data(0,0,0,0); - for (longT to_read = (longT)size(); to_read>0; ) { - raw.assign(cimg::min(to_read,cimg_iobuffer)); - cimg::fread(raw._data,raw._width,nfile); - to_read-=raw._width; - const float *ptrs = raw._data; - for (ulongT off = (ulongT)raw._width; off; --off) *(ptrd++) = (T)*(ptrs++); - } - } break; - default : - assign(); - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_pnm(): PNM type 'P%d' found, but type is not supported.", - cimg_instance, - filename?filename:"(FILE*)",ppm_type); - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Load image from a PFM file. - /** - \param filename Filename, as a C-string. - **/ - CImg& load_pfm(const char *const filename) { - return _load_pfm(0,filename); - } - - //! Load image from a PFM file \newinstance. - static CImg get_load_pfm(const char *const filename) { - return CImg().load_pfm(filename); - } - - //! Load image from a PFM file \overloading. - CImg& load_pfm(std::FILE *const file) { - return _load_pfm(file,0); - } - - //! Load image from a PFM file \newinstance. - static CImg get_load_pfm(std::FILE *const file) { - return CImg().load_pfm(file); - } - - CImg& _load_pfm(std::FILE *const file, const char *const filename) { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "load_pfm(): Specified filename is (null).", - cimg_instance); - - std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); - char pfm_type; - CImg item(16384,1,1,1,0); - int W = 0, H = 0, err = 0; - double scale = 0; - while ((err=std::fscanf(nfile,"%16383[^\n]",item.data()))!=EOF && (*item=='#' || !err)) std::fgetc(nfile); - if (cimg_sscanf(item," P%c",&pfm_type)!=1) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_pfm(): PFM header not found in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - } - while ((err=std::fscanf(nfile," %16383[^\n]",item.data()))!=EOF && (*item=='#' || !err)) std::fgetc(nfile); - if ((err=cimg_sscanf(item," %d %d",&W,&H))<2) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_pfm(): WIDTH and HEIGHT fields are undefined in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - } - if (err==2) { - while ((err=std::fscanf(nfile," %16383[^\n]",item.data()))!=EOF && (*item=='#' || !err)) std::fgetc(nfile); - if (cimg_sscanf(item,"%lf",&scale)!=1) - cimg::warn(_cimg_instance - "load_pfm(): SCALE field is undefined in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - } - std::fgetc(nfile); - const bool is_color = (pfm_type=='F'), is_inverted = (scale>0)!=cimg::endianness(); - if (is_color) { - assign(W,H,1,3,0); - CImg buf(3*W); - T *ptr_r = data(0,0,0,0), *ptr_g = data(0,0,0,1), *ptr_b = data(0,0,0,2); - cimg_forY(*this,y) { - cimg::fread(buf._data,3*W,nfile); - if (is_inverted) cimg::invert_endianness(buf._data,3*W); - const float *ptrs = buf._data; - cimg_forX(*this,x) { - *(ptr_r++) = (T)*(ptrs++); - *(ptr_g++) = (T)*(ptrs++); - *(ptr_b++) = (T)*(ptrs++); - } - } - } else { - assign(W,H,1,1,0); - CImg buf(W); - T *ptrd = data(0,0,0,0); - cimg_forY(*this,y) { - cimg::fread(buf._data,W,nfile); - if (is_inverted) cimg::invert_endianness(buf._data,W); - const float *ptrs = buf._data; - cimg_forX(*this,x) *(ptrd++) = (T)*(ptrs++); - } - } - if (!file) cimg::fclose(nfile); - return mirror('y'); // Most of the .pfm files are flipped along the y-axis. - } - - //! Load image from a RGB file. - /** - \param filename Filename, as a C-string. - \param dimw Width of the image buffer. - \param dimh Height of the image buffer. - **/ - CImg& load_rgb(const char *const filename, const unsigned int dimw, const unsigned int dimh=1) { - return _load_rgb(0,filename,dimw,dimh); - } - - //! Load image from a RGB file \newinstance. - static CImg get_load_rgb(const char *const filename, const unsigned int dimw, const unsigned int dimh=1) { - return CImg().load_rgb(filename,dimw,dimh); - } - - //! Load image from a RGB file \overloading. - CImg& load_rgb(std::FILE *const file, const unsigned int dimw, const unsigned int dimh=1) { - return _load_rgb(file,0,dimw,dimh); - } - - //! Load image from a RGB file \newinstance. - static CImg get_load_rgb(std::FILE *const file, const unsigned int dimw, const unsigned int dimh=1) { - return CImg().load_rgb(file,dimw,dimh); - } - - CImg& _load_rgb(std::FILE *const file, const char *const filename, - const unsigned int dimw, const unsigned int dimh) { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "load_rgb(): Specified filename is (null).", - cimg_instance); - - if (!dimw || !dimh) return assign(); - const longT cimg_iobuffer = (longT)24*1024*1024; - std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); - CImg raw; - assign(dimw,dimh,1,3); - T - *ptr_r = data(0,0,0,0), - *ptr_g = data(0,0,0,1), - *ptr_b = data(0,0,0,2); - for (longT to_read = (longT)size(); to_read>0; ) { - raw.assign(cimg::min(to_read,cimg_iobuffer)); - cimg::fread(raw._data,raw._width,nfile); - to_read-=raw._width; - const unsigned char *ptrs = raw._data; - for (ulongT off = raw._width/3UL; off; --off) { - *(ptr_r++) = (T)*(ptrs++); - *(ptr_g++) = (T)*(ptrs++); - *(ptr_b++) = (T)*(ptrs++); - } - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Load image from a RGBA file. - /** - \param filename Filename, as a C-string. - \param dimw Width of the image buffer. - \param dimh Height of the image buffer. - **/ - CImg& load_rgba(const char *const filename, const unsigned int dimw, const unsigned int dimh=1) { - return _load_rgba(0,filename,dimw,dimh); - } - - //! Load image from a RGBA file \newinstance. - static CImg get_load_rgba(const char *const filename, const unsigned int dimw, const unsigned int dimh=1) { - return CImg().load_rgba(filename,dimw,dimh); - } - - //! Load image from a RGBA file \overloading. - CImg& load_rgba(std::FILE *const file, const unsigned int dimw, const unsigned int dimh=1) { - return _load_rgba(file,0,dimw,dimh); - } - - //! Load image from a RGBA file \newinstance. - static CImg get_load_rgba(std::FILE *const file, const unsigned int dimw, const unsigned int dimh=1) { - return CImg().load_rgba(file,dimw,dimh); - } - - CImg& _load_rgba(std::FILE *const file, const char *const filename, - const unsigned int dimw, const unsigned int dimh) { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "load_rgba(): Specified filename is (null).", - cimg_instance); - - if (!dimw || !dimh) return assign(); - const longT cimg_iobuffer = (longT)24*1024*1024; - std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); - CImg raw; - assign(dimw,dimh,1,4); - T - *ptr_r = data(0,0,0,0), - *ptr_g = data(0,0,0,1), - *ptr_b = data(0,0,0,2), - *ptr_a = data(0,0,0,3); - for (longT to_read = (longT)size(); to_read>0; ) { - raw.assign(cimg::min(to_read,cimg_iobuffer)); - cimg::fread(raw._data,raw._width,nfile); - to_read-=raw._width; - const unsigned char *ptrs = raw._data; - for (ulongT off = raw._width/4UL; off; --off) { - *(ptr_r++) = (T)*(ptrs++); - *(ptr_g++) = (T)*(ptrs++); - *(ptr_b++) = (T)*(ptrs++); - *(ptr_a++) = (T)*(ptrs++); - } - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Load image from a TIFF file. - /** - \param filename Filename, as a C-string. - \param first_frame First frame to read (for multi-pages tiff). - \param last_frame Last frame to read (for multi-pages tiff). - \param step_frame Step value of frame reading. - \note - - libtiff support is enabled by defining the precompilation - directive \c cimg_use_tif. - - When libtiff is enabled, 2D and 3D (multipage) several - channel per pixel are supported for - char,uchar,short,ushort,float and \c double pixel types. - - If \c cimg_use_tif is not defined at compile time the - function uses CImg& load_other(const char*). - **/ - CImg& load_tiff(const char *const filename, - const unsigned int first_frame=0, const unsigned int last_frame=~0U, - const unsigned int step_frame=1, - float *const voxel_size=0, - CImg *const description=0) { - if (!filename) - throw CImgArgumentException(_cimg_instance - "load_tiff(): Specified filename is (null).", - cimg_instance); - - const unsigned int - nfirst_frame = first_frame1) - throw CImgArgumentException(_cimg_instance - "load_tiff(): Unable to read sub-images from file '%s' unless libtiff is enabled.", - cimg_instance, - filename); - return load_other(filename); -#else - TIFF *tif = TIFFOpen(filename,"r"); - if (tif) { - unsigned int nb_images = 0; - do ++nb_images; while (TIFFReadDirectory(tif)); - if (nfirst_frame>=nb_images || (nlast_frame!=~0U && nlast_frame>=nb_images)) - cimg::warn(_cimg_instance - "load_tiff(): File '%s' contains %u image(s) while specified frame range is [%u,%u] (step %u).", - cimg_instance, - filename,nb_images,nfirst_frame,nlast_frame,nstep_frame); - - if (nfirst_frame>=nb_images) return assign(); - if (nlast_frame>=nb_images) nlast_frame = nb_images - 1; - TIFFSetDirectory(tif,0); - CImg frame; - for (unsigned int l = nfirst_frame; l<=nlast_frame; l+=nstep_frame) { - frame._load_tiff(tif,l,voxel_size,description); - if (l==nfirst_frame) - assign(frame._width,frame._height,1 + (nlast_frame - nfirst_frame)/nstep_frame,frame._spectrum); - if (frame._width>_width || frame._height>_height || frame._spectrum>_spectrum) - resize(cimg::max(frame._width,_width), - cimg::max(frame._height,_height),-100, - cimg::max(frame._spectrum,_spectrum),0); - draw_image(0,0,(l - nfirst_frame)/nstep_frame,frame); - } - TIFFClose(tif); - } else throw CImgIOException(_cimg_instance - "load_tiff(): Failed to open file '%s'.", - cimg_instance, - filename); - return *this; -#endif - } - - //! Load image from a TIFF file \newinstance. - static CImg get_load_tiff(const char *const filename, - const unsigned int first_frame=0, const unsigned int last_frame=~0U, - const unsigned int step_frame=1, - float *const voxel_size=0, - CImg *const description=0) { - return CImg().load_tiff(filename,first_frame,last_frame,step_frame,voxel_size,description); - } - - // (Original contribution by Jerome Boulanger). -#ifdef cimg_use_tiff - template - void _load_tiff_tiled_contig(TIFF *const tif, const uint16 samplesperpixel, - const uint32 nx, const uint32 ny, const uint32 tw, const uint32 th) { - t *const buf = (t*)_TIFFmalloc(TIFFTileSize(tif)); - if (buf) { - for (unsigned int row = 0; row - void _load_tiff_tiled_separate(TIFF *const tif, const uint16 samplesperpixel, - const uint32 nx, const uint32 ny, const uint32 tw, const uint32 th) { - t *const buf = (t*)_TIFFmalloc(TIFFTileSize(tif)); - if (buf) { - for (unsigned int vv = 0; vv - void _load_tiff_contig(TIFF *const tif, const uint16 samplesperpixel, const uint32 nx, const uint32 ny) { - t *const buf = (t*)_TIFFmalloc(TIFFStripSize(tif)); - if (buf) { - uint32 row, rowsperstrip = (uint32)-1; - TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip); - for (row = 0; rowny?ny - row:rowsperstrip); - tstrip_t strip = TIFFComputeStrip(tif, row, 0); - if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) { - _TIFFfree(buf); TIFFClose(tif); - throw CImgIOException(_cimg_instance - "load_tiff(): Invalid strip in file '%s'.", - cimg_instance, - TIFFFileName(tif)); - } - const t *ptr = buf; - for (unsigned int rr = 0; rr - void _load_tiff_separate(TIFF *const tif, const uint16 samplesperpixel, const uint32 nx, const uint32 ny) { - t *buf = (t*)_TIFFmalloc(TIFFStripSize(tif)); - if (buf) { - uint32 row, rowsperstrip = (uint32)-1; - TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip); - for (unsigned int vv = 0; vvny?ny - row:rowsperstrip); - tstrip_t strip = TIFFComputeStrip(tif, row, vv); - if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) { - _TIFFfree(buf); TIFFClose(tif); - throw CImgIOException(_cimg_instance - "load_tiff(): Invalid strip in file '%s'.", - cimg_instance, - TIFFFileName(tif)); - } - const t *ptr = buf; - for (unsigned int rr = 0;rr& _load_tiff(TIFF *const tif, const unsigned int directory, - float *const voxel_size, CImg *const description) { - if (!TIFFSetDirectory(tif,directory)) return assign(); - uint16 samplesperpixel = 1, bitspersample = 8, photo = 0; - uint16 sampleformat = 1; - uint32 nx = 1, ny = 1; - const char *const filename = TIFFFileName(tif); - const bool is_spp = (bool)TIFFGetField(tif,TIFFTAG_SAMPLESPERPIXEL,&samplesperpixel); - TIFFGetField(tif,TIFFTAG_IMAGEWIDTH,&nx); - TIFFGetField(tif,TIFFTAG_IMAGELENGTH,&ny); - TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &sampleformat); - TIFFGetFieldDefaulted(tif,TIFFTAG_BITSPERSAMPLE,&bitspersample); - TIFFGetField(tif,TIFFTAG_PHOTOMETRIC,&photo); - if (voxel_size) { - const char *s_description = 0; - float vx = 0, vy = 0, vz = 0; - if (TIFFGetField(tif,TIFFTAG_IMAGEDESCRIPTION,&s_description) && s_description) { - const char *s_desc = std::strstr(s_description,"VX="); - if (s_desc && cimg_sscanf(s_desc,"VX=%f VY=%f VZ=%f",&vx,&vy,&vz)==3) { // CImg format. - voxel_size[0] = vx; voxel_size[1] = vy; voxel_size[2] = vz; - } - s_desc = std::strstr(s_description,"spacing="); - if (s_desc && cimg_sscanf(s_desc,"spacing=%f",&vz)==1) { // fiji format. - voxel_size[2] = vz; - } - } - TIFFGetField(tif,TIFFTAG_XRESOLUTION,voxel_size); - TIFFGetField(tif,TIFFTAG_YRESOLUTION,voxel_size + 1); - voxel_size[0] = 1.0f/voxel_size[0]; - voxel_size[1] = 1.0f/voxel_size[1]; - } - if (description) { - const char *s_description = 0; - if (TIFFGetField(tif,TIFFTAG_IMAGEDESCRIPTION,&s_description) && s_description) - CImg::string(s_description).move_to(*description); - } - const unsigned int spectrum = !is_spp || photo>=3?(photo>1?3:1):samplesperpixel; - assign(nx,ny,1,spectrum); - - if ((photo>=3 && sampleformat==1 && - (bitspersample==4 || bitspersample==8) && - (samplesperpixel==1 || samplesperpixel==3 || samplesperpixel==4)) || - (bitspersample==1 && samplesperpixel==1)) { - // Special case for unsigned color images. - uint32 *const raster = (uint32*)_TIFFmalloc(nx*ny*sizeof(uint32)); - if (!raster) { - _TIFFfree(raster); TIFFClose(tif); - throw CImgException(_cimg_instance - "load_tiff(): Failed to allocate memory (%s) for file '%s'.", - cimg_instance, - cimg::strbuffersize(nx*ny*sizeof(uint32)),filename); - } - TIFFReadRGBAImage(tif,nx,ny,raster,0); - switch (spectrum) { - case 1 : - cimg_forXY(*this,x,y) - (*this)(x,y,0) = (T)(float)TIFFGetR(raster[nx*(ny - 1 -y) + x]); - break; - case 3 : - cimg_forXY(*this,x,y) { - (*this)(x,y,0) = (T)(float)TIFFGetR(raster[nx*(ny - 1 -y) + x]); - (*this)(x,y,1) = (T)(float)TIFFGetG(raster[nx*(ny - 1 -y) + x]); - (*this)(x,y,2) = (T)(float)TIFFGetB(raster[nx*(ny - 1 -y) + x]); - } - break; - case 4 : - cimg_forXY(*this,x,y) { - (*this)(x,y,0) = (T)(float)TIFFGetR(raster[nx*(ny - 1 - y) + x]); - (*this)(x,y,1) = (T)(float)TIFFGetG(raster[nx*(ny - 1 - y) + x]); - (*this)(x,y,2) = (T)(float)TIFFGetB(raster[nx*(ny - 1 - y) + x]); - (*this)(x,y,3) = (T)(float)TIFFGetA(raster[nx*(ny - 1 - y) + x]); - } - break; - } - _TIFFfree(raster); - } else { // Other cases. - uint16 config; - TIFFGetField(tif,TIFFTAG_PLANARCONFIG,&config); - if (TIFFIsTiled(tif)) { - uint32 tw = 1, th = 1; - TIFFGetField(tif,TIFFTAG_TILEWIDTH,&tw); - TIFFGetField(tif,TIFFTAG_TILELENGTH,&th); - if (config==PLANARCONFIG_CONTIG) switch (bitspersample) { - case 8 : { - if (sampleformat==SAMPLEFORMAT_UINT) - _load_tiff_tiled_contig(tif,samplesperpixel,nx,ny,tw,th); - else _load_tiff_tiled_contig(tif,samplesperpixel,nx,ny,tw,th); - } break; - case 16 : - if (sampleformat==SAMPLEFORMAT_UINT) - _load_tiff_tiled_contig(tif,samplesperpixel,nx,ny,tw,th); - else _load_tiff_tiled_contig(tif,samplesperpixel,nx,ny,tw,th); - break; - case 32 : - if (sampleformat==SAMPLEFORMAT_UINT) - _load_tiff_tiled_contig(tif,samplesperpixel,nx,ny,tw,th); - else if (sampleformat==SAMPLEFORMAT_INT) - _load_tiff_tiled_contig(tif,samplesperpixel,nx,ny,tw,th); - else _load_tiff_tiled_contig(tif,samplesperpixel,nx,ny,tw,th); - break; - } else switch (bitspersample) { - case 8 : - if (sampleformat==SAMPLEFORMAT_UINT) - _load_tiff_tiled_separate(tif,samplesperpixel,nx,ny,tw,th); - else _load_tiff_tiled_separate(tif,samplesperpixel,nx,ny,tw,th); - break; - case 16 : - if (sampleformat==SAMPLEFORMAT_UINT) - _load_tiff_tiled_separate(tif,samplesperpixel,nx,ny,tw,th); - else _load_tiff_tiled_separate(tif,samplesperpixel,nx,ny,tw,th); - break; - case 32 : - if (sampleformat==SAMPLEFORMAT_UINT) - _load_tiff_tiled_separate(tif,samplesperpixel,nx,ny,tw,th); - else if (sampleformat==SAMPLEFORMAT_INT) - _load_tiff_tiled_separate(tif,samplesperpixel,nx,ny,tw,th); - else _load_tiff_tiled_separate(tif,samplesperpixel,nx,ny,tw,th); - break; - } - } else { - if (config==PLANARCONFIG_CONTIG) switch (bitspersample) { - case 8 : - if (sampleformat==SAMPLEFORMAT_UINT) - _load_tiff_contig(tif,samplesperpixel,nx,ny); - else _load_tiff_contig(tif,samplesperpixel,nx,ny); - break; - case 16 : - if (sampleformat==SAMPLEFORMAT_UINT) _load_tiff_contig(tif,samplesperpixel,nx,ny); - else _load_tiff_contig(tif,samplesperpixel,nx,ny); - break; - case 32 : - if (sampleformat==SAMPLEFORMAT_UINT) _load_tiff_contig(tif,samplesperpixel,nx,ny); - else if (sampleformat==SAMPLEFORMAT_INT) _load_tiff_contig(tif,samplesperpixel,nx,ny); - else _load_tiff_contig(tif,samplesperpixel,nx,ny); - break; - } else switch (bitspersample) { - case 8 : - if (sampleformat==SAMPLEFORMAT_UINT) _load_tiff_separate(tif,samplesperpixel,nx,ny); - else _load_tiff_separate(tif,samplesperpixel,nx,ny); - break; - case 16 : - if (sampleformat==SAMPLEFORMAT_UINT) _load_tiff_separate(tif,samplesperpixel,nx,ny); - else _load_tiff_separate(tif,samplesperpixel,nx,ny); - break; - case 32 : - if (sampleformat==SAMPLEFORMAT_UINT) _load_tiff_separate(tif,samplesperpixel,nx,ny); - else if (sampleformat==SAMPLEFORMAT_INT) _load_tiff_separate(tif,samplesperpixel,nx,ny); - else _load_tiff_separate(tif,samplesperpixel,nx,ny); - break; - } - } - } - return *this; - } -#endif - - //! Load image from a MINC2 file. - /** - \param filename Filename, as a C-string. - **/ - // (Original code by Haz-Edine Assemlal). - CImg& load_minc2(const char *const filename) { - if (!filename) - throw CImgArgumentException(_cimg_instance - "load_minc2(): Specified filename is (null).", - cimg_instance); -#ifndef cimg_use_minc2 - return load_other(filename); -#else - minc::minc_1_reader rdr; - rdr.open(filename); - assign(rdr.ndim(1)?rdr.ndim(1):1, - rdr.ndim(2)?rdr.ndim(2):1, - rdr.ndim(3)?rdr.ndim(3):1, - rdr.ndim(4)?rdr.ndim(4):1); - if(typeid(T)==typeid(unsigned char)) - rdr.setup_read_byte(); - else if(typeid(T)==typeid(int)) - rdr.setup_read_int(); - else if(typeid(T)==typeid(double)) - rdr.setup_read_double(); - else - rdr.setup_read_float(); - minc::load_standard_volume(rdr, this->_data); - return *this; -#endif - } - - //! Load image from a MINC2 file \newinstance. - static CImg get_load_minc2(const char *const filename) { - return CImg().load_analyze(filename); - } - - //! Load image from an ANALYZE7.5/NIFTI file. - /** - \param filename Filename, as a C-string. - \param[out] voxel_size Pointer to the three voxel sizes read from the file. - **/ - CImg& load_analyze(const char *const filename, float *const voxel_size=0) { - return _load_analyze(0,filename,voxel_size); - } - - //! Load image from an ANALYZE7.5/NIFTI file \newinstance. - static CImg get_load_analyze(const char *const filename, float *const voxel_size=0) { - return CImg().load_analyze(filename,voxel_size); - } - - //! Load image from an ANALYZE7.5/NIFTI file \overloading. - CImg& load_analyze(std::FILE *const file, float *const voxel_size=0) { - return _load_analyze(file,0,voxel_size); - } - - //! Load image from an ANALYZE7.5/NIFTI file \newinstance. - static CImg get_load_analyze(std::FILE *const file, float *const voxel_size=0) { - return CImg().load_analyze(file,voxel_size); - } - - CImg& _load_analyze(std::FILE *const file, const char *const filename, float *const voxel_size=0) { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "load_analyze(): Specified filename is (null).", - cimg_instance); - - std::FILE *nfile_header = 0, *nfile = 0; - if (!file) { - CImg body(1024); - const char *const ext = cimg::split_filename(filename,body); - if (!cimg::strcasecmp(ext,"hdr")) { // File is an Analyze header file. - nfile_header = cimg::fopen(filename,"rb"); - cimg_sprintf(body._data + std::strlen(body),".img"); - nfile = cimg::fopen(body,"rb"); - } else if (!cimg::strcasecmp(ext,"img")) { // File is an Analyze data file. - nfile = cimg::fopen(filename,"rb"); - cimg_sprintf(body._data + std::strlen(body),".hdr"); - nfile_header = cimg::fopen(body,"rb"); - } else nfile_header = nfile = cimg::fopen(filename,"rb"); // File is a Niftii file. - } else nfile_header = nfile = file; // File is a Niftii file. - if (!nfile || !nfile_header) - throw CImgIOException(_cimg_instance - "load_analyze(): Invalid Analyze7.5 or NIFTI header in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - - // Read header. - bool endian = false; - unsigned int header_size; - cimg::fread(&header_size,1,nfile_header); - if (!header_size) - throw CImgIOException(_cimg_instance - "load_analyze(): Invalid zero-size header in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - if (header_size>=4096) { endian = true; cimg::invert_endianness(header_size); } - - unsigned char *const header = new unsigned char[header_size]; - cimg::fread(header + 4,header_size - 4,nfile_header); - if (!file && nfile_header!=nfile) cimg::fclose(nfile_header); - if (endian) { - cimg::invert_endianness((short*)(header + 40),5); - cimg::invert_endianness((short*)(header + 70),1); - cimg::invert_endianness((short*)(header + 72),1); - cimg::invert_endianness((float*)(header + 76),4); - cimg::invert_endianness((float*)(header + 108),1); - cimg::invert_endianness((float*)(header + 112),1); - } - - if (nfile_header==nfile) { - const unsigned int vox_offset = (unsigned int)*(float*)(header + 108); - std::fseek(nfile,vox_offset,SEEK_SET); - } - - unsigned short *dim = (unsigned short*)(header + 40), dimx = 1, dimy = 1, dimz = 1, dimv = 1; - if (!dim[0]) - cimg::warn(_cimg_instance - "load_analyze(): File '%s' defines an image with zero dimensions.", - cimg_instance, - filename?filename:"(FILE*)"); - - if (dim[0]>4) - cimg::warn(_cimg_instance - "load_analyze(): File '%s' defines an image with %u dimensions, reading only the 4 first.", - cimg_instance, - filename?filename:"(FILE*)",dim[0]); - - if (dim[0]>=1) dimx = dim[1]; - if (dim[0]>=2) dimy = dim[2]; - if (dim[0]>=3) dimz = dim[3]; - if (dim[0]>=4) dimv = dim[4]; - float scalefactor = *(float*)(header + 112); if (scalefactor==0) scalefactor = 1; - const unsigned short datatype = *(unsigned short*)(header + 70); - if (voxel_size) { - const float *vsize = (float*)(header + 76); - voxel_size[0] = vsize[1]; voxel_size[1] = vsize[2]; voxel_size[2] = vsize[3]; - } - delete[] header; - - // Read pixel data. - assign(dimx,dimy,dimz,dimv); - const size_t pdim = (size_t)dimx*dimy*dimz*dimv; - switch (datatype) { - case 2 : { - unsigned char *const buffer = new unsigned char[pdim]; - cimg::fread(buffer,pdim,nfile); - cimg_foroff(*this,off) _data[off] = (T)(buffer[off]*scalefactor); - delete[] buffer; - } break; - case 4 : { - short *const buffer = new short[pdim]; - cimg::fread(buffer,pdim,nfile); - if (endian) cimg::invert_endianness(buffer,pdim); - cimg_foroff(*this,off) _data[off] = (T)(buffer[off]*scalefactor); - delete[] buffer; - } break; - case 8 : { - int *const buffer = new int[pdim]; - cimg::fread(buffer,pdim,nfile); - if (endian) cimg::invert_endianness(buffer,pdim); - cimg_foroff(*this,off) _data[off] = (T)(buffer[off]*scalefactor); - delete[] buffer; - } break; - case 16 : { - float *const buffer = new float[pdim]; - cimg::fread(buffer,pdim,nfile); - if (endian) cimg::invert_endianness(buffer,pdim); - cimg_foroff(*this,off) _data[off] = (T)(buffer[off]*scalefactor); - delete[] buffer; - } break; - case 64 : { - double *const buffer = new double[pdim]; - cimg::fread(buffer,pdim,nfile); - if (endian) cimg::invert_endianness(buffer,pdim); - cimg_foroff(*this,off) _data[off] = (T)(buffer[off]*scalefactor); - delete[] buffer; - } break; - default : - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_analyze(): Unable to load datatype %d in file '%s'", - cimg_instance, - datatype,filename?filename:"(FILE*)"); - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Load image from a .cimg[z] file. - /** - \param filename Filename, as a C-string. - \param axis Appending axis, if file contains multiple images. Can be { 'x' | 'y' | 'z' | 'c' }. - \param align Appending alignment. - **/ - CImg& load_cimg(const char *const filename, const char axis='z', const float align=0) { - CImgList list; - list.load_cimg(filename); - if (list._width==1) return list[0].move_to(*this); - return assign(list.get_append(axis,align)); - } - - //! Load image from a .cimg[z] file \newinstance - static CImg get_load_cimg(const char *const filename, const char axis='z', const float align=0) { - return CImg().load_cimg(filename,axis,align); - } - - //! Load image from a .cimg[z] file \overloading. - CImg& load_cimg(std::FILE *const file, const char axis='z', const float align=0) { - CImgList list; - list.load_cimg(file); - if (list._width==1) return list[0].move_to(*this); - return assign(list.get_append(axis,align)); - } - - //! Load image from a .cimg[z] file \newinstance - static CImg get_load_cimg(std::FILE *const file, const char axis='z', const float align=0) { - return CImg().load_cimg(file,axis,align); - } - - //! Load sub-images of a .cimg file. - /** - \param filename Filename, as a C-string. - \param n0 Starting frame. - \param n1 Ending frame (~0U for max). - \param x0 X-coordinate of the starting sub-image vertex. - \param y0 Y-coordinate of the starting sub-image vertex. - \param z0 Z-coordinate of the starting sub-image vertex. - \param c0 C-coordinate of the starting sub-image vertex. - \param x1 X-coordinate of the ending sub-image vertex (~0U for max). - \param y1 Y-coordinate of the ending sub-image vertex (~0U for max). - \param z1 Z-coordinate of the ending sub-image vertex (~0U for max). - \param c1 C-coordinate of the ending sub-image vertex (~0U for max). - \param axis Appending axis, if file contains multiple images. Can be { 'x' | 'y' | 'z' | 'c' }. - \param align Appending alignment. - **/ - CImg& load_cimg(const char *const filename, - const unsigned int n0, const unsigned int n1, - const unsigned int x0, const unsigned int y0, - const unsigned int z0, const unsigned int c0, - const unsigned int x1, const unsigned int y1, - const unsigned int z1, const unsigned int c1, - const char axis='z', const float align=0) { - CImgList list; - list.load_cimg(filename,n0,n1,x0,y0,z0,c0,x1,y1,z1,c1); - if (list._width==1) return list[0].move_to(*this); - return assign(list.get_append(axis,align)); - } - - //! Load sub-images of a .cimg file \newinstance. - static CImg get_load_cimg(const char *const filename, - const unsigned int n0, const unsigned int n1, - const unsigned int x0, const unsigned int y0, - const unsigned int z0, const unsigned int c0, - const unsigned int x1, const unsigned int y1, - const unsigned int z1, const unsigned int c1, - const char axis='z', const float align=0) { - return CImg().load_cimg(filename,n0,n1,x0,y0,z0,c0,x1,y1,z1,c1,axis,align); - } - - //! Load sub-images of a .cimg file \overloading. - CImg& load_cimg(std::FILE *const file, - const unsigned int n0, const unsigned int n1, - const unsigned int x0, const unsigned int y0, - const unsigned int z0, const unsigned int c0, - const unsigned int x1, const unsigned int y1, - const unsigned int z1, const unsigned int c1, - const char axis='z', const float align=0) { - CImgList list; - list.load_cimg(file,n0,n1,x0,y0,z0,c0,x1,y1,z1,c1); - if (list._width==1) return list[0].move_to(*this); - return assign(list.get_append(axis,align)); - } - - //! Load sub-images of a .cimg file \newinstance. - static CImg get_load_cimg(std::FILE *const file, - const unsigned int n0, const unsigned int n1, - const unsigned int x0, const unsigned int y0, - const unsigned int z0, const unsigned int c0, - const unsigned int x1, const unsigned int y1, - const unsigned int z1, const unsigned int c1, - const char axis='z', const float align=0) { - return CImg().load_cimg(file,n0,n1,x0,y0,z0,c0,x1,y1,z1,c1,axis,align); - } - - //! Load image from an INRIMAGE-4 file. - /** - \param filename Filename, as a C-string. - \param[out] voxel_size Pointer to the three voxel sizes read from the file. - **/ - CImg& load_inr(const char *const filename, float *const voxel_size=0) { - return _load_inr(0,filename,voxel_size); - } - - //! Load image from an INRIMAGE-4 file \newinstance. - static CImg get_load_inr(const char *const filename, float *const voxel_size=0) { - return CImg().load_inr(filename,voxel_size); - } - - //! Load image from an INRIMAGE-4 file \overloading. - CImg& load_inr(std::FILE *const file, float *const voxel_size=0) { - return _load_inr(file,0,voxel_size); - } - - //! Load image from an INRIMAGE-4 file \newinstance. - static CImg get_load_inr(std::FILE *const file, float *voxel_size=0) { - return CImg().load_inr(file,voxel_size); - } - - static void _load_inr_header(std::FILE *file, int out[8], float *const voxel_size) { - CImg item(1024), tmp1(64), tmp2(64); - *item = *tmp1 = *tmp2 = 0; - out[0] = std::fscanf(file,"%63s",item._data); - out[0] = out[1] = out[2] = out[3] = out[5] = 1; out[4] = out[6] = out[7] = -1; - if(cimg::strncasecmp(item,"#INRIMAGE-4#{",13)!=0) - throw CImgIOException("CImg<%s>::load_inr(): INRIMAGE-4 header not found.", - pixel_type()); - - while (std::fscanf(file," %63[^\n]%*c",item._data)!=EOF && std::strncmp(item,"##}",3)) { - cimg_sscanf(item," XDIM%*[^0-9]%d",out); - cimg_sscanf(item," YDIM%*[^0-9]%d",out + 1); - cimg_sscanf(item," ZDIM%*[^0-9]%d",out + 2); - cimg_sscanf(item," VDIM%*[^0-9]%d",out + 3); - cimg_sscanf(item," PIXSIZE%*[^0-9]%d",out + 6); - if (voxel_size) { - cimg_sscanf(item," VX%*[^0-9.+-]%f",voxel_size); - cimg_sscanf(item," VY%*[^0-9.+-]%f",voxel_size + 1); - cimg_sscanf(item," VZ%*[^0-9.+-]%f",voxel_size + 2); - } - if (cimg_sscanf(item," CPU%*[ =]%s",tmp1._data)) out[7] = cimg::strncasecmp(tmp1,"sun",3)?0:1; - switch (cimg_sscanf(item," TYPE%*[ =]%s %s",tmp1._data,tmp2._data)) { - case 0 : break; - case 2 : out[5] = cimg::strncasecmp(tmp1,"unsigned",8)?1:0; std::strncpy(tmp1,tmp2,tmp1._width - 1); - case 1 : - if (!cimg::strncasecmp(tmp1,"int",3) || !cimg::strncasecmp(tmp1,"fixed",5)) out[4] = 0; - if (!cimg::strncasecmp(tmp1,"float",5) || !cimg::strncasecmp(tmp1,"double",6)) out[4] = 1; - if (!cimg::strncasecmp(tmp1,"packed",6)) out[4] = 2; - if (out[4]>=0) break; - default : - throw CImgIOException("CImg<%s>::load_inr(): Invalid pixel type '%s' defined in header.", - pixel_type(), - tmp2._data); - } - } - if(out[0]<0 || out[1]<0 || out[2]<0 || out[3]<0) - throw CImgIOException("CImg<%s>::load_inr(): Invalid dimensions (%d,%d,%d,%d) defined in header.", - pixel_type(), - out[0],out[1],out[2],out[3]); - if(out[4]<0 || out[5]<0) - throw CImgIOException("CImg<%s>::load_inr(): Incomplete pixel type defined in header.", - pixel_type()); - if(out[6]<0) - throw CImgIOException("CImg<%s>::load_inr(): Incomplete PIXSIZE field defined in header.", - pixel_type()); - if(out[7]<0) - throw CImgIOException("CImg<%s>::load_inr(): Big/Little Endian coding type undefined in header.", - pixel_type()); - } - - CImg& _load_inr(std::FILE *const file, const char *const filename, float *const voxel_size) { -#define _cimg_load_inr_case(Tf,sign,pixsize,Ts) \ - if (!loaded && fopt[6]==pixsize && fopt[4]==Tf && fopt[5]==sign) { \ - Ts *xval, *const val = new Ts[(size_t)fopt[0]*fopt[3]]; \ - cimg_forYZ(*this,y,z) { \ - cimg::fread(val,fopt[0]*fopt[3],nfile); \ - if (fopt[7]!=endian) cimg::invert_endianness(val,fopt[0]*fopt[3]); \ - xval = val; cimg_forX(*this,x) cimg_forC(*this,c) (*this)(x,y,z,c) = (T)*(xval++); \ - } \ - delete[] val; \ - loaded = true; \ - } - - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "load_inr(): Specified filename is (null).", - cimg_instance); - - std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); - int fopt[8], endian = cimg::endianness()?1:0; - bool loaded = false; - if (voxel_size) voxel_size[0] = voxel_size[1] = voxel_size[2] = 1; - _load_inr_header(nfile,fopt,voxel_size); - assign(fopt[0],fopt[1],fopt[2],fopt[3]); - _cimg_load_inr_case(0,0,8,unsigned char); - _cimg_load_inr_case(0,1,8,char); - _cimg_load_inr_case(0,0,16,unsigned short); - _cimg_load_inr_case(0,1,16,short); - _cimg_load_inr_case(0,0,32,unsigned int); - _cimg_load_inr_case(0,1,32,int); - _cimg_load_inr_case(1,0,32,float); - _cimg_load_inr_case(1,1,32,float); - _cimg_load_inr_case(1,0,64,double); - _cimg_load_inr_case(1,1,64,double); - if (!loaded) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_inr(): Unknown pixel type defined in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Load image from a EXR file. - /** - \param filename Filename, as a C-string. - **/ - CImg& load_exr(const char *const filename) { - if (!filename) - throw CImgArgumentException(_cimg_instance - "load_exr(): Specified filename is (null).", - cimg_instance); - -#ifndef cimg_use_openexr - return load_other(filename); -#else - Imf::RgbaInputFile file(filename); - Imath::Box2i dw = file.dataWindow(); - const int - inwidth = dw.max.x - dw.min.x + 1, - inheight = dw.max.y - dw.min.y + 1; - Imf::Array2D pixels; - pixels.resizeErase(inheight,inwidth); - file.setFrameBuffer(&pixels[0][0] - dw.min.x - dw.min.y*inwidth, 1, inwidth); - file.readPixels(dw.min.y, dw.max.y); - assign(inwidth,inheight,1,4); - T *ptr_r = data(0,0,0,0), *ptr_g = data(0,0,0,1), *ptr_b = data(0,0,0,2), *ptr_a = data(0,0,0,3); - cimg_forXY(*this,x,y) { - *(ptr_r++) = (T)pixels[y][x].r; - *(ptr_g++) = (T)pixels[y][x].g; - *(ptr_b++) = (T)pixels[y][x].b; - *(ptr_a++) = (T)pixels[y][x].a; - } - return *this; -#endif - } - - //! Load image from a EXR file \newinstance. - static CImg get_load_exr(const char *const filename) { - return CImg().load_exr(filename); - } - - //! Load image from a PANDORE-5 file. - /** - \param filename Filename, as a C-string. - **/ - CImg& load_pandore(const char *const filename) { - return _load_pandore(0,filename); - } - - //! Load image from a PANDORE-5 file \newinstance. - static CImg get_load_pandore(const char *const filename) { - return CImg().load_pandore(filename); - } - - //! Load image from a PANDORE-5 file \overloading. - CImg& load_pandore(std::FILE *const file) { - return _load_pandore(file,0); - } - - //! Load image from a PANDORE-5 file \newinstance. - static CImg get_load_pandore(std::FILE *const file) { - return CImg().load_pandore(file); - } - - CImg& _load_pandore(std::FILE *const file, const char *const filename) { -#define __cimg_load_pandore_case(nbdim,nwidth,nheight,ndepth,ndim,stype) \ - cimg::fread(dims,nbdim,nfile); \ - if (endian) cimg::invert_endianness(dims,nbdim); \ - assign(nwidth,nheight,ndepth,ndim); \ - const size_t siz = size(); \ - stype *buffer = new stype[siz]; \ - cimg::fread(buffer,siz,nfile); \ - if (endian) cimg::invert_endianness(buffer,siz); \ - T *ptrd = _data; \ - cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++); \ - buffer-=siz; \ - delete[] buffer - -#define _cimg_load_pandore_case(nbdim,nwidth,nheight,ndepth,dim,stype1,stype2,stype3,ltype) { \ - if (sizeof(stype1)==ltype) { __cimg_load_pandore_case(nbdim,nwidth,nheight,ndepth,dim,stype1); } \ - else if (sizeof(stype2)==ltype) { __cimg_load_pandore_case(nbdim,nwidth,nheight,ndepth,dim,stype2); } \ - else if (sizeof(stype3)==ltype) { __cimg_load_pandore_case(nbdim,nwidth,nheight,ndepth,dim,stype3); } \ - else throw CImgIOException(_cimg_instance \ - "load_pandore(): Unknown pixel datatype in file '%s'.", \ - cimg_instance, \ - filename?filename:"(FILE*)"); } - - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "load_pandore(): Specified filename is (null).", - cimg_instance); - - std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); - CImg header(32); - cimg::fread(header._data,12,nfile); - if (cimg::strncasecmp("PANDORE",header,7)) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_pandore(): PANDORE header not found in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - } - unsigned int imageid, dims[8] = { 0 }; - int ptbuf[4] = { 0 }; - cimg::fread(&imageid,1,nfile); - const bool endian = imageid>255; - if (endian) cimg::invert_endianness(imageid); - cimg::fread(header._data,20,nfile); - - switch (imageid) { - case 2 : _cimg_load_pandore_case(2,dims[1],1,1,1,unsigned char,unsigned char,unsigned char,1); break; - case 3 : _cimg_load_pandore_case(2,dims[1],1,1,1,long,int,short,4); break; - case 4 : _cimg_load_pandore_case(2,dims[1],1,1,1,double,float,float,4); break; - case 5 : _cimg_load_pandore_case(3,dims[2],dims[1],1,1,unsigned char,unsigned char,unsigned char,1); break; - case 6 : _cimg_load_pandore_case(3,dims[2],dims[1],1,1,long,int,short,4); break; - case 7 : _cimg_load_pandore_case(3,dims[2],dims[1],1,1,double,float,float,4); break; - case 8 : _cimg_load_pandore_case(4,dims[3],dims[2],dims[1],1,unsigned char,unsigned char,unsigned char,1); break; - case 9 : _cimg_load_pandore_case(4,dims[3],dims[2],dims[1],1,long,int,short,4); break; - case 10 : _cimg_load_pandore_case(4,dims[3],dims[2],dims[1],1,double,float,float,4); break; - case 11 : { // Region 1d - cimg::fread(dims,3,nfile); - if (endian) cimg::invert_endianness(dims,3); - assign(dims[1],1,1,1); - const unsigned siz = size(); - if (dims[2]<256) { - unsigned char *buffer = new unsigned char[siz]; - cimg::fread(buffer,siz,nfile); - T *ptrd = _data; - cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++); - buffer-=siz; - delete[] buffer; - } else { - if (dims[2]<65536) { - unsigned short *buffer = new unsigned short[siz]; - cimg::fread(buffer,siz,nfile); - if (endian) cimg::invert_endianness(buffer,siz); - T *ptrd = _data; - cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++); - buffer-=siz; - delete[] buffer; - } else { - unsigned int *buffer = new unsigned int[siz]; - cimg::fread(buffer,siz,nfile); - if (endian) cimg::invert_endianness(buffer,siz); - T *ptrd = _data; - cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++); - buffer-=siz; - delete[] buffer; - } - } - } - break; - case 12 : { // Region 2d - cimg::fread(dims,4,nfile); - if (endian) cimg::invert_endianness(dims,4); - assign(dims[2],dims[1],1,1); - const size_t siz = size(); - if (dims[3]<256) { - unsigned char *buffer = new unsigned char[siz]; - cimg::fread(buffer,siz,nfile); - T *ptrd = _data; - cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++); - buffer-=siz; - delete[] buffer; - } else { - if (dims[3]<65536) { - unsigned short *buffer = new unsigned short[siz]; - cimg::fread(buffer,siz,nfile); - if (endian) cimg::invert_endianness(buffer,siz); - T *ptrd = _data; - cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++); - buffer-=siz; - delete[] buffer; - } else { - unsigned int *buffer = new unsigned int[siz]; - cimg::fread(buffer,siz,nfile); - if (endian) cimg::invert_endianness(buffer,siz); - T *ptrd = _data; - cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++); - buffer-=siz; - delete[] buffer; - } - } - } - break; - case 13 : { // Region 3d - cimg::fread(dims,5,nfile); - if (endian) cimg::invert_endianness(dims,5); - assign(dims[3],dims[2],dims[1],1); - const size_t siz = size(); - if (dims[4]<256) { - unsigned char *buffer = new unsigned char[siz]; - cimg::fread(buffer,siz,nfile); - T *ptrd = _data; - cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++); - buffer-=siz; - delete[] buffer; - } else { - if (dims[4]<65536) { - unsigned short *buffer = new unsigned short[siz]; - cimg::fread(buffer,siz,nfile); - if (endian) cimg::invert_endianness(buffer,siz); - T *ptrd = _data; - cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++); - buffer-=siz; - delete[] buffer; - } else { - unsigned int *buffer = new unsigned int[siz]; - cimg::fread(buffer,siz,nfile); - if (endian) cimg::invert_endianness(buffer,siz); - T *ptrd = _data; - cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++); - buffer-=siz; - delete[] buffer; - } - } - } - break; - case 16 : _cimg_load_pandore_case(4,dims[2],dims[1],1,3,unsigned char,unsigned char,unsigned char,1); break; - case 17 : _cimg_load_pandore_case(4,dims[2],dims[1],1,3,long,int,short,4); break; - case 18 : _cimg_load_pandore_case(4,dims[2],dims[1],1,3,double,float,float,4); break; - case 19 : _cimg_load_pandore_case(5,dims[3],dims[2],dims[1],3,unsigned char,unsigned char,unsigned char,1); break; - case 20 : _cimg_load_pandore_case(5,dims[3],dims[2],dims[1],3,long,int,short,4); break; - case 21 : _cimg_load_pandore_case(5,dims[3],dims[2],dims[1],3,double,float,float,4); break; - case 22 : _cimg_load_pandore_case(2,dims[1],1,1,dims[0],unsigned char,unsigned char,unsigned char,1); break; - case 23 : _cimg_load_pandore_case(2,dims[1],1,1,dims[0],long,int,short,4); - case 24 : _cimg_load_pandore_case(2,dims[1],1,1,dims[0],unsigned long,unsigned int,unsigned short,4); break; - case 25 : _cimg_load_pandore_case(2,dims[1],1,1,dims[0],double,float,float,4); break; - case 26 : _cimg_load_pandore_case(3,dims[2],dims[1],1,dims[0],unsigned char,unsigned char,unsigned char,1); break; - case 27 : _cimg_load_pandore_case(3,dims[2],dims[1],1,dims[0],long,int,short,4); break; - case 28 : _cimg_load_pandore_case(3,dims[2],dims[1],1,dims[0],unsigned long,unsigned int,unsigned short,4); break; - case 29 : _cimg_load_pandore_case(3,dims[2],dims[1],1,dims[0],double,float,float,4); break; - case 30 : _cimg_load_pandore_case(4,dims[3],dims[2],dims[1],dims[0],unsigned char,unsigned char,unsigned char,1); - break; - case 31 : _cimg_load_pandore_case(4,dims[3],dims[2],dims[1],dims[0],long,int,short,4); break; - case 32 : _cimg_load_pandore_case(4,dims[3],dims[2],dims[1],dims[0],unsigned long,unsigned int,unsigned short,4); - break; - case 33 : _cimg_load_pandore_case(4,dims[3],dims[2],dims[1],dims[0],double,float,float,4); break; - case 34 : { // Points 1d - cimg::fread(ptbuf,1,nfile); - if (endian) cimg::invert_endianness(ptbuf,1); - assign(1); (*this)(0) = (T)ptbuf[0]; - } break; - case 35 : { // Points 2d - cimg::fread(ptbuf,2,nfile); - if (endian) cimg::invert_endianness(ptbuf,2); - assign(2); (*this)(0) = (T)ptbuf[1]; (*this)(1) = (T)ptbuf[0]; - } break; - case 36 : { // Points 3d - cimg::fread(ptbuf,3,nfile); - if (endian) cimg::invert_endianness(ptbuf,3); - assign(3); (*this)(0) = (T)ptbuf[2]; (*this)(1) = (T)ptbuf[1]; (*this)(2) = (T)ptbuf[0]; - } break; - default : - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_pandore(): Unable to load data with ID_type %u in file '%s'.", - cimg_instance, - imageid,filename?filename:"(FILE*)"); - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Load image from a PAR-REC (Philips) file. - /** - \param filename Filename, as a C-string. - \param axis Appending axis, if file contains multiple images. Can be { 'x' | 'y' | 'z' | 'c' }. - \param align Appending alignment. - **/ - CImg& load_parrec(const char *const filename, const char axis='c', const float align=0) { - CImgList list; - list.load_parrec(filename); - if (list._width==1) return list[0].move_to(*this); - return assign(list.get_append(axis,align)); - } - - //! Load image from a PAR-REC (Philips) file \newinstance. - static CImg get_load_parrec(const char *const filename, const char axis='c', const float align=0) { - return CImg().load_parrec(filename,axis,align); - } - - //! Load image from a raw binary file. - /** - \param filename Filename, as a C-string. - \param size_x Width of the image buffer. - \param size_y Height of the image buffer. - \param size_z Depth of the image buffer. - \param size_c Spectrum of the image buffer. - \param is_multiplexed Tells if the image values are multiplexed along the C-axis. - \param invert_endianness Tells if the endianness of the image buffer must be inverted. - \param offset Starting offset of the read in the specified file. - **/ - CImg& load_raw(const char *const filename, - const unsigned int size_x=0, const unsigned int size_y=1, - const unsigned int size_z=1, const unsigned int size_c=1, - const bool is_multiplexed=false, const bool invert_endianness=false, - const ulongT offset=0) { - return _load_raw(0,filename,size_x,size_y,size_z,size_c,is_multiplexed,invert_endianness,offset); - } - - //! Load image from a raw binary file \newinstance. - static CImg get_load_raw(const char *const filename, - const unsigned int size_x=0, const unsigned int size_y=1, - const unsigned int size_z=1, const unsigned int size_c=1, - const bool is_multiplexed=false, const bool invert_endianness=false, - const ulongT offset=0) { - return CImg().load_raw(filename,size_x,size_y,size_z,size_c,is_multiplexed,invert_endianness,offset); - } - - //! Load image from a raw binary file \overloading. - CImg& load_raw(std::FILE *const file, - const unsigned int size_x=0, const unsigned int size_y=1, - const unsigned int size_z=1, const unsigned int size_c=1, - const bool is_multiplexed=false, const bool invert_endianness=false, - const ulongT offset=0) { - return _load_raw(file,0,size_x,size_y,size_z,size_c,is_multiplexed,invert_endianness,offset); - } - - //! Load image from a raw binary file \newinstance. - static CImg get_load_raw(std::FILE *const file, - const unsigned int size_x=0, const unsigned int size_y=1, - const unsigned int size_z=1, const unsigned int size_c=1, - const bool is_multiplexed=false, const bool invert_endianness=false, - const ulongT offset=0) { - return CImg().load_raw(file,size_x,size_y,size_z,size_c,is_multiplexed,invert_endianness,offset); - } - - CImg& _load_raw(std::FILE *const file, const char *const filename, - const unsigned int size_x, const unsigned int size_y, - const unsigned int size_z, const unsigned int size_c, - const bool is_multiplexed, const bool invert_endianness, - const ulongT offset) { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "load_raw(): Specified filename is (null).", - cimg_instance); - if (cimg::is_directory(filename)) - throw CImgArgumentException(_cimg_instance - "load_raw(): Specified filename '%s' is a directory.", - cimg_instance,filename); - - ulongT siz = (ulongT)size_x*size_y*size_z*size_c; - unsigned int - _size_x = size_x, - _size_y = size_y, - _size_z = size_z, - _size_c = size_c; - std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); - if (!siz) { // Retrieve file size. - const longT fpos = cimg::ftell(nfile); - if (fpos<0) throw CImgArgumentException(_cimg_instance - "load_raw(): Cannot determine size of input file '%s'.", - cimg_instance,filename?filename:"(FILE*)"); - cimg::fseek(nfile,0,SEEK_END); - siz = cimg::ftell(nfile)/sizeof(T); - _size_y = (unsigned int)siz; - _size_x = _size_z = _size_c = 1; - cimg::fseek(nfile,fpos,SEEK_SET); - } - cimg::fseek(nfile,offset,SEEK_SET); - assign(_size_x,_size_y,_size_z,_size_c,0); - if (siz && (!is_multiplexed || size_c==1)) { - cimg::fread(_data,siz,nfile); - if (invert_endianness) cimg::invert_endianness(_data,siz); - } else if (siz) { - CImg buf(1,1,1,_size_c); - cimg_forXYZ(*this,x,y,z) { - cimg::fread(buf._data,_size_c,nfile); - if (invert_endianness) cimg::invert_endianness(buf._data,_size_c); - set_vector_at(buf,x,y,z); - } - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Load image sequence from a YUV file. - /** - \param filename Filename, as a C-string. - \param size_x Width of the frames. - \param size_y Height of the frames. - \param first_frame Index of the first frame to read. - \param last_frame Index of the last frame to read. - \param step_frame Step value for frame reading. - \param yuv2rgb Tells if the YUV to RGB transform must be applied. - \param axis Appending axis, if file contains multiple images. Can be { 'x' | 'y' | 'z' | 'c' }. - **/ - CImg& load_yuv(const char *const filename, - const unsigned int size_x, const unsigned int size_y=1, - const unsigned int first_frame=0, const unsigned int last_frame=~0U, - const unsigned int step_frame=1, const bool yuv2rgb=true, const char axis='z') { - return get_load_yuv(filename,size_x,size_y,first_frame,last_frame,step_frame,yuv2rgb,axis).move_to(*this); - } - - //! Load image sequence from a YUV file \newinstance. - static CImg get_load_yuv(const char *const filename, - const unsigned int size_x, const unsigned int size_y=1, - const unsigned int first_frame=0, const unsigned int last_frame=~0U, - const unsigned int step_frame=1, const bool yuv2rgb=true, const char axis='z') { - return CImgList().load_yuv(filename,size_x,size_y,first_frame,last_frame,step_frame,yuv2rgb).get_append(axis); - } - - //! Load image sequence from a YUV file \overloading. - CImg& load_yuv(std::FILE *const file, - const unsigned int size_x, const unsigned int size_y=1, - const unsigned int first_frame=0, const unsigned int last_frame=~0U, - const unsigned int step_frame=1, const bool yuv2rgb=true, const char axis='z') { - return get_load_yuv(file,size_x,size_y,first_frame,last_frame,step_frame,yuv2rgb,axis).move_to(*this); - } - - //! Load image sequence from a YUV file \newinstance. - static CImg get_load_yuv(std::FILE *const file, - const unsigned int size_x, const unsigned int size_y=1, - const unsigned int first_frame=0, const unsigned int last_frame=~0U, - const unsigned int step_frame=1, const bool yuv2rgb=true, const char axis='z') { - return CImgList().load_yuv(file,size_x,size_y,first_frame,last_frame,step_frame,yuv2rgb).get_append(axis); - } - - //! Load 3d object from a .OFF file. - /** - \param[out] primitives Primitives data of the 3d object. - \param[out] colors Colors data of the 3d object. - \param filename Filename, as a C-string. - **/ - template - CImg& load_off(CImgList& primitives, CImgList& colors, const char *const filename) { - return _load_off(primitives,colors,0,filename); - } - - //! Load 3d object from a .OFF file \newinstance. - template - static CImg get_load_off(CImgList& primitives, CImgList& colors, const char *const filename) { - return CImg().load_off(primitives,colors,filename); - } - - //! Load 3d object from a .OFF file \overloading. - template - CImg& load_off(CImgList& primitives, CImgList& colors, std::FILE *const file) { - return _load_off(primitives,colors,file,0); - } - - //! Load 3d object from a .OFF file \newinstance. - template - static CImg get_load_off(CImgList& primitives, CImgList& colors, std::FILE *const file) { - return CImg().load_off(primitives,colors,file); - } - - template - CImg& _load_off(CImgList& primitives, CImgList& colors, - std::FILE *const file, const char *const filename) { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "load_off(): Specified filename is (null).", - cimg_instance); - - std::FILE *const nfile = file?file:cimg::fopen(filename,"r"); - unsigned int nb_points = 0, nb_primitives = 0, nb_read = 0; - CImg line(256); *line = 0; - int err; - - // Skip comments, and read magic string OFF - do { err = std::fscanf(nfile,"%255[^\n] ",line._data); } while (!err || (err==1 && *line=='#')); - if (cimg::strncasecmp(line,"OFF",3) && cimg::strncasecmp(line,"COFF",4)) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_off(): OFF header not found in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - } - do { err = std::fscanf(nfile,"%255[^\n] ",line._data); } while (!err || (err==1 && *line=='#')); - if ((err = cimg_sscanf(line,"%u%u%*[^\n] ",&nb_points,&nb_primitives))!=2) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_off(): Invalid number of vertices or primitives specified in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - } - - // Read points data - assign(nb_points,3); - float X = 0, Y = 0, Z = 0; - cimg_forX(*this,l) { - do { err = std::fscanf(nfile,"%255[^\n] ",line._data); } while (!err || (err==1 && *line=='#')); - if ((err = cimg_sscanf(line,"%f%f%f%*[^\n] ",&X,&Y,&Z))!=3) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "load_off(): Failed to read vertex %u/%u in file '%s'.", - cimg_instance, - l + 1,nb_points,filename?filename:"(FILE*)"); - } - (*this)(l,0) = (T)X; (*this)(l,1) = (T)Y; (*this)(l,2) = (T)Z; - } - - // Read primitive data - primitives.assign(); - colors.assign(); - bool stop_flag = false; - while (!stop_flag) { - float c0 = 0.7f, c1 = 0.7f, c2 = 0.7f; - unsigned int prim = 0, i0 = 0, i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0; - *line = 0; - if ((err = std::fscanf(nfile,"%u",&prim))!=1) stop_flag = true; - else { - ++nb_read; - switch (prim) { - case 1 : { - if ((err = std::fscanf(nfile,"%u%255[^\n] ",&i0,line._data))<2) { - cimg::warn(_cimg_instance - "load_off(): Failed to read primitive %u/%u from file '%s'.", - cimg_instance, - nb_read,nb_primitives,filename?filename:"(FILE*)"); - - err = std::fscanf(nfile,"%*[^\n] "); - } else { - err = cimg_sscanf(line,"%f%f%f",&c0,&c1,&c2); - CImg::vector(i0).move_to(primitives); - CImg::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255)).move_to(colors); - } - } break; - case 2 : { - if ((err = std::fscanf(nfile,"%u%u%255[^\n] ",&i0,&i1,line._data))<2) { - cimg::warn(_cimg_instance - "load_off(): Failed to read primitive %u/%u from file '%s'.", - cimg_instance, - nb_read,nb_primitives,filename?filename:"(FILE*)"); - - err = std::fscanf(nfile,"%*[^\n] "); - } else { - err = cimg_sscanf(line,"%f%f%f",&c0,&c1,&c2); - CImg::vector(i0,i1).move_to(primitives); - CImg::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255)).move_to(colors); - } - } break; - case 3 : { - if ((err = std::fscanf(nfile,"%u%u%u%255[^\n] ",&i0,&i1,&i2,line._data))<3) { - cimg::warn(_cimg_instance - "load_off(): Failed to read primitive %u/%u from file '%s'.", - cimg_instance, - nb_read,nb_primitives,filename?filename:"(FILE*)"); - - err = std::fscanf(nfile,"%*[^\n] "); - } else { - err = cimg_sscanf(line,"%f%f%f",&c0,&c1,&c2); - CImg::vector(i0,i2,i1).move_to(primitives); - CImg::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255)).move_to(colors); - } - } break; - case 4 : { - if ((err = std::fscanf(nfile,"%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,line._data))<4) { - cimg::warn(_cimg_instance - "load_off(): Failed to read primitive %u/%u from file '%s'.", - cimg_instance, - nb_read,nb_primitives,filename?filename:"(FILE*)"); - - err = std::fscanf(nfile,"%*[^\n] "); - } else { - err = cimg_sscanf(line,"%f%f%f",&c0,&c1,&c2); - CImg::vector(i0,i3,i2,i1).move_to(primitives); - CImg::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255)).move_to(colors); - } - } break; - case 5 : { - if ((err = std::fscanf(nfile,"%u%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,&i4,line._data))<5) { - cimg::warn(_cimg_instance - "load_off(): Failed to read primitive %u/%u from file '%s'.", - cimg_instance, - nb_read,nb_primitives,filename?filename:"(FILE*)"); - - err = std::fscanf(nfile,"%*[^\n] "); - } else { - err = cimg_sscanf(line,"%f%f%f",&c0,&c1,&c2); - CImg::vector(i0,i3,i2,i1).move_to(primitives); - CImg::vector(i0,i4,i3).move_to(primitives); - colors.insert(2,CImg::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255))); - ++nb_primitives; - } - } break; - case 6 : { - if ((err = std::fscanf(nfile,"%u%u%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,&i4,&i5,line._data))<6) { - cimg::warn(_cimg_instance - "load_off(): Failed to read primitive %u/%u from file '%s'.", - cimg_instance, - nb_read,nb_primitives,filename?filename:"(FILE*)"); - - err = std::fscanf(nfile,"%*[^\n] "); - } else { - err = cimg_sscanf(line,"%f%f%f",&c0,&c1,&c2); - CImg::vector(i0,i3,i2,i1).move_to(primitives); - CImg::vector(i0,i5,i4,i3).move_to(primitives); - colors.insert(2,CImg::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255))); - ++nb_primitives; - } - } break; - case 7 : { - if ((err = std::fscanf(nfile,"%u%u%u%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,&i4,&i5,&i6,line._data))<7) { - cimg::warn(_cimg_instance - "load_off(): Failed to read primitive %u/%u from file '%s'.", - cimg_instance, - nb_read,nb_primitives,filename?filename:"(FILE*)"); - - err = std::fscanf(nfile,"%*[^\n] "); - } else { - err = cimg_sscanf(line,"%f%f%f",&c0,&c1,&c2); - CImg::vector(i0,i4,i3,i1).move_to(primitives); - CImg::vector(i0,i6,i5,i4).move_to(primitives); - CImg::vector(i3,i2,i1).move_to(primitives); - colors.insert(3,CImg::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255))); - ++(++nb_primitives); - } - } break; - case 8 : { - if ((err = std::fscanf(nfile,"%u%u%u%u%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,&i4,&i5,&i6,&i7,line._data))<7) { - cimg::warn(_cimg_instance - "load_off(): Failed to read primitive %u/%u from file '%s'.", - cimg_instance, - nb_read,nb_primitives,filename?filename:"(FILE*)"); - - err = std::fscanf(nfile,"%*[^\n] "); - } else { - err = cimg_sscanf(line,"%f%f%f",&c0,&c1,&c2); - CImg::vector(i0,i3,i2,i1).move_to(primitives); - CImg::vector(i0,i5,i4,i3).move_to(primitives); - CImg::vector(i0,i7,i6,i5).move_to(primitives); - colors.insert(3,CImg::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255))); - ++(++nb_primitives); - } - } break; - default : - cimg::warn(_cimg_instance - "load_off(): Failed to read primitive %u/%u (%u vertices) from file '%s'.", - cimg_instance, - nb_read,nb_primitives,prim,filename?filename:"(FILE*)"); - - err = std::fscanf(nfile,"%*[^\n] "); - } - } - } - if (!file) cimg::fclose(nfile); - if (primitives._width!=nb_primitives) - cimg::warn(_cimg_instance - "load_off(): Only %u/%u primitives read from file '%s'.", - cimg_instance, - primitives._width,nb_primitives,filename?filename:"(FILE*)"); - return *this; - } - - //! Load image sequence from a video file, using OpenCV library. - /** - \param filename Filename, as a C-string. - \param first_frame Index of the first frame to read. - \param last_frame Index of the last frame to read. - \param step_frame Step value for frame reading. - **/ - CImg& load_video(const char *const filename, - const unsigned int first_frame=0, const unsigned int last_frame=~0U, - const unsigned int step_frame=1, - const char axis='z', const float align=0) { - return get_load_video(filename,first_frame,last_frame,step_frame,axis,align).move_to(*this); - } - - //! Load image sequence from a video file, using OpenCV library \newinstance. - static CImg get_load_video(const char *const filename, - const unsigned int first_frame=0, const unsigned int last_frame=~0U, - const unsigned int step_frame=1, - const char axis='z', const float align=0) { - return CImgList().load_video(filename,first_frame,last_frame,step_frame).get_append(axis,align); - } - - //! Load image sequence using FFMPEG's external tool 'ffmpeg'. - /** - \param filename Filename, as a C-string. - \param axis Appending axis, if file contains multiple images. Can be { 'x' | 'y' | 'z' | 'c' }. - \param align Appending alignment. - **/ - CImg& load_ffmpeg_external(const char *const filename, const char axis='z', const float align=0) { - return get_load_ffmpeg_external(filename,axis,align).move_to(*this); - } - - //! Load image sequence using FFMPEG's external tool 'ffmpeg' \newinstance. - static CImg get_load_ffmpeg_external(const char *const filename, const char axis='z', const float align=0) { - return CImgList().load_ffmpeg_external(filename).get_append(axis,align); - } - - //! Load gif file, using Imagemagick or GraphicsMagicks's external tools. - /** - \param filename Filename, as a C-string. - \param use_graphicsmagick Tells if GraphicsMagick's tool 'gm' is used instead of ImageMagick's tool 'convert'. - \param axis Appending axis, if file contains multiple images. Can be { 'x' | 'y' | 'z' | 'c' }. - \param align Appending alignment. - **/ - CImg& load_gif_external(const char *const filename, - const char axis='z', const float align=0) { - return get_load_gif_external(filename,axis,align).move_to(*this); - } - - //! Load gif file, using ImageMagick or GraphicsMagick's external tool 'convert' \newinstance. - static CImg get_load_gif_external(const char *const filename, - const char axis='z', const float align=0) { - return CImgList().load_gif_external(filename).get_append(axis,align); - } - - //! Load image using GraphicsMagick's external tool 'gm'. - /** - \param filename Filename, as a C-string. - **/ - CImg& load_graphicsmagick_external(const char *const filename) { - if (!filename) - throw CImgArgumentException(_cimg_instance - "load_graphicsmagick_external(): Specified filename is (null).", - cimg_instance); - std::fclose(cimg::fopen(filename,"rb")); // Check if file exists. - CImg command(1024), filename_tmp(256); - std::FILE *file = 0; - const CImg s_filename = CImg::string(filename)._system_strescape(); -#if cimg_OS==1 - cimg_snprintf(command,command._width,"%s convert \"%s\" pnm:-", - cimg::graphicsmagick_path(),s_filename.data()); - file = popen(command,"r"); - if (file) { - const unsigned int omode = cimg::exception_mode(); - cimg::exception_mode(0); - try { load_pnm(file); } catch (...) { - pclose(file); - cimg::exception_mode(omode); - throw CImgIOException(_cimg_instance - "load_graphicsmagick_external(): Failed to load file '%s' with external command 'gm'.", - cimg_instance, - filename); - } - pclose(file); - return *this; - } -#endif - do { - cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.pnm", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand()); - if ((file=std_fopen(filename_tmp,"rb"))!=0) cimg::fclose(file); - } while (file); - cimg_snprintf(command,command._width,"%s convert \"%s\" \"%s\"", - cimg::graphicsmagick_path(),s_filename.data(), - CImg::string(filename_tmp)._system_strescape().data()); - cimg::system(command,cimg::graphicsmagick_path()); - if (!(file = std_fopen(filename_tmp,"rb"))) { - cimg::fclose(cimg::fopen(filename,"r")); - throw CImgIOException(_cimg_instance - "load_graphicsmagick_external(): Failed to load file '%s' with external command 'gm'.", - cimg_instance, - filename); - - } else cimg::fclose(file); - load_pnm(filename_tmp); - std::remove(filename_tmp); - return *this; - } - - //! Load image using GraphicsMagick's external tool 'gm' \newinstance. - static CImg get_load_graphicsmagick_external(const char *const filename) { - return CImg().load_graphicsmagick_external(filename); - } - - //! Load gzipped image file, using external tool 'gunzip'. - /** - \param filename Filename, as a C-string. - **/ - CImg& load_gzip_external(const char *const filename) { - if (!filename) - throw CImgIOException(_cimg_instance - "load_gzip_external(): Specified filename is (null).", - cimg_instance); - std::fclose(cimg::fopen(filename,"rb")); // Check if file exists. - CImg command(1024), filename_tmp(256), body(256); - const char - *const ext = cimg::split_filename(filename,body), - *const ext2 = cimg::split_filename(body,0); - - std::FILE *file = 0; - do { - if (!cimg::strcasecmp(ext,"gz")) { - if (*ext2) cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.%s", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),ext2); - else cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand()); - } else { - if (*ext) cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.%s", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),ext); - else cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand()); - } - if ((file=std_fopen(filename_tmp,"rb"))!=0) cimg::fclose(file); - } while (file); - cimg_snprintf(command,command._width,"%s -c \"%s\" > \"%s\"", - cimg::gunzip_path(), - CImg::string(filename)._system_strescape().data(), - CImg::string(filename_tmp)._system_strescape().data()); - cimg::system(command); - if (!(file = std_fopen(filename_tmp,"rb"))) { - cimg::fclose(cimg::fopen(filename,"r")); - throw CImgIOException(_cimg_instance - "load_gzip_external(): Failed to load file '%s' with external command 'gunzip'.", - cimg_instance, - filename); - - } else cimg::fclose(file); - load(filename_tmp); - std::remove(filename_tmp); - return *this; - } - - //! Load gzipped image file, using external tool 'gunzip' \newinstance. - static CImg get_load_gzip_external(const char *const filename) { - return CImg().load_gzip_external(filename); - } - - //! Load image using ImageMagick's external tool 'convert'. - /** - \param filename Filename, as a C-string. - **/ - CImg& load_imagemagick_external(const char *const filename) { - if (!filename) - throw CImgArgumentException(_cimg_instance - "load_imagemagick_external(): Specified filename is (null).", - cimg_instance); - std::fclose(cimg::fopen(filename,"rb")); // Check if file exists. - CImg command(1024), filename_tmp(256); - std::FILE *file = 0; - const CImg s_filename = CImg::string(filename)._system_strescape(); -#if cimg_OS==1 - cimg_snprintf(command,command._width,"%s%s \"%s\" pnm:-", - cimg::imagemagick_path(), - !cimg::strcasecmp(cimg::split_filename(filename),"pdf")?" -density 400x400":"", - s_filename.data()); - file = popen(command,"r"); - if (file) { - const unsigned int omode = cimg::exception_mode(); - cimg::exception_mode(0); - try { load_pnm(file); } catch (...) { - pclose(file); - cimg::exception_mode(omode); - throw CImgIOException(_cimg_instance - "load_imagemagick_external(): Failed to load file '%s' with " - "external command 'convert'.", - cimg_instance, - filename); - } - pclose(file); - return *this; - } -#endif - do { - cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.pnm", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand()); - if ((file=std_fopen(filename_tmp,"rb"))!=0) cimg::fclose(file); - } while (file); - cimg_snprintf(command,command._width,"%s%s \"%s\" \"%s\"", - cimg::imagemagick_path(), - !cimg::strcasecmp(cimg::split_filename(filename),"pdf")?" -density 400x400":"", - s_filename.data(),CImg::string(filename_tmp)._system_strescape().data()); - cimg::system(command,cimg::imagemagick_path()); - if (!(file = std_fopen(filename_tmp,"rb"))) { - cimg::fclose(cimg::fopen(filename,"r")); - throw CImgIOException(_cimg_instance - "load_imagemagick_external(): Failed to load file '%s' with external command 'convert'.", - cimg_instance, - filename); - - } else cimg::fclose(file); - load_pnm(filename_tmp); - std::remove(filename_tmp); - return *this; - } - - //! Load image using ImageMagick's external tool 'convert' \newinstance. - static CImg get_load_imagemagick_external(const char *const filename) { - return CImg().load_imagemagick_external(filename); - } - - //! Load image from a DICOM file, using XMedcon's external tool 'medcon'. - /** - \param filename Filename, as a C-string. - **/ - CImg& load_medcon_external(const char *const filename) { - if (!filename) - throw CImgArgumentException(_cimg_instance - "load_medcon_external(): Specified filename is (null).", - cimg_instance); - std::fclose(cimg::fopen(filename,"rb")); // Check if file exists. - CImg command(1024), filename_tmp(256), body(256); - cimg::fclose(cimg::fopen(filename,"r")); - std::FILE *file = 0; - do { - cimg_snprintf(filename_tmp,filename_tmp._width,"%s.hdr",cimg::filenamerand()); - if ((file=std_fopen(filename_tmp,"rb"))!=0) cimg::fclose(file); - } while (file); - cimg_snprintf(command,command._width,"%s -w -c anlz -o \"%s\" -f \"%s\"", - cimg::medcon_path(), - CImg::string(filename_tmp)._system_strescape().data(), - CImg::string(filename)._system_strescape().data()); - cimg::system(command); - cimg::split_filename(filename_tmp,body); - - cimg_snprintf(command,command._width,"%s.hdr",body._data); - file = std_fopen(command,"rb"); - if (!file) { - cimg_snprintf(command,command._width,"m000-%s.hdr",body._data); - file = std_fopen(command,"rb"); - if (!file) { - throw CImgIOException(_cimg_instance - "load_medcon_external(): Failed to load file '%s' with external command 'medcon'.", - cimg_instance, - filename); - } - } - cimg::fclose(file); - load_analyze(command); - std::remove(command); - cimg::split_filename(command,body); - cimg_snprintf(command,command._width,"%s.img",body._data); - std::remove(command); - return *this; - } - - //! Load image from a DICOM file, using XMedcon's external tool 'medcon' \newinstance. - static CImg get_load_medcon_external(const char *const filename) { - return CImg().load_medcon_external(filename); - } - - //! Load image from a RAW Color Camera file, using external tool 'dcraw'. - /** - \param filename Filename, as a C-string. - **/ - CImg& load_dcraw_external(const char *const filename) { - if (!filename) - throw CImgArgumentException(_cimg_instance - "load_dcraw_external(): Specified filename is (null).", - cimg_instance); - std::fclose(cimg::fopen(filename,"rb")); // Check if file exists. - CImg command(1024), filename_tmp(256); - std::FILE *file = 0; - const CImg s_filename = CImg::string(filename)._system_strescape(); -#if cimg_OS==1 - cimg_snprintf(command,command._width,"%s -w -4 -c \"%s\"", - cimg::dcraw_path(),s_filename.data()); - file = popen(command,"r"); - if (file) { - const unsigned int omode = cimg::exception_mode(); - cimg::exception_mode(0); - try { load_pnm(file); } catch (...) { - pclose(file); - cimg::exception_mode(omode); - throw CImgIOException(_cimg_instance - "load_dcraw_external(): Failed to load file '%s' with external command 'dcraw'.", - cimg_instance, - filename); - } - pclose(file); - return *this; - } -#endif - do { - cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.ppm", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand()); - if ((file=std_fopen(filename_tmp,"rb"))!=0) cimg::fclose(file); - } while (file); - cimg_snprintf(command,command._width,"%s -w -4 -c \"%s\" > \"%s\"", - cimg::dcraw_path(),s_filename.data(),CImg::string(filename_tmp)._system_strescape().data()); - cimg::system(command,cimg::dcraw_path()); - if (!(file = std_fopen(filename_tmp,"rb"))) { - cimg::fclose(cimg::fopen(filename,"r")); - throw CImgIOException(_cimg_instance - "load_dcraw_external(): Failed to load file '%s' with external command 'dcraw'.", - cimg_instance, - filename); - - } else cimg::fclose(file); - load_pnm(filename_tmp); - std::remove(filename_tmp); - return *this; - } - - //! Load image from a RAW Color Camera file, using external tool 'dcraw' \newinstance. - static CImg get_load_dcraw_external(const char *const filename) { - return CImg().load_dcraw_external(filename); - } - - //! Load image from a camera stream, using OpenCV. - /** - \param camera_index Index of the camera to capture images from. - \param skip_frames Number of frames to skip before the capture. - \param release_camera Tells if the camera ressource must be released at the end of the method. - **/ - CImg& load_camera(const unsigned int camera_index=0, const unsigned int skip_frames=0, - const bool release_camera=true, const unsigned int capture_width=0, - const unsigned int capture_height=0) { -#ifdef cimg_use_opencv - if (camera_index>99) - throw CImgArgumentException(_cimg_instance - "load_camera(): Invalid request for camera #%u " - "(no more than 100 cameras can be managed simultaneously).", - cimg_instance, - camera_index); - static CvCapture *capture[100] = { 0 }; - static unsigned int capture_w[100], capture_h[100]; - if (release_camera) { - cimg::mutex(9); - if (capture[camera_index]) cvReleaseCapture(&(capture[camera_index])); - capture[camera_index] = 0; - capture_w[camera_index] = capture_h[camera_index] = 0; - cimg::mutex(9,0); - return *this; - } - if (!capture[camera_index]) { - cimg::mutex(9); - capture[camera_index] = cvCreateCameraCapture(camera_index); - capture_w[camera_index] = 0; - capture_h[camera_index] = 0; - cimg::mutex(9,0); - if (!capture[camera_index]) { - throw CImgIOException(_cimg_instance - "load_camera(): Failed to initialize camera #%u.", - cimg_instance, - camera_index); - } - } - cimg::mutex(9); - if (capture_width!=capture_w[camera_index]) { - cvSetCaptureProperty(capture[camera_index],CV_CAP_PROP_FRAME_WIDTH,capture_width); - capture_w[camera_index] = capture_width; - } - if (capture_height!=capture_h[camera_index]) { - cvSetCaptureProperty(capture[camera_index],CV_CAP_PROP_FRAME_HEIGHT,capture_height); - capture_h[camera_index] = capture_height; - } - const IplImage *img = 0; - for (unsigned int i = 0; iwidthStep - 3*img->width); - assign(img->width,img->height,1,3); - const unsigned char* ptrs = (unsigned char*)img->imageData; - T *ptr_r = data(0,0,0,0), *ptr_g = data(0,0,0,1), *ptr_b = data(0,0,0,2); - if (step>0) cimg_forY(*this,y) { - cimg_forX(*this,x) { *(ptr_b++) = (T)*(ptrs++); *(ptr_g++) = (T)*(ptrs++); *(ptr_r++) = (T)*(ptrs++); } - ptrs+=step; - } else for (ulongT siz = (ulongT)img->width*img->height; siz; --siz) { - *(ptr_b++) = (T)*(ptrs++); *(ptr_g++) = (T)*(ptrs++); *(ptr_r++) = (T)*(ptrs++); - } - } - cimg::mutex(9,0); - return *this; -#else - cimg::unused(camera_index,skip_frames,release_camera,capture_width,capture_height); - throw CImgIOException(_cimg_instance - "load_camera(): This function requires the OpenCV library to run " - "(macro 'cimg_use_opencv' must be defined).", - cimg_instance); -#endif - } - - //! Load image from a camera stream, using OpenCV \newinstance. - static CImg get_load_camera(const unsigned int camera_index=0, const unsigned int skip_frames=0, - const bool release_camera=true, - const unsigned int capture_width=0, const unsigned int capture_height=0) { - return CImg().load_camera(camera_index,skip_frames,release_camera,capture_width,capture_height); - } - - //! Load image using various non-native ways. - /** - \param filename Filename, as a C-string. - **/ - CImg& load_other(const char *const filename) { - if (!filename) - throw CImgArgumentException(_cimg_instance - "load_other(): Specified filename is (null).", - cimg_instance); - - const unsigned int omode = cimg::exception_mode(); - cimg::exception_mode(0); - try { load_magick(filename); } - catch (CImgException&) { - try { load_imagemagick_external(filename); } - catch (CImgException&) { - try { load_graphicsmagick_external(filename); } - catch (CImgException&) { - try { load_cimg(filename); } - catch (CImgException&) { - try { - std::fclose(cimg::fopen(filename,"rb")); - } catch (CImgException&) { - cimg::exception_mode(omode); - throw CImgIOException(_cimg_instance - "load_other(): Failed to open file '%s'.", - cimg_instance, - filename); - } - cimg::exception_mode(omode); - throw CImgIOException(_cimg_instance - "load_other(): Failed to recognize format of file '%s'.", - cimg_instance, - filename); - } - } - } - } - cimg::exception_mode(omode); - return *this; - } - - //! Load image using various non-native ways \newinstance. - static CImg get_load_other(const char *const filename) { - return CImg().load_other(filename); - } - - //@} - //--------------------------- - // - //! \name Data Output - //@{ - //--------------------------- - - //! Display information about the image data. - /** - \param title Name for the considered image. - \param display_stats Tells to compute and display image statistics. - **/ - const CImg& print(const char *const title=0, const bool display_stats=true) const { - int xm = 0, ym = 0, zm = 0, vm = 0, xM = 0, yM = 0, zM = 0, vM = 0; - CImg st; - if (!is_empty() && display_stats) { - st = get_stats(); - xm = (int)st[4]; ym = (int)st[5], zm = (int)st[6], vm = (int)st[7]; - xM = (int)st[8]; yM = (int)st[9], zM = (int)st[10], vM = (int)st[11]; - } - const ulongT siz = size(), msiz = siz*sizeof(T), siz1 = siz - 1, - mdisp = msiz<8*1024?0U:msiz<8*1024*1024?1U:2U, width1 = _width - 1; - - CImg _title(64); - if (!title) cimg_snprintf(_title,_title._width,"CImg<%s>",pixel_type()); - - std::fprintf(cimg::output(),"%s%s%s%s: %sthis%s = %p, %ssize%s = (%u,%u,%u,%u) [%lu %s], %sdata%s = (%s*)%p", - cimg::t_magenta,cimg::t_bold,title?title:_title._data,cimg::t_normal, - cimg::t_bold,cimg::t_normal,(void*)this, - cimg::t_bold,cimg::t_normal,_width,_height,_depth,_spectrum, - mdisp==0?msiz:(mdisp==1?(msiz>>10):(msiz>>20)), - mdisp==0?"b":(mdisp==1?"Kio":"Mio"), - cimg::t_bold,cimg::t_normal,pixel_type(),(void*)begin()); - if (_data) - std::fprintf(cimg::output(),"..%p (%s) = [ ",(void*)((char*)end() - 1),_is_shared?"shared":"non-shared"); - else std::fprintf(cimg::output()," (%s) = [ ",_is_shared?"shared":"non-shared"); - - if (!is_empty()) cimg_foroff(*this,off) { - std::fprintf(cimg::output(),cimg::type::format(),cimg::type::format(_data[off])); - if (off!=siz1) std::fprintf(cimg::output(),"%s",off%_width==width1?" ; ":" "); - if (off==7 && siz>16) { off = siz1 - 8; std::fprintf(cimg::output(),"... "); } - } - if (!is_empty() && display_stats) - std::fprintf(cimg::output(), - " ], %smin%s = %g, %smax%s = %g, %smean%s = %g, %sstd%s = %g, %scoords_min%s = (%u,%u,%u,%u), " - "%scoords_max%s = (%u,%u,%u,%u).\n", - cimg::t_bold,cimg::t_normal,st[0], - cimg::t_bold,cimg::t_normal,st[1], - cimg::t_bold,cimg::t_normal,st[2], - cimg::t_bold,cimg::t_normal,std::sqrt(st[3]), - cimg::t_bold,cimg::t_normal,xm,ym,zm,vm, - cimg::t_bold,cimg::t_normal,xM,yM,zM,vM); - else std::fprintf(cimg::output(),"%s].\n",is_empty()?"":" "); - std::fflush(cimg::output()); - return *this; - } - - //! Display image into a CImgDisplay window. - /** - \param disp Display window. - **/ - const CImg& display(CImgDisplay& disp) const { - disp.display(*this); - return *this; - } - - //! Display image into a CImgDisplay window, in an interactive way. - /** - \param disp Display window. - \param display_info Tells if image information are displayed on the standard output. - **/ - const CImg& display(CImgDisplay &disp, const bool display_info, unsigned int *const XYZ=0, - const bool exit_on_anykey=false) const { - return _display(disp,0,display_info,XYZ,exit_on_anykey,false); - } - - //! Display image into an interactive window. - /** - \param title Window title - \param display_info Tells if image information are displayed on the standard output. - **/ - const CImg& display(const char *const title=0, const bool display_info=true, unsigned int *const XYZ=0, - const bool exit_on_anykey=false) const { - CImgDisplay disp; - return _display(disp,title,display_info,XYZ,exit_on_anykey,false); - } - - const CImg& _display(CImgDisplay &disp, const char *const title, const bool display_info, - unsigned int *const XYZ, const bool exit_on_anykey, - const bool exit_on_simpleclick) const { - unsigned int oldw = 0, oldh = 0, _XYZ[3] = { 0 }, key = 0; - int x0 = 0, y0 = 0, z0 = 0, x1 = width() - 1, y1 = height() - 1, z1 = depth() - 1, - old_mouse_x = -1, old_mouse_y = -1; - - if (!disp) { - disp.assign(cimg_fitscreen(_width,_height,_depth),title?title:0,1); - if (!title) disp.set_title("CImg<%s> (%ux%ux%ux%u)",pixel_type(),_width,_height,_depth,_spectrum); - else disp.set_title("%s",title); - } else if (title) disp.set_title("%s",title); - disp.show().flush(); - - const CImg dtitle = CImg::string(disp.title()); - if (display_info) print(dtitle); - - CImg zoom; - for (bool reset_view = true, resize_disp = false, is_first_select = true; !key && !disp.is_closed(); ) { - if (reset_view) { - if (XYZ) { _XYZ[0] = XYZ[0]; _XYZ[1] = XYZ[1]; _XYZ[2] = XYZ[2]; } - else { - _XYZ[0] = (unsigned int)(x0 + x1)/2; - _XYZ[1] = (unsigned int)(y0 + y1)/2; - _XYZ[2] = (unsigned int)(z0 + z1)/2; - } - x0 = 0; y0 = 0; z0 = 0; x1 = width() - 1; y1 = height() - 1; z1 = depth() - 1; - oldw = disp._width; oldh = disp._height; - reset_view = false; - } - if (!x0 && !y0 && !z0 && x1==width() - 1 && y1==height() - 1 && z1==depth() - 1) { - if (is_empty()) zoom.assign(1,1,1,1,0); else zoom.assign(); - } else zoom = get_crop(x0,y0,z0,x1,y1,z1); - - const CImg& visu = zoom?zoom:*this; - - const unsigned int - dx = 1U + x1 - x0, dy = 1U + y1 - y0, dz = 1U + z1 - z0, - tw = dx + (dz>1?dz:0U), th = dy + (dz>1?dz:0U); - if (!is_empty() && !disp.is_fullscreen() && resize_disp) { - const unsigned int - ttw = tw*disp.width()/oldw, tth = th*disp.height()/oldh, - dM = cimg::max(ttw,tth), diM = (unsigned int)cimg::max(disp.width(),disp.height()), - imgw = cimg::max(16U,ttw*diM/dM), imgh = cimg::max(16U,tth*diM/dM); - disp.set_fullscreen(false).resize(cimg_fitscreen(imgw,imgh,1),false); - resize_disp = false; - } - oldw = tw; oldh = th; - - bool - go_up = false, go_down = false, go_left = false, go_right = false, - go_inc = false, go_dec = false, go_in = false, go_out = false, - go_in_center = false; - - disp.set_title("%s",dtitle._data); - if (_width>1 && visu._width==1) disp.set_title("%s | x=%u",disp._title,x0); - if (_height>1 && visu._height==1) disp.set_title("%s | y=%u",disp._title,y0); - if (_depth>1 && visu._depth==1) disp.set_title("%s | z=%u",disp._title,z0); - - if (!is_first_select) { - _XYZ[0] = (unsigned int)(x1 - x0)/2; - _XYZ[1] = (unsigned int)(y1 - y0)/2; - _XYZ[2] = (unsigned int)(z1 - z0)/2; - } - - disp._mouse_x = old_mouse_x; disp._mouse_y = old_mouse_y; - const CImg selection = visu._get_select(disp,0,2,_XYZ,x0,y0,z0,true,is_first_select,_depth>1); - old_mouse_x = disp._mouse_x; old_mouse_y = disp._mouse_y; - is_first_select = false; - - if (disp.wheel()) { - if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - go_down = !(go_up = disp.wheel()>0); - } else if (disp.is_keySHIFTLEFT() || disp.is_keySHIFTRIGHT()) { - go_left = !(go_right = disp.wheel()>0); - } - else if (disp.is_keyALT() || disp.is_keyALTGR() || _depth==1) { - go_out = !(go_in = disp.wheel()>0); go_in_center = false; - } - disp.set_wheel(); - } - - const int - sx0 = selection(0), sy0 = selection(1), sz0 = selection(2), - sx1 = selection(3), sy1 = selection(4), sz1 = selection(5); - if (sx0>=0 && sy0>=0 && sz0>=0 && sx1>=0 && sy1>=0 && sz1>=0) { - x1 = x0 + sx1; y1 = y0 + sy1; z1 = z0 + sz1; - x0+=sx0; y0+=sy0; z0+=sz0; - if (sx0==sx1 && sy0==sy1 && sz0==sz1) { - if (exit_on_simpleclick && (!zoom || is_empty())) break; else reset_view = true; - } - resize_disp = true; - } else switch (key = disp.key()) { -#if cimg_OS!=2 - case cimg::keyCTRLRIGHT : case cimg::keySHIFTRIGHT : -#endif - case 0 : case cimg::keyCTRLLEFT : case cimg::keyPAD5 : case cimg::keySHIFTLEFT : -#if cimg_OS!=2 - case cimg::keyALTGR : -#endif - case cimg::keyALT : key = 0; break; - case cimg::keyP : if (visu._depth>1 && (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT())) { - // Special mode: play stack of frames - const unsigned int - w1 = visu._width*disp.width()/(visu._width + (visu._depth>1?visu._depth:0)), - h1 = visu._height*disp.height()/(visu._height + (visu._depth>1?visu._depth:0)); - float frame_timing = 5; - bool is_stopped = false; - disp.set_key(key,false).set_wheel().resize(cimg_fitscreen(w1,h1,1),false); key = 0; - for (unsigned int timer = 0; !key && !disp.is_closed() && !disp.button(); ) { - if (disp.is_resized()) disp.resize(false); - if (!timer) { - visu.get_slice((int)_XYZ[2]).display(disp.set_title("%s | z=%d",dtitle.data(),_XYZ[2])); - (++_XYZ[2])%=visu._depth; - } - if (!is_stopped) { if (++timer>(unsigned int)frame_timing) timer = 0; } else timer = ~0U; - if (disp.wheel()) { frame_timing-=disp.wheel()/3.0f; disp.set_wheel(); } - switch (key = disp.key()) { -#if cimg_OS!=2 - case cimg::keyCTRLRIGHT : -#endif - case cimg::keyCTRLLEFT : key = 0; break; - case cimg::keyPAGEUP : frame_timing-=0.3f; key = 0; break; - case cimg::keyPAGEDOWN : frame_timing+=0.3f; key = 0; break; - case cimg::keySPACE : is_stopped = !is_stopped; disp.set_key(key,false); key = 0; break; - case cimg::keyARROWLEFT : case cimg::keyARROWUP : is_stopped = true; timer = 0; key = 0; break; - case cimg::keyARROWRIGHT : case cimg::keyARROWDOWN : is_stopped = true; - (_XYZ[2]+=visu._depth - 2)%=visu._depth; timer = 0; key = 0; break; - case cimg::keyD : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - disp.set_fullscreen(false). - resize(CImgDisplay::_fitscreen(3*disp.width()/2,3*disp.height()/2,1,128,-100,false), - CImgDisplay::_fitscreen(3*disp.width()/2,3*disp.height()/2,1,128,-100,true),false); - disp.set_key(key,false); key = 0; - } break; - case cimg::keyC : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - disp.set_fullscreen(false). - resize(cimg_fitscreen(2*disp.width()/3,2*disp.height()/3,1),false).set_key(key,false); key = 0; - } break; - case cimg::keyR : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - disp.set_fullscreen(false). - resize(cimg_fitscreen(_width,_height,_depth),false).set_key(key,false); key = 0; - } break; - case cimg::keyF : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - disp.resize(disp.screen_width(),disp.screen_height(),false). - toggle_fullscreen().set_key(key,false); key = 0; - } break; - } - frame_timing = frame_timing<1?1:(frame_timing>39?39:frame_timing); - disp.wait(20); - } - const unsigned int - w2 = (visu._width + (visu._depth>1?visu._depth:0))*disp.width()/visu._width, - h2 = (visu._height + (visu._depth>1?visu._depth:0))*disp.height()/visu._height; - disp.resize(cimg_fitscreen(w2,h2,1),false).set_title(dtitle.data()).set_key().set_button().set_wheel(); - key = 0; - } break; - case cimg::keyHOME : reset_view = resize_disp = true; key = 0; break; - case cimg::keyPADADD : go_in = true; go_in_center = true; key = 0; break; - case cimg::keyPADSUB : go_out = true; key = 0; break; - case cimg::keyARROWLEFT : case cimg::keyPAD4: go_left = true; key = 0; break; - case cimg::keyARROWRIGHT : case cimg::keyPAD6: go_right = true; key = 0; break; - case cimg::keyARROWUP : case cimg::keyPAD8: go_up = true; key = 0; break; - case cimg::keyARROWDOWN : case cimg::keyPAD2: go_down = true; key = 0; break; - case cimg::keyPAD7 : go_up = go_left = true; key = 0; break; - case cimg::keyPAD9 : go_up = go_right = true; key = 0; break; - case cimg::keyPAD1 : go_down = go_left = true; key = 0; break; - case cimg::keyPAD3 : go_down = go_right = true; key = 0; break; - case cimg::keyPAGEUP : go_inc = true; key = 0; break; - case cimg::keyPAGEDOWN : go_dec = true; key = 0; break; - } - if (go_in) { - const int - mx = go_in_center?disp.width()/2:disp.mouse_x(), - my = go_in_center?disp.height()/2:disp.mouse_y(), - mX = mx*(width() + (depth()>1?depth():0))/disp.width(), - mY = my*(height() + (depth()>1?depth():0))/disp.height(); - int X = (int)_XYZ[0], Y = (int)_XYZ[1], Z = (int)_XYZ[2]; - if (mX=height()) { - X = x0 + mX*(1 + x1 - x0)/width(); Z = z0 + (mY - height())*(1 + z1 - z0)/depth(); Y = (int)_XYZ[1]; - } - if (mX>=width() && mY4) { x0 = X - 3*(X - x0)/4; x1 = X + 3*(x1 - X)/4; } - if (y1 - y0>4) { y0 = Y - 3*(Y - y0)/4; y1 = Y + 3*(y1 - Y)/4; } - if (z1 - z0>4) { z0 = Z - 3*(Z - z0)/4; z1 = Z + 3*(z1 - Z)/4; } - } - if (go_out) { - const int - delta_x = (x1 - x0)/8, delta_y = (y1 - y0)/8, delta_z = (z1 - z0)/8, - ndelta_x = delta_x?delta_x:(_width>1), - ndelta_y = delta_y?delta_y:(_height>1), - ndelta_z = delta_z?delta_z:(_depth>1); - x0-=ndelta_x; y0-=ndelta_y; z0-=ndelta_z; - x1+=ndelta_x; y1+=ndelta_y; z1+=ndelta_z; - if (x0<0) { x1-=x0; x0 = 0; if (x1>=width()) x1 = width() - 1; } - if (y0<0) { y1-=y0; y0 = 0; if (y1>=height()) y1 = height() - 1; } - if (z0<0) { z1-=z0; z0 = 0; if (z1>=depth()) z1 = depth() - 1; } - if (x1>=width()) { x0-=(x1 - width() + 1); x1 = width() - 1; if (x0<0) x0 = 0; } - if (y1>=height()) { y0-=(y1 - height() + 1); y1 = height() - 1; if (y0<0) y0 = 0; } - if (z1>=depth()) { z0-=(z1 - depth() + 1); z1 = depth() - 1; if (z0<0) z0 = 0; } - const float - ratio = (float)(x1-x0)/(y1-y0), - ratiow = (float)disp._width/disp._height, - sub = cimg::min(cimg::abs(ratio - ratiow),cimg::abs(1/ratio-1/ratiow)); - if (sub>0.01) resize_disp = true; - } - if (go_left) { - const int delta = (x1 - x0)/4, ndelta = delta?delta:(_width>1); - if (x0 - ndelta>=0) { x0-=ndelta; x1-=ndelta; } - else { x1-=x0; x0 = 0; } - } - if (go_right) { - const int delta = (x1 - x0)/4, ndelta = delta?delta:(_width>1); - if (x1+ndelta1); - if (y0 - ndelta>=0) { y0-=ndelta; y1-=ndelta; } - else { y1-=y0; y0 = 0; } - } - if (go_down) { - const int delta = (y1 - y0)/4, ndelta = delta?delta:(_height>1); - if (y1+ndelta1); - if (z0 - ndelta>=0) { z0-=ndelta; z1-=ndelta; } - else { z1-=z0; z0 = 0; } - } - if (go_dec) { - const int delta = (z1 - z0)/4, ndelta = delta?delta:(_depth>1); - if (z1+ndelta - const CImg& display_object3d(CImgDisplay& disp, - const CImg& vertices, - const CImgList& primitives, - const CImgList& colors, - const to& opacities, - const bool centering=true, - const int render_static=4, const int render_motion=1, - const bool is_double_sided=true, const float focale=700, - const float light_x=0, const float light_y=0, const float light_z=-5e8f, - const float specular_lightness=0.2f, const float specular_shininess=0.1f, - const bool display_axes=true, float *const pose_matrix=0, - const bool exit_on_anykey=false) const { - return _display_object3d(disp,0,vertices,primitives,colors,opacities,centering,render_static, - render_motion,is_double_sided,focale, - light_x,light_y,light_z,specular_lightness,specular_shininess, - display_axes,pose_matrix,exit_on_anykey); - } - - //! Display object 3d in an interactive window \simplification. - template - const CImg& display_object3d(const char *const title, - const CImg& vertices, - const CImgList& primitives, - const CImgList& colors, - const to& opacities, - const bool centering=true, - const int render_static=4, const int render_motion=1, - const bool is_double_sided=true, const float focale=700, - const float light_x=0, const float light_y=0, const float light_z=-5e8f, - const float specular_lightness=0.2f, const float specular_shininess=0.1f, - const bool display_axes=true, float *const pose_matrix=0, - const bool exit_on_anykey=false) const { - CImgDisplay disp; - return _display_object3d(disp,title,vertices,primitives,colors,opacities,centering,render_static, - render_motion,is_double_sided,focale, - light_x,light_y,light_z,specular_lightness,specular_shininess, - display_axes,pose_matrix,exit_on_anykey); - } - - //! Display object 3d in an interactive window \simplification. - template - const CImg& display_object3d(CImgDisplay &disp, - const CImg& vertices, - const CImgList& primitives, - const CImgList& colors, - const bool centering=true, - const int render_static=4, const int render_motion=1, - const bool is_double_sided=true, const float focale=700, - const float light_x=0, const float light_y=0, const float light_z=-5e8f, - const float specular_lightness=0.2f, const float specular_shininess=0.1f, - const bool display_axes=true, float *const pose_matrix=0, - const bool exit_on_anykey=false) const { - return display_object3d(disp,vertices,primitives,colors,CImgList(),centering, - render_static,render_motion,is_double_sided,focale, - light_x,light_y,light_z,specular_lightness,specular_shininess, - display_axes,pose_matrix,exit_on_anykey); - } - - //! Display object 3d in an interactive window \simplification. - template - const CImg& display_object3d(const char *const title, - const CImg& vertices, - const CImgList& primitives, - const CImgList& colors, - const bool centering=true, - const int render_static=4, const int render_motion=1, - const bool is_double_sided=true, const float focale=700, - const float light_x=0, const float light_y=0, const float light_z=-5e8f, - const float specular_lightness=0.2f, const float specular_shininess=0.1f, - const bool display_axes=true, float *const pose_matrix=0, - const bool exit_on_anykey=false) const { - return display_object3d(title,vertices,primitives,colors,CImgList(),centering, - render_static,render_motion,is_double_sided,focale, - light_x,light_y,light_z,specular_lightness,specular_shininess, - display_axes,pose_matrix,exit_on_anykey); - } - - //! Display object 3d in an interactive window \simplification. - template - const CImg& display_object3d(CImgDisplay &disp, - const CImg& vertices, - const CImgList& primitives, - const bool centering=true, - const int render_static=4, const int render_motion=1, - const bool is_double_sided=true, const float focale=700, - const float light_x=0, const float light_y=0, const float light_z=-5e8f, - const float specular_lightness=0.2f, const float specular_shininess=0.1f, - const bool display_axes=true, float *const pose_matrix=0, - const bool exit_on_anykey=false) const { - return display_object3d(disp,vertices,primitives,CImgList(),centering, - render_static,render_motion,is_double_sided,focale, - light_x,light_y,light_z,specular_lightness,specular_shininess, - display_axes,pose_matrix,exit_on_anykey); - } - - - //! Display object 3d in an interactive window \simplification. - template - const CImg& display_object3d(const char *const title, - const CImg& vertices, - const CImgList& primitives, - const bool centering=true, - const int render_static=4, const int render_motion=1, - const bool is_double_sided=true, const float focale=700, - const float light_x=0, const float light_y=0, const float light_z=-5e8f, - const float specular_lightness=0.2f, const float specular_shininess=0.1f, - const bool display_axes=true, float *const pose_matrix=0, - const bool exit_on_anykey=false) const { - return display_object3d(title,vertices,primitives,CImgList(),centering, - render_static,render_motion,is_double_sided,focale, - light_x,light_y,light_z,specular_lightness,specular_shininess, - display_axes,pose_matrix,exit_on_anykey); - } - - //! Display object 3d in an interactive window \simplification. - template - const CImg& display_object3d(CImgDisplay &disp, - const CImg& vertices, - const bool centering=true, - const int render_static=4, const int render_motion=1, - const bool is_double_sided=true, const float focale=700, - const float light_x=0, const float light_y=0, const float light_z=-5e8f, - const float specular_lightness=0.2f, const float specular_shininess=0.1f, - const bool display_axes=true, float *const pose_matrix=0, - const bool exit_on_anykey=false) const { - return display_object3d(disp,vertices,CImgList(),centering, - render_static,render_motion,is_double_sided,focale, - light_x,light_y,light_z,specular_lightness,specular_shininess, - display_axes,pose_matrix,exit_on_anykey); - } - - //! Display object 3d in an interactive window \simplification. - template - const CImg& display_object3d(const char *const title, - const CImg& vertices, - const bool centering=true, - const int render_static=4, const int render_motion=1, - const bool is_double_sided=true, const float focale=700, - const float light_x=0, const float light_y=0, const float light_z=-5e8f, - const float specular_lightness=0.2f, const float specular_shininess=0.1f, - const bool display_axes=true, float *const pose_matrix=0, - const bool exit_on_anykey=false) const { - return display_object3d(title,vertices,CImgList(),centering, - render_static,render_motion,is_double_sided,focale, - light_x,light_y,light_z,specular_lightness,specular_shininess, - display_axes,pose_matrix,exit_on_anykey); - } - - template - const CImg& _display_object3d(CImgDisplay& disp, const char *const title, - const CImg& vertices, - const CImgList& primitives, - const CImgList& colors, - const to& opacities, - const bool centering, - const int render_static, const int render_motion, - const bool is_double_sided, const float focale, - const float light_x, const float light_y, const float light_z, - const float specular_lightness, const float specular_shininess, - const bool display_axes, float *const pose_matrix, - const bool exit_on_anykey) const { - typedef typename cimg::superset::type tpfloat; - - // Check input arguments - if (is_empty()) { - if (disp) return CImg(disp.width(),disp.height(),1,(colors && colors[0].size()==1)?1:3,0). - _display_object3d(disp,title,vertices,primitives,colors,opacities,centering, - render_static,render_motion,is_double_sided,focale, - light_x,light_y,light_z,specular_lightness,specular_shininess, - display_axes,pose_matrix,exit_on_anykey); - else return CImg(1,2,1,1,64,128).resize(cimg_fitscreen(CImgDisplay::screen_width()/2, - CImgDisplay::screen_height()/2,1), - 1,(colors && colors[0].size()==1)?1:3,3). - _display_object3d(disp,title,vertices,primitives,colors,opacities,centering, - render_static,render_motion,is_double_sided,focale, - light_x,light_y,light_z,specular_lightness,specular_shininess, - display_axes,pose_matrix,exit_on_anykey); - } else { if (disp) disp.resize(*this,false); } - CImg error_message(1024); - if (!vertices.is_object3d(primitives,colors,opacities,true,error_message)) - throw CImgArgumentException(_cimg_instance - "display_object3d(): Invalid specified 3d object (%u,%u) (%s).", - cimg_instance,vertices._width,primitives._width,error_message.data()); - if (vertices._width && !primitives) { - CImgList nprimitives(vertices._width,1,1,1,1); - cimglist_for(nprimitives,l) nprimitives(l,0) = (tf)l; - return _display_object3d(disp,title,vertices,nprimitives,colors,opacities,centering, - render_static,render_motion,is_double_sided,focale, - light_x,light_y,light_z,specular_lightness,specular_shininess, - display_axes,pose_matrix,exit_on_anykey); - } - if (!disp) { - disp.assign(cimg_fitscreen(_width,_height,_depth),title?title:0,3); - if (!title) disp.set_title("CImg<%s> (%u vertices, %u primitives)", - pixel_type(),vertices._width,primitives._width); - } else if (title) disp.set_title("%s",title); - - // Init 3d objects and compute object statistics - CImg - pose, - rotated_vertices(vertices._width,3), - bbox_vertices, rotated_bbox_vertices, - axes_vertices, rotated_axes_vertices, - bbox_opacities, axes_opacities; - CImgList bbox_primitives, axes_primitives; - CImgList reverse_primitives; - CImgList bbox_colors, bbox_colors2, axes_colors; - unsigned int ns_width = 0, ns_height = 0; - int _is_double_sided = (int)is_double_sided; - bool ndisplay_axes = display_axes; - const CImg - background_color(1,1,1,_spectrum,0), - foreground_color(1,1,1,_spectrum,255); - float - Xoff = 0, Yoff = 0, Zoff = 0, sprite_scale = 1, - xm = 0, xM = vertices?vertices.get_shared_row(0).max_min(xm):0, - ym = 0, yM = vertices?vertices.get_shared_row(1).max_min(ym):0, - zm = 0, zM = vertices?vertices.get_shared_row(2).max_min(zm):0; - const float delta = cimg::max(xM - xm,yM - ym,zM - zm); - - rotated_bbox_vertices = bbox_vertices.assign(8,3,1,1, - xm,xM,xM,xm,xm,xM,xM,xm, - ym,ym,yM,yM,ym,ym,yM,yM, - zm,zm,zm,zm,zM,zM,zM,zM); - bbox_primitives.assign(6,1,4,1,1, 0,3,2,1, 4,5,6,7, 1,2,6,5, 0,4,7,3, 0,1,5,4, 2,3,7,6); - bbox_colors.assign(6,_spectrum,1,1,1,background_color[0]); - bbox_colors2.assign(6,_spectrum,1,1,1,foreground_color[0]); - bbox_opacities.assign(bbox_colors._width,1,1,1,0.3f); - - rotated_axes_vertices = axes_vertices.assign(7,3,1,1, - 0,20,0,0,22,-6,-6, - 0,0,20,0,-6,22,-6, - 0,0,0,20,0,0,22); - axes_opacities.assign(3,1,1,1,1); - axes_colors.assign(3,_spectrum,1,1,1,foreground_color[0]); - axes_primitives.assign(3,1,2,1,1, 0,1, 0,2, 0,3); - - // Begin user interaction loop - CImg visu0(*this), visu; - CImg zbuffer(visu0.width(),visu0.height(),1,1,0); - bool init_pose = true, clicked = false, redraw = true; - unsigned int key = 0; - int - x0 = 0, y0 = 0, x1 = 0, y1 = 0, - nrender_static = render_static, - nrender_motion = render_motion; - disp.show().flush(); - - while (!disp.is_closed() && !key) { - - // Init object pose - if (init_pose) { - const float - ratio = delta>0?(2.0f*cimg::min(disp.width(),disp.height())/(3.0f*delta)):1, - dx = (xM + xm)/2, dy = (yM + ym)/2, dz = (zM + zm)/2; - if (centering) - CImg(4,3,1,1, ratio,0.,0.,-ratio*dx, 0.,ratio,0.,-ratio*dy, 0.,0.,ratio,-ratio*dz).move_to(pose); - else CImg(4,3,1,1, 1,0,0,0, 0,1,0,0, 0,0,1,0).move_to(pose); - if (pose_matrix) { - CImg pose0(pose_matrix,4,3,1,1,false); - pose0.resize(4,4,1,1,0); pose.resize(4,4,1,1,0); - pose0(3,3) = pose(3,3) = 1; - (pose0*pose).get_crop(0,0,3,2).move_to(pose); - Xoff = pose_matrix[12]; Yoff = pose_matrix[13]; Zoff = pose_matrix[14]; sprite_scale = pose_matrix[15]; - } else { Xoff = Yoff = Zoff = 0; sprite_scale = 1; } - init_pose = false; - redraw = true; - } - - // Rotate and draw 3d object - if (redraw) { - const float - r00 = pose(0,0), r10 = pose(1,0), r20 = pose(2,0), r30 = pose(3,0), - r01 = pose(0,1), r11 = pose(1,1), r21 = pose(2,1), r31 = pose(3,1), - r02 = pose(0,2), r12 = pose(1,2), r22 = pose(2,2), r32 = pose(3,2); - if ((clicked && nrender_motion>=0) || (!clicked && nrender_static>=0)) - cimg_forX(vertices,l) { - const float x = (float)vertices(l,0), y = (float)vertices(l,1), z = (float)vertices(l,2); - rotated_vertices(l,0) = r00*x + r10*y + r20*z + r30; - rotated_vertices(l,1) = r01*x + r11*y + r21*z + r31; - rotated_vertices(l,2) = r02*x + r12*y + r22*z + r32; - } - else cimg_forX(bbox_vertices,l) { - const float x = bbox_vertices(l,0), y = bbox_vertices(l,1), z = bbox_vertices(l,2); - rotated_bbox_vertices(l,0) = r00*x + r10*y + r20*z + r30; - rotated_bbox_vertices(l,1) = r01*x + r11*y + r21*z + r31; - rotated_bbox_vertices(l,2) = r02*x + r12*y + r22*z + r32; - } - - // Draw objects - const bool render_with_zbuffer = !clicked && nrender_static>0; - visu = visu0; - if ((clicked && nrender_motion<0) || (!clicked && nrender_static<0)) - visu.draw_object3d(Xoff + visu._width/2.0f,Yoff + visu._height/2.0f,Zoff, - rotated_bbox_vertices,bbox_primitives,bbox_colors,bbox_opacities,2,false,focale). - draw_object3d(Xoff + visu._width/2.0f,Yoff + visu._height/2.0f,Zoff, - rotated_bbox_vertices,bbox_primitives,bbox_colors2,1,false,focale); - else visu._draw_object3d((void*)0,render_with_zbuffer?zbuffer.fill(0):CImg::empty(), - Xoff + visu._width/2.0f,Yoff + visu._height/2.0f,Zoff, - rotated_vertices,reverse_primitives?reverse_primitives:primitives, - colors,opacities,clicked?nrender_motion:nrender_static,_is_double_sided==1,focale, - width()/2.0f + light_x,height()/2.0f + light_y,light_z + Zoff, - specular_lightness,specular_shininess,sprite_scale); - // Draw axes - if (ndisplay_axes) { - const float - n = (float)std::sqrt(1e-8 + r00*r00 + r01*r01 + r02*r02), - _r00 = r00/n, _r10 = r10/n, _r20 = r20/n, - _r01 = r01/n, _r11 = r11/n, _r21 = r21/n, - _r02 = r01/n, _r12 = r12/n, _r22 = r22/n, - Xaxes = 25, Yaxes = visu._height - 38.0f; - cimg_forX(axes_vertices,l) { - const float - x = axes_vertices(l,0), - y = axes_vertices(l,1), - z = axes_vertices(l,2); - rotated_axes_vertices(l,0) = _r00*x + _r10*y + _r20*z; - rotated_axes_vertices(l,1) = _r01*x + _r11*y + _r21*z; - rotated_axes_vertices(l,2) = _r02*x + _r12*y + _r22*z; - } - axes_opacities(0,0) = (rotated_axes_vertices(1,2)>0)?0.5f:1.0f; - axes_opacities(1,0) = (rotated_axes_vertices(2,2)>0)?0.5f:1.0f; - axes_opacities(2,0) = (rotated_axes_vertices(3,2)>0)?0.5f:1.0f; - visu.draw_object3d(Xaxes,Yaxes,0,rotated_axes_vertices,axes_primitives, - axes_colors,axes_opacities,1,false,focale). - draw_text((int)(Xaxes + rotated_axes_vertices(4,0)), - (int)(Yaxes + rotated_axes_vertices(4,1)), - "X",axes_colors[0]._data,0,axes_opacities(0,0),13). - draw_text((int)(Xaxes + rotated_axes_vertices(5,0)), - (int)(Yaxes + rotated_axes_vertices(5,1)), - "Y",axes_colors[1]._data,0,axes_opacities(1,0),13). - draw_text((int)(Xaxes + rotated_axes_vertices(6,0)), - (int)(Yaxes + rotated_axes_vertices(6,1)), - "Z",axes_colors[2]._data,0,axes_opacities(2,0),13); - } - visu.display(disp); - if (!clicked || nrender_motion==nrender_static) redraw = false; - } - - // Handle user interaction - disp.wait(); - if ((disp.button() || disp.wheel()) && disp.mouse_x()>=0 && disp.mouse_y()>=0) { - redraw = true; - if (!clicked) { x0 = x1 = disp.mouse_x(); y0 = y1 = disp.mouse_y(); if (!disp.wheel()) clicked = true; } - else { x1 = disp.mouse_x(); y1 = disp.mouse_y(); } - if (disp.button()&1) { - const float - R = 0.45f*cimg::min(disp.width(),disp.height()), - R2 = R*R, - u0 = (float)(x0 - disp.width()/2), - v0 = (float)(y0 - disp.height()/2), - u1 = (float)(x1 - disp.width()/2), - v1 = (float)(y1 - disp.height()/2), - n0 = (float)std::sqrt(u0*u0 + v0*v0), - n1 = (float)std::sqrt(u1*u1 + v1*v1), - nu0 = n0>R?(u0*R/n0):u0, - nv0 = n0>R?(v0*R/n0):v0, - nw0 = (float)std::sqrt(cimg::max(0,R2 - nu0*nu0 - nv0*nv0)), - nu1 = n1>R?(u1*R/n1):u1, - nv1 = n1>R?(v1*R/n1):v1, - nw1 = (float)std::sqrt(cimg::max(0,R2 - nu1*nu1 - nv1*nv1)), - u = nv0*nw1 - nw0*nv1, - v = nw0*nu1 - nu0*nw1, - w = nv0*nu1 - nu0*nv1, - n = (float)std::sqrt(u*u + v*v + w*w), - alpha = (float)std::asin(n/R2); - (CImg::rotation_matrix(u,v,w,alpha)*pose).move_to(pose); - x0 = x1; y0 = y1; - } - if (disp.button()&2) { - if (focale>0) Zoff-=(y0 - y1)*focale/400; - else { const float s = std::exp((y0 - y1)/400.0f); pose*=s; sprite_scale*=s; } - x0 = x1; y0 = y1; - } - if (disp.wheel()) { - if (focale>0) Zoff-=disp.wheel()*focale/20; - else { const float s = std::exp(disp.wheel()/20.0f); pose*=s; sprite_scale*=s; } - disp.set_wheel(); - } - if (disp.button()&4) { Xoff+=(x1 - x0); Yoff+=(y1 - y0); x0 = x1; y0 = y1; } - if ((disp.button()&1) && (disp.button()&2)) { - init_pose = true; disp.set_button(); x0 = x1; y0 = y1; - pose = CImg(4,3,1,1, 1,0,0,0, 0,1,0,0, 0,0,1,0); - } - } else if (clicked) { x0 = x1; y0 = y1; clicked = false; redraw = true; } - - CImg filename(32); - switch (key = disp.key()) { -#if cimg_OS!=2 - case cimg::keyCTRLRIGHT : -#endif - case 0 : case cimg::keyCTRLLEFT : key = 0; break; - case cimg::keyD: if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - disp.set_fullscreen(false). - resize(CImgDisplay::_fitscreen(3*disp.width()/2,3*disp.height()/2,1,128,-100,false), - CImgDisplay::_fitscreen(3*disp.width()/2,3*disp.height()/2,1,128,-100,true),false). - _is_resized = true; - disp.set_key(key,false); key = 0; - } break; - case cimg::keyC : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - disp.set_fullscreen(false). - resize(cimg_fitscreen(2*disp.width()/3,2*disp.height()/3,1),false)._is_resized = true; - disp.set_key(key,false); key = 0; - } break; - case cimg::keyR : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - disp.set_fullscreen(false).resize(cimg_fitscreen(_width,_height,_depth),false)._is_resized = true; - disp.set_key(key,false); key = 0; - } break; - case cimg::keyF : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - if (!ns_width || !ns_height || - ns_width>(unsigned int)disp.screen_width() || ns_height>(unsigned int)disp.screen_height()) { - ns_width = disp.screen_width()*3U/4; - ns_height = disp.screen_height()*3U/4; - } - if (disp.is_fullscreen()) disp.resize(ns_width,ns_height,false); - else { - ns_width = disp._width; ns_height = disp._height; - disp.resize(disp.screen_width(),disp.screen_height(),false); - } - disp.toggle_fullscreen()._is_resized = true; - disp.set_key(key,false); key = 0; - } break; - case cimg::keyT : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - // Switch single/double-sided primitives. - if (--_is_double_sided==-2) _is_double_sided = 1; - if (_is_double_sided>=0) reverse_primitives.assign(); - else primitives.get_reverse_object3d().move_to(reverse_primitives); - disp.set_key(key,false); key = 0; redraw = true; - } break; - case cimg::keyZ : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { // Enable/disable Z-buffer - if (zbuffer) zbuffer.assign(); - else zbuffer.assign(visu0.width(),visu0.height(),1,1,0); - disp.set_key(key,false); key = 0; redraw = true; - } break; - case cimg::keyA : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { // Show/hide 3d axes. - ndisplay_axes = !ndisplay_axes; - disp.set_key(key,false); key = 0; redraw = true; - } break; - case cimg::keyF1 : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { // Set rendering mode to points. - nrender_motion = (nrender_static==0 && nrender_motion!=0)?0:-1; nrender_static = 0; - disp.set_key(key,false); key = 0; redraw = true; - } break; - case cimg::keyF2 : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { // Set rendering mode to lines. - nrender_motion = (nrender_static==1 && nrender_motion!=1)?1:-1; nrender_static = 1; - disp.set_key(key,false); key = 0; redraw = true; - } break; - case cimg::keyF3 : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { // Set rendering mode to flat. - nrender_motion = (nrender_static==2 && nrender_motion!=2)?2:-1; nrender_static = 2; - disp.set_key(key,false); key = 0; redraw = true; - } break; - case cimg::keyF4 : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { // Set rendering mode to flat-shaded. - nrender_motion = (nrender_static==3 && nrender_motion!=3)?3:-1; nrender_static = 3; - disp.set_key(key,false); key = 0; redraw = true; - } break; - case cimg::keyF5 : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - // Set rendering mode to gouraud-shaded. - nrender_motion = (nrender_static==4 && nrender_motion!=4)?4:-1; nrender_static = 4; - disp.set_key(key,false); key = 0; redraw = true; - } break; - case cimg::keyF6 : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { // Set rendering mode to phong-shaded. - nrender_motion = (nrender_static==5 && nrender_motion!=5)?5:-1; nrender_static = 5; - disp.set_key(key,false); key = 0; redraw = true; - } break; - case cimg::keyS : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { // Save snapshot - static unsigned int snap_number = 0; - std::FILE *file; - do { - cimg_snprintf(filename,filename._width,cimg_appname "_%.4u.bmp",snap_number++); - if ((file=std_fopen(filename,"r"))!=0) cimg::fclose(file); - } while (file); - (+visu).draw_text(0,0," Saving snapshot... ", - foreground_color._data,background_color._data,0.7f,13).display(disp); - visu.save(filename); - (+visu).draw_text(0,0," Snapshot '%s' saved. ", - foreground_color._data,background_color._data,0.7f,13,filename._data).display(disp); - disp.set_key(key,false); key = 0; - } break; - case cimg::keyG : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { // Save object as a .off file - static unsigned int snap_number = 0; - std::FILE *file; - do { - cimg_snprintf(filename,filename._width,cimg_appname "_%.4u.off",snap_number++); - if ((file=std_fopen(filename,"r"))!=0) cimg::fclose(file); - } while (file); - (+visu).draw_text(0,0," Saving object... ", - foreground_color._data,background_color._data,0.7f,13).display(disp); - vertices.save_off(reverse_primitives?reverse_primitives:primitives,colors,filename); - (+visu).draw_text(0,0," Object '%s' saved. ", - foreground_color._data,background_color._data,0.7f,13,filename._data).display(disp); - disp.set_key(key,false); key = 0; - } break; - case cimg::keyO : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { // Save object as a .cimg file - static unsigned int snap_number = 0; - std::FILE *file; - do { -#ifdef cimg_use_zlib - cimg_snprintf(filename,filename._width,cimg_appname "_%.4u.cimgz",snap_number++); -#else - cimg_snprintf(filename,filename._width,cimg_appname "_%.4u.cimg",snap_number++); -#endif - if ((file=std_fopen(filename,"r"))!=0) cimg::fclose(file); - } while (file); - (+visu).draw_text(0,0," Saving object... ", - foreground_color._data,background_color._data,0.7f,13).display(disp); - vertices.get_object3dtoCImg3d(reverse_primitives?reverse_primitives:primitives,colors,opacities). - save(filename); - (+visu).draw_text(0,0," Object '%s' saved. ", - foreground_color._data,background_color._data,0.7f,13,filename._data).display(disp); - disp.set_key(key,false); key = 0; - } break; -#ifdef cimg_use_board - case cimg::keyP : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { // Save object as a .EPS file - static unsigned int snap_number = 0; - std::FILE *file; - do { - cimg_snprintf(filename,filename._width,cimg_appname "_%.4u.eps",snap_number++); - if ((file=std_fopen(filename,"r"))!=0) cimg::fclose(file); - } while (file); - (+visu).draw_text(0,0," Saving EPS snapshot... ", - foreground_color._data,background_color._data,0.7f,13).display(disp); - LibBoard::Board board; - (+visu)._draw_object3d(&board,zbuffer.fill(0), - Xoff + visu._width/2.0f,Yoff + visu._height/2.0f,Zoff, - rotated_vertices,reverse_primitives?reverse_primitives:primitives, - colors,opacities,clicked?nrender_motion:nrender_static, - _is_double_sided==1,focale, - visu.width()/2.0f + light_x,visu.height()/2.0f + light_y,light_z + Zoff, - specular_lightness,specular_shininess, - sprite_scale); - board.saveEPS(filename); - (+visu).draw_text(0,0," Object '%s' saved. ", - foreground_color._data,background_color._data,0.7f,13,filename._data).display(disp); - disp.set_key(key,false); key = 0; - } break; - case cimg::keyV : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { // Save object as a .SVG file - static unsigned int snap_number = 0; - std::FILE *file; - do { - cimg_snprintf(filename,filename._width,cimg_appname "_%.4u.svg",snap_number++); - if ((file=std_fopen(filename,"r"))!=0) cimg::fclose(file); - } while (file); - (+visu).draw_text(0,0," Saving SVG snapshot... ", - foreground_color._data,background_color._data,0.7f,13).display(disp); - LibBoard::Board board; - (+visu)._draw_object3d(&board,zbuffer.fill(0), - Xoff + visu._width/2.0f,Yoff + visu._height/2.0f,Zoff, - rotated_vertices,reverse_primitives?reverse_primitives:primitives, - colors,opacities,clicked?nrender_motion:nrender_static, - _is_double_sided==1,focale, - visu.width()/2.0f + light_x,visu.height()/2.0f + light_y,light_z + Zoff, - specular_lightness,specular_shininess, - sprite_scale); - board.saveSVG(filename); - (+visu).draw_text(0,0," Object '%s' saved. ", - foreground_color._data,background_color._data,0.7f,13,filename._data).display(disp); - disp.set_key(key,false); key = 0; - } break; -#endif - } - if (disp.is_resized()) { - disp.resize(false); visu0 = get_resize(disp,1); - if (zbuffer) zbuffer.assign(disp.width(),disp.height()); - redraw = true; - } - if (!exit_on_anykey && key && key!=cimg::keyESC && - (key!=cimg::keyW || (!disp.is_keyCTRLLEFT() && !disp.is_keyCTRLRIGHT()))) { - key = 0; - } - } - if (pose_matrix) { - std::memcpy(pose_matrix,pose._data,12*sizeof(float)); - pose_matrix[12] = Xoff; pose_matrix[13] = Yoff; pose_matrix[14] = Zoff; pose_matrix[15] = sprite_scale; - } - disp.set_button().set_key(key); - return *this; - } - - //! Display 1d graph in an interactive window. - /** - \param disp Display window. - \param plot_type Plot type. Can be { 0=points | 1=segments | 2=splines | 3=bars }. - \param vertex_type Vertex type. - \param labelx Title for the horizontal axis, as a C-string. - \param xmin Minimum value along the X-axis. - \param xmax Maximum value along the X-axis. - \param labely Title for the vertical axis, as a C-string. - \param ymin Minimum value along the X-axis. - \param ymax Maximum value along the X-axis. - **/ - const CImg& display_graph(CImgDisplay &disp, - const unsigned int plot_type=1, const unsigned int vertex_type=1, - const char *const labelx=0, const double xmin=0, const double xmax=0, - const char *const labely=0, const double ymin=0, const double ymax=0, - const bool exit_on_anykey=false) const { - return _display_graph(disp,0,plot_type,vertex_type,labelx,xmin,xmax,labely,ymin,ymax,exit_on_anykey); - } - - //! Display 1d graph in an interactive window \overloading. - const CImg& display_graph(const char *const title=0, - const unsigned int plot_type=1, const unsigned int vertex_type=1, - const char *const labelx=0, const double xmin=0, const double xmax=0, - const char *const labely=0, const double ymin=0, const double ymax=0, - const bool exit_on_anykey=false) const { - CImgDisplay disp; - return _display_graph(disp,title,plot_type,vertex_type,labelx,xmin,xmax,labely,ymin,ymax,exit_on_anykey); - } - - const CImg& _display_graph(CImgDisplay &disp, const char *const title=0, - const unsigned int plot_type=1, const unsigned int vertex_type=1, - const char *const labelx=0, const double xmin=0, const double xmax=0, - const char *const labely=0, const double ymin=0, const double ymax=0, - const bool exit_on_anykey=false) const { - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "display_graph(): Empty instance.", - cimg_instance); - if (!disp) disp.assign(cimg_fitscreen(CImgDisplay::screen_width()/2,CImgDisplay::screen_height()/2,1),0,0). - set_title(title?"%s":"CImg<%s>",title?title:pixel_type()); - const ulongT siz = (ulongT)_width*_height*_depth, siz1 = cimg::max(1U,siz - 1); - const unsigned int old_normalization = disp.normalization(); - disp.show().flush()._normalization = 0; - - double y0 = ymin, y1 = ymax, nxmin = xmin, nxmax = xmax; - if (nxmin==nxmax) { nxmin = 0; nxmax = siz1; } - int x0 = 0, x1 = width()*height()*depth() - 1, key = 0; - - for (bool reset_view = true; !key && !disp.is_closed(); ) { - if (reset_view) { x0 = 0; x1 = width()*height()*depth() - 1; y0 = ymin; y1 = ymax; reset_view = false; } - CImg zoom(x1 - x0 + 1,1,1,spectrum()); - cimg_forC(*this,c) zoom.get_shared_channel(c) = CImg(data(x0,0,0,c),x1 - x0 + 1,1,1,1,true); - if (y0==y1) { y0 = zoom.min_max(y1); const double dy = y1 - y0; y0-=dy/20; y1+=dy/20; } - if (y0==y1) { --y0; ++y1; } - - const CImg selection = zoom.get_select_graph(disp,plot_type,vertex_type, - labelx, - nxmin + x0*(nxmax - nxmin)/siz1, - nxmin + x1*(nxmax - nxmin)/siz1, - labely,y0,y1,true); - const int mouse_x = disp.mouse_x(), mouse_y = disp.mouse_y(); - if (selection[0]>=0) { - if (selection[2]<0) reset_view = true; - else { - x1 = x0 + selection[2]; x0+=selection[0]; - if (selection[1]>=0 && selection[3]>=0) { - y0 = y1 - selection[3]*(y1 - y0)/(disp.height() - 32); - y1-=selection[1]*(y1 - y0)/(disp.height() - 32); - } - } - } else { - bool go_in = false, go_out = false, go_left = false, go_right = false, go_up = false, go_down = false; - switch (key = (int)disp.key()) { - case cimg::keyHOME : reset_view = true; key = 0; disp.set_key(); break; - case cimg::keyPADADD : go_in = true; go_out = false; key = 0; disp.set_key(); break; - case cimg::keyPADSUB : go_out = true; go_in = false; key = 0; disp.set_key(); break; - case cimg::keyARROWLEFT : case cimg::keyPAD4 : go_left = true; go_right = false; key = 0; disp.set_key(); - break; - case cimg::keyARROWRIGHT : case cimg::keyPAD6 : go_right = true; go_left = false; key = 0; disp.set_key(); - break; - case cimg::keyARROWUP : case cimg::keyPAD8 : go_up = true; go_down = false; key = 0; disp.set_key(); break; - case cimg::keyARROWDOWN : case cimg::keyPAD2 : go_down = true; go_up = false; key = 0; disp.set_key(); break; - case cimg::keyPAD7 : go_left = true; go_up = true; key = 0; disp.set_key(); break; - case cimg::keyPAD9 : go_right = true; go_up = true; key = 0; disp.set_key(); break; - case cimg::keyPAD1 : go_left = true; go_down = true; key = 0; disp.set_key(); break; - case cimg::keyPAD3 : go_right = true; go_down = true; key = 0; disp.set_key(); break; - } - if (disp.wheel()) { - if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) go_up = !(go_down = disp.wheel()<0); - else if (disp.is_keySHIFTLEFT() || disp.is_keySHIFTRIGHT()) go_left = !(go_right = disp.wheel()>0); - else go_out = !(go_in = disp.wheel()>0); - key = 0; - } - - if (go_in) { - const int - xsiz = x1 - x0, - mx = (mouse_x - 16)*xsiz/(disp.width() - 32), - cx = x0 + (mx<0?0:(mx>=xsiz?xsiz:mx)); - if (x1 - x0>4) { - x0 = cx - 7*(cx - x0)/8; x1 = cx + 7*(x1 - cx)/8; - if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - const double - ysiz = y1 - y0, - my = (mouse_y - 16)*ysiz/(disp.height() - 32), - cy = y1 - (my<0?0:(my>=ysiz?ysiz:my)); - y0 = cy - 7*(cy - y0)/8; y1 = cy + 7*(y1 - cy)/8; - } else y0 = y1 = 0; - } - } - if (go_out) { - if (x0>0 || x1<(int)siz1) { - const int delta_x = (x1 - x0)/8, ndelta_x = delta_x?delta_x:(siz>1); - const double ndelta_y = (y1 - y0)/8; - x0-=ndelta_x; x1+=ndelta_x; - y0-=ndelta_y; y1+=ndelta_y; - if (x0<0) { x1-=x0; x0 = 0; if (x1>=(int)siz) x1 = (int)siz1; } - if (x1>=(int)siz) { x0-=(x1 - siz1); x1 = (int)siz1; if (x0<0) x0 = 0; } - } - } - if (go_left) { - const int delta = (x1 - x0)/5, ndelta = delta?delta:1; - if (x0 - ndelta>=0) { x0-=ndelta; x1-=ndelta; } - else { x1-=x0; x0 = 0; } - go_left = false; - } - if (go_right) { - const int delta = (x1 - x0)/5, ndelta = delta?delta:1; - if (x1 + ndelta<(int)siz) { x0+=ndelta; x1+=ndelta; } - else { x0+=(siz1 - x1); x1 = (int)siz1; } - go_right = false; - } - if (go_up) { - const double delta = (y1 - y0)/10, ndelta = delta?delta:1; - y0+=ndelta; y1+=ndelta; - go_up = false; - } - if (go_down) { - const double delta = (y1 - y0)/10, ndelta = delta?delta:1; - y0-=ndelta; y1-=ndelta; - go_down = false; - } - } - if (!exit_on_anykey && key && key!=(int)cimg::keyESC && - (key!=(int)cimg::keyW || (!disp.is_keyCTRLLEFT() && !disp.is_keyCTRLRIGHT()))) { - disp.set_key(key,false); - key = 0; - } - } - disp._normalization = old_normalization; - return *this; - } - - //! Save image as a file. - /** - \param filename Filename, as a C-string. - \param number When positive, represents an index added to the filename. Otherwise, no number is added. - \param digits Number of digits used for adding the number to the filename. - \note - - The used file format is defined by the file extension in the filename \p filename. - - Parameter \p number can be used to add a 6-digit number to the filename before saving. - - **/ - const CImg& save(const char *const filename, const int number=-1, const unsigned int digits=6) const { - if (!filename) - throw CImgArgumentException(_cimg_instance - "save(): Specified filename is (null).", - cimg_instance); - // Do not test for empty instances, since .cimg format is able to manage empty instances. - const bool is_stdout = *filename=='-' && (!filename[1] || filename[1]=='.'); - const char *const ext = cimg::split_filename(filename); - CImg nfilename(1024); - const char *const fn = is_stdout?filename:(number>=0)?cimg::number_filename(filename,number,digits,nfilename): - filename; - -#ifdef cimg_save_plugin - cimg_save_plugin(fn); -#endif -#ifdef cimg_save_plugin1 - cimg_save_plugin1(fn); -#endif -#ifdef cimg_save_plugin2 - cimg_save_plugin2(fn); -#endif -#ifdef cimg_save_plugin3 - cimg_save_plugin3(fn); -#endif -#ifdef cimg_save_plugin4 - cimg_save_plugin4(fn); -#endif -#ifdef cimg_save_plugin5 - cimg_save_plugin5(fn); -#endif -#ifdef cimg_save_plugin6 - cimg_save_plugin6(fn); -#endif -#ifdef cimg_save_plugin7 - cimg_save_plugin7(fn); -#endif -#ifdef cimg_save_plugin8 - cimg_save_plugin8(fn); -#endif - // Ascii formats - if (!cimg::strcasecmp(ext,"asc")) return save_ascii(fn); - else if (!cimg::strcasecmp(ext,"dlm") || - !cimg::strcasecmp(ext,"txt")) return save_dlm(fn); - else if (!cimg::strcasecmp(ext,"cpp") || - !cimg::strcasecmp(ext,"hpp") || - !cimg::strcasecmp(ext,"h") || - !cimg::strcasecmp(ext,"c")) return save_cpp(fn); - - // 2d binary formats - else if (!cimg::strcasecmp(ext,"bmp")) return save_bmp(fn); - else if (!cimg::strcasecmp(ext,"jpg") || - !cimg::strcasecmp(ext,"jpeg") || - !cimg::strcasecmp(ext,"jpe") || - !cimg::strcasecmp(ext,"jfif") || - !cimg::strcasecmp(ext,"jif")) return save_jpeg(fn); - else if (!cimg::strcasecmp(ext,"rgb")) return save_rgb(fn); - else if (!cimg::strcasecmp(ext,"rgba")) return save_rgba(fn); - else if (!cimg::strcasecmp(ext,"png")) return save_png(fn); - else if (!cimg::strcasecmp(ext,"pgm") || - !cimg::strcasecmp(ext,"ppm") || - !cimg::strcasecmp(ext,"pnm")) return save_pnm(fn); - else if (!cimg::strcasecmp(ext,"pnk")) return save_pnk(fn); - else if (!cimg::strcasecmp(ext,"pfm")) return save_pfm(fn); - else if (!cimg::strcasecmp(ext,"exr")) return save_exr(fn); - else if (!cimg::strcasecmp(ext,"tif") || - !cimg::strcasecmp(ext,"tiff")) return save_tiff(fn); - - // 3d binary formats - else if (!cimg::strcasecmp(ext,"cimgz")) return save_cimg(fn,true); - else if (!cimg::strcasecmp(ext,"cimg") || !*ext) return save_cimg(fn,false); - else if (!cimg::strcasecmp(ext,"dcm")) return save_medcon_external(fn); - else if (!cimg::strcasecmp(ext,"hdr") || - !cimg::strcasecmp(ext,"nii")) return save_analyze(fn); - else if (!cimg::strcasecmp(ext,"inr")) return save_inr(fn); - else if (!cimg::strcasecmp(ext,"mnc")) return save_minc2(fn); - else if (!cimg::strcasecmp(ext,"pan")) return save_pandore(fn); - else if (!cimg::strcasecmp(ext,"raw")) return save_raw(fn); - - // Archive files - else if (!cimg::strcasecmp(ext,"gz")) return save_gzip_external(fn); - - // Image sequences - else if (!cimg::strcasecmp(ext,"yuv")) return save_yuv(fn,true); - else if (!cimg::strcasecmp(ext,"avi") || - !cimg::strcasecmp(ext,"mov") || - !cimg::strcasecmp(ext,"asf") || - !cimg::strcasecmp(ext,"divx") || - !cimg::strcasecmp(ext,"flv") || - !cimg::strcasecmp(ext,"mpg") || - !cimg::strcasecmp(ext,"m1v") || - !cimg::strcasecmp(ext,"m2v") || - !cimg::strcasecmp(ext,"m4v") || - !cimg::strcasecmp(ext,"mjp") || - !cimg::strcasecmp(ext,"mp4") || - !cimg::strcasecmp(ext,"mkv") || - !cimg::strcasecmp(ext,"mpe") || - !cimg::strcasecmp(ext,"movie") || - !cimg::strcasecmp(ext,"ogm") || - !cimg::strcasecmp(ext,"ogg") || - !cimg::strcasecmp(ext,"ogv") || - !cimg::strcasecmp(ext,"qt") || - !cimg::strcasecmp(ext,"rm") || - !cimg::strcasecmp(ext,"vob") || - !cimg::strcasecmp(ext,"wmv") || - !cimg::strcasecmp(ext,"xvid") || - !cimg::strcasecmp(ext,"mpeg")) return save_video(fn); - return save_other(fn); - } - - //! Save image as an ascii file. - /** - \param filename Filename, as a C-string. - **/ - const CImg& save_ascii(const char *const filename) const { - return _save_ascii(0,filename); - } - - //! Save image as an ascii file \overloading. - const CImg& save_ascii(std::FILE *const file) const { - return _save_ascii(file,0); - } - - const CImg& _save_ascii(std::FILE *const file, const char *const filename) const { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "save_ascii(): Specified filename is (null).", - cimg_instance); - std::FILE *const nfile = file?file:cimg::fopen(filename,"w"); - std::fprintf(nfile,"%u %u %u %u\n",_width,_height,_depth,_spectrum); - const T* ptrs = _data; - cimg_forYZC(*this,y,z,c) { - cimg_forX(*this,x) std::fprintf(nfile,"%.16g ",(double)*(ptrs++)); - std::fputc('\n',nfile); - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Save image as a .cpp source file. - /** - \param filename Filename, as a C-string. - **/ - const CImg& save_cpp(const char *const filename) const { - return _save_cpp(0,filename); - } - - //! Save image as a .cpp source file \overloading. - const CImg& save_cpp(std::FILE *const file) const { - return _save_cpp(file,0); - } - - const CImg& _save_cpp(std::FILE *const file, const char *const filename) const { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "save_cpp(): Specified filename is (null).", - cimg_instance); - std::FILE *const nfile = file?file:cimg::fopen(filename,"w"); - CImg varname(1024); *varname = 0; - if (filename) cimg_sscanf(cimg::basename(filename),"%1023[a-zA-Z0-9_]",varname._data); - if (!*varname) cimg_snprintf(varname,varname._width,"unnamed"); - std::fprintf(nfile, - "/* Define image '%s' of size %ux%ux%ux%u and type '%s' */\n" - "%s data_%s[] = { %s\n ", - varname._data,_width,_height,_depth,_spectrum,pixel_type(),pixel_type(),varname._data, - is_empty()?"};":""); - if (!is_empty()) for (ulongT off = 0, siz = size() - 1; off<=siz; ++off) { - std::fprintf(nfile,cimg::type::format(),cimg::type::format((*this)[off])); - if (off==siz) std::fprintf(nfile," };\n"); - else if (!((off + 1)%16)) std::fprintf(nfile,",\n "); - else std::fprintf(nfile,", "); - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Save image as a DLM file. - /** - \param filename Filename, as a C-string. - **/ - const CImg& save_dlm(const char *const filename) const { - return _save_dlm(0,filename); - } - - //! Save image as a DLM file \overloading. - const CImg& save_dlm(std::FILE *const file) const { - return _save_dlm(file,0); - } - - const CImg& _save_dlm(std::FILE *const file, const char *const filename) const { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "save_dlm(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(file,filename); return *this; } - if (_depth>1) - cimg::warn(_cimg_instance - "save_dlm(): Instance is volumetric, values along Z will be unrolled in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - if (_spectrum>1) - cimg::warn(_cimg_instance - "save_dlm(): Instance is multispectral, values along C will be unrolled in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - - std::FILE *const nfile = file?file:cimg::fopen(filename,"w"); - const T* ptrs = _data; - cimg_forYZC(*this,y,z,c) { - cimg_forX(*this,x) std::fprintf(nfile,"%.16g%s",(double)*(ptrs++),(x==width() - 1)?"":","); - std::fputc('\n',nfile); - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Save image as a BMP file. - /** - \param filename Filename, as a C-string. - **/ - const CImg& save_bmp(const char *const filename) const { - return _save_bmp(0,filename); - } - - //! Save image as a BMP file \overloading. - const CImg& save_bmp(std::FILE *const file) const { - return _save_bmp(file,0); - } - - const CImg& _save_bmp(std::FILE *const file, const char *const filename) const { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "save_bmp(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(file,filename); return *this; } - if (_depth>1) - cimg::warn(_cimg_instance - "save_bmp(): Instance is volumetric, only the first slice will be saved in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - if (_spectrum>3) - cimg::warn(_cimg_instance - "save_bmp(): Instance is multispectral, only the three first channels will be saved in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - - std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); - CImg header(54,1,1,1,0); - unsigned char align_buf[4] = { 0 }; - const unsigned int - align = (4 - (3*_width)%4)%4, - buf_size = (3*_width + align)*height(), - file_size = 54 + buf_size; - header[0] = 'B'; header[1] = 'M'; - header[0x02] = file_size&0xFF; - header[0x03] = (file_size>>8)&0xFF; - header[0x04] = (file_size>>16)&0xFF; - header[0x05] = (file_size>>24)&0xFF; - header[0x0A] = 0x36; - header[0x0E] = 0x28; - header[0x12] = _width&0xFF; - header[0x13] = (_width>>8)&0xFF; - header[0x14] = (_width>>16)&0xFF; - header[0x15] = (_width>>24)&0xFF; - header[0x16] = _height&0xFF; - header[0x17] = (_height>>8)&0xFF; - header[0x18] = (_height>>16)&0xFF; - header[0x19] = (_height>>24)&0xFF; - header[0x1A] = 1; - header[0x1B] = 0; - header[0x1C] = 24; - header[0x1D] = 0; - header[0x22] = buf_size&0xFF; - header[0x23] = (buf_size>>8)&0xFF; - header[0x24] = (buf_size>>16)&0xFF; - header[0x25] = (buf_size>>24)&0xFF; - header[0x27] = 0x1; - header[0x2B] = 0x1; - cimg::fwrite(header._data,54,nfile); - - const T - *ptr_r = data(0,_height - 1,0,0), - *ptr_g = (_spectrum>=2)?data(0,_height - 1,0,1):0, - *ptr_b = (_spectrum>=3)?data(0,_height - 1,0,2):0; - - switch (_spectrum) { - case 1 : { - cimg_forY(*this,y) { - cimg_forX(*this,x) { - const unsigned char val = (unsigned char)*(ptr_r++); - std::fputc(val,nfile); std::fputc(val,nfile); std::fputc(val,nfile); - } - cimg::fwrite(align_buf,align,nfile); - ptr_r-=2*_width; - } - } break; - case 2 : { - cimg_forY(*this,y) { - cimg_forX(*this,x) { - std::fputc(0,nfile); - std::fputc((unsigned char)(*(ptr_g++)),nfile); - std::fputc((unsigned char)(*(ptr_r++)),nfile); - } - cimg::fwrite(align_buf,align,nfile); - ptr_r-=2*_width; ptr_g-=2*_width; - } - } break; - default : { - cimg_forY(*this,y) { - cimg_forX(*this,x) { - std::fputc((unsigned char)(*(ptr_b++)),nfile); - std::fputc((unsigned char)(*(ptr_g++)),nfile); - std::fputc((unsigned char)(*(ptr_r++)),nfile); - } - cimg::fwrite(align_buf,align,nfile); - ptr_r-=2*_width; ptr_g-=2*_width; ptr_b-=2*_width; - } - } - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Save image as a JPEG file. - /** - \param filename Filename, as a C-string. - \param quality Image quality (in %) - **/ - const CImg& save_jpeg(const char *const filename, const unsigned int quality=100) const { - return _save_jpeg(0,filename,quality); - } - - //! Save image as a JPEG file \overloading. - const CImg& save_jpeg(std::FILE *const file, const unsigned int quality=100) const { - return _save_jpeg(file,0,quality); - } - - const CImg& _save_jpeg(std::FILE *const file, const char *const filename, const unsigned int quality) const { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "save_jpeg(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(file,filename); return *this; } - if (_depth>1) - cimg::warn(_cimg_instance - "save_jpeg(): Instance is volumetric, only the first slice will be saved in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - -#ifndef cimg_use_jpeg - if (!file) return save_other(filename,quality); - else throw CImgIOException(_cimg_instance - "save_jpeg(): Unable to save data in '(*FILE)' unless libjpeg is enabled.", - cimg_instance); -#else - unsigned int dimbuf = 0; - J_COLOR_SPACE colortype = JCS_RGB; - - switch (_spectrum) { - case 1 : dimbuf = 1; colortype = JCS_GRAYSCALE; break; - case 2 : dimbuf = 3; colortype = JCS_RGB; break; - case 3 : dimbuf = 3; colortype = JCS_RGB; break; - default : dimbuf = 4; colortype = JCS_CMYK; break; - } - - // Call libjpeg functions - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_compress(&cinfo); - std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); - jpeg_stdio_dest(&cinfo,nfile); - cinfo.image_width = _width; - cinfo.image_height = _height; - cinfo.input_components = dimbuf; - cinfo.in_color_space = colortype; - jpeg_set_defaults(&cinfo); - jpeg_set_quality(&cinfo,quality<100?quality:100,TRUE); - jpeg_start_compress(&cinfo,TRUE); - - JSAMPROW row_pointer[1]; - CImg buffer(_width*dimbuf); - - while (cinfo.next_scanline& save_magick(const char *const filename, const unsigned int bytes_per_pixel=0) const { - if (!filename) - throw CImgArgumentException(_cimg_instance - "save_magick(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(0,filename); return *this; } - -#ifdef cimg_use_magick - double stmin, stmax = (double)max_min(stmin); - if (_depth>1) - cimg::warn(_cimg_instance - "save_magick(): Instance is volumetric, only the first slice will be saved in file '%s'.", - cimg_instance, - filename); - - if (_spectrum>3) - cimg::warn(_cimg_instance - "save_magick(): Instance is multispectral, only the three first channels will be " - "saved in file '%s'.", - cimg_instance, - filename); - - if (stmin<0 || (bytes_per_pixel==1 && stmax>=256) || stmax>=65536) - cimg::warn(_cimg_instance - "save_magick(): Instance has pixel values in [%g,%g], probable type overflow in file '%s'.", - cimg_instance, - filename,stmin,stmax); - - Magick::Image image(Magick::Geometry(_width,_height),"black"); - image.type(Magick::TrueColorType); - image.depth(bytes_per_pixel?(8*bytes_per_pixel):(stmax>=256?16:8)); - const T - *ptr_r = data(0,0,0,0), - *ptr_g = _spectrum>1?data(0,0,0,1):0, - *ptr_b = _spectrum>2?data(0,0,0,2):0; - Magick::PixelPacket *pixels = image.getPixels(0,0,_width,_height); - switch (_spectrum) { - case 1 : // Scalar images - for (ulongT off = (ulongT)_width*_height; off; --off) { - pixels->red = pixels->green = pixels->blue = (Magick::Quantum)*(ptr_r++); - ++pixels; - } - break; - case 2 : // RG images - for (ulongT off = (ulongT)_width*_height; off; --off) { - pixels->red = (Magick::Quantum)*(ptr_r++); - pixels->green = (Magick::Quantum)*(ptr_g++); - pixels->blue = 0; ++pixels; - } - break; - default : // RGB images - for (ulongT off = (ulongT)_width*_height; off; --off) { - pixels->red = (Magick::Quantum)*(ptr_r++); - pixels->green = (Magick::Quantum)*(ptr_g++); - pixels->blue = (Magick::Quantum)*(ptr_b++); - ++pixels; - } - } - image.syncPixels(); - image.write(filename); - return *this; -#else - cimg::unused(bytes_per_pixel); - throw CImgIOException(_cimg_instance - "save_magick(): Unable to save file '%s' unless libMagick++ is enabled.", - cimg_instance, - filename); -#endif - } - - //! Save image as a PNG file. - /** - \param filename Filename, as a C-string. - \param bytes_per_pixel Force the number of bytes per pixels for the saving, when possible. - **/ - const CImg& save_png(const char *const filename, const unsigned int bytes_per_pixel=0) const { - return _save_png(0,filename,bytes_per_pixel); - } - - //! Save image as a PNG file \overloading. - const CImg& save_png(std::FILE *const file, const unsigned int bytes_per_pixel=0) const { - return _save_png(file,0,bytes_per_pixel); - } - - const CImg& _save_png(std::FILE *const file, const char *const filename, - const unsigned int bytes_per_pixel=0) const { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "save_png(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(file,filename); return *this; } - -#ifndef cimg_use_png - cimg::unused(bytes_per_pixel); - if (!file) return save_other(filename); - else throw CImgIOException(_cimg_instance - "save_png(): Unable to save data in '(*FILE)' unless libpng is enabled.", - cimg_instance); -#else - const char *volatile nfilename = filename; // two 'volatile' here to remove a g++ warning due to 'setjmp'. - std::FILE *volatile nfile = file?file:cimg::fopen(nfilename,"wb"); - volatile double stmin, stmax = (double)max_min(stmin); - - if (_depth>1) - cimg::warn(_cimg_instance - "save_png(): Instance is volumetric, only the first slice will be saved in file '%s'.", - cimg_instance, - filename); - - if (_spectrum>4) - cimg::warn(_cimg_instance - "save_png(): Instance is multispectral, only the three first channels will be saved in file '%s'.", - cimg_instance, - filename); - - if (stmin<0 || (bytes_per_pixel==1 && stmax>=256) || stmax>=65536) - cimg::warn(_cimg_instance - "save_png(): Instance has pixel values in [%g,%g], probable type overflow in file '%s'.", - cimg_instance, - filename,stmin,stmax); - - // Setup PNG structures for write - png_voidp user_error_ptr = 0; - png_error_ptr user_error_fn = 0, user_warning_fn = 0; - png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,user_error_ptr, user_error_fn, - user_warning_fn); - if(!png_ptr){ - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "save_png(): Failed to initialize 'png_ptr' structure when saving file '%s'.", - cimg_instance, - nfilename?nfilename:"(FILE*)"); - } - png_infop info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_write_struct(&png_ptr,(png_infopp)0); - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "save_png(): Failed to initialize 'info_ptr' structure when saving file '%s'.", - cimg_instance, - nfilename?nfilename:"(FILE*)"); - } - if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_write_struct(&png_ptr, &info_ptr); - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "save_png(): Encountered unknown fatal error in libpng when saving file '%s'.", - cimg_instance, - nfilename?nfilename:"(FILE*)"); - } - png_init_io(png_ptr, nfile); - - const int bit_depth = bytes_per_pixel?(bytes_per_pixel*8):(stmax>=256?16:8); - - int color_type; - switch (spectrum()) { - case 1 : color_type = PNG_COLOR_TYPE_GRAY; break; - case 2 : color_type = PNG_COLOR_TYPE_GRAY_ALPHA; break; - case 3 : color_type = PNG_COLOR_TYPE_RGB; break; - default : color_type = PNG_COLOR_TYPE_RGB_ALPHA; - } - const int interlace_type = PNG_INTERLACE_NONE; - const int compression_type = PNG_COMPRESSION_TYPE_DEFAULT; - const int filter_method = PNG_FILTER_TYPE_DEFAULT; - png_set_IHDR(png_ptr,info_ptr,_width,_height,bit_depth,color_type,interlace_type,compression_type,filter_method); - png_write_info(png_ptr,info_ptr); - const int byte_depth = bit_depth>>3; - const int numChan = spectrum()>4?4:spectrum(); - const int pixel_bit_depth_flag = numChan * (bit_depth - 1); - - // Allocate Memory for Image Save and Fill pixel data - png_bytep *const imgData = new png_byte*[_height]; - for (unsigned int row = 0; row<_height; ++row) imgData[row] = new png_byte[byte_depth*numChan*_width]; - const T *pC0 = data(0,0,0,0); - switch (pixel_bit_depth_flag) { - case 7 : { // Gray 8-bit - cimg_forY(*this,y) { - unsigned char *ptrd = imgData[y]; - cimg_forX(*this,x) *(ptrd++) = (unsigned char)*(pC0++); - } - } break; - case 14 : { // Gray w/ Alpha 8-bit - const T *pC1 = data(0,0,0,1); - cimg_forY(*this,y) { - unsigned char *ptrd = imgData[y]; - cimg_forX(*this,x) { - *(ptrd++) = (unsigned char)*(pC0++); - *(ptrd++) = (unsigned char)*(pC1++); - } - } - } break; - case 21 : { // RGB 8-bit - const T *pC1 = data(0,0,0,1), *pC2 = data(0,0,0,2); - cimg_forY(*this,y) { - unsigned char *ptrd = imgData[y]; - cimg_forX(*this,x) { - *(ptrd++) = (unsigned char)*(pC0++); - *(ptrd++) = (unsigned char)*(pC1++); - *(ptrd++) = (unsigned char)*(pC2++); - } - } - } break; - case 28 : { // RGB x/ Alpha 8-bit - const T *pC1 = data(0,0,0,1), *pC2 = data(0,0,0,2), *pC3 = data(0,0,0,3); - cimg_forY(*this,y){ - unsigned char *ptrd = imgData[y]; - cimg_forX(*this,x){ - *(ptrd++) = (unsigned char)*(pC0++); - *(ptrd++) = (unsigned char)*(pC1++); - *(ptrd++) = (unsigned char)*(pC2++); - *(ptrd++) = (unsigned char)*(pC3++); - } - } - } break; - case 15 : { // Gray 16-bit - cimg_forY(*this,y){ - unsigned short *ptrd = (unsigned short*)(imgData[y]); - cimg_forX(*this,x) *(ptrd++) = (unsigned short)*(pC0++); - if (!cimg::endianness()) cimg::invert_endianness((unsigned short*)imgData[y],_width); - } - } break; - case 30 : { // Gray w/ Alpha 16-bit - const T *pC1 = data(0,0,0,1); - cimg_forY(*this,y){ - unsigned short *ptrd = (unsigned short*)(imgData[y]); - cimg_forX(*this,x) { - *(ptrd++) = (unsigned short)*(pC0++); - *(ptrd++) = (unsigned short)*(pC1++); - } - if (!cimg::endianness()) cimg::invert_endianness((unsigned short*)imgData[y],2*_width); - } - } break; - case 45 : { // RGB 16-bit - const T *pC1 = data(0,0,0,1), *pC2 = data(0,0,0,2); - cimg_forY(*this,y) { - unsigned short *ptrd = (unsigned short*)(imgData[y]); - cimg_forX(*this,x) { - *(ptrd++) = (unsigned short)*(pC0++); - *(ptrd++) = (unsigned short)*(pC1++); - *(ptrd++) = (unsigned short)*(pC2++); - } - if (!cimg::endianness()) cimg::invert_endianness((unsigned short*)imgData[y],3*_width); - } - } break; - case 60 : { // RGB w/ Alpha 16-bit - const T *pC1 = data(0,0,0,1), *pC2 = data(0,0,0,2), *pC3 = data(0,0,0,3); - cimg_forY(*this,y) { - unsigned short *ptrd = (unsigned short*)(imgData[y]); - cimg_forX(*this,x) { - *(ptrd++) = (unsigned short)*(pC0++); - *(ptrd++) = (unsigned short)*(pC1++); - *(ptrd++) = (unsigned short)*(pC2++); - *(ptrd++) = (unsigned short)*(pC3++); - } - if (!cimg::endianness()) cimg::invert_endianness((unsigned short*)imgData[y],4*_width); - } - } break; - default : - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimg_instance - "save_png(): Encountered unknown fatal error in libpng when saving file '%s'.", - cimg_instance, - nfilename?nfilename:"(FILE*)"); - } - png_write_image(png_ptr,imgData); - png_write_end(png_ptr,info_ptr); - png_destroy_write_struct(&png_ptr, &info_ptr); - - // Deallocate Image Write Memory - cimg_forY(*this,n) delete[] imgData[n]; - delete[] imgData; - - if (!file) cimg::fclose(nfile); - return *this; -#endif - } - - //! Save image as a PNM file. - /** - \param filename Filename, as a C-string. - \param bytes_per_pixel Force the number of bytes per pixels for the saving. - **/ - const CImg& save_pnm(const char *const filename, const unsigned int bytes_per_pixel=0) const { - return _save_pnm(0,filename,bytes_per_pixel); - } - - //! Save image as a PNM file \overloading. - const CImg& save_pnm(std::FILE *const file, const unsigned int bytes_per_pixel=0) const { - return _save_pnm(file,0,bytes_per_pixel); - } - - const CImg& _save_pnm(std::FILE *const file, const char *const filename, - const unsigned int bytes_per_pixel=0) const { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "save_pnm(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(file,filename); return *this; } - - double stmin, stmax = (double)max_min(stmin); - if (_depth>1) - cimg::warn(_cimg_instance - "save_pnm(): Instance is volumetric, only the first slice will be saved in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - if (_spectrum>3) - cimg::warn(_cimg_instance - "save_pnm(): Instance is multispectral, only the three first channels will be saved in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - if (stmin<0 || (bytes_per_pixel==1 && stmax>=256) || stmax>=65536) - cimg::warn(_cimg_instance - "save_pnm(): Instance has pixel values in [%g,%g], probable type overflow in file '%s'.", - cimg_instance, - stmin,stmax,filename?filename:"(FILE*)"); - - std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); - const T - *ptr_r = data(0,0,0,0), - *ptr_g = (_spectrum>=2)?data(0,0,0,1):0, - *ptr_b = (_spectrum>=3)?data(0,0,0,2):0; - const ulongT buf_size = cimg::min((ulongT)1024*1024,(ulongT)_width*_height*(_spectrum==1?1UL:3UL)); - - std::fprintf(nfile,"P%c\n%u %u\n%u\n", - (_spectrum==1?'5':'6'),_width,_height,stmax<256?255:(stmax<4096?4095:65535)); - - switch (_spectrum) { - case 1 : { // Scalar image - if (bytes_per_pixel==1 || (!bytes_per_pixel && stmax<256)) { // Binary PGM 8 bits - CImg buf((unsigned int)buf_size); - for (longT to_write = (longT)width()*height(); to_write>0; ) { - const ulongT N = cimg::min((ulongT)to_write,buf_size); - unsigned char *ptrd = buf._data; - for (ulongT i = N; i>0; --i) *(ptrd++) = (unsigned char)*(ptr_r++); - cimg::fwrite(buf._data,N,nfile); - to_write-=N; - } - } else { // Binary PGM 16 bits - CImg buf((unsigned int)buf_size); - for (longT to_write = (longT)width()*height(); to_write>0; ) { - const ulongT N = cimg::min((ulongT)to_write,buf_size); - unsigned short *ptrd = buf._data; - for (ulongT i = N; i>0; --i) *(ptrd++) = (unsigned short)*(ptr_r++); - if (!cimg::endianness()) cimg::invert_endianness(buf._data,buf_size); - cimg::fwrite(buf._data,N,nfile); - to_write-=N; - } - } - } break; - case 2 : { // RG image - if (bytes_per_pixel==1 || (!bytes_per_pixel && stmax<256)) { // Binary PPM 8 bits - CImg buf((unsigned int)buf_size); - for (longT to_write = (longT)width()*height(); to_write>0; ) { - const ulongT N = cimg::min((ulongT)to_write,buf_size/3); - unsigned char *ptrd = buf._data; - for (ulongT i = N; i>0; --i) { - *(ptrd++) = (unsigned char)*(ptr_r++); - *(ptrd++) = (unsigned char)*(ptr_g++); - *(ptrd++) = 0; - } - cimg::fwrite(buf._data,3*N,nfile); - to_write-=N; - } - } else { // Binary PPM 16 bits - CImg buf((unsigned int)buf_size); - for (longT to_write = (longT)width()*height(); to_write>0; ) { - const ulongT N = cimg::min((ulongT)to_write,buf_size/3); - unsigned short *ptrd = buf._data; - for (ulongT i = N; i>0; --i) { - *(ptrd++) = (unsigned short)*(ptr_r++); - *(ptrd++) = (unsigned short)*(ptr_g++); - *(ptrd++) = 0; - } - if (!cimg::endianness()) cimg::invert_endianness(buf._data,buf_size); - cimg::fwrite(buf._data,3*N,nfile); - to_write-=N; - } - } - } break; - default : { // RGB image - if (bytes_per_pixel==1 || (!bytes_per_pixel && stmax<256)) { // Binary PPM 8 bits - CImg buf((unsigned int)buf_size); - for (longT to_write = (longT)width()*height(); to_write>0; ) { - const ulongT N = cimg::min((ulongT)to_write,buf_size/3); - unsigned char *ptrd = buf._data; - for (ulongT i = N; i>0; --i) { - *(ptrd++) = (unsigned char)*(ptr_r++); - *(ptrd++) = (unsigned char)*(ptr_g++); - *(ptrd++) = (unsigned char)*(ptr_b++); - } - cimg::fwrite(buf._data,3*N,nfile); - to_write-=N; - } - } else { // Binary PPM 16 bits - CImg buf((unsigned int)buf_size); - for (longT to_write = (longT)width()*height(); to_write>0; ) { - const ulongT N = cimg::min((ulongT)to_write,buf_size/3); - unsigned short *ptrd = buf._data; - for (ulongT i = N; i>0; --i) { - *(ptrd++) = (unsigned short)*(ptr_r++); - *(ptrd++) = (unsigned short)*(ptr_g++); - *(ptrd++) = (unsigned short)*(ptr_b++); - } - if (!cimg::endianness()) cimg::invert_endianness(buf._data,buf_size); - cimg::fwrite(buf._data,3*N,nfile); - to_write-=N; - } - } - } - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Save image as a PNK file. - /** - \param filename Filename, as a C-string. - **/ - const CImg& save_pnk(const char *const filename) const { - return _save_pnk(0,filename); - } - - //! Save image as a PNK file \overloading. - const CImg& save_pnk(std::FILE *const file) const { - return _save_pnk(file,0); - } - - const CImg& _save_pnk(std::FILE *const file, const char *const filename) const { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "save_pnk(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(file,filename); return *this; } - if (_spectrum>1) - cimg::warn(_cimg_instance - "save_pnk(): Instance is multispectral, only the first channel will be saved in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - - const ulongT buf_size = cimg::min((ulongT)1024*1024,(ulongT)_width*_height*_depth); - std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); - const T *ptr = data(0,0,0,0); - - if (!cimg::type::is_float() && sizeof(T)==1 && _depth<2) // Can be saved as regular PNM file. - _save_pnm(file,filename,0); - else if (!cimg::type::is_float() && sizeof(T)==1) { // Save as extended P5 file: Binary byte-valued 3d. - std::fprintf(nfile,"P5\n%u %u %u\n255\n",_width,_height,_depth); - CImg buf((unsigned int)buf_size); - for (longT to_write = (longT)width()*height()*depth(); to_write>0; ) { - const ulongT N = cimg::min((ulongT)to_write,buf_size); - unsigned char *ptrd = buf._data; - for (ulongT i = N; i>0; --i) *(ptrd++) = (unsigned char)*(ptr++); - cimg::fwrite(buf._data,N,nfile); - to_write-=N; - } - } else if (!cimg::type::is_float()) { // Save as P8: Binary int32-valued 3d. - if (_depth>1) std::fprintf(nfile,"P8\n%u %u %u\n%d\n",_width,_height,_depth,(int)max()); - else std::fprintf(nfile,"P8\n%u %u\n%d\n",_width,_height,(int)max()); - CImg buf((unsigned int)buf_size); - for (longT to_write = (longT)width()*height()*depth(); to_write>0; ) { - const ulongT N = cimg::min((ulongT)to_write,buf_size); - int *ptrd = buf._data; - for (ulongT i = N; i>0; --i) *(ptrd++) = (int)*(ptr++); - cimg::fwrite(buf._data,N,nfile); - to_write-=N; - } - } else { // Save as P9: Binary float-valued 3d. - if (_depth>1) std::fprintf(nfile,"P9\n%u %u %u\n%g\n",_width,_height,_depth,(double)max()); - else std::fprintf(nfile,"P9\n%u %u\n%g\n",_width,_height,(double)max()); - CImg buf((unsigned int)buf_size); - for (longT to_write = (longT)width()*height()*depth(); to_write>0; ) { - const ulongT N = cimg::min((ulongT)to_write,buf_size); - float *ptrd = buf._data; - for (ulongT i = N; i>0; --i) *(ptrd++) = (float)*(ptr++); - cimg::fwrite(buf._data,N,nfile); - to_write-=N; - } - } - - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Save image as a PFM file. - /** - \param filename Filename, as a C-string. - **/ - const CImg& save_pfm(const char *const filename) const { - get_mirror('y')._save_pfm(0,filename); - return *this; - } - - //! Save image as a PFM file \overloading. - const CImg& save_pfm(std::FILE *const file) const { - get_mirror('y')._save_pfm(file,0); - return *this; - } - - const CImg& _save_pfm(std::FILE *const file, const char *const filename) const { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "save_pfm(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(file,filename); return *this; } - if (_depth>1) - cimg::warn(_cimg_instance - "save_pfm(): Instance is volumetric, only the first slice will be saved in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - if (_spectrum>3) - cimg::warn(_cimg_instance - "save_pfm(): image instance is multispectral, only the three first channels will be saved " - "in file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - - std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); - const T - *ptr_r = data(0,0,0,0), - *ptr_g = (_spectrum>=2)?data(0,0,0,1):0, - *ptr_b = (_spectrum>=3)?data(0,0,0,2):0; - const unsigned int buf_size = cimg::min(1024*1024U,_width*_height*(_spectrum==1?1:3)); - - std::fprintf(nfile,"P%c\n%u %u\n1.0\n", - (_spectrum==1?'f':'F'),_width,_height); - - switch (_spectrum) { - case 1 : { // Scalar image - CImg buf(buf_size); - for (longT to_write = (longT)width()*height(); to_write>0; ) { - const ulongT N = cimg::min((ulongT)to_write,buf_size); - float *ptrd = buf._data; - for (ulongT i = N; i>0; --i) *(ptrd++) = (float)*(ptr_r++); - if (!cimg::endianness()) cimg::invert_endianness(buf._data,buf_size); - cimg::fwrite(buf._data,N,nfile); - to_write-=N; - } - } break; - case 2 : { // RG image - CImg buf(buf_size); - for (longT to_write = (longT)width()*height(); to_write>0; ) { - const unsigned int N = cimg::min((unsigned int)to_write,buf_size/3); - float *ptrd = buf._data; - for (ulongT i = N; i>0; --i) { - *(ptrd++) = (float)*(ptr_r++); - *(ptrd++) = (float)*(ptr_g++); - *(ptrd++) = 0; - } - if (!cimg::endianness()) cimg::invert_endianness(buf._data,buf_size); - cimg::fwrite(buf._data,3*N,nfile); - to_write-=N; - } - } break; - default : { // RGB image - CImg buf(buf_size); - for (longT to_write = (longT)width()*height(); to_write>0; ) { - const unsigned int N = cimg::min((unsigned int)to_write,buf_size/3); - float *ptrd = buf._data; - for (ulongT i = N; i>0; --i) { - *(ptrd++) = (float)*(ptr_r++); - *(ptrd++) = (float)*(ptr_g++); - *(ptrd++) = (float)*(ptr_b++); - } - if (!cimg::endianness()) cimg::invert_endianness(buf._data,buf_size); - cimg::fwrite(buf._data,3*N,nfile); - to_write-=N; - } - } - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Save image as a RGB file. - /** - \param filename Filename, as a C-string. - **/ - const CImg& save_rgb(const char *const filename) const { - return _save_rgb(0,filename); - } - - //! Save image as a RGB file \overloading. - const CImg& save_rgb(std::FILE *const file) const { - return _save_rgb(file,0); - } - - const CImg& _save_rgb(std::FILE *const file, const char *const filename) const { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "save_rgb(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(file,filename); return *this; } - if (_spectrum!=3) - cimg::warn(_cimg_instance - "save_rgb(): image instance has not exactly 3 channels, for file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - - std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); - const ulongT wh = (ulongT)_width*_height; - unsigned char *const buffer = new unsigned char[3*wh], *nbuffer = buffer; - const T - *ptr1 = data(0,0,0,0), - *ptr2 = _spectrum>1?data(0,0,0,1):0, - *ptr3 = _spectrum>2?data(0,0,0,2):0; - switch (_spectrum) { - case 1 : { // Scalar image - for (ulongT k = 0; k& save_rgba(const char *const filename) const { - return _save_rgba(0,filename); - } - - //! Save image as a RGBA file \overloading. - const CImg& save_rgba(std::FILE *const file) const { - return _save_rgba(file,0); - } - - const CImg& _save_rgba(std::FILE *const file, const char *const filename) const { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "save_rgba(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(file,filename); return *this; } - if (_spectrum!=4) - cimg::warn(_cimg_instance - "save_rgba(): image instance has not exactly 4 channels, for file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - - std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); - const ulongT wh = (ulongT)_width*_height; - unsigned char *const buffer = new unsigned char[4*wh], *nbuffer = buffer; - const T - *ptr1 = data(0,0,0,0), - *ptr2 = _spectrum>1?data(0,0,0,1):0, - *ptr3 = _spectrum>2?data(0,0,0,2):0, - *ptr4 = _spectrum>3?data(0,0,0,3):0; - switch (_spectrum) { - case 1 : { // Scalar images - for (ulongT k = 0; k{ 0=None | 1=LZW | 2=JPEG }. - \note - - libtiff support is enabled by defining the precompilation - directive \c cimg_use_tif. - - When libtiff is enabled, 2D and 3D (multipage) several - channel per pixel are supported for - char,uchar,short,ushort,float and \c double pixel types. - - If \c cimg_use_tif is not defined at compile time the - function uses CImg&save_other(const char*). - **/ - const CImg& save_tiff(const char *const filename, const unsigned int compression_type=0, - const float *const voxel_size=0, const char *const description=0, - const bool use_bigtiff=true) const { - if (!filename) - throw CImgArgumentException(_cimg_instance - "save_tiff(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(0,filename); return *this; } - -#ifdef cimg_use_tiff - const bool - _use_bigtiff = use_bigtiff && sizeof(ulongT)>=8 && size()*sizeof(T)>=1UL<<31; // No bigtiff for small images. - TIFF *tif = TIFFOpen(filename,_use_bigtiff?"w8":"w4"); - if (tif) { - cimg_forZ(*this,z) _save_tiff(tif,z,z,compression_type,voxel_size,description); - TIFFClose(tif); - } else throw CImgIOException(_cimg_instance - "save_tiff(): Failed to open file '%s' for writing.", - cimg_instance, - filename); - return *this; -#else - cimg::unused(compression_type,voxel_size,description,use_bigtiff); - return save_other(filename); -#endif - } - -#ifdef cimg_use_tiff - -#define _cimg_save_tiff(types,typed,compression_type) if (!std::strcmp(types,pixel_type())) { \ - const typed foo = (typed)0; return _save_tiff(tif,directory,z,foo,compression_type,voxel_size,description); } - - // [internal] Save a plane into a tiff file - template - const CImg& _save_tiff(TIFF *tif, const unsigned int directory, const unsigned int z, const t& pixel_t, - const unsigned int compression_type, const float *const voxel_size, - const char *const description) const { - if (is_empty() || !tif || pixel_t) return *this; - const char *const filename = TIFFFileName(tif); - uint32 rowsperstrip = (uint32)-1; - uint16 spp = _spectrum, bpp = sizeof(t)*8, photometric; - if (spp==3 || spp==4) photometric = PHOTOMETRIC_RGB; - else photometric = PHOTOMETRIC_MINISBLACK; - TIFFSetDirectory(tif,directory); - TIFFSetField(tif,TIFFTAG_IMAGEWIDTH,_width); - TIFFSetField(tif,TIFFTAG_IMAGELENGTH,_height); - if (voxel_size) { - const float vx = voxel_size[0], vy = voxel_size[1], vz = voxel_size[2]; - TIFFSetField(tif,TIFFTAG_RESOLUTIONUNIT,RESUNIT_NONE); - TIFFSetField(tif,TIFFTAG_XRESOLUTION,1.0f/vx); - TIFFSetField(tif,TIFFTAG_YRESOLUTION,1.0f/vy); - CImg s_description(256); - cimg_snprintf(s_description,s_description._width,"VX=%g VY=%g VZ=%g spacing=%g",vx,vy,vz,vz); - TIFFSetField(tif,TIFFTAG_IMAGEDESCRIPTION,s_description.data()); - } - if (description) TIFFSetField(tif,TIFFTAG_IMAGEDESCRIPTION,description); - TIFFSetField(tif,TIFFTAG_ORIENTATION,ORIENTATION_TOPLEFT); - TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,spp); - if (cimg::type::is_float()) TIFFSetField(tif,TIFFTAG_SAMPLEFORMAT,3); - else if (cimg::type::min()==0) TIFFSetField(tif,TIFFTAG_SAMPLEFORMAT,1); - else TIFFSetField(tif,TIFFTAG_SAMPLEFORMAT,2); - TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,bpp); - TIFFSetField(tif,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG); - TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,photometric); - TIFFSetField(tif,TIFFTAG_COMPRESSION,compression_type==2?COMPRESSION_JPEG: - compression_type==1?COMPRESSION_LZW:COMPRESSION_NONE); - rowsperstrip = TIFFDefaultStripSize(tif,rowsperstrip); - TIFFSetField(tif,TIFFTAG_ROWSPERSTRIP,rowsperstrip); - TIFFSetField(tif,TIFFTAG_FILLORDER,FILLORDER_MSB2LSB); - TIFFSetField(tif,TIFFTAG_SOFTWARE,"CImg"); - t *const buf = (t*)_TIFFmalloc(TIFFStripSize(tif)); - if (buf) { - for (unsigned int row = 0; row<_height; row+=rowsperstrip) { - uint32 nrow = (row + rowsperstrip>_height?_height - row:rowsperstrip); - tstrip_t strip = TIFFComputeStrip(tif,row,0); - tsize_t i = 0; - for (unsigned int rr = 0; rr& _save_tiff(TIFF *tif, const unsigned int directory, const unsigned int z, - const unsigned int compression_type, const float *const voxel_size, - const char *const description) const { - _cimg_save_tiff("bool",unsigned char,compression_type); - _cimg_save_tiff("unsigned char",unsigned char,compression_type); - _cimg_save_tiff("char",char,compression_type); - _cimg_save_tiff("unsigned short",unsigned short,compression_type); - _cimg_save_tiff("short",short,compression_type); - _cimg_save_tiff("unsigned int",unsigned int,compression_type); - _cimg_save_tiff("int",int,compression_type); - _cimg_save_tiff("unsigned int64",unsigned int,compression_type); - _cimg_save_tiff("int64",int,compression_type); - _cimg_save_tiff("float",float,compression_type); - _cimg_save_tiff("double",float,compression_type); - const char *const filename = TIFFFileName(tif); - throw CImgInstanceException(_cimg_instance - "save_tiff(): Unsupported pixel type '%s' for file '%s'.", - cimg_instance, - pixel_type(),filename?filename:"(FILE*)"); - return *this; - } -#endif - - //! Save image as a MINC2 file. - /** - \param filename Filename, as a C-string. - \param imitate_file If non-zero, reference filename, as a C-string, to borrow header from. - **/ - const CImg& save_minc2(const char *const filename, - const char *const imitate_file=0) const { - if (!filename) - throw CImgArgumentException(_cimg_instance - "save_minc2(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(0,filename); return *this; } - -#ifndef cimg_use_minc2 - cimg::unused(imitate_file); - return save_other(filename); -#else - minc::minc_1_writer wtr; - if (imitate_file) - wtr.open(filename, imitate_file); - else { - minc::minc_info di; - if(width()) di.push_back(minc::dim_info(width(),width()*0.5,-1,minc::dim_info::DIM_X)); - if(height()) di.push_back(minc::dim_info(height(),height()*0.5,-1,minc::dim_info::DIM_Y)); - if(depth()) di.push_back(minc::dim_info(depth(),depth()*0.5,-1,minc::dim_info::DIM_Z)); - if(spectrum()) di.push_back(minc::dim_info(spectrum(),spectrum()*0.5,-1,minc::dim_info::DIM_TIME)); - wtr.open(filename,di,1,NC_FLOAT,0); - } - if(typeid(T)==typeid(unsigned char)) - wtr.setup_write_byte(); - else if(typeid(T)==typeid(int)) - wtr.setup_write_int(); - else if(typeid(T)==typeid(double)) - wtr.setup_write_double(); - else - wtr.setup_write_float(); - minc::save_standard_volume(wtr, this->_data); - return *this; -#endif - } - - //! Save image as an ANALYZE7.5 or NIFTI file. - /** - \param filename Filename, as a C-string. - \param voxel_size Pointer to 3 consecutive values that tell about the voxel sizes along the X,Y and Z dimensions. - **/ - const CImg& save_analyze(const char *const filename, const float *const voxel_size=0) const { - if (!filename) - throw CImgArgumentException(_cimg_instance - "save_analyze(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(0,filename); return *this; } - - std::FILE *file; - CImg hname(1024), iname(1024); - const char *const ext = cimg::split_filename(filename); - short datatype = -1; - if (!*ext) { - cimg_snprintf(hname,hname._width,"%s.hdr",filename); - cimg_snprintf(iname,iname._width,"%s.img",filename); - } - if (!cimg::strncasecmp(ext,"hdr",3)) { - std::strcpy(hname,filename); - std::strncpy(iname,filename,iname._width - 1); - cimg_sprintf(iname._data + std::strlen(iname) - 3,"img"); - } - if (!cimg::strncasecmp(ext,"img",3)) { - std::strcpy(hname,filename); - std::strncpy(iname,filename,iname._width - 1); - cimg_sprintf(hname._data + std::strlen(iname) - 3,"hdr"); - } - if (!cimg::strncasecmp(ext,"nii",3)) { - std::strncpy(hname,filename,hname._width - 1); *iname = 0; - } - - CImg header(*iname?348:352,1,1,1,0); - int *const iheader = (int*)header._data; - *iheader = 348; - std::strcpy(header._data + 4,"CImg"); - std::strcpy(header._data + 14," "); - ((short*)&(header[36]))[0] = 4096; - ((char*)&(header[38]))[0] = 114; - ((short*)&(header[40]))[0] = 4; - ((short*)&(header[40]))[1] = (short)_width; - ((short*)&(header[40]))[2] = (short)_height; - ((short*)&(header[40]))[3] = (short)_depth; - ((short*)&(header[40]))[4] = (short)_spectrum; - if (!cimg::strcasecmp(pixel_type(),"bool")) datatype = 2; - if (!cimg::strcasecmp(pixel_type(),"unsigned char")) datatype = 2; - if (!cimg::strcasecmp(pixel_type(),"char")) datatype = 2; - if (!cimg::strcasecmp(pixel_type(),"unsigned short")) datatype = 4; - if (!cimg::strcasecmp(pixel_type(),"short")) datatype = 4; - if (!cimg::strcasecmp(pixel_type(),"unsigned int")) datatype = 8; - if (!cimg::strcasecmp(pixel_type(),"int")) datatype = 8; - if (!cimg::strcasecmp(pixel_type(),"unsigned int64")) datatype = 8; - if (!cimg::strcasecmp(pixel_type(),"int64")) datatype = 8; - if (!cimg::strcasecmp(pixel_type(),"float")) datatype = 16; - if (!cimg::strcasecmp(pixel_type(),"double")) datatype = 64; - if (datatype<0) - throw CImgIOException(_cimg_instance - "save_analyze(): Unsupported pixel type '%s' for file '%s'.", - cimg_instance, - pixel_type(),filename); - - ((short*)&(header[70]))[0] = datatype; - ((short*)&(header[72]))[0] = sizeof(T); - ((float*)&(header[108]))[0] = (float)(*iname?0:header.width()); - ((float*)&(header[112]))[0] = 1; - ((float*)&(header[76]))[0] = 0; - if (voxel_size) { - ((float*)&(header[76]))[1] = voxel_size[0]; - ((float*)&(header[76]))[2] = voxel_size[1]; - ((float*)&(header[76]))[3] = voxel_size[2]; - } else ((float*)&(header[76]))[1] = ((float*)&(header[76]))[2] = ((float*)&(header[76]))[3] = 1; - file = cimg::fopen(hname,"wb"); - cimg::fwrite(header._data,header.width(),file); - if (*iname) { cimg::fclose(file); file = cimg::fopen(iname,"wb"); } - cimg::fwrite(_data,size(),file); - cimg::fclose(file); - return *this; - } - - //! Save image as a .cimg file. - /** - \param filename Filename, as a C-string. - \param is_compressed Tells if the file contains compressed image data. - **/ - const CImg& save_cimg(const char *const filename, const bool is_compressed=false) const { - CImgList(*this,true).save_cimg(filename,is_compressed); - return *this; - } - - //! Save image as a .cimg file \overloading. - const CImg& save_cimg(std::FILE *const file, const bool is_compressed=false) const { - CImgList(*this,true).save_cimg(file,is_compressed); - return *this; - } - - //! Save image as a sub-image into an existing .cimg file. - /** - \param filename Filename, as a C-string. - \param n0 Index of the image inside the file. - \param x0 X-coordinate of the sub-image location. - \param y0 Y-coordinate of the sub-image location. - \param z0 Z-coordinate of the sub-image location. - \param c0 C-coordinate of the sub-image location. - **/ - const CImg& save_cimg(const char *const filename, - const unsigned int n0, - const unsigned int x0, const unsigned int y0, - const unsigned int z0, const unsigned int c0) const { - CImgList(*this,true).save_cimg(filename,n0,x0,y0,z0,c0); - return *this; - } - - //! Save image as a sub-image into an existing .cimg file \overloading. - const CImg& save_cimg(std::FILE *const file, - const unsigned int n0, - const unsigned int x0, const unsigned int y0, - const unsigned int z0, const unsigned int c0) const { - CImgList(*this,true).save_cimg(file,n0,x0,y0,z0,c0); - return *this; - } - - //! Save blank image as a .cimg file. - /** - \param filename Filename, as a C-string. - \param dx Width of the image. - \param dy Height of the image. - \param dz Depth of the image. - \param dc Number of channels of the image. - \note - - All pixel values of the saved image are set to \c 0. - - Use this method to save large images without having to instanciate and allocate them. - **/ - static void save_empty_cimg(const char *const filename, - const unsigned int dx, const unsigned int dy=1, - const unsigned int dz=1, const unsigned int dc=1) { - return CImgList::save_empty_cimg(filename,1,dx,dy,dz,dc); - } - - //! Save blank image as a .cimg file \overloading. - /** - Same as save_empty_cimg(const char *,unsigned int,unsigned int,unsigned int,unsigned int) - with a file stream argument instead of a filename string. - **/ - static void save_empty_cimg(std::FILE *const file, - const unsigned int dx, const unsigned int dy=1, - const unsigned int dz=1, const unsigned int dc=1) { - return CImgList::save_empty_cimg(file,1,dx,dy,dz,dc); - } - - //! Save image as an INRIMAGE-4 file. - /** - \param filename Filename, as a C-string. - \param voxel_size Pointer to 3 values specifying the voxel sizes along the X,Y and Z dimensions. - **/ - const CImg& save_inr(const char *const filename, const float *const voxel_size=0) const { - return _save_inr(0,filename,voxel_size); - } - - //! Save image as an INRIMAGE-4 file \overloading. - const CImg& save_inr(std::FILE *const file, const float *const voxel_size=0) const { - return _save_inr(file,0,voxel_size); - } - - const CImg& _save_inr(std::FILE *const file, const char *const filename, const float *const voxel_size) const { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "save_inr(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(file,filename); return *this; } - - int inrpixsize = -1; - const char *inrtype = "unsigned fixed\nPIXSIZE=8 bits\nSCALE=2**0"; - if (!cimg::strcasecmp(pixel_type(),"unsigned char")) { - inrtype = "unsigned fixed\nPIXSIZE=8 bits\nSCALE=2**0"; inrpixsize = 1; - } - if (!cimg::strcasecmp(pixel_type(),"char")) { - inrtype = "fixed\nPIXSIZE=8 bits\nSCALE=2**0"; inrpixsize = 1; - } - if (!cimg::strcasecmp(pixel_type(),"unsigned short")) { - inrtype = "unsigned fixed\nPIXSIZE=16 bits\nSCALE=2**0";inrpixsize = 2; - } - if (!cimg::strcasecmp(pixel_type(),"short")) { - inrtype = "fixed\nPIXSIZE=16 bits\nSCALE=2**0"; inrpixsize = 2; - } - if (!cimg::strcasecmp(pixel_type(),"unsigned int")) { - inrtype = "unsigned fixed\nPIXSIZE=32 bits\nSCALE=2**0";inrpixsize = 4; - } - if (!cimg::strcasecmp(pixel_type(),"int")) { - inrtype = "fixed\nPIXSIZE=32 bits\nSCALE=2**0"; inrpixsize = 4; - } - if (!cimg::strcasecmp(pixel_type(),"float")) { - inrtype = "float\nPIXSIZE=32 bits"; inrpixsize = 4; - } - if (!cimg::strcasecmp(pixel_type(),"double")) { - inrtype = "float\nPIXSIZE=64 bits"; inrpixsize = 8; - } - if (inrpixsize<=0) - throw CImgIOException(_cimg_instance - "save_inr(): Unsupported pixel type '%s' for file '%s'", - cimg_instance, - pixel_type(),filename?filename:"(FILE*)"); - - std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); - CImg header(257); - int err = cimg_snprintf(header,header._width,"#INRIMAGE-4#{\nXDIM=%u\nYDIM=%u\nZDIM=%u\nVDIM=%u\n", - _width,_height,_depth,_spectrum); - if (voxel_size) err+=cimg_sprintf(header._data + err,"VX=%g\nVY=%g\nVZ=%g\n", - voxel_size[0],voxel_size[1],voxel_size[2]); - err+=cimg_sprintf(header._data + err,"TYPE=%s\nCPU=%s\n",inrtype,cimg::endianness()?"sun":"decm"); - std::memset(header._data + err,'\n',252 - err); - std::memcpy(header._data + 252,"##}\n",4); - cimg::fwrite(header._data,256,nfile); - cimg_forXYZ(*this,x,y,z) cimg_forC(*this,c) cimg::fwrite(&((*this)(x,y,z,c)),1,nfile); - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Save image as an OpenEXR file. - /** - \param filename Filename, as a C-string. - \note The OpenEXR file format is described here. - **/ - const CImg& save_exr(const char *const filename) const { - if (!filename) - throw CImgArgumentException(_cimg_instance - "save_exr(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(0,filename); return *this; } - if (_depth>1) - cimg::warn(_cimg_instance - "save_exr(): Instance is volumetric, only the first slice will be saved in file '%s'.", - cimg_instance, - filename); - -#ifndef cimg_use_openexr - return save_other(filename); -#else - Imf::Rgba *const ptrd0 = new Imf::Rgba[(size_t)_width*_height], *ptrd = ptrd0, rgba; - switch (_spectrum) { - case 1 : { // Grayscale image. - for (const T *ptr_r = data(), *const ptr_e = ptr_r + (ulongT)_width*_height; ptr_rPandore file specifications - for more information). - **/ - const CImg& save_pandore(const char *const filename, const unsigned int colorspace=0) const { - return _save_pandore(0,filename,colorspace); - } - - //! Save image as a Pandore-5 file \overloading. - /** - Same as save_pandore(const char *,unsigned int) const - with a file stream argument instead of a filename string. - **/ - const CImg& save_pandore(std::FILE *const file, const unsigned int colorspace=0) const { - return _save_pandore(file,0,colorspace); - } - - unsigned int _save_pandore_header_length(unsigned int id, unsigned int *dims, const unsigned int colorspace) const { - unsigned int nbdims = 0; - if (id==2 || id==3 || id==4) { - dims[0] = 1; dims[1] = _width; nbdims = 2; - } - if (id==5 || id==6 || id==7) { - dims[0] = 1; dims[1] = _height; dims[2] = _width; nbdims=3; - } - if (id==8 || id==9 || id==10) { - dims[0] = _spectrum; dims[1] = _depth; dims[2] = _height; dims[3] = _width; nbdims = 4; - } - if (id==16 || id==17 || id==18) { - dims[0] = 3; dims[1] = _height; dims[2] = _width; dims[3] = colorspace; nbdims = 4; - } - if (id==19 || id==20 || id==21) { - dims[0] = 3; dims[1] = _depth; dims[2] = _height; dims[3] = _width; dims[4] = colorspace; nbdims = 5; - } - if (id==22 || id==23 || id==25) { - dims[0] = _spectrum; dims[1] = _width; nbdims = 2; - } - if (id==26 || id==27 || id==29) { - dims[0] = _spectrum; dims[1] = _height; dims[2] = _width; nbdims=3; - } - if (id==30 || id==31 || id==33) { - dims[0] = _spectrum; dims[1] = _depth; dims[2] = _height; dims[3] = _width; nbdims = 4; - } - return nbdims; - } - - const CImg& _save_pandore(std::FILE *const file, const char *const filename, - const unsigned int colorspace) const { - -#define __cimg_save_pandore_case(dtype) \ - dtype *buffer = new dtype[size()]; \ - const T *ptrs = _data; \ - cimg_foroff(*this,off) *(buffer++) = (dtype)(*(ptrs++)); \ - buffer-=size(); \ - cimg::fwrite(buffer,size(),nfile); \ - delete[] buffer - -#define _cimg_save_pandore_case(sy,sz,sv,stype,id) \ - if (!saved && (sy?(sy==_height):true) && (sz?(sz==_depth):true) && \ - (sv?(sv==_spectrum):true) && !std::strcmp(stype,pixel_type())) { \ - unsigned int *iheader = (unsigned int*)(header + 12); \ - nbdims = _save_pandore_header_length((*iheader=id),dims,colorspace); \ - cimg::fwrite(header,36,nfile); \ - if (sizeof(unsigned long)==4) { CImg ndims(5); \ - for (int d = 0; d<5; ++d) ndims[d] = (unsigned long)dims[d]; cimg::fwrite(ndims._data,nbdims,nfile); } \ - else if (sizeof(unsigned int)==4) { CImg ndims(5); \ - for (int d = 0; d<5; ++d) ndims[d] = (unsigned int)dims[d]; cimg::fwrite(ndims._data,nbdims,nfile); } \ - else if (sizeof(unsigned short)==4) { CImg ndims(5); \ - for (int d = 0; d<5; ++d) ndims[d] = (unsigned short)dims[d]; cimg::fwrite(ndims._data,nbdims,nfile); } \ - else throw CImgIOException(_cimg_instance \ - "save_pandore(): Unsupported datatype for file '%s'.",\ - cimg_instance, \ - filename?filename:"(FILE*)"); \ - if (id==2 || id==5 || id==8 || id==16 || id==19 || id==22 || id==26 || id==30) { \ - __cimg_save_pandore_case(unsigned char); \ - } else if (id==3 || id==6 || id==9 || id==17 || id==20 || id==23 || id==27 || id==31) { \ - if (sizeof(unsigned long)==4) { __cimg_save_pandore_case(unsigned long); } \ - else if (sizeof(unsigned int)==4) { __cimg_save_pandore_case(unsigned int); } \ - else if (sizeof(unsigned short)==4) { __cimg_save_pandore_case(unsigned short); } \ - else throw CImgIOException(_cimg_instance \ - "save_pandore(): Unsupported datatype for file '%s'.",\ - cimg_instance, \ - filename?filename:"(FILE*)"); \ - } else if (id==4 || id==7 || id==10 || id==18 || id==21 || id==25 || id==29 || id==33) { \ - if (sizeof(double)==4) { __cimg_save_pandore_case(double); } \ - else if (sizeof(float)==4) { __cimg_save_pandore_case(float); } \ - else throw CImgIOException(_cimg_instance \ - "save_pandore(): Unsupported datatype for file '%s'.",\ - cimg_instance, \ - filename?filename:"(FILE*)"); \ - } \ - saved = true; \ - } - - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "save_pandore(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(file,filename); return *this; } - - std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); - unsigned char header[36] = { 'P','A','N','D','O','R','E','0','4',0,0,0, - 0,0,0,0,'C','I','m','g',0,0,0,0,0, - 'N','o',' ','d','a','t','e',0,0,0,0 }; - unsigned int nbdims, dims[5] = { 0 }; - bool saved = false; - _cimg_save_pandore_case(1,1,1,"unsigned char",2); - _cimg_save_pandore_case(1,1,1,"char",3); - _cimg_save_pandore_case(1,1,1,"unsigned short",3); - _cimg_save_pandore_case(1,1,1,"short",3); - _cimg_save_pandore_case(1,1,1,"unsigned int",3); - _cimg_save_pandore_case(1,1,1,"int",3); - _cimg_save_pandore_case(1,1,1,"unsigned int64",3); - _cimg_save_pandore_case(1,1,1,"int64",3); - _cimg_save_pandore_case(1,1,1,"float",4); - _cimg_save_pandore_case(1,1,1,"double",4); - - _cimg_save_pandore_case(0,1,1,"unsigned char",5); - _cimg_save_pandore_case(0,1,1,"char",6); - _cimg_save_pandore_case(0,1,1,"unsigned short",6); - _cimg_save_pandore_case(0,1,1,"short",6); - _cimg_save_pandore_case(0,1,1,"unsigned int",6); - _cimg_save_pandore_case(0,1,1,"int",6); - _cimg_save_pandore_case(0,1,1,"unsigned int64",6); - _cimg_save_pandore_case(0,1,1,"int64",6); - _cimg_save_pandore_case(0,1,1,"float",7); - _cimg_save_pandore_case(0,1,1,"double",7); - - _cimg_save_pandore_case(0,0,1,"unsigned char",8); - _cimg_save_pandore_case(0,0,1,"char",9); - _cimg_save_pandore_case(0,0,1,"unsigned short",9); - _cimg_save_pandore_case(0,0,1,"short",9); - _cimg_save_pandore_case(0,0,1,"unsigned int",9); - _cimg_save_pandore_case(0,0,1,"int",9); - _cimg_save_pandore_case(0,0,1,"unsigned int64",9); - _cimg_save_pandore_case(0,0,1,"int64",9); - _cimg_save_pandore_case(0,0,1,"float",10); - _cimg_save_pandore_case(0,0,1,"double",10); - - _cimg_save_pandore_case(0,1,3,"unsigned char",16); - _cimg_save_pandore_case(0,1,3,"char",17); - _cimg_save_pandore_case(0,1,3,"unsigned short",17); - _cimg_save_pandore_case(0,1,3,"short",17); - _cimg_save_pandore_case(0,1,3,"unsigned int",17); - _cimg_save_pandore_case(0,1,3,"int",17); - _cimg_save_pandore_case(0,1,3,"unsigned int64",17); - _cimg_save_pandore_case(0,1,3,"int64",17); - _cimg_save_pandore_case(0,1,3,"float",18); - _cimg_save_pandore_case(0,1,3,"double",18); - - _cimg_save_pandore_case(0,0,3,"unsigned char",19); - _cimg_save_pandore_case(0,0,3,"char",20); - _cimg_save_pandore_case(0,0,3,"unsigned short",20); - _cimg_save_pandore_case(0,0,3,"short",20); - _cimg_save_pandore_case(0,0,3,"unsigned int",20); - _cimg_save_pandore_case(0,0,3,"int",20); - _cimg_save_pandore_case(0,0,3,"unsigned int64",20); - _cimg_save_pandore_case(0,0,3,"int64",20); - _cimg_save_pandore_case(0,0,3,"float",21); - _cimg_save_pandore_case(0,0,3,"double",21); - - _cimg_save_pandore_case(1,1,0,"unsigned char",22); - _cimg_save_pandore_case(1,1,0,"char",23); - _cimg_save_pandore_case(1,1,0,"unsigned short",23); - _cimg_save_pandore_case(1,1,0,"short",23); - _cimg_save_pandore_case(1,1,0,"unsigned int",23); - _cimg_save_pandore_case(1,1,0,"int",23); - _cimg_save_pandore_case(1,1,0,"unsigned int64",23); - _cimg_save_pandore_case(1,1,0,"int64",23); - _cimg_save_pandore_case(1,1,0,"float",25); - _cimg_save_pandore_case(1,1,0,"double",25); - - _cimg_save_pandore_case(0,1,0,"unsigned char",26); - _cimg_save_pandore_case(0,1,0,"char",27); - _cimg_save_pandore_case(0,1,0,"unsigned short",27); - _cimg_save_pandore_case(0,1,0,"short",27); - _cimg_save_pandore_case(0,1,0,"unsigned int",27); - _cimg_save_pandore_case(0,1,0,"int",27); - _cimg_save_pandore_case(0,1,0,"unsigned int64",27); - _cimg_save_pandore_case(0,1,0,"int64",27); - _cimg_save_pandore_case(0,1,0,"float",29); - _cimg_save_pandore_case(0,1,0,"double",29); - - _cimg_save_pandore_case(0,0,0,"unsigned char",30); - _cimg_save_pandore_case(0,0,0,"char",31); - _cimg_save_pandore_case(0,0,0,"unsigned short",31); - _cimg_save_pandore_case(0,0,0,"short",31); - _cimg_save_pandore_case(0,0,0,"unsigned int",31); - _cimg_save_pandore_case(0,0,0,"int",31); - _cimg_save_pandore_case(0,0,0,"unsigned int64",31); - _cimg_save_pandore_case(0,0,0,"int64",31); - _cimg_save_pandore_case(0,0,0,"float",33); - _cimg_save_pandore_case(0,0,0,"double",33); - - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Save image as a raw data file. - /** - \param filename Filename, as a C-string. - \param is_multiplexed Tells if the image channels are stored in a multiplexed way (\c true) or not (\c false). - \note The .raw format does not store the image dimensions in the output file, - so you have to keep track of them somewhere to be able to read the file correctly afterwards. - **/ - const CImg& save_raw(const char *const filename, const bool is_multiplexed=false) const { - return _save_raw(0,filename,is_multiplexed); - } - - //! Save image as a raw data file \overloading. - /** - Same as save_raw(const char *,bool) const - with a file stream argument instead of a filename string. - **/ - const CImg& save_raw(std::FILE *const file, const bool is_multiplexed=false) const { - return _save_raw(file,0,is_multiplexed); - } - - const CImg& _save_raw(std::FILE *const file, const char *const filename, const bool is_multiplexed) const { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "save_raw(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(file,filename); return *this; } - - std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); - if (!is_multiplexed) cimg::fwrite(_data,size(),nfile); - else { - CImg buf(_spectrum); - cimg_forXYZ(*this,x,y,z) { - cimg_forC(*this,c) buf[c] = (*this)(x,y,z,c); - cimg::fwrite(buf._data,_spectrum,nfile); - } - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Save image as a .yuv video file. - /** - \param filename Filename, as a C-string. - \param is_rgb Tells if pixel values of the instance image are RGB-coded (\c true) or YUV-coded (\c false). - \note Each slice of the instance image is considered to be a single frame of the output video file. - **/ - const CImg& save_yuv(const char *const filename, const bool is_rgb=true) const { - get_split('z').save_yuv(filename,is_rgb); - return *this; - } - - //! Save image as a .yuv video file \overloading. - /** - Same as save_yuv(const char*,bool) const - with a file stream argument instead of a filename string. - **/ - const CImg& save_yuv(std::FILE *const file, const bool is_rgb=true) const { - get_split('z').save_yuv(file,is_rgb); - return *this; - } - - //! Save 3d object as an Object File Format (.off) file. - /** - \param filename Filename, as a C-string. - \param primitives List of 3d object primitives. - \param colors List of 3d object colors. - \note - - Instance image contains the vertices data of the 3d object. - - Textured, transparent or sphere-shaped primitives cannot be managed by the .off file format. - Such primitives will be lost or simplified during file saving. - - The .off file format is described here. - **/ - template - const CImg& save_off(const CImgList& primitives, const CImgList& colors, - const char *const filename) const { - return _save_off(primitives,colors,0,filename); - } - - //! Save 3d object as an Object File Format (.off) file \overloading. - /** - Same as save_off(const CImgList&,const CImgList&,const char*) const - with a file stream argument instead of a filename string. - **/ - template - const CImg& save_off(const CImgList& primitives, const CImgList& colors, - std::FILE *const file) const { - return _save_off(primitives,colors,file,0); - } - - template - const CImg& _save_off(const CImgList& primitives, const CImgList& colors, - std::FILE *const file, const char *const filename) const { - if (!file && !filename) - throw CImgArgumentException(_cimg_instance - "save_off(): Specified filename is (null).", - cimg_instance); - if (is_empty()) - throw CImgInstanceException(_cimg_instance - "save_off(): Empty instance, for file '%s'.", - cimg_instance, - filename?filename:"(FILE*)"); - - CImgList opacities; - CImg error_message(1024); - if (!is_object3d(primitives,colors,opacities,true,error_message)) - throw CImgInstanceException(_cimg_instance - "save_off(): Invalid specified 3d object, for file '%s' (%s).", - cimg_instance, - filename?filename:"(FILE*)",error_message.data()); - - const CImg default_color(1,3,1,1,200); - std::FILE *const nfile = file?file:cimg::fopen(filename,"w"); - unsigned int supported_primitives = 0; - cimglist_for(primitives,l) if (primitives[l].size()!=5) ++supported_primitives; - std::fprintf(nfile,"OFF\n%u %u %u\n",_width,supported_primitives,3*primitives._width); - cimg_forX(*this,i) std::fprintf(nfile,"%f %f %f\n", - (float)((*this)(i,0)),(float)((*this)(i,1)),(float)((*this)(i,2))); - cimglist_for(primitives,l) { - const CImg& color = l1?color[1]:r)/255.0f, b = (csiz>2?color[2]:g)/255.0f; - switch (psiz) { - case 1 : std::fprintf(nfile,"1 %u %f %f %f\n", - (unsigned int)primitives(l,0),r,g,b); break; - case 2 : std::fprintf(nfile,"2 %u %u %f %f %f\n", - (unsigned int)primitives(l,0),(unsigned int)primitives(l,1),r,g,b); break; - case 3 : std::fprintf(nfile,"3 %u %u %u %f %f %f\n", - (unsigned int)primitives(l,0),(unsigned int)primitives(l,2), - (unsigned int)primitives(l,1),r,g,b); break; - case 4 : std::fprintf(nfile,"4 %u %u %u %u %f %f %f\n", - (unsigned int)primitives(l,0),(unsigned int)primitives(l,3), - (unsigned int)primitives(l,2),(unsigned int)primitives(l,1),r,g,b); break; - case 5 : std::fprintf(nfile,"2 %u %u %f %f %f\n", - (unsigned int)primitives(l,0),(unsigned int)primitives(l,1),r,g,b); break; - case 6 : { - const unsigned int xt = (unsigned int)primitives(l,2), yt = (unsigned int)primitives(l,3); - const float - rt = color.atXY(xt,yt,0)/255.0f, - gt = (csiz>1?color.atXY(xt,yt,1):r)/255.0f, - bt = (csiz>2?color.atXY(xt,yt,2):g)/255.0f; - std::fprintf(nfile,"2 %u %u %f %f %f\n", - (unsigned int)primitives(l,0),(unsigned int)primitives(l,1),rt,gt,bt); - } break; - case 9 : { - const unsigned int xt = (unsigned int)primitives(l,3), yt = (unsigned int)primitives(l,4); - const float - rt = color.atXY(xt,yt,0)/255.0f, - gt = (csiz>1?color.atXY(xt,yt,1):r)/255.0f, - bt = (csiz>2?color.atXY(xt,yt,2):g)/255.0f; - std::fprintf(nfile,"3 %u %u %u %f %f %f\n", - (unsigned int)primitives(l,0),(unsigned int)primitives(l,2), - (unsigned int)primitives(l,1),rt,gt,bt); - } break; - case 12 : { - const unsigned int xt = (unsigned int)primitives(l,4), yt = (unsigned int)primitives(l,5); - const float - rt = color.atXY(xt,yt,0)/255.0f, - gt = (csiz>1?color.atXY(xt,yt,1):r)/255.0f, - bt = (csiz>2?color.atXY(xt,yt,2):g)/255.0f; - std::fprintf(nfile,"4 %u %u %u %u %f %f %f\n", - (unsigned int)primitives(l,0),(unsigned int)primitives(l,3), - (unsigned int)primitives(l,2),(unsigned int)primitives(l,1),rt,gt,bt); - } break; - } - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Save volumetric image as a video, using the OpenCV library. - /** - \param filename Filename to write data to. - \param fps Number of frames per second. - \param codec Type of compression (See http://www.fourcc.org/codecs.php to see available codecs). - \param keep_open Tells if the video writer associated to the specified filename - must be kept open or not (to allow frames to be added in the same file afterwards). - **/ - const CImg& save_video(const char *const filename, const unsigned int fps=25, - const char *codec=0, const bool keep_open=false) const { - if (is_empty()) { CImgList().save_video(filename,fps,codec,keep_open); return *this; } - CImgList list; - get_split('z').move_to(list); - list.save_video(filename,fps,codec,keep_open); - return *this; - } - - //! Save volumetric image as a video, using ffmpeg external binary. - /** - \param filename Filename, as a C-string. - \param fps Video framerate. - \param codec Video codec, as a C-string. - \param bitrate Video bitrate. - \note - - Each slice of the instance image is considered to be a single frame of the output video file. - - This method uses \c ffmpeg, an external executable binary provided by - FFmpeg. - It must be installed for the method to succeed. - **/ - const CImg& save_ffmpeg_external(const char *const filename, const unsigned int fps=25, - const char *const codec=0, const unsigned int bitrate=2048) const { - if (!filename) - throw CImgArgumentException(_cimg_instance - "save_ffmpeg_external(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(0,filename); return *this; } - - CImgList list; - get_split('z').move_to(list); - list.save_ffmpeg_external(filename,fps,codec,bitrate); - return *this; - } - - //! Save image using gzip external binary. - /** - \param filename Filename, as a C-string. - \note This method uses \c gzip, an external executable binary provided by - gzip. - It must be installed for the method to succeed. - **/ - const CImg& save_gzip_external(const char *const filename) const { - if (!filename) - throw CImgArgumentException(_cimg_instance - "save_gzip_external(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(0,filename); return *this; } - - CImg command(1024), filename_tmp(256), body(256); - const char - *ext = cimg::split_filename(filename,body), - *ext2 = cimg::split_filename(body,0); - std::FILE *file; - do { - if (!cimg::strcasecmp(ext,"gz")) { - if (*ext2) cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.%s", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),ext2); - else cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.cimg", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand()); - } else { - if (*ext) cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.%s", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),ext); - else cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.cimg", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand()); - } - if ((file=std_fopen(filename_tmp,"rb"))!=0) cimg::fclose(file); - } while (file); - save(filename_tmp); - cimg_snprintf(command,command._width,"%s -c \"%s\" > \"%s\"", - cimg::gzip_path(), - CImg::string(filename_tmp)._system_strescape().data(), - CImg::string(filename)._system_strescape().data()); - cimg::system(command); - file = std_fopen(filename,"rb"); - if (!file) - throw CImgIOException(_cimg_instance - "save_gzip_external(): Failed to save file '%s' with external command 'gzip'.", - cimg_instance, - filename); - - else cimg::fclose(file); - std::remove(filename_tmp); - return *this; - } - - //! Save image using GraphicsMagick's external binary. - /** - \param filename Filename, as a C-string. - \param quality Image quality (expressed in percent), when the file format supports it. - \note This method uses \c gm, an external executable binary provided by - GraphicsMagick. - It must be installed for the method to succeed. - **/ - const CImg& save_graphicsmagick_external(const char *const filename, const unsigned int quality=100) const { - if (!filename) - throw CImgArgumentException(_cimg_instance - "save_graphicsmagick_external(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(0,filename); return *this; } - if (_depth>1) - cimg::warn(_cimg_instance - "save_other(): File '%s', saving a volumetric image with an external call to " - "GraphicsMagick only writes the first image slice.", - cimg_instance,filename); - -#ifdef cimg_use_png -#define _cimg_sge_ext1 "png" -#define _cimg_sge_ext2 "png" -#else -#define _cimg_sge_ext1 "pgm" -#define _cimg_sge_ext2 "ppm" -#endif - CImg command(1024), filename_tmp(256); - std::FILE *file; - do { - cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.%s", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(), - _spectrum==1?_cimg_sge_ext1:_cimg_sge_ext2); - if ((file=std_fopen(filename_tmp,"rb"))!=0) cimg::fclose(file); - } while (file); -#ifdef cimg_use_png - save_png(filename_tmp); -#else - save_pnm(filename_tmp); -#endif - cimg_snprintf(command,command._width,"%s convert -quality %u \"%s\" \"%s\"", - cimg::graphicsmagick_path(),quality, - CImg::string(filename_tmp)._system_strescape().data(), - CImg::string(filename)._system_strescape().data()); - cimg::system(command); - file = std_fopen(filename,"rb"); - if (!file) - throw CImgIOException(_cimg_instance - "save_graphicsmagick_external(): Failed to save file '%s' with external command 'gm'.", - cimg_instance, - filename); - - if (file) cimg::fclose(file); - std::remove(filename_tmp); - return *this; - } - - //! Save image using ImageMagick's external binary. - /** - \param filename Filename, as a C-string. - \param quality Image quality (expressed in percent), when the file format supports it. - \note This method uses \c convert, an external executable binary provided by - ImageMagick. - It must be installed for the method to succeed. - **/ - const CImg& save_imagemagick_external(const char *const filename, const unsigned int quality=100) const { - if (!filename) - throw CImgArgumentException(_cimg_instance - "save_imagemagick_external(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(0,filename); return *this; } - if (_depth>1) - cimg::warn(_cimg_instance - "save_other(): File '%s', saving a volumetric image with an external call to " - "ImageMagick only writes the first image slice.", - cimg_instance,filename); -#ifdef cimg_use_png -#define _cimg_sie_ext1 "png" -#define _cimg_sie_ext2 "png" -#else -#define _cimg_sie_ext1 "pgm" -#define _cimg_sie_ext2 "ppm" -#endif - CImg command(1024), filename_tmp(256); - std::FILE *file; - do { - cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.%s",cimg::temporary_path(), - cimg_file_separator,cimg::filenamerand(),_spectrum==1?_cimg_sie_ext1:_cimg_sie_ext2); - if ((file=std_fopen(filename_tmp,"rb"))!=0) cimg::fclose(file); - } while (file); -#ifdef cimg_use_png - save_png(filename_tmp); -#else - save_pnm(filename_tmp); -#endif - cimg_snprintf(command,command._width,"%s -quality %u \"%s\" \"%s\"", - cimg::imagemagick_path(),quality, - CImg::string(filename_tmp)._system_strescape().data(), - CImg::string(filename)._system_strescape().data()); - cimg::system(command); - file = std_fopen(filename,"rb"); - if (!file) - throw CImgIOException(_cimg_instance - "save_imagemagick_external(): Failed to save file '%s' with external command 'convert'.", - cimg_instance, - filename); - - if (file) cimg::fclose(file); - std::remove(filename_tmp); - return *this; - } - - //! Save image as a Dicom file. - /** - \param filename Filename, as a C-string. - \note This method uses \c medcon, an external executable binary provided by - (X)Medcon. - It must be installed for the method to succeed. - **/ - const CImg& save_medcon_external(const char *const filename) const { - if (!filename) - throw CImgArgumentException(_cimg_instance - "save_medcon_external(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(0,filename); return *this; } - - CImg command(1024), filename_tmp(256), body(256); - std::FILE *file; - do { - cimg_snprintf(filename_tmp,filename_tmp._width,"%s.hdr",cimg::filenamerand()); - if ((file=std_fopen(filename_tmp,"rb"))!=0) cimg::fclose(file); - } while (file); - save_analyze(filename_tmp); - cimg_snprintf(command,command._width,"%s -w -c dicom -o \"%s\" -f \"%s\"", - cimg::medcon_path(), - CImg::string(filename)._system_strescape().data(), - CImg::string(filename_tmp)._system_strescape().data()); - cimg::system(command); - std::remove(filename_tmp); - cimg::split_filename(filename_tmp,body); - cimg_snprintf(filename_tmp,filename_tmp._width,"%s.img",body._data); - std::remove(filename_tmp); - - file = std_fopen(filename,"rb"); - if (!file) { - cimg_snprintf(command,command._width,"m000-%s",filename); - file = std_fopen(command,"rb"); - if (!file) { - cimg::fclose(cimg::fopen(filename,"r")); - throw CImgIOException(_cimg_instance - "save_medcon_external(): Failed to save file '%s' with external command 'medcon'.", - cimg_instance, - filename); - } - } - cimg::fclose(file); - std::rename(command,filename); - return *this; - } - - // Save image for non natively supported formats. - /** - \param filename Filename, as a C-string. - \param quality Image quality (expressed in percent), when the file format supports it. - \note - - The filename extension tells about the desired file format. - - This method tries to save the instance image as a file, using external tools from - ImageMagick or - GraphicsMagick. - At least one of these tool must be installed for the method to succeed. - - It is recommended to use the generic method save(const char*, int) const instead, - as it can handle some file formats natively. - **/ - const CImg& save_other(const char *const filename, const unsigned int quality=100) const { - if (!filename) - throw CImgArgumentException(_cimg_instance - "save_other(): Specified filename is (null).", - cimg_instance); - if (is_empty()) { cimg::fempty(0,filename); return *this; } - if (_depth>1) - cimg::warn(_cimg_instance - "save_other(): File '%s', saving a volumetric image with an external call to " - "ImageMagick or GraphicsMagick only writes the first image slice.", - cimg_instance,filename); - - const unsigned int omode = cimg::exception_mode(); - bool is_saved = true; - cimg::exception_mode(0); - try { save_magick(filename); } - catch (CImgException&) { - try { save_imagemagick_external(filename,quality); } - catch (CImgException&) { - try { save_graphicsmagick_external(filename,quality); } - catch (CImgException&) { - is_saved = false; - } - } - } - cimg::exception_mode(omode); - if (!is_saved) - throw CImgIOException(_cimg_instance - "save_other(): Failed to save file '%s'. Format is not natively supported, " - "and no external commands succeeded.", - cimg_instance, - filename); - return *this; - } - - //! Serialize a CImg instance into a raw CImg buffer. - /** - \param is_compressed tells if zlib compression must be used for serialization - (this requires 'cimg_use_zlib' been enabled). - **/ - CImg get_serialize(const bool is_compressed=false) const { - return CImgList(*this,true).get_serialize(is_compressed); - } - - // [internal] Return a 40x38 color logo of a 'danger' item. - static CImg _logo40x38() { - CImg res(40,38,1,3); - const unsigned char *ptrs = cimg::logo40x38; - T *ptr1 = res.data(0,0,0,0), *ptr2 = res.data(0,0,0,1), *ptr3 = res.data(0,0,0,2); - for (ulongT off = 0; off<(ulongT)res._width*res._height;) { - const unsigned char n = *(ptrs++), r = *(ptrs++), g = *(ptrs++), b = *(ptrs++); - for (unsigned int l = 0; l structure - # - # - # - #------------------------------------------ - */ - //! Represent a list of images CImg. - template - struct CImgList { - unsigned int _width, _allocated_width; - CImg *_data; - - //! Simple iterator type, to loop through each image of a list. - /** - \note - - The \c CImgList::iterator type is defined as a CImg*. - - You may use it like this: - \code - CImgList<> list; // Assuming this image list is not empty. - for (CImgList<>::iterator it = list.begin(); it* iterator; - - //! Simple const iterator type, to loop through each image of a \c const list instance. - /** - \note - - The \c CImgList::const_iterator type is defined to be a const CImg*. - - Similar to CImgList::iterator, but for constant list instances. - **/ - typedef const CImg* const_iterator; - - //! Pixel value type. - /** - Refer to the pixels value type of the images in the list. - \note - - The \c CImgList::value_type type of a \c CImgList is defined to be a \c T. - It is then similar to CImg::value_type. - - \c CImgList::value_type is actually not used in %CImg methods. It has been mainly defined for - compatibility with STL naming conventions. - **/ - typedef T value_type; - - // Define common types related to template type T. - typedef typename cimg::superset::type Tbool; - typedef typename cimg::superset::type Tuchar; - typedef typename cimg::superset::type Tchar; - typedef typename cimg::superset::type Tushort; - typedef typename cimg::superset::type Tshort; - typedef typename cimg::superset::type Tuint; - typedef typename cimg::superset::type Tint; - typedef typename cimg::superset::type Tulong; - typedef typename cimg::superset::type Tlong; - typedef typename cimg::superset::type Tfloat; - typedef typename cimg::superset::type Tdouble; - typedef typename cimg::last::type boolT; - typedef typename cimg::last::type ucharT; - typedef typename cimg::last::type charT; - typedef typename cimg::last::type ushortT; - typedef typename cimg::last::type shortT; - typedef typename cimg::last::type uintT; - typedef typename cimg::last::type intT; - typedef typename cimg::last::type ulongT; - typedef typename cimg::last::type longT; - typedef typename cimg::last::type uint64T; - typedef typename cimg::last::type int64T; - typedef typename cimg::last::type floatT; - typedef typename cimg::last::type doubleT; - - //@} - //--------------------------- - // - //! \name Plugins - //@{ - //--------------------------- -#ifdef cimglist_plugin -#include cimglist_plugin -#endif -#ifdef cimglist_plugin1 -#include cimglist_plugin1 -#endif -#ifdef cimglist_plugin2 -#include cimglist_plugin2 -#endif -#ifdef cimglist_plugin3 -#include cimglist_plugin3 -#endif -#ifdef cimglist_plugin4 -#include cimglist_plugin4 -#endif -#ifdef cimglist_plugin5 -#include cimglist_plugin5 -#endif -#ifdef cimglist_plugin6 -#include cimglist_plugin6 -#endif -#ifdef cimglist_plugin7 -#include cimglist_plugin7 -#endif -#ifdef cimglist_plugin8 -#include cimglist_plugin8 -#endif - - //@} - //-------------------------------------------------------- - // - //! \name Constructors / Destructor / Instance Management - //@{ - //-------------------------------------------------------- - - //! Destructor. - /** - Destroy current list instance. - \note - - Any allocated buffer is deallocated. - - Destroying an empty list does nothing actually. - **/ - ~CImgList() { - delete[] _data; - } - - //! Default constructor. - /** - Construct a new empty list instance. - \note - - An empty list has no pixel data and its dimension width() is set to \c 0, as well as its - image buffer pointer data(). - - An empty list may be reassigned afterwards, with the family of the assign() methods. - In all cases, the type of pixels stays \c T. - **/ - CImgList(): - _width(0),_allocated_width(0),_data(0) {} - - //! Construct list containing empty images. - /** - \param n Number of empty images. - \note Useful when you know by advance the number of images you want to manage, as - it will allocate the right amount of memory for the list, without needs for reallocation - (that may occur when starting from an empty list and inserting several images in it). - **/ - explicit CImgList(const unsigned int n):_width(n) { - if (n) _data = new CImg[_allocated_width = (unsigned int)cimg::max(16UL,cimg::nearest_pow2(n))]; - else { _allocated_width = 0; _data = 0; } - } - - //! Construct list containing images of specified size. - /** - \param n Number of images. - \param width Width of images. - \param height Height of images. - \param depth Depth of images. - \param spectrum Number of channels of images. - \note Pixel values are not initialized and may probably contain garbage. - **/ - CImgList(const unsigned int n, const unsigned int width, const unsigned int height=1, - const unsigned int depth=1, const unsigned int spectrum=1): - _width(0),_allocated_width(0),_data(0) { - assign(n); - cimglist_apply(*this,assign)(width,height,depth,spectrum); - } - - //! Construct list containing images of specified size, and initialize pixel values. - /** - \param n Number of images. - \param width Width of images. - \param height Height of images. - \param depth Depth of images. - \param spectrum Number of channels of images. - \param val Initialization value for images pixels. - **/ - CImgList(const unsigned int n, const unsigned int width, const unsigned int height, - const unsigned int depth, const unsigned int spectrum, const T& val): - _width(0),_allocated_width(0),_data(0) { - assign(n); - cimglist_apply(*this,assign)(width,height,depth,spectrum,val); - } - - //! Construct list containing images of specified size, and initialize pixel values from a sequence of integers. - /** - \param n Number of images. - \param width Width of images. - \param height Height of images. - \param depth Depth of images. - \param spectrum Number of channels of images. - \param val0 First value of the initializing integers sequence. - \param val1 Second value of the initializing integers sequence. - \warning You must specify at least width*height*depth*spectrum values in your argument list, - or you will probably segfault. - **/ - CImgList(const unsigned int n, const unsigned int width, const unsigned int height, - const unsigned int depth, const unsigned int spectrum, const int val0, const int val1, ...): - _width(0),_allocated_width(0),_data(0) { -#define _CImgList_stdarg(t) { \ - assign(n,width,height,depth,spectrum); \ - const ulongT siz = (ulongT)width*height*depth*spectrum, nsiz = siz*n; \ - T *ptrd = _data->_data; \ - va_list ap; \ - va_start(ap,val1); \ - for (ulongT l = 0, s = 0, i = 0; iwidth*height*depth*spectrum values in your argument list, - or you will probably segfault. - **/ - CImgList(const unsigned int n, const unsigned int width, const unsigned int height, - const unsigned int depth, const unsigned int spectrum, const double val0, const double val1, ...): - _width(0),_allocated_width(0),_data(0) { - _CImgList_stdarg(double); - } - - //! Construct list containing copies of an input image. - /** - \param n Number of images. - \param img Input image to copy in the constructed list. - \param is_shared Tells if the elements of the list are shared or non-shared copies of \c img. - **/ - template - CImgList(const unsigned int n, const CImg& img, const bool is_shared=false): - _width(0),_allocated_width(0),_data(0) { - assign(n); - cimglist_apply(*this,assign)(img,is_shared); - } - - //! Construct list from one image. - /** - \param img Input image to copy in the constructed list. - \param is_shared Tells if the element of the list is a shared or non-shared copy of \c img. - **/ - template - explicit CImgList(const CImg& img, const bool is_shared=false): - _width(0),_allocated_width(0),_data(0) { - assign(1); - _data[0].assign(img,is_shared); - } - - //! Construct list from two images. - /** - \param img1 First input image to copy in the constructed list. - \param img2 Second input image to copy in the constructed list. - \param is_shared Tells if the elements of the list are shared or non-shared copies of input images. - **/ - template - CImgList(const CImg& img1, const CImg& img2, const bool is_shared=false): - _width(0),_allocated_width(0),_data(0) { - assign(2); - _data[0].assign(img1,is_shared); _data[1].assign(img2,is_shared); - } - - //! Construct list from three images. - /** - \param img1 First input image to copy in the constructed list. - \param img2 Second input image to copy in the constructed list. - \param img3 Third input image to copy in the constructed list. - \param is_shared Tells if the elements of the list are shared or non-shared copies of input images. - **/ - template - CImgList(const CImg& img1, const CImg& img2, const CImg& img3, const bool is_shared=false): - _width(0),_allocated_width(0),_data(0) { - assign(3); - _data[0].assign(img1,is_shared); _data[1].assign(img2,is_shared); _data[2].assign(img3,is_shared); - } - - //! Construct list from four images. - /** - \param img1 First input image to copy in the constructed list. - \param img2 Second input image to copy in the constructed list. - \param img3 Third input image to copy in the constructed list. - \param img4 Fourth input image to copy in the constructed list. - \param is_shared Tells if the elements of the list are shared or non-shared copies of input images. - **/ - template - CImgList(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, - const bool is_shared=false): - _width(0),_allocated_width(0),_data(0) { - assign(4); - _data[0].assign(img1,is_shared); _data[1].assign(img2,is_shared); _data[2].assign(img3,is_shared); - _data[3].assign(img4,is_shared); - } - - //! Construct list from five images. - /** - \param img1 First input image to copy in the constructed list. - \param img2 Second input image to copy in the constructed list. - \param img3 Third input image to copy in the constructed list. - \param img4 Fourth input image to copy in the constructed list. - \param img5 Fifth input image to copy in the constructed list. - \param is_shared Tells if the elements of the list are shared or non-shared copies of input images. - **/ - template - CImgList(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, - const CImg& img5, const bool is_shared=false): - _width(0),_allocated_width(0),_data(0) { - assign(5); - _data[0].assign(img1,is_shared); _data[1].assign(img2,is_shared); _data[2].assign(img3,is_shared); - _data[3].assign(img4,is_shared); _data[4].assign(img5,is_shared); - } - - //! Construct list from six images. - /** - \param img1 First input image to copy in the constructed list. - \param img2 Second input image to copy in the constructed list. - \param img3 Third input image to copy in the constructed list. - \param img4 Fourth input image to copy in the constructed list. - \param img5 Fifth input image to copy in the constructed list. - \param img6 Sixth input image to copy in the constructed list. - \param is_shared Tells if the elements of the list are shared or non-shared copies of input images. - **/ - template - CImgList(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, - const CImg& img5, const CImg& img6, const bool is_shared=false): - _width(0),_allocated_width(0),_data(0) { - assign(6); - _data[0].assign(img1,is_shared); _data[1].assign(img2,is_shared); _data[2].assign(img3,is_shared); - _data[3].assign(img4,is_shared); _data[4].assign(img5,is_shared); _data[5].assign(img6,is_shared); - } - - //! Construct list from seven images. - /** - \param img1 First input image to copy in the constructed list. - \param img2 Second input image to copy in the constructed list. - \param img3 Third input image to copy in the constructed list. - \param img4 Fourth input image to copy in the constructed list. - \param img5 Fifth input image to copy in the constructed list. - \param img6 Sixth input image to copy in the constructed list. - \param img7 Seventh input image to copy in the constructed list. - \param is_shared Tells if the elements of the list are shared or non-shared copies of input images. - **/ - template - CImgList(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, - const CImg& img5, const CImg& img6, const CImg& img7, const bool is_shared=false): - _width(0),_allocated_width(0),_data(0) { - assign(7); - _data[0].assign(img1,is_shared); _data[1].assign(img2,is_shared); _data[2].assign(img3,is_shared); - _data[3].assign(img4,is_shared); _data[4].assign(img5,is_shared); _data[5].assign(img6,is_shared); - _data[6].assign(img7,is_shared); - } - - //! Construct list from eight images. - /** - \param img1 First input image to copy in the constructed list. - \param img2 Second input image to copy in the constructed list. - \param img3 Third input image to copy in the constructed list. - \param img4 Fourth input image to copy in the constructed list. - \param img5 Fifth input image to copy in the constructed list. - \param img6 Sixth input image to copy in the constructed list. - \param img7 Seventh input image to copy in the constructed list. - \param img8 Eighth input image to copy in the constructed list. - \param is_shared Tells if the elements of the list are shared or non-shared copies of input images. - **/ - template - CImgList(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, - const CImg& img5, const CImg& img6, const CImg& img7, const CImg& img8, - const bool is_shared=false): - _width(0),_allocated_width(0),_data(0) { - assign(8); - _data[0].assign(img1,is_shared); _data[1].assign(img2,is_shared); _data[2].assign(img3,is_shared); - _data[3].assign(img4,is_shared); _data[4].assign(img5,is_shared); _data[5].assign(img6,is_shared); - _data[6].assign(img7,is_shared); _data[7].assign(img8,is_shared); - } - - //! Construct list copy. - /** - \param list Input list to copy. - \note The shared state of each element of the constructed list is kept the same as in \c list. - **/ - template - CImgList(const CImgList& list):_width(0),_allocated_width(0),_data(0) { - assign(list._width); - cimglist_for(*this,l) _data[l].assign(list[l],false); - } - - //! Construct list copy \specialization. - CImgList(const CImgList& list):_width(0),_allocated_width(0),_data(0) { - assign(list._width); - cimglist_for(*this,l) _data[l].assign(list[l],list[l]._is_shared); - } - - //! Construct list copy, and force the shared state of the list elements. - /** - \param list Input list to copy. - \param is_shared Tells if the elements of the list are shared or non-shared copies of input images. - **/ - template - CImgList(const CImgList& list, const bool is_shared):_width(0),_allocated_width(0),_data(0) { - assign(list._width); - cimglist_for(*this,l) _data[l].assign(list[l],is_shared); - } - - //! Construct list by reading the content of a file. - /** - \param filename Filename, as a C-string. - **/ - explicit CImgList(const char *const filename):_width(0),_allocated_width(0),_data(0) { - assign(filename); - } - - //! Construct list from the content of a display window. - /** - \param disp Display window to get content from. - \note Constructed list contains a single image only. - **/ - explicit CImgList(const CImgDisplay& disp):_width(0),_allocated_width(0),_data(0) { - assign(disp); - } - - //! Return a list with elements being shared copies of images in the list instance. - /** - \note list2 = list1.get_shared() is equivalent to list2.assign(list1,true). - **/ - CImgList get_shared() { - CImgList res(_width); - cimglist_for(*this,l) res[l].assign(_data[l],true); - return res; - } - - //! Return a list with elements being shared copies of images in the list instance \const. - const CImgList get_shared() const { - CImgList res(_width); - cimglist_for(*this,l) res[l].assign(_data[l],true); - return res; - } - - //! Destructor \inplace. - /** - \see CImgList(). - **/ - CImgList& assign() { - delete[] _data; - _width = _allocated_width = 0; - _data = 0; - return *this; - } - - //! Destructor \inplace. - /** - Equivalent to assign(). - \note Only here for compatibility with STL naming conventions. - **/ - CImgList& clear() { - return assign(); - } - - //! Construct list containing empty images \inplace. - /** - \see CImgList(unsigned int). - **/ - CImgList& assign(const unsigned int n) { - if (!n) return assign(); - if (_allocated_width(n<<2)) { - delete[] _data; - _data = new CImg[_allocated_width = (unsigned int)cimg::max(16UL,cimg::nearest_pow2(n))]; - } - _width = n; - return *this; - } - - //! Construct list containing images of specified size \inplace. - /** - \see CImgList(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int). - **/ - CImgList& assign(const unsigned int n, const unsigned int width, const unsigned int height=1, - const unsigned int depth=1, const unsigned int spectrum=1) { - assign(n); - cimglist_apply(*this,assign)(width,height,depth,spectrum); - return *this; - } - - //! Construct list containing images of specified size, and initialize pixel values \inplace. - /** - \see CImgList(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, const T). - **/ - CImgList& assign(const unsigned int n, const unsigned int width, const unsigned int height, - const unsigned int depth, const unsigned int spectrum, const T& val) { - assign(n); - cimglist_apply(*this,assign)(width,height,depth,spectrum,val); - return *this; - } - - //! Construct list with images of specified size, and initialize pixel values from a sequence of integers \inplace. - /** - \see CImgList(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, const int, const int, ...). - **/ - CImgList& assign(const unsigned int n, const unsigned int width, const unsigned int height, - const unsigned int depth, const unsigned int spectrum, const int val0, const int val1, ...) { - _CImgList_stdarg(int); - return *this; - } - - //! Construct list with images of specified size, and initialize pixel values from a sequence of doubles \inplace. - /** - \see CImgList(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, const double, const double, ...). - **/ - CImgList& assign(const unsigned int n, const unsigned int width, const unsigned int height, - const unsigned int depth, const unsigned int spectrum, - const double val0, const double val1, ...) { - _CImgList_stdarg(double); - return *this; - } - - //! Construct list containing copies of an input image \inplace. - /** - \see CImgList(unsigned int, const CImg&, bool). - **/ - template - CImgList& assign(const unsigned int n, const CImg& img, const bool is_shared=false) { - assign(n); - cimglist_apply(*this,assign)(img,is_shared); - return *this; - } - - //! Construct list from one image \inplace. - /** - \see CImgList(const CImg&, bool). - **/ - template - CImgList& assign(const CImg& img, const bool is_shared=false) { - assign(1); - _data[0].assign(img,is_shared); - return *this; - } - - //! Construct list from two images \inplace. - /** - \see CImgList(const CImg&, const CImg&, bool). - **/ - template - CImgList& assign(const CImg& img1, const CImg& img2, const bool is_shared=false) { - assign(2); - _data[0].assign(img1,is_shared); _data[1].assign(img2,is_shared); - return *this; - } - - //! Construct list from three images \inplace. - /** - \see CImgList(const CImg&, const CImg&, const CImg&, bool). - **/ - template - CImgList& assign(const CImg& img1, const CImg& img2, const CImg& img3, const bool is_shared=false) { - assign(3); - _data[0].assign(img1,is_shared); _data[1].assign(img2,is_shared); _data[2].assign(img3,is_shared); - return *this; - } - - //! Construct list from four images \inplace. - /** - \see CImgList(const CImg&, const CImg&, const CImg&, const CImg&, bool). - **/ - template - CImgList& assign(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, - const bool is_shared=false) { - assign(4); - _data[0].assign(img1,is_shared); _data[1].assign(img2,is_shared); _data[2].assign(img3,is_shared); - _data[3].assign(img4,is_shared); - return *this; - } - - //! Construct list from five images \inplace. - /** - \see CImgList(const CImg&, const CImg&, const CImg&, const CImg&, const CImg&, bool). - **/ - template - CImgList& assign(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, - const CImg& img5, const bool is_shared=false) { - assign(5); - _data[0].assign(img1,is_shared); _data[1].assign(img2,is_shared); _data[2].assign(img3,is_shared); - _data[3].assign(img4,is_shared); _data[4].assign(img5,is_shared); - return *this; - } - - //! Construct list from six images \inplace. - /** - \see CImgList(const CImg&, const CImg&, const CImg&, const CImg&, const CImg&, const CImg&, bool). - **/ - template - CImgList& assign(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, - const CImg& img5, const CImg& img6, const bool is_shared=false) { - assign(6); - _data[0].assign(img1,is_shared); _data[1].assign(img2,is_shared); _data[2].assign(img3,is_shared); - _data[3].assign(img4,is_shared); _data[4].assign(img5,is_shared); _data[5].assign(img6,is_shared); - return *this; - } - - //! Construct list from seven images \inplace. - /** - \see CImgList(const CImg&, const CImg&, const CImg&, const CImg&, const CImg&, const CImg&, const CImg&, bool). - **/ - template - CImgList& assign(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, - const CImg& img5, const CImg& img6, const CImg& img7, const bool is_shared=false) { - assign(7); - _data[0].assign(img1,is_shared); _data[1].assign(img2,is_shared); _data[2].assign(img3,is_shared); - _data[3].assign(img4,is_shared); _data[4].assign(img5,is_shared); _data[5].assign(img6,is_shared); - _data[6].assign(img7,is_shared); - return *this; - } - - //! Construct list from eight images \inplace. - /** - \see CImgList(const CImg&, const CImg&, const CImg&, const CImg&, const CImg&, const CImg&, const CImg&, const CImg&, bool). - **/ - template - CImgList& assign(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, - const CImg& img5, const CImg& img6, const CImg& img7, const CImg& img8, - const bool is_shared=false) { - assign(8); - _data[0].assign(img1,is_shared); _data[1].assign(img2,is_shared); _data[2].assign(img3,is_shared); - _data[3].assign(img4,is_shared); _data[4].assign(img5,is_shared); _data[5].assign(img6,is_shared); - _data[6].assign(img7,is_shared); _data[7].assign(img8,is_shared); - return *this; - } - - //! Construct list as a copy of an existing list and force the shared state of the list elements \inplace. - /** - \see CImgList(const CImgList&, bool is_shared). - **/ - template - CImgList& assign(const CImgList& list, const bool is_shared=false) { - cimg::unused(is_shared); - assign(list._width); - cimglist_for(*this,l) _data[l].assign(list[l],false); - return *this; - } - - //! Construct list as a copy of an existing list and force shared state of elements \inplace \specialization. - CImgList& assign(const CImgList& list, const bool is_shared=false) { - if (this==&list) return *this; - CImgList res(list._width); - cimglist_for(res,l) res[l].assign(list[l],is_shared); - return res.move_to(*this); - } - - //! Construct list by reading the content of a file \inplace. - /** - \see CImgList(const char *const). - **/ - CImgList& assign(const char *const filename) { - return load(filename); - } - - //! Construct list from the content of a display window \inplace. - /** - \see CImgList(const CImgDisplay&). - **/ - CImgList& assign(const CImgDisplay &disp) { - return assign(CImg(disp)); - } - - //! Transfer the content of the list instance to another list. - /** - \param list Destination list. - \note When returning, the current list instance is empty and the initial content of \c list is destroyed. - **/ - template - CImgList& move_to(CImgList& list) { - list.assign(_width); - bool is_one_shared_element = false; - cimglist_for(*this,l) is_one_shared_element|=_data[l]._is_shared; - if (is_one_shared_element) cimglist_for(*this,l) list[l].assign(_data[l]); - else cimglist_for(*this,l) _data[l].move_to(list[l]); - assign(); - return list; - } - - //! Transfer the content of the list instance at a specified position in another list. - /** - \param list Destination list. - \param pos Index of the insertion in the list. - \note When returning, the list instance is empty and the initial content of \c list is preserved - (only images indexes may be modified). - **/ - template - CImgList& move_to(CImgList& list, const unsigned int pos) { - if (is_empty()) return list; - const unsigned int npos = pos>list._width?list._width:pos; - list.insert(_width,npos); - bool is_one_shared_element = false; - cimglist_for(*this,l) is_one_shared_element|=_data[l]._is_shared; - if (is_one_shared_element) cimglist_for(*this,l) list[npos + l].assign(_data[l]); - else cimglist_for(*this,l) _data[l].move_to(list[npos + l]); - assign(); - return list; - } - - //! Swap all fields between two list instances. - /** - \param list List to swap fields with. - \note Can be used to exchange the content of two lists in a fast way. - **/ - CImgList& swap(CImgList& list) { - cimg::swap(_width,list._width,_allocated_width,list._allocated_width); - cimg::swap(_data,list._data); - return list; - } - - //! Return a reference to an empty list. - /** - \note Can be used to define default values in a function taking a CImgList as an argument. - \code - void f(const CImgList& list=CImgList::empty()); - \endcode - **/ - static CImgList& empty() { - static CImgList _empty; - return _empty.assign(); - } - - //! Return a reference to an empty list \const. - static const CImgList& const_empty() { - static const CImgList _empty; - return _empty; - } - - //@} - //------------------------------------------ - // - //! \name Overloaded Operators - //@{ - //------------------------------------------ - - //! Return a reference to one image element of the list. - /** - \param pos Indice of the image element. - **/ - CImg& operator()(const unsigned int pos) { -#if cimg_verbosity>=3 - if (pos>=_width) { - cimg::warn(_cimglist_instance - "operator(): Invalid image request, at position [%u].", - cimglist_instance, - pos); - return *_data; - } -#endif - return _data[pos]; - } - - //! Return a reference to one image of the list. - /** - \param pos Indice of the image element. - **/ - const CImg& operator()(const unsigned int pos) const { - return const_cast*>(this)->operator()(pos); - } - - //! Return a reference to one pixel value of one image of the list. - /** - \param pos Indice of the image element. - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \note list(n,x,y,z,c) is equivalent to list[n](x,y,z,c). - **/ - T& operator()(const unsigned int pos, const unsigned int x, const unsigned int y=0, - const unsigned int z=0, const unsigned int c=0) { - return (*this)[pos](x,y,z,c); - } - - //! Return a reference to one pixel value of one image of the list \const. - const T& operator()(const unsigned int pos, const unsigned int x, const unsigned int y=0, - const unsigned int z=0, const unsigned int c=0) const { - return (*this)[pos](x,y,z,c); - } - - //! Return pointer to the first image of the list. - /** - \note Images in a list are stored as a buffer of \c CImg. - **/ - operator CImg*() { - return _data; - } - - //! Return pointer to the first image of the list \const. - operator const CImg*() const { - return _data; - } - - //! Construct list from one image \inplace. - /** - \param img Input image to copy in the constructed list. - \note list = img; is equivalent to list.assign(img);. - **/ - template - CImgList& operator=(const CImg& img) { - return assign(img); - } - - //! Construct list from another list. - /** - \param list Input list to copy. - \note list1 = list2 is equivalent to list1.assign(list2);. - **/ - template - CImgList& operator=(const CImgList& list) { - return assign(list); - } - - //! Construct list from another list \specialization. - CImgList& operator=(const CImgList& list) { - return assign(list); - } - - //! Construct list by reading the content of a file \inplace. - /** - \see CImgList(const char *const). - **/ - CImgList& operator=(const char *const filename) { - return assign(filename); - } - - //! Construct list from the content of a display window \inplace. - /** - \see CImgList(const CImgDisplay&). - **/ - CImgList& operator=(const CImgDisplay& disp) { - return assign(disp); - } - - //! Return a non-shared copy of a list. - /** - \note +list is equivalent to CImgList(list,false). - It forces the copy to have non-shared elements. - **/ - CImgList operator+() const { - return CImgList(*this,false); - } - - //! Return a copy of the list instance, where image \c img has been inserted at the end. - /** - \param img Image inserted at the end of the instance copy. - \note Define a convenient way to create temporary lists of images, as in the following code: - \code - (img1,img2,img3,img4).display("My four images"); - \endcode - **/ - template - CImgList& operator,(const CImg& img) { - return insert(img); - } - - //! Return a copy of the list instance, where image \c img has been inserted at the end \const. - template - CImgList operator,(const CImg& img) const { - return (+*this).insert(img); - } - - //! Return a copy of the list instance, where all elements of input list \c list have been inserted at the end. - /** - \param list List inserted at the end of the instance copy. - **/ - template - CImgList& operator,(const CImgList& list) { - return insert(list); - } - - //! Return a copy of the list instance, where all elements of input \c list have been inserted at the end \const. - template - CImgList& operator,(const CImgList& list) const { - return (+*this).insert(list); - } - - //! Return image corresponding to the appending of all images of the instance list along specified axis. - /** - \param axis Appending axis. Can be { 'x' | 'y' | 'z' | 'c' }. - \note list>'x' is equivalent to list.get_append('x'). - **/ - CImg operator>(const char axis) const { - return get_append(axis,0); - } - - //! Return list corresponding to the splitting of all images of the instance list along specified axis. - /** - \param axis Axis used for image splitting. - \note list<'x' is equivalent to list.get_split('x'). - **/ - CImgList operator<(const char axis) const { - return get_split(axis); - } - - //@} - //------------------------------------- - // - //! \name Instance Characteristics - //@{ - //------------------------------------- - - //! Return the type of image pixel values as a C string. - /** - Return a \c char* string containing the usual type name of the image pixel values - (i.e. a stringified version of the template parameter \c T). - \note - - The returned string may contain spaces (as in \c "unsigned char"). - - If the pixel type \c T does not correspond to a registered type, the string "unknown" is returned. - **/ - static const char* pixel_type() { - return cimg::type::string(); - } - - //! Return the size of the list, i.e. the number of images contained in it. - /** - \note Similar to size() but returns result as a (signed) integer. - **/ - int width() const { - return (int)_width; - } - - //! Return the size of the list, i.e. the number of images contained in it. - /** - \note Similar to width() but returns result as an unsigned integer. - **/ - unsigned int size() const { - return _width; - } - - //! Return pointer to the first image of the list. - /** - \note Images in a list are stored as a buffer of \c CImg. - **/ - CImg *data() { - return _data; - } - - //! Return pointer to the first image of the list \const. - const CImg *data() const { - return _data; - } - - //! Return pointer to the pos-th image of the list. - /** - \param pos Indice of the image element to access. - \note list.data(n); is equivalent to list.data + n;. - **/ -#if cimg_verbosity>=3 - CImg *data(const unsigned int pos) { - if (pos>=size()) - cimg::warn(_cimglist_instance - "data(): Invalid pointer request, at position [%u].", - cimglist_instance, - pos); - return _data + pos; - } - - const CImg *data(const unsigned int l) const { - return const_cast*>(this)->data(l); - } -#else - CImg *data(const unsigned int l) { - return _data + l; - } - - //! Return pointer to the pos-th image of the list \const. - const CImg *data(const unsigned int l) const { - return _data + l; - } -#endif - - //! Return iterator to the first image of the list. - /** - **/ - iterator begin() { - return _data; - } - - //! Return iterator to the first image of the list \const. - const_iterator begin() const { - return _data; - } - - //! Return iterator to one position after the last image of the list. - /** - **/ - iterator end() { - return _data + _width; - } - - //! Return iterator to one position after the last image of the list \const. - const_iterator end() const { - return _data + _width; - } - - //! Return reference to the first image of the list. - /** - **/ - CImg& front() { - return *_data; - } - - //! Return reference to the first image of the list \const. - const CImg& front() const { - return *_data; - } - - //! Return a reference to the last image of the list. - /** - **/ - const CImg& back() const { - return *(_data + _width - 1); - } - - //! Return a reference to the last image of the list \const. - CImg& back() { - return *(_data + _width - 1); - } - - //! Return pos-th image of the list. - /** - \param pos Indice of the image element to access. - **/ - CImg& at(const int pos) { - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "at(): Empty instance.", - cimglist_instance); - - return _data[pos<0?0:pos>=(int)_width?(int)_width - 1:pos]; - } - - //! Access to pixel value with Dirichlet boundary conditions. - /** - \param pos Indice of the image element to access. - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \param out_value Default value returned if \c offset is outside image bounds. - \note list.atNXYZC(p,x,y,z,c); is equivalent to list[p].atXYZC(x,y,z,c);. - **/ - T& atNXYZC(const int pos, const int x, const int y, const int z, const int c, const T& out_value) { - return (pos<0 || pos>=(int)_width)?(cimg::temporary(out_value)=out_value):_data[pos].atXYZC(x,y,z,c,out_value); - } - - //! Access to pixel value with Dirichlet boundary conditions \const. - T atNXYZC(const int pos, const int x, const int y, const int z, const int c, const T& out_value) const { - return (pos<0 || pos>=(int)_width)?out_value:_data[pos].atXYZC(x,y,z,c,out_value); - } - - //! Access to pixel value with Neumann boundary conditions. - /** - \param pos Indice of the image element to access. - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \note list.atNXYZC(p,x,y,z,c); is equivalent to list[p].atXYZC(x,y,z,c);. - **/ - T& atNXYZC(const int pos, const int x, const int y, const int z, const int c) { - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "atNXYZC(): Empty instance.", - cimglist_instance); - - return _atNXYZC(pos,x,y,z,c); - } - - //! Access to pixel value with Neumann boundary conditions \const. - T atNXYZC(const int pos, const int x, const int y, const int z, const int c) const { - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "atNXYZC(): Empty instance.", - cimglist_instance); - - return _atNXYZC(pos,x,y,z,c); - } - - T& _atNXYZC(const int pos, const int x, const int y, const int z, const int c) { - return _data[pos<0?0:(pos>=(int)_width?(int)_width - 1:pos)].atXYZC(x,y,z,c); - } - - T _atNXYZC(const int pos, const int x, const int y, const int z, const int c) const { - return _data[pos<0?0:(pos>=(int)_width?(int)_width - 1:pos)].atXYZC(x,y,z,c); - } - - //! Access pixel value with Dirichlet boundary conditions for the 3 first coordinates (\c pos, \c x,\c y,\c z). - /** - \param pos Indice of the image element to access. - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \param out_value Default value returned if \c offset is outside image bounds. - \note list.atNXYZ(p,x,y,z,c); is equivalent to list[p].atXYZ(x,y,z,c);. - **/ - T& atNXYZ(const int pos, const int x, const int y, const int z, const int c, const T& out_value) { - return (pos<0 || pos>=(int)_width)?(cimg::temporary(out_value)=out_value):_data[pos].atXYZ(x,y,z,c,out_value); - } - - //! Access pixel value with Dirichlet boundary conditions for the 3 first coordinates (\c pos, \c x,\c y,\c z) \const. - T atNXYZ(const int pos, const int x, const int y, const int z, const int c, const T& out_value) const { - return (pos<0 || pos>=(int)_width)?out_value:_data[pos].atXYZ(x,y,z,c,out_value); - } - - //! Access to pixel value with Neumann boundary conditions for the 4 first coordinates (\c pos, \c x,\c y,\c z). - /** - \param pos Indice of the image element to access. - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \note list.atNXYZ(p,x,y,z,c); is equivalent to list[p].atXYZ(x,y,z,c);. - **/ - T& atNXYZ(const int pos, const int x, const int y, const int z, const int c=0) { - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "atNXYZ(): Empty instance.", - cimglist_instance); - - return _atNXYZ(pos,x,y,z,c); - } - - //! Access to pixel value with Neumann boundary conditions for the 4 first coordinates (\c pos, \c x,\c y,\c z) \const. - T atNXYZ(const int pos, const int x, const int y, const int z, const int c=0) const { - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "atNXYZ(): Empty instance.", - cimglist_instance); - - return _atNXYZ(pos,x,y,z,c); - } - - T& _atNXYZ(const int pos, const int x, const int y, const int z, const int c=0) { - return _data[pos<0?0:(pos>=(int)_width?(int)_width - 1:pos)].atXYZ(x,y,z,c); - } - - T _atNXYZ(const int pos, const int x, const int y, const int z, const int c=0) const { - return _data[pos<0?0:(pos>=(int)_width?(int)_width - 1:pos)].atXYZ(x,y,z,c); - } - - //! Access to pixel value with Dirichlet boundary conditions for the 3 first coordinates (\c pos, \c x,\c y). - /** - \param pos Indice of the image element to access. - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \param out_value Default value returned if \c offset is outside image bounds. - \note list.atNXYZ(p,x,y,z,c); is equivalent to list[p].atXYZ(x,y,z,c);. - **/ - T& atNXY(const int pos, const int x, const int y, const int z, const int c, const T& out_value) { - return (pos<0 || pos>=(int)_width)?(cimg::temporary(out_value)=out_value):_data[pos].atXY(x,y,z,c,out_value); - } - - //! Access to pixel value with Dirichlet boundary conditions for the 3 first coordinates (\c pos, \c x,\c y) \const. - T atNXY(const int pos, const int x, const int y, const int z, const int c, const T& out_value) const { - return (pos<0 || pos>=(int)_width)?out_value:_data[pos].atXY(x,y,z,c,out_value); - } - - //! Access to pixel value with Neumann boundary conditions for the 3 first coordinates (\c pos, \c x,\c y). - /** - \param pos Indice of the image element to access. - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \note list.atNXYZ(p,x,y,z,c); is equivalent to list[p].atXYZ(x,y,z,c);. - **/ - T& atNXY(const int pos, const int x, const int y, const int z=0, const int c=0) { - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "atNXY(): Empty instance.", - cimglist_instance); - - return _atNXY(pos,x,y,z,c); - } - - //! Access to pixel value with Neumann boundary conditions for the 3 first coordinates (\c pos, \c x,\c y) \const. - T atNXY(const int pos, const int x, const int y, const int z=0, const int c=0) const { - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "atNXY(): Empty instance.", - cimglist_instance); - - return _atNXY(pos,x,y,z,c); - } - - T& _atNXY(const int pos, const int x, const int y, const int z=0, const int c=0) { - return _data[pos<0?0:(pos>=(int)_width?(int)_width - 1:pos)].atXY(x,y,z,c); - } - - T _atNXY(const int pos, const int x, const int y, const int z=0, const int c=0) const { - return _data[pos<0?0:(pos>=(int)_width?(int)_width - 1:pos)].atXY(x,y,z,c); - } - - //! Access to pixel value with Dirichlet boundary conditions for the 2 first coordinates (\c pos,\c x). - /** - \param pos Indice of the image element to access. - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \param out_value Default value returned if \c offset is outside image bounds. - \note list.atNXYZ(p,x,y,z,c); is equivalent to list[p].atXYZ(x,y,z,c);. - **/ - T& atNX(const int pos, const int x, const int y, const int z, const int c, const T& out_value) { - return (pos<0 || pos>=(int)_width)?(cimg::temporary(out_value)=out_value):_data[pos].atX(x,y,z,c,out_value); - } - - //! Access to pixel value with Dirichlet boundary conditions for the 2 first coordinates (\c pos,\c x) \const. - T atNX(const int pos, const int x, const int y, const int z, const int c, const T& out_value) const { - return (pos<0 || pos>=(int)_width)?out_value:_data[pos].atX(x,y,z,c,out_value); - } - - //! Access to pixel value with Neumann boundary conditions for the 2 first coordinates (\c pos, \c x). - /** - \param pos Indice of the image element to access. - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \note list.atNXYZ(p,x,y,z,c); is equivalent to list[p].atXYZ(x,y,z,c);. - **/ - T& atNX(const int pos, const int x, const int y=0, const int z=0, const int c=0) { - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "atNX(): Empty instance.", - cimglist_instance); - - return _atNX(pos,x,y,z,c); - } - - //! Access to pixel value with Neumann boundary conditions for the 2 first coordinates (\c pos, \c x) \const. - T atNX(const int pos, const int x, const int y=0, const int z=0, const int c=0) const { - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "atNX(): Empty instance.", - cimglist_instance); - - return _atNX(pos,x,y,z,c); - } - - T& _atNX(const int pos, const int x, const int y=0, const int z=0, const int c=0) { - return _data[pos<0?0:(pos>=(int)_width?(int)_width - 1:pos)].atX(x,y,z,c); - } - - T _atNX(const int pos, const int x, const int y=0, const int z=0, const int c=0) const { - return _data[pos<0?0:(pos>=(int)_width?(int)_width - 1:pos)].atX(x,y,z,c); - } - - //! Access to pixel value with Dirichlet boundary conditions for the first coordinate (\c pos). - /** - \param pos Indice of the image element to access. - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \param out_value Default value returned if \c offset is outside image bounds. - \note list.atNXYZ(p,x,y,z,c); is equivalent to list[p].atXYZ(x,y,z,c);. - **/ - T& atN(const int pos, const int x, const int y, const int z, const int c, const T& out_value) { - return (pos<0 || pos>=(int)_width)?(cimg::temporary(out_value)=out_value):(*this)(pos,x,y,z,c); - } - - //! Access to pixel value with Dirichlet boundary conditions for the first coordinate (\c pos) \const. - T atN(const int pos, const int x, const int y, const int z, const int c, const T& out_value) const { - return (pos<0 || pos>=(int)_width)?out_value:(*this)(pos,x,y,z,c); - } - - //! Return pixel value with Neumann boundary conditions for the first coordinate (\c pos). - /** - \param pos Indice of the image element to access. - \param x X-coordinate of the pixel value. - \param y Y-coordinate of the pixel value. - \param z Z-coordinate of the pixel value. - \param c C-coordinate of the pixel value. - \note list.atNXYZ(p,x,y,z,c); is equivalent to list[p].atXYZ(x,y,z,c);. - **/ - T& atN(const int pos, const int x=0, const int y=0, const int z=0, const int c=0) { - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "atN(): Empty instance.", - cimglist_instance); - return _atN(pos,x,y,z,c); - } - - //! Return pixel value with Neumann boundary conditions for the first coordinate (\c pos) \const. - T atN(const int pos, const int x=0, const int y=0, const int z=0, const int c=0) const { - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "atN(): Empty instance.", - cimglist_instance); - return _atN(pos,x,y,z,c); - } - - T& _atN(const int pos, const int x=0, const int y=0, const int z=0, const int c=0) { - return _data[pos<0?0:(pos>=(int)_width?(int)_width - 1:pos)](x,y,z,c); - } - - T _atN(const int pos, const int x=0, const int y=0, const int z=0, const int c=0) const { - return _data[pos<0?0:(pos>=(int)_width?(int)_width - 1:pos)](x,y,z,c); - } - - //! Return a C-string containing the values of all images in the instance list. - /** - \param separator Character separator set between consecutive pixel values. - \param max_size Maximum size of the returned string. - \note The result is returne as a CImg image whose pixel buffer contains the desired C-string. - **/ - CImg value_string(const char separator=',', const unsigned int max_size=0) const { - if (is_empty()) return CImg(1,1,1,1,0); - CImgList items; - for (unsigned int l = 0; l<_width - 1; ++l) { - CImg item = _data[l].value_string(separator,0); - item.back() = separator; - item.move_to(items); - } - _data[_width - 1].value_string(separator,0).move_to(items); - CImg res; (items>'x').move_to(res); - if (max_size) { res.crop(0,max_size); res(max_size) = 0; } - return res; - } - - //@} - //------------------------------------- - // - //! \name Instance Checking - //@{ - //------------------------------------- - - //! Return \c true if list is empty. - /** - **/ - bool is_empty() const { - return (!_data || !_width); - } - - //! Test if number of image elements is equal to specified value. - /** - \param size_n Number of image elements to test. - **/ - bool is_sameN(const unsigned int size_n) const { - return _width==size_n; - } - - //! Test if number of image elements is equal between two images lists. - /** - \param list Input list to compare with. - **/ - template - bool is_sameN(const CImgList& list) const { - return is_sameN(list._width); - } - - // Define useful functions to check list dimensions. - // (cannot be documented because macro-generated). -#define _cimglist_def_is_same1(axis) \ - bool is_same##axis(const unsigned int val) const { \ - bool res = true; \ - for (unsigned int l = 0; l<_width && res; ++l) res = _data[l].is_same##axis(val); return res; \ - } \ - bool is_sameN##axis(const unsigned int n, const unsigned int val) const { \ - return is_sameN(n) && is_same##axis(val); \ - } \ - -#define _cimglist_def_is_same2(axis1,axis2) \ - bool is_same##axis1##axis2(const unsigned int val1, const unsigned int val2) const { \ - bool res = true; \ - for (unsigned int l = 0; l<_width && res; ++l) res = _data[l].is_same##axis1##axis2(val1,val2); return res; \ - } \ - bool is_sameN##axis1##axis2(const unsigned int n, const unsigned int val1, const unsigned int val2) const { \ - return is_sameN(n) && is_same##axis1##axis2(val1,val2); \ - } \ - -#define _cimglist_def_is_same3(axis1,axis2,axis3) \ - bool is_same##axis1##axis2##axis3(const unsigned int val1, const unsigned int val2, \ - const unsigned int val3) const { \ - bool res = true; \ - for (unsigned int l = 0; l<_width && res; ++l) res = _data[l].is_same##axis1##axis2##axis3(val1,val2,val3); \ - return res; \ - } \ - bool is_sameN##axis1##axis2##axis3(const unsigned int n, const unsigned int val1, \ - const unsigned int val2, const unsigned int val3) const { \ - return is_sameN(n) && is_same##axis1##axis2##axis3(val1,val2,val3); \ - } \ - -#define _cimglist_def_is_same(axis) \ - template bool is_same##axis(const CImg& img) const { \ - bool res = true; for (unsigned int l = 0; l<_width && res; ++l) res = _data[l].is_same##axis(img); return res; \ - } \ - template bool is_same##axis(const CImgList& list) const { \ - const unsigned int lmin = cimg::min(_width,list._width); \ - bool res = true; for (unsigned int l = 0; l bool is_sameN##axis(const unsigned int n, const CImg& img) const { \ - return (is_sameN(n) && is_same##axis(img)); \ - } \ - template bool is_sameN##axis(const CImgList& list) const { \ - return (is_sameN(list) && is_same##axis(list)); \ - } - - _cimglist_def_is_same(XY) - _cimglist_def_is_same(XZ) - _cimglist_def_is_same(XC) - _cimglist_def_is_same(YZ) - _cimglist_def_is_same(YC) - _cimglist_def_is_same(XYZ) - _cimglist_def_is_same(XYC) - _cimglist_def_is_same(YZC) - _cimglist_def_is_same(XYZC) - _cimglist_def_is_same1(X) - _cimglist_def_is_same1(Y) - _cimglist_def_is_same1(Z) - _cimglist_def_is_same1(C) - _cimglist_def_is_same2(X,Y) - _cimglist_def_is_same2(X,Z) - _cimglist_def_is_same2(X,C) - _cimglist_def_is_same2(Y,Z) - _cimglist_def_is_same2(Y,C) - _cimglist_def_is_same2(Z,C) - _cimglist_def_is_same3(X,Y,Z) - _cimglist_def_is_same3(X,Y,C) - _cimglist_def_is_same3(X,Z,C) - _cimglist_def_is_same3(Y,Z,C) - - //! Test if dimensions of each image of the list match specified arguments. - /** - \param dx Checked image width. - \param dy Checked image height. - \param dz Checked image depth. - \param dc Checked image spectrum. - **/ - bool is_sameXYZC(const unsigned int dx, const unsigned int dy, - const unsigned int dz, const unsigned int dc) const { - bool res = true; - for (unsigned int l = 0; l<_width && res; ++l) res = _data[l].is_sameXYZC(dx,dy,dz,dc); - return res; - } - - //! Test if list dimensions match specified arguments. - /** - \param n Number of images in the list. - \param dx Checked image width. - \param dy Checked image height. - \param dz Checked image depth. - \param dc Checked image spectrum. - **/ - bool is_sameNXYZC(const unsigned int n, - const unsigned int dx, const unsigned int dy, - const unsigned int dz, const unsigned int dc) const { - return is_sameN(n) && is_sameXYZC(dx,dy,dz,dc); - } - - //! Test if list contains one particular pixel location. - /** - \param n Index of the image whom checked pixel value belong to. - \param x X-coordinate of the checked pixel value. - \param y Y-coordinate of the checked pixel value. - \param z Z-coordinate of the checked pixel value. - \param c C-coordinate of the checked pixel value. - **/ - bool containsNXYZC(const int n, const int x=0, const int y=0, const int z=0, const int c=0) const { - if (is_empty()) return false; - return n>=0 && n<(int)_width && x>=0 && x<_data[n].width() && y>=0 && y<_data[n].height() && - z>=0 && z<_data[n].depth() && c>=0 && c<_data[n].spectrum(); - } - - //! Test if list contains image with specified indice. - /** - \param n Index of the checked image. - **/ - bool containsN(const int n) const { - if (is_empty()) return false; - return n>=0 && n<(int)_width; - } - - //! Test if one image of the list contains the specified referenced value. - /** - \param pixel Reference to pixel value to test. - \param[out] n Index of image containing the pixel value, if test succeeds. - \param[out] x X-coordinate of the pixel value, if test succeeds. - \param[out] y Y-coordinate of the pixel value, if test succeeds. - \param[out] z Z-coordinate of the pixel value, if test succeeds. - \param[out] c C-coordinate of the pixel value, if test succeeds. - \note If true, set coordinates (n,x,y,z,c). - **/ - template - bool contains(const T& pixel, t& n, t& x, t&y, t& z, t& c) const { - if (is_empty()) return false; - cimglist_for(*this,l) if (_data[l].contains(pixel,x,y,z,c)) { n = (t)l; return true; } - return false; - } - - //! Test if one of the image list contains the specified referenced value. - /** - \param pixel Reference to pixel value to test. - \param[out] n Index of image containing the pixel value, if test succeeds. - \param[out] x X-coordinate of the pixel value, if test succeeds. - \param[out] y Y-coordinate of the pixel value, if test succeeds. - \param[out] z Z-coordinate of the pixel value, if test succeeds. - \note If true, set coordinates (n,x,y,z). - **/ - template - bool contains(const T& pixel, t& n, t& x, t&y, t& z) const { - t c; - return contains(pixel,n,x,y,z,c); - } - - //! Test if one of the image list contains the specified referenced value. - /** - \param pixel Reference to pixel value to test. - \param[out] n Index of image containing the pixel value, if test succeeds. - \param[out] x X-coordinate of the pixel value, if test succeeds. - \param[out] y Y-coordinate of the pixel value, if test succeeds. - \note If true, set coordinates (n,x,y). - **/ - template - bool contains(const T& pixel, t& n, t& x, t&y) const { - t z, c; - return contains(pixel,n,x,y,z,c); - } - - //! Test if one of the image list contains the specified referenced value. - /** - \param pixel Reference to pixel value to test. - \param[out] n Index of image containing the pixel value, if test succeeds. - \param[out] x X-coordinate of the pixel value, if test succeeds. - \note If true, set coordinates (n,x). - **/ - template - bool contains(const T& pixel, t& n, t& x) const { - t y, z, c; - return contains(pixel,n,x,y,z,c); - } - - //! Test if one of the image list contains the specified referenced value. - /** - \param pixel Reference to pixel value to test. - \param[out] n Index of image containing the pixel value, if test succeeds. - \note If true, set coordinates (n). - **/ - template - bool contains(const T& pixel, t& n) const { - t x, y, z, c; - return contains(pixel,n,x,y,z,c); - } - - //! Test if one of the image list contains the specified referenced value. - /** - \param pixel Reference to pixel value to test. - **/ - bool contains(const T& pixel) const { - unsigned int n, x, y, z, c; - return contains(pixel,n,x,y,z,c); - } - - //! Test if the list contains the image 'img'. - /** - \param img Reference to image to test. - \param[out] n Index of image in the list, if test succeeds. - \note If true, returns the position (n) of the image in the list. - **/ - template - bool contains(const CImg& img, t& n) const { - if (is_empty()) return false; - const CImg *const ptr = &img; - cimglist_for(*this,i) if (_data + i==ptr) { n = (t)i; return true; } - return false; - } - - //! Test if the list contains the image img. - /** - \param img Reference to image to test. - **/ - bool contains(const CImg& img) const { - unsigned int n; - return contains(img,n); - } - - //@} - //------------------------------------- - // - //! \name Mathematical Functions - //@{ - //------------------------------------- - - //! Return a reference to the minimum pixel value of the instance list. - /** - **/ - T& min() { - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "min(): Empty instance.", - cimglist_instance); - T *ptr_min = _data->_data; - T min_value = *ptr_min; - cimglist_for(*this,l) { - const CImg& img = _data[l]; - cimg_for(img,ptrs,T) if (*ptrs_data; - T min_value = *ptr_min; - cimglist_for(*this,l) { - const CImg& img = _data[l]; - cimg_for(img,ptrs,T) if (*ptrs_data; - T max_value = *ptr_max; - cimglist_for(*this,l) { - const CImg& img = _data[l]; - cimg_for(img,ptrs,T) if (*ptrs>max_value) max_value = *(ptr_max=ptrs); - } - return *ptr_max; - } - - //! Return a reference to the maximum pixel value of the instance list \const. - const T& max() const { - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "max(): Empty instance.", - cimglist_instance); - const T *ptr_max = _data->_data; - T max_value = *ptr_max; - cimglist_for(*this,l) { - const CImg& img = _data[l]; - cimg_for(img,ptrs,T) if (*ptrs>max_value) max_value = *(ptr_max=ptrs); - } - return *ptr_max; - } - - //! Return a reference to the minimum pixel value of the instance list and return the maximum vvalue as well. - /** - \param[out] max_val Value of the maximum value found. - **/ - template - T& min_max(t& max_val) { - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "min_max(): Empty instance.", - cimglist_instance); - T *ptr_min = _data->_data; - T min_value = *ptr_min, max_value = min_value; - cimglist_for(*this,l) { - const CImg& img = _data[l]; - cimg_for(img,ptrs,T) { - const T val = *ptrs; - if (valmax_value) max_value = val; - } - } - max_val = (t)max_value; - return *ptr_min; - } - - //! Return a reference to the minimum pixel value of the instance list and return the maximum vvalue as well \const. - /** - \param[out] max_val Value of the maximum value found. - **/ - template - const T& min_max(t& max_val) const { - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "min_max(): Empty instance.", - cimglist_instance); - const T *ptr_min = _data->_data; - T min_value = *ptr_min, max_value = min_value; - cimglist_for(*this,l) { - const CImg& img = _data[l]; - cimg_for(img,ptrs,T) { - const T val = *ptrs; - if (valmax_value) max_value = val; - } - } - max_val = (t)max_value; - return *ptr_min; - } - - //! Return a reference to the minimum pixel value of the instance list and return the minimum value as well. - /** - \param[out] min_val Value of the minimum value found. - **/ - template - T& max_min(t& min_val) { - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "max_min(): Empty instance.", - cimglist_instance); - T *ptr_max = _data->_data; - T min_value = *ptr_max, max_value = min_value; - cimglist_for(*this,l) { - const CImg& img = _data[l]; - cimg_for(img,ptrs,T) { - const T val = *ptrs; - if (val>max_value) { max_value = val; ptr_max = ptrs; } - if (val - const T& max_min(t& min_val) const { - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "max_min(): Empty instance.", - cimglist_instance); - const T *ptr_max = _data->_data; - T min_value = *ptr_max, max_value = min_value; - cimglist_for(*this,l) { - const CImg& img = _data[l]; - cimg_for(img,ptrs,T) { - const T val = *ptrs; - if (val>max_value) { max_value = val; ptr_max = ptrs; } - if (val - CImgList& insert(const CImg& img, const unsigned int pos=~0U, const bool is_shared=false) { - const unsigned int npos = pos==~0U?_width:pos; - if (npos>_width) - throw CImgArgumentException(_cimglist_instance - "insert(): Invalid insertion request of specified image (%u,%u,%u,%u,%p) " - "at position %u.", - cimglist_instance, - img._width,img._height,img._depth,img._spectrum,img._data,npos); - if (is_shared) - throw CImgArgumentException(_cimglist_instance - "insert(): Invalid insertion request of specified shared image " - "CImg<%s>(%u,%u,%u,%u,%p) at position %u (pixel types are different).", - cimglist_instance, - img.pixel_type(),img._width,img._height,img._depth,img._spectrum,img._data,npos); - - CImg *const new_data = (++_width>_allocated_width)?new CImg[_allocated_width?(_allocated_width<<=1): - (_allocated_width=16)]:0; - if (!_data) { // Insert new element into empty list. - _data = new_data; - *_data = img; - } else { - if (new_data) { // Insert with re-allocation. - if (npos) std::memcpy(new_data,_data,sizeof(CImg)*npos); - if (npos!=_width - 1) std::memcpy(new_data + npos + 1,_data + npos,sizeof(CImg)*(_width - 1 - npos)); - std::memset(_data,0,sizeof(CImg)*(_width - 1)); - delete[] _data; - _data = new_data; - } else if (npos!=_width - 1) // Insert without re-allocation. - std::memmove(_data + npos + 1,_data + npos,sizeof(CImg)*(_width - 1 - npos)); - _data[npos]._width = _data[npos]._height = _data[npos]._depth = _data[npos]._spectrum = 0; - _data[npos]._data = 0; - _data[npos] = img; - } - return *this; - } - - //! Insert a copy of the image \c img into the current image list, at position \c pos \specialization. - CImgList& insert(const CImg& img, const unsigned int pos=~0U, const bool is_shared=false) { - const unsigned int npos = pos==~0U?_width:pos; - if (npos>_width) - throw CImgArgumentException(_cimglist_instance - "insert(): Invalid insertion request of specified image (%u,%u,%u,%u,%p) " - "at position %u.", - cimglist_instance, - img._width,img._height,img._depth,img._spectrum,img._data,npos); - CImg *const new_data = (++_width>_allocated_width)?new CImg[_allocated_width?(_allocated_width<<=1): - (_allocated_width=16)]:0; - if (!_data) { // Insert new element into empty list. - _data = new_data; - if (is_shared && img) { - _data->_width = img._width; - _data->_height = img._height; - _data->_depth = img._depth; - _data->_spectrum = img._spectrum; - _data->_is_shared = true; - _data->_data = img._data; - } else *_data = img; - } - else { - if (new_data) { // Insert with re-allocation. - if (npos) std::memcpy(new_data,_data,sizeof(CImg)*npos); - if (npos!=_width - 1) std::memcpy(new_data + npos + 1,_data + npos,sizeof(CImg)*(_width - 1 - npos)); - if (is_shared && img) { - new_data[npos]._width = img._width; - new_data[npos]._height = img._height; - new_data[npos]._depth = img._depth; - new_data[npos]._spectrum = img._spectrum; - new_data[npos]._is_shared = true; - new_data[npos]._data = img._data; - } else { - new_data[npos]._width = new_data[npos]._height = new_data[npos]._depth = new_data[npos]._spectrum = 0; - new_data[npos]._data = 0; - new_data[npos] = img; - } - std::memset(_data,0,sizeof(CImg)*(_width - 1)); - delete[] _data; - _data = new_data; - } else { // Insert without re-allocation. - if (npos!=_width - 1) std::memmove(_data + npos + 1,_data + npos,sizeof(CImg)*(_width - 1 - npos)); - if (is_shared && img) { - _data[npos]._width = img._width; - _data[npos]._height = img._height; - _data[npos]._depth = img._depth; - _data[npos]._spectrum = img._spectrum; - _data[npos]._is_shared = true; - _data[npos]._data = img._data; - } else { - _data[npos]._width = _data[npos]._height = _data[npos]._depth = _data[npos]._spectrum = 0; - _data[npos]._data = 0; - _data[npos] = img; - } - } - } - return *this; - } - - //! Insert a copy of the image \c img into the current image list, at position \c pos \newinstance. - template - CImgList get_insert(const CImg& img, const unsigned int pos=~0U, const bool is_shared=false) const { - return (+*this).insert(img,pos,is_shared); - } - - //! Insert n empty images img into the current image list, at position \p pos. - /** - \param n Number of empty images to insert. - \param pos Index of the insertion. - **/ - CImgList& insert(const unsigned int n, const unsigned int pos=~0U) { - CImg empty; - if (!n) return *this; - const unsigned int npos = pos==~0U?_width:pos; - for (unsigned int i = 0; i get_insert(const unsigned int n, const unsigned int pos=~0U) const { - return (+*this).insert(n,pos); - } - - //! Insert \c n copies of the image \c img into the current image list, at position \c pos. - /** - \param n Number of image copies to insert. - \param img Image to insert by copy. - \param pos Index of the insertion. - \param is_shared Tells if inserted images are shared copies of \c img or not. - **/ - template - CImgList& insert(const unsigned int n, const CImg& img, const unsigned int pos=~0U, - const bool is_shared=false) { - if (!n) return *this; - const unsigned int npos = pos==~0U?_width:pos; - insert(img,npos,is_shared); - for (unsigned int i = 1; i - CImgList get_insert(const unsigned int n, const CImg& img, const unsigned int pos=~0U, - const bool is_shared=false) const { - return (+*this).insert(n,img,pos,is_shared); - } - - //! Insert a copy of the image list \c list into the current image list, starting from position \c pos. - /** - \param list Image list to insert. - \param pos Index of the insertion. - \param is_shared Tells if inserted images are shared copies of images of \c list or not. - **/ - template - CImgList& insert(const CImgList& list, const unsigned int pos=~0U, const bool is_shared=false) { - const unsigned int npos = pos==~0U?_width:pos; - if ((void*)this!=(void*)&list) cimglist_for(list,l) insert(list[l],npos + l,is_shared); - else insert(CImgList(list),npos,is_shared); - return *this; - } - - //! Insert a copy of the image list \c list into the current image list, starting from position \c pos \newinstance. - template - CImgList get_insert(const CImgList& list, const unsigned int pos=~0U, const bool is_shared=false) const { - return (+*this).insert(list,pos,is_shared); - } - - //! Insert n copies of the list \c list at position \c pos of the current list. - /** - \param n Number of list copies to insert. - \param list Image list to insert. - \param pos Index of the insertion. - \param is_shared Tells if inserted images are shared copies of images of \c list or not. - **/ - template - CImgList& insert(const unsigned int n, const CImgList& list, const unsigned int pos=~0U, - const bool is_shared=false) { - if (!n) return *this; - const unsigned int npos = pos==~0U?_width:pos; - for (unsigned int i = 0; i - CImgList get_insert(const unsigned int n, const CImgList& list, const unsigned int pos=~0U, - const bool is_shared=false) const { - return (+*this).insert(n,list,pos,is_shared); - } - - //! Remove all images between from indexes. - /** - \param pos1 Starting index of the removal. - \param pos2 Ending index of the removal. - **/ - CImgList& remove(const unsigned int pos1, const unsigned int pos2) { - const unsigned int - npos1 = pos1=_width) - throw CImgArgumentException(_cimglist_instance - "remove(): Invalid remove request at positions %u->%u.", - cimglist_instance, - npos1,tpos2); - else { - if (tpos2>=_width) - throw CImgArgumentException(_cimglist_instance - "remove(): Invalid remove request at positions %u->%u.", - cimglist_instance, - npos1,tpos2); - - for (unsigned int k = npos1; k<=npos2; ++k) _data[k].assign(); - const unsigned int nb = 1 + npos2 - npos1; - if (!(_width-=nb)) return assign(); - if (_width>(_allocated_width>>2) || _allocated_width<=16) { // Removing items without reallocation. - if (npos1!=_width) std::memmove(_data + npos1,_data + npos2 + 1,sizeof(CImg)*(_width - npos1)); - std::memset(_data + _width,0,sizeof(CImg)*nb); - } else { // Removing items with reallocation. - _allocated_width>>=2; - while (_allocated_width>16 && _width<(_allocated_width>>1)) _allocated_width>>=1; - CImg *const new_data = new CImg[_allocated_width]; - if (npos1) std::memcpy(new_data,_data,sizeof(CImg)*npos1); - if (npos1!=_width) std::memcpy(new_data + npos1,_data + npos2 + 1,sizeof(CImg)*(_width - npos1)); - if (_width!=_allocated_width) std::memset(new_data + _width,0,sizeof(CImg)*(_allocated_width - _width)); - std::memset(_data,0,sizeof(CImg)*(_width + nb)); - delete[] _data; - _data = new_data; - } - } - return *this; - } - - //! Remove all images between from indexes \newinstance. - CImgList get_remove(const unsigned int pos1, const unsigned int pos2) const { - return (+*this).remove(pos1,pos2); - } - - //! Remove image at index \c pos from the image list. - /** - \param pos Index of the image to remove. - **/ - CImgList& remove(const unsigned int pos) { - return remove(pos,pos); - } - - //! Remove image at index \c pos from the image list \newinstance. - CImgList get_remove(const unsigned int pos) const { - return (+*this).remove(pos); - } - - //! Remove last image. - /** - **/ - CImgList& remove() { - return remove(_width - 1); - } - - //! Remove last image \newinstance. - CImgList get_remove() const { - return (+*this).remove(); - } - - //! Reverse list order. - CImgList& reverse() { - for (unsigned int l = 0; l<_width/2; ++l) (*this)[l].swap((*this)[_width - 1 - l]); - return *this; - } - - //! Reverse list order \newinstance. - CImgList get_reverse() const { - return (+*this).reverse(); - } - - //! Return a sublist. - /** - \param pos0 Starting index of the sublist. - \param pos1 Ending index of the sublist. - **/ - CImgList& images(const unsigned int pos0, const unsigned int pos1) { - return get_images(pos0,pos1).move_to(*this); - } - - //! Return a sublist \newinstance. - CImgList get_images(const unsigned int pos0, const unsigned int pos1) const { - if (pos0>pos1 || pos1>=_width) - throw CImgArgumentException(_cimglist_instance - "images(): Specified sub-list indices (%u->%u) are out of bounds.", - cimglist_instance, - pos0,pos1); - CImgList res(pos1 - pos0 + 1); - cimglist_for(res,l) res[l].assign(_data[pos0 + l]); - return res; - } - - //! Return a shared sublist. - /** - \param pos0 Starting index of the sublist. - \param pos1 Ending index of the sublist. - **/ - CImgList get_shared_images(const unsigned int pos0, const unsigned int pos1) { - if (pos0>pos1 || pos1>=_width) - throw CImgArgumentException(_cimglist_instance - "get_shared_images(): Specified sub-list indices (%u->%u) are out of bounds.", - cimglist_instance, - pos0,pos1); - CImgList res(pos1 - pos0 + 1); - cimglist_for(res,l) res[l].assign(_data[pos0 + l],_data[pos0 + l]?true:false); - return res; - } - - //! Return a shared sublist \newinstance. - const CImgList get_shared_images(const unsigned int pos0, const unsigned int pos1) const { - if (pos0>pos1 || pos1>=_width) - throw CImgArgumentException(_cimglist_instance - "get_shared_images(): Specified sub-list indices (%u->%u) are out of bounds.", - cimglist_instance, - pos0,pos1); - CImgList res(pos1 - pos0 + 1); - cimglist_for(res,l) res[l].assign(_data[pos0 + l],_data[pos0 + l]?true:false); - return res; - } - - //! Return a single image which is the appending of all images of the current CImgList instance. - /** - \param axis Appending axis. Can be { 'x' | 'y' | 'z' | 'c' }. - \param align Appending alignment. - **/ - CImg get_append(const char axis, const float align=0) const { - if (is_empty()) return CImg(); - if (_width==1) return +((*this)[0]); - unsigned int dx = 0, dy = 0, dz = 0, dc = 0, pos = 0; - CImg res; - switch (cimg::lowercase(axis)) { - case 'x' : { // Along the X-axis. - cimglist_for(*this,l) { - const CImg& img = (*this)[l]; - if (img) { - dx+=img._width; - dy = cimg::max(dy,img._height); - dz = cimg::max(dz,img._depth); - dc = cimg::max(dc,img._spectrum); - } - } - res.assign(dx,dy,dz,dc,0); - if (res) cimglist_for(*this,l) { - const CImg& img = (*this)[l]; - if (img) res.draw_image(pos, - (int)(align*(dy - img._height)), - (int)(align*(dz - img._depth)), - (int)(align*(dc - img._spectrum)), - img); - pos+=img._width; - } - } break; - case 'y' : { // Along the Y-axis. - cimglist_for(*this,l) { - const CImg& img = (*this)[l]; - if (img) { - dx = cimg::max(dx,img._width); - dy+=img._height; - dz = cimg::max(dz,img._depth); - dc = cimg::max(dc,img._spectrum); - } - } - res.assign(dx,dy,dz,dc,0); - if (res) cimglist_for(*this,l) { - const CImg& img = (*this)[l]; - if (img) res.draw_image((int)(align*(dx - img._width)), - pos, - (int)(align*(dz - img._depth)), - (int)(align*(dc - img._spectrum)), - img); - pos+=img._height; - } - } break; - case 'z' : { // Along the Z-axis. - cimglist_for(*this,l) { - const CImg& img = (*this)[l]; - if (img) { - dx = cimg::max(dx,img._width); - dy = cimg::max(dy,img._height); - dz+=img._depth; - dc = cimg::max(dc,img._spectrum); - } - } - res.assign(dx,dy,dz,dc,0); - if (res) cimglist_for(*this,l) { - const CImg& img = (*this)[l]; - if (img) res.draw_image((int)(align*(dx - img._width)), - (int)(align*(dy - img._height)), - pos, - (int)(align*(dc - img._spectrum)), - img); - pos+=img._depth; - } - } break; - default : { // Along the C-axis. - cimglist_for(*this,l) { - const CImg& img = (*this)[l]; - if (img) { - dx = cimg::max(dx,img._width); - dy = cimg::max(dy,img._height); - dz = cimg::max(dz,img._depth); - dc+=img._spectrum; - } - } - res.assign(dx,dy,dz,dc,0); - if (res) cimglist_for(*this,l) { - const CImg& img = (*this)[l]; - if (img) res.draw_image((int)(align*(dx - img._width)), - (int)(align*(dy - img._height)), - (int)(align*(dz - img._depth)), - pos, - img); - pos+=img._spectrum; - } - } - } - return res; - } - - //! Return a list where each image has been split along the specified axis. - /** - \param axis Axis to split images along. - \param nb Number of spliting parts for each image. - **/ - CImgList& split(const char axis, const int nb=-1) { - return get_split(axis,nb).move_to(*this); - } - - //! Return a list where each image has been split along the specified axis \newinstance. - CImgList get_split(const char axis, const int nb=-1) const { - CImgList res; - cimglist_for(*this,l) _data[l].get_split(axis,nb).move_to(res,~0U); - return res; - } - - //! Insert image at the end of the list. - /** - \param img Image to insert. - **/ - template - CImgList& push_back(const CImg& img) { - return insert(img); - } - - //! Insert image at the front of the list. - /** - \param img Image to insert. - **/ - template - CImgList& push_front(const CImg& img) { - return insert(img,0); - } - - //! Insert list at the end of the current list. - /** - \param list List to insert. - **/ - template - CImgList& push_back(const CImgList& list) { - return insert(list); - } - - //! Insert list at the front of the current list. - /** - \param list List to insert. - **/ - template - CImgList& push_front(const CImgList& list) { - return insert(list,0); - } - - //! Remove last image. - /** - **/ - CImgList& pop_back() { - return remove(_width - 1); - } - - //! Remove first image. - /** - **/ - CImgList& pop_front() { - return remove(0); - } - - //! Remove image pointed by iterator. - /** - \param iter Iterator pointing to the image to remove. - **/ - CImgList& erase(const iterator iter) { - return remove(iter - _data); - } - - //@} - //---------------------------------- - // - //! \name Data Input - //@{ - //---------------------------------- - - //! Display a simple interactive interface to select images or sublists. - /** - \param disp Window instance to display selection and user interface. - \param feature_type Can be \c false to select a single image, or \c true to select a sublist. - \param axis Axis along whom images are appended for visualization. - \param align Alignment setting when images have not all the same size. - \return A one-column vector containing the selected image indexes. - **/ - CImg get_select(CImgDisplay &disp, const bool feature_type=true, - const char axis='x', const float align=0, - const bool exit_on_anykey=false) const { - return _get_select(disp,0,feature_type,axis,align,exit_on_anykey,0,false,false,false); - } - - //! Display a simple interactive interface to select images or sublists. - /** - \param title Title of a new window used to display selection and user interface. - \param feature_type Can be \c false to select a single image, or \c true to select a sublist. - \param axis Axis along whom images are appended for visualization. - \param align Alignment setting when images have not all the same size. - \return A one-column vector containing the selected image indexes. - **/ - CImg get_select(const char *const title, const bool feature_type=true, - const char axis='x', const float align=0, - const bool exit_on_anykey=false) const { - CImgDisplay disp; - return _get_select(disp,title,feature_type,axis,align,exit_on_anykey,0,false,false,false); - } - - CImg _get_select(CImgDisplay &disp, const char *const title, const bool feature_type, - const char axis, const float align, const bool exit_on_anykey, - const unsigned int orig, const bool resize_disp, - const bool exit_on_rightbutton, const bool exit_on_wheel) const { - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "select(): Empty instance.", - cimglist_instance); - - // Create image correspondence table and get list dimensions for visualization. - CImgList _indices; - unsigned int max_width = 0, max_height = 0, sum_width = 0, sum_height = 0; - cimglist_for(*this,l) { - const CImg& img = _data[l]; - const unsigned int - w = CImgDisplay::_fitscreen(img._width,img._height,img._depth,128,-85,false), - h = CImgDisplay::_fitscreen(img._width,img._height,img._depth,128,-85,true); - if (w>max_width) max_width = w; - if (h>max_height) max_height = h; - sum_width+=w; sum_height+=h; - if (axis=='x') CImg(w,1,1,1,(unsigned int)l).move_to(_indices); - else CImg(h,1,1,1,(unsigned int)l).move_to(_indices); - } - const CImg indices0 = _indices>'x'; - - // Create display window. - if (!disp) { - if (axis=='x') disp.assign(cimg_fitscreen(sum_width,max_height,1),title?title:0,1); - else disp.assign(cimg_fitscreen(max_width,sum_height,1),title?title:0,1); - if (!title) disp.set_title("CImgList<%s> (%u)",pixel_type(),_width); - } else if (title) disp.set_title("%s",title); - if (resize_disp) { - if (axis=='x') disp.resize(cimg_fitscreen(sum_width,max_height,1),false); - else disp.resize(cimg_fitscreen(max_width,sum_height,1),false); - } - - const unsigned int old_normalization = disp.normalization(); - bool old_is_resized = disp.is_resized(); - disp._normalization = 0; - disp.show().set_key(0); - static const unsigned char foreground_color[] = { 255,255,255 }, background_color[] = { 0,0,0 }; - - // Enter event loop. - CImg visu0, visu; - CImg indices; - CImg positions(_width,4,1,1,-1); - int oindice0 = -1, oindice1 = -1, indice0 = -1, indice1 = -1; - bool is_clicked = false, is_selected = false, text_down = false, update_display = true; - unsigned int key = 0; - - while (!is_selected && !disp.is_closed() && !key) { - - // Create background image. - if (!visu0) { - visu0.assign(disp._width,disp._height,1,3,0); visu.assign(); - (indices0.get_resize(axis=='x'?visu0._width:visu0._height,1)).move_to(indices); - unsigned int ind = 0; - if (axis=='x') for (unsigned int x = 0; x - onexone(1,1,1,1,0), - &src = _data[ind]?_data[ind]:onexone; - CImg res; - src.__get_select(disp,old_normalization,(src._width - 1)/2,(src._height - 1)/2,(src._depth - 1)/2). - move_to(res); - const unsigned int h = CImgDisplay::_fitscreen(res._width,res._height,1,128,-85,true); - res.resize(x - x0,cimg::max(32U,h*disp._height/max_height),1,res._spectrum==1?3:-100); - positions(ind,0) = positions(ind,2) = (int)x0; - positions(ind,1) = positions(ind,3) = (int)(align*(visu0.height() - res.height())); - positions(ind,2)+=res._width; - positions(ind,3)+=res._height - 1; - visu0.draw_image(positions(ind,0),positions(ind,1),res); - } else for (unsigned int y = 0; y &src = _data[ind]; - const CImg - img2d = src._depth>1?src.get_projections2d((src._width - 1)/2,(src._height - 1)/2,(src._depth - 1)/2): - cimg::type::string()==cimg::type::string()?src.get_shared():src; - CImg res = old_normalization==1 || - (old_normalization==3 && cimg::type::string()!=cimg::type::string())? - CImg(img2d.get_normalize(0,255)): - CImg(img2d); - if (res._spectrum>3) res.channels(0,2); - const unsigned int w = CImgDisplay::_fitscreen(res._width,res._height,1,128,-85,false); - res.resize(cimg::max(32U,w*disp._width/max_width),y - y0,1,res._spectrum==1?3:-100); - positions(ind,0) = positions(ind,2) = (int)(align*(visu0.width() - res.width())); - positions(ind,1) = positions(ind,3) = (int)y0; - positions(ind,2)+=res._width - 1; - positions(ind,3)+=res._height; - visu0.draw_image(positions(ind,0),positions(ind,1),res); - } - if (axis=='x') --positions(ind,2); else --positions(ind,3); - update_display = true; - } - - if (!visu || oindice0!=indice0 || oindice1!=indice1) { - if (indice0>=0 && indice1>=0) { - visu.assign(visu0,false); - const int indm = cimg::min(indice0,indice1), indM = cimg::max(indice0,indice1); - for (int ind = indm; ind<=indM; ++ind) if (positions(ind,0)>=0) { - visu.draw_rectangle(positions(ind,0),positions(ind,1),positions(ind,2),positions(ind,3), - background_color,0.2f); - if ((axis=='x' && positions(ind,2) - positions(ind,0)>=8) || - (axis!='x' && positions(ind,3) - positions(ind,1)>=8)) - visu.draw_rectangle(positions(ind,0),positions(ind,1),positions(ind,2),positions(ind,3), - foreground_color,0.9f,0xAAAAAAAA); - } - const int yt = (int)text_down?visu.height() - 13:0; - if (is_clicked) visu.draw_text(0,yt," Images #%u - #%u, Size = %u", - foreground_color,background_color,0.7f,13, - orig + indm,orig + indM,indM - indm + 1); - else visu.draw_text(0,yt," Image #%u (%u,%u,%u,%u)",foreground_color,background_color,0.7f,13, - orig + indice0, - _data[indice0]._width, - _data[indice0]._height, - _data[indice0]._depth, - _data[indice0]._spectrum); - update_display = true; - } else visu.assign(); - } - if (!visu) { visu.assign(visu0,true); update_display = true; } - if (update_display) { visu.display(disp); update_display = false; } - disp.wait(); - - // Manage user events. - const int xm = disp.mouse_x(), ym = disp.mouse_y(); - int indice = -1; - - if (xm>=0) { - indice = (int)indices(axis=='x'?xm:ym); - if (disp.button()&1) { - if (!is_clicked) { is_clicked = true; oindice0 = indice0; indice0 = indice; } - oindice1 = indice1; indice1 = indice; - if (!feature_type) is_selected = true; - } else { - if (!is_clicked) { oindice0 = oindice1 = indice0; indice0 = indice1 = indice; } - else is_selected = true; - } - } else { - if (is_clicked) { - if (!(disp.button()&1)) { is_clicked = is_selected = false; indice0 = indice1 = -1; } - else indice1 = -1; - } else indice0 = indice1 = -1; - } - - if (disp.button()&4) { is_clicked = is_selected = false; indice0 = indice1 = -1; } - if (disp.button()&2 && exit_on_rightbutton) { is_selected = true; indice1 = indice0 = -1; } - if (disp.wheel() && exit_on_wheel) is_selected = true; - - CImg filename(32); - switch (key = disp.key()) { -#if cimg_OS!=2 - case cimg::keyCTRLRIGHT : -#endif - case 0 : case cimg::keyCTRLLEFT : key = 0; break; - case cimg::keyD : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - disp.set_fullscreen(false). - resize(CImgDisplay::_fitscreen(3*disp.width()/2,3*disp.height()/2,1,128,-100,false), - CImgDisplay::_fitscreen(3*disp.width()/2,3*disp.height()/2,1,128,-100,true),false). - _is_resized = true; - disp.set_key(key,false); key = 0; visu0.assign(); - } break; - case cimg::keyC : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - disp.set_fullscreen(false). - resize(cimg_fitscreen(2*disp.width()/3,2*disp.height()/3,1),false)._is_resized = true; - disp.set_key(key,false); key = 0; visu0.assign(); - } break; - case cimg::keyR : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - disp.set_fullscreen(false). - resize(cimg_fitscreen(axis=='x'?sum_width:max_width,axis=='x'?max_height:sum_height,1),false). - _is_resized = true; - disp.set_key(key,false); key = 0; visu0.assign(); - } break; - case cimg::keyF : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - disp.resize(disp.screen_width(),disp.screen_height(),false).toggle_fullscreen()._is_resized = true; - disp.set_key(key,false); key = 0; visu0.assign(); - } break; - case cimg::keyS : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - static unsigned int snap_number = 0; - std::FILE *file; - do { - cimg_snprintf(filename,filename._width,cimg_appname "_%.4u.bmp",snap_number++); - if ((file=std_fopen(filename,"r"))!=0) cimg::fclose(file); - } while (file); - if (visu0) { - (+visu0).draw_text(0,0," Saving snapshot... ", - foreground_color,background_color,0.7f,13).display(disp); - visu0.save(filename); - (+visu0).draw_text(0,0," Snapshot '%s' saved. ", - foreground_color,background_color,0.7f,13,filename._data).display(disp); - } - disp.set_key(key,false).wait(); key = 0; - } break; - case cimg::keyO : - if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { - static unsigned int snap_number = 0; - std::FILE *file; - do { -#ifdef cimg_use_zlib - cimg_snprintf(filename,filename._width,cimg_appname "_%.4u.cimgz",snap_number++); -#else - cimg_snprintf(filename,filename._width,cimg_appname "_%.4u.cimg",snap_number++); -#endif - if ((file=std_fopen(filename,"r"))!=0) cimg::fclose(file); - } while (file); - (+visu0).draw_text(0,0," Saving instance... ", - foreground_color,background_color,0.7f,13).display(disp); - save(filename); - (+visu0).draw_text(0,0," Instance '%s' saved. ", - foreground_color,background_color,0.7f,13,filename._data).display(disp); - disp.set_key(key,false).wait(); key = 0; - } break; - } - if (disp.is_resized()) { disp.resize(false); visu0.assign(); } - if (ym>=0 && ym<13) { if (!text_down) { visu.assign(); text_down = true; }} - else if (ym>=visu.height() - 13) { if(text_down) { visu.assign(); text_down = false; }} - if (!exit_on_anykey && key && key!=cimg::keyESC && - (key!=cimg::keyW || (!disp.is_keyCTRLLEFT() && !disp.is_keyCTRLRIGHT()))) { - key = 0; - } - } - CImg res(1,2,1,1,-1); - if (is_selected) { - if (feature_type) res.fill(cimg::min(indice0,indice1),cimg::max(indice0,indice1)); - else res.fill(indice0); - } - if (!(disp.button()&2)) disp.set_button(); - disp._normalization = old_normalization; - disp._is_resized = old_is_resized; - disp.set_key(key); - return res; - } - - //! Load a list from a file. - /** - \param filename Filename to read data from. - **/ - CImgList& load(const char *const filename) { - if (!filename) - throw CImgArgumentException(_cimglist_instance - "load(): Specified filename is (null).", - cimglist_instance); - - if (!cimg::strncasecmp(filename,"http://",7) || !cimg::strncasecmp(filename,"https://",8)) { - CImg filename_local(256); - load(cimg::load_network(filename,filename_local)); - std::remove(filename_local); - return *this; - } - - const bool is_stdin = *filename=='-' && (!filename[1] || filename[1]=='.'); - const char *const ext = cimg::split_filename(filename); - const unsigned int omode = cimg::exception_mode(); - cimg::exception_mode(0); - try { -#ifdef cimglist_load_plugin - cimglist_load_plugin(filename); -#endif -#ifdef cimglist_load_plugin1 - cimglist_load_plugin1(filename); -#endif -#ifdef cimglist_load_plugin2 - cimglist_load_plugin2(filename); -#endif -#ifdef cimglist_load_plugin3 - cimglist_load_plugin3(filename); -#endif -#ifdef cimglist_load_plugin4 - cimglist_load_plugin4(filename); -#endif -#ifdef cimglist_load_plugin5 - cimglist_load_plugin5(filename); -#endif -#ifdef cimglist_load_plugin6 - cimglist_load_plugin6(filename); -#endif -#ifdef cimglist_load_plugin7 - cimglist_load_plugin7(filename); -#endif -#ifdef cimglist_load_plugin8 - cimglist_load_plugin8(filename); -#endif - if (!cimg::strcasecmp(ext,"tif") || - !cimg::strcasecmp(ext,"tiff")) load_tiff(filename); - else if (!cimg::strcasecmp(ext,"gif")) load_gif_external(filename); - else if (!cimg::strcasecmp(ext,"cimg") || - !cimg::strcasecmp(ext,"cimgz") || - !*ext) load_cimg(filename); - else if (!cimg::strcasecmp(ext,"rec") || - !cimg::strcasecmp(ext,"par")) load_parrec(filename); - else if (!cimg::strcasecmp(ext,"avi") || - !cimg::strcasecmp(ext,"mov") || - !cimg::strcasecmp(ext,"asf") || - !cimg::strcasecmp(ext,"divx") || - !cimg::strcasecmp(ext,"flv") || - !cimg::strcasecmp(ext,"mpg") || - !cimg::strcasecmp(ext,"m1v") || - !cimg::strcasecmp(ext,"m2v") || - !cimg::strcasecmp(ext,"m4v") || - !cimg::strcasecmp(ext,"mjp") || - !cimg::strcasecmp(ext,"mp4") || - !cimg::strcasecmp(ext,"mkv") || - !cimg::strcasecmp(ext,"mpe") || - !cimg::strcasecmp(ext,"movie") || - !cimg::strcasecmp(ext,"ogm") || - !cimg::strcasecmp(ext,"ogg") || - !cimg::strcasecmp(ext,"ogv") || - !cimg::strcasecmp(ext,"qt") || - !cimg::strcasecmp(ext,"rm") || - !cimg::strcasecmp(ext,"vob") || - !cimg::strcasecmp(ext,"wmv") || - !cimg::strcasecmp(ext,"xvid") || - !cimg::strcasecmp(ext,"mpeg")) load_video(filename); - else if (!cimg::strcasecmp(ext,"gz")) load_gzip_external(filename); - else throw CImgIOException("CImgList<%s>::load()", - pixel_type()); - } catch (CImgIOException&) { - std::FILE *file = 0; - if (!is_stdin) try { - file = cimg::fopen(filename,"rb"); - } catch (CImgIOException&) { - cimg::exception_mode(omode); - throw CImgIOException(_cimglist_instance - "load(): Failed to open file '%s'.", - cimglist_instance, - filename); - } - - try { - if (!is_stdin) { - const char *const f_type = cimg::ftype(file,filename); - std::fclose(file); - if (!cimg::strcasecmp(f_type,"gif")) load_gif_external(filename); - else if (!cimg::strcasecmp(f_type,"tif")) load_tiff(filename); - else throw CImgIOException("CImgList<%s>::load()", - pixel_type()); - } else throw CImgIOException("CImgList<%s>::load()", - pixel_type()); - } catch (CImgIOException&) { - assign(1); - try { - _data->load(filename); - } catch (CImgIOException&) { - cimg::exception_mode(omode); - throw CImgIOException(_cimglist_instance - "load(): Failed to recognize format of file '%s'.", - cimglist_instance, - filename); - } - } - } - cimg::exception_mode(omode); - return *this; - } - - //! Load a list from a file \newinstance. - static CImgList get_load(const char *const filename) { - return CImgList().load(filename); - } - - //! Load a list from a .cimg file. - /** - \param filename Filename to read data from. - **/ - CImgList& load_cimg(const char *const filename) { - return _load_cimg(0,filename); - } - - //! Load a list from a .cimg file \newinstance. - static CImgList get_load_cimg(const char *const filename) { - return CImgList().load_cimg(filename); - } - - //! Load a list from a .cimg file. - /** - \param file File to read data from. - **/ - CImgList& load_cimg(std::FILE *const file) { - return _load_cimg(file,0); - } - - //! Load a list from a .cimg file \newinstance. - static CImgList get_load_cimg(std::FILE *const file) { - return CImgList().load_cimg(file); - } - - CImgList& _load_cimg(std::FILE *const file, const char *const filename) { -#ifdef cimg_use_zlib -#define _cimgz_load_cimg_case(Tss) { \ - Bytef *const cbuf = new Bytef[csiz]; \ - cimg::fread(cbuf,csiz,nfile); \ - raw.assign(W,H,D,C); \ - uLongf destlen = (ulongT)raw.size()*sizeof(Tss); \ - uncompress((Bytef*)raw._data,&destlen,cbuf,csiz); \ - delete[] cbuf; \ - if (endian!=cimg::endianness()) cimg::invert_endianness(raw._data,raw.size()); \ - raw.move_to(img); \ -} -#else -#define _cimgz_load_cimg_case(Tss) \ - throw CImgIOException(_cimglist_instance \ - "load_cimg(): Unable to load compressed data from file '%s' unless zlib is enabled.", \ - cimglist_instance, \ - filename?filename:"(FILE*)"); -#endif - -#define _cimg_load_cimg_case(Ts,Tss) \ - if (!loaded && !cimg::strcasecmp(Ts,str_pixeltype)) { \ - for (unsigned int l = 0; l=0 && j<255) tmp[j++] = (char)i; tmp[j] = 0; \ - W = H = D = C = 0; csiz = 0; \ - if ((err = cimg_sscanf(tmp,"%u %u %u %u #%lu",&W,&H,&D,&C,&csiz))<4) \ - throw CImgIOException(_cimglist_instance \ - "load_cimg(): Invalid specified size (%u,%u,%u,%u) of image %u in file '%s'.", \ - cimglist_instance, \ - W,H,D,C,l,filename?filename:("(FILE*)")); \ - if (W*H*D*C>0) { \ - CImg raw; \ - CImg &img = _data[l]; \ - if (err==5) _cimgz_load_cimg_case(Tss) \ - else { \ - img.assign(W,H,D,C); \ - T *ptrd = img._data; \ - for (ulongT to_read = img.size(); to_read; ) { \ - raw.assign((unsigned int)cimg::min(to_read,cimg_iobuffer)); \ - cimg::fread(raw._data,raw._width,nfile); \ - if (endian!=cimg::endianness()) cimg::invert_endianness(raw._data,raw.size()); \ - const Tss *ptrs = raw._data; \ - for (ulongT off = (ulongT)raw._width; off; --off) *(ptrd++) = (T)*(ptrs++); \ - to_read-=raw._width; \ - } \ - } \ - } \ - } \ - loaded = true; \ - } - - if (!filename && !file) - throw CImgArgumentException(_cimglist_instance - "load_cimg(): Specified filename is (null).", - cimglist_instance); - - const ulongT cimg_iobuffer = (ulongT)24*1024*1024; - std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); - bool loaded = false, endian = cimg::endianness(); - CImg tmp(256), str_pixeltype(256), str_endian(256); - *tmp = *str_pixeltype = *str_endian = 0; - unsigned int j, N = 0, W, H, D, C; - ulongT csiz; - int i, err; - do { - j = 0; while ((i=std::fgetc(nfile))!='\n' && i>=0 && j<255) tmp[j++] = (char)i; tmp[j] = 0; - } while (*tmp=='#' && i>=0); - err = cimg_sscanf(tmp,"%u%*c%255[A-Za-z64_]%*c%255[sA-Za-z_ ]", - &N,str_pixeltype._data,str_endian._data); - if (err<2) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimglist_instance - "load_cimg(): CImg header not found in file '%s'.", - cimglist_instance, - filename?filename:"(FILE*)"); - } - if (!cimg::strncasecmp("little",str_endian,6)) endian = false; - else if (!cimg::strncasecmp("big",str_endian,3)) endian = true; - assign(N); - _cimg_load_cimg_case("bool",bool); - _cimg_load_cimg_case("unsigned_char",unsigned char); - _cimg_load_cimg_case("uchar",unsigned char); - _cimg_load_cimg_case("char",char); - _cimg_load_cimg_case("unsigned_short",unsigned short); - _cimg_load_cimg_case("ushort",unsigned short); - _cimg_load_cimg_case("short",short); - _cimg_load_cimg_case("unsigned_int",unsigned int); - _cimg_load_cimg_case("uint",unsigned int); - _cimg_load_cimg_case("int",int); - _cimg_load_cimg_case("unsigned_long",ulongT); - _cimg_load_cimg_case("ulong",ulongT); - _cimg_load_cimg_case("long",longT); - _cimg_load_cimg_case("unsigned_int64",uint64T); - _cimg_load_cimg_case("uint64",uint64T); - _cimg_load_cimg_case("int64",int64T); - _cimg_load_cimg_case("float",float); - _cimg_load_cimg_case("double",double); - - if (!loaded) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimglist_instance - "load_cimg(): Unsupported pixel type '%s' for file '%s'.", - cimglist_instance, - str_pixeltype._data,filename?filename:"(FILE*)"); - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Load a sublist list from a (non compressed) .cimg file. - /** - \param filename Filename to read data from. - \param n0 Starting index of images to read (~0U for max). - \param n1 Ending index of images to read (~0U for max). - \param x0 Starting X-coordinates of image regions to read. - \param y0 Starting Y-coordinates of image regions to read. - \param z0 Starting Z-coordinates of image regions to read. - \param c0 Starting C-coordinates of image regions to read. - \param x1 Ending X-coordinates of image regions to read (~0U for max). - \param y1 Ending Y-coordinates of image regions to read (~0U for max). - \param z1 Ending Z-coordinates of image regions to read (~0U for max). - \param c1 Ending C-coordinates of image regions to read (~0U for max). - **/ - CImgList& load_cimg(const char *const filename, - const unsigned int n0, const unsigned int n1, - const unsigned int x0, const unsigned int y0, - const unsigned int z0, const unsigned int c0, - const unsigned int x1, const unsigned int y1, - const unsigned int z1, const unsigned int c1) { - return _load_cimg(0,filename,n0,n1,x0,y0,z0,c0,x1,y1,z1,c1); - } - - //! Load a sublist list from a (non compressed) .cimg file \newinstance. - static CImgList get_load_cimg(const char *const filename, - const unsigned int n0, const unsigned int n1, - const unsigned int x0, const unsigned int y0, - const unsigned int z0, const unsigned int c0, - const unsigned int x1, const unsigned int y1, - const unsigned int z1, const unsigned int c1) { - return CImgList().load_cimg(filename,n0,n1,x0,y0,z0,c0,x1,y1,z1,c1); - } - - //! Load a sub-image list from a (non compressed) .cimg file \overloading. - CImgList& load_cimg(std::FILE *const file, - const unsigned int n0, const unsigned int n1, - const unsigned int x0, const unsigned int y0, - const unsigned int z0, const unsigned int c0, - const unsigned int x1, const unsigned int y1, - const unsigned int z1, const unsigned int c1) { - return _load_cimg(file,0,n0,n1,x0,y0,z0,c0,x1,y1,z1,c1); - } - - //! Load a sub-image list from a (non compressed) .cimg file \newinstance. - static CImgList get_load_cimg(std::FILE *const file, - const unsigned int n0, const unsigned int n1, - const unsigned int x0, const unsigned int y0, - const unsigned int z0, const unsigned int c0, - const unsigned int x1, const unsigned int y1, - const unsigned int z1, const unsigned int c1) { - return CImgList().load_cimg(file,n0,n1,x0,y0,z0,c0,x1,y1,z1,c1); - } - - CImgList& _load_cimg(std::FILE *const file, const char *const filename, - const unsigned int n0, const unsigned int n1, - const unsigned int x0, const unsigned int y0, - const unsigned int z0, const unsigned int c0, - const unsigned int x1, const unsigned int y1, - const unsigned int z1, const unsigned int c1) { -#define _cimg_load_cimg_case2(Ts,Tss) \ - if (!loaded && !cimg::strcasecmp(Ts,str_pixeltype)) { \ - for (unsigned int l = 0; l<=nn1; ++l) { \ - j = 0; while ((i=std::fgetc(nfile))!='\n' && i>=0) tmp[j++] = (char)i; tmp[j] = 0; \ - W = H = D = C = 0; \ - if (cimg_sscanf(tmp,"%u %u %u %u",&W,&H,&D,&C)!=4) \ - throw CImgIOException(_cimglist_instance \ - "load_cimg(): Invalid specified size (%u,%u,%u,%u) of image %u in file '%s'", \ - cimglist_instance, \ - W,H,D,C,l,filename?filename:"(FILE*)"); \ - if (W*H*D*C>0) { \ - if (l=W || ny0>=H || nz0>=D || nc0>=C) cimg::fseek(nfile,W*H*D*C*sizeof(Tss),SEEK_CUR); \ - else { \ - const unsigned int \ - _nx1 = nx1==~0U?W - 1:nx1, \ - _ny1 = ny1==~0U?H - 1:ny1, \ - _nz1 = nz1==~0U?D - 1:nz1, \ - _nc1 = nc1==~0U?C - 1:nc1; \ - if (_nx1>=W || _ny1>=H || _nz1>=D || _nc1>=C) \ - throw CImgArgumentException(_cimglist_instance \ - "load_cimg(): Invalid specified coordinates " \ - "[%u](%u,%u,%u,%u) -> [%u](%u,%u,%u,%u) " \ - "because image [%u] in file '%s' has size (%u,%u,%u,%u).", \ - cimglist_instance, \ - n0,x0,y0,z0,c0,n1,x1,y1,z1,c1,l,filename?filename:"(FILE*)",W,H,D,C); \ - CImg raw(1 + _nx1 - nx0); \ - CImg &img = _data[l - nn0]; \ - img.assign(1 + _nx1 - nx0,1 + _ny1 - ny0,1 + _nz1 - nz0,1 + _nc1 - nc0); \ - T *ptrd = img._data; \ - ulongT skipvb = nc0*W*H*D*sizeof(Tss); \ - if (skipvb) cimg::fseek(nfile,skipvb,SEEK_CUR); \ - for (unsigned int c = 1 + _nc1 - nc0; c; --c) { \ - const ulongT skipzb = nz0*W*H*sizeof(Tss); \ - if (skipzb) cimg::fseek(nfile,skipzb,SEEK_CUR); \ - for (unsigned int z = 1 + _nz1 - nz0; z; --z) { \ - const ulongT skipyb = ny0*W*sizeof(Tss); \ - if (skipyb) cimg::fseek(nfile,skipyb,SEEK_CUR); \ - for (unsigned int y = 1 + _ny1 - ny0; y; --y) { \ - const ulongT skipxb = nx0*sizeof(Tss); \ - if (skipxb) cimg::fseek(nfile,skipxb,SEEK_CUR); \ - cimg::fread(raw._data,raw._width,nfile); \ - if (endian!=cimg::endianness()) cimg::invert_endianness(raw._data,raw._width); \ - const Tss *ptrs = raw._data; \ - for (unsigned int off = raw._width; off; --off) *(ptrd++) = (T)*(ptrs++); \ - const ulongT skipxe = (W - 1 - _nx1)*sizeof(Tss); \ - if (skipxe) cimg::fseek(nfile,skipxe,SEEK_CUR); \ - } \ - const ulongT skipye = (H - 1 - _ny1)*W*sizeof(Tss); \ - if (skipye) cimg::fseek(nfile,skipye,SEEK_CUR); \ - } \ - const ulongT skipze = (D - 1 - _nz1)*W*H*sizeof(Tss); \ - if (skipze) cimg::fseek(nfile,skipze,SEEK_CUR); \ - } \ - const ulongT skipve = (C - 1 - _nc1)*W*H*D*sizeof(Tss); \ - if (skipve) cimg::fseek(nfile,skipve,SEEK_CUR); \ - } \ - } \ - } \ - loaded = true; \ - } - - if (!filename && !file) - throw CImgArgumentException(_cimglist_instance - "load_cimg(): Specified filename is (null).", - cimglist_instance); - unsigned int - nn0 = cimg::min(n0,n1), nn1 = cimg::max(n0,n1), - nx0 = cimg::min(x0,x1), nx1 = cimg::max(x0,x1), - ny0 = cimg::min(y0,y1), ny1 = cimg::max(y0,y1), - nz0 = cimg::min(z0,z1), nz1 = cimg::max(z0,z1), - nc0 = cimg::min(c0,c1), nc1 = cimg::max(c0,c1); - - std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); - bool loaded = false, endian = cimg::endianness(); - CImg tmp(256), str_pixeltype(256), str_endian(256); - *tmp = *str_pixeltype = *str_endian = 0; - unsigned int j, N, W, H, D, C; - int i, err; - j = 0; while ((i=std::fgetc(nfile))!='\n' && i!=EOF && j<256) tmp[j++] = (char)i; tmp[j] = 0; - err = cimg_sscanf(tmp,"%u%*c%255[A-Za-z64_]%*c%255[sA-Za-z_ ]", - &N,str_pixeltype._data,str_endian._data); - if (err<2) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimglist_instance - "load_cimg(): CImg header not found in file '%s'.", - cimglist_instance, - filename?filename:"(FILE*)"); - } - if (!cimg::strncasecmp("little",str_endian,6)) endian = false; - else if (!cimg::strncasecmp("big",str_endian,3)) endian = true; - nn1 = n1==~0U?N - 1:n1; - if (nn1>=N) - throw CImgArgumentException(_cimglist_instance - "load_cimg(): Invalid specified coordinates [%u](%u,%u,%u,%u) -> [%u](%u,%u,%u,%u) " - "because file '%s' contains only %u images.", - cimglist_instance, - n0,x0,y0,z0,c0,n1,x1,y1,z1,c1,filename?filename:"(FILE*)",N); - assign(1 + nn1 - n0); - _cimg_load_cimg_case2("bool",bool); - _cimg_load_cimg_case2("unsigned_char",unsigned char); - _cimg_load_cimg_case2("uchar",unsigned char); - _cimg_load_cimg_case2("char",char); - _cimg_load_cimg_case2("unsigned_short",unsigned short); - _cimg_load_cimg_case2("ushort",unsigned short); - _cimg_load_cimg_case2("short",short); - _cimg_load_cimg_case2("unsigned_int",unsigned int); - _cimg_load_cimg_case2("uint",unsigned int); - _cimg_load_cimg_case2("int",int); - _cimg_load_cimg_case2("unsigned_long",ulongT); - _cimg_load_cimg_case2("ulong",ulongT); - _cimg_load_cimg_case2("long",longT); - _cimg_load_cimg_case2("unsigned_int64",uint64T); - _cimg_load_cimg_case2("uint64",uint64T); - _cimg_load_cimg_case2("int64",int64T); - _cimg_load_cimg_case2("float",float); - _cimg_load_cimg_case2("double",double); - if (!loaded) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimglist_instance - "load_cimg(): Unsupported pixel type '%s' for file '%s'.", - cimglist_instance, - str_pixeltype._data,filename?filename:"(FILE*)"); - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Load a list from a PAR/REC (Philips) file. - /** - \param filename Filename to read data from. - **/ - CImgList& load_parrec(const char *const filename) { - if (!filename) - throw CImgArgumentException(_cimglist_instance - "load_parrec(): Specified filename is (null).", - cimglist_instance); - - CImg body(1024), filenamepar(1024), filenamerec(1024); - *body = *filenamepar = *filenamerec = 0; - const char *const ext = cimg::split_filename(filename,body); - if (!std::strcmp(ext,"par")) { - std::strncpy(filenamepar,filename,filenamepar._width - 1); - cimg_snprintf(filenamerec,filenamerec._width,"%s.rec",body._data); - } - if (!std::strcmp(ext,"PAR")) { - std::strncpy(filenamepar,filename,filenamepar._width - 1); - cimg_snprintf(filenamerec,filenamerec._width,"%s.REC",body._data); - } - if (!std::strcmp(ext,"rec")) { - std::strncpy(filenamerec,filename,filenamerec._width - 1); - cimg_snprintf(filenamepar,filenamepar._width,"%s.par",body._data); - } - if (!std::strcmp(ext,"REC")) { - std::strncpy(filenamerec,filename,filenamerec._width - 1); - cimg_snprintf(filenamepar,filenamepar._width,"%s.PAR",body._data); - } - std::FILE *file = cimg::fopen(filenamepar,"r"); - - // Parse header file - CImgList st_slices; - CImgList st_global; - CImg line(256); *line = 0; - int err; - do { err = std::fscanf(file,"%255[^\n]%*c",line._data); } while (err!=EOF && (*line=='#' || *line=='.')); - do { - unsigned int sn,size_x,size_y,pixsize; - float rs,ri,ss; - err = std::fscanf(file,"%u%*u%*u%*u%*u%*u%*u%u%*u%u%u%g%g%g%*[^\n]",&sn,&pixsize,&size_x,&size_y,&ri,&rs,&ss); - if (err==7) { - CImg::vector((float)sn,(float)pixsize,(float)size_x,(float)size_y,ri,rs,ss,0).move_to(st_slices); - unsigned int i; for (i = 0; i::vector(size_x,size_y,sn).move_to(st_global); - else { - CImg &vec = st_global[i]; - if (size_x>vec[0]) vec[0] = size_x; - if (size_y>vec[1]) vec[1] = size_y; - vec[2] = sn; - } - st_slices[st_slices._width - 1][7] = (float)i; - } - } while (err==7); - - // Read data - std::FILE *file2 = cimg::fopen(filenamerec,"rb"); - cimglist_for(st_global,l) { - const CImg& vec = st_global[l]; - CImg(vec[0],vec[1],vec[2]).move_to(*this); - } - - cimglist_for(st_slices,l) { - const CImg& vec = st_slices[l]; - const unsigned int - sn = (unsigned int)vec[0] - 1, - pixsize = (unsigned int)vec[1], - size_x = (unsigned int)vec[2], - size_y = (unsigned int)vec[3], - imn = (unsigned int)vec[7]; - const float ri = vec[4], rs = vec[5], ss = vec[6]; - switch (pixsize) { - case 8 : { - CImg buf(size_x,size_y); - cimg::fread(buf._data,size_x*size_y,file2); - if (cimg::endianness()) cimg::invert_endianness(buf._data,size_x*size_y); - CImg& img = (*this)[imn]; - cimg_forXY(img,x,y) img(x,y,sn) = (T)(( buf(x,y)*rs + ri )/(rs*ss)); - } break; - case 16 : { - CImg buf(size_x,size_y); - cimg::fread(buf._data,size_x*size_y,file2); - if (cimg::endianness()) cimg::invert_endianness(buf._data,size_x*size_y); - CImg& img = (*this)[imn]; - cimg_forXY(img,x,y) img(x,y,sn) = (T)(( buf(x,y)*rs + ri )/(rs*ss)); - } break; - case 32 : { - CImg buf(size_x,size_y); - cimg::fread(buf._data,size_x*size_y,file2); - if (cimg::endianness()) cimg::invert_endianness(buf._data,size_x*size_y); - CImg& img = (*this)[imn]; - cimg_forXY(img,x,y) img(x,y,sn) = (T)(( buf(x,y)*rs + ri )/(rs*ss)); - } break; - default : - cimg::fclose(file); - cimg::fclose(file2); - throw CImgIOException(_cimglist_instance - "load_parrec(): Unsupported %d-bits pixel type for file '%s'.", - cimglist_instance, - pixsize,filename); - } - } - cimg::fclose(file); - cimg::fclose(file2); - if (!_width) - throw CImgIOException(_cimglist_instance - "load_parrec(): Failed to recognize valid PAR-REC data in file '%s'.", - cimglist_instance, - filename); - return *this; - } - - //! Load a list from a PAR/REC (Philips) file \newinstance. - static CImgList get_load_parrec(const char *const filename) { - return CImgList().load_parrec(filename); - } - - //! Load a list from a YUV image sequence file. - /** - \param filename Filename to read data from. - \param size_x Width of the images. - \param size_y Height of the images. - \param first_frame Index of first image frame to read. - \param last_frame Index of last image frame to read. - \param step_frame Step applied between each frame. - \param yuv2rgb Apply YUV to RGB transformation during reading. - **/ - CImgList& load_yuv(const char *const filename, - const unsigned int size_x, const unsigned int size_y, - const unsigned int first_frame=0, const unsigned int last_frame=~0U, - const unsigned int step_frame=1, const bool yuv2rgb=true) { - return _load_yuv(0,filename,size_x,size_y,first_frame,last_frame,step_frame,yuv2rgb); - } - - //! Load a list from a YUV image sequence file \newinstance. - static CImgList get_load_yuv(const char *const filename, - const unsigned int size_x, const unsigned int size_y=1, - const unsigned int first_frame=0, const unsigned int last_frame=~0U, - const unsigned int step_frame=1, const bool yuv2rgb=true) { - return CImgList().load_yuv(filename,size_x,size_y,first_frame,last_frame,step_frame,yuv2rgb); - } - - //! Load a list from an image sequence YUV file \overloading. - CImgList& load_yuv(std::FILE *const file, - const unsigned int size_x, const unsigned int size_y, - const unsigned int first_frame=0, const unsigned int last_frame=~0U, - const unsigned int step_frame=1, const bool yuv2rgb=true) { - return _load_yuv(file,0,size_x,size_y,first_frame,last_frame,step_frame,yuv2rgb); - } - - //! Load a list from an image sequence YUV file \newinstance. - static CImgList get_load_yuv(std::FILE *const file, - const unsigned int size_x, const unsigned int size_y=1, - const unsigned int first_frame=0, const unsigned int last_frame=~0U, - const unsigned int step_frame=1, const bool yuv2rgb=true) { - return CImgList().load_yuv(file,size_x,size_y,first_frame,last_frame,step_frame,yuv2rgb); - } - - CImgList& _load_yuv(std::FILE *const file, const char *const filename, - const unsigned int size_x, const unsigned int size_y, - const unsigned int first_frame, const unsigned int last_frame, - const unsigned int step_frame, const bool yuv2rgb) { - if (!filename && !file) - throw CImgArgumentException(_cimglist_instance - "load_yuv(): Specified filename is (null).", - cimglist_instance); - if (size_x%2 || size_y%2) - throw CImgArgumentException(_cimglist_instance - "load_yuv(): Invalid odd XY dimensions %ux%u in file '%s'.", - cimglist_instance, - size_x,size_y,filename?filename:"(FILE*)"); - if (!size_x || !size_y) - throw CImgArgumentException(_cimglist_instance - "load_yuv(): Invalid sequence size (%u,%u) in file '%s'.", - cimglist_instance, - size_x,size_y,filename?filename:"(FILE*)"); - - const unsigned int - nfirst_frame = first_frame tmp(size_x,size_y,1,3), UV(size_x/2,size_y/2,1,2); - std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); - bool stop_flag = false; - int err; - if (nfirst_frame) { - err = cimg::fseek(nfile,nfirst_frame*(size_x*size_y + size_x*size_y/2),SEEK_CUR); - if (err) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimglist_instance - "load_yuv(): File '%s' doesn't contain frame number %u.", - cimglist_instance, - filename?filename:"(FILE*)",nfirst_frame); - } - } - unsigned int frame; - for (frame = nfirst_frame; !stop_flag && frame<=nlast_frame; frame+=nstep_frame) { - tmp.fill(0); - // *TRY* to read the luminance part, do not replace by cimg::fread! - err = (int)std::fread((void*)(tmp._data),1,(ulongT)tmp._width*tmp._height,nfile); - if (err!=(int)(tmp._width*tmp._height)) { - stop_flag = true; - if (err>0) - cimg::warn(_cimglist_instance - "load_yuv(): File '%s' contains incomplete data or given image dimensions " - "(%u,%u) are incorrect.", - cimglist_instance, - filename?filename:"(FILE*)",size_x,size_y); - } else { - UV.fill(0); - // *TRY* to read the luminance part, do not replace by cimg::fread! - err = (int)std::fread((void*)(UV._data),1,(size_t)(UV.size()),nfile); - if (err!=(int)(UV.size())) { - stop_flag = true; - if (err>0) - cimg::warn(_cimglist_instance - "load_yuv(): File '%s' contains incomplete data or given image dimensions (%u,%u) " - "are incorrect.", - cimglist_instance, - filename?filename:"(FILE*)",size_x,size_y); - } else { - cimg_forXY(UV,x,y) { - const int x2 = x*2, y2 = y*2; - tmp(x2,y2,1) = tmp(x2 + 1,y2,1) = tmp(x2,y2 + 1,1) = tmp(x2 + 1,y2 + 1,1) = UV(x,y,0); - tmp(x2,y2,2) = tmp(x2 + 1,y2,2) = tmp(x2,y2 + 1,2) = tmp(x2 + 1,y2 + 1,2) = UV(x,y,1); - } - if (yuv2rgb) tmp.YCbCrtoRGB(); - insert(tmp); - if (nstep_frame>1) cimg::fseek(nfile,(nstep_frame - 1)*(size_x*size_y + size_x*size_y/2),SEEK_CUR); - } - } - } - if (stop_flag && nlast_frame!=~0U && frame!=nlast_frame) - cimg::warn(_cimglist_instance - "load_yuv(): Frame %d not reached since only %u frames were found in file '%s'.", - cimglist_instance, - nlast_frame,frame - 1,filename?filename:"(FILE*)"); - - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Load an image from a video file, using OpenCV library. - /** - \param filename Filename, as a C-string. - \param first_frame Index of the first frame to read. - \param last_frame Index of the last frame to read. - \param step_frame Step value for frame reading. - \note If step_frame==0, the current video stream is forced to be released (without any frames read). - **/ - CImgList& load_video(const char *const filename, - const unsigned int first_frame=0, const unsigned int last_frame=~0U, - const unsigned int step_frame=1) { -#ifndef cimg_use_opencv - if (first_frame || last_frame!=~0U || step_frame>1) - throw CImgArgumentException(_cimglist_instance - "load_video() : File '%s', arguments 'first_frame', 'last_frame' " - "and 'step_frame' can be only set when using OpenCV " - "(-Dcimg_use_opencv must be enabled).", - cimglist_instance,filename); - return load_ffmpeg_external(filename); -#else - static CvCapture *captures[32] = { 0 }; - static CImgList filenames(32); - static CImg positions(32,1,1,1,0); - static int last_used_index = -1; - - // Detect if a video capture already exists for the specified filename. - cimg::mutex(9); - int index = -1; - if (filename) { - if (last_used_index>=0 && !std::strcmp(filename,filenames[last_used_index])) { - index = last_used_index; - } else cimglist_for(filenames,l) if (filenames[l] && !std::strcmp(filename,filenames[l])) { - index = l; break; - } - } else index = last_used_index; - cimg::mutex(9,0); - - // Release stream if needed. - if (!step_frame || (index>=0 && positions[index]>first_frame)) { - if (index>=0) { - cimg::mutex(9); - cvReleaseCapture(&captures[index]); - captures[index] = 0; filenames[index].assign(); positions[index] = 0; - if (last_used_index==index) last_used_index = -1; - index = -1; - cimg::mutex(9,0); - } else - if (filename) - cimg::warn(_cimglist_instance - "load_video() : File '%s', no opened video stream associated with filename found.", - cimglist_instance,filename); - else - cimg::warn(_cimglist_instance - "load_video() : No opened video stream found.", - cimglist_instance,filename); - if (!step_frame) return *this; - } - - // Find empty slot for capturing video stream. - if (index<0) { - if (!filename) - throw CImgArgumentException(_cimglist_instance - "load_video(): No already open video reader found. You must specify a " - "non-(null) filename argument for the first call.", - cimglist_instance); - else { cimg::mutex(9); cimglist_for(filenames,l) if (!filenames[l]) { index = l; break; } cimg::mutex(9,0); } - if (index<0) - throw CImgIOException(_cimglist_instance - "load_video(): File '%s', no video reader slots available. " - "You have to release some of your previously opened videos.", - cimglist_instance,filename); - cimg::mutex(9); - captures[index] = cvCaptureFromFile(filename); - CImg::string(filename).move_to(filenames[index]); - positions[index] = 0; - cimg::mutex(9,0); - if (!captures[index]) { - filenames[index].assign(); - std::fclose(cimg::fopen(filename,"rb")); // Check file availability. - throw CImgIOException(_cimglist_instance - "load_video(): File '%s', unable to detect format of video file.", - cimglist_instance,filename); - } - } - - cimg::mutex(9); - const unsigned int nb_frames = (unsigned int)cimg::max(0.,cvGetCaptureProperty(captures[index], - CV_CAP_PROP_FRAME_COUNT)); - cimg::mutex(9,0); - assign(); - - // Skip frames if necessary. - bool go_on = true; - unsigned int &pos = positions[index]; - while (pos frame(src->width,src->height,1,3); - const int step = (int)(src->widthStep - 3*src->width); - const unsigned char* ptrs = (unsigned char*)src->imageData; - T *ptr_r = frame.data(0,0,0,0), *ptr_g = frame.data(0,0,0,1), *ptr_b = frame.data(0,0,0,2); - if (step>0) cimg_forY(frame,y) { - cimg_forX(frame,x) { *(ptr_b++) = (T)*(ptrs++); *(ptr_g++) = (T)*(ptrs++); *(ptr_r++) = (T)*(ptrs++); } - ptrs+=step; - } else for (ulongT siz = (ulongT)src->width*src->height; siz; --siz) { - *(ptr_b++) = (T)*(ptrs++); *(ptr_g++) = (T)*(ptrs++); *(ptr_r++) = (T)*(ptrs++); - } - frame.move_to(*this); - ++pos; - - bool skip_failed = false; - for (unsigned int i = 1; i=nb_frames)) { // Close video stream when necessary. - cimg::mutex(9); - cvReleaseCapture(&captures[index]); - captures[index] = 0; - filenames[index].assign(); - positions[index] = 0; - index = -1; - cimg::mutex(9,0); - } - - cimg::mutex(9); - last_used_index = index; - cimg::mutex(9,0); - - if (is_empty()) - throw CImgIOException(_cimglist_instance - "load_video(): File '%s', unable to locate frame %u.", - cimglist_instance,filename,first_frame); - return *this; -#endif - } - - //! Load an image from a video file, using OpenCV library \newinstance. - static CImgList get_load_video(const char *const filename, - const unsigned int first_frame=0, const unsigned int last_frame=~0U, - const unsigned int step_frame=1) { - return CImgList().load_video(filename,first_frame,last_frame,step_frame); - } - - //! Load an image from a video file using the external tool 'ffmpeg'. - /** - \param filename Filename to read data from. - **/ - CImgList& load_ffmpeg_external(const char *const filename) { - if (!filename) - throw CImgArgumentException(_cimglist_instance - "load_ffmpeg_external(): Specified filename is (null).", - cimglist_instance); - std::fclose(cimg::fopen(filename,"rb")); // Check if file exists. - CImg command(1024), filename_tmp(256), filename_tmp2(256); - std::FILE *file = 0; - do { - cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand()); - cimg_snprintf(filename_tmp2,filename_tmp2._width,"%s_000001.ppm",filename_tmp._data); - if ((file=std_fopen(filename_tmp2,"rb"))!=0) cimg::fclose(file); - } while (file); - cimg_snprintf(filename_tmp2,filename_tmp2._width,"%s_%%6d.ppm",filename_tmp._data); -#if cimg_OS!=2 - cimg_snprintf(command,command._width,"%s -i \"%s\" \"%s\" >/dev/null 2>&1", - cimg::ffmpeg_path(), - CImg::string(filename)._system_strescape().data(), - CImg::string(filename_tmp2)._system_strescape().data()); -#else - cimg_snprintf(command,command._width,"\"%s -i \"%s\" \"%s\"\" >NUL 2>&1", - cimg::ffmpeg_path(), - CImg::string(filename)._system_strescape().data(), - CImg::string(filename_tmp2)._system_strescape().data()); -#endif - cimg::system(command,0); - const unsigned int omode = cimg::exception_mode(); - cimg::exception_mode(0); - assign(); - unsigned int i = 1; - for (bool stop_flag = false; !stop_flag; ++i) { - cimg_snprintf(filename_tmp2,filename_tmp2._width,"%s_%.6u.ppm",filename_tmp._data,i); - CImg img; - try { img.load_pnm(filename_tmp2); } - catch (CImgException&) { stop_flag = true; } - if (img) { img.move_to(*this); std::remove(filename_tmp2); } - } - cimg::exception_mode(omode); - if (is_empty()) - throw CImgIOException(_cimglist_instance - "load_ffmpeg_external(): Failed to open file '%s' with external command 'ffmpeg'.", - cimglist_instance, - filename); - return *this; - } - - //! Load an image from a video file using the external tool 'ffmpeg' \newinstance. - static CImgList get_load_ffmpeg_external(const char *const filename) { - return CImgList().load_ffmpeg_external(filename); - } - - //! Load gif file, using ImageMagick or GraphicsMagick's external tools. - /** - \param filename Filename to read data from. - \param use_graphicsmagick Tells if GraphicsMagick's tool 'gm' is used instead of ImageMagick's tool 'convert'. - **/ - CImgList& load_gif_external(const char *const filename) { - if (!filename) - throw CImgArgumentException(_cimglist_instance - "load_gif_external(): Specified filename is (null).", - cimglist_instance); - std::fclose(cimg::fopen(filename,"rb")); // Check if file exists. - if (!_load_gif_external(filename,false)) - if (!_load_gif_external(filename,true)) - try { assign(CImg().load_other(filename)); } catch (CImgException&) { assign(); } - if (is_empty()) - throw CImgIOException(_cimglist_instance - "load_gif_external(): Failed to open file '%s'.", - cimglist_instance,filename); - return *this; - } - - CImgList& _load_gif_external(const char *const filename, const bool use_graphicsmagick=false) { - CImg command(1024), filename_tmp(256), filename_tmp2(256); - std::FILE *file = 0; - do { - cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand()); - if (use_graphicsmagick) cimg_snprintf(filename_tmp2,filename_tmp2._width,"%s.png.0",filename_tmp._data); - else cimg_snprintf(filename_tmp2,filename_tmp2._width,"%s-0.png",filename_tmp._data); - if ((file=std_fopen(filename_tmp2,"rb"))!=0) cimg::fclose(file); - } while (file); -#if cimg_OS!=2 - if (use_graphicsmagick) cimg_snprintf(command,command._width,"%s convert \"%s\" \"%s.png\" >/dev/null 2>&1", - cimg::graphicsmagick_path(), - CImg::string(filename)._system_strescape().data(), - CImg::string(filename_tmp)._system_strescape().data()); - else cimg_snprintf(command,command._width,"%s \"%s\" \"%s.png\" >/dev/null 2>&1", - cimg::imagemagick_path(), - CImg::string(filename)._system_strescape().data(), - CImg::string(filename_tmp)._system_strescape().data()); -#else - if (use_graphicsmagick) cimg_snprintf(command,command._width,"\"%s convert \"%s\" \"%s.png\"\" >NUL 2>&1", - cimg::graphicsmagick_path(), - CImg::string(filename)._system_strescape().data(), - CImg::string(filename_tmp)._system_strescape().data()); - else cimg_snprintf(command,command._width,"\"%s \"%s\" \"%s.png\"\" >NUL 2>&1", - cimg::imagemagick_path(), - CImg::string(filename)._system_strescape().data(), - CImg::string(filename_tmp)._system_strescape().data()); -#endif - cimg::system(command,0); - const unsigned int omode = cimg::exception_mode(); - cimg::exception_mode(0); - assign(); - - // Try to read a single frame gif. - cimg_snprintf(filename_tmp2,filename_tmp2._width,"%s.png",filename_tmp._data); - CImg img; - try { img.load_png(filename_tmp2); } - catch (CImgException&) { } - if (img) { img.move_to(*this); std::remove(filename_tmp2); } - else { // Try to read animated gif. - unsigned int i = 0; - for (bool stop_flag = false; !stop_flag; ++i) { - if (use_graphicsmagick) cimg_snprintf(filename_tmp2,filename_tmp2._width,"%s.png.%u",filename_tmp._data,i); - else cimg_snprintf(filename_tmp2,filename_tmp2._width,"%s-%u.png",filename_tmp._data,i); - CImg img; - try { img.load_png(filename_tmp2); } - catch (CImgException&) { stop_flag = true; } - if (img) { img.move_to(*this); std::remove(filename_tmp2); } - } - } - cimg::exception_mode(omode); - return *this; - } - - //! Load gif file, using ImageMagick or GraphicsMagick's external tools \newinstance. - static CImgList get_load_gif_external(const char *const filename) { - return CImgList().load_gif_external(filename); - } - - //! Load a gzipped list, using external tool 'gunzip'. - /** - \param filename Filename to read data from. - **/ - CImgList& load_gzip_external(const char *const filename) { - if (!filename) - throw CImgIOException(_cimglist_instance - "load_gzip_external(): Specified filename is (null).", - cimglist_instance); - std::fclose(cimg::fopen(filename,"rb")); // Check if file exists. - CImg command(1024), filename_tmp(256), body(256); - const char - *ext = cimg::split_filename(filename,body), - *ext2 = cimg::split_filename(body,0); - std::FILE *file = 0; - do { - if (!cimg::strcasecmp(ext,"gz")) { - if (*ext2) cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.%s", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),ext2); - else cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand()); - } else { - if (*ext) cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.%s", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),ext); - else cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand()); - } - if ((file=std_fopen(filename_tmp,"rb"))!=0) cimg::fclose(file); - } while (file); - cimg_snprintf(command,command._width,"%s -c \"%s\" > \"%s\"", - cimg::gunzip_path(), - CImg::string(filename)._system_strescape().data(), - CImg::string(filename_tmp)._system_strescape().data()); - cimg::system(command); - if (!(file = std_fopen(filename_tmp,"rb"))) { - cimg::fclose(cimg::fopen(filename,"r")); - throw CImgIOException(_cimglist_instance - "load_gzip_external(): Failed to open file '%s'.", - cimglist_instance, - filename); - - } else cimg::fclose(file); - load(filename_tmp); - std::remove(filename_tmp); - return *this; - } - - //! Load a gzipped list, using external tool 'gunzip' \newinstance. - static CImgList get_load_gzip_external(const char *const filename) { - return CImgList().load_gzip_external(filename); - } - - //! Load a 3d object from a .OFF file. - /** - \param filename Filename to read data from. - \param[out] primitives At return, contains the list of 3d object primitives. - \param[out] colors At return, contains the list of 3d object colors. - \return List of 3d object vertices. - **/ - template - CImgList& load_off(const char *const filename, - CImgList& primitives, CImgList& colors) { - return get_load_off(filename,primitives,colors).move_to(*this); - } - - //! Load a 3d object from a .OFF file \newinstance. - template - static CImgList get_load_off(const char *const filename, - CImgList& primitives, CImgList& colors) { - return CImg().load_off(filename,primitives,colors)<'x'; - } - - //! Load images from a TIFF file. - /** - \param filename Filename to read data from. - \param first_frame Index of first image frame to read. - \param last_frame Index of last image frame to read. - \param step_frame Step applied between each frame. - **/ - CImgList& load_tiff(const char *const filename, - const unsigned int first_frame=0, const unsigned int last_frame=~0U, - const unsigned int step_frame=1, - float *const voxel_size=0, - CImg *const description=0) { - const unsigned int - nfirst_frame = first_frame::get_load_tiff(filename)); -#else - TIFF *tif = TIFFOpen(filename,"r"); - if (tif) { - unsigned int nb_images = 0; - do ++nb_images; while (TIFFReadDirectory(tif)); - if (nfirst_frame>=nb_images || (nlast_frame!=~0U && nlast_frame>=nb_images)) - cimg::warn(_cimglist_instance - "load_tiff(): Invalid specified frame range is [%u,%u] (step %u) since " - "file '%s' contains %u image(s).", - cimglist_instance, - nfirst_frame,nlast_frame,nstep_frame,filename,nb_images); - - if (nfirst_frame>=nb_images) return assign(); - if (nlast_frame>=nb_images) nlast_frame = nb_images - 1; - assign(1 + (nlast_frame - nfirst_frame)/nstep_frame); - TIFFSetDirectory(tif,0); -#if cimg_verbosity>=3 - TIFFSetWarningHandler(0); - TIFFSetErrorHandler(0); -#endif - cimglist_for(*this,l) _data[l]._load_tiff(tif,nfirst_frame + l*nstep_frame,voxel_size,description); - TIFFClose(tif); - } else throw CImgIOException(_cimglist_instance - "load_tiff(): Failed to open file '%s'.", - cimglist_instance, - filename); - return *this; -#endif - } - - //! Load a multi-page TIFF file \newinstance. - static CImgList get_load_tiff(const char *const filename, - const unsigned int first_frame=0, const unsigned int last_frame=~0U, - const unsigned int step_frame=1, - float *const voxel_size=0, - CImg *const description=0) { - return CImgList().load_tiff(filename,first_frame,last_frame,step_frame,voxel_size,description); - } - - //@} - //---------------------------------- - // - //! \name Data Output - //@{ - //---------------------------------- - - //! Print information about the list on the standard output. - /** - \param title Label set to the information displayed. - \param display_stats Tells if image statistics must be computed and displayed. - **/ - const CImgList& print(const char *const title=0, const bool display_stats=true) const { - unsigned int msiz = 0; - cimglist_for(*this,l) msiz+=_data[l].size(); - msiz*=sizeof(T); - const unsigned int mdisp = msiz<8*1024?0U:msiz<8*1024*1024?1U:2U; - CImg _title(64); - if (!title) cimg_snprintf(_title,_title._width,"CImgList<%s>",pixel_type()); - std::fprintf(cimg::output(),"%s%s%s%s: %sthis%s = %p, %ssize%s = %u/%u [%u %s], %sdata%s = (CImg<%s>*)%p", - cimg::t_magenta,cimg::t_bold,title?title:_title._data,cimg::t_normal, - cimg::t_bold,cimg::t_normal,(void*)this, - cimg::t_bold,cimg::t_normal,_width,_allocated_width, - mdisp==0?msiz:(mdisp==1?(msiz>>10):(msiz>>20)), - mdisp==0?"b":(mdisp==1?"Kio":"Mio"), - cimg::t_bold,cimg::t_normal,pixel_type(),(void*)begin()); - if (_data) std::fprintf(cimg::output(),"..%p.\n",(void*)((char*)end() - 1)); - else std::fprintf(cimg::output(),".\n"); - - char tmp[16] = { 0 }; - cimglist_for(*this,ll) { - cimg_snprintf(tmp,sizeof(tmp),"[%d]",ll); - std::fprintf(cimg::output()," "); - _data[ll].print(tmp,display_stats); - if (ll==3 && width()>8) { ll = width() - 5; std::fprintf(cimg::output()," ...\n"); } - } - std::fflush(cimg::output()); - return *this; - } - - //! Display the current CImgList instance in an existing CImgDisplay window (by reference). - /** - \param disp Reference to an existing CImgDisplay instance, where the current image list will be displayed. - \param axis Appending axis. Can be { 'x' | 'y' | 'z' | 'c' }. - \param align Appending alignmenet. - \note This function displays the list images of the current CImgList instance into an existing - CImgDisplay window. - Images of the list are appended in a single temporarly image for visualization purposes. - The function returns immediately. - **/ - const CImgList& display(CImgDisplay &disp, const char axis='x', const float align=0) const { - disp.display(*this,axis,align); - return *this; - } - - //! Display the current CImgList instance in a new display window. - /** - \param disp Display window. - \param display_info Tells if image information are displayed on the standard output. - \param axis Alignment axis for images viewing. - \param align Apending alignment. - \note This function opens a new window with a specific title and displays the list images of the - current CImgList instance into it. - Images of the list are appended in a single temporarly image for visualization purposes. - The function returns when a key is pressed or the display window is closed by the user. - **/ - const CImgList& display(CImgDisplay &disp, const bool display_info, - const char axis='x', const float align=0, - unsigned int *const XYZ=0, const bool exit_on_anykey=false) const { - bool is_exit = false; - return _display(disp,0,0,display_info,axis,align,XYZ,exit_on_anykey,0,true,is_exit); - } - - //! Display the current CImgList instance in a new display window. - /** - \param title Title of the opening display window. - \param display_info Tells if list information must be written on standard output. - \param axis Appending axis. Can be { 'x' | 'y' | 'z' | 'c' }. - \param align Appending alignment. - **/ - const CImgList& display(const char *const title=0, const bool display_info=true, - const char axis='x', const float align=0, - unsigned int *const XYZ=0, const bool exit_on_anykey=false) const { - CImgDisplay disp; - bool is_exit = false; - return _display(disp,title,0,display_info,axis,align,XYZ,exit_on_anykey,0,true,is_exit); - } - - const CImgList& _display(CImgDisplay &disp, const char *const title, const CImgList *const titles, - const bool display_info, const char axis, const float align, unsigned int *const XYZ, - const bool exit_on_anykey, const unsigned int orig, const bool is_first_call, - bool &is_exit) const { - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "display(): Empty instance.", - cimglist_instance); - if (!disp) { - if (axis=='x') { - unsigned int sum_width = 0, max_height = 0; - cimglist_for(*this,l) { - const CImg &img = _data[l]; - const unsigned int - w = CImgDisplay::_fitscreen(img._width,img._height,img._depth,128,-85,false), - h = CImgDisplay::_fitscreen(img._width,img._height,img._depth,128,-85,true); - sum_width+=w; - if (h>max_height) max_height = h; - } - disp.assign(cimg_fitscreen(sum_width,max_height,1),title?title:titles?titles->__display()._data:0,1); - } else { - unsigned int max_width = 0, sum_height = 0; - cimglist_for(*this,l) { - const CImg &img = _data[l]; - const unsigned int - w = CImgDisplay::_fitscreen(img._width,img._height,img._depth,128,-85,false), - h = CImgDisplay::_fitscreen(img._width,img._height,img._depth,128,-85,true); - if (w>max_width) max_width = w; - sum_height+=h; - } - disp.assign(cimg_fitscreen(max_width,sum_height,1),title?title:titles?titles->__display()._data:0,1); - } - if (!title && !titles) disp.set_title("CImgList<%s> (%u)",pixel_type(),_width); - } else if (title) disp.set_title("%s",title); - else if (titles) disp.set_title("%s",titles->__display()._data); - const CImg dtitle = CImg::string(disp.title()); - if (display_info) print(disp.title()); - disp.show().flush(); - - if (_width==1) { - const unsigned int dw = disp._width, dh = disp._height; - if (!is_first_call) - disp.resize(cimg_fitscreen(_data[0]._width,_data[0]._height,_data[0]._depth),false); - disp.set_title("%s (%ux%ux%ux%u)", - dtitle.data(),_data[0]._width,_data[0]._height,_data[0]._depth,_data[0]._spectrum); - _data[0]._display(disp,0,false,XYZ,exit_on_anykey,!is_first_call); - if (disp.key()) is_exit = true; - disp.resize(cimg_fitscreen(dw,dh,1),false).set_title("%s",dtitle.data()); - } else { - bool disp_resize = !is_first_call; - while (!disp.is_closed() && !is_exit) { - const CImg s = _get_select(disp,0,true,axis,align,exit_on_anykey,orig,disp_resize,!is_first_call,true); - disp_resize = true; - if (s[0]<0 && !disp.wheel()) { // No selections done. - if (disp.button()&2) { disp.flush(); break; } - is_exit = true; - } else if (disp.wheel()) { // Zoom in/out. - const int wheel = disp.wheel(); - disp.set_wheel(); - if (!is_first_call && wheel<0) break; - if (wheel>0 && _width>=4) { - const unsigned int - delta = cimg::max(1U,(unsigned int)cimg::round(0.3*_width)), - ind0 = (unsigned int)cimg::max(0,s[0] - (int)delta), - ind1 = (unsigned int)cimg::min(width() - 1,s[0] + (int)delta); - if ((ind0!=0 || ind1!=_width - 1) && ind1 - ind0>=3) { - const CImgList sublist = get_shared_images(ind0,ind1); - CImgList t_sublist; - if (titles) t_sublist = titles->get_shared_images(ind0,ind1); - sublist._display(disp,0,titles?&t_sublist:0,false,axis,align,XYZ,exit_on_anykey, - orig + ind0,false,is_exit); - } - } - } else if (s[0]!=0 || s[1]!=width() - 1) { - const CImgList sublist = get_shared_images(s[0],s[1]); - CImgList t_sublist; - if (titles) t_sublist = titles->get_shared_images(s[0],s[1]); - sublist._display(disp,0,titles?&t_sublist:0,false,axis,align,XYZ,exit_on_anykey, - orig + s[0],false,is_exit); - } - disp.set_title("%s",dtitle.data()); - } - } - return *this; - } - - // [internal] Return string to describe display title. - CImg __display() const { - CImg res, str; - cimglist_for(*this,l) { - CImg::string(_data[l]).move_to(str); - if (l!=width() - 1) { - str.resize(str._width + 1,1,1,1,0); - str[str._width - 2] = ','; - str[str._width - 1] = ' '; - } - res.append(str,'x'); - } - if (!res) return CImg(1,1,1,1,0).move_to(res); - cimg::strellipsize(res,128,false); - if (_width>1) { - const unsigned int l = (unsigned int)std::strlen(res); - if (res._width<=l + 16) res.resize(l + 16,1,1,1,0); - cimg_snprintf(res._data + l,16," (#%u)",_width); - } - return res; - } - - //! Save list into a file. - /** - \param filename Filename to write data to. - \param number When positive, represents an index added to the filename. Otherwise, no number is added. - \param digits Number of digits used for adding the number to the filename. - **/ - const CImgList& save(const char *const filename, const int number=-1, const unsigned int digits=6) const { - if (!filename) - throw CImgArgumentException(_cimglist_instance - "save(): Specified filename is (null).", - cimglist_instance); - // Do not test for empty instances, since .cimg format is able to manage empty instances. - const bool is_stdout = *filename=='-' && (!filename[1] || filename[1]=='.'); - const char *const ext = cimg::split_filename(filename); - CImg nfilename(1024); - const char *const fn = is_stdout?filename:number>=0?cimg::number_filename(filename,number,digits,nfilename): - filename; - -#ifdef cimglist_save_plugin - cimglist_save_plugin(fn); -#endif -#ifdef cimglist_save_plugin1 - cimglist_save_plugin1(fn); -#endif -#ifdef cimglist_save_plugin2 - cimglist_save_plugin2(fn); -#endif -#ifdef cimglist_save_plugin3 - cimglist_save_plugin3(fn); -#endif -#ifdef cimglist_save_plugin4 - cimglist_save_plugin4(fn); -#endif -#ifdef cimglist_save_plugin5 - cimglist_save_plugin5(fn); -#endif -#ifdef cimglist_save_plugin6 - cimglist_save_plugin6(fn); -#endif -#ifdef cimglist_save_plugin7 - cimglist_save_plugin7(fn); -#endif -#ifdef cimglist_save_plugin8 - cimglist_save_plugin8(fn); -#endif - if (!cimg::strcasecmp(ext,"cimgz")) return save_cimg(fn,true); - else if (!cimg::strcasecmp(ext,"cimg") || !*ext) return save_cimg(fn,false); - else if (!cimg::strcasecmp(ext,"yuv")) return save_yuv(fn,true); - else if (!cimg::strcasecmp(ext,"avi") || - !cimg::strcasecmp(ext,"mov") || - !cimg::strcasecmp(ext,"asf") || - !cimg::strcasecmp(ext,"divx") || - !cimg::strcasecmp(ext,"flv") || - !cimg::strcasecmp(ext,"mpg") || - !cimg::strcasecmp(ext,"m1v") || - !cimg::strcasecmp(ext,"m2v") || - !cimg::strcasecmp(ext,"m4v") || - !cimg::strcasecmp(ext,"mjp") || - !cimg::strcasecmp(ext,"mp4") || - !cimg::strcasecmp(ext,"mkv") || - !cimg::strcasecmp(ext,"mpe") || - !cimg::strcasecmp(ext,"movie") || - !cimg::strcasecmp(ext,"ogm") || - !cimg::strcasecmp(ext,"ogg") || - !cimg::strcasecmp(ext,"ogv") || - !cimg::strcasecmp(ext,"qt") || - !cimg::strcasecmp(ext,"rm") || - !cimg::strcasecmp(ext,"vob") || - !cimg::strcasecmp(ext,"wmv") || - !cimg::strcasecmp(ext,"xvid") || - !cimg::strcasecmp(ext,"mpeg")) return save_video(fn); -#ifdef cimg_use_tiff - else if (!cimg::strcasecmp(ext,"tif") || - !cimg::strcasecmp(ext,"tiff")) return save_tiff(fn); -#endif - else if (!cimg::strcasecmp(ext,"gz")) return save_gzip_external(fn); - else { - if (_width==1) _data[0].save(fn,-1); - else cimglist_for(*this,l) { _data[l].save(fn,is_stdout?-1:l); if (is_stdout) std::fputc(EOF,stdout); } - } - return *this; - } - - //! Tell if an image list can be saved as one single file. - /** - \param filename Filename, as a C-string. - \return \c true if the file format supports multiple images, \c false otherwise. - **/ - static bool is_saveable(const char *const filename) { - const char *const ext = cimg::split_filename(filename); - if (!cimg::strcasecmp(ext,"cimgz") || -#ifdef cimg_use_tiff - !cimg::strcasecmp(ext,"tif") || - !cimg::strcasecmp(ext,"tiff") || -#endif - !cimg::strcasecmp(ext,"yuv") || - !cimg::strcasecmp(ext,"avi") || - !cimg::strcasecmp(ext,"mov") || - !cimg::strcasecmp(ext,"asf") || - !cimg::strcasecmp(ext,"divx") || - !cimg::strcasecmp(ext,"flv") || - !cimg::strcasecmp(ext,"mpg") || - !cimg::strcasecmp(ext,"m1v") || - !cimg::strcasecmp(ext,"m2v") || - !cimg::strcasecmp(ext,"m4v") || - !cimg::strcasecmp(ext,"mjp") || - !cimg::strcasecmp(ext,"mp4") || - !cimg::strcasecmp(ext,"mkv") || - !cimg::strcasecmp(ext,"mpe") || - !cimg::strcasecmp(ext,"movie") || - !cimg::strcasecmp(ext,"ogm") || - !cimg::strcasecmp(ext,"ogg") || - !cimg::strcasecmp(ext,"ogv") || - !cimg::strcasecmp(ext,"qt") || - !cimg::strcasecmp(ext,"rm") || - !cimg::strcasecmp(ext,"vob") || - !cimg::strcasecmp(ext,"wmv") || - !cimg::strcasecmp(ext,"xvid") || - !cimg::strcasecmp(ext,"mpeg")) return true; - return false; - } - - //! Save image sequence as a GIF animated file. - /** - \param filename Filename to write data to. - \param fps Number of desired frames per second. - \param nb_loops Number of loops (\c 0 for infinite looping). - **/ - const CImgList& save_gif_external(const char *const filename, const float fps=25, - const unsigned int nb_loops=0) { - CImg command(1024), filename_tmp(256), filename_tmp2(256); - CImgList filenames; - std::FILE *file = 0; - -#ifdef cimg_use_png -#define _cimg_save_gif_ext "png" -#else -#define _cimg_save_gif_ext "ppm" -#endif - - do { - cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand()); - cimg_snprintf(filename_tmp2,filename_tmp2._width,"%s_000001." _cimg_save_gif_ext,filename_tmp._data); - if ((file=std_fopen(filename_tmp2,"rb"))!=0) cimg::fclose(file); - } while (file); - cimglist_for(*this,l) { - cimg_snprintf(filename_tmp2,filename_tmp2._width,"%s_%.6u." _cimg_save_gif_ext,filename_tmp._data,l + 1); - CImg::string(filename_tmp2).move_to(filenames); - if (_data[l]._depth>1 || _data[l]._spectrum!=3) _data[l].get_resize(-100,-100,1,3).save(filename_tmp2); - else _data[l].save(filename_tmp2); - } - -#if cimg_OS!=2 - cimg_snprintf(command,command._width,"%s -delay %u -loop %u", - cimg::imagemagick_path(),(unsigned int)cimg::max(0.0f,cimg::round(100/fps)),nb_loops); - CImg::string(command).move_to(filenames,0); - cimg_snprintf(command,command._width,"\"%s\" >/dev/null 2>&1", - CImg::string(filename)._system_strescape().data()); - CImg::string(command).move_to(filenames); -#else - cimg_snprintf(command,command._width,"\"%s -delay %u -loop %u", - cimg::imagemagick_path(),(unsigned int)cimg::max(0.0f,cimg::round(100/fps)),nb_loops); - CImg::string(command).move_to(filenames,0); - cimg_snprintf(command,command._width,"\"%s\"\" >NUL 2>&1", - CImg::string(filename)._system_strescape().data()); - CImg::string(command).move_to(filenames); -#endif - CImg _command = filenames>'x'; - cimg_for(_command,p,char) if (!*p) *p = ' '; - _command.back() = 0; - - cimg::system(_command); - file = std_fopen(filename,"rb"); - if (!file) - throw CImgIOException(_cimglist_instance - "save_gif_external(): Failed to save file '%s' with external command 'convert'.", - cimglist_instance, - filename); - else cimg::fclose(file); - cimglist_for_in(*this,1,filenames._width - 1,l) std::remove(filenames[l]); - return *this; - } - - const CImgList& _save_yuv(std::FILE *const file, const char *const filename, const bool is_rgb) const { - if (!file && !filename) - throw CImgArgumentException(_cimglist_instance - "save_yuv(): Specified filename is (null).", - cimglist_instance); - if (is_empty()) { cimg::fempty(file,filename); return *this; } - if ((*this)[0].width()%2 || (*this)[0].height()%2) - throw CImgInstanceException(_cimglist_instance - "save_yuv(): Invalid odd instance dimensions (%u,%u) for file '%s'.", - cimglist_instance, - (*this)[0].width(),(*this)[0].height(), - filename?filename:"(FILE*)"); - - std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); - cimglist_for(*this,l) { - CImg YCbCr((*this)[l]); - if (is_rgb) YCbCr.RGBtoYCbCr(); - cimg::fwrite(YCbCr._data,(size_t)YCbCr._width*YCbCr._height,nfile); - cimg::fwrite(YCbCr.get_resize(YCbCr._width/2, YCbCr._height/2,1,3,3).data(0,0,0,1), - (size_t)YCbCr._width*YCbCr._height/2,nfile); - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Save list as a YUV image sequence file. - /** - \param filename Filename to write data to. - \param is_rgb Tells if the RGB to YUV conversion must be done for saving. - **/ - const CImgList& save_yuv(const char *const filename=0, const bool is_rgb=true) const { - return _save_yuv(0,filename,is_rgb); - } - - //! Save image sequence into a YUV file. - /** - \param file File to write data to. - \param is_rgb Tells if the RGB to YUV conversion must be done for saving. - **/ - const CImgList& save_yuv(std::FILE *const file, const bool is_rgb=true) const { - return _save_yuv(file,0,is_rgb); - } - - const CImgList& _save_cimg(std::FILE *const file, const char *const filename, const bool is_compressed) const { - if (!file && !filename) - throw CImgArgumentException(_cimglist_instance - "save_cimg(): Specified filename is (null).", - cimglist_instance); -#ifndef cimg_use_zlib - if (is_compressed) - cimg::warn(_cimglist_instance - "save_cimg(): Unable to save compressed data in file '%s' unless zlib is enabled, " - "saving them uncompressed.", - cimglist_instance, - filename?filename:"(FILE*)"); -#endif - std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); - const char *const ptype = pixel_type(), *const etype = cimg::endianness()?"big":"little"; - if (std::strstr(ptype,"unsigned")==ptype) std::fprintf(nfile,"%u unsigned_%s %s_endian\n",_width,ptype + 9,etype); - else std::fprintf(nfile,"%u %s %s_endian\n",_width,ptype,etype); - cimglist_for(*this,l) { - const CImg& img = _data[l]; - std::fprintf(nfile,"%u %u %u %u",img._width,img._height,img._depth,img._spectrum); - if (img._data) { - CImg tmp; - if (cimg::endianness()) { tmp = img; cimg::invert_endianness(tmp._data,tmp.size()); } - const CImg& ref = cimg::endianness()?tmp:img; - bool failed_to_compress = true; - if (is_compressed) { -#ifdef cimg_use_zlib - const ulongT siz = sizeof(T)*ref.size(); - uLongf csiz = siz + siz/100 + 16; - Bytef *const cbuf = new Bytef[csiz]; - if (compress(cbuf,&csiz,(Bytef*)ref._data,siz)) - cimg::warn(_cimglist_instance - "save_cimg(): Failed to save compressed data for file '%s', saving them uncompressed.", - cimglist_instance, - filename?filename:"(FILE*)"); - else { - std::fprintf(nfile," #%lu\n",csiz); - cimg::fwrite(cbuf,csiz,nfile); - delete[] cbuf; - failed_to_compress = false; - } -#endif - } - if (failed_to_compress) { // Write in a non-compressed way. - std::fputc('\n',nfile); - cimg::fwrite(ref._data,ref.size(),nfile); - } - } else std::fputc('\n',nfile); - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Save list into a .cimg file. - /** - \param filename Filename to write data to. - \param is_compressed Tells if data compression must be enabled. - **/ - const CImgList& save_cimg(const char *const filename, const bool is_compressed=false) const { - return _save_cimg(0,filename,is_compressed); - } - - //! Save list into a .cimg file. - /** - \param file File to write data to. - \param is_compressed Tells if data compression must be enabled. - **/ - const CImgList& save_cimg(std::FILE *file, const bool is_compressed=false) const { - return _save_cimg(file,0,is_compressed); - } - - const CImgList& _save_cimg(std::FILE *const file, const char *const filename, - const unsigned int n0, - const unsigned int x0, const unsigned int y0, - const unsigned int z0, const unsigned int c0) const { -#define _cimg_save_cimg_case(Ts,Tss) \ - if (!saved && !cimg::strcasecmp(Ts,str_pixeltype)) { \ - for (unsigned int l = 0; l0) { \ - if (l=W || y0>=H || z0>=D || c0>=D) cimg::fseek(nfile,W*H*D*C*sizeof(Tss),SEEK_CUR); \ - else { \ - const CImg& img = (*this)[l - n0]; \ - const T *ptrs = img._data; \ - const unsigned int \ - x1 = x0 + img._width - 1, \ - y1 = y0 + img._height - 1, \ - z1 = z0 + img._depth - 1, \ - c1 = c0 + img._spectrum - 1, \ - nx1 = x1>=W?W - 1:x1, \ - ny1 = y1>=H?H - 1:y1, \ - nz1 = z1>=D?D - 1:z1, \ - nc1 = c1>=C?C - 1:c1; \ - CImg raw(1 + nx1 - x0); \ - const unsigned int skipvb = c0*W*H*D*sizeof(Tss); \ - if (skipvb) cimg::fseek(nfile,skipvb,SEEK_CUR); \ - for (unsigned int v = 1 + nc1 - c0; v; --v) { \ - const unsigned int skipzb = z0*W*H*sizeof(Tss); \ - if (skipzb) cimg::fseek(nfile,skipzb,SEEK_CUR); \ - for (unsigned int z = 1 + nz1 - z0; z; --z) { \ - const unsigned int skipyb = y0*W*sizeof(Tss); \ - if (skipyb) cimg::fseek(nfile,skipyb,SEEK_CUR); \ - for (unsigned int y = 1 + ny1 - y0; y; --y) { \ - const unsigned int skipxb = x0*sizeof(Tss); \ - if (skipxb) cimg::fseek(nfile,skipxb,SEEK_CUR); \ - raw.assign(ptrs, raw._width); \ - ptrs+=img._width; \ - if (endian) cimg::invert_endianness(raw._data,raw._width); \ - cimg::fwrite(raw._data,raw._width,nfile); \ - const unsigned int skipxe = (W - 1 - nx1)*sizeof(Tss); \ - if (skipxe) cimg::fseek(nfile,skipxe,SEEK_CUR); \ - } \ - const unsigned int skipye = (H - 1 - ny1)*W*sizeof(Tss); \ - if (skipye) cimg::fseek(nfile,skipye,SEEK_CUR); \ - } \ - const unsigned int skipze = (D - 1 - nz1)*W*H*sizeof(Tss); \ - if (skipze) cimg::fseek(nfile,skipze,SEEK_CUR); \ - } \ - const unsigned int skipve = (C - 1 - nc1)*W*H*D*sizeof(Tss); \ - if (skipve) cimg::fseek(nfile,skipve,SEEK_CUR); \ - } \ - } \ - } \ - saved = true; \ - } - - if (!file && !filename) - throw CImgArgumentException(_cimglist_instance - "save_cimg(): Specified filename is (null).", - cimglist_instance); - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "save_cimg(): Empty instance, for file '%s'.", - cimglist_instance, - filename?filename:"(FILE*)"); - - std::FILE *const nfile = file?file:cimg::fopen(filename,"rb+"); - bool saved = false, endian = cimg::endianness(); - CImg tmp(256), str_pixeltype(256), str_endian(256); - *tmp = *str_pixeltype = *str_endian = 0; - unsigned int j, N, W, H, D, C; - int i, err; - j = 0; while ((i=std::fgetc(nfile))!='\n' && i!=EOF && j<256) tmp[j++] = (char)i; tmp[j] = 0; - err = cimg_sscanf(tmp,"%u%*c%255[A-Za-z64_]%*c%255[sA-Za-z_ ]",&N,str_pixeltype._data,str_endian._data); - if (err<2) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimglist_instance - "save_cimg(): CImg header not found in file '%s'.", - cimglist_instance, - filename?filename:"(FILE*)"); - } - if (!cimg::strncasecmp("little",str_endian,6)) endian = false; - else if (!cimg::strncasecmp("big",str_endian,3)) endian = true; - const unsigned int lmax = cimg::min(N,n0 + _width); - _cimg_save_cimg_case("bool",bool); - _cimg_save_cimg_case("unsigned_char",unsigned char); - _cimg_save_cimg_case("uchar",unsigned char); - _cimg_save_cimg_case("char",char); - _cimg_save_cimg_case("unsigned_short",unsigned short); - _cimg_save_cimg_case("ushort",unsigned short); - _cimg_save_cimg_case("short",short); - _cimg_save_cimg_case("unsigned_int",unsigned int); - _cimg_save_cimg_case("uint",unsigned int); - _cimg_save_cimg_case("int",int); - _cimg_save_cimg_case("unsigned_int64",uint64T); - _cimg_save_cimg_case("uint64",uint64T); - _cimg_save_cimg_case("int64",int64T); - _cimg_save_cimg_case("float",float); - _cimg_save_cimg_case("double",double); - if (!saved) { - if (!file) cimg::fclose(nfile); - throw CImgIOException(_cimglist_instance - "save_cimg(): Unsupported data type '%s' for file '%s'.", - cimglist_instance, - filename?filename:"(FILE*)",str_pixeltype._data); - } - if (!file) cimg::fclose(nfile); - return *this; - } - - //! Insert the image instance into into an existing .cimg file, at specified coordinates. - /** - \param filename Filename to write data to. - \param n0 Starting index of images to write. - \param x0 Starting X-coordinates of image regions to write. - \param y0 Starting Y-coordinates of image regions to write. - \param z0 Starting Z-coordinates of image regions to write. - \param c0 Starting C-coordinates of image regions to write. - **/ - const CImgList& save_cimg(const char *const filename, - const unsigned int n0, - const unsigned int x0, const unsigned int y0, - const unsigned int z0, const unsigned int c0) const { - return _save_cimg(0,filename,n0,x0,y0,z0,c0); - } - - //! Insert the image instance into into an existing .cimg file, at specified coordinates. - /** - \param file File to write data to. - \param n0 Starting index of images to write. - \param x0 Starting X-coordinates of image regions to write. - \param y0 Starting Y-coordinates of image regions to write. - \param z0 Starting Z-coordinates of image regions to write. - \param c0 Starting C-coordinates of image regions to write. - **/ - const CImgList& save_cimg(std::FILE *const file, - const unsigned int n0, - const unsigned int x0, const unsigned int y0, - const unsigned int z0, const unsigned int c0) const { - return _save_cimg(file,0,n0,x0,y0,z0,c0); - } - - static void _save_empty_cimg(std::FILE *const file, const char *const filename, - const unsigned int nb, - const unsigned int dx, const unsigned int dy, - const unsigned int dz, const unsigned int dc) { - std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); - const ulongT siz = (ulongT)dx*dy*dz*dc*sizeof(T); - std::fprintf(nfile,"%u %s\n",nb,pixel_type()); - for (unsigned int i=nb; i; --i) { - std::fprintf(nfile,"%u %u %u %u\n",dx,dy,dz,dc); - for (ulongT off = siz; off; --off) std::fputc(0,nfile); - } - if (!file) cimg::fclose(nfile); - } - - //! Save empty (non-compressed) .cimg file with specified dimensions. - /** - \param filename Filename to write data to. - \param nb Number of images to write. - \param dx Width of images in the written file. - \param dy Height of images in the written file. - \param dz Depth of images in the written file. - \param dc Spectrum of images in the written file. - **/ - static void save_empty_cimg(const char *const filename, - const unsigned int nb, - const unsigned int dx, const unsigned int dy=1, - const unsigned int dz=1, const unsigned int dc=1) { - return _save_empty_cimg(0,filename,nb,dx,dy,dz,dc); - } - - //! Save empty .cimg file with specified dimensions. - /** - \param file File to write data to. - \param nb Number of images to write. - \param dx Width of images in the written file. - \param dy Height of images in the written file. - \param dz Depth of images in the written file. - \param dc Spectrum of images in the written file. - **/ - static void save_empty_cimg(std::FILE *const file, - const unsigned int nb, - const unsigned int dx, const unsigned int dy=1, - const unsigned int dz=1, const unsigned int dc=1) { - return _save_empty_cimg(file,0,nb,dx,dy,dz,dc); - } - - //! Save list as a TIFF file. - /** - \param filename Filename to write data to. - \param compression_type Compression mode used to write data. - **/ - const CImgList& save_tiff(const char *const filename, const unsigned int compression_type=0, - const float *const voxel_size=0, const char *const description=0, - const bool use_bigtiff=true) const { - if (!filename) - throw CImgArgumentException(_cimglist_instance - "save_tiff(): Specified filename is (null).", - cimglist_instance); - if (is_empty()) { cimg::fempty(0,filename); return *this; } - -#ifndef cimg_use_tiff - if (_width==1) _data[0].save_tiff(filename,compression_type,voxel_size,description,use_bigtiff); - else cimglist_for(*this,l) { - CImg nfilename(1024); - cimg::number_filename(filename,l,6,nfilename); - _data[l].save_tiff(nfilename,compression_type,voxel_size,description,use_bigtiff); - } -#else - ulongT siz = 0; - cimglist_for(*this,l) siz+=_data[l].size(); - const bool _use_bigtiff = use_bigtiff && sizeof(siz)>=8 && siz*sizeof(T)>=1UL<<31; // No bigtiff for small images. - TIFF *tif = TIFFOpen(filename,_use_bigtiff?"w8":"w4"); - if (tif) { - for (unsigned int dir = 0, l = 0; l<_width; ++l) { - const CImg& img = (*this)[l]; - cimg_forZ(img,z) img._save_tiff(tif,dir++,z,compression_type,voxel_size,description); - } - TIFFClose(tif); - } else - throw CImgIOException(_cimglist_instance - "save_tiff(): Failed to open stream for file '%s'.", - cimglist_instance, - filename); -#endif - return *this; - } - - //! Save list as a gzipped file, using external tool 'gzip'. - /** - \param filename Filename to write data to. - **/ - const CImgList& save_gzip_external(const char *const filename) const { - if (!filename) - throw CImgIOException(_cimglist_instance - "save_gzip_external(): Specified filename is (null).", - cimglist_instance); - - CImg command(1024), filename_tmp(256), body(256); - const char - *ext = cimg::split_filename(filename,body), - *ext2 = cimg::split_filename(body,0); - std::FILE *file; - do { - if (!cimg::strcasecmp(ext,"gz")) { - if (*ext2) cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.%s", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),ext2); - else cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.cimg", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand()); - } else { - if (*ext) cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.%s", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),ext); - else cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.cimg", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand()); - } - if ((file=std_fopen(filename_tmp,"rb"))!=0) cimg::fclose(file); - } while (file); - - if (is_saveable(body)) { - save(filename_tmp); - cimg_snprintf(command,command._width,"%s -c \"%s\" > \"%s\"", - cimg::gzip_path(), - CImg::string(filename_tmp)._system_strescape().data(), - CImg::string(filename)._system_strescape().data()); - cimg::system(command); - file = std_fopen(filename,"rb"); - if (!file) - throw CImgIOException(_cimglist_instance - "save_gzip_external(): Failed to save file '%s' with external command 'gzip'.", - cimglist_instance, - filename); - else cimg::fclose(file); - std::remove(filename_tmp); - } else { - CImg nfilename(1024); - cimglist_for(*this,l) { - cimg::number_filename(body,l,6,nfilename); - if (*ext) cimg_sprintf(nfilename._data + std::strlen(nfilename),".%s",ext); - _data[l].save_gzip_external(nfilename); - } - } - return *this; - } - - //! Save image sequence, using the OpenCV library. - /** - \param filename Filename to write data to. - \param fps Number of frames per second. - \param codec Type of compression (See http://www.fourcc.org/codecs.php to see available codecs). - \param keep_open Tells if the video writer associated to the specified filename - must be kept open or not (to allow frames to be added in the same file afterwards). - **/ - const CImgList& save_video(const char *const filename, const unsigned int fps=25, - const char *codec=0, const bool keep_open=false) const { -#ifndef cimg_use_opencv - cimg::unused(codec,keep_open); - return save_ffmpeg_external(filename,fps); -#else - static CvVideoWriter *writers[32] = { 0 }; - static CImgList filenames(32); - static CImg sizes(32,2,1,1,0); - static int last_used_index = -1; - - // Detect if a video writer already exists for the specified filename. - cimg::mutex(9); - int index = -1; - if (filename) { - if (last_used_index>=0 && !std::strcmp(filename,filenames[last_used_index])) { - index = last_used_index; - } else cimglist_for(filenames,l) if (filenames[l] && !std::strcmp(filename,filenames[l])) { - index = l; break; - } - } else index = last_used_index; - cimg::mutex(9,0); - - // Find empty slot for capturing video stream. - if (index<0) { - if (!filename) - throw CImgArgumentException(_cimglist_instance - "save_video(): No already open video writer found. You must specify a " - "non-(null) filename argument for the first call.", - cimglist_instance); - else { cimg::mutex(9); cimglist_for(filenames,l) if (!filenames[l]) { index = l; break; } cimg::mutex(9,0); } - if (index<0) - throw CImgIOException(_cimglist_instance - "save_video(): File '%s', no video writer slots available. " - "You have to release some of your previously opened videos.", - cimglist_instance,filename); - if (is_empty()) - throw CImgInstanceException(_cimglist_instance - "save_video(): Instance list is empty.", - cimglist_instance); - const unsigned int W = _data?_data[0]._width:0, H = _data?_data[0]._height:0; - if (!W || !H) - throw CImgInstanceException(_cimglist_instance - "save_video(): Frame [0] is an empty image.", - cimglist_instance); - -#define _cimg_docase(x) ((x)>='a'&&(x)<='z'?(x) + 'A' - 'a':(x)) - const char - *const _codec = codec && *codec?codec:"mp4v", - codec0 = _cimg_docase(_codec[0]), - codec1 = _codec[0]?_cimg_docase(_codec[1]):0, - codec2 = _codec[1]?_cimg_docase(_codec[2]):0, - codec3 = _codec[2]?_cimg_docase(_codec[3]):0; - cimg::mutex(9); - writers[index] = cvCreateVideoWriter(filename,CV_FOURCC(codec0,codec1,codec2,codec3), - fps,cvSize(W,H)); - CImg::string(filename).move_to(filenames[index]); - sizes(index,0) = W; sizes(index,1) = H; - cimg::mutex(9,0); - if (!writers[index]) - throw CImgIOException(_cimglist_instance - "save_video(): File '%s', unable to initialize video writer with codec '%c%c%c%c'.", - cimglist_instance,filename, - codec0,codec1,codec2,codec3); - } - - if (!is_empty()) { - const unsigned int W = sizes(index,0), H = sizes(index,1); - cimg::mutex(9); - IplImage *ipl = cvCreateImage(cvSize(W,H),8,3); - cimglist_for(*this,l) { - CImg &src = _data[l]; - if (src.is_empty()) - cimg::warn(_cimglist_instance - "save_video(): Skip empty frame %d for file '%s'.", - cimglist_instance,l,filename); - if (src._depth>1 || src._spectrum>3) - cimg::warn(_cimglist_instance - "save_video(): Frame %u has incompatible dimension (%u,%u,%u,%u). " - "Some image data may be ignored when writing frame into video file '%s'.", - cimglist_instance,l,src._width,src._height,src._depth,src._spectrum,filename); - if (src._width==W && src._height==H && src._spectrum==3) { - const T *ptr_r = src.data(0,0,0,0), *ptr_g = src.data(0,0,0,1), *ptr_b = src.data(0,0,0,2); - char *ptrd = ipl->imageData; - cimg_forXY(src,x,y) { - *(ptrd++) = (char)*(ptr_b++); *(ptrd++) = (char)*(ptr_g++); *(ptrd++) = (char)*(ptr_r++); - } - } else { - CImg _src(src,false); - _src.channels(0,cimg::min(_src._spectrum - 1,2U)).resize(W,H); - _src.resize(W,H,1,3,_src._spectrum==1); - const unsigned char *ptr_r = _src.data(0,0,0,0), *ptr_g = _src.data(0,0,0,1), *ptr_b = _src.data(0,0,0,2); - char *ptrd = ipl->imageData; - cimg_forXY(_src,x,y) { - *(ptrd++) = (char)*(ptr_b++); *(ptrd++) = (char)*(ptr_g++); *(ptrd++) = (char)*(ptr_r++); - } - } - cvWriteFrame(writers[index],ipl); - } - cvReleaseImage(&ipl); - cimg::mutex(9,0); - } - - cimg::mutex(9); - if (!keep_open) { - cvReleaseVideoWriter(&writers[index]); - writers[index] = 0; - filenames[index].assign(); - sizes(index,0) = sizes(index,1) = 0; - last_used_index = -1; - } else last_used_index = index; - cimg::mutex(9,0); - - return *this; -#endif - } - - //! Save image sequence, using the external tool 'ffmpeg'. - /** - \param filename Filename to write data to. - \param fps Number of frames per second. - \param codec Type of compression. - \param bitrate Output bitrate - **/ - const CImgList& save_ffmpeg_external(const char *const filename, const unsigned int fps=25, - const char *const codec=0, const unsigned int bitrate=2048) const { - if (!filename) - throw CImgArgumentException(_cimglist_instance - "save_ffmpeg_external(): Specified filename is (null).", - cimglist_instance); - if (is_empty()) { cimg::fempty(0,filename); return *this; } - - const char - *const ext = cimg::split_filename(filename), - *const _codec = codec?codec:!cimg::strcasecmp(ext,"flv")?"flv":"mpeg2video"; - - CImg command(1024), filename_tmp(256), filename_tmp2(256); - CImgList filenames; - std::FILE *file = 0; - cimglist_for(*this,l) if (!_data[l].is_sameXYZ(_data[0])) - throw CImgInstanceException(_cimglist_instance - "save_ffmpeg_external(): Invalid instance dimensions for file '%s'.", - cimglist_instance, - filename); - do { - cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand()); - cimg_snprintf(filename_tmp2,filename_tmp2._width,"%s_000001.ppm",filename_tmp._data); - if ((file=std_fopen(filename_tmp2,"rb"))!=0) cimg::fclose(file); - } while (file); - cimglist_for(*this,l) { - cimg_snprintf(filename_tmp2,filename_tmp2._width,"%s_%.6u.ppm",filename_tmp._data,l + 1); - CImg::string(filename_tmp2).move_to(filenames); - if (_data[l]._depth>1 || _data[l]._spectrum!=3) _data[l].get_resize(-100,-100,1,3).save_pnm(filename_tmp2); - else _data[l].save_pnm(filename_tmp2); - } -#if cimg_OS!=2 - cimg_snprintf(command,command._width,"%s -i \"%s_%%6d.ppm\" -vcodec %s -b %uk -r %u -y \"%s\" >/dev/null 2>&1", - cimg::ffmpeg_path(), - CImg::string(filename_tmp)._system_strescape().data(), - _codec,bitrate,fps, - CImg::string(filename)._system_strescape().data()); -#else - cimg_snprintf(command,command._width,"\"%s -i \"%s_%%6d.ppm\" -vcodec %s -b %uk -r %u -y \"%s\"\" >NUL 2>&1", - cimg::ffmpeg_path(), - CImg::string(filename_tmp)._system_strescape().data(), - _codec,bitrate,fps, - CImg::string(filename)._system_strescape().data()); -#endif - cimg::system(command); - file = std_fopen(filename,"rb"); - if (!file) - throw CImgIOException(_cimglist_instance - "save_ffmpeg_external(): Failed to save file '%s' with external command 'ffmpeg'.", - cimglist_instance, - filename); - else cimg::fclose(file); - cimglist_for(*this,l) std::remove(filenames[l]); - return *this; - } - - //! Serialize a CImgList instance into a raw CImg buffer. - /** - \param is_compressed tells if zlib compression must be used for serialization - (this requires 'cimg_use_zlib' been enabled). - **/ - CImg get_serialize(const bool is_compressed=false) const { -#ifndef cimg_use_zlib - if (is_compressed) - cimg::warn(_cimglist_instance - "get_serialize(): Unable to compress data unless zlib is enabled, " - "storing them uncompressed.", - cimglist_instance); -#endif - CImgList stream; - CImg tmpstr(128); - const char *const ptype = pixel_type(), *const etype = cimg::endianness()?"big":"little"; - if (std::strstr(ptype,"unsigned")==ptype) - cimg_snprintf(tmpstr,tmpstr._width,"%u unsigned_%s %s_endian\n",_width,ptype + 9,etype); - else - cimg_snprintf(tmpstr,tmpstr._width,"%u %s %s_endian\n",_width,ptype,etype); - CImg::string(tmpstr,false).move_to(stream); - cimglist_for(*this,l) { - const CImg& img = _data[l]; - cimg_snprintf(tmpstr,tmpstr._width,"%u %u %u %u",img._width,img._height,img._depth,img._spectrum); - CImg::string(tmpstr,false).move_to(stream); - if (img._data) { - CImg tmp; - if (cimg::endianness()) { tmp = img; cimg::invert_endianness(tmp._data,tmp.size()); } - const CImg& ref = cimg::endianness()?tmp:img; - bool failed_to_compress = true; - if (is_compressed) { -#ifdef cimg_use_zlib - const ulongT siz = sizeof(T)*ref.size(); - uLongf csiz = (ulongT)compressBound(siz); - Bytef *const cbuf = new Bytef[csiz]; - if (compress(cbuf,&csiz,(Bytef*)ref._data,siz)) - cimg::warn(_cimglist_instance - "get_serialize(): Failed to save compressed data, saving them uncompressed.", - cimglist_instance); - else { - cimg_snprintf(tmpstr,tmpstr._width," #%lu\n",csiz); - CImg::string(tmpstr,false).move_to(stream); - CImg(cbuf,csiz).move_to(stream); - delete[] cbuf; - failed_to_compress = false; - } -#endif - } - if (failed_to_compress) { // Write in a non-compressed way. - CImg::string("\n",false).move_to(stream); - stream.insert(1); - stream.back().assign((unsigned char*)ref._data,ref.size()*sizeof(T),1,1,1,true); - } - } else CImg::string("\n",false).move_to(stream); - } - cimglist_apply(stream,unroll)('y'); - return stream>'y'; - } - - //! Unserialize a CImg serialized buffer into a CImgList list. - template - static CImgList get_unserialize(const CImg& buffer) { -#ifdef cimg_use_zlib -#define _cimgz_unserialize_case(Tss) { \ - Bytef *cbuf = (Bytef*)stream; \ - if (sizeof(t)!=1 || cimg::type::string()==cimg::type::string()) { \ - cbuf = new Bytef[csiz]; Bytef *_cbuf = cbuf; \ - for (ulongT i = 0; i raw(W,H,D,C); \ - uLongf destlen = raw.size()*sizeof(Tss); \ - uncompress((Bytef*)raw._data,&destlen,cbuf,csiz); \ - if (!is_bytef) delete[] cbuf; \ - if (endian!=cimg::endianness()) cimg::invert_endianness(raw._data,raw.size()); \ - raw.move_to(img); \ - } -#else -#define _cimgz_unserialize_case(Tss) \ - throw CImgArgumentException("CImgList<%s>::get_unserialize(): Unable to unserialize compressed data " \ - "unless zlib is enabled.", \ - pixel_type()); -#endif - -#define _cimg_unserialize_case(Ts,Tss) \ - if (!loaded && !cimg::strcasecmp(Ts,str_pixeltype)) { \ - for (unsigned int l = 0; l::unserialize(): Invalid specified size (%u,%u,%u,%u) for " \ - "image #%u in serialized buffer.", \ - pixel_type(),W,H,D,C,l); \ - if (W*H*D*C>0) { \ - CImg &img = res._data[l]; \ - if (err==5) _cimgz_unserialize_case(Tss) \ - else { \ - if (sizeof(t)!=1) { \ - CImg raw(W*sizeof(Tss),H,D,C); \ - cimg_for(raw,p,unsigned char) *p = (unsigned char)*(stream++); \ - img.assign((Tss*)raw._data,W,H,D,C); \ - } else img.assign((Tss*)stream,W,H,D,C); \ - if (endian!=cimg::endianness()) cimg::invert_endianness(img._data,img.size()); \ - } \ - } \ - } \ - loaded = true; \ - } - - if (buffer.is_empty()) - throw CImgArgumentException("CImgList<%s>::get_unserialize(): Specified serialized buffer is (null).", - pixel_type()); - CImgList res; - const t *stream = buffer._data, *const estream = buffer._data + buffer.size(); - bool loaded = false, endian = cimg::endianness(), is_bytef = false; - CImg tmp(256), str_pixeltype(256), str_endian(256); - *tmp = *str_pixeltype = *str_endian = 0; - unsigned int j, N = 0, W, H, D, C; - ulongT csiz; - int i, err; - cimg::unused(is_bytef); - do { - j = 0; while ((i=(int)*stream)!='\n' && stream::get_unserialize(): CImg header not found in serialized buffer.", - pixel_type()); - if (!cimg::strncasecmp("little",str_endian,6)) endian = false; - else if (!cimg::strncasecmp("big",str_endian,3)) endian = true; - res.assign(N); - _cimg_unserialize_case("bool",bool); - _cimg_unserialize_case("unsigned_char",unsigned char); - _cimg_unserialize_case("uchar",unsigned char); - _cimg_unserialize_case("char",char); - _cimg_unserialize_case("unsigned_short",unsigned short); - _cimg_unserialize_case("ushort",unsigned short); - _cimg_unserialize_case("short",short); - _cimg_unserialize_case("unsigned_int",unsigned int); - _cimg_unserialize_case("uint",unsigned int); - _cimg_unserialize_case("int",int); - _cimg_unserialize_case("unsigned_int64",uint64T); - _cimg_unserialize_case("uint64",uint64T); - _cimg_unserialize_case("int64",int64T); - _cimg_unserialize_case("float",float); - _cimg_unserialize_case("double",double); - if (!loaded) - throw CImgArgumentException("CImgList<%s>::get_unserialize(): Unsupported pixel type '%s' defined " - "in serialized buffer.", - pixel_type(),str_pixeltype._data); - return res; - } - - //@} - //---------------------------------- - // - //! \name Others - //@{ - //---------------------------------- - - //! Crop font along the X-axis. - /** - **/ - CImgList& crop_font() { - return get_crop_font().move_to(*this); - } - - //! Crop font along the X-axis \newinstance. - /** - **/ - CImgList get_crop_font() const { - CImgList res; - cimglist_for(*this,l) { - const CImg& letter = (*this)[l]; - int xmin = letter.width(), xmax = 0; - cimg_forXY(letter,x,y) if (letter(x,y)) { if (xxmax) xmax = x; } - if (xmin>xmax) CImg(letter._width,letter._height,1,letter._spectrum,0).move_to(res); - else letter.get_crop(xmin,0,xmax,letter._height - 1).move_to(res); - } - res[' '].resize(res['f']._width,-100,-100,-100,0); - if (' ' + 256& font(const unsigned int font_height, const bool is_variable_width=true) { - if (!font_height) return CImgList::const_empty(); - cimg::mutex(11); - - // Decompress nearest base font data if needed. - static const char *data_fonts[] = { cimg::data_font12x13, cimg::data_font20x23, cimg::data_font47x53, 0 }; - static const unsigned int data_widths[] = { 12,20,47,90 }, data_heights[] = { 13,23,53,103 }, - data_Ms[] = { 86,79,57,47 }; - const unsigned int data_ind = font_height<=13U?0U:font_height<=23U?1U:font_height<=53U?2U:3U; - static CImg base_fonts[4]; - CImg &base_font = base_fonts[data_ind]; - if (!base_font) { - const unsigned int w = data_widths[data_ind], h = data_heights[data_ind], M = data_Ms[data_ind]; - base_font.assign(256*w,h); - const char *data_font = data_fonts[data_ind]; - unsigned char *ptrd = base_font; - const unsigned char *const ptrde = base_font.end(); - - // Special case needed for 90x103 to avoid MS compiler limit with big strings. - CImg data90x103; - if (!data_font) { - ((CImg(cimg::_data_font90x103[0], - (unsigned int)std::strlen(cimg::_data_font90x103[0]),1,1,1,true), - CImg(cimg::_data_font90x103[1], - (unsigned int)std::strlen(cimg::_data_font90x103[1]) + 1,1,1,1,true))>'x'). - move_to(data90x103); - data_font = data90x103.data(); - } - - // Uncompress font data (decode RLE). - for (const char *ptrs = data_font; *ptrs; ++ptrs) { - const int c = (int)(*ptrs - M - 32), v = c>=0?255:0, n = c>=0?c:-c; - if (ptrd + n<=ptrde) { std::memset(ptrd,v,n); ptrd+=n; } - else { std::memset(ptrd,v,ptrde - ptrd); break; } - } - } - - // Find optimal font cache location to return. - static CImgList fonts[16]; - static bool is_variable_widths[16] = { 0 }; - unsigned int ind = ~0U; - for (int i = 0; i<16; ++i) - if (!fonts[i] || (is_variable_widths[i]==is_variable_width && font_height==fonts[i][0]._height)) { - ind = (unsigned int)i; break; // Found empty slot or cached font. - } - if (ind==~0U) { // No empty slots nor existing font in cache. - std::memmove(fonts,fonts + 1,15*sizeof(CImgList)); - std::memmove(is_variable_widths,is_variable_widths + 1,15*sizeof(bool)); - std::memset(fonts + (ind=15),0,sizeof(CImgList)); // Free a slot in cache for new font. - } - CImgList &font = fonts[ind]; - - // Render requested font. - if (!font) { - const unsigned int padding_x = font_height<33U?1U:font_height<53U?2U:font_height<103U?3U:4U; - is_variable_widths[ind] = is_variable_width; - font = base_font.get_split('x',256); - if (font_height!=font[0]._height) - cimglist_for(font,l) - font[l].resize(cimg::max(1U,font[l]._width*font_height/font[l]._height),font_height,-100,-100, - font[0]._height>font_height?2:5); - if (is_variable_width) font.crop_font(); - cimglist_for(font,l) font[l].resize(font[l]._width + padding_x,-100,1,1,0,0,0.5); - font.insert(256,0); - cimglist_for_in(font,0,255,l) font[l].assign(font[l + 256]._width,font[l + 256]._height,1,3,1); - } - cimg::mutex(11,0); - return font; - } - - //! Compute a 1d Fast Fourier Transform, along specified axis. - /** - \param axis Axis along which the Fourier transform is computed. - \param invert Tells if the direct (\c false) or inverse transform (\c true) is computed. - **/ - CImgList& FFT(const char axis, const bool invert=false) { - if (is_empty()) return *this; - if (_width==1) insert(1); - if (_width>2) - cimg::warn(_cimglist_instance - "FFT(): Instance has more than 2 images", - cimglist_instance); - - CImg::FFT(_data[0],_data[1],axis,invert); - return *this; - } - - //! Compute a 1-D Fast Fourier Transform, along specified axis \newinstance. - CImgList get_FFT(const char axis, const bool invert=false) const { - return CImgList(*this,false).FFT(axis,invert); - } - - //! Compute a n-d Fast Fourier Transform. - /** - \param invert Tells if the direct (\c false) or inverse transform (\c true) is computed. - **/ - CImgList& FFT(const bool invert=false) { - if (is_empty()) return *this; - if (_width==1) insert(1); - if (_width>2) - cimg::warn(_cimglist_instance - "FFT(): Instance has more than 2 images", - cimglist_instance); - - CImg::FFT(_data[0],_data[1],invert); - return *this; - } - - //! Compute a n-d Fast Fourier Transform \newinstance. - CImgList get_FFT(const bool invert=false) const { - return CImgList(*this,false).FFT(invert); - } - - //! Reverse primitives orientations of a 3d object. - /** - **/ - CImgList& reverse_object3d() { - cimglist_for(*this,l) { - CImg& p = _data[l]; - switch (p.size()) { - case 2 : case 3: cimg::swap(p[0],p[1]); break; - case 6 : cimg::swap(p[0],p[1],p[2],p[4],p[3],p[5]); break; - case 9 : cimg::swap(p[0],p[1],p[3],p[5],p[4],p[6]); break; - case 4 : cimg::swap(p[0],p[1],p[2],p[3]); break; - case 12 : cimg::swap(p[0],p[1],p[2],p[3],p[4],p[6],p[5],p[7],p[8],p[10],p[9],p[11]); break; - } - } - return *this; - } - - //! Reverse primitives orientations of a 3d object \newinstance. - CImgList get_reverse_object3d() const { - return (+*this).reverse_object3d(); - } - - //@} - }; // struct CImgList { ... - - /* - #--------------------------------------------- - # - # Completion of previously declared functions - # - #---------------------------------------------- - */ - -namespace cimg { - - // Open a file (with wide character support on Windows). - inline std::FILE *win_fopen(const char *const path, const char *const mode) { -#if cimg_OS==2 - // Convert 'path' to a wide-character string. - int err = MultiByteToWideChar(CP_UTF8,0,path,-1,0,0); - if (!err) return std::fopen(path,mode); - CImg wpath(err); - err = MultiByteToWideChar(CP_UTF8,0,path,-1,wpath,err); - if (!err) return std::fopen(path,mode); - - // Convert 'mode' to a wide-character string. - err = MultiByteToWideChar(CP_UTF8,0,mode,-1,0,0); - if (!err) return std::fopen(path,mode); - CImg wmode(err); - err = MultiByteToWideChar(CP_UTF8,0,mode,-1,wmode,err); - if (!err) return std::fopen(path,mode); - - return _wfopen(wpath,wmode); -#else - return std::fopen(path,mode); -#endif - } - - //! Get/set path to store temporary files. - /** - \param user_path Specified path, or \c 0 to get the path currently used. - \param reinit_path Force path to be recalculated (may take some time). - \return Path where temporary files can be saved. - **/ - inline const char* temporary_path(const char *const user_path, const bool reinit_path) { -#define _cimg_test_temporary_path(p) \ - if (!path_found) { \ - cimg_snprintf(s_path,s_path.width(),"%s",p); \ - cimg_snprintf(tmp,tmp._width,"%s%c%s",s_path.data(),cimg_file_separator,filename_tmp._data); \ - if ((file=std_fopen(tmp,"wb"))!=0) { cimg::fclose(file); std::remove(tmp); path_found = true; } \ - } - static CImg s_path; - cimg::mutex(7); - if (reinit_path) s_path.assign(); - if (user_path) { - if (!s_path) s_path.assign(1024); - std::strncpy(s_path,user_path,1023); - } else if (!s_path) { - s_path.assign(1024); - bool path_found = false; - CImg tmp(1024), filename_tmp(256); - std::FILE *file = 0; - cimg_snprintf(filename_tmp,filename_tmp._width,"%s.tmp",cimg::filenamerand()); - char *tmpPath = std::getenv("TMP"); - if (!tmpPath) { tmpPath = std::getenv("TEMP"); winformat_string(tmpPath); } - if (tmpPath) _cimg_test_temporary_path(tmpPath); -#if cimg_OS==2 - _cimg_test_temporary_path("C:\\WINNT\\Temp"); - _cimg_test_temporary_path("C:\\WINDOWS\\Temp"); - _cimg_test_temporary_path("C:\\Temp"); - _cimg_test_temporary_path("C:"); - _cimg_test_temporary_path("D:\\WINNT\\Temp"); - _cimg_test_temporary_path("D:\\WINDOWS\\Temp"); - _cimg_test_temporary_path("D:\\Temp"); - _cimg_test_temporary_path("D:"); -#else - _cimg_test_temporary_path("/tmp"); - _cimg_test_temporary_path("/var/tmp"); -#endif - if (!path_found) { - *s_path = 0; - std::strncpy(tmp,filename_tmp,tmp._width - 1); - if ((file=std_fopen(tmp,"wb"))!=0) { cimg::fclose(file); std::remove(tmp); path_found = true; } - } - if (!path_found) { - cimg::mutex(7,0); - throw CImgIOException("cimg::temporary_path(): Failed to locate path for writing temporary files.\n"); - } - } - cimg::mutex(7,0); - return s_path; - } - - //! Get/set path to the Program Files/ directory (Windows only). - /** - \param user_path Specified path, or \c 0 to get the path currently used. - \param reinit_path Force path to be recalculated (may take some time). - \return Path containing the program files. - **/ -#if cimg_OS==2 - inline const char* programfiles_path(const char *const user_path, const bool reinit_path) { - static CImg s_path; - cimg::mutex(7); - if (reinit_path) s_path.assign(); - if (user_path) { - if (!s_path) s_path.assign(1024); - std::strncpy(s_path,user_path,1023); - } else if (!s_path) { - s_path.assign(MAX_PATH); - *s_path = 0; - // Note: in the following line, 0x26 = CSIDL_PROGRAM_FILES (not defined on every compiler). -#if !defined(__INTEL_COMPILER) - if (!SHGetSpecialFolderPathA(0,s_path,0x0026,false)) { - const char *const pfPath = std::getenv("PROGRAMFILES"); - if (pfPath) std::strncpy(s_path,pfPath,MAX_PATH - 1); - else std::strcpy(s_path,"C:\\PROGRA~1"); - } -#else - std::strcpy(s_path,"C:\\PROGRA~1"); -#endif - } - cimg::mutex(7,0); - return s_path; - } -#endif - - //! Get/set path to the ImageMagick's \c convert binary. - /** - \param user_path Specified path, or \c 0 to get the path currently used. - \param reinit_path Force path to be recalculated (may take some time). - \return Path containing the \c convert binary. - **/ - inline const char* imagemagick_path(const char *const user_path, const bool reinit_path) { - static CImg s_path; - cimg::mutex(7); - if (reinit_path) s_path.assign(); - if (user_path) { - if (!s_path) s_path.assign(1024); - std::strncpy(s_path,user_path,1023); - } else if (!s_path) { - s_path.assign(1024); - bool path_found = false; - std::FILE *file = 0; -#if cimg_OS==2 - const char *const pf_path = programfiles_path(); - if (!path_found) { - std::strcpy(s_path,".\\convert.exe"); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=10 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"%s\\IMAGEM~1.%.2d-\\convert.exe",pf_path,k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 9; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"%s\\IMAGEM~1.%d-Q\\convert.exe",pf_path,k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"%s\\IMAGEM~1.%d\\convert.exe",pf_path,k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=10 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"%s\\IMAGEM~1.%.2d-\\VISUA~1\\BIN\\convert.exe",pf_path,k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 9; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"%s\\IMAGEM~1.%d-Q\\VISUA~1\\BIN\\convert.exe",pf_path,k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"%s\\IMAGEM~1.%d\\VISUA~1\\BIN\\convert.exe",pf_path,k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=10 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"C:\\IMAGEM~1.%.2d-\\convert.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 9; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"C:\\IMAGEM~1.%d-Q\\convert.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"C:\\IMAGEM~1.%d\\convert.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=10 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"C:\\IMAGEM~1.%.2d-\\VISUA~1\\BIN\\convert.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 9; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"C:\\IMAGEM~1.%d-Q\\VISUA~1\\BIN\\convert.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"C:\\IMAGEM~1.%d\\VISUA~1\\BIN\\convert.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=10 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"D:\\IMAGEM~1.%.2d-\\convert.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 9; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"D:\\IMAGEM~1.%d-Q\\convert.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"D:\\IMAGEM~1.%d\\convert.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=10 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"D:\\IMAGEM~1.%.2d-\\VISUA~1\\BIN\\convert.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 9; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"D:\\IMAGEM~1.%d-Q\\VISUA~1\\BIN\\convert.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"D:\\IMAGEM~1.%d\\VISUA~1\\BIN\\convert.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) std::strcpy(s_path,"convert.exe"); -#else - if (!path_found) { - std::strcpy(s_path,"./convert"); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) std::strcpy(s_path,"convert"); -#endif - winformat_string(s_path); - } - cimg::mutex(7,0); - return s_path; - } - - //! Get/set path to the GraphicsMagick's \c gm binary. - /** - \param user_path Specified path, or \c 0 to get the path currently used. - \param reinit_path Force path to be recalculated (may take some time). - \return Path containing the \c gm binary. - **/ - inline const char* graphicsmagick_path(const char *const user_path, const bool reinit_path) { - static CImg s_path; - cimg::mutex(7); - if (reinit_path) s_path.assign(); - if (user_path) { - if (!s_path) s_path.assign(1024); - std::strncpy(s_path,user_path,1023); - } else if (!s_path) { - s_path.assign(1024); - bool path_found = false; - std::FILE *file = 0; -#if cimg_OS==2 - const char *const pf_path = programfiles_path(); - if (!path_found) { - std::strcpy(s_path,".\\gm.exe"); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=10 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"%s\\GRAPHI~1.%.2d-\\gm.exe",pf_path,k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 9; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"%s\\GRAPHI~1.%d-Q\\gm.exe",pf_path,k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"%s\\GRAPHI~1.%d\\gm.exe",pf_path,k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=10 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"%s\\GRAPHI~1.%.2d-\\VISUA~1\\BIN\\gm.exe",pf_path,k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 9; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"%s\\GRAPHI~1.%d-Q\\VISUA~1\\BIN\\gm.exe",pf_path,k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"%s\\GRAPHI~1.%d\\VISUA~1\\BIN\\gm.exe",pf_path,k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=10 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"C:\\GRAPHI~1.%.2d-\\gm.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 9; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"C:\\GRAPHI~1.%d-Q\\gm.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"C:\\GRAPHI~1.%d\\gm.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=10 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"C:\\GRAPHI~1.%.2d-\\VISUA~1\\BIN\\gm.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 9; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"C:\\GRAPHI~1.%d-Q\\VISUA~1\\BIN\\gm.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"C:\\GRAPHI~1.%d\\VISUA~1\\BIN\\gm.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=10 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"D:\\GRAPHI~1.%.2d-\\gm.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 9; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"D:\\GRAPHI~1.%d-Q\\gm.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"D:\\GRAPHI~1.%d\\gm.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=10 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"D:\\GRAPHI~1.%.2d-\\VISUA~1\\BIN\\gm.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 9; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"D:\\GRAPHI~1.%d-Q\\VISUA~1\\BIN\\gm.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - for (int k = 32; k>=0 && !path_found; --k) { - cimg_snprintf(s_path,s_path._width,"D:\\GRAPHI~1.%d\\VISUA~1\\BIN\\gm.exe",k); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) std::strcpy(s_path,"gm.exe"); -#else - if (!path_found) { - std::strcpy(s_path,"./gm"); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) std::strcpy(s_path,"gm"); -#endif - winformat_string(s_path); - } - cimg::mutex(7,0); - return s_path; - } - - //! Get/set path to the XMedcon's \c medcon binary. - /** - \param user_path Specified path, or \c 0 to get the path currently used. - \param reinit_path Force path to be recalculated (may take some time). - \return Path containing the \c medcon binary. - **/ - inline const char* medcon_path(const char *const user_path, const bool reinit_path) { - static CImg s_path; - cimg::mutex(7); - if (reinit_path) s_path.assign(); - if (user_path) { - if (!s_path) s_path.assign(1024); - std::strncpy(s_path,user_path,1023); - } else if (!s_path) { - s_path.assign(1024); - bool path_found = false; - std::FILE *file = 0; -#if cimg_OS==2 - const char *const pf_path = programfiles_path(); - if (!path_found) { - std::strcpy(s_path,".\\medcon.exe"); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) { - cimg_snprintf(s_path,s_path._width,"%s\\XMedCon\\bin\\medcon.bat",pf_path); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) { - cimg_snprintf(s_path,s_path._width,"%s\\XMedCon\\bin\\medcon.exe",pf_path); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) { - std::strcpy(s_path,"C:\\XMedCon\\bin\\medcon.exe"); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) std::strcpy(s_path,"medcon.exe"); -#else - if (!path_found) { - std::strcpy(s_path,"./medcon"); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) std::strcpy(s_path,"medcon"); -#endif - winformat_string(s_path); - } - cimg::mutex(7,0); - return s_path; - } - - //! Get/set path to the FFMPEG's \c ffmpeg binary. - /** - \param user_path Specified path, or \c 0 to get the path currently used. - \param reinit_path Force path to be recalculated (may take some time). - \return Path containing the \c ffmpeg binary. - **/ - inline const char *ffmpeg_path(const char *const user_path, const bool reinit_path) { - static CImg s_path; - cimg::mutex(7); - if (reinit_path) s_path.assign(); - if (user_path) { - if (!s_path) s_path.assign(1024); - std::strncpy(s_path,user_path,1023); - } else if (!s_path) { - s_path.assign(1024); - bool path_found = false; - std::FILE *file = 0; -#if cimg_OS==2 - if (!path_found) { - std::strcpy(s_path,".\\ffmpeg.exe"); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) std::strcpy(s_path,"ffmpeg.exe"); -#else - if (!path_found) { - std::strcpy(s_path,"./ffmpeg"); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) std::strcpy(s_path,"ffmpeg"); -#endif - winformat_string(s_path); - } - cimg::mutex(7,0); - return s_path; - } - - //! Get/set path to the \c gzip binary. - /** - \param user_path Specified path, or \c 0 to get the path currently used. - \param reinit_path Force path to be recalculated (may take some time). - \return Path containing the \c gzip binary. - **/ - inline const char *gzip_path(const char *const user_path, const bool reinit_path) { - static CImg s_path; - cimg::mutex(7); - if (reinit_path) s_path.assign(); - if (user_path) { - if (!s_path) s_path.assign(1024); - std::strncpy(s_path,user_path,1023); - } else if (!s_path) { - s_path.assign(1024); - bool path_found = false; - std::FILE *file = 0; -#if cimg_OS==2 - if (!path_found) { - std::strcpy(s_path,".\\gzip.exe"); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) std::strcpy(s_path,"gzip.exe"); -#else - if (!path_found) { - std::strcpy(s_path,"./gzip"); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) std::strcpy(s_path,"gzip"); -#endif - winformat_string(s_path); - } - cimg::mutex(7,0); - return s_path; - } - - //! Get/set path to the \c gunzip binary. - /** - \param user_path Specified path, or \c 0 to get the path currently used. - \param reinit_path Force path to be recalculated (may take some time). - \return Path containing the \c gunzip binary. - **/ - inline const char *gunzip_path(const char *const user_path, const bool reinit_path) { - static CImg s_path; - cimg::mutex(7); - if (reinit_path) s_path.assign(); - if (user_path) { - if (!s_path) s_path.assign(1024); - std::strncpy(s_path,user_path,1023); - } else if (!s_path) { - s_path.assign(1024); - bool path_found = false; - std::FILE *file = 0; -#if cimg_OS==2 - if (!path_found) { - std::strcpy(s_path,".\\gunzip.exe"); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) std::strcpy(s_path,"gunzip.exe"); -#else - if (!path_found) { - std::strcpy(s_path,"./gunzip"); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) std::strcpy(s_path,"gunzip"); -#endif - winformat_string(s_path); - } - cimg::mutex(7,0); - return s_path; - } - - //! Get/set path to the \c dcraw binary. - /** - \param user_path Specified path, or \c 0 to get the path currently used. - \param reinit_path Force path to be recalculated (may take some time). - \return Path containing the \c dcraw binary. - **/ - inline const char *dcraw_path(const char *const user_path, const bool reinit_path) { - static CImg s_path; - cimg::mutex(7); - if (reinit_path) s_path.assign(); - if (user_path) { - if (!s_path) s_path.assign(1024); - std::strncpy(s_path,user_path,1023); - } else if (!s_path) { - s_path.assign(1024); - bool path_found = false; - std::FILE *file = 0; -#if cimg_OS==2 - if (!path_found) { - std::strcpy(s_path,".\\dcraw.exe"); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) std::strcpy(s_path,"dcraw.exe"); -#else - if (!path_found) { - std::strcpy(s_path,"./dcraw"); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) std::strcpy(s_path,"dcraw"); -#endif - winformat_string(s_path); - } - cimg::mutex(7,0); - return s_path; - } - - //! Get/set path to the \c wget binary. - /** - \param user_path Specified path, or \c 0 to get the path currently used. - \param reinit_path Force path to be recalculated (may take some time). - \return Path containing the \c wget binary. - **/ - inline const char *wget_path(const char *const user_path, const bool reinit_path) { - static CImg s_path; - cimg::mutex(7); - if (reinit_path) s_path.assign(); - if (user_path) { - if (!s_path) s_path.assign(1024); - std::strncpy(s_path,user_path,1023); - } else if (!s_path) { - s_path.assign(1024); - bool path_found = false; - std::FILE *file = 0; -#if cimg_OS==2 - if (!path_found) { - std::strcpy(s_path,".\\wget.exe"); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) std::strcpy(s_path,"wget.exe"); -#else - if (!path_found) { - std::strcpy(s_path,"./wget"); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) std::strcpy(s_path,"wget"); -#endif - winformat_string(s_path); - } - cimg::mutex(7,0); - return s_path; - } - - //! Get/set path to the \c curl binary. - /** - \param user_path Specified path, or \c 0 to get the path currently used. - \param reinit_path Force path to be recalculated (may take some time). - \return Path containing the \c curl binary. - **/ - inline const char *curl_path(const char *const user_path, const bool reinit_path) { - static CImg s_path; - cimg::mutex(7); - if (reinit_path) s_path.assign(); - if (user_path) { - if (!s_path) s_path.assign(1024); - std::strncpy(s_path,user_path,1023); - } else if (!s_path) { - s_path.assign(1024); - bool path_found = false; - std::FILE *file = 0; -#if cimg_OS==2 - if (!path_found) { - std::strcpy(s_path,".\\curl.exe"); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) std::strcpy(s_path,"curl.exe"); -#else - if (!path_found) { - std::strcpy(s_path,"./curl"); - if ((file=std_fopen(s_path,"r"))!=0) { cimg::fclose(file); path_found = true; } - } - if (!path_found) std::strcpy(s_path,"curl"); -#endif - winformat_string(s_path); - } - cimg::mutex(7,0); - return s_path; - } - - // [internal] Sorting function, used by cimg::files(). - inline int _sort_files(const void* a, const void* b) { - const CImg &sa = *(CImg*)a, &sb = *(CImg*)b; - return std::strcmp(sa._data,sb._data); - } - - //! Return list of files/directories in specified directory. - /** - \param path Path to the directory. Set to 0 for current directory. - \param is_pattern Tell if specified path has a matching pattern in it. - \param mode Output type, can be primary { 0=files only | 1=folders only | 2=files + folders }. - \param include_path Tell if \c path must be included in resulting filenames. - \return A list of filenames. - **/ - inline CImgList files(const char *const path, const bool is_pattern=false, - const unsigned int mode=2, const bool include_path=false) { - if (!path || !*path) return files("*",true,mode,include_path); - CImgList res; - - // If path is a valid folder name, ignore argument 'is_pattern'. - const bool _is_pattern = is_pattern && !cimg::is_directory(path); - bool is_root = false, is_current = false; - cimg::unused(is_root,is_current); - - // Clean format of input path. - CImg pattern, _path = CImg::string(path); -#if cimg_OS==2 - for (char *ps = _path; *ps; ++ps) if (*ps=='\\') *ps='/'; -#endif - char *pd = _path; - for (char *ps = pd; *ps; ++ps) { if (*ps!='/' || *ps!=*(ps+1)) *(pd++) = *ps; } - *pd = 0; - unsigned int lp = (unsigned int)std::strlen(_path); - if (!_is_pattern && lp && _path[lp - 1]=='/') { - _path[lp - 1] = 0; --lp; -#if cimg_OS!=2 - is_root = !*_path; -#endif - } - - // Separate folder path and matching pattern. - if (_is_pattern) { - const unsigned int bpos = (unsigned int)(cimg::basename(_path,'/') - _path.data()); - CImg::string(_path).move_to(pattern); - if (bpos) { - _path[bpos - 1] = 0; // End 'path' at last slash. -#if cimg_OS!=2 - is_root = !*_path; -#endif - } else { // No path to folder specified, assuming current folder. - is_current = true; *_path = 0; - } - lp = (unsigned int)std::strlen(_path); - } - - // Windows version. -#if cimg_OS==2 - if (!_is_pattern) { - pattern.assign(lp + 3); - std::memcpy(pattern,_path,lp); - pattern[lp] = '/'; pattern[lp + 1] = '*'; pattern[lp + 2] = 0; - } - WIN32_FIND_DATAA file_data; - const HANDLE dir = FindFirstFileA(pattern.data(),&file_data); - if (dir==INVALID_HANDLE_VALUE) return CImgList::const_empty(); - do { - const char *const filename = file_data.cFileName; - if (*filename!='.' || (filename[1] && (filename[1]!='.' || filename[2]))) { - const unsigned int lf = (unsigned int)std::strlen(filename); - const bool is_directory = (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)!=0; - if ((!mode && !is_directory) || (mode==1 && is_directory) || mode>=2) { - if (include_path) { - CImg full_filename((lp?lp+1:0) + lf + 1); - if (lp) { std::memcpy(full_filename,_path,lp); full_filename[lp] = '/'; } - std::memcpy(full_filename._data + (lp?lp + 1:0),filename,lf + 1); - full_filename.move_to(res); - } else CImg(filename,lf + 1).move_to(res); - } - } - } while (FindNextFileA(dir,&file_data)); - FindClose(dir); - - // Unix version (posix). -#else - DIR *const dir = opendir(is_root?"/":is_current?".":_path.data()); - if (!dir) return CImgList::const_empty(); - struct dirent *ent; - while ((ent=readdir(dir))!=0) { - const char *const filename = ent->d_name; - if (*filename!='.' || (filename[1] && (filename[1]!='.' || filename[2]))) { - const unsigned int lf = (unsigned int)std::strlen(filename); - CImg full_filename(lp + lf + 2); - - if (!is_current) { - full_filename.assign(lp + lf + 2); - if (lp) std::memcpy(full_filename,_path,lp); - full_filename[lp] = '/'; - std::memcpy(full_filename._data + lp + 1,filename,lf + 1); - } else full_filename.assign(filename,lf + 1); - - struct stat st; - if (stat(full_filename,&st)==-1) continue; - const bool is_directory = (st.st_mode & S_IFDIR)!=0; - if ((!mode && !is_directory) || (mode==1 && is_directory) || mode==2) { - if (include_path) { - if (!_is_pattern || (_is_pattern && !fnmatch(pattern,full_filename,0))) - full_filename.move_to(res); - } else { - if (!_is_pattern || (_is_pattern && !fnmatch(pattern,full_filename,0))) - CImg(filename,lf + 1).move_to(res); - } - } - } - } - closedir(dir); -#endif - - // Sort resulting list by lexicographic order. - if (res._width>=2) std::qsort(res._data,res._width,sizeof(CImg),_sort_files); - - return res; - } - - //! Try to guess format from an image file. - /** - \param file Input file (can be \c 0 if \c filename is set). - \param filename Filename, as a C-string (can be \c 0 if \c file is set). - \return C-string containing the guessed file format, or \c 0 if nothing has been guessed. - **/ - inline const char *ftype(std::FILE *const file, const char *const filename) { - if (!file && !filename) - throw CImgArgumentException("cimg::ftype(): Specified filename is (null)."); - static const char - *const _pnm = "pnm", - *const _pfm = "pfm", - *const _bmp = "bmp", - *const _gif = "gif", - *const _jpg = "jpg", - *const _off = "off", - *const _pan = "pan", - *const _png = "png", - *const _tif = "tif", - *const _inr = "inr", - *const _dcm = "dcm"; - const char *f_type = 0; - CImg header; - const unsigned int omode = cimg::exception_mode(); - cimg::exception_mode(0); - try { - header._load_raw(file,filename,512,1,1,1,false,false,0); - const unsigned char *const uheader = (unsigned char*)header._data; - if (!std::strncmp(header,"OFF\n",4)) f_type = _off; // OFF. - else if (!std::strncmp(header,"#INRIMAGE",9)) f_type = _inr; // INRIMAGE. - else if (!std::strncmp(header,"PANDORE",7)) f_type = _pan; // PANDORE. - else if (!std::strncmp(header.data() + 128,"DICM",4)) f_type = _dcm; // DICOM. - else if (uheader[0]==0xFF && uheader[1]==0xD8 && uheader[2]==0xFF) f_type = _jpg; // JPEG. - else if (header[0]=='B' && header[1]=='M') f_type = _bmp; // BMP. - else if (header[0]=='G' && header[1]=='I' && header[2]=='F' && header[3]=='8' && header[5]=='a' && // GIF. - (header[4]=='7' || header[4]=='9')) f_type = _gif; - else if (uheader[0]==0x89 && uheader[1]==0x50 && uheader[2]==0x4E && uheader[3]==0x47 && // PNG. - uheader[4]==0x0D && uheader[5]==0x0A && uheader[6]==0x1A && uheader[7]==0x0A) f_type = _png; - else if ((uheader[0]==0x49 && uheader[1]==0x49) || (uheader[0]==0x4D && uheader[1]==0x4D)) f_type = _tif; // TIFF. - else { // PNM or PFM. - CImgList _header = header.get_split(CImg::vector('\n'),0,false); - cimglist_for(_header,l) { - if (_header(l,0)=='#') continue; - if (_header[l]._height==2 && _header(l,0)=='P') { - const char c = _header(l,1); - if (c=='f' || c=='F') { f_type = _pfm; break; } - if (c>='1' && c<='9') { f_type = _pnm; break; } - } - f_type = 0; break; - } - } - } catch (CImgIOException&) { } - cimg::exception_mode(omode); - return f_type; - } - - //! Load file from network as a local temporary file. - /** - \param filename Filename, as a C-string. - \param[out] filename_local C-string containing the path to a local copy of \c filename. - \param timeout Maximum time (in seconds) authorized for downloading the file from the URL. - \param try_fallback When using libcurl, tells using system calls as fallbacks in case of libcurl failure. - \return Value of \c filename_local. - \note Use the \c libcurl library, or the external binaries \c wget or \c curl to perform the download. - **/ - inline char *load_network(const char *const url, char *const filename_local, - const unsigned int timeout, const bool try_fallback, - const char *const referer) { - if (!url) - throw CImgArgumentException("cimg::load_network(): Specified URL is (null)."); - if (!filename_local) - throw CImgArgumentException("cimg::load_network(): Specified destination string is (null)."); - - const char *const __ext = cimg::split_filename(url), *const _ext = (*__ext && __ext>url)?__ext - 1:__ext; - CImg ext = CImg::string(_ext); - std::FILE *file = 0; - *filename_local = 0; - if (ext._width>16 || !cimg::strncasecmp(ext,"cgi",3)) *ext = 0; - else cimg::strwindows_reserved(ext); - do { - cimg_snprintf(filename_local,256,"%s%c%s%s", - cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),ext._data); - if ((file=std_fopen(filename_local,"rb"))!=0) cimg::fclose(file); - } while (file); - -#ifdef cimg_use_curl - const unsigned int omode = cimg::exception_mode(); - cimg::exception_mode(0); - try { - CURL *curl = 0; - CURLcode res; - curl = curl_easy_init(); - if (curl) { - file = cimg::fopen(filename_local,"wb"); - curl_easy_setopt(curl,CURLOPT_URL,url); - curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,0); - curl_easy_setopt(curl,CURLOPT_WRITEDATA,file); - curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,0L); - curl_easy_setopt(curl,CURLOPT_SSL_VERIFYHOST,0L); - curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION,1L); - if (timeout) curl_easy_setopt(curl,CURLOPT_TIMEOUT,(long)timeout); - if (std::strchr(url,'?')) curl_easy_setopt(curl,CURLOPT_HTTPGET,1L); - if (referer) curl_easy_setopt(curl,CURLOPT_REFERER,referer); - res = curl_easy_perform(curl); - curl_easy_cleanup(curl); - cimg::fseek(file,0,SEEK_END); // Check if file size is 0. - const cimg_ulong siz = cimg::ftell(file); - cimg::fclose(file); - if (siz>0 && res==CURLE_OK) { - cimg::exception_mode(omode); - return filename_local; - } else std::remove(filename_local); - } - } catch (...) { } - cimg::exception_mode(omode); - if (!try_fallback) throw CImgIOException("cimg::load_network(): Failed to load file '%s' with libcurl.",url); -#endif - - CImg command((unsigned int)std::strlen(url) + 64); - cimg::unused(try_fallback); - - // Try with 'curl' first. - if (timeout) { - if (referer) - cimg_snprintf(command,command._width,"%s -e %s -m %u -f --silent --compressed -o \"%s\" \"%s\"", - cimg::curl_path(),referer,timeout,filename_local,url); - else - cimg_snprintf(command,command._width,"%s -m %u -f --silent --compressed -o \"%s\" \"%s\"", - cimg::curl_path(),timeout,filename_local,url); - } else { - if (referer) - cimg_snprintf(command,command._width,"%s -e %s -f --silent --compressed -o \"%s\" \"%s\"", - cimg::curl_path(),referer,filename_local,url); - else - cimg_snprintf(command,command._width,"%s -f --silent --compressed -o \"%s\" \"%s\"", - cimg::curl_path(),filename_local,url); - } - cimg::system(command); - - if (!(file = std_fopen(filename_local,"rb"))) { - - // Try with 'wget' otherwise. - if (timeout) { - if (referer) - cimg_snprintf(command,command._width,"%s --referer=%s -T %u -q -r -l 0 --no-cache -O \"%s\" \"%s\"", - cimg::wget_path(),referer,timeout,filename_local,url); - else - cimg_snprintf(command,command._width,"%s -T %u -q -r -l 0 --no-cache -O \"%s\" \"%s\"", - cimg::wget_path(),timeout,filename_local,url); - } else { - if (referer) - cimg_snprintf(command,command._width,"%s --referer=%s -q -r -l 0 --no-cache -O \"%s\" \"%s\"", - cimg::wget_path(),referer,filename_local,url); - else - cimg_snprintf(command,command._width,"%s -q -r -l 0 --no-cache -O \"%s\" \"%s\"", - cimg::wget_path(),filename_local,url); - } - cimg::system(command); - - if (!(file = std_fopen(filename_local,"rb"))) - throw CImgIOException("cimg::load_network(): Failed to load file '%s' with external commands " - "'wget' or 'curl'.",url); - cimg::fclose(file); - - // Try gunzip it. - cimg_snprintf(command,command._width,"%s.gz",filename_local); - std::rename(filename_local,command); - cimg_snprintf(command,command._width,"%s --quiet \"%s.gz\"", - gunzip_path(),filename_local); - cimg::system(command); - file = std_fopen(filename_local,"rb"); - if (!file) { - cimg_snprintf(command,command._width,"%s.gz",filename_local); - std::rename(command,filename_local); - file = std_fopen(filename_local,"rb"); - } - } - cimg::fseek(file,0,SEEK_END); // Check if file size is 0. - if (std::ftell(file)<=0) - throw CImgIOException("cimg::load_network(): Failed to load URL '%s' with external commands " - "'wget' or 'curl'.",url); - cimg::fclose(file); - return filename_local; - } - - // Implement a tic/toc mechanism to display elapsed time of algorithms. - inline cimg_ulong tictoc(const bool is_tic) { - cimg::mutex(2); - static CImg times(64); - static unsigned int pos = 0; - const cimg_ulong t1 = cimg::time(); - if (is_tic) { // Tic. - times[pos++] = t1; - if (pos>=times._width) - throw CImgArgumentException("cimg::tic(): Too much calls to 'cimg::tic()' without calls to 'cimg::toc()'."); - cimg::mutex(2,0); - return t1; - } - // Toc. - if (!pos) - throw CImgArgumentException("cimg::toc(): No previous call to 'cimg::tic()' has been made."); - const cimg_ulong - t0 = times[--pos], - dt = t1>=t0?(t1 - t0):cimg::type::max(); - const unsigned int - edays = (unsigned int)(dt/86400000.0), - ehours = (unsigned int)((dt - edays*86400000.0)/3600000.0), - emin = (unsigned int)((dt - edays*86400000.0 - ehours*3600000.0)/60000.0), - esec = (unsigned int)((dt - edays*86400000.0 - ehours*3600000.0 - emin*60000.0)/1000.0), - ems = (unsigned int)(dt - edays*86400000.0 - ehours*3600000.0 - emin*60000.0 - esec*1000.0); - if (!edays && !ehours && !emin && !esec) - std::fprintf(cimg::output(),"%s[CImg]%*sElapsed time: %u ms%s\n", - cimg::t_red,1 + 2*pos,"",ems,cimg::t_normal); - else { - if (!edays && !ehours && !emin) - std::fprintf(cimg::output(),"%s[CImg]%*sElapsed time: %u sec %u ms%s\n", - cimg::t_red,1 + 2*pos,"",esec,ems,cimg::t_normal); - else { - if (!edays && !ehours) - std::fprintf(cimg::output(),"%s[CImg]%*sElapsed time: %u min %u sec %u ms%s\n", - cimg::t_red,1 + 2*pos,"",emin,esec,ems,cimg::t_normal); - else{ - if (!edays) - std::fprintf(cimg::output(),"%s[CImg]%*sElapsed time: %u hours %u min %u sec %u ms%s\n", - cimg::t_red,1 + 2*pos,"",ehours,emin,esec,ems,cimg::t_normal); - else{ - std::fprintf(cimg::output(),"%s[CImg]%*sElapsed time: %u days %u hours %u min %u sec %u ms%s\n", - cimg::t_red,1 + 2*pos,"",edays,ehours,emin,esec,ems,cimg::t_normal); - } - } - } - } - cimg::mutex(2,0); - return dt; - } - - // Return a temporary string describing the size of a memory buffer. - inline const char *strbuffersize(const cimg_ulong size) { - static CImg res(256); - cimg::mutex(5); - if (size<1024LU) cimg_snprintf(res,res._width,"%lu byte%s",size,size>1?"s":""); - else if (size<1024*1024LU) { const float nsize = size/1024.0f; cimg_snprintf(res,res._width,"%.1f Kio",nsize); } - else if (size<1024*1024*1024LU) { - const float nsize = size/(1024*1024.0f); cimg_snprintf(res,res._width,"%.1f Mio",nsize); - } else { const float nsize = size/(1024*1024*1024.0f); cimg_snprintf(res,res._width,"%.1f Gio",nsize); } - cimg::mutex(5,0); - return res; - } - - //! Display a simple dialog box, and wait for the user's response. - /** - \param title Title of the dialog window. - \param msg Main message displayed inside the dialog window. - \param button1_label Label of the 1st button. - \param button2_label Label of the 2nd button (\c 0 to hide button). - \param button3_label Label of the 3rd button (\c 0 to hide button). - \param button4_label Label of the 4th button (\c 0 to hide button). - \param button5_label Label of the 5th button (\c 0 to hide button). - \param button6_label Label of the 6th button (\c 0 to hide button). - \param logo Image logo displayed at the left of the main message. - \param is_centered Tells if the dialog window must be centered on the screen. - \return Indice of clicked button (from \c 0 to \c 5), or \c -1 if the dialog window has been closed by the user. - \note - - Up to 6 buttons can be defined in the dialog window. - - The function returns when a user clicked one of the button or closed the dialog window. - - If a button text is set to 0, the corresponding button (and the followings) will not appear in the dialog box. - At least one button must be specified. - **/ - template - inline int dialog(const char *const title, const char *const msg, - const char *const button1_label, const char *const button2_label, - const char *const button3_label, const char *const button4_label, - const char *const button5_label, const char *const button6_label, - const CImg& logo, const bool is_centered=false) { -#if cimg_display==0 - cimg::unused(title,msg,button1_label,button2_label,button3_label,button4_label,button5_label,button6_label, - logo._data,is_centered); - throw CImgIOException("cimg::dialog(): No display available."); -#else - static const unsigned char - black[] = { 0,0,0 }, white[] = { 255,255,255 }, gray[] = { 200,200,200 }, gray2[] = { 150,150,150 }; - - // Create buttons and canvas graphics - CImgList buttons, cbuttons, sbuttons; - if (button1_label) { CImg().draw_text(0,0,button1_label,black,gray,1,13).move_to(buttons); - if (button2_label) { CImg().draw_text(0,0,button2_label,black,gray,1,13).move_to(buttons); - if (button3_label) { CImg().draw_text(0,0,button3_label,black,gray,1,13).move_to(buttons); - if (button4_label) { CImg().draw_text(0,0,button4_label,black,gray,1,13).move_to(buttons); - if (button5_label) { CImg().draw_text(0,0,button5_label,black,gray,1,13).move_to(buttons); - if (button6_label) { CImg().draw_text(0,0,button6_label,black,gray,1,13).move_to(buttons); - }}}}}} - if (!buttons._width) - throw CImgArgumentException("cimg::dialog(): No buttons have been defined."); - cimglist_for(buttons,l) buttons[l].resize(-100,-100,1,3); - - unsigned int bw = 0, bh = 0; - cimglist_for(buttons,l) { bw = cimg::max(bw,buttons[l]._width); bh = cimg::max(bh,buttons[l]._height); } - bw+=8; bh+=8; - if (bw<64) bw = 64; - if (bw>128) bw = 128; - if (bh<24) bh = 24; - if (bh>48) bh = 48; - - CImg button(bw,bh,1,3); - button.draw_rectangle(0,0,bw - 1,bh - 1,gray); - button.draw_line(0,0,bw - 1,0,white).draw_line(0,bh - 1,0,0,white); - button.draw_line(bw - 1,0,bw - 1,bh - 1,black).draw_line(bw - 1,bh - 1,0,bh - 1,black); - button.draw_line(1,bh - 2,bw - 2,bh - 2,gray2).draw_line(bw - 2,bh - 2,bw - 2,1,gray2); - CImg sbutton(bw,bh,1,3); - sbutton.draw_rectangle(0,0,bw - 1,bh - 1,gray); - sbutton.draw_line(0,0,bw - 1,0,black).draw_line(bw - 1,0,bw - 1,bh - 1,black); - sbutton.draw_line(bw - 1,bh - 1,0,bh - 1,black).draw_line(0,bh - 1,0,0,black); - sbutton.draw_line(1,1,bw - 2,1,white).draw_line(1,bh - 2,1,1,white); - sbutton.draw_line(bw - 2,1,bw - 2,bh - 2,black).draw_line(bw - 2,bh - 2,1,bh - 2,black); - sbutton.draw_line(2,bh - 3,bw - 3,bh - 3,gray2).draw_line(bw - 3,bh - 3,bw - 3,2,gray2); - sbutton.draw_line(4,4,bw - 5,4,black,1,0xAAAAAAAA,true).draw_line(bw - 5,4,bw - 5,bh - 5,black,1,0xAAAAAAAA,false); - sbutton.draw_line(bw - 5,bh - 5,4,bh - 5,black,1,0xAAAAAAAA,false).draw_line(4,bh - 5,4,4,black,1,0xAAAAAAAA,false); - CImg cbutton(bw,bh,1,3); - cbutton.draw_rectangle(0,0,bw - 1,bh - 1,black).draw_rectangle(1,1,bw - 2,bh - 2,gray2). - draw_rectangle(2,2,bw - 3,bh - 3,gray); - cbutton.draw_line(4,4,bw - 5,4,black,1,0xAAAAAAAA,true).draw_line(bw - 5,4,bw - 5,bh - 5,black,1,0xAAAAAAAA,false); - cbutton.draw_line(bw - 5,bh - 5,4,bh - 5,black,1,0xAAAAAAAA,false).draw_line(4,bh - 5,4,4,black,1,0xAAAAAAAA,false); - - cimglist_for(buttons,ll) { - CImg(cbutton). - draw_image(1 + (bw -buttons[ll].width())/2,1 + (bh - buttons[ll].height())/2,buttons[ll]). - move_to(cbuttons); - CImg(sbutton). - draw_image((bw - buttons[ll].width())/2,(bh - buttons[ll].height())/2,buttons[ll]). - move_to(sbuttons); - CImg(button). - draw_image((bw - buttons[ll].width())/2,(bh - buttons[ll].height())/2,buttons[ll]). - move_to(buttons[ll]); - } - - CImg canvas; - if (msg) - ((CImg().draw_text(0,0,"%s",gray,0,1,13,msg)*=-1)+=200).resize(-100,-100,1,3).move_to(canvas); - - const unsigned int - bwall = (buttons._width - 1)*(12 + bw) + bw, - w = cimg::max(196U,36 + logo._width + canvas._width,24 + bwall), - h = cimg::max(96U,36 + canvas._height + bh,36 + logo._height + bh), - lx = 12 + (canvas._data?0:((w - 24 - logo._width)/2)), - ly = (h - 12 - bh - logo._height)/2, - tx = lx + logo._width + 12, - ty = (h - 12 - bh - canvas._height)/2, - bx = (w - bwall)/2, - by = h - 12 - bh; - - if (canvas._data) - canvas = CImg(w,h,1,3). - draw_rectangle(0,0,w - 1,h - 1,gray). - draw_line(0,0,w - 1,0,white).draw_line(0,h - 1,0,0,white). - draw_line(w - 1,0,w - 1,h - 1,black).draw_line(w - 1,h - 1,0,h - 1,black). - draw_image(tx,ty,canvas); - else - canvas = CImg(w,h,1,3). - draw_rectangle(0,0,w - 1,h - 1,gray). - draw_line(0,0,w - 1,0,white).draw_line(0,h - 1,0,0,white). - draw_line(w - 1,0,w - 1,h - 1,black).draw_line(w - 1,h - 1,0,h - 1,black); - if (logo._data) canvas.draw_image(lx,ly,logo); - - unsigned int xbuttons[6] = { 0 }; - cimglist_for(buttons,lll) { xbuttons[lll] = bx + (bw + 12)*lll; canvas.draw_image(xbuttons[lll],by,buttons[lll]); } - - // Open window and enter events loop - CImgDisplay disp(canvas,title?title:" ",0,false,is_centered?true:false); - if (is_centered) disp.move((CImgDisplay::screen_width() - disp.width())/2, - (CImgDisplay::screen_height() - disp.height())/2); - bool stop_flag = false, refresh = false; - int oselected = -1, oclicked = -1, selected = -1, clicked = -1; - while (!disp.is_closed() && !stop_flag) { - if (refresh) { - if (clicked>=0) - CImg(canvas).draw_image(xbuttons[clicked],by,cbuttons[clicked]).display(disp); - else { - if (selected>=0) - CImg(canvas).draw_image(xbuttons[selected],by,sbuttons[selected]).display(disp); - else canvas.display(disp); - } - refresh = false; - } - disp.wait(15); - if (disp.is_resized()) disp.resize(disp,false); - - if (disp.button()&1) { - oclicked = clicked; - clicked = -1; - cimglist_for(buttons,l) - if (disp.mouse_y()>=(int)by && disp.mouse_y()<(int)(by + bh) && - disp.mouse_x()>=(int)xbuttons[l] && disp.mouse_x()<(int)(xbuttons[l] + bw)) { - clicked = selected = l; - refresh = true; - } - if (clicked!=oclicked) refresh = true; - } else if (clicked>=0) stop_flag = true; - - if (disp.key()) { - oselected = selected; - switch (disp.key()) { - case cimg::keyESC : selected = -1; stop_flag = true; break; - case cimg::keyENTER : if (selected<0) selected = 0; stop_flag = true; break; - case cimg::keyTAB : - case cimg::keyARROWRIGHT : - case cimg::keyARROWDOWN : selected = (selected + 1)%buttons.width(); break; - case cimg::keyARROWLEFT : - case cimg::keyARROWUP : selected = (selected + buttons.width() - 1)%buttons.width(); break; - } - disp.set_key(); - if (selected!=oselected) refresh = true; - } - } - if (!disp) selected = -1; - return selected; -#endif - } - - //! Display a simple dialog box, and wait for the user's response \specialization. - inline int dialog(const char *const title, const char *const msg, - const char *const button1_label, const char *const button2_label, const char *const button3_label, - const char *const button4_label, const char *const button5_label, const char *const button6_label, - const bool is_centered) { - return dialog(title,msg,button1_label,button2_label,button3_label,button4_label,button5_label,button6_label, - CImg::_logo40x38(),is_centered); - } - - //! Evaluate math expression. - /** - \param expression C-string describing the formula to evaluate. - \param x Value of the pre-defined variable \c x. - \param y Value of the pre-defined variable \c y. - \param z Value of the pre-defined variable \c z. - \param c Value of the pre-defined variable \c c. - \return Result of the formula evaluation. - \note Set \c expression to \c 0 to keep evaluating the last specified \c expression. - \par Example - \code - const double - res1 = cimg::eval("cos(x)^2 + sin(y)^2",2,2), // will return '1'. - res2 = cimg::eval(0,1,1); // will return '1' too. - \endcode - **/ - inline double eval(const char *const expression, const double x, const double y, const double z, const double c) { - static const CImg empty; - return empty.eval(expression,x,y,z,c); - } - - template - inline CImg::type> eval(const char *const expression, const CImg& xyzc) { - static const CImg empty; - return empty.eval(expression,xyzc); - } - - // End of cimg:: namespace -} - - // End of cimg_library:: namespace -} - -//! Short alias name. -namespace cil = cimg_library_suffixed; - -#ifdef _cimg_redefine_False -#define False 0 -#endif -#ifdef _cimg_redefine_True -#define True 1 -#endif -#ifdef _cimg_redefine_None -#define None 0 -#endif -#ifdef _cimg_redefine_min -#define min(a,b) (((a)<(b))?(a):(b)) -#endif -#ifdef _cimg_redefine_max -#define max(a,b) (((a)>(b))?(a):(b)) -#endif -#ifdef _cimg_redefine_PI -#define PI 3.141592653589793238462643383 -#endif -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -#endif -// Local Variables: -// mode: c++ -// End: diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/CImgConfig.cmake.in b/applications/plugins/CImgPlugin/extlibs/CImg/CImgConfig.cmake.in deleted file mode 100644 index 636e273d268..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/CImgConfig.cmake.in +++ /dev/null @@ -1,8 +0,0 @@ -# CMake package configuration file for the CImg library. -# It defines the following variable: -# - CImg_INCLUDE_DIRS - -@PACKAGE_GUARD@ -@PACKAGE_INIT@ - -set(CImg_INCLUDE_DIRS "@CIMG_INCLUDE_DIR@") diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/CMakeLists.txt b/applications/plugins/CImgPlugin/extlibs/CImg/CMakeLists.txt deleted file mode 100644 index 9eb22aef6c6..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -cmake_minimum_required(VERSION 3.12) - -project(CImg) - -install(FILES - CImg.h - DESTINATION include/CImg - COMPONENT CImg_headers) - -install(DIRECTORY - plugins - DESTINATION include/CImg - COMPONENT CImg_headers) - - -include(CMakePackageConfigHelpers) - -### CImgConfig.cmake -## Build tree -set(CIMG_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..") -configure_file(CImgConfig.cmake.in ${CMAKE_BINARY_DIR}/lib/cmake/CImgConfig.cmake) - -## Install tree -set(CIMG_INCLUDE_DIR include) -configure_file(CImgConfig.cmake.in InstalledCImgConfig.cmake) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/InstalledCImgConfig.cmake - DESTINATION lib/cmake/CImg - RENAME CImgConfig.cmake) diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/Licence_CeCILL-C_V1-en.txt b/applications/plugins/CImgPlugin/extlibs/CImg/Licence_CeCILL-C_V1-en.txt deleted file mode 100644 index 2e9ffbaca59..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/Licence_CeCILL-C_V1-en.txt +++ /dev/null @@ -1,508 +0,0 @@ - - CeCILL-C FREE SOFTWARE LICENSE AGREEMENT - - - Notice - -This Agreement is a Free Software license agreement that is the result -of discussions between its authors in order to ensure compliance with -the two main principles guiding its drafting: - - * firstly, compliance with the principles governing the distribution - of Free Software: access to source code, broad rights granted to - users, - * secondly, the election of a governing law, French law, with which - it is conformant, both as regards the law of torts and - intellectual property law, and the protection that it offers to - both authors and holders of the economic rights over software. - -The authors of the CeCILL-C (for Ce[a] C[nrs] I[nria] L[logiciel] L[ibre]) -license are: - -Commissariat l'Energie Atomique - CEA, a public scientific, technical -and industrial research establishment, having its principal place of -business at 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris, France. - -Centre National de la Recherche Scientifique - CNRS, a public scientific -and technological establishment, having its principal place of business -at 3 rue Michel-Ange, 75794 Paris cedex 16, France. - -Institut National de Recherche en Informatique et en Automatique - -INRIA, a public scientific and technological establishment, having its -principal place of business at Domaine de Voluceau, Rocquencourt, BP -105, 78153 Le Chesnay cedex, France. - - - Preamble - -The purpose of this Free Software license agreement is to grant users the -right to modify and re-use the software governed by this license. - -The exercising of this right is conditional on the obligation to make -available to the community the modifications made to the source code of the -software so as to contribute to its evolution. - -In consideration of access to the source code and the rights to copy, -modify and redistribute granted by the license, users are provided only -with a limited warranty and the software's author, the holder of the -economic rights, and the successive licensors only have limited liability. - -In this respect, the risks associated with loading, using, modifying -and/or developing or reproducing the software by the user are brought to -the user's attention, given its Free Software status, which may make it -complicated to use, with the result that its use is reserved for -developers and experienced professionals having in-depth computer -knowledge. Users are therefore encouraged to load and test the suitability -of the software as regards their requirements in conditions enabling the -security of their systems and/or data to be ensured and, more generally, to -use and operate it in the same conditions of security. This Agreement may be -freely reproduced and published, provided it is not altered, and that no -provisions are either added or removed herefrom. - -This Agreement may apply to any or all software for which the holder of -the economic rights decides to submit the use thereof to its provisions. - - - Article 1 - DEFINITIONS - -For the purpose of this Agreement, when the following expressions -commence with a capital letter, they shall have the following meaning: - -Agreement: means this license agreement, and its possible subsequent -versions and annexes. - -Software: means the software in its Object Code and/or Source Code form -and, where applicable, its documentation, "as is" when the Licensee -accepts the Agreement. - -Initial Software: means the Software in its Source Code and possibly its -Object Code form and, where applicable, its documentation, "as is" when -it is first distributed under the terms and conditions of the Agreement. - -Modified Software: means the Software modified by at least one Integrated -Contribution. - -Source Code: means all the Software's instructions and program lines to -which access is required so as to modify the Software. - -Object Code: means the binary files originating from the compilation of -the Source Code. - -Holder: means the holder(s) of the economic rights over the Initial -Software. - -Licensee: means the Software user(s) having accepted the Agreement. - -Contributor: means a Licensee having made at least one Integrated -Contribution. - -Licensor: means the Holder, or any other individual or legal entity, who -distributes the Software under the Agreement. - -Integrated Contribution: means any or all modifications, corrections, -translations, adaptations and/or new functions integrated into the Source -Code by any or all Contributors. - -Related Module: means a set of sources files including their documentation -that, without modification to the Source Code, enables supplementary -functions or services in addition to those offered by the Software. - -Derivative Software: means any combination of the Software, modified or not, -and of a Related Module. - -Parties: mean both the Licensee and the Licensor. - -These expressions may be used both in singular and plural form. - - - Article 2 - PURPOSE - -The purpose of the Agreement is the grant by the Licensor to the -Licensee of a non-exclusive, transferable and worldwide license for the -Software as set forth in Article 5 hereinafter for the whole term of the -protection granted by the rights over said Software. - - - Article 3 - ACCEPTANCE - -3.1 The Licensee shall be deemed as having accepted the terms and -conditions of this Agreement upon the occurrence of the first of the -following events: - - * (i) loading the Software by any or all means, notably, by - downloading from a remote server, or by loading from a physical - medium; - * (ii) the first time the Licensee exercises any of the rights - granted hereunder. - -3.2 One copy of the Agreement, containing a notice relating to the -characteristics of the Software, to the limited warranty, and to the -fact that its use is restricted to experienced users has been provided -to the Licensee prior to its acceptance as set forth in Article 3.1 -hereinabove, and the Licensee hereby acknowledges that it has read and -understood it. - - - Article 4 - EFFECTIVE DATE AND TERM - - - 4.1 EFFECTIVE DATE - -The Agreement shall become effective on the date when it is accepted by -the Licensee as set forth in Article 3.1. - - - 4.2 TERM - -The Agreement shall remain in force for the entire legal term of -protection of the economic rights over the Software. - - - Article 5 - SCOPE OF RIGHTS GRANTED - -The Licensor hereby grants to the Licensee, who accepts, the following -rights over the Software for any or all use, and for the term of the -Agreement, on the basis of the terms and conditions set forth hereinafter. - -Besides, if the Licensor owns or comes to own one or more patents -protecting all or part of the functions of the Software or of its -components, the Licensor undertakes not to enforce the rights granted by -these patents against successive Licensees using, exploiting or -modifying the Software. If these patents are transferred, the Licensor -undertakes to have the transferees subscribe to the obligations set -forth in this paragraph. - - - 5.1 RIGHT OF USE - -The Licensee is authorized to use the Software, without any limitation -as to its fields of application, with it being hereinafter specified -that this comprises: - - 1. permanent or temporary reproduction of all or part of the Software - by any or all means and in any or all form. - 2. loading, displaying, running, or storing the Software on any or - all medium. - 3. entitlement to observe, study or test its operation so as to - determine the ideas and principles behind any or all constituent - elements of said Software. This shall apply when the Licensee - carries out any or all loading, displaying, running, transmission - or storage operation as regards the Software, that it is entitled - to carry out hereunder. - - - 5.2 RIGHT OF MODIFICATION - -The right of modification includes the right to translate, adapt, arrange, -or make any or all modifications to the Software, and the right to -reproduce the resulting Software. It includes, in particular, the right -to create a Derivative Software. - -The Licensee is authorized to make any or all modification to the -Software provided that it includes an explicit notice that it is the -author of said modification and indicates the date of the creation thereof. - - - 5.3 RIGHT OF DISTRIBUTION - -In particular, the right of distribution includes the right to publish, -transmit and communicate the Software to the general public on any or -all medium, and by any or all means, and the right to market, either in -consideration of a fee, or free of charge, one or more copies of the -Software by any means. - -The Licensee is further authorized to distribute copies of the modified -or unmodified Software to third parties according to the terms and -conditions set forth hereinafter. - - - 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION - -The Licensee is authorized to distribute true copies of the Software in -Source Code or Object Code form, provided that said distribution -complies with all the provisions of the Agreement and is accompanied by: - - 1. a copy of the Agreement, - - 2. a notice relating to the limitation of both the Licensor's - warranty and liability as set forth in Articles 8 and 9, - -and that, in the event that only the Object Code of the Software is -redistributed, the Licensee allows effective access to the full Source Code -of the Software at a minimum during the entire period of its distribution -of the Software, it being understood that the additional cost of acquiring -the Source Code shall not exceed the cost of transferring the data. - - - 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE - -When the Licensee makes an Integrated Contribution to the Software, the terms -and conditions for the distribution of the resulting Modified Software become -subject to all the provisions of this Agreement. - -The Licensee is authorized to distribute the Modified Software, in source -code or object code form, provided that said distribution complies with all -the provisions of the Agreement and is accompanied by: - - 1. a copy of the Agreement, - 2. a notice relating to the limitation of both the Licensor's warranty and - liability as set forth in Articles 8 and 9, - -and that, in the event that only the object code of the Modified Software is -redistributed, the Licensee allows effective access to the full source code -of the Modified Software at a minimum during the entire period of its -distribution of the Modified Software, it being understood that the -additional cost of acquiring the source code shall not exceed the cost of -transferring the data. - - 5.3.3 DISTRIBUTION OF DERIVATIVE SOFTWARE - -When the Licensee creates Derivative Software, this Derivative Software may -be distributed under a license agreement other than this Agreement, subject -to compliance with the requirement to include a notice concerning the rights -over the Software as defined in Article 6.4. In the event the creation of the -Derivative Software required modification of the Source Code, the Licensee -undertakes that: - - 1. the resulting Modified Software will be governed by this Agreement, - 2. the Integrated Contributions in the resulting Modified Software will be - clearly identified and documented, - 3. the Licensee will allow effective access to the source code of the - Modified Software, at a minimum during the entire period of - distribution of the Derivative Software, such that such modifications - may be carried over in a subsequent version of the Software; it being - understood that the additional cost of purchasing the source code of - the Modified Software shall not exceed the cost of transferring the - data. - - - 5.3.4 COMPATIBILITY WITH THE CeCILL LICENSE - -When a Modified Software contains an Integrated Contribution subject to the -CeCill license agreement, or when a Derivative Software contains a Related -Module subject to the CeCill license agreement, the provisions set forth in -the third item of Article 6.4 are optional. - - - Article 6 - INTELLECTUAL PROPERTY - - - 6.1 OVER THE INITIAL SOFTWARE - -The Holder owns the economic rights over the Initial Software. Any or -all use of the Initial Software is subject to compliance with the terms -and conditions under which the Holder has elected to distribute its work -and no one shall be entitled to modify the terms and conditions for the -distribution of said Initial Software. - -The Holder undertakes that the Initial Software will remain ruled at -least by the current license, for the duration set forth in Article 4.2. - - - 6.2 OVER THE INTEGRATED CONTRIBUTIONS - -A Licensee who develops an Integrated Contribution is the owner of the -intellectual property rights over this Contribution as defined by -applicable law. - - - 6.3 OVER THE RELATED MODULES - -A Licensee who develops an Related Module is the owner of the -intellectual property rights over this Related Module as defined by -applicable law and is free to choose the type of agreement that shall -govern its distribution under the conditions defined in Article 5.3.3. - - - 6.4 NOTICE OF RIGHTS - -The Licensee expressly undertakes: - - 1. not to remove, or modify, in any manner, the intellectual property - notices attached to the Software; - 2. to reproduce said notices, in an identical manner, in the copies - of the Software modified or not; - 3. to ensure that use of the Software, its intellectual property - notices and the fact that it is governed by the Agreement is - indicated in a text that is easily accessible, specifically from - the interface of any Derivative Software. - -The Licensee undertakes not to directly or indirectly infringe the -intellectual property rights of the Holder and/or Contributors on the -Software and to take, where applicable, vis--vis its staff, any and all -measures required to ensure respect of said intellectual property rights -of the Holder and/or Contributors. - - - Article 7 - RELATED SERVICES - -7.1 Under no circumstances shall the Agreement oblige the Licensor to -provide technical assistance or maintenance services for the Software. - -However, the Licensor is entitled to offer this type of services. The -terms and conditions of such technical assistance, and/or such -maintenance, shall be set forth in a separate instrument. Only the -Licensor offering said maintenance and/or technical assistance services -shall incur liability therefor. - -7.2 Similarly, any Licensor is entitled to offer to its licensees, under -its sole responsibility, a warranty, that shall only be binding upon -itself, for the redistribution of the Software and/or the Modified -Software, under terms and conditions that it is free to decide. Said -warranty, and the financial terms and conditions of its application, -shall be subject of a separate instrument executed between the Licensor -and the Licensee. - - - Article 8 - LIABILITY - -8.1 Subject to the provisions of Article 8.2, the Licensee shall be -entitled to claim compensation for any direct loss it may have suffered -from the Software as a result of a fault on the part of the relevant -Licensor, subject to providing evidence thereof. - -8.2 The Licensor's liability is limited to the commitments made under -this Agreement and shall not be incurred as a result of in particular: -(i) loss due the Licensee's total or partial failure to fulfill its -obligations, (ii) direct or consequential loss that is suffered by the -Licensee due to the use or performance of the Software, and (iii) more -generally, any consequential loss. In particular the Parties expressly -agree that any or all pecuniary or business loss (i.e. loss of data, -loss of profits, operating loss, loss of customers or orders, -opportunity cost, any disturbance to business activities) or any or all -legal proceedings instituted against the Licensee by a third party, -shall constitute consequential loss and shall not provide entitlement to -any or all compensation from the Licensor. - - - Article 9 - WARRANTY - -9.1 The Licensee acknowledges that the scientific and technical -state-of-the-art when the Software was distributed did not enable all -possible uses to be tested and verified, nor for the presence of -possible defects to be detected. In this respect, the Licensee's -attention has been drawn to the risks associated with loading, using, -modifying and/or developing and reproducing the Software which are -reserved for experienced users. - -The Licensee shall be responsible for verifying, by any or all means, -the suitability of the product for its requirements, its good working order, -and for ensuring that it shall not cause damage to either persons or -properties. - -9.2 The Licensor hereby represents, in good faith, that it is entitled -to grant all the rights over the Software (including in particular the -rights set forth in Article 5). - -9.3 The Licensee acknowledges that the Software is supplied "as is" by -the Licensor without any other express or tacit warranty, other than -that provided for in Article 9.2 and, in particular, without any warranty -as to its commercial value, its secured, safe, innovative or relevant -nature. - -Specifically, the Licensor does not warrant that the Software is free -from any error, that it will operate without interruption, that it will -be compatible with the Licensee's own equipment and software -configuration, nor that it will meet the Licensee's requirements. - -9.4 The Licensor does not either expressly or tacitly warrant that the -Software does not infringe any third party intellectual property right -relating to a patent, software or any other property right. Therefore, -the Licensor disclaims any and all liability towards the Licensee -arising out of any or all proceedings for infringement that may be -instituted in respect of the use, modification and redistribution of the -Software. Nevertheless, should such proceedings be instituted against -the Licensee, the Licensor shall provide it with technical and legal -assistance for its defense. Such technical and legal assistance shall be -decided on a case-by-case basis between the relevant Licensor and the -Licensee pursuant to a memorandum of understanding. The Licensor -disclaims any and all liability as regards the Licensee's use of the -name of the Software. No warranty is given as regards the existence of -prior rights over the name of the Software or as regards the existence -of a trademark. - - - Article 10 - TERMINATION - -10.1 In the event of a breach by the Licensee of its obligations -hereunder, the Licensor may automatically terminate this Agreement -thirty (30) days after notice has been sent to the Licensee and has -remained ineffective. - -10.2 A Licensee whose Agreement is terminated shall no longer be -authorized to use, modify or distribute the Software. However, any -licenses that it may have granted prior to termination of the Agreement -shall remain valid subject to their having been granted in compliance -with the terms and conditions hereof. - - - Article 11 - MISCELLANEOUS - - - 11.1 EXCUSABLE EVENTS - -Neither Party shall be liable for any or all delay, or failure to -perform the Agreement, that may be attributable to an event of force -majeure, an act of God or an outside cause, such as defective -functioning or interruptions of the electricity or telecommunications -networks, network paralysis following a virus attack, intervention by -government authorities, natural disasters, water damage, earthquakes, -fire, explosions, strikes and labor unrest, war, etc. - -11.2 Any failure by either Party, on one or more occasions, to invoke -one or more of the provisions hereof, shall under no circumstances be -interpreted as being a waiver by the interested Party of its right to -invoke said provision(s) subsequently. - -11.3 The Agreement cancels and replaces any or all previous agreements, -whether written or oral, between the Parties and having the same -purpose, and constitutes the entirety of the agreement between said -Parties concerning said purpose. No supplement or modification to the -terms and conditions hereof shall be effective as between the Parties -unless it is made in writing and signed by their duly authorized -representatives. - -11.4 In the event that one or more of the provisions hereof were to -conflict with a current or future applicable act or legislative text, -said act or legislative text shall prevail, and the Parties shall make -the necessary amendments so as to comply with said act or legislative -text. All other provisions shall remain effective. Similarly, invalidity -of a provision of the Agreement, for any reason whatsoever, shall not -cause the Agreement as a whole to be invalid. - - - 11.5 LANGUAGE - -The Agreement is drafted in both French and English and both versions -are deemed authentic. - - - Article 12 - NEW VERSIONS OF THE AGREEMENT - -12.1 Any person is authorized to duplicate and distribute copies of this -Agreement. - -12.2 So as to ensure coherence, the wording of this Agreement is -protected and may only be modified by the authors of the License, who -reserve the right to periodically publish updates or new versions of the -Agreement, each with a separate number. These subsequent versions may -address new issues encountered by Free Software. - -12.3 Any Software distributed under a given version of the Agreement -may only be subsequently distributed under the same version of the -Agreement or a subsequent version. - - - Article 13 - GOVERNING LAW AND JURISDICTION - -13.1 The Agreement is governed by French law. The Parties agree to -endeavor to seek an amicable solution to any disagreements or disputes -that may arise during the performance of the Agreement. - -13.2 Failing an amicable solution within two (2) months as from their -occurrence, and unless emergency proceedings are necessary, the -disagreements or disputes shall be referred to the Paris Courts having -jurisdiction, by the more diligent Party. - - -Version 1.0 dated 2006-07-12. diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/Licence_CeCILL_V2-en.txt b/applications/plugins/CImgPlugin/extlibs/CImg/Licence_CeCILL_V2-en.txt deleted file mode 100644 index 8720df6f44e..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/Licence_CeCILL_V2-en.txt +++ /dev/null @@ -1,504 +0,0 @@ - - CeCILL FREE SOFTWARE LICENSE AGREEMENT - - - Notice - -This Agreement is a Free Software license agreement that is the result -of discussions between its authors in order to ensure compliance with -the two main principles guiding its drafting: - - * firstly, compliance with the principles governing the distribution - of Free Software: access to source code, broad rights granted to - users, - * secondly, the election of a governing law, French law, with which - it is conformant, both as regards the law of torts and - intellectual property law, and the protection that it offers to - both authors and holders of the economic rights over software. - -The authors of the CeCILL (for Ce[a] C[nrs] I[nria] L[logiciel] L[ibre]) -license are: - -Commissariat l'Energie Atomique - CEA, a public scientific, technical -and industrial research establishment, having its principal place of -business at 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris, France. - -Centre National de la Recherche Scientifique - CNRS, a public scientific -and technological research establishment, having its principal place of -business at 3 rue Michel-Ange, 75794 Paris cedex 16, France. - -Institut National de Recherche en Informatique et en Automatique - -INRIA, a public scientific and technological establishment, having its -principal place of business at Domaine de Voluceau, Rocquencourt, BP -105, 78153 Le Chesnay cedex, France. - - - Preamble - -The purpose of this Free Software license agreement is to grant users -the right to modify and redistribute the software governed by this -license within the framework of an open source distribution model. - -The exercising of these rights is conditional upon certain obligations -for users so as to preserve this status for all subsequent redistributions. - -In consideration of access to the source code and the rights to copy, -modify and redistribute granted by the license, users are provided only -with a limited warranty and the software's author, the holder of the -economic rights, and the successive licensors only have limited liability. - -In this respect, the risks associated with loading, using, modifying -and/or developing or reproducing the software by the user are brought to -the user's attention, given its Free Software status, which may make it -complicated to use, with the result that its use is reserved for -developers and experienced professionals having in-depth computer -knowledge. Users are therefore encouraged to load and test the suitability -of the software as regards their requirements in conditions enabling -the security of their systems and/or data to be ensured and, more -generally, to use and operate it in the same conditions of security. -This Agreement may be freely reproduced and published, provided it is not -altered, and that no provisions are either added or removed herefrom. - -This Agreement may apply to any or all software for which the holder of -the economic rights decides to submit the use thereof to its provisions. - - - Article 1 - DEFINITIONS - -For the purpose of this Agreement, when the following expressions -commence with a capital letter, they shall have the following meaning: - -Agreement: means this license agreement, and its possible subsequent -versions and annexes. - -Software: means the software in its Object Code and/or Source Code form -and, where applicable, its documentation, "as is" when the Licensee -accepts the Agreement. - -Initial Software: means the Software in its Source Code and possibly its -Object Code form and, where applicable, its documentation, "as is" when -it is first distributed under the terms and conditions of the Agreement. - -Modified Software: means the Software modified by at least one -Contribution. - -Source Code: means all the Software's instructions and program lines to -which access is required so as to modify the Software. - -Object Code: means the binary files originating from the compilation of -the Source Code. - -Holder: means the holder(s) of the economic rights over the Initial -Software. - -Licensee: means the Software user(s) having accepted the Agreement. - -Contributor: means a Licensee having made at least one Contribution. - -Licensor: means the Holder, or any other individual or legal entity, who -distributes the Software under the Agreement. - -Contribution: means any or all modifications, corrections, translations, -adaptations and/or new functions integrated into the Software by any or -all Contributors, as well as any or all Internal Modules. - -Module: means a set of sources files including their documentation that -enables supplementary functions or services in addition to those offered -by the Software. - -External Module: means any or all Modules, not derived from the -Software, so that this Module and the Software run in separate address -spaces, with one calling the other when they are run. - -Internal Module: means any or all Module, connected to the Software so -that they both execute in the same address space. - -GNU GPL: means the GNU General Public License version 2 or any -subsequent version, as published by the Free Software Foundation Inc. - -Parties: mean both the Licensee and the Licensor. - -These expressions may be used both in singular and plural form. - - - Article 2 - PURPOSE - -The purpose of the Agreement is the grant by the Licensor to the -Licensee of a non-exclusive, transferable and worldwide license for the -Software as set forth in Article 5 hereinafter for the whole term of the -protection granted by the rights over said Software. - - - Article 3 - ACCEPTANCE - -3.1 The Licensee shall be deemed as having accepted the terms and -conditions of this Agreement upon the occurrence of the first of the -following events: - - * (i) loading the Software by any or all means, notably, by - downloading from a remote server, or by loading from a physical - medium; - * (ii) the first time the Licensee exercises any of the rights - granted hereunder. - -3.2 One copy of the Agreement, containing a notice relating to the -characteristics of the Software, to the limited warranty, and to the -fact that its use is restricted to experienced users has been provided -to the Licensee prior to its acceptance as set forth in Article 3.1 -hereinabove, and the Licensee hereby acknowledges that it has read and -understood it. - - - Article 4 - EFFECTIVE DATE AND TERM - - - 4.1 EFFECTIVE DATE - -The Agreement shall become effective on the date when it is accepted by -the Licensee as set forth in Article 3.1. - - - 4.2 TERM - -The Agreement shall remain in force for the entire legal term of -protection of the economic rights over the Software. - - - Article 5 - SCOPE OF RIGHTS GRANTED - -The Licensor hereby grants to the Licensee, who accepts, the following -rights over the Software for any or all use, and for the term of the -Agreement, on the basis of the terms and conditions set forth hereinafter. - -Besides, if the Licensor owns or comes to own one or more patents -protecting all or part of the functions of the Software or of its -components, the Licensor undertakes not to enforce the rights granted by -these patents against successive Licensees using, exploiting or -modifying the Software. If these patents are transferred, the Licensor -undertakes to have the transferees subscribe to the obligations set -forth in this paragraph. - - - 5.1 RIGHT OF USE - -The Licensee is authorized to use the Software, without any limitation -as to its fields of application, with it being hereinafter specified -that this comprises: - - 1. permanent or temporary reproduction of all or part of the Software - by any or all means and in any or all form. - - 2. loading, displaying, running, or storing the Software on any or - all medium. - - 3. entitlement to observe, study or test its operation so as to - determine the ideas and principles behind any or all constituent - elements of said Software. This shall apply when the Licensee - carries out any or all loading, displaying, running, transmission - or storage operation as regards the Software, that it is entitled - to carry out hereunder. - - - 5.2 ENTITLEMENT TO MAKE CONTRIBUTIONS - -The right to make Contributions includes the right to translate, adapt, -arrange, or make any or all modifications to the Software, and the right -to reproduce the resulting software. - -The Licensee is authorized to make any or all Contributions to the -Software provided that it includes an explicit notice that it is the -author of said Contribution and indicates the date of the creation thereof. - - - 5.3 RIGHT OF DISTRIBUTION - -In particular, the right of distribution includes the right to publish, -transmit and communicate the Software to the general public on any or -all medium, and by any or all means, and the right to market, either in -consideration of a fee, or free of charge, one or more copies of the -Software by any means. - -The Licensee is further authorized to distribute copies of the modified -or unmodified Software to third parties according to the terms and -conditions set forth hereinafter. - - - 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION - -The Licensee is authorized to distribute true copies of the Software in -Source Code or Object Code form, provided that said distribution -complies with all the provisions of the Agreement and is accompanied by: - - 1. a copy of the Agreement, - - 2. a notice relating to the limitation of both the Licensor's - warranty and liability as set forth in Articles 8 and 9, - -and that, in the event that only the Object Code of the Software is -redistributed, the Licensee allows future Licensees unhindered access to -the full Source Code of the Software by indicating how to access it, it -being understood that the additional cost of acquiring the Source Code -shall not exceed the cost of transferring the data. - - - 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE - -When the Licensee makes a Contribution to the Software, the terms and -conditions for the distribution of the resulting Modified Software -become subject to all the provisions of this Agreement. - -The Licensee is authorized to distribute the Modified Software, in -source code or object code form, provided that said distribution -complies with all the provisions of the Agreement and is accompanied by: - - 1. a copy of the Agreement, - - 2. a notice relating to the limitation of both the Licensor's - warranty and liability as set forth in Articles 8 and 9, - -and that, in the event that only the Object Code of the Modified -Software is redistributed, the Licensee allows future Licensees -unhindered access to the full source code of the Modified Software by -indicating how to access it, it being understood that the additional -cost of acquiring the source code shall not exceed the cost of -transferring the data. - - - 5.3.3 DISTRIBUTION OF EXTERNAL MODULES - -When the Licensee has developed an External Module, the terms and -conditions of this Agreement do not apply to said External Module, that -may be distributed under a separate license agreement. - - - 5.3.4 COMPATIBILITY WITH THE GNU GPL - -The Licensee can include a code that is subject to the provisions of one -of the versions of the GNU GPL in the Modified or unmodified Software, -and distribute that entire code under the terms of the same version of -the GNU GPL. - -The Licensee can include the Modified or unmodified Software in a code -that is subject to the provisions of one of the versions of the GNU GPL, -and distribute that entire code under the terms of the same version of -the GNU GPL. - - - Article 6 - INTELLECTUAL PROPERTY - - - 6.1 OVER THE INITIAL SOFTWARE - -The Holder owns the economic rights over the Initial Software. Any or -all use of the Initial Software is subject to compliance with the terms -and conditions under which the Holder has elected to distribute its work -and no one shall be entitled to modify the terms and conditions for the -distribution of said Initial Software. - -The Holder undertakes that the Initial Software will remain ruled at -least by the current license, for the duration set forth in Article 4.2. - - - 6.2 OVER THE CONTRIBUTIONS - -A Licensee who develops a Contribution is the owner of the intellectual -property rights over this Contribution as defined by applicable law. - - - 6.3 OVER THE EXTERNAL MODULES - -A Licensee who develops an External Module is the owner of the -intellectual property rights over this External Module as defined by -applicable law and is free to choose the type of agreement that shall -govern its distribution. - - - 6.4 JOINT PROVISIONS - -The Licensee expressly undertakes: - - 1. not to remove, or modify, in any manner, the intellectual property - notices attached to the Software; - - 2. to reproduce said notices, in an identical manner, in the copies - of the Software modified or not. - -The Licensee undertakes not to directly or indirectly infringe the -intellectual property rights of the Holder and/or Contributors on the -Software and to take, where applicable, vis--vis its staff, any and all -measures required to ensure respect of said intellectual property rights -of the Holder and/or Contributors. - - - Article 7 - RELATED SERVICES - -7.1 Under no circumstances shall the Agreement oblige the Licensor to -provide technical assistance or maintenance services for the Software. - -However, the Licensor is entitled to offer this type of services. The -terms and conditions of such technical assistance, and/or such -maintenance, shall be set forth in a separate instrument. Only the -Licensor offering said maintenance and/or technical assistance services -shall incur liability therefor. - -7.2 Similarly, any Licensor is entitled to offer to its licensees, under -its sole responsibility, a warranty, that shall only be binding upon -itself, for the redistribution of the Software and/or the Modified -Software, under terms and conditions that it is free to decide. Said -warranty, and the financial terms and conditions of its application, -shall be subject of a separate instrument executed between the Licensor -and the Licensee. - - - Article 8 - LIABILITY - -8.1 Subject to the provisions of Article 8.2, the Licensee shall be -entitled to claim compensation for any direct loss it may have suffered -from the Software as a result of a fault on the part of the relevant -Licensor, subject to providing evidence thereof. - -8.2 The Licensor's liability is limited to the commitments made under -this Agreement and shall not be incurred as a result of in particular: -(i) loss due the Licensee's total or partial failure to fulfill its -obligations, (ii) direct or consequential loss that is suffered by the -Licensee due to the use or performance of the Software, and (iii) more -generally, any consequential loss. In particular the Parties expressly -agree that any or all pecuniary or business loss (i.e. loss of data, -loss of profits, operating loss, loss of customers or orders, -opportunity cost, any disturbance to business activities) or any or all -legal proceedings instituted against the Licensee by a third party, -shall constitute consequential loss and shall not provide entitlement to -any or all compensation from the Licensor. - - - Article 9 - WARRANTY - -9.1 The Licensee acknowledges that the scientific and technical -state-of-the-art when the Software was distributed did not enable all -possible uses to be tested and verified, nor for the presence of -possible defects to be detected. In this respect, the Licensee's -attention has been drawn to the risks associated with loading, using, -modifying and/or developing and reproducing the Software which are -reserved for experienced users. - -The Licensee shall be responsible for verifying, by any or all means, -the suitability of the product for its requirements, its good working order, -and for ensuring that it shall not cause damage to either persons or -properties. - -9.2 The Licensor hereby represents, in good faith, that it is entitled -to grant all the rights over the Software (including in particular the -rights set forth in Article 5). - -9.3 The Licensee acknowledges that the Software is supplied "as is" by -the Licensor without any other express or tacit warranty, other than -that provided for in Article 9.2 and, in particular, without any warranty -as to its commercial value, its secured, safe, innovative or relevant -nature. - -Specifically, the Licensor does not warrant that the Software is free -from any error, that it will operate without interruption, that it will -be compatible with the Licensee's own equipment and software -configuration, nor that it will meet the Licensee's requirements. - -9.4 The Licensor does not either expressly or tacitly warrant that the -Software does not infringe any third party intellectual property right -relating to a patent, software or any other property right. Therefore, -the Licensor disclaims any and all liability towards the Licensee -arising out of any or all proceedings for infringement that may be -instituted in respect of the use, modification and redistribution of the -Software. Nevertheless, should such proceedings be instituted against -the Licensee, the Licensor shall provide it with technical and legal -assistance for its defense. Such technical and legal assistance shall be -decided on a case-by-case basis between the relevant Licensor and the -Licensee pursuant to a memorandum of understanding. The Licensor -disclaims any and all liability as regards the Licensee's use of the -name of the Software. No warranty is given as regards the existence of -prior rights over the name of the Software or as regards the existence -of a trademark. - - - Article 10 - TERMINATION - -10.1 In the event of a breach by the Licensee of its obligations -hereunder, the Licensor may automatically terminate this Agreement -thirty (30) days after notice has been sent to the Licensee and has -remained ineffective. - -10.2 A Licensee whose Agreement is terminated shall no longer be -authorized to use, modify or distribute the Software. However, any -licenses that it may have granted prior to termination of the Agreement -shall remain valid subject to their having been granted in compliance -with the terms and conditions hereof. - - - Article 11 - MISCELLANEOUS - - - 11.1 EXCUSABLE EVENTS - -Neither Party shall be liable for any or all delay, or failure to -perform the Agreement, that may be attributable to an event of force -majeure, an act of God or an outside cause, such as defective -functioning or interruptions of the electricity or telecommunications -networks, network paralysis following a virus attack, intervention by -government authorities, natural disasters, water damage, earthquakes, -fire, explosions, strikes and labor unrest, war, etc. - -11.2 Any failure by either Party, on one or more occasions, to invoke -one or more of the provisions hereof, shall under no circumstances be -interpreted as being a waiver by the interested Party of its right to -invoke said provision(s) subsequently. - -11.3 The Agreement cancels and replaces any or all previous agreements, -whether written or oral, between the Parties and having the same -purpose, and constitutes the entirety of the agreement between said -Parties concerning said purpose. No supplement or modification to the -terms and conditions hereof shall be effective as between the Parties -unless it is made in writing and signed by their duly authorized -representatives. - -11.4 In the event that one or more of the provisions hereof were to -conflict with a current or future applicable act or legislative text, -said act or legislative text shall prevail, and the Parties shall make -the necessary amendments so as to comply with said act or legislative -text. All other provisions shall remain effective. Similarly, invalidity -of a provision of the Agreement, for any reason whatsoever, shall not -cause the Agreement as a whole to be invalid. - - - 11.5 LANGUAGE - -The Agreement is drafted in both French and English and both versions -are deemed authentic. - - - Article 12 - NEW VERSIONS OF THE AGREEMENT - -12.1 Any person is authorized to duplicate and distribute copies of this -Agreement. - -12.2 So as to ensure coherence, the wording of this Agreement is -protected and may only be modified by the authors of the License, who -reserve the right to periodically publish updates or new versions of the -Agreement, each with a separate number. These subsequent versions may -address new issues encountered by Free Software. - -12.3 Any Software distributed under a given version of the Agreement may -only be subsequently distributed under the same version of the Agreement -or a subsequent version, subject to the provisions of Article 5.3.4. - - - Article 13 - GOVERNING LAW AND JURISDICTION - -13.1 The Agreement is governed by French law. The Parties agree to -endeavor to seek an amicable solution to any disagreements or disputes -that may arise during the performance of the Agreement. - -13.2 Failing an amicable solution within two (2) months as from their -occurrence, and unless emergency proceedings are necessary, the -disagreements or disputes shall be referred to the Paris Courts having -jurisdiction, by the more diligent Party. - - -Version 2.0 dated 2006-07-12. diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/README.txt b/applications/plugins/CImgPlugin/extlibs/CImg/README.txt deleted file mode 100644 index 30095f4d99f..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/README.txt +++ /dev/null @@ -1,179 +0,0 @@ --------------------------------------------------------------------------------- --------------------------------------------------------------------------------- - ____ _ _ ____ - (_ _)( )_( )( ___) - )( ) _ ( )__) - (__) (_) (_)(____) - ___ ____ __ __ ___ __ ____ ____ ____ __ ____ _ _ - / __)(_ _)( \/ )/ __) ( ) (_ _)( _ \( _ \ /__\ ( _ \( \/ ) - ( (__ _)(_ ) (( (_-. )(__ _)(_ ) _ < ) / /(__)\ ) / \ / - \___)(____)(_/\/\_)\___/ (____)(____)(____/(_)\_)(__)(__)(_)\_) (__) - - - C++ Template Image Processing Toolkit - - ( http://cimg.eu ) - - 1.7.3 - --------------------------------------------------------------------------------- - -# Summary -#--------- - - The CImg Library is a small, open-source, modern C++ toolkit for image processing. - It consists in a single header file 'CImg.h' providing a minimal set of C++ - classes and methods that can be used in your own sources, to load/save, - process and display images. Very portable (Unix/X11,Windows, MacOS X, FreeBSD, .. ), - efficient, easy to use, it's a pleasant library for developping image processing - algorithms in C++. - -# Authors and contributors : -#---------------------------- - - - David Tschumperle (project leader) ( http://tschumperle.users.greyc.fr/ ) - - - Maksim Aizenshtein - - Alberto Albiol - - Antonio Albiol - - Simon Barthelme - - Neil Brown - - Haz-Edine Assemlal - - Vincent Barra - - Wolf Blecher - - Romain Blei - - Yohan Bentolila - - Jerome Boulanger - - Pierre Buyssens - - Sebastien Coudert - - Frederic Devernay - - Olivier D'Hondt - - Francois-Xavier Dupe - - Gerd von Egidy - - Eric Fausett - - Jean-Marie Favreau - - Sebastien Fourey - - Alexandre Fournier - - Hon-Kwok Fung - - Vincent Garcia - - David Grimbichler - - Jinwei Gu - - Jean-Daniel Guyot - - Cedric Hammiche - - Matt Hanson - - Sebastien Hanel - - Michael Holroyd - - Christoph Hormann - - Werner Jainek - - Daniel Kondermann - - Pierre Kornprobst - - Jan W. Krieger - - Orges Leka - - Francois Lauze - - Xie Long - - Thomas Martin - - Cesar Martinez - - Jean Martinot - - Arnold Meijster (Center for High Performance Computing and Visualization, University of Groningen/The Netherlands) - - Nikita Melnichenko - - Julien Morat - - Baptiste Mougel - - Jovana Milutinovich - - Guillaume Nee - - Adam Newgas - - Francisco Oliveira - - Andrea Onofri - - Renaud Peteri - - Martin Petricek - - Paolo Prete - - Adrien Reboisson - - Klaus Schneider - - Jakob Schluttig - - Veronique Souchaud - - Konstantin Spirin - - David G. Starkweather - - Rainer Steffens - - Grzegorz Szwoch - - Thierry Thomas - - Yu-En-Yun - - Vo Duc Khanh - - Phillip Wood - - Bug Zhao - - Haibo Zheng - -# Institution -#------------- - - GREYC Image / CNRS UMR 6072 / FRANCE - - The CImg Library project started in 2000, at the INRIA-Sophia - Antipolis/France ( http://www-sop.inria.fr/ ), in the ROBOTVIS / ODYSSEE Team. - Since October 2004, it is maintained and developed in the Image team of - the GREYC Lab (CNRS, UMR 6072), in Caen/France. - Team web page : http://www.greyc.fr/image - -# Licenses -#---------- - - The source code of the CImg Library is distributed under - two distinct licenses : - - - The main library file 'CImg.h' is *dual-licensed* : - It can be either distributed under the CeCILL-C or CeCILL license. - (see files 'Licence_CeCILL-C_V1-en.txt' and 'Licence_CeCILL_V2-en.txt'). - Both are Free-Software licenses : - - * CeCILL-C is adapted to the distribution of - library components, and is close in its terms to the well known GNU LGPL license - (the 'CImg.h' file can thus be used in closed-source products under certain - conditions, please read carefully the license file). - - * CeCILL is close to (and even compatible with) the GNU GPL license. - - - Most of the other files are distributed under the CeCiLL license - (file 'Licence_CeCILL_V2-en.txt'). See each file header to see what license applies. - - These two CeCiLL licenses ( http://www.cecill.info/index.en.html ) have been - created under the supervision of the three biggest research institutions on - computer sciences in France : - - - CNRS ( http://www.cnrs.fr/ ) - - CEA ( http://www.cea.fr/ ) - - INRIA ( http://www.inria.fr/ ) - - You have to RESPECT these licenses. More particularly, please carefully read - the license terms before using the CImg library in commercial products. - -# Package structure : -#-------------------- - - The main package directory CImg/ is organized as follows : - - - README.txt : This file. - - Licence_CeCILL-C_V1-en.txt : A copy of the CeCiLL-C license file. - - Licence_CeCILL_V2-en.txt : A copy of the CeCiLL license. - - CImg.h : The single header file that constitutes the library itself. - - examples/ : A directory containing a lot of example programs performing - various things, using the CImg library. - - html/ : A directory containing a copy of the CImg web page in html - format. The reference documentation is generated - automatically with the tool 'doxygen' (http://www.doxygen.org). - - resources/ : A directory containing some resources files for compiling - CImg examples or packages with various C++ compilers and OS. - - plugins/ : A directory containing CImg plug-ins files that can be used to - add specific extra functionalities to the CImg library. - -# Getting started -#----------------- - - If you are new to CImg, you should first try to compile the different examples - provided in the 'examples/' directory, to see what CImg is capable of - (as CImg is a template-based library, no prior compilation of the library is mandatory). - Look at the 'resources/' directory to ease this compilation on different platforms. - - Then, you can look at the documentation 'html/reference/' to learn more about CImg - functions and classes. Finally, you can participate to the 'Forum' section - of the CImg web page and ask for help if needed. - -# End of file -#------------ diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/CImg_demo.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/CImg_demo.cpp deleted file mode 100644 index 7142145cf0e..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/CImg_demo.cpp +++ /dev/null @@ -1,1689 +0,0 @@ -/* - # - # File : CImg_demo.cpp - # ( C++ source file ) - # - # Description : A multi-part demo demonstrating some of the CImg capabilities. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -// Include static image data, so that the exe does not depend on external image files. -#include "img/CImg_demo.h" - -// Include CImg library header. -#include "CImg.h" -using namespace cimg_library; -#undef min -#undef max - -// Item : Blurring Gradient -//---------------------------- -void* item_blurring_gradient() { - const CImg src(data_milla,211,242,1,3); - CImgList grad = src.get_gradient(); - CImgList visu = (src,sqrt(grad[0].pow(2) + grad[1].pow(2)).normalize(0,255),src); - CImgDisplay disp(visu,"[#1] - Color Image, Gradient Norm and Blurring Gradient",0); - - for (double sigma = 0; !disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC(); sigma+=0.05) { - visu[2] = visu[1].get_blur((float)cimg::abs(30*std::cos(sigma))).normalize(0,255); - disp.resize(false).display(visu).wait(20); - } - return 0; -} - -// Item : Rotozoom -//----------------- -void* item_rotozoom() { - CImg src = CImg(data_milla,211,242,1,3,false).resize(400,300,1,3,3), img(src); - CImgDisplay disp(img.width(),img.height(),"[#2] - Rotozoom",0); - float alpha = 0, t = 0, angle = 0, zoom0 = -0.9f; - const unsigned char color[] = { 16,32,64 }; - - while (!disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC()) { - cimg_forYC(src,y,k) { - const int xc = 4*src.width() + (int)(60*std::sin((float)y*3/src.height() + 10*t)); - cimg_forX(src,x) { - const float val = (float)(src((xc + x)%src.width(),y,0,k)* - (1.3f + 0.20*std::sin(alpha + k*k*((float)src.width()/2 - x)* - ((float)src.height()/2 - y)*std::cos(t)/300.0))); - img(x,y,0,k) = (unsigned char)(val>255.0f?255:val); - } - } - const float zoom = (float)(zoom0 + 0.3f*(1 + std::cos(3*t))); - img.get_rotate(angle,0.5f*img.width(),0.5f*img.height(),1 + zoom,0,2). - draw_text(3,3,"Mouse buttons\nto zoom in/out",color,0,0.8f,24).display(disp.resize(false).wait(20)); - alpha+=0.7f; t+=0.01f; angle+=0.8f; - zoom0+=disp.button()&1?0.1f:disp.button()&2?-0.1f:0; - if (disp.is_keyCTRLLEFT() && disp.is_keyF()) disp.resize(400,400,false).toggle_fullscreen(false); - } - return 0; -} - -// Item : Anisotropic Smoothing (Total variation PDE, explicit scheme) -//-------------------------------------------------------------------- -void* item_anisotropic_smoothing() { - const CImg src = CImg<>(data_milla,211,242,1,3).noise(-30,1); - CImgList images(src,src); - CImgDisplay disp(images,"[#3] - Anisotropic smoothing"); - const float white[] = { 255, 255, 255 }, black[] = { 0, 0, 0 }; - - for (unsigned int iter = 0; !disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC(); ++iter) { - - // Compute PDE velocity field. - CImg_3x3(I,float); - CImg veloc(src); - float *ptrd = veloc.data(), betamax = 0; - cimg_forC(src,k) cimg_for3x3(images[1],x,y,0,k,I,float) { - const float - ix = (Inc - Ipc)/2, - iy = (Icn - Icp)/2, - ng = (float)std::sqrt(1e-10f + ix*ix + iy*iy), - ixx = Inc + Ipc - 2*Icc, - iyy = Icn + Icp - 2*Icc, - ixy = 0.25f*(Inn + Ipp - Ipn - Inp), - iee = (ix*ix*iyy + iy*iy*ixx - 2*ix*iy*ixy)/(ng*ng), - beta = iee/(0.1f + ng); - if (beta>betamax) betamax = beta; else if (-beta>betamax) betamax = -beta; - *(ptrd++) = beta; - } - veloc*=40.0f/betamax; - images[1]+=veloc; - images[0].draw_text(4,4,"Iteration : %u ",white,black,1,13,iter); - disp.resize(false).display(images); - } - return 0; -} - -// Item : Fractal Animation -//-------------------------- -void* item_fractal_animation() { - CImg img(400,400,1,3,0), noise(3,2,1,3); - CImgDisplay disp(img,"[#4] - Fractal Animation"); - float zoom = 0; - - for (unsigned int iter = 0; !disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC(); ++iter, zoom+=0.2f) { - img.draw_image((img.width() - noise.width())/2, - (img.height() - noise.height())/2, - noise.fill(0).noise(255,1)). - rotate((float)(10*std::sin(iter/25.0)),0.5f*img.width(),0.5f*img.height(), - (float)(1.04f + 0.02f*std::sin(zoom/10)),0,0). - resize(disp.resize(false)).display(disp.wait(25)); - if (disp.is_keyCTRLLEFT() && disp.is_keyF()) disp.resize(400,400,false).toggle_fullscreen(false); - } - return 0; -} - -// Item : Gamma Correction and Histogram Visualization -//----------------------------------------------------- -void* item_gamma_correction() { - CImg img = CImg<>(data_milla,211,242,1,3).normalize(0,1); - CImgList visu(img*255.0,CImg(512,300,1,3,0)); - CImgDisplay disp(visu,"[#5] - Gamma Corrected Image and Histogram (Click to set Gamma)"); - const unsigned char - yellow[] = { 255, 255, 0 }, blue[] = { 0, 155, 255 }, blue2[] = { 0, 0, 255 }, - blue3[] = { 0, 0, 155 }, white[] = { 255, 255, 255 }, green[] = { 50, 128, 50 }; - - for (double gamma = 1; !disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC(); ) { - cimg_forXYZC(visu[0],x,y,z,k) visu[0](x,y,z,k) = (unsigned char)(std::pow((double)img(x,y,z,k),1.0/gamma)*256); - const CImg hist = visu[0].get_histogram(50,0,255); - visu[1].fill(0).draw_text(50,5,"Gamma = %.3g",white,0,1,24,gamma). - draw_graph(hist,green,1,3,0,20000,0).draw_graph(hist,yellow,1,2,0,20000,0). - draw_axes(0,256,20000,0,white,0.7f); - const int xb = (int)(50 + gamma*150); - visu[1].draw_grid(20,20,0,0,false,false,white,0.3f,0xCCCCCCCC,0xCCCCCCCC). - draw_rectangle(51,31,xb - 1,39,blue2).draw_rectangle(50,30,xb,30,blue).draw_rectangle(xb,30,xb,40,blue). - draw_rectangle(xb,40,50,39,blue3).draw_rectangle(50,30,51,40,blue3); - if (disp.button() && disp.mouse_x()>=img.width() + 50 && disp.mouse_x()<=img.width() + 450) - gamma = (disp.mouse_x() - img.width() - 50)/150.0; - disp.resize(disp,false).display(visu).wait(); - } - return 0; -} - -// Item : Filled Triangles -//------------------------- -void* item_filled_triangles() { - - // Create a colored 640x480 background image which consists of different color shades. - CImg background(640,480,1,3); - cimg_forXY(background,x,y) background.fillC(x,y,0, - x*std::cos(6.0*y/background.height()) + - y*std::sin(9.0*x/background.width()), - x*std::sin(8.0*y/background.height()) - - y*std::cos(11.0*x/background.width()), - x*std::cos(13.0*y/background.height()) - - y*std::sin(8.0*x/background.width())); - background.normalize(0,180); - - // Init images and create display window. - CImg img0(background), img; - unsigned char white[] = { 255, 255, 255 }, color[100][3]; - CImgDisplay disp(img0,"[#6] - Filled Triangles (Click to shrink)"); - - // Define random properties (pos, size, colors, ..) for all triangles that will be displayed. - float posx[100], posy[100], rayon[100], angle[100], veloc[100], opacity[100]; - int num = 1; - std::srand((unsigned int)time(0)); - for (int k = 0; k<100; ++k) { - posx[k] = (float)(cimg::rand()*img0.width()); - posy[k] = (float)(cimg::rand()*img0.height()); - rayon[k] = (float)(10 + cimg::rand()*50); - angle[k] = (float)(cimg::rand()*360); - veloc[k] = (float)(cimg::rand()*20 - 10); - color[k][0] = (unsigned char)(cimg::rand()*255); - color[k][1] = (unsigned char)(cimg::rand()*255); - color[k][2] = (unsigned char)(cimg::rand()*255); - opacity[k] = (float)(0.3 + 1.5*cimg::rand()); - } - - // Start animation loop. - while (!disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC()) { - img = img0; - - // Draw each triangle on the background image. - for (int k = 0; k0 && disp.mouse_y()>0) { - float u = disp.mouse_x() - posx[k], v = disp.mouse_y() - posy[k]; - if (disp.button()) { u = -u; v = -v; } - posx[k]-=0.03f*u, posy[k]-=0.03f*v; - if (posx[k]<0 || posx[k]>=img.width()) posx[k] = (float)(cimg::rand()*img.width()); - if (posy[k]<0 || posy[k]>=img.height()) posy[k] = (float)(cimg::rand()*img.height()); - } - } - - // Display current animation framerate, and refresh display window. - img.draw_text(5,5,"%u frames/s",white,0,0.5f,13,(unsigned int)disp.frames_per_second()); - img0.resize(disp.display(img).resize(false).wait(20)); - if (++num>100) num = 100; - - // Allow the user to toggle fullscreen mode, by pressing CTRL+F. - if (disp.is_keyCTRLLEFT() && disp.is_keyF()) disp.resize(640,480,false).toggle_fullscreen(false); - } - return 0; -} - -// Item : Mandelbrot/Julia Explorer -//---------------------------------- -void* item_mandelbrot_explorer() { - - // Define image canvas and corresponding display window. - CImg img(800,600,1,3,0); - CImgDisplay disp(img); - - // Start main explorer loop. - double julia_r = 0, julia_i = 0; - for (bool endflag = false, fractal_type = false, smooth = false, show_help = true; !endflag;) { - bool stopflag = false; - double xmin, xmax, ymin, ymax; - - // Init default upper-left/lower-right coordinates of the fractal set. - if (fractal_type) { xmin = -1.5; xmax = 1.5; ymin = -1.5; ymax = 1.5; julia_r = 0.317; julia_i = 0.029; } - else { xmin = -2.25; xmax = 1.0; ymin = -1.5; ymax = 1.5; julia_r = julia_i = 0; } - - // Create random palette for displaying the fractal set. - const CImg palette = - CImg(256,1,1,3,16 + 120).noise(119,1).resize(1024,1,1,3,3).fillC(0,0,0,0,0,0); - - // Enter event loop for the current fractal set. - for (unsigned int maxiter = 64; !stopflag; ) { - - // Draw Mandelbrot or Julia fractal set on the image. - img.resize(disp.resize().set_title("[#7] - %s Set : (%g,%g)-(%g,%g), %s = (%g,%g) (%u iter.)", - fractal_type?"Julia":"Mandelbrot",xmin,ymin,xmax,ymax, - fractal_type?"c":"z0",julia_r,julia_i,maxiter)). - fill(0).draw_mandelbrot(palette,1,xmin,ymin,xmax,ymax,maxiter,smooth,fractal_type,julia_r,julia_i); - - // Display help if necessary. - if (show_help) { - const unsigned char white[] = { 255, 255, 255 }; - static CImg - help = CImg().draw_text(0,0,"\n" - " Use mouse to zoom on desired region. \n" - " H Show/Hide help \n" - " PAD 1...9 Fractal navigation \n" - " PAD +/- Zoom/Unzoom \n" - " SPACE Set/Disable color smoothing \n" - " ENTER Switch Mandelbrot/Julia sets \n" - " Arrows Change set parameterization \n" - " Page UP/DOWN Add/Reduce iteration numbers \n\n", - white).resize(-100,-100,1,3); - help.draw_rectangle(2,2,help.width() - 3,help.height() - 3,white,1,~0U); - img.draw_image(img.width() - help.width(),help,0.7f); - } - - // Get rectangular shape from the user to define the zoomed region. - const CImg selection = img.get_select(disp,2,0); - const int xs0 = selection[0], ys0 = selection[1], xs1 = selection[3], ys1 = selection[4]; - - // If the user has selected a region with the mouse, then zoom-in ! - if (xs0>=0 && ys0>=0 && xs1>=0 && ys1>=0) { - const double dx =(xmax - xmin)/img.width(), dy =(ymax - ymin)/img.height(); - const int dsmax = (ys1 - ys0)/2, xs = (xs0 + xs1)/2, ys = (ys0 + ys1)/2; - - // If the region is too small (point) then reset the fractal set position and zoom. - if (dsmax<5) stopflag = true; - xmin+=(xs - dsmax*dy/dx)*dx; - ymin+=(ys - dsmax)*dy; - xmax-=(img.width() - xs - dsmax*dy/dx)*dx; - ymax-=(img.height() - ys - dsmax)*dy; - } - - // Also, test if a key has been pressed. - // (moving in the fractal set can be done, using keyboard). - switch (disp.key()) { - - // Show/hide help. - case cimg::keyH: show_help = !show_help; break; - - // Switch between Julia/Mandelbrot sets. - case cimg::keyENTER: fractal_type = !fractal_type; stopflag = true; break; - - // Enable/disable smoothed colors. - case cimg::keySPACE: smooth = !smooth; break; - - // Change fractal set parameters. - case cimg::keyARROWLEFT: julia_r-=fractal_type?0.001f:0.05f; break; - case cimg::keyARROWRIGHT: julia_r+=fractal_type?0.001f:0.05f; break; - case cimg::keyARROWUP: julia_i+=fractal_type?0.001f:0.05f; break; - case cimg::keyARROWDOWN: julia_i-=fractal_type?0.001f:0.05f; break; - - // Add/remove iterations. - case cimg::keyPAGEDOWN: maxiter-=32; break; - case cimg::keyPAGEUP: maxiter+=16; break; - - // Move left, right, up and down in the fractal set. - case cimg::keyPAD4: { const double delta = (xmax - xmin)/10; xmin-=delta; xmax-=delta; } break; - case cimg::keyPAD6: { const double delta = (xmax - xmin)/10; xmin+=delta; xmax+=delta; } break; - case cimg::keyPAD8: { const double delta = (ymax - ymin)/10; ymin-=delta; ymax-=delta; } break; - case cimg::keyPAD2: { const double delta = (ymax - ymin)/10; ymin+=delta; ymax+=delta; } break; - - // Allow to zoom in/out in the fractal set. - case cimg::keyPADADD: { - const double - xc = 0.5*(xmin + xmax), - yc = 0.5*(ymin + ymax), - dx = (xmax - xmin)*0.85/2, - dy = (ymax - ymin)*0.85/2; - xmin = xc - dx; ymin = yc - dy; xmax = xc + dx; ymax = yc + dy; - } break; - case cimg::keyPADSUB: - const double - xc = 0.5*(xmin + xmax), - yc = 0.5*(ymin + ymax), - dx = (xmax - xmin)*1.15/2, - dy = (ymax - ymin)*1.15/2; - xmin = xc - dx; ymin = yc - dy; xmax = xc + dx; ymax = yc + dy; - break; - } - - // Do a simple test to check if more/less iterations are necessary for the next step. - const float value = (float)img.get_norm().get_histogram(256,0,255)(0)*3; - if (value>img.size()/6.0f) maxiter+=16; - if (maxiter>1024) maxiter = 1024; - if (value img(256,256 + 64,1,3,0); - unsigned char color[] = { 255, 255, 255 }; - cimg_for_inY(img,256,img.height() - 1,yy) cimg_forX(img,xx) img.fillC(xx,yy,0,xx,(yy - 256)*4,(3*xx)%256); - CImgDisplay disp(img.draw_text(5,5," ",color,color),"[#8] - Mini-Paint"); - while (!disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC()) { - const unsigned int but = disp.button(); - redraw = false; - xo = x; yo = y; x = disp.mouse_x(); y = disp.mouse_y(); - if (xo>=0 && yo>=0 && x>=0 && y>=0) { - if (but&1 || but&4) { - if (y<253) { - const float tmax = (float)cimg::max(cimg::abs(xo - x),cimg::abs(yo - y)) + 0.1f; - const int radius = (but&1?3:0) + (but&4?6:0); - for (float t = 0; t<=tmax; ++t) - img.draw_circle((int)(x + t*(xo - x)/tmax),(int)(y + t*(yo - y)/tmax),radius,color); - } - if (y>=256) { - color[0] = img(x,y,0); color[1] = img(x,y,1); color[2] = img(x,y,2); - img.draw_text(5,5," ",color,color); - } - redraw = true; - } - if (y>=253) y = 252; - if (disp.button()&2) { img.draw_fill(x,y,color); redraw = true; } - } - if (redraw) disp.display(img); - disp.resize(disp).wait(); - if (disp.key()) cimg_forC(img,k) { img.get_shared_rows(0,255,0,k).fill(0); img.display(disp); } - } - return 0; -} - -// Item : Soccer Bobs -//------------------- -void* item_soccer_bobs() { - CImg foot(data_foot,200,200,1,3,false), canvas0(640,480,1,3,0); - const unsigned char color[] = { 255, 255, 0 }; - float zoom = 0.2f; - cimg_forXY(canvas0,x,y) canvas0(x,y,1) = (unsigned char)(20 + (y*215/canvas0.height()) + 19*cimg::rand(-1,1)); - canvas0.draw_text(5,5,"Left/Right Mouse Button = Zoom In/Out\nMiddle Button = Reset Screen",color); - CImgList canvas(16,canvas0); - CImg mask(foot.width(),foot.height()); - cimg_forXY(mask,x,y) mask(x,y) = (foot(x,y,0)==255 && !foot(x,y,1) && !foot(x,y,2))?0:0.8f; - CImgDisplay disp(canvas0,"[#9] - Unlimited Soccer Bobs"); - for (unsigned int curr_canvas = 0; !disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC(); (++curr_canvas) %= 16) { - if (disp.mouse_x()>=0 && disp.mouse_y()>=0) - canvas[curr_canvas].draw_image((int)(disp.mouse_x() - zoom*foot.width()/2), - (int)(disp.mouse_y() - zoom*foot.height()/2), - foot.get_resize((int)(foot.width()*zoom),(int)(foot.height()*zoom)), - mask.get_resize((int)(foot.width()*zoom),(int)(foot.height()*zoom))); - zoom+=disp.button()&1?0.03f:disp.button()&2?-0.03f:0; - zoom = zoom<0.1f?0.1f:zoom>1?1.0f:zoom; - if (disp.button()&4) cimglist_for(canvas,l) canvas[l] = canvas0; - if (disp.is_keyCTRLLEFT() && disp.is_keyF()) disp.toggle_fullscreen(false); - disp.display(canvas[curr_canvas]).resize(disp,false).wait(20); - } - return 0; -} - -// Item : Bump Effect -//-------------------- -void* item_bump() { - CImg logo = CImg<>(56,32,1,1,0).draw_text(12,3,"I Love\nCImg !",CImg<>::vector(255).data()). - resize(-800,-800,1,1,3).blur(6).normalize(0,255); - logo+=CImg<>(logo.width(),logo.height(),1,1,0).noise(80,1).deriche(2,0,'y',false).deriche(10,0,'x',false); - CImgList grad = logo.get_gradient(); - cimglist_apply(grad,normalize)(-140,140); - logo.normalize(0,255); - CImg light = CImg<>(300 + 2*logo.width(),300 + 2*logo.height()); - light.draw_gaussian(0.5f*light.width(),0.5f*light.height(),80,CImg<>::vector(255).data()); - CImg img(logo.width(),logo.height(),1,3,0); - CImgDisplay disp(img,"[#10] - Bump Effect (Move lightsource with mouse)"); - for (float t = 0; !disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC(); t+=0.03f) { - const int - mouse_x = (disp.mouse_x()>=0 && disp.button())?disp.mouse_x()*img.width()/disp.width(): - (int)(img.width()/2 + img.width()*std::cos(1*t)/2), - mouse_y = (disp.mouse_y()>=0 && disp.button())?disp.mouse_y()*img.height()/disp.height(): - (int)(img.height()/2 + img.height()*std::sin(3*t)/2); - cimg_forXY(img,x,y) { - const int gx = (int)grad[0](x,y), gy = (int)grad[1](x,y); - const float val = 40 + (gx + gy)/2 + light(light.width()/2 + mouse_x - x + gx, - light.height()/2 + mouse_y - y + gy); - img(x,y,0) = img(x,y,1) = img(x,y,2) = (unsigned char)(val>255?255:val<0?0:val); - } - disp.resize(false).display(img.draw_image(0,0,0,1,logo,0.1f)).wait(25); - if (disp.is_keyCTRLLEFT() && disp.is_keyF()) disp.resize(640,480,false).toggle_fullscreen(false); - } - return 0; -} - -// Item : Bouncing Bubble -//------------------------ -void* item_bouncing_bubble() { - CImg back(420,256,1,3,0), img; - cimg_forXY(back,x,y) back(x,y,2) = (unsigned char)((y<2*back.height()/3)?30:(255 - 2*(y + back.height()/2))); - CImgDisplay disp(back,"[#11] - Bouncing bubble"); - const unsigned char col1[] = { 40, 100, 10 }, col2[] = { 20, 70, 0 }, col3[] = { 40, 150, 10 }, - col4[] = { 200, 255, 100 }, white[] = { 255, 255, 255 }; - float u = (float)std::sqrt(2.0f), cx = back.width()/2.0f, t = 0, vt = 0.05f, vx = 2; - while (!disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC()) { - img = back; - int xm = (int)cx, ym = (int)(img.height()/2 - 70 + (img.height()/2 + 10)*(1 - cimg::abs(std::cos((t+=vt))))); - float r1 = 50, r2 = 50; - vt = 0.05f; - if (xm + r1>=img.width()) { const float delta = (xm + r1) - img.width(); r1-=delta; r2+=delta; } - if (xm - r1<0) { const float delta = -(xm - r1); r1-=delta; r2+=delta; } - if (ym + r2>=img.height() - 40) { - const float delta = (ym + r2) - img.height() + 40; - r2-=delta; - r1+=delta; - vt = 0.05f - 0.0015f*(50 - r2); - } - if (ym - r2<0) { const float delta = -(ym - r2); r2-=delta; r1+=delta; } - img.draw_ellipse(xm,ym,r1,r2,0,col1). - draw_ellipse((int)(xm + 0.03*r1*u),(int)(ym - 0.03*r2*u),0.85f*r1,0.85f*r2,0,col2). - draw_ellipse((int)(xm + 0.1*r1*u),(int)(ym - 0.1*r2*u),0.8f*r1,0.8f*r2,0,col1). - draw_ellipse((int)(xm + 0.2*r1*u),(int)(ym - 0.2*r2*u),r1/2,r2/2,0,col3). - draw_ellipse((int)(xm + 0.3*r1*u),(int)(ym - 0.3*r2*u),r1/4,r2/4,0,col4). - draw_image(0,img.height() - 40,img.get_crop(0,img.height() - 80,img.width() - 1,img.height() - 40). - mirror('y'),0.45f). - draw_text(xm - 70,(int)(ym - r2 - 30),"Bubble (%d,%d)",white,0,0.7f,24,xm,ym); - if ((cx+=20*vt*vx)>=img.width() - 30 || cx<30) vx = -vx; - disp.display(img).wait(20); - if (disp.is_resized()) { - back.resize(disp.resize(disp.window_width()>200?disp.window_width():200,disp.height(),false)); - cx = back.width()/2.0f; - } - } - return 0; -} - -// Item : Virtual Landscape -//-------------------------- -void* item_virtual_landscape() { - CImg background(400,300,1,3,0), visu(background); - cimg_forXY(background,x,y) { - if (y>background.height()/2) { - background(x,y,2) = 255; - background(x,y,0) = (y - background.height()/2)*512/background.height(); - } else background(x,y,2) = y*512/background.height(); - } - const int white[] = { 255, 255, 255 }; - CImgDisplay disp(visu.draw_text(10,10,"Please wait, generating landscape...",white). - normalize(0,255),"[#12] - Virtual Landscape",0); - CImg - map = 5.0*(CImg<>(700,700,1,1,300).noise(300).draw_plasma(0.2f,300).normalize(-140,150).blur(5).cut(0,150)), - cmap(map.width(),map.height()); - CImg_3x3(I,float); Ipp = Inp = Icc = Ipn = Inn = 0; - cimg_for3x3(map,x,y,0,0,I,float) { - const float nox = 0.5f*(Inc - Ipc), noy = 0.5f*(Icn - Icp); - cmap(x,y) = cimg::max(0.0f,0.5f*nox + noy); - } - cmap.normalize(0,255); - - for (float t = 0; !disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC(); t+=0.0025f) { - visu = background; - const int - xm = (int)(map.width()/2 + (map.width()/3)*std::cos(4.2f*t)), - ym = (int)(map.height()/2 + (map.height()/3)*std::sin(5.6f*t)); - const CImg - smap = map.get_crop(xm,ym,xm + 100,ym + 90), - scmap = cmap.get_crop(xm,ym,xm + 100,ym + 90); - CImg ymin(visu.width(),1,1,1,visu.height()), ymax(ymin.width(),1,1,1,0); - cimg_forY(smap,z) { - const int y0 = (int)(visu.height() - 1 - 10*std::pow((double)z,0.63) + 80); - cimg_forX(visu,x) { - const int nz = smap.height() - z; - float mx = x*(smap.width() - 2.0f*nz*0.2f)/visu.width() + 0.2f*nz; - const int y = (int)(y0 - smap.linear_atX(mx,z)/(1 + 0.02*z)); - const float cc = (float)scmap.linear_atX(mx,z); - if (y0.25?1:4*cz; - if (y!=y0) for (int l = y>0?y:0; l0?y:0; l plasma, camp(3), cfreq(3), namp(3), nfreq(3); - CImgList font = CImgList::font(53); - CImg visu(400,300,1,3,0), letter, scroll(visu.width() + 2*font['W'].width(),font['W'].height(),1,1,0); - const char *text = " * The CImg Library : C++ Template Image Processing Toolkit *"; - CImgDisplay disp(visu,"[#13] - Plasma Effect"); - const unsigned char white[] = { 255, 255, 255 }; - unsigned int cplasma = 0, pos = 0, tpos = 0, lwidth = 0; - float tx = 0, ts = 0, alpha = 2, beta = 0; - namp.fill(0).noise(visu.height()/4,0); - nfreq.fill(0).noise(0.1); - - visu.draw_text(10,10,"Please wait, generating plasma...",white).display(disp); - const unsigned int nb_plasmas = 5; - plasma.assign(5*visu.width()/3,visu.height() + 1,1,nb_plasmas,0).noise(100).draw_plasma(); - cimg_forC(plasma,k) plasma.get_shared_channel(k).blur((float)(cimg::rand()*6)).normalize(0,255); - - while (!disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC()) { - if (alpha>1) { - alpha-=1; - cplasma = (cplasma + 1)%plasma.spectrum(); - camp = namp; - cfreq = nfreq; - namp.fill(0).noise(100).normalize(0,visu.height()/4.0f); - nfreq.fill(0).noise(0.2); - } - const unsigned int - v0 = cplasma, v1 = (cplasma + 1)%plasma.spectrum(), - v2 = (cplasma + 2)%plasma.spectrum(), v3 = (cplasma + 3)%plasma.spectrum(); - const float umalpha = 1 - alpha; - - unsigned char *ptr_r = visu.data(0,0,0,0), *ptr_g = visu.data(0,0,0,1), *ptr_b = visu.data(0,0,0,2); - cimg_forY(visu,y) { - const float - *ptr_r1 = plasma.data((unsigned int)cimg::max(0.0f,camp(0)*(1.1 + std::sin(tx + cfreq(0)*y))),y,v0), - *ptr_g1 = plasma.data((unsigned int)cimg::max(0.0f,camp(1)*(1.1 + std::sin(tx + cfreq(1)*y))),y,v1), - *ptr_b1 = plasma.data((unsigned int)cimg::max(0.0f,camp(2)*(2 + std::sin(tx + cfreq(2)*y))),y,v2), - *ptr_r2 = plasma.data((unsigned int)cimg::max(0.0f,namp(0)*(1.1 + std::sin(tx + nfreq(0)*y))),y,v1), - *ptr_g2 = plasma.data((unsigned int)cimg::max(0.0f,namp(1)*(1.1 + std::sin(tx + nfreq(1)*y))),y,v2), - *ptr_b2 = plasma.data((unsigned int)cimg::max(0.0f,namp(2)*(2 + std::sin(tx + nfreq(2)*y))),y,v3); - cimg_forX(visu,x) { - *(ptr_r++) = (unsigned char)(umalpha*(*(ptr_r1++)) + alpha*(*(ptr_r2++))); - *(ptr_g++) = (unsigned char)(umalpha*(*(ptr_g1++)) + alpha*(*(ptr_g2++))); - *(ptr_b++) = (unsigned char)(umalpha*(*(ptr_b1++)) + alpha*(*(ptr_b2++))); - } - } - if (!pos) { - const CImg& letter = font(text[tpos] + 256); - lwidth = (unsigned int)letter.width(); - scroll.draw_image(visu.width(),letter); - (++tpos) %= std::strlen(text); - } - scroll.shift(-2); - if ((pos+=2)>lwidth + 2) pos = 0; - cimg_forX(visu,x) { - const int y0 = (int)(visu.height()/2 + visu.height()/4*std::sin(ts + x/(70 + 30*std::cos(beta)))); - cimg_forY(scroll,y) { - if (scroll(x,y)) { - const unsigned int y1 = y0 + y + 2; visu(x,y1,0)/=2; visu(x,y1,1)/=2; visu(x,y1,2)/=2; - const unsigned int y2 = y1 - 6; visu(x,y2,0) = visu(x,y2,1) = visu(x,y2,2) = 255; - } - } - } - alpha+=0.007f; beta+=0.04f; tx+=0.09f; ts+=0.04f; - disp.resize(false).display(visu).wait(20); - if (disp.is_keyCTRLLEFT() && disp.is_keyF()) disp.resize(640,480,false).toggle_fullscreen(false); - } - return 0; -} - -// Item : Oriented Convolutions -//------------------------------ -void* item_oriented_convolutions() { - const CImg img = CImg(data_milla,211,242,1,3).RGBtoYCbCr().channel(0).noise(50,2); - CImgList visu = (img,img,img); - CImg mask(16,16); - const float value = 255; - CImgDisplay disp(visu,"[#14] - Original image, Oriented kernel and Convolved image"); - for (float angle = 0; !disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC(); angle+=0.1f) { - const float ca = (float)std::cos(angle), sa = (float)std::sin(angle); - const CImg - u = CImg<>::vector(ca,sa), - v = CImg<>::vector(-sa,ca), - tensor = 30.0*u*u.get_transpose() + 2.0*v*v.get_transpose(); - mask.draw_gaussian(0.5f*mask.width(),0.5f*mask.height(),tensor,&value); - mask/=mask.sum(); - visu[1] = mask.get_resize(img).normalize(0,255). - draw_text(2,2,"Angle = %d deg",&value,0,1,13,cimg::mod((int)(angle*180/cimg::PI),360)); - visu[2] = img.get_convolve(mask); - disp.resize(disp.window_width(),(int)(disp.height()*disp.window_width()/disp.width()),false). - display(visu).wait(25); - } - return 0; -} - -// Item : Shade Bobs -//------------------- -void* item_shade_bobs() { - float t = 100, rx = 0, ry = 0, rz = 0, rt = 0, rcx = 0; - CImg img(512,512,1,1,0), palette; - CImgDisplay disp(img,"[#15] - Shade Bobs"); - const unsigned char one = 1; - int nbbobs = 0, rybobs = 0; - while (!disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC()) { - if ((t+=0.015f)>4*cimg::PI) { - img.fill(0); - rx = (float)(cimg::rand(-1,1)); - ry = (float)(cimg::rand(-1,1)); - rz = (float)(cimg::rand(-1,1)); - rt = (float)(cimg::rand(-1,1)); - rcx = 0.6f*(float)(cimg::rand(-1,1)); - t = 0; - palette = CImg(3,4 + (int)(12*cimg::rand()),1,1,0).noise(255,2).resize(3,256,1,1,3); - palette(0) = palette(1) = palette(2) = 0; - nbbobs = 20 + (int)(cimg::rand()*80); - rybobs = (10 + (int)(cimg::rand()*50))*cimg::min(img.width(),img.height())/300; - } - for (int i = 0; i tmp(img); - cimg_for3x3(tmp,x,y,0,0,I,unsigned char) img(x,y) = (Inc + Ipc + Icn + Icp + (Icc<<2))>>3; - CImg visu(img.width(),img.height(),1,3); - cimg_forXY(visu,xx,yy) { - const unsigned char *col = palette.data(0,img(xx,yy)); - visu(xx,yy,0) = *(col++); - visu(xx,yy,1) = *(col++); - visu(xx,yy,2) = *(col++); - } - disp.display(visu).wait(25); - if (disp.is_keyCTRLLEFT() && disp.is_keyF()) disp.resize(640,480,false).toggle_fullscreen(false); - if (disp.is_resized()) img.resize(disp.resize(false),3); - if ((disp.key() && !disp.is_keyCTRLLEFT()) || disp.button()) { - t = 70; if (!(disp.is_keyQ() || disp.is_keyESC())) disp.set_key(); - disp.set_button(); - } - } - return 0; -} - -// Item : Fourier Filtering -//------------------------- -void* item_fourier_filtering() { - const CImg img = CImg(data_milla,211,242,1,3).RGBtoYCbCr().channel(0).resize(256,256); - CImgList F = img.get_FFT(); - cimglist_apply(F,shift)(img.width()/2,img.height()/2,0,0,2); - const CImg mag = ((F[0].get_pow(2) + F[1].get_pow(2)).sqrt() + 1).log().normalize(0,255); - CImgList visu(img,mag); - CImgDisplay disp(visu,"[#16] - Fourier Filtering (Click to set filter)"); - CImg mask(img.width(),img.height(),1,1,1); - const unsigned char one[] = { 1 }, zero[] = { 0 }, white[] = { 255 }; - int rmin = 0, rmax = 256; - while (!disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC()) { - disp.wait(); - const int - xm = disp.mouse_x()*2*img.width()/disp.width() - img.width(), - ym = disp.mouse_y()*img.height()/disp.height(), - x = xm - img.width()/2, - y = ym - img.height()/2; - if (disp.button() && xm>=0 && ym>=0) { - const int r = (int)cimg::max(0.0f,(float)std::sqrt((float)x*x + y*y) - 3); - if (disp.button()&1) rmax = r; - if (disp.button()&2) rmin = r; - if (rmin>=rmax) rmin = cimg::max(rmax - 1,0); - mask.fill(0).draw_circle(mag.width()/2,mag.height()/2,rmax,one). - draw_circle(mag.width()/2,mag.height()/2,rmin,zero); - CImgList nF(F); - cimglist_for(F,l) nF[l].mul(mask).shift(-img.width()/2,-img.height()/2,0,0,2); - visu[0] = nF.FFT(true)[0].normalize(0,255); - } - if (disp.is_resized()) disp.resize(disp.window_width(),disp.window_width()/2).display(visu); - visu[1] = mag.get_mul(mask).draw_text(5,5,"Freq Min/Max = %d / %d",white,zero,0.6f,13,(int)rmin,(int)rmax); - visu.display(disp); - } - return 0; -} - -// Item : Image Zoomer -//--------------------- -void* item_image_zoomer() { - const CImg img = CImg(data_logo,555,103,1,3,false); - CImgDisplay disp(img,"[#17] - Original Image"), dispz(500,500,"[#17] - Zoomed Image",0); - disp.move((CImgDisplay::screen_width() - dispz.width())/2, - (CImgDisplay::screen_height() - dispz.height() - disp.height())/2); - dispz.move(disp.window_x(),disp.window_y() + disp.window_height() + 40); - int factor = 20, x = 0, y = 0; - bool grid = false, redraw = false; - while (!disp.is_closed() && !dispz.is_closed() && - !disp.is_keyQ() && !dispz.is_keyQ() && !disp.is_keyESC() && !dispz.is_keyESC()) { - if (disp.mouse_x()>=0) { x = disp.mouse_x(); y = disp.mouse_y(); redraw = true; } - if (redraw) { - const int - x0 = x - factor, y0 = y - factor, - x1 = x + factor, y1 = y + factor; - const unsigned char red[] = { 255, 0, 0 }, black[] = { 0, 0, 0 }, white[] = { 255, 255, 255 }; - (+img).draw_rectangle(x0,y0,x1,y1,red,1.0f,~0U).display(disp); - CImg visu = img.get_crop(x0,y0,x1,y1).draw_point(x - x0,y - y0,red,0.2f).resize(dispz); - if (grid) { - const int bfac = 2*factor + 1; - for (int i = 0; i100) factor = 100; - disp.set_button(); redraw = true; - } - if (disp.button()&4 || dispz.button()) { grid = !grid; disp.set_button(); dispz.set_button(); redraw = true; } - if (disp.is_resized()) disp.resize(disp); - if (dispz.is_resized()) { dispz.resize(); redraw = true; } - CImgDisplay::wait(disp,dispz); - } - return 0; -} - -// Item : Blobs Editor -//-------------------- -void* item_blobs_editor() { - CImg img(300,300,1,3); - CImgList colors; - CImgList blobs; - CImgDisplay disp(img,"[#18] - Blobs Editor",0); - const unsigned int white[] = { 255, 255, 255 }; - bool moving = false; - - for (float alpha = 0; !disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC(); alpha+=0.1f) { - const int xm = disp.mouse_x()*img.width()/disp.width(), ym = disp.mouse_y()*img.height()/disp.height(); - int selected = -1; - img.fill(0); - - if (blobs) { - float dist = 0, dist_min = (float)img.width()*img.width() + img.height()*img.height(); - cimglist_for(blobs,l) { - const CImg& blob = blobs[l]; - const float - xb = blob[0], yb = blob[1], rb = blob[2], - sigma = (float)(rb*(1 + 0.05f*std::cos(blob[3]*alpha))), - sigma2 = 2*sigma*sigma, precision = 4.5f*sigma2; - const int - tx0 = (int)(xb - 3*sigma), - ty0 = (int)(yb - 3*sigma), - tx1 = (int)(xb + 3*sigma), - ty1 = (int)(yb + 3*sigma); - const unsigned int - col1 = colors[l](0), col2 = colors[l](1), col3 = colors[l](2), wh = img.width()*img.height(), - x0 = tx0<0?0:tx0, y0 = ty0<0?0:ty0, - x1 = tx1>=img.width()?img.width() - 1:tx1, y1 = ty1>=img.height()?img.height() - 1:ty1; - float dy = y0 - yb; - unsigned int *ptr = img.data(x0,y0); - for (unsigned int y = y0; y<=y1; ++y) { - float dx = x0 - xb; - for (unsigned int x = x0; x<=x1; ++x) { - float dist = dx*dx + dy*dy; - if (distimg.data(); ++off) { - unsigned int val1 = *(--ptr1), val2 = *(--ptr2), val3 = *(--ptr3); - const unsigned int pot = val1*val1 + val2*val2 + val3*val3; - if (pot<128*128) { *ptr1 = *ptr3 = 255*off/wh; *ptr2 = 180*off/wh; } - else { - if (pot<140*140) { *ptr1 >>= 1; *ptr2 >>= 1; *ptr3 >>= 1; } - else { - *ptr1 = val1<255?val1:255; - *ptr2 = val2<255?val2:255; - *ptr3 = val3<255?val3:255; - } - } - } - cimglist_for(blobs,ll) { - const CImg& blob = blobs[ll]; - const int - rb = (int)(blob[2]*(1 + 0.05f*std::cos(blob[3]*alpha))), - xb = (int)(blob[0] + rb/2.5f), - yb = (int)(blob[1] - rb/2.5f); - img.draw_circle(xb,yb,rb>>1,white,0.2f).draw_circle(xb,yb,rb/3,white,0.2f). - draw_circle(xb,yb,rb/5,white,0.2f); - } - } else { - CImg text; - text.draw_text(0,0, - "CImg Blobs Editor\n" - "-----------------------\n\n" - "* Left mouse button :\n Create and Move Blob.\n\n" - "* Right mouse button :\n Remove nearest Blob.\n\n" - "* Colors and size of Appearing Blobs\n" - " are randomly chosen.\n\n\n" - " >> Press mouse button to start ! <<", - white).resize(-100,-100,1,3); - img.fill(100).draw_image((img.width() - text.width())/2, - (img.height() - text.height())/2, - text,text,1,255U); - } - - if (disp.mouse_x()>=0 && disp.mouse_y()>=0) { - if (disp.button()&1) { - float dist_selected = 0; - if (selected>=0) { - const float a = xm - blobs[selected](0), b = ym - blobs[selected](1), c = blobs[selected](2); - dist_selected = a*a + b*b - c*c; - } - if (moving || dist_selected<0) { blobs[selected](0) = (float)xm; blobs[selected](1) = (float)ym; } - else { - blobs.insert(CImg<>::vector((float)xm,(float)ym,(float)(10 + 30*cimg::rand()),(float)(3*cimg::rand()))); - colors.insert(CImg<>(3).fill(0).noise(255,1).normalize(0,255)); - } - moving = true; - } else moving = false; - if (selected>=0 && disp.button()&2) { blobs.remove(selected); colors.remove(selected); disp.set_button(); } - } - - img.display(disp.wait(25)); - if (disp.is_resized()) { - img.resize(disp.resize(false)); - cimglist_for(blobs,l) if (blobs[l](0)>=img.width() || blobs[l](1)>=img.height()) { - blobs.remove(l); colors.remove(l--); - } - } - } - return 0; -} - -// Item : Double Torus -//--------------------- -void* item_double_torus() { - CImg visu(300,256,1,3,0); - CImgDisplay disp(visu,"[#19] - Double 3D Torus"); - CImgList primitives; - CImg - points = CImg<>::torus3d(primitives,60,20), - points2 = CImg<>::rotation_matrix(1,0,0,(float)cimg::PI/2.0f)*points; - CImgList colors(2*primitives.size(),CImg::vector(255,255,0)); - cimglist_for(primitives,ll) colors[ll++].fill(100,255,100); - cimglist_for(primitives,l) - if (l%2) colors[primitives.size() + l].fill(255,200,255); else colors[primitives.size() + l].fill(200,150,255); - const CImg opacities = CImg<>(primitives.size(),1,1,1,1.0f).append(CImg<>(primitives.size(),1,1,1,0.4f)); - points.shift_object3d(-30,0,0).append_object3d(primitives,points2.shift_object3d(30,0,0),primitives); - float alpha = 0, beta = 0, gamma = 0, theta = 0; - while (!disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC()) { - visu.get_shared_channels(1,2).fill(0); - visu.get_shared_row(visu.height() - 1,0,0).noise(200,1); - CImg_3x3(I,unsigned char); Ipp = Icp = Inp = Ipc = Inc = 0; - cimg_for3x3(visu,x,y,0,0,I,unsigned char) visu(x,y,0) = (Icc + Ipn + Icn + Inn)>>2; - for (unsigned int y = 0; y<100; ++y) std::memset(visu.data(0,y,0,2),255 - y*255/100,visu.width()); - const CImg - rpoints = CImg<>::rotation_matrix(1,1,0,(alpha+=0.01f))*CImg<>::rotation_matrix(1,0,1,(beta-=0.02f))* - CImg<>::rotation_matrix(0,1,1,(gamma+=0.03f))*points; - if (disp.is_resized()) disp.resize(false); - if (disp.is_keyCTRLLEFT() && disp.is_keyF()) disp.resize(300,256,false).toggle_fullscreen(false); - visu.draw_object3d(visu.width()/2.0f,visu.height()/2.0f,0, - rpoints,primitives,colors,opacities,4, - false,500.0f,(float)(std::cos(theta+=0.01f) + 1)*visu.width()/2.0f, - (float)visu.height(),-100.0f,0.1f,1.5f). - display(disp.wait(25)); - } - return 0; -} - -// Item : 3D Metaballs -//--------------------- -struct metaballs3d { - float cx1, cy1, cz1, cx2, cy2, cz2, cx3, cy3, cz3; - inline float operator()(const float x, const float y, const float z) const { - const float - x1 = x - cx1, y1 = y - cy1, z1 = z - cz1, - x2 = x - cx2, y2 = y - cy2, z2 = z - cz2, - x3 = x - cx3, y3 = y - cy3, z3 = z - cz3, - r1 = 0.3f*(x1*x1 + y1*y1 + z1*z1), - r2 = 0.4f*(x2*x2 + y2*y2 + z2*z2), - r3 = 0.5f*(x3*x3 + y3*y3 + z3*z3); - float potential = 0; - if (r1<1.3f) potential+= 1.0f - r1*(r1*(4*r1 + 17) - 22)/9; - if (r2<1.3f) potential+= 1.0f - r2*(r2*(4*r2 + 17) - 22)/9; - if (r3<1.3f) potential+= 1.0f - r3*(r3*(4*r3 + 17) - 22)/9; - return potential; - } -}; - -void* item_3d_metaballs() { - CImg img = CImg(100,100,1,3,0).noise(100,2).draw_plasma(1,0,10). - resize(512,320,1,3).blur(4); - img.get_shared_channel(2)/=4; img.get_shared_channel(1)/=2; - metaballs3d met; - CImgList primitives; - CImgList colors; - const unsigned char white[] = { 255,255,255 }; - float alpha = 0, beta = 0, delta = 0, theta = 0, gamma = 0; - CImgDisplay disp(img,"[#20] - 3D Metaballs"); - while (!disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC()) { - met.cx2 = 1.5f*(float)std::cos(theta); met.cy2 = 2.5f*(float)std::sin(3*(theta+=0.017f)); met.cz2 = 0; - met.cx1 = 0; met.cy1 = 2.0f*(float)std::sin(4*gamma); met.cz1 = 1.2f*(float)std::cos(2*(gamma-=0.0083f)); - met.cx3 = 2.5f*(float)std::cos(2.5*delta); met.cy3 = 0; met.cz3 = 1.5f*(float)std::sin(2*(delta+=0.0125f)); - const CImg - points = CImg<>::isosurface3d(primitives,met,0.8f,-4.5f,-4.5f,-3.5f,4.5f,4.5f,3.5f,24,24,24), - rot = 50.0*CImg<>::rotation_matrix(0,0,1,(alpha+=0.02f))*CImg<>::rotation_matrix(1,1,0,(beta+=0.076f)), - rpoints = rot*points; - primitives.reverse_object3d(); - if (colors.size() img(640,480,1,3,0); - CImgDisplay disp(img,"[#21] - Fireworks (Click to add/explode rockets)"); - CImgList colors; - const unsigned char white[] = { 255,255,255 }, red[] = { 128,0,0 }; - CImgList particles; - float time = 0, speed = 100.0f; - - while (!disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC()) { - - if (disp.button()&1 || !particles.size() || (--time)<0) { - particles.insert(CImg<>::vector((float)cimg::rand()*img.width(),(float)img.height(), - (float)cimg::rand(-1,1)*4,-6 - (float)cimg::rand()*3, - 30 + 60*(float)cimg::rand(),3)); - colors.insert(CImg::vector(255,255,255)); - time = (float)(cimg::rand()*speed); - } - img*=0.92f; - - cimglist_for(particles,l) { - bool remove_particle = false; - float &x = particles(l,0), &y = particles(l,1), &vx = particles(l,2), &vy = particles(l,3), - &t = particles(l,4), &r = particles(l,5); - const float r2 = (t>0 || t<-42)?r/3:r*(1 - 2*(-(t + 2)/40.0f)/3); - img.draw_ellipse((int)x,(int)y,r,r2,(float)(std::atan2(vy,vx)*180/cimg::PI),colors[l].data(),0.6f); - x+=vx; y+=vy; vy+=0.09f; t--; - if (y>img.height() + 10 || x<0 || x>=img.width() + 10) remove_particle = true; - - if (t<0 && t>=-1) { - if ((speed*=0.9f)<10) speed=10.0f; - const unsigned char - r = (unsigned char)cimg::min(50 + 3*(unsigned char)(100*cimg::rand()), 255), - g = (unsigned char)cimg::min(50 + 3*(unsigned char)(100*cimg::rand()), 255), - b = (unsigned char)cimg::min(50 + 3*(unsigned char)(100*cimg::rand()), 255); - const float di = 10 + (float)cimg::rand()*60, nr = (float)cimg::rand()*30; - for (float i=0; i<360; i+=di) { - const float rad = i*(float)cimg::PI/180, c = (float)std::cos(rad), s = (float)std::sin(rad); - particles.insert(CImg<>::vector(x,y,2*c + vx/1.5f,2*s + vy/1.5f,-2.0f,nr)); - colors.insert(CImg::vector(r,g,b)); - } - remove_particle = true; - } else if (t<-1) { r*=0.95f; if (r<0.5f) remove_particle=true; } - if (remove_particle) { particles.remove(l); colors.remove(l); l--; } - } - if (disp.button()&2) cimglist_for(particles,l) if (particles(l,4)>0) particles(l,4)=0.5f; - img.draw_text(5,5," %u frames/s ",white,red,0.5f,13,(unsigned int)disp.frames_per_second()); - disp.display(img).wait(25); - if (disp.is_keyCTRLLEFT() && disp.is_keyF()) disp.resize(640,480,false).toggle_fullscreen(false); - if (disp.is_resized()) disp.resize(disp,false); - } - return 0; -} - -// Item : Rubber Logo -//-------------------- -void* item_rubber_logo() { - const unsigned char white[] = { 255,255,255 }; - CImg background = CImg(300,300).noise(100,2); - background(0,0) = background(299,0) = background(299,299) = background(0,299) = 0; - background.draw_plasma().blur(1.0f,14.0f,0.0f,0).resize(-100,-100,1,3); - CImgDisplay disp(CImg(background). - draw_text(10,10,"Please wait, generating rubber object...",white),"[#22] - 3D Rubber Logo"); - - CImg vol = CImg().draw_text(30,30,"CImg",white,0,1,57).resize(-100,-100,15,1); - for (unsigned int k = 0; k<5; ++k) { vol.get_shared_slice(k).fill(0); vol.get_shared_slice(vol.depth()-1-k).fill(0); } - vol.resize(vol.width() + 30,vol.height() + 30,-100,1,0).blur(2).resize(-50,-50); - CImgList faces; - CImg points = vol.get_isosurface3d(faces,45); - CImgList colors(faces.size(),CImg::vector(100,100,255)); - cimglist_for(colors,l) { - const float x = (points(faces(l,0),0) + points(faces(l,1),0) + points(faces(l,2),0))/3; - if (x<30.3) colors[l] = CImg::vector(255,100,100); - else { if (x<34.6) colors[l] = CImg::vector(200,155,100); - else { if (x<55.5) colors[l] = CImg::vector(100,255,155); - }}} - faces.reverse_object3d(); - points.shift_object3d()*=5.5f; - - CImgList frames(100,background); - bool ok_visu = false; - unsigned int nb_frame = 0; - float alpha = 0, beta = 0, gamma = 0; - - while (!disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC()) { - CImg& frame = frames[nb_frame++]; - if (nb_frame>=frames.size()) { ok_visu = true; nb_frame = 0; } - const CImg - rot = CImg<>::rotation_matrix(0,1,0.2f,alpha+=0.011f)* - CImg<>::rotation_matrix(1,0.4f,1,beta+=0.015f)* - (1 + 0.1f*std::cos((double)(gamma+=0.1f))); - (frame=background).draw_object3d(frame.width()/2.0f,frame.height()/2.0f,frame.depth()/2.0f, - rot*points,faces,colors,5,false,500,0,0,-5000,0.1f,1.0f); - if (ok_visu) { - CImg visu(frame); - cimglist_for(frames,l) { - const unsigned int - y0 = l*visu.height()/frames.size(), - y1 = (l + 1)*visu.height()/frames.size() - 1; - cimg_forC(visu,k) - visu.get_shared_rows(y0,y1,0,k) = frames[(nb_frame + l)%frames.size()].get_shared_rows(y0,y1,0,k); - } - visu.get_resize(disp,1).draw_text(5,5," %u frames/s ",white,0,0.5f,13,(unsigned int)disp.frames_per_second()). - display(disp.wait(20)); - } - if (disp.is_keyCTRLLEFT() && disp.is_keyF()) disp.resize(300,300,false).toggle_fullscreen(false); - if (disp.is_resized()) disp.resize(); - } - return 0; -} - -// Item : Image Waves -//-------------------- -void* item_image_waves() { - const CImg img = CImg(data_milla,211,242,1,3,false).get_resize(128,128,1,3); - CImgList faces0; - CImgList colors0; - const CImgList - points0 = (img.get_elevation3d(faces0,colors0,img.get_channel(0).fill(0)).shift_object3d()*=3)<'x', - opacities0(faces0.size(),1,1,1,1,1.0f); - CImg - back = CImg(400,300,1,3).sequence(0,130), - ball = CImg(12,12,1,3,0).draw_circle(6,6,5,CImg::vector(0,128,64).data()); - const CImg mball = CImg<>(12,12,1,1,0).draw_circle(6,6,5,CImg<>::vector(1.0f).data()); - ball.draw_circle(7,5,4,CImg::vector(16,96,52).data()). - draw_circle(8,4,2,CImg::vector(0,128,64).data()). - draw_circle(8,4,1,CImg::vector(64,196,128).data()); - CImg uc(img.width()/2,img.height()/2,1,1,0), up(uc), upp(uc); - CImgList particles; - CImgDisplay disp(back,"[#23] - Image Waves (Try mouse buttons!)"); - for (float alpha = 0.0f, count = 10.0f; !disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC(); ) { - if ((disp.button()&1 && disp.mouse_x()>=0) || --count<0) { - CImg<>::vector((float)(cimg::rand()*(img.width() - 1)),(float)(cimg::rand()*(img.height() - 1)),-200,0). - move_to(particles); - count = (float)(cimg::rand()*15); - } - alpha = (disp.mouse_x()>=0 && disp.button()&2)?(float)(disp.mouse_x()*2*cimg::PI/disp.width()):(alpha + 0.02f); - if (disp.is_keyCTRLLEFT() && disp.is_keyF()) disp.resize(400,300,false).toggle_fullscreen(false); - cimglist_for(particles,l) { - float& z = up((int)particles(l,0)>>1,(int)particles(l,1)>>1); - if ((particles(l,2)+=(particles(l,3)+=0.5f))>z-10) { z = 250.0f; particles.remove(l--); } - } - CImg_3x3(U,float); Upp = Unp = Ucc = Upn = Unn = 0; - cimg_for3x3(up,x,y,0,0,U,float) uc(x,y) = (Unc + Upc + Ucn + Ucp)/2 - upp(x,y); - (uc-=(float)(uc.blur(0.7f).mean())).swap(upp).swap(up); - CImgList points(points0); - CImgList faces(faces0); - CImgList colors(colors0); - CImgList opacities(opacities0); - cimglist_for(points,p) - points(p,2) = cimg::min(30 + uc.linear_atXY((p%img.width())/2.0f,(p/img.width())/2.0f),70.0f); - cimglist_for(particles,l) { - points.insert(CImg<>::vector(3*(particles(l,0) - img.width()/2.0f),3*(particles(l,1) - img.height()/2.0f),30.0f + - particles(l,2))); - faces.insert(CImg::vector(points.size() - 1)); - colors.insert(ball,~0U,true); - opacities.insert(mball,~0U,true); - } - const CImg - rot = CImg<>::rotation_matrix(1.0f,0,0,(float)(cimg::PI/3.0f))*CImg<>::rotation_matrix(0,0,1.0f,alpha), - rpoints = rot*(points>'x'); - (+back).draw_object3d(back.width()/2.0f,back.height()/2.0f,0,rpoints,faces,colors,opacities,4,false, - 500.0f,0,0,0,1,1).display(disp.resize(false).wait(30)); - } - return 0; -} - -// Item : Breakout -//----------------- -void* item_breakout() { - - // Init graphics - CImg - board(8,10,1,1,0), - background = CImg(board.width()*32,board.height()*16 + 200,1,3,0).noise(20,1). - draw_plasma().blur(1,8,0,true), - visu0(background/2.0), visu(visu0), brick(16,16,1,1,200), racket(64,8,1,3,0), ball(8,8,1,3,0); - const unsigned char white[] = { 255,255,255 }, green1[] = { 60,150,30 }, green2[] = { 130,255,130 }; - cimg_for_borderXY(brick,x,y,1) brick(x,y) = x>y?255:128; - cimg_for_insideXY(brick,x,y,1) brick(x,y) = (unsigned char)cimg::min(255,64 + 8*(x + y)); - brick.resize(31,15,1,1,1).resize(32,16,1,1,0); - ball.draw_circle(4,4,2,white); ball-=ball.get_erode(3)/1.5; - racket.draw_circle(4,3,4,green1).draw_circle(3,2,2,green2); - cimg_forY(racket,y) - racket.draw_rectangle(4,y,racket.width() - 7,y, - CImg::vector((unsigned char)(y*4), - (unsigned char)(255 - y*32), - (unsigned char)(255 - y*25)).data()); - racket.draw_image(racket.width()/2,racket.get_crop(0,0,racket.width()/2 - 1,racket.height() - 1).mirror('x')); - const int - w = visu.width(), h = visu.height(), w2 = w/2, h2 = h/2, - bw = ball.width(), bh = ball.height(), bw2 = bw/2, bh2 = bh/2, - rw = racket.width(), rh = racket.height(), rw2 = rw/2; - float xr = (float)(w - rw2), oxr = (float)xr, xb = 0, yb = 0, oxb = 0, oyb = 0, vxb = 0, vyb = 0; - const CImg - racket_mask = racket.get_threshold(1).channel(1), - ball_mask = ball.get_threshold(1).channel(1); - - // Begin game loop - CImgDisplay disp(visu,"[#24] - Breakout"); - disp.move((CImgDisplay::screen_width() - w)/2,(CImgDisplay::screen_height() - h)/2); - for (unsigned int N = 0, N0 = 0; !disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC(); ) { - if (N0) { - int X = (int)xr; - if (disp.mouse_x()>=0) X = (int)(w2 + ((disp.mouse_x()<0?w2:disp.mouse_x()) - w2)*2); - else disp.set_mouse(xr>w2?w - 81:80,h2); - if (X=w - rw2) { X = w - rw2 - 1; disp.set_mouse(w - 81,h2); } - oxr = xr; xr = (float)X; oxb = xb; oyb = yb; xb+=vxb; yb+=vyb; - if ((xb>=w - bw2) || (xb=h - rh - 8 - bh2 && yb=xb) { - xb = oxb; yb = h - rh - 8.0f - bh2; vyb=-vyb; vxb+=(xr - oxr)/4; - if (cimg::abs(vxb)>8) vxb*=8/cimg::abs(vxb); - } - if (yb=((X + 1)<<5)) vxb=-vxb; - else if (oyb<(Y<<4) || oyb>=((Y + 1)<<4)) vyb=-vyb; - } - } - disp.set_title("[#24] - Breakout : %u/%u",N,N0); - } - if (yb>h || N==N0) { - disp.show_mouse(); - while (!disp.is_closed() && !disp.key() && !disp.button()) { - ((visu=visu0)/=2).draw_text(50,visu.height()/2 - 10,N0?" Game Over !":"Get Ready ?",white,0,1,24). - display(disp); - disp.wait(); - if (disp.is_resized()) disp.resize(disp); - } - board.fill(0); visu0 = background; - cimg_forXY(board,x,y) if (0.2f + cimg::rand(-1,1)>=0) { - CImg cbrick = CImg::vector(100 + cimg::rand()*155,100 + cimg::rand()*155,100 + cimg::rand()*155). - unroll('v').resize(brick.width(),brick.height()); - cimg_forC(cbrick,k) (cbrick.get_shared_channel(k).mul(brick))/=255; - visu0.draw_image(x*32,y*16,cbrick); - board(x,y) = 1; - } - N0 = (int)board.sum(); N = 0; - oxb = xb = (float)w2; oyb = yb = board.height()*16.0f + bh; vxb = 2.0f; vyb = 3.0f; - disp.hide_mouse(); - } else disp.display((visu=visu0).draw_image((int)(xr - rw2),h - rh - 8,racket,racket_mask). - draw_image((int)(xb - bw2),(int)(yb - bh2),ball,ball_mask)); - if (disp.is_resized()) disp.resize(disp); - disp.wait(20); - } - return 0; -} - -// Item : 3D Reflection -//---------------------- -void* item_3d_reflection() { - - // Init images and display - CImgDisplay disp(512,512,"[#25] - 3D Reflection",0); - CImg back = CImg(200,400,1,3,0).rand(0,255).draw_plasma(); - ((back,back.get_mirror('x'),back)>'x').blur(15,1,0,true).columns(100,499).normalize(0,120).move_to(back); - CImg - light0 = back.get_resize(-50,-50,1,1).normalize(1,255), - visu(back), - reflect(back.width(),back.height(),1,1), - light(light0); - back.get_shared_channel(0)/=3; - back.get_shared_channel(2)/=2; - - // Create 3D objects. - CImgList back_faces, main_faces; - CImgList main_colors, back_colors, light_colors, light_colors2; - CImgList back_pts0, main_pts = CImg<>::torus3d(main_faces,30,12,24,12)<'x'; - cimglist_for(main_faces,l) - if (l%2) CImg::vector(255,120,16).move_to(main_colors); - else CImg::vector(255,100,16).move_to(main_colors); - - const unsigned int res1 = 32, res2 = 32; - for (unsigned int v = 1; v::vector(x,y,z)); - } - const unsigned int N = back_pts0.size(); - back_pts0.insert(CImg<>::vector(0,0,-140)).insert(CImg<>::vector(0,0,140)); - CImg back_pts = back_pts0>'x'; - for (unsigned int vv = 0; vv::vector(res1*vv + nu,res1*nv + uu,res1*vv + uu)); - back_faces.insert(CImg::vector(res1*vv + nu,res1*nv + nu,res1*nv + uu)); - back_colors.insert(CImg::vector(128,255,255)); - back_colors.insert(CImg::vector(64,240,196)); - } - for (unsigned int uu = 0; uu::vector(nu,uu,N)); - back_faces.insert(CImg::vector(res1*(res2 - 2) + nu, N + 1,res1*(res2 - 2) + uu)); - if (uu%2) back_colors.insert(2,CImg::vector(128,255,255)); - else back_colors.insert(2,CImg::vector(64,240,196)); - } - light_colors.assign(main_faces.size(),CImg::vector(255)); - light_colors2.assign(back_faces.size(),CImg::vector(255)).insert(light,~0U,true); - - // Start 3D animation. - for (float main_x = -1.5f*visu.width(), - back_alpha = 0, back_beta = 0, back_theta = -3.0f, - main_alpha = 0, main_beta = 0, main_theta = 0; - !disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC(); - main_alpha+=0.041f, main_beta+=0.063f, main_theta+=0.02f, - back_alpha+=0.0031f, back_beta+=0.0043f, back_theta+=0.01f) { - const int - main_X = (int)(visu.width()/2 + main_x + 100*std::cos(2.1*main_theta)), - main_Y = (int)(visu.height()/2 + 120*std::sin(1.8*main_theta)); - CImg - rmain_pts = (CImg<>::rotation_matrix(-1,1,0,main_alpha)*CImg<>::rotation_matrix(1,0,1,main_beta))*(main_pts>'x'), - rback_pts = (CImg<>::rotation_matrix(1,1,0,back_alpha)*CImg<>::rotation_matrix(0.5,0,1,back_beta))*back_pts; - - (light=light0).draw_object3d(main_X/2.0f,main_Y/2.0f,0,rmain_pts,main_faces,light_colors,3,false, - 500,0,0,-5000,0.2f,0.1f); - reflect.fill(0).draw_object3d(2*visu.width()/3.0f,visu.height()/2.0f,0,rback_pts,back_faces,light_colors2,5,false, - 500,0,0,-5000,0.2f,0.1f); - rmain_pts*=2; - (visu=back).draw_object3d(2*visu.width()/3.0f,visu.height()/2.0f,0,rback_pts,back_faces,back_colors,3,false, - 500,0,0,-5000,0.2f,0.1f); - - unsigned char - *ptrs = reflect.data(), - *ptrr = visu.data(0,0,0,0), - *ptrg = visu.data(0,0,0,1), - *ptrb = visu.data(0,0,0,2); - cimg_foroff(reflect,xy) { - const unsigned char v = *(ptrs++); - if (v) { *ptrr = (*ptrr+v)>>1; *ptrg = (*ptrr+v)>>1; *ptrb = (*ptrb+v)>>1; } - ++ptrr; ++ptrg; ++ptrb; - } - - visu.draw_object3d((float)main_X,(float)main_Y,0,rmain_pts,main_faces,main_colors,4, - false,500,0,0,-5000,0.1f,1.4f); - - if (disp.is_resized()) { - const int s = cimg::min(disp.window_width(),disp.window_height()); - disp.resize(s,s,false); - } - if (disp.is_keyCTRLLEFT() && disp.is_keyF()) disp.resize(512,512,false).toggle_fullscreen(false); - disp.display(visu).wait(20); - back.shift(4,0,0,0,2); - light0.shift(-2,0,0,0,2); - if (main_x<0) main_x +=2; - const float H = back_theta<0?0.0f:(float)(0.3f - 0.3f*std::cos(back_theta)); - for (unsigned int p = 0, v = 1; v img0 = CImg(data_logo,555,103,1,3,true).get_resize(-144,-144,1,3,6); - CImgDisplay disp(img0,"[#26] - Fish-Eye Magnification"); - int rm = 80, xc = 0, yc = 0, rc = 0; - CImg img, res; - for (float alpha = 0; !disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC(); alpha+=0.02f) { - if (!img) img = img0.get_resize(disp,3); - if (disp.mouse_x()>=0) { xc = disp.mouse_x(); yc = disp.mouse_y(); rc = rm; } - else { - xc = (int)(img.width()*(1 + 0.9f*std::cos(1.2f*alpha))/2); - yc = (int)(img.height()*(1 + 0.8f*std::sin(3.4f*alpha))/2); - rc = (int)(90 + 60*std::sin(alpha)); - } - const int x0 = xc - rc, y0 = yc - rc, x1 = xc + rc, y1 = yc + rc; - res = img; - cimg_for_inXY(res,x0,y0,x1,y1,x,y) { - const float X = (float)x - xc, Y = (float)y - yc, r2 = X*X + Y*Y, rrc = (float)std::sqrt(r2)/rc; - if (rrc<1) { - const int xi = (int)(xc + rrc*X), yi = (int)(yc + rrc*Y); - res(x,y,0) = img(xi,yi,0); res(x,y,1) = img(xi,yi,1); res(x,y,2) = img(xi,yi,2); - } - } - const int xf = xc + 3*rc/8, yf = yc - 3*rc/8; - res.draw_circle(xc,yc,rc,purple,0.2f).draw_circle(xf,yf,rc/3,white,0.2f).draw_circle(xf,yf,rc/5,white,0.2f). - draw_circle(xf,yf,rc/10,white,0.2f).draw_circle(xc,yc,rc,black,0.7f,~0U); - disp.display(res).wait(20); - rm+=(disp.button()&1?8:(disp.button()&2?-8:0)); - rm = rm<30?30:(rm>200?200:rm); - if (disp.is_resized()) { disp.resize(false); img.assign(); } - } - return 0; -} - -// Item : Word Puzzle -//-------------------- -void* item_word_puzzle() { - - // Create B&W and color letters - CImg model(60,60,1,3,0), color(3), background, canvas, elaps; - CImgList letters('Z' - 'A' + 1), cletters(letters); - const unsigned char white[] = { 255, 255, 255 }, gray[] = { 128, 128, 128 }, black[] = { 0, 0, 0 }; - char tmptxt[] = { 'A',0 }; - model.fill(255).draw_rectangle(5,5,54,54,gray).blur(3,0).threshold(140).normalize(0,255); - cimglist_for(letters,l) - (letters[l].draw_text(5,2,&(tmptxt[0]=(char)('A' + l)),white,0,1,57).resize(60,60,1,1,0,0,0.5,0.5). - resize(-100,-100,1,3)|=model).blur(0.5); - { cimglist_for(cletters,l) { - CImg tmp = letters[l]; - color.rand(100,255); - cimg_forC(tmp,k) (tmp.get_shared_channel(k)*=color[k])/=255; - cletters[l] = tmp; - }} - - CImgDisplay disp(500,400,"[#27] - Word Puzzle",0); - while (!disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC()) { - - // Create background, word data and display. - background.assign(40,40,1,2,0).noise(30,2).distance(255).normalize(0,255).resize(500,400,1,3,3); - CImg current(14,6,1,1,0), solution(14,4,1,1,0); - current.get_shared_row(0).fill('T','H','E','C','I','M','G','L','I','B','R','A','R','Y'); - current.get_shared_row(1).rand(-30,background.width() - 30); - current.get_shared_row(2).rand(-30,background.height() - 30); - solution.get_shared_row(0) = current.get_shared_row(0); - solution.get_shared_row(1).fill(20,80,140,100,180,260,340,40,100,160,220,280,340,400); - solution.get_shared_row(2).fill(20,20,20,120,150,180,210,310,310,310,310,310,310,310); - cimg_forX(solution,l) background.draw_image(solution(l,1),solution(l,2),letters(solution(l) - 'A'),0.3f); - const int last = current.width() - 1; - - // Start user interaction - int timer = 0, completed = 0; - for (bool selected = false, refresh_canvas = true, stopflag = false; - !stopflag && !disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC(); disp.resize(disp).wait(20)) { - if (refresh_canvas) { - canvas = background; - cimg_forX(current,l) if (!current(l,5)) { - int &x = current(l,1), &y = current(l,2); - if (x<-30) x = -30; else if (x>canvas.width() - 30) x = canvas.width() - 30; - if (y<-30) y = -30; else if (y>canvas.height() - 30) y = canvas.height() - 30; - canvas.draw_rectangle(x + 8,y + 8,x + 67,y + 67,black,0.3f).draw_image(x,y,cletters(current(l) - 'A')); - } - refresh_canvas = false; - } - (+canvas).draw_text(280,3,"Elapsed Time : %d",white,0,0.7f,24,timer++).display(disp); - - if (disp.button()&1) { - const int mx = disp.mouse_x(), my = disp.mouse_y(); - if (mx>=0 && my>=0) { - if (!selected) { - int ind = -1; - cimg_forX(current,l) if (!current(l,5)) { - const int x = current(l,1), y = current(l,2), dx = mx - x, dy = my - y; - if (dx>=0 && dx<60 && dy>=0 && dy<60) { selected = true; ind = l; current(l,3) = dx; current(l,4) = dy; } - } - if (ind>=0 && ind vec = current.get_column(ind); - current.draw_image(ind,current.get_crop(ind + 1,last)).draw_image(last,vec); - } - } else { - current(last,1) = mx - current(last,3); - current(last,2) = my - current(last,4); - refresh_canvas = true; - } - } - } else { - bool win = true; - cimg_forX(solution,j) if (!solution(j,3)) { - win = false; - const int x = solution(j,1), y = solution(j,2); - cimg_forX(current,i) if (!current(i,5) && solution(j)==current(i)) { - const int xc = current(i,1), yc = current(i,2), dx = cimg::abs(x - xc), dy = cimg::abs(y - yc); - if (dx<=12 && dy<=12) { - cimg_forC(background,k) cimg_forY(letters[0],y) - background.get_shared_row(solution(j,2) + y,0,k). - draw_image(solution(j,1),0, - (CImg<>(cletters(solution(j) - 'A').get_shared_row(y,0,k))*=2.0*std::cos((y - 30.0f)/18)). - cut(0,255),0.8f); - current(i,5) = solution(j,3) = 1; refresh_canvas = true; - } - } - } - selected = false; - if (win) { stopflag = true; completed = 1; } - } - } - - // Display final score - const char - *const mention0 = "Need more training !", *const mention1 = "Still amateur, hu ?", - *const mention2 = "Not so bad !", *const mention3 = " Good !", *const mention4 = "Very good !", - *const mention5 = " Expert !", - *mention = completed?(timer<700?mention5:timer<800?mention4:timer<900?mention3: - timer<1000?mention2:timer<1200?mention1:mention0):mention0; - canvas.assign().draw_text(0,0,"Final time : %d\n\n%s",white,0,1,32,timer,mention).resize(-100,-100,1,3); - ((background/=2)&CImg(2,2).fill((unsigned char)0,255,255,0).resize(background,0,2)). - draw_image((background.width() - canvas.width())/2,(background.height() - canvas.height())/2, - canvas,canvas.get_dilate(3).dilate(3).dilate(3),1,255).display(disp.flush()); - while (!disp.is_closed() && !disp.key() && !disp.button()) disp.resize(disp).wait(); - } - return 0; -} - -// Run a selected effect -//----------------------- -void start_item(const unsigned int demo_number) { - switch (demo_number) { - case 1: item_blurring_gradient(); break; - case 2: item_rotozoom(); break; - case 3: item_anisotropic_smoothing(); break; - case 4: item_fractal_animation(); break; - case 5: item_gamma_correction(); break; - case 6: item_filled_triangles(); break; - case 7: item_mandelbrot_explorer(); break; - case 8: item_mini_paint(); break; - case 9: item_soccer_bobs(); break; - case 10: item_bump(); break; - case 11: item_bouncing_bubble(); break; - case 12: item_virtual_landscape(); break; - case 13: item_plasma(); break; - case 14: item_oriented_convolutions(); break; - case 15: item_shade_bobs(); break; - case 16: item_fourier_filtering(); break; - case 17: item_image_zoomer(); break; - case 18: item_blobs_editor(); break; - case 19: item_double_torus(); break; - case 20: item_3d_metaballs(); break; - case 21: item_fireworks(); break; - case 22: item_rubber_logo(); break; - case 23: item_image_waves(); break; - case 24: item_breakout(); break; - case 25: item_3d_reflection(); break; - case 26: item_fisheye_magnification(); break; - case 27: item_word_puzzle(); break; - default: break; - } -} - -/*--------------------------- - - Main procedure - - --------------------------*/ -int main(int argc, char **argv) { - - // Display info about the CImg Library configuration - //-------------------------------------------------- - unsigned int demo_number = cimg_option("-run",0,0); - if (demo_number) start_item(demo_number); - else { - cimg::info(); - - // Demo selection menu - //--------------------- - const unsigned char - white[] = { 255, 255, 255 }, black[] = { 0, 0, 0 }, red[] = { 120, 50, 80 }, - yellow[] = { 200, 155, 0 }, green[] = { 30, 200, 70 }, purple[] = { 175, 32, 186 }, - blue[] = { 55, 140, 185 }, grey[] = { 127, 127, 127 }; - float - rx = 0, ry = 0, t = 0, gamma = 0, vgamma = 0, T = 0.9f, - nrx = (float)(2*cimg::rand(-1,1)), - nry = (float)(2*cimg::rand(-1,1)); - int y0 = 2*13; - CImg back(1,2,1,3,10), fore, text, img; - back.fillC(0,1,0,10,10,235).resize(350,570,1,3,3).get_shared_channel(2).noise(10,1).draw_plasma(); - back.draw_rectangle(0,y0 - 7,back.width() - 1,y0 + 20,red); - fore.assign(back.width(),50,1,1,0).draw_text(20,y0 - 3,"** CImg %u.%u.%u Samples **",grey,0,1,23, - cimg_version/100,(cimg_version/10)%10,cimg_version%10); - (fore+=fore.get_dilate(3).dilate(3)).resize(-100,-100,1,3); - cimg_forXY(fore,x,y) - if (fore(x,y)==127) fore(x,y,0) = fore(x,y,1) = fore(x,y,2) = 1; - else if (fore(x,y)) { - const float val = cimg::min(255.0f,7.0f*(y - 3)); - fore(x,y,0) = (unsigned char)(val/1.5f); - fore(x,y,1) = (unsigned char)val; - fore(x,y,2) = (unsigned char)(val/1.1f); - } - text.draw_text(1,1, - "1- Blurring Gradient\n" - "2- Rotozoom\n" - "3- Anisotropic Smoothing\n" - "4- Fractal Animation\n" - "5- Gamma Correction\n" - "6- Filled Triangles\n" - "7- Mandelbrot explorer\n" - "8- Mini-Paint\n" - "9- Soccer Bobs\n" - "10- Bump Effect\n" - "11- Bouncing Bubble\n" - "12- Virtual Landscape\n" - "13- Plasma & Sinus Scroll\n" - "14- Oriented Convolutions\n" - "15- Shade Bobs\n" - "16- Fourier Filtering\n" - "17- Image Zoomer\n" - "18- Blobs Editor\n" - "19- Double Torus\n" - "20- 3D Metaballs\n" - "21- Fireworks\n" - "22- Rubber Logo\n" - "23- Image Waves\n" - "24- Breakout\n" - "25- 3D Reflection\n" - "26- Fish-Eye Magnification\n" - "27- Word Puzzle\n", - white,0,1,18).resize(-100,-100,1,3); - fore.resize(back,0).draw_image(20,y0 + 3*13,text|=text.get_dilate(3)>>4); - - CImgDisplay disp(back,"CImg Library Samples",0,false,true); - disp.move((disp.screen_width() - disp.window_width())/2,(disp.screen_height() - disp.window_height())/2); - img = back; back*=0.15f; - for (y0+=3*13; !disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC(); demo_number = 0) { - while (!demo_number && !disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC()) { - img*=0.85f; img+=back; - for (int i = 0; i<60; ++i) { - const float - mx = (float)(img.width()/2 + (img.width()/2 - 30)*((1 - gamma)*std::cos(3*t + rx*i*18.0f*cimg::PI/180) + - gamma*std::cos(3*t + nrx*i*18.0f*cimg::PI/180))), - my = (float)(img.height()/2 + (img.height()/2 - 30)*((1 - gamma)*std::sin(4*t + ry*i*18.0f*cimg::PI/180) + - gamma*std::sin(4*t + nry*i*18.0f*cimg::PI/180))), - mz = (float)(1.3f + 1.2f*((1 - gamma)*std::sin(2*t + (rx + ry)*i*20*cimg::PI/180) + - gamma*std::sin(2*t + (nrx + nry)*i*20*cimg::PI/180))); - const int j = i%5; - img.draw_circle((int)mx,(int)my,(int)(10*mz),j!=0?(j!=1?(j!=2?(j!=3?green:red):yellow):purple):blue,0.2f). - draw_circle((int)(mx + 4*mz),(int)(my - 4),(int)(3*mz),white,0.1f). - draw_circle((int)mx,(int)my,(int)(10*mz),black,0.2f,~0U); - } - const unsigned char *ptrs = fore.data(); - cimg_for(img,ptrd,unsigned char) { const unsigned char val = *(ptrs++); if (val) *ptrd = val; } - const int y = (disp.mouse_y() - y0)/18, _y = 18*y + y0 + 9; - if (y>=0 && y<27) { - for (int yy = _y - 9; yy<=_y + 8; ++yy) - img.draw_rectangle(0,yy,0,1,img.width() - 1,yy,0,1,(unsigned char)(130 - 14*cimg::abs(yy - _y))); - img.draw_triangle(2,_y - 6,2,_y + 6,8,_y,yellow). - draw_triangle(img.width() - 2,_y - 6,img.width() - 2,_y + 6,img.width() - 8,_y,yellow); - } - gamma+=vgamma; - if (gamma>1) { - gamma = vgamma = 0; - rx = nrx; - ry = nry; - nrx=(float)(2*cimg::rand(-1,1)); nry=(float)(2*cimg::rand(-1,1)); - } - t+=0.006f; T+=0.005f; if (T>1) { T-=(float)(1 + cimg::rand(-1,1)); vgamma = 0.03f; } - if (disp.button()) { demo_number = 1 + (disp.mouse_y() - y0)/18; disp.set_button(); } - disp.resize(disp,false).display(img).wait(25); - } - start_item(demo_number); - } - } - - // Exit demo - //----------- - std::exit(0); - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/CMakeLists.txt b/applications/plugins/CImgPlugin/extlibs/CImg/examples/CMakeLists.txt deleted file mode 100644 index 162029541cd..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/CMakeLists.txt +++ /dev/null @@ -1,310 +0,0 @@ -# -# File : CMakeLists.txt -# ( Configuration file for 'cmake' utility ) -# -# Description : CMakeLists.txt configuration file for compiling CImg-based code. -# This file is a part of the CImg Library project. -# ( http://cimg.eu ) -# -# Copyright : Antonio Albiol -# ( http://personales.upv.es/~aalbiol/ ) -# -# License : CeCILL v2.0 -# ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) -# -# This software is governed by the CeCILL license under French law and -# abiding by the rules of distribution of free software. You can use, -# modify and/ or redistribute the software under the terms of the CeCILL -# license as circulated by CEA, CNRS and INRIA at the following URL -# "http://www.cecill.info". -# -# As a counterpart to the access to the source code and rights to copy, -# modify and redistribute granted by the license, users are provided only -# with a limited warranty and the software's author, the holder of the -# economic rights, and the successive licensors have only limited -# liability. -# -# In this respect, the user's attention is drawn to the risks associated -# with loading, using, modifying and/or developing or reproducing the -# software by the user in light of its specific status of free software, -# that may mean that it is complicated to manipulate, and that also -# therefore means that it is reserved for developers and experienced -# professionals having in-depth computer knowledge. Users are therefore -# encouraged to load and test the software's suitability as regards their -# requirements in conditions enabling the security of their systems and/or -# data to be ensured and, more generally, to use and operate it in the -# same conditions as regards security. -# -# The fact that you are presently reading this means that you have had -# knowledge of the CeCILL license and that you accept its terms. -# - -cmake_minimum_required(VERSION 2.6) - - -PROJECT(Examples-CIMG) - -# Prevent compilation in-source -if( ${CMAKE_BINARY_DIR} STREQUAL ${PROJECT_SOURCE_DIR} ) - Message( " " ) - Message( FATAL_ERROR "Source and build directories are the same. - Create an empty build directory, - change into it and re-invoke cmake") -endif() - - -# To use PKG_CHECK_MODULES to find some optional packages -find_package(PkgConfig) - -# Tell CMake where to leave executables -SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}) - -#Path of CImg.h file relative to this file path -set(CIMG_H_PATH ${PROJECT_SOURCE_DIR}/..) -include_directories( ${PROJECT_SOURCE_DIR} ) -include_directories( ${CIMG_H_PATH} ) - - - - -# ### CIMG related stuff -# Flags to enable fast image display, using the XSHM library. -SET(CIMG_XSHM_CCFLAGS -Dcimg_use_xshm) - -# Flags to enable screen mode switching, using the XRandr library. -SET(CIMG_XRANDR_CCFLAGS -Dcimg_use_xrandr) - -# Flags to enable native support for JPEG image files, using the JPEG library. -# ( http://www.ijg.org/ ) -SET(CIMG_JPEG_CCFLAGS -Dcimg_use_jpeg) - -# Flags to enable native support for TIFF image files, using the TIFF library. -# ( http://www.libtiff.org/ ) -SET(CIMG_TIFF_CCFLAGS -Dcimg_use_tiff) - -# Flags to enable native support for PNG image files, using the PNG library. -# ( http://www.libpng.org/ ) -SET(CIMG_PNG_CCFLAGS -Dcimg_use_png) - -#Flags to enable OPENCV support (Camera) -# ( http://www.opencv.org/ ) -SET(CIMG_OPENCV_CCFLAGS-Dcimg_use_opencv) - -# Flags to enable native support for EXR image files, using the OpenEXR library. -# ( http://www.openexr.com/ ) -SET(CIMG_OPENEXR_CCFLAGS -Dcimg_use_openexr) - -# Flags to enable native support for various video files, using the FFMPEG library. -# ( http://www.ffmpeg.org/ ) -SET(CIMG_FFMPEG_CCFLAGS -Dcimg_use_ffmpeg) - -# Flags to enable native support of most classical image file formats, using the Magick++ library. -# ( http://www.imagemagick.org/Magick++/ ) -SET(CIMG_MAGICK_CCFLAGS -Dcimg_use_magick) - -# Flags to enable faster Discrete Fourier Transform computation, using the FFTW3 library -# ( http://www.fftw.org/ ) -SET(CIMG_FFTW3_CCFLAGS -Dcimg_use_fftw3) - - - - -# ### Search Additional Libraries ########## -FIND_PACKAGE(OpenCV) -FIND_PACKAGE(JPEG) -FIND_PACKAGE(TIFF) -FIND_PACKAGE(PNG) -FIND_PACKAGE(ZLIB) -FIND_PACKAGE(LAPACK) -FIND_PACKAGE(BLAS) - -PKG_CHECK_MODULES(FFTW3 fftw3) -PKG_CHECK_MODULES(OPENEXR OpenEXR) -PKG_CHECK_MODULES(MAGICK Magick++) - -# PKG_CHECK_MODULES(LIBAVCODEC libavcodec) -# PKG_CHECK_MODULES(LIBAVFORMAT libavformat) -# PKG_CHECK_MODULES(LIBSWSCALE libswscale) -# PKG_CHECK_MODULES(LIBAVUTIL libavutil) - -if(NOT WIN32) - FIND_PACKAGE(X11) - FIND_PACKAGE(Threads REQUIRED) -endif() - -# #### End of additional libraries search ########## - - -### Configure Paths according to detected packages -if(TIFF_FOUND) - get_filename_component(TIFF_LIB_DIRS ${TIFF_LIBRARIES} PATH) - SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_TIFF_CCFLAGS}") - link_directories(${TIFF_LIB_DIRS}) - include_directories(${TIFF_INCLUDE_DIR}) - SET(SYSTEM_LIBS ${SYSTEM_LIBS} ${TIFF_LIBRARIES}) -endif() - - - -if(JPEG_FOUND) - get_filename_component(JPEG_LIB_DIRS ${JPEG_LIBRARIES} PATH) - SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_JPEG_CCFLAGS}") - link_directories(${JPEG_LIB_DIRS}) - include_directories(${JPEG_INCLUDE_DIR}) - SET(SYSTEM_LIBS ${SYSTEM_LIBS} ${JPEG_LIBRARIES}) -endif() - - - - -if (ZLIB_FOUND) - SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_ZLIB_CCFLAGS}") - link_directories(${ZLIB_LIB_DIRS}) - include_directories(${ZLIB_INCLUDE_DIR}) - SET(SYSTEM_LIBS ${SYSTEM_LIBS} ${ZLIB_LIBRARIES}) - - # PNG requires ZLIB - if(PNG_FOUND) - SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_PNG_CCFLAGS}") - link_directories(${PNG_LIB_DIRS}) - include_directories(${PNG_INCLUDE_DIR} ) - SET( SYSTEM_LIBS ${SYSTEM_LIBS} ${PNG_LIBRARIES} ) - endif() -endif() - - - - -if(FFTW3_FOUND) - SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_FFTW3_CCFLAGS}") - link_directories( ${FFTW3_LIBRARY_DIRS} ) - include_directories( ${FFTW3_INCLUDE_DIRS} ) - SET( SYSTEM_LIBS ${SYSTEM_LIBS} ${FFTW3_LIBRARIES} ) -endif() - - - - -if(OPENEXR_FOUND) - SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_OPENEXR_CCFLAGS}") - link_directories( ${OPENEXR_LIBRARY_DIRS} ) - include_directories( ${OPENEXR_INCLUDE_DIRS} ) - SET( SYSTEM_LIBS ${SYSTEM_LIBS} ${OPENEXR_LIBRARIES} ) -endif() - - -if(MAGICK_FOUND) - SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_MAGICK_CCFLAGS}") - link_directories( ${MAGICK_LIBRARY_DIRS} ) - include_directories( ${MAGICK_INCLUDE_DIRS} ) - SET( SYSTEM_LIBS ${SYSTEM_LIBS} ${MAGICK_LIBRARIES} ) -endif() - - - - -if( LIBAVCODEC_FOUND AND LIBAVFORMAT_FOUND AND LIBSWSCALE_FOUND AND LIBAVUTIL_FOUND ) - SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_FFMPEG_CCFLAGS}") - link_directories( ${LIBAVFORMAT_LIBRARY_DIRS} ) - link_directories( ${LIBAVCODEC_LIBRARY_DIRS} ) - link_directories( ${LIBSWSCALE_LIBRARY_DIRS} ) - link_directories( ${LIBAVUTIL_LIBRARY_DIRS} ) - include_directories( ${LIBAVFORMAT_INCLUDE_DIRS} ${LIBAVFORMAT_INCLUDE_DIRS}/libavformat) - include_directories( ${LIBAVCODEC_INCLUDE_DIRS} ${LIBAVCODEC_INCLUDE_DIRS}/libavcodec ) - include_directories( ${LIBSWSCALE_INCLUDE_DIRS} ${LIBSWSCALE_INCLUDE_DIRS}/libswscale) - include_directories( ${LIBAVUTIL_INCLUDE_DIRS} ${LIBAVUTIL_INCLUDE_DIRS}/libavutil ) - SET( SYSTEM_LIBS ${SYSTEM_LIBS} ${LIBAVFORMAT_LIBRARIES} ) - SET( SYSTEM_LIBS ${SYSTEM_LIBS} ${LIBAVCODEC_LIBRARIES} ) - SET( SYSTEM_LIBS ${SYSTEM_LIBS} ${LIBSWSCALE_LIBRARIES} ) - SET( SYSTEM_LIBS ${SYSTEM_LIBS} ${LIBAVUTIL_LIBRARIES} ) -endif() - - -if(NOT APPLE) - if(NOT WIN32) - if(X11_FOUND) - SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_XSHM_CCFLAGS} ${CIMG_XRANDR_CCFLAGS}") - SET(SYSTEM_LIBS ${SYSTEM_LIBS} Xext Xrandr) - endif() - endif(NOT WIN32) -endif(NOT APPLE) - -if(X11_FOUND) - link_directories(${X11_LIB_DIRS}) - include_directories(${X11_INCLUDE_DIR}) - SET( SYSTEM_LIBS ${SYSTEM_LIBS} ${X11_LIBRARIES} ) -endif() - -if (NOT WIN32) - SET( SYSTEM_LIBS ${SYSTEM_LIBS} ${CMAKE_THREAD_LIBS_INIT} ) -endif() - -if( WIN32) - SET( SYSTEM_LIBS ${SYSTEM_LIBS} gdi32 ) -endif() - -if (OpenCV_FOUND) - message("OpenCV Found") - SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_OPENCV_CCFLAGS}") - include_directories(${OpenCV_INCLUDE_DIRS}) - link_directories(${OpenCV_LIB_DIRS}) - SET( SYSTEM_LIBS ${SYSTEM_LIBS} ${OpenCV_LIBS} ) -endif() - - - -if(LAPACK_FOUND) - SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_LAPACK_CCFLAGS}") - link_directories( ${LAPACK_LIBRARY_DIRS} ) - include_directories( ${LAPACK_INCLUDE_DIRS} ) - SET( SYSTEM_LIBS ${SYSTEM_LIBS} ${LAPACK_LIBRARIES} ) -endif() - -if(BLAS_FOUND) - SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_BLAS_CCFLAGS}") - link_directories( ${BLAS_LIBRARY_DIRS} ) - include_directories( ${BLAS_INCLUDE_DIRS} ) - SET( SYSTEM_LIBS ${SYSTEM_LIBS} ${BLAS_LIBRARIES} ) -endif() - - -# Add CIMG Flags to Compilation Flags -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CIMG_CFLAGS}") - - -SET(CIMG_FILES CImg_demo - captcha - curve_editor2d - dtmri_view3d - edge_explorer2d - fade_images - gaussian_fit1d - generate_loop_macros - hough_transform2d - image_registration2d - image2ascii - image_surface3d - jawbreaker - mcf_levelsets2d - mcf_levelsets3d - odykill - pde_heatflow2d - pde_TschumperleDeriche2d - plotter1d - radon_transform2d - scene3d - spherical_function3d - tetris - tron - tutorial - wavelet_atrous - use_draw_gradient - use_nlmeans - use_skeleton - use_RGBclass - ) - -foreach(program ${CIMG_FILES}) - add_executable(${program} ${program}.cpp) - target_link_libraries(${program} ${SYSTEM_LIBS} ) -endforeach(program) diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/Makefile b/applications/plugins/CImgPlugin/extlibs/CImg/examples/Makefile deleted file mode 100644 index 8265bca29fa..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/Makefile +++ /dev/null @@ -1,667 +0,0 @@ -# -# File : Makefile -# ( Makefile for GNU 'make' utility ) -# -# Description : Makefile for compiling CImg-based code on Unix. -# This file is a part of the CImg Library project. -# ( http://cimg.eu ) -# -# Copyright : David Tschumperle -# ( http://tschumperle.users.greyc.fr/ ) -# -# License : CeCILL v2.0 -# ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) -# -# This software is governed by the CeCILL license under French law and -# abiding by the rules of distribution of free software. You can use, -# modify and/ or redistribute the software under the terms of the CeCILL -# license as circulated by CEA, CNRS and INRIA at the following URL -# "http://www.cecill.info". -# -# As a counterpart to the access to the source code and rights to copy, -# modify and redistribute granted by the license, users are provided only -# with a limited warranty and the software's author, the holder of the -# economic rights, and the successive licensors have only limited -# liability. -# -# In this respect, the user's attention is drawn to the risks associated -# with loading, using, modifying and/or developing or reproducing the -# software by the user in light of its specific status of free software, -# that may mean that it is complicated to manipulate, and that also -# therefore means that it is reserved for developers and experienced -# professionals having in-depth computer knowledge. Users are therefore -# encouraged to load and test the software's suitability as regards their -# requirements in conditions enabling the security of their systems and/or -# data to be ensured and, more generally, to use and operate it in the -# same conditions as regards security. -# -# The fact that you are presently reading this means that you have had -# knowledge of the CeCILL license and that you accept its terms. -# - -#------------------------------------------------------- -# Define the list of files to be compiled -# (name of the source files without the .cpp extension) -#------------------------------------------------------- - -# Files which do not necessarily require external libraries to run. -CIMG_FILES = CImg_demo \ - captcha \ - curve_editor2d \ - dtmri_view3d \ - edge_explorer2d \ - fade_images \ - gaussian_fit1d \ - generate_loop_macros \ - hough_transform2d \ - image_registration2d \ - image2ascii \ - image_surface3d \ - jawbreaker \ - mcf_levelsets2d \ - mcf_levelsets3d \ - odykill \ - pde_heatflow2d \ - pde_TschumperleDeriche2d \ - plotter1d \ - radon_transform2d \ - scene3d \ - spherical_function3d \ - tetris \ - tron \ - tutorial \ - wavelet_atrous \ - use_chlpca \ - use_draw_gradient \ - use_nlmeans \ - use_patchmatch \ - use_skeleton \ - use_RGBclass \ - -# Files which requires external libraries to run. -CIMG_EXTRA_FILES = use_tiff_stream use_jpeg_buffer - -#--------------------------------- -# Set correct variables and paths -#--------------------------------- -CIMG_VERSION = 1.7.3 -X11PATH = /usr/X11R6 -EXEPFX = -ifeq ($(MSYSTEM),MINGW32) -EXESFX = .exe -else -EXESFX = -endif -CXXVER = $(CXX) -ifeq ($(notdir $(CXX)),g++) -CXXVER = `$(CXX) -v 2>&1 | tail -n 1` -endif -ifeq ($(notdir $(CXX)),clang++) -CXXVER = `$(CXX) -v 2>&1 | head -n 1` -endif -ifeq ($(notdir $(CXX)),icpc) -CXXVER = "icpc \( `$(CXX) -v 2>&1`\)" -CFLAGS = -I.. -LIBS = -else -CFLAGS = -I.. -Wall -Wextra -LIBS = -lm -endif - -#-------------------------------------------------- -# Set compilation flags allowing to customize CImg -#-------------------------------------------------- - -# Flags to enable strict code standards -ifeq ($(notdir $(CXX)),icpc) -CIMG_ANSI_CFLAGS = -std=c++11 -else -CIMG_ANSI_CFLAGS = -std=c++11 -pedantic -endif - -# Flags to enable code debugging. -CIMG_DEBUG_CFLAGS = -Dcimg_verbosity=3 -Dcimg_strict_warnings -g -fsanitize=address - -# Flags to enable color output messages. -# (requires a VT100 compatible terminal) -CIMG_VT100_CFLAGS = -Dcimg_use_vt100 - -# Flags to enable code optimization by the compiler. -ifeq ($(notdir $(CXX)),g++) -CIMG_OPT_CFLAGS = -O2 -mtune=generic -else -ifeq ($(notdir $(CXX)),icpc) -CIMG_OPT_CFLAGS = -fast -else -CIMG_OPT_CFLAGS = -O2 -endif -endif - -# Flags to enable OpenMP support. -ifeq ($(notdir $(CXX)),icpc) -CIMG_OPENMP_CFLAGS = #-Dcimg_use_openmp -openmp -i-static # -> Seems to bug the compiler! -else -CIMG_OPENMP_DEFINE = -Dcimg_use_openmp -fopenmp -CIMG_OPENMP_INCDIR = -CIMG_OPENMP_CFLAGS = $(CIMG_OPENMP_DEFINE) $(CIMG_OPENMP_INCDIR) -endif - -# Flags to enable OpenCV support. -CIMG_OPENCV_DEFINE = -Dcimg_use_opencv -CIMG_OPENCV_INCDIR = `pkg-config opencv --cflags || echo -I/usr/include/opencv` -I/usr/include/opencv -CIMG_OPENCV_CFLAGS = $(CIMG_OPENCV_DEFINE) $(CIMG_OPENCV_INCDIR) -CIMG_OPENCV_LIBS = `pkg-config opencv --libs || echo -lopencv_core -lopencv_highgui` - -# Flags used to disable display capablities of CImg -CIMG_NODISPLAY_CFLAGS = -Dcimg_display=0 - -# Flags to enable the use of the X11 library. -# (X11 is used by CImg to handle display windows) -CIMG_X11_DEFINE = -Dcimg_display=1 -CIMG_X11_INCDIR = `pkg-config --cflags x11 || echo -I/usr/X11R6/include` -CIMG_X11_CFLAGS = $(CIMG_X11_DEFINE) $(CIMG_X11_INCDIR) -CIMG_X11_LIBS = `pkg-config --libs x11 || echo -L/usr/X11R6/lib -lX11` -lpthread - -# Flags to enable fast image display, using the XSHM library (when using X11). -# !!! Seems to randomly crash when used on MacOSX and 64bits systems, so use it only when necessary !!! -CIMG_XSHM_CFLAGS = # -Dcimg_use_xshm `pkg-config --cflags xcb-shm` -CIMG_XSHM_LIBS = # `pkg-config --libs xcb-shm || echo -L$(USR)/X11R6/lib -lXext` - -# Flags to enable GDI32 display (Windows native). -CIMG_GDI32_DEFINE = -mwindows -CIMG_GDI32_INCDIR = -CIMG_GDI32_CFLAGS = $(CIMG_GDI32_DEFINE) $(CIMG_GDI32_INCDIR) -CIMG_GDI32_LIBS = -lgdi32 - -# Flags to enable screen mode switching, using the XRandr library (when using X11). -# ( http://www.x.org/wiki/Projects/XRandR ) -# !!! Not supported by the X11 server on MacOSX, so do not use it on MacOSX !!! -CIMG_XRANDR_DEFINE = -Dcimg_use_xrandr -CIMG_XRANDR_INCDIR = -CIMG_XRANDR_CFLAGS = $(CIMG_XRANDR_DEFINE) $(CIMG_XRANDR_INCDIR) -CIMG_XRANDR_LIBS = -lXrandr - -# Flags to enable native support for PNG image files, using the PNG library. -# ( http://www.libpng.org/ ) -CIMG_PNG_DEFINE = -Dcimg_use_png -CIMG_PNG_INCDIR = -CIMG_PNG_CFLAGS = $(CIMG_PNG_DEFINE) $(CIMG_PNG_INCDIR) -CIMG_PNG_LIBS = -lpng -lz - -# Flags to enable native support for JPEG image files, using the JPEG library. -# ( http://www.ijg.org/ ) -CIMG_JPEG_DEFINE = -Dcimg_use_jpeg -CIMG_JPEG_INCDIR = -CIMG_JPEG_CFLAGS = $(CIMG_JPEG_DEFINE) $(CIMG_JPEG_INCDIR) -CIMG_JPEG_LIBS = -ljpeg - -# Flags to enable native support for TIFF image files, using the TIFF library. -# ( http://www.libtiff.org/ ) -CIMG_TIFF_DEFINE = -Dcimg_use_tiff -CIMG_TIFF_INCDIR = -CIMG_TIFF_CFLAGS = $(CIMG_TIFF_DEFINE) $(CIMG_TIFF_INCDIR) -CIMG_TIFF_LIBS = -ltiff - -# Flags to enable native support for MINC2 image files, using the MINC2 library. -# ( http://en.wikibooks.org/wiki/MINC/Reference/MINC2.0_Users_Guide ) -CIMG_MINC2_DEFINE = -Dcimg_use_minc2 -CIMG_MINC2_INCDIR = -I${HOME}/local/include -CIMG_MINC2_CFLAGS = $(CIMG_MINC2_DEFINE) $(CIMG_MINC2_INCDIR) -CIMG_MINC2_LIBS = -lminc_io -lvolume_io2 -lminc2 -lnetcdf -lhdf5 -lz -L${HOME}/local/lib - -# Flags to enable native support for EXR image files, using the OpenEXR library. -# ( http://www.openexr.com/ ) -CIMG_EXR_DEFINE = -Dcimg_use_openexr -CIMG_EXR_INCDIR = -I/usr/include/OpenEXR -CIMG_EXR_CFLAGS = $(CIMG_EXR_DEFINE) $(CIMG_EXR_INCDIR) -CIMG_EXR_LIBS = -lIlmImf -lHalf - -# Flags to enable native support for various video files, using the FFMPEG library. -# ( http://www.ffmpeg.org/ ) -CIMG_FFMPEG_DEFINE = -Dcimg_use_ffmpeg -D__STDC_CONSTANT_MACROS -CIMG_FFMPEG_INCDIR = -I/usr/include/libavcodec -I/usr/include/libavformat -I/usr/include/libswscale -I/usr/include/ffmpeg -CIMG_FFMPEG_CFLAGS = $(CIMG_FFMPEG_DEFINE) $(CIMG_FFMPEG_INCDIR) -CIMG_FFMPEG_LIBS = -lavcodec -lavformat -lswscale - -# Flags to enable native support for compressed .cimgz files, using the Zlib library. -# ( http://www.zlib.net/ ) -CIMG_ZLIB_DEFINE = -Dcimg_use_zlib -CIMG_ZLIB_INCDIR = `pkg-config --cflags zlib || echo -I$(USR)/$(INCLUDE)` -CIMG_ZLIB_CFLAGS = $(CIMG_ZLIB_DEFINE) $(CIMG_ZLIB_INCDIR) -CIMG_ZLIB_LIBS = `pkg-config --libs zlib || echo -lz` - -# Flags to enable native support for downloading files from the network. -# ( http://curl.haxx.se/libcurl/ ) -CIMG_CURL_DEFINE = -Dcimg_use_curl -CIMG_CURL_INCDIR = -CIMG_CURL_CFLAGS = $(CIMG_CURL_DEFINE) -CIMG_CURL_LIBS = -lcurl - -# Flags to enable native support of most classical image file formats, using the Magick++ library. -# ( http://www.imagemagick.org/Magick++/ ) -CIMG_MAGICK_DEFINE = -Dcimg_use_magick -CIMG_MAGICK_INCDIR = `pkg-config --cflags GraphicsMagick++ || echo -I$(USR)/$(INCLUDE)/GraphicsMagick` -CIMG_MAGICK_CFLAGS = $(CIMG_MAGICK_DEFINE) $(CIMG_MAGICK_INCDIR) -CIMG_MAGICK_LIBS = `pkg-config --libs GraphicsMagick++ || echo -lGraphicsMagick++` - -# Flags to enable faster Discrete Fourier Transform computation, using the FFTW3 library -# ( http://www.fftw.org/ ) -CIMG_FFTW3_DEFINE = -Dcimg_use_fftw3 -CIMG_FFTW3_INCDIR = -CIMG_FFTW3_CFLAGS = $(CIMG_FFTW3_DEFINE) $(CIMG_FFTW3_INCDIR) -ifeq ($(OSTYPE),msys) -CIMG_FFTW3_LIBS = -lfftw3-3 -else -CIMG_FFTW3_LIBS = -lfftw3 -lfftw3_threads -endif - -# Flags to enable the use of LAPACK routines for matrix computation -# ( http://www.netlib.org/lapack/ ) -CIMG_LAPACK_DEFINE = -Dcimg_use_lapack -CIMG_LAPACK_INCDIR = -CIMG_LAPACK_CFLAGS = $(CIMG_LAPACK_DEFINE) $(CIMG_LAPACK_INCDIR) -CIMG_LAPACK_LIBS = -lblas -llapack - -# Flags to enable the use of the Board library -# ( http://libboard.sourceforge.net/ ) -CIMG_BOARD_DEFINE = -Dcimg_use_board -CIMG_BOARD_INCDIR = -I/usr/include/board -CIMG_BOARD_CFLAGS = $(CIMG_BOARD_DEFINE) $(CIMG_BOARD_INCDIR) -CIMG_BOARD_LIBS = -lboard - -# Flags to compile on Sun Solaris -CIMG_SOLARIS_LIBS = -R$(X11PATH)/lib -lrt -lnsl -lsocket - -# Flags to compile GIMP plug-ins. -ifeq ($(MSYSTEM),MINGW32) -CIMG_GIMP_CFLAGS = -mwindows -endif - -#------------------------- -# Define Makefile entries -#------------------------- -.cpp: - @echo - @echo "** Compiling '$* ($(CIMG_VERSION))' with '$(CXXVER)'" - @echo - $(CXX) -o $(EXEPFX)$*$(EXESFX) $< $(CFLAGS) $(CONF_CFLAGS) $(LIBS) $(CONF_LIBS) -ifeq ($(STRIP_EXE),true) - strip $(EXEPFX)$*$(EXESFX) -endif -menu: - @echo - @echo "CImg Library $(CIMG_VERSION) : Examples" - @echo "-----------------------------" - @echo " > linux : Linux/BSD target, X11 display, optimizations disabled." - @echo " > dlinux : Linux/BSD target, X11 display, debug mode." - @echo " > olinux : Linux/BSD target, X11 display, optimizations enabled." - @echo " > mlinux : Linus/BSD target, no display, minimal features, optimizations enabled." - @echo " > Mlinux : Linux/BSD target, X11 display, maximal features, optimizations enabled." - @echo - @echo " > solaris : Sun Solaris target, X11 display, optimizations disabled." - @echo " > dsolaris : Sun Solaris target, X11 display, debug mode." - @echo " > osolaris : Sun Solaris target, X11 display, optimizations enabled." - @echo " > msolaris : Sun Solaris target, no display, minimal features, optimizations enabled." - @echo " > Msolaris : Sun Solaris target, X11 display, maximal features, optimizations enabled." - @echo - @echo " > macosx : MacOSX target, X11 display, optimizations disabled." - @echo " > dmacosx : MacOSX target, X11 display, debug mode." - @echo " > omacosx : MacOSX target, X11 display, optimizations enabled." - @echo " > mmacosx : MacOSX target, no display, minimal features, optimizations enabled." - @echo " > Mmacosx : MacOSX target, X11 display, maximal features, optimizations enabled." - @echo - @echo " > windows : Windows target, GDI32 display, optimizations disabled." - @echo " > dwindows : Windows target, GDI32 display, debug mode." - @echo " > owindows : Windows target, GDI32 display, optimizations enabled." - @echo " > mwindows : Windows target, no display, minimal features, optimizations enabled." - @echo " > Mwindows : Windows target, GDI32 display, maximal features, optimizations enabled." - @echo - @echo " > clean : Clean generated files." - @echo - @echo "Choose your option :" - @read CHOICE; echo; $(MAKE) $$CHOICE; echo; echo "> Next time, you can bypass the menu by typing directly 'make $$CHOICE'"; echo; - -all: $(CIMG_FILES) - -clean: - rm -rf *.exe *.o *~ \#* $(CIMG_FILES) $(CIMG_EXTRA_FILES) -ifneq ($(EXEPFX),) - rm -f $(EXEPFX)* -endif - -# Custom user-defined target -custom: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_ANSI_CFLAGS) \ -$(CIMG_VT100_CFLAGS) \ -$(CIMG_TIFF_CFLAGS) \ -$(CIMG_X11_CFLAGS) \ -$(CIMG_LAPACK_CFLAGS) \ -$(CIMG_XSHM_CFLAGS)" \ -"CONF_LIBS = \ -$(CIMG_X11_LIBS) \ -$(CIMG_TIFF_LIBS) \ -$(CIMG_LAPACK_LIBS) \ -$(CIMG_XSHM_LIBS)" \ -all $(CIMG_EXTRA_FILES) - -# Linux/BSD/Mac OSX targets, with X11 display. - -#A target for Travis-CI -travis: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_ANSI_CFLAGS) \ -$(CIMG_VT100_CFLAGS) \ -$(CIMG_X11_CFLAGS) \ -$(CIMG_FFTW3_CFLAGS) \ -$(CIMG_PNG_CFLAGS) \ -$(CIMG_JPEG_CFLAGS) \ -$(CIMG_ZLIB_CFLAGS) \ -$(CIMG_CURL_CFLAGS) \ -$(CIMG_XSHM_CFLAGS)" \ -"CONF_LIBS = \ -$(CIMG_X11_LIBS) \ -$(CIMG_FFTW3_LIBS) \ -$(CIMG_PNG_LIBS) \ -$(CIMG_JPEG_LIBS) \ -$(CIMG_ZLIB_LIBS) \ -$(CIMG_CURL_LIBS) \ -$(CIMG_XSHM_LIBS)" \ -all - -linux: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_ANSI_CFLAGS) \ -$(CIMG_VT100_CFLAGS) \ -$(CIMG_X11_CFLAGS) \ -$(CIMG_XSHM_CFLAGS)" \ -"CONF_LIBS = \ -$(CIMG_X11_LIBS) \ -$(CIMG_XSHM_LIBS)" \ -all - -dlinux: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_ANSI_CFLAGS) \ -$(CIMG_DEBUG_CFLAGS) \ -$(CIMG_VT100_CFLAGS) \ -$(CIMG_X11_CFLAGS) \ -$(CIMG_XSHM_CFLAGS)" \ -"CONF_LIBS = \ -$(CIMG_X11_LIBS) \ -$(CIMG_XSHM_LIBS)" \ -all - -olinux: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_ANSI_CFLAGS) \ -$(CIMG_OPT_CFLAGS) \ -$(CIMG_OPENMP_CFLAGS) \ -$(CIMG_VT100_CFLAGS) \ -$(CIMG_X11_CFLAGS) \ -$(CIMG_XSHM_CFLAGS)" \ -"CONF_LIBS = \ -$(CIMG_X11_LIBS) \ -$(CIMG_XSHM_LIBS)" \ -"STRIP_EXE=true" \ -all - -mlinux: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_ANSI_CFLAGS) \ -$(CIMG_NODISPLAY_CFLAGS) \ -$(CIMG_OPT_CFLAGS)" \ -"STRIP_EXE=true" \ -all - -Mlinux: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_OPT_CFLAGS) \ -$(CIMG_VT100_CFLAGS) \ -$(CIMG_X11_CFLAGS) \ -$(CIMG_XSHM_CFLAGS) \ -$(CIMG_XRANDR_CFLAGS) \ -$(CIMG_TIFF_CFLAGS) \ -$(CIMG_EXR_CFLAGS) \ -$(CIMG_PNG_CFLAGS) \ -$(CIMG_JPEG_CFLAGS) \ -$(CIMG_ZLIB_CFLAGS) \ -$(CIMG_CURL_CFLAGS) \ -$(CIMG_OPENCV_CFLAGS) \ -$(CIMG_MAGICK_CFLAGS) \ -$(CIMG_FFTW3_CFLAGS)" \ -"CONF_LIBS = \ -$(CIMG_X11_LIBS) \ -$(CIMG_XSHM_LIBS) \ -$(CIMG_XRANDR_LIBS) \ -$(CIMG_TIFF_LIBS) -ltiffxx \ -$(CIMG_EXR_LIBS) \ -$(CIMG_PNG_LIBS) \ -$(CIMG_JPEG_LIBS) \ -$(CIMG_ZLIB_LIBS) \ -$(CIMG_CURL_LIBS) \ -$(CIMG_OPENCV_LIBS) \ -$(CIMG_MAGICK_LIBS) \ -$(CIMG_FFTW3_LIBS)" \ -"STRIP_EXE=true" \ -all $(CIMG_EXTRA_FILES) - -# Sun Solaris targets, with X11 display. -solaris: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_ANSI_CFLAGS) \ -$(CIMG_VT100_CFLAGS) \ -$(CIMG_X11_CFLAGS) \ -$(CIMG_XSHM_CFLAGS)" \ -"CONF_LIBS = \ -$(CIMG_SOLARIS_LIBS) \ -$(CIMG_X11_LIBS) \ -$(CIMG_XSHM_LIBS)" \ -all - -dsolaris: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_ANSI_CFLAGS) \ -$(CIMG_DEBUG_CFLAGS) \ -$(CIMG_VT100_CFLAGS) \ -$(CIMG_X11_CFLAGS) \ -$(CIMG_XSHM_CFLAGS)" \ -"CONF_LIBS = \ -$(CIMG_SOLARIS_LIBS) \ -$(CIMG_X11_LIBS) \ -$(CIMG_XSHM_LIBS)" \ -all - -osolaris: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_ANSI_CFLAGS) \ -$(CIMG_OPT_CFLAGS) \ -$(CIMG_VT100_CFLAGS) \ -$(CIMG_X11_CFLAGS) \ -$(CIMG_XSHM_CFLAGS)" \ -"CONF_LIBS = \ -$(CIMG_SOLARIS_LIBS) \ -$(CIMG_X11_LIBS) \ -$(CIMG_XSHM_LIBS)" \ -"STRIP_EXE=true" \ -all - -msolaris: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_ANSI_CFLAGS) \ -$(CIMG_NODISPLAY_CFLAGS) \ -$(CIMG_OPT_CFLAGS)" \ -"STRIP_EXE=true" \ -all - -Msolaris: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_OPT_CFLAGS) \ -$(CIMG_VT100_CFLAGS) \ -$(CIMG_X11_CFLAGS) \ -$(CIMG_XSHM_CFLAGS) \ -$(CIMG_XRANDR_CFLAGS) \ -$(CIMG_TIFF_CFLAGS) \ -$(CIMG_MINC2_CFLAGS) \ -$(CIMG_EXR_CFLAGS) \ -$(CIMG_PNG_CFLAGS) \ -$(CIMG_JPEG_CFLAGS) \ -$(CIMG_ZLIB_CFLAGS) \ -$(CIMG_OPENCV_CFLAGS) \ -$(CIMG_MAGICK_CFLAGS) \ -$(CIMG_FFTW3_CFLAGS)" \ -"CONF_LIBS = \ -$(CIMG_SOLARIS_LIBS) \ -$(CIMG_X11_LIBS) \ -$(CIMG_XSHM_LIBS) \ -$(CIMG_XRANDR_LIBS) \ -$(CIMG_TIFF_LIBS) \ -$(CIMG_MINC2_LIBS) \ -$(CIMG_EXR_LIBS) \ -$(CIMG_PNG_LIBS) \ -$(CIMG_JPEG_LIBS) \ -$(CIMG_ZLIB_LIBS) \ -$(CIMG_OPENCV_LIBS) \ -$(CIMG_MAGICK_LIBS) \ -$(CIMG_FFTW3_LIBS)" \ -"STRIP_EXE=true" \ -all $(CIMG_EXTRA_FILES) - -# MacOsX targets, with X11 display. -macosx: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_ANSI_CFLAGS) \ -$(CIMG_VT100_CFLAGS) \ -$(CIMG_X11_CFLAGS)" \ -"CONF_LIBS = \ -$(CIMG_X11_LIBS)" \ -all - -dmacosx: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_ANSI_CFLAGS) \ -$(CIMG_DEBUG_CFLAGS) \ -$(CIMG_VT100_CFLAGS) \ -$(CIMG_X11_CFLAGS)" \ -"CONF_LIBS = \ -$(CIMG_X11_LIBS)" \ -all - -omacosx: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_ANSI_CFLAGS) \ -$(CIMG_OPT_CFLAGS) \ -$(CIMG_VT100_CFLAGS) \ -$(CIMG_X11_CFLAGS)" \ -"CONF_LIBS = \ -$(CIMG_X11_LIBS)" \ -all - -mmacosx: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_ANSI_CFLAGS) \ -$(CIMG_NODISPLAY_CFLAGS) \ -$(CIMG_OPT_CFLAGS)" \ -all - -Mmacosx: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_OPT_CFLAGS) \ -$(CIMG_VT100_CFLAGS) \ -$(CIMG_X11_CFLAGS) \ -$(CIMG_TIFF_CFLAGS) \ -$(CIMG_MINC2_CFLAGS) \ -$(CIMG_EXR_CFLAGS) \ -$(CIMG_PNG_CFLAGS) \ -$(CIMG_JPEG_CFLAGS) \ -$(CIMG_ZLIB_CFLAGS) \ -$(CIMG_OPENCV_CFLAGS) \ -$(CIMG_MAGICK_CFLAGS) \ -$(CIMG_FFTW3_CFLAGS)" \ -"CONF_LIBS = \ -$(CIMG_X11_LIBS) \ -$(CIMG_TIFF_LIBS) \ -$(CIMG_MINC2_LIBS) \ -$(CIMG_EXR_LIBS) \ -$(CIMG_PNG_LIBS) \ -$(CIMG_JPEG_LIBS) \ -$(CIMG_ZLIB_LIBS) \ -$(CIMG_OPENCV_LIBS) \ -$(CIMG_MAGICK_LIBS) \ -$(CIMG_FFTW3_LIBS)" \ -all $(CIMG_EXTRA_FILES) - -# Windows targets, with GDI32 display. -windows: - @$(MAKE) \ -"CONF_CFLAGS = " \ -"CONF_LIBS = \ -$(CIMG_GDI32_LIBS)" \ -all - -dwindows: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_DEBUG_CFLAGS)" \ -"CONF_LIBS = \ -$(CIMG_GDI32_LIBS)" \ -all - -owindows: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_OPT_CFLAGS)" \ -"CONF_LIBS = \ -$(CIMG_GDI32_LIBS)" \ -"STRIP_EXE=true" \ -all - -mwindows: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_NODISPLAY_CFLAGS) \ -$(CIMG_OPT_CFLAGS)" \ -"STRIP_EXE=true" \ -all - -Mwindows: - @$(MAKE) \ -"CONF_CFLAGS = \ -$(CIMG_OPT_CFLAGS) \ -$(CIMG_TIFF_CFLAGS) \ -$(CIMG_PNG_CFLAGS) \ -$(CIMG_JPEG_CFLAGS) \ -$(CIMG_ZLIB_CFLAGS) \ -$(CIMG_OPENCV_CFLAGS) \ -$(CIMG_FFTW3_CFLAGS)" \ -"CONF_LIBS = \ -$(CIMG_GDI32_LIBS) \ -$(CIMG_TIFF_LIBS) \ -$(CIMG_PNG_LIBS) \ -$(CIMG_JPEG_LIBS) \ -$(CIMG_ZLIB_LIBS) \ -$(CIMG_OPENCV_LIBS) \ -$(CIMG_FFTW3_LIBS)" \ -"STRIP_EXE=true" \ -all $(CIMG_EXTRA_FILES) - -#----------------- -# End of makefile -#----------------- diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/captcha.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/captcha.cpp deleted file mode 100644 index d8f962b28cd..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/captcha.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - # - # File : captcha.cpp - # ( C++ source file ) - # - # Description : Captcha images generator. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#ifndef cimg_debug -#define cimg_debug 1 -#endif -#include "CImg.h" -using namespace cimg_library; -#undef min -#undef max - -// Main procedure -//---------------- -int main(int argc,char **argv) { - - // Read command line parameters - //------------------------------ - cimg_usage("Simple captcha generator."); - const char *file_o = cimg_option("-o",(const char*)0,"Output image file"); - const bool add_border = cimg_option("-b",true,"Add border to captcha image"); - const bool visu = cimg_option("-visu",true,"Enable visualization if no output file"); - - // Generate captcha text (6 char max). - //------------------------------------ - const char *predef_words[] = { - "aarrgh", "abacas", "abacus", "abakas", "abamps", "abased", "abaser", "abases", "abasia", "abated", "abater", - "abates", "abatis", "abator", "baobab", "barbal", "barbed", "barbel", "barber", "barbes", "barbet", "barbie", - "barbut", "barcas", "barded", "bardes", "bardic", "barege", "cavies", "cavils", "caving", "cavity", "cavort", - "cawing", "cayman", "cayuse", "ceased", "ceases", "cebids", "ceboid", "cecity", "cedarn", "dicast", "dicers", - "dicier", "dicing", "dicker", "dickey", "dickie", "dicots", "dictum", "didact", "diddle", "diddly", "didies", - "didoes", "emails", "embalm", "embank", "embark", "embars", "embays", "embeds", "embers", "emblem", "embody", - "emboli", "emboly", "embosk", "emboss", "fluffy", "fluids", "fluish", "fluked", "flukes", "flukey", "flumed", - "flumes", "flumps", "flunks", "flunky", "fluors", "flurry", "fluted", "genome", "genoms", "genres", "genros", - "gentes", "gentil", "gentle", "gently", "gentry", "geodes", "geodic", "geoids", "gerahs", "gerbil", "hotter", - "hottie", "houdah", "hounds", "houris", "hourly", "housed", "housel", "houser", "houses", "hovels", "hovers", - "howdah", "howdie", "inland", "inlays", "inlets", "inlier", "inmate", "inmesh", "inmost", "innage", "innate", - "inners", "inning", "inpour", "inputs", "inroad", "joypop", "jubbah", "jubhah", "jubile", "judder", "judged", - "judger", "judges", "judoka", "jugate", "jugful", "jugged", "juggle", "jugula", "knifer", "knifes", "knight", - "knives", "knobby", "knocks", "knolls", "knolly", "knosps", "knotty", "knouts", "knower", "knowns", "knubby", - "legate", "legato", "legend", "legers", "legged", "leggin", "legion", "legist", "legits", "legman", "legmen", - "legong", "legume", "lehuas", "mammal", "mammas", "mammee", "mammer", "mammet", "mammey", "mammie", "mammon", - "mamzer", "manage", "manana", "manats", "manche", "manege", "nihils", "nilgai", "nilgau", "nilled", "nimble", - "nimbly", "nimbus", "nimmed", "nimrod", "ninety", "ninjas", "ninons", "ninths", "niobic", "offish", "offkey", - "offset", "oftest", "ogdoad", "oghams", "ogival", "ogives", "oglers", "ogling", "ogress", "ogrish", "ogrism", - "ohmage", "papaws", "papaya", "papers", "papery", "pappus", "papula", "papule", "papyri", "parade", "paramo", - "parang", "paraph", "parcel", "pardah", "quasar", "quatre", "quaver", "qubits", "qubyte", "queans", "queasy", - "queazy", "queens", "queers", "quelea", "quells", "quench", "querns", "raised", "raiser", "raises", "raisin", - "raitas", "rajahs", "rakees", "rakers", "raking", "rakish", "rallye", "ralphs", "ramada", "ramate", "savory", - "savour", "savoys", "sawers", "sawfly", "sawing", "sawlog", "sawney", "sawyer", "saxony", "sayeds", "sayers", - "sayest", "sayids", "tondos", "toneme", "toners", "tongas", "tonged", "tonger", "tongue", "tonics", "tonier", - "toning", "tonish", "tonlet", "tonner", "tonnes", "uredia", "uredos", "ureide", "uremia", "uremic", "ureter", - "uretic", "urgent", "urgers", "urging", "urials", "urinal", "urines", "uropod", "villus", "vimina", "vinals", - "vincas", "vineal", "vinery", "vinier", "vinify", "vining", "vinous", "vinyls", "violas", "violet", "violin", - "webfed", "weblog", "wechts", "wedded", "wedder", "wedeln", "wedels", "wedged", "wedges", "wedgie", "weeded", - "weeder", "weekly", "weened", "xystoi", "xystos", "xystus", "yabber", "yabbie", "yachts", "yacked", "yaffed", - "yagers", "yahoos", "yairds", "yakked", "yakker", "yakuza", "zigged", "zigzag", "zillah", "zinced", "zincic", - "zincky", "zinebs", "zinged", "zinger", "zinnia", "zipped", "zipper", "zirams", "zircon" }; - cimg::srand(); - const char *const captcha_text = predef_words[std::rand()%(sizeof(predef_words)/sizeof(char*))]; - - // Create captcha image - //---------------------- - - // Write colored and distorted text - CImg captcha(256,64,1,3,0), color(3); - char letter[2] = { 0 }; - for (unsigned int k = 0; k<6; ++k) { - CImg tmp; - *letter = captcha_text[k]; - if (*letter) { - cimg_forX(color,i) color[i] = (unsigned char)(128 + (std::rand()%127)); - tmp.draw_text((int)(2 + 8*cimg::rand()), - (int)(12*cimg::rand()), - letter,color.data(),0,1,std::rand()%2?38:57).resize(-100,-100,1,3); - const unsigned int dir = std::rand()%4, wph = tmp.width() + tmp.height(); - cimg_forXYC(tmp,x,y,v) { - const int val = dir==0?x + y:(dir==1?x + tmp.height() - y:(dir==2?y + tmp.width() - x: - tmp.width() - x + tmp.height() - y)); - tmp(x,y,v) = (unsigned char)cimg::max(0.0f,cimg::min(255.0f,1.5f*tmp(x,y,v)*val/wph)); - } - if (std::rand()%2) tmp = (tmp.get_dilate(3)-=tmp); - tmp.blur((float)cimg::rand()*0.8f).normalize(0,255); - const float sin_offset = (float)cimg::rand(-1,1)*3, sin_freq = (float)cimg::rand(-1,1)/7; - cimg_forYC(captcha,y,v) captcha.get_shared_row(y,0,v).shift((int)(4*std::cos(y*sin_freq + sin_offset))); - captcha.draw_image(6 + 40*k,tmp); - } - } - - // Add geometric and random noise - CImg copy = (+captcha).fill(0); - for (unsigned int l = 0; l<3; ++l) { - if (l) copy.blur(0.5f).normalize(0,148); - for (unsigned int k = 0; k<10; ++k) { - cimg_forX(color,i) color[i] = (unsigned char)(128 + cimg::rand()*127); - if (cimg::rand()<0.5f) copy.draw_circle((int)(cimg::rand()*captcha.width()), - (int)(cimg::rand()*captcha.height()), - (int)(cimg::rand()*30), - color.data(),0.6f,~0U); - else copy.draw_line((int)(cimg::rand()*captcha.width()), - (int)(cimg::rand()*captcha.height()), - (int)(cimg::rand()*captcha.width()), - (int)(cimg::rand()*captcha.height()), - color.data(),0.6f); - } - } - captcha|=copy; - captcha.noise(10,2); - - if (add_border) - captcha.draw_rectangle(0,0,captcha.width() - 1,captcha.height() - 1, - CImg::vector(255,255,255).data(),1.0f,~0U); - captcha = (+captcha).fill(255) - captcha; - - // Write output image and captcha text - //------------------------------------- - std::printf("%s\n",captcha_text); - if (file_o) captcha.save(file_o); - else if (visu) { - CImgDisplay disp(CImg(512,128,1,3,180).draw_image(128,32,captcha),captcha_text,0); - while (!disp.is_closed() && !disp.key()) { disp.wait(); if (disp.is_resized()) disp.resize(disp).wait(100); } - } - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/curve_editor2d.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/curve_editor2d.cpp deleted file mode 100644 index 5ec1c7d9275..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/curve_editor2d.cpp +++ /dev/null @@ -1,356 +0,0 @@ -/* - # - # File : curve_editor2d.cpp - # ( C++ source file ) - # - # Description : A simple user interface to construct 2D spline curves. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # Antonio Albiol Colomer - # ( http://personales.upv.es/~aalbiol/index-english.html ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#include "CImg.h" -using namespace cimg_library; -#undef min -#undef max - -// Compute distance from a point to a segment. -//--------------------------------------------- -float dist_segment(const float x, const float y, const float x1, const float y1, const float x2, const float y2) { - const float - dx = x2 - x1, - dy = y2 - y1, - long_segment = (float)std::sqrt(dx*dx + dy*dy); - if (long_segment==0) { const float ddx = x - x1, ddy = y - y1; return (float)std::sqrt(ddx*ddx + ddy*ddy); } - const float - unitx = dx/long_segment, - unity = dy/long_segment, - vx = x - x1, - vy = y - y1, - long_proy = vx*unitx + vy*unity, - proyx = x1 + long_proy*unitx, - proyy = y1 + long_proy*unity; - if (long_proy>long_segment) { const float ddx = x - x2, ddy = y - y2; return std::sqrt(ddx*ddx + ddy*ddy); } - else if (long_proy<0) { const float ddx = x - x1, ddy = y - y1; return std::sqrt(ddx*ddx + ddy*ddy); } - const float ddx = x - proyx, ddy = y - proyy; - return std::sqrt(ddx*ddx + ddy*ddy); -} - -// Main procedure -//--------------- -int main(int argc, char **argv) { - - // Read command line parameters - //----------------------------- - cimg_usage("2D Spline Curve Editor"); - const char *file_i = cimg_option("-i",(char*)0,"Input image"); - const float contrast = cimg_option("-contrast",0.6f,"Image contrast"); - const char *file_ip = cimg_option("-ip",(char*)0,"Input control points"); - const char *file_oc = cimg_option("-oc",(char*)0,"Output curve points"); - const char *file_op = cimg_option("-op",(char*)0,"Output control points"); - const char *file_od = cimg_option("-od",(char*)0,"Output distance function"); - bool interp = cimg_option("-poly",true,"Use polynomial interpolation"); - bool closed = cimg_option("-closed",true,"Closed curve"); - bool show_tangents = cimg_option("-tangents",false,"Show tangents"); - bool show_points = cimg_option("-points",true,"Show control points"); - bool show_outline = cimg_option("-outline",true,"Show polygon outline"); - bool show_indices = cimg_option("-indices",true,"Show points indices"); - bool show_coordinates = cimg_option("-coords",false,"Show points coordinates"); - const float precision = cimg_option("-prec",0.05f,"Precision of curve discretization"); - - // Init image data - //----------------- - const unsigned char yellow[] = { 255,255,0 }, white[] = { 255,255,255 }, green[] = { 0,255,0 }, - blue[] = { 120,200,255 }, purple[] = { 255,100,255 }, black[] = { 0,0,0 }; - CImg img0, img, help_img; - if (file_i) { - std::fprintf(stderr,"\n - Load input image '%s' : ",cimg::basename(file_i)); - img0 = CImg<>(file_i).normalize(0,255.0f*contrast); - std::fprintf(stderr,"Size = %dx%dx%dx%d \n",img0.width(),img0.height(),img0.depth(),img0.spectrum()); - img0.resize(-100,-100,1,3); - } - else { - std::fprintf(stderr,"\n - No input image specified, use default 512x512 image.\n"); - img0.assign(512,512,1,3,0).draw_grid(32,32,0,0,false,false,green,0.4f,0xCCCCCCCC,0xCCCCCCCC); - } - - help_img.assign(220,210,1,3,0). - draw_text(5,5, - "------------------------------------------\n" - "2D Curve Editor\n" - "------------------------------------------\n" - "Left button : Create or move control point\n" - "Right button : Delete control point\n" - "Spacebar : Switch interpolation\n" - "Key 'C' : Switch open/closed mode\n" - "Key 'T' : Show/hide tangents\n" - "Key 'P' : Show/hide control points\n" - "Key 'O' : Show/hide polygon outline\n" - "Key 'N' : Show/hide points indices\n" - "Key 'X' : Show/hide points coordinates\n" - "Key 'H' : Show/hide this help\n" - "Key 'S' : Save control points\n" - "Key 'R' : Reset curve\n", - green); - CImgDisplay disp(img0,"2D Curve Editor",0); - CImgList points, curve; - bool moving = false, help = !file_i; - - if (file_ip) { - std::fprintf(stderr," - Load input control points '%s' : ",cimg::basename(file_ip)); - points = CImg<>(file_ip).transpose()<'x'; - std::fprintf(stderr," %u points\n",points.size()); - } - - // Enter interactive loop - //------------------------ - while (!disp.is_closed() && !disp.is_keyESC() && !disp.is_keyQ()) { - - // Handle mouse manipulation - //--------------------------- - const unsigned int button = disp.button(); - const float - x = disp.mouse_x()*(float)img0.width()/disp.width(), - y = disp.mouse_y()*(float)img0.height()/disp.height(); - - if (points && button && x>=0 && y>=0) { - - // Find nearest point and nearest segment - float dmin_pt = cimg::type::max(), dmin_seg = dmin_pt; - unsigned int p_pt = 0, p_seg = 0; - cimglist_for(points,p) { - const unsigned int - pnext = closed?(p + 1)%points.size():(p + 1<(int)points.size()?p + 1:p); - const float - xp = points(p,0), - yp = points(p,1); - const float - d_pt = (xp - x)*(xp - x) + (yp - y)*(yp - y), - d_seg = dist_segment(x,y,xp,yp,points(pnext,0),points(pnext,1)); - if (d_pt::vector(x,y),p_seg + 1); - moving = true; - } - if (button&2 && dmin_pt<100) { - if (points.size()>3) points.remove(p_pt); - disp.set_button(); - } - } - if (!button) moving = false; - - if (disp.key()) { - switch (disp.key()) { - case cimg::keySPACE : interp = !interp; break; - case cimg::keyC : closed = !closed; break; - case cimg::keyT : show_tangents = !show_tangents; break; - case cimg::keyP : show_points = !show_points; break; - case cimg::keyO : show_outline = !show_outline; break; - case cimg::keyN : show_indices = !show_indices; break; - case cimg::keyX : show_coordinates = !show_coordinates; break; - case cimg::keyR : points.assign(); break; - case cimg::keyH : help = !help; break; - case cimg::keyS : { - const char *filename = file_op?file_op:"curve_points.dlm"; - std::fprintf(stderr," - Save control points in '%s'\n",filename); - (points>'x').transpose().save(filename); - } break; - } - disp.set_key(); - } - - // Init list of points if empty - //------------------------------ - if (!points) { - const float - x0 = img0.width()/4.0f, - y0 = img0.height()/4.0f, - x1 = img0.width() - x0, - y1 = img0.height() - y0; - points.insert(CImg<>::vector(x0,y0)). - insert(CImg<>::vector(x1,y0)). - insert(CImg<>::vector(x1,y1)). - insert(CImg<>::vector(x0,y1)); - } - - // Estimate curve tangents - //------------------------- - CImg<> tangents(points.size(),2); - cimglist_for(points,p) { - const unsigned int - p0 = closed?(p + points.size() - 1)%points.size():(p?p - 1:0), - p1 = closed?(p + 1)%points.size():(p + 1<(int)points.size()?p + 1:p); - const float - x = points(p,0), - y = points(p,1), - x0 = points(p0,0), - y0 = points(p0,1), - x1 = points(p1,0), - y1 = points(p1,1), - u0 = x - x0, - v0 = y - y0, - n0 = 1e-8f + (float)std::sqrt(u0*u0 + v0*v0), - u1 = x1 - x, - v1 = y1 - y, - n1 = 1e-8f + (float)std::sqrt(u1*u1 + v1*v1), - u = u0/n0 + u1/n1, - v = v0/n0 + v1/n1, - n = 1e-8f + (float)std::sqrt(u*u + v*v), - fact = 0.5f*(n0 + n1); - tangents(p,0) = fact*u/n; - tangents(p,1) = fact*v/n; - } - - // Estimate 3th-order polynomial interpolation - //--------------------------------------------- - curve.assign(); - const unsigned int pmax = points.size() - (closed?0:1); - for (unsigned int p0 = 0; p0::vector(xt,yt)); - } - } - - // Draw curve and display image - //------------------------------- - const float - factx = (float)disp.width()/img0.width(), - facty = (float)disp.height()/img0.height(); - img = img0.get_resize(disp.width(),disp.height()); - if (help) img.draw_image(help_img,0.6f); - if (interp && show_outline) { - CImg<> npoints = points>'x'; - npoints.get_shared_row(0)*=factx; - npoints.get_shared_row(1)*=facty; - img.draw_polygon(npoints,blue,0.4f); - if (closed) img.draw_polygon(npoints,yellow,0.8f,0x11111111); - else img.draw_line(npoints,yellow,0.8f,0x11111111); - } - CImg<> ncurve = curve>'x'; - ncurve.get_shared_row(0)*=factx; - ncurve.get_shared_row(1)*=facty; - if (closed) img.draw_polygon(ncurve,white,1.0f,~0U); - else img.draw_line(ncurve,white); - - if (show_points) cimglist_for(points,p) { - const float - x = points(p,0)*factx, - y = points(p,1)*facty; - if (show_tangents) { - const float - u = tangents(p,0), - v = tangents(p,1), - n = 1e-8f + (float)std::sqrt(u*u + v*v), - nu = u/n, - nv = v/n; - img.draw_arrow((int)(x - 15*nu),(int)(y - 15*nv),(int)(x + 15*nu),(int)(y + 15*nv),green); - } - if (show_indices) img.draw_text((int)x,(int)(y - 16),"%d",purple,black,1,13,p); - if (show_coordinates) - img.draw_text((int)(x - 24),(int)(y + 8),"(%d,%d)",yellow,black,0.5f,13,(int)points(p,0),(int)points(p,1)); - img.draw_circle((int)x,(int)y,3,blue,0.7f); - } - - img.display(disp); - disp.wait(); - - if (disp.is_resized()) disp.resize(false); - } - - // Save output result and exit - //----------------------------- - if (file_op) { - std::fprintf(stderr," - Save control points in '%s'\n",cimg::basename(file_op)); - (points>'x').transpose().save(file_op); - } - if (file_oc) { - std::fprintf(stderr," - Save curve points in '%s'\n",cimg::basename(file_oc)); - (curve>'x').transpose().save(file_oc); - } - if (file_od) { - std::fprintf(stderr," - Computing distance function, please wait...."); std::fflush(stderr); - CImg<> ncurve = (closed?(+curve).insert(curve[0]):curve)>'x'; - const float zero = 0.0f, one = 1.0f; - CImg<> distance = - CImg<>(img0.width(),img0.height(),1,1,-1.0f).draw_line(ncurve,&zero).draw_fill(0,0,&one). - distance(0); - std::fprintf(stderr,"\n - Save distance function in '%s'\n",cimg::basename(file_od)); - distance.save(file_od); - } - - std::fprintf(stderr," - Exit.\n"); - std::exit(0); - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/dtmri_view3d.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/dtmri_view3d.cpp deleted file mode 100644 index 09d95c7ca9b..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/dtmri_view3d.cpp +++ /dev/null @@ -1,562 +0,0 @@ -/* - # - # File : dtmri_view3d.cpp - # ( C++ source file ) - # - # Description : A viewer of Diffusion-Tensor MRI volumes (medical imaging). - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#include "CImg.h" -using namespace cimg_library; -#undef min -#undef max - -// Compute fractional anisotropy (FA) of a tensor -//------------------------------------------- -template float get_FA(const T& val1, const T& val2, const T& val3) { - const float - l1 = val1>0?val1:0, l2 = val2>0?val2:0, l3 = val3>0?val3:0, - lm = (l1 + l2 + l3)/3, - tr2 = 2*(l1*l1 + l2*l2 + l3*l3), - ll1 = l1 - lm, - ll2 = l2 - lm, - ll3 = l3 - lm; - if (tr2>0) return (float)std::sqrt(3*(ll1*ll1 + ll2*ll2 + ll3*ll3)/tr2); - return 0; -} - -// Insert an ellipsoid in a CImg 3D scene -//---------------------------------------- -template -void insert_ellipsoid(const CImg& tensor, const float X, const float Y, const float Z, const float tfact, - const float vx, const float vy, const float vz, - CImgList& points, CImgList& faces, CImgList& colors, - const unsigned int res1=20, const unsigned int res2=20) { - - // Compute eigen elements - float l1 = tensor[0], l2 = tensor[1], l3 = tensor[2], fa = get_FA(l1,l2,l3); - CImg<> vec = CImg<>::matrix(tensor[3],tensor[6],tensor[9], - tensor[4],tensor[7],tensor[10], - tensor[5],tensor[8],tensor[11]); - const int - r = (int)cimg::min(30 + 1.5f*cimg::abs(255*fa*tensor[3]),255.0f), - g = (int)cimg::min(30 + 1.5f*cimg::abs(255*fa*tensor[4]),255.0f), - b = (int)cimg::min(30 + 1.5f*cimg::abs(255*fa*tensor[5]),255.0f); - - // Define mesh points - const unsigned int N0 = points.size(); - for (unsigned int v = 1; v::vector(X,Y,Z) + vec*CImg::vector(x,y,z)).mul(CImg::vector(vx,vy,vz))); - } - const unsigned int N1 = points.size(); - points.insert((CImg::vector(X,Y,Z) - vec*CImg::vector(0,0,l3*tfact))); - points.insert((CImg::vector(X,Y,Z) + vec*CImg::vector(0,0,l3*tfact))); - points[points.size() - 2](0)*=vx; points[points.size() - 2](1)*=vy; points[points.size() - 2](2)*=vz; - points[points.size() - 1](0)*=vx; points[points.size() - 1](1)*=vy; points[points.size() - 1](2)*=vz; - - // Define mesh triangles - for (unsigned int vv = 0; vv::vector(N0 + res1*vv + nu,N0 + res1*nv + uu,N0 + res1*vv + uu)); - faces.insert(CImg::vector(N0 + res1*vv + nu,N0 + res1*nv + nu,N0 + res1*nv + uu)); - colors.insert(CImg::vector((tc)r,(tc)g,(tc)b)); - colors.insert(CImg::vector((tc)r,(tc)g,(tc)b)); - } - for (unsigned int uu = 0; uu::vector(N0 + nu,N0 + uu,N1)); - faces.insert(CImg::vector(N0 + res1*(res2 - 2) + nu, N1 + 1,N0 + res1*(res2 - 2) + uu)); - colors.insert(CImg::vector((tc)r,(tc)g,(tc)b)); - colors.insert(CImg::vector((tc)r,(tc)g,(tc)b)); - } -} - -// Insert a fiber in a CImg 3D scene -//----------------------------------- -template -void insert_fiber(const CImg& fiber, const CImg& eigen, const CImg& palette, - const int xm, const int ym, const int zm, - const float vx, const float vy, const float vz, - CImgList& points, CImgList& primitives, CImgList& colors) { - const int N0 = points.size(); - float x0 = fiber(0,0), y0 = fiber(0,1), z0 = fiber(0,2), fa0 = eigen.linear_atXYZ(x0,y0,z0,12); - points.insert(CImg<>::vector(vx*(x0 -xm),vy*(y0 - ym),vz*(z0 - zm))); - for (int l = 1; l::vector(vx*(x1 - xm),vy*(y1 - ym),vz*(z1 - zm))); - primitives.insert(CImg::vector(N0 + l - 1,N0 + l)); - const unsigned char - icol = (unsigned char)(fa0*255), - r = palette(icol,0), - g = palette(icol,1), - b = palette(icol,2); - colors.insert(CImg::vector(r,g,b)); - x0 = x1; y0 = y1; z0 = z1; fa0 = fa1; - } -} - -// Compute fiber tracking using 4th-order Runge Kutta integration -//----------------------------------------------------------------- -template -CImg<> get_fibertrack(CImg& eigen, - const int X0, const int Y0, const int Z0, const float lmax=100, - const float dl=0.1f, const float FAmin=0.7f, const float cmin=0.5f) { -#define align_eigen(i,j,k) \ - { T &u = eigen(i,j,k,3), &v = eigen(i,j,k,4), &w = eigen(i,j,k,5); \ - if (u*cu + v*cv + w*cw<0) { u=-u; v=-v; w=-w; }} - - CImgList<> resf; - - // Forward tracking - float normU = 0, normpU = 0, l = 0, X = (float)X0, Y = (float)Y0, Z = (float)Z0; - T - pu = eigen(X0,Y0,Z0,3), - pv = eigen(X0,Y0,Z0,4), - pw = eigen(X0,Y0,Z0,5); - normpU = (float)std::sqrt(pu*pu + pv*pv + pw*pw); - bool stopflag = false; - - while (!stopflag) { - if (X<0 || X>eigen.width() - 1 || Y<0 || Y>eigen.height() - 1 || Z<0 || Z>eigen.depth() - 1 || - eigen((int)X,(int)Y,(int)Z,12)lmax) stopflag = true; - else { - resf.insert(CImg<>::vector(X,Y,Z)); - - const int - cx = (int)X, px = (cx - 1<0)?0:cx - 1, nx = (cx + 1>=eigen.width())?eigen.width() - 1:cx + 1, - cy = (int)Y, py = (cy - 1<0)?0:cy - 1, ny = (cy + 1>=eigen.height())?eigen.height() - 1:cy + 1, - cz = (int)Z, pz = (cz - 1<0)?0:cz - 1, nz = (cz + 1>=eigen.depth())?eigen.depth() - 1:cz + 1; - const T cu = eigen(cx,cy,cz,3), cv = eigen(cx,cy,cz,4), cw = eigen(cx,cy,cz,5); - - align_eigen(px,py,pz); align_eigen(cx,py,pz); align_eigen(nx,py,pz); - align_eigen(px,cy,pz); align_eigen(cx,cy,pz); align_eigen(nx,cy,pz); - align_eigen(px,ny,pz); align_eigen(cx,ny,pz); align_eigen(nx,ny,pz); - align_eigen(px,py,cz); align_eigen(cx,py,cz); align_eigen(nx,py,cz); - align_eigen(px,cy,cz); align_eigen(nx,cy,cz); - align_eigen(px,ny,cz); align_eigen(cx,ny,cz); align_eigen(nx,ny,cz); - align_eigen(px,py,nz); align_eigen(cx,py,nz); align_eigen(nx,py,nz); - align_eigen(px,cy,nz); align_eigen(cx,cy,nz); align_eigen(nx,cy,nz); - align_eigen(px,ny,nz); align_eigen(cx,ny,nz); align_eigen(nx,ny,nz); - - const T - u0 = 0.5f*dl*eigen.linear_atXYZ(X,Y,Z,3), - v0 = 0.5f*dl*eigen.linear_atXYZ(X,Y,Z,4), - w0 = 0.5f*dl*eigen.linear_atXYZ(X,Y,Z,5), - u1 = 0.5f*dl*eigen.linear_atXYZ(X + u0,Y + v0,Z + w0,3), - v1 = 0.5f*dl*eigen.linear_atXYZ(X + u0,Y + v0,Z + w0,4), - w1 = 0.5f*dl*eigen.linear_atXYZ(X + u0,Y + v0,Z + w0,5), - u2 = 0.5f*dl*eigen.linear_atXYZ(X + u1,Y + v1,Z + w1,3), - v2 = 0.5f*dl*eigen.linear_atXYZ(X + u1,Y + v1,Z + w1,4), - w2 = 0.5f*dl*eigen.linear_atXYZ(X + u1,Y + v1,Z + w1,5), - u3 = 0.5f*dl*eigen.linear_atXYZ(X + u2,Y + v2,Z + w2,3), - v3 = 0.5f*dl*eigen.linear_atXYZ(X + u2,Y + v2,Z + w2,4), - w3 = 0.5f*dl*eigen.linear_atXYZ(X + u2,Y + v2,Z + w2,5); - T - u = u0/3 + 2*u1/3 + 2*u2/3 + u3/3, - v = v0/3 + 2*v1/3 + 2*v2/3 + v3/3, - w = w0/3 + 2*w1/3 + 2*w2/3 + w3/3; - if (u*pu + v*pv + w*pw<0) { u = -u; v = -v; w = -w; } - normU = (float)std::sqrt(u*u + v*v + w*w); - const float scal = (u*pu + v*pv + w*pw)/(normU*normpU); - if (scaleigen.width() - 1 || Y<0 || Y>eigen.height() - 1 || Z<0 || Z>eigen.depth() - 1 || - eigen((int)X,(int)Y,(int)Z,12)lmax) stopflag = true; - else { - - const int - cx = (int)X, px = (cx - 1<0)?0:cx - 1, nx = (cx + 1>=eigen.width())?eigen.width() - 1:cx + 1, - cy = (int)Y, py = (cy - 1<0)?0:cy - 1, ny = (cy + 1>=eigen.height())?eigen.height() - 1:cy + 1, - cz = (int)Z, pz = (cz - 1<0)?0:cz - 1, nz = (cz + 1>=eigen.depth())?eigen.depth() - 1:cz + 1; - const T cu = eigen(cx,cy,cz,3), cv = eigen(cx,cy,cz,4), cw = eigen(cx,cy,cz,5); - - align_eigen(px,py,pz); align_eigen(cx,py,pz); align_eigen(nx,py,pz); - align_eigen(px,cy,pz); align_eigen(cx,cy,pz); align_eigen(nx,cy,pz); - align_eigen(px,ny,pz); align_eigen(cx,ny,pz); align_eigen(nx,ny,pz); - align_eigen(px,py,cz); align_eigen(cx,py,cz); align_eigen(nx,py,cz); - align_eigen(px,cy,cz); align_eigen(nx,cy,cz); - align_eigen(px,ny,cz); align_eigen(cx,ny,cz); align_eigen(nx,ny,cz); - align_eigen(px,py,nz); align_eigen(cx,py,nz); align_eigen(nx,py,nz); - align_eigen(px,cy,nz); align_eigen(cx,cy,nz); align_eigen(nx,cy,nz); - align_eigen(px,ny,nz); align_eigen(cx,ny,nz); align_eigen(nx,ny,nz); - - const T - u0 = 0.5f*dl*eigen.linear_atXYZ(X,Y,Z,3), - v0 = 0.5f*dl*eigen.linear_atXYZ(X,Y,Z,4), - w0 = 0.5f*dl*eigen.linear_atXYZ(X,Y,Z,5), - u1 = 0.5f*dl*eigen.linear_atXYZ(X + u0,Y + v0,Z + w0,3), - v1 = 0.5f*dl*eigen.linear_atXYZ(X + u0,Y + v0,Z + w0,4), - w1 = 0.5f*dl*eigen.linear_atXYZ(X + u0,Y + v0,Z + w0,5), - u2 = 0.5f*dl*eigen.linear_atXYZ(X + u1,Y + v1,Z + w1,3), - v2 = 0.5f*dl*eigen.linear_atXYZ(X + u1,Y + v1,Z + w1,4), - w2 = 0.5f*dl*eigen.linear_atXYZ(X + u1,Y + v1,Z + w1,5), - u3 = 0.5f*dl*eigen.linear_atXYZ(X + u2,Y + v2,Z + w2,3), - v3 = 0.5f*dl*eigen.linear_atXYZ(X + u2,Y + v2,Z + w2,4), - w3 = 0.5f*dl*eigen.linear_atXYZ(X + u2,Y + v2,Z + w2,5); - T - u = u0/3 + 2*u1/3 + 2*u2/3 + u3/3, - v = v0/3 + 2*v1/3 + 2*v2/3 + v3/3, - w = w0/3 + 2*w1/3 + 2*w2/3 + w3/3; - if (u*pu + v*pv + w*pw<0) { u = -u; v = -v; w = -w; } - normU = (float)std::sqrt(u*u + v*v + w*w); - const float scal = (u*pu + v*pv + w*pw)/(normU*normpU); - if (scal::vector(X,Y,Z),0); - } - } - - return resf>'x'; -} - -// Main procedure -//---------------- -int main(int argc,char **argv) { - - // Read and init data - //-------------------- - cimg_usage("A viewer of Diffusion-Tensor MRI volumes."); - const char *file_i = cimg_option("-i",(char*)0,"Input : Filename of tensor field (volume wxhxdx6)"); - const char* vsize = cimg_option("-vsize","1x1x1","Input : Voxel aspect"); - const bool normalize = cimg_option("-normalize",true,"Input : Enable tensor normalization"); - const char *file_f = cimg_option("-f",(char*)0,"Input : Input fibers\n"); - const float dl = cimg_option("-dl",0.5f,"Fiber computation : Integration step"); - const float famin = cimg_option("-famin",0.3f,"Fiber computation : Fractional Anisotropy threshold"); - const float cmin = cimg_option("-cmin",0.2f,"Fiber computation : Curvature threshold"); - const float lmin = cimg_option("-lmin",10.0f,"Fiber computation : Minimum length\n"); - const float lmax = cimg_option("-lmax",1000.0f,"Fiber computation : Maximum length\n"); - const float tfact = cimg_option("-tfact",1.2f,"Display : Tensor size factor"); - const char *bgcolor = cimg_option("-bg","0,0,0","Display : Background color"); - unsigned int bgr = 0, bgg = 0, bgb = 0; - std::sscanf(bgcolor,"%u%*c%u%*c%u",&bgr,&bgg,&bgb); - - CImg<> tensors; - if (file_i) { - std::fprintf(stderr,"\n- Loading tensors '%s'",cimg::basename(file_i)); - tensors.load(file_i); - } else { - // Create a synthetic tensor field here - std::fprintf(stderr,"\n- No input files : Creating a synthetic tensor field"); - tensors.assign(32,32,32,6); - cimg_forXYZ(tensors,x,y,z) { - const float - u = x - tensors.width()/2.0f, - v = y - tensors.height()/2.0f, - w = z - tensors.depth()/2.0f, - norm = (float)std::sqrt(1e-5f + u*u + v*v + w*w), - nu = u/norm, nv = v/norm, nw = w/norm; - const CImg<> - dir1 = CImg<>::vector(nu,nv,nw), - dir2 = CImg<>::vector(-nv,nu,nw), - dir3 = CImg<>::vector(nw*(nv - nu),-nw*(nu + nv),nu*nu + nv*nv); - tensors.set_tensor_at(2.0*dir1*dir1.get_transpose() + - 1.0*dir2*dir2.get_transpose() + - 0.7*dir3*dir3.get_transpose(), - x,y,z); - } - } - float voxw = 1, voxh = 1, voxd = 1; - std::sscanf(vsize,"%f%*c%f%*c%f",&voxw,&voxh,&voxd); - - std::fprintf(stderr," : %ux%ux%u image, voxsize=%gx%gx%g.", - tensors.width(),tensors.height(),tensors.depth(), - voxw,voxh,voxd); - - CImgList<> fibers; - if (file_f) { - std::fprintf(stderr,"\n- Loading fibers '%s'.",cimg::basename(file_f)); - fibers.load(file_f); - } - - const CImg fiber_palette = - CImg<>(2,1,1,3).fill(200,255,0,255,0,200).RGBtoHSV().resize(256,1,1,3,3).HSVtoRGB(); - - // Compute eigen elements - //------------------------ - std::fprintf(stderr,"\n- Compute eigen elements."); - CImg coloredFA(tensors.width(),tensors.height(),tensors.depth(),3); - CImg<> eigen(tensors.width(),tensors.height(),tensors.depth(),13); - CImg<> val,vec; - float eigmax = 0; - cimg_forXYZ(tensors,x,y,z) { - tensors.get_tensor_at(x,y,z).symmetric_eigen(val,vec); - eigen(x,y,z,0) = val[0]; eigen(x,y,z,1) = val[1]; eigen(x,y,z,2) = val[2]; - if (val[0]<0) val[0] = 0; - if (val[1]<0) val[1] = 0; - if (val[2]<0) val[2] = 0; - if (val[0]>eigmax) eigmax = val[0]; - eigen(x,y,z,3) = vec(0,0); eigen(x,y,z,4) = vec(0,1); eigen(x,y,z,5) = vec(0,2); - eigen(x,y,z,6) = vec(1,0); eigen(x,y,z,7) = vec(1,1); eigen(x,y,z,8) = vec(1,2); - eigen(x,y,z,9) = vec(2,0); eigen(x,y,z,10) = vec(2,1); eigen(x,y,z,11) = vec(2,2); - const float fa = get_FA(val[0],val[1],val[2]); - eigen(x,y,z,12) = fa; - const int - r = (int)cimg::min(255.0f,1.5f*cimg::abs(255*fa*vec(0,0))), - g = (int)cimg::min(255.0f,1.5f*cimg::abs(255*fa*vec(0,1))), - b = (int)cimg::min(255.0f,1.5f*cimg::abs(255*fa*vec(0,2))); - coloredFA(x,y,z,0) = (unsigned char)r; - coloredFA(x,y,z,1) = (unsigned char)g; - coloredFA(x,y,z,2) = (unsigned char)b; - } - tensors.assign(); - std::fprintf(stderr,"\n- Maximum diffusivity = %g, Maximum FA = %g",eigmax,eigen.get_shared_channel(12).max()); - if (normalize) { - std::fprintf(stderr,"\n- Normalize tensors."); - eigen.get_shared_channels(0,2)/=eigmax; - } - - // Init display and begin user interaction - //----------------------------------------- - std::fprintf(stderr,"\n- Open user window."); - CImgDisplay disp(256,256,"DTMRI Viewer",0); - CImgDisplay disp3d(800,600,"3D Local View",0,false,true); - unsigned int XYZ[3]; - XYZ[0] = eigen.width()/2; XYZ[1] = eigen.height()/2; XYZ[2] = eigen.depth()/2; - - while (!disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC()) { - const CImg s = coloredFA.get_select(disp,2,XYZ); - if (!disp.is_closed()) switch (disp.key()) { - - // Open 3D visualization window - //----------------------------- - case cimg::keyA : - case 0 : { - const unsigned char white[] = { 255 }; - disp3d.display(CImg(disp3d.width(),disp3d.height(),1,1,0). - draw_text(10,10,"Please wait...",white)).show(); - int xm,ym,zm,xM,yM,zM; - if (!disp.key()) { xm = s[0]; ym = s[1]; zm = s[2]; xM = s[3]; yM = s[4]; zM = s[5]; } - else { xm = ym = zm = 0; xM = eigen.width() - 1; yM = eigen.height() - 1; zM = eigen.height() - 1; } - const CImg<> img = eigen.get_crop(xm,ym,zm,xM,yM,zM); - CImgList<> points; - CImgList primitives; - CImgList colors; - - // Add ellipsoids to the 3D scene - int X = img.width()/2, Y = img.height()/2, Z = img.depth()/2; - cimg_forXY(img,x,y) - insert_ellipsoid(img.get_vector_at(x,y,Z),(float)x,(float)y,(float)Z, - tfact,voxw,voxh,voxd,points,primitives,colors,10,6); - cimg_forXZ(img,x,z) - insert_ellipsoid(img.get_vector_at(x,Y,z),(float)x,(float)Y,(float)z, - tfact,voxw,voxh,voxd,points,primitives,colors,10,6); - cimg_forYZ(img,y,z) - insert_ellipsoid(img.get_vector_at(X,y,z),(float)X,(float)y,(float)z, - tfact,voxw,voxh,voxd,points,primitives,colors,10,6); - - // Add computed fibers to the 3D scene - const CImg<> veigen = eigen.get_crop(xm,ym,zm,xM,yM,zM); - cimglist_for(fibers,l) { - const CImg<>& fiber = fibers[l]; - if (fiber.width()) insert_fiber(fiber,eigen,fiber_palette, - xm,ym,zm,voxw,voxh,voxd, - points,primitives,colors); - } - - // Display 3D object - CImg visu = CImg(3,disp3d.width(),disp3d.height(),1,0). - fill((unsigned char)bgr,(unsigned char)bgg,(unsigned char)bgb). - permute_axes("yzcx"); - bool stopflag = false; - while (!disp3d.is_closed() && !stopflag) { - const CImg<> pts = points>'x'; - visu.display_object3d(disp3d,pts,primitives,colors,true,4,-1,false,800,0.05f,1.0f); - disp3d.close(); - switch (disp3d.key()) { - case cimg::keyM : { // Create movie - std::fprintf(stderr,"\n- Movie mode.\n"); - const unsigned int N = 256; - CImg<> cpts(pts); - const CImg<> x = pts.get_shared_row(0), y = pts.get_shared_row(1), z = pts.get_shared_row(2); - float - xm, xM = x.max_min(xm), - ym, yM = y.max_min(ym), - zm, zM = z.max_min(zm), - ratio = 2.0f*cimg::min(visu.width(),visu.height())/(3.0f*cimg::max(xM - xm,yM - ym,zM - zm)), - dx = 0.5f*(xM + xm), dy = 0.5f*(yM + ym), dz = 0.5f*(zM +zm); - cimg_forX(pts,l) { - cpts(l,0) = (pts(l,0) - dx)*ratio; - cpts(l,1) = (pts(l,1) - dy)*ratio; - cpts(l,2) = (pts(l,2) - dz)*ratio; - } - - for (unsigned int i=0; i rpts = CImg<>::rotation_matrix(0,1,0,alpha)*CImg<>::rotation_matrix(1,0,0,1.30f)*cpts; - visu.fill(0).draw_object3d(visu.width()/2.0f,visu.height()/2.0f,-500.0f,rpts,primitives,colors, - 4,false,800.0f,visu.width()/2.0f,visu.height()/2.0f,-800.0f,0.05f,1.0f). - display(disp3d); - visu.save("frame.png",i); - } - visu.fill(0); - } break; - default: stopflag = true; - } - } - if (disp3d.is_fullscreen()) disp3d.toggle_fullscreen().resize(800,600).close(); - } break; - - // Compute region statistics - //--------------------------- - case cimg::keyR : { - std::fprintf(stderr,"\n- Statistics computation. Select region."); std::fflush(stderr); - const CImg s = coloredFA.get_select(disp,2,XYZ); - int xm, ym, zm, xM, yM, zM; - if (!disp.key()) { xm = s[0]; ym = s[1]; zm = s[2]; xM = s[3]; yM = s[4]; zM = s[5]; } - else { xm = ym = zm = 0; xM = eigen.width() - 1; yM = eigen.height() - 1; zM = eigen.height() - 1; } - const CImg<> img = eigen.get_crop(xm,ym,zm,xM,yM,zM); - std::fprintf(stderr,"\n- Mean diffusivity = %g, Mean FA = %g\n", - eigen.get_shared_channel(0).mean(), - eigen.get_shared_channel(12).mean()); - } break; - - // Track fiber bundle (single region) - //---------------------------------- - case cimg::keyF : { - std::fprintf(stderr,"\n- Tracking mode (single region). Select starting region.\n"); std::fflush(stderr); - const CImg s = coloredFA.get_select(disp,2,XYZ); - const unsigned int N = fibers.size(); - for (int z=s[2]; z<=s[5]; z++) - for (int y=s[1]; y<=s[4]; y++) - for (int x=s[0]; x<=s[3]; x++) { - const CImg<> fiber = get_fibertrack(eigen,x,y,z,lmax,dl,famin,cmin); - if (fiber.width()>lmin) { - std::fprintf(stderr,"\rFiber %u : Starting from (%d,%d,%d)\t\t",fibers.size(),x,y,z); - fibers.insert(fiber); - } - } - std::fprintf(stderr,"\n- %u fiber(s) added (total %u).",fibers.size() - N,fibers.size()); - } break; - - // Track fiber bundle (double regions) - //------------------------------------ - case cimg::keyG : { - std::fprintf(stderr,"\n- Tracking mode (double region). Select starting region."); std::fflush(stderr); - const CImg s = coloredFA.get_select(disp,2,XYZ); - std::fprintf(stderr," Select ending region."); std::fflush(stderr); - const CImg ns = coloredFA.get_select(disp,2,XYZ); - const unsigned int N = fibers.size(); - - // Track from start to end - for (int z = s[2]; z<=s[5]; ++z) - for (int y = s[1]; y<=s[4]; ++y) - for (int x = s[0]; x<=s[3]; ++x) { - const CImg<> fiber = get_fibertrack(eigen,x,y,z,lmax,dl,famin,cmin); - if (fiber.width()>lmin) { - bool valid_fiber = false; - cimg_forX(fiber,k) { - const int fx = (int)fiber(k,0), fy = (int)fiber(k,1), fz = (int)fiber(k,2); - if (fx>=ns[0] && fx<=ns[3] && - fy>=ns[1] && fy<=ns[4] && - fz>=ns[2] && fz<=ns[5]) valid_fiber = true; - } - if (valid_fiber) fibers.insert(fiber); - } - } - - // Track from end to start - for (int z = ns[2]; z<=ns[5]; ++z) - for (int y = ns[1]; y<=ns[4]; ++y) - for (int x = ns[0]; x<=ns[3]; ++x) { - const CImg<> fiber = get_fibertrack(eigen,x,y,z,lmax,dl,famin,cmin); - if (fiber.width()>lmin) { - bool valid_fiber = false; - cimg_forX(fiber,k) { - const int fx = (int)fiber(k,0), fy = (int)fiber(k,1), fz = (int)fiber(k,2); - if (fx>=s[0] && fx<=s[3] && - fy>=s[1] && fy<=s[4] && - fz>=s[2] && fz<=s[5]) valid_fiber = true; - } - if (valid_fiber) { - std::fprintf(stderr,"\rFiber %u : Starting from (%d,%d,%d)\t\t",fibers.size(),x,y,z); - fibers.insert(fiber); - } - } - } - - std::fprintf(stderr," %u fiber(s) added (total %u).",fibers.size() - N,fibers.size()); - } break; - - // Clear fiber bundle - //------------------- - case cimg::keyC : { - std::fprintf(stderr,"\n- Fibers removed."); - fibers.assign(); - } break; - - // Save fibers - //------------- - case cimg::keyS : { - fibers.save("fibers.cimg"); - std::fprintf(stderr,"\n- Fibers saved."); - } break; - - } - } - - std::fprintf(stderr,"\n- Exit.\n\n\n"); - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/edge_explorer2d.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/edge_explorer2d.cpp deleted file mode 100644 index b8188f82690..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/edge_explorer2d.cpp +++ /dev/null @@ -1,218 +0,0 @@ -/* - # - # File : edge_explorer2d.cpp - # ( C++ source file ) - # - # Description : Real time edge detection while moving a ROI - # (rectangle of interest) over the original image. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : Orges Leka - # ( oleka(at)students.uni-mainz.de ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#include "CImg.h" -using namespace cimg_library; -#ifndef cimg_imagepath -#define cimg_imagepath "img/" -#endif - -// Main procedure -//---------------- -int main(int argc, char** argv) { - - // Usage of the program displayed at the command line - cimg_usage("Real time edge detection with CImg. (c) Orges Leka"); - - // Read command line arguments - // With cimg_option we can get a new name for the image which is to be loaded from the command line. - const char* img_name = cimg_option("-i", cimg_imagepath "parrot.ppm","Input image."); - double - alpha = cimg_option("-a",1.0,"Blurring the gradient image."), - thresL = cimg_option("-tl",13.5,"Lower thresholding used in Hysteresis."), - thresH = cimg_option("-th",13.6,"Higher thresholding used in Hysteresis."); - const unsigned int - mode = cimg_option("-m",1,"Detection mode: 1 = Hysteresis, 2 = Gradient angle."), - factor = cimg_option("-s",80,"Half-size of edge-explorer window."); - - cimg_help("\nAdditional notes : user can press following keys on main display window :\n" - " - Left arrow : Decrease alpha.\n" - " - Right arrow : Increase alpha.\n"); - - // Construct a new image called 'edge' of size (2*factor,2*factor) - // and of type 'unsigned char'. - CImg edge(2*factor,2*factor); - CImgDisplay disp_edge(512,512,"Edge Explorer"); - - // Load the image with the name 'img_name' into the CImg 'img'. - // and create a display window 'disp' for the image 'img'. - const CImg img = CImg::get_load(img_name).norm().normalize(0,255); - CImgDisplay disp(img,"Original Image"); - - // Begin main interaction loop. - int x = 0, y = 0; - bool redraw = false; - while (!disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC()) { - disp.wait(100); - if (disp.button()&1) { alpha+=0.05; redraw = true; } - if (disp.button()&2) { alpha-=0.05; redraw = true; } - if (disp.wheel()) { alpha+=0.05*disp.wheel(); disp.set_wheel(); redraw = true; } - if (alpha<0) alpha = 0; - if (disp_edge.is_resized()) { disp_edge.resize(); redraw = true; } - if (disp_edge.is_closed()) disp_edge.show(); - if (disp.is_resized()) disp.resize(disp); - if (disp.mouse_x()>=0) { - x = disp.mouse_x(); // Getting the current position of the mouse. - y = disp.mouse_y(); // - redraw = true; // The image should be redrawn. - } - if (redraw) { - disp_edge.set_title("Edge explorer (alpha=%g)",alpha); - const int - x0 = x - factor, y0 = y - factor, // These are the coordinates for the red rectangle - x1 = x + factor, y1 = y + factor; // to be drawn on the original image. - const unsigned char - red[3] = { 255,0,0 }, // - black[3] = { 0,0,0 }; // Defining the colors we need for drawing. - - (+img).draw_rectangle(x0,y0,x1,y1,red,1.0f,0x55555555U).display(disp); - //^ We draw the red rectangle on the original window using 'draw_line'. - // Then we display the result via '.display(disp)' . - // Observe, that the color 'red' has to be of type 'const unsigned char', - // since the image 'img' is of type 'const CImg'. - - //'normalize' is used to get a greyscaled image. - CImg<> visu_bw = CImg<>(img).get_crop(x0,y0,x1,y1).get_norm().normalize(0,255).resize(-100,-100,1,2,2); - // get_crop(x0,y0,x1,y1) gets the rectangle we are interested in. - - edge.fill(255); // Background color in the edge-detection window is white. - - // grad[0] is the gradient image of 'visu_bw' in x-direction. - // grad[1] is the gradient image of 'visu_bw' in y-direction. - CImgList<> grad(visu_bw.blur((float)alpha).normalize(0,255).get_gradient()); - - // To avoid unnecessary calculations in the image loops: - const double - pi = cimg::PI, - p8 = pi/8.0, p38 = 3.0*p8, - p58 = 5.0*p8, p78 = 7.0*p8; - - cimg_forXY(visu_bw,s,t) { - // We take s,t instead of x,y, since x,y are already used. - // s corresponds to the x-ordinate of the pixel while t corresponds to the y-ordinate. - if ( 1 <= s && s <= visu_bw.width() - 1 && 1 <= t && t <=visu_bw.height() - 1) { // if - good points - double - Gs = grad[0](s,t), // - Gt = grad[1](s,t), // The actual pixel is (s,t) - Gst = cimg::abs(Gs) + cimg::abs(Gt), // - // ^-- For efficient computation we observe that |Gs|+ |Gt| ~=~ sqrt( Gs^2 + Gt^2) - Gr, Gur, Gu, Gul, Gl, Gdl, Gd, Gdr; - // ^-- right, up right, up, up left, left, down left, down, down right. - double theta = std::atan2(Gt,Gs) + pi; // theta is from the interval [0,Pi] - switch(mode) { - case 1: // Hysterese is applied - if (Gst>=thresH) { edge.draw_point(s,t,black); } - else if (thresL <= Gst && Gst < thresH) { - // Neighbourhood of the actual pixel: - Gr = cimg::abs(grad[0](s + 1,t)) + cimg::abs(grad[1](s + 1,t)); // right - Gl = cimg::abs(grad[0](s - 1,t)) + cimg::abs(grad[1](s - 1,t)); // left - Gur = cimg::abs(grad[0](s + 1,t + 1)) + cimg::abs(grad[1](s + 1,t + 1)); // up right - Gdl = cimg::abs(grad[0](s - 1,t - 1)) + cimg::abs(grad[1](s - 1,t - 1)); // down left - Gu = cimg::abs(grad[0](s,t + 1)) + cimg::abs(grad[1](s,t + 1)); // up - Gd = cimg::abs(grad[0](s,t - 1)) + cimg::abs(grad[1](s,t - 1)); // down - Gul = cimg::abs(grad[0](s - 1,t + 1)) + cimg::abs(grad[1](s - 1,t + 1)); // up left - Gdr = cimg::abs(grad[0](s + 1,t - 1)) + cimg::abs(grad[1](s + 1,t - 1)); // down right - if (Gr>=thresH || Gur>=thresH || Gu>=thresH || Gul>=thresH - || Gl>=thresH || Gdl >=thresH || Gu >=thresH || Gdr >=thresH) { - edge.draw_point(s,t,black); - } - }; - break; - case 2: // Angle 'theta' of the gradient (Gs,Gt) at the point (s,t). - if(theta >= pi)theta-=pi; - //rounding theta: - if ((p8 < theta && theta <= p38 ) || (p78 < theta && theta <= pi)) { - // See (*) below for explanation of the vocabulary used. - // Direction-pixel is (s + 1,t) with corresponding gradient value Gr. - Gr = cimg::abs(grad[0](s + 1,t)) + cimg::abs(grad[1](s + 1,t)); // right - // Contra-direction-pixel is (s - 1,t) with corresponding gradient value Gl. - Gl = cimg::abs(grad[0](s - 1,t)) + cimg::abs(grad[1](s - 1,t)); // left - if (Gr < Gst && Gl < Gst) { - edge.draw_point(s,t,black); - } - } - else if ( p8 < theta && theta <= p38) { - // Direction-pixel is (s + 1,t + 1) with corresponding gradient value Gur. - Gur = cimg::abs(grad[0](s + 1,t + 1)) + cimg::abs(grad[1](s + 1,t + 1)); // up right - // Contra-direction-pixel is (s-1,t-1) with corresponding gradient value Gdl. - Gdl = cimg::abs(grad[0](s - 1,t - 1)) + cimg::abs(grad[1](s - 1,t - 1)); // down left - if (Gur < Gst && Gdl < Gst) { - edge.draw_point(s,t,black); - } - } - else if ( p38 < theta && theta <= p58) { - // Direction-pixel is (s,t + 1) with corresponding gradient value Gu. - Gu = cimg::abs(grad[0](s,t + 1)) + cimg::abs(grad[1](s,t + 1)); // up - // Contra-direction-pixel is (s,t - 1) with corresponding gradient value Gd. - Gd = cimg::abs(grad[0](s,t - 1)) + cimg::abs(grad[1](s,t - 1)); // down - if (Gu < Gst && Gd < Gst) { - edge.draw_point(s,t,black); - } - } - else if (p58 < theta && theta <= p78) { - // Direction-pixel is (s - 1,t + 1) with corresponding gradient value Gul. - Gul = cimg::abs(grad[0](s - 1,t + 1)) + cimg::abs(grad[1](s - 1,t + 1)); // up left - // Contra-direction-pixel is (s + 1,t - 1) with corresponding gradient value Gdr. - Gdr = cimg::abs(grad[0](s + 1,t - 1)) + cimg::abs(grad[1](s + 1,t - 1)); // down right - if (Gul < Gst && Gdr < Gst) { - edge.draw_point(s,t,black); - } - }; - break; - } // switch - } // if good-points - } // cimg_forXY */ - edge.display(disp_edge); - }// if redraw - } // while - return 0; -} - -// (*) Comments to the vocabulary used: -// If (s,t) is the current pixel, and G=(Gs,Gt) is the gradient at (s,t), -// then the _direction_pixel_ of (s,t) shall be the one of the eight neighbour pixels -// of (s,t) in whose direction the gradient G shows. -// The _contra_direction_pixel is the pixel in the opposite direction in which the gradient G shows. -// The _corresponding_gradient_value_ of the pixel (x,y) with gradient G = (Gx,Gy) -// shall be |Gx| + |Gy| ~=~ sqrt(Gx^2 + Gy^2). diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/fade_images.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/fade_images.cpp deleted file mode 100644 index 6e5e0b6b290..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/fade_images.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - # - # File : fade_images.cpp - # ( C++ source file ) - # - # Description : Compute a linear fading between two images. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#include "CImg.h" -#ifndef cimg_imagepath -#define cimg_imagepath "img/" -#endif -#undef min -#undef max - -// Main procedure -//--------------- -int main(int argc,char **argv) { - - // Read and check command line parameters. - cimg_usage("Compute a linear fading between two 2D images"); - const char *file_i1 = cimg_option("-i1",cimg_imagepath "sh0r.pgm","Input Image 1"); - const char *file_i2 = cimg_option("-i2",cimg_imagepath "milla.bmp","Input Image 2"); - const char *file_o = cimg_option("-o",(char*)0,"Output Image"); - const bool visu = cimg_option("-visu",true,"Visualization mode"); - const double pmin = cimg_option("-min",40.0,"Begin of the fade (in %)")/100.0; - const double pmax = cimg_option("-max",60.0,"End of the fade (in %)")/100.0; - const double angle = cimg_option("-angle",0.0,"Fade angle")*cil::cimg::PI/180; - - // Init images. - cil::CImg img1(file_i1), img2(file_i2); - if (!img2.is_sameXYZC(img1)) { - int - dx = cil::cimg::max(img1.width(),img2.width()), - dy = cil::cimg::max(img1.height(),img2.height()), - dz = cil::cimg::max(img1.depth(),img2.depth()), - dv = cil::cimg::max(img1.spectrum(),img2.spectrum()); - img1.resize(dx,dy,dz,dv,3); - img2.resize(dx,dy,dz,dv,3); - } - cil::CImg dest(img1); - - // Compute the faded image. - const double ca = std::cos(angle), sa = std::sin(angle); - double alpha; - cimg_forXYZC(dest,x,y,z,k) { - const double X = ((double)x/img1.width() - 0.5)*ca + ((double)y/img1.height() - 0.5)*sa; - if (X + 0.5pmax) alpha = 1; else - alpha = (X + 0.5 - pmin)/(pmax - pmin); - } - dest(x,y,z,k) = (unsigned char)((1 - alpha)*img1(x,y,z,k) + alpha*img2(x,y,z,k)); - } - - // Save and exit - if (file_o) dest.save(file_o); - if (visu) dest.display("Image fading"); - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/gaussian_fit1d.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/gaussian_fit1d.cpp deleted file mode 100644 index 0d13db7b240..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/gaussian_fit1d.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* - # - # File : gaussian_fit1d.cpp - # ( C++ source file ) - # - # Description : Fit a gaussian function on a set of sample points, - # using the Levenberg-Marquardt algorithm. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#ifndef cimg_plugin -#define cimg_plugin "examples/gaussian_fit1d.cpp" -#include "CImg.h" -using namespace cimg_library; -#undef min -#undef max - -// Main procedure -//---------------- -int main(int argc,char **argv) { - cimg_usage("Fit gaussian function on sample points, using Levenberg-Marquardt algorithm."); - - // Read command line arguments. - const char *s_params = cimg_option("-p","10,3,4","Amplitude, Mean and Std of the ground truth"); - const unsigned int s_nb = cimg_option("-N",40,"Number of sample points"); - const float s_noise = cimg_option("-n",10.0f,"Pourcentage of noise on the samples points"); - const char *s_xrange = cimg_option("-x","-10,10","X-range allowed for the sample points"); - const char *f_params = cimg_option("-p0",(char*)0,"Amplitude, Mean and Std of the first estimate"); - const float f_lambda0 = cimg_option("-l",100.0f,"Initial damping factor"); - const float f_dlambda = cimg_option("-dl",0.9f,"Damping attenuation"); - float s_xmin = -10, s_xmax = 10, s_amp = 1, s_mean = 1, s_std = 1; - std::sscanf(s_xrange,"%f%*c%f",&s_xmin,&s_xmax); - std::sscanf(s_params,"%f%*c%f%*c%f",&s_amp,&s_mean,&s_std); - - // Create noisy samples of a Gaussian function. - const float s_std2 = 2*s_std*s_std, s_fact = s_amp/((float)std::sqrt(2*cimg::PI)*s_std); - CImg<> samples(s_nb,2); - cimg_forX(samples,i) { - const float - x = (float)(s_xmin + (s_xmax - s_xmin)*cimg::rand()), - y = s_fact*(float)(1 + s_noise*cimg::grand()/100)*std::exp(-cimg::sqr(x - s_mean)/s_std2); - samples(i,0) = x; - samples(i,1) = y; - } - - // Fit Gaussian function on the sample points and display curve iterations. - CImgDisplay disp(640,480,"Levenberg-Marquardt Gaussian Fitting",0); - float f_amp = 1, f_mean = 1, f_std = 1, f_lambda = f_lambda0; - if (f_params) std::sscanf(f_params,"%f%*c%f%*c%f",&f_amp,&f_mean,&f_std); - else { - const float& vmax = samples.get_shared_row(1).max(); - float cmax = 0; samples.contains(vmax,cmax); - f_mean = samples((int)cmax,0); - f_std = (s_xmax - s_xmin)/10; - f_amp = vmax*(float)std::sqrt(2*cimg::PI)*f_std; - } - CImg<> beta = CImg<>::vector(f_amp,f_mean,f_std); - for (unsigned int iter = 0; !disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC(); ++iter) { - - // Do one iteration of the Levenberg-Marquardt algorithm. - CImg<> YmF(1,s_nb), J(beta.height(),s_nb); - const float - f_amp = beta(0), f_mean = beta(1), f_std = beta(2), - f_std2 = 2*f_std*f_std, f_fact = (float)std::sqrt(2*cimg::PI)*f_std; - float f_error = 0; - cimg_forY(J,i) { - const float - x = samples(i,0), - f_exp = std::exp(-cimg::sqr(x - f_mean)/f_std2), - delta = samples(i,1) - f_amp*f_exp/f_fact; - YmF(i) = delta; - J(0,i) = f_exp/f_fact; - J(1,i) = f_amp*f_exp/f_fact*(x - f_mean)*2/f_std2; - J(2,i) = f_amp*f_exp/f_fact*(cimg::sqr(x - f_mean)/(f_std*f_std*f_std)); - f_error+=cimg::sqr(delta); - } - - CImg<> Jt = J.get_transpose(), M = Jt*J; - cimg_forX(M,x) M(x,x)*=1 + f_lambda; - beta+=M.get_invert()*Jt*YmF; - if (beta(0)<=0) beta(0) = 0.1f; - if (beta(2)<=0) beta(2) = 0.1f; - f_lambda*=f_dlambda; - - // Display fitting curves. - const unsigned char black[] = { 0,0,0 }, gray[] = { 228,228,228 }; - CImg(disp.width(),disp.height(),1,3,255). - draw_gaussfit(samples,beta(0),beta(1),beta(2),s_amp,s_mean,s_std). - draw_rectangle(5,7,150,100,gray,0.9f).draw_rectangle(5,7,150,100,black,1,~0U). - draw_text(10,10,"Iteration : %d",black,0,1,13,iter). - draw_text(10,25,"Amplitude : %.4g (%.4g)",black,0,1,13,beta(0),s_amp). - draw_text(10,40,"Mean : %.4g (%.4g)",black,0,1,13,beta(1),s_mean). - draw_text(10,55,"Std : %.4g (%.4g)",black,0,1,13,beta(2),s_std). - draw_text(10,70,"Error : %.4g",black,0,1,13,std::sqrt(f_error)). - draw_text(10,85,"Lambda : %.4g",black,0,1,13,f_lambda). - display(disp.resize(false).wait(20)); - } - - return 0; -} - -#else - -// Draw sample points, ideal and fitted gaussian curves on the instance image. -// (defined as a CImg plug-in function). -template -CImg& draw_gaussfit(const CImg& samples, - const float f_amp, const float f_mean, const float f_std, - const float i_amp, const float i_mean, const float i_std) { - if (is_empty()) return *this; - const unsigned char black[] = { 0,0,0 }, green[] = { 10,155,20 }, orange[] = { 155,20,0 }, purple[] = { 200,10,200 }; - float - xmin, xmax = samples.get_shared_row(0).max_min(xmin), deltax = xmax - xmin, - ymin, ymax = samples.get_shared_row(1).max_min(ymin), deltay = ymax - ymin; - xmin-=0.2f*deltax; xmax+=0.2f*deltax; ymin-=0.2f*deltay; ymax+=0.2f*deltay; - deltax = xmax - xmin; deltay = ymax - ymin; - draw_grid(64,64,0,0,false,false,black,0.3f,0x55555555,0x55555555).draw_axes(xmin,xmax,ymax,ymin,black,0.8f); - CImg<> nsamples(samples); - (nsamples.get_shared_row(0)-=xmin)*=width()/deltax; - (nsamples.get_shared_row(1)-=ymax)*=-height()/deltay; - cimg_forX(nsamples,i) draw_circle((int)nsamples(i,0),(int)nsamples(i,1),3,orange,1,~0U); - CImg truth(width(),2), fit(width(),2); - const float - i_std2 = 2*i_std*i_std, i_fact = i_amp/((float)std::sqrt(2*cimg::PI)*i_std), - f_std2 = 2*f_std*f_std, f_fact = f_amp/((float)std::sqrt(2*cimg::PI)*f_std); - cimg_forX(*this,x) { - const float - x0 = xmin + x*deltax/width(), - ys0 = i_fact*std::exp(-cimg::sqr(x0 - i_mean)/i_std2), - yf0 = f_fact*std::exp(-cimg::sqr(x0 - f_mean)/f_std2); - fit(x,0) = truth(x,0) = x; - truth(x,1) = (int)((ymax - ys0)*height()/deltay); - fit(x,1) = (int)((ymax - yf0)*height()/deltay); - } - return draw_line(truth,green,0.7f,0xCCCCCCCC).draw_line(fit,purple); -} - -#endif diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/generate_loop_macros.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/generate_loop_macros.cpp deleted file mode 100644 index ab09d8a9394..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/generate_loop_macros.cpp +++ /dev/null @@ -1,353 +0,0 @@ -/* - # - # File : generate_loop_macros.cpp - # ( C++ source file ) - # - # Description : Generate C++ macros to deal with MxN[xP] neighborhood - # loops within the CImg Library. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#include "CImg.h" -using namespace cimg_library; - -// Generate macro(s) 'cimg_forN(i,bound)' -//---------------------------------------- -void generate_forN(const unsigned int N) { - if (N>=2) { - const unsigned int Nn = N/2, Np = Nn - ((N + 1)%2); - std::printf("#define cimg_for%u(bound,i) for (int i = 0, \\\n",N); - for (unsigned int k = 0; k=(int)(bound)?(int)(bound) - 1:%u%c \\\n",k,k,k,k==Nn?';':','); - std::printf(" _n%u##i<(int)(bound) || ",Nn); - for (unsigned int k = Nn - 1; k>=1; --k) std::printf("_n%u##i==--_n%u##i || ",k,k + 1); - std::printf("\\\n i==("); - for (unsigned int k = Nn; k>=2; --k) std::printf("_n%u##i = ",k); - std::printf("--_n1##i); \\\n "); - for (unsigned int k = Np; k>=2; --k) std::printf("_p%u##i = _p%u##i, ",k,k - 1); - if (Np) std::printf("_p1##i = i++, \\\n "); - else std::printf(" ++i, "); - for (unsigned int k = 1; k=2) { - const unsigned int Nn = N/2, Np = Nn - ((N + 1)%2); - std::printf("#define cimg_for_in%u(bound,i0,i1,i) for (int i = (int)(i0)<0?0:(int)(i0), \\\n",N); - for (unsigned int k = 0; k=(int)(bound)?(int)(bound) - 1:i + %u%c \\\n",k,k,k,k==Nn?';':','); - std::printf(" i<=(int)(i1) && (_n%u##i<(int)(bound) || ",Nn); - for (unsigned int k = Nn - 1; k>=1; --k) std::printf("_n%u##i==--_n%u##i || ",k,k + 1); - std::printf("\\\n i==("); - for (unsigned int k = Nn; k>=2; --k) std::printf("_n%u##i = ",k); - std::printf("--_n1##i)); \\\n "); - for (unsigned int k = Np; k>=2; --k) std::printf("_p%u##i = _p%u##i, ",k,k - 1); - if (Np) std::printf("_p1##i = i++, \\\n "); - else std::printf(" ++i, "); - for (unsigned int k = 1; k1) std::printf("#define cimg_for%ux%ux%u(img,x,y,z,c,I,T) \\\n cimg_for%u((img)._depth,z)",M,N,P,P); - else std::printf("#define cimg_for%ux%u(img,x,y,z,c,I,T) \\\n",M,N); - if (N>1) std::printf(" cimg_for%u((img)._height,y) ",N); - else std::printf(" cimg_forY(img,y) "); - - std::printf("for (int x = 0%c \\\n",M>1?',':';'); - for (int k = Mp; k>=1; --k) std::printf(" _p%u##x = 0%s",k,k==1?", \\\n":","); - for (int k = 1; k=((img)._width)?(img).width() - 1:%u, \\\n",k,k,k); - - if (M>1) { - std::printf(" _n%u##x = (int)( \\\n ",Mn); - for (int k = 0, z = -Pp; z<=Pn; ++z) - for (int y = -Np; y<=Nn; ++y) { - for (int x = -Mp; x<=0; ++x) { std::printf("%sI[%d] =",k && x==-Mp?" (":(x==-Mp?"(":" "),k); ++k; } - k+=Mn; - if (y<0) std::sprintf(indy,"_p%d##",-y); else if (y>0) std::sprintf(indy,"_n%d##",y); else indy[0]='\0'; - if (z<0) std::sprintf(indz,"_p%d##",-z); else if (z>0) std::sprintf(indz,"_n%d##",z); else indz[0]='\0'; - std::printf(" (T)(img)(0,%sy,%sz,c))%s",indy,indz,k>=last?",":", \\\n"); - } - - std::printf(" \\\n"); - for (int x = 1; x0) std::sprintf(indy,"_n%d##",y); else indy[0]='\0'; - if (z<0) std::sprintf(indz,"_p%d##",-z); else if (z>0) std::sprintf(indz,"_n%d##",z); else indz[0]='\0'; - std::printf(" (I[%d] = (T)(img)(_n%d##x,%sy,%sz,c)), \\\n",(Mp + x) + (y + Np)*M + (z + Pp)*M*N,x,indy,indz); - } - std::printf(" %u>=((img)._width)?(img).width() - 1:%u); \\\n",Mn,Mn); - } - - if (M>1) std::printf(" (_n%u##x",Mn); else std::printf(" (x"); - std::printf("<(img).width() && ( \\\n"); - - for (int z = -Pp; z<=Pn; ++z) - for (int y = -Np; y<=Nn; ++y) { - if (M>1) std::sprintf(indx,"_n%d##",Mn); else indx[0]='\0'; - if (y<0) std::sprintf(indy,"_p%d##",-y); else if (y>0) std::sprintf(indy,"_n%d##",y); else indy[0]='\0'; - if (z<0) std::sprintf(indz,"_p%d##",-z); else if (z>0) std::sprintf(indz,"_n%d##",z); else indz[0]='\0'; - std::printf(" (I[%d] = (T)(img)(%sx,%sy,%sz,c))%s",M - 1 + (y + Np)*M + (z + Pp)*M*N,indx,indy,indz, - z==Pn && y==Nn?",1))":", \\\n"); - } - - if (M>1) { - std::printf(" || \\\n "); - for (int k = Mn - 1; k>=1; --k) std::printf("_n%d##x==--_n%u##x || ",k,k + 1); - std::printf("x==("); - for (int k = Mn; k>=2; --k) std::printf("_n%d##x = ",k); - std::printf("--_n1##x); \\\n"); - } else std::printf("; \\\n"); - - if (M>1) { - for (unsigned int k = 0, z = 0; z=2; --k) std::printf("_p%d##x = _p%d##x, ",k,k - 1); - if (M>2) std::printf("_p1##x = x++, "); else std::printf("++x, "); - for (int k = 1; k<=Mn - 1; ++k) std::printf("++_n%d##x, ",k); - std::printf("++_n%d##x)\n\n",Mn); - } else std::printf(" ++x)\n\n"); -} - -// Generate macro 'cimg_for_inMxN[xP](img,x,y,z,c,I,T)' -//----------------------------------------------------- -void generate_for_inMxNxP(const unsigned int M, const unsigned int N, const unsigned int P) { - char indx[16], indy[16], indz[16]; - const int - Mn = (int)(M/2), Mp = (int)(Mn - ((M + 1)%2)), - Nn = (int)(N/2), Np = (int)(Nn - ((N + 1)%2)), - Pn = (int)(P/2), Pp = (int)(Pn - ((P + 1)%2)); - - if (P>1) - std::printf("#define cimg_for_in%ux%ux%u(img,x0,y0,z0,x1,y1,z1,x,y,z,c,I,T) \\\n " - "cimg_for_in%u((img)._depth,z0,z1,z)",M,N,P,P); - else std::printf("#define cimg_for_in%ux%u(img,x0,y0,x1,y1,x,y,z,c,I,T) \\\n",M,N); - if (N>1) std::printf(" cimg_for_in%u((img)._height,y0,y1,y) ",N); - else std::printf(" cimg_for_inY(img,y0,y1,y) "); - - std::printf("for (int x = (int)(x0)<0?0:(int)(x0)%c \\\n",M>1?',':';'); - for (int k = Mp; k>=1; --k) std::printf(" _p%u##x = x - %u<0?0:x - %u, \\\n",k,k,k); - for (int k = 1; k=(img).width()?(img).width() - 1:x + %u, \\\n",k,k,k); - - if (M>1) { - std::printf(" _n%u##x = (int)( \\\n",Mn); - for (int x = -Mp; x0) std::sprintf(indx,"_n%d##",x); else indx[0]='\0'; - if (y<0) std::sprintf(indy,"_p%d##",-y); else if (y>0) std::sprintf(indy,"_n%d##",y); else indy[0]='\0'; - if (z<0) std::sprintf(indz,"_p%d##",-z); else if (z>0) std::sprintf(indz,"_n%d##",z); else indz[0]='\0'; - std::printf(" (I[%d] = (T)(img)(%sx,%sy,%sz,c)), \\\n",(Mp + x) + (y + Np)*M + (z + Pp)*M*N,indx,indy,indz); - } - std::printf(" x + %u>=(img).width()?(img).width() - 1:x + %u); \\\n",Mn,Mn); - } - std::printf(" x<=(int)(x1) && ("); - if (M>1) std::printf("(_n%u##x",Mn); else std::printf("(x"); - std::printf("<(img).width() && ( \\\n"); - - for (int z = -Pp; z<=Pn; ++z) - for (int y = -Np; y<=Nn; ++y) { - if (M>1) std::sprintf(indx,"_n%d##",Mn); else indx[0]='\0'; - if (y<0) std::sprintf(indy,"_p%d##",-y); else if (y>0) std::sprintf(indy,"_n%d##",y); else indy[0]='\0'; - if (z<0) std::sprintf(indz,"_p%d##",-z); else if (z>0) std::sprintf(indz,"_n%d##",z); else indz[0]='\0'; - std::printf(" (I[%d] = (T)(img)(%sx,%sy,%sz,c))%s",M - 1 + (y + Np)*M + (z + Pp)*M*N,indx,indy,indz, - z==Pn && y==Nn?",1))":", \\\n"); - } - - if (M>1) { - std::printf(" || \\\n "); - for (int k = Mn - 1; k>=1; --k) std::printf("_n%d##x==--_n%u##x || ",k,k + 1); - std::printf("x==("); - for (int k = Mn; k>=2; --k) std::printf("_n%d##x = ",k); - std::printf("--_n1##x)); \\\n"); - } else std::printf("); \\\n"); - - if (M>1) { - for (unsigned int k = 0, z = 0; z=2; --k) std::printf("_p%d##x = _p%d##x, ",k,k - 1); - if (M>2) std::printf("_p1##x = x++, "); else std::printf("++x, "); - for (int k = 1; k<=Mn - 1; ++k) std::printf("++_n%d##x, ",k); - std::printf("++_n%d##x)\n\n",Mn); - } else std::printf(" ++x)\n\n"); -} - -// Generate macro 'cimg_getMxN[xP](img,x,y,z,c,I,T)' -//-------------------------------------------------- -void generate_getMxNxP(const unsigned int M, const unsigned int N, const unsigned int P) { - const int - Mn = (int)(M/2), Mp = (int)(Mn - ((M + 1)%2)), - Nn = (int)(N/2), Np = (int)(Nn - ((N + 1)%2)), - Pn = (int)(P/2), Pp = (int)(Pn - ((P + 1)%2)), - last = M*N*P - 1; - if (P>1) std::printf("#define cimg_get%ux%ux%u(img,x,y,z,c,I,T) \\\n",M,N,P); - else std::printf("#define cimg_get%ux%u(img,x,y,z,c,I,T) \\\n",M,N); - char indx[16], indy[16], indz[16]; - for (int k = 0, z = -Pp; z<=Pn; ++z) - for (int y = -Np; y<=Nn; ++y) - for (int x = -Mp; x<=Mn; ++x) { - if (x<0) std::sprintf(indx,"_p%d##",-x); else if (x>0) std::sprintf(indx,"_n%d##",x); else indx[0]='\0'; - if (y<0) std::sprintf(indy,"_p%d##",-y); else if (y>0) std::sprintf(indy,"_n%d##",y); else indy[0]='\0'; - if (z<0) std::sprintf(indz,"_p%d##",-z); else if (z>0) std::sprintf(indz,"_n%d##",z); else indz[0]='\0'; - std::printf(" I[%u] = (T)(img)(%sx,%sy,%sz,c)%s",k,indx,indy,indz, - k==last?";\n\n":(x==Mn?", \\\n":",")); - ++k; - } -} - -//----------------- -// Main Procedure -//----------------- -int main(int argc, char **argv) { - - cimg_usage("Generate C++ macros to deal with MxN[xP] neighborhood loops within the CImg Library"); - - // Read command line arguments - //---------------------------- - const char *const size = cimg_option("-s","5x4","Size of the neighborhood"); - const bool do_forN = cimg_option("-forN",true,"Generate 'cimg_forN()'"); - const bool do_for_inN = cimg_option("-for_inN",true,"Generate 'cimg_for_inN()'"); - const bool do_for = cimg_option("-for",true,"Generate 'cimg_forMxNxP()'"); - const bool do_for_in = cimg_option("-for_in",true,"Generate 'cimg_for_inMxNxP()'"); - const bool do_get = cimg_option("-get",true,"Generate 'cimg_getMxNxP()'"); - if (cimg_option("-h",false,0)) std::exit(0); - - unsigned int M = 1, N = 1 , P = 1; - std::sscanf(size,"%u%*c%u%*c%u",&M,&N,&P); - if (!M || !N || !P || (M==1 && N==1 && P==1)) { - std::fprintf(stderr,"\n%s : Error, bad neighborhood size '%s'\n",argv[0],size); - std::exit(0); - } - if (!do_forN && !do_get && !do_for) return 0; - - if (P>1) - std::printf("// Define %ux%ux%u loop macros\n" - "//----------------------------\n",M,N,P); - else - std::printf("// Define %ux%u loop macros\n" - "//-------------------------\n",M,N); - - if (do_forN) { - if (N>1) generate_forN(N); - if (P>1 && P!=N) generate_forN(P); - } - if (do_for_inN) { - if (N>1) generate_for_inN(N); - if (P>1 && P!=N) generate_for_inN(P); - } - if (do_for) generate_forMxNxP(M,N,P); - if (do_for_in) generate_for_inMxNxP(M,N,P); - if (do_get) generate_getMxNxP(M,N,P); - - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/hough_transform2d.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/hough_transform2d.cpp deleted file mode 100644 index 16e29acf579..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/hough_transform2d.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* - # - # File : hough_transform2d.cpp - # ( C++ source file ) - # - # Description : Implementation of the Hough transform. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#include "CImg.h" -using namespace cimg_library; -#ifndef cimg_imagepath -#define cimg_imagepath "img/" -#endif - -// Main procedure -//---------------- -int main(int argc,char **argv) { - cimg_usage("Illustration of the Hough transform"); - CImg src(cimg_option("-i",cimg_imagepath "parrot.ppm","Input image")); - CImg<> vote(500,400,1,1,0), img = src.get_norm().normalize(0,255).resize(-100,-100,1,2,2); - - CImgDisplay disp(src,"Image"), dispvote(vote,"Hough Transform"); - const unsigned char col1[3]={255,255,255}, col2[3]={0,0,0}; - const double - alpha = cimg_option("-a",1.5,"Gradient smoothing"), - sigma = cimg_option("-s",0.5,"Hough Transform smoothing"), - rhomax = std::sqrt((double)(img.width()*img.width() + img.height()*img.height()))/2, - thetamax = 2*cimg::PI; - - if (cimg::dialog(cimg::basename(argv[0]), - "Instructions : \n" - "----------------\n\n" - "(1) When clicking on the color image, all lines crossing the selected point\n" - "will be voted in the Hough buffer.\n\n" - "(2) When clicking on the Hough buffer, the corresponding line is drawn\n" - "on the color image.\n\n" - "(3) When pressing the space bar, lines in the color image are detected from the\n" - "image gradients through votes in the Hough buffer.\n\n" - "Note that a logarithmic scaling is performed for displayin the vote image.\n" - "See also the available options (option '-h')\n","Start !","Quit",0,0,0,0, - src.get_resize(100,100,1,3),true)) std::exit(0); - - while (!disp.is_closed() && !dispvote.is_closed() && - !disp.is_keyQ() && !dispvote.is_keyQ() && !disp.is_keyESC() && !dispvote.is_keyESC()) { - - CImgDisplay::wait(disp,dispvote); - - // When pressing space bar, the vote is performed from the image gradients. - if (dispvote.is_keySPACE() || disp.is_keySPACE()) { - CImgList<> grad = img.get_gradient(); - cimglist_for(grad,l) grad[l].blur((float)alpha); - vote.fill(0); - cimg_forXY(img,x,y) { - const double - X = (double)x - img.width()/2, - Y = (double)y - img.height()/2, - gx = grad[0](x,y), - gy = grad[1](x,y); - double - theta = std::atan2(gy,gx), - rho = std::sqrt(X*X + Y*Y)*std::cos(std::atan2(Y,X) - theta); - if (rho<0) { rho=-rho; theta+=cimg::PI; } - theta = cimg::mod(theta,thetamax); - vote((int)(theta*dispvote.width()/thetamax),(int)(rho*dispvote.height()/rhomax))+= - (float)std::sqrt(gx*gx + gy*gy); - } - vote.blur((float)sigma); - CImg<> vote2(vote); cimg_forXY(vote2,x,y) vote2(x,y) = (float)std::log(1 + vote(x,y)); vote2.display(dispvote); - } - - // When clicking on the vote window. - if (dispvote.button()) { - const double - rho = dispvote.mouse_y()*rhomax/dispvote.height(), - theta = dispvote.mouse_x()*thetamax/dispvote.width(), - x = img.width()/2 + rho*std::cos(theta), - y = img.height()/2 + rho*std::sin(theta); - const int - x0 = (int)(x + 1000*std::sin(theta)), - y0 = (int)(y - 1000*std::cos(theta)), - x1 = (int)(x - 1000*std::sin(theta)), - y1 = (int)(y + 1000*std::cos(theta)); - CImg(src). - draw_line(x0,y0,x1,y1,col1,1.0f,0xF0F0F0F0).draw_line(x0,y0,x1,y1,col2,1.0f,0x0F0F0F0F). - draw_line(x0 + 1,y0,x1 + 1,y1,col1,1.0f,0xF0F0F0F0).draw_line(x0 + 1,y0,x1 + 1,y1,col2,1.0f,0x0F0F0F0F). - draw_line(x0,y0 + 1,x1,y1 + 1,col1,1.0f,0xF0F0F0F0).draw_line(x0,y0 + 1,x1,y1 + 1,col2,1.0f,0x0F0F0F0F). - display(disp); - } - - // When clicking on the image. - if (disp.button() && disp.mouse_x()>=0) { - const double - x0 = (double)disp.mouse_x() - disp.width()/2, - y0 = (double)disp.mouse_y() - disp.height()/2, - rho0 = std::sqrt(x0*x0 + y0*y0), - theta0 = std::atan2(y0,x0); - - for (double t=0; t vote2(vote); cimg_forXY(vote2,x,y) vote2(x,y) = (float)std::log(1 + vote(x,y)); vote2.display(dispvote); - } - dispvote.resize(dispvote); - disp.resize(disp); - } - - std::exit(0); - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/image2ascii.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/image2ascii.cpp deleted file mode 100644 index 460622c843e..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/image2ascii.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* - # - # File : image2ascii.cpp - # ( C++ source file ) - # - # Description : A basic image to ASCII-art converter. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -// Tell CImg not to use display capabilities. -#undef cimg_display -#define cimg_display 0 -#include "CImg.h" -using namespace cimg_library; - -/*--------------------------- - - Main procedure - - --------------------------*/ -int main(int argc,char **argv) { - cimg_usage("A simple image to ASCII-art converter.\n\nUsage : image2ascii [options] image"); - - // Read command line parameters - const char *const file_i = cimg_option("-i",(char*)0,"Input image"); - const char *const geom = cimg_option("-g","79x40","Output size"); - const int alphabet = cimg_option("-a",0,"Alphabet type (0=full, 1=numbers, 2=letters, 3=signs, 4=minimal"); - const bool invert = cimg_option("-invert",false,"Invert image intensities"); - const float contour = (float)cimg_option("-contour",0.0f,"Use image contours higher than specified threshold"); - const float blur = (float)cimg_option("-blur",0.8f,"Image pre-blur"); - const float sigma = (float)cimg_option("-sigma",10.0f,"Font pre-blur"); - - int w = 79, h = 40; - std::sscanf(geom,"%d%*c%d",&w,&h); - if (cimg_option("-h",false,0)) std::exit(0); - - // Init fonts - CImgList<> font_full = CImgList<>::font(13,false); - font_full.remove(0,255); - const int fw = font_full['A'].width(), fh = font_full['A'].height(); - CImgList<> font, font_blur; - CImgList font_code; - - switch (alphabet) { - case 1: { - font_code.insert(CImg<>::vector(' ')); - for (unsigned char l='0'; l<='9'; l++) font_code.insert(CImg<>::vector(l)); - } break; - case 2: { - font_code.insert(CImg<>::vector(' ')); - for (unsigned char l='A'; l<='Z'; l++) font_code.insert(CImg<>::vector(l)); - } break; - case 3: { - font_code.insert(CImg<>::vector(' ')); - font_code.insert(CImg<>::vector('-')); - font_code.insert(CImg<>::vector('_')); - font_code.insert(CImg<>::vector('|')); - font_code.insert(CImg<>::vector('/')); - font_code.insert(CImg<>::vector('\\')); - font_code.insert(CImg<>::vector('+')); - font_code.insert(CImg<>::vector('.')); - font_code.insert(CImg<>::vector('*')); - font_code.insert(CImg<>::vector('=')); - font_code.insert(CImg<>::vector(']')); - font_code.insert(CImg<>::vector('[')); - font_code.insert(CImg<>::vector('(')); - font_code.insert(CImg<>::vector(')')); - font_code.insert(CImg<>::vector('{')); - font_code.insert(CImg<>::vector('}')); - font_code.insert(CImg<>::vector('"')); - font_code.insert(CImg<>::vector('!')); - font_code.insert(CImg<>::vector('$')); - } break; - case 4: { - font_code.insert(CImg<>::vector(' ')); - font_code.insert(CImg<>::vector('.')); - font_code.insert(CImg<>::vector('/')); - font_code.insert(CImg<>::vector('\\')); - font_code.insert(CImg<>::vector('_')); - font_code.insert(CImg<>::vector('_')); - font_code.insert(CImg<>::vector('|')); - } break; - default: { for (unsigned char l=' '; l<='~'; l++) font_code.insert(CImg<>::vector(l)); } break; - } - cimglist_for(font_code,l) { - font.insert(font_full(font_code[l](0))); - font_blur.insert(font[l].get_resize(fw,fh,1,1).blur(sigma).normalize(0,255)); - } - - // Init images - CImg<> img; - if (!file_i) { float white[3] = { 255,255,255 }; img.assign().draw_text(0,0," CImg\nRocks !",white); } - else img.assign(file_i); - img.norm().resize(fw*w,fh*h); - if (blur) img.blur(blur); - if (contour>0) { - CImgList<> grad = img.get_gradient("xy",4); - img = (grad[0].pow(2) + grad[1].pow(2)).sqrt().normalize(0,100).threshold(contour); - } - img.normalize(0,255); - if (invert) img = 255.0f - img; - CImg dest(w,h,1,1,0); - - // Render ASCII-art image, using a simple correlation method. - CImg<> neigh; - cimg_forY(dest,y) { cimg_forX(dest,x) { - neigh = img.get_crop(x*fw,y*fh,(x + 1)*fw,(y + 1)*fh); - float scoremin = 2e28f; - unsigned int best = 0; - cimglist_for(font_code,l) { - const CImg<>& letter = font_blur[l]; - const float score = (float)((letter - neigh).pow(2).sum()); - if (score& src, const CImg& dest, const CImg<>& U, - const bool morph, const bool imode, const char *filename,int nb, CImgDisplay& disp) { - CImg visu = (src,dest,src)>'x', warp(src); - float t = 0; - for (unsigned int iteration = 0; !disp || (!disp.is_closed() && !disp.is_keyQ()); ++iteration) { - if (morph) cimg_forXYC(warp,x,y,k) { - const float dx = U(x,y,0), dy = U(x,y,1), - I1 = (float)src.linear_atXY(x - t*dx, y - t*dy, k), - I2 = (float)dest.linear_atXY(x + (1 - t)*dx,y + (1 - t)*dy,k); - warp(x,y,k) = (unsigned char)((1 - t)*I1 + t*I2); - } else cimg_forXYC(warp,x,y,k) { - const float dx = U(x,y,0), dy = U(x,y,1), I1 = (float)src.linear_atXY(x - t*dx, y - t*dy, 0,k); - warp(x,y,k) = (unsigned char)I1; - } - if (disp) visu.draw_image(2*src.width(),warp).display(disp.resize().wait(30)); - if (filename && *filename && (imode || (int)iteration frame %d ",iteration); - warp.save(filename,iteration); - } - t+=1.0f/nb; - if (t<0) { t = 0; nb = -nb; } - if (t>1) { t = 1; nb = -nb; if (filename && *filename) std::exit(0); } - } -} - -// optflow() : multiscale version of the image registration algorithm -//----------- -CImg<> optflow(const CImg<>& source, const CImg<>& target, - const float smoothness, const float precision, const unsigned int nb_scales, CImgDisplay& disp) { - const unsigned int iteration_max = 100000; - const float _precision = (float)std::pow(10.0,-(double)precision); - const CImg<> - src = source.get_resize(target,3).normalize(0,1), - dest = target.get_normalize(0,1); - CImg<> U; - - const unsigned int _nb_scales = nb_scales>0?nb_scales: - (unsigned int)(2*std::log((double)(cimg::max(src.width(),src.height())))); - for (int scale = _nb_scales - 1; scale>=0; --scale) { - const float factor = (float)std::pow(1.5,(double)scale); - const unsigned int - _sw = (unsigned int)(src.width()/factor), sw = _sw?_sw:1, - _sh = (unsigned int)(src.height()/factor), sh = _sh?_sh:1; - const CImg<> - I1 = src.get_resize(sw,sh,1,-100,2), - I2 = dest.get_resize(I1,2); - std::fprintf(stderr," * Scale %d\n",scale); - if (U) (U*=1.5f).resize(I2.width(),I2.height(),1,-100,3); - else U.assign(I2.width(),I2.height(),1,2,0); - - float dt = 2, energy = cimg::type::max(); - const CImgList<> dI = I2.get_gradient(); - - for (unsigned int iteration = 0; iteration0) dt*=0.5f; - energy = _energy; - if (disp) disp.resize(); - if (disp && disp.is_closed()) std::exit(0); - if (disp && !(iteration%300)) { - const unsigned char white[] = { 255,255,255 }; - CImg tmp = I1.get_warp(U,true,true,1).normalize(0,200); - tmp.resize(disp.width(),disp.height()).draw_quiver(U,white,0.7f,15,-14,true).display(disp); - } - } - std::fprintf(stderr,"\n"); - } - return U; -} - -/*------------------------ - - Main function - - ------------------------*/ - -int main(int argc,char **argv) { - - // Read command line parameters - cimg_usage("Compute an optical flow between two 2D images, and create a warped animation"); - const char - *name_i1 = cimg_option("-i",cimg_imagepath "sh0r.pgm","Input Image 1 (Destination)"), - *name_i2 = cimg_option("-i2",cimg_imagepath "sh1r.pgm","Input Image 2 (Source)"), - *name_o = cimg_option("-o",(const char*)NULL,"Output 2D flow (inrimage)"), - *name_seq = cimg_option("-o2",(const char*)NULL,"Output Warping Sequence"); - const float - smoothness = cimg_option("-s",0.1f,"Flow Smoothness"), - precision = cimg_option("-p",6.0f,"Convergence precision"); - const unsigned int - nb = cimg_option("-n",40,"Number of warped frames"), - nb_scales = cimg_option("-scale",0,"Number of scales (0=auto)"); - const bool - normalize = cimg_option("-equalize",true,"Histogram normalization of the images"), - morph = cimg_option("-m",true,"Morphing mode"), - imode = cimg_option("-c",true,"Complete interpolation (or last frame is missing)"), - dispflag = !cimg_option("-novisu",false,"Visualization"); - - // Init images and display - std::fprintf(stderr," - Init images.\n"); - const CImg<> - src(name_i1), - dest(CImg<>(name_i2).resize(src,3)), - src_blur = normalize?src.get_blur(0.5f).equalize(256):src.get_blur(0.5f), - dest_blur = normalize?dest.get_blur(0.5f).equalize(256):dest.get_blur(0.5f); - - CImgDisplay disp; - if (dispflag) { - unsigned int w = src.width(), h = src.height(); - const unsigned int dmin = cimg::min(w,h), minsiz = 512; - if (dminmaxsiz) { w=w*maxsiz/dmax; h=h*maxsiz/dmax; } - disp.assign(w,h,"Estimated Motion",0); - } - - // Run Motion estimation algorithm - std::fprintf(stderr," - Compute optical flow.\n"); - const CImg<> U = optflow(src_blur,dest_blur,smoothness,precision,nb_scales,disp); - if (name_o) U.save(name_o); - U.print("Computed flow"); - - // Do morphing animation - std::fprintf(stderr," - Create warped animation.\n"); - CImgDisplay disp2; - if (dispflag) { - unsigned int w = src.width(), h = src.height(); - const unsigned int dmin = cimg::min(w,h), minsiz = 100; - if (dminmaxsiz) { w = w*maxsiz/dmax; h=h*maxsiz/dmax; } - disp2.assign(3*w,h,"Source/Destination images and Motion animation",0); - } - - animate_warp(src.get_normalize(0,255),dest.get_normalize(0,255),U,morph,imode,name_seq,nb,disp2); - - std::exit(0); - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/image_surface3d.cpp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/image_surface3d.cpp deleted file mode 100644 index cd7614398e8..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/image_surface3d.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - # - # File : image_surface3d.cpp - # ( C++ source file ) - # - # Description : This tool allows to show an image as a 3D surface. - # This file is a part of the CImg Library project. - # ( http://cimg.eu ) - # - # Copyright : David Tschumperle - # ( http://tschumperle.users.greyc.fr/ ) - # - # License : CeCILL v2.0 - # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) - # - # This software is governed by the CeCILL license under French law and - # abiding by the rules of distribution of free software. You can use, - # modify and/ or redistribute the software under the terms of the CeCILL - # license as circulated by CEA, CNRS and INRIA at the following URL - # "http://www.cecill.info". - # - # As a counterpart to the access to the source code and rights to copy, - # modify and redistribute granted by the license, users are provided only - # with a limited warranty and the software's author, the holder of the - # economic rights, and the successive licensors have only limited - # liability. - # - # In this respect, the user's attention is drawn to the risks associated - # with loading, using, modifying and/or developing or reproducing the - # software by the user in light of its specific status of free software, - # that may mean that it is complicated to manipulate, and that also - # therefore means that it is reserved for developers and experienced - # professionals having in-depth computer knowledge. Users are therefore - # encouraged to load and test the software's suitability as regards their - # requirements in conditions enabling the security of their systems and/or - # data to be ensured and, more generally, to use and operate it in the - # same conditions as regards security. - # - # The fact that you are presently reading this means that you have had - # knowledge of the CeCILL license and that you accept its terms. - # -*/ - -#include "CImg.h" -using namespace cimg_library; -#ifndef cimg_imagepath -#define cimg_imagepath "img/" -#endif - -// Main procedure -//---------------- -int main(int argc,char **argv) { - - // Read command line arguments. - cimg_usage("Render an image as a surface"); - const char *file_i = cimg_option("-i",cimg_imagepath "logo.bmp","Input image"); - const char *file_o = cimg_option("-o",(char*)0,"Output 3D object"); - const float sigma = cimg_option("-smooth",1.0f,"Amount of image smoothing"); - const float ratioz = cimg_option("-z",0.25f,"Aspect ratio along z-axis"); - const unsigned int di = cimg_option("-di",10,"Step for isophote skipping"); - - // Load 2D image file. - std::fprintf(stderr,"\n- Load file '%s'",cimg::basename(file_i)); std::fflush(stderr); - const CImg - img = CImg<>(file_i).blur(sigma).resize(-100,-100,1,3), - norm = img.get_norm().normalize(0,255); - - // Compute surface with triangles. - std::fprintf(stderr,"\n- Create image surface"); std::fflush(stderr); - CImgList primitives; - CImgList colors; - const CImg<> points = img.get_elevation3d(primitives,colors,norm*-ratioz); - - // Compute image isophotes. - std::fprintf(stderr,"\n- Compute image isophotes"); std::fflush(stderr); - CImgList isoprimitives; - CImgList isocolors; - CImg<> isopoints; - for (unsigned int i = 0; i<255; i+=di) { - CImgList<> prims; - const CImg<> pts = norm.get_isoline3d(prims,(float)i); - isopoints.append_object3d(isoprimitives,pts,prims); - } - cimglist_for(isoprimitives,l) { - const unsigned int i0 = isoprimitives(l,0); - const float x0 = isopoints(i0,0), y0 = isopoints(i0,1); - const unsigned char - r = (unsigned char)img.linear_atXY(x0,y0,0), - g = (unsigned char)img.linear_atXY(x0,y0,1), - b = (unsigned char)img.linear_atXY(x0,y0,2); - isocolors.insert(CImg::vector(r,g,b)); - } - cimg_forX(isopoints,ll) isopoints(ll,2) = -ratioz*norm.linear_atXY(isopoints(ll,0),isopoints(ll,1)); - - // Save object if necessary - if (file_o) { - std::fprintf(stderr,"\n- Save 3d object as '%s'",cimg::basename(file_o)); std::fflush(stderr); - points.save_off(primitives,colors,file_o); - } - - // Enter event loop - std::fprintf(stderr, - "\n- Enter interactive loop.\n\n" - "Reminder : \n" - " + Use mouse to rotate and zoom object\n" - " + key 'F' : Toggle fullscreen\n" - " + key 'Q' or 'ESC' : Quit\n" - " + Any other key : Change rendering type\n\n"); std::fflush(stderr); - const char *const title = "Image viewed as a surface"; - CImgDisplay disp(800,600,title,0); - unsigned int rtype = 2; - CImg pose = CImg::identity_matrix(4); - - while (!disp.is_closed()) { - const unsigned char white[3]={ 255, 255, 255 }; - CImg visu(disp.width(),disp.height(),1,3,0); - visu.draw_text(10,10,"%s",white,0,1,24, - rtype==0?"Points":(rtype==1?"Lines":(rtype==2?"Faces":(rtype==3?"Flat-shaded faces": - (rtype==4?"Gouraud-shaded faces":(rtype==5?"Phong-shaded faces":"Isophotes")))))); - static bool first_time = true; - if (rtype==6) visu.display_object3d(disp,isopoints,isoprimitives,isocolors,first_time,1,-1,true, - 500.0f,0.0f,0.0f,-5000.0f,0.0f,0.0f,true,pose.data()); - else visu.display_object3d(disp,points,primitives,colors,first_time,rtype,-1,true, - 500.0f,0.0f,0.0f,-5000.0f,0.0f,0.0f,true,pose.data()); - first_time = false; - switch (disp.key()) { - case 0: break; - case cimg::keyBACKSPACE: rtype = (7 + rtype - 1)%7; break; - case cimg::keyQ: - case cimg::keyESC: disp.close(); break; - case cimg::keyF: - if (disp.is_fullscreen()) disp.resize(800,600); else disp.resize(disp.screen_width(),disp.screen_height()); - disp.toggle_fullscreen(); - break; - default: rtype = (rtype + 1)%7; break; - } - } - - return 0; -} diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/img/CImg_demo.h b/applications/plugins/CImgPlugin/extlibs/CImg/examples/img/CImg_demo.h deleted file mode 100644 index 7ca160c8094..00000000000 --- a/applications/plugins/CImgPlugin/extlibs/CImg/examples/img/CImg_demo.h +++ /dev/null @@ -1,27810 +0,0 @@ -/*------------------------------------------------------------ - - Define hard-coded color images used in the 'CImg_demo.cpp' - example file, so that the corresponding executable does not - depend on additional data files. - ---------------------------------------------------------------*/ - -/* Define image 'foot' of size 200x200x1x3 and type 'const unsigned char' */ -const unsigned char data_foot[] = { - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 154, 68, - 17, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 84, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 230, 165, 84, 26, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 25, 175, 255, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 253, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 215, 116, 26, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 253, 253, 254, 254, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 194, 74, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 205, 133, 68, 22, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 252, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 215, 144, 85, 33, 4, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 177, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 245, 194, 122, 67, 32, 5, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 205, 111, 39, 9, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 255, 255, 255, 255, - 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 205, 58, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 98, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 194, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 28, 116, 215, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 251, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 20, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 12, 50, 111, 177, 230, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, - 48, 105, 170, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 251, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 205, 72, 0, 0, 0, - 0, 0, 27, 66, 122, 194, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, - 242, 0, 0, 0, 0, 0, 108, 120, 171, 233, 253, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 249, 255, 255, 0, - 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 247, 254, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 0, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 252, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, - 219, 219, 219, 219, 0, 0, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 0, 0, 219, 219, 219, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 247, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, - 219, 219, 0, 0, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 0, 219, 219, 219, 219, 219, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, - 219, 0, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 155, 0, 0, 22, 88, 194, 245, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 219, 219, 219, 219, 219, 219, 219, 0, 0, 219, 219, 219, 219, 219, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 155, 0, 0, 0, 0, 0, 0, - 13, 110, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 0, - 0, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 42, 0, 0, 0, 0, 0, 0, 0, 0, 11, 92, 205, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, - 219, 219, 219, 219, 219, 219, 0, 0, 219, 219, 219, 219, 219, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 62, 189, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 0, 0, 219, - 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 156, 238, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, - 219, 219, 219, 219, 0, 0, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 194, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 0, 0, 219, 219, 219, - 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 207, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 27, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, - 219, 219, 0, 0, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 49, 0, 0, 0, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 0, 219, 219, 219, 219, 219, - 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 97, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 235, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, - 219, 0, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 245, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 177, 230, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 155, 32, 0, 10, 47, - 156, 238, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 219, 219, 219, 219, 219, 219, 0, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 235, 110, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 149, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 155, 0, 0, 0, 0, 0, 1, 32, 145, 245, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 0, - 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 245, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 194, 245, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 42, 0, 0, 0, 0, 0, - 0, 0, 2, 76, 226, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 219, 219, 219, 219, 219, 219, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 115, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 81, 165, 230, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 226, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 198, 152, 119, 119, 152, 198, 0, 0, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 92, 205, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 91, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 198, 121, - 33, 5, 4, 24, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 159, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6, 11, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 205, 255, - 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, - 255, 255, 155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 164, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 152, 33, 0, 0, 0, 0, 0, 110, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 181, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 7, - 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 145, 19, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 25, 194, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 119, 3, - 0, 0, 0, 0, 0, 16, 178, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 238, 147, 22, 0, 0, 0, 0, 0, 0, 0, 0, 58, - 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 219, 219, 119, 1, 0, 0, 0, 0, 0, 0, 70, 198, - 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 215, 39, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 215, 0, - 0, 0, 0, 0, 0, 0, 0, 2, 114, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 152, 2, - 0, 0, 0, 0, 0, 0, 5, 137, 219, 219, 219, 219, 219, 219, 219, 219, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 207, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 205, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 215, 0, 0, 0, 0, 0, 0, 0, 0, - 11, 185, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 219, 219, 219, 219, 198, 22, 0, 0, 0, 0, 0, 0, 0, 88, - 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 207, 68, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 133, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 115, 0, 0, 0, 0, 0, 0, 0, 0, 37, 230, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 217, 0, - 0, 0, 0, 0, 0, 0, 0, 27, 219, 219, 219, 219, 219, 219, 219, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 207, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 74, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 245, 76, 0, 0, 0, 0, 0, 0, - 0, 0, 74, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 219, 219, 219, 219, 219, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, - 176, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 230, 79, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 38, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 221, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 103, 219, 219, 219, 219, 219, 219, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, - 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 185, 0, 0, 0, 0, 0, - 0, 0, 0, 5, 165, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, - 219, 219, 219, 210, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 35, 210, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 245, 124, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 4, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 205, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 210, 120, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 173, 219, 219, 219, 219, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 164, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 72, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, - 219, 219, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 115, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 245, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 212, 0, 0, 0, 0, 0, 0, 0, 0, 4, 205, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 219, 219, 219, 219, 219, 159, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 219, 219, 219, 219, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 159, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 194, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 54, 245, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, - 188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 176, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 170, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 122, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 1, 100, - 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 219, 219, 219, 219, 219, 112, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 219, 219, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 194, 23, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 75, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 0, 0, 0, 0, 0, 0, 0, 6, 150, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 198, 152, 119, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 32, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 215, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 40, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 219, 219, 167, 62, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 198, 219, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 160, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 24, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 2, 186, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 137, 19, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 110, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 235, 0, 0, 0, 0, 0, 0, 0, - 0, 57, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 219, 219, 146, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 198, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 179, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 219, 178, 27, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 98, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, - 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, - 0, 0, 70, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, - 178, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 185, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 215, 0, 0, 0, 0, 0, 0, 0, 5, 235, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 219, 178, 58, 3, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 37, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, - 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 194, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, - 0, 0, 0, 213, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 159, 32, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, - 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 185, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 122, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 215, 0, 0, 0, 0, 0, 0, 0, 205, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 164, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 28, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 8, 0, 0, 0, - 0, 0, 4, 213, 255, 255, 255, 255, 255, 255, 255, 255, 238, 51, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, - 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 58, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 106, 0, 0, 0, 0, 0, 76, 235, 255, 255, 255, 255, - 255, 255, 255, 255, 120, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 182, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 106, 0, 0, - 6, 81, 235, 255, 255, 255, 255, 255, 255, 255, 255, 205, 10, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 45, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 29, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 194, 6, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 83, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, - 255, 230, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 122, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 207, 29, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 1, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 53, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 255, 255, 255, 255, 255, 255, 255, 160, 13, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 194, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 161, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 57, 22, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 52, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, - 255, 88, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 37, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 245, 86, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 255, 255, 255, 255, 255, 255, 31, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 229, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 53, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, - 205, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 15, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 215, 27, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 255, 255, 255, 125, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 163, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 57, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, - 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 17, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 101, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 55, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 255, 255, 255, 8, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 219, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 221, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, - 0, 0, 53, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 41, 198, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 86, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 28, 0, 0, 0, 0, 0, 0, 52, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 219, 219, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, - 255, 255, 255, 255, 255, 255, 255, 83, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 34, 0, 0, 0, 0, - 0, 0, 41, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 210, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255, 255, 255, 255, 245, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 37, 4, 0, 0, 0, 0, 0, 0, 23, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 151, 219, 219, 219, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 250, 253, 255, 255, 255, 255, 255, 221, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 6, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 36, 204, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 240, 255, 255, 255, 255, 255, - 255, 204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, 157, 219, 219, 219, 219, 219, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 250, 247, 255, 255, 255, 255, 255, 255, 196, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 48, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, - 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, - 255, 255, 255, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 140, 219, 219, 219, 219, 219, 219, 219, 219, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 198, - 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 24, 84, 170, 230, 0, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 100, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 0, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 37, 111, 205, 255, 255, - 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 185, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 207, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 21, - 84, 165, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 64, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 11, 39, 53, 72, 125, 205, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 167, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 23, 87, 170, 230, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 210, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 12, 50, 111, 177, 230, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 185, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 48, 105, - 170, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 128, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 28, - 49, 72, 111, 177, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 198, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, - 0, 0, 30, 74, 144, 215, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 79, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 176, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 46, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 131, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 210, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, - 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 1, 0, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 255, 255, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, - 198, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 205, 98, 20, 0, 98, 205, - 0, 0, 0, 0, 0, 0, 9, 1, 1, 1, 1, 1, 1, 0, 0, 2, - 2, 0, 0, 0, 0, 0, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 176, 39, 0, 0, 0, 0, 77, 0, 0, 0, 0, 0, 0, 9, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 238, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 185, 26, 0, 0, 0, 0, 0, 15, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 90, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 238, 216, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 238, 111, - 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 247, 251, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 215, 62, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 198, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 128, 18, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 230, 128, 23, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 15, 79, 176, 219, 0, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, - 255, 255, 255, 255, 255, 255, 255, 245, 141, 24, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 181, 47, 5, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 4, 23, 40, 57, 90, 146, 198, 219, 219, 219, 0, - 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 230, 137, 30, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 215, 124, 79, 54, 47, 51, 62, 95, 152, 198, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 255, 238, 125, 18, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 201, 30, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 20, 31, 0, 0, 0, 0, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 230, 105, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 24, 198, 24, 0, 0, 0, 0, 0, 0, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 164, - 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 95, 3, 0, 0, 0, 0, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 51, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 194, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 251, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 212, 4, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 0, 0, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 213, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 255, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 6, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 227, 16, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 8, 255, 255, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, - 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 37, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 84, 255, 255, 255, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 184, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 144, - 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 238, 64, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 6, 215, 255, 255, 255, 255, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 40, 255, - 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 0, 0, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 86, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 105, 255, 255, 255, 255, 255, 255, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 205, 133, 85, - 61, 63, 92, 144, 215, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 1, 170, 255, - 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 185, 124, 73, 28, 4, 0, 0, 0, 0, 1, 6, 5, 9, 0, 142, - 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 110, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 10, 230, 255, 255, 255, 255, 255, 255, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 217, 200, 155, 100, 54, 24, 3, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 34, 170, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 198, 20, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 255, 255, - 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 176, 114, 60, 22, 3, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 18, 170, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 219, 219, 219, 219, 110, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 133, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 210, 167, 105, 58, 25, 3, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 185, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 198, 20, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 205, 255, 255, - 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 198, - 113, 27, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 36, 205, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, - 219, 219, 219, 219, 219, 117, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 58, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 0, 0, 219, 219, 219, 219, 219, 219, 219, 210, 182, 148, - 125, 106, 79, 53, 33, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 210, 32, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 163, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, 219, - 219, 192, 114, 40, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 165, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 167, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 26, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 198, 142, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 164, 219, - 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 64, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 159, 43, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 31, 185, 219, 219, 219, 219, 219, 219, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 185, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 7, 215, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 176, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, - 198, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 106, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 114, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3, 98, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 210, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 194, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 159, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 173, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 245, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 52, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 178, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3, 137, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 58, 198, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 78, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 58, 230, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 50, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 88, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, - 194, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6, 155, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 8, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 120, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 105, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 185, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 230, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 51, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 124, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 116, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 210, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 198, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 215, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 67, 198, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 56, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 6, 154, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 25, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, - 83, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 238, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 10, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 84, 198, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 18, 215, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 176, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 74, 190, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 128, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 82, 202, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 0, 0, 0, 0, 219, 113, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 69, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 252, - 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 73, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 5, 109, 210, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, 0, 0, 219, 219, 219, - 219, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 215, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 139, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, - 0, 0, 219, 219, 219, 219, 219, 219, 219, 148, 35, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 25, 200, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 185, 7, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12, 146, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 0, 0, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 182, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3, 151, 253, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 137, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 0, 0, 0, 0, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 210, 125, 19, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, - 243, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 167, 3, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 14, 155, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, 0, 0, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 188, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 54, 229, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 210, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 10, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 22, 185, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 0, 0, 0, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 171, 37, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 215, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 141, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 9, 40, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 0, 0, 0, 0, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 214, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 18, 194, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 200, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 66, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, 0, 0, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 28, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 159, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 250, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 217, 37, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 5, 6, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 219, 219, 219, 219, 219, 0, - 0, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 12, 170, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 110, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 219, 0, 0, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 137, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 145, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 248, 255, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 185, - 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 198, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 8, 113, 217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 64, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3, 122, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 110, 1, - 0, 0, 0, 0, 0, 0, 0, 3, 113, 209, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 167, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 67, 198, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 198, 37, 0, 0, 0, 0, 0, 0, 3, 94, - 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 210, 27, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, - 198, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 159, - 39, 0, 0, 0, 1, 15, 106, 210, 219, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 6, 113, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 176, 107, 69, 66, 100, 167, 210, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 168, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 149, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 249, 255, 255, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 204, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 47, 176, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 58, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 113, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 252, - 247, 255, 219, 219, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 219, 219, - 219, 219, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 25, 149, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 47, 176, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 253, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 252, 255, 255, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 133, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 142, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 254, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 107, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 176, 114, 47, - 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 78, 198, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 251, 255, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 198, 142, 56, 8, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 198, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 206, 126, 29, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 65, 210, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 255, 255, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 158, 46, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3, 70, 190, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 204, 140, 52, 7, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 75, - 190, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 255, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 198, 110, 24, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3, 65, 190, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 198, 142, 72, 22, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 70, 185, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 252, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 198, 122, 46, 5, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3, 90, 204, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 204, 168, 124, 80, 43, 17, 4, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 98, 210, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 210, 167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 19, 130, 210, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 185, - 0, 0, 0, 0, 0, 0, 0, 3, 50, 167, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 204, 140, 58, 0, 0, 0, 42, 122, - 198, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 251, - 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, - 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 254, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 252, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, 0, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 0, 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, - 0, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 84, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 25, 175, 255, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 1, 1, 2, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 177, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 255, 255, 255, 255, - 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 6, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 194, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 28, 116, 215, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 9, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 12, 50, 111, 177, 230, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, - 48, 105, 170, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 255, 205, 72, 0, 0, 0, - 0, 0, 27, 66, 122, 194, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, - 6, 0, 0, 0, 0, 0, 108, 120, 171, 233, 253, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 12, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 255, 255, 0, - 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 13, 4, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 0, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 4, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, - 210, 210, 210, 210, 0, 0, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, - 210, 210, 0, 0, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 0, 210, 210, 210, 210, 210, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 0, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 155, 0, 0, 22, 88, 194, 245, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 155, 0, 0, 0, 0, 0, 0, - 13, 110, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 0, - 0, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 42, 0, 0, 0, 0, 0, 0, 0, 0, 11, 92, 205, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, - 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 62, 189, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, - 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 156, 238, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, - 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 194, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, - 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 207, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 27, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, - 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 49, 0, 0, 0, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 0, 210, 210, 210, 210, 210, - 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 97, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 235, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 0, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 245, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 177, 230, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 155, 32, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 210, 210, 210, 210, 210, 210, 0, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 235, 110, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 149, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 0, - 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 245, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 194, 245, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 42, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 115, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 81, 165, 230, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 189, 146, 114, 114, 146, 189, 0, 0, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 92, 205, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, 116, - 32, 5, 4, 23, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 159, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6, 11, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 205, 255, - 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, - 255, 255, 155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 146, 32, 0, 0, 0, 0, 0, 105, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 181, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 7, - 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 145, 19, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 114, 3, - 0, 0, 0, 0, 0, 16, 170, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 238, 147, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 210, 210, 114, 1, 0, 0, 0, 0, 0, 0, 67, 189, - 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 215, 39, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 215, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 146, 2, - 0, 0, 0, 0, 0, 0, 5, 132, 210, 210, 210, 210, 210, 210, 210, 210, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 207, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 205, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 215, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 210, 210, 210, 210, 189, 21, 0, 0, 0, 0, 0, 0, 0, 88, - 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 207, 68, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 133, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 208, 0, - 0, 0, 0, 0, 0, 0, 0, 26, 210, 210, 210, 210, 210, 210, 210, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 207, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 74, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 245, 76, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, - 169, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 230, 79, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 38, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 221, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 99, 210, 210, 210, 210, 210, 210, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, - 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 185, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, - 210, 210, 210, 202, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 34, 202, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 245, 124, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 4, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 202, 115, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 166, 210, 210, 210, 210, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 164, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, - 210, 210, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 110, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 245, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 210, 210, 210, 210, 210, 152, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 210, 210, 210, 210, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 159, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 194, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, - 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 169, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 170, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 122, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 210, 210, 210, 210, 210, 107, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 210, 210, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 194, 23, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 75, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 189, 146, 114, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 30, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 215, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 210, 210, 160, 59, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 189, 210, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 160, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 24, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 131, 18, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 105, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 235, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 210, 210, 140, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 189, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 210, 170, 26, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 94, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, - 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, - 170, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 185, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 215, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 210, 170, 56, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 37, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, - 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 194, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 152, 30, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, - 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 185, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 122, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 215, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 157, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 28, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 8, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, - 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 58, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 182, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 106, 0, 0, - 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 45, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 29, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 83, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 122, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 207, 29, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 1, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 53, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 194, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 161, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 57, 22, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 52, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 37, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 245, 86, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 229, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 53, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 15, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 215, 27, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 163, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 57, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 16, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 101, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 55, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, 210, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 221, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, - 0, 0, 53, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 40, 189, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 86, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 28, 0, 0, 0, 0, 0, 0, 52, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 210, 210, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, - 255, 255, 255, 255, 255, 255, 255, 83, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 34, 0, 0, 0, 0, - 0, 0, 41, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 202, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255, 255, 255, 255, 245, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 37, 4, 0, 0, 0, 0, 0, 0, 23, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 145, 210, 210, 210, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 250, 253, 255, 255, 255, 255, 255, 221, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 6, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 35, 196, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 240, 255, 255, 255, 255, 255, - 255, 204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, 151, 210, 210, 210, 210, 210, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 250, 247, 255, 255, 255, 255, 255, 255, 196, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 48, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, - 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, - 255, 255, 255, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 134, 210, 210, 210, 210, 210, 210, 210, 210, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 189, - 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 24, 84, 170, 230, 0, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 0, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 37, 111, 205, 255, 255, - 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 177, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 207, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 21, - 84, 165, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 61, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 11, 39, 53, 72, 125, 205, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 23, 87, 170, 230, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 8, 202, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 12, 50, 111, 177, 230, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 185, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 48, 105, - 170, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 123, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 28, - 49, 72, 111, 177, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 189, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, - 0, 0, 30, 74, 144, 215, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 76, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 169, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 44, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 125, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 202, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, - 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 1, 0, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 255, 255, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, - 189, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 205, 98, 20, 0, 98, 205, - 0, 0, 0, 0, 0, 0, 9, 1, 1, 1, 1, 1, 1, 0, 0, 2, - 2, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 176, 39, 0, 0, 0, 0, 77, 0, 0, 0, 0, 0, 0, 9, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 238, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 185, 26, 0, 0, 0, 0, 0, 15, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 86, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 238, 216, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 238, 111, - 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 247, 251, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 215, 62, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 189, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 128, 18, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 230, 128, 23, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 14, 76, 169, 210, 0, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, - 255, 255, 255, 255, 255, 255, 255, 245, 141, 24, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 181, 47, 5, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 4, 22, 39, 54, 86, 140, 189, 210, 210, 210, 0, - 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 230, 137, 30, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 215, 119, 76, 52, 45, 49, 59, 91, 146, 189, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 255, 238, 125, 18, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 201, 30, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 19, 30, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 230, 105, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 23, 189, 23, 0, 0, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 164, - 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 91, 3, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 51, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 194, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 251, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 212, 4, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 213, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 6, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 227, 16, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 37, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 184, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 238, 64, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 86, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 205, 133, 85, - 61, 63, 92, 144, 215, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 177, 119, 70, 27, 4, 0, 0, 0, 0, 1, 6, 5, 9, 0, 142, - 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 105, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 208, 192, 148, 96, 52, 23, 3, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 34, 170, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 210, 210, 210, 189, 19, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 169, 110, 58, 21, 2, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 18, 170, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 210, 210, 210, 210, 105, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 202, 160, 100, 55, 24, 3, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 185, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 210, 210, 210, 210, 210, 189, 19, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 189, - 108, 26, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 36, 205, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 210, 210, 210, - 210, 210, 210, 210, 210, 112, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 202, 175, 142, - 119, 101, 76, 51, 32, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 202, 30, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, - 210, 184, 110, 38, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 165, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 189, 136, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 157, 210, - 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 61, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 152, 41, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 30, 177, 210, 210, 210, 210, 210, 210, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 177, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 169, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, - 189, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 102, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 110, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, 94, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 202, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 152, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 166, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 50, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 170, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 189, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 75, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 48, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 84, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6, 149, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 7, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 100, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 177, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 49, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 119, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 202, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 189, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 64, 189, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 54, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 24, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, - 80, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 10, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 81, 189, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 169, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 71, 182, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 78, 194, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 0, 0, 0, 0, 210, 108, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, - 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 70, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 5, 105, 202, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 210, 210, 210, - 210, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 133, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, - 0, 0, 210, 210, 210, 210, 210, 210, 210, 142, 34, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 177, 7, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12, 140, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 175, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 131, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 202, 119, 18, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 160, 2, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 13, 149, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 180, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 202, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 21, 177, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 164, 35, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 255, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 135, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 9, 39, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 205, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 192, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 63, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 27, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 49, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 208, 35, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 5, 6, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 0, - 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 105, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 210, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 132, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 139, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 11, 255, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 177, - 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 189, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7, 109, 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 61, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 117, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 105, 1, - 0, 0, 0, 0, 0, 0, 0, 3, 109, 200, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 64, 189, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 189, 35, 0, 0, 0, 0, 0, 0, 2, 90, - 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 202, 26, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, - 189, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 152, - 37, 0, 0, 0, 1, 15, 102, 202, 210, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 255, 255, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 6, 108, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 169, 103, 66, 63, 96, 160, 202, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 255, 255, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 161, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 142, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 255, 255, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 196, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 45, 169, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 55, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 108, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 153, 255, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, - 210, 210, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 24, 142, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 45, 169, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 255, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 255, 255, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 128, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 136, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 187, 255, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 103, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 169, 110, 45, - 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 75, 189, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 154, 255, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 189, 136, 54, 7, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 189, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 255, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 198, 121, 28, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 63, 202, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 255, 255, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 152, 44, - 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3, 67, 182, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 255, 255, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 196, 134, 50, 7, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 72, - 182, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 255, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 189, 105, 23, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 63, 182, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 189, 136, 69, 21, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 68, 177, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 11, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 189, 117, 44, 5, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2, 86, 196, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 196, 161, 119, 77, 41, 16, 4, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 94, 202, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 202, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 18, 124, 202, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 177, - 0, 0, 0, 0, 0, 0, 0, 3, 48, 160, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 196, 134, 55, 0, 0, 0, 40, 117, - 189, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 9, - 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, - 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, - 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 84, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 25, 175, 255, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 8, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 1, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 177, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 255, 255, 255, 255, - 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 194, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 28, 116, 215, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 8, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 12, 50, 111, 177, 230, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, - 48, 105, 170, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 255, 205, 72, 0, 0, 0, - 0, 0, 27, 66, 122, 194, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, - 5, 0, 0, 0, 0, 0, 108, 120, 171, 233, 253, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 10, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 255, 255, 0, - 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 10, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 0, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 3, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, - 210, 210, 210, 210, 0, 0, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, - 210, 210, 0, 0, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 0, 210, 210, 210, 210, 210, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 0, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 155, 0, 0, 22, 88, 194, 245, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 155, 0, 0, 0, 0, 0, 0, - 13, 110, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 0, - 0, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 42, 0, 0, 0, 0, 0, 0, 0, 0, 11, 92, 205, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, - 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 62, 189, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, - 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 156, 238, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, - 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 194, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, - 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 207, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 27, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, - 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 49, 0, 0, 0, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 3, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 0, 210, 210, 210, 210, 210, - 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 97, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 235, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 0, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 245, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 177, 230, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 155, 32, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 210, 210, 210, 210, 210, 210, 0, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 235, 110, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 149, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 0, - 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 245, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 194, 245, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 42, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 115, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 81, 165, 230, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 189, 146, 114, 114, 146, 189, 0, 0, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 92, 205, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, 116, - 32, 5, 4, 23, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 159, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6, 11, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 205, 255, - 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, - 255, 255, 155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 146, 32, 0, 0, 0, 0, 0, 105, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 181, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 7, - 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 145, 19, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 114, 3, - 0, 0, 0, 0, 0, 16, 170, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 238, 147, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 210, 210, 114, 1, 0, 0, 0, 0, 0, 0, 67, 189, - 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 215, 39, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 215, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 146, 2, - 0, 0, 0, 0, 0, 0, 5, 132, 210, 210, 210, 210, 210, 210, 210, 210, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 207, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 205, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 215, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 210, 210, 210, 210, 189, 21, 0, 0, 0, 0, 0, 0, 0, 88, - 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 207, 68, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 133, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 208, 0, - 0, 0, 0, 0, 0, 0, 0, 26, 210, 210, 210, 210, 210, 210, 210, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 207, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 74, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 245, 76, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, - 169, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 230, 79, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 38, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 221, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 99, 210, 210, 210, 210, 210, 210, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, - 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 185, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, - 210, 210, 210, 202, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 34, 202, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 245, 124, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 4, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 202, 115, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 166, 210, 210, 210, 210, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 164, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, - 210, 210, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 110, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 245, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 210, 210, 210, 210, 210, 152, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 210, 210, 210, 210, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 159, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 194, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, - 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 169, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 170, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 122, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 210, 210, 210, 210, 210, 107, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 210, 210, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 194, 23, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 75, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 189, 146, 114, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 30, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 215, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 210, 210, 160, 59, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 189, 210, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 160, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 24, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 131, 18, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 105, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 235, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 210, 210, 140, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 189, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 210, 170, 26, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 94, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, - 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, - 170, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 185, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 215, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 210, 170, 56, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 37, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, - 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 194, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 152, 30, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, - 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 185, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 122, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 215, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 157, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 28, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 8, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, - 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 58, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 182, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 106, 0, 0, - 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 45, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 29, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 83, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 122, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 207, 29, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 1, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 53, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 194, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 161, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 57, 22, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 52, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 37, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 245, 86, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 229, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 53, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 15, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 215, 27, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 163, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 57, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 16, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 101, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 55, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, 210, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 221, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, - 0, 0, 53, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 40, 189, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 86, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 28, 0, 0, 0, 0, 0, 0, 52, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 210, 210, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, - 255, 255, 255, 255, 255, 255, 255, 83, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 34, 0, 0, 0, 0, - 0, 0, 41, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 202, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255, 255, 255, 255, 245, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 37, 4, 0, 0, 0, 0, 0, 0, 23, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 145, 210, 210, 210, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 250, 253, 255, 255, 255, 255, 255, 221, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 6, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 35, 196, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 240, 255, 255, 255, 255, 255, - 255, 204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, 151, 210, 210, 210, 210, 210, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 250, 247, 255, 255, 255, 255, 255, 255, 196, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 48, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, - 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, - 255, 255, 255, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 134, 210, 210, 210, 210, 210, 210, 210, 210, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 189, - 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 24, 84, 170, 230, 0, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 0, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 37, 111, 205, 255, 255, - 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 177, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 207, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 21, - 84, 165, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 61, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 11, 39, 53, 72, 125, 205, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 23, 87, 170, 230, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 8, 202, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 12, 50, 111, 177, 230, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 185, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 48, 105, - 170, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 123, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 28, - 49, 72, 111, 177, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 189, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, - 0, 0, 30, 74, 144, 215, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 76, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 169, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 44, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 125, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 202, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, - 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 1, 0, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 255, 255, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, - 189, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 205, 98, 20, 0, 98, 205, - 0, 0, 0, 0, 0, 0, 9, 1, 1, 1, 1, 1, 1, 0, 0, 2, - 2, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 176, 39, 0, 0, 0, 0, 77, 0, 0, 0, 0, 0, 0, 9, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 238, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 185, 26, 0, 0, 0, 0, 0, 15, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 86, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 238, 216, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 238, 111, - 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 247, 251, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 215, 62, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 189, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 128, 18, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 230, 128, 23, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 14, 76, 169, 210, 0, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, - 255, 255, 255, 255, 255, 255, 255, 245, 141, 24, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 181, 47, 5, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 4, 22, 39, 54, 86, 140, 189, 210, 210, 210, 0, - 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 230, 137, 30, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 215, 119, 76, 52, 45, 49, 59, 91, 146, 189, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 255, 238, 125, 18, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 201, 30, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 19, 30, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 230, 105, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 23, 189, 23, 0, 0, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 164, - 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 91, 3, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 51, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 194, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 251, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 212, 4, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 213, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 6, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 227, 16, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 37, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 184, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 238, 64, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 86, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 255, 205, 133, 85, - 61, 63, 92, 144, 215, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 177, 119, 70, 27, 4, 0, 0, 0, 0, 1, 6, 5, 9, 0, 142, - 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 105, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 208, 192, 148, 96, 52, 23, 3, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 34, 170, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 210, 210, 210, 189, 19, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 169, 110, 58, 21, 2, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 18, 170, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 210, 210, 210, 210, 105, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 202, 160, 100, 55, 24, 3, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 185, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 210, 210, 210, 210, 210, 189, 19, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 189, - 108, 26, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 36, 205, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 210, 210, 210, - 210, 210, 210, 210, 210, 112, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 202, 175, 142, - 119, 101, 76, 51, 32, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 202, 30, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, - 210, 184, 110, 38, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 165, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 189, 136, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 157, 210, - 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 61, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 152, 41, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 30, 177, 210, 210, 210, 210, 210, 210, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 177, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 169, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, - 189, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 102, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 110, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, 94, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 202, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 152, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 166, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 50, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 170, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 189, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 75, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 48, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 84, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6, 149, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 7, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 100, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 177, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 49, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 119, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 202, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 189, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 64, 189, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 54, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 24, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, - 80, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 10, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 81, 189, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 169, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 71, 182, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 78, 194, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 0, 0, 0, 0, 210, 108, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, - 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 70, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 5, 105, 202, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 210, 210, 210, - 210, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 133, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, - 0, 0, 210, 210, 210, 210, 210, 210, 210, 142, 34, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 177, 7, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12, 140, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 175, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 131, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 202, 119, 18, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 160, 2, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 13, 149, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 180, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 202, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 21, 177, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 164, 35, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 255, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 135, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 9, 39, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 205, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 192, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 63, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 27, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 45, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 208, 35, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 5, 6, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 0, - 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 105, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 210, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 132, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 139, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 255, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 177, - 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 189, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7, 109, 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 61, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 117, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 105, 1, - 0, 0, 0, 0, 0, 0, 0, 3, 109, 200, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 64, 189, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 189, 35, 0, 0, 0, 0, 0, 0, 2, 90, - 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 202, 26, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, - 189, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 152, - 37, 0, 0, 0, 1, 15, 102, 202, 210, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 255, 255, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 6, 108, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 169, 103, 66, 63, 96, 160, 202, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 255, 255, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 161, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 142, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 255, 255, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 196, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 45, 169, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 55, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 108, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, - 152, 255, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, - 210, 210, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 24, 142, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 45, 169, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 7, 255, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 255, 255, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 128, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 136, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 186, 255, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 103, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 169, 110, 45, - 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 75, 189, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 152, 255, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 189, 136, 54, 7, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 189, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 255, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 198, 121, 28, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 63, 202, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 255, 255, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 152, 44, - 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3, 67, 182, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 255, 255, 255, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 196, 134, 50, 7, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 72, - 182, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 255, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 189, 105, 23, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 63, 182, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 189, 136, 69, 21, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 68, 177, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 189, 117, 44, 5, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2, 86, 196, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 196, 161, 119, 77, 41, 16, 4, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 94, 202, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 202, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 18, 124, 202, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 177, - 0, 0, 0, 0, 0, 0, 0, 3, 48, 160, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 196, 134, 55, 0, 0, 0, 40, 117, - 189, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 8, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, - 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 255, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, - 0, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -/* Define image 'milla' of size 211x242x1x3 and type 'const unsigned char' */ -const unsigned char data_milla[] = { - 93, 92, 92, 91, 91, 90, 90, 90, 92, 90, 92, 91, 91, 92, 92, 92, - 93, 99, 97, 95, 101, 95, 89, 93, 92, 92, 94, 96, 97, 95, 95, 94, - 96, 96, 96, 96, 96, 96, 96, 96, 93, 94, 95, 96, 97, 98, 98, 98, - 94, 98, 98, 95, 96, 99, 99, 97, 99, 98, 98, 97, 97, 98, 98, 100, - 103, 103, 103, 102, 102, 103, 102, 102, 100, 101, 102, 101, 101, 101, 101, 100, - 102, 103, 103, 104, 103, 104, 104, 104, 104, 102, 104, 103, 103, 104, 104, 104, - 103, 103, 105, 104, 106, 105, 107, 105, 110, 107, 108, 105, 108, 107, 111, 110, - 108, 111, 108, 104, 112, 109, 108, 112, 112, 111, 115, 113, 113, 111, 115, 114, - 109, 108, 109, 110, 110, 110, 110, 109, 104, 111, 109, 105, 111, 108, 106, 112, - 107, 105, 104, 103, 104, 106, 109, 110, 110, 112, 108, 116, 112, 106, 108, 84, - 14, 31, 62, 66, 85, 85, 103, 106, 107, 109, 103, 105, 116, 114, 105, 109, - 112, 110, 110, 113, 113, 111, 112, 115, 116, 115, 113, 113, 115, 115, 113, 112, - 111, 112, 112, 112, 112, 111, 110, 109, 113, 113, 113, 112, 112, 111, 111, 111, - 114, 113, 113, 94, 94, 94, 93, 92, 91, 91, 91, 85, 85, 88, 88, 89, - 90, 88, 89, 93, 94, 94, 93, 92, 93, 95, 97, 93, 94, 96, 94, 93, - 92, 94, 94, 95, 95, 96, 95, 94, 92, 89, 88, 93, 93, 93, 93, 93, - 94, 96, 96, 96, 96, 96, 97, 97, 98, 98, 98, 100, 99, 99, 98, 98, - 99, 99, 100, 98, 100, 102, 100, 99, 98, 98, 99, 100, 103, 104, 100, 100, - 103, 102, 99, 101, 101, 101, 102, 102, 103, 103, 103, 105, 104, 105, 105, 105, - 106, 106, 106, 102, 105, 106, 102, 104, 106, 107, 104, 104, 103, 104, 104, 105, - 105, 106, 105, 105, 106, 109, 108, 108, 106, 108, 108, 106, 109, 110, 106, 108, - 110, 111, 108, 112, 110, 106, 107, 111, 112, 109, 107, 110, 109, 107, 105, 106, - 106, 109, 110, 106, 109, 109, 106, 106, 109, 109, 106, 114, 109, 111, 110, 116, - 99, 108, 78, 9, 30, 59, 64, 90, 88, 99, 105, 107, 111, 104, 104, 114, - 112, 104, 104, 109, 107, 107, 110, 111, 108, 108, 112, 113, 113, 113, 113, 113, - 113, 113, 113, 110, 112, 114, 114, 112, 111, 111, 112, 114, 114, 112, 111, 111, - 111, 111, 111, 109, 116, 113, 93, 94, 92, 92, 91, 90, 90, 88, 89, 88, - 89, 90, 89, 89, 89, 91, 92, 94, 94, 93, 92, 93, 94, 97, 91, 92, - 92, 92, 90, 90, 91, 92, 93, 93, 94, 94, 94, 93, 92, 92, 96, 95, - 94, 93, 93, 93, 94, 94, 96, 96, 96, 97, 97, 98, 98, 98, 100, 99, - 99, 98, 98, 99, 99, 100, 98, 99, 101, 101, 100, 98, 99, 100, 100, 104, - 104, 101, 101, 104, 103, 99, 101, 101, 102, 102, 102, 103, 103, 103, 105, 105, - 105, 106, 106, 107, 107, 106, 102, 105, 105, 102, 103, 106, 106, 104, 103, 103, - 104, 104, 104, 105, 105, 105, 104, 107, 109, 109, 108, 107, 108, 109, 106, 109, - 109, 106, 107, 110, 111, 108, 111, 110, 107, 108, 110, 111, 109, 108, 109, 109, - 107, 106, 106, 107, 108, 108, 108, 111, 111, 108, 108, 111, 111, 108, 113, 109, - 111, 109, 116, 100, 109, 78, 9, 30, 58, 62, 90, 88, 99, 105, 107, 109, - 103, 103, 114, 113, 104, 107, 110, 108, 108, 112, 112, 109, 110, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 110, 112, 114, 114, 112, 111, 111, 112, 114, 113, - 112, 111, 111, 111, 111, 112, 109, 116, 113, 92, 91, 91, 91, 90, 89, 87, - 87, 91, 91, 89, 89, 87, 89, 91, 92, 92, 94, 94, 94, 93, 93, 94, - 96, 91, 93, 92, 92, 91, 90, 91, 92, 92, 92, 92, 92, 93, 93, 94, - 95, 97, 96, 95, 94, 93, 93, 93, 93, 96, 96, 96, 97, 97, 98, 98, - 98, 100, 99, 99, 98, 98, 99, 99, 100, 98, 100, 102, 102, 100, 99, 100, - 101, 101, 104, 105, 102, 101, 103, 102, 98, 101, 102, 102, 102, 103, 103, 103, - 103, 105, 105, 105, 106, 106, 107, 107, 106, 102, 105, 105, 102, 103, 106, 106, - 104, 103, 104, 104, 104, 105, 105, 105, 105, 105, 108, 110, 110, 109, 108, 109, - 110, 106, 109, 109, 107, 107, 110, 111, 108, 109, 110, 110, 109, 109, 108, 109, - 110, 109, 109, 107, 107, 107, 107, 108, 108, 109, 112, 112, 109, 109, 112, 112, - 109, 111, 108, 110, 108, 116, 102, 110, 77, 10, 30, 59, 63, 90, 88, 99, - 105, 105, 108, 102, 102, 115, 114, 106, 108, 111, 109, 109, 113, 113, 110, 111, - 114, 113, 113, 113, 113, 113, 113, 113, 113, 110, 112, 114, 114, 112, 111, 111, - 112, 114, 113, 112, 111, 111, 111, 112, 112, 109, 116, 113, 92, 92, 91, 91, - 90, 90, 88, 88, 91, 90, 87, 86, 84, 86, 89, 91, 92, 94, 95, 94, - 93, 93, 94, 96, 94, 95, 95, 94, 93, 93, 94, 95, 94, 93, 92, 91, - 91, 93, 95, 96, 96, 96, 95, 94, 94, 94, 95, 95, 96, 96, 96, 97, - 97, 98, 98, 98, 100, 99, 99, 98, 98, 99, 99, 100, 99, 101, 103, 103, - 101, 100, 101, 102, 102, 105, 105, 102, 101, 103, 102, 98, 102, 102, 102, 103, - 103, 103, 104, 104, 105, 105, 105, 106, 106, 107, 107, 106, 102, 105, 105, 102, - 103, 106, 106, 104, 104, 104, 104, 105, 105, 105, 106, 106, 106, 108, 110, 111, - 109, 109, 109, 111, 106, 109, 110, 107, 107, 111, 111, 108, 108, 111, 111, 110, - 108, 107, 108, 111, 109, 109, 108, 107, 107, 108, 108, 108, 108, 111, 111, 108, - 108, 111, 111, 108, 110, 108, 109, 107, 116, 103, 111, 75, 11, 31, 60, 63, - 90, 88, 99, 105, 106, 109, 103, 102, 114, 113, 105, 107, 110, 108, 109, 112, - 112, 110, 110, 113, 114, 114, 113, 113, 113, 113, 112, 112, 110, 112, 114, 114, - 112, 111, 111, 112, 113, 113, 112, 111, 111, 111, 112, 113, 109, 116, 113, 92, - 92, 92, 92, 92, 92, 90, 90, 92, 91, 88, 86, 87, 88, 89, 90, 91, - 93, 95, 95, 94, 93, 93, 95, 94, 96, 95, 95, 94, 94, 94, 96, 96, - 95, 93, 91, 91, 92, 93, 94, 93, 93, 93, 94, 95, 96, 98, 99, 96, - 96, 96, 97, 97, 98, 98, 98, 100, 99, 99, 98, 98, 99, 99, 100, 99, - 101, 103, 103, 101, 100, 101, 102, 101, 104, 105, 102, 101, 103, 102, 98, 102, - 102, 103, 103, 103, 104, 104, 104, 105, 105, 105, 106, 106, 107, 107, 106, 102, - 105, 105, 102, 103, 106, 106, 104, 104, 104, 105, 105, 105, 106, 106, 106, 106, - 108, 110, 111, 109, 109, 109, 111, 107, 110, 110, 108, 108, 111, 112, 109, 108, - 111, 111, 110, 108, 107, 108, 111, 109, 109, 108, 109, 109, 108, 108, 108, 107, - 110, 110, 107, 107, 110, 110, 107, 109, 108, 110, 106, 116, 105, 110, 72, 12, - 32, 60, 64, 91, 88, 98, 105, 108, 111, 104, 103, 114, 112, 103, 105, 109, - 107, 107, 111, 111, 108, 109, 112, 114, 114, 114, 113, 113, 112, 112, 112, 110, - 112, 114, 114, 112, 111, 111, 112, 113, 112, 111, 111, 111, 112, 113, 113, 109, - 116, 113, 91, 92, 92, 92, 92, 93, 91, 91, 94, 93, 91, 90, 90, 91, - 93, 93, 91, 93, 95, 95, 94, 94, 93, 94, 92, 94, 93, 93, 92, 92, - 92, 94, 95, 94, 93, 93, 92, 92, 92, 92, 92, 93, 93, 94, 96, 98, - 99, 100, 96, 96, 96, 97, 97, 98, 98, 98, 100, 99, 99, 98, 98, 99, - 99, 100, 98, 100, 102, 102, 100, 99, 100, 101, 100, 103, 104, 101, 101, 104, - 103, 100, 103, 103, 103, 103, 104, 104, 104, 105, 105, 105, 105, 106, 106, 107, - 107, 106, 102, 105, 105, 102, 103, 106, 106, 104, 105, 105, 105, 105, 106, 106, - 106, 107, 105, 108, 110, 110, 109, 108, 109, 110, 107, 110, 111, 108, 108, 112, - 112, 109, 109, 110, 110, 109, 109, 108, 109, 110, 109, 109, 109, 109, 109, 109, - 108, 108, 106, 109, 109, 106, 106, 109, 109, 106, 110, 109, 110, 105, 115, 105, - 110, 68, 13, 33, 61, 64, 91, 88, 98, 105, 109, 111, 105, 103, 114, 111, - 102, 104, 108, 106, 107, 110, 110, 108, 108, 111, 115, 115, 114, 113, 113, 112, - 111, 111, 110, 112, 114, 114, 112, 111, 111, 112, 112, 112, 111, 111, 111, 112, - 113, 114, 109, 116, 113, 90, 90, 91, 89, 89, 90, 90, 90, 93, 93, 93, - 93, 93, 92, 92, 92, 90, 93, 95, 96, 95, 94, 93, 94, 93, 94, 94, - 93, 92, 92, 92, 94, 92, 92, 93, 94, 94, 94, 93, 93, 94, 94, 94, - 95, 96, 97, 98, 99, 96, 96, 96, 97, 97, 98, 98, 98, 100, 99, 99, - 98, 98, 99, 99, 100, 98, 99, 101, 101, 100, 98, 99, 100, 98, 102, 103, - 101, 102, 105, 105, 102, 103, 103, 103, 104, 104, 104, 105, 105, 105, 105, 105, - 106, 106, 107, 107, 106, 102, 105, 105, 102, 103, 106, 106, 104, 105, 105, 105, - 106, 106, 106, 107, 107, 104, 107, 109, 109, 108, 107, 108, 109, 107, 110, 111, - 108, 109, 112, 112, 109, 111, 110, 107, 108, 110, 111, 109, 108, 109, 109, 109, - 110, 110, 109, 108, 108, 107, 110, 110, 107, 107, 110, 110, 107, 111, 111, 111, - 104, 115, 106, 108, 64, 13, 34, 62, 65, 91, 88, 98, 104, 108, 110, 104, - 103, 114, 112, 103, 106, 109, 107, 108, 111, 111, 109, 109, 112, 115, 115, 114, - 113, 113, 112, 111, 111, 110, 112, 114, 114, 112, 111, 111, 112, 112, 111, 111, - 111, 111, 112, 113, 114, 109, 116, 113, 87, 87, 87, 88, 88, 89, 89, 89, - 90, 91, 91, 92, 92, 91, 90, 90, 90, 93, 95, 96, 95, 94, 93, 94, - 95, 97, 96, 96, 95, 94, 95, 96, 88, 89, 92, 94, 95, 96, 95, 95, - 96, 96, 95, 95, 95, 96, 97, 97, 96, 96, 96, 97, 97, 98, 98, 98, - 100, 99, 99, 98, 98, 99, 99, 100, 97, 99, 101, 100, 99, 98, 98, 99, - 97, 101, 102, 101, 102, 106, 106, 103, 103, 103, 103, 104, 104, 105, 105, 105, - 105, 105, 105, 106, 106, 107, 107, 106, 102, 105, 105, 102, 103, 106, 106, 104, - 105, 105, 105, 106, 106, 107, 107, 107, 104, 106, 108, 108, 107, 106, 107, 108, - 107, 111, 111, 108, 109, 112, 112, 110, 112, 110, 106, 107, 111, 112, 109, 107, - 108, 109, 110, 111, 111, 110, 108, 107, 109, 112, 112, 109, 109, 112, 112, 109, - 111, 112, 112, 104, 115, 106, 108, 62, 14, 34, 62, 65, 91, 88, 98, 104, - 105, 108, 102, 102, 114, 113, 105, 108, 110, 109, 109, 112, 113, 110, 110, 114, - 115, 115, 114, 113, 113, 112, 111, 111, 110, 112, 114, 114, 112, 111, 111, 112, - 111, 111, 111, 111, 111, 112, 114, 114, 109, 116, 113, 91, 91, 92, 92, 92, - 91, 90, 90, 92, 91, 90, 91, 93, 94, 93, 92, 94, 94, 94, 94, 94, - 94, 93, 93, 95, 96, 94, 95, 95, 94, 93, 92, 94, 91, 91, 94, 94, - 91, 91, 94, 97, 96, 96, 96, 96, 97, 98, 99, 101, 100, 98, 96, 95, - 95, 96, 96, 99, 100, 101, 102, 102, 100, 99, 98, 100, 99, 99, 99, 99, - 100, 101, 102, 106, 105, 103, 102, 101, 101, 102, 103, 104, 104, 104, 105, 105, - 106, 106, 106, 106, 106, 107, 107, 107, 108, 108, 107, 107, 105, 104, 104, 106, - 106, 105, 104, 110, 104, 107, 109, 103, 106, 111, 106, 108, 108, 108, 109, 109, - 110, 110, 110, 111, 110, 110, 110, 110, 110, 109, 109, 115, 114, 110, 110, 110, - 110, 111, 112, 110, 110, 109, 109, 109, 109, 109, 109, 110, 112, 111, 107, 107, - 111, 112, 110, 117, 109, 114, 111, 113, 102, 107, 58, 13, 37, 65, 65, 92, - 92, 102, 106, 113, 106, 104, 108, 113, 111, 106, 106, 110, 109, 110, 112, 111, - 107, 108, 112, 116, 115, 113, 111, 109, 108, 108, 107, 110, 114, 115, 112, 112, - 114, 112, 108, 117, 115, 111, 108, 108, 110, 113, 115, 108, 117, 115, 90, 90, - 91, 92, 91, 91, 91, 90, 92, 91, 90, 91, 93, 94, 95, 94, 94, 94, - 94, 94, 94, 94, 93, 93, 95, 96, 94, 95, 95, 94, 93, 92, 95, 92, - 92, 95, 95, 92, 92, 95, 97, 96, 96, 96, 96, 97, 98, 99, 96, 96, - 96, 96, 97, 98, 99, 100, 99, 100, 100, 101, 101, 100, 100, 99, 100, 100, - 99, 99, 100, 100, 101, 102, 104, 103, 102, 102, 102, 103, 104, 105, 104, 104, - 104, 105, 105, 106, 106, 106, 106, 106, 106, 106, 107, 107, 107, 107, 106, 104, - 102, 103, 105, 105, 104, 103, 109, 103, 107, 109, 103, 106, 110, 105, 108, 108, - 108, 109, 109, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 111, 112, 111, - 108, 108, 108, 108, 108, 109, 110, 110, 109, 109, 109, 109, 109, 109, 109, 112, - 111, 108, 108, 111, 112, 109, 113, 107, 112, 109, 114, 104, 109, 60, 14, 37, - 65, 65, 92, 92, 102, 106, 113, 106, 104, 108, 113, 111, 106, 106, 110, 109, - 110, 112, 111, 107, 108, 113, 114, 114, 113, 112, 111, 111, 112, 112, 111, 114, - 114, 111, 111, 113, 112, 109, 116, 114, 111, 109, 109, 110, 112, 114, 112, 116, - 112, 90, 88, 90, 90, 90, 90, 91, 91, 92, 91, 92, 93, 95, 96, 96, - 94, 94, 94, 94, 94, 94, 95, 94, 94, 95, 96, 94, 95, 95, 94, 93, - 92, 95, 92, 92, 95, 95, 92, 92, 95, 97, 96, 96, 96, 96, 97, 98, - 99, 95, 95, 96, 98, 99, 99, 99, 99, 100, 100, 100, 99, 99, 100, 100, - 101, 100, 100, 99, 99, 100, 101, 102, 102, 102, 102, 101, 102, 103, 104, 105, - 106, 104, 104, 104, 105, 105, 106, 106, 106, 105, 105, 105, 106, 106, 107, 107, - 106, 105, 103, 102, 102, 104, 105, 103, 102, 109, 103, 106, 108, 102, 105, 110, - 105, 108, 108, 108, 109, 109, 110, 110, 110, 109, 109, 109, 110, 111, 111, 112, - 112, 112, 111, 109, 108, 108, 109, 108, 109, 110, 110, 109, 109, 109, 109, 109, - 109, 108, 111, 112, 109, 109, 112, 111, 108, 110, 105, 110, 108, 114, 107, 112, - 60, 14, 38, 66, 66, 92, 92, 102, 105, 113, 106, 104, 108, 113, 111, 106, - 106, 110, 109, 110, 113, 111, 108, 109, 113, 112, 112, 112, 112, 113, 114, 115, - 116, 112, 115, 114, 110, 110, 113, 113, 110, 114, 113, 112, 111, 111, 111, 112, - 112, 114, 116, 109, 90, 88, 89, 89, 90, 90, 92, 92, 92, 91, 92, 93, - 95, 96, 96, 94, 96, 94, 94, 95, 95, 95, 94, 95, 95, 96, 94, 95, - 95, 94, 93, 92, 95, 92, 92, 95, 95, 92, 92, 95, 97, 96, 96, 96, - 96, 97, 98, 99, 97, 98, 99, 100, 99, 98, 96, 95, 101, 100, 99, 98, - 98, 100, 101, 102, 101, 100, 100, 100, 100, 101, 102, 103, 102, 102, 102, 102, - 103, 104, 104, 105, 104, 104, 104, 105, 105, 106, 106, 106, 105, 105, 105, 105, - 106, 106, 107, 106, 106, 104, 103, 103, 105, 105, 104, 103, 108, 103, 106, 108, - 102, 105, 109, 105, 108, 108, 108, 109, 109, 110, 110, 110, 108, 109, 109, 110, - 111, 112, 113, 113, 113, 113, 111, 111, 111, 111, 110, 110, 111, 111, 110, 110, - 110, 110, 110, 110, 107, 111, 112, 110, 110, 112, 111, 107, 109, 105, 110, 107, - 114, 108, 112, 57, 15, 38, 66, 66, 93, 92, 102, 105, 113, 106, 104, 108, - 113, 111, 106, 106, 109, 109, 110, 113, 112, 108, 110, 114, 112, 112, 111, 112, - 112, 113, 115, 115, 113, 115, 113, 109, 109, 112, 113, 111, 112, 113, 113, 113, - 112, 112, 111, 110, 113, 116, 110, 90, 87, 87, 87, 89, 90, 93, 93, 92, - 91, 92, 93, 96, 97, 96, 94, 96, 94, 94, 95, 95, 96, 95, 96, 95, - 96, 94, 95, 95, 94, 93, 92, 96, 93, 93, 96, 96, 93, 93, 96, 97, - 96, 96, 96, 96, 97, 98, 99, 97, 98, 99, 100, 100, 99, 97, 96, 100, - 100, 99, 98, 99, 100, 102, 103, 101, 101, 100, 100, 101, 101, 102, 103, 104, - 104, 104, 104, 103, 102, 102, 101, 104, 104, 104, 105, 105, 106, 106, 106, 105, - 105, 105, 106, 106, 107, 107, 106, 108, 106, 105, 105, 107, 107, 106, 105, 109, - 103, 106, 108, 102, 105, 110, 105, 108, 108, 108, 109, 109, 110, 110, 110, 109, - 109, 110, 111, 112, 113, 113, 114, 113, 113, 111, 111, 111, 111, 110, 110, 111, - 111, 110, 110, 110, 110, 110, 110, 107, 111, 112, 110, 110, 112, 111, 107, 111, - 108, 112, 106, 113, 108, 109, 52, 16, 39, 67, 67, 93, 92, 102, 105, 113, - 106, 104, 108, 113, 111, 106, 106, 109, 109, 110, 113, 112, 109, 111, 115, 113, - 112, 111, 111, 110, 111, 111, 111, 113, 115, 113, 109, 109, 112, 113, 111, 112, - 112, 113, 113, 113, 112, 111, 110, 109, 117, 114, 88, 87, 86, 86, 89, 90, - 93, 95, 92, 91, 92, 93, 96, 97, 96, 95, 96, 94, 95, 95, 96, 97, - 96, 96, 95, 96, 94, 95, 95, 94, 93, 92, 96, 93, 93, 96, 96, 93, - 93, 96, 97, 96, 96, 96, 96, 97, 98, 99, 94, 95, 97, 99, 100, 101, - 102, 102, 99, 99, 99, 99, 100, 101, 102, 103, 101, 101, 101, 101, 101, 102, - 103, 103, 104, 104, 105, 104, 103, 102, 101, 100, 104, 104, 104, 105, 105, 106, - 106, 106, 106, 106, 107, 107, 107, 108, 108, 107, 109, 107, 105, 106, 108, 108, - 107, 106, 110, 104, 107, 109, 103, 106, 111, 106, 108, 108, 108, 109, 109, 110, - 110, 110, 110, 110, 111, 111, 112, 113, 113, 113, 110, 111, 109, 110, 110, 109, - 108, 107, 112, 112, 111, 111, 111, 111, 111, 111, 108, 111, 112, 109, 109, 112, - 111, 108, 112, 110, 113, 106, 113, 108, 108, 47, 17, 40, 68, 67, 93, 92, - 102, 105, 113, 106, 104, 108, 113, 111, 106, 106, 109, 109, 110, 114, 113, 110, - 111, 116, 114, 113, 112, 110, 109, 109, 109, 109, 112, 115, 114, 110, 110, 113, - 113, 110, 112, 113, 113, 113, 113, 112, 111, 110, 108, 117, 116, 88, 86, 86, - 85, 88, 90, 93, 95, 92, 93, 92, 93, 96, 97, 97, 95, 96, 94, 95, - 95, 96, 97, 97, 97, 95, 96, 94, 95, 95, 94, 93, 92, 96, 93, 93, - 96, 96, 93, 93, 96, 97, 96, 96, 96, 96, 97, 98, 99, 95, 96, 96, - 97, 99, 101, 103, 104, 97, 98, 99, 100, 101, 102, 102, 102, 102, 101, 101, - 101, 101, 102, 103, 104, 102, 103, 104, 104, 104, 103, 102, 101, 104, 104, 104, - 105, 105, 106, 106, 106, 107, 107, 108, 108, 109, 109, 109, 108, 108, 106, 105, - 105, 107, 108, 106, 105, 111, 105, 109, 110, 105, 107, 112, 107, 108, 108, 108, - 109, 109, 110, 110, 110, 111, 112, 112, 112, 112, 112, 112, 112, 110, 110, 109, - 110, 110, 109, 107, 107, 112, 112, 111, 111, 111, 111, 111, 111, 109, 112, 111, - 108, 108, 111, 112, 109, 112, 110, 113, 105, 113, 109, 108, 45, 18, 41, 68, - 68, 93, 92, 102, 105, 113, 106, 104, 108, 113, 111, 106, 106, 109, 109, 110, - 114, 113, 110, 112, 117, 115, 114, 113, 111, 111, 110, 110, 110, 111, 114, 114, - 111, 111, 113, 112, 109, 113, 113, 113, 112, 112, 111, 111, 111, 110, 117, 113, - 90, 87, 88, 87, 88, 90, 93, 96, 92, 93, 92, 93, 95, 96, 96, 94, - 94, 94, 95, 96, 97, 97, 97, 98, 95, 96, 94, 95, 95, 94, 94, 92, - 97, 94, 94, 97, 97, 94, 94, 97, 97, 96, 96, 97, 97, 98, 99, 100, - 100, 99, 98, 97, 97, 99, 100, 101, 96, 97, 99, 101, 102, 102, 101, 101, - 102, 101, 101, 100, 101, 101, 103, 103, 99, 100, 102, 103, 104, 104, 103, 103, - 105, 105, 105, 106, 106, 107, 107, 106, 108, 108, 108, 108, 108, 109, 109, 107, - 107, 106, 105, 104, 107, 106, 105, 104, 112, 106, 110, 111, 105, 108, 113, 108, - 108, 108, 108, 109, 109, 110, 111, 111, 114, 114, 113, 113, 113, 112, 112, 111, - 112, 112, 112, 113, 113, 112, 109, 109, 112, 112, 111, 111, 111, 111, 111, 111, - 110, 112, 111, 107, 107, 111, 112, 110, 110, 109, 112, 104, 113, 111, 109, 45, - 17, 41, 69, 70, 94, 93, 104, 106, 113, 105, 104, 108, 111, 111, 108, 108, - 110, 109, 111, 114, 113, 111, 112, 117, 115, 114, 113, 112, 112, 112, 113, 113, - 110, 114, 115, 112, 112, 114, 112, 108, 114, 113, 112, 111, 111, 111, 112, 112, - 114, 116, 109, 91, 91, 89, 90, 90, 91, 91, 91, 92, 91, 91, 91, 91, - 92, 92, 93, 92, 92, 92, 93, 93, 94, 94, 94, 96, 96, 96, 97, 97, - 98, 98, 96, 92, 93, 94, 95, 95, 95, 96, 95, 95, 96, 98, 100, 98, - 98, 100, 101, 99, 98, 98, 99, 99, 100, 100, 100, 102, 102, 102, 101, 101, - 100, 100, 100, 99, 106, 103, 98, 104, 99, 98, 103, 98, 102, 100, 96, 96, - 103, 105, 105, 109, 112, 112, 113, 111, 110, 109, 106, 106, 113, 108, 104, 106, - 103, 98, 108, 103, 108, 109, 105, 108, 110, 106, 98, 114, 110, 108, 110, 110, - 107, 107, 111, 109, 108, 107, 109, 110, 112, 113, 113, 113, 114, 114, 114, 115, - 112, 112, 111, 112, 112, 113, 113, 111, 111, 111, 112, 110, 111, 111, 110, 109, - 110, 112, 115, 107, 110, 112, 111, 108, 106, 107, 109, 112, 104, 112, 107, 108, - 105, 108, 41, 16, 44, 67, 77, 94, 102, 105, 109, 115, 104, 100, 108, 113, - 110, 107, 110, 112, 110, 110, 113, 114, 111, 111, 115, 112, 114, 116, 115, 113, - 112, 114, 116, 111, 115, 115, 112, 111, 113, 112, 108, 114, 113, 112, 111, 111, - 111, 111, 112, 110, 111, 112, 92, 92, 92, 92, 92, 93, 91, 91, 93, 93, - 91, 91, 92, 93, 92, 92, 92, 92, 93, 93, 93, 94, 94, 94, 96, 96, - 96, 97, 97, 98, 98, 96, 93, 91, 93, 94, 94, 95, 96, 96, 95, 97, - 100, 100, 100, 99, 101, 101, 99, 98, 98, 99, 99, 100, 100, 100, 102, 102, - 102, 101, 101, 100, 100, 100, 100, 107, 103, 100, 104, 101, 98, 105, 98, 101, - 100, 97, 98, 103, 104, 104, 109, 110, 110, 109, 109, 107, 107, 106, 99, 105, - 102, 98, 102, 99, 96, 105, 101, 104, 104, 100, 103, 106, 105, 100, 108, 104, - 101, 103, 102, 98, 98, 101, 105, 105, 106, 108, 111, 111, 112, 110, 115, 115, - 115, 113, 114, 113, 113, 114, 109, 110, 111, 110, 107, 107, 108, 109, 110, 111, - 111, 110, 110, 111, 113, 116, 108, 111, 113, 112, 109, 107, 108, 109, 114, 107, - 114, 108, 108, 104, 106, 37, 17, 44, 67, 78, 96, 104, 106, 109, 114, 103, - 99, 106, 112, 109, 108, 110, 112, 110, 110, 113, 114, 111, 111, 115, 112, 114, - 116, 115, 113, 112, 114, 116, 110, 114, 114, 111, 111, 113, 113, 109, 114, 113, - 112, 111, 111, 111, 111, 112, 112, 113, 113, 92, 93, 92, 92, 93, 93, 91, - 91, 94, 94, 93, 93, 93, 94, 93, 93, 92, 93, 93, 93, 94, 94, 94, - 94, 96, 96, 96, 97, 97, 98, 98, 96, 94, 92, 93, 92, 93, 94, 97, - 98, 95, 97, 100, 100, 100, 100, 101, 102, 99, 98, 98, 99, 99, 100, 100, - 100, 102, 102, 101, 101, 101, 101, 100, 100, 103, 110, 107, 104, 108, 105, 100, - 107, 101, 104, 105, 103, 103, 106, 106, 103, 107, 104, 102, 100, 100, 101, 103, - 104, 97, 104, 102, 98, 103, 101, 98, 105, 106, 106, 104, 101, 104, 108, 108, - 106, 110, 107, 106, 108, 108, 105, 106, 108, 102, 104, 105, 107, 108, 109, 108, - 108, 113, 113, 111, 108, 108, 107, 108, 108, 111, 111, 111, 110, 108, 109, 112, - 112, 109, 110, 111, 112, 113, 114, 116, 118, 111, 112, 113, 113, 111, 109, 110, - 110, 117, 109, 116, 110, 109, 104, 105, 35, 17, 44, 67, 79, 96, 104, 106, - 109, 112, 101, 98, 105, 112, 109, 107, 110, 112, 110, 110, 113, 114, 111, 111, - 115, 113, 114, 115, 115, 113, 113, 114, 115, 109, 113, 113, 111, 111, 114, 114, - 110, 114, 113, 112, 111, 111, 111, 111, 112, 114, 114, 114, 93, 93, 92, 93, - 93, 93, 92, 92, 94, 94, 93, 92, 93, 94, 93, 93, 93, 93, 93, 94, - 94, 94, 95, 95, 96, 96, 96, 97, 97, 98, 98, 96, 95, 92, 92, 91, - 92, 94, 97, 99, 96, 97, 101, 100, 100, 100, 101, 102, 99, 98, 98, 99, - 99, 100, 100, 100, 101, 101, 101, 101, 101, 101, 101, 102, 103, 111, 108, 105, - 109, 106, 103, 109, 104, 104, 108, 107, 107, 108, 107, 103, 103, 99, 97, 95, - 95, 97, 100, 102, 101, 108, 104, 101, 106, 105, 101, 106, 102, 99, 100, 100, - 103, 105, 105, 104, 108, 105, 105, 108, 109, 108, 111, 113, 111, 112, 114, 114, - 114, 115, 116, 117, 118, 117, 115, 113, 111, 110, 111, 111, 113, 114, 113, 111, - 108, 108, 112, 115, 106, 108, 112, 112, 114, 116, 119, 120, 112, 112, 113, 113, - 112, 112, 111, 111, 116, 109, 116, 110, 109, 105, 106, 35, 18, 45, 68, 79, - 96, 104, 106, 109, 111, 100, 97, 105, 111, 108, 107, 110, 112, 110, 110, 113, - 114, 111, 111, 115, 114, 114, 114, 114, 114, 114, 114, 114, 108, 112, 113, 111, - 112, 115, 115, 111, 114, 113, 112, 111, 111, 111, 111, 112, 114, 114, 113, 93, - 93, 93, 93, 93, 94, 92, 92, 93, 93, 92, 92, 92, 93, 92, 92, 93, - 93, 94, 94, 94, 95, 95, 95, 96, 96, 96, 97, 97, 98, 98, 96, 96, - 94, 92, 91, 93, 95, 97, 99, 96, 98, 101, 101, 100, 99, 101, 102, 99, - 98, 98, 99, 99, 100, 100, 100, 101, 101, 101, 101, 101, 101, 101, 102, 104, - 113, 110, 107, 111, 108, 105, 110, 107, 106, 109, 110, 111, 109, 108, 104, 99, - 93, 91, 90, 92, 95, 99, 102, 101, 107, 104, 102, 110, 109, 104, 110, 112, - 112, 115, 118, 120, 119, 117, 116, 121, 117, 118, 121, 121, 118, 119, 123, 122, - 122, 123, 121, 120, 121, 125, 128, 123, 123, 121, 122, 122, 123, 124, 124, 120, - 120, 117, 112, 108, 106, 107, 108, 104, 107, 112, 113, 115, 116, 119, 120, 115, - 112, 112, 113, 113, 113, 112, 111, 113, 106, 115, 110, 110, 106, 106, 36, 19, - 46, 69, 80, 97, 104, 106, 109, 111, 100, 97, 104, 111, 109, 107, 110, 112, - 110, 110, 113, 114, 111, 111, 115, 114, 114, 114, 114, 114, 114, 114, 114, 108, - 112, 113, 111, 112, 115, 115, 111, 114, 113, 112, 111, 111, 111, 111, 112, 112, - 112, 112, 94, 94, 93, 93, 94, 94, 92, 93, 93, 93, 91, 91, 92, 93, - 92, 92, 94, 94, 94, 94, 95, 95, 95, 96, 96, 96, 96, 97, 97, 98, - 98, 96, 95, 94, 93, 92, 94, 95, 97, 98, 96, 98, 101, 101, 100, 100, - 101, 101, 98, 98, 98, 99, 99, 100, 100, 100, 100, 100, 101, 101, 101, 101, - 102, 103, 103, 110, 108, 105, 109, 106, 103, 110, 109, 107, 107, 111, 111, 108, - 107, 105, 98, 94, 92, 93, 94, 98, 101, 105, 107, 112, 110, 110, 119, 119, - 116, 123, 125, 126, 128, 133, 135, 131, 130, 130, 132, 130, 128, 130, 129, 124, - 123, 126, 123, 124, 124, 121, 120, 121, 125, 128, 121, 122, 123, 126, 127, 129, - 131, 129, 133, 132, 128, 125, 117, 112, 108, 106, 105, 107, 111, 112, 114, 117, - 118, 118, 113, 111, 111, 112, 114, 114, 113, 111, 111, 105, 114, 110, 110, 105, - 105, 35, 20, 47, 70, 80, 97, 104, 106, 109, 111, 100, 97, 105, 112, 110, - 108, 112, 112, 110, 110, 113, 114, 111, 111, 115, 115, 114, 113, 113, 115, 115, - 114, 113, 109, 113, 113, 111, 111, 114, 114, 110, 114, 113, 112, 111, 111, 111, - 111, 112, 112, 111, 111, 94, 94, 93, 94, 94, 94, 93, 93, 94, 94, 93, - 93, 93, 94, 93, 94, 94, 94, 94, 95, 95, 95, 96, 96, 96, 96, 96, - 97, 97, 98, 98, 96, 94, 94, 94, 95, 95, 96, 97, 97, 97, 98, 100, - 99, 98, 98, 99, 101, 98, 98, 98, 99, 99, 100, 100, 100, 100, 100, 100, - 101, 101, 102, 102, 102, 100, 106, 104, 101, 105, 102, 99, 106, 110, 105, 105, - 108, 108, 105, 105, 107, 102, 100, 102, 103, 105, 107, 110, 113, 117, 123, 118, - 117, 126, 125, 120, 126, 124, 123, 122, 127, 130, 126, 125, 127, 132, 130, 129, - 131, 130, 127, 128, 131, 131, 137, 141, 140, 136, 134, 136, 139, 134, 135, 136, - 138, 138, 137, 134, 128, 137, 134, 134, 133, 126, 120, 116, 112, 106, 107, 111, - 112, 112, 114, 115, 115, 112, 110, 109, 111, 114, 114, 113, 110, 111, 105, 114, - 109, 109, 103, 102, 31, 21, 47, 70, 81, 97, 105, 105, 109, 111, 101, 98, - 106, 113, 111, 110, 113, 112, 110, 110, 113, 114, 111, 111, 115, 116, 114, 112, - 113, 115, 116, 114, 112, 110, 114, 114, 111, 111, 113, 113, 109, 114, 113, 112, - 111, 111, 111, 111, 112, 114, 113, 112, 94, 94, 93, 94, 94, 95, 93, 93, - 96, 96, 94, 94, 94, 95, 94, 95, 94, 94, 94, 95, 95, 96, 96, 96, - 96, 96, 96, 97, 97, 98, 98, 98, 94, 94, 95, 96, 96, 96, 97, 96, - 97, 98, 100, 100, 98, 98, 100, 101, 98, 98, 98, 99, 99, 100, 100, 100, - 100, 100, 100, 101, 101, 102, 102, 101, 96, 101, 98, 97, 101, 99, 96, 105, - 109, 105, 103, 107, 106, 103, 104, 111, 109, 112, 113, 117, 118, 120, 123, 125, - 127, 131, 123, 120, 126, 121, 114, 121, 139, 137, 134, 138, 139, 137, 136, 140, - 149, 148, 149, 155, 156, 155, 157, 161, 152, 159, 165, 166, 164, 158, 158, 158, - 157, 157, 157, 156, 152, 147, 142, 133, 130, 127, 132, 133, 131, 126, 122, 118, - 111, 111, 111, 112, 111, 110, 111, 112, 111, 109, 108, 110, 113, 114, 112, 109, - 113, 106, 115, 109, 107, 101, 99, 28, 21, 48, 70, 81, 97, 105, 105, 109, - 112, 101, 98, 106, 114, 112, 111, 114, 112, 110, 110, 113, 114, 111, 111, 115, - 116, 114, 112, 113, 115, 116, 114, 112, 111, 115, 115, 112, 111, 113, 112, 108, - 114, 113, 112, 111, 111, 111, 111, 112, 116, 115, 113, 95, 97, 97, 96, 94, - 93, 92, 94, 92, 93, 94, 96, 96, 96, 93, 92, 93, 92, 90, 90, 91, - 93, 96, 98, 99, 98, 97, 95, 95, 96, 97, 98, 99, 97, 95, 96, 100, - 101, 99, 97, 97, 98, 99, 99, 97, 97, 99, 100, 100, 101, 101, 102, 102, - 101, 101, 100, 96, 99, 102, 102, 99, 98, 99, 99, 98, 94, 94, 96, 97, - 99, 100, 103, 97, 103, 107, 106, 103, 101, 102, 110, 120, 121, 127, 129, 122, - 125, 131, 128, 119, 121, 117, 119, 128, 124, 123, 137, 147, 148, 152, 155, 150, - 158, 164, 155, 172, 171, 169, 172, 173, 169, 169, 173, 166, 179, 177, 184, 178, - 167, 183, 188, 186, 178, 179, 160, 170, 157, 161, 144, 139, 138, 133, 122, 121, - 134, 138, 133, 121, 122, 112, 106, 108, 106, 103, 113, 109, 110, 111, 112, 112, - 113, 114, 114, 114, 108, 115, 107, 108, 107, 106, 32, 20, 53, 67, 84, 101, - 101, 110, 107, 113, 96, 97, 109, 111, 112, 115, 112, 111, 114, 107, 116, 116, - 107, 114, 111, 113, 113, 114, 114, 114, 113, 112, 112, 112, 113, 113, 114, 114, - 113, 113, 112, 114, 113, 113, 112, 112, 113, 113, 114, 109, 111, 112, 92, 94, - 94, 93, 91, 91, 90, 91, 94, 95, 94, 94, 94, 93, 91, 90, 95, 94, - 93, 93, 94, 96, 98, 99, 98, 97, 97, 96, 96, 97, 97, 98, 99, 97, - 95, 97, 99, 101, 99, 97, 97, 98, 99, 99, 97, 97, 99, 100, 100, 100, - 101, 101, 101, 101, 100, 100, 102, 104, 105, 104, 101, 100, 101, 100, 95, 92, - 93, 95, 96, 97, 99, 102, 100, 103, 110, 113, 112, 111, 111, 118, 136, 133, - 130, 126, 118, 119, 127, 125, 125, 133, 134, 139, 148, 145, 143, 157, 157, 157, - 162, 162, 158, 164, 169, 161, 181, 178, 177, 180, 181, 178, 178, 182, 175, 180, - 173, 182, 181, 173, 185, 185, 178, 173, 176, 161, 172, 162, 169, 157, 151, 147, - 141, 137, 130, 127, 130, 132, 138, 132, 117, 111, 116, 111, 104, 108, 112, 112, - 112, 112, 112, 112, 112, 112, 115, 110, 117, 109, 108, 105, 103, 28, 21, 53, - 68, 84, 101, 101, 110, 107, 113, 96, 98, 109, 111, 112, 115, 112, 111, 114, - 107, 116, 116, 107, 114, 111, 112, 113, 113, 114, 114, 113, 113, 112, 112, 113, - 113, 114, 114, 113, 113, 112, 114, 113, 113, 112, 112, 113, 113, 114, 110, 112, - 113, 92, 93, 93, 93, 91, 91, 90, 92, 96, 95, 93, 92, 91, 91, 89, - 89, 94, 94, 94, 95, 96, 97, 97, 98, 96, 97, 97, 98, 98, 97, 97, - 97, 100, 99, 98, 99, 101, 102, 99, 98, 96, 97, 99, 99, 96, 96, 98, - 99, 99, 99, 100, 100, 100, 100, 99, 99, 105, 105, 105, 104, 101, 101, 102, - 100, 95, 94, 96, 98, 101, 103, 105, 108, 114, 116, 117, 117, 117, 112, 107, - 113, 137, 135, 133, 133, 128, 134, 140, 137, 135, 144, 147, 153, 161, 157, 156, - 167, 159, 156, 160, 159, 155, 160, 165, 158, 168, 166, 166, 169, 169, 168, 169, - 172, 172, 171, 158, 168, 174, 168, 176, 170, 163, 164, 169, 156, 163, 156, 164, - 159, 163, 153, 150, 151, 140, 124, 124, 131, 141, 139, 130, 122, 120, 111, 104, - 111, 114, 114, 114, 113, 112, 111, 111, 110, 115, 111, 119, 111, 109, 105, 100, - 23, 22, 54, 68, 84, 100, 101, 110, 107, 112, 97, 99, 110, 111, 111, 114, - 111, 111, 114, 107, 116, 116, 107, 114, 111, 112, 112, 113, 114, 114, 113, 113, - 112, 112, 113, 113, 114, 114, 113, 113, 112, 114, 113, 113, 112, 112, 113, 113, - 114, 111, 113, 114, 95, 96, 97, 96, 95, 95, 94, 96, 95, 94, 91, 90, - 90, 91, 90, 91, 91, 92, 93, 94, 95, 95, 94, 94, 95, 96, 97, 99, - 99, 98, 97, 96, 99, 99, 99, 100, 100, 101, 99, 99, 96, 97, 99, 99, - 96, 96, 98, 99, 98, 99, 99, 100, 100, 99, 99, 98, 102, 102, 101, 100, - 100, 100, 101, 102, 102, 103, 106, 109, 112, 113, 115, 118, 121, 119, 117, 116, - 114, 113, 107, 112, 137, 139, 142, 151, 151, 156, 157, 148, 149, 154, 150, 153, - 162, 158, 156, 163, 156, 153, 157, 156, 148, 153, 158, 150, 155, 152, 152, 155, - 156, 154, 155, 158, 165, 163, 149, 159, 163, 159, 167, 162, 159, 162, 165, 156, - 154, 153, 155, 157, 167, 163, 159, 158, 152, 140, 135, 132, 127, 139, 141, 133, - 122, 109, 107, 119, 114, 114, 113, 113, 113, 112, 112, 112, 113, 110, 119, 112, - 111, 105, 99, 21, 23, 55, 68, 84, 100, 101, 110, 108, 112, 97, 100, 111, - 111, 110, 113, 111, 111, 114, 107, 116, 116, 107, 114, 111, 111, 112, 113, 114, - 114, 114, 113, 113, 112, 113, 113, 114, 114, 113, 113, 112, 114, 113, 113, 112, - 112, 113, 113, 114, 112, 114, 114, 95, 97, 98, 97, 96, 96, 96, 97, 92, - 91, 90, 90, 91, 93, 93, 94, 92, 93, 94, 95, 95, 95, 94, 94, 94, - 95, 97, 98, 99, 98, 97, 97, 100, 100, 101, 101, 100, 100, 99, 99, 96, - 97, 98, 98, 96, 96, 96, 99, 98, 99, 99, 100, 100, 99, 99, 98, 100, - 100, 99, 100, 101, 102, 102, 105, 112, 116, 116, 116, 117, 117, 119, 122, 119, - 117, 115, 117, 122, 125, 128, 134, 156, 155, 157, 162, 159, 161, 159, 147, 162, - 157, 147, 148, 161, 160, 155, 158, 154, 150, 155, 153, 144, 150, 155, 149, 151, - 148, 149, 151, 152, 149, 150, 154, 153, 156, 148, 155, 155, 147, 158, 157, 158, - 163, 162, 158, 150, 153, 151, 154, 164, 168, 163, 158, 159, 162, 155, 139, 127, - 135, 137, 134, 132, 123, 117, 123, 113, 112, 113, 113, 113, 114, 114, 114, 111, - 108, 118, 112, 111, 105, 99, 21, 25, 56, 69, 84, 100, 101, 111, 108, 111, - 98, 102, 112, 111, 109, 112, 111, 111, 114, 107, 116, 116, 107, 114, 111, 111, - 112, 113, 114, 114, 114, 114, 114, 112, 113, 113, 114, 114, 113, 113, 112, 114, - 113, 113, 112, 112, 113, 113, 114, 112, 114, 114, 93, 94, 95, 95, 94, 94, - 94, 96, 90, 90, 90, 91, 93, 95, 94, 95, 97, 97, 97, 97, 97, 97, - 97, 97, 94, 95, 96, 97, 98, 98, 98, 98, 99, 100, 102, 102, 99, 99, - 99, 100, 96, 97, 98, 98, 96, 96, 96, 97, 99, 99, 100, 100, 100, 100, - 99, 99, 101, 101, 101, 102, 104, 104, 103, 107, 117, 120, 119, 117, 114, 115, - 116, 119, 126, 127, 126, 129, 133, 140, 145, 151, 173, 168, 167, 167, 161, 165, - 168, 161, 166, 159, 147, 147, 159, 159, 156, 162, 156, 155, 161, 159, 149, 153, - 159, 154, 155, 152, 151, 153, 153, 150, 151, 154, 150, 156, 151, 158, 157, 146, - 159, 160, 158, 165, 159, 162, 153, 162, 157, 160, 157, 165, 165, 159, 164, 174, - 168, 150, 146, 139, 126, 127, 142, 143, 129, 121, 115, 112, 112, 113, 114, 115, - 115, 116, 111, 108, 118, 111, 110, 105, 99, 21, 26, 57, 69, 84, 99, 101, - 111, 109, 110, 98, 103, 114, 111, 108, 111, 110, 111, 114, 107, 116, 116, 107, - 114, 111, 110, 111, 112, 113, 114, 114, 114, 114, 112, 113, 113, 114, 114, 113, - 113, 112, 114, 113, 113, 112, 112, 113, 113, 114, 111, 113, 114, 90, 92, 93, - 93, 92, 93, 92, 94, 91, 92, 92, 94, 95, 95, 93, 93, 99, 98, 96, - 96, 95, 96, 97, 98, 95, 95, 95, 96, 97, 98, 99, 100, 98, 101, 102, - 102, 99, 99, 98, 101, 96, 97, 98, 98, 96, 96, 96, 97, 100, 100, 101, - 101, 101, 101, 100, 100, 102, 101, 101, 103, 104, 103, 98, 102, 113, 118, 116, - 114, 113, 116, 122, 126, 136, 143, 147, 149, 153, 155, 160, 164, 175, 170, 171, - 173, 167, 170, 176, 172, 159, 159, 152, 151, 155, 151, 152, 165, 158, 162, 169, - 167, 157, 161, 166, 161, 163, 160, 159, 160, 160, 157, 156, 159, 156, 163, 159, - 168, 167, 156, 167, 169, 166, 172, 161, 169, 159, 172, 164, 164, 157, 160, 166, - 167, 168, 170, 171, 167, 161, 149, 129, 125, 138, 141, 134, 129, 119, 114, 114, - 114, 114, 114, 114, 114, 114, 110, 119, 110, 109, 103, 97, 19, 27, 58, 70, - 84, 99, 101, 111, 109, 109, 98, 104, 114, 111, 108, 111, 110, 111, 114, 107, - 116, 116, 107, 114, 111, 110, 111, 112, 113, 114, 115, 115, 114, 112, 113, 113, - 114, 114, 113, 113, 112, 114, 113, 113, 112, 112, 113, 113, 114, 110, 112, 113, - 89, 91, 93, 93, 93, 91, 93, 95, 93, 93, 94, 96, 96, 93, 92, 91, - 98, 96, 94, 92, 92, 94, 96, 97, 96, 96, 95, 95, 96, 98, 100, 101, - 97, 101, 103, 102, 100, 98, 100, 103, 97, 98, 99, 98, 96, 94, 96, 97, - 100, 102, 102, 103, 102, 101, 100, 99, 100, 100, 101, 105, 108, 106, 101, 106, - 112, 119, 116, 117, 120, 126, 133, 140, 134, 144, 155, 161, 164, 168, 172, 177, - 171, 170, 178, 179, 171, 169, 168, 162, 156, 161, 160, 156, 153, 145, 146, 163, - 159, 161, 169, 167, 158, 162, 170, 165, 174, 170, 168, 169, 169, 164, 164, 167, - 162, 168, 164, 175, 175, 167, 175, 172, 171, 175, 163, 173, 162, 177, 168, 165, - 161, 161, 170, 177, 172, 163, 169, 181, 165, 161, 144, 131, 131, 133, 140, 147, - 127, 119, 116, 115, 114, 113, 111, 111, 117, 112, 120, 110, 108, 102, 96, 18, - 27, 59, 69, 84, 99, 101, 111, 111, 109, 99, 105, 115, 111, 107, 110, 110, - 111, 114, 107, 116, 116, 107, 114, 111, 110, 111, 112, 113, 114, 115, 115, 115, - 112, 113, 113, 114, 114, 113, 113, 112, 114, 113, 113, 112, 112, 113, 113, 114, - 109, 111, 112, 92, 92, 92, 92, 93, 94, 95, 94, 94, 94, 94, 91, 90, - 92, 96, 98, 94, 94, 94, 95, 95, 96, 96, 96, 92, 93, 94, 94, 95, - 96, 97, 97, 99, 101, 102, 103, 103, 104, 103, 103, 105, 103, 99, 97, 96, - 95, 95, 97, 97, 100, 101, 102, 101, 99, 97, 95, 105, 93, 102, 117, 118, - 112, 110, 110, 127, 131, 131, 133, 137, 137, 137, 136, 141, 148, 156, 160, 163, - 166, 173, 181, 176, 175, 179, 198, 170, 178, 176, 176, 166, 173, 159, 163, 167, - 154, 161, 166, 156, 171, 174, 164, 161, 168, 169, 161, 177, 172, 175, 175, 167, - 164, 168, 163, 173, 180, 176, 173, 177, 175, 171, 178, 181, 177, 173, 172, 174, - 176, 178, 174, 158, 167, 173, 169, 167, 170, 172, 167, 160, 159, 158, 150, 139, - 136, 150, 154, 142, 116, 110, 115, 119, 116, 110, 109, 112, 109, 110, 112, 104, - 111, 98, 24, 30, 60, 70, 85, 101, 103, 112, 109, 111, 93, 106, 112, 110, - 115, 108, 112, 111, 107, 114, 116, 109, 111, 116, 112, 114, 114, 115, 115, 115, - 114, 113, 113, 113, 114, 114, 114, 114, 113, 112, 111, 115, 115, 115, 114, 114, - 113, 113, 113, 111, 111, 112, 92, 92, 91, 90, 90, 90, 90, 90, 94, 94, - 93, 92, 91, 92, 94, 96, 94, 94, 94, 95, 95, 96, 96, 96, 93, 93, - 94, 95, 96, 96, 97, 97, 99, 99, 101, 101, 101, 103, 103, 104, 106, 104, - 100, 98, 97, 95, 93, 97, 102, 104, 105, 105, 103, 101, 99, 98, 98, 96, - 106, 116, 114, 112, 118, 120, 136, 140, 138, 140, 143, 146, 146, 145, 151, 153, - 157, 160, 165, 167, 170, 172, 177, 173, 181, 183, 177, 173, 180, 182, 169, 177, - 164, 167, 170, 157, 161, 165, 155, 163, 167, 164, 168, 175, 176, 172, 172, 168, - 175, 176, 168, 170, 175, 171, 176, 183, 179, 176, 180, 176, 173, 179, 177, 173, - 169, 171, 174, 176, 172, 167, 173, 174, 174, 173, 174, 177, 174, 166, 162, 162, - 161, 157, 147, 142, 152, 150, 138, 130, 129, 121, 117, 118, 118, 110, 110, 109, - 109, 113, 104, 112, 100, 23, 30, 57, 69, 84, 101, 104, 113, 110, 114, 95, - 107, 113, 110, 114, 106, 109, 111, 108, 114, 116, 109, 111, 116, 112, 111, 112, - 112, 113, 113, 112, 111, 111, 114, 115, 115, 115, 115, 114, 113, 112, 115, 115, - 115, 114, 114, 113, 113, 113, 111, 111, 112, 94, 93, 92, 91, 90, 90, 89, - 89, 94, 95, 94, 94, 92, 92, 92, 94, 94, 94, 94, 95, 95, 96, 96, - 96, 94, 94, 94, 95, 96, 96, 97, 97, 98, 97, 97, 98, 99, 100, 102, - 103, 102, 102, 101, 99, 97, 96, 93, 95, 104, 105, 104, 103, 103, 102, 101, - 102, 98, 103, 112, 111, 103, 107, 121, 125, 137, 140, 139, 140, 145, 149, 152, - 154, 156, 156, 157, 162, 169, 170, 167, 165, 176, 174, 181, 167, 184, 168, 180, - 187, 168, 177, 166, 170, 173, 159, 163, 166, 159, 160, 163, 167, 173, 177, 179, - 178, 172, 168, 174, 176, 169, 171, 178, 175, 176, 183, 179, 175, 179, 175, 171, - 178, 173, 171, 169, 172, 176, 175, 170, 163, 181, 176, 172, 172, 178, 180, 173, - 162, 165, 161, 160, 158, 151, 143, 144, 139, 125, 134, 142, 125, 115, 117, 117, - 108, 110, 109, 109, 113, 105, 110, 98, 22, 29, 57, 69, 84, 102, 105, 114, - 111, 115, 96, 108, 113, 110, 113, 105, 108, 112, 108, 114, 117, 110, 111, 116, - 112, 111, 111, 112, 113, 113, 112, 112, 111, 115, 116, 116, 116, 116, 115, 114, - 113, 115, 115, 115, 114, 114, 113, 113, 113, 111, 111, 112, 95, 95, 94, 93, - 93, 93, 93, 93, 93, 95, 95, 95, 93, 92, 91, 92, 94, 94, 94, 95, - 95, 96, 96, 96, 94, 95, 95, 96, 96, 97, 97, 97, 98, 97, 96, 95, - 97, 99, 102, 103, 100, 99, 100, 100, 99, 97, 94, 95, 99, 100, 100, 101, - 103, 102, 103, 104, 107, 111, 114, 104, 98, 110, 129, 131, 139, 143, 142, 142, - 146, 150, 155, 158, 157, 158, 160, 165, 168, 168, 164, 163, 174, 179, 176, 164, - 183, 168, 172, 185, 165, 174, 164, 170, 175, 162, 166, 169, 165, 160, 159, 167, - 172, 172, 172, 174, 175, 170, 176, 176, 168, 170, 177, 173, 173, 180, 176, 172, - 175, 171, 167, 174, 170, 172, 174, 175, 176, 175, 174, 172, 179, 174, 171, 170, - 175, 176, 170, 162, 168, 162, 160, 158, 153, 146, 143, 134, 118, 130, 142, 133, - 122, 121, 117, 110, 110, 107, 108, 113, 105, 109, 96, 19, 29, 57, 69, 85, - 102, 105, 115, 112, 115, 95, 108, 113, 110, 113, 106, 109, 112, 109, 115, 117, - 110, 111, 116, 111, 113, 113, 114, 115, 115, 115, 114, 114, 115, 115, 116, 116, - 115, 114, 113, 113, 115, 115, 115, 114, 114, 113, 113, 113, 112, 112, 112, 93, - 93, 93, 93, 94, 95, 96, 97, 93, 95, 95, 95, 93, 92, 91, 92, 94, - 94, 94, 95, 95, 96, 96, 96, 95, 96, 96, 96, 96, 97, 97, 97, 98, - 96, 95, 95, 96, 98, 102, 102, 98, 98, 100, 101, 99, 98, 95, 94, 95, - 96, 98, 101, 105, 106, 109, 111, 116, 111, 108, 98, 99, 118, 137, 137, 143, - 146, 145, 145, 146, 150, 154, 159, 152, 158, 165, 167, 166, 166, 165, 167, 172, - 183, 169, 174, 175, 174, 162, 179, 168, 177, 166, 172, 175, 160, 163, 166, 169, - 162, 161, 166, 171, 170, 169, 170, 177, 171, 175, 175, 168, 170, 177, 174, 172, - 179, 175, 172, 175, 171, 168, 174, 167, 173, 178, 177, 173, 173, 178, 183, 175, - 171, 172, 172, 172, 172, 171, 171, 174, 165, 159, 158, 157, 151, 147, 140, 128, - 128, 138, 145, 141, 129, 122, 116, 111, 107, 108, 111, 101, 105, 92, 16, 28, - 58, 70, 85, 103, 105, 115, 112, 112, 93, 106, 112, 110, 114, 108, 111, 113, - 110, 116, 118, 110, 111, 116, 111, 112, 113, 114, 115, 115, 115, 115, 115, 114, - 114, 114, 114, 114, 113, 112, 111, 115, 115, 115, 114, 114, 113, 113, 113, 112, - 112, 113, 89, 89, 90, 91, 92, 94, 95, 96, 94, 95, 94, 94, 92, 92, - 92, 94, 94, 94, 94, 95, 95, 96, 96, 96, 96, 96, 96, 97, 97, 97, - 97, 96, 97, 96, 96, 96, 97, 99, 101, 101, 98, 98, 99, 98, 99, 98, - 98, 96, 94, 96, 101, 106, 110, 112, 115, 117, 117, 105, 101, 101, 105, 125, - 141, 141, 147, 148, 150, 150, 150, 150, 155, 159, 153, 161, 167, 168, 167, 165, - 167, 170, 170, 179, 166, 179, 168, 174, 159, 170, 171, 179, 167, 169, 172, 158, - 161, 164, 167, 166, 165, 166, 169, 171, 172, 171, 173, 168, 172, 173, 167, 171, - 179, 177, 172, 179, 176, 172, 176, 173, 170, 177, 164, 171, 177, 175, 170, 170, - 177, 183, 172, 171, 176, 176, 173, 170, 174, 180, 176, 167, 160, 159, 159, 155, - 152, 148, 137, 128, 130, 142, 147, 137, 126, 120, 114, 109, 107, 109, 97, 103, - 90, 13, 30, 59, 71, 86, 103, 105, 114, 111, 111, 93, 106, 112, 111, 115, - 109, 112, 114, 111, 116, 118, 111, 111, 116, 111, 109, 110, 111, 112, 113, 113, - 113, 113, 113, 113, 114, 114, 113, 113, 112, 111, 115, 115, 115, 114, 114, 113, - 113, 113, 113, 113, 113, 91, 91, 91, 91, 92, 94, 94, 95, 94, 94, 93, - 92, 91, 92, 94, 96, 94, 94, 94, 95, 95, 96, 96, 96, 97, 97, 97, - 97, 97, 97, 97, 96, 96, 94, 97, 98, 99, 100, 101, 101, 98, 98, 98, - 97, 98, 98, 99, 98, 94, 98, 104, 109, 112, 115, 116, 117, 113, 101, 103, - 113, 120, 133, 145, 146, 149, 151, 154, 154, 155, 156, 158, 161, 161, 164, 167, - 169, 170, 169, 169, 169, 173, 166, 167, 175, 168, 168, 167, 164, 168, 176, 164, - 167, 171, 158, 163, 167, 162, 168, 170, 163, 162, 168, 172, 168, 171, 165, 171, - 171, 164, 168, 176, 174, 169, 176, 173, 170, 175, 172, 169, 176, 166, 169, 172, - 173, 172, 171, 172, 173, 175, 174, 176, 178, 174, 170, 174, 183, 175, 168, 163, - 164, 162, 157, 154, 153, 144, 138, 133, 133, 138, 140, 134, 122, 119, 112, 107, - 107, 94, 100, 86, 12, 31, 61, 73, 86, 103, 104, 113, 110, 113, 94, 107, - 113, 110, 114, 107, 110, 115, 111, 117, 119, 111, 111, 116, 111, 109, 110, 111, - 112, 113, 113, 113, 113, 114, 114, 115, 115, 114, 113, 113, 112, 115, 115, 115, - 114, 114, 113, 113, 113, 113, 113, 113, 95, 95, 94, 94, 94, 95, 95, 96, - 94, 94, 92, 91, 90, 92, 95, 98, 94, 94, 94, 95, 95, 96, 96, 96, - 97, 97, 97, 97, 97, 97, 97, 96, 96, 95, 98, 100, 101, 101, 101, 101, - 99, 99, 96, 96, 97, 99, 101, 101, 95, 98, 106, 112, 116, 116, 115, 117, - 112, 102, 111, 128, 134, 139, 149, 152, 150, 154, 158, 159, 158, 158, 162, 164, - 171, 169, 168, 169, 173, 173, 171, 167, 176, 156, 172, 167, 170, 160, 175, 162, - 161, 168, 157, 163, 170, 161, 170, 175, 158, 170, 170, 157, 155, 163, 166, 160, - 175, 169, 170, 169, 162, 165, 172, 169, 164, 171, 169, 166, 172, 169, 168, 174, - 171, 169, 171, 174, 178, 176, 170, 163, 177, 173, 174, 176, 174, 169, 172, 179, - 174, 169, 168, 168, 166, 158, 153, 154, 155, 158, 147, 132, 134, 149, 148, 130, - 125, 116, 109, 107, 95, 97, 83, 11, 32, 62, 73, 87, 103, 104, 112, 109, - 115, 96, 108, 113, 110, 113, 105, 108, 115, 112, 117, 119, 111, 111, 116, 111, - 111, 112, 113, 114, 115, 116, 116, 116, 115, 116, 116, 116, 116, 115, 114, 113, - 115, 115, 115, 114, 114, 113, 113, 113, 113, 113, 113, 89, 94, 95, 92, 91, - 94, 94, 93, 95, 95, 93, 94, 94, 95, 94, 94, 97, 96, 95, 94, 94, - 94, 95, 95, 91, 96, 99, 99, 100, 102, 101, 95, 97, 95, 95, 98, 99, - 96, 94, 98, 99, 97, 96, 96, 98, 99, 98, 97, 102, 107, 110, 111, 119, - 125, 119, 105, 109, 113, 118, 125, 135, 144, 151, 155, 158, 156, 154, 154, 158, - 160, 162, 162, 166, 172, 176, 170, 167, 168, 168, 164, 179, 170, 164, 165, 169, - 166, 164, 163, 165, 162, 163, 164, 164, 161, 165, 171, 169, 165, 169, 169, 160, - 158, 163, 161, 170, 166, 166, 169, 168, 164, 166, 172, 166, 171, 173, 165, 164, - 165, 173, 173, 167, 170, 174, 171, 174, 175, 176, 171, 175, 178, 166, 175, 181, - 178, 183, 174, 168, 174, 171, 165, 165, 159, 153, 161, 161, 156, 148, 140, 136, - 137, 140, 140, 135, 119, 111, 124, 96, 98, 71, 11, 33, 60, 72, 88, 104, - 102, 111, 110, 112, 98, 111, 113, 109, 115, 109, 110, 113, 114, 116, 115, 113, - 111, 111, 112, 116, 116, 115, 114, 114, 113, 112, 112, 115, 115, 115, 114, 114, - 113, 113, 113, 114, 114, 114, 114, 114, 114, 114, 114, 116, 115, 115, 89, 94, - 95, 92, 91, 94, 94, 93, 95, 95, 93, 94, 94, 95, 94, 94, 94, 94, - 94, 94, 94, 95, 97, 97, 93, 97, 99, 98, 98, 101, 101, 97, 99, 95, - 95, 98, 99, 96, 95, 98, 96, 97, 98, 101, 103, 104, 104, 103, 100, 108, - 117, 121, 123, 121, 112, 103, 116, 121, 124, 129, 137, 144, 151, 153, 156, 156, - 155, 155, 157, 158, 162, 163, 157, 164, 169, 167, 166, 170, 170, 168, 174, 166, - 162, 163, 165, 162, 161, 160, 167, 163, 162, 164, 164, 163, 165, 168, 168, 165, - 171, 173, 163, 160, 163, 158, 163, 161, 164, 168, 167, 162, 164, 169, 164, 167, - 167, 165, 167, 171, 171, 168, 168, 171, 172, 170, 170, 173, 172, 169, 175, 177, - 167, 174, 178, 173, 179, 169, 176, 179, 171, 168, 172, 168, 161, 166, 157, 158, - 155, 148, 138, 135, 136, 136, 146, 132, 119, 125, 100, 107, 74, 11, 33, 60, - 72, 89, 105, 103, 110, 110, 111, 97, 111, 113, 109, 115, 109, 111, 112, 113, - 115, 115, 113, 112, 112, 113, 114, 114, 114, 114, 114, 114, 114, 114, 115, 115, - 115, 114, 114, 113, 113, 113, 114, 114, 114, 114, 114, 114, 114, 114, 115, 115, - 114, 90, 94, 96, 92, 91, 94, 95, 93, 95, 95, 93, 94, 94, 95, 94, - 94, 93, 93, 93, 94, 95, 96, 98, 99, 95, 98, 98, 96, 97, 101, 101, - 98, 100, 96, 96, 100, 99, 96, 97, 100, 94, 97, 102, 105, 106, 105, 106, - 108, 107, 112, 118, 122, 119, 111, 107, 112, 123, 126, 128, 132, 136, 143, 148, - 151, 153, 156, 158, 157, 156, 156, 160, 163, 154, 160, 165, 165, 165, 168, 170, - 170, 168, 164, 164, 165, 165, 161, 161, 162, 167, 161, 159, 160, 162, 158, 158, - 160, 163, 162, 171, 175, 166, 163, 165, 156, 157, 158, 163, 167, 166, 162, 162, - 165, 162, 163, 162, 163, 169, 174, 171, 164, 168, 171, 170, 166, 165, 168, 169, - 166, 172, 175, 165, 172, 174, 169, 174, 165, 175, 174, 166, 164, 172, 169, 160, - 161, 154, 159, 162, 154, 142, 134, 133, 131, 150, 139, 129, 126, 102, 115, 74, - 13, 33, 61, 73, 90, 106, 103, 110, 109, 110, 95, 110, 112, 109, 115, 110, - 112, 110, 112, 114, 114, 113, 112, 113, 114, 112, 112, 113, 114, 114, 115, 116, - 116, 115, 115, 114, 114, 114, 114, 113, 113, 114, 114, 114, 114, 114, 114, 114, - 114, 113, 113, 114, 90, 95, 96, 93, 92, 94, 95, 93, 95, 95, 93, 94, - 94, 95, 94, 94, 94, 93, 93, 94, 95, 96, 97, 98, 96, 99, 98, 95, - 96, 100, 101, 99, 100, 97, 98, 100, 100, 97, 97, 100, 96, 100, 103, 105, - 104, 104, 106, 110, 125, 118, 113, 114, 112, 108, 116, 129, 129, 130, 131, 134, - 136, 142, 144, 147, 150, 156, 160, 159, 156, 156, 160, 165, 162, 165, 168, 168, - 168, 167, 168, 168, 165, 164, 166, 168, 167, 161, 162, 165, 168, 161, 158, 158, - 159, 156, 155, 157, 157, 157, 166, 169, 163, 164, 166, 157, 154, 156, 159, 160, - 160, 161, 162, 164, 161, 163, 163, 162, 165, 170, 168, 163, 164, 166, 165, 161, - 161, 165, 166, 164, 167, 171, 161, 167, 169, 164, 171, 163, 165, 169, 162, 160, - 167, 166, 159, 163, 158, 162, 163, 157, 148, 142, 138, 134, 142, 143, 139, 128, - 105, 116, 67, 12, 33, 61, 74, 91, 107, 103, 110, 108, 108, 94, 109, 112, - 109, 116, 110, 112, 109, 112, 114, 114, 113, 113, 114, 115, 113, 113, 113, 114, - 114, 115, 115, 115, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 112, 113, 113, 91, 95, 97, 93, 92, 95, 95, 94, 95, - 95, 93, 94, 94, 95, 94, 94, 96, 95, 95, 94, 94, 95, 95, 96, 97, - 99, 99, 95, 96, 100, 100, 98, 103, 100, 100, 102, 102, 98, 99, 102, 100, - 102, 103, 104, 106, 107, 111, 117, 130, 119, 110, 111, 116, 117, 127, 140, 132, - 132, 135, 135, 138, 140, 143, 145, 150, 156, 161, 160, 157, 156, 160, 165, 165, - 166, 168, 169, 169, 163, 165, 166, 166, 166, 167, 170, 168, 162, 163, 166, 171, - 165, 162, 161, 161, 157, 157, 157, 154, 154, 160, 161, 157, 164, 169, 158, 154, - 157, 157, 155, 155, 158, 162, 165, 161, 165, 165, 159, 157, 160, 164, 164, 158, - 160, 159, 156, 157, 162, 164, 162, 161, 166, 158, 165, 167, 162, 171, 164, 162, - 170, 167, 163, 168, 166, 165, 172, 163, 158, 156, 153, 153, 150, 146, 140, 136, - 142, 148, 135, 111, 117, 59, 16, 35, 62, 75, 91, 106, 103, 110, 108, 108, - 94, 108, 111, 108, 115, 110, 112, 109, 112, 114, 114, 113, 113, 114, 115, 115, - 115, 115, 114, 114, 113, 113, 113, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 112, 113, 113, 91, 95, 97, 94, 93, 95, - 96, 94, 95, 95, 93, 94, 94, 95, 94, 94, 97, 96, 95, 94, 94, 94, - 94, 95, 96, 99, 99, 97, 97, 100, 100, 99, 104, 101, 102, 104, 104, 100, - 100, 102, 102, 102, 102, 105, 110, 114, 114, 119, 118, 117, 115, 119, 127, 132, - 137, 140, 135, 135, 135, 137, 138, 140, 142, 145, 150, 157, 161, 162, 161, 160, - 163, 165, 164, 164, 166, 169, 167, 163, 163, 166, 168, 166, 165, 167, 166, 163, - 161, 164, 166, 163, 160, 159, 156, 152, 152, 156, 155, 151, 157, 153, 152, 163, - 168, 158, 156, 157, 157, 151, 151, 156, 163, 164, 161, 165, 165, 157, 153, 155, - 160, 163, 154, 157, 158, 155, 157, 161, 163, 161, 156, 163, 155, 163, 164, 160, - 169, 164, 160, 170, 168, 165, 168, 166, 166, 176, 162, 154, 149, 149, 153, 155, - 150, 144, 136, 139, 151, 140, 119, 120, 53, 23, 37, 64, 75, 90, 105, 102, - 111, 110, 108, 94, 108, 111, 108, 114, 109, 111, 110, 112, 114, 114, 113, 112, - 113, 114, 116, 116, 115, 114, 114, 113, 112, 112, 113, 113, 114, 114, 114, 114, - 115, 115, 114, 114, 114, 114, 114, 114, 114, 114, 113, 113, 114, 91, 96, 97, - 94, 93, 96, 96, 95, 95, 95, 93, 94, 94, 95, 94, 94, 95, 95, 94, - 94, 94, 95, 96, 96, 95, 99, 100, 98, 98, 100, 99, 97, 106, 103, 102, - 104, 105, 100, 100, 103, 105, 102, 103, 106, 113, 112, 107, 107, 101, 113, 121, - 125, 132, 137, 142, 140, 137, 135, 137, 138, 139, 140, 141, 145, 152, 157, 159, - 162, 163, 164, 164, 164, 165, 164, 166, 170, 169, 163, 163, 168, 175, 168, 164, - 167, 167, 165, 163, 164, 163, 164, 163, 161, 155, 148, 152, 160, 156, 154, 157, - 152, 149, 160, 163, 152, 155, 158, 158, 153, 151, 156, 161, 160, 156, 159, 159, - 154, 153, 157, 158, 156, 154, 157, 158, 156, 157, 160, 160, 157, 156, 163, 156, - 162, 163, 157, 167, 162, 162, 167, 164, 160, 165, 163, 162, 168, 157, 153, 151, - 152, 155, 155, 153, 147, 142, 134, 141, 135, 123, 121, 47, 26, 40, 65, 74, - 89, 103, 102, 111, 112, 109, 95, 109, 111, 107, 113, 107, 109, 112, 113, 115, - 115, 113, 112, 112, 113, 114, 114, 114, 114, 114, 114, 114, 114, 113, 113, 113, - 114, 114, 115, 115, 115, 114, 114, 114, 114, 114, 114, 114, 114, 115, 115, 114, - 91, 95, 97, 93, 93, 95, 96, 95, 95, 95, 93, 94, 94, 95, 94, 94, - 92, 93, 93, 94, 95, 96, 98, 99, 94, 99, 101, 99, 99, 99, 97, 96, - 106, 105, 102, 102, 102, 98, 96, 100, 103, 102, 103, 109, 118, 116, 104, 99, - 102, 124, 132, 127, 126, 134, 139, 139, 133, 134, 136, 137, 141, 143, 144, 149, - 154, 157, 159, 162, 166, 167, 166, 164, 172, 169, 171, 175, 172, 165, 164, 169, - 182, 173, 167, 169, 172, 169, 167, 166, 170, 170, 172, 169, 159, 154, 160, 169, - 159, 157, 160, 154, 150, 160, 161, 145, 154, 159, 160, 155, 154, 158, 159, 155, - 152, 151, 152, 152, 156, 160, 157, 150, 156, 160, 161, 158, 158, 160, 158, 154, - 155, 162, 154, 160, 159, 153, 164, 161, 169, 170, 163, 160, 169, 168, 164, 164, - 155, 154, 159, 158, 157, 155, 154, 152, 147, 131, 134, 133, 129, 132, 54, 36, - 49, 73, 78, 92, 103, 101, 110, 110, 108, 94, 107, 110, 107, 113, 107, 109, - 113, 114, 116, 115, 113, 111, 111, 112, 112, 112, 113, 114, 114, 115, 116, 116, - 113, 113, 113, 114, 114, 115, 115, 115, 114, 114, 114, 114, 114, 114, 114, 114, - 116, 115, 115, 92, 89, 91, 89, 92, 92, 94, 95, 96, 92, 90, 94, 95, - 93, 91, 92, 92, 98, 94, 92, 98, 96, 93, 99, 98, 101, 101, 98, 99, - 101, 102, 101, 102, 104, 103, 100, 94, 89, 86, 88, 96, 99, 105, 117, 125, - 122, 118, 120, 137, 143, 143, 136, 133, 131, 130, 130, 132, 128, 134, 139, 140, - 150, 158, 154, 157, 169, 168, 164, 170, 173, 171, 176, 175, 177, 176, 175, 176, - 177, 170, 162, 194, 174, 178, 185, 173, 169, 174, 166, 181, 169, 161, 164, 166, - 165, 162, 165, 170, 159, 154, 155, 163, 165, 163, 162, 169, 165, 159, 157, 158, - 160, 159, 156, 150, 149, 151, 148, 145, 145, 148, 153, 159, 159, 160, 152, 150, - 164, 167, 149, 155, 146, 155, 164, 155, 147, 152, 157, 168, 166, 166, 166, 169, - 171, 173, 170, 168, 160, 154, 153, 157, 159, 155, 151, 156, 140, 133, 132, 131, - 124, 98, 53, 74, 88, 99, 98, 104, 105, 100, 102, 103, 87, 102, 106, 106, - 112, 109, 113, 112, 112, 115, 115, 113, 113, 117, 118, 113, 113, 113, 114, 113, - 114, 114, 114, 116, 115, 113, 111, 110, 110, 110, 111, 113, 113, 113, 113, 113, - 113, 113, 113, 115, 115, 114, 93, 92, 92, 91, 92, 94, 95, 96, 96, 91, - 90, 94, 95, 93, 92, 93, 92, 97, 94, 92, 98, 96, 94, 98, 94, 97, - 98, 94, 94, 96, 96, 96, 104, 106, 102, 97, 92, 87, 86, 90, 91, 103, - 114, 117, 114, 114, 125, 146, 153, 155, 148, 140, 134, 131, 129, 127, 133, 126, - 133, 139, 139, 144, 149, 145, 160, 168, 163, 156, 162, 165, 167, 173, 161, 162, - 162, 162, 165, 168, 165, 159, 168, 154, 159, 165, 159, 163, 172, 164, 154, 153, - 156, 165, 165, 160, 158, 161, 157, 155, 154, 154, 150, 146, 149, 155, 148, 146, - 145, 146, 149, 150, 148, 145, 143, 144, 145, 144, 144, 144, 149, 153, 135, 139, - 149, 152, 149, 155, 152, 134, 150, 140, 146, 157, 151, 148, 156, 160, 157, 156, - 158, 159, 162, 163, 163, 159, 152, 152, 155, 159, 164, 164, 160, 156, 153, 148, - 148, 141, 127, 125, 122, 102, 95, 98, 103, 108, 116, 111, 103, 104, 98, 86, - 105, 110, 108, 113, 111, 116, 112, 112, 115, 115, 113, 113, 115, 116, 113, 113, - 113, 114, 113, 114, 113, 113, 116, 115, 113, 112, 111, 111, 111, 112, 113, 113, - 113, 113, 113, 113, 113, 113, 115, 114, 113, 94, 93, 93, 92, 92, 93, 94, - 94, 96, 91, 90, 94, 96, 93, 92, 94, 92, 98, 94, 92, 99, 97, 93, - 98, 93, 95, 96, 91, 91, 94, 94, 92, 104, 102, 99, 95, 92, 91, 92, - 97, 101, 107, 112, 111, 107, 112, 131, 154, 149, 146, 140, 135, 135, 133, 132, - 129, 139, 127, 128, 136, 134, 137, 148, 147, 141, 153, 158, 158, 163, 159, 150, - 149, 152, 153, 153, 153, 156, 160, 157, 152, 165, 158, 156, 150, 140, 143, 146, - 134, 142, 147, 155, 162, 163, 158, 160, 161, 157, 152, 153, 152, 147, 141, 142, - 147, 161, 160, 158, 156, 154, 148, 141, 137, 131, 134, 135, 134, 134, 135, 137, - 139, 136, 130, 133, 136, 131, 136, 139, 135, 137, 127, 128, 136, 132, 133, 141, - 142, 137, 141, 148, 154, 156, 152, 145, 140, 153, 152, 151, 152, 152, 154, 155, - 156, 154, 153, 156, 147, 130, 129, 139, 130, 111, 106, 108, 116, 128, 122, 113, - 115, 99, 89, 109, 112, 107, 112, 109, 113, 111, 111, 114, 114, 112, 112, 114, - 115, 112, 112, 113, 113, 113, 113, 114, 114, 116, 115, 114, 113, 112, 112, 112, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 114, 114, 113, 92, 91, 91, 91, - 90, 90, 91, 91, 96, 91, 90, 94, 96, 94, 93, 95, 93, 98, 95, 93, - 99, 97, 93, 98, 95, 96, 96, 93, 93, 97, 97, 94, 99, 96, 92, 91, - 92, 95, 99, 104, 116, 108, 103, 109, 121, 132, 142, 148, 143, 138, 135, 136, - 139, 137, 136, 134, 139, 122, 122, 133, 134, 143, 162, 171, 177, 190, 197, 199, - 205, 200, 189, 187, 189, 191, 191, 190, 191, 192, 186, 178, 185, 188, 186, 176, - 173, 182, 185, 177, 185, 186, 185, 184, 184, 187, 194, 199, 193, 183, 181, 183, - 186, 180, 176, 173, 177, 176, 179, 179, 180, 177, 175, 173, 178, 179, 181, 179, - 178, 175, 175, 175, 179, 166, 166, 166, 159, 158, 164, 168, 168, 156, 153, 156, - 155, 155, 159, 157, 169, 158, 144, 131, 126, 127, 132, 139, 148, 151, 150, 149, - 148, 150, 154, 155, 161, 153, 155, 154, 148, 148, 148, 130, 120, 121, 119, 118, - 128, 130, 127, 127, 110, 97, 110, 109, 105, 112, 108, 109, 110, 111, 113, 113, - 112, 112, 114, 115, 113, 113, 113, 113, 113, 113, 113, 113, 116, 115, 115, 114, - 114, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 112, 91, - 91, 91, 91, 91, 91, 90, 90, 96, 91, 91, 95, 97, 95, 94, 96, 94, - 100, 96, 94, 99, 97, 93, 96, 94, 96, 97, 94, 95, 96, 96, 93, 94, - 91, 90, 92, 98, 103, 109, 115, 117, 108, 106, 118, 137, 148, 148, 142, 141, - 134, 135, 142, 144, 140, 138, 136, 137, 125, 131, 143, 147, 158, 176, 183, 174, - 178, 171, 165, 172, 178, 182, 190, 198, 201, 203, 203, 204, 202, 193, 183, 195, - 204, 201, 191, 193, 201, 201, 199, 201, 198, 191, 187, 189, 194, 201, 204, 193, - 190, 193, 195, 193, 186, 186, 189, 192, 190, 189, 186, 184, 181, 181, 180, 176, - 174, 173, 172, 171, 170, 171, 170, 184, 177, 186, 191, 183, 175, 173, 172, 197, - 184, 180, 180, 179, 181, 184, 178, 178, 173, 164, 154, 142, 131, 119, 118, 123, - 134, 141, 148, 153, 155, 155, 155, 162, 152, 155, 160, 159, 159, 156, 138, 125, - 137, 134, 121, 125, 137, 138, 136, 127, 108, 114, 109, 105, 115, 107, 104, 108, - 109, 111, 111, 111, 111, 113, 114, 112, 112, 113, 113, 113, 113, 114, 114, 115, - 115, 115, 115, 114, 114, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 112, - 112, 111, 92, 92, 93, 94, 94, 94, 93, 93, 95, 91, 91, 95, 97, 96, - 95, 97, 95, 100, 96, 94, 100, 97, 91, 96, 92, 95, 95, 92, 91, 94, - 94, 91, 91, 89, 91, 98, 107, 113, 115, 119, 107, 113, 123, 135, 144, 145, - 147, 145, 134, 128, 133, 140, 138, 132, 129, 131, 136, 137, 151, 163, 163, 169, - 178, 173, 169, 174, 168, 162, 170, 176, 180, 189, 176, 180, 183, 184, 187, 187, - 179, 169, 187, 196, 190, 182, 186, 185, 182, 186, 185, 186, 185, 182, 182, 187, - 189, 187, 175, 186, 197, 196, 182, 173, 182, 197, 199, 197, 193, 188, 184, 183, - 185, 184, 179, 174, 172, 173, 175, 177, 178, 178, 174, 170, 176, 176, 168, 168, - 171, 169, 185, 175, 175, 176, 176, 179, 182, 174, 171, 177, 186, 189, 183, 167, - 146, 139, 128, 130, 123, 121, 126, 134, 142, 146, 151, 149, 155, 161, 154, 155, - 164, 160, 135, 148, 143, 128, 129, 137, 139, 139, 136, 119, 125, 115, 109, 118, - 110, 106, 108, 109, 111, 111, 109, 109, 113, 114, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 114, 114, 114, 114, 113, 112, 113, 113, 113, 113, 113, 113, - 113, 113, 111, 111, 111, 90, 91, 93, 94, 95, 95, 94, 93, 95, 91, 91, - 95, 98, 96, 96, 97, 97, 102, 97, 95, 100, 97, 91, 96, 91, 92, 92, - 89, 92, 95, 96, 90, 89, 87, 92, 100, 111, 116, 116, 117, 113, 126, 138, - 149, 150, 145, 146, 147, 129, 122, 127, 133, 131, 123, 127, 133, 145, 153, 167, - 169, 163, 170, 173, 159, 161, 173, 176, 175, 182, 182, 177, 180, 179, 181, 182, - 183, 187, 190, 186, 179, 179, 189, 187, 189, 200, 196, 193, 208, 192, 199, 202, - 197, 194, 196, 197, 195, 198, 204, 211, 211, 202, 196, 201, 212, 189, 191, 193, - 195, 198, 203, 211, 215, 187, 182, 178, 178, 181, 184, 187, 188, 191, 188, 188, - 177, 167, 178, 191, 185, 178, 171, 174, 176, 175, 179, 182, 174, 189, 183, 174, - 169, 171, 177, 182, 192, 169, 157, 136, 124, 124, 127, 131, 134, 139, 139, 149, - 158, 153, 154, 165, 167, 153, 153, 147, 144, 146, 137, 131, 139, 132, 122, 136, - 126, 112, 116, 111, 108, 110, 111, 113, 113, 109, 109, 111, 112, 111, 111, 113, - 112, 113, 112, 113, 113, 111, 112, 113, 114, 114, 113, 112, 111, 113, 113, 113, - 113, 113, 113, 113, 113, 111, 110, 110, 87, 88, 90, 92, 93, 93, 92, 92, - 95, 91, 91, 95, 98, 96, 96, 98, 97, 103, 97, 94, 100, 95, 91, 96, - 90, 93, 93, 92, 93, 97, 97, 94, 89, 88, 95, 105, 114, 117, 115, 115, - 133, 137, 146, 154, 156, 151, 147, 144, 130, 123, 127, 133, 127, 121, 129, 142, - 152, 158, 168, 159, 153, 164, 170, 157, 168, 178, 174, 169, 175, 178, 178, 184, - 185, 185, 182, 181, 185, 190, 189, 184, 193, 199, 193, 192, 199, 183, 174, 192, - 194, 203, 206, 195, 185, 185, 191, 194, 209, 199, 193, 198, 206, 205, 200, 196, - 208, 208, 206, 200, 194, 191, 192, 193, 200, 192, 188, 186, 188, 191, 193, 194, - 186, 195, 201, 191, 179, 186, 190, 174, 172, 168, 173, 176, 172, 177, 179, 169, - 168, 169, 171, 173, 175, 172, 166, 166, 190, 184, 174, 168, 165, 155, 138, 127, - 130, 125, 134, 149, 153, 155, 155, 151, 167, 152, 144, 160, 163, 136, 126, 140, - 125, 125, 147, 134, 115, 116, 111, 111, 112, 113, 114, 113, 111, 109, 111, 112, - 111, 111, 113, 112, 113, 112, 113, 113, 110, 111, 112, 113, 114, 113, 112, 111, - 113, 113, 113, 113, 113, 113, 113, 113, 110, 110, 110, 90, 94, 94, 91, 92, - 95, 95, 93, 96, 96, 97, 97, 97, 98, 98, 98, 102, 101, 98, 96, 95, - 91, 91, 90, 96, 94, 92, 92, 94, 97, 100, 101, 93, 97, 110, 113, 107, - 111, 129, 137, 138, 152, 161, 157, 150, 147, 139, 130, 126, 134, 136, 124, 115, - 123, 142, 156, 164, 160, 163, 165, 166, 165, 168, 170, 166, 170, 176, 183, 184, - 181, 181, 185, 190, 182, 177, 181, 192, 199, 199, 195, 194, 193, 194, 192, 190, - 191, 196, 198, 198, 199, 201, 203, 205, 206, 208, 205, 203, 194, 190, 194, 199, - 199, 197, 195, 208, 201, 208, 203, 184, 191, 205, 200, 197, 206, 209, 203, 198, - 197, 195, 192, 194, 204, 203, 190, 184, 191, 198, 193, 182, 169, 167, 169, 168, - 176, 184, 180, 180, 175, 168, 170, 180, 184, 177, 168, 166, 164, 164, 172, 178, - 175, 160, 149, 129, 121, 120, 131, 138, 134, 138, 153, 155, 160, 158, 153, 149, - 147, 145, 142, 136, 117, 114, 132, 135, 122, 114, 117, 119, 120, 116, 108, 107, - 110, 111, 110, 110, 111, 113, 112, 111, 111, 114, 116, 113, 114, 114, 114, 114, - 113, 112, 111, 114, 114, 114, 113, 113, 112, 112, 112, 113, 113, 113, 91, 94, - 94, 91, 92, 95, 96, 93, 94, 94, 94, 95, 95, 96, 96, 96, 99, 99, - 96, 95, 94, 93, 93, 94, 89, 94, 99, 101, 100, 101, 102, 102, 104, 99, - 105, 108, 105, 115, 130, 134, 146, 153, 153, 148, 143, 140, 136, 129, 129, 128, - 128, 130, 139, 149, 153, 148, 156, 155, 160, 163, 168, 170, 174, 176, 172, 171, - 176, 182, 187, 183, 185, 185, 185, 179, 179, 181, 191, 194, 194, 188, 194, 195, - 197, 196, 194, 192, 194, 195, 196, 198, 200, 202, 205, 207, 211, 207, 196, 195, - 197, 200, 201, 200, 199, 199, 201, 196, 204, 205, 195, 201, 208, 198, 202, 208, - 207, 201, 199, 204, 206, 204, 183, 199, 210, 204, 200, 197, 190, 178, 187, 176, - 178, 174, 162, 164, 173, 172, 187, 183, 179, 179, 180, 179, 173, 162, 155, 151, - 151, 157, 166, 171, 168, 165, 177, 150, 126, 120, 126, 127, 124, 130, 145, 148, - 147, 152, 158, 158, 147, 135, 139, 129, 124, 131, 136, 135, 129, 124, 119, 121, - 121, 115, 111, 110, 112, 110, 110, 111, 113, 112, 111, 111, 114, 116, 113, 114, - 114, 114, 114, 113, 112, 111, 114, 114, 114, 113, 113, 112, 112, 112, 113, 113, - 113, 91, 94, 94, 92, 92, 95, 96, 93, 94, 94, 95, 95, 95, 96, 96, - 96, 96, 96, 95, 95, 95, 95, 96, 97, 91, 97, 102, 105, 106, 105, 108, - 111, 116, 107, 106, 110, 115, 130, 143, 144, 156, 157, 154, 146, 139, 135, 128, - 120, 121, 123, 129, 140, 154, 163, 157, 143, 149, 151, 155, 161, 167, 171, 176, - 177, 175, 169, 173, 177, 183, 180, 182, 182, 179, 177, 181, 182, 187, 186, 187, - 182, 188, 191, 193, 193, 190, 187, 188, 187, 190, 192, 193, 196, 199, 203, 207, - 207, 191, 195, 202, 203, 199, 196, 195, 196, 209, 203, 204, 202, 196, 200, 202, - 190, 204, 209, 211, 212, 213, 214, 210, 204, 187, 195, 199, 190, 189, 194, 196, - 194, 183, 182, 187, 180, 164, 164, 178, 183, 176, 177, 178, 179, 179, 177, 174, - 168, 162, 155, 153, 154, 160, 162, 163, 162, 166, 175, 174, 156, 129, 109, 108, - 121, 142, 142, 138, 138, 145, 148, 144, 138, 139, 138, 133, 127, 132, 143, 143, - 134, 122, 126, 127, 122, 115, 113, 112, 112, 110, 111, 111, 112, 111, 111, 114, - 116, 113, 114, 114, 114, 114, 113, 112, 111, 114, 114, 114, 113, 113, 112, 112, - 112, 113, 113, 113, 91, 94, 95, 92, 92, 96, 96, 93, 97, 97, 97, 98, - 98, 98, 99, 99, 97, 95, 94, 94, 96, 96, 96, 98, 101, 101, 102, 104, - 106, 110, 113, 117, 117, 110, 112, 120, 126, 143, 159, 160, 159, 159, 154, 145, - 133, 123, 114, 108, 116, 131, 147, 154, 154, 154, 150, 145, 149, 150, 156, 162, - 167, 171, 175, 176, 173, 169, 173, 174, 175, 170, 175, 178, 179, 178, 182, 180, - 182, 180, 182, 183, 183, 185, 187, 187, 185, 184, 183, 184, 188, 188, 189, 191, - 193, 197, 199, 201, 194, 199, 203, 201, 197, 195, 194, 193, 217, 212, 206, 198, - 194, 199, 204, 201, 198, 195, 195, 192, 196, 195, 194, 188, 202, 200, 190, 177, - 173, 182, 193, 200, 187, 187, 192, 187, 171, 173, 187, 192, 177, 174, 174, 177, - 179, 178, 177, 175, 165, 162, 162, 161, 159, 155, 152, 150, 160, 165, 169, 166, - 158, 144, 121, 107, 121, 130, 131, 132, 134, 138, 143, 146, 140, 142, 141, 131, - 129, 137, 145, 144, 132, 130, 131, 126, 120, 119, 116, 110, 112, 111, 111, 110, - 111, 111, 114, 116, 113, 114, 114, 114, 114, 113, 112, 111, 114, 114, 114, 113, - 113, 112, 112, 112, 113, 113, 113, 92, 95, 95, 93, 93, 96, 97, 94, 97, - 97, 98, 98, 99, 99, 99, 99, 98, 97, 96, 95, 96, 95, 96, 96, 105, - 103, 103, 108, 114, 116, 112, 112, 112, 113, 122, 129, 133, 147, 161, 164, 152, - 150, 144, 133, 120, 110, 110, 111, 129, 143, 159, 164, 157, 154, 155, 153, 157, - 160, 164, 168, 171, 174, 176, 176, 172, 173, 178, 178, 171, 165, 170, 179, 179, - 179, 179, 176, 175, 174, 179, 182, 182, 183, 184, 183, 181, 182, 185, 188, 188, - 188, 188, 188, 190, 191, 192, 194, 202, 207, 207, 203, 203, 207, 207, 203, 209, - 215, 212, 205, 205, 211, 218, 224, 227, 214, 202, 196, 199, 204, 212, 215, 203, - 203, 198, 189, 183, 181, 179, 178, 199, 197, 198, 194, 181, 182, 188, 188, 195, - 184, 176, 179, 181, 179, 175, 175, 169, 168, 167, 167, 162, 159, 159, 158, 159, - 159, 156, 156, 160, 160, 147, 137, 102, 109, 115, 125, 137, 143, 144, 144, 144, - 144, 144, 140, 130, 127, 140, 149, 142, 135, 133, 128, 126, 124, 117, 109, 113, - 113, 111, 110, 111, 111, 114, 116, 113, 114, 114, 114, 114, 113, 112, 111, 114, - 114, 114, 113, 113, 112, 112, 112, 113, 113, 113, 92, 95, 96, 93, 93, 97, - 97, 94, 95, 96, 96, 96, 97, 97, 97, 98, 100, 99, 98, 96, 96, 94, - 95, 97, 100, 101, 106, 114, 119, 115, 103, 101, 117, 126, 138, 143, 142, 148, - 162, 161, 154, 144, 134, 126, 119, 121, 133, 139, 146, 145, 151, 156, 160, 166, - 163, 155, 162, 165, 169, 171, 171, 172, 174, 175, 174, 176, 184, 183, 178, 170, - 176, 183, 182, 179, 178, 174, 174, 173, 178, 181, 185, 187, 188, 185, 186, 188, - 193, 197, 189, 189, 189, 190, 189, 188, 187, 188, 196, 202, 202, 198, 201, 209, - 211, 206, 195, 211, 212, 207, 210, 208, 207, 214, 201, 195, 196, 197, 201, 197, - 197, 199, 198, 197, 197, 195, 192, 188, 184, 184, 197, 191, 195, 193, 186, 189, - 194, 189, 192, 180, 173, 178, 183, 180, 177, 179, 184, 180, 174, 167, 164, 163, - 165, 167, 153, 161, 167, 164, 156, 151, 154, 165, 138, 122, 105, 105, 123, 139, - 142, 140, 146, 147, 148, 147, 137, 128, 136, 144, 139, 135, 135, 132, 129, 126, - 120, 111, 113, 113, 111, 110, 110, 111, 114, 116, 113, 114, 114, 114, 114, 113, - 112, 111, 114, 114, 114, 113, 113, 112, 112, 112, 113, 113, 113, 92, 95, 96, - 93, 94, 97, 97, 94, 96, 96, 96, 97, 97, 97, 98, 98, 100, 99, 98, - 96, 96, 95, 97, 99, 99, 103, 108, 109, 107, 101, 97, 101, 131, 140, 151, - 156, 151, 156, 164, 162, 154, 140, 131, 133, 141, 149, 159, 160, 146, 139, 142, - 147, 159, 168, 167, 160, 169, 171, 172, 174, 172, 170, 169, 171, 177, 177, 182, - 186, 188, 183, 184, 187, 187, 184, 184, 182, 183, 182, 184, 184, 190, 192, 194, - 194, 194, 193, 196, 198, 193, 194, 196, 197, 196, 194, 190, 186, 187, 196, 200, - 194, 193, 199, 201, 197, 192, 208, 205, 199, 205, 201, 192, 200, 202, 204, 212, - 219, 218, 208, 202, 202, 204, 199, 196, 196, 197, 198, 200, 201, 192, 188, 195, - 197, 191, 193, 199, 194, 179, 170, 171, 180, 182, 176, 175, 185, 196, 193, 183, - 175, 170, 168, 166, 163, 172, 159, 152, 163, 173, 167, 155, 149, 171, 151, 124, - 111, 116, 127, 139, 145, 147, 152, 151, 146, 143, 143, 142, 132, 124, 127, 139, - 137, 130, 125, 118, 114, 114, 113, 111, 110, 110, 110, 113, 115, 113, 114, 114, - 114, 114, 113, 112, 111, 114, 114, 114, 113, 113, 112, 112, 112, 113, 113, 113, - 91, 95, 95, 92, 94, 97, 99, 97, 100, 100, 101, 101, 101, 100, 100, 100, - 99, 97, 97, 96, 94, 95, 98, 101, 103, 110, 111, 106, 97, 95, 101, 116, - 140, 144, 153, 156, 153, 158, 164, 155, 144, 128, 123, 136, 153, 161, 162, 153, - 144, 143, 149, 151, 155, 164, 169, 171, 175, 177, 180, 180, 179, 176, 174, 177, - 175, 172, 173, 183, 191, 191, 187, 184, 189, 188, 188, 189, 190, 190, 188, 186, - 188, 191, 195, 195, 195, 194, 194, 194, 193, 195, 197, 199, 199, 196, 193, 187, - 190, 205, 213, 204, 195, 196, 198, 195, 200, 212, 202, 195, 210, 211, 203, 211, - 218, 212, 206, 203, 198, 194, 200, 211, 209, 208, 205, 206, 204, 199, 193, 191, - 199, 197, 203, 203, 189, 187, 191, 187, 181, 179, 183, 191, 187, 174, 172, 183, - 184, 185, 180, 178, 179, 175, 167, 161, 168, 164, 166, 168, 156, 143, 149, 168, - 152, 155, 152, 140, 124, 118, 126, 139, 134, 146, 143, 137, 144, 159, 153, 125, - 115, 129, 149, 147, 134, 123, 120, 119, 117, 117, 114, 112, 108, 108, 109, 111, - 112, 113, 113, 113, 113, 112, 111, 110, 113, 113, 113, 112, 112, 111, 111, 111, - 113, 113, 113, 90, 90, 90, 92, 94, 96, 99, 100, 101, 101, 100, 101, 99, - 99, 97, 97, 100, 100, 99, 97, 94, 97, 99, 104, 114, 110, 105, 104, 112, - 121, 128, 132, 137, 145, 157, 157, 150, 153, 152, 136, 125, 125, 129, 144, 163, - 160, 147, 144, 147, 148, 154, 158, 161, 165, 169, 171, 173, 173, 174, 175, 177, - 179, 182, 181, 170, 175, 181, 182, 180, 179, 182, 186, 193, 185, 187, 189, 184, - 184, 183, 173, 181, 186, 192, 191, 187, 185, 189, 193, 185, 198, 206, 199, 187, - 186, 193, 197, 197, 198, 195, 192, 195, 203, 207, 206, 206, 202, 199, 200, 206, - 209, 208, 206, 203, 199, 201, 208, 205, 196, 195, 202, 207, 211, 211, 205, 200, - 200, 200, 198, 204, 203, 202, 199, 192, 187, 193, 203, 188, 189, 186, 180, 178, - 181, 182, 182, 187, 180, 171, 167, 169, 171, 167, 163, 169, 168, 165, 164, 162, - 158, 156, 153, 156, 159, 157, 153, 151, 141, 118, 99, 106, 122, 130, 131, 140, - 152, 153, 136, 143, 131, 134, 142, 144, 135, 125, 123, 121, 120, 118, 114, 110, - 106, 101, 104, 107, 110, 110, 110, 110, 110, 110, 110, 111, 111, 111, 110, 110, - 109, 109, 109, 113, 113, 113, 89, 89, 90, 92, 94, 97, 100, 101, 103, 103, - 103, 102, 101, 100, 98, 97, 101, 98, 96, 97, 100, 102, 106, 110, 108, 108, - 107, 110, 120, 130, 137, 141, 153, 150, 153, 151, 145, 146, 147, 133, 120, 130, - 137, 146, 155, 152, 143, 145, 148, 150, 152, 156, 160, 163, 165, 166, 175, 175, - 176, 177, 179, 180, 180, 180, 173, 175, 178, 179, 180, 180, 183, 186, 182, 174, - 176, 182, 181, 185, 186, 177, 183, 185, 186, 186, 185, 184, 184, 184, 184, 191, - 193, 189, 185, 188, 192, 194, 195, 200, 205, 205, 207, 207, 203, 196, 203, 205, - 209, 215, 220, 221, 217, 213, 198, 198, 203, 210, 211, 208, 209, 212, 199, 207, - 210, 206, 202, 203, 205, 206, 204, 197, 193, 198, 201, 196, 190, 186, 190, 193, - 192, 185, 183, 184, 185, 184, 181, 175, 170, 170, 173, 173, 168, 162, 171, 168, - 165, 164, 164, 162, 156, 153, 150, 152, 151, 149, 148, 144, 134, 124, 106, 105, - 111, 129, 139, 138, 141, 146, 138, 130, 127, 133, 138, 136, 133, 126, 123, 120, - 119, 114, 110, 105, 101, 103, 107, 110, 110, 110, 110, 110, 110, 110, 111, 111, - 111, 110, 110, 109, 109, 109, 112, 112, 112, 90, 89, 90, 93, 94, 97, 99, - 100, 104, 103, 101, 100, 99, 98, 98, 96, 96, 93, 93, 97, 104, 109, 110, - 114, 103, 107, 109, 117, 128, 138, 144, 147, 152, 148, 156, 162, 156, 146, 137, - 119, 123, 146, 158, 156, 155, 151, 146, 148, 155, 153, 153, 157, 163, 166, 166, - 164, 174, 175, 177, 178, 178, 177, 176, 174, 177, 176, 177, 178, 179, 181, 183, - 184, 181, 171, 173, 180, 182, 189, 191, 181, 191, 189, 187, 188, 189, 189, 186, - 183, 193, 193, 191, 188, 191, 197, 197, 193, 197, 199, 198, 195, 195, 199, 201, - 199, 201, 205, 209, 211, 209, 207, 204, 202, 212, 214, 214, 207, 201, 196, 192, - 187, 200, 208, 212, 207, 202, 202, 203, 203, 204, 197, 194, 198, 203, 198, 189, - 184, 186, 193, 195, 188, 184, 183, 184, 184, 179, 175, 173, 175, 178, 176, 169, - 162, 172, 168, 164, 165, 167, 167, 161, 156, 152, 153, 151, 150, 152, 155, 157, - 157, 136, 115, 104, 114, 130, 134, 133, 136, 132, 129, 123, 121, 126, 133, 134, - 128, 121, 117, 114, 112, 110, 109, 108, 108, 112, 112, 112, 112, 112, 112, 113, - 113, 114, 114, 114, 113, 114, 113, 113, 112, 111, 111, 111, 91, 91, 93, 94, - 95, 97, 98, 98, 100, 100, 100, 97, 98, 97, 95, 93, 90, 87, 92, 100, - 106, 110, 108, 110, 107, 112, 120, 127, 138, 146, 151, 153, 166, 154, 152, 152, - 140, 134, 136, 131, 130, 158, 170, 161, 156, 153, 149, 149, 161, 158, 156, 160, - 168, 172, 171, 168, 170, 171, 174, 176, 176, 175, 173, 171, 177, 174, 173, 174, - 177, 180, 181, 181, 191, 180, 179, 184, 185, 191, 191, 180, 190, 190, 190, 190, - 189, 189, 187, 185, 195, 195, 193, 192, 195, 200, 197, 191, 190, 193, 193, 190, - 191, 197, 201, 202, 202, 204, 204, 200, 195, 194, 198, 203, 203, 209, 210, 204, - 204, 212, 214, 210, 198, 201, 203, 201, 201, 203, 201, 197, 201, 200, 201, 198, - 193, 187, 192, 201, 177, 187, 192, 187, 181, 180, 181, 182, 177, 175, 174, 176, - 178, 177, 170, 165, 172, 167, 163, 164, 168, 169, 164, 158, 161, 158, 156, 151, - 149, 150, 155, 161, 149, 147, 129, 108, 106, 121, 126, 124, 135, 139, 130, 119, - 119, 127, 133, 130, 119, 113, 110, 109, 110, 112, 115, 114, 114, 113, 113, 113, - 113, 114, 114, 116, 117, 117, 117, 116, 117, 116, 116, 115, 112, 111, 111, 93, - 93, 94, 94, 95, 95, 97, 97, 96, 96, 96, 93, 94, 93, 91, 90, 87, - 88, 94, 103, 109, 111, 109, 109, 118, 125, 133, 139, 146, 150, 152, 153, 153, - 149, 156, 153, 135, 125, 125, 121, 137, 159, 166, 158, 158, 159, 153, 153, 162, - 159, 156, 160, 168, 172, 172, 169, 166, 168, 171, 174, 176, 176, 175, 173, 178, - 176, 174, 175, 178, 180, 181, 181, 196, 185, 185, 188, 187, 190, 189, 178, 184, - 188, 191, 190, 186, 184, 186, 189, 183, 189, 193, 192, 194, 196, 194, 190, 178, - 190, 202, 207, 206, 204, 198, 191, 199, 203, 205, 204, 201, 204, 212, 220, 221, - 224, 217, 202, 194, 197, 197, 192, 197, 196, 195, 197, 205, 211, 207, 199, 198, - 199, 203, 201, 195, 190, 196, 205, 172, 182, 191, 188, 181, 180, 183, 184, 178, - 176, 173, 173, 175, 175, 172, 169, 169, 165, 161, 162, 166, 168, 165, 160, 161, - 157, 156, 152, 147, 144, 146, 152, 145, 163, 160, 129, 102, 96, 105, 116, 134, - 144, 139, 127, 117, 121, 130, 133, 119, 110, 106, 105, 110, 115, 122, 121, 117, - 114, 114, 114, 114, 116, 116, 117, 118, 118, 120, 119, 120, 119, 119, 116, 114, - 111, 111, 95, 95, 95, 95, 95, 95, 95, 95, 95, 94, 93, 92, 91, 91, - 90, 90, 90, 94, 102, 107, 111, 111, 112, 116, 126, 134, 139, 144, 147, 148, - 147, 147, 136, 137, 144, 138, 122, 121, 127, 117, 145, 157, 157, 153, 161, 164, - 159, 160, 158, 156, 154, 156, 160, 164, 165, 164, 165, 167, 170, 173, 176, 177, - 178, 178, 179, 177, 178, 178, 179, 180, 181, 182, 189, 181, 185, 189, 186, 188, - 188, 179, 186, 192, 197, 195, 190, 187, 190, 195, 178, 186, 193, 194, 194, 197, - 198, 197, 184, 194, 201, 201, 198, 197, 195, 191, 193, 199, 205, 207, 204, 203, - 205, 208, 194, 196, 196, 194, 197, 207, 216, 220, 210, 206, 200, 198, 204, 209, - 203, 194, 199, 194, 195, 202, 207, 202, 195, 189, 176, 184, 192, 188, 184, 184, - 187, 186, 179, 176, 173, 172, 173, 174, 174, 174, 166, 164, 162, 162, 164, 165, - 164, 163, 157, 153, 153, 156, 152, 149, 149, 155, 159, 151, 147, 148, 134, 108, - 90, 97, 126, 136, 137, 130, 121, 117, 126, 134, 122, 111, 105, 103, 110, 117, - 125, 125, 117, 113, 113, 114, 114, 116, 116, 117, 118, 120, 120, 120, 120, 120, - 120, 118, 114, 111, 111, 96, 96, 96, 95, 95, 94, 94, 92, 94, 93, 93, - 91, 92, 92, 93, 93, 97, 102, 106, 107, 108, 110, 118, 127, 134, 140, 143, - 144, 144, 141, 140, 139, 148, 140, 128, 111, 110, 142, 170, 167, 160, 162, 157, - 156, 163, 163, 158, 163, 156, 155, 153, 152, 152, 154, 155, 156, 163, 164, 166, - 168, 171, 173, 175, 176, 175, 177, 180, 180, 178, 177, 179, 182, 179, 177, 185, - 191, 186, 187, 189, 182, 192, 194, 196, 195, 192, 190, 190, 192, 186, 191, 193, - 192, 192, 197, 199, 198, 194, 197, 194, 186, 183, 189, 197, 202, 194, 197, 199, - 198, 194, 191, 191, 192, 219, 216, 214, 213, 210, 208, 211, 217, 214, 213, 208, - 201, 200, 203, 201, 196, 202, 196, 195, 201, 205, 199, 190, 184, 185, 190, 192, - 189, 187, 188, 187, 185, 178, 176, 175, 174, 175, 175, 175, 175, 163, 164, 164, - 163, 161, 161, 163, 166, 159, 155, 156, 160, 159, 155, 154, 157, 165, 145, 136, - 147, 154, 135, 103, 94, 119, 123, 127, 134, 132, 122, 123, 130, 130, 116, 107, - 105, 109, 116, 125, 125, 116, 112, 112, 113, 113, 114, 114, 116, 117, 118, 118, - 119, 119, 119, 119, 116, 113, 110, 110, 98, 98, 96, 95, 94, 92, 92, 92, - 94, 94, 94, 95, 95, 97, 97, 100, 104, 109, 110, 108, 104, 108, 120, 133, - 138, 140, 141, 140, 136, 133, 130, 127, 117, 127, 141, 150, 163, 195, 201, 176, - 171, 167, 159, 158, 163, 157, 153, 163, 158, 157, 155, 152, 148, 148, 150, 152, - 160, 160, 161, 163, 165, 167, 169, 171, 168, 173, 178, 177, 173, 171, 173, 177, - 178, 176, 188, 193, 187, 186, 190, 184, 191, 189, 187, 186, 187, 185, 182, 179, - 195, 194, 189, 184, 185, 190, 192, 189, 188, 195, 198, 195, 192, 196, 202, 204, - 198, 197, 194, 191, 191, 193, 199, 203, 203, 198, 200, 206, 206, 199, 201, 210, - 198, 203, 205, 200, 198, 204, 210, 214, 200, 201, 202, 199, 191, 183, 185, 192, - 190, 193, 192, 187, 186, 187, 185, 181, 177, 177, 177, 177, 178, 178, 177, 176, - 163, 166, 167, 165, 160, 159, 164, 168, 166, 160, 159, 163, 163, 156, 152, 155, - 145, 157, 158, 146, 138, 135, 124, 119, 116, 110, 115, 133, 139, 127, 124, 129, - 139, 125, 112, 107, 109, 114, 122, 123, 113, 110, 110, 110, 112, 112, 113, 113, - 115, 115, 117, 116, 117, 116, 118, 115, 112, 109, 109, 99, 98, 96, 95, 94, - 92, 92, 90, 90, 91, 94, 99, 102, 101, 99, 100, 119, 113, 106, 105, 111, - 120, 128, 136, 136, 137, 135, 128, 127, 132, 139, 138, 167, 171, 181, 185, 183, - 180, 180, 179, 164, 161, 160, 160, 162, 163, 165, 166, 163, 164, 163, 160, 155, - 151, 149, 150, 143, 147, 152, 154, 155, 158, 162, 166, 170, 164, 165, 173, 178, - 175, 178, 185, 182, 178, 175, 180, 188, 191, 187, 182, 206, 202, 198, 193, 190, - 190, 191, 193, 193, 194, 196, 197, 192, 186, 189, 195, 184, 190, 197, 201, 199, - 195, 191, 189, 192, 195, 197, 197, 195, 195, 197, 200, 199, 204, 204, 202, 212, - 225, 224, 213, 203, 195, 191, 200, 210, 210, 203, 198, 211, 194, 184, 189, 194, - 190, 189, 193, 191, 189, 182, 182, 188, 181, 175, 184, 159, 174, 180, 171, 166, - 171, 173, 168, 176, 171, 167, 169, 172, 169, 157, 146, 161, 158, 162, 170, 170, - 163, 158, 159, 155, 155, 153, 152, 149, 146, 145, 148, 134, 104, 105, 132, 139, - 127, 129, 137, 139, 139, 124, 105, 105, 112, 117, 119, 111, 109, 107, 105, 109, - 113, 113, 107, 112, 112, 112, 112, 113, 114, 114, 114, 106, 113, 111, 98, 98, - 98, 95, 94, 92, 91, 91, 95, 97, 101, 102, 101, 101, 106, 119, 118, 115, - 109, 115, 123, 128, 129, 130, 122, 133, 143, 148, 152, 164, 175, 178, 179, 179, - 183, 182, 174, 169, 164, 164, 157, 155, 154, 156, 157, 158, 159, 159, 161, 159, - 157, 157, 158, 156, 152, 148, 143, 145, 145, 143, 142, 143, 148, 151, 158, 163, - 173, 179, 175, 168, 172, 181, 181, 179, 179, 184, 190, 193, 192, 189, 189, 189, - 189, 190, 191, 192, 194, 195, 193, 194, 197, 199, 196, 191, 193, 199, 198, 196, - 193, 190, 188, 191, 197, 201, 195, 198, 200, 200, 198, 197, 198, 200, 203, 210, - 210, 202, 201, 208, 210, 204, 194, 192, 195, 203, 206, 203, 199, 198, 196, 189, - 191, 200, 202, 193, 190, 192, 203, 197, 186, 181, 186, 183, 178, 181, 179, 172, - 175, 185, 182, 167, 159, 162, 164, 165, 163, 159, 154, 154, 159, 164, 165, 163, - 165, 170, 170, 163, 161, 164, 166, 156, 147, 145, 150, 149, 142, 134, 141, 137, - 134, 120, 116, 129, 136, 117, 133, 144, 138, 124, 118, 113, 107, 104, 106, 110, - 111, 107, 106, 108, 106, 103, 108, 108, 109, 109, 109, 109, 110, 110, 109, 116, - 112, 96, 97, 97, 95, 94, 93, 92, 94, 99, 99, 101, 105, 108, 110, 111, - 116, 112, 117, 116, 117, 120, 122, 133, 141, 169, 181, 191, 189, 181, 180, 184, - 183, 172, 172, 174, 171, 166, 159, 158, 160, 161, 161, 160, 160, 160, 161, 163, - 163, 166, 161, 159, 162, 167, 167, 161, 154, 153, 151, 148, 142, 138, 137, 139, - 142, 153, 152, 154, 158, 164, 171, 176, 181, 179, 180, 182, 186, 188, 190, 191, - 191, 186, 187, 189, 190, 190, 190, 189, 188, 191, 192, 196, 200, 198, 194, 195, - 200, 194, 202, 212, 218, 216, 209, 201, 196, 197, 199, 201, 201, 199, 198, 197, - 197, 197, 208, 213, 205, 198, 203, 209, 211, 212, 208, 204, 199, 193, 189, 194, - 202, 205, 196, 190, 189, 185, 176, 176, 182, 185, 182, 177, 174, 179, 183, 180, - 175, 190, 171, 162, 167, 166, 156, 149, 151, 158, 163, 168, 168, 163, 158, 157, - 160, 163, 165, 167, 169, 166, 160, 162, 168, 171, 163, 154, 150, 152, 149, 142, - 135, 142, 154, 152, 125, 113, 132, 136, 108, 120, 134, 133, 125, 123, 119, 118, - 121, 105, 111, 116, 113, 108, 110, 110, 109, 109, 109, 109, 109, 109, 109, 111, - 111, 111, 117, 114, 95, 96, 95, 94, 95, 93, 94, 95, 98, 96, 98, 111, - 123, 122, 106, 98, 116, 128, 130, 123, 113, 120, 147, 172, 173, 181, 188, 185, - 177, 172, 172, 165, 161, 160, 162, 161, 158, 157, 158, 160, 166, 168, 166, 166, - 166, 166, 168, 168, 167, 164, 164, 167, 170, 170, 165, 159, 161, 159, 155, 149, - 143, 139, 137, 137, 133, 138, 145, 152, 158, 162, 168, 173, 173, 177, 180, 183, - 182, 182, 184, 187, 190, 190, 191, 191, 190, 189, 188, 187, 189, 190, 194, 198, - 196, 192, 192, 196, 198, 198, 198, 196, 194, 194, 196, 198, 196, 198, 199, 199, - 198, 195, 194, 192, 191, 203, 211, 207, 203, 205, 210, 213, 194, 201, 212, 218, - 211, 195, 184, 181, 197, 191, 188, 191, 195, 195, 199, 205, 202, 204, 209, 208, - 205, 209, 209, 197, 187, 188, 183, 174, 176, 185, 181, 169, 166, 162, 161, 166, - 172, 170, 160, 151, 156, 161, 165, 164, 160, 157, 159, 164, 162, 168, 172, 164, - 152, 142, 144, 147, 143, 141, 149, 148, 137, 133, 126, 108, 122, 131, 129, 121, - 121, 117, 113, 113, 108, 112, 115, 113, 111, 113, 115, 112, 113, 112, 112, 111, - 111, 111, 111, 112, 110, 117, 115, 95, 96, 95, 94, 95, 93, 94, 98, 97, - 100, 109, 118, 123, 120, 105, 99, 131, 135, 134, 129, 124, 135, 160, 181, 166, - 167, 167, 166, 166, 168, 165, 158, 169, 166, 166, 163, 159, 158, 157, 158, 164, - 164, 164, 164, 164, 165, 166, 167, 162, 164, 166, 166, 164, 162, 160, 159, 160, - 159, 157, 153, 148, 142, 135, 132, 117, 128, 144, 154, 152, 145, 150, 160, 163, - 169, 174, 177, 177, 178, 180, 186, 185, 185, 185, 187, 189, 191, 194, 195, 192, - 191, 193, 196, 195, 191, 190, 194, 193, 193, 193, 191, 189, 190, 192, 195, 198, - 197, 197, 197, 197, 195, 193, 191, 194, 201, 207, 208, 206, 205, 203, 200, 217, - 204, 190, 185, 187, 194, 208, 220, 202, 200, 203, 212, 215, 206, 193, 183, 175, - 170, 173, 165, 147, 146, 150, 139, 136, 151, 163, 165, 172, 182, 182, 174, 174, - 163, 152, 150, 157, 162, 162, 159, 152, 160, 165, 164, 159, 157, 158, 160, 154, - 164, 172, 168, 156, 145, 146, 149, 148, 137, 145, 159, 151, 135, 122, 112, 99, - 111, 113, 115, 125, 124, 118, 118, 117, 117, 114, 111, 113, 118, 117, 111, 113, - 112, 109, 109, 107, 107, 106, 107, 109, 116, 115, 94, 95, 94, 94, 92, 93, - 95, 98, 97, 110, 121, 118, 109, 105, 111, 125, 135, 129, 124, 133, 144, 155, - 161, 160, 173, 168, 164, 160, 163, 167, 165, 158, 167, 166, 165, 165, 164, 164, - 163, 162, 165, 165, 165, 165, 164, 165, 165, 166, 166, 168, 169, 167, 163, 161, - 161, 162, 160, 160, 159, 158, 155, 148, 139, 133, 137, 109, 93, 108, 132, 142, - 148, 159, 153, 158, 164, 170, 173, 177, 181, 185, 183, 183, 183, 183, 184, 186, - 189, 190, 195, 192, 192, 195, 195, 192, 192, 195, 186, 193, 202, 207, 206, 200, - 194, 191, 200, 198, 196, 196, 196, 196, 195, 193, 188, 192, 197, 201, 204, 203, - 199, 194, 191, 192, 202, 215, 219, 208, 192, 182, 193, 186, 179, 175, 170, 156, - 137, 122, 132, 111, 107, 98, 74, 72, 85, 81, 74, 70, 79, 94, 101, 107, - 126, 149, 166, 169, 170, 166, 159, 155, 157, 159, 152, 160, 164, 162, 160, 159, - 161, 159, 156, 156, 158, 158, 161, 154, 146, 142, 147, 141, 144, 148, 144, 147, - 144, 131, 110, 115, 106, 101, 112, 119, 124, 133, 132, 130, 125, 122, 123, 127, - 124, 115, 119, 117, 116, 113, 113, 111, 110, 111, 112, 118, 115, 96, 96, 95, - 94, 92, 92, 94, 96, 103, 111, 115, 109, 101, 104, 119, 136, 133, 130, 129, - 141, 156, 161, 158, 151, 148, 146, 146, 144, 150, 159, 165, 165, 161, 162, 165, - 167, 171, 172, 173, 171, 173, 171, 170, 168, 166, 166, 165, 166, 173, 172, 169, - 168, 167, 167, 167, 166, 165, 163, 162, 161, 158, 153, 144, 139, 145, 83, 40, - 54, 90, 110, 128, 148, 147, 150, 155, 162, 166, 171, 173, 175, 181, 182, 183, - 183, 184, 184, 183, 183, 194, 190, 188, 191, 192, 191, 193, 197, 195, 192, 187, - 183, 183, 188, 196, 203, 200, 197, 193, 192, 194, 195, 195, 194, 188, 189, 191, - 195, 197, 196, 194, 193, 194, 189, 187, 189, 186, 176, 165, 159, 148, 142, 135, - 130, 131, 130, 126, 121, 89, 54, 50, 54, 35, 33, 47, 42, 46, 36, 33, - 38, 42, 51, 76, 104, 129, 141, 158, 167, 167, 161, 155, 152, 154, 157, 159, - 156, 157, 161, 161, 157, 159, 156, 154, 154, 158, 155, 149, 145, 148, 145, 145, - 141, 136, 142, 149, 143, 155, 157, 142, 121, 110, 103, 103, 116, 133, 135, 136, - 135, 136, 136, 132, 126, 127, 125, 123, 121, 120, 119, 117, 117, 113, 119, 116, - 93, 91, 91, 91, 91, 94, 96, 100, 110, 107, 103, 103, 111, 121, 130, 133, - 138, 142, 146, 151, 152, 152, 161, 167, 161, 162, 160, 152, 150, 153, 160, 163, - 169, 170, 170, 172, 175, 176, 174, 171, 172, 170, 169, 169, 167, 165, 165, 164, - 175, 168, 162, 162, 167, 170, 168, 164, 166, 163, 159, 157, 155, 151, 144, 140, - 110, 69, 42, 51, 55, 52, 81, 124, 147, 149, 153, 157, 162, 165, 164, 167, - 170, 174, 181, 186, 192, 193, 192, 192, 192, 187, 184, 187, 190, 191, 194, 199, - 191, 195, 200, 203, 203, 202, 201, 201, 200, 195, 190, 189, 192, 194, 195, 194, - 201, 200, 198, 195, 189, 183, 182, 184, 176, 166, 156, 150, 145, 139, 137, 140, - 141, 145, 149, 149, 148, 145, 141, 137, 80, 38, 38, 55, 42, 35, 41, 29, - 29, 38, 40, 31, 30, 41, 48, 46, 86, 91, 105, 128, 152, 166, 166, 160, - 156, 157, 155, 150, 153, 160, 160, 156, 159, 162, 164, 159, 153, 148, 151, 158, - 160, 148, 148, 151, 135, 126, 130, 137, 137, 157, 163, 153, 136, 112, 99, 106, - 116, 127, 139, 142, 144, 143, 140, 135, 129, 127, 123, 120, 120, 119, 118, 120, - 115, 122, 119, 80, 84, 89, 89, 89, 94, 99, 104, 119, 108, 101, 109, 126, - 138, 145, 145, 135, 145, 143, 138, 147, 156, 163, 171, 157, 160, 161, 159, 155, - 158, 169, 174, 180, 176, 173, 170, 170, 169, 170, 170, 167, 172, 167, 163, 170, - 169, 167, 171, 172, 168, 163, 161, 161, 163, 163, 163, 159, 165, 157, 149, 162, - 139, 159, 133, 65, 31, 38, 43, 41, 37, 35, 75, 107, 128, 149, 157, 160, - 166, 173, 175, 183, 176, 185, 192, 188, 187, 192, 190, 197, 190, 202, 202, 174, - 171, 193, 204, 207, 194, 187, 192, 198, 194, 188, 186, 189, 188, 187, 185, 183, - 180, 178, 177, 169, 168, 166, 164, 163, 162, 161, 161, 161, 159, 156, 155, 156, - 157, 156, 155, 154, 177, 135, 157, 160, 133, 158, 114, 32, 32, 33, 33, 32, - 30, 28, 27, 29, 32, 35, 33, 28, 28, 33, 39, 47, 52, 70, 88, 124, - 153, 154, 169, 159, 169, 165, 154, 153, 153, 156, 166, 157, 163, 170, 164, 160, - 156, 156, 156, 152, 151, 154, 156, 151, 143, 138, 141, 146, 157, 151, 147, 150, - 136, 103, 84, 90, 93, 115, 140, 149, 152, 150, 140, 137, 123, 124, 127, 118, - 114, 123, 125, 121, 121, 120, 79, 80, 83, 90, 96, 100, 104, 107, 100, 103, - 112, 126, 138, 144, 147, 146, 148, 156, 151, 144, 148, 151, 155, 162, 170, 169, - 166, 163, 164, 168, 176, 179, 179, 176, 173, 171, 169, 168, 168, 168, 168, 173, - 168, 165, 171, 170, 168, 173, 168, 165, 161, 160, 160, 161, 160, 160, 162, 143, - 177, 149, 146, 147, 144, 64, 42, 28, 40, 38, 36, 35, 27, 45, 46, 75, - 115, 143, 161, 168, 165, 158, 159, 158, 170, 179, 173, 174, 182, 185, 192, 177, - 181, 187, 175, 173, 171, 156, 163, 165, 169, 171, 171, 173, 177, 182, 173, 173, - 173, 172, 171, 170, 169, 167, 166, 166, 165, 164, 164, 164, 164, 165, 170, 167, - 165, 164, 165, 166, 165, 165, 167, 155, 169, 154, 161, 143, 156, 52, 36, 36, - 36, 35, 34, 32, 30, 30, 33, 33, 32, 31, 30, 30, 32, 33, 37, 42, - 52, 53, 84, 121, 133, 153, 159, 168, 164, 161, 167, 164, 152, 148, 155, 161, - 164, 162, 159, 159, 158, 155, 157, 153, 152, 151, 150, 144, 144, 150, 139, 150, - 149, 147, 151, 146, 131, 130, 121, 104, 102, 119, 135, 150, 155, 145, 145, 124, - 117, 114, 106, 112, 123, 123, 133, 129, 125, 84, 85, 90, 101, 109, 111, 104, - 100, 91, 104, 120, 134, 141, 140, 145, 146, 142, 151, 151, 152, 158, 159, 161, - 167, 176, 172, 164, 161, 164, 168, 174, 174, 176, 174, 172, 170, 169, 168, 168, - 168, 168, 173, 167, 164, 169, 167, 163, 169, 163, 161, 159, 159, 159, 158, 157, - 155, 159, 142, 160, 154, 129, 150, 85, 25, 33, 37, 47, 35, 33, 40, 31, - 28, 38, 43, 52, 62, 80, 102, 119, 126, 122, 121, 132, 136, 122, 119, 128, - 133, 136, 111, 93, 87, 86, 101, 106, 93, 69, 105, 141, 155, 155, 158, 162, - 163, 170, 170, 170, 171, 171, 171, 172, 172, 178, 177, 176, 175, 174, 174, 174, - 174, 177, 175, 173, 173, 174, 175, 174, 173, 174, 161, 163, 168, 153, 159, 104, - 22, 37, 36, 35, 33, 32, 31, 30, 30, 35, 32, 29, 28, 30, 31, 29, - 27, 31, 37, 42, 31, 50, 84, 101, 128, 150, 160, 160, 160, 169, 169, 162, - 161, 154, 157, 158, 157, 159, 161, 157, 152, 157, 152, 151, 151, 150, 148, 147, - 151, 144, 156, 153, 147, 148, 149, 148, 159, 156, 133, 118, 113, 113, 124, 132, - 127, 131, 123, 125, 127, 124, 129, 131, 121, 120, 118, 116, 97, 98, 104, 113, - 117, 111, 102, 99, 109, 117, 126, 134, 137, 136, 144, 148, 132, 141, 147, 152, - 161, 162, 165, 174, 175, 173, 165, 161, 161, 164, 169, 171, 174, 173, 172, 171, - 170, 170, 169, 169, 167, 172, 166, 162, 167, 163, 158, 163, 160, 159, 158, 158, - 158, 157, 154, 151, 155, 150, 139, 135, 142, 101, 32, 42, 39, 44, 44, 32, - 30, 38, 37, 32, 30, 31, 34, 36, 40, 45, 50, 51, 57, 52, 59, 61, - 47, 42, 48, 49, 52, 52, 52, 49, 47, 54, 55, 46, 46, 99, 152, 168, - 170, 174, 178, 173, 182, 180, 181, 181, 182, 182, 184, 183, 192, 191, 189, 186, - 184, 182, 181, 181, 179, 178, 176, 176, 177, 178, 177, 175, 175, 178, 147, 164, - 166, 123, 46, 40, 32, 30, 29, 27, 27, 28, 29, 30, 32, 31, 30, 29, - 30, 30, 29, 28, 32, 33, 40, 34, 42, 56, 67, 102, 122, 144, 156, 159, - 164, 163, 162, 168, 158, 158, 156, 155, 159, 161, 156, 148, 152, 150, 153, 157, - 157, 152, 147, 148, 150, 159, 153, 144, 143, 143, 146, 163, 159, 157, 156, 140, - 112, 100, 106, 106, 105, 105, 117, 121, 119, 126, 131, 119, 128, 129, 128, 119, - 117, 115, 114, 111, 104, 105, 111, 126, 127, 129, 133, 136, 136, 142, 141, 140, - 144, 145, 149, 156, 155, 158, 169, 175, 177, 174, 168, 161, 160, 167, 174, 171, - 171, 171, 172, 172, 171, 171, 171, 168, 173, 167, 163, 167, 162, 156, 161, 158, - 157, 156, 157, 157, 156, 152, 149, 149, 148, 144, 121, 137, 37, 34, 53, 40, - 38, 32, 31, 30, 28, 34, 33, 24, 31, 41, 45, 42, 34, 27, 25, 43, - 34, 36, 43, 40, 41, 45, 42, 31, 41, 43, 41, 42, 44, 45, 48, 85, - 126, 163, 166, 167, 176, 186, 180, 187, 184, 185, 182, 184, 182, 185, 186, 192, - 191, 188, 186, 184, 182, 182, 181, 181, 179, 178, 178, 179, 178, 176, 174, 175, - 173, 169, 145, 169, 49, 43, 43, 26, 26, 25, 25, 25, 27, 29, 30, 26, - 30, 33, 32, 29, 28, 30, 34, 34, 25, 34, 39, 42, 37, 42, 86, 100, - 124, 140, 150, 161, 159, 151, 151, 163, 161, 157, 155, 159, 161, 155, 146, 151, - 148, 151, 156, 158, 153, 149, 150, 151, 154, 147, 144, 148, 148, 149, 160, 147, - 159, 172, 162, 126, 105, 101, 95, 78, 75, 78, 77, 74, 86, 107, 109, 112, - 119, 126, 132, 123, 112, 106, 102, 101, 114, 130, 129, 128, 131, 137, 141, 140, - 140, 134, 143, 142, 141, 145, 152, 150, 156, 171, 170, 175, 174, 167, 159, 156, - 164, 171, 169, 170, 171, 172, 173, 173, 172, 172, 171, 176, 171, 167, 170, 165, - 159, 162, 156, 155, 154, 155, 155, 153, 150, 147, 139, 153, 138, 148, 63, 31, - 46, 40, 34, 33, 25, 38, 39, 25, 31, 29, 37, 34, 33, 30, 28, 27, - 34, 44, 32, 20, 20, 29, 29, 33, 35, 30, 40, 37, 22, 18, 28, 31, - 35, 50, 106, 138, 163, 166, 167, 177, 179, 173, 186, 185, 183, 181, 180, 181, - 182, 182, 187, 187, 186, 185, 185, 186, 187, 187, 184, 183, 181, 181, 181, 179, - 176, 175, 169, 171, 180, 157, 100, 26, 52, 24, 26, 26, 26, 27, 28, 29, - 31, 32, 24, 29, 34, 33, 29, 27, 31, 36, 37, 24, 31, 38, 42, 35, - 37, 78, 108, 114, 113, 120, 145, 160, 162, 164, 165, 164, 160, 156, 158, 160, - 155, 147, 159, 151, 148, 149, 152, 151, 152, 155, 151, 153, 145, 145, 150, 145, - 139, 148, 151, 157, 164, 163, 143, 126, 109, 87, 63, 56, 61, 65, 59, 63, - 79, 84, 72, 84, 97, 122, 113, 106, 109, 113, 113, 124, 138, 136, 136, 137, - 141, 142, 140, 141, 136, 134, 133, 133, 140, 151, 150, 157, 174, 169, 171, 169, - 165, 160, 158, 161, 164, 166, 167, 169, 171, 172, 172, 172, 171, 169, 175, 170, - 166, 170, 164, 157, 161, 154, 152, 151, 151, 151, 150, 147, 145, 137, 153, 128, - 137, 15, 48, 39, 34, 35, 39, 28, 42, 43, 28, 34, 25, 29, 26, 29, - 34, 33, 27, 24, 26, 41, 30, 32, 37, 31, 32, 36, 32, 23, 27, 26, - 36, 48, 37, 33, 53, 131, 153, 175, 181, 184, 189, 187, 180, 187, 186, 184, - 182, 182, 183, 184, 186, 189, 188, 188, 188, 189, 190, 191, 192, 187, 185, 183, - 182, 182, 179, 175, 173, 168, 180, 165, 155, 32, 46, 36, 26, 31, 31, 32, - 32, 32, 32, 31, 29, 26, 29, 32, 32, 30, 28, 29, 30, 37, 33, 39, - 37, 43, 43, 36, 58, 113, 118, 110, 107, 124, 143, 158, 173, 163, 163, 160, - 156, 157, 159, 156, 149, 161, 151, 145, 147, 150, 151, 151, 153, 151, 153, 147, - 148, 149, 139, 132, 141, 153, 150, 156, 160, 156, 149, 126, 94, 70, 55, 62, - 77, 76, 71, 72, 72, 76, 79, 82, 106, 101, 104, 119, 132, 131, 131, 138, - 151, 149, 145, 142, 137, 137, 144, 143, 134, 130, 132, 138, 146, 145, 151, 169, - 175, 175, 171, 168, 168, 165, 166, 163, 165, 167, 169, 171, 172, 173, 172, 172, - 167, 173, 168, 165, 168, 163, 156, 160, 152, 150, 148, 147, 148, 147, 145, 144, - 146, 136, 141, 70, 42, 33, 33, 40, 35, 44, 27, 33, 33, 26, 36, 21, - 40, 30, 27, 32, 36, 33, 30, 30, 30, 23, 27, 31, 22, 22, 29, 29, - 28, 32, 27, 31, 40, 33, 52, 99, 159, 168, 173, 171, 170, 176, 182, 184, - 187, 186, 184, 183, 183, 185, 187, 189, 191, 190, 189, 188, 188, 188, 188, 189, - 187, 185, 183, 182, 181, 177, 173, 170, 175, 178, 158, 109, 28, 49, 15, 44, - 32, 33, 33, 33, 32, 30, 28, 26, 30, 28, 28, 29, 30, 29, 26, 23, - 28, 37, 46, 34, 40, 47, 28, 28, 98, 123, 134, 125, 116, 112, 123, 143, - 159, 161, 159, 156, 156, 158, 156, 152, 155, 148, 147, 152, 155, 152, 148, 145, - 146, 150, 149, 151, 152, 142, 138, 150, 136, 138, 150, 161, 163, 163, 148, 119, - 89, 59, 55, 73, 77, 74, 77, 80, 80, 75, 71, 113, 119, 123, 128, 134, - 139, 146, 149, 154, 153, 151, 148, 141, 136, 138, 137, 148, 144, 135, 133, 148, - 159, 166, 174, 176, 179, 175, 170, 171, 170, 167, 162, 157, 158, 162, 168, 173, - 176, 175, 173, 171, 168, 166, 165, 164, 162, 156, 151, 155, 148, 151, 154, 146, - 145, 146, 140, 162, 119, 125, 48, 34, 46, 28, 35, 38, 36, 35, 38, 41, - 40, 33, 26, 22, 31, 32, 30, 31, 26, 26, 38, 30, 31, 30, 28, 26, - 27, 27, 30, 30, 26, 25, 40, 57, 67, 100, 148, 172, 175, 179, 181, 182, - 183, 184, 186, 187, 187, 187, 187, 187, 187, 186, 186, 192, 192, 191, 190, 190, - 189, 188, 188, 188, 191, 189, 182, 176, 176, 175, 174, 186, 160, 164, 58, 44, - 33, 31, 32, 32, 30, 38, 42, 32, 30, 32, 26, 33, 25, 32, 32, 23, - 34, 42, 27, 34, 36, 38, 40, 41, 40, 38, 36, 81, 126, 122, 130, 134, - 130, 103, 129, 136, 154, 166, 163, 157, 157, 163, 165, 160, 154, 152, 155, 154, - 148, 147, 150, 152, 150, 148, 149, 148, 144, 141, 141, 130, 139, 143, 141, 147, - 151, 146, 136, 81, 53, 66, 89, 81, 80, 84, 70, 78, 74, 71, 118, 121, - 124, 128, 133, 139, 146, 148, 154, 154, 152, 150, 143, 138, 141, 140, 140, 148, - 147, 142, 144, 145, 154, 167, 187, 186, 175, 167, 164, 168, 171, 169, 171, 170, - 167, 166, 168, 170, 171, 171, 170, 168, 166, 166, 166, 163, 158, 154, 149, 143, - 147, 150, 145, 146, 149, 143, 145, 139, 97, 38, 39, 39, 32, 35, 34, 32, - 31, 33, 36, 35, 28, 23, 26, 31, 28, 26, 28, 23, 21, 31, 27, 29, - 31, 32, 32, 32, 29, 29, 34, 27, 35, 79, 132, 153, 156, 166, 168, 171, - 175, 178, 179, 180, 182, 183, 190, 190, 190, 190, 189, 189, 189, 190, 190, 190, - 189, 189, 189, 188, 188, 188, 185, 185, 181, 177, 177, 179, 176, 172, 174, 164, - 132, 31, 31, 31, 27, 37, 28, 28, 30, 26, 20, 28, 37, 36, 19, 26, - 40, 40, 30, 30, 31, 24, 32, 34, 36, 38, 39, 39, 38, 37, 60, 119, - 123, 128, 132, 129, 124, 122, 125, 137, 147, 151, 153, 159, 162, 161, 156, 149, - 146, 149, 150, 147, 146, 148, 148, 150, 151, 149, 145, 140, 140, 143, 137, 139, - 140, 142, 146, 149, 142, 135, 123, 90, 80, 83, 73, 72, 81, 81, 83, 80, - 77, 125, 128, 131, 133, 137, 143, 149, 151, 148, 147, 147, 146, 141, 137, 142, - 142, 170, 175, 171, 162, 163, 161, 164, 172, 178, 182, 181, 178, 174, 171, 167, - 157, 165, 164, 164, 166, 170, 173, 174, 174, 166, 165, 164, 164, 164, 161, 156, - 153, 148, 142, 145, 148, 144, 147, 149, 141, 135, 153, 62, 34, 45, 36, 40, - 36, 31, 31, 31, 33, 33, 32, 27, 23, 29, 29, 21, 22, 28, 22, 18, - 26, 41, 37, 32, 29, 27, 29, 31, 33, 28, 47, 75, 115, 157, 169, 164, - 166, 170, 174, 179, 182, 183, 184, 186, 188, 191, 191, 191, 191, 191, 191, 191, - 191, 188, 188, 188, 188, 188, 187, 187, 187, 184, 181, 177, 175, 180, 184, 179, - 172, 174, 170, 99, 24, 31, 37, 25, 36, 42, 42, 35, 28, 35, 46, 41, - 23, 26, 32, 28, 26, 33, 36, 34, 35, 32, 33, 36, 38, 40, 40, 40, - 37, 37, 99, 127, 126, 131, 130, 144, 118, 126, 131, 137, 145, 155, 164, 165, - 162, 162, 154, 149, 151, 155, 154, 152, 151, 146, 152, 155, 151, 143, 139, 141, - 146, 142, 137, 136, 141, 147, 144, 137, 134, 123, 98, 77, 74, 71, 67, 69, - 75, 67, 67, 66, 128, 133, 136, 140, 145, 147, 149, 151, 148, 144, 145, 146, - 142, 139, 143, 144, 163, 174, 172, 160, 152, 149, 155, 169, 168, 175, 178, 179, - 174, 171, 164, 154, 156, 159, 166, 172, 177, 176, 171, 167, 165, 165, 165, 164, - 162, 158, 153, 150, 153, 147, 149, 149, 144, 147, 147, 136, 140, 129, 34, 36, - 41, 37, 40, 31, 32, 33, 32, 34, 33, 33, 29, 26, 27, 26, 19, 23, - 32, 26, 21, 29, 29, 29, 31, 35, 39, 42, 42, 41, 73, 110, 139, 152, - 159, 159, 164, 177, 174, 175, 182, 183, 187, 186, 190, 190, 190, 189, 191, 189, - 191, 190, 192, 192, 191, 190, 190, 189, 188, 187, 186, 186, 184, 184, 181, 179, - 182, 185, 181, 175, 167, 144, 61, 33, 34, 42, 29, 33, 18, 38, 40, 29, - 32, 40, 34, 22, 32, 43, 34, 27, 36, 34, 31, 44, 32, 33, 35, 38, - 40, 41, 41, 39, 30, 66, 131, 127, 132, 137, 147, 125, 137, 137, 139, 143, - 152, 160, 163, 164, 166, 159, 154, 153, 158, 158, 157, 152, 149, 154, 155, 151, - 146, 145, 145, 145, 143, 134, 130, 140, 145, 139, 133, 135, 133, 111, 82, 75, - 83, 80, 72, 79, 67, 70, 70, 126, 130, 137, 141, 144, 144, 141, 142, 150, - 147, 146, 148, 147, 144, 146, 145, 150, 174, 181, 171, 159, 153, 166, 188, 173, - 173, 168, 160, 160, 165, 172, 173, 173, 173, 175, 177, 176, 170, 161, 155, 168, - 169, 170, 169, 165, 159, 154, 151, 156, 152, 154, 153, 148, 151, 148, 132, 144, - 78, 23, 42, 30, 38, 32, 25, 33, 34, 33, 34, 35, 34, 30, 28, 26, - 25, 19, 26, 32, 25, 22, 34, 34, 47, 68, 89, 103, 106, 101, 96, 133, - 154, 162, 163, 168, 172, 172, 180, 171, 175, 180, 182, 185, 185, 188, 189, 190, - 190, 191, 191, 192, 192, 193, 192, 195, 194, 192, 191, 189, 187, 186, 185, 183, - 186, 186, 182, 179, 180, 178, 175, 162, 108, 33, 39, 29, 40, 39, 48, 87, - 111, 97, 51, 25, 22, 32, 46, 19, 44, 51, 47, 45, 29, 21, 38, 33, - 34, 36, 38, 40, 41, 42, 41, 37, 37, 126, 128, 134, 144, 137, 139, 140, - 140, 139, 139, 140, 145, 153, 161, 165, 160, 156, 153, 157, 158, 156, 150, 152, - 153, 151, 147, 148, 151, 147, 141, 143, 134, 132, 140, 146, 140, 134, 138, 155, - 126, 84, 66, 74, 73, 67, 73, 71, 74, 72, 132, 135, 140, 145, 144, 143, - 140, 137, 144, 140, 139, 142, 143, 141, 141, 143, 133, 138, 133, 134, 149, 154, - 152, 152, 165, 167, 164, 160, 160, 166, 175, 175, 185, 181, 176, 173, 170, 168, - 165, 162, 171, 173, 175, 174, 169, 163, 159, 156, 156, 154, 158, 157, 153, 156, - 149, 129, 131, 43, 31, 48, 31, 40, 32, 28, 31, 32, 32, 32, 32, 32, - 29, 28, 26, 26, 22, 26, 29, 21, 27, 49, 91, 101, 116, 130, 142, 151, - 157, 161, 154, 164, 164, 162, 168, 169, 167, 173, 175, 179, 183, 185, 186, 187, - 188, 190, 191, 191, 192, 193, 193, 194, 195, 195, 195, 194, 193, 191, 189, 187, - 186, 185, 181, 186, 187, 182, 177, 175, 174, 172, 184, 122, 53, 45, 30, 38, - 43, 82, 130, 167, 177, 164, 148, 104, 45, 18, 43, 39, 32, 35, 45, 42, - 32, 32, 35, 35, 36, 38, 39, 41, 42, 40, 43, 29, 103, 127, 136, 146, - 133, 149, 141, 141, 142, 140, 136, 136, 146, 159, 162, 163, 161, 158, 158, 160, - 158, 154, 151, 151, 146, 142, 146, 152, 147, 136, 144, 142, 140, 144, 145, 140, - 138, 140, 144, 117, 90, 76, 74, 70, 65, 60, 68, 72, 72, 139, 139, 142, - 142, 142, 140, 140, 137, 135, 132, 132, 137, 142, 140, 141, 144, 152, 138, 110, - 109, 133, 149, 147, 142, 150, 159, 163, 163, 164, 167, 169, 167, 175, 171, 168, - 168, 169, 171, 172, 172, 167, 171, 175, 175, 171, 166, 162, 161, 159, 159, 163, - 161, 155, 156, 146, 121, 89, 37, 41, 41, 37, 34, 33, 34, 30, 32, 31, - 31, 31, 30, 29, 29, 27, 28, 24, 26, 26, 23, 44, 80, 129, 132, 134, - 134, 135, 143, 158, 170, 165, 176, 178, 177, 176, 169, 169, 184, 180, 184, 188, - 190, 190, 190, 191, 192, 191, 191, 192, 192, 193, 194, 195, 194, 191, 191, 190, - 190, 189, 188, 188, 187, 182, 185, 184, 180, 179, 178, 174, 169, 191, 163, 98, - 43, 39, 41, 37, 121, 161, 172, 159, 156, 178, 164, 126, 114, 110, 78, 55, - 49, 48, 49, 45, 36, 36, 36, 37, 37, 38, 40, 41, 40, 39, 42, 69, - 123, 137, 140, 144, 149, 146, 145, 147, 147, 140, 135, 139, 150, 157, 164, 167, - 164, 162, 164, 164, 159, 150, 154, 151, 145, 147, 153, 149, 141, 144, 150, 148, - 144, 140, 139, 138, 139, 139, 121, 118, 111, 92, 84, 82, 71, 85, 87, 88, - 141, 138, 136, 134, 134, 135, 136, 137, 138, 135, 136, 142, 146, 145, 146, 148, - 137, 137, 115, 93, 91, 105, 131, 157, 163, 166, 162, 154, 153, 158, 165, 168, - 165, 164, 166, 169, 172, 172, 169, 167, 162, 167, 172, 174, 170, 166, 163, 163, - 164, 164, 167, 163, 155, 154, 140, 112, 45, 38, 40, 25, 37, 20, 28, 31, - 29, 30, 31, 31, 30, 29, 29, 30, 26, 29, 26, 27, 28, 30, 63, 110, - 136, 146, 158, 161, 157, 155, 160, 165, 175, 174, 171, 175, 185, 181, 177, 187, - 179, 182, 185, 187, 186, 186, 187, 188, 186, 187, 187, 188, 189, 190, 191, 191, - 188, 188, 188, 188, 189, 189, 189, 189, 186, 185, 182, 180, 184, 185, 178, 169, - 159, 173, 114, 25, 41, 43, 27, 145, 149, 175, 174, 171, 185, 173, 159, 178, - 162, 147, 140, 114, 60, 32, 38, 40, 36, 36, 36, 36, 36, 36, 39, 36, - 30, 56, 41, 117, 134, 132, 157, 145, 148, 146, 147, 149, 142, 132, 129, 135, - 143, 154, 163, 160, 158, 160, 159, 158, 149, 156, 157, 149, 147, 154, 153, 147, - 142, 152, 152, 142, 135, 137, 137, 134, 145, 125, 123, 109, 74, 72, 87, 82, - 93, 93, 89, 141, 138, 132, 133, 137, 142, 143, 140, 137, 131, 137, 140, 137, - 141, 146, 138, 143, 136, 122, 112, 98, 84, 98, 129, 174, 168, 161, 158, 154, - 149, 149, 154, 169, 168, 164, 165, 168, 171, 171, 169, 166, 168, 170, 169, 168, - 167, 172, 173, 172, 167, 160, 152, 157, 166, 134, 79, 33, 38, 36, 28, 28, - 34, 34, 29, 30, 26, 23, 22, 25, 30, 35, 37, 34, 32, 29, 31, 51, - 82, 112, 123, 142, 146, 150, 154, 155, 159, 166, 172, 173, 181, 186, 182, 181, - 183, 182, 177, 185, 190, 188, 184, 183, 188, 190, 190, 184, 188, 188, 187, 185, - 186, 188, 190, 190, 189, 186, 186, 190, 190, 189, 187, 187, 181, 183, 186, 180, - 181, 179, 173, 163, 112, 81, 44, 40, 33, 32, 121, 164, 163, 170, 182, 188, - 184, 186, 194, 173, 185, 183, 171, 145, 84, 36, 33, 34, 34, 43, 47, 37, - 31, 39, 36, 38, 33, 47, 94, 135, 136, 137, 151, 143, 151, 156, 151, 142, - 138, 135, 132, 133, 146, 160, 163, 161, 159, 158, 155, 149, 148, 149, 146, 144, - 142, 143, 142, 148, 143, 144, 149, 148, 143, 139, 141, 147, 131, 128, 93, 81, - 87, 78, 93, 94, 92, 91, 142, 145, 145, 145, 142, 140, 140, 140, 144, 137, - 140, 143, 138, 141, 144, 137, 128, 133, 133, 133, 125, 103, 89, 94, 121, 152, - 166, 147, 139, 154, 155, 141, 159, 163, 163, 161, 160, 160, 163, 166, 165, 169, - 170, 167, 162, 161, 169, 173, 179, 172, 168, 162, 157, 147, 100, 40, 47, 45, - 44, 42, 37, 29, 28, 32, 28, 26, 28, 30, 32, 29, 23, 19, 41, 30, - 43, 80, 111, 121, 130, 141, 142, 148, 158, 164, 164, 166, 168, 170, 176, 181, - 183, 180, 181, 183, 185, 183, 183, 186, 184, 182, 185, 189, 189, 184, 193, 184, - 177, 174, 176, 180, 178, 176, 190, 189, 185, 185, 187, 189, 188, 187, 188, 181, - 183, 184, 178, 179, 178, 170, 174, 128, 86, 33, 32, 39, 36, 99, 164, 153, - 156, 174, 182, 173, 169, 174, 164, 174, 179, 184, 183, 149, 85, 38, 57, 37, - 26, 31, 38, 36, 36, 37, 37, 23, 41, 67, 121, 136, 137, 141, 142, 148, - 152, 147, 142, 139, 135, 130, 137, 127, 142, 165, 167, 160, 160, 159, 151, 149, - 148, 147, 149, 149, 150, 149, 147, 143, 145, 150, 150, 145, 141, 141, 147, 136, - 123, 90, 63, 80, 77, 97, 100, 99, 97, 138, 146, 151, 151, 144, 139, 138, - 139, 145, 138, 139, 142, 138, 141, 144, 136, 131, 136, 130, 126, 126, 116, 101, - 95, 91, 114, 143, 160, 161, 155, 147, 139, 151, 156, 160, 156, 152, 152, 158, - 165, 158, 162, 165, 161, 156, 156, 164, 172, 157, 165, 172, 157, 128, 112, 102, - 86, 47, 46, 38, 30, 35, 45, 37, 19, 33, 27, 23, 23, 29, 35, 40, - 43, 40, 44, 73, 115, 140, 139, 140, 145, 150, 156, 163, 169, 170, 172, 175, - 178, 178, 181, 182, 178, 178, 181, 185, 186, 186, 188, 187, 186, 189, 190, 187, - 181, 176, 177, 181, 184, 186, 184, 179, 176, 188, 187, 183, 183, 185, 188, 188, - 187, 189, 181, 182, 182, 176, 177, 176, 168, 168, 129, 82, 26, 33, 47, 24, - 40, 105, 152, 174, 152, 149, 175, 184, 167, 185, 182, 177, 169, 170, 165, 113, - 42, 27, 45, 45, 32, 37, 44, 38, 26, 38, 18, 38, 40, 97, 138, 140, - 136, 144, 147, 149, 146, 145, 144, 139, 132, 137, 118, 131, 155, 160, 165, 168, - 154, 157, 152, 148, 149, 151, 154, 155, 152, 148, 144, 145, 149, 150, 145, 141, - 141, 144, 144, 124, 97, 45, 65, 60, 76, 81, 87, 89, 135, 142, 147, 148, - 144, 141, 139, 139, 142, 135, 137, 140, 136, 140, 143, 136, 135, 140, 128, 117, - 124, 126, 120, 116, 88, 83, 97, 126, 146, 148, 144, 143, 151, 152, 156, 153, - 149, 148, 153, 157, 153, 153, 156, 156, 155, 157, 164, 168, 176, 157, 149, 151, - 156, 163, 160, 145, 148, 117, 78, 48, 33, 31, 38, 46, 32, 34, 38, 37, - 34, 31, 31, 31, 58, 89, 120, 127, 128, 136, 145, 146, 154, 156, 158, 158, - 161, 166, 178, 185, 180, 180, 181, 180, 178, 180, 184, 186, 187, 189, 189, 185, - 184, 185, 183, 179, 181, 182, 181, 177, 171, 171, 183, 196, 185, 185, 184, 186, - 187, 188, 186, 186, 189, 181, 181, 181, 174, 175, 174, 167, 176, 158, 123, 64, - 48, 50, 32, 40, 54, 79, 124, 160, 164, 149, 151, 169, 167, 166, 170, 165, - 163, 182, 172, 127, 36, 52, 51, 41, 45, 41, 33, 30, 38, 24, 35, 30, - 65, 139, 142, 141, 149, 149, 149, 148, 151, 152, 146, 137, 133, 129, 135, 135, - 137, 165, 177, 148, 159, 153, 148, 147, 151, 154, 152, 147, 145, 141, 142, 147, - 148, 144, 142, 142, 134, 145, 128, 114, 44, 62, 54, 64, 66, 76, 82, 141, - 140, 139, 141, 143, 144, 140, 138, 139, 133, 135, 139, 136, 141, 144, 136, 125, - 140, 138, 126, 128, 126, 115, 109, 100, 101, 90, 80, 102, 144, 167, 160, 153, - 149, 150, 148, 146, 144, 142, 142, 148, 147, 146, 148, 154, 156, 155, 153, 163, - 153, 158, 171, 176, 178, 173, 158, 155, 138, 145, 156, 120, 51, 19, 30, 29, - 32, 36, 34, 35, 47, 69, 86, 115, 139, 154, 144, 134, 140, 152, 156, 151, - 152, 154, 152, 153, 156, 166, 173, 172, 175, 178, 180, 181, 181, 184, 185, 179, - 185, 186, 180, 176, 177, 180, 180, 179, 182, 189, 194, 191, 180, 176, 176, 178, - 182, 185, 189, 189, 188, 185, 184, 188, 181, 181, 181, 174, 175, 174, 165, 161, - 165, 149, 89, 37, 16, 20, 47, 39, 43, 78, 133, 168, 164, 152, 150, 167, - 167, 180, 180, 167, 170, 166, 141, 123, 78, 41, 40, 47, 35, 33, 45, 31, - 33, 31, 34, 36, 128, 142, 151, 151, 150, 150, 149, 153, 155, 149, 140, 139, - 137, 139, 130, 128, 153, 171, 157, 163, 156, 150, 149, 152, 152, 149, 144, 141, - 138, 139, 145, 147, 144, 143, 144, 129, 141, 128, 128, 54, 65, 65, 68, 67, - 75, 77, 149, 144, 140, 140, 143, 144, 141, 137, 141, 133, 137, 141, 137, 141, - 144, 137, 123, 138, 138, 129, 128, 126, 119, 117, 119, 119, 111, 100, 97, 114, - 138, 149, 153, 146, 149, 151, 148, 144, 141, 137, 149, 145, 143, 143, 145, 145, - 145, 143, 139, 158, 182, 182, 159, 150, 160, 165, 152, 152, 149, 144, 132, 106, - 68, 37, 41, 51, 64, 74, 89, 113, 145, 168, 160, 154, 155, 159, 158, 152, - 153, 159, 157, 161, 166, 166, 163, 159, 160, 160, 163, 164, 168, 175, 177, 177, - 181, 185, 177, 180, 182, 179, 177, 182, 184, 184, 181, 173, 176, 193, 204, 198, - 183, 173, 175, 179, 183, 187, 188, 186, 183, 183, 186, 179, 181, 183, 176, 176, - 174, 165, 174, 175, 167, 139, 100, 68, 51, 43, 34, 57, 63, 63, 97, 152, - 175, 162, 147, 145, 155, 166, 169, 172, 171, 162, 160, 137, 100, 55, 27, 39, - 50, 35, 26, 36, 27, 38, 25, 101, 144, 156, 151, 150, 150, 148, 151, 154, - 149, 141, 146, 140, 137, 143, 140, 132, 143, 167, 164, 161, 158, 157, 157, 153, - 147, 143, 142, 138, 139, 144, 147, 144, 143, 145, 142, 140, 125, 128, 57, 51, - 61, 58, 52, 60, 63, 144, 143, 141, 141, 140, 141, 140, 139, 141, 134, 137, - 139, 135, 137, 140, 132, 130, 136, 131, 124, 127, 129, 129, 139, 123, 114, 119, - 126, 111, 88, 91, 105, 132, 131, 143, 149, 148, 145, 144, 145, 148, 147, 146, - 142, 139, 140, 147, 153, 178, 170, 168, 168, 170, 179, 178, 160, 155, 172, 167, - 150, 155, 160, 118, 55, 94, 113, 138, 157, 164, 161, 157, 154, 166, 157, 155, - 161, 167, 164, 160, 161, 167, 171, 176, 176, 173, 169, 167, 167, 163, 160, 163, - 168, 169, 169, 172, 178, 177, 178, 179, 180, 184, 186, 179, 170, 170, 145, 127, - 127, 141, 157, 180, 195, 175, 176, 179, 181, 181, 181, 182, 184, 184, 178, 182, - 185, 179, 178, 175, 165, 164, 160, 152, 150, 144, 125, 86, 39, 52, 32, 26, - 39, 46, 59, 106, 159, 171, 173, 164, 158, 163, 162, 156, 156, 150, 162, 162, - 99, 29, 42, 64, 30, 26, 33, 29, 36, 35, 69, 153, 157, 152, 153, 153, - 150, 152, 154, 150, 143, 145, 149, 144, 149, 149, 117, 108, 147, 163, 163, 164, - 163, 160, 154, 147, 144, 145, 143, 143, 146, 147, 144, 142, 144, 152, 135, 125, - 132, 70, 41, 56, 43, 39, 46, 51, 131, 136, 140, 141, 138, 137, 140, 141, - 142, 134, 135, 137, 131, 132, 134, 126, 131, 133, 129, 127, 133, 128, 124, 131, - 137, 142, 137, 125, 120, 122, 120, 103, 104, 112, 132, 142, 142, 142, 148, 153, - 147, 151, 151, 145, 139, 142, 158, 172, 168, 166, 167, 164, 162, 172, 170, 152, - 152, 148, 154, 163, 158, 144, 144, 157, 165, 162, 157, 155, 158, 162, 166, 167, - 157, 174, 178, 165, 163, 176, 180, 171, 171, 173, 175, 173, 172, 172, 175, 177, - 168, 162, 160, 162, 162, 158, 163, 170, 176, 172, 170, 173, 181, 181, 164, 147, - 99, 95, 95, 99, 96, 100, 122, 145, 175, 175, 175, 175, 175, 177, 181, 185, - 182, 177, 182, 187, 181, 180, 176, 165, 165, 172, 165, 156, 149, 150, 137, 96, - 64, 47, 43, 52, 48, 39, 53, 83, 123, 148, 151, 145, 158, 161, 157, 163, - 170, 138, 149, 135, 61, 36, 57, 49, 31, 30, 34, 33, 51, 50, 162, 156, - 155, 157, 157, 154, 154, 155, 152, 147, 135, 162, 155, 145, 147, 112, 87, 112, - 161, 165, 168, 168, 161, 153, 147, 145, 150, 148, 146, 149, 148, 144, 142, 143, - 147, 124, 126, 143, 94, 51, 67, 47, 45, 53, 59, 137, 139, 139, 136, 136, - 141, 141, 139, 138, 137, 137, 136, 134, 133, 131, 131, 132, 132, 133, 131, 132, - 132, 134, 137, 138, 140, 140, 136, 135, 133, 126, 108, 104, 73, 117, 161, 139, - 139, 162, 152, 151, 159, 147, 135, 148, 167, 170, 165, 166, 161, 157, 159, 161, - 161, 152, 145, 161, 152, 145, 145, 146, 147, 156, 168, 160, 159, 158, 157, 158, - 161, 165, 167, 171, 173, 178, 179, 178, 174, 171, 168, 189, 181, 176, 177, 184, - 188, 184, 178, 181, 177, 170, 168, 167, 164, 162, 158, 158, 161, 155, 148, 161, - 169, 130, 79, 87, 99, 70, 79, 89, 102, 111, 117, 154, 173, 174, 165, 168, - 174, 177, 183, 177, 175, 174, 177, 182, 183, 175, 169, 171, 172, 168, 157, 151, - 151, 148, 142, 121, 92, 58, 42, 44, 48, 43, 37, 49, 108, 160, 159, 145, - 143, 153, 155, 155, 160, 170, 137, 123, 57, 30, 60, 41, 27, 34, 44, 32, - 73, 153, 167, 150, 162, 163, 151, 149, 158, 157, 146, 139, 149, 148, 145, 149, - 137, 108, 92, 132, 179, 178, 179, 170, 157, 155, 141, 149, 150, 146, 141, 141, - 143, 140, 135, 135, 129, 127, 139, 102, 56, 64, 78, 62, 72, 92, 138, 140, - 139, 136, 136, 138, 140, 138, 136, 136, 136, 136, 134, 133, 132, 129, 132, 131, - 132, 130, 131, 133, 137, 140, 136, 140, 143, 143, 145, 146, 144, 129, 121, 89, - 105, 131, 138, 160, 172, 143, 132, 121, 115, 138, 165, 171, 176, 192, 149, 145, - 145, 151, 155, 158, 157, 153, 154, 152, 154, 158, 158, 153, 152, 158, 162, 164, - 167, 168, 169, 170, 171, 171, 174, 175, 179, 179, 178, 176, 174, 172, 183, 178, - 174, 176, 184, 185, 183, 179, 183, 180, 177, 175, 175, 172, 166, 162, 160, 157, - 152, 142, 133, 122, 105, 88, 75, 92, 95, 83, 79, 89, 95, 100, 107, 137, - 160, 169, 179, 180, 172, 171, 183, 182, 180, 177, 175, 173, 170, 170, 169, 172, - 170, 162, 159, 160, 157, 152, 143, 144, 131, 96, 57, 34, 37, 48, 33, 50, - 81, 120, 153, 164, 153, 138, 170, 159, 158, 152, 164, 113, 41, 24, 31, 30, - 32, 39, 46, 95, 163, 169, 151, 158, 162, 156, 154, 158, 155, 146, 141, 146, - 143, 141, 144, 134, 107, 91, 55, 133, 163, 166, 159, 155, 164, 155, 145, 148, - 147, 143, 144, 145, 141, 135, 147, 133, 122, 135, 111, 76, 76, 75, 89, 92, - 100, 139, 142, 139, 135, 134, 138, 138, 135, 135, 135, 135, 135, 135, 134, 133, - 131, 132, 131, 131, 130, 131, 134, 139, 144, 138, 143, 145, 145, 149, 153, 153, - 143, 135, 122, 112, 98, 92, 106, 107, 80, 57, 81, 123, 169, 187, 164, 141, - 144, 148, 150, 154, 160, 165, 167, 169, 169, 157, 158, 163, 167, 166, 160, 156, - 156, 162, 166, 170, 173, 175, 174, 171, 169, 173, 174, 174, 174, 174, 173, 172, - 171, 175, 176, 174, 176, 180, 181, 181, 179, 181, 182, 184, 186, 186, 183, 176, - 172, 168, 160, 159, 156, 134, 101, 83, 82, 77, 79, 54, 70, 69, 90, 79, - 116, 123, 148, 165, 173, 184, 188, 185, 187, 184, 185, 183, 179, 173, 173, 175, - 181, 171, 173, 173, 169, 167, 167, 164, 159, 151, 156, 156, 140, 118, 102, 100, - 105, 92, 64, 50, 70, 98, 118, 139, 161, 149, 148, 145, 151, 159, 134, 59, - 34, 26, 36, 30, 41, 77, 128, 174, 171, 154, 154, 157, 159, 160, 157, 151, - 147, 146, 144, 140, 139, 140, 132, 112, 97, 71, 92, 116, 159, 183, 162, 162, - 166, 144, 148, 148, 145, 145, 145, 142, 136, 134, 126, 118, 130, 116, 94, 98, - 91, 103, 100, 94, 140, 143, 140, 136, 135, 137, 136, 132, 134, 134, 134, 135, - 135, 135, 134, 132, 131, 131, 131, 130, 132, 135, 142, 147, 142, 146, 147, 145, - 149, 153, 152, 145, 141, 145, 132, 105, 95, 97, 87, 73, 59, 120, 163, 164, - 158, 154, 150, 148, 160, 165, 171, 174, 173, 171, 171, 171, 167, 165, 166, 165, - 167, 166, 167, 169, 167, 171, 174, 177, 178, 177, 174, 172, 176, 177, 177, 176, - 176, 177, 178, 178, 175, 176, 178, 178, 178, 178, 178, 180, 178, 180, 185, 188, - 190, 189, 185, 183, 181, 167, 164, 165, 156, 129, 108, 99, 82, 100, 87, 60, - 76, 79, 118, 102, 142, 156, 160, 159, 167, 174, 178, 188, 189, 190, 188, 184, - 179, 177, 179, 183, 176, 178, 179, 178, 175, 172, 168, 165, 171, 164, 159, 159, - 162, 159, 149, 139, 141, 121, 107, 104, 97, 92, 108, 132, 145, 157, 156, 159, - 145, 133, 66, 43, 29, 38, 28, 58, 121, 160, 177, 172, 159, 150, 151, 158, - 160, 153, 147, 147, 148, 144, 144, 145, 139, 133, 125, 115, 112, 80, 78, 120, - 171, 153, 145, 153, 148, 150, 149, 145, 143, 143, 142, 138, 135, 139, 134, 133, - 104, 81, 88, 84, 94, 98, 94, 140, 141, 140, 136, 135, 137, 135, 131, 133, - 133, 134, 135, 133, 133, 132, 132, 130, 131, 131, 130, 132, 137, 142, 147, 146, - 149, 149, 146, 149, 153, 153, 148, 156, 155, 139, 127, 130, 115, 91, 77, 92, - 149, 172, 144, 135, 154, 166, 165, 159, 166, 172, 173, 169, 162, 159, 157, 167, - 166, 167, 165, 168, 172, 176, 178, 178, 179, 180, 181, 181, 183, 182, 182, 184, - 184, 183, 183, 183, 186, 187, 188, 180, 182, 184, 182, 180, 178, 179, 179, 178, - 179, 181, 182, 183, 184, 183, 183, 184, 175, 164, 159, 162, 165, 158, 148, 117, - 115, 52, 126, 65, 77, 121, 135, 135, 150, 157, 161, 170, 172, 171, 178, 196, - 194, 191, 189, 185, 182, 176, 174, 182, 183, 185, 187, 186, 182, 178, 176, 170, - 170, 169, 165, 160, 157, 158, 159, 159, 153, 148, 144, 136, 126, 114, 107, 121, - 126, 126, 140, 142, 143, 72, 28, 31, 36, 32, 85, 159, 177, 175, 174, 164, - 150, 146, 153, 157, 150, 145, 147, 145, 140, 147, 149, 137, 134, 138, 136, 105, - 103, 103, 91, 130, 143, 154, 151, 151, 153, 150, 143, 139, 140, 140, 138, 126, - 133, 130, 129, 102, 83, 90, 84, 89, 96, 96, 137, 140, 140, 137, 136, 137, - 135, 131, 134, 134, 135, 135, 133, 132, 131, 131, 130, 131, 132, 133, 134, 136, - 141, 144, 145, 148, 149, 149, 151, 158, 158, 155, 157, 157, 150, 142, 131, 104, - 87, 89, 117, 146, 160, 157, 160, 162, 154, 147, 159, 165, 169, 171, 166, 161, - 157, 156, 159, 164, 169, 171, 173, 178, 178, 178, 183, 182, 181, 181, 181, 183, - 183, 184, 182, 184, 184, 184, 185, 187, 188, 189, 188, 187, 188, 187, 185, 183, - 182, 181, 180, 181, 182, 180, 179, 176, 176, 177, 172, 182, 181, 169, 165, 172, - 172, 163, 170, 156, 179, 255, 90, 69, 131, 126, 148, 160, 163, 167, 176, 177, - 176, 185, 186, 187, 188, 191, 191, 190, 184, 181, 186, 186, 189, 194, 195, 192, - 190, 191, 175, 175, 172, 167, 163, 163, 167, 171, 164, 163, 159, 147, 144, 149, - 146, 138, 139, 130, 131, 137, 145, 151, 96, 54, 37, 45, 54, 116, 177, 176, - 172, 176, 169, 154, 146, 149, 154, 150, 145, 143, 143, 133, 144, 151, 137, 136, - 150, 149, 114, 108, 123, 104, 140, 139, 146, 148, 148, 151, 150, 143, 139, 139, - 139, 138, 128, 126, 118, 125, 108, 89, 90, 77, 71, 78, 77, 136, 139, 140, - 137, 136, 137, 136, 132, 135, 135, 135, 135, 132, 131, 130, 129, 129, 132, 134, - 135, 135, 136, 138, 142, 142, 146, 147, 148, 152, 156, 157, 155, 148, 155, 158, - 151, 133, 125, 138, 154, 169, 168, 161, 158, 168, 167, 161, 165, 162, 166, 165, - 164, 162, 161, 163, 165, 160, 168, 173, 174, 179, 184, 184, 181, 181, 181, 181, - 181, 180, 183, 183, 183, 182, 183, 184, 185, 186, 188, 189, 188, 191, 190, 190, - 190, 190, 189, 187, 184, 182, 185, 189, 188, 186, 181, 180, 180, 175, 188, 193, - 183, 175, 174, 167, 158, 159, 186, 150, 72, 167, 157, 169, 162, 159, 164, 158, - 158, 167, 172, 177, 191, 183, 189, 194, 196, 195, 193, 192, 193, 189, 187, 190, - 196, 197, 193, 190, 193, 201, 190, 177, 173, 175, 175, 168, 161, 153, 165, 172, - 166, 157, 157, 156, 154, 156, 138, 143, 121, 112, 97, 60, 27, 53, 76, 99, - 147, 176, 166, 170, 175, 170, 159, 150, 150, 155, 155, 146, 137, 148, 129, 140, - 152, 141, 144, 158, 151, 128, 91, 114, 120, 171, 144, 124, 128, 140, 145, 149, - 145, 141, 140, 139, 137, 146, 140, 128, 131, 102, 69, 63, 54, 60, 65, 73, - 135, 139, 140, 137, 136, 138, 136, 131, 136, 136, 136, 133, 132, 131, 129, 129, - 130, 133, 136, 138, 138, 137, 138, 141, 141, 145, 146, 147, 150, 153, 153, 149, - 169, 156, 143, 136, 132, 148, 169, 171, 158, 165, 161, 153, 160, 165, 165, 172, - 161, 158, 155, 152, 152, 154, 160, 162, 171, 176, 177, 174, 178, 187, 191, 188, - 183, 184, 187, 188, 187, 187, 185, 185, 188, 189, 190, 192, 194, 195, 195, 194, - 190, 188, 189, 190, 192, 192, 190, 185, 180, 187, 195, 198, 198, 194, 191, 192, - 195, 192, 183, 177, 179, 181, 180, 174, 180, 139, 166, 175, 155, 175, 157, 163, - 157, 164, 166, 172, 184, 189, 192, 205, 200, 206, 211, 205, 194, 185, 187, 192, - 189, 188, 189, 194, 194, 188, 185, 189, 182, 180, 178, 179, 183, 185, 184, 181, - 180, 174, 167, 163, 164, 164, 165, 168, 170, 150, 171, 155, 158, 130, 92, 49, - 71, 108, 139, 167, 169, 157, 169, 172, 171, 162, 155, 153, 158, 159, 147, 133, - 154, 128, 137, 155, 147, 154, 163, 149, 119, 99, 132, 128, 185, 171, 149, 133, - 133, 141, 149, 149, 145, 143, 140, 135, 118, 121, 126, 133, 100, 61, 69, 75, - 90, 89, 95, 138, 138, 138, 137, 136, 135, 134, 133, 133, 133, 134, 132, 129, - 128, 128, 128, 133, 136, 138, 140, 140, 140, 141, 144, 144, 151, 155, 151, 149, - 152, 152, 147, 145, 147, 123, 129, 144, 174, 164, 156, 161, 166, 156, 167, 150, - 137, 112, 126, 130, 138, 144, 145, 148, 159, 168, 173, 166, 171, 178, 181, 185, - 186, 188, 190, 182, 182, 184, 184, 185, 187, 189, 190, 185, 191, 194, 193, 193, - 195, 196, 193, 194, 193, 196, 192, 189, 188, 187, 188, 190, 197, 196, 195, 198, - 194, 190, 195, 200, 196, 190, 185, 182, 178, 175, 172, 171, 169, 167, 167, 170, - 170, 167, 164, 173, 176, 178, 172, 167, 169, 178, 188, 205, 211, 207, 191, 182, - 183, 185, 180, 174, 178, 184, 188, 184, 179, 182, 189, 187, 185, 182, 177, 177, - 176, 176, 177, 174, 184, 186, 177, 175, 183, 186, 184, 174, 169, 172, 172, 161, - 149, 127, 96, 116, 136, 158, 168, 172, 173, 170, 165, 179, 163, 153, 157, 165, - 161, 148, 137, 144, 150, 141, 130, 152, 185, 177, 142, 127, 70, 105, 147, 166, - 157, 168, 174, 146, 131, 144, 155, 144, 140, 139, 127, 126, 121, 125, 133, 84, - 89, 91, 85, 92, 102, 105, 137, 137, 137, 137, 137, 137, 136, 136, 130, 132, - 132, 131, 129, 128, 127, 130, 135, 139, 141, 142, 141, 141, 142, 143, 148, 153, - 154, 150, 149, 150, 149, 144, 157, 143, 133, 164, 162, 163, 148, 154, 138, 160, - 171, 129, 101, 72, 48, 67, 71, 95, 126, 147, 159, 166, 167, 164, 175, 178, - 183, 184, 185, 184, 184, 186, 185, 186, 186, 187, 188, 190, 191, 192, 191, 196, - 198, 196, 194, 196, 196, 193, 194, 194, 196, 196, 194, 191, 192, 191, 187, 193, - 193, 191, 197, 192, 188, 194, 192, 190, 188, 186, 183, 181, 175, 172, 171, 170, - 169, 171, 176, 177, 179, 178, 178, 179, 180, 179, 178, 175, 174, 174, 182, 195, - 200, 193, 187, 185, 181, 173, 178, 176, 180, 186, 188, 184, 181, 182, 185, 184, - 182, 181, 180, 180, 181, 181, 177, 186, 188, 180, 177, 183, 183, 178, 193, 185, - 183, 180, 172, 172, 165, 146, 146, 158, 169, 170, 170, 170, 170, 167, 177, 168, - 165, 169, 171, 164, 150, 139, 131, 142, 154, 155, 159, 162, 154, 142, 120, 74, - 113, 148, 165, 157, 165, 168, 187, 151, 137, 144, 147, 152, 146, 125, 122, 116, - 122, 134, 88, 87, 92, 91, 112, 116, 118, 136, 136, 137, 138, 137, 138, 138, - 138, 131, 132, 133, 133, 131, 131, 130, 134, 135, 140, 142, 142, 142, 142, 142, - 144, 147, 149, 150, 146, 146, 148, 149, 145, 155, 136, 146, 187, 172, 167, 158, - 160, 161, 167, 152, 62, 54, 54, 76, 120, 116, 135, 157, 165, 168, 168, 169, - 167, 174, 177, 180, 181, 181, 179, 180, 180, 188, 189, 190, 190, 192, 193, 195, - 196, 194, 199, 201, 198, 197, 199, 200, 197, 193, 195, 199, 200, 199, 195, 194, - 193, 186, 193, 191, 189, 194, 191, 187, 193, 185, 185, 185, 186, 186, 183, 176, - 172, 172, 170, 170, 173, 179, 184, 189, 191, 190, 184, 181, 180, 184, 183, 177, - 170, 170, 183, 191, 189, 187, 185, 181, 171, 179, 172, 172, 181, 190, 190, 185, - 180, 182, 182, 182, 183, 183, 183, 184, 184, 180, 188, 190, 184, 181, 184, 182, - 176, 187, 180, 178, 173, 167, 174, 179, 168, 166, 171, 176, 174, 172, 170, 168, - 166, 171, 168, 171, 176, 175, 164, 150, 141, 130, 137, 156, 169, 165, 149, 142, - 148, 111, 92, 139, 157, 160, 150, 164, 172, 186, 150, 129, 130, 139, 146, 139, - 119, 122, 118, 125, 131, 87, 80, 89, 93, 98, 101, 103, 138, 138, 138, 138, - 137, 138, 137, 137, 133, 134, 135, 135, 134, 134, 135, 139, 135, 140, 142, 143, - 144, 143, 145, 146, 142, 142, 143, 143, 146, 150, 152, 148, 149, 140, 156, 187, - 164, 177, 173, 156, 161, 160, 107, 49, 60, 59, 81, 106, 141, 153, 164, 164, - 163, 168, 177, 182, 170, 173, 177, 179, 181, 181, 183, 187, 191, 191, 192, 192, - 194, 195, 197, 198, 195, 200, 202, 199, 198, 201, 203, 201, 194, 196, 199, 200, - 199, 196, 192, 191, 191, 198, 195, 191, 195, 190, 187, 192, 186, 184, 186, 187, - 187, 185, 178, 174, 171, 170, 170, 173, 178, 185, 192, 195, 198, 189, 180, 177, - 180, 183, 182, 179, 180, 184, 186, 181, 179, 180, 181, 177, 177, 168, 166, 175, - 185, 187, 186, 183, 180, 181, 182, 182, 183, 183, 183, 183, 183, 189, 192, 189, - 188, 189, 185, 179, 188, 185, 188, 185, 177, 181, 186, 177, 166, 170, 177, 180, - 181, 178, 174, 170, 170, 166, 170, 177, 178, 168, 155, 145, 145, 137, 144, 161, - 167, 159, 153, 154, 119, 106, 143, 147, 156, 154, 161, 162, 143, 130, 125, 127, - 130, 131, 125, 117, 122, 126, 128, 110, 74, 71, 82, 81, 88, 95, 100, 139, - 139, 138, 137, 136, 135, 134, 133, 132, 133, 134, 134, 132, 134, 136, 139, 134, - 138, 141, 143, 144, 145, 148, 149, 142, 139, 140, 142, 147, 149, 151, 149, 151, - 142, 159, 188, 167, 179, 173, 152, 150, 140, 54, 55, 66, 58, 76, 85, 133, - 148, 162, 166, 167, 168, 172, 172, 175, 178, 182, 186, 188, 189, 192, 196, 192, - 193, 193, 194, 195, 197, 198, 199, 200, 204, 205, 200, 198, 201, 202, 199, 198, - 200, 203, 202, 201, 196, 193, 190, 194, 200, 196, 191, 194, 188, 186, 190, 188, - 185, 184, 182, 182, 180, 177, 174, 173, 172, 171, 172, 174, 180, 186, 191, 195, - 189, 183, 177, 177, 179, 180, 181, 185, 186, 183, 177, 176, 178, 181, 180, 177, - 171, 169, 173, 177, 179, 180, 184, 180, 180, 180, 180, 180, 180, 181, 181, 181, - 186, 189, 191, 192, 192, 188, 183, 188, 187, 192, 189, 179, 182, 186, 177, 167, - 166, 171, 177, 183, 183, 180, 179, 174, 165, 164, 171, 177, 173, 162, 152, 148, - 144, 146, 151, 162, 166, 161, 152, 130, 112, 134, 135, 160, 162, 150, 131, 116, - 123, 127, 129, 132, 129, 124, 124, 119, 131, 126, 87, 64, 71, 84, 76, 88, - 102, 113, 140, 139, 138, 137, 135, 134, 131, 131, 130, 131, 131, 130, 129, 130, - 133, 137, 134, 139, 141, 143, 144, 144, 147, 148, 146, 140, 140, 145, 149, 146, - 145, 142, 136, 126, 143, 186, 172, 173, 164, 161, 159, 119, 29, 54, 58, 69, - 107, 132, 151, 161, 169, 171, 171, 170, 170, 167, 180, 183, 187, 187, 188, 188, - 190, 194, 193, 194, 194, 195, 196, 198, 199, 200, 205, 208, 207, 201, 197, 198, - 199, 197, 203, 204, 206, 205, 202, 199, 195, 194, 193, 197, 194, 189, 192, 188, - 184, 188, 189, 185, 182, 181, 180, 178, 175, 173, 174, 173, 172, 171, 170, 172, - 179, 182, 188, 190, 192, 188, 184, 180, 180, 180, 179, 178, 178, 178, 179, 180, - 178, 177, 180, 175, 174, 173, 172, 170, 173, 179, 179, 178, 177, 176, 177, 178, - 180, 181, 178, 180, 184, 188, 191, 191, 188, 184, 183, 179, 181, 177, 169, 175, - 182, 174, 169, 161, 157, 162, 169, 172, 174, 177, 171, 160, 155, 160, 168, 167, - 160, 152, 138, 150, 157, 156, 156, 157, 153, 144, 115, 122, 155, 145, 153, 139, - 129, 125, 126, 130, 123, 123, 134, 134, 126, 127, 126, 134, 124, 80, 76, 86, - 102, 91, 89, 105, 116, 137, 136, 135, 134, 133, 132, 131, 131, 133, 134, 132, - 130, 129, 131, 134, 137, 137, 139, 143, 143, 143, 142, 143, 144, 149, 142, 138, - 145, 150, 147, 144, 137, 124, 130, 141, 169, 160, 166, 159, 167, 153, 89, 60, - 77, 89, 103, 120, 139, 152, 156, 159, 161, 169, 178, 184, 183, 182, 183, 186, - 185, 185, 185, 189, 190, 194, 195, 196, 196, 197, 199, 201, 202, 204, 208, 207, - 201, 199, 201, 202, 201, 202, 204, 205, 204, 201, 199, 199, 197, 190, 196, 193, - 189, 194, 191, 189, 193, 189, 186, 186, 186, 185, 182, 178, 175, 175, 176, 175, - 173, 170, 170, 174, 177, 179, 181, 185, 184, 184, 183, 186, 187, 179, 177, 178, - 178, 180, 179, 179, 179, 181, 175, 176, 177, 177, 173, 173, 177, 177, 175, 174, - 173, 175, 178, 183, 185, 180, 179, 181, 187, 191, 191, 188, 185, 188, 184, 186, - 184, 178, 184, 189, 179, 169, 157, 152, 156, 163, 164, 165, 167, 170, 161, 157, - 159, 162, 160, 156, 153, 143, 151, 158, 158, 153, 149, 145, 139, 107, 127, 165, - 147, 141, 121, 123, 140, 136, 144, 130, 121, 132, 132, 124, 130, 134, 128, 117, - 87, 101, 100, 113, 107, 105, 117, 125, 133, 133, 133, 133, 133, 132, 132, 132, - 137, 138, 135, 133, 132, 133, 137, 140, 140, 141, 144, 143, 141, 139, 140, 140, - 145, 139, 137, 145, 151, 149, 146, 137, 134, 162, 160, 151, 138, 160, 159, 161, - 152, 61, 87, 91, 127, 162, 161, 174, 168, 170, 173, 175, 181, 185, 182, 176, - 184, 186, 188, 188, 188, 189, 193, 196, 197, 197, 197, 198, 199, 201, 202, 203, - 199, 203, 204, 201, 201, 206, 209, 209, 200, 201, 201, 200, 199, 198, 199, 200, - 191, 196, 193, 192, 197, 197, 196, 202, 190, 189, 192, 194, 194, 190, 184, 180, - 177, 178, 179, 174, 171, 170, 172, 175, 170, 167, 165, 167, 174, 181, 189, 193, - 191, 183, 178, 176, 177, 177, 183, 183, 177, 172, 174, 181, 184, 181, 178, 178, - 177, 174, 172, 171, 174, 180, 186, 190, 184, 182, 183, 188, 192, 192, 189, 187, - 182, 180, 186, 188, 182, 185, 183, 168, 170, 160, 158, 167, 174, 170, 165, 163, - 175, 170, 169, 169, 166, 161, 160, 160, 157, 150, 148, 151, 156, 152, 144, 138, - 127, 122, 140, 125, 142, 135, 132, 141, 136, 153, 148, 131, 133, 127, 124, 139, - 135, 115, 103, 87, 111, 96, 104, 106, 112, 119, 121, 131, 133, 134, 132, 132, - 134, 135, 131, 136, 132, 130, 132, 137, 141, 140, 138, 142, 137, 136, 137, 143, - 144, 142, 137, 149, 147, 157, 149, 143, 145, 140, 140, 153, 168, 157, 146, 141, - 136, 151, 154, 145, 81, 100, 134, 142, 155, 156, 168, 167, 171, 176, 182, 186, - 186, 185, 183, 186, 188, 190, 191, 195, 196, 197, 198, 203, 207, 208, 207, 205, - 204, 205, 206, 210, 207, 205, 204, 205, 205, 204, 202, 210, 207, 203, 197, 194, - 192, 192, 191, 194, 195, 196, 195, 193, 192, 197, 200, 192, 195, 194, 194, 171, - 190, 180, 177, 175, 178, 181, 178, 176, 179, 186, 188, 183, 183, 174, 168, 172, - 170, 174, 186, 185, 188, 189, 183, 176, 173, 179, 183, 178, 185, 188, 180, 175, - 178, 181, 180, 173, 175, 175, 174, 174, 176, 177, 181, 182, 183, 186, 189, 192, - 192, 189, 186, 190, 187, 184, 181, 177, 175, 176, 178, 166, 158, 161, 175, 183, - 177, 174, 178, 163, 167, 173, 174, 171, 168, 167, 165, 159, 146, 152, 159, 154, - 147, 144, 136, 130, 116, 139, 137, 136, 149, 142, 147, 152, 154, 148, 133, 127, - 131, 134, 133, 129, 112, 102, 90, 97, 104, 99, 114, 107, 119, 125, 129, 133, - 134, 132, 132, 134, 135, 131, 136, 136, 136, 135, 136, 138, 142, 144, 143, 141, - 140, 138, 140, 140, 142, 142, 154, 147, 156, 146, 142, 147, 141, 139, 165, 175, - 159, 148, 142, 135, 145, 146, 145, 103, 123, 140, 142, 162, 167, 168, 172, 174, - 178, 182, 185, 184, 183, 182, 188, 188, 190, 192, 195, 196, 197, 198, 199, 202, - 204, 204, 203, 203, 205, 207, 207, 205, 203, 203, 204, 204, 203, 202, 209, 207, - 203, 198, 195, 193, 193, 193, 196, 193, 192, 194, 196, 197, 198, 196, 187, 189, - 185, 189, 175, 190, 174, 173, 180, 170, 172, 178, 182, 188, 187, 174, 171, 179, - 180, 180, 184, 176, 164, 167, 176, 180, 183, 182, 179, 176, 178, 180, 180, 185, - 189, 184, 181, 181, 183, 182, 178, 178, 176, 175, 175, 175, 175, 177, 178, 182, - 188, 194, 197, 198, 197, 197, 183, 184, 185, 184, 181, 176, 173, 170, 168, 159, - 162, 176, 183, 174, 164, 161, 173, 175, 178, 174, 168, 162, 159, 156, 156, 150, - 157, 163, 154, 145, 145, 140, 121, 116, 142, 145, 144, 155, 147, 153, 146, 149, - 145, 133, 130, 136, 138, 135, 131, 103, 95, 90, 96, 105, 100, 109, 110, 119, - 124, 129, 132, 133, 130, 131, 134, 133, 130, 137, 139, 142, 139, 136, 137, 143, - 148, 139, 140, 141, 139, 138, 140, 147, 152, 150, 142, 149, 141, 139, 146, 139, - 137, 175, 178, 159, 148, 145, 140, 145, 140, 135, 121, 139, 142, 140, 164, 173, - 167, 177, 180, 181, 183, 184, 183, 182, 181, 188, 189, 191, 192, 195, 196, 198, - 199, 197, 201, 203, 203, 204, 205, 208, 211, 206, 204, 203, 203, 205, 205, 204, - 203, 206, 205, 200, 198, 196, 194, 195, 194, 197, 192, 190, 194, 197, 200, 198, - 192, 184, 191, 182, 187, 183, 185, 169, 170, 172, 164, 176, 179, 166, 174, 192, - 190, 181, 186, 183, 181, 187, 181, 173, 175, 169, 172, 177, 181, 183, 182, 180, - 176, 181, 185, 189, 188, 185, 185, 184, 183, 184, 181, 177, 176, 174, 174, 174, - 173, 174, 180, 187, 190, 188, 185, 184, 184, 184, 184, 183, 181, 177, 174, 171, - 166, 167, 159, 163, 178, 188, 183, 174, 170, 169, 170, 172, 169, 165, 162, 160, - 160, 157, 155, 164, 168, 153, 144, 142, 137, 112, 121, 147, 152, 151, 157, 152, - 157, 146, 147, 144, 135, 132, 138, 138, 136, 132, 91, 90, 96, 95, 105, 105, - 108, 121, 126, 125, 128, 132, 132, 130, 131, 134, 134, 131, 137, 139, 142, 142, - 140, 140, 142, 143, 133, 133, 136, 140, 143, 149, 154, 157, 146, 141, 148, 141, - 138, 145, 142, 142, 172, 175, 154, 147, 151, 149, 152, 144, 133, 131, 142, 146, - 147, 165, 175, 167, 177, 179, 179, 180, 181, 181, 182, 182, 189, 189, 191, 192, - 195, 197, 198, 200, 204, 206, 208, 208, 208, 210, 212, 215, 205, 204, 204, 205, - 207, 207, 206, 204, 202, 199, 198, 196, 195, 194, 195, 193, 196, 194, 194, 195, - 197, 197, 194, 190, 187, 200, 186, 187, 188, 177, 169, 168, 175, 167, 184, 188, - 166, 165, 178, 172, 185, 190, 184, 179, 187, 189, 185, 187, 172, 172, 175, 180, - 184, 185, 182, 176, 179, 183, 188, 188, 187, 186, 185, 183, 187, 183, 178, 176, - 175, 176, 174, 173, 185, 192, 199, 200, 195, 189, 188, 189, 193, 189, 181, 172, - 168, 169, 169, 165, 152, 150, 156, 169, 179, 177, 174, 174, 163, 163, 165, 163, - 162, 161, 160, 160, 164, 160, 166, 167, 153, 144, 138, 128, 109, 130, 149, 153, - 153, 152, 149, 157, 149, 150, 145, 134, 133, 138, 136, 133, 128, 83, 93, 104, - 95, 103, 113, 113, 104, 108, 106, 128, 129, 132, 129, 129, 133, 135, 132, 136, - 136, 139, 142, 145, 144, 140, 135, 133, 131, 133, 142, 150, 155, 154, 150, 148, - 146, 155, 143, 136, 143, 140, 144, 168, 171, 155, 153, 160, 159, 161, 153, 149, - 143, 141, 155, 161, 165, 170, 168, 174, 176, 176, 177, 179, 181, 183, 183, 189, - 191, 193, 195, 197, 198, 199, 200, 209, 212, 214, 214, 213, 212, 213, 214, 204, - 203, 203, 204, 206, 206, 204, 201, 197, 196, 196, 196, 196, 196, 197, 196, 197, - 199, 202, 199, 196, 192, 191, 191, 187, 201, 190, 188, 188, 174, 178, 163, 124, - 115, 134, 165, 180, 187, 183, 164, 172, 183, 186, 185, 193, 192, 181, 178, 179, - 176, 173, 175, 180, 182, 181, 176, 177, 179, 184, 187, 186, 185, 183, 182, 186, - 183, 179, 178, 176, 177, 176, 177, 180, 187, 196, 198, 195, 192, 192, 194, 195, - 192, 182, 171, 167, 169, 167, 159, 155, 160, 174, 185, 188, 182, 177, 177, 169, - 167, 167, 164, 161, 159, 156, 156, 164, 157, 159, 160, 153, 148, 139, 123, 109, - 139, 149, 151, 156, 151, 152, 159, 150, 150, 144, 133, 132, 137, 135, 129, 116, - 81, 99, 107, 94, 101, 115, 120, 118, 123, 123, 129, 129, 131, 128, 129, 133, - 135, 133, 137, 135, 137, 140, 145, 144, 138, 131, 139, 136, 136, 143, 150, 153, - 148, 141, 148, 144, 152, 140, 131, 135, 130, 130, 165, 174, 164, 164, 166, 160, - 165, 158, 160, 152, 138, 158, 169, 158, 163, 165, 172, 174, 176, 177, 180, 182, - 184, 187, 190, 191, 194, 195, 197, 198, 199, 201, 208, 212, 215, 215, 213, 210, - 209, 208, 200, 200, 200, 201, 203, 202, 200, 196, 195, 195, 196, 197, 198, 198, - 199, 199, 199, 201, 203, 200, 194, 190, 191, 194, 184, 194, 187, 186, 186, 175, - 188, 143, 57, 60, 75, 105, 137, 154, 167, 178, 174, 188, 187, 180, 185, 187, - 183, 184, 183, 178, 173, 172, 175, 177, 177, 174, 176, 175, 178, 185, 186, 183, - 182, 184, 183, 183, 183, 180, 176, 176, 178, 180, 178, 182, 187, 187, 184, 181, - 180, 181, 188, 190, 187, 179, 175, 175, 165, 151, 153, 164, 182, 196, 202, 196, - 188, 184, 167, 166, 166, 166, 166, 165, 162, 160, 161, 153, 153, 153, 150, 151, - 144, 124, 108, 146, 148, 150, 160, 153, 156, 162, 146, 148, 143, 133, 131, 133, - 127, 117, 99, 81, 100, 102, 92, 102, 113, 122, 116, 120, 120, 129, 129, 131, - 128, 129, 133, 136, 134, 138, 138, 139, 139, 141, 140, 138, 135, 141, 140, 140, - 144, 146, 147, 144, 142, 146, 137, 142, 133, 131, 135, 126, 119, 158, 173, 169, - 167, 167, 157, 162, 158, 158, 159, 140, 157, 168, 159, 167, 168, 173, 176, 179, - 181, 184, 185, 187, 187, 191, 191, 194, 195, 197, 199, 200, 201, 204, 210, 214, - 216, 214, 210, 207, 205, 202, 201, 201, 203, 203, 202, 199, 195, 197, 197, 198, - 201, 203, 203, 204, 204, 202, 201, 200, 198, 197, 195, 196, 197, 190, 190, 187, - 188, 189, 181, 194, 108, 53, 69, 64, 64, 77, 77, 95, 140, 174, 188, 185, - 172, 174, 181, 186, 193, 183, 180, 177, 175, 176, 177, 178, 176, 178, 174, 175, - 183, 185, 182, 182, 186, 183, 185, 187, 183, 175, 174, 177, 183, 195, 195, 194, - 192, 189, 186, 183, 182, 184, 189, 187, 180, 179, 180, 170, 153, 148, 150, 158, - 170, 182, 186, 183, 177, 162, 161, 163, 165, 168, 167, 163, 161, 160, 155, 155, - 152, 147, 147, 143, 126, 108, 152, 147, 150, 163, 152, 153, 155, 143, 146, 145, - 137, 132, 125, 112, 94, 90, 87, 97, 94, 97, 112, 115, 124, 128, 134, 134, - 126, 128, 128, 125, 126, 131, 135, 134, 137, 139, 141, 138, 135, 134, 138, 141, - 140, 140, 141, 143, 141, 142, 143, 145, 148, 133, 135, 131, 140, 148, 133, 122, - 147, 168, 169, 168, 165, 154, 158, 157, 153, 165, 147, 158, 173, 168, 182, 181, - 175, 177, 181, 183, 186, 187, 186, 187, 190, 191, 194, 195, 198, 199, 200, 201, - 203, 209, 215, 218, 217, 212, 208, 206, 205, 205, 205, 206, 207, 205, 201, 197, - 197, 198, 199, 202, 204, 206, 207, 206, 203, 199, 195, 195, 199, 202, 201, 199, - 199, 191, 189, 191, 191, 187, 195, 80, 52, 70, 57, 56, 78, 65, 59, 96, - 147, 172, 182, 177, 180, 181, 179, 181, 184, 183, 182, 181, 180, 180, 180, 179, - 179, 173, 175, 182, 185, 182, 183, 186, 183, 187, 189, 185, 174, 171, 177, 185, - 187, 186, 184, 185, 186, 186, 185, 183, 187, 189, 184, 175, 176, 182, 177, 162, - 179, 168, 157, 158, 171, 183, 186, 181, 167, 165, 165, 165, 164, 159, 152, 147, - 165, 161, 162, 154, 140, 140, 138, 124, 109, 158, 149, 151, 166, 149, 146, 145, - 149, 156, 156, 147, 138, 124, 100, 78, 92, 96, 101, 90, 104, 121, 116, 123, - 121, 129, 133, 124, 124, 127, 129, 132, 132, 133, 132, 138, 137, 135, 133, 134, - 136, 139, 141, 139, 138, 140, 140, 141, 141, 142, 142, 138, 138, 136, 132, 129, - 127, 126, 117, 135, 170, 168, 157, 157, 152, 160, 162, 156, 156, 148, 149, 167, - 177, 180, 189, 178, 179, 182, 182, 181, 182, 184, 186, 191, 186, 187, 194, 199, - 200, 200, 204, 212, 211, 210, 209, 209, 208, 205, 203, 196, 196, 197, 199, 203, - 203, 201, 197, 192, 192, 195, 198, 200, 201, 201, 199, 209, 204, 198, 194, 193, - 195, 196, 196, 201, 183, 189, 184, 186, 181, 169, 51, 53, 75, 60, 57, 53, - 65, 52, 65, 119, 176, 185, 171, 171, 188, 166, 183, 180, 186, 184, 178, 178, - 185, 180, 168, 185, 183, 178, 174, 177, 183, 188, 189, 192, 189, 185, 181, 178, - 179, 183, 186, 186, 190, 194, 193, 188, 183, 181, 180, 187, 184, 181, 182, 183, - 179, 171, 164, 160, 171, 169, 146, 174, 171, 179, 181, 165, 161, 166, 167, 158, - 159, 163, 159, 168, 156, 155, 150, 135, 139, 140, 120, 121, 156, 154, 145, 158, - 155, 141, 153, 162, 159, 145, 126, 114, 109, 104, 99, 107, 105, 101, 101, 106, - 113, 122, 127, 131, 125, 121, 124, 125, 128, 129, 130, 131, 131, 132, 135, 137, - 137, 137, 138, 139, 142, 140, 135, 134, 135, 135, 135, 136, 137, 137, 136, 135, - 133, 129, 124, 121, 122, 113, 132, 165, 167, 159, 157, 155, 164, 167, 165, 164, - 155, 155, 169, 176, 178, 185, 181, 184, 187, 189, 187, 183, 184, 183, 192, 188, - 188, 192, 195, 195, 194, 196, 207, 205, 207, 205, 207, 204, 204, 200, 203, 203, - 206, 203, 201, 197, 199, 198, 197, 195, 195, 196, 197, 198, 199, 200, 202, 201, - 200, 200, 200, 198, 194, 190, 189, 180, 184, 183, 188, 178, 155, 52, 67, 65, - 50, 65, 66, 70, 48, 54, 95, 177, 187, 179, 178, 185, 166, 181, 181, 187, - 187, 183, 184, 189, 184, 172, 180, 177, 176, 174, 177, 181, 185, 184, 183, 181, - 179, 176, 174, 177, 186, 192, 195, 196, 196, 193, 188, 184, 184, 185, 191, 187, - 184, 184, 184, 181, 174, 167, 161, 168, 159, 145, 169, 177, 180, 181, 167, 161, - 163, 162, 153, 155, 161, 160, 168, 157, 155, 148, 134, 135, 136, 117, 119, 156, - 162, 156, 167, 156, 135, 142, 118, 121, 116, 107, 105, 108, 109, 107, 112, 109, - 105, 104, 108, 116, 127, 132, 134, 129, 126, 133, 131, 131, 131, 131, 132, 133, - 133, 133, 134, 136, 139, 140, 140, 139, 136, 133, 132, 133, 133, 133, 133, 132, - 131, 127, 126, 125, 122, 118, 116, 118, 110, 123, 152, 158, 157, 153, 149, 160, - 162, 166, 168, 161, 161, 173, 177, 176, 180, 182, 188, 193, 194, 192, 185, 182, - 179, 185, 181, 183, 191, 197, 199, 201, 204, 203, 202, 204, 204, 204, 201, 201, - 198, 193, 197, 202, 199, 196, 195, 202, 207, 200, 198, 196, 196, 196, 197, 199, - 200, 201, 200, 200, 200, 200, 198, 194, 190, 185, 184, 187, 188, 197, 178, 140, - 59, 75, 58, 52, 79, 70, 68, 54, 60, 80, 186, 184, 178, 177, 173, 167, - 180, 181, 186, 186, 184, 187, 193, 186, 175, 176, 174, 175, 175, 177, 179, 183, - 183, 179, 179, 178, 175, 173, 177, 188, 197, 201, 199, 195, 190, 185, 183, 185, - 187, 192, 188, 184, 183, 183, 181, 175, 171, 165, 167, 148, 145, 157, 178, 175, - 179, 169, 161, 161, 157, 148, 151, 160, 160, 166, 158, 154, 147, 134, 133, 131, - 118, 119, 146, 149, 140, 142, 128, 106, 107, 102, 108, 107, 102, 105, 110, 113, - 112, 111, 109, 105, 105, 110, 119, 129, 133, 132, 128, 126, 139, 137, 135, 134, - 134, 134, 135, 136, 135, 134, 135, 135, 136, 134, 133, 131, 130, 129, 128, 128, - 127, 126, 123, 121, 123, 122, 121, 119, 117, 116, 118, 113, 112, 138, 149, 157, - 152, 146, 157, 156, 157, 161, 159, 162, 174, 176, 174, 179, 183, 187, 192, 194, - 190, 187, 183, 180, 178, 178, 181, 188, 195, 197, 201, 206, 203, 204, 206, 204, - 202, 198, 197, 196, 190, 193, 196, 195, 195, 197, 205, 208, 197, 196, 196, 197, - 197, 198, 198, 198, 203, 199, 195, 192, 193, 194, 195, 195, 185, 189, 186, 187, - 198, 175, 121, 65, 73, 60, 65, 87, 60, 63, 66, 75, 89, 196, 174, 166, - 167, 161, 168, 181, 180, 182, 180, 179, 183, 188, 184, 177, 180, 176, 176, 175, - 177, 177, 182, 186, 184, 185, 184, 179, 176, 179, 191, 200, 196, 194, 190, 185, - 182, 181, 182, 184, 187, 184, 181, 180, 180, 179, 177, 174, 170, 170, 147, 149, - 145, 171, 169, 176, 169, 161, 161, 158, 148, 151, 159, 158, 160, 155, 150, 144, - 136, 131, 128, 124, 108, 124, 119, 106, 105, 95, 84, 87, 97, 103, 103, 100, - 101, 104, 106, 104, 107, 108, 108, 110, 114, 119, 125, 126, 126, 125, 124, 145, - 142, 139, 138, 136, 135, 136, 137, 138, 136, 133, 131, 130, 129, 129, 127, 117, - 117, 118, 120, 118, 118, 117, 113, 124, 123, 122, 121, 118, 116, 118, 114, 99, - 119, 137, 156, 154, 148, 161, 154, 150, 158, 160, 163, 174, 176, 173, 179, 183, - 186, 191, 192, 190, 187, 187, 187, 185, 182, 185, 188, 190, 188, 190, 194, 203, - 204, 206, 200, 196, 190, 191, 190, 202, 198, 199, 196, 199, 198, 201, 197, 190, - 192, 195, 198, 200, 199, 197, 195, 198, 195, 191, 189, 190, 192, 193, 193, 185, - 189, 183, 181, 188, 170, 103, 61, 67, 66, 76, 91, 64, 69, 69, 69, 107, - 196, 165, 162, 163, 162, 173, 182, 183, 181, 176, 174, 178, 184, 184, 181, 185, - 177, 175, 173, 172, 172, 180, 188, 187, 187, 186, 183, 180, 184, 195, 203, 189, - 188, 186, 185, 184, 183, 182, 181, 181, 180, 179, 179, 180, 180, 180, 179, 170, - 169, 152, 155, 139, 162, 168, 178, 166, 161, 163, 163, 153, 154, 160, 156, 154, - 153, 144, 140, 138, 133, 129, 133, 92, 99, 97, 92, 93, 93, 93, 98, 94, - 102, 104, 101, 102, 105, 109, 108, 104, 106, 111, 117, 122, 124, 126, 124, 123, - 122, 123, 140, 138, 137, 136, 135, 133, 131, 131, 129, 125, 122, 120, 118, 117, - 118, 115, 108, 107, 113, 115, 119, 120, 120, 119, 118, 118, 116, 113, 109, 108, - 107, 105, 91, 101, 120, 148, 149, 146, 160, 151, 153, 160, 163, 167, 177, 175, - 171, 176, 184, 188, 189, 189, 188, 189, 192, 194, 189, 187, 189, 194, 196, 193, - 199, 205, 205, 205, 203, 196, 189, 184, 186, 187, 196, 195, 196, 198, 202, 202, - 200, 195, 189, 192, 197, 201, 202, 201, 197, 195, 190, 191, 193, 195, 197, 195, - 190, 187, 189, 190, 184, 180, 180, 173, 103, 59, 68, 69, 72, 90, 78, 83, - 64, 53, 124, 182, 163, 169, 169, 175, 178, 183, 188, 184, 179, 176, 179, 183, - 183, 181, 183, 175, 171, 170, 169, 167, 178, 190, 186, 185, 184, 183, 185, 189, - 197, 202, 187, 187, 186, 187, 188, 187, 183, 181, 179, 180, 181, 182, 182, 182, - 182, 181, 167, 160, 155, 156, 141, 156, 172, 179, 163, 160, 165, 166, 157, 157, - 161, 156, 150, 151, 140, 135, 139, 133, 131, 144, 87, 92, 98, 99, 100, 101, - 100, 100, 99, 107, 109, 105, 104, 107, 111, 111, 109, 112, 118, 125, 132, 133, - 131, 128, 125, 125, 127, 127, 127, 128, 128, 126, 124, 121, 119, 113, 111, 110, - 110, 108, 107, 107, 104, 102, 102, 108, 112, 116, 116, 116, 115, 105, 105, 105, - 103, 100, 98, 100, 101, 102, 101, 114, 143, 144, 142, 157, 145, 153, 163, 165, - 168, 177, 173, 169, 176, 184, 186, 188, 188, 188, 188, 190, 192, 186, 187, 192, - 198, 202, 203, 210, 218, 206, 206, 204, 194, 188, 184, 189, 191, 192, 195, 204, - 207, 211, 207, 206, 203, 195, 196, 200, 202, 203, 201, 199, 197, 190, 191, 194, - 197, 199, 197, 192, 188, 194, 191, 189, 185, 178, 185, 110, 61, 67, 70, 65, - 88, 85, 80, 58, 69, 149, 173, 170, 180, 172, 185, 182, 188, 191, 185, 182, - 182, 184, 183, 179, 177, 179, 171, 170, 172, 172, 169, 180, 193, 190, 187, 184, - 185, 189, 193, 197, 197, 190, 188, 187, 187, 188, 187, 183, 180, 178, 180, 182, - 183, 182, 180, 178, 177, 169, 153, 158, 152, 148, 152, 173, 170, 162, 158, 164, - 166, 158, 158, 162, 158, 151, 152, 138, 133, 139, 132, 132, 153, 92, 92, 100, - 106, 102, 102, 101, 95, 95, 103, 105, 100, 97, 102, 107, 107, 121, 123, 127, - 131, 134, 134, 133, 130, 128, 130, 131, 113, 113, 115, 114, 113, 111, 107, 104, - 102, 102, 105, 106, 107, 106, 103, 100, 92, 91, 95, 98, 100, 99, 97, 95, - 93, 95, 95, 97, 98, 100, 102, 105, 124, 116, 121, 148, 146, 145, 161, 146, - 150, 160, 163, 166, 175, 174, 168, 176, 180, 183, 186, 186, 185, 185, 185, 186, - 187, 188, 191, 196, 198, 197, 203, 210, 210, 209, 206, 197, 190, 187, 194, 199, - 205, 213, 224, 225, 221, 212, 209, 208, 201, 202, 202, 203, 202, 201, 200, 199, - 197, 195, 193, 193, 195, 196, 197, 196, 189, 185, 187, 185, 173, 189, 113, 57, - 65, 68, 61, 85, 80, 67, 58, 101, 173, 173, 178, 185, 167, 186, 183, 196, - 189, 185, 183, 185, 186, 182, 175, 171, 176, 169, 172, 177, 177, 174, 184, 198, - 199, 193, 188, 189, 193, 195, 194, 191, 193, 189, 185, 184, 185, 184, 181, 178, - 176, 178, 181, 181, 179, 175, 172, 171, 175, 150, 159, 149, 152, 149, 171, 159, - 161, 157, 162, 163, 156, 158, 163, 160, 151, 153, 136, 131, 139, 131, 132, 156, - 92, 90, 97, 104, 101, 103, 109, 104, 100, 107, 113, 112, 112, 120, 128, 130, - 133, 133, 133, 131, 130, 129, 128, 126, 130, 131, 132, 104, 105, 106, 105, 103, - 97, 92, 88, 93, 100, 94, 84, 81, 74, 70, 75, 63, 71, 77, 82, 89, - 83, 82, 96, 97, 95, 94, 100, 109, 115, 118, 121, 138, 135, 135, 140, 143, - 144, 145, 149, 155, 159, 164, 167, 169, 168, 167, 169, 176, 179, 181, 183, 185, - 186, 187, 187, 190, 188, 189, 194, 196, 194, 196, 200, 202, 202, 204, 204, 207, - 206, 208, 207, 208, 208, 212, 213, 216, 216, 216, 215, 208, 204, 201, 198, 199, - 201, 205, 207, 202, 197, 191, 187, 187, 189, 191, 194, 198, 191, 176, 185, 186, - 188, 159, 58, 78, 59, 68, 85, 76, 67, 92, 126, 168, 176, 183, 187, 188, - 189, 191, 193, 182, 187, 191, 190, 184, 178, 175, 174, 179, 176, 177, 176, 179, - 179, 180, 178, 197, 191, 186, 186, 192, 197, 199, 198, 189, 187, 184, 182, 182, - 182, 180, 178, 178, 172, 175, 179, 175, 177, 180, 172, 166, 168, 166, 157, 159, - 140, 166, 170, 161, 161, 160, 158, 160, 162, 158, 149, 149, 142, 141, 137, 140, - 116, 149, 161, 99, 95, 111, 107, 100, 107, 102, 101, 113, 117, 123, 129, 134, - 136, 137, 135, 140, 139, 135, 130, 125, 122, 124, 127, 129, 129, 129, 86, 85, - 82, 78, 77, 76, 75, 75, 66, 74, 74, 69, 66, 57, 52, 54, 60, 65, - 66, 79, 96, 96, 91, 97, 97, 105, 115, 121, 122, 121, 120, 124, 126, 127, - 129, 133, 137, 139, 144, 151, 150, 154, 160, 164, 167, 167, 168, 170, 172, 174, - 179, 182, 184, 186, 188, 188, 187, 185, 187, 192, 194, 192, 192, 196, 197, 199, - 201, 203, 203, 202, 200, 199, 203, 204, 206, 208, 209, 211, 211, 211, 213, 211, - 208, 205, 204, 205, 207, 208, 210, 209, 206, 201, 196, 192, 189, 190, 187, 187, - 183, 195, 192, 190, 167, 87, 68, 70, 81, 75, 57, 72, 126, 171, 177, 182, - 187, 189, 188, 189, 192, 195, 190, 191, 191, 189, 183, 177, 173, 172, 176, 176, - 177, 175, 175, 178, 187, 192, 192, 188, 187, 190, 196, 199, 199, 196, 189, 186, - 184, 183, 182, 182, 180, 178, 179, 172, 176, 179, 174, 175, 177, 169, 171, 169, - 163, 154, 159, 145, 175, 180, 166, 166, 164, 161, 162, 164, 159, 150, 148, 146, - 136, 135, 134, 123, 148, 156, 101, 97, 115, 117, 120, 137, 137, 137, 147, 145, - 146, 146, 144, 141, 138, 136, 136, 136, 133, 130, 127, 126, 129, 131, 135, 136, - 135, 77, 76, 72, 68, 67, 64, 62, 62, 56, 58, 63, 62, 61, 56, 56, - 58, 73, 80, 83, 89, 100, 96, 91, 99, 93, 104, 116, 115, 107, 98, 100, - 108, 123, 124, 127, 130, 132, 134, 142, 151, 146, 150, 157, 162, 165, 167, 169, - 172, 171, 173, 176, 178, 180, 182, 182, 183, 183, 181, 185, 190, 192, 189, 189, - 192, 192, 194, 198, 200, 199, 196, 192, 190, 199, 199, 200, 201, 203, 204, 206, - 207, 216, 214, 212, 210, 208, 207, 207, 207, 204, 207, 209, 206, 197, 188, 182, - 182, 190, 191, 193, 201, 192, 188, 180, 131, 105, 100, 91, 76, 81, 120, 164, - 180, 181, 189, 193, 198, 199, 199, 199, 199, 201, 198, 191, 186, 181, 177, 173, - 169, 185, 184, 183, 174, 170, 172, 184, 192, 186, 186, 188, 194, 199, 200, 197, - 193, 188, 186, 184, 183, 183, 182, 180, 178, 179, 172, 176, 178, 173, 174, 174, - 166, 173, 170, 165, 158, 166, 151, 177, 178, 164, 164, 161, 158, 159, 160, 154, - 145, 145, 150, 131, 134, 125, 132, 148, 153, 106, 97, 112, 119, 129, 147, 145, - 144, 138, 136, 135, 134, 132, 130, 127, 126, 130, 129, 129, 127, 126, 125, 128, - 132, 134, 135, 134, 56, 58, 59, 61, 61, 61, 58, 57, 72, 65, 68, 71, - 67, 71, 82, 87, 93, 105, 106, 99, 93, 81, 78, 90, 82, 89, 95, 91, - 83, 83, 91, 103, 127, 130, 132, 133, 131, 131, 139, 149, 144, 149, 155, 160, - 163, 165, 168, 170, 173, 173, 174, 176, 176, 177, 176, 176, 180, 179, 183, 188, - 190, 188, 187, 189, 190, 190, 192, 193, 193, 192, 190, 188, 197, 197, 196, 197, - 198, 201, 204, 205, 211, 210, 210, 209, 208, 206, 205, 204, 213, 220, 226, 225, - 218, 210, 207, 209, 207, 200, 197, 197, 187, 185, 186, 170, 169, 151, 134, 127, - 144, 180, 189, 172, 183, 191, 197, 205, 209, 209, 207, 206, 204, 198, 187, 182, - 179, 177, 173, 169, 189, 184, 179, 172, 170, 173, 183, 189, 187, 187, 190, 195, - 198, 198, 194, 190, 188, 186, 184, 184, 183, 182, 180, 177, 178, 172, 176, 179, - 173, 174, 174, 166, 172, 172, 171, 168, 175, 153, 169, 162, 161, 161, 159, 156, - 156, 157, 152, 142, 138, 153, 131, 135, 118, 138, 152, 155, 105, 90, 105, 116, - 127, 142, 134, 128, 130, 127, 126, 125, 125, 126, 126, 126, 121, 122, 122, 121, - 119, 120, 122, 125, 121, 125, 127, 83, 82, 85, 89, 95, 100, 106, 109, 90, - 76, 80, 86, 81, 85, 99, 101, 96, 102, 97, 89, 90, 86, 83, 92, 86, - 90, 93, 95, 99, 106, 120, 130, 132, 132, 134, 135, 132, 131, 138, 148, 147, - 151, 156, 160, 161, 163, 166, 169, 171, 171, 172, 173, 173, 174, 173, 174, 181, - 179, 182, 188, 189, 188, 188, 190, 188, 188, 188, 188, 189, 190, 192, 193, 197, - 197, 196, 197, 198, 201, 204, 204, 203, 203, 204, 205, 205, 204, 203, 203, 197, - 203, 209, 209, 204, 200, 201, 207, 214, 204, 201, 196, 188, 189, 189, 190, 196, - 193, 198, 199, 194, 199, 203, 197, 194, 196, 197, 199, 201, 206, 209, 211, 200, - 194, 187, 182, 179, 178, 175, 171, 177, 170, 166, 166, 174, 182, 190, 191, 192, - 192, 192, 194, 194, 193, 191, 189, 187, 186, 184, 184, 184, 183, 179, 177, 177, - 171, 176, 180, 174, 175, 175, 166, 169, 170, 170, 168, 174, 150, 164, 155, 163, - 163, 161, 158, 159, 160, 155, 145, 132, 154, 135, 136, 119, 141, 156, 159, 99, - 83, 98, 114, 129, 143, 131, 123, 128, 123, 120, 116, 114, 112, 114, 114, 115, - 115, 115, 114, 112, 111, 112, 114, 113, 119, 121, 98, 92, 86, 82, 84, 91, - 100, 104, 94, 77, 86, 98, 86, 86, 94, 86, 86, 82, 72, 76, 98, 110, - 106, 103, 104, 108, 113, 119, 125, 129, 135, 136, 130, 129, 131, 134, 133, 132, - 137, 144, 148, 151, 155, 158, 159, 161, 164, 166, 165, 166, 168, 171, 172, 174, - 176, 176, 182, 180, 181, 185, 188, 186, 188, 190, 188, 186, 185, 185, 186, 189, - 192, 194, 194, 194, 195, 196, 198, 200, 201, 202, 199, 199, 201, 202, 203, 204, - 204, 204, 208, 211, 212, 211, 208, 207, 209, 213, 208, 201, 206, 200, 198, 200, - 190, 197, 195, 195, 210, 218, 207, 202, 209, 214, 207, 201, 191, 185, 185, 193, - 202, 208, 194, 191, 188, 185, 181, 179, 177, 174, 176, 167, 163, 164, 175, 183, - 187, 184, 195, 194, 194, 193, 191, 190, 189, 188, 187, 186, 185, 185, 185, 183, - 179, 176, 176, 171, 176, 179, 173, 173, 172, 163, 164, 164, 163, 158, 165, 146, - 166, 164, 162, 162, 159, 156, 156, 157, 151, 143, 133, 149, 136, 134, 129, 141, - 159, 157, 103, 84, 100, 116, 128, 137, 124, 117, 113, 111, 107, 104, 102, 100, - 101, 101, 108, 109, 111, 110, 107, 108, 108, 110, 112, 115, 117, 121, 114, 105, - 98, 95, 95, 97, 98, 97, 75, 86, 101, 86, 85, 94, 83, 83, 87, 83, - 88, 110, 122, 118, 117, 117, 122, 128, 133, 134, 134, 135, 132, 134, 129, 131, - 135, 136, 132, 133, 136, 145, 148, 152, 155, 157, 160, 162, 164, 163, 164, 166, - 170, 173, 175, 177, 177, 182, 179, 179, 184, 185, 184, 188, 191, 189, 186, 186, - 186, 187, 188, 189, 190, 190, 191, 193, 195, 197, 198, 198, 197, 197, 196, 197, - 198, 199, 201, 202, 203, 200, 199, 197, 196, 194, 194, 194, 196, 203, 203, 215, - 203, 203, 207, 191, 203, 197, 189, 195, 202, 204, 207, 208, 201, 206, 201, 191, - 185, 187, 192, 195, 197, 191, 193, 193, 191, 185, 181, 179, 176, 181, 172, 167, - 165, 170, 176, 181, 180, 193, 193, 194, 194, 192, 189, 189, 188, 186, 185, 185, - 185, 185, 183, 179, 175, 178, 172, 176, 178, 170, 168, 165, 155, 155, 158, 160, - 156, 162, 144, 167, 168, 163, 162, 158, 153, 152, 151, 144, 136, 141, 144, 132, - 129, 141, 140, 157, 148, 109, 86, 97, 109, 117, 124, 110, 107, 107, 106, 105, - 104, 103, 103, 104, 104, 101, 103, 105, 106, 104, 104, 106, 107, 108, 108, 109, - 117, 115, 116, 114, 112, 106, 102, 97, 105, 79, 89, 103, 88, 90, 105, 96, - 97, 114, 120, 116, 119, 119, 120, 126, 121, 125, 132, 134, 134, 135, 140, 142, - 141, 134, 133, 136, 137, 132, 129, 128, 141, 145, 149, 152, 155, 159, 163, 165, - 166, 166, 168, 171, 172, 172, 175, 175, 180, 177, 177, 181, 181, 182, 185, 190, - 187, 186, 187, 187, 187, 186, 185, 184, 186, 187, 190, 192, 194, 194, 195, 193, - 197, 194, 194, 195, 196, 197, 199, 200, 205, 203, 201, 200, 200, 200, 199, 199, - 207, 210, 221, 200, 197, 204, 191, 208, 201, 198, 202, 202, 199, 208, 208, 194, - 196, 196, 195, 196, 198, 196, 192, 187, 189, 194, 197, 194, 189, 182, 178, 178, - 174, 170, 167, 164, 168, 174, 185, 190, 188, 191, 194, 193, 194, 191, 188, 187, - 186, 185, 185, 185, 185, 183, 179, 175, 179, 172, 175, 176, 167, 163, 160, 149, - 146, 154, 162, 161, 166, 143, 164, 163, 169, 168, 163, 157, 154, 151, 144, 135, - 150, 139, 130, 125, 149, 139, 155, 137, 104, 79, 87, 98, 104, 113, 103, 103, - 99, 98, 97, 95, 93, 90, 89, 88, 89, 92, 96, 97, 97, 98, 99, 101, - 96, 97, 98, 131, 128, 126, 124, 123, 121, 122, 120, 124, 110, 108, 137, 124, - 138, 131, 122, 126, 124, 124, 125, 129, 135, 135, 134, 135, 138, 135, 131, 131, - 138, 140, 139, 139, 136, 133, 133, 136, 135, 134, 131, 130, 141, 148, 148, 152, - 159, 163, 161, 165, 160, 162, 165, 169, 169, 172, 172, 176, 177, 176, 176, 178, - 182, 186, 188, 189, 188, 187, 186, 185, 185, 184, 184, 188, 189, 190, 190, 192, - 192, 193, 192, 199, 199, 199, 199, 199, 197, 196, 195, 201, 200, 198, 198, 199, - 201, 204, 207, 211, 208, 203, 204, 206, 205, 201, 195, 204, 200, 197, 203, 211, - 213, 205, 197, 192, 191, 189, 192, 197, 198, 197, 193, 188, 186, 184, 181, 178, - 176, 172, 171, 180, 166, 159, 161, 166, 167, 176, 185, 184, 188, 193, 192, 188, - 183, 183, 187, 187, 186, 185, 184, 183, 181, 177, 173, 177, 176, 179, 176, 163, - 157, 150, 135, 144, 152, 149, 148, 160, 164, 163, 164, 169, 162, 156, 153, 150, - 147, 147, 147, 141, 160, 102, 143, 138, 157, 158, 151, 96, 83, 77, 85, 86, - 78, 78, 90, 88, 86, 88, 79, 85, 85, 70, 78, 79, 75, 83, 90, 86, - 88, 89, 82, 90, 91, 95, 126, 125, 127, 129, 130, 130, 129, 127, 124, 123, - 124, 130, 119, 127, 130, 131, 130, 128, 128, 129, 132, 135, 137, 136, 141, 141, - 140, 134, 132, 134, 133, 127, 133, 134, 137, 141, 144, 141, 134, 128, 130, 143, - 151, 147, 144, 152, 163, 170, 169, 165, 166, 168, 171, 171, 171, 172, 175, 174, - 174, 174, 176, 179, 184, 186, 187, 187, 186, 185, 185, 186, 185, 186, 186, 186, - 187, 189, 190, 191, 191, 192, 197, 198, 199, 200, 201, 201, 201, 200, 199, 199, - 199, 201, 204, 208, 212, 214, 213, 210, 206, 207, 209, 209, 203, 199, 203, 200, - 198, 203, 209, 211, 207, 201, 200, 198, 195, 196, 197, 198, 194, 192, 191, 190, - 188, 186, 181, 179, 177, 176, 173, 164, 160, 160, 165, 170, 181, 187, 187, 189, - 192, 191, 186, 183, 184, 186, 188, 186, 185, 184, 183, 181, 177, 173, 174, 170, - 173, 170, 160, 158, 155, 140, 143, 152, 151, 146, 152, 154, 156, 161, 165, 158, - 153, 151, 150, 147, 141, 137, 138, 146, 119, 145, 154, 153, 153, 143, 88, 73, - 69, 81, 82, 71, 62, 67, 74, 75, 89, 82, 76, 77, 69, 74, 77, 69, - 70, 71, 68, 76, 87, 87, 85, 87, 92, 128, 131, 134, 135, 136, 134, 132, - 128, 126, 131, 126, 109, 117, 121, 129, 131, 131, 131, 131, 131, 131, 130, 132, - 132, 129, 132, 134, 131, 131, 134, 133, 130, 131, 135, 139, 143, 145, 143, 137, - 132, 132, 140, 146, 146, 147, 154, 163, 166, 165, 165, 167, 168, 172, 173, 173, - 173, 173, 172, 173, 172, 173, 175, 179, 181, 182, 182, 182, 183, 184, 185, 186, - 187, 184, 185, 187, 189, 190, 191, 191, 191, 192, 193, 195, 197, 200, 201, 202, - 202, 200, 200, 200, 202, 205, 209, 212, 214, 211, 208, 206, 207, 209, 210, 205, - 202, 201, 200, 199, 202, 206, 208, 207, 206, 208, 204, 202, 201, 199, 198, 193, - 191, 190, 189, 187, 184, 180, 178, 175, 174, 170, 170, 168, 162, 166, 175, 184, - 188, 190, 190, 191, 189, 186, 184, 186, 188, 189, 187, 186, 185, 184, 181, 177, - 173, 170, 168, 173, 172, 163, 161, 156, 139, 137, 148, 148, 143, 149, 153, 159, - 169, 164, 160, 156, 155, 154, 150, 142, 134, 141, 132, 134, 141, 160, 148, 147, - 140, 79, 65, 63, 77, 87, 80, 71, 73, 68, 65, 93, 90, 72, 74, 73, - 74, 79, 69, 67, 66, 64, 74, 88, 92, 91, 91, 92, 123, 124, 127, 130, - 132, 131, 132, 130, 129, 131, 118, 87, 121, 126, 131, 122, 130, 130, 132, 133, - 131, 126, 127, 130, 127, 129, 130, 129, 131, 134, 134, 131, 134, 133, 133, 133, - 135, 137, 138, 139, 131, 131, 136, 143, 155, 162, 159, 154, 158, 160, 164, 165, - 169, 173, 174, 170, 172, 172, 171, 172, 172, 174, 176, 178, 176, 176, 177, 178, - 180, 183, 185, 186, 187, 187, 188, 189, 190, 189, 189, 189, 188, 190, 192, 195, - 197, 198, 199, 200, 203, 203, 202, 202, 202, 203, 205, 205, 206, 204, 203, 204, - 206, 207, 203, 201, 200, 201, 201, 201, 202, 205, 207, 209, 209, 207, 205, 202, - 199, 197, 193, 190, 191, 189, 187, 181, 178, 175, 172, 170, 172, 178, 176, 167, - 168, 179, 187, 186, 192, 191, 190, 187, 185, 185, 187, 189, 189, 188, 186, 185, - 184, 181, 176, 173, 170, 170, 177, 178, 169, 164, 153, 132, 142, 150, 148, 144, - 153, 159, 165, 172, 160, 161, 160, 155, 151, 149, 144, 138, 147, 127, 137, 139, - 148, 148, 146, 147, 81, 70, 66, 78, 84, 82, 79, 82, 73, 62, 93, 93, - 67, 73, 75, 69, 74, 68, 72, 75, 71, 76, 86, 87, 94, 95, 93, 103, - 102, 104, 108, 114, 119, 123, 124, 121, 128, 113, 80, 110, 114, 118, 109, 116, - 116, 121, 128, 129, 125, 125, 127, 134, 134, 130, 124, 122, 124, 124, 123, 131, - 132, 132, 132, 133, 135, 137, 139, 129, 128, 133, 140, 149, 155, 157, 158, 156, - 160, 163, 162, 167, 172, 171, 166, 171, 172, 171, 171, 171, 173, 174, 176, 174, - 174, 175, 177, 180, 183, 185, 187, 192, 192, 192, 192, 191, 190, 188, 188, 190, - 191, 193, 195, 197, 197, 198, 198, 205, 205, 204, 203, 202, 202, 201, 201, 203, - 202, 202, 202, 202, 202, 202, 201, 199, 200, 201, 201, 200, 202, 206, 210, 206, - 205, 203, 200, 196, 194, 192, 191, 196, 193, 190, 184, 180, 175, 172, 171, 172, - 178, 177, 168, 171, 182, 189, 186, 193, 191, 188, 186, 185, 185, 187, 189, 189, - 187, 185, 184, 183, 179, 175, 171, 172, 169, 172, 172, 165, 163, 156, 136, 152, - 155, 148, 145, 159, 165, 164, 165, 152, 157, 157, 148, 140, 140, 142, 141, 143, - 127, 134, 145, 138, 153, 146, 144, 85, 81, 84, 88, 86, 78, 76, 78, 86, - 66, 89, 87, 66, 74, 74, 63, 66, 63, 69, 71, 65, 67, 76, 77, 91, - 93, 93, 105, 104, 102, 101, 103, 106, 108, 110, 110, 123, 118, 87, 86, 88, - 97, 99, 97, 97, 104, 119, 126, 123, 120, 122, 119, 120, 117, 112, 110, 115, - 118, 117, 127, 133, 136, 139, 139, 137, 136, 135, 127, 132, 139, 138, 134, 134, - 148, 165, 158, 164, 166, 163, 167, 172, 169, 162, 170, 170, 169, 170, 169, 170, - 170, 173, 173, 174, 176, 178, 181, 184, 187, 189, 192, 192, 192, 192, 191, 189, - 188, 187, 193, 194, 196, 197, 198, 198, 198, 198, 203, 203, 203, 204, 204, 205, - 205, 205, 204, 204, 204, 204, 202, 203, 203, 203, 200, 201, 201, 201, 200, 201, - 204, 205, 201, 201, 199, 195, 192, 189, 190, 192, 192, 190, 186, 183, 178, 175, - 172, 171, 170, 169, 168, 169, 174, 185, 190, 189, 191, 189, 186, 185, 185, 185, - 186, 186, 188, 186, 184, 183, 181, 178, 173, 169, 173, 164, 161, 159, 156, 163, - 165, 151, 144, 147, 143, 146, 165, 173, 169, 167, 155, 160, 157, 144, 137, 140, - 144, 143, 131, 129, 135, 154, 143, 158, 151, 124, 79, 87, 101, 112, 109, 97, - 87, 85, 96, 76, 87, 82, 71, 77, 72, 63, 63, 58, 61, 60, 52, 57, - 68, 72, 93, 94, 95, 120, 117, 114, 111, 109, 107, 104, 104, 111, 117, 112, - 95, 68, 76, 86, 92, 92, 91, 99, 117, 127, 121, 114, 111, 103, 107, 108, - 107, 110, 117, 119, 121, 128, 135, 140, 142, 139, 137, 136, 136, 131, 131, 136, - 139, 136, 131, 138, 149, 150, 160, 162, 160, 164, 172, 170, 162, 167, 168, 167, - 167, 166, 167, 167, 166, 170, 170, 173, 175, 178, 181, 183, 185, 187, 188, 190, - 190, 190, 190, 189, 189, 190, 191, 192, 194, 195, 196, 196, 196, 197, 198, 200, - 202, 203, 204, 205, 205, 203, 204, 204, 203, 203, 202, 201, 202, 202, 201, 200, - 200, 201, 202, 201, 201, 199, 198, 197, 193, 189, 186, 188, 191, 186, 185, 182, - 180, 178, 176, 173, 172, 175, 168, 165, 172, 182, 187, 190, 192, 189, 188, 185, - 184, 185, 185, 186, 186, 187, 185, 183, 181, 179, 176, 171, 167, 168, 160, 158, - 159, 160, 170, 174, 160, 137, 145, 146, 151, 168, 175, 170, 169, 164, 164, 157, - 143, 140, 146, 144, 136, 127, 133, 142, 151, 153, 150, 161, 102, 75, 88, 105, - 123, 128, 121, 112, 104, 104, 93, 96, 87, 85, 88, 76, 74, 70, 66, 67, - 66, 58, 65, 78, 84, 99, 97, 94, 114, 115, 116, 118, 117, 118, 116, 115, - 119, 111, 98, 98, 64, 84, 88, 87, 99, 95, 101, 120, 129, 120, 107, 102, - 112, 117, 119, 119, 121, 125, 123, 123, 133, 137, 137, 133, 131, 132, 137, 139, - 136, 126, 127, 140, 150, 143, 128, 120, 139, 150, 155, 155, 161, 173, 173, 164, - 164, 165, 164, 164, 163, 162, 161, 162, 164, 164, 165, 169, 172, 175, 178, 180, - 183, 184, 187, 188, 189, 190, 190, 189, 184, 185, 187, 190, 191, 193, 193, 194, - 195, 196, 197, 199, 200, 201, 201, 201, 202, 203, 204, 203, 201, 200, 200, 201, - 203, 201, 199, 200, 202, 203, 199, 197, 198, 198, 197, 190, 186, 184, 186, 188, - 186, 184, 184, 183, 183, 183, 181, 181, 187, 172, 167, 177, 189, 190, 189, 191, - 188, 186, 184, 184, 185, 185, 185, 184, 186, 184, 182, 180, 178, 175, 170, 166, - 164, 159, 164, 170, 172, 179, 177, 159, 147, 158, 160, 160, 168, 167, 159, 158, - 166, 162, 150, 138, 140, 146, 138, 122, 131, 137, 148, 141, 158, 139, 171, 91, - 85, 91, 105, 120, 130, 128, 118, 111, 111, 108, 111, 99, 102, 101, 83, 89, - 81, 79, 85, 88, 80, 84, 93, 96, 100, 96, 93, 120, 117, 109, 104, 104, - 110, 110, 105, 110, 104, 101, 115, 99, 78, 87, 91, 100, 113, 116, 117, 121, - 115, 108, 113, 113, 115, 119, 118, 117, 119, 125, 131, 134, 133, 141, 142, 132, - 131, 135, 128, 130, 126, 129, 137, 146, 147, 144, 142, 124, 139, 143, 147, 163, - 172, 166, 164, 162, 167, 172, 174, 172, 170, 170, 172, 167, 169, 168, 168, 168, - 170, 175, 181, 178, 180, 184, 187, 189, 189, 188, 187, 195, 190, 188, 189, 189, - 188, 190, 194, 191, 189, 193, 199, 199, 194, 195, 201, 201, 202, 204, 204, 202, - 200, 197, 195, 199, 200, 200, 198, 198, 197, 196, 196, 191, 192, 190, 190, 189, - 190, 193, 195, 195, 192, 186, 179, 181, 184, 179, 170, 173, 165, 166, 177, 188, - 190, 188, 187, 188, 188, 189, 189, 189, 186, 185, 184, 182, 183, 184, 181, 175, - 171, 170, 171, 163, 169, 174, 180, 163, 160, 168, 137, 156, 156, 157, 161, 168, - 173, 173, 168, 160, 150, 149, 133, 134, 144, 131, 126, 141, 148, 140, 152, 171, - 129, 173, 92, 90, 95, 115, 132, 130, 127, 125, 116, 109, 112, 113, 112, 113, - 112, 106, 97, 97, 94, 93, 94, 97, 98, 97, 97, 95, 94, 93, 126, 124, - 116, 108, 103, 102, 96, 88, 98, 92, 85, 96, 88, 79, 97, 98, 101, 104, - 98, 95, 104, 105, 102, 108, 102, 104, 109, 112, 115, 119, 124, 128, 130, 128, - 135, 135, 129, 128, 133, 128, 132, 131, 126, 125, 133, 145, 147, 145, 143, 146, - 136, 128, 136, 144, 151, 163, 170, 172, 173, 171, 168, 166, 167, 170, 169, 170, - 170, 167, 165, 166, 172, 175, 172, 173, 178, 181, 183, 185, 186, 186, 190, 186, - 186, 188, 189, 187, 189, 193, 194, 192, 195, 200, 200, 196, 197, 203, 199, 201, - 203, 203, 201, 199, 197, 194, 199, 200, 198, 197, 197, 195, 194, 192, 191, 192, - 190, 189, 187, 188, 190, 193, 189, 188, 182, 175, 178, 184, 185, 180, 167, 165, - 173, 184, 187, 186, 184, 188, 185, 186, 187, 187, 187, 184, 184, 182, 181, 179, - 177, 175, 174, 172, 169, 166, 167, 187, 165, 170, 188, 160, 147, 161, 163, 160, - 161, 167, 172, 173, 171, 167, 164, 151, 149, 134, 131, 138, 127, 129, 142, 140, - 143, 145, 134, 146, 151, 79, 90, 99, 121, 135, 132, 128, 124, 119, 118, 121, - 121, 117, 116, 116, 110, 101, 97, 95, 92, 93, 96, 95, 95, 93, 94, 92, - 93, 123, 125, 122, 118, 114, 112, 104, 96, 96, 94, 86, 94, 91, 89, 104, - 94, 100, 99, 90, 88, 100, 103, 103, 108, 108, 108, 112, 117, 122, 126, 128, - 128, 129, 125, 130, 130, 124, 125, 131, 127, 122, 129, 129, 126, 131, 144, 149, - 145, 149, 151, 144, 138, 140, 136, 137, 149, 149, 156, 166, 174, 175, 174, 171, - 169, 167, 167, 168, 165, 163, 163, 166, 169, 168, 168, 171, 172, 174, 179, 181, - 182, 185, 182, 183, 187, 188, 186, 187, 191, 194, 193, 195, 197, 197, 195, 198, - 203, 198, 199, 200, 200, 199, 198, 195, 193, 198, 196, 196, 196, 194, 192, 191, - 190, 190, 189, 189, 187, 185, 185, 187, 189, 181, 183, 182, 177, 178, 180, 181, - 178, 163, 169, 181, 189, 188, 183, 183, 188, 186, 186, 187, 186, 186, 186, 184, - 182, 187, 182, 177, 175, 175, 174, 168, 163, 171, 178, 179, 187, 174, 159, 170, - 164, 170, 164, 167, 176, 179, 172, 167, 167, 167, 151, 149, 134, 128, 131, 124, - 135, 152, 154, 151, 151, 139, 171, 110, 89, 90, 107, 130, 139, 136, 130, 126, - 124, 119, 121, 118, 114, 113, 113, 109, 101, 98, 94, 93, 93, 96, 95, 95, - 92, 89, 86, 87, 118, 123, 124, 123, 124, 124, 120, 113, 107, 111, 106, 113, - 109, 106, 108, 80, 101, 107, 106, 108, 116, 115, 111, 114, 122, 122, 122, 125, - 129, 129, 126, 122, 130, 123, 126, 126, 119, 122, 129, 125, 121, 125, 126, 124, - 123, 131, 144, 157, 155, 158, 155, 155, 156, 144, 136, 144, 138, 143, 149, 155, - 160, 161, 164, 164, 162, 162, 164, 162, 162, 162, 167, 170, 167, 167, 166, 168, - 169, 172, 175, 177, 180, 179, 180, 186, 187, 186, 186, 189, 192, 192, 192, 192, - 191, 192, 195, 199, 196, 197, 197, 197, 197, 196, 193, 193, 192, 193, 193, 193, - 192, 191, 191, 190, 187, 188, 187, 185, 183, 182, 184, 185, 175, 178, 181, 181, - 177, 173, 169, 166, 166, 174, 183, 188, 186, 182, 183, 187, 188, 188, 188, 188, - 189, 188, 186, 185, 187, 184, 179, 175, 171, 168, 164, 161, 162, 182, 197, 188, - 155, 163, 192, 163, 173, 166, 170, 181, 182, 171, 166, 168, 166, 149, 147, 132, - 124, 127, 126, 145, 149, 158, 132, 144, 161, 156, 65, 91, 90, 116, 135, 142, - 141, 134, 129, 133, 129, 130, 125, 121, 119, 122, 118, 113, 115, 112, 111, 112, - 115, 116, 116, 112, 106, 102, 102, 121, 125, 125, 120, 119, 120, 117, 114, 120, - 125, 120, 126, 124, 120, 116, 81, 107, 120, 125, 125, 130, 124, 120, 127, 129, - 128, 126, 127, 128, 126, 122, 114, 124, 115, 117, 118, 114, 119, 126, 122, 129, - 122, 119, 117, 109, 108, 129, 155, 168, 165, 152, 147, 151, 148, 146, 155, 157, - 150, 139, 132, 131, 134, 144, 150, 153, 155, 157, 157, 158, 160, 166, 170, 168, - 167, 165, 165, 165, 168, 171, 172, 176, 174, 176, 182, 184, 182, 183, 186, 187, - 189, 189, 187, 186, 188, 191, 195, 194, 194, 195, 195, 193, 193, 192, 192, 189, - 189, 190, 191, 191, 192, 191, 191, 186, 187, 185, 184, 182, 181, 183, 183, 179, - 179, 178, 178, 174, 170, 169, 168, 176, 179, 181, 182, 184, 185, 185, 186, 187, - 187, 187, 186, 188, 186, 186, 185, 177, 179, 179, 173, 165, 161, 162, 165, 170, - 205, 179, 157, 170, 172, 174, 174, 170, 167, 172, 182, 183, 173, 168, 168, 162, - 147, 145, 129, 122, 129, 133, 153, 158, 153, 130, 147, 160, 134, 95, 88, 86, - 120, 138, 140, 143, 136, 129, 136, 124, 122, 118, 112, 108, 109, 105, 99, 107, - 104, 103, 102, 107, 110, 111, 107, 103, 101, 101, 120, 125, 125, 120, 117, 120, - 121, 120, 125, 124, 117, 124, 125, 126, 128, 100, 115, 126, 127, 123, 125, 120, - 123, 135, 127, 126, 127, 129, 129, 127, 124, 118, 114, 103, 108, 112, 110, 117, - 125, 121, 119, 117, 122, 125, 116, 103, 102, 109, 150, 159, 155, 151, 157, 159, - 156, 160, 160, 156, 151, 146, 144, 142, 139, 137, 139, 141, 145, 147, 147, 150, - 155, 160, 163, 163, 162, 162, 162, 164, 166, 167, 173, 172, 173, 177, 179, 178, - 179, 183, 186, 189, 190, 187, 186, 189, 191, 191, 192, 192, 192, 192, 191, 191, - 191, 191, 188, 189, 189, 190, 191, 191, 191, 191, 185, 185, 184, 183, 180, 181, - 181, 184, 186, 179, 172, 170, 170, 173, 179, 185, 185, 181, 178, 177, 181, 186, - 186, 183, 184, 183, 182, 181, 183, 182, 182, 182, 173, 178, 181, 176, 167, 164, - 170, 177, 204, 184, 151, 161, 178, 171, 173, 168, 168, 170, 176, 180, 180, 175, - 172, 168, 158, 148, 145, 124, 120, 136, 141, 156, 174, 150, 148, 156, 136, 129, - 164, 89, 86, 123, 136, 134, 141, 135, 126, 134, 117, 116, 109, 102, 97, 95, - 90, 83, 89, 85, 83, 84, 86, 91, 92, 89, 83, 83, 85, 119, 125, 128, - 126, 125, 128, 130, 130, 128, 123, 114, 125, 126, 127, 137, 116, 118, 124, 124, - 119, 121, 118, 120, 131, 124, 126, 129, 131, 131, 130, 130, 128, 116, 104, 108, - 111, 109, 115, 122, 116, 109, 119, 127, 127, 128, 121, 95, 67, 93, 130, 155, - 160, 167, 168, 158, 154, 150, 153, 159, 165, 167, 161, 152, 144, 139, 141, 143, - 143, 142, 144, 146, 149, 155, 155, 155, 157, 157, 160, 162, 164, 171, 169, 169, - 172, 173, 173, 175, 179, 182, 187, 189, 186, 184, 188, 188, 186, 191, 191, 189, - 189, 189, 189, 188, 188, 191, 192, 191, 191, 190, 189, 188, 188, 184, 184, 184, - 183, 181, 182, 183, 185, 186, 176, 168, 170, 175, 178, 183, 187, 185, 184, 180, - 176, 180, 185, 185, 181, 180, 180, 180, 179, 181, 180, 180, 180, 176, 178, 179, - 175, 169, 167, 171, 176, 192, 153, 152, 188, 181, 172, 185, 159, 168, 177, 182, - 178, 176, 178, 175, 166, 156, 151, 147, 121, 119, 143, 147, 155, 160, 145, 144, - 148, 131, 133, 168, 101, 94, 132, 138, 131, 143, 137, 124, 132, 129, 129, 123, - 117, 114, 111, 106, 99, 101, 98, 95, 94, 95, 98, 99, 97, 91, 90, 92, - 123, 129, 133, 129, 126, 126, 126, 124, 132, 125, 120, 132, 132, 128, 135, 118, - 117, 123, 122, 120, 125, 121, 116, 121, 117, 123, 127, 127, 126, 126, 129, 129, - 126, 114, 115, 117, 112, 117, 119, 111, 122, 130, 121, 105, 117, 133, 109, 64, - 47, 102, 141, 150, 157, 164, 159, 156, 161, 157, 153, 151, 154, 158, 160, 159, - 153, 154, 154, 152, 149, 147, 149, 151, 145, 146, 148, 150, 152, 155, 157, 160, - 168, 164, 162, 165, 168, 168, 171, 176, 176, 184, 187, 183, 181, 184, 184, 180, - 189, 189, 186, 186, 186, 187, 186, 187, 194, 193, 193, 190, 190, 186, 186, 183, - 183, 183, 183, 182, 181, 180, 184, 185, 179, 169, 168, 175, 182, 180, 179, 177, - 180, 185, 184, 179, 179, 183, 184, 181, 184, 183, 182, 181, 181, 181, 182, 182, - 176, 174, 171, 166, 162, 160, 161, 162, 131, 162, 171, 188, 202, 179, 168, 169, - 169, 183, 187, 177, 174, 180, 178, 164, 156, 154, 149, 119, 118, 147, 151, 152, - 147, 162, 144, 148, 170, 154, 139, 135, 100, 136, 139, 130, 143, 138, 125, 134, - 125, 126, 125, 120, 120, 119, 117, 110, 109, 106, 101, 99, 99, 100, 100, 98, - 98, 96, 96, 121, 123, 125, 126, 125, 124, 123, 124, 123, 121, 123, 121, 121, - 121, 121, 120, 110, 119, 118, 117, 120, 116, 113, 120, 105, 111, 114, 112, 114, - 122, 125, 124, 120, 120, 122, 121, 117, 116, 117, 120, 119, 122, 121, 108, 119, - 115, 115, 67, 35, 56, 90, 124, 148, 157, 153, 149, 157, 157, 157, 157, 159, - 160, 160, 159, 149, 148, 148, 151, 156, 158, 157, 157, 159, 161, 160, 155, 146, - 140, 137, 137, 151, 154, 158, 162, 166, 164, 160, 156, 170, 174, 178, 184, 183, - 181, 183, 186, 183, 183, 181, 177, 178, 184, 187, 187, 184, 185, 188, 188, 188, - 183, 179, 175, 183, 180, 178, 177, 180, 180, 178, 175, 151, 163, 176, 179, 177, - 176, 180, 185, 183, 181, 180, 182, 184, 185, 186, 185, 188, 185, 181, 179, 181, - 181, 180, 179, 180, 176, 169, 163, 161, 158, 150, 143, 164, 157, 177, 187, 175, - 179, 179, 154, 170, 182, 192, 189, 180, 172, 168, 164, 142, 149, 154, 139, 116, - 151, 151, 154, 164, 148, 145, 158, 162, 152, 144, 149, 104, 125, 120, 128, 133, - 122, 130, 129, 132, 130, 136, 134, 122, 121, 120, 105, 115, 110, 108, 107, 108, - 106, 103, 102, 101, 104, 102, 126, 127, 127, 125, 122, 120, 120, 120, 121, 120, - 119, 117, 116, 116, 116, 117, 116, 124, 123, 119, 123, 120, 116, 122, 116, 118, - 116, 108, 104, 107, 109, 108, 110, 113, 115, 115, 112, 112, 115, 117, 117, 116, - 115, 111, 121, 110, 117, 85, 37, 45, 54, 67, 86, 115, 145, 167, 166, 164, - 158, 154, 153, 156, 156, 152, 157, 156, 156, 157, 161, 164, 167, 167, 161, 161, - 159, 155, 152, 150, 150, 151, 152, 150, 146, 145, 150, 156, 159, 163, 159, 162, - 167, 176, 179, 180, 184, 190, 183, 183, 182, 177, 179, 182, 185, 182, 190, 189, - 188, 184, 181, 178, 178, 177, 176, 176, 178, 179, 181, 176, 169, 161, 169, 174, - 179, 181, 180, 179, 180, 180, 186, 185, 186, 188, 190, 190, 187, 184, 188, 185, - 182, 180, 180, 180, 179, 178, 167, 171, 172, 166, 159, 159, 164, 170, 160, 176, - 184, 185, 184, 179, 172, 170, 190, 195, 196, 187, 178, 174, 174, 171, 160, 155, - 145, 127, 111, 155, 163, 169, 150, 145, 151, 166, 173, 162, 151, 146, 125, 109, - 125, 112, 135, 126, 130, 130, 128, 124, 128, 128, 124, 128, 126, 112, 120, 115, - 107, 100, 96, 95, 101, 104, 95, 100, 102, 126, 126, 125, 124, 122, 119, 121, - 122, 125, 122, 119, 117, 116, 114, 115, 116, 115, 122, 120, 118, 123, 119, 116, - 121, 116, 118, 114, 106, 103, 106, 110, 111, 119, 121, 123, 123, 121, 122, 124, - 125, 119, 113, 115, 117, 127, 112, 123, 101, 32, 38, 41, 41, 44, 65, 98, - 123, 136, 145, 155, 161, 166, 169, 164, 156, 162, 161, 160, 158, 158, 160, 165, - 168, 163, 163, 163, 164, 164, 163, 160, 159, 157, 153, 146, 143, 145, 152, 157, - 161, 158, 157, 160, 165, 167, 169, 173, 178, 179, 178, 180, 174, 176, 177, 179, - 173, 182, 182, 184, 180, 178, 175, 178, 179, 180, 174, 168, 165, 166, 169, 170, - 170, 184, 182, 180, 180, 182, 181, 181, 180, 187, 188, 190, 192, 193, 191, 186, - 182, 187, 185, 182, 180, 180, 180, 178, 176, 169, 169, 167, 161, 156, 156, 161, - 168, 163, 193, 192, 182, 189, 179, 168, 186, 192, 193, 190, 182, 176, 174, 173, - 168, 157, 152, 147, 137, 125, 164, 158, 155, 142, 145, 153, 163, 171, 166, 154, - 143, 149, 99, 125, 104, 134, 127, 127, 127, 134, 125, 125, 122, 117, 120, 117, - 103, 95, 104, 113, 113, 109, 101, 95, 93, 95, 98, 101, 115, 116, 122, 122, - 123, 124, 125, 126, 127, 125, 122, 117, 117, 118, 121, 121, 117, 122, 120, 117, - 123, 120, 116, 122, 116, 115, 115, 114, 114, 116, 121, 124, 130, 131, 131, 131, - 128, 128, 128, 129, 121, 120, 120, 118, 129, 118, 125, 92, 27, 39, 49, 49, - 42, 41, 50, 60, 136, 143, 145, 142, 145, 159, 170, 174, 166, 167, 167, 164, - 159, 157, 160, 163, 165, 166, 169, 173, 174, 170, 160, 152, 162, 161, 158, 157, - 157, 156, 154, 154, 158, 155, 156, 159, 161, 162, 167, 172, 183, 186, 187, 184, - 184, 187, 185, 181, 177, 182, 185, 184, 178, 173, 172, 172, 172, 167, 161, 159, - 162, 168, 177, 182, 182, 179, 178, 176, 178, 181, 184, 184, 186, 186, 187, 190, - 191, 190, 186, 183, 186, 183, 181, 179, 179, 178, 176, 174, 178, 165, 154, 154, - 160, 162, 157, 155, 178, 196, 193, 181, 180, 176, 174, 187, 179, 181, 182, 179, - 179, 178, 172, 163, 151, 150, 152, 147, 132, 160, 146, 138, 164, 168, 169, 167, - 172, 175, 169, 157, 157, 110, 111, 112, 131, 123, 128, 123, 134, 128, 126, 120, - 112, 114, 112, 100, 108, 105, 99, 90, 86, 90, 95, 97, 95, 96, 96, 103, - 107, 115, 119, 121, 121, 121, 120, 120, 118, 116, 114, 114, 117, 120, 121, 119, - 123, 119, 116, 123, 120, 116, 121, 118, 118, 119, 120, 118, 113, 115, 117, 121, - 122, 122, 123, 121, 122, 121, 121, 119, 126, 123, 110, 123, 121, 117, 64, 32, - 38, 41, 43, 41, 40, 41, 44, 50, 85, 121, 144, 155, 160, 155, 147, 169, - 173, 175, 174, 169, 166, 166, 167, 168, 167, 167, 168, 169, 167, 160, 154, 165, - 166, 165, 167, 166, 163, 158, 155, 151, 149, 149, 154, 160, 163, 169, 173, 169, - 171, 174, 173, 174, 176, 175, 171, 184, 185, 183, 178, 171, 166, 165, 165, 155, - 160, 167, 172, 176, 177, 177, 175, 178, 179, 180, 177, 176, 177, 183, 189, 186, - 185, 184, 186, 188, 190, 189, 188, 183, 181, 179, 178, 177, 175, 172, 170, 168, - 157, 152, 159, 168, 170, 168, 169, 200, 191, 192, 186, 169, 176, 188, 180, 180, - 181, 181, 180, 182, 183, 178, 169, 162, 156, 150, 136, 114, 147, 148, 156, 166, - 171, 169, 162, 164, 170, 167, 156, 153, 139, 96, 132, 131, 121, 133, 123, 125, - 123, 127, 125, 118, 121, 124, 117, 121, 115, 104, 96, 94, 97, 91, 84, 87, - 84, 82, 102, 106, 112, 115, 115, 112, 111, 111, 111, 109, 108, 108, 109, 111, - 113, 115, 113, 117, 111, 107, 115, 114, 110, 114, 110, 111, 114, 115, 114, 109, - 108, 112, 115, 116, 116, 119, 120, 122, 123, 122, 114, 124, 120, 102, 115, 116, - 107, 44, 36, 38, 37, 40, 43, 44, 42, 41, 34, 47, 55, 61, 82, 120, - 150, 162, 160, 166, 171, 174, 174, 173, 172, 172, 171, 166, 161, 158, 159, 162, - 165, 166, 167, 165, 163, 163, 165, 166, 167, 165, 151, 145, 143, 146, 151, 151, - 154, 156, 165, 168, 172, 170, 172, 174, 175, 170, 171, 166, 161, 156, 158, 162, - 169, 172, 164, 167, 172, 176, 177, 177, 178, 178, 180, 181, 183, 181, 177, 177, - 180, 185, 186, 185, 184, 185, 188, 190, 191, 190, 180, 178, 176, 175, 174, 172, - 169, 166, 154, 155, 161, 166, 163, 160, 168, 183, 210, 189, 192, 190, 170, 183, - 197, 177, 190, 188, 183, 177, 177, 179, 179, 173, 163, 157, 151, 136, 111, 144, - 154, 170, 153, 160, 163, 162, 164, 166, 161, 150, 151, 164, 92, 140, 137, 128, - 137, 129, 128, 128, 134, 132, 126, 129, 130, 118, 69, 73, 78, 82, 86, 81, - 62, 40, 80, 72, 67, 110, 109, 111, 111, 110, 109, 110, 110, 110, 108, 108, - 108, 109, 108, 109, 110, 108, 111, 104, 102, 111, 110, 105, 109, 105, 102, 105, - 111, 111, 107, 108, 115, 116, 116, 116, 119, 121, 124, 124, 123, 110, 116, 113, - 101, 113, 109, 103, 49, 36, 38, 42, 45, 45, 42, 36, 31, 40, 42, 37, - 37, 61, 103, 128, 131, 154, 155, 158, 162, 167, 169, 169, 168, 166, 164, 161, - 158, 157, 160, 165, 169, 165, 164, 162, 163, 167, 168, 168, 168, 159, 152, 147, - 147, 147, 144, 143, 144, 136, 137, 140, 136, 139, 140, 142, 137, 153, 148, 148, - 151, 162, 170, 178, 177, 178, 175, 173, 171, 170, 174, 182, 186, 181, 180, 181, - 180, 180, 180, 179, 178, 184, 183, 184, 185, 188, 188, 186, 184, 177, 176, 174, - 173, 172, 170, 166, 162, 159, 160, 166, 168, 160, 154, 166, 186, 199, 194, 192, - 188, 184, 190, 191, 183, 190, 190, 186, 179, 176, 176, 176, 171, 156, 154, 155, - 145, 121, 148, 152, 165, 163, 168, 173, 177, 180, 176, 171, 164, 153, 169, 100, - 122, 143, 138, 133, 135, 140, 134, 135, 136, 130, 129, 119, 98, 95, 92, 84, - 75, 78, 87, 88, 77, 75, 65, 58, 117, 115, 114, 112, 110, 112, 114, 118, - 114, 114, 114, 114, 112, 112, 112, 112, 114, 116, 109, 107, 115, 115, 111, 115, - 112, 108, 108, 112, 109, 105, 107, 115, 113, 112, 111, 112, 114, 115, 114, 112, - 110, 110, 110, 105, 116, 104, 105, 63, 38, 40, 41, 41, 39, 39, 38, 38, - 38, 34, 28, 36, 79, 133, 160, 160, 156, 154, 154, 157, 163, 167, 168, 166, - 161, 165, 169, 169, 166, 162, 162, 163, 164, 165, 168, 170, 171, 169, 164, 162, - 162, 156, 153, 155, 157, 155, 153, 154, 155, 158, 157, 154, 154, 156, 156, 153, - 156, 155, 159, 169, 180, 184, 179, 172, 169, 173, 178, 180, 180, 177, 179, 181, - 178, 176, 174, 178, 183, 184, 179, 173, 180, 180, 182, 185, 186, 184, 180, 176, - 176, 174, 173, 172, 171, 168, 164, 160, 172, 163, 161, 166, 169, 169, 177, 193, - 181, 199, 190, 183, 197, 193, 180, 188, 184, 190, 193, 190, 185, 181, 176, 169, - 163, 156, 153, 142, 118, 146, 149, 162, 164, 163, 166, 169, 171, 166, 164, 163, - 156, 161, 109, 100, 146, 145, 127, 137, 143, 131, 129, 131, 130, 129, 111, 82, - 93, 94, 88, 73, 68, 73, 69, 59, 66, 57, 53, 109, 110, 109, 105, 103, - 108, 110, 110, 109, 112, 116, 118, 116, 115, 115, 115, 117, 120, 112, 107, 112, - 113, 113, 121, 113, 114, 112, 106, 104, 106, 107, 105, 109, 110, 109, 110, 111, - 112, 111, 110, 106, 120, 120, 110, 110, 117, 103, 78, 37, 38, 42, 44, 38, - 30, 32, 42, 38, 37, 33, 43, 84, 136, 164, 166, 171, 172, 171, 167, 162, - 159, 158, 158, 160, 161, 162, 163, 163, 165, 167, 169, 169, 168, 168, 167, 167, - 167, 168, 169, 165, 160, 152, 149, 152, 155, 156, 155, 159, 159, 159, 160, 161, - 161, 162, 162, 164, 164, 166, 169, 172, 176, 179, 181, 175, 173, 173, 173, 174, - 176, 178, 179, 180, 180, 178, 178, 178, 179, 180, 181, 181, 181, 182, 184, 185, - 184, 181, 178, 177, 177, 173, 167, 161, 159, 163, 167, 163, 166, 167, 165, 170, - 181, 187, 190, 191, 179, 180, 187, 189, 193, 190, 175, 191, 185, 180, 179, 181, - 180, 176, 171, 174, 162, 153, 141, 121, 154, 154, 162, 167, 164, 166, 170, 172, - 167, 167, 168, 156, 148, 119, 95, 128, 127, 137, 135, 139, 133, 128, 123, 121, - 116, 106, 96, 106, 90, 77, 75, 80, 78, 62, 46, 78, 104, 65, 106, 106, - 106, 102, 101, 106, 109, 108, 106, 109, 113, 115, 115, 113, 116, 118, 126, 129, - 122, 116, 118, 112, 106, 110, 110, 110, 110, 106, 106, 108, 109, 107, 115, 116, - 114, 115, 115, 116, 115, 114, 111, 120, 119, 113, 116, 123, 116, 100, 45, 40, - 37, 37, 36, 41, 55, 71, 80, 83, 81, 82, 105, 143, 164, 165, 177, 180, - 181, 179, 176, 173, 173, 173, 169, 174, 177, 175, 171, 169, 173, 176, 180, 178, - 178, 178, 179, 181, 183, 184, 181, 177, 170, 162, 156, 155, 157, 161, 153, 155, - 159, 162, 164, 163, 162, 160, 164, 165, 168, 172, 176, 179, 182, 184, 182, 181, - 179, 178, 177, 178, 177, 178, 181, 181, 181, 180, 182, 181, 183, 183, 181, 181, - 182, 184, 186, 186, 184, 182, 174, 172, 170, 166, 163, 162, 164, 167, 167, 168, - 168, 170, 180, 191, 193, 191, 192, 196, 206, 204, 185, 181, 190, 192, 187, 185, - 184, 181, 177, 174, 175, 174, 166, 167, 167, 149, 115, 139, 148, 168, 167, 165, - 166, 171, 173, 169, 167, 167, 153, 143, 116, 94, 132, 135, 139, 132, 128, 127, - 125, 127, 128, 127, 121, 114, 95, 87, 76, 74, 76, 74, 68, 59, 39, 62, - 63, 103, 106, 106, 103, 102, 105, 108, 108, 104, 108, 112, 111, 109, 108, 113, - 118, 111, 118, 116, 113, 118, 113, 105, 108, 106, 109, 111, 107, 109, 112, 113, - 112, 120, 120, 118, 118, 117, 118, 117, 116, 113, 113, 110, 110, 114, 118, 116, - 111, 79, 72, 66, 66, 69, 81, 100, 115, 117, 126, 127, 120, 127, 147, 162, - 163, 177, 180, 183, 184, 183, 181, 180, 180, 177, 184, 189, 187, 178, 173, 176, - 182, 183, 182, 182, 182, 184, 187, 190, 192, 188, 186, 181, 170, 159, 153, 153, - 157, 156, 157, 159, 161, 163, 165, 165, 166, 162, 164, 166, 170, 173, 175, 177, - 177, 180, 179, 177, 175, 174, 174, 175, 176, 178, 178, 179, 179, 180, 179, 180, - 179, 180, 179, 178, 179, 180, 181, 179, 178, 172, 170, 167, 166, 167, 168, 169, - 168, 167, 168, 170, 177, 189, 200, 198, 192, 201, 196, 200, 199, 186, 185, 190, - 186, 180, 182, 183, 178, 171, 166, 170, 172, 167, 161, 156, 143, 118, 145, 146, - 155, 166, 164, 166, 171, 174, 169, 167, 166, 159, 143, 115, 89, 131, 141, 144, - 139, 143, 142, 141, 135, 129, 121, 112, 108, 108, 103, 96, 88, 81, 78, 76, - 74, 58, 60, 84, 108, 109, 111, 106, 104, 108, 110, 107, 106, 110, 111, 107, - 102, 101, 106, 111, 99, 107, 108, 109, 117, 113, 108, 112, 108, 111, 113, 113, - 114, 116, 117, 114, 120, 120, 117, 116, 115, 116, 116, 115, 115, 110, 105, 108, - 110, 109, 109, 110, 114, 112, 111, 114, 117, 123, 131, 137, 134, 144, 146, 140, - 142, 155, 165, 167, 175, 179, 183, 185, 185, 183, 182, 181, 181, 186, 190, 189, - 183, 179, 179, 181, 183, 182, 180, 180, 181, 184, 187, 190, 185, 185, 182, 176, - 167, 160, 156, 157, 163, 160, 157, 154, 155, 159, 164, 167, 162, 164, 165, 167, - 168, 169, 169, 168, 173, 172, 171, 171, 171, 172, 174, 175, 175, 176, 177, 178, - 178, 178, 177, 177, 181, 179, 177, 176, 176, 177, 176, 174, 175, 171, 169, 169, - 172, 174, 173, 170, 164, 170, 177, 184, 194, 202, 199, 193, 200, 188, 187, 189, - 186, 191, 193, 184, 183, 184, 184, 178, 172, 168, 171, 173, 167, 157, 152, 143, - 124, 154, 151, 157, 165, 162, 163, 170, 174, 169, 165, 163, 167, 148, 122, 85, - 124, 142, 147, 150, 136, 137, 140, 138, 134, 130, 124, 122, 123, 119, 115, 106, - 98, 94, 91, 88, 91, 70, 79, 116, 117, 119, 112, 110, 112, 113, 110, 111, - 113, 114, 108, 104, 104, 109, 114, 115, 120, 118, 115, 121, 116, 110, 115, 115, - 117, 119, 118, 118, 120, 120, 116, 123, 120, 117, 116, 114, 116, 116, 115, 119, - 113, 110, 114, 115, 111, 110, 114, 123, 126, 130, 133, 136, 137, 135, 133, 143, - 150, 152, 150, 152, 164, 173, 176, 180, 183, 187, 189, 188, 186, 185, 184, 184, - 184, 185, 186, 186, 185, 181, 178, 187, 186, 184, 182, 182, 184, 184, 186, 181, - 181, 181, 183, 183, 179, 171, 167, 164, 163, 160, 157, 156, 156, 158, 159, 163, - 163, 165, 166, 167, 167, 168, 167, 172, 171, 170, 170, 170, 172, 176, 177, 176, - 176, 177, 178, 178, 178, 178, 176, 178, 177, 175, 175, 177, 178, 178, 177, 175, - 172, 169, 170, 173, 175, 173, 171, 166, 177, 188, 193, 196, 200, 199, 198, 193, - 191, 197, 196, 183, 186, 196, 197, 192, 190, 186, 181, 178, 176, 176, 176, 160, - 165, 172, 157, 123, 147, 155, 175, 164, 160, 160, 167, 172, 168, 164, 161, 163, - 148, 132, 87, 119, 139, 140, 149, 135, 136, 139, 140, 138, 136, 135, 133, 126, - 123, 121, 120, 118, 117, 114, 108, 99, 92, 82, 118, 122, 122, 118, 116, 115, - 116, 114, 115, 115, 115, 114, 115, 115, 120, 123, 122, 127, 122, 119, 124, 120, - 115, 119, 120, 123, 124, 119, 119, 122, 122, 118, 125, 121, 118, 117, 116, 118, - 119, 119, 115, 113, 112, 115, 116, 115, 116, 119, 127, 134, 139, 139, 140, 143, - 143, 141, 149, 154, 155, 155, 157, 167, 172, 172, 181, 184, 187, 188, 187, 185, - 185, 185, 186, 183, 181, 184, 188, 188, 184, 179, 186, 185, 183, 182, 181, 180, - 179, 178, 177, 176, 178, 183, 188, 188, 182, 176, 173, 175, 176, 175, 172, 167, - 162, 158, 159, 159, 159, 160, 161, 163, 165, 166, 171, 168, 166, 165, 165, 165, - 169, 170, 169, 169, 168, 168, 168, 169, 172, 171, 168, 166, 167, 170, 174, 176, - 177, 176, 174, 172, 170, 170, 171, 173, 174, 174, 176, 189, 199, 200, 198, 200, - 200, 201, 201, 192, 192, 193, 187, 191, 195, 188, 192, 188, 183, 179, 176, 174, - 174, 173, 166, 166, 168, 154, 123, 148, 152, 167, 167, 160, 159, 164, 171, 168, - 164, 161, 153, 142, 139, 92, 120, 138, 129, 137, 142, 142, 141, 141, 139, 138, - 135, 134, 137, 134, 131, 133, 136, 133, 129, 121, 109, 125, 113, 116, 120, 122, - 119, 118, 120, 121, 117, 118, 117, 116, 117, 121, 125, 126, 126, 119, 125, 122, - 119, 126, 124, 119, 123, 122, 123, 123, 120, 121, 125, 125, 123, 125, 121, 118, - 117, 117, 120, 121, 122, 113, 115, 113, 111, 113, 117, 120, 121, 131, 141, 149, - 148, 147, 152, 157, 158, 154, 160, 164, 164, 161, 164, 166, 167, 178, 181, 183, - 184, 184, 183, 184, 186, 186, 184, 183, 183, 184, 184, 183, 181, 182, 184, 184, - 183, 180, 178, 176, 174, 177, 177, 178, 180, 182, 183, 182, 183, 190, 191, 189, - 187, 183, 179, 175, 173, 168, 166, 163, 161, 161, 162, 164, 165, 165, 164, 163, - 162, 163, 164, 166, 167, 167, 165, 163, 162, 163, 165, 169, 169, 166, 165, 166, - 169, 173, 174, 173, 172, 173, 173, 173, 172, 173, 176, 180, 184, 188, 196, 202, - 201, 199, 200, 199, 198, 205, 190, 185, 189, 189, 194, 192, 178, 188, 187, 185, - 178, 171, 167, 171, 174, 172, 163, 157, 147, 126, 155, 153, 159, 171, 163, 159, - 164, 171, 169, 167, 164, 156, 141, 139, 89, 120, 143, 129, 137, 129, 126, 126, - 131, 138, 144, 146, 146, 147, 144, 141, 140, 140, 138, 135, 130, 122, 138, 129, - 111, 116, 119, 117, 118, 121, 122, 121, 124, 120, 117, 119, 122, 126, 124, 121, - 122, 129, 127, 126, 129, 124, 117, 121, 122, 123, 122, 119, 121, 126, 128, 126, - 124, 121, 117, 117, 119, 121, 124, 124, 122, 124, 122, 115, 114, 122, 128, 126, - 128, 141, 153, 153, 152, 155, 159, 160, 161, 170, 177, 176, 171, 165, 166, 170, - 179, 181, 185, 185, 186, 186, 189, 191, 184, 185, 186, 182, 180, 178, 180, 182, - 182, 185, 186, 187, 184, 181, 178, 177, 182, 184, 184, 181, 177, 178, 183, 189, - 202, 196, 188, 179, 177, 177, 182, 184, 188, 183, 178, 171, 169, 167, 168, 168, - 162, 160, 163, 162, 164, 167, 171, 172, 172, 170, 167, 164, 165, 168, 171, 174, - 176, 176, 177, 178, 179, 178, 174, 171, 175, 176, 177, 176, 176, 180, 188, 194, - 195, 198, 199, 197, 197, 200, 196, 191, 191, 193, 202, 200, 185, 181, 194, 196, - 190, 194, 194, 185, 175, 170, 175, 183, 163, 168, 172, 157, 124, 150, 159, 180, - 174, 165, 160, 164, 170, 170, 167, 165, 167, 145, 135, 81, 114, 148, 136, 146, - 142, 135, 129, 127, 130, 131, 130, 126, 135, 134, 133, 133, 134, 136, 138, 139, - 142, 142, 134, 122, 119, 119, 117, 114, 115, 119, 122, 126, 126, 124, 123, 124, - 126, 128, 128, 125, 123, 123, 122, 122, 123, 124, 124, 132, 124, 119, 119, 123, - 125, 123, 120, 122, 124, 125, 125, 128, 130, 126, 118, 122, 128, 131, 112, 114, - 125, 122, 136, 143, 147, 154, 158, 159, 159, 163, 165, 174, 174, 176, 177, 177, - 175, 170, 166, 171, 175, 181, 183, 186, 185, 188, 188, 183, 183, 189, 192, 198, - 195, 191, 183, 186, 183, 180, 177, 176, 176, 178, 180, 174, 179, 185, 186, 183, - 180, 178, 178, 181, 188, 192, 181, 173, 172, 181, 185, 189, 190, 195, 192, 189, - 181, 178, 173, 176, 174, 173, 169, 167, 165, 163, 163, 161, 162, 164, 168, 174, - 180, 185, 188, 193, 188, 185, 185, 182, 174, 168, 167, 174, 178, 183, 185, 186, - 187, 189, 192, 194, 198, 202, 200, 198, 198, 196, 192, 187, 194, 194, 189, 191, - 199, 199, 190, 198, 196, 189, 181, 181, 184, 185, 182, 171, 169, 167, 154, 137, - 143, 155, 154, 170, 165, 163, 162, 165, 166, 166, 166, 157, 146, 140, 94, 107, - 128, 142, 135, 138, 134, 133, 127, 127, 125, 127, 127, 129, 130, 133, 136, 139, - 140, 141, 141, 131, 133, 135, 132, 128, 128, 125, 122, 120, 122, 124, 122, 121, - 121, 121, 125, 127, 130, 130, 124, 122, 121, 121, 122, 123, 124, 124, 120, 118, - 116, 117, 119, 120, 116, 113, 124, 123, 119, 113, 114, 121, 125, 124, 126, 120, - 122, 120, 127, 129, 118, 133, 145, 150, 157, 160, 161, 162, 164, 167, 165, 166, - 169, 173, 173, 170, 165, 161, 166, 171, 176, 180, 184, 185, 184, 183, 183, 184, - 186, 190, 194, 194, 191, 187, 190, 188, 185, 183, 181, 181, 182, 182, 181, 180, - 178, 174, 172, 174, 179, 184, 181, 186, 187, 182, 179, 182, 186, 187, 191, 190, - 188, 184, 180, 179, 181, 183, 182, 181, 179, 178, 178, 180, 183, 185, 183, 182, - 182, 182, 182, 184, 186, 188, 195, 190, 189, 191, 191, 187, 185, 185, 186, 188, - 190, 190, 189, 190, 194, 197, 196, 201, 202, 198, 196, 197, 197, 195, 197, 202, - 200, 193, 193, 199, 198, 189, 195, 195, 190, 183, 181, 183, 181, 176, 169, 165, - 161, 146, 130, 137, 152, 153, 167, 163, 162, 162, 164, 165, 164, 163, 158, 150, - 142, 104, 109, 134, 143, 139, 137, 136, 136, 134, 132, 130, 127, 126, 129, 129, - 128, 128, 129, 131, 133, 134, 132, 133, 134, 128, 127, 130, 126, 124, 121, 121, - 121, 124, 124, 124, 124, 125, 126, 128, 130, 122, 121, 121, 122, 123, 124, 126, - 127, 127, 127, 128, 128, 126, 123, 118, 115, 116, 116, 113, 105, 104, 111, 118, - 120, 114, 109, 118, 119, 116, 105, 102, 135, 148, 153, 160, 163, 163, 164, 165, - 167, 165, 167, 171, 176, 178, 176, 170, 166, 158, 161, 166, 175, 184, 189, 189, - 187, 185, 185, 185, 187, 191, 193, 193, 192, 188, 187, 186, 184, 182, 181, 179, - 179, 183, 180, 176, 171, 169, 171, 177, 182, 178, 181, 182, 182, 184, 189, 189, - 185, 190, 189, 186, 182, 180, 180, 184, 187, 189, 187, 186, 186, 188, 193, 197, - 201, 196, 194, 192, 190, 187, 187, 187, 187, 193, 188, 186, 190, 192, 191, 192, - 194, 197, 197, 196, 194, 192, 193, 196, 199, 199, 202, 201, 196, 193, 196, 197, - 196, 200, 203, 200, 192, 193, 198, 197, 191, 192, 193, 190, 185, 183, 183, 179, - 173, 173, 166, 160, 145, 129, 137, 156, 160, 163, 160, 160, 162, 164, 165, 164, - 163, 156, 154, 142, 114, 106, 139, 140, 140, 142, 143, 144, 144, 142, 138, 134, - 132, 136, 134, 131, 129, 128, 130, 132, 133, 132, 131, 131, 120, 122, 127, 127, - 126, 123, 122, 123, 128, 126, 126, 124, 123, 122, 122, 122, 121, 122, 122, 123, - 125, 127, 129, 130, 125, 127, 127, 125, 119, 114, 110, 107, 113, 117, 122, 118, - 115, 117, 118, 118, 119, 114, 117, 111, 109, 106, 104, 133, 149, 154, 160, 164, - 164, 164, 164, 166, 170, 171, 173, 178, 182, 182, 178, 176, 165, 165, 165, 172, - 182, 190, 191, 189, 187, 186, 185, 186, 188, 192, 195, 196, 187, 187, 187, 186, - 184, 182, 179, 177, 180, 180, 180, 178, 176, 173, 172, 171, 171, 176, 179, 179, - 182, 186, 186, 182, 185, 187, 189, 189, 187, 184, 184, 184, 190, 190, 189, 189, - 190, 193, 196, 198, 193, 192, 190, 189, 187, 188, 189, 191, 194, 188, 185, 187, - 188, 188, 190, 193, 198, 198, 197, 196, 195, 195, 195, 196, 197, 200, 200, 194, - 192, 194, 195, 193, 193, 194, 191, 187, 189, 196, 197, 194, 191, 191, 189, 184, - 183, 185, 182, 176, 174, 166, 160, 148, 133, 139, 157, 163, 160, 158, 159, 162, - 165, 166, 164, 162, 159, 161, 144, 121, 103, 142, 139, 144, 143, 144, 145, 145, - 144, 141, 138, 135, 139, 137, 135, 133, 132, 132, 134, 135, 132, 128, 126, 124, - 128, 134, 134, 133, 131, 130, 128, 125, 125, 123, 121, 120, 119, 119, 118, 124, - 125, 125, 127, 129, 131, 133, 134, 131, 132, 132, 129, 125, 121, 120, 119, 124, - 130, 137, 135, 132, 131, 130, 127, 121, 120, 119, 110, 118, 129, 119, 127, 147, - 153, 160, 164, 163, 163, 164, 166, 170, 170, 170, 173, 177, 179, 179, 178, 182, - 177, 171, 171, 177, 182, 183, 182, 185, 184, 184, 183, 185, 188, 192, 195, 191, - 191, 192, 191, 190, 187, 184, 182, 180, 180, 181, 180, 178, 173, 167, 163, 161, - 169, 176, 176, 177, 181, 185, 186, 188, 190, 191, 191, 188, 186, 185, 185, 189, - 190, 190, 192, 193, 193, 192, 192, 192, 192, 189, 189, 190, 192, 194, 195, 198, - 191, 187, 189, 190, 190, 192, 195, 194, 195, 197, 199, 199, 198, 196, 194, 191, - 196, 197, 193, 191, 192, 191, 189, 189, 188, 186, 184, 187, 193, 195, 193, 188, - 188, 184, 179, 180, 183, 183, 179, 169, 161, 159, 150, 135, 137, 153, 158, 159, - 158, 159, 162, 165, 166, 165, 163, 165, 168, 149, 123, 102, 140, 140, 147, 140, - 140, 140, 140, 139, 138, 137, 137, 135, 136, 136, 136, 136, 135, 134, 134, 133, - 131, 128, 132, 135, 138, 138, 134, 132, 131, 130, 126, 127, 126, 126, 127, 126, - 126, 127, 125, 128, 128, 129, 131, 133, 135, 137, 139, 139, 139, 139, 140, 140, - 140, 138, 132, 136, 136, 133, 132, 134, 135, 133, 86, 108, 126, 110, 107, 114, - 110, 129, 144, 151, 159, 163, 163, 162, 163, 165, 171, 171, 171, 173, 176, 178, - 177, 176, 179, 174, 169, 168, 173, 179, 184, 185, 180, 181, 182, 182, 181, 183, - 186, 189, 189, 189, 190, 190, 189, 187, 184, 183, 185, 181, 177, 174, 173, 171, - 169, 168, 156, 164, 170, 170, 171, 178, 186, 190, 193, 192, 189, 186, 183, 184, - 188, 191, 187, 189, 191, 194, 195, 195, 194, 192, 191, 190, 187, 187, 187, 189, - 191, 192, 194, 188, 185, 187, 190, 190, 193, 196, 194, 195, 198, 201, 203, 201, - 197, 193, 187, 192, 194, 191, 190, 191, 190, 188, 192, 190, 187, 186, 187, 189, - 189, 188, 185, 184, 181, 176, 176, 180, 181, 177, 170, 162, 161, 156, 140, 139, - 152, 157, 161, 159, 159, 162, 165, 166, 166, 164, 161, 163, 151, 117, 99, 128, - 132, 138, 139, 139, 139, 140, 141, 141, 141, 142, 138, 139, 140, 141, 141, 140, - 139, 138, 136, 135, 133, 132, 134, 136, 136, 134, 130, 130, 130, 130, 131, 131, - 132, 130, 129, 130, 130, 126, 126, 126, 127, 129, 130, 132, 133, 126, 125, 126, - 129, 133, 133, 129, 125, 130, 133, 130, 128, 129, 133, 134, 130, 82, 98, 116, - 104, 96, 93, 97, 129, 142, 149, 158, 163, 164, 164, 164, 166, 172, 172, 175, - 179, 181, 180, 175, 171, 171, 170, 170, 171, 174, 179, 184, 187, 179, 182, 185, - 185, 183, 182, 183, 185, 186, 186, 186, 186, 185, 185, 184, 183, 188, 183, 177, - 175, 176, 178, 178, 177, 163, 165, 164, 162, 166, 175, 181, 182, 189, 189, 188, - 187, 186, 187, 190, 193, 185, 187, 188, 190, 192, 191, 191, 191, 189, 188, 187, - 186, 184, 185, 186, 187, 188, 183, 181, 184, 187, 187, 188, 192, 196, 196, 196, - 199, 201, 200, 196, 192, 188, 192, 192, 188, 187, 190, 192, 192, 193, 190, 188, - 187, 187, 185, 183, 182, 186, 187, 184, 180, 180, 181, 179, 173, 174, 164, 163, - 158, 142, 139, 152, 158, 165, 161, 160, 161, 164, 166, 166, 166, 156, 157, 156, - 113, 103, 118, 126, 126, 134, 136, 140, 143, 145, 145, 144, 143, 145, 145, 144, - 144, 143, 143, 143, 141, 136, 136, 136, 128, 130, 133, 136, 136, 134, 135, 136, - 129, 128, 128, 127, 124, 123, 122, 121, 123, 122, 123, 123, 125, 126, 128, 128, - 128, 125, 127, 130, 134, 131, 124, 116, 128, 131, 132, 131, 135, 138, 135, 128, - 132, 104, 91, 92, 112, 116, 104, 122, 142, 149, 158, 164, 165, 165, 166, 167, - 168, 171, 175, 180, 182, 178, 169, 164, 179, 180, 180, 178, 176, 174, 175, 176, - 181, 185, 189, 190, 187, 185, 185, 185, 188, 188, 188, 188, 188, 188, 188, 188, - 186, 184, 182, 183, 186, 187, 185, 183, 172, 167, 158, 153, 158, 168, 170, 167, - 177, 182, 188, 192, 192, 190, 188, 187, 187, 184, 183, 183, 183, 184, 184, 185, - 192, 190, 189, 188, 186, 187, 189, 190, 191, 186, 183, 186, 187, 186, 186, 189, - 198, 196, 194, 194, 196, 196, 193, 190, 190, 192, 191, 186, 185, 191, 195, 196, - 190, 187, 185, 186, 186, 183, 180, 179, 190, 192, 191, 187, 186, 185, 179, 171, - 172, 160, 158, 153, 136, 133, 147, 154, 167, 163, 161, 161, 164, 166, 167, 167, - 159, 160, 168, 119, 115, 120, 130, 125, 121, 126, 132, 137, 140, 139, 136, 134, - 145, 143, 140, 137, 135, 136, 138, 139, 134, 135, 137, 131, 133, 134, 136, 135, - 133, 131, 128, 138, 132, 116, 129, 117, 122, 115, 123, 116, 104, 97, 97, 104, - 107, 106, 101, 113, 120, 124, 116, 111, 112, 116, 118, 126, 127, 128, 129, 132, - 132, 132, 133, 140, 140, 132, 120, 107, 91, 94, 116, 140, 152, 156, 161, 167, - 163, 159, 166, 167, 172, 178, 181, 178, 175, 171, 170, 177, 178, 178, 177, 175, - 175, 177, 179, 178, 183, 189, 194, 195, 191, 186, 182, 181, 182, 184, 188, 190, - 188, 183, 179, 179, 186, 191, 188, 179, 173, 173, 176, 181, 177, 163, 159, 164, - 161, 158, 167, 172, 178, 187, 193, 190, 182, 178, 178, 180, 182, 188, 194, 188, - 179, 178, 182, 192, 187, 181, 181, 186, 190, 191, 191, 192, 187, 183, 183, 187, - 192, 194, 194, 198, 199, 198, 196, 193, 191, 192, 194, 192, 192, 191, 190, 190, - 189, 188, 188, 190, 189, 189, 190, 189, 186, 180, 176, 185, 181, 179, 182, 183, - 179, 176, 177, 171, 168, 163, 155, 142, 135, 140, 149, 161, 158, 158, 160, 163, - 165, 166, 166, 153, 154, 163, 98, 132, 121, 121, 133, 127, 128, 129, 133, 135, - 135, 133, 130, 133, 130, 127, 126, 127, 131, 135, 139, 131, 133, 135, 129, 128, - 128, 129, 130, 128, 126, 123, 122, 127, 116, 119, 105, 113, 103, 100, 113, 108, - 100, 91, 84, 83, 88, 93, 85, 90, 92, 91, 94, 100, 101, 98, 101, 109, - 121, 136, 140, 134, 133, 137, 119, 135, 138, 134, 135, 131, 125, 130, 140, 151, - 155, 159, 164, 161, 158, 165, 167, 171, 177, 179, 177, 174, 172, 172, 176, 178, - 179, 179, 178, 178, 179, 181, 175, 178, 183, 187, 190, 190, 189, 188, 187, 183, - 178, 177, 179, 182, 185, 186, 183, 177, 174, 178, 186, 187, 180, 172, 172, 180, - 180, 172, 163, 149, 144, 152, 163, 176, 179, 172, 179, 196, 194, 178, 182, 185, - 190, 192, 183, 179, 186, 198, 184, 184, 185, 184, 185, 187, 190, 192, 199, 194, - 187, 185, 186, 189, 190, 191, 192, 193, 194, 193, 192, 192, 194, 195, 192, 192, - 191, 190, 190, 189, 188, 188, 191, 190, 189, 187, 185, 180, 173, 168, 177, 173, - 173, 177, 178, 175, 172, 173, 175, 170, 163, 152, 141, 136, 144, 155, 160, 159, - 161, 164, 166, 166, 164, 162, 156, 158, 153, 110, 136, 124, 122, 130, 130, 129, - 128, 130, 132, 132, 131, 129, 132, 133, 134, 134, 132, 130, 128, 127, 131, 132, - 134, 124, 122, 123, 124, 125, 125, 126, 126, 119, 141, 137, 127, 96, 105, 101, - 103, 82, 77, 77, 77, 79, 83, 90, 95, 100, 99, 95, 93, 95, 96, 90, - 85, 104, 102, 109, 121, 123, 119, 124, 136, 138, 151, 145, 129, 131, 131, 124, - 120, 140, 153, 157, 159, 165, 163, 158, 165, 167, 171, 174, 177, 177, 176, 176, - 176, 176, 178, 181, 182, 181, 180, 180, 181, 177, 178, 179, 181, 183, 186, 188, - 190, 189, 184, 177, 173, 174, 178, 181, 183, 175, 179, 183, 183, 181, 180, 182, - 185, 183, 180, 175, 173, 173, 166, 152, 140, 146, 149, 160, 175, 180, 179, 188, - 202, 190, 182, 177, 179, 182, 181, 177, 177, 179, 183, 188, 189, 187, 188, 192, - 196, 201, 196, 189, 185, 185, 187, 190, 191, 191, 193, 194, 194, 193, 192, 194, - 196, 192, 192, 191, 190, 190, 189, 188, 188, 194, 193, 191, 189, 186, 181, 175, - 171, 176, 174, 175, 180, 182, 179, 176, 176, 182, 175, 164, 151, 138, 135, 145, - 158, 159, 160, 165, 168, 169, 166, 162, 160, 159, 162, 136, 127, 141, 129, 127, - 129, 130, 129, 126, 126, 129, 131, 132, 133, 130, 132, 134, 136, 137, 137, 136, - 134, 132, 134, 136, 114, 112, 113, 114, 117, 121, 126, 127, 122, 129, 116, 115, - 92, 98, 92, 93, 85, 75, 72, 80, 92, 95, 84, 72, 80, 81, 83, 89, - 96, 101, 100, 98, 114, 106, 108, 119, 125, 118, 121, 132, 132, 141, 133, 124, - 123, 119, 113, 116, 140, 155, 158, 158, 164, 164, 160, 167, 167, 170, 172, 174, - 175, 176, 178, 179, 177, 180, 183, 184, 182, 180, 179, 179, 184, 183, 182, 181, - 181, 182, 182, 183, 185, 184, 182, 181, 180, 178, 174, 172, 172, 180, 186, 182, - 172, 168, 174, 184, 185, 174, 167, 165, 168, 173, 162, 141, 133, 131, 142, 162, - 171, 169, 175, 190, 194, 189, 187, 189, 191, 189, 183, 179, 181, 184, 187, 188, - 190, 193, 197, 201, 197, 193, 187, 184, 184, 188, 193, 196, 196, 198, 199, 198, - 195, 193, 194, 194, 191, 191, 191, 190, 190, 189, 189, 189, 189, 188, 188, 188, - 188, 186, 182, 179, 181, 178, 179, 184, 186, 182, 179, 179, 185, 178, 166, 152, - 138, 133, 142, 155, 161, 163, 167, 169, 168, 165, 162, 160, 160, 163, 121, 141, - 143, 136, 136, 135, 132, 128, 125, 124, 127, 131, 134, 136, 133, 132, 130, 129, - 130, 134, 137, 140, 133, 135, 138, 99, 96, 97, 98, 100, 105, 109, 111, 125, - 106, 87, 111, 112, 114, 91, 82, 93, 84, 82, 90, 100, 102, 91, 80, 78, - 80, 85, 91, 96, 99, 101, 104, 104, 101, 113, 136, 145, 135, 125, 122, 127, - 132, 135, 139, 131, 104, 87, 96, 134, 152, 157, 155, 159, 162, 162, 169, 167, - 170, 173, 175, 175, 176, 179, 181, 179, 181, 184, 184, 181, 178, 176, 176, 187, - 187, 186, 185, 184, 181, 179, 178, 181, 181, 182, 184, 184, 181, 176, 172, 180, - 174, 169, 169, 174, 174, 169, 165, 169, 175, 182, 170, 147, 145, 144, 127, 130, - 147, 146, 132, 150, 187, 193, 169, 176, 185, 193, 191, 183, 182, 188, 195, 184, - 182, 181, 184, 191, 197, 200, 201, 194, 191, 187, 184, 184, 187, 192, 196, 196, - 198, 199, 199, 196, 195, 194, 195, 191, 191, 190, 190, 190, 190, 189, 189, 183, - 182, 182, 183, 184, 183, 181, 178, 180, 177, 177, 181, 181, 177, 173, 173, 179, - 173, 164, 152, 139, 133, 141, 152, 163, 164, 167, 168, 165, 163, 162, 163, 159, - 159, 118, 149, 144, 145, 146, 146, 139, 135, 130, 127, 128, 130, 132, 132, 140, - 138, 134, 131, 128, 128, 129, 130, 134, 136, 137, 86, 84, 83, 84, 84, 88, - 93, 94, 103, 97, 99, 133, 124, 112, 93, 99, 85, 86, 89, 89, 88, 91, - 98, 105, 101, 99, 99, 101, 100, 96, 97, 101, 98, 97, 105, 119, 129, 124, - 115, 110, 139, 136, 134, 137, 125, 94, 80, 96, 127, 147, 153, 150, 154, 159, - 161, 168, 168, 171, 175, 177, 176, 177, 179, 181, 180, 182, 184, 183, 180, 178, - 177, 177, 183, 184, 186, 187, 186, 184, 182, 180, 181, 179, 178, 178, 181, 183, - 184, 184, 177, 178, 178, 179, 178, 178, 177, 178, 180, 181, 188, 176, 149, 139, - 118, 75, 86, 106, 111, 98, 99, 128, 160, 174, 185, 182, 176, 175, 181, 187, - 185, 178, 183, 180, 178, 183, 192, 198, 200, 199, 198, 196, 193, 188, 185, 185, - 188, 191, 189, 192, 195, 196, 196, 195, 196, 197, 190, 190, 190, 190, 190, 190, - 190, 190, 188, 186, 184, 184, 184, 182, 179, 177, 182, 177, 176, 178, 179, 175, - 172, 173, 171, 167, 161, 152, 140, 135, 142, 152, 162, 164, 167, 167, 164, 161, - 162, 164, 155, 151, 130, 153, 145, 153, 152, 156, 150, 145, 139, 135, 132, 130, - 128, 126, 136, 139, 142, 144, 144, 141, 138, 135, 133, 134, 135, 84, 84, 84, - 86, 90, 94, 98, 99, 87, 101, 111, 131, 107, 97, 87, 100, 98, 98, 98, - 91, 81, 80, 88, 97, 84, 79, 79, 87, 96, 99, 103, 107, 98, 101, 105, - 104, 106, 113, 117, 118, 130, 128, 122, 124, 126, 117, 115, 133, 125, 146, 153, - 149, 154, 161, 164, 171, 172, 175, 177, 179, 178, 178, 179, 180, 180, 182, 183, - 182, 181, 180, 181, 183, 182, 183, 184, 185, 186, 185, 184, 183, 183, 180, 177, - 176, 179, 182, 184, 185, 175, 186, 196, 194, 184, 179, 185, 195, 195, 182, 183, - 180, 164, 157, 116, 43, 52, 46, 54, 64, 53, 46, 82, 133, 178, 179, 180, - 184, 191, 195, 186, 173, 179, 182, 187, 193, 197, 200, 200, 200, 202, 202, 199, - 194, 188, 185, 186, 188, 188, 191, 195, 197, 197, 196, 196, 197, 190, 190, 190, - 190, 190, 190, 190, 190, 193, 191, 188, 186, 185, 183, 179, 177, 184, 179, 176, - 179, 180, 178, 177, 179, 173, 169, 162, 152, 139, 133, 140, 151, 157, 161, 167, - 168, 165, 161, 161, 162, 150, 143, 150, 157, 148, 159, 153, 158, 153, 151, 147, - 143, 140, 136, 131, 127, 129, 133, 140, 146, 150, 151, 150, 149, 136, 137, 137, - 96, 96, 99, 103, 109, 114, 119, 121, 129, 126, 111, 124, 118, 126, 104, 95, - 91, 90, 92, 96, 104, 109, 112, 114, 104, 91, 85, 92, 103, 106, 105, 103, - 94, 113, 128, 128, 129, 138, 143, 142, 134, 141, 138, 136, 144, 139, 129, 127, - 126, 148, 156, 151, 157, 165, 170, 175, 172, 176, 180, 181, 181, 179, 179, 180, - 179, 181, 182, 182, 182, 183, 186, 189, 184, 184, 183, 183, 183, 183, 183, 183, - 186, 182, 183, 180, 182, 180, 180, 176, 187, 184, 187, 188, 194, 191, 188, 183, - 182, 175, 185, 181, 159, 155, 121, 50, 89, 64, 49, 54, 60, 57, 58, 66, - 105, 147, 187, 190, 171, 162, 171, 181, 177, 186, 197, 203, 204, 201, 201, 202, - 203, 204, 202, 198, 191, 187, 187, 189, 194, 197, 200, 200, 199, 196, 195, 195, - 192, 190, 190, 190, 190, 190, 190, 190, 189, 187, 184, 182, 181, 180, 177, 176, - 182, 177, 174, 176, 178, 177, 178, 182, 182, 175, 165, 152, 137, 129, 136, 146, - 149, 158, 167, 171, 167, 162, 161, 161, 147, 140, 166, 160, 150, 161, 148, 153, - 146, 145, 144, 143, 141, 136, 132, 128, 125, 127, 128, 131, 135, 138, 144, 144, - 141, 141, 140, 127, 126, 126, 125, 126, 126, 126, 126, 131, 128, 125, 120, 120, - 121, 126, 127, 121, 120, 112, 109, 119, 123, 125, 135, 127, 121, 114, 109, 108, - 108, 111, 115, 137, 136, 133, 131, 127, 129, 138, 148, 143, 135, 132, 141, 142, - 132, 128, 128, 129, 150, 153, 144, 151, 162, 166, 167, 171, 176, 182, 183, 179, - 174, 175, 177, 177, 181, 185, 187, 186, 185, 185, 186, 184, 185, 186, 186, 187, - 187, 186, 186, 183, 182, 182, 179, 180, 180, 182, 182, 180, 185, 192, 192, 189, - 183, 179, 177, 186, 166, 167, 160, 157, 144, 99, 69, 116, 101, 76, 55, 43, - 40, 42, 48, 48, 83, 88, 143, 158, 180, 189, 183, 190, 195, 199, 196, 196, - 197, 197, 195, 207, 207, 206, 201, 192, 186, 191, 200, 191, 192, 193, 195, 196, - 197, 198, 198, 192, 193, 194, 194, 192, 192, 193, 195, 197, 189, 182, 184, 186, - 183, 180, 179, 181, 184, 178, 179, 184, 178, 172, 179, 177, 164, 171, 150, 145, - 129, 150, 145, 146, 152, 161, 159, 156, 169, 173, 158, 138, 156, 163, 148, 140, - 150, 153, 145, 149, 151, 149, 141, 129, 122, 122, 125, 125, 124, 125, 131, 135, - 135, 144, 152, 137, 160, 140, 129, 130, 129, 129, 128, 127, 126, 125, 120, 121, - 124, 125, 126, 127, 128, 126, 116, 120, 120, 119, 128, 129, 131, 140, 127, 133, - 139, 141, 139, 133, 129, 132, 133, 132, 136, 140, 144, 137, 133, 132, 132, 130, - 133, 141, 141, 135, 139, 147, 130, 149, 153, 145, 152, 162, 165, 167, 173, 177, - 183, 183, 179, 174, 175, 176, 176, 179, 183, 185, 185, 184, 185, 186, 187, 188, - 188, 188, 187, 186, 185, 184, 186, 185, 183, 182, 181, 182, 183, 183, 180, 183, - 187, 187, 184, 182, 181, 182, 188, 166, 166, 154, 153, 142, 122, 65, 97, 100, - 105, 107, 100, 84, 62, 51, 44, 48, 56, 142, 184, 195, 196, 197, 194, 200, - 202, 200, 198, 201, 201, 201, 201, 204, 206, 205, 198, 190, 191, 198, 191, 191, - 192, 192, 192, 192, 192, 192, 190, 192, 193, 192, 191, 190, 191, 193, 196, 189, - 184, 186, 188, 185, 181, 180, 174, 180, 177, 176, 178, 170, 168, 178, 176, 163, - 167, 144, 135, 123, 144, 146, 170, 169, 171, 165, 156, 159, 160, 148, 161, 154, - 157, 165, 158, 142, 141, 153, 148, 118, 97, 96, 102, 102, 105, 111, 125, 119, - 116, 120, 126, 131, 141, 147, 138, 156, 147, 129, 130, 131, 131, 128, 127, 125, - 124, 128, 128, 126, 124, 123, 122, 121, 117, 115, 108, 100, 105, 127, 134, 127, - 125, 123, 128, 131, 127, 119, 116, 120, 125, 141, 131, 125, 129, 137, 137, 134, - 132, 138, 140, 144, 142, 127, 110, 109, 118, 129, 148, 151, 144, 151, 160, 163, - 165, 172, 177, 181, 180, 178, 175, 176, 176, 175, 178, 182, 184, 184, 184, 185, - 186, 190, 190, 190, 189, 188, 186, 185, 184, 187, 186, 184, 182, 181, 181, 182, - 182, 181, 181, 182, 181, 180, 180, 183, 185, 183, 168, 174, 161, 161, 147, 122, - 48, 110, 101, 93, 90, 93, 97, 97, 98, 122, 96, 84, 143, 173, 173, 168, - 173, 190, 195, 198, 196, 194, 198, 199, 198, 195, 200, 207, 210, 204, 194, 192, - 195, 196, 196, 196, 195, 194, 193, 191, 190, 189, 190, 191, 190, 189, 188, 189, - 191, 194, 188, 186, 189, 190, 186, 181, 180, 179, 185, 183, 180, 178, 168, 167, - 179, 178, 169, 169, 145, 131, 126, 152, 158, 151, 150, 160, 167, 160, 156, 153, - 142, 151, 158, 160, 154, 152, 155, 150, 143, 126, 91, 74, 85, 96, 89, 87, - 95, 110, 111, 113, 123, 129, 130, 132, 133, 134, 139, 139, 129, 130, 133, 132, - 132, 128, 126, 125, 134, 127, 120, 112, 111, 113, 116, 115, 99, 112, 114, 108, - 107, 108, 118, 137, 125, 128, 126, 121, 117, 120, 125, 127, 123, 113, 104, 106, - 112, 113, 113, 114, 114, 121, 129, 132, 122, 110, 109, 114, 125, 144, 148, 144, - 151, 158, 160, 165, 171, 172, 177, 179, 179, 177, 179, 180, 176, 179, 182, 184, - 184, 185, 187, 188, 190, 191, 191, 190, 189, 188, 187, 186, 187, 186, 184, 182, - 180, 180, 181, 181, 183, 182, 181, 179, 179, 179, 181, 183, 179, 175, 177, 164, - 161, 157, 96, 69, 113, 105, 99, 97, 102, 106, 107, 106, 105, 102, 104, 138, - 165, 183, 197, 207, 185, 190, 193, 191, 189, 193, 195, 196, 196, 200, 206, 210, - 205, 195, 191, 193, 197, 197, 198, 197, 196, 193, 191, 190, 188, 190, 191, 190, - 188, 187, 188, 189, 191, 187, 187, 191, 192, 186, 181, 180, 187, 191, 185, 181, - 180, 171, 166, 176, 176, 172, 170, 149, 129, 132, 157, 168, 169, 160, 165, 169, - 157, 149, 146, 140, 142, 153, 152, 140, 139, 147, 142, 121, 104, 89, 85, 89, - 84, 75, 77, 89, 91, 98, 106, 112, 116, 117, 121, 123, 123, 120, 125, 132, - 133, 136, 134, 133, 132, 129, 128, 120, 115, 107, 105, 109, 115, 120, 121, 118, - 119, 112, 112, 124, 126, 122, 125, 111, 119, 124, 129, 135, 139, 131, 120, 126, - 125, 129, 133, 133, 126, 122, 121, 113, 114, 116, 119, 119, 117, 121, 125, 121, - 139, 145, 143, 151, 157, 159, 163, 166, 169, 174, 176, 179, 179, 181, 183, 177, - 179, 182, 183, 183, 184, 186, 188, 186, 187, 188, 188, 188, 188, 187, 187, 188, - 187, 185, 183, 182, 182, 183, 183, 185, 184, 182, 181, 180, 178, 176, 176, 177, - 181, 172, 157, 153, 160, 69, 118, 109, 105, 104, 106, 105, 102, 94, 88, 107, - 110, 132, 153, 170, 170, 174, 181, 190, 195, 196, 194, 193, 197, 199, 199, 201, - 201, 205, 206, 201, 193, 190, 192, 191, 192, 193, 193, 193, 191, 189, 187, 189, - 190, 191, 190, 188, 187, 188, 189, 188, 186, 187, 192, 192, 186, 182, 181, 189, - 187, 178, 176, 182, 175, 168, 173, 169, 170, 166, 149, 122, 129, 148, 157, 172, - 156, 150, 147, 139, 141, 152, 154, 154, 135, 129, 140, 138, 119, 111, 112, 99, - 96, 90, 73, 59, 61, 71, 80, 80, 87, 91, 87, 85, 88, 100, 110, 111, - 114, 119, 136, 136, 136, 136, 134, 133, 131, 130, 120, 117, 116, 118, 123, 124, - 121, 118, 127, 122, 114, 120, 141, 141, 122, 110, 120, 123, 122, 119, 125, 131, - 122, 109, 114, 114, 117, 117, 113, 108, 110, 117, 135, 128, 118, 111, 109, 110, - 112, 112, 117, 135, 141, 143, 151, 157, 157, 165, 166, 167, 171, 175, 177, 181, - 183, 184, 180, 182, 183, 184, 184, 184, 186, 188, 185, 186, 187, 188, 188, 188, - 188, 187, 191, 190, 188, 187, 186, 187, 188, 189, 187, 185, 183, 182, 180, 177, - 172, 169, 163, 175, 171, 157, 149, 135, 45, 111, 105, 99, 93, 88, 90, 95, - 101, 106, 109, 92, 124, 152, 182, 177, 177, 194, 194, 198, 198, 195, 194, 197, - 200, 199, 204, 201, 201, 201, 197, 191, 190, 193, 190, 191, 193, 195, 194, 193, - 191, 189, 189, 190, 191, 190, 187, 186, 187, 188, 188, 186, 189, 193, 193, 187, - 184, 185, 189, 185, 175, 176, 186, 183, 175, 179, 170, 173, 164, 149, 117, 128, - 139, 144, 142, 138, 143, 146, 143, 147, 153, 148, 132, 123, 118, 122, 122, 114, - 110, 108, 94, 93, 85, 71, 66, 72, 69, 60, 67, 81, 92, 90, 83, 80, - 82, 84, 93, 108, 114, 137, 137, 134, 133, 131, 131, 131, 131, 133, 130, 129, - 130, 132, 130, 124, 119, 106, 130, 141, 133, 120, 109, 116, 137, 136, 137, 128, - 115, 116, 124, 125, 114, 118, 113, 109, 105, 101, 102, 114, 127, 118, 116, 113, - 111, 114, 116, 115, 112, 114, 131, 139, 142, 150, 155, 158, 167, 169, 169, 171, - 173, 177, 181, 182, 183, 181, 183, 184, 183, 182, 182, 184, 186, 186, 187, 187, - 187, 187, 186, 186, 185, 189, 188, 187, 186, 187, 188, 189, 190, 188, 184, 181, - 179, 178, 175, 170, 167, 154, 164, 164, 147, 138, 97, 67, 88, 93, 96, 100, - 102, 104, 105, 107, 111, 124, 107, 138, 147, 176, 177, 179, 195, 192, 196, 198, - 193, 192, 195, 198, 197, 201, 198, 197, 198, 196, 191, 190, 194, 192, 194, 196, - 197, 197, 195, 192, 190, 188, 189, 189, 188, 185, 184, 184, 186, 190, 189, 191, - 195, 194, 189, 188, 190, 191, 188, 179, 179, 186, 182, 178, 184, 175, 177, 163, - 151, 117, 134, 143, 146, 154, 158, 167, 163, 151, 147, 138, 117, 104, 112, 108, - 97, 97, 107, 108, 95, 84, 83, 81, 81, 82, 81, 73, 63, 70, 80, 88, - 90, 88, 88, 82, 74, 83, 91, 90, 137, 136, 132, 131, 129, 130, 131, 132, - 133, 125, 121, 122, 127, 131, 129, 126, 139, 130, 112, 110, 127, 132, 125, 124, - 107, 116, 121, 116, 116, 122, 120, 108, 95, 91, 95, 98, 98, 95, 98, 105, - 105, 112, 121, 126, 126, 120, 109, 102, 110, 129, 137, 142, 151, 155, 158, 168, - 172, 172, 173, 173, 177, 180, 180, 180, 182, 183, 183, 182, 180, 180, 182, 184, - 188, 188, 188, 187, 186, 185, 183, 182, 185, 184, 183, 183, 184, 185, 187, 189, - 187, 183, 178, 175, 174, 173, 170, 168, 166, 159, 149, 122, 116, 72, 126, 106, - 98, 98, 94, 88, 82, 81, 87, 94, 98, 115, 164, 150, 172, 183, 185, 183, - 195, 199, 200, 194, 193, 195, 198, 197, 198, 195, 195, 197, 196, 192, 191, 194, - 190, 192, 194, 195, 193, 191, 187, 185, 186, 187, 188, 186, 184, 182, 182, 184, - 193, 192, 194, 197, 196, 191, 191, 194, 189, 189, 181, 177, 179, 171, 168, 178, - 172, 174, 156, 149, 117, 140, 148, 150, 146, 145, 144, 130, 121, 128, 130, 114, - 112, 94, 88, 94, 90, 74, 74, 87, 86, 79, 77, 77, 75, 72, 82, 95, - 90, 84, 73, 65, 72, 87, 94, 95, 84, 77, 66, 137, 138, 137, 137, 135, - 134, 132, 130, 131, 128, 125, 113, 98, 103, 108, 102, 96, 112, 118, 119, 119, - 113, 111, 118, 127, 120, 121, 125, 119, 101, 89, 90, 103, 97, 94, 90, 91, - 95, 102, 108, 102, 108, 115, 119, 121, 122, 127, 132, 118, 127, 138, 147, 152, - 156, 157, 160, 173, 173, 175, 176, 178, 182, 185, 189, 186, 185, 184, 183, 183, - 184, 185, 186, 185, 185, 186, 187, 188, 190, 191, 192, 184, 181, 187, 188, 179, - 181, 188, 187, 183, 186, 186, 180, 176, 174, 170, 165, 168, 133, 144, 124, 90, - 111, 123, 98, 111, 105, 101, 96, 93, 90, 92, 94, 84, 126, 154, 162, 172, - 177, 180, 186, 193, 196, 199, 198, 195, 194, 196, 199, 207, 202, 196, 194, 194, - 193, 190, 186, 187, 189, 192, 194, 194, 193, 191, 190, 194, 190, 186, 186, 189, - 191, 189, 187, 198, 197, 196, 197, 197, 194, 188, 183, 192, 189, 185, 179, 174, - 172, 173, 174, 174, 156, 165, 139, 95, 150, 150, 160, 145, 143, 142, 137, 126, - 116, 110, 107, 107, 102, 97, 92, 86, 79, 81, 88, 82, 79, 75, 75, 80, - 83, 82, 79, 86, 89, 92, 89, 77, 70, 79, 92, 80, 73, 68, 138, 138, - 137, 135, 133, 131, 129, 128, 129, 125, 124, 117, 107, 114, 119, 112, 104, 111, - 107, 105, 114, 117, 121, 132, 116, 118, 117, 115, 114, 115, 114, 108, 92, 97, - 104, 105, 102, 96, 93, 93, 104, 114, 130, 136, 130, 115, 99, 91, 130, 125, - 128, 137, 144, 145, 150, 156, 166, 169, 174, 176, 178, 180, 182, 184, 188, 187, - 187, 185, 186, 186, 188, 188, 187, 187, 188, 187, 187, 184, 183, 182, 193, 186, - 192, 192, 190, 190, 196, 188, 191, 187, 182, 173, 173, 172, 169, 161, 149, 145, - 144, 118, 105, 114, 111, 114, 110, 109, 108, 106, 102, 100, 98, 98, 97, 133, - 159, 166, 175, 181, 182, 188, 192, 194, 198, 199, 199, 198, 198, 199, 197, 196, - 195, 195, 195, 192, 189, 186, 190, 189, 188, 187, 187, 188, 190, 191, 192, 186, - 179, 177, 180, 188, 196, 200, 200, 200, 199, 195, 190, 187, 186, 186, 188, 183, - 177, 175, 175, 176, 176, 174, 191, 171, 170, 126, 102, 149, 145, 146, 136, 130, - 126, 120, 118, 125, 135, 142, 121, 112, 107, 104, 102, 94, 90, 93, 91, 90, - 88, 89, 92, 97, 101, 105, 110, 109, 110, 107, 96, 80, 73, 70, 80, 98, - 91, 138, 137, 137, 136, 135, 133, 131, 130, 132, 125, 125, 123, 118, 124, 129, - 121, 116, 113, 98, 91, 97, 97, 95, 101, 108, 119, 123, 116, 115, 120, 114, - 100, 108, 101, 89, 78, 78, 88, 108, 121, 132, 124, 112, 102, 104, 115, 132, - 146, 123, 117, 121, 133, 143, 148, 157, 166, 164, 169, 177, 180, 182, 182, 181, - 181, 188, 187, 189, 186, 188, 187, 189, 188, 185, 184, 189, 188, 190, 186, 186, - 185, 191, 182, 185, 188, 187, 190, 191, 180, 186, 185, 183, 180, 181, 176, 164, - 148, 145, 156, 134, 103, 121, 124, 103, 126, 121, 122, 124, 123, 123, 119, 115, - 113, 110, 142, 160, 167, 178, 185, 184, 188, 191, 192, 197, 200, 203, 202, 199, - 196, 187, 191, 195, 196, 195, 191, 188, 187, 190, 190, 188, 187, 187, 188, 189, - 189, 182, 185, 189, 192, 193, 195, 197, 198, 204, 205, 203, 197, 190, 188, 191, - 196, 189, 181, 174, 173, 178, 180, 177, 173, 171, 162, 160, 108, 124, 160, 156, - 149, 143, 135, 126, 113, 100, 91, 87, 84, 112, 106, 102, 107, 111, 107, 103, - 104, 105, 111, 113, 114, 113, 116, 119, 125, 100, 97, 98, 104, 105, 97, 88, - 78, 75, 103, 98, 137, 135, 136, 136, 136, 136, 135, 133, 136, 128, 128, 129, - 125, 127, 130, 120, 126, 125, 115, 107, 109, 103, 95, 98, 83, 91, 97, 100, - 107, 117, 123, 117, 119, 115, 111, 108, 105, 101, 95, 93, 102, 111, 122, 128, - 128, 119, 108, 101, 104, 113, 122, 123, 130, 142, 152, 154, 161, 166, 175, 179, - 181, 179, 181, 181, 187, 187, 187, 187, 187, 187, 187, 188, 184, 185, 186, 186, - 186, 186, 185, 185, 191, 184, 188, 192, 188, 190, 192, 184, 198, 193, 183, 175, - 174, 180, 181, 177, 158, 153, 123, 96, 125, 135, 111, 126, 128, 130, 132, 134, - 133, 130, 126, 125, 122, 145, 160, 168, 181, 186, 184, 188, 192, 192, 195, 200, - 204, 202, 196, 190, 187, 191, 195, 196, 192, 189, 189, 190, 189, 191, 193, 194, - 194, 192, 190, 188, 183, 189, 196, 199, 197, 194, 193, 194, 205, 204, 201, 197, - 194, 193, 195, 197, 191, 186, 181, 178, 179, 179, 177, 177, 171, 172, 168, 103, - 144, 155, 147, 131, 123, 122, 124, 125, 123, 119, 116, 112, 98, 94, 93, 98, - 103, 101, 102, 106, 107, 113, 117, 119, 119, 115, 112, 109, 119, 113, 109, 112, - 113, 110, 102, 93, 84, 94, 93, 132, 132, 133, 134, 136, 136, 138, 136, 137, - 128, 130, 131, 127, 128, 129, 120, 107, 114, 114, 112, 117, 114, 111, 118, 128, - 114, 102, 95, 89, 84, 88, 96, 109, 113, 122, 135, 142, 133, 112, 94, 125, - 122, 116, 113, 114, 119, 124, 128, 127, 146, 148, 127, 122, 140, 151, 144, 157, - 161, 167, 171, 173, 175, 178, 180, 186, 186, 186, 187, 187, 186, 186, 186, 188, - 187, 184, 182, 181, 180, 179, 180, 183, 180, 187, 189, 181, 183, 188, 185, 186, - 195, 200, 196, 190, 185, 179, 174, 156, 140, 133, 120, 128, 142, 132, 133, 131, - 131, 132, 132, 132, 131, 130, 129, 130, 149, 162, 172, 187, 191, 191, 194, 196, - 194, 195, 199, 201, 199, 192, 187, 194, 196, 196, 193, 189, 188, 190, 194, 193, - 193, 193, 193, 193, 192, 192, 192, 195, 193, 189, 184, 181, 185, 194, 202, 206, - 201, 197, 196, 198, 197, 191, 185, 185, 186, 185, 181, 178, 175, 178, 183, 170, - 176, 166, 101, 151, 152, 154, 142, 155, 146, 136, 124, 113, 106, 102, 97, 107, - 105, 103, 103, 101, 98, 102, 108, 120, 117, 115, 115, 119, 118, 113, 108, 114, - 115, 118, 119, 119, 118, 114, 107, 96, 90, 82, 129, 128, 130, 132, 133, 133, - 134, 135, 134, 125, 128, 134, 128, 128, 132, 127, 106, 109, 104, 98, 100, 99, - 98, 107, 106, 100, 105, 119, 123, 115, 114, 123, 116, 108, 104, 108, 121, 127, - 125, 120, 98, 103, 112, 125, 137, 145, 149, 149, 144, 159, 153, 124, 116, 135, - 149, 144, 157, 158, 163, 167, 171, 174, 179, 183, 185, 186, 186, 187, 187, 186, - 186, 185, 184, 184, 183, 183, 183, 184, 184, 186, 179, 177, 186, 185, 179, 179, - 190, 187, 181, 192, 203, 195, 181, 162, 149, 137, 143, 133, 157, 154, 136, 144, - 148, 147, 139, 138, 138, 137, 136, 137, 137, 137, 136, 154, 167, 179, 194, 195, - 195, 202, 199, 199, 199, 197, 198, 196, 192, 189, 201, 199, 195, 191, 188, 189, - 192, 195, 197, 194, 189, 186, 186, 190, 196, 200, 193, 192, 190, 189, 190, 194, - 199, 204, 212, 205, 200, 201, 205, 202, 191, 180, 175, 180, 183, 181, 176, 174, - 182, 188, 164, 166, 147, 92, 141, 144, 160, 158, 152, 150, 149, 147, 146, 141, - 136, 131, 121, 119, 120, 121, 118, 117, 123, 132, 112, 102, 92, 89, 95, 101, - 103, 102, 108, 119, 129, 134, 136, 134, 129, 122, 121, 118, 102, 132, 131, 131, - 132, 133, 133, 134, 133, 134, 126, 131, 137, 131, 130, 137, 135, 134, 133, 120, - 109, 110, 104, 98, 102, 113, 118, 131, 141, 142, 133, 123, 117, 133, 128, 123, - 117, 115, 108, 100, 93, 100, 103, 108, 118, 127, 132, 132, 131, 133, 135, 130, - 119, 118, 127, 135, 135, 148, 152, 157, 163, 168, 171, 176, 179, 179, 180, 181, - 182, 182, 181, 180, 180, 174, 175, 177, 178, 177, 175, 171, 169, 173, 167, 172, - 173, 170, 174, 184, 181, 184, 179, 166, 147, 138, 141, 150, 155, 149, 142, 164, - 161, 148, 151, 150, 153, 150, 149, 149, 150, 149, 149, 148, 147, 140, 156, 171, - 183, 195, 195, 195, 204, 202, 201, 201, 199, 195, 195, 196, 198, 202, 198, 192, - 189, 189, 191, 193, 194, 194, 193, 191, 191, 192, 194, 198, 200, 188, 191, 197, - 203, 207, 207, 203, 200, 206, 203, 200, 202, 204, 201, 193, 186, 173, 176, 181, - 180, 178, 178, 184, 187, 182, 172, 143, 101, 133, 129, 143, 135, 132, 135, 139, - 143, 144, 140, 129, 122, 129, 127, 130, 136, 140, 142, 147, 151, 145, 135, 129, - 126, 129, 134, 140, 142, 151, 158, 161, 158, 154, 147, 136, 125, 148, 155, 140, - 139, 136, 137, 135, 136, 135, 134, 134, 138, 130, 135, 140, 132, 129, 138, 138, - 135, 132, 122, 121, 129, 126, 115, 115, 121, 129, 131, 124, 126, 135, 138, 132, - 138, 139, 137, 132, 125, 122, 121, 123, 122, 120, 119, 124, 132, 139, 143, 143, - 149, 139, 137, 148, 154, 149, 144, 144, 136, 140, 148, 155, 160, 165, 167, 170, - 175, 176, 178, 179, 179, 178, 176, 176, 172, 173, 173, 170, 162, 151, 139, 132, - 135, 127, 127, 130, 131, 137, 146, 139, 129, 137, 146, 153, 161, 168, 169, 165, - 171, 158, 154, 147, 154, 161, 145, 151, 154, 154, 155, 156, 154, 153, 151, 148, - 140, 158, 174, 184, 194, 191, 191, 203, 203, 203, 202, 197, 194, 194, 199, 204, - 201, 196, 191, 189, 192, 195, 195, 193, 186, 191, 198, 204, 205, 203, 198, 195, - 197, 195, 193, 195, 200, 204, 205, 204, 190, 190, 191, 193, 194, 193, 191, 189, - 181, 181, 181, 181, 181, 182, 182, 181, 177, 162, 137, 118, 146, 144, 150, 138, - 148, 144, 138, 137, 138, 140, 141, 140, 139, 134, 134, 142, 149, 148, 147, 144, - 144, 143, 145, 144, 143, 142, 142, 146, 150, 152, 151, 147, 148, 151, 145, 137, - 134, 142, 138, 138, 129, 128, 130, 136, 134, 133, 133, 139, 136, 135, 138, 140, - 135, 138, 138, 136, 135, 134, 130, 127, 126, 129, 133, 137, 138, 135, 134, 135, - 140, 142, 144, 141, 144, 148, 150, 148, 144, 138, 134, 127, 135, 134, 130, 136, - 139, 145, 157, 148, 149, 151, 153, 154, 155, 155, 153, 160, 154, 147, 142, 144, - 152, 161, 168, 172, 172, 170, 165, 161, 163, 171, 179, 168, 161, 146, 130, 126, - 133, 142, 148, 161, 164, 167, 167, 164, 161, 164, 165, 170, 170, 170, 171, 169, - 169, 170, 170, 166, 166, 166, 166, 165, 164, 162, 161, 163, 158, 156, 157, 157, - 154, 156, 158, 151, 161, 173, 180, 188, 200, 203, 201, 199, 195, 195, 200, 200, - 196, 194, 201, 205, 198, 189, 187, 192, 195, 193, 188, 191, 197, 199, 195, 194, - 197, 195, 189, 187, 196, 203, 202, 196, 194, 200, 207, 201, 194, 188, 191, 198, - 200, 194, 187, 180, 180, 180, 182, 183, 181, 179, 175, 165, 172, 101, 150, 140, - 142, 152, 155, 153, 151, 150, 148, 147, 144, 143, 140, 145, 143, 141, 141, 143, - 148, 154, 156, 150, 149, 150, 150, 150, 149, 147, 147, 149, 150, 158, 162, 158, - 157, 147, 125, 122, 130, 153, 136, 134, 136, 140, 139, 135, 134, 138, 139, 136, - 137, 139, 139, 136, 136, 137, 132, 134, 136, 138, 136, 136, 138, 139, 143, 143, - 143, 143, 144, 148, 150, 150, 145, 146, 148, 149, 148, 147, 148, 147, 138, 149, - 151, 149, 152, 148, 146, 154, 154, 154, 154, 155, 156, 158, 160, 161, 159, 159, - 159, 159, 159, 159, 159, 159, 150, 152, 153, 149, 145, 145, 150, 154, 143, 152, - 161, 166, 172, 176, 174, 169, 171, 172, 173, 173, 170, 170, 172, 173, 173, 173, - 172, 171, 170, 169, 168, 168, 168, 167, 166, 165, 163, 162, 159, 159, 166, 163, - 162, 165, 162, 158, 158, 160, 157, 157, 169, 186, 198, 200, 203, 208, 199, 195, - 194, 197, 197, 192, 192, 198, 199, 196, 190, 187, 189, 193, 196, 198, 195, 199, - 200, 197, 197, 200, 199, 194, 191, 195, 198, 199, 198, 198, 201, 205, 203, 197, - 191, 190, 192, 191, 185, 179, 179, 179, 180, 179, 179, 177, 173, 171, 171, 159, - 112, 149, 145, 148, 154, 149, 153, 153, 151, 152, 154, 155, 155, 155, 152, 150, - 145, 142, 142, 144, 146, 148, 152, 150, 152, 149, 150, 149, 153, 153, 168, 157, - 153, 144, 141, 149, 158, 148, 107, 136, 159, 128, 129, 135, 139, 135, 129, 130, - 137, 138, 135, 135, 139, 141, 138, 139, 141, 133, 137, 142, 145, 143, 140, 140, - 139, 142, 143, 146, 147, 148, 150, 151, 152, 144, 143, 142, 142, 144, 147, 149, - 151, 145, 156, 157, 156, 158, 152, 147, 153, 156, 155, 154, 153, 155, 157, 160, - 162, 162, 164, 167, 170, 170, 167, 164, 162, 173, 176, 179, 178, 175, 172, 173, - 174, 173, 178, 180, 178, 177, 176, 172, 166, 180, 179, 175, 175, 177, 179, 178, - 178, 181, 180, 178, 176, 174, 173, 169, 169, 177, 175, 172, 170, 166, 165, 164, - 164, 166, 164, 166, 170, 168, 163, 161, 162, 162, 153, 163, 187, 200, 195, 197, - 208, 199, 195, 193, 194, 194, 191, 192, 196, 194, 194, 192, 188, 185, 188, 195, - 201, 196, 199, 198, 195, 196, 200, 200, 199, 199, 198, 197, 197, 198, 199, 200, - 199, 205, 202, 197, 194, 192, 188, 184, 181, 181, 179, 180, 181, 181, 180, 176, - 172, 166, 135, 126, 145, 149, 155, 160, 148, 155, 155, 154, 154, 156, 158, 160, - 161, 160, 158, 154, 151, 150, 150, 149, 150, 157, 157, 158, 154, 152, 152, 158, - 161, 153, 152, 161, 162, 155, 152, 150, 135, 142, 104, 137, 124, 125, 129, 134, - 134, 131, 132, 136, 136, 133, 135, 140, 143, 141, 142, 145, 139, 142, 145, 145, - 144, 140, 138, 137, 138, 140, 143, 147, 148, 149, 149, 149, 146, 145, 143, 143, - 146, 149, 152, 154, 151, 159, 157, 154, 159, 158, 156, 165, 159, 159, 160, 160, - 161, 163, 165, 166, 172, 171, 170, 170, 172, 174, 176, 178, 170, 173, 175, 175, - 172, 170, 169, 169, 180, 180, 177, 171, 172, 178, 182, 182, 187, 182, 177, 177, - 179, 181, 180, 179, 183, 181, 180, 179, 177, 176, 172, 172, 182, 180, 177, 174, - 170, 171, 172, 173, 166, 164, 165, 169, 167, 163, 161, 163, 166, 157, 161, 178, - 189, 190, 193, 201, 201, 197, 195, 192, 192, 190, 191, 193, 194, 195, 193, 190, - 187, 188, 192, 195, 194, 194, 192, 191, 192, 195, 198, 198, 203, 201, 199, 197, - 196, 196, 195, 195, 199, 199, 197, 195, 191, 188, 187, 187, 179, 178, 178, 178, - 180, 179, 175, 173, 160, 117, 142, 142, 148, 155, 157, 145, 159, 158, 156, 154, - 153, 154, 155, 157, 161, 161, 159, 159, 159, 159, 158, 158, 159, 161, 161, 157, - 152, 152, 155, 160, 161, 157, 159, 157, 146, 145, 148, 139, 135, 127, 120, 133, - 128, 127, 133, 138, 140, 142, 144, 140, 137, 138, 143, 144, 141, 140, 143, 142, - 143, 143, 142, 140, 139, 139, 140, 137, 139, 143, 145, 147, 147, 146, 147, 153, - 152, 152, 153, 153, 154, 156, 157, 156, 163, 160, 159, 167, 166, 164, 171, 163, - 165, 168, 171, 172, 172, 171, 170, 176, 174, 171, 170, 171, 174, 178, 181, 180, - 181, 181, 180, 179, 178, 178, 179, 167, 173, 178, 180, 183, 186, 184, 181, 189, - 184, 179, 176, 177, 179, 177, 174, 175, 175, 175, 173, 172, 172, 171, 171, 176, - 174, 170, 168, 168, 169, 170, 172, 169, 165, 162, 164, 165, 162, 164, 168, 165, - 164, 163, 166, 177, 190, 197, 198, 200, 200, 198, 194, 193, 193, 192, 192, 192, - 191, 189, 190, 192, 193, 190, 189, 193, 191, 189, 189, 190, 192, 194, 197, 196, - 199, 200, 198, 194, 192, 195, 198, 189, 191, 191, 189, 186, 184, 184, 186, 179, - 178, 176, 173, 173, 170, 166, 164, 161, 121, 160, 145, 147, 147, 149, 143, 160, - 161, 159, 156, 153, 152, 153, 155, 155, 156, 155, 156, 157, 158, 157, 157, 152, - 154, 156, 156, 153, 151, 153, 154, 160, 154, 157, 157, 148, 147, 151, 145, 138, - 131, 162, 140, 132, 128, 134, 141, 144, 146, 146, 145, 142, 142, 144, 142, 137, - 134, 136, 139, 139, 139, 137, 137, 138, 141, 145, 140, 142, 145, 147, 148, 148, - 147, 147, 153, 153, 154, 155, 155, 155, 155, 155, 152, 161, 162, 164, 171, 166, - 158, 161, 160, 163, 167, 171, 172, 171, 168, 166, 173, 173, 173, 173, 172, 171, - 170, 169, 172, 171, 169, 168, 168, 170, 171, 172, 176, 180, 182, 180, 178, 177, - 174, 168, 186, 183, 179, 177, 177, 175, 174, 173, 174, 173, 173, 173, 174, 174, - 175, 175, 171, 173, 170, 169, 169, 171, 171, 172, 173, 168, 164, 166, 167, 165, - 168, 172, 166, 170, 169, 162, 169, 186, 197, 197, 197, 198, 197, 194, 193, 194, - 191, 188, 185, 184, 184, 188, 193, 196, 193, 191, 196, 192, 189, 191, 192, 191, - 193, 197, 187, 192, 197, 197, 194, 194, 197, 200, 190, 190, 190, 188, 185, 182, - 182, 183, 186, 185, 180, 175, 170, 164, 158, 154, 150, 126, 161, 149, 153, 152, - 157, 157, 157, 160, 162, 161, 157, 156, 157, 160, 157, 157, 155, 155, 155, 156, - 155, 155, 149, 150, 152, 155, 156, 156, 155, 155, 148, 143, 151, 159, 154, 150, - 150, 139, 134, 126, 139, 137, 133, 132, 136, 138, 136, 138, 142, 142, 140, 141, - 143, 141, 135, 132, 133, 138, 138, 140, 137, 138, 138, 141, 145, 144, 145, 145, - 146, 146, 146, 146, 146, 148, 148, 148, 149, 151, 152, 152, 152, 150, 157, 159, - 160, 167, 163, 154, 157, 158, 160, 163, 165, 167, 166, 165, 164, 171, 172, 173, - 173, 172, 170, 168, 167, 173, 172, 171, 172, 174, 175, 175, 175, 172, 173, 171, - 167, 170, 178, 183, 184, 181, 181, 182, 179, 177, 176, 176, 175, 176, 176, 176, - 176, 176, 177, 177, 177, 175, 175, 175, 175, 173, 173, 173, 173, 170, 166, 166, - 170, 169, 167, 168, 172, 171, 171, 170, 167, 168, 171, 182, 191, 190, 195, 197, - 193, 192, 193, 191, 184, 183, 182, 183, 184, 185, 188, 193, 197, 197, 192, 191, - 194, 194, 191, 192, 197, 188, 190, 194, 196, 197, 197, 195, 194, 192, 191, 189, - 188, 187, 185, 183, 183, 184, 181, 175, 169, 163, 156, 152, 148, 144, 139, 152, - 148, 157, 156, 160, 165, 155, 160, 163, 164, 160, 158, 159, 161, 161, 160, 158, - 157, 157, 158, 158, 156, 152, 147, 144, 145, 149, 150, 148, 144, 155, 137, 130, - 130, 127, 132, 142, 140, 135, 57, 89, 136, 136, 139, 140, 136, 131, 133, 137, - 135, 134, 136, 140, 140, 136, 134, 136, 142, 143, 142, 141, 138, 138, 138, 140, - 144, 144, 144, 144, 144, 144, 144, 144, 150, 150, 149, 149, 152, 154, 156, 158, - 158, 161, 157, 155, 164, 165, 163, 169, 164, 164, 166, 167, 168, 169, 170, 170, - 174, 173, 171, 170, 170, 173, 175, 177, 169, 169, 170, 172, 175, 175, 174, 173, - 176, 179, 179, 176, 176, 179, 179, 176, 176, 179, 182, 182, 179, 176, 178, 180, - 175, 174, 174, 174, 174, 172, 172, 172, 176, 177, 177, 176, 174, 173, 172, 171, - 166, 164, 167, 171, 171, 167, 166, 169, 178, 171, 170, 176, 169, 156, 163, 180, - 187, 192, 195, 192, 192, 193, 191, 182, 183, 184, 187, 181, 177, 178, 190, 198, - 198, 191, 193, 194, 194, 189, 190, 195, 196, 193, 193, 196, 200, 198, 191, 184, - 187, 185, 183, 183, 184, 184, 182, 182, 170, 168, 163, 158, 153, 149, 144, 140, - 154, 156, 151, 149, 156, 151, 149, 152, 154, 159, 164, 164, 160, 156, 156, 158, - 159, 158, 156, 156, 157, 159, 160, 159, 151, 142, 133, 131, 134, 135, 131, 126, - 131, 120, 126, 137, 132, 124, 116, 102, 117, 84, 109, 134, 134, 136, 136, 137, - 135, 130, 123, 126, 128, 132, 135, 137, 137, 136, 136, 140, 141, 141, 142, 141, - 141, 142, 142, 137, 142, 146, 147, 144, 144, 147, 150, 148, 148, 149, 150, 150, - 151, 154, 154, 154, 152, 151, 150, 152, 155, 161, 164, 158, 162, 166, 168, 167, - 166, 166, 167, 166, 167, 167, 168, 170, 171, 172, 172, 168, 169, 170, 170, 170, - 172, 176, 179, 179, 175, 171, 172, 176, 178, 176, 173, 179, 170, 174, 178, 170, - 168, 175, 176, 180, 176, 172, 170, 169, 169, 171, 173, 171, 172, 173, 173, 172, - 170, 166, 164, 165, 163, 165, 170, 172, 169, 168, 172, 172, 172, 171, 172, 175, - 172, 168, 163, 182, 177, 175, 176, 182, 186, 186, 183, 180, 179, 180, 169, 166, - 181, 189, 171, 184, 191, 191, 187, 190, 186, 187, 196, 195, 194, 192, 190, 188, - 187, 187, 187, 187, 185, 183, 181, 179, 177, 175, 174, 172, 166, 155, 147, 146, - 149, 157, 162, 161, 161, 161, 157, 155, 155, 160, 164, 160, 158, 156, 160, 164, - 164, 157, 151, 155, 156, 157, 160, 160, 153, 140, 128, 114, 115, 115, 116, 120, - 125, 122, 116, 120, 118, 120, 126, 134, 134, 127, 117, 107, 93, 88, 138, 135, - 133, 132, 133, 134, 133, 130, 140, 138, 135, 131, 133, 134, 136, 139, 141, 142, - 143, 144, 143, 144, 144, 144, 141, 141, 142, 144, 146, 146, 146, 145, 148, 148, - 149, 150, 151, 151, 154, 154, 152, 152, 153, 154, 155, 157, 161, 162, 158, 161, - 165, 166, 167, 167, 168, 169, 170, 170, 170, 170, 170, 171, 171, 171, 170, 171, - 172, 172, 171, 172, 174, 176, 177, 174, 170, 172, 175, 177, 175, 172, 180, 169, - 172, 179, 175, 173, 174, 168, 172, 171, 168, 166, 166, 168, 170, 172, 173, 175, - 174, 173, 172, 171, 169, 169, 169, 166, 168, 172, 172, 169, 167, 170, 174, 176, - 177, 179, 181, 181, 177, 175, 174, 165, 155, 153, 158, 166, 172, 175, 179, 173, - 169, 161, 159, 175, 186, 177, 185, 193, 193, 190, 194, 190, 185, 190, 188, 188, - 188, 189, 189, 190, 190, 190, 185, 181, 178, 180, 186, 188, 185, 181, 162, 161, - 156, 152, 151, 155, 160, 162, 164, 165, 164, 161, 157, 154, 155, 157, 161, 159, - 158, 162, 167, 168, 164, 159, 163, 161, 157, 156, 157, 158, 157, 154, 131, 126, - 119, 114, 116, 123, 126, 124, 136, 135, 137, 140, 141, 132, 116, 102, 116, 118, - 116, 133, 129, 128, 129, 130, 130, 130, 129, 138, 135, 132, 129, 129, 130, 131, - 135, 138, 140, 141, 142, 143, 144, 145, 145, 146, 143, 141, 144, 148, 148, 147, - 141, 148, 148, 148, 149, 151, 152, 152, 152, 151, 153, 155, 157, 159, 159, 159, - 158, 159, 161, 164, 165, 165, 166, 169, 171, 171, 171, 170, 169, 168, 168, 169, - 169, 171, 173, 175, 174, 173, 171, 172, 173, 176, 173, 171, 172, 175, 176, 174, - 171, 179, 167, 170, 178, 177, 175, 172, 162, 167, 165, 163, 163, 164, 165, 168, - 171, 175, 176, 174, 172, 169, 170, 171, 171, 173, 170, 171, 173, 172, 168, 167, - 170, 168, 173, 177, 179, 179, 178, 178, 179, 181, 177, 174, 173, 175, 174, 171, - 165, 173, 161, 159, 159, 156, 161, 170, 168, 167, 175, 177, 181, 192, 191, 184, - 186, 183, 184, 186, 187, 188, 188, 187, 186, 184, 176, 170, 171, 176, 177, 170, - 163, 156, 157, 158, 161, 163, 164, 166, 166, 166, 168, 169, 167, 164, 161, 157, - 157, 157, 156, 154, 158, 163, 166, 164, 162, 165, 164, 160, 158, 158, 161, 166, - 167, 162, 157, 149, 142, 142, 147, 149, 148, 145, 137, 128, 123, 122, 120, 115, - 110, 120, 129, 125, 116, 114, 116, 121, 124, 121, 119, 118, 119, 121, 125, 128, - 129, 130, 128, 128, 135, 136, 139, 140, 141, 142, 143, 143, 147, 146, 145, 147, - 149, 149, 147, 143, 149, 148, 149, 149, 151, 152, 153, 153, 153, 154, 156, 158, - 160, 160, 160, 159, 162, 163, 164, 164, 164, 165, 167, 170, 167, 167, 165, 165, - 165, 165, 166, 167, 170, 172, 175, 175, 174, 172, 172, 172, 175, 173, 172, 173, - 175, 176, 174, 171, 177, 169, 172, 177, 173, 173, 172, 161, 164, 163, 162, 161, - 161, 163, 166, 167, 172, 174, 173, 173, 170, 170, 170, 169, 174, 171, 170, 173, - 173, 169, 169, 171, 167, 173, 178, 177, 175, 175, 177, 180, 176, 177, 180, 183, - 182, 178, 170, 164, 172, 161, 165, 171, 164, 159, 160, 157, 160, 165, 166, 171, - 185, 184, 177, 178, 182, 183, 184, 183, 182, 179, 175, 173, 179, 173, 167, 165, - 165, 163, 157, 152, 159, 163, 166, 169, 171, 172, 172, 173, 169, 170, 171, 169, - 168, 166, 166, 164, 158, 156, 154, 156, 160, 163, 163, 163, 164, 168, 170, 170, - 167, 165, 165, 163, 157, 158, 160, 156, 155, 153, 150, 143, 143, 132, 121, 112, - 112, 114, 116, 114, 109, 115, 117, 108, 101, 102, 107, 110, 108, 109, 114, 113, - 115, 122, 127, 130, 131, 131, 132, 136, 136, 138, 139, 140, 140, 143, 143, 147, - 150, 152, 153, 150, 149, 149, 149, 149, 148, 149, 150, 151, 151, 153, 153, 155, - 154, 156, 156, 157, 158, 160, 161, 164, 165, 166, 165, 163, 163, 165, 167, 165, - 164, 163, 163, 164, 166, 168, 170, 167, 169, 172, 173, 172, 171, 171, 172, 173, - 173, 173, 174, 175, 175, 173, 171, 174, 168, 173, 173, 166, 167, 170, 164, 165, - 163, 162, 161, 161, 160, 161, 164, 169, 171, 173, 175, 175, 173, 169, 167, 172, - 169, 169, 172, 173, 171, 170, 175, 176, 179, 182, 181, 178, 177, 179, 182, 176, - 174, 171, 171, 174, 178, 181, 183, 196, 185, 191, 200, 192, 183, 184, 184, 176, - 177, 172, 169, 177, 174, 165, 167, 174, 175, 175, 174, 171, 167, 163, 161, 164, - 165, 166, 166, 166, 165, 167, 170, 168, 169, 170, 172, 175, 176, 175, 176, 171, - 170, 169, 167, 166, 166, 166, 167, 165, 163, 160, 160, 162, 164, 165, 165, 165, - 170, 174, 175, 172, 167, 165, 163, 151, 155, 161, 160, 159, 156, 151, 143, 148, - 145, 143, 139, 136, 126, 117, 108, 106, 105, 113, 114, 102, 96, 99, 103, 104, - 111, 120, 121, 122, 122, 125, 127, 132, 137, 142, 140, 141, 141, 142, 143, 143, - 146, 146, 146, 151, 156, 156, 152, 149, 152, 154, 150, 149, 149, 150, 151, 152, - 153, 154, 155, 155, 156, 155, 156, 157, 160, 161, 163, 165, 166, 166, 164, 164, - 165, 166, 167, 166, 165, 165, 166, 169, 172, 172, 166, 167, 170, 170, 170, 170, - 171, 172, 171, 172, 173, 174, 174, 173, 172, 171, 169, 168, 174, 171, 162, 164, - 169, 162, 163, 163, 162, 162, 160, 160, 160, 163, 167, 171, 175, 178, 178, 175, - 169, 166, 169, 166, 166, 170, 171, 171, 171, 177, 179, 180, 181, 180, 178, 177, - 177, 178, 180, 180, 180, 180, 180, 179, 177, 178, 172, 161, 164, 169, 162, 160, - 167, 171, 176, 178, 171, 165, 173, 168, 165, 169, 173, 174, 175, 174, 173, 171, - 169, 168, 162, 166, 171, 171, 169, 170, 175, 179, 172, 172, 170, 171, 172, 173, - 173, 174, 174, 171, 168, 165, 164, 163, 161, 160, 165, 164, 161, 160, 160, 161, - 161, 162, 162, 163, 163, 164, 163, 163, 163, 165, 161, 165, 168, 164, 164, 164, - 166, 162, 163, 160, 158, 153, 149, 141, 134, 127, 125, 110, 107, 104, 92, 89, - 96, 99, 96, 101, 110, 118, 118, 119, 121, 126, 130, 136, 140, 141, 143, 143, - 143, 143, 144, 146, 146, 147, 151, 153, 153, 154, 153, 155, 152, 150, 148, 149, - 149, 151, 152, 154, 154, 153, 153, 156, 157, 157, 157, 157, 157, 159, 162, 165, - 167, 166, 166, 167, 168, 170, 169, 167, 165, 166, 168, 171, 171, 168, 168, 169, - 168, 166, 166, 168, 170, 167, 169, 172, 173, 172, 170, 169, 168, 167, 166, 171, - 170, 162, 166, 167, 155, 160, 160, 158, 159, 159, 160, 161, 163, 165, 168, 171, - 173, 173, 171, 167, 165, 167, 163, 164, 167, 167, 166, 169, 175, 175, 174, 172, - 171, 172, 172, 171, 170, 168, 172, 178, 179, 176, 168, 159, 155, 180, 174, 177, - 178, 171, 171, 180, 181, 168, 174, 170, 167, 173, 171, 170, 178, 175, 175, 175, - 175, 175, 175, 175, 175, 169, 171, 173, 172, 171, 171, 173, 174, 171, 170, 171, - 170, 170, 170, 171, 173, 174, 170, 168, 167, 167, 165, 161, 158, 161, 161, 160, - 160, 159, 159, 159, 160, 160, 159, 157, 158, 161, 163, 162, 162, 159, 164, 166, - 159, 159, 160, 166, 164, 172, 165, 160, 152, 151, 148, 150, 147, 136, 127, 117, - 77, 71, 77, 88, 90, 80, 78, 82, 98, 103, 110, 117, 122, 126, 126, 127, - 138, 140, 139, 139, 139, 140, 140, 141, 148, 146, 145, 149, 154, 155, 152, 148, - 150, 148, 150, 151, 152, 155, 156, 156, 153, 155, 158, 160, 160, 158, 155, 153, - 153, 157, 162, 165, 166, 166, 167, 168, 171, 169, 166, 164, 164, 165, 168, 169, - 171, 170, 169, 166, 164, 163, 165, 167, 164, 167, 170, 171, 170, 168, 167, 166, - 168, 165, 169, 171, 169, 171, 166, 148, 157, 156, 157, 157, 159, 160, 162, 164, - 163, 166, 167, 166, 168, 165, 164, 163, 168, 163, 163, 166, 167, 164, 167, 173, - 174, 171, 167, 167, 170, 172, 170, 168, 172, 172, 171, 170, 169, 170, 173, 177, - 175, 177, 183, 183, 173, 175, 177, 171, 177, 185, 181, 178, 180, 176, 173, 181, - 174, 173, 173, 172, 172, 172, 172, 173, 176, 174, 173, 176, 179, 182, 181, 179, - 172, 172, 172, 173, 173, 171, 171, 170, 170, 168, 170, 172, 174, 172, 167, 162, - 164, 164, 165, 164, 164, 163, 164, 165, 166, 166, 166, 170, 174, 173, 166, 163, - 161, 167, 171, 166, 165, 165, 168, 166, 166, 166, 167, 164, 160, 152, 144, 138, - 130, 143, 145, 86, 83, 84, 85, 84, 86, 72, 45, 91, 100, 104, 104, 104, - 107, 111, 113, 116, 129, 129, 129, 134, 132, 133, 143, 135, 144, 152, 153, 149, - 147, 147, 150, 151, 147, 148, 155, 156, 154, 156, 160, 161, 163, 166, 166, 163, - 161, 160, 158, 161, 160, 158, 159, 160, 160, 158, 157, 163, 164, 165, 167, 168, - 170, 173, 173, 167, 166, 164, 163, 163, 164, 165, 166, 166, 168, 167, 163, 163, - 168, 170, 168, 169, 175, 179, 175, 169, 168, 171, 177, 168, 167, 165, 162, 159, - 159, 160, 165, 166, 171, 172, 169, 170, 170, 166, 159, 163, 165, 168, 167, 165, - 166, 170, 175, 176, 174, 173, 175, 177, 176, 172, 169, 165, 168, 172, 175, 177, - 177, 175, 175, 178, 180, 180, 180, 179, 180, 182, 184, 184, 184, 183, 182, 180, - 179, 179, 176, 179, 179, 179, 178, 176, 174, 172, 171, 173, 171, 170, 172, 175, - 178, 179, 179, 177, 175, 173, 171, 170, 170, 171, 172, 173, 171, 169, 167, 166, - 165, 166, 166, 169, 172, 168, 159, 160, 164, 166, 163, 168, 165, 163, 165, 169, - 171, 169, 166, 167, 168, 170, 165, 164, 161, 166, 167, 161, 160, 163, 160, 158, - 149, 143, 138, 141, 144, 149, 79, 76, 82, 83, 78, 73, 62, 40, 88, 98, - 104, 102, 98, 101, 105, 109, 121, 130, 127, 127, 138, 138, 135, 139, 146, 147, - 149, 147, 146, 144, 144, 144, 152, 149, 150, 156, 159, 156, 157, 161, 159, 160, - 162, 161, 158, 156, 154, 155, 155, 154, 153, 155, 157, 158, 159, 158, 158, 159, - 161, 162, 163, 164, 167, 167, 170, 169, 167, 166, 165, 166, 166, 167, 164, 167, - 168, 165, 166, 169, 169, 168, 170, 173, 176, 173, 169, 168, 171, 173, 166, 165, - 165, 162, 160, 158, 161, 165, 165, 175, 175, 171, 168, 170, 171, 171, 171, 170, - 168, 168, 168, 170, 170, 170, 171, 170, 170, 171, 174, 174, 172, 169, 169, 170, - 173, 174, 175, 175, 174, 174, 178, 181, 183, 182, 181, 179, 178, 178, 180, 180, - 181, 181, 181, 180, 179, 179, 176, 176, 176, 175, 175, 175, 175, 175, 184, 181, - 178, 177, 178, 178, 177, 176, 178, 178, 178, 177, 175, 173, 170, 169, 169, 168, - 167, 166, 165, 166, 167, 168, 165, 168, 169, 165, 165, 169, 169, 165, 166, 165, - 164, 165, 167, 169, 169, 166, 170, 171, 172, 170, 167, 165, 167, 169, 173, 168, - 165, 165, 166, 163, 155, 150, 153, 152, 149, 81, 78, 89, 96, 87, 79, 74, - 67, 84, 95, 106, 107, 107, 112, 118, 125, 130, 136, 132, 134, 148, 149, 145, - 149, 145, 142, 141, 144, 151, 157, 160, 160, 157, 155, 156, 160, 161, 160, 161, - 163, 157, 158, 159, 158, 155, 154, 153, 155, 151, 150, 150, 152, 156, 158, 158, - 157, 161, 161, 162, 163, 163, 164, 164, 164, 166, 165, 164, 163, 163, 163, 163, - 163, 162, 167, 169, 168, 168, 170, 168, 164, 172, 172, 172, 171, 170, 169, 169, - 170, 166, 165, 165, 163, 161, 160, 163, 168, 166, 176, 178, 172, 168, 170, 175, - 179, 178, 173, 168, 169, 171, 172, 170, 166, 173, 172, 172, 174, 177, 177, 176, - 175, 174, 174, 174, 174, 174, 174, 173, 173, 174, 176, 180, 181, 180, 178, 174, - 172, 176, 177, 179, 180, 181, 180, 179, 178, 176, 175, 175, 175, 176, 178, 180, - 182, 188, 185, 182, 180, 179, 178, 176, 174, 173, 175, 177, 178, 176, 172, 167, - 164, 164, 163, 163, 163, 163, 164, 165, 166, 160, 165, 171, 169, 170, 171, 169, - 165, 166, 167, 166, 165, 165, 166, 168, 169, 163, 164, 165, 164, 162, 160, 160, - 160, 170, 162, 155, 155, 160, 160, 153, 146, 149, 145, 140, 94, 90, 101, 108, - 95, 82, 85, 88, 97, 103, 104, 99, 93, 90, 87, 87, 93, 101, 99, 102, - 115, 118, 116, 120, 117, 119, 121, 126, 134, 142, 149, 152, 156, 155, 155, 157, - 159, 158, 160, 161, 159, 160, 161, 158, 156, 154, 156, 157, 153, 152, 151, 153, - 157, 159, 158, 157, 164, 164, 165, 165, 165, 165, 164, 164, 163, 163, 163, 163, - 163, 164, 164, 165, 165, 169, 171, 169, 169, 172, 171, 167, 175, 172, 170, 170, - 172, 172, 172, 169, 167, 166, 165, 164, 164, 164, 167, 171, 169, 176, 176, 173, - 170, 173, 176, 176, 177, 174, 170, 170, 170, 171, 170, 168, 175, 175, 175, 176, - 177, 177, 177, 177, 177, 176, 175, 174, 174, 175, 176, 177, 171, 172, 173, 175, - 178, 177, 175, 173, 175, 176, 178, 181, 181, 180, 178, 177, 178, 177, 176, 176, - 177, 180, 183, 185, 181, 179, 177, 177, 178, 178, 177, 174, 168, 168, 171, 172, - 171, 168, 165, 163, 162, 162, 161, 161, 161, 161, 161, 162, 163, 166, 169, 170, - 170, 168, 167, 165, 164, 165, 167, 166, 165, 164, 167, 170, 167, 168, 169, 169, - 167, 165, 163, 162, 167, 162, 157, 157, 158, 157, 152, 146, 147, 146, 145, 103, - 97, 103, 103, 85, 74, 80, 86, 77, 82, 88, 96, 106, 117, 122, 121, 115, - 127, 128, 128, 135, 134, 135, 143, 139, 145, 150, 151, 150, 151, 156, 160, 148, - 148, 148, 149, 150, 152, 154, 153, 159, 159, 159, 157, 155, 155, 157, 159, 157, - 155, 154, 155, 158, 159, 158, 157, 161, 161, 162, 162, 162, 162, 161, 161, 163, - 164, 165, 167, 169, 170, 171, 171, 169, 171, 171, 167, 168, 172, 173, 171, 176, - 172, 169, 169, 172, 171, 171, 166, 163, 163, 164, 163, 163, 164, 167, 171, 171, - 173, 173, 172, 174, 177, 173, 166, 170, 172, 172, 171, 169, 169, 171, 174, 173, - 173, 173, 172, 171, 171, 171, 172, 177, 176, 175, 175, 175, 177, 180, 180, 174, - 171, 169, 169, 173, 174, 175, 174, 174, 174, 175, 176, 175, 173, 171, 172, 178, - 179, 177, 177, 177, 179, 182, 184, 178, 177, 177, 178, 179, 180, 179, 174, 167, - 166, 166, 167, 167, 168, 168, 168, 165, 164, 164, 163, 161, 160, 158, 160, 167, - 168, 167, 167, 167, 165, 164, 165, 161, 163, 166, 166, 164, 163, 165, 166, 163, - 162, 162, 162, 161, 159, 156, 154, 154, 155, 157, 155, 151, 147, 143, 143, 139, - 139, 140, 99, 92, 97, 98, 85, 83, 92, 94, 116, 119, 120, 119, 121, 125, - 123, 119, 128, 141, 141, 138, 141, 137, 137, 146, 135, 143, 149, 149, 143, 140, - 143, 146, 147, 148, 150, 148, 150, 155, 156, 153, 154, 156, 156, 156, 155, 153, - 156, 156, 159, 158, 157, 158, 160, 161, 160, 159, 163, 163, 165, 165, 165, 165, - 165, 164, 162, 163, 165, 167, 169, 170, 171, 171, 171, 173, 171, 167, 167, 172, - 174, 173, 172, 169, 166, 165, 167, 168, 166, 163, 160, 161, 161, 160, 161, 162, - 164, 169, 171, 171, 170, 171, 175, 179, 172, 162, 167, 171, 173, 172, 169, 168, - 173, 177, 174, 175, 175, 173, 170, 170, 171, 172, 175, 175, 174, 174, 175, 177, - 179, 179, 179, 173, 168, 167, 171, 171, 171, 168, 170, 170, 170, 168, 168, 167, - 166, 168, 175, 176, 175, 174, 174, 175, 176, 177, 180, 179, 179, 179, 180, 180, - 177, 172, 171, 166, 167, 164, 166, 166, 171, 171, 167, 165, 167, 163, 163, 159, - 159, 159, 172, 170, 165, 166, 164, 163, 164, 167, 164, 166, 170, 172, 172, 169, - 169, 166, 159, 156, 154, 153, 153, 152, 149, 147, 146, 151, 156, 154, 148, 143, - 142, 143, 143, 144, 143, 89, 88, 93, 94, 92, 99, 106, 100, 91, 102, 109, - 110, 112, 118, 123, 127, 131, 141, 138, 136, 143, 140, 136, 144, 144, 148, 151, - 153, 151, 150, 152, 151, 145, 148, 150, 147, 149, 154, 157, 153, 149, 151, 156, - 157, 155, 152, 154, 153, 156, 155, 154, 156, 161, 162, 162, 161, 164, 164, 165, - 166, 166, 166, 166, 166, 161, 162, 163, 165, 166, 166, 165, 165, 167, 170, 170, - 167, 168, 171, 172, 170, 172, 169, 167, 165, 165, 165, 164, 164, 162, 162, 163, - 162, 161, 162, 166, 169, 169, 170, 169, 169, 173, 177, 172, 166, 172, 172, 173, - 173, 173, 174, 176, 177, 174, 175, 175, 174, 171, 171, 174, 176, 174, 173, 173, - 173, 173, 173, 174, 173, 179, 173, 171, 171, 174, 174, 172, 167, 170, 169, 168, - 166, 167, 168, 169, 171, 172, 172, 173, 173, 173, 174, 174, 175, 178, 177, 177, - 177, 178, 177, 175, 171, 172, 170, 168, 165, 166, 166, 169, 169, 169, 168, 169, - 167, 167, 164, 162, 162, 172, 169, 165, 168, 167, 165, 166, 171, 166, 168, 171, - 174, 176, 173, 169, 165, 163, 158, 155, 154, 154, 154, 152, 149, 150, 151, 153, - 153, 151, 150, 151, 152, 156, 157, 157, 87, 87, 90, 88, 86, 96, 95, 79, - 83, 97, 109, 107, 105, 107, 118, 125, 128, 134, 129, 131, 144, 144, 139, 141, - 145, 143, 142, 141, 143, 143, 141, 136, 137, 139, 142, 139, 142, 148, 150, 146, - 147, 150, 155, 156, 155, 155, 154, 154, 153, 152, 153, 155, 159, 164, 164, 163, - 160, 160, 160, 162, 162, 163, 163, 163, 166, 166, 167, 168, 168, 166, 165, 164, - 163, 168, 170, 168, 169, 171, 169, 163, 172, 172, 170, 166, 165, 164, 164, 165, - 164, 167, 166, 165, 165, 165, 169, 171, 167, 170, 171, 169, 170, 175, 176, 175, - 178, 174, 171, 172, 176, 178, 177, 174, 167, 169, 170, 169, 167, 168, 171, 175, - 173, 173, 172, 171, 170, 169, 169, 167, 174, 171, 171, 174, 180, 180, 175, 169, - 172, 171, 170, 168, 169, 172, 175, 177, 172, 172, 175, 175, 177, 177, 178, 177, - 174, 172, 174, 174, 177, 176, 175, 172, 172, 170, 169, 165, 165, 163, 164, 163, - 168, 168, 170, 169, 170, 167, 166, 167, 170, 166, 166, 170, 171, 169, 168, 173, - 159, 160, 162, 168, 171, 169, 163, 154, 147, 142, 137, 135, 136, 137, 135, 133, - 131, 128, 126, 127, 131, 135, 136, 136, 132, 137, 142, 85, 88, 92, 100, 105, - 107, 102, 99, 78, 106, 120, 106, 100, 109, 116, 111, 126, 128, 130, 131, 134, - 134, 134, 134, 137, 141, 141, 136, 134, 138, 137, 131, 132, 133, 135, 134, 132, - 131, 137, 141, 141, 144, 148, 149, 150, 152, 153, 154, 153, 153, 152, 153, 154, - 158, 160, 162, 161, 165, 164, 158, 156, 162, 165, 164, 162, 160, 159, 163, 169, - 171, 170, 167, 173, 167, 166, 171, 173, 169, 168, 172, 169, 168, 165, 162, 161, - 158, 156, 154, 163, 163, 164, 163, 162, 164, 171, 176, 171, 171, 172, 172, 172, - 170, 168, 167, 170, 171, 174, 175, 175, 174, 172, 169, 168, 172, 175, 174, 169, - 167, 170, 174, 171, 172, 173, 174, 174, 173, 171, 170, 175, 175, 176, 177, 177, - 176, 176, 174, 175, 174, 174, 174, 175, 180, 183, 184, 176, 173, 174, 175, 180, - 179, 178, 173, 179, 172, 169, 168, 173, 173, 173, 167, 171, 168, 169, 167, 171, - 170, 172, 170, 172, 171, 175, 173, 173, 166, 163, 159, 169, 162, 166, 168, 159, - 159, 166, 168, 166, 164, 153, 139, 133, 142, 151, 152, 146, 143, 141, 139, 135, - 132, 135, 140, 132, 132, 132, 132, 131, 131, 131, 131, 131, 129, 129, 90, 90, - 91, 92, 93, 88, 82, 76, 83, 102, 110, 105, 104, 114, 117, 113, 118, 120, - 122, 124, 125, 126, 128, 127, 119, 124, 126, 124, 126, 132, 133, 127, 122, 122, - 124, 124, 125, 126, 130, 132, 132, 135, 138, 141, 142, 145, 149, 153, 153, 152, - 152, 151, 152, 153, 156, 157, 161, 165, 165, 159, 158, 160, 160, 157, 161, 163, - 165, 166, 167, 168, 169, 170, 172, 167, 166, 170, 172, 169, 168, 170, 168, 167, - 164, 161, 159, 157, 156, 155, 157, 159, 162, 162, 164, 166, 169, 173, 168, 168, - 169, 169, 168, 166, 164, 163, 171, 171, 174, 174, 174, 173, 171, 170, 166, 170, - 175, 175, 171, 168, 168, 170, 165, 166, 167, 169, 169, 170, 170, 170, 173, 173, - 176, 177, 177, 177, 178, 177, 174, 174, 173, 172, 173, 175, 179, 179, 176, 174, - 172, 173, 175, 176, 173, 171, 169, 167, 165, 168, 173, 174, 171, 168, 168, 172, - 173, 170, 166, 165, 167, 170, 169, 171, 173, 175, 175, 173, 171, 169, 177, 169, - 171, 171, 160, 158, 165, 163, 148, 152, 160, 160, 147, 134, 138, 148, 143, 137, - 136, 140, 145, 143, 136, 129, 131, 131, 130, 129, 128, 127, 126, 126, 130, 130, - 131, 102, 103, 104, 106, 104, 101, 97, 93, 96, 100, 103, 105, 110, 117, 116, - 111, 118, 118, 119, 121, 121, 121, 123, 121, 116, 119, 121, 120, 120, 122, 121, - 115, 118, 117, 116, 117, 120, 122, 124, 124, 132, 134, 136, 138, 142, 146, 151, - 156, 155, 155, 154, 153, 153, 154, 157, 157, 158, 162, 164, 161, 161, 161, 160, - 157, 160, 165, 168, 167, 164, 164, 167, 171, 167, 163, 161, 165, 166, 164, 163, - 164, 169, 167, 163, 159, 156, 153, 153, 152, 153, 155, 159, 161, 161, 162, 164, - 165, 163, 162, 163, 164, 165, 165, 165, 165, 173, 173, 174, 174, 174, 173, 172, - 170, 167, 171, 177, 178, 175, 172, 170, 171, 170, 170, 170, 170, 170, 171, 172, - 173, 172, 172, 176, 175, 175, 176, 175, 175, 177, 178, 176, 175, 175, 176, 178, - 177, 180, 177, 175, 175, 175, 176, 175, 173, 174, 173, 172, 174, 176, 175, 170, - 165, 170, 174, 176, 171, 164, 161, 164, 169, 163, 164, 166, 167, 168, 168, 168, - 168, 171, 161, 163, 164, 154, 150, 156, 152, 156, 147, 150, 158, 152, 136, 141, - 156, 157, 150, 144, 141, 143, 143, 140, 136, 140, 139, 138, 137, 135, 134, 132, - 132, 125, 127, 129, 99, 101, 103, 104, 106, 106, 105, 104, 108, 103, 101, 107, - 112, 111, 111, 110, 116, 116, 116, 116, 115, 114, 113, 112, 114, 114, 116, 114, - 114, 111, 110, 106, 118, 114, 111, 112, 115, 117, 117, 115, 132, 135, 140, 141, - 145, 148, 151, 155, 155, 155, 155, 155, 156, 156, 159, 159, 158, 161, 163, 162, - 163, 164, 165, 165, 163, 165, 166, 165, 163, 163, 165, 168, 167, 164, 163, 164, - 165, 165, 163, 163, 169, 168, 164, 159, 152, 148, 147, 146, 148, 152, 156, 158, - 158, 156, 156, 155, 158, 159, 161, 163, 165, 167, 170, 170, 171, 171, 172, 172, - 174, 174, 174, 173, 168, 170, 174, 175, 173, 171, 171, 171, 176, 175, 173, 172, - 171, 172, 173, 174, 173, 174, 174, 174, 173, 172, 172, 172, 176, 175, 174, 173, - 172, 172, 173, 171, 174, 172, 170, 169, 169, 170, 171, 172, 171, 170, 169, 170, - 171, 171, 169, 167, 173, 174, 176, 171, 168, 165, 167, 169, 166, 164, 164, 162, - 162, 161, 162, 161, 168, 159, 162, 164, 158, 156, 161, 160, 164, 141, 130, 138, - 147, 149, 149, 151, 147, 151, 154, 147, 143, 142, 146, 146, 149, 147, 148, 146, - 146, 144, 144, 144, 144, 146, 147, 105, 104, 104, 103, 102, 99, 98, 98, 107, - 104, 105, 111, 111, 108, 108, 113, 106, 104, 105, 105, 105, 105, 104, 104, 104, - 103, 106, 108, 109, 108, 108, 108, 112, 110, 107, 109, 111, 114, 115, 113, 128, - 134, 141, 144, 146, 146, 148, 148, 147, 148, 149, 151, 152, 153, 155, 155, 160, - 159, 159, 158, 158, 159, 162, 168, 166, 163, 160, 161, 163, 165, 164, 163, 170, - 169, 168, 167, 168, 169, 168, 166, 168, 169, 166, 161, 154, 150, 149, 150, 145, - 147, 151, 155, 158, 158, 156, 155, 159, 160, 160, 162, 164, 166, 168, 169, 168, - 168, 170, 172, 173, 175, 178, 177, 168, 168, 168, 167, 167, 168, 169, 171, 172, - 171, 170, 169, 169, 171, 172, 173, 176, 175, 173, 171, 168, 166, 165, 164, 165, - 164, 162, 161, 159, 159, 159, 160, 160, 161, 160, 160, 160, 162, 165, 167, 161, - 159, 158, 159, 162, 167, 170, 171, 168, 165, 164, 162, 167, 166, 166, 162, 166, - 163, 163, 159, 159, 157, 158, 157, 158, 147, 151, 155, 151, 152, 155, 153, 141, - 134, 127, 128, 141, 150, 147, 139, 126, 135, 145, 147, 150, 152, 150, 142, 148, - 147, 148, 147, 148, 147, 148, 149, 152, 154, 155, 109, 107, 108, 105, 103, 101, - 102, 103, 100, 101, 106, 109, 110, 109, 112, 117, 99, 98, 100, 102, 104, 105, - 105, 106, 106, 104, 103, 106, 106, 103, 103, 107, 110, 109, 109, 110, 114, 117, - 119, 120, 126, 132, 141, 146, 148, 148, 148, 149, 149, 150, 152, 154, 155, 156, - 158, 158, 165, 161, 158, 157, 155, 152, 155, 160, 165, 162, 158, 158, 163, 165, - 164, 161, 166, 166, 165, 162, 163, 165, 164, 160, 165, 168, 170, 166, 160, 156, - 156, 158, 144, 144, 147, 152, 158, 161, 162, 162, 164, 163, 162, 161, 161, 161, - 162, 163, 168, 168, 169, 171, 172, 175, 179, 178, 173, 171, 170, 169, 169, 172, - 174, 176, 169, 169, 170, 171, 172, 174, 176, 176, 174, 172, 169, 166, 162, 159, - 158, 157, 156, 155, 155, 152, 151, 150, 150, 150, 152, 156, 158, 158, 159, 159, - 163, 164, 168, 165, 161, 157, 157, 158, 162, 163, 160, 152, 150, 150, 158, 159, - 158, 152, 154, 151, 152, 150, 152, 150, 152, 151, 150, 139, 141, 146, 141, 141, - 145, 139, 133, 138, 136, 125, 122, 134, 147, 152, 150, 145, 137, 132, 144, 154, - 154, 141, 148, 146, 149, 147, 150, 149, 151, 152, 146, 146, 147, 96, 95, 96, - 94, 93, 93, 97, 99, 96, 101, 104, 106, 107, 112, 114, 113, 103, 103, 104, - 106, 105, 106, 106, 106, 105, 99, 95, 97, 96, 93, 94, 101, 107, 110, 111, - 109, 109, 110, 112, 116, 123, 129, 138, 142, 146, 149, 151, 154, 154, 155, 158, - 160, 161, 161, 162, 161, 164, 160, 161, 161, 157, 151, 152, 158, 163, 162, 160, - 160, 161, 164, 165, 166, 161, 163, 161, 157, 158, 161, 160, 155, 165, 170, 173, - 169, 161, 156, 154, 155, 148, 146, 144, 147, 154, 158, 159, 160, 163, 164, 163, - 162, 162, 163, 165, 166, 170, 170, 170, 170, 171, 173, 176, 176, 175, 173, 172, - 172, 174, 176, 177, 177, 172, 172, 173, 173, 174, 173, 173, 172, 167, 164, 162, - 159, 156, 153, 152, 150, 149, 148, 146, 145, 143, 142, 141, 143, 146, 152, 157, - 155, 156, 153, 157, 157, 168, 164, 162, 155, 152, 148, 150, 149, 147, 143, 141, - 141, 146, 147, 147, 144, 138, 138, 139, 139, 141, 140, 141, 142, 152, 141, 143, - 148, 143, 143, 145, 139, 138, 138, 134, 124, 115, 119, 138, 157, 161, 159, 149, - 134, 136, 147, 152, 147, 150, 149, 150, 149, 151, 150, 151, 151, 153, 151, 153, - 100, 98, 99, 95, 92, 91, 93, 97, 99, 103, 105, 102, 106, 112, 112, 103, - 108, 106, 106, 103, 100, 96, 93, 91, 76, 71, 69, 74, 78, 80, 85, 94, - 100, 104, 104, 98, 93, 90, 91, 95, 110, 115, 122, 129, 135, 141, 148, 152, - 155, 156, 159, 160, 160, 159, 159, 158, 163, 160, 162, 165, 164, 155, 156, 162, - 162, 165, 166, 164, 161, 162, 167, 172, 166, 168, 166, 162, 162, 166, 165, 158, - 164, 169, 171, 169, 158, 150, 147, 146, 155, 150, 145, 144, 147, 150, 151, 153, - 161, 163, 163, 164, 167, 169, 172, 175, 172, 170, 169, 168, 166, 167, 168, 169, - 165, 163, 164, 166, 168, 169, 167, 166, 170, 169, 168, 167, 164, 161, 157, 153, - 158, 156, 154, 152, 148, 147, 147, 145, 137, 136, 135, 136, 135, 133, 132, 134, - 136, 141, 145, 145, 142, 141, 141, 143, 141, 141, 142, 141, 140, 140, 141, 141, - 138, 138, 138, 137, 136, 136, 138, 139, 133, 134, 135, 133, 136, 133, 134, 134, - 130, 119, 120, 127, 124, 124, 126, 121, 126, 118, 119, 128, 125, 110, 109, 123, - 115, 145, 163, 157, 143, 141, 144, 146, 147, 147, 146, 146, 145, 145, 145, 145, - 149, 149, 147, 104, 98, 96, 98, 98, 93, 91, 94, 104, 98, 100, 108, 112, - 109, 105, 106, 102, 95, 104, 91, 87, 78, 54, 72, 62, 61, 61, 60, 60, - 61, 62, 67, 89, 84, 84, 88, 85, 78, 80, 87, 92, 89, 95, 112, 129, - 136, 140, 145, 150, 155, 158, 158, 156, 156, 160, 163, 167, 166, 164, 161, 161, - 160, 161, 163, 165, 167, 168, 168, 168, 168, 169, 169, 162, 161, 161, 165, 169, - 170, 167, 161, 168, 167, 164, 163, 162, 161, 161, 162, 153, 156, 158, 157, 153, - 152, 159, 165, 171, 168, 167, 164, 163, 164, 167, 169, 163, 162, 164, 164, 163, - 162, 158, 157, 153, 155, 157, 157, 155, 156, 159, 162, 159, 154, 151, 151, 153, - 154, 149, 145, 145, 140, 141, 144, 142, 136, 135, 137, 133, 131, 129, 130, 132, - 131, 129, 128, 136, 143, 143, 139, 139, 144, 143, 140, 144, 137, 134, 135, 133, - 128, 126, 132, 131, 132, 132, 132, 128, 126, 123, 122, 122, 120, 118, 115, 117, - 116, 120, 121, 118, 128, 110, 102, 116, 87, 113, 129, 123, 129, 129, 118, 112, - 107, 91, 78, 89, 108, 139, 170, 151, 146, 122, 143, 140, 137, 142, 151, 152, - 144, 144, 148, 151, 151, 151, 58, 59, 59, 58, 58, 57, 57, 57, 59, 60, - 59, 61, 61, 62, 62, 62, 60, 66, 64, 62, 68, 64, 58, 62, 61, 63, - 65, 67, 68, 68, 68, 68, 70, 70, 70, 70, 70, 70, 70, 70, 67, 68, - 69, 70, 71, 72, 72, 72, 69, 73, 73, 70, 71, 74, 74, 72, 74, 73, - 73, 72, 72, 73, 73, 73, 74, 74, 74, 76, 76, 77, 78, 78, 77, 78, - 79, 81, 81, 81, 81, 80, 79, 79, 78, 79, 80, 81, 81, 81, 81, 82, - 81, 83, 83, 84, 84, 84, 82, 82, 82, 83, 83, 84, 84, 84, 87, 86, - 85, 84, 85, 86, 88, 89, 85, 91, 85, 84, 89, 89, 85, 92, 89, 91, - 92, 93, 90, 91, 92, 93, 90, 92, 93, 94, 94, 94, 94, 93, 88, 95, - 93, 90, 95, 93, 90, 97, 92, 90, 88, 88, 88, 91, 93, 95, 94, 97, - 92, 101, 96, 91, 92, 69, 4, 24, 59, 67, 90, 92, 108, 108, 103, 102, - 91, 92, 102, 102, 97, 101, 104, 101, 101, 104, 104, 102, 103, 106, 107, 106, - 104, 104, 106, 106, 104, 103, 103, 104, 104, 104, 104, 103, 102, 101, 105, 105, - 105, 104, 104, 103, 103, 103, 104, 103, 103, 59, 59, 59, 58, 59, 58, 58, - 58, 55, 56, 58, 59, 60, 62, 62, 60, 62, 63, 63, 62, 61, 62, 64, - 68, 64, 65, 67, 67, 66, 65, 67, 69, 70, 71, 71, 71, 69, 68, 64, - 64, 68, 69, 68, 69, 68, 70, 71, 71, 71, 71, 71, 72, 72, 73, 73, - 73, 75, 74, 74, 73, 73, 74, 74, 75, 71, 73, 75, 75, 74, 73, 73, - 74, 75, 78, 79, 77, 77, 80, 79, 76, 77, 77, 77, 78, 78, 79, 79, - 79, 80, 81, 80, 82, 82, 83, 83, 83, 81, 86, 85, 83, 83, 87, 86, - 85, 83, 84, 83, 85, 84, 86, 85, 86, 84, 87, 88, 89, 87, 87, 87, - 89, 85, 90, 89, 87, 87, 91, 90, 89, 93, 91, 89, 90, 94, 95, 94, - 92, 95, 94, 92, 92, 91, 93, 94, 95, 91, 94, 94, 91, 91, 94, 94, - 91, 99, 94, 96, 95, 101, 84, 93, 66, 1, 25, 58, 67, 97, 95, 105, - 107, 103, 101, 92, 90, 102, 102, 98, 101, 102, 100, 100, 103, 104, 101, 101, - 105, 106, 106, 106, 106, 106, 106, 106, 106, 102, 104, 106, 106, 104, 103, 103, - 104, 106, 106, 104, 103, 103, 103, 103, 103, 101, 108, 105, 58, 58, 57, 57, - 58, 57, 57, 58, 59, 59, 60, 61, 63, 63, 65, 65, 63, 63, 63, 62, - 61, 62, 65, 68, 62, 63, 65, 65, 63, 63, 65, 67, 68, 68, 69, 69, - 69, 68, 67, 67, 71, 70, 69, 68, 68, 68, 69, 69, 71, 71, 71, 72, - 72, 73, 73, 73, 75, 74, 74, 73, 73, 74, 74, 75, 73, 74, 76, 76, - 75, 73, 74, 75, 75, 79, 79, 76, 76, 79, 78, 75, 77, 77, 78, 78, - 78, 79, 79, 79, 80, 80, 80, 81, 81, 82, 82, 83, 81, 86, 86, 83, - 84, 87, 87, 85, 84, 84, 85, 85, 85, 86, 86, 86, 85, 88, 90, 90, - 89, 88, 89, 90, 87, 90, 90, 87, 88, 91, 92, 89, 92, 91, 90, 91, - 93, 94, 94, 93, 94, 94, 94, 93, 93, 94, 95, 95, 93, 96, 96, 93, - 93, 96, 96, 93, 98, 94, 96, 94, 101, 85, 94, 66, 1, 27, 59, 67, - 98, 96, 105, 107, 100, 99, 90, 90, 102, 105, 101, 104, 104, 101, 101, 105, - 105, 102, 103, 106, 106, 106, 106, 106, 106, 106, 106, 106, 102, 104, 106, 106, - 104, 103, 103, 104, 106, 105, 104, 103, 103, 103, 103, 104, 101, 108, 105, 57, - 56, 56, 56, 57, 56, 57, 57, 61, 61, 60, 60, 61, 63, 65, 66, 63, - 64, 63, 63, 62, 62, 65, 67, 62, 64, 65, 65, 64, 63, 66, 67, 67, - 67, 67, 67, 68, 68, 69, 70, 72, 71, 70, 69, 68, 68, 68, 68, 71, - 71, 71, 72, 72, 73, 73, 73, 75, 74, 74, 73, 73, 74, 74, 75, 73, - 75, 77, 77, 75, 74, 75, 76, 76, 79, 80, 77, 76, 78, 77, 74, 77, - 78, 78, 78, 79, 79, 79, 79, 80, 80, 80, 81, 81, 82, 82, 83, 81, - 86, 86, 83, 84, 87, 87, 85, 84, 85, 85, 85, 86, 86, 86, 86, 86, - 89, 91, 91, 90, 89, 90, 91, 87, 90, 90, 88, 88, 91, 92, 89, 90, - 91, 93, 92, 92, 91, 94, 95, 94, 94, 94, 94, 94, 94, 95, 95, 94, - 97, 97, 94, 94, 97, 97, 94, 96, 93, 95, 93, 101, 87, 95, 65, 2, - 27, 60, 68, 98, 96, 105, 107, 98, 98, 89, 89, 103, 106, 103, 105, 105, - 102, 102, 106, 106, 103, 104, 107, 106, 106, 106, 106, 106, 106, 106, 106, 102, - 104, 106, 106, 104, 103, 103, 104, 106, 105, 104, 103, 103, 103, 104, 104, 101, - 108, 105, 57, 57, 56, 56, 57, 57, 58, 58, 61, 60, 58, 57, 58, 60, - 63, 65, 62, 64, 64, 63, 62, 62, 65, 67, 65, 66, 68, 67, 66, 66, - 69, 70, 69, 68, 67, 66, 66, 68, 70, 71, 71, 71, 70, 69, 69, 69, - 70, 70, 71, 71, 71, 72, 72, 73, 73, 73, 75, 74, 74, 73, 73, 74, - 74, 75, 74, 76, 78, 78, 76, 75, 76, 77, 77, 80, 80, 77, 76, 78, - 77, 74, 78, 78, 78, 79, 79, 79, 80, 80, 80, 80, 80, 81, 81, 82, - 82, 83, 81, 86, 86, 83, 84, 87, 87, 85, 85, 85, 85, 86, 86, 86, - 87, 87, 87, 89, 91, 92, 90, 90, 90, 92, 87, 90, 91, 88, 88, 92, - 92, 89, 89, 92, 94, 93, 91, 90, 93, 96, 94, 94, 95, 94, 94, 95, - 95, 95, 93, 96, 96, 93, 93, 96, 96, 93, 95, 93, 94, 92, 101, 88, - 96, 63, 3, 28, 61, 68, 98, 96, 105, 107, 99, 99, 90, 89, 102, 105, - 102, 104, 104, 101, 102, 105, 105, 103, 103, 106, 107, 107, 106, 106, 106, 106, - 105, 105, 102, 104, 106, 106, 104, 103, 103, 104, 105, 105, 104, 103, 103, 103, - 104, 105, 101, 108, 105, 57, 57, 59, 59, 59, 59, 60, 60, 62, 61, 59, - 57, 58, 59, 63, 64, 61, 63, 65, 65, 63, 62, 64, 66, 65, 67, 68, - 68, 67, 67, 69, 71, 71, 70, 68, 66, 66, 67, 68, 69, 68, 68, 68, - 69, 70, 71, 73, 74, 71, 71, 71, 72, 72, 73, 73, 73, 75, 74, 74, - 73, 73, 74, 74, 75, 74, 76, 78, 78, 76, 75, 76, 77, 76, 79, 80, - 77, 76, 78, 77, 74, 78, 78, 79, 79, 79, 80, 80, 80, 80, 80, 80, - 81, 81, 82, 82, 83, 81, 86, 86, 83, 84, 87, 87, 85, 85, 85, 86, - 86, 86, 87, 87, 87, 87, 89, 91, 92, 90, 90, 90, 92, 88, 91, 91, - 89, 89, 92, 93, 90, 89, 92, 94, 93, 91, 90, 93, 96, 94, 94, 95, - 96, 96, 95, 95, 95, 92, 95, 95, 92, 92, 95, 95, 92, 94, 93, 95, - 91, 101, 90, 95, 60, 4, 29, 61, 69, 99, 96, 104, 107, 101, 101, 91, - 90, 102, 104, 100, 102, 103, 100, 100, 104, 104, 101, 102, 105, 107, 107, 107, - 106, 106, 105, 105, 105, 102, 104, 106, 106, 104, 103, 103, 104, 105, 104, 103, - 103, 103, 104, 105, 105, 101, 108, 105, 58, 59, 59, 59, 59, 60, 61, 61, - 64, 63, 62, 61, 61, 62, 64, 64, 61, 63, 65, 65, 63, 63, 64, 65, - 63, 65, 66, 66, 65, 65, 67, 69, 70, 69, 68, 68, 67, 67, 67, 67, - 67, 68, 68, 69, 71, 73, 74, 75, 71, 71, 71, 72, 72, 73, 73, 73, - 75, 74, 74, 73, 73, 74, 74, 75, 73, 75, 77, 77, 75, 74, 75, 76, - 75, 78, 79, 76, 76, 79, 78, 76, 79, 79, 79, 79, 80, 80, 80, 81, - 80, 80, 80, 81, 81, 82, 82, 83, 81, 86, 86, 83, 84, 87, 87, 85, - 86, 86, 86, 86, 87, 87, 87, 88, 86, 89, 91, 91, 90, 89, 90, 91, - 88, 91, 92, 89, 89, 93, 93, 90, 90, 91, 93, 92, 92, 91, 94, 95, - 94, 94, 96, 96, 96, 96, 95, 95, 91, 94, 94, 91, 91, 94, 94, 91, - 95, 94, 95, 90, 100, 90, 95, 56, 5, 30, 62, 69, 99, 96, 104, 107, - 102, 101, 92, 90, 102, 103, 99, 101, 102, 99, 100, 103, 103, 101, 101, 104, - 108, 108, 107, 106, 106, 105, 104, 104, 102, 104, 106, 106, 104, 103, 103, 104, - 104, 104, 103, 103, 103, 104, 105, 106, 101, 108, 105, 57, 57, 58, 59, 59, - 60, 60, 60, 63, 63, 63, 63, 63, 63, 63, 63, 60, 63, 65, 66, 65, - 64, 64, 65, 64, 65, 67, 66, 65, 65, 67, 69, 67, 67, 68, 69, 69, - 69, 68, 68, 69, 69, 69, 70, 71, 72, 73, 74, 71, 71, 71, 72, 72, - 73, 73, 73, 75, 74, 74, 73, 73, 74, 74, 75, 73, 74, 76, 76, 75, - 73, 74, 75, 73, 77, 78, 76, 77, 80, 80, 78, 79, 79, 79, 80, 80, - 80, 81, 81, 80, 80, 80, 81, 81, 82, 82, 83, 81, 86, 86, 83, 84, - 87, 87, 85, 86, 86, 86, 87, 87, 87, 88, 88, 85, 88, 90, 90, 89, - 88, 89, 90, 88, 91, 92, 89, 90, 93, 93, 90, 92, 91, 90, 91, 93, - 94, 94, 93, 94, 94, 96, 97, 97, 96, 95, 95, 92, 95, 95, 92, 92, - 95, 95, 92, 96, 96, 96, 89, 100, 91, 93, 52, 5, 31, 63, 70, 99, - 96, 104, 106, 101, 100, 91, 90, 102, 104, 100, 103, 103, 100, 101, 104, 104, - 102, 102, 105, 108, 108, 107, 106, 106, 105, 104, 104, 102, 104, 106, 106, 104, - 103, 103, 104, 104, 103, 103, 103, 103, 104, 105, 106, 101, 108, 105, 57, 57, - 57, 58, 58, 59, 59, 59, 60, 61, 61, 62, 62, 61, 60, 60, 60, 63, - 65, 66, 65, 64, 64, 65, 66, 68, 69, 69, 68, 67, 70, 71, 63, 64, - 67, 69, 70, 71, 70, 70, 71, 71, 70, 70, 70, 71, 72, 72, 71, 71, - 71, 72, 72, 73, 73, 73, 75, 74, 74, 73, 73, 74, 74, 75, 72, 74, - 76, 75, 74, 73, 73, 74, 72, 76, 77, 76, 77, 81, 81, 79, 79, 79, - 79, 80, 80, 81, 81, 81, 80, 80, 80, 81, 81, 82, 82, 83, 81, 86, - 86, 83, 84, 87, 87, 85, 86, 86, 86, 87, 87, 88, 88, 88, 85, 87, - 89, 89, 88, 87, 88, 89, 88, 92, 92, 89, 90, 93, 93, 91, 93, 91, - 89, 90, 94, 95, 94, 92, 93, 94, 97, 98, 98, 97, 95, 94, 94, 97, - 97, 94, 94, 97, 97, 94, 96, 97, 97, 89, 100, 91, 93, 50, 6, 31, - 63, 70, 99, 96, 104, 106, 98, 98, 89, 89, 102, 105, 102, 105, 104, 102, - 102, 105, 106, 103, 103, 107, 108, 108, 107, 106, 106, 105, 104, 104, 102, 104, - 106, 106, 104, 103, 103, 104, 103, 103, 103, 103, 103, 104, 106, 106, 101, 108, - 105, 61, 61, 62, 62, 62, 61, 60, 60, 62, 61, 60, 61, 63, 64, 63, - 62, 64, 64, 64, 64, 64, 64, 64, 64, 66, 67, 68, 69, 68, 67, 68, - 67, 69, 66, 66, 69, 69, 66, 66, 69, 72, 71, 71, 71, 71, 72, 73, - 74, 76, 75, 73, 71, 70, 70, 71, 71, 74, 75, 76, 77, 77, 75, 74, - 73, 75, 74, 74, 74, 74, 75, 76, 77, 81, 80, 78, 77, 76, 76, 77, - 79, 80, 80, 80, 81, 81, 82, 82, 82, 81, 81, 82, 82, 82, 83, 83, - 84, 86, 86, 85, 85, 87, 87, 86, 85, 91, 85, 88, 90, 84, 87, 92, - 87, 89, 89, 89, 90, 90, 91, 91, 91, 92, 91, 91, 91, 91, 91, 90, - 90, 96, 95, 93, 93, 93, 93, 96, 97, 95, 95, 96, 96, 96, 96, 96, - 96, 95, 97, 96, 92, 92, 96, 97, 95, 102, 94, 99, 96, 98, 87, 92, - 46, 5, 34, 66, 70, 100, 100, 108, 108, 106, 96, 91, 95, 101, 103, 103, - 103, 104, 102, 103, 105, 104, 100, 101, 105, 109, 108, 106, 104, 102, 101, 101, - 100, 102, 106, 107, 104, 104, 106, 104, 100, 109, 107, 103, 100, 100, 102, 105, - 107, 100, 109, 107, 61, 61, 61, 62, 61, 61, 61, 60, 62, 61, 60, 61, - 63, 64, 62, 61, 64, 64, 64, 64, 64, 64, 64, 64, 66, 67, 68, 69, - 68, 67, 68, 67, 70, 67, 67, 70, 70, 67, 67, 70, 72, 71, 71, 71, - 71, 72, 73, 74, 71, 71, 71, 71, 72, 73, 74, 75, 74, 75, 75, 76, - 76, 75, 75, 74, 75, 75, 74, 74, 75, 75, 76, 77, 79, 78, 77, 77, - 77, 78, 79, 81, 80, 80, 80, 81, 81, 82, 82, 82, 81, 81, 81, 81, - 82, 82, 82, 84, 85, 85, 83, 84, 86, 86, 85, 84, 90, 84, 88, 90, - 84, 87, 91, 86, 89, 89, 89, 90, 90, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 92, 93, 92, 91, 91, 91, 91, 93, 94, 95, 95, 96, 96, - 96, 96, 96, 96, 94, 97, 96, 93, 93, 96, 97, 94, 98, 92, 97, 94, - 99, 89, 94, 48, 6, 34, 66, 70, 100, 100, 108, 108, 106, 96, 91, 95, - 101, 103, 103, 103, 104, 102, 103, 105, 104, 100, 101, 106, 107, 107, 106, 105, - 104, 104, 105, 105, 103, 106, 106, 103, 103, 105, 104, 101, 108, 106, 103, 101, - 101, 102, 104, 106, 104, 108, 104, 61, 62, 61, 61, 61, 61, 61, 61, 62, - 61, 59, 60, 62, 63, 61, 61, 64, 64, 64, 64, 64, 65, 66, 66, 66, - 67, 68, 69, 69, 68, 69, 68, 70, 67, 67, 70, 70, 67, 67, 70, 72, - 71, 71, 71, 71, 72, 73, 74, 70, 70, 71, 73, 74, 74, 74, 74, 75, - 75, 75, 74, 74, 75, 75, 76, 75, 75, 74, 74, 75, 76, 77, 77, 77, - 77, 76, 77, 78, 79, 80, 82, 80, 80, 80, 81, 81, 82, 82, 82, 80, - 80, 80, 81, 81, 82, 82, 83, 84, 84, 83, 83, 85, 86, 84, 83, 90, - 84, 87, 89, 83, 86, 91, 86, 89, 89, 89, 90, 90, 91, 91, 91, 90, - 90, 90, 91, 92, 92, 93, 93, 93, 92, 92, 91, 91, 92, 93, 94, 95, - 95, 96, 96, 96, 96, 96, 96, 93, 96, 97, 94, 94, 97, 96, 93, 95, - 90, 95, 93, 99, 92, 97, 48, 6, 35, 67, 71, 100, 100, 108, 107, 106, - 96, 91, 95, 101, 103, 103, 103, 104, 102, 103, 106, 104, 101, 102, 106, 105, - 105, 105, 105, 106, 107, 108, 109, 104, 107, 106, 102, 102, 105, 105, 102, 106, - 105, 104, 103, 103, 103, 104, 104, 106, 108, 101, 61, 62, 60, 60, 61, 61, - 62, 62, 62, 61, 59, 60, 62, 63, 61, 61, 63, 64, 64, 65, 65, 65, - 66, 67, 66, 67, 68, 69, 69, 68, 69, 68, 70, 67, 67, 70, 70, 67, - 67, 70, 72, 71, 71, 71, 71, 72, 73, 74, 72, 73, 74, 75, 74, 73, - 71, 70, 76, 75, 74, 73, 73, 75, 76, 77, 76, 75, 75, 75, 75, 76, - 77, 78, 77, 77, 77, 77, 78, 79, 79, 81, 80, 80, 80, 81, 81, 82, - 82, 82, 80, 80, 80, 80, 81, 81, 82, 83, 85, 85, 84, 84, 86, 86, - 85, 84, 89, 84, 87, 89, 83, 86, 90, 86, 89, 89, 89, 90, 90, 91, - 91, 91, 89, 90, 90, 91, 92, 93, 94, 94, 94, 94, 94, 94, 94, 94, - 95, 95, 96, 96, 97, 97, 97, 97, 97, 97, 92, 96, 97, 95, 95, 97, - 96, 92, 94, 90, 95, 92, 99, 93, 97, 45, 7, 35, 67, 71, 101, 100, - 108, 107, 106, 96, 91, 95, 101, 103, 103, 103, 103, 102, 103, 106, 105, 101, - 103, 107, 105, 105, 104, 105, 105, 106, 108, 108, 105, 107, 105, 101, 101, 104, - 105, 103, 104, 105, 105, 105, 104, 104, 103, 102, 105, 108, 102, 61, 61, 61, - 61, 60, 61, 63, 63, 62, 61, 59, 60, 61, 62, 61, 61, 63, 64, 64, - 65, 65, 66, 67, 68, 66, 67, 68, 69, 69, 68, 69, 68, 71, 68, 68, - 71, 71, 68, 68, 71, 72, 71, 71, 71, 71, 72, 73, 74, 72, 73, 74, - 75, 75, 74, 72, 71, 75, 75, 74, 73, 74, 75, 77, 78, 76, 76, 75, - 75, 76, 76, 77, 78, 79, 79, 79, 79, 78, 77, 77, 77, 80, 80, 80, - 81, 81, 82, 82, 82, 80, 80, 80, 81, 81, 82, 82, 83, 87, 87, 86, - 86, 88, 88, 87, 86, 90, 84, 87, 89, 83, 86, 91, 86, 89, 89, 89, - 90, 90, 91, 91, 91, 90, 90, 91, 92, 93, 94, 94, 95, 94, 94, 94, - 94, 94, 94, 95, 95, 96, 96, 97, 97, 97, 97, 97, 97, 92, 96, 97, - 95, 95, 97, 96, 92, 96, 93, 97, 91, 98, 93, 94, 40, 8, 36, 68, - 72, 101, 100, 108, 107, 106, 96, 91, 95, 101, 103, 103, 103, 103, 102, 103, - 106, 105, 102, 104, 108, 106, 105, 104, 104, 103, 104, 104, 104, 105, 107, 105, - 101, 101, 104, 105, 103, 104, 104, 105, 105, 105, 104, 103, 102, 101, 109, 106, - 62, 61, 60, 60, 60, 61, 63, 65, 62, 61, 59, 60, 61, 62, 61, 61, - 63, 64, 65, 65, 66, 67, 68, 68, 66, 67, 68, 69, 69, 68, 69, 68, - 71, 68, 68, 71, 71, 68, 68, 71, 72, 71, 71, 71, 71, 72, 73, 74, - 69, 70, 72, 74, 75, 76, 77, 77, 74, 74, 74, 74, 75, 76, 77, 78, - 76, 76, 76, 76, 76, 77, 78, 78, 79, 79, 80, 79, 78, 77, 76, 76, - 80, 80, 80, 81, 81, 82, 82, 82, 81, 81, 82, 82, 82, 83, 83, 84, - 88, 88, 86, 87, 89, 89, 88, 87, 91, 85, 88, 90, 84, 87, 92, 87, - 89, 89, 89, 90, 90, 91, 91, 91, 91, 91, 92, 92, 93, 94, 94, 94, - 91, 92, 92, 93, 93, 92, 93, 92, 97, 97, 98, 98, 98, 98, 98, 98, - 93, 96, 97, 94, 94, 97, 96, 93, 97, 95, 98, 91, 98, 93, 93, 35, - 9, 37, 69, 72, 101, 100, 108, 107, 106, 96, 91, 95, 101, 103, 103, 103, - 103, 102, 103, 107, 106, 103, 104, 109, 107, 106, 105, 103, 102, 102, 102, 102, - 104, 107, 106, 102, 102, 105, 105, 102, 104, 105, 105, 105, 105, 104, 103, 102, - 100, 109, 108, 62, 62, 60, 59, 59, 61, 64, 65, 62, 60, 59, 60, 61, - 62, 61, 61, 63, 64, 65, 65, 66, 67, 69, 69, 67, 68, 68, 69, 69, - 68, 69, 68, 71, 68, 68, 71, 71, 68, 68, 71, 72, 71, 71, 71, 71, - 72, 73, 74, 70, 71, 71, 72, 74, 76, 78, 79, 72, 73, 74, 75, 76, - 77, 77, 77, 77, 76, 76, 76, 76, 77, 78, 79, 77, 78, 79, 79, 79, - 78, 77, 77, 80, 80, 80, 81, 81, 82, 82, 82, 82, 82, 83, 83, 84, - 84, 84, 85, 87, 87, 86, 86, 88, 89, 87, 86, 92, 86, 90, 91, 86, - 88, 93, 88, 89, 89, 89, 90, 90, 91, 91, 91, 92, 93, 93, 93, 93, - 93, 93, 93, 91, 91, 92, 93, 93, 92, 92, 92, 97, 97, 98, 98, 98, - 98, 98, 98, 94, 97, 96, 93, 93, 96, 97, 94, 97, 95, 98, 90, 98, - 94, 93, 33, 10, 38, 69, 73, 101, 100, 108, 107, 106, 96, 91, 95, 101, - 103, 103, 103, 103, 102, 103, 107, 106, 103, 105, 110, 108, 107, 106, 104, 104, - 103, 103, 103, 103, 106, 106, 103, 103, 105, 104, 101, 105, 105, 105, 104, 104, - 103, 103, 103, 102, 109, 105, 61, 61, 59, 58, 59, 61, 64, 66, 62, 60, - 59, 60, 62, 63, 61, 61, 64, 64, 65, 66, 67, 67, 69, 70, 67, 68, - 68, 69, 69, 68, 68, 68, 73, 69, 69, 72, 72, 69, 69, 72, 72, 71, - 71, 70, 70, 71, 72, 73, 75, 74, 73, 72, 72, 74, 75, 76, 71, 72, - 74, 76, 77, 77, 76, 76, 77, 76, 76, 77, 76, 78, 78, 80, 76, 77, - 79, 80, 81, 81, 80, 78, 79, 79, 79, 80, 80, 81, 81, 82, 83, 83, - 85, 85, 85, 86, 86, 86, 86, 85, 84, 85, 86, 87, 86, 85, 93, 87, - 91, 92, 86, 89, 94, 89, 89, 89, 89, 90, 90, 91, 90, 90, 93, 93, - 92, 92, 92, 93, 93, 92, 93, 93, 95, 96, 96, 95, 94, 94, 97, 97, - 98, 98, 98, 98, 97, 98, 95, 97, 96, 92, 92, 96, 97, 95, 95, 94, - 97, 89, 98, 96, 94, 33, 11, 38, 70, 73, 100, 99, 107, 106, 106, 97, - 91, 95, 101, 103, 102, 102, 103, 102, 104, 107, 106, 104, 105, 110, 108, 107, - 106, 105, 105, 105, 106, 106, 102, 106, 107, 104, 104, 106, 104, 100, 106, 105, - 104, 103, 103, 103, 104, 104, 106, 108, 101, 58, 58, 58, 59, 59, 60, 60, - 60, 61, 60, 60, 60, 60, 61, 63, 64, 64, 64, 64, 65, 65, 66, 66, - 66, 68, 68, 68, 69, 69, 70, 70, 70, 69, 70, 71, 72, 72, 72, 72, - 71, 69, 70, 72, 71, 69, 69, 71, 72, 72, 73, 73, 74, 74, 75, 75, - 75, 77, 77, 77, 76, 76, 75, 75, 75, 76, 83, 80, 78, 81, 79, 75, - 83, 78, 82, 81, 77, 77, 84, 86, 82, 78, 79, 79, 80, 80, 79, 80, - 79, 81, 90, 87, 83, 87, 84, 81, 89, 80, 85, 86, 84, 85, 89, 85, - 77, 93, 89, 89, 91, 91, 88, 88, 92, 93, 93, 91, 91, 92, 92, 90, - 90, 88, 89, 91, 91, 91, 91, 91, 92, 93, 96, 97, 97, 94, 94, 96, - 97, 95, 96, 96, 95, 94, 95, 96, 100, 92, 95, 97, 96, 93, 91, 92, - 94, 97, 89, 97, 92, 92, 89, 92, 29, 12, 43, 67, 79, 94, 103, 103, - 106, 109, 96, 92, 98, 103, 100, 99, 102, 102, 101, 101, 104, 105, 102, 102, - 106, 103, 105, 107, 106, 104, 103, 105, 107, 103, 107, 107, 104, 103, 105, 104, - 100, 106, 105, 104, 103, 103, 103, 103, 104, 102, 104, 104, 57, 57, 59, 59, - 59, 60, 60, 60, 62, 62, 62, 62, 63, 64, 66, 66, 63, 64, 65, 65, - 65, 66, 66, 66, 68, 68, 68, 69, 69, 70, 70, 70, 70, 71, 70, 71, - 71, 72, 72, 72, 69, 71, 71, 71, 69, 68, 70, 72, 72, 73, 73, 74, - 74, 75, 75, 75, 77, 77, 77, 76, 76, 75, 75, 75, 75, 82, 80, 77, - 81, 78, 75, 82, 78, 81, 81, 78, 79, 84, 85, 81, 80, 79, 79, 80, - 80, 81, 80, 81, 76, 85, 83, 82, 85, 82, 81, 88, 82, 83, 83, 81, - 82, 87, 86, 81, 89, 85, 85, 87, 86, 82, 82, 85, 91, 92, 92, 93, - 93, 91, 89, 87, 90, 90, 92, 92, 93, 94, 94, 95, 93, 94, 95, 94, - 92, 92, 93, 96, 95, 96, 96, 95, 93, 94, 96, 99, 93, 96, 98, 97, - 94, 92, 93, 94, 99, 92, 98, 92, 92, 88, 90, 26, 13, 45, 67, 78, - 94, 102, 103, 106, 108, 97, 91, 98, 102, 99, 98, 100, 102, 101, 101, 104, - 105, 102, 102, 106, 103, 105, 107, 106, 104, 103, 105, 107, 102, 106, 106, 103, - 103, 105, 105, 101, 106, 105, 104, 103, 103, 103, 103, 104, 105, 106, 106, 57, - 58, 59, 59, 60, 60, 60, 60, 63, 63, 64, 64, 64, 65, 67, 67, 63, - 65, 65, 65, 66, 66, 66, 66, 68, 68, 68, 69, 69, 70, 70, 70, 71, - 72, 70, 69, 70, 71, 73, 74, 69, 71, 71, 71, 69, 69, 70, 73, 72, - 73, 73, 74, 74, 75, 75, 75, 77, 77, 76, 76, 76, 76, 75, 75, 74, - 81, 78, 75, 79, 76, 73, 80, 76, 79, 80, 78, 80, 83, 83, 80, 84, - 84, 82, 82, 82, 83, 84, 85, 81, 88, 86, 83, 88, 86, 83, 90, 91, - 91, 89, 88, 89, 95, 95, 93, 95, 92, 91, 93, 93, 90, 91, 95, 90, - 92, 93, 93, 93, 91, 90, 88, 93, 93, 92, 92, 91, 92, 93, 93, 95, - 95, 96, 95, 95, 96, 99, 101, 96, 97, 96, 95, 93, 92, 94, 97, 94, - 97, 98, 98, 96, 94, 95, 95, 102, 94, 100, 94, 93, 88, 89, 24, 13, - 45, 67, 79, 94, 102, 103, 106, 106, 95, 90, 97, 102, 99, 97, 100, 102, - 101, 101, 104, 105, 102, 102, 106, 104, 105, 106, 106, 104, 104, 105, 106, 101, - 105, 105, 103, 103, 106, 106, 102, 106, 105, 104, 103, 103, 103, 103, 104, 107, - 107, 107, 58, 58, 59, 60, 60, 60, 61, 61, 63, 63, 64, 63, 64, 65, - 67, 67, 64, 65, 65, 66, 66, 66, 67, 67, 68, 68, 68, 69, 69, 70, - 70, 70, 72, 72, 69, 68, 69, 71, 73, 75, 70, 71, 72, 71, 69, 69, - 70, 73, 72, 73, 73, 74, 74, 75, 75, 75, 76, 76, 76, 76, 76, 76, - 76, 75, 74, 80, 77, 74, 78, 75, 72, 80, 75, 77, 79, 80, 80, 81, - 80, 80, 87, 87, 85, 83, 83, 85, 86, 88, 87, 92, 88, 85, 90, 86, - 82, 87, 83, 83, 81, 81, 84, 86, 86, 85, 87, 84, 84, 87, 88, 87, - 88, 93, 91, 93, 92, 92, 90, 89, 90, 91, 91, 90, 90, 90, 90, 91, - 92, 92, 92, 93, 94, 95, 95, 98, 101, 104, 95, 97, 97, 95, 92, 92, - 93, 96, 95, 97, 98, 98, 97, 97, 96, 96, 101, 94, 100, 94, 93, 89, - 90, 24, 14, 46, 68, 79, 94, 102, 103, 106, 105, 94, 89, 97, 101, 98, - 97, 100, 102, 101, 101, 104, 105, 102, 102, 106, 105, 105, 105, 105, 105, 105, - 105, 105, 100, 104, 105, 103, 104, 107, 107, 103, 106, 105, 104, 103, 103, 103, - 103, 104, 107, 107, 106, 58, 58, 60, 60, 60, 61, 61, 61, 62, 62, 63, - 63, 63, 64, 66, 66, 64, 64, 65, 65, 65, 66, 66, 66, 67, 67, 67, - 68, 68, 69, 69, 70, 72, 71, 69, 68, 69, 71, 73, 75, 70, 72, 72, - 72, 71, 70, 72, 73, 72, 73, 73, 74, 74, 75, 75, 75, 76, 76, 76, - 76, 76, 76, 76, 75, 73, 79, 76, 73, 77, 74, 71, 79, 76, 77, 78, - 81, 82, 80, 79, 81, 90, 90, 88, 85, 84, 86, 87, 88, 85, 88, 84, - 82, 87, 84, 79, 83, 81, 81, 81, 84, 86, 85, 81, 80, 84, 80, 78, - 81, 81, 78, 77, 81, 81, 81, 79, 77, 74, 75, 79, 82, 77, 79, 79, - 82, 85, 87, 88, 90, 89, 91, 92, 92, 92, 93, 97, 100, 95, 96, 97, - 96, 94, 92, 91, 94, 96, 97, 97, 98, 98, 98, 97, 96, 98, 91, 99, - 94, 94, 90, 90, 25, 15, 47, 69, 80, 95, 102, 103, 106, 105, 94, 89, - 96, 101, 99, 97, 100, 102, 101, 101, 104, 105, 102, 102, 106, 105, 105, 105, - 105, 105, 105, 105, 105, 100, 104, 105, 103, 104, 107, 107, 103, 106, 105, 104, - 103, 103, 103, 103, 104, 105, 105, 105, 59, 59, 60, 60, 61, 61, 61, 62, - 62, 62, 62, 62, 63, 64, 66, 66, 65, 65, 65, 65, 66, 66, 66, 67, - 67, 67, 67, 68, 68, 69, 69, 70, 71, 71, 70, 69, 70, 71, 73, 74, - 70, 72, 72, 72, 71, 71, 72, 75, 73, 73, 73, 74, 74, 75, 75, 75, - 75, 75, 76, 76, 76, 76, 77, 76, 74, 81, 77, 74, 78, 75, 72, 79, - 80, 78, 78, 82, 82, 79, 78, 82, 89, 89, 87, 86, 85, 84, 85, 85, - 82, 85, 79, 76, 83, 82, 76, 78, 73, 69, 71, 76, 76, 72, 69, 67, - 69, 64, 62, 63, 60, 55, 54, 57, 52, 53, 51, 48, 44, 45, 49, 55, - 48, 50, 54, 59, 64, 68, 70, 72, 85, 88, 91, 91, 90, 91, 93, 96, - 94, 96, 97, 97, 94, 93, 92, 94, 96, 96, 96, 97, 99, 99, 98, 96, - 96, 90, 98, 94, 94, 89, 89, 24, 16, 48, 70, 80, 95, 102, 103, 106, - 105, 94, 89, 97, 102, 100, 98, 102, 102, 101, 101, 104, 105, 102, 102, 106, - 106, 105, 104, 104, 106, 106, 105, 104, 101, 105, 105, 103, 103, 106, 106, 102, - 106, 105, 104, 103, 103, 103, 103, 104, 105, 104, 104, 59, 59, 60, 61, 61, - 61, 62, 62, 63, 63, 64, 64, 64, 65, 67, 68, 65, 65, 65, 66, 66, - 66, 67, 67, 67, 67, 67, 68, 68, 69, 69, 70, 70, 70, 70, 71, 71, - 72, 71, 71, 71, 72, 74, 73, 72, 72, 73, 75, 73, 73, 73, 74, 74, - 75, 75, 75, 75, 75, 75, 76, 76, 77, 77, 77, 75, 83, 79, 76, 80, - 77, 74, 81, 83, 78, 78, 81, 81, 78, 78, 84, 84, 85, 84, 83, 83, - 81, 79, 78, 78, 79, 70, 65, 71, 67, 59, 59, 40, 33, 32, 37, 37, - 32, 28, 30, 33, 28, 26, 28, 25, 22, 20, 23, 22, 25, 28, 27, 23, - 21, 24, 27, 22, 26, 31, 35, 39, 40, 40, 41, 64, 71, 77, 83, 86, - 89, 93, 96, 93, 97, 98, 99, 97, 94, 94, 95, 95, 95, 94, 96, 99, - 99, 98, 95, 96, 90, 98, 93, 93, 87, 86, 20, 17, 48, 70, 81, 95, - 103, 102, 106, 105, 95, 90, 98, 103, 101, 100, 103, 102, 101, 101, 104, 105, - 102, 102, 106, 107, 105, 103, 104, 106, 107, 105, 103, 102, 106, 106, 103, 103, - 105, 105, 101, 106, 105, 104, 103, 103, 103, 103, 104, 106, 105, 104, 59, 59, - 60, 61, 61, 62, 62, 62, 65, 65, 65, 65, 65, 66, 68, 69, 65, 65, - 65, 66, 66, 67, 67, 67, 67, 67, 67, 68, 68, 69, 69, 69, 68, 70, - 71, 72, 72, 72, 71, 70, 71, 72, 74, 74, 72, 72, 74, 75, 73, 73, - 73, 74, 74, 75, 75, 75, 75, 75, 75, 76, 76, 77, 77, 78, 77, 85, - 82, 78, 82, 79, 76, 82, 86, 80, 78, 82, 81, 78, 79, 85, 79, 79, - 78, 78, 77, 75, 73, 71, 66, 66, 54, 47, 48, 42, 32, 28, 30, 19, - 16, 20, 19, 14, 13, 16, 23, 19, 18, 22, 23, 20, 22, 24, 13, 18, - 24, 25, 21, 17, 17, 19, 18, 20, 24, 25, 26, 23, 19, 19, 33, 43, - 54, 64, 73, 80, 86, 91, 90, 95, 98, 99, 97, 96, 96, 97, 96, 94, - 93, 95, 98, 99, 97, 94, 98, 91, 99, 93, 91, 85, 83, 17, 17, 49, - 70, 81, 95, 103, 102, 106, 106, 95, 90, 98, 104, 102, 101, 104, 102, 101, - 101, 104, 105, 102, 102, 106, 107, 105, 103, 104, 106, 107, 105, 103, 103, 107, - 107, 104, 103, 105, 104, 100, 106, 105, 104, 103, 103, 103, 103, 104, 108, 107, - 105, 60, 62, 64, 63, 61, 60, 61, 63, 61, 62, 65, 67, 67, 67, 67, - 66, 64, 63, 61, 61, 62, 64, 67, 69, 70, 69, 68, 66, 66, 67, 68, - 69, 73, 71, 69, 70, 74, 75, 73, 71, 71, 72, 75, 75, 73, 73, 75, - 76, 76, 77, 77, 78, 78, 77, 77, 76, 72, 75, 78, 78, 75, 74, 75, - 79, 84, 84, 84, 83, 83, 83, 84, 84, 77, 80, 82, 81, 76, 74, 75, - 75, 70, 64, 67, 67, 56, 54, 56, 49, 33, 31, 23, 21, 25, 19, 15, - 21, 19, 12, 16, 16, 11, 17, 21, 10, 25, 21, 19, 21, 19, 15, 15, - 17, 8, 18, 16, 23, 16, 6, 22, 27, 28, 22, 28, 10, 25, 14, 20, - 11, 19, 29, 32, 30, 42, 67, 86, 91, 90, 99, 96, 93, 97, 97, 97, - 104, 96, 95, 96, 97, 97, 98, 99, 99, 99, 93, 99, 91, 92, 91, 90, - 21, 16, 54, 67, 84, 99, 99, 107, 104, 107, 90, 89, 101, 101, 102, 105, - 102, 101, 105, 98, 107, 107, 98, 105, 102, 104, 104, 105, 105, 105, 104, 103, - 103, 104, 105, 105, 106, 106, 105, 105, 104, 106, 105, 105, 104, 104, 105, 105, - 106, 101, 103, 104, 57, 59, 61, 60, 58, 58, 59, 60, 63, 64, 65, 65, - 65, 64, 65, 64, 66, 65, 64, 64, 65, 67, 69, 70, 69, 68, 68, 67, - 67, 68, 68, 69, 73, 71, 69, 71, 73, 75, 73, 71, 71, 72, 75, 75, - 73, 73, 75, 76, 76, 76, 77, 77, 77, 77, 76, 76, 78, 80, 81, 80, - 77, 76, 77, 80, 82, 84, 83, 82, 82, 81, 80, 79, 75, 76, 79, 79, - 78, 76, 74, 71, 65, 50, 44, 39, 26, 26, 29, 22, 18, 21, 19, 19, - 24, 19, 17, 26, 18, 14, 17, 17, 11, 17, 19, 10, 27, 22, 21, 23, - 21, 18, 18, 20, 10, 15, 6, 15, 14, 6, 18, 18, 13, 11, 19, 5, - 18, 12, 19, 14, 16, 19, 21, 25, 31, 40, 58, 74, 92, 96, 92, 92, - 103, 105, 100, 102, 99, 97, 97, 97, 97, 97, 97, 97, 100, 95, 101, 93, - 92, 89, 87, 17, 17, 54, 68, 84, 99, 99, 107, 104, 107, 90, 90, 101, - 101, 102, 105, 102, 101, 105, 98, 107, 107, 98, 105, 102, 103, 104, 104, 105, - 105, 104, 104, 103, 104, 105, 105, 106, 106, 105, 105, 104, 106, 105, 105, 104, - 104, 105, 105, 106, 102, 104, 105, 57, 58, 60, 60, 58, 58, 59, 61, 65, - 64, 64, 63, 62, 62, 63, 63, 65, 65, 65, 66, 67, 68, 68, 69, 67, - 68, 68, 69, 69, 68, 68, 68, 71, 70, 69, 70, 72, 73, 73, 72, 72, - 73, 75, 75, 73, 73, 75, 76, 75, 75, 76, 76, 76, 76, 75, 75, 81, - 81, 81, 80, 77, 77, 78, 80, 79, 81, 82, 82, 81, 80, 78, 77, 79, - 76, 73, 71, 67, 62, 55, 46, 44, 27, 22, 21, 13, 17, 21, 14, 7, - 14, 14, 17, 22, 16, 15, 26, 18, 15, 19, 18, 12, 17, 20, 11, 21, - 16, 16, 18, 18, 14, 15, 18, 16, 13, 0, 10, 13, 7, 15, 12, 6, - 8, 15, 5, 14, 11, 19, 16, 18, 13, 14, 23, 22, 19, 31, 52, 76, - 87, 90, 92, 101, 101, 98, 105, 101, 99, 99, 98, 97, 96, 96, 95, 100, - 96, 103, 95, 93, 89, 84, 12, 18, 55, 68, 84, 98, 99, 107, 104, 106, - 91, 91, 102, 101, 101, 104, 101, 101, 105, 98, 107, 107, 98, 105, 102, 103, - 103, 104, 105, 105, 104, 104, 103, 104, 105, 105, 106, 106, 105, 105, 104, 106, - 105, 105, 104, 104, 105, 105, 106, 103, 105, 106, 60, 61, 64, 63, 62, 62, - 63, 65, 64, 63, 62, 61, 61, 62, 64, 65, 62, 63, 64, 65, 66, 66, - 65, 65, 66, 67, 68, 70, 70, 69, 68, 67, 70, 70, 70, 71, 71, 72, - 73, 73, 72, 73, 75, 75, 73, 73, 75, 76, 74, 75, 75, 76, 76, 75, - 75, 74, 78, 78, 77, 76, 76, 76, 77, 78, 79, 78, 79, 80, 78, 76, - 73, 72, 69, 62, 54, 49, 45, 40, 34, 24, 22, 10, 13, 19, 19, 22, - 21, 10, 9, 11, 7, 8, 15, 11, 6, 16, 15, 14, 18, 17, 9, 12, - 17, 9, 12, 9, 7, 10, 9, 7, 8, 11, 15, 13, 0, 7, 11, 4, - 13, 8, 8, 12, 15, 9, 9, 10, 15, 14, 20, 14, 14, 19, 19, 18, - 23, 33, 43, 67, 84, 88, 91, 88, 92, 108, 99, 99, 98, 98, 98, 97, - 97, 97, 98, 95, 103, 96, 95, 89, 83, 10, 19, 56, 68, 84, 98, 99, - 107, 105, 106, 91, 92, 103, 101, 100, 103, 101, 101, 105, 98, 107, 107, 98, - 105, 102, 102, 103, 104, 105, 105, 105, 104, 104, 104, 105, 105, 106, 106, 105, - 105, 104, 106, 105, 105, 104, 104, 105, 105, 106, 104, 106, 106, 60, 62, 65, - 64, 63, 63, 65, 66, 61, 60, 61, 61, 62, 64, 67, 68, 63, 64, 65, - 66, 66, 66, 65, 65, 65, 66, 68, 69, 70, 69, 68, 68, 69, 69, 70, - 70, 71, 71, 73, 73, 72, 73, 75, 75, 73, 73, 76, 76, 74, 75, 75, - 76, 76, 75, 75, 74, 76, 76, 75, 76, 77, 78, 78, 76, 77, 74, 72, - 68, 65, 60, 56, 53, 43, 35, 27, 24, 25, 26, 25, 21, 22, 11, 13, - 18, 15, 17, 14, 2, 15, 10, 0, 1, 11, 10, 5, 11, 14, 14, 19, - 17, 8, 11, 16, 10, 12, 9, 9, 11, 12, 9, 10, 13, 12, 14, 3, - 10, 9, 0, 11, 10, 11, 18, 17, 15, 10, 14, 15, 16, 17, 19, 16, - 13, 18, 27, 27, 21, 22, 45, 61, 73, 84, 87, 90, 102, 96, 97, 98, - 98, 98, 99, 99, 99, 96, 93, 102, 96, 95, 89, 83, 10, 21, 57, 69, - 84, 98, 99, 108, 105, 105, 92, 94, 104, 101, 99, 102, 101, 101, 105, 98, - 107, 107, 98, 105, 102, 102, 103, 104, 105, 105, 105, 105, 105, 104, 105, 105, - 106, 106, 105, 105, 104, 106, 105, 105, 104, 104, 105, 105, 106, 104, 106, 106, - 58, 59, 62, 62, 61, 61, 63, 65, 59, 59, 61, 62, 64, 66, 68, 69, - 68, 68, 68, 68, 68, 68, 68, 68, 65, 66, 67, 68, 69, 69, 69, 69, - 68, 69, 71, 71, 70, 70, 73, 74, 72, 73, 75, 75, 73, 73, 76, 77, - 75, 75, 76, 76, 76, 76, 75, 75, 77, 77, 77, 78, 80, 80, 79, 74, - 69, 63, 58, 52, 45, 39, 34, 31, 29, 24, 17, 13, 13, 16, 16, 16, - 27, 15, 14, 14, 11, 15, 19, 12, 17, 12, 0, 0, 12, 14, 9, 17, - 13, 15, 21, 19, 9, 13, 19, 14, 15, 12, 11, 13, 13, 10, 11, 13, - 10, 16, 9, 16, 11, 0, 12, 13, 11, 18, 14, 19, 10, 22, 19, 20, - 14, 20, 18, 12, 17, 29, 27, 17, 23, 30, 33, 49, 79, 92, 89, 91, - 94, 97, 97, 98, 99, 100, 100, 101, 96, 93, 102, 95, 94, 89, 83, 10, - 22, 58, 69, 84, 97, 99, 108, 106, 104, 92, 95, 106, 101, 98, 101, 100, - 101, 105, 98, 107, 107, 98, 105, 102, 101, 102, 103, 104, 105, 105, 105, 105, - 104, 105, 105, 106, 106, 105, 105, 104, 106, 105, 105, 104, 104, 105, 105, 106, - 103, 105, 106, 55, 57, 60, 60, 59, 60, 61, 63, 60, 61, 63, 65, 66, - 66, 67, 67, 70, 69, 67, 67, 66, 67, 68, 69, 66, 66, 66, 67, 68, - 69, 70, 71, 67, 70, 71, 71, 70, 70, 72, 75, 72, 73, 75, 75, 73, - 73, 76, 77, 76, 76, 77, 77, 77, 77, 76, 76, 78, 77, 77, 79, 80, - 79, 74, 66, 52, 45, 38, 32, 26, 23, 20, 18, 20, 19, 16, 12, 9, - 9, 10, 10, 20, 14, 16, 18, 14, 20, 27, 23, 13, 14, 9, 8, 15, - 12, 11, 22, 11, 13, 20, 18, 8, 12, 19, 14, 16, 13, 12, 13, 13, - 10, 11, 14, 12, 18, 13, 22, 17, 6, 15, 15, 12, 18, 10, 18, 10, - 25, 18, 19, 17, 21, 23, 20, 19, 19, 21, 24, 26, 26, 21, 32, 62, - 78, 82, 89, 95, 99, 99, 99, 99, 99, 99, 99, 99, 95, 103, 94, 93, - 87, 81, 8, 23, 59, 70, 84, 97, 99, 108, 106, 103, 92, 96, 106, 101, - 98, 101, 100, 101, 105, 98, 107, 107, 98, 105, 102, 101, 102, 103, 104, 105, - 106, 106, 105, 104, 105, 105, 106, 106, 105, 105, 104, 106, 105, 105, 104, 104, - 105, 105, 106, 102, 103, 104, 56, 58, 60, 60, 60, 60, 62, 64, 62, 64, - 65, 67, 67, 67, 66, 65, 69, 67, 65, 63, 63, 65, 67, 68, 67, 67, - 66, 65, 66, 68, 70, 71, 68, 70, 72, 71, 69, 69, 71, 74, 71, 72, - 75, 75, 73, 74, 76, 77, 75, 75, 76, 77, 78, 77, 78, 77, 78, 78, - 75, 76, 75, 69, 62, 52, 33, 26, 22, 18, 15, 17, 17, 17, 3, 7, - 11, 14, 12, 12, 14, 17, 11, 11, 19, 23, 16, 16, 17, 11, 7, 15, - 15, 13, 13, 5, 5, 20, 10, 10, 18, 16, 7, 11, 19, 14, 23, 19, - 17, 19, 18, 14, 14, 17, 15, 20, 14, 25, 23, 13, 19, 16, 15, 19, - 7, 17, 8, 26, 14, 16, 20, 20, 27, 30, 21, 9, 15, 31, 21, 28, - 24, 23, 36, 50, 66, 90, 95, 99, 99, 98, 99, 98, 97, 97, 103, 98, - 104, 94, 90, 84, 78, 5, 24, 60, 70, 84, 97, 99, 107, 105, 103, 92, - 97, 107, 101, 97, 100, 100, 101, 105, 98, 107, 107, 98, 105, 102, 101, 102, - 102, 103, 104, 105, 105, 105, 104, 105, 105, 106, 106, 105, 105, 104, 106, 105, - 105, 104, 104, 105, 105, 106, 101, 103, 103, 61, 61, 61, 61, 62, 63, 64, - 65, 65, 65, 65, 65, 64, 66, 70, 74, 68, 68, 68, 69, 69, 70, 70, - 69, 65, 66, 67, 67, 68, 69, 69, 70, 72, 72, 73, 72, 73, 71, 70, - 70, 75, 74, 73, 73, 73, 75, 76, 76, 69, 70, 71, 73, 75, 77, 78, - 78, 88, 74, 74, 81, 68, 51, 38, 23, 22, 15, 12, 13, 14, 12, 8, - 3, 5, 7, 13, 15, 13, 17, 22, 26, 16, 14, 18, 38, 10, 21, 21, - 21, 12, 22, 8, 13, 17, 7, 14, 19, 10, 22, 25, 15, 12, 19, 20, - 12, 26, 21, 24, 23, 13, 12, 16, 11, 19, 26, 22, 19, 23, 19, 15, - 22, 25, 21, 17, 16, 18, 22, 22, 22, 10, 19, 23, 17, 13, 14, 16, - 16, 13, 18, 24, 25, 22, 27, 47, 73, 95, 90, 86, 94, 102, 102, 99, - 98, 101, 98, 96, 96, 83, 89, 75, 6, 27, 62, 71, 84, 98, 99, 106, - 101, 103, 83, 96, 102, 102, 107, 100, 104, 101, 98, 105, 107, 99, 101, 106, - 102, 104, 104, 105, 105, 105, 104, 103, 103, 103, 104, 104, 104, 104, 103, 102, - 101, 105, 105, 105, 104, 104, 103, 103, 103, 101, 101, 102, 61, 61, 60, 59, - 59, 59, 61, 61, 65, 65, 67, 66, 65, 66, 70, 72, 68, 69, 69, 70, - 69, 70, 70, 70, 66, 66, 67, 68, 68, 68, 69, 69, 72, 72, 72, 72, - 71, 70, 70, 71, 73, 74, 74, 74, 74, 77, 77, 76, 74, 73, 75, 75, - 77, 79, 80, 81, 81, 75, 76, 72, 52, 36, 27, 16, 15, 11, 9, 9, - 12, 12, 11, 8, 10, 10, 12, 15, 18, 20, 21, 19, 18, 12, 20, 22, - 17, 13, 23, 25, 14, 23, 10, 16, 19, 6, 11, 16, 9, 17, 21, 18, - 19, 26, 27, 23, 21, 17, 21, 22, 13, 15, 20, 17, 21, 28, 24, 21, - 25, 21, 17, 23, 21, 17, 13, 15, 18, 20, 16, 12, 21, 24, 22, 19, - 18, 21, 18, 12, 12, 16, 21, 23, 20, 21, 32, 54, 80, 93, 97, 93, - 96, 103, 105, 101, 101, 100, 97, 99, 86, 89, 74, 5, 27, 62, 70, 85, - 98, 100, 106, 102, 104, 85, 97, 103, 102, 106, 98, 101, 101, 99, 105, 107, - 99, 101, 106, 102, 101, 102, 102, 103, 103, 102, 101, 101, 104, 105, 105, 105, - 105, 104, 103, 102, 105, 105, 105, 104, 104, 103, 103, 103, 101, 101, 102, 63, - 62, 61, 60, 59, 59, 60, 60, 65, 66, 68, 68, 66, 66, 68, 70, 68, - 69, 68, 69, 69, 70, 70, 70, 67, 67, 67, 68, 68, 68, 69, 69, 72, - 72, 70, 69, 69, 70, 72, 73, 72, 74, 75, 77, 77, 78, 77, 76, 78, - 77, 76, 76, 77, 78, 79, 81, 77, 75, 76, 61, 34, 25, 23, 15, 14, - 9, 8, 9, 11, 14, 15, 15, 15, 13, 12, 15, 20, 21, 16, 12, 17, - 13, 20, 6, 25, 9, 23, 30, 13, 24, 12, 19, 22, 10, 13, 17, 10, - 11, 14, 18, 24, 28, 28, 27, 21, 17, 20, 22, 15, 17, 22, 19, 21, - 28, 24, 20, 24, 20, 16, 23, 17, 15, 13, 16, 20, 19, 14, 8, 29, - 26, 20, 18, 22, 24, 17, 8, 14, 15, 19, 22, 21, 19, 23, 36, 56, - 85, 96, 88, 85, 96, 102, 97, 101, 100, 99, 101, 88, 92, 75, 4, 26, - 62, 70, 85, 99, 101, 107, 103, 105, 86, 98, 103, 102, 105, 97, 100, 102, - 99, 105, 108, 101, 102, 106, 102, 101, 101, 102, 103, 103, 102, 102, 101, 105, - 106, 106, 106, 106, 105, 104, 103, 105, 105, 105, 104, 104, 103, 103, 103, 101, - 101, 102, 64, 64, 63, 62, 62, 62, 64, 64, 64, 66, 69, 69, 67, 66, - 67, 68, 68, 69, 68, 69, 69, 70, 70, 70, 67, 68, 68, 69, 68, 69, - 69, 69, 72, 72, 69, 69, 68, 70, 72, 75, 72, 73, 76, 78, 79, 79, - 78, 76, 77, 76, 74, 74, 74, 76, 78, 79, 78, 75, 69, 46, 20, 19, - 23, 14, 12, 9, 8, 8, 11, 13, 16, 17, 14, 13, 13, 15, 19, 17, - 13, 8, 15, 18, 15, 5, 24, 12, 15, 30, 12, 23, 13, 21, 26, 13, - 17, 20, 16, 11, 10, 18, 23, 23, 21, 23, 24, 19, 22, 22, 14, 16, - 21, 17, 18, 25, 21, 17, 20, 16, 12, 19, 15, 16, 18, 19, 20, 19, - 18, 18, 27, 22, 17, 16, 19, 21, 15, 8, 17, 15, 16, 21, 22, 19, - 19, 25, 37, 66, 84, 84, 84, 91, 98, 97, 101, 101, 101, 103, 90, 92, - 75, 3, 26, 62, 70, 86, 99, 101, 108, 104, 105, 85, 98, 103, 102, 105, - 98, 101, 103, 100, 106, 108, 101, 102, 106, 101, 103, 103, 104, 105, 105, 105, - 104, 104, 105, 105, 106, 106, 105, 104, 103, 103, 105, 105, 105, 104, 104, 103, - 103, 103, 102, 102, 102, 62, 62, 62, 62, 63, 64, 67, 68, 64, 66, 69, - 69, 67, 66, 67, 68, 68, 68, 68, 69, 69, 70, 70, 70, 68, 69, 69, - 69, 69, 70, 69, 69, 72, 73, 70, 69, 70, 72, 74, 76, 72, 74, 76, - 79, 79, 80, 79, 77, 75, 75, 74, 74, 74, 76, 77, 77, 78, 66, 52, - 30, 10, 16, 20, 12, 12, 11, 10, 8, 9, 10, 13, 15, 7, 11, 15, - 16, 15, 12, 11, 12, 13, 25, 11, 15, 16, 18, 6, 24, 15, 27, 15, - 23, 26, 14, 17, 20, 20, 13, 12, 17, 21, 20, 18, 19, 24, 18, 21, - 21, 13, 14, 21, 19, 16, 23, 19, 16, 19, 15, 11, 17, 10, 16, 21, - 20, 16, 16, 21, 27, 21, 20, 18, 18, 17, 15, 14, 16, 21, 16, 14, - 19, 22, 21, 20, 23, 30, 45, 63, 81, 90, 91, 95, 99, 100, 101, 101, - 104, 91, 93, 75, 2, 28, 63, 71, 86, 100, 101, 108, 104, 102, 83, 96, - 102, 102, 106, 100, 103, 104, 101, 107, 109, 101, 102, 106, 101, 102, 103, 104, - 105, 105, 105, 105, 105, 104, 104, 104, 104, 104, 103, 102, 101, 105, 105, 105, - 104, 104, 103, 103, 103, 102, 102, 103, 58, 58, 59, 60, 61, 63, 66, 67, - 65, 66, 68, 68, 66, 66, 68, 70, 68, 68, 68, 69, 69, 70, 70, 70, - 69, 69, 69, 70, 70, 70, 69, 70, 74, 73, 71, 72, 73, 75, 75, 77, - 74, 76, 77, 78, 79, 80, 79, 79, 77, 76, 77, 77, 77, 76, 74, 74, - 68, 49, 34, 19, 8, 12, 15, 7, 11, 11, 10, 10, 9, 9, 11, 13, - 6, 11, 16, 17, 13, 11, 12, 15, 14, 21, 8, 23, 12, 20, 4, 17, - 21, 30, 18, 23, 26, 12, 15, 18, 18, 17, 16, 17, 19, 21, 21, 20, - 20, 15, 18, 19, 12, 16, 23, 22, 16, 23, 20, 16, 20, 17, 13, 20, - 7, 14, 20, 18, 13, 13, 20, 28, 18, 20, 22, 23, 18, 13, 17, 25, - 23, 18, 15, 18, 22, 21, 21, 25, 24, 25, 39, 63, 81, 86, 90, 96, - 99, 100, 100, 102, 90, 93, 75, 4, 30, 64, 72, 87, 100, 101, 107, 103, - 101, 83, 96, 102, 103, 107, 101, 104, 105, 102, 107, 109, 102, 102, 106, 101, - 99, 100, 101, 102, 103, 103, 103, 103, 103, 103, 104, 104, 103, 103, 102, 101, - 105, 105, 105, 104, 104, 103, 103, 103, 103, 103, 103, 60, 60, 60, 60, 61, - 63, 65, 66, 65, 65, 67, 66, 65, 66, 70, 72, 68, 68, 68, 69, 69, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 73, 74, 74, 75, 77, - 78, 77, 79, 76, 76, 76, 77, 78, 80, 80, 82, 77, 79, 79, 78, 75, - 71, 66, 63, 53, 33, 24, 20, 12, 10, 10, 6, 9, 11, 13, 13, 11, - 10, 12, 14, 14, 14, 16, 15, 15, 14, 14, 14, 17, 10, 11, 19, 12, - 14, 14, 14, 18, 27, 15, 21, 25, 13, 18, 22, 16, 22, 21, 14, 13, - 19, 21, 17, 20, 14, 18, 18, 10, 14, 22, 20, 14, 21, 18, 15, 20, - 17, 14, 21, 11, 14, 17, 18, 17, 16, 17, 18, 21, 20, 22, 25, 19, - 15, 19, 28, 22, 17, 16, 21, 23, 20, 19, 22, 17, 18, 24, 38, 60, - 78, 88, 91, 98, 99, 98, 100, 87, 90, 75, 5, 32, 66, 74, 87, 100, - 100, 106, 102, 103, 84, 97, 103, 102, 106, 99, 102, 106, 102, 108, 110, 102, - 102, 107, 102, 99, 100, 101, 102, 103, 103, 103, 103, 104, 104, 105, 105, 104, - 103, 103, 102, 105, 105, 105, 104, 104, 103, 103, 103, 103, 103, 103, 64, 64, - 63, 63, 63, 64, 66, 67, 65, 65, 66, 65, 64, 66, 71, 74, 68, 68, - 68, 69, 69, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 73, 75, - 75, 77, 79, 79, 79, 79, 77, 77, 76, 76, 77, 79, 80, 82, 76, 77, - 76, 75, 70, 64, 57, 52, 41, 23, 21, 26, 18, 9, 8, 7, 5, 10, - 14, 15, 12, 12, 15, 17, 21, 18, 14, 15, 18, 18, 16, 12, 20, 0, - 16, 13, 16, 8, 25, 14, 12, 22, 11, 19, 25, 16, 25, 30, 13, 24, - 23, 11, 6, 14, 17, 11, 24, 18, 19, 18, 8, 11, 18, 15, 11, 18, - 14, 13, 17, 16, 13, 21, 16, 16, 16, 21, 23, 23, 15, 10, 23, 19, - 21, 23, 19, 14, 17, 26, 21, 19, 19, 23, 22, 19, 16, 17, 17, 24, - 23, 24, 43, 75, 91, 88, 95, 97, 95, 98, 85, 90, 75, 6, 33, 67, - 74, 88, 100, 100, 105, 101, 105, 86, 98, 103, 102, 105, 97, 100, 106, 103, - 108, 110, 102, 102, 107, 102, 101, 102, 103, 104, 105, 106, 106, 106, 105, 106, - 106, 106, 106, 105, 104, 103, 105, 105, 105, 104, 104, 103, 103, 103, 103, 103, - 103, 58, 63, 64, 61, 60, 63, 65, 64, 66, 66, 67, 68, 68, 69, 70, - 70, 71, 70, 69, 68, 68, 68, 68, 68, 64, 69, 72, 72, 73, 75, 74, - 70, 74, 72, 72, 75, 77, 74, 75, 79, 77, 75, 74, 74, 75, 76, 75, - 74, 79, 80, 75, 65, 65, 63, 48, 28, 26, 23, 19, 15, 11, 9, 9, - 8, 12, 10, 8, 8, 10, 12, 12, 12, 15, 21, 22, 16, 13, 14, 13, - 9, 25, 16, 10, 12, 16, 16, 14, 14, 16, 16, 17, 19, 19, 18, 22, - 28, 26, 20, 24, 24, 13, 11, 16, 14, 21, 17, 17, 20, 17, 13, 15, - 21, 15, 20, 20, 14, 11, 14, 20, 22, 14, 19, 21, 20, 21, 24, 23, - 20, 24, 27, 15, 24, 28, 25, 30, 21, 15, 24, 22, 18, 19, 15, 12, - 19, 14, 14, 14, 19, 32, 50, 71, 85, 95, 92, 90, 108, 84, 91, 64, - 6, 34, 65, 73, 89, 101, 98, 104, 102, 102, 88, 101, 103, 101, 107, 101, - 102, 104, 106, 108, 107, 104, 102, 102, 103, 107, 107, 105, 104, 104, 103, 102, - 102, 105, 105, 105, 104, 104, 103, 103, 103, 104, 104, 104, 104, 104, 104, 104, - 104, 106, 105, 105, 58, 63, 64, 61, 60, 63, 65, 64, 66, 66, 67, 68, - 68, 69, 70, 70, 68, 68, 68, 68, 68, 69, 70, 70, 66, 70, 72, 71, - 71, 74, 74, 70, 74, 72, 72, 75, 77, 74, 76, 79, 74, 75, 76, 77, - 79, 78, 77, 76, 71, 73, 73, 66, 58, 45, 30, 15, 22, 19, 16, 12, - 10, 8, 5, 6, 10, 10, 9, 9, 9, 10, 12, 13, 6, 13, 15, 13, - 12, 16, 16, 13, 20, 13, 9, 13, 15, 13, 12, 14, 21, 18, 17, 21, - 21, 20, 22, 28, 25, 21, 27, 29, 19, 16, 17, 13, 18, 16, 17, 21, - 20, 15, 15, 20, 15, 18, 18, 16, 18, 22, 22, 19, 19, 22, 23, 21, - 21, 24, 23, 20, 26, 28, 16, 23, 27, 23, 29, 19, 26, 30, 24, 21, - 26, 22, 17, 20, 6, 10, 15, 18, 24, 36, 54, 69, 94, 92, 89, 104, - 84, 97, 67, 9, 34, 65, 73, 90, 102, 99, 103, 102, 101, 87, 101, 103, - 101, 107, 101, 103, 103, 105, 107, 107, 104, 103, 103, 104, 105, 105, 104, 104, - 104, 104, 104, 104, 105, 105, 105, 104, 104, 103, 103, 103, 104, 104, 104, 104, - 104, 104, 104, 104, 105, 105, 104, 59, 63, 65, 61, 60, 63, 66, 64, 66, - 66, 67, 68, 68, 69, 70, 70, 66, 66, 66, 67, 68, 69, 71, 72, 68, - 71, 71, 69, 70, 74, 74, 71, 73, 71, 71, 76, 77, 74, 75, 78, 72, - 75, 78, 79, 77, 76, 75, 74, 70, 66, 64, 57, 41, 23, 13, 10, 18, - 16, 13, 11, 9, 7, 5, 4, 7, 10, 12, 11, 8, 8, 13, 16, 4, - 10, 14, 14, 14, 17, 19, 17, 15, 11, 11, 15, 15, 12, 12, 16, 21, - 16, 14, 17, 19, 18, 17, 21, 22, 21, 30, 34, 25, 22, 21, 12, 13, - 15, 17, 22, 21, 17, 15, 18, 15, 16, 15, 16, 22, 27, 24, 17, 21, - 24, 23, 19, 19, 22, 23, 20, 25, 28, 16, 23, 25, 20, 25, 16, 26, - 28, 19, 17, 25, 23, 14, 15, 3, 11, 17, 20, 19, 24, 39, 52, 83, - 87, 87, 96, 82, 101, 64, 8, 34, 66, 74, 91, 103, 99, 103, 101, 100, - 85, 100, 102, 101, 107, 102, 104, 101, 104, 106, 106, 105, 104, 104, 105, 103, - 103, 104, 105, 105, 106, 106, 106, 105, 105, 104, 104, 104, 104, 103, 103, 104, - 104, 104, 104, 104, 104, 104, 104, 103, 103, 104, 59, 64, 65, 62, 61, 63, - 66, 64, 66, 66, 67, 68, 68, 69, 70, 70, 67, 66, 66, 67, 68, 69, - 70, 71, 69, 72, 71, 68, 69, 73, 74, 72, 73, 70, 71, 76, 76, 75, - 75, 78, 74, 76, 77, 76, 73, 71, 70, 70, 78, 62, 46, 37, 22, 9, - 8, 17, 14, 13, 12, 10, 9, 7, 6, 5, 5, 10, 14, 13, 8, 8, - 13, 18, 12, 15, 18, 18, 17, 18, 17, 17, 14, 14, 15, 19, 18, 15, - 15, 20, 23, 18, 15, 17, 18, 17, 16, 18, 20, 19, 28, 31, 25, 27, - 26, 17, 14, 15, 18, 19, 19, 18, 18, 20, 17, 19, 19, 18, 21, 26, - 24, 20, 21, 23, 22, 18, 18, 22, 23, 21, 22, 26, 16, 22, 24, 19, - 26, 18, 20, 22, 15, 13, 19, 18, 13, 15, 10, 14, 18, 20, 19, 22, - 30, 40, 62, 76, 86, 90, 77, 99, 55, 7, 34, 66, 75, 92, 104, 99, - 103, 100, 98, 84, 99, 102, 101, 108, 102, 104, 100, 104, 106, 106, 105, 105, - 105, 106, 104, 104, 104, 105, 105, 106, 105, 105, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 102, 103, 103, 60, 64, 66, - 62, 61, 64, 66, 65, 66, 66, 67, 68, 68, 69, 70, 70, 69, 68, 68, - 67, 67, 68, 68, 69, 70, 72, 73, 69, 70, 74, 74, 71, 73, 71, 71, - 76, 76, 74, 75, 78, 76, 76, 74, 74, 71, 70, 71, 71, 74, 53, 33, - 23, 14, 8, 11, 19, 11, 11, 11, 11, 10, 9, 8, 7, 5, 10, 15, - 14, 11, 10, 14, 19, 18, 19, 21, 22, 20, 16, 16, 17, 15, 15, 16, - 21, 19, 15, 16, 21, 26, 21, 18, 20, 20, 18, 17, 20, 18, 18, 24, - 25, 21, 28, 31, 20, 16, 17, 17, 15, 15, 17, 21, 24, 19, 23, 23, - 17, 15, 19, 23, 23, 17, 19, 18, 15, 16, 22, 24, 22, 17, 22, 14, - 22, 24, 19, 28, 21, 19, 25, 21, 17, 20, 18, 17, 25, 18, 16, 14, - 16, 19, 24, 28, 32, 42, 62, 85, 87, 76, 95, 45, 9, 36, 67, 76, - 92, 103, 99, 103, 100, 98, 84, 98, 101, 100, 107, 102, 104, 101, 104, 106, - 106, 105, 105, 106, 107, 106, 106, 106, 105, 105, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 102, 103, 103, - 60, 64, 66, 63, 62, 64, 67, 65, 66, 66, 67, 68, 68, 69, 70, 70, - 70, 69, 68, 67, 67, 67, 67, 68, 69, 72, 73, 71, 71, 74, 74, 70, - 73, 70, 71, 75, 75, 74, 74, 78, 76, 74, 72, 72, 73, 75, 72, 69, - 53, 40, 27, 22, 18, 13, 12, 13, 8, 9, 11, 13, 12, 12, 11, 9, - 8, 11, 15, 16, 15, 14, 17, 19, 17, 17, 19, 22, 20, 16, 16, 19, - 19, 15, 16, 17, 19, 16, 16, 18, 22, 19, 19, 19, 16, 12, 15, 20, - 20, 19, 22, 21, 17, 28, 33, 22, 20, 21, 19, 14, 14, 19, 23, 24, - 21, 25, 25, 17, 13, 15, 20, 23, 14, 18, 19, 16, 18, 22, 24, 22, - 15, 22, 14, 22, 23, 19, 28, 24, 19, 26, 24, 19, 20, 18, 17, 29, - 22, 17, 12, 12, 16, 22, 24, 26, 31, 49, 77, 83, 78, 94, 37, 17, - 38, 69, 76, 91, 102, 98, 104, 102, 98, 84, 98, 101, 100, 106, 101, 103, - 102, 104, 106, 106, 105, 104, 105, 106, 107, 107, 106, 105, 105, 104, 103, 103, - 103, 103, 104, 104, 104, 104, 105, 105, 104, 104, 104, 104, 104, 104, 104, 104, - 103, 103, 104, 60, 65, 66, 63, 62, 65, 67, 66, 66, 66, 67, 68, 68, - 69, 70, 70, 68, 68, 67, 67, 67, 68, 69, 69, 68, 72, 74, 72, 72, - 74, 73, 68, 72, 69, 71, 75, 76, 74, 74, 77, 77, 74, 70, 71, 74, - 71, 62, 52, 30, 30, 27, 20, 14, 12, 11, 8, 5, 8, 11, 14, 14, - 15, 15, 13, 12, 13, 15, 18, 19, 20, 20, 20, 20, 19, 21, 25, 24, - 18, 18, 21, 25, 18, 14, 17, 20, 18, 17, 18, 19, 20, 21, 21, 15, - 11, 15, 24, 23, 23, 24, 21, 16, 28, 31, 17, 20, 24, 22, 17, 15, - 20, 24, 23, 18, 21, 21, 16, 15, 19, 20, 19, 17, 20, 21, 19, 20, - 23, 23, 20, 16, 23, 16, 23, 24, 18, 28, 23, 23, 26, 20, 15, 18, - 16, 13, 23, 21, 19, 16, 15, 16, 18, 20, 23, 28, 35, 61, 72, 77, - 93, 29, 20, 41, 70, 75, 90, 100, 98, 104, 104, 99, 85, 99, 101, 99, - 105, 99, 101, 104, 105, 107, 107, 105, 104, 104, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 103, 103, 103, 104, 104, 105, 105, 105, 104, 104, 104, 104, 104, - 104, 104, 104, 105, 105, 104, 60, 66, 66, 64, 62, 66, 67, 66, 66, 66, - 67, 68, 68, 69, 70, 70, 67, 66, 66, 67, 68, 69, 71, 72, 67, 72, - 75, 73, 73, 75, 73, 67, 72, 70, 71, 76, 78, 76, 77, 81, 79, 74, - 68, 68, 68, 60, 43, 27, 12, 21, 25, 14, 6, 9, 12, 12, 6, 8, - 11, 15, 16, 16, 15, 14, 13, 12, 14, 17, 21, 22, 21, 19, 26, 23, - 25, 29, 26, 19, 18, 22, 32, 21, 15, 18, 21, 21, 21, 20, 25, 28, - 32, 31, 23, 18, 24, 34, 26, 26, 27, 23, 17, 27, 28, 12, 19, 24, - 25, 20, 17, 22, 23, 20, 17, 18, 17, 17, 21, 25, 22, 15, 20, 24, - 25, 22, 22, 25, 22, 18, 19, 26, 18, 24, 24, 18, 27, 22, 30, 29, - 19, 14, 21, 20, 13, 17, 19, 23, 24, 21, 18, 16, 18, 22, 27, 23, - 44, 56, 71, 86, 19, 13, 39, 68, 73, 87, 99, 97, 106, 106, 102, 88, - 101, 102, 99, 105, 97, 99, 104, 106, 108, 107, 105, 102, 102, 103, 103, 103, - 104, 105, 105, 105, 106, 106, 103, 103, 103, 104, 104, 105, 105, 105, 104, 104, - 104, 104, 104, 104, 104, 104, 106, 105, 105, 63, 63, 62, 63, 63, 66, 68, - 69, 70, 66, 64, 68, 69, 67, 65, 68, 67, 73, 69, 67, 73, 71, 66, - 72, 73, 76, 76, 73, 74, 78, 79, 75, 67, 69, 74, 78, 79, 80, 81, - 81, 82, 75, 69, 66, 57, 40, 26, 15, 14, 14, 14, 11, 9, 12, 13, - 14, 16, 12, 16, 16, 11, 16, 20, 12, 11, 22, 20, 17, 22, 26, 24, - 29, 28, 30, 29, 28, 29, 30, 23, 13, 41, 18, 22, 32, 21, 20, 27, - 20, 38, 28, 24, 29, 33, 32, 31, 32, 37, 26, 18, 22, 27, 29, 27, - 26, 33, 29, 23, 21, 22, 24, 23, 23, 23, 26, 26, 23, 20, 18, 22, - 25, 28, 28, 28, 20, 15, 29, 32, 17, 27, 20, 28, 37, 23, 13, 16, - 20, 28, 25, 20, 19, 19, 19, 19, 20, 28, 25, 19, 17, 18, 20, 19, - 18, 32, 25, 28, 39, 48, 51, 31, 0, 41, 68, 82, 85, 96, 101, 101, - 105, 107, 89, 103, 104, 99, 102, 94, 99, 103, 105, 106, 106, 104, 104, 105, - 106, 104, 103, 103, 104, 105, 106, 106, 106, 108, 107, 105, 103, 102, 102, 102, - 103, 105, 105, 105, 105, 105, 105, 105, 105, 107, 107, 106, 67, 66, 66, 65, - 66, 68, 69, 70, 70, 65, 64, 68, 69, 67, 66, 67, 68, 74, 69, 67, - 73, 71, 67, 73, 69, 72, 73, 71, 71, 76, 76, 72, 74, 73, 76, 79, - 80, 83, 83, 83, 76, 74, 69, 55, 33, 16, 16, 23, 18, 15, 12, 10, - 8, 11, 13, 16, 21, 14, 18, 22, 15, 18, 19, 15, 32, 41, 36, 29, - 35, 38, 40, 46, 34, 35, 35, 35, 38, 41, 38, 30, 32, 18, 23, 31, - 27, 34, 43, 38, 31, 32, 39, 50, 53, 49, 47, 50, 49, 47, 45, 46, - 41, 38, 40, 47, 39, 38, 36, 38, 40, 42, 39, 38, 40, 43, 44, 43, - 42, 42, 44, 47, 27, 29, 39, 40, 37, 40, 37, 19, 38, 28, 34, 42, - 33, 28, 32, 34, 27, 25, 22, 22, 23, 22, 19, 18, 16, 18, 20, 24, - 28, 28, 24, 22, 23, 24, 32, 31, 24, 29, 32, 26, 42, 61, 70, 84, - 100, 101, 100, 107, 102, 90, 107, 108, 101, 103, 96, 102, 102, 105, 106, 106, - 104, 104, 105, 106, 103, 103, 103, 104, 105, 106, 106, 107, 108, 107, 105, 104, - 103, 103, 103, 104, 105, 105, 105, 105, 105, 105, 105, 105, 107, 106, 105, 68, - 67, 67, 66, 66, 67, 68, 68, 70, 65, 64, 68, 70, 67, 66, 68, 68, - 73, 69, 67, 74, 72, 68, 73, 68, 72, 73, 71, 71, 75, 75, 72, 78, - 76, 77, 77, 78, 79, 80, 79, 75, 68, 56, 38, 18, 8, 16, 30, 19, - 14, 10, 8, 8, 9, 10, 11, 22, 12, 17, 27, 27, 31, 42, 48, 50, - 67, 72, 72, 77, 73, 64, 63, 66, 67, 67, 67, 70, 74, 71, 64, 73, - 64, 62, 58, 49, 55, 58, 50, 60, 67, 78, 86, 87, 85, 87, 94, 98, - 97, 98, 97, 92, 86, 87, 92, 106, 105, 103, 101, 99, 93, 86, 80, 71, - 73, 74, 73, 71, 70, 72, 72, 66, 59, 62, 63, 58, 61, 64, 55, 51, - 37, 38, 44, 39, 37, 41, 40, 31, 34, 37, 40, 41, 35, 25, 19, 27, - 25, 21, 18, 17, 17, 18, 20, 19, 23, 30, 27, 14, 19, 33, 38, 41, - 53, 59, 75, 95, 98, 97, 106, 96, 87, 107, 108, 101, 104, 99, 103, 103, - 105, 107, 107, 105, 105, 106, 107, 104, 104, 105, 105, 105, 105, 105, 106, 108, - 107, 106, 105, 104, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 106, - 106, 105, 66, 65, 65, 65, 64, 64, 65, 65, 70, 65, 64, 68, 70, 68, - 67, 69, 69, 73, 70, 68, 74, 72, 68, 75, 72, 76, 76, 74, 74, 78, - 78, 75, 79, 76, 74, 73, 74, 75, 75, 74, 75, 54, 32, 23, 20, 19, - 20, 22, 18, 13, 10, 10, 11, 11, 9, 11, 22, 11, 19, 36, 45, 60, - 85, 103, 121, 140, 147, 149, 155, 150, 139, 137, 139, 141, 141, 140, 141, 142, - 136, 127, 132, 132, 130, 123, 120, 131, 135, 127, 138, 141, 142, 143, 143, 146, - 155, 164, 169, 165, 161, 165, 166, 162, 156, 155, 157, 158, 159, 161, 160, 159, - 155, 153, 153, 152, 152, 150, 147, 144, 143, 143, 144, 130, 127, 127, 118, 117, - 123, 121, 111, 93, 87, 90, 85, 83, 86, 81, 89, 77, 58, 44, 36, 38, - 41, 42, 38, 33, 30, 25, 21, 19, 19, 18, 24, 18, 21, 23, 18, 23, - 24, 19, 31, 47, 51, 59, 77, 90, 94, 103, 94, 85, 102, 103, 99, 106, - 99, 101, 104, 105, 107, 107, 105, 105, 106, 107, 105, 105, 105, 105, 105, 105, - 104, 105, 108, 107, 107, 106, 106, 105, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 104, 65, 65, 65, 65, 65, 65, 64, 64, 70, 65, 65, - 69, 71, 69, 68, 70, 68, 73, 69, 67, 74, 72, 70, 76, 74, 77, 78, - 75, 76, 80, 80, 77, 80, 77, 74, 74, 73, 72, 70, 65, 56, 35, 18, - 17, 24, 24, 18, 14, 18, 14, 14, 18, 18, 13, 11, 14, 21, 19, 38, - 65, 81, 102, 128, 146, 151, 161, 154, 148, 155, 161, 165, 173, 181, 184, 186, - 186, 187, 185, 176, 166, 176, 183, 180, 172, 174, 182, 184, 182, 186, 183, 179, - 175, 177, 183, 190, 195, 189, 190, 191, 195, 191, 186, 184, 189, 190, 190, 187, - 186, 182, 181, 179, 180, 177, 175, 173, 172, 169, 168, 167, 166, 178, 171, 177, - 182, 173, 165, 163, 156, 167, 148, 143, 143, 137, 138, 139, 131, 129, 122, 111, - 99, 85, 72, 58, 47, 33, 32, 35, 38, 37, 33, 28, 23, 26, 15, 15, - 20, 18, 19, 16, 8, 16, 41, 42, 37, 51, 74, 88, 96, 94, 84, 98, - 97, 97, 109, 103, 100, 105, 106, 108, 108, 105, 105, 107, 108, 106, 106, 105, - 105, 105, 105, 104, 104, 107, 107, 107, 107, 106, 106, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 105, 104, 104, 103, 66, 66, 67, 68, 68, 68, 67, 67, - 69, 65, 65, 69, 71, 70, 69, 71, 68, 73, 69, 67, 75, 74, 71, 77, - 73, 76, 76, 73, 75, 78, 78, 77, 81, 79, 77, 75, 73, 69, 60, 52, - 28, 21, 18, 20, 20, 15, 11, 12, 13, 11, 13, 18, 16, 9, 10, 17, - 33, 45, 74, 102, 117, 136, 152, 158, 164, 173, 167, 161, 169, 175, 179, 188, - 175, 179, 182, 183, 186, 186, 178, 168, 186, 195, 189, 181, 185, 184, 181, 187, - 186, 187, 186, 183, 186, 191, 193, 191, 179, 190, 201, 200, 186, 177, 186, 201, - 203, 201, 197, 192, 188, 187, 189, 192, 190, 188, 186, 184, 186, 188, 188, 188, - 182, 179, 181, 182, 172, 172, 175, 169, 176, 162, 160, 161, 157, 160, 161, 152, - 146, 151, 157, 158, 151, 132, 111, 92, 60, 48, 37, 29, 29, 28, 28, 24, - 24, 15, 18, 20, 10, 9, 16, 20, 10, 31, 32, 23, 35, 53, 68, 80, - 87, 82, 98, 97, 97, 112, 107, 103, 105, 106, 108, 108, 106, 106, 107, 108, - 107, 107, 105, 105, 105, 105, 103, 103, 105, 105, 106, 106, 106, 106, 105, 104, - 105, 105, 105, 105, 105, 105, 105, 105, 103, 103, 103, 64, 65, 67, 68, 69, - 69, 68, 67, 69, 65, 65, 69, 72, 70, 70, 71, 68, 73, 70, 68, 75, - 74, 71, 77, 72, 76, 76, 73, 73, 76, 77, 76, 81, 79, 76, 73, 69, - 59, 44, 30, 14, 14, 18, 21, 17, 9, 7, 12, 5, 4, 9, 16, 16, - 12, 21, 39, 62, 82, 110, 127, 135, 153, 163, 157, 160, 174, 177, 176, 183, - 183, 178, 181, 180, 182, 183, 184, 188, 191, 187, 180, 180, 190, 188, 190, 201, - 197, 194, 209, 193, 200, 203, 198, 195, 197, 198, 196, 196, 202, 209, 209, 200, - 194, 199, 210, 187, 189, 191, 193, 196, 201, 209, 216, 196, 193, 189, 187, 190, - 193, 194, 196, 196, 193, 191, 181, 171, 182, 192, 186, 179, 172, 175, 177, 173, - 177, 177, 168, 180, 173, 164, 157, 157, 161, 166, 167, 123, 101, 74, 56, 48, - 44, 38, 33, 28, 19, 22, 24, 13, 10, 19, 23, 16, 19, 17, 23, 33, - 34, 41, 61, 67, 72, 98, 98, 94, 107, 105, 105, 104, 105, 107, 107, 106, - 106, 108, 109, 108, 108, 107, 106, 105, 104, 103, 103, 103, 104, 105, 106, 106, - 105, 104, 103, 105, 105, 105, 105, 105, 105, 105, 105, 103, 102, 102, 61, 62, - 64, 66, 67, 67, 66, 66, 69, 65, 65, 69, 72, 70, 70, 72, 68, 74, - 70, 69, 75, 75, 71, 77, 74, 77, 77, 73, 74, 77, 77, 75, 76, 75, - 72, 68, 62, 48, 28, 12, 17, 13, 12, 17, 19, 14, 10, 10, 4, 5, - 12, 22, 24, 27, 45, 70, 91, 112, 132, 136, 137, 157, 169, 158, 167, 177, - 173, 168, 174, 177, 177, 183, 184, 184, 181, 180, 184, 189, 188, 183, 194, 200, - 194, 193, 200, 184, 175, 193, 193, 202, 205, 194, 184, 184, 189, 192, 207, 197, - 191, 196, 204, 203, 198, 194, 206, 206, 204, 198, 192, 189, 190, 193, 205, 199, - 193, 191, 193, 196, 198, 197, 190, 196, 202, 192, 180, 187, 190, 175, 180, 178, - 183, 186, 181, 183, 183, 173, 170, 169, 171, 172, 171, 168, 162, 156, 168, 153, - 137, 125, 114, 96, 69, 48, 39, 24, 25, 32, 28, 24, 21, 14, 26, 11, - 7, 26, 38, 21, 20, 46, 45, 60, 94, 96, 87, 98, 99, 104, 103, 104, - 107, 107, 105, 106, 108, 109, 108, 108, 107, 106, 105, 104, 103, 103, 102, 103, - 104, 105, 106, 105, 104, 103, 105, 105, 105, 105, 105, 105, 105, 105, 102, 102, - 102, 64, 68, 68, 65, 66, 69, 69, 67, 70, 70, 71, 71, 71, 72, 72, - 72, 73, 72, 71, 71, 70, 71, 71, 71, 77, 75, 73, 72, 71, 72, 75, - 76, 74, 74, 76, 65, 40, 27, 27, 21, 9, 17, 21, 17, 13, 11, 8, - 3, 1, 15, 25, 23, 27, 49, 85, 111, 131, 139, 148, 155, 161, 164, 167, - 169, 164, 165, 171, 178, 179, 176, 176, 180, 185, 177, 172, 176, 187, 194, 194, - 190, 192, 193, 192, 190, 188, 189, 191, 193, 192, 193, 195, 197, 199, 200, 199, - 201, 208, 203, 199, 203, 208, 208, 206, 204, 217, 210, 217, 212, 193, 200, 214, - 206, 198, 205, 208, 202, 197, 196, 195, 190, 192, 199, 199, 186, 180, 187, 192, - 192, 188, 180, 178, 180, 177, 185, 190, 185, 185, 177, 170, 172, 181, 185, 178, - 167, 162, 155, 152, 153, 153, 141, 118, 97, 64, 45, 34, 37, 35, 25, 23, - 30, 20, 19, 18, 17, 17, 22, 28, 35, 41, 35, 49, 79, 97, 94, 92, - 101, 105, 106, 104, 99, 100, 104, 108, 107, 107, 108, 107, 106, 103, 103, 104, - 106, 105, 106, 106, 106, 106, 105, 104, 103, 106, 106, 106, 105, 105, 104, 104, - 104, 105, 105, 105, 65, 68, 68, 65, 66, 69, 70, 67, 68, 68, 68, 69, - 69, 70, 70, 70, 70, 70, 69, 70, 71, 73, 74, 75, 70, 74, 76, 76, - 73, 72, 71, 71, 73, 64, 57, 45, 25, 18, 16, 7, 9, 11, 11, 8, - 8, 13, 12, 9, 10, 17, 27, 42, 67, 96, 117, 126, 146, 153, 161, 167, - 169, 170, 171, 173, 170, 170, 172, 181, 183, 182, 181, 184, 181, 178, 175, 180, - 187, 193, 190, 187, 194, 195, 196, 195, 193, 191, 190, 191, 192, 192, 194, 196, - 199, 201, 202, 206, 206, 208, 210, 213, 214, 213, 212, 212, 214, 209, 217, 218, - 208, 214, 221, 208, 204, 206, 205, 199, 197, 202, 204, 203, 182, 198, 206, 203, - 196, 193, 186, 177, 192, 186, 184, 181, 168, 171, 178, 177, 189, 186, 181, 182, - 183, 182, 174, 167, 164, 160, 156, 157, 161, 157, 147, 135, 135, 99, 62, 48, - 46, 41, 33, 26, 22, 14, 13, 18, 26, 28, 23, 18, 32, 34, 44, 63, - 83, 92, 95, 96, 97, 103, 105, 101, 99, 103, 106, 107, 107, 108, 107, 106, - 103, 103, 104, 106, 105, 106, 106, 106, 106, 105, 104, 103, 106, 106, 106, 105, - 105, 104, 104, 104, 105, 105, 105, 64, 67, 67, 65, 65, 68, 69, 66, 67, - 67, 68, 68, 68, 69, 69, 69, 67, 67, 68, 70, 72, 75, 77, 78, 71, - 74, 77, 76, 72, 70, 68, 69, 70, 53, 41, 31, 18, 18, 18, 8, 14, - 15, 13, 11, 13, 17, 16, 14, 16, 26, 42, 68, 101, 128, 139, 139, 155, - 162, 167, 171, 171, 170, 171, 172, 175, 174, 175, 182, 185, 185, 184, 187, 181, - 182, 183, 187, 189, 191, 189, 187, 193, 196, 198, 198, 195, 192, 190, 189, 192, - 193, 194, 197, 200, 204, 206, 210, 201, 209, 215, 217, 212, 210, 208, 210, 222, - 217, 217, 216, 209, 214, 215, 202, 210, 214, 216, 217, 218, 219, 215, 209, 192, - 200, 202, 195, 192, 197, 199, 197, 186, 185, 188, 181, 165, 165, 179, 184, 177, - 178, 179, 180, 180, 178, 174, 173, 175, 172, 168, 167, 166, 164, 158, 151, 147, - 145, 134, 106, 71, 45, 38, 40, 39, 27, 19, 17, 19, 21, 18, 14, 22, - 31, 38, 46, 63, 84, 93, 91, 89, 99, 105, 102, 99, 101, 104, 106, 107, - 108, 107, 106, 103, 103, 104, 106, 105, 106, 106, 106, 106, 105, 104, 103, 106, - 106, 106, 105, 105, 104, 104, 104, 105, 105, 105, 64, 67, 68, 65, 65, 69, - 69, 66, 70, 70, 70, 71, 71, 71, 72, 72, 68, 68, 69, 71, 73, 76, - 77, 78, 78, 76, 73, 70, 69, 68, 67, 65, 55, 38, 29, 23, 17, 20, - 25, 18, 14, 16, 19, 19, 16, 17, 17, 16, 29, 53, 81, 101, 118, 132, - 145, 150, 162, 167, 171, 174, 173, 170, 170, 171, 178, 179, 180, 184, 182, 180, - 182, 188, 186, 188, 189, 190, 189, 190, 189, 190, 190, 192, 194, 194, 192, 191, - 190, 191, 193, 193, 194, 196, 198, 202, 204, 206, 201, 209, 213, 211, 207, 205, - 204, 203, 227, 222, 216, 208, 204, 209, 214, 211, 208, 204, 202, 202, 203, 205, - 201, 198, 212, 210, 200, 187, 183, 192, 203, 208, 188, 186, 191, 186, 170, 172, - 186, 191, 176, 173, 173, 176, 178, 177, 176, 178, 176, 178, 178, 176, 172, 164, - 157, 151, 152, 151, 145, 135, 120, 100, 72, 46, 40, 36, 30, 25, 18, 16, - 17, 20, 16, 25, 31, 35, 43, 62, 78, 87, 89, 97, 101, 99, 100, 103, - 104, 102, 106, 108, 107, 106, 103, 103, 104, 106, 105, 106, 106, 106, 106, 105, - 104, 103, 106, 106, 106, 105, 105, 104, 104, 104, 105, 105, 105, 65, 68, 68, - 66, 66, 69, 70, 67, 70, 70, 71, 71, 72, 72, 72, 72, 71, 70, 71, - 72, 73, 75, 76, 76, 80, 74, 69, 68, 70, 68, 60, 50, 31, 20, 20, - 18, 9, 14, 21, 19, 10, 13, 15, 16, 15, 18, 27, 38, 67, 91, 116, - 129, 135, 142, 151, 158, 168, 173, 176, 179, 177, 175, 174, 176, 178, 184, 188, - 189, 181, 176, 180, 190, 189, 190, 189, 187, 185, 185, 189, 192, 189, 190, 191, - 190, 191, 192, 195, 198, 195, 195, 195, 195, 197, 198, 199, 199, 204, 208, 208, - 204, 204, 208, 208, 204, 210, 216, 213, 206, 206, 212, 219, 226, 233, 225, 211, - 207, 208, 215, 222, 226, 214, 215, 210, 201, 195, 193, 191, 188, 200, 193, 194, - 190, 177, 178, 187, 187, 194, 183, 177, 180, 182, 180, 176, 176, 172, 173, 174, - 174, 171, 168, 165, 163, 159, 154, 145, 138, 136, 130, 113, 93, 44, 39, 35, - 35, 33, 29, 22, 16, 13, 16, 24, 29, 29, 36, 54, 78, 89, 94, 96, - 95, 99, 104, 103, 99, 105, 107, 107, 106, 103, 103, 104, 106, 105, 106, 106, - 106, 106, 105, 104, 103, 106, 106, 106, 105, 105, 104, 104, 104, 105, 105, 105, - 65, 68, 69, 66, 66, 70, 70, 67, 68, 69, 69, 69, 70, 70, 70, 71, - 73, 72, 73, 73, 73, 74, 75, 74, 73, 70, 69, 70, 69, 60, 45, 28, - 21, 16, 21, 20, 8, 9, 16, 16, 13, 11, 13, 18, 25, 39, 61, 82, - 106, 118, 129, 137, 148, 158, 159, 155, 167, 171, 175, 177, 177, 177, 176, 177, - 180, 186, 190, 193, 184, 180, 182, 193, 188, 189, 184, 184, 180, 183, 184, 188, - 190, 189, 190, 190, 191, 193, 198, 202, 194, 196, 195, 197, 195, 195, 193, 193, - 198, 202, 202, 198, 201, 209, 211, 206, 195, 211, 212, 207, 210, 208, 207, 216, - 207, 204, 202, 206, 207, 206, 206, 208, 207, 208, 208, 206, 203, 200, 196, 191, - 198, 190, 191, 192, 185, 188, 193, 189, 192, 180, 173, 180, 185, 182, 179, 179, - 179, 175, 171, 166, 166, 168, 171, 173, 157, 161, 163, 156, 142, 133, 133, 135, - 99, 73, 44, 31, 32, 33, 24, 12, 13, 12, 17, 23, 22, 22, 38, 60, - 78, 87, 91, 95, 99, 104, 102, 99, 105, 107, 107, 106, 104, 103, 104, 106, - 105, 106, 106, 106, 106, 105, 104, 103, 106, 106, 106, 105, 105, 104, 104, 104, - 105, 105, 105, 65, 68, 69, 66, 67, 70, 70, 67, 69, 69, 69, 70, 70, - 70, 71, 71, 73, 72, 73, 73, 73, 75, 74, 74, 70, 69, 68, 63, 55, - 43, 32, 22, 25, 18, 24, 23, 11, 11, 16, 15, 16, 11, 16, 32, 55, - 77, 98, 117, 130, 135, 136, 141, 153, 162, 161, 154, 164, 167, 173, 176, 177, - 177, 178, 177, 179, 179, 182, 188, 188, 185, 184, 189, 187, 186, 184, 184, 183, - 184, 184, 184, 186, 188, 190, 190, 190, 192, 194, 197, 191, 194, 196, 197, 196, - 194, 192, 190, 193, 205, 209, 203, 202, 208, 210, 206, 201, 217, 214, 208, 214, - 210, 201, 206, 203, 205, 212, 220, 218, 210, 204, 204, 206, 204, 201, 201, 202, - 203, 205, 206, 192, 188, 193, 197, 191, 193, 199, 196, 180, 174, 175, 184, 188, - 182, 181, 185, 182, 175, 168, 164, 165, 166, 167, 167, 176, 160, 152, 159, 164, - 155, 139, 129, 146, 119, 79, 50, 35, 30, 24, 19, 12, 14, 14, 14, 19, - 26, 32, 38, 56, 76, 91, 96, 97, 98, 100, 100, 104, 107, 107, 106, 104, - 104, 104, 107, 105, 106, 106, 106, 106, 105, 104, 103, 106, 106, 106, 105, 105, - 104, 104, 104, 105, 105, 105, 66, 70, 70, 67, 67, 70, 70, 68, 71, 71, - 72, 72, 72, 74, 74, 73, 72, 72, 72, 73, 74, 75, 75, 74, 72, 70, - 63, 49, 32, 22, 22, 22, 23, 15, 20, 21, 13, 14, 19, 17, 13, 10, - 20, 50, 83, 105, 117, 127, 138, 147, 151, 151, 154, 160, 163, 162, 167, 172, - 176, 181, 181, 183, 184, 183, 177, 172, 173, 183, 191, 191, 187, 184, 189, 188, - 188, 189, 190, 190, 188, 184, 184, 187, 189, 191, 191, 190, 190, 190, 191, 193, - 197, 199, 199, 196, 193, 191, 199, 215, 223, 214, 205, 206, 208, 205, 210, 222, - 212, 205, 220, 221, 213, 220, 219, 212, 205, 203, 198, 194, 201, 212, 211, 210, - 209, 210, 209, 204, 198, 196, 201, 199, 205, 205, 193, 191, 195, 191, 185, 183, - 189, 197, 193, 180, 178, 183, 170, 167, 165, 167, 171, 171, 167, 162, 169, 165, - 166, 166, 152, 134, 139, 156, 137, 135, 121, 94, 63, 41, 33, 33, 16, 21, - 17, 10, 19, 36, 32, 19, 33, 63, 89, 98, 93, 93, 96, 101, 103, 105, - 106, 106, 104, 104, 107, 109, 106, 107, 107, 107, 107, 106, 105, 104, 107, 107, - 107, 106, 106, 105, 105, 105, 105, 105, 105, 70, 70, 70, 69, 68, 67, 66, - 65, 66, 66, 67, 68, 69, 70, 71, 71, 75, 74, 73, 74, 73, 74, 74, - 75, 77, 63, 44, 31, 25, 24, 20, 16, 13, 15, 24, 22, 15, 17, 20, - 11, 13, 27, 46, 81, 117, 129, 126, 134, 146, 150, 154, 158, 161, 164, 168, - 170, 172, 172, 173, 175, 177, 181, 184, 186, 175, 181, 187, 188, 184, 183, 186, - 190, 194, 186, 188, 190, 185, 185, 184, 174, 183, 188, 192, 193, 189, 187, 191, - 195, 187, 200, 208, 201, 189, 188, 195, 201, 203, 204, 201, 198, 201, 209, 213, - 212, 212, 208, 205, 206, 212, 215, 214, 212, 209, 205, 207, 214, 211, 202, 201, - 208, 213, 217, 217, 211, 206, 206, 206, 204, 210, 209, 208, 205, 198, 193, 199, - 207, 192, 193, 190, 184, 182, 185, 186, 184, 183, 175, 166, 163, 168, 170, 167, - 163, 169, 168, 165, 164, 161, 157, 152, 147, 145, 144, 138, 128, 116, 96, 63, - 33, 27, 31, 29, 20, 21, 27, 22, 13, 38, 42, 55, 78, 93, 97, 95, - 96, 99, 100, 101, 104, 106, 110, 112, 113, 108, 107, 107, 107, 107, 107, 107, - 107, 108, 108, 108, 107, 107, 106, 106, 106, 106, 106, 106, 71, 70, 70, 69, - 68, 66, 65, 65, 67, 67, 69, 69, 71, 72, 72, 73, 78, 77, 75, 76, - 77, 77, 75, 73, 61, 47, 31, 22, 17, 16, 14, 12, 22, 17, 18, 17, - 11, 15, 22, 18, 17, 43, 69, 96, 124, 136, 137, 145, 148, 150, 152, 156, - 160, 163, 165, 166, 175, 175, 176, 177, 179, 180, 180, 182, 179, 184, 187, 188, - 186, 186, 189, 192, 186, 178, 180, 186, 185, 189, 190, 181, 187, 189, 190, 190, - 189, 188, 188, 188, 188, 195, 197, 193, 189, 192, 196, 198, 199, 204, 209, 209, - 211, 211, 207, 200, 207, 209, 213, 219, 224, 225, 221, 219, 204, 207, 212, 219, - 220, 217, 218, 221, 208, 216, 219, 215, 211, 212, 214, 215, 213, 206, 202, 207, - 210, 205, 196, 192, 195, 198, 197, 190, 185, 186, 187, 186, 181, 175, 170, 170, - 173, 173, 168, 162, 171, 168, 165, 164, 164, 162, 156, 151, 145, 145, 142, 137, - 132, 122, 102, 82, 52, 37, 29, 33, 30, 19, 14, 21, 22, 26, 37, 57, - 79, 92, 96, 98, 99, 100, 102, 104, 106, 109, 112, 112, 108, 107, 107, 107, - 107, 107, 107, 107, 108, 108, 108, 107, 107, 106, 106, 106, 105, 105, 105, 70, - 70, 70, 68, 68, 66, 66, 65, 69, 70, 71, 71, 73, 74, 76, 76, 80, - 78, 77, 77, 77, 75, 70, 64, 40, 31, 20, 15, 14, 15, 13, 11, 12, - 8, 16, 26, 21, 18, 16, 11, 29, 68, 98, 113, 130, 139, 144, 152, 155, - 153, 153, 157, 163, 166, 166, 164, 174, 175, 177, 178, 178, 177, 176, 176, 182, - 182, 183, 184, 185, 187, 189, 190, 185, 175, 177, 184, 186, 193, 195, 185, 195, - 193, 191, 192, 193, 193, 190, 187, 197, 197, 195, 192, 195, 201, 201, 197, 201, - 203, 202, 199, 199, 203, 205, 203, 205, 209, 213, 215, 213, 211, 208, 208, 218, - 223, 223, 216, 210, 205, 201, 196, 209, 217, 221, 216, 211, 211, 212, 212, 213, - 206, 203, 207, 209, 204, 195, 190, 191, 198, 200, 193, 186, 185, 186, 186, 179, - 175, 173, 175, 178, 176, 169, 162, 172, 168, 164, 165, 167, 167, 161, 156, 152, - 151, 149, 144, 142, 139, 133, 123, 92, 59, 34, 32, 35, 29, 22, 21, 16, - 18, 24, 37, 58, 83, 96, 102, 103, 105, 104, 106, 106, 107, 106, 106, 106, - 106, 106, 106, 106, 106, 105, 105, 106, 106, 106, 105, 104, 103, 103, 104, 105, - 104, 104, 71, 71, 70, 69, 69, 68, 67, 67, 70, 71, 71, 73, 74, 75, - 76, 78, 78, 78, 76, 77, 75, 68, 56, 45, 29, 22, 16, 14, 14, 16, - 15, 13, 24, 12, 14, 17, 9, 11, 25, 33, 46, 90, 119, 126, 137, 148, - 151, 155, 163, 158, 156, 160, 168, 172, 171, 168, 170, 171, 174, 176, 176, 175, - 173, 173, 182, 180, 179, 180, 183, 186, 187, 187, 195, 184, 183, 188, 189, 195, - 195, 184, 194, 194, 194, 194, 193, 193, 191, 189, 199, 199, 197, 196, 199, 204, - 201, 195, 194, 197, 197, 194, 195, 201, 205, 206, 206, 208, 208, 204, 199, 198, - 202, 207, 209, 218, 219, 213, 213, 221, 223, 219, 207, 210, 212, 210, 210, 212, - 210, 206, 210, 209, 210, 207, 199, 193, 198, 207, 182, 192, 197, 192, 183, 182, - 183, 184, 177, 175, 174, 176, 178, 177, 170, 165, 172, 167, 163, 164, 168, 169, - 164, 160, 162, 162, 157, 151, 145, 142, 140, 137, 118, 103, 73, 42, 30, 35, - 34, 23, 21, 24, 25, 27, 41, 66, 91, 102, 106, 108, 109, 107, 106, 104, - 102, 101, 104, 105, 105, 105, 105, 104, 104, 104, 104, 105, 104, 104, 103, 102, - 102, 103, 104, 105, 105, 70, 70, 69, 69, 68, 68, 68, 68, 70, 72, 72, - 73, 74, 75, 76, 78, 80, 79, 79, 77, 70, 56, 40, 27, 21, 17, 14, - 14, 14, 15, 16, 15, 11, 10, 20, 24, 14, 14, 27, 35, 67, 104, 127, - 134, 146, 158, 160, 159, 164, 159, 156, 160, 168, 172, 172, 169, 166, 168, 171, - 174, 176, 176, 175, 175, 183, 181, 179, 180, 183, 185, 186, 186, 200, 189, 189, - 192, 191, 194, 193, 182, 188, 192, 195, 194, 190, 188, 190, 193, 187, 193, 197, - 196, 198, 200, 198, 194, 182, 194, 206, 211, 210, 208, 202, 195, 203, 207, 209, - 208, 205, 208, 216, 224, 227, 230, 223, 208, 200, 203, 203, 198, 203, 202, 201, - 203, 211, 217, 213, 205, 207, 208, 209, 207, 201, 196, 201, 210, 177, 187, 193, - 190, 183, 182, 183, 184, 178, 176, 173, 173, 175, 175, 172, 169, 169, 165, 161, - 162, 166, 168, 165, 162, 167, 166, 162, 156, 149, 143, 141, 141, 126, 134, 120, - 81, 43, 32, 34, 34, 28, 29, 29, 24, 27, 47, 77, 101, 106, 109, 111, - 109, 106, 102, 98, 97, 102, 104, 104, 104, 104, 103, 103, 103, 103, 104, 103, - 102, 101, 100, 100, 102, 106, 108, 108, 70, 70, 70, 70, 70, 70, 71, 71, - 71, 71, 73, 74, 76, 76, 77, 77, 81, 81, 78, 71, 59, 44, 28, 18, - 16, 15, 13, 13, 14, 15, 16, 16, 4, 9, 20, 22, 16, 27, 45, 50, - 92, 116, 131, 139, 156, 166, 166, 167, 160, 156, 154, 156, 160, 164, 165, 164, - 165, 167, 170, 173, 176, 177, 178, 178, 181, 182, 183, 183, 184, 185, 186, 187, - 193, 185, 189, 193, 190, 192, 192, 183, 190, 196, 201, 199, 194, 191, 194, 199, - 182, 190, 197, 198, 198, 201, 202, 201, 188, 198, 205, 205, 202, 201, 199, 195, - 197, 203, 209, 211, 208, 207, 209, 212, 200, 202, 202, 200, 203, 213, 222, 226, - 216, 212, 206, 204, 210, 215, 209, 200, 208, 203, 201, 208, 213, 208, 200, 194, - 181, 189, 194, 190, 186, 186, 187, 186, 179, 176, 173, 172, 173, 174, 174, 174, - 166, 164, 162, 162, 164, 165, 164, 165, 163, 162, 162, 162, 158, 151, 150, 150, - 148, 133, 122, 114, 94, 62, 40, 31, 32, 28, 27, 24, 21, 31, 61, 90, - 103, 109, 110, 111, 107, 103, 97, 97, 102, 104, 104, 104, 104, 103, 103, 102, - 103, 103, 103, 101, 101, 99, 99, 101, 106, 108, 108, 69, 69, 69, 70, 70, - 71, 71, 72, 74, 75, 75, 75, 77, 77, 78, 78, 78, 77, 70, 58, 41, - 28, 20, 17, 14, 14, 14, 17, 19, 20, 22, 24, 36, 32, 26, 18, 27, - 70, 110, 120, 124, 136, 142, 149, 162, 166, 165, 170, 158, 156, 154, 153, 153, - 155, 156, 157, 164, 165, 167, 169, 172, 174, 176, 177, 176, 179, 182, 182, 180, - 179, 181, 184, 184, 182, 189, 195, 190, 191, 193, 186, 196, 198, 200, 199, 196, - 194, 194, 196, 190, 195, 197, 196, 196, 201, 203, 202, 198, 201, 198, 190, 187, - 193, 201, 206, 198, 201, 203, 202, 198, 195, 195, 196, 225, 222, 220, 219, 216, - 214, 217, 223, 220, 219, 214, 207, 206, 209, 207, 202, 208, 203, 202, 208, 210, - 204, 195, 189, 187, 192, 194, 191, 188, 189, 188, 186, 180, 178, 177, 176, 177, - 177, 177, 177, 165, 166, 166, 165, 163, 163, 165, 168, 165, 161, 162, 166, 165, - 160, 156, 158, 160, 135, 121, 127, 128, 105, 71, 46, 44, 30, 23, 25, 21, - 21, 42, 71, 96, 103, 108, 110, 107, 104, 100, 100, 103, 105, 105, 104, 104, - 103, 103, 103, 104, 103, 103, 101, 101, 100, 100, 101, 105, 107, 106, 68, 68, - 69, 70, 71, 72, 72, 72, 76, 76, 76, 77, 77, 77, 77, 76, 72, 69, - 59, 43, 25, 15, 14, 17, 16, 18, 20, 23, 25, 28, 32, 35, 30, 46, - 67, 82, 105, 146, 162, 147, 151, 156, 154, 158, 164, 160, 158, 168, 159, 158, - 156, 153, 149, 149, 151, 153, 161, 161, 162, 164, 166, 168, 170, 172, 169, 174, - 179, 179, 175, 173, 175, 179, 180, 181, 192, 197, 191, 190, 194, 188, 195, 193, - 191, 190, 191, 189, 186, 183, 199, 198, 193, 188, 189, 194, 196, 193, 192, 199, - 202, 199, 196, 200, 206, 208, 202, 201, 198, 195, 195, 197, 203, 207, 209, 204, - 206, 212, 212, 205, 207, 216, 204, 209, 211, 206, 204, 210, 216, 220, 207, 208, - 209, 206, 196, 188, 190, 197, 192, 195, 194, 189, 187, 188, 186, 182, 179, 179, - 179, 179, 180, 180, 179, 178, 165, 168, 169, 167, 162, 161, 166, 170, 171, 165, - 164, 168, 168, 161, 157, 157, 144, 152, 150, 134, 122, 116, 104, 85, 59, 36, - 24, 30, 26, 16, 28, 53, 90, 99, 105, 108, 107, 106, 102, 103, 104, 106, - 106, 106, 105, 105, 104, 104, 104, 105, 104, 103, 102, 101, 100, 102, 103, 105, - 105, 69, 68, 69, 70, 71, 71, 72, 71, 71, 72, 74, 76, 78, 75, 70, - 64, 68, 52, 35, 26, 21, 17, 19, 21, 19, 25, 28, 30, 37, 51, 64, - 71, 109, 121, 135, 145, 151, 156, 162, 168, 159, 160, 161, 163, 163, 164, 166, - 167, 164, 165, 164, 161, 156, 152, 150, 151, 144, 148, 153, 155, 156, 159, 163, - 167, 169, 163, 164, 174, 179, 176, 179, 187, 184, 180, 180, 185, 194, 197, 193, - 188, 210, 206, 202, 197, 194, 194, 195, 197, 197, 198, 200, 201, 196, 190, 193, - 199, 188, 194, 201, 205, 203, 199, 195, 193, 196, 199, 201, 201, 199, 199, 201, - 204, 204, 209, 209, 207, 217, 230, 229, 218, 208, 200, 196, 205, 215, 215, 208, - 203, 216, 199, 189, 194, 199, 195, 192, 196, 194, 192, 183, 183, 187, 180, 174, - 185, 161, 176, 182, 173, 168, 173, 175, 170, 178, 173, 169, 171, 174, 171, 159, - 148, 162, 159, 163, 171, 172, 165, 160, 159, 154, 151, 147, 143, 139, 134, 130, - 127, 100, 52, 32, 40, 30, 13, 22, 46, 73, 99, 105, 98, 102, 106, 103, - 106, 107, 107, 105, 103, 105, 109, 106, 101, 103, 104, 103, 104, 103, 104, 104, - 104, 99, 106, 104, 68, 68, 68, 70, 71, 71, 72, 72, 75, 77, 77, 73, - 68, 66, 69, 69, 50, 34, 23, 22, 25, 25, 23, 24, 19, 36, 56, 70, - 85, 105, 125, 136, 147, 154, 161, 163, 163, 161, 163, 165, 160, 160, 160, 159, - 158, 158, 159, 159, 162, 160, 158, 158, 159, 157, 153, 149, 144, 146, 146, 144, - 143, 144, 149, 152, 157, 162, 172, 178, 174, 169, 173, 182, 183, 181, 184, 189, - 196, 199, 198, 195, 193, 193, 193, 194, 195, 196, 198, 199, 197, 198, 201, 203, - 200, 195, 197, 203, 202, 200, 197, 194, 192, 195, 201, 205, 199, 202, 204, 204, - 202, 201, 202, 204, 208, 215, 215, 207, 206, 213, 215, 209, 199, 197, 200, 208, - 211, 208, 204, 203, 201, 194, 196, 205, 207, 198, 193, 195, 206, 200, 187, 182, - 185, 182, 177, 182, 181, 174, 177, 187, 184, 169, 161, 164, 166, 167, 165, 161, - 156, 156, 161, 166, 164, 162, 164, 169, 169, 163, 161, 164, 165, 155, 143, 141, - 144, 143, 133, 123, 125, 108, 80, 45, 16, 19, 26, 20, 57, 91, 108, 108, - 111, 107, 98, 96, 103, 108, 109, 105, 104, 105, 103, 100, 102, 102, 103, 103, - 103, 103, 102, 102, 100, 107, 103, 66, 67, 67, 69, 70, 72, 73, 73, 76, - 74, 70, 68, 67, 64, 61, 54, 26, 19, 17, 17, 19, 25, 37, 51, 87, - 107, 128, 136, 139, 146, 154, 162, 161, 167, 170, 170, 167, 164, 165, 167, 168, - 166, 166, 163, 161, 161, 160, 160, 165, 162, 160, 163, 168, 168, 162, 155, 154, - 152, 149, 143, 139, 138, 140, 141, 150, 149, 151, 157, 163, 170, 177, 182, 181, - 182, 187, 191, 194, 196, 197, 197, 190, 191, 193, 194, 194, 194, 193, 192, 195, - 196, 200, 204, 202, 198, 199, 204, 198, 206, 216, 222, 220, 213, 205, 200, 201, - 203, 205, 205, 203, 202, 201, 201, 199, 210, 215, 207, 200, 205, 211, 213, 214, - 210, 206, 201, 195, 191, 196, 204, 210, 201, 195, 194, 188, 179, 179, 185, 186, - 183, 176, 173, 178, 182, 179, 176, 192, 176, 167, 172, 171, 161, 154, 156, 163, - 168, 173, 173, 168, 163, 162, 162, 162, 161, 163, 165, 162, 159, 161, 167, 170, - 162, 152, 148, 148, 145, 138, 132, 140, 141, 118, 67, 32, 36, 36, 12, 41, - 72, 92, 98, 107, 110, 109, 114, 100, 108, 113, 110, 105, 105, 105, 104, 106, - 106, 106, 106, 106, 106, 106, 105, 101, 107, 104, 65, 66, 68, 68, 71, 72, - 73, 74, 73, 65, 61, 65, 71, 64, 44, 21, 17, 18, 21, 20, 16, 30, - 67, 102, 113, 131, 148, 155, 156, 157, 159, 161, 164, 167, 169, 168, 165, 164, - 165, 167, 171, 171, 169, 167, 166, 166, 165, 165, 166, 165, 165, 168, 171, 171, - 166, 160, 162, 160, 156, 150, 144, 140, 138, 136, 130, 133, 140, 149, 155, 161, - 167, 174, 175, 179, 185, 188, 188, 188, 190, 193, 194, 194, 195, 195, 194, 193, - 192, 191, 193, 194, 198, 202, 200, 196, 196, 200, 202, 202, 202, 200, 198, 198, - 200, 202, 200, 202, 203, 203, 202, 199, 198, 197, 193, 205, 213, 209, 205, 207, - 212, 215, 196, 203, 214, 220, 213, 197, 186, 183, 202, 196, 193, 196, 198, 198, - 202, 208, 203, 205, 208, 207, 204, 208, 208, 198, 189, 193, 188, 179, 181, 190, - 186, 174, 171, 167, 166, 171, 177, 175, 165, 153, 157, 160, 164, 163, 159, 156, - 158, 163, 161, 167, 170, 164, 150, 142, 142, 148, 147, 140, 129, 109, 77, 58, - 43, 25, 47, 69, 81, 87, 97, 100, 97, 102, 97, 104, 107, 105, 103, 105, - 107, 106, 107, 107, 107, 106, 106, 106, 106, 106, 99, 105, 102, 65, 66, 68, - 68, 71, 72, 73, 73, 67, 64, 63, 63, 60, 48, 29, 11, 21, 20, 25, - 29, 37, 59, 98, 134, 129, 140, 151, 156, 161, 165, 165, 161, 177, 176, 173, - 171, 164, 161, 160, 159, 165, 164, 164, 164, 164, 165, 166, 167, 163, 165, 167, - 167, 165, 163, 161, 160, 161, 160, 158, 154, 149, 143, 136, 132, 112, 123, 139, - 151, 149, 144, 149, 161, 165, 171, 179, 182, 183, 184, 189, 192, 189, 189, 189, - 191, 193, 195, 198, 199, 196, 195, 197, 200, 199, 195, 194, 198, 197, 197, 197, - 195, 193, 194, 196, 199, 202, 201, 201, 201, 201, 199, 197, 196, 196, 203, 209, - 210, 208, 207, 205, 202, 219, 206, 192, 187, 189, 196, 210, 222, 205, 203, 206, - 215, 218, 209, 194, 184, 176, 171, 173, 165, 144, 143, 147, 138, 138, 156, 168, - 170, 177, 187, 187, 179, 179, 168, 157, 155, 162, 167, 167, 164, 154, 161, 166, - 165, 160, 158, 159, 161, 155, 165, 172, 170, 156, 147, 146, 151, 154, 137, 134, - 135, 116, 89, 67, 51, 39, 52, 62, 72, 88, 95, 92, 95, 99, 99, 98, - 95, 99, 104, 103, 99, 101, 102, 102, 102, 102, 102, 101, 100, 97, 104, 100, - 67, 67, 68, 70, 71, 72, 72, 71, 66, 70, 69, 55, 36, 23, 23, 26, - 20, 11, 17, 37, 67, 93, 115, 131, 156, 162, 164, 165, 168, 172, 171, 166, - 175, 174, 171, 168, 164, 161, 158, 157, 160, 160, 160, 162, 164, 166, 168, 169, - 167, 169, 170, 168, 164, 162, 162, 163, 161, 161, 160, 159, 156, 149, 140, 133, - 132, 102, 86, 103, 127, 139, 147, 158, 154, 160, 169, 175, 179, 183, 190, 194, - 187, 187, 187, 187, 188, 190, 193, 194, 199, 196, 196, 199, 199, 196, 196, 199, - 190, 197, 206, 211, 210, 204, 198, 195, 204, 202, 200, 200, 200, 200, 199, 198, - 190, 194, 199, 203, 206, 205, 201, 196, 193, 194, 204, 217, 221, 210, 194, 185, - 196, 189, 182, 178, 173, 159, 138, 123, 133, 112, 107, 98, 71, 69, 82, 80, - 76, 75, 84, 99, 106, 112, 131, 154, 171, 174, 175, 171, 164, 160, 162, 164, - 157, 165, 169, 167, 165, 164, 163, 161, 158, 158, 160, 163, 163, 159, 151, 144, - 148, 140, 141, 139, 131, 126, 114, 93, 64, 65, 55, 52, 65, 76, 86, 100, - 104, 104, 101, 98, 102, 106, 104, 98, 102, 102, 102, 102, 102, 102, 101, 100, - 99, 105, 100, 69, 68, 69, 70, 71, 71, 70, 69, 67, 66, 58, 40, 22, - 14, 22, 30, 16, 12, 24, 53, 86, 111, 127, 136, 148, 155, 158, 159, 163, - 171, 173, 171, 163, 162, 162, 163, 162, 161, 160, 158, 159, 160, 161, 163, 166, - 169, 171, 172, 176, 173, 170, 169, 168, 168, 168, 167, 166, 164, 163, 162, 159, - 154, 145, 139, 138, 76, 33, 49, 85, 107, 127, 147, 148, 152, 160, 167, 172, - 177, 182, 184, 185, 186, 187, 187, 188, 188, 187, 187, 198, 194, 192, 195, 196, - 195, 197, 201, 199, 196, 191, 187, 187, 192, 200, 207, 204, 201, 197, 196, 198, - 199, 199, 199, 190, 192, 194, 198, 200, 199, 197, 196, 197, 192, 190, 192, 189, - 179, 168, 162, 151, 145, 138, 133, 132, 131, 127, 122, 89, 54, 50, 54, 32, - 30, 44, 41, 51, 42, 39, 44, 48, 57, 82, 110, 135, 147, 164, 173, 173, - 167, 161, 158, 163, 168, 169, 166, 164, 168, 166, 162, 164, 161, 159, 161, 163, - 162, 156, 147, 144, 139, 144, 143, 139, 143, 142, 126, 126, 118, 93, 68, 55, - 48, 53, 70, 95, 101, 104, 103, 106, 109, 106, 102, 106, 106, 106, 106, 105, - 104, 104, 104, 99, 105, 101, 72, 71, 71, 71, 71, 70, 69, 66, 68, 55, - 36, 24, 18, 18, 18, 17, 16, 27, 50, 78, 99, 120, 142, 161, 165, 172, - 175, 168, 163, 163, 162, 162, 166, 165, 165, 165, 164, 162, 159, 156, 158, 159, - 160, 162, 164, 166, 168, 170, 177, 170, 164, 163, 168, 171, 169, 165, 167, 164, - 160, 158, 157, 153, 146, 140, 106, 62, 38, 47, 50, 49, 78, 123, 146, 149, - 153, 159, 164, 167, 169, 169, 172, 176, 181, 188, 192, 195, 194, 194, 194, 189, - 186, 189, 192, 193, 196, 201, 193, 197, 202, 205, 205, 204, 203, 203, 202, 197, - 192, 191, 194, 196, 197, 196, 203, 203, 201, 198, 192, 186, 185, 187, 179, 169, - 159, 153, 148, 142, 140, 143, 144, 148, 150, 150, 149, 147, 143, 139, 80, 38, - 38, 55, 39, 32, 38, 28, 31, 43, 45, 36, 35, 46, 53, 51, 91, 96, - 110, 133, 157, 171, 171, 166, 165, 168, 165, 160, 160, 167, 167, 163, 164, 169, - 169, 166, 158, 155, 158, 160, 154, 142, 148, 156, 145, 133, 131, 130, 118, 128, - 123, 108, 88, 63, 52, 62, 75, 86, 97, 100, 99, 101, 103, 101, 102, 104, - 104, 104, 104, 103, 102, 102, 97, 105, 102, 73, 77, 80, 78, 74, 70, 67, - 62, 64, 41, 19, 12, 14, 15, 15, 14, 8, 36, 63, 85, 119, 142, 155, - 165, 152, 160, 166, 168, 164, 160, 160, 164, 172, 171, 168, 165, 162, 161, 160, - 161, 160, 165, 160, 158, 166, 166, 164, 171, 172, 168, 163, 161, 161, 163, 162, - 162, 158, 165, 157, 149, 162, 140, 160, 134, 66, 32, 39, 43, 41, 34, 31, - 71, 102, 123, 144, 152, 156, 162, 167, 169, 178, 172, 180, 188, 183, 184, 189, - 187, 197, 190, 202, 202, 175, 173, 194, 205, 208, 195, 188, 193, 199, 195, 189, - 187, 190, 188, 187, 185, 183, 180, 178, 178, 172, 171, 169, 167, 166, 165, 164, - 164, 164, 162, 159, 158, 159, 160, 159, 158, 155, 178, 134, 157, 160, 133, 159, - 115, 33, 33, 34, 34, 32, 30, 28, 26, 29, 34, 37, 35, 30, 30, 35, - 41, 49, 54, 72, 90, 126, 155, 156, 171, 164, 174, 170, 159, 158, 158, 161, - 171, 159, 168, 172, 169, 162, 161, 161, 158, 151, 150, 153, 157, 152, 142, 135, - 134, 135, 139, 130, 123, 125, 108, 75, 54, 50, 45, 62, 82, 87, 91, 96, - 94, 102, 97, 106, 112, 102, 95, 100, 101, 97, 98, 97, 74, 75, 76, 76, - 76, 72, 63, 54, 34, 25, 17, 18, 18, 13, 11, 10, 22, 53, 81, 105, - 133, 148, 151, 156, 161, 163, 167, 169, 168, 166, 163, 164, 170, 171, 168, 166, - 164, 163, 163, 163, 163, 168, 163, 160, 167, 166, 164, 171, 168, 166, 161, 160, - 160, 161, 159, 159, 161, 143, 177, 149, 147, 148, 145, 66, 45, 31, 42, 40, - 36, 34, 23, 41, 40, 68, 105, 134, 152, 159, 155, 148, 151, 150, 162, 171, - 166, 167, 177, 180, 189, 174, 178, 184, 175, 173, 171, 156, 163, 164, 168, 170, - 170, 172, 176, 181, 172, 172, 172, 171, 170, 169, 168, 168, 169, 169, 168, 167, - 167, 167, 167, 168, 173, 170, 168, 167, 168, 169, 168, 168, 166, 154, 168, 154, - 161, 144, 157, 53, 37, 37, 37, 36, 34, 32, 30, 29, 33, 33, 32, 31, - 30, 30, 32, 33, 37, 42, 52, 53, 84, 121, 133, 153, 161, 170, 166, 163, - 169, 166, 154, 150, 157, 163, 166, 164, 161, 161, 160, 157, 158, 154, 151, 150, - 146, 140, 139, 142, 132, 141, 138, 133, 138, 131, 116, 107, 84, 57, 48, 56, - 67, 83, 94, 94, 106, 98, 99, 99, 90, 92, 98, 97, 107, 104, 100, 73, - 71, 73, 77, 79, 70, 53, 38, 17, 17, 21, 24, 18, 11, 10, 16, 23, - 57, 90, 118, 147, 158, 157, 161, 165, 163, 164, 165, 168, 168, 163, 162, 171, - 170, 168, 166, 165, 164, 165, 165, 165, 170, 164, 161, 166, 164, 160, 167, 163, - 162, 159, 159, 159, 158, 156, 154, 158, 142, 160, 154, 130, 151, 86, 27, 36, - 40, 49, 37, 33, 39, 27, 24, 32, 37, 43, 53, 71, 93, 109, 116, 114, - 114, 125, 129, 117, 114, 123, 128, 133, 108, 90, 84, 86, 101, 106, 92, 70, - 106, 142, 156, 156, 159, 163, 164, 171, 171, 171, 172, 172, 172, 173, 173, 181, - 180, 179, 178, 177, 177, 177, 177, 180, 178, 176, 176, 177, 178, 177, 176, 173, - 160, 163, 168, 153, 160, 105, 23, 38, 37, 36, 33, 32, 31, 30, 29, 35, - 32, 29, 28, 30, 31, 29, 27, 31, 37, 42, 31, 50, 84, 101, 128, 152, - 162, 162, 162, 171, 171, 164, 163, 156, 159, 160, 159, 161, 163, 159, 154, 159, - 154, 152, 152, 149, 144, 144, 146, 137, 147, 144, 136, 137, 136, 135, 140, 123, - 93, 69, 59, 53, 62, 77, 79, 96, 97, 107, 111, 106, 106, 104, 92, 94, - 93, 92, 76, 72, 73, 76, 72, 55, 36, 22, 22, 19, 21, 20, 14, 10, - 13, 23, 24, 57, 91, 123, 153, 163, 161, 165, 163, 162, 163, 166, 166, 166, - 164, 163, 169, 169, 168, 167, 166, 166, 166, 166, 164, 169, 163, 159, 164, 160, - 155, 160, 160, 159, 158, 158, 158, 157, 153, 150, 154, 150, 139, 135, 143, 102, - 33, 43, 42, 46, 46, 34, 29, 37, 33, 28, 24, 25, 25, 27, 31, 37, - 40, 41, 50, 45, 52, 54, 42, 37, 43, 44, 49, 48, 48, 45, 46, 53, - 54, 47, 46, 101, 152, 170, 171, 176, 179, 175, 183, 182, 182, 184, 183, 185, - 185, 186, 195, 194, 192, 189, 187, 185, 184, 184, 182, 181, 179, 179, 180, 181, - 180, 178, 175, 178, 147, 164, 167, 124, 47, 41, 33, 31, 29, 27, 27, 27, - 28, 29, 32, 31, 30, 29, 30, 30, 29, 28, 32, 33, 40, 34, 42, 56, - 67, 102, 124, 146, 158, 161, 166, 165, 164, 170, 160, 160, 158, 157, 161, 163, - 158, 150, 154, 152, 154, 158, 158, 151, 146, 145, 145, 152, 146, 135, 134, 132, - 135, 146, 134, 124, 115, 93, 60, 48, 57, 64, 71, 80, 97, 103, 99, 103, - 102, 90, 102, 103, 104, 84, 76, 68, 61, 47, 31, 22, 20, 24, 19, 15, - 14, 13, 11, 16, 24, 42, 70, 100, 128, 153, 157, 154, 159, 160, 165, 170, - 170, 168, 165, 166, 169, 167, 167, 167, 168, 168, 167, 168, 168, 165, 170, 164, - 160, 164, 159, 153, 158, 158, 157, 156, 157, 157, 156, 152, 149, 149, 148, 144, - 121, 138, 38, 35, 54, 40, 38, 32, 30, 29, 27, 30, 29, 18, 25, 35, - 39, 34, 26, 19, 18, 36, 27, 31, 38, 35, 36, 41, 38, 27, 37, 42, - 40, 40, 42, 45, 48, 87, 130, 165, 171, 169, 181, 188, 185, 190, 189, 188, - 188, 187, 188, 188, 189, 195, 194, 191, 189, 187, 185, 185, 184, 184, 182, 181, - 181, 182, 181, 179, 177, 175, 173, 169, 146, 170, 50, 44, 44, 27, 27, 25, - 25, 25, 26, 28, 29, 26, 30, 33, 32, 29, 28, 30, 34, 34, 25, 34, - 39, 42, 37, 42, 86, 102, 126, 142, 152, 163, 161, 153, 153, 165, 163, 159, - 157, 161, 163, 157, 148, 156, 153, 153, 158, 160, 154, 148, 147, 148, 149, 142, - 137, 141, 139, 140, 149, 128, 134, 141, 125, 86, 62, 59, 58, 48, 49, 57, - 57, 51, 61, 76, 78, 83, 93, 102, 83, 67, 50, 36, 22, 12, 14, 24, - 14, 9, 8, 12, 16, 15, 17, 23, 52, 79, 105, 129, 153, 155, 152, 159, - 153, 160, 168, 169, 166, 164, 165, 168, 166, 166, 167, 168, 169, 169, 169, 169, - 168, 173, 168, 164, 167, 162, 156, 159, 156, 155, 154, 155, 155, 153, 150, 147, - 139, 153, 138, 148, 64, 32, 47, 41, 34, 32, 24, 37, 38, 24, 27, 25, - 31, 28, 27, 25, 20, 19, 27, 37, 25, 13, 15, 24, 24, 28, 31, 26, - 36, 33, 20, 16, 26, 29, 34, 51, 110, 142, 167, 170, 171, 182, 184, 178, - 191, 190, 189, 187, 186, 187, 188, 188, 190, 190, 189, 188, 188, 189, 190, 190, - 187, 186, 184, 184, 184, 182, 179, 177, 170, 172, 181, 158, 101, 27, 53, 25, - 27, 26, 26, 27, 27, 28, 30, 31, 22, 29, 34, 33, 29, 27, 31, 36, - 37, 24, 31, 38, 42, 35, 37, 78, 110, 116, 115, 122, 147, 162, 164, 166, - 167, 166, 162, 158, 160, 162, 157, 149, 164, 156, 150, 151, 154, 153, 153, 154, - 151, 150, 142, 140, 146, 141, 135, 141, 140, 139, 143, 135, 112, 93, 75, 56, - 36, 32, 37, 42, 34, 36, 48, 53, 43, 57, 72, 58, 40, 27, 22, 15, - 7, 9, 17, 9, 6, 7, 11, 15, 17, 21, 30, 52, 75, 102, 130, 153, - 155, 153, 162, 150, 155, 164, 168, 168, 166, 164, 164, 165, 166, 168, 170, 171, - 171, 171, 170, 169, 175, 170, 166, 170, 164, 157, 161, 154, 152, 151, 151, 151, - 150, 147, 145, 137, 153, 128, 137, 16, 49, 40, 35, 32, 35, 24, 38, 39, - 24, 30, 21, 25, 22, 24, 29, 28, 22, 19, 21, 36, 25, 27, 32, 27, - 28, 32, 28, 21, 25, 24, 34, 47, 36, 32, 53, 135, 158, 180, 187, 190, - 195, 193, 187, 194, 193, 192, 190, 190, 191, 192, 192, 192, 191, 191, 191, 192, - 193, 194, 195, 190, 188, 186, 185, 185, 182, 178, 175, 169, 179, 164, 153, 30, - 44, 34, 24, 29, 28, 29, 29, 29, 28, 27, 28, 25, 28, 31, 31, 29, - 27, 28, 29, 36, 32, 38, 36, 42, 42, 35, 58, 115, 120, 112, 109, 126, - 145, 160, 175, 165, 165, 162, 158, 159, 161, 158, 151, 166, 158, 150, 152, 155, - 153, 154, 154, 152, 153, 147, 145, 146, 136, 129, 136, 148, 140, 142, 142, 135, - 126, 102, 71, 47, 33, 38, 53, 49, 41, 41, 41, 49, 54, 56, 28, 14, - 11, 19, 22, 12, 4, 4, 15, 12, 9, 11, 10, 14, 23, 38, 54, 77, - 103, 130, 151, 150, 145, 154, 154, 156, 163, 171, 176, 176, 170, 165, 164, 166, - 168, 170, 171, 172, 171, 171, 167, 173, 168, 165, 168, 163, 156, 160, 152, 150, - 148, 147, 148, 147, 145, 144, 146, 136, 141, 70, 43, 34, 34, 40, 31, 40, - 23, 29, 29, 22, 32, 17, 36, 26, 22, 27, 31, 28, 25, 25, 25, 18, - 22, 26, 18, 18, 25, 25, 26, 30, 24, 30, 39, 32, 50, 99, 162, 173, - 178, 177, 176, 182, 188, 191, 194, 194, 192, 191, 191, 193, 196, 197, 194, 193, - 192, 191, 191, 191, 191, 192, 190, 188, 186, 185, 184, 180, 176, 172, 176, 177, - 157, 108, 26, 47, 13, 42, 29, 30, 30, 30, 28, 26, 24, 22, 29, 27, - 27, 28, 29, 28, 25, 22, 27, 36, 45, 33, 39, 46, 27, 28, 99, 125, - 136, 127, 118, 114, 125, 145, 161, 163, 161, 158, 158, 160, 158, 154, 160, 155, - 152, 157, 160, 157, 151, 148, 147, 151, 150, 151, 152, 142, 138, 150, 135, 134, - 145, 153, 152, 150, 131, 101, 70, 38, 30, 47, 49, 44, 45, 48, 53, 49, - 45, 23, 19, 17, 15, 13, 12, 10, 9, 12, 11, 14, 14, 11, 11, 19, - 32, 66, 88, 104, 123, 150, 164, 160, 159, 156, 160, 167, 173, 179, 181, 173, - 164, 156, 157, 161, 167, 172, 175, 174, 172, 171, 168, 166, 165, 164, 162, 156, - 151, 155, 148, 151, 154, 146, 145, 146, 140, 162, 120, 126, 49, 35, 47, 29, - 35, 34, 30, 29, 32, 36, 35, 29, 23, 19, 28, 29, 27, 28, 23, 23, - 35, 27, 28, 27, 25, 22, 23, 25, 28, 28, 24, 24, 39, 55, 67, 100, - 148, 175, 180, 184, 187, 188, 189, 190, 193, 194, 195, 195, 195, 195, 195, 195, - 194, 195, 195, 194, 193, 193, 192, 191, 191, 191, 194, 192, 185, 179, 179, 178, - 176, 185, 158, 161, 55, 41, 30, 27, 28, 28, 25, 33, 37, 27, 25, 27, - 22, 32, 24, 31, 31, 22, 33, 41, 26, 33, 35, 37, 39, 40, 39, 37, - 36, 82, 129, 125, 133, 137, 133, 106, 132, 139, 157, 169, 166, 160, 160, 166, - 168, 165, 159, 157, 160, 159, 153, 150, 153, 155, 153, 151, 150, 150, 146, 143, - 142, 130, 139, 143, 142, 144, 147, 137, 124, 65, 31, 40, 62, 53, 50, 54, - 40, 50, 48, 45, 14, 11, 9, 7, 6, 5, 6, 6, 9, 9, 12, 14, - 13, 13, 20, 33, 54, 86, 112, 128, 143, 147, 146, 151, 167, 167, 170, 170, - 175, 179, 177, 171, 172, 169, 166, 165, 167, 169, 170, 170, 170, 168, 166, 166, - 166, 163, 158, 154, 148, 142, 147, 150, 145, 146, 149, 144, 146, 140, 98, 39, - 40, 40, 33, 32, 29, 26, 25, 28, 31, 30, 25, 20, 23, 28, 25, 23, - 25, 19, 17, 27, 24, 26, 28, 28, 28, 28, 27, 27, 32, 26, 34, 78, - 132, 153, 156, 166, 171, 176, 180, 184, 185, 186, 188, 190, 197, 197, 198, 198, - 197, 197, 197, 196, 193, 193, 192, 192, 192, 191, 191, 191, 188, 188, 184, 180, - 180, 182, 179, 174, 173, 162, 129, 28, 28, 27, 23, 33, 23, 23, 25, 21, - 15, 23, 32, 31, 15, 25, 39, 39, 29, 29, 30, 23, 31, 33, 35, 37, - 38, 38, 37, 36, 61, 122, 126, 131, 135, 132, 127, 125, 128, 140, 150, 154, - 156, 162, 165, 164, 161, 154, 151, 154, 155, 152, 149, 151, 151, 153, 154, 152, - 147, 142, 142, 144, 137, 141, 145, 147, 151, 150, 139, 128, 109, 70, 54, 56, - 45, 44, 53, 53, 57, 54, 51, 13, 10, 8, 7, 6, 8, 9, 9, 6, - 5, 7, 10, 9, 10, 16, 28, 74, 103, 126, 141, 158, 160, 154, 156, 158, - 166, 176, 181, 185, 182, 171, 159, 166, 165, 165, 167, 171, 174, 175, 175, 167, - 166, 165, 165, 166, 163, 158, 154, 147, 141, 145, 148, 144, 147, 149, 142, 136, - 154, 63, 35, 45, 36, 40, 33, 26, 22, 22, 25, 28, 27, 22, 18, 26, - 26, 20, 21, 27, 21, 17, 25, 37, 33, 28, 25, 26, 28, 29, 31, 28, - 46, 74, 116, 158, 169, 164, 167, 174, 178, 183, 186, 187, 189, 191, 193, 196, - 196, 197, 197, 197, 197, 197, 197, 191, 191, 191, 191, 191, 190, 190, 190, 187, - 184, 180, 178, 183, 187, 182, 174, 173, 167, 96, 21, 28, 33, 21, 32, 37, - 37, 30, 23, 30, 41, 36, 18, 22, 28, 24, 22, 29, 32, 30, 31, 28, - 29, 32, 34, 36, 36, 36, 36, 38, 102, 130, 129, 134, 133, 147, 121, 129, - 134, 140, 148, 158, 167, 168, 165, 164, 156, 151, 153, 157, 156, 155, 154, 149, - 155, 158, 154, 146, 142, 144, 147, 143, 139, 141, 150, 157, 151, 140, 131, 113, - 80, 53, 46, 44, 40, 45, 51, 43, 42, 42, 8, 9, 10, 11, 11, 12, - 12, 11, 8, 7, 7, 10, 10, 9, 13, 22, 56, 90, 117, 130, 141, 144, - 145, 155, 149, 161, 175, 182, 184, 179, 166, 154, 157, 160, 167, 173, 178, 177, - 172, 168, 166, 166, 166, 165, 164, 160, 155, 151, 152, 146, 148, 149, 144, 147, - 148, 137, 141, 130, 35, 37, 41, 37, 40, 28, 27, 25, 24, 26, 28, 28, - 24, 21, 24, 23, 18, 22, 31, 24, 19, 27, 25, 25, 27, 31, 38, 41, - 40, 39, 73, 110, 140, 153, 160, 160, 165, 178, 175, 179, 184, 188, 189, 191, - 192, 195, 193, 194, 194, 195, 194, 196, 195, 195, 194, 193, 193, 192, 191, 190, - 189, 189, 187, 187, 184, 182, 185, 188, 184, 177, 165, 141, 58, 30, 30, 38, - 25, 28, 13, 33, 35, 24, 27, 36, 30, 18, 29, 39, 30, 23, 32, 30, - 27, 40, 28, 29, 31, 34, 36, 37, 37, 38, 31, 69, 134, 130, 135, 140, - 150, 128, 140, 140, 142, 146, 155, 163, 166, 167, 168, 161, 155, 155, 159, 160, - 158, 155, 152, 157, 158, 154, 149, 148, 148, 146, 142, 133, 135, 150, 158, 151, - 140, 135, 124, 94, 58, 47, 56, 55, 52, 59, 45, 46, 46, 2, 4, 8, - 12, 13, 13, 10, 8, 16, 13, 12, 14, 12, 9, 11, 17, 31, 75, 116, - 133, 141, 146, 155, 174, 157, 161, 164, 165, 167, 171, 172, 170, 172, 174, 176, - 178, 177, 171, 162, 156, 169, 170, 171, 170, 167, 161, 156, 152, 155, 151, 153, - 153, 148, 151, 149, 133, 145, 79, 24, 43, 30, 38, 32, 22, 25, 24, 25, - 27, 28, 27, 26, 24, 23, 22, 18, 25, 32, 25, 21, 34, 32, 46, 67, - 88, 102, 105, 101, 96, 133, 154, 164, 164, 172, 176, 176, 182, 173, 177, 180, - 184, 186, 187, 189, 191, 191, 192, 192, 194, 193, 195, 194, 195, 198, 197, 195, - 194, 192, 190, 189, 188, 186, 189, 189, 185, 182, 183, 181, 177, 158, 102, 27, - 33, 22, 33, 32, 40, 79, 103, 90, 44, 18, 15, 26, 42, 16, 40, 47, - 43, 41, 25, 17, 34, 29, 30, 32, 34, 36, 37, 38, 40, 38, 40, 129, - 131, 137, 147, 140, 142, 143, 143, 142, 142, 143, 148, 156, 164, 166, 161, 155, - 154, 156, 159, 155, 151, 153, 154, 152, 148, 150, 153, 149, 141, 138, 131, 135, - 150, 159, 153, 144, 141, 146, 109, 59, 39, 48, 52, 51, 57, 49, 50, 48, - 3, 6, 11, 16, 18, 17, 13, 10, 14, 10, 9, 10, 8, 5, 5, 8, - 4, 29, 58, 88, 125, 143, 141, 141, 151, 157, 163, 165, 167, 171, 172, 170, - 184, 182, 177, 174, 171, 169, 166, 163, 172, 174, 176, 175, 171, 165, 161, 157, - 155, 153, 157, 157, 153, 157, 150, 130, 132, 44, 32, 49, 31, 40, 32, 25, - 24, 23, 25, 25, 25, 25, 25, 24, 23, 23, 21, 25, 29, 20, 26, 48, - 89, 100, 115, 129, 141, 150, 157, 161, 154, 164, 166, 164, 173, 174, 172, 175, - 176, 180, 184, 186, 187, 188, 189, 191, 192, 192, 193, 194, 194, 195, 196, 196, - 198, 197, 196, 194, 192, 190, 189, 188, 184, 189, 190, 185, 180, 178, 177, 174, - 180, 116, 47, 38, 23, 31, 35, 74, 122, 159, 170, 157, 141, 98, 39, 12, - 38, 35, 28, 31, 41, 38, 28, 28, 31, 31, 32, 34, 35, 37, 38, 39, - 44, 32, 106, 130, 139, 149, 136, 152, 144, 144, 145, 143, 139, 139, 149, 160, - 161, 162, 160, 157, 157, 159, 157, 153, 151, 152, 147, 143, 148, 154, 149, 136, - 137, 135, 141, 152, 158, 156, 150, 146, 137, 102, 67, 52, 51, 51, 50, 45, - 48, 48, 48, 9, 11, 13, 16, 17, 17, 17, 16, 12, 7, 5, 7, 6, - 2, 0, 3, 14, 19, 27, 55, 105, 136, 136, 131, 138, 151, 164, 170, 171, - 169, 164, 159, 174, 172, 169, 169, 170, 172, 173, 173, 168, 172, 176, 176, 173, - 168, 164, 162, 158, 158, 162, 161, 155, 157, 147, 122, 90, 38, 42, 42, 37, - 34, 33, 31, 23, 23, 24, 24, 24, 23, 25, 25, 24, 25, 23, 24, 25, - 22, 43, 79, 127, 130, 132, 132, 135, 143, 158, 170, 167, 178, 180, 179, 181, - 174, 174, 187, 181, 183, 187, 189, 189, 189, 190, 191, 190, 190, 191, 191, 192, - 193, 194, 195, 194, 194, 193, 193, 192, 191, 191, 190, 185, 188, 187, 183, 182, - 181, 177, 171, 187, 157, 91, 36, 32, 34, 29, 113, 153, 164, 152, 149, 172, - 158, 120, 108, 105, 73, 50, 44, 43, 44, 40, 31, 31, 31, 32, 32, 33, - 35, 36, 37, 40, 45, 72, 126, 140, 143, 147, 152, 149, 148, 150, 150, 143, - 138, 142, 151, 153, 160, 163, 160, 158, 160, 161, 158, 150, 154, 151, 145, 147, - 153, 151, 138, 135, 141, 148, 152, 154, 155, 151, 145, 132, 106, 95, 87, 70, - 67, 71, 59, 65, 63, 64, 8, 7, 7, 8, 9, 10, 13, 14, 15, 10, - 9, 12, 12, 9, 8, 10, 0, 14, 20, 23, 43, 70, 100, 129, 139, 148, - 154, 155, 155, 160, 164, 164, 161, 163, 165, 168, 171, 171, 168, 166, 161, 167, - 171, 174, 170, 166, 163, 162, 163, 163, 167, 163, 155, 154, 141, 113, 46, 39, - 41, 26, 37, 20, 28, 28, 24, 25, 26, 26, 26, 25, 26, 27, 23, 25, - 25, 25, 26, 29, 60, 107, 134, 145, 157, 160, 156, 154, 159, 164, 176, 175, - 172, 178, 188, 184, 180, 190, 179, 182, 184, 186, 185, 185, 186, 187, 187, 188, - 188, 189, 190, 191, 192, 192, 189, 189, 189, 191, 190, 192, 192, 192, 189, 188, - 185, 183, 187, 188, 181, 171, 156, 169, 110, 21, 36, 35, 19, 137, 141, 168, - 165, 162, 177, 165, 152, 171, 156, 140, 133, 107, 53, 28, 34, 35, 31, 31, - 31, 31, 31, 32, 34, 35, 32, 61, 46, 122, 139, 137, 160, 148, 151, 149, - 150, 152, 145, 135, 132, 136, 142, 153, 159, 157, 154, 157, 158, 157, 150, 159, - 158, 150, 149, 154, 153, 144, 133, 145, 152, 148, 147, 151, 147, 140, 141, 112, - 104, 89, 55, 55, 75, 67, 71, 66, 63, 10, 4, 1, 2, 7, 12, 13, - 13, 10, 4, 7, 10, 7, 11, 14, 8, 17, 16, 13, 13, 11, 8, 27, - 68, 123, 129, 137, 144, 150, 154, 158, 159, 165, 159, 158, 159, 164, 167, 167, - 165, 162, 165, 166, 165, 163, 162, 163, 168, 172, 169, 162, 154, 159, 168, 136, - 81, 35, 40, 38, 30, 28, 34, 34, 29, 29, 27, 24, 23, 24, 29, 34, - 36, 33, 31, 25, 27, 46, 80, 107, 121, 141, 146, 150, 151, 152, 156, 162, - 168, 168, 178, 183, 182, 181, 185, 183, 178, 185, 187, 188, 184, 183, 188, 191, - 191, 187, 191, 193, 192, 192, 193, 195, 195, 191, 188, 185, 187, 189, 191, 190, - 188, 188, 182, 186, 189, 183, 185, 185, 176, 164, 111, 78, 41, 37, 28, 27, - 114, 157, 154, 160, 172, 175, 172, 174, 182, 165, 179, 177, 165, 138, 79, 30, - 27, 30, 29, 40, 43, 33, 29, 34, 36, 42, 39, 53, 100, 141, 142, 142, - 156, 148, 156, 159, 154, 145, 141, 138, 135, 136, 149, 161, 163, 158, 159, 159, - 158, 157, 158, 157, 154, 147, 142, 138, 137, 145, 143, 145, 152, 153, 148, 145, - 142, 143, 123, 116, 80, 65, 70, 61, 72, 65, 61, 60, 11, 11, 11, 11, - 11, 9, 9, 9, 14, 7, 10, 13, 11, 14, 17, 12, 7, 14, 16, 19, - 18, 2, 0, 13, 54, 100, 127, 123, 127, 153, 161, 147, 155, 154, 154, 156, - 155, 156, 159, 162, 161, 165, 166, 163, 156, 155, 160, 168, 179, 174, 170, 164, - 159, 149, 102, 42, 49, 47, 46, 44, 37, 29, 28, 32, 29, 28, 29, 31, - 33, 30, 23, 18, 40, 29, 39, 76, 107, 117, 124, 137, 142, 148, 156, 160, - 160, 159, 161, 163, 167, 174, 179, 177, 178, 183, 185, 183, 180, 183, 184, 182, - 185, 189, 189, 185, 196, 190, 183, 180, 184, 188, 186, 181, 189, 185, 184, 184, - 186, 188, 189, 188, 189, 182, 186, 187, 182, 183, 184, 176, 175, 129, 85, 32, - 29, 36, 31, 94, 155, 144, 146, 161, 168, 159, 155, 162, 154, 167, 172, 177, - 177, 143, 80, 32, 50, 32, 21, 27, 34, 34, 34, 36, 42, 31, 49, 75, - 127, 142, 143, 147, 147, 153, 155, 150, 145, 142, 138, 133, 143, 133, 145, 166, - 167, 160, 161, 165, 161, 161, 160, 157, 152, 149, 145, 144, 148, 146, 148, 153, - 153, 148, 142, 141, 144, 130, 115, 78, 50, 63, 59, 71, 68, 66, 65, 7, - 12, 17, 17, 13, 8, 7, 8, 15, 8, 12, 15, 11, 14, 17, 11, 10, - 17, 13, 10, 16, 12, 6, 10, 18, 53, 97, 126, 140, 144, 142, 138, 147, - 152, 156, 155, 151, 151, 159, 166, 160, 164, 166, 162, 156, 156, 162, 171, 159, - 169, 176, 160, 130, 114, 104, 88, 49, 48, 38, 30, 35, 45, 37, 19, 32, - 28, 22, 22, 28, 34, 39, 39, 36, 40, 67, 110, 134, 134, 132, 140, 146, - 152, 159, 163, 164, 164, 166, 169, 168, 172, 175, 174, 175, 181, 185, 186, 183, - 185, 184, 183, 186, 190, 187, 181, 177, 178, 182, 187, 189, 187, 182, 177, 187, - 183, 182, 182, 184, 187, 189, 188, 190, 182, 185, 185, 179, 180, 182, 174, 169, - 130, 81, 26, 30, 44, 19, 35, 96, 143, 163, 142, 136, 162, 169, 155, 174, - 175, 170, 161, 164, 158, 106, 36, 20, 40, 40, 28, 33, 40, 34, 26, 43, - 26, 46, 48, 103, 144, 146, 142, 149, 152, 152, 149, 148, 147, 142, 135, 143, - 124, 134, 156, 160, 165, 169, 160, 165, 162, 158, 157, 157, 155, 152, 149, 149, - 147, 148, 152, 153, 148, 142, 141, 141, 138, 116, 85, 32, 48, 42, 53, 52, - 55, 60, 4, 8, 13, 14, 13, 10, 8, 8, 12, 5, 10, 13, 9, 13, - 16, 11, 14, 21, 11, 2, 10, 19, 20, 25, 7, 12, 38, 80, 110, 119, - 122, 129, 143, 149, 153, 152, 150, 151, 156, 162, 158, 160, 161, 161, 160, 162, - 166, 170, 179, 160, 152, 154, 158, 165, 162, 147, 150, 119, 78, 48, 33, 31, - 38, 46, 31, 33, 34, 33, 30, 27, 26, 26, 53, 84, 112, 119, 120, 129, - 136, 139, 148, 150, 150, 150, 151, 156, 165, 172, 167, 170, 172, 173, 174, 177, - 181, 183, 184, 186, 186, 182, 181, 182, 180, 176, 178, 179, 181, 177, 171, 171, - 183, 196, 181, 181, 183, 185, 186, 187, 187, 187, 190, 182, 184, 184, 177, 178, - 180, 173, 177, 159, 123, 64, 45, 47, 27, 35, 47, 70, 113, 149, 151, 136, - 138, 156, 159, 158, 162, 157, 156, 175, 164, 119, 29, 45, 44, 36, 40, 37, - 29, 28, 42, 32, 43, 38, 71, 145, 148, 147, 154, 154, 152, 151, 154, 155, - 149, 140, 139, 132, 136, 136, 137, 166, 178, 151, 167, 161, 156, 155, 157, 157, - 153, 148, 146, 144, 145, 150, 151, 147, 143, 142, 131, 139, 120, 102, 31, 45, - 36, 41, 38, 47, 54, 10, 9, 8, 10, 12, 13, 10, 8, 9, 3, 8, - 12, 9, 14, 19, 13, 5, 21, 19, 9, 13, 15, 10, 9, 9, 18, 17, - 18, 47, 98, 126, 130, 139, 144, 147, 148, 147, 147, 147, 149, 158, 157, 156, - 158, 160, 162, 161, 160, 166, 156, 161, 174, 179, 181, 174, 159, 156, 139, 145, - 156, 117, 48, 16, 27, 25, 28, 31, 29, 30, 42, 61, 79, 108, 132, 145, - 135, 125, 131, 142, 146, 141, 143, 142, 140, 139, 142, 149, 156, 158, 161, 165, - 170, 172, 174, 177, 181, 175, 181, 182, 176, 172, 173, 176, 176, 175, 178, 185, - 190, 184, 173, 169, 171, 174, 178, 184, 188, 188, 187, 186, 185, 189, 182, 184, - 184, 177, 178, 180, 171, 163, 167, 151, 91, 37, 16, 17, 42, 32, 36, 69, - 124, 157, 153, 141, 140, 158, 159, 171, 171, 158, 160, 158, 133, 114, 71, 34, - 33, 40, 30, 28, 44, 35, 41, 39, 42, 42, 134, 148, 157, 156, 155, 153, - 152, 156, 158, 152, 143, 142, 140, 140, 131, 129, 154, 172, 160, 166, 162, 156, - 155, 158, 158, 152, 147, 144, 141, 142, 148, 150, 147, 144, 144, 126, 135, 120, - 116, 41, 48, 47, 47, 41, 49, 54, 18, 13, 9, 9, 12, 13, 11, 7, - 11, 6, 10, 14, 10, 14, 19, 14, 3, 19, 19, 10, 11, 11, 8, 12, - 17, 23, 24, 20, 26, 49, 77, 100, 128, 136, 140, 144, 145, 145, 144, 142, - 156, 155, 153, 153, 154, 154, 151, 150, 144, 161, 185, 185, 162, 153, 161, 166, - 153, 152, 149, 141, 129, 103, 63, 32, 33, 43, 56, 66, 79, 104, 134, 157, - 150, 144, 142, 147, 146, 140, 141, 147, 144, 148, 150, 150, 145, 141, 140, 142, - 145, 147, 154, 162, 167, 168, 172, 178, 170, 176, 178, 175, 173, 175, 177, 175, - 172, 164, 167, 184, 193, 187, 172, 164, 170, 175, 182, 186, 187, 185, 184, 184, - 187, 180, 184, 186, 179, 179, 180, 171, 176, 177, 169, 141, 100, 68, 48, 40, - 29, 50, 56, 53, 87, 142, 163, 151, 137, 136, 145, 156, 159, 162, 163, 154, - 151, 128, 93, 48, 20, 32, 45, 34, 30, 44, 35, 46, 31, 107, 150, 162, - 156, 155, 153, 151, 154, 157, 152, 144, 149, 141, 138, 144, 141, 133, 144, 168, - 165, 162, 159, 160, 160, 159, 155, 151, 145, 141, 142, 147, 150, 147, 144, 145, - 139, 134, 117, 116, 44, 34, 43, 37, 30, 38, 41, 12, 11, 9, 9, 10, - 11, 10, 9, 14, 7, 10, 14, 10, 12, 15, 9, 10, 17, 10, 3, 8, - 9, 14, 25, 13, 8, 17, 30, 21, 2, 10, 39, 92, 108, 122, 132, 135, - 138, 141, 146, 150, 152, 153, 149, 146, 147, 152, 158, 181, 173, 171, 171, 171, - 180, 178, 160, 155, 169, 164, 146, 151, 156, 111, 48, 85, 102, 127, 146, 153, - 151, 144, 141, 152, 143, 141, 148, 151, 148, 144, 146, 150, 154, 157, 157, 151, - 147, 145, 145, 141, 140, 145, 151, 155, 156, 162, 170, 170, 171, 172, 173, 177, - 177, 170, 160, 160, 135, 114, 114, 126, 142, 163, 182, 167, 173, 178, 180, 180, - 180, 183, 185, 185, 179, 185, 188, 182, 181, 181, 171, 166, 162, 154, 152, 144, - 125, 86, 36, 49, 27, 21, 31, 38, 51, 96, 149, 162, 165, 156, 150, 155, - 153, 147, 147, 141, 153, 153, 90, 22, 35, 57, 27, 30, 41, 37, 44, 41, - 75, 159, 163, 157, 158, 156, 153, 155, 157, 153, 146, 146, 150, 145, 152, 152, - 118, 108, 144, 160, 160, 161, 163, 161, 160, 157, 154, 151, 146, 146, 149, 150, - 147, 143, 144, 149, 129, 117, 120, 57, 24, 38, 22, 17, 27, 32, 0, 4, - 8, 9, 8, 7, 10, 14, 15, 7, 10, 12, 6, 7, 9, 2, 10, 14, - 8, 6, 12, 7, 4, 11, 20, 26, 25, 18, 16, 20, 20, 18, 48, 72, - 97, 111, 117, 123, 134, 145, 143, 150, 153, 147, 141, 145, 161, 175, 171, 169, - 170, 165, 163, 172, 170, 149, 149, 144, 147, 156, 149, 135, 135, 148, 152, 147, - 142, 140, 143, 148, 149, 151, 139, 157, 161, 148, 145, 158, 162, 153, 150, 152, - 152, 150, 146, 146, 149, 153, 144, 140, 140, 144, 145, 144, 150, 160, 167, 165, - 161, 164, 172, 171, 154, 134, 86, 80, 80, 82, 79, 81, 103, 130, 168, 172, - 174, 174, 174, 176, 182, 186, 183, 178, 185, 190, 184, 183, 182, 171, 169, 174, - 167, 158, 149, 150, 137, 96, 61, 44, 39, 47, 42, 33, 47, 75, 116, 141, - 142, 138, 149, 154, 148, 154, 161, 129, 140, 126, 54, 29, 50, 46, 35, 38, - 42, 41, 57, 56, 168, 162, 160, 162, 160, 157, 157, 158, 155, 150, 135, 163, - 158, 148, 150, 113, 84, 107, 152, 154, 159, 161, 161, 159, 157, 157, 156, 151, - 149, 152, 151, 147, 143, 143, 144, 118, 118, 131, 81, 34, 49, 26, 26, 34, - 40, 7, 9, 9, 6, 6, 11, 14, 12, 11, 12, 12, 11, 10, 9, 7, - 7, 11, 13, 12, 10, 8, 8, 10, 13, 14, 18, 20, 18, 19, 17, 11, - 7, 29, 13, 61, 111, 97, 105, 136, 132, 137, 149, 142, 131, 145, 164, 167, - 165, 167, 162, 158, 159, 161, 158, 149, 141, 154, 145, 136, 137, 136, 137, 146, - 155, 143, 142, 139, 138, 140, 143, 146, 148, 152, 155, 157, 158, 158, 154, 149, - 146, 164, 156, 149, 150, 157, 160, 156, 150, 153, 150, 148, 148, 150, 150, 148, - 145, 148, 153, 145, 138, 151, 156, 117, 65, 73, 82, 53, 60, 70, 82, 91, - 100, 147, 170, 174, 165, 168, 174, 178, 184, 178, 176, 177, 180, 185, 186, 180, - 175, 174, 176, 170, 159, 153, 153, 149, 143, 120, 91, 57, 38, 40, 44, 39, - 31, 44, 103, 153, 154, 138, 139, 146, 148, 148, 153, 164, 131, 117, 51, 24, - 57, 45, 35, 42, 52, 38, 79, 159, 173, 155, 167, 166, 154, 152, 161, 160, - 149, 139, 150, 151, 151, 155, 138, 105, 83, 117, 161, 160, 165, 163, 158, 165, - 153, 155, 153, 149, 144, 144, 146, 141, 135, 132, 123, 119, 127, 89, 39, 46, - 57, 43, 53, 73, 8, 10, 9, 6, 6, 11, 13, 11, 11, 11, 11, 11, - 10, 9, 8, 8, 11, 12, 11, 9, 7, 9, 12, 15, 10, 14, 17, 17, - 19, 22, 18, 15, 29, 8, 30, 65, 79, 111, 133, 112, 107, 102, 103, 128, - 157, 164, 169, 187, 146, 145, 145, 148, 152, 154, 150, 146, 145, 142, 141, 146, - 144, 139, 138, 141, 144, 144, 145, 146, 147, 148, 148, 148, 151, 153, 154, 155, - 154, 152, 148, 146, 157, 150, 146, 147, 153, 156, 154, 150, 153, 153, 153, 155, - 157, 155, 152, 148, 147, 147, 139, 130, 120, 110, 91, 74, 58, 75, 76, 65, - 59, 69, 75, 83, 100, 134, 160, 169, 179, 180, 173, 172, 184, 183, 183, 180, - 178, 176, 175, 175, 172, 176, 172, 164, 161, 161, 158, 153, 144, 145, 130, 96, - 56, 33, 35, 47, 29, 47, 78, 117, 150, 161, 150, 134, 166, 155, 151, 146, - 158, 107, 35, 21, 35, 38, 40, 47, 52, 101, 169, 175, 156, 163, 165, 159, - 157, 161, 158, 149, 141, 147, 146, 147, 150, 135, 102, 77, 34, 107, 137, 145, - 145, 152, 172, 165, 151, 151, 150, 146, 147, 148, 142, 135, 144, 127, 114, 123, - 98, 59, 58, 54, 68, 70, 78, 9, 12, 12, 8, 7, 11, 11, 9, 9, - 9, 11, 11, 11, 10, 9, 10, 11, 12, 10, 9, 7, 10, 13, 17, 11, - 13, 15, 15, 19, 23, 21, 19, 25, 22, 19, 12, 16, 43, 56, 39, 24, - 56, 104, 155, 176, 153, 132, 137, 144, 147, 151, 156, 158, 160, 160, 159, 144, - 144, 146, 151, 148, 142, 137, 137, 140, 143, 147, 150, 149, 148, 146, 144, 146, - 148, 148, 148, 146, 146, 145, 143, 147, 145, 143, 145, 147, 150, 150, 150, 152, - 154, 157, 164, 166, 167, 162, 158, 154, 148, 145, 142, 120, 87, 66, 66, 60, - 63, 36, 52, 51, 72, 61, 102, 116, 145, 165, 173, 184, 188, 186, 188, 185, - 186, 186, 182, 175, 175, 180, 186, 174, 176, 176, 172, 170, 170, 167, 162, 153, - 158, 157, 142, 118, 102, 100, 105, 91, 63, 49, 69, 97, 118, 139, 158, 146, - 146, 141, 147, 155, 130, 55, 34, 30, 44, 38, 49, 83, 134, 180, 177, 159, - 159, 160, 162, 163, 160, 154, 150, 146, 145, 146, 147, 146, 133, 105, 79, 42, - 57, 80, 127, 163, 155, 165, 176, 150, 151, 151, 148, 148, 148, 143, 136, 131, - 120, 110, 118, 103, 77, 80, 70, 80, 77, 71, 10, 13, 13, 9, 8, 10, - 10, 6, 8, 8, 10, 11, 11, 11, 10, 11, 11, 11, 9, 9, 8, 11, - 16, 20, 15, 16, 15, 13, 14, 18, 17, 15, 17, 29, 22, 5, 7, 21, - 25, 23, 22, 91, 141, 148, 144, 143, 139, 139, 153, 158, 164, 167, 164, 161, - 158, 159, 150, 149, 146, 146, 145, 144, 144, 146, 142, 144, 147, 150, 151, 149, - 146, 144, 148, 147, 147, 146, 146, 145, 146, 146, 145, 146, 146, 146, 146, 145, - 147, 149, 149, 152, 159, 166, 170, 173, 171, 169, 167, 153, 148, 151, 142, 115, - 92, 83, 66, 84, 71, 44, 58, 63, 100, 88, 135, 153, 160, 159, 167, 174, - 179, 189, 190, 191, 191, 187, 181, 179, 184, 188, 179, 181, 182, 181, 178, 175, - 171, 168, 173, 166, 161, 161, 164, 161, 151, 141, 143, 123, 110, 107, 100, 93, - 109, 133, 145, 157, 156, 157, 143, 131, 62, 43, 33, 46, 36, 66, 127, 166, - 183, 178, 164, 155, 154, 161, 163, 156, 150, 150, 148, 145, 150, 153, 145, 134, - 116, 94, 76, 37, 33, 79, 142, 139, 146, 161, 151, 153, 152, 148, 146, 146, - 143, 138, 132, 133, 126, 121, 91, 64, 70, 61, 68, 71, 66, 10, 14, 13, - 9, 8, 10, 9, 5, 9, 9, 10, 11, 12, 12, 11, 11, 10, 11, 11, - 10, 10, 13, 18, 21, 19, 19, 17, 14, 14, 18, 17, 14, 22, 25, 17, - 17, 32, 33, 23, 24, 50, 118, 150, 128, 121, 143, 157, 158, 150, 157, 163, - 163, 156, 148, 142, 141, 148, 147, 144, 142, 142, 146, 149, 151, 150, 151, 152, - 153, 153, 153, 152, 152, 154, 152, 151, 151, 151, 152, 153, 154, 148, 151, 152, - 150, 148, 146, 146, 148, 149, 153, 158, 163, 165, 168, 169, 169, 168, 159, 146, - 143, 146, 149, 142, 132, 101, 99, 36, 112, 49, 63, 105, 123, 129, 148, 157, - 161, 170, 172, 172, 179, 197, 195, 193, 191, 187, 184, 181, 179, 184, 185, 187, - 189, 188, 184, 180, 178, 175, 175, 174, 170, 165, 162, 163, 164, 164, 158, 153, - 149, 141, 129, 117, 110, 123, 128, 128, 140, 142, 143, 70, 29, 37, 44, 40, - 93, 165, 183, 181, 180, 169, 155, 149, 156, 160, 153, 148, 150, 145, 141, 155, - 159, 145, 135, 127, 110, 62, 52, 50, 41, 95, 123, 149, 154, 154, 156, 153, - 146, 142, 143, 141, 138, 123, 127, 122, 117, 89, 66, 72, 61, 62, 67, 64, - 10, 13, 13, 10, 9, 10, 9, 5, 10, 10, 11, 11, 12, 11, 10, 9, - 10, 11, 12, 13, 12, 14, 17, 20, 19, 21, 19, 17, 19, 23, 22, 17, - 15, 19, 19, 24, 26, 16, 15, 31, 74, 115, 138, 141, 149, 153, 147, 140, - 150, 155, 159, 159, 152, 145, 139, 137, 137, 141, 143, 144, 146, 149, 149, 147, - 153, 152, 151, 151, 151, 152, 151, 152, 150, 150, 150, 150, 151, 151, 152, 153, - 154, 156, 157, 156, 153, 151, 150, 150, 151, 155, 159, 161, 161, 163, 162, 163, - 156, 164, 163, 151, 147, 156, 156, 147, 154, 142, 165, 252, 76, 57, 119, 116, - 144, 158, 163, 167, 176, 177, 177, 186, 187, 188, 190, 193, 193, 192, 189, 186, - 188, 188, 191, 196, 197, 194, 192, 193, 180, 180, 177, 172, 168, 168, 172, 178, - 171, 173, 166, 154, 151, 154, 152, 144, 142, 133, 133, 139, 147, 151, 96, 55, - 43, 53, 62, 124, 183, 182, 178, 182, 174, 159, 149, 152, 157, 153, 148, 146, - 143, 134, 152, 161, 145, 137, 136, 119, 67, 50, 63, 48, 99, 115, 137, 149, - 151, 154, 153, 146, 142, 142, 140, 138, 125, 120, 110, 113, 95, 72, 72, 54, - 42, 45, 44, 8, 11, 12, 9, 10, 11, 10, 6, 11, 11, 11, 11, 10, - 9, 8, 7, 8, 11, 13, 14, 14, 16, 16, 18, 18, 20, 20, 18, 20, - 24, 23, 17, 2, 10, 23, 29, 26, 34, 64, 96, 126, 137, 141, 147, 161, - 163, 159, 161, 154, 154, 153, 150, 148, 145, 144, 143, 137, 142, 146, 145, 148, - 153, 153, 149, 150, 150, 150, 150, 149, 149, 149, 149, 148, 147, 148, 149, 150, - 150, 151, 152, 157, 159, 159, 159, 158, 157, 155, 153, 153, 159, 166, 169, 168, - 168, 166, 166, 157, 169, 174, 165, 157, 156, 151, 142, 146, 173, 137, 60, 155, - 148, 160, 155, 155, 162, 158, 158, 167, 172, 178, 192, 184, 190, 196, 198, 197, - 195, 197, 198, 191, 189, 191, 198, 199, 195, 195, 198, 206, 195, 184, 180, 183, - 183, 176, 169, 163, 177, 182, 176, 167, 165, 164, 162, 162, 144, 146, 124, 115, - 99, 62, 30, 59, 84, 107, 155, 182, 172, 176, 181, 175, 164, 153, 153, 158, - 158, 149, 140, 148, 130, 148, 162, 149, 144, 143, 119, 77, 29, 48, 60, 126, - 114, 113, 128, 141, 148, 152, 148, 144, 143, 140, 137, 143, 134, 120, 119, 89, - 52, 45, 29, 29, 30, 36, 8, 12, 12, 9, 10, 12, 10, 7, 12, 12, - 12, 11, 10, 9, 7, 7, 8, 11, 14, 16, 16, 15, 16, 17, 17, 19, - 19, 17, 18, 21, 19, 11, 24, 15, 15, 21, 36, 71, 108, 124, 126, 144, - 146, 144, 153, 161, 161, 166, 148, 144, 138, 135, 134, 136, 138, 139, 145, 149, - 148, 145, 147, 154, 158, 156, 152, 153, 153, 154, 153, 153, 151, 151, 152, 153, - 154, 156, 156, 157, 157, 158, 159, 158, 158, 160, 162, 162, 159, 157, 153, 161, - 172, 179, 180, 178, 177, 176, 176, 170, 161, 158, 160, 164, 163, 158, 164, 126, - 153, 163, 143, 166, 148, 156, 151, 160, 162, 168, 181, 186, 192, 205, 199, 207, - 212, 207, 196, 190, 192, 197, 193, 190, 191, 196, 196, 190, 190, 194, 187, 185, - 183, 186, 188, 190, 190, 188, 190, 184, 177, 173, 171, 171, 172, 173, 175, 155, - 174, 158, 161, 133, 93, 52, 77, 117, 148, 176, 175, 163, 175, 178, 176, 167, - 157, 156, 161, 162, 150, 136, 155, 131, 145, 163, 153, 151, 148, 119, 74, 46, - 76, 77, 146, 145, 135, 130, 133, 143, 151, 150, 148, 146, 141, 136, 115, 117, - 118, 121, 84, 44, 48, 50, 62, 58, 62, 11, 11, 11, 10, 10, 9, 10, - 9, 9, 12, 12, 12, 9, 8, 8, 8, 9, 12, 14, 16, 16, 16, 17, - 19, 19, 24, 25, 20, 18, 18, 17, 11, 8, 18, 11, 36, 72, 123, 129, - 136, 147, 158, 148, 159, 140, 127, 102, 113, 113, 119, 123, 124, 127, 136, 143, - 146, 140, 143, 149, 152, 154, 155, 157, 158, 148, 148, 148, 148, 149, 151, 153, - 154, 149, 155, 158, 157, 157, 159, 160, 159, 164, 165, 165, 164, 161, 160, 160, - 161, 164, 174, 174, 173, 179, 176, 172, 177, 178, 172, 166, 163, 160, 159, 156, - 155, 154, 154, 151, 154, 157, 158, 155, 152, 161, 163, 165, 162, 158, 162, 174, - 183, 202, 210, 208, 193, 184, 187, 189, 186, 181, 183, 189, 193, 189, 184, 187, - 194, 189, 187, 184, 182, 179, 178, 178, 179, 179, 189, 191, 182, 180, 188, 191, - 186, 176, 171, 174, 174, 163, 151, 129, 101, 122, 145, 167, 177, 178, 179, 176, - 171, 184, 168, 155, 159, 167, 163, 150, 139, 149, 157, 147, 133, 152, 178, 162, - 121, 99, 40, 75, 119, 145, 142, 158, 169, 142, 129, 142, 155, 145, 141, 142, - 128, 126, 117, 117, 121, 69, 71, 69, 60, 70, 81, 82, 10, 10, 10, 10, - 11, 11, 12, 12, 9, 11, 12, 11, 9, 8, 10, 10, 11, 14, 16, 17, - 16, 16, 17, 18, 22, 27, 25, 19, 15, 17, 14, 10, 25, 21, 31, 83, - 104, 126, 128, 145, 135, 157, 165, 121, 89, 58, 34, 50, 52, 74, 102, 123, - 135, 141, 140, 137, 147, 150, 154, 155, 154, 153, 153, 154, 151, 150, 150, 151, - 152, 154, 155, 156, 155, 160, 162, 160, 158, 160, 160, 159, 163, 166, 168, 168, - 165, 164, 165, 165, 161, 170, 170, 169, 175, 173, 169, 174, 168, 166, 164, 162, - 161, 160, 157, 154, 154, 153, 152, 155, 160, 164, 163, 162, 161, 162, 163, 165, - 165, 165, 165, 167, 177, 192, 199, 194, 189, 190, 185, 179, 185, 183, 185, 191, - 193, 189, 186, 187, 187, 186, 184, 183, 182, 182, 181, 181, 179, 188, 190, 182, - 179, 185, 185, 180, 195, 187, 185, 182, 174, 174, 167, 150, 152, 167, 178, 179, - 176, 176, 176, 173, 182, 173, 167, 171, 173, 166, 152, 144, 138, 152, 160, 156, - 155, 153, 141, 125, 103, 57, 95, 133, 154, 148, 157, 161, 181, 148, 135, 144, - 148, 153, 149, 126, 122, 112, 114, 121, 71, 66, 66, 67, 91, 99, 100, 9, - 9, 10, 11, 11, 12, 14, 14, 10, 11, 13, 13, 11, 11, 13, 14, 14, - 17, 19, 19, 17, 17, 17, 19, 20, 22, 20, 16, 15, 17, 15, 13, 28, - 20, 48, 110, 118, 132, 138, 151, 155, 164, 145, 53, 40, 37, 59, 101, 95, - 114, 133, 142, 143, 143, 142, 140, 146, 149, 151, 152, 150, 148, 148, 148, 154, - 153, 154, 154, 156, 157, 159, 160, 158, 163, 165, 162, 161, 163, 164, 163, 161, - 164, 168, 169, 168, 167, 167, 168, 160, 170, 168, 167, 172, 169, 165, 171, 163, - 163, 163, 164, 164, 162, 158, 154, 154, 153, 153, 156, 162, 168, 171, 173, 172, - 168, 165, 166, 172, 173, 168, 163, 166, 180, 190, 190, 188, 187, 183, 176, 184, - 178, 177, 186, 195, 195, 187, 182, 184, 184, 184, 185, 185, 185, 186, 186, 182, - 190, 192, 186, 183, 186, 184, 178, 189, 182, 180, 175, 169, 176, 181, 172, 172, - 180, 185, 183, 178, 176, 174, 172, 176, 173, 173, 178, 177, 166, 152, 146, 140, - 147, 162, 172, 162, 142, 132, 133, 96, 77, 124, 144, 149, 141, 156, 167, 182, - 148, 127, 130, 140, 149, 142, 120, 122, 114, 115, 115, 69, 58, 61, 67, 76, - 83, 82, 11, 11, 11, 11, 11, 12, 13, 13, 12, 13, 15, 15, 14, 14, - 18, 19, 14, 17, 19, 20, 19, 18, 20, 21, 15, 15, 13, 13, 14, 18, - 20, 20, 28, 32, 64, 115, 113, 144, 155, 147, 155, 154, 98, 37, 43, 41, - 63, 86, 121, 133, 141, 141, 138, 144, 150, 156, 142, 146, 148, 151, 150, 151, - 151, 153, 155, 155, 156, 156, 158, 159, 161, 162, 159, 164, 166, 163, 162, 165, - 167, 165, 160, 164, 167, 169, 167, 165, 164, 164, 164, 172, 169, 168, 172, 169, - 164, 170, 164, 164, 163, 165, 165, 164, 159, 156, 153, 152, 152, 154, 159, 166, - 173, 176, 179, 171, 162, 161, 166, 171, 172, 170, 173, 180, 183, 181, 178, 181, - 182, 180, 180, 174, 171, 180, 190, 192, 188, 185, 182, 183, 184, 184, 185, 185, - 185, 185, 185, 191, 194, 191, 190, 191, 187, 181, 190, 187, 190, 187, 179, 183, - 188, 181, 172, 179, 186, 189, 187, 184, 180, 176, 175, 171, 172, 179, 180, 170, - 157, 150, 155, 149, 152, 164, 167, 155, 144, 144, 106, 93, 130, 136, 147, 147, - 156, 159, 140, 130, 125, 128, 133, 134, 128, 118, 119, 120, 116, 93, 52, 45, - 52, 54, 64, 75, 78, 14, 13, 12, 11, 10, 9, 10, 9, 11, 12, 13, - 13, 12, 14, 16, 20, 14, 15, 18, 20, 19, 20, 21, 22, 15, 12, 10, - 12, 17, 19, 21, 23, 36, 41, 73, 122, 119, 149, 157, 143, 144, 133, 42, - 41, 48, 38, 56, 63, 110, 126, 140, 144, 143, 145, 146, 146, 148, 151, 154, - 155, 156, 157, 160, 162, 156, 156, 156, 157, 158, 160, 161, 162, 163, 167, 168, - 163, 161, 164, 165, 163, 162, 166, 169, 170, 166, 164, 162, 162, 166, 173, 169, - 165, 168, 165, 160, 167, 168, 167, 164, 162, 163, 161, 158, 156, 152, 151, 150, - 151, 153, 159, 165, 169, 173, 170, 164, 159, 159, 163, 166, 169, 175, 177, 176, - 173, 171, 175, 178, 180, 180, 174, 172, 176, 180, 182, 183, 187, 182, 182, 182, - 182, 182, 182, 183, 183, 183, 188, 191, 193, 194, 194, 190, 185, 190, 189, 194, - 191, 181, 184, 188, 181, 173, 175, 180, 186, 189, 189, 186, 185, 179, 170, 166, - 173, 179, 175, 164, 157, 159, 156, 154, 157, 164, 163, 154, 143, 120, 103, 125, - 128, 155, 159, 147, 130, 117, 125, 128, 132, 135, 132, 125, 124, 115, 122, 110, - 66, 38, 41, 53, 45, 63, 81, 90, 14, 13, 12, 11, 9, 8, 7, 7, - 9, 10, 10, 9, 9, 10, 13, 16, 14, 17, 18, 20, 19, 19, 20, 21, - 19, 13, 10, 14, 18, 18, 17, 20, 29, 34, 66, 126, 131, 146, 148, 154, - 152, 110, 15, 38, 38, 47, 85, 110, 129, 139, 147, 149, 148, 147, 144, 142, - 153, 155, 156, 157, 156, 156, 158, 160, 157, 157, 157, 158, 159, 161, 162, 163, - 168, 171, 170, 164, 160, 161, 162, 160, 166, 168, 170, 171, 168, 164, 163, 163, - 162, 169, 166, 162, 165, 162, 158, 165, 169, 166, 164, 163, 161, 159, 156, 155, - 153, 152, 151, 149, 147, 149, 153, 159, 165, 168, 170, 169, 165, 162, 164, 166, - 167, 168, 170, 172, 172, 173, 174, 174, 182, 178, 175, 176, 175, 173, 176, 182, - 181, 180, 179, 178, 179, 180, 182, 183, 180, 182, 186, 190, 193, 193, 190, 186, - 185, 181, 183, 179, 171, 177, 184, 178, 175, 170, 166, 171, 175, 178, 180, 183, - 176, 165, 157, 162, 170, 169, 162, 157, 149, 162, 167, 162, 158, 157, 149, 137, - 108, 115, 148, 141, 150, 139, 128, 126, 129, 136, 128, 126, 137, 137, 127, 125, - 120, 122, 107, 58, 49, 55, 67, 58, 63, 82, 93, 11, 12, 11, 10, 9, - 8, 7, 7, 9, 10, 11, 9, 8, 10, 13, 16, 17, 20, 21, 21, 19, - 17, 16, 17, 19, 12, 10, 17, 22, 21, 17, 20, 26, 48, 71, 114, 122, - 141, 145, 160, 146, 77, 44, 58, 65, 79, 96, 115, 130, 135, 136, 138, 143, - 153, 157, 156, 154, 155, 156, 155, 153, 154, 155, 156, 158, 158, 159, 159, 160, - 162, 164, 165, 167, 171, 170, 164, 162, 164, 165, 164, 165, 167, 168, 168, 165, - 165, 165, 165, 158, 165, 162, 161, 166, 164, 162, 170, 169, 169, 168, 168, 167, - 165, 159, 157, 154, 154, 153, 148, 145, 145, 147, 151, 156, 160, 164, 165, 165, - 166, 169, 171, 166, 165, 166, 168, 170, 171, 171, 173, 178, 177, 176, 178, 178, - 174, 174, 178, 180, 178, 176, 175, 177, 180, 185, 187, 182, 181, 183, 189, 193, - 193, 190, 187, 190, 186, 188, 186, 180, 186, 191, 184, 175, 166, 161, 165, 169, - 170, 171, 173, 175, 166, 159, 161, 164, 162, 158, 158, 153, 163, 168, 164, 156, - 151, 143, 135, 103, 123, 161, 144, 141, 122, 124, 143, 143, 151, 137, 126, 135, - 133, 124, 126, 127, 115, 97, 61, 70, 65, 75, 72, 77, 93, 101, 9, 9, - 9, 9, 9, 8, 8, 8, 13, 14, 14, 12, 11, 12, 16, 19, 20, 22, - 22, 21, 17, 14, 13, 13, 15, 9, 9, 19, 24, 24, 21, 25, 44, 89, - 99, 103, 105, 140, 147, 154, 143, 49, 69, 69, 103, 135, 134, 148, 145, 149, - 150, 153, 156, 160, 155, 150, 156, 159, 158, 158, 157, 158, 159, 161, 160, 160, - 160, 161, 162, 164, 165, 166, 162, 166, 167, 164, 164, 169, 172, 172, 160, 162, - 164, 163, 162, 162, 163, 166, 156, 164, 162, 161, 169, 169, 167, 176, 170, 172, - 174, 176, 177, 173, 166, 159, 155, 156, 154, 149, 144, 143, 145, 148, 144, 144, - 144, 146, 153, 162, 170, 176, 175, 170, 165, 164, 165, 168, 171, 175, 173, 172, - 174, 181, 184, 182, 179, 179, 178, 177, 174, 173, 176, 182, 188, 192, 186, 184, - 185, 190, 194, 194, 191, 189, 184, 182, 188, 190, 184, 187, 185, 173, 176, 169, - 167, 176, 180, 176, 171, 169, 180, 175, 171, 171, 168, 163, 162, 165, 167, 160, - 156, 159, 159, 154, 144, 138, 125, 122, 137, 125, 143, 138, 135, 146, 143, 163, - 155, 136, 136, 129, 122, 133, 127, 100, 81, 60, 78, 60, 65, 71, 83, 94, - 97, 7, 11, 12, 10, 10, 12, 11, 7, 12, 8, 6, 8, 13, 18, 17, - 15, 22, 17, 13, 14, 18, 18, 12, 7, 19, 17, 29, 23, 18, 23, 17, - 32, 69, 103, 102, 104, 114, 119, 139, 147, 136, 67, 81, 112, 119, 129, 130, - 142, 144, 149, 154, 160, 161, 162, 159, 157, 158, 158, 158, 160, 161, 162, 163, - 163, 166, 167, 168, 167, 165, 164, 165, 166, 170, 167, 165, 164, 165, 165, 164, - 162, 170, 168, 164, 160, 157, 157, 156, 157, 159, 163, 165, 164, 162, 164, 169, - 174, 172, 177, 176, 176, 152, 171, 159, 156, 153, 156, 156, 153, 149, 152, 157, - 161, 157, 160, 151, 147, 151, 151, 155, 169, 168, 172, 173, 170, 163, 161, 166, - 174, 174, 182, 185, 180, 175, 178, 181, 181, 174, 176, 178, 177, 176, 178, 182, - 186, 184, 185, 188, 191, 194, 194, 191, 188, 192, 189, 186, 183, 179, 177, 178, - 183, 172, 167, 170, 184, 189, 183, 180, 184, 168, 172, 175, 176, 173, 170, 169, - 170, 166, 156, 160, 167, 157, 150, 146, 138, 130, 118, 139, 139, 137, 152, 145, - 154, 162, 164, 155, 138, 130, 131, 131, 126, 116, 94, 78, 61, 64, 69, 60, - 77, 78, 94, 102, 7, 11, 12, 10, 10, 12, 11, 7, 12, 12, 12, 11, - 13, 15, 19, 21, 23, 21, 17, 15, 14, 13, 12, 12, 24, 19, 28, 21, - 20, 26, 20, 33, 88, 116, 110, 110, 117, 121, 135, 137, 133, 90, 104, 118, - 119, 136, 141, 145, 150, 152, 156, 160, 161, 160, 157, 154, 158, 158, 159, 161, - 161, 162, 163, 163, 162, 162, 164, 164, 163, 163, 165, 167, 167, 165, 163, 163, - 164, 164, 163, 162, 169, 168, 164, 161, 158, 158, 157, 159, 161, 161, 161, 163, - 165, 169, 170, 170, 165, 171, 166, 170, 156, 169, 153, 152, 158, 148, 147, 153, - 155, 161, 160, 147, 148, 156, 157, 159, 163, 155, 145, 148, 159, 163, 167, 166, - 163, 163, 165, 168, 174, 182, 186, 181, 178, 181, 183, 182, 179, 179, 179, 178, - 177, 177, 180, 182, 180, 184, 190, 196, 199, 200, 199, 199, 185, 186, 187, 186, - 183, 178, 175, 175, 174, 168, 171, 185, 189, 180, 170, 167, 178, 180, 180, 176, - 170, 164, 161, 161, 163, 157, 165, 169, 157, 148, 147, 142, 123, 118, 144, 147, - 147, 158, 152, 160, 156, 159, 152, 139, 132, 134, 132, 127, 116, 83, 70, 61, - 62, 67, 61, 72, 81, 96, 101, 7, 11, 12, 10, 9, 12, 11, 8, 13, - 15, 17, 14, 11, 12, 18, 25, 19, 20, 18, 16, 11, 13, 17, 20, 20, - 14, 21, 16, 19, 28, 23, 35, 102, 125, 114, 114, 125, 126, 135, 131, 123, - 105, 120, 120, 117, 141, 150, 144, 155, 156, 157, 159, 158, 157, 154, 153, 158, - 159, 159, 160, 161, 162, 162, 163, 160, 161, 163, 163, 164, 165, 168, 171, 166, - 164, 163, 163, 165, 165, 164, 163, 166, 166, 163, 161, 159, 158, 159, 160, 162, - 160, 159, 163, 169, 172, 169, 166, 163, 172, 161, 166, 162, 163, 147, 148, 150, - 142, 151, 154, 140, 148, 166, 164, 158, 165, 162, 160, 166, 162, 154, 156, 152, - 155, 160, 166, 168, 167, 165, 164, 173, 181, 185, 184, 181, 182, 184, 183, 185, - 182, 180, 179, 179, 179, 179, 178, 176, 182, 189, 192, 190, 187, 186, 186, 186, - 186, 185, 183, 179, 176, 173, 171, 173, 168, 172, 187, 194, 189, 180, 176, 174, - 175, 174, 171, 167, 164, 162, 162, 162, 160, 170, 171, 156, 146, 144, 139, 114, - 123, 149, 154, 154, 160, 155, 162, 153, 157, 152, 138, 133, 135, 131, 124, 116, - 70, 65, 66, 61, 67, 66, 70, 93, 104, 103, 7, 11, 11, 9, 9, 12, - 12, 9, 13, 15, 17, 17, 15, 15, 17, 20, 12, 14, 15, 15, 16, 19, - 22, 25, 15, 10, 22, 16, 18, 29, 28, 45, 105, 126, 114, 117, 132, 136, - 142, 135, 121, 115, 123, 124, 124, 144, 154, 146, 155, 155, 155, 156, 155, 155, - 154, 154, 159, 159, 159, 160, 161, 163, 162, 163, 164, 166, 168, 168, 168, 170, - 172, 175, 165, 164, 164, 165, 167, 167, 166, 164, 162, 162, 161, 161, 159, 160, - 161, 161, 164, 163, 163, 167, 169, 170, 167, 165, 164, 177, 163, 165, 166, 155, - 147, 146, 153, 145, 159, 162, 140, 139, 152, 149, 163, 169, 162, 160, 168, 170, - 166, 168, 155, 155, 158, 163, 169, 170, 167, 163, 171, 176, 181, 184, 183, 182, - 182, 183, 187, 184, 181, 179, 180, 181, 179, 178, 187, 194, 201, 202, 197, 191, - 190, 191, 195, 191, 183, 174, 170, 171, 171, 170, 158, 159, 165, 178, 185, 183, - 180, 180, 168, 168, 167, 165, 164, 163, 162, 162, 165, 161, 167, 168, 155, 146, - 140, 130, 111, 132, 151, 155, 156, 155, 152, 160, 156, 158, 151, 138, 131, 133, - 128, 118, 111, 62, 67, 74, 61, 68, 74, 78, 78, 88, 83, 7, 11, 11, - 8, 9, 13, 13, 10, 12, 12, 14, 17, 18, 18, 14, 10, 14, 12, 12, - 17, 23, 25, 22, 18, 16, 15, 29, 21, 19, 27, 29, 49, 103, 126, 119, - 125, 141, 146, 151, 144, 135, 125, 122, 133, 140, 144, 152, 150, 152, 152, 152, - 153, 153, 155, 155, 155, 159, 159, 158, 160, 161, 162, 163, 162, 169, 170, 172, - 172, 171, 170, 171, 172, 162, 161, 161, 162, 164, 164, 162, 161, 160, 160, 160, - 160, 160, 162, 162, 164, 165, 168, 171, 170, 167, 165, 164, 166, 162, 176, 165, - 163, 163, 150, 154, 139, 102, 93, 112, 142, 157, 163, 159, 142, 150, 164, 167, - 168, 175, 175, 164, 161, 162, 159, 157, 159, 164, 166, 166, 163, 167, 170, 175, - 180, 182, 181, 180, 182, 186, 184, 182, 181, 181, 182, 183, 182, 182, 189, 198, - 200, 197, 194, 194, 196, 197, 194, 184, 173, 169, 171, 169, 164, 161, 169, 183, - 194, 194, 188, 183, 183, 174, 172, 169, 166, 163, 161, 158, 157, 163, 156, 159, - 160, 153, 148, 141, 125, 111, 141, 151, 153, 157, 152, 153, 162, 156, 156, 148, - 135, 129, 130, 124, 113, 96, 58, 70, 77, 60, 66, 77, 86, 94, 104, 103, - 8, 11, 10, 7, 8, 13, 13, 12, 13, 11, 12, 15, 19, 18, 12, 6, - 20, 16, 14, 17, 23, 23, 16, 9, 16, 13, 26, 18, 14, 21, 19, 38, - 103, 132, 128, 136, 149, 150, 155, 149, 146, 134, 119, 136, 148, 139, 146, 147, - 150, 150, 152, 153, 154, 156, 156, 156, 158, 159, 159, 160, 161, 162, 163, 163, - 167, 170, 173, 173, 171, 168, 167, 166, 158, 158, 158, 159, 161, 160, 158, 156, - 158, 159, 160, 163, 164, 166, 167, 169, 168, 173, 174, 173, 167, 165, 165, 169, - 157, 168, 161, 160, 160, 151, 164, 119, 35, 38, 52, 82, 113, 132, 144, 158, - 154, 170, 169, 162, 167, 169, 166, 167, 166, 161, 157, 156, 159, 161, 162, 161, - 166, 166, 169, 176, 179, 179, 179, 181, 183, 184, 184, 183, 181, 181, 185, 187, - 180, 184, 189, 189, 186, 183, 182, 183, 190, 192, 189, 181, 177, 177, 167, 156, - 159, 173, 191, 205, 208, 202, 194, 190, 172, 171, 168, 168, 168, 167, 164, 161, - 157, 150, 150, 153, 150, 151, 144, 126, 110, 148, 150, 152, 161, 154, 157, 163, - 149, 152, 145, 134, 128, 127, 115, 101, 80, 58, 71, 72, 60, 68, 78, 90, - 93, 104, 101, 8, 11, 10, 7, 8, 13, 14, 13, 14, 14, 14, 14, 15, - 14, 12, 10, 21, 20, 18, 18, 18, 16, 12, 7, 14, 7, 16, 12, 16, - 24, 17, 29, 97, 132, 135, 142, 150, 147, 152, 149, 144, 141, 121, 135, 149, - 141, 152, 152, 151, 151, 152, 154, 156, 157, 156, 156, 159, 159, 159, 160, 160, - 162, 163, 163, 163, 168, 172, 174, 172, 168, 165, 163, 160, 159, 159, 161, 161, - 160, 157, 155, 159, 161, 164, 167, 168, 171, 172, 173, 171, 173, 171, 171, 170, - 169, 170, 172, 162, 162, 159, 161, 161, 155, 168, 84, 31, 47, 43, 42, 55, - 57, 75, 120, 154, 170, 167, 156, 158, 165, 170, 177, 167, 164, 161, 159, 160, - 161, 162, 163, 165, 164, 166, 174, 178, 178, 179, 183, 183, 187, 188, 186, 181, - 180, 184, 190, 198, 198, 197, 195, 192, 189, 186, 185, 187, 192, 190, 183, 182, - 183, 173, 158, 154, 159, 167, 179, 188, 192, 189, 183, 167, 166, 165, 167, 170, - 169, 165, 162, 156, 150, 150, 149, 144, 147, 143, 126, 110, 154, 147, 150, 163, - 152, 152, 156, 147, 150, 146, 136, 127, 117, 98, 77, 69, 63, 71, 64, 65, - 78, 80, 91, 107, 119, 117, 9, 11, 10, 7, 8, 13, 15, 14, 16, 18, - 17, 15, 10, 9, 13, 18, 19, 20, 20, 17, 14, 12, 12, 14, 18, 7, - 14, 14, 27, 39, 29, 33, 88, 128, 135, 143, 146, 141, 148, 147, 141, 151, - 129, 141, 154, 151, 167, 164, 154, 155, 156, 158, 159, 159, 158, 156, 159, 159, - 159, 160, 161, 163, 164, 163, 162, 167, 173, 176, 175, 170, 166, 164, 163, 163, - 163, 164, 165, 163, 159, 157, 161, 163, 167, 170, 173, 175, 176, 178, 175, 171, - 168, 168, 173, 176, 175, 174, 173, 164, 163, 165, 165, 161, 169, 56, 30, 49, - 38, 38, 60, 48, 41, 78, 128, 154, 164, 161, 162, 165, 163, 165, 168, 167, - 166, 165, 164, 164, 164, 165, 166, 163, 165, 173, 178, 178, 180, 186, 183, 188, - 192, 188, 179, 176, 182, 190, 190, 189, 187, 188, 189, 189, 188, 185, 189, 191, - 186, 177, 178, 184, 179, 167, 185, 174, 163, 164, 177, 189, 191, 186, 172, 170, - 167, 167, 166, 161, 154, 148, 160, 156, 157, 151, 140, 141, 138, 124, 110, 156, - 145, 147, 162, 147, 143, 142, 145, 150, 147, 136, 123, 106, 79, 53, 66, 67, - 71, 60, 72, 89, 84, 95, 100, 112, 116, 12, 13, 15, 17, 17, 17, 17, - 16, 20, 17, 13, 12, 10, 12, 15, 18, 19, 18, 17, 17, 16, 16, 16, - 16, 17, 18, 21, 21, 23, 24, 28, 36, 81, 132, 134, 129, 137, 138, 147, - 152, 148, 146, 136, 135, 151, 160, 163, 172, 159, 160, 161, 161, 158, 156, 157, - 158, 160, 154, 152, 158, 161, 162, 162, 163, 171, 170, 169, 168, 168, 168, 165, - 164, 157, 157, 158, 160, 164, 163, 161, 160, 160, 164, 167, 170, 172, 173, 173, - 172, 182, 177, 171, 167, 166, 168, 169, 171, 177, 162, 168, 163, 162, 160, 147, - 31, 35, 58, 44, 43, 42, 54, 42, 53, 101, 155, 165, 153, 152, 171, 149, - 166, 165, 171, 168, 162, 164, 171, 165, 153, 171, 169, 165, 164, 168, 178, 185, - 188, 193, 191, 187, 183, 180, 181, 185, 188, 188, 192, 196, 195, 190, 185, 183, - 182, 189, 186, 183, 184, 185, 181, 173, 166, 165, 176, 174, 151, 179, 176, 181, - 183, 167, 163, 168, 169, 160, 161, 165, 160, 164, 152, 155, 153, 140, 144, 143, - 120, 118, 149, 146, 134, 149, 148, 135, 143, 144, 136, 118, 98, 82, 75, 68, - 60, 69, 67, 66, 67, 74, 85, 96, 103, 111, 106, 101, 12, 13, 13, 14, - 15, 15, 15, 14, 17, 17, 17, 16, 17, 18, 18, 19, 15, 15, 15, 14, - 14, 15, 15, 17, 19, 21, 24, 24, 24, 26, 28, 35, 81, 130, 134, 132, - 137, 138, 151, 157, 156, 156, 145, 143, 155, 160, 159, 166, 162, 165, 168, 167, - 164, 160, 157, 156, 161, 156, 153, 156, 159, 157, 157, 158, 166, 166, 165, 167, - 166, 167, 164, 163, 164, 167, 167, 166, 162, 160, 159, 162, 166, 168, 168, 169, - 170, 171, 172, 173, 175, 174, 173, 173, 173, 171, 167, 165, 168, 161, 165, 164, - 167, 157, 135, 31, 48, 49, 36, 55, 56, 62, 42, 44, 77, 156, 166, 159, - 159, 166, 149, 164, 166, 172, 171, 167, 170, 174, 169, 157, 163, 163, 162, 164, - 168, 176, 181, 185, 183, 183, 181, 178, 176, 179, 187, 193, 197, 198, 198, 195, - 190, 186, 186, 187, 193, 189, 186, 186, 185, 182, 175, 169, 163, 170, 161, 147, - 171, 179, 182, 183, 169, 163, 165, 164, 155, 157, 163, 161, 166, 155, 157, 153, - 141, 142, 139, 118, 114, 145, 147, 140, 152, 145, 126, 129, 92, 88, 79, 69, - 63, 64, 64, 61, 68, 67, 66, 69, 78, 90, 103, 112, 115, 110, 106, 11, - 10, 11, 11, 11, 10, 11, 12, 12, 13, 15, 15, 16, 17, 16, 15, 16, - 17, 16, 16, 15, 15, 16, 16, 15, 18, 21, 22, 23, 26, 30, 36, 74, - 119, 128, 130, 133, 132, 147, 152, 158, 160, 151, 149, 159, 161, 157, 161, 163, - 166, 171, 172, 169, 162, 155, 152, 154, 150, 151, 156, 161, 163, 165, 168, 164, - 165, 165, 167, 166, 165, 164, 163, 156, 162, 165, 164, 159, 159, 165, 172, 172, - 171, 169, 169, 169, 170, 172, 173, 174, 173, 173, 173, 173, 171, 167, 165, 164, - 165, 166, 167, 176, 157, 118, 38, 56, 40, 35, 66, 59, 60, 48, 50, 62, - 165, 163, 158, 158, 154, 150, 163, 164, 169, 170, 168, 170, 176, 171, 160, 159, - 160, 161, 165, 168, 174, 179, 184, 179, 181, 180, 177, 175, 179, 189, 198, 203, - 201, 197, 192, 187, 185, 187, 189, 194, 190, 186, 185, 185, 183, 176, 173, 167, - 169, 150, 147, 159, 180, 177, 181, 171, 163, 163, 159, 150, 153, 162, 161, 164, - 156, 155, 152, 141, 138, 133, 116, 111, 134, 131, 120, 124, 111, 90, 90, 73, - 73, 70, 65, 64, 67, 69, 66, 67, 67, 67, 71, 80, 93, 105, 113, 116, - 113, 110, 11, 11, 9, 8, 8, 10, 11, 12, 11, 13, 14, 14, 15, 15, - 14, 15, 19, 20, 19, 18, 17, 16, 15, 15, 19, 22, 26, 29, 31, 35, - 39, 46, 68, 105, 119, 130, 132, 129, 144, 146, 147, 153, 149, 150, 161, 160, - 155, 160, 161, 165, 169, 171, 167, 161, 156, 153, 150, 147, 149, 156, 160, 163, - 167, 171, 168, 168, 169, 169, 165, 163, 161, 162, 154, 159, 160, 161, 159, 163, - 169, 176, 169, 169, 169, 170, 170, 171, 171, 171, 176, 172, 168, 165, 166, 167, - 168, 170, 164, 170, 165, 166, 177, 154, 99, 43, 52, 42, 48, 74, 49, 53, - 58, 65, 71, 175, 154, 146, 148, 142, 151, 164, 163, 165, 164, 163, 166, 171, - 169, 162, 163, 162, 162, 165, 168, 172, 179, 187, 184, 187, 186, 181, 178, 181, - 192, 201, 198, 196, 192, 187, 184, 183, 184, 186, 189, 186, 183, 182, 182, 181, - 178, 176, 172, 172, 149, 151, 147, 173, 171, 178, 171, 163, 163, 160, 150, 153, - 161, 159, 160, 155, 153, 149, 141, 136, 128, 118, 97, 106, 98, 82, 81, 73, - 63, 65, 64, 67, 66, 60, 58, 59, 60, 59, 64, 66, 70, 76, 84, 93, - 101, 107, 111, 112, 110, 10, 10, 9, 8, 9, 10, 12, 13, 17, 17, 17, - 15, 16, 17, 17, 19, 17, 19, 20, 21, 22, 22, 22, 23, 36, 40, 42, - 44, 46, 49, 53, 57, 59, 89, 109, 132, 134, 131, 147, 144, 140, 148, 148, - 151, 161, 160, 154, 157, 160, 163, 165, 166, 164, 161, 160, 160, 157, 154, 154, - 158, 158, 156, 158, 162, 170, 171, 170, 167, 161, 158, 156, 158, 168, 166, 165, - 164, 164, 166, 166, 166, 163, 166, 169, 172, 174, 173, 171, 169, 172, 169, 165, - 163, 164, 166, 167, 168, 163, 168, 159, 157, 164, 146, 81, 39, 46, 47, 58, - 77, 51, 59, 61, 58, 88, 172, 142, 140, 144, 143, 154, 164, 166, 164, 160, - 158, 162, 167, 167, 164, 168, 163, 161, 163, 163, 167, 177, 189, 187, 189, 188, - 185, 182, 186, 196, 204, 192, 191, 189, 188, 186, 185, 184, 183, 183, 182, 181, - 181, 182, 182, 182, 181, 172, 171, 154, 157, 141, 164, 170, 180, 168, 163, 165, - 165, 155, 156, 162, 159, 156, 155, 150, 145, 143, 136, 127, 126, 75, 77, 70, - 63, 63, 66, 67, 70, 58, 62, 65, 60, 59, 61, 64, 63, 61, 67, 76, - 85, 94, 100, 103, 105, 110, 111, 112, 9, 11, 9, 10, 11, 13, 14, 16, - 16, 16, 16, 16, 16, 17, 18, 22, 23, 27, 30, 35, 39, 41, 43, 45, - 48, 51, 53, 52, 53, 55, 56, 60, 56, 71, 94, 124, 130, 130, 146, 139, - 141, 150, 151, 153, 161, 159, 152, 155, 161, 162, 163, 163, 162, 163, 165, 167, - 161, 159, 161, 166, 166, 165, 169, 174, 173, 173, 170, 165, 156, 153, 154, 157, - 164, 165, 164, 167, 170, 171, 167, 164, 162, 166, 171, 175, 176, 175, 171, 169, - 164, 165, 167, 169, 171, 169, 164, 162, 167, 169, 160, 156, 156, 149, 78, 37, - 45, 50, 54, 76, 65, 72, 54, 42, 105, 159, 140, 147, 150, 156, 159, 165, - 171, 167, 162, 160, 163, 166, 166, 164, 166, 161, 157, 160, 160, 162, 175, 191, - 186, 187, 186, 185, 187, 191, 198, 203, 190, 190, 189, 190, 190, 189, 185, 183, - 181, 182, 183, 184, 184, 184, 184, 183, 169, 162, 157, 158, 143, 158, 174, 181, - 165, 162, 167, 168, 159, 159, 163, 159, 153, 154, 147, 142, 144, 134, 127, 132, - 66, 64, 64, 64, 65, 67, 69, 69, 62, 68, 68, 65, 62, 63, 68, 68, - 67, 75, 85, 96, 104, 109, 111, 112, 112, 114, 116, 9, 11, 12, 14, 15, - 17, 18, 18, 17, 19, 22, 25, 27, 28, 28, 30, 37, 41, 46, 51, 55, - 58, 59, 61, 55, 58, 60, 60, 62, 64, 67, 69, 72, 74, 88, 121, 125, - 126, 143, 133, 141, 151, 151, 154, 161, 157, 150, 155, 158, 159, 161, 161, 161, - 161, 163, 165, 159, 160, 166, 172, 174, 177, 182, 190, 177, 177, 172, 165, 157, - 156, 158, 163, 161, 167, 173, 179, 180, 178, 175, 174, 168, 170, 174, 176, 177, - 175, 173, 171, 164, 165, 168, 171, 173, 171, 166, 163, 170, 167, 163, 159, 152, - 159, 83, 36, 44, 49, 46, 71, 70, 69, 48, 55, 130, 150, 147, 158, 150, - 163, 163, 169, 172, 168, 165, 164, 166, 165, 162, 160, 162, 157, 156, 162, 163, - 164, 177, 194, 191, 189, 186, 187, 191, 195, 198, 198, 193, 191, 190, 190, 191, - 190, 185, 182, 180, 182, 184, 185, 184, 182, 180, 179, 171, 155, 160, 154, 150, - 154, 175, 172, 164, 160, 166, 168, 160, 160, 164, 161, 154, 158, 145, 140, 144, - 133, 125, 137, 67, 61, 64, 65, 61, 63, 64, 60, 59, 65, 65, 60, 58, - 60, 65, 68, 84, 88, 95, 103, 109, 112, 113, 114, 115, 117, 118, 12, 13, - 15, 19, 21, 22, 22, 24, 26, 31, 37, 43, 46, 47, 46, 46, 45, 49, - 53, 56, 58, 58, 60, 60, 62, 66, 69, 72, 75, 79, 84, 86, 100, 91, - 98, 127, 127, 127, 145, 132, 136, 146, 149, 153, 159, 157, 151, 155, 154, 156, - 159, 159, 158, 158, 158, 159, 160, 161, 165, 170, 172, 171, 177, 184, 183, 181, - 177, 170, 161, 160, 166, 173, 177, 187, 196, 198, 192, 185, 180, 181, 175, 176, - 176, 177, 176, 175, 174, 173, 171, 169, 167, 167, 169, 170, 171, 171, 165, 159, - 161, 159, 147, 163, 87, 30, 40, 47, 42, 69, 66, 54, 47, 88, 152, 150, - 156, 163, 145, 164, 164, 177, 170, 166, 166, 168, 168, 164, 158, 154, 160, 155, - 158, 167, 168, 170, 181, 199, 200, 195, 190, 191, 195, 198, 195, 192, 196, 192, - 188, 187, 188, 187, 183, 180, 178, 180, 183, 183, 181, 177, 174, 173, 177, 152, - 161, 151, 154, 151, 173, 161, 163, 159, 164, 165, 158, 160, 165, 163, 157, 161, - 146, 138, 144, 132, 124, 139, 66, 56, 56, 61, 58, 63, 70, 68, 64, 71, - 75, 74, 74, 83, 91, 95, 100, 101, 104, 106, 108, 109, 110, 110, 116, 117, - 118, 28, 28, 31, 33, 32, 31, 30, 30, 39, 51, 49, 43, 44, 40, 37, - 45, 35, 45, 51, 59, 66, 62, 64, 80, 81, 81, 83, 89, 99, 107, 110, - 108, 118, 113, 113, 119, 124, 127, 129, 133, 139, 143, 148, 151, 152, 151, 150, - 150, 153, 154, 156, 158, 160, 161, 162, 162, 165, 163, 164, 169, 172, 170, 172, - 175, 176, 176, 177, 179, 180, 181, 182, 183, 181, 183, 185, 188, 189, 190, 188, - 189, 182, 181, 178, 175, 176, 178, 182, 184, 179, 174, 168, 164, 164, 166, 168, - 168, 171, 163, 148, 157, 158, 160, 131, 31, 53, 36, 46, 67, 59, 54, 81, - 113, 148, 152, 159, 163, 166, 167, 170, 172, 163, 168, 172, 171, 166, 160, 157, - 156, 163, 162, 163, 166, 170, 175, 177, 179, 198, 193, 188, 188, 195, 200, 200, - 199, 192, 190, 187, 185, 185, 185, 183, 181, 180, 174, 177, 181, 177, 179, 182, - 174, 168, 170, 168, 159, 161, 142, 168, 172, 163, 163, 162, 160, 162, 164, 160, - 154, 157, 152, 151, 144, 145, 116, 139, 144, 71, 60, 70, 64, 57, 69, 66, - 67, 80, 85, 91, 97, 102, 104, 105, 106, 111, 111, 110, 108, 105, 106, 108, - 111, 111, 111, 111, 30, 29, 28, 28, 29, 32, 36, 38, 33, 45, 49, 49, - 49, 43, 38, 41, 47, 52, 56, 69, 85, 87, 84, 93, 93, 102, 112, 118, - 120, 119, 118, 117, 110, 107, 109, 115, 120, 122, 128, 135, 134, 138, 144, 148, - 150, 150, 151, 152, 150, 152, 154, 157, 159, 161, 163, 163, 162, 160, 162, 167, - 170, 168, 168, 171, 171, 173, 175, 178, 178, 177, 176, 175, 178, 179, 181, 183, - 183, 185, 185, 185, 190, 188, 185, 182, 181, 182, 184, 185, 187, 186, 183, 178, - 173, 169, 166, 164, 160, 159, 155, 167, 164, 162, 139, 59, 41, 47, 59, 57, - 40, 58, 113, 157, 154, 158, 163, 165, 166, 167, 171, 174, 171, 172, 172, 170, - 165, 159, 155, 154, 160, 163, 163, 165, 167, 174, 184, 193, 193, 190, 189, 193, - 199, 202, 200, 197, 192, 189, 187, 186, 185, 185, 183, 181, 181, 174, 178, 181, - 176, 177, 179, 171, 173, 171, 165, 156, 161, 147, 177, 182, 168, 168, 166, 163, - 164, 166, 161, 155, 155, 156, 146, 142, 139, 123, 138, 139, 73, 62, 74, 77, - 82, 101, 104, 107, 118, 119, 120, 120, 118, 116, 114, 112, 114, 114, 113, 112, - 111, 112, 115, 117, 117, 117, 116, 43, 41, 39, 38, 38, 40, 42, 44, 42, - 48, 55, 58, 59, 58, 58, 59, 71, 77, 80, 88, 99, 96, 91, 100, 94, - 105, 116, 115, 106, 97, 97, 100, 108, 107, 110, 114, 116, 117, 125, 134, 128, - 132, 139, 144, 148, 150, 152, 154, 150, 153, 154, 156, 158, 160, 160, 161, 158, - 156, 158, 163, 165, 162, 162, 165, 167, 169, 173, 175, 174, 172, 168, 166, 175, - 174, 175, 176, 177, 178, 180, 181, 193, 191, 189, 187, 185, 184, 184, 184, 181, - 184, 186, 183, 174, 165, 159, 156, 162, 160, 162, 170, 162, 158, 149, 103, 78, - 74, 68, 57, 63, 106, 150, 163, 159, 163, 170, 175, 176, 176, 177, 177, 179, - 176, 172, 167, 162, 158, 154, 151, 169, 171, 169, 164, 162, 168, 181, 193, 187, - 189, 191, 197, 202, 203, 198, 194, 191, 189, 187, 186, 186, 185, 183, 181, 182, - 175, 178, 180, 175, 176, 176, 168, 175, 172, 167, 160, 168, 153, 179, 180, 166, - 166, 163, 160, 161, 162, 156, 150, 152, 160, 141, 141, 130, 132, 140, 136, 80, - 63, 76, 83, 95, 117, 119, 122, 118, 117, 116, 115, 113, 112, 111, 110, 114, - 115, 115, 114, 113, 115, 118, 119, 116, 116, 117, 37, 39, 41, 45, 48, 49, - 51, 51, 69, 66, 71, 75, 76, 82, 93, 97, 98, 109, 110, 103, 97, 87, - 84, 96, 86, 92, 95, 90, 80, 78, 85, 94, 115, 115, 117, 117, 115, 115, - 122, 132, 127, 131, 137, 142, 146, 148, 151, 153, 155, 155, 156, 156, 156, 155, - 154, 154, 155, 154, 156, 161, 163, 160, 159, 161, 163, 165, 167, 169, 169, 168, - 166, 164, 173, 173, 171, 172, 172, 175, 178, 179, 188, 187, 187, 186, 185, 183, - 182, 181, 190, 197, 203, 202, 195, 187, 184, 183, 179, 169, 166, 166, 155, 153, - 155, 139, 141, 126, 111, 108, 126, 163, 175, 155, 159, 165, 174, 182, 186, 186, - 185, 184, 182, 176, 168, 163, 160, 158, 154, 152, 171, 171, 165, 162, 162, 169, - 180, 190, 188, 190, 193, 198, 201, 201, 195, 191, 191, 189, 187, 187, 186, 185, - 183, 180, 181, 175, 178, 181, 175, 176, 176, 168, 174, 174, 173, 170, 177, 155, - 171, 164, 163, 163, 161, 158, 158, 159, 154, 147, 146, 163, 141, 142, 123, 137, - 143, 139, 80, 60, 72, 83, 99, 118, 116, 114, 117, 116, 115, 114, 114, 115, - 117, 117, 112, 114, 114, 113, 111, 112, 114, 115, 107, 110, 112, 73, 74, 77, - 83, 90, 98, 104, 109, 92, 81, 88, 96, 90, 97, 111, 112, 105, 111, 105, - 97, 98, 93, 90, 97, 89, 91, 90, 90, 90, 95, 105, 115, 118, 119, 121, - 121, 116, 115, 120, 129, 128, 132, 137, 141, 144, 146, 149, 152, 155, 155, 156, - 155, 155, 154, 153, 152, 156, 154, 155, 159, 160, 157, 157, 159, 161, 162, 162, - 162, 163, 164, 166, 167, 171, 171, 169, 170, 171, 173, 176, 178, 180, 181, 182, - 183, 183, 182, 181, 181, 175, 181, 187, 187, 182, 178, 179, 181, 186, 172, 169, - 164, 156, 157, 157, 159, 168, 166, 172, 177, 174, 183, 189, 181, 171, 170, 171, - 173, 178, 183, 186, 188, 178, 172, 165, 160, 160, 159, 156, 154, 160, 157, 152, - 156, 166, 178, 187, 192, 193, 195, 195, 197, 197, 196, 193, 191, 190, 189, 187, - 187, 187, 186, 182, 180, 180, 174, 179, 183, 176, 177, 177, 168, 171, 172, 172, - 170, 176, 152, 166, 157, 165, 165, 163, 160, 161, 162, 157, 150, 140, 162, 142, - 143, 124, 140, 149, 146, 78, 57, 72, 90, 109, 127, 121, 119, 124, 122, 119, - 115, 113, 111, 110, 111, 112, 112, 112, 111, 107, 107, 108, 108, 103, 106, 111, - 91, 89, 82, 81, 83, 91, 100, 107, 98, 83, 95, 107, 96, 96, 104, 98, - 95, 93, 83, 87, 108, 120, 113, 108, 106, 107, 108, 110, 111, 114, 116, 118, - 116, 116, 118, 121, 117, 116, 119, 126, 129, 132, 136, 139, 142, 144, 147, 149, - 150, 152, 154, 155, 156, 156, 156, 156, 157, 153, 152, 156, 157, 155, 155, 159, - 160, 160, 159, 159, 160, 163, 166, 168, 168, 168, 169, 169, 171, 173, 173, 176, - 176, 177, 179, 180, 181, 182, 182, 182, 186, 189, 190, 189, 186, 185, 187, 190, - 177, 169, 174, 168, 166, 168, 158, 165, 164, 168, 184, 197, 188, 184, 192, 196, - 184, 175, 165, 159, 162, 170, 179, 185, 172, 169, 166, 163, 162, 160, 158, 157, - 159, 154, 150, 155, 167, 179, 184, 185, 196, 197, 197, 196, 194, 193, 191, 190, - 190, 189, 188, 188, 188, 186, 182, 179, 179, 174, 179, 182, 175, 175, 174, 165, - 166, 166, 165, 160, 167, 148, 168, 166, 164, 164, 161, 158, 158, 159, 153, 146, - 139, 157, 143, 141, 131, 140, 152, 145, 85, 63, 77, 96, 114, 129, 122, 118, - 117, 115, 111, 108, 106, 104, 104, 104, 111, 112, 112, 109, 106, 105, 105, 106, - 106, 109, 112, 115, 112, 105, 98, 95, 95, 97, 99, 98, 79, 91, 106, 91, - 90, 99, 90, 93, 99, 95, 99, 121, 133, 127, 123, 119, 120, 122, 121, 118, - 114, 110, 111, 119, 119, 118, 122, 120, 116, 115, 118, 126, 129, 133, 136, 138, - 141, 145, 149, 151, 153, 155, 156, 157, 157, 157, 157, 157, 152, 150, 153, 152, - 151, 152, 158, 158, 158, 158, 159, 160, 161, 162, 163, 163, 163, 165, 167, 168, - 169, 169, 169, 174, 174, 175, 176, 177, 179, 180, 181, 178, 177, 175, 174, 172, - 172, 172, 173, 172, 171, 180, 168, 168, 172, 159, 171, 166, 160, 168, 179, 182, - 189, 191, 183, 183, 175, 165, 159, 161, 166, 172, 174, 168, 170, 171, 169, 166, - 162, 161, 159, 164, 159, 154, 156, 162, 172, 178, 181, 194, 196, 197, 197, 195, - 192, 191, 190, 189, 188, 188, 188, 188, 186, 182, 178, 181, 175, 179, 181, 172, - 170, 167, 157, 157, 160, 162, 158, 164, 146, 169, 170, 165, 164, 160, 155, 154, - 153, 146, 139, 147, 150, 139, 136, 143, 139, 150, 136, 92, 66, 78, 93, 107, - 120, 114, 114, 115, 115, 114, 113, 113, 113, 112, 112, 107, 107, 108, 107, 105, - 104, 103, 104, 104, 107, 109, 108, 110, 111, 111, 107, 102, 96, 93, 101, 75, - 86, 100, 85, 87, 102, 96, 100, 120, 126, 121, 124, 124, 122, 128, 118, 120, - 123, 120, 117, 116, 119, 123, 128, 124, 122, 125, 123, 118, 113, 111, 124, 126, - 130, 133, 136, 140, 144, 148, 154, 156, 156, 157, 156, 156, 155, 155, 158, 152, - 148, 150, 150, 149, 152, 157, 157, 159, 160, 160, 160, 159, 158, 157, 159, 159, - 162, 165, 165, 167, 166, 166, 171, 171, 171, 172, 173, 174, 176, 177, 182, 180, - 178, 177, 177, 177, 176, 173, 176, 178, 186, 165, 162, 172, 159, 177, 170, 169, - 175, 176, 176, 186, 189, 175, 173, 170, 169, 170, 172, 173, 169, 165, 167, 172, - 175, 175, 170, 165, 161, 161, 158, 157, 153, 155, 160, 170, 183, 192, 191, 194, - 197, 199, 197, 194, 191, 190, 189, 188, 188, 188, 188, 186, 182, 178, 182, 175, - 178, 179, 169, 165, 162, 151, 148, 156, 164, 163, 168, 145, 166, 165, 171, 171, - 165, 160, 157, 154, 147, 138, 153, 145, 135, 130, 152, 139, 148, 128, 89, 63, - 73, 89, 103, 119, 117, 121, 113, 112, 111, 109, 107, 104, 103, 102, 102, 103, - 105, 105, 103, 103, 102, 104, 99, 101, 104, 113, 113, 111, 111, 108, 108, 107, - 106, 110, 96, 94, 123, 110, 124, 116, 108, 114, 115, 115, 115, 119, 125, 126, - 125, 126, 127, 123, 119, 119, 123, 125, 125, 130, 127, 124, 124, 124, 123, 119, - 116, 115, 124, 131, 131, 133, 140, 144, 142, 150, 148, 147, 150, 153, 153, 151, - 151, 154, 152, 149, 148, 150, 151, 155, 157, 162, 161, 160, 159, 158, 158, 158, - 158, 162, 163, 164, 166, 166, 168, 167, 166, 173, 173, 172, 173, 172, 170, 169, - 168, 174, 173, 171, 171, 172, 174, 177, 178, 180, 176, 171, 172, 174, 174, 170, - 167, 176, 171, 170, 176, 185, 187, 179, 171, 165, 164, 165, 168, 173, 176, 175, - 174, 169, 168, 167, 165, 162, 160, 159, 158, 164, 152, 145, 151, 158, 163, 174, - 187, 187, 194, 199, 200, 194, 189, 189, 190, 190, 189, 188, 187, 186, 184, 180, - 176, 180, 179, 182, 179, 166, 160, 153, 138, 149, 157, 154, 153, 165, 169, 166, - 167, 172, 165, 157, 154, 151, 148, 148, 150, 144, 163, 105, 146, 140, 155, 152, - 142, 83, 70, 70, 86, 96, 97, 107, 120, 113, 108, 110, 100, 106, 109, 93, - 101, 100, 95, 102, 107, 103, 103, 103, 95, 100, 102, 106, 104, 106, 108, 110, - 111, 111, 110, 109, 106, 105, 106, 112, 101, 109, 112, 113, 112, 112, 112, 113, - 116, 120, 122, 122, 127, 129, 128, 124, 121, 123, 122, 119, 126, 127, 130, 134, - 134, 131, 122, 116, 115, 128, 134, 130, 127, 133, 144, 153, 154, 153, 151, 153, - 154, 154, 153, 151, 153, 152, 149, 147, 148, 151, 153, 156, 160, 160, 159, 158, - 158, 159, 159, 160, 160, 160, 163, 165, 166, 167, 167, 166, 169, 170, 171, 172, - 173, 173, 173, 172, 171, 171, 171, 173, 175, 179, 183, 186, 182, 178, 174, 175, - 178, 178, 175, 171, 174, 171, 171, 176, 182, 184, 180, 175, 173, 171, 171, 172, - 175, 176, 175, 173, 173, 172, 172, 170, 168, 166, 166, 164, 156, 150, 146, 150, - 157, 166, 179, 189, 190, 195, 200, 199, 194, 191, 190, 192, 191, 189, 188, 187, - 186, 184, 180, 176, 177, 173, 176, 173, 163, 161, 158, 145, 148, 159, 156, 151, - 157, 159, 159, 164, 168, 161, 154, 152, 152, 149, 143, 139, 142, 150, 122, 148, - 154, 151, 145, 131, 75, 62, 63, 83, 97, 95, 95, 101, 104, 101, 114, 109, - 103, 105, 96, 101, 105, 96, 95, 96, 91, 99, 108, 107, 100, 100, 105, 109, - 112, 115, 117, 118, 116, 114, 113, 110, 115, 110, 93, 103, 107, 115, 117, 117, - 116, 116, 116, 116, 117, 118, 121, 117, 122, 124, 123, 123, 126, 125, 122, 124, - 125, 129, 133, 133, 131, 125, 120, 117, 125, 131, 131, 132, 137, 146, 151, 152, - 152, 152, 153, 155, 156, 155, 152, 151, 150, 148, 147, 146, 148, 151, 153, 154, - 155, 155, 156, 157, 158, 158, 159, 158, 159, 161, 163, 164, 165, 165, 165, 164, - 165, 167, 169, 172, 173, 174, 174, 172, 172, 172, 174, 176, 180, 183, 186, 180, - 177, 175, 176, 178, 179, 177, 174, 172, 171, 172, 175, 179, 181, 181, 180, 181, - 180, 178, 177, 177, 176, 174, 172, 172, 171, 171, 168, 167, 165, 164, 162, 153, - 156, 154, 152, 158, 171, 184, 190, 193, 196, 199, 197, 192, 190, 192, 194, 192, - 190, 189, 188, 187, 184, 180, 176, 173, 171, 176, 175, 166, 164, 159, 144, 142, - 155, 153, 148, 154, 158, 162, 172, 167, 163, 157, 156, 156, 152, 144, 136, 145, - 136, 137, 144, 160, 146, 140, 128, 64, 52, 54, 78, 97, 100, 100, 104, 98, - 93, 121, 119, 100, 103, 102, 103, 108, 99, 96, 94, 91, 102, 115, 116, 107, - 104, 105, 103, 106, 109, 112, 114, 115, 116, 116, 117, 118, 105, 77, 111, 118, - 121, 112, 117, 117, 119, 120, 118, 115, 116, 120, 117, 122, 122, 121, 123, 128, - 128, 125, 124, 123, 123, 123, 123, 125, 126, 127, 119, 119, 121, 131, 142, 149, - 146, 141, 145, 147, 149, 150, 152, 156, 156, 152, 151, 150, 149, 147, 147, 147, - 149, 150, 148, 149, 149, 151, 152, 155, 157, 158, 161, 161, 162, 163, 164, 163, - 163, 163, 160, 162, 164, 167, 169, 170, 171, 172, 175, 175, 174, 174, 173, 174, - 176, 177, 175, 173, 172, 173, 175, 176, 175, 173, 171, 172, 174, 174, 175, 178, - 181, 183, 185, 183, 181, 178, 177, 175, 174, 172, 173, 173, 171, 168, 165, 162, - 161, 158, 158, 164, 163, 157, 160, 175, 187, 190, 195, 197, 198, 195, 191, 191, - 193, 195, 192, 191, 189, 188, 187, 184, 179, 176, 173, 173, 180, 181, 172, 167, - 156, 137, 147, 157, 153, 149, 158, 164, 168, 175, 163, 164, 161, 156, 153, 151, - 146, 140, 151, 131, 140, 141, 148, 144, 137, 134, 64, 53, 55, 72, 90, 97, - 103, 110, 102, 90, 121, 122, 97, 102, 107, 101, 106, 100, 105, 106, 102, 107, - 117, 114, 112, 108, 106, 85, 87, 88, 92, 98, 105, 110, 114, 113, 120, 107, - 74, 106, 112, 114, 105, 107, 105, 110, 117, 118, 116, 115, 120, 127, 128, 124, - 118, 115, 119, 119, 117, 121, 120, 120, 120, 121, 123, 125, 127, 117, 117, 121, - 129, 138, 144, 146, 147, 145, 149, 150, 149, 152, 157, 154, 148, 153, 151, 150, - 149, 149, 148, 149, 149, 146, 146, 147, 149, 152, 155, 157, 159, 164, 164, 164, - 164, 163, 162, 160, 160, 162, 163, 165, 167, 169, 169, 170, 170, 177, 177, 176, - 175, 173, 173, 172, 173, 172, 171, 171, 171, 174, 174, 174, 173, 172, 173, 174, - 174, 174, 176, 180, 184, 183, 181, 179, 176, 174, 172, 173, 173, 178, 177, 174, - 171, 167, 163, 160, 159, 160, 165, 164, 160, 165, 180, 189, 190, 196, 197, 196, - 194, 191, 191, 193, 195, 192, 190, 188, 187, 186, 182, 178, 174, 175, 172, 175, - 175, 168, 166, 159, 141, 157, 162, 153, 150, 164, 170, 167, 168, 155, 160, 158, - 149, 142, 142, 144, 143, 146, 130, 137, 147, 138, 149, 137, 129, 67, 64, 68, - 80, 87, 88, 93, 101, 111, 92, 115, 115, 95, 104, 106, 97, 100, 97, 104, - 106, 99, 102, 109, 105, 111, 108, 108, 89, 88, 86, 87, 89, 93, 98, 102, - 104, 119, 115, 87, 86, 90, 98, 99, 92, 90, 97, 112, 119, 116, 113, 116, - 113, 114, 111, 106, 105, 110, 113, 111, 115, 119, 124, 127, 127, 125, 124, 125, - 116, 121, 128, 130, 126, 128, 142, 157, 147, 153, 153, 150, 152, 157, 154, 145, - 153, 152, 151, 149, 148, 148, 148, 148, 146, 148, 148, 150, 153, 156, 159, 161, - 164, 164, 164, 164, 163, 161, 160, 159, 165, 166, 168, 169, 170, 170, 170, 170, - 175, 175, 175, 176, 175, 176, 176, 177, 173, 173, 173, 173, 174, 175, 175, 175, - 173, 174, 174, 174, 174, 175, 178, 182, 178, 177, 175, 173, 170, 170, 172, 174, - 176, 174, 173, 170, 166, 163, 160, 159, 158, 159, 158, 161, 170, 183, 190, 193, - 197, 195, 194, 193, 191, 191, 192, 192, 191, 189, 187, 186, 184, 181, 176, 172, - 176, 167, 164, 162, 159, 166, 168, 156, 149, 154, 148, 151, 170, 178, 172, 170, - 158, 163, 158, 145, 139, 142, 146, 145, 134, 132, 138, 155, 143, 152, 139, 107, - 59, 66, 81, 98, 104, 100, 99, 103, 116, 97, 109, 106, 96, 106, 102, 96, - 97, 92, 96, 95, 88, 92, 104, 103, 113, 109, 110, 104, 103, 99, 98, 96, - 96, 98, 100, 108, 117, 113, 99, 72, 82, 93, 96, 91, 86, 94, 112, 121, - 115, 108, 107, 98, 102, 103, 102, 105, 112, 117, 115, 116, 121, 126, 128, 127, - 125, 126, 126, 120, 123, 128, 133, 130, 126, 133, 143, 142, 149, 151, 149, 151, - 159, 157, 147, 152, 151, 150, 149, 148, 146, 146, 145, 145, 145, 146, 148, 151, - 154, 156, 158, 160, 161, 162, 162, 162, 162, 161, 161, 164, 165, 166, 168, 169, - 170, 170, 170, 170, 171, 173, 175, 176, 177, 178, 178, 175, 176, 176, 175, 175, - 174, 174, 175, 175, 174, 175, 175, 175, 176, 178, 178, 176, 176, 175, 171, 167, - 167, 170, 173, 170, 169, 169, 167, 166, 164, 164, 163, 165, 158, 157, 166, 178, - 188, 192, 196, 195, 194, 193, 192, 191, 191, 189, 189, 190, 188, 186, 184, 182, - 179, 174, 170, 171, 163, 161, 162, 163, 173, 177, 165, 142, 152, 151, 156, 173, - 180, 173, 172, 167, 167, 158, 144, 142, 148, 146, 138, 130, 136, 145, 152, 153, - 144, 149, 85, 54, 65, 84, 106, 118, 119, 117, 115, 117, 107, 112, 107, 106, - 113, 102, 104, 101, 97, 101, 101, 93, 98, 111, 112, 119, 113, 110, 99, 100, - 103, 105, 106, 109, 110, 112, 119, 112, 102, 104, 71, 91, 98, 94, 100, 91, - 97, 116, 125, 116, 103, 98, 107, 112, 114, 114, 116, 120, 121, 117, 123, 123, - 123, 121, 119, 122, 127, 132, 128, 120, 121, 136, 145, 141, 126, 115, 130, 138, - 143, 144, 150, 160, 160, 151, 151, 150, 149, 147, 146, 145, 144, 144, 141, 142, - 142, 144, 147, 150, 153, 153, 156, 157, 159, 160, 161, 162, 162, 163, 158, 159, - 161, 164, 165, 167, 167, 168, 168, 169, 170, 172, 173, 174, 174, 174, 174, 175, - 176, 175, 173, 172, 173, 174, 176, 176, 174, 175, 176, 177, 176, 174, 177, 176, - 175, 171, 167, 167, 168, 172, 170, 171, 171, 171, 171, 171, 172, 171, 177, 164, - 161, 173, 187, 191, 193, 197, 194, 192, 192, 192, 191, 191, 188, 187, 189, 187, - 185, 183, 181, 178, 173, 169, 167, 162, 167, 173, 175, 182, 180, 164, 152, 165, - 165, 165, 173, 172, 162, 161, 169, 165, 151, 139, 142, 148, 140, 124, 134, 140, - 151, 142, 158, 133, 159, 73, 61, 66, 81, 100, 115, 121, 118, 115, 116, 116, - 120, 112, 116, 118, 104, 114, 106, 105, 114, 118, 110, 114, 124, 123, 120, 112, - 109, 105, 102, 96, 91, 93, 101, 104, 102, 110, 105, 105, 121, 106, 85, 97, - 98, 100, 112, 115, 116, 119, 113, 106, 111, 111, 113, 114, 113, 112, 114, 120, - 125, 124, 121, 129, 132, 122, 121, 125, 121, 124, 122, 125, 135, 144, 145, 142, - 140, 117, 130, 134, 138, 154, 160, 154, 153, 151, 154, 159, 159, 157, 155, 155, - 157, 148, 148, 147, 145, 145, 148, 153, 156, 153, 155, 157, 160, 163, 163, 162, - 161, 169, 166, 164, 165, 165, 164, 166, 170, 166, 164, 168, 174, 174, 169, 170, - 174, 173, 174, 176, 176, 176, 174, 170, 168, 174, 175, 175, 176, 175, 174, 173, - 173, 170, 171, 171, 171, 170, 173, 176, 179, 179, 179, 172, 167, 169, 174, 169, - 160, 165, 159, 160, 173, 189, 192, 192, 193, 194, 196, 197, 197, 195, 192, 188, - 187, 185, 186, 187, 184, 178, 174, 173, 174, 166, 172, 177, 183, 166, 163, 171, - 142, 161, 163, 162, 166, 173, 178, 176, 171, 163, 153, 150, 134, 136, 146, 133, - 128, 142, 149, 141, 153, 171, 123, 161, 74, 66, 69, 89, 108, 111, 116, 120, - 115, 108, 113, 116, 117, 121, 123, 120, 115, 115, 114, 115, 118, 121, 123, 122, - 121, 115, 112, 112, 111, 109, 103, 95, 92, 93, 90, 83, 98, 93, 89, 102, - 94, 86, 104, 103, 101, 103, 97, 94, 102, 103, 100, 106, 100, 102, 104, 108, - 110, 115, 119, 122, 120, 118, 125, 128, 119, 121, 126, 122, 128, 127, 124, 123, - 131, 143, 147, 143, 136, 137, 127, 119, 127, 135, 142, 154, 158, 161, 162, 160, - 157, 155, 156, 157, 154, 153, 151, 148, 146, 148, 151, 154, 150, 151, 153, 156, - 159, 159, 160, 160, 166, 162, 162, 164, 165, 163, 165, 169, 169, 167, 170, 175, - 175, 171, 172, 178, 172, 173, 175, 175, 175, 173, 170, 169, 174, 175, 176, 175, - 174, 172, 171, 171, 170, 171, 171, 170, 170, 171, 174, 177, 176, 175, 170, 166, - 168, 174, 175, 172, 161, 161, 169, 182, 189, 190, 190, 194, 193, 194, 195, 195, - 193, 190, 187, 185, 184, 182, 180, 178, 177, 175, 172, 169, 170, 190, 168, 173, - 191, 163, 150, 166, 168, 167, 166, 172, 177, 178, 174, 170, 167, 154, 150, 135, - 133, 140, 129, 131, 143, 141, 144, 144, 131, 140, 139, 61, 66, 73, 93, 109, - 112, 113, 118, 114, 112, 117, 118, 118, 119, 122, 120, 113, 110, 110, 109, 112, - 113, 114, 113, 113, 112, 112, 111, 108, 110, 109, 105, 103, 103, 98, 92, 91, - 91, 86, 95, 92, 93, 108, 97, 100, 99, 89, 87, 99, 102, 99, 104, 104, - 104, 106, 111, 116, 120, 122, 122, 122, 118, 123, 125, 117, 119, 125, 123, 118, - 125, 127, 124, 129, 142, 147, 143, 142, 143, 136, 131, 133, 129, 130, 142, 140, - 147, 157, 166, 167, 166, 163, 161, 156, 154, 152, 149, 146, 146, 147, 151, 147, - 147, 149, 150, 152, 154, 157, 158, 161, 158, 159, 163, 164, 162, 163, 167, 169, - 168, 170, 172, 172, 170, 173, 178, 171, 173, 174, 174, 173, 172, 170, 168, 173, - 174, 174, 174, 173, 171, 170, 169, 169, 171, 171, 169, 168, 168, 171, 173, 168, - 170, 170, 167, 168, 172, 173, 170, 157, 165, 179, 190, 190, 187, 189, 196, 194, - 194, 195, 194, 192, 189, 187, 185, 190, 185, 180, 178, 178, 177, 171, 166, 174, - 181, 182, 190, 177, 162, 173, 169, 175, 171, 172, 181, 184, 177, 170, 170, 170, - 154, 150, 135, 130, 133, 126, 137, 152, 154, 150, 150, 136, 164, 98, 71, 66, - 81, 102, 114, 116, 116, 117, 118, 111, 114, 113, 112, 113, 116, 114, 110, 108, - 106, 105, 107, 108, 109, 108, 108, 107, 109, 107, 105, 108, 111, 110, 111, 113, - 111, 107, 101, 106, 103, 110, 108, 105, 107, 81, 102, 107, 105, 107, 115, 114, - 107, 110, 118, 117, 116, 120, 123, 124, 119, 117, 125, 119, 122, 122, 115, 118, - 125, 121, 117, 121, 124, 122, 121, 129, 142, 152, 148, 150, 147, 147, 148, 137, - 129, 137, 131, 136, 142, 148, 153, 156, 157, 157, 153, 153, 152, 150, 149, 149, - 151, 155, 150, 149, 148, 148, 149, 150, 153, 155, 156, 155, 156, 162, 163, 162, - 162, 165, 167, 167, 167, 167, 166, 167, 170, 174, 169, 171, 171, 171, 171, 170, - 168, 168, 170, 171, 171, 171, 171, 170, 170, 169, 169, 170, 169, 168, 166, 167, - 168, 172, 162, 166, 171, 171, 169, 165, 161, 160, 162, 172, 184, 190, 190, 189, - 191, 195, 196, 196, 196, 196, 192, 191, 189, 188, 190, 187, 182, 178, 174, 171, - 167, 164, 165, 185, 200, 191, 158, 166, 195, 168, 178, 173, 175, 186, 187, 176, - 169, 171, 169, 152, 148, 133, 126, 129, 128, 145, 146, 155, 131, 143, 158, 149, - 53, 74, 66, 90, 109, 119, 122, 120, 121, 125, 120, 121, 120, 118, 119, 123, - 124, 120, 124, 122, 121, 122, 125, 126, 126, 126, 124, 125, 125, 108, 111, 111, - 107, 106, 107, 107, 104, 109, 116, 114, 120, 118, 115, 111, 78, 106, 119, 124, - 124, 126, 120, 115, 122, 124, 121, 119, 120, 121, 119, 112, 107, 120, 114, 116, - 117, 113, 118, 125, 121, 127, 120, 115, 113, 104, 103, 124, 150, 160, 157, 146, - 141, 145, 142, 140, 149, 151, 144, 133, 127, 126, 131, 139, 145, 147, 148, 150, - 150, 149, 152, 155, 157, 153, 152, 149, 147, 147, 148, 151, 152, 155, 153, 155, - 161, 163, 161, 161, 164, 165, 167, 167, 165, 164, 166, 169, 170, 167, 168, 169, - 169, 169, 169, 167, 167, 167, 167, 169, 170, 170, 171, 170, 170, 168, 169, 168, - 167, 165, 166, 167, 170, 166, 167, 168, 168, 166, 162, 160, 161, 172, 177, 182, - 184, 188, 192, 193, 194, 195, 195, 195, 194, 191, 189, 187, 186, 180, 182, 182, - 176, 168, 164, 165, 168, 173, 208, 182, 160, 173, 175, 177, 179, 175, 174, 177, - 187, 188, 178, 171, 171, 165, 150, 146, 130, 124, 131, 135, 153, 155, 150, 129, - 146, 157, 127, 83, 71, 65, 96, 112, 117, 124, 122, 121, 131, 117, 117, 115, - 110, 110, 113, 112, 109, 116, 115, 114, 115, 117, 120, 122, 122, 121, 124, 124, - 107, 111, 111, 106, 104, 107, 108, 107, 112, 113, 106, 113, 114, 115, 119, 94, - 112, 125, 126, 122, 121, 116, 118, 130, 120, 119, 120, 120, 120, 118, 115, 111, - 113, 106, 109, 113, 110, 117, 124, 120, 117, 115, 118, 121, 111, 98, 97, 104, - 142, 151, 149, 145, 151, 153, 150, 154, 154, 150, 145, 143, 141, 139, 136, 134, - 136, 138, 139, 141, 141, 143, 147, 149, 152, 151, 147, 146, 146, 146, 149, 150, - 153, 151, 152, 156, 158, 157, 157, 161, 164, 167, 168, 165, 164, 167, 169, 169, - 165, 166, 166, 166, 167, 167, 166, 166, 166, 167, 168, 169, 170, 170, 170, 170, - 167, 167, 167, 166, 165, 166, 168, 171, 174, 167, 162, 160, 162, 165, 170, 178, - 181, 182, 180, 181, 185, 193, 194, 191, 192, 191, 190, 189, 186, 185, 183, 183, - 176, 181, 184, 179, 170, 167, 173, 180, 207, 187, 154, 164, 181, 174, 176, 173, - 173, 177, 181, 185, 185, 180, 175, 171, 161, 151, 146, 125, 122, 138, 143, 156, - 171, 146, 145, 155, 133, 125, 154, 74, 66, 100, 112, 112, 123, 123, 118, 130, - 113, 114, 110, 104, 101, 103, 100, 94, 100, 98, 96, 97, 99, 101, 102, 104, - 103, 106, 108, 106, 111, 114, 112, 111, 114, 116, 116, 113, 110, 101, 112, 113, - 114, 124, 107, 113, 123, 121, 116, 116, 113, 113, 124, 115, 117, 120, 120, 120, - 119, 119, 122, 115, 109, 111, 114, 112, 118, 122, 116, 107, 117, 123, 123, 122, - 115, 89, 60, 87, 124, 149, 154, 161, 162, 155, 151, 147, 150, 156, 162, 164, - 160, 151, 143, 137, 139, 140, 140, 139, 139, 139, 141, 144, 143, 143, 142, 143, - 144, 146, 147, 151, 148, 148, 151, 152, 152, 153, 157, 160, 165, 167, 164, 162, - 166, 166, 164, 164, 165, 165, 165, 165, 165, 166, 166, 169, 170, 170, 170, 169, - 168, 167, 167, 166, 166, 168, 167, 166, 167, 170, 172, 174, 164, 158, 160, 167, - 170, 176, 183, 183, 185, 182, 180, 184, 192, 193, 189, 191, 191, 188, 187, 184, - 183, 181, 181, 179, 181, 182, 178, 172, 170, 174, 179, 195, 156, 155, 191, 184, - 175, 188, 164, 173, 184, 187, 183, 181, 183, 178, 169, 159, 154, 148, 122, 121, - 145, 149, 155, 156, 141, 141, 145, 128, 129, 158, 86, 74, 109, 114, 109, 125, - 125, 116, 129, 129, 131, 127, 123, 121, 122, 120, 114, 116, 113, 110, 108, 109, - 111, 112, 111, 111, 114, 116, 109, 115, 119, 115, 112, 112, 112, 109, 117, 112, - 105, 119, 119, 115, 122, 107, 112, 120, 117, 115, 120, 116, 109, 114, 111, 114, - 118, 118, 117, 117, 118, 123, 125, 117, 118, 120, 115, 117, 119, 111, 120, 128, - 119, 103, 112, 128, 104, 59, 41, 96, 135, 143, 150, 157, 155, 152, 157, 153, - 150, 149, 152, 157, 159, 158, 151, 152, 152, 150, 146, 144, 144, 144, 137, 138, - 137, 139, 142, 143, 145, 146, 150, 147, 145, 148, 148, 148, 151, 156, 156, 162, - 165, 161, 159, 162, 162, 158, 164, 164, 164, 164, 164, 165, 165, 166, 173, 172, - 172, 172, 169, 168, 165, 165, 165, 167, 167, 167, 166, 167, 171, 173, 167, 159, - 158, 167, 174, 173, 172, 173, 180, 186, 186, 181, 183, 190, 190, 187, 192, 191, - 188, 187, 184, 184, 183, 183, 179, 177, 174, 169, 165, 163, 164, 165, 134, 167, - 174, 193, 207, 184, 173, 174, 176, 190, 192, 182, 179, 185, 181, 167, 159, 157, - 150, 120, 120, 149, 153, 152, 144, 159, 141, 147, 167, 150, 131, 124, 84, 119, - 120, 112, 129, 128, 117, 130, 125, 128, 127, 124, 126, 129, 127, 121, 123, 120, - 114, 112, 112, 113, 113, 113, 116, 119, 119, 107, 109, 111, 111, 110, 109, 110, - 111, 110, 110, 110, 110, 110, 110, 110, 111, 103, 112, 111, 110, 113, 109, 106, - 113, 98, 106, 109, 107, 109, 117, 120, 119, 116, 119, 121, 120, 116, 115, 115, - 118, 119, 122, 121, 108, 119, 115, 115, 66, 29, 49, 83, 117, 141, 150, 148, - 144, 154, 154, 155, 155, 157, 161, 161, 158, 147, 145, 145, 148, 153, 155, 154, - 152, 154, 156, 155, 150, 141, 134, 131, 131, 140, 142, 146, 150, 151, 149, 144, - 140, 152, 153, 158, 162, 161, 156, 158, 164, 162, 164, 162, 158, 159, 165, 168, - 168, 165, 166, 169, 171, 169, 166, 160, 158, 166, 163, 161, 162, 165, 167, 165, - 163, 142, 155, 170, 175, 173, 172, 176, 183, 183, 183, 182, 184, 186, 189, 190, - 189, 192, 189, 185, 183, 183, 183, 182, 181, 183, 179, 172, 166, 164, 161, 156, - 149, 170, 165, 183, 195, 183, 187, 186, 161, 177, 189, 197, 194, 185, 177, 171, - 167, 145, 152, 155, 140, 118, 153, 153, 156, 165, 149, 146, 159, 162, 149, 140, - 143, 96, 114, 109, 117, 123, 112, 122, 121, 127, 126, 132, 132, 123, 123, 122, - 109, 121, 118, 116, 118, 119, 118, 115, 114, 116, 121, 119, 112, 113, 112, 110, - 107, 107, 107, 109, 110, 109, 108, 108, 107, 107, 107, 108, 107, 115, 114, 112, - 116, 113, 109, 117, 111, 115, 113, 105, 101, 104, 106, 105, 106, 109, 111, 111, - 111, 111, 113, 115, 117, 116, 117, 113, 123, 112, 119, 84, 33, 38, 47, 60, - 79, 108, 140, 162, 163, 161, 155, 151, 153, 157, 157, 153, 155, 153, 153, 154, - 158, 161, 164, 164, 158, 158, 157, 153, 150, 148, 148, 149, 146, 142, 138, 137, - 139, 144, 147, 148, 143, 144, 149, 156, 157, 158, 162, 169, 164, 167, 165, 161, - 162, 166, 168, 166, 173, 173, 171, 168, 164, 162, 161, 161, 159, 161, 163, 166, - 168, 164, 157, 152, 161, 168, 175, 179, 177, 176, 177, 180, 188, 187, 188, 190, - 192, 192, 189, 186, 190, 187, 184, 182, 182, 182, 181, 180, 171, 175, 176, 170, - 163, 163, 170, 176, 168, 184, 192, 193, 194, 189, 182, 180, 197, 202, 201, 192, - 183, 179, 177, 174, 163, 158, 146, 128, 113, 157, 165, 171, 153, 148, 154, 169, - 173, 162, 149, 144, 119, 104, 118, 105, 126, 118, 121, 121, 120, 116, 120, 123, - 121, 126, 127, 114, 125, 121, 115, 111, 107, 107, 113, 118, 108, 115, 117, 112, - 113, 112, 111, 109, 109, 110, 111, 114, 113, 110, 108, 107, 108, 108, 109, 108, - 115, 113, 111, 116, 114, 111, 118, 113, 115, 111, 105, 102, 105, 109, 110, 115, - 117, 119, 119, 120, 121, 123, 124, 119, 113, 117, 119, 129, 114, 125, 100, 28, - 31, 34, 34, 39, 60, 93, 118, 132, 142, 152, 158, 166, 169, 164, 157, 160, - 159, 158, 156, 157, 159, 164, 167, 162, 162, 162, 163, 163, 162, 159, 157, 152, - 146, 140, 135, 137, 141, 146, 149, 143, 141, 144, 147, 149, 148, 153, 160, 162, - 165, 164, 161, 160, 164, 163, 160, 166, 169, 168, 167, 162, 162, 162, 166, 164, - 161, 155, 152, 153, 157, 161, 162, 176, 176, 176, 177, 179, 181, 181, 180, 189, - 190, 192, 194, 195, 193, 188, 184, 189, 187, 184, 182, 182, 182, 180, 178, 173, - 173, 171, 165, 160, 160, 167, 174, 171, 201, 200, 190, 199, 189, 178, 196, 199, - 200, 195, 187, 181, 179, 176, 171, 160, 155, 148, 138, 127, 166, 160, 157, 145, - 148, 156, 166, 171, 166, 152, 141, 143, 94, 118, 97, 125, 119, 118, 118, 125, - 117, 117, 117, 113, 118, 117, 104, 101, 111, 122, 127, 122, 116, 112, 109, 110, - 113, 116, 102, 106, 109, 112, 113, 114, 114, 117, 118, 116, 113, 111, 111, 112, - 114, 116, 110, 117, 113, 112, 118, 117, 113, 119, 113, 114, 114, 113, 113, 117, - 120, 123, 126, 127, 127, 127, 127, 127, 127, 128, 121, 120, 122, 120, 131, 120, - 127, 91, 24, 32, 42, 42, 37, 36, 45, 55, 132, 139, 141, 139, 145, 159, - 170, 174, 164, 165, 165, 162, 157, 156, 159, 162, 164, 165, 168, 172, 173, 169, - 159, 151, 160, 156, 153, 151, 151, 148, 146, 143, 146, 143, 141, 144, 145, 146, - 149, 155, 170, 174, 175, 172, 172, 175, 173, 169, 165, 170, 173, 172, 166, 161, - 160, 160, 160, 156, 149, 147, 150, 159, 169, 176, 176, 175, 175, 176, 178, 181, - 184, 185, 188, 188, 189, 192, 193, 192, 188, 185, 188, 185, 183, 181, 181, 180, - 178, 176, 182, 169, 158, 158, 164, 166, 163, 161, 186, 204, 201, 189, 190, 186, - 184, 197, 186, 188, 187, 184, 184, 183, 175, 166, 154, 153, 153, 148, 134, 162, - 148, 139, 167, 171, 172, 170, 172, 175, 166, 155, 151, 105, 104, 105, 122, 115, - 119, 114, 125, 119, 118, 115, 108, 111, 113, 103, 114, 115, 111, 105, 104, 109, - 114, 115, 113, 112, 112, 93, 99, 105, 111, 113, 113, 112, 114, 114, 112, 110, - 109, 109, 112, 115, 118, 114, 120, 114, 113, 120, 119, 115, 120, 117, 119, 120, - 121, 119, 117, 116, 118, 120, 118, 118, 119, 120, 121, 120, 120, 119, 126, 126, - 113, 125, 123, 119, 63, 29, 32, 37, 39, 36, 35, 37, 40, 46, 81, 120, - 143, 154, 159, 156, 147, 167, 171, 173, 172, 167, 164, 164, 166, 167, 166, 166, - 167, 168, 166, 159, 153, 164, 163, 162, 162, 161, 158, 151, 147, 143, 138, 137, - 142, 145, 148, 154, 161, 158, 162, 165, 164, 165, 167, 166, 162, 175, 176, 174, - 169, 162, 157, 156, 156, 146, 151, 158, 165, 169, 171, 171, 171, 174, 176, 177, - 177, 175, 178, 184, 190, 188, 187, 186, 188, 190, 192, 191, 190, 185, 183, 181, - 180, 179, 177, 174, 172, 172, 161, 156, 163, 171, 173, 174, 175, 208, 199, 199, - 193, 179, 186, 198, 190, 187, 188, 186, 185, 187, 188, 181, 172, 165, 159, 151, - 137, 116, 149, 150, 157, 169, 173, 172, 165, 164, 170, 164, 154, 147, 134, 88, - 125, 122, 113, 124, 114, 113, 114, 119, 119, 114, 120, 127, 123, 131, 128, 121, - 114, 116, 120, 117, 109, 107, 103, 102, 92, 98, 104, 107, 107, 106, 105, 105, - 105, 105, 103, 103, 104, 108, 110, 112, 110, 114, 108, 106, 114, 113, 109, 115, - 111, 112, 115, 119, 118, 113, 112, 113, 114, 112, 112, 115, 119, 121, 122, 121, - 114, 124, 123, 105, 117, 118, 109, 43, 33, 32, 33, 36, 38, 39, 38, 37, - 30, 43, 53, 59, 80, 119, 150, 163, 160, 164, 169, 172, 172, 171, 170, 170, - 169, 165, 160, 157, 158, 161, 164, 165, 166, 164, 162, 162, 162, 164, 162, 160, - 144, 139, 135, 138, 140, 140, 143, 148, 158, 163, 165, 165, 165, 169, 168, 165, - 164, 161, 154, 151, 151, 157, 162, 166, 157, 161, 166, 170, 171, 173, 174, 176, - 177, 181, 183, 182, 178, 178, 183, 188, 188, 187, 186, 187, 190, 192, 193, 192, - 182, 180, 178, 177, 176, 174, 171, 168, 158, 159, 165, 170, 166, 163, 174, 189, - 218, 197, 199, 197, 180, 193, 207, 187, 197, 195, 188, 182, 182, 184, 182, 176, - 166, 160, 152, 137, 113, 146, 156, 171, 156, 162, 166, 165, 163, 166, 158, 148, - 145, 159, 84, 133, 128, 120, 127, 120, 116, 116, 125, 126, 121, 128, 132, 126, - 80, 89, 98, 105, 111, 109, 90, 68, 104, 96, 91, 102, 104, 105, 105, 104, - 103, 104, 106, 106, 105, 105, 105, 106, 108, 108, 109, 107, 110, 103, 101, 110, - 111, 106, 110, 106, 106, 109, 115, 115, 113, 114, 119, 115, 113, 113, 116, 120, - 123, 123, 122, 110, 116, 116, 104, 116, 112, 106, 49, 33, 34, 38, 41, 42, - 38, 32, 27, 38, 40, 35, 35, 61, 103, 128, 131, 154, 155, 158, 162, 167, - 170, 170, 169, 167, 165, 162, 159, 158, 161, 166, 170, 166, 165, 163, 164, 166, - 167, 167, 165, 154, 147, 140, 141, 140, 138, 136, 137, 131, 134, 134, 133, 133, - 137, 136, 134, 147, 145, 142, 148, 156, 167, 172, 174, 172, 172, 169, 167, 166, - 172, 180, 186, 181, 181, 182, 183, 183, 183, 182, 181, 186, 185, 186, 187, 190, - 190, 188, 186, 179, 178, 176, 175, 174, 172, 168, 164, 162, 163, 169, 171, 163, - 157, 172, 192, 206, 201, 199, 195, 194, 200, 201, 193, 197, 197, 191, 184, 181, - 181, 179, 174, 159, 157, 156, 146, 123, 150, 154, 166, 166, 170, 175, 180, 179, - 176, 168, 162, 147, 164, 92, 115, 134, 130, 123, 126, 128, 122, 126, 128, 125, - 128, 123, 105, 107, 109, 104, 99, 105, 117, 118, 109, 104, 94, 87, 109, 110, - 108, 106, 104, 106, 110, 114, 111, 111, 111, 111, 112, 112, 111, 111, 113, 115, - 108, 106, 116, 116, 112, 116, 116, 112, 112, 116, 115, 111, 113, 119, 112, 109, - 108, 109, 113, 114, 113, 111, 110, 110, 113, 108, 119, 107, 108, 65, 37, 37, - 37, 37, 36, 35, 34, 34, 36, 32, 26, 35, 78, 132, 160, 160, 156, 154, - 154, 157, 163, 167, 168, 167, 162, 166, 170, 170, 167, 163, 163, 164, 167, 168, - 169, 171, 172, 170, 165, 161, 161, 153, 150, 153, 154, 153, 151, 151, 152, 155, - 154, 151, 151, 153, 153, 150, 153, 152, 156, 166, 177, 181, 176, 169, 165, 171, - 176, 178, 178, 177, 179, 181, 179, 177, 177, 181, 186, 187, 182, 176, 182, 182, - 184, 187, 188, 186, 182, 178, 178, 176, 175, 174, 173, 170, 166, 162, 175, 166, - 164, 169, 172, 172, 183, 199, 188, 206, 197, 190, 207, 203, 190, 198, 191, 197, - 198, 195, 190, 186, 179, 172, 166, 159, 154, 143, 120, 148, 151, 163, 167, 165, - 168, 171, 170, 166, 161, 161, 150, 156, 101, 93, 137, 137, 117, 128, 129, 119, - 117, 123, 125, 127, 114, 88, 105, 110, 108, 98, 96, 102, 101, 92, 101, 92, - 88, 101, 105, 103, 99, 97, 102, 106, 106, 106, 109, 113, 115, 116, 115, 114, - 114, 116, 119, 111, 106, 113, 114, 114, 122, 117, 118, 116, 110, 110, 112, 113, - 109, 108, 107, 106, 107, 110, 111, 110, 109, 107, 121, 123, 113, 113, 120, 106, - 80, 36, 36, 40, 41, 35, 26, 31, 40, 36, 35, 32, 42, 83, 137, 165, - 166, 171, 172, 171, 167, 162, 159, 158, 158, 160, 162, 163, 164, 164, 166, 168, - 170, 171, 172, 170, 170, 169, 170, 171, 170, 166, 159, 151, 148, 151, 154, 155, - 154, 158, 158, 158, 159, 160, 160, 161, 161, 163, 163, 165, 168, 171, 175, 178, - 179, 173, 173, 173, 173, 174, 176, 178, 181, 182, 182, 181, 181, 181, 182, 183, - 184, 183, 183, 184, 186, 187, 186, 183, 180, 179, 179, 175, 169, 163, 161, 165, - 169, 166, 169, 170, 168, 173, 184, 192, 195, 198, 186, 187, 194, 199, 203, 200, - 185, 198, 192, 185, 184, 186, 185, 179, 174, 177, 165, 154, 142, 123, 156, 156, - 163, 169, 166, 168, 172, 171, 167, 164, 166, 150, 143, 111, 88, 119, 118, 127, - 126, 125, 121, 116, 115, 116, 114, 109, 102, 118, 106, 97, 98, 107, 107, 94, - 79, 116, 145, 103, 96, 101, 100, 96, 95, 100, 103, 104, 102, 106, 110, 112, - 112, 113, 115, 117, 125, 128, 121, 115, 117, 113, 107, 111, 111, 114, 114, 110, - 110, 114, 115, 111, 114, 113, 111, 112, 114, 115, 114, 113, 112, 121, 122, 116, - 119, 126, 119, 102, 44, 38, 35, 34, 33, 37, 54, 69, 78, 83, 81, 82, - 106, 144, 165, 167, 178, 180, 181, 179, 176, 173, 173, 173, 169, 174, 177, 176, - 172, 170, 174, 178, 182, 182, 180, 180, 181, 183, 185, 187, 182, 178, 171, 163, - 157, 156, 158, 160, 152, 154, 158, 161, 163, 162, 161, 159, 163, 164, 167, 171, - 175, 178, 181, 182, 183, 181, 179, 178, 177, 178, 179, 180, 183, 183, 183, 183, - 183, 184, 184, 185, 183, 183, 184, 186, 188, 188, 186, 184, 176, 174, 172, 168, - 165, 164, 166, 169, 170, 171, 171, 173, 183, 194, 198, 196, 199, 203, 213, 211, - 195, 191, 200, 202, 194, 192, 189, 186, 182, 179, 178, 177, 169, 170, 168, 150, - 117, 141, 150, 169, 169, 167, 168, 173, 172, 168, 164, 165, 147, 138, 108, 87, - 123, 126, 129, 123, 116, 115, 116, 119, 123, 126, 123, 121, 105, 100, 95, 95, - 99, 101, 96, 91, 77, 101, 102, 93, 98, 98, 95, 94, 99, 102, 102, 98, - 104, 107, 106, 104, 105, 110, 115, 108, 115, 113, 112, 117, 112, 104, 109, 107, - 110, 112, 111, 113, 116, 117, 113, 120, 117, 115, 115, 116, 117, 116, 115, 114, - 114, 113, 113, 117, 121, 119, 113, 78, 70, 64, 63, 69, 80, 99, 114, 117, - 126, 127, 122, 129, 149, 164, 165, 178, 181, 184, 185, 184, 183, 182, 182, 179, - 186, 191, 189, 180, 175, 178, 184, 185, 184, 184, 184, 186, 189, 192, 194, 190, - 188, 183, 173, 162, 156, 156, 158, 154, 155, 157, 159, 161, 163, 163, 164, 160, - 162, 164, 168, 171, 173, 175, 175, 181, 179, 177, 175, 174, 174, 175, 176, 178, - 178, 179, 181, 180, 181, 180, 181, 182, 181, 180, 181, 182, 183, 181, 180, 174, - 172, 169, 168, 169, 170, 171, 170, 170, 171, 173, 180, 192, 203, 203, 197, 208, - 203, 207, 206, 195, 194, 199, 195, 187, 189, 188, 183, 176, 171, 173, 175, 170, - 164, 157, 144, 120, 147, 148, 156, 168, 166, 168, 173, 173, 168, 164, 163, 153, - 137, 107, 82, 122, 132, 134, 129, 134, 133, 132, 129, 124, 120, 114, 111, 115, - 113, 109, 104, 99, 97, 97, 99, 91, 95, 119, 95, 101, 101, 98, 96, 100, - 101, 101, 100, 104, 105, 102, 97, 96, 101, 108, 94, 104, 103, 106, 114, 112, - 107, 111, 107, 112, 114, 114, 115, 120, 118, 115, 120, 117, 114, 113, 114, 115, - 115, 114, 116, 111, 108, 111, 113, 112, 112, 112, 113, 110, 109, 111, 117, 122, - 130, 136, 134, 144, 148, 142, 144, 157, 168, 170, 176, 180, 184, 186, 186, 184, - 183, 183, 183, 188, 192, 191, 185, 181, 181, 183, 185, 184, 182, 182, 183, 186, - 189, 192, 187, 187, 184, 178, 169, 163, 159, 158, 161, 158, 155, 152, 153, 157, - 162, 165, 160, 162, 163, 165, 166, 167, 167, 166, 174, 172, 171, 171, 171, 172, - 174, 175, 175, 177, 177, 179, 178, 179, 177, 177, 183, 181, 179, 178, 178, 179, - 178, 176, 177, 173, 171, 171, 174, 176, 175, 172, 167, 173, 180, 187, 197, 205, - 204, 198, 207, 195, 194, 196, 195, 200, 202, 193, 190, 191, 189, 183, 177, 173, - 174, 176, 170, 160, 153, 144, 126, 156, 153, 158, 167, 164, 165, 172, 173, 168, - 162, 160, 161, 142, 114, 78, 115, 133, 136, 140, 127, 129, 132, 132, 130, 127, - 124, 124, 126, 126, 123, 118, 111, 107, 106, 107, 116, 99, 108, 102, 107, 106, - 102, 100, 102, 102, 101, 102, 104, 105, 102, 98, 98, 102, 109, 108, 115, 111, - 110, 116, 113, 107, 112, 112, 116, 118, 117, 117, 121, 119, 115, 120, 117, 114, - 113, 114, 116, 115, 114, 120, 114, 113, 117, 118, 114, 113, 116, 124, 126, 130, - 133, 136, 136, 136, 134, 144, 151, 154, 153, 158, 170, 179, 179, 181, 184, 188, - 190, 189, 187, 186, 185, 185, 186, 187, 188, 188, 187, 183, 180, 187, 186, 184, - 182, 182, 184, 186, 188, 183, 183, 183, 185, 185, 181, 173, 168, 162, 160, 157, - 154, 153, 153, 155, 156, 160, 160, 162, 163, 164, 164, 165, 165, 173, 172, 171, - 171, 171, 173, 174, 175, 174, 174, 175, 176, 176, 176, 176, 177, 180, 179, 177, - 177, 179, 180, 180, 179, 177, 174, 171, 172, 175, 177, 175, 173, 169, 180, 191, - 196, 199, 203, 204, 203, 200, 198, 203, 202, 192, 195, 205, 206, 199, 197, 191, - 186, 183, 181, 179, 179, 163, 168, 173, 158, 125, 149, 157, 176, 166, 162, 162, - 169, 171, 167, 161, 158, 157, 142, 124, 79, 109, 130, 129, 139, 127, 131, 134, - 135, 134, 133, 132, 132, 126, 125, 124, 125, 125, 124, 121, 119, 115, 110, 99, - 104, 109, 109, 105, 103, 105, 105, 103, 104, 106, 106, 105, 106, 109, 113, 116, - 115, 120, 115, 112, 117, 115, 110, 116, 117, 120, 121, 118, 118, 121, 121, 117, - 122, 118, 115, 114, 116, 118, 118, 118, 116, 114, 115, 118, 119, 118, 119, 121, - 128, 134, 139, 139, 140, 143, 144, 142, 150, 155, 158, 158, 163, 173, 178, 178, - 182, 185, 188, 189, 188, 186, 186, 186, 187, 184, 183, 186, 190, 190, 186, 181, - 186, 184, 183, 182, 181, 180, 180, 180, 179, 178, 180, 185, 190, 190, 184, 177, - 171, 172, 173, 172, 169, 164, 159, 155, 156, 156, 156, 157, 158, 160, 162, 163, - 169, 169, 167, 166, 166, 166, 167, 168, 167, 167, 166, 166, 166, 168, 169, 169, - 169, 168, 169, 172, 176, 178, 179, 178, 176, 174, 172, 172, 173, 175, 176, 176, - 179, 192, 202, 203, 201, 203, 205, 206, 208, 199, 198, 199, 196, 200, 204, 197, - 199, 195, 188, 184, 181, 179, 177, 176, 169, 169, 169, 155, 125, 150, 154, 168, - 169, 162, 161, 166, 170, 167, 161, 158, 147, 136, 131, 84, 110, 129, 118, 129, - 137, 137, 136, 136, 135, 134, 132, 131, 136, 133, 131, 133, 136, 136, 129, 123, - 114, 133, 120, 100, 106, 107, 104, 103, 107, 108, 106, 107, 106, 105, 108, 112, - 116, 117, 117, 110, 116, 113, 112, 119, 117, 112, 118, 117, 120, 120, 117, 118, - 122, 122, 120, 122, 118, 115, 114, 117, 120, 120, 121, 114, 116, 116, 114, 116, - 120, 123, 124, 132, 141, 149, 148, 148, 153, 158, 159, 157, 163, 167, 167, 167, - 171, 173, 174, 179, 182, 184, 185, 185, 184, 185, 187, 187, 185, 185, 185, 186, - 186, 185, 183, 182, 181, 181, 180, 179, 178, 176, 174, 179, 179, 180, 182, 184, - 185, 184, 184, 188, 187, 185, 183, 179, 175, 171, 169, 164, 162, 159, 157, 157, - 158, 160, 161, 163, 162, 161, 160, 161, 162, 164, 166, 164, 162, 160, 159, 160, - 162, 163, 166, 167, 167, 168, 171, 175, 176, 175, 174, 175, 175, 175, 174, 175, - 178, 182, 186, 191, 199, 205, 204, 202, 203, 204, 203, 212, 197, 191, 195, 198, - 203, 201, 187, 195, 194, 190, 183, 176, 172, 174, 177, 175, 166, 158, 148, 128, - 157, 155, 160, 173, 165, 161, 166, 170, 168, 164, 161, 149, 135, 131, 81, 110, - 134, 118, 129, 124, 123, 123, 128, 135, 140, 142, 142, 143, 140, 137, 136, 136, - 135, 131, 127, 118, 137, 127, 95, 102, 105, 103, 104, 106, 109, 108, 111, 107, - 104, 106, 111, 115, 113, 110, 113, 120, 118, 117, 122, 118, 110, 115, 115, 118, - 117, 114, 116, 121, 123, 121, 120, 117, 113, 113, 115, 118, 119, 121, 119, 123, - 121, 114, 113, 123, 127, 126, 126, 141, 153, 153, 152, 156, 160, 161, 162, 173, - 180, 179, 175, 172, 173, 174, 180, 182, 184, 186, 185, 187, 188, 192, 184, 186, - 186, 184, 180, 180, 180, 182, 182, 182, 183, 184, 184, 181, 178, 177, 184, 186, - 186, 183, 179, 180, 185, 189, 200, 194, 184, 177, 173, 175, 178, 182, 184, 181, - 174, 169, 165, 165, 164, 166, 160, 161, 161, 163, 165, 168, 172, 173, 170, 168, - 165, 162, 163, 167, 169, 172, 178, 178, 179, 180, 181, 180, 176, 173, 177, 178, - 179, 178, 178, 182, 190, 197, 198, 201, 202, 200, 200, 203, 201, 196, 198, 200, - 209, 206, 191, 190, 200, 202, 197, 199, 199, 190, 177, 172, 178, 186, 166, 171, - 173, 158, 126, 152, 161, 181, 176, 167, 162, 166, 170, 170, 166, 165, 163, 139, - 128, 73, 107, 139, 125, 138, 137, 131, 124, 123, 125, 127, 125, 121, 129, 129, - 127, 128, 128, 131, 132, 133, 136, 136, 127, 104, 105, 105, 103, 102, 102, 106, - 109, 113, 111, 109, 108, 108, 110, 112, 114, 114, 114, 114, 113, 113, 114, 115, - 115, 123, 118, 113, 113, 117, 119, 117, 114, 113, 115, 115, 115, 118, 121, 115, - 109, 113, 119, 122, 105, 107, 120, 115, 130, 139, 144, 151, 155, 156, 159, 163, - 166, 175, 175, 177, 180, 180, 178, 173, 169, 171, 175, 178, 183, 183, 185, 185, - 188, 180, 183, 186, 192, 195, 195, 188, 183, 186, 183, 180, 177, 176, 176, 178, - 180, 174, 179, 185, 186, 183, 180, 178, 178, 182, 189, 190, 182, 171, 172, 179, - 185, 186, 190, 192, 192, 186, 181, 175, 173, 176, 176, 173, 171, 169, 167, 165, - 165, 164, 165, 167, 171, 177, 184, 188, 191, 196, 191, 188, 188, 185, 177, 171, - 170, 177, 181, 186, 188, 189, 190, 192, 195, 197, 203, 207, 205, 203, 203, 201, - 197, 192, 199, 199, 194, 196, 206, 204, 195, 200, 198, 191, 183, 182, 185, 186, - 183, 172, 170, 168, 155, 139, 145, 157, 155, 172, 170, 168, 167, 167, 168, 168, - 169, 157, 144, 137, 89, 100, 119, 131, 124, 130, 128, 125, 121, 119, 119, 119, - 119, 120, 122, 124, 128, 130, 132, 132, 132, 125, 127, 130, 112, 115, 113, 111, - 108, 108, 108, 110, 108, 107, 105, 105, 107, 109, 112, 114, 111, 112, 110, 111, - 111, 113, 113, 114, 109, 108, 105, 107, 108, 110, 105, 102, 113, 112, 106, 100, - 101, 108, 112, 111, 113, 107, 111, 109, 117, 119, 108, 127, 141, 147, 154, 157, - 158, 159, 164, 167, 166, 167, 170, 174, 176, 173, 168, 162, 166, 168, 173, 177, - 181, 182, 181, 180, 180, 181, 183, 187, 191, 191, 188, 184, 190, 188, 185, 183, - 181, 181, 182, 182, 181, 180, 178, 174, 172, 174, 179, 185, 182, 187, 188, 183, - 179, 182, 186, 187, 191, 190, 188, 184, 180, 179, 181, 183, 183, 182, 180, 179, - 181, 183, 186, 188, 189, 188, 188, 188, 190, 192, 194, 196, 198, 193, 192, 194, - 194, 190, 188, 188, 189, 191, 193, 193, 192, 193, 197, 200, 201, 206, 207, 203, - 201, 202, 202, 200, 202, 207, 205, 198, 198, 204, 203, 194, 196, 196, 191, 184, - 182, 184, 182, 177, 170, 166, 162, 147, 132, 139, 154, 156, 170, 168, 167, 167, - 168, 169, 169, 168, 159, 150, 140, 99, 103, 127, 132, 128, 128, 127, 127, 125, - 123, 121, 118, 117, 120, 120, 119, 119, 120, 122, 124, 125, 126, 127, 129, 108, - 112, 112, 111, 108, 107, 105, 107, 110, 110, 108, 108, 109, 110, 112, 114, 108, - 108, 108, 109, 110, 111, 113, 114, 114, 114, 115, 115, 113, 110, 105, 102, 105, - 105, 100, 92, 89, 96, 103, 105, 101, 96, 107, 108, 106, 98, 95, 129, 144, - 150, 157, 160, 160, 161, 165, 167, 165, 167, 172, 177, 179, 177, 173, 167, 158, - 158, 163, 172, 181, 186, 186, 184, 182, 182, 182, 184, 188, 190, 190, 189, 188, - 187, 186, 184, 182, 181, 179, 179, 183, 180, 176, 171, 169, 171, 177, 183, 179, - 182, 183, 183, 184, 189, 189, 185, 190, 189, 186, 182, 180, 180, 184, 187, 190, - 188, 187, 187, 189, 194, 200, 204, 202, 200, 198, 196, 195, 195, 195, 195, 196, - 191, 189, 193, 195, 194, 195, 197, 200, 200, 199, 197, 195, 196, 199, 202, 204, - 207, 206, 201, 198, 201, 202, 201, 205, 208, 205, 197, 198, 203, 202, 196, 193, - 194, 191, 186, 184, 184, 180, 174, 174, 167, 161, 146, 131, 139, 158, 163, 166, - 165, 165, 167, 169, 170, 169, 168, 157, 154, 140, 109, 100, 132, 129, 129, 132, - 133, 134, 134, 132, 128, 124, 122, 126, 124, 121, 119, 118, 120, 122, 125, 126, - 125, 125, 100, 104, 107, 109, 108, 107, 106, 107, 112, 112, 110, 108, 107, 108, - 107, 108, 107, 108, 108, 109, 111, 113, 115, 116, 111, 113, 113, 111, 105, 100, - 96, 94, 99, 106, 108, 105, 100, 102, 103, 103, 106, 101, 106, 102, 102, 101, - 98, 128, 145, 151, 157, 161, 161, 161, 164, 166, 170, 171, 174, 179, 183, 183, - 181, 177, 165, 162, 162, 169, 179, 187, 188, 186, 184, 183, 182, 183, 185, 189, - 192, 193, 187, 187, 187, 186, 184, 182, 179, 177, 180, 180, 180, 178, 176, 173, - 172, 171, 172, 177, 180, 180, 182, 186, 186, 182, 185, 187, 189, 189, 187, 184, - 184, 184, 191, 191, 190, 190, 191, 194, 199, 201, 199, 198, 196, 195, 195, 196, - 197, 197, 197, 191, 188, 190, 191, 191, 193, 196, 201, 201, 200, 199, 198, 198, - 198, 199, 202, 205, 205, 199, 197, 199, 200, 198, 198, 199, 196, 192, 194, 201, - 202, 199, 192, 192, 190, 185, 184, 186, 183, 177, 175, 167, 161, 149, 135, 141, - 159, 166, 163, 163, 164, 167, 170, 171, 169, 167, 160, 161, 142, 116, 97, 135, - 128, 134, 133, 134, 135, 135, 134, 131, 128, 125, 129, 127, 125, 123, 122, 122, - 124, 125, 124, 122, 120, 104, 108, 111, 114, 113, 113, 111, 112, 109, 109, 108, - 106, 105, 106, 106, 105, 110, 111, 111, 113, 115, 117, 119, 120, 117, 118, 118, - 115, 111, 107, 106, 106, 110, 118, 123, 121, 117, 116, 115, 112, 108, 107, 108, - 101, 113, 126, 115, 125, 143, 149, 156, 160, 160, 160, 161, 163, 170, 170, 172, - 175, 179, 181, 181, 180, 182, 174, 168, 168, 174, 179, 180, 179, 182, 181, 181, - 180, 182, 185, 189, 192, 191, 191, 192, 191, 190, 187, 184, 182, 180, 180, 181, - 180, 178, 173, 167, 163, 162, 170, 177, 177, 178, 182, 185, 186, 188, 190, 191, - 191, 188, 186, 185, 185, 189, 190, 191, 193, 194, 194, 195, 195, 195, 195, 195, - 195, 196, 198, 200, 201, 201, 194, 190, 192, 193, 193, 195, 198, 197, 198, 200, - 202, 202, 201, 199, 197, 196, 201, 202, 198, 196, 197, 196, 194, 194, 193, 191, - 189, 192, 198, 200, 198, 189, 189, 185, 180, 181, 184, 184, 180, 170, 162, 160, - 151, 137, 139, 155, 161, 162, 163, 164, 167, 170, 171, 170, 168, 166, 168, 147, - 118, 96, 133, 129, 137, 130, 130, 130, 130, 129, 128, 127, 127, 125, 126, 126, - 126, 126, 125, 124, 124, 125, 123, 120, 109, 112, 115, 115, 114, 112, 111, 111, - 110, 111, 111, 113, 114, 115, 115, 116, 114, 115, 115, 116, 118, 120, 122, 124, - 126, 126, 126, 126, 127, 127, 127, 127, 120, 124, 124, 119, 116, 119, 120, 118, - 71, 95, 115, 104, 102, 111, 109, 127, 140, 147, 155, 159, 160, 159, 160, 162, - 171, 171, 171, 175, 178, 180, 179, 178, 176, 171, 166, 165, 170, 176, 181, 182, - 177, 178, 179, 179, 178, 180, 183, 186, 189, 189, 190, 190, 189, 187, 184, 183, - 185, 181, 177, 174, 173, 171, 169, 168, 157, 165, 171, 171, 172, 179, 187, 191, - 193, 192, 189, 186, 183, 184, 188, 191, 187, 189, 192, 195, 196, 196, 195, 195, - 194, 193, 193, 193, 193, 195, 197, 198, 197, 191, 188, 190, 193, 193, 196, 199, - 197, 198, 201, 204, 206, 204, 200, 196, 192, 197, 199, 196, 195, 196, 195, 193, - 197, 195, 192, 191, 192, 194, 194, 193, 186, 185, 182, 177, 177, 181, 182, 178, - 171, 163, 162, 157, 142, 141, 154, 160, 164, 164, 164, 167, 170, 171, 171, 169, - 162, 163, 150, 112, 93, 121, 121, 128, 129, 129, 129, 130, 131, 131, 131, 132, - 128, 129, 130, 131, 131, 130, 129, 129, 128, 127, 125, 109, 111, 113, 113, 111, - 110, 110, 111, 114, 115, 116, 119, 121, 122, 123, 123, 119, 119, 119, 120, 122, - 123, 125, 126, 119, 118, 119, 122, 126, 126, 122, 118, 122, 122, 118, 113, 113, - 118, 117, 115, 68, 85, 106, 98, 91, 92, 98, 129, 138, 145, 154, 159, 160, - 160, 161, 163, 169, 172, 175, 179, 181, 180, 177, 173, 168, 167, 167, 168, 171, - 176, 181, 184, 176, 179, 182, 182, 180, 179, 180, 182, 186, 186, 186, 186, 185, - 185, 184, 183, 188, 183, 177, 175, 176, 178, 178, 177, 161, 163, 162, 160, 164, - 173, 179, 180, 187, 187, 186, 185, 183, 184, 187, 190, 185, 187, 188, 190, 192, - 192, 192, 192, 192, 191, 190, 189, 190, 191, 192, 193, 191, 186, 184, 187, 190, - 190, 191, 195, 199, 199, 199, 202, 204, 203, 199, 195, 193, 197, 197, 193, 192, - 195, 197, 197, 198, 195, 193, 192, 192, 190, 188, 187, 187, 188, 185, 181, 181, - 182, 180, 174, 175, 165, 164, 159, 144, 141, 154, 161, 168, 167, 165, 166, 169, - 171, 171, 171, 157, 157, 155, 108, 97, 112, 115, 116, 121, 124, 128, 131, 133, - 133, 132, 131, 133, 133, 132, 132, 131, 131, 131, 132, 129, 129, 129, 108, 110, - 113, 113, 113, 114, 115, 118, 113, 113, 115, 116, 117, 118, 116, 117, 121, 122, - 121, 123, 123, 126, 126, 128, 126, 125, 125, 130, 132, 131, 122, 114, 123, 123, - 121, 119, 121, 123, 118, 112, 118, 91, 81, 86, 107, 115, 105, 122, 139, 145, - 154, 160, 161, 161, 163, 164, 165, 168, 175, 180, 182, 178, 171, 164, 176, 177, - 177, 175, 173, 171, 172, 173, 178, 182, 186, 187, 184, 182, 182, 182, 188, 188, - 188, 188, 188, 188, 188, 188, 186, 184, 182, 183, 186, 187, 185, 183, 170, 165, - 156, 151, 156, 166, 168, 165, 175, 180, 186, 190, 189, 187, 185, 184, 184, 184, - 183, 183, 183, 184, 185, 186, 193, 193, 192, 191, 192, 193, 195, 196, 194, 189, - 186, 189, 190, 189, 189, 192, 201, 199, 197, 197, 199, 199, 196, 193, 195, 197, - 196, 191, 190, 196, 200, 201, 195, 192, 190, 191, 191, 188, 185, 184, 191, 193, - 192, 188, 187, 186, 180, 172, 173, 161, 159, 154, 138, 135, 149, 157, 170, 169, - 166, 166, 169, 171, 172, 172, 160, 161, 167, 114, 110, 114, 119, 115, 109, 114, - 120, 125, 128, 127, 124, 122, 133, 131, 128, 125, 123, 124, 126, 127, 125, 128, - 130, 112, 114, 115, 116, 115, 113, 111, 110, 122, 117, 105, 120, 111, 118, 113, - 125, 120, 113, 103, 106, 110, 116, 112, 110, 119, 129, 130, 125, 117, 121, 122, - 122, 124, 121, 121, 121, 120, 118, 117, 117, 124, 126, 119, 112, 102, 90, 95, - 116, 137, 145, 149, 154, 163, 159, 155, 162, 165, 170, 176, 179, 178, 175, 171, - 170, 175, 176, 176, 175, 173, 173, 175, 177, 176, 181, 187, 192, 193, 189, 184, - 180, 181, 182, 184, 188, 190, 188, 183, 179, 179, 186, 191, 188, 179, 173, 173, - 176, 179, 173, 159, 155, 161, 158, 155, 164, 169, 175, 183, 189, 186, 178, 173, - 175, 177, 179, 185, 191, 188, 179, 178, 183, 193, 188, 184, 184, 189, 193, 194, - 194, 195, 190, 186, 186, 190, 195, 197, 197, 201, 202, 201, 199, 196, 194, 195, - 197, 197, 197, 196, 195, 195, 194, 193, 193, 195, 194, 194, 195, 194, 191, 185, - 181, 186, 182, 180, 183, 184, 180, 177, 178, 172, 169, 164, 156, 144, 137, 142, - 152, 164, 164, 163, 165, 168, 170, 171, 172, 155, 155, 162, 93, 127, 115, 111, - 123, 115, 116, 117, 121, 123, 123, 121, 118, 121, 118, 115, 114, 115, 119, 123, - 127, 122, 125, 127, 112, 113, 113, 113, 111, 109, 108, 107, 106, 112, 105, 112, - 101, 111, 102, 103, 123, 121, 113, 104, 97, 96, 101, 106, 98, 103, 105, 104, - 107, 113, 114, 110, 104, 107, 118, 129, 129, 123, 118, 121, 103, 119, 125, 126, - 129, 128, 124, 128, 134, 144, 148, 152, 160, 157, 154, 161, 165, 169, 175, 177, - 177, 174, 172, 172, 174, 176, 177, 177, 176, 176, 177, 179, 173, 176, 181, 185, - 188, 188, 187, 186, 187, 183, 178, 177, 179, 182, 185, 186, 183, 177, 174, 178, - 186, 187, 180, 172, 168, 176, 176, 169, 160, 146, 141, 149, 160, 173, 176, 168, - 175, 191, 189, 173, 179, 182, 187, 189, 183, 179, 186, 198, 185, 185, 186, 187, - 188, 190, 193, 195, 202, 197, 190, 188, 189, 192, 193, 194, 195, 196, 197, 196, - 195, 195, 197, 198, 197, 197, 196, 195, 195, 194, 193, 193, 196, 195, 194, 192, - 190, 185, 178, 173, 178, 174, 174, 178, 179, 176, 173, 174, 176, 171, 164, 153, - 143, 138, 146, 158, 163, 165, 166, 169, 171, 171, 169, 168, 158, 159, 152, 106, - 131, 118, 112, 121, 118, 117, 116, 118, 120, 120, 119, 117, 120, 121, 122, 122, - 120, 118, 116, 115, 119, 124, 126, 113, 113, 113, 111, 111, 111, 112, 112, 104, - 128, 128, 121, 94, 104, 102, 109, 95, 96, 96, 96, 98, 102, 109, 114, 119, - 118, 114, 112, 114, 115, 109, 100, 111, 105, 110, 118, 117, 107, 109, 120, 120, - 136, 131, 119, 122, 126, 121, 116, 134, 144, 150, 152, 158, 156, 154, 161, 163, - 167, 172, 175, 175, 174, 174, 174, 174, 176, 179, 180, 179, 178, 178, 179, 175, - 176, 177, 179, 181, 184, 186, 188, 189, 184, 177, 173, 174, 178, 181, 183, 175, - 179, 183, 183, 181, 180, 182, 185, 179, 176, 171, 170, 170, 163, 150, 138, 144, - 146, 157, 171, 176, 174, 183, 197, 187, 179, 174, 176, 179, 178, 177, 177, 179, - 184, 189, 190, 188, 189, 195, 199, 204, 199, 192, 188, 188, 190, 193, 194, 194, - 196, 197, 197, 196, 195, 197, 199, 197, 197, 196, 195, 195, 194, 193, 193, 199, - 198, 196, 194, 191, 186, 180, 176, 177, 175, 176, 181, 183, 180, 177, 177, 183, - 176, 165, 152, 140, 137, 147, 161, 162, 166, 171, 174, 174, 171, 167, 166, 161, - 163, 135, 123, 136, 123, 117, 120, 118, 116, 113, 113, 116, 118, 119, 120, 117, - 119, 121, 123, 124, 124, 123, 122, 120, 122, 125, 110, 109, 109, 108, 109, 111, - 114, 115, 109, 118, 109, 109, 90, 100, 95, 101, 102, 95, 92, 100, 112, 115, - 104, 92, 100, 101, 103, 109, 116, 121, 120, 117, 127, 113, 111, 120, 120, 108, - 108, 116, 114, 123, 117, 110, 113, 113, 108, 110, 132, 146, 151, 151, 157, 157, - 156, 163, 163, 166, 170, 172, 173, 174, 176, 177, 175, 178, 181, 182, 180, 178, - 177, 177, 182, 181, 180, 179, 179, 180, 180, 181, 185, 184, 182, 181, 180, 178, - 174, 172, 172, 180, 186, 182, 172, 168, 174, 182, 181, 170, 163, 162, 165, 171, - 160, 139, 131, 129, 139, 158, 167, 164, 170, 185, 189, 186, 184, 186, 188, 186, - 183, 179, 181, 184, 188, 189, 191, 194, 200, 204, 200, 196, 190, 187, 187, 191, - 196, 199, 199, 201, 202, 201, 198, 196, 197, 197, 196, 196, 196, 195, 195, 194, - 194, 194, 194, 193, 193, 193, 193, 191, 187, 184, 182, 179, 180, 185, 187, 183, - 180, 180, 186, 179, 167, 153, 140, 135, 144, 158, 164, 169, 173, 175, 173, 170, - 167, 166, 162, 164, 120, 137, 138, 130, 126, 126, 118, 115, 112, 111, 114, 118, - 121, 123, 120, 119, 117, 116, 117, 121, 124, 127, 121, 123, 126, 100, 100, 97, - 96, 96, 97, 100, 102, 115, 97, 80, 107, 111, 115, 95, 92, 110, 104, 102, - 110, 120, 122, 111, 100, 98, 100, 105, 111, 116, 119, 121, 123, 121, 114, 121, - 138, 143, 128, 112, 106, 109, 114, 117, 123, 118, 93, 80, 90, 127, 144, 149, - 147, 153, 156, 156, 163, 163, 166, 169, 171, 173, 174, 177, 179, 177, 179, 182, - 182, 179, 176, 174, 174, 185, 185, 184, 183, 182, 179, 177, 176, 181, 181, 182, - 184, 184, 181, 176, 172, 180, 174, 169, 169, 174, 174, 169, 163, 165, 168, 176, - 164, 142, 140, 139, 123, 125, 142, 140, 126, 143, 180, 185, 164, 171, 180, 188, - 186, 180, 179, 185, 192, 184, 182, 182, 185, 192, 198, 201, 202, 197, 194, 190, - 187, 187, 190, 195, 199, 199, 201, 202, 202, 199, 198, 197, 198, 196, 196, 195, - 195, 195, 195, 194, 194, 188, 187, 187, 188, 189, 188, 186, 183, 181, 178, 178, - 182, 182, 178, 174, 174, 180, 174, 165, 153, 141, 135, 143, 155, 166, 170, 173, - 174, 170, 168, 168, 169, 161, 160, 117, 145, 139, 139, 136, 137, 126, 122, 117, - 114, 115, 117, 119, 119, 127, 125, 121, 118, 115, 115, 116, 117, 121, 123, 124, - 94, 92, 89, 86, 84, 84, 85, 86, 95, 91, 94, 129, 123, 115, 97, 109, - 100, 105, 108, 108, 107, 110, 117, 124, 120, 118, 118, 120, 119, 115, 116, 120, - 117, 114, 117, 126, 128, 118, 104, 94, 121, 116, 114, 118, 110, 81, 71, 89, - 120, 139, 145, 142, 148, 153, 155, 162, 164, 167, 171, 173, 174, 175, 177, 179, - 178, 180, 182, 181, 178, 176, 175, 175, 181, 182, 184, 185, 184, 182, 180, 178, - 181, 179, 178, 178, 181, 183, 184, 184, 177, 178, 178, 179, 178, 178, 177, 176, - 176, 174, 182, 170, 144, 134, 114, 71, 81, 101, 106, 92, 92, 121, 152, 166, - 180, 177, 171, 170, 178, 184, 182, 175, 183, 180, 179, 184, 193, 199, 201, 200, - 201, 199, 196, 191, 188, 188, 191, 194, 192, 195, 198, 199, 199, 198, 199, 200, - 195, 195, 195, 195, 195, 195, 195, 195, 193, 191, 189, 189, 189, 187, 184, 182, - 183, 178, 177, 179, 180, 176, 173, 174, 172, 168, 162, 153, 142, 137, 144, 155, - 165, 170, 173, 173, 169, 166, 168, 170, 157, 152, 129, 149, 140, 147, 142, 144, - 137, 132, 126, 122, 119, 117, 115, 113, 123, 126, 129, 131, 131, 128, 125, 122, - 119, 120, 122, 96, 96, 94, 93, 92, 92, 93, 94, 81, 95, 106, 129, 109, - 99, 90, 107, 111, 115, 114, 108, 97, 97, 104, 114, 100, 96, 95, 104, 112, - 116, 119, 123, 119, 121, 118, 112, 108, 109, 106, 102, 110, 106, 100, 104, 110, - 102, 104, 123, 116, 138, 145, 141, 146, 153, 158, 165, 166, 169, 173, 175, 176, - 176, 177, 178, 178, 180, 181, 180, 179, 178, 179, 181, 180, 181, 182, 183, 184, - 183, 182, 181, 183, 180, 177, 176, 179, 182, 184, 185, 175, 186, 196, 194, 184, - 179, 185, 193, 191, 175, 177, 174, 159, 152, 112, 39, 48, 41, 49, 58, 46, - 39, 74, 125, 173, 174, 175, 179, 188, 192, 183, 170, 179, 182, 187, 193, 198, - 201, 201, 201, 205, 205, 202, 197, 191, 188, 189, 191, 191, 194, 198, 200, 200, - 199, 199, 200, 195, 195, 195, 195, 195, 195, 195, 195, 198, 196, 193, 191, 190, - 188, 184, 182, 185, 180, 177, 180, 181, 179, 178, 180, 174, 170, 163, 153, 141, - 135, 142, 154, 161, 167, 173, 174, 170, 166, 167, 168, 152, 144, 149, 153, 143, - 153, 143, 146, 140, 136, 132, 128, 125, 121, 116, 112, 114, 118, 125, 131, 135, - 136, 135, 134, 122, 123, 124, 102, 102, 103, 105, 107, 110, 111, 113, 121, 117, - 104, 118, 116, 125, 105, 97, 99, 100, 102, 106, 112, 117, 120, 120, 110, 97, - 91, 100, 111, 114, 113, 114, 105, 124, 135, 130, 125, 129, 128, 123, 114, 119, - 115, 116, 125, 122, 114, 115, 117, 140, 148, 143, 149, 157, 162, 169, 166, 170, - 174, 178, 177, 177, 177, 178, 177, 179, 180, 180, 180, 181, 184, 187, 182, 182, - 181, 181, 181, 181, 181, 181, 184, 183, 181, 181, 180, 181, 178, 177, 185, 184, - 185, 188, 192, 191, 186, 181, 178, 171, 181, 177, 157, 154, 120, 52, 90, 65, - 50, 54, 60, 56, 57, 65, 100, 143, 183, 186, 168, 159, 168, 181, 177, 186, - 197, 204, 205, 204, 204, 205, 206, 207, 205, 201, 194, 190, 190, 192, 197, 200, - 203, 203, 202, 199, 198, 198, 195, 196, 196, 196, 196, 196, 195, 195, 194, 192, - 189, 187, 186, 185, 182, 179, 183, 178, 175, 177, 179, 178, 179, 183, 183, 176, - 166, 153, 139, 131, 138, 149, 157, 166, 175, 177, 173, 168, 165, 165, 148, 139, - 164, 156, 145, 157, 142, 145, 136, 134, 133, 132, 130, 127, 121, 118, 115, 114, - 116, 117, 120, 123, 127, 129, 127, 128, 128, 118, 117, 115, 114, 113, 113, 111, - 111, 116, 114, 111, 109, 108, 111, 116, 121, 120, 122, 111, 107, 115, 117, 118, - 126, 118, 112, 105, 102, 101, 103, 105, 110, 128, 123, 120, 116, 111, 110, 118, - 128, 120, 112, 112, 120, 121, 113, 109, 112, 118, 141, 143, 135, 141, 155, 158, - 160, 163, 170, 176, 177, 173, 171, 172, 174, 175, 180, 183, 185, 184, 183, 183, - 184, 182, 183, 184, 184, 185, 185, 184, 184, 182, 181, 179, 178, 177, 179, 179, - 180, 177, 183, 188, 190, 185, 181, 175, 175, 183, 166, 167, 161, 160, 149, 106, - 79, 127, 112, 89, 68, 54, 51, 53, 55, 48, 80, 84, 139, 156, 177, 189, - 183, 189, 196, 200, 199, 199, 203, 203, 201, 210, 209, 208, 203, 194, 188, 193, - 202, 193, 194, 195, 197, 198, 199, 200, 201, 195, 196, 197, 197, 195, 195, 196, - 198, 200, 192, 185, 187, 189, 186, 183, 182, 182, 183, 179, 180, 184, 178, 172, - 179, 179, 166, 174, 153, 148, 132, 154, 153, 158, 164, 171, 167, 162, 173, 176, - 160, 136, 155, 159, 144, 139, 149, 152, 144, 146, 147, 147, 139, 130, 124, 123, - 126, 124, 120, 118, 121, 119, 117, 123, 133, 127, 151, 132, 112, 113, 112, 112, - 111, 110, 109, 108, 103, 106, 109, 110, 111, 112, 113, 115, 110, 119, 115, 112, - 119, 119, 117, 124, 112, 118, 124, 127, 125, 120, 119, 119, 115, 113, 114, 121, - 122, 117, 113, 112, 112, 110, 114, 122, 122, 116, 120, 131, 117, 140, 144, 136, - 143, 155, 158, 160, 166, 171, 177, 177, 173, 171, 172, 173, 174, 178, 182, 184, - 183, 182, 183, 184, 185, 186, 186, 186, 185, 184, 183, 182, 183, 183, 181, 180, - 178, 179, 180, 180, 177, 180, 183, 183, 180, 178, 177, 178, 186, 166, 166, 157, - 158, 152, 133, 78, 112, 117, 122, 124, 117, 101, 80, 63, 46, 47, 53, 140, - 182, 195, 196, 198, 195, 201, 205, 203, 204, 207, 209, 207, 205, 206, 208, 207, - 200, 192, 193, 200, 193, 193, 194, 194, 194, 194, 194, 194, 194, 196, 197, 196, - 194, 193, 194, 196, 199, 192, 187, 189, 191, 188, 184, 183, 173, 179, 178, 177, - 178, 170, 168, 178, 178, 165, 170, 147, 138, 127, 150, 154, 182, 181, 181, 173, - 160, 162, 162, 148, 160, 153, 156, 164, 158, 145, 145, 156, 151, 123, 103, 105, - 113, 114, 116, 122, 132, 123, 115, 114, 115, 116, 123, 131, 132, 151, 141, 110, - 111, 112, 112, 112, 111, 108, 107, 113, 113, 111, 110, 109, 108, 107, 108, 111, - 107, 95, 99, 118, 124, 114, 111, 109, 114, 117, 114, 109, 107, 111, 117, 127, - 117, 110, 115, 121, 123, 120, 118, 124, 126, 130, 128, 113, 96, 94, 104, 118, - 139, 144, 137, 144, 153, 155, 159, 166, 171, 175, 177, 175, 172, 172, 174, 173, - 176, 180, 182, 182, 182, 183, 184, 188, 188, 188, 187, 186, 184, 183, 182, 184, - 184, 181, 179, 178, 178, 179, 179, 178, 178, 178, 177, 176, 176, 179, 181, 177, - 165, 171, 162, 163, 153, 130, 59, 124, 117, 110, 107, 110, 114, 114, 111, 125, - 97, 82, 144, 173, 175, 169, 174, 191, 198, 201, 199, 200, 204, 205, 204, 199, - 202, 209, 212, 206, 196, 194, 197, 198, 198, 198, 197, 196, 195, 193, 192, 193, - 194, 195, 194, 192, 191, 192, 194, 197, 191, 189, 192, 193, 189, 184, 183, 178, - 184, 184, 181, 178, 168, 167, 179, 178, 170, 172, 148, 134, 130, 156, 164, 159, - 158, 166, 171, 163, 158, 152, 142, 151, 158, 160, 156, 156, 160, 158, 152, 139, - 107, 90, 104, 116, 110, 107, 115, 126, 123, 123, 127, 128, 125, 124, 126, 130, - 138, 135, 110, 112, 113, 114, 113, 112, 110, 109, 119, 114, 106, 101, 100, 102, - 105, 108, 96, 109, 109, 103, 101, 100, 108, 128, 112, 115, 116, 113, 111, 114, - 120, 123, 118, 105, 96, 98, 104, 105, 105, 106, 106, 111, 119, 122, 112, 100, - 99, 105, 117, 137, 141, 137, 144, 152, 154, 159, 165, 169, 174, 176, 176, 175, - 177, 178, 174, 177, 180, 182, 182, 183, 185, 186, 188, 189, 189, 188, 187, 186, - 185, 184, 184, 183, 181, 179, 177, 177, 178, 178, 180, 179, 177, 175, 175, 175, - 177, 180, 173, 169, 173, 162, 163, 160, 104, 81, 126, 120, 114, 115, 120, 124, - 123, 120, 113, 105, 107, 141, 167, 187, 198, 210, 188, 193, 196, 194, 195, 199, - 201, 200, 198, 202, 208, 212, 207, 197, 193, 195, 199, 199, 200, 199, 198, 195, - 193, 192, 192, 194, 195, 194, 191, 190, 191, 192, 194, 190, 190, 194, 195, 189, - 184, 183, 188, 190, 186, 182, 180, 171, 166, 176, 176, 173, 173, 152, 133, 136, - 161, 172, 176, 167, 169, 172, 160, 151, 148, 142, 144, 156, 155, 144, 146, 158, - 153, 137, 126, 118, 113, 119, 115, 106, 108, 118, 119, 122, 124, 127, 125, 122, - 123, 125, 126, 122, 125, 112, 114, 114, 115, 115, 114, 113, 112, 105, 102, 96, - 96, 100, 106, 111, 114, 115, 116, 107, 108, 118, 120, 114, 117, 103, 111, 118, - 125, 132, 136, 130, 121, 128, 127, 131, 135, 133, 126, 120, 119, 111, 110, 112, - 115, 115, 113, 115, 119, 115, 133, 139, 137, 145, 151, 153, 160, 162, 165, 170, - 174, 177, 179, 181, 183, 177, 180, 182, 184, 183, 184, 186, 188, 186, 187, 188, - 188, 188, 188, 187, 188, 187, 186, 184, 182, 181, 180, 181, 181, 183, 182, 180, - 179, 178, 176, 174, 173, 170, 172, 165, 153, 153, 163, 75, 128, 122, 121, 120, - 122, 124, 121, 113, 104, 117, 118, 139, 160, 176, 176, 177, 184, 193, 198, 199, - 197, 196, 200, 203, 201, 203, 203, 207, 208, 203, 195, 192, 194, 193, 194, 195, - 195, 195, 193, 191, 189, 193, 194, 195, 194, 191, 190, 191, 192, 191, 189, 190, - 195, 195, 189, 185, 184, 190, 188, 179, 177, 182, 175, 168, 173, 170, 171, 167, - 151, 124, 131, 151, 160, 177, 161, 153, 150, 142, 144, 155, 158, 158, 141, 139, - 152, 151, 136, 127, 137, 133, 136, 129, 114, 102, 104, 114, 120, 118, 121, 121, - 114, 106, 106, 114, 122, 121, 123, 126, 114, 115, 115, 114, 115, 115, 116, 116, - 107, 107, 107, 112, 116, 119, 116, 113, 124, 119, 110, 116, 137, 137, 118, 106, - 116, 119, 119, 119, 126, 132, 125, 114, 124, 125, 127, 127, 120, 114, 116, 121, - 139, 129, 118, 111, 109, 110, 109, 109, 112, 129, 135, 137, 145, 151, 154, 162, - 162, 165, 169, 173, 177, 181, 183, 184, 180, 182, 183, 184, 184, 184, 186, 188, - 185, 186, 187, 188, 188, 188, 188, 188, 189, 189, 187, 186, 184, 185, 186, 187, - 185, 183, 181, 180, 178, 175, 170, 166, 156, 166, 164, 154, 148, 140, 51, 121, - 120, 115, 109, 107, 109, 117, 123, 125, 123, 104, 133, 161, 190, 183, 183, 200, - 197, 201, 201, 198, 197, 200, 202, 201, 206, 203, 203, 203, 199, 193, 192, 195, - 192, 193, 195, 197, 196, 195, 193, 191, 193, 194, 195, 194, 190, 189, 190, 191, - 191, 189, 192, 196, 196, 190, 187, 188, 190, 186, 176, 177, 186, 183, 175, 180, - 171, 174, 166, 151, 119, 131, 140, 147, 145, 141, 146, 151, 147, 154, 159, 156, - 144, 136, 134, 140, 143, 138, 135, 139, 135, 140, 134, 119, 116, 122, 118, 108, - 113, 123, 130, 124, 113, 107, 105, 105, 112, 124, 127, 115, 114, 113, 112, 112, - 114, 116, 117, 120, 120, 120, 124, 127, 127, 120, 116, 103, 128, 139, 131, 117, - 106, 113, 134, 136, 137, 129, 118, 121, 129, 130, 123, 133, 129, 124, 120, 114, - 115, 125, 136, 125, 121, 116, 114, 115, 117, 116, 112, 109, 126, 134, 137, 147, - 152, 155, 164, 167, 167, 169, 173, 177, 181, 182, 183, 181, 183, 184, 183, 182, - 182, 184, 186, 187, 188, 188, 188, 188, 187, 187, 186, 187, 186, 185, 184, 185, - 186, 187, 188, 186, 182, 179, 177, 176, 173, 168, 164, 148, 157, 159, 146, 138, - 103, 75, 101, 109, 115, 120, 125, 127, 129, 131, 132, 140, 121, 150, 159, 187, - 185, 187, 203, 197, 201, 201, 196, 194, 197, 198, 197, 203, 200, 199, 200, 198, - 193, 192, 196, 194, 196, 198, 199, 199, 197, 194, 192, 192, 193, 193, 192, 188, - 187, 187, 189, 193, 192, 194, 198, 197, 192, 191, 193, 192, 189, 180, 180, 187, - 183, 177, 183, 174, 177, 163, 152, 118, 135, 142, 148, 157, 163, 172, 170, 160, - 158, 151, 132, 123, 133, 133, 124, 127, 141, 141, 132, 130, 132, 133, 133, 135, - 134, 125, 115, 119, 126, 132, 130, 125, 121, 113, 104, 109, 116, 112, 116, 114, - 111, 110, 110, 113, 116, 118, 120, 117, 115, 118, 124, 128, 128, 125, 136, 128, - 110, 108, 124, 132, 125, 125, 108, 119, 124, 121, 123, 129, 126, 118, 110, 110, - 113, 116, 114, 111, 112, 118, 115, 121, 127, 130, 129, 123, 112, 102, 108, 124, - 132, 137, 148, 152, 155, 165, 170, 170, 171, 173, 177, 180, 180, 180, 182, 183, - 183, 182, 180, 180, 182, 185, 189, 189, 189, 188, 187, 186, 184, 183, 183, 182, - 181, 181, 182, 183, 185, 187, 185, 181, 176, 173, 172, 171, 168, 165, 160, 153, - 144, 122, 120, 80, 138, 121, 116, 117, 116, 112, 106, 107, 112, 117, 113, 129, - 177, 163, 183, 194, 193, 191, 200, 204, 203, 197, 195, 197, 198, 197, 200, 197, - 197, 199, 198, 194, 193, 196, 192, 194, 196, 197, 195, 193, 189, 187, 190, 191, - 192, 190, 187, 185, 185, 187, 196, 195, 197, 200, 199, 194, 194, 197, 190, 190, - 182, 178, 180, 172, 167, 177, 172, 174, 156, 147, 116, 139, 147, 152, 151, 152, - 153, 141, 133, 144, 149, 136, 138, 123, 121, 130, 127, 115, 115, 129, 133, 128, - 126, 128, 127, 124, 131, 145, 138, 131, 116, 106, 111, 123, 129, 127, 116, 108, - 96, 116, 116, 116, 116, 116, 117, 117, 118, 121, 120, 119, 109, 95, 100, 107, - 101, 93, 110, 115, 116, 119, 114, 112, 121, 130, 125, 126, 131, 125, 107, 98, - 100, 118, 116, 111, 107, 106, 110, 116, 120, 112, 116, 120, 124, 125, 126, 129, - 132, 116, 122, 133, 142, 147, 151, 154, 157, 170, 171, 173, 174, 176, 180, 185, - 189, 184, 183, 182, 181, 181, 182, 183, 184, 183, 183, 184, 186, 186, 189, 190, - 191, 181, 178, 184, 185, 176, 178, 185, 184, 180, 183, 183, 177, 173, 171, 167, - 162, 162, 130, 143, 127, 94, 119, 135, 115, 129, 128, 124, 121, 118, 118, 117, - 118, 102, 140, 166, 174, 180, 185, 186, 192, 196, 199, 200, 199, 195, 194, 196, - 199, 209, 204, 198, 196, 196, 195, 192, 188, 189, 191, 194, 196, 196, 195, 193, - 192, 198, 194, 190, 190, 192, 194, 192, 190, 201, 200, 199, 200, 200, 197, 191, - 186, 195, 192, 186, 180, 175, 173, 172, 173, 171, 154, 163, 136, 92, 148, 148, - 159, 153, 154, 155, 151, 143, 137, 135, 135, 138, 136, 135, 134, 129, 124, 127, - 134, 127, 122, 118, 121, 126, 129, 126, 122, 130, 131, 132, 127, 113, 104, 112, - 126, 116, 111, 106, 116, 117, 116, 116, 116, 116, 115, 116, 119, 117, 118, 112, - 104, 111, 118, 111, 101, 108, 104, 105, 115, 121, 124, 137, 121, 122, 123, 121, - 120, 121, 120, 118, 105, 111, 119, 120, 115, 109, 105, 102, 112, 122, 135, 140, - 132, 117, 101, 91, 126, 121, 122, 133, 139, 140, 145, 153, 163, 166, 171, 174, - 176, 178, 179, 182, 186, 185, 183, 183, 182, 184, 184, 186, 184, 186, 185, 186, - 184, 183, 181, 179, 190, 183, 186, 189, 184, 187, 190, 185, 185, 184, 177, 170, - 168, 169, 164, 158, 146, 143, 145, 122, 111, 124, 124, 130, 130, 131, 130, 128, - 126, 124, 122, 119, 112, 145, 168, 175, 183, 187, 188, 191, 195, 197, 199, 200, - 199, 198, 198, 199, 199, 198, 197, 197, 197, 194, 191, 188, 192, 191, 190, 189, - 189, 190, 192, 193, 196, 190, 183, 181, 183, 191, 199, 203, 203, 203, 202, 198, - 193, 190, 189, 189, 191, 186, 178, 176, 176, 177, 175, 174, 188, 169, 167, 123, - 100, 144, 141, 146, 144, 143, 138, 136, 138, 148, 161, 172, 154, 149, 147, 147, - 145, 139, 137, 138, 129, 127, 125, 127, 130, 134, 139, 141, 147, 145, 143, 139, - 126, 111, 102, 102, 117, 138, 129, 119, 118, 118, 119, 117, 118, 117, 118, 122, - 117, 119, 118, 115, 121, 126, 118, 113, 110, 98, 90, 98, 100, 100, 107, 114, - 125, 129, 122, 120, 125, 119, 106, 118, 110, 98, 87, 86, 96, 113, 126, 136, - 128, 114, 104, 104, 115, 132, 144, 117, 112, 114, 127, 137, 142, 151, 161, 159, - 163, 171, 177, 178, 178, 177, 177, 184, 183, 183, 182, 182, 184, 183, 185, 180, - 182, 184, 186, 185, 184, 181, 180, 186, 177, 178, 183, 180, 185, 184, 175, 179, - 180, 176, 175, 174, 171, 158, 143, 142, 154, 134, 107, 127, 134, 115, 139, 136, - 139, 141, 143, 141, 137, 133, 130, 122, 150, 167, 174, 184, 189, 187, 189, 192, - 193, 197, 200, 203, 202, 199, 196, 189, 193, 197, 198, 197, 193, 190, 189, 192, - 192, 190, 189, 189, 190, 191, 191, 186, 189, 193, 196, 196, 198, 200, 201, 207, - 208, 206, 200, 193, 191, 194, 199, 192, 184, 177, 176, 179, 181, 176, 173, 169, - 158, 154, 103, 119, 154, 151, 147, 151, 148, 138, 129, 120, 114, 114, 114, 146, - 141, 139, 147, 151, 149, 145, 144, 137, 139, 142, 143, 143, 145, 149, 153, 129, - 125, 124, 129, 129, 122, 111, 105, 107, 139, 134, 119, 120, 121, 121, 121, 122, - 123, 123, 128, 119, 122, 123, 120, 124, 125, 117, 123, 124, 114, 108, 112, 107, - 101, 104, 89, 97, 103, 104, 110, 120, 124, 120, 122, 119, 115, 112, 108, 104, - 98, 93, 102, 110, 121, 127, 124, 115, 104, 96, 97, 107, 113, 116, 123, 135, - 144, 148, 154, 161, 168, 173, 175, 175, 175, 175, 181, 179, 179, 179, 179, 180, - 180, 181, 177, 179, 180, 180, 180, 180, 179, 179, 183, 175, 179, 184, 179, 182, - 184, 176, 190, 185, 175, 167, 166, 172, 174, 171, 153, 150, 122, 97, 129, 141, - 119, 136, 140, 142, 144, 146, 145, 141, 137, 134, 126, 148, 163, 171, 183, 188, - 185, 189, 191, 191, 195, 200, 204, 202, 196, 190, 189, 193, 197, 198, 194, 191, - 191, 192, 191, 193, 195, 196, 196, 194, 192, 190, 187, 193, 200, 203, 200, 197, - 196, 197, 208, 207, 204, 200, 197, 196, 198, 200, 194, 189, 184, 181, 180, 180, - 177, 174, 167, 169, 162, 98, 138, 149, 142, 130, 128, 131, 135, 138, 139, 139, - 139, 139, 127, 124, 124, 132, 137, 136, 136, 137, 133, 135, 139, 142, 140, 137, - 133, 131, 139, 133, 129, 130, 131, 127, 119, 113, 111, 124, 123, 116, 118, 119, - 120, 122, 123, 125, 126, 129, 119, 121, 125, 121, 123, 122, 115, 103, 113, 113, - 112, 119, 118, 116, 123, 133, 120, 106, 98, 89, 83, 85, 93, 107, 111, 120, - 133, 140, 131, 110, 90, 121, 116, 110, 107, 108, 113, 118, 122, 118, 137, 137, - 118, 113, 131, 141, 137, 149, 155, 159, 164, 166, 169, 170, 172, 176, 177, 176, - 178, 178, 177, 178, 178, 180, 179, 177, 175, 174, 173, 172, 173, 172, 169, 176, - 178, 170, 172, 177, 174, 175, 185, 190, 186, 180, 175, 169, 164, 149, 134, 129, - 118, 126, 141, 134, 136, 136, 136, 137, 135, 135, 133, 132, 131, 129, 148, 160, - 170, 185, 189, 188, 194, 193, 193, 195, 199, 201, 199, 192, 187, 196, 198, 198, - 195, 191, 190, 192, 196, 195, 195, 195, 195, 195, 194, 194, 194, 199, 197, 193, - 188, 184, 188, 197, 205, 209, 204, 200, 199, 201, 200, 194, 188, 188, 189, 188, - 184, 179, 176, 178, 181, 166, 173, 161, 95, 144, 145, 147, 139, 155, 150, 141, - 132, 125, 120, 119, 117, 129, 127, 126, 126, 125, 122, 124, 130, 138, 136, 132, - 132, 134, 133, 127, 123, 127, 129, 130, 131, 131, 129, 125, 121, 114, 109, 103, - 114, 115, 117, 119, 120, 123, 123, 124, 125, 116, 119, 125, 122, 122, 125, 122, - 102, 109, 104, 100, 104, 103, 103, 112, 111, 104, 107, 119, 119, 110, 109, 118, - 109, 102, 96, 102, 113, 121, 119, 113, 90, 95, 103, 116, 128, 136, 140, 140, - 134, 149, 143, 113, 105, 124, 138, 134, 147, 150, 155, 159, 162, 167, 171, 174, - 173, 174, 174, 175, 175, 175, 175, 174, 173, 174, 173, 174, 174, 175, 175, 174, - 167, 164, 171, 172, 164, 167, 175, 175, 166, 180, 189, 184, 167, 151, 135, 126, - 133, 123, 148, 148, 129, 139, 144, 143, 138, 137, 134, 132, 131, 130, 130, 130, - 131, 148, 161, 173, 187, 191, 190, 199, 196, 196, 196, 197, 198, 196, 192, 189, - 203, 201, 197, 193, 190, 191, 194, 197, 199, 196, 191, 188, 188, 192, 198, 202, - 197, 196, 194, 193, 193, 197, 202, 207, 215, 208, 203, 204, 208, 205, 194, 183, - 178, 183, 186, 184, 177, 175, 179, 186, 160, 160, 140, 86, 134, 137, 154, 152, - 148, 149, 149, 150, 150, 149, 145, 143, 134, 134, 135, 134, 132, 129, 135, 145, - 127, 117, 106, 103, 106, 112, 113, 112, 115, 127, 136, 142, 142, 142, 135, 129, - 131, 129, 112, 119, 120, 120, 121, 122, 122, 123, 124, 125, 117, 122, 128, 122, - 121, 128, 128, 133, 133, 120, 111, 114, 109, 103, 107, 116, 122, 131, 140, 137, - 126, 114, 108, 121, 118, 111, 106, 102, 97, 89, 82, 88, 91, 98, 108, 117, - 122, 122, 120, 121, 122, 117, 106, 105, 116, 124, 123, 136, 141, 146, 152, 156, - 162, 167, 170, 167, 167, 168, 169, 169, 168, 167, 168, 162, 163, 165, 167, 166, - 164, 160, 158, 158, 152, 155, 158, 153, 159, 168, 167, 168, 165, 150, 133, 123, - 127, 135, 140, 136, 129, 151, 149, 136, 142, 140, 145, 142, 141, 139, 137, 135, - 133, 132, 132, 129, 149, 163, 175, 186, 188, 188, 199, 197, 198, 198, 196, 195, - 195, 196, 198, 204, 200, 194, 191, 191, 193, 195, 196, 196, 195, 193, 193, 194, - 196, 200, 202, 192, 195, 201, 207, 210, 210, 206, 203, 209, 206, 203, 205, 207, - 204, 196, 189, 178, 181, 184, 183, 179, 179, 181, 185, 178, 166, 136, 95, 126, - 122, 134, 126, 123, 126, 133, 140, 143, 140, 132, 126, 135, 133, 137, 141, 144, - 143, 149, 156, 156, 151, 142, 139, 140, 145, 148, 150, 157, 164, 167, 163, 157, - 152, 139, 128, 148, 156, 142, 126, 127, 126, 126, 125, 126, 125, 125, 129, 121, - 126, 131, 121, 120, 127, 131, 131, 130, 122, 121, 131, 128, 117, 115, 121, 128, - 126, 118, 117, 125, 126, 119, 125, 124, 122, 117, 110, 107, 106, 108, 106, 104, - 106, 111, 119, 126, 129, 129, 134, 124, 123, 134, 140, 135, 129, 131, 121, 126, - 134, 141, 145, 150, 155, 158, 160, 159, 162, 163, 163, 162, 160, 161, 157, 158, - 158, 155, 148, 137, 125, 118, 118, 107, 107, 110, 112, 120, 127, 123, 113, 121, - 130, 137, 145, 152, 153, 150, 154, 142, 138, 131, 140, 147, 132, 138, 141, 141, - 140, 138, 136, 134, 132, 130, 128, 146, 162, 174, 184, 182, 184, 196, 198, 200, - 199, 197, 194, 196, 201, 206, 201, 197, 191, 190, 192, 195, 195, 195, 188, 193, - 200, 206, 207, 205, 200, 197, 201, 199, 197, 199, 203, 207, 208, 207, 193, 193, - 194, 196, 197, 196, 194, 192, 186, 186, 184, 184, 184, 183, 182, 181, 173, 159, - 132, 112, 139, 135, 141, 128, 135, 131, 128, 129, 132, 135, 138, 137, 139, 134, - 134, 140, 145, 145, 142, 143, 150, 153, 153, 152, 149, 148, 148, 148, 152, 154, - 152, 148, 149, 151, 145, 136, 130, 137, 135, 128, 124, 120, 124, 127, 125, 124, - 123, 127, 124, 123, 126, 126, 124, 124, 129, 131, 131, 129, 125, 122, 121, 123, - 124, 127, 126, 123, 121, 120, 123, 125, 128, 125, 128, 130, 132, 130, 126, 120, - 116, 109, 117, 113, 109, 115, 118, 124, 139, 129, 130, 132, 134, 135, 136, 136, - 135, 141, 136, 129, 124, 126, 134, 143, 150, 152, 151, 149, 145, 141, 143, 151, - 160, 149, 142, 127, 111, 108, 115, 124, 127, 138, 141, 144, 144, 141, 140, 141, - 144, 149, 149, 149, 150, 150, 150, 151, 152, 148, 149, 149, 149, 147, 146, 146, - 144, 146, 141, 139, 140, 140, 137, 139, 142, 137, 148, 160, 168, 179, 192, 196, - 194, 195, 192, 195, 201, 203, 199, 200, 205, 206, 196, 187, 185, 190, 193, 191, - 189, 192, 198, 199, 195, 196, 199, 197, 191, 190, 199, 206, 205, 199, 197, 203, - 210, 204, 197, 191, 194, 201, 203, 197, 190, 183, 183, 185, 187, 188, 187, 182, - 178, 165, 170, 99, 144, 131, 131, 139, 141, 139, 137, 136, 136, 135, 134, 133, - 132, 137, 135, 133, 134, 136, 141, 147, 152, 148, 148, 149, 149, 149, 148, 146, - 144, 146, 146, 154, 158, 154, 152, 142, 120, 117, 125, 148, 127, 126, 128, 132, - 130, 126, 125, 126, 127, 124, 123, 125, 125, 122, 122, 126, 125, 127, 129, 129, - 127, 126, 125, 127, 129, 128, 126, 126, 126, 128, 130, 132, 129, 129, 130, 131, - 130, 129, 127, 126, 117, 128, 128, 126, 129, 125, 123, 131, 133, 133, 133, 134, - 135, 137, 139, 140, 138, 138, 138, 138, 138, 138, 138, 138, 126, 128, 129, 125, - 121, 122, 127, 131, 120, 130, 139, 144, 150, 154, 153, 148, 145, 146, 147, 147, - 147, 147, 149, 150, 151, 151, 150, 149, 149, 148, 147, 148, 148, 147, 146, 145, - 143, 142, 141, 141, 148, 145, 145, 148, 148, 144, 144, 145, 142, 142, 154, 173, - 186, 191, 195, 201, 195, 192, 194, 198, 200, 198, 198, 202, 197, 193, 187, 184, - 186, 190, 194, 196, 196, 200, 200, 197, 199, 202, 201, 196, 194, 198, 201, 202, - 201, 201, 204, 208, 206, 200, 194, 193, 195, 194, 188, 182, 182, 182, 183, 184, - 184, 183, 179, 174, 173, 160, 110, 143, 136, 137, 140, 135, 137, 137, 137, 138, - 140, 141, 143, 143, 140, 138, 136, 133, 133, 135, 139, 141, 145, 146, 145, 145, - 143, 144, 146, 148, 160, 152, 145, 139, 133, 143, 149, 142, 101, 132, 154, 116, - 120, 126, 130, 125, 118, 119, 123, 124, 121, 121, 125, 126, 123, 124, 128, 124, - 128, 133, 134, 132, 130, 127, 127, 128, 128, 129, 130, 132, 132, 133, 134, 127, - 126, 125, 125, 126, 129, 131, 133, 124, 135, 134, 133, 135, 129, 124, 130, 135, - 134, 133, 132, 134, 136, 139, 141, 141, 143, 146, 149, 149, 146, 143, 141, 149, - 152, 155, 154, 151, 149, 150, 151, 150, 156, 158, 156, 155, 154, 151, 145, 154, - 153, 152, 152, 154, 156, 156, 156, 159, 158, 157, 155, 153, 152, 151, 151, 157, - 155, 152, 150, 148, 147, 146, 146, 150, 148, 149, 153, 154, 149, 147, 147, 147, - 139, 149, 175, 189, 186, 189, 202, 195, 193, 193, 196, 196, 194, 195, 198, 192, - 191, 188, 184, 183, 186, 193, 199, 196, 199, 200, 197, 198, 202, 202, 201, 202, - 201, 200, 200, 201, 202, 203, 202, 208, 205, 200, 197, 195, 191, 187, 184, 182, - 182, 183, 184, 184, 183, 179, 176, 169, 134, 121, 138, 140, 145, 146, 134, 140, - 140, 140, 140, 142, 144, 148, 149, 148, 146, 145, 142, 141, 141, 142, 143, 150, - 150, 149, 147, 143, 144, 149, 153, 143, 144, 151, 154, 144, 143, 139, 126, 138, - 102, 133, 111, 112, 116, 120, 120, 116, 117, 123, 121, 119, 121, 127, 128, 126, - 127, 132, 128, 131, 135, 135, 131, 127, 126, 125, 125, 127, 128, 130, 131, 132, - 132, 132, 129, 128, 126, 126, 128, 131, 134, 136, 130, 138, 134, 131, 136, 135, - 133, 142, 138, 138, 139, 139, 140, 142, 144, 145, 151, 150, 149, 149, 151, 153, - 155, 157, 146, 149, 151, 151, 149, 147, 146, 146, 157, 158, 155, 149, 150, 156, - 160, 161, 164, 159, 154, 154, 156, 159, 158, 157, 161, 161, 159, 158, 156, 155, - 154, 154, 161, 160, 156, 154, 152, 153, 154, 155, 150, 148, 148, 152, 153, 149, - 147, 148, 150, 142, 145, 164, 177, 179, 184, 193, 195, 193, 193, 192, 192, 192, - 193, 193, 192, 192, 189, 186, 185, 186, 190, 193, 194, 194, 194, 193, 194, 197, - 200, 200, 206, 204, 202, 200, 199, 199, 198, 198, 202, 202, 200, 198, 194, 191, - 190, 190, 180, 179, 179, 181, 181, 181, 177, 176, 161, 115, 138, 135, 138, 143, - 143, 132, 144, 143, 142, 140, 139, 140, 143, 145, 149, 149, 150, 150, 150, 150, - 151, 151, 150, 152, 152, 148, 143, 142, 145, 150, 151, 147, 149, 146, 135, 134, - 137, 133, 135, 129, 120, 118, 113, 112, 118, 123, 124, 126, 129, 123, 122, 123, - 129, 130, 127, 126, 129, 129, 130, 130, 130, 126, 125, 125, 126, 124, 126, 128, - 130, 133, 133, 132, 130, 136, 135, 135, 136, 136, 137, 138, 139, 135, 142, 139, - 138, 144, 143, 141, 148, 142, 144, 147, 150, 151, 151, 150, 149, 155, 153, 150, - 149, 150, 153, 157, 160, 158, 159, 159, 158, 157, 156, 157, 158, 146, 152, 158, - 160, 163, 166, 164, 159, 166, 161, 156, 154, 155, 157, 155, 154, 155, 155, 154, - 155, 154, 154, 153, 153, 155, 153, 152, 150, 150, 151, 154, 156, 153, 149, 148, - 150, 151, 149, 150, 154, 150, 148, 146, 151, 161, 175, 184, 186, 190, 192, 192, - 190, 189, 191, 190, 190, 188, 187, 187, 188, 190, 191, 190, 189, 193, 191, 191, - 191, 191, 193, 197, 200, 199, 202, 203, 201, 197, 195, 198, 201, 192, 194, 194, - 192, 189, 187, 187, 189, 180, 178, 176, 175, 173, 170, 167, 163, 159, 117, 155, - 139, 137, 135, 136, 128, 145, 146, 146, 143, 140, 139, 141, 143, 143, 144, 146, - 147, 148, 149, 150, 150, 143, 145, 146, 146, 143, 141, 143, 144, 149, 143, 146, - 146, 137, 136, 140, 139, 143, 138, 167, 123, 115, 111, 117, 123, 126, 128, 130, - 129, 126, 128, 130, 128, 123, 120, 123, 125, 125, 124, 123, 122, 124, 127, 131, - 127, 129, 130, 132, 133, 133, 132, 133, 136, 136, 137, 138, 138, 138, 137, 137, - 131, 140, 141, 143, 148, 143, 135, 138, 139, 142, 146, 150, 151, 150, 147, 145, - 152, 152, 152, 152, 151, 150, 149, 148, 150, 149, 147, 146, 146, 148, 150, 151, - 155, 159, 161, 160, 158, 157, 154, 148, 164, 161, 157, 155, 155, 155, 154, 153, - 154, 155, 155, 155, 156, 156, 157, 157, 152, 152, 151, 151, 151, 153, 154, 156, - 157, 152, 150, 153, 154, 152, 155, 158, 149, 152, 150, 146, 152, 170, 182, 184, - 185, 189, 189, 188, 187, 188, 187, 184, 181, 180, 182, 186, 191, 194, 193, 191, - 196, 192, 191, 193, 193, 192, 196, 200, 190, 195, 200, 200, 197, 197, 200, 203, - 193, 193, 193, 191, 188, 185, 185, 184, 186, 182, 177, 173, 168, 162, 155, 152, - 146, 121, 155, 141, 141, 139, 143, 143, 142, 145, 149, 148, 144, 143, 145, 148, - 145, 145, 146, 146, 146, 147, 148, 147, 141, 142, 144, 147, 148, 148, 146, 146, - 139, 134, 142, 150, 145, 141, 141, 136, 140, 137, 147, 118, 115, 113, 117, 119, - 118, 120, 124, 126, 124, 125, 128, 128, 122, 119, 120, 123, 123, 122, 122, 120, - 123, 126, 130, 129, 130, 132, 133, 133, 133, 133, 133, 134, 134, 134, 135, 134, - 135, 135, 135, 132, 139, 138, 139, 146, 142, 133, 136, 137, 139, 142, 144, 146, - 145, 144, 143, 150, 151, 152, 152, 151, 149, 147, 146, 151, 150, 149, 150, 152, - 154, 154, 154, 151, 152, 150, 146, 150, 158, 163, 164, 159, 159, 160, 159, 157, - 156, 156, 157, 158, 158, 158, 159, 159, 160, 160, 160, 156, 156, 156, 156, 156, - 156, 156, 156, 156, 152, 153, 157, 157, 156, 157, 159, 154, 154, 152, 151, 152, - 156, 166, 176, 177, 183, 185, 184, 182, 185, 183, 178, 177, 179, 180, 181, 183, - 186, 191, 195, 197, 192, 191, 194, 196, 193, 194, 199, 189, 191, 195, 197, 198, - 198, 196, 195, 193, 192, 190, 189, 188, 186, 184, 183, 181, 177, 171, 166, 160, - 153, 147, 142, 137, 130, 144, 139, 145, 143, 146, 151, 140, 145, 150, 151, 147, - 145, 147, 149, 149, 148, 149, 148, 148, 149, 150, 151, 148, 145, 141, 142, 146, - 147, 145, 141, 152, 134, 127, 127, 124, 129, 139, 141, 146, 72, 101, 117, 117, - 120, 123, 118, 113, 115, 121, 119, 118, 121, 127, 127, 123, 121, 123, 125, 126, - 125, 124, 121, 121, 123, 125, 129, 129, 131, 131, 131, 131, 130, 131, 136, 136, - 135, 135, 135, 137, 139, 141, 140, 143, 136, 134, 143, 144, 142, 148, 143, 143, - 145, 146, 147, 148, 149, 149, 153, 152, 150, 149, 149, 152, 154, 156, 148, 147, - 148, 150, 154, 154, 153, 152, 155, 158, 158, 155, 155, 159, 159, 156, 156, 159, - 162, 162, 159, 158, 160, 162, 157, 158, 157, 157, 157, 158, 158, 158, 159, 158, - 158, 157, 157, 156, 155, 154, 152, 150, 153, 158, 159, 156, 155, 156, 162, 152, - 153, 158, 151, 140, 146, 164, 172, 179, 182, 181, 180, 184, 179, 173, 177, 181, - 181, 178, 174, 176, 187, 196, 196, 192, 191, 195, 194, 191, 190, 195, 196, 193, - 193, 196, 200, 198, 191, 184, 187, 185, 183, 183, 184, 184, 182, 180, 164, 160, - 156, 151, 146, 143, 137, 133, 145, 146, 139, 137, 143, 139, 135, 138, 140, 144, - 151, 151, 147, 143, 144, 146, 147, 146, 147, 147, 148, 150, 152, 154, 151, 144, - 135, 133, 135, 136, 132, 127, 132, 121, 127, 138, 133, 125, 117, 108, 129, 101, - 124, 117, 119, 121, 121, 122, 120, 114, 109, 112, 114, 118, 123, 125, 126, 125, - 123, 123, 123, 122, 123, 124, 124, 125, 125, 122, 127, 131, 132, 130, 130, 133, - 137, 134, 134, 135, 136, 136, 137, 137, 137, 137, 135, 133, 132, 134, 137, 140, - 143, 137, 141, 145, 147, 146, 145, 145, 146, 145, 146, 146, 147, 149, 150, 151, - 151, 149, 150, 151, 151, 151, 153, 158, 161, 161, 157, 153, 154, 158, 160, 158, - 155, 161, 152, 156, 160, 152, 150, 157, 160, 163, 162, 158, 156, 155, 156, 158, - 159, 154, 154, 155, 156, 155, 153, 152, 150, 151, 149, 153, 158, 160, 157, 159, - 161, 156, 154, 153, 155, 157, 156, 151, 147, 166, 162, 160, 164, 170, 175, 174, - 172, 173, 174, 173, 164, 161, 178, 184, 168, 181, 190, 188, 185, 188, 187, 185, - 194, 193, 192, 190, 188, 186, 185, 185, 185, 185, 183, 181, 179, 177, 175, 173, - 171, 165, 157, 147, 139, 135, 139, 146, 152, 148, 149, 148, 144, 141, 141, 146, - 150, 146, 144, 143, 147, 151, 151, 145, 139, 143, 144, 148, 151, 151, 144, 132, - 124, 118, 123, 123, 124, 128, 133, 130, 124, 128, 126, 128, 134, 142, 142, 135, - 128, 122, 110, 105, 125, 123, 121, 120, 121, 122, 120, 117, 127, 126, 123, 122, - 121, 123, 125, 126, 124, 124, 125, 126, 126, 127, 127, 127, 126, 126, 127, 129, - 131, 132, 131, 130, 134, 134, 135, 136, 137, 137, 137, 137, 135, 135, 135, 136, - 137, 139, 140, 141, 137, 140, 144, 145, 146, 146, 147, 148, 149, 149, 149, 149, - 149, 150, 150, 150, 151, 152, 153, 153, 152, 153, 156, 158, 159, 156, 152, 154, - 157, 159, 157, 154, 162, 151, 154, 161, 157, 157, 158, 154, 158, 157, 154, 154, - 153, 155, 157, 159, 158, 157, 156, 155, 155, 154, 155, 155, 155, 154, 156, 160, - 160, 157, 157, 158, 158, 158, 159, 162, 163, 163, 161, 158, 159, 149, 141, 139, - 144, 154, 160, 163, 172, 165, 161, 155, 153, 169, 180, 172, 180, 188, 188, 188, - 191, 188, 182, 187, 183, 183, 182, 184, 183, 185, 184, 185, 179, 176, 172, 175, - 180, 183, 179, 176, 154, 150, 146, 140, 140, 141, 145, 148, 149, 150, 150, 147, - 143, 140, 141, 143, 147, 145, 145, 149, 154, 155, 152, 147, 151, 149, 148, 147, - 148, 149, 149, 150, 137, 136, 129, 124, 126, 133, 136, 134, 146, 146, 147, 151, - 152, 143, 127, 114, 131, 133, 131, 125, 124, 123, 124, 124, 124, 124, 123, 130, - 127, 124, 121, 120, 121, 122, 124, 124, 123, 124, 125, 126, 127, 128, 128, 129, - 126, 124, 127, 131, 133, 129, 126, 134, 136, 136, 137, 137, 138, 138, 138, 134, - 136, 138, 140, 141, 141, 141, 140, 138, 140, 143, 144, 144, 145, 148, 150, 150, - 150, 149, 148, 147, 147, 148, 148, 153, 155, 157, 156, 155, 153, 154, 155, 158, - 155, 153, 154, 157, 158, 156, 153, 163, 151, 154, 162, 161, 161, 158, 148, 153, - 153, 150, 150, 151, 154, 157, 158, 160, 159, 157, 155, 154, 155, 157, 157, 160, - 158, 159, 163, 162, 158, 157, 158, 155, 157, 161, 162, 162, 163, 162, 163, 166, - 162, 159, 160, 162, 161, 158, 154, 162, 152, 150, 150, 147, 154, 163, 161, 160, - 169, 171, 177, 188, 187, 180, 182, 177, 178, 180, 181, 182, 182, 181, 180, 178, - 170, 164, 165, 170, 171, 164, 155, 146, 146, 147, 148, 148, 148, 148, 148, 149, - 151, 152, 150, 147, 144, 143, 143, 143, 142, 141, 145, 150, 153, 152, 150, 153, - 152, 151, 149, 148, 151, 158, 163, 168, 167, 159, 152, 152, 157, 160, 159, 156, - 148, 139, 134, 133, 131, 126, 121, 132, 141, 137, 116, 116, 118, 123, 124, 121, - 116, 115, 114, 117, 119, 123, 124, 123, 121, 119, 121, 122, 122, 123, 124, 125, - 126, 126, 130, 129, 128, 128, 130, 130, 128, 126, 135, 136, 137, 137, 137, 138, - 139, 139, 136, 137, 139, 141, 142, 142, 142, 141, 141, 142, 143, 143, 143, 144, - 146, 149, 146, 146, 144, 144, 144, 144, 145, 146, 152, 154, 157, 157, 156, 154, - 154, 154, 157, 155, 154, 155, 157, 158, 156, 154, 161, 153, 156, 161, 159, 159, - 158, 149, 152, 151, 149, 150, 150, 152, 155, 156, 158, 157, 156, 156, 155, 155, - 156, 155, 161, 158, 159, 163, 162, 158, 158, 161, 154, 157, 162, 163, 161, 160, - 162, 164, 162, 163, 166, 169, 169, 166, 158, 152, 159, 148, 152, 161, 153, 148, - 149, 148, 151, 159, 160, 165, 178, 177, 170, 171, 173, 174, 174, 174, 172, 170, - 165, 164, 169, 164, 157, 156, 155, 154, 147, 143, 148, 150, 153, 155, 156, 154, - 153, 152, 148, 149, 150, 151, 150, 149, 149, 150, 144, 142, 141, 143, 147, 150, - 151, 151, 152, 156, 161, 161, 157, 155, 157, 159, 161, 166, 166, 164, 161, 161, - 156, 151, 150, 140, 128, 121, 119, 123, 123, 123, 117, 125, 127, 116, 111, 109, - 114, 115, 113, 112, 115, 112, 114, 119, 123, 126, 126, 126, 125, 123, 123, 123, - 124, 126, 126, 126, 126, 128, 131, 133, 132, 129, 128, 128, 130, 135, 136, 137, - 138, 139, 139, 139, 139, 141, 140, 139, 139, 140, 141, 142, 143, 143, 144, 145, - 144, 142, 142, 144, 146, 144, 143, 142, 142, 143, 145, 147, 149, 149, 153, 155, - 156, 155, 154, 154, 155, 156, 156, 156, 157, 158, 158, 156, 154, 158, 154, 159, - 159, 152, 153, 158, 152, 152, 152, 151, 150, 150, 152, 153, 153, 155, 157, 159, - 161, 161, 159, 156, 154, 159, 156, 158, 161, 162, 160, 162, 164, 162, 166, 168, - 169, 165, 164, 166, 168, 162, 160, 159, 159, 162, 167, 170, 172, 182, 171, 177, - 186, 178, 171, 172, 172, 163, 167, 162, 161, 169, 166, 157, 159, 164, 165, 164, - 164, 160, 157, 152, 151, 153, 155, 155, 156, 155, 155, 156, 157, 156, 155, 156, - 157, 156, 155, 154, 154, 149, 148, 147, 146, 148, 149, 149, 150, 151, 149, 148, - 148, 149, 151, 153, 153, 153, 158, 165, 165, 162, 157, 157, 157, 148, 157, 161, - 162, 159, 158, 151, 145, 148, 147, 144, 142, 137, 129, 118, 110, 110, 111, 119, - 128, 118, 110, 113, 114, 113, 117, 125, 124, 123, 121, 122, 124, 128, 131, 134, - 128, 128, 128, 129, 129, 129, 129, 129, 127, 132, 135, 133, 129, 126, 127, 133, - 136, 137, 137, 138, 139, 140, 139, 140, 141, 141, 139, 138, 139, 140, 142, 143, - 142, 144, 145, 145, 143, 143, 144, 145, 146, 145, 144, 144, 145, 148, 151, 154, - 148, 151, 153, 153, 153, 153, 154, 155, 154, 155, 156, 157, 157, 156, 155, 154, - 155, 154, 160, 157, 148, 150, 157, 150, 152, 152, 151, 151, 152, 152, 152, 152, - 155, 157, 161, 164, 164, 161, 156, 153, 156, 153, 155, 159, 160, 159, 162, 166, - 167, 168, 169, 168, 165, 164, 164, 165, 167, 167, 169, 169, 169, 169, 167, 166, - 158, 146, 149, 154, 147, 147, 154, 158, 163, 166, 159, 156, 161, 159, 153, 157, - 161, 160, 161, 160, 159, 157, 155, 154, 148, 152, 157, 157, 155, 156, 161, 165, - 159, 157, 156, 154, 151, 151, 151, 151, 151, 148, 144, 142, 143, 144, 144, 143, - 151, 150, 149, 148, 147, 148, 149, 150, 150, 151, 153, 154, 153, 153, 155, 157, - 155, 161, 162, 160, 158, 160, 160, 158, 158, 157, 153, 150, 144, 138, 129, 124, - 125, 114, 111, 124, 114, 108, 113, 114, 109, 111, 119, 122, 121, 119, 120, 123, - 127, 132, 135, 132, 131, 132, 132, 130, 129, 129, 129, 129, 130, 130, 130, 130, - 129, 128, 129, 136, 138, 139, 139, 139, 140, 140, 140, 139, 139, 139, 140, 140, - 140, 140, 139, 138, 141, 144, 146, 145, 145, 146, 147, 149, 148, 146, 144, 145, - 147, 150, 153, 150, 152, 153, 152, 149, 149, 151, 153, 150, 152, 155, 156, 155, - 153, 152, 151, 153, 152, 157, 156, 150, 154, 155, 143, 149, 149, 150, 151, 151, - 152, 153, 152, 153, 154, 157, 159, 159, 157, 154, 152, 156, 152, 152, 155, 158, - 157, 160, 163, 163, 162, 160, 161, 161, 161, 160, 159, 157, 161, 167, 169, 166, - 158, 149, 143, 164, 157, 160, 161, 154, 157, 166, 167, 153, 161, 157, 156, 160, - 159, 157, 165, 160, 160, 160, 160, 160, 160, 160, 160, 154, 156, 158, 157, 156, - 156, 158, 159, 156, 156, 155, 152, 150, 149, 148, 147, 148, 147, 144, 144, 146, - 146, 143, 141, 147, 147, 148, 148, 146, 146, 147, 148, 148, 147, 147, 148, 151, - 153, 153, 153, 148, 153, 153, 149, 146, 150, 153, 155, 160, 156, 148, 143, 139, - 139, 138, 140, 132, 126, 118, 102, 95, 99, 109, 109, 99, 93, 95, 108, 112, - 117, 122, 126, 127, 127, 127, 133, 133, 132, 131, 131, 129, 127, 126, 131, 127, - 126, 128, 131, 132, 129, 127, 136, 137, 137, 138, 138, 138, 139, 139, 134, 137, - 139, 142, 143, 141, 138, 136, 135, 139, 144, 147, 148, 147, 148, 149, 150, 148, - 145, 143, 143, 144, 147, 148, 153, 154, 153, 150, 147, 146, 148, 150, 147, 150, - 153, 154, 153, 151, 150, 149, 151, 149, 152, 154, 152, 157, 152, 134, 144, 145, - 146, 149, 151, 152, 154, 153, 149, 150, 151, 152, 151, 151, 150, 150, 155, 152, - 151, 154, 155, 155, 158, 161, 161, 159, 157, 156, 159, 161, 159, 157, 161, 161, - 160, 160, 159, 160, 163, 165, 157, 156, 164, 165, 155, 157, 160, 154, 160, 168, - 167, 164, 165, 161, 158, 166, 156, 155, 155, 154, 154, 154, 154, 155, 158, 157, - 155, 159, 162, 165, 164, 162, 155, 155, 154, 153, 151, 149, 148, 147, 144, 144, - 146, 149, 153, 153, 148, 145, 147, 150, 151, 152, 150, 150, 151, 152, 153, 153, - 154, 158, 161, 160, 156, 150, 147, 153, 155, 152, 149, 151, 153, 152, 151, 153, - 152, 151, 145, 139, 129, 125, 121, 135, 139, 109, 106, 109, 110, 109, 111, 96, - 69, 113, 120, 124, 121, 120, 122, 123, 121, 119, 128, 128, 126, 131, 128, 126, - 134, 126, 132, 139, 138, 134, 129, 129, 132, 138, 134, 133, 137, 137, 132, 133, - 137, 136, 140, 143, 145, 144, 144, 143, 144, 145, 144, 141, 142, 143, 143, 141, - 140, 144, 145, 146, 148, 149, 151, 152, 152, 149, 148, 146, 145, 145, 146, 147, - 148, 148, 150, 149, 145, 145, 150, 152, 150, 148, 152, 156, 154, 148, 147, 152, - 158, 151, 153, 152, 151, 151, 151, 154, 154, 149, 153, 154, 153, 152, 153, 149, - 145, 148, 152, 155, 155, 153, 154, 158, 163, 163, 161, 160, 162, 164, 163, 159, - 156, 152, 155, 159, 162, 164, 164, 162, 161, 156, 156, 156, 156, 157, 158, 160, - 162, 162, 162, 162, 161, 159, 158, 158, 157, 160, 160, 160, 159, 157, 155, 153, - 152, 154, 152, 151, 153, 156, 159, 160, 160, 156, 154, 152, 148, 147, 147, 148, - 149, 149, 148, 146, 144, 143, 144, 144, 144, 152, 155, 151, 145, 143, 150, 152, - 149, 154, 151, 148, 150, 154, 156, 153, 151, 152, 153, 153, 150, 147, 147, 149, - 153, 144, 146, 146, 146, 141, 135, 126, 121, 123, 126, 132, 102, 99, 105, 109, - 103, 100, 88, 68, 114, 122, 128, 124, 118, 119, 121, 121, 127, 132, 129, 129, - 137, 135, 130, 134, 139, 138, 137, 135, 132, 130, 129, 129, 138, 135, 135, 138, - 137, 132, 131, 135, 131, 135, 139, 139, 139, 139, 140, 141, 141, 140, 139, 141, - 142, 143, 141, 140, 140, 141, 142, 143, 144, 145, 146, 146, 152, 151, 149, 148, - 147, 148, 148, 149, 146, 149, 150, 147, 148, 151, 151, 147, 147, 150, 151, 150, - 146, 147, 150, 154, 149, 151, 151, 149, 149, 150, 153, 155, 148, 154, 157, 153, - 150, 152, 154, 154, 156, 155, 155, 155, 156, 158, 158, 158, 158, 157, 157, 158, - 161, 161, 159, 156, 156, 157, 160, 161, 162, 162, 161, 159, 158, 158, 159, 160, - 159, 157, 156, 156, 158, 158, 160, 160, 160, 159, 158, 158, 157, 157, 157, 156, - 156, 156, 156, 156, 165, 162, 159, 159, 160, 160, 159, 158, 157, 157, 157, 156, - 154, 152, 149, 148, 148, 147, 146, 145, 144, 145, 146, 147, 146, 151, 150, 148, - 148, 152, 153, 149, 150, 148, 147, 148, 150, 151, 151, 151, 155, 157, 158, 156, - 153, 151, 153, 155, 159, 154, 151, 151, 152, 149, 141, 133, 132, 130, 128, 102, - 101, 112, 122, 112, 106, 100, 93, 108, 119, 128, 127, 124, 128, 134, 136, 132, - 135, 131, 133, 145, 146, 140, 142, 136, 133, 129, 131, 136, 142, 145, 145, 143, - 141, 141, 142, 142, 138, 137, 139, 132, 135, 136, 136, 136, 137, 139, 141, 139, - 138, 138, 139, 141, 143, 143, 142, 143, 143, 143, 144, 144, 145, 145, 145, 148, - 147, 146, 145, 145, 145, 145, 145, 144, 149, 151, 150, 150, 152, 150, 146, 151, - 151, 149, 150, 149, 150, 150, 151, 149, 151, 151, 150, 150, 152, 155, 158, 149, - 155, 160, 154, 150, 152, 158, 162, 163, 158, 155, 156, 159, 160, 158, 154, 160, - 159, 159, 161, 164, 164, 163, 162, 161, 161, 161, 161, 161, 161, 160, 160, 159, - 161, 162, 163, 162, 160, 156, 155, 157, 158, 160, 161, 163, 162, 161, 159, 157, - 156, 156, 156, 157, 159, 161, 163, 169, 167, 164, 162, 161, 160, 158, 156, 156, - 158, 160, 161, 159, 155, 150, 147, 147, 146, 146, 146, 146, 147, 148, 149, 141, - 146, 150, 151, 152, 153, 151, 147, 149, 150, 151, 150, 150, 150, 152, 155, 149, - 150, 151, 150, 148, 146, 146, 146, 156, 148, 141, 141, 146, 146, 139, 131, 132, - 126, 123, 115, 112, 122, 131, 117, 107, 109, 112, 121, 125, 124, 116, 109, 104, - 101, 97, 95, 99, 97, 101, 112, 113, 109, 113, 108, 107, 108, 113, 119, 127, - 134, 139, 144, 143, 141, 142, 141, 139, 138, 139, 137, 138, 139, 139, 139, 140, - 142, 144, 141, 140, 138, 140, 142, 144, 143, 142, 146, 146, 145, 146, 146, 146, - 145, 145, 144, 145, 144, 145, 144, 146, 145, 147, 146, 151, 152, 151, 150, 154, - 152, 148, 156, 153, 151, 151, 153, 155, 153, 152, 150, 152, 152, 151, 151, 153, - 156, 158, 151, 155, 158, 155, 152, 155, 159, 159, 162, 159, 157, 157, 158, 159, - 158, 156, 162, 162, 162, 163, 164, 164, 164, 164, 164, 163, 162, 161, 161, 162, - 163, 164, 159, 160, 161, 163, 165, 164, 162, 160, 161, 162, 164, 164, 164, 163, - 161, 160, 159, 158, 157, 157, 158, 161, 164, 167, 163, 161, 159, 159, 160, 160, - 159, 158, 154, 155, 158, 159, 158, 155, 152, 150, 149, 149, 148, 148, 148, 148, - 148, 148, 142, 143, 146, 149, 149, 150, 149, 147, 147, 151, 152, 151, 149, 150, - 152, 157, 157, 158, 159, 159, 157, 155, 153, 152, 157, 152, 147, 147, 148, 147, - 142, 136, 133, 132, 131, 124, 116, 121, 124, 107, 96, 102, 108, 98, 103, 108, - 113, 122, 131, 134, 129, 115, 123, 124, 125, 130, 129, 128, 136, 130, 133, 137, - 138, 135, 137, 142, 147, 139, 139, 139, 137, 137, 137, 136, 135, 140, 142, 142, - 142, 141, 142, 144, 146, 144, 144, 143, 144, 145, 145, 144, 143, 145, 146, 144, - 144, 145, 145, 144, 144, 146, 147, 148, 150, 152, 153, 154, 154, 152, 154, 154, - 150, 151, 155, 156, 154, 159, 155, 152, 152, 155, 156, 154, 151, 148, 150, 151, - 150, 150, 151, 154, 157, 153, 155, 155, 154, 157, 160, 156, 149, 155, 157, 159, - 158, 156, 156, 158, 161, 160, 160, 160, 159, 158, 158, 158, 159, 164, 163, 162, - 162, 162, 164, 167, 169, 166, 164, 162, 162, 165, 166, 164, 163, 161, 162, 163, - 162, 161, 159, 157, 155, 159, 158, 156, 156, 156, 158, 161, 163, 157, 156, 156, - 157, 158, 160, 159, 158, 155, 156, 156, 157, 157, 158, 158, 158, 155, 154, 154, - 153, 151, 150, 148, 146, 146, 144, 143, 145, 145, 144, 146, 147, 144, 148, 151, - 152, 149, 150, 151, 155, 156, 157, 157, 157, 156, 154, 151, 149, 149, 150, 152, - 150, 146, 142, 138, 136, 130, 130, 131, 117, 111, 115, 116, 106, 105, 114, 116, - 137, 138, 137, 134, 135, 136, 133, 125, 128, 137, 137, 134, 136, 132, 129, 139, - 126, 131, 137, 136, 130, 127, 129, 135, 140, 143, 143, 141, 141, 143, 143, 140, - 139, 141, 143, 143, 142, 142, 143, 145, 148, 147, 146, 146, 146, 147, 146, 145, - 147, 147, 147, 147, 147, 148, 148, 147, 145, 146, 147, 150, 151, 153, 153, 154, - 153, 156, 153, 150, 149, 155, 156, 156, 157, 154, 151, 152, 154, 155, 153, 150, - 147, 148, 148, 147, 146, 147, 149, 152, 154, 153, 152, 153, 158, 162, 155, 145, - 152, 156, 160, 159, 156, 155, 160, 164, 161, 162, 162, 160, 157, 157, 158, 159, - 162, 162, 161, 161, 162, 164, 166, 168, 172, 169, 164, 163, 164, 165, 163, 160, - 160, 160, 158, 156, 154, 153, 152, 151, 156, 155, 154, 153, 153, 154, 155, 156, - 159, 158, 158, 158, 160, 160, 157, 156, 159, 158, 157, 156, 156, 158, 161, 163, - 157, 157, 157, 155, 153, 151, 149, 145, 150, 143, 141, 142, 142, 142, 146, 150, - 149, 152, 156, 159, 158, 158, 157, 158, 154, 154, 152, 151, 151, 150, 147, 145, - 144, 149, 154, 152, 146, 141, 140, 141, 138, 138, 137, 107, 105, 109, 112, 110, - 119, 126, 119, 110, 119, 126, 125, 126, 129, 133, 133, 131, 137, 134, 132, 137, - 135, 131, 136, 137, 139, 142, 142, 140, 139, 139, 143, 142, 146, 147, 144, 144, - 149, 150, 146, 140, 142, 144, 146, 144, 144, 143, 145, 148, 146, 145, 147, 149, - 150, 149, 148, 150, 150, 150, 151, 151, 151, 152, 151, 143, 144, 145, 147, 148, - 148, 147, 147, 149, 152, 152, 149, 150, 153, 154, 152, 157, 156, 154, 154, 154, - 154, 153, 153, 151, 151, 150, 149, 146, 147, 149, 152, 152, 153, 152, 152, 156, - 160, 158, 152, 158, 158, 158, 158, 158, 159, 161, 162, 161, 162, 162, 161, 158, - 158, 161, 163, 161, 160, 160, 160, 160, 160, 161, 162, 173, 169, 165, 165, 166, - 166, 162, 157, 158, 157, 154, 152, 150, 151, 152, 153, 153, 153, 155, 155, 155, - 156, 156, 157, 160, 159, 159, 159, 160, 159, 158, 155, 160, 160, 156, 155, 154, - 156, 157, 159, 157, 158, 157, 157, 155, 154, 150, 148, 150, 142, 141, 144, 145, - 144, 148, 154, 151, 154, 158, 163, 166, 166, 161, 158, 161, 159, 156, 155, 155, - 155, 153, 150, 151, 152, 154, 154, 152, 151, 152, 153, 154, 155, 155, 103, 102, - 106, 104, 103, 113, 114, 98, 100, 114, 124, 122, 116, 118, 125, 131, 128, 131, - 126, 128, 140, 140, 135, 137, 140, 138, 135, 134, 134, 134, 133, 132, 135, 141, - 143, 140, 140, 146, 147, 143, 142, 145, 148, 149, 148, 146, 145, 145, 144, 143, - 144, 146, 150, 151, 151, 150, 146, 146, 146, 147, 147, 148, 149, 148, 148, 148, - 149, 150, 150, 148, 147, 146, 145, 150, 152, 150, 151, 153, 151, 148, 159, 159, - 159, 158, 157, 156, 156, 157, 156, 156, 155, 152, 150, 150, 152, 154, 150, 153, - 154, 152, 153, 158, 162, 161, 164, 160, 156, 157, 161, 163, 162, 159, 154, 156, - 157, 156, 154, 155, 158, 162, 160, 160, 159, 158, 157, 156, 156, 156, 166, 165, - 163, 166, 170, 170, 163, 157, 158, 157, 153, 151, 152, 154, 157, 159, 153, 155, - 157, 158, 159, 160, 160, 161, 156, 156, 156, 158, 159, 160, 158, 156, 158, 158, - 155, 153, 151, 151, 150, 151, 154, 156, 156, 157, 156, 155, 152, 150, 148, 142, - 142, 148, 149, 148, 151, 158, 145, 147, 151, 158, 163, 163, 156, 151, 147, 143, - 138, 136, 137, 138, 136, 134, 132, 129, 127, 128, 132, 136, 137, 137, 134, 139, - 142, 101, 103, 108, 116, 122, 124, 121, 118, 94, 122, 135, 121, 111, 120, 123, - 116, 127, 128, 130, 131, 131, 131, 131, 132, 135, 139, 137, 133, 131, 135, 134, - 129, 134, 138, 140, 139, 137, 136, 139, 142, 139, 142, 145, 146, 145, 145, 146, - 147, 146, 145, 144, 145, 146, 148, 150, 152, 148, 152, 152, 144, 143, 149, 152, - 151, 147, 144, 143, 147, 153, 155, 154, 151, 157, 151, 150, 155, 157, 153, 152, - 157, 156, 155, 153, 153, 152, 151, 149, 147, 156, 156, 155, 151, 149, 149, 153, - 159, 156, 156, 157, 157, 157, 155, 154, 153, 156, 157, 157, 158, 158, 157, 155, - 155, 155, 159, 162, 161, 156, 154, 157, 161, 158, 159, 160, 161, 161, 160, 158, - 157, 164, 165, 166, 167, 165, 164, 162, 160, 158, 157, 155, 155, 156, 159, 162, - 163, 159, 159, 157, 161, 163, 165, 161, 159, 163, 158, 153, 154, 157, 160, 157, - 154, 154, 154, 152, 153, 154, 156, 155, 156, 155, 157, 158, 159, 156, 152, 146, - 142, 147, 140, 144, 147, 141, 142, 151, 155, 156, 156, 146, 133, 128, 137, 145, - 150, 147, 145, 143, 141, 137, 134, 137, 142, 134, 134, 134, 134, 133, 133, 133, - 133, 133, 131, 130, 106, 106, 107, 110, 110, 108, 101, 95, 102, 118, 126, 120, - 117, 125, 126, 120, 124, 124, 126, 128, 129, 130, 129, 131, 121, 126, 128, 126, - 128, 134, 135, 132, 128, 130, 132, 132, 133, 134, 137, 139, 137, 137, 139, 139, - 138, 140, 144, 145, 145, 144, 144, 143, 144, 144, 145, 146, 148, 152, 152, 147, - 144, 147, 147, 144, 146, 147, 149, 150, 151, 152, 153, 154, 156, 151, 150, 154, - 156, 153, 152, 155, 155, 154, 152, 152, 152, 153, 152, 152, 153, 155, 155, 153, - 151, 151, 154, 158, 153, 153, 154, 154, 153, 151, 150, 149, 157, 157, 157, 157, - 157, 156, 154, 153, 151, 157, 162, 162, 158, 155, 155, 157, 152, 153, 154, 156, - 156, 157, 157, 157, 160, 161, 162, 163, 163, 163, 161, 160, 157, 155, 154, 153, - 154, 156, 157, 160, 161, 161, 159, 160, 162, 164, 160, 159, 157, 155, 153, 156, - 161, 162, 159, 154, 154, 155, 156, 153, 149, 148, 150, 153, 152, 154, 156, 158, - 158, 156, 154, 152, 159, 151, 153, 154, 146, 145, 152, 154, 140, 146, 155, 156, - 145, 133, 135, 146, 144, 139, 138, 142, 147, 145, 138, 131, 133, 133, 132, 131, - 130, 129, 128, 128, 132, 132, 133, 120, 121, 122, 124, 124, 123, 118, 114, 116, - 119, 119, 120, 123, 128, 125, 121, 128, 128, 129, 131, 131, 131, 130, 131, 123, - 126, 128, 127, 127, 130, 128, 125, 130, 129, 128, 129, 132, 134, 134, 134, 140, - 140, 140, 140, 140, 142, 147, 150, 149, 149, 148, 147, 147, 148, 148, 148, 147, - 152, 154, 152, 149, 150, 149, 146, 147, 151, 154, 153, 150, 150, 153, 157, 153, - 149, 147, 151, 152, 150, 149, 150, 154, 154, 151, 150, 149, 149, 150, 151, 150, - 152, 155, 154, 152, 150, 149, 150, 148, 149, 150, 151, 152, 152, 150, 150, 156, - 156, 157, 157, 156, 155, 154, 153, 152, 158, 164, 165, 162, 159, 157, 158, 157, - 157, 157, 157, 157, 158, 159, 160, 158, 158, 159, 161, 161, 161, 160, 160, 162, - 161, 158, 157, 157, 158, 160, 162, 167, 166, 163, 164, 164, 165, 164, 162, 163, - 163, 162, 164, 166, 165, 160, 155, 155, 159, 161, 156, 149, 146, 149, 154, 148, - 149, 151, 152, 153, 153, 153, 153, 157, 148, 150, 151, 143, 141, 147, 147, 152, - 144, 146, 156, 151, 137, 139, 156, 158, 152, 146, 143, 145, 145, 142, 138, 142, - 141, 140, 139, 137, 136, 134, 134, 125, 127, 129, 117, 119, 121, 124, 128, 127, - 126, 125, 128, 123, 120, 123, 127, 124, 122, 121, 130, 130, 130, 130, 129, 128, - 127, 126, 128, 129, 130, 129, 128, 126, 123, 121, 132, 129, 126, 127, 131, 133, - 131, 129, 144, 145, 146, 145, 145, 145, 148, 150, 149, 149, 149, 149, 150, 150, - 150, 150, 147, 151, 153, 153, 151, 152, 154, 154, 150, 151, 152, 151, 149, 149, - 151, 154, 153, 150, 149, 150, 151, 151, 149, 149, 154, 153, 151, 147, 145, 145, - 146, 148, 150, 151, 153, 154, 151, 147, 143, 142, 145, 146, 148, 150, 152, 154, - 155, 155, 154, 154, 155, 155, 156, 156, 156, 156, 154, 157, 161, 162, 160, 158, - 158, 158, 163, 162, 160, 159, 158, 159, 160, 161, 159, 160, 160, 159, 160, 159, - 159, 159, 164, 163, 162, 161, 160, 160, 161, 162, 165, 165, 163, 162, 162, 163, - 164, 165, 164, 164, 163, 164, 165, 165, 163, 159, 161, 162, 162, 159, 154, 153, - 153, 157, 152, 152, 150, 150, 148, 149, 148, 149, 160, 151, 154, 157, 151, 151, - 158, 156, 161, 141, 129, 138, 149, 150, 150, 153, 148, 153, 154, 149, 143, 144, - 146, 148, 149, 149, 148, 148, 146, 146, 144, 144, 144, 146, 145, 123, 125, 125, - 125, 124, 123, 122, 122, 130, 124, 124, 127, 126, 121, 122, 127, 123, 124, 125, - 125, 125, 125, 124, 123, 123, 124, 125, 128, 128, 128, 126, 126, 128, 126, 124, - 126, 130, 133, 132, 130, 143, 145, 148, 149, 147, 145, 145, 145, 142, 143, 144, - 146, 147, 148, 148, 149, 151, 151, 151, 150, 149, 150, 154, 157, 153, 150, 147, - 148, 150, 152, 151, 150, 157, 156, 155, 154, 155, 156, 155, 151, 150, 149, 151, - 149, 147, 147, 150, 153, 148, 150, 152, 154, 153, 151, 147, 143, 147, 148, 148, - 150, 151, 153, 153, 154, 151, 151, 152, 154, 155, 157, 157, 159, 154, 155, 155, - 154, 154, 155, 156, 158, 159, 158, 157, 156, 156, 158, 159, 160, 163, 162, 162, - 159, 159, 157, 158, 157, 160, 159, 159, 158, 157, 157, 157, 156, 157, 156, 155, - 155, 155, 158, 160, 163, 157, 155, 154, 155, 158, 163, 166, 167, 163, 160, 156, - 157, 159, 161, 158, 157, 158, 158, 155, 154, 151, 152, 150, 152, 153, 144, 148, - 154, 150, 150, 156, 154, 143, 135, 127, 130, 143, 153, 149, 141, 127, 136, 144, - 148, 149, 153, 149, 143, 147, 148, 147, 148, 147, 148, 147, 148, 150, 152, 151, - 127, 130, 130, 130, 127, 127, 127, 128, 123, 124, 127, 128, 127, 124, 127, 132, - 121, 123, 125, 127, 128, 129, 129, 130, 131, 129, 128, 130, 130, 127, 127, 129, - 128, 128, 128, 131, 134, 138, 140, 139, 142, 147, 150, 153, 151, 148, 147, 145, - 144, 145, 147, 149, 150, 151, 151, 151, 156, 152, 150, 149, 146, 143, 147, 152, - 153, 149, 145, 145, 150, 152, 151, 148, 153, 153, 152, 149, 150, 152, 151, 145, - 145, 148, 152, 152, 153, 153, 157, 161, 150, 150, 150, 153, 155, 156, 155, 153, - 152, 151, 150, 149, 148, 148, 147, 148, 151, 151, 151, 153, 154, 157, 158, 160, - 159, 158, 157, 156, 156, 159, 161, 163, 156, 156, 157, 158, 159, 161, 163, 165, - 166, 164, 162, 159, 158, 156, 155, 156, 157, 158, 157, 157, 158, 157, 157, 155, - 153, 154, 155, 156, 156, 158, 160, 163, 165, 164, 158, 156, 155, 157, 160, 162, - 158, 153, 148, 151, 156, 160, 156, 153, 152, 152, 150, 151, 150, 151, 150, 152, - 151, 140, 144, 149, 144, 144, 147, 144, 137, 142, 139, 127, 125, 137, 150, 154, - 150, 144, 133, 131, 140, 153, 150, 140, 144, 145, 145, 146, 146, 148, 147, 148, - 142, 142, 141, 114, 118, 118, 119, 117, 119, 122, 126, 121, 124, 127, 127, 126, - 129, 129, 130, 128, 129, 130, 132, 133, 133, 133, 133, 131, 125, 123, 125, 124, - 121, 121, 126, 129, 130, 131, 132, 132, 133, 135, 137, 142, 145, 148, 151, 150, - 149, 149, 150, 150, 152, 153, 155, 156, 156, 155, 154, 158, 154, 153, 153, 150, - 144, 145, 150, 152, 149, 147, 147, 148, 151, 152, 153, 148, 150, 148, 144, 145, - 148, 147, 140, 143, 148, 153, 155, 154, 153, 155, 158, 154, 152, 150, 150, 153, - 155, 154, 153, 154, 152, 151, 150, 149, 150, 150, 151, 153, 153, 152, 152, 153, - 155, 155, 158, 161, 160, 159, 159, 161, 163, 164, 164, 159, 159, 160, 160, 161, - 160, 160, 161, 163, 161, 159, 156, 155, 154, 155, 156, 156, 157, 157, 158, 158, - 157, 158, 155, 151, 153, 155, 156, 154, 154, 155, 158, 167, 165, 161, 157, 151, - 150, 149, 150, 152, 150, 146, 148, 151, 154, 152, 151, 143, 145, 144, 146, 146, - 147, 146, 147, 157, 147, 148, 153, 148, 148, 150, 146, 144, 143, 139, 128, 119, - 122, 141, 158, 158, 156, 144, 131, 131, 144, 147, 144, 145, 146, 145, 146, 146, - 147, 146, 146, 148, 146, 144, 120, 123, 124, 121, 118, 117, 120, 124, 124, 128, - 129, 126, 127, 132, 129, 122, 132, 133, 133, 132, 130, 128, 126, 126, 110, 105, - 105, 110, 114, 113, 118, 126, 127, 127, 128, 125, 120, 119, 120, 122, 135, 136, - 140, 143, 143, 145, 148, 150, 151, 153, 154, 155, 155, 154, 152, 151, 156, 154, - 156, 160, 156, 150, 149, 153, 149, 150, 151, 149, 146, 147, 152, 157, 151, 153, - 151, 147, 147, 151, 150, 143, 146, 151, 156, 155, 151, 147, 146, 147, 158, 153, - 148, 145, 146, 147, 146, 146, 152, 151, 151, 152, 154, 156, 159, 160, 157, 155, - 154, 154, 153, 154, 155, 156, 153, 154, 155, 157, 159, 160, 158, 157, 161, 162, - 161, 160, 157, 154, 150, 148, 159, 159, 157, 155, 153, 154, 156, 156, 150, 151, - 152, 153, 153, 154, 153, 150, 144, 146, 150, 150, 147, 146, 146, 148, 146, 148, - 149, 148, 147, 147, 148, 150, 149, 150, 150, 149, 148, 148, 150, 151, 145, 146, - 147, 148, 148, 148, 146, 146, 142, 131, 132, 138, 135, 135, 136, 131, 136, 127, - 130, 138, 135, 122, 121, 132, 117, 142, 160, 154, 140, 138, 141, 143, 144, 144, - 143, 143, 142, 142, 140, 140, 144, 141, 139, 130, 124, 122, 125, 125, 120, 117, - 120, 130, 124, 124, 132, 136, 131, 127, 127, 125, 119, 131, 122, 120, 114, 96, - 117, 109, 110, 110, 109, 107, 106, 107, 108, 120, 114, 115, 122, 123, 117, 119, - 127, 128, 121, 122, 134, 144, 145, 146, 148, 147, 150, 153, 153, 151, 151, 155, - 158, 162, 161, 159, 156, 155, 155, 155, 155, 150, 149, 150, 150, 150, 150, 151, - 151, 144, 143, 143, 147, 151, 152, 149, 146, 154, 155, 155, 154, 154, 156, 156, - 157, 150, 153, 155, 152, 148, 147, 151, 158, 162, 160, 156, 153, 151, 152, 155, - 157, 151, 153, 157, 159, 160, 160, 159, 158, 151, 153, 155, 155, 155, 156, 159, - 162, 159, 156, 153, 153, 155, 156, 154, 152, 153, 151, 152, 155, 154, 151, 150, - 153, 149, 149, 150, 151, 153, 153, 151, 149, 150, 153, 153, 149, 151, 156, 157, - 155, 159, 153, 150, 151, 151, 146, 147, 153, 148, 149, 149, 149, 148, 146, 143, - 142, 144, 142, 140, 139, 139, 140, 142, 143, 140, 150, 132, 122, 133, 104, 128, - 144, 139, 148, 149, 141, 136, 133, 120, 100, 100, 111, 140, 171, 152, 147, 123, - 144, 139, 136, 141, 150, 151, 143, 141, 145, 146, 146, 146, 26, 28, 28, 27, - 25, 24, 24, 24, 24, 24, 24, 25, 25, 24, 26, 26, 27, 35, 33, 31, - 37, 33, 27, 31, 30, 31, 33, 37, 38, 38, 38, 35, 37, 35, 37, 35, - 37, 35, 37, 35, 34, 33, 36, 35, 38, 37, 39, 39, 38, 42, 42, 39, - 40, 43, 43, 41, 43, 42, 42, 41, 41, 42, 42, 43, 42, 42, 42, 43, - 43, 44, 44, 44, 43, 44, 45, 46, 46, 46, 46, 45, 45, 45, 47, 48, - 48, 49, 49, 49, 49, 49, 49, 50, 50, 51, 51, 51, 51, 51, 51, 52, - 52, 53, 53, 53, 56, 55, 54, 53, 54, 55, 57, 58, 54, 58, 54, 51, - 58, 56, 54, 59, 58, 58, 61, 60, 59, 58, 61, 62, 58, 59, 60, 61, - 61, 61, 61, 60, 55, 62, 60, 57, 62, 60, 57, 66, 63, 61, 62, 59, - 62, 62, 67, 66, 68, 68, 66, 72, 70, 62, 66, 46, 0, 16, 54, 62, - 86, 85, 101, 97, 91, 86, 75, 76, 89, 90, 86, 90, 91, 86, 86, 89, - 89, 87, 88, 91, 92, 91, 89, 89, 91, 91, 89, 88, 90, 91, 91, 91, - 91, 90, 89, 88, 92, 92, 92, 91, 91, 90, 90, 90, 92, 91, 91, 27, - 27, 27, 26, 26, 25, 25, 25, 21, 22, 24, 25, 26, 25, 27, 26, 31, - 32, 32, 31, 30, 31, 35, 38, 34, 35, 37, 38, 37, 36, 38, 39, 39, - 37, 40, 37, 38, 34, 33, 30, 37, 35, 37, 35, 37, 36, 40, 40, 40, - 40, 40, 41, 41, 42, 42, 42, 44, 43, 43, 42, 42, 43, 43, 44, 41, - 43, 45, 44, 43, 42, 42, 43, 44, 47, 48, 45, 45, 48, 47, 42, 43, - 41, 43, 44, 44, 45, 45, 45, 49, 49, 50, 51, 51, 52, 52, 52, 52, - 56, 56, 53, 54, 57, 57, 55, 54, 54, 54, 55, 55, 56, 56, 56, 55, - 55, 59, 57, 58, 55, 58, 57, 56, 58, 60, 55, 58, 59, 61, 59, 63, - 61, 59, 60, 64, 65, 63, 61, 64, 63, 61, 60, 60, 61, 63, 64, 60, - 63, 65, 60, 62, 63, 65, 60, 70, 63, 67, 64, 72, 53, 64, 42, 0, - 19, 53, 60, 89, 87, 95, 96, 92, 91, 80, 79, 90, 90, 84, 86, 86, - 84, 84, 87, 88, 85, 85, 89, 90, 90, 90, 90, 90, 90, 90, 90, 89, - 91, 93, 93, 91, 90, 90, 91, 93, 93, 91, 90, 90, 90, 90, 90, 90, - 97, 94, 26, 26, 25, 25, 25, 24, 24, 24, 25, 25, 26, 27, 28, 28, - 29, 30, 31, 32, 32, 31, 30, 31, 35, 38, 32, 33, 36, 36, 36, 36, - 38, 37, 37, 37, 38, 38, 38, 37, 36, 36, 40, 39, 38, 37, 37, 37, - 38, 38, 40, 40, 40, 41, 41, 42, 42, 42, 44, 43, 43, 42, 42, 43, - 43, 44, 42, 43, 45, 45, 44, 42, 43, 44, 44, 48, 48, 45, 45, 48, - 47, 41, 43, 41, 42, 42, 44, 45, 45, 45, 49, 49, 50, 51, 51, 52, - 52, 52, 52, 56, 56, 53, 54, 57, 57, 55, 54, 54, 55, 55, 55, 56, - 56, 56, 55, 58, 60, 60, 59, 58, 59, 60, 57, 60, 60, 57, 58, 61, - 62, 59, 62, 61, 60, 61, 63, 64, 63, 62, 63, 63, 62, 61, 61, 62, - 63, 63, 62, 65, 65, 62, 62, 65, 65, 62, 67, 63, 65, 63, 70, 54, - 63, 42, 0, 22, 53, 60, 87, 85, 93, 96, 90, 90, 81, 81, 90, 92, - 84, 87, 88, 85, 85, 89, 89, 86, 87, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 89, 91, 93, 93, 91, 90, 90, 91, 93, 92, 91, 90, 90, 90, - 90, 91, 90, 97, 94, 25, 24, 24, 24, 24, 23, 23, 23, 27, 27, 26, - 26, 26, 28, 30, 31, 29, 30, 32, 32, 31, 31, 35, 37, 32, 34, 36, - 36, 35, 34, 36, 37, 36, 36, 36, 36, 37, 37, 38, 39, 41, 40, 39, - 38, 37, 37, 37, 37, 40, 40, 40, 41, 41, 42, 42, 42, 44, 43, 43, - 42, 42, 43, 43, 44, 42, 44, 46, 46, 44, 43, 44, 45, 45, 48, 49, - 46, 45, 47, 46, 40, 43, 42, 42, 42, 45, 45, 45, 45, 49, 49, 50, - 51, 51, 52, 52, 52, 52, 56, 56, 53, 54, 57, 57, 55, 54, 55, 55, - 55, 56, 56, 56, 56, 56, 59, 61, 61, 60, 59, 60, 61, 57, 60, 60, - 58, 58, 61, 62, 59, 60, 61, 63, 62, 62, 61, 63, 64, 63, 63, 62, - 62, 62, 62, 63, 63, 63, 66, 66, 63, 63, 66, 66, 63, 65, 62, 64, - 62, 70, 56, 64, 41, 0, 22, 54, 61, 87, 85, 93, 96, 88, 89, 80, - 80, 91, 93, 86, 88, 89, 86, 86, 90, 90, 87, 88, 91, 90, 90, 90, - 90, 90, 90, 90, 90, 89, 91, 93, 93, 91, 90, 90, 91, 93, 92, 91, - 90, 90, 90, 91, 91, 90, 97, 94, 25, 25, 24, 24, 24, 24, 24, 24, - 27, 26, 24, 23, 23, 25, 28, 30, 28, 30, 33, 32, 31, 31, 35, 37, - 35, 36, 39, 38, 37, 37, 39, 40, 38, 37, 36, 35, 35, 37, 39, 40, - 40, 40, 39, 38, 38, 38, 39, 39, 40, 40, 40, 41, 41, 42, 42, 42, - 44, 43, 43, 42, 42, 43, 43, 44, 43, 45, 47, 47, 45, 44, 45, 46, - 46, 49, 49, 46, 45, 47, 46, 40, 44, 42, 42, 43, 45, 45, 46, 46, - 49, 49, 50, 51, 51, 52, 52, 52, 52, 56, 56, 53, 54, 57, 57, 55, - 55, 55, 55, 56, 56, 56, 57, 57, 57, 59, 61, 62, 60, 60, 60, 62, - 57, 60, 61, 58, 58, 62, 62, 59, 59, 62, 64, 63, 61, 60, 62, 65, - 63, 63, 63, 62, 62, 63, 63, 63, 62, 65, 65, 62, 62, 65, 65, 62, - 64, 62, 63, 61, 70, 57, 65, 39, 0, 23, 55, 61, 87, 85, 93, 96, - 89, 90, 81, 80, 90, 92, 85, 87, 88, 85, 86, 89, 89, 87, 87, 90, - 91, 91, 90, 90, 90, 90, 89, 89, 89, 91, 93, 93, 91, 90, 90, 91, - 92, 92, 91, 90, 90, 90, 91, 92, 90, 97, 94, 25, 25, 26, 26, 26, - 26, 26, 26, 28, 27, 25, 23, 24, 25, 28, 29, 27, 29, 31, 31, 32, - 31, 32, 34, 35, 37, 38, 38, 38, 38, 39, 41, 40, 39, 37, 35, 35, - 36, 37, 38, 37, 37, 37, 38, 39, 40, 42, 43, 40, 40, 40, 41, 41, - 42, 42, 42, 44, 43, 43, 42, 42, 43, 43, 44, 43, 45, 47, 47, 45, - 44, 45, 46, 45, 48, 49, 46, 45, 47, 46, 40, 44, 42, 43, 43, 45, - 46, 46, 46, 49, 49, 50, 51, 51, 52, 52, 52, 52, 56, 56, 53, 54, - 57, 57, 55, 55, 55, 56, 56, 56, 57, 57, 57, 57, 59, 61, 62, 60, - 60, 60, 62, 58, 61, 61, 59, 59, 62, 63, 60, 59, 62, 64, 63, 61, - 60, 62, 65, 63, 63, 63, 64, 64, 63, 63, 63, 61, 64, 64, 61, 61, - 64, 64, 61, 63, 62, 64, 60, 70, 59, 64, 36, 0, 24, 55, 62, 88, - 85, 92, 96, 91, 92, 82, 81, 90, 91, 83, 85, 87, 84, 84, 88, 88, - 85, 86, 89, 91, 91, 91, 90, 90, 89, 89, 89, 89, 91, 93, 93, 91, - 90, 90, 91, 92, 91, 90, 90, 90, 91, 92, 92, 90, 97, 94, 25, 26, - 26, 26, 26, 27, 27, 27, 30, 29, 28, 27, 27, 28, 30, 30, 27, 29, - 31, 31, 32, 32, 32, 33, 33, 35, 36, 36, 36, 36, 37, 39, 39, 38, - 37, 37, 36, 36, 36, 36, 36, 37, 37, 38, 40, 42, 43, 44, 40, 40, - 40, 41, 41, 42, 42, 42, 44, 43, 43, 42, 42, 43, 43, 44, 42, 44, - 46, 46, 44, 43, 44, 45, 44, 47, 48, 45, 45, 48, 47, 42, 45, 43, - 43, 43, 46, 46, 46, 47, 49, 49, 50, 51, 51, 52, 52, 52, 52, 56, - 56, 53, 54, 57, 57, 55, 56, 56, 56, 56, 57, 57, 57, 58, 56, 59, - 61, 61, 60, 59, 60, 61, 58, 61, 62, 59, 59, 63, 63, 60, 60, 61, - 63, 62, 62, 61, 63, 64, 63, 63, 64, 64, 64, 64, 63, 63, 60, 63, - 63, 60, 60, 63, 63, 60, 64, 63, 64, 59, 69, 59, 64, 32, 0, 25, - 56, 62, 88, 85, 92, 96, 92, 92, 83, 81, 90, 90, 82, 84, 86, 83, - 84, 87, 87, 85, 85, 88, 92, 92, 91, 90, 90, 89, 88, 88, 89, 91, - 93, 93, 91, 90, 90, 91, 91, 91, 90, 90, 90, 91, 92, 93, 90, 97, - 94, 24, 24, 25, 25, 25, 26, 26, 26, 29, 29, 29, 29, 29, 29, 29, - 29, 24, 27, 31, 32, 31, 30, 32, 33, 32, 33, 37, 36, 35, 35, 36, - 38, 36, 36, 37, 38, 38, 38, 37, 37, 38, 38, 38, 39, 40, 41, 42, - 43, 40, 40, 40, 41, 41, 42, 42, 42, 44, 43, 43, 42, 42, 43, 43, - 44, 42, 43, 45, 45, 44, 42, 43, 44, 42, 46, 47, 45, 46, 49, 49, - 44, 45, 43, 43, 44, 46, 46, 47, 47, 49, 49, 50, 51, 51, 52, 52, - 52, 52, 56, 56, 53, 54, 57, 57, 55, 56, 56, 56, 57, 57, 57, 58, - 58, 55, 58, 60, 60, 59, 58, 59, 60, 58, 61, 62, 59, 60, 63, 63, - 60, 62, 61, 60, 61, 63, 64, 63, 62, 63, 63, 64, 65, 65, 64, 63, - 63, 61, 64, 64, 61, 61, 64, 64, 61, 65, 65, 65, 58, 69, 60, 62, - 28, 0, 26, 57, 63, 88, 85, 92, 95, 91, 91, 82, 81, 90, 91, 83, - 86, 87, 84, 85, 88, 88, 86, 86, 89, 92, 92, 91, 90, 90, 89, 88, - 88, 89, 91, 93, 93, 91, 90, 90, 91, 91, 90, 90, 90, 90, 91, 92, - 93, 90, 97, 94, 23, 23, 23, 24, 24, 25, 25, 25, 26, 27, 27, 28, - 28, 27, 26, 26, 24, 27, 31, 32, 31, 30, 32, 33, 34, 36, 39, 39, - 38, 37, 39, 40, 32, 33, 36, 38, 39, 40, 39, 39, 40, 40, 39, 39, - 39, 40, 41, 41, 40, 40, 40, 41, 41, 42, 42, 42, 44, 43, 43, 42, - 42, 43, 43, 44, 41, 43, 45, 44, 43, 42, 42, 43, 41, 45, 46, 45, - 46, 50, 50, 45, 45, 43, 43, 44, 46, 47, 47, 47, 49, 49, 50, 51, - 51, 52, 52, 52, 52, 56, 56, 53, 54, 57, 57, 55, 56, 56, 56, 57, - 57, 58, 58, 58, 55, 57, 59, 59, 58, 57, 58, 59, 58, 62, 62, 59, - 60, 63, 63, 61, 63, 61, 59, 60, 64, 65, 63, 61, 62, 63, 65, 66, - 66, 65, 63, 62, 63, 66, 66, 63, 63, 66, 66, 63, 65, 66, 66, 58, - 69, 60, 62, 26, 0, 26, 57, 63, 88, 85, 92, 95, 88, 89, 80, 80, - 90, 92, 85, 88, 88, 86, 86, 89, 90, 87, 87, 91, 92, 92, 91, 90, - 90, 89, 88, 88, 89, 91, 93, 93, 91, 90, 90, 91, 90, 90, 90, 90, - 90, 91, 93, 93, 90, 97, 94, 27, 27, 28, 28, 28, 27, 26, 26, 28, - 27, 26, 27, 29, 30, 29, 28, 28, 28, 28, 28, 28, 28, 30, 30, 34, - 35, 35, 36, 38, 37, 37, 36, 38, 35, 35, 38, 38, 35, 35, 38, 41, - 40, 40, 40, 40, 41, 42, 43, 45, 44, 42, 40, 39, 39, 40, 40, 43, - 44, 45, 46, 46, 44, 43, 42, 44, 43, 43, 43, 43, 44, 45, 46, 50, - 49, 47, 46, 45, 45, 46, 45, 46, 44, 44, 45, 47, 48, 48, 48, 50, - 50, 52, 52, 52, 53, 53, 53, 57, 56, 55, 55, 57, 57, 56, 55, 61, - 55, 58, 60, 54, 57, 62, 57, 59, 59, 59, 60, 60, 61, 61, 61, 62, - 61, 61, 61, 61, 61, 60, 60, 66, 65, 63, 63, 63, 63, 65, 66, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 66, 65, 61, 61, 65, 66, 64, 71, - 63, 68, 65, 67, 56, 61, 22, 0, 29, 60, 63, 89, 89, 96, 97, 96, - 87, 82, 86, 89, 90, 86, 86, 88, 86, 87, 89, 88, 84, 85, 89, 93, - 92, 90, 88, 86, 85, 85, 84, 89, 93, 94, 91, 91, 93, 91, 87, 96, - 94, 90, 87, 87, 89, 92, 94, 89, 98, 96, 27, 27, 27, 28, 27, 27, - 27, 26, 28, 27, 26, 27, 29, 30, 29, 28, 28, 28, 28, 28, 28, 28, - 30, 30, 34, 35, 35, 36, 38, 37, 37, 36, 39, 36, 36, 39, 39, 36, - 36, 39, 41, 40, 40, 40, 40, 41, 42, 43, 40, 40, 40, 40, 41, 42, - 43, 44, 43, 44, 44, 45, 45, 44, 44, 43, 44, 44, 43, 43, 44, 44, - 45, 46, 48, 47, 46, 46, 46, 47, 48, 47, 46, 44, 44, 45, 47, 48, - 48, 48, 50, 50, 51, 51, 52, 52, 52, 53, 56, 55, 53, 54, 56, 56, - 55, 54, 60, 54, 58, 60, 54, 57, 61, 56, 59, 59, 59, 60, 60, 61, - 61, 61, 61, 61, 61, 61, 61, 61, 61, 62, 63, 62, 61, 61, 61, 61, - 62, 63, 64, 64, 64, 64, 64, 64, 64, 64, 63, 66, 65, 62, 62, 65, - 66, 63, 67, 61, 66, 63, 68, 58, 63, 24, 0, 29, 60, 63, 89, 89, - 96, 97, 96, 87, 82, 86, 89, 90, 86, 86, 88, 86, 87, 89, 88, 84, - 85, 90, 91, 91, 90, 89, 88, 88, 89, 89, 90, 93, 93, 90, 90, 92, - 91, 88, 95, 93, 90, 88, 88, 89, 91, 93, 93, 97, 93, 27, 27, 27, - 27, 27, 27, 27, 27, 28, 27, 26, 27, 29, 30, 29, 28, 28, 26, 26, - 26, 28, 29, 29, 29, 32, 33, 35, 36, 36, 35, 35, 34, 39, 36, 36, - 39, 39, 36, 36, 39, 41, 40, 40, 40, 40, 41, 42, 43, 39, 39, 40, - 42, 43, 43, 43, 43, 44, 44, 44, 43, 43, 44, 44, 45, 44, 44, 43, - 43, 44, 45, 46, 46, 46, 46, 45, 46, 47, 48, 49, 48, 46, 44, 44, - 45, 47, 48, 48, 48, 49, 49, 50, 51, 51, 52, 52, 52, 55, 54, 53, - 53, 55, 56, 54, 53, 60, 54, 57, 59, 53, 56, 61, 56, 59, 59, 59, - 60, 60, 61, 61, 61, 60, 60, 60, 61, 62, 62, 63, 63, 63, 62, 62, - 61, 61, 62, 62, 63, 64, 64, 64, 64, 64, 64, 64, 64, 62, 65, 66, - 63, 63, 66, 65, 62, 64, 59, 64, 62, 68, 61, 66, 24, 0, 30, 61, - 64, 89, 89, 96, 96, 96, 87, 82, 86, 89, 90, 86, 86, 88, 86, 87, - 90, 88, 85, 86, 90, 89, 89, 89, 89, 90, 91, 92, 93, 91, 94, 93, - 89, 89, 92, 92, 89, 93, 92, 91, 90, 90, 90, 91, 91, 95, 97, 90, - 27, 27, 26, 26, 27, 27, 28, 28, 28, 27, 26, 27, 29, 30, 29, 26, - 28, 26, 26, 27, 29, 29, 29, 30, 32, 33, 35, 36, 36, 35, 35, 34, - 39, 36, 36, 39, 39, 36, 36, 39, 41, 40, 40, 40, 40, 41, 42, 43, - 41, 42, 43, 44, 43, 42, 40, 39, 45, 44, 43, 42, 42, 44, 45, 46, - 45, 44, 44, 44, 44, 45, 46, 47, 46, 46, 46, 46, 47, 48, 48, 47, - 46, 44, 44, 45, 47, 48, 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, - 56, 55, 54, 54, 56, 56, 55, 54, 59, 54, 57, 59, 53, 56, 60, 56, - 59, 59, 59, 60, 60, 61, 61, 61, 59, 60, 60, 61, 62, 63, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, - 61, 65, 66, 64, 64, 66, 65, 61, 63, 59, 64, 61, 68, 62, 66, 21, - 0, 30, 61, 64, 90, 89, 96, 96, 96, 87, 82, 86, 89, 90, 86, 86, - 87, 86, 87, 90, 89, 85, 87, 91, 89, 89, 88, 89, 89, 90, 92, 92, - 92, 94, 92, 88, 88, 91, 92, 90, 91, 92, 92, 92, 91, 91, 90, 89, - 94, 97, 91, 27, 26, 26, 26, 26, 27, 29, 29, 28, 27, 26, 27, 29, - 30, 29, 26, 28, 26, 26, 27, 27, 28, 30, 31, 32, 33, 33, 34, 36, - 35, 35, 34, 40, 37, 37, 40, 40, 37, 37, 40, 41, 40, 40, 40, 40, - 41, 42, 43, 41, 42, 43, 44, 44, 43, 41, 40, 44, 44, 43, 42, 43, - 44, 46, 47, 45, 45, 44, 44, 45, 45, 46, 47, 48, 48, 48, 48, 47, - 46, 46, 43, 46, 44, 44, 45, 47, 48, 48, 48, 49, 49, 50, 51, 51, - 52, 52, 52, 58, 57, 56, 56, 58, 58, 57, 56, 60, 54, 57, 59, 53, - 56, 61, 56, 59, 59, 59, 60, 60, 61, 61, 61, 60, 60, 61, 62, 63, - 64, 64, 65, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, - 65, 65, 65, 61, 65, 66, 64, 64, 66, 65, 61, 65, 62, 66, 60, 67, - 62, 63, 16, 0, 31, 62, 65, 90, 89, 96, 96, 96, 87, 82, 86, 89, - 90, 86, 86, 87, 86, 87, 90, 89, 86, 88, 92, 90, 89, 88, 88, 87, - 88, 88, 88, 92, 94, 92, 88, 88, 91, 92, 90, 91, 91, 92, 92, 92, - 91, 90, 89, 90, 98, 95, 27, 26, 25, 25, 26, 27, 29, 31, 28, 27, - 26, 27, 29, 30, 29, 26, 28, 26, 27, 27, 28, 29, 31, 31, 32, 33, - 33, 34, 36, 35, 35, 34, 40, 37, 37, 40, 40, 37, 37, 40, 41, 40, - 40, 40, 40, 41, 42, 43, 38, 39, 41, 43, 44, 45, 46, 46, 43, 43, - 43, 43, 44, 45, 46, 47, 45, 45, 45, 45, 45, 46, 47, 47, 48, 48, - 49, 48, 47, 46, 45, 42, 46, 44, 44, 45, 47, 48, 48, 48, 50, 50, - 52, 52, 52, 53, 53, 53, 59, 58, 56, 57, 59, 59, 58, 57, 61, 55, - 58, 60, 54, 57, 62, 57, 59, 59, 59, 60, 60, 61, 61, 61, 61, 61, - 62, 62, 63, 64, 64, 64, 61, 62, 62, 63, 63, 62, 62, 61, 66, 66, - 66, 66, 66, 66, 66, 66, 62, 65, 66, 63, 63, 66, 65, 62, 66, 64, - 67, 60, 67, 62, 62, 11, 0, 32, 63, 65, 90, 89, 96, 96, 96, 87, - 82, 86, 89, 90, 86, 86, 87, 86, 87, 91, 90, 87, 88, 93, 91, 90, - 89, 87, 86, 86, 86, 86, 91, 94, 93, 89, 89, 92, 92, 89, 91, 92, - 92, 92, 92, 91, 90, 89, 89, 98, 97, 27, 26, 25, 24, 25, 27, 30, - 31, 28, 27, 26, 27, 29, 30, 29, 26, 28, 26, 27, 27, 28, 29, 32, - 32, 30, 31, 33, 34, 34, 33, 35, 34, 40, 37, 37, 40, 40, 37, 37, - 40, 41, 40, 40, 40, 40, 41, 42, 43, 39, 40, 40, 41, 43, 45, 47, - 48, 41, 42, 43, 44, 45, 46, 46, 46, 46, 45, 45, 45, 45, 46, 47, - 48, 46, 47, 48, 48, 48, 47, 46, 43, 46, 44, 44, 45, 47, 48, 48, - 48, 51, 51, 53, 53, 54, 54, 54, 54, 58, 57, 56, 56, 58, 59, 57, - 56, 62, 56, 60, 61, 56, 58, 63, 58, 59, 59, 59, 60, 60, 61, 61, - 61, 62, 63, 63, 63, 63, 63, 63, 63, 61, 61, 62, 63, 63, 62, 61, - 61, 66, 66, 66, 66, 66, 66, 66, 66, 63, 66, 65, 62, 62, 65, 66, - 63, 66, 64, 67, 59, 67, 63, 62, 9, 0, 33, 63, 66, 90, 89, 96, - 96, 96, 87, 82, 86, 89, 90, 86, 86, 87, 86, 87, 91, 90, 87, 89, - 94, 92, 91, 90, 88, 88, 87, 87, 87, 90, 93, 93, 90, 90, 92, 91, - 88, 92, 92, 92, 91, 91, 90, 90, 90, 91, 98, 94, 27, 26, 25, 24, - 25, 27, 30, 32, 28, 27, 26, 27, 29, 30, 29, 28, 28, 26, 27, 28, - 29, 29, 32, 33, 30, 31, 33, 34, 34, 33, 33, 34, 39, 38, 38, 41, - 41, 38, 38, 41, 41, 40, 40, 40, 40, 41, 42, 43, 44, 43, 42, 41, - 41, 43, 44, 45, 40, 41, 43, 45, 46, 46, 45, 45, 46, 45, 45, 45, - 45, 46, 47, 48, 44, 45, 47, 48, 49, 49, 48, 47, 46, 44, 44, 45, - 47, 48, 48, 48, 52, 52, 54, 54, 54, 55, 55, 55, 57, 56, 55, 55, - 57, 57, 56, 55, 63, 57, 61, 62, 56, 59, 64, 57, 57, 57, 57, 58, - 58, 59, 59, 59, 62, 64, 63, 63, 63, 63, 63, 62, 63, 63, 65, 66, - 66, 65, 63, 63, 66, 66, 66, 66, 66, 66, 68, 66, 64, 66, 65, 61, - 61, 65, 66, 64, 64, 63, 66, 58, 69, 67, 65, 9, 0, 33, 64, 64, - 90, 87, 96, 94, 96, 86, 82, 86, 89, 90, 88, 88, 87, 86, 88, 91, - 90, 88, 89, 94, 92, 91, 90, 89, 89, 89, 90, 90, 89, 93, 94, 91, - 91, 93, 91, 87, 93, 92, 91, 90, 90, 90, 91, 91, 93, 95, 90, 27, - 27, 27, 28, 28, 29, 29, 29, 30, 29, 29, 29, 29, 30, 31, 30, 27, - 27, 27, 28, 28, 29, 29, 29, 31, 31, 31, 32, 32, 33, 33, 35, 35, - 36, 37, 38, 38, 38, 38, 37, 36, 37, 39, 39, 37, 37, 39, 42, 42, - 43, 43, 44, 44, 45, 45, 45, 47, 47, 47, 46, 46, 45, 45, 45, 44, - 51, 48, 45, 49, 46, 43, 50, 45, 49, 48, 44, 44, 51, 53, 50, 47, - 48, 48, 49, 49, 48, 50, 49, 50, 58, 56, 52, 57, 54, 51, 59, 49, - 54, 55, 53, 54, 58, 54, 46, 62, 58, 57, 59, 59, 56, 56, 59, 57, - 54, 55, 55, 56, 57, 58, 58, 57, 59, 60, 60, 63, 62, 62, 62, 61, - 63, 64, 64, 64, 64, 65, 66, 66, 67, 67, 66, 65, 66, 70, 71, 61, - 64, 66, 65, 62, 60, 63, 65, 68, 60, 68, 63, 66, 63, 66, 7, 1, - 38, 59, 68, 82, 89, 90, 91, 95, 83, 79, 86, 93, 90, 88, 91, 90, - 86, 86, 89, 90, 87, 87, 91, 88, 90, 92, 91, 89, 88, 90, 92, 90, - 94, 94, 91, 90, 92, 91, 87, 93, 92, 91, 90, 90, 90, 90, 91, 89, - 88, 91, 27, 27, 28, 28, 28, 29, 29, 29, 31, 31, 30, 30, 31, 32, - 33, 31, 29, 27, 28, 28, 28, 29, 29, 29, 31, 31, 31, 32, 32, 33, - 33, 33, 36, 36, 36, 37, 37, 38, 38, 38, 36, 38, 39, 39, 38, 37, - 39, 40, 43, 43, 43, 44, 44, 45, 45, 45, 47, 47, 47, 46, 46, 45, - 45, 45, 44, 51, 48, 45, 49, 46, 43, 50, 45, 48, 48, 45, 46, 51, - 52, 49, 48, 48, 48, 48, 48, 48, 50, 50, 44, 52, 51, 49, 55, 52, - 50, 58, 50, 52, 52, 49, 51, 55, 54, 49, 57, 53, 52, 54, 53, 49, - 49, 51, 52, 50, 53, 54, 55, 54, 55, 53, 59, 59, 61, 61, 64, 64, - 64, 65, 60, 61, 62, 61, 61, 61, 62, 64, 66, 67, 67, 66, 67, 68, - 70, 71, 64, 65, 67, 66, 63, 61, 64, 65, 70, 63, 72, 66, 66, 62, - 65, 6, 2, 37, 59, 66, 82, 89, 88, 91, 92, 81, 78, 85, 92, 89, - 89, 90, 90, 86, 86, 89, 90, 87, 87, 91, 88, 90, 92, 91, 89, 88, - 90, 92, 89, 93, 93, 90, 90, 92, 92, 88, 93, 92, 91, 90, 90, 90, - 90, 91, 89, 90, 90, 27, 28, 28, 28, 29, 29, 29, 29, 32, 32, 32, - 32, 32, 33, 34, 32, 29, 28, 28, 28, 29, 29, 29, 29, 31, 31, 31, - 32, 32, 33, 33, 33, 37, 37, 36, 35, 36, 37, 39, 40, 36, 38, 39, - 39, 38, 38, 39, 41, 43, 43, 43, 44, 44, 45, 45, 45, 47, 47, 46, - 46, 46, 46, 45, 45, 44, 51, 48, 45, 49, 46, 43, 50, 45, 48, 49, - 47, 48, 51, 51, 48, 50, 47, 47, 46, 46, 47, 51, 52, 47, 54, 53, - 50, 55, 53, 50, 57, 58, 58, 56, 54, 56, 61, 61, 59, 62, 59, 58, - 60, 60, 57, 58, 60, 50, 50, 53, 54, 54, 53, 54, 53, 60, 60, 60, - 59, 61, 61, 62, 62, 62, 62, 63, 62, 61, 62, 67, 69, 64, 65, 67, - 67, 68, 68, 70, 70, 66, 66, 67, 67, 65, 63, 66, 66, 73, 65, 74, - 68, 67, 62, 64, 4, 2, 37, 59, 67, 82, 89, 88, 91, 90, 79, 77, - 84, 92, 89, 88, 90, 90, 86, 86, 89, 90, 87, 87, 91, 89, 90, 91, - 91, 89, 89, 90, 91, 88, 92, 92, 90, 90, 93, 93, 89, 93, 92, 91, - 90, 90, 90, 90, 91, 91, 91, 91, 28, 28, 28, 29, 29, 29, 30, 30, - 32, 32, 32, 31, 32, 33, 34, 34, 30, 28, 28, 29, 29, 29, 30, 30, - 31, 31, 31, 32, 32, 33, 33, 35, 38, 37, 35, 34, 35, 37, 39, 41, - 37, 38, 40, 39, 38, 38, 39, 41, 43, 43, 43, 44, 44, 45, 45, 45, - 46, 46, 46, 46, 46, 46, 46, 46, 44, 51, 48, 45, 49, 46, 43, 50, - 45, 47, 49, 50, 50, 51, 50, 46, 51, 47, 47, 45, 45, 47, 51, 53, - 52, 58, 55, 52, 57, 54, 50, 55, 51, 50, 49, 49, 52, 54, 54, 53, - 56, 53, 53, 56, 57, 56, 57, 60, 54, 53, 55, 55, 54, 54, 57, 58, - 61, 60, 60, 59, 61, 61, 62, 60, 61, 62, 62, 62, 61, 63, 69, 72, - 63, 65, 68, 67, 68, 68, 70, 70, 65, 66, 67, 67, 66, 66, 67, 67, - 72, 65, 74, 68, 67, 63, 65, 4, 3, 38, 60, 67, 82, 89, 88, 91, - 89, 78, 76, 84, 91, 88, 88, 90, 90, 86, 86, 89, 90, 87, 87, 91, - 90, 90, 90, 90, 90, 90, 90, 90, 87, 91, 92, 90, 91, 94, 94, 90, - 93, 92, 91, 90, 90, 90, 90, 91, 91, 91, 90, 28, 28, 29, 29, 29, - 30, 30, 30, 31, 31, 31, 31, 31, 32, 33, 33, 30, 30, 31, 31, 31, - 32, 32, 32, 33, 33, 33, 34, 34, 35, 35, 35, 38, 37, 35, 34, 35, - 37, 39, 41, 37, 39, 40, 40, 39, 38, 40, 41, 43, 43, 43, 44, 44, - 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 46, 44, 51, 48, 45, 49, - 46, 43, 50, 47, 47, 49, 51, 52, 50, 49, 47, 51, 47, 45, 43, 45, - 47, 49, 51, 51, 55, 51, 49, 56, 54, 49, 54, 53, 53, 54, 57, 59, - 58, 55, 54, 58, 54, 53, 56, 56, 53, 53, 56, 53, 51, 50, 48, 48, - 49, 53, 56, 53, 54, 55, 57, 59, 61, 62, 63, 61, 61, 61, 59, 59, - 59, 62, 64, 62, 64, 68, 68, 67, 66, 67, 69, 66, 66, 66, 67, 67, - 67, 68, 67, 69, 62, 73, 68, 68, 64, 65, 5, 4, 39, 61, 68, 83, - 89, 88, 91, 89, 78, 76, 83, 91, 89, 88, 90, 90, 86, 86, 89, 90, - 87, 87, 91, 90, 90, 90, 90, 90, 90, 90, 90, 87, 91, 92, 90, 91, - 94, 94, 90, 93, 92, 91, 90, 90, 90, 90, 91, 89, 89, 89, 29, 29, - 29, 29, 30, 30, 30, 31, 31, 31, 30, 30, 31, 32, 33, 33, 31, 31, - 31, 31, 32, 32, 32, 33, 33, 33, 33, 34, 34, 35, 35, 35, 37, 37, - 36, 35, 36, 37, 39, 40, 37, 39, 40, 40, 39, 39, 40, 42, 42, 43, - 43, 44, 44, 45, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 44, 51, - 48, 45, 49, 46, 43, 50, 50, 48, 48, 52, 52, 49, 48, 48, 48, 47, - 45, 44, 46, 47, 49, 50, 51, 55, 50, 48, 57, 56, 51, 55, 52, 50, - 52, 57, 58, 54, 51, 50, 52, 48, 46, 47, 45, 40, 39, 41, 34, 33, - 32, 29, 28, 29, 33, 38, 33, 35, 39, 43, 47, 50, 52, 53, 62, 63, - 64, 63, 61, 60, 60, 61, 62, 64, 68, 68, 67, 67, 67, 68, 66, 65, - 65, 66, 68, 68, 69, 67, 67, 61, 72, 68, 68, 63, 64, 4, 5, 40, - 62, 68, 83, 89, 88, 91, 89, 78, 76, 84, 92, 90, 89, 92, 90, 86, - 86, 89, 90, 87, 87, 91, 91, 90, 89, 89, 91, 91, 90, 89, 88, 92, - 92, 90, 90, 93, 93, 89, 93, 92, 91, 90, 90, 90, 90, 91, 89, 88, - 88, 29, 29, 29, 30, 30, 30, 31, 31, 32, 32, 32, 32, 32, 33, 34, - 35, 31, 31, 31, 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, 35, 35, - 35, 36, 36, 36, 37, 37, 38, 38, 38, 38, 39, 41, 40, 39, 39, 40, - 42, 42, 42, 42, 43, 43, 44, 44, 44, 44, 44, 44, 45, 45, 46, 46, - 46, 44, 51, 48, 45, 49, 46, 43, 50, 53, 48, 48, 51, 51, 48, 48, - 50, 46, 44, 46, 46, 46, 46, 48, 48, 49, 52, 47, 43, 50, 47, 40, - 42, 29, 24, 23, 28, 29, 24, 21, 23, 27, 23, 21, 23, 21, 18, 17, - 20, 17, 21, 24, 23, 19, 17, 22, 25, 20, 23, 27, 30, 33, 33, 32, - 31, 49, 53, 57, 60, 60, 60, 62, 63, 59, 62, 66, 67, 68, 67, 67, - 68, 65, 64, 63, 65, 68, 68, 69, 66, 67, 61, 72, 67, 67, 61, 61, - 0, 6, 40, 62, 69, 83, 90, 87, 91, 89, 79, 77, 85, 93, 91, 91, - 93, 90, 86, 86, 89, 90, 87, 87, 91, 92, 90, 88, 89, 91, 92, 90, - 88, 89, 93, 93, 90, 90, 92, 92, 88, 93, 92, 91, 90, 90, 90, 90, - 91, 93, 92, 91, 29, 29, 29, 30, 30, 31, 31, 31, 34, 34, 33, 33, - 33, 34, 35, 36, 31, 31, 31, 32, 32, 33, 33, 33, 33, 33, 33, 34, - 34, 35, 35, 35, 35, 36, 37, 38, 38, 38, 38, 37, 38, 39, 41, 41, - 39, 39, 41, 42, 42, 42, 42, 43, 43, 44, 44, 44, 44, 44, 44, 45, - 45, 46, 46, 46, 44, 51, 48, 45, 49, 46, 43, 50, 54, 49, 47, 51, - 50, 47, 48, 52, 45, 44, 46, 47, 47, 46, 48, 47, 45, 46, 38, 32, - 35, 29, 20, 20, 27, 19, 16, 20, 20, 16, 15, 18, 26, 23, 23, 27, - 28, 26, 28, 31, 18, 24, 30, 31, 27, 23, 25, 26, 25, 27, 29, 30, - 29, 25, 21, 18, 26, 32, 41, 48, 53, 56, 60, 62, 59, 62, 66, 67, - 68, 67, 67, 68, 65, 63, 62, 64, 67, 68, 68, 65, 69, 62, 73, 67, - 65, 59, 58, 0, 6, 41, 62, 69, 83, 90, 87, 91, 90, 79, 77, 85, - 94, 92, 92, 94, 90, 86, 86, 89, 90, 87, 87, 91, 92, 90, 88, 89, - 91, 92, 90, 88, 90, 94, 94, 91, 90, 92, 91, 87, 93, 92, 91, 90, - 90, 90, 90, 91, 95, 94, 92, 30, 32, 33, 32, 30, 29, 30, 32, 30, - 31, 33, 35, 35, 35, 34, 33, 32, 31, 29, 29, 30, 32, 35, 37, 38, - 37, 36, 34, 34, 35, 36, 37, 40, 38, 36, 37, 41, 42, 40, 38, 38, - 39, 41, 41, 39, 39, 41, 42, 42, 43, 43, 44, 44, 43, 43, 42, 38, - 41, 44, 44, 41, 40, 41, 44, 49, 48, 48, 48, 48, 49, 50, 51, 44, - 48, 51, 50, 46, 44, 45, 45, 43, 37, 41, 42, 32, 32, 37, 32, 20, - 20, 13, 12, 20, 15, 12, 21, 20, 16, 20, 21, 16, 23, 27, 17, 33, - 30, 28, 30, 29, 25, 25, 28, 22, 33, 31, 38, 31, 21, 37, 42, 42, - 35, 37, 19, 32, 20, 26, 14, 18, 24, 24, 19, 29, 50, 64, 66, 62, - 68, 63, 59, 65, 64, 63, 71, 64, 64, 65, 66, 66, 67, 70, 70, 70, - 64, 73, 65, 66, 65, 65, 1, 5, 46, 59, 72, 87, 86, 92, 89, 91, - 74, 76, 88, 91, 92, 96, 92, 89, 90, 83, 92, 92, 83, 90, 87, 89, - 89, 90, 90, 90, 89, 88, 88, 91, 92, 92, 93, 93, 92, 92, 91, 93, - 92, 92, 91, 91, 92, 92, 93, 88, 90, 91, 27, 29, 30, 29, 27, 27, - 28, 29, 32, 33, 33, 33, 33, 32, 32, 31, 34, 33, 32, 32, 33, 35, - 37, 38, 37, 36, 36, 35, 35, 36, 36, 37, 40, 38, 36, 38, 40, 42, - 40, 38, 38, 39, 41, 41, 39, 39, 41, 42, 42, 42, 43, 43, 43, 43, - 42, 42, 44, 46, 47, 46, 43, 42, 43, 45, 47, 47, 47, 47, 47, 47, - 47, 47, 44, 46, 50, 51, 50, 48, 47, 45, 45, 32, 27, 22, 11, 11, - 18, 13, 12, 17, 16, 18, 26, 22, 20, 31, 23, 20, 24, 24, 19, 25, - 28, 19, 37, 33, 32, 34, 33, 30, 30, 33, 26, 31, 23, 32, 31, 23, - 35, 35, 29, 26, 30, 16, 28, 21, 28, 20, 20, 20, 20, 21, 25, 30, - 43, 54, 69, 70, 62, 60, 71, 71, 65, 68, 67, 66, 66, 66, 66, 66, - 68, 68, 71, 66, 75, 67, 66, 63, 62, 0, 6, 46, 60, 72, 87, 86, - 92, 89, 91, 74, 77, 88, 91, 92, 96, 92, 89, 90, 83, 92, 92, 83, - 90, 87, 88, 89, 89, 90, 90, 89, 89, 88, 91, 92, 92, 93, 93, 92, - 92, 91, 93, 92, 92, 91, 91, 92, 92, 93, 89, 91, 92, 27, 28, 29, - 29, 27, 27, 28, 30, 34, 33, 32, 31, 30, 30, 30, 30, 35, 35, 35, - 36, 37, 38, 38, 39, 37, 38, 38, 39, 39, 38, 38, 38, 39, 38, 37, - 38, 40, 41, 40, 39, 38, 39, 41, 41, 39, 39, 41, 42, 41, 41, 42, - 42, 42, 42, 41, 41, 47, 47, 47, 46, 43, 43, 44, 45, 45, 46, 47, - 48, 48, 48, 48, 48, 51, 50, 48, 47, 44, 39, 33, 27, 29, 15, 11, - 10, 6, 10, 15, 9, 6, 14, 17, 21, 27, 22, 21, 32, 24, 21, 25, - 24, 18, 23, 27, 19, 29, 25, 25, 27, 27, 24, 25, 28, 29, 28, 15, - 25, 29, 23, 30, 26, 17, 19, 25, 14, 20, 16, 24, 20, 23, 16, 18, - 24, 20, 13, 23, 39, 58, 65, 65, 64, 69, 66, 64, 71, 69, 68, 68, - 67, 66, 65, 67, 66, 71, 67, 77, 69, 67, 63, 59, 0, 7, 47, 60, - 72, 86, 86, 92, 89, 90, 75, 78, 89, 91, 91, 95, 91, 89, 90, 83, - 92, 92, 83, 90, 87, 88, 88, 89, 90, 90, 89, 89, 88, 91, 92, 92, - 93, 93, 92, 92, 91, 93, 92, 92, 91, 91, 92, 92, 93, 92, 94, 95, - 30, 31, 33, 32, 31, 31, 32, 34, 33, 32, 30, 29, 29, 30, 31, 32, - 32, 33, 34, 35, 36, 36, 35, 35, 36, 37, 38, 40, 40, 39, 38, 37, - 38, 38, 38, 39, 39, 40, 40, 40, 38, 39, 41, 41, 39, 39, 41, 42, - 40, 41, 41, 42, 42, 41, 41, 40, 44, 44, 43, 42, 42, 42, 43, 44, - 47, 47, 49, 50, 50, 49, 48, 48, 47, 42, 36, 32, 29, 25, 19, 12, - 15, 5, 8, 15, 17, 21, 21, 10, 12, 15, 13, 15, 23, 19, 15, 24, - 21, 19, 23, 22, 14, 18, 23, 15, 18, 15, 14, 17, 17, 15, 16, 19, - 27, 25, 11, 20, 24, 18, 25, 20, 17, 21, 24, 17, 14, 14, 18, 18, - 26, 20, 21, 24, 22, 17, 21, 27, 32, 52, 65, 65, 63, 57, 61, 76, - 68, 68, 67, 67, 67, 66, 68, 68, 69, 66, 77, 70, 69, 63, 58, 0, - 8, 48, 60, 72, 86, 86, 92, 90, 90, 75, 79, 90, 91, 90, 94, 91, - 89, 90, 83, 92, 92, 83, 90, 87, 87, 88, 89, 90, 90, 90, 89, 89, - 91, 92, 92, 93, 93, 92, 92, 91, 93, 92, 92, 91, 91, 92, 92, 93, - 93, 95, 95, 30, 32, 34, 33, 32, 32, 34, 35, 30, 29, 29, 29, 30, - 32, 34, 35, 33, 34, 35, 36, 36, 36, 35, 35, 35, 36, 38, 39, 40, - 39, 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 38, 39, 41, 41, 39, - 39, 41, 42, 38, 39, 39, 40, 40, 39, 39, 38, 40, 40, 39, 40, 41, - 42, 42, 44, 49, 49, 47, 45, 43, 40, 38, 37, 29, 23, 17, 16, 18, - 20, 20, 17, 21, 11, 13, 18, 15, 17, 17, 5, 21, 16, 6, 7, 20, - 19, 14, 19, 17, 16, 21, 19, 10, 14, 19, 13, 15, 12, 12, 14, 15, - 12, 13, 19, 21, 26, 16, 23, 20, 11, 21, 20, 19, 25, 22, 19, 13, - 17, 15, 16, 23, 25, 22, 18, 24, 31, 28, 19, 18, 36, 47, 54, 62, - 61, 61, 71, 66, 66, 67, 67, 67, 68, 70, 70, 67, 64, 76, 70, 69, - 63, 58, 0, 10, 49, 61, 72, 86, 86, 93, 90, 89, 76, 81, 91, 91, - 89, 93, 91, 89, 90, 83, 92, 92, 83, 90, 87, 87, 88, 89, 90, 90, - 90, 90, 90, 91, 92, 92, 93, 93, 92, 92, 91, 93, 92, 92, 91, 91, - 92, 92, 93, 93, 95, 95, 28, 29, 31, 31, 30, 30, 32, 34, 28, 28, - 29, 30, 32, 34, 35, 36, 38, 38, 38, 38, 38, 38, 38, 38, 35, 36, - 37, 38, 39, 39, 39, 39, 37, 38, 40, 40, 38, 38, 40, 41, 38, 39, - 41, 41, 39, 39, 41, 42, 39, 39, 40, 40, 40, 40, 39, 39, 41, 41, - 41, 42, 44, 44, 43, 41, 46, 43, 39, 34, 29, 25, 22, 21, 22, 19, - 14, 13, 14, 18, 20, 20, 30, 18, 17, 17, 13, 17, 23, 16, 23, 18, - 6, 6, 20, 21, 17, 24, 17, 18, 24, 22, 12, 16, 22, 17, 18, 15, - 14, 16, 16, 13, 14, 19, 19, 27, 21, 28, 22, 11, 22, 23, 19, 26, - 19, 23, 14, 25, 19, 21, 18, 25, 24, 18, 25, 36, 33, 20, 25, 27, - 25, 36, 62, 71, 64, 63, 65, 66, 66, 67, 68, 69, 71, 72, 67, 64, - 76, 69, 68, 63, 58, 0, 11, 50, 61, 72, 85, 86, 93, 91, 88, 76, - 82, 93, 91, 88, 92, 90, 89, 90, 83, 92, 92, 83, 90, 87, 86, 87, - 88, 89, 90, 90, 90, 90, 91, 92, 92, 93, 93, 92, 92, 91, 93, 92, - 92, 91, 91, 92, 92, 93, 92, 94, 95, 25, 27, 29, 29, 28, 29, 30, - 32, 29, 30, 31, 33, 34, 34, 34, 34, 40, 39, 37, 37, 36, 37, 38, - 39, 36, 36, 36, 37, 38, 39, 40, 41, 36, 39, 40, 40, 38, 38, 39, - 42, 38, 39, 41, 41, 39, 39, 41, 42, 40, 40, 41, 41, 41, 41, 40, - 40, 42, 41, 41, 43, 44, 43, 38, 34, 33, 30, 25, 20, 16, 15, 15, - 15, 20, 21, 21, 19, 18, 19, 21, 20, 26, 18, 20, 22, 17, 22, 31, - 27, 16, 17, 13, 12, 18, 15, 17, 28, 17, 19, 26, 24, 14, 18, 25, - 20, 22, 19, 18, 19, 19, 16, 16, 21, 22, 31, 26, 35, 29, 18, 27, - 27, 22, 28, 17, 25, 16, 31, 21, 22, 20, 24, 27, 26, 25, 26, 30, - 30, 32, 28, 18, 24, 49, 61, 61, 64, 67, 68, 68, 68, 68, 68, 70, - 70, 70, 66, 77, 68, 67, 61, 56, 0, 12, 51, 62, 72, 85, 86, 93, - 91, 87, 76, 83, 93, 91, 88, 92, 90, 89, 90, 83, 92, 92, 83, 90, - 87, 86, 87, 88, 89, 90, 91, 91, 90, 91, 92, 92, 93, 93, 92, 92, - 91, 93, 92, 92, 91, 91, 92, 92, 93, 91, 94, 95, 25, 27, 29, 29, - 29, 29, 31, 33, 31, 32, 33, 35, 35, 34, 33, 32, 37, 35, 33, 31, - 31, 33, 37, 38, 37, 37, 36, 37, 38, 40, 42, 43, 38, 39, 41, 40, - 38, 37, 39, 40, 38, 39, 41, 41, 39, 39, 41, 44, 44, 45, 43, 44, - 42, 41, 39, 38, 39, 39, 40, 42, 42, 40, 33, 28, 20, 18, 14, 12, - 11, 14, 17, 19, 8, 14, 20, 24, 24, 23, 28, 29, 19, 16, 24, 27, - 20, 19, 22, 16, 11, 18, 20, 17, 16, 8, 11, 26, 16, 15, 25, 23, - 14, 18, 26, 21, 30, 26, 24, 28, 27, 23, 23, 26, 25, 32, 26, 37, - 35, 25, 32, 29, 26, 30, 18, 28, 18, 35, 22, 22, 26, 26, 33, 38, - 30, 19, 25, 40, 30, 33, 25, 21, 30, 42, 55, 73, 72, 72, 71, 68, - 68, 67, 68, 68, 74, 69, 78, 68, 66, 60, 56, 0, 15, 54, 62, 74, - 85, 86, 95, 91, 89, 76, 84, 94, 91, 87, 91, 90, 89, 90, 83, 92, - 92, 83, 90, 87, 86, 87, 90, 91, 92, 93, 93, 93, 91, 92, 92, 93, - 93, 92, 92, 91, 93, 92, 92, 91, 91, 92, 92, 93, 90, 92, 94, 30, - 30, 30, 30, 31, 32, 33, 33, 33, 33, 33, 32, 31, 33, 37, 38, 33, - 31, 31, 32, 34, 35, 37, 39, 35, 37, 38, 40, 41, 42, 45, 43, 43, - 42, 41, 41, 39, 38, 37, 35, 41, 40, 38, 37, 39, 40, 43, 45, 45, - 46, 45, 43, 42, 38, 36, 35, 44, 32, 37, 49, 43, 32, 24, 14, 19, - 16, 14, 15, 17, 16, 12, 8, 9, 13, 19, 22, 22, 23, 31, 34, 24, - 20, 26, 46, 18, 28, 29, 29, 20, 29, 17, 22, 26, 15, 22, 25, 13, - 24, 29, 19, 16, 23, 26, 18, 35, 30, 33, 35, 25, 24, 28, 23, 27, - 34, 30, 27, 33, 30, 26, 33, 38, 34, 30, 29, 31, 34, 36, 35, 22, - 31, 34, 29, 25, 25, 27, 25, 23, 26, 31, 31, 28, 30, 50, 69, 79, - 67, 62, 67, 74, 73, 67, 66, 71, 68, 69, 71, 62, 68, 57, 0, 20, - 57, 66, 79, 89, 88, 94, 88, 90, 71, 84, 90, 91, 96, 89, 93, 89, - 83, 90, 92, 87, 89, 94, 90, 92, 92, 95, 95, 95, 94, 93, 93, 91, - 92, 92, 92, 92, 91, 90, 89, 93, 93, 93, 92, 92, 91, 91, 91, 89, - 89, 92, 30, 30, 29, 28, 28, 28, 29, 29, 33, 33, 34, 33, 32, 33, - 36, 36, 31, 29, 29, 30, 32, 35, 37, 37, 37, 37, 40, 41, 44, 44, - 47, 45, 45, 42, 42, 40, 37, 37, 35, 36, 38, 38, 39, 38, 40, 41, - 44, 47, 52, 52, 51, 47, 44, 40, 38, 37, 35, 32, 38, 43, 31, 23, - 22, 15, 20, 16, 14, 15, 18, 19, 17, 15, 16, 16, 19, 22, 24, 26, - 27, 24, 23, 18, 28, 30, 25, 21, 32, 34, 22, 31, 20, 25, 28, 15, - 20, 22, 12, 18, 22, 19, 23, 30, 33, 29, 30, 26, 33, 34, 27, 29, - 34, 29, 27, 32, 30, 27, 33, 29, 28, 34, 34, 30, 26, 29, 32, 34, - 30, 28, 36, 36, 35, 31, 31, 32, 29, 22, 23, 26, 30, 32, 29, 30, - 42, 56, 69, 75, 76, 71, 69, 74, 73, 68, 70, 69, 71, 73, 66, 71, - 59, 0, 20, 58, 65, 79, 91, 89, 96, 91, 92, 73, 85, 91, 91, 95, - 87, 88, 89, 84, 90, 92, 87, 89, 94, 90, 91, 92, 92, 93, 94, 93, - 92, 91, 94, 93, 93, 93, 93, 92, 91, 90, 93, 93, 93, 92, 92, 91, - 91, 91, 89, 89, 90, 32, 31, 30, 29, 28, 28, 28, 28, 33, 34, 35, - 35, 33, 33, 34, 34, 31, 29, 31, 32, 34, 35, 37, 37, 38, 38, 40, - 41, 44, 44, 47, 45, 45, 41, 40, 37, 35, 36, 36, 37, 36, 37, 40, - 40, 42, 42, 44, 46, 55, 55, 52, 47, 44, 40, 38, 38, 34, 35, 40, - 34, 18, 14, 20, 16, 19, 15, 14, 15, 18, 21, 22, 22, 21, 19, 19, - 23, 26, 27, 23, 17, 22, 18, 26, 12, 30, 14, 30, 37, 19, 29, 20, - 26, 29, 16, 22, 23, 14, 13, 16, 20, 28, 32, 33, 32, 28, 24, 30, - 32, 27, 29, 35, 30, 27, 32, 28, 24, 30, 26, 24, 31, 28, 26, 24, - 29, 33, 32, 27, 22, 42, 38, 33, 30, 35, 35, 28, 16, 23, 25, 28, - 32, 31, 27, 32, 39, 49, 71, 80, 69, 61, 69, 71, 65, 70, 69, 72, - 75, 68, 72, 59, 0, 19, 58, 65, 79, 92, 90, 97, 92, 93, 74, 86, - 91, 91, 94, 86, 87, 90, 84, 90, 93, 86, 87, 94, 90, 91, 91, 92, - 93, 94, 93, 93, 91, 95, 94, 94, 94, 94, 93, 92, 91, 93, 93, 93, - 92, 92, 91, 91, 91, 89, 89, 90, 33, 33, 32, 31, 31, 31, 32, 32, - 32, 34, 36, 36, 34, 33, 33, 32, 31, 29, 31, 32, 34, 35, 37, 37, - 37, 39, 41, 42, 44, 45, 47, 45, 45, 41, 39, 36, 34, 36, 36, 38, - 35, 36, 40, 41, 44, 43, 45, 46, 53, 52, 49, 45, 42, 39, 38, 38, - 38, 39, 38, 22, 7, 14, 25, 20, 19, 16, 15, 15, 18, 21, 23, 25, - 20, 20, 21, 24, 25, 24, 20, 14, 20, 23, 20, 10, 29, 16, 22, 36, - 17, 28, 20, 27, 32, 19, 23, 26, 20, 13, 12, 20, 27, 27, 26, 28, - 31, 26, 32, 32, 24, 28, 34, 28, 24, 29, 25, 21, 26, 22, 20, 27, - 23, 27, 29, 30, 31, 30, 31, 30, 39, 34, 29, 26, 30, 29, 23, 16, - 24, 23, 25, 29, 30, 28, 27, 30, 33, 56, 72, 67, 63, 67, 68, 65, - 70, 69, 72, 76, 67, 72, 58, 0, 19, 58, 65, 80, 92, 90, 98, 93, - 93, 73, 86, 91, 91, 94, 87, 88, 88, 85, 91, 93, 86, 87, 94, 89, - 93, 93, 94, 95, 96, 96, 95, 94, 93, 93, 94, 94, 93, 92, 91, 91, - 93, 93, 93, 92, 92, 91, 91, 91, 90, 90, 90, 31, 31, 31, 31, 32, - 33, 35, 36, 32, 34, 36, 36, 34, 33, 33, 32, 31, 31, 31, 32, 34, - 35, 37, 37, 38, 39, 40, 40, 42, 43, 45, 45, 45, 41, 39, 36, 35, - 37, 37, 39, 35, 36, 40, 42, 44, 44, 46, 47, 48, 48, 46, 44, 43, - 40, 39, 40, 42, 33, 27, 11, 2, 14, 26, 20, 20, 18, 17, 16, 17, - 19, 21, 24, 14, 19, 24, 25, 22, 20, 19, 18, 17, 26, 12, 19, 20, - 21, 10, 28, 18, 29, 20, 27, 30, 17, 20, 23, 22, 15, 14, 19, 23, - 22, 23, 24, 29, 23, 29, 29, 21, 25, 32, 27, 20, 26, 23, 20, 23, - 19, 18, 24, 17, 25, 30, 29, 25, 25, 32, 38, 31, 29, 28, 26, 25, - 22, 21, 22, 26, 22, 21, 26, 29, 29, 27, 29, 31, 41, 57, 69, 73, - 68, 68, 69, 68, 69, 72, 76, 66, 71, 57, 0, 20, 59, 66, 80, 93, - 90, 98, 93, 90, 71, 84, 90, 91, 95, 89, 90, 89, 84, 92, 94, 86, - 87, 94, 89, 90, 91, 94, 95, 95, 95, 95, 95, 92, 92, 92, 92, 92, - 91, 90, 89, 93, 93, 93, 92, 92, 91, 91, 91, 90, 90, 91, 27, 27, - 28, 29, 30, 32, 34, 35, 33, 34, 35, 35, 33, 33, 34, 36, 33, 31, - 31, 32, 34, 35, 37, 37, 39, 39, 40, 41, 43, 43, 45, 43, 43, 41, - 40, 38, 37, 39, 38, 39, 36, 37, 40, 41, 44, 44, 47, 49, 49, 49, - 49, 47, 46, 44, 42, 40, 38, 22, 15, 7, 2, 14, 26, 18, 21, 19, - 19, 19, 18, 18, 20, 23, 14, 20, 25, 26, 21, 19, 20, 21, 17, 22, - 9, 24, 15, 22, 8, 20, 23, 32, 22, 26, 29, 15, 18, 21, 20, 19, - 18, 19, 21, 23, 26, 25, 25, 20, 26, 27, 20, 24, 34, 30, 20, 26, - 24, 20, 24, 21, 20, 27, 14, 21, 29, 27, 22, 22, 29, 36, 28, 27, - 30, 28, 24, 20, 24, 31, 28, 22, 20, 24, 29, 28, 29, 30, 28, 28, - 36, 56, 67, 67, 66, 68, 68, 67, 71, 73, 64, 68, 54, 0, 22, 60, - 67, 81, 93, 90, 97, 92, 89, 71, 84, 90, 92, 96, 90, 91, 90, 85, - 92, 94, 87, 87, 94, 89, 87, 88, 91, 92, 93, 93, 93, 93, 91, 91, - 92, 92, 91, 91, 90, 89, 93, 93, 93, 92, 92, 91, 91, 91, 91, 91, - 91, 29, 29, 29, 29, 30, 32, 33, 34, 33, 33, 34, 33, 32, 33, 36, - 38, 33, 33, 33, 34, 36, 37, 37, 37, 40, 40, 41, 41, 43, 43, 43, - 43, 42, 41, 42, 41, 40, 41, 39, 40, 37, 37, 39, 40, 43, 44, 48, - 49, 47, 49, 49, 49, 46, 42, 39, 35, 29, 12, 9, 12, 10, 15, 24, - 19, 20, 20, 22, 22, 21, 21, 22, 24, 22, 23, 25, 25, 23, 22, 22, - 20, 20, 11, 12, 20, 13, 14, 16, 15, 20, 29, 17, 22, 28, 16, 21, - 25, 19, 25, 25, 18, 17, 23, 26, 22, 25, 19, 23, 23, 18, 22, 30, - 28, 18, 25, 22, 19, 24, 21, 18, 25, 15, 18, 23, 24, 23, 22, 23, - 24, 29, 28, 30, 30, 25, 19, 23, 32, 25, 22, 22, 27, 30, 27, 26, - 30, 26, 27, 27, 36, 50, 63, 65, 63, 69, 67, 69, 71, 61, 65, 53, - 0, 24, 62, 69, 81, 93, 89, 96, 91, 91, 72, 85, 91, 91, 95, 88, - 89, 91, 85, 91, 93, 85, 85, 92, 87, 87, 88, 89, 90, 93, 93, 93, - 93, 92, 92, 93, 93, 92, 91, 91, 90, 93, 93, 93, 92, 92, 91, 91, - 91, 91, 91, 91, 33, 33, 32, 32, 32, 33, 34, 35, 33, 33, 33, 32, - 31, 33, 37, 40, 33, 33, 33, 34, 36, 37, 37, 37, 40, 40, 41, 41, - 43, 43, 43, 43, 42, 42, 43, 43, 42, 42, 40, 40, 38, 38, 39, 39, - 42, 44, 49, 50, 44, 46, 48, 48, 44, 40, 33, 30, 21, 8, 12, 22, - 21, 19, 24, 22, 18, 20, 24, 25, 23, 23, 25, 27, 30, 27, 24, 25, - 26, 26, 24, 18, 23, 1, 17, 13, 16, 7, 26, 14, 14, 23, 12, 19, - 28, 19, 28, 33, 16, 27, 29, 14, 12, 18, 23, 15, 29, 23, 24, 23, - 16, 19, 26, 23, 16, 21, 18, 16, 21, 19, 17, 24, 20, 19, 22, 26, - 29, 28, 21, 15, 31, 27, 26, 28, 23, 18, 21, 29, 24, 21, 25, 28, - 31, 26, 24, 27, 30, 35, 31, 24, 38, 64, 72, 64, 69, 67, 66, 69, - 58, 64, 52, 0, 25, 63, 69, 82, 93, 89, 95, 90, 93, 74, 86, 91, - 91, 94, 86, 87, 91, 86, 91, 93, 85, 85, 92, 87, 89, 90, 91, 92, - 95, 96, 96, 96, 93, 94, 94, 94, 94, 93, 92, 91, 93, 93, 93, 92, - 92, 91, 91, 91, 91, 91, 91, 27, 32, 33, 30, 29, 32, 33, 32, 34, - 34, 34, 35, 35, 36, 36, 36, 38, 37, 36, 35, 35, 35, 38, 38, 34, - 39, 42, 42, 44, 46, 45, 40, 43, 40, 40, 41, 40, 37, 35, 39, 38, - 36, 37, 37, 41, 42, 44, 43, 48, 50, 47, 41, 41, 42, 30, 12, 12, - 14, 14, 16, 19, 23, 25, 26, 25, 21, 19, 19, 22, 24, 23, 23, 24, - 30, 32, 26, 21, 22, 21, 15, 27, 16, 12, 14, 18, 17, 16, 16, 18, - 17, 20, 22, 22, 20, 24, 30, 30, 25, 31, 29, 21, 17, 24, 20, 27, - 23, 23, 26, 24, 20, 22, 28, 20, 25, 25, 19, 16, 19, 25, 27, 19, - 24, 26, 25, 26, 29, 26, 25, 31, 34, 20, 29, 31, 28, 33, 24, 18, - 26, 28, 24, 29, 24, 21, 31, 30, 28, 25, 24, 31, 41, 56, 65, 70, - 65, 63, 82, 58, 63, 38, 0, 26, 61, 68, 83, 94, 87, 94, 91, 90, - 76, 89, 91, 90, 96, 90, 89, 87, 87, 89, 88, 87, 85, 85, 86, 92, - 92, 93, 92, 92, 91, 90, 90, 93, 93, 93, 92, 92, 91, 91, 91, 92, - 92, 92, 92, 92, 92, 92, 92, 94, 93, 93, 27, 32, 33, 30, 29, 32, - 33, 32, 34, 34, 34, 35, 35, 36, 36, 36, 35, 35, 35, 35, 35, 36, - 40, 40, 36, 40, 42, 41, 42, 45, 45, 41, 44, 40, 40, 41, 40, 37, - 36, 39, 35, 36, 39, 41, 45, 45, 48, 47, 41, 45, 48, 45, 38, 29, - 16, 5, 14, 15, 16, 18, 21, 22, 24, 24, 23, 21, 20, 20, 21, 22, - 23, 24, 15, 22, 25, 23, 20, 24, 24, 19, 22, 15, 11, 14, 16, 15, - 14, 15, 22, 21, 20, 23, 23, 22, 26, 31, 31, 30, 36, 38, 28, 25, - 27, 20, 25, 21, 25, 27, 26, 21, 21, 26, 21, 24, 24, 22, 24, 28, - 28, 23, 23, 26, 27, 25, 25, 28, 25, 24, 32, 34, 23, 28, 32, 25, - 31, 21, 28, 34, 30, 29, 36, 32, 27, 33, 23, 26, 26, 26, 24, 31, - 43, 53, 73, 67, 63, 77, 58, 70, 41, 0, 26, 61, 68, 84, 95, 88, - 93, 91, 89, 75, 89, 91, 90, 96, 90, 90, 86, 86, 88, 88, 87, 86, - 86, 87, 90, 90, 92, 92, 92, 92, 92, 92, 93, 93, 93, 92, 92, 91, - 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 93, 93, 92, 28, 32, 34, - 30, 29, 32, 34, 32, 34, 34, 34, 35, 35, 36, 36, 36, 36, 36, 36, - 37, 38, 39, 41, 42, 38, 41, 41, 39, 40, 44, 44, 41, 44, 40, 40, - 42, 40, 37, 36, 39, 33, 36, 42, 44, 45, 44, 47, 47, 43, 40, 40, - 37, 28, 13, 5, 6, 15, 17, 16, 18, 20, 21, 23, 22, 20, 21, 23, - 22, 20, 20, 23, 26, 13, 19, 23, 23, 21, 24, 26, 22, 18, 14, 14, - 17, 17, 16, 16, 19, 24, 21, 19, 21, 23, 21, 23, 26, 31, 30, 39, - 43, 34, 31, 31, 21, 22, 21, 27, 29, 28, 24, 23, 26, 23, 24, 23, - 24, 30, 35, 32, 23, 27, 30, 29, 25, 22, 25, 26, 23, 31, 34, 22, - 27, 29, 24, 29, 20, 30, 31, 25, 25, 35, 34, 27, 28, 20, 27, 30, - 29, 22, 23, 31, 39, 67, 66, 65, 72, 57, 75, 39, 0, 26, 62, 69, - 85, 96, 88, 93, 90, 88, 73, 88, 90, 90, 96, 91, 91, 84, 85, 87, - 87, 86, 85, 87, 88, 86, 86, 89, 90, 90, 91, 94, 94, 93, 93, 92, - 92, 92, 92, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 91, 91, 92, - 28, 33, 34, 31, 30, 32, 34, 32, 34, 34, 34, 35, 35, 36, 36, 36, - 37, 36, 36, 37, 38, 39, 40, 41, 39, 42, 41, 38, 39, 43, 44, 42, - 44, 40, 41, 42, 40, 38, 36, 39, 35, 38, 42, 42, 42, 40, 44, 44, - 52, 39, 27, 21, 13, 3, 6, 16, 17, 19, 18, 20, 20, 21, 22, 21, - 18, 21, 25, 24, 20, 20, 23, 28, 21, 24, 27, 27, 24, 24, 24, 24, - 19, 16, 20, 23, 22, 18, 21, 25, 28, 24, 21, 23, 24, 22, 23, 25, - 30, 32, 41, 44, 38, 37, 37, 26, 23, 24, 27, 27, 27, 24, 27, 29, - 26, 29, 29, 28, 31, 35, 33, 26, 27, 27, 26, 22, 22, 24, 25, 25, - 29, 33, 23, 27, 29, 22, 29, 21, 23, 28, 23, 23, 31, 32, 26, 31, - 26, 28, 31, 28, 24, 24, 27, 32, 51, 60, 68, 67, 55, 73, 29, 0, - 26, 62, 70, 86, 97, 88, 93, 89, 86, 72, 87, 90, 90, 97, 91, 91, - 83, 85, 87, 87, 86, 86, 88, 89, 87, 87, 89, 90, 90, 91, 93, 93, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 90, 91, 91, 29, 33, 35, 31, 30, 33, 34, 33, 34, 34, 34, 35, 35, - 36, 36, 36, 39, 38, 38, 37, 37, 38, 38, 39, 40, 42, 40, 36, 37, - 41, 41, 41, 45, 41, 41, 43, 41, 38, 37, 40, 38, 39, 40, 40, 41, - 41, 46, 47, 51, 31, 17, 11, 9, 5, 12, 24, 18, 18, 21, 22, 23, - 23, 23, 22, 18, 21, 26, 25, 22, 21, 24, 29, 26, 27, 29, 30, 26, - 22, 22, 23, 22, 20, 23, 27, 25, 21, 24, 28, 33, 30, 27, 28, 28, - 25, 26, 28, 30, 32, 38, 39, 35, 40, 44, 33, 29, 28, 28, 24, 24, - 25, 30, 33, 31, 35, 35, 29, 27, 28, 32, 31, 25, 25, 24, 21, 22, - 25, 27, 25, 26, 31, 23, 28, 30, 23, 32, 25, 23, 32, 31, 28, 34, - 34, 33, 41, 33, 28, 26, 24, 26, 27, 28, 29, 34, 51, 70, 67, 56, - 71, 19, 0, 28, 63, 71, 86, 96, 88, 93, 89, 86, 72, 86, 89, 89, - 96, 91, 91, 82, 83, 85, 85, 86, 86, 87, 88, 89, 89, 91, 90, 90, - 89, 89, 89, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 90, 91, 91, 29, 33, 35, 32, 31, 33, 35, 33, 34, 34, - 34, 35, 35, 36, 36, 36, 40, 39, 38, 37, 37, 37, 37, 38, 39, 42, - 40, 38, 38, 41, 41, 38, 45, 41, 42, 43, 41, 39, 37, 40, 39, 37, - 38, 39, 44, 46, 48, 46, 33, 22, 15, 13, 15, 15, 18, 20, 17, 20, - 22, 24, 24, 25, 25, 23, 20, 22, 26, 27, 26, 25, 27, 29, 25, 25, - 27, 30, 26, 22, 22, 25, 25, 22, 22, 26, 27, 24, 23, 28, 31, 28, - 28, 28, 25, 21, 23, 30, 35, 33, 39, 35, 32, 42, 47, 36, 34, 33, - 32, 24, 24, 27, 32, 35, 34, 38, 38, 30, 26, 26, 31, 32, 23, 25, - 26, 21, 23, 27, 29, 27, 24, 31, 23, 30, 31, 25, 34, 27, 25, 35, - 34, 32, 36, 34, 36, 47, 35, 27, 20, 20, 23, 27, 27, 26, 27, 40, - 66, 66, 60, 71, 12, 0, 30, 65, 71, 85, 95, 87, 94, 91, 86, 72, - 86, 89, 89, 95, 90, 90, 83, 83, 85, 85, 86, 85, 86, 87, 90, 90, - 91, 90, 90, 89, 88, 88, 91, 91, 92, 92, 92, 92, 93, 93, 92, 92, - 92, 92, 92, 92, 92, 92, 91, 91, 92, 29, 34, 35, 32, 31, 34, 35, - 34, 34, 34, 34, 35, 35, 36, 36, 36, 38, 39, 38, 38, 37, 38, 39, - 39, 38, 42, 41, 39, 39, 41, 40, 36, 45, 41, 42, 43, 42, 39, 37, - 40, 40, 37, 37, 39, 45, 43, 39, 31, 10, 12, 15, 14, 14, 16, 19, - 19, 18, 19, 23, 25, 28, 29, 29, 27, 23, 23, 25, 28, 29, 30, 29, - 29, 27, 26, 28, 32, 29, 23, 23, 27, 34, 27, 23, 28, 30, 28, 27, - 29, 29, 30, 33, 32, 26, 21, 25, 36, 40, 39, 43, 37, 33, 42, 45, - 31, 34, 35, 34, 29, 27, 30, 34, 33, 33, 36, 36, 31, 30, 32, 33, - 29, 27, 28, 29, 26, 27, 30, 30, 27, 25, 32, 25, 30, 31, 23, 33, - 28, 30, 34, 30, 28, 34, 34, 33, 40, 33, 28, 23, 23, 23, 25, 23, - 23, 27, 29, 52, 57, 61, 71, 5, 0, 33, 66, 70, 84, 93, 87, 94, - 93, 87, 73, 87, 89, 88, 94, 88, 88, 85, 84, 86, 86, 86, 85, 85, - 86, 88, 88, 88, 88, 90, 90, 90, 90, 91, 91, 91, 92, 92, 93, 93, - 93, 92, 92, 92, 92, 92, 92, 92, 92, 93, 93, 92, 29, 32, 35, 30, - 31, 32, 35, 32, 34, 32, 34, 33, 35, 34, 36, 36, 36, 37, 37, 38, - 38, 39, 41, 42, 37, 42, 42, 40, 40, 41, 39, 35, 44, 42, 40, 41, - 42, 39, 37, 41, 41, 37, 36, 38, 43, 37, 24, 12, 1, 12, 19, 10, - 8, 15, 21, 23, 17, 20, 25, 28, 32, 33, 33, 31, 29, 25, 29, 30, - 36, 35, 34, 32, 37, 34, 36, 40, 36, 29, 28, 32, 44, 34, 30, 33, - 36, 35, 34, 33, 40, 42, 45, 44, 35, 30, 38, 49, 45, 44, 48, 41, - 36, 46, 45, 29, 34, 39, 40, 34, 33, 36, 37, 34, 32, 35, 32, 32, - 36, 40, 36, 29, 32, 36, 37, 32, 32, 32, 32, 28, 31, 38, 28, 34, - 31, 25, 34, 29, 37, 37, 29, 27, 35, 36, 30, 33, 29, 29, 31, 28, - 25, 21, 22, 24, 26, 20, 36, 46, 57, 70, 0, 0, 30, 64, 69, 81, - 90, 86, 94, 94, 88, 74, 87, 89, 88, 94, 87, 87, 87, 87, 89, 88, - 86, 85, 85, 86, 86, 88, 89, 90, 90, 93, 94, 94, 91, 91, 91, 92, - 92, 93, 93, 93, 92, 92, 92, 92, 92, 92, 92, 92, 94, 93, 93, 29, - 26, 28, 26, 29, 29, 33, 32, 35, 29, 29, 31, 34, 30, 30, 32, 36, - 42, 38, 36, 42, 40, 36, 42, 42, 45, 45, 42, 43, 46, 47, 42, 35, - 37, 40, 39, 38, 37, 39, 39, 43, 39, 37, 39, 36, 26, 15, 11, 16, - 19, 19, 15, 17, 18, 21, 23, 27, 25, 32, 34, 33, 40, 46, 38, 34, - 41, 42, 36, 44, 45, 43, 48, 47, 49, 48, 47, 48, 49, 42, 33, 62, - 40, 44, 53, 42, 40, 46, 39, 58, 47, 42, 46, 50, 49, 47, 51, 58, - 47, 42, 43, 49, 51, 49, 48, 55, 51, 45, 41, 44, 44, 43, 42, 42, - 44, 44, 41, 36, 35, 36, 40, 44, 42, 42, 34, 30, 43, 47, 31, 40, - 32, 39, 48, 34, 24, 26, 30, 37, 33, 30, 29, 30, 31, 31, 31, 37, - 32, 25, 21, 23, 23, 21, 19, 30, 22, 25, 34, 42, 44, 23, 0, 34, - 61, 74, 76, 85, 89, 85, 88, 92, 75, 89, 91, 89, 93, 87, 90, 88, - 87, 89, 89, 87, 89, 91, 92, 89, 91, 91, 92, 92, 95, 95, 95, 95, - 94, 92, 90, 89, 89, 89, 90, 92, 92, 92, 92, 92, 92, 92, 92, 94, - 94, 93, 32, 29, 29, 28, 29, 31, 32, 33, 33, 28, 27, 31, 32, 30, - 29, 32, 34, 42, 38, 36, 42, 40, 37, 42, 38, 41, 42, 39, 39, 43, - 43, 38, 40, 38, 39, 39, 38, 38, 40, 41, 37, 40, 40, 32, 16, 5, - 11, 25, 25, 26, 22, 20, 19, 21, 22, 25, 33, 28, 35, 41, 39, 42, - 47, 41, 55, 62, 57, 50, 56, 59, 61, 67, 55, 56, 56, 56, 59, 62, - 59, 52, 56, 42, 47, 55, 50, 56, 65, 59, 51, 51, 57, 67, 69, 65, - 63, 66, 65, 63, 64, 62, 60, 54, 59, 63, 58, 54, 55, 54, 59, 58, - 58, 56, 57, 59, 60, 57, 56, 56, 58, 61, 42, 42, 52, 54, 51, 55, - 52, 34, 52, 42, 46, 55, 45, 40, 43, 45, 37, 33, 32, 30, 30, 30, - 28, 26, 26, 27, 27, 30, 32, 30, 26, 23, 23, 24, 32, 32, 25, 30, - 32, 26, 38, 53, 63, 74, 87, 89, 85, 90, 87, 75, 93, 95, 91, 94, - 89, 93, 90, 89, 91, 91, 89, 89, 93, 94, 91, 91, 93, 94, 94, 95, - 96, 95, 97, 94, 92, 91, 90, 90, 90, 91, 92, 92, 92, 92, 92, 92, - 92, 92, 94, 93, 92, 33, 30, 30, 29, 29, 30, 31, 31, 33, 28, 27, - 31, 33, 30, 29, 33, 34, 42, 38, 36, 43, 41, 37, 42, 37, 40, 41, - 38, 38, 42, 42, 37, 43, 41, 40, 39, 39, 39, 40, 41, 40, 37, 31, - 19, 4, 0, 11, 30, 27, 25, 20, 17, 19, 20, 23, 25, 38, 29, 36, - 46, 47, 51, 64, 68, 67, 80, 85, 85, 90, 86, 77, 76, 79, 80, 80, - 80, 83, 87, 84, 78, 88, 80, 78, 73, 64, 69, 72, 63, 72, 78, 88, - 96, 97, 94, 96, 103, 104, 102, 104, 102, 98, 91, 93, 97, 112, 110, 109, - 106, 105, 98, 92, 87, 79, 81, 82, 81, 80, 78, 80, 81, 74, 67, 70, - 70, 65, 68, 71, 64, 62, 49, 50, 57, 50, 49, 53, 51, 41, 42, 46, - 48, 48, 43, 34, 28, 38, 36, 31, 27, 24, 24, 25, 24, 23, 25, 33, - 29, 17, 22, 37, 41, 41, 49, 55, 69, 86, 88, 84, 91, 81, 72, 94, - 96, 89, 93, 90, 93, 90, 89, 91, 91, 89, 89, 93, 94, 91, 91, 94, - 94, 94, 94, 96, 95, 97, 94, 93, 92, 91, 91, 91, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 93, 93, 92, 31, 28, 28, 28, 27, 27, 28, 28, - 33, 28, 27, 31, 33, 31, 30, 34, 35, 42, 39, 37, 43, 41, 37, 43, - 40, 43, 43, 41, 41, 45, 45, 42, 44, 39, 38, 35, 38, 38, 39, 40, - 45, 28, 12, 8, 10, 13, 17, 23, 24, 21, 18, 21, 24, 25, 26, 29, - 40, 30, 38, 55, 63, 76, 101, 116, 132, 149, 156, 158, 164, 159, 148, 146, - 148, 150, 150, 149, 150, 151, 145, 136, 142, 143, 141, 133, 130, 140, 144, 136, - 146, 148, 149, 149, 149, 152, 160, 168, 169, 163, 162, 163, 167, 160, 157, 153, - 158, 156, 160, 159, 161, 157, 156, 154, 156, 157, 157, 155, 152, 149, 148, 146, - 148, 134, 130, 130, 122, 121, 127, 127, 120, 104, 99, 100, 96, 94, 95, 91, - 98, 86, 67, 52, 45, 44, 48, 51, 49, 45, 42, 36, 30, 27, 26, 26, - 31, 24, 28, 29, 26, 29, 32, 25, 33, 46, 50, 55, 73, 82, 85, 91, - 81, 73, 89, 91, 87, 94, 90, 90, 90, 89, 91, 91, 89, 89, 93, 94, - 92, 92, 94, 94, 94, 94, 95, 94, 97, 94, 94, 93, 93, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 91, 30, 30, 30, 30, 30, - 30, 29, 29, 35, 30, 30, 34, 36, 34, 33, 35, 35, 43, 39, 37, 43, - 41, 38, 43, 41, 44, 45, 42, 43, 46, 46, 43, 45, 40, 40, 38, 42, - 41, 41, 40, 35, 18, 4, 7, 18, 22, 18, 15, 23, 23, 23, 29, 32, - 30, 32, 35, 42, 41, 57, 81, 95, 115, 140, 154, 157, 167, 160, 154, 161, - 167, 171, 179, 187, 190, 192, 192, 193, 191, 182, 172, 182, 190, 187, 178, 180, - 188, 190, 188, 191, 188, 183, 179, 181, 187, 194, 198, 190, 188, 192, 193, 192, - 184, 185, 187, 191, 188, 188, 184, 183, 179, 180, 180, 179, 177, 175, 174, 172, - 171, 168, 167, 180, 171, 178, 183, 172, 164, 162, 157, 175, 158, 151, 151, 147, - 147, 146, 139, 135, 129, 117, 104, 91, 78, 65, 55, 45, 46, 49, 51, 48, - 44, 39, 34, 36, 23, 24, 29, 27, 28, 27, 18, 21, 43, 45, 37, 50, - 69, 81, 88, 85, 72, 85, 85, 84, 95, 91, 88, 90, 89, 91, 91, 89, - 89, 93, 94, 92, 92, 94, 94, 94, 94, 95, 94, 96, 94, 94, 94, 93, - 93, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 91, 91, 90, 33, 31, - 32, 33, 33, 33, 32, 32, 34, 30, 30, 34, 36, 35, 34, 36, 38, 43, - 39, 37, 44, 42, 38, 44, 40, 43, 43, 40, 41, 44, 44, 42, 45, 43, - 42, 43, 45, 44, 39, 33, 13, 10, 12, 15, 20, 15, 13, 17, 20, 20, - 25, 31, 31, 27, 30, 40, 54, 66, 92, 117, 130, 145, 161, 165, 170, 178, - 172, 166, 174, 180, 184, 193, 180, 184, 187, 188, 191, 191, 183, 173, 191, 200, - 194, 186, 190, 189, 186, 191, 190, 191, 190, 187, 189, 194, 196, 194, 180, 191, - 202, 201, 187, 178, 187, 202, 204, 202, 198, 193, 189, 188, 190, 194, 192, 189, - 189, 186, 188, 190, 190, 189, 184, 178, 184, 182, 173, 171, 176, 171, 181, 169, - 167, 166, 163, 164, 166, 155, 150, 154, 161, 163, 154, 136, 115, 98, 71, 62, - 50, 42, 40, 40, 38, 35, 35, 26, 28, 29, 20, 20, 28, 29, 18, 37, - 38, 27, 36, 53, 66, 76, 80, 73, 87, 85, 83, 98, 92, 88, 88, 89, - 91, 91, 89, 89, 93, 94, 93, 93, 94, 94, 94, 94, 94, 93, 94, 92, - 93, 93, 93, 93, 92, 91, 92, 92, 92, 92, 92, 92, 92, 92, 90, 90, - 90, 31, 30, 32, 33, 34, 34, 33, 32, 34, 30, 30, 34, 37, 35, 35, - 36, 38, 43, 40, 38, 44, 42, 38, 44, 39, 42, 42, 39, 40, 43, 44, - 41, 45, 43, 43, 44, 45, 39, 29, 20, 8, 12, 19, 22, 22, 13, 12, - 19, 15, 16, 23, 32, 33, 29, 41, 57, 80, 100, 125, 139, 147, 161, 171, - 162, 166, 179, 182, 181, 188, 188, 183, 186, 185, 187, 188, 189, 193, 196, 192, - 185, 185, 195, 193, 195, 206, 202, 199, 214, 198, 205, 208, 203, 200, 202, 203, - 200, 199, 205, 212, 212, 203, 197, 202, 213, 190, 192, 194, 196, 199, 204, 212, - 220, 201, 197, 195, 192, 195, 198, 200, 199, 200, 196, 196, 184, 174, 183, 196, - 190, 183, 176, 179, 179, 176, 180, 181, 170, 183, 174, 165, 157, 157, 162, 166, - 170, 133, 112, 85, 67, 58, 54, 48, 41, 37, 28, 31, 33, 22, 20, 29, - 33, 24, 28, 27, 30, 39, 37, 41, 59, 63, 65, 89, 87, 82, 92, 89, - 88, 88, 89, 91, 91, 89, 89, 93, 94, 93, 93, 95, 94, 94, 93, 94, - 93, 92, 91, 92, 93, 93, 92, 91, 90, 92, 92, 92, 92, 92, 92, 92, - 92, 90, 89, 89, 28, 27, 29, 31, 32, 32, 31, 31, 34, 30, 30, 34, - 37, 35, 35, 39, 38, 44, 40, 38, 44, 42, 38, 44, 40, 43, 43, 40, - 41, 44, 44, 42, 42, 41, 41, 42, 41, 33, 18, 7, 17, 15, 19, 25, - 27, 22, 17, 19, 18, 21, 29, 38, 41, 43, 60, 84, 106, 123, 144, 146, - 147, 165, 175, 163, 173, 182, 178, 173, 179, 182, 182, 188, 189, 189, 186, 185, - 189, 194, 193, 188, 198, 204, 198, 197, 204, 188, 179, 197, 198, 207, 210, 199, - 189, 189, 194, 197, 210, 198, 192, 197, 205, 204, 199, 195, 207, 207, 205, 199, - 193, 190, 191, 195, 209, 205, 199, 197, 197, 200, 202, 202, 193, 200, 206, 196, - 182, 189, 192, 177, 182, 179, 182, 185, 180, 183, 184, 172, 169, 167, 169, 170, - 170, 165, 159, 155, 171, 159, 144, 132, 121, 102, 74, 53, 46, 30, 31, 38, - 34, 30, 28, 22, 35, 20, 17, 35, 46, 26, 24, 47, 44, 56, 88, 87, - 76, 84, 83, 88, 88, 89, 91, 91, 89, 89, 93, 94, 93, 93, 95, 94, - 94, 93, 94, 93, 91, 90, 91, 92, 93, 92, 91, 90, 92, 92, 92, 92, - 92, 92, 92, 92, 89, 89, 89, 31, 35, 35, 32, 33, 36, 36, 34, 37, - 37, 38, 38, 38, 39, 39, 39, 43, 42, 41, 40, 39, 38, 38, 38, 44, - 42, 40, 39, 39, 41, 44, 45, 41, 42, 48, 42, 24, 17, 23, 22, 14, - 24, 32, 28, 23, 21, 16, 14, 17, 35, 44, 39, 43, 62, 94, 118, 138, - 144, 155, 163, 168, 172, 175, 177, 169, 169, 175, 182, 183, 180, 180, 184, 189, - 181, 176, 180, 191, 198, 198, 194, 195, 195, 195, 193, 191, 192, 195, 197, 196, - 197, 199, 201, 203, 204, 204, 202, 204, 198, 194, 198, 203, 203, 201, 199, 212, - 205, 212, 207, 188, 195, 209, 204, 200, 210, 213, 207, 202, 201, 197, 193, 195, - 203, 200, 187, 181, 188, 192, 190, 186, 176, 174, 176, 174, 182, 188, 181, 181, - 172, 165, 167, 176, 179, 172, 163, 161, 156, 154, 155, 156, 142, 120, 99, 68, - 49, 37, 38, 38, 28, 26, 33, 27, 28, 29, 27, 28, 30, 36, 41, 45, - 37, 45, 73, 86, 82, 78, 86, 92, 93, 90, 84, 84, 88, 93, 92, 92, - 93, 95, 94, 92, 92, 95, 96, 94, 93, 93, 93, 93, 92, 91, 90, 93, - 93, 93, 92, 92, 91, 91, 91, 92, 92, 92, 32, 35, 35, 32, 33, 36, - 37, 34, 35, 35, 35, 36, 36, 37, 37, 37, 40, 40, 39, 39, 39, 40, - 41, 42, 37, 41, 44, 45, 43, 42, 42, 42, 44, 36, 34, 27, 14, 12, - 16, 14, 19, 25, 25, 21, 22, 24, 22, 21, 29, 36, 45, 58, 79, 104, - 121, 128, 147, 154, 163, 170, 174, 178, 180, 180, 173, 168, 171, 179, 182, 180, - 180, 182, 180, 176, 174, 178, 186, 191, 189, 185, 192, 193, 194, 193, 191, 189, - 189, 190, 191, 192, 194, 196, 199, 201, 203, 204, 198, 198, 201, 203, 205, 203, - 203, 202, 205, 199, 208, 208, 199, 204, 212, 200, 203, 207, 206, 200, 198, 203, - 205, 201, 180, 196, 205, 199, 193, 190, 183, 173, 186, 178, 180, 174, 164, 164, - 174, 171, 184, 179, 176, 175, 176, 175, 168, 160, 159, 157, 152, 155, 158, 156, - 146, 133, 136, 98, 62, 49, 45, 40, 32, 27, 27, 23, 22, 29, 37, 38, - 33, 27, 38, 38, 45, 60, 75, 83, 83, 84, 84, 91, 92, 88, 85, 87, - 92, 92, 92, 93, 95, 94, 92, 92, 95, 96, 94, 93, 93, 93, 93, 92, - 91, 90, 93, 93, 93, 92, 92, 91, 91, 91, 92, 92, 92, 34, 37, 37, - 35, 35, 38, 39, 36, 37, 37, 38, 38, 38, 39, 39, 39, 37, 37, 38, - 39, 40, 42, 44, 45, 38, 42, 46, 46, 44, 42, 42, 44, 44, 29, 21, - 16, 11, 17, 22, 18, 28, 31, 29, 26, 27, 29, 28, 26, 33, 45, 59, - 82, 109, 132, 139, 136, 151, 158, 165, 172, 174, 176, 178, 178, 173, 168, 170, - 176, 180, 179, 179, 181, 176, 176, 178, 181, 184, 185, 184, 181, 187, 190, 192, - 192, 189, 186, 185, 184, 187, 188, 189, 192, 195, 199, 202, 203, 192, 196, 205, - 204, 202, 197, 198, 197, 212, 204, 207, 203, 199, 201, 205, 192, 206, 210, 212, - 213, 214, 213, 209, 203, 186, 193, 195, 188, 185, 188, 190, 188, 179, 178, 183, - 175, 160, 159, 174, 178, 171, 170, 173, 172, 172, 170, 166, 166, 168, 164, 161, - 160, 162, 159, 154, 147, 143, 143, 132, 105, 69, 43, 36, 39, 42, 32, 25, - 26, 30, 32, 30, 25, 31, 37, 42, 45, 58, 78, 84, 82, 80, 90, 94, - 91, 86, 87, 91, 92, 92, 93, 95, 94, 92, 92, 95, 96, 94, 93, 93, - 93, 93, 92, 91, 90, 93, 93, 93, 92, 92, 91, 91, 91, 92, 92, 92, - 34, 37, 38, 35, 35, 39, 39, 36, 40, 40, 40, 41, 41, 41, 42, 42, - 38, 38, 38, 39, 41, 43, 44, 45, 46, 45, 43, 42, 42, 43, 43, 41, - 32, 16, 13, 14, 12, 22, 32, 32, 31, 34, 36, 33, 32, 29, 28, 27, - 46, 69, 95, 111, 122, 134, 142, 146, 155, 161, 168, 172, 173, 175, 176, 175, - 174, 170, 172, 175, 174, 171, 174, 179, 178, 179, 181, 181, 181, 181, 181, 182, - 182, 184, 186, 186, 184, 183, 182, 183, 186, 186, 187, 189, 191, 195, 197, 199, - 193, 200, 204, 202, 198, 196, 195, 194, 218, 213, 207, 199, 195, 200, 205, 202, - 200, 199, 195, 194, 196, 197, 194, 189, 203, 201, 191, 176, 172, 181, 192, 197, - 182, 181, 186, 181, 165, 167, 181, 186, 171, 168, 168, 171, 173, 172, 171, 171, - 168, 168, 168, 169, 165, 159, 153, 146, 149, 148, 143, 133, 117, 97, 68, 45, - 39, 37, 34, 31, 27, 27, 29, 32, 27, 34, 40, 39, 44, 57, 72, 80, - 83, 90, 93, 90, 89, 90, 92, 89, 92, 93, 95, 94, 92, 92, 95, 96, - 94, 93, 93, 93, 93, 92, 91, 90, 93, 93, 93, 92, 92, 91, 91, 91, - 92, 92, 92, 35, 38, 38, 36, 36, 39, 40, 37, 40, 40, 41, 41, 42, - 42, 42, 42, 41, 40, 40, 40, 41, 42, 43, 43, 49, 44, 41, 42, 45, - 45, 38, 29, 12, 3, 8, 9, 9, 19, 30, 34, 26, 31, 33, 32, 30, - 29, 37, 47, 80, 103, 125, 135, 137, 142, 148, 154, 162, 166, 172, 175, 175, - 177, 177, 176, 174, 176, 180, 181, 173, 168, 172, 182, 181, 182, 181, 179, 177, - 177, 181, 184, 182, 183, 184, 183, 183, 184, 187, 190, 188, 188, 188, 188, 190, - 191, 192, 193, 199, 203, 203, 199, 199, 203, 203, 199, 205, 211, 208, 201, 201, - 207, 214, 221, 229, 219, 206, 201, 203, 207, 214, 218, 206, 205, 200, 191, 185, - 181, 179, 177, 194, 190, 191, 187, 174, 175, 183, 183, 190, 179, 172, 175, 177, - 175, 171, 171, 165, 166, 166, 167, 166, 163, 161, 159, 157, 151, 143, 136, 134, - 128, 112, 92, 42, 37, 34, 37, 40, 39, 35, 31, 27, 29, 34, 36, 33, - 35, 53, 74, 85, 90, 90, 88, 90, 93, 92, 87, 92, 93, 95, 94, 92, - 92, 95, 96, 94, 93, 93, 93, 93, 92, 91, 90, 93, 93, 93, 92, 92, - 91, 91, 91, 92, 92, 92, 35, 38, 39, 36, 36, 40, 40, 37, 38, 39, - 39, 39, 40, 40, 40, 41, 43, 42, 42, 41, 41, 41, 42, 42, 43, 41, - 42, 45, 46, 39, 25, 11, 5, 3, 11, 13, 9, 16, 27, 31, 29, 28, - 30, 34, 39, 51, 72, 89, 114, 123, 132, 139, 148, 156, 158, 153, 163, 167, - 171, 173, 175, 173, 175, 174, 176, 178, 186, 185, 180, 172, 178, 185, 184, 181, - 180, 176, 176, 175, 180, 181, 186, 184, 187, 184, 187, 187, 194, 196, 190, 189, - 191, 190, 191, 188, 189, 189, 195, 202, 202, 198, 201, 209, 211, 206, 195, 211, - 212, 207, 210, 208, 207, 215, 205, 201, 200, 203, 205, 201, 201, 203, 202, 200, - 200, 198, 195, 190, 186, 183, 193, 186, 190, 190, 183, 186, 191, 187, 190, 178, - 173, 179, 184, 181, 178, 177, 175, 169, 164, 161, 161, 164, 169, 173, 158, 161, - 162, 154, 142, 133, 132, 133, 92, 66, 41, 32, 39, 43, 38, 27, 30, 27, - 31, 33, 29, 26, 39, 58, 77, 85, 88, 89, 91, 93, 92, 87, 92, 93, - 95, 94, 92, 92, 95, 96, 94, 93, 93, 93, 93, 92, 91, 90, 93, 93, - 93, 92, 92, 91, 91, 91, 92, 92, 92, 35, 38, 39, 36, 37, 40, 40, - 37, 39, 39, 39, 40, 40, 40, 41, 41, 43, 42, 42, 41, 41, 42, 42, - 43, 40, 41, 42, 39, 33, 23, 14, 5, 11, 7, 15, 18, 12, 18, 28, - 31, 32, 29, 33, 48, 68, 88, 106, 124, 131, 134, 136, 141, 153, 162, 161, - 154, 161, 164, 168, 171, 173, 170, 173, 173, 176, 176, 182, 185, 188, 182, 184, - 186, 187, 183, 184, 181, 183, 181, 184, 182, 187, 187, 191, 189, 191, 190, 195, - 195, 192, 192, 196, 195, 196, 192, 191, 189, 193, 204, 208, 202, 201, 207, 209, - 205, 200, 216, 213, 207, 213, 209, 200, 206, 205, 207, 214, 222, 220, 209, 203, - 203, 205, 200, 197, 197, 198, 197, 199, 202, 190, 186, 194, 197, 191, 193, 199, - 195, 182, 175, 176, 185, 188, 182, 181, 185, 179, 171, 165, 162, 162, 167, 169, - 170, 179, 164, 154, 160, 167, 157, 140, 128, 139, 108, 73, 49, 41, 39, 37, - 33, 29, 30, 30, 27, 29, 32, 35, 39, 57, 75, 89, 92, 90, 89, 90, - 89, 92, 93, 95, 94, 92, 92, 95, 96, 94, 93, 93, 93, 93, 92, 91, - 90, 93, 93, 93, 92, 92, 91, 91, 91, 92, 92, 92, 35, 39, 39, 36, - 37, 40, 40, 36, 41, 39, 40, 40, 40, 41, 41, 43, 42, 42, 42, 41, - 41, 42, 43, 44, 43, 44, 40, 29, 14, 7, 9, 12, 14, 9, 15, 18, - 16, 23, 32, 32, 29, 26, 37, 63, 94, 116, 124, 130, 138, 146, 148, 149, - 152, 159, 163, 163, 165, 169, 173, 176, 176, 176, 176, 179, 174, 172, 173, 183, - 191, 191, 187, 184, 189, 188, 188, 189, 190, 190, 190, 185, 185, 188, 191, 192, - 192, 191, 191, 191, 192, 194, 197, 199, 199, 196, 193, 190, 198, 214, 224, 213, - 206, 205, 209, 204, 211, 221, 213, 204, 221, 220, 214, 219, 223, 214, 210, 205, - 200, 196, 203, 214, 210, 209, 208, 209, 205, 200, 194, 192, 200, 198, 204, 204, - 192, 190, 196, 192, 186, 184, 189, 197, 193, 180, 178, 183, 169, 165, 162, 165, - 169, 172, 169, 164, 173, 169, 168, 169, 153, 137, 140, 156, 132, 128, 118, 94, - 68, 49, 43, 45, 30, 35, 29, 21, 27, 41, 37, 23, 37, 65, 89, 94, - 87, 85, 86, 91, 92, 93, 95, 94, 92, 92, 95, 96, 92, 93, 93, 93, - 93, 92, 91, 90, 93, 93, 93, 92, 92, 91, 91, 91, 94, 94, 94, 35, - 37, 37, 37, 35, 35, 35, 33, 36, 34, 34, 35, 35, 36, 36, 38, 45, - 47, 46, 43, 42, 43, 43, 45, 48, 37, 25, 16, 15, 17, 18, 16, 11, - 13, 25, 26, 22, 29, 34, 27, 29, 42, 62, 92, 127, 135, 131, 135, 144, - 147, 152, 156, 159, 162, 166, 168, 170, 170, 171, 173, 175, 178, 181, 182, 171, - 177, 183, 184, 183, 182, 185, 189, 196, 188, 190, 192, 187, 187, 188, 176, 182, - 187, 192, 192, 188, 186, 190, 194, 186, 199, 207, 200, 188, 187, 194, 200, 201, - 202, 201, 196, 201, 207, 213, 210, 212, 206, 205, 204, 212, 213, 214, 210, 209, - 203, 207, 212, 209, 200, 199, 206, 211, 215, 215, 209, 204, 204, 204, 202, 206, - 205, 204, 201, 194, 189, 197, 206, 191, 192, 189, 183, 181, 184, 185, 181, 180, - 172, 163, 160, 166, 168, 167, 163, 169, 168, 165, 164, 159, 155, 151, 147, 149, - 147, 142, 132, 120, 101, 68, 37, 32, 36, 35, 26, 27, 33, 28, 18, 45, - 46, 58, 76, 89, 88, 85, 87, 88, 89, 91, 94, 94, 96, 96, 96, 92, - 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 90, 90, 89, 89, 91, 96, - 98, 98, 35, 37, 37, 37, 35, 35, 33, 33, 35, 35, 34, 34, 35, 35, - 35, 37, 47, 48, 46, 45, 46, 47, 46, 46, 35, 26, 17, 12, 12, 16, - 17, 17, 27, 20, 24, 24, 22, 29, 38, 35, 34, 59, 82, 107, 130, 139, - 139, 145, 146, 148, 150, 154, 158, 161, 163, 164, 173, 173, 174, 175, 177, 178, - 178, 179, 175, 179, 182, 183, 184, 184, 187, 190, 187, 179, 181, 187, 188, 192, - 193, 182, 188, 188, 189, 189, 188, 187, 187, 187, 187, 194, 196, 192, 188, 191, - 195, 197, 198, 203, 208, 208, 210, 210, 206, 199, 206, 208, 212, 218, 223, 224, - 220, 217, 202, 204, 209, 216, 217, 214, 215, 218, 205, 213, 216, 212, 208, 209, - 211, 212, 208, 201, 197, 202, 205, 200, 192, 188, 191, 194, 193, 186, 182, 183, - 184, 183, 179, 173, 168, 168, 171, 171, 166, 160, 169, 166, 163, 162, 162, 160, - 154, 152, 151, 152, 147, 141, 135, 124, 103, 83, 52, 38, 31, 35, 35, 23, - 21, 27, 31, 33, 39, 57, 73, 83, 87, 87, 87, 89, 92, 92, 94, 95, - 96, 95, 92, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 90, 90, 89, - 89, 91, 95, 97, 97, 35, 37, 37, 37, 35, 35, 35, 35, 37, 37, 37, - 37, 36, 36, 37, 39, 46, 45, 44, 44, 47, 47, 44, 41, 22, 17, 12, - 11, 14, 20, 21, 21, 21, 17, 27, 38, 36, 33, 33, 27, 45, 82, 108, - 122, 134, 141, 145, 151, 153, 151, 151, 155, 161, 164, 164, 162, 172, 173, 175, - 176, 176, 175, 174, 173, 178, 178, 179, 180, 181, 183, 187, 188, 184, 174, 178, - 185, 189, 196, 198, 186, 196, 192, 190, 191, 192, 192, 189, 186, 196, 196, 194, - 191, 194, 200, 200, 196, 200, 202, 201, 198, 198, 202, 204, 202, 204, 208, 212, - 214, 212, 210, 207, 206, 216, 220, 220, 213, 207, 202, 198, 193, 206, 214, 218, - 213, 208, 208, 209, 209, 208, 201, 198, 202, 205, 200, 191, 186, 187, 194, 196, - 189, 183, 182, 183, 183, 177, 173, 171, 173, 176, 174, 167, 160, 170, 166, 162, - 163, 165, 165, 159, 156, 154, 156, 152, 146, 143, 139, 133, 122, 91, 58, 34, - 34, 39, 33, 28, 28, 25, 25, 27, 37, 55, 76, 85, 89, 89, 91, 92, - 92, 94, 94, 94, 93, 92, 92, 92, 92, 92, 92, 92, 92, 93, 93, 93, - 92, 92, 91, 91, 91, 93, 94, 94, 36, 38, 38, 38, 36, 36, 36, 36, - 36, 37, 37, 37, 36, 36, 36, 39, 40, 39, 40, 43, 46, 43, 34, 27, - 16, 14, 13, 16, 22, 26, 27, 26, 40, 28, 29, 32, 27, 29, 41, 48, - 59, 101, 126, 130, 139, 145, 148, 151, 160, 156, 154, 158, 166, 170, 169, 166, - 168, 169, 172, 174, 174, 173, 171, 170, 178, 176, 175, 176, 179, 182, 185, 185, - 194, 183, 184, 189, 192, 198, 198, 185, 193, 193, 193, 193, 192, 192, 190, 188, - 198, 198, 196, 195, 198, 203, 200, 194, 193, 196, 196, 193, 194, 200, 204, 205, - 205, 207, 207, 203, 198, 197, 201, 206, 207, 215, 216, 210, 210, 218, 220, 216, - 204, 207, 209, 207, 207, 209, 207, 203, 205, 204, 205, 202, 195, 189, 194, 203, - 178, 188, 193, 188, 180, 179, 180, 181, 175, 173, 172, 174, 176, 175, 168, 163, - 170, 165, 161, 162, 166, 167, 162, 159, 164, 163, 159, 151, 144, 139, 137, 135, - 115, 100, 72, 43, 32, 38, 37, 27, 29, 31, 29, 28, 39, 61, 79, 88, - 89, 89, 91, 92, 94, 93, 94, 93, 94, 92, 94, 92, 94, 92, 94, 92, - 95, 93, 95, 92, 94, 91, 93, 91, 93, 91, 93, 36, 38, 38, 38, 38, - 38, 36, 36, 37, 38, 36, 36, 37, 37, 35, 36, 38, 38, 40, 42, 41, - 35, 24, 16, 15, 17, 20, 22, 27, 29, 30, 31, 33, 31, 40, 44, 33, - 31, 42, 48, 77, 110, 130, 134, 146, 154, 153, 155, 161, 157, 154, 158, 166, - 170, 170, 167, 164, 166, 169, 172, 174, 174, 173, 172, 177, 175, 173, 174, 179, - 181, 182, 182, 199, 188, 190, 193, 192, 195, 194, 183, 187, 191, 194, 193, 189, - 187, 189, 192, 186, 192, 196, 195, 197, 199, 197, 193, 181, 193, 205, 210, 209, - 207, 201, 194, 202, 206, 208, 207, 204, 207, 215, 223, 225, 228, 221, 206, 198, - 201, 201, 196, 201, 200, 199, 201, 209, 215, 211, 203, 202, 203, 205, 203, 197, - 192, 197, 206, 173, 183, 190, 187, 180, 179, 181, 182, 176, 174, 171, 171, 173, - 173, 170, 167, 167, 163, 159, 160, 164, 166, 163, 161, 167, 165, 162, 155, 146, - 139, 137, 137, 122, 130, 118, 79, 45, 33, 38, 38, 32, 34, 32, 27, 27, - 44, 69, 88, 89, 89, 91, 92, 94, 93, 94, 93, 95, 94, 95, 94, 95, - 94, 95, 94, 96, 95, 96, 94, 95, 93, 94, 93, 93, 91, 93, 39, 39, - 39, 39, 39, 39, 37, 37, 37, 37, 36, 36, 37, 37, 35, 35, 38, 39, - 40, 37, 35, 27, 18, 15, 19, 21, 25, 27, 31, 32, 32, 34, 27, 32, - 44, 43, 36, 43, 59, 59, 98, 120, 132, 136, 152, 161, 159, 160, 157, 154, - 152, 154, 158, 162, 163, 162, 163, 165, 168, 171, 174, 175, 176, 176, 176, 176, - 177, 177, 180, 181, 182, 183, 192, 184, 190, 194, 191, 193, 193, 184, 189, 195, - 200, 198, 193, 190, 193, 198, 181, 189, 196, 197, 197, 200, 201, 200, 187, 197, - 204, 204, 201, 200, 198, 194, 196, 202, 208, 210, 207, 206, 208, 211, 198, 200, - 200, 198, 201, 211, 220, 224, 214, 210, 204, 202, 208, 213, 207, 196, 203, 198, - 197, 204, 209, 204, 196, 190, 177, 185, 191, 187, 183, 183, 185, 184, 177, 174, - 171, 170, 171, 172, 172, 172, 164, 162, 160, 160, 162, 163, 162, 162, 161, 159, - 159, 158, 154, 146, 145, 146, 144, 129, 118, 113, 94, 64, 43, 33, 33, 28, - 30, 26, 23, 30, 55, 79, 86, 88, 90, 90, 92, 94, 94, 94, 95, 95, - 95, 95, 95, 95, 95, 95, 96, 96, 96, 95, 95, 94, 94, 94, 93, 91, - 93, 39, 40, 40, 40, 39, 39, 39, 39, 39, 39, 39, 39, 38, 38, 39, - 37, 36, 37, 34, 28, 22, 16, 17, 20, 23, 26, 32, 34, 35, 35, 38, - 41, 58, 55, 48, 37, 43, 82, 118, 126, 126, 137, 139, 143, 157, 159, 157, - 162, 153, 151, 149, 148, 148, 150, 151, 152, 159, 160, 162, 164, 167, 169, 171, - 172, 171, 174, 177, 177, 175, 174, 178, 181, 180, 178, 188, 194, 191, 192, 194, - 187, 195, 197, 199, 198, 195, 193, 193, 195, 189, 194, 196, 195, 195, 200, 202, - 201, 197, 200, 197, 189, 186, 192, 200, 205, 197, 200, 202, 201, 197, 194, 194, - 195, 221, 218, 216, 215, 212, 210, 213, 219, 216, 215, 210, 203, 202, 205, 203, - 198, 204, 196, 195, 201, 204, 198, 189, 183, 182, 187, 189, 186, 183, 184, 183, - 181, 177, 175, 174, 173, 174, 174, 174, 174, 162, 163, 163, 162, 160, 160, 162, - 165, 161, 157, 158, 162, 161, 154, 151, 153, 156, 133, 118, 126, 129, 107, 74, - 46, 39, 25, 24, 28, 27, 25, 41, 65, 84, 86, 90, 90, 92, 92, 95, - 96, 95, 97, 97, 97, 97, 97, 97, 97, 98, 98, 98, 97, 97, 96, 96, - 94, 94, 92, 94, 40, 40, 40, 40, 39, 39, 39, 39, 40, 40, 40, 41, - 39, 40, 40, 38, 34, 33, 28, 21, 12, 10, 16, 26, 29, 33, 39, 41, - 41, 42, 45, 48, 47, 65, 84, 97, 117, 152, 167, 149, 150, 152, 148, 150, - 158, 153, 151, 161, 154, 153, 151, 148, 144, 144, 146, 148, 156, 156, 157, 159, - 161, 163, 165, 167, 164, 169, 174, 174, 170, 168, 172, 176, 177, 177, 191, 196, - 192, 191, 195, 189, 194, 192, 190, 189, 190, 188, 185, 182, 198, 197, 192, 187, - 188, 193, 195, 192, 191, 198, 201, 198, 195, 199, 205, 207, 201, 200, 197, 194, - 194, 196, 202, 206, 205, 200, 202, 208, 208, 201, 203, 212, 200, 205, 207, 202, - 200, 206, 212, 216, 200, 201, 202, 199, 190, 182, 184, 191, 187, 190, 189, 184, - 182, 183, 181, 177, 176, 176, 176, 176, 177, 177, 176, 175, 162, 165, 166, 164, - 159, 158, 163, 167, 167, 161, 160, 164, 164, 157, 151, 152, 140, 149, 148, 134, - 123, 118, 106, 84, 52, 27, 21, 33, 32, 23, 32, 53, 83, 86, 87, 90, - 92, 93, 95, 96, 95, 95, 97, 95, 97, 95, 97, 95, 98, 96, 98, 95, - 97, 94, 96, 94, 94, 93, 94, 41, 42, 40, 40, 40, 40, 39, 38, 38, - 39, 39, 42, 44, 42, 38, 32, 37, 24, 13, 11, 13, 18, 25, 34, 35, - 41, 46, 45, 49, 60, 71, 80, 121, 132, 145, 153, 156, 156, 162, 166, 155, - 155, 153, 154, 155, 156, 158, 159, 158, 159, 158, 155, 150, 146, 144, 145, 138, - 142, 147, 149, 150, 153, 157, 161, 164, 158, 159, 168, 174, 171, 174, 182, 181, - 177, 176, 181, 192, 195, 191, 186, 209, 205, 201, 196, 193, 193, 194, 196, 196, - 197, 199, 200, 195, 189, 192, 198, 187, 193, 200, 204, 202, 198, 194, 192, 195, - 198, 200, 200, 198, 198, 200, 203, 200, 205, 205, 203, 213, 226, 225, 214, 204, - 196, 192, 201, 211, 211, 204, 199, 210, 192, 182, 187, 192, 188, 185, 189, 187, - 185, 177, 177, 182, 175, 169, 180, 158, 173, 179, 170, 165, 170, 172, 167, 175, - 170, 166, 168, 171, 168, 156, 145, 157, 154, 158, 166, 169, 162, 157, 157, 152, - 150, 147, 144, 140, 136, 133, 124, 88, 38, 25, 41, 36, 23, 32, 53, 74, - 91, 91, 80, 85, 90, 92, 97, 95, 94, 93, 90, 94, 97, 96, 89, 94, - 93, 94, 93, 94, 94, 95, 95, 89, 96, 96, 40, 42, 40, 40, 40, 40, - 40, 39, 42, 44, 43, 41, 37, 36, 40, 42, 27, 15, 8, 14, 24, 29, - 33, 38, 36, 53, 72, 83, 94, 111, 128, 138, 152, 158, 164, 165, 161, 158, - 158, 159, 153, 153, 150, 150, 150, 150, 151, 151, 156, 154, 152, 152, 153, 151, - 147, 143, 138, 140, 140, 138, 137, 138, 143, 146, 152, 157, 167, 173, 170, 164, - 168, 177, 180, 178, 180, 185, 194, 197, 196, 193, 192, 192, 192, 193, 194, 195, - 197, 198, 196, 197, 200, 202, 199, 194, 196, 202, 201, 199, 196, 193, 191, 194, - 200, 204, 198, 201, 203, 203, 201, 200, 201, 203, 204, 211, 211, 203, 202, 209, - 211, 205, 195, 193, 196, 204, 207, 204, 200, 197, 194, 187, 189, 198, 200, 191, - 186, 188, 199, 193, 181, 176, 180, 177, 172, 176, 178, 171, 174, 184, 181, 166, - 158, 161, 163, 164, 162, 158, 153, 153, 158, 163, 160, 158, 160, 165, 167, 161, - 159, 162, 163, 153, 144, 142, 146, 145, 136, 121, 110, 90, 70, 42, 24, 30, - 39, 31, 61, 87, 98, 93, 95, 91, 83, 83, 88, 93, 94, 90, 89, 90, - 88, 85, 88, 88, 89, 89, 89, 89, 89, 91, 91, 98, 94, 38, 41, 41, - 42, 42, 41, 41, 42, 44, 43, 41, 41, 39, 38, 36, 33, 11, 10, 11, - 15, 23, 32, 49, 63, 101, 120, 139, 144, 141, 145, 152, 159, 159, 164, 167, - 166, 162, 158, 157, 159, 160, 159, 156, 154, 153, 153, 153, 153, 160, 156, 154, - 157, 162, 162, 156, 149, 148, 146, 143, 137, 133, 132, 134, 136, 143, 142, 146, - 152, 158, 165, 172, 177, 176, 177, 183, 187, 190, 192, 195, 195, 189, 190, 192, - 193, 193, 193, 192, 191, 194, 195, 199, 203, 201, 197, 198, 203, 197, 205, 215, - 221, 219, 212, 204, 199, 200, 202, 204, 204, 202, 201, 200, 200, 196, 205, 210, - 202, 195, 200, 206, 208, 209, 205, 201, 196, 190, 186, 191, 199, 203, 194, 188, - 187, 181, 172, 172, 178, 180, 177, 171, 168, 173, 177, 174, 170, 189, 172, 163, - 168, 167, 157, 150, 152, 159, 164, 169, 169, 164, 159, 158, 159, 158, 158, 160, - 162, 161, 157, 159, 165, 168, 160, 153, 149, 149, 146, 139, 127, 125, 124, 108, - 65, 38, 47, 48, 24, 47, 73, 86, 87, 92, 93, 92, 96, 81, 89, 94, - 91, 86, 86, 86, 85, 87, 87, 87, 87, 87, 87, 87, 89, 89, 97, 94, - 39, 40, 41, 41, 43, 43, 42, 43, 42, 36, 34, 41, 47, 42, 23, 5, - 11, 17, 24, 24, 23, 40, 78, 113, 125, 140, 156, 157, 155, 152, 153, 152, - 157, 159, 162, 160, 158, 156, 157, 159, 164, 164, 160, 159, 158, 158, 158, 158, - 161, 159, 159, 162, 165, 165, 160, 154, 156, 154, 150, 144, 138, 134, 132, 131, - 123, 127, 136, 144, 150, 156, 163, 169, 170, 174, 181, 184, 184, 184, 188, 191, - 193, 193, 194, 194, 193, 192, 191, 190, 192, 193, 197, 201, 199, 195, 195, 199, - 201, 201, 201, 199, 197, 197, 199, 201, 199, 201, 202, 202, 201, 198, 197, 193, - 190, 200, 208, 204, 200, 202, 207, 210, 191, 198, 209, 215, 208, 192, 181, 178, - 195, 189, 186, 189, 191, 191, 195, 201, 197, 199, 203, 202, 199, 203, 203, 192, - 184, 189, 184, 175, 177, 186, 182, 170, 167, 163, 162, 167, 173, 171, 161, 150, - 152, 156, 160, 159, 157, 154, 156, 161, 159, 165, 171, 164, 151, 142, 143, 143, - 133, 122, 120, 104, 79, 65, 53, 35, 52, 70, 77, 78, 85, 84, 82, 84, - 77, 83, 86, 84, 82, 84, 86, 84, 85, 85, 85, 84, 84, 84, 84, 84, - 81, 89, 86, 39, 42, 41, 41, 43, 43, 42, 43, 39, 38, 39, 42, 42, - 33, 15, 1, 22, 25, 31, 37, 46, 71, 109, 142, 137, 147, 152, 155, 157, - 158, 155, 150, 166, 165, 165, 160, 157, 152, 151, 151, 157, 156, 156, 156, 156, - 157, 158, 159, 155, 157, 159, 159, 157, 155, 153, 152, 153, 152, 150, 146, 141, - 135, 128, 124, 106, 117, 133, 144, 144, 139, 144, 155, 160, 166, 173, 176, 179, - 180, 184, 188, 188, 188, 188, 190, 192, 194, 197, 198, 195, 194, 196, 199, 198, - 194, 193, 197, 196, 196, 196, 194, 192, 193, 195, 198, 201, 200, 200, 200, 200, - 198, 196, 192, 193, 198, 204, 205, 203, 202, 200, 197, 214, 201, 187, 182, 184, - 191, 205, 217, 198, 194, 197, 206, 209, 200, 186, 176, 168, 163, 165, 157, 137, - 136, 140, 133, 133, 152, 164, 166, 173, 183, 183, 175, 175, 164, 153, 151, 158, - 163, 163, 160, 149, 156, 161, 160, 155, 153, 154, 156, 150, 160, 170, 167, 154, - 144, 144, 146, 144, 125, 128, 131, 114, 91, 70, 56, 41, 54, 59, 66, 79, - 81, 79, 79, 77, 75, 73, 70, 73, 78, 77, 73, 75, 75, 74, 74, 73, - 73, 72, 72, 73, 80, 77, 40, 43, 41, 42, 42, 43, 41, 42, 38, 45, - 47, 37, 21, 11, 13, 21, 27, 23, 27, 48, 77, 104, 125, 136, 162, 164, - 164, 161, 162, 165, 161, 153, 164, 163, 161, 159, 156, 154, 152, 151, 154, 154, - 154, 155, 156, 158, 159, 160, 159, 161, 162, 160, 156, 154, 154, 155, 153, 153, - 152, 151, 148, 141, 132, 125, 126, 96, 80, 97, 123, 134, 142, 153, 149, 155, - 163, 169, 175, 179, 185, 189, 186, 186, 186, 186, 187, 189, 192, 193, 198, 195, - 195, 198, 198, 195, 195, 198, 189, 196, 205, 210, 209, 203, 197, 194, 203, 201, - 199, 199, 199, 199, 198, 194, 185, 189, 194, 198, 201, 200, 196, 191, 188, 189, - 199, 212, 216, 205, 189, 178, 187, 180, 173, 169, 164, 150, 130, 115, 125, 104, - 99, 90, 64, 62, 75, 75, 71, 71, 80, 95, 102, 108, 127, 150, 167, 170, - 171, 167, 160, 156, 158, 160, 151, 159, 163, 161, 159, 158, 158, 156, 153, 153, - 155, 157, 160, 153, 147, 139, 142, 135, 136, 134, 125, 121, 112, 92, 64, 64, - 52, 47, 59, 67, 75, 85, 82, 79, 75, 72, 75, 79, 77, 70, 74, 73, - 73, 72, 72, 71, 70, 70, 67, 73, 69, 42, 44, 44, 44, 42, 42, 42, - 42, 41, 43, 38, 24, 9, 5, 15, 30, 25, 26, 38, 65, 97, 120, 133, - 141, 150, 154, 156, 154, 154, 161, 162, 161, 152, 152, 153, 154, 155, 155, 154, - 152, 156, 156, 156, 157, 158, 160, 161, 162, 167, 165, 162, 161, 160, 160, 160, - 159, 158, 156, 155, 154, 151, 146, 137, 131, 132, 70, 27, 43, 79, 100, 122, - 142, 143, 147, 154, 161, 168, 173, 177, 179, 184, 185, 186, 186, 187, 187, 186, - 186, 197, 193, 191, 194, 195, 194, 196, 200, 198, 195, 190, 186, 186, 191, 199, - 206, 203, 200, 196, 195, 197, 198, 198, 195, 185, 185, 187, 191, 193, 192, 190, - 189, 190, 185, 183, 185, 182, 172, 161, 155, 142, 136, 129, 124, 124, 123, 119, - 114, 81, 46, 42, 46, 25, 23, 37, 36, 45, 38, 35, 40, 44, 53, 78, - 106, 131, 143, 160, 169, 169, 163, 157, 154, 158, 162, 161, 158, 157, 161, 160, - 156, 158, 155, 153, 153, 157, 154, 149, 142, 143, 139, 140, 138, 132, 135, 134, - 119, 120, 113, 89, 64, 52, 43, 44, 57, 74, 76, 79, 78, 80, 82, 79, - 74, 77, 76, 76, 75, 74, 73, 72, 70, 62, 66, 62, 45, 44, 44, 44, - 44, 42, 42, 41, 44, 34, 19, 11, 10, 13, 16, 20, 29, 44, 64, 89, - 107, 125, 146, 163, 166, 173, 172, 165, 156, 155, 157, 157, 159, 159, 159, 159, - 160, 159, 156, 153, 155, 155, 155, 156, 157, 158, 159, 160, 166, 159, 153, 155, - 160, 163, 161, 157, 159, 156, 152, 150, 146, 142, 135, 128, 97, 54, 29, 38, - 44, 42, 73, 119, 144, 147, 151, 156, 161, 164, 165, 166, 169, 173, 179, 185, - 190, 192, 191, 191, 191, 186, 183, 186, 189, 188, 193, 198, 190, 194, 199, 202, - 202, 201, 200, 200, 199, 196, 191, 190, 193, 195, 196, 193, 198, 196, 194, 191, - 185, 179, 178, 180, 172, 162, 152, 146, 141, 135, 133, 136, 137, 141, 142, 142, - 141, 136, 132, 128, 70, 28, 28, 45, 30, 25, 31, 23, 26, 39, 41, 32, - 31, 42, 49, 47, 87, 92, 106, 129, 153, 167, 167, 162, 160, 162, 157, 152, - 153, 160, 160, 156, 158, 162, 163, 158, 152, 147, 151, 155, 154, 142, 146, 150, - 137, 125, 123, 122, 112, 124, 121, 105, 84, 59, 46, 51, 57, 64, 75, 78, - 76, 77, 76, 73, 72, 72, 71, 70, 70, 70, 69, 66, 57, 62, 59, 44, - 48, 51, 48, 45, 44, 44, 40, 44, 25, 8, 6, 12, 17, 17, 22, 27, - 55, 76, 91, 118, 141, 153, 167, 156, 162, 169, 167, 163, 159, 163, 165, 170, - 167, 164, 161, 159, 158, 158, 156, 154, 159, 154, 152, 157, 157, 155, 161, 160, - 156, 151, 151, 153, 155, 157, 157, 153, 157, 149, 139, 150, 126, 144, 116, 50, - 16, 25, 31, 31, 29, 28, 72, 106, 127, 148, 156, 157, 163, 167, 169, 175, - 169, 177, 185, 179, 179, 184, 182, 189, 182, 194, 194, 167, 162, 186, 197, 202, - 189, 183, 188, 194, 190, 184, 182, 185, 186, 185, 183, 181, 178, 176, 173, 165, - 162, 160, 158, 157, 156, 155, 155, 155, 153, 150, 149, 150, 151, 150, 151, 150, - 173, 129, 149, 150, 121, 145, 101, 17, 17, 20, 20, 20, 20, 20, 21, 27, - 33, 36, 34, 29, 29, 34, 40, 48, 53, 71, 89, 125, 154, 155, 170, 160, - 170, 166, 155, 154, 154, 157, 167, 156, 164, 169, 163, 159, 155, 157, 153, 149, - 146, 149, 152, 147, 137, 130, 128, 129, 135, 127, 119, 121, 104, 71, 46, 38, - 31, 48, 68, 72, 72, 72, 68, 70, 62, 68, 73, 66, 62, 68, 67, 59, - 56, 55, 44, 46, 47, 49, 49, 48, 43, 36, 20, 13, 11, 16, 19, 18, - 15, 20, 43, 74, 92, 108, 130, 143, 148, 156, 164, 167, 169, 169, 169, 167, - 170, 169, 171, 168, 165, 163, 161, 160, 159, 159, 157, 162, 157, 154, 158, 157, - 155, 159, 156, 152, 149, 150, 152, 153, 154, 155, 156, 135, 169, 137, 133, 130, - 127, 45, 24, 12, 28, 27, 28, 29, 22, 42, 44, 75, 113, 139, 155, 160, - 156, 147, 148, 147, 159, 168, 160, 161, 171, 174, 182, 165, 171, 175, 165, 163, - 161, 146, 155, 159, 163, 165, 165, 167, 171, 176, 168, 168, 170, 169, 168, 165, - 166, 163, 162, 160, 159, 158, 158, 158, 158, 159, 164, 161, 159, 158, 159, 160, - 159, 161, 162, 150, 163, 146, 149, 130, 141, 37, 19, 21, 21, 22, 22, 22, - 22, 24, 31, 33, 32, 31, 30, 30, 32, 33, 37, 42, 52, 53, 84, 121, - 133, 153, 158, 167, 163, 160, 166, 163, 151, 147, 154, 160, 163, 161, 158, 158, - 157, 154, 153, 149, 147, 146, 143, 137, 135, 139, 126, 136, 134, 130, 132, 126, - 111, 101, 76, 47, 38, 47, 56, 67, 75, 67, 75, 61, 61, 60, 54, 57, - 67, 64, 70, 63, 60, 45, 44, 47, 53, 55, 50, 34, 23, 6, 10, 16, - 23, 20, 15, 16, 26, 43, 75, 98, 119, 143, 153, 154, 161, 169, 166, 164, - 164, 167, 166, 167, 164, 168, 167, 165, 163, 162, 161, 160, 160, 158, 163, 157, - 154, 157, 155, 151, 155, 151, 148, 147, 149, 151, 150, 151, 149, 153, 134, 152, - 142, 116, 133, 68, 6, 17, 23, 35, 24, 25, 35, 26, 25, 36, 41, 48, - 56, 74, 94, 110, 115, 111, 108, 119, 123, 113, 110, 119, 124, 128, 101, 85, - 77, 78, 93, 98, 87, 64, 101, 137, 151, 151, 154, 158, 159, 166, 166, 166, - 167, 167, 166, 168, 167, 172, 171, 170, 169, 168, 168, 168, 168, 171, 169, 167, - 167, 168, 169, 168, 167, 168, 155, 155, 158, 141, 146, 89, 7, 22, 21, 22, - 21, 22, 23, 22, 25, 33, 32, 29, 28, 30, 31, 29, 27, 31, 37, 42, - 31, 50, 84, 101, 128, 149, 159, 159, 159, 168, 168, 161, 160, 153, 156, 157, - 156, 158, 160, 156, 151, 154, 149, 147, 147, 145, 141, 139, 142, 131, 142, 139, - 132, 131, 130, 129, 134, 116, 85, 62, 49, 42, 47, 57, 56, 66, 62, 71, - 75, 70, 72, 74, 60, 57, 53, 54, 49, 49, 52, 57, 53, 40, 22, 12, - 15, 16, 18, 20, 16, 13, 18, 31, 40, 73, 100, 125, 150, 158, 160, 166, - 167, 166, 164, 162, 162, 161, 161, 161, 166, 166, 165, 164, 163, 163, 161, 161, - 157, 162, 156, 152, 155, 151, 146, 151, 148, 147, 148, 148, 150, 149, 148, 145, - 149, 142, 129, 123, 129, 86, 15, 25, 25, 32, 33, 23, 24, 33, 32, 29, - 26, 27, 28, 28, 32, 35, 39, 39, 44, 39, 46, 48, 38, 33, 39, 40, - 44, 45, 45, 42, 42, 49, 50, 42, 44, 98, 150, 165, 166, 171, 174, 170, - 178, 177, 177, 177, 177, 176, 179, 177, 186, 185, 183, 180, 178, 176, 175, 175, - 173, 172, 170, 170, 171, 172, 171, 169, 167, 170, 137, 152, 153, 110, 31, 25, - 17, 17, 17, 17, 19, 22, 23, 25, 30, 31, 30, 29, 30, 30, 29, 28, - 32, 33, 40, 34, 42, 56, 67, 102, 121, 143, 155, 158, 163, 162, 161, 167, - 157, 157, 155, 154, 158, 160, 155, 147, 149, 147, 149, 153, 153, 147, 141, 140, - 139, 146, 140, 130, 127, 126, 129, 139, 127, 117, 109, 85, 49, 35, 40, 42, - 44, 49, 64, 67, 64, 69, 72, 58, 67, 68, 68, 62, 58, 50, 45, 35, - 22, 14, 15, 22, 19, 15, 16, 16, 15, 19, 32, 57, 85, 105, 127, 148, - 152, 153, 160, 165, 169, 169, 167, 161, 158, 161, 165, 164, 164, 164, 165, 165, - 164, 163, 163, 158, 163, 157, 153, 155, 150, 144, 149, 146, 145, 146, 147, 149, - 148, 144, 141, 141, 140, 134, 109, 124, 22, 17, 38, 28, 28, 24, 25, 24, - 23, 29, 28, 18, 25, 35, 39, 32, 23, 16, 12, 30, 21, 25, 32, 31, - 32, 38, 35, 24, 36, 40, 38, 41, 43, 47, 50, 86, 129, 164, 167, 166, - 177, 183, 179, 183, 182, 181, 178, 178, 176, 179, 180, 186, 185, 182, 180, 178, - 176, 176, 175, 175, 173, 172, 172, 173, 172, 170, 166, 165, 161, 157, 132, 156, - 34, 28, 28, 13, 13, 13, 15, 17, 21, 24, 27, 26, 30, 33, 32, 29, - 28, 30, 34, 34, 25, 34, 39, 42, 37, 42, 86, 99, 123, 139, 149, 160, - 158, 150, 150, 162, 160, 156, 154, 158, 160, 154, 145, 150, 147, 148, 153, 155, - 149, 143, 142, 141, 143, 136, 131, 133, 132, 133, 143, 122, 129, 136, 119, 78, - 53, 45, 39, 24, 22, 26, 24, 19, 30, 47, 49, 51, 60, 68, 66, 52, - 37, 26, 15, 8, 12, 24, 17, 13, 11, 16, 20, 19, 20, 29, 67, 90, - 109, 129, 148, 149, 151, 161, 159, 163, 168, 164, 158, 153, 157, 161, 161, 163, - 164, 165, 166, 166, 164, 164, 161, 166, 161, 157, 158, 153, 147, 150, 144, 143, - 144, 145, 147, 145, 142, 139, 131, 143, 126, 136, 50, 16, 31, 27, 24, 27, - 19, 33, 34, 20, 26, 24, 31, 28, 27, 22, 17, 16, 21, 31, 19, 7, - 9, 18, 20, 25, 28, 25, 35, 34, 21, 19, 31, 34, 40, 55, 113, 143, - 168, 169, 170, 178, 180, 172, 184, 183, 179, 175, 174, 175, 176, 176, 181, 181, - 180, 179, 179, 180, 181, 181, 178, 177, 175, 175, 175, 173, 170, 166, 156, 156, - 165, 142, 85, 11, 37, 11, 13, 14, 16, 19, 22, 24, 28, 29, 23, 29, - 34, 33, 29, 27, 31, 36, 37, 24, 31, 38, 42, 35, 37, 76, 107, 113, - 112, 119, 144, 159, 161, 163, 164, 163, 159, 155, 157, 159, 154, 146, 158, 150, - 145, 146, 149, 148, 147, 149, 143, 143, 135, 134, 137, 132, 126, 133, 136, 135, - 140, 131, 107, 84, 63, 38, 15, 6, 9, 11, 4, 6, 19, 24, 13, 27, - 42, 46, 31, 20, 15, 12, 7, 12, 22, 16, 14, 15, 19, 22, 20, 23, - 34, 64, 87, 107, 128, 148, 151, 152, 164, 154, 158, 161, 161, 157, 153, 153, - 154, 160, 162, 164, 166, 167, 167, 166, 165, 161, 167, 162, 158, 160, 154, 147, - 151, 144, 142, 141, 141, 141, 140, 137, 135, 127, 143, 116, 125, 2, 33, 24, - 21, 27, 32, 21, 37, 38, 23, 29, 20, 22, 19, 21, 25, 24, 16, 13, - 15, 30, 19, 23, 28, 24, 25, 31, 29, 22, 28, 29, 39, 53, 42, 40, - 61, 138, 161, 183, 187, 188, 191, 189, 180, 186, 185, 181, 177, 177, 176, 177, - 178, 181, 182, 182, 182, 183, 184, 185, 186, 181, 179, 177, 176, 176, 173, 169, - 164, 153, 161, 146, 138, 15, 29, 21, 11, 17, 19, 22, 24, 24, 25, 26, - 26, 23, 26, 29, 29, 27, 25, 26, 27, 34, 30, 36, 34, 40, 40, 33, - 56, 112, 115, 107, 104, 121, 140, 155, 170, 160, 160, 157, 153, 154, 156, 153, - 146, 160, 151, 144, 146, 149, 148, 147, 148, 144, 145, 139, 138, 137, 127, 120, - 130, 144, 138, 141, 138, 130, 118, 92, 57, 29, 10, 14, 27, 22, 13, 13, - 13, 20, 24, 29, 18, 7, 6, 17, 23, 16, 11, 13, 25, 22, 19, 19, - 17, 19, 28, 43, 65, 87, 107, 127, 145, 146, 145, 157, 159, 158, 160, 162, - 163, 160, 156, 154, 159, 162, 164, 166, 167, 168, 166, 166, 159, 165, 160, 157, - 158, 153, 146, 150, 142, 140, 138, 137, 138, 137, 135, 134, 136, 124, 129, 58, - 29, 20, 18, 28, 28, 39, 22, 28, 28, 21, 31, 14, 33, 23, 18, 23, - 25, 22, 19, 19, 19, 12, 18, 22, 15, 17, 26, 26, 29, 35, 31, 36, - 47, 40, 61, 107, 167, 176, 181, 177, 176, 180, 184, 184, 187, 183, 181, 178, - 176, 178, 179, 182, 183, 184, 183, 182, 182, 182, 182, 183, 181, 179, 177, 176, - 175, 171, 167, 159, 158, 157, 139, 90, 11, 32, 0, 30, 20, 23, 25, 25, - 25, 23, 23, 21, 27, 25, 25, 26, 27, 26, 23, 20, 25, 34, 43, 31, - 37, 44, 25, 26, 94, 120, 131, 122, 113, 109, 120, 140, 156, 158, 156, 153, - 153, 155, 153, 149, 154, 148, 146, 151, 154, 151, 144, 141, 139, 143, 142, 143, - 142, 132, 128, 142, 131, 133, 142, 150, 146, 142, 123, 89, 55, 19, 10, 24, - 25, 18, 20, 23, 26, 22, 20, 15, 17, 17, 17, 18, 19, 20, 20, 24, - 23, 24, 23, 19, 17, 23, 39, 80, 99, 109, 121, 145, 158, 160, 162, 158, - 162, 164, 164, 166, 165, 159, 151, 151, 153, 157, 163, 168, 171, 169, 167, 163, - 160, 158, 157, 154, 152, 146, 141, 147, 140, 143, 146, 136, 135, 134, 128, 150, - 106, 112, 35, 21, 33, 15, 23, 31, 32, 29, 32, 33, 32, 26, 18, 14, - 23, 24, 22, 23, 18, 18, 30, 22, 23, 22, 20, 19, 22, 26, 29, 31, - 29, 30, 47, 66, 77, 112, 158, 180, 183, 187, 187, 188, 187, 186, 186, 187, - 184, 184, 182, 180, 180, 178, 179, 184, 186, 185, 184, 184, 183, 182, 182, 182, - 185, 183, 176, 170, 170, 169, 163, 167, 137, 142, 38, 26, 15, 15, 17, 19, - 19, 29, 33, 24, 22, 24, 19, 30, 22, 29, 29, 20, 31, 39, 24, 31, - 33, 35, 37, 38, 37, 35, 34, 77, 122, 118, 126, 130, 126, 99, 125, 132, - 150, 162, 159, 153, 153, 159, 161, 159, 153, 151, 154, 153, 147, 143, 146, 146, - 144, 142, 142, 139, 135, 132, 134, 128, 139, 141, 137, 139, 138, 128, 112, 52, - 17, 23, 43, 31, 26, 28, 14, 26, 23, 22, 11, 10, 12, 12, 13, 14, - 17, 18, 22, 22, 23, 24, 21, 19, 27, 41, 67, 99, 116, 127, 138, 142, - 144, 154, 169, 169, 166, 161, 161, 163, 163, 158, 166, 165, 162, 161, 163, 165, - 165, 165, 162, 160, 158, 158, 156, 153, 148, 146, 143, 137, 139, 142, 135, 136, - 137, 130, 132, 126, 84, 25, 26, 26, 19, 23, 26, 26, 25, 25, 28, 26, - 20, 15, 18, 23, 20, 18, 20, 16, 14, 24, 19, 21, 23, 25, 27, 27, - 28, 28, 35, 31, 40, 86, 140, 163, 166, 174, 176, 179, 183, 184, 183, 182, - 184, 183, 189, 189, 187, 185, 184, 182, 182, 182, 182, 184, 183, 183, 183, 182, - 182, 182, 179, 179, 175, 171, 171, 173, 170, 161, 155, 141, 110, 11, 13, 15, - 12, 24, 17, 17, 21, 17, 11, 19, 28, 28, 12, 23, 37, 37, 27, 27, - 28, 21, 29, 31, 33, 35, 36, 36, 35, 32, 55, 115, 119, 124, 128, 125, - 120, 118, 121, 133, 143, 147, 149, 155, 158, 157, 155, 148, 145, 148, 149, 146, - 142, 144, 142, 144, 145, 143, 136, 131, 131, 136, 135, 140, 141, 143, 145, 144, - 130, 118, 98, 59, 41, 39, 24, 22, 29, 29, 34, 31, 28, 11, 10, 11, - 11, 12, 15, 20, 21, 18, 17, 20, 22, 20, 19, 27, 38, 88, 115, 131, - 140, 152, 155, 153, 157, 160, 167, 172, 172, 171, 166, 157, 148, 160, 160, 160, - 162, 166, 169, 169, 169, 159, 158, 157, 157, 155, 152, 147, 146, 142, 136, 137, - 140, 134, 137, 137, 128, 122, 138, 49, 21, 33, 24, 28, 24, 23, 23, 23, - 23, 25, 23, 18, 12, 19, 19, 15, 16, 23, 19, 15, 23, 34, 30, 25, - 22, 24, 26, 30, 32, 30, 51, 79, 121, 163, 177, 172, 172, 177, 179, 184, - 185, 186, 185, 187, 187, 189, 189, 187, 185, 185, 185, 185, 185, 182, 182, 182, - 182, 182, 181, 181, 181, 178, 175, 171, 169, 174, 178, 173, 161, 155, 148, 79, - 4, 13, 21, 10, 23, 31, 33, 26, 19, 26, 35, 30, 12, 19, 25, 21, - 19, 26, 29, 27, 28, 25, 26, 29, 31, 33, 33, 33, 32, 32, 95, 123, - 122, 127, 126, 140, 114, 122, 127, 133, 141, 151, 160, 161, 158, 159, 151, 146, - 148, 152, 151, 148, 147, 140, 146, 149, 145, 135, 131, 133, 139, 138, 136, 137, - 145, 149, 143, 131, 122, 103, 70, 41, 32, 25, 19, 21, 27, 19, 20, 18, - 9, 11, 14, 16, 18, 19, 22, 22, 19, 17, 20, 22, 21, 19, 25, 35, - 72, 105, 123, 130, 135, 138, 143, 155, 151, 161, 170, 175, 173, 166, 155, 144, - 151, 155, 162, 168, 173, 172, 166, 162, 158, 158, 158, 157, 153, 149, 144, 143, - 147, 142, 143, 141, 134, 135, 134, 123, 125, 114, 21, 23, 29, 25, 28, 19, - 23, 23, 22, 23, 24, 22, 18, 15, 17, 16, 13, 18, 29, 25, 20, 28, - 24, 22, 24, 28, 36, 39, 41, 40, 73, 112, 142, 157, 164, 164, 169, 182, - 177, 178, 183, 184, 186, 187, 187, 189, 186, 187, 187, 185, 185, 184, 186, 186, - 185, 184, 184, 183, 182, 181, 180, 180, 178, 178, 175, 173, 176, 179, 175, 166, - 150, 124, 41, 15, 18, 27, 16, 22, 9, 29, 31, 18, 21, 27, 21, 9, - 24, 36, 27, 20, 29, 27, 24, 37, 25, 26, 28, 31, 33, 34, 34, 34, - 25, 62, 127, 123, 128, 133, 143, 121, 133, 133, 135, 139, 148, 156, 159, 160, - 163, 156, 150, 150, 154, 155, 152, 148, 143, 148, 149, 145, 138, 137, 137, 138, - 137, 129, 129, 142, 149, 141, 132, 127, 115, 86, 48, 35, 39, 35, 28, 35, - 22, 22, 22, 4, 7, 12, 16, 19, 19, 18, 17, 25, 22, 23, 25, 26, - 23, 25, 32, 51, 93, 122, 132, 137, 140, 153, 173, 158, 161, 161, 158, 159, - 161, 164, 163, 167, 169, 171, 173, 172, 166, 156, 150, 161, 162, 163, 162, 156, - 150, 145, 144, 150, 147, 148, 145, 138, 139, 135, 117, 129, 63, 8, 29, 18, - 26, 22, 13, 22, 22, 22, 21, 22, 19, 17, 15, 16, 15, 13, 21, 32, - 27, 26, 36, 33, 44, 65, 86, 100, 103, 99, 94, 131, 154, 163, 166, 173, - 177, 177, 181, 170, 174, 178, 179, 181, 182, 184, 186, 186, 187, 187, 187, 187, - 186, 188, 186, 189, 188, 186, 185, 183, 181, 180, 179, 177, 180, 180, 176, 173, - 174, 172, 166, 146, 88, 13, 21, 12, 25, 26, 37, 76, 100, 84, 38, 10, - 5, 14, 31, 11, 37, 44, 40, 38, 22, 14, 31, 26, 27, 29, 31, 33, - 34, 35, 36, 32, 31, 120, 122, 128, 138, 131, 133, 134, 134, 133, 133, 134, - 139, 147, 157, 161, 156, 151, 149, 152, 154, 150, 145, 145, 146, 144, 140, 139, - 142, 138, 131, 132, 126, 128, 141, 149, 143, 135, 132, 139, 102, 52, 28, 33, - 33, 28, 32, 26, 26, 24, 7, 10, 15, 20, 22, 21, 20, 17, 22, 18, - 19, 21, 22, 19, 19, 25, 26, 48, 65, 88, 121, 137, 137, 139, 151, 156, - 159, 159, 159, 164, 167, 166, 180, 177, 172, 169, 166, 164, 160, 157, 164, 166, - 168, 167, 160, 154, 150, 149, 150, 149, 152, 149, 143, 143, 136, 114, 116, 28, - 16, 33, 19, 28, 22, 18, 18, 18, 19, 17, 17, 17, 16, 15, 16, 18, - 17, 23, 31, 25, 32, 53, 90, 98, 113, 127, 139, 148, 155, 159, 152, 162, - 163, 161, 169, 170, 168, 172, 171, 175, 179, 181, 182, 183, 184, 186, 187, 187, - 188, 189, 189, 189, 191, 190, 189, 188, 187, 185, 183, 181, 180, 179, 175, 180, - 181, 176, 171, 169, 168, 163, 168, 102, 35, 28, 15, 25, 32, 71, 119, 156, - 164, 149, 131, 86, 25, 0, 32, 32, 25, 28, 38, 35, 25, 25, 28, 28, - 29, 31, 32, 34, 35, 34, 36, 23, 97, 121, 130, 140, 127, 143, 135, 135, - 136, 134, 130, 130, 140, 152, 157, 158, 156, 153, 153, 155, 152, 148, 143, 144, - 139, 135, 137, 143, 138, 126, 129, 127, 133, 141, 148, 145, 140, 136, 131, 95, - 59, 40, 37, 34, 29, 22, 24, 24, 22, 11, 12, 17, 19, 21, 20, 20, - 21, 17, 15, 14, 17, 20, 17, 17, 22, 37, 39, 35, 55, 101, 128, 132, - 129, 138, 149, 159, 163, 164, 164, 161, 157, 170, 167, 164, 164, 165, 167, 167, - 167, 160, 164, 168, 168, 162, 157, 153, 154, 154, 154, 157, 153, 145, 143, 133, - 106, 72, 20, 26, 26, 25, 22, 23, 24, 17, 18, 18, 16, 16, 13, 14, - 16, 17, 20, 19, 25, 30, 28, 51, 85, 130, 131, 133, 133, 133, 141, 156, - 168, 162, 173, 175, 174, 175, 168, 168, 180, 175, 178, 182, 184, 184, 184, 185, - 186, 186, 186, 189, 189, 190, 189, 192, 190, 187, 185, 184, 184, 183, 182, 182, - 181, 176, 179, 178, 174, 173, 172, 168, 160, 176, 145, 81, 26, 24, 28, 26, - 111, 150, 161, 146, 141, 160, 144, 104, 94, 99, 69, 46, 40, 39, 40, 36, - 27, 27, 27, 28, 28, 29, 31, 32, 32, 32, 36, 63, 117, 131, 134, 138, - 143, 140, 139, 141, 141, 134, 129, 133, 143, 150, 157, 160, 157, 155, 157, 156, - 153, 142, 146, 143, 137, 137, 143, 140, 129, 126, 132, 138, 139, 141, 142, 141, - 135, 126, 99, 89, 77, 57, 49, 49, 35, 41, 39, 38, 13, 12, 11, 12, - 13, 14, 16, 19, 20, 18, 18, 22, 23, 23, 23, 26, 20, 32, 28, 25, - 41, 66, 98, 128, 139, 148, 151, 150, 150, 155, 160, 161, 158, 159, 161, 164, - 167, 167, 163, 161, 156, 159, 166, 166, 162, 158, 155, 157, 158, 158, 159, 153, - 145, 142, 127, 97, 30, 23, 27, 12, 25, 10, 18, 21, 18, 19, 20, 20, - 17, 16, 17, 20, 18, 22, 23, 26, 31, 35, 69, 114, 135, 141, 155, 156, - 152, 150, 155, 160, 170, 169, 166, 171, 181, 175, 173, 181, 171, 174, 179, 181, - 180, 180, 181, 182, 181, 183, 183, 184, 185, 186, 187, 187, 183, 183, 183, 184, - 184, 183, 183, 183, 180, 179, 176, 174, 178, 177, 172, 160, 147, 158, 101, 12, - 30, 32, 16, 134, 138, 162, 158, 153, 166, 152, 136, 155, 144, 130, 123, 97, - 43, 19, 25, 29, 25, 27, 27, 27, 28, 29, 31, 31, 27, 54, 40, 115, - 132, 130, 153, 141, 144, 140, 141, 143, 136, 126, 123, 128, 137, 148, 156, 152, - 151, 152, 153, 152, 142, 150, 150, 142, 138, 144, 143, 135, 124, 135, 142, 136, - 135, 138, 138, 130, 132, 104, 97, 78, 41, 37, 53, 44, 48, 45, 40, 16, - 11, 7, 10, 15, 20, 21, 20, 17, 11, 15, 18, 15, 21, 25, 18, 28, - 26, 19, 18, 17, 12, 33, 73, 128, 132, 137, 143, 147, 150, 153, 155, 164, - 160, 158, 159, 161, 164, 164, 162, 159, 160, 163, 162, 160, 159, 164, 165, 164, - 156, 149, 141, 146, 155, 123, 68, 22, 27, 25, 17, 18, 24, 24, 21, 24, - 21, 18, 17, 19, 24, 30, 32, 31, 29, 26, 28, 50, 83, 113, 122, 136, - 136, 142, 142, 143, 147, 153, 159, 162, 171, 176, 174, 173, 174, 175, 170, 177, - 180, 180, 176, 175, 180, 183, 183, 178, 184, 186, 185, 184, 185, 187, 188, 186, - 184, 181, 182, 185, 185, 184, 182, 180, 174, 175, 178, 172, 171, 173, 165, 156, - 106, 73, 36, 32, 24, 23, 108, 149, 145, 151, 162, 166, 160, 162, 166, 144, - 155, 155, 143, 119, 60, 16, 15, 21, 23, 35, 40, 32, 30, 38, 38, 43, - 37, 53, 98, 139, 138, 138, 150, 142, 149, 152, 147, 136, 132, 129, 126, 127, - 140, 155, 155, 153, 151, 151, 149, 146, 147, 146, 143, 138, 134, 132, 131, 136, - 133, 137, 143, 146, 141, 135, 134, 134, 112, 104, 64, 49, 52, 41, 53, 47, - 43, 42, 19, 20, 20, 20, 19, 17, 17, 17, 22, 15, 18, 21, 18, 21, - 24, 18, 14, 20, 24, 27, 26, 10, 7, 20, 61, 104, 130, 123, 127, 151, - 157, 143, 154, 155, 155, 153, 152, 153, 156, 159, 158, 162, 163, 160, 156, 155, - 163, 165, 169, 160, 156, 151, 146, 136, 89, 29, 38, 36, 35, 33, 27, 19, - 18, 24, 23, 23, 24, 26, 28, 25, 21, 16, 38, 27, 40, 75, 108, 118, - 126, 134, 132, 136, 144, 149, 149, 149, 151, 153, 160, 166, 170, 168, 169, 173, - 175, 173, 173, 176, 176, 174, 177, 181, 181, 177, 187, 180, 173, 170, 173, 177, - 175, 174, 185, 184, 182, 182, 182, 184, 183, 182, 181, 174, 175, 176, 168, 169, - 170, 164, 169, 124, 81, 27, 24, 31, 25, 88, 148, 135, 137, 152, 159, 150, - 146, 146, 129, 138, 144, 151, 153, 121, 61, 18, 40, 26, 17, 24, 35, 37, - 39, 41, 45, 33, 51, 77, 127, 140, 141, 143, 141, 147, 148, 143, 136, 133, - 129, 124, 133, 123, 136, 158, 159, 152, 153, 155, 150, 149, 148, 146, 143, 141, - 139, 138, 140, 137, 139, 144, 146, 141, 134, 131, 135, 118, 102, 62, 33, 45, - 39, 54, 53, 51, 50, 15, 21, 26, 26, 21, 16, 15, 16, 23, 16, 19, - 22, 18, 21, 24, 17, 15, 23, 21, 19, 25, 21, 14, 17, 25, 58, 100, - 127, 139, 142, 139, 134, 144, 149, 153, 151, 147, 146, 153, 160, 155, 159, 161, - 157, 154, 154, 163, 167, 148, 155, 162, 149, 119, 103, 93, 77, 38, 37, 28, - 20, 27, 37, 29, 11, 27, 23, 18, 18, 24, 30, 35, 36, 33, 37, 67, - 107, 134, 131, 130, 136, 135, 140, 147, 151, 152, 153, 157, 160, 159, 163, 165, - 163, 166, 171, 175, 176, 176, 178, 177, 176, 179, 182, 179, 173, 169, 170, 174, - 178, 180, 178, 173, 171, 183, 182, 180, 180, 180, 183, 183, 182, 182, 174, 174, - 174, 168, 169, 168, 162, 161, 124, 76, 18, 23, 37, 13, 29, 89, 136, 157, - 133, 128, 154, 162, 141, 152, 149, 144, 138, 142, 139, 90, 24, 10, 34, 36, - 25, 32, 41, 35, 28, 46, 28, 48, 50, 103, 142, 144, 138, 143, 146, 145, - 142, 139, 138, 133, 126, 133, 114, 125, 148, 152, 157, 161, 150, 154, 151, 147, - 146, 147, 147, 145, 142, 141, 138, 139, 143, 146, 141, 134, 131, 132, 126, 103, - 69, 15, 30, 22, 35, 38, 42, 46, 12, 17, 22, 23, 21, 18, 16, 16, - 20, 13, 17, 20, 16, 20, 23, 17, 19, 25, 17, 9, 18, 27, 28, 32, - 14, 18, 44, 83, 112, 121, 124, 128, 140, 144, 148, 147, 144, 144, 149, 155, - 152, 153, 155, 155, 156, 158, 165, 165, 170, 149, 141, 143, 147, 154, 151, 136, - 139, 108, 68, 38, 25, 23, 30, 38, 27, 29, 31, 30, 27, 24, 23, 22, - 49, 80, 109, 116, 117, 123, 131, 131, 136, 136, 139, 139, 141, 146, 156, 164, - 159, 161, 163, 163, 165, 168, 172, 174, 177, 179, 179, 175, 174, 175, 173, 169, - 171, 172, 173, 169, 163, 163, 175, 188, 178, 180, 181, 181, 182, 183, 181, 181, - 182, 174, 173, 173, 166, 167, 166, 161, 169, 151, 115, 56, 38, 40, 21, 29, - 39, 63, 107, 143, 145, 130, 132, 147, 140, 135, 141, 136, 137, 157, 151, 108, - 19, 37, 38, 32, 37, 34, 28, 29, 43, 34, 45, 40, 71, 143, 146, 143, - 148, 148, 145, 144, 145, 146, 140, 131, 129, 123, 128, 128, 129, 158, 170, 142, - 156, 150, 145, 144, 147, 148, 145, 140, 138, 135, 136, 141, 144, 140, 135, 132, - 122, 127, 107, 86, 14, 27, 16, 23, 24, 33, 40, 18, 17, 16, 18, 20, - 21, 18, 16, 17, 11, 15, 19, 16, 21, 25, 18, 7, 25, 23, 15, 20, - 22, 17, 17, 18, 26, 24, 23, 52, 101, 130, 130, 136, 138, 140, 140, 139, - 138, 140, 141, 150, 149, 148, 150, 156, 158, 157, 153, 157, 147, 152, 165, 170, - 172, 166, 151, 148, 131, 137, 148, 110, 41, 9, 20, 22, 25, 28, 26, 26, - 38, 58, 73, 102, 126, 138, 128, 116, 122, 133, 136, 129, 128, 130, 128, 128, - 131, 139, 148, 149, 152, 156, 160, 163, 164, 167, 170, 166, 172, 173, 167, 163, - 164, 167, 167, 166, 169, 176, 181, 176, 165, 161, 165, 171, 175, 180, 184, 184, - 182, 180, 179, 181, 174, 175, 175, 166, 167, 168, 159, 152, 156, 140, 80, 27, - 6, 10, 36, 26, 30, 64, 119, 153, 149, 137, 131, 143, 140, 154, 154, 143, - 148, 145, 122, 105, 63, 26, 27, 34, 26, 25, 42, 36, 43, 41, 44, 42, - 132, 146, 153, 150, 149, 146, 145, 147, 149, 143, 134, 133, 131, 132, 123, 121, - 146, 164, 151, 157, 152, 146, 145, 148, 148, 143, 138, 135, 132, 133, 139, 143, - 140, 136, 134, 117, 123, 107, 100, 24, 30, 27, 28, 26, 36, 40, 26, 21, - 17, 17, 20, 21, 19, 15, 19, 13, 17, 21, 17, 21, 25, 19, 5, 21, - 23, 14, 17, 18, 15, 19, 28, 34, 33, 29, 34, 55, 84, 103, 124, 127, - 133, 136, 138, 137, 137, 135, 149, 147, 145, 145, 149, 149, 147, 143, 137, 152, - 176, 176, 153, 144, 153, 158, 145, 144, 141, 134, 122, 96, 57, 26, 30, 40, - 54, 63, 77, 99, 130, 151, 141, 135, 133, 135, 134, 126, 127, 133, 128, 132, - 135, 137, 133, 129, 129, 132, 135, 139, 145, 153, 158, 159, 163, 168, 162, 167, - 169, 166, 164, 167, 169, 168, 165, 157, 160, 177, 187, 181, 166, 157, 166, 172, - 178, 182, 182, 180, 178, 178, 179, 172, 175, 177, 168, 168, 168, 159, 165, 166, - 158, 130, 90, 58, 41, 33, 23, 44, 50, 51, 85, 140, 163, 147, 127, 121, - 133, 144, 147, 152, 152, 143, 142, 119, 85, 40, 12, 26, 39, 30, 31, 46, - 37, 48, 31, 105, 148, 158, 150, 149, 146, 144, 145, 148, 143, 135, 140, 133, - 130, 136, 133, 125, 136, 160, 157, 154, 151, 151, 151, 149, 144, 140, 136, 132, - 133, 138, 143, 140, 136, 135, 130, 122, 104, 100, 27, 16, 23, 20, 16, 24, - 27, 23, 22, 20, 20, 20, 21, 20, 19, 23, 16, 19, 22, 18, 20, 23, - 14, 12, 19, 15, 8, 14, 18, 21, 33, 22, 18, 28, 41, 31, 11, 17, - 43, 90, 102, 117, 125, 129, 132, 136, 140, 145, 146, 146, 142, 139, 140, 146, - 151, 174, 166, 164, 164, 163, 172, 170, 152, 147, 162, 155, 137, 142, 147, 103, - 42, 80, 98, 125, 142, 147, 142, 136, 132, 141, 132, 128, 132, 136, 132, 128, - 127, 134, 138, 142, 143, 138, 134, 132, 134, 130, 131, 135, 141, 146, 147, 152, - 159, 160, 161, 162, 163, 167, 168, 161, 151, 151, 126, 106, 106, 119, 135, 156, - 176, 164, 168, 173, 175, 175, 175, 177, 179, 179, 173, 176, 179, 173, 172, 171, - 159, 153, 149, 141, 139, 134, 115, 78, 29, 44, 23, 17, 29, 36, 49, 97, - 147, 153, 154, 145, 139, 144, 144, 138, 138, 132, 144, 144, 81, 12, 27, 49, - 22, 29, 43, 39, 46, 41, 73, 157, 159, 151, 152, 149, 146, 146, 148, 144, - 137, 138, 142, 137, 143, 143, 110, 100, 137, 153, 153, 154, 155, 153, 150, 146, - 143, 141, 137, 137, 140, 143, 140, 135, 134, 140, 117, 104, 104, 40, 6, 18, - 5, 3, 13, 18, 10, 15, 19, 20, 18, 17, 20, 23, 24, 16, 18, 20, - 14, 15, 17, 10, 15, 16, 13, 11, 19, 14, 13, 20, 29, 37, 37, 28, - 27, 31, 30, 25, 49, 70, 93, 108, 113, 119, 131, 142, 140, 146, 148, 142, - 136, 138, 154, 168, 164, 162, 163, 159, 155, 164, 162, 142, 142, 135, 139, 146, - 142, 126, 128, 141, 146, 142, 137, 135, 136, 139, 139, 138, 127, 141, 145, 130, - 125, 138, 140, 131, 131, 133, 136, 134, 131, 133, 136, 141, 132, 129, 131, 134, - 137, 135, 141, 150, 158, 155, 152, 155, 163, 162, 145, 126, 78, 73, 73, 75, - 72, 75, 97, 123, 162, 167, 169, 169, 169, 171, 176, 180, 177, 172, 176, 181, - 175, 174, 172, 159, 155, 160, 154, 145, 139, 140, 129, 88, 56, 39, 36, 44, - 42, 33, 47, 73, 110, 133, 135, 130, 142, 144, 139, 145, 152, 120, 131, 117, - 44, 19, 40, 39, 34, 40, 44, 43, 57, 54, 166, 158, 154, 156, 153, 150, - 148, 149, 146, 141, 127, 155, 149, 139, 141, 105, 77, 101, 147, 150, 154, 155, - 153, 149, 146, 145, 146, 142, 140, 143, 144, 140, 135, 133, 135, 106, 105, 115, - 64, 16, 29, 9, 11, 20, 26, 17, 19, 19, 16, 16, 21, 23, 21, 20, - 20, 20, 19, 18, 17, 15, 15, 16, 17, 17, 15, 16, 16, 18, 23, 24, - 29, 30, 30, 32, 30, 24, 15, 33, 13, 62, 112, 99, 106, 137, 133, 137, - 148, 139, 128, 140, 159, 162, 157, 161, 156, 150, 151, 153, 151, 140, 132, 146, - 135, 127, 126, 127, 127, 137, 147, 136, 135, 132, 131, 130, 131, 132, 133, 137, - 135, 138, 137, 134, 130, 125, 122, 142, 136, 132, 133, 140, 146, 142, 138, 142, - 139, 137, 137, 140, 139, 139, 136, 138, 142, 135, 128, 141, 147, 108, 56, 64, - 74, 45, 53, 63, 75, 84, 93, 141, 163, 166, 157, 160, 166, 172, 178, 172, - 170, 170, 173, 178, 179, 173, 165, 163, 162, 157, 146, 142, 142, 141, 135, 115, - 87, 55, 37, 39, 43, 40, 31, 40, 97, 147, 148, 132, 130, 138, 140, 138, - 143, 152, 119, 105, 39, 12, 48, 44, 37, 44, 54, 38, 77, 157, 169, 149, - 161, 159, 147, 143, 152, 151, 140, 131, 142, 142, 141, 145, 130, 98, 78, 114, - 159, 158, 162, 157, 150, 154, 141, 145, 144, 140, 135, 137, 139, 133, 125, 123, - 111, 106, 111, 72, 21, 26, 40, 28, 38, 58, 18, 20, 19, 16, 16, 20, - 22, 20, 19, 19, 19, 19, 18, 17, 16, 15, 18, 16, 18, 16, 15, 17, - 20, 23, 21, 25, 29, 29, 31, 33, 32, 25, 34, 14, 35, 69, 85, 115, - 138, 117, 111, 104, 103, 127, 154, 158, 163, 181, 139, 137, 137, 141, 145, 145, - 142, 136, 136, 132, 132, 134, 133, 128, 127, 131, 134, 133, 134, 133, 134, 134, - 132, 132, 133, 132, 132, 131, 130, 126, 123, 121, 134, 129, 125, 129, 135, 140, - 138, 136, 142, 142, 141, 144, 147, 145, 143, 139, 138, 135, 130, 118, 111, 98, - 82, 63, 50, 65, 69, 55, 52, 60, 68, 75, 92, 127, 152, 161, 171, 172, - 167, 166, 178, 177, 176, 173, 171, 169, 168, 168, 161, 162, 161, 153, 150, 153, - 150, 147, 139, 140, 128, 94, 54, 31, 36, 45, 26, 42, 73, 112, 143, 154, - 143, 125, 157, 144, 141, 134, 146, 95, 21, 12, 34, 40, 42, 49, 52, 99, - 167, 171, 150, 157, 158, 152, 148, 152, 149, 140, 133, 139, 137, 137, 140, 127, - 96, 74, 33, 108, 138, 144, 142, 145, 161, 154, 141, 142, 141, 137, 140, 141, - 134, 125, 135, 115, 101, 107, 81, 41, 38, 35, 51, 56, 64, 21, 24, 23, - 19, 18, 22, 22, 20, 20, 20, 21, 21, 21, 20, 19, 19, 20, 18, 19, - 18, 17, 20, 24, 28, 22, 25, 27, 27, 31, 35, 35, 30, 34, 30, 27, - 21, 26, 52, 65, 47, 31, 60, 106, 155, 174, 149, 127, 129, 135, 138, 142, - 147, 150, 150, 151, 149, 135, 133, 136, 138, 136, 130, 123, 123, 126, 127, 131, - 134, 134, 131, 126, 124, 125, 125, 125, 123, 122, 119, 118, 119, 123, 124, 122, - 124, 128, 132, 132, 134, 138, 142, 146, 151, 155, 154, 151, 147, 143, 134, 134, - 129, 109, 74, 56, 53, 50, 50, 26, 40, 41, 60, 51, 91, 106, 136, 155, - 163, 176, 180, 178, 180, 179, 180, 179, 175, 170, 170, 174, 179, 165, 165, 167, - 163, 161, 163, 160, 155, 148, 153, 152, 137, 116, 100, 98, 103, 87, 59, 44, - 64, 92, 110, 131, 149, 137, 134, 130, 136, 143, 118, 43, 24, 29, 46, 40, - 51, 83, 132, 178, 173, 153, 153, 153, 155, 154, 151, 145, 141, 138, 137, 136, - 136, 136, 125, 99, 77, 44, 61, 84, 130, 162, 149, 156, 165, 140, 142, 142, - 139, 141, 141, 135, 126, 122, 108, 97, 102, 86, 59, 60, 51, 64, 61, 55, - 22, 25, 24, 20, 19, 21, 21, 17, 19, 19, 20, 21, 21, 21, 20, 20, - 20, 20, 20, 18, 18, 21, 27, 31, 26, 28, 28, 26, 28, 32, 31, 27, - 27, 38, 33, 17, 19, 34, 36, 32, 30, 96, 144, 148, 143, 139, 133, 132, - 145, 150, 156, 157, 155, 151, 149, 147, 140, 136, 135, 132, 132, 130, 130, 130, - 122, 125, 128, 131, 130, 128, 124, 122, 126, 123, 123, 122, 120, 120, 121, 121, - 119, 120, 123, 123, 125, 126, 127, 131, 133, 138, 146, 153, 159, 160, 160, 158, - 154, 140, 135, 138, 129, 102, 79, 70, 53, 71, 58, 31, 46, 50, 88, 77, - 125, 144, 150, 149, 159, 166, 171, 181, 184, 185, 184, 180, 176, 174, 178, 182, - 172, 174, 175, 174, 171, 168, 164, 161, 168, 161, 156, 156, 159, 156, 148, 136, - 138, 118, 103, 100, 93, 87, 101, 125, 135, 147, 144, 145, 131, 118, 50, 33, - 32, 48, 38, 68, 127, 164, 181, 174, 158, 149, 147, 154, 154, 147, 141, 141, - 140, 137, 140, 142, 135, 126, 111, 93, 80, 44, 40, 85, 144, 136, 138, 150, - 142, 144, 143, 139, 139, 139, 135, 128, 123, 121, 113, 105, 74, 46, 50, 43, - 51, 54, 52, 22, 25, 24, 20, 19, 21, 20, 16, 19, 19, 20, 21, 21, - 21, 20, 20, 20, 21, 23, 20, 21, 24, 29, 33, 30, 31, 30, 27, 28, - 32, 29, 25, 33, 37, 30, 30, 47, 47, 36, 34, 60, 124, 153, 128, 120, - 139, 150, 148, 141, 148, 154, 153, 147, 137, 132, 128, 134, 132, 130, 126, 127, - 129, 132, 132, 128, 127, 128, 129, 129, 129, 128, 128, 130, 127, 126, 126, 126, - 127, 128, 129, 123, 123, 127, 125, 125, 125, 127, 130, 133, 138, 144, 148, 151, - 153, 156, 156, 155, 146, 134, 130, 133, 136, 129, 119, 88, 86, 23, 99, 36, - 50, 92, 111, 117, 136, 147, 151, 160, 162, 164, 171, 191, 189, 188, 186, 184, - 181, 177, 175, 179, 180, 182, 184, 183, 179, 175, 173, 169, 169, 167, 163, 158, - 155, 157, 157, 157, 151, 146, 142, 134, 122, 108, 101, 112, 117, 117, 128, 130, - 131, 58, 21, 35, 46, 42, 95, 165, 181, 179, 176, 163, 149, 142, 149, 151, - 144, 139, 141, 137, 133, 144, 148, 134, 127, 123, 111, 69, 61, 60, 50, 99, - 122, 143, 145, 145, 147, 144, 137, 135, 136, 133, 128, 114, 115, 109, 101, 72, - 48, 52, 43, 45, 49, 49, 21, 24, 24, 21, 20, 21, 20, 16, 20, 20, - 21, 21, 21, 20, 19, 20, 22, 23, 24, 25, 25, 25, 28, 31, 31, 32, - 31, 30, 32, 37, 34, 30, 29, 32, 33, 38, 41, 32, 29, 43, 84, 121, - 141, 141, 145, 146, 137, 130, 141, 145, 149, 147, 141, 132, 127, 123, 123, 125, - 128, 127, 129, 131, 131, 126, 127, 124, 123, 123, 123, 124, 126, 127, 125, 125, - 125, 125, 126, 127, 128, 129, 127, 128, 129, 128, 128, 128, 129, 130, 133, 138, - 143, 146, 147, 147, 149, 150, 143, 152, 151, 139, 135, 143, 143, 134, 141, 129, - 152, 239, 63, 43, 105, 104, 132, 146, 153, 157, 166, 167, 169, 178, 181, 182, - 185, 188, 190, 189, 185, 182, 185, 185, 190, 193, 194, 191, 189, 188, 174, 174, - 170, 165, 161, 161, 165, 170, 163, 164, 158, 146, 143, 147, 142, 134, 131, 122, - 122, 128, 134, 139, 84, 47, 41, 55, 64, 126, 183, 180, 176, 178, 168, 153, - 142, 145, 148, 144, 139, 137, 135, 126, 141, 150, 134, 129, 133, 121, 75, 62, - 75, 59, 105, 115, 132, 141, 142, 145, 144, 137, 135, 135, 132, 128, 116, 108, - 97, 97, 78, 54, 52, 36, 24, 26, 27, 21, 24, 25, 22, 22, 23, 22, - 18, 22, 22, 22, 22, 21, 20, 19, 18, 23, 26, 28, 29, 29, 28, 29, - 29, 29, 32, 31, 30, 33, 37, 34, 30, 15, 25, 38, 44, 42, 49, 79, - 108, 136, 143, 143, 145, 155, 154, 147, 149, 143, 142, 141, 139, 137, 132, 130, - 129, 121, 125, 129, 127, 130, 133, 133, 126, 122, 121, 121, 121, 120, 121, 122, - 122, 121, 121, 122, 123, 126, 127, 128, 126, 129, 130, 130, 131, 133, 134, 134, - 133, 135, 142, 150, 154, 154, 152, 153, 153, 143, 155, 160, 151, 143, 142, 136, - 127, 130, 157, 121, 44, 139, 131, 143, 139, 143, 150, 146, 146, 157, 162, 170, - 184, 178, 184, 191, 193, 194, 192, 193, 194, 190, 188, 193, 197, 198, 192, 191, - 194, 200, 189, 176, 172, 172, 172, 165, 158, 154, 167, 173, 167, 156, 154, 153, - 151, 152, 134, 135, 113, 104, 88, 51, 23, 57, 86, 109, 157, 182, 170, 174, - 177, 169, 158, 146, 146, 149, 149, 140, 131, 140, 122, 137, 151, 138, 136, 140, - 122, 86, 42, 62, 72, 133, 116, 109, 120, 133, 139, 143, 139, 137, 136, 132, - 127, 134, 122, 107, 103, 72, 34, 25, 9, 9, 10, 18, 19, 23, 25, 22, - 22, 24, 22, 18, 23, 23, 23, 22, 21, 20, 18, 18, 21, 26, 27, 29, - 29, 28, 27, 28, 27, 30, 28, 27, 29, 32, 28, 24, 41, 32, 30, 34, - 48, 81, 116, 130, 129, 143, 143, 139, 145, 150, 149, 154, 139, 135, 130, 125, - 124, 124, 125, 125, 130, 132, 132, 127, 129, 135, 139, 133, 124, 122, 125, 126, - 125, 125, 123, 123, 126, 127, 128, 130, 133, 134, 134, 132, 131, 130, 130, 134, - 138, 138, 138, 136, 134, 144, 156, 164, 166, 163, 164, 163, 162, 157, 148, 144, - 146, 148, 147, 142, 148, 109, 137, 147, 127, 149, 131, 140, 139, 149, 151, 157, - 172, 177, 184, 197, 194, 201, 207, 202, 193, 186, 188, 193, 192, 189, 190, 195, - 193, 187, 186, 190, 181, 179, 177, 178, 181, 183, 180, 180, 181, 176, 169, 165, - 163, 163, 164, 166, 168, 148, 165, 149, 152, 124, 85, 45, 75, 116, 147, 175, - 175, 161, 171, 174, 170, 161, 152, 149, 154, 155, 143, 129, 147, 122, 134, 152, - 143, 144, 145, 119, 81, 56, 87, 86, 151, 146, 132, 123, 123, 132, 140, 142, - 139, 139, 135, 128, 106, 106, 105, 105, 68, 24, 29, 30, 41, 38, 43, 20, - 20, 22, 21, 21, 20, 20, 19, 19, 21, 23, 22, 19, 18, 18, 18, 19, - 22, 24, 26, 24, 24, 25, 27, 25, 31, 33, 28, 24, 25, 24, 23, 26, - 38, 27, 46, 76, 122, 125, 127, 138, 147, 137, 148, 130, 117, 90, 104, 106, - 115, 118, 119, 122, 130, 136, 137, 127, 129, 133, 134, 136, 135, 137, 137, 123, - 120, 122, 122, 123, 125, 127, 128, 123, 129, 132, 131, 131, 133, 134, 134, 140, - 143, 144, 142, 140, 139, 141, 144, 147, 158, 160, 160, 165, 162, 160, 165, 167, - 162, 154, 150, 146, 142, 139, 137, 136, 135, 135, 137, 141, 142, 141, 138, 149, - 154, 156, 152, 149, 152, 165, 177, 197, 205, 203, 188, 181, 186, 188, 182, 174, - 177, 183, 187, 183, 178, 181, 188, 184, 182, 179, 178, 176, 175, 175, 176, 175, - 185, 187, 178, 176, 184, 187, 183, 173, 168, 171, 171, 160, 148, 126, 97, 120, - 142, 164, 174, 176, 175, 172, 167, 180, 164, 152, 154, 162, 158, 145, 134, 142, - 149, 137, 124, 142, 170, 157, 116, 98, 40, 75, 118, 144, 139, 156, 163, 130, - 116, 129, 143, 137, 135, 135, 122, 118, 108, 106, 107, 50, 51, 46, 38, 49, - 62, 64, 19, 19, 19, 19, 22, 22, 22, 22, 18, 20, 22, 21, 19, 18, - 19, 19, 19, 22, 24, 25, 22, 22, 23, 24, 26, 31, 30, 25, 22, 22, - 21, 21, 46, 42, 45, 90, 103, 118, 117, 130, 118, 140, 151, 108, 77, 47, - 23, 42, 48, 71, 100, 119, 131, 136, 133, 128, 135, 136, 138, 137, 136, 133, - 133, 133, 126, 124, 124, 125, 126, 128, 129, 130, 129, 134, 136, 134, 132, 134, - 134, 134, 142, 145, 147, 147, 147, 145, 148, 148, 146, 154, 156, 156, 162, 159, - 155, 163, 158, 156, 154, 150, 147, 143, 137, 134, 134, 133, 134, 139, 145, 148, - 150, 149, 151, 152, 153, 156, 156, 156, 156, 159, 171, 187, 194, 189, 186, 186, - 184, 175, 177, 175, 178, 184, 186, 182, 180, 181, 182, 181, 181, 180, 181, 181, - 181, 181, 178, 187, 189, 181, 178, 184, 184, 179, 194, 186, 184, 181, 173, 173, - 166, 149, 148, 162, 173, 174, 172, 172, 172, 169, 178, 169, 164, 168, 170, 163, - 149, 138, 131, 143, 150, 148, 146, 146, 133, 118, 96, 50, 91, 128, 150, 143, - 154, 155, 169, 133, 122, 132, 140, 147, 142, 120, 114, 103, 103, 105, 53, 45, - 43, 43, 70, 79, 80, 18, 20, 21, 22, 22, 23, 24, 24, 19, 20, 23, - 23, 21, 21, 22, 23, 19, 22, 24, 24, 23, 23, 23, 25, 27, 29, 28, - 24, 23, 23, 24, 26, 47, 39, 61, 116, 118, 126, 127, 136, 139, 147, 129, - 38, 29, 27, 49, 94, 90, 109, 129, 136, 138, 136, 133, 129, 134, 135, 135, - 134, 130, 127, 127, 125, 129, 127, 128, 128, 130, 131, 133, 134, 132, 137, 139, - 136, 135, 137, 138, 138, 138, 143, 147, 148, 148, 146, 148, 148, 143, 154, 152, - 153, 158, 155, 151, 158, 152, 152, 152, 151, 150, 145, 138, 134, 134, 133, 135, - 138, 146, 152, 157, 159, 160, 155, 152, 155, 160, 163, 159, 155, 157, 173, 185, - 185, 183, 182, 180, 170, 177, 168, 170, 179, 188, 188, 182, 177, 179, 179, 181, - 182, 182, 182, 183, 183, 181, 189, 191, 185, 182, 185, 183, 177, 188, 181, 179, - 174, 168, 175, 180, 171, 168, 175, 180, 178, 174, 172, 170, 168, 172, 169, 170, - 175, 174, 163, 149, 140, 132, 138, 152, 163, 153, 134, 123, 126, 89, 70, 119, - 138, 145, 136, 153, 161, 171, 135, 115, 120, 132, 142, 135, 114, 114, 103, 103, - 99, 49, 35, 37, 42, 53, 61, 61, 20, 22, 22, 22, 22, 23, 23, 23, - 21, 22, 25, 25, 24, 24, 27, 28, 19, 20, 22, 25, 25, 24, 26, 27, - 22, 22, 21, 23, 25, 29, 31, 33, 45, 48, 75, 119, 112, 137, 143, 132, - 139, 138, 83, 23, 33, 31, 53, 77, 114, 126, 135, 133, 131, 134, 139, 143, - 128, 129, 130, 130, 129, 127, 128, 128, 129, 129, 130, 130, 132, 133, 135, 136, - 133, 138, 140, 137, 136, 139, 141, 139, 135, 141, 144, 148, 146, 145, 143, 145, - 145, 155, 152, 152, 156, 152, 150, 156, 153, 155, 155, 154, 152, 147, 142, 136, - 133, 132, 132, 137, 142, 151, 158, 162, 165, 157, 150, 148, 153, 159, 162, 161, - 163, 171, 176, 173, 173, 175, 176, 173, 171, 164, 164, 173, 183, 185, 183, 180, - 177, 178, 181, 181, 182, 182, 182, 182, 184, 190, 193, 190, 189, 190, 186, 180, - 189, 186, 189, 186, 178, 182, 187, 180, 168, 174, 181, 184, 183, 180, 176, 172, - 171, 167, 169, 176, 177, 167, 154, 144, 147, 139, 141, 155, 157, 146, 135, 135, - 98, 85, 124, 130, 142, 141, 152, 152, 131, 118, 115, 120, 126, 127, 121, 110, - 110, 108, 102, 75, 29, 20, 24, 25, 38, 50, 54, 22, 24, 23, 22, 21, - 20, 20, 19, 20, 21, 22, 22, 21, 23, 25, 26, 16, 17, 20, 23, 23, - 24, 28, 29, 24, 21, 20, 24, 29, 31, 33, 37, 53, 57, 84, 126, 117, - 141, 144, 128, 128, 117, 28, 28, 36, 27, 45, 52, 102, 115, 129, 131, 131, - 131, 131, 129, 129, 130, 133, 134, 133, 132, 135, 137, 130, 130, 130, 131, 132, - 134, 135, 136, 137, 141, 142, 137, 135, 138, 139, 137, 136, 141, 144, 147, 144, - 143, 141, 141, 145, 154, 150, 148, 151, 147, 145, 153, 157, 157, 155, 151, 149, - 144, 141, 136, 131, 130, 129, 132, 134, 142, 148, 155, 159, 155, 150, 145, 145, - 150, 153, 157, 165, 168, 166, 164, 165, 168, 171, 172, 171, 165, 163, 167, 173, - 175, 176, 180, 177, 177, 177, 177, 179, 179, 180, 180, 182, 187, 190, 192, 193, - 193, 189, 184, 189, 188, 193, 190, 180, 183, 187, 180, 169, 170, 175, 181, 185, - 185, 182, 181, 175, 166, 163, 170, 176, 172, 161, 151, 151, 146, 143, 147, 153, - 154, 144, 134, 111, 94, 118, 120, 149, 152, 142, 125, 109, 114, 120, 123, 128, - 125, 117, 114, 104, 107, 94, 45, 13, 13, 24, 14, 33, 50, 59, 25, 24, - 23, 22, 20, 19, 17, 17, 18, 19, 19, 18, 18, 19, 22, 21, 15, 16, - 20, 22, 23, 23, 27, 28, 28, 22, 22, 28, 32, 31, 32, 35, 45, 47, - 74, 128, 127, 137, 135, 138, 136, 95, 2, 25, 27, 36, 74, 99, 116, 126, - 134, 135, 134, 131, 127, 122, 132, 133, 135, 133, 131, 131, 133, 133, 131, 131, - 131, 132, 133, 135, 136, 137, 142, 145, 144, 138, 134, 135, 136, 134, 140, 142, - 144, 146, 143, 142, 140, 142, 141, 148, 145, 143, 146, 145, 141, 149, 158, 159, - 154, 151, 147, 142, 139, 135, 132, 131, 130, 128, 129, 131, 136, 143, 149, 154, - 156, 154, 150, 148, 149, 153, 155, 156, 159, 160, 162, 163, 163, 165, 171, 169, - 167, 167, 168, 166, 169, 175, 176, 175, 174, 173, 176, 177, 179, 180, 179, 181, - 185, 189, 192, 192, 189, 185, 184, 180, 182, 178, 170, 176, 183, 177, 171, 165, - 161, 166, 171, 174, 176, 179, 172, 161, 154, 159, 167, 166, 159, 151, 141, 152, - 156, 152, 147, 147, 138, 127, 98, 105, 140, 132, 143, 131, 123, 120, 122, 126, - 121, 119, 130, 128, 119, 113, 106, 106, 87, 35, 22, 24, 35, 23, 30, 48, - 59, 22, 23, 22, 21, 20, 19, 17, 17, 19, 20, 20, 18, 15, 17, 20, - 21, 18, 16, 20, 20, 21, 21, 23, 24, 29, 24, 23, 30, 37, 35, 34, - 36, 39, 60, 79, 117, 119, 134, 132, 144, 130, 63, 29, 44, 53, 67, 84, - 103, 116, 118, 120, 120, 126, 133, 138, 135, 132, 131, 132, 129, 128, 126, 128, - 129, 132, 132, 133, 133, 134, 136, 138, 139, 141, 145, 144, 138, 136, 138, 139, - 138, 138, 140, 141, 142, 139, 140, 140, 142, 135, 144, 141, 140, 145, 145, 143, - 154, 158, 161, 158, 156, 153, 147, 142, 137, 133, 131, 130, 126, 125, 125, 128, - 134, 140, 143, 147, 148, 148, 150, 153, 156, 150, 151, 154, 156, 158, 158, 160, - 161, 169, 166, 168, 170, 170, 166, 168, 172, 173, 171, 171, 170, 172, 175, 180, - 182, 179, 178, 180, 186, 190, 190, 187, 184, 187, 183, 185, 183, 177, 183, 188, - 180, 171, 161, 156, 160, 165, 166, 167, 169, 171, 162, 156, 158, 161, 159, 155, - 152, 145, 153, 157, 154, 145, 140, 131, 124, 92, 112, 152, 135, 133, 114, 118, - 136, 135, 143, 130, 119, 128, 125, 112, 114, 111, 96, 73, 36, 41, 33, 39, - 34, 40, 55, 65, 20, 20, 20, 20, 20, 19, 18, 18, 23, 24, 23, 19, - 18, 19, 23, 24, 19, 18, 21, 20, 19, 18, 20, 22, 27, 21, 22, 33, - 41, 40, 37, 39, 56, 98, 104, 103, 100, 131, 133, 138, 128, 35, 55, 56, - 91, 124, 123, 135, 129, 130, 132, 132, 136, 138, 134, 127, 132, 132, 132, 132, - 129, 130, 131, 133, 134, 134, 134, 135, 136, 138, 139, 140, 136, 140, 141, 138, - 138, 143, 146, 145, 134, 133, 137, 136, 136, 136, 139, 141, 134, 141, 141, 140, - 148, 148, 149, 159, 159, 162, 164, 164, 161, 155, 146, 138, 132, 133, 132, 127, - 125, 124, 126, 131, 127, 128, 127, 129, 136, 145, 155, 160, 160, 154, 149, 148, - 151, 153, 157, 162, 162, 162, 166, 173, 176, 174, 173, 173, 172, 170, 169, 168, - 171, 177, 183, 187, 183, 181, 182, 187, 191, 191, 188, 186, 181, 179, 185, 187, - 181, 184, 182, 169, 172, 164, 162, 171, 176, 172, 167, 165, 176, 171, 168, 168, - 165, 160, 159, 159, 159, 151, 145, 148, 148, 143, 132, 126, 113, 110, 128, 115, - 135, 129, 128, 139, 136, 155, 148, 129, 127, 118, 109, 117, 108, 79, 57, 31, - 47, 24, 26, 31, 43, 54, 59, 18, 24, 25, 23, 21, 23, 22, 18, 22, - 18, 14, 16, 21, 23, 22, 18, 23, 16, 15, 16, 22, 22, 20, 17, 31, - 29, 42, 37, 34, 38, 35, 47, 82, 111, 107, 105, 107, 109, 125, 131, 121, - 54, 67, 99, 105, 116, 117, 127, 126, 128, 133, 137, 139, 138, 136, 132, 134, - 132, 133, 132, 134, 135, 135, 135, 140, 142, 143, 142, 140, 139, 140, 141, 145, - 142, 140, 139, 140, 140, 139, 136, 144, 139, 135, 131, 130, 129, 130, 132, 137, - 140, 144, 143, 142, 143, 148, 157, 161, 167, 164, 162, 137, 154, 140, 135, 130, - 133, 134, 131, 130, 133, 141, 144, 140, 142, 135, 130, 134, 134, 138, 151, 152, - 156, 157, 153, 147, 145, 150, 159, 163, 173, 176, 170, 165, 168, 173, 173, 168, - 170, 171, 170, 171, 173, 176, 180, 181, 182, 185, 188, 191, 191, 188, 185, 189, - 186, 183, 180, 176, 174, 175, 179, 168, 162, 165, 179, 185, 179, 176, 180, 164, - 168, 172, 173, 170, 167, 166, 164, 159, 147, 149, 156, 146, 139, 133, 125, 118, - 105, 129, 128, 129, 143, 138, 146, 154, 156, 147, 131, 121, 119, 116, 108, 97, - 70, 50, 29, 29, 31, 19, 35, 38, 53, 61, 20, 24, 25, 23, 23, 23, - 22, 18, 22, 22, 20, 19, 18, 20, 24, 24, 24, 22, 19, 18, 18, 20, - 22, 22, 36, 32, 43, 35, 35, 41, 37, 47, 98, 122, 113, 109, 112, 110, - 123, 122, 119, 74, 90, 104, 105, 123, 128, 129, 129, 129, 133, 137, 137, 136, - 132, 130, 132, 132, 131, 133, 134, 135, 135, 135, 136, 137, 139, 139, 138, 138, - 140, 142, 142, 140, 138, 138, 139, 139, 138, 136, 143, 139, 135, 132, 131, 130, - 131, 134, 139, 138, 140, 142, 145, 148, 149, 153, 152, 159, 152, 155, 139, 150, - 132, 131, 135, 125, 125, 133, 136, 144, 143, 130, 130, 138, 141, 142, 146, 138, - 128, 131, 143, 147, 151, 150, 147, 146, 148, 152, 162, 173, 177, 172, 169, 171, - 175, 174, 173, 173, 172, 171, 172, 172, 174, 176, 177, 181, 187, 193, 196, 197, - 196, 196, 182, 183, 184, 183, 180, 175, 172, 171, 170, 163, 166, 180, 185, 176, - 166, 163, 174, 176, 177, 173, 167, 161, 158, 155, 156, 149, 154, 159, 146, 137, - 134, 129, 110, 105, 133, 136, 138, 149, 145, 152, 148, 150, 144, 129, 121, 121, - 116, 108, 95, 58, 40, 27, 25, 28, 20, 30, 41, 55, 60, 20, 26, 27, - 22, 22, 25, 22, 19, 23, 25, 25, 22, 17, 18, 22, 28, 21, 22, 21, - 21, 18, 20, 27, 31, 32, 27, 36, 30, 31, 40, 36, 48, 111, 131, 117, - 112, 118, 115, 123, 116, 109, 90, 106, 106, 103, 125, 134, 126, 132, 132, 133, - 135, 135, 134, 130, 129, 132, 133, 134, 135, 134, 135, 136, 137, 134, 136, 138, - 138, 139, 140, 143, 146, 141, 139, 138, 138, 140, 140, 139, 137, 140, 137, 136, - 134, 133, 132, 135, 135, 140, 137, 138, 142, 148, 151, 151, 149, 146, 157, 144, - 147, 143, 142, 126, 125, 127, 119, 131, 134, 123, 133, 151, 149, 142, 148, 145, - 143, 149, 145, 137, 139, 134, 137, 142, 147, 149, 148, 146, 148, 162, 170, 174, - 173, 172, 173, 174, 173, 177, 174, 173, 172, 172, 172, 172, 171, 171, 177, 184, - 187, 185, 182, 181, 181, 181, 181, 180, 178, 174, 171, 168, 165, 169, 163, 167, - 182, 190, 185, 176, 172, 170, 171, 171, 168, 164, 161, 159, 157, 156, 153, 160, - 162, 145, 135, 131, 126, 101, 110, 138, 143, 145, 151, 148, 155, 145, 148, 141, - 127, 119, 120, 113, 102, 91, 41, 34, 32, 24, 28, 25, 31, 54, 65, 64, - 22, 26, 26, 24, 22, 25, 23, 20, 23, 23, 25, 23, 21, 19, 21, 23, - 17, 18, 20, 21, 25, 29, 33, 38, 29, 24, 36, 30, 30, 40, 38, 54, - 112, 130, 115, 115, 125, 127, 130, 120, 107, 100, 108, 110, 108, 127, 137, 127, - 132, 131, 131, 132, 132, 132, 130, 130, 135, 133, 134, 135, 136, 136, 138, 137, - 139, 141, 143, 143, 143, 145, 147, 150, 140, 139, 139, 140, 142, 142, 141, 139, - 136, 135, 134, 133, 133, 133, 136, 136, 141, 142, 142, 146, 148, 149, 148, 145, - 146, 159, 145, 144, 145, 132, 124, 123, 130, 122, 139, 145, 125, 126, 139, 135, - 149, 152, 148, 143, 153, 153, 149, 151, 137, 137, 140, 145, 150, 151, 148, 146, - 160, 166, 171, 173, 174, 173, 173, 173, 179, 176, 174, 172, 173, 174, 172, 171, - 182, 189, 196, 197, 192, 186, 185, 186, 190, 186, 178, 169, 165, 166, 166, 164, - 154, 154, 160, 173, 181, 179, 176, 176, 164, 164, 164, 162, 161, 160, 159, 157, - 160, 155, 159, 160, 144, 135, 127, 117, 98, 119, 140, 144, 147, 146, 145, 153, - 148, 147, 139, 124, 116, 114, 107, 95, 85, 31, 34, 38, 24, 30, 35, 38, - 41, 51, 49, 22, 27, 26, 23, 21, 25, 24, 21, 22, 20, 22, 23, 25, - 22, 18, 14, 20, 18, 19, 25, 34, 37, 35, 31, 30, 29, 41, 32, 28, - 36, 36, 57, 109, 131, 119, 122, 134, 137, 139, 129, 122, 111, 107, 119, 123, - 127, 132, 128, 129, 128, 128, 129, 130, 132, 133, 131, 135, 136, 136, 138, 139, - 138, 141, 139, 144, 146, 148, 148, 147, 146, 147, 148, 138, 137, 137, 138, 140, - 140, 138, 136, 134, 134, 134, 134, 136, 137, 140, 141, 144, 147, 151, 152, 149, - 146, 147, 146, 142, 154, 143, 141, 141, 126, 130, 115, 79, 70, 91, 124, 143, - 151, 149, 131, 137, 149, 153, 152, 161, 159, 148, 145, 146, 143, 141, 143, 148, - 150, 147, 146, 157, 161, 166, 170, 171, 170, 171, 172, 178, 176, 173, 172, 174, - 175, 175, 175, 177, 184, 193, 195, 192, 189, 189, 191, 192, 189, 179, 168, 164, - 166, 164, 158, 157, 164, 178, 189, 190, 184, 179, 179, 170, 168, 166, 163, 160, - 158, 155, 152, 159, 151, 151, 152, 143, 138, 128, 112, 98, 128, 140, 142, 149, - 144, 147, 155, 146, 144, 134, 121, 112, 111, 102, 88, 69, 27, 38, 41, 23, - 28, 38, 48, 58, 71, 70, 23, 27, 25, 22, 23, 25, 24, 21, 23, 19, - 18, 21, 23, 22, 15, 10, 26, 25, 25, 28, 34, 35, 29, 22, 30, 27, - 38, 29, 23, 29, 26, 43, 108, 136, 128, 133, 141, 140, 143, 134, 133, 120, - 104, 122, 131, 122, 126, 125, 127, 126, 128, 129, 131, 133, 134, 135, 135, 136, - 137, 138, 139, 140, 141, 142, 145, 146, 149, 149, 147, 144, 143, 142, 134, 134, - 134, 135, 137, 136, 134, 131, 132, 133, 134, 136, 139, 141, 144, 145, 147, 152, - 156, 154, 148, 145, 148, 149, 136, 145, 138, 135, 137, 127, 140, 95, 12, 17, - 34, 66, 101, 121, 136, 149, 143, 156, 155, 148, 153, 155, 150, 151, 150, 145, - 141, 140, 143, 145, 143, 145, 156, 157, 160, 167, 169, 168, 170, 172, 175, 176, - 176, 174, 174, 174, 177, 179, 175, 179, 184, 184, 181, 178, 177, 178, 185, 187, - 184, 176, 172, 172, 162, 150, 155, 168, 186, 200, 204, 198, 190, 186, 168, 167, - 165, 165, 165, 164, 161, 156, 154, 145, 143, 145, 140, 141, 132, 113, 97, 135, - 139, 141, 153, 146, 151, 155, 138, 138, 131, 118, 109, 105, 91, 75, 50, 26, - 39, 36, 22, 30, 40, 52, 61, 71, 71, 23, 27, 27, 22, 23, 25, 25, - 22, 24, 22, 20, 20, 19, 18, 15, 14, 30, 30, 31, 30, 31, 30, 26, - 22, 27, 19, 27, 21, 23, 30, 22, 31, 102, 136, 136, 138, 142, 137, 140, - 134, 131, 127, 106, 121, 132, 121, 131, 129, 128, 129, 131, 133, 134, 135, 135, - 135, 138, 138, 139, 140, 141, 143, 144, 142, 141, 144, 148, 150, 148, 144, 141, - 139, 136, 135, 135, 137, 137, 136, 133, 130, 136, 137, 139, 142, 146, 148, 151, - 152, 151, 152, 153, 152, 153, 152, 155, 152, 140, 138, 135, 134, 137, 130, 143, - 60, 8, 26, 24, 28, 44, 48, 68, 113, 143, 158, 155, 143, 143, 150, 155, - 162, 152, 149, 145, 143, 144, 145, 146, 147, 156, 155, 157, 165, 168, 167, 170, - 174, 173, 176, 180, 177, 171, 170, 176, 182, 191, 191, 190, 188, 185, 182, 179, - 178, 180, 185, 183, 176, 175, 176, 166, 152, 150, 154, 162, 174, 184, 188, 185, - 179, 163, 162, 162, 164, 167, 166, 162, 157, 153, 146, 144, 142, 135, 137, 131, - 114, 97, 141, 137, 140, 155, 144, 147, 148, 133, 135, 130, 118, 107, 94, 72, - 49, 38, 29, 36, 28, 27, 40, 42, 56, 76, 88, 89, 25, 27, 26, 23, - 24, 27, 27, 24, 25, 25, 25, 20, 16, 15, 17, 23, 26, 29, 29, 28, - 25, 24, 26, 28, 30, 18, 23, 22, 33, 42, 30, 35, 90, 129, 134, 139, - 139, 132, 138, 135, 127, 138, 115, 125, 137, 133, 148, 144, 135, 134, 136, 138, - 138, 138, 137, 135, 138, 138, 139, 140, 142, 141, 142, 142, 140, 145, 151, 154, - 151, 146, 142, 139, 138, 138, 138, 139, 140, 139, 135, 132, 137, 141, 144, 147, - 152, 154, 155, 157, 154, 150, 149, 149, 156, 159, 158, 154, 148, 137, 136, 138, - 138, 136, 144, 32, 7, 30, 21, 24, 50, 41, 37, 74, 121, 144, 154, 148, - 148, 150, 147, 149, 152, 151, 150, 149, 149, 149, 151, 152, 157, 154, 156, 164, - 168, 169, 171, 178, 175, 180, 185, 181, 172, 169, 175, 183, 183, 182, 180, 181, - 182, 182, 181, 180, 184, 186, 181, 172, 173, 179, 174, 161, 181, 170, 159, 160, - 173, 185, 187, 182, 168, 166, 164, 164, 163, 158, 151, 143, 156, 150, 151, 144, - 132, 133, 128, 112, 96, 143, 133, 135, 151, 135, 134, 133, 133, 134, 130, 118, - 102, 82, 52, 23, 33, 33, 35, 22, 34, 51, 46, 58, 69, 82, 86, 26, - 29, 31, 31, 32, 30, 30, 27, 32, 27, 24, 21, 20, 20, 23, 23, 21, - 20, 20, 22, 22, 24, 27, 27, 26, 27, 28, 27, 25, 25, 27, 33, 79, - 129, 132, 125, 130, 129, 138, 142, 137, 136, 124, 122, 136, 144, 147, 156, 144, - 145, 144, 144, 140, 139, 138, 137, 140, 133, 132, 136, 140, 139, 139, 141, 151, - 152, 149, 148, 146, 143, 139, 135, 128, 128, 129, 131, 135, 137, 135, 134, 139, - 143, 146, 149, 151, 152, 152, 153, 163, 158, 152, 148, 147, 149, 150, 149, 151, - 133, 139, 134, 136, 133, 123, 7, 15, 42, 31, 34, 36, 52, 41, 53, 99, - 150, 158, 143, 138, 155, 131, 148, 146, 152, 152, 147, 151, 162, 158, 146, 162, - 160, 157, 155, 161, 172, 180, 184, 188, 188, 184, 180, 175, 176, 180, 183, 183, - 187, 191, 190, 185, 180, 178, 179, 186, 183, 180, 181, 184, 180, 172, 165, 161, - 170, 168, 145, 173, 170, 176, 178, 162, 158, 163, 164, 155, 156, 160, 154, 155, - 141, 147, 144, 134, 137, 134, 108, 101, 131, 127, 116, 132, 132, 121, 131, 130, - 122, 101, 77, 59, 48, 36, 27, 32, 30, 28, 29, 36, 48, 61, 67, 78, - 73, 66, 24, 27, 28, 29, 28, 28, 28, 26, 29, 27, 27, 25, 26, 25, - 26, 26, 17, 17, 17, 19, 21, 24, 26, 27, 28, 29, 30, 29, 26, 24, - 26, 31, 77, 124, 129, 125, 130, 130, 143, 148, 147, 145, 133, 129, 142, 145, - 144, 151, 148, 151, 153, 153, 148, 142, 140, 137, 141, 135, 133, 134, 135, 134, - 131, 135, 148, 149, 149, 148, 144, 141, 138, 134, 135, 135, 138, 137, 133, 133, - 133, 138, 146, 149, 149, 150, 151, 152, 153, 154, 156, 155, 154, 154, 154, 152, - 148, 143, 141, 131, 135, 134, 140, 130, 111, 10, 31, 34, 25, 46, 54, 60, - 42, 45, 77, 153, 161, 150, 145, 149, 131, 144, 145, 151, 155, 152, 159, 167, - 164, 152, 155, 152, 153, 155, 161, 170, 178, 180, 181, 182, 180, 177, 173, 176, - 182, 188, 192, 193, 193, 190, 185, 181, 183, 184, 192, 188, 185, 185, 187, 184, - 177, 168, 160, 165, 156, 142, 166, 174, 177, 178, 164, 158, 160, 159, 150, 152, - 158, 155, 154, 143, 146, 146, 134, 135, 130, 104, 95, 125, 124, 117, 131, 125, - 109, 113, 77, 71, 61, 48, 39, 35, 31, 25, 29, 27, 27, 31, 40, 53, - 69, 77, 82, 77, 71, 24, 25, 23, 23, 23, 21, 22, 21, 21, 20, 22, - 23, 24, 22, 21, 20, 22, 24, 24, 25, 27, 29, 29, 31, 29, 31, 30, - 30, 27, 26, 29, 33, 69, 110, 120, 123, 126, 124, 139, 143, 147, 149, 139, - 135, 146, 146, 142, 146, 148, 152, 157, 158, 153, 144, 138, 133, 134, 129, 130, - 134, 137, 139, 141, 146, 147, 147, 148, 148, 145, 141, 138, 135, 129, 132, 138, - 136, 132, 133, 139, 150, 151, 152, 150, 150, 150, 151, 153, 154, 155, 154, 154, - 154, 154, 152, 148, 143, 137, 135, 139, 140, 149, 130, 95, 17, 39, 26, 25, - 58, 55, 58, 48, 49, 62, 162, 158, 149, 144, 137, 132, 143, 144, 149, 154, - 153, 160, 169, 166, 155, 151, 149, 152, 156, 161, 168, 176, 179, 177, 178, 177, - 174, 172, 176, 184, 193, 198, 196, 192, 187, 182, 180, 184, 186, 191, 187, 185, - 184, 184, 182, 178, 172, 164, 164, 145, 142, 154, 175, 172, 176, 166, 158, 158, - 154, 145, 148, 157, 155, 152, 144, 147, 145, 134, 131, 122, 103, 92, 112, 107, - 95, 100, 91, 74, 74, 57, 54, 51, 39, 36, 35, 34, 30, 28, 27, 28, - 33, 42, 56, 71, 80, 83, 80, 77, 24, 23, 21, 20, 20, 20, 21, 20, - 19, 18, 19, 19, 20, 19, 16, 18, 25, 26, 25, 27, 28, 27, 28, 27, - 30, 30, 32, 31, 30, 31, 32, 38, 59, 96, 111, 121, 123, 121, 135, 136, - 137, 140, 137, 136, 145, 145, 140, 145, 147, 151, 155, 155, 151, 144, 137, 134, - 129, 127, 128, 133, 138, 138, 142, 149, 149, 152, 153, 150, 146, 141, 137, 135, - 128, 132, 134, 134, 135, 138, 147, 155, 148, 150, 150, 151, 151, 152, 152, 152, - 157, 153, 149, 146, 147, 148, 149, 148, 137, 140, 138, 139, 150, 127, 76, 22, - 35, 28, 38, 66, 45, 51, 56, 64, 69, 172, 147, 137, 134, 125, 133, 144, - 143, 145, 148, 148, 156, 163, 164, 157, 155, 151, 153, 156, 161, 166, 174, 182, - 182, 184, 183, 178, 175, 178, 187, 196, 193, 191, 187, 182, 179, 178, 181, 183, - 186, 183, 182, 181, 181, 180, 180, 175, 169, 167, 144, 146, 142, 168, 166, 173, - 166, 158, 158, 155, 145, 148, 156, 153, 148, 143, 144, 142, 135, 129, 118, 104, - 77, 82, 71, 54, 55, 50, 44, 44, 45, 45, 40, 34, 26, 26, 24, 20, - 22, 24, 31, 38, 46, 56, 67, 74, 80, 80, 81, 25, 23, 21, 20, 20, - 18, 20, 21, 24, 21, 20, 16, 16, 16, 16, 19, 17, 20, 21, 24, 24, - 24, 26, 25, 35, 36, 35, 34, 32, 32, 33, 40, 47, 78, 98, 122, 123, - 121, 136, 132, 128, 136, 136, 137, 145, 145, 139, 143, 144, 147, 150, 151, 149, - 144, 141, 141, 136, 133, 133, 134, 135, 133, 133, 139, 153, 156, 154, 148, 141, - 135, 134, 133, 143, 141, 140, 139, 142, 143, 146, 146, 144, 149, 152, 155, 157, - 156, 154, 152, 155, 152, 148, 146, 147, 149, 150, 148, 139, 141, 133, 131, 138, - 120, 58, 18, 27, 32, 46, 68, 45, 57, 59, 56, 84, 168, 136, 129, 130, - 126, 137, 144, 146, 144, 144, 143, 149, 159, 160, 157, 158, 152, 152, 154, 156, - 161, 172, 184, 185, 186, 185, 182, 177, 181, 191, 199, 185, 184, 182, 181, 181, - 180, 179, 178, 180, 179, 180, 180, 181, 181, 181, 180, 169, 166, 149, 152, 136, - 159, 165, 175, 163, 158, 160, 160, 150, 151, 157, 152, 145, 144, 140, 138, 137, - 129, 115, 110, 55, 53, 41, 33, 35, 39, 44, 46, 34, 36, 36, 28, 25, - 24, 25, 22, 19, 24, 36, 46, 55, 62, 69, 72, 78, 81, 84, 23, 22, - 22, 21, 21, 22, 22, 23, 20, 19, 16, 15, 14, 15, 16, 17, 16, 18, - 22, 28, 32, 34, 35, 36, 36, 35, 35, 31, 28, 24, 25, 31, 37, 60, - 81, 112, 116, 117, 135, 127, 129, 138, 137, 140, 146, 143, 137, 138, 145, 147, - 148, 148, 145, 146, 146, 148, 140, 138, 139, 144, 142, 141, 145, 153, 158, 160, - 155, 147, 137, 132, 133, 133, 141, 141, 141, 146, 149, 151, 148, 146, 145, 149, - 154, 158, 159, 158, 154, 152, 147, 148, 150, 152, 154, 152, 147, 142, 143, 142, - 134, 130, 130, 123, 56, 16, 27, 35, 42, 67, 59, 68, 52, 40, 101, 153, - 132, 136, 136, 141, 142, 145, 151, 149, 146, 145, 150, 156, 158, 156, 156, 148, - 146, 150, 151, 156, 170, 186, 184, 184, 183, 182, 182, 186, 193, 198, 183, 183, - 182, 183, 185, 184, 180, 178, 178, 179, 182, 183, 183, 183, 183, 180, 166, 157, - 152, 153, 138, 153, 169, 176, 160, 157, 162, 163, 154, 154, 158, 152, 142, 143, - 139, 134, 138, 128, 116, 118, 45, 40, 36, 32, 35, 39, 41, 41, 33, 37, - 36, 30, 24, 24, 26, 26, 25, 33, 44, 56, 65, 71, 76, 78, 80, 84, - 86, 21, 20, 23, 22, 22, 23, 22, 22, 19, 20, 20, 22, 23, 23, 23, - 21, 19, 20, 25, 32, 36, 38, 39, 37, 28, 28, 27, 25, 23, 19, 22, - 30, 48, 57, 73, 107, 111, 111, 130, 119, 129, 139, 138, 141, 146, 141, 135, - 138, 143, 142, 144, 144, 144, 144, 144, 146, 138, 139, 143, 149, 152, 152, 158, - 168, 161, 163, 157, 147, 137, 134, 137, 141, 140, 145, 152, 158, 160, 160, 157, - 158, 151, 153, 157, 159, 160, 158, 156, 154, 147, 148, 151, 154, 156, 154, 149, - 143, 146, 141, 138, 134, 127, 134, 62, 16, 26, 32, 32, 61, 63, 63, 46, - 52, 124, 144, 139, 147, 137, 149, 146, 152, 155, 150, 149, 150, 154, 155, 154, - 152, 152, 144, 145, 152, 154, 158, 172, 188, 186, 184, 181, 182, 186, 190, 192, - 192, 186, 184, 183, 183, 184, 183, 180, 177, 175, 177, 181, 182, 181, 179, 179, - 176, 168, 150, 155, 149, 145, 149, 170, 167, 159, 155, 161, 163, 155, 155, 159, - 154, 145, 146, 137, 133, 138, 127, 115, 122, 45, 33, 32, 33, 29, 32, 35, - 30, 27, 29, 30, 24, 19, 20, 23, 25, 42, 46, 54, 63, 69, 73, 78, - 80, 81, 85, 86, 20, 21, 23, 25, 26, 26, 25, 25, 26, 29, 34, 38, - 41, 41, 39, 34, 25, 25, 29, 32, 36, 36, 34, 32, 33, 32, 34, 32, - 33, 32, 36, 43, 72, 71, 80, 110, 112, 113, 130, 119, 123, 133, 136, 137, - 143, 141, 133, 138, 137, 139, 142, 142, 141, 141, 139, 140, 139, 140, 142, 147, - 149, 148, 152, 161, 166, 167, 161, 151, 143, 139, 144, 150, 155, 164, 175, 179, - 174, 168, 164, 164, 158, 159, 159, 160, 159, 158, 157, 156, 154, 152, 150, 150, - 152, 153, 154, 151, 141, 134, 136, 134, 122, 138, 64, 9, 20, 30, 28, 56, - 57, 46, 43, 82, 147, 142, 145, 150, 131, 150, 147, 160, 153, 149, 150, 152, - 154, 152, 148, 144, 147, 142, 147, 157, 159, 161, 174, 193, 195, 190, 185, 186, - 190, 191, 189, 186, 189, 185, 181, 180, 181, 180, 178, 175, 173, 175, 180, 180, - 178, 174, 173, 170, 172, 147, 156, 146, 149, 146, 168, 156, 158, 154, 159, 160, - 153, 155, 160, 156, 147, 150, 137, 131, 138, 124, 113, 123, 43, 28, 24, 27, - 24, 28, 39, 36, 30, 35, 39, 37, 35, 41, 49, 53, 59, 60, 64, 66, - 69, 72, 74, 74, 81, 82, 83, 32, 34, 36, 37, 36, 33, 31, 29, 37, - 47, 44, 37, 36, 31, 28, 34, 21, 28, 34, 41, 50, 45, 44, 57, 58, - 54, 55, 57, 64, 68, 71, 73, 91, 90, 92, 100, 107, 111, 114, 118, 124, - 128, 133, 136, 136, 135, 132, 133, 135, 134, 136, 138, 140, 141, 142, 142, 143, - 141, 142, 147, 148, 146, 148, 153, 159, 161, 160, 159, 161, 159, 159, 159, 160, - 161, 166, 168, 172, 175, 174, 174, 167, 165, 162, 159, 160, 162, 166, 168, 163, - 158, 152, 148, 148, 150, 152, 151, 150, 141, 124, 133, 134, 136, 109, 10, 33, - 18, 32, 55, 51, 46, 75, 105, 141, 142, 149, 151, 152, 153, 153, 155, 146, - 151, 157, 156, 152, 148, 145, 144, 150, 149, 152, 156, 161, 166, 170, 173, 193, - 188, 183, 183, 188, 193, 194, 191, 183, 181, 178, 176, 178, 178, 176, 174, 175, - 169, 172, 176, 174, 176, 179, 171, 163, 165, 163, 154, 156, 137, 163, 167, 158, - 158, 157, 155, 157, 159, 155, 147, 146, 141, 142, 137, 139, 108, 129, 128, 49, - 32, 38, 29, 22, 33, 32, 32, 45, 47, 53, 58, 63, 63, 64, 64, 71, - 72, 70, 69, 68, 70, 72, 75, 73, 73, 73, 29, 30, 28, 27, 27, 29, - 31, 32, 26, 37, 42, 40, 39, 32, 29, 32, 39, 44, 47, 60, 79, 80, - 76, 82, 81, 87, 95, 99, 99, 94, 93, 89, 84, 82, 85, 93, 100, 104, - 112, 120, 119, 123, 129, 133, 134, 134, 133, 132, 129, 131, 134, 137, 139, 141, - 143, 143, 140, 138, 140, 145, 146, 144, 144, 149, 154, 156, 158, 158, 156, 155, - 152, 151, 156, 157, 161, 163, 168, 170, 172, 172, 174, 172, 169, 166, 165, 166, - 168, 169, 171, 170, 167, 162, 157, 153, 150, 147, 139, 137, 131, 143, 140, 138, - 117, 37, 22, 29, 45, 43, 30, 49, 105, 148, 146, 146, 151, 153, 152, 153, - 154, 157, 154, 155, 157, 155, 151, 145, 141, 140, 145, 147, 150, 153, 156, 165, - 177, 187, 188, 185, 184, 186, 192, 195, 192, 189, 183, 180, 178, 177, 178, 178, - 176, 174, 176, 169, 173, 176, 173, 174, 176, 168, 168, 166, 160, 151, 156, 142, - 172, 177, 163, 163, 161, 158, 159, 161, 156, 148, 147, 145, 138, 135, 133, 115, - 128, 123, 51, 34, 42, 41, 45, 65, 69, 71, 84, 84, 83, 83, 81, 76, - 76, 74, 75, 75, 76, 74, 75, 77, 80, 80, 79, 77, 76, 34, 35, 32, - 30, 30, 30, 33, 34, 31, 36, 44, 46, 46, 44, 45, 51, 72, 84, 87, - 94, 107, 104, 99, 105, 99, 109, 118, 115, 104, 92, 92, 89, 85, 79, 84, - 89, 93, 97, 107, 118, 114, 118, 125, 130, 132, 134, 134, 134, 129, 129, 131, - 133, 135, 137, 137, 138, 136, 134, 137, 142, 144, 141, 141, 144, 147, 149, 153, - 153, 152, 148, 144, 142, 151, 152, 155, 156, 162, 163, 167, 168, 179, 177, 175, - 173, 171, 170, 170, 170, 167, 170, 172, 169, 160, 151, 145, 141, 141, 139, 141, - 149, 138, 134, 128, 81, 59, 57, 52, 43, 53, 97, 141, 153, 148, 150, 156, - 161, 162, 162, 163, 163, 165, 162, 157, 152, 147, 143, 139, 137, 154, 155, 156, - 152, 151, 159, 174, 185, 181, 182, 184, 190, 195, 194, 190, 186, 180, 178, 178, - 177, 177, 176, 176, 174, 175, 168, 173, 175, 170, 171, 171, 163, 170, 167, 162, - 155, 163, 148, 174, 175, 161, 161, 158, 155, 156, 157, 151, 143, 144, 149, 133, - 134, 124, 124, 129, 120, 57, 35, 42, 47, 58, 79, 82, 85, 83, 84, 83, - 82, 80, 76, 77, 74, 78, 78, 78, 79, 78, 80, 83, 84, 76, 74, 74, - 20, 25, 27, 30, 32, 33, 35, 35, 54, 50, 54, 58, 59, 65, 76, 86, - 101, 118, 119, 114, 108, 99, 96, 108, 97, 101, 105, 98, 87, 84, 89, 89, - 91, 84, 88, 91, 90, 92, 102, 114, 111, 117, 123, 128, 130, 132, 133, 133, - 133, 131, 132, 132, 132, 132, 131, 131, 133, 132, 135, 140, 142, 139, 138, 140, - 142, 143, 145, 145, 145, 144, 142, 140, 149, 149, 149, 152, 155, 160, 165, 166, - 174, 173, 173, 172, 171, 169, 168, 167, 176, 183, 189, 188, 181, 173, 170, 168, - 158, 148, 145, 145, 132, 130, 134, 118, 120, 106, 95, 93, 114, 153, 166, 145, - 147, 152, 160, 168, 172, 172, 171, 170, 168, 162, 153, 148, 145, 143, 139, 136, - 157, 155, 152, 150, 151, 158, 171, 182, 182, 183, 186, 191, 192, 192, 187, 183, - 180, 178, 178, 178, 177, 176, 176, 173, 174, 168, 173, 176, 170, 171, 171, 163, - 169, 169, 168, 165, 172, 150, 166, 159, 158, 158, 156, 153, 153, 154, 149, 140, - 135, 152, 132, 135, 117, 132, 134, 124, 58, 32, 39, 48, 62, 80, 78, 79, - 85, 86, 85, 82, 84, 83, 84, 84, 79, 78, 78, 77, 75, 76, 78, 79, - 68, 69, 71, 48, 51, 54, 59, 68, 75, 81, 85, 70, 58, 65, 72, 69, - 75, 89, 95, 100, 110, 107, 99, 101, 99, 96, 103, 96, 96, 97, 96, 95, - 99, 110, 110, 92, 85, 89, 92, 91, 92, 100, 112, 113, 117, 122, 126, 128, - 130, 131, 132, 132, 130, 131, 131, 131, 130, 129, 129, 136, 134, 136, 141, 142, - 139, 139, 139, 140, 139, 139, 139, 140, 139, 141, 142, 146, 148, 148, 151, 154, - 159, 164, 165, 166, 167, 168, 169, 169, 168, 167, 167, 161, 167, 173, 173, 168, - 164, 165, 166, 165, 151, 148, 143, 133, 134, 136, 138, 147, 147, 157, 163, 163, - 170, 178, 168, 157, 155, 156, 158, 164, 169, 172, 174, 164, 158, 151, 146, 143, - 142, 139, 136, 144, 141, 139, 144, 155, 167, 178, 184, 187, 188, 188, 190, 188, - 187, 182, 180, 179, 178, 176, 176, 178, 177, 173, 171, 173, 167, 172, 176, 171, - 172, 172, 163, 166, 167, 167, 165, 171, 147, 161, 152, 160, 160, 158, 155, 156, - 157, 152, 143, 129, 151, 134, 136, 118, 135, 139, 130, 57, 30, 39, 54, 72, - 91, 85, 84, 95, 94, 91, 85, 85, 81, 81, 80, 81, 81, 79, 78, 75, - 72, 73, 72, 67, 71, 75, 62, 58, 53, 51, 53, 63, 72, 78, 71, 55, - 68, 80, 71, 71, 79, 74, 76, 77, 67, 73, 97, 111, 106, 102, 101, 103, - 104, 105, 108, 109, 112, 106, 87, 81, 84, 89, 91, 91, 97, 106, 112, 117, - 121, 124, 126, 128, 129, 129, 127, 126, 128, 130, 131, 132, 132, 132, 137, 134, - 134, 138, 139, 137, 138, 139, 138, 137, 136, 134, 135, 136, 139, 141, 143, 143, - 146, 148, 154, 156, 159, 163, 162, 163, 165, 166, 167, 168, 168, 168, 172, 175, - 176, 175, 172, 171, 173, 174, 157, 148, 153, 147, 143, 145, 137, 144, 144, 149, - 167, 180, 174, 172, 182, 184, 170, 160, 150, 144, 148, 156, 165, 171, 158, 155, - 152, 149, 145, 143, 141, 139, 143, 137, 134, 140, 154, 168, 175, 177, 190, 190, - 190, 189, 185, 184, 180, 179, 179, 178, 177, 177, 179, 177, 173, 170, 172, 167, - 172, 175, 170, 170, 169, 160, 161, 161, 160, 155, 162, 143, 163, 161, 159, 159, - 156, 153, 153, 154, 148, 139, 129, 146, 135, 134, 126, 135, 142, 131, 63, 36, - 45, 61, 77, 92, 84, 86, 90, 92, 86, 83, 81, 79, 77, 77, 82, 81, - 81, 78, 75, 72, 72, 71, 72, 77, 80, 81, 74, 69, 62, 59, 61, 63, - 65, 66, 46, 59, 74, 61, 60, 69, 57, 56, 61, 59, 65, 89, 101, 98, - 95, 95, 97, 98, 97, 95, 90, 88, 84, 86, 83, 84, 90, 94, 91, 93, - 98, 109, 112, 118, 121, 121, 124, 127, 128, 125, 125, 127, 129, 132, 133, 133, - 133, 137, 133, 132, 135, 135, 134, 136, 139, 137, 134, 134, 132, 133, 134, 135, - 134, 136, 139, 143, 146, 152, 153, 155, 155, 160, 160, 161, 162, 163, 165, 166, - 167, 164, 163, 161, 160, 158, 158, 158, 157, 152, 150, 160, 148, 146, 150, 136, - 150, 146, 142, 151, 163, 169, 177, 181, 171, 167, 158, 150, 144, 148, 153, 158, - 160, 154, 156, 157, 155, 149, 145, 141, 141, 148, 142, 138, 141, 149, 161, 169, - 173, 188, 189, 190, 190, 186, 183, 180, 179, 178, 177, 177, 177, 177, 175, 173, - 169, 172, 166, 172, 174, 167, 165, 162, 152, 152, 155, 157, 153, 159, 141, 164, - 165, 160, 159, 155, 150, 149, 148, 141, 132, 137, 140, 131, 129, 138, 134, 140, - 122, 72, 39, 46, 59, 71, 83, 79, 81, 91, 94, 93, 92, 89, 89, 88, - 88, 81, 80, 79, 76, 73, 70, 70, 71, 75, 79, 81, 69, 70, 71, 70, - 69, 64, 60, 56, 66, 40, 51, 67, 52, 54, 71, 60, 57, 74, 82, 80, - 84, 84, 85, 91, 85, 88, 92, 91, 89, 86, 90, 93, 94, 89, 90, 95, - 96, 92, 90, 91, 106, 109, 113, 116, 119, 123, 127, 128, 130, 129, 130, 131, - 131, 131, 131, 131, 137, 132, 130, 132, 132, 130, 135, 138, 133, 132, 133, 133, - 133, 132, 129, 128, 132, 135, 140, 144, 147, 148, 150, 149, 154, 153, 155, 154, - 157, 158, 160, 161, 166, 164, 162, 161, 161, 161, 160, 156, 156, 157, 166, 145, - 140, 149, 136, 156, 150, 151, 156, 159, 162, 173, 175, 161, 159, 155, 156, 157, - 159, 159, 155, 151, 153, 158, 161, 160, 153, 147, 143, 143, 142, 141, 140, 140, - 147, 158, 171, 181, 182, 185, 190, 189, 188, 185, 180, 179, 178, 177, 179, 177, - 179, 177, 173, 169, 173, 166, 171, 172, 164, 160, 157, 146, 143, 151, 159, 158, - 163, 140, 161, 160, 166, 164, 160, 153, 150, 147, 140, 131, 142, 133, 128, 123, - 145, 131, 138, 113, 70, 38, 46, 60, 75, 93, 92, 99, 96, 97, 98, 96, - 94, 91, 90, 87, 85, 86, 84, 82, 77, 73, 73, 73, 72, 74, 76, 73, - 72, 70, 69, 67, 66, 68, 67, 73, 59, 57, 88, 75, 89, 83, 73, 76, - 76, 76, 79, 84, 90, 93, 94, 97, 99, 97, 93, 93, 100, 102, 99, 101, - 98, 95, 95, 98, 99, 96, 93, 94, 104, 111, 113, 116, 123, 127, 125, 129, - 124, 124, 127, 130, 130, 130, 130, 131, 130, 128, 127, 129, 130, 135, 136, 135, - 132, 131, 130, 131, 131, 131, 131, 135, 136, 139, 142, 143, 144, 144, 143, 150, - 150, 151, 150, 151, 149, 148, 147, 155, 154, 152, 152, 155, 157, 160, 160, 160, - 155, 150, 151, 153, 153, 149, 146, 155, 153, 151, 159, 168, 172, 164, 158, 154, - 153, 153, 156, 161, 163, 162, 160, 155, 154, 151, 149, 146, 144, 142, 141, 151, - 141, 134, 139, 147, 151, 162, 176, 176, 182, 189, 189, 184, 179, 179, 181, 181, - 180, 181, 178, 179, 177, 173, 169, 173, 172, 175, 172, 159, 153, 146, 131, 143, - 151, 148, 147, 159, 163, 159, 160, 165, 156, 151, 146, 143, 140, 140, 139, 133, - 152, 94, 137, 129, 143, 138, 127, 66, 51, 51, 70, 85, 91, 105, 120, 109, - 105, 108, 101, 109, 113, 99, 107, 103, 94, 98, 97, 87, 82, 78, 67, 73, - 72, 76, 63, 64, 66, 68, 69, 71, 70, 69, 68, 67, 68, 76, 65, 73, - 76, 77, 76, 78, 78, 79, 83, 89, 93, 93, 100, 103, 104, 99, 99, 101, - 102, 96, 100, 99, 102, 106, 109, 106, 98, 92, 94, 107, 114, 110, 109, 116, - 127, 135, 133, 131, 130, 132, 134, 134, 131, 130, 130, 129, 127, 126, 126, 129, - 132, 132, 133, 131, 130, 129, 131, 132, 132, 133, 133, 133, 137, 139, 140, 141, - 141, 141, 145, 146, 147, 148, 149, 149, 151, 150, 150, 150, 150, 152, 157, 161, - 165, 165, 162, 157, 153, 154, 157, 157, 154, 150, 156, 153, 152, 157, 165, 167, - 163, 160, 162, 162, 161, 162, 162, 163, 161, 159, 159, 158, 156, 154, 151, 149, - 148, 148, 146, 141, 137, 140, 146, 154, 167, 176, 179, 183, 187, 186, 183, 180, - 180, 182, 184, 182, 181, 180, 179, 177, 173, 169, 170, 166, 169, 166, 156, 154, - 151, 138, 142, 152, 150, 145, 151, 153, 152, 157, 159, 152, 146, 144, 141, 138, - 132, 128, 128, 136, 111, 137, 142, 138, 132, 115, 58, 44, 47, 72, 92, 97, - 104, 110, 106, 102, 119, 116, 114, 119, 113, 118, 117, 105, 99, 93, 81, 83, - 89, 82, 71, 70, 75, 69, 72, 75, 77, 78, 78, 76, 74, 74, 79, 74, - 59, 68, 72, 80, 82, 82, 83, 83, 83, 85, 85, 89, 93, 91, 95, 99, - 100, 102, 105, 104, 99, 98, 98, 102, 106, 109, 107, 101, 96, 96, 104, 110, - 110, 113, 119, 128, 132, 133, 133, 131, 132, 135, 136, 133, 131, 130, 129, 126, - 125, 125, 127, 130, 131, 130, 128, 128, 129, 130, 131, 134, 135, 133, 134, 136, - 138, 139, 140, 140, 140, 140, 141, 143, 145, 148, 149, 152, 152, 151, 151, 151, - 153, 158, 162, 165, 165, 160, 156, 154, 155, 157, 158, 156, 153, 154, 153, 153, - 156, 162, 164, 164, 165, 170, 170, 166, 165, 164, 163, 160, 158, 158, 157, 155, - 152, 150, 148, 146, 146, 143, 147, 145, 142, 147, 159, 172, 177, 182, 184, 186, - 184, 182, 180, 182, 184, 185, 183, 182, 181, 180, 177, 173, 169, 166, 164, 169, - 168, 159, 157, 152, 137, 136, 148, 147, 142, 148, 152, 155, 165, 158, 154, 149, - 148, 145, 141, 133, 125, 131, 122, 126, 133, 148, 133, 124, 112, 45, 33, 37, - 64, 89, 98, 104, 109, 100, 94, 125, 127, 112, 117, 118, 119, 122, 109, 102, - 95, 84, 88, 98, 94, 80, 74, 75, 66, 66, 71, 74, 76, 79, 80, 79, - 79, 83, 70, 41, 76, 81, 86, 77, 83, 85, 87, 88, 86, 85, 88, 93, - 90, 96, 99, 98, 102, 106, 106, 101, 99, 96, 96, 96, 99, 101, 102, 103, - 97, 97, 100, 109, 123, 130, 127, 122, 126, 128, 130, 129, 132, 136, 136, 130, - 130, 129, 128, 125, 125, 126, 128, 128, 124, 122, 125, 124, 128, 131, 133, 134, - 136, 136, 137, 138, 139, 138, 138, 138, 136, 138, 140, 143, 145, 146, 149, 150, - 154, 154, 153, 153, 155, 156, 158, 156, 155, 152, 151, 152, 154, 155, 154, 152, - 153, 154, 155, 155, 158, 161, 164, 168, 173, 173, 169, 166, 164, 162, 160, 158, - 159, 158, 155, 151, 148, 145, 143, 142, 147, 155, 154, 147, 149, 163, 175, 176, - 184, 185, 185, 182, 181, 181, 183, 185, 185, 184, 182, 181, 180, 177, 172, 169, - 166, 166, 173, 174, 165, 160, 149, 130, 141, 150, 147, 143, 152, 158, 161, 168, - 154, 155, 153, 148, 142, 140, 135, 129, 137, 117, 129, 130, 136, 132, 122, 117, - 44, 33, 35, 56, 78, 90, 103, 111, 100, 91, 124, 128, 107, 116, 122, 116, - 119, 111, 112, 108, 97, 99, 102, 95, 86, 78, 76, 49, 48, 52, 56, 62, - 70, 75, 78, 76, 84, 71, 38, 71, 74, 79, 70, 74, 75, 80, 87, 88, - 87, 88, 94, 101, 104, 100, 96, 96, 99, 99, 95, 96, 94, 94, 94, 97, - 99, 101, 103, 95, 95, 99, 107, 118, 124, 126, 127, 127, 129, 131, 130, 133, - 136, 134, 128, 133, 130, 129, 128, 128, 128, 127, 128, 124, 122, 125, 125, 130, - 133, 135, 137, 142, 142, 142, 142, 141, 140, 138, 138, 138, 139, 141, 143, 145, - 145, 148, 148, 156, 156, 155, 154, 155, 155, 154, 152, 152, 150, 150, 150, 152, - 152, 153, 152, 153, 154, 155, 155, 157, 159, 163, 169, 169, 169, 167, 164, 161, - 159, 159, 159, 164, 162, 159, 155, 151, 147, 144, 145, 148, 156, 155, 149, 153, - 167, 177, 176, 185, 185, 183, 181, 181, 181, 183, 185, 185, 183, 181, 180, 179, - 175, 171, 167, 168, 165, 168, 168, 161, 159, 152, 134, 151, 155, 147, 144, 158, - 164, 160, 161, 146, 151, 150, 141, 131, 131, 133, 132, 135, 119, 128, 136, 126, - 137, 120, 110, 43, 38, 43, 59, 71, 77, 85, 95, 107, 89, 116, 119, 103, - 114, 119, 109, 112, 107, 110, 108, 98, 95, 100, 90, 86, 79, 79, 55, 52, - 52, 52, 54, 59, 63, 66, 68, 84, 80, 51, 50, 53, 64, 65, 60, 61, - 68, 83, 91, 88, 87, 90, 89, 90, 89, 84, 85, 90, 93, 89, 91, 93, - 98, 101, 103, 101, 100, 100, 94, 99, 106, 107, 105, 106, 120, 136, 129, 135, - 136, 131, 133, 138, 135, 125, 133, 132, 131, 128, 127, 127, 127, 126, 125, 125, - 127, 128, 131, 134, 137, 139, 142, 142, 142, 142, 141, 139, 138, 137, 141, 142, - 144, 145, 146, 146, 148, 148, 154, 154, 154, 155, 157, 158, 158, 156, 153, 152, - 152, 152, 152, 153, 154, 154, 154, 155, 155, 155, 157, 158, 161, 166, 164, 165, - 163, 160, 157, 156, 158, 160, 161, 159, 157, 154, 150, 147, 144, 145, 146, 149, - 148, 150, 158, 170, 178, 179, 185, 183, 181, 180, 181, 181, 182, 182, 184, 182, - 180, 179, 177, 174, 169, 165, 169, 160, 157, 155, 152, 159, 161, 149, 143, 147, - 142, 145, 164, 172, 165, 163, 149, 154, 150, 137, 128, 131, 135, 134, 123, 121, - 129, 147, 133, 140, 123, 87, 34, 39, 54, 72, 82, 83, 85, 91, 105, 90, - 106, 106, 100, 112, 110, 105, 106, 101, 100, 97, 84, 86, 94, 87, 88, 80, - 81, 71, 68, 66, 64, 62, 64, 64, 65, 73, 83, 79, 64, 37, 46, 59, - 63, 60, 57, 65, 83, 95, 89, 82, 82, 76, 80, 83, 82, 85, 92, 96, - 93, 92, 95, 100, 102, 103, 101, 101, 101, 98, 100, 105, 109, 108, 104, 111, - 121, 123, 131, 133, 131, 134, 140, 138, 128, 133, 131, 130, 129, 128, 127, 127, - 124, 125, 123, 127, 127, 130, 133, 135, 137, 139, 140, 140, 140, 140, 140, 139, - 139, 139, 140, 141, 143, 144, 145, 147, 147, 149, 150, 152, 154, 157, 158, 159, - 157, 154, 154, 154, 153, 153, 152, 153, 154, 156, 155, 155, 155, 158, 159, 160, - 162, 162, 162, 161, 157, 153, 152, 156, 159, 155, 154, 153, 151, 152, 150, 149, - 148, 153, 148, 146, 154, 166, 174, 179, 182, 183, 182, 180, 179, 181, 181, 180, - 180, 183, 181, 179, 177, 175, 172, 167, 163, 164, 156, 154, 155, 156, 166, 170, - 158, 136, 145, 145, 150, 167, 174, 166, 165, 158, 158, 150, 136, 131, 137, 135, - 127, 121, 127, 138, 144, 143, 132, 133, 65, 27, 34, 53, 76, 91, 96, 97, - 98, 100, 92, 101, 98, 101, 110, 103, 106, 104, 100, 102, 97, 87, 89, 100, - 97, 94, 86, 83, 68, 67, 69, 71, 74, 76, 76, 77, 85, 78, 67, 68, - 37, 57, 63, 60, 69, 62, 70, 89, 98, 89, 78, 73, 85, 90, 94, 94, - 96, 100, 100, 95, 98, 97, 97, 95, 95, 97, 102, 106, 105, 96, 97, 111, - 123, 118, 103, 95, 113, 122, 127, 126, 132, 143, 143, 132, 132, 131, 130, 127, - 126, 125, 124, 124, 123, 121, 124, 124, 127, 128, 131, 132, 135, 136, 138, 138, - 139, 140, 140, 140, 133, 134, 136, 139, 140, 142, 144, 145, 147, 148, 149, 151, - 154, 155, 155, 153, 153, 153, 154, 153, 151, 150, 152, 153, 157, 156, 154, 155, - 159, 160, 158, 156, 160, 162, 161, 156, 152, 151, 154, 157, 155, 155, 155, 155, - 157, 157, 157, 159, 167, 153, 149, 161, 174, 177, 179, 183, 182, 180, 179, 179, - 181, 181, 179, 178, 182, 180, 178, 176, 174, 171, 166, 162, 160, 155, 160, 166, - 168, 175, 173, 157, 146, 158, 159, 159, 167, 166, 155, 154, 160, 156, 143, 131, - 131, 137, 129, 113, 125, 131, 144, 134, 150, 121, 143, 51, 33, 35, 47, 67, - 84, 93, 94, 92, 94, 93, 101, 95, 103, 108, 97, 110, 103, 102, 109, 110, - 100, 102, 109, 104, 95, 85, 82, 74, 71, 64, 59, 61, 68, 72, 69, 76, - 71, 72, 87, 72, 51, 63, 65, 72, 84, 87, 88, 94, 88, 81, 86, 88, - 90, 92, 91, 90, 92, 98, 101, 99, 95, 103, 105, 97, 96, 100, 95, 100, - 97, 100, 110, 121, 122, 119, 119, 99, 115, 119, 121, 137, 144, 138, 135, 133, - 135, 140, 140, 138, 136, 136, 138, 131, 129, 130, 127, 127, 127, 132, 136, 133, - 133, 136, 139, 140, 140, 139, 138, 144, 140, 138, 139, 139, 138, 142, 146, 144, - 142, 146, 152, 154, 149, 150, 153, 152, 152, 154, 154, 153, 151, 149, 147, 154, - 155, 155, 155, 157, 156, 155, 155, 153, 154, 154, 154, 155, 157, 160, 163, 164, - 163, 159, 153, 157, 162, 157, 148, 154, 147, 148, 161, 175, 178, 178, 179, 182, - 183, 184, 184, 185, 182, 179, 178, 178, 179, 180, 177, 171, 167, 166, 167, 159, - 165, 170, 176, 159, 156, 164, 135, 155, 156, 156, 160, 167, 172, 169, 164, 154, - 144, 142, 126, 125, 135, 122, 117, 134, 141, 135, 145, 163, 111, 145, 52, 38, - 36, 52, 72, 78, 86, 91, 87, 78, 82, 89, 94, 100, 106, 105, 101, 103, - 103, 102, 104, 105, 104, 103, 99, 90, 86, 84, 80, 78, 71, 63, 60, 60, - 58, 51, 64, 59, 56, 68, 60, 52, 71, 71, 73, 75, 69, 66, 77, 78, - 75, 81, 75, 77, 82, 83, 88, 90, 97, 98, 95, 91, 98, 100, 94, 95, - 100, 96, 103, 102, 99, 98, 108, 120, 123, 122, 118, 122, 112, 104, 112, 118, - 125, 137, 142, 143, 144, 140, 137, 135, 136, 138, 135, 135, 136, 131, 129, 128, - 132, 133, 129, 130, 131, 134, 135, 136, 137, 137, 140, 136, 136, 138, 139, 137, - 141, 145, 147, 145, 148, 153, 155, 151, 152, 156, 151, 151, 153, 153, 152, 150, - 149, 147, 154, 155, 155, 154, 156, 154, 153, 152, 153, 154, 154, 153, 154, 155, - 158, 161, 160, 159, 156, 151, 156, 162, 163, 159, 149, 149, 157, 169, 175, 175, - 176, 180, 180, 181, 182, 182, 183, 180, 178, 176, 177, 175, 173, 171, 170, 168, - 165, 162, 163, 183, 161, 166, 184, 156, 143, 159, 162, 160, 160, 166, 171, 172, - 167, 163, 158, 145, 142, 127, 122, 129, 118, 120, 135, 133, 138, 139, 124, 128, - 123, 39, 38, 38, 56, 72, 77, 80, 86, 82, 76, 80, 85, 86, 90, 96, - 96, 93, 92, 91, 90, 92, 94, 92, 91, 88, 88, 85, 85, 77, 77, 75, - 71, 71, 70, 64, 57, 59, 58, 52, 61, 60, 60, 75, 66, 72, 71, 61, - 59, 71, 74, 72, 77, 77, 77, 82, 85, 92, 94, 98, 96, 94, 90, 95, - 96, 91, 93, 99, 96, 93, 100, 102, 99, 106, 119, 124, 122, 126, 130, 123, - 115, 117, 113, 114, 124, 123, 130, 140, 147, 148, 147, 144, 142, 138, 137, 137, - 133, 130, 128, 130, 131, 128, 126, 126, 127, 129, 132, 133, 134, 135, 132, 133, - 137, 138, 136, 139, 143, 147, 146, 148, 150, 152, 150, 153, 156, 150, 150, 151, - 151, 150, 149, 148, 146, 153, 153, 153, 153, 154, 152, 151, 150, 150, 151, 151, - 149, 150, 150, 155, 157, 152, 154, 156, 155, 156, 159, 162, 159, 145, 153, 166, - 176, 176, 172, 175, 181, 181, 181, 182, 181, 182, 180, 178, 176, 183, 178, 173, - 171, 171, 170, 164, 159, 167, 174, 175, 183, 170, 155, 166, 162, 169, 164, 166, - 175, 178, 171, 163, 163, 161, 145, 142, 127, 119, 122, 115, 126, 144, 146, 145, - 145, 129, 154, 84, 49, 38, 48, 63, 74, 79, 81, 84, 82, 72, 72, 73, - 74, 79, 85, 84, 83, 83, 82, 81, 82, 84, 83, 82, 82, 81, 81, 80, - 71, 75, 77, 76, 77, 81, 78, 73, 69, 74, 70, 77, 77, 74, 76, 49, - 71, 79, 77, 79, 87, 86, 80, 83, 91, 88, 90, 91, 97, 95, 93, 88, - 96, 90, 93, 93, 88, 91, 98, 94, 92, 96, 99, 97, 98, 106, 119, 132, - 132, 137, 134, 134, 135, 121, 113, 121, 115, 118, 124, 130, 135, 136, 138, 139, - 136, 136, 136, 134, 133, 132, 135, 136, 130, 129, 126, 124, 125, 127, 129, 131, - 130, 129, 130, 136, 137, 136, 138, 141, 145, 145, 145, 145, 146, 147, 150, 152, - 148, 148, 148, 148, 148, 147, 146, 146, 149, 150, 150, 150, 152, 151, 151, 150, - 149, 150, 149, 148, 148, 148, 152, 155, 146, 152, 159, 159, 156, 152, 150, 148, - 150, 159, 170, 176, 175, 173, 176, 180, 183, 183, 183, 183, 183, 182, 180, 179, - 183, 180, 175, 171, 167, 164, 160, 157, 158, 178, 193, 184, 151, 159, 188, 161, - 172, 166, 169, 180, 181, 170, 162, 164, 160, 143, 140, 125, 115, 118, 117, 135, - 139, 148, 126, 138, 151, 139, 39, 54, 40, 57, 72, 78, 82, 83, 85, 88, - 79, 78, 78, 77, 81, 89, 90, 89, 95, 95, 94, 95, 98, 99, 99, 100, - 98, 99, 97, 74, 76, 76, 72, 71, 73, 72, 69, 77, 83, 80, 86, 86, - 83, 79, 47, 76, 89, 94, 94, 97, 91, 86, 93, 95, 92, 91, 91, 93, - 90, 85, 79, 91, 84, 86, 87, 85, 90, 97, 93, 102, 95, 90, 88, 82, - 81, 102, 130, 147, 146, 134, 127, 131, 128, 126, 133, 135, 128, 117, 108, 107, - 112, 120, 126, 131, 132, 134, 132, 132, 133, 137, 138, 132, 131, 126, 125, 123, - 124, 126, 127, 128, 126, 128, 134, 136, 134, 137, 140, 142, 144, 144, 142, 143, - 145, 148, 148, 146, 145, 146, 146, 145, 145, 145, 145, 146, 146, 148, 149, 151, - 152, 151, 151, 146, 147, 148, 147, 147, 147, 151, 153, 150, 153, 156, 156, 155, - 151, 151, 151, 160, 164, 168, 170, 173, 176, 178, 179, 182, 182, 182, 181, 182, - 180, 179, 178, 173, 175, 175, 169, 161, 157, 158, 161, 166, 201, 175, 153, 166, - 168, 170, 172, 169, 167, 171, 181, 182, 172, 164, 164, 156, 141, 138, 122, 113, - 120, 124, 143, 146, 143, 124, 141, 150, 117, 69, 51, 38, 62, 75, 76, 84, - 85, 84, 93, 75, 75, 72, 71, 71, 78, 78, 75, 85, 85, 84, 85, 90, - 93, 92, 93, 95, 98, 98, 72, 76, 76, 71, 69, 72, 74, 73, 80, 81, - 74, 81, 84, 85, 88, 62, 81, 95, 96, 92, 92, 87, 89, 100, 91, 90, - 91, 91, 91, 87, 86, 82, 83, 75, 78, 82, 82, 89, 96, 92, 92, 90, - 93, 96, 89, 76, 75, 84, 129, 140, 137, 133, 137, 139, 136, 140, 138, 134, - 129, 126, 122, 120, 117, 117, 121, 123, 125, 125, 125, 125, 128, 131, 132, 129, - 124, 123, 121, 122, 123, 124, 126, 124, 125, 129, 131, 130, 133, 137, 141, 144, - 145, 142, 143, 146, 148, 146, 144, 143, 143, 143, 143, 143, 144, 144, 145, 146, - 147, 148, 151, 151, 151, 151, 145, 145, 147, 146, 146, 147, 151, 154, 160, 153, - 150, 148, 151, 154, 161, 168, 169, 168, 166, 166, 170, 177, 179, 176, 179, 178, - 177, 176, 177, 176, 175, 175, 169, 174, 177, 172, 163, 160, 166, 173, 200, 180, - 147, 157, 174, 167, 169, 166, 167, 170, 175, 179, 179, 174, 168, 164, 152, 142, - 138, 117, 111, 127, 132, 146, 162, 137, 138, 150, 126, 114, 142, 55, 39, 68, - 76, 73, 85, 85, 82, 93, 75, 73, 70, 65, 64, 66, 66, 62, 68, 68, - 66, 69, 71, 74, 75, 75, 76, 80, 82, 71, 74, 77, 75, 76, 79, 81, - 81, 80, 76, 67, 78, 81, 82, 92, 76, 83, 92, 90, 85, 86, 83, 84, - 95, 86, 86, 89, 90, 90, 87, 89, 90, 84, 77, 80, 83, 83, 89, 94, - 88, 82, 92, 98, 98, 100, 93, 67, 41, 73, 112, 137, 142, 149, 150, 140, - 136, 132, 135, 139, 145, 147, 142, 131, 125, 122, 124, 125, 123, 122, 120, 120, - 122, 124, 121, 119, 119, 117, 119, 120, 121, 124, 121, 121, 124, 125, 125, 129, - 133, 137, 142, 144, 141, 141, 145, 145, 141, 143, 142, 141, 141, 141, 141, 143, - 143, 148, 149, 149, 149, 150, 149, 148, 148, 144, 144, 145, 144, 145, 148, 153, - 155, 160, 150, 146, 148, 156, 159, 166, 172, 170, 171, 168, 165, 169, 176, 178, - 174, 177, 177, 175, 174, 175, 174, 173, 173, 172, 174, 175, 171, 165, 163, 167, - 172, 188, 149, 148, 184, 177, 168, 181, 157, 167, 177, 181, 177, 175, 177, 171, - 162, 150, 145, 140, 114, 110, 134, 138, 145, 145, 132, 134, 140, 121, 118, 146, - 67, 49, 77, 78, 70, 87, 87, 80, 94, 91, 92, 90, 87, 87, 88, 87, - 83, 85, 84, 81, 82, 83, 85, 86, 85, 86, 90, 90, 74, 78, 82, 80, - 77, 77, 77, 76, 84, 78, 72, 87, 87, 83, 90, 77, 82, 89, 87, 85, - 90, 86, 80, 85, 79, 83, 87, 87, 86, 84, 88, 91, 94, 86, 87, 89, - 86, 89, 91, 83, 95, 103, 94, 78, 90, 106, 82, 39, 27, 84, 123, 133, - 140, 147, 143, 140, 145, 141, 135, 134, 137, 139, 141, 140, 136, 137, 137, 135, - 129, 127, 125, 125, 118, 117, 115, 117, 117, 119, 119, 120, 126, 121, 119, 122, - 123, 123, 127, 132, 132, 139, 142, 138, 138, 141, 141, 137, 142, 142, 141, 141, - 141, 142, 144, 145, 154, 153, 153, 152, 150, 148, 148, 145, 145, 144, 144, 146, - 145, 148, 154, 157, 153, 147, 146, 156, 163, 163, 162, 162, 168, 172, 172, 167, - 168, 174, 176, 173, 179, 178, 176, 175, 173, 173, 175, 175, 170, 168, 165, 160, - 156, 154, 155, 156, 127, 160, 167, 186, 200, 177, 166, 167, 169, 183, 186, 176, - 173, 179, 174, 160, 150, 148, 142, 112, 109, 138, 142, 142, 135, 150, 134, 142, - 160, 141, 118, 106, 61, 91, 87, 76, 92, 92, 81, 93, 87, 89, 90, 87, - 90, 94, 93, 87, 90, 87, 84, 82, 82, 83, 83, 84, 90, 91, 91, 72, - 74, 76, 78, 77, 76, 76, 79, 78, 78, 78, 80, 80, 80, 80, 82, 74, - 83, 82, 81, 84, 80, 77, 84, 69, 76, 79, 77, 79, 85, 90, 89, 87, - 89, 93, 92, 88, 87, 90, 93, 93, 96, 97, 84, 95, 91, 91, 45, 15, - 39, 73, 109, 133, 142, 142, 138, 145, 145, 143, 143, 144, 145, 143, 140, 132, - 130, 130, 131, 136, 138, 135, 133, 135, 136, 135, 128, 119, 112, 109, 107, 118, - 120, 124, 128, 128, 126, 121, 117, 130, 132, 134, 139, 138, 134, 136, 143, 143, - 147, 145, 141, 142, 148, 151, 151, 148, 149, 152, 153, 152, 148, 145, 140, 146, - 143, 141, 143, 146, 150, 148, 147, 127, 142, 158, 164, 162, 163, 167, 171, 171, - 170, 169, 171, 173, 175, 176, 175, 178, 175, 171, 169, 170, 170, 171, 170, 172, - 168, 161, 155, 153, 150, 144, 137, 160, 154, 173, 184, 172, 176, 178, 153, 170, - 182, 191, 188, 179, 171, 164, 160, 136, 143, 147, 132, 107, 142, 142, 145, 157, - 141, 140, 153, 154, 140, 128, 127, 77, 92, 81, 85, 88, 76, 83, 82, 89, - 88, 94, 93, 83, 84, 83, 72, 83, 79, 77, 78, 79, 78, 75, 78, 83, - 89, 87, 77, 78, 79, 77, 74, 73, 75, 77, 78, 77, 78, 77, 76, 76, - 78, 79, 78, 86, 85, 83, 87, 84, 80, 87, 81, 84, 82, 74, 70, 73, - 75, 74, 77, 80, 84, 84, 83, 83, 88, 90, 91, 90, 93, 89, 99, 88, - 95, 63, 21, 28, 39, 52, 73, 102, 136, 158, 158, 154, 148, 142, 141, 143, - 141, 137, 140, 138, 136, 137, 141, 144, 145, 145, 139, 139, 136, 132, 129, 127, - 127, 128, 124, 121, 117, 116, 117, 122, 125, 127, 120, 122, 127, 132, 134, 135, - 139, 148, 147, 151, 149, 145, 146, 150, 152, 150, 157, 157, 155, 152, 148, 146, - 145, 145, 141, 142, 144, 147, 151, 148, 141, 137, 148, 156, 164, 167, 168, 167, - 168, 170, 175, 174, 175, 177, 179, 179, 176, 173, 177, 174, 171, 169, 169, 169, - 168, 167, 157, 161, 162, 156, 149, 149, 158, 164, 155, 171, 181, 182, 183, 178, - 173, 171, 190, 195, 195, 186, 177, 173, 170, 167, 154, 149, 138, 120, 102, 146, - 154, 160, 146, 141, 147, 162, 165, 152, 137, 129, 103, 84, 92, 76, 93, 81, - 82, 80, 81, 77, 81, 83, 80, 87, 87, 75, 85, 83, 76, 71, 67, 67, - 73, 82, 78, 86, 88, 77, 78, 78, 77, 75, 74, 78, 79, 82, 80, 79, - 77, 76, 76, 79, 80, 79, 86, 84, 82, 87, 84, 81, 87, 82, 84, 80, - 74, 71, 74, 78, 79, 86, 88, 90, 90, 92, 93, 95, 96, 93, 87, 93, - 95, 105, 90, 101, 79, 16, 21, 26, 26, 33, 54, 89, 115, 129, 137, 147, - 151, 156, 157, 152, 143, 145, 144, 143, 141, 139, 141, 146, 149, 142, 142, 142, - 143, 142, 141, 138, 136, 132, 127, 118, 114, 116, 121, 124, 127, 122, 118, 121, - 125, 127, 127, 129, 138, 146, 149, 149, 145, 145, 148, 148, 144, 151, 153, 153, - 151, 147, 146, 147, 149, 148, 144, 138, 135, 137, 141, 146, 149, 163, 164, 165, - 168, 172, 173, 173, 170, 176, 177, 179, 181, 182, 180, 175, 171, 176, 174, 171, - 169, 169, 169, 167, 165, 159, 159, 157, 151, 146, 146, 155, 162, 160, 190, 189, - 179, 190, 180, 169, 187, 192, 193, 189, 181, 175, 173, 169, 164, 151, 146, 140, - 130, 116, 155, 149, 146, 138, 141, 149, 159, 163, 156, 140, 128, 127, 74, 92, - 68, 92, 82, 79, 77, 86, 78, 80, 79, 75, 80, 81, 70, 67, 78, 91, - 94, 92, 85, 80, 82, 87, 94, 97, 67, 70, 75, 77, 78, 79, 82, 84, - 85, 83, 82, 79, 79, 80, 85, 86, 81, 87, 84, 82, 88, 86, 82, 88, - 82, 83, 83, 82, 82, 85, 89, 92, 97, 98, 98, 98, 99, 99, 99, 100, - 95, 94, 98, 96, 107, 96, 103, 70, 9, 22, 34, 34, 31, 32, 42, 52, - 129, 136, 138, 134, 137, 151, 160, 162, 151, 150, 150, 147, 142, 138, 141, 144, - 146, 145, 148, 152, 153, 148, 138, 130, 139, 136, 133, 129, 129, 127, 125, 121, - 124, 121, 120, 121, 122, 123, 127, 135, 153, 158, 159, 156, 156, 159, 157, 153, - 149, 154, 157, 156, 150, 145, 144, 144, 144, 138, 133, 131, 134, 144, 156, 164, - 164, 164, 166, 166, 170, 173, 176, 177, 177, 175, 176, 179, 180, 179, 175, 172, - 175, 172, 170, 168, 168, 167, 165, 163, 168, 155, 144, 144, 150, 152, 151, 149, - 175, 193, 190, 178, 181, 177, 175, 188, 179, 181, 181, 178, 178, 177, 168, 159, - 145, 144, 145, 140, 123, 151, 137, 131, 160, 164, 165, 163, 164, 165, 157, 142, - 135, 85, 78, 76, 89, 78, 80, 73, 86, 80, 81, 77, 71, 76, 81, 72, - 86, 88, 87, 82, 82, 89, 94, 99, 101, 102, 102, 57, 62, 70, 75, 77, - 77, 79, 80, 80, 78, 78, 77, 77, 80, 85, 87, 84, 89, 84, 82, 89, - 88, 84, 89, 86, 87, 88, 89, 87, 84, 84, 86, 90, 89, 89, 90, 90, - 91, 92, 92, 93, 100, 99, 86, 101, 99, 95, 42, 14, 20, 26, 30, 30, - 31, 34, 39, 45, 80, 118, 141, 150, 155, 150, 139, 155, 158, 160, 157, 152, - 149, 149, 148, 149, 148, 148, 147, 148, 146, 139, 133, 144, 144, 143, 142, 141, - 138, 132, 126, 122, 116, 115, 120, 124, 127, 133, 139, 140, 145, 148, 147, 148, - 150, 149, 145, 158, 159, 157, 152, 145, 140, 139, 139, 129, 134, 143, 149, 153, - 157, 157, 159, 163, 167, 168, 169, 170, 172, 178, 182, 177, 174, 173, 175, 177, - 179, 178, 177, 172, 170, 168, 167, 166, 164, 161, 159, 158, 147, 142, 149, 160, - 162, 162, 163, 197, 188, 191, 185, 170, 177, 189, 181, 180, 181, 180, 179, 181, - 182, 174, 165, 156, 150, 143, 129, 105, 138, 139, 149, 162, 168, 165, 158, 156, - 160, 155, 141, 131, 114, 65, 97, 89, 76, 85, 75, 73, 75, 82, 83, 79, - 89, 98, 97, 107, 108, 103, 100, 104, 110, 108, 105, 108, 107, 103, 56, 61, - 68, 71, 71, 70, 71, 71, 71, 70, 71, 71, 72, 75, 79, 81, 79, 83, - 77, 75, 83, 82, 78, 83, 79, 80, 83, 86, 85, 80, 79, 81, 84, 83, - 83, 86, 89, 91, 94, 93, 88, 98, 96, 78, 93, 94, 85, 22, 18, 20, - 22, 27, 32, 36, 37, 36, 31, 44, 54, 60, 81, 117, 148, 157, 150, 151, - 156, 159, 159, 156, 155, 155, 154, 147, 142, 139, 140, 141, 144, 145, 146, 144, - 142, 142, 143, 143, 142, 140, 125, 117, 114, 115, 120, 118, 123, 127, 140, 144, - 147, 146, 147, 150, 150, 146, 146, 142, 136, 132, 133, 138, 144, 150, 141, 145, - 152, 156, 157, 161, 162, 164, 168, 171, 175, 174, 172, 172, 176, 179, 177, 174, - 173, 174, 177, 179, 180, 179, 169, 167, 165, 164, 163, 161, 158, 155, 144, 145, - 151, 156, 155, 152, 162, 177, 207, 186, 191, 189, 171, 184, 198, 178, 190, 188, - 182, 176, 176, 178, 175, 169, 157, 151, 144, 129, 102, 135, 145, 163, 149, 157, - 159, 158, 158, 158, 149, 135, 129, 139, 61, 105, 95, 84, 91, 81, 76, 76, - 86, 90, 89, 98, 108, 103, 63, 76, 89, 99, 108, 110, 93, 72, 114, 108, - 101, 65, 66, 69, 69, 68, 67, 70, 71, 71, 70, 72, 72, 73, 74, 77, - 78, 76, 79, 72, 70, 79, 79, 74, 78, 74, 73, 76, 82, 82, 79, 80, - 86, 84, 82, 82, 85, 90, 93, 93, 92, 82, 88, 89, 77, 89, 85, 79, - 25, 16, 22, 27, 32, 35, 35, 31, 28, 41, 43, 38, 38, 63, 105, 130, - 129, 144, 143, 146, 150, 155, 156, 156, 153, 151, 149, 146, 141, 140, 143, 148, - 152, 148, 147, 145, 146, 148, 147, 147, 146, 135, 127, 121, 119, 121, 116, 117, - 118, 112, 117, 118, 116, 117, 120, 120, 117, 131, 128, 126, 131, 140, 150, 156, - 157, 158, 157, 157, 155, 154, 160, 168, 176, 171, 173, 174, 174, 176, 176, 175, - 172, 175, 172, 173, 174, 177, 177, 175, 173, 166, 165, 163, 162, 161, 159, 155, - 151, 151, 152, 158, 160, 152, 146, 162, 182, 198, 193, 191, 187, 186, 192, 193, - 185, 190, 190, 185, 178, 175, 175, 172, 167, 150, 148, 148, 138, 112, 139, 143, - 158, 159, 165, 170, 173, 174, 168, 159, 150, 133, 145, 69, 87, 103, 94, 87, - 87, 88, 82, 87, 92, 95, 100, 100, 89, 95, 101, 102, 101, 112, 125, 129, - 122, 120, 112, 105, 72, 72, 72, 70, 68, 70, 75, 79, 76, 76, 78, 78, - 78, 78, 80, 80, 82, 84, 77, 75, 84, 84, 80, 84, 83, 79, 79, 83, - 81, 77, 79, 86, 81, 78, 77, 78, 83, 84, 83, 81, 82, 82, 86, 81, - 92, 80, 81, 41, 19, 22, 26, 28, 29, 32, 33, 35, 39, 35, 31, 40, - 83, 137, 162, 158, 148, 142, 142, 145, 151, 155, 156, 153, 148, 150, 154, 154, - 151, 145, 145, 146, 150, 151, 153, 153, 156, 152, 147, 141, 143, 134, 131, 132, - 135, 132, 130, 132, 135, 138, 137, 134, 134, 136, 136, 133, 136, 135, 139, 149, - 160, 164, 159, 154, 153, 158, 163, 165, 166, 165, 169, 171, 171, 169, 168, 172, - 179, 180, 175, 167, 171, 169, 171, 174, 175, 173, 169, 165, 165, 163, 162, 161, - 160, 157, 153, 149, 164, 155, 153, 158, 161, 161, 173, 189, 180, 198, 189, 182, - 199, 195, 182, 190, 184, 190, 192, 189, 184, 180, 172, 165, 157, 150, 146, 135, - 109, 137, 140, 155, 160, 160, 163, 166, 165, 158, 154, 149, 136, 137, 78, 65, - 106, 101, 81, 89, 90, 79, 79, 87, 95, 102, 93, 74, 95, 107, 109, 103, - 107, 116, 116, 109, 121, 112, 108, 64, 67, 67, 63, 61, 66, 71, 71, 71, - 74, 80, 82, 82, 81, 83, 83, 85, 88, 80, 75, 81, 82, 82, 90, 84, - 85, 83, 77, 76, 78, 79, 76, 77, 76, 75, 76, 79, 80, 80, 79, 76, - 90, 94, 84, 84, 91, 79, 56, 18, 21, 28, 32, 28, 23, 29, 41, 39, - 38, 37, 47, 88, 141, 167, 164, 163, 162, 161, 157, 152, 147, 146, 146, 148, - 148, 149, 150, 150, 150, 152, 154, 157, 157, 156, 153, 155, 153, 154, 152, 150, - 141, 133, 128, 133, 134, 135, 134, 140, 140, 140, 141, 142, 142, 143, 143, 145, - 145, 147, 150, 153, 157, 160, 164, 160, 161, 161, 161, 164, 166, 168, 170, 171, - 171, 172, 172, 172, 173, 174, 175, 172, 170, 171, 173, 174, 173, 170, 167, 166, - 166, 162, 156, 150, 148, 152, 156, 155, 158, 161, 159, 164, 175, 185, 188, 190, - 178, 180, 187, 191, 195, 192, 177, 191, 185, 179, 178, 180, 179, 172, 167, 168, - 156, 146, 134, 112, 145, 145, 155, 164, 163, 163, 167, 166, 159, 157, 154, 136, - 124, 90, 62, 90, 85, 92, 87, 86, 81, 78, 79, 86, 89, 88, 88, 108, - 103, 98, 104, 118, 121, 109, 96, 135, 163, 122, 60, 63, 64, 60, 59, 64, - 69, 69, 67, 71, 77, 79, 79, 79, 84, 86, 94, 97, 90, 84, 86, 81, - 75, 79, 79, 81, 81, 77, 77, 80, 81, 78, 83, 82, 80, 81, 83, 84, - 84, 83, 81, 90, 93, 87, 90, 97, 92, 78, 26, 25, 23, 25, 26, 34, - 52, 70, 81, 85, 83, 84, 108, 146, 167, 164, 172, 170, 171, 169, 166, 163, - 163, 161, 157, 162, 165, 162, 158, 156, 160, 164, 168, 167, 167, 166, 168, 169, - 171, 170, 166, 162, 155, 145, 139, 138, 140, 142, 134, 136, 140, 143, 145, 144, - 143, 141, 145, 146, 149, 153, 157, 160, 163, 167, 169, 169, 167, 166, 167, 168, - 168, 169, 172, 172, 172, 172, 175, 173, 176, 174, 170, 170, 171, 173, 175, 175, - 173, 171, 163, 161, 159, 155, 152, 151, 153, 156, 159, 160, 162, 164, 174, 185, - 191, 189, 191, 195, 206, 204, 187, 183, 192, 194, 187, 185, 183, 180, 176, 173, - 171, 170, 160, 161, 160, 142, 106, 130, 139, 161, 164, 164, 163, 168, 168, 163, - 157, 153, 133, 119, 87, 61, 94, 93, 94, 84, 76, 75, 77, 83, 93, 98, - 101, 105, 94, 93, 93, 98, 107, 110, 108, 104, 90, 116, 117, 57, 61, 62, - 59, 58, 63, 68, 68, 64, 69, 75, 74, 72, 72, 79, 84, 77, 84, 82, - 81, 86, 81, 73, 77, 75, 78, 80, 78, 80, 83, 84, 81, 86, 84, 82, - 82, 85, 86, 85, 84, 83, 83, 82, 82, 88, 92, 90, 89, 60, 57, 52, - 54, 61, 76, 97, 112, 117, 126, 127, 121, 128, 146, 161, 160, 172, 173, 176, - 177, 176, 172, 171, 171, 168, 173, 178, 176, 167, 161, 164, 170, 172, 171, 173, - 171, 175, 176, 179, 180, 176, 174, 169, 156, 145, 139, 139, 142, 139, 140, 142, - 144, 146, 148, 148, 149, 145, 147, 149, 153, 156, 158, 160, 160, 167, 167, 165, - 163, 162, 162, 163, 164, 166, 166, 167, 168, 170, 168, 170, 168, 169, 168, 167, - 168, 169, 170, 168, 167, 161, 159, 156, 155, 156, 157, 158, 157, 159, 162, 164, - 171, 185, 196, 196, 190, 201, 196, 200, 199, 190, 189, 194, 190, 180, 182, 182, - 177, 170, 165, 166, 168, 161, 155, 149, 136, 109, 136, 137, 148, 163, 163, 165, - 168, 169, 163, 157, 154, 141, 121, 86, 56, 93, 99, 99, 93, 95, 92, 93, - 93, 92, 90, 90, 90, 99, 102, 102, 101, 99, 101, 102, 104, 96, 101, 125, - 60, 64, 66, 62, 60, 64, 68, 67, 66, 70, 73, 70, 65, 64, 71, 77, - 64, 73, 73, 75, 83, 81, 76, 80, 76, 80, 82, 82, 83, 87, 86, 83, - 86, 84, 81, 80, 83, 84, 84, 83, 85, 80, 77, 80, 84, 83, 83, 88, - 95, 97, 97, 102, 109, 117, 126, 134, 132, 142, 145, 139, 139, 152, 161, 163, - 170, 174, 176, 178, 178, 176, 175, 172, 172, 177, 181, 178, 172, 168, 168, 170, - 174, 173, 171, 171, 172, 175, 178, 179, 174, 173, 170, 164, 155, 146, 142, 142, - 146, 143, 140, 137, 138, 142, 147, 150, 145, 147, 148, 150, 151, 152, 152, 151, - 160, 160, 159, 159, 159, 160, 162, 163, 163, 163, 165, 165, 166, 165, 165, 165, - 170, 168, 166, 165, 165, 166, 165, 163, 164, 160, 158, 158, 161, 163, 162, 159, - 158, 164, 171, 178, 190, 198, 197, 191, 200, 188, 187, 189, 190, 195, 197, 188, - 183, 184, 183, 177, 171, 167, 167, 169, 161, 151, 145, 136, 115, 145, 142, 150, - 162, 161, 162, 169, 169, 163, 157, 151, 149, 126, 93, 52, 86, 102, 104, 104, - 88, 90, 95, 96, 95, 96, 96, 100, 105, 108, 108, 106, 102, 100, 101, 103, - 112, 95, 106, 67, 71, 72, 67, 65, 67, 70, 68, 69, 71, 74, 70, 66, - 66, 73, 79, 79, 85, 82, 80, 86, 82, 76, 81, 81, 85, 87, 86, 86, - 89, 88, 84, 87, 84, 81, 80, 80, 82, 84, 83, 88, 82, 82, 86, 87, - 83, 84, 92, 108, 114, 120, 123, 128, 131, 131, 129, 139, 146, 149, 146, 148, - 160, 167, 168, 175, 178, 182, 184, 183, 179, 178, 177, 177, 175, 176, 177, 177, - 174, 170, 167, 179, 178, 176, 174, 174, 174, 175, 177, 172, 170, 170, 172, 172, - 167, 159, 154, 147, 145, 142, 139, 138, 138, 140, 141, 145, 145, 147, 148, 149, - 149, 150, 150, 159, 158, 157, 157, 157, 159, 161, 162, 161, 159, 162, 161, 163, - 161, 163, 163, 167, 166, 164, 164, 166, 167, 167, 166, 164, 161, 158, 159, 162, - 164, 162, 160, 160, 171, 184, 189, 192, 196, 198, 197, 193, 191, 199, 198, 187, - 190, 200, 201, 192, 190, 185, 180, 177, 175, 172, 172, 154, 159, 165, 150, 114, - 138, 146, 168, 163, 161, 159, 166, 167, 162, 156, 149, 145, 126, 105, 56, 82, - 99, 97, 103, 88, 91, 96, 97, 97, 98, 101, 102, 100, 101, 103, 105, 107, - 108, 105, 103, 102, 98, 89, 69, 74, 75, 71, 69, 70, 73, 71, 72, 73, - 75, 74, 75, 77, 84, 87, 86, 91, 86, 83, 88, 85, 80, 85, 86, 89, - 90, 87, 87, 90, 90, 86, 89, 85, 82, 81, 82, 84, 87, 87, 84, 82, - 84, 87, 88, 87, 90, 97, 112, 122, 129, 129, 132, 135, 138, 137, 145, 149, - 151, 149, 151, 159, 164, 164, 174, 179, 182, 183, 182, 180, 178, 178, 179, 176, - 172, 175, 179, 179, 173, 170, 178, 179, 175, 174, 173, 172, 172, 169, 168, 167, - 167, 172, 177, 177, 170, 163, 158, 157, 158, 157, 154, 149, 144, 140, 141, 141, - 141, 142, 143, 145, 147, 148, 156, 155, 153, 152, 152, 152, 154, 153, 152, 152, - 151, 151, 151, 150, 154, 154, 155, 155, 156, 159, 163, 165, 166, 165, 163, 161, - 159, 159, 160, 162, 163, 165, 170, 183, 195, 196, 194, 196, 199, 200, 201, 192, - 194, 195, 191, 195, 199, 192, 192, 188, 182, 178, 175, 173, 170, 169, 160, 160, - 161, 147, 114, 139, 143, 160, 166, 161, 158, 163, 168, 163, 156, 149, 135, 120, - 112, 61, 83, 98, 86, 92, 99, 97, 98, 98, 97, 97, 97, 98, 105, 103, - 103, 105, 110, 109, 103, 99, 92, 112, 102, 66, 71, 74, 71, 70, 73, 76, - 74, 75, 74, 75, 77, 81, 85, 88, 88, 81, 87, 84, 83, 90, 88, 83, - 88, 87, 89, 89, 86, 87, 91, 91, 89, 89, 83, 80, 79, 83, 86, 89, - 90, 82, 84, 85, 83, 85, 89, 92, 97, 116, 129, 139, 138, 140, 145, 152, - 153, 150, 154, 158, 156, 153, 155, 155, 158, 171, 177, 179, 180, 179, 178, 179, - 181, 179, 177, 174, 174, 175, 175, 174, 172, 174, 176, 176, 175, 174, 170, 168, - 166, 168, 168, 169, 171, 171, 172, 171, 170, 175, 175, 173, 171, 167, 163, 159, - 157, 152, 150, 147, 145, 145, 146, 148, 149, 148, 147, 146, 145, 146, 147, 149, - 148, 147, 145, 143, 142, 143, 143, 147, 149, 153, 154, 155, 158, 162, 163, 162, - 161, 162, 162, 162, 161, 162, 165, 169, 175, 182, 192, 198, 197, 195, 196, 198, - 197, 205, 190, 187, 191, 195, 200, 198, 182, 188, 187, 184, 177, 170, 166, 167, - 170, 166, 157, 150, 140, 117, 146, 144, 152, 170, 164, 160, 163, 168, 164, 159, - 152, 139, 121, 112, 58, 83, 103, 86, 92, 86, 82, 82, 87, 94, 102, 104, - 105, 106, 105, 102, 101, 101, 100, 96, 94, 89, 109, 104, 59, 65, 70, 68, - 69, 73, 75, 74, 79, 75, 72, 74, 79, 83, 81, 80, 82, 89, 89, 86, - 93, 86, 81, 83, 86, 86, 87, 82, 86, 89, 93, 89, 85, 82, 78, 78, - 80, 85, 87, 88, 86, 92, 90, 84, 83, 92, 97, 102, 111, 131, 143, 143, - 144, 148, 154, 155, 154, 164, 169, 168, 161, 156, 157, 160, 172, 176, 180, 180, - 180, 181, 183, 186, 176, 178, 176, 173, 170, 169, 170, 172, 174, 175, 176, 177, - 176, 173, 170, 167, 173, 175, 175, 172, 166, 167, 172, 177, 187, 181, 172, 164, - 161, 162, 166, 170, 173, 169, 163, 157, 154, 153, 153, 153, 147, 147, 148, 149, - 151, 154, 156, 157, 155, 153, 150, 147, 148, 149, 154, 157, 165, 165, 168, 167, - 170, 167, 165, 160, 166, 165, 168, 165, 167, 169, 179, 186, 189, 194, 195, 193, - 193, 196, 195, 190, 191, 193, 202, 202, 187, 185, 196, 198, 190, 193, 193, 184, - 172, 167, 171, 179, 157, 162, 165, 150, 115, 141, 150, 173, 171, 166, 161, 165, - 168, 168, 161, 157, 154, 125, 110, 52, 79, 108, 93, 102, 99, 93, 86, 85, - 87, 89, 87, 83, 93, 91, 91, 90, 92, 93, 96, 97, 102, 104, 99, 66, - 66, 68, 66, 64, 67, 71, 74, 79, 78, 76, 75, 74, 76, 78, 79, 82, - 81, 83, 80, 82, 81, 84, 82, 92, 84, 81, 79, 85, 85, 85, 80, 80, - 82, 80, 80, 83, 88, 83, 76, 80, 88, 93, 76, 79, 91, 89, 108, 127, - 137, 144, 148, 149, 151, 155, 158, 167, 167, 169, 171, 169, 167, 162, 158, 163, - 167, 173, 175, 176, 177, 178, 180, 173, 175, 179, 184, 188, 187, 181, 173, 176, - 173, 170, 167, 166, 166, 168, 168, 162, 167, 173, 174, 171, 168, 166, 166, 168, - 173, 177, 168, 159, 160, 167, 175, 177, 180, 183, 182, 177, 171, 166, 163, 166, - 165, 163, 160, 158, 156, 154, 154, 153, 154, 156, 160, 166, 170, 177, 180, 185, - 180, 179, 177, 176, 166, 162, 159, 168, 170, 177, 177, 180, 179, 183, 186, 190, - 196, 200, 198, 196, 196, 194, 190, 185, 192, 192, 188, 190, 199, 198, 189, 195, - 193, 186, 178, 177, 180, 180, 177, 164, 162, 160, 147, 128, 134, 146, 147, 167, - 166, 164, 163, 166, 165, 165, 162, 149, 132, 122, 69, 74, 90, 101, 92, 94, - 92, 89, 85, 83, 83, 83, 83, 87, 86, 91, 92, 97, 96, 99, 99, 91, - 95, 100, 75, 73, 74, 72, 71, 70, 73, 75, 73, 72, 71, 71, 71, 73, - 76, 78, 77, 77, 78, 76, 79, 78, 81, 79, 77, 73, 73, 72, 76, 75, - 73, 70, 81, 80, 74, 66, 67, 74, 78, 77, 81, 75, 81, 81, 90, 92, - 83, 105, 130, 140, 147, 150, 151, 152, 156, 159, 158, 159, 162, 166, 167, 164, - 159, 154, 158, 161, 166, 170, 174, 175, 174, 173, 173, 174, 176, 180, 184, 184, - 181, 175, 180, 176, 173, 171, 169, 169, 170, 170, 169, 168, 166, 162, 160, 162, - 167, 171, 168, 171, 174, 169, 167, 170, 176, 177, 183, 182, 180, 176, 172, 171, - 171, 173, 175, 174, 172, 171, 172, 174, 177, 179, 179, 178, 178, 178, 179, 181, - 183, 185, 189, 184, 183, 185, 185, 181, 179, 179, 180, 182, 184, 184, 183, 184, - 188, 191, 194, 199, 200, 196, 194, 195, 195, 193, 195, 200, 198, 191, 191, 197, - 196, 187, 191, 191, 186, 179, 177, 179, 176, 171, 162, 158, 154, 139, 121, 128, - 143, 147, 163, 162, 163, 163, 167, 168, 165, 162, 153, 140, 125, 79, 79, 98, - 102, 96, 95, 94, 94, 92, 90, 88, 85, 84, 87, 87, 86, 86, 87, 89, - 91, 92, 92, 93, 97, 71, 73, 74, 72, 72, 70, 71, 72, 75, 75, 74, - 74, 75, 76, 78, 80, 73, 73, 74, 74, 76, 76, 79, 79, 80, 79, 81, - 80, 79, 75, 71, 68, 73, 73, 68, 60, 58, 65, 70, 72, 69, 64, 77, - 80, 79, 70, 69, 107, 133, 143, 150, 153, 153, 154, 157, 159, 157, 159, 164, - 169, 171, 169, 164, 159, 150, 151, 156, 165, 174, 179, 179, 177, 175, 175, 175, - 177, 181, 183, 183, 180, 178, 175, 174, 172, 170, 169, 167, 167, 171, 168, 164, - 159, 157, 159, 165, 169, 165, 166, 169, 169, 172, 177, 179, 175, 180, 179, 178, - 174, 172, 172, 176, 179, 182, 180, 179, 179, 181, 186, 191, 195, 192, 190, 188, - 186, 184, 184, 184, 184, 187, 182, 180, 184, 186, 185, 186, 188, 191, 191, 190, - 188, 186, 187, 190, 193, 197, 200, 199, 194, 191, 194, 195, 194, 198, 201, 198, - 190, 191, 196, 195, 189, 188, 189, 186, 181, 179, 179, 174, 168, 166, 159, 153, - 138, 120, 128, 147, 154, 159, 158, 159, 161, 165, 166, 165, 162, 151, 144, 125, - 89, 76, 103, 99, 97, 97, 98, 99, 99, 97, 93, 89, 87, 91, 89, 86, - 84, 83, 85, 87, 89, 90, 91, 91, 65, 66, 70, 71, 72, 71, 72, 73, - 78, 77, 76, 74, 73, 73, 74, 73, 72, 73, 73, 74, 76, 78, 80, 81, - 76, 78, 78, 76, 70, 65, 61, 60, 70, 76, 79, 73, 69, 71, 70, 70, - 74, 69, 76, 71, 73, 72, 72, 106, 133, 144, 150, 154, 154, 154, 156, 158, - 162, 163, 166, 171, 175, 175, 172, 169, 157, 155, 155, 162, 172, 180, 181, 179, - 177, 176, 175, 176, 178, 182, 185, 184, 175, 175, 175, 174, 172, 170, 167, 165, - 168, 168, 168, 166, 164, 161, 160, 159, 158, 161, 166, 166, 170, 174, 176, 172, - 175, 177, 181, 181, 179, 176, 176, 176, 183, 183, 182, 182, 183, 186, 190, 192, - 189, 188, 186, 185, 184, 185, 186, 187, 188, 182, 179, 181, 182, 182, 184, 187, - 192, 192, 191, 190, 189, 189, 189, 190, 195, 198, 198, 192, 190, 192, 193, 191, - 191, 192, 189, 185, 187, 194, 195, 192, 187, 187, 185, 180, 179, 181, 177, 171, - 167, 159, 153, 141, 124, 130, 148, 155, 156, 156, 158, 161, 166, 167, 165, 161, - 154, 149, 127, 96, 71, 106, 98, 99, 98, 99, 100, 100, 99, 96, 93, 90, - 94, 92, 90, 88, 87, 87, 89, 90, 88, 86, 84, 69, 73, 77, 79, 78, - 77, 78, 78, 75, 75, 75, 73, 72, 72, 74, 71, 75, 76, 76, 78, 80, - 82, 84, 85, 82, 83, 83, 80, 76, 72, 71, 72, 83, 92, 96, 92, 88, - 85, 82, 79, 74, 73, 76, 70, 83, 95, 86, 102, 131, 140, 147, 151, 151, - 151, 152, 154, 160, 160, 161, 164, 168, 170, 170, 169, 172, 165, 159, 159, 165, - 170, 171, 170, 173, 172, 172, 171, 173, 176, 180, 183, 179, 179, 180, 179, 178, - 175, 172, 170, 168, 168, 169, 168, 166, 161, 155, 151, 148, 156, 163, 163, 164, - 168, 173, 174, 176, 178, 181, 181, 180, 178, 177, 177, 181, 182, 183, 185, 186, - 186, 186, 186, 186, 186, 185, 185, 186, 188, 190, 191, 192, 185, 181, 183, 184, - 184, 186, 189, 188, 189, 191, 193, 193, 192, 190, 188, 189, 194, 195, 191, 189, - 190, 189, 187, 187, 186, 184, 182, 185, 191, 193, 191, 184, 184, 180, 175, 176, - 179, 178, 174, 162, 154, 152, 143, 126, 128, 144, 150, 155, 156, 158, 161, 166, - 167, 164, 161, 158, 156, 132, 98, 70, 104, 97, 102, 95, 94, 94, 94, 93, - 92, 91, 91, 89, 90, 90, 90, 90, 89, 88, 88, 88, 86, 83, 75, 78, - 81, 81, 79, 77, 78, 78, 76, 77, 78, 81, 82, 85, 85, 84, 82, 81, - 83, 82, 86, 86, 90, 90, 94, 92, 94, 92, 95, 93, 95, 97, 94, 100, - 98, 92, 90, 90, 89, 85, 38, 61, 83, 70, 70, 80, 79, 102, 128, 138, - 146, 150, 151, 150, 151, 153, 161, 161, 161, 164, 167, 169, 168, 167, 167, 162, - 157, 156, 161, 167, 172, 173, 168, 169, 170, 170, 169, 171, 174, 177, 177, 177, - 178, 178, 177, 175, 172, 171, 173, 169, 165, 162, 161, 159, 157, 156, 143, 151, - 157, 157, 158, 165, 173, 177, 181, 180, 177, 176, 175, 176, 180, 183, 179, 181, - 184, 187, 188, 188, 187, 186, 185, 184, 183, 183, 183, 185, 187, 188, 188, 182, - 179, 181, 184, 184, 187, 190, 188, 189, 192, 195, 197, 195, 191, 187, 185, 190, - 192, 189, 188, 189, 188, 186, 190, 188, 185, 184, 185, 187, 187, 186, 181, 180, - 177, 172, 172, 176, 176, 172, 163, 155, 154, 149, 131, 130, 143, 149, 155, 157, - 158, 161, 166, 167, 165, 162, 154, 151, 132, 92, 67, 92, 89, 93, 93, 93, - 93, 94, 95, 95, 95, 96, 92, 93, 94, 95, 95, 94, 93, 90, 89, 88, - 86, 77, 79, 81, 81, 77, 75, 75, 78, 80, 82, 85, 87, 90, 93, 94, - 94, 90, 90, 91, 91, 94, 94, 97, 97, 91, 89, 91, 93, 98, 97, 94, - 90, 99, 102, 96, 90, 87, 89, 87, 82, 33, 50, 71, 64, 59, 61, 67, - 103, 126, 136, 145, 150, 151, 151, 152, 154, 160, 162, 165, 169, 171, 170, 166, - 162, 159, 158, 158, 159, 162, 167, 172, 175, 167, 170, 173, 173, 171, 170, 171, - 173, 174, 174, 174, 174, 173, 173, 172, 171, 176, 171, 165, 163, 164, 166, 166, - 165, 148, 150, 149, 147, 149, 158, 164, 165, 174, 174, 174, 173, 174, 177, 180, - 185, 177, 179, 180, 182, 184, 184, 184, 184, 183, 182, 181, 180, 180, 181, 182, - 183, 182, 177, 175, 178, 181, 181, 182, 186, 190, 190, 190, 193, 195, 194, 190, - 186, 186, 190, 190, 186, 185, 188, 190, 190, 191, 188, 186, 185, 185, 183, 181, - 180, 182, 183, 180, 176, 176, 177, 174, 168, 167, 157, 156, 151, 133, 130, 143, - 150, 159, 157, 158, 159, 163, 165, 165, 164, 149, 145, 137, 88, 71, 80, 83, - 81, 86, 86, 90, 93, 95, 95, 94, 93, 95, 95, 94, 94, 93, 93, 93, - 93, 87, 87, 87, 75, 77, 80, 81, 81, 79, 80, 82, 80, 80, 83, 86, - 88, 89, 90, 92, 98, 98, 100, 99, 102, 102, 105, 104, 105, 101, 104, 106, - 111, 107, 101, 93, 104, 104, 101, 97, 95, 94, 88, 79, 83, 56, 46, 50, - 75, 84, 74, 96, 124, 136, 145, 151, 152, 152, 154, 155, 156, 159, 165, 170, - 172, 168, 160, 154, 167, 168, 168, 166, 164, 162, 163, 164, 169, 173, 177, 178, - 175, 173, 173, 173, 176, 176, 176, 176, 176, 176, 176, 176, 174, 172, 170, 171, - 174, 175, 173, 171, 157, 152, 143, 138, 141, 151, 153, 150, 160, 165, 173, 178, - 180, 178, 180, 179, 177, 176, 175, 175, 175, 176, 177, 178, 185, 184, 183, 182, - 182, 183, 185, 186, 185, 180, 177, 180, 181, 180, 180, 183, 192, 190, 188, 188, - 190, 190, 187, 184, 188, 190, 189, 184, 183, 189, 193, 194, 188, 185, 183, 184, - 184, 181, 178, 177, 186, 188, 187, 183, 182, 181, 174, 166, 165, 153, 151, 146, - 127, 124, 138, 146, 161, 159, 159, 159, 163, 165, 166, 165, 152, 147, 149, 92, - 81, 82, 87, 79, 71, 76, 82, 87, 90, 89, 86, 84, 95, 93, 90, 87, - 85, 86, 88, 87, 82, 84, 86, 80, 82, 83, 83, 82, 80, 76, 74, 89, - 86, 75, 91, 85, 93, 90, 103, 103, 96, 89, 89, 96, 99, 98, 93, 105, - 112, 116, 108, 103, 104, 108, 107, 109, 105, 103, 100, 96, 91, 86, 84, 90, - 89, 84, 76, 70, 59, 64, 90, 122, 135, 139, 144, 152, 148, 144, 151, 153, - 158, 164, 167, 166, 163, 159, 158, 163, 164, 164, 163, 161, 161, 163, 165, 164, - 169, 175, 180, 181, 177, 172, 168, 169, 170, 172, 176, 178, 176, 171, 167, 167, - 174, 179, 176, 167, 161, 161, 164, 167, 162, 147, 143, 146, 141, 138, 147, 152, - 160, 171, 178, 177, 169, 169, 170, 170, 172, 178, 184, 180, 171, 170, 175, 185, - 180, 175, 175, 180, 184, 185, 185, 186, 181, 177, 177, 181, 186, 188, 188, 192, - 193, 192, 190, 187, 185, 186, 188, 190, 190, 189, 188, 188, 187, 186, 186, 188, - 187, 187, 188, 187, 184, 178, 174, 181, 177, 175, 178, 179, 175, 171, 172, 164, - 161, 156, 148, 133, 126, 131, 141, 155, 154, 156, 158, 162, 164, 164, 162, 144, - 141, 144, 71, 98, 83, 76, 87, 77, 76, 77, 81, 83, 83, 81, 78, 81, - 78, 75, 74, 75, 79, 83, 87, 79, 79, 81, 82, 82, 80, 80, 78, 76, - 72, 71, 73, 81, 75, 84, 76, 88, 81, 86, 112, 111, 104, 94, 88, 86, - 92, 96, 89, 93, 96, 94, 98, 103, 105, 100, 93, 94, 103, 110, 107, 95, - 87, 87, 67, 83, 90, 89, 95, 95, 93, 103, 120, 134, 138, 142, 149, 146, - 143, 150, 153, 157, 163, 165, 165, 162, 160, 160, 162, 164, 165, 165, 164, 164, - 165, 167, 161, 164, 169, 173, 176, 176, 175, 174, 175, 171, 166, 165, 167, 170, - 173, 174, 171, 165, 162, 166, 174, 175, 168, 160, 157, 165, 164, 154, 143, 127, - 122, 130, 141, 156, 161, 156, 164, 185, 185, 169, 172, 175, 180, 182, 175, 171, - 178, 190, 177, 177, 178, 178, 179, 181, 184, 186, 193, 188, 181, 179, 180, 183, - 184, 185, 186, 187, 188, 187, 186, 186, 188, 189, 190, 190, 189, 188, 188, 187, - 186, 186, 189, 188, 187, 185, 183, 178, 171, 166, 173, 169, 169, 173, 174, 171, - 167, 168, 168, 163, 156, 145, 132, 127, 135, 147, 154, 155, 159, 162, 165, 165, - 162, 158, 147, 145, 132, 81, 102, 86, 77, 82, 78, 77, 76, 78, 80, 80, - 79, 77, 80, 81, 82, 82, 80, 78, 76, 73, 77, 78, 80, 81, 80, 78, - 77, 76, 76, 75, 75, 71, 96, 99, 95, 71, 83, 84, 95, 86, 90, 92, - 90, 94, 96, 105, 108, 115, 112, 110, 106, 110, 109, 105, 93, 103, 94, 96, - 101, 93, 81, 78, 86, 84, 97, 94, 83, 89, 94, 90, 91, 120, 135, 140, - 142, 148, 146, 143, 150, 152, 156, 160, 163, 163, 162, 162, 162, 162, 164, 167, - 168, 167, 166, 166, 167, 163, 164, 165, 167, 169, 172, 174, 176, 177, 172, 165, - 161, 162, 166, 169, 171, 163, 167, 171, 171, 169, 168, 170, 173, 168, 165, 159, - 155, 153, 144, 129, 117, 123, 127, 142, 159, 165, 168, 179, 193, 180, 172, 167, - 169, 172, 171, 169, 169, 171, 176, 181, 182, 180, 181, 186, 190, 195, 190, 183, - 179, 179, 181, 184, 185, 185, 187, 188, 188, 187, 186, 188, 190, 190, 190, 189, - 188, 188, 187, 186, 186, 192, 191, 189, 187, 184, 179, 173, 169, 172, 170, 171, - 176, 178, 175, 171, 171, 175, 168, 157, 144, 129, 126, 136, 150, 151, 154, 161, - 164, 167, 164, 160, 156, 150, 149, 115, 98, 107, 89, 82, 81, 78, 74, 71, - 71, 74, 76, 77, 78, 75, 77, 79, 81, 82, 82, 81, 80, 78, 80, 80, - 75, 76, 74, 72, 72, 75, 76, 77, 75, 86, 80, 83, 67, 79, 78, 88, - 96, 93, 90, 98, 110, 113, 102, 90, 98, 99, 101, 107, 114, 119, 118, 113, - 120, 105, 100, 104, 98, 81, 76, 82, 78, 85, 81, 75, 78, 81, 78, 86, - 119, 137, 141, 141, 147, 147, 145, 152, 152, 155, 158, 160, 161, 162, 164, 165, - 163, 166, 169, 170, 168, 166, 165, 165, 170, 169, 168, 167, 167, 168, 168, 169, - 173, 172, 170, 169, 168, 166, 162, 160, 160, 168, 174, 170, 160, 156, 162, 170, - 170, 159, 151, 147, 148, 150, 137, 116, 110, 108, 122, 146, 156, 158, 166, 181, - 185, 179, 177, 179, 181, 179, 175, 171, 173, 176, 180, 181, 183, 186, 191, 195, - 191, 187, 181, 178, 178, 182, 187, 190, 190, 192, 193, 192, 189, 187, 188, 188, - 189, 189, 189, 188, 188, 187, 187, 187, 187, 186, 186, 186, 186, 184, 180, 177, - 177, 174, 175, 180, 182, 178, 174, 174, 178, 171, 159, 145, 129, 124, 133, 147, - 153, 157, 163, 165, 166, 163, 160, 156, 151, 148, 99, 112, 108, 96, 91, 87, - 79, 73, 70, 69, 72, 76, 79, 81, 78, 77, 75, 74, 75, 79, 82, 85, - 79, 81, 84, 66, 65, 61, 58, 58, 60, 61, 63, 80, 64, 52, 82, 90, - 97, 80, 81, 104, 102, 100, 108, 118, 120, 109, 98, 96, 98, 103, 109, 114, - 117, 119, 119, 115, 105, 110, 124, 122, 100, 80, 72, 73, 76, 81, 89, 84, - 63, 51, 64, 111, 133, 138, 136, 141, 144, 144, 151, 151, 154, 157, 159, 160, - 161, 164, 166, 164, 166, 169, 169, 166, 163, 161, 161, 172, 172, 171, 170, 169, - 166, 164, 163, 169, 169, 170, 172, 172, 169, 164, 160, 168, 162, 157, 157, 162, - 162, 157, 151, 156, 158, 164, 148, 123, 120, 117, 98, 103, 122, 124, 112, 133, - 174, 182, 160, 167, 174, 182, 180, 173, 172, 178, 185, 176, 174, 174, 177, 184, - 190, 193, 194, 188, 185, 181, 178, 178, 181, 186, 190, 190, 192, 193, 193, 190, - 189, 188, 189, 189, 189, 188, 188, 188, 188, 187, 187, 181, 180, 180, 181, 182, - 181, 179, 176, 176, 173, 173, 177, 177, 173, 168, 168, 172, 166, 157, 145, 130, - 124, 132, 144, 155, 158, 163, 164, 163, 161, 158, 157, 148, 144, 96, 120, 109, - 105, 100, 96, 84, 78, 73, 70, 71, 73, 75, 75, 83, 81, 77, 74, 71, - 71, 72, 75, 79, 81, 82, 57, 55, 53, 47, 46, 46, 46, 47, 59, 57, - 65, 104, 103, 98, 83, 98, 95, 101, 106, 104, 105, 106, 115, 120, 118, 114, - 116, 116, 117, 111, 114, 116, 113, 106, 107, 110, 107, 92, 74, 60, 85, 79, - 79, 85, 77, 49, 42, 63, 104, 128, 134, 131, 136, 141, 143, 150, 152, 155, - 159, 161, 161, 162, 164, 166, 165, 167, 169, 168, 165, 163, 162, 162, 168, 169, - 171, 172, 171, 169, 167, 165, 169, 167, 166, 166, 169, 171, 172, 172, 165, 166, - 166, 167, 166, 166, 165, 164, 167, 164, 170, 154, 125, 112, 89, 46, 59, 81, - 87, 78, 82, 115, 149, 163, 176, 171, 165, 164, 171, 177, 175, 168, 175, 172, - 171, 176, 185, 191, 193, 192, 192, 190, 187, 182, 179, 179, 182, 185, 183, 186, - 189, 190, 190, 189, 190, 191, 188, 188, 188, 188, 188, 188, 188, 188, 186, 184, - 182, 182, 182, 180, 177, 175, 178, 173, 172, 174, 175, 171, 167, 168, 164, 160, - 154, 145, 131, 126, 133, 144, 154, 158, 163, 163, 162, 159, 158, 158, 144, 136, - 108, 124, 110, 113, 106, 104, 95, 88, 82, 78, 75, 73, 71, 69, 79, 82, - 85, 87, 87, 84, 81, 80, 80, 81, 80, 58, 58, 57, 52, 53, 53, 53, - 54, 45, 61, 77, 104, 88, 85, 79, 99, 104, 109, 111, 102, 94, 91, 101, - 108, 97, 90, 92, 98, 109, 110, 116, 120, 114, 112, 108, 97, 87, 82, 76, - 68, 73, 67, 63, 69, 77, 71, 76, 98, 101, 127, 134, 130, 135, 142, 146, - 153, 154, 157, 161, 163, 163, 163, 164, 165, 165, 167, 168, 167, 166, 165, 166, - 168, 167, 168, 169, 170, 171, 170, 169, 168, 171, 168, 165, 164, 167, 170, 172, - 173, 163, 174, 184, 182, 172, 167, 173, 181, 182, 165, 165, 158, 140, 130, 87, - 12, 23, 19, 30, 44, 36, 33, 71, 122, 169, 168, 169, 173, 181, 185, 176, - 163, 171, 174, 179, 185, 190, 193, 193, 193, 196, 196, 193, 188, 182, 179, 180, - 182, 182, 185, 189, 191, 191, 190, 190, 191, 188, 188, 188, 188, 188, 188, 188, - 188, 191, 189, 186, 184, 183, 181, 177, 175, 180, 175, 172, 175, 176, 174, 172, - 174, 166, 162, 155, 145, 130, 124, 131, 143, 147, 155, 163, 164, 163, 159, 157, - 156, 139, 128, 128, 128, 113, 117, 107, 106, 98, 93, 89, 85, 82, 78, 73, - 69, 71, 75, 82, 88, 92, 93, 92, 93, 83, 84, 82, 66, 66, 68, 68, - 69, 73, 74, 76, 85, 84, 75, 92, 95, 105, 89, 84, 88, 91, 91, 95, - 101, 104, 107, 108, 98, 83, 79, 87, 98, 101, 100, 100, 91, 108, 117, 109, - 100, 100, 97, 90, 77, 82, 81, 83, 93, 92, 85, 91, 100, 127, 137, 130, - 138, 144, 151, 155, 154, 156, 162, 163, 165, 164, 164, 165, 164, 164, 167, 167, - 167, 168, 171, 174, 169, 169, 168, 168, 168, 168, 168, 168, 171, 169, 168, 167, - 167, 167, 165, 163, 172, 172, 173, 176, 180, 179, 174, 169, 169, 162, 170, 165, - 142, 136, 100, 31, 72, 47, 36, 42, 52, 51, 53, 60, 94, 134, 174, 177, - 159, 152, 161, 173, 169, 178, 189, 196, 197, 195, 195, 194, 197, 196, 196, 190, - 185, 179, 181, 181, 188, 189, 194, 192, 193, 188, 189, 189, 186, 186, 186, 186, - 186, 186, 188, 188, 187, 185, 182, 180, 179, 178, 175, 172, 178, 173, 170, 172, - 174, 173, 174, 177, 177, 170, 158, 145, 128, 120, 127, 138, 144, 153, 164, 167, - 163, 156, 151, 150, 132, 119, 141, 129, 115, 122, 106, 109, 101, 102, 101, 100, - 98, 94, 89, 83, 80, 79, 78, 78, 79, 80, 84, 86, 90, 93, 90, 87, - 86, 85, 84, 81, 81, 80, 80, 85, 85, 82, 81, 82, 84, 91, 97, 99, - 101, 90, 84, 90, 91, 90, 97, 89, 81, 76, 73, 73, 74, 79, 81, 97, - 91, 88, 83, 78, 77, 85, 93, 86, 78, 79, 89, 92, 83, 79, 87, 100, - 126, 131, 120, 129, 139, 145, 144, 150, 154, 162, 161, 159, 156, 157, 159, 160, - 162, 168, 170, 169, 168, 168, 169, 167, 168, 171, 171, 172, 172, 171, 169, 162, - 161, 160, 158, 160, 161, 164, 165, 162, 170, 176, 177, 173, 168, 164, 163, 174, - 158, 159, 155, 153, 142, 98, 70, 119, 104, 80, 61, 48, 45, 47, 47, 36, - 65, 72, 127, 144, 168, 181, 175, 184, 190, 192, 190, 188, 191, 191, 187, 199, - 196, 197, 190, 183, 175, 182, 189, 182, 181, 184, 184, 187, 186, 189, 190, 184, - 185, 186, 186, 184, 184, 187, 189, 191, 183, 176, 178, 182, 179, 176, 175, 177, - 179, 174, 175, 182, 176, 170, 177, 176, 161, 167, 144, 137, 121, 140, 140, 148, - 154, 160, 154, 148, 156, 157, 138, 113, 127, 132, 115, 108, 118, 121, 116, 127, - 135, 134, 126, 116, 110, 109, 110, 104, 95, 89, 86, 83, 77, 80, 91, 92, - 118, 96, 82, 83, 82, 82, 81, 80, 81, 80, 75, 77, 80, 81, 82, 83, - 84, 87, 84, 91, 86, 83, 88, 84, 82, 88, 73, 79, 85, 90, 90, 86, - 84, 84, 77, 73, 75, 81, 85, 80, 78, 77, 79, 77, 82, 90, 90, 84, - 90, 105, 100, 125, 129, 121, 128, 139, 142, 144, 150, 155, 161, 161, 157, 154, - 157, 158, 159, 160, 164, 166, 168, 167, 168, 169, 170, 171, 173, 173, 172, 171, - 170, 167, 164, 160, 160, 159, 159, 160, 163, 163, 162, 165, 171, 171, 168, 166, - 166, 167, 174, 154, 156, 148, 151, 144, 127, 71, 107, 111, 114, 116, 107, 91, - 68, 49, 32, 29, 38, 125, 170, 183, 188, 190, 189, 195, 196, 194, 192, 195, - 194, 193, 191, 193, 195, 194, 187, 179, 180, 187, 180, 180, 181, 181, 181, 181, - 181, 181, 180, 182, 183, 182, 183, 182, 183, 185, 190, 183, 178, 180, 184, 181, - 177, 176, 169, 175, 173, 172, 176, 168, 168, 178, 175, 160, 163, 138, 127, 113, - 136, 141, 172, 171, 170, 158, 143, 143, 140, 122, 132, 125, 126, 136, 130, 118, - 118, 135, 142, 119, 101, 102, 109, 110, 112, 116, 124, 109, 95, 90, 87, 83, - 85, 95, 100, 121, 109, 78, 79, 80, 80, 79, 78, 78, 77, 82, 82, 82, - 81, 80, 79, 80, 79, 82, 77, 66, 67, 85, 89, 79, 74, 72, 77, 80, - 79, 74, 74, 78, 81, 90, 78, 71, 76, 85, 86, 83, 81, 87, 89, 95, - 93, 78, 61, 61, 75, 98, 124, 128, 121, 128, 137, 142, 145, 152, 157, 161, - 162, 160, 157, 160, 159, 158, 161, 165, 167, 167, 167, 170, 171, 175, 175, 175, - 174, 173, 171, 171, 167, 165, 163, 162, 160, 159, 159, 162, 162, 163, 163, 166, - 165, 165, 165, 168, 169, 161, 146, 154, 146, 149, 139, 117, 45, 111, 104, 94, - 91, 92, 96, 95, 91, 108, 79, 67, 128, 161, 162, 161, 166, 185, 191, 192, - 190, 188, 192, 191, 190, 185, 189, 196, 199, 193, 183, 181, 184, 185, 185, 185, - 184, 183, 182, 180, 179, 179, 180, 181, 180, 181, 180, 181, 183, 188, 182, 180, - 183, 186, 182, 177, 176, 173, 179, 179, 176, 176, 166, 165, 177, 176, 165, 165, - 139, 123, 116, 142, 150, 146, 145, 152, 156, 144, 137, 131, 118, 125, 132, 136, - 132, 133, 138, 135, 135, 130, 104, 89, 102, 115, 111, 108, 114, 125, 119, 114, - 113, 110, 105, 101, 100, 103, 110, 106, 77, 76, 78, 78, 80, 78, 76, 76, - 86, 82, 77, 71, 70, 72, 77, 79, 65, 78, 79, 71, 67, 64, 72, 89, - 77, 80, 80, 77, 77, 82, 88, 88, 80, 66, 57, 59, 67, 68, 68, 69, - 69, 75, 83, 86, 76, 64, 63, 74, 96, 121, 125, 121, 128, 136, 140, 145, - 151, 154, 159, 161, 161, 162, 164, 165, 161, 162, 167, 167, 169, 170, 172, 173, - 175, 176, 176, 175, 174, 173, 173, 171, 167, 164, 162, 160, 158, 160, 161, 161, - 165, 164, 165, 163, 164, 164, 166, 165, 151, 145, 148, 139, 141, 139, 83, 61, - 106, 99, 93, 91, 96, 98, 97, 95, 92, 86, 90, 124, 154, 173, 190, 201, - 181, 186, 187, 185, 183, 187, 187, 186, 185, 189, 195, 199, 194, 184, 180, 182, - 186, 186, 187, 186, 185, 182, 180, 179, 178, 180, 181, 180, 180, 179, 180, 181, - 185, 181, 181, 185, 188, 182, 177, 176, 182, 185, 181, 177, 178, 169, 164, 174, - 174, 168, 164, 141, 119, 121, 146, 157, 160, 151, 152, 155, 141, 130, 126, 120, - 123, 135, 136, 127, 130, 142, 139, 126, 123, 116, 114, 119, 118, 109, 113, 124, - 123, 126, 124, 124, 120, 115, 112, 111, 107, 100, 101, 75, 74, 75, 75, 77, - 78, 77, 78, 72, 70, 66, 65, 71, 77, 82, 85, 84, 83, 75, 73, 82, - 84, 78, 80, 67, 75, 82, 90, 99, 105, 99, 89, 91, 90, 94, 98, 97, - 90, 82, 81, 73, 73, 75, 78, 78, 76, 79, 87, 93, 117, 123, 121, 131, - 137, 139, 145, 150, 153, 158, 161, 164, 167, 169, 171, 165, 166, 170, 170, 171, - 172, 174, 176, 174, 175, 176, 176, 176, 176, 175, 174, 169, 168, 166, 164, 163, - 165, 166, 166, 170, 169, 167, 166, 166, 164, 162, 156, 144, 143, 136, 124, 125, - 136, 49, 103, 96, 94, 93, 93, 94, 89, 81, 75, 93, 97, 121, 142, 162, - 162, 168, 175, 186, 191, 190, 188, 185, 189, 189, 188, 190, 190, 194, 195, 190, - 182, 179, 181, 180, 181, 182, 182, 182, 180, 178, 176, 179, 180, 181, 180, 180, - 179, 180, 181, 182, 180, 181, 186, 188, 182, 178, 177, 184, 182, 174, 172, 180, - 173, 166, 171, 165, 165, 159, 140, 111, 117, 134, 141, 157, 141, 134, 131, 123, - 125, 136, 141, 143, 127, 128, 142, 144, 130, 124, 134, 134, 138, 134, 118, 109, - 111, 123, 132, 129, 131, 131, 121, 111, 110, 115, 118, 110, 106, 108, 75, 72, - 72, 73, 75, 77, 77, 79, 72, 72, 74, 80, 87, 89, 86, 83, 91, 84, - 75, 81, 100, 100, 81, 69, 81, 84, 86, 85, 94, 101, 94, 82, 90, 91, - 93, 93, 87, 80, 82, 86, 104, 95, 84, 75, 73, 74, 74, 78, 92, 113, - 119, 121, 131, 137, 139, 147, 150, 152, 156, 160, 165, 169, 171, 172, 168, 170, - 171, 172, 172, 172, 174, 176, 173, 174, 175, 176, 176, 176, 176, 174, 174, 171, - 169, 168, 169, 170, 171, 172, 172, 170, 168, 167, 166, 163, 158, 149, 130, 135, - 135, 123, 118, 110, 23, 94, 91, 86, 80, 75, 77, 81, 87, 93, 98, 82, - 114, 142, 175, 169, 173, 190, 190, 194, 192, 189, 186, 189, 189, 188, 193, 190, - 190, 190, 186, 180, 179, 182, 179, 180, 182, 184, 183, 182, 180, 178, 179, 180, - 181, 180, 179, 178, 179, 180, 182, 180, 183, 187, 189, 183, 180, 181, 184, 180, - 171, 172, 184, 181, 173, 175, 165, 166, 155, 138, 105, 114, 122, 126, 124, 120, - 125, 131, 130, 136, 145, 143, 134, 129, 131, 140, 144, 142, 140, 144, 141, 146, - 141, 129, 127, 133, 132, 122, 128, 137, 143, 134, 123, 114, 111, 108, 106, 114, - 117, 74, 70, 68, 69, 69, 71, 77, 80, 85, 85, 87, 92, 97, 96, 91, - 85, 68, 90, 101, 93, 82, 71, 78, 99, 102, 103, 97, 87, 89, 99, 100, - 94, 104, 102, 95, 91, 86, 85, 95, 105, 94, 89, 85, 83, 83, 85, 84, - 84, 89, 107, 115, 118, 130, 135, 140, 149, 154, 154, 157, 161, 167, 171, 172, - 173, 171, 173, 172, 171, 170, 170, 172, 174, 173, 174, 174, 174, 174, 173, 173, - 172, 172, 171, 170, 169, 170, 171, 172, 173, 173, 169, 166, 164, 163, 160, 155, - 147, 124, 128, 130, 118, 112, 77, 51, 75, 82, 87, 92, 96, 98, 97, 99, - 101, 114, 98, 130, 139, 171, 170, 176, 192, 190, 194, 192, 187, 183, 186, 186, - 185, 190, 187, 186, 187, 185, 180, 179, 183, 181, 183, 185, 186, 186, 184, 181, - 179, 178, 179, 179, 178, 177, 176, 176, 178, 184, 183, 185, 189, 190, 185, 184, - 186, 186, 183, 175, 175, 182, 178, 173, 179, 169, 169, 151, 138, 102, 117, 122, - 127, 136, 143, 152, 152, 143, 144, 141, 125, 119, 134, 137, 131, 137, 153, 156, - 148, 143, 146, 146, 147, 149, 148, 139, 129, 133, 139, 143, 138, 131, 126, 116, - 104, 108, 112, 109, 73, 67, 66, 65, 67, 70, 75, 79, 85, 80, 81, 83, - 93, 97, 98, 94, 101, 90, 72, 70, 89, 96, 91, 91, 76, 88, 93, 91, - 92, 98, 98, 91, 87, 88, 89, 92, 88, 85, 86, 92, 88, 94, 99, 103, - 100, 94, 83, 76, 87, 104, 113, 118, 129, 135, 138, 150, 155, 157, 159, 161, - 167, 170, 170, 170, 172, 173, 171, 170, 168, 168, 170, 171, 175, 175, 175, 172, - 173, 170, 168, 167, 168, 167, 166, 166, 167, 168, 170, 172, 170, 166, 163, 158, - 159, 156, 155, 148, 138, 129, 122, 98, 97, 57, 116, 100, 94, 95, 93, 86, - 80, 78, 83, 89, 90, 106, 157, 143, 167, 178, 182, 180, 193, 197, 194, 188, - 184, 186, 186, 185, 187, 184, 184, 186, 185, 181, 180, 183, 179, 181, 183, 184, - 182, 180, 176, 174, 176, 177, 178, 176, 176, 174, 174, 176, 187, 186, 188, 191, - 192, 187, 187, 190, 184, 184, 177, 173, 175, 167, 163, 172, 164, 164, 144, 132, - 98, 119, 126, 130, 131, 134, 136, 125, 119, 133, 143, 134, 139, 129, 130, 142, - 143, 133, 135, 151, 151, 143, 143, 145, 141, 138, 146, 156, 148, 137, 122, 108, - 110, 119, 123, 122, 115, 110, 98, 73, 69, 71, 71, 73, 74, 76, 78, 85, - 83, 85, 74, 64, 69, 77, 70, 58, 72, 80, 81, 85, 80, 80, 90, 99, - 95, 96, 103, 97, 79, 69, 75, 97, 97, 92, 88, 87, 89, 93, 98, 88, - 93, 97, 101, 100, 101, 105, 108, 93, 100, 113, 122, 127, 132, 135, 140, 155, - 156, 160, 161, 164, 168, 175, 179, 172, 171, 170, 169, 169, 170, 170, 171, 170, - 168, 169, 168, 171, 171, 172, 173, 166, 163, 169, 170, 161, 163, 168, 167, 163, - 166, 168, 160, 158, 154, 152, 145, 146, 111, 125, 110, 79, 104, 121, 99, 115, - 112, 106, 102, 99, 96, 96, 96, 80, 117, 146, 154, 165, 170, 176, 182, 189, - 192, 192, 191, 185, 184, 184, 187, 196, 191, 185, 183, 183, 182, 179, 175, 176, - 178, 181, 183, 183, 182, 180, 179, 184, 180, 176, 176, 181, 183, 181, 179, 192, - 191, 190, 191, 193, 190, 184, 179, 188, 185, 180, 174, 170, 168, 167, 168, 164, - 142, 150, 121, 73, 127, 125, 138, 132, 137, 138, 138, 133, 130, 132, 136, 143, - 146, 148, 150, 148, 145, 150, 157, 148, 141, 135, 137, 141, 142, 137, 128, 131, - 129, 124, 116, 99, 87, 91, 110, 114, 114, 109, 75, 72, 71, 73, 72, 73, - 76, 78, 83, 81, 84, 80, 73, 80, 88, 80, 66, 73, 69, 71, 81, 88, - 93, 107, 91, 95, 95, 93, 92, 93, 92, 91, 85, 94, 100, 101, 97, 89, - 85, 81, 91, 99, 113, 117, 110, 95, 79, 67, 101, 96, 98, 108, 117, 120, - 125, 134, 146, 151, 156, 161, 164, 166, 170, 170, 174, 173, 172, 171, 171, 171, - 172, 171, 169, 168, 168, 166, 165, 163, 160, 160, 173, 166, 172, 172, 170, 170, - 174, 166, 169, 165, 158, 151, 149, 150, 145, 141, 131, 128, 131, 108, 99, 113, - 114, 119, 119, 119, 118, 115, 112, 108, 106, 100, 91, 123, 149, 156, 168, 173, - 178, 182, 188, 190, 191, 192, 189, 188, 186, 187, 186, 185, 184, 184, 184, 181, - 178, 175, 179, 178, 177, 176, 176, 177, 179, 180, 182, 176, 169, 167, 172, 180, - 188, 192, 194, 194, 193, 189, 186, 183, 182, 182, 184, 179, 172, 170, 171, 171, - 170, 166, 179, 157, 152, 106, 79, 122, 116, 122, 123, 125, 124, 125, 129, 142, - 158, 174, 161, 158, 159, 163, 162, 158, 157, 159, 148, 143, 141, 140, 141, 142, - 142, 139, 139, 133, 126, 118, 100, 80, 71, 78, 110, 140, 132, 79, 75, 75, - 76, 77, 79, 78, 80, 86, 81, 85, 86, 84, 90, 95, 87, 80, 77, 64, - 59, 67, 71, 70, 79, 86, 97, 101, 94, 90, 95, 89, 78, 94, 89, 77, - 66, 63, 73, 91, 103, 113, 105, 92, 80, 80, 91, 108, 119, 91, 83, 88, - 101, 113, 118, 129, 141, 140, 147, 157, 162, 166, 166, 166, 166, 173, 171, 171, - 170, 170, 169, 169, 168, 161, 161, 164, 165, 163, 161, 159, 158, 167, 158, 162, - 164, 164, 166, 166, 155, 161, 160, 157, 155, 155, 151, 136, 123, 127, 141, 122, - 93, 115, 123, 105, 130, 129, 129, 131, 131, 129, 123, 119, 114, 102, 129, 149, - 156, 170, 175, 178, 181, 186, 187, 189, 192, 193, 192, 187, 184, 176, 180, 184, - 185, 184, 180, 177, 176, 179, 179, 177, 176, 176, 177, 178, 178, 172, 175, 179, - 182, 185, 187, 189, 190, 198, 199, 197, 191, 186, 184, 187, 192, 185, 177, 170, - 169, 173, 175, 171, 165, 157, 146, 138, 84, 97, 130, 122, 122, 128, 130, 124, - 116, 109, 106, 109, 114, 148, 147, 148, 157, 163, 161, 159, 156, 148, 150, 150, - 149, 145, 143, 141, 141, 111, 103, 97, 97, 93, 82, 69, 72, 96, 137, 132, - 81, 79, 80, 80, 82, 85, 85, 87, 92, 86, 90, 91, 90, 93, 95, 86, - 92, 93, 84, 77, 83, 80, 75, 78, 63, 71, 75, 77, 81, 91, 93, 91, - 93, 92, 88, 85, 79, 75, 69, 65, 74, 82, 93, 99, 97, 88, 75, 67, - 68, 75, 84, 87, 95, 109, 121, 126, 135, 142, 152, 159, 161, 163, 163, 163, - 169, 166, 168, 166, 166, 164, 164, 163, 158, 157, 158, 156, 156, 154, 153, 155, - 164, 158, 162, 165, 162, 163, 165, 155, 169, 164, 154, 144, 143, 149, 148, 147, - 133, 133, 104, 81, 114, 127, 106, 125, 128, 130, 132, 132, 131, 125, 121, 117, - 109, 129, 146, 154, 170, 175, 177, 181, 186, 186, 187, 192, 194, 192, 184, 178, - 176, 180, 184, 185, 181, 178, 178, 179, 178, 180, 182, 183, 183, 181, 179, 177, - 173, 179, 186, 189, 189, 186, 185, 186, 199, 198, 195, 191, 190, 189, 191, 193, - 187, 182, 177, 174, 174, 172, 169, 165, 156, 154, 146, 78, 114, 123, 112, 100, - 105, 110, 118, 121, 126, 128, 131, 134, 123, 124, 126, 133, 139, 138, 138, 139, - 132, 133, 136, 136, 131, 124, 116, 110, 114, 105, 94, 92, 91, 85, 75, 76, - 92, 114, 115, 82, 81, 82, 83, 87, 88, 90, 91, 93, 86, 90, 93, 89, - 91, 93, 85, 74, 83, 85, 86, 95, 93, 93, 100, 110, 94, 79, 71, 61, - 53, 54, 60, 69, 72, 81, 94, 102, 93, 72, 53, 84, 80, 74, 71, 72, - 77, 82, 86, 85, 104, 107, 87, 84, 102, 114, 111, 126, 133, 140, 146, 150, - 155, 157, 159, 164, 162, 164, 163, 163, 160, 159, 157, 159, 156, 151, 147, 146, - 145, 144, 147, 152, 151, 158, 158, 152, 152, 157, 152, 153, 160, 165, 161, 153, - 148, 142, 137, 121, 108, 104, 95, 105, 121, 113, 117, 116, 116, 117, 114, 114, - 111, 110, 109, 109, 130, 145, 155, 173, 177, 181, 186, 188, 188, 187, 191, 191, - 189, 180, 175, 183, 185, 185, 182, 178, 177, 179, 183, 182, 182, 182, 182, 182, - 181, 181, 181, 185, 183, 179, 174, 173, 177, 186, 194, 200, 195, 191, 190, 194, - 193, 187, 181, 181, 182, 181, 177, 171, 168, 170, 169, 154, 156, 142, 73, 118, - 117, 118, 108, 129, 127, 118, 111, 105, 103, 103, 105, 117, 115, 116, 116, 112, - 109, 112, 117, 122, 117, 114, 113, 113, 110, 101, 94, 97, 94, 94, 93, 91, - 89, 85, 85, 88, 89, 84, 81, 81, 83, 85, 86, 88, 91, 92, 92, 83, - 88, 94, 90, 90, 96, 92, 75, 83, 78, 76, 81, 80, 81, 90, 89, 81, - 83, 91, 90, 80, 77, 80, 63, 52, 47, 54, 66, 73, 71, 67, 44, 49, - 60, 73, 85, 93, 97, 99, 98, 114, 108, 81, 73, 94, 110, 107, 122, 127, - 134, 140, 145, 151, 158, 159, 159, 160, 160, 159, 159, 157, 155, 152, 151, 149, - 146, 145, 145, 144, 146, 148, 145, 145, 152, 153, 145, 145, 154, 151, 143, 154, - 163, 156, 140, 123, 108, 96, 98, 88, 115, 116, 100, 110, 115, 116, 110, 109, - 107, 103, 102, 101, 101, 102, 111, 132, 147, 159, 177, 180, 184, 192, 191, 191, - 189, 189, 188, 186, 180, 177, 190, 188, 184, 180, 177, 178, 181, 184, 186, 183, - 178, 175, 175, 179, 185, 189, 183, 182, 180, 179, 182, 186, 191, 196, 206, 199, - 194, 195, 201, 198, 187, 176, 171, 176, 179, 177, 169, 167, 170, 174, 148, 144, - 122, 64, 108, 108, 122, 120, 119, 121, 121, 123, 127, 126, 124, 123, 114, 113, - 114, 114, 109, 105, 111, 119, 96, 86, 73, 70, 74, 78, 79, 77, 81, 90, - 102, 105, 106, 105, 101, 95, 97, 97, 85, 87, 88, 88, 89, 90, 90, 93, - 93, 94, 86, 91, 97, 91, 90, 97, 99, 105, 107, 96, 89, 91, 87, 83, - 85, 95, 99, 107, 112, 108, 97, 81, 67, 69, 59, 53, 50, 47, 41, 33, - 28, 36, 39, 47, 57, 68, 73, 73, 74, 81, 87, 82, 72, 73, 86, 96, - 97, 112, 119, 126, 134, 140, 145, 152, 155, 153, 151, 152, 152, 152, 149, 148, - 146, 138, 137, 139, 139, 136, 132, 130, 130, 135, 131, 135, 137, 133, 136, 145, - 141, 143, 138, 124, 104, 94, 98, 106, 107, 94, 85, 107, 107, 96, 103, 104, - 109, 106, 105, 104, 102, 100, 97, 96, 101, 109, 133, 150, 162, 177, 178, 182, - 193, 193, 193, 191, 189, 185, 185, 184, 186, 191, 187, 181, 178, 178, 180, 182, - 183, 183, 182, 180, 180, 181, 183, 187, 189, 178, 181, 187, 193, 199, 199, 195, - 192, 200, 197, 194, 196, 200, 197, 189, 182, 171, 174, 177, 176, 171, 171, 172, - 173, 166, 150, 117, 71, 98, 93, 103, 93, 90, 95, 101, 109, 113, 112, 105, - 99, 107, 105, 106, 109, 111, 109, 112, 116, 114, 106, 98, 95, 97, 103, 107, - 111, 119, 128, 133, 131, 126, 122, 112, 97, 112, 116, 105, 94, 94, 94, 93, - 95, 95, 94, 96, 100, 92, 97, 102, 93, 89, 97, 102, 104, 105, 96, 97, - 107, 104, 93, 91, 95, 100, 97, 86, 84, 89, 88, 75, 72, 65, 65, 60, - 53, 50, 49, 53, 54, 52, 54, 59, 67, 74, 80, 82, 91, 85, 84, 97, - 105, 100, 96, 99, 92, 97, 107, 115, 122, 127, 133, 136, 139, 139, 139, 140, - 140, 137, 134, 132, 128, 127, 125, 122, 113, 100, 88, 83, 88, 80, 80, 83, - 82, 90, 97, 90, 80, 88, 96, 103, 111, 118, 119, 111, 108, 91, 89, 82, - 93, 102, 88, 96, 99, 99, 99, 98, 96, 92, 90, 94, 104, 130, 148, 162, - 174, 173, 176, 190, 192, 193, 192, 189, 184, 185, 188, 193, 189, 183, 179, 176, - 180, 183, 183, 182, 175, 180, 187, 193, 194, 192, 187, 184, 187, 185, 183, 185, - 192, 196, 197, 196, 184, 184, 185, 187, 188, 187, 187, 185, 179, 179, 177, 177, - 175, 175, 174, 169, 161, 142, 112, 88, 111, 104, 108, 93, 101, 97, 93, 93, - 98, 103, 105, 104, 105, 100, 98, 102, 107, 104, 100, 97, 102, 103, 104, 103, - 103, 102, 104, 108, 113, 117, 118, 116, 118, 123, 119, 106, 92, 95, 94, 92, - 86, 84, 88, 94, 94, 95, 96, 101, 98, 97, 100, 100, 96, 97, 100, 102, - 102, 100, 96, 92, 89, 91, 91, 92, 88, 83, 79, 77, 79, 79, 79, 74, - 77, 80, 82, 80, 76, 70, 68, 61, 69, 66, 62, 68, 71, 79, 93, 86, - 87, 89, 92, 93, 94, 94, 95, 101, 96, 89, 86, 88, 96, 105, 114, 119, - 120, 118, 112, 108, 108, 114, 120, 109, 100, 84, 68, 62, 69, 76, 80, 94, - 97, 100, 100, 99, 97, 99, 101, 106, 106, 106, 107, 107, 107, 108, 106, 98, - 97, 97, 97, 97, 98, 97, 98, 100, 95, 95, 96, 96, 94, 96, 106, 110, - 129, 143, 152, 164, 179, 186, 186, 186, 185, 187, 193, 192, 188, 188, 191, 192, - 181, 174, 170, 177, 180, 178, 175, 178, 184, 187, 183, 183, 186, 186, 180, 179, - 188, 195, 194, 188, 186, 192, 199, 193, 186, 180, 183, 190, 192, 188, 181, 176, - 176, 178, 180, 181, 177, 173, 167, 153, 155, 78, 120, 102, 101, 105, 106, 104, - 100, 99, 98, 97, 98, 97, 95, 98, 96, 94, 92, 94, 97, 103, 105, 100, - 100, 103, 103, 103, 104, 102, 103, 105, 108, 117, 123, 119, 120, 110, 88, 79, - 85, 110, 88, 87, 89, 95, 97, 95, 96, 100, 101, 98, 97, 99, 99, 95, - 95, 98, 96, 98, 100, 98, 94, 91, 90, 87, 90, 85, 82, 80, 78, 78, - 80, 82, 80, 83, 84, 85, 84, 83, 82, 81, 72, 83, 84, 82, 85, 81, - 79, 87, 88, 88, 88, 89, 90, 92, 94, 95, 93, 93, 93, 93, 93, 93, - 93, 95, 88, 92, 93, 87, 83, 81, 85, 87, 76, 83, 90, 95, 100, 104, - 100, 95, 94, 95, 96, 96, 97, 97, 99, 100, 102, 102, 101, 100, 102, 101, - 100, 98, 97, 94, 95, 94, 92, 91, 91, 91, 100, 97, 99, 102, 103, 99, - 99, 106, 113, 119, 133, 154, 170, 176, 184, 191, 184, 183, 186, 190, 189, 186, - 186, 188, 184, 178, 172, 169, 171, 175, 181, 183, 182, 186, 188, 185, 186, 189, - 190, 185, 183, 187, 190, 191, 190, 190, 193, 197, 195, 189, 183, 182, 184, 183, - 177, 173, 175, 175, 176, 177, 177, 173, 169, 163, 159, 142, 89, 117, 107, 105, - 105, 98, 101, 101, 98, 99, 101, 102, 103, 103, 98, 96, 93, 90, 90, 92, - 93, 95, 99, 101, 101, 100, 99, 102, 104, 108, 121, 114, 108, 101, 97, 107, - 116, 108, 65, 94, 116, 76, 79, 85, 91, 90, 86, 89, 96, 97, 94, 94, - 96, 97, 92, 93, 96, 93, 97, 102, 102, 100, 95, 92, 87, 89, 85, 85, - 84, 83, 84, 85, 86, 81, 80, 79, 79, 80, 83, 85, 87, 79, 90, 90, - 89, 91, 85, 80, 86, 90, 89, 88, 87, 89, 91, 94, 96, 96, 98, 101, - 104, 104, 101, 98, 98, 111, 116, 117, 116, 113, 108, 108, 107, 106, 109, 109, - 107, 105, 104, 98, 92, 103, 102, 100, 100, 104, 106, 106, 106, 110, 109, 110, - 108, 106, 105, 103, 103, 107, 104, 102, 100, 98, 97, 98, 98, 101, 99, 103, - 107, 107, 102, 100, 106, 114, 112, 123, 153, 171, 169, 176, 190, 184, 181, 183, - 185, 185, 183, 184, 185, 179, 176, 176, 172, 170, 173, 181, 187, 184, 187, 189, - 186, 187, 191, 191, 190, 193, 192, 191, 191, 192, 193, 194, 193, 199, 196, 191, - 188, 186, 182, 178, 175, 176, 175, 176, 177, 175, 174, 168, 162, 152, 114, 99, - 110, 109, 110, 109, 95, 101, 101, 101, 101, 103, 105, 108, 109, 106, 104, 102, - 99, 98, 98, 98, 99, 106, 108, 108, 105, 102, 105, 110, 116, 107, 108, 116, - 118, 112, 110, 107, 93, 101, 64, 96, 69, 70, 74, 81, 85, 83, 86, 91, - 92, 90, 92, 95, 97, 93, 94, 98, 96, 99, 100, 100, 97, 92, 88, 85, - 83, 85, 85, 86, 85, 86, 86, 86, 83, 82, 80, 80, 82, 85, 88, 90, - 85, 93, 90, 87, 92, 91, 89, 98, 93, 93, 94, 94, 95, 97, 99, 100, - 106, 105, 104, 104, 106, 108, 110, 114, 108, 113, 113, 113, 108, 106, 104, 104, - 113, 111, 106, 100, 100, 106, 110, 108, 112, 107, 102, 102, 106, 109, 108, 107, - 112, 111, 112, 111, 109, 108, 106, 106, 114, 110, 109, 104, 104, 105, 106, 107, - 101, 99, 102, 106, 106, 100, 100, 105, 116, 111, 119, 138, 155, 161, 167, 180, - 183, 182, 181, 182, 182, 181, 182, 181, 179, 177, 177, 174, 172, 173, 178, 181, - 182, 182, 183, 182, 183, 186, 189, 189, 197, 195, 193, 191, 190, 190, 189, 189, - 193, 193, 191, 189, 185, 182, 181, 181, 174, 173, 173, 172, 173, 170, 164, 159, - 143, 94, 111, 106, 103, 105, 104, 90, 105, 104, 103, 101, 100, 101, 103, 105, - 107, 107, 107, 107, 107, 107, 107, 109, 109, 111, 113, 109, 104, 106, 109, 114, - 116, 112, 114, 114, 103, 102, 105, 99, 97, 90, 82, 75, 70, 69, 77, 84, - 88, 92, 96, 93, 89, 90, 94, 95, 90, 89, 92, 94, 95, 95, 92, 89, - 88, 86, 87, 82, 84, 85, 87, 88, 88, 87, 84, 90, 89, 89, 90, 90, - 91, 92, 93, 90, 97, 94, 93, 100, 99, 97, 104, 97, 99, 102, 105, 106, - 106, 105, 104, 110, 108, 105, 104, 105, 108, 112, 117, 117, 120, 120, 119, 116, - 115, 114, 115, 101, 105, 108, 110, 113, 115, 113, 109, 116, 111, 106, 104, 105, - 107, 106, 104, 105, 105, 107, 107, 106, 106, 107, 107, 110, 106, 106, 102, 104, - 103, 105, 107, 104, 100, 99, 101, 102, 97, 101, 107, 111, 114, 116, 122, 136, - 154, 167, 170, 178, 181, 180, 179, 178, 179, 178, 178, 176, 175, 174, 175, 178, - 179, 178, 177, 183, 181, 180, 180, 183, 185, 188, 191, 192, 195, 196, 194, 190, - 188, 191, 194, 185, 187, 187, 185, 182, 180, 180, 182, 172, 170, 168, 164, 163, - 158, 151, 145, 138, 92, 125, 105, 101, 95, 94, 85, 104, 105, 104, 101, 98, - 97, 99, 101, 103, 104, 105, 106, 107, 108, 108, 108, 104, 106, 110, 110, 107, - 106, 108, 109, 117, 111, 114, 116, 107, 106, 110, 105, 103, 97, 127, 79, 71, - 68, 74, 83, 88, 92, 96, 95, 92, 93, 93, 91, 84, 81, 81, 86, 86, - 85, 84, 83, 85, 88, 92, 85, 87, 87, 89, 90, 90, 89, 88, 90, 90, - 91, 92, 92, 92, 91, 91, 86, 95, 96, 98, 104, 99, 91, 94, 94, 97, - 101, 105, 106, 105, 102, 100, 107, 107, 107, 107, 106, 105, 104, 105, 109, 110, - 108, 105, 105, 107, 107, 108, 110, 114, 114, 110, 108, 107, 103, 97, 114, 111, - 107, 105, 105, 104, 104, 103, 104, 105, 107, 107, 108, 108, 111, 111, 109, 109, - 108, 105, 105, 107, 108, 107, 108, 103, 101, 101, 102, 100, 103, 109, 106, 114, - 117, 113, 124, 145, 161, 167, 169, 174, 176, 174, 175, 176, 175, 172, 169, 168, - 169, 173, 179, 182, 181, 179, 186, 182, 180, 182, 185, 184, 187, 191, 183, 188, - 193, 193, 190, 190, 193, 196, 186, 186, 186, 184, 181, 178, 178, 176, 178, 173, - 168, 161, 155, 147, 138, 131, 121, 92, 121, 104, 101, 97, 98, 98, 99, 104, - 107, 106, 102, 101, 103, 106, 105, 105, 105, 105, 105, 106, 106, 108, 104, 105, - 108, 111, 112, 112, 113, 113, 106, 101, 111, 119, 114, 110, 110, 103, 102, 95, - 106, 75, 69, 70, 75, 79, 80, 84, 88, 90, 88, 89, 89, 86, 78, 75, - 76, 82, 82, 82, 81, 80, 82, 85, 89, 88, 89, 90, 91, 91, 91, 91, - 89, 89, 87, 87, 88, 88, 89, 89, 89, 86, 93, 93, 94, 101, 97, 88, - 91, 92, 94, 97, 99, 101, 100, 99, 98, 105, 106, 107, 107, 106, 104, 102, - 103, 110, 109, 108, 109, 111, 111, 111, 111, 106, 107, 103, 99, 100, 108, 113, - 114, 109, 109, 110, 108, 107, 106, 106, 107, 110, 110, 112, 113, 113, 114, 114, - 116, 114, 114, 114, 113, 112, 110, 110, 110, 107, 103, 101, 105, 105, 102, 103, - 107, 110, 111, 114, 115, 119, 127, 141, 155, 160, 167, 171, 169, 170, 172, 170, - 164, 163, 164, 165, 166, 170, 173, 178, 182, 185, 180, 179, 182, 185, 182, 183, - 188, 181, 183, 187, 189, 190, 190, 188, 187, 185, 184, 182, 181, 180, 178, 176, - 175, 172, 166, 159, 151, 143, 134, 125, 116, 108, 97, 107, 98, 103, 98, 99, - 104, 97, 102, 108, 109, 105, 103, 105, 107, 109, 108, 108, 107, 107, 108, 111, - 111, 111, 107, 106, 107, 111, 112, 112, 108, 119, 101, 94, 94, 91, 96, 106, - 107, 106, 31, 61, 74, 74, 77, 80, 78, 75, 79, 85, 83, 82, 82, 85, - 85, 79, 76, 78, 81, 82, 82, 81, 78, 78, 82, 84, 88, 88, 89, 89, - 89, 89, 91, 89, 91, 89, 88, 88, 89, 91, 93, 95, 94, 97, 91, 89, - 98, 99, 97, 103, 98, 98, 100, 101, 102, 103, 104, 104, 108, 107, 105, 104, - 104, 107, 109, 111, 105, 106, 107, 109, 111, 111, 110, 109, 110, 113, 111, 108, - 108, 109, 109, 106, 106, 108, 111, 111, 109, 108, 110, 112, 109, 109, 111, 111, - 111, 111, 111, 113, 116, 118, 116, 115, 114, 112, 111, 108, 105, 101, 104, 106, - 107, 102, 101, 104, 113, 109, 110, 118, 115, 107, 118, 139, 151, 160, 165, 163, - 164, 167, 163, 156, 161, 164, 165, 161, 159, 161, 172, 181, 183, 178, 178, 181, - 182, 178, 178, 183, 186, 183, 183, 186, 190, 188, 181, 174, 177, 175, 173, 173, - 174, 174, 172, 168, 152, 147, 140, 133, 127, 121, 111, 104, 112, 110, 99, 95, - 98, 91, 86, 91, 95, 101, 109, 109, 105, 101, 102, 104, 107, 106, 106, 106, - 107, 109, 113, 116, 115, 107, 98, 96, 101, 102, 98, 93, 98, 87, 93, 104, - 99, 91, 83, 72, 89, 59, 83, 74, 76, 78, 80, 81, 81, 78, 72, 75, - 77, 79, 81, 83, 81, 79, 78, 79, 77, 79, 80, 80, 80, 82, 82, 79, - 84, 90, 91, 91, 91, 94, 95, 89, 87, 88, 89, 89, 90, 91, 91, 91, - 89, 87, 86, 88, 91, 95, 98, 92, 96, 100, 102, 101, 100, 100, 101, 100, - 101, 101, 102, 104, 105, 106, 106, 106, 107, 108, 108, 108, 110, 112, 115, 115, - 111, 107, 106, 110, 112, 110, 105, 111, 102, 106, 110, 102, 100, 109, 111, 117, - 115, 111, 109, 110, 111, 113, 114, 111, 114, 115, 113, 112, 109, 107, 103, 104, - 100, 103, 106, 108, 105, 104, 107, 105, 106, 107, 112, 119, 122, 121, 121, 141, - 139, 139, 142, 148, 153, 152, 152, 154, 154, 154, 144, 142, 159, 165, 149, 164, - 172, 173, 170, 173, 171, 170, 179, 180, 179, 177, 175, 173, 172, 172, 172, 172, - 170, 168, 166, 164, 162, 160, 156, 149, 140, 128, 118, 113, 112, 116, 117, 113, - 109, 106, 99, 94, 92, 97, 103, 101, 99, 99, 103, 107, 107, 103, 97, 103, - 104, 109, 112, 112, 105, 95, 86, 81, 86, 86, 87, 91, 96, 93, 87, 91, - 89, 91, 97, 103, 103, 96, 88, 81, 68, 63, 83, 81, 81, 80, 83, 84, - 85, 82, 92, 88, 85, 81, 79, 78, 80, 81, 78, 78, 79, 80, 82, 83, - 84, 84, 83, 83, 86, 88, 90, 93, 92, 89, 89, 87, 88, 89, 90, 90, - 91, 91, 89, 89, 89, 90, 91, 93, 95, 96, 92, 95, 99, 100, 101, 101, - 102, 103, 104, 104, 104, 104, 104, 105, 105, 105, 108, 109, 110, 110, 109, 110, - 110, 112, 113, 110, 106, 108, 109, 111, 109, 106, 112, 101, 104, 111, 107, 106, - 109, 105, 111, 110, 107, 106, 108, 110, 112, 114, 115, 117, 116, 115, 112, 111, - 110, 110, 108, 106, 108, 110, 110, 105, 104, 106, 107, 108, 111, 118, 123, 125, - 127, 128, 130, 123, 115, 113, 118, 128, 134, 137, 146, 142, 138, 131, 129, 147, - 158, 150, 158, 168, 168, 167, 172, 167, 163, 168, 164, 164, 166, 165, 167, 166, - 168, 166, 163, 157, 156, 156, 164, 164, 163, 157, 133, 128, 121, 114, 112, 112, - 112, 111, 110, 107, 105, 100, 96, 91, 92, 96, 100, 100, 101, 105, 110, 111, - 110, 105, 111, 109, 109, 108, 109, 110, 112, 113, 99, 99, 92, 87, 89, 96, - 99, 97, 109, 106, 110, 111, 112, 101, 87, 74, 90, 92, 90, 86, 84, 85, - 86, 88, 88, 88, 87, 94, 91, 87, 82, 79, 78, 79, 79, 79, 77, 80, - 81, 82, 83, 84, 84, 86, 83, 81, 84, 88, 92, 89, 83, 89, 88, 88, - 89, 90, 91, 91, 91, 88, 90, 92, 94, 95, 95, 95, 94, 93, 95, 98, - 99, 99, 100, 103, 105, 105, 105, 104, 103, 102, 102, 103, 103, 107, 109, 111, - 110, 109, 107, 108, 109, 112, 109, 107, 108, 111, 112, 110, 105, 112, 100, 105, - 113, 112, 112, 111, 101, 106, 105, 105, 105, 106, 108, 111, 113, 117, 116, 114, - 112, 111, 112, 112, 112, 115, 110, 111, 114, 113, 107, 106, 108, 103, 106, 112, - 116, 119, 122, 126, 129, 133, 131, 128, 128, 130, 129, 126, 122, 132, 123, 121, - 121, 118, 126, 135, 133, 132, 143, 145, 150, 163, 160, 155, 157, 153, 154, 158, - 157, 160, 158, 159, 156, 156, 146, 142, 141, 148, 147, 142, 132, 119, 118, 117, - 116, 115, 114, 110, 108, 106, 107, 106, 104, 101, 98, 96, 96, 96, 95, 96, - 100, 106, 109, 110, 108, 113, 112, 112, 110, 112, 115, 122, 126, 130, 130, 122, - 115, 115, 120, 120, 119, 116, 106, 99, 92, 91, 88, 84, 79, 92, 103, 99, - 78, 77, 81, 86, 90, 87, 83, 82, 82, 82, 83, 85, 84, 81, 79, 76, - 76, 77, 78, 79, 80, 81, 82, 82, 87, 86, 85, 86, 88, 88, 86, 83, - 90, 88, 89, 89, 90, 91, 92, 92, 90, 91, 93, 95, 96, 96, 96, 95, - 96, 97, 98, 98, 98, 99, 101, 104, 101, 101, 99, 99, 99, 99, 100, 101, - 106, 108, 111, 111, 110, 108, 108, 108, 111, 109, 108, 109, 111, 112, 110, 108, - 112, 102, 107, 112, 110, 110, 111, 101, 104, 103, 104, 104, 104, 106, 109, 110, - 113, 113, 113, 113, 112, 112, 111, 110, 116, 113, 113, 114, 116, 112, 112, 112, - 102, 106, 113, 116, 116, 117, 123, 128, 127, 128, 131, 134, 134, 128, 120, 114, - 124, 114, 118, 126, 121, 116, 117, 115, 120, 127, 128, 133, 149, 148, 141, 142, - 144, 145, 147, 145, 145, 141, 138, 135, 142, 135, 130, 127, 128, 125, 120, 114, - 116, 116, 118, 118, 117, 114, 111, 109, 103, 102, 103, 103, 104, 103, 103, 103, - 97, 95, 96, 98, 103, 106, 109, 109, 112, 116, 122, 122, 121, 119, 121, 122, - 124, 129, 130, 127, 125, 122, 118, 110, 109, 99, 87, 78, 77, 78, 81, 80, - 78, 88, 90, 79, 74, 75, 80, 83, 81, 81, 84, 81, 83, 86, 88, 89, - 88, 88, 83, 79, 79, 80, 81, 81, 81, 82, 82, 85, 88, 90, 89, 86, - 85, 85, 87, 88, 88, 89, 90, 91, 91, 92, 92, 94, 93, 93, 93, 94, - 95, 96, 97, 98, 99, 100, 99, 97, 97, 99, 101, 99, 98, 97, 97, 98, - 100, 102, 104, 101, 104, 109, 110, 109, 108, 108, 109, 110, 110, 112, 113, 114, - 114, 112, 108, 109, 105, 110, 110, 103, 104, 110, 104, 107, 106, 105, 104, 105, - 106, 107, 107, 110, 110, 114, 116, 116, 114, 111, 109, 115, 112, 113, 115, 117, - 115, 116, 118, 113, 114, 119, 121, 120, 120, 124, 129, 123, 121, 119, 119, 120, - 122, 125, 127, 143, 132, 138, 147, 141, 133, 134, 134, 128, 131, 126, 124, 133, - 130, 121, 123, 129, 130, 132, 129, 128, 122, 120, 116, 121, 120, 123, 121, 123, - 120, 124, 123, 118, 116, 117, 116, 113, 110, 107, 107, 100, 99, 100, 99, 102, - 105, 105, 106, 104, 102, 100, 100, 104, 107, 111, 111, 113, 118, 126, 129, 127, - 122, 121, 121, 113, 120, 125, 125, 123, 119, 113, 106, 110, 107, 104, 99, 95, - 84, 76, 70, 73, 75, 83, 92, 82, 77, 80, 84, 84, 89, 95, 95, 92, - 90, 89, 89, 91, 95, 95, 86, 84, 84, 85, 84, 84, 85, 85, 84, 89, - 92, 91, 87, 82, 86, 88, 89, 89, 89, 90, 91, 92, 92, 93, 94, 94, - 93, 92, 93, 94, 96, 97, 97, 99, 100, 100, 98, 98, 99, 100, 101, 100, - 99, 99, 100, 103, 106, 108, 100, 102, 107, 107, 107, 107, 108, 109, 108, 109, - 112, 113, 113, 112, 111, 108, 108, 105, 111, 108, 99, 101, 109, 102, 106, 106, - 105, 105, 106, 106, 106, 106, 107, 110, 114, 117, 119, 116, 111, 108, 112, 109, - 110, 114, 115, 117, 119, 121, 119, 116, 119, 120, 120, 119, 120, 123, 125, 125, - 124, 124, 123, 120, 118, 118, 113, 103, 106, 111, 104, 103, 112, 116, 121, 124, - 119, 115, 121, 118, 115, 119, 123, 123, 124, 123, 122, 120, 118, 117, 111, 115, - 120, 120, 118, 119, 124, 126, 117, 114, 111, 108, 104, 102, 102, 101, 101, 98, - 96, 98, 100, 102, 101, 100, 104, 103, 101, 100, 102, 103, 107, 108, 110, 111, - 117, 118, 118, 118, 119, 121, 121, 126, 128, 123, 122, 123, 124, 120, 120, 116, - 113, 107, 102, 95, 87, 83, 89, 79, 76, 89, 78, 76, 81, 85, 81, 84, - 92, 97, 94, 91, 90, 90, 92, 97, 97, 91, 89, 87, 87, 86, 86, 85, - 85, 83, 85, 86, 86, 86, 83, 85, 85, 89, 89, 90, 90, 91, 92, 93, - 93, 92, 92, 93, 94, 94, 94, 94, 93, 93, 96, 99, 101, 100, 100, 101, - 102, 104, 103, 101, 99, 100, 102, 105, 107, 102, 103, 104, 103, 103, 103, 105, - 107, 104, 106, 111, 112, 111, 109, 108, 105, 106, 103, 108, 107, 102, 106, 107, - 95, 103, 103, 103, 104, 105, 106, 107, 106, 105, 105, 108, 110, 112, 110, 109, - 107, 111, 107, 110, 113, 115, 116, 119, 121, 115, 112, 112, 112, 115, 115, 115, - 114, 112, 116, 121, 120, 115, 105, 96, 91, 115, 111, 114, 115, 108, 110, 121, - 122, 110, 117, 113, 111, 118, 117, 115, 123, 121, 121, 121, 121, 121, 121, 121, - 121, 115, 117, 119, 118, 117, 117, 119, 118, 113, 109, 106, 102, 99, 96, 96, - 96, 97, 97, 96, 100, 103, 104, 103, 98, 100, 98, 100, 100, 101, 101, 105, - 106, 108, 107, 111, 112, 116, 118, 120, 120, 116, 121, 119, 114, 112, 114, 118, - 116, 122, 115, 108, 100, 97, 96, 96, 98, 97, 95, 86, 63, 59, 63, 76, - 77, 69, 64, 67, 81, 83, 86, 90, 93, 93, 93, 89, 91, 89, 86, 85, - 85, 84, 83, 83, 87, 84, 83, 85, 87, 88, 85, 82, 91, 91, 92, 93, - 93, 94, 95, 95, 91, 91, 96, 96, 97, 95, 92, 90, 89, 93, 98, 101, - 102, 104, 105, 106, 107, 105, 102, 100, 100, 99, 102, 103, 105, 105, 104, 101, - 101, 100, 102, 104, 101, 104, 107, 108, 109, 105, 106, 103, 105, 100, 106, 108, - 106, 110, 105, 87, 99, 99, 100, 102, 105, 106, 108, 107, 102, 101, 102, 103, - 105, 104, 105, 105, 111, 107, 109, 112, 115, 114, 119, 119, 116, 111, 108, 110, - 113, 115, 114, 112, 116, 116, 114, 111, 108, 109, 110, 115, 111, 111, 121, 119, - 109, 111, 116, 110, 116, 124, 122, 119, 122, 118, 115, 123, 116, 115, 115, 114, - 114, 114, 114, 115, 118, 114, 115, 116, 119, 122, 121, 119, 111, 109, 106, 103, - 102, 99, 98, 97, 95, 96, 100, 105, 110, 111, 108, 102, 103, 103, 104, 104, - 105, 105, 107, 108, 111, 111, 114, 120, 126, 125, 121, 116, 112, 118, 119, 115, - 113, 112, 114, 113, 110, 111, 109, 107, 102, 95, 86, 83, 82, 99, 103, 67, - 62, 67, 70, 70, 72, 60, 33, 77, 85, 89, 85, 83, 83, 85, 80, 74, - 82, 82, 81, 86, 83, 82, 91, 83, 90, 97, 97, 93, 89, 89, 92, 96, - 92, 92, 97, 95, 91, 92, 96, 96, 98, 102, 102, 101, 100, 99, 97, 96, - 95, 95, 96, 99, 100, 98, 97, 104, 105, 104, 106, 107, 108, 109, 107, 101, - 100, 98, 97, 97, 98, 99, 100, 100, 102, 101, 97, 99, 102, 106, 104, 103, - 108, 114, 111, 105, 104, 109, 115, 107, 108, 107, 105, 104, 104, 106, 108, 103, - 105, 106, 104, 106, 107, 105, 100, 105, 108, 113, 113, 111, 112, 118, 121, 119, - 116, 115, 118, 120, 119, 115, 112, 108, 111, 115, 117, 119, 119, 117, 116, 117, - 118, 120, 118, 118, 119, 119, 121, 121, 121, 119, 118, 116, 115, 115, 114, 118, - 120, 120, 119, 117, 115, 111, 110, 112, 109, 109, 110, 113, 116, 117, 117, 113, - 111, 107, 104, 103, 103, 104, 105, 105, 104, 102, 102, 101, 101, 103, 103, 108, - 111, 107, 100, 97, 103, 105, 102, 107, 106, 105, 107, 113, 117, 117, 112, 111, - 110, 110, 107, 104, 102, 105, 108, 100, 101, 102, 101, 97, 90, 82, 75, 77, - 80, 88, 56, 53, 61, 64, 63, 59, 49, 28, 77, 86, 92, 88, 81, 81, - 84, 81, 83, 85, 82, 82, 93, 92, 88, 92, 97, 97, 97, 95, 93, 91, - 90, 90, 99, 96, 96, 100, 98, 94, 94, 98, 92, 95, 98, 98, 96, 95, - 95, 94, 92, 91, 92, 96, 99, 100, 101, 100, 102, 103, 102, 103, 102, 103, - 103, 103, 106, 103, 101, 100, 99, 100, 100, 101, 98, 101, 102, 99, 100, 103, - 103, 102, 105, 108, 110, 108, 104, 104, 107, 111, 105, 106, 106, 104, 103, 103, - 106, 106, 102, 107, 109, 105, 104, 106, 110, 110, 113, 112, 113, 113, 114, 116, - 118, 116, 116, 113, 113, 114, 117, 117, 115, 112, 112, 113, 116, 117, 118, 118, - 117, 118, 121, 124, 125, 123, 122, 118, 117, 115, 117, 117, 117, 117, 117, 116, - 113, 115, 115, 117, 117, 116, 116, 114, 114, 113, 122, 119, 116, 113, 114, 114, - 113, 112, 114, 114, 114, 113, 111, 109, 106, 105, 105, 104, 103, 102, 101, 102, - 103, 104, 104, 107, 107, 102, 102, 106, 104, 100, 101, 102, 103, 105, 107, 111, - 113, 112, 112, 112, 113, 111, 108, 106, 108, 110, 114, 109, 106, 106, 107, 104, - 96, 89, 85, 83, 81, 59, 55, 68, 77, 72, 65, 61, 56, 72, 83, 92, - 92, 88, 91, 97, 96, 92, 91, 87, 89, 102, 103, 98, 100, 93, 90, 87, - 89, 95, 101, 104, 104, 104, 102, 102, 104, 102, 99, 99, 101, 92, 94, 95, - 95, 93, 93, 94, 94, 89, 88, 90, 94, 98, 100, 102, 103, 105, 105, 103, - 104, 102, 103, 102, 102, 102, 101, 100, 99, 99, 99, 99, 99, 98, 103, 105, - 104, 104, 106, 104, 100, 108, 108, 107, 107, 106, 107, 107, 108, 105, 106, 106, - 105, 104, 105, 108, 109, 103, 108, 112, 106, 104, 106, 114, 118, 120, 115, 113, - 114, 117, 118, 118, 112, 118, 115, 115, 117, 120, 120, 119, 118, 117, 117, 117, - 117, 117, 117, 116, 118, 120, 122, 124, 125, 124, 120, 116, 112, 115, 115, 117, - 118, 117, 116, 115, 116, 115, 114, 114, 114, 115, 117, 119, 120, 126, 121, 118, - 116, 115, 112, 110, 110, 112, 114, 116, 117, 115, 111, 106, 103, 103, 102, 102, - 102, 102, 103, 104, 105, 98, 103, 107, 105, 106, 105, 103, 99, 103, 104, 108, - 109, 111, 114, 118, 120, 110, 111, 112, 111, 109, 107, 107, 107, 117, 109, 102, - 102, 107, 107, 100, 90, 89, 84, 80, 72, 66, 79, 87, 78, 67, 73, 76, - 85, 89, 89, 82, 73, 69, 65, 60, 55, 58, 56, 57, 69, 71, 67, 71, - 65, 65, 66, 71, 78, 84, 91, 95, 102, 103, 102, 103, 101, 99, 99, 100, - 96, 97, 98, 97, 95, 95, 97, 99, 93, 92, 93, 96, 99, 103, 104, 103, - 108, 108, 108, 106, 104, 104, 102, 102, 101, 99, 101, 99, 101, 100, 102, 101, - 103, 105, 109, 105, 107, 108, 109, 105, 113, 110, 108, 108, 110, 111, 110, 108, - 106, 107, 107, 106, 106, 107, 110, 113, 105, 108, 110, 107, 106, 109, 115, 115, - 119, 116, 115, 115, 116, 117, 118, 114, 118, 118, 118, 119, 120, 120, 120, 120, - 120, 119, 118, 117, 117, 118, 119, 120, 117, 118, 121, 121, 123, 120, 118, 115, - 116, 117, 119, 118, 118, 117, 115, 114, 116, 116, 115, 115, 116, 118, 121, 121, - 117, 115, 113, 111, 112, 112, 111, 109, 107, 110, 113, 114, 113, 110, 107, 105, - 104, 104, 103, 103, 103, 103, 103, 103, 99, 99, 102, 104, 102, 102, 101, 101, - 101, 106, 111, 112, 113, 115, 121, 125, 122, 123, 124, 124, 122, 120, 118, 117, - 122, 117, 112, 112, 113, 112, 107, 100, 98, 95, 94, 81, 71, 79, 81, 68, - 57, 66, 72, 65, 70, 73, 79, 86, 96, 98, 92, 77, 85, 86, 84, 90, - 89, 86, 94, 87, 91, 93, 94, 92, 92, 97, 103, 96, 98, 98, 97, 95, - 96, 96, 95, 98, 99, 99, 99, 96, 97, 99, 101, 99, 98, 97, 99, 103, - 106, 105, 106, 109, 107, 106, 104, 102, 102, 100, 100, 102, 103, 105, 106, 109, - 109, 111, 110, 109, 110, 111, 106, 108, 111, 113, 111, 116, 112, 109, 109, 112, - 113, 111, 108, 105, 106, 107, 106, 106, 107, 110, 112, 107, 109, 109, 108, 111, - 114, 112, 105, 112, 114, 115, 114, 114, 114, 116, 119, 116, 116, 116, 115, 114, - 114, 114, 115, 120, 119, 118, 118, 118, 120, 123, 124, 120, 118, 118, 116, 119, - 120, 119, 117, 116, 114, 115, 115, 114, 110, 108, 109, 116, 115, 113, 113, 113, - 113, 116, 118, 112, 109, 109, 110, 111, 110, 109, 109, 107, 107, 107, 108, 108, - 109, 109, 109, 106, 105, 105, 104, 102, 101, 99, 99, 101, 98, 97, 98, 98, - 97, 100, 101, 100, 105, 112, 117, 116, 118, 124, 127, 128, 128, 128, 128, 127, - 125, 122, 120, 120, 121, 123, 121, 117, 113, 109, 107, 101, 99, 102, 75, 66, - 73, 76, 67, 67, 78, 80, 104, 106, 103, 101, 102, 102, 99, 89, 90, 99, - 100, 96, 98, 92, 90, 97, 85, 89, 95, 92, 86, 82, 84, 90, 96, 101, - 101, 99, 100, 101, 101, 98, 98, 98, 99, 99, 98, 96, 98, 99, 102, 102, - 101, 104, 107, 108, 109, 108, 111, 111, 109, 107, 107, 105, 104, 103, 102, 103, - 107, 107, 111, 110, 113, 111, 113, 113, 113, 107, 109, 112, 116, 113, 114, 111, - 108, 108, 110, 111, 109, 106, 103, 104, 104, 103, 103, 104, 106, 109, 110, 107, - 106, 107, 112, 116, 111, 101, 109, 113, 116, 115, 114, 113, 118, 122, 117, 118, - 118, 116, 113, 113, 114, 115, 118, 118, 117, 117, 118, 120, 122, 123, 126, 122, - 117, 116, 118, 117, 116, 113, 111, 111, 110, 108, 105, 104, 103, 105, 113, 112, - 111, 110, 108, 109, 110, 111, 112, 111, 111, 111, 110, 110, 107, 105, 109, 109, - 108, 107, 107, 109, 112, 114, 108, 108, 108, 106, 104, 102, 100, 98, 103, 98, - 95, 96, 95, 95, 100, 106, 106, 113, 121, 127, 129, 130, 133, 135, 132, 133, - 131, 130, 130, 129, 126, 124, 123, 128, 133, 131, 125, 120, 119, 120, 116, 114, - 115, 67, 63, 70, 72, 72, 82, 91, 87, 78, 87, 94, 92, 93, 95, 99, - 99, 95, 100, 99, 95, 101, 97, 93, 97, 95, 96, 99, 97, 95, 94, 94, - 97, 99, 105, 106, 103, 104, 107, 108, 102, 97, 99, 102, 101, 99, 98, 98, - 99, 102, 103, 102, 106, 109, 112, 114, 113, 115, 113, 111, 110, 110, 108, 107, - 108, 103, 104, 107, 107, 110, 108, 109, 107, 111, 112, 114, 109, 112, 113, 116, - 112, 114, 112, 110, 109, 109, 109, 108, 108, 106, 106, 106, 105, 103, 104, 106, - 109, 108, 109, 108, 108, 112, 116, 113, 107, 113, 113, 115, 115, 115, 116, 118, - 119, 117, 118, 118, 117, 114, 114, 117, 119, 117, 116, 116, 116, 116, 116, 117, - 117, 125, 121, 117, 117, 119, 117, 113, 108, 110, 109, 107, 105, 104, 105, 106, - 107, 110, 110, 109, 109, 109, 110, 108, 109, 112, 111, 109, 109, 110, 109, 106, - 104, 110, 111, 108, 106, 106, 107, 109, 110, 109, 109, 109, 108, 107, 105, 102, - 101, 103, 95, 93, 96, 98, 97, 102, 111, 110, 117, 124, 133, 139, 140, 140, - 139, 146, 145, 142, 141, 141, 141, 139, 136, 137, 138, 140, 140, 138, 137, 138, - 139, 139, 140, 140, 64, 61, 67, 67, 67, 79, 82, 66, 68, 82, 93, 91, - 84, 86, 92, 97, 94, 96, 91, 93, 105, 103, 98, 99, 100, 96, 93, 90, - 91, 91, 87, 87, 94, 101, 103, 98, 101, 105, 106, 100, 100, 103, 106, 105, - 104, 103, 102, 102, 101, 102, 103, 107, 111, 116, 116, 115, 111, 111, 109, 108, - 106, 105, 104, 105, 108, 110, 111, 112, 112, 110, 109, 108, 107, 112, 114, 112, - 113, 115, 113, 109, 117, 115, 114, 112, 111, 110, 110, 111, 110, 111, 110, 108, - 107, 107, 109, 111, 107, 109, 110, 108, 109, 114, 117, 116, 119, 115, 113, 114, - 118, 120, 119, 116, 110, 112, 113, 112, 110, 111, 114, 118, 116, 116, 115, 114, - 113, 112, 112, 111, 119, 117, 116, 119, 121, 121, 115, 109, 111, 110, 107, 105, - 106, 108, 111, 113, 110, 111, 111, 112, 113, 114, 112, 112, 108, 107, 106, 107, - 109, 109, 106, 105, 111, 110, 108, 105, 104, 103, 103, 103, 107, 108, 109, 109, - 109, 107, 105, 104, 101, 94, 94, 99, 102, 103, 107, 115, 108, 112, 121, 131, - 140, 141, 137, 134, 135, 135, 130, 128, 129, 130, 128, 126, 124, 121, 119, 120, - 124, 128, 129, 129, 123, 128, 132, 62, 62, 69, 79, 86, 90, 89, 86, 65, - 93, 104, 90, 79, 88, 90, 84, 95, 94, 96, 97, 98, 96, 96, 94, 97, - 100, 99, 92, 90, 92, 91, 88, 94, 98, 100, 98, 97, 95, 99, 100, 98, - 101, 104, 103, 103, 103, 104, 105, 104, 106, 105, 108, 109, 113, 115, 117, 114, - 117, 114, 105, 101, 105, 107, 107, 108, 108, 107, 111, 117, 119, 118, 115, 121, - 115, 114, 119, 121, 117, 116, 118, 114, 113, 111, 110, 109, 107, 105, 103, 112, - 112, 112, 109, 107, 108, 113, 116, 113, 113, 114, 114, 114, 112, 109, 108, 111, - 112, 113, 114, 114, 113, 111, 110, 111, 115, 118, 117, 112, 110, 113, 117, 114, - 115, 116, 117, 117, 116, 114, 113, 118, 116, 117, 118, 117, 116, 117, 115, 114, - 113, 112, 112, 113, 116, 119, 120, 115, 114, 113, 116, 117, 118, 115, 112, 114, - 109, 104, 105, 106, 108, 106, 102, 108, 109, 108, 108, 110, 111, 111, 111, 111, - 112, 114, 114, 112, 107, 102, 96, 100, 93, 97, 100, 95, 96, 108, 113, 120, - 120, 117, 107, 106, 118, 129, 137, 139, 140, 138, 136, 132, 129, 132, 137, 129, - 129, 129, 129, 128, 128, 128, 128, 128, 126, 125, 67, 67, 70, 72, 76, 73, - 69, 63, 72, 89, 97, 89, 87, 93, 95, 87, 90, 91, 91, 93, 94, 95, - 95, 96, 84, 89, 89, 87, 89, 94, 96, 92, 90, 93, 93, 93, 94, 95, - 96, 98, 97, 98, 99, 100, 100, 102, 106, 108, 108, 107, 107, 107, 108, 111, - 113, 114, 116, 118, 117, 107, 105, 103, 103, 100, 107, 111, 113, 114, 115, 116, - 117, 118, 120, 115, 114, 118, 120, 117, 116, 116, 113, 112, 110, 109, 108, 108, - 107, 107, 108, 110, 111, 110, 109, 110, 113, 117, 110, 110, 111, 111, 110, 108, - 105, 104, 112, 112, 113, 113, 113, 112, 110, 109, 108, 113, 118, 118, 114, 111, - 111, 113, 108, 109, 110, 112, 112, 113, 113, 113, 115, 113, 115, 116, 116, 118, - 117, 116, 113, 112, 112, 111, 112, 114, 116, 118, 118, 116, 115, 115, 117, 116, - 115, 111, 109, 105, 103, 106, 111, 110, 109, 105, 109, 111, 113, 109, 106, 104, - 107, 109, 109, 110, 113, 114, 115, 112, 111, 108, 113, 105, 107, 108, 101, 100, - 110, 113, 103, 112, 125, 131, 124, 115, 120, 134, 139, 136, 135, 139, 144, 142, - 135, 128, 130, 130, 129, 128, 127, 126, 125, 125, 129, 129, 132, 80, 81, 84, - 86, 89, 87, 85, 83, 88, 89, 90, 89, 93, 96, 94, 87, 93, 93, 94, - 96, 96, 96, 96, 96, 89, 92, 94, 93, 93, 93, 94, 90, 94, 93, 92, - 93, 94, 96, 97, 97, 101, 102, 103, 103, 102, 105, 110, 114, 113, 113, 112, - 113, 113, 116, 117, 115, 115, 117, 118, 111, 109, 105, 104, 101, 105, 112, 115, - 114, 111, 111, 114, 118, 114, 110, 108, 112, 113, 111, 110, 111, 113, 112, 109, - 107, 105, 104, 105, 105, 105, 107, 110, 110, 109, 108, 108, 109, 107, 107, 108, - 109, 108, 108, 107, 107, 112, 112, 111, 111, 110, 109, 108, 109, 109, 114, 120, - 121, 118, 115, 113, 114, 113, 113, 113, 113, 113, 114, 115, 116, 113, 113, 115, - 116, 116, 118, 117, 117, 119, 118, 118, 117, 117, 118, 120, 121, 125, 121, 121, - 119, 119, 119, 119, 116, 117, 114, 113, 115, 117, 114, 111, 106, 112, 116, 120, - 113, 108, 103, 108, 111, 107, 106, 110, 109, 112, 110, 112, 110, 112, 103, 105, - 106, 98, 98, 106, 107, 115, 111, 117, 133, 131, 119, 124, 144, 153, 151, 145, - 142, 144, 144, 141, 137, 141, 140, 139, 138, 136, 135, 133, 133, 125, 127, 131, - 79, 79, 83, 87, 92, 94, 95, 94, 100, 95, 90, 94, 96, 94, 90, 89, - 95, 94, 94, 94, 94, 93, 92, 93, 95, 96, 97, 96, 95, 95, 93, 90, - 99, 96, 93, 94, 95, 97, 96, 94, 108, 110, 112, 112, 111, 112, 115, 118, - 115, 115, 115, 117, 118, 118, 119, 119, 115, 116, 117, 114, 111, 110, 109, 109, - 108, 112, 113, 112, 110, 110, 112, 115, 114, 111, 110, 111, 112, 112, 110, 110, - 113, 112, 109, 105, 101, 100, 100, 101, 103, 105, 108, 109, 107, 104, 101, 100, - 103, 104, 106, 108, 108, 110, 112, 112, 110, 110, 109, 109, 110, 110, 110, 110, - 109, 113, 117, 118, 116, 114, 114, 114, 119, 118, 116, 115, 114, 115, 116, 117, - 114, 115, 115, 116, 116, 115, 115, 117, 122, 123, 122, 121, 120, 122, 123, 121, - 124, 121, 121, 118, 118, 117, 120, 119, 118, 116, 115, 114, 117, 115, 115, 112, - 119, 122, 123, 119, 115, 113, 114, 117, 113, 112, 111, 110, 109, 109, 109, 107, - 114, 105, 108, 113, 107, 109, 117, 118, 126, 107, 101, 114, 128, 132, 136, 142, - 143, 150, 154, 146, 143, 141, 146, 145, 149, 146, 148, 145, 146, 143, 144, 144, - 144, 148, 148, 85, 84, 86, 87, 88, 89, 90, 90, 101, 96, 94, 98, 95, - 91, 89, 94, 87, 87, 88, 88, 90, 90, 89, 91, 93, 93, 97, 100, 100, - 101, 100, 100, 101, 97, 92, 94, 98, 101, 98, 96, 110, 113, 115, 117, 116, - 115, 114, 114, 110, 111, 112, 116, 117, 118, 119, 117, 118, 115, 114, 111, 108, - 107, 108, 112, 111, 108, 105, 106, 108, 110, 109, 108, 115, 114, 113, 112, 113, - 114, 113, 110, 112, 112, 112, 109, 105, 104, 106, 108, 103, 105, 108, 110, 111, - 109, 106, 103, 107, 108, 106, 108, 109, 111, 110, 111, 107, 107, 106, 108, 107, - 109, 110, 113, 109, 111, 111, 110, 110, 111, 112, 114, 115, 114, 113, 112, 112, - 114, 115, 116, 119, 118, 117, 117, 116, 114, 114, 115, 118, 119, 118, 117, 116, - 118, 118, 118, 116, 114, 115, 113, 113, 113, 118, 118, 112, 108, 107, 107, 111, - 115, 119, 120, 121, 120, 117, 117, 120, 121, 119, 117, 119, 118, 116, 114, 112, - 112, 111, 112, 111, 99, 103, 110, 106, 109, 114, 114, 106, 103, 99, 106, 122, - 134, 135, 128, 121, 131, 142, 143, 147, 148, 147, 138, 145, 143, 145, 143, 145, - 143, 145, 146, 151, 153, 152, 89, 88, 92, 91, 93, 92, 95, 96, 94, 95, - 96, 98, 95, 93, 94, 99, 83, 84, 86, 88, 92, 95, 95, 98, 101, 100, - 99, 104, 106, 103, 105, 106, 102, 100, 100, 100, 106, 107, 109, 107, 113, 116, - 121, 122, 124, 120, 119, 116, 114, 113, 117, 119, 120, 121, 122, 122, 125, 119, - 114, 110, 105, 100, 101, 106, 111, 107, 103, 103, 108, 110, 109, 106, 111, 111, - 110, 107, 108, 110, 109, 104, 108, 111, 114, 113, 111, 110, 113, 116, 104, 104, - 105, 109, 112, 114, 113, 112, 112, 111, 108, 107, 106, 106, 104, 105, 107, 107, - 105, 107, 106, 109, 111, 114, 114, 114, 113, 112, 112, 115, 117, 119, 112, 112, - 113, 114, 115, 117, 119, 120, 120, 118, 118, 115, 113, 111, 112, 112, 115, 115, - 117, 116, 116, 116, 116, 115, 113, 113, 114, 115, 115, 114, 117, 119, 122, 118, - 113, 108, 107, 109, 112, 116, 117, 113, 109, 111, 117, 120, 117, 113, 113, 112, - 111, 111, 111, 111, 111, 112, 109, 96, 101, 106, 101, 101, 107, 104, 102, 109, - 110, 103, 104, 118, 133, 141, 142, 139, 130, 126, 137, 148, 147, 135, 141, 140, - 142, 141, 143, 143, 144, 145, 141, 141, 143, 76, 76, 80, 80, 83, 84, 90, - 95, 91, 95, 98, 96, 94, 97, 98, 96, 89, 90, 91, 93, 95, 98, 100, - 102, 102, 98, 98, 102, 102, 99, 102, 105, 106, 103, 104, 103, 104, 104, 106, - 106, 114, 116, 121, 122, 125, 123, 124, 123, 121, 121, 124, 126, 127, 127, 127, - 125, 126, 120, 117, 114, 108, 100, 99, 104, 107, 105, 103, 103, 104, 107, 108, - 109, 104, 106, 104, 100, 101, 104, 103, 99, 106, 111, 116, 116, 112, 110, 111, - 113, 108, 106, 104, 105, 109, 112, 112, 111, 113, 112, 109, 108, 107, 108, 107, - 108, 109, 109, 106, 106, 105, 107, 108, 112, 116, 116, 115, 115, 117, 119, 120, - 120, 115, 115, 116, 116, 117, 116, 116, 116, 118, 116, 116, 113, 111, 110, 112, - 112, 114, 114, 115, 115, 115, 116, 116, 115, 110, 113, 116, 116, 115, 112, 114, - 114, 123, 121, 117, 110, 105, 103, 103, 106, 111, 109, 106, 107, 111, 113, 112, - 110, 103, 104, 104, 105, 106, 106, 106, 106, 116, 103, 107, 112, 107, 107, 110, - 105, 108, 111, 109, 103, 96, 103, 124, 144, 149, 149, 140, 124, 127, 137, 143, - 137, 141, 139, 141, 139, 142, 140, 142, 142, 145, 143, 145, 83, 84, 85, 84, - 83, 82, 87, 91, 92, 96, 97, 94, 94, 97, 97, 90, 98, 100, 100, 101, - 102, 104, 105, 106, 93, 89, 91, 98, 102, 102, 107, 113, 112, 111, 112, 108, - 103, 101, 102, 103, 116, 117, 118, 120, 120, 122, 124, 125, 122, 122, 124, 125, - 125, 124, 124, 122, 127, 122, 122, 122, 119, 110, 107, 112, 107, 107, 108, 106, - 103, 104, 109, 114, 108, 110, 108, 104, 104, 108, 107, 102, 108, 113, 117, 116, - 109, 104, 102, 103, 113, 108, 103, 101, 102, 104, 104, 104, 111, 109, 109, 110, - 112, 114, 117, 117, 114, 112, 111, 109, 108, 109, 110, 112, 111, 113, 114, 116, - 118, 119, 117, 116, 120, 120, 119, 118, 115, 112, 108, 106, 117, 116, 114, 112, - 112, 112, 113, 113, 107, 108, 110, 111, 111, 113, 112, 111, 105, 106, 110, 110, - 107, 106, 106, 107, 105, 106, 107, 106, 103, 103, 104, 107, 109, 112, 112, 111, - 110, 110, 112, 113, 107, 108, 109, 109, 110, 109, 108, 106, 102, 91, 92, 98, - 95, 95, 99, 96, 102, 96, 100, 113, 111, 100, 99, 115, 106, 135, 153, 147, - 133, 131, 134, 136, 137, 137, 136, 136, 135, 135, 134, 136, 141, 139, 137, 95, - 89, 87, 90, 90, 85, 82, 85, 95, 89, 90, 96, 100, 93, 91, 94, 97, - 97, 112, 106, 111, 110, 95, 120, 115, 117, 117, 116, 113, 111, 112, 110, 122, - 116, 117, 124, 126, 122, 124, 129, 128, 116, 113, 121, 125, 124, 120, 119, 116, - 118, 121, 121, 119, 119, 125, 128, 132, 131, 127, 124, 123, 123, 123, 119, 111, - 109, 110, 110, 110, 110, 111, 111, 104, 103, 103, 107, 111, 112, 109, 105, 115, - 117, 116, 115, 115, 116, 116, 117, 109, 112, 114, 112, 108, 107, 112, 116, 119, - 114, 111, 108, 109, 110, 113, 117, 111, 112, 115, 119, 119, 119, 119, 118, 112, - 115, 117, 117, 117, 118, 121, 124, 121, 117, 114, 114, 116, 117, 114, 111, 114, - 111, 112, 115, 116, 112, 111, 114, 110, 109, 109, 110, 112, 114, 112, 110, 114, - 118, 118, 114, 115, 120, 121, 116, 120, 114, 111, 112, 111, 106, 106, 114, 112, - 115, 115, 115, 113, 111, 108, 107, 108, 106, 104, 103, 103, 104, 106, 107, 104, - 112, 96, 87, 101, 72, 99, 115, 112, 120, 122, 113, 110, 106, 92, 79, 86, - 104, 134, 165, 146, 141, 117, 138, 134, 131, 136, 145, 146, 138, 136, 140, 143, - 143, 143 }; - -/* Define image 'logo' of size 555x103x1x3 and type 'unsigned char' */ -const unsigned char data_logo[] = { - 76, 77, 75, 75, 75, 99, 102, 72, 63, 0, 84, 115, 114, 110, 115, 80, - 81, 108, 112, 69, 38, 87, 115, 118, 96, 116, 84, 88, 85, 107, 83, 72, - 65, 0, 111, 131, 127, 72, 131, 75, 73, 77, 104, 102, 33, 56, 111, 110, - 111, 114, 116, 112, 87, 80, 104, 100, 106, 24, 96, 79, 71, 71, 104, 108, - 83, 69, 65, 57, 63, 32, 100, 120, 76, 79, 79, 65, 107, 67, 84, 69, - 59, 32, 65, 112, 67, 68, 69, 111, 103, 71, 103, 59, 61, 4, 107, 111, - 80, 118, 136, 80, 65, 106, 71, 96, 37, 38, 115, 123, 118, 57, 48, 57, - 83, 57, 87, 51, 49, 12, 100, 106, 118, 111, 96, 100, 96, 68, 65, 55, - 46, 0, 103, 106, 97, 103, 72, 65, 63, 93, 127, 68, 65, 17, 92, 126, - 106, 65, 64, 96, 68, 61, 57, 55, 36, 67, 131, 110, 67, 106, 93, 63, - 65, 63, 95, 130, 53, 0, 100, 79, 103, 99, 75, 59, 64, 93, 97, 89, - 14, 104, 106, 65, 71, 67, 68, 103, 69, 55, 63, 99, 16, 97, 96, 72, - 100, 99, 88, 75, 67, 69, 55, 52, 46, 1, 52, 123, 84, 87, 57, 85, - 48, 93, 52, 49, 45, 17, 95, 100, 64, 103, 77, 57, 53, 49, 48, 48, - 38, 5, 89, 93, 102, 99, 55, 59, 68, 52, 89, 36, 8, 136, 111, 112, - 80, 136, 111, 106, 76, 85, 76, 79, 69, 38, 61, 108, 93, 68, 59, 65, - 92, 59, 89, 52, 28, 52, 128, 147, 127, 154, 100, 93, 96, 128, 85, 88, - 26, 53, 93, 99, 89, 52, 56, 52, 103, 49, 49, 76, 22, 73, 103, 124, - 89, 132, 56, 51, 45, 52, 42, 53, 46, 12, 88, 55, 59, 59, 87, 57, - 48, 51, 84, 40, 49, 12, 123, 96, 87, 91, 92, 63, 65, 99, 49, 44, - 40, 4, 53, 118, 89, 111, 44, 46, 42, 73, 40, 41, 18, 81, 91, 88, - 87, 83, 49, 56, 93, 93, 46, 41, 33, 1, 93, 63, 93, 92, 46, 57, - 40, 44, 41, 80, 42, 1, 123, 95, 134, 69, 53, 84, 45, 41, 37, 36, - 17, 61, 91, 49, 102, 85, 38, 85, 87, 32, 36, 36, 5, 97, 142, 114, - 83, 72, 76, 143, 108, 69, 71, 64, 57, 1, 73, 79, 79, 48, 41, 42, - 48, 45, 44, 45, 44, 8, 79, 83, 38, 102, 68, 77, 30, 33, 30, 28, - 26, 2, 87, 107, 88, 93, 111, 34, 83, 88, 41, 36, 30, 20, 0, 108, - 115, 99, 91, 88, 69, 64, 60, 56, 61, 1, 115, 89, 116, 71, 26, 76, - 33, 84, 30, 26, 5, 75, 106, 53, 73, 32, 71, 24, 65, 97, 55, 26, - 20, 10, 48, 89, 80, 89, 85, 46, 21, 22, 30, 32, 22, 5, 77, 75, - 28, 71, 38, 79, 25, 20, 18, 16, 0, 114, 107, 95, 21, 24, 83, 69, - 73, 102, 30, 20, 16, 1, 85, 21, 21, 14, 16, 95, 75, 40, 17, 16, - 10, 1, 38, 80, 48, 77, 93, 10, 17, 21, 9, 14, 6, 0, 71, 76, - 21, 16, 9, 10, 22, 71, 16, 13, 6, 0, 38, 96, 67, 42, 29, 96, - 30, 30, 33, 24, 57, 18, 12, 97, 38, 114, 30, 110, 104, 110, 75, 75, - 93, 99, 77, 60, 0, 88, 120, 108, 103, 119, 87, 80, 106, 112, 63, 34, - 88, 106, 115, 108, 92, 84, 85, 84, 104, 89, 75, 65, 0, 107, 122, 118, - 76, 118, 76, 72, 88, 96, 91, 45, 61, 106, 107, 108, 93, 92, 76, 79, - 95, 81, 89, 97, 37, 92, 85, 71, 72, 77, 108, 99, 83, 67, 57, 60, - 42, 100, 124, 80, 77, 89, 75, 107, 77, 89, 67, 52, 29, 67, 112, 69, - 68, 69, 106, 99, 75, 99, 57, 59, 1, 106, 107, 96, 112, 130, 87, 65, - 102, 75, 87, 30, 42, 97, 114, 68, 49, 55, 63, 69, 72, 59, 46, 44, - 17, 96, 102, 97, 131, 106, 92, 95, 95, 64, 57, 48, 0, 99, 102, 110, - 96, 72, 67, 71, 87, 107, 84, 65, 18, 87, 120, 103, 71, 68, 91, 95, - 64, 53, 57, 34, 67, 119, 92, 67, 79, 80, 84, 63, 64, 87, 115, 48, - 0, 99, 87, 88, 97, 76, 63, 69, 85, 95, 85, 20, 111, 102, 72, 76, - 60, 95, 93, 64, 64, 55, 84, 25, 91, 96, 88, 93, 72, 73, 73, 65, - 80, 53, 53, 41, 0, 65, 107, 73, 57, 72, 75, 52, 77, 51, 51, 46, - 24, 89, 103, 68, 92, 88, 65, 73, 71, 57, 46, 44, 5, 84, 89, 87, - 64, 57, 80, 59, 61, 79, 41, 12, 126, 110, 111, 91, 107, 110, 99, 83, - 95, 77, 87, 69, 36, 63, 110, 95, 59, 69, 87, 81, 56, 85, 61, 26, - 56, 123, 136, 120, 135, 99, 88, 97, 122, 85, 85, 32, 61, 93, 97, 77, - 49, 63, 55, 92, 51, 49, 65, 21, 69, 106, 115, 91, 112, 67, 56, 49, - 48, 44, 52, 48, 18, 68, 63, 65, 89, 85, 67, 48, 48, 69, 45, 48, - 12, 118, 102, 73, 83, 53, 53, 71, 92, 42, 45, 41, 5, 64, 103, 84, - 110, 41, 46, 48, 65, 40, 40, 17, 77, 87, 88, 83, 57, 84, 84, 87, - 65, 46, 49, 33, 1, 93, 67, 89, 81, 48, 52, 51, 36, 51, 67, 40, - 2, 114, 112, 100, 65, 38, 81, 45, 44, 36, 34, 17, 64, 83, 87, 95, - 57, 36, 83, 84, 32, 36, 34, 8, 91, 128, 108, 103, 68, 68, 110, 103, - 67, 81, 67, 61, 8, 69, 73, 68, 44, 40, 41, 37, 42, 40, 41, 41, - 12, 77, 81, 52, 83, 59, 76, 30, 32, 37, 28, 22, 4, 83, 83, 83, - 93, 76, 38, 75, 81, 51, 36, 28, 20, 0, 115, 119, 89, 83, 67, 65, - 65, 57, 56, 55, 0, 102, 104, 115, 57, 28, 68, 37, 81, 36, 25, 6, - 72, 108, 63, 65, 33, 63, 24, 25, 22, 22, 28, 21, 10, 48, 97, 61, - 79, 81, 42, 24, 24, 59, 37, 28, 5, 75, 61, 36, 44, 49, 72, 28, - 20, 20, 13, 1, 102, 91, 76, 40, 24, 85, 75, 55, 49, 40, 21, 14, - 1, 83, 41, 28, 17, 13, 25, 84, 73, 17, 25, 10, 0, 51, 77, 60, - 88, 51, 26, 17, 24, 8, 8, 6, 0, 75, 72, 18, 18, 12, 10, 12, - 69, 21, 34, 6, 0, 34, 87, 61, 48, 28, 79, 34, 28, 29, 21, 51, - 16, 12, 104, 51, 104, 41, 84, 97, 85, 75, 75, 88, 100, 77, 69, 8, - 91, 115, 103, 110, 110, 89, 80, 93, 108, 67, 32, 88, 111, 108, 112, 88, - 87, 79, 85, 100, 87, 76, 64, 0, 106, 110, 81, 106, 92, 76, 73, 79, - 102, 91, 42, 64, 110, 96, 77, 79, 96, 96, 95, 88, 88, 85, 103, 36, - 85, 84, 73, 69, 71, 87, 100, 95, 76, 57, 57, 42, 102, 126, 79, 81, - 77, 77, 85, 91, 81, 69, 65, 28, 73, 97, 73, 69, 87, 104, 80, 91, - 92, 56, 59, 2, 92, 106, 83, 81, 79, 72, 67, 100, 77, 81, 28, 42, - 104, 108, 65, 41, 63, 42, 48, 46, 46, 51, 44, 17, 91, 100, 99, 100, - 116, 100, 80, 91, 67, 57, 48, 0, 97, 111, 104, 88, 79, 65, 67, 68, - 65, 76, 65, 24, 79, 118, 99, 69, 64, 76, 97, 60, 59, 59, 33, 68, - 115, 103, 100, 85, 81, 83, 81, 67, 81, 102, 60, 1, 88, 88, 96, 87, - 84, 68, 72, 80, 89, 79, 21, 104, 102, 69, 68, 93, 68, 59, 71, 65, - 51, 79, 28, 87, 96, 80, 75, 83, 77, 72, 72, 67, 52, 52, 53, 9, - 51, 103, 72, 63, 75, 71, 57, 69, 51, 49, 46, 26, 85, 102, 68, 91, - 76, 76, 63, 67, 59, 51, 42, 4, 80, 88, 76, 64, 77, 52, 59, 48, - 71, 32, 13, 118, 107, 108, 100, 88, 76, 80, 91, 77, 83, 83, 68, 33, - 64, 104, 91, 64, 68, 104, 84, 63, 73, 67, 28, 80, 122, 122, 119, 126, - 108, 96, 103, 119, 89, 87, 37, 59, 93, 95, 76, 55, 63, 56, 87, 49, - 46, 59, 20, 69, 100, 107, 92, 108, 80, 53, 51, 45, 44, 51, 48, 20, - 83, 68, 63, 100, 61, 59, 51, 48, 68, 45, 52, 20, 106, 96, 72, 80, - 104, 106, 104, 87, 45, 46, 34, 9, 65, 96, 83, 76, 41, 45, 56, 41, - 40, 41, 22, 68, 85, 87, 81, 63, 59, 48, 61, 49, 45, 45, 32, 9, - 100, 73, 103, 53, 37, 49, 51, 34, 44, 57, 40, 2, 107, 89, 112, 91, - 63, 89, 49, 45, 41, 30, 21, 75, 69, 96, 73, 37, 44, 80, 87, 33, - 34, 36, 8, 83, 128, 110, 95, 81, 72, 76, 69, 69, 76, 68, 60, 5, - 67, 79, 53, 37, 36, 34, 34, 37, 44, 37, 33, 10, 73, 84, 59, 71, - 52, 68, 32, 33, 34, 30, 26, 0, 80, 81, 87, 103, 49, 37, 63, 84, - 45, 37, 29, 20, 0, 95, 120, 89, 80, 65, 69, 65, 69, 53, 55, 0, - 96, 91, 60, 33, 59, 56, 60, 76, 30, 26, 8, 64, 99, 55, 85, 30, - 28, 22, 22, 22, 22, 28, 18, 9, 44, 87, 71, 76, 75, 44, 25, 26, - 30, 37, 25, 10, 67, 55, 57, 59, 51, 65, 26, 21, 20, 16, 1, 96, - 69, 61, 30, 22, 79, 75, 48, 42, 33, 34, 16, 0, 92, 22, 24, 25, - 16, 16, 14, 75, 49, 24, 10, 0, 51, 64, 72, 103, 24, 16, 37, 37, - 8, 8, 6, 0, 65, 72, 41, 30, 16, 9, 46, 32, 18, 18, 6, 0, - 33, 34, 63, 51, 24, 22, 25, 28, 25, 25, 42, 13, 16, 96, 63, 93, - 83, 80, 92, 85, 73, 75, 85, 93, 72, 68, 0, 92, 123, 100, 99, 110, - 106, 81, 91, 99, 65, 26, 87, 108, 100, 81, 81, 99, 89, 91, 93, 97, - 75, 63, 8, 104, 104, 77, 96, 80, 77, 73, 83, 88, 71, 42, 69, 106, - 92, 114, 88, 103, 95, 91, 87, 79, 88, 91, 40, 83, 96, 79, 69, 71, - 69, 75, 87, 64, 61, 53, 44, 106, 134, 67, 72, 75, 91, 80, 76, 67, - 65, 64, 24, 71, 103, 69, 72, 93, 84, 85, 85, 71, 59, 56, 2, 102, - 106, 100, 97, 93, 68, 84, 80, 89, 59, 25, 42, 92, 59, 42, 34, 36, - 29, 34, 34, 36, 45, 37, 17, 87, 100, 89, 93, 110, 112, 83, 72, 71, - 64, 41, 0, 95, 102, 102, 85, 83, 95, 79, 76, 71, 75, 67, 26, 76, - 97, 96, 72, 67, 71, 88, 71, 56, 44, 29, 65, 110, 97, 103, 111, 91, - 107, 95, 81, 75, 92, 57, 0, 84, 93, 79, 81, 83, 71, 65, 80, 75, - 73, 25, 99, 97, 73, 71, 69, 68, 57, 60, 67, 46, 71, 30, 83, 89, - 85, 87, 80, 76, 73, 75, 80, 52, 52, 52, 2, 63, 85, 63, 52, 72, - 63, 57, 67, 48, 51, 46, 30, 81, 100, 76, 89, 97, 59, 69, 65, 59, - 49, 38, 9, 65, 85, 93, 68, 42, 75, 60, 65, 67, 29, 12, 104, 111, - 107, 97, 79, 84, 85, 77, 75, 88, 87, 68, 28, 67, 103, 84, 60, 75, - 81, 69, 59, 69, 67, 28, 63, 120, 128, 112, 99, 95, 100, 115, 112, 89, - 87, 42, 59, 88, 103, 53, 65, 55, 52, 99, 49, 44, 51, 17, 69, 99, - 91, 84, 91, 96, 55, 61, 48, 44, 55, 48, 21, 73, 67, 71, 76, 65, - 67, 56, 49, 61, 45, 55, 21, 103, 96, 71, 83, 75, 79, 61, 60, 59, - 59, 32, 12, 67, 83, 84, 73, 41, 49, 55, 36, 38, 46, 24, 69, 83, - 84, 77, 88, 56, 55, 55, 64, 38, 44, 33, 2, 87, 61, 76, 79, 33, - 61, 64, 37, 41, 56, 41, 2, 92, 96, 110, 73, 60, 104, 56, 48, 38, - 34, 24, 73, 52, 88, 68, 36, 40, 73, 72, 32, 34, 36, 6, 88, 120, - 103, 69, 76, 72, 69, 65, 71, 83, 69, 57, 8, 52, 72, 40, 32, 30, - 25, 36, 34, 40, 29, 29, 10, 67, 67, 53, 57, 46, 61, 37, 45, 37, - 30, 28, 0, 77, 77, 77, 99, 37, 46, 57, 72, 57, 33, 30, 18, 0, - 103, 120, 80, 73, 65, 69, 65, 71, 52, 55, 0, 88, 95, 56, 26, 52, - 24, 44, 34, 52, 26, 9, 61, 75, 84, 61, 45, 22, 21, 22, 22, 22, - 33, 25, 8, 52, 81, 75, 65, 64, 56, 26, 26, 38, 38, 29, 9, 72, - 53, 53, 45, 52, 45, 25, 20, 18, 16, 1, 89, 60, 49, 34, 25, 76, - 83, 87, 57, 40, 24, 18, 0, 88, 41, 34, 33, 10, 14, 14, 16, 38, - 24, 10, 1, 57, 67, 57, 34, 10, 21, 21, 16, 8, 8, 6, 0, 60, - 71, 20, 30, 21, 9, 30, 25, 28, 20, 6, 0, 16, 56, 52, 51, 22, - 21, 21, 21, 14, 17, 26, 10, 18, 80, 63, 64, 92, 72, 75, 76, 75, - 75, 88, 89, 69, 60, 0, 89, 97, 99, 102, 104, 106, 85, 84, 84, 64, - 26, 84, 115, 110, 89, 96, 108, 96, 93, 95, 81, 71, 61, 0, 103, 106, - 75, 100, 79, 79, 73, 77, 91, 65, 44, 68, 102, 106, 91, 88, 99, 104, - 92, 92, 92, 85, 91, 41, 52, 88, 83, 69, 72, 69, 71, 69, 72, 57, - 56, 46, 102, 110, 76, 92, 81, 95, 88, 79, 71, 65, 53, 22, 72, 99, - 72, 89, 85, 79, 87, 89, 63, 57, 56, 12, 97, 92, 91, 80, 68, 83, - 71, 77, 92, 57, 22, 41, 93, 51, 28, 29, 34, 42, 25, 30, 37, 51, - 37, 21, 85, 99, 93, 89, 110, 88, 89, 73, 75, 53, 41, 0, 92, 89, - 108, 93, 68, 76, 81, 88, 84, 72, 69, 30, 44, 93, 103, 85, 64, 65, - 83, 75, 53, 42, 29, 64, 108, 100, 77, 88, 99, 89, 87, 89, 75, 93, - 48, 0, 91, 99, 97, 77, 83, 75, 73, 79, 77, 75, 28, 93, 96, 92, - 76, 77, 65, 55, 55, 68, 67, 72, 29, 81, 81, 77, 77, 83, 79, 85, - 83, 80, 53, 52, 42, 2, 48, 91, 60, 60, 67, 55, 64, 63, 52, 48, - 45, 30, 49, 91, 69, 96, 97, 63, 67, 56, 55, 41, 38, 9, 76, 80, - 72, 59, 75, 80, 80, 73, 71, 26, 10, 59, 114, 103, 89, 81, 85, 81, - 79, 79, 89, 67, 67, 26, 75, 100, 87, 68, 77, 65, 61, 64, 65, 56, - 28, 64, 120, 108, 122, 92, 118, 100, 111, 95, 88, 91, 46, 48, 84, 100, - 53, 64, 67, 72, 88, 51, 40, 48, 22, 69, 93, 75, 79, 68, 72, 64, - 56, 67, 42, 53, 48, 24, 75, 69, 69, 69, 60, 61, 65, 53, 48, 48, - 51, 24, 92, 92, 83, 79, 57, 75, 61, 67, 60, 46, 42, 12, 73, 93, - 75, 65, 38, 53, 49, 36, 37, 37, 24, 32, 77, 81, 79, 80, 53, 46, - 67, 52, 41, 41, 30, 4, 84, 84, 71, 75, 53, 68, 72, 34, 40, 53, - 40, 5, 89, 88, 104, 61, 88, 89, 71, 49, 34, 34, 25, 75, 69, 83, - 69, 65, 34, 67, 71, 32, 34, 37, 12, 75, 126, 97, 79, 72, 72, 79, - 76, 72, 77, 79, 53, 9, 38, 67, 33, 28, 37, 26, 32, 24, 32, 25, - 25, 10, 32, 68, 42, 73, 49, 51, 51, 51, 38, 42, 25, 0, 77, 80, - 81, 48, 67, 68, 52, 73, 67, 38, 44, 17, 0, 107, 115, 81, 73, 68, - 72, 67, 57, 52, 63, 4, 96, 83, 45, 36, 60, 56, 38, 46, 57, 26, - 14, 22, 64, 83, 85, 41, 32, 29, 24, 21, 21, 28, 21, 8, 46, 80, - 63, 63, 59, 51, 24, 22, 36, 42, 22, 10, 64, 57, 49, 44, 52, 67, - 26, 22, 18, 16, 1, 96, 73, 49, 20, 28, 20, 30, 32, 22, 38, 22, - 14, 2, 77, 33, 22, 14, 14, 10, 14, 14, 21, 14, 10, 0, 53, 61, - 57, 9, 28, 14, 59, 26, 21, 17, 5, 0, 48, 61, 28, 41, 36, 9, - 22, 33, 22, 16, 5, 0, 5, 12, 25, 36, 49, 37, 14, 12, 10, 36, - 17, 8, 26, 84, 68, 41, 32, 76, 79, 80, 75, 81, 81, 92, 77, 55, - 1, 84, 110, 92, 99, 107, 103, 85, 95, 95, 51, 24, 84, 110, 114, 93, - 93, 103, 103, 100, 95, 88, 84, 63, 0, 99, 110, 84, 100, 77, 73, 76, - 80, 88, 48, 41, 61, 84, 110, 95, 97, 83, 89, 88, 91, 79, 92, 69, - 44, 51, 79, 85, 79, 73, 72, 68, 77, 65, 56, 51, 49, 91, 128, 83, - 92, 83, 81, 93, 79, 67, 67, 46, 18, 76, 103, 68, 91, 76, 81, 95, - 87, 61, 52, 55, 5, 95, 96, 99, 89, 80, 87, 89, 77, 88, 56, 21, - 45, 91, 32, 49, 45, 51, 45, 22, 25, 34, 44, 33, 24, 51, 99, 93, - 84, 106, 102, 108, 96, 72, 51, 53, 0, 89, 96, 108, 91, 80, 76, 73, - 72, 75, 72, 68, 34, 38, 76, 83, 96, 63, 52, 73, 71, 49, 41, 25, - 56, 107, 95, 91, 88, 89, 83, 87, 72, 75, 92, 41, 0, 88, 88, 87, - 75, 84, 76, 67, 64, 84, 77, 34, 59, 81, 103, 87, 97, 75, 75, 79, - 83, 46, 69, 34, 55, 76, 79, 76, 75, 75, 71, 73, 57, 52, 55, 34, - 1, 48, 95, 65, 49, 49, 57, 45, 46, 46, 48, 45, 33, 38, 83, 91, - 92, 61, 67, 63, 53, 53, 44, 44, 8, 71, 76, 68, 48, 53, 40, 60, - 60, 81, 28, 12, 56, 112, 104, 89, 79, 80, 83, 93, 89, 89, 75, 56, - 21, 65, 95, 79, 68, 92, 65, 60, 63, 64, 52, 28, 57, 110, 108, 95, - 99, 91, 100, 107, 92, 87, 92, 49, 25, 72, 95, 49, 71, 67, 84, 73, - 44, 48, 45, 16, 68, 88, 81, 88, 67, 63, 68, 45, 48, 42, 52, 49, - 25, 65, 64, 71, 71, 64, 64, 60, 67, 49, 46, 53, 24, 45, 96, 85, - 63, 69, 77, 60, 75, 51, 48, 46, 12, 72, 92, 67, 38, 40, 56, 48, - 37, 38, 42, 30, 32, 72, 76, 75, 68, 57, 76, 42, 48, 40, 36, 30, - 4, 80, 69, 61, 56, 64, 37, 52, 34, 36, 49, 52, 8, 76, 104, 81, - 56, 52, 56, 75, 55, 33, 34, 22, 68, 61, 81, 77, 61, 37, 63, 36, - 34, 36, 37, 13, 88, 116, 93, 67, 64, 80, 63, 79, 75, 84, 71, 61, - 9, 60, 59, 28, 21, 26, 40, 24, 28, 20, 18, 24, 9, 24, 60, 87, - 53, 42, 29, 36, 48, 37, 33, 18, 5, 59, 80, 48, 51, 59, 52, 68, - 51, 51, 41, 32, 17, 0, 99, 107, 75, 72, 65, 68, 67, 56, 51, 51, - 4, 83, 88, 42, 26, 56, 57, 45, 33, 53, 24, 21, 17, 57, 81, 85, - 40, 21, 22, 20, 21, 25, 30, 21, 5, 69, 71, 59, 83, 56, 40, 26, - 26, 25, 44, 26, 10, 20, 65, 51, 46, 41, 41, 36, 22, 21, 12, 1, - 92, 61, 46, 28, 28, 37, 32, 26, 26, 41, 18, 14, 2, 75, 28, 14, - 10, 12, 13, 38, 25, 17, 13, 9, 0, 53, 55, 68, 30, 29, 40, 41, - 9, 22, 9, 5, 0, 34, 59, 32, 30, 30, 36, 37, 30, 22, 14, 5, - 0, 5, 4, 18, 21, 21, 33, 14, 9, 10, 24, 10, 4, 36, 72, 37, - 36, 32, 99, 92, 87, 84, 83, 81, 80, 81, 68, 16, 84, 96, 93, 92, - 93, 102, 96, 100, 95, 61, 20, 80, 103, 96, 96, 87, 92, 91, 95, 81, - 88, 79, 63, 0, 95, 102, 92, 79, 81, 96, 91, 93, 69, 56, 38, 80, - 91, 104, 104, 93, 65, 61, 65, 72, 72, 63, 64, 69, 63, 55, 61, 76, - 80, 79, 75, 64, 59, 52, 46, 56, 97, 124, 88, 96, 84, 93, 84, 67, - 76, 64, 63, 16, 75, 96, 67, 93, 93, 93, 83, 87, 73, 52, 56, 6, - 95, 96, 99, 87, 83, 93, 87, 89, 89, 41, 18, 40, 41, 22, 22, 45, - 37, 46, 26, 20, 24, 24, 49, 25, 40, 85, 93, 88, 85, 80, 84, 77, - 59, 55, 42, 1, 85, 80, 103, 83, 84, 79, 73, 69, 71, 67, 65, 63, - 61, 38, 42, 48, 53, 53, 63, 72, 56, 52, 28, 68, 102, 83, 83, 75, - 87, 85, 84, 87, 88, 91, 56, 1, 81, 88, 88, 79, 87, 84, 69, 80, - 80, 75, 37, 41, 48, 77, 75, 91, 85, 67, 61, 81, 63, 40, 34, 41, - 45, 73, 49, 52, 56, 52, 53, 52, 49, 55, 51, 14, 56, 84, 52, 48, - 44, 49, 46, 44, 49, 45, 45, 46, 32, 45, 71, 72, 51, 44, 59, 51, - 56, 51, 42, 5, 67, 73, 53, 67, 57, 57, 52, 56, 46, 25, 36, 40, - 110, 103, 93, 92, 85, 85, 84, 85, 87, 72, 65, 18, 69, 89, 76, 64, - 71, 73, 60, 60, 63, 55, 24, 92, 114, 92, 91, 99, 102, 100, 88, 96, - 96, 91, 53, 41, 61, 89, 51, 79, 73, 59, 53, 51, 49, 42, 16, 63, - 85, 68, 45, 45, 45, 46, 44, 45, 49, 53, 49, 26, 34, 75, 72, 71, - 65, 57, 56, 63, 48, 48, 51, 32, 38, 83, 84, 67, 75, 92, 71, 61, - 40, 46, 41, 16, 64, 69, 44, 38, 38, 38, 32, 36, 26, 34, 40, 26, - 36, 61, 60, 68, 45, 48, 41, 40, 40, 44, 28, 6, 71, 84, 89, 60, - 61, 61, 34, 57, 49, 45, 38, 6, 83, 88, 73, 93, 41, 40, 57, 53, - 42, 28, 20, 75, 65, 75, 69, 53, 37, 56, 37, 36, 34, 34, 14, 73, - 122, 99, 87, 76, 77, 80, 80, 76, 71, 71, 59, 9, 44, 17, 17, 14, - 6, 13, 14, 14, 14, 14, 20, 12, 28, 55, 42, 29, 30, 25, 30, 32, - 32, 36, 25, 1, 68, 68, 46, 45, 68, 53, 46, 45, 45, 45, 32, 16, - 0, 103, 107, 73, 72, 76, 68, 68, 76, 49, 49, 0, 76, 75, 46, 28, - 53, 53, 53, 38, 38, 25, 22, 14, 51, 68, 59, 18, 20, 26, 21, 25, - 28, 28, 22, 6, 49, 71, 76, 36, 45, 41, 26, 33, 40, 45, 32, 17, - 10, 36, 64, 61, 49, 53, 46, 36, 25, 16, 2, 81, 63, 44, 18, 26, - 28, 36, 32, 26, 41, 16, 18, 0, 69, 21, 14, 14, 12, 16, 30, 42, - 18, 16, 9, 1, 55, 79, 51, 32, 26, 48, 16, 24, 24, 9, 5, 0, - 16, 40, 44, 44, 33, 30, 36, 34, 29, 9, 5, 0, 5, 13, 6, 9, - 8, 8, 9, 9, 9, 21, 24, 4, 71, 85, 64, 46, 41, 76, 80, 75, - 80, 79, 87, 81, 69, 61, 0, 80, 81, 83, 81, 83, 81, 85, 80, 73, - 59, 14, 79, 83, 80, 77, 79, 77, 79, 85, 75, 76, 63, 61, 12, 89, - 96, 95, 92, 92, 84, 91, 89, 65, 53, 42, 68, 87, 96, 93, 65, 71, - 56, 55, 63, 71, 60, 57, 55, 59, 60, 63, 72, 67, 67, 65, 65, 51, - 53, 44, 56, 95, 95, 88, 75, 68, 73, 79, 63, 61, 63, 63, 13, 71, - 96, 87, 71, 67, 81, 89, 80, 69, 57, 56, 8, 89, 95, 104, 88, 89, - 96, 92, 87, 61, 49, 16, 49, 42, 14, 18, 13, 21, 16, 20, 20, 18, - 17, 21, 24, 52, 36, 44, 46, 46, 48, 49, 55, 60, 46, 36, 4, 77, - 83, 83, 80, 75, 52, 71, 44, 48, 51, 63, 46, 52, 55, 61, 55, 56, - 59, 59, 79, 57, 40, 21, 63, 67, 79, 68, 65, 65, 68, 69, 71, 63, - 57, 56, 1, 79, 77, 81, 76, 71, 69, 69, 69, 68, 61, 59, 59, 64, - 51, 49, 53, 52, 49, 63, 55, 60, 56, 53, 57, 56, 55, 45, 57, 56, - 48, 56, 57, 56, 53, 52, 4, 44, 75, 57, 45, 37, 37, 41, 42, 42, - 42, 46, 44, 46, 51, 49, 51, 49, 49, 51, 52, 52, 45, 37, 12, 57, - 63, 57, 53, 48, 44, 57, 40, 36, 32, 22, 38, 61, 100, 107, 69, 85, - 85, 88, 72, 73, 67, 65, 14, 61, 59, 61, 53, 55, 55, 59, 59, 63, - 56, 25, 68, 103, 95, 92, 83, 85, 83, 80, 72, 63, 65, 53, 41, 53, - 68, 64, 55, 53, 51, 52, 56, 44, 41, 13, 64, 81, 67, 63, 65, 57, - 63, 55, 60, 63, 59, 48, 51, 29, 33, 41, 59, 36, 40, 57, 61, 59, - 61, 46, 41, 32, 42, 88, 73, 71, 67, 40, 42, 49, 38, 30, 25, 59, - 76, 42, 32, 33, 34, 28, 28, 34, 28, 28, 33, 40, 40, 49, 42, 45, - 41, 42, 44, 45, 42, 30, 5, 68, 71, 77, 61, 38, 67, 59, 65, 49, - 48, 42, 9, 73, 88, 61, 57, 67, 65, 60, 59, 36, 34, 24, 73, 59, - 52, 42, 57, 34, 33, 36, 34, 33, 38, 10, 77, 104, 84, 53, 76, 72, - 53, 65, 69, 68, 65, 32, 12, 10, 13, 18, 8, 9, 14, 12, 13, 13, - 16, 16, 14, 22, 28, 26, 24, 24, 28, 29, 26, 26, 25, 25, 0, 56, - 60, 56, 53, 51, 49, 48, 38, 41, 40, 28, 16, 0, 93, 103, 72, 71, - 68, 71, 69, 75, 46, 49, 6, 63, 75, 44, 26, 20, 29, 22, 24, 16, - 18, 22, 16, 16, 18, 20, 22, 26, 25, 25, 24, 26, 25, 20, 6, 18, - 49, 45, 20, 28, 40, 37, 22, 30, 30, 30, 17, 12, 14, 25, 20, 20, - 18, 18, 24, 25, 16, 2, 53, 60, 53, 45, 42, 42, 37, 26, 32, 41, - 17, 17, 0, 65, 37, 14, 12, 10, 29, 25, 25, 20, 17, 10, 1, 49, - 75, 30, 30, 6, 29, 28, 8, 9, 20, 4, 0, 13, 22, 36, 10, 10, - 16, 25, 21, 10, 10, 5, 0, 4, 10, 10, 9, 8, 8, 8, 10, 8, - 17, 10, 2, 56, 85, 42, 24, 24, 56, 55, 63, 52, 51, 46, 63, 45, - 18, 0, 33, 41, 38, 40, 45, 42, 42, 44, 48, 42, 17, 44, 51, 49, - 46, 44, 42, 40, 41, 40, 38, 37, 30, 0, 33, 36, 34, 42, 42, 37, - 38, 49, 45, 34, 45, 38, 60, 65, 38, 37, 46, 38, 36, 37, 34, 36, - 32, 33, 30, 30, 34, 38, 41, 42, 44, 48, 49, 53, 41, 46, 64, 63, - 55, 49, 53, 60, 51, 48, 56, 51, 32, 12, 37, 55, 65, 55, 59, 57, - 64, 57, 60, 53, 52, 9, 81, 92, 91, 91, 79, 75, 83, 73, 46, 45, - 12, 61, 26, 10, 14, 10, 10, 12, 17, 16, 13, 20, 16, 17, 21, 22, - 18, 30, 32, 34, 36, 36, 40, 42, 38, 1, 24, 36, 41, 26, 26, 26, - 28, 21, 21, 18, 26, 25, 18, 20, 26, 26, 28, 21, 51, 53, 52, 33, - 20, 36, 42, 41, 41, 41, 56, 51, 41, 37, 36, 32, 16, 30, 33, 37, - 45, 52, 40, 41, 45, 45, 45, 45, 46, 45, 49, 51, 55, 51, 51, 49, - 51, 51, 55, 48, 45, 44, 53, 48, 44, 41, 52, 41, 37, 36, 52, 36, - 8, 6, 41, 29, 29, 32, 20, 25, 17, 16, 18, 21, 18, 18, 20, 20, - 20, 20, 26, 28, 32, 33, 44, 36, 34, 12, 12, 13, 14, 13, 16, 10, - 14, 13, 17, 12, 12, 25, 46, 42, 49, 52, 49, 48, 51, 51, 51, 46, - 44, 13, 38, 44, 42, 45, 42, 42, 44, 55, 46, 45, 26, 18, 71, 81, - 60, 60, 65, 76, 61, 61, 67, 69, 59, 41, 36, 37, 42, 49, 52, 51, - 55, 63, 41, 37, 12, 56, 75, 75, 69, 55, 60, 60, 60, 51, 48, 46, - 40, 37, 41, 45, 45, 42, 44, 41, 44, 42, 41, 40, 38, 41, 42, 44, - 46, 49, 44, 42, 41, 41, 41, 34, 45, 17, 60, 33, 26, 25, 22, 21, - 24, 18, 17, 16, 17, 17, 17, 30, 16, 17, 17, 20, 18, 28, 30, 26, - 25, 6, 18, 64, 60, 26, 26, 52, 51, 26, 33, 44, 33, 9, 44, 72, - 67, 48, 46, 57, 56, 38, 36, 32, 25, 69, 59, 36, 34, 32, 32, 34, - 32, 33, 33, 36, 17, 65, 81, 73, 26, 21, 22, 22, 25, 18, 18, 12, - 36, 13, 0, 1, 8, 1, 8, 0, 4, 5, 8, 4, 10, 13, 18, 22, - 21, 16, 22, 21, 22, 14, 24, 22, 17, 0, 10, 13, 14, 13, 13, 12, - 13, 13, 13, 13, 13, 13, 0, 41, 89, 85, 83, 83, 81, 80, 73, 45, - 64, 8, 42, 61, 24, 26, 21, 22, 32, 26, 24, 22, 22, 21, 18, 12, - 10, 10, 8, 10, 9, 9, 8, 6, 6, 4, 9, 9, 9, 12, 10, 10, - 10, 10, 13, 12, 12, 13, 13, 14, 14, 16, 16, 16, 14, 14, 16, 14, - 2, 9, 17, 26, 12, 14, 17, 34, 34, 41, 21, 20, 12, 4, 60, 20, - 22, 21, 17, 18, 13, 17, 12, 9, 6, 2, 8, 14, 30, 2, 2, 1, - 4, 1, 1, 1, 13, 0, 2, 2, 1, 8, 4, 5, 4, 8, 10, 14, - 4, 0, 8, 2, 13, 4, 9, 12, 13, 9, 16, 17, 9, 5, 37, 85, - 30, 29, 25, 4, 1, 4, 12, 13, 1, 1, 18, 20, 6, 21, 17, 13, - 12, 10, 24, 9, 8, 6, 25, 20, 2, 21, 4, 2, 2, 13, 2, 2, - 2, 1, 1, 1, 2, 5, 8, 5, 9, 6, 6, 6, 12, 9, 9, 45, - 48, 51, 72, 72, 81, 81, 83, 89, 91, 87, 81, 83, 81, 81, 100, 80, - 83, 52, 55, 51, 49, 42, 42, 36, 25, 28, 24, 22, 18, 18, 17, 17, - 17, 18, 20, 20, 20, 22, 26, 26, 29, 33, 34, 37, 38, 41, 44, 48, - 16, 13, 34, 36, 36, 34, 36, 37, 37, 37, 33, 14, 33, 9, 24, 12, - 18, 12, 17, 36, 55, 69, 72, 59, 61, 75, 79, 88, 79, 72, 59, 53, - 44, 46, 18, 36, 2, 16, 18, 33, 33, 40, 48, 57, 65, 91, 81, 65, - 56, 88, 91, 77, 87, 88, 63, 48, 42, 33, 21, 10, 18, 16, 8, 10, - 10, 9, 5, 6, 6, 5, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, - 0, 8, 0, 0, 0, 13, 0, 0, 0, 21, 0, 0, 4, 12, 20, 25, - 24, 65, 89, 92, 99, 92, 85, 63, 72, 88, 85, 69, 83, 80, 73, 59, - 40, 34, 17, 26, 13, 1, 0, 12, 10, 0, 0, 8, 2, 4, 0, 2, - 4, 4, 0, 1, 1, 0, 2, 9, 10, 0, 4, 1, 1, 25, 28, 1, - 1, 14, 16, 16, 17, 24, 17, 30, 9, 9, 14, 10, 9, 10, 14, 9, - 9, 9, 14, 10, 10, 10, 32, 10, 10, 10, 13, 16, 20, 20, 37, 10, - 29, 48, 48, 30, 29, 44, 44, 29, 29, 30, 29, 28, 21, 21, 17, 10, - 13, 14, 16, 21, 21, 32, 32, 30, 28, 32, 30, 22, 21, 28, 22, 17, - 14, 26, 16, 36, 21, 32, 44, 56, 53, 57, 65, 85, 67, 49, 45, 34, - 34, 42, 71, 68, 71, 64, 48, 34, 28, 24, 18, 13, 14, 17, 25, 18, - 22, 14, 18, 21, 24, 16, 17, 13, 26, 25, 25, 26, 26, 25, 22, 25, - 25, 24, 24, 26, 65, 34, 26, 34, 28, 32, 28, 29, 25, 25, 26, 33, - 20, 26, 37, 42, 52, 53, 55, 55, 45, 52, 38, 29, 5, 25, 97, 69, - 63, 45, 22, 25, 17, 16, 4, 4, 4, 1, 8, 6, 2, 1, 8, 8, - 5, 1, 6, 8, 2, 1, 5, 6, 5, 0, 4, 1, 4, 0, 1, 1, - 0, 0, 20, 22, 26, 29, 32, 34, 37, 40, 44, 42, 6, 49, 16, 17, - 12, 10, 14, 12, 10, 9, 12, 6, 9, 29, 41, 45, 56, 57, 60, 61, - 52, 45, 38, 17, 6, 57, 69, 68, 49, 63, 57, 52, 21, 10, 10, 4, - 8, 8, 9, 8, 12, 10, 6, 4, 5, 4, 2, 2, 9, 8, 9, 6, - 6, 9, 12, 13, 14, 13, 13, 12, 0, 51, 2, 2, 5, 2, 1, 1, - 0, 1, 1, 0, 1, 4, 14, 29, 25, 26, 36, 40, 37, 33, 25, 6, - 0, 41, 69, 61, 61, 61, 56, 26, 16, 6, 4, 1, 0, 0, 2, 0, - 0, 4, 2, 2, 1, 2, 0, 6, 4, 24, 76, 42, 40, 29, 138, 130, - 122, 114, 106, 103, 99, 75, 36, 16, 52, 102, 108, 95, 81, 83, 87, 87, - 89, 68, 30, 40, 102, 106, 107, 102, 111, 108, 108, 99, 104, 92, 103, 99, - 108, 110, 114, 122, 118, 108, 111, 100, 59, 45, 53, 81, 108, 122, 111, 102, - 111, 110, 111, 100, 106, 111, 103, 71, 65, 77, 71, 83, 80, 79, 87, 81, - 41, 53, 41, 40, 102, 99, 89, 81, 88, 87, 76, 76, 77, 65, 65, 72, - 81, 93, 83, 84, 60, 51, 34, 22, 32, 22, 13, 17, 22, 12, 10, 13, - 28, 8, 6, 8, 37, 21, 21, 26, 56, 65, 69, 76, 69, 75, 84, 76, - 73, 81, 72, 63, 53, 67, 84, 68, 73, 71, 75, 69, 76, 60, 48, 4, - 36, 100, 103, 103, 107, 97, 92, 87, 84, 92, 83, 49, 76, 89, 100, 91, - 91, 85, 71, 81, 52, 44, 22, 33, 76, 80, 89, 92, 92, 79, 85, 97, - 99, 64, 63, 67, 111, 108, 111, 110, 108, 106, 111, 108, 102, 67, 71, 97, - 104, 107, 100, 85, 95, 106, 89, 91, 89, 91, 77, 16, 40, 91, 96, 71, - 79, 85, 93, 76, 81, 79, 28, 28, 36, 99, 85, 85, 92, 87, 83, 96, - 85, 60, 67, 52, 64, 72, 88, 80, 85, 76, 64, 65, 65, 41, 20, 2, - 26, 75, 84, 73, 65, 72, 64, 61, 57, 40, 20, 0, 37, 85, 107, 80, - 77, 76, 72, 87, 88, 87, 48, 33, 41, 95, 99, 87, 92, 93, 97, 68, - 77, 37, 40, 32, 75, 80, 81, 64, 65, 60, 55, 77, 64, 57, 25, 32, - 37, 67, 72, 65, 71, 40, 40, 17, 16, 12, 13, 18, 17, 26, 32, 25, - 26, 20, 20, 29, 34, 25, 25, 17, 9, 55, 81, 88, 71, 80, 64, 56, - 24, 22, 14, 9, 16, 29, 49, 53, 52, 52, 59, 51, 53, 44, 33, 49, - 73, 106, 114, 100, 99, 97, 93, 91, 88, 87, 34, 34, 61, 91, 89, 95, - 87, 84, 79, 88, 79, 59, 41, 40, 65, 65, 72, 67, 59, 55, 59, 48, - 26, 20, 13, 21, 21, 32, 32, 24, 12, 16, 12, 25, 8, 10, 29, 25, - 46, 63, 64, 77, 80, 87, 80, 85, 75, 40, 33, 55, 67, 71, 75, 71, - 73, 72, 75, 63, 80, 59, 44, 0, 76, 71, 64, 44, 71, 69, 60, 52, - 48, 64, 53, 44, 75, 83, 72, 76, 84, 76, 68, 61, 60, 52, 12, 0, - 20, 68, 96, 75, 67, 65, 72, 59, 56, 71, 56, 17, 0, 64, 75, 69, - 68, 61, 55, 18, 36, 32, 25, 1, 16, 26, 44, 51, 49, 59, 67, 72, - 59, 68, 55, 68, 55, 61, 65, 60, 57, 65, 61, 71, 56, 41, 18, 8, - 68, 69, 45, 48, 56, 38, 46, 41, 46, 41, 25, 33, 24, 60, 68, 67, - 57, 69, 64, 55, 52, 14, 2, 26, 59, 55, 41, 44, 44, 38, 12, 8, - 5, 5, 5, 0, 1, 32, 32, 30, 32, 40, 41, 42, 41, 41, 12, 2, - 38, 71, 67, 71, 67, 63, 56, 49, 44, 26, 8, 0, 49, 79, 59, 56, - 51, 60, 49, 55, 46, 25, 6, 0, 37, 52, 51, 13, 10, 8, 6, 13, - 6, 2, 6, 2, 71, 48, 106, 116, 120, 124, 115, 107, 110, 103, 106, 96, - 93, 41, 24, 107, 100, 93, 85, 97, 97, 92, 89, 87, 96, 32, 115, 118, - 118, 114, 110, 115, 112, 122, 110, 118, 108, 102, 93, 107, 100, 106, 104, 110, - 106, 106, 106, 102, 103, 55, 118, 112, 99, 95, 102, 93, 107, 92, 97, 93, - 67, 69, 57, 75, 88, 83, 85, 72, 71, 72, 77, 85, 57, 51, 85, 97, - 93, 97, 103, 92, 96, 93, 95, 89, 85, 72, 85, 80, 80, 80, 73, 80, - 69, 69, 73, 67, 71, 52, 12, 30, 81, 88, 67, 75, 76, 88, 79, 73, - 40, 18, 60, 85, 85, 92, 81, 89, 91, 102, 93, 81, 89, 73, 38, 68, - 89, 100, 96, 72, 83, 83, 76, 79, 64, 52, 5, 76, 110, 88, 89, 95, - 83, 93, 77, 81, 102, 80, 52, 76, 104, 102, 89, 96, 92, 96, 71, 85, - 49, 22, 76, 87, 95, 85, 88, 83, 89, 83, 96, 89, 96, 91, 81, 75, - 75, 73, 72, 73, 72, 72, 75, 77, 85, 79, 67, 80, 81, 80, 71, 88, - 87, 92, 92, 99, 93, 87, 16, 100, 114, 99, 95, 99, 91, 79, 80, 76, - 79, 34, 24, 75, 83, 87, 85, 89, 88, 91, 91, 81, 71, 60, 48, 63, - 91, 93, 88, 92, 87, 76, 71, 68, 45, 22, 6, 83, 87, 87, 80, 84, - 85, 79, 75, 75, 64, 21, 1, 115, 119, 119, 112, 116, 111, 106, 97, 116, - 110, 76, 34, 100, 118, 115, 106, 103, 89, 100, 92, 84, 53, 40, 75, 96, - 84, 80, 80, 89, 91, 81, 87, 84, 85, 72, 30, 64, 83, 85, 81, 81, - 77, 73, 65, 38, 24, 12, 42, 63, 40, 48, 55, 51, 61, 52, 46, 44, - 30, 28, 12, 8, 68, 88, 69, 61, 68, 72, 88, 71, 83, 67, 55, 72, - 53, 76, 80, 89, 76, 91, 71, 81, 57, 51, 59, 91, 115, 79, 83, 79, - 80, 64, 79, 69, 63, 67, 53, 85, 72, 77, 67, 64, 64, 75, 67, 64, - 57, 73, 61, 65, 69, 68, 55, 71, 69, 71, 57, 57, 60, 60, 81, 76, - 83, 83, 84, 85, 83, 89, 93, 93, 40, 41, 63, 116, 116, 118, 115, 118, - 114, 107, 111, 108, 67, 33, 53, 77, 73, 67, 64, 56, 57, 48, 44, 55, - 63, 30, 2, 51, 72, 61, 49, 44, 59, 38, 51, 46, 36, 41, 49, 49, - 55, 59, 51, 40, 45, 46, 53, 44, 63, 14, 0, 93, 97, 102, 103, 97, - 93, 91, 79, 87, 81, 64, 33, 0, 68, 67, 72, 75, 75, 69, 63, 55, - 48, 26, 6, 49, 81, 83, 85, 88, 87, 85, 76, 67, 63, 30, 55, 80, - 79, 80, 80, 71, 63, 49, 52, 56, 42, 22, 9, 67, 73, 44, 42, 34, - 40, 55, 45, 60, 49, 20, 16, 63, 80, 76, 76, 75, 65, 59, 67, 65, - 16, 4, 48, 60, 60, 60, 63, 55, 56, 42, 44, 37, 28, 8, 37, 67, - 81, 77, 76, 69, 72, 68, 60, 65, 44, 21, 2, 60, 61, 51, 48, 48, - 32, 34, 20, 30, 45, 10, 1, 32, 76, 61, 49, 33, 37, 36, 37, 55, - 42, 10, 0, 56, 56, 64, 52, 48, 30, 41, 46, 45, 5, 8, 0, 69, - 64, 85, 84, 92, 138, 136, 124, 120, 111, 110, 71, 71, 41, 22, 92, 99, - 83, 83, 87, 60, 83, 87, 84, 41, 34, 118, 132, 139, 150, 170, 178, 189, - 197, 205, 205, 212, 216, 220, 213, 218, 218, 216, 202, 193, 155, 128, 123, 120, - 93, 112, 108, 110, 104, 99, 104, 106, 84, 60, 60, 63, 59, 55, 76, 95, - 107, 85, 77, 87, 85, 88, 84, 77, 37, 96, 103, 91, 92, 83, 85, 87, - 84, 79, 85, 84, 77, 75, 91, 93, 92, 83, 80, 72, 72, 80, 83, 63, - 55, 16, 92, 88, 100, 99, 85, 95, 95, 88, 89, 73, 20, 73, 110, 96, - 76, 99, 91, 84, 83, 84, 95, 91, 69, 45, 68, 92, 100, 81, 80, 88, - 84, 91, 75, 64, 60, 4, 83, 103, 100, 91, 79, 85, 81, 96, 81, 91, - 87, 37, 71, 92, 93, 95, 79, 81, 75, 73, 80, 56, 28, 81, 72, 81, - 83, 75, 91, 88, 96, 97, 84, 77, 65, 93, 75, 91, 81, 84, 84, 84, - 77, 67, 65, 55, 55, 73, 89, 85, 87, 89, 88, 83, 88, 88, 87, 87, - 81, 16, 103, 112, 73, 72, 73, 67, 68, 64, 76, 75, 34, 25, 72, 92, - 87, 83, 73, 71, 75, 77, 88, 72, 65, 34, 57, 88, 77, 81, 89, 87, - 67, 60, 71, 49, 37, 9, 80, 83, 79, 76, 76, 68, 68, 68, 61, 65, - 28, 0, 100, 112, 114, 115, 111, 111, 114, 103, 103, 108, 85, 41, 110, 106, - 103, 84, 73, 79, 64, 72, 75, 89, 71, 92, 79, 73, 79, 65, 76, 52, - 57, 56, 60, 44, 46, 36, 84, 118, 80, 87, 84, 91, 81, 72, 84, 33, - 12, 52, 53, 36, 52, 38, 33, 52, 40, 36, 45, 26, 24, 14, 10, 69, - 97, 65, 57, 76, 64, 67, 65, 52, 71, 34, 48, 99, 92, 91, 97, 92, - 85, 79, 77, 67, 53, 55, 106, 108, 75, 77, 73, 64, 57, 71, 88, 83, - 85, 85, 95, 93, 104, 93, 93, 97, 124, 96, 103, 99, 102, 95, 102, 103, - 106, 97, 96, 103, 99, 102, 79, 60, 41, 85, 83, 77, 81, 76, 73, 64, - 73, 72, 69, 46, 30, 88, 122, 111, 110, 107, 112, 112, 118, 104, 87, 83, - 40, 56, 73, 72, 51, 48, 63, 51, 46, 63, 61, 56, 30, 4, 40, 73, - 63, 61, 51, 59, 53, 65, 61, 46, 41, 41, 64, 77, 65, 81, 80, 73, - 60, 80, 68, 59, 16, 4, 83, 96, 87, 88, 92, 89, 84, 83, 76, 93, - 67, 30, 0, 71, 75, 71, 52, 53, 41, 57, 69, 52, 14, 9, 45, 89, - 85, 73, 57, 48, 68, 45, 44, 36, 33, 65, 84, 68, 68, 53, 45, 52, - 67, 56, 45, 24, 20, 5, 65, 76, 65, 44, 45, 51, 55, 52, 46, 45, - 20, 36, 76, 77, 72, 57, 72, 52, 49, 57, 72, 14, 4, 56, 63, 37, - 37, 30, 22, 25, 20, 26, 46, 38, 8, 33, 72, 65, 72, 79, 59, 48, - 49, 67, 59, 56, 17, 2, 59, 44, 25, 55, 37, 37, 26, 20, 25, 21, - 8, 0, 48, 71, 48, 59, 44, 32, 32, 60, 41, 38, 12, 0, 24, 59, - 51, 59, 51, 55, 42, 52, 38, 13, 8, 1, 83, 103, 84, 75, 84, 112, - 99, 108, 103, 91, 77, 81, 93, 44, 36, 67, 93, 85, 73, 64, 60, 61, - 64, 68, 93, 102, 130, 204, 212, 222, 225, 225, 224, 226, 228, 233, 234, 237, - 237, 237, 233, 230, 230, 229, 226, 221, 222, 193, 147, 132, 122, 146, 161, 190, - 165, 140, 107, 85, 56, 61, 61, 60, 55, 97, 108, 99, 96, 84, 95, 100, - 102, 85, 95, 81, 89, 87, 89, 64, 91, 85, 92, 84, 87, 79, 79, 77, - 89, 106, 114, 99, 102, 97, 104, 100, 83, 69, 63, 56, 16, 100, 92, 97, - 96, 97, 84, 85, 79, 77, 71, 32, 80, 89, 99, 88, 84, 89, 79, 84, - 95, 96, 80, 65, 37, 64, 95, 107, 85, 80, 85, 91, 84, 76, 60, 46, - 5, 71, 95, 93, 91, 88, 85, 83, 65, 100, 99, 77, 45, 75, 93, 89, - 81, 81, 79, 67, 79, 81, 59, 38, 48, 75, 77, 84, 93, 102, 80, 81, - 84, 71, 72, 57, 84, 89, 71, 87, 83, 85, 68, 76, 76, 75, 51, 51, - 81, 85, 83, 81, 76, 80, 83, 61, 83, 83, 49, 53, 21, 64, 115, 75, - 71, 79, 59, 67, 69, 75, 72, 37, 22, 71, 85, 84, 67, 71, 71, 67, - 69, 84, 72, 60, 34, 63, 81, 72, 61, 91, 93, 67, 61, 73, 40, 37, - 9, 60, 88, 75, 72, 79, 64, 83, 77, 57, 61, 25, 4, 65, 111, 102, - 89, 85, 85, 93, 99, 88, 85, 88, 87, 91, 107, 104, 95, 83, 100, 71, - 83, 63, 69, 61, 71, 60, 72, 67, 63, 60, 67, 65, 64, 60, 67, 64, - 68, 76, 89, 97, 65, 72, 73, 107, 77, 73, 30, 9, 34, 45, 34, 42, - 51, 55, 48, 52, 36, 29, 32, 18, 10, 8, 64, 83, 60, 63, 76, 77, - 77, 71, 61, 64, 34, 87, 103, 96, 87, 75, 76, 73, 68, 77, 52, 51, - 65, 87, 107, 67, 76, 63, 68, 73, 116, 202, 205, 193, 206, 221, 222, 206, - 214, 228, 232, 228, 225, 232, 242, 226, 229, 224, 241, 221, 210, 216, 246, 222, - 155, 91, 57, 45, 85, 100, 114, 110, 106, 106, 93, 87, 88, 69, 46, 42, - 104, 115, 104, 103, 110, 108, 120, 114, 87, 95, 77, 45, 45, 72, 60, 51, - 45, 56, 51, 45, 45, 60, 53, 25, 1, 51, 84, 68, 88, 65, 52, 60, - 53, 51, 46, 40, 18, 69, 76, 63, 65, 69, 69, 44, 68, 67, 59, 13, - 4, 57, 91, 85, 77, 72, 71, 65, 69, 73, 84, 65, 29, 0, 68, 68, - 60, 34, 55, 57, 52, 55, 53, 25, 12, 56, 87, 67, 60, 60, 53, 64, - 33, 42, 38, 22, 60, 71, 56, 49, 48, 67, 45, 46, 37, 30, 34, 21, - 9, 64, 76, 67, 59, 68, 68, 34, 45, 38, 46, 12, 29, 80, 76, 69, - 41, 69, 55, 71, 68, 64, 16, 5, 55, 45, 30, 32, 21, 21, 21, 21, - 21, 41, 36, 9, 30, 67, 64, 69, 89, 61, 44, 49, 53, 45, 41, 16, - 2, 52, 56, 29, 63, 29, 41, 24, 25, 37, 21, 6, 0, 48, 72, 49, - 45, 40, 41, 37, 56, 36, 20, 10, 0, 45, 42, 49, 51, 34, 37, 36, - 26, 34, 28, 9, 1, 67, 61, 59, 28, 17, 81, 81, 88, 81, 87, 73, - 95, 85, 44, 32, 72, 96, 89, 65, 61, 56, 55, 102, 115, 162, 197, 214, - 226, 236, 233, 233, 230, 230, 225, 232, 237, 238, 237, 236, 233, 232, 228, 222, - 225, 226, 225, 221, 224, 218, 220, 212, 205, 208, 202, 194, 130, 106, 83, 56, - 61, 67, 68, 69, 123, 183, 193, 186, 187, 194, 199, 202, 198, 195, 194, 193, - 193, 136, 114, 106, 102, 103, 92, 89, 97, 99, 135, 170, 195, 201, 195, 193, - 189, 134, 97, 84, 53, 64, 46, 18, 65, 92, 84, 81, 80, 80, 71, 81, - 85, 73, 34, 55, 89, 100, 81, 84, 84, 79, 80, 85, 95, 79, 67, 36, - 71, 84, 100, 88, 77, 84, 88, 81, 76, 59, 51, 6, 61, 99, 104, 97, - 88, 96, 71, 85, 89, 88, 77, 36, 75, 84, 93, 75, 75, 85, 73, 91, - 76, 57, 37, 42, 89, 93, 73, 76, 77, 89, 77, 81, 76, 68, 51, 91, - 89, 79, 76, 73, 72, 75, 97, 87, 73, 64, 49, 85, 83, 91, 72, 80, - 81, 77, 81, 72, 80, 83, 76, 22, 64, 112, 79, 73, 67, 53, 57, 57, - 75, 73, 37, 20, 71, 84, 73, 61, 60, 60, 61, 63, 80, 65, 53, 36, - 52, 79, 76, 60, 77, 68, 56, 61, 71, 41, 21, 4, 60, 92, 68, 61, - 72, 77, 71, 63, 68, 56, 25, 2, 100, 102, 93, 92, 99, 99, 95, 96, - 130, 181, 193, 199, 209, 214, 221, 224, 230, 232, 249, 249, 246, 240, 240, 225, - 232, 236, 233, 230, 225, 228, 222, 224, 198, 202, 181, 205, 197, 228, 190, 182, - 174, 175, 199, 142, 83, 36, 14, 48, 28, 51, 55, 45, 41, 56, 30, 26, - 10, 34, 10, 8, 5, 61, 89, 64, 65, 80, 85, 81, 57, 55, 67, 24, - 88, 102, 87, 71, 71, 80, 87, 77, 84, 64, 40, 49, 81, 103, 65, 69, - 61, 64, 67, 127, 190, 195, 199, 205, 206, 212, 209, 209, 214, 217, 218, 220, - 222, 221, 218, 218, 216, 208, 208, 204, 199, 199, 193, 143, 85, 57, 12, 77, - 88, 92, 96, 95, 93, 111, 108, 76, 77, 49, 49, 76, 115, 103, 120, 118, - 102, 93, 72, 75, 87, 81, 46, 42, 76, 64, 45, 51, 51, 51, 44, 56, - 37, 52, 33, 0, 53, 83, 59, 67, 55, 64, 61, 80, 44, 42, 40, 32, - 63, 84, 72, 79, 81, 79, 77, 65, 55, 53, 14, 0, 60, 91, 76, 67, - 63, 69, 81, 83, 85, 91, 71, 28, 0, 65, 57, 51, 40, 69, 53, 55, - 57, 44, 20, 9, 41, 89, 72, 53, 52, 45, 63, 37, 36, 28, 22, 57, - 80, 48, 64, 71, 56, 46, 44, 48, 53, 32, 22, 14, 59, 64, 51, 57, - 45, 45, 36, 51, 38, 44, 12, 32, 76, 68, 52, 67, 59, 83, 68, 67, - 61, 18, 5, 42, 61, 34, 34, 24, 20, 17, 21, 21, 21, 25, 8, 2, - 64, 64, 77, 83, 42, 49, 51, 45, 56, 40, 21, 2, 45, 59, 30, 65, - 17, 40, 22, 20, 30, 18, 5, 0, 33, 68, 57, 60, 44, 44, 34, 53, - 42, 22, 10, 0, 41, 53, 48, 21, 26, 24, 25, 14, 29, 12, 8, 6, - 68, 60, 45, 56, 18, 77, 76, 79, 84, 77, 73, 95, 81, 44, 36, 97, - 88, 64, 61, 69, 91, 103, 177, 228, 233, 236, 237, 230, 229, 229, 229, 205, - 175, 162, 166, 170, 162, 146, 135, 128, 124, 112, 108, 116, 122, 135, 183, 205, - 218, 217, 214, 212, 202, 202, 187, 136, 103, 72, 55, 63, 53, 69, 116, 147, - 204, 201, 213, 201, 212, 218, 218, 216, 225, 222, 228, 225, 222, 217, 222, 220, - 217, 212, 202, 210, 214, 210, 217, 214, 202, 198, 189, 191, 134, 97, 79, 49, - 63, 49, 21, 65, 91, 73, 73, 102, 87, 87, 85, 76, 71, 34, 33, 84, - 93, 92, 88, 87, 93, 95, 96, 96, 79, 67, 36, 63, 106, 110, 80, 85, - 85, 89, 80, 75, 60, 46, 9, 77, 100, 92, 88, 81, 96, 77, 81, 92, - 77, 81, 36, 80, 81, 87, 80, 76, 88, 79, 83, 76, 57, 37, 33, 88, - 75, 72, 77, 85, 75, 87, 81, 68, 63, 48, 80, 91, 72, 69, 69, 81, - 77, 73, 76, 69, 49, 49, 85, 87, 97, 85, 83, 68, 88, 81, 68, 81, - 80, 79, 24, 67, 107, 81, 69, 67, 52, 53, 68, 79, 71, 37, 18, 77, - 79, 71, 61, 64, 59, 59, 64, 75, 63, 59, 37, 61, 76, 69, 60, 56, - 88, 79, 61, 65, 42, 21, 8, 69, 92, 75, 71, 72, 64, 63, 51, 67, - 76, 24, 2, 112, 114, 93, 95, 103, 91, 106, 179, 190, 202, 205, 205, 213, - 225, 225, 229, 233, 237, 246, 248, 248, 245, 244, 242, 226, 236, 241, 232, 225, - 225, 233, 226, 221, 228, 217, 213, 204, 210, 199, 195, 186, 206, 187, 157, 81, - 34, 13, 45, 26, 52, 45, 40, 46, 34, 36, 26, 13, 33, 12, 6, 5, - 64, 83, 65, 76, 71, 81, 84, 69, 56, 59, 22, 87, 96, 72, 83, 83, - 89, 99, 95, 91, 72, 51, 67, 77, 111, 72, 76, 76, 61, 63, 91, 131, - 178, 193, 197, 199, 195, 205, 194, 199, 206, 209, 210, 217, 217, 220, 209, 205, - 210, 202, 191, 190, 194, 166, 99, 76, 33, 21, 81, 95, 76, 89, 89, 97, - 96, 107, 80, 80, 49, 44, 77, 110, 96, 91, 71, 73, 77, 75, 80, 84, - 89, 60, 40, 71, 64, 56, 44, 46, 49, 52, 41, 55, 75, 30, 2, 75, - 59, 73, 52, 53, 60, 65, 59, 60, 44, 40, 30, 65, 85, 56, 79, 60, - 56, 56, 59, 64, 57, 13, 0, 93, 80, 71, 75, 77, 76, 76, 87, 85, - 83, 67, 40, 0, 61, 76, 48, 79, 45, 38, 52, 49, 44, 18, 4, 37, - 87, 69, 64, 60, 63, 60, 48, 33, 33, 22, 60, 76, 45, 56, 72, 59, - 46, 52, 51, 37, 33, 24, 18, 60, 79, 65, 67, 68, 48, 37, 41, 38, - 56, 16, 40, 73, 64, 44, 73, 79, 81, 61, 67, 52, 21, 5, 44, 55, - 41, 32, 21, 20, 33, 20, 24, 37, 46, 9, 2, 60, 57, 51, 42, 45, - 40, 40, 37, 38, 42, 20, 4, 37, 63, 38, 79, 17, 40, 16, 33, 26, - 22, 8, 2, 45, 67, 60, 55, 42, 33, 41, 44, 45, 30, 13, 0, 41, - 57, 28, 22, 10, 13, 14, 18, 25, 8, 8, 0, 63, 56, 34, 13, 2, - 102, 80, 75, 75, 73, 73, 99, 71, 48, 34, 99, 93, 64, 73, 97, 130, - 216, 236, 234, 232, 233, 236, 230, 217, 185, 151, 118, 107, 102, 103, 103, 103, - 103, 102, 100, 103, 100, 102, 99, 100, 99, 102, 115, 124, 151, 183, 191, 198, - 185, 140, 116, 84, 48, 52, 57, 60, 72, 128, 153, 226, 232, 202, 220, 212, - 224, 222, 226, 224, 221, 220, 226, 233, 229, 226, 224, 218, 217, 224, 217, 213, - 212, 212, 217, 209, 201, 201, 191, 118, 81, 68, 49, 59, 49, 24, 89, 89, - 84, 83, 92, 79, 87, 84, 88, 89, 68, 25, 80, 92, 103, 103, 103, 97, - 97, 91, 89, 76, 65, 36, 61, 92, 99, 89, 84, 88, 93, 83, 77, 77, - 49, 8, 71, 97, 92, 97, 89, 96, 92, 95, 95, 67, 65, 26, 76, 79, - 96, 73, 97, 81, 80, 75, 79, 68, 57, 32, 80, 77, 75, 72, 72, 77, - 77, 77, 67, 53, 45, 75, 83, 67, 65, 72, 81, 71, 71, 68, 64, 41, - 45, 75, 80, 88, 89, 79, 67, 81, 71, 80, 64, 81, 73, 26, 45, 67, - 108, 80, 65, 61, 53, 63, 79, 65, 38, 22, 64, 73, 68, 52, 56, 53, - 52, 71, 79, 73, 55, 30, 48, 65, 64, 55, 53, 83, 60, 64, 65, 46, - 30, 9, 71, 83, 67, 77, 71, 76, 71, 63, 69, 59, 25, 0, 92, 110, - 93, 96, 102, 91, 165, 190, 198, 201, 206, 210, 210, 217, 221, 229, 229, 232, - 241, 245, 244, 246, 245, 244, 238, 229, 238, 232, 228, 230, 220, 217, 221, 225, - 214, 213, 202, 198, 194, 190, 185, 189, 143, 120, 49, 33, 14, 45, 29, 41, - 56, 38, 34, 33, 24, 25, 13, 21, 17, 10, 6, 51, 95, 68, 81, 67, - 76, 79, 72, 64, 55, 29, 83, 81, 96, 104, 107, 118, 116, 114, 104, 87, - 77, 53, 92, 118, 80, 76, 60, 57, 64, 64, 79, 92, 104, 107, 107, 100, - 97, 93, 99, 97, 97, 99, 103, 108, 108, 104, 104, 106, 99, 96, 99, 96, - 92, 79, 71, 32, 38, 77, 91, 75, 73, 96, 89, 91, 99, 77, 75, 51, - 53, 72, 107, 108, 85, 85, 108, 93, 96, 102, 72, 80, 79, 40, 60, 77, - 61, 45, 48, 42, 51, 57, 56, 61, 29, 4, 46, 68, 65, 52, 52, 49, - 45, 57, 64, 51, 38, 30, 55, 92, 51, 84, 85, 69, 76, 73, 71, 48, - 17, 2, 92, 92, 79, 83, 73, 77, 76, 91, 83, 83, 65, 30, 0, 67, - 75, 55, 53, 52, 55, 44, 53, 29, 16, 10, 40, 84, 72, 46, 64, 55, - 46, 42, 36, 36, 26, 63, 77, 63, 63, 67, 55, 46, 46, 64, 40, 22, - 25, 12, 68, 73, 60, 48, 59, 55, 36, 48, 34, 42, 14, 59, 67, 45, - 68, 63, 61, 57, 67, 69, 56, 16, 6, 22, 41, 53, 32, 33, 20, 37, - 33, 21, 33, 45, 9, 22, 55, 64, 52, 40, 38, 42, 40, 40, 38, 38, - 21, 4, 38, 61, 29, 51, 20, 34, 16, 36, 28, 17, 6, 0, 57, 68, - 64, 63, 42, 38, 51, 46, 46, 34, 12, 0, 24, 41, 21, 9, 4, 1, - 2, 12, 18, 9, 8, 1, 64, 77, 28, 2, 25, 130, 88, 85, 84, 84, - 87, 88, 87, 48, 48, 75, 61, 75, 102, 165, 225, 240, 233, 234, 226, 216, - 195, 169, 126, 110, 103, 103, 103, 104, 104, 104, 104, 110, 104, 91, 77, 69, - 76, 84, 95, 124, 107, 100, 100, 97, 106, 108, 108, 108, 104, 100, 63, 48, - 52, 57, 51, 68, 111, 131, 182, 191, 191, 159, 124, 115, 120, 126, 123, 122, - 124, 135, 162, 190, 198, 205, 210, 216, 214, 206, 195, 197, 204, 202, 198, 183, - 138, 115, 92, 77, 45, 44, 56, 44, 24, 61, 85, 85, 83, 83, 93, 92, - 84, 84, 92, 53, 28, 68, 91, 88, 89, 95, 88, 91, 91, 88, 71, 65, - 30, 57, 85, 102, 104, 106, 97, 99, 83, 79, 64, 45, 6, 64, 92, 91, - 92, 84, 96, 88, 89, 84, 79, 48, 25, 75, 83, 91, 72, 84, 83, 84, - 76, 73, 77, 49, 32, 52, 84, 77, 84, 77, 76, 77, 72, 65, 49, 40, - 65, 89, 73, 68, 73, 76, 77, 72, 73, 68, 41, 40, 79, 77, 77, 75, - 76, 76, 81, 79, 81, 61, 51, 64, 32, 38, 68, 83, 95, 76, 61, 52, - 69, 71, 68, 41, 18, 60, 80, 65, 61, 52, 53, 64, 96, 68, 64, 51, - 24, 61, 75, 55, 49, 55, 51, 56, 57, 55, 40, 30, 10, 48, 91, 79, - 80, 69, 61, 63, 79, 65, 67, 24, 5, 69, 108, 95, 96, 106, 93, 93, - 138, 182, 191, 189, 169, 123, 114, 111, 110, 115, 112, 110, 104, 108, 108, 111, - 111, 111, 107, 103, 104, 106, 104, 103, 97, 97, 106, 110, 104, 102, 95, 89, - 93, 71, 63, 60, 56, 45, 16, 12, 41, 36, 45, 38, 45, 34, 29, 29, - 26, 10, 17, 14, 6, 5, 56, 71, 72, 63, 71, 77, 59, 65, 57, 48, - 33, 87, 89, 110, 132, 170, 179, 181, 162, 166, 144, 118, 102, 88, 115, 71, - 84, 71, 56, 59, 57, 72, 71, 64, 73, 79, 83, 80, 79, 81, 81, 81, - 83, 84, 84, 85, 87, 87, 85, 84, 85, 85, 81, 85, 81, 22, 13, 36, - 80, 85, 76, 85, 80, 80, 85, 102, 76, 71, 63, 42, 53, 92, 103, 83, - 69, 100, 104, 103, 77, 72, 80, 65, 44, 46, 63, 65, 49, 52, 52, 51, - 52, 53, 57, 21, 2, 41, 75, 69, 51, 55, 52, 45, 55, 65, 42, 37, - 14, 67, 84, 57, 67, 84, 85, 67, 83, 71, 44, 13, 2, 60, 77, 68, - 81, 87, 72, 77, 81, 81, 84, 63, 29, 1, 63, 53, 69, 53, 40, 32, - 45, 25, 24, 21, 14, 38, 77, 71, 63, 71, 57, 51, 46, 46, 26, 16, - 68, 72, 63, 71, 71, 48, 48, 61, 44, 34, 26, 24, 17, 71, 63, 48, - 61, 46, 38, 44, 52, 36, 42, 12, 38, 76, 72, 76, 57, 28, 60, 61, - 81, 57, 16, 8, 17, 42, 51, 37, 30, 29, 37, 18, 20, 36, 34, 10, - 18, 49, 63, 57, 45, 52, 45, 46, 45, 42, 40, 26, 6, 16, 57, 36, - 26, 22, 26, 18, 33, 33, 18, 5, 0, 30, 67, 45, 55, 38, 48, 36, - 37, 46, 20, 10, 0, 55, 49, 9, 9, 2, 13, 1, 6, 20, 14, 4, - 2, 64, 81, 20, 6, 51, 111, 112, 99, 104, 91, 100, 81, 81, 49, 46, - 63, 72, 114, 199, 234, 237, 234, 237, 236, 189, 146, 114, 104, 104, 106, 108, - 112, 100, 116, 115, 102, 73, 46, 30, 30, 29, 36, 30, 34, 37, 59, 77, - 119, 112, 100, 103, 99, 99, 96, 107, 95, 44, 41, 45, 53, 52, 71, 87, - 108, 103, 118, 104, 108, 92, 88, 87, 95, 89, 92, 87, 97, 93, 95, 102, - 103, 106, 103, 103, 103, 100, 97, 100, 106, 107, 95, 95, 85, 73, 40, 44, - 51, 53, 44, 25, 51, 81, 91, 84, 96, 85, 91, 91, 88, 84, 56, 32, - 56, 87, 85, 87, 81, 85, 89, 92, 84, 65, 63, 24, 63, 73, 85, 91, - 88, 84, 81, 84, 69, 69, 49, 8, 64, 85, 97, 92, 93, 88, 88, 89, - 80, 76, 59, 24, 68, 76, 91, 92, 77, 83, 71, 79, 59, 56, 45, 37, - 45, 44, 60, 57, 52, 55, 57, 59, 64, 60, 38, 72, 85, 67, 63, 73, - 73, 72, 72, 71, 69, 48, 36, 77, 75, 73, 69, 68, 71, 69, 73, 72, - 72, 72, 72, 51, 37, 73, 88, 77, 59, 49, 51, 72, 64, 65, 42, 17, - 71, 83, 71, 61, 51, 51, 65, 84, 68, 61, 51, 26, 51, 67, 53, 49, - 40, 42, 41, 51, 41, 38, 24, 10, 45, 88, 67, 42, 61, 72, 75, 56, - 61, 61, 22, 5, 97, 100, 95, 92, 96, 95, 99, 99, 102, 102, 102, 96, - 97, 97, 99, 97, 97, 95, 99, 97, 97, 96, 97, 96, 96, 92, 92, 89, - 88, 87, 88, 79, 84, 81, 80, 79, 77, 72, 72, 69, 61, 57, 42, 38, - 18, 12, 17, 37, 29, 41, 33, 29, 13, 17, 10, 2, 14, 16, 28, 6, - 2, 61, 95, 73, 65, 68, 65, 69, 59, 56, 25, 51, 91, 108, 174, 193, - 206, 206, 204, 189, 194, 194, 186, 174, 139, 112, 76, 53, 55, 60, 48, 55, - 44, 60, 56, 55, 64, 77, 87, 87, 89, 88, 85, 89, 93, 95, 95, 95, - 93, 92, 93, 93, 91, 97, 71, 18, 25, 14, 8, 72, 79, 87, 69, 77, - 68, 64, 61, 79, 67, 60, 41, 55, 73, 81, 77, 96, 88, 83, 73, 68, - 65, 69, 75, 45, 40, 51, 81, 75, 69, 63, 67, 69, 55, 53, 34, 1, - 49, 73, 75, 63, 55, 61, 52, 57, 73, 34, 37, 22, 55, 91, 65, 76, - 63, 46, 46, 57, 56, 51, 13, 1, 60, 85, 71, 72, 73, 75, 80, 83, - 76, 79, 72, 28, 1, 63, 69, 37, 30, 34, 29, 25, 37, 24, 17, 16, - 42, 73, 69, 73, 53, 42, 56, 51, 51, 29, 18, 52, 65, 56, 64, 52, - 49, 49, 48, 48, 46, 26, 25, 20, 75, 61, 57, 40, 42, 40, 33, 45, - 38, 20, 10, 63, 64, 77, 57, 33, 49, 44, 64, 45, 55, 13, 9, 13, - 38, 46, 42, 46, 40, 30, 20, 21, 24, 29, 8, 2, 52, 60, 64, 44, - 48, 48, 40, 34, 40, 42, 17, 8, 10, 53, 44, 24, 33, 30, 18, 25, - 22, 14, 5, 0, 49, 63, 55, 44, 32, 36, 36, 45, 46, 32, 26, 0, - 24, 38, 5, 17, 5, 16, 6, 8, 21, 9, 4, 12, 55, 52, 26, 42, - 95, 68, 67, 68, 64, 60, 61, 61, 52, 41, 76, 71, 112, 213, 240, 237, - 238, 236, 238, 197, 132, 107, 108, 108, 115, 115, 110, 115, 120, 115, 81, 44, - 26, 22, 24, 25, 26, 32, 32, 33, 36, 36, 49, 77, 108, 150, 112, 103, - 102, 102, 107, 89, 42, 37, 40, 49, 52, 55, 87, 84, 84, 79, 77, 91, - 92, 93, 93, 93, 95, 95, 92, 93, 92, 93, 95, 93, 92, 93, 91, 91, - 89, 87, 87, 91, 89, 87, 83, 61, 36, 38, 36, 51, 51, 46, 28, 34, - 79, 80, 91, 79, 55, 65, 57, 49, 45, 46, 55, 34, 51, 67, 79, 77, - 76, 76, 75, 80, 64, 63, 22, 61, 67, 87, 91, 89, 85, 81, 69, 65, - 63, 45, 12, 65, 69, 71, 71, 69, 69, 69, 71, 73, 63, 56, 24, 64, - 71, 85, 75, 57, 67, 64, 53, 55, 61, 55, 51, 55, 67, 51, 69, 61, - 64, 55, 64, 63, 44, 38, 59, 71, 76, 63, 65, 69, 69, 64, 68, 64, - 46, 34, 77, 73, 73, 64, 68, 67, 67, 61, 64, 60, 67, 56, 60, 34, - 48, 55, 53, 52, 53, 59, 60, 64, 63, 44, 14, 72, 64, 71, 59, 51, - 48, 46, 51, 56, 55, 44, 34, 48, 60, 41, 33, 36, 36, 37, 36, 37, - 36, 18, 12, 33, 64, 67, 48, 57, 67, 64, 61, 65, 72, 21, 2, 89, - 104, 97, 95, 93, 93, 95, 92, 92, 84, 88, 87, 76, 85, 72, 80, 85, - 81, 114, 111, 108, 111, 108, 108, 108, 107, 106, 103, 100, 102, 97, 93, 92, - 95, 89, 88, 91, 85, 67, 38, 18, 16, 13, 12, 10, 8, 17, 4, 8, - 9, 2, 1, 1, 2, 1, 2, 2, 9, 10, 5, 2, 46, 76, 81, 79, - 75, 83, 75, 60, 56, 22, 60, 100, 158, 214, 210, 206, 210, 195, 202, 205, - 197, 179, 174, 150, 73, 64, 68, 61, 64, 60, 57, 53, 61, 67, 38, 38, - 41, 75, 162, 107, 104, 111, 108, 124, 118, 120, 124, 131, 127, 128, 126, 107, - 84, 49, 14, 30, 16, 9, 56, 72, 79, 79, 77, 80, 76, 81, 77, 73, - 69, 67, 72, 75, 57, 57, 63, 56, 55, 56, 65, 67, 56, 51, 51, 48, - 45, 46, 44, 42, 42, 30, 41, 40, 42, 20, 4, 44, 53, 56, 59, 56, - 60, 51, 57, 61, 41, 34, 20, 79, 91, 65, 61, 41, 56, 59, 49, 48, - 51, 13, 1, 80, 80, 69, 73, 67, 77, 68, 72, 69, 73, 59, 42, 1, - 56, 65, 38, 45, 28, 32, 25, 28, 22, 16, 5, 44, 65, 63, 60, 36, - 40, 52, 52, 34, 28, 16, 48, 52, 53, 49, 49, 52, 49, 49, 52, 46, - 26, 32, 25, 80, 61, 41, 38, 42, 38, 30, 40, 34, 14, 10, 52, 38, - 52, 56, 52, 46, 38, 41, 38, 37, 14, 13, 12, 25, 34, 36, 20, 26, - 26, 33, 32, 32, 29, 10, 0, 44, 51, 48, 41, 36, 33, 32, 30, 26, - 26, 10, 10, 10, 9, 9, 9, 14, 16, 10, 28, 20, 18, 6, 5, 44, - 59, 51, 38, 33, 33, 33, 34, 34, 26, 14, 0, 45, 42, 5, 12, 9, - 16, 12, 12, 6, 5, 2, 0, 42, 60, 45, 38, 30, 44, 36, 46, 45, - 41, 38, 44, 55, 88, 67, 93, 194, 238, 236, 237, 237, 240, 189, 136, 107, - 115, 119, 118, 111, 103, 119, 124, 119, 80, 30, 20, 21, 20, 22, 30, 37, - 41, 40, 45, 40, 40, 41, 60, 85, 140, 155, 116, 115, 115, 108, 92, 38, - 34, 36, 46, 52, 41, 73, 81, 81, 81, 83, 88, 93, 95, 96, 100, 99, - 100, 102, 103, 103, 97, 96, 96, 96, 95, 99, 93, 93, 91, 89, 88, 93, - 79, 40, 34, 33, 32, 24, 28, 46, 45, 42, 29, 33, 38, 46, 53, 36, - 32, 30, 26, 28, 22, 24, 25, 36, 36, 48, 51, 55, 57, 63, 64, 64, - 55, 24, 53, 61, 77, 79, 73, 68, 55, 29, 33, 28, 17, 12, 38, 40, - 40, 42, 42, 42, 42, 46, 46, 45, 34, 29, 44, 46, 53, 32, 29, 29, - 32, 21, 13, 21, 18, 13, 12, 10, 12, 12, 12, 17, 18, 20, 21, 22, - 29, 17, 18, 18, 18, 18, 32, 33, 22, 28, 33, 56, 33, 56, 69, 56, - 52, 52, 52, 51, 51, 51, 49, 51, 49, 46, 48, 51, 55, 55, 56, 57, - 59, 59, 59, 61, 44, 18, 65, 64, 53, 46, 41, 45, 42, 40, 48, 48, - 36, 16, 44, 29, 25, 14, 13, 12, 12, 12, 12, 9, 9, 13, 17, 17, - 20, 17, 16, 17, 17, 26, 26, 36, 21, 0, 14, 51, 57, 56, 57, 61, - 67, 65, 68, 65, 68, 48, 68, 97, 106, 118, 122, 120, 123, 126, 119, 124, - 123, 124, 123, 123, 120, 119, 115, 114, 111, 108, 107, 102, 106, 95, 77, 52, - 17, 12, 12, 10, 8, 6, 6, 6, 20, 13, 10, 14, 13, 10, 6, 8, - 8, 6, 5, 8, 2, 8, 5, 29, 59, 61, 57, 64, 65, 51, 38, 57, - 21, 67, 118, 197, 216, 210, 210, 210, 216, 190, 165, 134, 127, 106, 87, 71, - 69, 46, 34, 52, 52, 46, 45, 49, 45, 32, 40, 34, 72, 173, 147, 108, - 108, 131, 123, 126, 128, 131, 140, 135, 136, 132, 110, 73, 18, 14, 10, 32, - 26, 34, 59, 57, 49, 53, 56, 53, 55, 57, 56, 57, 56, 59, 60, 61, - 61, 60, 60, 60, 61, 59, 59, 59, 57, 51, 51, 48, 46, 40, 57, 44, - 41, 32, 41, 40, 21, 4, 17, 45, 46, 25, 30, 46, 45, 36, 36, 40, - 30, 25, 59, 106, 46, 37, 45, 44, 28, 29, 36, 26, 20, 2, 65, 88, - 80, 84, 76, 80, 71, 69, 75, 71, 42, 30, 1, 59, 60, 33, 34, 24, - 20, 21, 21, 18, 12, 12, 34, 14, 18, 20, 21, 20, 20, 17, 12, 10, - 18, 16, 18, 20, 17, 17, 21, 32, 41, 41, 41, 21, 22, 14, 73, 57, - 38, 32, 36, 25, 24, 22, 20, 17, 14, 36, 18, 29, 16, 16, 33, 26, - 32, 26, 30, 28, 14, 9, 21, 26, 29, 24, 20, 17, 17, 14, 14, 13, - 9, 13, 17, 17, 8, 9, 12, 12, 9, 10, 10, 9, 10, 10, 8, 10, - 10, 10, 13, 14, 13, 14, 13, 16, 5, 0, 36, 33, 30, 28, 29, 28, - 26, 26, 26, 14, 17, 0, 37, 30, 1, 1, 0, 0, 0, 0, 1, 2, - 0, 0, 5, 9, 8, 12, 2, 102, 96, 89, 84, 80, 83, 79, 88, 67, - 76, 151, 234, 237, 237, 237, 236, 186, 135, 111, 114, 123, 112, 104, 100, 123, - 130, 124, 91, 34, 18, 20, 18, 20, 32, 37, 37, 33, 33, 28, 33, 18, - 24, 56, 77, 120, 165, 138, 116, 115, 110, 97, 37, 34, 36, 45, 48, 40, - 40, 42, 46, 48, 48, 51, 63, 110, 170, 114, 99, 100, 104, 102, 100, 95, - 95, 99, 100, 108, 108, 108, 102, 99, 103, 99, 71, 32, 28, 28, 21, 22, - 25, 22, 25, 28, 28, 29, 25, 25, 26, 24, 45, 49, 52, 55, 59, 60, - 56, 25, 75, 76, 52, 46, 45, 46, 41, 38, 44, 53, 20, 46, 29, 25, - 22, 21, 22, 16, 14, 14, 14, 16, 8, 12, 12, 9, 9, 10, 12, 12, - 12, 14, 16, 16, 32, 13, 24, 45, 48, 53, 45, 56, 64, 87, 69, 80, - 68, 89, 96, 88, 97, 96, 89, 83, 77, 63, 33, 29, 72, 106, 108, 81, - 77, 67, 51, 46, 41, 14, 12, 9, 8, 9, 9, 8, 8, 9, 9, 9, - 9, 12, 13, 13, 14, 14, 17, 20, 21, 22, 26, 29, 45, 46, 59, 45, - 21, 59, 41, 34, 25, 24, 24, 21, 24, 24, 21, 22, 17, 12, 30, 48, - 48, 52, 73, 81, 77, 85, 73, 40, 12, 53, 88, 87, 67, 46, 48, 48, - 34, 32, 12, 9, 1, 9, 9, 21, 16, 17, 17, 26, 24, 28, 28, 36, - 51, 75, 108, 171, 161, 111, 122, 140, 134, 131, 134, 132, 132, 130, 128, 127, - 126, 123, 122, 119, 114, 112, 102, 103, 92, 48, 16, 13, 10, 9, 10, 13, - 13, 16, 24, 14, 21, 42, 55, 59, 61, 64, 57, 56, 40, 36, 13, 10, - 5, 5, 20, 16, 17, 29, 30, 55, 56, 44, 46, 17, 76, 134, 204, 232, - 213, 213, 202, 151, 124, 92, 93, 85, 79, 77, 73, 28, 51, 40, 45, 42, - 34, 29, 33, 30, 32, 49, 55, 73, 181, 177, 114, 95, 112, 120, 131, 135, - 139, 144, 140, 140, 134, 112, 65, 16, 14, 13, 14, 10, 4, 4, 5, 2, - 1, 1, 2, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4, 9, 9, 10, 10, 10, 13, 14, 18, 21, 25, 36, 13, 40, 51, 48, - 32, 33, 41, 40, 25, 26, 33, 12, 2, 9, 36, 38, 33, 29, 40, 41, - 33, 29, 44, 41, 8, 1, 16, 46, 49, 14, 9, 6, 5, 6, 12, 33, - 21, 17, 29, 21, 33, 30, 36, 40, 40, 37, 29, 13, 45, 53, 60, 56, - 33, 12, 9, 13, 9, 17, 18, 30, 24, 56, 33, 32, 34, 30, 42, 51, - 44, 51, 33, 12, 49, 56, 59, 55, 30, 24, 24, 12, 16, 16, 8, 13, - 22, 20, 12, 16, 13, 13, 12, 10, 13, 8, 5, 5, 12, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 2, 1, 4, - 6, 8, 8, 4, 0, 12, 5, 8, 5, 5, 5, 8, 5, 5, 5, 6, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 1, - 0, 1, 110, 97, 99, 91, 89, 95, 89, 68, 73, 135, 222, 237, 237, 238, - 236, 187, 124, 112, 120, 127, 110, 104, 110, 126, 136, 131, 110, 44, 18, 17, - 16, 17, 26, 30, 29, 30, 32, 33, 48, 52, 68, 64, 57, 71, 111, 169, - 153, 120, 115, 116, 96, 38, 34, 34, 45, 49, 40, 48, 88, 97, 99, 92, - 97, 95, 111, 181, 153, 99, 97, 102, 96, 102, 111, 114, 127, 131, 134, 132, - 138, 135, 131, 103, 96, 36, 28, 26, 21, 20, 20, 22, 21, 20, 21, 28, - 28, 45, 60, 73, 84, 96, 100, 104, 103, 102, 93, 63, 41, 87, 92, 64, - 64, 68, 69, 61, 51, 48, 53, 20, 20, 28, 45, 48, 53, 83, 93, 103, - 72, 59, 55, 102, 100, 110, 88, 96, 83, 102, 87, 80, 87, 80, 32, 20, - 64, 104, 95, 106, 97, 81, 73, 83, 100, 79, 93, 85, 79, 68, 83, 96, - 92, 81, 84, 75, 92, 38, 28, 79, 115, 102, 100, 115, 111, 114, 118, 104, - 96, 48, 24, 85, 100, 93, 97, 96, 100, 106, 99, 97, 96, 91, 87, 85, - 92, 89, 96, 85, 84, 76, 49, 37, 38, 33, 45, 18, 24, 30, 52, 63, - 60, 65, 79, 69, 61, 52, 41, 33, 76, 100, 99, 97, 95, 97, 93, 87, - 83, 73, 41, 13, 68, 89, 89, 83, 84, 83, 83, 80, 59, 40, 33, 2, - 57, 71, 72, 63, 68, 76, 73, 71, 73, 69, 24, 44, 80, 102, 195, 170, - 120, 114, 126, 143, 143, 140, 144, 153, 153, 151, 153, 153, 144, 142, 118, 112, - 102, 118, 104, 88, 28, 16, 12, 12, 14, 14, 16, 24, 24, 25, 13, 34, - 68, 67, 79, 85, 89, 80, 79, 65, 61, 59, 46, 24, 4, 71, 75, 73, - 71, 30, 29, 24, 46, 46, 10, 85, 162, 214, 210, 218, 201, 138, 103, 93, - 85, 76, 77, 73, 80, 33, 28, 41, 49, 61, 64, 72, 57, 60, 59, 63, - 69, 93, 72, 190, 186, 150, 110, 108, 111, 131, 146, 139, 142, 146, 142, 132, - 116, 61, 16, 21, 18, 17, 10, 14, 45, 52, 51, 53, 51, 56, 45, 80, - 72, 42, 48, 92, 79, 96, 102, 97, 106, 104, 93, 108, 108, 103, 96, 77, - 80, 96, 97, 87, 87, 91, 87, 83, 55, 38, 17, 4, 46, 73, 63, 55, - 51, 38, 25, 26, 8, 17, 16, 18, 2, 1, 8, 2, 2, 0, 4, 0, - 1, 0, 2, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 2, 10, 10, 14, 20, 36, 44, 26, 22, 37, 4, 24, 61, 73, 77, 75, - 71, 75, 76, 81, 51, 29, 14, 49, 63, 65, 77, 72, 61, 60, 55, 44, - 42, 40, 52, 37, 51, 59, 48, 51, 55, 64, 63, 71, 68, 32, 10, 61, - 55, 34, 65, 60, 56, 51, 42, 32, 24, 18, 12, 13, 5, 12, 29, 24, - 40, 40, 41, 29, 25, 20, 4, 9, 20, 68, 77, 60, 65, 69, 67, 59, - 61, 40, 44, 55, 63, 67, 79, 76, 71, 26, 5, 1, 0, 5, 0, 0, - 6, 6, 2, 4, 6, 5, 2, 4, 4, 0, 0, 8, 21, 24, 29, 18, - 29, 44, 53, 38, 25, 17, 1, 16, 68, 83, 69, 71, 83, 77, 80, 80, - 87, 85, 87, 72, 83, 126, 216, 230, 238, 236, 234, 177, 122, 114, 122, 130, - 107, 107, 119, 130, 143, 139, 128, 81, 25, 18, 17, 18, 26, 30, 32, 33, - 38, 79, 79, 75, 79, 79, 67, 63, 64, 85, 166, 173, 143, 112, 107, 91, - 36, 32, 32, 44, 46, 36, 83, 107, 114, 114, 110, 96, 85, 97, 193, 177, - 120, 96, 97, 108, 116, 131, 134, 136, 142, 143, 147, 146, 140, 134, 110, 84, - 28, 24, 21, 20, 24, 30, 36, 33, 34, 34, 36, 48, 96, 107, 110, 103, - 100, 102, 95, 88, 81, 65, 60, 22, 85, 85, 71, 65, 63, 71, 72, 77, - 48, 56, 20, 71, 102, 99, 102, 99, 107, 88, 107, 81, 108, 68, 72, 91, - 93, 95, 97, 83, 80, 85, 79, 93, 95, 40, 17, 84, 100, 104, 95, 96, - 96, 97, 84, 83, 89, 83, 57, 77, 91, 100, 97, 85, 93, 96, 89, 93, - 41, 38, 93, 114, 110, 85, 103, 100, 102, 95, 100, 111, 68, 25, 110, 118, - 118, 81, 72, 69, 71, 79, 79, 72, 96, 87, 51, 65, 77, 95, 81, 84, - 80, 85, 87, 72, 42, 49, 14, 44, 85, 91, 91, 87, 92, 84, 84, 83, - 61, 42, 28, 75, 96, 83, 77, 75, 73, 73, 72, 68, 76, 46, 14, 59, - 88, 93, 83, 76, 85, 87, 83, 76, 52, 33, 9, 80, 102, 99, 76, 71, - 60, 77, 72, 65, 69, 32, 42, 79, 97, 187, 202, 150, 110, 120, 140, 142, - 154, 159, 167, 170, 166, 170, 162, 155, 148, 115, 107, 122, 118, 107, 79, 21, - 12, 10, 16, 20, 18, 21, 30, 25, 34, 17, 55, 75, 84, 77, 73, 60, - 67, 61, 71, 73, 76, 60, 29, 4, 65, 71, 84, 77, 72, 65, 68, 48, - 45, 12, 85, 175, 216, 216, 208, 150, 108, 95, 83, 89, 73, 71, 85, 85, - 28, 21, 34, 29, 36, 36, 40, 41, 44, 38, 71, 102, 83, 91, 195, 191, - 178, 110, 106, 115, 136, 148, 144, 154, 151, 142, 132, 114, 48, 18, 10, 16, - 17, 16, 29, 71, 87, 72, 67, 65, 59, 68, 64, 65, 59, 69, 81, 102, - 95, 96, 91, 92, 77, 81, 100, 115, 84, 80, 77, 64, 75, 67, 69, 65, - 69, 64, 67, 69, 65, 20, 4, 44, 79, 71, 69, 55, 56, 56, 55, 38, - 37, 25, 17, 13, 83, 84, 65, 60, 61, 52, 49, 46, 36, 16, 4, 22, - 81, 73, 61, 64, 73, 72, 73, 60, 72, 59, 14, 2, 26, 59, 56, 21, - 25, 30, 33, 38, 26, 5, 45, 92, 84, 80, 64, 63, 49, 55, 40, 46, - 30, 14, 56, 69, 71, 59, 52, 49, 48, 44, 56, 64, 57, 46, 49, 63, - 67, 69, 64, 69, 77, 73, 57, 57, 30, 12, 59, 57, 56, 37, 45, 48, - 51, 55, 53, 41, 18, 18, 12, 49, 56, 49, 55, 41, 33, 12, 28, 30, - 16, 6, 2, 51, 67, 64, 55, 59, 55, 67, 48, 56, 48, 41, 42, 42, - 57, 53, 45, 49, 51, 48, 55, 48, 46, 37, 37, 63, 68, 79, 71, 81, - 79, 71, 69, 55, 63, 60, 65, 42, 45, 46, 56, 60, 30, 45, 32, 44, - 26, 5, 53, 84, 85, 61, 42, 28, 84, 87, 88, 79, 83, 71, 81, 85, - 185, 225, 229, 233, 233, 187, 126, 112, 124, 134, 115, 107, 131, 139, 144, 140, - 138, 115, 49, 18, 17, 20, 26, 36, 32, 28, 33, 77, 88, 87, 79, 76, - 85, 85, 63, 72, 79, 146, 178, 158, 116, 103, 84, 34, 30, 30, 44, 48, - 42, 96, 119, 99, 103, 92, 93, 92, 97, 198, 182, 166, 97, 97, 112, 123, - 135, 142, 148, 144, 148, 147, 150, 144, 128, 110, 55, 28, 22, 18, 30, 33, - 36, 38, 36, 40, 42, 38, 84, 115, 114, 107, 107, 92, 93, 77, 71, 76, - 59, 59, 26, 77, 91, 77, 60, 63, 67, 68, 77, 49, 57, 21, 76, 93, - 100, 95, 111, 80, 89, 93, 69, 81, 61, 87, 103, 99, 87, 87, 79, 81, - 80, 85, 87, 87, 34, 17, 99, 96, 93, 87, 95, 97, 88, 84, 85, 77, - 71, 49, 75, 97, 107, 93, 92, 92, 89, 84, 88, 40, 29, 85, 110, 111, - 103, 100, 85, 100, 87, 100, 93, 92, 29, 96, 89, 126, 115, 115, 114, 110, - 111, 107, 102, 85, 77, 52, 92, 103, 96, 103, 92, 91, 89, 87, 83, 61, - 52, 17, 72, 96, 88, 88, 69, 75, 63, 61, 75, 73, 44, 29, 63, 80, - 87, 79, 80, 76, 75, 76, 81, 71, 46, 16, 63, 73, 92, 80, 68, 79, - 75, 88, 87, 52, 36, 0, 80, 77, 88, 88, 97, 92, 88, 95, 73, 73, - 36, 40, 83, 100, 186, 213, 191, 128, 115, 130, 144, 151, 159, 171, 174, 173, - 171, 174, 166, 153, 116, 116, 130, 120, 110, 77, 18, 12, 13, 20, 22, 33, - 33, 25, 29, 29, 17, 64, 76, 81, 72, 55, 56, 52, 64, 52, 57, 65, - 67, 28, 4, 75, 73, 76, 67, 61, 65, 55, 30, 45, 20, 80, 182, 213, - 220, 190, 111, 92, 87, 89, 75, 72, 92, 91, 75, 28, 20, 24, 45, 33, - 34, 32, 41, 33, 34, 75, 97, 92, 87, 199, 205, 191, 110, 97, 114, 122, - 139, 144, 147, 154, 146, 132, 116, 53, 17, 9, 21, 26, 10, 40, 77, 63, - 67, 64, 63, 59, 68, 63, 51, 48, 64, 95, 108, 97, 85, 83, 76, 81, - 77, 87, 91, 91, 84, 59, 75, 87, 92, 92, 99, 93, 92, 75, 63, 29, - 21, 5, 56, 75, 69, 71, 68, 65, 49, 53, 51, 45, 24, 18, 53, 84, - 68, 65, 65, 61, 71, 64, 52, 55, 18, 2, 64, 81, 55, 46, 60, 65, - 56, 59, 65, 52, 53, 20, 2, 45, 49, 33, 20, 32, 18, 29, 40, 18, - 5, 34, 91, 69, 65, 40, 38, 37, 41, 42, 77, 29, 16, 46, 59, 45, - 69, 80, 61, 51, 56, 40, 45, 42, 26, 57, 68, 81, 81, 79, 91, 71, - 73, 37, 68, 34, 13, 56, 52, 55, 42, 30, 28, 32, 38, 32, 53, 25, - 18, 2, 56, 56, 56, 53, 29, 40, 26, 26, 29, 30, 5, 4, 67, 64, - 29, 40, 34, 42, 52, 59, 60, 48, 59, 16, 51, 41, 55, 45, 44, 44, - 33, 28, 41, 57, 14, 69, 77, 69, 69, 72, 64, 55, 64, 68, 67, 63, - 24, 26, 53, 79, 60, 60, 51, 37, 17, 48, 49, 33, 4, 63, 83, 61, - 55, 25, 10, 75, 75, 76, 97, 67, 83, 81, 127, 222, 225, 230, 234, 209, - 143, 116, 120, 132, 130, 107, 124, 146, 151, 147, 142, 132, 85, 25, 17, 16, - 22, 26, 38, 33, 17, 34, 81, 81, 87, 77, 71, 73, 71, 72, 67, 77, - 116, 183, 173, 122, 106, 79, 34, 30, 30, 44, 49, 42, 77, 114, 100, 102, - 97, 93, 102, 104, 202, 194, 178, 92, 99, 112, 131, 139, 150, 147, 157, 148, - 144, 148, 139, 127, 112, 33, 24, 21, 18, 32, 42, 42, 37, 41, 42, 38, - 53, 103, 112, 114, 106, 89, 87, 83, 80, 72, 69, 65, 55, 25, 76, 81, - 84, 77, 73, 68, 60, 61, 48, 55, 17, 84, 92, 111, 81, 79, 79, 76, - 83, 83, 80, 59, 83, 103, 95, 89, 89, 100, 92, 92, 84, 76, 81, 37, - 20, 77, 100, 84, 102, 85, 69, 91, 84, 80, 80, 71, 48, 76, 89, 107, - 89, 106, 95, 85, 93, 84, 44, 26, 85, 106, 103, 96, 96, 95, 84, 83, - 89, 93, 103, 33, 65, 110, 84, 107, 116, 100, 112, 106, 96, 107, 91, 67, - 51, 95, 100, 85, 75, 73, 65, 83, 88, 81, 75, 52, 22, 84, 88, 89, - 92, 68, 59, 60, 67, 71, 60, 40, 16, 72, 85, 75, 85, 81, 76, 83, - 80, 77, 60, 48, 22, 56, 77, 88, 84, 84, 65, 80, 75, 81, 48, 32, - 0, 80, 87, 83, 84, 92, 77, 103, 100, 104, 85, 41, 41, 81, 100, 183, - 205, 189, 130, 114, 127, 140, 144, 155, 171, 177, 178, 178, 170, 166, 148, 118, - 128, 132, 124, 116, 63, 17, 12, 16, 24, 33, 29, 25, 25, 30, 36, 20, - 68, 83, 80, 56, 64, 71, 67, 60, 56, 59, 61, 51, 28, 4, 75, 57, - 80, 72, 73, 65, 51, 32, 42, 14, 85, 178, 209, 216, 167, 102, 92, 83, - 85, 76, 77, 100, 93, 77, 26, 17, 16, 25, 36, 38, 29, 34, 32, 22, - 71, 97, 76, 93, 199, 193, 197, 108, 97, 104, 115, 130, 138, 153, 158, 150, - 134, 110, 49, 20, 8, 13, 26, 12, 40, 77, 80, 61, 53, 45, 48, 41, - 48, 44, 41, 14, 89, 104, 92, 80, 76, 76, 87, 91, 92, 79, 96, 83, - 57, 79, 89, 100, 91, 81, 71, 60, 76, 69, 67, 24, 6, 52, 55, 75, - 55, 49, 44, 44, 46, 56, 71, 26, 16, 68, 84, 46, 56, 41, 63, 68, - 72, 59, 55, 21, 2, 72, 80, 59, 49, 64, 77, 75, 72, 73, 59, 61, - 20, 2, 51, 41, 18, 20, 37, 20, 20, 28, 22, 4, 37, 75, 72, 40, - 57, 60, 38, 41, 46, 42, 45, 12, 40, 61, 48, 69, 51, 36, 44, 36, - 51, 49, 42, 30, 72, 60, 56, 49, 60, 71, 81, 60, 60, 52, 33, 14, - 52, 51, 67, 52, 37, 40, 36, 40, 40, 51, 44, 17, 22, 41, 65, 56, - 37, 34, 52, 26, 37, 22, 20, 5, 6, 28, 63, 59, 33, 33, 30, 29, - 20, 30, 25, 18, 13, 59, 49, 57, 36, 32, 29, 25, 26, 29, 57, 18, - 71, 73, 69, 52, 55, 42, 44, 49, 44, 42, 30, 25, 26, 55, 48, 42, - 37, 26, 16, 29, 30, 38, 40, 2, 25, 85, 55, 56, 13, 0, 110, 104, - 102, 76, 73, 83, 93, 178, 221, 234, 228, 220, 158, 126, 116, 131, 135, 120, - 112, 144, 155, 155, 147, 140, 120, 55, 18, 14, 18, 24, 32, 38, 33, 18, - 71, 91, 84, 77, 71, 76, 80, 69, 65, 65, 69, 111, 189, 181, 154, 104, - 75, 34, 28, 28, 40, 49, 42, 64, 118, 102, 97, 100, 92, 89, 95, 209, - 199, 178, 93, 103, 114, 126, 140, 148, 150, 150, 147, 148, 148, 136, 118, 112, - 30, 20, 18, 32, 38, 44, 42, 46, 41, 42, 37, 52, 106, 107, 110, 89, - 83, 84, 83, 77, 73, 68, 60, 67, 37, 83, 79, 68, 71, 69, 80, 57, - 71, 46, 55, 16, 77, 87, 92, 68, 84, 69, 89, 61, 80, 75, 51, 83, - 103, 89, 93, 91, 92, 99, 88, 88, 93, 75, 36, 18, 81, 93, 88, 102, - 93, 95, 85, 91, 76, 84, 69, 49, 75, 89, 92, 92, 107, 91, 79, 89, - 77, 49, 25, 87, 111, 111, 106, 93, 91, 89, 88, 87, 89, 103, 44, 37, - 108, 116, 119, 112, 108, 106, 104, 104, 115, 97, 75, 51, 89, 104, 83, 81, - 95, 73, 73, 73, 84, 65, 53, 20, 76, 104, 77, 83, 65, 60, 75, 60, - 64, 64, 41, 17, 60, 76, 77, 95, 76, 73, 72, 67, 64, 68, 51, 24, - 57, 85, 88, 89, 71, 75, 73, 79, 77, 49, 36, 4, 87, 76, 75, 93, - 95, 77, 91, 103, 107, 80, 34, 46, 83, 88, 148, 213, 195, 134, 110, 122, - 140, 144, 155, 167, 166, 169, 173, 174, 165, 130, 114, 131, 136, 126, 116, 44, - 14, 10, 20, 25, 33, 26, 25, 29, 32, 29, 25, 68, 81, 67, 65, 57, - 61, 53, 61, 65, 53, 60, 51, 26, 4, 55, 80, 73, 69, 65, 65, 44, - 33, 44, 16, 92, 193, 208, 208, 138, 103, 85, 91, 77, 71, 91, 93, 96, - 77, 25, 17, 21, 20, 38, 42, 38, 33, 36, 26, 63, 97, 92, 97, 201, - 205, 201, 106, 93, 102, 119, 123, 131, 151, 157, 151, 135, 106, 51, 21, 12, - 17, 17, 13, 33, 69, 68, 60, 46, 63, 56, 56, 56, 45, 38, 46, 102, - 106, 96, 81, 93, 83, 89, 89, 77, 75, 91, 75, 60, 80, 95, 92, 80, - 73, 69, 69, 75, 69, 64, 22, 6, 51, 72, 64, 45, 48, 48, 51, 42, - 56, 49, 25, 16, 36, 79, 44, 53, 57, 68, 57, 73, 63, 45, 22, 4, - 34, 80, 49, 60, 49, 60, 55, 53, 51, 48, 56, 17, 5, 44, 32, 24, - 25, 38, 18, 20, 21, 17, 5, 38, 79, 68, 52, 68, 79, 63, 41, 44, - 52, 29, 13, 36, 72, 48, 65, 51, 30, 41, 61, 45, 56, 41, 24, 75, - 67, 64, 61, 79, 75, 60, 32, 59, 55, 33, 14, 52, 46, 67, 73, 63, - 56, 51, 55, 44, 38, 24, 20, 22, 49, 67, 42, 41, 28, 42, 30, 49, - 20, 17, 4, 5, 28, 68, 60, 36, 26, 26, 26, 29, 29, 24, 20, 14, - 56, 30, 49, 46, 37, 32, 21, 24, 38, 33, 8, 52, 72, 63, 46, 40, - 34, 37, 42, 28, 49, 32, 17, 26, 59, 51, 57, 41, 37, 9, 33, 33, - 36, 24, 4, 26, 67, 55, 24, 1, 0, 108, 83, 92, 67, 81, 84, 127, - 210, 222, 225, 225, 181, 120, 120, 128, 135, 131, 108, 126, 151, 158, 154, 146, - 135, 99, 28, 16, 14, 20, 28, 29, 37, 34, 18, 80, 87, 81, 75, 75, - 79, 83, 73, 68, 71, 68, 93, 187, 183, 162, 104, 76, 30, 26, 29, 41, - 48, 44, 55, 112, 103, 99, 100, 95, 97, 91, 210, 199, 169, 99, 99, 111, - 124, 136, 136, 148, 146, 148, 148, 144, 131, 115, 114, 29, 18, 17, 32, 45, - 38, 40, 46, 49, 45, 40, 51, 107, 112, 107, 84, 77, 84, 71, 75, 80, - 68, 61, 63, 26, 80, 75, 85, 91, 85, 84, 57, 64, 45, 56, 20, 75, - 89, 106, 81, 79, 76, 65, 71, 76, 77, 52, 88, 97, 84, 92, 92, 99, - 83, 80, 83, 84, 75, 41, 17, 73, 89, 81, 102, 104, 100, 88, 85, 77, - 79, 68, 45, 76, 83, 85, 87, 102, 107, 103, 102, 77, 41, 26, 77, 108, - 108, 103, 91, 87, 85, 97, 83, 91, 99, 75, 37, 96, 112, 106, 102, 88, - 100, 108, 114, 92, 87, 67, 52, 91, 104, 73, 79, 83, 76, 76, 93, 83, - 60, 55, 22, 69, 85, 88, 81, 68, 57, 55, 73, 72, 59, 41, 22, 75, - 80, 81, 103, 85, 80, 65, 76, 83, 72, 64, 25, 59, 88, 73, 69, 72, - 65, 60, 68, 80, 51, 36, 4, 75, 77, 72, 79, 80, 83, 65, 88, 81, - 61, 48, 45, 68, 99, 136, 212, 212, 154, 107, 111, 138, 144, 157, 167, 173, - 178, 173, 165, 161, 123, 127, 139, 134, 127, 115, 25, 13, 10, 21, 30, 29, - 25, 29, 34, 34, 33, 25, 68, 79, 75, 68, 72, 53, 71, 60, 65, 53, - 59, 56, 28, 4, 71, 55, 68, 97, 65, 64, 60, 34, 41, 13, 84, 181, - 205, 205, 126, 89, 81, 81, 72, 77, 95, 95, 97, 91, 22, 17, 12, 17, - 36, 44, 36, 29, 36, 29, 71, 106, 81, 104, 205, 206, 201, 106, 100, 106, - 108, 123, 135, 147, 158, 153, 138, 119, 46, 20, 17, 14, 18, 16, 33, 65, - 64, 55, 42, 67, 36, 52, 69, 41, 42, 48, 103, 97, 83, 69, 84, 87, - 96, 75, 68, 75, 91, 67, 57, 75, 100, 83, 71, 73, 59, 65, 56, 77, - 79, 24, 6, 49, 64, 72, 41, 46, 51, 38, 45, 40, 46, 25, 14, 53, - 75, 34, 49, 53, 56, 73, 75, 51, 53, 22, 4, 32, 76, 49, 46, 46, - 48, 44, 45, 69, 53, 53, 18, 4, 56, 34, 21, 26, 38, 20, 17, 17, - 13, 5, 55, 81, 64, 73, 83, 85, 69, 51, 49, 49, 29, 16, 34, 76, - 57, 60, 51, 29, 32, 42, 34, 53, 46, 17, 79, 59, 64, 53, 67, 56, - 37, 32, 65, 46, 32, 16, 52, 46, 64, 40, 45, 49, 46, 49, 48, 36, - 25, 18, 6, 40, 67, 60, 26, 24, 41, 25, 38, 41, 32, 5, 4, 22, - 67, 56, 26, 32, 18, 24, 22, 25, 17, 17, 10, 51, 63, 36, 34, 32, - 44, 30, 22, 33, 41, 14, 53, 60, 55, 41, 22, 22, 34, 52, 37, 37, - 18, 22, 34, 53, 63, 32, 18, 24, 18, 33, 18, 42, 25, 6, 34, 57, - 41, 29, 0, 0, 127, 92, 73, 65, 83, 88, 174, 214, 226, 220, 208, 154, - 115, 116, 134, 138, 131, 114, 142, 158, 158, 153, 146, 132, 76, 20, 13, 14, - 24, 29, 36, 34, 34, 21, 87, 85, 84, 71, 80, 85, 77, 69, 72, 76, - 71, 99, 185, 186, 170, 108, 77, 34, 26, 29, 45, 51, 45, 42, 108, 107, - 97, 107, 97, 99, 96, 212, 194, 178, 103, 102, 112, 124, 132, 136, 144, 148, - 148, 148, 135, 130, 112, 111, 30, 17, 16, 33, 48, 46, 42, 40, 48, 45, - 37, 64, 102, 115, 92, 91, 80, 83, 81, 81, 75, 76, 59, 59, 26, 85, - 76, 71, 72, 75, 80, 56, 63, 46, 52, 18, 75, 88, 95, 71, 76, 71, - 76, 64, 63, 73, 53, 81, 95, 99, 93, 97, 81, 84, 87, 85, 83, 72, - 37, 16, 69, 89, 80, 77, 92, 92, 84, 85, 80, 77, 64, 38, 71, 88, - 99, 89, 103, 89, 87, 77, 87, 37, 28, 68, 108, 103, 97, 88, 91, 93, - 85, 83, 89, 95, 69, 30, 72, 110, 115, 91, 102, 107, 104, 92, 96, 81, - 61, 59, 91, 100, 71, 77, 87, 76, 75, 63, 75, 76, 55, 25, 73, 85, - 84, 88, 80, 59, 59, 56, 68, 67, 42, 26, 72, 88, 71, 76, 84, 68, - 79, 81, 80, 72, 56, 26, 59, 73, 83, 68, 67, 64, 73, 72, 69, 53, - 37, 0, 93, 81, 69, 57, 83, 77, 89, 85, 80, 71, 42, 37, 67, 99, - 87, 213, 217, 181, 110, 110, 132, 143, 154, 165, 170, 170, 169, 171, 150, 124, - 132, 143, 135, 127, 115, 21, 13, 12, 20, 33, 30, 29, 36, 41, 34, 30, - 25, 57, 79, 72, 76, 53, 68, 61, 60, 67, 52, 56, 56, 28, 4, 67, - 65, 69, 67, 93, 81, 68, 34, 41, 12, 75, 170, 195, 228, 142, 92, 75, - 83, 71, 89, 96, 96, 102, 76, 22, 17, 10, 22, 30, 40, 38, 29, 33, - 25, 75, 92, 88, 115, 210, 213, 199, 97, 92, 103, 115, 122, 138, 146, 159, - 154, 139, 130, 48, 25, 8, 17, 22, 17, 28, 67, 63, 56, 61, 52, 48, - 52, 44, 53, 33, 40, 92, 95, 92, 83, 88, 69, 65, 79, 72, 83, 85, - 56, 60, 81, 97, 79, 65, 69, 65, 61, 77, 68, 61, 25, 9, 51, 61, - 61, 36, 57, 37, 48, 44, 46, 38, 26, 14, 55, 83, 36, 44, 59, 59, - 63, 65, 44, 55, 24, 4, 34, 75, 55, 57, 55, 48, 55, 73, 42, 46, - 49, 17, 4, 42, 29, 24, 30, 36, 32, 16, 13, 9, 6, 46, 76, 53, - 75, 73, 72, 67, 79, 73, 51, 25, 13, 44, 69, 37, 65, 44, 32, 36, - 44, 45, 56, 42, 18, 69, 68, 77, 55, 57, 52, 44, 29, 28, 42, 29, - 14, 33, 42, 61, 55, 52, 51, 41, 51, 46, 49, 22, 18, 4, 40, 76, - 56, 46, 22, 38, 32, 36, 20, 24, 4, 4, 22, 64, 59, 38, 40, 24, - 22, 22, 21, 22, 34, 10, 40, 44, 17, 26, 25, 20, 28, 26, 28, 41, - 24, 60, 71, 68, 53, 16, 44, 38, 42, 32, 40, 28, 20, 38, 46, 26, - 51, 24, 12, 22, 21, 21, 16, 9, 4, 34, 52, 46, 18, 0, 0, 77, - 104, 73, 76, 84, 114, 199, 221, 214, 217, 170, 128, 115, 131, 135, 138, 120, - 126, 155, 159, 157, 151, 142, 124, 40, 16, 12, 17, 24, 34, 37, 42, 36, - 20, 95, 84, 79, 73, 87, 77, 75, 72, 73, 69, 65, 120, 183, 182, 178, - 106, 73, 33, 28, 29, 44, 48, 44, 40, 107, 106, 102, 108, 103, 96, 93, - 217, 191, 189, 104, 100, 111, 120, 131, 138, 142, 144, 148, 143, 135, 128, 111, - 110, 26, 16, 16, 33, 53, 44, 46, 44, 55, 46, 37, 67, 107, 114, 91, - 83, 88, 91, 81, 81, 84, 72, 57, 57, 26, 77, 81, 75, 73, 59, 63, - 67, 60, 48, 51, 17, 73, 93, 104, 77, 79, 81, 60, 77, 67, 73, 49, - 87, 97, 95, 85, 84, 92, 91, 91, 88, 83, 46, 44, 18, 65, 81, 85, - 81, 83, 85, 80, 79, 84, 76, 68, 34, 83, 87, 95, 92, 95, 96, 91, - 97, 85, 37, 28, 64, 95, 102, 93, 77, 95, 95, 77, 87, 87, 83, 76, - 38, 71, 107, 116, 110, 88, 96, 80, 92, 88, 79, 42, 68, 83, 99, 81, - 83, 67, 61, 67, 59, 65, 76, 55, 29, 49, 75, 93, 65, 56, 65, 71, - 61, 65, 51, 42, 10, 67, 80, 76, 69, 71, 60, 72, 80, 72, 67, 57, - 32, 36, 67, 79, 83, 85, 83, 81, 84, 69, 46, 33, 0, 79, 72, 68, - 69, 72, 88, 87, 84, 59, 87, 48, 51, 42, 96, 80, 218, 221, 213, 111, - 108, 131, 147, 150, 154, 170, 171, 170, 170, 140, 128, 147, 146, 135, 126, 115, - 22, 13, 9, 24, 38, 29, 32, 36, 45, 38, 36, 28, 48, 76, 71, 69, - 68, 71, 71, 65, 63, 60, 56, 60, 26, 5, 63, 57, 53, 67, 103, 71, - 63, 34, 37, 8, 57, 114, 182, 228, 147, 88, 84, 87, 88, 96, 92, 99, - 92, 48, 21, 18, 12, 21, 32, 40, 38, 36, 29, 17, 68, 89, 83, 108, - 210, 204, 202, 102, 95, 106, 119, 128, 138, 146, 158, 155, 148, 135, 49, 24, - 6, 12, 20, 14, 17, 59, 56, 63, 57, 55, 57, 51, 44, 49, 33, 9, - 93, 96, 76, 65, 71, 76, 79, 79, 80, 85, 88, 56, 63, 88, 77, 61, - 84, 61, 57, 63, 64, 68, 60, 28, 9, 41, 65, 69, 42, 40, 44, 42, - 41, 53, 55, 29, 12, 68, 75, 42, 52, 59, 56, 57, 59, 42, 41, 29, - 2, 37, 64, 55, 52, 49, 72, 72, 48, 41, 40, 53, 16, 4, 57, 33, - 21, 18, 17, 34, 13, 13, 9, 6, 38, 71, 64, 67, 65, 81, 63, 59, - 55, 46, 33, 12, 41, 71, 59, 59, 34, 32, 42, 44, 37, 61, 44, 21, - 67, 59, 79, 45, 45, 72, 38, 28, 36, 25, 33, 14, 24, 49, 37, 51, - 75, 63, 46, 45, 55, 45, 25, 17, 28, 40, 76, 44, 28, 33, 36, 22, - 10, 10, 9, 5, 5, 17, 37, 53, 34, 29, 33, 29, 25, 22, 24, 12, - 9, 25, 24, 22, 21, 25, 21, 33, 26, 30, 14, 17, 65, 68, 65, 60, - 24, 45, 26, 25, 48, 20, 28, 22, 44, 29, 17, 18, 10, 21, 5, 6, - 2, 16, 5, 5, 20, 51, 10, 12, 2, 0, 104, 79, 64, 83, 88, 138, - 198, 218, 212, 204, 135, 131, 127, 132, 138, 138, 114, 144, 162, 161, 158, 150, - 140, 116, 32, 16, 13, 18, 24, 30, 26, 37, 36, 18, 88, 80, 80, 81, - 73, 73, 72, 68, 69, 77, 65, 130, 183, 183, 166, 102, 68, 33, 26, 28, - 46, 55, 49, 46, 95, 116, 95, 102, 102, 92, 89, 220, 193, 198, 104, 100, - 111, 122, 130, 140, 144, 146, 146, 131, 132, 130, 115, 115, 25, 14, 13, 36, - 49, 40, 45, 41, 60, 46, 36, 68, 100, 100, 87, 56, 57, 75, 79, 61, - 61, 65, 63, 67, 40, 89, 80, 75, 60, 65, 57, 65, 56, 45, 48, 14, - 73, 81, 95, 67, 77, 80, 72, 79, 79, 69, 40, 81, 97, 106, 102, 102, - 95, 83, 73, 81, 59, 46, 41, 18, 52, 71, 75, 55, 65, 84, 75, 59, - 65, 73, 60, 36, 69, 80, 95, 97, 80, 71, 68, 67, 53, 45, 25, 59, - 103, 106, 100, 96, 87, 85, 84, 87, 80, 84, 83, 42, 56, 102, 112, 104, - 81, 103, 97, 88, 83, 75, 42, 56, 81, 99, 83, 77, 64, 65, 55, 60, - 61, 64, 56, 26, 48, 56, 55, 55, 55, 53, 57, 57, 64, 64, 41, 12, - 64, 80, 81, 71, 71, 68, 61, 68, 59, 59, 56, 34, 42, 60, 84, 83, - 92, 81, 73, 79, 46, 48, 38, 2, 80, 73, 65, 69, 56, 75, 79, 81, - 69, 77, 34, 46, 33, 89, 85, 221, 226, 214, 111, 106, 131, 146, 150, 153, - 163, 170, 167, 158, 128, 140, 146, 146, 139, 132, 118, 18, 13, 10, 21, 33, - 30, 32, 33, 41, 45, 37, 32, 37, 73, 77, 77, 63, 67, 69, 63, 63, - 59, 52, 48, 26, 6, 55, 59, 69, 67, 61, 57, 51, 45, 40, 8, 41, - 83, 139, 136, 95, 85, 73, 63, 79, 77, 83, 79, 45, 22, 20, 17, 14, - 17, 33, 37, 37, 34, 32, 18, 73, 88, 73, 69, 204, 216, 213, 104, 93, - 106, 120, 130, 139, 147, 161, 155, 135, 124, 46, 24, 9, 12, 20, 16, 16, - 42, 59, 55, 57, 55, 56, 53, 45, 53, 30, 29, 96, 91, 67, 73, 89, - 91, 85, 89, 87, 89, 83, 55, 69, 97, 75, 76, 77, 63, 65, 75, 67, - 64, 55, 28, 8, 48, 61, 65, 41, 36, 38, 34, 52, 57, 48, 28, 13, - 44, 71, 40, 33, 37, 38, 40, 38, 42, 49, 32, 5, 37, 36, 76, 69, - 72, 75, 76, 41, 49, 45, 49, 20, 6, 42, 22, 20, 14, 22, 20, 30, - 16, 12, 5, 33, 68, 63, 64, 81, 53, 57, 51, 42, 46, 28, 14, 41, - 68, 44, 38, 42, 67, 46, 63, 53, 48, 38, 20, 59, 57, 56, 57, 59, - 52, 49, 44, 30, 42, 37, 18, 21, 36, 48, 40, 28, 24, 24, 34, 29, - 26, 24, 18, 29, 60, 76, 46, 20, 4, 4, 14, 13, 2, 4, 9, 6, - 9, 24, 29, 26, 18, 20, 16, 16, 17, 21, 18, 17, 25, 25, 38, 25, - 29, 18, 18, 21, 24, 17, 22, 37, 60, 71, 45, 25, 21, 20, 22, 17, - 13, 14, 18, 20, 18, 18, 20, 18, 10, 32, 28, 33, 26, 13, 24, 26, - 34, 34, 28, 16, 10, 77, 79, 57, 80, 91, 147, 201, 212, 213, 151, 134, - 122, 132, 136, 142, 135, 119, 154, 165, 162, 157, 148, 136, 103, 25, 14, 12, - 17, 22, 34, 36, 44, 34, 22, 89, 79, 73, 80, 72, 69, 67, 68, 71, - 67, 69, 140, 178, 178, 163, 104, 65, 33, 28, 29, 46, 52, 49, 41, 83, - 114, 107, 91, 102, 93, 88, 220, 199, 206, 106, 103, 111, 124, 138, 136, 140, - 139, 132, 124, 130, 127, 116, 116, 22, 14, 12, 36, 44, 45, 40, 41, 38, - 56, 56, 61, 71, 73, 67, 63, 67, 61, 63, 65, 85, 76, 64, 57, 28, - 73, 80, 60, 53, 57, 56, 53, 51, 56, 53, 21, 73, 91, 87, 67, 64, - 63, 57, 67, 65, 64, 45, 63, 80, 96, 63, 68, 59, 57, 51, 44, 36, - 32, 45, 40, 44, 45, 44, 55, 40, 42, 41, 41, 42, 40, 34, 30, 51, - 51, 53, 46, 40, 40, 44, 42, 36, 36, 49, 51, 83, 93, 87, 72, 81, - 85, 88, 75, 75, 88, 81, 72, 52, 60, 100, 91, 69, 80, 80, 81, 80, - 68, 46, 52, 75, 76, 61, 60, 61, 68, 68, 59, 56, 57, 53, 52, 45, - 53, 53, 53, 45, 51, 44, 61, 53, 59, 42, 21, 69, 64, 65, 63, 61, - 60, 60, 60, 56, 56, 46, 53, 29, 33, 36, 40, 37, 40, 38, 38, 38, - 44, 37, 2, 28, 77, 72, 34, 49, 65, 69, 61, 56, 69, 61, 51, 38, - 60, 64, 212, 228, 217, 106, 103, 126, 140, 144, 144, 150, 162, 163, 158, 135, - 151, 151, 150, 142, 132, 118, 17, 12, 12, 18, 29, 33, 38, 37, 34, 36, - 40, 38, 30, 36, 53, 63, 57, 57, 55, 57, 59, 59, 52, 53, 28, 6, - 51, 63, 64, 49, 52, 42, 41, 41, 40, 16, 28, 41, 64, 83, 59, 29, - 20, 16, 14, 16, 16, 16, 16, 18, 17, 10, 10, 14, 34, 34, 36, 26, - 32, 20, 67, 75, 91, 69, 185, 214, 210, 102, 95, 110, 123, 134, 139, 148, - 161, 155, 136, 123, 42, 26, 25, 10, 20, 18, 16, 20, 36, 42, 41, 52, - 44, 53, 45, 42, 37, 38, 93, 83, 87, 84, 79, 80, 75, 76, 81, 77, - 63, 53, 57, 79, 87, 85, 77, 81, 75, 67, 42, 38, 37, 26, 9, 38, - 48, 55, 64, 75, 53, 63, 52, 40, 25, 30, 12, 42, 64, 63, 55, 53, - 51, 49, 42, 45, 40, 33, 5, 28, 21, 22, 28, 38, 41, 25, 28, 41, - 21, 25, 18, 6, 44, 22, 28, 26, 26, 20, 18, 18, 10, 10, 33, 29, - 24, 29, 20, 38, 46, 52, 46, 38, 25, 17, 21, 48, 38, 48, 34, 41, - 40, 45, 38, 33, 40, 12, 42, 55, 53, 34, 38, 42, 42, 33, 33, 36, - 32, 25, 30, 30, 28, 22, 24, 24, 22, 29, 22, 21, 20, 17, 2, 55, - 1, 22, 1, 20, 2, 4, 17, 16, 4, 5, 10, 10, 9, 8, 9, 9, - 9, 9, 12, 12, 10, 13, 10, 14, 18, 13, 20, 14, 13, 12, 14, 16, - 17, 14, 28, 41, 22, 37, 17, 21, 60, 65, 60, 29, 51, 48, 18, 17, - 12, 14, 18, 16, 17, 13, 9, 8, 12, 16, 37, 16, 14, 53, 57, 68, - 52, 53, 56, 83, 88, 165, 213, 157, 151, 144, 112, 142, 131, 138, 139, 131, - 131, 161, 165, 161, 155, 147, 132, 87, 20, 14, 13, 20, 26, 36, 36, 37, - 34, 13, 84, 79, 69, 69, 55, 61, 67, 60, 72, 69, 68, 154, 182, 177, - 163, 97, 61, 33, 29, 30, 48, 51, 56, 52, 59, 85, 106, 99, 97, 91, - 87, 218, 212, 214, 107, 102, 108, 123, 124, 124, 127, 126, 131, 134, 132, 131, - 122, 119, 21, 13, 13, 32, 36, 38, 44, 45, 41, 46, 44, 46, 55, 52, - 48, 53, 53, 53, 56, 55, 56, 57, 57, 56, 53, 59, 56, 55, 53, 53, - 55, 55, 51, 51, 45, 22, 67, 91, 60, 53, 49, 49, 52, 49, 48, 49, - 41, 48, 49, 46, 46, 44, 41, 40, 41, 38, 37, 33, 28, 18, 18, 17, - 18, 17, 14, 14, 14, 12, 13, 10, 10, 12, 10, 16, 17, 17, 13, 14, - 21, 32, 28, 30, 28, 41, 61, 60, 71, 80, 69, 65, 71, 73, 72, 71, - 72, 61, 56, 64, 57, 53, 46, 38, 38, 38, 45, 40, 32, 38, 41, 49, - 42, 42, 61, 60, 59, 42, 42, 36, 32, 38, 48, 53, 53, 53, 40, 32, - 34, 44, 48, 46, 41, 18, 34, 37, 32, 38, 37, 38, 37, 40, 40, 40, - 42, 44, 42, 48, 32, 33, 28, 18, 14, 13, 17, 20, 16, 0, 13, 14, - 21, 18, 21, 25, 29, 30, 38, 46, 65, 53, 51, 51, 76, 210, 229, 218, - 106, 100, 107, 118, 134, 143, 153, 150, 155, 151, 136, 153, 151, 148, 140, 128, - 116, 16, 12, 9, 14, 17, 25, 24, 28, 32, 33, 34, 30, 32, 41, 42, - 44, 41, 44, 44, 45, 44, 48, 49, 44, 26, 6, 56, 60, 41, 30, 32, - 28, 22, 33, 33, 17, 14, 16, 25, 20, 17, 16, 14, 13, 13, 17, 18, - 13, 14, 14, 16, 17, 18, 18, 18, 20, 20, 21, 29, 18, 29, 34, 41, - 73, 171, 217, 208, 103, 99, 110, 119, 132, 142, 150, 163, 154, 135, 120, 41, - 29, 8, 14, 14, 17, 16, 20, 20, 20, 18, 18, 18, 21, 20, 18, 30, - 25, 33, 67, 67, 53, 53, 60, 63, 53, 52, 53, 51, 45, 48, 46, 48, - 49, 57, 42, 44, 34, 32, 24, 36, 26, 29, 29, 29, 14, 29, 34, 22, - 30, 22, 21, 37, 28, 29, 28, 32, 29, 26, 25, 22, 22, 21, 36, 28, - 26, 2, 6, 6, 10, 10, 9, 10, 13, 10, 12, 18, 29, 18, 10, 18, - 17, 12, 16, 18, 14, 14, 34, 17, 22, 17, 21, 26, 22, 20, 18, 20, - 25, 22, 21, 21, 24, 21, 22, 22, 24, 22, 24, 22, 25, 24, 24, 20, - 13, 16, 25, 17, 17, 16, 25, 16, 17, 17, 20, 21, 16, 14, 17, 16, - 16, 16, 14, 14, 14, 14, 13, 12, 12, 1, 32, 32, 32, 29, 45, 41, - 41, 41, 46, 48, 49, 49, 59, 63, 67, 71, 81, 107, 127, 148, 162, 170, - 226, 224, 221, 208, 202, 202, 198, 202, 187, 185, 175, 158, 73, 26, 21, 17, - 18, 14, 68, 60, 153, 183, 162, 159, 158, 97, 80, 81, 59, 48, 46, 55, - 85, 110, 143, 161, 153, 115, 75, 42, 13, 8, 6, 87, 80, 83, 99, 107, - 179, 120, 139, 111, 112, 111, 128, 127, 138, 144, 138, 138, 165, 167, 158, 151, - 139, 126, 45, 17, 12, 14, 24, 28, 20, 32, 32, 28, 18, 40, 48, 45, - 46, 46, 46, 48, 49, 73, 63, 51, 136, 174, 175, 162, 97, 55, 32, 28, - 33, 46, 48, 49, 51, 55, 60, 57, 61, 64, 96, 72, 222, 217, 217, 106, - 99, 107, 122, 116, 116, 115, 118, 120, 132, 131, 134, 122, 116, 18, 10, 10, - 20, 18, 21, 22, 22, 18, 21, 26, 29, 34, 44, 44, 46, 49, 49, 48, - 53, 57, 60, 64, 57, 52, 64, 71, 60, 72, 79, 89, 123, 107, 52, 49, - 57, 51, 46, 45, 44, 42, 52, 44, 42, 33, 29, 30, 32, 26, 37, 34, - 36, 34, 40, 30, 36, 32, 61, 81, 108, 110, 106, 115, 102, 107, 97, 111, - 108, 93, 73, 77, 75, 80, 95, 95, 81, 72, 57, 41, 30, 26, 20, 16, - 14, 13, 12, 10, 10, 12, 13, 10, 12, 14, 14, 13, 13, 18, 24, 72, - 77, 83, 88, 93, 89, 61, 61, 40, 96, 95, 107, 81, 41, 38, 55, 33, - 34, 72, 79, 96, 84, 89, 97, 103, 99, 87, 67, 53, 44, 29, 30, 40, - 20, 10, 9, 9, 10, 8, 8, 9, 9, 6, 8, 8, 8, 8, 12, 29, - 34, 57, 72, 67, 68, 59, 33, 29, 0, 57, 91, 79, 60, 81, 60, 67, - 68, 49, 38, 37, 41, 42, 46, 65, 199, 216, 206, 95, 91, 102, 103, 97, - 111, 128, 143, 150, 155, 132, 147, 154, 150, 138, 131, 115, 14, 10, 9, 8, - 8, 8, 8, 8, 8, 8, 13, 12, 8, 9, 10, 21, 22, 25, 12, 13, - 13, 22, 14, 30, 10, 6, 61, 24, 18, 18, 20, 17, 21, 14, 13, 13, - 13, 16, 14, 12, 17, 16, 9, 9, 10, 10, 10, 12, 10, 10, 10, 10, - 12, 13, 18, 26, 30, 33, 30, 13, 61, 80, 79, 71, 171, 204, 193, 106, - 99, 111, 123, 131, 139, 153, 162, 155, 134, 104, 37, 32, 6, 12, 9, 12, - 4, 4, 4, 2, 2, 4, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, - 4, 4, 4, 5, 6, 6, 8, 8, 10, 10, 13, 13, 13, 17, 18, 18, - 24, 48, 53, 45, 38, 44, 30, 28, 26, 25, 22, 24, 29, 36, 60, 67, - 77, 69, 64, 60, 57, 63, 67, 57, 46, 26, 29, 34, 14, 32, 75, 83, - 59, 51, 57, 32, 22, 16, 17, 13, 14, 12, 18, 29, 25, 21, 25, 26, - 21, 17, 24, 28, 30, 38, 33, 34, 30, 33, 28, 24, 17, 14, 12, 12, - 9, 10, 9, 10, 9, 10, 10, 10, 9, 10, 10, 38, 10, 8, 8, 8, - 6, 5, 5, 5, 4, 4, 2, 2, 2, 2, 1, 1, 0, 18, 1, 0, - 0, 1, 0, 2, 40, 37, 56, 60, 84, 107, 144, 148, 163, 171, 165, 151, - 140, 132, 119, 120, 130, 116, 110, 118, 123, 139, 153, 163, 175, 185, 182, 179, - 177, 178, 174, 173, 166, 159, 146, 147, 138, 20, 14, 12, 67, 33, 130, 189, - 195, 197, 194, 193, 198, 190, 187, 195, 199, 189, 195, 195, 204, 201, 189, 197, - 194, 136, 55, 48, 12, 9, 112, 114, 122, 116, 165, 159, 161, 157, 127, 146, - 103, 103, 108, 111, 111, 130, 138, 163, 163, 161, 147, 136, 122, 42, 16, 13, - 22, 26, 38, 37, 45, 32, 38, 40, 42, 55, 59, 61, 68, 73, 79, 71, - 59, 76, 56, 128, 171, 174, 123, 95, 52, 32, 28, 42, 48, 46, 42, 45, - 53, 59, 63, 69, 84, 88, 88, 220, 218, 218, 106, 99, 107, 115, 112, 122, - 128, 131, 131, 130, 132, 139, 124, 123, 22, 13, 10, 21, 32, 42, 42, 49, - 64, 153, 162, 177, 183, 183, 178, 189, 197, 202, 197, 197, 193, 190, 194, 195, - 194, 187, 189, 186, 183, 179, 185, 179, 183, 127, 99, 57, 67, 72, 102, 143, - 169, 182, 181, 169, 162, 151, 153, 154, 143, 134, 116, 104, 114, 111, 106, 114, - 118, 93, 132, 159, 178, 186, 193, 187, 179, 178, 174, 142, 114, 87, 99, 99, - 88, 103, 97, 107, 93, 108, 93, 89, 77, 52, 36, 21, 77, 96, 92, 85, - 85, 89, 93, 100, 89, 88, 80, 83, 85, 79, 76, 92, 92, 92, 92, 88, - 80, 65, 33, 100, 114, 87, 85, 114, 108, 104, 95, 84, 110, 138, 151, 159, - 151, 155, 155, 151, 143, 128, 104, 85, 79, 51, 44, 17, 33, 95, 104, 80, - 83, 69, 95, 81, 83, 76, 73, 65, 76, 91, 75, 71, 65, 75, 60, 63, - 71, 55, 32, 1, 71, 89, 96, 100, 72, 93, 89, 75, 81, 67, 51, 56, - 75, 75, 64, 218, 229, 221, 106, 102, 112, 110, 111, 110, 114, 112, 119, 118, - 136, 154, 155, 150, 136, 127, 110, 16, 12, 10, 18, 22, 22, 28, 18, 18, - 16, 30, 9, 12, 33, 76, 72, 65, 65, 65, 40, 22, 21, 16, 20, 20, - 18, 40, 59, 64, 65, 69, 79, 72, 65, 56, 64, 75, 84, 72, 65, 53, - 60, 51, 56, 29, 29, 25, 21, 22, 29, 37, 36, 36, 41, 51, 53, 48, - 51, 34, 14, 73, 73, 81, 77, 183, 214, 179, 104, 100, 110, 124, 132, 142, - 151, 165, 157, 157, 123, 44, 33, 6, 6, 17, 17, 32, 65, 71, 72, 72, - 71, 80, 76, 73, 71, 38, 24, 67, 84, 96, 88, 85, 89, 97, 93, 87, - 80, 84, 84, 97, 116, 104, 104, 104, 87, 79, 83, 96, 163, 174, 186, 170, - 146, 103, 67, 57, 57, 64, 76, 116, 136, 157, 143, 146, 140, 132, 140, 119, - 118, 111, 103, 69, 44, 36, 20, 10, 71, 85, 108, 111, 85, 89, 65, 59, - 64, 65, 55, 52, 72, 123, 136, 147, 148, 147, 151, 153, 144, 151, 161, 175, - 182, 181, 165, 150, 100, 81, 41, 41, 34, 33, 21, 9, 26, 65, 79, 57, - 65, 64, 55, 51, 41, 24, 9, 28, 71, 83, 71, 69, 85, 84, 68, 99, - 99, 99, 69, 76, 111, 119, 150, 150, 146, 154, 142, 134, 124, 77, 45, 42, - 65, 118, 155, 167, 182, 193, 193, 193, 197, 199, 190, 175, 187, 174, 159, 157, - 159, 148, 143, 144, 146, 142, 143, 139, 153, 150, 154, 179, 179, 163, 150, 161, - 147, 139, 132, 147, 134, 110, 115, 96, 48, 166, 212, 202, 218, 178, 218, 174, - 214, 204, 225, 206, 210, 195, 205, 201, 201, 195, 201, 198, 146, 64, 67, 61, - 61, 126, 136, 115, 135, 194, 195, 229, 189, 116, 104, 108, 123, 128, 135, 123, - 131, 147, 166, 165, 150, 142, 136, 122, 40, 17, 13, 38, 38, 53, 60, 63, - 65, 68, 85, 91, 99, 95, 103, 103, 106, 104, 106, 87, 76, 49, 79, 135, - 169, 110, 79, 38, 34, 33, 46, 63, 63, 61, 55, 56, 92, 106, 103, 103, - 91, 87, 225, 220, 218, 106, 99, 108, 118, 130, 135, 134, 135, 134, 134, 130, - 136, 124, 123, 22, 10, 10, 26, 45, 55, 122, 69, 128, 165, 185, 190, 190, - 193, 198, 204, 209, 210, 214, 222, 225, 225, 229, 228, 229, 226, 233, 224, 232, - 236, 234, 228, 222, 224, 216, 218, 217, 209, 209, 212, 208, 210, 202, 201, 190, - 186, 183, 183, 177, 167, 157, 142, 139, 97, 99, 127, 153, 171, 187, 198, 208, - 209, 206, 209, 206, 205, 202, 197, 190, 171, 122, 103, 89, 79, 81, 85, 91, - 97, 97, 97, 95, 71, 48, 22, 95, 88, 102, 95, 97, 96, 83, 81, 84, - 91, 91, 65, 63, 102, 107, 114, 114, 108, 88, 81, 93, 64, 36, 108, 108, - 108, 88, 119, 87, 96, 111, 130, 173, 202, 213, 210, 208, 206, 199, 194, 189, - 178, 174, 157, 144, 81, 44, 22, 93, 93, 76, 76, 84, 89, 93, 77, 76, - 87, 93, 83, 61, 81, 79, 72, 71, 68, 68, 69, 69, 63, 36, 0, 57, - 84, 85, 80, 65, 61, 76, 73, 60, 69, 76, 32, 65, 89, 68, 226, 234, - 221, 104, 96, 107, 123, 130, 134, 138, 138, 135, 136, 140, 155, 153, 144, 136, - 130, 116, 13, 12, 13, 18, 12, 20, 32, 29, 26, 17, 12, 10, 17, 61, - 84, 89, 84, 89, 81, 73, 68, 76, 73, 61, 65, 75, 79, 76, 79, 75, - 81, 88, 91, 68, 76, 76, 95, 115, 108, 100, 119, 120, 120, 75, 63, 59, - 51, 46, 45, 51, 46, 37, 24, 29, 30, 22, 18, 17, 30, 18, 73, 83, - 80, 75, 212, 217, 186, 100, 97, 107, 123, 134, 140, 151, 163, 157, 140, 128, - 45, 45, 49, 51, 52, 77, 72, 80, 83, 83, 79, 87, 64, 68, 67, 67, - 71, 30, 91, 84, 87, 99, 91, 126, 148, 163, 167, 170, 170, 174, 182, 189, - 189, 182, 183, 181, 181, 181, 183, 190, 190, 191, 189, 181, 171, 170, 144, 138, - 154, 139, 154, 177, 182, 195, 191, 185, 183, 183, 170, 171, 177, 173, 150, 69, - 32, 30, 14, 83, 102, 87, 107, 112, 93, 108, 104, 81, 102, 120, 159, 158, - 179, 183, 191, 185, 186, 186, 190, 194, 193, 197, 205, 205, 206, 204, 202, 195, - 175, 154, 102, 60, 49, 22, 6, 68, 77, 60, 71, 77, 61, 71, 60, 51, - 18, 14, 80, 167, 178, 181, 175, 181, 189, 198, 206, 201, 195, 198, 194, 195, - 194, 195, 177, 191, 193, 185, 148, 170, 136, 61, 46, 95, 150, 177, 185, 191, - 195, 199, 204, 201, 204, 201, 174, 202, 197, 155, 104, 95, 146, 167, 167, 163, - 150, 157, 153, 142, 120, 119, 106, 114, 112, 104, 147, 150, 95, 148, 157, 118, - 110, 106, 53, 34, 91, 155, 187, 143, 124, 97, 102, 108, 108, 136, 178, 183, - 183, 191, 171, 175, 187, 191, 111, 76, 65, 87, 102, 114, 108, 108, 116, 140, - 177, 202, 237, 208, 122, 103, 120, 130, 136, 147, 153, 158, 162, 161, 153, 151, - 142, 138, 122, 36, 16, 14, 34, 49, 53, 75, 67, 79, 89, 83, 87, 92, - 97, 100, 88, 104, 95, 96, 92, 76, 65, 68, 80, 151, 96, 63, 42, 36, - 30, 57, 56, 55, 52, 42, 84, 108, 104, 96, 93, 87, 85, 232, 224, 220, - 100, 97, 114, 122, 135, 132, 138, 140, 138, 132, 130, 134, 123, 120, 22, 10, - 12, 25, 40, 110, 49, 64, 76, 111, 169, 178, 185, 194, 197, 201, 205, 210, - 216, 218, 218, 225, 225, 228, 229, 229, 232, 226, 234, 233, 233, 228, 221, 213, - 208, 210, 210, 216, 217, 212, 208, 209, 202, 187, 189, 175, 166, 178, 167, 167, - 122, 87, 122, 139, 163, 183, 198, 199, 195, 190, 202, 209, 208, 210, 210, 210, - 206, 205, 201, 195, 190, 171, 147, 104, 81, 75, 81, 80, 79, 84, 81, 85, - 53, 29, 97, 91, 100, 91, 83, 72, 68, 69, 69, 68, 71, 52, 76, 114, - 95, 79, 111, 111, 102, 73, 71, 61, 37, 114, 112, 120, 111, 120, 126, 115, - 142, 201, 218, 226, 224, 213, 204, 194, 181, 155, 140, 116, 93, 73, 64, 132, - 55, 29, 100, 88, 92, 100, 95, 91, 83, 73, 85, 77, 65, 52, 84, 85, - 81, 59, 60, 73, 67, 59, 73, 46, 33, 0, 65, 61, 68, 69, 76, 79, - 85, 95, 88, 76, 79, 40, 63, 84, 61, 233, 236, 232, 107, 97, 110, 130, - 138, 144, 151, 151, 151, 154, 151, 148, 144, 142, 140, 132, 122, 17, 12, 14, - 13, 21, 12, 8, 18, 17, 21, 9, 12, 17, 65, 88, 91, 87, 83, 88, - 77, 81, 85, 100, 87, 67, 65, 79, 123, 158, 165, 177, 186, 197, 198, 193, - 198, 206, 212, 209, 212, 221, 221, 212, 206, 210, 189, 195, 195, 199, 190, 157, - 67, 28, 20, 24, 18, 18, 12, 32, 21, 65, 73, 83, 89, 218, 224, 213, - 96, 93, 107, 122, 132, 142, 151, 162, 162, 155, 169, 87, 76, 71, 71, 72, - 73, 73, 91, 92, 99, 77, 79, 75, 92, 76, 71, 67, 69, 59, 87, 79, - 68, 100, 173, 186, 187, 170, 183, 194, 189, 195, 185, 183, 198, 183, 197, 198, - 190, 185, 183, 177, 178, 181, 185, 193, 181, 171, 131, 138, 178, 193, 193, 190, - 185, 197, 183, 169, 134, 138, 122, 112, 122, 107, 81, 26, 26, 17, 67, 73, - 93, 77, 81, 100, 80, 76, 103, 146, 153, 174, 178, 179, 177, 170, 178, 182, - 189, 183, 181, 177, 171, 174, 179, 183, 194, 199, 201, 201, 198, 187, 123, 53, - 30, 8, 79, 75, 61, 56, 51, 46, 52, 71, 61, 29, 22, 115, 177, 181, - 173, 189, 202, 201, 201, 204, 204, 205, 198, 189, 183, 186, 179, 174, 166, 151, - 158, 148, 146, 122, 68, 53, 118, 154, 175, 183, 189, 195, 205, 205, 165, 165, - 147, 136, 139, 134, 112, 64, 68, 89, 162, 167, 151, 142, 130, 131, 127, 127, - 123, 119, 124, 126, 132, 132, 140, 142, 142, 144, 106, 96, 97, 111, 46, 57, - 72, 81, 77, 75, 72, 72, 73, 77, 76, 79, 79, 83, 87, 89, 91, 84, - 80, 75, 60, 88, 22, 18, 13, 100, 102, 119, 130, 193, 208, 199, 190, 139, - 107, 115, 134, 155, 158, 158, 162, 163, 159, 153, 147, 140, 138, 124, 34, 16, - 14, 37, 55, 55, 73, 75, 85, 65, 100, 104, 89, 87, 93, 85, 96, 96, - 96, 96, 79, 64, 37, 71, 147, 96, 63, 38, 33, 33, 57, 60, 52, 52, - 49, 95, 108, 102, 92, 89, 85, 85, 237, 228, 222, 108, 97, 114, 124, 132, - 134, 142, 139, 134, 127, 127, 131, 124, 119, 20, 10, 12, 22, 44, 60, 59, - 67, 119, 143, 174, 173, 130, 161, 138, 143, 142, 138, 134, 134, 132, 130, 126, - 126, 122, 120, 119, 127, 122, 116, 116, 118, 110, 107, 110, 110, 163, 178, 210, - 183, 174, 170, 154, 131, 108, 102, 102, 103, 107, 102, 99, 115, 118, 170, 197, - 198, 199, 205, 183, 167, 174, 171, 159, 148, 139, 143, 142, 144, 146, 167, 182, - 182, 186, 114, 92, 64, 79, 72, 49, 61, 71, 83, 60, 26, 73, 92, 104, - 83, 67, 76, 81, 69, 64, 59, 77, 48, 71, 116, 111, 84, 88, 102, 79, - 79, 76, 60, 48, 119, 123, 103, 115, 122, 127, 135, 205, 228, 233, 222, 213, - 185, 135, 108, 93, 87, 80, 76, 64, 42, 44, 63, 48, 17, 67, 85, 83, - 81, 71, 63, 56, 63, 61, 83, 67, 40, 77, 79, 73, 60, 72, 67, 65, - 63, 76, 49, 29, 0, 64, 72, 76, 72, 73, 65, 65, 75, 79, 81, 55, - 21, 69, 97, 49, 230, 237, 233, 110, 100, 108, 135, 142, 148, 148, 157, 157, - 161, 157, 158, 154, 144, 138, 134, 122, 13, 8, 9, 13, 26, 14, 5, 18, - 6, 44, 9, 10, 12, 57, 87, 85, 85, 89, 88, 80, 85, 76, 75, 60, - 42, 84, 92, 84, 151, 178, 189, 198, 201, 205, 209, 212, 214, 218, 221, 226, - 226, 225, 224, 222, 220, 222, 221, 218, 217, 212, 185, 79, 30, 26, 17, 34, - 13, 18, 32, 16, 45, 63, 80, 72, 226, 230, 224, 100, 93, 107, 122, 132, - 142, 151, 162, 165, 161, 136, 170, 119, 124, 179, 195, 198, 199, 198, 199, 198, - 195, 193, 197, 191, 185, 175, 110, 68, 72, 71, 48, 91, 103, 110, 183, 197, - 178, 194, 195, 198, 169, 157, 132, 144, 163, 185, 182, 182, 165, 167, 147, 158, - 155, 151, 150, 146, 130, 114, 163, 193, 195, 195, 189, 185, 155, 138, 111, 104, - 106, 100, 102, 99, 110, 37, 28, 25, 16, 77, 77, 95, 104, 73, 83, 96, - 72, 106, 143, 162, 183, 187, 169, 157, 134, 132, 132, 139, 134, 134, 126, 123, - 120, 127, 128, 144, 153, 154, 165, 175, 187, 169, 81, 42, 12, 49, 80, 61, - 51, 53, 51, 59, 60, 65, 28, 18, 107, 158, 183, 195, 195, 229, 193, 197, - 197, 197, 190, 179, 175, 187, 178, 171, 167, 103, 88, 84, 79, 87, 77, 71, - 63, 114, 161, 175, 187, 202, 171, 162, 143, 120, 126, 118, 115, 119, 110, 114, - 63, 48, 77, 99, 162, 161, 142, 155, 131, 127, 114, 131, 128, 132, 132, 131, - 131, 138, 139, 142, 132, 100, 88, 91, 108, 55, 60, 64, 67, 64, 71, 79, - 81, 77, 71, 76, 68, 80, 73, 76, 75, 77, 72, 69, 88, 77, 16, 12, - 12, 46, 84, 93, 110, 118, 191, 209, 232, 190, 119, 104, 126, 140, 154, 162, - 158, 159, 159, 161, 154, 150, 143, 136, 118, 29, 14, 14, 34, 51, 63, 71, - 76, 88, 69, 100, 100, 84, 92, 83, 85, 91, 107, 104, 87, 73, 67, 40, - 68, 136, 97, 85, 61, 40, 34, 53, 49, 52, 40, 40, 103, 112, 96, 99, - 92, 84, 80, 237, 228, 221, 107, 99, 112, 124, 130, 136, 136, 130, 127, 126, - 127, 126, 122, 115, 20, 10, 9, 22, 38, 44, 61, 42, 77, 110, 134, 108, - 142, 118, 107, 107, 110, 110, 99, 107, 111, 108, 100, 100, 100, 103, 100, 100, - 97, 100, 97, 97, 97, 96, 96, 97, 100, 103, 103, 99, 96, 95, 95, 95, - 96, 97, 100, 103, 106, 110, 112, 118, 118, 187, 195, 195, 198, 182, 150, 124, - 111, 106, 107, 104, 102, 106, 108, 108, 111, 114, 131, 132, 159, 155, 93, 64, - 87, 60, 73, 75, 69, 76, 53, 28, 89, 102, 97, 83, 84, 77, 102, 71, - 60, 56, 72, 45, 79, 116, 106, 84, 72, 75, 68, 75, 73, 60, 41, 110, - 120, 111, 135, 128, 136, 202, 226, 237, 234, 214, 155, 87, 76, 68, 68, 68, - 64, 55, 49, 36, 29, 45, 49, 28, 68, 81, 85, 67, 61, 59, 57, 56, - 60, 72, 59, 46, 80, 84, 63, 63, 79, 77, 60, 71, 75, 63, 28, 1, - 57, 81, 76, 64, 83, 95, 85, 83, 76, 71, 56, 22, 64, 71, 49, 236, - 240, 234, 110, 102, 110, 135, 144, 153, 153, 161, 166, 167, 165, 159, 154, 146, - 139, 131, 118, 10, 10, 13, 10, 20, 5, 8, 1, 18, 26, 13, 9, 17, - 53, 84, 83, 73, 81, 92, 77, 84, 64, 60, 53, 42, 83, 85, 107, 99, - 126, 151, 185, 199, 198, 206, 209, 217, 217, 224, 208, 230, 228, 225, 210, 224, - 228, 222, 197, 228, 228, 186, 77, 28, 14, 32, 29, 13, 21, 28, 24, 33, - 61, 79, 71, 229, 234, 228, 102, 93, 106, 119, 131, 144, 150, 162, 167, 167, - 159, 174, 181, 186, 191, 198, 198, 198, 198, 197, 194, 194, 190, 191, 187, 183, - 181, 177, 167, 103, 80, 76, 75, 59, 72, 99, 122, 108, 104, 110, 95, 93, - 91, 87, 96, 95, 103, 103, 103, 102, 103, 100, 99, 103, 108, 107, 106, 130, - 119, 161, 195, 193, 185, 186, 136, 114, 107, 106, 104, 111, 110, 111, 116, 87, - 29, 22, 16, 9, 75, 80, 89, 93, 93, 77, 103, 108, 116, 165, 163, 151, - 163, 153, 111, 93, 91, 92, 95, 96, 96, 95, 95, 99, 102, 103, 107, 110, - 115, 119, 124, 134, 171, 123, 57, 13, 57, 77, 60, 60, 57, 53, 49, 46, - 65, 29, 20, 40, 83, 143, 159, 155, 146, 135, 114, 106, 99, 85, 79, 84, - 80, 81, 79, 72, 69, 71, 65, 65, 65, 61, 76, 68, 118, 165, 175, 175, - 167, 128, 123, 102, 107, 119, 120, 128, 119, 124, 108, 61, 61, 56, 60, 96, - 185, 161, 153, 144, 138, 135, 132, 134, 135, 132, 131, 135, 135, 130, 118, 134, - 93, 33, 84, 84, 85, 89, 92, 53, 63, 97, 124, 110, 111, 100, 97, 88, - 89, 87, 81, 95, 79, 80, 93, 84, 25, 10, 9, 16, 21, 72, 87, 100, - 104, 185, 212, 238, 179, 123, 108, 126, 148, 158, 162, 162, 165, 169, 162, 155, - 150, 143, 134, 120, 32, 14, 17, 36, 48, 56, 60, 71, 80, 63, 91, 96, - 80, 102, 83, 76, 91, 76, 79, 77, 69, 67, 46, 77, 130, 128, 99, 76, - 60, 52, 53, 51, 48, 38, 68, 102, 106, 100, 95, 89, 80, 77, 241, 232, - 230, 102, 99, 111, 122, 130, 136, 128, 127, 126, 135, 134, 132, 127, 120, 20, - 9, 9, 22, 34, 44, 72, 63, 42, 72, 107, 111, 115, 122, 108, 110, 96, - 107, 112, 107, 104, 102, 106, 107, 108, 108, 108, 107, 108, 110, 110, 111, 115, - 118, 114, 111, 99, 97, 96, 97, 97, 100, 97, 102, 110, 112, 116, 119, 122, - 122, 119, 122, 112, 142, 201, 177, 151, 131, 104, 119, 119, 118, 116, 116, 118, - 118, 118, 116, 114, 112, 107, 108, 114, 135, 102, 67, 77, 61, 65, 68, 71, - 76, 56, 29, 88, 102, 99, 96, 95, 73, 99, 73, 59, 69, 72, 42, 72, - 107, 102, 88, 85, 83, 79, 75, 71, 60, 45, 118, 126, 139, 118, 130, 190, - 225, 238, 238, 226, 159, 103, 71, 56, 44, 38, 34, 40, 36, 36, 25, 29, - 33, 52, 28, 42, 91, 87, 61, 61, 61, 64, 61, 56, 68, 64, 44, 76, - 80, 60, 75, 79, 63, 59, 71, 69, 73, 32, 0, 68, 76, 81, 71, 65, - 61, 69, 76, 83, 65, 49, 32, 57, 87, 51, 228, 238, 237, 108, 97, 110, - 134, 147, 154, 161, 165, 175, 175, 173, 162, 158, 148, 142, 130, 120, 10, 8, - 10, 13, 22, 16, 8, 10, 30, 37, 14, 9, 16, 55, 79, 83, 83, 88, - 76, 81, 79, 64, 56, 65, 36, 72, 96, 77, 108, 110, 115, 120, 134, 142, - 135, 127, 126, 128, 131, 131, 153, 144, 139, 157, 167, 139, 132, 147, 165, 126, - 106, 75, 24, 21, 30, 37, 16, 18, 22, 34, 17, 59, 69, 68, 233, 234, - 232, 106, 95, 107, 120, 131, 143, 151, 163, 170, 169, 165, 161, 131, 175, 185, - 191, 199, 198, 199, 197, 195, 195, 194, 193, 191, 190, 185, 181, 170, 166, 150, - 144, 79, 72, 72, 59, 63, 72, 87, 75, 85, 83, 85, 84, 89, 89, 96, - 95, 96, 97, 99, 100, 103, 103, 106, 110, 112, 131, 122, 151, 186, 178, 181, - 120, 108, 112, 108, 119, 118, 120, 116, 120, 120, 76, 20, 18, 21, 12, 71, - 80, 87, 87, 97, 95, 79, 97, 132, 139, 148, 127, 119, 95, 85, 93, 102, - 99, 99, 102, 100, 104, 106, 107, 106, 108, 108, 108, 111, 111, 112, 114, 124, - 147, 67, 17, 51, 68, 52, 59, 59, 61, 55, 51, 53, 44, 26, 33, 36, - 61, 69, 73, 68, 77, 79, 68, 69, 67, 69, 67, 73, 75, 72, 69, 72, - 79, 106, 110, 112, 112, 81, 76, 122, 193, 182, 142, 110, 107, 119, 122, 128, - 131, 134, 132, 132, 134, 96, 48, 14, 48, 65, 53, 80, 178, 162, 148, 148, - 148, 143, 146, 146, 150, 148, 150, 150, 147, 136, 110, 100, 88, 89, 76, 73, - 76, 92, 81, 60, 95, 182, 183, 132, 132, 115, 118, 118, 110, 123, 123, 126, - 115, 112, 37, 16, 10, 20, 25, 40, 65, 87, 84, 110, 191, 214, 238, 161, - 128, 108, 127, 150, 157, 161, 166, 166, 170, 166, 162, 147, 142, 132, 122, 32, - 16, 16, 40, 44, 56, 71, 64, 79, 68, 97, 97, 75, 96, 87, 77, 75, - 111, 76, 77, 67, 65, 37, 65, 126, 123, 92, 96, 80, 67, 69, 48, 41, - 33, 71, 106, 99, 102, 87, 104, 106, 81, 238, 232, 233, 107, 95, 112, 123, - 132, 127, 136, 140, 142, 147, 146, 139, 128, 124, 20, 9, 9, 24, 37, 45, - 57, 49, 69, 40, 57, 108, 80, 89, 96, 107, 126, 135, 115, 118, 119, 139, - 119, 123, 126, 135, 123, 123, 124, 138, 128, 130, 139, 139, 134, 132, 124, 116, - 114, 114, 115, 116, 116, 120, 124, 131, 134, 138, 138, 139, 128, 124, 100, 116, - 132, 124, 102, 124, 124, 143, 140, 128, 127, 128, 127, 127, 128, 128, 126, 124, - 120, 119, 115, 111, 115, 71, 63, 73, 60, 65, 71, 71, 57, 34, 83, 95, - 95, 93, 95, 80, 103, 84, 57, 65, 60, 38, 67, 107, 103, 75, 84, 65, - 89, 88, 88, 79, 77, 119, 148, 142, 142, 178, 216, 237, 242, 234, 209, 119, - 77, 51, 29, 26, 32, 26, 25, 28, 32, 30, 32, 30, 93, 30, 36, 89, - 81, 61, 61, 65, 65, 64, 61, 61, 61, 42, 72, 83, 63, 76, 68, 59, - 59, 60, 73, 52, 30, 0, 67, 77, 65, 63, 63, 67, 67, 76, 73, 61, - 40, 40, 48, 83, 76, 238, 242, 238, 115, 97, 108, 132, 143, 154, 161, 167, - 175, 174, 173, 171, 161, 144, 140, 132, 122, 10, 10, 9, 13, 21, 12, 8, - 10, 32, 24, 4, 9, 14, 44, 65, 83, 83, 79, 84, 89, 63, 51, 45, - 44, 37, 83, 84, 76, 111, 108, 92, 100, 107, 108, 110, 116, 114, 108, 114, - 120, 118, 122, 124, 126, 124, 127, 115, 119, 112, 112, 91, 48, 16, 12, 34, - 28, 16, 20, 18, 30, 9, 53, 81, 71, 233, 240, 233, 107, 97, 110, 124, - 131, 143, 151, 163, 169, 171, 169, 162, 163, 144, 139, 138, 134, 132, 128, 127, - 124, 124, 123, 122, 120, 116, 114, 112, 104, 112, 110, 110, 89, 95, 72, 93, - 87, 92, 85, 88, 89, 91, 93, 93, 95, 99, 102, 102, 103, 104, 107, 110, - 110, 112, 114, 119, 120, 115, 122, 119, 163, 194, 123, 115, 120, 124, 128, 130, - 130, 127, 123, 126, 122, 65, 18, 18, 17, 8, 64, 79, 84, 89, 83, 84, - 81, 87, 81, 84, 79, 85, 87, 73, 68, 61, 68, 85, 85, 108, 108, 110, - 114, 116, 116, 118, 118, 120, 120, 122, 120, 119, 116, 161, 85, 30, 33, 53, - 73, 69, 57, 46, 48, 53, 42, 59, 28, 18, 53, 49, 65, 69, 79, 80, - 81, 81, 89, 88, 92, 95, 99, 102, 103, 106, 104, 108, 118, 122, 124, 122, - 91, 79, 115, 163, 155, 126, 106, 128, 134, 140, 138, 139, 138, 138, 139, 127, - 79, 14, 33, 44, 49, 51, 61, 103, 163, 162, 140, 131, 154, 154, 155, 155, - 159, 159, 161, 159, 155, 142, 122, 95, 40, 79, 81, 75, 73, 73, 53, 96, - 191, 179, 162, 161, 132, 126, 128, 134, 122, 128, 144, 124, 104, 38, 14, 8, - 22, 26, 8, 63, 80, 79, 100, 202, 220, 229, 162, 116, 108, 127, 147, 158, - 162, 165, 165, 170, 166, 162, 150, 139, 136, 124, 33, 14, 20, 40, 55, 61, - 67, 71, 73, 64, 92, 89, 76, 85, 88, 84, 75, 69, 75, 71, 67, 57, - 33, 63, 122, 112, 84, 87, 84, 63, 111, 75, 40, 32, 84, 104, 95, 95, - 85, 100, 89, 79, 240, 232, 234, 107, 95, 110, 123, 135, 138, 150, 154, 159, - 161, 154, 142, 131, 126, 20, 9, 10, 18, 30, 42, 41, 57, 85, 61, 41, - 53, 96, 96, 92, 167, 179, 161, 115, 134, 159, 126, 128, 138, 148, 134, 132, - 136, 147, 134, 138, 144, 138, 143, 144, 143, 140, 136, 134, 134, 132, 138, 139, - 140, 143, 146, 150, 150, 150, 150, 144, 127, 132, 99, 97, 132, 130, 102, 72, - 65, 79, 103, 119, 154, 131, 134, 153, 135, 135, 134, 131, 130, 126, 115, 131, - 89, 52, 69, 71, 68, 60, 79, 60, 33, 41, 91, 96, 108, 96, 79, 102, - 83, 52, 68, 56, 40, 93, 96, 103, 88, 97, 91, 107, 126, 144, 151, 161, - 190, 206, 212, 217, 221, 236, 242, 244, 233, 169, 92, 45, 52, 37, 46, 41, - 46, 41, 37, 36, 37, 37, 40, 40, 42, 29, 69, 77, 65, 68, 68, 67, - 73, 65, 65, 61, 40, 67, 72, 61, 75, 67, 61, 63, 65, 75, 57, 28, - 1, 60, 79, 73, 75, 72, 79, 76, 73, 77, 55, 25, 18, 49, 76, 53, - 237, 244, 241, 112, 99, 108, 135, 146, 151, 161, 166, 171, 173, 173, 171, 162, - 144, 136, 134, 122, 10, 8, 14, 9, 14, 8, 9, 2, 24, 10, 13, 6, - 14, 40, 61, 79, 89, 83, 79, 67, 63, 52, 52, 48, 32, 83, 83, 88, - 76, 80, 73, 76, 124, 130, 103, 116, 122, 128, 131, 130, 122, 123, 124, 126, - 122, 118, 120, 118, 116, 104, 87, 33, 17, 16, 28, 34, 16, 21, 22, 34, - 9, 56, 73, 75, 228, 238, 237, 108, 99, 111, 124, 134, 143, 153, 165, 169, - 170, 169, 155, 147, 116, 91, 85, 106, 100, 114, 112, 112, 108, 106, 102, 99, - 91, 88, 88, 88, 81, 80, 73, 67, 61, 57, 53, 56, 64, 53, 63, 170, - 99, 100, 97, 104, 103, 108, 111, 111, 112, 118, 122, 122, 123, 124, 126, 128, - 128, 130, 120, 122, 119, 118, 126, 135, 139, 138, 138, 135, 134, 132, 128, 110, - 41, 21, 13, 17, 12, 52, 79, 76, 84, 88, 88, 91, 79, 75, 65, 57, - 45, 41, 37, 29, 36, 36, 51, 65, 80, 93, 112, 110, 118, 116, 122, 115, - 119, 124, 130, 130, 128, 127, 124, 122, 59, 14, 51, 53, 42, 38, 55, 46, - 49, 42, 49, 28, 25, 49, 45, 45, 53, 52, 134, 89, 96, 102, 106, 104, - 108, 112, 111, 114, 115, 114, 114, 126, 128, 131, 131, 126, 85, 106, 151, 130, - 123, 134, 144, 140, 143, 139, 140, 144, 142, 140, 128, 61, 30, 29, 37, 30, - 42, 57, 63, 130, 170, 155, 134, 132, 153, 163, 163, 161, 166, 166, 170, 170, - 166, 148, 108, 77, 68, 40, 63, 71, 56, 60, 110, 191, 190, 177, 136, 150, - 134, 135, 135, 140, 147, 144, 118, 120, 30, 16, 20, 24, 8, 0, 57, 77, - 77, 96, 199, 221, 233, 139, 116, 107, 126, 140, 155, 161, 161, 163, 170, 166, - 165, 151, 143, 134, 126, 30, 14, 17, 36, 56, 64, 64, 84, 87, 56, 89, - 84, 77, 84, 84, 87, 75, 69, 69, 67, 65, 60, 33, 63, 128, 142, 93, - 91, 92, 92, 65, 76, 45, 25, 81, 100, 93, 93, 87, 93, 85, 76, 241, - 238, 233, 104, 96, 110, 124, 139, 147, 159, 165, 163, 165, 157, 144, 132, 126, - 17, 9, 9, 20, 38, 41, 41, 46, 64, 61, 45, 42, 80, 87, 91, 195, - 190, 124, 107, 118, 136, 134, 151, 157, 136, 138, 147, 151, 142, 146, 142, 148, - 148, 147, 159, 159, 163, 157, 148, 144, 146, 151, 155, 154, 158, 157, 161, 161, - 161, 159, 155, 140, 140, 140, 134, 106, 60, 38, 28, 30, 41, 77, 111, 130, - 170, 179, 177, 163, 170, 169, 155, 135, 132, 124, 115, 104, 57, 51, 68, 65, - 63, 64, 63, 46, 36, 83, 83, 73, 93, 84, 85, 61, 61, 57, 46, 61, - 91, 84, 126, 140, 171, 195, 218, 222, 237, 237, 244, 244, 246, 248, 246, 246, - 248, 248, 238, 213, 134, 89, 56, 29, 40, 38, 38, 41, 37, 38, 40, 44, - 44, 38, 40, 40, 34, 67, 85, 80, 79, 80, 76, 80, 72, 63, 56, 40, - 71, 77, 64, 67, 77, 72, 88, 75, 65, 61, 25, 0, 64, 88, 76, 87, - 83, 75, 81, 79, 71, 56, 26, 20, 45, 73, 51, 237, 244, 240, 110, 97, - 108, 132, 143, 151, 158, 162, 167, 174, 171, 171, 165, 146, 139, 132, 123, 10, - 10, 9, 12, 18, 20, 20, 8, 6, 10, 6, 6, 18, 29, 56, 56, 57, - 55, 57, 56, 44, 48, 49, 45, 33, 57, 77, 77, 69, 68, 65, 65, 73, - 57, 79, 157, 119, 112, 118, 134, 135, 140, 142, 147, 147, 150, 142, 147, 112, - 106, 89, 21, 12, 16, 20, 16, 29, 33, 17, 28, 20, 48, 69, 77, 216, - 238, 238, 107, 99, 108, 124, 135, 144, 153, 165, 169, 170, 166, 157, 124, 65, - 26, 24, 24, 64, 81, 108, 106, 111, 108, 108, 110, 110, 108, 112, 112, 111, - 108, 59, 55, 59, 56, 53, 52, 48, 51, 57, 174, 178, 108, 88, 114, 120, - 112, 115, 119, 119, 120, 126, 128, 131, 134, 135, 135, 135, 128, 127, 116, 112, - 138, 143, 143, 146, 140, 140, 139, 134, 135, 124, 79, 20, 17, 13, 17, 13, - 34, 73, 77, 75, 65, 55, 41, 45, 45, 45, 38, 49, 49, 48, 45, 61, - 59, 37, 32, 61, 99, 112, 167, 170, 166, 144, 153, 166, 151, 151, 147, 132, - 136, 126, 153, 91, 29, 18, 51, 51, 46, 41, 45, 44, 45, 55, 25, 21, - 37, 46, 52, 38, 45, 131, 158, 100, 99, 108, 119, 116, 118, 120, 122, 120, - 120, 123, 128, 138, 135, 136, 135, 131, 89, 89, 131, 143, 147, 147, 147, 146, - 138, 143, 143, 142, 138, 96, 41, 33, 32, 9, 34, 34, 55, 51, 57, 148, - 163, 139, 127, 136, 153, 161, 166, 169, 173, 173, 174, 175, 167, 138, 72, 67, - 48, 67, 61, 67, 60, 119, 202, 195, 212, 147, 153, 136, 135, 138, 139, 151, - 144, 118, 118, 26, 14, 6, 12, 8, 0, 56, 59, 67, 89, 208, 220, 234, - 140, 102, 111, 130, 144, 153, 157, 159, 165, 167, 166, 162, 155, 136, 131, 123, - 33, 16, 18, 37, 53, 53, 63, 65, 72, 55, 99, 97, 76, 65, 64, 67, - 64, 64, 61, 63, 65, 61, 44, 69, 87, 110, 95, 33, 44, 40, 38, 37, - 34, 24, 49, 79, 77, 69, 68, 87, 77, 75, 242, 240, 233, 103, 96, 108, - 123, 138, 150, 163, 166, 163, 166, 158, 143, 132, 124, 17, 9, 9, 18, 22, - 34, 37, 36, 41, 34, 38, 46, 79, 93, 87, 198, 195, 167, 112, 115, 123, - 139, 139, 144, 157, 154, 142, 155, 146, 150, 148, 148, 155, 166, 170, 178, 185, - 185, 179, 159, 158, 161, 167, 166, 167, 166, 167, 169, 169, 166, 162, 144, 144, - 142, 110, 60, 28, 28, 24, 20, 29, 57, 87, 119, 173, 177, 190, 181, 175, - 151, 170, 163, 150, 131, 119, 116, 71, 42, 49, 61, 64, 63, 59, 59, 51, - 44, 46, 52, 52, 55, 55, 55, 56, 49, 77, 88, 115, 177, 214, 234, 240, - 240, 245, 249, 252, 252, 252, 252, 252, 250, 252, 249, 248, 245, 233, 171, 122, - 93, 53, 26, 38, 36, 34, 34, 38, 37, 38, 38, 42, 37, 41, 38, 36, - 36, 52, 56, 52, 64, 56, 60, 57, 56, 59, 37, 67, 67, 67, 55, 60, - 59, 61, 56, 57, 44, 28, 2, 59, 65, 72, 77, 71, 71, 69, 71, 59, - 52, 25, 21, 36, 71, 46, 237, 242, 237, 108, 95, 108, 134, 144, 153, 158, - 159, 162, 171, 173, 171, 161, 151, 139, 131, 120, 9, 8, 9, 12, 14, 12, - 14, 16, 17, 16, 33, 24, 20, 32, 38, 44, 37, 37, 41, 45, 40, 44, - 49, 40, 28, 65, 72, 67, 64, 63, 65, 64, 65, 61, 59, 161, 167, 112, - 111, 122, 127, 135, 140, 147, 148, 144, 150, 147, 119, 107, 91, 21, 13, 17, - 13, 10, 20, 22, 12, 17, 24, 37, 51, 73, 224, 242, 238, 112, 99, 110, - 124, 136, 142, 150, 165, 170, 167, 178, 146, 77, 34, 16, 12, 9, 26, 73, - 123, 163, 167, 162, 119, 151, 154, 153, 150, 122, 119, 114, 80, 49, 63, 53, - 52, 49, 48, 40, 45, 161, 187, 161, 103, 103, 122, 123, 127, 127, 131, 131, - 134, 138, 138, 139, 139, 143, 140, 138, 136, 136, 148, 147, 151, 146, 142, 127, - 120, 110, 96, 95, 69, 30, 16, 10, 12, 17, 13, 25, 32, 37, 34, 38, - 40, 40, 51, 52, 57, 49, 63, 60, 60, 56, 57, 60, 60, 61, 77, 104, - 175, 187, 189, 179, 171, 171, 174, 170, 163, 167, 157, 143, 138, 126, 115, 63, - 16, 24, 59, 57, 40, 41, 40, 36, 52, 29, 21, 30, 48, 44, 40, 48, - 126, 166, 155, 97, 100, 120, 122, 126, 126, 124, 128, 128, 126, 142, 148, 151, - 148, 147, 139, 143, 151, 153, 150, 150, 144, 140, 132, 126, 116, 111, 108, 84, - 45, 26, 21, 30, 21, 26, 13, 28, 32, 20, 92, 169, 163, 132, 126, 136, - 153, 159, 167, 171, 174, 174, 177, 177, 161, 111, 56, 67, 77, 77, 65, 59, - 155, 204, 199, 187, 165, 162, 144, 140, 146, 150, 148, 144, 116, 114, 24, 9, - 5, 17, 13, 13, 53, 51, 59, 88, 197, 221, 234, 131, 97, 107, 128, 144, - 155, 158, 165, 166, 167, 159, 155, 157, 139, 132, 124, 36, 14, 20, 36, 37, - 56, 64, 60, 69, 57, 91, 84, 60, 61, 59, 64, 61, 60, 57, 65, 65, - 55, 41, 49, 37, 24, 22, 22, 22, 20, 17, 20, 20, 22, 29, 32, 37, - 44, 45, 57, 77, 76, 241, 240, 229, 103, 96, 108, 127, 139, 150, 162, 169, - 169, 162, 157, 142, 130, 122, 14, 8, 8, 16, 14, 32, 36, 28, 29, 30, - 28, 33, 48, 87, 87, 205, 198, 193, 114, 110, 122, 135, 165, 163, 144, 154, - 148, 150, 157, 161, 163, 167, 170, 174, 178, 169, 153, 174, 183, 190, 181, 163, - 178, 178, 175, 171, 183, 178, 175, 178, 174, 181, 150, 144, 100, 45, 28, 21, - 17, 17, 20, 48, 81, 114, 182, 190, 161, 165, 183, 179, 159, 155, 161, 135, - 124, 131, 80, 44, 42, 57, 59, 57, 52, 55, 53, 57, 55, 52, 56, 56, - 53, 57, 46, 87, 95, 140, 218, 241, 242, 244, 248, 249, 252, 252, 250, 241, - 236, 230, 229, 229, 222, 220, 213, 209, 175, 140, 128, 102, 55, 49, 38, 41, - 38, 38, 42, 40, 40, 41, 40, 40, 42, 40, 38, 42, 42, 42, 42, 42, - 45, 42, 42, 42, 42, 40, 41, 34, 40, 40, 49, 32, 36, 34, 32, 28, - 33, 4, 16, 28, 30, 33, 32, 33, 32, 42, 36, 22, 12, 34, 33, 64, - 53, 240, 242, 238, 110, 95, 103, 130, 140, 153, 158, 163, 170, 170, 173, 163, - 157, 148, 139, 131, 123, 8, 10, 10, 14, 14, 16, 22, 12, 14, 13, 10, - 16, 18, 18, 18, 28, 25, 24, 22, 22, 24, 25, 24, 38, 42, 40, 46, - 38, 30, 59, 60, 55, 57, 61, 52, 142, 173, 162, 112, 116, 130, 128, 136, - 143, 139, 146, 148, 150, 123, 112, 83, 18, 10, 9, 14, 12, 16, 26, 25, - 13, 16, 36, 49, 75, 233, 242, 241, 112, 100, 110, 124, 135, 144, 153, 166, - 170, 163, 157, 112, 40, 20, 9, 10, 12, 18, 59, 142, 179, 128, 162, 154, - 154, 158, 167, 140, 146, 122, 118, 107, 44, 41, 45, 51, 49, 45, 52, 38, - 89, 197, 179, 114, 104, 112, 136, 131, 134, 135, 136, 138, 140, 142, 143, 144, - 146, 148, 153, 155, 151, 153, 151, 136, 104, 65, 41, 22, 16, 16, 17, 14, - 13, 9, 13, 10, 18, 14, 30, 28, 30, 34, 44, 64, 106, 177, 195, 209, - 210, 208, 199, 186, 177, 103, 92, 85, 85, 108, 186, 213, 163, 191, 183, 185, - 182, 174, 178, 177, 170, 163, 155, 142, 132, 147, 91, 29, 16, 29, 34, 38, - 40, 37, 41, 42, 44, 28, 29, 40, 45, 29, 38, 104, 175, 173, 108, 100, - 110, 123, 132, 130, 130, 135, 143, 146, 153, 157, 157, 157, 154, 151, 155, 155, - 151, 146, 130, 95, 67, 38, 26, 20, 13, 21, 21, 22, 25, 25, 1, 4, - 4, 34, 36, 25, 22, 32, 118, 171, 146, 120, 122, 143, 154, 159, 166, 171, - 175, 178, 181, 177, 135, 68, 37, 45, 63, 75, 88, 187, 201, 202, 189, 161, - 151, 154, 153, 154, 155, 148, 147, 128, 110, 21, 10, 6, 9, 13, 10, 33, - 41, 40, 72, 190, 222, 221, 130, 107, 110, 128, 144, 154, 159, 162, 166, 165, - 151, 158, 150, 139, 132, 124, 44, 17, 18, 25, 29, 30, 37, 67, 65, 52, - 60, 60, 53, 41, 38, 40, 36, 32, 28, 21, 29, 29, 37, 17, 41, 45, - 48, 52, 55, 52, 61, 53, 37, 18, 59, 104, 104, 81, 87, 87, 83, 77, - 242, 237, 222, 104, 96, 107, 126, 134, 150, 162, 169, 167, 163, 158, 142, 127, - 126, 18, 9, 9, 13, 13, 10, 21, 25, 26, 24, 26, 30, 38, 88, 91, - 208, 206, 204, 116, 126, 116, 132, 161, 165, 151, 153, 154, 165, 173, 173, 173, - 171, 169, 178, 143, 89, 59, 80, 150, 183, 185, 169, 161, 174, 175, 177, 175, - 175, 179, 181, 183, 185, 154, 151, 95, 42, 25, 21, 17, 17, 20, 49, 73, - 106, 195, 197, 163, 186, 189, 187, 165, 181, 170, 140, 128, 118, 100, 53, 38, - 48, 44, 37, 32, 38, 36, 36, 37, 40, 40, 38, 42, 55, 68, 106, 165, - 236, 245, 246, 244, 250, 249, 238, 220, 191, 167, 124, 112, 115, 108, 111, 116, - 114, 110, 115, 131, 118, 124, 116, 89, 63, 20, 18, 16, 13, 12, 12, 10, - 9, 8, 9, 9, 5, 4, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 2, 6, 8, 6, 1, 1, 0, 2, 5, 6, 2, 16, 14, 14, 6, - 17, 16, 13, 13, 17, 18, 17, 30, 25, 24, 75, 57, 240, 244, 242, 114, - 96, 106, 130, 142, 154, 161, 169, 173, 171, 169, 159, 161, 144, 136, 132, 120, - 6, 9, 12, 10, 9, 9, 8, 9, 8, 10, 9, 9, 9, 14, 24, 57, - 64, 75, 71, 73, 67, 67, 63, 56, 56, 80, 85, 77, 48, 38, 37, 34, - 53, 67, 57, 76, 185, 179, 119, 115, 126, 128, 134, 135, 136, 150, 146, 146, - 116, 111, 84, 18, 8, 13, 17, 12, 20, 21, 24, 22, 28, 55, 51, 80, - 233, 244, 241, 107, 97, 108, 122, 134, 140, 154, 166, 169, 165, 144, 73, 26, - 14, 10, 10, 10, 28, 72, 185, 193, 162, 130, 159, 162, 150, 142, 131, 151, - 126, 120, 111, 41, 40, 41, 45, 46, 42, 51, 45, 75, 210, 201, 126, 103, - 115, 130, 139, 139, 138, 139, 138, 142, 144, 147, 147, 158, 162, 159, 155, 157, - 148, 100, 53, 16, 10, 9, 8, 8, 8, 9, 8, 9, 10, 13, 10, 21, - 29, 30, 46, 55, 72, 126, 185, 234, 242, 244, 244, 244, 242, 240, 240, 237, - 237, 236, 232, 224, 229, 229, 224, 208, 190, 183, 179, 179, 177, 175, 178, 174, - 170, 169, 150, 140, 127, 115, 61, 18, 21, 22, 28, 20, 25, 28, 26, 33, - 33, 32, 33, 29, 33, 42, 97, 186, 183, 120, 106, 107, 120, 130, 134, 138, - 153, 157, 162, 161, 159, 157, 159, 163, 159, 157, 153, 134, 91, 46, 13, 9, - 6, 8, 9, 10, 14, 12, 2, 6, 4, 6, 13, 5, 5, 10, 16, 8, - 20, 64, 151, 165, 128, 118, 132, 147, 155, 159, 167, 174, 177, 182, 185, 158, - 100, 75, 75, 76, 73, 112, 201, 205, 208, 194, 166, 157, 167, 155, 150, 157, - 146, 147, 123, 119, 21, 9, 10, 2, 2, 1, 144, 134, 128, 85, 186, 221, - 222, 140, 110, 107, 126, 144, 154, 158, 162, 163, 159, 159, 161, 140, 138, 132, - 127, 49, 17, 18, 24, 45, 41, 37, 37, 41, 46, 37, 44, 61, 73, 71, - 84, 89, 92, 100, 99, 91, 73, 22, 67, 79, 104, 110, 102, 93, 93, 91, - 68, 44, 17, 92, 104, 102, 100, 104, 104, 84, 84, 245, 233, 233, 104, 93, - 104, 127, 135, 148, 162, 166, 165, 161, 158, 143, 132, 127, 20, 10, 9, 16, - 12, 18, 32, 30, 38, 5, 36, 30, 84, 87, 99, 216, 212, 210, 130, 126, - 131, 123, 154, 162, 155, 153, 167, 177, 177, 177, 175, 167, 169, 155, 91, 34, - 36, 59, 108, 174, 197, 178, 157, 174, 179, 178, 181, 182, 183, 186, 187, 185, - 159, 155, 103, 48, 32, 24, 22, 20, 22, 52, 85, 103, 199, 204, 169, 166, - 170, 189, 189, 186, 173, 151, 134, 122, 126, 76, 37, 42, 49, 56, 52, 59, - 80, 88, 97, 91, 99, 95, 84, 96, 135, 183, 240, 242, 245, 249, 244, 221, - 186, 143, 118, 112, 104, 97, 107, 110, 111, 97, 115, 114, 110, 104, 123, 126, - 127, 122, 116, 76, 80, 61, 59, 60, 65, 60, 60, 57, 51, 55, 41, 49, - 73, 92, 95, 108, 102, 99, 111, 114, 97, 75, 69, 79, 122, 97, 100, 128, - 124, 99, 89, 91, 110, 83, 10, 0, 22, 45, 60, 32, 38, 33, 29, 26, - 5, 14, 21, 49, 77, 73, 65, 241, 244, 241, 112, 95, 110, 131, 143, 153, - 161, 170, 170, 171, 166, 162, 161, 143, 135, 132, 124, 8, 14, 12, 24, 48, - 61, 67, 71, 77, 75, 73, 63, 72, 72, 71, 83, 106, 97, 97, 80, 87, - 84, 89, 89, 80, 93, 103, 99, 79, 56, 49, 45, 42, 53, 59, 71, 193, - 187, 136, 115, 122, 132, 130, 132, 146, 148, 147, 146, 122, 110, 77, 16, 8, - 14, 22, 29, 36, 46, 45, 57, 57, 41, 77, 81, 233, 244, 240, 106, 97, - 108, 124, 135, 143, 155, 167, 166, 178, 134, 40, 20, 16, 13, 16, 8, 44, - 72, 195, 198, 187, 130, 154, 155, 157, 139, 130, 130, 127, 123, 112, 44, 34, - 38, 53, 49, 44, 45, 37, 65, 212, 209, 182, 110, 107, 122, 134, 143, 148, - 140, 144, 144, 151, 151, 158, 167, 162, 159, 159, 144, 83, 25, 9, 6, 9, - 9, 13, 14, 14, 14, 13, 13, 13, 12, 18, 22, 32, 42, 60, 107, 204, - 236, 240, 242, 242, 242, 240, 241, 241, 241, 240, 238, 236, 234, 233, 230, 230, - 230, 226, 222, 169, 165, 182, 183, 190, 173, 185, 178, 175, 171, 161, 146, 132, - 138, 87, 26, 26, 28, 36, 33, 45, 38, 33, 24, 18, 22, 29, 29, 36, - 53, 96, 191, 197, 166, 103, 104, 112, 127, 134, 148, 162, 162, 159, 161, 162, - 161, 162, 165, 159, 155, 138, 77, 17, 12, 5, 4, 0, 1, 1, 5, 4, - 10, 18, 13, 16, 14, 20, 26, 17, 17, 9, 9, 21, 37, 135, 162, 139, - 118, 118, 134, 151, 157, 165, 170, 177, 181, 183, 183, 131, 73, 65, 59, 89, - 146, 210, 208, 216, 206, 171, 161, 166, 151, 154, 154, 150, 148, 127, 118, 25, - 14, 12, 12, 34, 42, 103, 88, 93, 80, 155, 216, 224, 146, 110, 107, 126, - 140, 154, 159, 162, 163, 157, 159, 157, 140, 135, 132, 126, 57, 18, 20, 29, - 41, 55, 64, 64, 64, 45, 68, 99, 119, 112, 115, 122, 122, 116, 110, 116, - 104, 76, 22, 67, 138, 122, 123, 104, 106, 110, 80, 69, 44, 20, 100, 102, - 87, 80, 80, 96, 84, 85, 245, 236, 233, 104, 92, 106, 128, 134, 148, 162, - 169, 167, 162, 157, 143, 134, 128, 20, 10, 10, 13, 14, 26, 34, 24, 37, - 12, 29, 32, 84, 95, 106, 214, 216, 213, 131, 107, 114, 123, 134, 161, 158, - 162, 175, 178, 177, 179, 178, 173, 167, 122, 45, 30, 32, 37, 63, 153, 199, - 185, 158, 159, 174, 189, 190, 193, 194, 195, 195, 191, 185, 163, 134, 65, 34, - 26, 25, 21, 40, 65, 89, 97, 201, 209, 183, 166, 186, 189, 174, 187, 170, - 163, 136, 127, 119, 99, 45, 36, 51, 48, 81, 69, 76, 92, 96, 112, 87, - 100, 103, 139, 222, 241, 244, 245, 249, 230, 182, 136, 114, 108, 108, 111, 122, - 72, 41, 34, 37, 48, 99, 106, 114, 151, 174, 181, 171, 128, 124, 112, 91, - 63, 85, 83, 65, 69, 63, 64, 57, 76, 88, 59, 93, 112, 108, 107, 72, - 96, 118, 119, 100, 96, 80, 73, 112, 111, 119, 115, 120, 107, 110, 104, 96, - 93, 64, 0, 60, 52, 55, 65, 53, 46, 55, 45, 22, 18, 20, 77, 77, - 65, 76, 244, 244, 241, 103, 99, 110, 132, 142, 153, 162, 169, 169, 174, 165, - 159, 158, 142, 135, 132, 120, 8, 10, 17, 38, 60, 56, 60, 63, 64, 73, - 68, 77, 59, 80, 108, 88, 79, 77, 81, 93, 80, 79, 93, 134, 147, 199, - 185, 131, 96, 73, 59, 60, 57, 55, 55, 61, 199, 198, 169, 116, 120, 130, - 132, 130, 139, 153, 146, 151, 120, 112, 80, 17, 10, 16, 28, 48, 52, 51, - 49, 55, 34, 64, 91, 138, 234, 244, 238, 111, 99, 110, 126, 136, 143, 159, - 167, 165, 158, 114, 36, 20, 10, 12, 18, 9, 52, 83, 204, 202, 194, 158, - 151, 151, 159, 142, 144, 132, 128, 130, 118, 41, 37, 32, 42, 52, 55, 37, - 33, 59, 213, 206, 190, 108, 107, 115, 130, 140, 148, 148, 150, 165, 169, 167, - 169, 169, 161, 159, 146, 87, 20, 5, 6, 8, 9, 16, 14, 17, 17, 17, - 17, 17, 22, 22, 22, 20, 33, 48, 95, 221, 238, 238, 242, 241, 238, 229, - 218, 197, 194, 185, 186, 190, 201, 205, 208, 218, 221, 224, 220, 224, 210, 171, - 198, 197, 206, 205, 197, 178, 182, 175, 167, 150, 139, 132, 110, 55, 22, 20, - 48, 41, 46, 61, 60, 56, 49, 56, 64, 65, 64, 52, 104, 193, 201, 183, - 106, 104, 114, 127, 139, 151, 162, 165, 167, 165, 166, 163, 167, 165, 161, 136, - 77, 16, 12, 4, 2, 4, 6, 2, 4, 9, 6, 20, 30, 37, 30, 44, - 40, 41, 44, 48, 40, 41, 13, 42, 122, 159, 158, 118, 114, 128, 144, 154, - 159, 166, 173, 178, 185, 191, 178, 118, 56, 79, 102, 174, 212, 210, 210, 193, - 178, 166, 161, 158, 162, 155, 150, 148, 128, 119, 17, 12, 13, 22, 20, 6, - 103, 97, 93, 97, 107, 208, 213, 175, 114, 107, 120, 142, 151, 158, 161, 159, - 159, 157, 146, 128, 135, 131, 126, 81, 22, 20, 36, 45, 61, 68, 60, 63, - 34, 100, 116, 122, 118, 112, 134, 128, 131, 122, 123, 97, 73, 20, 84, 146, - 139, 142, 136, 126, 104, 92, 61, 41, 22, 93, 102, 87, 87, 83, 92, 83, - 81, 241, 230, 233, 102, 92, 107, 130, 136, 148, 162, 167, 170, 159, 158, 144, - 135, 128, 21, 12, 10, 12, 6, 29, 29, 14, 26, 12, 44, 21, 102, 95, - 143, 221, 220, 216, 115, 106, 114, 136, 135, 146, 157, 169, 178, 179, 179, 177, - 174, 170, 161, 92, 34, 29, 30, 37, 64, 126, 201, 198, 163, 153, 171, 177, - 189, 195, 198, 198, 198, 197, 191, 167, 155, 88, 41, 24, 25, 22, 53, 75, - 91, 100, 194, 214, 198, 170, 186, 187, 185, 186, 171, 170, 140, 132, 123, 116, - 68, 37, 49, 44, 46, 61, 95, 76, 81, 79, 88, 85, 104, 199, 244, 242, - 246, 248, 218, 158, 116, 111, 111, 115, 134, 120, 63, 32, 28, 32, 29, 48, - 97, 179, 193, 185, 159, 166, 166, 171, 130, 127, 118, 93, 49, 67, 64, 75, - 59, 61, 60, 61, 56, 63, 128, 123, 116, 107, 111, 106, 95, 100, 88, 76, - 69, 93, 123, 118, 107, 104, 99, 103, 103, 112, 100, 100, 76, 16, 69, 44, - 25, 17, 13, 21, 26, 49, 29, 12, 22, 75, 88, 72, 108, 244, 244, 238, - 106, 99, 111, 132, 142, 151, 161, 169, 169, 173, 163, 158, 142, 131, 134, 131, - 120, 9, 14, 18, 48, 49, 61, 60, 71, 56, 61, 61, 52, 37, 81, 104, - 91, 75, 73, 83, 81, 84, 87, 163, 224, 205, 217, 205, 161, 100, 80, 60, - 69, 57, 51, 55, 56, 199, 199, 187, 118, 120, 131, 139, 134, 135, 146, 140, - 135, 122, 115, 69, 18, 9, 21, 36, 48, 42, 45, 65, 40, 33, 64, 93, - 142, 234, 242, 240, 118, 102, 114, 127, 140, 147, 161, 167, 162, 154, 84, 32, - 17, 12, 13, 20, 8, 57, 89, 202, 206, 204, 124, 147, 150, 157, 128, 134, - 138, 127, 128, 115, 38, 29, 30, 38, 40, 46, 46, 38, 59, 218, 209, 193, - 107, 108, 114, 127, 140, 148, 154, 167, 170, 174, 175, 170, 167, 165, 150, 85, - 22, 5, 9, 10, 9, 14, 16, 24, 30, 28, 29, 25, 26, 22, 26, 32, - 25, 36, 65, 169, 238, 238, 238, 234, 230, 197, 175, 151, 150, 147, 151, 154, - 158, 163, 167, 171, 174, 178, 181, 191, 195, 204, 198, 199, 195, 194, 197, 198, - 195, 187, 178, 169, 154, 146, 128, 119, 75, 28, 32, 44, 49, 42, 51, 40, - 46, 55, 60, 59, 48, 44, 45, 88, 197, 205, 193, 107, 104, 114, 128, 138, - 154, 162, 165, 166, 167, 166, 169, 166, 165, 150, 96, 26, 13, 4, 6, 9, - 6, 8, 8, 14, 12, 9, 33, 40, 42, 41, 44, 32, 28, 22, 30, 33, - 45, 1, 44, 100, 143, 170, 134, 112, 120, 138, 148, 155, 162, 170, 177, 182, - 195, 194, 185, 138, 110, 148, 204, 204, 212, 208, 189, 191, 173, 179, 165, 162, - 161, 154, 150, 135, 119, 24, 12, 5, 30, 5, 59, 69, 89, 93, 81, 88, - 191, 216, 197, 114, 103, 116, 139, 151, 155, 158, 161, 157, 154, 138, 136, 135, - 131, 126, 97, 25, 22, 36, 48, 60, 64, 55, 69, 41, 103, 132, 126, 130, - 128, 122, 126, 124, 128, 112, 93, 76, 20, 91, 139, 166, 189, 162, 140, 116, - 103, 67, 44, 24, 87, 97, 89, 102, 84, 89, 79, 91, 240, 237, 232, 93, - 93, 106, 127, 134, 147, 162, 169, 167, 162, 157, 147, 138, 127, 18, 13, 10, - 10, 16, 29, 29, 17, 17, 14, 34, 21, 88, 100, 143, 226, 225, 217, 118, - 118, 114, 123, 136, 155, 158, 171, 177, 181, 181, 177, 174, 167, 143, 53, 29, - 25, 30, 49, 53, 107, 191, 204, 171, 150, 154, 173, 182, 191, 198, 198, 199, - 199, 195, 191, 169, 124, 51, 29, 25, 29, 55, 76, 91, 91, 190, 220, 212, - 175, 170, 185, 174, 185, 173, 166, 147, 136, 128, 131, 85, 36, 37, 45, 41, - 60, 83, 89, 93, 88, 77, 93, 130, 229, 237, 242, 245, 224, 146, 114, 114, - 114, 120, 139, 140, 83, 49, 26, 29, 32, 30, 51, 112, 197, 191, 162, 165, - 170, 169, 174, 134, 130, 115, 107, 84, 46, 56, 51, 56, 49, 60, 59, 52, - 22, 118, 128, 100, 115, 110, 116, 126, 120, 97, 76, 67, 88, 126, 111, 107, - 99, 97, 103, 100, 96, 99, 108, 42, 14, 44, 51, 38, 13, 16, 14, 20, - 37, 25, 13, 18, 75, 85, 67, 91, 242, 244, 240, 110, 100, 110, 132, 143, - 150, 161, 167, 170, 174, 162, 158, 136, 131, 131, 131, 119, 9, 14, 14, 25, - 51, 57, 72, 65, 52, 72, 55, 59, 41, 72, 108, 80, 95, 77, 69, 87, - 77, 95, 198, 226, 208, 213, 183, 139, 97, 67, 49, 53, 59, 49, 55, 57, - 206, 204, 194, 122, 123, 131, 136, 139, 140, 131, 146, 132, 120, 115, 59, 17, - 10, 20, 38, 46, 40, 44, 76, 41, 29, 63, 95, 138, 232, 241, 240, 120, - 103, 114, 126, 138, 146, 161, 165, 163, 144, 61, 24, 14, 12, 13, 24, 10, - 56, 85, 205, 208, 232, 127, 147, 147, 148, 139, 131, 130, 127, 124, 112, 34, - 30, 24, 38, 37, 46, 36, 42, 59, 222, 220, 204, 107, 106, 115, 126, 138, - 148, 154, 166, 173, 173, 171, 167, 163, 158, 111, 32, 6, 9, 9, 8, 9, - 17, 26, 33, 33, 33, 26, 28, 26, 28, 28, 34, 32, 42, 89, 218, 236, - 236, 229, 214, 179, 146, 134, 135, 140, 148, 157, 166, 173, 183, 193, 197, 201, - 202, 199, 183, 187, 191, 194, 195, 198, 202, 201, 205, 202, 182, 178, 163, 154, - 147, 132, 128, 95, 36, 30, 34, 41, 59, 46, 48, 52, 38, 33, 49, 60, - 60, 60, 76, 198, 210, 199, 110, 106, 115, 128, 139, 154, 162, 165, 167, 166, - 171, 169, 165, 157, 116, 40, 16, 6, 6, 9, 9, 8, 10, 12, 8, 9, - 5, 36, 42, 33, 26, 28, 33, 28, 18, 36, 37, 37, 4, 46, 91, 115, - 165, 146, 116, 110, 128, 136, 154, 161, 169, 173, 182, 187, 199, 198, 195, 182, - 204, 210, 210, 212, 212, 193, 181, 179, 173, 167, 169, 159, 153, 151, 135, 123, - 18, 12, 9, 20, 6, 1, 120, 81, 84, 80, 71, 130, 213, 205, 120, 102, - 112, 130, 144, 153, 158, 161, 159, 157, 147, 132, 136, 128, 128, 111, 32, 25, - 36, 44, 57, 68, 59, 76, 40, 77, 118, 126, 124, 120, 123, 123, 134, 119, - 115, 95, 77, 24, 118, 159, 210, 216, 225, 183, 140, 115, 81, 42, 22, 88, - 96, 97, 87, 85, 87, 80, 84, 238, 241, 225, 97, 92, 103, 122, 134, 146, - 162, 169, 167, 162, 158, 147, 138, 128, 20, 9, 16, 10, 14, 25, 33, 30, - 30, 8, 30, 29, 87, 96, 114, 228, 225, 221, 127, 118, 126, 122, 142, 138, - 162, 167, 179, 173, 181, 178, 169, 165, 123, 41, 28, 22, 32, 42, 55, 88, - 183, 208, 189, 151, 148, 167, 178, 187, 191, 198, 199, 201, 199, 195, 175, 157, - 69, 32, 24, 26, 55, 75, 89, 91, 170, 224, 216, 183, 185, 181, 186, 186, - 177, 161, 148, 139, 130, 122, 102, 44, 34, 45, 41, 56, 87, 96, 80, 80, - 92, 88, 181, 234, 241, 244, 233, 157, 116, 116, 120, 127, 143, 142, 146, 71, - 45, 26, 18, 34, 37, 68, 89, 202, 198, 165, 166, 170, 163, 165, 166, 132, - 124, 120, 93, 46, 44, 52, 55, 48, 51, 57, 56, 42, 122, 136, 106, 115, - 110, 116, 126, 107, 92, 88, 59, 99, 127, 116, 96, 102, 96, 108, 104, 102, - 106, 100, 60, 0, 53, 41, 25, 13, 30, 41, 51, 38, 13, 12, 16, 71, - 83, 61, 89, 244, 242, 232, 108, 99, 111, 131, 139, 154, 161, 166, 170, 173, - 161, 154, 146, 136, 131, 130, 115, 9, 14, 17, 32, 53, 65, 67, 63, 51, - 64, 55, 53, 38, 81, 97, 75, 84, 89, 80, 79, 75, 100, 214, 220, 224, - 218, 177, 115, 85, 49, 32, 53, 49, 49, 51, 60, 210, 208, 202, 126, 123, - 134, 138, 142, 139, 132, 150, 130, 116, 110, 46, 17, 10, 18, 38, 45, 38, - 45, 64, 42, 25, 77, 89, 95, 229, 241, 237, 119, 104, 114, 124, 135, 143, - 162, 163, 161, 142, 41, 17, 14, 14, 14, 17, 9, 53, 88, 205, 206, 208, - 146, 138, 143, 143, 139, 131, 130, 123, 122, 107, 29, 25, 24, 34, 37, 41, - 37, 34, 52, 228, 224, 210, 111, 106, 116, 127, 136, 147, 155, 166, 173, 173, - 169, 157, 161, 136, 49, 6, 10, 10, 9, 14, 16, 20, 38, 41, 36, 32, - 30, 33, 30, 29, 42, 30, 29, 63, 179, 216, 230, 218, 195, 159, 135, 124, - 132, 142, 157, 166, 175, 182, 190, 201, 210, 213, 216, 217, 216, 213, 198, 193, - 194, 189, 185, 183, 206, 206, 206, 183, 178, 161, 158, 150, 136, 128, 106, 52, - 30, 28, 49, 46, 56, 49, 44, 40, 42, 26, 38, 56, 33, 64, 195, 216, - 206, 108, 106, 115, 130, 138, 154, 161, 165, 167, 167, 170, 166, 162, 136, 53, - 14, 12, 9, 12, 9, 13, 13, 12, 8, 8, 9, 5, 41, 42, 24, 26, - 25, 30, 18, 22, 42, 29, 44, 5, 42, 73, 95, 126, 165, 124, 112, 116, - 132, 148, 158, 166, 170, 177, 186, 194, 201, 202, 205, 208, 205, 209, 221, 208, - 190, 183, 183, 175, 170, 163, 161, 153, 150, 135, 122, 16, 12, 5, 12, 63, - 72, 114, 68, 80, 83, 79, 95, 193, 206, 132, 103, 111, 124, 142, 150, 154, - 158, 163, 165, 158, 148, 126, 126, 127, 116, 44, 22, 34, 37, 55, 68, 59, - 65, 61, 51, 111, 126, 126, 130, 124, 126, 126, 123, 108, 99, 81, 34, 155, - 193, 226, 209, 204, 198, 209, 139, 102, 46, 24, 81, 89, 91, 79, 77, 81, - 72, 79, 240, 240, 230, 102, 95, 99, 118, 132, 148, 161, 170, 170, 162, 158, - 147, 138, 126, 17, 12, 13, 13, 12, 24, 29, 37, 34, 30, 26, 32, 79, - 89, 104, 226, 226, 222, 128, 104, 114, 124, 134, 136, 153, 163, 174, 181, 183, - 178, 167, 157, 100, 34, 26, 22, 32, 48, 60, 81, 171, 216, 198, 155, 144, - 158, 173, 182, 190, 193, 197, 201, 202, 198, 193, 174, 102, 36, 25, 28, 55, - 75, 80, 83, 144, 221, 221, 187, 169, 181, 187, 177, 165, 146, 140, 140, 134, - 123, 115, 60, 36, 40, 38, 55, 87, 97, 85, 85, 87, 79, 197, 238, 241, - 242, 190, 124, 118, 124, 130, 130, 144, 148, 148, 65, 26, 24, 22, 29, 36, - 55, 92, 205, 206, 183, 163, 169, 167, 165, 167, 136, 132, 119, 91, 40, 40, - 51, 44, 51, 55, 59, 40, 71, 111, 122, 106, 99, 97, 106, 102, 106, 89, - 72, 41, 107, 127, 116, 96, 106, 96, 106, 104, 103, 96, 97, 56, 0, 51, - 42, 33, 13, 16, 22, 16, 12, 24, 16, 17, 72, 83, 68, 85, 241, 240, - 226, 104, 99, 112, 132, 143, 153, 161, 167, 166, 173, 173, 161, 154, 139, 124, - 127, 112, 10, 16, 16, 46, 51, 57, 67, 73, 71, 69, 52, 56, 38, 75, - 97, 73, 72, 84, 67, 83, 76, 110, 218, 232, 222, 169, 118, 106, 61, 42, - 41, 48, 45, 42, 48, 60, 213, 216, 210, 130, 124, 135, 143, 158, 144, 144, - 148, 120, 115, 107, 33, 14, 10, 17, 38, 41, 38, 45, 64, 41, 22, 88, - 91, 71, 225, 240, 234, 120, 104, 114, 126, 138, 146, 162, 162, 158, 132, 34, - 16, 14, 13, 13, 17, 10, 44, 96, 209, 214, 206, 140, 135, 139, 144, 138, - 132, 132, 131, 115, 104, 25, 22, 18, 30, 32, 34, 45, 53, 55, 228, 228, - 216, 112, 108, 118, 127, 138, 148, 157, 161, 173, 169, 163, 159, 151, 96, 21, - 8, 10, 10, 9, 8, 14, 18, 38, 42, 60, 59, 57, 52, 42, 34, 30, - 40, 48, 122, 217, 225, 212, 179, 144, 126, 124, 136, 146, 157, 169, 175, 185, - 191, 199, 208, 199, 148, 116, 144, 193, 217, 214, 201, 193, 187, 195, 197, 206, - 204, 202, 183, 175, 163, 157, 147, 134, 127, 112, 71, 32, 22, 40, 44, 55, - 60, 45, 40, 42, 34, 41, 57, 20, 77, 204, 218, 213, 112, 107, 118, 131, - 138, 154, 161, 166, 169, 170, 170, 163, 153, 96, 25, 16, 12, 12, 10, 17, - 18, 13, 10, 10, 9, 12, 9, 40, 46, 30, 26, 16, 20, 22, 40, 33, - 25, 26, 2, 44, 63, 81, 104, 159, 158, 114, 106, 124, 142, 155, 162, 169, - 175, 185, 186, 191, 199, 197, 198, 212, 217, 209, 195, 189, 186, 179, 175, 170, - 163, 161, 153, 150, 132, 120, 13, 9, 9, 17, 5, 10, 97, 110, 87, 75, - 71, 64, 132, 204, 162, 104, 107, 118, 134, 144, 150, 158, 166, 161, 162, 153, - 126, 122, 128, 123, 61, 25, 28, 44, 49, 65, 63, 71, 59, 48, 106, 123, - 130, 126, 130, 130, 128, 124, 114, 102, 79, 34, 167, 206, 224, 216, 220, 201, - 179, 142, 100, 42, 25, 80, 97, 91, 93, 80, 83, 75, 96, 240, 241, 233, - 107, 93, 97, 112, 136, 146, 161, 167, 167, 163, 158, 147, 139, 128, 22, 14, - 8, 13, 14, 21, 21, 36, 33, 42, 16, 13, 79, 87, 103, 225, 225, 220, - 115, 103, 115, 127, 122, 127, 142, 158, 170, 177, 177, 174, 161, 147, 73, 29, - 26, 20, 34, 63, 53, 77, 153, 216, 206, 159, 142, 148, 167, 177, 183, 189, - 190, 195, 201, 201, 194, 181, 142, 48, 30, 24, 51, 72, 79, 84, 120, 218, - 224, 191, 171, 182, 182, 175, 154, 143, 136, 143, 139, 126, 124, 76, 34, 34, - 40, 53, 84, 102, 81, 72, 75, 85, 208, 232, 240, 238, 157, 118, 123, 131, - 135, 139, 148, 151, 154, 59, 28, 24, 17, 29, 34, 55, 81, 205, 212, 204, - 169, 170, 169, 165, 171, 142, 136, 116, 88, 33, 33, 42, 48, 44, 48, 51, - 46, 60, 120, 118, 108, 103, 103, 104, 100, 112, 88, 65, 56, 85, 108, 114, - 102, 104, 104, 104, 107, 103, 103, 95, 57, 13, 53, 40, 34, 8, 16, 40, - 12, 12, 25, 10, 18, 79, 81, 69, 89, 240, 236, 178, 100, 99, 112, 132, - 139, 148, 155, 163, 166, 173, 174, 169, 158, 144, 128, 126, 116, 10, 17, 18, - 49, 42, 59, 61, 64, 72, 55, 53, 48, 36, 83, 88, 73, 79, 80, 75, - 83, 77, 118, 230, 234, 221, 139, 107, 88, 49, 38, 33, 51, 45, 41, 55, - 67, 213, 216, 210, 131, 126, 139, 163, 162, 161, 154, 147, 118, 116, 107, 29, - 16, 12, 18, 37, 40, 38, 46, 52, 34, 22, 60, 89, 103, 224, 238, 236, - 123, 103, 115, 124, 138, 146, 163, 163, 159, 124, 30, 16, 13, 16, 13, 18, - 10, 48, 88, 209, 213, 228, 119, 132, 134, 140, 132, 136, 139, 134, 114, 92, - 25, 22, 22, 29, 32, 29, 38, 32, 53, 232, 221, 214, 111, 108, 119, 130, - 139, 151, 159, 161, 171, 167, 161, 159, 139, 52, 10, 10, 10, 10, 12, 14, - 16, 38, 40, 53, 46, 48, 55, 64, 42, 32, 26, 36, 73, 199, 222, 220, - 197, 136, 112, 124, 135, 147, 158, 167, 174, 182, 186, 195, 202, 202, 104, 64, - 59, 69, 106, 154, 218, 209, 204, 190, 197, 205, 208, 208, 195, 179, 175, 167, - 159, 147, 134, 122, 116, 83, 38, 40, 41, 46, 51, 48, 44, 38, 45, 41, - 37, 56, 34, 64, 217, 220, 216, 112, 108, 119, 131, 139, 153, 162, 165, 167, - 171, 166, 158, 136, 56, 14, 12, 13, 13, 21, 17, 16, 10, 9, 13, 10, - 13, 12, 45, 49, 32, 29, 34, 29, 33, 41, 20, 26, 29, 1, 41, 59, - 77, 81, 134, 171, 123, 104, 120, 135, 151, 161, 169, 174, 181, 187, 189, 189, - 187, 187, 190, 198, 199, 195, 193, 193, 182, 174, 171, 163, 162, 154, 151, 135, - 116, 12, 10, 6, 25, 9, 9, 95, 92, 93, 67, 72, 67, 96, 183, 189, - 108, 106, 114, 123, 140, 153, 159, 167, 165, 165, 154, 123, 123, 128, 126, 92, - 29, 26, 32, 37, 48, 69, 68, 64, 45, 87, 126, 127, 123, 128, 126, 128, - 124, 111, 97, 87, 28, 182, 213, 224, 217, 185, 163, 134, 107, 95, 40, 25, - 56, 93, 96, 100, 75, 81, 73, 85, 241, 242, 234, 107, 97, 96, 115, 130, - 143, 158, 166, 167, 165, 155, 144, 140, 127, 21, 16, 20, 14, 17, 32, 24, - 24, 29, 37, 25, 26, 69, 81, 96, 222, 233, 222, 126, 115, 115, 120, 120, - 126, 132, 146, 159, 177, 175, 162, 158, 140, 57, 30, 22, 20, 34, 55, 49, - 68, 138, 210, 212, 174, 138, 140, 159, 170, 175, 182, 186, 189, 194, 197, 195, - 181, 169, 79, 29, 25, 48, 63, 77, 81, 106, 213, 224, 194, 170, 181, 185, - 166, 150, 131, 128, 130, 136, 128, 126, 97, 44, 30, 38, 49, 81, 88, 80, - 75, 87, 88, 209, 232, 241, 218, 142, 122, 128, 135, 134, 150, 154, 159, 161, - 56, 28, 26, 22, 28, 38, 44, 75, 206, 216, 212, 171, 170, 174, 167, 170, - 143, 134, 118, 88, 29, 29, 38, 38, 37, 41, 45, 16, 64, 112, 111, 108, - 108, 107, 102, 99, 122, 91, 63, 51, 107, 123, 99, 106, 108, 116, 123, 114, - 106, 100, 102, 41, 16, 36, 37, 41, 10, 16, 14, 12, 12, 10, 13, 18, - 73, 81, 68, 81, 236, 236, 166, 99, 96, 111, 120, 132, 142, 151, 162, 166, - 175, 173, 169, 158, 146, 126, 128, 115, 12, 18, 16, 33, 41, 48, 60, 64, - 64, 56, 53, 52, 34, 64, 84, 73, 75, 72, 68, 72, 79, 157, 244, 236, - 210, 122, 103, 77, 34, 37, 37, 48, 44, 40, 49, 67, 216, 217, 210, 131, - 127, 139, 163, 157, 161, 148, 150, 116, 116, 106, 30, 14, 10, 20, 34, 38, - 37, 37, 48, 34, 17, 61, 95, 99, 224, 237, 236, 120, 104, 112, 126, 138, - 148, 165, 161, 163, 123, 26, 14, 14, 17, 13, 24, 12, 41, 79, 206, 214, - 210, 134, 127, 131, 140, 135, 132, 136, 132, 114, 85, 20, 20, 20, 26, 30, - 33, 34, 34, 76, 232, 233, 217, 112, 108, 119, 130, 139, 153, 159, 163, 170, - 165, 161, 157, 110, 30, 10, 12, 13, 9, 12, 9, 10, 44, 46, 55, 71, - 59, 44, 64, 41, 38, 34, 42, 132, 213, 218, 210, 167, 112, 119, 132, 142, - 157, 166, 170, 179, 179, 190, 194, 205, 165, 72, 37, 22, 28, 46, 103, 198, - 218, 209, 195, 186, 208, 206, 206, 204, 189, 175, 169, 158, 147, 131, 118, 118, - 92, 42, 40, 36, 53, 45, 48, 57, 37, 45, 36, 46, 51, 25, 72, 217, - 226, 217, 114, 110, 119, 131, 138, 154, 161, 161, 166, 166, 161, 155, 110, 33, - 14, 12, 17, 18, 24, 20, 13, 10, 12, 16, 9, 13, 9, 42, 37, 42, - 24, 37, 33, 33, 33, 33, 28, 24, 4, 36, 55, 64, 63, 92, 162, 138, - 103, 110, 131, 146, 157, 166, 173, 178, 185, 191, 191, 194, 193, 190, 189, 191, - 202, 193, 194, 185, 177, 169, 165, 165, 155, 148, 134, 120, 13, 9, 6, 18, - 12, 9, 69, 69, 72, 79, 63, 61, 67, 128, 185, 122, 102, 107, 115, 138, - 150, 158, 162, 167, 161, 147, 128, 123, 130, 124, 110, 36, 30, 41, 38, 44, - 67, 56, 72, 49, 81, 112, 122, 131, 128, 132, 126, 120, 103, 100, 88, 32, - 181, 224, 229, 218, 165, 124, 97, 92, 73, 34, 25, 44, 83, 93, 97, 77, - 76, 71, 87, 240, 241, 230, 103, 95, 99, 119, 131, 140, 158, 163, 167, 162, - 155, 146, 142, 124, 22, 18, 17, 14, 17, 26, 24, 13, 25, 26, 30, 36, - 56, 88, 112, 228, 230, 222, 127, 118, 123, 119, 118, 123, 136, 150, 146, 154, - 157, 153, 154, 131, 40, 26, 20, 20, 33, 37, 52, 67, 99, 202, 213, 183, - 138, 135, 151, 163, 170, 171, 175, 181, 189, 194, 194, 189, 181, 106, 34, 24, - 49, 56, 75, 80, 91, 205, 222, 204, 173, 179, 185, 167, 157, 147, 147, 143, - 130, 131, 122, 108, 53, 33, 36, 34, 68, 83, 76, 72, 85, 81, 208, 234, - 241, 187, 134, 127, 131, 136, 135, 147, 154, 159, 161, 55, 25, 24, 17, 25, - 41, 61, 72, 204, 218, 217, 171, 174, 173, 163, 171, 147, 134, 120, 84, 29, - 25, 30, 34, 36, 40, 48, 29, 84, 115, 120, 116, 108, 118, 104, 107, 92, - 88, 84, 45, 99, 115, 123, 119, 128, 118, 115, 107, 114, 108, 93, 61, 0, - 51, 36, 12, 14, 10, 6, 12, 10, 16, 14, 18, 59, 80, 61, 84, 233, - 230, 178, 103, 100, 108, 114, 126, 134, 148, 161, 167, 173, 174, 162, 157, 143, - 128, 132, 111, 13, 17, 18, 33, 40, 49, 57, 61, 56, 67, 53, 49, 34, - 63, 77, 79, 63, 77, 75, 69, 91, 197, 237, 237, 208, 122, 103, 63, 34, - 32, 36, 36, 42, 36, 48, 63, 212, 218, 206, 130, 128, 142, 167, 162, 154, - 148, 147, 119, 115, 102, 24, 14, 14, 22, 30, 38, 36, 45, 46, 37, 16, - 69, 89, 69, 221, 237, 232, 118, 106, 116, 126, 138, 153, 165, 162, 159, 116, - 32, 16, 14, 10, 17, 21, 12, 34, 67, 206, 212, 201, 130, 126, 130, 140, - 138, 130, 134, 132, 114, 85, 17, 16, 13, 24, 28, 34, 32, 30, 57, 233, - 226, 220, 112, 108, 119, 131, 140, 153, 161, 163, 169, 161, 155, 146, 75, 14, - 13, 14, 12, 12, 16, 13, 12, 38, 49, 55, 65, 68, 45, 59, 42, 40, - 34, 37, 158, 209, 216, 201, 135, 107, 120, 134, 147, 159, 163, 175, 181, 185, - 191, 197, 208, 130, 42, 20, 18, 22, 41, 81, 159, 221, 212, 206, 182, 206, - 210, 213, 205, 193, 177, 170, 161, 147, 134, 123, 122, 107, 52, 41, 32, 36, - 45, 48, 42, 21, 42, 29, 57, 44, 36, 60, 210, 226, 224, 112, 107, 118, - 131, 138, 153, 162, 158, 166, 165, 159, 144, 81, 21, 16, 16, 17, 21, 17, - 14, 14, 13, 14, 13, 12, 13, 9, 41, 42, 25, 38, 38, 34, 36, 34, - 34, 24, 21, 1, 29, 45, 51, 64, 79, 124, 155, 119, 100, 119, 139, 154, - 162, 173, 177, 183, 187, 183, 182, 186, 195, 191, 185, 189, 201, 194, 186, 179, - 173, 166, 165, 157, 150, 139, 120, 8, 12, 8, 10, 16, 2, 60, 59, 60, - 53, 48, 53, 55, 84, 174, 167, 102, 104, 115, 136, 148, 155, 157, 155, 151, - 148, 122, 123, 123, 126, 123, 65, 30, 30, 36, 40, 64, 64, 73, 55, 61, - 100, 111, 114, 116, 110, 114, 114, 107, 100, 89, 44, 186, 225, 233, 197, 150, - 102, 95, 95, 68, 34, 28, 34, 52, 60, 73, 65, 76, 67, 79, 238, 240, - 222, 104, 93, 102, 116, 126, 136, 157, 167, 165, 162, 155, 143, 142, 124, 22, - 20, 22, 13, 17, 8, 22, 24, 12, 29, 34, 28, 49, 81, 106, 226, 229, - 221, 128, 104, 111, 127, 128, 127, 138, 140, 139, 151, 150, 150, 148, 127, 41, - 29, 25, 21, 33, 42, 56, 69, 80, 191, 214, 193, 142, 132, 140, 157, 163, - 166, 169, 174, 181, 189, 190, 189, 182, 140, 49, 28, 42, 55, 69, 69, 79, - 194, 225, 212, 174, 175, 185, 173, 161, 157, 150, 147, 144, 130, 122, 120, 76, - 36, 36, 33, 63, 89, 100, 77, 80, 71, 187, 236, 241, 181, 128, 132, 139, - 142, 136, 148, 158, 162, 162, 53, 26, 21, 17, 24, 32, 49, 77, 213, 220, - 218, 173, 173, 174, 167, 171, 147, 135, 123, 85, 28, 25, 28, 32, 48, 33, - 46, 30, 80, 88, 77, 85, 84, 85, 84, 87, 83, 83, 60, 32, 96, 108, - 110, 100, 115, 106, 99, 95, 106, 102, 85, 40, 0, 44, 14, 18, 13, 24, - 12, 30, 12, 17, 17, 16, 60, 77, 71, 84, 237, 238, 220, 104, 100, 106, - 114, 114, 134, 153, 162, 173, 175, 167, 157, 147, 132, 127, 123, 107, 16, 20, - 20, 30, 44, 44, 53, 57, 57, 63, 51, 48, 34, 61, 80, 79, 69, 67, - 73, 72, 107, 220, 237, 241, 209, 126, 100, 52, 32, 26, 38, 29, 42, 41, - 38, 53, 214, 213, 206, 126, 128, 140, 159, 154, 153, 144, 136, 118, 114, 97, - 25, 12, 13, 18, 26, 37, 34, 38, 65, 36, 13, 76, 87, 80, 214, 234, - 226, 122, 107, 116, 127, 140, 154, 158, 161, 162, 131, 41, 16, 17, 17, 16, - 22, 12, 30, 60, 206, 205, 199, 122, 127, 130, 140, 131, 132, 130, 132, 114, - 80, 16, 17, 10, 29, 25, 26, 25, 29, 55, 230, 228, 220, 114, 107, 118, - 128, 139, 153, 162, 166, 166, 158, 155, 140, 53, 13, 13, 13, 13, 10, 9, - 16, 12, 49, 55, 49, 44, 38, 44, 41, 41, 38, 30, 37, 165, 208, 201, - 191, 119, 108, 120, 134, 147, 166, 166, 178, 182, 185, 191, 197, 201, 116, 37, - 24, 18, 18, 33, 60, 135, 222, 214, 208, 190, 204, 208, 209, 208, 201, 179, - 174, 161, 153, 135, 126, 119, 112, 72, 45, 45, 36, 40, 49, 42, 38, 29, - 25, 25, 26, 25, 57, 197, 225, 225, 115, 107, 118, 131, 136, 153, 159, 158, - 165, 162, 154, 136, 59, 17, 16, 16, 20, 18, 20, 16, 13, 13, 12, 12, - 12, 16, 13, 33, 36, 37, 42, 38, 38, 37, 34, 37, 20, 21, 1, 26, - 38, 52, 57, 71, 80, 162, 138, 102, 110, 135, 150, 159, 169, 177, 181, 181, - 182, 179, 183, 187, 197, 197, 183, 190, 194, 189, 183, 174, 167, 167, 157, 151, - 139, 120, 8, 9, 8, 18, 13, 5, 59, 46, 52, 60, 42, 41, 38, 48, - 100, 186, 114, 102, 112, 126, 142, 148, 155, 158, 150, 134, 122, 122, 122, 123, - 126, 99, 41, 36, 40, 42, 49, 53, 53, 57, 69, 84, 73, 75, 81, 77, - 80, 77, 108, 100, 85, 36, 170, 224, 236, 179, 120, 102, 95, 92, 67, 32, - 26, 34, 40, 42, 46, 48, 49, 75, 83, 240, 238, 229, 107, 88, 97, 115, - 116, 134, 148, 158, 163, 161, 154, 142, 140, 126, 24, 20, 9, 9, 12, 13, - 17, 5, 5, 20, 29, 30, 42, 80, 92, 224, 228, 228, 123, 99, 111, 122, - 130, 142, 143, 138, 134, 140, 135, 147, 144, 122, 45, 26, 26, 14, 36, 34, - 56, 53, 73, 182, 214, 195, 139, 130, 135, 150, 155, 162, 163, 169, 177, 183, - 187, 186, 181, 161, 73, 34, 34, 51, 60, 68, 79, 175, 226, 217, 179, 169, - 183, 187, 161, 169, 162, 154, 148, 144, 131, 122, 111, 52, 34, 32, 55, 85, - 89, 68, 69, 76, 177, 221, 240, 169, 126, 135, 142, 143, 136, 150, 166, 170, - 170, 61, 34, 20, 21, 24, 33, 65, 89, 221, 224, 221, 177, 175, 175, 169, - 170, 151, 138, 126, 81, 25, 28, 25, 28, 29, 28, 33, 40, 42, 64, 64, - 67, 68, 73, 69, 64, 77, 80, 42, 40, 37, 83, 75, 65, 60, 77, 63, - 53, 51, 72, 49, 9, 24, 16, 12, 10, 12, 17, 14, 13, 13, 22, 17, - 17, 55, 67, 73, 97, 238, 234, 226, 106, 104, 108, 114, 122, 135, 159, 161, - 167, 174, 170, 159, 146, 122, 130, 132, 103, 17, 21, 21, 26, 32, 37, 44, - 51, 53, 49, 49, 46, 32, 64, 69, 73, 63, 65, 65, 75, 130, 240, 245, - 240, 190, 120, 100, 44, 29, 28, 30, 34, 33, 36, 40, 48, 214, 218, 209, - 130, 130, 139, 153, 155, 154, 151, 119, 119, 114, 95, 20, 14, 10, 20, 24, - 32, 36, 37, 49, 30, 20, 42, 77, 76, 206, 230, 228, 122, 108, 118, 128, - 143, 154, 165, 163, 162, 139, 46, 16, 17, 17, 14, 18, 10, 49, 79, 199, - 212, 209, 128, 124, 124, 134, 134, 131, 128, 126, 112, 72, 16, 13, 12, 20, - 17, 22, 28, 30, 49, 230, 229, 225, 116, 110, 115, 124, 140, 154, 162, 166, - 167, 158, 154, 139, 45, 13, 16, 16, 25, 17, 12, 18, 17, 44, 52, 41, - 46, 46, 44, 41, 49, 41, 32, 34, 163, 202, 199, 167, 106, 111, 119, 130, - 148, 163, 166, 171, 175, 183, 189, 194, 208, 107, 37, 26, 21, 21, 21, 42, - 127, 225, 220, 210, 189, 194, 206, 206, 213, 208, 191, 174, 163, 153, 143, 134, - 119, 119, 88, 51, 52, 29, 30, 34, 29, 40, 21, 4, 18, 13, 22, 61, - 181, 221, 226, 115, 108, 119, 131, 135, 151, 159, 161, 163, 159, 151, 130, 52, - 20, 16, 18, 24, 20, 25, 14, 18, 18, 20, 18, 21, 20, 14, 14, 30, - 51, 17, 20, 29, 30, 26, 32, 24, 21, 1, 25, 29, 34, 32, 59, 61, - 99, 153, 104, 99, 127, 143, 157, 166, 173, 174, 177, 177, 181, 182, 185, 187, - 195, 194, 185, 189, 189, 185, 178, 170, 167, 158, 154, 140, 122, 9, 9, 6, - 10, 4, 2, 55, 63, 68, 64, 61, 72, 68, 64, 49, 148, 167, 110, 106, - 112, 130, 142, 147, 153, 147, 138, 127, 122, 115, 126, 127, 120, 63, 40, 30, - 33, 34, 36, 33, 33, 37, 40, 40, 48, 53, 60, 64, 65, 80, 97, 92, - 38, 171, 220, 230, 169, 112, 93, 93, 91, 65, 30, 20, 26, 36, 36, 36, - 42, 42, 68, 68, 240, 237, 226, 107, 99, 96, 115, 127, 127, 143, 155, 166, - 162, 151, 142, 142, 118, 24, 24, 24, 17, 17, 24, 21, 22, 22, 38, 21, - 25, 42, 72, 102, 224, 229, 224, 126, 111, 114, 123, 128, 140, 134, 136, 132, - 135, 135, 144, 140, 118, 41, 37, 25, 26, 51, 67, 63, 65, 68, 171, 209, - 205, 144, 126, 134, 146, 153, 155, 162, 165, 170, 178, 183, 185, 182, 173, 95, - 38, 26, 40, 55, 64, 73, 153, 226, 220, 183, 169, 177, 187, 183, 154, 169, - 159, 155, 143, 144, 130, 123, 85, 37, 37, 52, 59, 65, 60, 76, 72, 134, - 226, 240, 169, 131, 136, 146, 142, 143, 157, 167, 173, 175, 68, 41, 26, 22, - 49, 64, 65, 100, 222, 226, 224, 183, 175, 178, 171, 171, 155, 140, 124, 89, - 24, 22, 22, 8, 6, 5, 8, 8, 20, 18, 9, 9, 18, 20, 18, 17, - 24, 28, 26, 38, 13, 13, 8, 10, 13, 14, 4, 9, 13, 14, 2, 8, - 38, 5, 30, 42, 48, 49, 56, 55, 53, 51, 44, 18, 77, 72, 77, 108, - 237, 238, 226, 106, 104, 111, 116, 127, 140, 155, 158, 163, 167, 171, 158, 146, - 126, 130, 127, 99, 21, 24, 21, 24, 29, 28, 29, 32, 33, 38, 37, 33, - 32, 55, 60, 53, 55, 63, 75, 75, 190, 241, 245, 236, 166, 115, 97, 37, - 28, 24, 20, 22, 25, 29, 40, 53, 220, 222, 208, 128, 123, 123, 144, 151, - 151, 144, 116, 108, 118, 88, 18, 12, 12, 14, 21, 26, 29, 28, 30, 28, - 16, 21, 80, 81, 199, 226, 226, 123, 110, 119, 128, 142, 153, 165, 167, 166, - 146, 68, 24, 18, 18, 10, 17, 29, 59, 112, 208, 214, 197, 126, 122, 123, - 130, 130, 134, 130, 123, 111, 65, 13, 12, 9, 12, 14, 13, 29, 34, 45, - 229, 233, 228, 114, 106, 114, 124, 140, 154, 162, 169, 166, 157, 151, 140, 42, - 13, 16, 16, 20, 26, 24, 13, 12, 26, 29, 25, 28, 34, 33, 28, 28, - 34, 37, 41, 150, 201, 183, 144, 100, 110, 116, 130, 147, 165, 171, 178, 173, - 183, 185, 187, 204, 131, 42, 29, 17, 26, 30, 52, 131, 222, 221, 216, 191, - 178, 202, 208, 208, 206, 194, 174, 166, 157, 151, 136, 118, 119, 102, 56, 56, - 44, 37, 33, 29, 4, 16, 12, 17, 13, 21, 72, 174, 228, 224, 115, 110, - 120, 131, 135, 151, 159, 161, 165, 158, 151, 131, 51, 18, 20, 22, 17, 17, - 14, 13, 12, 12, 9, 9, 8, 5, 14, 14, 5, 14, 10, 9, 5, 6, - 14, 22, 22, 16, 2, 28, 29, 32, 29, 25, 33, 67, 136, 122, 95, 120, - 140, 153, 162, 167, 170, 170, 169, 170, 171, 174, 183, 191, 198, 187, 186, 193, - 186, 178, 170, 167, 158, 154, 142, 123, 6, 6, 6, 10, 5, 4, 143, 134, - 119, 119, 119, 111, 118, 75, 69, 89, 161, 114, 104, 107, 115, 128, 143, 143, - 142, 134, 140, 140, 128, 116, 123, 127, 108, 51, 45, 59, 64, 67, 60, 64, - 71, 77, 92, 81, 87, 81, 65, 68, 59, 68, 88, 42, 159, 222, 233, 189, - 114, 96, 95, 85, 53, 26, 25, 26, 49, 63, 73, 72, 69, 72, 81, 226, - 232, 224, 100, 91, 106, 118, 118, 120, 130, 151, 165, 157, 150, 139, 139, 122, - 25, 24, 26, 9, 21, 24, 24, 17, 29, 45, 26, 24, 75, 72, 124, 221, - 226, 222, 123, 112, 122, 130, 128, 138, 124, 146, 139, 138, 132, 143, 136, 111, - 41, 36, 22, 34, 60, 69, 67, 68, 69, 151, 214, 201, 150, 123, 130, 139, - 148, 151, 159, 162, 166, 174, 179, 181, 178, 175, 124, 44, 40, 41, 63, 68, - 85, 142, 221, 224, 183, 166, 173, 182, 186, 179, 154, 166, 162, 155, 146, 144, - 127, 116, 57, 37, 38, 40, 48, 67, 83, 72, 118, 217, 228, 173, 134, 142, - 151, 139, 140, 155, 175, 179, 179, 80, 32, 24, 16, 38, 64, 73, 147, 226, - 226, 224, 179, 179, 175, 169, 169, 155, 140, 126, 88, 28, 24, 24, 18, 30, - 20, 29, 18, 77, 83, 76, 65, 73, 75, 76, 69, 75, 72, 29, 17, 29, - 96, 88, 75, 73, 88, 84, 73, 68, 65, 63, 37, 4, 26, 81, 89, 93, - 83, 91, 84, 85, 53, 37, 16, 81, 81, 83, 163, 234, 238, 216, 104, 104, - 108, 118, 130, 143, 151, 151, 150, 155, 167, 159, 147, 130, 136, 138, 100, 25, - 26, 28, 36, 41, 44, 30, 42, 42, 40, 36, 46, 41, 51, 55, 65, 64, - 68, 79, 148, 234, 241, 244, 236, 144, 110, 95, 33, 25, 21, 24, 25, 32, - 36, 40, 63, 217, 221, 210, 126, 124, 127, 134, 139, 153, 142, 120, 114, 119, - 97, 20, 14, 13, 18, 21, 21, 24, 24, 20, 26, 12, 32, 67, 72, 195, - 222, 220, 126, 110, 119, 128, 139, 153, 159, 163, 165, 153, 91, 25, 20, 16, - 20, 20, 44, 69, 181, 221, 221, 206, 123, 122, 126, 127, 126, 138, 136, 118, - 111, 55, 13, 9, 9, 21, 21, 28, 34, 36, 56, 229, 228, 226, 115, 106, - 118, 130, 142, 153, 163, 167, 163, 155, 147, 142, 46, 17, 20, 29, 36, 42, - 40, 20, 17, 20, 18, 26, 18, 22, 20, 25, 16, 24, 20, 26, 138, 197, - 187, 131, 100, 112, 116, 128, 131, 162, 171, 169, 173, 177, 187, 191, 202, 150, - 56, 33, 24, 40, 32, 75, 135, 224, 222, 218, 189, 174, 193, 206, 205, 202, - 195, 178, 173, 157, 158, 142, 127, 120, 110, 67, 48, 57, 55, 48, 33, 5, - 21, 85, 115, 88, 85, 122, 194, 216, 221, 111, 110, 116, 130, 130, 147, 157, - 162, 159, 158, 148, 134, 55, 22, 24, 36, 42, 64, 76, 81, 81, 77, 88, - 84, 77, 33, 14, 45, 63, 61, 53, 57, 57, 38, 16, 8, 6, 17, 20, - 13, 17, 17, 24, 24, 17, 30, 102, 134, 100, 99, 134, 140, 150, 157, 153, - 155, 150, 151, 139, 146, 146, 183, 197, 205, 178, 191, 186, 177, 169, 166, 157, - 153, 143, 119, 6, 6, 6, 6, 22, 24, 144, 124, 136, 126, 124, 136, 89, - 103, 72, 36, 158, 140, 110, 106, 108, 108, 118, 130, 132, 143, 136, 134, 142, - 132, 122, 131, 122, 95, 49, 46, 37, 57, 65, 65, 80, 91, 115, 97, 102, - 103, 91, 83, 92, 96, 89, 60, 181, 230, 236, 186, 114, 92, 89, 71, 38, - 24, 25, 26, 59, 69, 69, 71, 67, 71, 83, 210, 225, 222, 95, 89, 106, - 119, 118, 118, 127, 139, 159, 157, 148, 136, 138, 123, 33, 29, 24, 20, 36, - 49, 67, 72, 73, 80, 76, 73, 60, 85, 191, 214, 221, 220, 120, 104, 114, - 115, 130, 139, 119, 130, 138, 142, 134, 140, 139, 115, 36, 29, 26, 32, 65, - 60, 63, 59, 68, 132, 206, 204, 158, 120, 128, 131, 140, 151, 157, 163, 163, - 171, 177, 177, 174, 174, 148, 69, 40, 37, 72, 75, 77, 120, 212, 221, 189, - 163, 169, 178, 186, 187, 163, 153, 165, 167, 157, 151, 139, 126, 100, 64, 60, - 63, 87, 91, 89, 79, 97, 199, 225, 175, 140, 144, 154, 138, 142, 157, 179, - 186, 185, 130, 56, 26, 13, 48, 71, 87, 175, 230, 229, 225, 179, 178, 177, - 170, 166, 155, 140, 126, 81, 25, 22, 22, 34, 32, 33, 32, 17, 91, 91, - 80, 63, 59, 68, 60, 67, 71, 75, 37, 13, 73, 93, 76, 81, 81, 77, - 84, 75, 81, 73, 77, 34, 4, 77, 91, 87, 87, 77, 79, 64, 76, 64, - 51, 14, 84, 85, 85, 186, 238, 240, 220, 104, 103, 107, 116, 132, 146, 157, - 154, 140, 150, 151, 147, 126, 126, 139, 140, 100, 28, 28, 25, 38, 29, 41, - 46, 46, 53, 57, 59, 53, 61, 72, 73, 80, 85, 92, 131, 204, 242, 244, - 241, 213, 122, 111, 68, 29, 22, 21, 26, 32, 30, 38, 41, 71, 220, 225, - 220, 119, 118, 128, 114, 130, 131, 131, 114, 119, 118, 103, 21, 13, 13, 20, - 25, 38, 34, 40, 30, 26, 9, 88, 80, 81, 173, 218, 214, 131, 112, 119, - 127, 138, 147, 162, 163, 167, 167, 130, 40, 24, 18, 24, 40, 53, 89, 194, - 222, 222, 208, 123, 122, 124, 122, 131, 128, 126, 118, 100, 29, 12, 8, 14, - 28, 32, 32, 37, 33, 67, 226, 229, 228, 116, 107, 116, 126, 140, 153, 162, - 167, 159, 150, 144, 132, 59, 25, 17, 30, 46, 53, 53, 38, 13, 28, 91, - 88, 85, 81, 91, 81, 81, 80, 80, 48, 122, 187, 183, 120, 100, 114, 119, - 123, 124, 150, 155, 173, 169, 166, 179, 189, 193, 194, 107, 46, 40, 46, 53, - 123, 194, 226, 224, 220, 183, 173, 187, 197, 198, 197, 195, 171, 171, 163, 154, - 154, 135, 120, 120, 72, 69, 88, 130, 118, 36, 10, 67, 123, 111, 120, 142, - 151, 210, 220, 208, 112, 108, 118, 127, 124, 143, 153, 161, 161, 154, 147, 132, - 61, 26, 21, 42, 73, 88, 85, 80, 84, 85, 85, 85, 88, 57, 20, 59, - 71, 69, 69, 64, 65, 60, 60, 48, 17, 8, 20, 36, 83, 89, 57, 72, - 77, 64, 34, 144, 122, 91, 112, 124, 132, 139, 142, 120, 122, 130, 67, 55, - 77, 162, 197, 209, 185, 182, 185, 175, 167, 165, 157, 148, 139, 114, 5, 8, - 9, 17, 57, 64, 123, 120, 99, 124, 122, 112, 79, 102, 71, 30, 143, 139, - 103, 107, 106, 106, 104, 106, 112, 132, 147, 139, 132, 140, 127, 120, 124, 116, - 84, 46, 55, 63, 34, 57, 76, 111, 102, 95, 97, 87, 83, 79, 92, 72, - 56, 123, 210, 234, 230, 199, 112, 88, 81, 59, 32, 22, 25, 24, 56, 71, - 63, 63, 57, 71, 115, 228, 222, 204, 100, 100, 108, 120, 124, 119, 126, 132, - 148, 153, 143, 128, 139, 124, 30, 30, 9, 61, 51, 59, 60, 73, 84, 76, - 75, 60, 80, 102, 221, 220, 220, 209, 123, 97, 107, 118, 142, 143, 127, 116, - 124, 131, 128, 139, 138, 114, 49, 26, 26, 33, 65, 65, 75, 52, 60, 110, - 197, 199, 165, 122, 127, 127, 140, 144, 154, 161, 157, 165, 169, 174, 170, 170, - 161, 92, 44, 30, 61, 73, 76, 102, 194, 218, 198, 163, 166, 177, 185, 189, - 182, 153, 154, 166, 170, 159, 150, 138, 128, 96, 87, 84, 87, 83, 77, 75, - 81, 179, 229, 178, 142, 150, 158, 138, 140, 169, 181, 187, 190, 158, 42, 26, - 25, 61, 80, 96, 186, 233, 230, 225, 179, 178, 170, 169, 166, 158, 140, 123, - 76, 24, 22, 21, 30, 41, 42, 30, 18, 84, 99, 85, 96, 83, 83, 99, - 83, 73, 73, 37, 34, 89, 99, 77, 83, 76, 64, 57, 77, 63, 49, 73, - 25, 1, 76, 95, 80, 65, 59, 67, 75, 80, 56, 41, 17, 84, 85, 91, - 208, 238, 233, 213, 108, 104, 110, 114, 126, 147, 157, 159, 159, 153, 138, 131, - 122, 134, 138, 144, 104, 56, 29, 28, 40, 34, 40, 53, 56, 48, 45, 49, - 48, 69, 85, 95, 100, 93, 126, 198, 241, 246, 244, 236, 155, 118, 108, 55, - 26, 24, 20, 29, 33, 32, 37, 41, 69, 221, 222, 217, 127, 128, 123, 131, - 116, 110, 106, 111, 122, 112, 102, 21, 17, 12, 22, 32, 40, 41, 42, 44, - 24, 10, 81, 92, 77, 139, 208, 216, 147, 114, 120, 128, 139, 146, 155, 162, - 159, 167, 150, 103, 48, 45, 49, 72, 100, 170, 197, 221, 214, 214, 123, 120, - 124, 124, 124, 131, 119, 114, 69, 17, 13, 6, 16, 26, 30, 38, 44, 40, - 79, 224, 226, 225, 114, 110, 119, 134, 142, 153, 163, 167, 158, 151, 147, 134, - 71, 26, 18, 34, 53, 46, 49, 55, 13, 99, 97, 88, 84, 80, 92, 91, - 84, 87, 75, 52, 59, 177, 175, 118, 103, 114, 118, 122, 127, 130, 162, 170, - 178, 158, 173, 179, 189, 202, 155, 76, 52, 68, 112, 135, 213, 222, 224, 220, - 185, 167, 174, 183, 179, 183, 185, 175, 171, 166, 162, 161, 151, 127, 120, 81, - 85, 127, 136, 131, 28, 5, 76, 126, 112, 136, 143, 158, 214, 221, 217, 108, - 107, 118, 128, 120, 134, 154, 165, 158, 151, 143, 131, 88, 32, 25, 45, 79, - 76, 81, 73, 84, 80, 69, 72, 85, 88, 18, 61, 68, 63, 41, 32, 29, - 32, 40, 59, 34, 9, 14, 79, 79, 79, 80, 83, 68, 61, 56, 41, 45, - 52, 72, 102, 97, 107, 89, 65, 42, 38, 28, 33, 65, 139, 197, 209, 191, - 175, 183, 174, 169, 166, 155, 148, 139, 106, 4, 8, 13, 26, 41, 44, 134, - 102, 96, 102, 83, 100, 81, 75, 64, 36, 139, 134, 97, 115, 107, 103, 106, - 104, 102, 108, 131, 150, 139, 128, 138, 123, 128, 120, 116, 79, 63, 60, 57, - 53, 73, 108, 89, 87, 83, 79, 80, 75, 76, 91, 132, 183, 226, 232, 229, - 185, 110, 88, 64, 36, 25, 21, 25, 24, 41, 65, 64, 52, 57, 85, 191, - 228, 225, 208, 104, 99, 108, 123, 124, 138, 126, 120, 135, 148, 146, 134, 138, - 114, 33, 29, 14, 51, 53, 51, 76, 59, 59, 61, 57, 57, 80, 153, 212, - 216, 220, 209, 123, 118, 106, 116, 132, 131, 142, 131, 115, 115, 124, 130, 138, - 116, 55, 24, 21, 33, 68, 81, 57, 56, 64, 92, 185, 199, 163, 124, 119, - 124, 136, 142, 150, 158, 155, 157, 159, 165, 169, 163, 163, 120, 53, 51, 68, - 67, 81, 89, 151, 217, 201, 162, 162, 173, 186, 186, 187, 173, 148, 153, 167, - 165, 159, 148, 132, 127, 119, 112, 92, 77, 81, 79, 68, 114, 216, 189, 147, - 148, 166, 140, 140, 174, 183, 194, 197, 179, 75, 32, 25, 30, 85, 104, 204, - 233, 233, 228, 175, 177, 171, 167, 170, 159, 139, 115, 48, 22, 22, 13, 33, - 32, 38, 34, 22, 52, 71, 95, 59, 84, 79, 77, 77, 81, 71, 40, 30, - 60, 97, 87, 91, 59, 59, 76, 53, 59, 64, 64, 26, 0, 76, 84, 65, - 73, 83, 73, 76, 63, 51, 46, 24, 71, 76, 102, 218, 237, 236, 210, 111, - 107, 111, 112, 122, 143, 155, 163, 157, 151, 150, 147, 130, 135, 144, 144, 111, - 87, 32, 29, 40, 32, 34, 34, 38, 41, 40, 40, 63, 68, 97, 102, 95, - 127, 185, 234, 244, 248, 245, 221, 128, 114, 100, 41, 24, 20, 21, 30, 30, - 30, 37, 55, 110, 205, 216, 217, 128, 112, 119, 123, 114, 118, 107, 107, 119, - 120, 102, 22, 14, 16, 17, 18, 40, 44, 40, 37, 29, 8, 88, 88, 75, - 95, 189, 213, 181, 118, 116, 128, 135, 144, 151, 162, 161, 171, 171, 151, 107, - 107, 128, 159, 187, 202, 197, 225, 209, 209, 124, 123, 124, 126, 132, 126, 114, - 92, 24, 9, 10, 9, 24, 21, 28, 41, 40, 40, 81, 218, 228, 222, 112, - 104, 114, 123, 142, 153, 161, 166, 158, 150, 143, 134, 111, 36, 18, 34, 45, - 48, 45, 41, 13, 102, 100, 115, 95, 85, 91, 73, 73, 79, 85, 72, 36, - 122, 174, 127, 97, 114, 119, 123, 130, 126, 150, 155, 167, 155, 166, 171, 183, - 191, 202, 165, 131, 150, 177, 213, 221, 224, 218, 218, 181, 166, 163, 173, 177, - 174, 179, 177, 177, 170, 162, 154, 161, 144, 124, 87, 93, 114, 143, 123, 24, - 5, 64, 108, 126, 124, 140, 171, 218, 216, 220, 110, 106, 116, 131, 126, 142, - 154, 163, 159, 151, 140, 134, 108, 42, 32, 45, 76, 76, 75, 83, 92, 89, - 83, 71, 87, 63, 28, 53, 67, 60, 34, 37, 36, 25, 24, 57, 45, 10, - 13, 83, 67, 73, 71, 64, 63, 49, 40, 41, 34, 37, 32, 34, 49, 44, - 29, 26, 29, 24, 18, 36, 64, 147, 205, 216, 194, 171, 181, 177, 170, 166, - 158, 144, 136, 97, 2, 6, 12, 28, 4, 2, 132, 97, 107, 107, 96, 89, - 119, 81, 64, 30, 142, 128, 100, 80, 104, 112, 106, 106, 106, 102, 111, 131, - 142, 139, 138, 135, 114, 123, 123, 114, 97, 84, 88, 79, 97, 96, 115, 93, - 84, 81, 83, 93, 132, 181, 214, 232, 236, 232, 208, 163, 96, 75, 46, 28, - 21, 21, 25, 28, 51, 60, 61, 59, 67, 122, 214, 218, 226, 204, 93, 93, - 111, 119, 120, 136, 115, 119, 123, 142, 136, 131, 136, 116, 37, 33, 45, 80, - 77, 49, 60, 51, 67, 53, 56, 52, 79, 165, 210, 213, 208, 191, 124, 104, - 112, 128, 142, 136, 144, 147, 135, 116, 112, 127, 132, 118, 49, 37, 37, 40, - 69, 73, 67, 52, 57, 64, 179, 201, 163, 116, 123, 123, 135, 140, 147, 157, - 161, 148, 148, 153, 153, 161, 162, 138, 84, 55, 40, 53, 75, 77, 127, 208, - 209, 163, 161, 171, 179, 185, 187, 187, 177, 146, 153, 171, 165, 154, 148, 138, - 128, 130, 132, 106, 83, 72, 72, 83, 181, 213, 163, 153, 165, 140, 143, 179, - 189, 201, 201, 194, 140, 69, 29, 30, 92, 148, 214, 233, 233, 229, 183, 178, - 166, 167, 167, 158, 134, 103, 29, 22, 21, 17, 40, 32, 34, 37, 25, 32, - 93, 99, 85, 89, 83, 80, 76, 73, 67, 38, 34, 63, 100, 69, 77, 63, - 80, 63, 52, 63, 64, 61, 34, 6, 79, 88, 61, 64, 64, 52, 67, 53, - 42, 40, 40, 72, 88, 157, 222, 241, 233, 208, 111, 110, 115, 107, 118, 138, - 151, 159, 165, 161, 154, 148, 142, 126, 131, 147, 130, 93, 33, 34, 33, 40, - 38, 53, 57, 51, 42, 46, 61, 77, 100, 96, 115, 175, 232, 241, 246, 246, - 242, 166, 116, 114, 87, 30, 21, 14, 21, 28, 29, 38, 40, 56, 171, 206, - 214, 204, 123, 116, 122, 127, 115, 115, 118, 102, 106, 119, 107, 28, 16, 13, - 16, 33, 41, 42, 34, 37, 29, 6, 80, 87, 80, 80, 115, 197, 197, 124, - 116, 124, 132, 140, 142, 150, 147, 174, 177, 175, 166, 182, 195, 198, 206, 205, - 213, 202, 209, 161, 124, 124, 132, 135, 130, 120, 114, 34, 13, 12, 8, 14, - 24, 25, 33, 36, 37, 41, 161, 221, 224, 222, 112, 99, 114, 120, 140, 148, - 159, 159, 162, 153, 147, 144, 138, 56, 30, 26, 48, 48, 45, 42, 16, 73, - 103, 115, 106, 97, 110, 91, 92, 84, 77, 84, 38, 61, 166, 143, 102, 103, - 118, 120, 124, 127, 131, 155, 157, 154, 163, 166, 178, 183, 199, 209, 205, 214, - 216, 221, 220, 218, 224, 204, 182, 161, 162, 142, 162, 167, 177, 177, 175, 177, - 167, 166, 159, 159, 140, 118, 96, 131, 139, 63, 20, 5, 56, 108, 108, 115, - 127, 155, 216, 226, 214, 110, 104, 115, 126, 120, 147, 155, 159, 155, 151, 143, - 136, 122, 63, 33, 51, 76, 72, 81, 81, 84, 83, 84, 87, 72, 75, 22, - 42, 65, 55, 26, 34, 18, 20, 29, 32, 36, 12, 16, 40, 63, 36, 52, - 53, 63, 38, 33, 29, 28, 22, 30, 29, 36, 24, 22, 25, 21, 24, 20, - 59, 65, 170, 212, 218, 182, 167, 179, 175, 170, 166, 158, 143, 132, 52, 2, - 6, 13, 38, 2, 1, 135, 111, 89, 100, 102, 87, 85, 88, 64, 26, 128, - 119, 96, 85, 71, 85, 115, 110, 106, 104, 102, 107, 132, 146, 143, 143, 136, - 118, 116, 119, 148, 126, 116, 115, 120, 124, 131, 132, 134, 134, 154, 186, 212, - 225, 236, 234, 229, 216, 186, 111, 84, 51, 30, 22, 18, 22, 26, 41, 55, - 48, 59, 61, 127, 182, 228, 225, 226, 212, 108, 93, 104, 115, 130, 132, 122, - 126, 119, 128, 130, 132, 135, 123, 91, 67, 37, 69, 80, 80, 60, 59, 64, - 77, 55, 65, 99, 185, 205, 209, 212, 155, 110, 112, 118, 126, 131, 143, 143, - 144, 143, 134, 111, 116, 130, 123, 95, 49, 44, 44, 73, 56, 59, 52, 56, - 55, 158, 198, 163, 114, 119, 123, 135, 143, 147, 154, 158, 146, 144, 139, 139, - 146, 154, 147, 100, 56, 29, 49, 68, 79, 107, 190, 209, 170, 158, 169, 178, - 181, 183, 185, 187, 177, 150, 154, 166, 163, 155, 147, 143, 132, 132, 131, 100, - 72, 77, 77, 127, 218, 175, 154, 162, 144, 179, 183, 199, 205, 204, 206, 186, - 110, 40, 45, 102, 179, 230, 232, 233, 222, 178, 177, 174, 169, 166, 146, 134, - 83, 24, 21, 21, 22, 37, 37, 32, 38, 29, 29, 81, 97, 84, 89, 77, - 76, 84, 75, 75, 46, 34, 64, 91, 76, 76, 57, 67, 52, 60, 56, 61, - 63, 32, 1, 84, 88, 52, 64, 53, 60, 44, 36, 45, 63, 59, 71, 96, - 206, 233, 228, 237, 197, 112, 115, 115, 116, 110, 127, 147, 157, 159, 161, 158, - 154, 150, 136, 139, 132, 154, 108, 89, 69, 65, 71, 73, 71, 69, 75, 75, - 69, 71, 91, 108, 96, 171, 228, 234, 238, 245, 241, 216, 122, 118, 108, 56, - 28, 21, 17, 25, 26, 34, 36, 49, 171, 208, 206, 216, 195, 110, 124, 132, - 123, 128, 130, 134, 123, 104, 120, 115, 41, 13, 12, 25, 29, 30, 40, 44, - 30, 26, 5, 79, 80, 75, 81, 84, 122, 195, 132, 118, 122, 126, 131, 134, - 134, 135, 138, 153, 182, 181, 190, 193, 204, 210, 212, 201, 206, 186, 124, 123, - 132, 134, 131, 122, 122, 57, 13, 10, 9, 5, 21, 26, 32, 41, 38, 38, - 65, 199, 213, 221, 218, 112, 102, 108, 118, 132, 144, 157, 159, 159, 155, 146, - 139, 124, 107, 46, 25, 28, 49, 46, 45, 20, 69, 103, 116, 93, 102, 110, - 71, 103, 83, 77, 76, 45, 37, 153, 175, 110, 95, 112, 122, 124, 123, 126, - 139, 140, 151, 163, 169, 170, 175, 181, 195, 194, 204, 210, 212, 216, 213, 206, - 189, 173, 161, 139, 139, 138, 142, 159, 167, 175, 174, 171, 161, 161, 162, 159, - 132, 102, 138, 91, 28, 8, 8, 53, 103, 111, 124, 138, 162, 216, 221, 217, - 115, 107, 114, 122, 122, 157, 157, 157, 155, 151, 143, 132, 123, 106, 44, 56, - 80, 85, 75, 75, 80, 80, 85, 84, 92, 84, 36, 37, 67, 55, 29, 21, - 29, 29, 32, 28, 33, 9, 16, 69, 60, 57, 49, 38, 40, 29, 34, 29, - 38, 29, 25, 36, 29, 28, 22, 22, 17, 21, 16, 53, 79, 199, 214, 217, - 162, 162, 179, 178, 170, 165, 157, 142, 130, 42, 2, 4, 12, 32, 4, 10, - 124, 116, 91, 93, 102, 107, 73, 92, 64, 30, 122, 119, 97, 91, 85, 69, - 68, 87, 111, 111, 107, 104, 106, 127, 144, 139, 130, 123, 119, 148, 165, 175, - 175, 183, 189, 185, 191, 189, 194, 206, 213, 225, 228, 232, 230, 218, 217, 177, - 127, 81, 52, 33, 24, 21, 22, 34, 42, 52, 46, 71, 120, 159, 183, 210, - 213, 220, 225, 206, 114, 87, 114, 107, 116, 130, 144, 147, 130, 122, 120, 136, - 135, 140, 119, 106, 108, 110, 116, 104, 84, 68, 55, 75, 53, 72, 140, 198, - 209, 209, 201, 153, 118, 107, 110, 126, 138, 143, 132, 147, 147, 140, 131, 110, - 123, 122, 108, 92, 57, 53, 75, 71, 59, 53, 44, 53, 124, 202, 177, 111, - 116, 124, 138, 142, 148, 157, 139, 134, 130, 127, 126, 128, 142, 146, 127, 92, - 60, 32, 56, 71, 93, 150, 204, 174, 155, 161, 171, 175, 179, 178, 181, 182, - 170, 151, 159, 166, 159, 155, 143, 132, 131, 127, 93, 75, 68, 72, 79, 178, - 210, 158, 155, 140, 185, 195, 204, 208, 210, 209, 208, 178, 124, 132, 182, 222, - 234, 233, 233, 214, 186, 179, 173, 170, 159, 136, 120, 46, 20, 18, 20, 25, - 41, 36, 45, 45, 36, 30, 85, 100, 64, 84, 77, 71, 83, 88, 77, 61, - 34, 48, 95, 65, 77, 56, 51, 51, 63, 57, 49, 65, 25, 4, 76, 81, - 51, 63, 42, 59, 59, 53, 61, 65, 75, 130, 201, 222, 234, 236, 228, 182, - 114, 119, 108, 119, 123, 112, 136, 148, 153, 155, 154, 155, 153, 151, 143, 127, - 142, 157, 108, 103, 103, 100, 97, 100, 96, 91, 91, 87, 83, 89, 128, 181, - 226, 230, 237, 241, 240, 230, 142, 116, 120, 104, 42, 22, 18, 21, 29, 33, - 32, 48, 175, 204, 209, 210, 205, 197, 119, 111, 124, 119, 138, 120, 126, 122, - 130, 112, 115, 95, 17, 22, 16, 16, 30, 41, 41, 34, 21, 10, 71, 80, - 76, 67, 72, 83, 103, 173, 170, 124, 124, 123, 126, 127, 128, 128, 130, 130, - 131, 140, 159, 163, 166, 177, 182, 159, 124, 128, 127, 126, 124, 122, 115, 46, - 13, 9, 8, 4, 6, 14, 21, 30, 40, 37, 44, 158, 213, 214, 217, 212, - 114, 103, 114, 120, 134, 143, 153, 161, 161, 157, 150, 151, 134, 136, 100, 63, - 40, 33, 34, 48, 21, 71, 103, 111, 110, 92, 93, 73, 79, 96, 73, 79, - 42, 29, 124, 167, 135, 95, 103, 118, 123, 126, 120, 122, 126, 150, 161, 158, - 167, 163, 162, 158, 153, 173, 185, 189, 197, 194, 183, 158, 136, 140, 139, 136, - 138, 139, 136, 139, 151, 157, 154, 151, 158, 148, 140, 114, 131, 91, 28, 0, - 9, 5, 46, 91, 120, 142, 138, 189, 205, 216, 216, 118, 106, 108, 123, 144, - 154, 166, 155, 153, 151, 142, 134, 124, 123, 91, 56, 44, 55, 73, 79, 87, - 80, 77, 89, 68, 103, 29, 20, 56, 37, 42, 30, 30, 37, 33, 25, 33, - 10, 12, 59, 61, 63, 65, 65, 57, 48, 44, 33, 40, 37, 18, 34, 37, - 37, 28, 25, 21, 20, 30, 40, 108, 210, 224, 217, 154, 157, 173, 177, 170, - 163, 157, 144, 128, 30, 2, 4, 10, 30, 4, 1, 118, 85, 85, 79, 81, - 73, 73, 72, 60, 30, 114, 112, 97, 84, 81, 80, 68, 53, 61, 84, 104, - 107, 103, 106, 112, 120, 128, 135, 135, 139, 139, 150, 171, 185, 194, 198, 208, - 204, 209, 216, 220, 221, 217, 217, 214, 197, 158, 118, 79, 48, 32, 24, 20, - 20, 30, 38, 53, 42, 128, 166, 202, 212, 199, 206, 208, 213, 209, 154, 110, - 89, 135, 116, 124, 131, 132, 126, 132, 139, 132, 127, 146, 135, 136, 130, 139, - 144, 159, 140, 127, 100, 80, 46, 45, 75, 163, 199, 202, 201, 206, 144, 119, - 115, 116, 144, 146, 138, 138, 132, 131, 132, 139, 128, 108, 123, 119, 106, 81, - 106, 91, 84, 51, 59, 48, 51, 89, 185, 187, 128, 108, 124, 135, 139, 138, - 138, 134, 127, 124, 118, 118, 116, 118, 132, 134, 108, 75, 26, 42, 65, 79, - 104, 179, 193, 151, 155, 163, 171, 174, 175, 175, 181, 179, 158, 150, 163, 165, - 153, 138, 136, 128, 103, 64, 41, 63, 68, 72, 99, 204, 170, 163, 147, 187, - 195, 209, 210, 213, 209, 216, 210, 205, 209, 226, 230, 230, 233, 232, 201, 181, - 182, 177, 166, 140, 131, 85, 25, 20, 18, 21, 30, 42, 38, 46, 41, 38, - 25, 71, 73, 92, 76, 85, 93, 91, 88, 77, 73, 33, 38, 64, 85, 88, - 49, 55, 49, 57, 63, 63, 60, 26, 1, 72, 73, 69, 52, 60, 53, 59, - 68, 106, 167, 187, 218, 216, 232, 221, 226, 224, 150, 116, 118, 124, 130, 142, - 123, 116, 135, 140, 142, 142, 144, 148, 148, 153, 142, 138, 148, 159, 146, 169, - 179, 189, 198, 204, 208, 212, 217, 220, 217, 222, 222, 226, 232, 237, 237, 224, - 154, 118, 122, 118, 81, 26, 18, 18, 21, 30, 36, 76, 150, 221, 206, 201, - 214, 216, 158, 124, 128, 135, 130, 131, 124, 138, 119, 122, 111, 112, 96, 67, - 48, 20, 17, 12, 36, 41, 32, 28, 9, 69, 71, 65, 65, 72, 61, 79, - 91, 99, 107, 112, 151, 155, 150, 147, 147, 143, 140, 136, 131, 131, 128, 128, - 128, 130, 127, 124, 124, 122, 120, 118, 81, 29, 12, 9, 9, 4, 4, 22, - 20, 32, 37, 38, 41, 136, 197, 206, 209, 214, 205, 108, 104, 107, 120, 134, - 136, 139, 146, 153, 153, 148, 140, 146, 138, 142, 112, 93, 79, 59, 32, 21, - 55, 104, 95, 107, 80, 99, 95, 93, 97, 73, 77, 59, 25, 81, 148, 177, - 114, 102, 110, 118, 119, 122, 123, 124, 127, 130, 132, 131, 132, 140, 130, 128, - 126, 128, 130, 127, 126, 128, 131, 131, 136, 136, 139, 142, 139, 139, 142, 135, - 130, 130, 128, 127, 123, 135, 138, 99, 26, 0, 5, 5, 5, 45, 89, 97, - 132, 191, 197, 195, 213, 206, 115, 111, 116, 120, 147, 151, 153, 144, 153, 150, - 143, 136, 127, 122, 120, 119, 97, 67, 63, 49, 84, 79, 75, 76, 65, 89, - 32, 13, 72, 26, 26, 28, 41, 36, 38, 25, 30, 12, 12, 51, 55, 56, - 52, 40, 42, 30, 24, 20, 24, 26, 18, 30, 41, 36, 29, 32, 34, 14, - 42, 51, 138, 220, 222, 210, 146, 151, 161, 173, 173, 163, 157, 143, 126, 25, - 4, 4, 12, 24, 6, 2, 77, 76, 75, 79, 73, 73, 80, 67, 61, 26, - 93, 104, 97, 88, 99, 85, 77, 68, 55, 48, 53, 71, 95, 104, 106, 104, - 104, 111, 108, 116, 118, 122, 127, 142, 165, 177, 186, 201, 205, 202, 202, 202, - 199, 181, 158, 118, 84, 65, 44, 30, 24, 18, 18, 21, 29, 38, 38, 104, - 225, 193, 202, 194, 206, 201, 210, 177, 140, 118, 104, 115, 115, 116, 112, 118, - 111, 116, 115, 120, 119, 123, 127, 120, 130, 142, 134, 138, 138, 135, 139, 148, - 79, 45, 63, 96, 216, 190, 193, 197, 202, 138, 122, 126, 136, 119, 140, 138, - 135, 123, 126, 123, 123, 123, 120, 120, 122, 108, 114, 108, 102, 77, 49, 51, - 52, 46, 57, 144, 191, 151, 106, 123, 127, 131, 134, 132, 127, 126, 119, 118, - 114, 110, 107, 103, 108, 122, 85, 72, 65, 49, 61, 77, 130, 197, 161, 151, - 158, 161, 159, 166, 169, 174, 178, 174, 155, 153, 159, 147, 136, 136, 115, 69, - 34, 33, 32, 71, 65, 63, 157, 182, 174, 134, 182, 197, 198, 205, 210, 217, - 217, 221, 220, 222, 230, 228, 230, 226, 217, 190, 186, 179, 175, 161, 134, 99, - 38, 22, 20, 18, 17, 34, 40, 37, 40, 45, 41, 26, 56, 79, 92, 89, - 73, 76, 71, 83, 65, 41, 33, 32, 64, 89, 73, 46, 60, 57, 59, 63, - 72, 38, 29, 4, 64, 69, 59, 67, 32, 52, 79, 185, 210, 205, 213, 234, - 212, 225, 240, 221, 190, 120, 118, 119, 138, 140, 131, 139, 131, 127, 127, 124, - 127, 130, 123, 127, 130, 136, 146, 143, 132, 167, 170, 182, 190, 198, 202, 208, - 213, 216, 218, 222, 224, 229, 229, 230, 226, 199, 138, 115, 118, 124, 114, 49, - 20, 17, 18, 28, 34, 83, 181, 190, 190, 202, 208, 228, 205, 140, 120, 111, - 119, 116, 131, 126, 115, 128, 115, 114, 126, 96, 83, 73, 63, 44, 16, 21, - 40, 28, 28, 8, 64, 73, 61, 46, 38, 48, 52, 53, 51, 56, 57, 75, - 96, 103, 106, 103, 100, 107, 111, 111, 112, 111, 110, 111, 118, 115, 114, 107, - 102, 72, 30, 17, 9, 8, 5, 2, 4, 8, 18, 22, 40, 37, 44, 140, - 190, 197, 198, 202, 209, 147, 108, 100, 110, 126, 122, 127, 135, 136, 144, 140, - 153, 148, 138, 143, 126, 138, 148, 144, 103, 67, 38, 24, 69, 106, 85, 100, - 79, 93, 89, 97, 71, 79, 73, 20, 69, 135, 144, 150, 144, 139, 136, 143, - 138, 116, 115, 118, 118, 123, 126, 126, 123, 122, 127, 119, 102, 96, 89, 81, - 85, 97, 114, 123, 130, 134, 135, 132, 127, 132, 132, 135, 138, 136, 132, 132, - 123, 96, 28, 9, 1, 2, 5, 6, 44, 99, 132, 194, 204, 201, 198, 214, - 187, 114, 106, 120, 128, 126, 140, 147, 150, 146, 147, 143, 139, 135, 128, 120, - 118, 114, 126, 111, 76, 53, 53, 56, 68, 61, 88, 29, 12, 67, 42, 28, - 33, 45, 28, 29, 32, 22, 14, 17, 55, 71, 49, 45, 34, 33, 32, 22, - 24, 32, 20, 38, 34, 28, 20, 20, 21, 26, 14, 42, 51, 158, 220, 225, - 208, 142, 146, 150, 163, 171, 163, 155, 143, 118, 13, 5, 2, 12, 24, 14, - 17, 72, 75, 76, 80, 72, 77, 84, 85, 59, 25, 99, 99, 93, 97, 84, - 80, 72, 67, 59, 55, 45, 38, 42, 48, 65, 83, 96, 97, 103, 103, 103, - 104, 106, 111, 119, 124, 128, 135, 153, 150, 144, 142, 115, 91, 76, 57, 34, - 29, 28, 22, 17, 18, 22, 21, 42, 49, 41, 146, 191, 212, 193, 194, 178, - 155, 134, 122, 108, 89, 83, 79, 81, 85, 88, 91, 91, 95, 99, 100, 99, - 102, 104, 110, 115, 119, 118, 116, 120, 126, 126, 114, 80, 42, 72, 154, 175, - 181, 155, 158, 135, 128, 107, 110, 115, 110, 116, 115, 119, 111, 122, 123, 114, - 127, 123, 118, 108, 106, 106, 102, 93, 45, 25, 33, 48, 41, 45, 100, 171, - 178, 104, 115, 112, 115, 116, 116, 114, 118, 112, 112, 108, 106, 103, 103, 100, - 99, 91, 80, 46, 42, 48, 60, 92, 155, 173, 147, 153, 157, 155, 150, 159, - 165, 166, 170, 167, 158, 140, 136, 139, 123, 85, 46, 32, 26, 26, 49, 63, - 65, 126, 195, 175, 151, 162, 182, 195, 198, 201, 201, 201, 199, 201, 198, 199, - 199, 201, 199, 191, 182, 177, 174, 165, 139, 111, 37, 18, 18, 18, 20, 20, - 34, 32, 34, 42, 40, 41, 34, 33, 36, 40, 49, 33, 36, 42, 36, 34, - 44, 42, 38, 37, 48, 52, 57, 44, 45, 44, 42, 41, 44, 22, 2, 24, - 52, 56, 36, 40, 61, 154, 202, 198, 204, 218, 242, 212, 206, 198, 148, 120, - 114, 122, 132, 135, 134, 136, 136, 134, 132, 126, 130, 131, 128, 127, 123, 120, - 122, 123, 124, 122, 122, 123, 123, 132, 140, 159, 182, 187, 201, 201, 198, 195, - 197, 198, 185, 158, 119, 114, 116, 123, 123, 97, 25, 16, 12, 28, 32, 59, - 165, 186, 191, 201, 193, 201, 170, 139, 127, 111, 128, 115, 116, 118, 124, 107, - 112, 100, 107, 100, 120, 100, 103, 89, 79, 20, 18, 38, 26, 25, 9, 72, - 67, 34, 30, 26, 30, 29, 34, 25, 26, 21, 20, 20, 22, 22, 18, 20, - 18, 17, 17, 16, 16, 13, 14, 18, 14, 13, 10, 10, 10, 6, 6, 6, - 2, 2, 5, 13, 20, 13, 41, 33, 52, 136, 181, 181, 178, 193, 201, 171, - 122, 104, 112, 122, 116, 120, 127, 126, 128, 126, 130, 139, 135, 124, 140, 135, - 118, 115, 116, 153, 130, 37, 25, 57, 53, 57, 59, 63, 64, 68, 68, 73, - 73, 56, 16, 38, 84, 97, 88, 87, 83, 91, 95, 99, 103, 103, 99, 99, - 111, 112, 103, 99, 96, 73, 34, 13, 8, 4, 4, 5, 12, 53, 91, 100, - 104, 106, 102, 95, 96, 100, 99, 96, 95, 92, 80, 38, 16, 2, 0, 1, - 12, 10, 14, 84, 140, 179, 195, 183, 181, 201, 199, 134, 110, 114, 124, 118, - 119, 118, 127, 128, 130, 134, 130, 122, 124, 123, 123, 120, 112, 112, 128, 114, - 96, 84, 85, 76, 75, 57, 46, 14, 38, 53, 60, 45, 46, 32, 28, 29, - 24, 10, 16, 51, 40, 26, 33, 22, 16, 14, 21, 21, 21, 26, 22, 18, - 17, 13, 18, 14, 17, 37, 48, 63, 178, 225, 225, 204, 138, 143, 148, 158, - 166, 161, 154, 139, 96, 8, 4, 2, 6, 16, 10, 5, 84, 80, 79, 80, - 79, 87, 80, 73, 56, 25, 88, 95, 77, 83, 75, 75, 64, 65, 57, 56, - 49, 45, 40, 38, 33, 32, 33, 41, 46, 57, 68, 88, 88, 89, 89, 85, - 85, 80, 77, 76, 72, 63, 42, 32, 28, 24, 24, 18, 16, 16, 25, 33, - 33, 29, 37, 26, 26, 80, 126, 144, 139, 134, 135, 87, 75, 64, 59, 44, - 25, 28, 28, 24, 22, 22, 25, 26, 28, 33, 33, 30, 37, 68, 77, 84, - 81, 80, 79, 95, 88, 61, 33, 46, 68, 130, 131, 142, 139, 143, 115, 92, - 81, 81, 96, 97, 96, 93, 99, 100, 106, 103, 102, 102, 104, 99, 92, 89, - 89, 83, 49, 22, 22, 20, 24, 44, 34, 42, 103, 122, 104, 110, 88, 106, - 107, 111, 108, 110, 107, 103, 96, 96, 89, 97, 89, 92, 91, 76, 24, 26, - 59, 40, 67, 93, 157, 166, 146, 153, 151, 151, 151, 154, 154, 153, 148, 143, - 138, 138, 123, 97, 49, 32, 30, 30, 32, 38, 68, 61, 161, 183, 178, 163, - 118, 150, 181, 183, 187, 190, 189, 187, 185, 182, 175, 174, 177, 178, 177, 174, - 159, 143, 131, 103, 40, 21, 18, 18, 24, 28, 25, 30, 22, 22, 33, 34, - 38, 37, 42, 42, 56, 44, 46, 44, 48, 46, 46, 44, 44, 42, 37, 45, - 44, 30, 26, 13, 13, 20, 20, 18, 18, 2, 9, 13, 21, 38, 33, 57, - 144, 193, 209, 197, 199, 173, 143, 128, 119, 111, 120, 114, 130, 128, 128, 128, - 130, 130, 130, 126, 126, 123, 122, 122, 120, 112, 118, 119, 119, 119, 119, 116, - 119, 116, 114, 112, 111, 111, 112, 115, 116, 116, 114, 111, 111, 110, 111, 111, - 118, 120, 126, 119, 49, 13, 14, 17, 28, 30, 128, 186, 171, 182, 197, 169, - 135, 128, 111, 110, 96, 103, 100, 97, 104, 100, 97, 88, 93, 93, 92, 89, - 97, 91, 83, 76, 20, 21, 33, 26, 20, 12, 61, 65, 30, 24, 24, 24, - 22, 22, 20, 17, 14, 12, 13, 12, 12, 10, 12, 9, 9, 9, 6, 6, - 6, 8, 6, 5, 4, 5, 2, 2, 2, 4, 8, 6, 9, 17, 13, 16, - 26, 41, 41, 87, 166, 173, 185, 177, 154, 140, 115, 104, 114, 110, 116, 110, - 114, 111, 110, 112, 119, 124, 126, 119, 116, 126, 126, 114, 111, 120, 126, 100, - 24, 46, 55, 52, 52, 46, 55, 53, 55, 51, 60, 56, 28, 17, 20, 24, - 21, 16, 13, 14, 12, 9, 9, 10, 9, 8, 6, 8, 5, 5, 5, 5, - 4, 2, 2, 2, 1, 1, 2, 4, 2, 4, 2, 1, 1, 2, 2, 1, - 1, 2, 1, 1, 1, 2, 0, 0, 0, 1, 4, 8, 12, 14, 89, 157, - 198, 189, 195, 185, 154, 126, 115, 108, 112, 115, 108, 106, 114, 118, 116, 120, - 123, 119, 115, 112, 112, 108, 100, 104, 114, 111, 106, 77, 69, 56, 60, 51, - 33, 29, 25, 26, 25, 29, 28, 28, 25, 36, 28, 24, 13, 9, 45, 41, - 20, 14, 40, 71, 115, 153, 140, 84, 18, 30, 34, 9, 14, 14, 22, 14, - 41, 36, 88, 202, 224, 230, 199, 135, 138, 143, 154, 163, 159, 148, 135, 60, - 2, 5, 2, 2, 1, 1, 0, 29, 29, 32, 51, 52, 53, 61, 57, 53, - 24, 38, 44, 40, 41, 42, 40, 38, 36, 34, 34, 33, 30, 26, 29, 25, - 24, 22, 24, 22, 25, 24, 21, 21, 21, 24, 22, 24, 22, 22, 22, 22, - 22, 22, 17, 14, 12, 14, 21, 33, 25, 34, 40, 37, 25, 25, 36, 26, - 14, 26, 34, 33, 30, 28, 18, 26, 28, 20, 14, 16, 16, 16, 14, 13, - 14, 13, 13, 13, 16, 14, 12, 8, 12, 14, 13, 13, 18, 22, 5, 9, - 20, 20, 25, 14, 32, 42, 44, 63, 29, 4, 5, 16, 16, 13, 13, 14, - 17, 13, 13, 16, 13, 13, 14, 16, 20, 20, 18, 18, 17, 22, 26, 34, - 44, 41, 34, 26, 33, 30, 24, 20, 9, 10, 16, 13, 12, 10, 10, 8, - 6, 10, 6, 5, 10, 14, 6, 6, 13, 10, 12, 16, 13, 25, 59, 91, - 151, 154, 142, 140, 144, 143, 146, 148, 146, 143, 138, 134, 123, 85, 44, 32, - 29, 29, 28, 18, 41, 64, 60, 147, 181, 194, 175, 132, 107, 108, 124, 119, - 119, 112, 127, 122, 118, 115, 115, 115, 118, 114, 112, 108, 65, 49, 28, 20, - 18, 20, 21, 18, 18, 10, 8, 18, 8, 8, 8, 8, 20, 6, 6, 5, - 6, 8, 6, 6, 8, 8, 6, 6, 10, 21, 22, 34, 37, 65, 75, 79, - 80, 64, 57, 30, 5, 45, 55, 52, 28, 34, 55, 88, 120, 139, 126, 124, - 110, 93, 92, 93, 99, 100, 102, 126, 126, 120, 124, 124, 126, 126, 124, 124, - 123, 120, 122, 122, 118, 120, 120, 120, 120, 118, 116, 116, 115, 116, 115, 115, - 115, 114, 112, 114, 114, 112, 112, 112, 114, 116, 119, 123, 126, 122, 88, 21, - 12, 13, 14, 20, 29, 87, 151, 173, 138, 131, 102, 88, 83, 84, 85, 88, - 89, 89, 91, 91, 93, 92, 91, 91, 92, 87, 87, 83, 81, 76, 48, 21, - 18, 20, 21, 21, 10, 59, 22, 22, 14, 14, 13, 17, 9, 10, 12, 10, - 6, 6, 5, 5, 5, 6, 6, 6, 6, 5, 5, 5, 6, 8, 9, 10, - 10, 10, 10, 12, 13, 16, 17, 25, 12, 17, 29, 49, 41, 51, 143, 140, - 130, 123, 118, 108, 107, 99, 93, 99, 100, 106, 103, 100, 102, 108, 106, 106, - 111, 110, 108, 108, 104, 100, 95, 93, 95, 92, 33, 38, 5, 4, 5, 4, - 2, 4, 2, 4, 4, 1, 4, 2, 1, 10, 9, 6, 2, 9, 4, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 2, - 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 4, 4, 13, 9, 12, 17, 107, 150, 170, 154, 157, 131, 112, - 106, 100, 97, 100, 93, 99, 100, 96, 96, 106, 107, 110, 107, 106, 102, 96, - 96, 97, 95, 93, 87, 53, 20, 9, 5, 5, 5, 5, 4, 5, 4, 2, - 4, 5, 5, 5, 5, 6, 6, 13, 9, 41, 14, 32, 75, 138, 158, 171, - 186, 182, 169, 100, 21, 17, 49, 65, 56, 57, 48, 34, 60, 112, 214, 230, - 230, 189, 132, 138, 142, 154, 161, 158, 146, 130, 28, 2, 4, 5, 9, 14, - 29, 41, 85, 84, 83, 79, 57, 32, 40, 26, 38, 13, 0, 2, 2, 16, - 1, 2, 9, 12, 2, 2, 9, 10, 10, 6, 10, 10, 10, 5, 5, 14, - 13, 13, 12, 12, 12, 10, 9, 9, 9, 9, 9, 12, 10, 13, 20, 21, - 30, 28, 37, 42, 40, 44, 48, 51, 63, 59, 30, 34, 42, 52, 37, 33, - 29, 28, 32, 30, 28, 26, 28, 29, 29, 26, 25, 24, 22, 25, 29, 26, - 24, 22, 20, 17, 14, 20, 29, 33, 14, 24, 37, 17, 20, 17, 38, 34, - 44, 48, 46, 40, 33, 30, 34, 33, 30, 28, 32, 30, 30, 28, 29, 32, - 32, 29, 30, 30, 24, 26, 26, 30, 24, 29, 55, 48, 49, 49, 52, 46, - 33, 38, 33, 33, 36, 38, 36, 30, 32, 32, 30, 26, 29, 30, 28, 25, - 32, 32, 29, 28, 34, 41, 42, 53, 57, 48, 46, 92, 140, 148, 158, 142, - 147, 142, 146, 136, 139, 126, 114, 67, 36, 32, 30, 21, 20, 18, 32, 56, - 63, 128, 165, 190, 199, 171, 119, 81, 61, 59, 55, 51, 51, 41, 41, 38, - 42, 36, 38, 37, 37, 33, 36, 30, 30, 29, 32, 22, 36, 29, 33, 29, - 29, 29, 29, 28, 21, 20, 18, 6, 5, 26, 83, 110, 72, 77, 79, 79, - 73, 64, 69, 77, 83, 103, 89, 102, 103, 75, 81, 76, 84, 72, 45, 9, - 55, 49, 61, 57, 26, 41, 55, 73, 60, 60, 60, 52, 52, 44, 40, 37, - 32, 34, 32, 33, 28, 28, 25, 24, 22, 26, 22, 26, 24, 24, 22, 24, - 21, 22, 20, 22, 21, 26, 24, 25, 24, 21, 24, 29, 34, 55, 89, 104, - 114, 116, 118, 120, 120, 123, 124, 120, 106, 34, 13, 10, 12, 17, 28, 26, - 45, 53, 52, 56, 59, 60, 17, 12, 12, 12, 9, 9, 9, 9, 6, 8, - 8, 8, 9, 9, 9, 10, 9, 9, 10, 10, 8, 5, 8, 6, 8, 12, - 14, 30, 38, 37, 45, 51, 41, 36, 36, 36, 25, 5, 32, 46, 40, 38, - 26, 29, 25, 30, 20, 10, 16, 28, 49, 55, 52, 49, 45, 51, 45, 46, - 48, 41, 36, 8, 33, 49, 51, 41, 65, 88, 84, 93, 81, 76, 71, 69, - 68, 61, 38, 51, 36, 40, 36, 32, 28, 30, 29, 29, 28, 29, 28, 28, - 29, 29, 28, 32, 32, 28, 8, 10, 55, 60, 61, 67, 68, 61, 72, 60, - 56, 56, 21, 5, 53, 56, 63, 52, 56, 45, 51, 21, 12, 9, 8, 4, - 9, 9, 8, 6, 5, 4, 6, 5, 2, 5, 4, 4, 2, 9, 12, 10, - 5, 13, 10, 5, 2, 2, 5, 4, 6, 8, 8, 6, 6, 6, 8, 18, - 24, 10, 17, 13, 96, 99, 104, 95, 102, 88, 76, 52, 40, 38, 25, 24, - 22, 25, 18, 18, 18, 18, 13, 16, 14, 10, 9, 10, 13, 12, 10, 10, - 8, 9, 22, 24, 34, 36, 21, 32, 40, 46, 52, 48, 45, 24, 22, 17, - 12, 33, 34, 28, 13, 44, 81, 144, 189, 191, 187, 198, 186, 147, 100, 24, - 24, 49, 63, 53, 41, 51, 49, 81, 159, 220, 230, 232, 175, 130, 132, 140, - 151, 158, 153, 142, 106, 12, 4, 2, 5, 20, 41, 48, 55, 139, 128, 122, - 116, 88, 77, 71, 64, 42, 5, 26, 89, 103, 87, 83, 93, 104, 89, 85, - 84, 84, 84, 85, 91, 89, 89, 77, 65, 40, 33, 26, 18, 17, 16, 17, - 18, 25, 26, 24, 26, 29, 37, 36, 38, 41, 40, 38, 46, 57, 68, 75, - 72, 83, 76, 85, 71, 52, 25, 80, 68, 45, 41, 41, 37, 38, 37, 38, - 40, 37, 26, 34, 44, 46, 41, 40, 41, 44, 37, 29, 22, 18, 17, 10, - 13, 26, 28, 24, 21, 28, 26, 26, 30, 24, 5, 56, 45, 38, 37, 36, - 33, 41, 33, 29, 29, 32, 29, 28, 18, 21, 33, 26, 29, 30, 32, 25, - 32, 26, 25, 26, 51, 55, 48, 49, 49, 52, 49, 52, 44, 10, 67, 56, - 40, 41, 30, 34, 37, 33, 30, 33, 33, 32, 34, 34, 37, 37, 34, 36, - 37, 37, 46, 51, 53, 41, 48, 127, 136, 136, 140, 131, 128, 126, 124, 107, - 64, 49, 38, 36, 32, 34, 22, 18, 29, 56, 85, 76, 131, 186, 195, 201, - 158, 99, 51, 34, 29, 57, 34, 34, 32, 38, 40, 36, 33, 34, 36, 34, - 34, 28, 30, 26, 28, 25, 28, 24, 18, 24, 29, 29, 28, 32, 33, 28, - 36, 18, 6, 5, 91, 107, 97, 91, 77, 83, 79, 97, 88, 92, 52, 72, - 80, 77, 76, 84, 84, 73, 72, 80, 84, 44, 5, 34, 61, 57, 65, 48, - 25, 37, 41, 25, 20, 20, 34, 22, 24, 22, 22, 22, 22, 21, 17, 17, - 16, 20, 13, 14, 14, 17, 14, 17, 14, 14, 14, 14, 14, 13, 10, 13, - 13, 12, 12, 12, 12, 12, 12, 12, 13, 17, 22, 30, 41, 55, 69, 79, - 87, 87, 71, 33, 13, 13, 12, 17, 18, 32, 33, 34, 28, 29, 30, 25, - 33, 25, 25, 24, 20, 24, 21, 18, 17, 18, 17, 16, 16, 13, 14, 14, - 13, 13, 12, 12, 13, 12, 12, 18, 12, 18, 14, 56, 84, 87, 84, 81, - 87, 79, 76, 77, 49, 26, 1, 65, 51, 45, 41, 38, 49, 59, 40, 44, - 29, 16, 60, 71, 65, 63, 61, 68, 63, 63, 61, 55, 49, 36, 8, 55, - 48, 44, 63, 75, 64, 69, 61, 64, 61, 68, 45, 28, 29, 33, 29, 22, - 20, 18, 17, 17, 18, 16, 16, 16, 16, 12, 12, 10, 8, 12, 9, 9, - 6, 9, 12, 69, 71, 65, 64, 59, 55, 53, 56, 61, 72, 24, 5, 72, - 56, 42, 56, 46, 48, 45, 41, 37, 26, 12, 4, 18, 42, 36, 22, 26, - 37, 36, 22, 26, 33, 26, 16, 14, 26, 30, 29, 38, 34, 32, 26, 26, - 12, 2, 10, 22, 30, 24, 22, 26, 18, 21, 22, 22, 12, 17, 6, 69, - 77, 63, 45, 51, 48, 44, 26, 29, 29, 30, 20, 22, 20, 25, 18, 18, - 16, 16, 13, 17, 14, 13, 17, 20, 17, 17, 17, 21, 26, 24, 26, 32, - 38, 37, 26, 40, 57, 56, 26, 26, 49, 56, 51, 36, 34, 16, 12, 49, - 76, 134, 190, 189, 174, 187, 136, 112, 91, 99, 24, 26, 49, 76, 75, 80, - 65, 51, 88, 191, 222, 229, 228, 159, 128, 134, 139, 150, 151, 144, 134, 61, - 5, 5, 2, 4, 21, 44, 41, 69, 107, 107, 111, 108, 95, 108, 91, 83, - 45, 2, 107, 102, 93, 91, 91, 91, 85, 92, 89, 88, 83, 84, 85, 83, - 79, 80, 80, 79, 91, 84, 61, 40, 36, 24, 42, 57, 59, 56, 56, 53, - 52, 49, 52, 48, 42, 29, 36, 71, 80, 88, 83, 85, 81, 84, 87, 80, - 64, 28, 79, 69, 67, 61, 63, 61, 57, 56, 51, 49, 45, 26, 42, 56, - 65, 61, 60, 56, 59, 52, 42, 41, 38, 33, 10, 48, 49, 48, 59, 32, - 37, 55, 34, 32, 33, 12, 56, 71, 61, 64, 61, 49, 48, 36, 32, 38, - 30, 12, 21, 67, 36, 60, 45, 52, 38, 51, 38, 25, 17, 14, 26, 46, - 56, 55, 52, 52, 63, 52, 46, 40, 9, 67, 71, 41, 48, 40, 40, 40, - 40, 45, 37, 37, 26, 18, 32, 36, 45, 34, 40, 41, 48, 45, 46, 51, - 51, 41, 103, 132, 115, 84, 69, 65, 61, 51, 49, 42, 42, 34, 30, 33, - 26, 21, 37, 51, 55, 77, 79, 173, 186, 198, 197, 150, 97, 40, 34, 34, - 33, 34, 33, 36, 42, 41, 41, 59, 84, 124, 136, 154, 162, 153, 142, 97, - 52, 36, 29, 24, 26, 26, 21, 14, 17, 16, 21, 30, 21, 16, 17, 96, - 107, 68, 56, 55, 59, 55, 51, 75, 48, 63, 88, 88, 75, 95, 67, 69, - 63, 71, 73, 88, 41, 4, 45, 51, 72, 49, 41, 45, 25, 21, 21, 33, - 37, 13, 17, 14, 16, 18, 9, 14, 12, 12, 9, 6, 9, 9, 10, 12, - 12, 12, 10, 10, 10, 10, 12, 9, 12, 12, 12, 14, 14, 20, 14, 17, - 17, 20, 14, 13, 10, 13, 13, 14, 14, 16, 14, 14, 16, 13, 13, 12, - 12, 8, 17, 30, 40, 37, 30, 30, 28, 26, 24, 25, 24, 22, 28, 21, - 24, 21, 20, 20, 17, 17, 14, 14, 14, 14, 16, 13, 12, 14, 12, 14, - 16, 22, 26, 26, 22, 36, 67, 83, 79, 69, 68, 67, 69, 67, 75, 55, - 30, 2, 57, 53, 60, 33, 48, 48, 44, 40, 44, 34, 16, 63, 80, 84, - 79, 72, 77, 83, 77, 64, 64, 55, 38, 6, 55, 46, 51, 85, 88, 72, - 64, 87, 57, 26, 29, 32, 33, 36, 24, 21, 20, 17, 17, 17, 17, 16, - 13, 14, 14, 14, 12, 9, 9, 9, 10, 10, 8, 8, 10, 21, 68, 64, - 53, 56, 59, 52, 44, 44, 46, 91, 22, 6, 67, 64, 65, 64, 61, 60, - 53, 40, 41, 29, 12, 4, 37, 46, 45, 34, 32, 21, 26, 33, 24, 16, - 17, 9, 21, 40, 59, 53, 55, 41, 48, 42, 25, 14, 5, 42, 51, 32, - 32, 26, 26, 26, 25, 18, 16, 13, 17, 9, 48, 91, 65, 57, 42, 37, - 44, 29, 29, 29, 28, 21, 21, 24, 25, 17, 20, 20, 17, 20, 16, 16, - 18, 21, 18, 22, 24, 20, 21, 25, 26, 34, 25, 33, 13, 18, 57, 55, - 77, 51, 25, 22, 26, 18, 22, 18, 12, 46, 79, 85, 171, 189, 173, 170, - 139, 96, 89, 93, 68, 40, 32, 45, 69, 45, 51, 46, 63, 120, 204, 222, - 229, 222, 142, 127, 132, 139, 148, 147, 140, 112, 20, 4, 5, 1, 4, 22, - 41, 44, 59, 81, 88, 84, 77, 81, 79, 102, 79, 45, 10, 91, 108, 96, - 107, 92, 89, 91, 84, 80, 77, 61, 49, 64, 84, 97, 97, 91, 93, 72, - 80, 84, 67, 41, 29, 51, 63, 60, 63, 59, 61, 61, 57, 57, 61, 33, - 28, 57, 85, 92, 88, 87, 80, 85, 84, 76, 64, 53, 30, 75, 73, 67, - 67, 68, 63, 67, 56, 57, 59, 48, 28, 51, 55, 63, 63, 64, 75, 71, - 68, 56, 55, 41, 33, 13, 51, 60, 49, 59, 59, 53, 51, 55, 34, 30, - 9, 49, 69, 85, 88, 89, 64, 65, 53, 48, 34, 32, 9, 51, 75, 73, - 65, 63, 59, 59, 60, 49, 44, 28, 13, 34, 53, 59, 44, 42, 51, 55, - 53, 57, 28, 2, 75, 76, 71, 53, 33, 37, 28, 40, 34, 32, 36, 24, - 16, 30, 67, 56, 56, 55, 55, 49, 49, 48, 51, 59, 41, 119, 127, 108, - 85, 75, 61, 60, 53, 49, 41, 41, 33, 22, 21, 28, 33, 51, 53, 87, - 81, 112, 170, 198, 197, 201, 136, 96, 63, 59, 60, 49, 45, 49, 64, 80, - 112, 146, 179, 204, 216, 221, 225, 224, 217, 217, 208, 183, 153, 120, 65, 40, - 25, 22, 20, 20, 16, 12, 26, 17, 13, 4, 69, 107, 55, 45, 57, 60, - 56, 51, 71, 51, 67, 77, 85, 80, 85, 92, 83, 73, 75, 73, 81, 38, - 5, 45, 49, 57, 48, 41, 24, 25, 26, 22, 21, 20, 12, 55, 34, 26, - 24, 26, 40, 24, 30, 26, 25, 20, 21, 26, 16, 25, 29, 28, 25, 22, - 22, 21, 18, 18, 20, 20, 32, 28, 30, 28, 30, 28, 28, 25, 28, 18, - 16, 13, 14, 13, 10, 12, 12, 12, 13, 12, 13, 10, 5, 22, 37, 40, - 42, 45, 41, 44, 38, 38, 28, 26, 24, 52, 53, 34, 32, 30, 24, 25, - 29, 26, 10, 6, 25, 32, 36, 22, 17, 22, 29, 18, 33, 26, 30, 20, - 30, 65, 77, 69, 71, 73, 64, 64, 53, 61, 65, 22, 4, 37, 60, 56, - 55, 51, 61, 65, 44, 57, 29, 16, 59, 81, 81, 84, 80, 79, 85, 73, - 79, 63, 55, 45, 8, 53, 40, 45, 57, 68, 107, 83, 64, 29, 33, 30, - 46, 64, 61, 56, 40, 44, 44, 45, 37, 36, 25, 25, 24, 26, 22, 21, - 20, 17, 17, 16, 14, 18, 13, 12, 10, 51, 75, 84, 56, 40, 52, 73, - 49, 51, 71, 21, 8, 57, 63, 60, 56, 55, 49, 81, 36, 38, 37, 12, - 5, 41, 46, 32, 44, 28, 33, 17, 18, 20, 29, 14, 10, 38, 57, 63, - 60, 42, 30, 32, 53, 25, 16, 12, 46, 45, 29, 24, 25, 20, 32, 20, - 21, 12, 13, 16, 5, 51, 72, 44, 63, 49, 56, 56, 36, 28, 29, 32, - 25, 29, 28, 13, 20, 20, 20, 21, 18, 22, 21, 16, 21, 26, 26, 28, - 24, 25, 26, 30, 28, 45, 34, 22, 5, 46, 59, 51, 42, 42, 16, 26, - 16, 12, 21, 10, 51, 81, 102, 183, 179, 177, 146, 103, 93, 89, 110, 57, - 40, 29, 51, 56, 57, 48, 48, 64, 143, 212, 220, 226, 205, 131, 128, 134, - 140, 147, 143, 135, 71, 9, 5, 4, 1, 2, 22, 34, 26, 77, 77, 75, - 88, 88, 84, 80, 84, 65, 42, 20, 72, 102, 103, 96, 106, 92, 95, 91, - 93, 79, 60, 44, 83, 92, 93, 84, 77, 77, 80, 77, 79, 80, 49, 30, - 64, 72, 71, 72, 67, 67, 65, 60, 59, 69, 33, 26, 59, 88, 89, 95, - 93, 72, 73, 76, 75, 68, 45, 33, 73, 68, 65, 68, 64, 72, 67, 61, - 60, 64, 51, 36, 53, 63, 76, 65, 53, 76, 64, 80, 64, 57, 49, 37, - 14, 44, 64, 63, 53, 49, 49, 51, 55, 38, 34, 9, 60, 77, 83, 80, - 83, 88, 67, 73, 57, 48, 34, 6, 60, 73, 85, 73, 69, 68, 72, 65, - 64, 60, 26, 13, 57, 60, 67, 61, 45, 53, 72, 60, 52, 40, 8, 79, - 75, 64, 59, 44, 36, 37, 48, 51, 48, 44, 28, 13, 61, 69, 71, 68, - 67, 57, 59, 53, 55, 60, 57, 51, 108, 124, 111, 97, 84, 69, 63, 56, - 46, 41, 41, 24, 21, 30, 30, 49, 49, 63, 83, 71, 84, 182, 191, 208, - 177, 131, 99, 115, 119, 108, 118, 126, 150, 169, 194, 208, 218, 224, 225, 224, - 222, 220, 220, 220, 217, 212, 213, 206, 206, 175, 108, 42, 22, 21, 17, 24, - 18, 24, 32, 5, 4, 68, 103, 67, 51, 84, 59, 80, 67, 55, 42, 67, - 93, 89, 72, 83, 77, 93, 88, 65, 65, 76, 46, 8, 52, 48, 59, 52, - 52, 34, 33, 14, 24, 13, 29, 21, 41, 60, 52, 32, 36, 28, 38, 32, - 32, 32, 33, 20, 18, 32, 33, 34, 37, 30, 30, 30, 32, 32, 33, 28, - 26, 32, 38, 33, 34, 29, 32, 29, 30, 28, 18, 32, 37, 37, 37, 32, - 33, 20, 17, 17, 12, 13, 10, 6, 28, 40, 46, 41, 36, 37, 40, 44, - 41, 33, 26, 28, 48, 60, 38, 49, 46, 45, 33, 26, 28, 24, 8, 40, - 40, 37, 38, 38, 34, 32, 28, 28, 25, 25, 24, 21, 60, 75, 76, 69, - 68, 61, 63, 52, 59, 42, 29, 5, 53, 60, 72, 56, 48, 48, 53, 60, - 53, 33, 22, 71, 84, 77, 76, 79, 84, 87, 84, 83, 75, 61, 41, 6, - 53, 44, 55, 38, 52, 72, 93, 81, 29, 33, 28, 49, 67, 55, 52, 51, - 52, 49, 51, 52, 51, 33, 33, 22, 34, 33, 29, 28, 28, 24, 21, 25, - 25, 14, 12, 44, 65, 73, 60, 56, 48, 57, 48, 55, 53, 83, 28, 9, - 69, 64, 59, 76, 51, 53, 48, 53, 37, 37, 13, 4, 40, 52, 34, 71, - 40, 41, 40, 32, 24, 26, 14, 6, 49, 63, 64, 33, 26, 25, 26, 46, - 25, 12, 5, 38, 45, 30, 26, 22, 21, 16, 18, 17, 16, 16, 18, 10, - 57, 76, 64, 42, 49, 46, 60, 44, 46, 25, 24, 10, 8, 22, 18, 21, - 18, 21, 14, 17, 20, 10, 12, 21, 38, 41, 40, 44, 22, 16, 18, 22, - 29, 30, 25, 9, 52, 53, 49, 42, 32, 20, 24, 18, 14, 10, 10, 52, - 81, 106, 185, 179, 146, 112, 96, 85, 103, 100, 73, 37, 30, 38, 61, 52, - 40, 53, 96, 187, 216, 222, 228, 185, 124, 127, 132, 146, 143, 138, 114, 20, - 5, 5, 4, 1, 2, 12, 40, 21, 49, 108, 76, 76, 80, 73, 81, 81, - 88, 38, 2, 72, 108, 100, 97, 104, 99, 92, 89, 92, 71, 61, 42, 80, - 87, 76, 84, 85, 87, 103, 91, 80, 83, 60, 38, 71, 76, 80, 73, 80, - 73, 75, 64, 57, 64, 34, 24, 73, 91, 88, 89, 87, 71, 84, 77, 80, - 65, 56, 37, 69, 76, 61, 77, 76, 61, 64, 69, 67, 68, 55, 36, 59, - 72, 71, 68, 53, 65, 61, 75, 71, 64, 52, 37, 5, 46, 52, 63, 56, - 51, 49, 52, 55, 38, 34, 10, 55, 76, 79, 71, 67, 67, 68, 64, 63, - 49, 32, 8, 68, 85, 83, 73, 73, 67, 77, 75, 68, 59, 37, 14, 57, - 63, 69, 53, 64, 53, 65, 59, 49, 41, 6, 76, 67, 59, 53, 53, 41, - 42, 56, 59, 53, 44, 26, 13, 63, 65, 75, 69, 71, 59, 63, 63, 56, - 49, 46, 44, 95, 119, 116, 92, 96, 88, 72, 67, 52, 48, 25, 17, 25, - 45, 52, 52, 65, 53, 77, 69, 80, 155, 201, 204, 171, 119, 91, 111, 182, - 186, 191, 199, 204, 209, 218, 220, 220, 220, 213, 208, 193, 190, 190, 179, 170, - 159, 162, 166, 182, 198, 197, 151, 61, 29, 20, 16, 20, 20, 18, 1, 5, - 89, 114, 80, 56, 55, 67, 52, 65, 64, 37, 67, 88, 84, 68, 65, 67, - 68, 72, 72, 69, 71, 46, 9, 55, 34, 57, 44, 57, 52, 34, 30, 16, - 12, 21, 21, 49, 53, 37, 45, 45, 32, 38, 44, 46, 38, 29, 13, 30, - 48, 64, 60, 34, 34, 34, 40, 40, 38, 37, 21, 30, 57, 49, 51, 49, - 34, 33, 33, 30, 29, 21, 30, 44, 38, 42, 36, 36, 30, 28, 28, 25, - 25, 12, 5, 33, 40, 45, 51, 55, 55, 44, 30, 45, 34, 28, 22, 45, - 45, 61, 44, 41, 44, 41, 33, 34, 26, 4, 46, 40, 25, 41, 37, 22, - 24, 38, 30, 36, 28, 24, 16, 59, 75, 77, 59, 57, 51, 49, 61, 41, - 48, 30, 1, 55, 60, 69, 53, 42, 38, 42, 49, 63, 36, 24, 77, 85, - 93, 87, 80, 73, 75, 84, 85, 80, 67, 41, 6, 53, 40, 45, 36, 60, - 68, 67, 49, 30, 34, 33, 52, 63, 61, 53, 52, 49, 52, 46, 45, 52, - 52, 32, 26, 34, 37, 32, 30, 29, 29, 26, 30, 28, 17, 8, 59, 51, - 71, 42, 52, 51, 56, 53, 48, 53, 65, 32, 9, 68, 64, 72, 75, 76, - 75, 48, 53, 38, 37, 14, 4, 32, 53, 44, 46, 51, 38, 33, 38, 36, - 28, 14, 14, 53, 63, 59, 25, 24, 37, 37, 40, 24, 16, 5, 56, 33, - 36, 17, 17, 16, 17, 17, 20, 18, 16, 17, 8, 41, 85, 63, 55, 46, - 59, 37, 48, 40, 37, 26, 6, 10, 18, 29, 25, 16, 16, 14, 17, 21, - 12, 13, 42, 40, 40, 40, 30, 41, 36, 41, 28, 29, 25, 25, 16, 51, - 56, 44, 40, 32, 18, 12, 16, 16, 13, 12, 44, 77, 84, 178, 177, 131, - 102, 97, 95, 118, 112, 73, 25, 30, 40, 55, 52, 46, 72, 159, 202, 208, - 222, 217, 146, 122, 127, 139, 142, 136, 123, 48, 6, 4, 4, 2, 1, 4, - 20, 34, 25, 17, 108, 77, 76, 81, 85, 88, 83, 80, 37, 2, 80, 100, - 95, 104, 102, 100, 97, 97, 85, 71, 56, 38, 79, 75, 84, 83, 96, 93, - 95, 85, 87, 80, 72, 41, 75, 85, 87, 85, 77, 80, 71, 67, 61, 60, - 32, 48, 80, 87, 87, 76, 81, 61, 65, 65, 67, 67, 64, 38, 60, 73, - 63, 56, 61, 68, 72, 77, 64, 64, 65, 34, 59, 69, 67, 61, 60, 72, - 67, 79, 71, 71, 53, 37, 8, 42, 60, 65, 52, 67, 55, 51, 52, 38, - 36, 14, 56, 80, 72, 72, 72, 73, 72, 67, 67, 51, 32, 8, 63, 67, - 76, 76, 77, 77, 81, 77, 76, 59, 32, 25, 61, 60, 69, 59, 65, 65, - 79, 56, 46, 36, 6, 76, 76, 63, 57, 53, 69, 69, 69, 68, 63, 45, - 26, 10, 65, 72, 72, 67, 68, 64, 67, 72, 57, 59, 61, 40, 83, 111, - 112, 102, 84, 92, 77, 71, 56, 64, 29, 14, 38, 51, 65, 68, 65, 53, - 100, 72, 93, 108, 177, 197, 174, 115, 103, 111, 148, 183, 193, 195, 202, 205, - 206, 208, 199, 193, 185, 166, 147, 143, 143, 144, 136, 140, 136, 143, 146, 144, - 155, 179, 169, 73, 18, 16, 22, 18, 16, 12, 14, 91, 95, 81, 56, 57, - 65, 53, 64, 59, 37, 64, 88, 79, 69, 75, 68, 67, 63, 77, 76, 68, - 45, 9, 46, 33, 67, 72, 60, 40, 29, 22, 21, 13, 26, 9, 42, 59, - 44, 46, 34, 37, 42, 44, 44, 41, 28, 14, 42, 60, 59, 63, 65, 45, - 44, 42, 38, 44, 33, 22, 56, 52, 56, 52, 51, 48, 36, 34, 36, 32, - 21, 41, 40, 49, 44, 46, 42, 36, 29, 30, 30, 25, 12, 5, 37, 46, - 45, 42, 38, 44, 44, 30, 37, 37, 29, 18, 46, 45, 56, 52, 57, 60, - 44, 53, 32, 26, 4, 51, 41, 34, 40, 34, 44, 37, 44, 40, 41, 34, - 24, 29, 59, 83, 59, 60, 56, 65, 52, 55, 64, 42, 32, 1, 65, 60, - 55, 52, 61, 65, 67, 64, 51, 38, 21, 72, 80, 88, 99, 92, 85, 83, - 84, 77, 83, 67, 41, 5, 52, 48, 46, 42, 71, 26, 29, 28, 29, 36, - 30, 52, 61, 59, 63, 48, 61, 55, 53, 46, 49, 48, 40, 26, 30, 34, - 44, 41, 44, 38, 37, 36, 28, 18, 8, 51, 75, 69, 51, 55, 71, 64, - 63, 49, 45, 67, 24, 12, 64, 68, 55, 53, 56, 56, 56, 53, 37, 37, - 17, 5, 41, 61, 32, 40, 34, 55, 44, 45, 37, 24, 13, 20, 53, 67, - 38, 30, 26, 41, 42, 41, 22, 12, 5, 52, 57, 34, 30, 22, 25, 24, - 24, 26, 21, 18, 18, 9, 48, 72, 81, 59, 53, 42, 29, 36, 36, 33, - 22, 5, 22, 41, 38, 32, 26, 26, 25, 32, 22, 12, 8, 41, 34, 37, - 26, 36, 41, 28, 40, 32, 30, 25, 14, 16, 49, 65, 32, 34, 25, 20, - 14, 16, 14, 14, 10, 45, 67, 79, 127, 171, 143, 107, 99, 102, 126, 114, - 53, 44, 36, 45, 49, 41, 69, 134, 198, 208, 212, 220, 193, 124, 123, 128, - 143, 136, 128, 80, 10, 4, 8, 4, 2, 1, 2, 21, 34, 38, 18, 76, - 80, 85, 99, 96, 89, 81, 80, 38, 4, 92, 103, 97, 102, 102, 100, 91, - 99, 79, 68, 56, 36, 75, 100, 108, 100, 100, 97, 87, 83, 81, 81, 75, - 44, 45, 69, 75, 69, 73, 72, 72, 65, 64, 60, 32, 52, 85, 89, 72, - 69, 68, 71, 69, 71, 69, 64, 61, 38, 55, 80, 68, 65, 56, 67, 53, - 61, 53, 52, 65, 38, 63, 72, 68, 67, 71, 73, 71, 60, 63, 73, 53, - 36, 6, 46, 53, 65, 56, 56, 61, 52, 49, 42, 37, 9, 45, 79, 73, - 73, 75, 73, 69, 71, 63, 49, 33, 5, 44, 83, 71, 83, 77, 80, 81, - 80, 73, 72, 30, 10, 55, 67, 72, 65, 60, 61, 57, 59, 55, 28, 1, - 72, 69, 52, 63, 56, 52, 51, 56, 53, 60, 44, 25, 9, 67, 59, 65, - 65, 64, 65, 73, 85, 63, 59, 59, 46, 63, 107, 110, 100, 81, 88, 77, - 76, 68, 60, 34, 17, 45, 64, 67, 61, 57, 56, 100, 77, 102, 77, 147, - 205, 177, 107, 99, 100, 120, 130, 157, 166, 175, 178, 179, 173, 158, 140, 134, - 138, 139, 140, 144, 154, 157, 161, 146, 139, 134, 128, 135, 136, 173, 146, 69, - 16, 22, 16, 12, 8, 5, 75, 89, 79, 44, 55, 69, 57, 64, 55, 38, - 64, 84, 87, 79, 68, 75, 69, 68, 81, 75, 71, 44, 12, 38, 40, 42, - 46, 51, 51, 30, 22, 21, 13, 36, 8, 33, 48, 53, 52, 68, 65, 75, - 73, 69, 45, 34, 6, 46, 60, 55, 65, 55, 53, 55, 67, 71, 49, 37, - 20, 55, 49, 65, 52, 46, 52, 46, 45, 36, 33, 24, 42, 45, 45, 45, - 41, 41, 38, 36, 32, 29, 24, 13, 4, 37, 48, 40, 34, 44, 60, 37, - 40, 41, 34, 29, 18, 55, 52, 55, 46, 51, 51, 52, 55, 40, 21, 4, - 49, 48, 57, 45, 42, 45, 52, 40, 38, 37, 42, 29, 18, 41, 75, 81, - 81, 79, 73, 80, 81, 59, 55, 22, 0, 49, 61, 60, 68, 77, 64, 63, - 61, 48, 38, 21, 56, 85, 83, 85, 81, 83, 84, 85, 93, 88, 80, 41, - 5, 52, 36, 52, 65, 37, 56, 38, 44, 28, 36, 34, 51, 56, 69, 69, - 53, 56, 61, 64, 57, 59, 51, 48, 29, 34, 44, 38, 41, 45, 42, 41, - 41, 32, 17, 9, 64, 73, 67, 75, 59, 60, 57, 48, 48, 55, 68, 24, - 14, 36, 68, 57, 48, 56, 56, 52, 46, 37, 34, 14, 5, 45, 53, 44, - 40, 45, 46, 49, 37, 29, 20, 17, 12, 53, 64, 38, 25, 38, 33, 38, - 37, 22, 14, 4, 51, 38, 40, 33, 45, 44, 53, 51, 45, 26, 20, 20, - 9, 42, 76, 87, 85, 61, 64, 32, 32, 34, 28, 20, 14, 33, 33, 22, - 30, 40, 40, 41, 29, 18, 12, 9, 46, 33, 33, 18, 42, 41, 34, 38, - 28, 30, 29, 21, 9, 48, 63, 40, 32, 20, 20, 17, 30, 10, 17, 9, - 33, 52, 72, 95, 131, 166, 111, 99, 126, 136, 96, 45, 45, 57, 44, 53, - 71, 132, 186, 208, 209, 220, 209, 150, 120, 127, 138, 135, 124, 96, 20, 5, - 5, 5, 5, 2, 1, 1, 14, 33, 5, 28, 77, 79, 79, 77, 79, 81, - 83, 69, 33, 5, 65, 103, 96, 97, 96, 97, 100, 89, 71, 65, 57, 29, - 84, 83, 91, 81, 95, 84, 83, 76, 72, 72, 68, 67, 46, 51, 60, 59, - 69, 71, 72, 61, 63, 61, 28, 55, 81, 80, 69, 75, 76, 75, 69, 75, - 65, 81, 57, 42, 55, 79, 75, 77, 67, 72, 61, 59, 57, 67, 51, 42, - 67, 76, 71, 80, 63, 64, 73, 69, 71, 56, 53, 40, 10, 38, 60, 63, - 63, 57, 64, 55, 55, 44, 40, 13, 72, 80, 85, 87, 77, 73, 73, 72, - 68, 48, 33, 4, 61, 84, 72, 79, 81, 80, 88, 80, 76, 65, 42, 12, - 59, 73, 77, 63, 64, 61, 61, 65, 49, 44, 5, 67, 81, 67, 81, 69, - 81, 72, 71, 67, 63, 44, 25, 9, 71, 68, 69, 77, 64, 63, 61, 72, - 72, 57, 63, 45, 55, 99, 102, 97, 97, 84, 80, 79, 73, 65, 36, 17, - 53, 67, 68, 68, 69, 91, 75, 100, 65, 107, 84, 190, 189, 120, 108, 102, - 107, 114, 127, 131, 132, 136, 132, 130, 123, 115, 114, 112, 116, 130, 140, 150, - 154, 155, 158, 143, 140, 142, 139, 128, 138, 167, 80, 17, 16, 17, 13, 5, - 5, 67, 93, 75, 57, 59, 61, 59, 65, 49, 32, 61, 83, 93, 93, 81, - 80, 83, 83, 87, 73, 69, 44, 17, 37, 38, 51, 40, 37, 26, 24, 12, - 18, 24, 21, 28, 41, 69, 67, 65, 65, 59, 67, 51, 44, 45, 29, 9, - 44, 64, 67, 55, 56, 56, 53, 57, 55, 44, 37, 20, 72, 46, 69, 45, - 56, 49, 48, 46, 49, 36, 22, 37, 45, 38, 38, 38, 44, 36, 36, 33, - 33, 25, 14, 5, 37, 46, 40, 30, 40, 36, 36, 28, 29, 34, 26, 20, - 51, 61, 57, 48, 46, 48, 53, 55, 36, 28, 12, 49, 46, 45, 59, 46, - 45, 45, 48, 46, 51, 52, 40, 22, 38, 61, 71, 72, 69, 52, 56, 51, - 51, 44, 32, 4, 52, 60, 59, 64, 61, 57, 51, 49, 51, 44, 32, 36, - 73, 77, 79, 77, 76, 79, 79, 76, 77, 69, 46, 5, 49, 48, 33, 38, - 28, 33, 33, 33, 33, 37, 37, 33, 57, 46, 49, 45, 51, 46, 49, 46, - 51, 48, 48, 41, 32, 32, 32, 28, 32, 36, 37, 42, 32, 21, 9, 63, - 73, 61, 49, 48, 55, 48, 49, 57, 68, 69, 34, 12, 21, 63, 71, 63, - 71, 59, 53, 33, 34, 25, 14, 5, 38, 49, 53, 63, 49, 53, 46, 41, - 38, 18, 16, 18, 52, 76, 51, 24, 26, 41, 42, 53, 26, 10, 4, 33, - 51, 37, 36, 38, 30, 26, 30, 33, 40, 21, 22, 9, 38, 64, 77, 71, - 53, 55, 24, 32, 33, 29, 16, 13, 40, 29, 32, 26, 25, 20, 22, 26, - 20, 9, 9, 45, 26, 36, 38, 38, 32, 33, 33, 30, 30, 32, 22, 8, - 46, 53, 33, 17, 26, 20, 17, 12, 14, 9, 14, 34, 40, 34, 59, 77, - 155, 143, 100, 110, 132, 123, 56, 42, 52, 67, 107, 148, 185, 198, 204, 217, - 213, 162, 119, 123, 135, 131, 120, 87, 18, 6, 5, 6, 5, 4, 2, 1, - 1, 20, 25, 57, 65, 67, 65, 65, 65, 65, 65, 63, 61, 32, 13, 37, - 71, 103, 107, 87, 88, 71, 69, 69, 51, 51, 29, 79, 77, 75, 76, 76, - 79, 75, 64, 59, 57, 59, 56, 60, 71, 71, 61, 57, 57, 57, 55, 60, - 48, 26, 71, 80, 87, 69, 69, 61, 64, 61, 60, 59, 64, 63, 52, 45, - 61, 60, 55, 60, 59, 73, 64, 63, 67, 64, 57, 56, 55, 59, 68, 61, - 56, 55, 55, 53, 52, 49, 38, 5, 36, 60, 56, 55, 53, 53, 53, 55, - 56, 37, 16, 51, 68, 65, 67, 67, 68, 64, 77, 68, 48, 30, 6, 65, - 84, 79, 73, 72, 76, 68, 75, 73, 61, 34, 6, 56, 61, 72, 71, 63, - 71, 71, 64, 46, 42, 5, 61, 68, 67, 67, 64, 64, 63, 61, 59, 59, - 42, 24, 8, 65, 67, 72, 68, 73, 68, 75, 61, 68, 68, 60, 48, 45, - 76, 100, 87, 81, 71, 59, 61, 65, 63, 41, 16, 46, 64, 84, 75, 95, - 107, 77, 112, 112, 100, 69, 111, 174, 132, 100, 102, 108, 111, 112, 107, 120, - 116, 120, 112, 108, 104, 104, 108, 147, 153, 128, 148, 159, 154, 154, 162, 147, - 146, 143, 143, 139, 163, 81, 13, 12, 14, 13, 2, 4, 63, 85, 75, 60, - 55, 61, 59, 65, 52, 30, 63, 69, 83, 80, 73, 72, 68, 71, 68, 59, - 56, 45, 16, 8, 28, 26, 9, 5, 20, 21, 2, 5, 12, 14, 30, 44, - 60, 68, 56, 53, 48, 48, 45, 45, 49, 26, 9, 38, 59, 69, 61, 64, - 67, 57, 61, 59, 46, 38, 21, 52, 45, 60, 48, 40, 40, 33, 30, 40, - 37, 33, 33, 28, 32, 29, 29, 26, 25, 26, 28, 25, 24, 13, 4, 38, - 53, 22, 22, 25, 21, 22, 24, 24, 26, 24, 25, 25, 36, 48, 48, 36, - 34, 33, 32, 26, 29, 4, 46, 45, 42, 40, 40, 41, 42, 40, 40, 37, - 38, 37, 34, 26, 24, 30, 32, 30, 28, 30, 30, 30, 32, 34, 1, 26, - 52, 53, 51, 49, 49, 29, 26, 29, 33, 46, 48, 40, 52, 64, 57, 60, - 59, 63, 69, 68, 57, 41, 5, 41, 29, 26, 29, 29, 29, 32, 34, 20, - 18, 20, 38, 38, 41, 41, 45, 42, 44, 44, 45, 44, 45, 44, 44, 42, - 48, 42, 42, 40, 30, 32, 40, 30, 24, 12, 60, 75, 55, 60, 64, 48, - 67, 71, 57, 49, 46, 36, 13, 16, 59, 55, 59, 32, 29, 29, 20, 24, - 20, 14, 4, 36, 41, 36, 21, 34, 34, 37, 26, 26, 21, 16, 17, 49, - 61, 32, 33, 29, 38, 40, 56, 18, 13, 4, 48, 41, 42, 36, 32, 29, - 29, 29, 26, 24, 24, 25, 10, 21, 34, 57, 51, 34, 24, 29, 25, 22, - 29, 25, 13, 40, 30, 34, 24, 32, 25, 24, 21, 20, 10, 9, 38, 40, - 36, 32, 33, 33, 32, 25, 28, 24, 22, 14, 9, 40, 49, 24, 9, 10, - 13, 16, 14, 13, 10, 12, 24, 33, 32, 37, 57, 73, 170, 112, 107, 138, - 130, 124, 120, 123, 150, 177, 182, 193, 195, 209, 206, 162, 116, 122, 130, 119, - 111, 81, 22, 6, 6, 6, 5, 4, 4, 4, 1, 1, 12, 14, 12, 10, - 38, 36, 34, 30, 26, 25, 21, 20, 16, 18, 20, 26, 32, 30, 38, 40, - 48, 38, 48, 52, 42, 28, 42, 34, 40, 37, 30, 30, 36, 29, 28, 25, - 29, 28, 34, 28, 34, 34, 49, 67, 69, 69, 49, 38, 26, 61, 67, 69, - 61, 59, 53, 63, 60, 55, 64, 63, 59, 55, 59, 64, 72, 64, 63, 63, - 61, 61, 61, 59, 57, 57, 56, 56, 34, 36, 25, 18, 17, 17, 16, 16, - 13, 17, 5, 14, 16, 18, 20, 21, 25, 44, 52, 45, 37, 20, 5, 42, - 60, 32, 40, 46, 60, 32, 45, 44, 24, 6, 32, 44, 36, 36, 44, 44, - 37, 37, 45, 45, 18, 8, 32, 41, 30, 41, 37, 37, 28, 42, 34, 20, - 6, 16, 38, 38, 37, 36, 40, 40, 38, 38, 41, 40, 21, 8, 48, 71, - 65, 51, 49, 61, 61, 44, 49, 56, 61, 52, 56, 59, 53, 49, 56, 53, - 55, 48, 45, 45, 36, 16, 49, 75, 76, 65, 64, 79, 80, 76, 85, 107, - 108, 142, 174, 167, 112, 106, 97, 108, 99, 56, 45, 45, 46, 45, 42, 44, - 44, 81, 103, 163, 123, 126, 153, 155, 159, 157, 154, 161, 147, 147, 140, 162, - 91, 20, 12, 13, 2, 9, 8, 22, 42, 64, 83, 81, 75, 84, 55, 48, - 30, 55, 56, 71, 69, 65, 52, 46, 44, 40, 40, 30, 22, 21, 25, 10, - 13, 12, 10, 8, 9, 6, 6, 5, 5, 6, 14, 40, 46, 46, 44, 40, - 60, 46, 56, 42, 16, 9, 32, 55, 49, 42, 51, 52, 49, 46, 49, 46, - 38, 24, 63, 45, 37, 40, 38, 38, 38, 38, 36, 34, 33, 32, 33, 32, - 32, 32, 30, 29, 28, 28, 28, 25, 25, 4, 18, 21, 17, 17, 20, 21, - 20, 21, 21, 24, 21, 21, 24, 24, 25, 25, 24, 24, 24, 25, 24, 21, - 4, 25, 29, 26, 28, 28, 29, 29, 29, 30, 30, 32, 32, 26, 30, 33, - 32, 28, 34, 33, 29, 24, 34, 29, 22, 9, 33, 20, 17, 16, 20, 12, - 18, 21, 13, 13, 22, 13, 28, 34, 30, 28, 42, 48, 44, 33, 48, 49, - 29, 6, 37, 9, 10, 10, 10, 8, 8, 9, 9, 6, 6, 8, 6, 6, - 6, 8, 8, 8, 8, 10, 10, 9, 10, 12, 14, 14, 16, 18, 21, 40, - 38, 45, 32, 21, 9, 51, 69, 56, 67, 71, 64, 63, 51, 52, 36, 33, - 24, 20, 12, 18, 18, 20, 22, 21, 14, 14, 12, 10, 17, 6, 12, 12, - 12, 13, 13, 20, 28, 17, 14, 17, 16, 25, 32, 28, 21, 29, 20, 24, - 28, 25, 20, 12, 4, 38, 36, 38, 38, 33, 30, 29, 28, 29, 26, 25, - 26, 24, 25, 22, 22, 22, 22, 20, 22, 21, 22, 21, 20, 14, 36, 21, - 25, 24, 22, 21, 14, 18, 20, 12, 6, 5, 8, 6, 8, 8, 6, 5, - 6, 20, 18, 17, 9, 9, 33, 14, 9, 8, 10, 9, 5, 8, 8, 6, - 21, 24, 12, 26, 26, 37, 42, 88, 132, 112, 123, 148, 151, 159, 167, 174, - 181, 191, 194, 205, 198, 165, 120, 120, 119, 110, 96, 60, 18, 9, 6, 8, - 4, 5, 5, 6, 2, 4, 0, 0, 0, 0, 0, 65, 60, 75, 77, 69, - 63, 84, 80, 29, 6, 44, 73, 68, 52, 63, 57, 33, 29, 34, 32, 30, - 28, 17, 21, 40, 48, 63, 68, 81, 81, 96, 103, 84, 67, 85, 93, 85, - 76, 48, 37, 34, 30, 52, 45, 26, 42, 44, 36, 37, 29, 30, 22, 25, - 24, 22, 24, 21, 17, 16, 13, 13, 12, 12, 12, 12, 12, 12, 13, 12, - 10, 12, 21, 53, 69, 79, 77, 81, 80, 81, 75, 75, 42, 6, 79, 108, - 107, 89, 53, 52, 44, 28, 26, 37, 29, 5, 1, 13, 9, 10, 1, 10, - 6, 1, 1, 8, 6, 0, 0, 10, 2, 1, 1, 5, 2, 1, 4, 8, - 8, 1, 1, 4, 13, 1, 0, 4, 1, 2, 0, 0, 4, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 2, 14, 5, 16, 13, 17, 16, 18, 24, 29, - 44, 44, 46, 55, 37, 36, 29, 33, 29, 28, 28, 22, 21, 32, 26, 28, - 18, 48, 52, 51, 60, 72, 72, 67, 96, 76, 110, 132, 146, 194, 189, 150, - 110, 100, 102, 100, 32, 29, 28, 37, 34, 32, 37, 36, 56, 95, 154, 161, - 126, 122, 150, 153, 155, 155, 162, 143, 144, 158, 151, 85, 17, 13, 10, 4, - 2, 13, 18, 20, 26, 18, 17, 29, 29, 37, 51, 30, 51, 52, 46, 33, - 34, 37, 34, 22, 24, 25, 18, 12, 6, 8, 9, 5, 4, 4, 2, 4, - 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 2, 4, 5, 5, 5, - 6, 12, 14, 20, 18, 21, 21, 26, 34, 46, 49, 38, 25, 46, 34, 34, - 28, 21, 22, 20, 16, 14, 14, 10, 8, 8, 8, 5, 4, 4, 6, 2, - 2, 2, 6, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 2, - 2, 4, 5, 1, 2, 8, 9, 1, 4, 12, 13, 10, 2, 10, 9, 1, - 1, 8, 1, 1, 5, 5, 0, 0, 0, 4, 1, 0, 2, 2, 0, 0, - 0, 2, 0, 0, 8, 10, 20, 40, 63, 42, 48, 57, 71, 60, 45, 25, - 17, 42, 60, 60, 45, 46, 22, 12, 12, 9, 13, 9, 5, 6, 26, 28, - 22, 22, 33, 29, 33, 26, 41, 20, 1, 16, 75, 96, 59, 69, 77, 88, - 67, 69, 64, 64, 60, 68, 76, 76, 65, 32, 22, 21, 21, 32, 18, 9, - 24, 22, 22, 21, 24, 21, 21, 22, 24, 22, 24, 21, 20, 16, 9, 6, - 14, 21, 10, 12, 38, 59, 64, 36, 6, 45, 59, 56, 22, 20, 18, 22, - 14, 20, 10, 34, 17, 12, 8, 8, 13, 8, 20, 17, 21, 13, 14, 17, - 6, 18, 18, 30, 14, 17, 16, 18, 16, 20, 20, 16, 16, 18, 18, 16, - 17, 20, 17, 16, 16, 21, 17, 6, 18, 36, 26, 26, 21, 25, 28, 30, - 41, 29, 21, 8, 45, 65, 65, 51, 64, 61, 59, 29, 21, 17, 8, 4, - 2, 9, 25, 33, 33, 36, 29, 32, 20, 28, 14, 14, 36, 75, 96, 65, - 63, 65, 53, 127, 151, 138, 146, 123, 126, 128, 144, 147, 154, 153, 155, 140, - 127, 131, 107, 72, 53, 29, 10, 9, 9, 8, 5, 9, 12, 18, 17, 21, - 1, 0, 18, 64, 64, 61, 115, 114, 110, 108, 96, 102, 96, 92, 61, 18, - 44, 59, 55, 59, 68, 63, 63, 64, 53, 55, 30, 18, 52, 112, 123, 115, - 116, 115, 114, 107, 103, 89, 102, 107, 106, 107, 99, 108, 106, 97, 87, 76, - 51, 48, 25, 28, 33, 42, 48, 61, 67, 91, 76, 83, 67, 48, 45, 53, - 100, 107, 100, 89, 112, 103, 80, 108, 95, 96, 88, 93, 91, 97, 112, 96, - 89, 76, 87, 91, 79, 87, 77, 45, 9, 80, 106, 106, 99, 107, 107, 83, - 93, 57, 38, 29, 42, 60, 60, 59, 51, 46, 34, 46, 36, 12, 14, 4, - 24, 108, 104, 72, 76, 99, 97, 76, 76, 73, 28, 2, 18, 67, 81, 53, - 56, 53, 52, 61, 52, 26, 10, 44, 57, 60, 46, 42, 46, 46, 44, 42, - 33, 29, 4, 6, 81, 99, 96, 80, 95, 69, 30, 21, 18, 17, 14, 16, - 20, 34, 52, 56, 61, 61, 65, 73, 71, 69, 51, 18, 85, 87, 88, 75, - 107, 80, 88, 75, 84, 126, 143, 199, 202, 190, 177, 119, 104, 100, 110, 30, - 28, 30, 29, 32, 26, 28, 42, 55, 92, 175, 177, 119, 126, 110, 127, 134, - 130, 126, 154, 150, 138, 97, 68, 17, 13, 5, 20, 16, 20, 69, 80, 63, - 63, 38, 30, 30, 28, 44, 22, 18, 29, 41, 44, 46, 37, 42, 41, 60, - 56, 59, 61, 96, 91, 100, 89, 97, 91, 84, 102, 97, 89, 91, 83, 81, - 84, 88, 100, 81, 85, 73, 44, 52, 41, 30, 2, 9, 69, 103, 108, 77, - 73, 61, 55, 45, 48, 30, 34, 26, 28, 42, 40, 44, 29, 41, 41, 64, - 36, 33, 37, 72, 96, 100, 83, 71, 84, 87, 80, 79, 85, 77, 13, 2, - 45, 104, 75, 77, 72, 80, 77, 85, 95, 91, 88, 77, 88, 89, 104, 88, - 87, 87, 88, 84, 81, 16, 5, 26, 91, 110, 84, 87, 89, 89, 87, 95, - 92, 93, 95, 89, 97, 108, 104, 102, 96, 92, 88, 80, 85, 80, 18, 1, - 44, 72, 83, 88, 81, 79, 83, 73, 80, 71, 34, 14, 44, 73, 59, 59, - 53, 51, 56, 48, 45, 36, 9, 28, 69, 79, 76, 75, 69, 64, 40, 42, - 53, 36, 22, 1, 80, 84, 67, 72, 68, 77, 65, 80, 63, 65, 59, 63, - 42, 59, 72, 60, 55, 65, 64, 57, 45, 26, 9, 8, 8, 6, 5, 6, - 6, 6, 5, 5, 6, 6, 6, 6, 13, 61, 76, 69, 61, 67, 57, 60, - 65, 64, 46, 6, 53, 69, 60, 55, 44, 42, 36, 48, 49, 38, 8, 13, - 63, 75, 72, 65, 59, 44, 22, 12, 12, 10, 4, 0, 0, 4, 2, 0, - 0, 2, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 6, 1, 1, 1, - 10, 2, 2, 17, 33, 49, 79, 80, 83, 81, 79, 73, 36, 26, 8, 53, - 65, 42, 48, 53, 45, 44, 42, 55, 46, 32, 10, 5, 45, 65, 73, 72, - 67, 75, 65, 65, 29, 16, 14, 100, 110, 88, 97, 85, 97, 89, 99, 41, - 61, 61, 88, 89, 99, 134, 135, 132, 127, 132, 131, 116, 84, 57, 22, 12, - 13, 14, 13, 8, 6, 10, 17, 13, 20, 29, 8, 1, 4, 42, 68, 83, - 84, 84, 91, 91, 103, 99, 104, 95, 100, 63, 18, 59, 61, 72, 52, 65, - 65, 48, 72, 72, 55, 29, 14, 103, 111, 104, 80, 85, 81, 75, 79, 84, - 79, 91, 67, 84, 89, 110, 111, 103, 106, 97, 97, 64, 59, 25, 69, 97, - 93, 97, 92, 97, 92, 106, 119, 83, 73, 73, 56, 72, 111, 103, 84, 89, - 104, 111, 118, 112, 96, 95, 97, 77, 79, 92, 92, 87, 88, 80, 76, 76, - 77, 80, 53, 6, 91, 108, 102, 104, 97, 97, 96, 102, 80, 56, 30, 53, - 65, 63, 68, 61, 60, 65, 75, 65, 30, 9, 12, 83, 107, 95, 89, 89, - 91, 96, 96, 93, 88, 33, 0, 89, 96, 100, 95, 88, 84, 88, 81, 76, - 51, 13, 67, 59, 56, 44, 48, 36, 37, 26, 25, 25, 32, 1, 5, 83, - 97, 99, 96, 93, 88, 85, 92, 84, 80, 67, 75, 59, 72, 89, 80, 88, - 84, 99, 100, 93, 84, 51, 18, 92, 104, 96, 112, 87, 100, 80, 83, 111, - 144, 197, 198, 194, 198, 170, 111, 104, 106, 110, 36, 28, 25, 30, 32, 28, - 46, 40, 60, 87, 186, 186, 123, 120, 127, 123, 92, 103, 99, 83, 76, 87, - 72, 49, 13, 13, 6, 18, 14, 45, 85, 77, 79, 71, 76, 76, 65, 68, - 36, 25, 42, 100, 104, 96, 95, 93, 104, 85, 99, 53, 83, 71, 69, 87, - 81, 93, 85, 77, 81, 88, 75, 72, 80, 73, 76, 65, 46, 33, 61, 38, - 42, 37, 36, 41, 33, 2, 8, 83, 118, 100, 96, 108, 107, 87, 96, 104, - 69, 52, 28, 55, 95, 99, 96, 95, 87, 95, 99, 93, 110, 89, 64, 61, - 65, 64, 61, 69, 76, 64, 77, 69, 76, 38, 4, 99, 91, 60, 71, 85, - 79, 85, 69, 81, 91, 88, 79, 59, 55, 61, 51, 46, 59, 59, 52, 48, - 18, 0, 97, 119, 115, 116, 112, 116, 111, 112, 106, 104, 108, 103, 80, 63, - 75, 77, 76, 81, 81, 81, 64, 63, 68, 18, 12, 60, 79, 80, 60, 52, - 61, 56, 57, 57, 76, 37, 20, 55, 71, 52, 59, 56, 69, 53, 34, 55, - 37, 9, 22, 73, 72, 57, 75, 61, 65, 71, 57, 36, 32, 22, 4, 79, - 79, 60, 59, 51, 64, 72, 72, 64, 73, 40, 32, 59, 72, 60, 57, 53, - 51, 49, 57, 32, 32, 12, 17, 80, 89, 71, 60, 81, 89, 85, 81, 85, - 77, 75, 68, 71, 75, 92, 93, 87, 83, 64, 60, 52, 59, 42, 8, 48, - 68, 65, 64, 61, 61, 56, 36, 30, 12, 8, 49, 104, 102, 110, 97, 100, - 89, 85, 77, 48, 22, 5, 57, 64, 75, 61, 76, 61, 69, 55, 65, 60, - 63, 51, 52, 85, 69, 83, 76, 83, 84, 63, 73, 100, 75, 25, 18, 60, - 83, 75, 72, 59, 57, 48, 57, 45, 21, 6, 51, 64, 67, 42, 48, 53, - 52, 48, 44, 41, 44, 13, 6, 55, 64, 72, 67, 67, 67, 59, 36, 22, - 12, 9, 108, 85, 96, 96, 95, 75, 130, 127, 56, 44, 36, 32, 38, 42, - 59, 65, 56, 59, 57, 51, 33, 18, 13, 10, 13, 13, 13, 2, 4, 9, - 20, 21, 13, 25, 10, 9, 0, 2, 38, 73, 55, 57, 77, 80, 87, 96, - 102, 96, 95, 97, 55, 8, 42, 59, 67, 60, 57, 52, 68, 63, 68, 49, - 29, 16, 107, 108, 83, 73, 87, 85, 102, 89, 73, 79, 83, 61, 81, 99, - 81, 97, 92, 97, 99, 96, 93, 57, 26, 87, 99, 104, 84, 80, 76, 76, - 71, 69, 64, 76, 71, 53, 108, 115, 106, 97, 103, 99, 97, 87, 100, 83, - 80, 60, 96, 99, 80, 75, 73, 79, 77, 81, 69, 77, 67, 49, 6, 84, - 97, 92, 104, 99, 96, 89, 92, 75, 57, 32, 59, 51, 72, 79, 77, 84, - 88, 80, 63, 33, 9, 2, 111, 104, 81, 84, 84, 81, 80, 75, 81, 77, - 33, 10, 95, 72, 77, 79, 83, 89, 88, 89, 71, 63, 17, 61, 49, 41, - 34, 21, 14, 34, 24, 13, 26, 34, 1, 2, 76, 96, 83, 79, 71, 77, - 89, 91, 83, 79, 52, 42, 87, 103, 99, 92, 85, 91, 87, 93, 93, 80, - 55, 20, 88, 93, 107, 99, 123, 104, 83, 91, 116, 173, 199, 197, 195, 194, - 138, 107, 106, 103, 97, 26, 24, 25, 28, 22, 36, 46, 36, 56, 88, 201, - 193, 175, 122, 124, 144, 135, 134, 134, 130, 130, 111, 100, 48, 13, 10, 6, - 21, 13, 48, 87, 69, 84, 75, 71, 65, 69, 61, 38, 22, 76, 88, 79, - 85, 88, 80, 72, 68, 65, 89, 73, 60, 83, 93, 95, 87, 75, 76, 60, - 67, 64, 76, 64, 61, 33, 52, 48, 28, 28, 30, 29, 41, 38, 45, 28, - 6, 6, 77, 123, 104, 108, 95, 93, 103, 103, 108, 112, 63, 29, 77, 100, - 103, 96, 107, 92, 99, 92, 81, 85, 57, 71, 88, 83, 80, 73, 68, 71, - 80, 80, 73, 75, 51, 5, 95, 57, 96, 88, 60, 64, 89, 75, 69, 69, - 72, 45, 64, 77, 88, 92, 81, 79, 80, 59, 57, 21, 8, 102, 115, 110, - 89, 93, 97, 104, 100, 107, 99, 104, 83, 61, 88, 89, 85, 80, 80, 81, - 69, 69, 64, 56, 25, 1, 59, 80, 71, 56, 59, 56, 72, 73, 67, 71, - 36, 18, 59, 64, 38, 57, 36, 44, 38, 36, 67, 37, 9, 21, 67, 65, - 61, 59, 57, 67, 64, 63, 36, 33, 21, 2, 51, 77, 64, 64, 48, 46, - 60, 45, 63, 48, 38, 29, 56, 72, 67, 59, 52, 61, 56, 48, 37, 32, - 12, 46, 92, 84, 83, 81, 84, 87, 84, 80, 71, 68, 64, 40, 72, 93, - 75, 61, 71, 64, 63, 67, 52, 69, 34, 9, 45, 51, 75, 38, 36, 37, - 22, 17, 22, 8, 5, 64, 104, 102, 84, 89, 91, 102, 95, 96, 68, 36, - 9, 49, 56, 33, 48, 63, 79, 44, 34, 56, 38, 37, 48, 57, 63, 85, - 99, 97, 95, 83, 81, 83, 93, 80, 46, 30, 64, 72, 55, 59, 59, 63, - 63, 64, 34, 22, 6, 55, 65, 65, 38, 38, 49, 37, 49, 51, 49, 41, - 12, 5, 57, 69, 63, 51, 57, 56, 52, 32, 18, 10, 6, 81, 97, 81, - 107, 115, 97, 97, 48, 65, 56, 51, 29, 33, 24, 24, 29, 20, 24, 20, - 21, 18, 16, 14, 10, 13, 5, 5, 13, 22, 21, 18, 17, 18, 26, 10, - 2, 0, 0, 44, 67, 48, 12, 112, 106, 102, 79, 80, 99, 91, 91, 55, - 6, 53, 64, 68, 81, 61, 57, 52, 60, 61, 34, 24, 14, 83, 111, 79, - 83, 69, 88, 76, 89, 73, 81, 85, 63, 77, 93, 75, 79, 87, 107, 100, - 87, 93, 65, 26, 83, 104, 79, 81, 75, 73, 73, 68, 65, 73, 71, 37, - 22, 111, 112, 100, 107, 95, 99, 95, 95, 107, 77, 81, 55, 91, 93, 77, - 79, 79, 73, 89, 89, 80, 72, 81, 45, 6, 80, 99, 93, 97, 92, 85, - 76, 106, 96, 59, 41, 37, 60, 61, 77, 69, 51, 63, 71, 57, 5, 9, - 2, 72, 103, 79, 84, 81, 88, 79, 87, 85, 84, 36, 1, 61, 85, 89, - 68, 67, 72, 73, 103, 84, 41, 20, 26, 46, 46, 33, 18, 24, 10, 17, - 16, 14, 22, 1, 4, 71, 92, 93, 72, 64, 69, 71, 69, 67, 51, 55, - 46, 102, 102, 91, 112, 83, 89, 87, 91, 93, 84, 60, 24, 93, 96, 92, - 69, 67, 85, 77, 103, 144, 202, 198, 198, 190, 140, 111, 100, 103, 114, 56, - 24, 24, 24, 25, 36, 38, 48, 46, 69, 92, 201, 202, 187, 122, 124, 128, - 143, 147, 148, 147, 143, 135, 116, 56, 12, 14, 5, 18, 10, 37, 83, 71, - 75, 73, 88, 87, 71, 67, 46, 24, 79, 81, 81, 72, 79, 85, 71, 68, - 71, 72, 69, 52, 79, 93, 69, 64, 81, 67, 71, 61, 61, 65, 68, 59, - 30, 49, 67, 64, 55, 34, 17, 46, 21, 22, 25, 6, 8, 91, 112, 95, - 99, 104, 106, 102, 99, 97, 93, 71, 36, 85, 102, 87, 84, 85, 83, 81, - 85, 77, 59, 52, 76, 91, 68, 76, 76, 75, 72, 73, 73, 76, 83, 32, - 5, 51, 87, 65, 79, 79, 76, 83, 87, 84, 76, 59, 41, 65, 77, 71, - 61, 52, 60, 61, 73, 65, 18, 6, 75, 115, 107, 114, 102, 100, 103, 108, - 106, 111, 93, 79, 60, 91, 95, 73, 81, 77, 79, 80, 81, 76, 52, 22, - 1, 57, 84, 69, 52, 53, 56, 61, 55, 60, 65, 38, 25, 44, 75, 42, - 44, 48, 42, 52, 41, 51, 29, 9, 21, 44, 68, 57, 49, 48, 59, 63, - 64, 36, 36, 22, 0, 49, 85, 52, 65, 46, 51, 56, 41, 63, 41, 33, - 21, 65, 73, 71, 61, 38, 45, 48, 60, 55, 45, 12, 63, 93, 77, 59, - 61, 64, 75, 64, 77, 68, 60, 42, 37, 72, 88, 69, 72, 68, 64, 55, - 53, 56, 64, 34, 10, 51, 57, 36, 38, 18, 25, 22, 24, 9, 6, 2, - 52, 102, 99, 83, 89, 88, 88, 84, 103, 75, 40, 6, 48, 49, 79, 64, - 73, 87, 34, 55, 57, 36, 44, 53, 42, 80, 97, 89, 88, 75, 84, 85, - 84, 81, 76, 55, 20, 72, 64, 61, 42, 46, 40, 46, 60, 44, 22, 9, - 49, 69, 72, 38, 37, 36, 41, 36, 33, 46, 26, 10, 4, 56, 60, 64, - 37, 42, 30, 30, 29, 21, 13, 9, 88, 93, 95, 79, 89, 68, 104, 64, - 67, 56, 53, 45, 36, 25, 24, 21, 21, 18, 17, 14, 16, 14, 13, 10, - 5, 6, 16, 21, 22, 30, 17, 14, 17, 30, 12, 21, 0, 0, 41, 67, - 37, 59, 77, 80, 80, 96, 80, 77, 89, 84, 60, 14, 52, 52, 64, 60, - 60, 63, 57, 69, 55, 40, 36, 13, 85, 103, 89, 71, 88, 77, 77, 72, - 75, 85, 75, 57, 87, 99, 93, 84, 93, 108, 95, 85, 102, 64, 32, 71, - 96, 75, 76, 71, 67, 84, 79, 77, 75, 68, 46, 20, 111, 112, 106, 99, - 92, 100, 83, 84, 88, 71, 73, 53, 91, 93, 79, 81, 79, 84, 69, 77, - 88, 71, 72, 48, 8, 83, 96, 85, 115, 100, 83, 89, 99, 88, 64, 42, - 55, 51, 56, 45, 32, 42, 45, 38, 49, 12, 6, 1, 71, 99, 76, 83, - 87, 85, 85, 89, 87, 80, 34, 1, 68, 81, 80, 76, 69, 67, 68, 83, - 77, 44, 18, 56, 65, 24, 29, 13, 32, 13, 12, 28, 24, 22, 0, 2, - 79, 93, 88, 69, 73, 76, 80, 75, 64, 55, 36, 42, 97, 106, 89, 97, - 77, 91, 103, 102, 91, 76, 56, 29, 79, 85, 93, 73, 68, 79, 67, 100, - 181, 198, 197, 194, 146, 115, 100, 107, 111, 65, 38, 21, 25, 25, 26, 36, - 41, 48, 48, 64, 89, 209, 206, 195, 120, 122, 128, 131, 139, 143, 146, 147, - 140, 120, 57, 10, 10, 5, 21, 9, 42, 84, 68, 73, 71, 87, 87, 68, - 79, 38, 24, 71, 79, 87, 96, 96, 100, 71, 63, 61, 71, 60, 49, 73, - 92, 75, 75, 61, 73, 75, 76, 60, 80, 65, 53, 36, 61, 57, 48, 28, - 21, 10, 16, 18, 25, 21, 4, 6, 91, 114, 111, 92, 114, 99, 97, 97, - 91, 96, 68, 42, 73, 97, 80, 77, 72, 95, 79, 67, 75, 63, 44, 79, - 93, 69, 68, 75, 67, 75, 69, 72, 76, 79, 33, 5, 55, 83, 92, 56, - 59, 81, 67, 68, 69, 71, 57, 38, 63, 93, 81, 48, 71, 87, 73, 56, - 56, 17, 0, 89, 110, 108, 106, 99, 100, 92, 93, 93, 102, 95, 75, 57, - 87, 85, 67, 69, 75, 79, 79, 81, 64, 61, 22, 1, 51, 75, 63, 60, - 52, 59, 45, 60, 60, 65, 42, 24, 48, 64, 34, 32, 46, 46, 45, 51, - 52, 29, 12, 18, 60, 67, 48, 75, 52, 68, 65, 41, 38, 37, 18, 1, - 73, 71, 57, 64, 44, 42, 52, 38, 73, 42, 33, 25, 56, 68, 80, 65, - 68, 56, 44, 42, 49, 32, 14, 53, 95, 88, 85, 67, 71, 52, 59, 59, - 65, 32, 30, 21, 67, 80, 59, 56, 53, 44, 52, 53, 65, 57, 37, 14, - 44, 61, 34, 29, 24, 38, 24, 25, 9, 6, 4, 56, 103, 100, 83, 99, - 89, 83, 81, 93, 67, 42, 6, 34, 41, 56, 67, 46, 51, 48, 57, 29, - 51, 49, 52, 8, 77, 95, 76, 88, 92, 84, 96, 100, 96, 81, 52, 22, - 63, 67, 51, 45, 44, 44, 59, 60, 65, 33, 8, 52, 55, 65, 38, 40, - 44, 41, 37, 53, 44, 40, 14, 2, 49, 76, 60, 41, 33, 42, 34, 28, - 24, 13, 8, 100, 104, 88, 91, 63, 65, 83, 64, 65, 52, 56, 55, 48, - 22, 33, 21, 24, 22, 21, 16, 14, 14, 17, 9, 2, 6, 17, 26, 29, - 26, 30, 22, 22, 21, 13, 5, 0, 6, 49, 61, 40, 30, 114, 114, 93, - 92, 96, 91, 89, 102, 63, 10, 34, 60, 65, 52, 75, 55, 59, 45, 57, - 36, 24, 12, 85, 108, 87, 89, 89, 77, 85, 84, 77, 84, 69, 56, 81, - 88, 85, 72, 93, 99, 93, 83, 100, 64, 34, 75, 96, 83, 83, 61, 69, - 83, 72, 69, 69, 68, 59, 41, 116, 120, 92, 104, 77, 92, 85, 88, 83, - 79, 77, 53, 92, 87, 80, 83, 87, 72, 81, 85, 85, 69, 73, 49, 8, - 79, 91, 97, 92, 102, 81, 85, 107, 81, 65, 36, 59, 69, 48, 55, 59, - 55, 53, 41, 32, 20, 5, 10, 77, 100, 91, 87, 89, 96, 97, 89, 92, - 79, 34, 0, 79, 83, 64, 77, 76, 67, 69, 72, 67, 53, 24, 51, 57, - 40, 24, 16, 29, 6, 13, 17, 16, 20, 0, 2, 83, 93, 88, 79, 79, - 72, 81, 88, 69, 55, 40, 53, 107, 99, 96, 84, 72, 92, 95, 84, 80, - 79, 56, 29, 81, 89, 96, 79, 91, 64, 61, 99, 190, 199, 193, 155, 116, - 97, 119, 57, 55, 37, 22, 24, 22, 26, 25, 32, 40, 42, 49, 75, 115, - 208, 205, 198, 118, 118, 126, 128, 131, 135, 143, 147, 140, 116, 48, 9, 8, - 5, 16, 13, 48, 83, 68, 72, 71, 88, 73, 80, 56, 44, 30, 71, 92, - 77, 93, 83, 81, 91, 80, 59, 68, 59, 46, 80, 92, 89, 55, 89, 65, - 71, 60, 79, 72, 65, 46, 40, 32, 53, 38, 24, 12, 12, 20, 20, 28, - 17, 1, 5, 95, 112, 92, 95, 103, 114, 103, 91, 103, 97, 72, 42, 64, - 102, 85, 79, 97, 84, 67, 75, 64, 53, 40, 79, 95, 69, 79, 88, 81, - 87, 92, 76, 72, 75, 38, 9, 60, 76, 84, 60, 73, 85, 77, 68, 76, - 68, 57, 36, 60, 76, 73, 65, 60, 59, 59, 59, 59, 18, 0, 88, 112, - 108, 108, 103, 107, 99, 93, 95, 99, 91, 52, 63, 89, 76, 67, 79, 89, - 88, 71, 63, 63, 56, 21, 17, 69, 76, 60, 56, 52, 68, 53, 64, 64, - 65, 44, 29, 52, 75, 34, 30, 51, 53, 55, 44, 44, 26, 10, 17, 57, - 64, 55, 65, 55, 64, 45, 41, 41, 40, 21, 8, 68, 67, 45, 56, 40, - 41, 55, 36, 56, 42, 32, 25, 51, 69, 67, 72, 72, 59, 34, 45, 46, - 32, 17, 41, 89, 81, 84, 63, 60, 63, 89, 65, 59, 33, 33, 34, 67, - 77, 61, 55, 52, 68, 71, 61, 68, 61, 42, 14, 44, 56, 37, 25, 12, - 18, 16, 33, 13, 6, 6, 65, 102, 96, 84, 99, 84, 84, 91, 95, 69, - 41, 6, 53, 44, 53, 57, 40, 51, 59, 38, 26, 37, 44, 25, 5, 79, - 93, 89, 96, 95, 85, 83, 84, 80, 81, 53, 26, 57, 69, 61, 40, 44, - 41, 49, 55, 56, 33, 6, 42, 63, 59, 38, 40, 33, 38, 33, 33, 42, - 34, 14, 4, 55, 63, 61, 40, 24, 33, 30, 18, 22, 12, 6, 102, 93, - 93, 64, 76, 81, 49, 65, 55, 59, 56, 52, 44, 26, 37, 25, 22, 16, - 18, 13, 22, 21, 17, 9, 4, 8, 17, 26, 21, 25, 29, 14, 20, 6, - 18, 5, 0, 1, 36, 63, 24, 18, 88, 100, 104, 97, 95, 88, 91, 88, - 59, 10, 46, 55, 61, 59, 52, 51, 55, 53, 56, 38, 25, 13, 77, 100, - 77, 77, 80, 80, 85, 81, 79, 67, 68, 45, 84, 89, 88, 65, 91, 83, - 83, 81, 87, 64, 36, 53, 89, 81, 87, 71, 75, 81, 81, 85, 80, 65, - 65, 38, 118, 106, 100, 108, 85, 102, 83, 88, 79, 83, 75, 56, 88, 87, - 80, 71, 76, 71, 87, 75, 81, 69, 63, 48, 8, 84, 81, 79, 92, 92, - 83, 84, 92, 81, 68, 37, 49, 44, 52, 41, 34, 34, 49, 48, 18, 10, - 8, 2, 76, 100, 77, 83, 99, 97, 83, 88, 93, 77, 36, 12, 83, 80, - 65, 79, 73, 64, 71, 69, 72, 64, 28, 56, 52, 61, 26, 18, 41, 12, - 12, 13, 28, 20, 0, 1, 83, 81, 92, 80, 75, 61, 77, 87, 71, 57, - 38, 63, 110, 96, 84, 80, 79, 97, 85, 77, 68, 71, 60, 30, 76, 91, - 89, 88, 65, 63, 72, 93, 183, 191, 166, 118, 99, 106, 56, 34, 24, 21, - 21, 22, 21, 25, 22, 33, 42, 44, 63, 81, 166, 210, 206, 199, 119, 119, - 126, 130, 130, 134, 143, 144, 138, 112, 26, 9, 9, 6, 16, 13, 44, 80, - 64, 73, 72, 83, 76, 77, 59, 40, 25, 72, 83, 85, 81, 73, 64, 64, - 65, 63, 65, 46, 42, 75, 89, 91, 65, 73, 61, 75, 73, 79, 68, 59, - 49, 30, 42, 52, 37, 37, 44, 46, 38, 28, 32, 16, 5, 4, 75, 112, - 91, 95, 87, 104, 114, 99, 93, 96, 69, 48, 64, 96, 79, 89, 87, 93, - 68, 71, 65, 52, 41, 83, 97, 79, 75, 91, 84, 85, 79, 76, 72, 67, - 51, 10, 69, 76, 84, 61, 72, 81, 72, 73, 71, 68, 53, 32, 53, 79, - 75, 81, 60, 65, 73, 63, 56, 20, 5, 89, 108, 118, 91, 85, 103, 100, - 99, 91, 93, 89, 46, 63, 95, 77, 71, 79, 97, 88, 77, 69, 55, 51, - 22, 2, 72, 75, 55, 53, 51, 64, 60, 64, 60, 64, 48, 22, 41, 71, - 41, 73, 37, 26, 38, 53, 40, 25, 9, 14, 63, 61, 45, 71, 51, 44, - 42, 38, 42, 38, 20, 5, 37, 56, 49, 38, 42, 40, 63, 36, 52, 40, - 30, 20, 55, 67, 77, 68, 76, 71, 57, 40, 44, 29, 16, 46, 85, 83, - 76, 49, 63, 53, 67, 57, 41, 37, 34, 32, 69, 71, 56, 61, 63, 51, - 45, 53, 48, 52, 38, 12, 38, 53, 41, 26, 21, 9, 9, 8, 14, 5, - 5, 67, 97, 96, 84, 88, 92, 85, 85, 100, 59, 41, 9, 48, 30, 51, - 40, 45, 36, 40, 41, 36, 38, 18, 37, 21, 77, 91, 89, 103, 77, 84, - 91, 87, 85, 77, 52, 28, 59, 61, 45, 30, 48, 59, 46, 56, 25, 28, - 8, 30, 38, 60, 32, 37, 41, 42, 32, 32, 38, 34, 12, 2, 53, 61, - 59, 34, 36, 29, 44, 21, 34, 10, 6, 59, 102, 79, 81, 79, 73, 59, - 65, 64, 63, 57, 61, 45, 28, 29, 25, 13, 28, 25, 24, 13, 16, 12, - 13, 4, 13, 20, 34, 37, 30, 25, 21, 8, 12, 12, 2, 0, 1, 49, - 38, 49, 20, 75, 106, 110, 89, 92, 95, 87, 81, 56, 5, 38, 61, 64, - 59, 56, 59, 68, 68, 48, 32, 24, 12, 72, 95, 79, 100, 80, 88, 80, - 72, 81, 73, 71, 41, 69, 103, 76, 63, 91, 87, 83, 83, 91, 65, 40, - 51, 89, 75, 89, 63, 76, 71, 75, 87, 75, 65, 41, 10, 115, 108, 95, - 89, 99, 88, 96, 92, 88, 76, 77, 52, 87, 84, 73, 77, 69, 71, 79, - 80, 75, 71, 67, 46, 8, 80, 93, 89, 95, 89, 73, 81, 87, 89, 69, - 53, 40, 51, 69, 60, 55, 61, 37, 33, 18, 1, 5, 1, 67, 96, 92, - 84, 87, 96, 85, 91, 83, 69, 37, 2, 60, 79, 61, 80, 73, 77, 59, - 68, 81, 52, 33, 16, 49, 49, 21, 20, 30, 13, 9, 17, 16, 16, 0, - 0, 79, 89, 89, 80, 80, 83, 81, 79, 68, 52, 41, 67, 108, 81, 91, - 92, 85, 85, 84, 97, 89, 67, 60, 32, 76, 87, 91, 88, 84, 75, 61, - 87, 170, 197, 162, 107, 89, 96, 44, 32, 24, 20, 25, 21, 20, 25, 22, - 45, 42, 41, 67, 93, 182, 217, 210, 204, 120, 119, 124, 130, 132, 138, 142, - 143, 130, 84, 13, 9, 8, 8, 16, 13, 51, 75, 65, 73, 75, 68, 80, - 71, 40, 46, 25, 65, 81, 76, 72, 71, 69, 81, 69, 64, 68, 57, 40, - 79, 80, 102, 72, 67, 68, 72, 73, 75, 59, 57, 30, 38, 28, 38, 33, - 32, 29, 29, 13, 18, 28, 18, 5, 4, 97, 114, 99, 88, 88, 88, 91, - 91, 89, 87, 81, 59, 67, 100, 79, 95, 83, 84, 61, 72, 53, 53, 38, - 77, 92, 73, 75, 81, 95, 76, 77, 75, 72, 64, 37, 9, 40, 56, 79, - 69, 83, 69, 68, 81, 68, 61, 48, 32, 48, 68, 69, 85, 80, 76, 59, - 63, 65, 18, 4, 76, 111, 110, 103, 99, 92, 97, 95, 95, 97, 72, 41, - 65, 88, 80, 63, 79, 99, 81, 72, 63, 57, 45, 24, 1, 57, 77, 53, - 46, 56, 55, 55, 60, 59, 61, 44, 36, 34, 63, 38, 36, 67, 26, 26, - 36, 32, 25, 8, 13, 56, 55, 48, 61, 61, 59, 48, 40, 48, 40, 22, - 5, 49, 67, 44, 37, 37, 32, 46, 46, 36, 38, 25, 14, 49, 63, 71, - 61, 69, 63, 60, 40, 42, 30, 17, 34, 73, 73, 103, 61, 68, 42, 37, - 44, 29, 28, 34, 28, 69, 69, 52, 45, 61, 49, 49, 44, 48, 44, 38, - 13, 37, 55, 42, 34, 26, 16, 26, 18, 8, 6, 2, 68, 96, 89, 92, - 95, 88, 75, 88, 103, 64, 42, 6, 49, 34, 63, 37, 25, 25, 57, 42, - 28, 25, 20, 45, 26, 81, 92, 92, 87, 87, 83, 83, 77, 83, 80, 73, - 29, 33, 64, 55, 46, 51, 49, 34, 30, 33, 25, 9, 20, 51, 56, 40, - 32, 29, 30, 34, 38, 36, 24, 9, 1, 41, 49, 53, 34, 44, 24, 30, - 22, 20, 10, 5, 89, 96, 76, 85, 80, 80, 65, 69, 69, 61, 57, 56, - 48, 28, 45, 30, 13, 13, 10, 9, 16, 10, 16, 8, 4, 17, 29, 28, - 13, 9, 10, 10, 8, 21, 13, 4, 0, 0, 22, 57, 21, 24, 80, 96, - 114, 107, 88, 83, 88, 81, 59, 8, 38, 56, 64, 69, 73, 65, 55, 52, - 45, 26, 17, 13, 71, 83, 97, 81, 100, 88, 81, 81, 80, 84, 65, 38, - 80, 89, 81, 80, 64, 71, 76, 71, 71, 69, 41, 53, 76, 73, 79, 80, - 76, 75, 75, 75, 75, 73, 46, 18, 106, 102, 77, 80, 88, 102, 100, 84, - 100, 75, 72, 46, 77, 85, 79, 72, 77, 73, 73, 76, 67, 69, 71, 46, - 9, 80, 83, 61, 75, 73, 59, 59, 75, 69, 72, 55, 34, 44, 30, 44, - 25, 28, 28, 34, 32, 1, 5, 8, 65, 92, 73, 80, 81, 80, 83, 93, - 87, 61, 36, 1, 59, 77, 64, 76, 77, 69, 68, 72, 69, 53, 22, 12, - 29, 21, 29, 21, 28, 24, 29, 22, 25, 16, 0, 0, 83, 92, 80, 83, - 85, 99, 89, 73, 59, 56, 29, 79, 108, 97, 102, 91, 93, 87, 72, 79, - 84, 77, 63, 34, 71, 85, 91, 87, 83, 61, 56, 69, 126, 198, 163, 114, - 97, 97, 49, 36, 22, 29, 29, 24, 24, 24, 24, 30, 42, 61, 83, 136, - 205, 216, 213, 198, 122, 119, 126, 131, 138, 143, 144, 139, 119, 41, 10, 8, - 5, 10, 21, 10, 42, 72, 71, 81, 76, 80, 77, 71, 53, 42, 24, 36, - 76, 79, 56, 61, 60, 52, 69, 67, 65, 52, 34, 68, 76, 79, 79, 73, - 73, 72, 71, 71, 64, 52, 32, 30, 45, 53, 57, 45, 42, 29, 45, 34, - 14, 13, 1, 2, 96, 110, 99, 68, 67, 67, 76, 63, 72, 73, 75, 60, - 55, 87, 83, 84, 83, 83, 59, 72, 51, 49, 32, 71, 85, 76, 75, 80, - 76, 76, 73, 76, 75, 72, 33, 9, 61, 73, 100, 79, 81, 79, 68, 65, - 63, 60, 49, 28, 38, 51, 60, 69, 76, 65, 72, 59, 64, 17, 10, 77, - 97, 102, 100, 92, 97, 99, 96, 95, 91, 73, 36, 61, 65, 91, 88, 95, - 88, 77, 65, 63, 51, 52, 21, 1, 67, 65, 55, 46, 53, 49, 48, 44, - 45, 45, 49, 37, 20, 44, 64, 49, 52, 18, 26, 38, 38, 26, 14, 10, - 57, 49, 44, 52, 46, 49, 46, 45, 45, 41, 20, 8, 48, 46, 42, 30, - 29, 26, 29, 33, 32, 36, 26, 14, 38, 57, 69, 68, 59, 49, 37, 42, - 44, 32, 18, 22, 46, 71, 68, 67, 34, 38, 36, 37, 34, 26, 25, 14, - 67, 69, 42, 56, 60, 56, 56, 41, 55, 46, 41, 21, 17, 52, 33, 36, - 14, 9, 16, 22, 20, 6, 14, 60, 91, 79, 93, 92, 91, 87, 88, 99, - 56, 41, 5, 48, 48, 52, 37, 24, 21, 18, 25, 36, 17, 33, 45, 4, - 68, 83, 81, 87, 79, 85, 76, 84, 79, 83, 64, 29, 33, 52, 53, 37, - 44, 33, 34, 36, 24, 29, 12, 16, 45, 25, 24, 17, 20, 25, 34, 37, - 25, 24, 14, 0, 44, 51, 61, 56, 38, 36, 37, 26, 21, 12, 4, 100, - 106, 72, 71, 73, 72, 73, 68, 68, 55, 59, 60, 48, 25, 22, 20, 10, - 9, 14, 16, 13, 10, 13, 9, 2, 17, 34, 9, 22, 40, 25, 26, 18, - 10, 9, 5, 0, 1, 45, 33, 30, 20, 81, 85, 88, 89, 99, 91, 91, - 73, 56, 6, 32, 48, 51, 49, 45, 48, 45, 46, 40, 29, 24, 12, 65, - 89, 97, 96, 87, 84, 85, 85, 84, 81, 57, 36, 77, 77, 81, 81, 83, - 72, 75, 72, 68, 68, 64, 60, 46, 48, 49, 46, 51, 49, 51, 55, 53, - 55, 56, 24, 116, 97, 92, 97, 88, 89, 89, 89, 88, 83, 76, 49, 89, - 87, 73, 73, 72, 64, 68, 61, 65, 64, 68, 46, 10, 77, 80, 73, 73, - 69, 84, 68, 65, 57, 71, 38, 33, 38, 28, 25, 24, 21, 21, 18, 17, - 13, 4, 1, 48, 91, 84, 84, 83, 91, 87, 91, 73, 73, 38, 1, 57, - 73, 63, 56, 77, 75, 71, 59, 61, 45, 40, 30, 18, 18, 12, 8, 5, - 5, 6, 5, 2, 4, 0, 1, 89, 89, 89, 83, 80, 77, 73, 73, 46, - 48, 29, 71, 103, 95, 84, 80, 80, 80, 72, 71, 71, 68, 63, 36, 46, - 76, 83, 77, 68, 44, 63, 59, 100, 182, 183, 143, 92, 119, 85, 44, 36, - 29, 33, 30, 30, 33, 38, 36, 65, 73, 116, 195, 216, 214, 216, 191, 120, - 120, 127, 135, 140, 146, 140, 128, 65, 12, 10, 8, 6, 9, 14, 16, 41, - 63, 67, 65, 64, 63, 59, 53, 56, 53, 30, 37, 72, 80, 55, 59, 64, - 60, 63, 61, 53, 48, 32, 46, 71, 75, 59, 56, 68, 71, 59, 59, 59, - 45, 29, 30, 29, 10, 14, 12, 25, 9, 12, 8, 4, 10, 0, 2, 84, - 97, 103, 96, 88, 87, 91, 88, 83, 81, 76, 75, 75, 52, 57, 63, 61, - 60, 72, 69, 64, 49, 29, 68, 84, 79, 81, 75, 76, 75, 77, 73, 72, - 68, 42, 13, 56, 59, 60, 60, 60, 60, 64, 57, 60, 49, 46, 25, 38, - 44, 57, 57, 52, 51, 51, 51, 44, 18, 0, 13, 48, 60, 49, 49, 57, - 67, 59, 56, 65, 57, 29, 26, 32, 34, 37, 41, 45, 41, 46, 44, 52, - 46, 18, 8, 64, 63, 64, 67, 59, 67, 56, 53, 49, 45, 41, 41, 20, - 18, 29, 37, 28, 20, 38, 37, 32, 25, 12, 9, 52, 45, 64, 49, 48, - 51, 49, 48, 46, 44, 24, 0, 38, 49, 25, 25, 28, 32, 30, 44, 33, - 38, 22, 14, 22, 45, 48, 37, 34, 38, 41, 32, 32, 37, 29, 18, 28, - 46, 45, 32, 32, 49, 36, 29, 32, 26, 25, 22, 60, 64, 63, 60, 55, - 60, 56, 49, 48, 53, 45, 17, 12, 38, 42, 42, 33, 12, 25, 25, 16, - 6, 6, 65, 93, 85, 88, 91, 92, 96, 88, 96, 69, 41, 5, 38, 45, - 36, 18, 25, 17, 17, 21, 17, 21, 25, 28, 12, 56, 68, 71, 49, 53, - 64, 64, 67, 59, 55, 46, 41, 42, 38, 33, 33, 32, 42, 30, 30, 25, - 25, 24, 10, 13, 16, 13, 17, 17, 20, 13, 37, 26, 17, 13, 0, 37, - 44, 42, 45, 41, 55, 24, 17, 20, 12, 2, 92, 92, 76, 65, 68, 60, - 59, 59, 60, 59, 55, 52, 44, 28, 30, 14, 22, 17, 13, 14, 10, 12, - 8, 8, 2, 20, 37, 44, 21, 16, 12, 8, 9, 8, 6, 4, 0, 0, - 32, 36, 25, 24, 72, 69, 69, 68, 69, 67, 69, 59, 41, 6, 29, 40, - 34, 25, 38, 40, 32, 29, 36, 32, 22, 10, 46, 89, 88, 85, 83, 63, - 56, 53, 64, 60, 51, 33, 53, 59, 59, 57, 56, 57, 60, 56, 56, 55, - 55, 51, 52, 37, 26, 21, 22, 32, 16, 12, 13, 10, 10, 21, 114, 77, - 92, 48, 88, 85, 83, 53, 84, 79, 72, 46, 81, 84, 65, 61, 57, 56, - 49, 53, 53, 53, 41, 21, 13, 44, 38, 41, 38, 37, 40, 37, 38, 36, - 33, 30, 26, 22, 21, 22, 20, 14, 13, 14, 12, 10, 12, 0, 18, 68, - 73, 51, 56, 77, 71, 64, 67, 65, 36, 16, 48, 64, 65, 61, 53, 51, - 49, 46, 42, 44, 18, 10, 6, 5, 9, 18, 22, 16, 8, 10, 10, 8, - 1, 0, 80, 51, 61, 59, 60, 64, 65, 71, 49, 42, 26, 63, 79, 85, - 83, 76, 79, 73, 69, 67, 71, 76, 67, 63, 64, 61, 41, 45, 59, 57, - 51, 56, 65, 162, 193, 157, 111, 111, 107, 72, 44, 30, 42, 41, 38, 36, - 40, 63, 73, 114, 183, 216, 216, 217, 213, 161, 119, 122, 128, 140, 143, 142, - 132, 92, 21, 10, 9, 8, 10, 10, 14, 17, 25, 52, 52, 48, 38, 51, - 49, 38, 41, 46, 36, 34, 67, 53, 51, 41, 40, 38, 37, 38, 40, 48, - 26, 16, 16, 22, 18, 17, 18, 24, 32, 44, 49, 34, 28, 8, 8, 5, - 5, 4, 4, 2, 0, 2, 4, 0, 5, 1, 10, 52, 63, 53, 53, 56, - 67, 60, 59, 61, 61, 61, 53, 63, 60, 63, 60, 67, 63, 65, 55, 48, - 34, 55, 75, 75, 77, 67, 64, 61, 60, 53, 56, 53, 38, 14, 24, 26, - 25, 26, 28, 30, 32, 36, 34, 36, 36, 24, 24, 13, 17, 17, 13, 9, - 9, 12, 12, 10, 2, 2, 5, 13, 5, 4, 12, 17, 8, 9, 16, 18, - 18, 16, 5, 13, 13, 12, 18, 26, 21, 26, 32, 32, 21, 0, 14, 24, - 28, 26, 26, 29, 30, 24, 25, 25, 22, 24, 20, 24, 33, 24, 22, 22, - 14, 22, 20, 24, 13, 16, 45, 40, 49, 46, 45, 44, 44, 40, 40, 38, - 18, 12, 34, 12, 16, 9, 9, 12, 14, 6, 5, 9, 13, 13, 9, 10, - 13, 12, 12, 14, 14, 17, 20, 28, 30, 30, 29, 32, 29, 26, 26, 28, - 26, 25, 24, 28, 28, 22, 57, 53, 51, 51, 41, 40, 38, 34, 33, 32, - 18, 21, 21, 18, 22, 16, 14, 9, 9, 9, 10, 5, 5, 61, 67, 83, - 85, 79, 76, 75, 81, 72, 53, 38, 8, 48, 33, 24, 21, 22, 20, 20, - 22, 22, 21, 22, 36, 17, 13, 14, 14, 13, 18, 21, 24, 24, 26, 34, - 38, 32, 29, 25, 26, 25, 25, 24, 25, 22, 22, 20, 18, 17, 20, 18, - 18, 16, 17, 16, 16, 12, 16, 16, 12, 0, 21, 29, 41, 17, 20, 25, - 36, 25, 16, 10, 2, 59, 92, 75, 63, 61, 61, 60, 55, 40, 38, 34, - 29, 29, 29, 16, 9, 20, 17, 13, 16, 13, 16, 10, 10, 2, 9, 18, - 16, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, - 45, 42, 38, 32, 30, 29, 25, 22, 0, 4, 8, 8, 6, 8, 14, 12, - 13, 18, 30, 17, 9, 64, 34, 33, 32, 32, 44, 33, 25, 22, 40, 36, - 20, 17, 13, 16, 13, 13, 12, 16, 13, 12, 10, 13, 12, 13, 29, 42, - 52, 52, 57, 91, 76, 95, 76, 55, 8, 122, 83, 96, 75, 63, 56, 57, - 57, 71, 73, 71, 44, 45, 46, 46, 40, 36, 33, 28, 25, 21, 22, 16, - 13, 12, 10, 9, 8, 6, 6, 5, 5, 4, 4, 4, 2, 1, 5, 6, - 1, 0, 1, 4, 0, 0, 1, 2, 0, 17, 13, 13, 17, 16, 34, 61, - 37, 46, 55, 33, 1, 44, 14, 20, 16, 17, 12, 17, 12, 16, 9, 8, - 9, 10, 24, 49, 44, 57, 61, 67, 59, 68, 64, 38, 0, 92, 79, 77, - 68, 61, 59, 59, 45, 55, 44, 25, 48, 49, 52, 49, 49, 51, 52, 52, - 53, 49, 55, 52, 51, 51, 33, 25, 26, 28, 37, 64, 63, 65, 108, 181, - 171, 114, 81, 151, 100, 77, 76, 80, 81, 81, 80, 79, 102, 150, 197, 216, - 216, 214, 214, 199, 132, 119, 127, 139, 142, 139, 132, 103, 29, 12, 10, 8, - 10, 14, 16, 8, 17, 24, 21, 25, 28, 28, 28, 29, 30, 34, 42, 42, - 36, 38, 30, 33, 40, 33, 37, 45, 61, 52, 46, 32, 37, 79, 81, 71, - 63, 46, 45, 41, 37, 13, 9, 6, 4, 0, 13, 2, 1, 2, 9, 0, - 2, 4, 0, 0, 5, 8, 2, 2, 2, 6, 5, 5, 6, 8, 9, 10, - 12, 13, 16, 18, 25, 25, 29, 30, 36, 37, 45, 33, 37, 51, 51, 32, - 33, 36, 37, 22, 22, 26, 21, 12, 2, 8, 2, 13, 14, 8, 6, 12, - 12, 6, 8, 10, 13, 45, 57, 69, 68, 60, 72, 64, 68, 36, 32, 1, - 14, 102, 108, 72, 67, 84, 92, 60, 64, 61, 21, 10, 40, 89, 85, 48, - 45, 48, 26, 25, 20, 25, 13, 10, 4, 1, 0, 8, 1, 0, 0, 6, - 4, 0, 2, 9, 8, 10, 6, 12, 9, 8, 20, 14, 10, 13, 21, 5, - 8, 37, 8, 12, 8, 9, 9, 9, 6, 6, 4, 4, 9, 6, 22, 34, - 40, 40, 42, 52, 59, 48, 46, 24, 10, 51, 76, 85, 64, 65, 42, 29, - 24, 16, 16, 13, 12, 14, 12, 17, 10, 12, 14, 12, 14, 16, 17, 17, - 13, 25, 21, 30, 24, 24, 18, 22, 21, 20, 18, 18, 16, 13, 6, 2, - 1, 1, 2, 2, 2, 2, 6, 4, 12, 18, 25, 21, 36, 37, 33, 24, - 40, 44, 25, 6, 34, 18, 25, 21, 18, 20, 22, 29, 33, 34, 33, 45, - 1, 32, 103, 103, 65, 65, 57, 56, 48, 34, 17, 13, 10, 8, 8, 8, - 6, 6, 6, 5, 5, 4, 6, 6, 4, 1, 0, 0, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 4, 2, 6, 4, 5, 5, 6, 6, 17, 10, 1, - 55, 87, 61, 53, 51, 46, 45, 45, 41, 40, 48, 37, 41, 13, 17, 25, - 16, 13, 6, 4, 2, 2, 2, 1, 1, 2, 1, 1, 1, 4, 4, 1, - 1, 2, 1, 0, 0, 0, 1, 0, 0, 0, 52, 63, 64, 56, 68, 57, - 68, 67, 52, 0, 32, 83, 80, 55, 60, 65, 53, 36, 25, 20, 12, 12, - 22, 53, 56, 48, 59, 65, 88, 76, 68, 64, 52, 14, 65, 87, 89, 80, - 69, 83, 73, 84, 80, 77, 36, 9, 68, 119, 115, 110, 108, 103, 102, 102, - 111, 88, 51, 10, 122, 84, 88, 123, 115, 99, 81, 84, 61, 45, 25, 38, - 44, 51, 53, 59, 59, 57, 65, 69, 68, 46, 64, 61, 112, 115, 115, 116, - 122, 118, 111, 115, 123, 110, 93, 89, 110, 106, 100, 108, 107, 102, 91, 83, - 102, 81, 20, 1, 65, 106, 104, 81, 67, 49, 40, 36, 20, 14, 10, 1, - 10, 44, 51, 56, 48, 57, 61, 64, 61, 65, 41, 1, 52, 111, 123, 126, - 122, 120, 104, 114, 103, 76, 37, 0, 88, 77, 92, 89, 96, 88, 87, 75, - 63, 44, 25, 9, 9, 9, 9, 10, 10, 10, 13, 12, 12, 12, 16, 17, - 18, 59, 61, 79, 79, 76, 103, 97, 76, 69, 120, 179, 128, 88, 114, 126, - 123, 135, 131, 118, 124, 138, 148, 191, 210, 214, 218, 216, 213, 212, 150, 122, - 126, 135, 138, 134, 126, 89, 28, 13, 13, 10, 16, 14, 12, 17, 25, 32, - 38, 73, 88, 80, 63, 61, 48, 45, 45, 36, 32, 29, 53, 84, 99, 91, - 104, 75, 76, 88, 67, 49, 29, 55, 99, 80, 65, 64, 80, 72, 73, 46, - 42, 36, 0, 16, 118, 110, 85, 73, 87, 85, 81, 76, 84, 65, 33, 0, - 30, 76, 88, 87, 88, 88, 91, 83, 81, 76, 69, 63, 75, 76, 77, 79, - 73, 51, 37, 30, 24, 24, 25, 17, 22, 42, 38, 49, 42, 51, 48, 55, - 56, 45, 33, 4, 18, 61, 67, 77, 69, 64, 65, 57, 65, 67, 60, 60, - 59, 80, 89, 93, 88, 87, 79, 65, 61, 34, 4, 91, 88, 67, 84, 72, - 80, 68, 81, 75, 61, 25, 6, 83, 100, 96, 93, 93, 88, 79, 57, 64, - 65, 26, 18, 4, 14, 100, 93, 60, 45, 91, 85, 61, 49, 61, 55, 24, - 2, 36, 89, 84, 48, 46, 41, 34, 25, 17, 9, 4, 6, 33, 34, 37, - 28, 41, 45, 36, 40, 40, 29, 0, 30, 92, 87, 83, 85, 88, 77, 79, - 75, 59, 24, 9, 59, 85, 63, 60, 80, 80, 79, 79, 56, 29, 22, 5, - 37, 122, 115, 75, 68, 67, 60, 51, 24, 10, 12, 5, 5, 6, 6, 4, - 5, 4, 4, 1, 4, 2, 2, 2, 5, 12, 55, 64, 65, 63, 49, 72, - 57, 16, 5, 40, 79, 72, 67, 29, 24, 16, 12, 10, 6, 9, 2, 14, - 34, 76, 75, 75, 77, 75, 79, 69, 72, 53, 45, 4, 85, 119, 111, 95, - 112, 99, 100, 99, 99, 89, 89, 68, 63, 81, 61, 45, 57, 69, 60, 57, - 46, 34, 2, 0, 14, 68, 95, 64, 59, 63, 79, 64, 60, 52, 4, 0, - 48, 64, 60, 38, 64, 53, 53, 12, 6, 10, 1, 64, 68, 72, 69, 76, - 73, 72, 72, 73, 75, 68, 38, 24, 18, 21, 45, 40, 34, 38, 37, 25, - 18, 9, 12, 4, 2, 14, 37, 40, 52, 38, 44, 45, 60, 60, 67, 56, - 72, 76, 83, 81, 83, 120, 103, 110, 104, 99, 100, 64, 68, 53, 0, 67, - 77, 95, 91, 84, 87, 83, 81, 80, 75, 33, 12, 73, 112, 114, 108, 106, - 97, 110, 107, 96, 67, 57, 16, 91, 92, 85, 76, 73, 92, 81, 77, 75, - 77, 41, 8, 96, 118, 93, 99, 108, 119, 99, 102, 83, 92, 57, 14, 130, - 106, 81, 79, 59, 80, 93, 111, 119, 104, 85, 99, 116, 106, 108, 116, 106, - 107, 112, 103, 108, 92, 102, 88, 76, 110, 97, 85, 93, 96, 83, 76, 72, - 76, 91, 64, 76, 93, 110, 114, 99, 99, 88, 83, 92, 91, 45, 0, 84, - 102, 127, 89, 95, 71, 80, 77, 71, 55, 33, 8, 69, 112, 108, 108, 100, - 99, 64, 84, 87, 71, 46, 1, 102, 124, 106, 91, 77, 100, 89, 81, 84, - 73, 36, 0, 104, 75, 81, 87, 83, 80, 83, 84, 71, 56, 25, 30, 100, - 81, 76, 80, 93, 93, 77, 75, 72, 68, 67, 63, 69, 65, 104, 108, 106, - 89, 89, 91, 85, 56, 73, 169, 146, 97, 79, 158, 169, 177, 190, 199, 205, - 206, 210, 213, 214, 213, 209, 212, 205, 155, 124, 130, 134, 130, 126, 99, 56, - 26, 16, 13, 10, 18, 13, 18, 25, 40, 25, 26, 64, 103, 114, 100, 103, - 106, 112, 111, 112, 92, 83, 84, 87, 102, 99, 83, 72, 83, 72, 71, 71, - 52, 32, 51, 97, 93, 81, 67, 63, 59, 73, 80, 52, 40, 0, 118, 120, - 95, 97, 92, 93, 89, 67, 64, 59, 55, 65, 0, 110, 104, 92, 93, 81, - 92, 77, 80, 80, 81, 77, 55, 49, 77, 80, 72, 72, 60, 59, 64, 72, - 40, 22, 41, 91, 89, 96, 85, 87, 87, 81, 85, 83, 64, 36, 2, 99, - 93, 102, 96, 85, 80, 73, 65, 71, 67, 48, 59, 95, 114, 108, 93, 93, - 79, 83, 85, 59, 36, 2, 104, 84, 83, 73, 65, 64, 63, 63, 69, 75, - 26, 9, 96, 108, 85, 51, 68, 55, 83, 76, 60, 38, 33, 20, 0, 104, - 115, 96, 48, 65, 84, 75, 61, 59, 59, 56, 29, 2, 87, 96, 75, 72, - 77, 68, 83, 45, 30, 21, 2, 36, 87, 96, 102, 88, 83, 75, 72, 76, - 71, 41, 14, 80, 97, 92, 83, 71, 73, 71, 72, 69, 75, 28, 8, 67, - 93, 63, 65, 52, 52, 55, 67, 71, 60, 25, 4, 106, 126, 104, 102, 108, - 104, 100, 73, 85, 83, 81, 81, 92, 99, 89, 87, 91, 80, 97, 87, 88, - 87, 71, 69, 75, 61, 63, 60, 68, 56, 75, 63, 60, 20, 5, 52, 104, - 72, 64, 71, 48, 57, 51, 36, 28, 14, 24, 63, 85, 89, 97, 88, 88, - 80, 84, 71, 65, 55, 33, 12, 100, 110, 115, 103, 103, 93, 76, 71, 80, - 68, 65, 76, 77, 67, 40, 41, 57, 61, 28, 34, 24, 59, 2, 0, 71, - 96, 63, 60, 55, 49, 57, 49, 55, 61, 9, 0, 56, 56, 45, 55, 69, - 52, 53, 52, 16, 10, 0, 91, 72, 67, 67, 65, 61, 38, 53, 64, 52, - 49, 30, 21, 16, 30, 37, 21, 24, 17, 20, 17, 25, 21, 2, 0, 34, - 64, 75, 75, 79, 71, 63, 53, 67, 52, 61, 56, 57, 46, 65, 84, 72, - 143, 128, 106, 114, 122, 108, 119, 67, 55, 0, 71, 85, 92, 89, 73, 76, - 53, 67, 65, 73, 38, 13, 97, 118, 107, 100, 97, 100, 104, 111, 106, 72, - 57, 18, 91, 102, 111, 122, 104, 112, 102, 99, 83, 79, 46, 8, 88, 116, - 95, 96, 79, 83, 88, 81, 68, 68, 52, 13, 130, 102, 99, 69, 77, 77, - 81, 84, 65, 84, 95, 91, 65, 64, 77, 77, 79, 60, 55, 80, 61, 64, - 95, 64, 111, 97, 104, 100, 88, 95, 92, 95, 91, 79, 81, 57, 103, 124, - 110, 92, 103, 97, 96, 102, 96, 91, 49, 1, 89, 104, 131, 88, 75, 93, - 67, 84, 68, 60, 37, 21, 88, 107, 96, 102, 102, 91, 85, 91, 88, 83, - 46, 0, 99, 124, 71, 80, 85, 85, 77, 103, 79, 85, 41, 0, 97, 71, - 79, 75, 73, 75, 73, 76, 76, 53, 25, 92, 93, 89, 77, 65, 83, 89, - 80, 72, 84, 72, 84, 65, 46, 103, 114, 97, 76, 68, 73, 89, 93, 53, - 55, 124, 154, 104, 73, 112, 118, 136, 154, 179, 191, 199, 204, 202, 204, 208, - 193, 170, 147, 119, 132, 128, 112, 92, 56, 28, 16, 17, 14, 13, 16, 13, - 17, 22, 34, 26, 29, 29, 64, 104, 112, 112, 110, 106, 100, 102, 104, 85, - 83, 64, 103, 95, 69, 72, 84, 87, 84, 73, 52, 67, 30, 52, 85, 80, - 69, 72, 69, 64, 71, 71, 52, 38, 0, 122, 118, 114, 87, 79, 77, 73, - 57, 57, 57, 73, 67, 0, 107, 87, 80, 84, 96, 88, 87, 97, 83, 81, - 63, 36, 69, 116, 87, 72, 67, 65, 63, 75, 71, 40, 30, 85, 89, 83, - 75, 64, 77, 88, 69, 71, 64, 53, 40, 9, 97, 76, 73, 76, 96, 84, - 69, 63, 67, 51, 42, 84, 118, 91, 77, 91, 81, 60, 48, 71, 42, 34, - 0, 68, 81, 71, 56, 45, 53, 68, 67, 87, 64, 28, 6, 85, 107, 64, - 57, 41, 46, 49, 60, 37, 30, 32, 18, 2, 88, 91, 84, 65, 69, 57, - 53, 64, 56, 80, 61, 30, 4, 91, 95, 61, 53, 55, 51, 53, 63, 34, - 29, 4, 75, 95, 91, 87, 79, 87, 84, 77, 52, 49, 29, 8, 80, 95, - 84, 68, 69, 59, 63, 63, 63, 56, 25, 8, 65, 88, 72, 69, 67, 52, - 51, 46, 57, 65, 24, 5, 93, 115, 112, 111, 97, 91, 81, 95, 80, 76, - 65, 72, 89, 89, 103, 69, 84, 88, 80, 80, 65, 83, 69, 46, 42, 83, - 91, 67, 61, 40, 34, 65, 48, 25, 5, 42, 102, 77, 65, 63, 53, 65, - 51, 52, 32, 16, 30, 65, 95, 84, 73, 69, 69, 71, 69, 76, 83, 37, - 40, 10, 89, 106, 112, 106, 100, 69, 71, 99, 96, 92, 81, 61, 34, 73, - 73, 44, 41, 30, 26, 9, 32, 41, 1, 4, 85, 85, 59, 61, 51, 68, - 69, 61, 55, 52, 10, 0, 38, 45, 41, 29, 22, 22, 18, 36, 32, 10, - 0, 102, 81, 59, 67, 46, 42, 33, 42, 45, 48, 42, 29, 16, 22, 40, - 33, 21, 8, 4, 4, 5, 12, 20, 0, 4, 53, 93, 95, 61, 67, 60, - 61, 68, 53, 33, 40, 44, 51, 89, 107, 131, 136, 84, 89, 115, 108, 79, - 95, 116, 68, 53, 0, 64, 99, 89, 67, 65, 75, 72, 64, 52, 65, 38, - 16, 80, 120, 103, 108, 99, 95, 93, 95, 111, 73, 60, 25, 59, 104, 104, - 89, 97, 111, 107, 79, 77, 77, 45, 6, 104, 110, 112, 88, 97, 97, 88, - 99, 75, 87, 57, 5, 124, 107, 97, 68, 65, 71, 87, 80, 81, 77, 61, - 67, 60, 97, 71, 69, 87, 80, 83, 80, 79, 61, 56, 37, 111, 100, 103, - 95, 83, 85, 76, 73, 92, 84, 75, 59, 119, 122, 93, 87, 83, 91, 96, - 88, 85, 104, 45, 0, 93, 110, 114, 71, 76, 91, 84, 100, 99, 81, 40, - 6, 106, 106, 110, 92, 104, 97, 88, 89, 85, 69, 46, 0, 93, 118, 69, - 81, 77, 93, 96, 97, 83, 67, 40, 0, 99, 80, 80, 87, 84, 73, 75, - 73, 79, 59, 25, 92, 89, 79, 84, 89, 85, 77, 79, 79, 71, 71, 57, - 38, 61, 110, 104, 96, 69, 72, 76, 64, 89, 56, 48, 108, 153, 104, 67, - 81, 99, 111, 118, 124, 150, 161, 170, 169, 163, 159, 139, 126, 126, 119, 100, - 77, 45, 29, 17, 14, 14, 13, 17, 13, 13, 24, 22, 29, 32, 32, 28, - 25, 67, 116, 119, 112, 88, 97, 88, 80, 72, 71, 52, 88, 107, 69, 75, - 97, 77, 69, 65, 73, 55, 69, 37, 42, 87, 83, 75, 87, 71, 83, 69, - 67, 60, 37, 0, 76, 111, 92, 97, 111, 88, 81, 76, 60, 59, 63, 36, - 4, 76, 75, 87, 96, 84, 85, 83, 77, 76, 55, 51, 34, 73, 108, 71, - 67, 84, 97, 92, 73, 60, 38, 21, 83, 88, 76, 64, 60, 56, 77, 76, - 63, 53, 49, 40, 2, 91, 65, 76, 57, 83, 97, 85, 64, 67, 41, 26, - 80, 119, 89, 85, 89, 79, 55, 65, 55, 46, 37, 0, 87, 91, 91, 42, - 57, 63, 59, 77, 72, 79, 29, 5, 88, 104, 59, 52, 41, 53, 53, 42, - 45, 29, 25, 20, 1, 77, 95, 53, 69, 75, 61, 56, 55, 51, 63, 53, - 41, 4, 79, 89, 59, 44, 61, 63, 59, 59, 56, 29, 0, 81, 100, 77, - 73, 73, 59, 53, 46, 40, 45, 28, 1, 76, 96, 76, 56, 69, 55, 53, - 57, 55, 63, 26, 5, 64, 88, 84, 65, 79, 79, 75, 53, 52, 49, 25, - 5, 81, 108, 111, 106, 110, 100, 107, 107, 104, 95, 64, 91, 106, 83, 63, - 57, 59, 64, 59, 46, 51, 55, 34, 30, 55, 96, 89, 33, 53, 55, 87, - 46, 49, 24, 6, 52, 95, 73, 48, 68, 71, 56, 64, 52, 38, 17, 26, - 64, 95, 80, 68, 68, 80, 80, 65, 64, 76, 38, 41, 1, 88, 102, 99, - 103, 108, 68, 75, 83, 93, 88, 79, 56, 60, 84, 63, 24, 44, 18, 29, - 28, 33, 34, 1, 0, 68, 72, 63, 60, 49, 56, 64, 61, 59, 44, 10, - 0, 65, 57, 26, 37, 34, 28, 17, 33, 44, 12, 0, 96, 64, 61, 65, - 42, 67, 36, 33, 57, 49, 36, 33, 16, 12, 40, 29, 8, 12, 16, 10, - 8, 9, 16, 0, 10, 73, 96, 61, 53, 60, 37, 51, 84, 57, 41, 51, - 38, 51, 93, 131, 77, 30, 111, 112, 120, 83, 92, 97, 110, 64, 53, 1, - 64, 95, 91, 56, 61, 64, 77, 51, 51, 71, 40, 17, 72, 110, 104, 100, - 110, 114, 93, 91, 97, 76, 61, 22, 100, 112, 103, 89, 93, 106, 106, 80, - 79, 80, 45, 6, 93, 110, 87, 96, 99, 91, 96, 85, 77, 75, 55, 5, - 122, 97, 95, 68, 71, 68, 92, 84, 84, 73, 53, 73, 92, 89, 95, 91, - 68, 71, 80, 68, 72, 76, 77, 32, 110, 110, 100, 83, 85, 77, 93, 73, - 84, 81, 77, 61, 118, 119, 77, 79, 84, 85, 72, 84, 85, 83, 48, 1, - 93, 107, 123, 83, 93, 76, 67, 68, 92, 59, 40, 0, 93, 97, 116, 96, - 106, 92, 91, 87, 69, 79, 48, 0, 106, 118, 79, 91, 89, 88, 79, 95, - 89, 77, 40, 0, 89, 89, 81, 81, 80, 75, 73, 73, 75, 56, 28, 57, - 76, 93, 81, 71, 85, 76, 75, 80, 75, 67, 56, 36, 87, 111, 102, 91, - 81, 65, 72, 77, 95, 63, 46, 99, 154, 115, 84, 60, 64, 64, 69, 89, - 110, 114, 118, 122, 118, 116, 112, 87, 65, 44, 29, 21, 18, 18, 14, 10, - 16, 17, 12, 25, 26, 28, 29, 36, 37, 32, 32, 25, 60, 112, 96, 83, - 71, 81, 87, 84, 69, 55, 51, 93, 97, 71, 87, 77, 77, 60, 56, 79, - 65, 72, 38, 34, 81, 80, 71, 71, 75, 68, 61, 63, 46, 38, 0, 80, - 108, 106, 119, 95, 51, 49, 64, 52, 72, 72, 37, 2, 79, 89, 87, 91, - 72, 76, 77, 76, 56, 67, 53, 32, 75, 115, 83, 63, 65, 57, 60, 79, - 64, 38, 21, 71, 87, 73, 79, 71, 56, 71, 65, 52, 53, 42, 37, 1, - 73, 80, 76, 56, 76, 92, 85, 60, 51, 42, 30, 83, 123, 71, 77, 65, - 76, 56, 56, 46, 52, 34, 2, 92, 88, 79, 45, 52, 67, 72, 64, 75, - 65, 30, 4, 103, 106, 56, 42, 41, 38, 49, 48, 36, 38, 26, 18, 0, - 83, 111, 75, 73, 67, 59, 44, 77, 55, 57, 59, 28, 1, 77, 93, 51, - 45, 52, 49, 48, 53, 33, 28, 0, 84, 93, 57, 75, 55, 46, 52, 41, - 44, 37, 28, 9, 85, 95, 68, 65, 49, 55, 53, 51, 41, 60, 26, 5, - 63, 83, 77, 56, 45, 53, 45, 48, 53, 49, 26, 2, 97, 120, 110, 115, - 88, 91, 92, 100, 92, 91, 42, 89, 91, 84, 65, 57, 46, 55, 52, 52, - 53, 34, 46, 28, 91, 104, 102, 29, 67, 65, 73, 42, 44, 41, 10, 53, - 99, 76, 67, 69, 72, 53, 49, 65, 52, 17, 9, 51, 93, 64, 56, 51, - 59, 65, 59, 55, 83, 49, 41, 2, 99, 103, 96, 103, 95, 76, 73, 67, - 103, 83, 79, 51, 64, 92, 51, 21, 33, 10, 18, 26, 28, 30, 1, 0, - 57, 83, 53, 51, 46, 46, 49, 48, 40, 49, 10, 0, 42, 44, 42, 37, - 51, 41, 17, 24, 36, 12, 0, 106, 61, 59, 65, 37, 72, 36, 33, 32, - 38, 30, 30, 14, 18, 34, 24, 2, 9, 2, 4, 1, 5, 20, 0, 32, - 85, 87, 45, 48, 60, 48, 41, 68, 32, 28, 42, 33, 71, 108, 107, 24, - 32, 116, 119, 80, 87, 95, 83, 103, 79, 52, 0, 69, 100, 91, 59, 57, - 64, 71, 52, 51, 65, 42, 18, 68, 115, 108, 104, 92, 103, 104, 92, 93, - 89, 64, 25, 99, 104, 103, 96, 81, 84, 92, 77, 79, 75, 45, 5, 95, - 114, 91, 92, 92, 89, 102, 91, 77, 80, 59, 6, 124, 111, 91, 71, 68, - 69, 69, 76, 85, 79, 51, 97, 102, 89, 88, 71, 69, 91, 99, 68, 88, - 83, 84, 46, 119, 95, 84, 79, 84, 73, 93, 72, 89, 79, 65, 65, 122, - 110, 79, 87, 71, 83, 88, 103, 81, 81, 51, 0, 89, 110, 123, 83, 81, - 79, 71, 69, 103, 57, 42, 5, 100, 112, 99, 87, 99, 81, 81, 87, 71, - 81, 49, 1, 102, 122, 79, 76, 87, 85, 88, 95, 88, 72, 41, 0, 92, - 83, 83, 89, 76, 75, 76, 71, 67, 56, 30, 60, 81, 85, 83, 80, 85, - 75, 67, 71, 65, 71, 60, 29, 89, 110, 104, 75, 84, 64, 75, 87, 77, - 69, 42, 89, 150, 123, 93, 77, 60, 52, 46, 48, 42, 41, 41, 41, 45, - 38, 33, 30, 22, 22, 20, 18, 16, 14, 14, 16, 10, 18, 29, 34, 44, - 44, 41, 38, 32, 33, 33, 25, 63, 116, 85, 88, 88, 83, 72, 95, 83, - 69, 37, 87, 100, 69, 91, 67, 55, 55, 53, 73, 67, 73, 41, 24, 83, - 87, 92, 87, 88, 81, 73, 63, 51, 40, 0, 76, 102, 85, 104, 51, 48, - 59, 64, 51, 60, 61, 59, 0, 106, 96, 68, 100, 72, 64, 61, 64, 55, - 80, 57, 30, 81, 103, 76, 75, 59, 61, 53, 75, 65, 40, 24, 68, 83, - 99, 112, 65, 53, 49, 52, 53, 56, 49, 37, 0, 114, 72, 65, 59, 72, - 71, 85, 59, 52, 46, 29, 81, 122, 89, 83, 60, 72, 51, 51, 44, 56, - 40, 0, 96, 88, 91, 48, 51, 52, 77, 80, 77, 75, 30, 5, 95, 110, - 59, 42, 33, 37, 34, 49, 28, 37, 28, 21, 1, 115, 115, 73, 88, 38, - 59, 79, 42, 48, 63, 53, 30, 0, 84, 87, 55, 41, 49, 102, 55, 65, - 32, 26, 0, 83, 96, 60, 69, 42, 60, 45, 40, 40, 52, 28, 16, 79, - 91, 56, 69, 52, 51, 49, 51, 45, 61, 26, 4, 57, 85, 65, 44, 44, - 53, 77, 49, 49, 59, 28, 2, 91, 126, 107, 102, 85, 89, 88, 88, 93, - 85, 41, 91, 103, 69, 96, 72, 53, 48, 51, 46, 38, 37, 44, 28, 89, - 95, 87, 37, 75, 83, 42, 44, 25, 22, 9, 55, 100, 60, 61, 64, 38, - 32, 28, 52, 59, 17, 12, 67, 92, 79, 53, 52, 49, 53, 48, 65, 75, - 51, 37, 5, 97, 115, 97, 97, 69, 68, 71, 65, 97, 77, 79, 45, 64, - 91, 57, 13, 32, 9, 20, 22, 28, 28, 0, 0, 71, 75, 59, 48, 44, - 60, 59, 49, 34, 51, 10, 0, 61, 46, 32, 29, 18, 53, 26, 26, 26, - 12, 0, 91, 75, 69, 36, 21, 75, 33, 30, 26, 48, 20, 30, 14, 14, - 26, 21, 13, 34, 20, 21, 6, 6, 13, 0, 41, 89, 79, 41, 46, 48, - 41, 55, 75, 32, 29, 33, 33, 63, 108, 46, 38, 33, 118, 107, 77, 89, - 95, 80, 104, 67, 55, 0, 60, 93, 84, 59, 65, 57, 77, 49, 63, 72, - 46, 21, 45, 102, 114, 100, 104, 100, 89, 85, 93, 96, 60, 29, 73, 110, - 87, 97, 102, 87, 96, 81, 77, 87, 49, 6, 95, 111, 81, 83, 107, 89, - 87, 75, 68, 71, 59, 5, 123, 110, 106, 72, 72, 68, 72, 72, 84, 76, - 49, 103, 99, 91, 73, 68, 77, 114, 68, 69, 68, 81, 96, 42, 108, 89, - 88, 85, 83, 76, 100, 72, 83, 76, 45, 71, 123, 123, 79, 112, 79, 77, - 89, 107, 79, 79, 57, 0, 88, 103, 112, 81, 89, 76, 71, 65, 99, 61, - 44, 13, 96, 112, 92, 92, 83, 79, 104, 87, 77, 72, 51, 0, 99, 123, - 68, 89, 85, 80, 83, 102, 79, 71, 41, 0, 88, 83, 85, 80, 68, 72, - 73, 71, 77, 52, 30, 57, 93, 64, 77, 81, 89, 77, 85, 84, 53, 76, - 51, 26, 100, 116, 102, 85, 83, 61, 65, 85, 73, 71, 44, 84, 143, 127, - 104, 92, 81, 75, 53, 44, 41, 37, 34, 34, 29, 29, 28, 25, 22, 20, - 18, 18, 18, 18, 17, 6, 17, 29, 46, 51, 41, 42, 42, 42, 42, 36, - 36, 30, 59, 127, 88, 76, 92, 85, 85, 80, 76, 75, 30, 88, 88, 71, - 68, 69, 55, 76, 64, 60, 65, 77, 41, 20, 69, 84, 93, 71, 64, 60, - 68, 60, 51, 40, 0, 92, 99, 89, 97, 48, 49, 73, 51, 51, 71, 72, - 60, 0, 100, 87, 75, 99, 64, 61, 69, 53, 51, 76, 55, 26, 73, 122, - 72, 63, 65, 63, 57, 76, 64, 40, 25, 61, 95, 96, 68, 56, 67, 49, - 71, 68, 59, 51, 40, 6, 104, 59, 77, 51, 72, 49, 100, 55, 53, 45, - 30, 79, 120, 77, 88, 67, 65, 68, 45, 44, 41, 36, 0, 89, 87, 87, - 45, 61, 45, 56, 59, 81, 57, 30, 4, 97, 111, 65, 55, 36, 33, 32, - 63, 29, 33, 30, 20, 0, 106, 124, 67, 80, 38, 61, 53, 64, 53, 52, - 49, 30, 2, 73, 102, 53, 49, 84, 79, 60, 55, 33, 29, 5, 88, 97, - 51, 57, 45, 45, 40, 53, 38, 52, 29, 6, 76, 95, 67, 72, 67, 73, - 71, 73, 45, 67, 28, 2, 68, 77, 59, 51, 89, 44, 42, 46, 48, 65, - 26, 4, 124, 122, 110, 91, 91, 104, 88, 91, 91, 91, 45, 95, 87, 92, - 68, 89, 61, 44, 49, 34, 37, 36, 49, 25, 95, 107, 83, 29, 71, 63, - 41, 40, 41, 26, 10, 59, 106, 45, 51, 36, 28, 28, 25, 26, 51, 17, - 28, 64, 92, 91, 52, 48, 48, 61, 48, 51, 69, 55, 37, 4, 92, 115, - 93, 91, 77, 68, 67, 71, 84, 77, 73, 41, 76, 96, 46, 16, 13, 5, - 18, 21, 21, 46, 0, 2, 73, 80, 53, 53, 56, 51, 36, 57, 44, 48, - 12, 0, 67, 56, 29, 33, 29, 20, 28, 28, 21, 12, 1, 77, 83, 46, - 53, 34, 75, 30, 28, 28, 38, 21, 26, 9, 16, 21, 22, 24, 16, 20, - 21, 5, 6, 6, 0, 41, 97, 65, 42, 51, 53, 46, 57, 96, 36, 34, - 34, 30, 76, 107, 41, 63, 63, 122, 81, 76, 88, 88, 77, 116, 64, 56, - 0, 61, 84, 91, 60, 79, 59, 68, 48, 53, 61, 52, 29, 52, 96, 114, - 112, 108, 88, 112, 96, 91, 100, 61, 30, 46, 108, 107, 89, 88, 89, 77, - 89, 81, 76, 51, 5, 104, 116, 83, 83, 80, 88, 92, 72, 68, 73, 59, - 2, 123, 110, 100, 71, 68, 65, 91, 75, 73, 73, 45, 108, 84, 75, 69, - 76, 107, 73, 69, 75, 81, 69, 80, 24, 112, 95, 80, 81, 72, 76, 103, - 68, 84, 72, 51, 85, 124, 110, 83, 108, 83, 72, 81, 111, 76, 75, 56, - 0, 88, 92, 122, 80, 77, 67, 72, 68, 114, 75, 53, 5, 99, 114, 85, - 85, 77, 77, 103, 80, 77, 67, 55, 0, 85, 123, 81, 76, 79, 79, 76, - 102, 72, 71, 41, 0, 96, 69, 80, 71, 68, 65, 72, 68, 71, 55, 32, - 26, 57, 104, 77, 71, 57, 71, 59, 59, 57, 79, 53, 22, 111, 112, 108, - 72, 92, 65, 63, 85, 67, 69, 46, 75, 130, 123, 127, 95, 91, 79, 71, - 57, 53, 44, 40, 34, 30, 30, 28, 30, 26, 29, 26, 26, 24, 20, 30, - 6, 28, 51, 49, 45, 57, 51, 59, 64, 61, 37, 34, 24, 55, 131, 88, - 99, 63, 91, 102, 65, 75, 72, 33, 80, 89, 72, 75, 59, 55, 87, 67, - 64, 64, 83, 44, 21, 75, 81, 84, 69, 60, 61, 67, 61, 48, 38, 0, - 93, 95, 85, 114, 48, 49, 61, 49, 49, 56, 57, 38, 1, 67, 81, 64, - 110, 67, 64, 67, 53, 53, 83, 59, 24, 67, 120, 65, 63, 68, 57, 67, - 60, 56, 41, 24, 73, 92, 102, 53, 52, 51, 64, 60, 51, 49, 46, 40, - 0, 100, 61, 69, 52, 77, 51, 84, 55, 53, 40, 16, 71, 120, 83, 92, - 67, 63, 53, 49, 49, 44, 36, 0, 91, 75, 106, 42, 48, 45, 45, 57, - 85, 60, 32, 2, 99, 118, 69, 73, 29, 42, 29, 73, 30, 29, 28, 20, - 0, 91, 99, 51, 93, 38, 59, 45, 68, 49, 53, 48, 30, 2, 87, 108, - 55, 38, 80, 52, 53, 57, 42, 30, 0, 79, 87, 57, 42, 42, 40, 38, - 72, 40, 68, 32, 1, 61, 91, 83, 51, 64, 59, 51, 44, 44, 73, 29, - 1, 63, 77, 56, 79, 95, 68, 41, 45, 46, 60, 28, 2, 108, 114, 108, - 85, 92, 107, 87, 87, 87, 89, 44, 100, 102, 75, 75, 81, 53, 38, 60, - 36, 36, 40, 37, 21, 97, 96, 37, 87, 38, 42, 51, 38, 41, 29, 13, - 32, 97, 46, 40, 28, 25, 26, 24, 25, 52, 20, 10, 56, 84, 99, 48, - 41, 46, 71, 48, 51, 83, 41, 41, 1, 93, 116, 95, 67, 69, 67, 67, - 97, 83, 72, 71, 34, 76, 88, 67, 13, 13, 10, 12, 22, 20, 26, 0, - 0, 48, 69, 38, 33, 30, 46, 37, 60, 36, 73, 12, 0, 53, 53, 25, - 17, 24, 30, 25, 17, 30, 13, 2, 25, 96, 41, 36, 30, 59, 26, 24, - 24, 48, 17, 18, 5, 20, 14, 2, 6, 5, 18, 6, 4, 13, 1, 0, - 45, 91, 55, 32, 51, 38, 45, 45, 81, 42, 37, 33, 25, 71, 111, 45, - 61, 5, 122, 79, 81, 87, 89, 73, 116, 65, 51, 0, 55, 77, 97, 56, - 87, 56, 64, 49, 56, 46, 59, 29, 33, 88, 118, 115, 119, 87, 108, 122, - 80, 107, 57, 33, 26, 119, 112, 76, 76, 81, 93, 92, 76, 75, 52, 4, - 108, 120, 84, 77, 80, 80, 73, 75, 68, 73, 60, 2, 123, 111, 111, 71, - 68, 68, 73, 76, 73, 68, 37, 112, 77, 72, 65, 110, 88, 68, 71, 75, - 84, 72, 67, 21, 99, 97, 77, 72, 72, 76, 112, 67, 79, 71, 46, 96, - 128, 115, 80, 110, 71, 77, 81, 114, 76, 76, 60, 0, 80, 88, 122, 68, - 81, 68, 77, 67, 134, 61, 51, 0, 110, 115, 81, 83, 75, 75, 111, 77, - 73, 68, 52, 0, 79, 122, 76, 76, 73, 71, 76, 112, 76, 75, 42, 0, - 84, 76, 75, 67, 64, 73, 67, 68, 64, 51, 34, 32, 56, 107, 106, 59, - 71, 61, 53, 56, 53, 96, 52, 21, 108, 118, 120, 75, 100, 97, 60, 77, - 69, 60, 45, 69, 115, 126, 118, 114, 93, 85, 76, 71, 63, 55, 41, 42, - 41, 37, 36, 36, 22, 24, 24, 22, 20, 20, 36, 5, 28, 55, 37, 63, - 44, 45, 63, 85, 81, 52, 36, 32, 48, 136, 79, 108, 64, 102, 77, 68, - 72, 60, 29, 80, 84, 68, 72, 60, 55, 99, 61, 65, 60, 97, 46, 24, - 79, 75, 59, 60, 61, 61, 61, 63, 48, 38, 0, 96, 80, 80, 130, 48, - 48, 56, 49, 51, 55, 64, 42, 0, 69, 85, 67, 110, 64, 64, 63, 53, - 49, 92, 52, 20, 69, 134, 60, 65, 61, 53, 55, 56, 56, 41, 25, 65, - 97, 60, 52, 51, 52, 49, 52, 55, 51, 41, 38, 1, 115, 63, 61, 51, - 92, 49, 100, 51, 46, 37, 17, 65, 119, 67, 102, 57, 57, 53, 44, 38, - 48, 37, 0, 104, 73, 93, 42, 51, 81, 84, 56, 96, 59, 33, 1, 115, - 127, 77, 75, 25, 32, 30, 81, 37, 26, 28, 20, 0, 89, 111, 63, 95, - 38, 52, 44, 77, 48, 53, 48, 32, 0, 91, 99, 51, 42, 88, 44, 57, - 55, 34, 30, 0, 89, 106, 53, 42, 41, 38, 38, 81, 40, 40, 29, 0, - 55, 96, 97, 46, 44, 42, 41, 38, 38, 85, 29, 1, 57, 65, 55, 83, - 110, 45, 40, 40, 45, 77, 29, 1, 112, 126, 120, 84, 85, 115, 85, 84, - 85, 87, 26, 104, 99, 93, 57, 92, 51, 38, 44, 33, 36, 33, 37, 17, - 102, 97, 36, 97, 37, 40, 38, 37, 37, 29, 14, 22, 97, 42, 30, 29, - 68, 26, 24, 26, 40, 20, 10, 51, 56, 107, 44, 44, 45, 56, 48, 48, - 68, 45, 38, 1, 84, 119, 87, 71, 67, 67, 64, 99, 80, 75, 72, 28, - 81, 89, 71, 16, 5, 12, 17, 10, 17, 22, 0, 0, 40, 68, 21, 17, - 17, 24, 33, 72, 34, 45, 13, 0, 45, 44, 29, 17, 25, 24, 22, 26, - 30, 13, 8, 5, 97, 45, 33, 29, 48, 28, 22, 22, 26, 18, 16, 8, - 6, 14, 1, 30, 1, 0, 2, 5, 4, 1, 0, 38, 83, 40, 37, 53, - 41, 33, 53, 91, 28, 26, 38, 21, 92, 106, 9, 8, 0, 162, 165, 161, - 159, 159, 170, 173, 154, 132, 0, 162, 179, 179, 175, 181, 155, 165, 177, 178, - 148, 84, 124, 179, 181, 165, 181, 163, 165, 165, 174, 159, 153, 140, 0, 170, - 185, 182, 151, 186, 155, 153, 155, 169, 161, 72, 100, 169, 169, 170, 174, 175, - 173, 161, 158, 170, 163, 169, 46, 161, 157, 150, 150, 165, 171, 154, 140, 139, - 122, 130, 65, 148, 170, 148, 150, 147, 131, 161, 131, 155, 142, 126, 68, 102, - 170, 138, 146, 146, 169, 165, 146, 163, 124, 130, 8, 163, 166, 143, 171, 185, - 151, 134, 165, 144, 153, 77, 73, 153, 158, 158, 120, 115, 123, 138, 124, 142, - 123, 115, 30, 155, 163, 170, 166, 153, 157, 153, 138, 135, 115, 100, 0, 150, - 157, 153, 159, 140, 138, 128, 153, 173, 139, 136, 37, 148, 171, 158, 135, 134, - 150, 130, 131, 120, 119, 79, 102, 174, 159, 135, 157, 148, 130, 132, 130, 147, - 171, 114, 1, 153, 139, 154, 153, 138, 123, 131, 146, 148, 142, 33, 151, 154, - 127, 132, 128, 126, 153, 132, 114, 128, 147, 34, 144, 147, 134, 150, 148, 142, - 135, 130, 128, 110, 110, 99, 4, 104, 151, 127, 135, 112, 132, 102, 135, 111, - 106, 96, 34, 142, 147, 123, 148, 132, 116, 112, 104, 100, 104, 85, 13, 135, - 136, 144, 143, 112, 115, 123, 107, 135, 84, 17, 169, 153, 153, 132, 171, 151, - 148, 123, 135, 130, 130, 115, 65, 91, 147, 138, 120, 112, 118, 138, 115, 132, - 97, 56, 73, 163, 177, 162, 182, 144, 139, 140, 163, 132, 128, 38, 106, 135, - 138, 131, 107, 104, 107, 139, 104, 104, 108, 49, 91, 136, 157, 130, 162, 106, - 103, 95, 103, 92, 104, 99, 28, 124, 104, 108, 103, 126, 106, 97, 100, 122, - 83, 99, 26, 150, 130, 124, 126, 127, 108, 110, 132, 93, 92, 83, 8, 91, - 139, 120, 140, 87, 89, 87, 107, 88, 88, 36, 114, 124, 123, 122, 119, 95, - 99, 126, 126, 92, 84, 69, 4, 122, 102, 123, 123, 88, 99, 80, 85, 83, - 110, 81, 4, 146, 123, 154, 107, 95, 115, 84, 80, 80, 77, 38, 76, 116, - 84, 127, 114, 72, 111, 114, 64, 75, 69, 8, 119, 161, 136, 114, 104, 107, - 161, 131, 102, 103, 89, 85, 2, 91, 97, 97, 57, 52, 51, 57, 53, 55, - 56, 49, 16, 104, 106, 73, 119, 92, 103, 63, 68, 63, 63, 61, 8, 110, - 127, 111, 114, 130, 65, 106, 111, 73, 68, 61, 40, 0, 123, 131, 118, 110, - 110, 91, 87, 84, 76, 81, 4, 124, 103, 128, 87, 53, 93, 61, 99, 57, - 52, 13, 92, 122, 76, 88, 56, 87, 45, 84, 111, 76, 53, 41, 25, 56, - 103, 96, 103, 102, 68, 46, 48, 53, 56, 44, 12, 89, 89, 52, 84, 56, - 91, 48, 45, 42, 37, 1, 123, 116, 107, 42, 44, 93, 83, 87, 111, 49, - 38, 33, 2, 91, 38, 38, 36, 36, 104, 84, 55, 32, 32, 26, 2, 51, - 84, 60, 84, 100, 22, 30, 36, 24, 29, 20, 0, 77, 83, 33, 26, 21, - 22, 34, 76, 25, 22, 13, 8, 40, 97, 68, 42, 29, 97, 30, 30, 33, - 24, 59, 18, 12, 97, 38, 114, 30, 181, 178, 181, 158, 159, 167, 173, 155, - 127, 1, 163, 183, 177, 170, 183, 161, 162, 175, 178, 134, 75, 128, 173, 179, - 177, 161, 162, 158, 162, 174, 162, 153, 140, 0, 167, 181, 178, 155, 179, 157, - 150, 162, 162, 154, 88, 103, 159, 167, 170, 159, 162, 153, 155, 163, 158, 157, - 162, 67, 155, 159, 150, 151, 153, 169, 167, 158, 136, 122, 126, 83, 150, 173, - 151, 148, 158, 144, 167, 143, 157, 139, 111, 64, 106, 170, 140, 144, 144, 166, - 162, 147, 159, 120, 122, 5, 157, 159, 155, 169, 181, 155, 135, 163, 147, 144, - 64, 73, 142, 150, 122, 115, 118, 124, 127, 131, 127, 122, 110, 46, 150, 159, - 158, 178, 163, 150, 151, 153, 135, 116, 104, 0, 146, 154, 165, 155, 140, 139, - 136, 147, 162, 148, 134, 42, 143, 167, 157, 136, 135, 147, 150, 126, 112, 119, - 75, 103, 166, 148, 134, 140, 142, 142, 130, 130, 140, 162, 102, 0, 151, 143, - 144, 151, 139, 128, 134, 140, 147, 140, 40, 155, 148, 135, 135, 118, 144, 146, - 119, 126, 115, 135, 52, 136, 147, 143, 144, 132, 132, 134, 128, 136, 110, 112, - 88, 2, 111, 139, 119, 108, 119, 120, 108, 124, 110, 108, 99, 48, 135, 150, - 126, 143, 139, 123, 127, 127, 115, 103, 97, 12, 131, 132, 132, 116, 114, 128, - 112, 115, 127, 91, 22, 158, 151, 151, 140, 150, 151, 144, 128, 142, 131, 135, - 115, 60, 93, 148, 136, 108, 119, 134, 130, 114, 128, 103, 55, 77, 159, 169, - 157, 167, 142, 136, 140, 158, 132, 126, 46, 111, 134, 136, 123, 106, 110, 108, - 132, 106, 102, 100, 48, 89, 136, 148, 130, 147, 114, 107, 100, 100, 93, 103, - 99, 40, 107, 110, 111, 127, 124, 111, 97, 99, 111, 89, 96, 26, 146, 134, - 114, 116, 100, 100, 112, 128, 87, 93, 84, 6, 99, 128, 114, 138, 83, 91, - 91, 99, 85, 84, 34, 108, 120, 122, 118, 102, 119, 119, 120, 104, 91, 85, - 68, 4, 122, 104, 120, 114, 89, 95, 92, 75, 92, 99, 76, 4, 138, 136, - 128, 103, 84, 115, 84, 84, 77, 76, 36, 80, 111, 112, 120, 89, 71, 108, - 111, 65, 75, 68, 9, 112, 150, 132, 128, 96, 97, 134, 127, 99, 108, 95, - 89, 14, 89, 92, 91, 55, 51, 51, 46, 53, 52, 51, 48, 20, 103, 106, - 79, 106, 89, 102, 64, 67, 71, 61, 51, 9, 106, 107, 107, 114, 102, 69, - 99, 104, 81, 68, 56, 40, 0, 130, 135, 110, 104, 89, 88, 87, 79, 75, - 75, 0, 114, 116, 126, 76, 53, 87, 64, 97, 63, 49, 17, 89, 123, 84, - 81, 56, 79, 46, 51, 49, 49, 53, 41, 22, 56, 110, 80, 95, 99, 63, - 49, 51, 77, 60, 49, 14, 88, 79, 57, 64, 68, 87, 49, 45, 42, 30, - 1, 111, 102, 91, 59, 45, 96, 88, 71, 65, 57, 38, 30, 2, 88, 55, - 46, 37, 34, 44, 93, 83, 33, 40, 25, 1, 61, 83, 68, 93, 63, 38, - 29, 37, 24, 22, 18, 0, 81, 80, 30, 30, 24, 22, 24, 76, 29, 42, - 13, 8, 36, 87, 63, 48, 28, 80, 34, 28, 29, 21, 52, 16, 12, 104, - 51, 104, 41, 169, 174, 169, 161, 159, 162, 173, 155, 147, 17, 162, 179, 173, - 173, 178, 162, 162, 169, 175, 140, 69, 131, 175, 175, 179, 166, 155, 151, 158, - 169, 159, 155, 138, 0, 165, 174, 157, 173, 165, 154, 153, 155, 166, 153, 84, - 110, 170, 163, 153, 155, 163, 166, 166, 161, 158, 154, 166, 71, 150, 158, 153, - 150, 148, 158, 159, 162, 146, 123, 120, 80, 153, 175, 150, 148, 143, 146, 148, - 157, 151, 140, 136, 60, 118, 162, 144, 144, 154, 165, 153, 157, 155, 118, 123, - 6, 153, 163, 147, 150, 148, 139, 136, 162, 147, 139, 57, 76, 139, 151, 126, - 106, 119, 110, 115, 120, 116, 116, 111, 48, 144, 159, 158, 158, 169, 159, 140, - 147, 135, 122, 102, 1, 146, 162, 161, 150, 144, 136, 139, 136, 131, 142, 134, - 52, 135, 166, 153, 136, 132, 138, 151, 116, 124, 122, 72, 107, 165, 157, 153, - 142, 142, 142, 139, 131, 136, 148, 123, 4, 144, 144, 148, 144, 144, 132, 135, - 136, 143, 135, 48, 148, 150, 127, 123, 143, 127, 110, 128, 127, 107, 130, 56, - 132, 146, 138, 135, 139, 136, 131, 131, 123, 108, 108, 112, 18, 99, 134, 114, - 119, 116, 116, 114, 116, 108, 107, 99, 53, 131, 147, 126, 140, 130, 128, 119, - 122, 116, 111, 95, 10, 127, 131, 123, 115, 127, 107, 114, 106, 123, 79, 32, - 150, 150, 150, 144, 136, 126, 128, 139, 131, 135, 130, 115, 56, 97, 144, 134, - 114, 118, 146, 132, 118, 119, 107, 55, 110, 159, 158, 154, 159, 150, 140, 144, - 157, 131, 128, 56, 107, 134, 135, 122, 106, 112, 108, 130, 104, 97, 95, 44, - 93, 132, 143, 131, 143, 123, 104, 102, 96, 92, 102, 99, 44, 116, 114, 107, - 135, 108, 107, 99, 97, 110, 91, 99, 40, 135, 128, 111, 118, 136, 138, 136, - 124, 88, 95, 73, 13, 99, 120, 110, 108, 81, 85, 95, 81, 84, 84, 46, - 102, 120, 122, 118, 104, 100, 92, 103, 92, 88, 85, 67, 14, 127, 110, 131, - 87, 76, 84, 88, 75, 84, 88, 76, 5, 134, 120, 136, 123, 103, 120, 87, - 84, 83, 64, 42, 92, 100, 120, 104, 71, 77, 108, 112, 68, 71, 68, 10, - 107, 150, 134, 122, 112, 100, 107, 99, 100, 106, 95, 84, 8, 88, 99, 71, - 49, 48, 46, 46, 48, 56, 49, 38, 20, 97, 107, 88, 95, 77, 95, 64, - 64, 67, 64, 61, 1, 103, 106, 110, 123, 79, 69, 88, 107, 76, 71, 59, - 40, 0, 112, 136, 108, 102, 88, 92, 88, 93, 72, 76, 0, 107, 103, 77, - 56, 81, 77, 80, 92, 57, 51, 20, 83, 115, 77, 102, 55, 49, 48, 48, - 48, 49, 53, 36, 20, 55, 100, 87, 91, 92, 65, 51, 52, 55, 60, 45, - 20, 80, 73, 75, 75, 69, 80, 48, 44, 44, 37, 2, 107, 85, 77, 51, - 44, 91, 88, 65, 60, 52, 48, 33, 0, 96, 38, 41, 44, 36, 34, 33, - 85, 61, 38, 25, 1, 60, 72, 77, 110, 37, 28, 51, 51, 22, 22, 18, - 0, 72, 79, 51, 40, 26, 21, 55, 41, 26, 26, 12, 6, 34, 36, 64, - 51, 25, 22, 25, 28, 25, 25, 44, 13, 16, 96, 63, 93, 83, 166, 171, - 169, 155, 158, 162, 169, 150, 142, 0, 162, 183, 169, 169, 178, 173, 159, 167, - 169, 138, 60, 132, 174, 165, 153, 154, 170, 166, 166, 167, 166, 153, 136, 17, - 163, 171, 154, 163, 159, 155, 150, 158, 158, 135, 81, 115, 166, 162, 174, 162, - 171, 166, 162, 157, 155, 159, 158, 79, 147, 165, 154, 148, 150, 144, 151, 158, - 130, 131, 111, 85, 159, 182, 135, 138, 143, 153, 139, 142, 136, 135, 134, 55, - 115, 165, 143, 146, 158, 154, 154, 153, 138, 122, 118, 8, 155, 162, 159, 158, - 155, 136, 153, 150, 154, 120, 53, 75, 131, 111, 114, 100, 103, 106, 107, 112, - 111, 112, 103, 53, 139, 158, 153, 154, 165, 167, 146, 134, 139, 119, 88, 1, - 143, 155, 159, 147, 147, 154, 144, 144, 140, 142, 135, 60, 131, 153, 151, 138, - 132, 136, 146, 134, 120, 92, 64, 108, 161, 153, 155, 159, 147, 158, 147, 138, - 132, 143, 118, 1, 142, 147, 135, 139, 143, 134, 124, 136, 127, 131, 55, 144, - 148, 127, 130, 130, 128, 111, 111, 127, 102, 122, 63, 128, 142, 140, 142, 138, - 132, 131, 132, 134, 110, 111, 110, 5, 103, 119, 108, 104, 114, 112, 108, 120, - 100, 107, 100, 61, 126, 146, 128, 140, 144, 110, 123, 122, 116, 107, 85, 20, - 116, 128, 139, 122, 100, 127, 115, 118, 120, 75, 29, 136, 153, 148, 142, 127, - 134, 136, 131, 128, 135, 132, 116, 48, 103, 143, 128, 108, 122, 127, 122, 112, - 116, 106, 55, 87, 155, 165, 148, 139, 139, 144, 154, 151, 134, 127, 63, 106, - 131, 140, 108, 112, 108, 104, 136, 106, 85, 88, 41, 93, 134, 130, 124, 130, - 135, 104, 108, 97, 95, 103, 97, 48, 110, 112, 114, 118, 110, 110, 104, 99, - 104, 91, 99, 44, 132, 130, 111, 119, 115, 119, 106, 103, 103, 102, 69, 20, - 96, 111, 118, 106, 81, 89, 92, 77, 84, 88, 49, 102, 118, 119, 115, 122, - 97, 95, 96, 103, 80, 84, 68, 6, 114, 100, 100, 114, 69, 102, 102, 76, - 73, 92, 79, 6, 122, 124, 135, 108, 99, 132, 93, 88, 81, 73, 45, 92, - 84, 114, 99, 72, 75, 100, 100, 65, 72, 65, 9, 111, 143, 127, 99, 107, - 103, 99, 95, 102, 110, 95, 83, 10, 68, 95, 55, 44, 48, 40, 51, 48, - 53, 41, 37, 18, 92, 87, 79, 83, 75, 88, 71, 73, 69, 63, 61, 0, - 100, 103, 102, 120, 69, 76, 85, 96, 87, 65, 59, 38, 0, 119, 136, 100, - 96, 88, 92, 88, 93, 71, 72, 0, 100, 106, 73, 51, 76, 51, 67, 59, - 73, 51, 24, 80, 93, 97, 77, 65, 46, 46, 48, 48, 48, 59, 42, 17, - 63, 96, 91, 81, 83, 76, 51, 52, 61, 60, 49, 21, 85, 72, 71, 63, - 69, 64, 46, 44, 41, 38, 2, 100, 77, 68, 53, 45, 89, 95, 97, 72, - 57, 40, 34, 0, 93, 55, 51, 45, 29, 34, 33, 33, 52, 38, 26, 2, - 65, 75, 65, 48, 21, 33, 33, 29, 22, 21, 17, 0, 67, 77, 32, 41, - 30, 21, 40, 34, 36, 28, 12, 5, 20, 59, 55, 52, 24, 21, 21, 21, - 14, 18, 28, 10, 18, 80, 63, 64, 92, 153, 159, 162, 158, 158, 163, 166, - 148, 126, 0, 161, 170, 167, 174, 175, 173, 163, 163, 148, 135, 57, 131, 177, - 177, 165, 169, 174, 169, 167, 166, 158, 146, 132, 0, 162, 166, 151, 167, 157, - 155, 151, 153, 159, 124, 81, 112, 162, 170, 165, 163, 167, 171, 163, 161, 163, - 157, 158, 84, 97, 157, 157, 147, 150, 148, 147, 144, 143, 122, 114, 88, 153, - 157, 146, 158, 150, 158, 154, 146, 139, 136, 112, 49, 115, 162, 143, 155, 155, - 148, 153, 154, 131, 120, 119, 24, 153, 154, 154, 147, 140, 148, 142, 148, 154, - 116, 48, 77, 134, 112, 95, 104, 104, 108, 104, 108, 106, 111, 103, 59, 138, - 157, 154, 151, 166, 150, 148, 135, 138, 112, 88, 0, 138, 146, 163, 153, 136, - 142, 146, 150, 148, 140, 136, 68, 89, 150, 155, 144, 131, 130, 142, 135, 114, - 91, 61, 110, 158, 155, 139, 147, 153, 144, 142, 146, 131, 142, 100, 0, 146, - 151, 150, 139, 143, 136, 135, 136, 131, 132, 60, 139, 144, 143, 126, 136, 118, - 106, 107, 128, 128, 123, 64, 127, 136, 134, 134, 136, 135, 138, 136, 134, 107, - 111, 89, 8, 93, 120, 103, 115, 110, 100, 110, 110, 108, 102, 99, 64, 84, - 140, 126, 144, 143, 118, 123, 108, 114, 92, 84, 20, 122, 123, 119, 108, 127, - 130, 131, 124, 124, 72, 29, 85, 154, 146, 138, 131, 135, 132, 130, 131, 135, - 111, 114, 44, 110, 142, 130, 118, 126, 116, 115, 115, 115, 97, 53, 85, 157, - 146, 155, 135, 155, 143, 150, 138, 132, 131, 71, 81, 128, 140, 107, 112, 116, - 118, 130, 104, 81, 83, 41, 93, 128, 119, 120, 114, 116, 110, 107, 112, 92, - 103, 97, 51, 111, 114, 112, 114, 106, 106, 110, 99, 96, 93, 96, 48, 123, - 127, 120, 116, 93, 114, 104, 108, 103, 92, 83, 17, 102, 116, 104, 97, 77, - 89, 85, 77, 80, 77, 48, 63, 112, 118, 115, 118, 95, 87, 106, 92, 81, - 81, 65, 8, 111, 116, 95, 104, 93, 106, 108, 72, 80, 88, 75, 10, 118, - 118, 131, 99, 118, 122, 104, 88, 73, 72, 46, 89, 97, 108, 99, 96, 69, - 96, 97, 65, 71, 65, 16, 99, 147, 123, 106, 103, 100, 107, 104, 103, 106, - 104, 77, 18, 57, 89, 49, 46, 52, 41, 46, 38, 44, 38, 37, 20, 49, - 96, 67, 102, 76, 81, 79, 77, 71, 72, 55, 0, 100, 104, 104, 77, 92, - 93, 80, 97, 93, 71, 69, 37, 0, 122, 131, 102, 96, 91, 93, 89, 79, - 69, 80, 8, 106, 95, 64, 56, 83, 79, 61, 67, 76, 49, 28, 38, 84, - 102, 100, 60, 55, 53, 48, 44, 46, 53, 38, 17, 59, 95, 81, 81, 77, - 72, 48, 46, 59, 63, 44, 21, 79, 75, 68, 61, 68, 81, 49, 46, 41, - 36, 2, 104, 87, 68, 41, 48, 41, 51, 52, 42, 56, 38, 30, 6, 81, - 46, 38, 26, 29, 26, 28, 29, 37, 29, 24, 2, 63, 69, 65, 21, 40, - 26, 69, 38, 34, 32, 16, 0, 53, 69, 38, 51, 44, 20, 32, 41, 30, - 24, 12, 5, 10, 16, 29, 38, 51, 38, 14, 12, 10, 38, 18, 8, 26, - 84, 68, 41, 32, 154, 158, 159, 157, 158, 158, 167, 155, 116, 2, 157, 175, - 163, 173, 177, 173, 165, 170, 167, 110, 51, 134, 174, 179, 167, 166, 171, 171, - 170, 169, 159, 158, 135, 1, 159, 173, 157, 167, 157, 150, 151, 155, 157, 95, - 79, 111, 142, 173, 157, 167, 157, 163, 161, 162, 144, 161, 130, 89, 96, 150, - 157, 153, 150, 148, 147, 150, 136, 120, 102, 96, 150, 178, 151, 158, 150, 144, - 158, 146, 135, 138, 99, 40, 122, 163, 142, 157, 147, 148, 159, 153, 128, 110, - 114, 13, 146, 150, 159, 154, 148, 153, 155, 148, 151, 114, 44, 77, 143, 106, - 111, 107, 128, 111, 99, 100, 104, 111, 96, 71, 89, 155, 154, 147, 162, 159, - 163, 157, 130, 107, 112, 1, 134, 153, 163, 151, 146, 143, 140, 139, 140, 139, - 135, 75, 80, 136, 142, 151, 130, 110, 135, 134, 104, 89, 55, 99, 158, 151, - 148, 146, 146, 139, 144, 131, 131, 144, 87, 0, 143, 143, 143, 135, 143, 138, - 128, 123, 140, 135, 71, 100, 130, 151, 132, 150, 123, 119, 134, 138, 100, 120, - 71, 93, 128, 134, 134, 128, 128, 127, 128, 108, 106, 112, 72, 4, 91, 122, - 119, 99, 93, 103, 97, 97, 97, 102, 96, 68, 75, 132, 140, 140, 108, 122, - 118, 104, 112, 95, 97, 18, 118, 119, 114, 102, 107, 97, 118, 115, 130, 72, - 32, 83, 153, 147, 136, 130, 131, 134, 140, 136, 138, 119, 96, 36, 106, 136, - 123, 118, 136, 115, 114, 112, 112, 95, 52, 81, 147, 144, 134, 139, 132, 140, - 146, 135, 131, 132, 72, 45, 120, 135, 106, 116, 115, 127, 122, 93, 85, 76, - 33, 92, 122, 123, 128, 114, 108, 112, 92, 96, 92, 102, 97, 53, 102, 110, - 115, 114, 108, 107, 106, 110, 99, 92, 99, 51, 71, 128, 122, 106, 111, 118, - 103, 114, 91, 92, 87, 16, 99, 116, 99, 75, 77, 91, 85, 80, 77, 81, - 65, 60, 107, 112, 112, 107, 97, 112, 84, 88, 79, 72, 64, 8, 110, 103, - 87, 96, 103, 75, 92, 73, 72, 83, 83, 13, 108, 131, 114, 95, 91, 93, - 108, 93, 72, 75, 42, 85, 91, 112, 103, 93, 71, 93, 68, 68, 72, 68, - 17, 108, 138, 122, 93, 87, 110, 88, 108, 104, 111, 96, 89, 13, 77, 81, - 48, 34, 37, 52, 37, 40, 37, 30, 33, 18, 45, 89, 110, 79, 69, 57, - 64, 80, 68, 64, 41, 13, 84, 103, 77, 80, 87, 80, 93, 80, 80, 73, - 60, 36, 0, 115, 122, 96, 95, 89, 91, 91, 77, 68, 68, 8, 93, 97, - 61, 48, 79, 79, 71, 56, 72, 49, 41, 33, 79, 99, 102, 60, 45, 46, - 44, 44, 49, 55, 37, 12, 81, 87, 79, 99, 75, 61, 48, 51, 49, 65, - 48, 24, 32, 81, 69, 65, 60, 59, 53, 46, 42, 28, 4, 103, 76, 65, - 48, 48, 56, 51, 46, 45, 59, 36, 30, 5, 79, 41, 29, 29, 26, 28, - 51, 37, 33, 29, 24, 2, 61, 61, 77, 44, 41, 52, 53, 24, 36, 22, - 16, 0, 38, 67, 41, 40, 40, 44, 46, 38, 30, 22, 10, 4, 10, 8, - 21, 24, 24, 34, 14, 10, 10, 26, 13, 4, 36, 72, 37, 36, 32, 171, - 167, 163, 162, 161, 159, 158, 158, 143, 33, 155, 167, 163, 166, 167, 174, 169, - 169, 167, 130, 44, 134, 171, 169, 169, 159, 167, 166, 169, 154, 158, 153, 134, - 1, 157, 167, 162, 153, 153, 163, 159, 163, 127, 116, 71, 124, 159, 169, 170, - 163, 127, 118, 130, 140, 140, 128, 130, 136, 128, 108, 119, 148, 153, 153, 150, - 130, 127, 114, 92, 108, 153, 175, 154, 159, 147, 158, 146, 134, 144, 132, 130, - 36, 128, 159, 139, 161, 157, 158, 151, 154, 140, 108, 116, 16, 150, 155, 159, - 153, 151, 158, 154, 154, 150, 87, 38, 77, 93, 87, 89, 106, 103, 108, 104, - 84, 88, 88, 111, 77, 83, 142, 151, 150, 148, 143, 142, 142, 123, 119, 91, - 4, 134, 130, 161, 147, 147, 143, 134, 130, 134, 128, 126, 123, 120, 83, 89, - 100, 111, 111, 127, 134, 120, 112, 60, 114, 154, 140, 142, 131, 140, 142, 142, - 140, 142, 142, 114, 5, 139, 143, 144, 131, 142, 140, 122, 139, 138, 132, 79, - 76, 89, 124, 120, 142, 131, 112, 104, 134, 110, 81, 73, 76, 87, 127, 96, - 97, 102, 100, 102, 102, 102, 114, 107, 29, 95, 114, 93, 95, 88, 103, 93, - 91, 104, 95, 95, 100, 68, 88, 123, 124, 96, 92, 106, 102, 115, 108, 95, - 13, 112, 118, 103, 119, 112, 112, 107, 112, 104, 67, 76, 69, 148, 144, 139, - 139, 131, 132, 130, 132, 131, 116, 111, 32, 110, 132, 123, 110, 115, 120, 110, - 110, 112, 97, 46, 127, 153, 131, 128, 139, 140, 140, 128, 136, 136, 131, 80, - 67, 112, 131, 104, 122, 119, 111, 108, 103, 85, 73, 30, 93, 119, 111, 93, - 95, 93, 96, 93, 96, 99, 102, 97, 57, 63, 112, 115, 114, 111, 102, 102, - 108, 95, 93, 93, 67, 65, 119, 119, 108, 112, 128, 111, 104, 83, 92, 81, - 20, 93, 96, 79, 76, 77, 77, 68, 76, 57, 71, 80, 56, 71, 97, 97, - 104, 81, 84, 79, 77, 79, 85, 60, 10, 100, 118, 122, 97, 102, 100, 71, - 96, 83, 76, 71, 12, 112, 118, 107, 124, 84, 83, 95, 91, 81, 59, 34, - 93, 93, 108, 97, 85, 72, 87, 72, 71, 71, 61, 18, 96, 143, 124, 114, - 103, 104, 108, 107, 103, 99, 97, 83, 14, 64, 37, 37, 34, 25, 34, 33, - 32, 33, 32, 28, 24, 44, 84, 65, 56, 57, 52, 59, 61, 63, 65, 57, - 2, 92, 95, 76, 75, 93, 83, 76, 76, 76, 75, 57, 33, 0, 118, 124, - 95, 93, 97, 91, 91, 97, 65, 71, 1, 88, 87, 63, 48, 77, 76, 76, - 60, 60, 48, 42, 32, 72, 87, 79, 41, 42, 52, 44, 46, 49, 52, 42, - 13, 64, 87, 93, 55, 64, 61, 45, 53, 60, 67, 52, 34, 24, 49, 79, - 77, 68, 69, 65, 55, 46, 37, 4, 93, 79, 63, 40, 46, 48, 55, 52, - 46, 57, 32, 33, 0, 75, 36, 28, 29, 25, 29, 42, 55, 33, 30, 22, - 4, 63, 88, 60, 44, 38, 59, 29, 37, 37, 22, 14, 0, 18, 49, 52, - 52, 41, 40, 44, 42, 37, 17, 10, 4, 9, 14, 9, 12, 10, 9, 10, - 10, 10, 24, 26, 4, 71, 85, 64, 46, 41, 151, 154, 151, 157, 155, 161, - 157, 144, 128, 0, 153, 159, 161, 157, 159, 159, 162, 158, 151, 124, 32, 135, - 144, 144, 140, 144, 142, 144, 151, 143, 143, 134, 131, 26, 151, 165, 165, 161, - 163, 153, 159, 157, 122, 110, 71, 119, 153, 166, 163, 127, 136, 118, 116, 128, - 138, 126, 122, 114, 122, 123, 130, 142, 139, 138, 136, 135, 111, 108, 83, 108, - 157, 157, 153, 139, 132, 140, 147, 127, 127, 130, 130, 28, 122, 161, 154, 142, - 139, 148, 155, 147, 138, 120, 114, 17, 144, 153, 162, 153, 154, 159, 155, 148, - 119, 106, 33, 83, 104, 73, 80, 72, 91, 81, 85, 85, 84, 80, 83, 84, - 110, 91, 97, 103, 107, 107, 108, 115, 127, 103, 77, 8, 128, 142, 143, 140, - 136, 104, 131, 93, 103, 104, 122, 99, 102, 115, 126, 115, 118, 123, 122, 138, - 122, 84, 46, 111, 122, 130, 123, 120, 124, 127, 128, 130, 123, 115, 114, 4, - 134, 135, 139, 134, 130, 128, 128, 127, 126, 119, 116, 118, 122, 102, 97, 102, - 103, 99, 112, 107, 118, 112, 110, 111, 111, 97, 93, 116, 112, 97, 115, 118, - 115, 112, 110, 10, 81, 107, 110, 95, 77, 80, 87, 88, 89, 91, 100, 92, - 96, 102, 106, 107, 106, 106, 107, 110, 111, 99, 81, 26, 106, 108, 106, 97, - 92, 87, 95, 81, 75, 67, 59, 68, 91, 139, 147, 108, 127, 127, 132, 114, - 115, 111, 111, 25, 106, 103, 106, 96, 100, 100, 108, 108, 111, 96, 48, 93, - 140, 130, 127, 116, 119, 119, 114, 106, 93, 96, 80, 67, 106, 116, 112, 107, - 104, 104, 104, 107, 77, 73, 26, 93, 120, 114, 107, 110, 103, 108, 102, 106, - 110, 102, 91, 93, 61, 68, 75, 99, 72, 76, 102, 104, 103, 104, 91, 83, - 60, 77, 124, 112, 111, 108, 80, 83, 93, 83, 65, 32, 84, 100, 81, 69, - 67, 65, 60, 60, 69, 59, 59, 68, 79, 81, 91, 85, 88, 83, 84, 85, - 87, 83, 64, 12, 93, 106, 114, 99, 69, 103, 99, 102, 83, 81, 77, 17, - 104, 118, 97, 88, 103, 102, 97, 97, 75, 72, 41, 93, 87, 83, 75, 87, - 68, 67, 72, 69, 68, 65, 14, 99, 130, 111, 75, 103, 102, 76, 92, 97, - 96, 92, 42, 18, 21, 36, 40, 25, 24, 36, 26, 28, 28, 34, 36, 26, - 38, 51, 53, 49, 51, 55, 57, 55, 56, 55, 56, 0, 80, 87, 84, 81, - 80, 79, 77, 67, 71, 69, 53, 30, 0, 108, 120, 93, 92, 91, 92, 91, - 97, 63, 65, 13, 77, 85, 60, 46, 41, 51, 45, 45, 32, 33, 42, 34, - 36, 38, 40, 46, 49, 48, 49, 46, 51, 49, 38, 12, 29, 65, 63, 38, - 45, 59, 56, 41, 49, 49, 51, 36, 28, 30, 41, 37, 37, 36, 37, 42, - 46, 36, 5, 64, 75, 69, 63, 60, 59, 56, 45, 51, 57, 34, 32, 1, - 71, 48, 28, 25, 24, 41, 37, 37, 33, 32, 24, 4, 57, 84, 41, 44, - 18, 41, 40, 20, 22, 33, 12, 0, 17, 30, 45, 17, 20, 25, 33, 30, - 18, 18, 9, 2, 8, 13, 12, 10, 9, 10, 9, 12, 9, 18, 12, 2, - 56, 85, 42, 24, 24, 119, 114, 132, 108, 106, 99, 131, 96, 40, 0, 72, - 88, 83, 84, 96, 92, 91, 93, 103, 91, 38, 92, 106, 103, 99, 92, 91, - 85, 87, 84, 83, 81, 67, 0, 72, 79, 76, 89, 91, 80, 83, 102, 97, - 73, 71, 79, 119, 123, 84, 80, 85, 76, 72, 71, 68, 72, 65, 67, 64, - 65, 75, 85, 89, 92, 96, 104, 107, 102, 80, 95, 114, 126, 110, 103, 110, - 122, 102, 100, 114, 103, 68, 25, 80, 110, 127, 115, 120, 119, 128, 122, 124, - 111, 110, 22, 138, 151, 153, 153, 140, 136, 144, 135, 97, 95, 25, 102, 79, - 61, 75, 61, 65, 64, 76, 68, 56, 67, 60, 59, 61, 60, 48, 75, 80, - 84, 88, 88, 93, 96, 81, 4, 53, 77, 81, 59, 57, 57, 61, 48, 45, - 41, 59, 56, 41, 40, 55, 56, 59, 45, 107, 114, 111, 71, 42, 75, 88, - 85, 83, 83, 97, 87, 79, 72, 72, 63, 34, 64, 67, 75, 91, 93, 84, - 84, 95, 93, 92, 93, 97, 95, 102, 104, 111, 107, 106, 104, 107, 106, 114, - 99, 95, 93, 114, 100, 93, 87, 110, 87, 80, 77, 110, 77, 18, 16, 79, - 63, 63, 65, 44, 55, 37, 34, 40, 48, 42, 41, 44, 44, 44, 44, 57, - 64, 71, 75, 96, 80, 75, 26, 40, 42, 48, 45, 51, 41, 48, 45, 53, - 41, 38, 59, 89, 77, 92, 96, 89, 85, 91, 91, 88, 80, 76, 22, 77, - 84, 85, 89, 85, 85, 89, 97, 89, 83, 46, 37, 107, 119, 96, 99, 102, - 114, 103, 102, 108, 112, 103, 76, 69, 75, 84, 91, 93, 95, 104, 110, 72, - 67, 24, 87, 110, 118, 114, 96, 103, 104, 103, 91, 91, 89, 80, 77, 84, - 89, 89, 88, 88, 85, 88, 88, 87, 80, 80, 85, 83, 85, 89, 91, 88, - 87, 85, 85, 84, 75, 81, 21, 84, 55, 49, 46, 42, 41, 45, 38, 34, - 33, 36, 34, 36, 52, 36, 37, 37, 41, 38, 57, 60, 55, 53, 13, 36, - 97, 95, 51, 53, 84, 84, 53, 64, 77, 65, 16, 72, 106, 102, 79, 81, - 96, 92, 73, 73, 69, 42, 91, 85, 67, 61, 56, 56, 59, 56, 57, 60, - 60, 24, 85, 107, 96, 38, 34, 34, 38, 40, 29, 30, 18, 51, 25, 1, - 2, 12, 4, 17, 2, 8, 10, 17, 14, 20, 29, 36, 48, 45, 36, 51, - 46, 49, 33, 53, 52, 40, 1, 25, 30, 32, 30, 30, 28, 29, 29, 29, - 29, 28, 26, 0, 51, 108, 106, 103, 103, 102, 100, 95, 60, 81, 16, 55, - 73, 40, 42, 38, 40, 49, 45, 44, 42, 42, 41, 40, 28, 25, 22, 20, - 21, 20, 18, 17, 16, 16, 9, 16, 14, 17, 21, 17, 20, 22, 24, 29, - 28, 24, 29, 28, 32, 30, 34, 34, 33, 30, 34, 36, 32, 6, 18, 30, - 41, 26, 30, 33, 51, 52, 59, 37, 34, 26, 9, 65, 32, 33, 36, 29, - 30, 26, 30, 24, 24, 18, 5, 14, 22, 38, 8, 8, 8, 9, 8, 5, - 5, 17, 0, 5, 5, 5, 9, 6, 8, 6, 16, 18, 22, 8, 2, 13, - 6, 16, 6, 10, 14, 14, 10, 17, 20, 12, 5, 37, 85, 30, 29, 25, - 8, 4, 8, 28, 29, 4, 4, 40, 42, 13, 44, 34, 26, 24, 21, 49, - 18, 17, 13, 53, 42, 5, 38, 9, 6, 5, 24, 6, 5, 4, 2, 4, - 2, 6, 12, 16, 10, 16, 14, 14, 16, 20, 20, 20, 79, 76, 73, 107, - 107, 123, 124, 126, 132, 138, 136, 131, 132, 131, 134, 151, 134, 134, 95, 95, - 93, 88, 80, 80, 67, 44, 46, 42, 40, 36, 36, 36, 34, 34, 37, 40, - 40, 42, 46, 55, 56, 63, 69, 73, 80, 81, 85, 92, 99, 34, 34, 73, - 76, 76, 73, 77, 77, 79, 77, 69, 28, 79, 41, 71, 40, 56, 37, 40, - 68, 85, 110, 112, 96, 100, 116, 126, 140, 130, 119, 103, 95, 87, 87, 42, - 76, 5, 32, 30, 51, 53, 61, 73, 89, 102, 138, 130, 102, 95, 135, 139, - 122, 134, 138, 107, 89, 81, 71, 44, 22, 40, 33, 17, 24, 24, 21, 12, - 13, 13, 10, 8, 5, 6, 4, 5, 2, 2, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 14, 0, - 0, 0, 25, 0, 0, 0, 38, 0, 0, 9, 26, 33, 38, 37, 92, 123, - 127, 134, 128, 122, 92, 106, 127, 126, 116, 124, 120, 112, 96, 72, 69, 36, - 59, 29, 2, 1, 26, 22, 1, 0, 17, 5, 8, 1, 6, 9, 9, 1, - 5, 4, 1, 6, 18, 21, 1, 8, 4, 2, 36, 37, 2, 2, 21, 22, - 25, 26, 33, 29, 59, 21, 20, 32, 24, 20, 22, 32, 22, 20, 22, 30, - 24, 22, 22, 56, 25, 24, 24, 30, 36, 45, 41, 65, 22, 59, 80, 79, - 61, 61, 75, 73, 59, 60, 64, 60, 55, 42, 46, 49, 37, 41, 41, 45, - 51, 46, 69, 69, 67, 63, 69, 67, 51, 48, 60, 48, 38, 34, 59, 34, - 52, 26, 44, 63, 75, 75, 76, 87, 111, 93, 69, 73, 61, 59, 64, 97, - 95, 97, 89, 72, 57, 46, 42, 36, 29, 29, 32, 46, 36, 44, 32, 36, - 44, 49, 33, 34, 26, 52, 51, 52, 56, 55, 52, 46, 53, 53, 52, 49, - 44, 88, 59, 45, 56, 44, 48, 45, 45, 40, 40, 42, 53, 29, 41, 56, - 63, 71, 72, 75, 73, 69, 75, 64, 51, 12, 34, 119, 83, 77, 60, 34, - 34, 28, 25, 10, 9, 8, 5, 16, 12, 6, 5, 17, 17, 13, 5, 17, - 17, 5, 4, 13, 14, 13, 1, 9, 2, 9, 1, 5, 2, 0, 0, 26, - 30, 36, 38, 42, 46, 49, 53, 59, 56, 13, 60, 28, 29, 22, 22, 25, - 24, 21, 18, 21, 14, 16, 38, 51, 56, 69, 71, 73, 75, 68, 60, 53, - 34, 12, 68, 80, 79, 57, 72, 67, 60, 26, 14, 13, 6, 10, 10, 10, - 9, 13, 12, 8, 5, 6, 6, 4, 6, 17, 14, 18, 12, 12, 17, 25, - 26, 29, 29, 28, 25, 1, 55, 9, 9, 16, 10, 8, 6, 6, 9, 5, - 4, 5, 10, 21, 36, 32, 33, 44, 48, 45, 42, 34, 17, 0, 48, 75, - 68, 67, 67, 61, 30, 20, 10, 6, 2, 2, 0, 4, 1, 1, 6, 6, - 6, 4, 6, 4, 9, 4, 24, 76, 42, 40, 29, 191, 187, 182, 177, 171, - 159, 166, 135, 73, 32, 80, 151, 161, 147, 136, 142, 139, 139, 144, 123, 57, - 68, 155, 161, 162, 157, 165, 163, 162, 157, 163, 147, 157, 150, 162, 165, 162, - 167, 167, 163, 161, 151, 96, 64, 80, 114, 157, 167, 162, 159, 165, 166, 163, - 155, 165, 167, 162, 124, 114, 131, 122, 143, 143, 136, 146, 139, 75, 100, 69, - 64, 154, 153, 140, 136, 139, 136, 126, 128, 126, 114, 106, 116, 134, 151, 143, - 138, 112, 88, 61, 45, 56, 41, 24, 37, 42, 36, 34, 41, 48, 37, 30, - 34, 57, 51, 64, 59, 87, 100, 108, 119, 111, 122, 131, 126, 118, 132, 118, - 119, 91, 107, 134, 116, 119, 122, 126, 123, 131, 106, 97, 9, 57, 148, 153, - 153, 157, 148, 143, 130, 131, 150, 138, 88, 116, 134, 154, 143, 140, 136, 122, - 135, 102, 89, 48, 67, 114, 119, 134, 135, 134, 115, 126, 139, 139, 96, 92, - 97, 153, 150, 155, 154, 153, 148, 154, 150, 144, 97, 106, 138, 143, 148, 142, - 130, 134, 147, 130, 130, 128, 136, 114, 33, 64, 132, 142, 103, 120, 128, 140, - 102, 124, 124, 60, 55, 53, 136, 124, 130, 132, 136, 132, 142, 135, 97, 107, - 91, 95, 110, 130, 123, 127, 120, 107, 108, 114, 79, 45, 6, 44, 108, 126, - 102, 96, 108, 99, 97, 93, 75, 42, 0, 52, 110, 142, 106, 107, 106, 103, - 116, 122, 118, 71, 48, 61, 132, 139, 127, 131, 134, 136, 99, 120, 56, 63, - 56, 112, 122, 120, 104, 107, 99, 95, 115, 108, 92, 51, 57, 64, 100, 108, - 100, 104, 71, 71, 34, 32, 26, 25, 36, 37, 45, 49, 45, 48, 48, 48, - 57, 61, 59, 55, 53, 21, 73, 110, 116, 89, 107, 84, 83, 40, 46, 33, - 21, 30, 46, 71, 77, 75, 80, 85, 83, 81, 72, 60, 68, 95, 127, 138, - 127, 123, 123, 116, 115, 114, 114, 59, 57, 87, 119, 116, 122, 116, 112, 107, - 114, 107, 81, 60, 57, 85, 87, 92, 88, 77, 72, 75, 63, 37, 29, 21, - 30, 29, 41, 41, 34, 18, 21, 18, 37, 16, 17, 42, 37, 61, 77, 79, - 93, 96, 103, 96, 104, 92, 57, 52, 72, 89, 96, 100, 97, 100, 100, 102, - 93, 108, 84, 69, 1, 99, 87, 83, 67, 93, 92, 79, 72, 67, 85, 71, - 64, 96, 107, 95, 99, 107, 100, 92, 88, 85, 79, 28, 0, 22, 81, 114, - 87, 81, 81, 85, 76, 65, 88, 72, 26, 0, 77, 92, 88, 87, 80, 63, - 24, 46, 42, 40, 2, 24, 33, 52, 57, 57, 69, 79, 84, 68, 81, 68, - 83, 68, 73, 79, 75, 71, 80, 77, 87, 72, 59, 37, 13, 79, 81, 59, - 64, 72, 52, 57, 53, 61, 55, 34, 44, 34, 69, 77, 79, 69, 80, 76, - 69, 68, 24, 6, 34, 71, 68, 53, 56, 56, 51, 21, 12, 9, 8, 6, - 1, 4, 34, 36, 36, 37, 45, 48, 49, 49, 51, 24, 6, 46, 80, 76, - 79, 76, 71, 67, 61, 56, 37, 17, 0, 56, 84, 68, 63, 59, 67, 57, - 61, 53, 30, 12, 1, 42, 59, 57, 17, 13, 12, 9, 16, 10, 5, 10, - 2, 71, 48, 106, 116, 120, 186, 179, 173, 174, 167, 173, 166, 161, 87, 42, - 162, 161, 158, 153, 161, 159, 159, 157, 154, 158, 57, 166, 173, 170, 170, 166, - 173, 167, 174, 166, 175, 161, 155, 150, 165, 158, 163, 162, 165, 157, 157, 161, - 154, 153, 85, 147, 169, 157, 162, 165, 157, 163, 158, 161, 155, 120, 131, 107, - 126, 140, 136, 139, 130, 131, 134, 134, 143, 103, 91, 127, 158, 155, 155, 161, - 151, 154, 151, 153, 150, 144, 130, 143, 142, 146, 144, 140, 144, 138, 138, 140, - 135, 138, 104, 28, 56, 127, 136, 120, 123, 127, 135, 130, 123, 84, 61, 93, - 131, 134, 138, 128, 144, 151, 154, 147, 131, 147, 134, 73, 112, 146, 158, 154, - 123, 138, 140, 131, 136, 116, 99, 12, 124, 158, 147, 144, 143, 135, 148, 124, - 128, 158, 143, 95, 119, 158, 154, 147, 151, 148, 151, 123, 138, 100, 45, 116, - 132, 143, 130, 134, 134, 140, 130, 143, 140, 143, 138, 126, 107, 111, 115, 119, - 115, 116, 118, 122, 120, 128, 124, 95, 123, 132, 120, 114, 127, 136, 134, 135, - 140, 143, 140, 34, 147, 158, 147, 144, 147, 140, 134, 135, 131, 130, 72, 45, - 104, 123, 128, 127, 136, 136, 139, 138, 132, 123, 111, 85, 93, 128, 139, 127, - 130, 130, 124, 116, 118, 88, 49, 20, 123, 134, 135, 126, 130, 132, 128, 124, - 123, 107, 48, 2, 153, 155, 151, 150, 153, 151, 146, 139, 154, 147, 108, 51, - 138, 153, 151, 143, 143, 132, 138, 130, 127, 87, 63, 114, 136, 122, 116, 114, - 131, 132, 126, 128, 127, 128, 119, 56, 100, 119, 122, 118, 116, 112, 108, 100, - 73, 51, 24, 80, 100, 81, 93, 96, 92, 102, 92, 92, 85, 76, 61, 46, - 17, 100, 119, 107, 104, 102, 108, 119, 100, 112, 95, 77, 99, 76, 96, 103, - 111, 100, 114, 97, 107, 84, 69, 75, 115, 138, 108, 111, 111, 107, 95, 110, - 104, 93, 99, 77, 112, 106, 111, 103, 102, 100, 108, 103, 99, 91, 103, 92, - 99, 100, 102, 88, 102, 96, 97, 87, 81, 80, 76, 107, 100, 103, 106, 110, - 112, 108, 114, 120, 122, 57, 63, 80, 136, 139, 140, 138, 140, 136, 131, 134, - 132, 88, 52, 79, 106, 102, 97, 96, 89, 91, 81, 79, 83, 93, 57, 10, - 72, 91, 81, 69, 69, 77, 65, 81, 77, 61, 65, 71, 64, 77, 80, 77, - 67, 73, 73, 77, 69, 91, 34, 0, 112, 118, 120, 122, 116, 114, 111, 100, - 108, 103, 84, 48, 0, 81, 89, 95, 97, 97, 92, 87, 77, 69, 40, 9, - 63, 95, 99, 102, 103, 102, 102, 93, 84, 81, 42, 64, 93, 95, 95, 96, - 89, 81, 71, 71, 73, 60, 42, 14, 80, 85, 61, 56, 49, 55, 72, 64, - 79, 69, 30, 24, 72, 93, 91, 91, 89, 80, 76, 83, 80, 29, 8, 57, - 75, 75, 75, 77, 71, 71, 60, 57, 52, 40, 17, 40, 75, 91, 88, 85, - 81, 83, 80, 69, 76, 55, 32, 6, 68, 71, 61, 59, 59, 45, 46, 34, - 44, 55, 21, 2, 40, 83, 71, 59, 42, 46, 45, 46, 61, 49, 17, 1, - 61, 61, 69, 59, 55, 38, 48, 53, 51, 9, 12, 1, 69, 64, 85, 84, - 92, 191, 191, 185, 178, 175, 175, 150, 134, 87, 46, 155, 161, 153, 153, 154, - 111, 153, 151, 148, 80, 64, 171, 183, 182, 190, 201, 205, 209, 214, 217, 220, - 224, 228, 230, 226, 226, 226, 226, 218, 209, 189, 173, 167, 161, 142, 167, 159, - 158, 154, 148, 151, 150, 135, 112, 118, 128, 114, 96, 130, 144, 157, 142, 139, - 143, 144, 146, 144, 139, 65, 151, 161, 153, 154, 148, 148, 151, 148, 144, 146, - 147, 138, 139, 150, 154, 153, 147, 144, 139, 138, 146, 147, 131, 111, 34, 142, - 146, 157, 157, 148, 153, 153, 150, 150, 131, 56, 118, 162, 154, 138, 157, 150, - 138, 138, 150, 150, 151, 132, 77, 110, 151, 159, 148, 147, 150, 150, 148, 132, - 119, 108, 9, 132, 153, 154, 143, 134, 143, 130, 147, 138, 151, 144, 76, 107, - 148, 142, 148, 140, 142, 126, 126, 136, 107, 57, 126, 122, 128, 138, 124, 139, - 140, 147, 146, 138, 127, 97, 130, 123, 139, 139, 140, 139, 135, 127, 114, 112, - 104, 88, 118, 144, 134, 135, 146, 143, 140, 144, 143, 142, 140, 135, 33, 150, - 158, 131, 127, 130, 124, 126, 120, 131, 128, 72, 46, 103, 128, 132, 126, 126, - 122, 127, 127, 135, 124, 115, 67, 85, 126, 118, 123, 131, 132, 119, 108, 112, - 95, 81, 29, 123, 127, 128, 127, 127, 120, 120, 120, 114, 110, 64, 1, 131, - 150, 151, 153, 148, 151, 153, 146, 143, 147, 124, 60, 146, 143, 142, 130, 123, - 126, 115, 120, 120, 127, 112, 132, 119, 112, 116, 106, 115, 92, 96, 95, 99, - 80, 79, 64, 123, 142, 116, 119, 118, 122, 112, 108, 110, 64, 22, 89, 96, - 85, 99, 91, 84, 95, 89, 84, 87, 69, 65, 56, 22, 97, 130, 104, 104, - 118, 106, 107, 104, 93, 103, 59, 67, 127, 122, 120, 128, 123, 118, 112, 106, - 93, 76, 71, 127, 132, 103, 106, 106, 99, 92, 103, 116, 111, 116, 112, 122, - 120, 130, 123, 122, 123, 147, 123, 128, 123, 127, 116, 126, 126, 128, 122, 120, - 123, 122, 122, 104, 85, 59, 108, 108, 106, 110, 106, 103, 92, 103, 102, 97, - 69, 48, 108, 143, 135, 132, 130, 136, 134, 140, 128, 111, 104, 61, 81, 100, - 103, 87, 85, 93, 84, 83, 91, 93, 85, 56, 10, 61, 95, 83, 93, 75, - 89, 79, 92, 92, 80, 68, 61, 81, 99, 92, 107, 104, 100, 88, 106, 93, - 85, 36, 9, 104, 116, 110, 110, 112, 111, 107, 106, 99, 114, 87, 42, 0, - 88, 96, 89, 79, 79, 67, 83, 91, 73, 29, 14, 60, 102, 103, 93, 77, - 71, 88, 68, 67, 52, 45, 76, 100, 87, 87, 73, 65, 71, 83, 75, 65, - 42, 37, 9, 79, 88, 80, 59, 60, 67, 72, 69, 67, 64, 32, 45, 88, - 92, 87, 73, 87, 69, 68, 72, 85, 29, 8, 65, 77, 56, 55, 49, 41, - 44, 40, 45, 63, 53, 18, 36, 81, 77, 84, 91, 72, 60, 61, 77, 68, - 67, 30, 8, 67, 57, 38, 63, 49, 48, 41, 34, 40, 33, 18, 0, 55, - 77, 59, 67, 55, 42, 44, 68, 49, 45, 18, 1, 30, 65, 57, 65, 57, - 61, 51, 57, 46, 20, 13, 1, 83, 103, 84, 75, 84, 179, 171, 175, 171, - 166, 154, 157, 166, 92, 68, 106, 158, 154, 127, 122, 119, 120, 122, 116, 153, - 154, 178, 221, 220, 228, 229, 226, 225, 226, 229, 233, 236, 238, 240, 240, 236, - 234, 236, 234, 234, 232, 232, 216, 178, 167, 161, 173, 179, 205, 179, 167, 148, - 138, 104, 119, 122, 111, 96, 146, 157, 150, 151, 143, 151, 157, 155, 143, 153, - 132, 150, 144, 151, 115, 155, 148, 153, 147, 153, 143, 143, 140, 146, 153, 155, - 147, 147, 143, 161, 158, 131, 123, 131, 107, 34, 148, 153, 155, 155, 157, 147, - 147, 148, 143, 130, 83, 126, 148, 153, 151, 148, 146, 134, 144, 148, 154, 140, - 127, 69, 103, 150, 163, 150, 146, 150, 153, 142, 132, 114, 95, 10, 116, 144, - 147, 143, 140, 143, 131, 118, 157, 157, 136, 83, 114, 150, 147, 139, 134, 131, - 124, 130, 140, 111, 80, 80, 126, 130, 138, 146, 151, 132, 134, 136, 123, 126, - 89, 122, 143, 127, 143, 139, 140, 127, 134, 135, 134, 95, 81, 127, 142, 131, - 139, 132, 139, 138, 112, 138, 139, 95, 97, 45, 99, 161, 132, 123, 127, 112, - 119, 123, 130, 126, 77, 42, 103, 123, 127, 116, 119, 120, 122, 124, 138, 123, - 108, 61, 92, 118, 114, 103, 134, 139, 119, 110, 118, 83, 81, 26, 93, 136, - 126, 124, 127, 116, 128, 128, 111, 102, 55, 6, 84, 148, 142, 134, 130, 130, - 135, 136, 128, 124, 130, 126, 131, 143, 144, 136, 127, 139, 120, 128, 110, 116, - 104, 115, 106, 116, 115, 110, 108, 112, 114, 111, 106, 110, 106, 108, 111, 122, - 130, 100, 108, 108, 132, 108, 106, 60, 20, 79, 89, 85, 92, 97, 99, 93, - 93, 88, 80, 71, 57, 51, 20, 95, 115, 100, 108, 118, 118, 118, 114, 104, - 103, 55, 111, 135, 130, 122, 111, 112, 110, 103, 106, 81, 75, 80, 110, 128, - 96, 107, 100, 99, 104, 136, 206, 209, 201, 213, 224, 224, 212, 221, 230, 234, - 230, 228, 233, 244, 229, 230, 225, 242, 221, 212, 216, 246, 222, 167, 112, 84, - 63, 107, 127, 139, 136, 132, 132, 122, 116, 115, 99, 71, 63, 123, 138, 130, - 128, 134, 134, 143, 138, 110, 122, 97, 69, 69, 100, 93, 87, 83, 88, 85, - 83, 83, 93, 83, 46, 6, 71, 108, 96, 112, 88, 79, 91, 85, 76, 77, - 68, 36, 89, 99, 91, 93, 96, 95, 73, 96, 95, 87, 32, 9, 68, 112, - 107, 100, 96, 96, 89, 93, 97, 107, 85, 41, 0, 84, 84, 80, 61, 81, - 80, 75, 77, 79, 44, 17, 72, 100, 87, 83, 81, 76, 83, 56, 64, 56, - 33, 72, 91, 77, 71, 68, 84, 67, 67, 57, 49, 52, 38, 13, 76, 88, - 80, 76, 83, 84, 56, 64, 60, 64, 22, 36, 92, 91, 84, 61, 81, 72, - 85, 83, 80, 30, 9, 67, 61, 51, 51, 41, 41, 41, 41, 41, 57, 51, - 20, 32, 76, 75, 81, 100, 75, 56, 61, 65, 56, 51, 30, 9, 60, 67, - 41, 71, 41, 52, 37, 40, 49, 34, 17, 0, 56, 77, 61, 55, 49, 52, - 48, 64, 44, 26, 18, 1, 49, 46, 56, 57, 42, 45, 44, 34, 42, 36, - 13, 2, 67, 61, 59, 28, 17, 163, 163, 166, 162, 162, 154, 169, 157, 93, - 59, 114, 161, 157, 127, 124, 110, 103, 161, 167, 197, 214, 222, 228, 236, 233, - 233, 229, 229, 224, 230, 237, 238, 238, 236, 234, 233, 230, 225, 229, 230, 232, - 229, 233, 230, 221, 225, 222, 209, 202, 216, 157, 144, 131, 106, 123, 123, 114, - 110, 163, 193, 198, 194, 198, 205, 209, 210, 208, 208, 204, 206, 208, 177, 166, - 162, 155, 159, 153, 150, 154, 151, 169, 185, 199, 205, 202, 195, 190, 155, 139, - 131, 108, 130, 103, 44, 104, 151, 146, 148, 146, 147, 140, 148, 153, 132, 84, - 96, 150, 159, 142, 144, 148, 136, 134, 138, 154, 140, 128, 67, 112, 148, 158, - 147, 146, 147, 151, 139, 138, 115, 103, 14, 112, 151, 157, 150, 143, 155, 124, - 148, 148, 148, 135, 67, 116, 139, 148, 134, 134, 139, 128, 143, 134, 111, 76, - 75, 140, 146, 127, 131, 132, 143, 131, 135, 128, 116, 81, 127, 143, 135, 134, - 131, 130, 134, 148, 140, 134, 120, 76, 130, 140, 140, 126, 138, 136, 135, 138, - 130, 136, 138, 128, 49, 102, 158, 135, 123, 118, 106, 114, 111, 127, 126, 77, - 38, 104, 123, 122, 112, 112, 112, 115, 119, 128, 116, 102, 65, 84, 112, 110, - 103, 124, 110, 103, 108, 114, 85, 48, 10, 95, 139, 118, 116, 124, 127, 122, - 118, 115, 100, 55, 4, 134, 142, 136, 134, 138, 135, 128, 132, 157, 194, 205, - 209, 218, 222, 230, 232, 236, 237, 248, 248, 246, 238, 238, 224, 232, 236, 232, - 230, 225, 228, 222, 224, 204, 205, 187, 206, 198, 228, 191, 182, 177, 178, 199, - 155, 114, 63, 26, 85, 77, 92, 99, 91, 89, 97, 79, 81, 55, 68, 49, - 42, 13, 93, 122, 106, 111, 122, 122, 119, 104, 92, 104, 42, 116, 132, 124, - 108, 107, 114, 118, 111, 115, 89, 71, 56, 106, 126, 93, 99, 96, 97, 97, - 142, 199, 205, 206, 213, 213, 217, 216, 213, 217, 221, 224, 225, 226, 225, 224, - 222, 221, 213, 214, 210, 208, 209, 202, 154, 106, 79, 22, 100, 118, 122, 126, - 124, 123, 136, 135, 107, 106, 72, 71, 97, 136, 128, 144, 140, 124, 120, 97, - 103, 110, 103, 67, 64, 104, 96, 83, 87, 85, 85, 83, 87, 75, 80, 60, - 1, 73, 108, 83, 97, 80, 89, 88, 107, 71, 71, 67, 46, 79, 104, 99, - 104, 106, 104, 103, 93, 81, 81, 32, 0, 71, 112, 99, 91, 88, 93, 104, - 104, 107, 111, 91, 40, 0, 79, 80, 77, 65, 95, 76, 76, 80, 64, 38, - 10, 60, 106, 92, 77, 72, 68, 83, 60, 59, 44, 34, 68, 97, 69, 83, - 87, 76, 68, 63, 68, 72, 49, 38, 18, 72, 77, 71, 75, 65, 65, 59, - 69, 57, 63, 24, 40, 89, 83, 69, 80, 75, 95, 83, 81, 77, 32, 12, - 55, 76, 53, 52, 42, 40, 38, 38, 40, 40, 40, 18, 2, 75, 76, 88, - 95, 56, 63, 64, 57, 67, 51, 33, 10, 53, 68, 41, 75, 29, 52, 37, - 34, 44, 30, 17, 0, 42, 75, 67, 69, 53, 55, 45, 63, 49, 29, 17, - 1, 46, 59, 55, 29, 34, 32, 33, 24, 37, 18, 13, 8, 68, 60, 45, - 56, 18, 161, 161, 162, 163, 161, 154, 167, 151, 93, 65, 153, 150, 123, 119, - 128, 158, 159, 205, 233, 234, 236, 237, 230, 228, 228, 228, 204, 175, 162, 167, - 170, 163, 147, 136, 131, 127, 116, 112, 120, 128, 143, 191, 214, 228, 228, 228, - 225, 221, 221, 209, 157, 139, 119, 106, 124, 104, 115, 151, 175, 206, 205, 213, - 204, 214, 220, 218, 216, 226, 224, 229, 226, 225, 222, 225, 221, 218, 213, 206, - 210, 214, 218, 216, 222, 214, 213, 208, 208, 155, 135, 126, 102, 127, 104, 48, - 106, 154, 139, 140, 161, 154, 153, 151, 147, 131, 85, 67, 142, 154, 153, 148, - 150, 155, 155, 155, 155, 139, 128, 63, 107, 162, 163, 144, 150, 147, 153, 139, - 138, 115, 96, 17, 126, 153, 144, 146, 140, 148, 138, 142, 151, 142, 138, 67, - 118, 138, 144, 136, 134, 140, 138, 139, 135, 110, 77, 61, 139, 131, 131, 134, - 140, 130, 142, 135, 120, 108, 77, 116, 139, 131, 127, 131, 139, 136, 134, 136, - 126, 95, 77, 131, 143, 150, 140, 139, 120, 143, 136, 127, 138, 135, 131, 53, - 104, 155, 138, 118, 116, 104, 107, 119, 128, 127, 80, 37, 111, 116, 118, 115, - 115, 110, 110, 120, 124, 115, 106, 64, 89, 108, 107, 97, 95, 132, 131, 106, - 111, 88, 48, 21, 106, 139, 124, 124, 123, 118, 116, 102, 115, 119, 51, 4, - 148, 148, 135, 132, 139, 127, 136, 199, 202, 216, 212, 214, 220, 232, 233, 234, - 238, 241, 245, 248, 248, 244, 242, 242, 226, 236, 240, 229, 224, 228, 233, 229, - 221, 226, 216, 213, 205, 214, 206, 201, 186, 212, 199, 169, 107, 61, 28, 83, - 76, 92, 93, 88, 93, 87, 85, 81, 59, 65, 48, 40, 12, 100, 119, 106, - 115, 112, 122, 122, 112, 93, 95, 37, 115, 128, 110, 119, 119, 120, 127, 122, - 119, 104, 76, 81, 103, 131, 100, 104, 107, 96, 95, 116, 144, 190, 201, 206, - 208, 204, 210, 201, 205, 212, 214, 216, 222, 222, 224, 216, 210, 217, 209, 201, - 197, 204, 178, 116, 97, 51, 33, 106, 122, 107, 120, 120, 126, 126, 134, 110, - 110, 73, 67, 99, 132, 120, 116, 97, 99, 103, 97, 103, 107, 114, 83, 61, - 100, 96, 89, 80, 84, 85, 85, 79, 87, 100, 57, 8, 95, 84, 99, 80, - 84, 91, 96, 87, 87, 75, 65, 45, 81, 108, 87, 103, 89, 87, 85, 87, - 92, 87, 29, 1, 114, 103, 95, 99, 102, 100, 100, 108, 107, 104, 88, 57, - 1, 77, 96, 73, 102, 75, 63, 77, 72, 65, 36, 6, 56, 103, 89, 85, - 80, 83, 81, 71, 55, 49, 33, 72, 95, 67, 75, 89, 77, 68, 71, 71, - 57, 53, 42, 24, 75, 91, 83, 84, 85, 68, 59, 63, 60, 75, 28, 48, - 85, 79, 63, 87, 92, 95, 77, 81, 69, 36, 10, 59, 71, 59, 51, 41, - 40, 51, 37, 42, 53, 60, 20, 4, 69, 69, 63, 56, 59, 56, 56, 53, - 55, 53, 34, 12, 46, 72, 51, 87, 28, 51, 32, 46, 40, 36, 20, 4, - 53, 73, 69, 64, 52, 45, 52, 52, 53, 38, 20, 0, 48, 63, 36, 30, - 18, 22, 22, 26, 33, 14, 13, 1, 63, 56, 34, 13, 2, 173, 161, 158, - 158, 154, 154, 170, 140, 102, 69, 153, 159, 122, 131, 159, 179, 225, 236, 233, - 232, 233, 234, 229, 216, 185, 150, 118, 107, 103, 104, 104, 104, 104, 104, 103, - 106, 106, 107, 104, 107, 108, 111, 126, 136, 166, 197, 206, 214, 202, 162, 140, - 124, 93, 104, 115, 110, 118, 159, 178, 232, 234, 218, 229, 224, 232, 228, 232, - 230, 225, 225, 230, 234, 232, 229, 226, 221, 220, 228, 222, 221, 222, 222, 225, - 220, 216, 216, 208, 146, 127, 116, 99, 122, 107, 55, 139, 150, 143, 150, 158, - 139, 150, 151, 154, 155, 126, 56, 135, 153, 159, 161, 161, 157, 157, 151, 150, - 135, 127, 63, 100, 154, 158, 150, 146, 146, 154, 142, 140, 132, 100, 16, 120, - 151, 147, 153, 146, 148, 151, 153, 154, 128, 116, 53, 112, 134, 147, 135, 146, - 139, 136, 134, 136, 120, 110, 63, 131, 132, 135, 132, 128, 132, 135, 134, 118, - 89, 69, 112, 131, 127, 123, 134, 140, 134, 132, 128, 120, 81, 72, 124, 138, - 142, 142, 135, 122, 138, 131, 138, 115, 136, 126, 59, 79, 108, 155, 136, 114, - 110, 107, 116, 132, 119, 80, 44, 99, 114, 115, 106, 107, 104, 103, 127, 127, - 122, 100, 61, 80, 102, 102, 95, 92, 131, 108, 106, 108, 91, 67, 25, 110, - 123, 118, 128, 123, 126, 123, 115, 118, 104, 57, 1, 118, 146, 134, 134, 132, - 126, 189, 201, 208, 214, 217, 221, 220, 225, 230, 234, 234, 237, 241, 245, 244, - 246, 245, 244, 238, 230, 240, 233, 230, 232, 222, 222, 225, 229, 220, 220, 209, - 205, 202, 199, 195, 202, 159, 138, 73, 63, 28, 83, 81, 87, 99, 92, 88, - 81, 76, 79, 59, 60, 55, 46, 14, 75, 127, 108, 118, 108, 114, 119, 112, - 106, 88, 45, 112, 119, 126, 131, 132, 143, 139, 135, 128, 120, 104, 87, 114, - 136, 106, 104, 88, 87, 99, 93, 104, 112, 122, 122, 120, 112, 110, 107, 110, - 108, 108, 108, 114, 118, 118, 114, 114, 116, 111, 108, 108, 107, 106, 92, 87, - 49, 53, 103, 119, 106, 106, 126, 119, 120, 124, 108, 104, 76, 73, 93, 130, - 132, 112, 112, 132, 118, 120, 126, 92, 102, 102, 57, 89, 106, 95, 81, 85, - 80, 85, 91, 87, 91, 53, 9, 67, 93, 89, 80, 81, 80, 76, 85, 91, - 79, 63, 45, 72, 111, 77, 108, 110, 96, 100, 97, 96, 75, 38, 8, 111, - 112, 102, 106, 97, 102, 100, 112, 106, 106, 87, 44, 1, 84, 96, 80, 80, - 75, 76, 65, 79, 49, 30, 16, 56, 97, 93, 71, 84, 77, 69, 67, 57, - 56, 37, 75, 95, 81, 81, 84, 75, 67, 67, 84, 60, 41, 42, 16, 81, - 87, 79, 65, 76, 72, 57, 67, 56, 63, 25, 68, 81, 63, 81, 80, 77, - 73, 83, 84, 72, 32, 14, 36, 56, 68, 52, 52, 40, 55, 52, 38, 49, - 60, 20, 24, 65, 76, 65, 55, 55, 59, 55, 55, 55, 51, 36, 13, 48, - 72, 42, 59, 32, 44, 32, 49, 41, 30, 17, 1, 64, 75, 72, 71, 52, - 48, 60, 56, 55, 41, 18, 0, 30, 48, 29, 18, 13, 10, 12, 20, 26, - 16, 13, 1, 64, 77, 28, 2, 25, 189, 165, 163, 163, 162, 159, 158, 162, - 102, 87, 118, 118, 134, 162, 198, 229, 240, 233, 233, 225, 216, 195, 170, 126, - 110, 103, 104, 104, 106, 104, 106, 106, 112, 111, 103, 92, 88, 93, 97, 107, - 128, 108, 111, 114, 114, 122, 126, 127, 130, 127, 131, 102, 87, 104, 116, 100, - 111, 143, 162, 204, 212, 208, 174, 142, 128, 134, 138, 134, 131, 134, 140, 167, - 195, 204, 210, 216, 221, 220, 213, 201, 206, 213, 216, 212, 201, 159, 138, 123, - 119, 89, 89, 120, 99, 55, 97, 147, 148, 150, 150, 157, 157, 151, 151, 157, - 103, 68, 122, 153, 151, 153, 155, 151, 153, 153, 151, 128, 130, 56, 96, 139, - 158, 158, 159, 154, 155, 143, 140, 120, 92, 16, 116, 146, 148, 151, 144, 150, - 146, 147, 144, 142, 89, 42, 112, 134, 146, 128, 138, 142, 139, 134, 128, 128, - 103, 61, 95, 138, 132, 139, 130, 132, 132, 126, 116, 88, 61, 106, 144, 132, - 126, 134, 135, 136, 132, 134, 123, 83, 65, 130, 127, 138, 135, 135, 134, 139, - 138, 136, 114, 97, 115, 67, 72, 111, 134, 147, 123, 110, 103, 118, 126, 123, - 88, 38, 96, 118, 110, 112, 103, 103, 123, 147, 118, 114, 95, 41, 88, 106, - 88, 87, 93, 93, 102, 102, 99, 81, 68, 28, 80, 138, 130, 131, 123, 112, - 114, 124, 114, 108, 51, 8, 88, 143, 134, 132, 139, 124, 122, 161, 201, 208, - 204, 183, 139, 130, 126, 123, 128, 123, 111, 106, 110, 111, 114, 114, 112, 110, - 106, 107, 110, 110, 107, 102, 103, 111, 116, 112, 111, 104, 99, 104, 84, 79, - 77, 76, 65, 33, 22, 80, 88, 92, 87, 91, 85, 80, 80, 79, 55, 56, - 49, 40, 12, 92, 108, 111, 106, 112, 118, 103, 108, 99, 79, 48, 115, 123, - 139, 153, 181, 187, 195, 178, 177, 158, 135, 123, 111, 135, 97, 110, 95, 84, - 87, 89, 104, 95, 87, 92, 96, 97, 96, 95, 96, 95, 95, 95, 96, 96, - 97, 99, 99, 96, 97, 99, 96, 93, 97, 96, 36, 29, 48, 104, 114, 107, - 116, 112, 112, 116, 128, 107, 102, 88, 60, 72, 115, 126, 108, 95, 122, 130, - 127, 102, 99, 103, 89, 64, 75, 95, 97, 85, 87, 87, 85, 85, 87, 87, - 41, 6, 64, 100, 93, 77, 85, 81, 76, 83, 92, 72, 63, 29, 89, 106, - 88, 91, 108, 111, 93, 107, 96, 72, 30, 6, 69, 102, 92, 104, 108, 96, - 102, 104, 104, 106, 84, 42, 2, 79, 75, 93, 80, 64, 55, 69, 45, 44, - 37, 18, 57, 91, 91, 83, 89, 77, 72, 68, 68, 44, 24, 84, 91, 83, - 89, 88, 69, 68, 79, 65, 55, 45, 41, 21, 83, 79, 65, 79, 67, 60, - 63, 69, 55, 57, 21, 48, 89, 87, 91, 73, 48, 76, 77, 95, 73, 29, - 16, 29, 56, 68, 55, 51, 48, 55, 36, 37, 51, 49, 22, 21, 59, 75, - 69, 61, 65, 59, 60, 60, 57, 52, 40, 14, 25, 67, 49, 37, 33, 38, - 33, 45, 46, 33, 17, 1, 40, 73, 56, 64, 48, 57, 46, 48, 55, 28, - 18, 0, 57, 55, 18, 17, 12, 21, 10, 16, 28, 22, 9, 2, 64, 81, - 20, 6, 51, 177, 178, 169, 173, 161, 170, 157, 158, 104, 81, 120, 128, 170, - 218, 236, 236, 234, 237, 236, 191, 143, 114, 106, 106, 107, 110, 114, 102, 118, - 116, 108, 87, 67, 53, 56, 53, 61, 60, 63, 67, 85, 97, 126, 115, 116, - 119, 119, 120, 120, 128, 126, 83, 77, 89, 110, 106, 116, 124, 140, 134, 142, - 127, 127, 110, 103, 100, 107, 99, 103, 96, 104, 100, 103, 110, 111, 115, 115, - 115, 114, 111, 112, 116, 122, 124, 118, 119, 112, 110, 81, 85, 108, 112, 99, - 57, 85, 134, 154, 151, 159, 153, 155, 155, 151, 146, 108, 80, 100, 144, 148, - 151, 146, 148, 151, 151, 147, 127, 124, 44, 104, 126, 150, 153, 150, 147, 142, - 146, 132, 126, 97, 18, 118, 142, 151, 148, 151, 148, 148, 151, 140, 138, 114, - 44, 110, 130, 146, 143, 135, 138, 127, 130, 106, 103, 97, 75, 83, 84, 107, - 104, 100, 103, 107, 107, 116, 108, 64, 114, 140, 128, 123, 131, 132, 132, 132, - 131, 127, 93, 57, 127, 127, 127, 124, 120, 128, 126, 131, 128, 130, 128, 126, - 96, 73, 112, 128, 123, 103, 99, 102, 119, 120, 120, 89, 33, 106, 124, 115, - 110, 102, 99, 123, 136, 116, 110, 96, 45, 80, 99, 88, 87, 80, 83, 85, - 92, 84, 79, 55, 29, 76, 136, 112, 83, 103, 119, 120, 103, 108, 110, 48, - 8, 128, 135, 132, 128, 131, 128, 131, 131, 130, 128, 126, 118, 116, 112, 112, - 111, 111, 106, 100, 97, 99, 97, 99, 99, 97, 95, 93, 92, 92, 91, 92, - 84, 88, 88, 87, 87, 88, 83, 83, 84, 77, 72, 56, 56, 32, 24, 30, - 77, 75, 88, 83, 72, 57, 60, 51, 40, 55, 51, 56, 41, 6, 93, 128, - 114, 110, 110, 108, 111, 103, 96, 49, 75, 124, 138, 186, 202, 213, 212, 205, - 197, 201, 201, 197, 178, 151, 132, 103, 79, 80, 87, 72, 81, 72, 84, 83, - 81, 92, 103, 103, 102, 103, 102, 99, 100, 104, 106, 107, 107, 104, 104, 106, - 106, 103, 107, 83, 30, 38, 32, 14, 96, 104, 115, 100, 110, 97, 93, 89, - 111, 95, 84, 61, 77, 96, 106, 100, 119, 108, 107, 96, 91, 88, 89, 99, - 67, 67, 83, 108, 103, 99, 92, 99, 100, 87, 83, 63, 5, 72, 100, 100, - 92, 84, 91, 83, 87, 100, 60, 63, 33, 69, 108, 93, 102, 89, 72, 75, - 84, 85, 80, 30, 2, 71, 108, 95, 97, 97, 97, 103, 106, 99, 100, 95, - 38, 2, 76, 89, 67, 55, 56, 49, 45, 59, 45, 34, 18, 60, 91, 89, - 93, 75, 67, 76, 72, 72, 48, 28, 63, 85, 76, 81, 72, 69, 71, 68, - 68, 67, 44, 41, 24, 87, 79, 75, 61, 63, 60, 56, 64, 59, 32, 20, - 73, 76, 92, 73, 53, 65, 61, 80, 63, 73, 26, 20, 24, 55, 61, 59, - 64, 57, 49, 38, 38, 40, 45, 18, 4, 63, 72, 75, 59, 61, 61, 53, - 49, 53, 56, 32, 20, 21, 63, 55, 37, 42, 41, 33, 40, 37, 26, 17, - 1, 56, 71, 65, 53, 41, 46, 45, 53, 55, 40, 32, 1, 30, 45, 14, - 25, 14, 24, 14, 16, 29, 17, 9, 13, 55, 52, 26, 42, 95, 144, 140, - 143, 135, 124, 130, 128, 110, 83, 142, 132, 169, 226, 241, 238, 238, 236, 240, - 198, 131, 108, 110, 111, 116, 116, 111, 115, 120, 118, 92, 61, 48, 44, 45, - 48, 48, 56, 57, 61, 64, 69, 81, 103, 119, 154, 115, 120, 122, 124, 132, - 118, 79, 75, 76, 97, 103, 85, 127, 120, 119, 114, 106, 114, 111, 110, 110, - 108, 107, 108, 106, 104, 104, 104, 106, 104, 103, 104, 103, 104, 104, 103, 104, - 110, 108, 108, 111, 95, 72, 76, 75, 106, 108, 99, 61, 72, 128, 143, 154, - 139, 107, 122, 108, 104, 97, 96, 107, 84, 103, 123, 140, 136, 139, 139, 139, - 142, 122, 127, 41, 103, 120, 148, 150, 150, 146, 144, 128, 124, 122, 92, 24, - 123, 128, 131, 130, 127, 127, 127, 132, 135, 116, 112, 44, 104, 126, 138, 131, - 104, 120, 118, 107, 108, 115, 106, 103, 108, 120, 102, 123, 116, 118, 104, 119, - 116, 75, 64, 97, 115, 131, 115, 122, 126, 126, 119, 126, 122, 91, 57, 128, - 126, 126, 119, 123, 123, 123, 119, 119, 115, 122, 112, 114, 76, 87, 95, 97, - 99, 102, 107, 110, 120, 119, 92, 30, 110, 107, 116, 107, 100, 97, 95, 100, - 107, 107, 85, 64, 77, 92, 79, 72, 75, 76, 79, 77, 79, 77, 40, 30, - 59, 110, 118, 89, 104, 115, 114, 108, 115, 120, 45, 4, 122, 139, 132, 131, - 126, 124, 128, 123, 119, 108, 111, 106, 89, 99, 81, 87, 93, 83, 115, 114, - 111, 112, 111, 111, 111, 111, 108, 107, 104, 107, 104, 100, 96, 103, 99, 97, - 102, 97, 77, 48, 32, 28, 24, 24, 21, 14, 34, 29, 40, 42, 37, 34, - 34, 37, 36, 38, 36, 42, 40, 34, 6, 68, 115, 118, 116, 114, 122, 115, - 102, 95, 42, 85, 130, 174, 217, 216, 209, 218, 206, 208, 214, 210, 194, 190, - 166, 102, 88, 96, 87, 92, 89, 88, 77, 88, 96, 57, 65, 64, 102, 163, - 110, 116, 122, 119, 131, 126, 128, 132, 134, 134, 134, 131, 116, 92, 61, 26, - 45, 33, 20, 75, 99, 104, 106, 104, 107, 104, 108, 104, 100, 96, 93, 99, - 100, 79, 79, 84, 77, 76, 79, 89, 91, 79, 72, 80, 79, 77, 80, 76, - 76, 75, 61, 73, 71, 73, 40, 9, 67, 81, 84, 88, 87, 87, 84, 87, - 85, 72, 59, 30, 102, 112, 92, 89, 68, 87, 87, 77, 76, 79, 29, 4, - 99, 103, 93, 97, 91, 100, 92, 96, 92, 96, 79, 59, 2, 75, 87, 59, - 68, 48, 53, 46, 49, 44, 32, 8, 60, 84, 83, 80, 60, 64, 73, 73, - 55, 44, 25, 60, 72, 73, 68, 68, 71, 71, 71, 72, 67, 45, 51, 30, - 92, 79, 61, 60, 61, 59, 49, 60, 52, 28, 20, 64, 52, 65, 72, 68, - 64, 55, 59, 56, 53, 29, 24, 20, 40, 51, 52, 36, 42, 42, 49, 46, - 46, 45, 24, 2, 57, 63, 60, 55, 51, 48, 45, 45, 41, 40, 28, 26, - 25, 20, 21, 20, 29, 29, 22, 40, 34, 33, 17, 8, 51, 67, 61, 48, - 42, 41, 41, 44, 42, 34, 22, 1, 51, 48, 14, 20, 17, 24, 20, 20, - 13, 13, 8, 1, 42, 60, 45, 38, 30, 91, 80, 92, 91, 88, 83, 88, - 102, 134, 123, 150, 217, 241, 237, 238, 237, 241, 191, 136, 108, 116, 122, 120, - 112, 103, 120, 127, 122, 89, 49, 40, 42, 38, 42, 55, 73, 79, 80, 87, - 84, 80, 76, 89, 106, 147, 159, 120, 119, 119, 132, 119, 73, 68, 69, 92, - 104, 83, 116, 127, 124, 122, 120, 119, 118, 116, 115, 119, 116, 115, 116, 118, - 118, 111, 108, 108, 108, 108, 111, 107, 110, 107, 108, 107, 115, 104, 72, 69, - 68, 67, 56, 60, 100, 99, 93, 59, 71, 83, 95, 103, 76, 69, 67, 59, - 57, 51, 52, 56, 80, 80, 96, 107, 111, 115, 122, 122, 126, 111, 42, 92, - 112, 138, 143, 135, 130, 97, 61, 71, 60, 38, 26, 83, 87, 87, 89, 92, - 91, 91, 95, 99, 96, 69, 60, 81, 91, 92, 65, 60, 59, 60, 45, 30, - 46, 37, 29, 28, 21, 25, 22, 22, 30, 33, 33, 36, 37, 48, 36, 38, - 38, 38, 40, 65, 68, 48, 56, 63, 97, 55, 99, 114, 106, 100, 102, 102, - 100, 102, 103, 103, 106, 102, 99, 100, 106, 111, 111, 112, 115, 115, 116, 115, - 114, 92, 37, 100, 106, 99, 95, 89, 95, 89, 80, 97, 97, 69, 32, 68, - 60, 44, 32, 29, 28, 25, 28, 26, 20, 21, 32, 38, 36, 44, 37, 36, - 37, 37, 52, 52, 65, 49, 0, 18, 73, 81, 80, 79, 84, 91, 88, 91, - 87, 87, 49, 81, 111, 122, 134, 135, 130, 126, 127, 120, 127, 126, 127, 127, - 126, 123, 123, 120, 119, 116, 115, 115, 110, 114, 104, 84, 60, 28, 21, 21, - 18, 12, 13, 12, 10, 37, 37, 33, 40, 38, 36, 29, 33, 33, 32, 29, - 37, 30, 34, 10, 44, 99, 103, 96, 106, 108, 89, 72, 92, 36, 93, 144, - 205, 220, 217, 216, 220, 225, 202, 177, 146, 140, 123, 106, 91, 89, 68, 56, - 73, 76, 73, 72, 76, 69, 53, 68, 60, 102, 174, 150, 111, 110, 135, 132, - 134, 136, 139, 144, 142, 140, 136, 119, 83, 29, 25, 21, 52, 40, 46, 83, - 83, 73, 80, 84, 80, 79, 84, 83, 84, 81, 83, 87, 89, 88, 89, 88, - 88, 89, 85, 88, 88, 84, 76, 80, 80, 77, 67, 87, 75, 68, 56, 73, - 71, 38, 8, 30, 73, 76, 51, 59, 79, 77, 64, 65, 69, 53, 42, 87, - 124, 73, 64, 73, 73, 53, 55, 63, 52, 44, 8, 83, 110, 103, 104, 97, - 102, 91, 91, 97, 93, 60, 41, 4, 77, 84, 53, 56, 44, 40, 42, 41, - 38, 21, 17, 53, 26, 32, 33, 36, 33, 32, 32, 24, 22, 29, 30, 34, - 34, 33, 32, 38, 51, 60, 61, 61, 38, 38, 20, 88, 73, 57, 52, 55, - 38, 36, 36, 32, 30, 24, 44, 26, 37, 25, 28, 45, 41, 46, 41, 42, - 41, 28, 16, 33, 40, 42, 37, 33, 32, 33, 32, 30, 28, 22, 16, 28, - 29, 21, 21, 25, 25, 22, 24, 24, 22, 26, 25, 24, 26, 25, 26, 28, - 29, 28, 30, 28, 30, 16, 1, 45, 44, 41, 37, 38, 37, 36, 36, 34, - 21, 24, 0, 42, 36, 9, 9, 8, 8, 8, 6, 8, 10, 5, 1, 5, - 9, 8, 12, 2, 143, 140, 136, 132, 130, 126, 128, 144, 126, 139, 190, 240, - 241, 240, 238, 238, 190, 135, 111, 115, 126, 114, 106, 100, 124, 131, 126, 97, - 49, 37, 37, 37, 37, 59, 69, 68, 60, 60, 52, 59, 33, 38, 93, 110, - 134, 170, 143, 122, 120, 135, 123, 69, 64, 67, 88, 97, 77, 55, 56, 61, - 61, 57, 60, 73, 135, 171, 115, 116, 118, 119, 115, 104, 99, 99, 103, 107, - 116, 118, 119, 114, 112, 118, 116, 93, 60, 59, 57, 46, 49, 56, 49, 57, - 63, 61, 67, 55, 55, 55, 51, 87, 91, 96, 99, 106, 111, 108, 53, 122, - 127, 100, 92, 89, 91, 85, 80, 95, 111, 38, 84, 65, 55, 51, 46, 46, - 34, 33, 34, 28, 32, 17, 22, 21, 18, 18, 21, 22, 24, 22, 26, 29, - 30, 64, 29, 36, 64, 71, 77, 73, 81, 93, 128, 108, 116, 111, 132, 142, - 130, 142, 142, 136, 130, 127, 110, 63, 48, 102, 144, 147, 116, 112, 97, 83, - 75, 69, 26, 25, 20, 18, 18, 18, 18, 17, 18, 20, 21, 21, 24, 28, - 29, 32, 30, 34, 41, 46, 49, 57, 63, 95, 99, 112, 93, 41, 95, 87, - 69, 55, 52, 48, 44, 46, 46, 40, 38, 29, 25, 44, 72, 71, 79, 111, - 122, 120, 130, 119, 79, 25, 84, 130, 130, 99, 77, 79, 80, 67, 67, 26, - 18, 2, 9, 9, 34, 20, 17, 18, 36, 28, 29, 29, 42, 61, 91, 126, - 175, 174, 124, 131, 144, 138, 135, 138, 136, 136, 134, 132, 132, 131, 130, 128, - 126, 120, 119, 106, 112, 102, 55, 24, 21, 16, 16, 17, 20, 24, 26, 45, - 38, 44, 71, 80, 87, 92, 95, 88, 84, 69, 65, 32, 29, 20, 10, 36, - 36, 37, 52, 55, 91, 93, 85, 85, 28, 103, 157, 209, 234, 220, 222, 213, - 163, 136, 111, 110, 104, 96, 95, 91, 49, 64, 55, 61, 59, 51, 46, 51, - 49, 52, 71, 75, 102, 182, 178, 115, 103, 114, 128, 139, 142, 147, 148, 146, - 146, 139, 120, 75, 26, 26, 26, 32, 24, 10, 9, 12, 6, 5, 4, 6, - 2, 1, 1, 2, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 9, 20, 20, - 22, 22, 22, 28, 29, 37, 40, 46, 61, 26, 60, 79, 76, 59, 59, 69, - 67, 51, 53, 61, 26, 6, 13, 52, 56, 48, 42, 56, 60, 48, 44, 63, - 57, 12, 4, 30, 71, 71, 32, 21, 17, 14, 13, 20, 44, 32, 25, 37, - 30, 45, 44, 49, 53, 55, 53, 48, 22, 63, 67, 75, 69, 44, 20, 17, - 25, 17, 33, 36, 46, 29, 72, 45, 44, 48, 42, 56, 64, 59, 65, 51, - 20, 60, 67, 71, 67, 40, 34, 36, 20, 25, 25, 17, 22, 36, 34, 25, - 28, 25, 24, 21, 20, 21, 17, 10, 12, 13, 4, 2, 2, 1, 1, 1, - 1, 0, 0, 0, 2, 5, 1, 5, 2, 5, 9, 8, 14, 18, 22, 22, - 13, 2, 18, 14, 16, 13, 12, 12, 13, 12, 10, 10, 12, 0, 4, 4, - 4, 4, 2, 2, 1, 1, 1, 1, 1, 2, 2, 4, 1, 1, 1, 173, - 165, 163, 159, 158, 161, 154, 127, 138, 181, 232, 241, 241, 241, 240, 191, 127, - 114, 123, 128, 110, 102, 108, 126, 139, 132, 115, 55, 36, 33, 30, 33, 48, - 60, 52, 48, 45, 52, 68, 76, 93, 95, 97, 107, 128, 174, 159, 127, 122, - 136, 122, 71, 64, 65, 87, 100, 61, 65, 128, 143, 144, 138, 143, 144, 143, - 182, 154, 116, 110, 103, 97, 103, 114, 118, 127, 132, 135, 134, 139, 138, 131, - 116, 114, 60, 55, 52, 45, 44, 42, 46, 46, 45, 45, 55, 56, 81, 96, - 112, 124, 140, 143, 146, 153, 144, 143, 115, 69, 138, 144, 123, 112, 116, 122, - 110, 100, 99, 110, 37, 42, 46, 71, 71, 81, 120, 135, 146, 112, 88, 85, - 150, 153, 159, 144, 148, 138, 150, 142, 138, 140, 135, 69, 36, 96, 157, 151, - 159, 153, 131, 122, 134, 154, 126, 143, 128, 128, 107, 131, 147, 144, 128, 134, - 127, 143, 75, 45, 110, 157, 146, 144, 161, 159, 162, 165, 150, 139, 81, 41, - 120, 136, 135, 136, 135, 138, 144, 138, 136, 138, 135, 127, 127, 134, 134, 139, - 132, 130, 124, 87, 72, 73, 64, 93, 37, 53, 56, 87, 97, 96, 103, 118, - 110, 103, 93, 83, 51, 111, 142, 144, 143, 142, 144, 142, 138, 134, 122, 84, - 30, 102, 134, 135, 128, 130, 128, 128, 124, 95, 77, 69, 6, 75, 96, 97, - 91, 96, 104, 104, 103, 108, 108, 48, 57, 102, 123, 197, 182, 132, 122, 128, - 147, 146, 143, 147, 155, 157, 155, 155, 155, 147, 144, 122, 116, 106, 126, 111, - 93, 36, 24, 18, 17, 22, 25, 29, 40, 46, 51, 40, 61, 100, 103, 118, - 124, 127, 119, 116, 106, 100, 95, 81, 60, 8, 100, 108, 108, 106, 55, 55, - 52, 87, 83, 21, 116, 178, 216, 218, 225, 210, 148, 119, 110, 102, 92, 93, - 89, 95, 55, 38, 72, 69, 79, 83, 89, 79, 81, 79, 83, 88, 116, 103, - 191, 187, 153, 111, 110, 118, 139, 148, 144, 148, 151, 146, 135, 123, 71, 25, - 32, 32, 37, 22, 24, 65, 73, 72, 76, 71, 76, 67, 106, 92, 61, 64, - 115, 99, 118, 124, 123, 128, 126, 118, 131, 131, 127, 120, 99, 102, 119, 120, - 112, 111, 116, 112, 110, 83, 64, 37, 9, 68, 100, 91, 79, 76, 59, 45, - 44, 17, 26, 26, 29, 5, 4, 17, 4, 4, 1, 10, 0, 2, 1, 5, - 4, 1, 4, 1, 0, 0, 1, 1, 0, 0, 0, 2, 0, 6, 20, 17, - 22, 30, 46, 61, 38, 32, 53, 10, 30, 75, 87, 93, 89, 88, 92, 96, - 100, 67, 49, 24, 67, 79, 83, 92, 85, 77, 75, 69, 56, 56, 48, 63, - 48, 64, 72, 60, 67, 67, 79, 76, 79, 81, 51, 20, 72, 69, 52, 80, - 76, 72, 67, 57, 45, 38, 30, 21, 21, 8, 14, 33, 28, 45, 46, 48, - 34, 30, 25, 10, 13, 28, 79, 88, 69, 75, 80, 76, 68, 71, 48, 53, - 64, 71, 73, 84, 83, 76, 33, 10, 5, 4, 10, 4, 2, 9, 9, 5, - 6, 9, 8, 5, 5, 4, 2, 2, 9, 21, 25, 29, 20, 30, 45, 55, - 40, 25, 18, 4, 17, 69, 85, 71, 72, 83, 155, 158, 158, 161, 155, 154, - 132, 150, 179, 229, 237, 241, 241, 238, 183, 126, 116, 124, 132, 107, 104, 118, - 130, 146, 142, 131, 88, 40, 34, 32, 34, 48, 63, 60, 51, 60, 114, 115, - 112, 115, 115, 102, 107, 104, 112, 174, 181, 150, 120, 126, 115, 65, 61, 64, - 87, 93, 56, 110, 155, 166, 166, 159, 153, 146, 134, 194, 178, 134, 108, 97, - 110, 119, 132, 136, 139, 144, 146, 151, 148, 143, 134, 122, 102, 53, 51, 45, - 42, 46, 63, 68, 65, 71, 69, 75, 80, 136, 153, 158, 157, 154, 157, 150, - 138, 135, 120, 120, 51, 138, 136, 126, 122, 115, 126, 128, 126, 96, 118, 38, - 107, 147, 150, 157, 154, 159, 128, 158, 127, 159, 126, 116, 140, 143, 144, 148, - 139, 139, 140, 132, 148, 150, 83, 32, 126, 155, 158, 153, 154, 154, 148, 134, - 128, 146, 142, 95, 123, 144, 151, 151, 142, 148, 151, 139, 143, 77, 64, 130, - 159, 155, 134, 153, 150, 151, 143, 150, 159, 110, 42, 151, 161, 161, 115, 108, - 107, 108, 118, 119, 112, 139, 124, 87, 96, 114, 139, 120, 123, 123, 127, 136, - 123, 83, 100, 33, 76, 126, 138, 140, 138, 140, 135, 135, 134, 106, 85, 45, - 110, 142, 134, 131, 130, 128, 128, 128, 112, 126, 93, 30, 96, 132, 136, 131, - 124, 130, 131, 128, 123, 95, 69, 21, 122, 144, 142, 110, 106, 100, 123, 108, - 102, 107, 63, 56, 103, 120, 191, 202, 162, 119, 122, 143, 144, 158, 162, 171, - 175, 171, 174, 166, 159, 153, 118, 108, 126, 123, 112, 84, 29, 20, 17, 25, - 32, 34, 38, 49, 51, 59, 44, 83, 108, 124, 120, 116, 108, 112, 107, 114, - 115, 116, 96, 67, 8, 95, 106, 120, 114, 110, 103, 104, 89, 83, 21, 118, - 189, 218, 224, 217, 162, 123, 111, 97, 104, 87, 84, 100, 102, 45, 36, 63, - 52, 63, 60, 64, 67, 69, 59, 92, 126, 111, 115, 195, 193, 181, 112, 107, - 116, 139, 151, 151, 157, 155, 146, 136, 120, 56, 29, 21, 29, 37, 29, 44, - 93, 112, 99, 92, 89, 89, 89, 91, 91, 84, 87, 96, 120, 114, 115, 111, - 115, 96, 100, 122, 135, 107, 99, 103, 83, 99, 95, 99, 96, 96, 93, 93, - 96, 93, 42, 9, 67, 106, 99, 100, 83, 87, 80, 84, 61, 61, 46, 26, - 20, 104, 107, 83, 81, 83, 73, 68, 71, 60, 33, 9, 33, 106, 97, 76, - 80, 97, 96, 89, 75, 95, 80, 30, 5, 37, 73, 71, 34, 38, 42, 46, - 49, 37, 12, 57, 110, 103, 100, 87, 85, 73, 79, 65, 64, 53, 25, 73, - 87, 89, 80, 71, 68, 65, 63, 69, 77, 71, 61, 64, 75, 80, 81, 73, - 79, 88, 85, 75, 72, 52, 21, 71, 73, 71, 59, 61, 64, 68, 72, 71, - 60, 33, 36, 18, 55, 63, 55, 60, 48, 38, 16, 33, 37, 20, 13, 6, - 61, 79, 75, 67, 71, 67, 77, 61, 68, 60, 53, 52, 51, 67, 63, 56, - 59, 60, 57, 63, 55, 52, 42, 42, 71, 73, 84, 76, 87, 84, 76, 76, - 60, 67, 64, 68, 51, 53, 53, 64, 67, 38, 53, 40, 51, 32, 8, 56, - 87, 88, 63, 44, 29, 161, 161, 162, 155, 151, 138, 153, 151, 212, 233, 237, - 238, 238, 194, 130, 116, 127, 138, 115, 104, 131, 140, 148, 143, 139, 119, 61, - 34, 32, 36, 51, 64, 67, 52, 56, 115, 127, 128, 126, 123, 148, 148, 111, - 116, 116, 158, 186, 167, 124, 122, 108, 64, 59, 61, 87, 95, 67, 140, 170, - 158, 162, 150, 154, 155, 139, 198, 182, 167, 108, 97, 114, 126, 138, 144, 151, - 147, 151, 150, 153, 147, 128, 122, 73, 51, 45, 42, 64, 69, 76, 77, 76, - 87, 85, 73, 120, 165, 166, 159, 158, 143, 151, 135, 127, 136, 114, 119, 56, - 131, 143, 135, 120, 123, 123, 126, 132, 99, 119, 40, 114, 146, 143, 142, 162, - 130, 144, 153, 128, 142, 99, 132, 158, 155, 148, 148, 143, 146, 144, 147, 144, - 144, 75, 33, 139, 151, 151, 146, 153, 155, 144, 143, 144, 140, 127, 87, 118, - 148, 159, 148, 148, 150, 148, 138, 142, 75, 48, 123, 151, 158, 151, 147, 134, - 148, 135, 151, 140, 140, 49, 135, 130, 167, 155, 162, 161, 157, 158, 154, 148, - 131, 122, 81, 138, 150, 143, 148, 142, 142, 142, 130, 128, 107, 106, 38, 104, - 142, 138, 130, 126, 127, 119, 116, 127, 119, 87, 45, 106, 132, 136, 126, 132, - 127, 124, 127, 128, 119, 95, 37, 100, 112, 136, 122, 122, 126, 116, 132, 132, - 96, 76, 0, 120, 126, 135, 135, 142, 138, 127, 138, 110, 112, 68, 51, 104, - 126, 190, 214, 197, 132, 116, 132, 147, 155, 163, 177, 179, 178, 177, 179, 170, - 157, 119, 119, 135, 126, 114, 85, 26, 20, 20, 33, 44, 53, 52, 49, 56, - 55, 41, 95, 114, 122, 116, 104, 104, 103, 110, 102, 104, 110, 107, 67, 8, - 107, 110, 108, 104, 102, 104, 89, 61, 85, 29, 111, 193, 214, 226, 201, 124, - 108, 102, 106, 87, 85, 107, 107, 91, 46, 37, 40, 69, 65, 60, 57, 73, - 68, 55, 96, 124, 119, 114, 199, 205, 193, 111, 103, 115, 127, 142, 148, 153, - 159, 150, 135, 122, 61, 26, 18, 36, 49, 21, 56, 106, 92, 95, 95, 97, - 95, 102, 97, 80, 75, 79, 112, 131, 122, 111, 108, 100, 110, 104, 115, 118, - 116, 110, 77, 100, 115, 119, 119, 124, 120, 119, 106, 91, 57, 44, 12, 79, - 102, 99, 100, 99, 96, 79, 81, 77, 71, 49, 28, 73, 107, 95, 92, 92, - 89, 99, 93, 77, 80, 37, 6, 84, 104, 83, 76, 87, 91, 83, 84, 89, - 79, 75, 37, 6, 59, 64, 48, 32, 45, 28, 41, 53, 26, 12, 48, 110, - 91, 87, 68, 67, 65, 68, 69, 97, 52, 28, 65, 75, 65, 89, 97, 83, - 71, 77, 60, 67, 59, 37, 67, 83, 92, 91, 88, 102, 84, 89, 55, 81, - 55, 24, 68, 67, 71, 63, 49, 46, 51, 57, 52, 71, 42, 37, 5, 60, - 63, 63, 59, 34, 45, 33, 32, 34, 36, 13, 9, 77, 75, 46, 55, 49, - 56, 65, 71, 71, 61, 68, 29, 59, 52, 64, 56, 55, 55, 45, 41, 52, - 67, 22, 75, 84, 75, 75, 79, 69, 61, 69, 75, 72, 67, 30, 34, 60, - 84, 67, 68, 59, 45, 28, 56, 56, 40, 5, 64, 85, 64, 56, 28, 13, - 155, 153, 154, 163, 132, 147, 153, 175, 233, 233, 238, 240, 218, 150, 122, 123, - 136, 132, 106, 123, 147, 154, 150, 144, 135, 93, 41, 30, 30, 40, 52, 68, - 67, 30, 53, 122, 135, 150, 146, 140, 142, 140, 123, 115, 120, 138, 193, 182, - 132, 124, 100, 63, 57, 60, 87, 99, 83, 106, 167, 159, 159, 159, 157, 161, - 146, 204, 194, 179, 102, 99, 114, 134, 142, 153, 150, 159, 151, 148, 153, 140, - 127, 124, 53, 45, 42, 41, 69, 83, 81, 79, 87, 87, 81, 92, 148, 163, - 163, 158, 139, 146, 142, 139, 132, 131, 127, 114, 53, 128, 134, 139, 132, 131, - 126, 116, 116, 100, 115, 33, 124, 142, 161, 132, 139, 140, 132, 140, 143, 140, - 97, 127, 159, 154, 150, 151, 157, 151, 153, 144, 135, 135, 80, 40, 118, 155, - 144, 155, 142, 118, 146, 144, 140, 140, 130, 81, 126, 143, 158, 147, 158, 151, - 140, 143, 139, 75, 48, 122, 151, 148, 146, 143, 144, 134, 131, 140, 144, 151, - 55, 93, 157, 119, 147, 154, 142, 161, 154, 143, 151, 140, 107, 77, 140, 147, - 134, 127, 126, 122, 135, 139, 128, 124, 106, 45, 124, 138, 134, 136, 123, 112, - 114, 120, 127, 106, 83, 28, 111, 132, 127, 135, 127, 126, 130, 127, 127, 108, - 96, 49, 92, 119, 135, 131, 131, 116, 130, 124, 126, 92, 67, 0, 116, 131, - 132, 132, 138, 126, 146, 144, 143, 131, 72, 60, 106, 127, 190, 206, 197, 132, - 115, 128, 143, 147, 159, 177, 182, 183, 182, 174, 170, 151, 119, 132, 138, 130, - 122, 69, 25, 20, 24, 49, 55, 52, 49, 53, 61, 64, 48, 100, 122, 123, - 106, 111, 115, 112, 107, 106, 106, 107, 89, 68, 8, 106, 93, 114, 110, 108, - 103, 87, 64, 80, 24, 116, 187, 210, 222, 179, 118, 108, 99, 99, 87, 91, - 115, 107, 93, 45, 32, 33, 52, 64, 69, 59, 68, 68, 46, 91, 122, 108, - 120, 199, 198, 198, 110, 102, 110, 119, 134, 140, 155, 162, 154, 138, 115, 59, - 29, 18, 25, 51, 25, 57, 106, 108, 93, 91, 85, 85, 76, 85, 76, 68, - 24, 104, 127, 118, 106, 104, 103, 114, 118, 119, 104, 120, 107, 76, 106, 116, - 126, 118, 110, 102, 93, 102, 96, 97, 46, 12, 76, 83, 103, 89, 84, 72, - 80, 83, 88, 99, 52, 25, 91, 107, 79, 87, 75, 91, 95, 97, 87, 80, - 41, 6, 97, 103, 87, 79, 91, 102, 97, 96, 99, 87, 87, 38, 5, 64, - 55, 30, 33, 48, 26, 28, 40, 34, 9, 49, 93, 92, 67, 81, 83, 67, - 68, 71, 63, 65, 24, 59, 79, 69, 88, 72, 60, 67, 59, 71, 71, 63, - 41, 87, 75, 72, 67, 77, 85, 95, 77, 75, 69, 53, 25, 65, 65, 79, - 67, 55, 57, 53, 57, 60, 67, 60, 36, 28, 46, 71, 61, 41, 38, 57, - 32, 42, 26, 24, 13, 10, 38, 75, 71, 46, 49, 46, 45, 36, 46, 41, - 32, 26, 67, 59, 65, 48, 44, 41, 37, 40, 41, 65, 28, 76, 80, 76, - 59, 63, 52, 51, 57, 51, 48, 36, 33, 36, 61, 56, 51, 45, 36, 25, - 38, 38, 46, 44, 5, 28, 88, 57, 57, 14, 0, 171, 169, 165, 150, 135, - 150, 157, 208, 232, 241, 236, 229, 169, 128, 122, 134, 139, 122, 110, 144, 159, - 159, 151, 143, 124, 65, 33, 28, 34, 46, 65, 69, 67, 30, 108, 134, 134, - 146, 140, 144, 148, 143, 122, 118, 112, 132, 199, 193, 165, 123, 97, 61, 55, - 59, 81, 99, 73, 92, 169, 161, 158, 159, 157, 154, 142, 209, 199, 178, 102, - 103, 116, 128, 143, 151, 154, 154, 150, 151, 153, 138, 123, 123, 49, 41, 40, - 68, 79, 83, 87, 91, 87, 87, 80, 89, 154, 161, 162, 144, 143, 140, 146, - 139, 135, 127, 123, 123, 65, 139, 132, 124, 131, 126, 138, 111, 120, 97, 115, - 30, 122, 134, 142, 126, 143, 128, 148, 114, 140, 134, 89, 130, 158, 150, 153, - 153, 154, 157, 148, 147, 146, 134, 80, 33, 124, 148, 147, 155, 153, 150, 144, - 148, 135, 142, 127, 84, 123, 142, 143, 148, 158, 147, 135, 140, 132, 81, 46, - 127, 154, 157, 151, 143, 142, 140, 135, 135, 135, 151, 73, 60, 155, 162, 162, - 154, 154, 155, 148, 151, 159, 144, 119, 75, 136, 144, 138, 136, 143, 131, 127, - 126, 132, 114, 108, 44, 111, 140, 123, 126, 122, 116, 126, 116, 122, 110, 84, - 29, 104, 128, 127, 142, 124, 122, 120, 115, 111, 120, 97, 52, 95, 130, 134, - 138, 123, 126, 124, 128, 122, 96, 77, 10, 123, 124, 122, 139, 140, 128, 134, - 142, 146, 122, 65, 68, 107, 120, 163, 214, 202, 136, 111, 123, 143, 147, 159, - 173, 171, 174, 178, 179, 169, 132, 115, 134, 142, 131, 122, 51, 22, 20, 37, - 49, 56, 53, 55, 60, 73, 60, 55, 102, 123, 114, 112, 107, 108, 103, 108, - 111, 100, 104, 87, 63, 6, 88, 111, 107, 107, 104, 104, 77, 67, 85, 29, - 120, 199, 210, 216, 153, 118, 100, 107, 91, 81, 103, 108, 111, 93, 44, 32, - 34, 41, 65, 71, 72, 65, 75, 46, 88, 123, 118, 122, 199, 206, 202, 108, - 97, 106, 120, 126, 135, 154, 161, 155, 139, 110, 59, 32, 21, 29, 38, 29, - 52, 96, 99, 92, 87, 97, 87, 87, 88, 77, 65, 61, 122, 128, 122, 111, - 119, 112, 116, 116, 104, 103, 116, 99, 79, 108, 122, 119, 110, 103, 97, 97, - 103, 96, 95, 48, 13, 75, 99, 95, 81, 83, 84, 85, 79, 88, 73, 51, - 25, 55, 99, 76, 84, 87, 95, 87, 100, 91, 73, 44, 9, 55, 103, 79, - 88, 79, 88, 83, 81, 80, 76, 83, 36, 10, 60, 46, 38, 40, 51, 24, - 28, 30, 25, 10, 51, 97, 91, 76, 91, 99, 85, 68, 69, 71, 51, 28, - 56, 88, 69, 83, 71, 56, 64, 81, 68, 76, 65, 37, 87, 83, 80, 77, - 93, 89, 77, 51, 76, 71, 53, 26, 64, 61, 80, 87, 76, 71, 68, 72, - 61, 57, 41, 38, 28, 56, 72, 48, 46, 32, 48, 37, 55, 24, 20, 10, - 9, 40, 79, 73, 51, 42, 41, 42, 44, 42, 36, 34, 26, 64, 40, 59, - 57, 48, 44, 34, 36, 49, 42, 16, 57, 77, 69, 56, 48, 44, 45, 51, - 37, 56, 40, 22, 32, 65, 59, 63, 51, 46, 20, 42, 41, 42, 30, 6, - 29, 69, 57, 26, 1, 0, 171, 161, 163, 131, 146, 155, 179, 226, 234, 236, - 236, 193, 128, 124, 131, 139, 132, 108, 124, 155, 162, 157, 148, 138, 106, 42, - 29, 29, 38, 52, 57, 68, 71, 30, 124, 138, 138, 147, 146, 151, 150, 143, - 126, 124, 112, 120, 199, 197, 174, 123, 96, 61, 55, 57, 85, 96, 88, 81, - 165, 162, 159, 158, 155, 155, 136, 212, 201, 174, 106, 100, 114, 127, 139, 139, - 153, 148, 153, 153, 147, 131, 120, 123, 46, 38, 36, 69, 85, 77, 83, 97, - 95, 91, 85, 85, 154, 163, 158, 142, 136, 148, 131, 135, 143, 130, 120, 123, - 53, 134, 132, 136, 146, 142, 142, 118, 118, 95, 120, 40, 122, 138, 158, 143, - 138, 142, 123, 132, 139, 139, 92, 131, 154, 147, 154, 153, 157, 146, 140, 143, - 140, 136, 87, 34, 119, 147, 143, 155, 159, 154, 146, 144, 139, 139, 123, 76, - 124, 136, 135, 146, 153, 157, 154, 153, 131, 76, 48, 116, 154, 155, 154, 142, - 139, 140, 151, 130, 142, 148, 118, 61, 140, 158, 143, 142, 131, 150, 158, 159, - 138, 132, 108, 80, 139, 144, 124, 132, 131, 127, 126, 143, 134, 106, 108, 51, - 107, 123, 132, 123, 122, 114, 114, 128, 126, 107, 87, 40, 115, 131, 131, 147, - 131, 132, 118, 124, 135, 123, 110, 55, 97, 132, 123, 119, 123, 122, 114, 118, - 122, 97, 76, 10, 115, 126, 120, 128, 131, 130, 116, 130, 126, 103, 80, 67, - 95, 127, 155, 213, 213, 158, 107, 112, 140, 148, 162, 173, 178, 183, 178, 169, - 163, 123, 128, 143, 138, 132, 119, 32, 22, 17, 34, 53, 57, 55, 61, 68, - 68, 67, 56, 102, 120, 119, 114, 116, 104, 116, 108, 112, 100, 106, 97, 65, - 8, 97, 92, 102, 132, 103, 103, 100, 69, 80, 26, 114, 190, 214, 214, 142, - 106, 96, 97, 84, 89, 108, 108, 112, 106, 38, 29, 28, 37, 63, 72, 68, - 57, 73, 49, 93, 130, 112, 127, 204, 208, 201, 107, 100, 107, 111, 123, 138, - 151, 162, 158, 142, 123, 56, 30, 30, 26, 42, 33, 52, 95, 96, 91, 83, - 95, 68, 80, 102, 69, 69, 64, 123, 122, 108, 99, 108, 112, 120, 99, 95, - 103, 118, 91, 73, 104, 126, 111, 97, 103, 89, 95, 88, 103, 107, 49, 14, - 72, 93, 100, 79, 81, 84, 73, 80, 71, 76, 52, 25, 71, 95, 68, 81, - 84, 87, 100, 99, 81, 81, 45, 10, 53, 99, 79, 77, 77, 79, 75, 76, - 95, 79, 76, 40, 9, 72, 51, 34, 41, 49, 26, 24, 25, 20, 9, 65, - 100, 87, 95, 103, 104, 91, 76, 75, 69, 51, 29, 55, 93, 77, 81, 72, - 55, 56, 67, 57, 73, 68, 26, 91, 76, 80, 72, 83, 73, 57, 51, 80, - 65, 53, 29, 65, 63, 77, 57, 64, 67, 63, 65, 65, 53, 44, 37, 12, - 46, 72, 67, 30, 29, 46, 30, 44, 46, 36, 12, 9, 34, 77, 69, 41, - 48, 34, 38, 37, 40, 30, 30, 24, 59, 72, 46, 46, 44, 55, 42, 34, - 44, 52, 21, 59, 67, 61, 52, 33, 32, 42, 59, 45, 42, 25, 28, 42, - 60, 69, 40, 29, 34, 29, 40, 28, 49, 32, 9, 38, 60, 44, 30, 0, - 0, 183, 163, 148, 131, 150, 155, 206, 229, 236, 232, 222, 159, 124, 123, 136, - 142, 132, 112, 143, 161, 161, 155, 148, 135, 84, 34, 26, 30, 46, 55, 72, - 67, 71, 34, 130, 138, 146, 143, 148, 154, 148, 140, 127, 128, 116, 126, 199, - 199, 185, 120, 100, 64, 55, 57, 89, 99, 89, 67, 158, 165, 157, 166, 158, - 159, 147, 213, 194, 177, 108, 103, 114, 127, 135, 139, 147, 151, 153, 153, 136, - 128, 116, 119, 45, 36, 36, 72, 91, 95, 85, 84, 92, 93, 79, 103, 154, - 162, 147, 143, 139, 144, 144, 147, 136, 138, 115, 120, 56, 136, 136, 130, 131, - 136, 138, 111, 116, 95, 110, 38, 123, 142, 143, 127, 138, 131, 136, 132, 122, - 134, 89, 130, 153, 157, 154, 157, 147, 144, 146, 143, 138, 132, 83, 33, 116, - 142, 143, 139, 147, 148, 143, 142, 139, 135, 120, 67, 114, 139, 154, 148, 155, - 147, 143, 131, 143, 72, 51, 106, 153, 150, 150, 139, 144, 148, 140, 130, 140, - 144, 114, 48, 111, 157, 161, 132, 143, 157, 146, 139, 144, 131, 95, 85, 138, - 142, 124, 130, 139, 130, 130, 116, 130, 130, 107, 55, 112, 132, 128, 131, 130, - 112, 111, 111, 123, 116, 88, 44, 115, 136, 122, 126, 134, 120, 130, 131, 132, - 122, 106, 56, 99, 116, 130, 120, 120, 119, 126, 122, 115, 99, 79, 0, 127, - 127, 116, 99, 132, 127, 136, 134, 127, 110, 77, 59, 89, 130, 120, 214, 217, - 183, 110, 111, 135, 146, 158, 170, 174, 174, 173, 175, 153, 124, 134, 148, 139, - 131, 119, 29, 22, 20, 33, 59, 65, 63, 71, 83, 71, 63, 57, 91, 119, - 118, 120, 104, 114, 108, 107, 112, 97, 103, 100, 68, 9, 96, 99, 102, 103, - 130, 115, 106, 69, 79, 21, 103, 181, 208, 233, 153, 106, 91, 97, 83, 103, - 110, 110, 115, 91, 37, 32, 25, 38, 57, 71, 73, 60, 72, 45, 99, 120, - 116, 136, 210, 216, 199, 102, 95, 106, 118, 124, 140, 150, 163, 158, 142, 132, - 57, 36, 18, 30, 46, 36, 48, 95, 95, 92, 96, 87, 81, 87, 76, 85, - 57, 53, 110, 118, 116, 110, 114, 96, 92, 106, 100, 110, 112, 77, 84, 111, - 124, 106, 95, 97, 97, 89, 103, 96, 93, 51, 17, 77, 88, 92, 73, 88, - 75, 83, 79, 76, 65, 53, 24, 75, 104, 69, 76, 87, 89, 91, 92, 71, - 81, 46, 8, 57, 97, 83, 87, 83, 77, 83, 99, 71, 72, 73, 37, 9, - 59, 44, 36, 45, 46, 41, 22, 18, 14, 10, 57, 96, 77, 96, 93, 93, - 89, 99, 95, 72, 48, 28, 61, 84, 59, 85, 67, 56, 59, 67, 67, 76, - 64, 25, 83, 84, 92, 73, 76, 71, 59, 49, 48, 60, 52, 28, 46, 59, - 75, 71, 67, 67, 59, 67, 64, 67, 42, 37, 8, 45, 81, 63, 51, 26, - 42, 37, 41, 22, 28, 10, 9, 36, 76, 71, 53, 53, 40, 38, 37, 36, - 34, 46, 22, 49, 55, 30, 37, 37, 32, 40, 37, 38, 51, 29, 68, 77, - 75, 61, 26, 52, 48, 49, 38, 46, 34, 25, 46, 55, 36, 57, 33, 21, - 30, 29, 29, 24, 14, 8, 38, 55, 49, 21, 0, 0, 157, 170, 150, 142, - 151, 170, 221, 233, 229, 232, 182, 135, 124, 134, 139, 142, 122, 126, 158, 163, - 161, 154, 144, 127, 52, 30, 26, 33, 48, 68, 72, 72, 72, 33, 138, 136, - 144, 142, 151, 146, 144, 142, 131, 126, 111, 146, 199, 197, 191, 124, 97, 64, - 56, 57, 87, 95, 85, 64, 161, 158, 162, 162, 161, 157, 146, 217, 191, 189, - 110, 102, 112, 123, 132, 140, 144, 147, 153, 146, 135, 128, 114, 116, 42, 34, - 33, 71, 96, 91, 93, 91, 99, 92, 80, 107, 161, 162, 148, 143, 150, 154, - 142, 144, 147, 134, 116, 116, 56, 132, 131, 132, 135, 115, 118, 119, 111, 96, - 107, 36, 126, 148, 150, 139, 139, 144, 116, 140, 134, 135, 83, 139, 155, 155, - 148, 146, 150, 146, 147, 146, 140, 99, 95, 38, 112, 135, 146, 144, 140, 146, - 143, 139, 140, 136, 123, 60, 128, 135, 150, 150, 151, 148, 144, 150, 140, 71, - 51, 99, 139, 150, 148, 127, 146, 144, 127, 139, 139, 128, 120, 64, 108, 154, - 162, 158, 128, 144, 123, 139, 134, 124, 69, 100, 135, 140, 135, 131, 119, 115, - 120, 114, 116, 127, 110, 60, 89, 122, 132, 111, 100, 111, 120, 112, 114, 100, - 89, 22, 112, 127, 126, 122, 120, 112, 120, 128, 123, 118, 107, 63, 68, 112, - 128, 130, 132, 130, 130, 128, 114, 92, 71, 0, 119, 122, 115, 118, 111, 136, - 134, 131, 103, 134, 83, 73, 61, 127, 118, 220, 222, 216, 111, 111, 134, 151, - 154, 158, 175, 177, 174, 174, 142, 128, 150, 151, 139, 130, 119, 29, 22, 17, - 38, 64, 60, 68, 72, 81, 76, 72, 63, 83, 115, 116, 115, 114, 115, 115, - 112, 108, 106, 103, 99, 63, 10, 93, 89, 87, 102, 138, 106, 100, 69, 76, - 16, 84, 136, 189, 234, 159, 106, 100, 100, 102, 110, 106, 112, 106, 63, 36, - 30, 26, 38, 57, 72, 72, 68, 71, 36, 93, 116, 112, 131, 209, 208, 205, - 104, 96, 108, 120, 131, 140, 150, 161, 161, 151, 139, 59, 33, 17, 25, 42, - 33, 37, 89, 88, 96, 91, 89, 92, 84, 75, 80, 56, 16, 107, 120, 102, - 92, 99, 104, 106, 107, 108, 112, 114, 77, 88, 116, 107, 88, 111, 91, 88, - 91, 92, 96, 91, 55, 17, 69, 93, 97, 80, 75, 77, 79, 75, 85, 85, - 57, 21, 91, 97, 75, 79, 87, 85, 87, 88, 72, 69, 51, 5, 61, 89, - 84, 81, 80, 97, 96, 73, 69, 68, 79, 36, 8, 71, 48, 33, 30, 29, - 46, 18, 20, 16, 10, 51, 89, 87, 89, 88, 102, 84, 80, 76, 69, 56, - 26, 57, 87, 76, 79, 59, 56, 65, 68, 60, 80, 65, 28, 81, 76, 93, - 65, 65, 88, 59, 49, 56, 48, 53, 29, 37, 65, 55, 67, 88, 77, 63, - 63, 71, 63, 44, 37, 32, 46, 81, 49, 30, 38, 40, 25, 13, 14, 14, - 14, 10, 30, 49, 67, 49, 44, 48, 42, 40, 37, 36, 26, 20, 37, 36, - 34, 33, 36, 33, 44, 37, 41, 26, 25, 72, 75, 72, 68, 33, 53, 36, - 34, 56, 28, 36, 29, 51, 37, 26, 28, 18, 29, 13, 14, 9, 21, 12, - 9, 25, 55, 14, 14, 2, 0, 167, 155, 128, 146, 154, 185, 218, 233, 228, - 218, 148, 136, 132, 136, 142, 140, 114, 144, 166, 165, 161, 153, 143, 120, 44, - 29, 26, 37, 49, 55, 55, 73, 69, 30, 135, 135, 150, 146, 144, 143, 144, - 135, 128, 132, 107, 155, 198, 201, 185, 122, 95, 64, 56, 60, 88, 102, 96, - 76, 136, 171, 158, 158, 161, 155, 144, 221, 193, 198, 111, 103, 112, 123, 132, - 143, 148, 150, 150, 132, 131, 130, 118, 122, 40, 32, 32, 76, 93, 87, 92, - 87, 103, 93, 76, 114, 154, 158, 146, 115, 116, 132, 140, 126, 123, 127, 123, - 123, 65, 144, 136, 130, 120, 120, 118, 122, 110, 93, 104, 29, 124, 135, 148, - 127, 142, 143, 135, 143, 143, 130, 73, 128, 155, 161, 158, 158, 150, 142, 132, - 140, 112, 100, 91, 41, 99, 124, 128, 107, 120, 138, 132, 112, 122, 130, 116, - 61, 119, 128, 150, 153, 132, 124, 122, 118, 102, 85, 44, 95, 146, 151, 148, - 146, 134, 131, 128, 136, 127, 134, 131, 71, 91, 151, 159, 146, 122, 151, 144, - 134, 127, 118, 69, 83, 132, 139, 132, 126, 115, 118, 112, 114, 112, 120, 110, - 59, 81, 100, 100, 100, 103, 100, 106, 104, 114, 114, 87, 25, 111, 128, 128, - 122, 123, 120, 115, 118, 111, 110, 107, 68, 81, 106, 128, 130, 138, 128, 120, - 127, 91, 96, 83, 8, 116, 120, 112, 119, 100, 122, 127, 130, 119, 124, 69, - 69, 52, 124, 123, 222, 228, 220, 112, 108, 134, 148, 153, 157, 169, 174, 171, - 162, 130, 142, 148, 150, 142, 136, 122, 26, 21, 18, 38, 63, 65, 67, 71, - 79, 79, 75, 64, 72, 110, 118, 120, 108, 112, 114, 107, 107, 103, 96, 83, - 61, 10, 84, 92, 103, 100, 100, 95, 84, 79, 80, 17, 65, 111, 155, 150, - 112, 99, 89, 76, 93, 92, 97, 92, 60, 37, 33, 29, 28, 36, 60, 69, - 72, 67, 71, 37, 97, 115, 104, 103, 202, 217, 213, 104, 95, 108, 122, 131, - 142, 150, 165, 159, 139, 130, 56, 34, 18, 24, 42, 37, 33, 68, 91, 88, - 92, 88, 89, 87, 79, 83, 55, 38, 119, 115, 95, 103, 115, 116, 114, 116, - 112, 116, 108, 73, 95, 123, 102, 103, 103, 92, 93, 102, 95, 96, 87, 55, - 17, 76, 91, 95, 77, 72, 72, 71, 83, 87, 77, 56, 25, 61, 92, 72, - 65, 69, 72, 72, 68, 73, 77, 55, 13, 61, 59, 100, 95, 97, 99, 100, - 65, 75, 72, 75, 44, 14, 60, 37, 32, 25, 36, 30, 40, 21, 20, 10, - 46, 88, 84, 85, 100, 76, 79, 75, 65, 71, 51, 30, 59, 85, 65, 61, - 64, 85, 67, 83, 73, 67, 60, 32, 73, 76, 73, 75, 77, 71, 68, 64, - 52, 63, 57, 36, 34, 51, 63, 56, 44, 40, 40, 52, 46, 44, 42, 37, - 33, 65, 81, 51, 24, 6, 8, 20, 18, 8, 9, 17, 16, 21, 36, 42, - 41, 34, 33, 32, 30, 32, 34, 33, 29, 37, 36, 49, 37, 40, 30, 32, - 34, 34, 29, 33, 45, 67, 79, 53, 34, 30, 29, 32, 26, 22, 22, 26, - 29, 26, 26, 29, 25, 17, 38, 34, 38, 33, 20, 28, 30, 38, 38, 30, - 18, 12, 157, 158, 116, 142, 157, 189, 222, 228, 229, 169, 140, 132, 135, 140, - 146, 138, 119, 158, 169, 166, 159, 151, 139, 107, 38, 28, 25, 36, 48, 69, - 73, 76, 73, 36, 138, 142, 143, 148, 143, 138, 134, 136, 130, 124, 115, 165, - 195, 198, 182, 123, 91, 64, 57, 63, 89, 102, 97, 72, 127, 169, 163, 144, - 161, 153, 140, 221, 199, 210, 111, 104, 112, 127, 140, 139, 143, 142, 134, 123, - 130, 128, 119, 122, 36, 30, 29, 79, 87, 83, 87, 87, 76, 110, 103, 111, - 122, 130, 122, 122, 126, 122, 120, 127, 140, 134, 122, 116, 57, 135, 134, 115, - 110, 114, 116, 111, 103, 104, 114, 45, 126, 142, 143, 132, 127, 124, 112, 130, - 126, 123, 83, 111, 135, 148, 118, 122, 114, 114, 110, 95, 79, 67, 96, 84, - 93, 93, 95, 97, 85, 87, 88, 88, 89, 81, 73, 55, 93, 93, 97, 91, - 77, 79, 84, 85, 73, 72, 88, 87, 126, 138, 132, 112, 128, 132, 136, 120, - 118, 136, 128, 118, 84, 96, 148, 139, 110, 130, 131, 131, 128, 107, 72, 76, - 119, 124, 108, 108, 111, 122, 123, 110, 107, 108, 104, 102, 92, 107, 108, 108, - 95, 104, 88, 107, 100, 110, 91, 38, 119, 112, 112, 112, 112, 111, 110, 112, - 107, 108, 89, 104, 61, 72, 76, 83, 79, 83, 83, 84, 83, 93, 77, 5, - 51, 124, 119, 68, 91, 110, 115, 107, 99, 112, 104, 83, 59, 81, 103, 213, - 229, 220, 107, 104, 128, 143, 148, 147, 154, 167, 169, 161, 135, 153, 155, 154, - 144, 136, 122, 25, 20, 20, 34, 59, 65, 71, 73, 71, 75, 80, 79, 63, - 73, 95, 103, 102, 100, 99, 102, 103, 103, 97, 96, 61, 12, 80, 93, 96, - 85, 88, 76, 77, 77, 77, 32, 49, 68, 87, 108, 79, 48, 41, 30, 29, - 32, 30, 30, 29, 33, 30, 25, 25, 32, 63, 65, 65, 55, 71, 40, 91, - 103, 119, 102, 189, 214, 212, 102, 96, 112, 124, 136, 140, 153, 165, 159, 140, - 128, 51, 36, 37, 22, 44, 42, 34, 42, 64, 72, 71, 79, 76, 85, 76, - 75, 65, 52, 118, 107, 111, 110, 103, 103, 97, 100, 106, 102, 85, 72, 83, - 103, 112, 107, 103, 107, 102, 96, 75, 67, 69, 53, 20, 64, 75, 85, 95, - 102, 85, 92, 83, 72, 53, 59, 24, 64, 84, 89, 80, 79, 77, 75, 65, - 71, 65, 56, 12, 51, 41, 44, 55, 64, 67, 49, 53, 65, 42, 49, 41, - 14, 60, 37, 42, 40, 40, 30, 28, 28, 20, 16, 45, 48, 45, 48, 38, - 57, 68, 71, 71, 61, 46, 36, 36, 67, 59, 68, 55, 61, 60, 65, 59, - 53, 61, 17, 60, 72, 69, 53, 59, 61, 61, 53, 53, 56, 52, 44, 49, - 51, 48, 44, 44, 44, 42, 48, 42, 40, 38, 37, 6, 60, 5, 28, 4, - 25, 6, 9, 24, 22, 9, 13, 18, 20, 20, 20, 21, 21, 21, 22, 24, - 24, 22, 28, 21, 26, 29, 26, 32, 28, 24, 24, 26, 28, 28, 25, 37, - 49, 32, 46, 28, 29, 65, 71, 65, 34, 55, 52, 26, 25, 21, 22, 26, - 24, 25, 20, 17, 14, 16, 20, 41, 18, 17, 56, 60, 71, 104, 106, 111, - 146, 150, 201, 230, 179, 171, 151, 124, 148, 143, 140, 143, 132, 131, 165, 169, - 165, 158, 150, 134, 93, 33, 26, 26, 40, 52, 71, 76, 72, 72, 21, 134, - 136, 136, 136, 108, 119, 126, 118, 132, 130, 116, 175, 202, 195, 182, 119, 89, - 65, 59, 63, 92, 97, 108, 97, 95, 132, 161, 148, 147, 144, 140, 221, 210, - 214, 112, 104, 110, 126, 126, 126, 127, 126, 131, 134, 132, 131, 124, 123, 34, - 29, 30, 69, 76, 81, 89, 91, 87, 96, 91, 97, 110, 110, 99, 106, 107, - 110, 112, 112, 115, 120, 118, 118, 112, 119, 115, 112, 111, 108, 106, 104, 97, - 106, 93, 51, 119, 147, 120, 112, 106, 107, 110, 104, 102, 103, 87, 102, 103, - 99, 99, 93, 89, 84, 85, 81, 77, 65, 53, 32, 33, 30, 30, 29, 26, - 25, 25, 22, 25, 21, 21, 22, 22, 29, 34, 33, 29, 32, 42, 61, 56, - 60, 57, 76, 107, 102, 122, 130, 118, 108, 122, 124, 123, 120, 120, 106, 95, - 107, 96, 91, 77, 64, 63, 63, 73, 63, 51, 69, 73, 81, 80, 79, 107, - 110, 108, 88, 85, 69, 64, 75, 83, 95, 97, 96, 79, 69, 72, 92, 100, - 99, 88, 37, 69, 77, 68, 79, 79, 80, 80, 84, 84, 87, 89, 89, 87, - 93, 67, 67, 57, 40, 29, 26, 36, 42, 33, 0, 26, 26, 38, 34, 40, - 44, 52, 55, 65, 77, 104, 88, 79, 73, 114, 212, 230, 220, 106, 103, 110, - 119, 135, 146, 157, 154, 159, 154, 138, 155, 155, 153, 143, 131, 119, 24, 20, - 18, 26, 36, 52, 51, 60, 65, 68, 71, 67, 67, 83, 85, 88, 85, 88, - 87, 89, 88, 93, 93, 87, 63, 16, 88, 92, 72, 63, 63, 57, 48, 68, - 64, 36, 32, 33, 53, 41, 37, 32, 34, 28, 29, 37, 36, 28, 28, 28, - 29, 38, 40, 40, 41, 44, 44, 45, 71, 36, 53, 56, 68, 104, 178, 217, - 208, 104, 100, 111, 120, 134, 144, 153, 167, 158, 139, 126, 52, 40, 16, 30, - 32, 36, 34, 41, 40, 41, 38, 40, 41, 44, 41, 40, 51, 34, 48, 91, - 91, 79, 77, 87, 89, 80, 77, 80, 77, 73, 77, 76, 77, 79, 85, 73, - 75, 64, 57, 46, 56, 51, 52, 56, 53, 32, 59, 59, 46, 63, 46, 41, - 60, 52, 52, 55, 56, 53, 51, 51, 45, 46, 41, 55, 38, 34, 6, 16, - 14, 24, 24, 21, 22, 29, 26, 28, 36, 51, 33, 22, 33, 32, 24, 26, - 29, 29, 28, 48, 33, 37, 29, 34, 40, 37, 33, 33, 41, 48, 45, 42, - 42, 45, 42, 44, 45, 46, 44, 44, 42, 44, 44, 42, 37, 18, 29, 45, - 32, 33, 33, 45, 32, 33, 34, 40, 38, 32, 30, 37, 34, 33, 32, 30, - 30, 30, 30, 29, 28, 26, 2, 37, 34, 34, 32, 46, 42, 41, 42, 46, - 48, 51, 51, 59, 64, 68, 72, 83, 107, 128, 150, 163, 171, 228, 226, 222, - 209, 202, 205, 199, 204, 191, 187, 178, 162, 80, 36, 32, 29, 29, 22, 73, - 65, 155, 185, 165, 161, 159, 100, 83, 83, 61, 51, 48, 57, 87, 111, 144, - 162, 154, 116, 76, 45, 16, 9, 9, 142, 139, 140, 161, 159, 205, 140, 147, - 130, 124, 127, 135, 132, 143, 148, 140, 139, 169, 170, 162, 154, 140, 128, 55, - 29, 25, 30, 45, 56, 40, 67, 67, 55, 29, 77, 95, 88, 91, 91, 93, - 93, 99, 140, 119, 91, 166, 193, 198, 182, 118, 83, 63, 59, 68, 91, 91, - 95, 96, 102, 108, 106, 112, 114, 150, 118, 225, 218, 218, 111, 102, 108, 123, - 116, 116, 115, 116, 119, 131, 131, 134, 124, 120, 29, 24, 25, 42, 38, 42, - 45, 48, 38, 40, 46, 53, 60, 77, 73, 80, 84, 85, 83, 89, 93, 97, - 102, 96, 87, 100, 106, 99, 104, 110, 116, 146, 132, 92, 99, 110, 108, 95, - 92, 87, 80, 79, 72, 72, 63, 56, 56, 57, 49, 64, 59, 57, 56, 63, - 56, 61, 56, 89, 112, 146, 150, 144, 155, 147, 153, 146, 158, 157, 136, 110, - 111, 107, 116, 136, 136, 120, 110, 93, 73, 60, 51, 42, 29, 29, 25, 25, - 21, 21, 22, 24, 20, 24, 26, 26, 25, 24, 29, 37, 107, 114, 120, 126, - 132, 128, 96, 106, 57, 134, 130, 143, 116, 68, 64, 84, 60, 63, 111, 118, - 124, 114, 115, 123, 128, 123, 112, 103, 92, 84, 60, 59, 84, 40, 22, 21, - 21, 22, 16, 16, 17, 20, 13, 14, 16, 16, 16, 18, 52, 60, 91, 107, - 103, 106, 97, 65, 61, 0, 84, 124, 114, 80, 115, 81, 92, 89, 68, 57, - 55, 63, 60, 63, 106, 201, 216, 208, 95, 92, 103, 104, 99, 112, 130, 147, - 154, 159, 132, 148, 158, 154, 140, 134, 118, 20, 17, 17, 14, 14, 14, 16, - 16, 14, 17, 28, 25, 17, 21, 42, 59, 41, 44, 25, 30, 28, 49, 33, - 71, 24, 16, 92, 48, 38, 37, 37, 33, 40, 32, 26, 29, 26, 28, 29, - 28, 34, 30, 24, 24, 26, 25, 26, 28, 26, 28, 26, 28, 30, 32, 36, - 46, 53, 56, 73, 34, 83, 104, 104, 103, 177, 202, 193, 107, 100, 112, 124, - 132, 142, 155, 166, 159, 136, 111, 46, 42, 14, 24, 17, 22, 6, 6, 6, - 4, 5, 5, 4, 4, 2, 2, 2, 2, 4, 5, 5, 5, 8, 9, 9, - 10, 13, 14, 16, 16, 21, 21, 26, 28, 29, 33, 36, 36, 45, 68, 73, - 64, 57, 63, 49, 49, 52, 48, 44, 48, 49, 55, 71, 76, 85, 77, 72, - 69, 67, 71, 76, 68, 63, 49, 52, 56, 26, 38, 88, 96, 69, 60, 65, - 40, 29, 22, 24, 20, 24, 18, 25, 37, 36, 29, 34, 34, 30, 25, 33, - 38, 42, 55, 46, 48, 42, 45, 40, 36, 28, 24, 21, 22, 18, 20, 18, - 18, 17, 20, 18, 20, 17, 21, 21, 51, 20, 16, 14, 14, 12, 10, 10, - 9, 8, 6, 5, 4, 5, 4, 1, 1, 0, 18, 1, 0, 0, 1, 1, - 8, 44, 40, 56, 60, 85, 108, 146, 150, 165, 174, 165, 151, 140, 132, 120, - 122, 131, 118, 108, 118, 124, 139, 155, 165, 177, 186, 185, 182, 178, 179, 175, - 174, 169, 159, 147, 150, 139, 28, 22, 18, 72, 40, 132, 189, 194, 197, 194, - 191, 198, 190, 187, 195, 201, 190, 197, 197, 204, 201, 189, 197, 195, 138, 59, - 51, 13, 10, 173, 173, 178, 170, 199, 169, 173, 163, 140, 151, 103, 103, 108, - 111, 111, 132, 140, 167, 167, 163, 150, 139, 124, 52, 29, 26, 41, 46, 63, - 64, 73, 60, 67, 67, 71, 87, 96, 99, 112, 119, 130, 120, 110, 135, 103, - 161, 193, 197, 147, 120, 83, 64, 59, 81, 87, 85, 76, 81, 93, 99, 99, - 110, 130, 147, 147, 221, 218, 218, 110, 100, 108, 115, 112, 122, 128, 131, 132, - 130, 132, 140, 126, 126, 33, 26, 26, 41, 55, 75, 77, 84, 99, 175, 185, - 193, 198, 198, 193, 201, 208, 210, 205, 202, 195, 191, 197, 197, 194, 189, 190, - 185, 182, 178, 183, 178, 183, 142, 120, 80, 88, 91, 119, 157, 178, 194, 191, - 182, 177, 169, 167, 174, 167, 161, 142, 134, 140, 143, 136, 148, 161, 130, 163, - 178, 190, 195, 199, 198, 193, 193, 189, 169, 148, 130, 150, 147, 140, 151, 150, - 155, 146, 154, 140, 139, 124, 97, 75, 45, 112, 135, 128, 124, 124, 130, 128, - 135, 130, 130, 122, 120, 122, 120, 116, 135, 134, 134, 140, 132, 115, 115, 53, - 138, 151, 122, 119, 150, 148, 144, 132, 116, 140, 163, 174, 179, 171, 175, 175, - 171, 165, 154, 131, 118, 112, 92, 85, 38, 52, 131, 140, 116, 119, 110, 132, - 118, 122, 115, 110, 103, 112, 128, 120, 112, 110, 122, 106, 108, 122, 93, 65, - 2, 110, 128, 136, 142, 104, 138, 135, 115, 119, 96, 80, 77, 99, 104, 108, - 220, 229, 222, 107, 103, 114, 111, 111, 111, 114, 114, 119, 118, 139, 157, 159, - 151, 139, 130, 111, 22, 20, 18, 37, 48, 48, 53, 51, 52, 51, 59, 51, - 30, 56, 107, 104, 89, 93, 95, 61, 38, 36, 40, 42, 46, 33, 61, 80, - 88, 88, 95, 103, 100, 87, 79, 87, 102, 110, 97, 89, 81, 83, 73, 75, - 44, 44, 40, 34, 37, 45, 55, 53, 53, 59, 73, 77, 72, 76, 77, 32, - 103, 103, 111, 108, 187, 213, 179, 106, 102, 111, 126, 134, 146, 154, 169, 161, - 159, 130, 55, 44, 12, 12, 21, 22, 41, 83, 87, 91, 92, 92, 99, 97, - 96, 93, 57, 36, 84, 106, 118, 111, 108, 111, 119, 115, 108, 104, 108, 104, - 116, 134, 123, 122, 119, 103, 95, 99, 110, 169, 179, 190, 175, 154, 115, 81, - 72, 71, 77, 87, 124, 143, 162, 146, 150, 144, 136, 144, 123, 120, 115, 110, - 77, 57, 55, 44, 20, 85, 102, 124, 127, 102, 106, 79, 72, 76, 80, 67, - 64, 85, 134, 144, 154, 155, 155, 157, 157, 150, 157, 165, 181, 187, 185, 170, - 155, 110, 91, 51, 49, 44, 44, 32, 12, 32, 77, 92, 68, 77, 75, 69, - 64, 52, 41, 18, 34, 83, 95, 84, 84, 97, 96, 81, 110, 110, 110, 80, - 85, 120, 128, 157, 157, 153, 158, 147, 140, 132, 84, 48, 45, 67, 120, 158, - 170, 183, 194, 193, 193, 198, 201, 190, 179, 189, 175, 161, 159, 161, 148, 142, - 143, 143, 138, 140, 135, 148, 147, 153, 179, 179, 162, 150, 159, 146, 139, 134, - 150, 136, 114, 119, 102, 53, 167, 212, 202, 220, 179, 218, 174, 214, 204, 224, - 206, 212, 195, 205, 202, 201, 195, 202, 198, 147, 67, 68, 63, 64, 182, 189, - 171, 183, 210, 197, 238, 198, 135, 104, 108, 124, 128, 136, 123, 132, 148, 170, - 167, 153, 144, 139, 126, 49, 29, 26, 67, 65, 83, 97, 106, 110, 108, 132, - 147, 154, 157, 162, 162, 165, 163, 166, 144, 135, 91, 127, 169, 195, 136, 108, - 72, 68, 67, 84, 107, 107, 103, 96, 91, 134, 155, 155, 157, 153, 142, 226, - 221, 220, 108, 100, 110, 116, 131, 136, 135, 136, 135, 134, 130, 138, 124, 124, - 33, 25, 26, 57, 80, 95, 151, 110, 170, 191, 201, 210, 208, 210, 212, 220, - 222, 222, 222, 230, 232, 232, 233, 234, 234, 230, 236, 225, 233, 237, 237, 229, - 225, 225, 220, 224, 224, 216, 216, 218, 216, 221, 216, 214, 205, 204, 201, 204, - 199, 195, 187, 174, 174, 134, 132, 157, 174, 181, 193, 202, 210, 212, 209, 213, - 210, 210, 208, 204, 199, 186, 151, 139, 130, 122, 139, 139, 143, 148, 148, 148, - 146, 118, 92, 46, 142, 134, 147, 140, 143, 142, 130, 128, 130, 136, 135, 115, - 93, 140, 151, 157, 153, 147, 138, 130, 136, 112, 56, 147, 148, 146, 124, 154, - 120, 131, 147, 159, 193, 213, 222, 221, 220, 218, 214, 210, 206, 195, 193, 181, - 171, 116, 85, 46, 131, 139, 123, 120, 130, 134, 138, 118, 115, 130, 132, 123, - 99, 126, 126, 126, 126, 123, 123, 123, 116, 110, 76, 0, 99, 124, 132, 127, - 100, 104, 124, 123, 102, 112, 116, 65, 102, 126, 110, 228, 236, 222, 106, 97, - 108, 124, 131, 136, 140, 139, 138, 138, 143, 159, 155, 147, 139, 131, 118, 20, - 20, 20, 46, 48, 60, 76, 71, 72, 64, 61, 55, 40, 91, 118, 124, 122, - 124, 118, 108, 99, 111, 104, 88, 93, 103, 110, 100, 104, 100, 107, 116, 118, - 96, 106, 102, 123, 140, 135, 128, 143, 142, 140, 100, 88, 84, 75, 72, 65, - 72, 67, 57, 45, 61, 65, 59, 57, 59, 77, 40, 102, 111, 111, 108, 210, - 217, 187, 102, 99, 108, 124, 135, 143, 155, 167, 161, 143, 135, 55, 56, 61, - 64, 65, 92, 88, 99, 102, 103, 102, 107, 89, 93, 93, 92, 95, 42, 112, - 108, 111, 122, 116, 143, 159, 171, 174, 179, 179, 181, 189, 194, 191, 186, 187, - 185, 185, 183, 186, 193, 194, 195, 193, 186, 177, 177, 153, 146, 159, 146, 158, - 181, 186, 199, 195, 190, 189, 187, 174, 175, 182, 177, 155, 80, 51, 55, 26, - 97, 118, 106, 123, 128, 110, 124, 120, 97, 118, 130, 165, 165, 182, 186, 193, - 186, 189, 187, 190, 194, 194, 199, 206, 206, 208, 205, 205, 198, 179, 159, 110, - 69, 59, 30, 9, 84, 93, 80, 89, 95, 80, 89, 79, 67, 33, 21, 93, - 170, 181, 185, 178, 182, 189, 198, 206, 202, 197, 199, 195, 197, 194, 195, 179, - 193, 193, 185, 148, 171, 140, 65, 46, 96, 153, 178, 186, 194, 195, 201, 205, - 204, 205, 202, 179, 204, 198, 161, 110, 104, 151, 170, 167, 165, 150, 157, 153, - 142, 122, 120, 106, 116, 112, 107, 146, 150, 97, 150, 158, 118, 112, 110, 59, - 41, 93, 157, 187, 144, 126, 97, 102, 110, 110, 138, 179, 185, 185, 193, 173, - 178, 189, 193, 112, 79, 67, 88, 103, 115, 163, 162, 173, 189, 187, 204, 242, - 216, 138, 104, 122, 131, 139, 151, 158, 162, 166, 163, 154, 153, 143, 139, 126, - 46, 28, 29, 63, 80, 91, 124, 115, 134, 142, 131, 136, 140, 159, 163, 157, - 166, 161, 159, 155, 140, 130, 116, 124, 181, 127, 96, 77, 69, 65, 99, 104, - 99, 95, 75, 124, 162, 159, 157, 153, 153, 148, 233, 224, 218, 103, 99, 115, - 122, 136, 132, 138, 140, 138, 132, 130, 135, 124, 123, 33, 25, 26, 57, 77, - 144, 95, 104, 119, 135, 189, 197, 202, 212, 213, 216, 218, 221, 225, 226, 226, - 232, 233, 234, 234, 233, 236, 229, 236, 237, 236, 232, 225, 218, 213, 216, 217, - 222, 224, 221, 218, 220, 214, 199, 202, 189, 181, 198, 186, 187, 143, 122, 150, - 163, 171, 186, 201, 202, 197, 191, 204, 209, 209, 213, 213, 212, 210, 208, 205, - 202, 197, 185, 167, 138, 120, 118, 139, 135, 135, 140, 136, 135, 100, 61, 146, - 143, 146, 139, 139, 131, 128, 130, 130, 128, 127, 92, 111, 153, 140, 127, 151, - 153, 147, 119, 111, 108, 56, 153, 147, 157, 148, 155, 158, 150, 169, 214, 225, - 234, 232, 222, 216, 206, 194, 171, 159, 136, 116, 99, 92, 159, 102, 60, 142, - 134, 139, 144, 140, 138, 134, 126, 134, 127, 115, 87, 123, 135, 131, 118, 118, - 126, 120, 114, 123, 89, 71, 0, 104, 95, 103, 119, 124, 123, 131, 139, 134, - 120, 116, 72, 99, 124, 110, 233, 237, 233, 108, 100, 111, 132, 140, 148, 154, - 155, 154, 157, 153, 151, 144, 143, 142, 135, 124, 21, 20, 21, 45, 65, 64, - 61, 71, 71, 73, 64, 63, 42, 99, 124, 130, 127, 123, 128, 115, 116, 120, - 130, 119, 100, 88, 108, 150, 179, 185, 194, 201, 210, 212, 205, 209, 216, 220, - 218, 218, 226, 226, 217, 210, 214, 194, 201, 199, 204, 195, 169, 85, 46, 41, - 57, 55, 60, 55, 77, 42, 91, 102, 112, 120, 217, 224, 213, 97, 95, 108, - 123, 135, 144, 154, 166, 167, 159, 171, 97, 88, 84, 85, 88, 92, 93, 111, - 115, 120, 103, 106, 102, 115, 102, 97, 93, 93, 75, 108, 102, 93, 118, 177, - 187, 187, 173, 182, 194, 189, 197, 185, 182, 198, 185, 198, 199, 190, 186, 185, - 178, 181, 182, 187, 195, 185, 178, 139, 144, 182, 197, 197, 195, 189, 201, 189, - 174, 140, 143, 127, 119, 127, 115, 91, 42, 52, 28, 83, 91, 111, 96, 100, - 118, 97, 92, 115, 151, 158, 178, 182, 181, 178, 170, 178, 183, 190, 183, 182, - 178, 171, 175, 179, 185, 195, 201, 202, 202, 201, 191, 128, 60, 38, 9, 92, - 92, 81, 77, 73, 68, 73, 88, 80, 46, 30, 122, 178, 181, 174, 190, 204, - 204, 204, 205, 204, 208, 199, 189, 183, 187, 179, 174, 167, 151, 158, 150, 146, - 123, 73, 55, 119, 155, 177, 185, 190, 197, 208, 208, 170, 169, 151, 140, 142, - 138, 116, 73, 77, 99, 167, 171, 154, 144, 134, 134, 130, 128, 126, 120, 126, - 127, 134, 134, 142, 143, 144, 146, 107, 99, 102, 114, 53, 61, 75, 83, 79, - 77, 75, 73, 75, 79, 77, 79, 80, 84, 88, 91, 92, 85, 81, 76, 63, - 89, 22, 18, 13, 155, 155, 177, 182, 202, 208, 201, 205, 144, 110, 115, 138, - 161, 162, 162, 166, 166, 161, 155, 148, 142, 139, 127, 45, 28, 29, 67, 88, - 97, 126, 130, 136, 110, 154, 159, 154, 155, 163, 154, 166, 166, 165, 157, 142, - 123, 75, 116, 178, 131, 99, 73, 68, 71, 102, 111, 96, 97, 85, 146, 166, - 158, 153, 150, 148, 148, 238, 228, 221, 110, 100, 115, 124, 134, 135, 143, 140, - 134, 127, 126, 131, 124, 120, 32, 24, 26, 57, 83, 104, 110, 108, 161, 158, - 175, 177, 142, 165, 146, 148, 146, 142, 138, 136, 134, 132, 130, 130, 126, 123, - 123, 128, 123, 119, 118, 119, 112, 110, 112, 115, 169, 186, 220, 193, 185, 181, - 166, 144, 120, 115, 118, 120, 127, 120, 123, 144, 140, 174, 198, 199, 201, 206, - 189, 173, 175, 171, 162, 153, 143, 146, 144, 148, 148, 171, 186, 187, 194, 143, - 126, 107, 120, 130, 102, 124, 131, 135, 107, 59, 118, 142, 151, 135, 130, 134, - 139, 128, 122, 116, 131, 83, 106, 154, 153, 131, 135, 144, 122, 122, 116, 108, - 65, 155, 155, 142, 155, 155, 159, 165, 218, 234, 240, 230, 221, 197, 148, 124, - 110, 106, 99, 96, 85, 69, 72, 93, 93, 38, 93, 132, 128, 132, 124, 119, - 114, 119, 115, 131, 119, 67, 116, 130, 126, 118, 126, 120, 119, 112, 123, 93, - 64, 0, 102, 104, 124, 122, 120, 110, 114, 122, 120, 126, 88, 53, 103, 134, - 99, 232, 238, 234, 111, 103, 111, 138, 144, 153, 151, 159, 159, 165, 159, 161, - 155, 146, 140, 136, 124, 18, 17, 18, 44, 69, 67, 63, 68, 71, 89, 64, - 63, 33, 92, 120, 120, 122, 128, 126, 122, 126, 114, 111, 97, 63, 111, 126, - 115, 173, 195, 204, 210, 212, 216, 217, 221, 222, 226, 226, 232, 232, 228, 228, - 225, 222, 225, 224, 221, 218, 214, 190, 96, 52, 48, 56, 65, 53, 63, 76, - 41, 67, 93, 111, 107, 226, 230, 222, 102, 93, 108, 122, 134, 144, 154, 166, - 170, 166, 139, 173, 130, 135, 185, 198, 202, 204, 204, 205, 204, 201, 199, 202, - 199, 193, 185, 128, 92, 95, 96, 65, 111, 120, 122, 187, 198, 179, 195, 198, - 198, 173, 157, 135, 147, 166, 185, 185, 182, 165, 167, 146, 158, 157, 154, 151, - 148, 134, 122, 167, 197, 201, 199, 193, 189, 162, 144, 118, 111, 111, 106, 107, - 106, 115, 52, 44, 48, 26, 91, 95, 112, 120, 92, 102, 114, 85, 115, 147, - 165, 186, 191, 169, 157, 134, 132, 132, 139, 134, 134, 126, 123, 120, 127, 128, - 146, 154, 155, 167, 177, 190, 173, 88, 49, 14, 59, 97, 81, 72, 75, 72, - 79, 79, 84, 48, 26, 115, 165, 186, 197, 199, 230, 194, 201, 201, 199, 193, - 181, 175, 189, 181, 171, 167, 102, 88, 84, 79, 87, 79, 75, 64, 115, 162, - 177, 190, 205, 175, 166, 147, 123, 130, 120, 118, 122, 114, 119, 69, 60, 88, - 107, 167, 165, 144, 158, 132, 128, 116, 132, 130, 134, 134, 134, 134, 139, 140, - 143, 134, 103, 91, 95, 111, 61, 65, 67, 69, 65, 72, 80, 83, 79, 72, - 77, 69, 81, 75, 77, 76, 77, 75, 71, 91, 79, 16, 12, 12, 46, 144, - 147, 167, 175, 199, 212, 240, 199, 131, 106, 127, 144, 158, 165, 161, 163, 162, - 163, 155, 153, 144, 139, 122, 41, 26, 29, 65, 83, 108, 122, 130, 143, 119, - 151, 158, 148, 158, 150, 158, 150, 171, 163, 148, 136, 132, 77, 108, 175, 135, - 124, 92, 76, 71, 99, 99, 95, 79, 68, 154, 167, 158, 157, 153, 148, 147, - 238, 228, 222, 108, 102, 114, 126, 131, 138, 138, 130, 126, 124, 127, 126, 123, - 116, 30, 24, 24, 56, 72, 85, 108, 95, 126, 151, 151, 126, 148, 130, 119, - 119, 119, 119, 108, 114, 115, 114, 107, 107, 106, 107, 104, 104, 100, 103, 99, - 99, 99, 97, 97, 97, 106, 108, 110, 107, 106, 104, 106, 106, 96, 97, 100, - 104, 106, 110, 112, 144, 136, 190, 197, 208, 206, 189, 158, 132, 118, 111, 114, - 108, 106, 110, 112, 111, 114, 116, 132, 136, 163, 169, 126, 104, 127, 123, 132, - 134, 128, 130, 104, 61, 136, 150, 147, 139, 142, 134, 154, 127, 118, 114, 127, - 79, 114, 155, 150, 134, 120, 122, 114, 119, 116, 103, 63, 146, 157, 147, 166, - 161, 166, 216, 232, 242, 240, 222, 169, 103, 92, 83, 85, 85, 84, 77, 73, - 61, 57, 72, 91, 63, 99, 124, 132, 122, 116, 114, 112, 111, 116, 122, 111, - 81, 118, 134, 119, 119, 128, 127, 115, 118, 124, 108, 63, 5, 100, 115, 126, - 116, 130, 138, 131, 127, 126, 118, 85, 51, 96, 116, 96, 237, 242, 236, 111, - 103, 111, 138, 148, 157, 155, 163, 169, 171, 167, 162, 157, 147, 142, 134, 120, - 16, 18, 21, 42, 65, 61, 67, 67, 79, 77, 68, 59, 45, 87, 120, 122, - 110, 119, 128, 120, 123, 108, 96, 89, 64, 107, 122, 138, 124, 146, 166, 201, - 213, 210, 214, 220, 226, 226, 229, 216, 236, 234, 232, 218, 230, 234, 229, 206, - 234, 234, 190, 95, 46, 37, 65, 68, 55, 65, 73, 53, 52, 97, 110, 106, - 229, 234, 228, 103, 95, 108, 119, 132, 147, 153, 165, 171, 171, 163, 178, 183, - 190, 197, 204, 204, 205, 204, 204, 201, 202, 198, 199, 197, 193, 190, 187, 178, - 123, 104, 100, 99, 75, 93, 112, 130, 116, 111, 115, 103, 100, 97, 95, 102, - 100, 107, 107, 106, 104, 104, 103, 102, 104, 110, 110, 108, 136, 124, 165, 199, - 198, 190, 191, 142, 119, 112, 111, 110, 115, 114, 116, 123, 93, 42, 36, 37, - 20, 89, 97, 107, 111, 110, 96, 118, 119, 124, 167, 166, 153, 165, 153, 115, - 99, 96, 97, 99, 100, 100, 99, 99, 102, 104, 106, 110, 111, 116, 120, 126, - 135, 174, 128, 63, 14, 68, 95, 80, 79, 77, 73, 71, 68, 84, 49, 29, - 51, 87, 148, 166, 161, 151, 139, 116, 108, 102, 87, 80, 85, 80, 83, 80, - 73, 69, 71, 67, 67, 67, 63, 79, 69, 118, 166, 177, 178, 170, 131, 126, - 104, 110, 123, 124, 131, 123, 130, 114, 67, 68, 67, 72, 106, 190, 163, 154, - 147, 140, 136, 135, 136, 138, 134, 134, 138, 138, 132, 119, 135, 95, 37, 88, - 88, 89, 93, 96, 59, 68, 99, 128, 112, 114, 102, 99, 88, 91, 88, 83, - 96, 81, 81, 96, 85, 25, 10, 9, 16, 21, 138, 139, 142, 165, 195, 213, - 244, 185, 130, 110, 128, 153, 162, 165, 165, 169, 173, 165, 158, 151, 144, 136, - 123, 41, 26, 32, 68, 76, 102, 104, 119, 130, 108, 148, 155, 143, 170, 150, - 148, 163, 147, 146, 130, 132, 128, 87, 119, 169, 171, 138, 119, 96, 95, 96, - 97, 91, 79, 107, 151, 165, 159, 155, 148, 143, 140, 242, 232, 230, 103, 100, - 114, 123, 131, 138, 128, 127, 124, 136, 135, 132, 127, 122, 30, 22, 24, 55, - 67, 84, 122, 115, 88, 119, 148, 134, 134, 138, 126, 124, 112, 122, 124, 118, - 115, 111, 115, 115, 115, 115, 114, 111, 112, 114, 112, 114, 118, 119, 115, 112, - 99, 99, 97, 97, 97, 99, 97, 102, 108, 112, 116, 119, 122, 122, 120, 146, - 131, 157, 201, 186, 163, 142, 114, 122, 122, 119, 119, 119, 120, 120, 120, 118, - 116, 115, 110, 110, 115, 138, 128, 103, 123, 123, 127, 130, 130, 128, 107, 63, - 136, 150, 150, 146, 148, 126, 150, 131, 115, 123, 127, 73, 106, 146, 143, 134, - 134, 130, 126, 120, 120, 108, 71, 153, 161, 170, 155, 162, 208, 232, 242, 244, - 233, 171, 118, 84, 75, 68, 64, 61, 65, 64, 64, 49, 59, 64, 92, 64, - 67, 136, 134, 119, 115, 115, 119, 116, 108, 119, 116, 79, 115, 131, 118, 127, - 130, 118, 115, 120, 118, 118, 68, 1, 107, 111, 130, 111, 116, 112, 118, 124, - 127, 107, 79, 63, 85, 126, 100, 229, 238, 237, 110, 99, 111, 136, 151, 158, - 163, 169, 179, 179, 177, 165, 161, 150, 143, 132, 122, 16, 16, 20, 41, 67, - 68, 64, 71, 76, 81, 67, 59, 45, 88, 116, 119, 120, 124, 118, 123, 120, - 107, 93, 97, 59, 100, 130, 115, 136, 135, 136, 138, 147, 154, 148, 139, 138, - 139, 140, 142, 159, 153, 148, 163, 173, 146, 142, 155, 171, 135, 118, 88, 40, - 41, 67, 68, 59, 64, 67, 72, 33, 88, 100, 104, 233, 234, 232, 107, 96, - 108, 120, 132, 147, 155, 167, 174, 174, 170, 165, 135, 178, 189, 195, 204, 204, - 205, 202, 202, 202, 201, 199, 198, 198, 194, 189, 181, 177, 163, 158, 103, 97, - 96, 75, 77, 85, 97, 84, 95, 92, 95, 93, 97, 96, 103, 102, 102, 103, - 104, 106, 107, 106, 108, 112, 115, 138, 128, 157, 190, 183, 185, 126, 114, 116, - 112, 123, 122, 124, 122, 127, 124, 83, 32, 32, 41, 24, 87, 97, 104, 104, - 114, 110, 92, 110, 138, 142, 148, 128, 126, 100, 92, 100, 107, 106, 104, 106, - 106, 110, 110, 111, 110, 112, 111, 111, 112, 114, 115, 115, 126, 151, 73, 18, - 61, 87, 75, 80, 79, 80, 76, 72, 75, 63, 42, 44, 46, 65, 73, 76, - 71, 79, 80, 71, 71, 68, 71, 68, 75, 75, 72, 69, 72, 80, 108, 112, - 115, 114, 85, 77, 123, 197, 186, 144, 111, 111, 123, 126, 134, 135, 138, 136, - 136, 138, 102, 55, 24, 57, 75, 65, 89, 183, 165, 150, 151, 151, 146, 148, - 147, 153, 151, 153, 153, 148, 139, 111, 100, 89, 92, 80, 77, 81, 96, 87, - 65, 97, 185, 187, 136, 135, 118, 120, 120, 112, 126, 127, 128, 118, 114, 37, - 16, 10, 20, 25, 40, 132, 136, 131, 169, 202, 216, 244, 171, 132, 110, 130, - 154, 161, 165, 169, 170, 174, 170, 165, 148, 143, 135, 124, 41, 28, 33, 75, - 72, 97, 120, 111, 130, 114, 151, 154, 136, 165, 151, 147, 143, 174, 144, 132, - 131, 123, 72, 103, 162, 159, 134, 139, 126, 104, 111, 96, 80, 67, 107, 163, - 159, 163, 150, 159, 162, 147, 240, 232, 233, 108, 96, 114, 123, 134, 127, 138, - 140, 143, 150, 148, 140, 130, 126, 30, 22, 24, 60, 72, 87, 102, 96, 123, - 84, 103, 150, 130, 132, 120, 128, 144, 150, 134, 134, 134, 147, 131, 134, 134, - 140, 130, 128, 131, 140, 134, 135, 142, 143, 138, 135, 126, 118, 114, 115, 116, - 116, 118, 122, 126, 132, 135, 140, 140, 142, 130, 126, 120, 134, 148, 138, 114, - 127, 128, 148, 147, 131, 130, 131, 130, 131, 131, 131, 128, 127, 123, 122, 118, - 114, 134, 102, 108, 131, 123, 124, 130, 126, 108, 73, 132, 147, 144, 144, 148, - 136, 154, 142, 112, 120, 112, 68, 104, 144, 144, 118, 128, 100, 135, 132, 132, - 120, 110, 155, 178, 171, 171, 198, 225, 242, 246, 240, 217, 132, 89, 71, 46, - 46, 55, 51, 51, 56, 64, 57, 63, 60, 127, 68, 61, 135, 131, 118, 119, - 120, 122, 120, 115, 111, 114, 73, 112, 132, 119, 127, 122, 116, 115, 114, 120, - 96, 65, 2, 106, 111, 107, 116, 116, 119, 119, 126, 120, 107, 65, 73, 91, - 122, 119, 241, 244, 238, 116, 100, 111, 135, 147, 158, 163, 170, 179, 178, 177, - 175, 163, 146, 142, 134, 123, 16, 17, 18, 40, 64, 65, 67, 71, 81, 76, - 67, 63, 42, 76, 106, 120, 122, 119, 123, 126, 107, 87, 85, 77, 59, 107, - 120, 115, 139, 139, 122, 126, 128, 127, 127, 131, 128, 124, 128, 132, 131, 134, - 135, 136, 135, 136, 126, 130, 124, 123, 99, 64, 34, 32, 68, 64, 59, 63, - 63, 68, 22, 85, 111, 107, 233, 241, 233, 110, 99, 111, 124, 134, 146, 155, - 167, 173, 175, 174, 166, 167, 148, 143, 143, 140, 138, 135, 134, 131, 132, 130, - 128, 128, 126, 122, 122, 116, 122, 120, 122, 108, 114, 97, 110, 103, 107, 103, - 103, 103, 104, 106, 104, 104, 108, 110, 108, 108, 111, 114, 115, 115, 116, 119, - 122, 124, 118, 127, 124, 167, 198, 130, 120, 124, 128, 132, 134, 135, 132, 130, - 131, 127, 72, 32, 32, 38, 14, 79, 95, 102, 107, 100, 100, 97, 102, 96, - 97, 92, 97, 97, 85, 80, 73, 79, 95, 95, 115, 114, 115, 118, 120, 120, - 122, 122, 124, 124, 124, 123, 122, 119, 163, 92, 37, 41, 73, 91, 87, 77, - 68, 71, 73, 64, 76, 48, 28, 63, 60, 69, 73, 83, 83, 84, 84, 92, - 89, 95, 97, 102, 103, 107, 108, 106, 111, 122, 124, 128, 124, 95, 80, 116, - 166, 158, 130, 108, 132, 136, 144, 142, 143, 142, 142, 142, 132, 83, 22, 40, - 53, 61, 60, 71, 110, 169, 165, 142, 132, 158, 157, 158, 158, 162, 162, 163, - 161, 157, 144, 123, 96, 44, 81, 85, 79, 79, 79, 59, 100, 194, 182, 166, - 163, 136, 130, 131, 136, 124, 132, 148, 126, 107, 38, 14, 8, 22, 26, 8, - 126, 130, 126, 165, 210, 221, 237, 166, 122, 110, 130, 151, 162, 166, 167, 169, - 173, 170, 165, 153, 140, 138, 127, 44, 28, 36, 69, 89, 108, 112, 119, 123, - 106, 147, 148, 139, 157, 153, 148, 144, 127, 131, 138, 130, 115, 65, 102, 155, - 157, 143, 150, 138, 122, 163, 128, 76, 61, 131, 162, 157, 155, 147, 157, 153, - 143, 241, 233, 234, 108, 96, 111, 123, 136, 139, 153, 158, 163, 165, 158, 144, - 132, 128, 30, 22, 25, 56, 63, 84, 85, 108, 136, 115, 83, 91, 142, 146, - 122, 174, 182, 162, 134, 148, 166, 142, 142, 148, 154, 143, 140, 144, 151, 142, - 144, 148, 143, 147, 148, 147, 144, 140, 136, 136, 135, 140, 143, 143, 147, 148, - 154, 154, 153, 154, 147, 128, 153, 116, 112, 136, 132, 112, 88, 81, 95, 119, - 134, 161, 134, 136, 159, 138, 138, 136, 134, 132, 128, 118, 134, 112, 85, 122, - 128, 127, 122, 132, 112, 73, 80, 143, 148, 154, 148, 132, 154, 142, 106, 123, - 106, 65, 132, 135, 142, 135, 136, 134, 147, 162, 174, 179, 186, 208, 217, 225, - 226, 229, 241, 246, 248, 238, 177, 104, 60, 73, 69, 81, 68, 83, 77, 75, - 72, 72, 72, 76, 72, 84, 57, 108, 127, 120, 122, 123, 122, 126, 120, 114, - 115, 68, 111, 126, 118, 127, 120, 116, 118, 118, 123, 102, 63, 4, 103, 115, - 120, 126, 122, 122, 123, 123, 123, 93, 45, 60, 83, 122, 106, 238, 245, 241, - 114, 102, 110, 136, 148, 155, 163, 170, 174, 177, 177, 175, 166, 146, 138, 135, - 123, 14, 16, 22, 37, 59, 63, 67, 68, 77, 68, 68, 57, 41, 69, 99, - 114, 127, 119, 116, 110, 107, 84, 88, 83, 46, 110, 119, 124, 115, 116, 108, - 110, 148, 150, 123, 134, 136, 142, 143, 142, 135, 135, 136, 136, 134, 130, 131, - 128, 126, 114, 97, 46, 33, 33, 64, 69, 59, 65, 65, 69, 28, 85, 104, - 108, 229, 238, 237, 110, 100, 112, 124, 135, 146, 157, 169, 173, 175, 174, 159, - 151, 120, 96, 89, 110, 107, 120, 119, 119, 116, 115, 112, 108, 102, 100, 102, - 102, 96, 96, 91, 88, 84, 83, 79, 83, 91, 83, 87, 174, 111, 108, 108, - 114, 112, 116, 118, 118, 119, 123, 127, 127, 128, 128, 131, 134, 132, 135, 126, - 127, 124, 124, 131, 140, 144, 144, 144, 142, 139, 138, 134, 115, 52, 32, 25, - 37, 22, 65, 95, 93, 102, 104, 104, 106, 95, 89, 80, 73, 61, 57, 51, - 45, 51, 52, 64, 77, 89, 102, 119, 116, 123, 123, 127, 122, 126, 130, 135, - 134, 131, 130, 127, 126, 65, 18, 65, 72, 61, 59, 73, 68, 71, 64, 68, - 48, 40, 64, 57, 55, 67, 63, 138, 93, 100, 106, 108, 108, 112, 116, 115, - 118, 118, 116, 116, 128, 132, 134, 134, 128, 87, 108, 153, 132, 126, 139, 148, - 144, 147, 144, 146, 148, 146, 146, 134, 67, 37, 36, 45, 44, 56, 67, 72, - 139, 174, 157, 134, 135, 157, 167, 167, 165, 170, 170, 174, 174, 169, 150, 111, - 81, 72, 45, 67, 76, 61, 65, 112, 193, 193, 182, 140, 153, 136, 139, 139, - 144, 151, 150, 120, 122, 30, 16, 20, 24, 8, 0, 119, 126, 123, 161, 210, - 224, 238, 148, 119, 108, 128, 144, 159, 165, 165, 166, 173, 170, 167, 154, 144, - 136, 130, 41, 28, 36, 64, 92, 111, 108, 144, 136, 95, 138, 144, 140, 158, - 158, 147, 140, 135, 135, 132, 131, 119, 63, 104, 167, 186, 147, 142, 144, 142, - 120, 131, 87, 53, 127, 159, 154, 157, 148, 151, 148, 142, 242, 238, 233, 107, - 97, 111, 126, 140, 150, 163, 169, 169, 169, 161, 147, 134, 128, 28, 22, 24, - 57, 73, 80, 84, 92, 120, 115, 91, 81, 131, 142, 127, 198, 193, 127, 124, - 132, 150, 146, 161, 163, 147, 148, 153, 155, 148, 151, 148, 153, 153, 150, 163, - 163, 167, 159, 153, 148, 150, 155, 159, 157, 162, 161, 163, 165, 165, 163, 159, - 142, 157, 157, 138, 110, 77, 59, 48, 51, 60, 96, 130, 143, 177, 182, 181, - 167, 174, 171, 161, 139, 135, 127, 116, 123, 85, 89, 118, 120, 120, 122, 116, - 95, 75, 136, 139, 120, 147, 138, 140, 112, 115, 111, 80, 95, 130, 132, 165, - 175, 197, 213, 230, 230, 242, 241, 248, 246, 250, 250, 249, 249, 250, 250, 244, - 220, 143, 102, 76, 42, 73, 79, 79, 75, 77, 76, 79, 83, 77, 73, 76, - 83, 72, 104, 134, 130, 130, 130, 126, 132, 124, 110, 108, 72, 111, 128, 118, - 120, 123, 119, 132, 122, 114, 108, 60, 6, 107, 128, 115, 134, 128, 124, 130, - 126, 116, 95, 46, 64, 88, 119, 103, 238, 245, 240, 111, 100, 110, 135, 147, - 154, 162, 167, 170, 177, 175, 175, 167, 147, 140, 135, 126, 13, 18, 18, 37, - 61, 63, 69, 67, 67, 71, 65, 59, 52, 57, 93, 96, 100, 96, 97, 97, - 80, 84, 87, 83, 53, 80, 115, 116, 108, 108, 104, 103, 112, 93, 106, 173, - 134, 127, 131, 146, 147, 151, 151, 155, 155, 158, 147, 153, 122, 114, 99, 37, - 28, 32, 56, 53, 68, 71, 56, 65, 41, 79, 100, 110, 220, 240, 238, 110, - 100, 111, 126, 138, 147, 157, 170, 174, 174, 170, 161, 130, 69, 38, 34, 34, - 73, 92, 111, 110, 114, 112, 112, 112, 112, 111, 115, 115, 114, 110, 64, 68, - 81, 79, 77, 76, 76, 80, 84, 177, 179, 118, 100, 122, 130, 120, 122, 126, - 126, 127, 132, 134, 136, 139, 140, 139, 139, 132, 132, 122, 119, 143, 148, 150, - 151, 146, 146, 144, 139, 140, 130, 85, 32, 26, 25, 36, 25, 46, 89, 92, - 91, 81, 69, 55, 59, 59, 60, 49, 61, 63, 61, 59, 73, 69, 52, 48, - 75, 107, 119, 171, 174, 170, 148, 157, 170, 155, 155, 151, 138, 140, 128, 155, - 96, 36, 28, 67, 72, 65, 60, 64, 65, 65, 73, 42, 36, 48, 60, 65, - 52, 59, 136, 163, 103, 103, 112, 123, 120, 122, 124, 124, 124, 124, 127, 131, - 140, 139, 140, 139, 134, 92, 91, 135, 147, 151, 151, 151, 151, 143, 147, 148, - 146, 143, 102, 46, 40, 37, 18, 46, 48, 64, 61, 67, 155, 166, 140, 128, - 140, 157, 163, 171, 174, 177, 178, 178, 178, 171, 140, 76, 69, 52, 71, 65, - 72, 65, 123, 204, 198, 216, 151, 155, 140, 138, 142, 142, 155, 148, 120, 120, - 26, 14, 6, 12, 8, 0, 110, 110, 111, 153, 222, 224, 240, 147, 103, 112, - 132, 147, 155, 159, 162, 169, 171, 170, 165, 157, 138, 132, 126, 42, 29, 37, - 67, 89, 91, 108, 118, 120, 92, 155, 153, 138, 131, 128, 130, 127, 127, 126, - 124, 132, 124, 81, 116, 134, 161, 143, 72, 88, 83, 83, 79, 67, 51, 92, - 130, 131, 126, 124, 147, 142, 139, 244, 240, 233, 104, 97, 110, 124, 139, 153, - 167, 171, 166, 169, 162, 146, 134, 127, 28, 21, 25, 55, 51, 72, 84, 79, - 91, 76, 83, 87, 112, 144, 126, 201, 198, 170, 127, 128, 136, 153, 150, 154, - 162, 159, 150, 159, 150, 151, 150, 151, 158, 170, 174, 181, 187, 187, 183, 163, - 162, 165, 171, 170, 171, 171, 171, 173, 173, 170, 165, 147, 159, 158, 114, 75, - 46, 46, 42, 38, 48, 77, 106, 136, 178, 181, 194, 185, 179, 155, 174, 167, - 154, 134, 120, 130, 93, 75, 95, 114, 119, 118, 112, 114, 102, 89, 95, 103, - 103, 106, 104, 104, 106, 83, 116, 126, 155, 201, 226, 238, 242, 242, 246, 250, - 253, 253, 253, 252, 253, 252, 252, 250, 250, 248, 238, 178, 138, 103, 73, 40, - 73, 69, 69, 69, 73, 73, 76, 76, 81, 75, 81, 79, 76, 75, 93, 99, - 97, 108, 104, 107, 106, 104, 111, 68, 106, 115, 115, 103, 108, 108, 111, 106, - 106, 93, 60, 5, 102, 114, 118, 122, 116, 115, 115, 115, 102, 92, 41, 69, - 84, 116, 96, 238, 242, 238, 110, 96, 110, 135, 147, 155, 161, 162, 163, 175, - 177, 175, 163, 153, 140, 132, 122, 12, 16, 17, 36, 57, 57, 56, 65, 68, - 65, 75, 68, 64, 64, 71, 77, 71, 73, 77, 81, 75, 80, 85, 73, 48, - 87, 108, 104, 102, 102, 103, 104, 104, 100, 91, 175, 179, 126, 124, 132, 136, - 146, 150, 155, 155, 150, 155, 151, 126, 115, 99, 34, 26, 30, 44, 45, 56, - 61, 49, 51, 48, 56, 80, 107, 228, 241, 237, 115, 100, 112, 126, 139, 144, - 154, 169, 174, 173, 182, 151, 83, 45, 26, 21, 18, 37, 85, 131, 165, 169, - 162, 120, 153, 155, 153, 151, 123, 120, 115, 83, 55, 79, 77, 76, 75, 76, - 73, 76, 163, 190, 169, 111, 112, 130, 131, 134, 134, 136, 138, 139, 142, 142, - 143, 143, 147, 144, 142, 140, 142, 154, 153, 155, 151, 146, 132, 126, 116, 103, - 100, 77, 40, 25, 22, 24, 36, 25, 38, 45, 51, 46, 52, 56, 55, 65, - 67, 71, 60, 77, 75, 75, 71, 71, 73, 73, 75, 87, 111, 179, 190, 191, - 183, 174, 174, 177, 173, 166, 170, 161, 147, 142, 128, 120, 67, 20, 34, 77, - 76, 59, 61, 59, 56, 71, 49, 37, 42, 60, 57, 56, 61, 131, 169, 159, - 102, 104, 124, 126, 130, 130, 128, 132, 131, 130, 144, 151, 155, 151, 150, 143, - 147, 157, 157, 154, 154, 150, 144, 136, 131, 122, 116, 112, 89, 49, 32, 28, - 37, 28, 38, 26, 41, 42, 33, 100, 171, 165, 134, 127, 140, 157, 162, 170, - 175, 178, 179, 182, 181, 165, 114, 60, 71, 80, 83, 71, 64, 158, 206, 202, - 191, 170, 165, 147, 144, 150, 153, 151, 148, 120, 116, 24, 9, 5, 17, 13, - 13, 114, 107, 97, 150, 214, 225, 240, 139, 99, 108, 132, 148, 158, 161, 167, - 170, 171, 161, 158, 158, 140, 134, 128, 45, 28, 37, 63, 67, 93, 112, 110, - 119, 96, 150, 138, 119, 122, 116, 124, 124, 122, 115, 130, 134, 110, 73, 88, - 76, 53, 51, 51, 49, 44, 42, 45, 45, 46, 57, 63, 72, 80, 84, 110, - 138, 140, 242, 240, 229, 104, 97, 111, 130, 140, 153, 167, 174, 173, 165, 159, - 144, 132, 123, 24, 20, 22, 49, 56, 63, 73, 65, 67, 76, 65, 73, 85, - 139, 128, 208, 201, 197, 126, 122, 132, 147, 170, 169, 153, 159, 150, 153, 159, - 165, 167, 171, 174, 178, 181, 173, 161, 179, 187, 193, 185, 167, 183, 182, 181, - 177, 189, 182, 179, 183, 178, 186, 166, 159, 106, 61, 46, 38, 36, 34, 36, - 67, 102, 134, 189, 193, 165, 169, 186, 183, 163, 159, 165, 138, 126, 132, 99, - 68, 77, 95, 110, 108, 104, 104, 102, 112, 110, 104, 107, 106, 104, 108, 77, - 126, 135, 175, 228, 244, 244, 244, 248, 249, 252, 253, 252, 245, 240, 234, 234, - 233, 229, 225, 220, 216, 183, 147, 138, 110, 69, 69, 67, 75, 72, 75, 79, - 77, 80, 81, 80, 81, 84, 81, 79, 89, 89, 91, 91, 89, 92, 91, 91, - 88, 87, 83, 84, 73, 84, 84, 84, 68, 76, 73, 68, 59, 65, 8, 33, - 57, 63, 67, 65, 67, 64, 79, 69, 44, 24, 88, 69, 108, 104, 241, 244, - 238, 110, 95, 104, 131, 144, 157, 162, 166, 173, 174, 177, 165, 159, 148, 140, - 134, 126, 13, 18, 18, 42, 45, 48, 49, 45, 51, 45, 42, 49, 51, 49, - 51, 61, 59, 56, 56, 53, 55, 56, 53, 63, 71, 64, 71, 61, 59, 93, - 97, 92, 95, 100, 84, 155, 185, 173, 124, 127, 138, 136, 146, 150, 148, 150, - 154, 154, 130, 119, 91, 30, 24, 25, 42, 41, 46, 61, 60, 45, 45, 55, - 77, 108, 234, 244, 241, 115, 103, 114, 126, 138, 147, 157, 170, 174, 169, 161, - 116, 48, 30, 20, 24, 21, 32, 71, 148, 179, 131, 163, 155, 155, 159, 169, - 143, 147, 124, 119, 110, 51, 51, 65, 75, 73, 72, 80, 69, 111, 199, 189, - 120, 111, 120, 144, 139, 142, 142, 142, 144, 146, 146, 148, 148, 150, 153, 157, - 161, 157, 157, 155, 142, 108, 71, 49, 30, 24, 24, 25, 24, 22, 20, 24, - 22, 34, 24, 46, 41, 45, 48, 57, 77, 116, 183, 201, 212, 214, 212, 204, - 190, 181, 112, 100, 95, 95, 116, 191, 216, 166, 194, 187, 189, 186, 177, 182, - 181, 173, 166, 159, 146, 135, 150, 95, 32, 22, 45, 52, 57, 60, 57, 60, - 63, 63, 45, 40, 53, 61, 41, 52, 112, 178, 177, 112, 103, 114, 127, 138, - 134, 134, 138, 147, 150, 157, 161, 161, 161, 158, 157, 159, 159, 155, 150, 134, - 99, 72, 42, 32, 25, 18, 26, 26, 28, 32, 30, 9, 12, 12, 44, 46, - 37, 34, 42, 124, 175, 147, 122, 123, 147, 158, 163, 170, 175, 179, 183, 185, - 179, 138, 71, 41, 49, 67, 79, 92, 190, 204, 205, 194, 166, 155, 157, 155, - 157, 158, 153, 151, 131, 112, 21, 10, 6, 9, 13, 10, 53, 63, 69, 120, - 208, 228, 232, 139, 110, 110, 132, 147, 157, 163, 166, 170, 169, 154, 161, 151, - 139, 134, 127, 52, 30, 34, 49, 53, 55, 67, 114, 112, 87, 114, 112, 106, - 83, 75, 84, 76, 67, 59, 44, 60, 60, 68, 33, 68, 72, 79, 87, 89, - 85, 100, 93, 80, 40, 99, 153, 150, 124, 131, 135, 143, 140, 244, 240, 222, - 106, 97, 108, 126, 135, 151, 166, 173, 170, 166, 162, 143, 127, 127, 29, 22, - 24, 51, 56, 55, 68, 69, 69, 67, 69, 69, 69, 135, 128, 212, 210, 206, - 127, 132, 128, 142, 166, 170, 159, 155, 157, 167, 178, 178, 178, 177, 173, 182, - 150, 99, 76, 97, 162, 189, 187, 173, 165, 178, 179, 181, 179, 179, 183, 183, - 189, 190, 169, 165, 100, 57, 44, 38, 34, 34, 36, 71, 97, 130, 202, 199, - 166, 190, 191, 191, 169, 185, 174, 143, 131, 119, 114, 76, 68, 85, 72, 67, - 59, 63, 57, 60, 57, 61, 61, 61, 67, 84, 97, 144, 191, 240, 245, 246, - 244, 252, 250, 242, 225, 197, 173, 130, 118, 120, 112, 115, 120, 118, 115, 120, - 136, 126, 131, 124, 97, 83, 25, 22, 20, 17, 14, 14, 14, 12, 10, 13, - 13, 8, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 4, 10, - 12, 9, 2, 2, 8, 6, 9, 10, 8, 30, 28, 30, 13, 30, 32, 30, - 26, 33, 34, 33, 81, 51, 48, 115, 103, 241, 244, 242, 114, 97, 106, 132, - 146, 158, 165, 173, 177, 177, 173, 162, 165, 146, 138, 134, 122, 10, 16, 21, - 25, 17, 14, 14, 17, 16, 17, 18, 20, 20, 25, 36, 76, 83, 96, 91, - 97, 91, 93, 88, 81, 79, 108, 115, 108, 75, 63, 64, 63, 88, 104, 95, - 100, 195, 189, 130, 124, 135, 136, 142, 144, 144, 154, 150, 148, 123, 118, 91, - 29, 22, 26, 38, 24, 36, 40, 42, 37, 48, 83, 77, 111, 234, 245, 241, - 111, 99, 110, 123, 136, 143, 157, 170, 173, 169, 148, 77, 37, 24, 22, 25, - 18, 38, 85, 186, 194, 165, 132, 162, 165, 153, 143, 132, 153, 127, 122, 112, - 46, 49, 57, 64, 68, 67, 80, 75, 97, 212, 202, 132, 111, 122, 138, 147, - 146, 144, 144, 143, 146, 147, 151, 151, 162, 167, 165, 161, 161, 153, 104, 57, - 22, 17, 16, 14, 14, 16, 16, 17, 20, 22, 22, 24, 38, 45, 44, 63, - 71, 85, 135, 190, 236, 242, 245, 245, 244, 242, 240, 240, 237, 238, 237, 233, - 225, 230, 229, 225, 210, 191, 186, 182, 182, 179, 178, 181, 178, 174, 171, 153, - 144, 130, 119, 65, 21, 29, 36, 44, 36, 41, 45, 44, 52, 52, 52, 53, - 48, 44, 56, 104, 189, 187, 124, 108, 111, 126, 134, 138, 140, 155, 161, 167, - 166, 165, 162, 165, 169, 163, 161, 157, 138, 93, 51, 17, 13, 10, 12, 13, - 14, 18, 16, 8, 10, 9, 14, 18, 13, 13, 17, 28, 22, 32, 71, 157, - 166, 130, 119, 135, 151, 159, 163, 171, 178, 181, 186, 187, 161, 102, 77, 77, - 81, 79, 116, 204, 208, 210, 201, 171, 161, 170, 158, 154, 159, 148, 151, 127, - 122, 21, 9, 10, 2, 2, 1, 194, 189, 183, 143, 209, 228, 230, 150, 112, - 108, 128, 148, 157, 161, 166, 166, 161, 162, 163, 140, 136, 135, 130, 57, 30, - 36, 49, 83, 76, 71, 68, 75, 80, 73, 77, 99, 115, 112, 130, 136, 136, - 144, 148, 140, 128, 42, 96, 119, 144, 153, 142, 138, 135, 134, 107, 93, 37, - 140, 158, 158, 158, 161, 162, 144, 147, 246, 233, 236, 106, 95, 104, 128, 136, - 151, 165, 171, 169, 163, 161, 144, 134, 130, 30, 24, 25, 57, 59, 73, 87, - 100, 108, 72, 100, 65, 127, 138, 138, 218, 213, 213, 136, 131, 136, 134, 159, - 167, 158, 155, 170, 182, 182, 181, 179, 171, 173, 159, 103, 55, 57, 81, 128, - 183, 199, 182, 161, 178, 183, 182, 183, 186, 187, 190, 191, 189, 162, 170, 108, - 60, 51, 44, 40, 38, 38, 69, 110, 127, 206, 205, 173, 170, 174, 191, 193, - 190, 175, 155, 136, 123, 134, 93, 61, 75, 89, 92, 88, 89, 119, 127, 134, - 132, 140, 132, 115, 134, 174, 205, 242, 244, 245, 250, 246, 225, 190, 147, 122, - 115, 108, 103, 111, 114, 115, 103, 118, 116, 115, 111, 127, 128, 130, 127, 123, - 87, 102, 80, 79, 83, 91, 84, 84, 84, 79, 77, 68, 69, 99, 124, 127, - 143, 132, 124, 143, 147, 130, 102, 93, 103, 155, 126, 127, 163, 161, 126, 116, - 116, 144, 106, 16, 0, 48, 92, 110, 75, 76, 73, 72, 71, 46, 59, 44, - 76, 116, 115, 112, 242, 244, 241, 114, 96, 111, 134, 147, 155, 165, 174, 174, - 175, 169, 165, 163, 144, 135, 135, 127, 12, 20, 21, 32, 63, 80, 85, 93, - 100, 99, 97, 87, 93, 95, 91, 107, 131, 123, 124, 108, 114, 116, 118, 120, - 108, 122, 126, 123, 102, 91, 79, 76, 69, 92, 93, 95, 202, 197, 147, 124, - 131, 140, 135, 139, 150, 151, 150, 148, 127, 115, 87, 26, 21, 28, 40, 51, - 57, 71, 72, 83, 83, 68, 103, 114, 234, 245, 241, 107, 99, 111, 126, 138, - 146, 159, 171, 170, 182, 136, 48, 30, 25, 26, 28, 16, 56, 84, 197, 199, - 189, 132, 157, 158, 158, 140, 131, 131, 128, 124, 115, 48, 42, 52, 72, 68, - 67, 72, 67, 88, 213, 210, 189, 116, 114, 128, 140, 151, 155, 146, 148, 148, - 155, 155, 162, 171, 166, 163, 163, 148, 87, 30, 17, 14, 16, 17, 21, 21, - 22, 22, 22, 22, 25, 25, 37, 36, 48, 60, 75, 119, 208, 237, 240, 242, - 242, 244, 241, 242, 244, 244, 242, 241, 237, 237, 234, 232, 233, 233, 229, 224, - 170, 167, 185, 187, 193, 177, 187, 181, 178, 174, 163, 148, 135, 140, 91, 29, - 32, 37, 45, 42, 56, 48, 42, 34, 28, 32, 38, 40, 46, 65, 103, 194, - 201, 170, 107, 107, 116, 132, 138, 151, 166, 166, 163, 166, 166, 163, 166, 170, - 163, 158, 140, 80, 21, 16, 9, 8, 5, 6, 5, 8, 8, 18, 24, 17, - 18, 18, 24, 33, 24, 24, 14, 17, 32, 45, 142, 163, 139, 119, 119, 135, - 157, 161, 169, 174, 179, 186, 186, 186, 134, 76, 68, 64, 92, 148, 213, 209, - 218, 212, 175, 165, 170, 154, 158, 158, 153, 154, 130, 120, 25, 14, 12, 12, - 34, 42, 165, 157, 157, 136, 193, 225, 232, 157, 114, 108, 128, 144, 157, 162, - 165, 166, 158, 162, 158, 140, 135, 135, 128, 64, 32, 37, 57, 73, 103, 115, - 119, 115, 87, 104, 146, 167, 162, 167, 177, 178, 171, 170, 174, 157, 132, 45, - 99, 183, 170, 169, 155, 157, 157, 128, 111, 95, 42, 148, 161, 151, 148, 142, - 154, 146, 144, 246, 234, 234, 106, 93, 107, 131, 136, 151, 166, 173, 170, 165, - 161, 146, 135, 130, 32, 24, 25, 57, 67, 79, 106, 92, 106, 88, 99, 64, - 131, 134, 143, 217, 218, 214, 136, 115, 122, 131, 142, 165, 161, 166, 179, 183, - 182, 183, 182, 175, 173, 128, 63, 52, 53, 60, 85, 167, 202, 189, 162, 163, - 179, 194, 195, 198, 199, 202, 202, 197, 189, 177, 138, 75, 49, 46, 45, 40, - 57, 84, 116, 127, 208, 210, 186, 169, 189, 191, 177, 190, 173, 166, 139, 130, - 120, 111, 67, 63, 85, 89, 120, 108, 107, 131, 134, 147, 127, 138, 151, 175, - 230, 244, 244, 245, 250, 233, 187, 139, 116, 112, 111, 114, 126, 80, 60, 57, - 60, 69, 115, 120, 128, 158, 178, 185, 175, 131, 130, 118, 97, 87, 112, 111, - 93, 95, 91, 89, 85, 107, 123, 84, 123, 153, 148, 151, 104, 135, 155, 158, - 135, 128, 112, 96, 142, 147, 157, 154, 157, 146, 147, 144, 131, 128, 92, 0, - 108, 107, 111, 118, 108, 104, 108, 88, 72, 68, 38, 116, 116, 112, 116, 244, - 244, 241, 104, 100, 112, 135, 144, 157, 166, 173, 171, 177, 166, 162, 159, 143, - 135, 134, 123, 10, 18, 38, 53, 84, 81, 89, 92, 95, 100, 97, 104, 92, - 102, 135, 122, 116, 115, 119, 124, 114, 114, 122, 155, 165, 208, 195, 147, 116, - 99, 92, 93, 91, 91, 92, 85, 208, 208, 179, 124, 128, 135, 138, 134, 140, - 155, 147, 154, 126, 116, 85, 28, 22, 34, 46, 72, 80, 84, 85, 91, 59, - 87, 122, 158, 236, 244, 238, 114, 100, 112, 127, 139, 146, 163, 171, 169, 162, - 118, 42, 30, 21, 25, 32, 18, 63, 95, 205, 205, 197, 161, 154, 154, 159, - 142, 146, 134, 128, 131, 119, 45, 42, 41, 60, 72, 75, 68, 68, 85, 214, - 212, 197, 115, 114, 122, 136, 147, 154, 154, 154, 169, 173, 171, 173, 174, 165, - 163, 150, 92, 25, 13, 14, 16, 17, 26, 22, 28, 28, 28, 29, 29, 38, - 40, 44, 33, 49, 64, 107, 224, 240, 238, 244, 242, 240, 230, 220, 199, 197, - 186, 189, 193, 204, 206, 209, 220, 222, 226, 222, 225, 213, 175, 201, 199, 209, - 209, 199, 181, 185, 179, 170, 153, 140, 135, 112, 57, 26, 28, 59, 53, 59, - 73, 73, 68, 61, 69, 76, 77, 77, 63, 111, 195, 204, 187, 108, 107, 118, - 131, 143, 154, 166, 170, 171, 169, 169, 169, 171, 169, 165, 140, 80, 20, 14, - 9, 8, 9, 12, 8, 9, 17, 9, 24, 37, 45, 37, 51, 48, 49, 53, - 57, 48, 49, 26, 49, 127, 162, 158, 118, 115, 130, 148, 159, 163, 171, 177, - 182, 189, 194, 181, 120, 59, 83, 106, 178, 213, 212, 213, 198, 183, 170, 165, - 161, 165, 158, 154, 154, 131, 122, 17, 12, 13, 22, 20, 6, 166, 161, 155, - 153, 161, 224, 222, 186, 120, 108, 123, 146, 155, 161, 165, 161, 162, 158, 146, - 128, 135, 134, 128, 87, 37, 38, 65, 76, 116, 132, 118, 114, 71, 147, 174, - 181, 178, 171, 190, 186, 186, 179, 182, 148, 128, 37, 120, 189, 179, 175, 174, - 165, 151, 143, 104, 89, 46, 142, 159, 150, 151, 148, 153, 147, 148, 241, 229, - 234, 102, 92, 107, 131, 139, 151, 166, 171, 173, 162, 161, 147, 138, 131, 32, - 26, 29, 59, 57, 84, 102, 92, 93, 87, 107, 49, 147, 135, 173, 224, 221, - 217, 123, 114, 120, 140, 143, 154, 159, 173, 183, 185, 183, 182, 179, 174, 165, - 100, 52, 48, 52, 59, 89, 148, 205, 201, 167, 157, 175, 182, 194, 201, 204, - 205, 204, 204, 197, 178, 167, 95, 55, 44, 46, 41, 73, 102, 118, 132, 204, - 216, 201, 174, 190, 191, 186, 190, 175, 174, 144, 135, 126, 126, 84, 61, 80, - 83, 84, 99, 131, 126, 131, 127, 134, 132, 151, 213, 245, 244, 246, 248, 222, - 163, 119, 115, 114, 118, 138, 126, 75, 55, 49, 57, 49, 68, 115, 183, 195, - 189, 163, 170, 170, 174, 131, 131, 122, 99, 64, 97, 99, 108, 96, 95, 95, - 99, 88, 89, 165, 162, 158, 153, 150, 144, 136, 144, 128, 114, 95, 119, 161, - 159, 151, 150, 144, 148, 148, 155, 144, 142, 106, 29, 115, 104, 93, 87, 85, - 91, 95, 107, 83, 63, 41, 116, 127, 119, 144, 245, 244, 238, 107, 100, 114, - 135, 144, 154, 165, 171, 173, 175, 165, 161, 142, 131, 134, 134, 122, 13, 22, - 38, 71, 77, 95, 95, 103, 87, 92, 97, 87, 57, 106, 132, 124, 114, 110, - 119, 115, 118, 119, 179, 228, 216, 218, 208, 174, 119, 103, 85, 103, 91, 87, - 92, 83, 206, 208, 195, 126, 128, 138, 144, 138, 139, 147, 140, 139, 126, 120, - 77, 28, 22, 42, 57, 75, 76, 83, 96, 73, 57, 85, 123, 163, 236, 244, - 240, 120, 104, 115, 128, 144, 151, 165, 171, 166, 158, 88, 40, 26, 24, 28, - 33, 18, 69, 104, 204, 208, 204, 128, 150, 153, 158, 128, 135, 138, 128, 130, - 116, 45, 37, 41, 55, 60, 67, 75, 72, 87, 220, 214, 199, 114, 114, 119, - 132, 147, 155, 159, 171, 175, 178, 179, 175, 171, 169, 154, 89, 28, 13, 17, - 17, 17, 24, 24, 34, 42, 45, 46, 42, 45, 41, 45, 51, 41, 53, 80, - 175, 240, 240, 241, 237, 232, 197, 177, 154, 153, 151, 155, 158, 162, 167, 171, - 175, 179, 183, 186, 197, 198, 206, 201, 202, 199, 199, 201, 202, 199, 191, 181, - 171, 157, 148, 131, 122, 77, 30, 38, 53, 59, 55, 65, 51, 60, 69, 71, - 71, 59, 56, 56, 97, 199, 208, 197, 110, 107, 116, 132, 142, 158, 166, 170, - 170, 171, 170, 173, 170, 169, 153, 99, 29, 16, 9, 12, 12, 12, 13, 13, - 22, 18, 12, 40, 49, 53, 51, 53, 42, 40, 34, 44, 46, 56, 12, 51, - 107, 146, 170, 132, 112, 122, 142, 153, 159, 166, 173, 179, 186, 199, 198, 187, - 139, 114, 153, 208, 206, 214, 212, 195, 197, 178, 183, 169, 165, 163, 157, 154, - 138, 122, 24, 12, 5, 30, 5, 59, 146, 155, 155, 146, 147, 214, 226, 208, - 122, 106, 118, 143, 154, 159, 161, 162, 159, 155, 136, 136, 135, 132, 127, 103, - 40, 42, 67, 88, 118, 126, 111, 123, 83, 151, 190, 186, 189, 187, 183, 186, - 186, 187, 171, 144, 130, 36, 127, 182, 194, 204, 186, 171, 157, 148, 114, 92, - 51, 134, 154, 151, 159, 150, 148, 142, 153, 241, 236, 232, 93, 93, 106, 128, - 136, 148, 165, 173, 170, 165, 161, 150, 139, 130, 32, 28, 25, 60, 71, 84, - 104, 95, 95, 87, 103, 51, 136, 142, 175, 229, 226, 220, 124, 120, 119, 128, - 142, 158, 162, 175, 182, 186, 186, 182, 179, 171, 147, 67, 49, 44, 52, 77, - 83, 135, 198, 206, 175, 154, 157, 177, 187, 198, 204, 204, 205, 205, 201, 197, - 181, 131, 63, 48, 44, 52, 76, 106, 122, 128, 201, 221, 213, 178, 174, 189, - 177, 189, 175, 169, 151, 138, 130, 134, 97, 57, 67, 83, 80, 96, 120, 140, - 143, 135, 126, 146, 167, 233, 238, 244, 245, 228, 148, 116, 116, 118, 123, 142, - 144, 92, 63, 48, 41, 53, 52, 73, 131, 199, 194, 167, 169, 174, 171, 178, - 142, 135, 118, 111, 89, 61, 85, 83, 92, 83, 93, 95, 83, 37, 154, 166, - 143, 159, 153, 159, 166, 162, 143, 114, 93, 112, 165, 155, 153, 146, 144, 148, - 147, 144, 146, 151, 65, 30, 81, 106, 100, 88, 88, 88, 91, 99, 68, 63, - 38, 118, 128, 115, 131, 242, 245, 241, 111, 102, 112, 134, 146, 151, 165, 171, - 174, 178, 165, 161, 136, 130, 131, 132, 120, 13, 22, 26, 42, 79, 92, 107, - 103, 92, 106, 89, 95, 61, 93, 136, 115, 127, 115, 107, 120, 115, 126, 208, - 228, 213, 217, 195, 153, 115, 89, 75, 85, 92, 87, 93, 85, 213, 210, 202, - 130, 130, 136, 140, 143, 144, 134, 147, 136, 123, 119, 65, 28, 24, 41, 63, - 75, 75, 81, 106, 76, 52, 84, 124, 159, 234, 242, 240, 123, 106, 116, 127, - 140, 148, 166, 169, 167, 147, 67, 33, 25, 25, 29, 38, 24, 69, 102, 205, - 209, 233, 130, 150, 150, 150, 140, 134, 130, 128, 124, 114, 40, 37, 34, 56, - 56, 67, 65, 75, 88, 224, 221, 209, 114, 111, 120, 131, 144, 155, 159, 171, - 177, 178, 177, 173, 169, 162, 115, 37, 14, 17, 17, 14, 18, 24, 36, 46, - 52, 52, 45, 46, 45, 46, 49, 49, 52, 59, 100, 220, 237, 237, 230, 217, - 181, 147, 135, 138, 143, 151, 161, 170, 178, 190, 199, 202, 206, 208, 205, 189, - 193, 198, 199, 202, 205, 209, 208, 209, 206, 185, 181, 166, 157, 150, 135, 131, - 97, 37, 36, 44, 51, 68, 60, 61, 65, 48, 45, 64, 72, 71, 73, 87, - 201, 213, 202, 112, 108, 118, 132, 143, 157, 166, 170, 171, 171, 175, 174, 170, - 161, 119, 42, 20, 10, 12, 14, 16, 13, 14, 17, 17, 17, 8, 44, 52, - 45, 40, 41, 46, 41, 34, 48, 51, 48, 14, 53, 96, 120, 166, 144, 116, - 112, 131, 140, 158, 165, 171, 177, 186, 193, 204, 201, 199, 185, 208, 213, 213, - 214, 216, 199, 187, 185, 178, 171, 173, 163, 157, 155, 139, 127, 18, 12, 9, - 20, 6, 1, 169, 146, 148, 143, 124, 175, 225, 217, 130, 104, 114, 132, 148, - 155, 161, 162, 162, 159, 147, 131, 136, 130, 131, 115, 46, 45, 65, 75, 112, - 130, 116, 135, 81, 120, 179, 187, 185, 183, 183, 185, 190, 181, 169, 148, 134, - 42, 157, 194, 218, 218, 226, 197, 167, 153, 131, 91, 49, 135, 154, 158, 151, - 147, 148, 142, 148, 240, 241, 225, 99, 92, 103, 122, 135, 148, 166, 171, 171, - 165, 162, 151, 140, 131, 33, 28, 33, 61, 69, 79, 89, 107, 108, 76, 99, - 69, 131, 139, 157, 230, 226, 224, 131, 122, 128, 128, 146, 143, 166, 171, 185, - 178, 186, 183, 173, 169, 130, 56, 45, 37, 52, 65, 85, 119, 193, 209, 191, - 155, 153, 171, 183, 194, 197, 204, 205, 208, 205, 201, 186, 167, 79, 48, 42, - 49, 79, 106, 122, 130, 186, 225, 218, 187, 187, 185, 189, 189, 179, 163, 151, - 140, 131, 123, 111, 64, 61, 80, 79, 91, 126, 146, 123, 123, 136, 140, 201, - 237, 241, 245, 234, 159, 119, 119, 123, 130, 146, 144, 150, 81, 60, 46, 33, - 59, 57, 88, 112, 205, 201, 169, 170, 174, 166, 169, 169, 135, 128, 124, 99, - 60, 65, 81, 85, 81, 84, 95, 92, 64, 159, 173, 148, 159, 154, 158, 166, - 151, 138, 132, 81, 131, 166, 158, 143, 147, 144, 154, 150, 148, 150, 144, 92, - 0, 102, 102, 91, 85, 89, 106, 110, 93, 65, 63, 34, 108, 124, 110, 130, - 245, 242, 232, 110, 100, 114, 132, 142, 157, 165, 169, 174, 175, 162, 157, 146, - 136, 131, 130, 116, 14, 24, 29, 49, 80, 99, 106, 102, 93, 103, 91, 89, - 57, 103, 126, 110, 118, 122, 116, 114, 112, 130, 220, 226, 230, 226, 189, 127, - 102, 72, 65, 87, 81, 85, 89, 88, 217, 213, 209, 132, 130, 140, 142, 147, - 142, 135, 153, 134, 119, 115, 55, 26, 22, 38, 63, 75, 72, 81, 93, 81, - 46, 103, 120, 126, 232, 241, 237, 122, 107, 116, 126, 139, 147, 167, 167, 165, - 144, 49, 28, 24, 26, 30, 33, 21, 67, 103, 206, 208, 209, 148, 140, 144, - 143, 139, 132, 131, 124, 122, 107, 36, 32, 33, 52, 57, 63, 68, 69, 83, - 229, 224, 216, 116, 111, 122, 132, 142, 154, 161, 171, 177, 178, 173, 161, 166, - 140, 53, 14, 17, 18, 16, 25, 26, 26, 55, 60, 56, 53, 52, 55, 51, - 52, 59, 49, 46, 76, 183, 217, 233, 220, 197, 162, 138, 126, 134, 144, 159, - 171, 181, 187, 197, 206, 216, 218, 221, 222, 221, 218, 202, 197, 201, 194, 190, - 189, 213, 212, 210, 187, 182, 163, 159, 153, 139, 131, 107, 53, 34, 36, 60, - 59, 69, 61, 57, 48, 55, 40, 51, 67, 45, 73, 198, 217, 209, 112, 108, - 118, 134, 142, 158, 165, 169, 171, 173, 175, 170, 166, 140, 56, 18, 14, 13, - 16, 16, 18, 18, 17, 14, 17, 17, 8, 48, 52, 38, 40, 38, 42, 32, - 37, 55, 41, 55, 13, 51, 80, 102, 130, 163, 123, 112, 118, 135, 153, 163, - 169, 173, 181, 190, 199, 206, 206, 209, 212, 208, 212, 224, 213, 195, 189, 189, - 179, 174, 165, 165, 157, 155, 138, 124, 16, 12, 5, 12, 63, 72, 162, 135, - 144, 140, 135, 153, 213, 220, 144, 104, 112, 127, 144, 153, 157, 159, 166, 167, - 161, 150, 124, 124, 128, 122, 57, 44, 67, 69, 110, 127, 115, 118, 114, 85, - 165, 186, 187, 190, 187, 187, 186, 182, 165, 153, 139, 57, 195, 212, 228, 212, - 205, 201, 214, 165, 142, 93, 52, 130, 148, 147, 139, 142, 146, 135, 138, 241, - 241, 230, 103, 95, 99, 116, 132, 150, 165, 174, 173, 165, 162, 150, 140, 130, - 34, 28, 33, 65, 68, 77, 92, 108, 104, 102, 93, 72, 124, 139, 147, 230, - 229, 225, 130, 110, 119, 128, 135, 139, 155, 166, 178, 186, 187, 183, 170, 161, - 110, 49, 44, 36, 52, 77, 92, 115, 186, 217, 201, 159, 148, 161, 178, 187, - 197, 197, 202, 206, 208, 205, 198, 183, 108, 49, 44, 49, 79, 107, 115, 123, - 166, 225, 222, 191, 173, 183, 190, 179, 167, 146, 140, 142, 135, 124, 122, 79, - 61, 75, 75, 91, 124, 147, 132, 127, 132, 131, 209, 240, 242, 242, 193, 126, - 120, 127, 132, 132, 148, 151, 153, 76, 48, 44, 36, 52, 57, 77, 115, 208, - 209, 187, 167, 173, 170, 167, 171, 139, 136, 122, 96, 53, 56, 84, 71, 80, - 85, 100, 71, 97, 154, 159, 151, 146, 144, 151, 148, 150, 136, 111, 64, 139, - 165, 158, 144, 151, 144, 151, 151, 148, 142, 140, 83, 0, 106, 99, 96, 85, - 91, 76, 68, 65, 75, 64, 34, 111, 123, 116, 126, 241, 241, 226, 106, 100, - 114, 135, 146, 155, 165, 170, 169, 177, 175, 163, 155, 139, 124, 126, 114, 14, - 24, 34, 63, 79, 93, 106, 106, 110, 107, 88, 95, 57, 97, 127, 110, 107, - 118, 104, 118, 112, 138, 222, 233, 230, 179, 128, 118, 80, 64, 69, 80, 79, - 77, 84, 88, 218, 220, 216, 135, 130, 139, 146, 159, 148, 147, 150, 122, 118, - 111, 41, 25, 24, 37, 63, 71, 73, 81, 95, 81, 41, 112, 122, 104, 228, - 240, 236, 123, 106, 116, 127, 142, 148, 167, 166, 161, 136, 42, 26, 25, 29, - 28, 30, 24, 61, 111, 210, 216, 208, 143, 138, 140, 146, 139, 134, 132, 132, - 115, 104, 32, 29, 29, 48, 51, 53, 71, 81, 83, 229, 229, 220, 118, 112, - 123, 131, 143, 155, 162, 166, 178, 173, 167, 165, 155, 100, 28, 16, 18, 18, - 18, 17, 21, 26, 49, 64, 84, 83, 81, 79, 68, 57, 46, 59, 68, 131, - 220, 228, 213, 179, 144, 127, 126, 139, 148, 161, 174, 181, 190, 197, 204, 213, - 204, 154, 123, 150, 198, 222, 220, 205, 198, 193, 201, 202, 213, 209, 206, 186, - 178, 166, 159, 150, 135, 128, 114, 72, 36, 29, 51, 55, 68, 72, 57, 46, - 53, 48, 55, 68, 32, 87, 205, 220, 216, 115, 108, 120, 134, 142, 158, 165, - 170, 173, 174, 175, 167, 155, 99, 29, 18, 16, 16, 17, 21, 22, 18, 17, - 17, 18, 20, 12, 48, 57, 45, 40, 30, 36, 37, 52, 48, 38, 40, 12, - 52, 69, 88, 110, 162, 157, 114, 106, 127, 147, 159, 167, 173, 179, 190, 191, - 197, 205, 202, 204, 216, 220, 213, 202, 194, 191, 186, 181, 173, 166, 166, 157, - 154, 136, 123, 13, 9, 9, 17, 5, 10, 155, 166, 144, 136, 134, 119, 175, - 218, 175, 106, 108, 119, 136, 147, 153, 159, 169, 163, 165, 155, 124, 120, 130, - 126, 73, 44, 56, 76, 99, 127, 124, 128, 110, 84, 161, 185, 190, 186, 189, - 187, 187, 185, 169, 157, 135, 57, 201, 218, 225, 217, 220, 202, 195, 162, 138, - 88, 56, 124, 154, 147, 154, 142, 146, 135, 155, 241, 241, 233, 108, 95, 97, - 111, 138, 148, 165, 171, 171, 166, 161, 150, 142, 132, 37, 32, 25, 65, 72, - 67, 80, 107, 110, 114, 76, 48, 120, 134, 148, 230, 228, 221, 122, 108, 119, - 130, 126, 130, 144, 161, 174, 182, 181, 179, 165, 151, 84, 44, 42, 33, 55, - 88, 87, 112, 173, 217, 208, 163, 146, 151, 171, 182, 189, 194, 195, 199, 206, - 208, 199, 190, 151, 60, 46, 44, 75, 104, 114, 124, 150, 224, 225, 194, 174, - 185, 185, 177, 155, 144, 136, 143, 142, 127, 127, 92, 59, 67, 75, 87, 126, - 150, 128, 116, 119, 138, 217, 234, 242, 238, 159, 120, 127, 134, 138, 142, 151, - 154, 158, 72, 49, 42, 28, 53, 57, 77, 108, 208, 214, 206, 173, 173, 173, - 169, 174, 144, 140, 120, 93, 46, 49, 65, 79, 71, 83, 85, 83, 83, 161, - 158, 153, 147, 150, 151, 147, 157, 132, 99, 81, 108, 151, 157, 147, 150, 150, - 148, 150, 148, 148, 138, 83, 24, 103, 96, 96, 81, 88, 95, 71, 72, 84, - 56, 36, 120, 124, 116, 131, 240, 236, 179, 102, 100, 114, 134, 142, 151, 158, - 166, 169, 177, 177, 171, 161, 146, 126, 126, 118, 16, 26, 37, 72, 71, 95, - 99, 103, 108, 96, 92, 83, 55, 110, 119, 108, 111, 115, 110, 118, 116, 144, - 233, 236, 229, 150, 118, 102, 69, 60, 65, 80, 76, 76, 88, 97, 216, 220, - 216, 136, 130, 143, 166, 163, 163, 158, 148, 119, 118, 111, 37, 26, 25, 40, - 61, 72, 73, 83, 84, 68, 42, 79, 119, 131, 226, 238, 237, 126, 106, 118, - 126, 140, 148, 169, 167, 162, 128, 40, 26, 25, 30, 30, 33, 25, 61, 107, - 209, 214, 229, 122, 135, 136, 142, 134, 138, 142, 135, 114, 92, 30, 29, 30, - 49, 49, 49, 67, 64, 84, 234, 225, 218, 116, 112, 123, 134, 144, 157, 163, - 166, 177, 171, 165, 163, 142, 56, 18, 18, 18, 18, 24, 26, 22, 56, 61, - 79, 73, 75, 80, 88, 69, 51, 45, 56, 89, 204, 225, 222, 195, 135, 114, - 126, 136, 148, 161, 173, 179, 187, 190, 201, 206, 208, 111, 72, 67, 77, 112, - 161, 224, 213, 208, 194, 202, 210, 214, 212, 199, 182, 179, 171, 162, 150, 135, - 123, 118, 84, 41, 45, 51, 56, 63, 61, 56, 45, 56, 53, 51, 67, 46, - 72, 218, 221, 218, 116, 111, 122, 135, 143, 157, 165, 169, 171, 175, 170, 162, - 139, 59, 18, 14, 17, 20, 25, 22, 21, 17, 17, 22, 21, 22, 13, 53, - 61, 46, 44, 49, 44, 48, 53, 33, 40, 41, 10, 49, 65, 85, 89, 138, - 171, 122, 104, 123, 139, 157, 165, 173, 178, 185, 191, 194, 194, 193, 193, 197, - 204, 206, 202, 198, 198, 187, 178, 174, 165, 166, 158, 155, 138, 118, 12, 10, - 6, 25, 9, 9, 148, 147, 144, 130, 134, 122, 153, 206, 205, 111, 107, 115, - 124, 143, 154, 161, 170, 166, 167, 155, 120, 122, 130, 127, 100, 48, 51, 60, - 72, 95, 135, 124, 112, 79, 138, 186, 187, 186, 189, 186, 189, 185, 167, 153, - 144, 45, 212, 224, 225, 218, 202, 181, 155, 138, 127, 84, 55, 95, 148, 154, - 165, 138, 143, 136, 146, 242, 242, 234, 108, 97, 95, 114, 131, 144, 162, 170, - 171, 167, 158, 147, 143, 132, 37, 33, 38, 69, 75, 89, 93, 93, 103, 106, - 89, 72, 110, 130, 142, 229, 236, 225, 130, 118, 118, 123, 123, 126, 134, 147, - 162, 181, 181, 165, 163, 146, 69, 44, 38, 29, 53, 81, 85, 104, 163, 213, - 213, 178, 143, 144, 163, 174, 181, 187, 191, 194, 199, 204, 201, 190, 178, 87, - 45, 42, 75, 97, 114, 124, 142, 220, 225, 198, 173, 183, 187, 167, 150, 131, - 126, 130, 135, 130, 127, 107, 64, 59, 73, 81, 120, 139, 126, 116, 131, 140, - 216, 233, 241, 221, 144, 124, 131, 138, 136, 153, 157, 162, 165, 69, 49, 45, - 32, 53, 64, 71, 106, 208, 218, 214, 175, 174, 177, 170, 173, 147, 138, 120, - 92, 42, 44, 64, 64, 61, 71, 79, 32, 84, 154, 148, 151, 153, 153, 147, - 147, 162, 134, 93, 73, 140, 163, 146, 151, 153, 159, 163, 157, 146, 146, 144, - 63, 32, 79, 92, 93, 79, 85, 72, 71, 75, 68, 63, 37, 115, 123, 116, - 126, 237, 234, 165, 99, 97, 112, 122, 134, 144, 154, 165, 169, 179, 175, 171, - 161, 147, 126, 127, 119, 17, 28, 29, 52, 69, 80, 97, 103, 103, 97, 92, - 89, 53, 89, 116, 106, 107, 106, 104, 108, 116, 175, 244, 236, 220, 131, 114, - 95, 56, 59, 63, 76, 73, 75, 85, 96, 218, 220, 214, 136, 131, 142, 166, - 159, 163, 151, 153, 116, 118, 108, 38, 25, 25, 41, 61, 69, 75, 75, 79, - 69, 34, 80, 123, 128, 228, 238, 236, 123, 107, 114, 126, 142, 151, 169, 163, - 166, 127, 36, 25, 26, 34, 28, 42, 26, 57, 97, 206, 214, 210, 135, 130, - 132, 142, 136, 135, 138, 134, 112, 85, 28, 26, 29, 45, 48, 53, 61, 68, - 100, 233, 234, 221, 116, 111, 123, 134, 144, 158, 165, 167, 174, 169, 165, 161, - 112, 36, 18, 20, 21, 18, 22, 18, 16, 63, 67, 80, 95, 84, 71, 89, - 68, 61, 55, 64, 142, 216, 220, 212, 166, 111, 120, 134, 144, 159, 171, 174, - 185, 185, 194, 201, 209, 170, 80, 46, 33, 37, 55, 110, 204, 222, 213, 199, - 191, 213, 213, 210, 208, 193, 178, 173, 161, 148, 132, 118, 119, 93, 45, 44, - 45, 65, 56, 61, 69, 44, 55, 49, 59, 60, 36, 81, 218, 228, 218, 116, - 112, 122, 135, 140, 157, 165, 165, 169, 170, 165, 159, 112, 37, 17, 16, 21, - 24, 28, 25, 20, 18, 20, 25, 20, 22, 12, 49, 49, 56, 41, 52, 48, - 48, 48, 46, 41, 37, 14, 45, 61, 71, 72, 97, 162, 136, 103, 111, 134, - 151, 162, 170, 175, 182, 189, 197, 197, 198, 197, 195, 194, 198, 209, 199, 199, - 190, 182, 173, 167, 169, 158, 153, 136, 123, 13, 9, 6, 18, 12, 9, 136, - 134, 130, 132, 119, 119, 119, 173, 204, 136, 102, 107, 116, 140, 153, 159, 165, - 171, 163, 148, 128, 123, 131, 126, 116, 55, 56, 76, 72, 89, 128, 111, 130, - 89, 132, 169, 182, 190, 187, 190, 186, 179, 155, 155, 146, 52, 212, 229, 229, - 220, 167, 144, 127, 120, 103, 73, 55, 79, 132, 148, 159, 136, 135, 132, 148, - 241, 241, 230, 104, 95, 99, 119, 131, 142, 162, 167, 170, 165, 158, 148, 146, - 131, 40, 36, 38, 69, 75, 83, 83, 76, 99, 93, 95, 84, 91, 134, 155, - 233, 233, 226, 130, 120, 126, 122, 120, 124, 136, 151, 147, 157, 159, 154, 158, - 138, 53, 40, 36, 29, 49, 56, 79, 104, 134, 208, 213, 187, 140, 142, 154, - 167, 175, 177, 179, 186, 194, 201, 199, 195, 190, 114, 48, 41, 76, 89, 111, - 120, 132, 214, 225, 206, 177, 182, 187, 167, 158, 148, 147, 142, 127, 131, 123, - 114, 71, 59, 69, 67, 111, 131, 114, 111, 128, 134, 217, 236, 241, 190, 135, - 130, 135, 140, 138, 151, 157, 162, 165, 68, 46, 44, 30, 53, 61, 84, 102, - 208, 220, 220, 177, 178, 175, 166, 175, 150, 138, 123, 88, 42, 38, 46, 57, - 61, 67, 83, 52, 122, 155, 161, 157, 150, 158, 147, 151, 134, 134, 128, 67, - 134, 155, 163, 161, 167, 161, 158, 151, 157, 150, 136, 93, 0, 91, 93, 81, - 79, 76, 71, 68, 71, 69, 67, 36, 96, 122, 108, 127, 234, 229, 178, 103, - 102, 110, 114, 126, 135, 151, 163, 171, 175, 178, 165, 159, 143, 127, 132, 114, - 18, 28, 30, 52, 65, 81, 96, 100, 93, 106, 92, 87, 49, 91, 107, 110, - 97, 110, 108, 104, 124, 209, 240, 237, 216, 130, 114, 76, 55, 52, 61, 63, - 71, 65, 84, 92, 214, 220, 210, 134, 132, 144, 169, 163, 157, 151, 148, 119, - 118, 106, 33, 24, 28, 41, 57, 69, 72, 81, 80, 76, 30, 93, 118, 104, - 224, 237, 232, 122, 108, 119, 127, 142, 157, 169, 166, 163, 120, 41, 28, 25, - 22, 33, 38, 24, 48, 87, 206, 212, 202, 132, 128, 131, 142, 140, 130, 135, - 134, 114, 87, 25, 24, 22, 38, 46, 56, 59, 64, 87, 234, 228, 222, 116, - 111, 123, 135, 144, 158, 166, 169, 173, 163, 161, 148, 77, 22, 21, 22, 20, - 21, 28, 26, 16, 51, 69, 81, 89, 88, 72, 83, 71, 59, 55, 57, 166, - 212, 220, 202, 134, 107, 122, 135, 150, 163, 169, 181, 186, 190, 197, 202, 212, - 136, 53, 29, 28, 33, 51, 89, 167, 225, 214, 209, 186, 213, 217, 218, 209, - 197, 181, 173, 163, 148, 135, 123, 123, 108, 53, 45, 41, 45, 57, 61, 55, - 30, 53, 41, 71, 55, 45, 69, 212, 228, 226, 115, 110, 120, 134, 142, 155, - 166, 162, 170, 169, 163, 148, 84, 25, 18, 20, 21, 26, 24, 25, 25, 22, - 25, 24, 22, 22, 12, 49, 55, 40, 51, 52, 48, 49, 48, 48, 36, 34, - 6, 38, 52, 59, 72, 87, 128, 155, 118, 102, 122, 143, 159, 167, 177, 179, - 186, 193, 187, 186, 189, 199, 195, 190, 195, 208, 201, 191, 183, 177, 169, 170, - 159, 154, 143, 123, 8, 12, 8, 10, 16, 2, 127, 126, 126, 114, 104, 102, - 108, 142, 201, 185, 102, 106, 116, 139, 151, 158, 159, 158, 154, 150, 120, 122, - 123, 128, 131, 79, 55, 61, 69, 79, 122, 123, 126, 103, 104, 157, 169, 173, - 178, 167, 170, 171, 161, 158, 150, 64, 216, 230, 234, 198, 163, 126, 119, 123, - 93, 73, 60, 69, 88, 106, 120, 114, 135, 123, 136, 240, 240, 222, 104, 95, - 102, 116, 126, 138, 159, 170, 167, 165, 158, 146, 146, 130, 42, 38, 42, 65, - 75, 60, 84, 84, 69, 96, 104, 80, 85, 128, 147, 233, 233, 225, 131, 107, - 114, 130, 130, 128, 139, 142, 139, 151, 150, 153, 154, 134, 52, 41, 40, 29, - 51, 63, 83, 107, 120, 199, 214, 195, 147, 139, 144, 159, 167, 169, 173, 179, - 187, 194, 197, 194, 191, 148, 60, 44, 68, 85, 104, 110, 122, 205, 226, 214, - 178, 178, 187, 174, 163, 158, 151, 148, 144, 127, 120, 123, 91, 59, 68, 65, - 104, 131, 150, 124, 122, 124, 198, 237, 241, 185, 130, 135, 142, 144, 140, 151, - 161, 165, 166, 68, 48, 41, 30, 44, 57, 76, 107, 216, 221, 221, 177, 177, - 178, 170, 174, 151, 138, 126, 89, 41, 38, 44, 53, 77, 57, 87, 51, 115, - 128, 118, 127, 128, 130, 127, 131, 127, 127, 95, 53, 131, 146, 150, 143, 155, - 147, 139, 136, 148, 144, 126, 61, 0, 92, 76, 76, 69, 81, 72, 85, 69, - 77, 61, 34, 99, 118, 115, 124, 238, 237, 220, 106, 102, 106, 115, 114, 135, - 155, 165, 177, 179, 170, 159, 148, 132, 127, 124, 111, 22, 29, 33, 48, 68, - 79, 92, 96, 100, 102, 88, 84, 51, 89, 110, 108, 100, 102, 106, 108, 136, - 226, 238, 241, 217, 131, 110, 67, 51, 45, 71, 56, 68, 69, 72, 83, 214, - 213, 209, 130, 132, 143, 162, 157, 155, 146, 138, 119, 115, 100, 33, 22, 26, - 40, 51, 68, 71, 76, 96, 75, 28, 104, 118, 111, 220, 236, 228, 126, 110, - 118, 128, 144, 157, 163, 165, 166, 134, 49, 28, 28, 33, 33, 40, 25, 45, - 81, 206, 202, 199, 124, 131, 130, 142, 132, 134, 131, 134, 114, 81, 22, 24, - 21, 46, 42, 45, 48, 61, 83, 233, 230, 224, 118, 111, 120, 131, 144, 158, - 166, 171, 171, 161, 159, 144, 57, 21, 21, 21, 22, 20, 20, 29, 16, 69, - 75, 76, 68, 63, 71, 69, 68, 61, 51, 59, 173, 210, 202, 190, 118, 110, - 122, 135, 148, 170, 170, 183, 189, 189, 197, 202, 205, 122, 48, 33, 28, 28, - 41, 68, 142, 226, 218, 212, 194, 209, 213, 214, 213, 205, 182, 178, 163, 154, - 136, 126, 120, 114, 75, 48, 51, 46, 51, 63, 55, 44, 41, 38, 37, 36, - 34, 65, 198, 226, 226, 118, 110, 120, 134, 139, 155, 162, 161, 169, 166, 157, - 139, 63, 21, 18, 20, 24, 26, 29, 25, 24, 24, 22, 22, 22, 26, 16, - 42, 49, 51, 56, 52, 51, 51, 49, 51, 32, 36, 6, 37, 46, 60, 65, - 79, 87, 162, 136, 102, 112, 139, 154, 165, 174, 181, 183, 185, 186, 183, 186, - 190, 201, 201, 189, 197, 199, 195, 189, 178, 169, 171, 161, 157, 142, 123, 8, - 9, 8, 18, 13, 5, 127, 102, 114, 126, 92, 88, 84, 95, 146, 209, 128, - 102, 112, 128, 144, 150, 158, 159, 151, 132, 119, 120, 120, 124, 127, 110, 63, - 65, 73, 76, 91, 100, 99, 106, 124, 146, 127, 130, 138, 131, 134, 127, 162, - 157, 146, 56, 195, 230, 236, 182, 138, 124, 119, 116, 92, 67, 59, 72, 76, - 87, 92, 91, 92, 130, 136, 241, 238, 229, 108, 88, 96, 114, 115, 135, 151, - 162, 167, 165, 158, 144, 143, 132, 42, 38, 24, 61, 65, 68, 76, 57, 53, - 75, 89, 83, 75, 124, 136, 232, 233, 232, 127, 102, 114, 123, 131, 143, 144, - 140, 136, 142, 136, 151, 150, 128, 56, 38, 40, 24, 49, 52, 81, 91, 114, - 193, 214, 198, 147, 136, 139, 153, 159, 165, 167, 174, 182, 190, 193, 191, 189, - 169, 81, 48, 56, 81, 96, 108, 123, 193, 229, 220, 183, 173, 187, 190, 161, - 170, 165, 155, 150, 144, 130, 122, 116, 71, 64, 61, 96, 130, 140, 115, 107, - 128, 191, 225, 240, 171, 128, 138, 144, 147, 139, 153, 169, 171, 173, 75, 55, - 38, 29, 42, 55, 89, 116, 222, 225, 222, 182, 179, 178, 173, 174, 155, 142, - 128, 87, 38, 41, 41, 44, 48, 46, 60, 71, 71, 103, 103, 107, 108, 116, - 110, 100, 124, 123, 60, 61, 51, 122, 110, 96, 89, 116, 95, 83, 77, 110, - 76, 14, 51, 75, 64, 45, 48, 56, 48, 44, 44, 61, 49, 37, 89, 104, - 118, 135, 240, 234, 228, 107, 106, 110, 114, 122, 136, 162, 165, 170, 177, 173, - 162, 147, 120, 130, 131, 108, 25, 33, 34, 41, 52, 61, 79, 89, 92, 89, - 85, 84, 46, 92, 99, 104, 95, 96, 99, 111, 155, 242, 245, 241, 198, 127, - 111, 60, 48, 44, 59, 67, 57, 63, 73, 80, 216, 218, 212, 135, 134, 142, - 155, 157, 155, 154, 119, 120, 115, 97, 28, 24, 24, 42, 45, 61, 69, 73, - 79, 64, 38, 60, 106, 107, 212, 232, 229, 126, 112, 120, 130, 146, 157, 169, - 167, 166, 142, 55, 30, 29, 32, 26, 34, 24, 63, 96, 199, 210, 210, 131, - 128, 126, 135, 135, 132, 130, 126, 111, 73, 24, 20, 21, 38, 32, 37, 46, - 61, 77, 233, 232, 228, 120, 114, 119, 127, 144, 159, 167, 171, 171, 161, 159, - 142, 49, 21, 24, 24, 37, 28, 22, 30, 22, 65, 73, 63, 71, 68, 65, - 61, 69, 60, 53, 56, 171, 205, 202, 166, 104, 111, 120, 131, 151, 167, 170, - 177, 181, 189, 193, 199, 212, 114, 46, 36, 32, 32, 32, 52, 134, 229, 222, - 214, 194, 199, 213, 212, 220, 212, 195, 177, 166, 154, 144, 135, 119, 119, 88, - 53, 56, 37, 40, 45, 37, 45, 29, 17, 26, 20, 30, 68, 182, 221, 228, - 116, 110, 122, 134, 139, 155, 163, 163, 166, 163, 155, 132, 55, 25, 18, 24, - 32, 28, 32, 25, 28, 28, 29, 28, 30, 28, 17, 22, 41, 61, 28, 32, - 42, 44, 40, 45, 37, 33, 6, 36, 37, 42, 40, 65, 69, 100, 151, 104, - 100, 130, 147, 161, 170, 177, 178, 182, 181, 185, 186, 189, 191, 199, 198, 190, - 195, 194, 190, 182, 173, 171, 162, 158, 144, 124, 9, 9, 6, 10, 4, 2, - 87, 99, 104, 104, 110, 118, 120, 134, 97, 181, 190, 111, 107, 112, 132, 144, - 148, 154, 148, 136, 126, 120, 112, 126, 130, 130, 80, 65, 61, 61, 63, 63, - 60, 59, 65, 68, 71, 84, 89, 97, 104, 107, 131, 153, 154, 59, 201, 232, - 232, 170, 130, 118, 118, 115, 91, 64, 46, 55, 73, 72, 72, 79, 80, 119, - 111, 241, 237, 226, 107, 99, 95, 114, 128, 127, 144, 159, 170, 165, 155, 144, - 146, 126, 42, 46, 45, 56, 60, 71, 68, 72, 73, 93, 65, 69, 76, 119, - 140, 232, 234, 225, 131, 114, 116, 126, 130, 143, 136, 139, 135, 138, 136, 150, - 146, 124, 52, 49, 38, 32, 73, 91, 88, 104, 110, 186, 210, 206, 153, 132, - 136, 148, 155, 159, 166, 170, 175, 183, 189, 190, 190, 181, 104, 51, 45, 65, - 88, 102, 115, 175, 229, 224, 186, 173, 179, 189, 186, 154, 170, 161, 157, 144, - 144, 131, 126, 95, 61, 67, 89, 106, 111, 99, 111, 123, 162, 230, 238, 171, - 132, 139, 148, 146, 146, 161, 171, 175, 179, 81, 60, 48, 36, 67, 85, 93, - 127, 226, 228, 226, 189, 179, 182, 174, 174, 159, 144, 126, 95, 34, 33, 36, - 13, 13, 9, 12, 13, 34, 36, 16, 14, 32, 33, 25, 25, 36, 41, 36, - 61, 30, 30, 18, 24, 29, 32, 9, 22, 30, 34, 6, 24, 76, 22, 51, - 64, 71, 75, 84, 84, 87, 85, 88, 40, 118, 112, 120, 143, 238, 240, 229, - 107, 106, 112, 118, 127, 142, 158, 161, 166, 170, 174, 161, 146, 124, 130, 127, - 103, 29, 34, 34, 42, 53, 53, 55, 57, 60, 72, 68, 56, 46, 85, 91, - 84, 81, 93, 107, 107, 202, 242, 246, 238, 173, 122, 107, 53, 45, 38, 36, - 40, 44, 51, 71, 79, 221, 224, 208, 131, 127, 124, 147, 154, 153, 146, 118, - 110, 118, 89, 25, 22, 26, 36, 44, 55, 59, 59, 64, 57, 33, 41, 104, - 112, 206, 228, 228, 127, 114, 122, 130, 146, 155, 169, 171, 170, 148, 73, 34, - 29, 34, 24, 29, 44, 75, 124, 208, 214, 197, 128, 124, 123, 131, 131, 135, - 131, 123, 110, 67, 21, 18, 17, 25, 28, 30, 49, 63, 68, 233, 236, 230, - 118, 110, 118, 127, 144, 159, 167, 174, 170, 159, 157, 143, 46, 22, 22, 25, - 26, 37, 32, 24, 17, 44, 49, 44, 45, 56, 55, 46, 46, 55, 56, 61, - 159, 204, 187, 143, 99, 111, 118, 131, 150, 169, 177, 183, 178, 189, 190, 193, - 208, 136, 52, 37, 25, 33, 38, 61, 138, 226, 224, 218, 195, 183, 209, 213, - 213, 212, 198, 177, 169, 158, 153, 138, 118, 119, 102, 59, 61, 49, 41, 38, - 33, 12, 21, 17, 22, 20, 26, 80, 175, 229, 225, 118, 112, 123, 134, 139, - 155, 163, 163, 169, 162, 154, 134, 55, 22, 22, 29, 21, 20, 16, 14, 14, - 12, 10, 10, 10, 6, 17, 21, 13, 21, 18, 16, 12, 14, 24, 34, 34, - 25, 8, 37, 36, 38, 36, 34, 40, 72, 135, 120, 95, 123, 143, 157, 166, - 171, 174, 174, 173, 174, 175, 178, 187, 194, 202, 191, 191, 199, 191, 183, 173, - 173, 162, 159, 146, 127, 6, 6, 6, 10, 5, 4, 197, 191, 183, 179, 179, - 177, 179, 126, 138, 135, 194, 136, 104, 108, 115, 130, 146, 144, 143, 132, 139, - 139, 126, 115, 124, 130, 120, 76, 75, 93, 99, 104, 97, 104, 106, 123, 136, - 126, 132, 126, 106, 110, 95, 104, 143, 64, 187, 232, 233, 191, 128, 118, 116, - 106, 83, 55, 56, 52, 79, 102, 115, 115, 114, 124, 132, 228, 234, 224, 102, - 91, 104, 118, 116, 120, 131, 154, 167, 159, 153, 140, 143, 128, 41, 42, 48, - 30, 34, 40, 40, 30, 48, 67, 44, 40, 118, 110, 163, 230, 232, 226, 128, - 118, 126, 132, 130, 140, 127, 148, 143, 140, 134, 148, 142, 118, 51, 49, 38, - 45, 81, 95, 99, 110, 111, 173, 216, 202, 158, 132, 134, 142, 151, 155, 162, - 165, 170, 179, 186, 189, 185, 185, 132, 55, 56, 65, 95, 107, 126, 167, 225, - 226, 187, 171, 177, 185, 189, 181, 154, 169, 163, 157, 147, 144, 127, 120, 76, - 65, 69, 73, 79, 96, 115, 122, 154, 222, 229, 175, 135, 144, 154, 142, 143, - 159, 178, 181, 183, 92, 52, 44, 25, 61, 88, 102, 162, 229, 229, 225, 185, - 183, 179, 171, 171, 159, 143, 127, 93, 40, 36, 38, 29, 53, 33, 56, 38, - 112, 124, 119, 106, 116, 120, 119, 107, 119, 120, 63, 37, 51, 138, 132, 114, - 114, 134, 126, 111, 108, 108, 103, 72, 32, 52, 118, 134, 138, 131, 135, 130, - 132, 93, 84, 37, 119, 123, 122, 182, 236, 240, 218, 106, 106, 110, 119, 131, - 144, 153, 153, 151, 158, 170, 162, 148, 128, 136, 138, 106, 34, 38, 41, 57, - 67, 69, 49, 68, 69, 67, 60, 72, 65, 76, 81, 92, 95, 99, 112, 169, - 237, 244, 246, 240, 150, 116, 103, 49, 42, 38, 41, 45, 56, 61, 75, 91, - 220, 222, 212, 130, 127, 130, 136, 142, 154, 143, 119, 115, 119, 99, 28, 24, - 28, 40, 45, 42, 44, 48, 38, 57, 25, 48, 89, 103, 202, 224, 221, 130, - 114, 122, 130, 142, 155, 163, 167, 169, 157, 95, 38, 32, 28, 33, 34, 59, - 87, 185, 221, 222, 208, 126, 124, 127, 128, 127, 139, 136, 116, 110, 57, 21, - 17, 24, 38, 40, 49, 56, 67, 83, 232, 230, 230, 119, 110, 122, 134, 144, - 158, 169, 173, 167, 159, 153, 144, 51, 25, 29, 40, 46, 55, 52, 26, 22, - 25, 24, 33, 25, 29, 25, 30, 21, 30, 25, 37, 147, 199, 191, 128, 99, - 112, 118, 128, 132, 166, 177, 174, 177, 181, 191, 197, 206, 154, 65, 41, 32, - 48, 40, 83, 143, 228, 225, 222, 193, 179, 199, 212, 210, 208, 199, 182, 177, - 158, 161, 143, 128, 120, 111, 68, 55, 64, 61, 57, 41, 9, 25, 89, 120, - 93, 91, 128, 194, 216, 222, 114, 111, 120, 134, 132, 151, 159, 166, 162, 161, - 153, 136, 59, 26, 26, 41, 46, 68, 83, 88, 88, 84, 93, 91, 84, 37, - 16, 53, 73, 72, 63, 67, 67, 49, 26, 14, 13, 25, 24, 14, 18, 20, - 25, 25, 18, 34, 104, 132, 100, 100, 138, 144, 155, 162, 157, 159, 154, 154, - 143, 150, 148, 186, 201, 209, 183, 197, 191, 182, 171, 171, 161, 158, 146, 122, - 6, 6, 6, 6, 22, 24, 198, 187, 193, 186, 182, 194, 148, 173, 140, 60, - 194, 171, 112, 107, 107, 108, 119, 131, 134, 144, 135, 132, 140, 131, 122, 134, - 134, 110, 80, 80, 75, 96, 108, 106, 115, 126, 158, 135, 150, 148, 138, 120, - 146, 150, 143, 88, 208, 234, 237, 190, 126, 112, 111, 95, 69, 51, 55, 53, - 97, 111, 112, 116, 115, 126, 128, 212, 226, 222, 96, 89, 104, 118, 118, 118, - 127, 140, 163, 159, 153, 138, 143, 131, 52, 48, 46, 34, 57, 75, 102, 110, - 114, 122, 118, 116, 102, 122, 213, 217, 222, 225, 127, 110, 118, 118, 132, 142, - 120, 132, 142, 146, 138, 146, 144, 123, 46, 42, 41, 41, 88, 88, 99, 100, - 110, 161, 209, 204, 167, 131, 131, 132, 144, 154, 161, 167, 169, 177, 183, 185, - 181, 183, 158, 77, 53, 60, 106, 114, 122, 155, 220, 226, 193, 167, 173, 182, - 189, 189, 163, 153, 167, 169, 159, 154, 139, 127, 107, 84, 84, 88, 114, 120, - 122, 128, 139, 209, 226, 177, 142, 147, 157, 140, 146, 161, 183, 189, 186, 138, - 72, 48, 22, 68, 95, 114, 187, 233, 230, 228, 183, 181, 181, 173, 170, 159, - 143, 127, 85, 37, 34, 38, 63, 55, 59, 64, 38, 131, 139, 124, 110, 107, - 116, 103, 107, 112, 123, 75, 29, 106, 139, 128, 131, 131, 128, 132, 124, 130, - 123, 126, 76, 28, 115, 136, 132, 132, 127, 128, 116, 124, 106, 99, 37, 126, - 126, 124, 199, 240, 241, 221, 106, 103, 108, 118, 134, 147, 159, 155, 140, 151, - 153, 148, 124, 124, 139, 139, 106, 36, 40, 40, 64, 49, 60, 69, 73, 80, - 85, 85, 79, 88, 100, 103, 110, 116, 124, 155, 214, 244, 245, 242, 218, 127, - 118, 80, 44, 37, 37, 49, 53, 56, 68, 72, 96, 222, 228, 221, 123, 122, - 131, 115, 131, 132, 131, 114, 120, 118, 104, 29, 24, 26, 45, 49, 65, 69, - 69, 61, 59, 20, 112, 107, 111, 183, 221, 216, 135, 115, 122, 130, 142, 150, - 166, 167, 171, 170, 135, 52, 38, 33, 37, 56, 72, 103, 197, 222, 224, 208, - 126, 124, 126, 122, 132, 130, 127, 116, 100, 34, 18, 14, 28, 45, 52, 53, - 64, 63, 89, 232, 232, 232, 120, 112, 122, 131, 144, 158, 167, 173, 163, 153, - 148, 136, 61, 33, 26, 40, 60, 68, 67, 52, 17, 32, 106, 107, 97, 96, - 106, 100, 93, 95, 99, 64, 132, 190, 185, 118, 100, 114, 119, 124, 124, 153, - 158, 178, 173, 170, 183, 194, 197, 198, 114, 56, 48, 55, 63, 131, 201, 229, - 226, 222, 187, 177, 193, 204, 204, 202, 199, 175, 175, 166, 157, 155, 136, 122, - 122, 73, 76, 93, 132, 122, 46, 16, 75, 131, 119, 128, 150, 158, 210, 220, - 209, 115, 110, 120, 131, 127, 147, 157, 163, 165, 157, 150, 135, 65, 30, 25, - 45, 80, 95, 93, 87, 92, 93, 93, 93, 96, 63, 22, 67, 81, 80, 80, - 75, 76, 72, 71, 59, 29, 21, 22, 38, 88, 95, 61, 75, 83, 68, 38, - 144, 120, 91, 115, 128, 136, 142, 144, 123, 124, 131, 71, 57, 81, 165, 199, - 213, 190, 187, 190, 179, 170, 170, 159, 153, 143, 116, 5, 8, 9, 17, 57, - 64, 186, 183, 161, 187, 185, 173, 140, 171, 139, 60, 182, 177, 116, 108, 106, - 104, 103, 104, 112, 134, 148, 139, 131, 139, 124, 120, 126, 131, 104, 81, 89, - 103, 73, 99, 112, 155, 147, 140, 154, 138, 132, 122, 147, 111, 89, 146, 226, - 237, 232, 202, 127, 110, 104, 85, 61, 46, 56, 46, 95, 110, 104, 108, 111, - 123, 162, 229, 225, 204, 102, 99, 108, 119, 124, 118, 124, 132, 151, 155, 146, - 130, 146, 132, 49, 51, 22, 83, 83, 93, 97, 111, 123, 118, 116, 103, 115, - 136, 232, 228, 226, 212, 130, 103, 111, 120, 144, 147, 130, 119, 127, 135, 134, - 144, 144, 123, 60, 40, 40, 40, 88, 93, 112, 95, 104, 144, 201, 199, 166, - 132, 130, 130, 143, 147, 158, 163, 161, 170, 175, 182, 177, 177, 170, 99, 56, - 51, 97, 115, 122, 140, 205, 222, 201, 167, 170, 179, 187, 191, 183, 153, 154, - 169, 173, 162, 153, 138, 130, 104, 108, 110, 116, 116, 112, 126, 130, 193, 230, - 179, 142, 153, 161, 140, 143, 173, 185, 190, 191, 163, 63, 51, 41, 81, 103, - 122, 197, 234, 232, 228, 185, 182, 173, 173, 171, 162, 143, 124, 81, 36, 36, - 36, 53, 76, 83, 63, 41, 123, 143, 131, 142, 134, 132, 142, 131, 123, 120, - 77, 59, 134, 143, 128, 124, 120, 114, 110, 123, 114, 103, 122, 56, 26, 118, - 136, 127, 118, 112, 118, 123, 127, 99, 91, 40, 124, 127, 128, 218, 238, 234, - 216, 110, 104, 110, 114, 126, 150, 159, 161, 159, 151, 136, 130, 119, 131, 138, - 144, 111, 65, 41, 42, 68, 52, 64, 77, 81, 76, 76, 80, 79, 95, 115, - 123, 131, 123, 151, 209, 241, 246, 245, 238, 161, 123, 115, 67, 42, 40, 34, - 51, 56, 57, 67, 72, 96, 222, 225, 220, 131, 131, 126, 132, 116, 110, 106, - 112, 123, 112, 103, 29, 28, 25, 48, 63, 76, 77, 72, 76, 53, 21, 106, - 118, 107, 157, 212, 217, 151, 116, 123, 130, 142, 148, 159, 166, 163, 170, 153, - 108, 60, 60, 65, 87, 112, 174, 198, 221, 216, 217, 126, 123, 126, 124, 124, - 132, 118, 112, 71, 24, 18, 16, 30, 44, 51, 61, 71, 71, 102, 229, 230, - 229, 119, 114, 123, 136, 146, 158, 169, 173, 162, 155, 151, 138, 75, 34, 28, - 45, 65, 63, 64, 68, 18, 116, 118, 110, 104, 102, 111, 108, 100, 106, 95, - 69, 77, 179, 177, 116, 104, 115, 118, 122, 127, 131, 166, 175, 182, 161, 177, - 183, 194, 205, 161, 85, 61, 77, 122, 143, 220, 225, 226, 222, 189, 171, 178, - 189, 185, 187, 189, 179, 174, 169, 165, 162, 153, 127, 120, 84, 91, 130, 139, - 135, 38, 10, 84, 134, 122, 144, 150, 162, 216, 222, 217, 110, 108, 120, 131, - 122, 138, 158, 169, 162, 154, 146, 135, 91, 36, 29, 49, 85, 84, 89, 83, - 93, 89, 79, 81, 93, 96, 22, 71, 80, 73, 56, 48, 46, 48, 53, 71, - 46, 22, 16, 85, 85, 85, 87, 89, 75, 68, 63, 44, 48, 52, 75, 104, - 99, 108, 92, 68, 45, 42, 32, 36, 69, 143, 201, 213, 197, 181, 189, 177, - 171, 171, 158, 151, 143, 108, 4, 8, 13, 26, 41, 44, 191, 173, 166, 171, - 163, 169, 143, 138, 131, 64, 185, 177, 136, 119, 107, 103, 104, 104, 100, 108, - 134, 151, 138, 128, 138, 120, 130, 122, 132, 104, 99, 99, 93, 89, 107, 151, - 138, 132, 127, 127, 123, 116, 120, 134, 171, 208, 233, 232, 229, 186, 124, 108, - 88, 65, 53, 45, 51, 45, 75, 103, 108, 100, 110, 130, 209, 229, 228, 208, - 106, 99, 108, 123, 124, 139, 124, 119, 135, 150, 148, 139, 140, 123, 55, 51, - 38, 79, 85, 83, 110, 97, 95, 99, 95, 99, 112, 183, 220, 225, 228, 217, - 131, 123, 110, 119, 135, 134, 147, 135, 119, 119, 130, 135, 144, 126, 64, 37, - 34, 40, 91, 106, 99, 100, 106, 134, 191, 198, 165, 126, 131, 126, 139, 146, - 154, 162, 159, 161, 166, 171, 177, 171, 173, 128, 63, 68, 102, 107, 123, 134, - 175, 222, 208, 166, 165, 177, 189, 190, 190, 174, 148, 153, 170, 167, 161, 150, - 132, 128, 126, 120, 107, 110, 115, 118, 119, 151, 220, 190, 148, 151, 167, 143, - 144, 178, 189, 197, 198, 182, 89, 56, 41, 52, 106, 128, 210, 234, 234, 230, - 179, 179, 174, 170, 174, 163, 142, 118, 57, 34, 34, 24, 59, 60, 72, 69, - 51, 79, 102, 139, 96, 134, 131, 127, 124, 130, 119, 80, 57, 92, 143, 128, - 135, 110, 114, 124, 108, 112, 112, 112, 64, 24, 115, 130, 116, 123, 128, 122, - 124, 104, 95, 95, 52, 111, 118, 136, 225, 237, 237, 214, 112, 108, 111, 112, - 123, 144, 158, 166, 158, 153, 150, 146, 128, 134, 143, 144, 118, 95, 44, 45, - 67, 46, 59, 60, 67, 69, 71, 69, 93, 96, 124, 130, 126, 153, 198, 236, - 244, 248, 245, 225, 132, 119, 107, 56, 40, 36, 37, 51, 53, 60, 68, 83, - 127, 205, 216, 221, 132, 116, 123, 124, 115, 119, 108, 108, 119, 120, 103, 30, - 24, 34, 38, 40, 77, 81, 71, 68, 63, 17, 111, 115, 104, 120, 197, 214, - 183, 122, 119, 131, 138, 147, 153, 165, 163, 174, 175, 155, 114, 115, 135, 165, - 190, 205, 197, 226, 210, 210, 127, 124, 126, 126, 134, 124, 114, 91, 30, 17, - 17, 21, 41, 40, 46, 65, 67, 71, 103, 224, 232, 225, 118, 108, 118, 128, - 146, 158, 167, 171, 162, 154, 148, 139, 114, 42, 28, 46, 59, 61, 60, 55, - 18, 122, 120, 134, 118, 108, 111, 93, 93, 102, 107, 89, 55, 130, 177, 126, - 97, 114, 119, 123, 130, 126, 151, 158, 171, 158, 169, 175, 189, 197, 206, 170, - 138, 158, 185, 217, 225, 226, 221, 222, 185, 170, 166, 178, 181, 178, 183, 181, - 181, 174, 165, 155, 162, 146, 124, 88, 99, 119, 146, 126, 33, 12, 71, 118, - 135, 134, 148, 175, 220, 216, 221, 111, 108, 120, 134, 127, 144, 158, 167, 162, - 154, 143, 136, 112, 46, 36, 48, 84, 84, 84, 92, 100, 97, 92, 79, 95, - 68, 30, 63, 77, 72, 51, 53, 52, 42, 41, 68, 56, 25, 16, 89, 76, - 80, 77, 71, 71, 57, 49, 49, 42, 45, 38, 41, 53, 48, 33, 30, 33, - 28, 22, 38, 69, 150, 209, 220, 198, 177, 187, 181, 174, 170, 161, 148, 140, - 99, 2, 6, 12, 28, 4, 2, 190, 171, 179, 173, 170, 163, 183, 144, 130, - 59, 187, 173, 142, 106, 115, 114, 106, 106, 104, 100, 111, 132, 142, 139, 136, - 134, 114, 124, 124, 131, 123, 115, 124, 119, 136, 136, 154, 146, 135, 132, 130, - 135, 173, 208, 228, 234, 236, 232, 208, 170, 112, 97, 75, 56, 42, 45, 51, - 52, 88, 100, 103, 110, 112, 158, 222, 218, 229, 205, 96, 95, 110, 119, 120, - 136, 115, 118, 123, 143, 138, 136, 140, 124, 59, 56, 71, 106, 102, 80, 91, - 84, 102, 95, 95, 91, 112, 195, 226, 224, 216, 193, 132, 111, 118, 134, 148, - 144, 153, 153, 140, 120, 118, 134, 142, 127, 64, 48, 49, 48, 89, 99, 102, - 95, 102, 107, 189, 199, 175, 130, 124, 124, 138, 143, 150, 159, 165, 153, 153, - 158, 159, 169, 170, 147, 92, 67, 65, 93, 118, 124, 159, 216, 217, 167, 163, - 174, 183, 187, 191, 190, 178, 144, 154, 173, 167, 157, 150, 139, 128, 128, 135, - 116, 104, 111, 122, 130, 194, 214, 163, 154, 166, 142, 146, 183, 193, 204, 202, - 195, 150, 87, 51, 53, 115, 165, 221, 233, 234, 232, 186, 182, 169, 170, 171, - 162, 134, 107, 40, 34, 33, 29, 65, 61, 68, 72, 53, 57, 138, 144, 135, - 138, 135, 128, 128, 126, 115, 79, 64, 93, 144, 112, 119, 110, 128, 116, 107, - 115, 112, 111, 71, 28, 116, 132, 112, 110, 110, 97, 112, 102, 91, 73, 77, - 112, 124, 179, 226, 242, 234, 213, 112, 111, 116, 107, 118, 139, 153, 162, 167, - 162, 155, 147, 140, 124, 130, 147, 134, 103, 46, 48, 52, 59, 60, 76, 80, - 75, 71, 76, 88, 108, 128, 127, 142, 189, 233, 241, 246, 246, 244, 170, 120, - 119, 95, 44, 36, 24, 40, 46, 55, 67, 69, 83, 179, 208, 214, 206, 127, - 120, 126, 128, 118, 118, 119, 103, 107, 119, 108, 34, 25, 26, 37, 63, 75, - 81, 64, 67, 61, 14, 106, 114, 107, 108, 134, 201, 198, 127, 120, 127, 135, - 143, 146, 153, 150, 177, 181, 178, 169, 185, 198, 201, 208, 206, 213, 202, 212, - 163, 127, 127, 134, 136, 130, 119, 114, 38, 20, 17, 14, 28, 38, 44, 51, - 61, 65, 72, 173, 226, 228, 226, 118, 104, 118, 126, 143, 153, 165, 165, 167, - 159, 153, 147, 140, 61, 38, 36, 60, 63, 61, 57, 22, 88, 123, 135, 127, - 119, 130, 112, 112, 106, 99, 106, 55, 76, 171, 142, 100, 104, 118, 122, 124, - 127, 132, 158, 161, 157, 165, 169, 182, 189, 204, 213, 208, 217, 218, 225, 222, - 221, 226, 209, 186, 165, 166, 143, 165, 171, 181, 182, 181, 181, 170, 169, 161, - 162, 142, 118, 100, 132, 143, 69, 29, 10, 63, 118, 119, 124, 135, 158, 217, - 228, 217, 112, 107, 118, 130, 122, 151, 158, 163, 158, 155, 146, 139, 126, 67, - 37, 56, 83, 80, 89, 91, 93, 92, 93, 96, 80, 80, 26, 53, 76, 68, - 44, 51, 37, 38, 46, 48, 48, 25, 18, 48, 72, 46, 60, 61, 69, 48, - 42, 40, 37, 32, 38, 36, 40, 30, 26, 30, 26, 29, 26, 64, 71, 173, - 214, 221, 187, 173, 185, 179, 174, 171, 162, 146, 135, 52, 2, 6, 13, 38, - 2, 1, 189, 177, 161, 169, 170, 163, 159, 162, 130, 52, 177, 169, 140, 127, - 103, 100, 118, 110, 104, 103, 102, 107, 134, 146, 142, 143, 135, 118, 116, 136, - 158, 144, 139, 143, 150, 154, 159, 166, 170, 171, 185, 206, 224, 230, 236, 234, - 229, 217, 187, 124, 103, 77, 61, 48, 41, 49, 53, 73, 92, 88, 100, 111, - 154, 190, 229, 232, 229, 213, 111, 95, 103, 115, 131, 134, 120, 124, 119, 130, - 131, 139, 144, 131, 107, 88, 61, 93, 106, 108, 89, 88, 97, 119, 95, 102, - 130, 209, 220, 220, 220, 163, 118, 120, 124, 131, 136, 151, 150, 153, 151, 139, - 115, 124, 138, 132, 107, 60, 55, 51, 95, 83, 97, 93, 99, 100, 175, 198, - 177, 127, 120, 124, 136, 146, 151, 157, 162, 151, 150, 144, 144, 154, 163, 155, - 110, 65, 45, 81, 111, 126, 147, 202, 217, 174, 161, 173, 181, 185, 187, 187, - 190, 178, 150, 154, 169, 166, 157, 150, 144, 132, 132, 135, 118, 111, 120, 126, - 158, 222, 177, 155, 163, 147, 183, 187, 202, 208, 205, 206, 190, 123, 64, 69, - 126, 191, 233, 233, 234, 226, 181, 179, 177, 171, 170, 150, 135, 88, 36, 33, - 34, 46, 65, 71, 57, 76, 65, 55, 128, 143, 134, 138, 128, 128, 136, 126, - 123, 87, 67, 97, 138, 127, 119, 114, 119, 100, 115, 111, 111, 115, 68, 18, - 122, 130, 106, 112, 104, 107, 93, 75, 77, 108, 99, 112, 131, 216, 236, 230, - 238, 202, 115, 116, 116, 118, 110, 127, 150, 159, 162, 163, 159, 155, 148, 135, - 138, 131, 154, 118, 102, 85, 83, 92, 95, 96, 96, 104, 104, 100, 99, 118, - 134, 127, 186, 229, 233, 238, 245, 242, 220, 126, 122, 114, 65, 41, 36, 30, - 44, 49, 61, 67, 76, 179, 209, 208, 216, 198, 114, 128, 135, 124, 130, 131, - 134, 124, 104, 120, 115, 46, 22, 25, 53, 60, 63, 77, 81, 60, 56, 13, - 103, 107, 104, 110, 110, 138, 198, 136, 120, 124, 128, 134, 135, 136, 138, 140, - 155, 185, 183, 193, 195, 206, 212, 213, 202, 208, 189, 127, 126, 134, 135, 132, - 122, 120, 59, 20, 17, 16, 13, 37, 44, 48, 64, 65, 68, 93, 206, 220, - 226, 224, 119, 107, 115, 123, 135, 148, 162, 165, 166, 162, 151, 144, 127, 110, - 53, 34, 37, 64, 61, 59, 28, 84, 123, 135, 112, 123, 130, 95, 123, 104, - 99, 97, 63, 51, 159, 175, 108, 95, 112, 122, 124, 123, 124, 140, 142, 154, - 166, 171, 173, 179, 185, 201, 198, 208, 214, 216, 220, 217, 210, 194, 177, 165, - 142, 140, 139, 144, 165, 171, 181, 179, 175, 165, 163, 165, 162, 134, 107, 140, - 96, 36, 14, 12, 59, 112, 122, 134, 144, 166, 218, 221, 220, 118, 108, 116, - 124, 124, 159, 159, 161, 158, 155, 146, 135, 126, 110, 49, 63, 87, 92, 83, - 85, 89, 89, 95, 93, 99, 91, 40, 48, 77, 68, 46, 38, 46, 46, 46, - 45, 45, 24, 18, 75, 69, 65, 59, 48, 49, 40, 45, 40, 49, 40, 34, - 42, 36, 33, 28, 28, 22, 26, 20, 59, 84, 202, 217, 220, 166, 167, 185, - 183, 174, 169, 161, 144, 132, 42, 2, 4, 12, 32, 4, 10, 181, 182, 162, - 165, 173, 174, 154, 165, 130, 60, 170, 167, 143, 130, 122, 111, 91, 96, 114, - 112, 107, 103, 104, 127, 147, 139, 130, 123, 131, 151, 163, 177, 181, 189, 194, - 193, 201, 198, 204, 216, 218, 225, 228, 230, 229, 218, 217, 181, 136, 102, 76, - 63, 51, 44, 45, 63, 75, 88, 81, 106, 144, 171, 187, 212, 220, 226, 229, - 209, 118, 89, 112, 106, 115, 131, 146, 148, 131, 122, 120, 144, 144, 143, 130, - 119, 122, 124, 130, 123, 108, 97, 85, 115, 95, 104, 169, 208, 224, 221, 204, - 161, 127, 115, 116, 132, 147, 154, 143, 155, 155, 147, 136, 118, 131, 134, 120, - 100, 65, 64, 96, 99, 93, 93, 89, 97, 154, 202, 177, 126, 119, 127, 140, - 146, 151, 159, 142, 136, 132, 130, 130, 134, 148, 154, 135, 97, 72, 61, 93, - 115, 138, 174, 212, 185, 158, 163, 174, 179, 182, 181, 185, 185, 171, 151, 162, - 169, 161, 157, 144, 134, 132, 132, 108, 111, 110, 120, 127, 193, 212, 158, 157, - 143, 189, 199, 208, 212, 212, 208, 208, 183, 139, 146, 191, 225, 236, 236, 234, - 218, 189, 183, 177, 173, 162, 139, 123, 56, 32, 30, 34, 51, 72, 71, 87, - 85, 75, 55, 131, 146, 107, 134, 118, 115, 135, 138, 123, 111, 68, 79, 140, - 107, 118, 111, 107, 106, 116, 111, 102, 118, 53, 24, 115, 127, 103, 107, 92, - 95, 104, 102, 104, 108, 114, 153, 209, 226, 234, 237, 232, 189, 116, 120, 110, - 119, 123, 112, 138, 150, 154, 158, 155, 157, 154, 151, 143, 126, 140, 157, 119, - 115, 116, 115, 115, 120, 119, 118, 118, 115, 110, 120, 148, 191, 226, 229, 236, - 241, 241, 233, 146, 120, 123, 110, 55, 36, 32, 36, 56, 59, 60, 73, 182, - 206, 210, 214, 206, 199, 123, 116, 128, 122, 139, 123, 130, 124, 131, 111, 115, - 97, 26, 41, 30, 32, 63, 79, 79, 64, 46, 22, 95, 106, 107, 95, 99, - 107, 122, 178, 173, 127, 127, 124, 128, 130, 130, 130, 131, 132, 132, 143, 162, - 166, 170, 179, 183, 161, 126, 130, 128, 126, 124, 120, 115, 49, 20, 16, 14, - 12, 17, 29, 37, 49, 64, 64, 73, 173, 220, 220, 224, 217, 120, 110, 118, - 126, 136, 146, 158, 166, 166, 163, 157, 154, 138, 138, 104, 69, 48, 42, 46, - 61, 29, 88, 123, 131, 130, 115, 114, 99, 102, 118, 93, 100, 59, 41, 134, - 169, 135, 93, 102, 119, 123, 126, 120, 122, 126, 153, 163, 159, 170, 165, 165, - 159, 154, 175, 187, 193, 202, 198, 187, 162, 139, 143, 139, 138, 139, 142, 138, - 143, 155, 161, 157, 155, 162, 151, 142, 119, 132, 96, 34, 8, 14, 10, 53, - 102, 128, 150, 143, 189, 206, 216, 218, 120, 108, 110, 124, 147, 158, 170, 158, - 155, 155, 143, 136, 127, 126, 95, 60, 49, 60, 80, 87, 95, 89, 87, 99, - 76, 110, 34, 30, 69, 53, 57, 49, 48, 52, 49, 42, 45, 25, 14, 65, - 69, 72, 73, 73, 65, 56, 53, 44, 52, 48, 26, 42, 44, 44, 34, 30, - 28, 26, 34, 44, 112, 212, 225, 218, 157, 161, 178, 182, 174, 169, 159, 146, - 131, 30, 2, 4, 10, 30, 4, 1, 183, 162, 163, 159, 161, 151, 150, 138, - 124, 56, 165, 165, 143, 128, 126, 119, 106, 83, 80, 95, 108, 108, 103, 106, - 112, 120, 128, 135, 136, 140, 140, 151, 173, 185, 194, 197, 206, 202, 206, 214, - 220, 221, 217, 217, 214, 199, 162, 128, 97, 72, 60, 49, 41, 42, 53, 69, - 88, 75, 147, 173, 204, 213, 209, 216, 216, 217, 212, 158, 114, 92, 139, 120, - 127, 132, 136, 130, 134, 143, 138, 134, 148, 147, 142, 138, 146, 148, 162, 147, - 136, 122, 112, 83, 81, 103, 193, 218, 218, 216, 217, 154, 131, 126, 124, 155, - 155, 147, 146, 142, 140, 142, 147, 135, 115, 134, 131, 119, 91, 111, 100, 108, - 84, 97, 92, 93, 124, 189, 187, 143, 126, 127, 138, 142, 142, 140, 136, 131, - 128, 120, 120, 120, 122, 140, 142, 119, 83, 44, 75, 110, 126, 144, 194, 204, - 155, 159, 166, 174, 177, 178, 179, 185, 182, 158, 151, 165, 166, 154, 138, 138, - 132, 114, 81, 68, 91, 111, 119, 140, 208, 171, 165, 150, 191, 199, 213, 213, - 216, 210, 216, 210, 206, 212, 228, 232, 230, 234, 233, 205, 183, 185, 181, 170, - 143, 132, 92, 36, 32, 30, 37, 61, 73, 73, 84, 80, 81, 53, 115, 112, - 139, 127, 135, 140, 138, 135, 124, 120, 65, 72, 104, 134, 128, 96, 110, 102, - 110, 115, 114, 111, 63, 22, 112, 119, 119, 102, 99, 97, 103, 108, 134, 182, - 198, 222, 217, 232, 226, 230, 228, 157, 118, 119, 126, 131, 143, 123, 116, 135, - 142, 142, 143, 144, 150, 150, 153, 142, 136, 148, 157, 148, 169, 178, 187, 197, - 202, 206, 210, 216, 218, 216, 221, 221, 225, 230, 237, 238, 226, 157, 120, 124, - 122, 89, 38, 32, 30, 40, 59, 61, 93, 159, 222, 208, 205, 218, 218, 163, - 130, 132, 138, 132, 134, 127, 139, 123, 127, 115, 112, 97, 71, 55, 33, 32, - 30, 73, 77, 60, 60, 20, 95, 99, 95, 92, 96, 88, 103, 111, 116, 120, - 124, 154, 158, 153, 150, 148, 144, 142, 138, 132, 134, 130, 130, 130, 131, 130, - 126, 124, 122, 120, 116, 83, 34, 20, 16, 14, 12, 14, 40, 34, 48, 61, - 65, 69, 150, 206, 214, 216, 220, 212, 118, 111, 114, 126, 136, 139, 143, 151, - 158, 158, 154, 146, 150, 140, 144, 115, 99, 87, 67, 42, 28, 67, 126, 118, - 128, 100, 120, 116, 115, 119, 96, 99, 72, 41, 95, 154, 177, 112, 102, 110, - 118, 119, 120, 123, 124, 128, 130, 134, 132, 132, 142, 130, 128, 126, 127, 131, - 128, 126, 130, 132, 132, 138, 138, 140, 143, 140, 139, 143, 138, 134, 132, 131, - 131, 127, 138, 139, 103, 33, 8, 12, 16, 10, 52, 100, 107, 136, 193, 198, - 198, 214, 208, 118, 114, 118, 122, 150, 155, 157, 148, 157, 153, 146, 139, 130, - 124, 123, 123, 103, 72, 69, 55, 92, 88, 84, 85, 73, 96, 37, 22, 83, - 44, 45, 45, 57, 52, 52, 41, 42, 25, 14, 59, 65, 67, 63, 49, 53, - 40, 36, 30, 34, 36, 25, 40, 48, 42, 36, 37, 40, 24, 48, 56, 140, - 221, 224, 212, 148, 155, 165, 178, 178, 167, 159, 146, 127, 25, 4, 4, 12, - 24, 6, 2, 162, 161, 157, 154, 154, 154, 151, 128, 127, 52, 132, 158, 147, - 135, 139, 130, 118, 106, 89, 75, 71, 81, 102, 107, 107, 106, 106, 112, 110, - 118, 119, 124, 130, 144, 166, 178, 186, 199, 204, 201, 202, 202, 199, 182, 162, - 127, 99, 85, 69, 57, 48, 38, 40, 46, 55, 69, 68, 126, 228, 206, 214, - 206, 217, 208, 217, 183, 146, 122, 107, 119, 119, 120, 116, 123, 116, 122, 120, - 127, 126, 132, 138, 130, 139, 144, 142, 150, 151, 153, 163, 155, 110, 83, 95, - 118, 222, 208, 210, 210, 216, 150, 134, 136, 148, 131, 151, 148, 144, 134, 134, - 132, 134, 132, 131, 132, 134, 120, 127, 124, 120, 100, 87, 88, 92, 87, 97, - 162, 191, 169, 123, 124, 130, 134, 136, 136, 130, 130, 122, 120, 119, 114, 111, - 108, 115, 134, 96, 83, 87, 87, 107, 126, 159, 209, 165, 155, 162, 162, 162, - 169, 173, 178, 182, 177, 155, 154, 162, 147, 136, 139, 124, 85, 59, 57, 59, - 106, 108, 112, 175, 185, 174, 138, 185, 201, 202, 209, 214, 220, 218, 221, 218, - 222, 230, 228, 232, 229, 221, 194, 190, 183, 179, 165, 135, 104, 51, 34, 32, - 30, 30, 65, 73, 73, 77, 85, 85, 57, 89, 123, 138, 132, 116, 122, 116, - 132, 110, 85, 72, 64, 104, 136, 111, 92, 112, 108, 110, 114, 120, 84, 61, - 16, 100, 115, 107, 107, 71, 95, 111, 195, 216, 212, 216, 236, 220, 229, 242, - 226, 199, 128, 119, 120, 140, 142, 134, 142, 132, 127, 127, 124, 127, 130, 123, - 127, 130, 136, 146, 143, 131, 166, 169, 181, 189, 198, 202, 208, 212, 216, 218, - 221, 222, 228, 228, 230, 226, 201, 140, 118, 122, 127, 118, 59, 33, 29, 32, - 48, 59, 97, 186, 193, 197, 208, 212, 232, 210, 146, 126, 116, 123, 120, 134, - 128, 119, 131, 119, 118, 127, 99, 84, 77, 68, 53, 29, 42, 76, 56, 57, - 17, 91, 100, 91, 71, 64, 69, 77, 77, 73, 75, 75, 89, 108, 114, 115, - 112, 107, 112, 116, 116, 116, 115, 112, 114, 119, 118, 115, 108, 104, 76, 37, - 24, 16, 14, 12, 9, 12, 17, 33, 38, 63, 64, 72, 155, 201, 205, 206, - 209, 216, 155, 118, 108, 118, 132, 127, 131, 139, 139, 148, 147, 158, 154, 144, - 147, 132, 140, 151, 147, 108, 73, 51, 32, 88, 126, 104, 122, 99, 116, 108, - 115, 92, 100, 95, 33, 84, 142, 148, 151, 146, 139, 138, 142, 138, 115, 114, - 118, 119, 124, 126, 127, 124, 123, 128, 120, 104, 99, 92, 85, 89, 100, 116, - 124, 131, 136, 138, 134, 127, 134, 134, 136, 139, 138, 135, 135, 126, 102, 34, - 17, 9, 8, 16, 10, 51, 110, 139, 195, 205, 202, 199, 216, 189, 116, 108, - 123, 131, 130, 144, 150, 154, 151, 151, 147, 142, 138, 131, 122, 120, 118, 130, - 118, 83, 60, 60, 61, 75, 68, 95, 34, 21, 77, 59, 46, 49, 60, 42, - 44, 46, 34, 26, 20, 63, 79, 60, 56, 45, 42, 41, 32, 33, 40, 29, - 46, 42, 37, 30, 28, 29, 33, 18, 49, 57, 161, 221, 226, 209, 143, 148, - 154, 169, 175, 166, 159, 147, 120, 13, 5, 2, 12, 24, 14, 17, 150, 153, - 154, 158, 151, 151, 155, 159, 120, 49, 154, 154, 147, 146, 136, 132, 124, 115, - 99, 91, 76, 65, 64, 64, 76, 91, 100, 103, 107, 107, 107, 108, 110, 115, - 122, 127, 131, 138, 154, 153, 148, 146, 123, 103, 91, 76, 57, 53, 53, 42, - 36, 38, 45, 46, 76, 84, 75, 166, 208, 220, 206, 206, 187, 165, 142, 128, - 114, 95, 87, 83, 84, 88, 92, 95, 93, 100, 104, 107, 106, 110, 115, 122, - 128, 134, 131, 131, 135, 147, 140, 134, 107, 77, 107, 181, 198, 198, 171, 174, - 150, 143, 120, 115, 127, 122, 128, 127, 128, 120, 132, 134, 124, 138, 134, 130, - 122, 119, 122, 118, 112, 69, 45, 56, 87, 80, 83, 131, 175, 177, 126, 134, - 131, 131, 132, 131, 127, 128, 123, 122, 119, 114, 111, 111, 108, 106, 97, 89, - 63, 75, 87, 106, 135, 178, 187, 150, 157, 159, 158, 153, 162, 167, 169, 174, - 171, 161, 140, 138, 142, 131, 97, 65, 55, 44, 45, 77, 103, 112, 154, 199, - 175, 155, 165, 185, 199, 202, 205, 205, 204, 202, 204, 201, 202, 202, 205, 202, - 195, 186, 181, 179, 169, 140, 116, 48, 29, 30, 30, 33, 36, 65, 64, 71, - 81, 79, 83, 75, 68, 69, 76, 89, 69, 72, 81, 72, 72, 92, 89, 77, - 79, 88, 93, 108, 96, 97, 97, 97, 92, 95, 53, 13, 55, 96, 100, 77, - 83, 97, 170, 208, 210, 214, 225, 244, 218, 214, 206, 157, 130, 122, 124, 134, - 136, 136, 139, 139, 136, 134, 127, 130, 132, 130, 127, 123, 120, 122, 123, 124, - 122, 122, 123, 123, 132, 140, 159, 182, 189, 201, 202, 199, 195, 198, 199, 186, - 159, 120, 116, 119, 127, 127, 104, 36, 28, 20, 53, 53, 79, 171, 189, 193, - 205, 199, 204, 178, 146, 132, 118, 132, 120, 119, 123, 127, 111, 115, 106, 111, - 103, 123, 106, 108, 96, 81, 30, 36, 76, 53, 53, 21, 96, 93, 60, 57, - 53, 56, 53, 57, 46, 46, 41, 37, 34, 36, 36, 32, 32, 30, 30, 29, - 26, 25, 22, 24, 28, 24, 22, 21, 18, 20, 14, 14, 12, 10, 10, 14, - 24, 34, 28, 63, 59, 76, 151, 191, 191, 187, 201, 209, 181, 131, 114, 120, - 130, 124, 127, 132, 131, 134, 132, 134, 143, 139, 130, 143, 140, 123, 122, 123, - 154, 135, 49, 32, 73, 72, 76, 79, 83, 84, 88, 88, 93, 93, 71, 22, - 56, 96, 111, 100, 95, 89, 97, 100, 104, 108, 107, 103, 103, 114, 115, 107, - 103, 100, 77, 41, 21, 16, 12, 12, 13, 20, 57, 93, 103, 108, 110, 106, - 97, 100, 103, 103, 102, 99, 96, 84, 44, 24, 12, 8, 6, 18, 22, 18, - 95, 148, 182, 198, 186, 181, 202, 202, 136, 112, 116, 127, 122, 122, 122, 130, - 132, 134, 136, 132, 126, 127, 126, 127, 123, 115, 116, 132, 119, 103, 89, 91, - 81, 80, 64, 52, 25, 51, 64, 71, 59, 60, 45, 42, 45, 37, 24, 18, - 59, 49, 37, 42, 30, 25, 22, 32, 30, 30, 34, 30, 26, 28, 25, 29, - 25, 26, 41, 53, 69, 179, 225, 226, 206, 140, 147, 151, 162, 170, 163, 158, - 142, 99, 8, 4, 2, 6, 16, 10, 5, 162, 158, 158, 158, 154, 162, 153, - 144, 118, 52, 143, 153, 132, 139, 130, 130, 116, 118, 108, 104, 93, 87, 73, - 69, 60, 56, 53, 57, 60, 68, 79, 95, 96, 99, 97, 95, 95, 91, 89, - 88, 85, 77, 63, 52, 49, 46, 45, 37, 33, 36, 48, 61, 63, 59, 69, - 49, 49, 99, 143, 159, 153, 146, 144, 93, 80, 69, 64, 49, 34, 37, 38, - 32, 30, 30, 33, 34, 34, 40, 38, 36, 44, 72, 81, 88, 88, 85, 83, - 114, 110, 68, 40, 59, 99, 157, 151, 159, 157, 159, 130, 107, 87, 88, 102, - 106, 103, 102, 107, 108, 112, 112, 114, 114, 115, 111, 106, 102, 103, 96, 67, - 42, 40, 36, 41, 76, 68, 76, 131, 146, 128, 130, 108, 124, 124, 127, 123, - 124, 122, 115, 110, 108, 102, 111, 103, 106, 106, 91, 38, 44, 80, 76, 112, - 132, 178, 169, 150, 155, 154, 154, 153, 155, 157, 155, 150, 144, 139, 140, 131, - 108, 65, 53, 48, 49, 56, 63, 106, 108, 178, 189, 179, 167, 120, 151, 183, - 187, 191, 194, 193, 191, 189, 185, 178, 177, 181, 182, 181, 178, 163, 146, 135, - 108, 51, 33, 30, 30, 42, 55, 49, 60, 45, 46, 69, 73, 80, 79, 83, - 87, 103, 92, 96, 92, 100, 99, 97, 93, 93, 91, 79, 97, 95, 65, 56, - 30, 28, 42, 40, 38, 38, 14, 34, 40, 55, 80, 73, 95, 163, 205, 218, - 210, 210, 183, 157, 140, 130, 123, 130, 124, 131, 128, 130, 130, 131, 131, 131, - 126, 126, 123, 123, 122, 120, 112, 118, 119, 119, 119, 119, 118, 120, 116, 114, - 112, 111, 112, 114, 116, 118, 118, 115, 112, 112, 111, 114, 112, 119, 123, 128, - 123, 57, 22, 25, 29, 55, 51, 139, 189, 183, 193, 205, 175, 143, 135, 119, - 115, 103, 108, 106, 102, 108, 103, 102, 92, 97, 99, 97, 95, 102, 96, 88, - 84, 32, 42, 57, 51, 42, 26, 89, 92, 60, 52, 52, 51, 49, 49, 45, - 38, 34, 26, 30, 26, 25, 26, 25, 22, 22, 22, 18, 17, 16, 18, 17, - 16, 14, 13, 12, 10, 9, 9, 13, 12, 17, 30, 22, 29, 40, 61, 65, - 107, 179, 183, 193, 186, 163, 151, 124, 115, 124, 120, 126, 119, 123, 118, 116, - 120, 126, 131, 132, 127, 124, 131, 131, 122, 118, 124, 131, 110, 30, 60, 69, - 69, 68, 63, 73, 71, 73, 68, 80, 76, 38, 24, 36, 41, 40, 34, 30, - 26, 25, 21, 21, 21, 21, 17, 17, 17, 16, 14, 14, 14, 13, 12, 10, - 9, 8, 9, 10, 12, 10, 13, 12, 10, 10, 12, 10, 9, 8, 10, 10, - 9, 10, 10, 9, 9, 8, 4, 8, 20, 24, 20, 100, 161, 201, 191, 197, - 186, 157, 130, 118, 112, 116, 119, 111, 108, 116, 122, 120, 126, 128, 124, 119, - 116, 116, 112, 104, 108, 119, 116, 111, 83, 77, 65, 69, 60, 44, 41, 36, - 38, 40, 42, 40, 42, 38, 49, 42, 36, 25, 10, 55, 52, 29, 22, 48, - 76, 118, 155, 142, 89, 28, 36, 40, 13, 20, 20, 28, 18, 45, 42, 93, - 205, 225, 232, 202, 136, 140, 146, 158, 169, 163, 151, 138, 61, 2, 5, 2, - 2, 1, 1, 0, 61, 60, 65, 106, 110, 111, 126, 119, 111, 49, 79, 88, - 87, 87, 87, 83, 83, 79, 76, 75, 73, 67, 59, 63, 57, 53, 49, 52, - 49, 51, 46, 42, 41, 40, 44, 42, 44, 42, 44, 44, 44, 44, 42, 36, - 30, 26, 30, 40, 56, 44, 60, 67, 63, 52, 51, 65, 45, 28, 38, 45, - 41, 38, 34, 26, 38, 40, 30, 24, 25, 25, 25, 22, 21, 22, 20, 18, - 20, 21, 20, 17, 12, 16, 20, 17, 17, 24, 28, 6, 12, 26, 26, 33, - 18, 34, 45, 48, 67, 32, 5, 8, 20, 20, 17, 18, 20, 22, 18, 18, - 22, 20, 21, 22, 25, 30, 30, 30, 29, 26, 34, 41, 48, 61, 61, 51, - 44, 56, 53, 44, 37, 17, 18, 28, 24, 22, 17, 20, 17, 13, 17, 13, - 10, 16, 22, 13, 13, 20, 20, 24, 26, 26, 44, 96, 132, 173, 158, 146, - 144, 148, 147, 150, 153, 147, 144, 142, 142, 131, 97, 61, 51, 46, 46, 49, - 36, 64, 103, 106, 167, 186, 195, 178, 136, 111, 112, 128, 123, 123, 118, 131, - 126, 122, 119, 118, 119, 122, 118, 116, 112, 73, 60, 40, 30, 29, 33, 34, - 30, 29, 14, 13, 33, 13, 13, 13, 14, 38, 13, 10, 29, 30, 12, 12, - 29, 13, 13, 13, 16, 26, 44, 41, 59, 56, 97, 111, 119, 118, 104, 95, - 63, 13, 92, 100, 100, 56, 76, 89, 118, 142, 157, 143, 140, 128, 114, 108, - 110, 112, 114, 112, 127, 127, 120, 126, 126, 127, 127, 126, 124, 124, 122, 123, - 123, 120, 120, 122, 122, 122, 119, 116, 118, 116, 118, 116, 116, 116, 115, 114, - 115, 115, 115, 115, 114, 115, 118, 120, 124, 127, 126, 95, 29, 21, 24, 24, - 38, 48, 102, 161, 178, 148, 140, 111, 96, 91, 92, 93, 96, 97, 96, 97, - 97, 100, 100, 100, 97, 102, 95, 95, 92, 92, 89, 63, 40, 38, 46, 48, - 42, 24, 84, 48, 44, 34, 32, 32, 33, 24, 25, 22, 20, 14, 13, 12, - 12, 12, 12, 12, 12, 10, 9, 9, 9, 10, 12, 13, 13, 16, 14, 16, - 17, 18, 24, 26, 38, 21, 29, 41, 71, 64, 76, 157, 154, 143, 135, 130, - 122, 120, 112, 107, 112, 112, 115, 114, 110, 111, 115, 112, 112, 118, 115, 116, - 115, 111, 106, 100, 100, 102, 99, 37, 49, 9, 6, 9, 6, 5, 6, 5, - 8, 9, 4, 10, 8, 4, 24, 21, 13, 4, 18, 9, 1, 1, 2, 2, - 4, 4, 5, 6, 5, 5, 5, 5, 4, 5, 6, 9, 9, 9, 9, 10, - 10, 10, 9, 8, 8, 8, 8, 8, 5, 8, 8, 8, 6, 6, 5, 2, - 5, 8, 18, 21, 25, 22, 118, 154, 173, 158, 159, 135, 116, 111, 104, 102, - 104, 97, 103, 104, 99, 100, 108, 111, 114, 111, 110, 106, 100, 99, 102, 97, - 97, 91, 60, 26, 13, 9, 9, 10, 10, 9, 12, 10, 6, 10, 14, 16, - 14, 14, 17, 18, 22, 12, 51, 24, 41, 81, 143, 162, 174, 186, 183, 171, - 104, 30, 20, 52, 69, 61, 61, 52, 41, 65, 116, 216, 232, 232, 191, 134, - 140, 144, 158, 165, 161, 148, 132, 29, 2, 4, 5, 9, 14, 29, 41, 139, - 138, 132, 130, 103, 60, 81, 51, 83, 20, 0, 5, 5, 32, 2, 5, 20, - 22, 4, 5, 17, 20, 18, 12, 18, 17, 17, 9, 9, 32, 30, 29, 28, - 28, 25, 24, 21, 21, 21, 20, 20, 22, 21, 24, 33, 36, 49, 49, 60, - 73, 72, 72, 76, 80, 102, 95, 63, 63, 64, 73, 59, 53, 48, 46, 52, - 48, 45, 42, 46, 45, 45, 41, 38, 38, 36, 38, 44, 42, 37, 34, 30, - 26, 22, 30, 44, 49, 22, 37, 57, 28, 30, 28, 57, 45, 56, 61, 59, - 52, 45, 42, 46, 45, 42, 40, 45, 41, 42, 40, 41, 44, 45, 41, 44, - 45, 38, 40, 41, 44, 37, 44, 85, 75, 85, 85, 91, 69, 52, 64, 51, - 59, 64, 57, 53, 46, 48, 48, 45, 41, 42, 46, 42, 40, 48, 49, 45, - 45, 52, 63, 64, 84, 92, 76, 79, 131, 166, 153, 162, 147, 153, 147, 150, - 143, 146, 134, 123, 79, 52, 46, 45, 32, 33, 36, 52, 93, 104, 153, 177, - 193, 199, 175, 124, 92, 73, 71, 68, 64, 65, 59, 56, 52, 56, 51, 52, - 52, 52, 48, 49, 44, 51, 49, 52, 38, 59, 46, 60, 51, 52, 51, 52, - 52, 52, 52, 53, 46, 12, 38, 114, 147, 103, 108, 111, 112, 110, 93, 103, - 107, 122, 144, 136, 144, 144, 114, 120, 119, 131, 116, 96, 22, 103, 100, 115, - 114, 64, 79, 88, 104, 92, 87, 87, 77, 79, 68, 65, 61, 53, 55, 41, - 41, 36, 34, 33, 30, 30, 33, 30, 33, 30, 30, 29, 30, 29, 29, 28, - 28, 28, 32, 30, 32, 32, 29, 32, 37, 41, 60, 92, 107, 115, 119, 120, - 123, 123, 126, 127, 123, 111, 42, 24, 18, 17, 28, 56, 45, 61, 68, 67, - 68, 69, 71, 26, 20, 20, 18, 17, 17, 17, 16, 14, 14, 16, 16, 18, - 20, 18, 22, 22, 22, 24, 24, 12, 6, 12, 9, 13, 25, 32, 51, 63, - 57, 72, 76, 67, 59, 67, 64, 52, 9, 41, 59, 55, 55, 38, 46, 37, - 48, 29, 18, 25, 37, 64, 69, 65, 64, 61, 65, 61, 63, 64, 56, 53, - 20, 46, 68, 73, 67, 88, 107, 107, 112, 100, 96, 88, 87, 81, 71, 52, - 60, 45, 49, 44, 41, 36, 38, 36, 37, 36, 37, 36, 36, 37, 37, 36, - 41, 41, 36, 12, 17, 71, 76, 79, 87, 87, 81, 92, 81, 80, 81, 41, - 12, 69, 72, 79, 69, 72, 63, 68, 34, 21, 13, 10, 6, 13, 13, 12, - 9, 9, 6, 9, 8, 5, 9, 6, 8, 4, 12, 14, 13, 8, 16, 13, - 8, 4, 4, 8, 6, 8, 10, 10, 10, 9, 10, 12, 24, 30, 24, 30, - 20, 108, 107, 111, 102, 108, 95, 81, 59, 46, 44, 32, 30, 28, 30, 24, - 22, 22, 24, 18, 21, 20, 16, 14, 14, 17, 14, 14, 14, 12, 13, 28, - 29, 41, 42, 30, 40, 46, 55, 61, 56, 51, 30, 29, 22, 17, 40, 40, - 34, 22, 52, 85, 148, 191, 193, 187, 201, 187, 150, 104, 32, 29, 53, 68, - 60, 49, 56, 55, 85, 162, 221, 232, 232, 178, 132, 135, 143, 154, 161, 155, - 144, 107, 12, 4, 2, 5, 20, 41, 48, 55, 194, 189, 185, 178, 154, 134, - 124, 115, 87, 13, 44, 131, 159, 127, 127, 140, 162, 136, 134, 134, 132, 130, - 131, 134, 138, 138, 124, 104, 71, 61, 53, 29, 28, 25, 26, 29, 38, 40, - 40, 42, 48, 63, 60, 65, 68, 65, 69, 69, 91, 111, 119, 119, 132, 126, - 140, 116, 102, 52, 120, 115, 79, 77, 75, 72, 71, 71, 75, 75, 72, 52, - 60, 83, 85, 79, 79, 81, 84, 75, 57, 45, 36, 32, 18, 20, 44, 46, - 42, 42, 51, 49, 52, 59, 46, 8, 88, 71, 64, 64, 63, 61, 67, 48, - 45, 42, 45, 42, 42, 34, 37, 48, 42, 45, 46, 46, 41, 48, 41, 38, - 44, 84, 87, 77, 85, 91, 95, 95, 99, 89, 14, 100, 92, 76, 75, 55, - 60, 55, 53, 53, 57, 56, 52, 56, 57, 61, 61, 61, 65, 65, 69, 81, - 87, 93, 77, 83, 159, 162, 142, 146, 138, 136, 134, 132, 116, 77, 64, 53, - 51, 41, 51, 40, 33, 49, 87, 120, 118, 157, 194, 198, 202, 162, 104, 71, - 56, 51, 69, 55, 55, 51, 56, 56, 55, 52, 57, 59, 60, 59, 56, 56, - 53, 53, 53, 55, 53, 52, 59, 64, 65, 67, 72, 73, 73, 77, 71, 48, - 9, 122, 146, 138, 134, 119, 119, 114, 138, 122, 132, 81, 114, 123, 120, 114, - 127, 131, 120, 122, 124, 128, 85, 16, 92, 110, 112, 118, 96, 68, 79, 87, - 61, 51, 49, 64, 46, 48, 45, 45, 42, 42, 30, 26, 26, 24, 26, 21, - 22, 24, 25, 24, 24, 22, 22, 22, 22, 22, 20, 20, 18, 21, 20, 20, - 20, 20, 20, 21, 20, 22, 25, 30, 38, 49, 61, 76, 84, 92, 92, 77, - 41, 24, 24, 22, 24, 33, 59, 59, 57, 44, 46, 49, 42, 51, 42, 41, - 37, 36, 37, 34, 29, 26, 28, 25, 22, 22, 18, 21, 20, 17, 17, 14, - 14, 16, 16, 18, 33, 21, 40, 28, 76, 112, 118, 118, 115, 118, 112, 111, - 111, 81, 59, 2, 85, 68, 67, 60, 56, 71, 83, 59, 61, 51, 26, 75, - 91, 87, 84, 81, 87, 81, 83, 80, 72, 67, 53, 20, 76, 75, 67, 85, - 95, 91, 93, 84, 84, 76, 80, 59, 42, 44, 45, 41, 33, 30, 28, 25, - 25, 25, 21, 22, 22, 21, 17, 17, 14, 13, 16, 14, 13, 10, 16, 16, - 85, 89, 85, 85, 85, 83, 81, 84, 87, 95, 46, 13, 93, 81, 72, 81, - 73, 75, 72, 63, 55, 42, 24, 6, 24, 53, 48, 26, 32, 45, 44, 26, - 32, 40, 34, 21, 24, 38, 40, 41, 46, 48, 41, 38, 36, 17, 4, 13, - 26, 37, 28, 26, 30, 25, 26, 29, 33, 28, 32, 13, 81, 84, 73, 52, - 60, 55, 51, 33, 36, 37, 37, 26, 26, 28, 30, 24, 24, 22, 22, 20, - 21, 20, 18, 22, 24, 22, 21, 22, 25, 32, 29, 34, 41, 46, 49, 36, - 45, 65, 61, 37, 40, 60, 65, 61, 45, 45, 26, 18, 57, 81, 139, 193, - 190, 177, 187, 142, 116, 93, 104, 32, 32, 53, 80, 79, 84, 71, 57, 93, - 194, 222, 230, 229, 163, 131, 136, 142, 153, 154, 147, 136, 63, 5, 5, 2, - 4, 21, 44, 41, 69, 177, 174, 179, 174, 170, 175, 158, 147, 92, 6, 165, - 163, 159, 155, 155, 159, 151, 155, 154, 151, 147, 146, 147, 147, 146, 147, 142, - 143, 147, 138, 110, 79, 69, 46, 75, 93, 95, 88, 87, 87, 84, 81, 83, - 79, 75, 56, 60, 114, 132, 142, 140, 140, 138, 130, 135, 135, 114, 59, 122, - 116, 116, 112, 115, 112, 104, 104, 95, 93, 85, 52, 75, 97, 111, 108, 104, - 106, 106, 97, 84, 83, 80, 68, 18, 79, 84, 85, 99, 57, 65, 91, 64, - 60, 65, 20, 81, 106, 99, 106, 103, 89, 88, 65, 60, 67, 56, 29, 40, - 102, 59, 93, 76, 87, 63, 81, 64, 44, 30, 22, 44, 85, 89, 92, 85, - 91, 115, 99, 95, 79, 12, 106, 103, 73, 88, 79, 73, 75, 75, 81, 69, - 68, 52, 42, 52, 61, 77, 64, 69, 76, 85, 83, 85, 92, 93, 76, 142, - 161, 140, 95, 81, 76, 75, 65, 63, 56, 55, 44, 41, 49, 45, 38, 56, - 80, 95, 116, 119, 189, 195, 201, 198, 154, 104, 63, 56, 55, 56, 55, 56, - 56, 61, 61, 64, 77, 100, 136, 148, 165, 173, 165, 154, 115, 75, 63, 57, - 53, 57, 60, 59, 59, 63, 63, 65, 73, 72, 72, 34, 135, 143, 123, 110, - 110, 110, 107, 104, 119, 80, 97, 134, 138, 119, 131, 115, 122, 112, 122, 119, - 132, 88, 14, 97, 103, 120, 110, 99, 92, 61, 59, 55, 72, 71, 45, 37, - 36, 36, 42, 26, 32, 22, 22, 21, 20, 20, 20, 18, 20, 20, 21, 20, - 20, 20, 21, 20, 20, 20, 20, 20, 21, 25, 32, 28, 30, 32, 30, 26, - 22, 20, 21, 21, 24, 25, 25, 24, 25, 26, 24, 24, 21, 22, 13, 25, - 60, 67, 65, 59, 59, 56, 53, 49, 45, 42, 41, 45, 40, 38, 37, 33, - 33, 30, 30, 26, 26, 26, 25, 28, 24, 24, 24, 21, 24, 29, 38, 46, - 48, 46, 59, 93, 116, 114, 108, 107, 100, 99, 100, 107, 88, 64, 6, 80, - 73, 79, 60, 71, 72, 69, 61, 64, 59, 26, 80, 102, 108, 103, 95, 100, - 107, 103, 87, 85, 73, 56, 18, 69, 68, 80, 110, 111, 88, 81, 102, 75, - 46, 46, 46, 49, 51, 37, 33, 32, 26, 26, 26, 25, 24, 20, 21, 21, - 20, 18, 16, 14, 14, 16, 16, 13, 12, 22, 30, 88, 81, 76, 80, 84, - 80, 75, 75, 75, 111, 46, 16, 89, 89, 91, 91, 88, 87, 81, 68, 64, - 46, 28, 6, 48, 61, 64, 48, 45, 29, 34, 42, 36, 24, 26, 18, 28, - 55, 73, 69, 69, 60, 65, 59, 40, 26, 6, 55, 63, 46, 46, 40, 40, - 40, 37, 32, 30, 29, 34, 16, 61, 103, 73, 65, 49, 42, 51, 36, 34, - 36, 34, 25, 25, 28, 29, 20, 22, 24, 20, 24, 18, 18, 21, 24, 21, - 26, 28, 24, 25, 32, 34, 42, 34, 42, 22, 26, 63, 63, 85, 61, 38, - 36, 40, 33, 34, 29, 22, 53, 85, 92, 175, 190, 175, 171, 139, 96, 91, - 96, 73, 46, 37, 48, 75, 53, 57, 52, 69, 124, 206, 222, 230, 224, 144, - 130, 135, 140, 153, 150, 142, 114, 21, 4, 5, 1, 4, 22, 41, 44, 59, - 163, 169, 163, 158, 163, 159, 174, 144, 95, 22, 155, 173, 170, 175, 162, 162, - 162, 154, 147, 143, 120, 104, 115, 147, 158, 159, 153, 155, 130, 143, 143, 123, - 80, 55, 91, 104, 104, 106, 102, 103, 102, 100, 99, 103, 69, 52, 95, 136, - 147, 146, 136, 140, 138, 143, 144, 114, 108, 63, 119, 123, 118, 120, 120, 116, - 122, 107, 107, 110, 91, 56, 95, 102, 114, 116, 119, 132, 127, 124, 108, 108, - 83, 68, 18, 80, 103, 87, 99, 107, 93, 95, 93, 65, 63, 17, 72, 107, - 142, 144, 146, 107, 110, 96, 89, 64, 59, 26, 75, 114, 122, 112, 108, 103, - 104, 107, 87, 75, 53, 21, 56, 92, 96, 81, 69, 91, 99, 99, 110, 63, - 5, 114, 111, 118, 110, 68, 72, 56, 75, 71, 67, 69, 46, 33, 49, 108, - 92, 92, 91, 91, 84, 84, 83, 93, 111, 73, 154, 159, 139, 99, 87, 72, - 69, 61, 61, 51, 51, 42, 40, 37, 46, 55, 77, 83, 122, 120, 142, 186, - 204, 202, 202, 139, 103, 83, 77, 81, 71, 68, 71, 80, 95, 124, 155, 186, - 208, 218, 224, 226, 226, 218, 220, 212, 190, 163, 138, 88, 67, 57, 60, 60, - 63, 60, 60, 71, 69, 68, 12, 96, 142, 100, 97, 114, 114, 107, 107, 114, - 81, 102, 123, 135, 132, 126, 131, 127, 120, 127, 123, 126, 81, 14, 97, 102, - 112, 108, 97, 64, 63, 61, 61, 67, 49, 29, 80, 68, 56, 49, 56, 68, - 48, 52, 49, 44, 40, 38, 44, 40, 51, 51, 51, 44, 42, 42, 40, 37, - 34, 36, 33, 55, 48, 51, 49, 57, 55, 57, 51, 48, 38, 29, 22, 26, - 24, 21, 21, 20, 20, 22, 20, 24, 22, 9, 33, 64, 77, 81, 84, 81, - 85, 79, 79, 67, 56, 48, 76, 80, 60, 57, 59, 48, 48, 57, 55, 24, - 9, 38, 53, 61, 40, 32, 40, 48, 32, 55, 48, 52, 45, 53, 95, 114, - 108, 107, 108, 100, 99, 84, 95, 102, 48, 8, 59, 84, 77, 87, 85, 95, - 96, 72, 87, 51, 28, 73, 104, 110, 110, 104, 103, 112, 99, 104, 85, 75, - 64, 20, 71, 64, 72, 83, 96, 128, 107, 93, 53, 56, 46, 61, 85, 81, - 76, 55, 61, 61, 64, 55, 53, 44, 40, 34, 37, 34, 32, 30, 28, 28, - 26, 25, 28, 22, 25, 16, 68, 95, 104, 83, 72, 80, 99, 80, 79, 96, - 45, 18, 77, 89, 88, 84, 83, 77, 104, 65, 63, 60, 28, 8, 51, 63, - 48, 64, 45, 53, 34, 37, 38, 51, 28, 21, 48, 72, 80, 77, 65, 56, - 55, 68, 40, 30, 13, 59, 60, 46, 42, 44, 38, 48, 37, 37, 25, 32, - 34, 13, 63, 83, 61, 79, 65, 71, 72, 51, 41, 41, 40, 33, 37, 36, - 21, 28, 28, 28, 28, 26, 29, 28, 24, 29, 32, 33, 33, 30, 32, 33, - 38, 34, 52, 48, 33, 12, 53, 65, 57, 51, 53, 30, 38, 29, 25, 32, - 21, 59, 88, 106, 186, 181, 175, 144, 103, 96, 93, 112, 64, 45, 33, 55, - 60, 61, 55, 55, 71, 147, 213, 220, 228, 208, 134, 131, 136, 143, 150, 146, - 138, 72, 9, 5, 4, 1, 2, 22, 34, 26, 77, 162, 157, 167, 165, 162, - 155, 157, 128, 88, 38, 110, 171, 174, 170, 175, 166, 163, 165, 163, 147, 120, - 97, 143, 155, 159, 154, 150, 146, 151, 136, 143, 139, 96, 61, 107, 128, 132, - 131, 127, 127, 127, 118, 110, 119, 67, 48, 97, 143, 146, 148, 148, 132, 131, - 138, 132, 120, 89, 71, 118, 118, 123, 114, 115, 127, 124, 116, 114, 118, 97, - 67, 96, 115, 131, 124, 106, 134, 122, 132, 123, 111, 103, 77, 25, 67, 110, - 103, 97, 95, 95, 92, 102, 72, 69, 17, 97, 115, 143, 138, 139, 144, 115, - 120, 106, 92, 63, 13, 95, 116, 131, 127, 119, 118, 120, 115, 111, 104, 52, - 21, 100, 102, 104, 104, 79, 96, 120, 110, 102, 85, 12, 118, 120, 110, 103, - 89, 75, 79, 99, 103, 97, 91, 56, 20, 99, 110, 115, 114, 104, 95, 96, - 91, 91, 102, 103, 91, 146, 159, 148, 130, 106, 87, 77, 69, 61, 53, 55, - 45, 37, 48, 52, 79, 79, 100, 118, 112, 123, 195, 198, 210, 183, 135, 104, - 122, 127, 118, 126, 136, 158, 174, 198, 210, 221, 225, 226, 225, 224, 221, 220, - 221, 218, 213, 213, 208, 210, 181, 127, 71, 61, 59, 61, 65, 61, 69, 76, - 51, 10, 99, 146, 120, 106, 132, 114, 132, 116, 99, 71, 100, 139, 138, 127, - 132, 124, 138, 132, 118, 116, 122, 97, 18, 103, 102, 114, 111, 110, 87, 83, - 63, 75, 65, 67, 49, 72, 89, 87, 68, 67, 59, 65, 63, 60, 59, 59, - 40, 33, 49, 51, 55, 60, 52, 56, 57, 57, 59, 57, 49, 45, 53, 64, - 60, 63, 57, 59, 57, 57, 56, 37, 59, 63, 64, 63, 56, 56, 34, 32, - 30, 28, 28, 24, 10, 41, 71, 85, 85, 83, 85, 85, 89, 83, 75, 63, - 53, 71, 89, 68, 80, 77, 77, 61, 52, 60, 53, 13, 64, 65, 67, 64, - 64, 59, 55, 52, 51, 46, 49, 51, 44, 85, 107, 111, 104, 106, 95, 95, - 85, 95, 77, 64, 12, 76, 81, 95, 80, 77, 81, 84, 88, 84, 57, 37, - 91, 106, 103, 104, 106, 112, 115, 112, 110, 99, 83, 60, 20, 71, 67, 83, - 69, 84, 99, 119, 107, 56, 57, 46, 67, 91, 77, 75, 73, 75, 71, 73, - 75, 71, 53, 52, 41, 57, 59, 56, 53, 53, 44, 40, 46, 46, 32, 22, - 56, 87, 93, 81, 83, 76, 87, 79, 84, 81, 106, 53, 21, 88, 89, 87, - 100, 79, 81, 75, 79, 60, 63, 28, 6, 53, 69, 56, 88, 59, 60, 63, - 53, 44, 49, 28, 18, 63, 80, 80, 57, 51, 51, 52, 67, 41, 25, 5, - 48, 60, 49, 52, 42, 41, 32, 37, 36, 33, 34, 37, 21, 71, 85, 80, - 60, 68, 65, 76, 61, 63, 40, 37, 18, 14, 32, 28, 32, 29, 30, 24, - 26, 29, 20, 17, 26, 46, 51, 51, 52, 29, 25, 25, 30, 38, 45, 37, - 17, 57, 60, 57, 51, 44, 33, 36, 32, 28, 24, 22, 60, 88, 110, 186, - 182, 146, 112, 99, 89, 107, 104, 80, 44, 36, 44, 65, 56, 48, 61, 102, - 189, 217, 224, 228, 187, 127, 130, 135, 148, 146, 140, 116, 20, 5, 5, 4, - 1, 4, 12, 40, 21, 49, 181, 162, 162, 161, 155, 159, 155, 153, 79, 5, - 122, 174, 171, 170, 174, 169, 165, 162, 165, 135, 118, 93, 142, 155, 146, 153, - 150, 157, 165, 157, 148, 144, 114, 71, 120, 138, 140, 124, 139, 135, 135, 124, - 108, 106, 69, 45, 120, 147, 147, 151, 140, 130, 143, 136, 138, 119, 111, 79, - 116, 126, 114, 135, 124, 114, 115, 127, 124, 127, 104, 69, 103, 128, 131, 130, - 107, 118, 119, 127, 123, 119, 107, 79, 8, 71, 97, 108, 100, 95, 93, 97, - 100, 72, 69, 20, 88, 116, 138, 132, 127, 131, 130, 115, 111, 96, 60, 28, - 108, 126, 130, 127, 130, 122, 132, 131, 119, 107, 71, 20, 104, 104, 108, 96, - 104, 100, 111, 108, 100, 85, 10, 118, 104, 97, 92, 102, 87, 91, 114, 116, - 103, 91, 55, 36, 102, 110, 124, 124, 123, 102, 103, 107, 102, 92, 92, 83, - 136, 157, 154, 132, 132, 123, 95, 91, 71, 64, 48, 33, 42, 71, 80, 81, - 100, 96, 118, 116, 122, 178, 206, 208, 179, 122, 96, 114, 183, 187, 193, 201, - 205, 212, 220, 221, 221, 221, 214, 209, 194, 193, 193, 181, 171, 161, 162, 166, - 182, 199, 199, 161, 87, 67, 57, 60, 61, 64, 67, 42, 9, 118, 154, 128, - 115, 110, 119, 107, 114, 111, 63, 102, 132, 135, 122, 122, 122, 123, 124, 122, - 119, 116, 96, 20, 102, 95, 112, 107, 111, 107, 99, 81, 73, 64, 55, 52, - 80, 88, 79, 81, 81, 64, 81, 85, 87, 75, 53, 38, 44, 79, 95, 91, - 59, 59, 60, 64, 65, 65, 68, 37, 51, 87, 83, 84, 83, 65, 64, 67, - 63, 63, 42, 59, 72, 69, 73, 65, 65, 56, 52, 51, 48, 45, 25, 8, - 64, 72, 87, 93, 97, 95, 85, 73, 91, 79, 68, 44, 71, 73, 91, 75, - 73, 80, 76, 67, 67, 57, 6, 72, 69, 53, 75, 72, 42, 48, 72, 64, - 68, 53, 51, 37, 83, 110, 112, 96, 95, 89, 87, 97, 76, 83, 64, 2, - 76, 83, 102, 83, 73, 71, 75, 83, 96, 60, 38, 97, 110, 116, 114, 107, - 100, 102, 112, 115, 104, 89, 61, 20, 69, 63, 69, 63, 85, 99, 96, 81, - 57, 59, 52, 69, 88, 85, 79, 76, 75, 76, 72, 71, 73, 73, 53, 44, - 60, 63, 63, 60, 59, 57, 56, 56, 55, 34, 16, 77, 67, 88, 72, 80, - 80, 84, 84, 77, 80, 92, 57, 22, 89, 89, 95, 99, 100, 99, 75, 81, - 63, 63, 30, 6, 46, 71, 67, 68, 65, 57, 53, 59, 59, 51, 29, 24, - 71, 81, 79, 46, 48, 60, 60, 63, 38, 28, 5, 72, 53, 53, 40, 41, - 41, 44, 42, 45, 45, 36, 40, 18, 59, 97, 77, 72, 65, 76, 57, 65, - 59, 55, 44, 13, 20, 29, 42, 38, 28, 29, 29, 32, 34, 24, 18, 49, - 48, 53, 51, 40, 52, 49, 51, 37, 42, 38, 37, 21, 56, 61, 53, 49, - 44, 32, 25, 29, 29, 26, 22, 51, 85, 91, 183, 178, 130, 103, 100, 99, - 120, 118, 80, 32, 36, 44, 59, 57, 53, 79, 163, 204, 208, 224, 220, 148, - 124, 130, 142, 143, 138, 126, 49, 6, 4, 4, 2, 1, 4, 20, 34, 25, - 17, 178, 166, 161, 161, 165, 161, 159, 147, 76, 6, 132, 170, 166, 174, 169, - 171, 169, 167, 157, 132, 112, 89, 136, 140, 155, 154, 161, 155, 150, 153, 154, - 142, 134, 80, 122, 130, 136, 132, 126, 131, 130, 126, 119, 108, 68, 83, 135, - 146, 146, 134, 140, 123, 128, 135, 128, 123, 122, 83, 103, 127, 123, 108, 111, - 123, 126, 135, 122, 123, 119, 72, 106, 130, 128, 116, 110, 124, 128, 128, 126, - 126, 111, 77, 13, 77, 108, 110, 99, 111, 100, 99, 97, 75, 73, 26, 81, - 122, 131, 134, 136, 136, 136, 131, 116, 97, 60, 28, 100, 112, 118, 126, 134, - 135, 135, 134, 128, 108, 64, 46, 107, 104, 108, 103, 123, 118, 122, 104, 96, - 72, 9, 123, 118, 107, 102, 108, 124, 126, 126, 124, 118, 96, 55, 18, 107, - 120, 130, 127, 127, 127, 128, 130, 108, 107, 108, 79, 124, 153, 151, 143, 128, - 131, 116, 111, 83, 96, 52, 30, 59, 75, 100, 103, 104, 96, 136, 118, 131, - 144, 191, 204, 175, 118, 106, 112, 151, 185, 194, 197, 204, 206, 206, 209, 201, - 195, 186, 167, 150, 144, 144, 147, 139, 142, 138, 144, 147, 144, 155, 181, 173, - 96, 57, 60, 64, 63, 67, 63, 29, 128, 132, 132, 115, 111, 118, 107, 111, - 102, 64, 96, 136, 131, 123, 128, 120, 122, 114, 128, 127, 115, 92, 20, 97, - 92, 118, 122, 114, 100, 87, 73, 75, 68, 55, 29, 76, 99, 83, 89, 77, - 80, 92, 93, 95, 84, 55, 37, 64, 95, 95, 103, 100, 75, 76, 73, 67, - 77, 63, 36, 81, 85, 91, 89, 91, 84, 71, 68, 69, 67, 45, 71, 73, - 81, 77, 77, 73, 65, 57, 57, 52, 48, 25, 6, 69, 84, 89, 75, 85, - 93, 95, 73, 83, 81, 68, 37, 72, 76, 88, 83, 89, 93, 76, 83, 67, - 60, 6, 80, 72, 65, 69, 67, 73, 71, 76, 73, 75, 68, 52, 55, 85, - 116, 96, 97, 93, 102, 89, 89, 97, 77, 68, 4, 85, 84, 80, 79, 99, - 95, 100, 89, 81, 63, 36, 92, 104, 112, 120, 118, 111, 110, 111, 104, 110, - 89, 61, 20, 68, 68, 71, 69, 96, 55, 60, 63, 56, 61, 51, 71, 87, - 85, 88, 71, 85, 80, 79, 73, 76, 73, 63, 44, 55, 64, 73, 72, 72, - 68, 67, 65, 56, 36, 16, 69, 96, 89, 77, 84, 93, 91, 89, 77, 73, - 92, 51, 26, 87, 93, 84, 83, 84, 83, 84, 80, 61, 63, 33, 9, 57, - 79, 52, 61, 49, 73, 63, 69, 61, 46, 28, 30, 68, 85, 60, 55, 49, - 64, 65, 63, 37, 25, 5, 68, 73, 53, 51, 45, 48, 49, 51, 51, 46, - 38, 41, 22, 61, 85, 92, 71, 67, 60, 49, 55, 53, 52, 41, 9, 32, - 53, 55, 46, 42, 40, 44, 48, 36, 25, 14, 48, 46, 49, 42, 48, 53, - 41, 52, 45, 46, 38, 28, 21, 55, 72, 41, 45, 37, 33, 28, 29, 28, - 25, 20, 52, 73, 85, 131, 173, 142, 108, 103, 106, 130, 118, 60, 51, 40, - 48, 53, 48, 76, 138, 201, 208, 212, 221, 194, 126, 124, 131, 146, 139, 130, - 81, 12, 4, 8, 4, 2, 1, 2, 21, 34, 38, 18, 162, 163, 165, 174, - 171, 166, 157, 150, 80, 9, 154, 171, 170, 171, 171, 171, 165, 165, 144, 130, - 112, 81, 130, 154, 167, 165, 162, 159, 153, 151, 148, 143, 135, 87, 85, 119, - 128, 123, 131, 131, 126, 123, 124, 107, 65, 92, 143, 144, 130, 130, 130, 138, - 138, 135, 134, 115, 119, 83, 102, 135, 126, 123, 110, 128, 104, 120, 103, 96, - 123, 77, 108, 132, 131, 115, 122, 134, 132, 118, 112, 127, 111, 75, 9, 81, - 103, 115, 102, 102, 107, 99, 93, 81, 77, 20, 75, 124, 132, 128, 130, 128, - 124, 134, 116, 99, 65, 25, 73, 127, 116, 132, 135, 138, 138, 138, 128, 126, - 61, 18, 104, 112, 111, 112, 107, 115, 110, 110, 110, 61, 4, 120, 116, 97, - 115, 108, 102, 95, 108, 99, 119, 92, 52, 16, 108, 110, 118, 124, 119, 128, - 132, 138, 110, 108, 108, 89, 103, 148, 150, 142, 128, 134, 119, 118, 112, 99, - 63, 32, 72, 97, 106, 102, 100, 99, 135, 123, 136, 122, 171, 209, 178, 110, - 103, 106, 120, 131, 158, 167, 177, 178, 181, 174, 159, 143, 135, 140, 142, 143, - 146, 157, 158, 163, 147, 140, 135, 130, 136, 136, 173, 153, 93, 53, 63, 60, - 60, 59, 14, 103, 128, 127, 96, 112, 122, 114, 114, 96, 65, 99, 134, 136, - 130, 122, 127, 123, 122, 131, 126, 116, 89, 25, 92, 97, 99, 104, 107, 107, - 89, 72, 77, 73, 60, 29, 55, 91, 93, 92, 103, 104, 119, 118, 115, 89, - 60, 16, 68, 96, 96, 103, 91, 84, 89, 108, 100, 80, 67, 34, 83, 87, - 95, 87, 84, 88, 84, 84, 71, 67, 49, 69, 80, 81, 80, 76, 77, 73, - 67, 61, 57, 46, 28, 6, 71, 88, 69, 73, 81, 102, 88, 84, 88, 77, - 68, 40, 83, 81, 88, 80, 87, 83, 85, 87, 71, 46, 8, 79, 79, 95, - 77, 76, 79, 89, 77, 75, 73, 81, 60, 42, 68, 104, 114, 115, 108, 103, - 110, 115, 92, 85, 46, 1, 69, 88, 87, 96, 106, 95, 95, 93, 80, 64, - 34, 73, 107, 107, 111, 108, 111, 112, 111, 118, 114, 106, 63, 21, 67, 60, - 73, 88, 65, 83, 67, 68, 53, 63, 55, 71, 77, 95, 93, 76, 79, 88, - 89, 83, 85, 79, 72, 48, 57, 75, 60, 69, 76, 75, 72, 71, 59, 38, - 18, 87, 95, 91, 97, 87, 87, 84, 77, 77, 81, 95, 51, 33, 53, 92, - 84, 77, 83, 81, 79, 75, 61, 59, 32, 9, 59, 73, 65, 61, 68, 67, - 69, 59, 53, 41, 32, 24, 69, 80, 63, 46, 61, 55, 61, 60, 38, 29, - 4, 64, 60, 57, 53, 68, 68, 75, 73, 69, 53, 41, 42, 24, 57, 91, - 97, 96, 77, 77, 51, 51, 53, 46, 33, 22, 45, 48, 40, 46, 55, 55, - 53, 44, 34, 25, 14, 53, 48, 46, 32, 55, 52, 48, 51, 44, 46, 42, - 34, 13, 53, 68, 48, 41, 32, 33, 30, 41, 24, 29, 18, 42, 60, 79, - 102, 135, 167, 112, 103, 130, 139, 100, 52, 51, 60, 48, 57, 77, 135, 187, - 208, 209, 221, 210, 151, 120, 130, 140, 138, 126, 97, 18, 5, 5, 5, 5, - 2, 1, 1, 14, 33, 5, 28, 158, 159, 157, 154, 157, 155, 154, 138, 71, - 12, 116, 171, 169, 169, 169, 171, 171, 158, 134, 126, 112, 72, 150, 147, 158, - 148, 157, 148, 146, 142, 138, 138, 132, 130, 91, 96, 108, 107, 124, 130, 134, - 119, 123, 116, 60, 93, 142, 146, 124, 134, 135, 136, 131, 135, 122, 143, 106, - 88, 100, 135, 126, 128, 119, 130, 114, 111, 107, 123, 96, 84, 112, 134, 127, - 139, 111, 114, 132, 128, 130, 115, 110, 84, 21, 68, 107, 110, 112, 104, 108, - 103, 103, 83, 81, 26, 119, 127, 128, 139, 127, 122, 123, 124, 120, 96, 64, - 8, 108, 130, 119, 130, 134, 132, 140, 134, 128, 120, 83, 20, 114, 122, 120, - 110, 118, 115, 118, 123, 99, 93, 9, 118, 134, 123, 130, 122, 123, 124, 119, - 114, 118, 95, 52, 13, 119, 118, 122, 135, 126, 116, 114, 130, 127, 108, 111, - 91, 96, 143, 147, 142, 142, 134, 128, 127, 118, 107, 68, 32, 80, 100, 106, - 108, 116, 132, 119, 136, 114, 140, 126, 201, 191, 123, 111, 107, 115, 119, 127, - 132, 134, 139, 134, 132, 126, 118, 115, 115, 118, 132, 143, 153, 157, 158, 159, - 144, 142, 142, 140, 130, 139, 170, 100, 53, 59, 60, 63, 51, 14, 102, 140, - 128, 116, 114, 116, 115, 118, 95, 52, 96, 130, 142, 139, 134, 132, 132, 132, - 135, 122, 114, 95, 34, 93, 99, 107, 100, 91, 84, 81, 65, 76, 79, 52, - 64, 76, 106, 116, 102, 107, 103, 116, 99, 92, 89, 55, 16, 76, 100, 106, - 95, 97, 97, 96, 99, 97, 75, 69, 30, 97, 87, 96, 83, 91, 85, 88, - 89, 89, 71, 49, 67, 75, 73, 75, 73, 76, 69, 68, 65, 65, 48, 30, - 9, 73, 89, 87, 67, 89, 73, 72, 79, 79, 76, 65, 44, 79, 91, 91, - 83, 80, 81, 87, 87, 67, 64, 22, 80, 80, 80, 93, 83, 81, 81, 87, - 87, 88, 87, 76, 51, 68, 91, 99, 102, 99, 83, 91, 85, 85, 80, 69, - 8, 72, 91, 89, 92, 93, 89, 83, 80, 81, 75, 55, 52, 95, 103, 103, - 103, 102, 104, 104, 103, 103, 95, 68, 21, 65, 67, 56, 64, 55, 69, 64, - 63, 63, 72, 64, 55, 79, 71, 73, 69, 75, 72, 75, 73, 77, 75, 75, - 69, 55, 61, 61, 55, 63, 67, 65, 72, 63, 44, 16, 76, 95, 85, 79, - 79, 83, 77, 79, 85, 93, 96, 60, 28, 38, 87, 95, 88, 95, 84, 79, - 57, 59, 49, 32, 9, 55, 71, 73, 81, 71, 76, 69, 65, 63, 38, 32, - 28, 69, 93, 72, 45, 48, 63, 64, 75, 42, 24, 5, 45, 68, 57, 60, - 61, 53, 49, 53, 57, 64, 42, 44, 24, 55, 80, 92, 85, 71, 71, 42, - 51, 52, 49, 29, 18, 52, 46, 51, 44, 41, 37, 40, 42, 34, 21, 14, - 55, 44, 48, 52, 52, 48, 49, 48, 45, 46, 48, 36, 10, 52, 59, 41, - 29, 38, 32, 29, 24, 26, 20, 20, 45, 49, 42, 65, 81, 157, 144, 103, - 114, 135, 127, 61, 49, 56, 72, 111, 150, 186, 198, 202, 217, 213, 165, 119, - 124, 136, 134, 122, 87, 18, 6, 5, 6, 5, 5, 2, 1, 2, 21, 25, - 57, 65, 139, 138, 138, 138, 136, 138, 131, 130, 67, 26, 79, 128, 173, 174, - 151, 155, 134, 134, 132, 104, 99, 72, 142, 146, 144, 140, 143, 147, 142, 132, - 126, 122, 124, 119, 124, 138, 134, 123, 110, 110, 110, 106, 111, 97, 59, 119, - 140, 148, 127, 128, 118, 124, 120, 119, 114, 123, 122, 107, 92, 111, 114, 108, - 116, 115, 127, 122, 122, 123, 123, 116, 111, 99, 104, 128, 123, 118, 114, 115, - 112, 108, 103, 81, 9, 64, 107, 104, 102, 104, 102, 100, 102, 93, 77, 30, - 83, 119, 119, 122, 120, 123, 120, 128, 122, 95, 59, 30, 112, 128, 123, 122, - 122, 127, 115, 128, 123, 108, 72, 12, 108, 106, 124, 124, 120, 122, 126, 116, - 96, 88, 9, 110, 120, 119, 118, 119, 118, 116, 115, 114, 115, 89, 49, 29, - 112, 116, 124, 119, 123, 118, 124, 114, 118, 119, 111, 97, 85, 120, 146, 138, - 131, 124, 110, 115, 122, 106, 71, 30, 80, 103, 126, 122, 134, 146, 127, 150, - 147, 135, 116, 144, 182, 134, 103, 106, 110, 118, 119, 115, 124, 123, 126, 120, - 118, 115, 116, 120, 151, 155, 131, 150, 161, 157, 157, 165, 148, 147, 143, 144, - 140, 166, 96, 46, 52, 57, 61, 44, 9, 92, 124, 127, 118, 111, 118, 115, - 106, 95, 51, 96, 115, 132, 130, 124, 122, 119, 119, 116, 108, 104, 93, 29, - 48, 84, 85, 61, 55, 75, 73, 49, 52, 60, 61, 67, 79, 99, 108, 99, - 96, 93, 96, 93, 92, 91, 48, 30, 68, 95, 110, 104, 104, 110, 97, 102, - 97, 77, 68, 33, 85, 83, 89, 84, 79, 77, 67, 64, 80, 76, 72, 71, - 56, 59, 59, 59, 55, 53, 55, 57, 52, 51, 29, 6, 77, 95, 59, 60, - 64, 60, 61, 61, 65, 69, 63, 61, 59, 64, 76, 76, 65, 65, 63, 64, - 59, 67, 5, 79, 79, 80, 76, 76, 79, 81, 79, 79, 75, 79, 77, 72, - 53, 52, 61, 65, 63, 61, 65, 65, 65, 69, 73, 5, 41, 85, 85, 83, - 83, 80, 53, 51, 53, 59, 73, 73, 59, 73, 85, 79, 83, 80, 85, 91, - 91, 81, 63, 21, 57, 51, 52, 57, 55, 56, 60, 63, 40, 38, 41, 69, - 71, 73, 75, 76, 75, 76, 77, 79, 75, 77, 73, 73, 72, 77, 75, 76, - 73, 60, 60, 71, 60, 46, 20, 85, 96, 81, 87, 92, 79, 93, 96, 84, - 73, 71, 63, 32, 32, 83, 77, 85, 55, 53, 53, 42, 46, 42, 32, 9, - 53, 63, 60, 42, 59, 59, 63, 49, 51, 42, 30, 25, 68, 81, 55, 56, - 49, 60, 60, 76, 34, 26, 5, 67, 63, 60, 57, 55, 52, 52, 52, 49, - 48, 46, 46, 26, 34, 52, 73, 67, 52, 41, 48, 44, 41, 49, 45, 18, - 52, 48, 51, 42, 48, 42, 40, 37, 34, 24, 14, 48, 53, 49, 46, 48, - 48, 46, 41, 42, 40, 36, 24, 13, 44, 56, 34, 21, 22, 25, 28, 26, - 25, 21, 21, 33, 42, 41, 46, 67, 77, 171, 114, 110, 140, 134, 128, 124, - 126, 153, 179, 182, 193, 195, 210, 206, 163, 116, 124, 131, 120, 111, 83, 22, - 6, 6, 6, 5, 4, 5, 4, 1, 2, 12, 14, 12, 10, 81, 77, 75, - 67, 60, 56, 49, 45, 36, 40, 40, 56, 65, 63, 80, 84, 95, 77, 97, - 107, 84, 69, 106, 75, 99, 93, 65, 67, 85, 71, 60, 55, 68, 64, 77, - 60, 76, 75, 99, 131, 134, 132, 95, 81, 56, 114, 123, 127, 118, 116, 110, - 123, 118, 115, 126, 127, 120, 115, 119, 130, 135, 134, 130, 132, 128, 130, 128, - 124, 122, 122, 119, 119, 75, 76, 53, 40, 37, 36, 33, 33, 28, 36, 10, - 32, 32, 37, 41, 44, 55, 84, 99, 89, 76, 37, 10, 85, 112, 68, 83, - 95, 114, 68, 91, 91, 48, 29, 60, 83, 68, 67, 84, 80, 69, 67, 84, - 85, 38, 13, 63, 83, 61, 87, 77, 77, 59, 91, 75, 42, 10, 33, 80, - 81, 80, 79, 87, 88, 83, 84, 88, 87, 45, 17, 85, 122, 118, 96, 92, - 108, 111, 84, 95, 103, 115, 102, 107, 111, 104, 93, 107, 103, 103, 95, 92, - 89, 69, 33, 76, 112, 112, 103, 100, 112, 112, 103, 106, 130, 136, 167, 182, - 170, 115, 108, 103, 110, 106, 65, 56, 56, 57, 57, 56, 60, 60, 97, 116, - 165, 124, 130, 154, 158, 161, 158, 155, 162, 148, 148, 142, 163, 102, 46, 46, - 55, 44, 53, 18, 48, 75, 102, 128, 126, 120, 132, 97, 87, 55, 91, 100, - 122, 122, 115, 95, 87, 83, 77, 77, 60, 48, 63, 69, 61, 65, 63, 61, - 53, 55, 53, 53, 44, 45, 45, 55, 87, 85, 93, 100, 96, 104, 87, 97, - 83, 32, 28, 63, 91, 87, 77, 88, 89, 85, 81, 85, 80, 68, 36, 87, - 84, 72, 79, 77, 76, 76, 77, 73, 71, 69, 67, 71, 69, 67, 68, 67, - 64, 61, 61, 60, 56, 53, 6, 49, 59, 53, 55, 56, 59, 57, 60, 61, - 63, 61, 57, 63, 60, 61, 61, 59, 57, 56, 60, 53, 46, 5, 52, 60, - 55, 59, 59, 63, 64, 64, 65, 67, 68, 68, 59, 67, 73, 68, 60, 73, - 71, 63, 51, 75, 63, 48, 18, 52, 38, 33, 33, 36, 26, 32, 34, 29, - 30, 34, 29, 46, 55, 46, 44, 64, 72, 65, 51, 71, 72, 44, 25, 51, - 21, 22, 22, 21, 18, 18, 20, 20, 14, 14, 20, 14, 13, 13, 17, 16, - 16, 17, 20, 21, 20, 21, 24, 28, 29, 32, 34, 40, 72, 69, 76, 60, - 41, 17, 73, 93, 80, 89, 93, 88, 87, 75, 76, 63, 60, 48, 45, 28, - 41, 40, 44, 48, 44, 33, 32, 28, 25, 34, 13, 24, 21, 21, 28, 29, - 36, 48, 34, 30, 33, 29, 34, 46, 49, 45, 51, 41, 46, 48, 45, 34, - 24, 5, 60, 57, 61, 60, 56, 55, 53, 52, 53, 52, 49, 49, 46, 48, - 45, 45, 46, 45, 44, 45, 44, 44, 42, 38, 18, 46, 37, 41, 40, 38, - 36, 28, 34, 36, 24, 13, 12, 13, 13, 16, 13, 13, 12, 14, 29, 26, - 25, 18, 12, 38, 21, 16, 16, 18, 17, 13, 16, 14, 12, 30, 30, 13, - 33, 33, 42, 49, 93, 132, 114, 126, 151, 153, 161, 169, 174, 181, 191, 194, - 205, 199, 166, 120, 122, 119, 110, 97, 61, 18, 10, 8, 8, 4, 5, 5, - 8, 4, 4, 0, 0, 0, 0, 0, 99, 88, 118, 123, 102, 92, 135, 134, - 64, 13, 84, 131, 127, 95, 107, 99, 60, 53, 65, 61, 57, 69, 34, 36, - 60, 71, 89, 102, 119, 122, 140, 151, 127, 108, 127, 143, 131, 122, 87, 76, - 75, 68, 108, 93, 56, 88, 92, 73, 73, 61, 60, 49, 51, 51, 46, 51, - 42, 37, 32, 26, 26, 24, 24, 25, 25, 24, 22, 26, 24, 21, 24, 37, - 88, 112, 124, 124, 128, 131, 131, 127, 128, 89, 10, 120, 161, 161, 138, 88, - 89, 76, 56, 55, 71, 57, 10, 1, 29, 20, 21, 1, 21, 12, 2, 2, - 14, 32, 1, 0, 41, 22, 2, 1, 21, 16, 4, 6, 20, 17, 5, 4, - 9, 30, 2, 1, 10, 2, 6, 0, 1, 9, 0, 0, 1, 4, 2, 2, - 1, 2, 2, 4, 26, 8, 34, 29, 38, 37, 42, 51, 63, 85, 87, 95, - 106, 79, 76, 69, 72, 65, 61, 60, 51, 46, 67, 57, 59, 36, 67, 72, - 73, 81, 93, 93, 93, 118, 120, 142, 161, 163, 199, 190, 153, 114, 104, 106, - 107, 48, 49, 49, 56, 53, 51, 57, 56, 73, 111, 158, 162, 127, 126, 151, - 154, 157, 157, 163, 144, 146, 159, 153, 97, 42, 41, 45, 32, 10, 33, 45, - 46, 55, 41, 41, 57, 61, 72, 96, 53, 83, 95, 89, 68, 64, 67, 64, - 44, 45, 46, 34, 25, 14, 16, 16, 12, 9, 9, 8, 8, 5, 5, 5, - 4, 2, 2, 1, 1, 0, 0, 0, 6, 8, 12, 12, 14, 16, 22, 26, - 36, 33, 38, 49, 46, 61, 79, 83, 65, 37, 76, 64, 64, 53, 44, 44, - 38, 33, 29, 29, 22, 16, 14, 20, 10, 9, 8, 21, 6, 5, 5, 24, - 4, 2, 1, 2, 2, 0, 1, 4, 2, 2, 5, 8, 5, 6, 9, 12, - 4, 6, 18, 20, 4, 8, 26, 28, 24, 6, 21, 21, 4, 2, 16, 4, - 4, 12, 13, 1, 1, 0, 8, 2, 0, 5, 8, 0, 0, 0, 6, 0, - 0, 17, 22, 29, 55, 84, 63, 71, 87, 99, 89, 73, 51, 34, 64, 92, - 92, 76, 80, 36, 26, 25, 22, 25, 21, 16, 13, 40, 44, 38, 41, 53, - 52, 52, 51, 65, 45, 5, 21, 95, 116, 76, 85, 97, 110, 85, 88, 87, - 84, 81, 87, 97, 99, 85, 49, 36, 41, 41, 60, 41, 18, 45, 46, 46, - 44, 48, 46, 46, 48, 48, 46, 52, 45, 44, 34, 21, 17, 24, 34, 18, - 21, 52, 76, 84, 57, 13, 56, 75, 73, 37, 32, 28, 36, 22, 28, 18, - 49, 30, 24, 18, 18, 25, 20, 30, 30, 34, 26, 26, 22, 17, 36, 37, - 46, 33, 37, 36, 38, 36, 41, 42, 37, 36, 38, 40, 37, 37, 42, 38, - 34, 34, 42, 36, 14, 25, 48, 38, 38, 30, 36, 38, 42, 52, 42, 37, - 14, 56, 77, 77, 61, 75, 72, 69, 38, 30, 28, 14, 9, 5, 14, 30, - 40, 38, 42, 37, 40, 29, 37, 26, 17, 38, 80, 102, 69, 67, 69, 59, - 132, 154, 138, 148, 123, 126, 130, 144, 147, 155, 154, 157, 140, 128, 131, 107, - 72, 55, 29, 12, 9, 9, 8, 6, 10, 12, 18, 18, 22, 2, 0, 18, - 64, 64, 61, 178, 178, 174, 174, 166, 170, 165, 150, 124, 38, 87, 142, 130, - 136, 138, 130, 130, 130, 112, 119, 85, 40, 79, 158, 173, 177, 177, 175, 174, - 173, 169, 157, 165, 170, 167, 167, 165, 165, 162, 153, 143, 127, 104, 95, 53, - 56, 63, 73, 79, 93, 103, 136, 115, 124, 108, 77, 79, 81, 148, 161, 150, - 135, 167, 158, 135, 159, 147, 150, 140, 143, 140, 147, 166, 154, 139, 134, 139, - 143, 139, 144, 135, 95, 16, 122, 162, 163, 159, 163, 163, 127, 147, 110, 73, - 61, 88, 116, 122, 112, 108, 106, 100, 103, 97, 65, 53, 8, 36, 155, 158, - 112, 119, 151, 151, 123, 128, 122, 63, 6, 30, 102, 126, 95, 95, 91, 91, - 111, 97, 53, 29, 76, 97, 99, 87, 84, 84, 83, 79, 77, 73, 72, 37, - 9, 123, 142, 139, 116, 139, 106, 56, 42, 40, 37, 33, 36, 40, 63, 84, - 93, 96, 107, 108, 119, 120, 118, 100, 34, 116, 134, 132, 114, 143, 127, 130, - 120, 123, 157, 162, 206, 205, 191, 179, 123, 108, 104, 116, 46, 48, 48, 49, - 51, 41, 41, 61, 72, 110, 178, 178, 120, 127, 114, 132, 136, 135, 131, 157, - 153, 143, 106, 83, 41, 40, 38, 38, 45, 45, 100, 114, 96, 97, 73, 61, - 63, 57, 76, 40, 37, 45, 61, 64, 68, 59, 61, 60, 84, 80, 80, 84, - 130, 132, 140, 131, 139, 134, 128, 139, 136, 132, 131, 120, 122, 123, 127, 135, - 123, 127, 118, 93, 96, 89, 79, 33, 14, 92, 135, 143, 104, 100, 85, 79, - 67, 72, 51, 57, 41, 46, 61, 61, 65, 51, 60, 65, 89, 60, 55, 60, - 99, 131, 135, 112, 100, 122, 123, 107, 103, 122, 112, 26, 5, 61, 134, 96, - 100, 97, 104, 103, 111, 119, 119, 115, 110, 116, 120, 135, 119, 119, 119, 120, - 116, 114, 34, 12, 33, 108, 135, 103, 108, 111, 111, 110, 118, 119, 120, 119, - 114, 124, 135, 130, 128, 126, 123, 119, 103, 116, 112, 38, 2, 64, 96, 115, - 120, 115, 114, 115, 110, 114, 102, 67, 32, 69, 106, 97, 97, 93, 92, 95, - 87, 83, 76, 37, 36, 91, 107, 106, 104, 102, 96, 68, 75, 88, 63, 53, - 4, 103, 106, 92, 99, 95, 102, 93, 104, 92, 93, 87, 89, 59, 84, 99, - 88, 76, 92, 88, 81, 71, 51, 20, 17, 14, 13, 13, 13, 12, 13, 12, - 10, 12, 12, 12, 12, 20, 77, 93, 85, 79, 87, 76, 76, 85, 88, 67, - 14, 67, 87, 76, 71, 61, 61, 53, 65, 69, 53, 20, 18, 73, 85, 84, - 77, 72, 56, 33, 21, 22, 20, 9, 0, 0, 9, 5, 0, 0, 6, 4, - 0, 0, 4, 2, 0, 2, 2, 2, 1, 9, 2, 2, 4, 14, 4, 5, - 24, 46, 61, 91, 93, 95, 95, 92, 88, 49, 45, 14, 64, 79, 61, 64, - 69, 63, 59, 59, 69, 59, 44, 21, 8, 53, 75, 84, 84, 77, 85, 76, - 76, 38, 29, 17, 106, 115, 95, 103, 91, 103, 95, 104, 46, 65, 65, 91, - 92, 102, 135, 136, 134, 128, 134, 132, 118, 85, 59, 24, 13, 13, 14, 13, - 10, 8, 12, 18, 14, 22, 32, 10, 4, 4, 42, 68, 83, 84, 166, 170, - 169, 174, 171, 174, 167, 167, 124, 38, 111, 142, 140, 135, 136, 136, 128, 144, - 139, 122, 88, 32, 144, 169, 170, 144, 155, 153, 136, 155, 153, 153, 158, 115, - 144, 158, 170, 173, 166, 169, 159, 155, 118, 120, 53, 110, 150, 143, 150, 144, - 144, 139, 161, 174, 130, 120, 119, 93, 106, 157, 150, 138, 140, 157, 159, 169, - 165, 150, 146, 148, 120, 120, 150, 151, 151, 154, 147, 143, 143, 138, 139, 112, - 13, 135, 165, 155, 162, 161, 158, 157, 162, 131, 107, 64, 123, 128, 130, 130, - 128, 126, 131, 135, 124, 96, 53, 24, 122, 162, 155, 151, 151, 151, 155, 155, - 154, 140, 71, 1, 130, 143, 155, 144, 142, 142, 147, 140, 138, 100, 33, 119, - 119, 118, 110, 111, 104, 102, 95, 95, 93, 92, 36, 9, 123, 142, 146, 146, - 139, 135, 130, 136, 131, 122, 107, 116, 93, 106, 130, 128, 128, 128, 143, 147, - 140, 131, 100, 37, 128, 150, 140, 150, 130, 139, 130, 127, 150, 166, 204, 204, - 198, 201, 174, 115, 108, 110, 115, 48, 46, 42, 53, 51, 44, 64, 60, 80, - 107, 189, 187, 126, 123, 130, 123, 100, 107, 104, 93, 89, 95, 87, 68, 37, - 38, 37, 49, 42, 75, 128, 123, 126, 111, 114, 116, 107, 107, 76, 46, 63, - 138, 144, 135, 131, 135, 142, 123, 139, 93, 127, 110, 96, 120, 118, 130, 124, - 111, 122, 126, 112, 115, 120, 111, 115, 111, 81, 83, 99, 89, 81, 88, 84, - 87, 79, 34, 14, 110, 151, 139, 132, 144, 143, 118, 131, 139, 103, 85, 42, - 79, 128, 134, 132, 131, 124, 131, 134, 128, 142, 126, 92, 89, 95, 97, 97, - 102, 107, 99, 112, 107, 118, 67, 8, 132, 128, 84, 99, 119, 116, 123, 99, - 118, 127, 123, 112, 83, 88, 95, 88, 83, 93, 92, 88, 83, 40, 0, 119, - 146, 138, 143, 139, 144, 139, 140, 135, 135, 138, 132, 108, 81, 103, 107, 107, - 111, 111, 110, 99, 97, 99, 40, 24, 85, 110, 114, 97, 93, 100, 96, 97, - 97, 108, 71, 40, 83, 106, 92, 97, 93, 104, 92, 77, 89, 77, 41, 30, - 96, 99, 88, 106, 88, 99, 103, 93, 76, 61, 53, 8, 100, 102, 85, 84, - 80, 93, 99, 99, 92, 99, 67, 48, 79, 100, 91, 87, 84, 83, 83, 85, - 55, 57, 24, 29, 100, 111, 88, 80, 99, 108, 100, 97, 104, 95, 91, 84, - 89, 92, 112, 112, 107, 103, 89, 81, 80, 84, 68, 17, 65, 85, 81, 79, - 76, 76, 71, 53, 49, 26, 17, 59, 118, 116, 124, 112, 116, 106, 100, 93, - 64, 34, 12, 65, 80, 88, 75, 87, 76, 83, 65, 77, 75, 73, 61, 61, - 97, 87, 96, 89, 97, 99, 77, 87, 112, 88, 32, 25, 72, 95, 89, 87, - 75, 75, 65, 75, 57, 38, 14, 63, 79, 79, 60, 64, 68, 68, 64, 60, - 59, 59, 28, 9, 63, 77, 84, 79, 79, 79, 72, 52, 34, 24, 10, 114, - 92, 102, 102, 100, 81, 135, 132, 63, 48, 38, 36, 41, 46, 60, 68, 59, - 61, 59, 53, 36, 21, 14, 10, 13, 13, 13, 4, 5, 12, 21, 22, 16, - 28, 12, 12, 4, 2, 38, 73, 55, 57, 161, 161, 165, 171, 174, 171, 169, - 167, 118, 17, 79, 140, 143, 140, 136, 118, 143, 139, 142, 119, 88, 34, 155, - 173, 155, 144, 162, 162, 173, 162, 151, 157, 151, 108, 140, 162, 151, 165, 142, - 163, 163, 162, 150, 119, 56, 138, 153, 166, 143, 138, 134, 143, 136, 142, 134, - 139, 128, 89, 153, 170, 165, 161, 158, 157, 155, 147, 151, 142, 140, 100, 143, - 158, 142, 139, 138, 143, 143, 150, 135, 142, 123, 103, 13, 131, 154, 151, 162, - 161, 159, 154, 155, 130, 110, 65, 122, 118, 130, 131, 131, 136, 139, 135, 124, - 100, 55, 5, 159, 161, 147, 147, 147, 144, 144, 140, 139, 131, 75, 25, 138, - 132, 140, 142, 144, 148, 147, 147, 126, 120, 40, 116, 103, 100, 85, 99, 95, - 103, 92, 91, 89, 92, 41, 5, 124, 143, 142, 135, 128, 131, 140, 142, 131, - 131, 96, 73, 126, 148, 151, 144, 140, 144, 144, 148, 142, 132, 110, 38, 127, - 142, 151, 142, 161, 146, 126, 135, 150, 186, 205, 202, 199, 198, 142, 112, 110, - 108, 106, 40, 41, 42, 49, 33, 53, 64, 56, 79, 111, 201, 194, 177, 123, - 126, 147, 136, 135, 134, 131, 131, 112, 102, 67, 37, 36, 40, 48, 38, 79, - 130, 119, 128, 124, 120, 116, 120, 104, 84, 42, 110, 131, 128, 132, 132, 128, - 122, 118, 107, 132, 118, 88, 116, 138, 138, 132, 120, 123, 107, 112, 108, 123, - 110, 103, 68, 99, 99, 87, 88, 88, 88, 95, 95, 96, 73, 42, 12, 102, - 157, 142, 143, 135, 135, 144, 143, 147, 147, 95, 45, 107, 138, 140, 135, 143, - 131, 136, 132, 123, 123, 89, 99, 126, 123, 122, 115, 108, 112, 119, 120, 114, - 114, 84, 13, 130, 83, 132, 127, 93, 96, 126, 112, 103, 103, 111, 67, 91, - 115, 123, 126, 118, 114, 118, 100, 99, 42, 18, 124, 144, 138, 124, 126, 130, - 135, 132, 136, 131, 134, 111, 85, 120, 122, 119, 115, 115, 115, 104, 104, 103, - 91, 52, 5, 81, 112, 107, 95, 97, 96, 108, 108, 104, 108, 69, 40, 85, - 97, 84, 95, 80, 87, 80, 81, 99, 77, 38, 29, 89, 93, 91, 96, 92, - 103, 100, 97, 77, 65, 49, 6, 65, 99, 88, 87, 79, 76, 89, 76, 93, - 76, 63, 45, 77, 100, 95, 89, 84, 91, 87, 80, 63, 60, 24, 61, 112, - 104, 104, 103, 106, 106, 104, 102, 92, 89, 87, 55, 91, 114, 99, 88, 95, - 91, 88, 92, 80, 93, 61, 18, 63, 68, 92, 59, 55, 57, 42, 40, 40, - 21, 14, 75, 119, 118, 103, 108, 107, 118, 112, 111, 83, 51, 17, 60, 65, - 45, 65, 81, 95, 53, 46, 71, 53, 48, 60, 73, 73, 97, 110, 110, 106, - 95, 93, 96, 106, 92, 56, 40, 76, 87, 72, 76, 76, 77, 76, 79, 49, - 40, 13, 65, 79, 79, 56, 57, 67, 55, 65, 65, 65, 57, 26, 8, 67, - 83, 75, 64, 68, 69, 65, 46, 30, 22, 9, 87, 104, 87, 112, 120, 104, - 103, 53, 73, 63, 57, 34, 38, 26, 25, 30, 21, 25, 21, 22, 20, 17, - 16, 12, 13, 8, 8, 14, 24, 24, 21, 18, 21, 29, 12, 5, 2, 0, - 44, 67, 48, 12, 178, 177, 174, 161, 161, 173, 165, 150, 116, 13, 110, 142, - 146, 148, 136, 136, 127, 138, 132, 100, 83, 34, 134, 167, 154, 158, 143, 162, - 155, 163, 148, 159, 146, 102, 128, 162, 130, 151, 143, 169, 163, 155, 151, 131, - 59, 134, 167, 143, 148, 142, 143, 146, 142, 139, 146, 146, 80, 42, 155, 169, - 155, 167, 158, 157, 155, 161, 163, 138, 143, 92, 139, 155, 138, 139, 140, 138, - 147, 146, 142, 136, 136, 97, 12, 130, 154, 151, 158, 155, 150, 130, 166, 158, - 114, 79, 81, 123, 127, 131, 128, 115, 123, 126, 123, 55, 56, 5, 110, 161, - 144, 147, 143, 151, 138, 150, 140, 135, 77, 4, 91, 147, 150, 136, 134, 138, - 139, 157, 146, 85, 46, 76, 100, 107, 92, 100, 102, 93, 92, 99, 99, 81, - 40, 5, 114, 139, 150, 130, 124, 126, 131, 127, 124, 103, 100, 77, 146, 154, - 146, 161, 142, 147, 144, 146, 146, 132, 114, 42, 127, 142, 143, 123, 120, 131, - 124, 142, 167, 212, 205, 204, 195, 146, 118, 107, 106, 118, 67, 42, 41, 42, - 45, 57, 56, 65, 65, 95, 115, 202, 205, 190, 123, 126, 131, 146, 148, 151, - 150, 146, 138, 118, 73, 36, 38, 37, 46, 34, 67, 124, 120, 126, 124, 135, - 130, 123, 108, 91, 46, 112, 127, 128, 126, 130, 135, 120, 119, 110, 118, 112, - 79, 112, 136, 116, 115, 130, 116, 118, 112, 111, 114, 119, 100, 64, 97, 114, - 110, 103, 92, 83, 100, 80, 85, 71, 41, 12, 123, 146, 135, 136, 142, 143, - 143, 142, 139, 128, 104, 52, 116, 139, 128, 127, 126, 126, 123, 126, 120, 97, - 80, 108, 127, 112, 116, 118, 119, 116, 118, 118, 116, 120, 59, 12, 69, 124, - 92, 119, 120, 115, 119, 123, 120, 114, 95, 63, 92, 116, 111, 104, 96, 103, - 104, 112, 104, 40, 14, 95, 143, 135, 143, 134, 130, 134, 138, 135, 140, 123, - 107, 85, 122, 127, 110, 115, 115, 112, 116, 116, 110, 84, 51, 2, 77, 114, - 104, 91, 93, 96, 102, 96, 99, 99, 71, 48, 72, 108, 85, 83, 89, 83, - 93, 85, 87, 68, 38, 28, 65, 92, 87, 84, 85, 93, 96, 99, 76, 65, - 52, 0, 63, 106, 80, 91, 79, 80, 87, 73, 93, 69, 55, 34, 85, 100, - 97, 92, 72, 79, 80, 89, 83, 73, 24, 84, 115, 102, 84, 89, 91, 97, - 89, 100, 93, 84, 64, 52, 89, 111, 93, 96, 93, 89, 83, 81, 83, 89, - 60, 24, 64, 73, 57, 59, 41, 45, 44, 44, 29, 20, 10, 61, 116, 115, - 102, 108, 106, 106, 103, 119, 89, 56, 14, 59, 59, 91, 73, 81, 103, 51, - 72, 75, 51, 63, 71, 52, 89, 110, 103, 102, 91, 99, 99, 99, 96, 91, - 65, 28, 84, 80, 77, 61, 64, 59, 61, 76, 57, 41, 17, 61, 83, 87, - 57, 53, 53, 59, 55, 52, 63, 41, 21, 5, 67, 73, 75, 53, 56, 48, - 44, 41, 34, 25, 10, 93, 100, 100, 85, 96, 73, 110, 69, 72, 63, 60, - 52, 40, 29, 25, 24, 22, 20, 18, 16, 17, 14, 14, 10, 9, 10, 18, - 24, 25, 36, 18, 17, 20, 34, 14, 24, 2, 0, 41, 67, 37, 59, 163, - 165, 163, 169, 159, 157, 167, 151, 126, 30, 110, 138, 142, 131, 138, 142, 134, - 139, 128, 111, 89, 29, 131, 163, 162, 146, 165, 157, 157, 148, 148, 162, 138, - 99, 146, 165, 159, 157, 161, 170, 162, 155, 159, 130, 69, 120, 155, 142, 144, - 140, 140, 154, 147, 148, 143, 142, 95, 38, 155, 169, 163, 159, 154, 161, 146, - 148, 150, 130, 134, 88, 136, 150, 139, 140, 140, 142, 134, 140, 147, 132, 131, - 102, 16, 131, 154, 151, 169, 162, 150, 155, 161, 151, 120, 87, 107, 120, 126, - 116, 115, 118, 120, 114, 122, 68, 52, 4, 108, 154, 144, 146, 151, 150, 150, - 147, 146, 136, 75, 2, 93, 143, 142, 139, 136, 135, 136, 143, 131, 93, 48, - 108, 104, 87, 92, 97, 104, 95, 92, 97, 104, 76, 41, 2, 124, 142, 146, - 128, 132, 139, 142, 139, 118, 106, 75, 72, 144, 155, 144, 150, 138, 148, 150, - 150, 142, 128, 108, 55, 116, 135, 144, 130, 119, 126, 114, 136, 195, 206, 205, - 201, 153, 122, 107, 108, 115, 73, 53, 40, 41, 45, 44, 57, 59, 68, 69, - 89, 115, 210, 208, 198, 123, 124, 131, 134, 142, 147, 148, 151, 143, 123, 75, - 34, 34, 33, 49, 30, 72, 126, 118, 123, 123, 132, 131, 119, 122, 81, 46, - 102, 130, 135, 142, 142, 144, 120, 114, 107, 119, 100, 75, 108, 136, 123, 122, - 114, 124, 124, 122, 108, 127, 118, 96, 61, 107, 107, 102, 88, 84, 77, 80, - 79, 83, 67, 34, 10, 123, 148, 148, 132, 151, 138, 134, 138, 131, 134, 103, - 63, 103, 136, 123, 122, 118, 134, 119, 106, 116, 100, 71, 107, 131, 115, 115, - 116, 114, 119, 114, 115, 119, 120, 60, 10, 85, 122, 126, 91, 93, 118, 111, - 108, 108, 112, 96, 59, 88, 128, 119, 92, 112, 124, 112, 99, 99, 37, 0, - 114, 138, 139, 136, 131, 134, 124, 127, 128, 130, 124, 100, 80, 120, 119, 106, - 108, 112, 116, 115, 115, 100, 97, 51, 5, 84, 107, 99, 99, 92, 97, 87, - 100, 100, 100, 77, 46, 77, 100, 80, 79, 91, 91, 89, 92, 91, 69, 42, - 24, 81, 93, 81, 108, 91, 102, 100, 80, 77, 71, 46, 2, 95, 91, 81, - 88, 75, 73, 81, 71, 100, 72, 55, 38, 79, 96, 106, 93, 96, 87, 77, - 76, 79, 61, 29, 68, 114, 111, 106, 93, 93, 77, 83, 84, 88, 53, 49, - 33, 85, 103, 85, 83, 80, 72, 80, 81, 91, 84, 60, 28, 57, 80, 55, - 49, 48, 61, 46, 49, 28, 24, 9, 65, 119, 116, 100, 115, 107, 102, 100, - 110, 80, 57, 14, 46, 55, 65, 80, 65, 65, 67, 75, 52, 67, 69, 69, - 13, 87, 107, 92, 103, 107, 97, 110, 112, 110, 96, 60, 30, 76, 81, 67, - 60, 61, 61, 75, 73, 81, 52, 17, 64, 71, 80, 57, 59, 61, 59, 55, - 68, 60, 55, 29, 4, 59, 88, 71, 57, 48, 56, 46, 40, 36, 26, 10, - 107, 111, 93, 96, 69, 71, 87, 72, 71, 57, 63, 61, 53, 26, 38, 26, - 29, 28, 26, 20, 18, 20, 22, 13, 5, 8, 20, 29, 34, 32, 36, 26, - 25, 24, 14, 9, 4, 6, 49, 61, 40, 30, 181, 178, 170, 167, 167, 163, - 165, 167, 126, 24, 83, 140, 142, 127, 146, 135, 139, 123, 130, 104, 83, 28, - 132, 171, 161, 163, 166, 153, 161, 159, 151, 161, 131, 100, 144, 153, 140, 143, - 161, 163, 161, 153, 157, 128, 76, 126, 157, 155, 150, 134, 144, 153, 144, 139, - 140, 143, 104, 69, 162, 173, 153, 163, 142, 155, 151, 150, 142, 138, 138, 87, - 142, 144, 140, 142, 143, 132, 143, 146, 146, 131, 132, 106, 17, 132, 154, 154, - 151, 162, 144, 151, 166, 138, 124, 76, 114, 134, 114, 115, 115, 112, 115, 102, - 111, 83, 51, 20, 120, 159, 153, 147, 150, 158, 158, 151, 154, 136, 75, 1, - 118, 143, 127, 140, 140, 134, 138, 138, 126, 108, 57, 110, 104, 95, 87, 99, - 104, 92, 99, 93, 97, 77, 38, 4, 132, 143, 146, 136, 139, 132, 143, 147, - 124, 104, 79, 91, 151, 150, 147, 142, 132, 148, 146, 135, 132, 130, 107, 56, - 118, 138, 146, 130, 138, 115, 110, 135, 202, 208, 201, 161, 123, 104, 123, 71, - 69, 56, 41, 41, 40, 46, 42, 45, 59, 64, 73, 102, 136, 209, 208, 199, - 120, 120, 130, 131, 132, 138, 147, 150, 143, 119, 65, 33, 30, 32, 40, 37, - 79, 124, 116, 122, 122, 135, 123, 126, 103, 91, 60, 100, 136, 128, 139, 131, - 131, 135, 128, 107, 116, 100, 71, 111, 135, 131, 108, 134, 115, 116, 108, 124, - 120, 114, 85, 65, 91, 106, 93, 87, 79, 76, 80, 79, 87, 61, 36, 9, - 123, 148, 132, 132, 142, 150, 142, 132, 144, 136, 107, 64, 96, 139, 127, 119, - 136, 126, 112, 118, 103, 88, 64, 108, 134, 115, 123, 127, 123, 128, 131, 120, - 115, 118, 69, 18, 89, 118, 123, 96, 114, 119, 116, 110, 115, 108, 95, 55, - 85, 116, 114, 107, 103, 103, 103, 100, 100, 41, 0, 110, 139, 139, 139, 135, - 138, 132, 128, 128, 130, 122, 69, 89, 122, 112, 106, 116, 123, 118, 106, 97, - 96, 92, 48, 30, 99, 108, 99, 95, 92, 104, 93, 104, 103, 103, 79, 55, - 81, 107, 80, 75, 91, 93, 93, 84, 81, 68, 42, 22, 79, 89, 91, 100, - 91, 99, 84, 80, 79, 72, 51, 14, 88, 88, 72, 80, 69, 72, 89, 68, - 87, 72, 53, 37, 72, 97, 96, 99, 99, 91, 68, 77, 75, 63, 33, 57, - 111, 103, 104, 85, 85, 88, 110, 88, 83, 56, 52, 53, 87, 102, 88, 83, - 80, 93, 93, 87, 92, 87, 68, 29, 60, 73, 57, 46, 34, 42, 40, 57, - 34, 20, 12, 76, 118, 114, 103, 115, 103, 103, 108, 111, 87, 57, 16, 64, - 55, 63, 72, 57, 67, 79, 56, 49, 53, 64, 40, 10, 89, 107, 104, 110, - 108, 100, 96, 99, 95, 95, 63, 34, 71, 85, 73, 55, 61, 57, 67, 72, - 71, 52, 17, 56, 79, 73, 57, 59, 51, 57, 51, 49, 59, 51, 29, 5, - 64, 76, 73, 56, 40, 46, 41, 32, 36, 24, 9, 107, 99, 99, 71, 83, - 88, 55, 73, 60, 67, 63, 59, 51, 29, 42, 30, 30, 25, 26, 21, 29, - 29, 25, 14, 5, 10, 20, 32, 25, 30, 33, 18, 24, 9, 21, 9, 4, - 1, 36, 63, 24, 18, 167, 173, 177, 169, 169, 162, 166, 161, 123, 24, 87, - 138, 142, 134, 134, 132, 132, 130, 134, 106, 84, 32, 119, 169, 151, 154, 157, - 155, 161, 155, 154, 138, 128, 83, 144, 158, 157, 132, 161, 154, 154, 153, 151, - 130, 79, 102, 148, 154, 153, 142, 148, 154, 146, 155, 151, 139, 123, 65, 165, - 161, 163, 163, 151, 163, 144, 153, 132, 144, 132, 91, 138, 143, 139, 132, 136, - 135, 147, 142, 144, 131, 118, 102, 17, 136, 146, 140, 155, 154, 150, 150, 155, - 140, 127, 79, 102, 93, 126, 116, 104, 104, 123, 119, 89, 67, 52, 6, 114, - 158, 144, 146, 158, 153, 143, 153, 154, 135, 79, 25, 127, 134, 132, 142, 139, - 134, 138, 135, 131, 123, 64, 115, 122, 122, 91, 102, 110, 97, 97, 96, 106, - 76, 40, 2, 131, 131, 148, 136, 138, 120, 142, 147, 126, 110, 75, 100, 158, - 148, 140, 139, 138, 146, 139, 134, 120, 124, 115, 59, 112, 136, 136, 135, 111, - 116, 119, 131, 198, 201, 174, 126, 108, 108, 69, 56, 42, 38, 37, 40, 38, - 45, 34, 48, 59, 67, 89, 111, 177, 212, 209, 202, 122, 122, 130, 131, 132, - 136, 146, 147, 140, 116, 46, 33, 32, 20, 40, 37, 79, 123, 114, 123, 123, - 131, 123, 124, 103, 84, 53, 108, 124, 131, 131, 124, 119, 120, 118, 114, 110, - 87, 65, 110, 134, 135, 116, 120, 110, 124, 123, 126, 118, 107, 85, 61, 96, - 104, 95, 92, 95, 96, 93, 88, 87, 52, 36, 8, 97, 147, 134, 132, 120, - 144, 151, 139, 136, 136, 106, 69, 97, 135, 122, 130, 126, 134, 111, 114, 106, - 85, 65, 118, 135, 120, 120, 131, 126, 127, 122, 120, 116, 108, 84, 22, 103, - 116, 122, 99, 112, 118, 112, 112, 110, 107, 91, 49, 80, 119, 114, 119, 103, - 107, 114, 104, 99, 42, 12, 111, 138, 146, 120, 118, 134, 131, 130, 122, 124, - 119, 61, 88, 127, 115, 110, 115, 128, 122, 111, 103, 88, 85, 53, 6, 92, - 108, 95, 93, 91, 102, 99, 103, 100, 103, 83, 48, 73, 104, 85, 106, 75, - 69, 84, 91, 81, 67, 40, 20, 81, 84, 77, 104, 89, 83, 83, 79, 80, - 72, 49, 13, 55, 79, 75, 67, 72, 69, 96, 67, 83, 69, 51, 30, 77, - 95, 106, 96, 104, 99, 88, 73, 72, 59, 33, 64, 107, 103, 99, 73, 88, - 81, 91, 84, 65, 60, 53, 48, 89, 96, 81, 87, 88, 76, 71, 79, 75, - 77, 65, 28, 56, 71, 63, 46, 44, 34, 34, 33, 36, 17, 10, 79, 112, - 114, 100, 106, 110, 103, 104, 115, 73, 56, 18, 59, 45, 63, 60, 61, 53, - 61, 57, 55, 56, 36, 55, 29, 89, 104, 104, 116, 93, 99, 104, 102, 100, - 92, 63, 37, 71, 77, 65, 51, 65, 72, 63, 71, 42, 46, 18, 42, 49, - 75, 51, 56, 59, 60, 51, 51, 55, 51, 28, 2, 63, 75, 71, 51, 51, - 44, 59, 33, 46, 24, 8, 64, 107, 85, 88, 84, 79, 65, 72, 72, 68, - 65, 68, 51, 30, 36, 32, 24, 36, 33, 32, 22, 24, 20, 20, 8, 17, - 25, 37, 41, 36, 29, 24, 12, 14, 14, 6, 5, 1, 49, 38, 49, 20, - 155, 177, 177, 163, 167, 166, 163, 147, 120, 12, 89, 139, 142, 136, 136, 136, - 143, 140, 128, 96, 84, 28, 118, 159, 153, 167, 158, 159, 153, 139, 154, 140, - 130, 69, 122, 166, 139, 126, 157, 157, 148, 151, 153, 131, 87, 103, 151, 144, - 155, 134, 148, 147, 147, 155, 147, 138, 89, 21, 165, 167, 157, 154, 161, 151, - 157, 158, 146, 131, 135, 84, 135, 139, 132, 135, 132, 135, 144, 142, 136, 134, - 127, 100, 16, 135, 146, 154, 158, 151, 140, 147, 146, 151, 128, 102, 83, 102, - 130, 122, 115, 128, 100, 111, 92, 51, 52, 2, 106, 157, 154, 147, 151, 157, - 147, 154, 146, 123, 79, 5, 87, 132, 130, 143, 138, 140, 123, 135, 144, 104, - 71, 65, 108, 103, 83, 97, 106, 97, 97, 102, 99, 72, 38, 0, 130, 135, - 144, 138, 135, 143, 143, 142, 123, 107, 77, 104, 157, 139, 148, 148, 143, 143, - 143, 151, 147, 119, 114, 61, 111, 135, 142, 139, 134, 124, 110, 126, 190, 208, - 171, 116, 93, 107, 63, 55, 41, 37, 42, 38, 38, 48, 40, 69, 60, 63, - 92, 122, 190, 220, 212, 205, 123, 122, 128, 132, 136, 142, 144, 146, 132, 95, - 34, 30, 30, 28, 42, 36, 77, 118, 114, 123, 124, 120, 126, 119, 85, 92, - 52, 99, 122, 123, 122, 120, 123, 131, 119, 112, 116, 100, 59, 114, 127, 143, - 122, 116, 119, 120, 120, 123, 107, 103, 63, 80, 89, 96, 92, 89, 87, 91, - 80, 84, 85, 61, 41, 6, 131, 148, 134, 127, 123, 127, 130, 134, 128, 124, - 116, 81, 100, 138, 123, 135, 126, 126, 100, 115, 88, 88, 60, 111, 130, 116, - 119, 124, 134, 119, 122, 118, 115, 104, 65, 20, 63, 91, 118, 111, 122, 111, - 111, 120, 110, 100, 80, 46, 71, 107, 111, 123, 119, 116, 102, 103, 106, 41, - 8, 100, 140, 140, 134, 131, 126, 130, 126, 126, 130, 100, 55, 96, 120, 116, - 102, 115, 130, 114, 107, 96, 92, 77, 59, 5, 77, 110, 93, 84, 95, 93, - 92, 102, 97, 96, 77, 63, 68, 97, 83, 83, 100, 68, 69, 72, 72, 67, - 36, 18, 72, 77, 76, 97, 97, 95, 85, 79, 85, 72, 52, 12, 63, 87, - 69, 64, 65, 65, 76, 77, 65, 68, 45, 24, 72, 91, 100, 91, 97, 93, - 91, 71, 72, 60, 34, 52, 96, 95, 123, 85, 93, 68, 63, 69, 51, 48, - 53, 38, 89, 93, 80, 75, 88, 76, 77, 72, 75, 71, 64, 29, 51, 71, - 63, 56, 48, 37, 49, 42, 33, 18, 9, 80, 111, 107, 110, 112, 107, 93, - 107, 118, 80, 56, 14, 60, 48, 79, 55, 45, 46, 77, 60, 51, 44, 38, - 64, 33, 93, 103, 107, 102, 102, 97, 97, 92, 96, 95, 84, 38, 46, 80, - 71, 64, 64, 64, 51, 46, 52, 44, 21, 32, 64, 73, 57, 51, 48, 49, - 53, 56, 52, 38, 20, 1, 52, 63, 67, 51, 60, 41, 44, 34, 34, 24, - 6, 96, 102, 83, 91, 85, 87, 72, 75, 76, 67, 64, 64, 53, 30, 51, - 37, 24, 24, 21, 17, 25, 21, 25, 17, 8, 20, 33, 32, 18, 16, 14, - 14, 12, 24, 17, 9, 5, 0, 22, 57, 21, 24, 157, 169, 181, 177, 163, - 158, 166, 150, 124, 17, 79, 135, 140, 146, 146, 140, 134, 131, 128, 91, 79, - 32, 118, 136, 166, 155, 169, 155, 154, 153, 155, 157, 126, 68, 147, 159, 148, - 150, 135, 138, 144, 135, 139, 138, 89, 106, 138, 144, 150, 146, 142, 144, 146, - 147, 147, 139, 100, 33, 153, 159, 144, 148, 150, 163, 163, 153, 158, 131, 128, - 72, 127, 138, 135, 130, 135, 131, 138, 134, 128, 131, 128, 99, 18, 136, 140, - 132, 136, 136, 126, 127, 135, 131, 130, 104, 72, 108, 107, 112, 93, 97, 107, - 115, 112, 52, 46, 16, 100, 153, 142, 144, 146, 143, 144, 154, 148, 111, 76, - 2, 85, 139, 124, 142, 142, 135, 134, 138, 131, 108, 59, 60, 77, 79, 99, - 96, 104, 99, 103, 99, 104, 67, 33, 0, 131, 143, 138, 139, 139, 153, 147, - 131, 115, 110, 60, 122, 157, 153, 157, 146, 146, 140, 131, 134, 138, 131, 115, - 63, 110, 134, 142, 139, 135, 110, 108, 115, 155, 210, 174, 124, 100, 108, 68, - 52, 41, 46, 48, 42, 45, 44, 42, 46, 63, 87, 111, 157, 206, 218, 216, - 201, 123, 122, 130, 134, 142, 147, 148, 142, 122, 57, 32, 28, 26, 29, 49, - 32, 73, 118, 116, 128, 124, 127, 124, 120, 97, 85, 51, 67, 116, 122, 107, - 112, 111, 99, 119, 118, 114, 92, 56, 102, 123, 126, 126, 120, 120, 120, 119, - 118, 111, 97, 57, 65, 96, 102, 106, 97, 95, 87, 97, 89, 73, 52, 29, - 5, 131, 146, 140, 104, 103, 102, 115, 95, 110, 112, 107, 85, 84, 122, 126, - 123, 122, 122, 97, 115, 84, 81, 51, 100, 126, 120, 120, 123, 120, 119, 116, - 118, 116, 114, 60, 20, 93, 114, 134, 115, 120, 118, 110, 108, 103, 100, 85, - 42, 65, 76, 102, 111, 116, 106, 112, 100, 104, 36, 22, 102, 127, 132, 130, - 124, 128, 130, 128, 126, 122, 99, 46, 92, 96, 122, 120, 127, 119, 110, 100, - 97, 83, 88, 46, 2, 99, 102, 95, 81, 92, 88, 85, 84, 83, 83, 85, - 64, 45, 83, 102, 80, 84, 61, 69, 76, 77, 69, 51, 14, 76, 76, 83, - 89, 84, 87, 84, 84, 83, 77, 51, 17, 64, 69, 68, 59, 56, 52, 57, - 61, 61, 64, 45, 22, 52, 85, 97, 97, 88, 79, 67, 72, 72, 61, 38, - 41, 67, 92, 89, 89, 60, 64, 60, 63, 63, 45, 42, 24, 88, 93, 71, - 83, 85, 81, 83, 71, 81, 72, 67, 40, 32, 69, 56, 57, 41, 33, 37, - 46, 41, 16, 22, 71, 108, 96, 111, 108, 108, 104, 106, 114, 71, 56, 14, - 60, 60, 68, 57, 42, 41, 38, 45, 56, 37, 52, 63, 8, 79, 96, 95, - 100, 92, 99, 88, 97, 93, 97, 75, 38, 46, 67, 67, 55, 61, 51, 52, - 55, 42, 46, 28, 28, 60, 45, 44, 33, 36, 40, 52, 55, 41, 40, 32, - 1, 55, 64, 75, 68, 53, 51, 53, 40, 36, 26, 6, 106, 111, 79, 79, - 80, 79, 80, 75, 75, 61, 65, 67, 53, 28, 29, 28, 18, 18, 22, 24, - 20, 18, 22, 17, 6, 20, 38, 16, 28, 42, 29, 30, 20, 13, 13, 10, - 6, 1, 45, 33, 30, 20, 162, 163, 165, 159, 171, 162, 161, 144, 118, 16, - 71, 128, 131, 134, 127, 130, 127, 130, 124, 93, 87, 29, 112, 153, 166, 162, - 154, 154, 157, 157, 155, 153, 115, 67, 146, 146, 146, 148, 147, 140, 143, 139, - 136, 136, 131, 126, 100, 103, 107, 103, 111, 107, 110, 119, 114, 115, 111, 40, - 166, 154, 154, 161, 150, 153, 153, 154, 147, 144, 135, 75, 140, 138, 130, 130, - 134, 123, 128, 122, 127, 126, 128, 97, 22, 138, 135, 128, 124, 120, 130, 119, - 115, 104, 124, 104, 103, 107, 91, 87, 87, 81, 84, 77, 76, 69, 46, 2, - 73, 153, 147, 148, 147, 153, 150, 151, 131, 130, 83, 2, 87, 138, 123, 126, - 140, 136, 127, 112, 115, 89, 83, 93, 91, 92, 73, 61, 53, 49, 53, 55, - 51, 49, 29, 1, 140, 140, 142, 135, 135, 132, 130, 127, 91, 97, 59, 115, - 151, 148, 142, 134, 138, 136, 131, 128, 130, 123, 115, 71, 77, 118, 126, 126, - 108, 85, 111, 104, 135, 198, 195, 155, 99, 124, 97, 57, 56, 52, 56, 53, - 55, 56, 60, 56, 91, 97, 139, 201, 217, 217, 218, 194, 122, 123, 130, 138, - 144, 150, 144, 132, 79, 32, 29, 28, 29, 28, 37, 41, 68, 106, 110, 111, - 111, 110, 103, 100, 104, 99, 64, 72, 116, 123, 103, 107, 114, 110, 110, 112, - 99, 88, 55, 80, 116, 122, 104, 100, 115, 119, 106, 107, 106, 84, 51, 61, - 69, 63, 63, 61, 68, 63, 53, 52, 41, 42, 26, 6, 116, 135, 140, 134, - 127, 126, 130, 130, 123, 123, 118, 119, 118, 84, 92, 96, 97, 97, 118, 115, - 106, 83, 46, 95, 123, 120, 123, 118, 119, 118, 120, 114, 114, 110, 73, 28, - 91, 95, 100, 102, 100, 100, 106, 97, 100, 85, 84, 37, 64, 71, 99, 96, - 93, 92, 91, 89, 84, 40, 0, 22, 68, 81, 71, 69, 80, 89, 83, 77, - 89, 79, 36, 49, 56, 63, 65, 75, 77, 72, 77, 76, 89, 80, 41, 25, - 99, 97, 100, 102, 93, 95, 93, 91, 87, 84, 79, 80, 53, 56, 64, 71, - 67, 61, 81, 80, 64, 69, 51, 12, 71, 69, 100, 85, 84, 87, 84, 83, - 81, 79, 55, 1, 53, 69, 51, 49, 53, 59, 57, 68, 61, 67, 38, 21, - 36, 75, 76, 65, 64, 69, 71, 61, 61, 65, 57, 36, 46, 64, 64, 52, - 52, 65, 55, 48, 53, 48, 44, 40, 83, 89, 88, 84, 80, 84, 83, 75, - 75, 79, 72, 37, 28, 55, 60, 61, 52, 32, 44, 45, 40, 18, 13, 76, - 110, 103, 104, 108, 108, 112, 106, 112, 85, 56, 14, 52, 57, 55, 37, 46, - 37, 36, 40, 36, 38, 44, 44, 16, 68, 81, 84, 63, 67, 76, 76, 77, - 69, 65, 57, 57, 60, 55, 52, 51, 48, 59, 49, 49, 44, 42, 42, 24, - 28, 32, 29, 33, 32, 34, 29, 52, 41, 34, 29, 0, 48, 57, 56, 60, - 56, 67, 40, 30, 33, 25, 6, 99, 97, 83, 72, 75, 67, 65, 65, 65, - 65, 61, 57, 48, 30, 37, 22, 30, 25, 24, 24, 22, 22, 18, 17, 6, - 24, 41, 45, 24, 20, 16, 13, 14, 13, 12, 10, 6, 0, 32, 36, 25, - 24, 153, 147, 147, 143, 144, 140, 143, 124, 88, 14, 63, 119, 115, 95, 122, - 124, 112, 106, 120, 100, 84, 26, 89, 153, 155, 155, 150, 124, 115, 110, 130, - 123, 99, 64, 107, 119, 120, 120, 118, 120, 126, 120, 120, 116, 118, 111, 114, - 83, 61, 48, 53, 73, 37, 28, 33, 24, 24, 37, 161, 126, 144, 92, 146, - 147, 146, 108, 147, 139, 128, 73, 131, 132, 123, 120, 115, 115, 103, 111, 111, - 111, 88, 45, 28, 92, 92, 97, 95, 91, 99, 93, 99, 93, 91, 87, 84, - 81, 81, 84, 77, 67, 68, 68, 61, 57, 57, 0, 32, 124, 132, 100, 110, - 138, 128, 119, 124, 120, 76, 36, 72, 119, 134, 130, 116, 118, 114, 110, 107, - 114, 76, 60, 52, 44, 41, 60, 63, 55, 37, 44, 41, 34, 25, 0, 126, - 92, 114, 107, 115, 120, 123, 126, 96, 87, 55, 108, 123, 130, 124, 118, 124, - 123, 119, 115, 122, 123, 114, 111, 108, 108, 77, 83, 108, 106, 97, 100, 102, - 186, 208, 171, 123, 112, 119, 88, 56, 44, 55, 55, 52, 52, 57, 83, 96, - 132, 190, 216, 218, 218, 214, 163, 122, 124, 132, 144, 146, 146, 136, 104, 38, - 29, 26, 25, 29, 32, 34, 41, 53, 89, 92, 87, 79, 93, 92, 83, 83, - 89, 77, 69, 103, 95, 99, 83, 83, 79, 76, 80, 80, 85, 48, 40, 40, - 55, 48, 48, 49, 57, 60, 80, 92, 65, 46, 52, 56, 56, 53, 51, 51, - 51, 41, 40, 40, 30, 33, 4, 18, 83, 97, 83, 85, 91, 104, 93, 97, - 99, 99, 97, 92, 102, 104, 106, 106, 111, 110, 111, 95, 81, 57, 81, 115, - 115, 119, 104, 103, 100, 99, 88, 95, 89, 68, 30, 52, 56, 52, 55, 55, - 59, 60, 65, 64, 65, 61, 37, 52, 28, 32, 32, 25, 21, 20, 25, 24, - 22, 6, 6, 10, 25, 10, 9, 20, 33, 17, 17, 30, 34, 38, 33, 12, - 26, 30, 30, 41, 59, 45, 56, 65, 64, 52, 0, 32, 53, 59, 59, 59, - 63, 65, 57, 59, 61, 57, 60, 56, 64, 64, 65, 61, 64, 49, 65, 57, - 68, 48, 28, 63, 64, 87, 83, 81, 80, 79, 73, 76, 75, 45, 22, 49, - 28, 33, 21, 22, 24, 30, 14, 13, 18, 28, 20, 18, 20, 24, 24, 25, - 28, 30, 34, 38, 51, 57, 57, 59, 60, 53, 53, 52, 52, 51, 48, 46, - 48, 44, 38, 80, 77, 75, 73, 63, 63, 63, 60, 56, 55, 41, 44, 42, - 42, 46, 38, 36, 30, 30, 28, 29, 14, 10, 73, 81, 100, 102, 95, 92, - 92, 97, 88, 67, 51, 18, 61, 48, 44, 41, 41, 37, 38, 38, 38, 37, - 40, 53, 22, 20, 21, 18, 17, 26, 30, 34, 34, 38, 48, 53, 48, 41, - 44, 45, 41, 42, 41, 42, 40, 41, 38, 36, 34, 40, 38, 37, 33, 37, - 34, 34, 26, 34, 34, 28, 0, 29, 41, 55, 29, 32, 38, 51, 37, 29, - 24, 5, 65, 99, 80, 69, 68, 68, 65, 60, 44, 42, 38, 32, 30, 32, - 20, 14, 28, 25, 21, 25, 22, 25, 20, 20, 8, 13, 22, 20, 16, 8, - 9, 8, 6, 6, 6, 5, 4, 0, 0, 0, 0, 0, 104, 96, 91, 84, - 71, 67, 64, 57, 51, 0, 25, 33, 37, 34, 40, 53, 51, 57, 73, 93, - 76, 25, 107, 73, 72, 68, 67, 89, 67, 55, 48, 83, 76, 42, 36, 29, - 36, 30, 29, 28, 34, 29, 28, 26, 29, 29, 29, 49, 59, 84, 84, 95, - 144, 122, 150, 124, 110, 16, 171, 128, 142, 111, 96, 87, 89, 93, 123, 128, - 122, 68, 84, 87, 91, 76, 72, 68, 57, 53, 46, 52, 38, 32, 21, 18, - 17, 16, 13, 13, 10, 9, 8, 9, 8, 5, 4, 9, 12, 4, 0, 2, - 8, 0, 0, 2, 9, 0, 37, 24, 28, 30, 33, 71, 112, 80, 96, 108, - 71, 4, 68, 48, 53, 48, 49, 49, 55, 42, 46, 44, 42, 45, 32, 38, - 72, 57, 85, 93, 106, 77, 108, 104, 95, 0, 142, 123, 122, 112, 104, 102, - 103, 85, 107, 91, 53, 96, 96, 106, 102, 100, 100, 103, 104, 107, 100, 108, - 103, 102, 99, 68, 51, 51, 52, 59, 100, 97, 106, 150, 198, 187, 128, 88, - 154, 112, 92, 95, 97, 102, 102, 100, 99, 120, 163, 201, 218, 218, 217, 216, - 202, 135, 122, 130, 143, 146, 143, 136, 111, 44, 29, 28, 26, 28, 33, 34, - 20, 42, 53, 48, 53, 59, 60, 60, 63, 64, 71, 80, 81, 76, 80, 64, - 65, 68, 61, 67, 73, 93, 89, 95, 56, 65, 115, 120, 108, 97, 77, 79, - 77, 72, 48, 41, 44, 8, 0, 29, 6, 4, 6, 18, 0, 4, 4, 0, - 0, 29, 29, 21, 20, 18, 24, 24, 21, 21, 25, 26, 28, 29, 32, 36, - 41, 48, 51, 56, 59, 65, 68, 77, 57, 63, 80, 77, 55, 56, 60, 57, - 42, 41, 46, 34, 24, 6, 18, 6, 29, 32, 16, 12, 24, 25, 14, 14, - 22, 25, 68, 83, 93, 97, 91, 103, 96, 99, 69, 64, 4, 18, 128, 139, - 95, 91, 116, 127, 81, 96, 95, 46, 21, 49, 118, 115, 71, 71, 73, 51, - 51, 46, 57, 34, 25, 6, 4, 2, 26, 6, 4, 5, 22, 14, 6, 12, - 28, 24, 24, 24, 33, 32, 29, 53, 45, 37, 38, 64, 34, 12, 55, 21, - 28, 21, 25, 22, 21, 18, 18, 13, 10, 22, 14, 34, 48, 55, 56, 61, - 75, 76, 69, 69, 49, 14, 72, 100, 108, 85, 92, 65, 51, 44, 29, 29, - 25, 24, 30, 25, 34, 20, 22, 32, 22, 29, 32, 34, 34, 28, 49, 44, - 59, 51, 49, 42, 51, 48, 45, 42, 44, 41, 36, 21, 12, 12, 9, 9, - 8, 9, 10, 17, 12, 17, 26, 33, 29, 46, 49, 45, 32, 53, 57, 34, - 14, 46, 34, 37, 34, 33, 30, 33, 41, 45, 48, 48, 64, 4, 37, 112, - 114, 72, 73, 65, 64, 55, 41, 21, 16, 12, 10, 9, 9, 9, 8, 6, - 6, 6, 4, 13, 12, 4, 2, 6, 4, 1, 0, 5, 2, 0, 1, 6, - 0, 0, 9, 9, 14, 13, 13, 14, 16, 17, 30, 24, 4, 63, 92, 65, - 56, 53, 49, 49, 49, 45, 44, 52, 41, 45, 17, 21, 29, 18, 17, 10, - 9, 8, 8, 9, 9, 9, 8, 8, 6, 6, 8, 8, 4, 4, 5, 4, - 2, 2, 2, 2, 1, 1, 1, 84, 97, 100, 99, 114, 110, 120, 123, 115, - 1, 71, 146, 143, 99, 111, 123, 104, 71, 60, 55, 45, 32, 48, 91, 96, - 87, 102, 111, 143, 127, 120, 119, 104, 32, 106, 136, 140, 135, 127, 139, 135, - 140, 140, 140, 79, 24, 93, 171, 174, 161, 158, 154, 151, 154, 166, 151, 104, - 21, 167, 131, 139, 174, 167, 150, 128, 126, 91, 71, 44, 63, 65, 76, 83, - 89, 89, 88, 97, 103, 107, 80, 88, 93, 153, 165, 165, 169, 170, 167, 162, - 163, 171, 162, 138, 130, 162, 158, 153, 165, 163, 159, 139, 120, 161, 136, 42, - 4, 99, 158, 157, 130, 112, 87, 77, 72, 36, 26, 20, 2, 28, 67, 75, - 83, 77, 91, 97, 102, 102, 110, 89, 20, 77, 155, 169, 174, 171, 170, 155, - 165, 157, 122, 95, 0, 138, 127, 150, 146, 150, 143, 139, 122, 112, 89, 52, - 20, 18, 18, 18, 21, 21, 20, 24, 22, 22, 22, 29, 32, 34, 88, 99, - 120, 111, 110, 148, 136, 126, 108, 154, 199, 147, 99, 115, 135, 131, 144, 143, - 134, 140, 151, 162, 195, 213, 216, 220, 218, 214, 213, 153, 124, 128, 139, 142, - 138, 130, 97, 42, 29, 28, 24, 34, 25, 25, 34, 55, 57, 68, 99, 115, - 108, 91, 89, 75, 69, 69, 59, 55, 53, 80, 118, 135, 131, 142, 114, 115, - 124, 103, 100, 52, 93, 140, 126, 108, 108, 123, 112, 116, 87, 81, 73, 12, - 20, 151, 150, 110, 102, 115, 116, 112, 104, 124, 103, 52, 16, 40, 97, 116, - 108, 111, 114, 122, 111, 111, 108, 102, 88, 106, 111, 118, 115, 110, 84, 64, - 52, 37, 38, 42, 33, 37, 67, 63, 76, 69, 80, 81, 89, 88, 81, 69, - 9, 26, 80, 89, 95, 89, 87, 88, 84, 88, 91, 84, 92, 81, 110, 123, - 127, 123, 122, 116, 104, 97, 69, 8, 118, 124, 108, 122, 112, 118, 110, 119, - 115, 96, 57, 16, 110, 127, 128, 118, 119, 122, 114, 87, 100, 102, 63, 52, - 6, 20, 130, 124, 81, 73, 122, 119, 88, 73, 91, 87, 45, 12, 52, 116, - 111, 67, 67, 63, 56, 48, 41, 36, 6, 16, 45, 49, 53, 46, 60, 64, - 59, 63, 67, 57, 0, 41, 116, 115, 112, 114, 116, 108, 108, 104, 81, 51, - 13, 80, 111, 93, 92, 107, 106, 106, 104, 84, 57, 46, 9, 42, 139, 131, - 84, 79, 77, 71, 60, 32, 16, 20, 10, 10, 10, 12, 9, 9, 8, 8, - 5, 8, 6, 6, 5, 10, 17, 67, 79, 83, 81, 68, 91, 76, 33, 12, - 52, 96, 91, 84, 42, 40, 21, 16, 16, 10, 13, 6, 25, 45, 92, 91, - 91, 93, 91, 96, 88, 89, 68, 64, 6, 93, 130, 123, 108, 123, 111, 112, - 111, 110, 102, 100, 77, 72, 92, 73, 59, 68, 81, 72, 69, 59, 48, 12, - 0, 18, 77, 106, 69, 69, 73, 91, 69, 72, 64, 10, 0, 59, 75, 71, - 46, 73, 64, 64, 22, 14, 24, 4, 71, 72, 76, 76, 83, 80, 80, 79, - 80, 83, 76, 49, 30, 21, 24, 49, 42, 37, 41, 40, 29, 22, 13, 16, - 6, 4, 16, 38, 41, 52, 40, 45, 46, 61, 61, 68, 57, 72, 77, 83, - 83, 83, 182, 173, 175, 173, 169, 169, 124, 127, 115, 2, 123, 148, 163, 162, - 158, 159, 155, 153, 155, 147, 85, 30, 118, 173, 175, 173, 167, 165, 174, 169, - 159, 123, 114, 36, 148, 158, 157, 142, 140, 159, 153, 147, 147, 142, 89, 17, - 139, 177, 157, 163, 171, 175, 157, 162, 148, 158, 116, 24, 178, 162, 134, 143, - 107, 135, 148, 162, 169, 151, 131, 139, 159, 148, 158, 167, 155, 155, 165, 158, - 159, 142, 153, 143, 107, 159, 148, 144, 148, 151, 134, 127, 118, 128, 142, 114, - 119, 136, 153, 155, 144, 150, 142, 138, 146, 155, 91, 1, 120, 159, 177, 151, - 154, 122, 134, 134, 126, 107, 72, 16, 95, 166, 163, 163, 158, 158, 112, 146, - 148, 118, 100, 14, 140, 170, 161, 153, 143, 159, 153, 146, 148, 120, 91, 0, - 154, 127, 144, 146, 144, 142, 144, 142, 122, 116, 52, 46, 147, 135, 115, 119, - 139, 139, 115, 115, 114, 111, 108, 102, 104, 93, 144, 158, 155, 146, 143, 144, - 131, 107, 107, 193, 167, 116, 85, 159, 170, 179, 193, 201, 206, 208, 212, 214, - 217, 216, 210, 213, 206, 158, 127, 134, 138, 134, 130, 106, 67, 40, 30, 26, - 24, 33, 24, 36, 46, 60, 56, 51, 92, 132, 150, 143, 138, 142, 150, 144, - 148, 127, 114, 116, 128, 140, 142, 131, 126, 132, 124, 122, 114, 106, 60, 88, - 140, 136, 122, 112, 111, 107, 119, 126, 95, 81, 0, 154, 157, 140, 142, 138, - 139, 136, 118, 116, 111, 108, 114, 14, 147, 142, 131, 132, 126, 130, 119, 122, - 122, 123, 120, 95, 75, 115, 120, 116, 111, 96, 97, 108, 115, 71, 38, 64, - 120, 123, 128, 116, 123, 123, 119, 112, 112, 100, 72, 5, 131, 126, 132, 128, - 118, 115, 108, 100, 104, 100, 81, 85, 126, 144, 140, 130, 130, 120, 122, 124, - 97, 73, 4, 134, 120, 120, 114, 107, 107, 104, 106, 111, 106, 60, 18, 122, - 135, 118, 96, 107, 99, 118, 114, 102, 87, 67, 57, 2, 134, 139, 127, 73, - 88, 115, 111, 89, 88, 89, 89, 52, 14, 112, 123, 106, 103, 107, 100, 114, - 75, 57, 60, 5, 52, 114, 123, 127, 118, 112, 106, 103, 107, 103, 71, 20, - 104, 123, 119, 111, 102, 102, 102, 104, 100, 99, 57, 12, 91, 118, 88, 97, - 85, 87, 88, 96, 99, 87, 53, 8, 120, 142, 118, 114, 123, 119, 115, 84, - 100, 96, 93, 95, 106, 116, 104, 102, 106, 99, 111, 102, 104, 103, 85, 83, - 91, 81, 77, 79, 87, 77, 97, 88, 84, 38, 13, 64, 119, 93, 84, 89, - 68, 79, 73, 55, 48, 33, 34, 77, 102, 106, 114, 106, 106, 97, 102, 89, - 84, 72, 51, 16, 110, 120, 128, 115, 115, 107, 87, 83, 91, 77, 75, 88, - 89, 80, 51, 52, 72, 75, 41, 45, 36, 69, 14, 0, 80, 107, 77, 75, - 69, 65, 72, 65, 69, 75, 22, 0, 67, 68, 61, 69, 83, 67, 68, 64, - 26, 25, 4, 96, 76, 76, 76, 75, 71, 49, 63, 72, 63, 57, 41, 28, - 18, 34, 40, 22, 26, 20, 21, 18, 26, 24, 5, 1, 34, 65, 77, 77, - 81, 73, 64, 55, 68, 53, 63, 57, 59, 48, 65, 84, 72, 195, 187, 175, - 179, 183, 177, 181, 128, 122, 2, 130, 151, 162, 162, 151, 155, 136, 144, 143, - 154, 96, 32, 153, 179, 175, 170, 169, 170, 173, 175, 171, 131, 119, 40, 146, - 170, 175, 182, 173, 174, 169, 165, 151, 144, 99, 20, 136, 177, 163, 165, 146, - 148, 157, 153, 130, 124, 110, 22, 178, 154, 161, 128, 142, 142, 147, 151, 130, - 135, 150, 143, 104, 106, 126, 128, 130, 108, 103, 135, 108, 111, 155, 100, 157, - 154, 165, 163, 155, 161, 158, 161, 153, 144, 140, 96, 148, 175, 166, 155, 161, - 158, 157, 161, 148, 150, 99, 2, 134, 162, 179, 151, 126, 154, 124, 148, 127, - 112, 83, 33, 134, 163, 157, 161, 159, 154, 151, 151, 148, 138, 100, 16, 143, - 171, 138, 143, 148, 150, 144, 159, 142, 131, 100, 0, 150, 123, 142, 142, 139, - 139, 138, 138, 128, 112, 53, 142, 147, 138, 118, 108, 131, 135, 119, 112, 127, - 115, 124, 110, 71, 144, 161, 151, 134, 131, 136, 146, 143, 100, 87, 162, 179, - 126, 81, 115, 119, 136, 155, 182, 194, 202, 205, 204, 205, 210, 194, 173, 148, - 122, 135, 131, 118, 99, 67, 41, 30, 30, 28, 26, 28, 25, 33, 46, 56, - 56, 63, 60, 91, 135, 150, 148, 147, 142, 139, 143, 144, 123, 118, 88, 143, - 142, 124, 126, 134, 136, 134, 126, 96, 116, 57, 84, 130, 127, 120, 122, 119, - 111, 115, 119, 97, 80, 18, 158, 155, 154, 134, 128, 127, 124, 114, 114, 112, - 124, 114, 13, 144, 130, 123, 124, 134, 128, 126, 134, 123, 122, 103, 60, 103, - 150, 131, 119, 116, 111, 111, 120, 115, 76, 52, 114, 120, 116, 111, 108, 118, - 124, 110, 108, 99, 91, 81, 21, 131, 114, 116, 119, 132, 126, 112, 107, 100, - 89, 64, 112, 147, 128, 119, 128, 120, 104, 96, 106, 81, 69, 0, 93, 119, - 111, 100, 92, 97, 110, 110, 123, 102, 61, 13, 110, 132, 106, 100, 83, 92, - 95, 103, 85, 68, 69, 59, 4, 122, 112, 119, 103, 106, 96, 92, 100, 95, - 114, 93, 57, 14, 118, 122, 99, 92, 92, 89, 89, 96, 64, 68, 6, 99, - 123, 120, 115, 104, 115, 114, 107, 87, 85, 60, 13, 107, 122, 111, 100, 99, - 89, 89, 89, 88, 80, 55, 10, 89, 112, 99, 99, 96, 83, 84, 81, 89, - 93, 53, 12, 110, 131, 130, 128, 116, 110, 96, 115, 93, 88, 79, 84, 106, - 111, 122, 92, 102, 106, 102, 100, 87, 100, 92, 71, 55, 102, 111, 92, 88, - 71, 68, 87, 75, 45, 13, 59, 116, 97, 88, 84, 76, 85, 73, 75, 52, - 34, 40, 81, 111, 102, 92, 89, 89, 89, 89, 95, 100, 56, 59, 13, 99, - 118, 126, 119, 115, 85, 85, 114, 110, 107, 96, 69, 45, 84, 84, 57, 53, - 44, 41, 26, 46, 51, 13, 8, 97, 97, 73, 76, 67, 83, 83, 76, 69, - 68, 24, 0, 51, 60, 57, 46, 41, 41, 37, 52, 42, 25, 5, 107, 85, - 65, 76, 59, 55, 46, 55, 55, 57, 55, 41, 21, 26, 44, 36, 24, 9, - 4, 4, 6, 13, 22, 1, 5, 55, 96, 97, 64, 69, 63, 64, 69, 55, - 34, 41, 46, 51, 89, 107, 131, 136, 165, 166, 179, 178, 155, 167, 181, 131, - 122, 2, 127, 162, 162, 147, 144, 153, 147, 146, 139, 143, 104, 37, 130, 182, - 173, 175, 166, 165, 163, 166, 174, 132, 122, 51, 102, 171, 173, 163, 167, 175, - 173, 153, 148, 143, 97, 17, 147, 166, 175, 150, 159, 155, 161, 165, 140, 146, - 122, 10, 175, 155, 157, 128, 136, 140, 155, 147, 146, 143, 95, 100, 104, 158, - 122, 122, 150, 146, 144, 142, 144, 112, 107, 65, 158, 158, 165, 159, 150, 154, - 143, 140, 151, 150, 136, 93, 165, 173, 157, 150, 150, 153, 155, 148, 142, 159, - 93, 0, 138, 163, 158, 131, 130, 151, 150, 158, 158, 144, 87, 14, 154, 162, - 166, 157, 163, 158, 151, 154, 148, 119, 102, 13, 139, 165, 138, 147, 146, 154, - 157, 157, 144, 120, 97, 0, 151, 131, 143, 147, 144, 138, 140, 135, 136, 119, - 53, 143, 134, 135, 131, 139, 135, 116, 128, 127, 118, 111, 107, 68, 88, 153, - 155, 150, 131, 135, 138, 128, 140, 103, 88, 144, 183, 131, 80, 88, 103, 114, - 119, 126, 151, 162, 173, 170, 166, 161, 140, 128, 130, 124, 107, 87, 57, 44, - 32, 28, 26, 26, 36, 21, 26, 45, 46, 52, 55, 69, 64, 55, 96, 154, - 154, 153, 138, 139, 128, 128, 118, 114, 77, 126, 150, 124, 128, 143, 130, 126, - 122, 126, 102, 116, 69, 71, 131, 128, 122, 132, 112, 122, 116, 118, 103, 79, - 14, 106, 151, 139, 142, 151, 135, 130, 126, 115, 111, 115, 75, 17, 104, 123, - 128, 135, 127, 126, 118, 119, 120, 104, 93, 61, 111, 146, 119, 118, 128, 135, - 134, 120, 107, 79, 40, 112, 127, 118, 111, 110, 106, 119, 115, 99, 95, 88, - 80, 5, 114, 108, 119, 104, 124, 134, 126, 107, 103, 80, 46, 110, 150, 127, - 124, 127, 118, 102, 104, 93, 87, 75, 2, 111, 126, 126, 89, 102, 106, 102, - 115, 112, 112, 64, 12, 114, 131, 103, 97, 92, 95, 92, 81, 89, 69, 64, - 61, 4, 97, 114, 83, 107, 108, 99, 97, 95, 93, 95, 89, 67, 13, 104, - 116, 93, 85, 99, 102, 97, 95, 83, 69, 1, 107, 127, 107, 106, 106, 93, - 89, 84, 77, 81, 60, 4, 103, 122, 106, 91, 99, 85, 83, 87, 84, 88, - 56, 9, 88, 112, 110, 96, 107, 107, 103, 87, 87, 73, 55, 10, 100, 127, - 130, 124, 127, 119, 126, 127, 123, 115, 76, 106, 123, 106, 87, 80, 85, 87, - 84, 69, 75, 79, 60, 44, 65, 116, 111, 67, 83, 83, 106, 72, 76, 46, - 17, 64, 111, 95, 75, 91, 92, 81, 84, 75, 59, 37, 37, 80, 112, 99, - 88, 88, 97, 99, 85, 84, 95, 56, 60, 2, 97, 112, 112, 118, 122, 84, - 91, 99, 107, 102, 92, 63, 71, 95, 76, 38, 57, 33, 44, 40, 44, 46, - 12, 0, 76, 85, 76, 75, 65, 72, 77, 76, 75, 60, 24, 0, 75, 69, - 44, 53, 52, 45, 36, 49, 57, 26, 5, 102, 69, 69, 75, 55, 75, 48, - 46, 65, 59, 48, 44, 20, 13, 44, 32, 8, 13, 17, 10, 9, 9, 17, - 1, 10, 76, 99, 65, 56, 63, 41, 55, 85, 60, 42, 52, 40, 51, 93, - 131, 77, 30, 177, 177, 183, 162, 170, 173, 177, 130, 122, 2, 127, 159, 162, - 142, 140, 143, 151, 136, 138, 144, 110, 44, 124, 170, 171, 169, 175, 177, 165, - 162, 166, 135, 124, 51, 157, 175, 171, 163, 165, 173, 173, 154, 150, 147, 99, - 16, 144, 167, 158, 162, 163, 161, 165, 148, 146, 139, 115, 12, 173, 146, 153, - 131, 139, 136, 159, 148, 151, 140, 85, 108, 159, 154, 158, 155, 142, 143, 146, - 138, 142, 134, 134, 57, 157, 169, 163, 154, 155, 147, 159, 140, 146, 144, 134, - 92, 166, 171, 147, 151, 154, 148, 142, 153, 144, 143, 99, 2, 138, 162, 175, - 150, 154, 132, 127, 127, 147, 115, 88, 1, 146, 153, 170, 158, 163, 155, 153, - 153, 128, 128, 103, 13, 148, 163, 143, 153, 153, 148, 144, 153, 148, 130, 97, - 0, 144, 147, 143, 143, 142, 139, 140, 136, 128, 116, 61, 96, 124, 144, 134, - 119, 136, 120, 122, 122, 116, 114, 106, 60, 124, 154, 150, 146, 140, 128, 134, - 138, 143, 116, 87, 138, 186, 144, 110, 72, 75, 73, 79, 95, 114, 116, 120, - 123, 122, 120, 118, 95, 76, 57, 45, 37, 34, 32, 28, 24, 28, 34, 22, - 48, 52, 53, 55, 60, 63, 69, 68, 57, 89, 144, 139, 131, 115, 127, 128, - 127, 116, 95, 77, 131, 143, 124, 135, 130, 131, 118, 116, 130, 115, 118, 76, - 60, 120, 127, 118, 116, 119, 115, 108, 111, 93, 81, 12, 110, 150, 148, 157, - 139, 108, 106, 116, 107, 120, 120, 77, 14, 114, 132, 127, 130, 115, 120, 120, - 120, 106, 106, 97, 57, 110, 150, 127, 115, 116, 110, 108, 123, 108, 77, 41, - 96, 126, 119, 123, 118, 106, 114, 102, 96, 97, 84, 79, 2, 103, 118, 119, - 103, 119, 130, 124, 103, 89, 81, 46, 112, 153, 115, 118, 108, 116, 102, 103, - 87, 92, 72, 4, 122, 124, 118, 92, 99, 110, 112, 106, 112, 104, 67, 9, - 127, 132, 100, 92, 92, 81, 92, 92, 76, 75, 68, 57, 1, 104, 135, 112, - 110, 104, 99, 89, 110, 93, 96, 92, 56, 8, 104, 120, 89, 88, 91, 89, - 87, 92, 64, 67, 1, 107, 122, 93, 107, 91, 84, 88, 79, 83, 68, 60, - 14, 111, 122, 100, 95, 81, 87, 83, 80, 72, 87, 56, 8, 87, 108, 106, - 88, 81, 88, 81, 83, 87, 76, 56, 6, 114, 138, 128, 132, 111, 115, 114, - 119, 112, 111, 52, 104, 112, 106, 92, 84, 76, 80, 77, 77, 77, 60, 69, - 41, 106, 123, 120, 64, 93, 89, 95, 71, 71, 60, 21, 65, 115, 97, 89, - 92, 95, 79, 73, 84, 73, 36, 18, 68, 110, 84, 76, 73, 79, 85, 79, - 73, 99, 67, 60, 5, 110, 115, 111, 116, 110, 92, 88, 83, 116, 96, 92, - 57, 76, 103, 65, 37, 46, 25, 30, 40, 37, 42, 14, 0, 67, 95, 69, - 67, 64, 64, 67, 63, 57, 63, 25, 0, 55, 59, 59, 55, 64, 56, 37, - 42, 46, 26, 5, 110, 68, 67, 75, 49, 79, 46, 46, 45, 51, 44, 40, - 18, 22, 37, 25, 4, 10, 2, 4, 1, 5, 22, 1, 33, 89, 89, 49, - 52, 64, 52, 44, 68, 33, 29, 44, 36, 71, 108, 107, 24, 32, 181, 183, - 162, 166, 170, 154, 171, 142, 116, 2, 132, 163, 162, 142, 142, 144, 144, 138, - 138, 139, 114, 49, 118, 173, 175, 174, 167, 173, 173, 162, 163, 148, 123, 56, - 157, 171, 170, 167, 159, 161, 162, 153, 151, 143, 97, 12, 148, 174, 162, 159, - 161, 158, 167, 155, 144, 146, 123, 12, 177, 166, 146, 148, 138, 139, 138, 150, - 154, 142, 81, 151, 162, 154, 153, 146, 142, 154, 159, 139, 154, 144, 146, 73, - 165, 157, 155, 148, 154, 140, 159, 139, 148, 143, 120, 102, 170, 166, 148, 155, - 147, 154, 151, 163, 143, 144, 104, 0, 136, 165, 175, 148, 138, 135, 132, 130, - 159, 112, 93, 10, 148, 166, 161, 154, 159, 148, 147, 153, 130, 134, 104, 10, - 148, 170, 144, 144, 150, 150, 150, 153, 147, 128, 100, 0, 148, 138, 144, 148, - 139, 138, 142, 132, 122, 118, 64, 99, 122, 128, 124, 126, 138, 127, 116, 122, - 112, 120, 111, 52, 124, 155, 155, 136, 140, 127, 136, 144, 131, 124, 85, 126, - 185, 155, 124, 103, 77, 64, 60, 60, 55, 55, 53, 53, 57, 53, 49, 46, - 41, 40, 36, 34, 30, 30, 29, 34, 18, 30, 53, 60, 67, 68, 68, 65, - 67, 72, 72, 59, 91, 151, 130, 134, 134, 131, 122, 140, 126, 112, 59, 127, - 144, 124, 139, 123, 115, 115, 114, 127, 116, 115, 83, 42, 123, 134, 136, 132, - 130, 126, 118, 111, 100, 81, 2, 111, 144, 134, 146, 107, 102, 114, 116, 108, - 111, 116, 107, 9, 146, 138, 116, 138, 120, 110, 108, 110, 106, 122, 100, 55, - 118, 140, 123, 123, 111, 111, 104, 118, 112, 80, 45, 95, 124, 138, 147, 115, - 103, 96, 99, 97, 100, 92, 76, 0, 143, 112, 112, 104, 116, 115, 124, 104, - 91, 87, 45, 111, 151, 127, 122, 104, 114, 99, 99, 85, 96, 80, 0, 130, - 124, 126, 93, 97, 97, 116, 116, 115, 111, 67, 12, 123, 136, 102, 92, 87, - 81, 77, 93, 71, 77, 69, 63, 2, 142, 142, 112, 119, 85, 99, 114, 87, - 87, 100, 89, 60, 5, 111, 116, 91, 85, 89, 128, 93, 100, 64, 67, 0, - 108, 124, 95, 103, 83, 93, 81, 77, 79, 88, 63, 22, 106, 118, 91, 100, - 84, 81, 81, 83, 76, 89, 56, 5, 85, 111, 96, 80, 81, 88, 106, 84, - 83, 87, 57, 5, 110, 142, 126, 123, 110, 111, 110, 110, 114, 104, 49, 106, - 123, 93, 115, 97, 83, 77, 77, 72, 67, 64, 68, 38, 104, 114, 110, 69, - 99, 103, 69, 72, 52, 44, 20, 68, 115, 85, 85, 87, 67, 60, 57, 75, - 79, 37, 25, 81, 108, 97, 76, 73, 71, 72, 69, 83, 93, 71, 56, 6, - 110, 126, 112, 112, 85, 85, 87, 83, 111, 91, 93, 52, 76, 100, 71, 29, - 45, 25, 32, 37, 40, 41, 12, 0, 81, 88, 73, 65, 61, 75, 73, 67, - 52, 64, 25, 0, 71, 61, 49, 46, 38, 67, 44, 44, 40, 26, 8, 96, - 80, 77, 46, 33, 81, 44, 44, 41, 59, 33, 40, 17, 17, 29, 22, 14, - 36, 21, 22, 8, 6, 14, 0, 44, 92, 81, 45, 49, 51, 45, 59, 76, - 33, 30, 34, 34, 63, 108, 46, 38, 33, 181, 177, 161, 169, 170, 153, 174, - 136, 123, 0, 130, 158, 161, 142, 144, 140, 151, 134, 142, 143, 118, 60, 88, - 163, 178, 170, 173, 170, 165, 161, 162, 158, 124, 64, 123, 174, 159, 167, 170, - 163, 166, 157, 148, 153, 106, 16, 148, 174, 159, 157, 169, 161, 161, 144, 131, - 136, 124, 9, 175, 162, 166, 143, 139, 139, 143, 153, 153, 139, 77, 157, 162, - 155, 148, 142, 144, 169, 140, 136, 131, 146, 158, 65, 161, 153, 158, 154, 153, - 147, 163, 138, 144, 142, 92, 106, 171, 174, 150, 169, 151, 150, 158, 166, 139, - 144, 115, 0, 140, 162, 169, 148, 153, 139, 136, 126, 153, 120, 96, 22, 143, - 166, 157, 157, 151, 144, 162, 153, 140, 132, 110, 12, 150, 171, 136, 151, 150, - 146, 147, 157, 140, 128, 99, 0, 147, 136, 144, 143, 134, 134, 139, 134, 135, - 112, 68, 99, 146, 115, 128, 131, 146, 123, 135, 131, 103, 124, 100, 46, 139, - 163, 154, 143, 140, 124, 128, 143, 128, 127, 87, 118, 181, 163, 139, 127, 112, - 96, 71, 61, 56, 52, 49, 48, 46, 44, 44, 41, 38, 37, 36, 34, 34, - 37, 37, 14, 28, 57, 69, 73, 72, 84, 85, 88, 89, 76, 76, 68, 85, - 162, 136, 126, 138, 131, 128, 127, 126, 118, 51, 128, 138, 124, 124, 126, 115, - 130, 119, 119, 118, 119, 85, 37, 107, 131, 136, 122, 118, 112, 112, 111, 102, - 84, 12, 123, 143, 138, 142, 103, 104, 122, 107, 108, 119, 123, 111, 9, 142, - 131, 119, 138, 115, 112, 114, 103, 100, 119, 99, 45, 111, 154, 122, 115, 115, - 112, 108, 120, 111, 80, 49, 87, 132, 135, 116, 104, 114, 96, 112, 110, 106, - 93, 84, 14, 138, 104, 120, 99, 114, 97, 135, 102, 92, 84, 45, 112, 150, - 119, 126, 108, 108, 111, 89, 85, 84, 76, 0, 114, 123, 124, 92, 106, 92, - 102, 103, 118, 96, 68, 8, 122, 136, 107, 100, 88, 85, 84, 96, 75, 71, - 73, 63, 1, 134, 150, 107, 114, 85, 102, 95, 102, 88, 89, 87, 61, 9, - 103, 127, 92, 92, 115, 112, 97, 91, 65, 68, 8, 112, 124, 88, 93, 81, - 81, 79, 88, 79, 87, 64, 9, 104, 122, 100, 102, 96, 102, 99, 102, 77, - 92, 60, 4, 93, 104, 89, 87, 116, 81, 80, 81, 83, 93, 59, 9, 142, - 139, 128, 114, 112, 124, 108, 112, 111, 111, 56, 111, 108, 112, 93, 110, 89, - 75, 77, 64, 65, 63, 69, 34, 110, 124, 106, 64, 93, 87, 69, 68, 71, - 48, 22, 71, 120, 73, 76, 64, 56, 56, 55, 57, 72, 38, 42, 77, 108, - 107, 75, 71, 67, 83, 68, 69, 89, 72, 57, 5, 103, 126, 108, 106, 92, - 84, 83, 87, 97, 91, 88, 48, 87, 107, 60, 32, 28, 20, 28, 36, 29, - 57, 12, 5, 87, 92, 69, 69, 72, 68, 55, 72, 60, 63, 26, 0, 77, - 68, 46, 51, 46, 38, 45, 44, 36, 28, 8, 84, 87, 56, 64, 48, 83, - 41, 41, 42, 51, 34, 36, 12, 17, 22, 24, 25, 17, 22, 22, 5, 8, - 8, 0, 44, 100, 68, 46, 55, 57, 51, 60, 96, 37, 34, 36, 32, 76, - 107, 41, 63, 63, 183, 163, 161, 162, 167, 151, 181, 134, 127, 0, 130, 155, - 162, 142, 154, 139, 143, 131, 136, 135, 127, 84, 93, 162, 178, 178, 174, 163, - 178, 170, 163, 162, 124, 65, 83, 173, 173, 163, 163, 163, 155, 163, 151, 144, - 111, 12, 157, 171, 159, 158, 153, 157, 157, 142, 131, 139, 124, 6, 175, 162, - 154, 139, 144, 135, 161, 154, 147, 139, 69, 163, 151, 147, 146, 146, 165, 144, - 138, 143, 146, 131, 143, 38, 166, 157, 153, 153, 136, 150, 163, 132, 153, 132, - 93, 126, 177, 165, 151, 165, 154, 147, 153, 167, 138, 139, 112, 0, 146, 154, - 174, 147, 138, 130, 138, 131, 166, 138, 115, 12, 151, 167, 153, 153, 143, 143, - 162, 148, 140, 126, 115, 9, 140, 170, 147, 144, 144, 140, 144, 157, 134, 132, - 96, 0, 148, 128, 140, 136, 131, 128, 136, 131, 131, 118, 72, 52, 108, 155, - 140, 131, 104, 124, 108, 114, 107, 127, 104, 41, 151, 161, 158, 134, 147, 126, - 127, 143, 122, 124, 92, 102, 171, 163, 162, 132, 126, 114, 97, 81, 77, 63, - 57, 52, 49, 48, 46, 49, 48, 52, 49, 51, 46, 42, 51, 13, 53, 73, - 75, 77, 96, 99, 106, 110, 110, 79, 77, 60, 84, 167, 136, 144, 114, 138, - 144, 114, 122, 116, 51, 123, 138, 126, 128, 119, 115, 136, 119, 122, 115, 123, - 89, 41, 110, 130, 132, 122, 115, 115, 114, 115, 100, 83, 9, 124, 140, 135, - 154, 102, 106, 114, 104, 110, 108, 114, 79, 9, 106, 128, 111, 146, 118, 118, - 112, 104, 104, 123, 100, 40, 111, 154, 116, 115, 116, 108, 116, 107, 106, 84, - 48, 99, 131, 139, 104, 104, 97, 108, 106, 97, 96, 89, 83, 1, 124, 108, - 115, 99, 119, 96, 123, 100, 92, 80, 28, 107, 150, 123, 128, 108, 106, 97, - 93, 91, 88, 76, 0, 118, 114, 136, 89, 96, 92, 92, 102, 122, 102, 69, - 6, 124, 142, 108, 111, 84, 92, 81, 104, 75, 68, 71, 64, 0, 112, 122, - 88, 124, 87, 100, 88, 103, 87, 91, 84, 60, 8, 112, 131, 92, 84, 112, - 91, 92, 92, 77, 71, 0, 107, 116, 95, 80, 79, 79, 76, 103, 80, 100, - 67, 2, 91, 119, 112, 87, 95, 89, 85, 80, 76, 99, 61, 4, 89, 104, - 87, 108, 120, 99, 79, 80, 81, 85, 60, 6, 126, 131, 128, 110, 112, 127, - 108, 108, 107, 110, 52, 116, 122, 96, 99, 103, 84, 68, 88, 65, 64, 69, - 61, 30, 112, 116, 69, 107, 67, 71, 77, 69, 71, 52, 28, 45, 114, 75, - 68, 59, 53, 56, 52, 56, 73, 41, 25, 72, 103, 114, 72, 63, 65, 89, - 68, 69, 100, 60, 60, 2, 104, 127, 110, 84, 85, 81, 83, 111, 97, 85, - 85, 40, 87, 99, 80, 29, 28, 21, 26, 37, 30, 38, 14, 0, 61, 84, - 56, 52, 49, 63, 55, 75, 52, 84, 26, 0, 64, 67, 45, 38, 41, 46, - 42, 36, 45, 30, 9, 36, 102, 52, 48, 44, 67, 38, 38, 38, 60, 32, - 29, 8, 24, 16, 2, 6, 6, 20, 8, 5, 13, 2, 0, 49, 93, 59, - 37, 55, 42, 49, 48, 83, 44, 38, 34, 26, 71, 111, 45, 61, 5, 183, - 162, 163, 166, 169, 142, 181, 135, 118, 0, 128, 151, 166, 139, 159, 136, 142, - 134, 134, 123, 138, 88, 68, 157, 181, 179, 181, 163, 175, 183, 158, 169, 120, - 72, 55, 179, 177, 150, 150, 159, 166, 166, 148, 144, 114, 10, 159, 177, 159, - 158, 157, 154, 147, 150, 132, 139, 124, 6, 173, 162, 165, 138, 138, 138, 147, - 153, 148, 136, 55, 169, 146, 151, 138, 169, 155, 142, 138, 148, 154, 134, 130, - 33, 158, 161, 150, 138, 140, 151, 170, 128, 148, 131, 84, 136, 178, 169, 150, - 166, 147, 150, 151, 170, 140, 140, 118, 0, 140, 153, 174, 132, 143, 132, 144, - 132, 179, 120, 110, 1, 158, 165, 151, 151, 139, 140, 166, 146, 136, 131, 112, - 8, 136, 169, 143, 144, 142, 134, 144, 163, 136, 138, 99, 0, 144, 139, 136, - 131, 124, 140, 131, 130, 123, 110, 75, 64, 108, 157, 158, 115, 131, 123, 104, - 112, 103, 142, 99, 33, 147, 161, 166, 138, 153, 151, 124, 138, 120, 115, 92, - 96, 161, 169, 158, 154, 134, 122, 111, 104, 92, 80, 64, 68, 65, 64, 63, - 63, 51, 55, 52, 49, 42, 44, 56, 10, 57, 79, 72, 92, 93, 95, 116, - 127, 126, 106, 77, 69, 76, 167, 132, 150, 116, 143, 130, 116, 120, 104, 41, - 127, 135, 123, 127, 119, 116, 144, 115, 123, 114, 135, 99, 46, 112, 126, 114, - 116, 116, 116, 108, 118, 102, 80, 2, 128, 131, 131, 165, 102, 103, 108, 103, - 110, 106, 119, 88, 5, 114, 132, 114, 144, 116, 118, 110, 104, 99, 130, 93, - 33, 112, 163, 114, 116, 114, 106, 103, 104, 102, 84, 52, 88, 134, 111, 104, - 102, 102, 99, 100, 104, 97, 87, 81, 2, 139, 108, 110, 97, 130, 95, 135, - 96, 87, 75, 26, 103, 148, 112, 135, 102, 102, 102, 89, 81, 93, 79, 0, - 134, 114, 128, 88, 97, 119, 122, 102, 130, 103, 72, 4, 138, 150, 114, 112, - 81, 85, 84, 115, 87, 67, 75, 64, 0, 114, 136, 104, 124, 87, 95, 89, - 112, 84, 93, 85, 64, 4, 115, 124, 91, 87, 119, 87, 96, 91, 69, 71, - 0, 114, 131, 92, 79, 80, 73, 76, 111, 80, 72, 65, 2, 88, 122, 123, - 85, 81, 80, 77, 71, 72, 110, 61, 2, 85, 96, 87, 110, 132, 80, 79, - 77, 81, 102, 63, 4, 130, 143, 138, 108, 107, 132, 106, 106, 106, 107, 32, - 122, 119, 114, 85, 114, 83, 69, 75, 61, 64, 61, 63, 24, 118, 116, 69, - 115, 65, 71, 69, 68, 68, 52, 30, 36, 114, 72, 60, 56, 88, 57, 52, - 56, 63, 41, 26, 60, 76, 122, 68, 65, 64, 79, 67, 65, 87, 65, 56, - 2, 97, 130, 103, 85, 83, 83, 81, 112, 95, 89, 87, 30, 92, 100, 83, - 29, 20, 20, 30, 25, 26, 32, 17, 0, 55, 83, 42, 38, 38, 45, 52, - 84, 51, 60, 29, 0, 57, 59, 48, 37, 42, 41, 40, 44, 46, 29, 20, - 16, 103, 57, 45, 44, 59, 38, 37, 37, 40, 33, 26, 9, 8, 16, 1, - 32, 2, 0, 2, 5, 5, 2, 0, 42, 85, 45, 42, 57, 45, 37, 56, - 91, 29, 28, 40, 22, 92, 106, 9, 8, 0, 9, 12, 9, 12, 12, 56, - 59, 12, 14, 0, 34, 80, 80, 75, 80, 34, 30, 73, 80, 22, 10, 68, - 85, 88, 60, 85, 40, 44, 44, 76, 42, 30, 26, 0, 85, 110, 104, 32, - 108, 34, 36, 41, 77, 77, 16, 38, 91, 88, 91, 93, 96, 91, 60, 51, - 81, 77, 84, 16, 76, 53, 42, 44, 85, 89, 60, 48, 42, 38, 42, 24, - 89, 108, 56, 59, 60, 49, 95, 51, 67, 49, 42, 21, 59, 102, 52, 53, - 55, 100, 92, 57, 93, 45, 48, 2, 99, 103, 68, 110, 130, 71, 56, 97, - 61, 89, 32, 34, 112, 120, 114, 52, 42, 51, 80, 52, 83, 46, 48, 12, - 99, 106, 118, 111, 96, 100, 96, 69, 68, 57, 49, 0, 104, 108, 102, 106, - 76, 71, 68, 99, 130, 73, 71, 20, 99, 131, 112, 73, 73, 103, 77, 72, - 65, 65, 44, 72, 139, 119, 80, 116, 104, 76, 80, 77, 107, 139, 68, 1, - 114, 93, 116, 114, 91, 77, 83, 108, 112, 104, 21, 118, 120, 87, 91, 88, - 88, 119, 92, 76, 87, 115, 24, 115, 116, 96, 119, 119, 111, 100, 93, 95, - 77, 77, 71, 2, 76, 136, 106, 110, 84, 108, 75, 114, 84, 80, 72, 26, - 120, 126, 99, 128, 108, 92, 88, 83, 80, 83, 68, 10, 119, 122, 130, 127, - 93, 96, 106, 89, 122, 69, 14, 159, 140, 142, 118, 161, 140, 136, 112, 122, - 116, 118, 104, 60, 87, 139, 128, 111, 104, 108, 130, 107, 127, 92, 53, 69, - 159, 175, 159, 181, 142, 136, 138, 162, 130, 127, 38, 106, 136, 139, 132, 110, - 106, 111, 142, 108, 107, 111, 52, 93, 140, 161, 135, 166, 114, 112, 102, 111, - 100, 115, 110, 30, 131, 116, 119, 114, 136, 119, 112, 115, 135, 96, 114, 30, - 162, 144, 140, 140, 142, 126, 128, 148, 112, 112, 102, 9, 110, 153, 136, 157, - 108, 114, 110, 126, 112, 112, 49, 134, 146, 146, 144, 143, 124, 128, 150, 148, - 122, 115, 96, 5, 144, 134, 150, 151, 122, 134, 112, 119, 119, 139, 116, 5, - 170, 153, 178, 143, 135, 147, 122, 119, 123, 119, 60, 93, 148, 123, 161, 147, - 112, 147, 148, 103, 122, 112, 10, 153, 191, 174, 157, 150, 154, 193, 170, 150, - 150, 134, 131, 5, 124, 131, 135, 103, 104, 99, 111, 106, 118, 119, 107, 34, - 153, 157, 136, 158, 140, 154, 124, 134, 123, 124, 123, 17, 162, 174, 163, 165, - 175, 132, 162, 165, 144, 139, 134, 92, 0, 170, 181, 174, 169, 170, 153, 150, - 147, 140, 144, 12, 163, 151, 167, 144, 128, 157, 140, 159, 139, 128, 37, 159, - 179, 155, 150, 135, 150, 123, 163, 177, 151, 142, 112, 76, 96, 171, 167, 171, - 170, 155, 146, 147, 146, 151, 135, 41, 166, 169, 151, 167, 147, 170, 148, 147, - 147, 131, 6, 187, 185, 182, 153, 146, 175, 171, 170, 185, 157, 138, 136, 14, - 154, 138, 139, 153, 150, 178, 167, 155, 130, 135, 124, 14, 153, 154, 169, 157, - 174, 139, 148, 147, 136, 139, 115, 0, 173, 179, 158, 159, 146, 150, 163, 177, - 162, 144, 116, 73, 115, 185, 173, 161, 155, 183, 155, 155, 144, 151, 163, 76, - 88, 187, 174, 198, 174, 68, 57, 63, 12, 12, 45, 55, 20, 13, 0, 41, - 89, 71, 65, 84, 41, 29, 68, 79, 21, 9, 68, 72, 85, 73, 55, 38, - 45, 44, 71, 52, 34, 26, 0, 83, 97, 92, 37, 91, 37, 34, 55, 67, - 64, 26, 44, 87, 85, 87, 69, 67, 48, 51, 71, 53, 65, 75, 28, 72, - 61, 44, 44, 52, 89, 79, 59, 44, 37, 41, 30, 89, 112, 61, 59, 71, - 57, 93, 61, 72, 49, 37, 20, 59, 102, 55, 53, 55, 95, 88, 60, 89, - 44, 45, 1, 97, 99, 87, 104, 123, 77, 56, 93, 65, 80, 25, 40, 93, - 111, 64, 42, 49, 57, 65, 67, 53, 42, 42, 17, 95, 100, 97, 131, 106, - 92, 96, 95, 65, 59, 51, 0, 102, 106, 112, 100, 76, 72, 77, 92, 112, - 89, 71, 22, 93, 126, 110, 77, 76, 99, 103, 72, 61, 67, 41, 72, 127, - 103, 80, 91, 92, 96, 77, 77, 99, 126, 61, 0, 112, 100, 103, 111, 92, - 81, 87, 100, 110, 102, 26, 124, 116, 93, 96, 80, 111, 111, 84, 87, 77, - 103, 36, 110, 116, 110, 114, 97, 97, 99, 92, 104, 76, 79, 63, 1, 85, - 122, 96, 83, 95, 97, 80, 100, 83, 83, 75, 37, 115, 128, 102, 120, 116, - 100, 106, 104, 92, 81, 79, 9, 115, 118, 116, 99, 95, 112, 95, 97, 112, - 75, 20, 148, 139, 140, 126, 138, 140, 132, 118, 130, 116, 124, 106, 55, 88, - 140, 127, 100, 110, 124, 122, 104, 123, 99, 52, 75, 155, 166, 154, 165, 140, - 132, 136, 157, 130, 124, 46, 111, 135, 138, 124, 107, 110, 111, 134, 110, 104, - 103, 49, 92, 140, 153, 135, 153, 122, 115, 108, 108, 102, 114, 108, 45, 116, - 120, 123, 138, 136, 124, 111, 112, 124, 104, 111, 32, 157, 148, 131, 131, 119, - 119, 130, 144, 106, 112, 103, 8, 116, 142, 128, 154, 103, 114, 114, 118, 110, - 107, 48, 130, 143, 146, 142, 128, 143, 144, 144, 131, 119, 112, 96, 5, 144, - 134, 147, 142, 123, 130, 126, 107, 128, 130, 110, 6, 163, 163, 159, 139, 127, - 148, 123, 124, 119, 116, 57, 100, 144, 144, 153, 127, 112, 144, 147, 106, 122, - 108, 12, 147, 183, 170, 167, 136, 140, 173, 166, 147, 150, 142, 135, 24, 131, - 127, 135, 103, 97, 100, 100, 111, 115, 115, 106, 42, 150, 155, 130, 148, 148, - 154, 126, 130, 131, 123, 103, 18, 158, 162, 161, 163, 157, 136, 158, 161, 148, - 139, 124, 93, 0, 174, 181, 170, 165, 155, 151, 150, 139, 138, 138, 1, 154, - 159, 165, 136, 124, 153, 139, 157, 140, 126, 48, 155, 179, 159, 144, 132, 143, - 124, 134, 136, 138, 140, 110, 71, 99, 175, 161, 165, 169, 151, 144, 148, 154, - 150, 139, 51, 162, 163, 154, 157, 159, 169, 148, 147, 144, 110, 6, 181, 178, - 173, 159, 147, 177, 173, 162, 162, 159, 136, 124, 14, 150, 139, 150, 151, 150, - 151, 171, 165, 142, 139, 119, 8, 151, 154, 147, 162, 170, 158, 136, 143, 138, - 130, 112, 0, 178, 175, 154, 158, 148, 151, 155, 177, 163, 158, 112, 67, 120, - 181, 170, 163, 154, 177, 157, 154, 146, 147, 161, 72, 87, 190, 175, 194, 177, - 22, 46, 24, 12, 12, 38, 56, 20, 14, 2, 49, 81, 65, 73, 73, 45, - 28, 51, 73, 22, 9, 67, 79, 76, 79, 45, 48, 38, 48, 65, 51, 36, - 25, 0, 81, 80, 45, 75, 57, 37, 37, 44, 75, 64, 24, 46, 89, 72, - 49, 49, 72, 69, 69, 61, 64, 60, 81, 24, 64, 60, 46, 42, 44, 64, - 81, 75, 55, 38, 38, 32, 89, 114, 59, 63, 60, 60, 68, 75, 64, 51, - 48, 18, 64, 84, 60, 53, 73, 93, 67, 79, 81, 44, 45, 1, 83, 97, - 72, 71, 68, 63, 57, 92, 69, 75, 24, 40, 100, 106, 60, 36, 57, 36, - 42, 41, 42, 48, 42, 17, 91, 100, 99, 100, 116, 100, 80, 91, 68, 59, - 51, 0, 99, 114, 107, 92, 83, 71, 72, 75, 72, 81, 72, 28, 85, 124, - 106, 77, 73, 84, 104, 68, 68, 68, 40, 75, 124, 114, 110, 97, 93, 95, - 93, 80, 93, 112, 75, 2, 102, 103, 110, 102, 100, 85, 89, 96, 104, 96, - 30, 118, 116, 89, 87, 110, 89, 77, 91, 88, 72, 96, 40, 104, 115, 103, - 99, 106, 102, 96, 96, 91, 76, 76, 80, 13, 73, 116, 92, 91, 96, 93, - 85, 93, 81, 80, 75, 41, 111, 126, 102, 119, 107, 107, 96, 99, 93, 88, - 76, 8, 112, 116, 107, 99, 111, 89, 96, 88, 107, 64, 26, 140, 138, 139, - 132, 123, 114, 116, 127, 116, 122, 119, 104, 52, 92, 135, 124, 104, 110, 138, - 124, 108, 114, 102, 52, 107, 155, 155, 153, 158, 147, 138, 142, 155, 130, 127, - 55, 107, 136, 136, 124, 107, 114, 112, 131, 108, 102, 97, 45, 96, 136, 148, - 136, 148, 131, 112, 108, 103, 100, 112, 108, 49, 124, 124, 119, 146, 122, 120, - 114, 112, 123, 106, 114, 46, 146, 144, 128, 134, 151, 153, 151, 140, 107, 114, - 91, 16, 115, 134, 124, 126, 102, 108, 115, 104, 107, 107, 64, 123, 143, 144, - 142, 132, 128, 123, 130, 120, 116, 116, 93, 17, 148, 139, 157, 116, 107, 114, - 120, 107, 122, 119, 110, 8, 161, 151, 165, 155, 140, 153, 126, 123, 126, 99, - 65, 112, 136, 150, 139, 112, 119, 144, 147, 110, 114, 107, 14, 140, 183, 171, - 163, 157, 143, 151, 143, 148, 150, 139, 127, 10, 130, 136, 119, 100, 100, 103, - 103, 107, 119, 115, 89, 46, 146, 155, 142, 140, 128, 148, 126, 124, 127, 126, - 124, 2, 154, 159, 162, 171, 140, 136, 150, 163, 144, 142, 124, 91, 0, 163, - 186, 169, 165, 154, 155, 154, 159, 131, 142, 1, 148, 147, 132, 124, 151, 147, - 143, 154, 136, 127, 55, 153, 177, 158, 167, 130, 124, 127, 128, 132, 135, 138, - 96, 61, 104, 170, 158, 161, 166, 154, 147, 150, 148, 151, 135, 65, 154, 161, - 159, 161, 158, 163, 150, 142, 147, 134, 8, 179, 170, 167, 155, 148, 174, 174, - 163, 155, 155, 134, 130, 0, 153, 130, 135, 154, 150, 147, 144, 169, 154, 139, - 115, 10, 150, 154, 147, 190, 159, 135, 162, 158, 131, 132, 110, 0, 173, 175, - 169, 162, 157, 148, 165, 169, 161, 148, 112, 63, 124, 139, 169, 163, 148, 144, - 146, 150, 150, 147, 150, 63, 103, 189, 178, 190, 185, 16, 36, 25, 10, 12, - 33, 45, 16, 14, 0, 51, 92, 61, 60, 72, 68, 33, 45, 59, 22, 8, - 65, 75, 67, 42, 41, 61, 51, 52, 56, 64, 33, 25, 2, 79, 73, 40, - 65, 42, 40, 37, 49, 57, 41, 25, 52, 84, 67, 92, 60, 79, 68, 64, - 60, 49, 63, 68, 26, 63, 76, 55, 42, 44, 44, 51, 64, 44, 40, 37, - 33, 92, 123, 48, 53, 57, 75, 65, 59, 49, 48, 48, 17, 61, 91, 56, - 57, 81, 71, 73, 75, 59, 45, 44, 2, 93, 97, 91, 89, 85, 59, 76, - 71, 81, 52, 21, 40, 89, 55, 36, 29, 30, 24, 29, 28, 30, 44, 36, - 16, 87, 99, 89, 93, 110, 112, 83, 72, 73, 65, 42, 0, 97, 106, 104, - 89, 87, 99, 83, 81, 76, 80, 72, 32, 83, 104, 103, 80, 76, 80, 96, - 80, 65, 51, 34, 73, 119, 108, 112, 120, 102, 116, 106, 92, 88, 103, 72, - 0, 99, 107, 95, 97, 97, 87, 83, 96, 89, 91, 34, 114, 114, 91, 91, - 89, 89, 76, 79, 88, 68, 88, 44, 102, 110, 107, 110, 104, 100, 97, 99, - 103, 77, 77, 79, 4, 81, 100, 84, 77, 93, 88, 83, 93, 75, 81, 75, - 48, 107, 126, 106, 118, 123, 89, 100, 99, 93, 84, 68, 16, 99, 115, 124, - 104, 83, 110, 97, 102, 103, 60, 24, 127, 140, 138, 130, 115, 120, 123, 116, - 115, 123, 122, 106, 44, 96, 134, 119, 100, 114, 119, 114, 104, 111, 102, 52, - 84, 153, 162, 146, 136, 136, 142, 151, 150, 131, 126, 61, 106, 132, 143, 111, - 112, 110, 107, 139, 108, 89, 91, 41, 96, 138, 135, 130, 135, 140, 112, 116, - 106, 102, 112, 108, 53, 118, 123, 124, 130, 123, 122, 118, 112, 119, 106, 114, - 51, 144, 144, 128, 135, 131, 135, 124, 122, 122, 120, 85, 22, 112, 126, 135, - 123, 100, 111, 112, 100, 108, 110, 67, 123, 140, 143, 139, 146, 124, 123, 123, - 128, 110, 114, 96, 9, 136, 131, 120, 142, 100, 134, 134, 108, 103, 126, 112, - 9, 150, 154, 163, 143, 136, 162, 131, 127, 123, 114, 68, 115, 122, 143, 135, - 114, 116, 138, 138, 106, 115, 103, 12, 146, 178, 167, 143, 153, 148, 143, 140, - 150, 153, 138, 127, 16, 102, 134, 100, 95, 108, 95, 110, 112, 116, 106, 97, - 52, 139, 130, 126, 132, 126, 142, 132, 130, 131, 123, 126, 0, 153, 158, 158, - 169, 136, 140, 148, 155, 151, 135, 124, 88, 0, 165, 186, 163, 161, 155, 155, - 154, 159, 128, 131, 1, 142, 147, 130, 118, 151, 124, 138, 131, 140, 124, 64, - 147, 165, 148, 139, 132, 124, 128, 128, 132, 131, 143, 102, 55, 112, 167, 159, - 148, 161, 161, 146, 147, 151, 144, 138, 68, 155, 161, 158, 147, 154, 155, 150, - 147, 143, 136, 9, 170, 167, 162, 155, 150, 173, 178, 179, 169, 157, 135, 127, - 2, 147, 134, 146, 122, 130, 146, 144, 140, 148, 139, 122, 14, 150, 157, 143, - 163, 130, 138, 131, 132, 131, 124, 106, 0, 148, 175, 159, 159, 158, 155, 161, - 163, 159, 144, 104, 53, 130, 143, 143, 163, 151, 151, 153, 151, 143, 134, 135, - 59, 104, 183, 177, 178, 185, 9, 10, 10, 10, 12, 38, 38, 12, 12, 0, - 48, 56, 61, 59, 67, 67, 38, 34, 46, 21, 6, 61, 84, 75, 48, 60, - 75, 60, 55, 59, 42, 30, 25, 0, 77, 79, 36, 71, 40, 41, 36, 41, - 61, 40, 28, 52, 80, 83, 64, 61, 75, 81, 67, 67, 67, 59, 68, 26, - 36, 65, 59, 42, 46, 44, 45, 45, 51, 37, 38, 36, 89, 99, 57, 75, - 63, 79, 72, 61, 52, 48, 38, 16, 63, 87, 57, 76, 73, 67, 75, 77, - 49, 44, 44, 9, 88, 83, 80, 69, 57, 73, 60, 68, 85, 49, 18, 37, - 91, 44, 20, 21, 28, 37, 20, 24, 33, 49, 36, 20, 84, 97, 93, 89, - 110, 88, 89, 75, 75, 55, 42, 0, 93, 93, 111, 97, 73, 81, 85, 92, - 88, 77, 75, 36, 49, 100, 108, 92, 72, 73, 91, 84, 61, 51, 34, 73, - 118, 111, 91, 100, 110, 100, 97, 102, 88, 104, 60, 0, 104, 112, 111, 93, - 99, 91, 91, 95, 93, 91, 38, 107, 111, 108, 92, 97, 83, 72, 72, 88, - 89, 89, 44, 100, 103, 102, 100, 106, 103, 107, 106, 103, 76, 77, 64, 5, - 69, 104, 81, 87, 88, 77, 87, 87, 81, 77, 73, 49, 69, 119, 103, 123, - 123, 95, 100, 87, 89, 73, 67, 16, 107, 108, 104, 92, 110, 112, 115, 110, - 107, 59, 24, 79, 143, 135, 124, 118, 122, 119, 116, 118, 124, 102, 103, 40, - 103, 132, 120, 108, 116, 108, 106, 107, 108, 93, 51, 83, 153, 143, 154, 131, - 153, 142, 147, 135, 130, 130, 69, 81, 130, 142, 110, 112, 119, 120, 132, 107, - 84, 84, 42, 96, 132, 124, 127, 120, 123, 118, 116, 120, 100, 114, 107, 57, - 119, 124, 123, 127, 119, 119, 123, 112, 111, 108, 110, 57, 136, 143, 136, 132, - 108, 130, 123, 126, 122, 111, 100, 20, 115, 130, 120, 114, 97, 108, 104, 99, - 103, 99, 65, 81, 135, 140, 139, 142, 122, 114, 132, 119, 110, 110, 91, 10, - 132, 143, 118, 128, 127, 136, 138, 103, 116, 120, 106, 14, 146, 150, 159, 136, - 148, 153, 139, 127, 112, 111, 69, 110, 132, 139, 135, 132, 111, 134, 132, 106, - 114, 103, 21, 135, 182, 163, 148, 150, 142, 150, 147, 151, 150, 146, 119, 30, - 93, 128, 97, 104, 114, 108, 112, 107, 110, 103, 100, 56, 81, 148, 115, 155, - 124, 139, 135, 130, 132, 132, 114, 0, 150, 158, 158, 142, 153, 154, 144, 157, - 153, 142, 131, 84, 0, 167, 179, 162, 161, 155, 157, 154, 138, 126, 136, 21, - 142, 138, 122, 118, 155, 151, 128, 132, 140, 123, 64, 89, 154, 167, 166, 127, - 128, 128, 127, 123, 128, 138, 99, 51, 111, 166, 161, 153, 151, 155, 144, 144, - 148, 147, 132, 72, 154, 161, 158, 147, 148, 166, 151, 146, 143, 127, 13, 166, - 169, 162, 150, 155, 147, 153, 155, 150, 155, 134, 120, 25, 138, 124, 130, 100, - 115, 118, 115, 118, 140, 122, 111, 16, 142, 150, 135, 122, 157, 131, 167, 135, - 148, 139, 93, 0, 124, 171, 161, 167, 162, 155, 159, 161, 155, 144, 102, 49, - 110, 138, 139, 147, 148, 158, 148, 140, 138, 147, 122, 51, 97, 182, 179, 173, - 170, 17, 20, 21, 13, 26, 29, 42, 22, 12, 0, 40, 75, 51, 56, 69, - 61, 36, 52, 53, 17, 6, 59, 77, 80, 53, 55, 68, 67, 64, 56, 53, - 48, 25, 0, 73, 81, 49, 69, 38, 37, 42, 45, 57, 26, 24, 41, 64, - 87, 72, 72, 55, 63, 61, 65, 55, 68, 46, 29, 36, 56, 63, 55, 48, - 48, 42, 55, 42, 37, 36, 36, 76, 118, 65, 75, 65, 65, 79, 63, 49, - 48, 33, 12, 67, 91, 53, 79, 63, 68, 83, 75, 48, 40, 42, 4, 87, - 87, 88, 79, 69, 77, 81, 68, 80, 48, 17, 42, 85, 22, 42, 40, 45, - 41, 16, 18, 30, 42, 33, 24, 51, 99, 93, 84, 107, 102, 110, 97, 72, - 53, 56, 0, 91, 99, 111, 95, 85, 81, 79, 77, 80, 77, 73, 40, 44, - 84, 91, 103, 71, 60, 83, 80, 57, 49, 30, 64, 116, 106, 103, 100, 100, - 93, 99, 84, 87, 104, 52, 0, 102, 103, 103, 91, 100, 92, 84, 81, 100, - 95, 46, 72, 96, 118, 103, 115, 91, 89, 97, 103, 67, 88, 49, 71, 97, - 102, 100, 97, 97, 95, 96, 79, 75, 79, 52, 2, 68, 107, 91, 73, 71, - 80, 73, 73, 73, 76, 72, 52, 60, 111, 119, 119, 88, 99, 95, 84, 88, - 75, 77, 14, 102, 106, 99, 84, 89, 79, 99, 97, 115, 59, 25, 75, 142, - 135, 124, 116, 118, 120, 128, 124, 126, 108, 87, 33, 99, 128, 114, 110, 128, - 107, 104, 106, 106, 89, 49, 79, 143, 142, 131, 136, 130, 138, 144, 132, 128, - 130, 71, 45, 122, 136, 107, 116, 118, 130, 124, 96, 88, 79, 34, 96, 126, - 128, 134, 120, 116, 119, 100, 103, 99, 111, 107, 60, 111, 120, 126, 126, 122, - 120, 119, 123, 114, 107, 112, 59, 80, 143, 138, 123, 127, 134, 122, 131, 107, - 111, 104, 17, 114, 130, 115, 93, 96, 110, 106, 102, 99, 102, 87, 80, 130, - 136, 138, 134, 124, 138, 111, 115, 107, 100, 89, 12, 134, 130, 110, 128, 135, - 106, 126, 106, 106, 115, 112, 17, 139, 159, 147, 134, 130, 131, 142, 132, 110, - 115, 64, 108, 126, 150, 132, 131, 108, 131, 107, 108, 116, 104, 22, 140, 173, - 162, 134, 123, 154, 127, 153, 148, 154, 140, 134, 18, 110, 122, 99, 85, 104, - 112, 104, 108, 102, 92, 95, 57, 83, 144, 158, 126, 118, 111, 116, 139, 126, - 120, 87, 28, 140, 158, 139, 146, 148, 144, 154, 144, 147, 143, 124, 81, 0, - 163, 171, 159, 161, 155, 154, 157, 136, 123, 124, 20, 132, 136, 118, 111, 153, - 150, 146, 126, 132, 122, 97, 85, 153, 167, 166, 126, 122, 122, 123, 122, 127, - 135, 95, 37, 140, 162, 158, 171, 150, 143, 127, 144, 147, 151, 136, 81, 87, - 159, 158, 154, 150, 140, 143, 143, 142, 99, 16, 177, 165, 161, 151, 154, 155, - 154, 150, 148, 154, 128, 119, 24, 131, 123, 112, 128, 112, 114, 132, 115, 135, - 126, 115, 17, 139, 130, 173, 158, 155, 163, 159, 132, 148, 123, 89, 1, 100, - 170, 161, 163, 159, 159, 163, 158, 155, 142, 97, 36, 111, 130, 136, 138, 142, - 142, 151, 142, 142, 144, 124, 44, 114, 179, 165, 161, 158, 53, 41, 34, 28, - 28, 28, 24, 28, 13, 4, 41, 55, 52, 49, 51, 60, 53, 60, 55, 20, - 5, 52, 69, 59, 59, 49, 52, 52, 57, 44, 53, 41, 25, 0, 68, 72, - 60, 45, 51, 67, 61, 63, 42, 28, 25, 63, 67, 80, 80, 68, 40, 38, - 41, 45, 46, 37, 41, 45, 40, 37, 42, 53, 57, 56, 52, 44, 37, 34, - 34, 41, 84, 112, 71, 81, 68, 77, 69, 49, 59, 46, 46, 10, 64, 84, - 52, 80, 81, 81, 71, 75, 60, 40, 44, 4, 87, 87, 89, 76, 72, 85, - 77, 81, 81, 36, 16, 36, 36, 17, 16, 41, 32, 41, 18, 16, 18, 20, - 48, 24, 40, 85, 95, 88, 85, 81, 85, 79, 60, 56, 45, 1, 87, 83, - 106, 88, 88, 83, 79, 75, 76, 72, 71, 69, 68, 45, 49, 55, 61, 61, - 71, 81, 65, 61, 33, 77, 111, 95, 95, 87, 97, 97, 96, 97, 100, 103, - 69, 2, 96, 103, 103, 93, 102, 100, 84, 96, 96, 91, 51, 53, 61, 92, - 89, 108, 100, 81, 76, 99, 79, 55, 51, 56, 63, 96, 69, 71, 75, 72, - 75, 73, 72, 79, 76, 21, 75, 99, 72, 71, 67, 77, 72, 69, 79, 72, - 72, 77, 53, 71, 100, 103, 77, 73, 87, 81, 91, 85, 76, 10, 97, 103, - 87, 103, 95, 95, 89, 95, 87, 55, 65, 61, 138, 134, 127, 126, 120, 120, - 119, 120, 120, 106, 100, 29, 102, 124, 114, 102, 107, 112, 102, 103, 106, 92, - 45, 123, 148, 128, 126, 136, 138, 138, 126, 135, 135, 128, 79, 67, 112, 134, - 106, 123, 120, 114, 111, 107, 88, 76, 32, 97, 123, 116, 102, 103, 103, 104, - 102, 104, 108, 111, 107, 64, 71, 122, 126, 126, 123, 115, 114, 122, 110, 108, - 107, 79, 75, 134, 135, 126, 128, 143, 130, 123, 100, 111, 100, 22, 108, 111, - 96, 93, 96, 97, 87, 99, 75, 92, 104, 75, 93, 120, 122, 128, 107, 110, - 106, 104, 107, 115, 83, 14, 124, 144, 150, 128, 134, 132, 100, 130, 114, 106, - 100, 16, 140, 148, 140, 155, 126, 126, 132, 128, 120, 89, 52, 118, 126, 147, - 131, 122, 111, 124, 114, 112, 114, 96, 25, 131, 178, 165, 154, 144, 146, 153, - 151, 147, 143, 140, 124, 20, 102, 91, 88, 85, 79, 95, 91, 91, 96, 92, - 84, 68, 75, 140, 111, 104, 107, 102, 114, 116, 118, 122, 120, 6, 143, 153, - 142, 140, 153, 148, 143, 144, 144, 142, 118, 76, 0, 166, 178, 158, 157, 159, - 155, 155, 159, 118, 135, 4, 128, 128, 116, 107, 150, 150, 150, 124, 127, 118, - 103, 85, 146, 158, 155, 114, 116, 132, 116, 120, 124, 132, 115, 37, 126, 162, - 166, 128, 143, 142, 124, 132, 144, 151, 140, 111, 80, 115, 157, 159, 157, 155, - 153, 140, 142, 130, 17, 171, 166, 158, 147, 150, 154, 157, 155, 151, 153, 118, - 120, 4, 131, 115, 112, 115, 107, 110, 120, 140, 131, 127, 107, 21, 139, 178, - 142, 158, 154, 162, 131, 150, 150, 123, 84, 1, 64, 162, 166, 166, 161, 157, - 157, 158, 155, 128, 93, 32, 112, 135, 132, 138, 135, 138, 138, 140, 138, 139, - 131, 36, 166, 182, 169, 162, 161, 21, 26, 18, 25, 25, 36, 29, 16, 12, - 0, 34, 34, 36, 36, 37, 36, 41, 34, 28, 20, 4, 51, 52, 48, 44, - 45, 44, 44, 53, 40, 41, 25, 24, 4, 61, 64, 63, 63, 60, 53, 61, - 60, 40, 26, 30, 48, 63, 71, 68, 42, 45, 32, 32, 38, 45, 36, 34, - 33, 37, 38, 38, 49, 42, 44, 42, 41, 32, 37, 33, 42, 80, 79, 72, - 60, 52, 57, 61, 46, 45, 46, 46, 9, 61, 84, 73, 56, 52, 68, 77, - 68, 56, 45, 44, 5, 80, 85, 95, 76, 80, 88, 84, 79, 55, 42, 13, - 45, 36, 8, 13, 9, 17, 12, 14, 16, 16, 14, 18, 21, 51, 36, 44, - 48, 48, 48, 51, 56, 61, 48, 37, 4, 80, 85, 88, 84, 80, 56, 76, - 49, 53, 56, 68, 52, 57, 61, 69, 61, 63, 67, 67, 87, 65, 46, 25, - 72, 77, 88, 79, 77, 77, 80, 81, 84, 76, 71, 69, 2, 93, 92, 97, - 91, 88, 85, 87, 87, 84, 79, 76, 77, 83, 68, 65, 69, 71, 68, 81, - 75, 81, 77, 75, 79, 77, 73, 65, 81, 80, 69, 81, 83, 81, 79, 77, - 6, 61, 89, 83, 71, 59, 60, 65, 67, 68, 69, 76, 72, 75, 80, 81, - 83, 81, 81, 84, 87, 87, 77, 64, 21, 89, 93, 89, 84, 79, 73, 83, - 68, 63, 56, 48, 60, 83, 128, 136, 97, 116, 116, 122, 104, 106, 100, 100, - 22, 99, 95, 97, 89, 93, 92, 100, 102, 104, 92, 45, 92, 136, 126, 124, - 114, 116, 116, 111, 103, 92, 93, 79, 65, 107, 118, 114, 108, 106, 106, 107, - 108, 79, 75, 28, 97, 126, 120, 115, 118, 111, 116, 110, 115, 119, 111, 100, - 103, 71, 77, 84, 111, 83, 87, 114, 116, 115, 118, 103, 97, 69, 91, 139, - 130, 127, 126, 96, 99, 112, 100, 80, 36, 97, 114, 100, 89, 84, 83, 77, - 79, 89, 76, 77, 88, 102, 106, 118, 112, 115, 110, 112, 115, 115, 112, 91, - 16, 115, 135, 143, 131, 96, 135, 132, 134, 114, 114, 110, 24, 135, 148, 134, - 118, 140, 139, 136, 135, 114, 111, 61, 119, 120, 118, 111, 122, 107, 106, 114, - 112, 110, 100, 21, 135, 169, 154, 108, 144, 146, 112, 134, 142, 140, 135, 61, - 26, 57, 89, 96, 73, 69, 91, 79, 80, 83, 92, 96, 72, 75, 96, 100, - 97, 103, 107, 110, 108, 112, 112, 116, 2, 134, 148, 147, 143, 142, 142, 140, - 128, 136, 135, 112, 72, 0, 157, 175, 158, 157, 155, 155, 155, 159, 115, 116, - 30, 120, 124, 114, 106, 102, 115, 110, 111, 79, 79, 104, 92, 95, 103, 106, - 124, 126, 124, 126, 123, 130, 127, 102, 33, 73, 138, 136, 111, 115, 138, 135, - 118, 127, 130, 134, 116, 93, 100, 112, 112, 118, 118, 123, 127, 142, 124, 18, - 132, 165, 161, 155, 155, 151, 154, 148, 151, 153, 126, 118, 9, 127, 118, 107, - 106, 106, 122, 123, 123, 124, 122, 112, 26, 131, 175, 136, 154, 104, 150, 148, - 112, 122, 138, 76, 2, 53, 130, 158, 111, 120, 135, 154, 151, 135, 131, 81, - 26, 111, 136, 136, 135, 134, 134, 134, 139, 138, 134, 128, 32, 154, 181, 165, - 154, 153, 8, 8, 10, 8, 8, 8, 10, 8, 2, 0, 9, 10, 10, 10, - 13, 12, 12, 12, 14, 12, 5, 16, 20, 18, 18, 16, 16, 14, 14, 14, - 14, 14, 12, 0, 14, 16, 16, 20, 20, 17, 17, 24, 21, 16, 36, 21, - 37, 42, 20, 18, 32, 24, 21, 25, 21, 21, 18, 21, 18, 18, 21, 22, - 24, 25, 26, 29, 30, 38, 30, 34, 52, 46, 40, 36, 40, 44, 37, 36, - 42, 36, 24, 8, 28, 44, 53, 42, 46, 45, 51, 45, 46, 41, 40, 6, - 73, 84, 83, 81, 69, 67, 75, 65, 40, 38, 10, 57, 20, 6, 12, 8, - 9, 10, 14, 14, 12, 18, 14, 17, 20, 22, 18, 30, 32, 34, 36, 37, - 40, 42, 40, 1, 26, 38, 45, 29, 29, 29, 30, 24, 24, 21, 30, 29, - 21, 22, 30, 30, 32, 24, 59, 61, 60, 38, 24, 44, 52, 51, 49, 49, - 64, 59, 49, 44, 44, 38, 20, 40, 42, 48, 57, 64, 53, 55, 60, 60, - 60, 61, 64, 61, 67, 69, 73, 69, 69, 69, 71, 69, 77, 67, 64, 63, - 77, 68, 64, 59, 76, 60, 55, 53, 77, 53, 13, 10, 59, 46, 46, 49, - 33, 41, 28, 26, 30, 37, 32, 32, 34, 33, 33, 33, 45, 49, 55, 59, - 75, 63, 60, 21, 30, 33, 37, 36, 40, 32, 37, 36, 42, 33, 30, 48, - 77, 68, 81, 84, 79, 76, 81, 80, 79, 73, 69, 21, 71, 77, 79, 83, - 79, 79, 83, 91, 84, 79, 44, 36, 106, 116, 95, 97, 99, 111, 102, 102, - 108, 111, 102, 77, 71, 76, 85, 92, 95, 97, 107, 112, 75, 69, 24, 91, - 114, 124, 120, 103, 111, 112, 111, 99, 99, 97, 88, 85, 93, 100, 100, 99, - 100, 97, 100, 102, 102, 93, 93, 99, 96, 100, 106, 108, 104, 103, 102, 103, - 102, 92, 99, 24, 96, 65, 61, 57, 53, 52, 57, 49, 45, 44, 46, 45, - 48, 65, 48, 49, 51, 57, 53, 77, 81, 75, 76, 18, 51, 126, 123, 71, - 76, 111, 112, 75, 89, 107, 93, 22, 99, 139, 138, 111, 115, 132, 128, 108, - 111, 106, 61, 116, 116, 104, 93, 85, 85, 87, 87, 88, 92, 92, 33, 119, - 147, 132, 56, 60, 53, 59, 65, 57, 63, 29, 77, 59, 14, 12, 30, 22, - 49, 25, 36, 40, 55, 52, 59, 80, 87, 110, 103, 85, 112, 103, 107, 76, - 118, 111, 88, 4, 53, 65, 68, 65, 64, 61, 64, 64, 64, 63, 61, 61, - 0, 83, 165, 166, 163, 163, 163, 161, 158, 108, 134, 36, 92, 116, 89, 96, - 89, 89, 106, 106, 104, 104, 106, 104, 102, 73, 68, 59, 53, 55, 51, 49, - 45, 42, 40, 29, 48, 41, 49, 61, 51, 57, 71, 75, 92, 92, 80, 96, - 93, 104, 99, 118, 119, 116, 99, 119, 124, 111, 24, 68, 99, 119, 100, 110, - 112, 142, 151, 155, 127, 122, 106, 37, 114, 102, 102, 131, 111, 111, 108, 115, - 106, 107, 91, 32, 63, 85, 108, 48, 46, 46, 51, 48, 37, 36, 53, 4, - 28, 28, 32, 34, 37, 38, 40, 103, 124, 134, 79, 25, 106, 126, 136, 131, - 135, 135, 136, 136, 140, 134, 116, 30, 112, 183, 157, 151, 154, 0, 0, 0, - 2, 4, 0, 0, 5, 5, 1, 6, 5, 4, 4, 2, 8, 2, 2, 1, - 9, 6, 0, 12, 1, 1, 0, 6, 1, 0, 1, 0, 0, 0, 1, 2, - 4, 1, 6, 2, 2, 2, 8, 4, 4, 30, 37, 42, 60, 59, 67, 68, - 68, 76, 76, 71, 64, 67, 65, 64, 84, 64, 67, 37, 41, 37, 37, 30, - 30, 28, 20, 24, 18, 18, 13, 14, 13, 13, 12, 14, 14, 16, 14, 17, - 20, 21, 22, 25, 26, 29, 29, 32, 33, 37, 13, 9, 28, 29, 29, 28, - 30, 30, 32, 32, 28, 12, 26, 6, 20, 10, 16, 10, 16, 34, 53, 68, - 72, 59, 61, 75, 79, 88, 79, 72, 59, 53, 45, 46, 18, 37, 2, 16, - 20, 34, 36, 41, 51, 60, 69, 95, 87, 69, 60, 93, 96, 83, 92, 93, - 68, 53, 48, 38, 25, 12, 22, 18, 9, 13, 13, 12, 5, 8, 8, 5, - 4, 2, 4, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 18, - 0, 0, 0, 29, 0, 0, 6, 20, 26, 32, 32, 79, 107, 111, 118, 111, - 106, 79, 91, 110, 108, 96, 107, 103, 96, 81, 60, 56, 28, 46, 24, 2, - 1, 21, 18, 1, 0, 14, 4, 6, 1, 5, 6, 8, 1, 4, 2, 1, - 6, 17, 20, 1, 6, 4, 2, 33, 36, 2, 2, 20, 21, 24, 25, 32, - 26, 55, 20, 20, 30, 22, 20, 22, 30, 22, 20, 22, 30, 25, 24, 24, - 56, 26, 24, 25, 32, 37, 46, 42, 67, 22, 63, 85, 84, 65, 65, 79, - 79, 64, 67, 71, 65, 61, 46, 52, 57, 44, 48, 49, 53, 59, 53, 80, - 80, 77, 72, 81, 79, 60, 56, 72, 57, 45, 41, 72, 42, 60, 29, 52, - 73, 85, 85, 87, 99, 128, 110, 83, 89, 77, 73, 79, 115, 112, 115, 106, - 88, 73, 61, 57, 48, 40, 41, 44, 64, 49, 63, 44, 51, 65, 72, 48, - 49, 38, 73, 73, 77, 84, 81, 77, 71, 81, 80, 79, 76, 63, 114, 87, - 68, 80, 64, 68, 65, 67, 59, 59, 61, 79, 42, 65, 81, 92, 100, 102, - 106, 104, 103, 110, 100, 81, 36, 51, 158, 107, 104, 84, 57, 51, 46, 41, - 26, 29, 24, 17, 36, 29, 18, 16, 37, 36, 33, 17, 38, 40, 10, 8, - 28, 30, 26, 2, 18, 5, 18, 2, 10, 5, 0, 0, 48, 56, 64, 71, - 77, 83, 89, 96, 103, 102, 32, 97, 61, 65, 55, 56, 59, 55, 49, 44, - 48, 37, 37, 72, 88, 95, 116, 120, 124, 127, 124, 116, 114, 93, 30, 120, - 130, 128, 95, 119, 111, 100, 48, 33, 28, 16, 20, 25, 20, 18, 25, 20, - 14, 10, 14, 21, 8, 25, 65, 52, 63, 46, 45, 65, 96, 103, 114, 114, - 111, 96, 9, 97, 45, 46, 71, 55, 40, 36, 34, 46, 25, 20, 32, 52, - 80, 102, 99, 103, 118, 123, 120, 124, 115, 97, 5, 118, 166, 162, 158, 153, - 153, 95, 77, 41, 32, 21, 22, 38, 45, 49, 57, 89, 104, 110, 93, 104, - 114, 115, 29, 111, 173, 96, 89, 65, 107, 97, 87, 76, 64, 69, 57, 36, - 10, 5, 34, 75, 79, 64, 51, 49, 57, 59, 59, 36, 14, 24, 76, 79, - 81, 76, 87, 83, 84, 72, 79, 68, 80, 77, 87, 87, 93, 104, 99, 85, - 92, 81, 42, 38, 44, 72, 91, 108, 95, 80, 92, 89, 95, 83, 84, 92, - 84, 53, 49, 61, 55, 63, 61, 60, 69, 63, 32, 37, 34, 34, 89, 85, - 76, 67, 76, 76, 64, 64, 67, 55, 56, 63, 71, 83, 71, 73, 49, 42, - 29, 17, 28, 18, 10, 13, 20, 8, 6, 9, 25, 5, 4, 5, 34, 18, - 14, 22, 55, 63, 67, 73, 68, 73, 81, 75, 71, 79, 71, 61, 53, 67, - 84, 69, 73, 72, 75, 71, 77, 60, 49, 4, 37, 104, 107, 107, 111, 102, - 96, 89, 88, 97, 88, 55, 81, 95, 107, 96, 97, 92, 77, 88, 59, 51, - 26, 40, 83, 88, 97, 102, 100, 87, 93, 107, 107, 71, 68, 73, 120, 119, - 122, 122, 120, 116, 122, 119, 114, 76, 80, 110, 115, 119, 114, 100, 107, 119, - 103, 104, 103, 107, 91, 22, 51, 108, 115, 84, 96, 104, 114, 87, 100, 99, - 42, 40, 44, 118, 104, 108, 112, 112, 108, 119, 111, 80, 89, 75, 81, 93, - 112, 104, 108, 102, 89, 91, 95, 64, 36, 5, 38, 97, 111, 92, 87, 97, - 87, 85, 83, 64, 36, 0, 48, 103, 132, 99, 100, 99, 96, 110, 114, 111, - 65, 45, 57, 126, 131, 120, 124, 126, 131, 93, 114, 53, 60, 53, 108, 118, - 118, 102, 103, 96, 92, 112, 106, 91, 49, 56, 63, 100, 108, 100, 104, 71, - 72, 36, 33, 26, 26, 38, 40, 48, 52, 48, 53, 53, 53, 63, 67, 65, - 61, 61, 24, 79, 118, 124, 95, 115, 91, 91, 45, 55, 38, 25, 36, 53, - 80, 87, 84, 92, 97, 97, 93, 85, 72, 79, 107, 140, 153, 143, 139, 139, - 130, 130, 130, 131, 72, 71, 104, 139, 135, 142, 136, 132, 127, 134, 128, 97, - 75, 72, 100, 104, 110, 107, 93, 87, 89, 76, 45, 38, 28, 41, 37, 51, - 51, 46, 25, 28, 25, 51, 22, 24, 59, 53, 81, 97, 99, 116, 120, 126, - 120, 131, 118, 80, 77, 99, 123, 134, 138, 136, 140, 143, 142, 139, 148, 123, - 108, 13, 138, 115, 116, 104, 132, 131, 114, 107, 97, 123, 104, 99, 136, 153, - 139, 143, 148, 147, 139, 138, 132, 130, 57, 0, 29, 115, 159, 122, 119, 124, - 124, 120, 91, 136, 115, 48, 0, 116, 142, 140, 138, 131, 89, 38, 80, 73, - 80, 9, 53, 55, 81, 84, 88, 110, 124, 127, 106, 127, 114, 135, 114, 122, - 130, 128, 127, 138, 138, 148, 134, 119, 99, 33, 124, 139, 111, 127, 135, 108, - 107, 103, 120, 108, 73, 91, 80, 124, 131, 138, 134, 140, 144, 143, 146, 71, - 26, 85, 146, 144, 122, 124, 131, 120, 77, 36, 36, 25, 22, 8, 18, 71, - 75, 77, 87, 99, 107, 106, 115, 122, 102, 44, 115, 163, 167, 167, 167, 165, - 166, 165, 161, 123, 102, 5, 130, 175, 171, 166, 167, 171, 167, 166, 157, 115, - 93, 21, 130, 163, 161, 81, 73, 81, 76, 83, 87, 68, 108, 28, 165, 111, - 182, 190, 197, 88, 76, 67, 69, 63, 64, 51, 48, 12, 10, 77, 68, 57, - 46, 63, 61, 53, 49, 46, 63, 17, 91, 92, 95, 89, 84, 89, 89, 100, - 87, 93, 85, 77, 69, 81, 73, 80, 80, 87, 85, 84, 83, 81, 85, 41, - 110, 91, 77, 71, 80, 69, 88, 68, 76, 72, 46, 48, 40, 59, 72, 65, - 68, 55, 52, 53, 60, 68, 44, 40, 75, 84, 79, 84, 91, 77, 83, 80, - 81, 77, 73, 60, 72, 68, 67, 67, 59, 67, 55, 55, 60, 53, 57, 42, - 9, 28, 75, 81, 59, 69, 71, 83, 73, 68, 34, 16, 57, 83, 83, 89, - 77, 85, 87, 99, 89, 79, 85, 71, 38, 68, 89, 102, 96, 72, 84, 83, - 76, 79, 64, 53, 5, 80, 114, 92, 95, 97, 87, 99, 81, 85, 106, 85, - 57, 81, 111, 107, 96, 103, 99, 103, 77, 92, 57, 26, 84, 96, 104, 95, - 97, 93, 100, 93, 106, 102, 107, 102, 93, 84, 84, 84, 84, 85, 84, 84, - 88, 89, 97, 92, 75, 95, 99, 92, 85, 100, 103, 106, 106, 112, 110, 106, - 24, 119, 132, 119, 116, 119, 112, 103, 103, 100, 102, 52, 33, 89, 103, 107, - 106, 114, 112, 115, 115, 108, 99, 87, 69, 80, 112, 120, 110, 112, 111, 104, - 97, 96, 72, 38, 14, 110, 118, 119, 110, 115, 116, 112, 108, 107, 92, 40, - 2, 142, 146, 142, 140, 143, 142, 136, 130, 144, 139, 102, 46, 130, 146, 144, - 136, 136, 126, 134, 126, 122, 84, 60, 110, 132, 118, 114, 111, 128, 128, 122, - 124, 124, 126, 116, 56, 99, 119, 122, 119, 118, 114, 110, 102, 75, 53, 25, - 85, 106, 87, 100, 102, 97, 108, 99, 99, 93, 84, 69, 55, 20, 110, 127, - 118, 118, 111, 119, 128, 110, 122, 104, 85, 110, 84, 106, 112, 120, 111, 124, - 111, 119, 96, 79, 83, 128, 151, 124, 127, 128, 122, 112, 128, 124, 112, 118, - 93, 130, 128, 132, 128, 126, 126, 132, 128, 126, 116, 126, 116, 124, 126, 127, - 115, 126, 120, 122, 111, 103, 97, 92, 130, 124, 126, 128, 136, 142, 136, 142, - 150, 153, 79, 88, 102, 166, 170, 171, 170, 173, 171, 166, 169, 167, 118, 77, - 115, 146, 143, 143, 143, 136, 138, 131, 127, 124, 136, 95, 30, 108, 123, 115, - 104, 110, 111, 110, 130, 128, 103, 106, 108, 92, 120, 123, 128, 115, 124, 123, - 124, 119, 143, 69, 0, 161, 170, 169, 171, 166, 166, 165, 158, 163, 162, 136, - 85, 0, 119, 146, 155, 158, 157, 154, 147, 135, 126, 77, 20, 103, 142, 153, - 154, 153, 150, 153, 150, 142, 143, 81, 102, 142, 153, 148, 159, 158, 154, 147, - 139, 139, 124, 111, 32, 142, 144, 130, 114, 110, 114, 148, 138, 155, 147, 73, - 60, 127, 159, 165, 169, 165, 159, 162, 166, 155, 96, 26, 116, 157, 161, 166, - 166, 162, 162, 154, 135, 140, 114, 71, 71, 143, 177, 174, 170, 173, 173, 171, - 150, 171, 136, 120, 42, 150, 170, 166, 166, 166, 158, 148, 153, 159, 143, 114, - 8, 131, 178, 173, 170, 163, 163, 165, 161, 167, 155, 106, 17, 150, 151, 175, - 171, 167, 159, 161, 170, 158, 96, 122, 26, 173, 131, 187, 187, 190, 107, 104, - 88, 84, 68, 68, 14, 25, 10, 6, 55, 63, 40, 38, 45, 28, 40, 49, - 45, 18, 17, 95, 112, 123, 136, 163, 174, 189, 197, 205, 205, 213, 214, 221, - 212, 222, 222, 218, 202, 193, 147, 112, 107, 107, 75, 91, 89, 92, 88, 81, - 88, 91, 65, 41, 40, 40, 38, 41, 60, 80, 92, 68, 60, 72, 68, 72, - 67, 59, 29, 81, 89, 76, 77, 67, 71, 71, 69, 63, 72, 71, 63, 61, - 80, 81, 80, 69, 67, 59, 60, 67, 69, 51, 45, 12, 85, 81, 93, 92, - 77, 88, 87, 81, 83, 67, 17, 71, 107, 93, 72, 96, 87, 81, 80, 80, - 91, 85, 68, 45, 68, 92, 100, 83, 81, 88, 84, 91, 75, 64, 60, 4, - 85, 107, 104, 95, 83, 91, 85, 100, 85, 96, 92, 42, 75, 99, 99, 102, - 87, 88, 81, 80, 87, 63, 33, 89, 81, 89, 93, 85, 100, 99, 107, 108, - 96, 89, 73, 103, 87, 104, 97, 99, 99, 97, 91, 80, 79, 68, 65, 88, - 108, 102, 103, 108, 107, 103, 107, 107, 106, 106, 100, 22, 122, 131, 97, 96, - 97, 92, 93, 89, 99, 97, 52, 34, 87, 110, 110, 103, 100, 96, 102, 103, - 112, 100, 92, 52, 73, 108, 100, 104, 114, 112, 97, 88, 95, 77, 65, 22, - 108, 112, 111, 110, 110, 103, 103, 103, 96, 96, 53, 0, 123, 140, 142, 143, - 139, 140, 143, 135, 134, 138, 116, 56, 139, 136, 135, 122, 115, 118, 108, 115, - 115, 123, 107, 128, 116, 110, 114, 103, 112, 89, 93, 92, 97, 79, 77, 64, - 122, 144, 118, 120, 119, 124, 115, 110, 112, 67, 24, 95, 103, 92, 104, 97, - 91, 103, 97, 92, 93, 79, 73, 65, 26, 106, 139, 115, 118, 130, 118, 119, - 116, 106, 114, 68, 75, 138, 134, 132, 140, 136, 130, 126, 118, 106, 87, 80, - 140, 147, 120, 122, 123, 118, 112, 123, 134, 130, 136, 132, 140, 139, 148, 143, - 143, 143, 165, 143, 148, 142, 147, 132, 146, 146, 148, 143, 140, 139, 140, 140, - 126, 107, 76, 134, 138, 138, 140, 138, 135, 122, 135, 135, 127, 95, 69, 135, - 175, 169, 165, 163, 170, 166, 174, 162, 143, 134, 91, 118, 140, 146, 135, 135, - 139, 132, 131, 131, 139, 128, 91, 29, 99, 132, 118, 143, 114, 140, 122, 139, - 142, 134, 114, 97, 115, 144, 146, 157, 154, 151, 143, 157, 146, 138, 76, 18, - 155, 169, 163, 165, 166, 165, 162, 162, 157, 167, 140, 76, 0, 136, 154, 143, - 146, 143, 130, 144, 147, 131, 67, 29, 108, 142, 158, 155, 142, 139, 148, 134, - 134, 108, 88, 119, 163, 155, 159, 148, 135, 142, 146, 143, 136, 108, 99, 25, - 139, 143, 142, 119, 120, 138, 144, 142, 148, 142, 81, 95, 151, 166, 161, 158, - 161, 157, 157, 148, 158, 95, 29, 131, 161, 155, 155, 151, 146, 146, 143, 147, - 157, 139, 76, 60, 157, 169, 170, 177, 169, 147, 146, 165, 144, 150, 124, 46, - 155, 165, 157, 150, 154, 148, 155, 150, 154, 127, 106, 6, 135, 170, 169, 173, - 169, 165, 165, 173, 163, 157, 120, 16, 134, 153, 153, 175, 173, 174, 171, 173, - 166, 114, 118, 21, 174, 190, 187, 185, 187, 73, 52, 68, 60, 40, 22, 28, - 46, 10, 13, 44, 57, 44, 41, 28, 24, 26, 30, 38, 61, 76, 110, 204, - 216, 228, 230, 230, 232, 234, 234, 238, 241, 244, 242, 241, 238, 236, 236, 233, - 229, 222, 224, 189, 139, 122, 110, 140, 159, 191, 165, 135, 92, 67, 38, 40, - 40, 42, 41, 84, 96, 84, 81, 67, 80, 85, 87, 69, 80, 68, 73, 72, - 73, 52, 75, 69, 77, 69, 71, 63, 63, 64, 79, 97, 108, 91, 95, 91, - 93, 89, 75, 59, 51, 46, 12, 93, 85, 91, 88, 89, 77, 77, 71, 69, - 64, 26, 77, 85, 96, 84, 80, 87, 75, 81, 91, 92, 77, 63, 37, 63, - 95, 107, 87, 80, 87, 91, 84, 77, 61, 48, 5, 73, 99, 97, 95, 92, - 89, 87, 69, 104, 104, 83, 49, 80, 100, 97, 89, 87, 85, 75, 85, 89, - 67, 46, 55, 84, 87, 95, 104, 111, 91, 92, 96, 83, 85, 65, 93, 104, - 85, 102, 97, 100, 84, 92, 92, 91, 63, 60, 96, 104, 99, 102, 95, 100, - 102, 79, 102, 103, 65, 68, 32, 79, 134, 99, 92, 99, 81, 89, 92, 97, - 95, 56, 32, 87, 104, 106, 92, 95, 96, 95, 97, 111, 99, 85, 49, 79, - 102, 96, 85, 115, 119, 97, 89, 100, 65, 65, 21, 83, 120, 108, 107, 110, - 99, 112, 111, 95, 88, 45, 6, 79, 139, 132, 123, 119, 120, 126, 128, 119, - 116, 122, 118, 123, 136, 138, 131, 120, 132, 115, 123, 104, 111, 100, 111, 102, - 112, 111, 107, 104, 110, 111, 110, 104, 108, 104, 107, 112, 123, 132, 103, 110, - 111, 136, 112, 107, 61, 21, 84, 96, 92, 99, 104, 106, 100, 100, 96, 88, - 79, 67, 59, 22, 103, 123, 112, 122, 130, 130, 130, 126, 116, 114, 61, 120, - 147, 142, 134, 126, 126, 123, 118, 119, 95, 87, 88, 123, 140, 112, 124, 120, - 116, 122, 150, 212, 214, 208, 218, 228, 230, 220, 226, 236, 238, 236, 233, 236, - 248, 233, 234, 232, 248, 226, 216, 220, 249, 226, 179, 132, 107, 81, 131, 158, - 169, 166, 162, 163, 153, 150, 146, 131, 96, 87, 150, 170, 165, 163, 169, 169, - 177, 173, 142, 158, 128, 100, 103, 143, 139, 135, 131, 136, 134, 134, 134, 139, - 126, 77, 21, 106, 148, 144, 153, 127, 122, 139, 136, 120, 126, 114, 65, 130, - 143, 144, 148, 148, 147, 128, 148, 148, 140, 65, 20, 96, 166, 163, 159, 157, - 155, 153, 154, 155, 163, 139, 75, 0, 131, 128, 135, 122, 148, 136, 132, 134, - 142, 91, 33, 118, 143, 147, 148, 144, 143, 142, 126, 128, 110, 68, 116, 162, - 155, 147, 138, 148, 139, 138, 127, 118, 115, 100, 28, 130, 143, 142, 144, 151, - 154, 140, 144, 143, 138, 67, 69, 159, 163, 163, 151, 151, 158, 161, 159, 159, - 93, 32, 132, 154, 153, 151, 147, 144, 142, 142, 142, 150, 138, 81, 57, 150, - 167, 170, 179, 169, 147, 148, 161, 140, 132, 126, 59, 147, 169, 155, 153, 144, - 148, 154, 153, 155, 126, 103, 6, 138, 171, 170, 161, 163, 169, 167, 170, 157, - 126, 116, 13, 136, 124, 147, 173, 166, 170, 166, 159, 161, 150, 127, 24, 171, - 143, 179, 171, 169, 24, 25, 36, 25, 36, 14, 46, 37, 10, 14, 49, 57, - 48, 26, 21, 22, 24, 71, 89, 150, 195, 218, 234, 242, 240, 241, 238, 238, - 234, 238, 244, 245, 244, 241, 240, 238, 234, 228, 232, 230, 230, 224, 224, 217, - 224, 210, 202, 212, 206, 189, 122, 92, 65, 37, 38, 46, 53, 57, 114, 186, - 195, 189, 191, 199, 205, 206, 204, 199, 198, 195, 195, 130, 103, 93, 89, 91, - 79, 76, 87, 88, 132, 171, 201, 206, 199, 201, 194, 132, 92, 76, 42, 52, - 37, 13, 60, 84, 77, 73, 72, 71, 63, 73, 77, 65, 29, 52, 84, 96, - 77, 81, 80, 76, 77, 81, 89, 73, 64, 36, 71, 84, 100, 89, 77, 84, - 88, 83, 77, 60, 51, 6, 65, 103, 107, 102, 92, 102, 76, 91, 95, 93, - 83, 40, 80, 91, 100, 81, 81, 91, 80, 96, 83, 65, 44, 49, 99, 104, - 83, 88, 89, 100, 88, 92, 88, 80, 59, 100, 103, 93, 92, 89, 87, 91, - 110, 100, 89, 81, 57, 100, 103, 108, 91, 100, 100, 96, 100, 92, 100, 103, - 95, 34, 79, 131, 103, 93, 88, 76, 81, 80, 97, 96, 56, 28, 87, 103, - 97, 87, 87, 87, 88, 92, 104, 92, 79, 52, 69, 97, 93, 85, 104, 91, - 84, 89, 96, 68, 37, 8, 83, 123, 100, 99, 107, 111, 106, 100, 99, 85, - 45, 4, 124, 131, 126, 123, 130, 127, 122, 124, 154, 194, 205, 210, 218, 222, - 229, 232, 236, 237, 250, 250, 249, 242, 244, 229, 238, 242, 240, 237, 233, 233, - 230, 230, 210, 212, 195, 214, 206, 234, 199, 191, 186, 186, 206, 161, 116, 65, - 28, 91, 84, 99, 104, 97, 96, 104, 85, 89, 63, 75, 57, 51, 16, 102, - 131, 118, 123, 132, 132, 131, 118, 104, 116, 48, 127, 146, 138, 123, 123, 128, - 131, 126, 128, 102, 87, 60, 119, 139, 110, 115, 115, 116, 115, 154, 209, 213, - 212, 221, 222, 226, 225, 222, 228, 230, 232, 232, 233, 232, 230, 230, 229, 222, - 224, 220, 220, 220, 213, 165, 122, 97, 33, 124, 150, 155, 157, 157, 157, 166, - 165, 140, 136, 99, 96, 124, 170, 163, 178, 174, 158, 157, 134, 142, 143, 134, - 96, 93, 146, 142, 131, 136, 136, 135, 134, 131, 124, 123, 99, 10, 110, 150, - 126, 146, 122, 132, 131, 153, 116, 115, 112, 75, 111, 146, 148, 153, 155, 154, - 153, 150, 132, 134, 65, 1, 99, 167, 157, 153, 148, 153, 162, 161, 163, 166, - 146, 73, 1, 119, 139, 143, 126, 158, 132, 134, 138, 116, 84, 20, 111, 154, - 153, 144, 135, 134, 143, 130, 130, 95, 72, 110, 163, 150, 151, 150, 144, 142, - 132, 139, 143, 111, 99, 36, 128, 140, 147, 148, 142, 143, 144, 148, 138, 140, - 71, 76, 155, 157, 154, 153, 158, 167, 162, 158, 161, 99, 42, 124, 159, 154, - 150, 147, 143, 143, 131, 136, 139, 126, 77, 8, 154, 167, 174, 178, 148, 150, - 151, 143, 146, 136, 131, 64, 140, 169, 134, 161, 131, 155, 155, 151, 157, 116, - 100, 8, 128, 171, 170, 173, 167, 169, 166, 170, 159, 126, 104, 12, 135, 146, - 146, 136, 144, 144, 143, 139, 157, 122, 131, 32, 174, 140, 174, 181, 169, 17, - 16, 18, 28, 18, 14, 45, 33, 10, 16, 67, 51, 28, 24, 32, 51, 75, - 171, 233, 241, 242, 245, 240, 238, 238, 237, 216, 185, 171, 175, 178, 169, 153, - 139, 132, 127, 116, 111, 118, 123, 136, 187, 208, 221, 220, 214, 210, 197, 199, - 183, 131, 91, 56, 34, 40, 34, 55, 108, 142, 208, 205, 218, 206, 218, 221, - 224, 221, 232, 228, 232, 229, 228, 224, 230, 228, 225, 218, 208, 217, 220, 213, - 221, 217, 202, 198, 189, 191, 132, 91, 69, 38, 51, 40, 16, 60, 84, 65, - 64, 93, 77, 79, 77, 68, 63, 30, 30, 80, 88, 87, 84, 81, 89, 89, - 92, 91, 75, 64, 34, 63, 106, 110, 80, 85, 85, 89, 81, 76, 60, 48, - 9, 81, 104, 96, 92, 85, 100, 83, 87, 96, 83, 87, 40, 84, 88, 95, - 87, 83, 93, 87, 91, 84, 65, 44, 38, 97, 87, 84, 88, 97, 87, 97, - 92, 80, 73, 55, 89, 103, 88, 84, 85, 96, 95, 91, 92, 85, 63, 57, - 100, 107, 116, 104, 102, 85, 106, 100, 88, 102, 100, 96, 37, 81, 127, 106, - 89, 87, 75, 77, 89, 100, 95, 57, 28, 93, 97, 93, 88, 89, 84, 84, - 92, 100, 89, 84, 52, 77, 93, 91, 80, 77, 114, 110, 88, 92, 71, 37, - 17, 92, 123, 107, 107, 107, 100, 99, 85, 99, 104, 42, 4, 139, 139, 126, - 124, 131, 119, 131, 197, 202, 214, 213, 213, 220, 232, 232, 233, 237, 241, 249, - 250, 250, 248, 246, 246, 232, 242, 245, 237, 232, 236, 240, 236, 228, 233, 225, - 221, 214, 224, 216, 209, 195, 220, 206, 173, 110, 64, 28, 88, 81, 97, 100, - 95, 100, 93, 92, 89, 65, 72, 55, 46, 13, 110, 128, 118, 127, 124, 132, - 132, 124, 104, 107, 42, 126, 140, 124, 132, 134, 134, 139, 135, 132, 118, 88, - 88, 118, 144, 115, 120, 124, 116, 112, 131, 154, 201, 210, 216, 217, 213, 220, - 212, 216, 221, 224, 226, 230, 230, 230, 225, 222, 225, 220, 213, 210, 214, 193, - 132, 118, 67, 45, 132, 151, 142, 154, 154, 158, 158, 163, 142, 142, 100, 92, - 127, 165, 157, 153, 134, 135, 138, 128, 135, 139, 147, 114, 91, 143, 142, 138, - 130, 134, 136, 131, 130, 131, 138, 96, 24, 131, 126, 144, 124, 135, 140, 144, - 132, 132, 124, 107, 73, 112, 153, 142, 153, 147, 144, 142, 140, 146, 143, 60, - 2, 162, 161, 155, 158, 161, 159, 159, 166, 163, 162, 144, 104, 2, 120, 153, - 136, 161, 142, 122, 136, 127, 122, 77, 14, 110, 153, 153, 150, 140, 147, 146, - 136, 123, 103, 69, 118, 163, 143, 143, 157, 146, 142, 142, 142, 128, 120, 107, - 42, 136, 153, 151, 155, 158, 150, 143, 146, 140, 151, 77, 88, 150, 157, 147, - 159, 166, 165, 159, 155, 153, 107, 38, 136, 158, 157, 150, 146, 144, 147, 130, - 140, 144, 144, 81, 13, 151, 166, 154, 151, 148, 159, 162, 159, 159, 140, 131, - 71, 126, 170, 159, 170, 131, 142, 154, 157, 157, 134, 110, 12, 138, 173, 170, - 167, 166, 161, 163, 166, 166, 147, 116, 9, 150, 140, 138, 134, 130, 132, 132, - 132, 153, 118, 123, 26, 173, 143, 173, 169, 161, 56, 22, 16, 16, 14, 13, - 49, 21, 13, 9, 68, 55, 28, 37, 64, 110, 221, 245, 242, 240, 242, 242, - 237, 226, 194, 159, 124, 112, 107, 110, 108, 108, 107, 106, 103, 106, 103, 103, - 102, 102, 99, 102, 115, 124, 151, 185, 190, 197, 185, 136, 108, 71, 32, 33, - 36, 41, 57, 122, 150, 230, 237, 202, 221, 214, 228, 229, 234, 232, 228, 226, - 234, 238, 236, 230, 230, 224, 221, 226, 221, 217, 216, 214, 220, 210, 202, 205, - 195, 114, 75, 59, 40, 48, 40, 18, 84, 81, 77, 73, 84, 71, 79, 75, - 81, 81, 61, 22, 76, 87, 99, 99, 99, 92, 92, 85, 85, 71, 63, 36, - 60, 93, 99, 89, 85, 88, 95, 84, 77, 77, 51, 8, 73, 102, 96, 102, - 93, 100, 97, 100, 99, 72, 69, 30, 80, 85, 102, 80, 103, 88, 88, 81, - 85, 76, 65, 38, 91, 88, 87, 84, 84, 88, 89, 89, 79, 63, 52, 84, - 95, 83, 81, 89, 97, 88, 88, 85, 80, 53, 53, 91, 100, 107, 107, 97, - 85, 100, 91, 100, 83, 102, 91, 40, 59, 84, 127, 104, 85, 81, 76, 85, - 102, 89, 57, 33, 80, 92, 91, 79, 81, 79, 77, 100, 103, 99, 79, 48, - 65, 85, 85, 77, 75, 111, 87, 88, 89, 73, 53, 20, 96, 108, 100, 111, - 107, 110, 107, 97, 102, 89, 48, 1, 111, 136, 124, 124, 126, 119, 186, 201, - 206, 212, 216, 221, 220, 226, 230, 236, 234, 238, 246, 249, 248, 249, 250, 248, - 244, 236, 245, 241, 240, 241, 230, 230, 232, 236, 228, 226, 217, 213, 210, 206, - 202, 208, 163, 142, 76, 65, 28, 88, 88, 92, 104, 99, 95, 89, 84, 88, - 67, 68, 63, 55, 17, 81, 136, 119, 128, 122, 124, 130, 124, 119, 99, 51, - 123, 132, 138, 143, 144, 155, 150, 147, 140, 136, 116, 103, 127, 148, 122, 120, - 104, 106, 119, 110, 119, 126, 132, 131, 130, 122, 119, 115, 119, 116, 116, 116, - 120, 126, 126, 123, 123, 126, 120, 119, 118, 116, 118, 104, 103, 65, 68, 131, - 148, 139, 140, 157, 153, 154, 154, 143, 136, 104, 99, 122, 163, 167, 148, 151, - 167, 154, 155, 161, 120, 131, 134, 80, 131, 148, 140, 131, 135, 131, 134, 139, - 131, 134, 87, 22, 103, 136, 130, 127, 128, 130, 126, 131, 138, 124, 104, 72, - 104, 151, 127, 157, 161, 150, 150, 146, 148, 127, 76, 16, 159, 166, 159, 163, - 158, 161, 159, 166, 162, 161, 144, 80, 5, 131, 153, 144, 146, 130, 131, 118, - 140, 99, 71, 32, 114, 136, 158, 139, 144, 143, 136, 139, 126, 115, 73, 122, - 161, 150, 147, 148, 147, 136, 138, 154, 131, 108, 107, 30, 140, 147, 151, 136, - 147, 147, 140, 144, 136, 140, 69, 124, 153, 143, 151, 162, 161, 157, 161, 159, - 154, 110, 53, 104, 134, 155, 153, 150, 144, 150, 147, 134, 136, 144, 79, 48, - 143, 167, 154, 157, 157, 161, 159, 159, 159, 140, 135, 75, 134, 170, 157, 139, - 132, 136, 153, 157, 157, 132, 103, 9, 143, 170, 171, 170, 165, 162, 169, 170, - 166, 146, 122, 9, 126, 131, 130, 127, 118, 116, 119, 130, 139, 126, 116, 18, - 158, 181, 169, 165, 173, 95, 34, 29, 28, 29, 36, 40, 33, 12, 21, 49, - 26, 38, 69, 155, 232, 246, 241, 241, 233, 225, 205, 178, 132, 115, 108, 110, - 110, 110, 110, 108, 110, 115, 107, 91, 73, 64, 71, 81, 96, 130, 112, 100, - 99, 95, 104, 106, 103, 103, 99, 92, 49, 33, 33, 36, 32, 55, 104, 127, - 182, 191, 194, 162, 124, 116, 122, 128, 127, 124, 128, 140, 169, 199, 208, 214, - 220, 224, 222, 213, 205, 204, 210, 208, 202, 187, 139, 114, 88, 72, 37, 34, - 45, 34, 18, 56, 79, 77, 73, 73, 85, 84, 75, 76, 84, 48, 25, 64, - 87, 83, 85, 91, 83, 85, 87, 84, 67, 64, 30, 57, 85, 102, 104, 106, - 99, 99, 84, 79, 65, 46, 6, 67, 96, 95, 96, 88, 100, 92, 93, 88, - 84, 52, 26, 80, 88, 97, 79, 89, 89, 92, 84, 80, 84, 59, 38, 61, - 95, 88, 95, 88, 88, 88, 84, 77, 59, 45, 75, 103, 88, 84, 89, 92, - 92, 89, 89, 83, 53, 48, 95, 95, 99, 95, 96, 96, 102, 99, 100, 80, - 68, 81, 46, 52, 85, 104, 116, 95, 81, 73, 89, 93, 92, 63, 28, 77, - 97, 87, 87, 77, 79, 95, 122, 93, 91, 75, 34, 76, 91, 73, 71, 77, - 76, 83, 83, 81, 65, 55, 22, 68, 122, 112, 114, 106, 95, 97, 108, 97, - 95, 42, 8, 83, 134, 124, 124, 132, 118, 116, 158, 198, 206, 202, 183, 139, - 128, 126, 123, 127, 123, 115, 110, 114, 115, 116, 118, 116, 112, 110, 112, 115, - 114, 112, 107, 108, 116, 120, 118, 115, 108, 104, 108, 88, 83, 81, 79, 69, - 34, 24, 85, 95, 97, 93, 96, 93, 87, 88, 87, 61, 63, 57, 46, 14, - 100, 118, 122, 118, 124, 128, 116, 122, 112, 88, 53, 126, 136, 153, 163, 190, - 197, 206, 191, 186, 169, 147, 136, 123, 146, 114, 124, 111, 99, 104, 108, 122, - 110, 100, 103, 107, 107, 106, 106, 106, 104, 106, 106, 106, 104, 106, 110, 108, - 107, 107, 111, 108, 106, 110, 111, 46, 44, 60, 131, 144, 140, 148, 146, 147, - 150, 159, 140, 135, 116, 83, 95, 146, 159, 144, 131, 151, 166, 161, 136, 135, - 135, 123, 91, 114, 139, 142, 135, 136, 134, 132, 131, 131, 128, 68, 18, 102, - 143, 136, 120, 135, 130, 126, 131, 138, 120, 104, 52, 134, 147, 143, 136, 158, - 161, 148, 158, 146, 124, 63, 14, 96, 159, 153, 162, 163, 155, 161, 162, 162, - 161, 140, 76, 5, 122, 130, 154, 146, 118, 110, 126, 96, 93, 80, 34, 108, - 136, 153, 146, 151, 142, 138, 131, 134, 99, 48, 144, 162, 153, 157, 157, 140, - 142, 146, 142, 126, 110, 102, 40, 136, 148, 134, 151, 144, 140, 142, 144, 132, - 122, 59, 93, 161, 165, 167, 151, 140, 159, 161, 170, 155, 99, 56, 87, 134, - 158, 151, 150, 148, 148, 130, 128, 139, 139, 88, 40, 140, 166, 158, 159, 162, - 150, 150, 159, 158, 143, 138, 80, 104, 166, 161, 128, 130, 140, 154, 157, 157, - 134, 103, 12, 134, 171, 169, 167, 163, 167, 166, 166, 165, 136, 124, 8, 134, - 131, 124, 120, 118, 116, 112, 127, 147, 135, 115, 24, 166, 183, 169, 158, 173, - 71, 73, 53, 61, 45, 56, 28, 26, 12, 24, 25, 36, 85, 198, 240, 244, - 241, 242, 242, 199, 153, 119, 110, 110, 112, 114, 118, 108, 124, 120, 104, 72, - 38, 20, 20, 17, 24, 17, 21, 25, 49, 73, 122, 118, 99, 102, 95, 95, - 91, 102, 87, 29, 28, 29, 33, 33, 56, 76, 100, 97, 115, 102, 107, 91, - 85, 84, 95, 88, 92, 88, 100, 95, 97, 106, 106, 110, 104, 106, 106, 102, - 99, 102, 107, 108, 95, 92, 83, 69, 33, 36, 41, 42, 34, 21, 46, 75, - 83, 75, 88, 77, 83, 83, 80, 76, 51, 28, 53, 83, 81, 81, 76, 80, - 85, 88, 80, 61, 60, 24, 61, 72, 87, 91, 88, 84, 81, 85, 71, 69, - 49, 8, 67, 89, 102, 96, 97, 92, 93, 95, 85, 81, 65, 26, 73, 83, - 97, 97, 84, 89, 79, 87, 65, 63, 53, 44, 53, 52, 69, 67, 63, 65, - 68, 69, 76, 72, 45, 83, 100, 84, 79, 89, 89, 88, 89, 88, 85, 61, - 42, 93, 92, 92, 88, 85, 91, 88, 93, 92, 93, 92, 91, 69, 52, 89, - 104, 96, 77, 71, 73, 92, 88, 89, 64, 25, 87, 103, 92, 85, 76, 75, - 95, 111, 93, 87, 75, 37, 67, 84, 73, 71, 64, 67, 68, 75, 67, 63, - 44, 22, 65, 119, 96, 69, 88, 103, 104, 87, 93, 93, 40, 6, 120, 126, - 123, 120, 123, 120, 124, 124, 124, 123, 120, 114, 114, 111, 111, 110, 110, 106, - 104, 102, 102, 102, 103, 103, 102, 97, 97, 96, 96, 95, 96, 88, 93, 92, - 92, 92, 92, 87, 87, 87, 83, 76, 60, 57, 33, 24, 32, 83, 80, 93, - 89, 77, 63, 67, 56, 45, 60, 57, 61, 48, 8, 103, 138, 124, 122, 120, - 120, 123, 116, 110, 57, 83, 136, 150, 194, 213, 221, 221, 212, 208, 213, 213, - 209, 186, 163, 144, 119, 95, 96, 102, 87, 97, 88, 100, 100, 97, 110, 118, - 112, 112, 112, 111, 110, 110, 114, 115, 115, 115, 114, 112, 115, 115, 114, 118, - 96, 41, 51, 46, 21, 123, 134, 147, 134, 144, 130, 126, 122, 146, 126, 112, - 85, 106, 126, 136, 130, 153, 138, 139, 126, 123, 120, 119, 132, 93, 103, 124, - 146, 144, 142, 134, 143, 144, 131, 127, 103, 13, 111, 146, 146, 140, 134, 140, - 131, 136, 146, 103, 104, 53, 99, 146, 146, 150, 143, 120, 126, 135, 142, 136, - 61, 6, 100, 163, 155, 158, 157, 157, 161, 163, 159, 157, 154, 71, 6, 114, - 143, 135, 112, 110, 99, 93, 114, 97, 79, 33, 111, 147, 151, 155, 138, 136, - 139, 135, 138, 107, 57, 104, 159, 148, 147, 142, 140, 144, 139, 142, 140, 107, - 102, 44, 140, 150, 144, 140, 142, 140, 139, 140, 136, 81, 57, 131, 143, 169, - 154, 148, 144, 150, 161, 153, 159, 93, 75, 80, 140, 147, 146, 157, 148, 144, - 134, 130, 130, 131, 76, 14, 143, 165, 159, 151, 157, 157, 150, 147, 150, 150, - 135, 107, 104, 159, 153, 150, 136, 144, 153, 154, 154, 111, 100, 13, 139, 171, - 166, 165, 161, 162, 162, 166, 163, 155, 118, 8, 127, 123, 115, 124, 112, 118, - 114, 127, 143, 126, 118, 40, 170, 153, 173, 174, 189, 12, 12, 14, 13, 12, - 13, 13, 10, 10, 34, 32, 84, 216, 245, 242, 244, 241, 245, 206, 139, 112, - 114, 115, 120, 122, 118, 122, 127, 119, 81, 37, 16, 13, 12, 13, 14, 18, - 18, 18, 21, 18, 37, 69, 108, 155, 118, 100, 99, 97, 102, 83, 29, 25, - 25, 30, 32, 44, 75, 73, 73, 68, 71, 87, 89, 91, 91, 92, 93, 95, - 92, 93, 93, 95, 96, 95, 95, 95, 92, 92, 91, 87, 87, 91, 88, 84, - 81, 56, 29, 32, 28, 41, 41, 37, 21, 30, 72, 73, 83, 71, 48, 59, - 52, 42, 40, 42, 49, 32, 46, 63, 75, 73, 72, 72, 69, 75, 61, 60, - 22, 61, 67, 88, 92, 89, 85, 81, 69, 67, 64, 45, 12, 69, 73, 75, - 75, 75, 75, 75, 76, 79, 67, 61, 26, 69, 79, 92, 83, 63, 75, 72, - 63, 63, 71, 64, 60, 64, 76, 60, 80, 72, 75, 65, 75, 75, 51, 45, - 68, 81, 91, 76, 81, 84, 85, 79, 84, 80, 60, 41, 95, 92, 92, 83, - 87, 85, 87, 81, 84, 80, 88, 77, 80, 52, 64, 71, 72, 72, 73, 80, - 81, 87, 87, 65, 22, 91, 85, 93, 83, 76, 75, 72, 77, 83, 81, 67, - 51, 64, 77, 63, 56, 60, 60, 61, 61, 63, 61, 32, 24, 49, 93, 100, - 75, 88, 99, 96, 92, 97, 104, 37, 2, 112, 130, 124, 122, 118, 118, 120, - 115, 112, 103, 106, 102, 88, 96, 81, 87, 93, 84, 118, 115, 112, 115, 114, - 114, 114, 112, 111, 110, 106, 110, 107, 103, 100, 106, 102, 102, 106, 103, 81, - 49, 32, 28, 24, 24, 21, 16, 36, 32, 44, 46, 41, 40, 40, 41, 40, - 44, 40, 48, 45, 41, 8, 73, 126, 128, 128, 126, 132, 126, 114, 107, 49, - 95, 142, 183, 222, 222, 214, 225, 213, 212, 221, 217, 205, 199, 175, 118, 103, - 112, 102, 110, 107, 106, 93, 104, 114, 68, 80, 77, 116, 170, 114, 124, 128, - 126, 136, 132, 134, 138, 138, 138, 138, 135, 127, 104, 75, 37, 59, 48, 29, - 95, 127, 134, 136, 135, 139, 135, 140, 136, 132, 130, 126, 134, 134, 106, 106, - 114, 107, 106, 108, 122, 123, 108, 99, 122, 120, 120, 124, 119, 120, 120, 102, - 116, 115, 116, 68, 20, 107, 130, 131, 135, 136, 131, 136, 138, 127, 120, 99, - 49, 146, 157, 144, 143, 119, 142, 140, 130, 132, 132, 59, 8, 148, 159, 154, - 155, 151, 158, 151, 155, 151, 157, 134, 106, 6, 126, 146, 110, 123, 95, 104, - 97, 103, 96, 72, 16, 111, 142, 144, 143, 127, 132, 138, 140, 119, 95, 55, - 102, 139, 146, 139, 139, 144, 144, 147, 146, 139, 110, 116, 53, 151, 148, 134, - 142, 138, 136, 122, 136, 122, 80, 60, 122, 118, 134, 148, 146, 146, 130, 143, - 135, 134, 104, 79, 60, 115, 136, 138, 119, 127, 130, 132, 131, 130, 135, 91, - 18, 144, 147, 151, 144, 147, 142, 146, 139, 144, 136, 140, 135, 132, 103, 107, - 112, 142, 143, 119, 147, 151, 142, 104, 22, 139, 170, 165, 161, 154, 151, 147, - 151, 153, 140, 126, 9, 153, 120, 114, 116, 114, 127, 128, 132, 126, 119, 108, - 26, 166, 175, 161, 159, 163, 10, 4, 13, 13, 9, 5, 12, 24, 63, 32, - 63, 190, 242, 240, 241, 241, 245, 199, 143, 114, 122, 124, 126, 120, 111, 126, - 132, 124, 81, 22, 10, 9, 9, 12, 18, 18, 22, 21, 24, 18, 20, 24, - 46, 79, 144, 158, 122, 120, 120, 104, 85, 26, 24, 21, 29, 33, 26, 59, - 65, 67, 68, 72, 80, 88, 92, 93, 97, 97, 99, 100, 103, 104, 100, 99, - 99, 97, 97, 100, 93, 95, 92, 89, 88, 93, 76, 34, 28, 28, 25, 20, - 22, 37, 36, 33, 25, 26, 33, 41, 46, 32, 26, 26, 22, 24, 20, 20, - 22, 33, 32, 44, 45, 51, 53, 59, 60, 61, 52, 24, 52, 60, 77, 79, - 75, 68, 53, 29, 33, 28, 17, 12, 41, 44, 44, 45, 48, 48, 46, 51, - 52, 51, 37, 32, 49, 52, 59, 36, 33, 33, 36, 25, 14, 25, 21, 16, - 14, 12, 14, 13, 14, 20, 21, 22, 24, 26, 33, 22, 24, 24, 24, 25, - 42, 42, 29, 36, 41, 68, 40, 71, 84, 73, 69, 69, 69, 68, 69, 69, - 69, 71, 69, 67, 68, 72, 77, 77, 79, 81, 81, 83, 83, 84, 65, 28, - 81, 84, 76, 72, 67, 72, 67, 60, 75, 73, 53, 25, 57, 48, 34, 25, - 22, 21, 20, 21, 21, 16, 16, 25, 30, 29, 36, 30, 29, 30, 30, 42, - 42, 56, 40, 0, 18, 68, 76, 73, 75, 79, 85, 83, 85, 83, 83, 49, - 80, 111, 120, 131, 134, 131, 128, 130, 124, 130, 128, 130, 130, 128, 127, 127, - 124, 123, 120, 118, 118, 112, 119, 111, 89, 63, 28, 21, 21, 18, 12, 13, - 12, 10, 38, 40, 36, 42, 41, 38, 30, 36, 36, 36, 32, 41, 34, 41, - 12, 48, 110, 114, 107, 118, 120, 102, 81, 104, 40, 103, 155, 210, 225, 224, - 220, 224, 230, 209, 185, 155, 148, 134, 116, 103, 102, 80, 67, 87, 89, 88, - 87, 91, 83, 67, 84, 75, 119, 179, 155, 115, 114, 139, 139, 140, 142, 144, - 148, 147, 146, 140, 128, 93, 40, 33, 29, 69, 55, 60, 107, 110, 100, 110, - 114, 108, 108, 114, 114, 115, 111, 112, 120, 124, 123, 126, 124, 126, 126, 122, - 128, 127, 122, 111, 119, 122, 118, 102, 128, 119, 106, 88, 116, 114, 63, 18, - 56, 122, 126, 92, 102, 128, 130, 111, 111, 118, 91, 72, 136, 165, 122, 111, - 126, 124, 99, 103, 114, 99, 87, 16, 127, 163, 159, 159, 151, 159, 142, 146, - 157, 151, 107, 75, 9, 124, 144, 102, 107, 92, 89, 93, 89, 87, 44, 33, - 110, 79, 72, 75, 79, 72, 72, 73, 68, 59, 59, 77, 85, 87, 85, 85, - 99, 116, 131, 135, 135, 102, 96, 36, 148, 138, 132, 126, 128, 93, 85, 88, - 83, 81, 64, 84, 59, 76, 69, 83, 102, 107, 115, 107, 108, 110, 93, 55, - 97, 112, 115, 112, 107, 106, 122, 120, 114, 110, 87, 37, 100, 107, 95, 97, - 108, 110, 103, 111, 112, 110, 136, 131, 123, 138, 138, 139, 143, 143, 139, 143, - 139, 135, 97, 14, 138, 154, 153, 151, 151, 148, 151, 151, 151, 118, 127, 6, - 124, 107, 103, 110, 104, 108, 106, 91, 114, 122, 88, 24, 68, 100, 112, 111, - 108, 77, 71, 61, 57, 49, 57, 49, 56, 29, 36, 136, 238, 241, 240, 240, - 241, 195, 140, 116, 120, 130, 122, 114, 108, 131, 136, 131, 93, 28, 9, 9, - 8, 10, 18, 20, 21, 21, 22, 17, 21, 12, 20, 40, 67, 122, 169, 142, - 122, 120, 106, 91, 26, 24, 22, 29, 30, 25, 37, 40, 44, 45, 46, 52, - 63, 107, 175, 119, 97, 100, 106, 104, 107, 100, 99, 103, 104, 111, 111, 111, - 104, 100, 104, 100, 69, 26, 22, 21, 17, 18, 21, 18, 21, 22, 22, 25, - 21, 21, 22, 20, 40, 44, 46, 49, 55, 56, 51, 21, 71, 71, 48, 42, - 42, 44, 38, 36, 41, 52, 20, 45, 30, 25, 22, 21, 22, 16, 14, 16, - 14, 16, 9, 13, 12, 9, 9, 12, 12, 13, 13, 14, 17, 17, 36, 14, - 25, 46, 51, 57, 49, 60, 68, 93, 76, 85, 76, 97, 104, 96, 106, 106, - 99, 92, 87, 72, 38, 33, 79, 115, 118, 89, 85, 73, 60, 55, 49, 18, - 16, 12, 12, 12, 12, 12, 10, 13, 13, 13, 14, 16, 18, 20, 22, 21, - 25, 29, 33, 34, 40, 44, 65, 69, 83, 67, 30, 76, 64, 52, 40, 38, - 36, 33, 34, 36, 32, 30, 24, 20, 37, 63, 61, 68, 95, 104, 102, 111, - 100, 63, 20, 73, 115, 115, 88, 68, 69, 69, 57, 56, 22, 16, 2, 9, - 9, 30, 18, 18, 18, 34, 28, 29, 29, 41, 60, 89, 124, 179, 175, 124, - 131, 144, 139, 136, 139, 139, 139, 136, 135, 135, 134, 132, 131, 130, 123, 126, - 114, 118, 107, 56, 24, 21, 16, 16, 17, 20, 24, 26, 48, 41, 46, 73, - 83, 92, 96, 100, 92, 89, 75, 71, 33, 32, 21, 10, 41, 41, 44, 59, - 63, 102, 104, 97, 97, 32, 112, 167, 214, 238, 224, 228, 220, 170, 143, 119, - 119, 115, 108, 107, 103, 60, 72, 64, 69, 68, 60, 56, 60, 60, 63, 83, - 85, 119, 189, 182, 119, 110, 118, 135, 144, 147, 151, 153, 151, 150, 142, 128, - 85, 36, 36, 37, 46, 34, 17, 14, 18, 10, 8, 6, 9, 5, 2, 2, - 4, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2, 0, 0, 0, 0, 4, 4, 18, 37, 37, 42, 41, 40, - 51, 52, 67, 71, 81, 104, 48, 97, 130, 128, 106, 106, 120, 116, 97, 102, - 112, 53, 13, 25, 91, 99, 84, 75, 99, 106, 84, 79, 111, 103, 24, 10, - 67, 131, 126, 72, 46, 38, 32, 29, 40, 79, 68, 80, 85, 80, 99, 100, - 106, 112, 115, 118, 111, 51, 123, 116, 130, 119, 84, 46, 40, 68, 45, 87, - 93, 102, 51, 135, 96, 89, 100, 88, 108, 122, 119, 130, 124, 59, 118, 131, - 140, 136, 88, 87, 89, 55, 67, 65, 55, 63, 102, 100, 91, 89, 83, 79, - 72, 67, 69, 64, 40, 41, 29, 18, 16, 17, 9, 8, 9, 12, 1, 1, - 1, 17, 29, 17, 36, 33, 40, 52, 40, 83, 103, 126, 123, 84, 17, 80, - 89, 85, 84, 84, 80, 79, 79, 73, 75, 71, 5, 52, 55, 65, 60, 46, - 60, 59, 55, 56, 48, 56, 42, 52, 59, 59, 60, 65, 73, 56, 59, 48, - 45, 55, 51, 28, 32, 115, 225, 238, 238, 240, 238, 194, 130, 118, 127, 134, - 118, 112, 116, 132, 143, 139, 115, 42, 10, 8, 8, 8, 16, 16, 17, 22, - 28, 25, 40, 42, 59, 52, 40, 56, 110, 171, 157, 126, 120, 115, 91, 28, - 24, 21, 30, 30, 34, 44, 76, 84, 85, 77, 84, 81, 107, 186, 161, 97, - 99, 108, 102, 106, 115, 118, 132, 139, 140, 140, 144, 143, 136, 106, 97, 32, - 24, 21, 18, 17, 17, 18, 17, 17, 17, 24, 22, 41, 56, 69, 79, 92, - 95, 100, 99, 96, 88, 57, 38, 83, 88, 60, 60, 65, 65, 59, 48, 46, - 52, 20, 20, 28, 45, 48, 53, 83, 93, 103, 73, 59, 56, 103, 103, 112, - 92, 100, 85, 106, 91, 85, 91, 84, 36, 21, 68, 112, 102, 112, 104, 88, - 80, 91, 108, 87, 102, 92, 87, 76, 92, 106, 103, 91, 93, 85, 103, 46, - 32, 85, 124, 114, 112, 127, 123, 126, 130, 116, 107, 57, 29, 96, 112, 106, - 110, 108, 112, 119, 112, 111, 111, 106, 102, 100, 108, 107, 112, 103, 103, 95, - 65, 52, 55, 46, 67, 28, 38, 42, 69, 80, 79, 84, 99, 89, 83, 73, - 64, 42, 95, 123, 124, 124, 122, 124, 120, 116, 112, 102, 67, 24, 89, 118, - 119, 114, 114, 114, 114, 110, 84, 65, 57, 6, 71, 89, 91, 84, 89, 97, - 96, 95, 102, 100, 42, 56, 97, 120, 201, 183, 134, 123, 131, 148, 148, 147, - 151, 159, 159, 158, 159, 159, 153, 148, 130, 124, 114, 131, 118, 99, 37, 24, - 18, 17, 24, 25, 29, 40, 48, 52, 44, 64, 106, 108, 123, 130, 134, 126, - 123, 112, 107, 102, 88, 65, 9, 108, 116, 118, 115, 61, 63, 59, 99, 95, - 24, 127, 186, 220, 224, 230, 217, 157, 127, 120, 111, 102, 106, 100, 107, 65, - 45, 88, 80, 88, 93, 100, 91, 93, 89, 95, 99, 131, 120, 197, 191, 157, - 115, 114, 126, 144, 151, 148, 153, 155, 151, 140, 131, 81, 36, 42, 44, 53, - 34, 32, 85, 96, 93, 100, 92, 97, 88, 135, 114, 80, 80, 140, 123, 146, - 155, 155, 159, 157, 151, 165, 165, 161, 154, 128, 132, 154, 155, 150, 150, 155, - 151, 150, 123, 100, 65, 18, 102, 144, 138, 119, 119, 95, 77, 73, 32, 42, - 45, 45, 10, 8, 33, 9, 8, 4, 20, 1, 5, 2, 12, 9, 4, 8, - 5, 1, 0, 2, 2, 0, 0, 0, 5, 1, 14, 42, 34, 42, 61, 85, - 114, 83, 71, 115, 71, 77, 128, 142, 151, 148, 148, 151, 158, 161, 127, 112, - 56, 126, 135, 147, 153, 143, 134, 130, 122, 102, 106, 83, 103, 91, 115, 130, - 112, 128, 123, 139, 138, 124, 146, 130, 57, 131, 144, 131, 159, 158, 153, 146, - 131, 110, 106, 91, 61, 59, 24, 30, 79, 75, 111, 119, 124, 102, 96, 102, - 87, 37, 76, 167, 171, 140, 155, 167, 151, 144, 148, 114, 131, 140, 140, 140, - 146, 150, 143, 87, 46, 36, 33, 53, 32, 30, 33, 33, 28, 24, 28, 28, - 24, 24, 26, 30, 29, 33, 53, 68, 72, 72, 85, 112, 122, 104, 87, 81, - 89, 93, 142, 154, 140, 140, 146, 21, 24, 24, 37, 40, 44, 32, 38, 97, - 216, 232, 241, 237, 236, 185, 127, 119, 128, 136, 115, 112, 126, 136, 151, 146, - 135, 83, 18, 10, 9, 9, 14, 14, 17, 25, 29, 65, 64, 61, 65, 67, - 52, 44, 48, 77, 170, 175, 147, 118, 106, 85, 25, 21, 20, 28, 29, 29, - 77, 92, 99, 97, 96, 79, 69, 92, 197, 182, 122, 97, 103, 112, 122, 139, - 142, 144, 148, 151, 154, 153, 147, 139, 114, 84, 22, 20, 17, 17, 20, 25, - 29, 26, 29, 28, 29, 44, 92, 102, 104, 97, 93, 95, 88, 83, 75, 60, - 53, 20, 81, 81, 67, 60, 59, 65, 68, 75, 44, 55, 20, 71, 102, 99, - 102, 99, 108, 88, 108, 81, 110, 72, 75, 93, 97, 97, 102, 88, 85, 89, - 83, 97, 99, 44, 18, 89, 107, 111, 102, 104, 103, 104, 91, 89, 99, 92, - 64, 87, 100, 110, 108, 96, 104, 107, 99, 103, 49, 45, 102, 124, 120, 99, - 116, 114, 115, 107, 114, 124, 79, 30, 123, 131, 131, 92, 84, 81, 83, 91, - 92, 85, 111, 100, 65, 79, 92, 114, 96, 100, 97, 103, 107, 93, 60, 72, - 24, 60, 106, 115, 116, 112, 118, 111, 111, 110, 84, 65, 37, 93, 122, 112, - 108, 107, 106, 106, 106, 93, 106, 75, 24, 83, 118, 120, 114, 108, 115, 116, - 114, 108, 81, 57, 17, 111, 134, 131, 102, 97, 92, 112, 99, 93, 99, 57, - 55, 100, 116, 195, 205, 163, 120, 124, 146, 148, 162, 167, 174, 177, 174, 177, - 170, 163, 157, 126, 116, 130, 130, 118, 88, 30, 20, 17, 25, 32, 34, 40, - 51, 53, 60, 48, 87, 114, 130, 127, 124, 116, 120, 115, 122, 123, 123, 104, - 73, 8, 102, 115, 130, 123, 120, 114, 115, 103, 95, 24, 128, 194, 221, 228, - 222, 167, 131, 119, 106, 115, 97, 95, 111, 114, 55, 42, 77, 64, 76, 72, - 77, 80, 83, 71, 104, 140, 128, 132, 202, 197, 185, 115, 111, 120, 143, 155, - 157, 161, 159, 151, 140, 128, 65, 40, 29, 40, 55, 42, 57, 116, 140, 128, - 118, 115, 119, 114, 120, 118, 112, 108, 116, 146, 140, 142, 138, 146, 123, 128, - 151, 163, 136, 124, 140, 108, 134, 134, 140, 139, 135, 136, 132, 135, 136, 76, - 18, 102, 150, 148, 148, 128, 138, 122, 134, 102, 102, 83, 42, 33, 148, 150, - 118, 120, 124, 115, 104, 114, 103, 64, 20, 56, 159, 155, 115, 120, 154, 153, - 131, 112, 151, 130, 68, 12, 63, 116, 115, 93, 114, 112, 116, 112, 106, 69, - 106, 169, 165, 163, 155, 157, 148, 154, 144, 130, 123, 57, 135, 148, 162, 157, - 134, 135, 128, 128, 124, 135, 122, 116, 122, 130, 138, 131, 116, 124, 135, 147, - 148, 142, 134, 63, 135, 153, 144, 154, 142, 140, 150, 157, 157, 147, 97, 114, - 51, 97, 135, 128, 143, 144, 140, 128, 138, 138, 103, 95, 30, 136, 163, 161, - 155, 157, 157, 161, 150, 161, 151, 142, 131, 108, 150, 151, 143, 146, 147, 148, - 151, 114, 102, 95, 102, 148, 151, 165, 161, 169, 166, 167, 167, 144, 138, 138, - 144, 155, 155, 154, 170, 171, 150, 159, 153, 155, 134, 91, 130, 169, 167, 162, - 167, 166, 30, 36, 38, 24, 38, 24, 33, 45, 179, 228, 229, 232, 233, 193, - 130, 118, 131, 140, 123, 114, 138, 147, 153, 148, 144, 120, 46, 9, 9, 10, - 13, 21, 14, 14, 24, 63, 73, 71, 60, 56, 59, 57, 41, 53, 64, 147, - 179, 162, 120, 102, 79, 24, 20, 17, 28, 30, 33, 84, 104, 83, 85, 75, - 75, 75, 88, 204, 187, 173, 99, 103, 116, 130, 143, 148, 155, 151, 155, 154, - 157, 151, 135, 114, 53, 24, 17, 17, 24, 28, 29, 32, 28, 32, 34, 34, - 80, 108, 108, 100, 100, 85, 87, 71, 64, 69, 53, 52, 22, 73, 87, 73, - 55, 59, 63, 63, 73, 45, 55, 21, 75, 93, 99, 95, 111, 80, 89, 93, - 72, 81, 63, 89, 106, 103, 91, 92, 83, 87, 85, 89, 92, 92, 38, 18, - 103, 103, 102, 95, 102, 106, 96, 93, 95, 88, 81, 57, 83, 107, 116, 104, - 103, 104, 102, 95, 99, 48, 33, 95, 119, 122, 115, 112, 99, 112, 100, 114, - 107, 106, 36, 108, 103, 139, 127, 130, 128, 124, 126, 122, 116, 100, 93, 64, - 111, 122, 115, 122, 112, 111, 111, 104, 102, 80, 76, 28, 88, 119, 114, 108, - 99, 103, 92, 89, 102, 97, 67, 38, 87, 110, 115, 106, 110, 106, 104, 107, - 108, 99, 75, 29, 87, 99, 120, 107, 104, 111, 102, 118, 116, 81, 64, 0, - 110, 114, 123, 123, 130, 127, 116, 127, 102, 103, 63, 49, 102, 122, 194, 217, - 201, 136, 119, 136, 150, 159, 167, 178, 182, 179, 179, 181, 173, 161, 127, 126, - 140, 131, 120, 88, 28, 20, 20, 34, 45, 55, 53, 52, 57, 57, 44, 99, - 119, 128, 123, 112, 112, 111, 118, 110, 112, 118, 115, 73, 9, 115, 119, 118, - 115, 111, 115, 97, 71, 97, 33, 122, 199, 218, 230, 206, 131, 115, 110, 114, - 99, 97, 116, 118, 102, 56, 45, 46, 81, 83, 73, 72, 89, 87, 67, 108, - 140, 136, 132, 206, 209, 198, 114, 108, 119, 132, 146, 153, 157, 163, 155, 140, - 128, 71, 36, 28, 49, 68, 32, 73, 134, 123, 124, 127, 134, 131, 136, 132, - 111, 103, 99, 135, 163, 157, 147, 142, 135, 148, 142, 153, 154, 153, 146, 104, - 136, 157, 158, 158, 162, 159, 158, 148, 131, 95, 77, 22, 116, 147, 147, 150, - 150, 146, 124, 128, 122, 114, 89, 42, 110, 151, 144, 143, 143, 142, 150, 147, - 127, 128, 72, 13, 132, 159, 144, 139, 147, 148, 144, 146, 148, 140, 126, 77, - 14, 93, 108, 102, 99, 118, 110, 112, 118, 89, 67, 95, 167, 159, 157, 146, - 147, 144, 147, 147, 159, 118, 63, 128, 131, 134, 161, 166, 158, 142, 154, 130, - 147, 115, 75, 111, 143, 147, 134, 136, 155, 150, 163, 130, 144, 135, 68, 134, - 138, 147, 154, 136, 135, 138, 148, 142, 154, 120, 118, 24, 120, 130, 136, 135, - 134, 139, 132, 131, 138, 131, 107, 42, 167, 162, 148, 151, 148, 151, 154, 155, - 154, 151, 146, 122, 132, 143, 151, 144, 146, 151, 153, 150, 154, 159, 83, 150, - 170, 157, 161, 170, 154, 155, 155, 171, 170, 144, 119, 135, 170, 181, 173, 171, - 169, 162, 148, 169, 167, 150, 92, 138, 171, 162, 166, 163, 162, 16, 18, 20, - 59, 21, 41, 34, 104, 222, 226, 230, 233, 212, 146, 119, 126, 139, 138, 114, - 130, 153, 159, 155, 150, 139, 87, 18, 9, 8, 12, 14, 25, 16, 10, 28, - 65, 57, 59, 46, 38, 40, 37, 49, 45, 59, 114, 185, 174, 126, 104, 75, - 24, 21, 17, 28, 30, 26, 71, 99, 83, 84, 79, 75, 85, 95, 206, 199, - 185, 95, 104, 116, 138, 147, 155, 154, 163, 155, 153, 157, 146, 134, 116, 30, - 20, 17, 16, 25, 37, 36, 30, 33, 36, 30, 49, 96, 106, 108, 100, 83, - 79, 76, 73, 64, 63, 60, 49, 22, 71, 76, 80, 73, 68, 64, 56, 57, - 45, 52, 17, 83, 91, 110, 81, 79, 80, 77, 84, 83, 81, 60, 85, 106, - 99, 93, 93, 104, 96, 96, 89, 81, 85, 41, 21, 83, 107, 92, 108, 92, - 75, 99, 92, 89, 89, 81, 55, 85, 100, 116, 102, 116, 106, 96, 103, 95, - 51, 32, 95, 116, 114, 108, 108, 108, 97, 96, 103, 108, 116, 40, 75, 124, - 95, 119, 128, 114, 127, 122, 111, 122, 108, 80, 61, 114, 119, 106, 96, 95, - 89, 104, 108, 100, 95, 76, 33, 104, 114, 111, 115, 97, 87, 88, 95, 100, - 84, 63, 22, 93, 112, 106, 115, 107, 104, 110, 107, 107, 88, 77, 40, 80, - 104, 118, 115, 115, 100, 112, 108, 111, 79, 56, 0, 107, 120, 119, 120, 127, - 114, 135, 134, 134, 120, 67, 57, 102, 123, 194, 210, 199, 135, 118, 132, 146, - 150, 163, 178, 183, 185, 186, 177, 173, 155, 127, 138, 142, 136, 127, 72, 26, - 20, 24, 51, 55, 53, 52, 56, 64, 67, 51, 104, 127, 128, 114, 118, 122, - 120, 115, 114, 112, 115, 97, 75, 8, 112, 103, 122, 119, 118, 114, 97, 75, - 92, 28, 127, 193, 214, 226, 185, 124, 115, 107, 107, 99, 102, 124, 116, 103, - 55, 40, 40, 65, 79, 84, 73, 85, 87, 60, 104, 138, 128, 138, 208, 205, - 202, 114, 107, 115, 124, 139, 146, 159, 166, 158, 143, 123, 69, 38, 25, 36, - 71, 40, 73, 135, 140, 126, 128, 123, 122, 110, 122, 107, 96, 34, 124, 159, - 154, 142, 143, 139, 150, 154, 155, 140, 155, 142, 103, 144, 157, 163, 157, 150, - 144, 139, 138, 134, 142, 81, 21, 114, 130, 151, 143, 140, 116, 136, 139, 140, - 147, 93, 40, 134, 151, 136, 144, 136, 144, 147, 148, 142, 130, 76, 13, 154, - 158, 147, 143, 150, 159, 153, 153, 158, 150, 144, 80, 12, 103, 102, 97, 103, - 118, 108, 108, 111, 104, 59, 93, 153, 159, 143, 155, 155, 147, 147, 148, 130, - 130, 60, 119, 138, 140, 161, 150, 143, 146, 138, 143, 148, 138, 81, 150, 144, - 142, 138, 148, 153, 161, 153, 139, 142, 132, 76, 130, 142, 153, 143, 138, 139, - 139, 142, 148, 150, 142, 120, 56, 100, 143, 127, 128, 138, 146, 124, 140, 134, - 111, 111, 40, 112, 166, 158, 139, 148, 144, 148, 142, 147, 144, 126, 111, 146, - 143, 148, 154, 151, 147, 150, 148, 138, 159, 100, 154, 178, 170, 163, 174, 167, - 150, 169, 154, 136, 128, 130, 139, 170, 166, 165, 150, 157, 151, 162, 161, 157, - 140, 89, 108, 170, 162, 165, 157, 161, 75, 67, 64, 25, 32, 37, 56, 170, - 218, 236, 224, 218, 162, 132, 122, 138, 142, 128, 119, 151, 163, 163, 155, 147, - 126, 52, 10, 6, 9, 10, 16, 24, 16, 12, 55, 75, 64, 46, 37, 44, - 49, 34, 40, 42, 52, 107, 190, 182, 157, 102, 69, 24, 18, 14, 25, 30, - 32, 57, 103, 83, 80, 83, 72, 71, 83, 213, 204, 186, 95, 108, 119, 132, - 147, 155, 158, 157, 155, 155, 157, 144, 122, 118, 28, 17, 16, 25, 32, 37, - 33, 40, 34, 36, 30, 46, 99, 102, 104, 81, 75, 76, 75, 71, 65, 61, - 55, 61, 34, 79, 75, 64, 67, 65, 76, 53, 68, 44, 52, 16, 76, 85, - 92, 68, 85, 71, 89, 63, 81, 75, 53, 85, 106, 93, 97, 95, 96, 103, - 92, 93, 97, 80, 41, 20, 85, 102, 96, 108, 100, 103, 93, 99, 85, 93, - 80, 56, 84, 100, 103, 103, 116, 103, 89, 99, 89, 57, 30, 96, 120, 122, - 118, 107, 106, 104, 100, 100, 102, 116, 53, 45, 124, 131, 132, 126, 123, 122, - 119, 119, 130, 112, 89, 60, 108, 119, 106, 104, 115, 97, 95, 95, 104, 85, - 77, 32, 92, 122, 100, 104, 95, 88, 100, 89, 95, 88, 64, 24, 84, 106, - 106, 122, 103, 102, 100, 96, 92, 99, 79, 41, 83, 115, 118, 120, 106, 108, - 107, 111, 107, 81, 64, 8, 114, 112, 110, 127, 128, 116, 123, 131, 136, 112, - 59, 64, 103, 115, 165, 220, 206, 140, 115, 127, 147, 151, 163, 174, 173, 177, - 181, 181, 173, 139, 123, 139, 146, 135, 127, 53, 22, 20, 38, 49, 57, 56, - 57, 63, 77, 64, 59, 107, 128, 120, 119, 115, 116, 111, 116, 119, 108, 112, - 95, 69, 8, 96, 119, 115, 116, 114, 115, 85, 77, 97, 33, 131, 204, 213, - 220, 159, 126, 107, 115, 100, 93, 112, 118, 119, 102, 52, 40, 40, 52, 80, - 85, 89, 81, 93, 57, 104, 139, 135, 139, 209, 210, 206, 112, 103, 111, 126, - 131, 140, 159, 165, 159, 143, 118, 68, 41, 30, 40, 59, 44, 69, 124, 131, - 126, 126, 134, 118, 118, 120, 111, 92, 79, 148, 162, 157, 147, 155, 151, 155, - 154, 140, 142, 153, 135, 106, 147, 161, 158, 150, 143, 135, 136, 142, 132, 139, - 85, 25, 112, 144, 146, 138, 138, 140, 140, 136, 142, 116, 92, 42, 87, 142, - 136, 142, 144, 146, 142, 151, 144, 123, 83, 18, 99, 158, 140, 150, 146, 151, - 144, 144, 146, 138, 140, 79, 24, 99, 102, 100, 111, 119, 108, 112, 110, 93, - 60, 96, 157, 159, 153, 159, 165, 158, 148, 147, 136, 118, 68, 120, 148, 144, - 148, 148, 140, 140, 157, 146, 150, 146, 88, 144, 154, 151, 150, 162, 158, 151, - 128, 146, 144, 132, 81, 130, 139, 155, 165, 150, 150, 157, 161, 150, 143, 120, - 122, 55, 111, 135, 118, 132, 128, 139, 132, 142, 127, 110, 100, 40, 120, 167, - 162, 146, 138, 132, 140, 138, 135, 120, 130, 103, 138, 131, 138, 150, 151, 150, - 147, 143, 150, 139, 77, 127, 170, 157, 155, 150, 161, 150, 155, 159, 155, 151, - 103, 120, 171, 167, 155, 167, 169, 143, 163, 162, 154, 138, 85, 116, 165, 163, - 163, 161, 157, 71, 28, 44, 21, 40, 37, 100, 206, 220, 221, 222, 182, 120, - 126, 134, 142, 136, 116, 132, 159, 166, 161, 153, 142, 102, 22, 6, 6, 9, - 14, 16, 21, 14, 13, 61, 65, 57, 41, 42, 45, 51, 41, 42, 48, 49, - 87, 187, 183, 163, 102, 69, 20, 17, 17, 26, 30, 29, 48, 97, 85, 81, - 83, 76, 81, 81, 214, 205, 173, 102, 104, 116, 131, 143, 142, 155, 153, 157, - 157, 151, 138, 119, 118, 26, 16, 14, 25, 38, 32, 33, 38, 41, 37, 32, - 46, 100, 106, 100, 76, 71, 76, 63, 67, 72, 60, 56, 57, 24, 75, 71, - 83, 87, 81, 80, 53, 60, 42, 55, 20, 73, 88, 106, 80, 80, 77, 65, - 72, 77, 79, 55, 91, 100, 88, 96, 97, 103, 88, 85, 88, 89, 80, 45, - 18, 79, 97, 89, 108, 111, 107, 96, 95, 87, 88, 79, 51, 85, 93, 95, - 99, 111, 116, 114, 111, 88, 49, 30, 87, 119, 120, 116, 106, 102, 102, 111, - 96, 106, 114, 85, 45, 111, 127, 118, 114, 102, 115, 124, 128, 107, 102, 81, - 64, 110, 120, 95, 100, 102, 96, 96, 115, 104, 79, 79, 36, 88, 104, 110, - 103, 96, 87, 85, 102, 99, 84, 65, 33, 97, 110, 110, 127, 111, 110, 96, - 104, 112, 102, 91, 42, 84, 116, 107, 102, 107, 103, 96, 102, 107, 83, 64, - 9, 104, 114, 108, 116, 118, 118, 104, 119, 115, 93, 73, 63, 91, 122, 155, - 218, 217, 162, 111, 116, 143, 150, 166, 175, 179, 185, 181, 171, 167, 131, 135, - 147, 143, 136, 123, 33, 22, 18, 36, 55, 59, 59, 64, 71, 72, 71, 60, - 107, 126, 126, 120, 124, 112, 123, 116, 119, 108, 114, 106, 71, 8, 104, 102, - 111, 142, 112, 112, 110, 79, 91, 30, 126, 195, 220, 220, 150, 112, 102, 106, - 93, 100, 116, 116, 120, 114, 45, 37, 33, 46, 76, 87, 84, 72, 91, 61, - 108, 146, 131, 144, 213, 213, 206, 111, 106, 111, 118, 130, 142, 157, 166, 162, - 146, 130, 67, 40, 41, 38, 63, 49, 69, 123, 128, 128, 122, 124, 100, 111, - 135, 99, 97, 83, 151, 154, 142, 135, 140, 148, 154, 134, 130, 143, 154, 124, - 96, 146, 163, 153, 135, 143, 131, 135, 131, 138, 148, 87, 28, 111, 142, 148, - 136, 136, 138, 128, 134, 119, 123, 93, 41, 106, 135, 127, 139, 143, 144, 153, - 148, 138, 132, 84, 22, 100, 151, 142, 144, 144, 143, 142, 143, 154, 134, 127, - 87, 20, 114, 107, 97, 111, 119, 110, 108, 107, 96, 60, 110, 162, 157, 162, - 166, 167, 159, 153, 150, 136, 122, 72, 118, 154, 151, 157, 150, 140, 140, 148, - 138, 146, 146, 56, 150, 153, 153, 150, 157, 150, 144, 127, 144, 142, 138, 85, - 131, 140, 150, 139, 154, 150, 146, 147, 154, 136, 123, 120, 33, 106, 131, 138, - 112, 120, 136, 122, 131, 140, 130, 102, 40, 116, 167, 161, 134, 142, 135, 132, - 132, 131, 115, 120, 104, 135, 157, 148, 147, 148, 155, 146, 144, 143, 153, 81, - 130, 169, 165, 159, 153, 151, 155, 153, 146, 138, 122, 115, 143, 169, 170, 150, - 157, 159, 158, 151, 153, 155, 142, 92, 123, 163, 159, 162, 159, 155, 93, 45, - 20, 20, 37, 45, 161, 209, 224, 214, 206, 159, 116, 119, 139, 144, 138, 120, - 148, 165, 165, 161, 153, 138, 77, 12, 4, 5, 10, 16, 18, 20, 16, 16, - 69, 64, 56, 36, 48, 56, 44, 37, 46, 53, 52, 93, 185, 185, 171, 110, - 71, 24, 16, 16, 28, 32, 30, 34, 93, 91, 79, 89, 79, 81, 83, 217, - 201, 186, 106, 107, 118, 131, 139, 143, 150, 155, 157, 155, 143, 135, 116, 115, - 28, 16, 13, 26, 42, 38, 34, 32, 40, 37, 30, 60, 95, 110, 84, 83, - 72, 75, 75, 73, 67, 69, 53, 53, 24, 81, 72, 67, 67, 71, 76, 52, - 59, 44, 51, 18, 73, 87, 95, 71, 76, 72, 77, 65, 64, 75, 55, 85, - 99, 103, 97, 102, 87, 89, 92, 89, 88, 77, 42, 17, 75, 96, 89, 87, - 100, 100, 93, 93, 88, 87, 75, 44, 79, 97, 108, 102, 112, 102, 97, 88, - 97, 45, 33, 77, 119, 115, 111, 102, 104, 108, 100, 96, 104, 108, 81, 36, - 85, 124, 128, 104, 114, 123, 118, 108, 112, 97, 72, 69, 110, 116, 92, 99, - 108, 97, 97, 85, 97, 97, 77, 40, 92, 110, 106, 110, 106, 87, 87, 84, - 96, 92, 67, 36, 96, 115, 100, 104, 112, 99, 108, 110, 111, 102, 85, 45, - 85, 102, 114, 103, 103, 100, 108, 104, 100, 84, 65, 0, 118, 115, 104, 88, - 119, 115, 124, 122, 115, 100, 71, 55, 85, 124, 115, 220, 222, 189, 114, 114, - 139, 150, 162, 173, 177, 178, 175, 178, 158, 132, 139, 151, 143, 136, 123, 29, - 22, 20, 34, 60, 68, 65, 75, 87, 73, 67, 61, 95, 124, 124, 127, 112, - 122, 116, 115, 119, 106, 111, 108, 75, 10, 103, 107, 110, 112, 139, 124, 115, - 79, 91, 22, 114, 186, 213, 237, 159, 112, 97, 106, 93, 111, 119, 116, 123, - 99, 44, 38, 30, 46, 71, 85, 91, 76, 93, 56, 115, 138, 135, 154, 220, - 220, 208, 107, 100, 111, 123, 130, 144, 155, 167, 162, 147, 139, 68, 45, 26, - 42, 67, 53, 67, 124, 127, 128, 131, 120, 114, 122, 110, 119, 81, 69, 134, - 150, 150, 143, 148, 132, 128, 142, 139, 147, 147, 106, 119, 153, 162, 142, 134, - 136, 142, 131, 140, 134, 139, 89, 29, 119, 132, 142, 128, 139, 132, 136, 134, - 124, 111, 95, 38, 114, 148, 130, 134, 143, 147, 146, 146, 124, 134, 87, 17, - 106, 151, 144, 150, 146, 143, 147, 157, 130, 126, 128, 81, 21, 100, 104, 104, - 110, 116, 115, 106, 103, 85, 60, 103, 161, 150, 163, 162, 161, 157, 163, 159, - 140, 120, 71, 123, 142, 132, 158, 147, 140, 142, 150, 144, 147, 143, 53, 144, - 157, 158, 150, 153, 150, 124, 130, 124, 134, 136, 85, 108, 138, 146, 151, 146, - 148, 140, 148, 150, 154, 128, 120, 26, 103, 138, 136, 130, 116, 130, 132, 130, - 110, 126, 100, 45, 120, 166, 153, 144, 144, 136, 131, 128, 124, 115, 132, 100, - 130, 148, 142, 142, 140, 139, 144, 139, 140, 153, 93, 153, 173, 162, 162, 153, - 151, 158, 155, 134, 147, 144, 110, 154, 165, 161, 165, 153, 151, 135, 146, 140, - 136, 124, 87, 136, 161, 162, 154, 159, 159, 20, 65, 20, 33, 38, 83, 190, - 218, 208, 212, 171, 132, 116, 138, 142, 144, 128, 132, 162, 167, 165, 158, 148, - 130, 36, 8, 5, 6, 10, 17, 20, 29, 17, 14, 76, 63, 49, 40, 57, - 45, 41, 40, 48, 44, 45, 116, 185, 182, 178, 103, 67, 22, 17, 16, 26, - 29, 29, 33, 92, 89, 84, 92, 85, 80, 80, 221, 199, 197, 107, 106, 115, - 127, 136, 143, 147, 151, 157, 151, 142, 135, 115, 114, 25, 14, 10, 25, 46, - 36, 38, 36, 48, 38, 29, 61, 102, 108, 83, 75, 80, 83, 73, 75, 77, - 65, 52, 52, 24, 72, 79, 72, 68, 56, 60, 64, 56, 45, 49, 17, 72, - 92, 103, 77, 77, 83, 61, 79, 67, 75, 51, 89, 102, 99, 91, 88, 97, - 95, 96, 92, 87, 51, 48, 20, 71, 88, 93, 91, 91, 93, 89, 88, 92, - 85, 77, 40, 92, 96, 106, 104, 106, 107, 102, 108, 96, 45, 33, 73, 106, - 114, 108, 92, 108, 108, 91, 102, 100, 96, 88, 46, 83, 123, 131, 126, 100, - 112, 93, 108, 104, 95, 53, 81, 104, 115, 103, 103, 88, 84, 89, 83, 87, - 97, 79, 45, 68, 99, 114, 88, 77, 88, 96, 88, 91, 76, 68, 17, 92, - 107, 106, 100, 99, 91, 100, 108, 102, 97, 87, 51, 57, 96, 111, 112, 116, - 114, 112, 112, 99, 77, 59, 0, 108, 110, 104, 107, 102, 124, 122, 119, 92, - 123, 76, 69, 59, 122, 111, 226, 226, 220, 115, 114, 138, 153, 157, 163, 177, - 179, 177, 177, 148, 136, 154, 154, 143, 135, 123, 30, 22, 18, 38, 67, 63, - 71, 76, 85, 80, 76, 68, 88, 122, 123, 122, 120, 122, 122, 119, 116, 112, - 112, 106, 69, 10, 100, 97, 96, 111, 147, 116, 110, 79, 87, 18, 93, 146, - 193, 237, 165, 112, 108, 107, 110, 118, 114, 120, 114, 69, 42, 36, 32, 46, - 71, 88, 91, 84, 91, 46, 110, 135, 132, 148, 220, 214, 210, 110, 102, 112, - 126, 135, 146, 155, 166, 165, 157, 144, 71, 45, 25, 37, 64, 51, 56, 119, - 122, 131, 126, 124, 127, 116, 106, 112, 81, 24, 126, 154, 136, 127, 138, 142, - 144, 144, 146, 148, 148, 104, 126, 157, 150, 124, 150, 131, 131, 131, 132, 136, - 136, 93, 29, 112, 140, 144, 136, 132, 127, 134, 126, 136, 138, 102, 37, 134, - 143, 132, 131, 142, 142, 142, 143, 127, 119, 89, 13, 111, 148, 146, 146, 144, - 157, 154, 128, 130, 128, 138, 77, 17, 108, 102, 100, 97, 100, 116, 103, 104, - 88, 52, 96, 151, 155, 158, 157, 165, 150, 144, 143, 138, 124, 71, 114, 148, - 143, 154, 143, 140, 144, 148, 139, 151, 144, 53, 148, 153, 162, 144, 146, 161, - 138, 139, 139, 134, 136, 93, 100, 140, 135, 147, 161, 157, 146, 150, 153, 146, - 126, 126, 52, 95, 140, 111, 124, 115, 132, 120, 111, 115, 107, 110, 49, 114, - 127, 158, 140, 135, 136, 132, 134, 126, 119, 122, 92, 132, 142, 143, 142, 138, - 142, 147, 143, 135, 134, 96, 158, 177, 167, 163, 144, 157, 146, 142, 158, 134, - 143, 126, 161, 144, 134, 139, 131, 144, 134, 127, 115, 130, 108, 93, 120, 162, - 146, 144, 157, 163, 64, 25, 18, 41, 45, 114, 189, 213, 204, 204, 134, 136, - 134, 139, 144, 144, 122, 150, 169, 169, 165, 157, 147, 120, 26, 6, 5, 6, - 12, 18, 12, 20, 17, 13, 68, 56, 48, 52, 40, 40, 38, 36, 42, 53, - 46, 126, 185, 182, 166, 99, 61, 22, 16, 14, 30, 38, 33, 37, 83, 99, - 76, 84, 83, 73, 76, 225, 199, 205, 108, 106, 115, 127, 135, 146, 151, 153, - 153, 138, 139, 136, 122, 119, 22, 13, 10, 29, 41, 32, 37, 32, 53, 38, - 29, 63, 92, 92, 80, 49, 49, 68, 71, 53, 55, 59, 57, 61, 37, 84, - 76, 71, 56, 61, 55, 63, 53, 42, 46, 14, 72, 80, 93, 65, 77, 80, - 72, 80, 79, 71, 42, 84, 102, 110, 106, 106, 99, 87, 79, 85, 63, 51, - 46, 21, 57, 77, 81, 63, 73, 92, 83, 67, 73, 83, 69, 40, 79, 89, - 106, 108, 89, 81, 79, 77, 63, 55, 29, 68, 114, 116, 112, 110, 99, 97, - 96, 102, 93, 99, 96, 51, 67, 118, 127, 116, 95, 119, 112, 103, 97, 88, - 52, 67, 103, 114, 103, 97, 85, 88, 80, 83, 83, 88, 80, 42, 64, 79, - 77, 77, 79, 77, 81, 81, 89, 89, 65, 18, 91, 108, 108, 100, 100, 99, - 92, 97, 89, 88, 87, 55, 68, 91, 114, 114, 122, 112, 104, 111, 76, 81, - 69, 6, 107, 110, 100, 107, 89, 111, 115, 118, 107, 114, 63, 65, 48, 119, - 116, 226, 232, 222, 116, 111, 139, 151, 155, 159, 171, 177, 174, 165, 136, 147, - 153, 154, 146, 140, 126, 28, 21, 18, 40, 64, 68, 69, 75, 83, 83, 79, - 68, 77, 115, 124, 127, 115, 119, 120, 114, 114, 110, 103, 89, 68, 12, 92, - 100, 112, 110, 111, 106, 92, 88, 92, 20, 73, 122, 163, 157, 120, 106, 96, - 83, 100, 97, 103, 99, 68, 44, 40, 34, 33, 44, 75, 87, 89, 83, 91, - 48, 114, 134, 123, 122, 213, 224, 220, 110, 97, 112, 127, 136, 146, 155, 169, - 163, 144, 138, 67, 46, 26, 34, 64, 56, 51, 93, 123, 120, 126, 122, 123, - 122, 111, 114, 79, 48, 150, 148, 131, 140, 150, 153, 151, 153, 148, 154, 143, - 100, 131, 162, 140, 142, 139, 134, 134, 139, 134, 139, 135, 95, 32, 122, 138, - 143, 134, 128, 127, 126, 134, 134, 124, 102, 44, 95, 136, 131, 122, 128, 131, - 130, 123, 131, 128, 97, 26, 112, 110, 158, 154, 155, 157, 158, 115, 131, 128, - 131, 93, 30, 102, 97, 97, 96, 102, 99, 114, 103, 91, 56, 104, 154, 148, - 151, 161, 144, 146, 144, 136, 142, 123, 81, 119, 151, 142, 144, 144, 155, 139, - 157, 144, 136, 138, 77, 144, 154, 153, 151, 155, 148, 148, 147, 139, 146, 142, - 110, 93, 120, 138, 135, 116, 110, 118, 135, 123, 123, 126, 123, 52, 116, 142, - 127, 102, 102, 88, 114, 115, 104, 110, 112, 73, 97, 123, 134, 134, 128, 128, - 135, 131, 128, 130, 146, 127, 139, 139, 153, 146, 146, 136, 147, 146, 139, 140, - 135, 126, 174, 171, 142, 144, 142, 140, 142, 135, 130, 135, 135, 142, 128, 130, - 136, 124, 115, 139, 147, 154, 143, 146, 142, 148, 155, 158, 155, 150, 146, 25, - 25, 13, 38, 48, 126, 191, 202, 209, 146, 139, 122, 139, 143, 148, 142, 127, - 162, 171, 169, 165, 155, 143, 106, 18, 6, 4, 6, 9, 17, 16, 30, 14, - 14, 69, 52, 41, 46, 38, 36, 34, 36, 44, 41, 51, 136, 179, 177, 162, - 102, 57, 21, 17, 16, 29, 33, 33, 30, 71, 97, 91, 75, 84, 77, 75, - 225, 208, 210, 108, 107, 116, 131, 144, 143, 147, 146, 139, 131, 136, 134, 122, - 122, 20, 13, 10, 29, 37, 37, 32, 32, 32, 48, 49, 55, 64, 67, 60, - 56, 60, 55, 56, 59, 80, 71, 59, 52, 25, 68, 76, 56, 51, 52, 51, - 49, 46, 53, 52, 21, 72, 88, 85, 67, 63, 63, 57, 67, 67, 65, 46, - 65, 84, 100, 67, 72, 63, 63, 56, 48, 40, 34, 51, 45, 49, 51, 51, - 60, 46, 48, 48, 48, 49, 46, 41, 36, 59, 59, 61, 56, 48, 48, 52, - 52, 44, 44, 59, 59, 93, 106, 99, 83, 93, 99, 102, 88, 87, 102, 95, - 85, 63, 72, 116, 107, 83, 96, 96, 97, 96, 81, 56, 61, 93, 96, 81, - 81, 83, 91, 92, 80, 79, 81, 77, 75, 68, 79, 80, 80, 69, 77, 67, - 84, 79, 84, 68, 30, 97, 91, 93, 92, 91, 91, 89, 92, 87, 88, 72, - 85, 51, 59, 63, 68, 65, 69, 68, 69, 69, 77, 64, 4, 45, 114, 107, - 60, 81, 99, 104, 96, 89, 103, 95, 77, 55, 77, 96, 220, 233, 224, 111, - 108, 132, 147, 151, 150, 157, 170, 170, 165, 143, 158, 158, 157, 148, 140, 126, - 25, 20, 20, 34, 61, 68, 75, 76, 75, 80, 85, 84, 68, 79, 100, 110, - 108, 107, 107, 110, 111, 111, 106, 104, 68, 12, 87, 100, 104, 95, 97, 84, - 87, 88, 88, 36, 57, 77, 96, 118, 87, 56, 48, 37, 34, 37, 37, 37, - 34, 40, 36, 30, 30, 40, 77, 80, 81, 68, 89, 49, 107, 120, 136, 120, - 201, 222, 218, 107, 100, 116, 130, 140, 146, 158, 169, 165, 146, 136, 63, 48, - 49, 33, 64, 63, 53, 63, 92, 100, 99, 107, 107, 116, 106, 106, 93, 68, - 148, 138, 144, 144, 135, 135, 128, 131, 139, 134, 115, 96, 119, 138, 148, 140, - 138, 143, 139, 138, 119, 107, 114, 93, 37, 106, 118, 136, 144, 147, 136, 140, - 131, 122, 97, 104, 44, 102, 122, 140, 128, 128, 127, 124, 108, 119, 111, 96, - 26, 97, 83, 89, 107, 118, 119, 100, 107, 120, 89, 100, 91, 30, 104, 102, - 103, 103, 106, 100, 97, 103, 95, 61, 102, 116, 118, 114, 102, 112, 134, 126, - 142, 128, 116, 95, 83, 134, 126, 139, 124, 134, 131, 138, 132, 128, 139, 37, - 134, 146, 143, 132, 139, 139, 143, 135, 134, 142, 134, 124, 130, 135, 135, 132, - 132, 127, 128, 134, 131, 123, 124, 123, 22, 108, 84, 115, 75, 110, 91, 95, - 118, 114, 96, 107, 111, 118, 115, 122, 122, 120, 119, 123, 127, 124, 112, 131, - 104, 124, 126, 131, 134, 136, 119, 123, 134, 130, 132, 128, 140, 147, 127, 155, - 147, 128, 138, 150, 147, 116, 132, 132, 126, 128, 138, 143, 143, 138, 142, 144, - 126, 107, 102, 95, 147, 99, 147, 163, 163, 173, 14, 17, 17, 40, 48, 150, - 209, 148, 143, 150, 112, 147, 131, 144, 146, 138, 138, 169, 173, 169, 162, 154, - 138, 89, 14, 6, 5, 8, 12, 17, 16, 20, 14, 9, 61, 53, 37, 37, - 29, 34, 38, 33, 45, 42, 48, 151, 181, 175, 163, 95, 53, 21, 17, 16, - 32, 34, 37, 36, 48, 71, 89, 84, 83, 76, 72, 225, 217, 220, 110, 107, - 112, 130, 131, 131, 134, 132, 138, 142, 139, 138, 127, 124, 18, 12, 9, 25, - 28, 30, 36, 38, 34, 38, 37, 40, 46, 44, 41, 46, 48, 46, 51, 48, - 49, 51, 51, 49, 48, 53, 51, 51, 48, 48, 51, 51, 46, 46, 42, 24, - 64, 89, 59, 53, 49, 49, 52, 51, 49, 51, 42, 51, 51, 49, 51, 48, - 45, 44, 44, 42, 40, 36, 30, 20, 20, 18, 20, 18, 16, 16, 16, 14, - 16, 13, 13, 14, 13, 18, 21, 21, 17, 18, 25, 37, 33, 37, 34, 48, - 73, 71, 84, 93, 83, 77, 84, 87, 87, 85, 85, 75, 67, 76, 69, 64, - 56, 48, 46, 46, 55, 48, 38, 51, 55, 63, 59, 59, 81, 83, 81, 64, - 63, 51, 46, 56, 64, 73, 75, 75, 60, 51, 53, 68, 75, 73, 67, 29, - 55, 61, 53, 64, 63, 64, 64, 68, 68, 69, 72, 73, 71, 77, 55, 53, - 46, 32, 24, 21, 29, 34, 28, 0, 24, 24, 34, 30, 36, 40, 46, 51, - 60, 71, 96, 81, 73, 69, 107, 217, 234, 225, 110, 106, 115, 124, 140, 150, - 158, 157, 162, 159, 144, 159, 159, 155, 147, 135, 123, 24, 20, 20, 28, 37, - 53, 53, 63, 68, 71, 75, 71, 71, 88, 91, 93, 92, 95, 93, 96, 96, - 100, 102, 93, 69, 17, 95, 99, 80, 71, 72, 64, 53, 77, 73, 40, 38, - 40, 63, 49, 44, 38, 41, 33, 34, 44, 42, 33, 33, 33, 36, 48, 51, - 51, 53, 56, 55, 57, 91, 46, 68, 68, 84, 123, 191, 224, 216, 108, 104, - 115, 126, 139, 148, 158, 171, 163, 144, 132, 63, 51, 22, 45, 48, 55, 51, - 61, 61, 63, 59, 60, 61, 67, 63, 63, 72, 45, 68, 123, 123, 111, 108, - 120, 123, 115, 112, 118, 112, 110, 119, 118, 118, 122, 124, 116, 116, 104, 93, - 79, 87, 85, 87, 97, 91, 60, 103, 97, 87, 112, 84, 73, 99, 93, 91, - 100, 97, 96, 92, 92, 85, 88, 77, 93, 59, 53, 12, 40, 37, 55, 59, - 53, 59, 73, 73, 77, 89, 104, 91, 73, 91, 95, 89, 84, 89, 95, 92, - 99, 100, 99, 77, 84, 93, 88, 81, 80, 112, 123, 122, 114, 114, 115, 115, - 116, 116, 118, 112, 111, 110, 111, 111, 107, 95, 36, 84, 128, 95, 97, 96, - 130, 97, 103, 104, 119, 111, 102, 97, 114, 107, 106, 103, 99, 99, 100, 100, - 97, 93, 91, 13, 108, 97, 89, 80, 76, 75, 68, 67, 69, 65, 68, 67, - 73, 80, 83, 84, 95, 119, 139, 161, 173, 179, 238, 236, 233, 225, 221, 222, - 220, 228, 220, 213, 209, 198, 153, 126, 142, 139, 143, 114, 150, 140, 193, 204, - 202, 194, 197, 167, 146, 150, 134, 128, 122, 130, 150, 165, 170, 197, 174, 150, - 126, 142, 84, 143, 143, 53, 41, 46, 59, 77, 165, 114, 144, 106, 112, 110, - 135, 135, 143, 153, 144, 144, 173, 174, 166, 158, 146, 131, 44, 9, 5, 6, - 12, 12, 6, 13, 12, 14, 12, 21, 25, 22, 25, 24, 24, 25, 26, 44, - 37, 33, 131, 173, 173, 162, 95, 45, 18, 16, 18, 29, 32, 33, 34, 40, - 42, 42, 44, 48, 80, 60, 229, 224, 222, 111, 104, 112, 128, 123, 123, 122, - 124, 127, 139, 138, 140, 128, 122, 16, 9, 9, 17, 16, 18, 20, 20, 17, - 20, 25, 28, 32, 41, 41, 44, 46, 46, 45, 51, 55, 57, 63, 55, 51, - 63, 71, 60, 73, 80, 93, 127, 110, 51, 46, 56, 49, 44, 44, 42, 42, - 53, 45, 44, 33, 30, 30, 32, 28, 38, 36, 36, 36, 41, 33, 38, 34, - 65, 85, 115, 116, 111, 122, 108, 114, 104, 118, 115, 100, 80, 83, 80, 85, - 102, 103, 88, 80, 65, 49, 37, 32, 25, 18, 18, 16, 16, 13, 13, 14, - 16, 13, 16, 18, 18, 17, 16, 21, 28, 84, 89, 95, 102, 106, 103, 73, - 77, 46, 111, 110, 122, 96, 53, 51, 68, 45, 48, 89, 97, 112, 102, 106, - 115, 119, 116, 104, 88, 75, 65, 45, 44, 64, 30, 17, 17, 17, 17, 13, - 13, 14, 16, 10, 12, 13, 13, 13, 16, 44, 52, 79, 95, 89, 93, 84, - 56, 52, 0, 77, 115, 104, 76, 107, 77, 87, 84, 64, 53, 52, 59, 57, - 60, 97, 209, 221, 214, 100, 97, 110, 111, 107, 119, 136, 151, 157, 162, 139, - 154, 161, 157, 144, 138, 122, 20, 17, 17, 14, 14, 16, 17, 17, 16, 18, - 30, 28, 18, 22, 46, 63, 44, 48, 28, 33, 30, 53, 37, 77, 26, 17, - 100, 53, 44, 42, 42, 38, 44, 36, 32, 33, 30, 32, 34, 34, 41, 37, - 29, 30, 33, 32, 34, 36, 34, 36, 34, 36, 38, 41, 45, 57, 64, 69, - 95, 45, 96, 120, 120, 123, 187, 212, 199, 111, 104, 116, 130, 138, 146, 162, - 170, 165, 143, 120, 57, 53, 22, 36, 25, 34, 9, 9, 9, 6, 6, 8, - 6, 5, 5, 5, 5, 5, 6, 8, 9, 9, 14, 14, 16, 17, 22, 24, - 26, 26, 34, 36, 44, 48, 51, 56, 61, 63, 75, 99, 103, 93, 85, 93, - 79, 84, 89, 84, 79, 87, 83, 85, 96, 102, 108, 103, 99, 96, 93, 97, - 100, 97, 93, 89, 93, 96, 52, 61, 126, 139, 103, 92, 96, 67, 55, 46, - 52, 51, 57, 49, 59, 81, 84, 72, 88, 91, 87, 76, 91, 93, 100, 112, - 103, 103, 96, 95, 91, 88, 72, 60, 59, 63, 52, 53, 48, 49, 46, 53, - 51, 53, 46, 59, 59, 102, 55, 42, 41, 37, 33, 30, 29, 28, 24, 20, - 22, 21, 20, 18, 20, 20, 20, 24, 6, 29, 29, 21, 40, 63, 102, 73, - 77, 84, 110, 135, 171, 177, 190, 199, 190, 181, 169, 165, 155, 159, 165, 151, - 143, 146, 150, 165, 177, 179, 190, 197, 201, 199, 201, 193, 195, 198, 195, 177, - 178, 183, 182, 104, 95, 89, 146, 136, 174, 199, 205, 208, 205, 205, 208, 208, - 205, 213, 216, 210, 212, 208, 212, 208, 198, 205, 202, 161, 123, 150, 65, 56, - 76, 80, 92, 88, 144, 166, 162, 163, 126, 153, 108, 110, 115, 118, 118, 136, - 146, 171, 170, 167, 154, 143, 127, 40, 9, 6, 12, 18, 28, 25, 32, 18, - 26, 28, 30, 40, 42, 44, 48, 55, 57, 49, 34, 49, 36, 122, 171, 170, - 120, 89, 41, 20, 16, 29, 34, 33, 30, 33, 40, 45, 52, 57, 72, 72, - 72, 226, 225, 224, 111, 104, 112, 120, 118, 127, 135, 138, 139, 136, 139, 147, - 132, 128, 20, 12, 9, 20, 29, 37, 38, 45, 59, 153, 161, 177, 183, 185, - 182, 190, 199, 204, 198, 199, 197, 195, 199, 201, 199, 195, 197, 194, 191, 187, - 193, 189, 193, 134, 102, 59, 69, 75, 107, 150, 177, 189, 189, 177, 170, 159, - 158, 161, 148, 139, 122, 108, 118, 116, 110, 119, 124, 100, 142, 169, 189, 195, - 201, 197, 190, 189, 183, 151, 122, 93, 107, 107, 97, 111, 107, 116, 104, 116, - 103, 99, 88, 61, 45, 26, 87, 107, 102, 96, 96, 100, 103, 110, 102, 100, - 92, 95, 96, 91, 89, 106, 106, 106, 108, 103, 92, 84, 41, 115, 130, 103, - 100, 130, 127, 122, 114, 100, 127, 154, 165, 171, 165, 169, 170, 165, 157, 143, - 122, 106, 99, 73, 65, 30, 44, 116, 124, 102, 104, 93, 118, 104, 107, 99, - 96, 89, 99, 115, 104, 97, 95, 106, 91, 93, 106, 81, 56, 2, 100, 118, - 127, 131, 96, 127, 123, 106, 110, 88, 75, 73, 95, 99, 102, 225, 234, 226, - 111, 107, 118, 116, 118, 116, 120, 120, 127, 127, 143, 161, 162, 157, 143, 134, - 115, 22, 21, 20, 38, 49, 51, 56, 53, 55, 53, 61, 53, 34, 59, 112, - 111, 95, 99, 100, 65, 42, 38, 42, 48, 51, 37, 67, 87, 95, 95, 102, - 110, 108, 93, 85, 93, 110, 118, 106, 99, 92, 91, 83, 83, 51, 51, 45, - 41, 44, 53, 63, 63, 63, 69, 84, 91, 85, 89, 99, 42, 120, 122, 130, - 128, 201, 218, 190, 110, 107, 116, 131, 138, 148, 161, 173, 166, 165, 138, 67, - 57, 17, 18, 26, 29, 53, 104, 107, 114, 115, 116, 120, 123, 123, 119, 80, - 49, 104, 132, 147, 140, 139, 142, 151, 144, 139, 136, 142, 131, 143, 159, 151, - 147, 143, 128, 122, 126, 134, 187, 198, 208, 194, 173, 139, 108, 100, 95, 103, - 111, 148, 166, 181, 161, 163, 159, 153, 162, 142, 139, 134, 132, 104, 89, 88, - 85, 42, 123, 148, 167, 169, 151, 154, 119, 115, 120, 132, 110, 110, 135, 171, - 177, 185, 186, 186, 186, 185, 175, 183, 189, 201, 206, 201, 189, 179, 144, 134, - 103, 99, 93, 97, 77, 22, 52, 128, 148, 118, 130, 122, 127, 119, 97, 110, - 51, 59, 138, 151, 140, 143, 155, 151, 140, 161, 163, 161, 131, 128, 167, 170, - 193, 194, 189, 186, 182, 177, 174, 118, 63, 87, 85, 148, 183, 193, 201, 210, - 208, 209, 212, 213, 206, 208, 208, 197, 191, 190, 189, 175, 170, 167, 167, 162, - 157, 153, 166, 171, 178, 191, 193, 177, 179, 171, 162, 171, 171, 170, 187, 167, - 181, 169, 142, 187, 229, 225, 234, 212, 233, 206, 228, 221, 232, 220, 220, 214, - 212, 210, 210, 205, 220, 217, 169, 122, 161, 159, 166, 97, 111, 84, 108, 195, - 199, 234, 197, 110, 111, 114, 130, 134, 140, 128, 138, 154, 174, 171, 158, 148, - 143, 127, 37, 10, 6, 24, 25, 40, 42, 44, 45, 49, 64, 67, 76, 68, - 77, 76, 81, 77, 79, 61, 51, 30, 61, 128, 165, 104, 71, 26, 21, 18, - 32, 46, 46, 46, 41, 45, 81, 91, 87, 87, 73, 71, 230, 228, 224, 111, - 103, 114, 120, 136, 142, 142, 143, 142, 140, 136, 144, 131, 128, 21, 9, 9, - 24, 40, 49, 118, 64, 124, 165, 186, 191, 191, 194, 202, 206, 212, 213, 218, - 226, 229, 230, 233, 234, 236, 234, 240, 233, 241, 242, 242, 236, 230, 230, 225, - 225, 224, 216, 216, 218, 216, 217, 212, 208, 201, 195, 193, 194, 186, 175, 166, - 150, 146, 103, 106, 135, 163, 183, 199, 209, 218, 217, 216, 218, 216, 214, 210, - 205, 199, 181, 130, 111, 97, 87, 92, 96, 102, 108, 107, 107, 104, 81, 59, - 28, 107, 100, 114, 107, 110, 108, 96, 95, 96, 104, 104, 81, 73, 115, 120, - 127, 126, 120, 104, 97, 108, 81, 44, 126, 126, 124, 106, 135, 103, 114, 130, - 146, 186, 212, 222, 220, 217, 216, 210, 205, 201, 193, 190, 171, 162, 103, 67, - 37, 115, 120, 103, 102, 111, 115, 119, 102, 99, 112, 118, 107, 85, 111, 110, - 107, 107, 106, 104, 106, 102, 95, 64, 0, 88, 114, 120, 115, 91, 93, 112, - 111, 92, 103, 107, 59, 95, 119, 102, 233, 240, 226, 110, 102, 112, 130, 136, - 140, 144, 143, 142, 143, 147, 162, 159, 151, 144, 135, 122, 20, 20, 20, 48, - 49, 61, 77, 73, 75, 67, 64, 59, 44, 96, 123, 131, 128, 131, 123, 115, - 106, 119, 112, 95, 99, 110, 118, 107, 112, 107, 115, 124, 126, 106, 116, 111, - 132, 150, 146, 139, 153, 151, 150, 111, 97, 93, 85, 83, 73, 81, 76, 65, - 53, 75, 80, 75, 73, 77, 99, 52, 119, 130, 130, 128, 222, 225, 195, 107, - 104, 114, 130, 140, 147, 161, 171, 166, 148, 142, 67, 68, 75, 79, 81, 110, - 107, 119, 123, 126, 124, 131, 116, 122, 123, 120, 123, 57, 140, 140, 143, 153, - 148, 170, 182, 194, 197, 204, 201, 202, 209, 214, 212, 208, 209, 208, 206, 205, - 208, 212, 212, 213, 210, 205, 198, 198, 174, 170, 183, 162, 171, 190, 195, 206, - 204, 199, 205, 198, 186, 186, 197, 187, 169, 107, 84, 99, 52, 138, 163, 154, - 169, 173, 158, 169, 165, 150, 165, 165, 191, 194, 208, 206, 216, 209, 209, 208, - 209, 213, 212, 216, 221, 218, 220, 217, 214, 212, 195, 179, 143, 116, 108, 77, - 18, 140, 161, 153, 159, 161, 154, 159, 154, 132, 87, 45, 153, 193, 198, 212, - 204, 202, 208, 214, 220, 220, 214, 217, 216, 216, 210, 213, 198, 208, 208, 199, - 170, 189, 171, 87, 76, 118, 177, 193, 199, 206, 208, 212, 217, 221, 220, 218, - 209, 217, 217, 187, 139, 167, 194, 190, 189, 183, 169, 171, 161, 150, 136, 138, - 118, 136, 123, 131, 155, 158, 124, 163, 166, 143, 159, 167, 146, 135, 144, 187, - 208, 174, 161, 136, 136, 140, 142, 171, 204, 209, 214, 209, 204, 205, 210, 213, - 154, 124, 119, 143, 157, 167, 79, 80, 84, 114, 185, 206, 241, 216, 116, 110, - 127, 135, 142, 154, 161, 165, 169, 167, 159, 158, 148, 143, 128, 33, 9, 6, - 20, 34, 36, 53, 44, 55, 65, 61, 65, 71, 71, 71, 56, 77, 64, 68, - 63, 48, 36, 49, 64, 144, 89, 51, 29, 24, 16, 41, 37, 37, 37, 32, - 72, 92, 88, 77, 76, 67, 68, 237, 230, 226, 106, 103, 119, 127, 142, 139, - 144, 147, 146, 140, 136, 142, 130, 127, 21, 10, 10, 20, 33, 106, 41, 59, - 71, 114, 174, 182, 189, 198, 201, 204, 209, 214, 220, 225, 226, 229, 232, 233, - 233, 236, 237, 234, 240, 240, 240, 234, 228, 220, 214, 217, 217, 222, 224, 218, - 214, 214, 210, 195, 197, 183, 174, 189, 177, 175, 130, 92, 128, 147, 174, 194, - 209, 210, 208, 202, 214, 220, 218, 221, 218, 218, 214, 213, 209, 205, 198, 179, - 155, 112, 89, 83, 93, 91, 91, 95, 93, 96, 64, 37, 110, 104, 114, 104, - 99, 88, 85, 85, 87, 85, 87, 64, 87, 127, 110, 96, 124, 124, 116, 89, - 85, 79, 44, 130, 127, 136, 127, 138, 140, 132, 157, 212, 225, 233, 230, 222, - 216, 206, 194, 169, 155, 131, 108, 88, 80, 148, 80, 48, 124, 115, 120, 126, - 122, 119, 114, 104, 115, 107, 95, 73, 110, 118, 115, 97, 99, 108, 103, 97, - 107, 76, 59, 0, 93, 87, 93, 107, 112, 112, 119, 127, 123, 110, 108, 65, - 92, 116, 102, 238, 242, 237, 112, 104, 115, 136, 144, 151, 158, 158, 158, 161, - 158, 155, 151, 147, 147, 138, 128, 22, 20, 22, 45, 68, 67, 64, 73, 73, - 76, 67, 67, 46, 104, 130, 135, 134, 130, 135, 122, 123, 127, 136, 127, 107, - 93, 116, 159, 187, 193, 201, 209, 214, 216, 210, 214, 221, 224, 222, 222, 230, - 229, 221, 216, 220, 201, 206, 204, 208, 199, 174, 95, 55, 51, 71, 71, 77, - 72, 100, 55, 107, 120, 132, 139, 228, 233, 222, 103, 99, 114, 128, 139, 150, - 159, 170, 171, 165, 175, 111, 102, 97, 102, 104, 114, 116, 132, 138, 143, 131, - 132, 130, 142, 131, 126, 122, 122, 95, 138, 128, 126, 143, 193, 201, 202, 190, - 198, 210, 206, 216, 204, 202, 217, 204, 217, 217, 209, 205, 204, 198, 201, 202, - 206, 214, 205, 199, 157, 159, 190, 204, 205, 205, 198, 214, 195, 183, 150, 153, - 138, 128, 142, 131, 116, 73, 96, 53, 126, 140, 157, 150, 153, 166, 150, 144, - 157, 179, 187, 204, 206, 201, 202, 191, 201, 205, 209, 202, 201, 195, 189, 191, - 195, 199, 209, 212, 212, 212, 209, 202, 153, 110, 92, 18, 140, 161, 154, 153, - 150, 147, 148, 158, 151, 114, 61, 159, 194, 197, 190, 208, 214, 225, 225, 218, - 218, 222, 218, 206, 201, 206, 197, 193, 186, 174, 178, 170, 165, 148, 99, 87, - 142, 174, 191, 198, 204, 206, 218, 217, 193, 183, 170, 155, 157, 155, 140, 116, - 142, 165, 202, 191, 169, 157, 142, 139, 138, 136, 132, 127, 135, 135, 140, 142, - 150, 151, 155, 159, 134, 128, 155, 171, 146, 134, 130, 134, 127, 120, 119, 112, - 112, 112, 111, 114, 116, 119, 124, 130, 127, 120, 122, 118, 114, 135, 89, 103, - 112, 68, 72, 87, 99, 199, 210, 206, 191, 146, 114, 120, 140, 162, 165, 166, - 170, 170, 166, 159, 153, 147, 143, 130, 32, 9, 6, 24, 40, 34, 49, 51, - 63, 44, 76, 80, 60, 53, 60, 55, 65, 65, 64, 69, 49, 36, 21, 52, - 139, 85, 51, 24, 18, 18, 40, 40, 37, 36, 37, 80, 92, 84, 75, 71, - 67, 67, 241, 234, 230, 112, 103, 119, 130, 139, 142, 150, 147, 142, 134, 134, - 138, 131, 124, 18, 9, 10, 20, 38, 55, 52, 60, 114, 146, 181, 181, 135, - 167, 144, 148, 148, 146, 140, 139, 138, 136, 131, 132, 130, 127, 126, 134, 127, - 122, 122, 123, 116, 114, 115, 116, 171, 187, 220, 191, 185, 179, 165, 140, 115, - 108, 107, 108, 114, 107, 104, 122, 126, 182, 208, 209, 212, 218, 193, 177, 183, - 181, 167, 157, 147, 151, 150, 153, 154, 177, 191, 191, 194, 122, 99, 72, 87, - 85, 61, 76, 84, 93, 69, 34, 84, 104, 118, 97, 84, 92, 97, 85, 80, - 75, 92, 59, 81, 128, 126, 100, 104, 115, 93, 93, 89, 77, 55, 134, 136, - 120, 132, 138, 143, 151, 216, 236, 238, 232, 222, 197, 147, 120, 106, 99, 92, - 89, 77, 57, 60, 80, 72, 29, 81, 112, 110, 112, 103, 96, 91, 97, 95, - 111, 99, 56, 103, 114, 108, 99, 108, 103, 102, 96, 107, 79, 53, 0, 92, - 96, 111, 110, 110, 100, 102, 111, 110, 115, 81, 46, 97, 127, 91, 237, 242, - 238, 116, 106, 115, 142, 147, 155, 155, 165, 165, 170, 165, 165, 161, 150, 144, - 140, 128, 18, 17, 18, 45, 72, 69, 67, 72, 75, 91, 67, 67, 37, 99, - 126, 126, 128, 134, 132, 128, 132, 122, 119, 106, 67, 118, 136, 123, 179, 202, - 209, 216, 214, 220, 221, 225, 225, 229, 230, 234, 234, 230, 230, 229, 226, 228, - 226, 225, 222, 220, 195, 104, 61, 56, 72, 80, 71, 81, 96, 56, 79, 114, - 130, 128, 236, 238, 232, 106, 99, 114, 128, 139, 148, 161, 170, 174, 170, 146, - 177, 143, 148, 191, 204, 209, 210, 210, 212, 212, 209, 209, 212, 209, 204, 197, - 153, 119, 122, 126, 85, 139, 147, 146, 208, 217, 199, 214, 216, 216, 191, 175, - 155, 165, 186, 204, 202, 201, 185, 186, 165, 177, 174, 170, 169, 166, 153, 139, - 177, 204, 213, 212, 201, 198, 175, 154, 130, 123, 123, 120, 119, 122, 128, 80, - 73, 88, 49, 126, 142, 157, 165, 147, 154, 162, 131, 148, 178, 194, 212, 214, - 190, 179, 153, 151, 150, 155, 148, 147, 139, 135, 134, 136, 139, 157, 163, 166, - 177, 187, 198, 183, 123, 95, 24, 96, 163, 153, 150, 153, 147, 153, 153, 155, - 127, 57, 153, 191, 204, 208, 225, 241, 212, 224, 224, 222, 216, 202, 193, 205, - 198, 190, 182, 119, 107, 103, 95, 106, 103, 93, 88, 136, 179, 191, 206, 214, - 195, 183, 162, 138, 143, 134, 135, 136, 134, 140, 108, 118, 158, 171, 201, 181, - 158, 163, 139, 138, 130, 140, 139, 144, 143, 142, 144, 148, 150, 155, 148, 123, - 122, 136, 166, 147, 153, 127, 124, 123, 123, 122, 123, 119, 112, 112, 106, 112, - 107, 114, 111, 112, 114, 115, 127, 120, 81, 80, 122, 110, 45, 63, 73, 81, - 199, 213, 236, 195, 119, 111, 132, 147, 162, 169, 165, 167, 167, 167, 161, 155, - 150, 143, 123, 25, 8, 5, 18, 36, 42, 48, 52, 63, 45, 77, 75, 55, - 61, 51, 52, 64, 81, 79, 59, 44, 36, 24, 53, 124, 88, 72, 49, 25, - 20, 36, 30, 37, 25, 30, 88, 95, 77, 81, 73, 67, 60, 242, 236, 230, - 111, 104, 116, 131, 138, 143, 144, 138, 134, 131, 134, 134, 128, 120, 18, 10, - 8, 18, 33, 37, 55, 34, 71, 104, 136, 111, 147, 123, 111, 111, 115, 114, - 103, 112, 116, 114, 106, 107, 107, 108, 106, 106, 103, 106, 103, 103, 103, 103, - 102, 103, 107, 108, 108, 106, 103, 102, 102, 100, 102, 103, 106, 108, 111, 114, - 118, 123, 126, 198, 208, 206, 209, 190, 157, 131, 116, 111, 112, 111, 108, 112, - 115, 115, 118, 122, 139, 140, 170, 165, 102, 72, 95, 75, 87, 87, 81, 88, - 65, 37, 102, 114, 111, 97, 100, 92, 115, 85, 76, 73, 87, 56, 89, 128, - 120, 100, 88, 91, 84, 89, 88, 75, 49, 124, 136, 127, 150, 144, 153, 214, - 234, 242, 241, 222, 167, 97, 87, 79, 79, 79, 77, 68, 63, 49, 44, 61, - 72, 48, 85, 107, 114, 100, 95, 91, 91, 89, 93, 102, 91, 68, 104, 116, - 100, 100, 111, 111, 97, 103, 108, 93, 53, 4, 89, 107, 112, 103, 118, 127, - 120, 116, 114, 107, 80, 46, 89, 108, 88, 241, 245, 240, 116, 107, 115, 142, - 151, 159, 161, 169, 174, 175, 173, 167, 161, 151, 146, 138, 124, 16, 18, 21, - 44, 68, 64, 72, 71, 83, 80, 71, 61, 49, 92, 126, 127, 116, 126, 134, - 127, 130, 116, 103, 96, 68, 114, 132, 147, 132, 154, 174, 208, 218, 218, 220, - 225, 232, 232, 234, 224, 241, 241, 237, 226, 237, 238, 234, 212, 240, 240, 195, - 103, 55, 46, 80, 84, 71, 84, 95, 69, 63, 119, 130, 127, 237, 242, 236, - 107, 100, 112, 126, 139, 151, 158, 170, 175, 175, 169, 185, 190, 197, 204, 210, - 214, 213, 212, 212, 210, 212, 210, 210, 209, 206, 202, 201, 191, 144, 131, 130, - 128, 97, 123, 135, 151, 138, 131, 132, 122, 115, 112, 108, 114, 111, 118, 116, - 114, 112, 112, 111, 108, 111, 116, 115, 114, 151, 139, 174, 210, 208, 199, 202, - 154, 128, 124, 122, 119, 126, 126, 128, 138, 111, 69, 60, 73, 40, 127, 142, - 153, 155, 154, 151, 161, 157, 163, 193, 193, 182, 189, 174, 139, 118, 115, 114, - 114, 114, 114, 111, 110, 111, 112, 112, 116, 118, 122, 126, 132, 142, 181, 150, - 104, 22, 111, 162, 157, 153, 151, 148, 148, 146, 155, 127, 64, 92, 111, 175, - 194, 185, 174, 161, 138, 130, 119, 103, 97, 102, 97, 100, 96, 89, 85, 85, - 81, 81, 80, 80, 93, 89, 138, 181, 190, 193, 186, 144, 138, 122, 123, 138, - 142, 143, 138, 148, 134, 99, 102, 128, 147, 171, 214, 177, 162, 154, 147, 142, - 139, 143, 142, 140, 140, 144, 144, 139, 130, 154, 123, 88, 122, 142, 158, 159, - 169, 147, 155, 132, 150, 144, 139, 130, 126, 122, 123, 120, 115, 126, 116, 120, - 127, 122, 79, 72, 73, 102, 118, 22, 57, 79, 65, 195, 216, 242, 189, 127, - 115, 132, 155, 165, 169, 170, 171, 177, 169, 162, 155, 148, 140, 126, 29, 8, - 6, 18, 33, 36, 40, 48, 59, 41, 65, 69, 49, 71, 52, 41, 56, 42, - 46, 53, 41, 38, 29, 61, 119, 114, 87, 61, 46, 34, 36, 32, 33, 25, - 56, 87, 88, 81, 76, 72, 61, 59, 245, 237, 236, 107, 104, 116, 128, 138, - 143, 134, 132, 131, 140, 139, 139, 132, 126, 18, 9, 8, 20, 29, 37, 67, - 53, 36, 65, 103, 111, 118, 124, 111, 112, 99, 110, 115, 111, 110, 108, 112, - 114, 114, 114, 114, 111, 114, 115, 116, 118, 120, 122, 120, 116, 104, 103, 100, - 103, 103, 104, 103, 107, 112, 116, 120, 123, 126, 127, 124, 128, 120, 150, 210, - 186, 159, 138, 111, 127, 127, 126, 124, 124, 124, 124, 124, 123, 122, 120, 114, - 116, 120, 143, 108, 75, 87, 76, 79, 81, 84, 88, 67, 38, 100, 114, 114, - 110, 108, 87, 111, 88, 75, 84, 87, 52, 83, 119, 115, 104, 103, 99, 96, - 91, 88, 77, 55, 132, 140, 154, 135, 147, 202, 233, 244, 244, 234, 170, 114, - 80, 67, 57, 52, 49, 53, 51, 51, 38, 45, 51, 75, 49, 56, 118, 115, - 96, 93, 93, 97, 93, 88, 99, 96, 65, 103, 114, 99, 110, 112, 100, 97, - 104, 102, 103, 57, 1, 96, 102, 116, 100, 104, 100, 106, 112, 116, 97, 72, - 57, 80, 118, 91, 240, 246, 241, 114, 103, 115, 140, 154, 161, 167, 173, 182, - 183, 181, 170, 165, 154, 147, 136, 126, 16, 16, 20, 41, 69, 71, 68, 75, - 79, 84, 69, 61, 49, 93, 123, 124, 126, 131, 124, 130, 126, 115, 102, 106, - 63, 107, 139, 126, 146, 143, 144, 146, 157, 162, 157, 146, 144, 146, 146, 147, - 165, 158, 154, 169, 177, 151, 147, 161, 177, 142, 126, 96, 48, 51, 83, 83, - 77, 84, 87, 92, 42, 106, 120, 126, 240, 242, 238, 111, 100, 112, 127, 138, - 151, 161, 171, 178, 178, 174, 170, 142, 186, 197, 202, 210, 212, 212, 212, 210, - 210, 210, 209, 209, 209, 205, 201, 194, 191, 182, 177, 131, 127, 126, 95, 97, - 104, 112, 97, 110, 108, 110, 107, 108, 107, 112, 111, 111, 112, 112, 114, 114, - 114, 116, 119, 119, 148, 143, 167, 199, 191, 195, 140, 126, 126, 123, 132, 131, - 135, 132, 139, 138, 100, 57, 57, 79, 45, 124, 142, 150, 148, 155, 151, 139, - 147, 166, 166, 173, 154, 154, 124, 114, 122, 124, 123, 119, 120, 118, 122, 120, - 120, 120, 120, 118, 118, 119, 119, 118, 119, 131, 163, 111, 26, 102, 155, 153, - 157, 154, 153, 153, 151, 148, 135, 103, 84, 88, 88, 95, 93, 88, 95, 96, - 87, 87, 84, 88, 84, 89, 89, 87, 85, 87, 93, 116, 119, 122, 120, 97, - 91, 142, 206, 198, 163, 126, 126, 132, 139, 146, 140, 143, 142, 142, 153, 123, - 85, 72, 112, 139, 142, 154, 208, 175, 157, 158, 155, 150, 151, 151, 158, 155, - 158, 157, 154, 147, 123, 122, 114, 118, 131, 131, 147, 158, 159, 150, 139, 189, - 195, 157, 154, 139, 139, 139, 134, 140, 140, 140, 142, 138, 77, 67, 65, 84, - 93, 111, 14, 60, 56, 72, 197, 217, 244, 162, 132, 114, 134, 157, 165, 169, - 173, 174, 179, 174, 170, 153, 147, 139, 127, 28, 9, 6, 22, 30, 38, 49, - 42, 53, 46, 73, 72, 45, 65, 59, 42, 42, 84, 44, 52, 37, 38, 21, - 51, 116, 114, 80, 81, 64, 53, 55, 28, 28, 21, 60, 87, 81, 83, 67, - 88, 91, 61, 245, 237, 238, 112, 99, 118, 128, 139, 132, 143, 146, 147, 154, - 153, 146, 135, 130, 18, 9, 8, 20, 33, 38, 51, 41, 61, 32, 49, 103, - 72, 83, 97, 110, 128, 139, 116, 119, 122, 144, 123, 127, 131, 140, 128, 127, - 130, 144, 134, 136, 144, 146, 139, 139, 130, 122, 119, 119, 120, 120, 122, 126, - 131, 138, 140, 144, 146, 146, 134, 130, 107, 124, 139, 131, 108, 132, 132, 150, - 147, 136, 135, 136, 134, 135, 135, 135, 132, 132, 127, 126, 123, 119, 122, 77, - 72, 87, 75, 79, 84, 84, 68, 44, 95, 108, 108, 107, 110, 95, 115, 100, - 73, 80, 75, 48, 79, 119, 116, 89, 99, 77, 106, 104, 104, 93, 89, 135, - 163, 157, 157, 190, 225, 244, 246, 241, 218, 130, 87, 63, 38, 37, 44, 38, - 38, 42, 49, 45, 49, 46, 112, 52, 51, 116, 111, 95, 96, 97, 99, 97, - 93, 91, 93, 60, 99, 115, 102, 111, 104, 97, 97, 97, 106, 83, 55, 1, - 95, 102, 95, 103, 103, 106, 107, 114, 108, 96, 60, 68, 83, 115, 111, 245, - 248, 242, 120, 104, 115, 139, 151, 161, 169, 175, 183, 182, 181, 181, 167, 150, - 146, 138, 127, 16, 18, 18, 41, 67, 68, 71, 76, 85, 80, 69, 65, 48, - 81, 112, 126, 127, 126, 130, 131, 114, 93, 93, 84, 63, 114, 131, 127, 148, - 148, 131, 134, 136, 134, 134, 138, 134, 131, 134, 138, 136, 139, 140, 142, 140, - 143, 132, 135, 131, 131, 106, 72, 42, 40, 83, 80, 76, 81, 84, 88, 30, - 104, 130, 128, 241, 246, 241, 114, 103, 115, 131, 139, 151, 161, 171, 178, 181, - 178, 171, 173, 154, 150, 148, 146, 144, 142, 140, 140, 139, 138, 138, 139, 135, - 134, 132, 131, 134, 136, 138, 132, 136, 127, 128, 123, 126, 126, 123, 122, 120, - 120, 119, 118, 120, 120, 119, 119, 120, 123, 123, 123, 124, 126, 128, 130, 123, - 139, 136, 177, 208, 142, 130, 134, 138, 142, 142, 144, 142, 142, 143, 139, 89, - 55, 55, 75, 25, 119, 138, 147, 151, 144, 143, 140, 142, 138, 134, 127, 128, - 126, 116, 110, 104, 107, 119, 118, 128, 127, 127, 128, 131, 130, 131, 130, 131, - 131, 131, 128, 126, 123, 169, 122, 68, 71, 140, 161, 159, 150, 144, 147, 148, - 143, 143, 124, 61, 107, 103, 92, 95, 99, 99, 100, 97, 107, 104, 108, 111, - 114, 115, 116, 119, 115, 120, 128, 131, 134, 131, 111, 103, 135, 182, 175, 140, - 122, 139, 142, 147, 146, 147, 144, 144, 146, 147, 106, 67, 71, 103, 122, 127, - 143, 162, 193, 174, 147, 136, 163, 162, 162, 162, 166, 166, 169, 165, 162, 151, - 142, 123, 88, 124, 130, 134, 136, 148, 144, 140, 198, 187, 179, 175, 157, 147, - 147, 151, 140, 146, 151, 144, 134, 73, 63, 59, 75, 93, 99, 17, 51, 49, - 60, 206, 222, 230, 170, 122, 115, 135, 154, 165, 170, 171, 173, 178, 174, 169, - 157, 146, 142, 130, 30, 9, 9, 26, 38, 41, 46, 48, 51, 45, 69, 63, - 46, 51, 59, 55, 41, 42, 48, 40, 36, 32, 18, 49, 111, 96, 61, 63, - 64, 38, 92, 55, 26, 20, 71, 88, 75, 76, 67, 83, 72, 60, 245, 241, - 240, 111, 99, 115, 128, 142, 144, 157, 161, 166, 167, 161, 148, 138, 132, 18, - 9, 10, 16, 25, 36, 34, 51, 77, 52, 34, 46, 91, 89, 92, 171, 185, - 166, 118, 138, 165, 130, 134, 143, 155, 138, 139, 143, 154, 140, 144, 151, 146, - 150, 153, 151, 148, 143, 140, 139, 139, 143, 146, 147, 150, 153, 158, 158, 157, - 158, 151, 132, 139, 106, 104, 142, 136, 107, 76, 68, 83, 110, 127, 161, 138, - 140, 159, 142, 142, 140, 138, 136, 132, 123, 139, 95, 59, 80, 84, 81, 75, - 91, 71, 44, 51, 104, 110, 120, 110, 93, 115, 99, 67, 84, 69, 48, 106, - 108, 116, 104, 111, 107, 123, 143, 159, 166, 175, 201, 216, 222, 226, 229, 242, - 246, 248, 241, 178, 102, 53, 63, 53, 65, 55, 65, 61, 57, 56, 56, 56, - 60, 59, 67, 45, 92, 107, 99, 99, 102, 99, 104, 99, 93, 93, 56, 96, - 107, 99, 110, 103, 99, 100, 100, 107, 88, 53, 4, 91, 106, 108, 114, 111, - 111, 111, 111, 112, 85, 41, 53, 77, 112, 96, 244, 249, 245, 118, 104, 114, - 142, 154, 159, 167, 174, 179, 182, 181, 179, 170, 151, 144, 139, 127, 14, 16, - 22, 37, 61, 65, 71, 72, 80, 71, 72, 61, 46, 75, 104, 119, 132, 124, - 123, 116, 114, 91, 96, 89, 51, 116, 130, 135, 126, 127, 119, 120, 157, 158, - 131, 140, 143, 147, 148, 148, 142, 142, 144, 144, 142, 136, 138, 135, 132, 120, - 103, 52, 38, 40, 80, 84, 77, 85, 85, 87, 37, 103, 123, 131, 238, 246, - 244, 114, 104, 116, 131, 140, 151, 162, 173, 177, 179, 178, 165, 155, 126, 102, - 95, 112, 114, 127, 127, 128, 124, 124, 122, 120, 115, 115, 116, 116, 114, 115, - 112, 112, 111, 111, 108, 114, 124, 116, 116, 178, 127, 119, 120, 127, 126, 128, - 130, 128, 130, 131, 134, 134, 134, 134, 136, 138, 136, 144, 138, 139, 136, 134, - 139, 148, 153, 153, 153, 151, 150, 148, 146, 128, 72, 53, 46, 75, 44, 100, - 136, 136, 147, 146, 147, 146, 135, 127, 119, 111, 99, 95, 84, 81, 85, 87, - 96, 108, 114, 119, 130, 128, 135, 135, 136, 134, 136, 138, 140, 139, 136, 134, - 131, 140, 95, 34, 114, 140, 123, 124, 140, 144, 147, 143, 139, 123, 95, 123, - 108, 92, 118, 116, 157, 106, 114, 119, 120, 120, 123, 127, 126, 128, 127, 126, - 126, 136, 138, 140, 140, 134, 108, 126, 171, 142, 135, 146, 151, 155, 151, 158, - 159, 151, 157, 158, 150, 92, 65, 65, 79, 107, 126, 134, 146, 186, 191, 165, - 140, 140, 159, 171, 170, 170, 174, 174, 177, 177, 173, 155, 134, 104, 110, 102, - 128, 136, 136, 146, 151, 197, 198, 195, 165, 169, 155, 154, 154, 158, 155, 153, - 142, 142, 65, 57, 55, 64, 68, 75, 10, 46, 48, 53, 206, 224, 236, 142, - 123, 114, 134, 147, 162, 167, 169, 171, 178, 175, 173, 158, 150, 140, 131, 26, - 8, 6, 21, 38, 44, 44, 59, 63, 36, 68, 56, 48, 48, 49, 59, 42, - 38, 37, 36, 34, 32, 21, 46, 115, 130, 73, 72, 72, 73, 44, 55, 29, - 16, 68, 83, 75, 75, 67, 76, 67, 56, 248, 244, 240, 111, 100, 115, 130, - 146, 154, 166, 171, 170, 171, 163, 151, 138, 132, 14, 9, 8, 16, 33, 36, - 34, 40, 55, 53, 37, 36, 72, 79, 88, 199, 195, 132, 110, 120, 140, 138, - 158, 163, 143, 143, 153, 158, 148, 154, 150, 158, 157, 155, 167, 167, 170, 163, - 155, 153, 153, 159, 162, 161, 165, 165, 167, 169, 169, 167, 163, 146, 147, 148, - 142, 111, 64, 41, 29, 33, 44, 83, 118, 138, 178, 185, 185, 173, 177, 175, - 162, 142, 139, 131, 122, 111, 64, 59, 79, 77, 76, 77, 75, 59, 45, 96, - 97, 85, 108, 99, 100, 76, 76, 72, 57, 71, 103, 100, 142, 155, 183, 206, - 228, 232, 244, 245, 250, 249, 252, 252, 250, 250, 250, 250, 246, 222, 143, 99, - 68, 36, 57, 59, 60, 59, 59, 59, 60, 65, 63, 57, 60, 64, 57, 88, - 114, 108, 108, 110, 104, 111, 103, 91, 88, 59, 96, 111, 100, 103, 108, 103, - 118, 107, 97, 93, 51, 5, 96, 118, 106, 122, 118, 112, 118, 114, 106, 87, - 42, 56, 80, 110, 92, 244, 249, 245, 115, 104, 114, 139, 151, 158, 166, 171, - 175, 182, 181, 181, 173, 153, 146, 139, 128, 13, 18, 18, 37, 64, 67, 73, - 69, 69, 75, 68, 61, 57, 63, 100, 103, 107, 103, 104, 104, 87, 91, 93, - 89, 57, 87, 124, 127, 120, 119, 116, 115, 123, 106, 115, 179, 140, 132, 136, - 151, 154, 157, 157, 159, 159, 162, 153, 158, 127, 119, 104, 44, 34, 38, 71, - 69, 85, 89, 73, 84, 55, 96, 119, 131, 230, 248, 245, 114, 104, 115, 131, - 142, 151, 161, 173, 178, 179, 175, 165, 134, 76, 48, 45, 45, 83, 102, 115, - 114, 118, 116, 115, 115, 116, 115, 118, 119, 118, 114, 72, 83, 107, 104, 106, - 106, 107, 115, 116, 182, 183, 128, 112, 131, 142, 132, 132, 135, 135, 136, 139, - 140, 142, 143, 144, 144, 144, 138, 142, 135, 128, 150, 155, 158, 159, 154, 154, - 153, 148, 150, 143, 99, 52, 45, 45, 69, 46, 76, 130, 132, 132, 123, 107, - 88, 92, 93, 95, 77, 93, 92, 91, 91, 102, 95, 88, 84, 104, 123, 131, - 175, 178, 174, 155, 162, 174, 161, 161, 157, 146, 144, 132, 161, 118, 64, 57, - 122, 142, 127, 127, 128, 142, 144, 143, 110, 91, 92, 114, 119, 103, 118, 158, - 175, 115, 115, 124, 135, 131, 131, 134, 134, 132, 132, 134, 138, 144, 144, 146, - 144, 139, 106, 112, 143, 151, 154, 161, 161, 161, 158, 158, 158, 158, 157, 123, - 76, 68, 63, 63, 107, 111, 127, 135, 142, 194, 179, 148, 132, 143, 161, 169, - 175, 177, 181, 182, 182, 182, 175, 148, 107, 100, 102, 127, 135, 147, 142, 158, - 206, 204, 222, 171, 173, 161, 155, 158, 157, 158, 153, 139, 138, 59, 53, 52, - 45, 88, 87, 14, 20, 40, 46, 213, 222, 238, 144, 107, 116, 136, 151, 159, - 163, 166, 174, 177, 174, 170, 161, 143, 138, 128, 30, 8, 8, 22, 36, 37, - 44, 40, 49, 37, 73, 73, 46, 33, 33, 36, 33, 34, 30, 33, 34, 32, - 28, 51, 69, 91, 77, 17, 25, 21, 21, 20, 22, 14, 36, 61, 60, 51, - 51, 68, 59, 56, 248, 245, 241, 108, 100, 112, 128, 144, 157, 170, 173, 170, - 171, 165, 151, 138, 131, 14, 8, 9, 16, 18, 28, 30, 29, 34, 29, 32, - 41, 75, 88, 84, 202, 201, 175, 116, 119, 126, 143, 144, 151, 163, 161, 150, - 163, 154, 158, 157, 157, 163, 175, 178, 185, 190, 191, 186, 167, 165, 167, 174, - 173, 174, 174, 174, 175, 177, 174, 170, 151, 151, 150, 116, 64, 29, 30, 26, - 22, 30, 61, 91, 126, 182, 185, 199, 189, 183, 158, 178, 170, 157, 139, 126, - 123, 76, 49, 57, 73, 76, 75, 71, 72, 63, 56, 60, 67, 65, 69, 68, - 69, 69, 59, 88, 100, 130, 189, 222, 240, 245, 246, 249, 252, 255, 255, 255, - 253, 255, 255, 255, 253, 253, 250, 241, 182, 134, 103, 64, 33, 56, 53, 53, - 53, 57, 56, 59, 59, 64, 57, 64, 61, 59, 59, 76, 81, 79, 91, 85, - 88, 87, 85, 89, 56, 92, 99, 99, 87, 92, 92, 95, 89, 91, 77, 51, - 5, 89, 102, 106, 111, 106, 104, 104, 104, 92, 84, 37, 61, 75, 108, 87, - 244, 248, 244, 114, 100, 115, 140, 151, 159, 165, 167, 170, 179, 181, 181, 167, - 157, 146, 138, 126, 12, 17, 18, 37, 60, 60, 60, 69, 72, 71, 79, 73, - 69, 69, 76, 83, 76, 80, 84, 88, 81, 87, 93, 80, 52, 92, 119, 115, - 112, 112, 115, 115, 116, 112, 102, 183, 186, 132, 131, 138, 143, 153, 157, 161, - 161, 155, 159, 155, 132, 120, 104, 40, 33, 37, 57, 60, 71, 80, 65, 67, - 61, 67, 96, 127, 234, 246, 242, 119, 104, 115, 131, 143, 148, 159, 173, 179, - 178, 187, 154, 88, 55, 36, 29, 25, 46, 96, 140, 169, 174, 167, 126, 159, - 161, 158, 154, 128, 124, 119, 88, 63, 97, 103, 104, 103, 108, 112, 111, 170, - 193, 179, 120, 123, 139, 140, 142, 142, 144, 144, 146, 148, 148, 148, 148, 153, - 151, 148, 146, 147, 161, 159, 161, 158, 154, 142, 136, 128, 116, 114, 92, 57, - 44, 41, 45, 68, 46, 67, 77, 84, 77, 85, 92, 89, 99, 103, 106, 85, - 114, 108, 110, 104, 102, 100, 100, 100, 108, 126, 185, 194, 195, 187, 179, 179, - 181, 178, 171, 175, 165, 153, 144, 131, 134, 91, 34, 72, 142, 143, 123, 130, - 127, 124, 143, 127, 92, 85, 111, 118, 110, 122, 158, 183, 170, 112, 115, 134, - 136, 140, 140, 138, 142, 139, 138, 150, 155, 158, 155, 154, 148, 151, 159, 159, - 162, 162, 158, 155, 148, 142, 135, 131, 130, 110, 73, 59, 55, 64, 61, 97, - 100, 114, 120, 119, 159, 198, 174, 140, 132, 144, 161, 166, 174, 179, 182, 182, - 186, 183, 170, 132, 96, 114, 124, 138, 143, 142, 181, 221, 221, 197, 183, 178, - 165, 163, 166, 165, 155, 153, 138, 134, 55, 51, 48, 68, 85, 99, 5, 5, - 33, 46, 201, 224, 238, 134, 104, 114, 135, 151, 161, 165, 173, 174, 177, 169, - 162, 162, 144, 136, 130, 33, 6, 9, 22, 22, 38, 42, 36, 45, 40, 65, - 59, 32, 33, 32, 36, 32, 32, 30, 34, 33, 28, 26, 34, 22, 12, 10, - 10, 13, 10, 8, 10, 10, 14, 20, 21, 25, 32, 32, 38, 59, 57, 246, - 245, 240, 108, 99, 114, 134, 144, 157, 170, 177, 175, 167, 162, 148, 136, 126, - 13, 8, 8, 13, 12, 26, 29, 22, 24, 24, 22, 28, 41, 79, 84, 209, - 204, 201, 118, 112, 124, 140, 171, 170, 151, 162, 158, 159, 165, 169, 171, 175, - 178, 182, 186, 177, 161, 181, 190, 197, 189, 170, 186, 185, 183, 178, 190, 185, - 181, 185, 181, 187, 157, 153, 106, 49, 29, 22, 20, 18, 20, 52, 85, 122, - 189, 197, 170, 175, 191, 189, 167, 165, 169, 143, 131, 138, 85, 49, 49, 65, - 71, 69, 65, 67, 65, 71, 69, 65, 69, 69, 67, 72, 55, 99, 108, 154, - 225, 246, 248, 248, 250, 252, 253, 255, 255, 248, 241, 237, 237, 236, 232, 229, - 222, 218, 186, 148, 138, 110, 64, 60, 53, 59, 57, 57, 63, 60, 61, 63, - 63, 64, 65, 63, 61, 69, 69, 71, 72, 71, 73, 72, 72, 71, 71, 67, - 68, 59, 68, 68, 72, 56, 63, 61, 57, 49, 56, 8, 28, 51, 55, 59, - 57, 59, 56, 71, 63, 38, 21, 79, 63, 100, 95, 245, 248, 244, 115, 100, - 110, 136, 148, 159, 166, 171, 178, 179, 182, 173, 163, 154, 144, 136, 128, 13, - 18, 20, 44, 46, 51, 52, 49, 53, 49, 46, 53, 55, 52, 53, 65, 64, - 61, 61, 59, 60, 61, 59, 67, 76, 69, 77, 68, 65, 103, 108, 103, 107, - 111, 93, 162, 191, 179, 128, 131, 143, 143, 153, 157, 155, 155, 158, 157, 135, - 124, 95, 36, 30, 33, 56, 55, 60, 77, 76, 61, 59, 65, 95, 128, 241, - 248, 245, 119, 106, 116, 131, 142, 151, 162, 174, 178, 174, 165, 120, 56, 40, - 28, 36, 28, 44, 83, 157, 185, 135, 169, 161, 159, 163, 174, 148, 153, 127, - 123, 114, 59, 63, 87, 102, 103, 102, 115, 107, 139, 202, 199, 130, 119, 130, - 154, 148, 150, 150, 150, 151, 151, 151, 154, 154, 154, 158, 163, 166, 163, 163, - 161, 148, 118, 83, 63, 44, 40, 38, 41, 40, 36, 36, 40, 41, 63, 41, - 81, 72, 76, 77, 89, 110, 143, 197, 210, 220, 221, 218, 210, 199, 189, 131, - 120, 116, 116, 130, 195, 220, 173, 198, 191, 193, 190, 182, 186, 185, 178, 173, - 165, 151, 139, 155, 114, 40, 44, 95, 114, 120, 124, 124, 127, 132, 134, 110, - 81, 103, 122, 87, 112, 148, 191, 186, 123, 114, 123, 135, 147, 142, 142, 142, - 150, 153, 159, 163, 163, 163, 161, 159, 163, 162, 162, 158, 143, 114, 88, 63, - 52, 48, 45, 49, 51, 51, 56, 56, 48, 56, 57, 96, 104, 114, 122, 120, - 177, 190, 155, 128, 127, 150, 161, 167, 174, 178, 183, 187, 189, 183, 146, 103, - 93, 102, 120, 138, 139, 201, 220, 210, 210, 182, 171, 171, 170, 170, 167, 158, - 154, 144, 130, 49, 46, 46, 60, 84, 83, 20, 29, 20, 41, 193, 225, 221, - 132, 114, 115, 135, 150, 159, 166, 170, 174, 174, 159, 165, 155, 144, 139, 131, - 41, 9, 9, 12, 17, 18, 24, 46, 42, 37, 33, 36, 26, 21, 20, 18, - 16, 13, 13, 9, 13, 13, 24, 10, 32, 36, 37, 40, 44, 41, 46, 37, - 21, 12, 46, 89, 91, 69, 73, 72, 64, 59, 248, 245, 232, 110, 100, 112, - 132, 142, 157, 169, 177, 174, 169, 165, 148, 132, 130, 17, 9, 9, 10, 10, - 9, 17, 21, 22, 20, 21, 26, 36, 81, 87, 212, 213, 210, 120, 131, 120, - 136, 167, 170, 158, 161, 162, 171, 181, 181, 181, 179, 177, 185, 150, 93, 60, - 83, 157, 191, 191, 175, 167, 182, 183, 185, 183, 183, 186, 187, 190, 193, 161, - 158, 99, 45, 26, 22, 18, 18, 21, 53, 79, 115, 202, 204, 173, 195, 197, - 195, 173, 189, 179, 147, 135, 124, 106, 60, 45, 56, 51, 44, 37, 44, 41, - 41, 42, 45, 45, 45, 49, 63, 77, 119, 177, 241, 249, 252, 246, 253, 252, - 244, 226, 199, 175, 132, 119, 123, 116, 118, 123, 120, 116, 123, 139, 127, 134, - 126, 97, 73, 24, 21, 17, 16, 13, 13, 13, 10, 9, 12, 12, 6, 5, - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 4, 9, 10, 8, 2, - 2, 6, 5, 9, 9, 6, 26, 24, 26, 12, 28, 28, 26, 24, 29, 30, - 30, 72, 45, 44, 107, 93, 246, 249, 246, 119, 102, 111, 136, 150, 161, 167, - 177, 181, 181, 179, 169, 169, 150, 143, 139, 126, 10, 16, 21, 26, 17, 16, - 16, 17, 17, 18, 20, 21, 21, 26, 38, 79, 85, 100, 95, 103, 95, 99, - 93, 87, 84, 115, 122, 116, 81, 69, 71, 71, 97, 116, 107, 110, 202, 195, - 134, 130, 139, 143, 147, 150, 151, 159, 154, 154, 130, 124, 96, 34, 26, 32, - 48, 29, 44, 49, 52, 45, 59, 100, 93, 130, 241, 249, 245, 114, 103, 114, - 128, 140, 148, 162, 174, 178, 174, 153, 83, 45, 32, 32, 36, 25, 49, 96, - 191, 198, 169, 135, 166, 169, 158, 150, 138, 157, 131, 126, 118, 55, 57, 75, - 84, 93, 95, 114, 110, 127, 213, 205, 140, 119, 130, 144, 155, 155, 153, 153, - 151, 153, 153, 157, 158, 167, 171, 170, 166, 166, 158, 112, 68, 36, 30, 26, - 25, 26, 28, 29, 30, 33, 38, 41, 48, 73, 77, 73, 97, 107, 120, 158, - 202, 240, 245, 246, 248, 246, 248, 244, 244, 240, 240, 238, 236, 229, 233, 233, - 228, 214, 198, 191, 187, 187, 187, 186, 187, 185, 181, 178, 159, 148, 132, 132, - 85, 33, 59, 80, 95, 84, 96, 104, 103, 114, 116, 118, 119, 111, 85, 118, - 148, 202, 197, 134, 118, 120, 134, 142, 144, 144, 158, 163, 169, 169, 167, 165, - 169, 171, 167, 166, 162, 146, 103, 64, 37, 30, 28, 26, 29, 32, 34, 36, - 36, 38, 44, 60, 61, 60, 63, 63, 97, 102, 112, 138, 189, 177, 136, 124, - 138, 154, 162, 167, 175, 181, 186, 190, 190, 170, 120, 99, 107, 138, 142, 155, - 209, 212, 213, 214, 186, 175, 179, 171, 169, 169, 155, 155, 140, 135, 42, 38, - 38, 12, 10, 8, 115, 104, 97, 48, 185, 222, 224, 142, 114, 114, 132, 151, - 159, 165, 170, 171, 167, 167, 166, 146, 142, 139, 132, 48, 10, 9, 8, 24, - 22, 18, 20, 24, 30, 20, 29, 45, 56, 53, 65, 71, 76, 81, 80, 71, - 49, 14, 56, 64, 91, 96, 89, 79, 80, 76, 55, 26, 9, 76, 88, 84, - 81, 88, 87, 67, 65, 250, 240, 242, 110, 97, 110, 132, 142, 157, 169, 173, - 171, 166, 165, 148, 138, 132, 18, 9, 9, 14, 10, 16, 26, 26, 34, 4, - 29, 25, 79, 80, 95, 220, 217, 217, 135, 131, 136, 127, 161, 169, 163, 161, - 175, 185, 185, 185, 182, 175, 177, 162, 93, 34, 34, 60, 112, 181, 204, 185, - 163, 179, 186, 183, 186, 189, 190, 193, 194, 193, 166, 163, 108, 51, 34, 25, - 24, 22, 24, 56, 91, 110, 206, 209, 178, 177, 181, 198, 197, 194, 179, 159, - 140, 128, 132, 81, 42, 49, 59, 64, 60, 65, 91, 99, 107, 102, 110, 104, - 93, 108, 148, 193, 245, 248, 249, 250, 248, 228, 193, 150, 124, 119, 111, 104, - 112, 116, 116, 104, 122, 120, 118, 112, 131, 132, 134, 130, 126, 84, 92, 72, - 69, 72, 79, 73, 72, 71, 65, 65, 56, 60, 87, 111, 112, 128, 119, 112, - 130, 132, 116, 89, 83, 93, 142, 114, 116, 150, 146, 115, 107, 107, 131, 97, - 14, 0, 42, 81, 99, 65, 68, 64, 63, 63, 40, 52, 40, 71, 108, 107, - 103, 246, 249, 245, 118, 100, 115, 138, 151, 159, 167, 178, 178, 181, 175, 170, - 167, 148, 140, 138, 130, 12, 21, 21, 33, 63, 81, 87, 95, 103, 102, 100, - 89, 96, 97, 95, 111, 136, 127, 130, 114, 120, 123, 124, 127, 115, 128, 131, - 130, 108, 100, 87, 85, 77, 103, 104, 104, 209, 204, 151, 130, 135, 146, 142, - 146, 155, 157, 154, 153, 131, 120, 92, 32, 26, 33, 49, 61, 69, 85, 88, - 99, 99, 83, 120, 135, 241, 249, 246, 111, 102, 115, 131, 142, 151, 163, 175, - 175, 186, 142, 55, 38, 34, 37, 37, 22, 67, 97, 202, 204, 191, 135, 159, - 162, 162, 146, 135, 136, 131, 128, 118, 55, 51, 65, 92, 89, 93, 104, 102, - 118, 216, 213, 197, 123, 122, 136, 146, 158, 163, 154, 155, 155, 162, 162, 170, - 175, 171, 169, 167, 154, 95, 44, 30, 25, 26, 29, 33, 36, 36, 38, 38, - 44, 46, 49, 69, 60, 81, 99, 108, 147, 217, 241, 244, 246, 246, 248, 246, - 246, 246, 246, 245, 245, 242, 242, 240, 238, 238, 237, 234, 228, 175, 174, 191, - 193, 199, 182, 194, 187, 183, 181, 169, 154, 138, 146, 108, 38, 51, 72, 76, - 77, 95, 83, 75, 68, 61, 63, 73, 76, 87, 126, 143, 206, 210, 181, 116, - 116, 126, 139, 144, 154, 167, 169, 167, 170, 171, 169, 170, 173, 167, 162, 147, - 91, 40, 33, 26, 26, 28, 30, 29, 30, 32, 63, 59, 42, 46, 48, 57, - 80, 65, 68, 53, 76, 106, 114, 183, 179, 147, 124, 123, 139, 158, 165, 171, - 177, 183, 189, 190, 190, 147, 108, 102, 134, 134, 177, 216, 214, 228, 218, 186, - 178, 178, 170, 170, 169, 158, 157, 142, 132, 48, 42, 41, 32, 81, 91, 68, - 44, 55, 42, 140, 216, 226, 147, 115, 114, 132, 147, 159, 165, 170, 171, 165, - 166, 163, 146, 140, 139, 131, 56, 12, 10, 10, 24, 29, 38, 37, 38, 25, - 52, 81, 100, 92, 95, 100, 100, 95, 85, 95, 84, 53, 13, 55, 124, 107, - 108, 87, 89, 93, 64, 55, 25, 12, 85, 83, 67, 57, 61, 77, 67, 68, - 250, 242, 241, 110, 96, 111, 135, 140, 157, 170, 175, 173, 167, 163, 150, 139, - 132, 18, 10, 9, 12, 12, 22, 30, 20, 33, 10, 24, 29, 76, 91, 102, - 218, 221, 218, 136, 111, 118, 127, 139, 167, 166, 170, 182, 187, 187, 187, 186, - 179, 175, 126, 46, 29, 32, 37, 64, 158, 206, 193, 165, 166, 181, 195, 197, - 199, 201, 204, 204, 198, 193, 171, 139, 71, 36, 28, 26, 22, 42, 69, 95, - 104, 208, 214, 193, 175, 194, 198, 183, 195, 178, 173, 143, 134, 126, 104, 51, - 41, 57, 57, 91, 79, 84, 103, 107, 122, 97, 112, 119, 153, 229, 246, 248, - 248, 252, 236, 189, 142, 119, 115, 114, 115, 127, 77, 49, 44, 46, 57, 110, - 116, 124, 161, 183, 189, 181, 135, 132, 120, 99, 76, 100, 99, 80, 84, 77, - 79, 73, 92, 107, 72, 110, 134, 131, 131, 89, 118, 138, 142, 120, 115, 99, - 88, 131, 134, 143, 140, 143, 132, 134, 131, 119, 116, 81, 0, 96, 93, 97, - 106, 95, 92, 95, 79, 61, 60, 36, 108, 108, 103, 110, 249, 248, 245, 110, - 104, 116, 140, 150, 161, 169, 175, 177, 183, 173, 166, 165, 147, 140, 138, 126, - 12, 18, 40, 55, 85, 84, 92, 95, 97, 103, 100, 107, 96, 104, 139, 127, - 122, 120, 124, 130, 120, 120, 130, 162, 170, 210, 199, 153, 123, 107, 100, 103, - 100, 102, 103, 93, 213, 213, 185, 130, 134, 140, 144, 142, 146, 161, 151, 159, - 131, 122, 91, 32, 28, 44, 57, 87, 95, 104, 106, 111, 73, 100, 142, 174, - 242, 248, 242, 116, 104, 115, 132, 144, 151, 167, 175, 174, 167, 123, 49, 38, - 29, 37, 44, 26, 73, 108, 209, 209, 199, 163, 157, 158, 165, 147, 150, 139, - 132, 136, 122, 53, 49, 52, 80, 93, 97, 103, 108, 120, 217, 218, 205, 122, - 120, 128, 142, 153, 161, 162, 162, 174, 178, 177, 177, 178, 170, 169, 154, 99, - 37, 25, 25, 26, 32, 48, 41, 49, 48, 51, 52, 51, 68, 71, 84, 59, - 81, 99, 138, 230, 244, 244, 249, 248, 245, 236, 224, 204, 201, 190, 193, 197, - 208, 212, 214, 224, 226, 229, 226, 230, 217, 181, 206, 205, 216, 216, 205, 187, - 191, 185, 177, 158, 146, 139, 126, 72, 45, 57, 103, 104, 112, 124, 127, 118, - 111, 122, 128, 127, 130, 118, 158, 206, 213, 197, 118, 116, 124, 138, 148, 157, - 169, 173, 174, 173, 173, 171, 174, 173, 167, 144, 91, 36, 29, 25, 28, 30, - 37, 36, 40, 59, 28, 55, 88, 99, 85, 111, 103, 110, 124, 127, 111, 112, - 111, 115, 181, 186, 166, 126, 119, 132, 150, 162, 166, 174, 179, 186, 193, 197, - 186, 142, 99, 135, 144, 194, 216, 216, 216, 201, 193, 185, 177, 174, 175, 169, - 158, 157, 142, 135, 44, 41, 40, 63, 91, 91, 65, 56, 55, 64, 77, 210, - 216, 178, 115, 112, 127, 148, 158, 163, 169, 167, 166, 163, 153, 134, 140, 138, - 132, 83, 17, 10, 17, 30, 34, 37, 30, 37, 16, 81, 93, 100, 95, 88, - 114, 106, 110, 99, 102, 77, 51, 12, 71, 134, 128, 134, 127, 115, 88, 75, - 46, 24, 13, 79, 84, 65, 65, 61, 73, 63, 63, 248, 236, 242, 107, 95, - 111, 135, 143, 155, 170, 174, 177, 165, 163, 151, 140, 134, 20, 12, 10, 10, - 5, 25, 25, 13, 24, 10, 37, 18, 95, 91, 142, 225, 224, 221, 119, 111, - 118, 142, 142, 153, 166, 177, 186, 187, 187, 185, 182, 178, 169, 95, 33, 29, - 30, 36, 65, 130, 208, 204, 170, 159, 177, 183, 197, 202, 206, 206, 205, 205, - 198, 175, 163, 92, 44, 26, 28, 24, 57, 80, 96, 107, 201, 220, 206, 181, - 195, 197, 193, 195, 179, 178, 148, 139, 130, 123, 73, 42, 56, 53, 55, 71, - 104, 89, 96, 92, 102, 100, 119, 209, 248, 248, 249, 250, 225, 166, 122, 116, - 116, 120, 140, 127, 69, 41, 36, 42, 37, 56, 108, 187, 199, 191, 169, 175, - 175, 181, 136, 134, 126, 100, 59, 84, 83, 93, 79, 79, 79, 81, 73, 77, - 147, 143, 138, 131, 131, 126, 118, 124, 111, 97, 84, 108, 147, 144, 135, 134, - 128, 132, 132, 140, 130, 127, 95, 25, 104, 89, 79, 72, 71, 75, 79, 93, - 72, 55, 37, 107, 119, 110, 138, 249, 248, 244, 111, 104, 116, 139, 148, 158, - 167, 175, 178, 182, 170, 165, 148, 136, 139, 136, 126, 13, 24, 40, 72, 80, - 97, 97, 106, 89, 95, 100, 91, 60, 108, 138, 128, 120, 115, 124, 120, 124, - 126, 186, 229, 220, 220, 209, 178, 126, 110, 92, 111, 99, 97, 104, 91, 212, - 214, 201, 130, 131, 143, 150, 144, 144, 154, 146, 144, 131, 124, 81, 32, 28, - 53, 71, 92, 96, 104, 115, 93, 72, 99, 143, 179, 242, 246, 244, 123, 107, - 118, 132, 147, 157, 169, 175, 171, 162, 95, 48, 34, 33, 40, 45, 28, 80, - 119, 208, 212, 208, 130, 151, 155, 162, 134, 139, 144, 131, 135, 119, 52, 45, - 52, 72, 80, 89, 108, 110, 122, 222, 221, 209, 120, 119, 126, 139, 151, 159, - 165, 177, 178, 182, 182, 179, 175, 173, 158, 96, 40, 25, 28, 29, 36, 45, - 41, 55, 67, 76, 79, 75, 80, 76, 83, 89, 72, 91, 114, 193, 244, 246, - 246, 245, 237, 205, 181, 157, 155, 154, 158, 161, 165, 169, 174, 178, 181, 185, - 189, 199, 202, 210, 206, 206, 204, 202, 206, 208, 205, 197, 187, 178, 162, 153, - 135, 131, 95, 42, 63, 92, 100, 106, 120, 93, 124, 130, 122, 120, 114, 115, - 119, 153, 210, 217, 206, 118, 115, 124, 138, 147, 161, 169, 173, 173, 174, 173, - 175, 174, 171, 157, 106, 44, 30, 26, 30, 34, 40, 46, 51, 73, 64, 28, - 89, 112, 120, 118, 115, 111, 110, 107, 128, 132, 135, 72, 116, 166, 181, 182, - 140, 118, 126, 143, 155, 162, 170, 177, 183, 189, 204, 201, 193, 155, 142, 175, - 213, 217, 218, 222, 205, 201, 189, 189, 178, 175, 173, 161, 157, 146, 132, 44, - 38, 37, 85, 85, 108, 10, 45, 55, 40, 51, 190, 216, 199, 116, 110, 123, - 147, 157, 162, 166, 169, 163, 161, 143, 140, 140, 136, 131, 102, 20, 12, 17, - 28, 30, 33, 26, 44, 21, 84, 110, 103, 108, 106, 99, 103, 102, 106, 89, - 73, 55, 13, 77, 127, 163, 193, 163, 136, 104, 89, 49, 25, 13, 72, 79, - 69, 83, 63, 72, 60, 73, 245, 242, 241, 99, 96, 111, 132, 140, 154, 169, - 175, 174, 167, 165, 154, 143, 132, 16, 12, 9, 8, 13, 25, 25, 14, 16, - 13, 29, 17, 81, 96, 142, 229, 229, 224, 123, 123, 118, 127, 143, 162, 167, - 179, 185, 190, 190, 186, 182, 175, 150, 53, 29, 25, 30, 48, 53, 110, 199, - 210, 179, 157, 159, 179, 190, 199, 205, 206, 208, 208, 204, 198, 177, 130, 55, - 32, 26, 30, 59, 81, 96, 97, 197, 224, 218, 185, 179, 195, 183, 194, 179, - 174, 155, 143, 135, 138, 91, 40, 44, 53, 51, 69, 93, 103, 108, 102, 92, - 110, 144, 234, 244, 246, 248, 230, 151, 119, 119, 119, 126, 146, 147, 89, 56, - 34, 34, 41, 38, 60, 124, 205, 198, 170, 174, 179, 177, 183, 143, 138, 120, - 114, 91, 55, 72, 68, 75, 68, 79, 79, 68, 30, 138, 147, 124, 139, 132, - 139, 147, 143, 123, 96, 83, 103, 151, 139, 136, 130, 128, 132, 131, 127, 130, - 136, 57, 26, 71, 92, 85, 73, 73, 72, 76, 85, 57, 55, 34, 110, 119, - 106, 124, 249, 249, 246, 115, 106, 116, 139, 151, 157, 167, 175, 179, 183, 170, - 166, 142, 135, 136, 136, 124, 13, 24, 26, 44, 80, 95, 110, 106, 95, 110, - 93, 99, 64, 96, 142, 120, 132, 120, 112, 126, 122, 132, 212, 229, 216, 218, - 199, 157, 122, 95, 83, 93, 102, 99, 106, 95, 218, 216, 208, 132, 132, 142, - 146, 148, 151, 140, 151, 143, 128, 123, 71, 32, 28, 52, 77, 91, 96, 103, - 122, 97, 65, 97, 144, 175, 240, 245, 242, 126, 108, 120, 132, 144, 153, 169, - 174, 171, 151, 73, 41, 34, 37, 44, 51, 33, 81, 116, 209, 213, 236, 132, - 153, 153, 154, 146, 138, 135, 131, 130, 118, 46, 45, 46, 75, 76, 89, 99, - 112, 124, 226, 224, 216, 119, 116, 124, 136, 148, 158, 163, 175, 181, 181, 181, - 177, 173, 165, 122, 49, 26, 28, 28, 34, 38, 38, 51, 71, 87, 88, 81, - 84, 83, 85, 93, 77, 91, 92, 128, 228, 244, 244, 238, 224, 187, 151, 139, - 140, 146, 154, 163, 173, 181, 191, 201, 205, 208, 209, 208, 191, 195, 199, 202, - 204, 206, 209, 209, 213, 210, 191, 187, 173, 162, 154, 139, 138, 112, 48, 56, - 80, 93, 111, 115, 115, 116, 85, 110, 131, 126, 122, 140, 150, 213, 222, 212, - 119, 115, 124, 139, 147, 159, 169, 173, 174, 174, 178, 177, 173, 163, 123, 55, - 33, 25, 30, 38, 48, 48, 51, 56, 69, 60, 24, 99, 122, 122, 124, 119, - 131, 122, 123, 132, 134, 134, 80, 122, 162, 174, 185, 154, 122, 118, 134, 143, - 161, 167, 175, 179, 189, 195, 208, 206, 204, 194, 213, 216, 216, 225, 225, 206, - 195, 193, 187, 181, 179, 171, 161, 158, 146, 135, 40, 38, 37, 63, 85, 106, - 92, 38, 41, 40, 34, 108, 212, 206, 120, 108, 118, 136, 151, 159, 165, 167, - 166, 163, 154, 136, 142, 134, 135, 115, 26, 14, 18, 28, 29, 37, 29, 46, - 17, 60, 95, 102, 102, 96, 100, 99, 112, 96, 95, 75, 55, 16, 106, 153, - 214, 220, 230, 189, 138, 104, 64, 25, 13, 72, 79, 77, 65, 65, 67, 63, - 64, 245, 245, 234, 103, 95, 107, 127, 139, 153, 169, 175, 174, 167, 165, 154, - 143, 134, 17, 9, 14, 9, 12, 22, 28, 28, 26, 6, 25, 25, 80, 91, - 110, 230, 229, 228, 134, 124, 131, 127, 148, 146, 170, 175, 187, 182, 190, 187, - 177, 173, 128, 41, 28, 22, 32, 41, 56, 91, 190, 214, 195, 158, 154, 173, - 186, 195, 199, 205, 208, 209, 206, 202, 183, 163, 73, 34, 25, 29, 59, 79, - 95, 97, 179, 228, 224, 193, 194, 191, 195, 194, 185, 170, 157, 146, 135, 128, - 107, 48, 41, 53, 49, 64, 97, 110, 93, 93, 106, 104, 191, 240, 246, 248, - 238, 163, 122, 122, 126, 132, 150, 147, 153, 77, 52, 34, 24, 45, 45, 76, - 103, 210, 205, 173, 175, 179, 173, 173, 175, 140, 132, 127, 100, 55, 56, 67, - 71, 67, 68, 77, 75, 55, 142, 155, 130, 139, 134, 139, 147, 131, 118, 114, - 72, 119, 151, 143, 127, 131, 127, 136, 134, 132, 134, 128, 81, 0, 89, 87, - 76, 69, 76, 91, 96, 81, 55, 55, 30, 100, 116, 100, 123, 250, 248, 240, - 114, 104, 118, 138, 146, 162, 169, 173, 179, 181, 169, 162, 151, 142, 136, 135, - 120, 14, 25, 29, 51, 81, 102, 108, 104, 96, 106, 93, 92, 60, 106, 130, - 115, 123, 127, 122, 119, 119, 136, 225, 229, 233, 229, 191, 131, 107, 77, 75, - 95, 89, 96, 102, 97, 222, 221, 213, 136, 134, 146, 147, 151, 147, 142, 157, - 139, 124, 120, 60, 32, 28, 48, 77, 92, 92, 102, 112, 106, 59, 120, 140, - 146, 237, 244, 240, 124, 108, 119, 132, 143, 151, 170, 173, 169, 150, 56, 36, - 34, 38, 44, 46, 30, 80, 118, 210, 214, 212, 151, 143, 148, 148, 144, 138, - 136, 127, 126, 112, 42, 40, 42, 72, 80, 87, 103, 108, 118, 230, 226, 221, - 122, 115, 126, 138, 146, 157, 163, 175, 181, 181, 178, 167, 169, 144, 64, 29, - 28, 30, 34, 49, 48, 40, 87, 96, 95, 93, 92, 95, 92, 97, 92, 88, - 83, 108, 198, 225, 240, 229, 206, 167, 140, 130, 138, 148, 162, 174, 182, 190, - 198, 209, 218, 220, 222, 224, 222, 218, 205, 201, 204, 198, 197, 194, 214, 214, - 216, 194, 187, 170, 166, 157, 142, 138, 120, 61, 49, 71, 106, 106, 127, 114, - 110, 84, 107, 106, 120, 118, 108, 143, 210, 226, 218, 119, 116, 124, 139, 146, - 161, 167, 171, 174, 175, 177, 173, 169, 143, 63, 33, 29, 32, 41, 49, 52, - 53, 57, 60, 72, 64, 24, 102, 127, 134, 119, 120, 126, 111, 134, 139, 128, - 136, 72, 120, 151, 165, 166, 174, 130, 118, 120, 138, 155, 165, 171, 177, 183, - 194, 202, 209, 212, 210, 214, 217, 216, 229, 218, 202, 195, 194, 187, 181, 174, - 171, 161, 158, 144, 132, 36, 36, 33, 55, 118, 124, 84, 20, 36, 45, 41, - 60, 193, 206, 132, 108, 116, 131, 148, 157, 161, 165, 171, 173, 165, 154, 131, - 131, 134, 122, 41, 12, 16, 21, 25, 38, 30, 40, 37, 36, 91, 103, 103, - 107, 100, 100, 103, 102, 87, 77, 59, 26, 144, 191, 232, 214, 210, 206, 217, - 138, 89, 29, 13, 65, 69, 73, 59, 55, 61, 53, 61, 246, 245, 238, 107, - 97, 104, 122, 138, 155, 167, 177, 175, 167, 165, 154, 143, 131, 14, 10, 12, - 12, 10, 21, 25, 33, 30, 28, 22, 29, 72, 83, 99, 230, 230, 228, 134, - 110, 119, 130, 139, 143, 161, 173, 183, 189, 191, 186, 174, 165, 104, 33, 25, - 22, 32, 48, 61, 84, 178, 221, 205, 162, 150, 163, 181, 189, 198, 201, 205, - 208, 209, 206, 199, 182, 106, 38, 28, 29, 59, 80, 85, 89, 151, 226, 226, - 197, 179, 191, 197, 185, 174, 155, 150, 147, 140, 130, 120, 67, 41, 48, 46, - 64, 96, 111, 99, 97, 102, 93, 206, 244, 246, 245, 195, 130, 123, 130, 135, - 136, 151, 155, 155, 71, 34, 30, 28, 38, 44, 64, 104, 214, 212, 190, 173, - 178, 175, 173, 178, 144, 140, 127, 97, 46, 49, 69, 57, 65, 72, 81, 57, - 85, 134, 140, 131, 124, 123, 131, 128, 131, 115, 95, 55, 127, 151, 143, 127, - 135, 127, 135, 134, 132, 126, 126, 75, 0, 92, 84, 81, 69, 75, 64, 57, - 53, 64, 56, 32, 103, 114, 107, 119, 248, 246, 233, 110, 104, 119, 140, 150, - 161, 169, 175, 174, 182, 181, 170, 159, 144, 131, 131, 118, 14, 25, 34, 64, - 80, 96, 108, 108, 112, 111, 91, 97, 60, 100, 131, 115, 111, 123, 110, 123, - 119, 144, 226, 234, 233, 183, 132, 123, 84, 71, 75, 88, 87, 87, 96, 97, - 224, 225, 220, 139, 135, 144, 151, 165, 154, 153, 155, 128, 124, 116, 46, 29, - 29, 48, 77, 89, 93, 102, 112, 106, 52, 128, 142, 126, 233, 242, 238, 126, - 110, 119, 132, 146, 153, 170, 170, 165, 140, 49, 36, 36, 41, 41, 41, 34, - 76, 124, 214, 220, 210, 146, 140, 144, 150, 143, 139, 138, 136, 122, 108, 38, - 37, 40, 68, 71, 76, 100, 116, 116, 232, 232, 225, 122, 116, 126, 136, 146, - 157, 165, 170, 181, 178, 173, 169, 159, 107, 40, 28, 30, 33, 40, 41, 38, - 42, 72, 104, 130, 130, 127, 127, 119, 102, 79, 96, 108, 153, 228, 237, 222, - 187, 150, 130, 130, 142, 153, 163, 177, 183, 191, 199, 206, 216, 208, 165, 139, - 162, 204, 224, 222, 209, 201, 197, 205, 205, 216, 212, 212, 193, 185, 173, 167, - 155, 140, 136, 123, 85, 49, 59, 91, 100, 126, 124, 110, 80, 107, 108, 122, - 119, 96, 147, 217, 229, 222, 122, 115, 126, 139, 146, 161, 167, 173, 175, 177, - 177, 170, 158, 106, 41, 33, 32, 38, 51, 56, 59, 57, 61, 68, 77, 69, - 26, 108, 135, 131, 123, 115, 134, 131, 139, 143, 120, 134, 63, 123, 139, 155, - 165, 182, 165, 119, 111, 131, 148, 162, 169, 175, 182, 194, 194, 201, 208, 205, - 206, 220, 224, 220, 209, 201, 198, 193, 189, 179, 173, 171, 159, 157, 143, 131, - 32, 34, 34, 61, 85, 104, 63, 77, 49, 32, 29, 28, 114, 202, 161, 111, - 112, 124, 142, 151, 158, 165, 174, 169, 170, 159, 130, 127, 135, 130, 61, 16, - 12, 26, 22, 33, 32, 42, 34, 30, 84, 100, 107, 103, 107, 107, 106, 103, - 91, 80, 56, 26, 159, 209, 229, 222, 226, 209, 181, 140, 91, 26, 14, 65, - 81, 72, 73, 59, 63, 55, 80, 245, 246, 241, 112, 97, 103, 118, 143, 154, - 167, 174, 174, 170, 165, 154, 144, 134, 20, 13, 6, 12, 13, 18, 18, 30, - 30, 38, 13, 10, 72, 80, 97, 229, 232, 226, 120, 108, 119, 134, 128, 132, - 148, 166, 178, 186, 185, 182, 169, 154, 76, 29, 26, 20, 34, 63, 53, 80, - 158, 222, 213, 166, 146, 154, 174, 183, 191, 197, 199, 204, 209, 209, 202, 189, - 148, 52, 32, 25, 53, 76, 84, 91, 127, 224, 229, 202, 181, 191, 191, 182, - 163, 153, 146, 151, 147, 132, 131, 83, 40, 41, 48, 61, 95, 115, 95, 85, - 88, 102, 216, 238, 244, 242, 163, 124, 130, 136, 140, 144, 157, 158, 161, 65, - 36, 30, 21, 40, 44, 64, 96, 213, 218, 210, 177, 178, 178, 174, 181, 150, - 144, 124, 96, 40, 41, 55, 64, 57, 67, 69, 67, 72, 142, 138, 134, 128, - 128, 130, 127, 136, 114, 84, 72, 99, 136, 142, 131, 134, 134, 132, 135, 132, - 134, 123, 75, 21, 91, 83, 81, 65, 73, 83, 59, 59, 71, 49, 32, 112, - 115, 107, 123, 246, 244, 189, 106, 106, 118, 139, 146, 157, 163, 173, 174, 182, - 182, 177, 166, 150, 132, 131, 123, 16, 28, 37, 73, 72, 97, 102, 106, 111, - 99, 95, 87, 57, 114, 123, 114, 116, 120, 115, 123, 123, 151, 236, 237, 232, - 153, 123, 107, 75, 65, 73, 88, 84, 87, 100, 107, 222, 226, 220, 140, 134, - 148, 170, 170, 167, 162, 154, 124, 124, 116, 42, 30, 30, 49, 75, 89, 95, - 104, 102, 87, 52, 92, 139, 151, 233, 241, 240, 128, 108, 120, 131, 144, 154, - 171, 171, 166, 134, 48, 34, 36, 45, 45, 46, 37, 75, 123, 214, 220, 233, - 126, 138, 139, 147, 138, 143, 146, 138, 118, 97, 38, 37, 40, 72, 68, 73, - 99, 102, 119, 236, 233, 224, 120, 116, 127, 138, 147, 158, 166, 170, 179, 175, - 169, 166, 146, 65, 32, 30, 33, 38, 49, 53, 38, 88, 99, 127, 123, 123, - 126, 132, 120, 91, 79, 99, 124, 216, 233, 230, 205, 140, 118, 130, 140, 153, - 165, 175, 182, 189, 194, 204, 210, 210, 127, 95, 89, 99, 128, 170, 225, 217, - 210, 198, 206, 214, 217, 217, 205, 189, 185, 177, 169, 154, 140, 131, 127, 96, - 53, 67, 91, 102, 115, 115, 110, 79, 110, 114, 120, 119, 103, 143, 226, 230, - 225, 122, 116, 127, 139, 146, 159, 167, 171, 175, 178, 173, 165, 143, 71, 33, - 29, 37, 52, 57, 57, 61, 61, 65, 73, 83, 76, 29, 115, 142, 135, 140, - 138, 136, 139, 142, 118, 127, 132, 65, 123, 136, 155, 161, 175, 181, 128, 110, - 126, 142, 158, 166, 174, 181, 189, 195, 197, 198, 197, 197, 198, 205, 208, 208, - 205, 201, 194, 186, 181, 173, 170, 162, 158, 144, 126, 30, 32, 30, 73, 60, - 103, 64, 59, 60, 22, 32, 30, 63, 181, 186, 114, 111, 120, 131, 148, 159, - 166, 175, 171, 173, 159, 127, 128, 135, 131, 93, 20, 14, 16, 18, 24, 37, - 41, 41, 29, 67, 103, 103, 99, 106, 102, 106, 102, 89, 76, 63, 21, 177, - 217, 228, 225, 186, 165, 130, 100, 87, 24, 14, 42, 75, 79, 80, 53, 61, - 55, 67, 245, 246, 242, 112, 100, 100, 119, 136, 151, 166, 173, 174, 171, 161, - 151, 146, 131, 18, 14, 17, 12, 14, 29, 21, 21, 26, 33, 21, 22, 63, - 75, 89, 226, 237, 230, 132, 120, 119, 126, 127, 131, 138, 154, 167, 185, 185, - 170, 166, 147, 57, 29, 22, 20, 34, 53, 49, 69, 143, 218, 217, 182, 143, - 146, 166, 177, 183, 190, 193, 197, 202, 206, 204, 190, 177, 83, 32, 26, 52, - 67, 83, 88, 112, 220, 229, 205, 179, 190, 194, 174, 161, 139, 135, 138, 144, - 136, 132, 104, 49, 37, 48, 57, 92, 102, 93, 87, 100, 104, 217, 237, 245, - 225, 148, 128, 132, 140, 139, 155, 161, 165, 167, 61, 37, 33, 26, 40, 49, - 56, 91, 214, 221, 217, 179, 178, 182, 175, 178, 153, 142, 124, 95, 37, 37, - 52, 52, 49, 57, 63, 25, 75, 135, 131, 132, 134, 132, 127, 126, 143, 115, - 80, 64, 127, 148, 130, 135, 138, 143, 148, 142, 132, 130, 130, 55, 26, 68, - 79, 80, 64, 71, 60, 59, 61, 56, 55, 33, 107, 115, 107, 118, 245, 242, - 171, 103, 102, 116, 128, 139, 150, 159, 171, 174, 183, 181, 177, 166, 151, 131, - 132, 123, 17, 29, 29, 53, 71, 81, 102, 107, 107, 100, 95, 93, 55, 92, - 120, 111, 111, 111, 110, 114, 123, 181, 246, 237, 222, 135, 119, 100, 61, 64, - 69, 84, 80, 85, 97, 106, 225, 226, 220, 140, 135, 147, 171, 163, 169, 157, - 158, 123, 124, 115, 44, 30, 30, 52, 76, 88, 96, 95, 96, 88, 44, 92, - 142, 147, 232, 240, 238, 124, 110, 116, 131, 146, 155, 173, 167, 170, 132, 44, - 34, 36, 48, 40, 57, 37, 72, 114, 212, 220, 214, 139, 132, 136, 146, 140, - 140, 143, 136, 118, 91, 36, 34, 38, 67, 69, 76, 92, 107, 132, 237, 237, - 226, 120, 115, 126, 136, 147, 158, 166, 171, 177, 173, 169, 163, 118, 48, 32, - 32, 37, 42, 48, 41, 28, 96, 104, 130, 140, 134, 119, 136, 119, 107, 95, - 108, 167, 228, 230, 224, 175, 115, 123, 138, 148, 163, 174, 177, 186, 187, 197, - 202, 213, 178, 99, 71, 59, 63, 79, 127, 208, 224, 216, 205, 195, 216, 216, - 214, 213, 199, 186, 179, 167, 154, 138, 124, 127, 104, 56, 61, 85, 119, 106, - 114, 115, 75, 107, 112, 119, 112, 93, 148, 229, 236, 226, 123, 118, 126, 138, - 144, 159, 166, 169, 173, 173, 167, 162, 120, 53, 34, 33, 45, 56, 63, 63, - 63, 64, 71, 76, 77, 77, 28, 110, 138, 140, 140, 142, 136, 139, 140, 136, - 130, 128, 80, 128, 131, 142, 148, 159, 181, 146, 108, 116, 136, 153, 163, 171, - 178, 186, 193, 199, 199, 202, 201, 198, 197, 201, 210, 202, 202, 194, 187, 178, - 174, 173, 162, 157, 142, 128, 28, 30, 30, 53, 63, 102, 20, 22, 33, 45, - 25, 22, 32, 107, 181, 119, 107, 111, 122, 144, 157, 165, 170, 175, 169, 154, - 134, 130, 136, 131, 112, 28, 17, 21, 21, 21, 37, 28, 44, 29, 61, 91, - 99, 108, 106, 111, 103, 97, 83, 80, 65, 24, 175, 226, 234, 226, 173, 123, - 92, 87, 65, 20, 14, 30, 68, 76, 76, 59, 56, 52, 69, 244, 245, 238, - 110, 97, 103, 123, 138, 147, 166, 170, 174, 169, 162, 153, 147, 128, 20, 17, - 16, 12, 16, 24, 21, 12, 22, 24, 26, 32, 51, 83, 107, 229, 234, 232, - 132, 124, 128, 123, 124, 128, 142, 157, 153, 162, 165, 158, 161, 139, 40, 25, - 20, 20, 32, 37, 52, 68, 102, 210, 217, 191, 143, 140, 157, 169, 177, 179, - 183, 189, 197, 202, 202, 198, 189, 110, 37, 25, 52, 61, 80, 85, 97, 213, - 228, 212, 183, 189, 194, 174, 167, 155, 154, 150, 136, 138, 128, 114, 59, 40, - 44, 42, 79, 96, 87, 84, 99, 97, 217, 244, 245, 194, 139, 132, 136, 143, - 142, 154, 162, 167, 169, 61, 34, 32, 22, 37, 49, 71, 85, 210, 222, 222, - 179, 183, 181, 173, 181, 155, 142, 127, 89, 37, 32, 40, 46, 48, 55, 67, - 41, 104, 136, 142, 138, 131, 139, 127, 131, 116, 114, 110, 59, 120, 142, 148, - 146, 153, 146, 143, 136, 142, 135, 122, 83, 0, 80, 79, 65, 65, 63, 59, - 56, 59, 57, 59, 32, 89, 114, 99, 119, 241, 237, 187, 107, 107, 115, 119, - 132, 142, 157, 169, 177, 181, 183, 170, 165, 148, 132, 138, 119, 18, 29, 32, - 52, 68, 83, 99, 104, 96, 108, 95, 89, 52, 95, 110, 114, 102, 115, 114, - 111, 131, 213, 241, 240, 220, 132, 119, 81, 60, 57, 67, 69, 79, 73, 95, - 103, 221, 228, 216, 138, 136, 150, 174, 169, 162, 157, 153, 124, 123, 111, 38, - 29, 33, 51, 72, 88, 92, 102, 99, 99, 40, 110, 138, 127, 229, 238, 234, - 123, 110, 120, 132, 146, 159, 173, 170, 167, 127, 49, 37, 36, 33, 48, 53, - 33, 61, 103, 213, 218, 206, 135, 131, 135, 144, 143, 136, 140, 136, 118, 92, - 33, 30, 34, 56, 68, 81, 88, 103, 122, 237, 234, 230, 122, 115, 126, 138, - 147, 158, 167, 171, 177, 169, 165, 151, 85, 36, 34, 37, 38, 44, 53, 53, - 26, 75, 110, 131, 136, 130, 120, 130, 120, 99, 96, 97, 189, 222, 230, 214, - 139, 112, 127, 140, 154, 167, 171, 183, 189, 193, 198, 205, 214, 147, 76, 53, - 51, 57, 75, 110, 177, 226, 217, 213, 190, 216, 220, 221, 213, 204, 187, 179, - 169, 154, 140, 130, 130, 116, 63, 60, 80, 88, 104, 116, 107, 64, 104, 107, - 135, 106, 102, 144, 224, 237, 232, 120, 115, 124, 138, 144, 158, 167, 165, 173, - 171, 166, 151, 95, 44, 33, 40, 48, 64, 69, 79, 80, 79, 81, 81, 85, - 75, 28, 116, 138, 131, 136, 143, 138, 138, 135, 138, 123, 123, 46, 124, 128, - 135, 143, 157, 167, 165, 126, 107, 126, 146, 161, 169, 178, 183, 190, 195, 191, - 190, 194, 204, 201, 194, 198, 212, 204, 195, 189, 181, 174, 173, 162, 157, 146, - 128, 24, 29, 29, 53, 73, 83, 8, 8, 9, 8, 6, 17, 18, 48, 167, - 162, 107, 110, 122, 144, 155, 162, 165, 165, 159, 155, 127, 130, 130, 134, 126, - 63, 20, 13, 18, 20, 34, 34, 48, 30, 42, 79, 88, 91, 92, 87, 91, - 91, 87, 77, 67, 36, 181, 229, 238, 208, 154, 99, 91, 88, 61, 21, 14, - 21, 38, 42, 57, 49, 57, 49, 63, 242, 244, 234, 110, 97, 106, 122, 131, - 143, 165, 174, 171, 169, 161, 150, 147, 127, 20, 18, 20, 12, 14, 6, 20, - 22, 10, 25, 32, 25, 44, 75, 100, 228, 232, 229, 134, 110, 118, 132, 135, - 132, 144, 147, 144, 157, 157, 157, 157, 135, 41, 29, 25, 21, 32, 42, 56, - 71, 81, 199, 220, 201, 147, 138, 146, 162, 169, 171, 175, 182, 189, 195, 198, - 197, 190, 147, 52, 30, 45, 59, 73, 75, 85, 201, 229, 220, 185, 185, 194, - 181, 170, 166, 159, 155, 151, 136, 128, 127, 83, 42, 42, 41, 72, 100, 114, - 89, 93, 87, 198, 242, 245, 187, 135, 138, 144, 147, 143, 154, 165, 170, 170, - 60, 36, 29, 21, 32, 42, 61, 92, 221, 224, 224, 181, 182, 183, 177, 179, - 157, 143, 130, 91, 34, 32, 36, 42, 64, 46, 69, 41, 99, 111, 100, 108, - 108, 110, 108, 111, 107, 108, 80, 45, 118, 132, 135, 128, 140, 132, 124, 122, - 134, 130, 111, 55, 0, 80, 63, 63, 57, 68, 59, 75, 57, 65, 53, 30, - 91, 110, 106, 116, 244, 245, 225, 110, 106, 112, 120, 120, 142, 161, 171, 181, - 185, 175, 166, 154, 139, 134, 130, 116, 22, 30, 33, 49, 69, 80, 95, 99, - 104, 104, 91, 88, 52, 92, 114, 112, 104, 107, 111, 115, 143, 232, 241, 242, - 220, 135, 115, 71, 55, 51, 77, 61, 75, 77, 83, 92, 222, 222, 214, 134, - 135, 148, 166, 162, 161, 153, 144, 126, 122, 107, 38, 28, 32, 51, 64, 87, - 92, 96, 112, 97, 34, 122, 138, 132, 226, 237, 229, 127, 112, 120, 132, 147, - 161, 166, 167, 169, 139, 56, 37, 37, 46, 46, 55, 37, 57, 99, 213, 212, - 205, 127, 134, 135, 146, 138, 140, 136, 138, 119, 88, 30, 30, 30, 67, 63, - 67, 72, 97, 116, 236, 236, 229, 122, 114, 124, 135, 147, 158, 167, 174, 174, - 166, 163, 148, 68, 33, 33, 36, 42, 44, 44, 59, 25, 107, 116, 126, 115, - 108, 119, 122, 119, 106, 92, 97, 193, 222, 216, 201, 123, 114, 127, 140, 154, - 173, 173, 185, 190, 191, 199, 205, 209, 135, 71, 57, 52, 52, 64, 89, 153, - 228, 221, 214, 199, 213, 217, 218, 216, 210, 189, 183, 170, 159, 142, 132, 127, - 122, 83, 61, 69, 88, 96, 118, 104, 67, 96, 96, 93, 87, 85, 134, 213, - 234, 232, 123, 115, 124, 138, 143, 158, 165, 165, 173, 170, 161, 144, 76, 41, - 34, 44, 60, 76, 79, 77, 77, 81, 80, 80, 84, 83, 33, 110, 135, 136, - 144, 139, 138, 138, 144, 142, 112, 132, 37, 123, 122, 134, 135, 148, 151, 178, - 147, 108, 118, 142, 155, 166, 175, 183, 187, 189, 189, 186, 190, 195, 205, 206, - 193, 199, 204, 197, 191, 182, 175, 175, 163, 158, 146, 128, 22, 26, 28, 56, - 68, 87, 2, 1, 2, 8, 2, 4, 5, 17, 75, 177, 108, 107, 118, 134, - 148, 155, 163, 166, 157, 139, 126, 128, 128, 130, 131, 100, 33, 22, 22, 26, - 26, 29, 30, 33, 42, 56, 49, 52, 56, 55, 57, 56, 87, 79, 63, 28, - 166, 225, 240, 189, 119, 99, 91, 87, 59, 18, 14, 21, 26, 26, 29, 32, - 33, 57, 67, 245, 242, 240, 114, 92, 102, 120, 122, 140, 157, 165, 170, 167, - 162, 148, 144, 130, 21, 17, 8, 8, 10, 12, 14, 5, 5, 18, 26, 26, - 38, 73, 87, 225, 230, 232, 128, 104, 116, 127, 135, 146, 151, 147, 142, 146, - 142, 154, 151, 127, 46, 26, 26, 14, 36, 34, 56, 53, 75, 190, 221, 204, - 146, 134, 142, 154, 162, 166, 170, 177, 183, 191, 195, 194, 189, 167, 76, 37, - 36, 55, 65, 73, 85, 183, 230, 224, 189, 178, 194, 195, 169, 177, 170, 163, - 157, 151, 139, 128, 118, 57, 41, 40, 65, 97, 103, 81, 80, 92, 187, 229, - 245, 175, 132, 140, 147, 148, 143, 155, 173, 177, 177, 68, 42, 28, 25, 30, - 41, 76, 103, 226, 228, 226, 185, 183, 183, 178, 178, 159, 146, 132, 87, 33, - 34, 33, 36, 38, 38, 48, 57, 57, 87, 87, 89, 91, 97, 92, 85, 104, - 106, 53, 53, 45, 108, 97, 85, 79, 103, 83, 72, 68, 97, 67, 13, 42, - 61, 52, 37, 38, 46, 40, 37, 36, 52, 41, 33, 81, 96, 108, 128, 245, - 238, 234, 111, 110, 115, 120, 128, 143, 167, 170, 177, 182, 178, 167, 153, 128, - 135, 138, 114, 25, 34, 34, 42, 52, 63, 81, 92, 95, 92, 88, 87, 48, - 95, 103, 110, 100, 102, 104, 116, 161, 245, 248, 242, 201, 131, 115, 64, 52, - 49, 67, 75, 63, 69, 84, 89, 222, 228, 218, 138, 136, 147, 161, 163, 161, - 159, 126, 126, 122, 104, 33, 29, 29, 53, 56, 77, 88, 93, 96, 81, 51, - 71, 123, 127, 220, 233, 232, 127, 114, 122, 134, 150, 161, 171, 170, 169, 148, - 63, 40, 40, 44, 37, 46, 34, 75, 111, 208, 220, 217, 134, 131, 131, 140, - 139, 139, 135, 131, 118, 80, 30, 28, 30, 60, 48, 55, 69, 96, 111, 237, - 238, 232, 124, 116, 123, 131, 147, 161, 169, 174, 175, 166, 163, 146, 60, 36, - 37, 40, 63, 52, 46, 60, 36, 106, 114, 102, 115, 110, 107, 97, 111, 100, - 96, 96, 193, 220, 216, 175, 110, 115, 124, 136, 157, 171, 173, 178, 182, 191, - 195, 202, 214, 127, 71, 60, 56, 59, 55, 77, 148, 230, 225, 217, 198, 202, - 216, 216, 221, 216, 202, 183, 173, 162, 148, 140, 126, 127, 97, 65, 71, 73, - 80, 88, 72, 67, 67, 69, 71, 60, 79, 132, 201, 230, 233, 123, 115, 127, - 138, 142, 158, 166, 166, 170, 167, 159, 140, 72, 45, 36, 51, 73, 73, 77, - 71, 76, 80, 83, 84, 85, 77, 34, 77, 119, 139, 102, 111, 127, 134, 128, - 136, 123, 124, 37, 123, 120, 122, 120, 131, 139, 146, 165, 112, 107, 134, 150, - 163, 173, 179, 181, 183, 182, 186, 187, 190, 194, 204, 204, 194, 198, 195, 193, - 185, 177, 175, 165, 159, 147, 128, 24, 28, 28, 55, 63, 64, 36, 41, 46, - 40, 29, 45, 36, 13, 17, 138, 162, 115, 111, 118, 138, 148, 154, 158, 155, - 142, 131, 127, 122, 132, 134, 122, 59, 28, 13, 18, 21, 22, 20, 18, 24, - 25, 25, 32, 37, 42, 46, 48, 59, 75, 68, 30, 165, 220, 234, 177, 110, - 91, 89, 85, 57, 18, 10, 17, 24, 22, 24, 30, 30, 52, 55, 244, 241, - 236, 112, 103, 102, 120, 132, 134, 151, 162, 174, 169, 158, 147, 146, 123, 20, - 21, 21, 16, 16, 21, 20, 20, 21, 36, 20, 22, 38, 65, 97, 225, 232, - 228, 130, 115, 119, 128, 132, 146, 143, 143, 140, 143, 140, 153, 147, 123, 41, - 38, 25, 26, 49, 68, 63, 67, 69, 178, 216, 210, 150, 130, 139, 151, 158, - 161, 167, 171, 178, 186, 191, 193, 190, 179, 99, 41, 28, 42, 59, 69, 80, - 161, 230, 228, 193, 178, 186, 195, 191, 162, 178, 169, 165, 151, 151, 136, 130, - 92, 44, 44, 61, 71, 77, 71, 87, 87, 147, 234, 244, 174, 136, 142, 151, - 148, 148, 163, 175, 179, 182, 75, 49, 34, 28, 56, 73, 79, 114, 230, 230, - 229, 191, 183, 187, 181, 179, 163, 148, 130, 95, 29, 28, 29, 10, 9, 6, - 9, 10, 28, 28, 13, 12, 25, 28, 22, 21, 30, 36, 32, 53, 25, 25, - 14, 20, 24, 26, 8, 18, 25, 29, 5, 20, 67, 18, 45, 59, 65, 68, - 77, 77, 79, 77, 77, 36, 110, 104, 112, 138, 245, 245, 234, 111, 111, 118, - 122, 135, 148, 163, 167, 173, 175, 179, 166, 153, 131, 136, 134, 108, 29, 36, - 34, 44, 55, 56, 56, 59, 63, 75, 71, 59, 48, 89, 95, 88, 85, 97, - 112, 112, 208, 245, 248, 240, 177, 126, 112, 57, 49, 42, 41, 44, 49, 57, - 80, 87, 228, 230, 216, 135, 131, 131, 151, 159, 159, 151, 124, 118, 124, 96, - 30, 28, 32, 45, 57, 69, 75, 75, 81, 75, 41, 53, 120, 132, 214, 229, - 229, 127, 114, 123, 134, 150, 159, 171, 174, 173, 154, 81, 45, 40, 48, 34, - 40, 59, 89, 138, 214, 221, 204, 131, 127, 128, 135, 136, 140, 135, 128, 116, - 75, 28, 25, 28, 40, 42, 49, 75, 96, 96, 238, 241, 234, 122, 114, 122, - 132, 147, 161, 169, 177, 174, 163, 161, 146, 57, 34, 34, 44, 48, 63, 56, - 52, 26, 77, 87, 80, 80, 96, 95, 84, 83, 95, 93, 102, 183, 218, 204, - 151, 106, 115, 122, 136, 154, 171, 178, 185, 179, 191, 193, 195, 210, 147, 75, - 61, 45, 49, 61, 83, 151, 228, 225, 222, 199, 186, 212, 216, 217, 214, 205, - 183, 175, 165, 157, 143, 124, 126, 108, 69, 79, 71, 60, 60, 55, 46, 51, - 49, 59, 56, 67, 140, 195, 236, 230, 124, 118, 127, 139, 143, 157, 166, 166, - 173, 166, 159, 142, 71, 42, 41, 67, 44, 32, 28, 25, 33, 20, 17, 17, - 30, 10, 33, 59, 57, 69, 65, 57, 59, 59, 84, 114, 118, 99, 40, 122, - 93, 106, 100, 112, 116, 128, 155, 132, 104, 127, 146, 159, 169, 173, 175, 175, - 174, 177, 178, 182, 190, 197, 208, 195, 194, 201, 193, 186, 177, 175, 165, 161, - 148, 130, 22, 25, 26, 51, 53, 59, 115, 100, 80, 84, 84, 69, 80, 42, - 24, 64, 147, 106, 110, 112, 120, 138, 153, 150, 148, 139, 146, 146, 132, 123, - 131, 132, 108, 40, 32, 42, 51, 49, 42, 46, 57, 57, 73, 64, 69, 64, - 49, 52, 44, 52, 67, 34, 155, 222, 237, 198, 115, 92, 91, 81, 42, 16, - 14, 16, 40, 51, 60, 59, 56, 56, 65, 237, 237, 232, 106, 95, 110, 123, - 123, 127, 138, 158, 171, 162, 155, 144, 143, 126, 22, 21, 25, 8, 20, 21, - 21, 16, 28, 42, 24, 21, 68, 67, 119, 222, 229, 226, 128, 118, 127, 135, - 134, 143, 132, 153, 147, 147, 139, 151, 144, 116, 41, 37, 22, 36, 60, 69, - 67, 69, 71, 158, 221, 210, 155, 127, 136, 144, 154, 158, 165, 167, 173, 182, - 186, 190, 186, 183, 128, 46, 42, 44, 67, 72, 91, 148, 226, 229, 194, 177, - 182, 191, 194, 187, 162, 175, 170, 165, 155, 151, 134, 123, 64, 45, 46, 49, - 57, 76, 93, 85, 132, 225, 236, 178, 139, 148, 158, 146, 147, 162, 182, 185, - 186, 87, 40, 32, 20, 48, 75, 87, 157, 233, 232, 229, 189, 189, 185, 178, - 177, 165, 148, 132, 93, 34, 30, 32, 24, 42, 26, 44, 30, 97, 107, 100, - 88, 99, 102, 102, 91, 102, 100, 49, 30, 44, 123, 116, 100, 100, 118, 112, - 99, 95, 95, 89, 63, 26, 46, 108, 122, 126, 119, 124, 119, 120, 84, 73, - 32, 111, 115, 115, 183, 242, 245, 225, 110, 110, 115, 124, 138, 151, 159, 158, - 157, 166, 177, 167, 154, 136, 142, 143, 111, 34, 40, 42, 59, 69, 72, 52, - 71, 72, 69, 63, 75, 68, 80, 84, 95, 99, 103, 119, 174, 241, 246, 248, - 244, 154, 122, 107, 55, 46, 42, 46, 51, 63, 69, 85, 100, 226, 232, 218, - 132, 131, 134, 142, 147, 159, 148, 126, 122, 126, 106, 33, 29, 33, 49, 57, - 53, 55, 60, 49, 75, 33, 57, 104, 123, 209, 226, 222, 131, 115, 123, 134, - 146, 159, 166, 170, 173, 161, 103, 49, 42, 38, 44, 46, 73, 102, 194, 229, - 230, 213, 130, 127, 131, 134, 132, 143, 140, 124, 116, 64, 28, 25, 37, 59, - 61, 73, 81, 103, 116, 237, 237, 234, 123, 114, 126, 138, 148, 159, 170, 175, - 171, 163, 158, 147, 61, 38, 42, 63, 64, 77, 72, 45, 34, 37, 33, 46, - 36, 42, 37, 45, 33, 46, 37, 61, 173, 213, 206, 135, 104, 118, 123, 134, - 138, 169, 178, 175, 179, 185, 195, 201, 209, 162, 87, 67, 56, 71, 61, 104, - 159, 229, 226, 225, 198, 182, 202, 214, 214, 212, 206, 187, 182, 166, 165, 148, - 134, 127, 118, 77, 76, 88, 85, 85, 68, 30, 52, 128, 165, 128, 126, 174, - 210, 226, 230, 120, 118, 126, 139, 138, 154, 162, 169, 166, 166, 158, 144, 77, - 49, 46, 73, 77, 112, 132, 146, 142, 136, 144, 153, 140, 65, 32, 112, 153, - 151, 132, 142, 143, 126, 93, 59, 57, 81, 64, 24, 32, 40, 40, 38, 30, - 69, 142, 147, 110, 110, 140, 147, 157, 163, 159, 162, 158, 159, 153, 158, 159, - 191, 205, 213, 186, 198, 193, 185, 177, 174, 163, 159, 148, 126, 20, 22, 26, - 49, 48, 51, 115, 84, 103, 88, 91, 106, 52, 57, 25, 21, 144, 127, 114, - 111, 114, 115, 126, 138, 139, 150, 142, 142, 148, 136, 130, 139, 123, 92, 36, - 30, 17, 38, 46, 46, 68, 79, 100, 84, 83, 85, 73, 68, 72, 76, 69, - 49, 177, 236, 241, 195, 116, 89, 85, 65, 28, 14, 14, 17, 46, 57, 55, - 56, 52, 52, 69, 216, 230, 230, 100, 92, 111, 124, 123, 123, 134, 146, 167, - 162, 155, 143, 142, 127, 30, 26, 21, 18, 33, 45, 61, 67, 68, 75, 69, - 68, 53, 81, 190, 217, 225, 225, 126, 110, 119, 120, 135, 144, 126, 138, 146, - 148, 142, 147, 146, 122, 34, 30, 25, 32, 65, 60, 63, 59, 69, 136, 216, - 210, 165, 126, 134, 136, 147, 157, 162, 169, 170, 178, 183, 185, 182, 182, 155, - 72, 42, 38, 76, 80, 84, 128, 218, 228, 198, 174, 178, 187, 195, 195, 171, - 162, 175, 175, 166, 161, 147, 132, 107, 69, 67, 71, 96, 102, 100, 93, 112, - 210, 232, 182, 146, 153, 159, 146, 148, 165, 186, 191, 191, 136, 64, 34, 17, - 56, 81, 99, 185, 237, 234, 232, 187, 187, 186, 179, 175, 165, 147, 131, 87, - 32, 28, 30, 49, 44, 48, 51, 29, 114, 119, 106, 89, 87, 96, 85, 91, - 96, 103, 61, 24, 93, 124, 111, 114, 115, 111, 116, 108, 114, 107, 110, 65, - 22, 106, 124, 120, 120, 115, 116, 104, 112, 96, 88, 32, 116, 118, 116, 201, - 245, 245, 226, 110, 108, 114, 123, 140, 154, 165, 162, 147, 157, 158, 154, 131, - 131, 146, 146, 111, 37, 41, 41, 65, 51, 61, 71, 77, 83, 88, 88, 83, - 92, 104, 106, 114, 120, 130, 162, 218, 248, 248, 246, 221, 131, 123, 84, 48, - 41, 41, 55, 61, 64, 76, 81, 104, 226, 232, 225, 127, 126, 135, 122, 136, - 138, 138, 119, 127, 124, 111, 34, 29, 32, 56, 64, 81, 88, 85, 77, 77, - 25, 128, 124, 130, 194, 222, 217, 135, 116, 123, 134, 144, 154, 169, 171, 175, - 174, 142, 61, 49, 45, 49, 69, 87, 116, 204, 230, 228, 213, 130, 127, 130, - 127, 136, 135, 131, 122, 107, 42, 26, 22, 42, 67, 75, 79, 97, 97, 120, - 237, 238, 236, 124, 116, 126, 135, 147, 158, 169, 175, 169, 158, 154, 143, 72, - 45, 40, 60, 87, 96, 93, 79, 26, 42, 139, 148, 126, 131, 142, 139, 120, - 131, 139, 97, 159, 206, 201, 124, 106, 118, 124, 130, 131, 157, 162, 181, 175, - 174, 187, 197, 199, 201, 128, 79, 71, 77, 87, 150, 209, 230, 228, 226, 193, - 181, 197, 206, 208, 206, 205, 183, 181, 171, 162, 161, 142, 127, 127, 83, 96, - 112, 143, 134, 77, 44, 124, 178, 173, 178, 190, 193, 222, 229, 218, 122, 118, - 127, 138, 134, 150, 159, 167, 169, 163, 157, 143, 84, 55, 46, 73, 130, 153, - 155, 154, 159, 161, 159, 162, 163, 115, 41, 138, 162, 170, 170, 166, 166, 163, - 157, 140, 107, 97, 53, 67, 154, 161, 106, 120, 143, 114, 85, 161, 132, 102, - 122, 134, 140, 146, 148, 134, 135, 147, 107, 97, 112, 175, 204, 217, 194, 189, - 191, 182, 175, 173, 162, 155, 147, 122, 17, 24, 29, 53, 89, 102, 88, 84, - 60, 87, 84, 76, 37, 55, 25, 10, 127, 123, 100, 114, 111, 111, 110, 112, - 119, 140, 153, 146, 140, 147, 132, 127, 131, 116, 79, 29, 38, 44, 14, 38, - 63, 96, 84, 76, 76, 65, 63, 63, 69, 56, 44, 118, 212, 238, 237, 209, - 112, 85, 77, 51, 21, 13, 14, 14, 44, 57, 49, 48, 37, 55, 103, 236, - 228, 210, 106, 103, 114, 126, 130, 124, 130, 140, 157, 159, 150, 135, 142, 130, - 28, 28, 9, 59, 44, 53, 55, 68, 77, 69, 68, 52, 75, 96, 224, 221, - 224, 216, 127, 103, 112, 123, 146, 148, 132, 123, 132, 139, 136, 146, 144, 120, - 49, 26, 26, 33, 67, 67, 75, 52, 61, 112, 206, 206, 173, 126, 132, 134, - 146, 151, 161, 166, 163, 171, 177, 182, 178, 177, 167, 96, 46, 32, 67, 79, - 83, 108, 201, 225, 208, 173, 175, 186, 194, 197, 189, 161, 163, 177, 179, 167, - 159, 144, 136, 103, 96, 95, 97, 95, 89, 89, 96, 190, 237, 185, 147, 157, - 165, 144, 147, 178, 189, 194, 197, 166, 51, 37, 30, 69, 91, 108, 195, 237, - 236, 232, 189, 187, 181, 178, 175, 166, 147, 128, 81, 30, 29, 28, 42, 60, - 65, 48, 32, 106, 123, 112, 122, 112, 112, 123, 111, 102, 102, 61, 49, 118, - 128, 111, 110, 106, 96, 92, 107, 97, 87, 106, 48, 21, 107, 126, 115, 104, - 99, 106, 111, 115, 88, 80, 36, 116, 119, 122, 221, 244, 241, 222, 112, 110, - 115, 120, 132, 157, 166, 167, 166, 161, 144, 138, 127, 139, 144, 150, 116, 69, - 42, 42, 69, 53, 65, 80, 84, 79, 79, 83, 81, 99, 119, 127, 135, 128, - 157, 213, 245, 249, 248, 242, 163, 126, 119, 71, 46, 44, 38, 57, 63, 65, - 76, 81, 106, 230, 232, 224, 134, 134, 128, 138, 124, 118, 114, 119, 130, 119, - 110, 34, 33, 30, 60, 80, 95, 97, 89, 93, 69, 28, 122, 134, 127, 170, - 216, 218, 153, 118, 124, 135, 146, 153, 162, 170, 167, 175, 159, 118, 71, 73, - 79, 102, 126, 181, 206, 230, 222, 221, 128, 126, 130, 130, 130, 135, 123, 118, - 77, 30, 25, 24, 46, 65, 73, 91, 103, 107, 131, 236, 238, 234, 123, 119, - 127, 139, 148, 159, 169, 175, 166, 162, 157, 144, 83, 48, 42, 63, 92, 91, - 95, 93, 29, 157, 163, 159, 148, 148, 155, 148, 136, 146, 139, 107, 119, 195, - 190, 122, 108, 119, 123, 128, 132, 138, 170, 178, 185, 166, 181, 187, 197, 209, - 169, 104, 85, 97, 139, 159, 224, 228, 229, 226, 194, 175, 183, 194, 190, 193, - 194, 186, 181, 174, 170, 167, 157, 134, 127, 91, 108, 138, 147, 146, 69, 36, - 135, 179, 175, 189, 190, 193, 226, 233, 226, 118, 118, 127, 138, 131, 144, 161, - 171, 169, 162, 155, 146, 108, 63, 55, 80, 135, 154, 161, 158, 169, 162, 154, - 157, 161, 161, 41, 140, 167, 167, 158, 153, 153, 153, 153, 163, 131, 107, 28, - 148, 155, 153, 151, 150, 142, 132, 130, 77, 76, 75, 107, 134, 111, 119, 118, - 95, 77, 88, 79, 87, 103, 161, 205, 217, 201, 182, 191, 181, 177, 174, 162, - 155, 146, 115, 17, 24, 41, 59, 89, 111, 100, 55, 49, 56, 26, 55, 37, - 32, 18, 17, 119, 114, 77, 119, 112, 108, 110, 110, 107, 116, 139, 155, 144, - 138, 144, 128, 136, 127, 114, 71, 46, 42, 41, 36, 61, 93, 71, 69, 65, - 60, 63, 59, 59, 76, 120, 182, 232, 238, 234, 193, 110, 85, 59, 26, 16, - 12, 13, 14, 30, 53, 48, 34, 37, 72, 191, 234, 229, 216, 111, 103, 114, - 128, 130, 143, 131, 127, 143, 154, 153, 138, 143, 118, 30, 26, 13, 45, 48, - 44, 72, 51, 52, 55, 51, 51, 76, 150, 214, 218, 224, 214, 127, 122, 111, - 122, 136, 136, 146, 135, 122, 123, 131, 135, 144, 122, 56, 24, 21, 34, 69, - 83, 57, 56, 64, 93, 193, 206, 171, 130, 123, 130, 143, 148, 157, 163, 162, - 163, 167, 171, 177, 171, 170, 124, 56, 53, 72, 72, 87, 96, 159, 224, 209, - 171, 171, 182, 194, 195, 195, 179, 155, 162, 177, 174, 167, 157, 140, 134, 126, - 119, 99, 89, 93, 91, 83, 128, 224, 197, 153, 157, 171, 148, 147, 183, 194, - 201, 202, 186, 81, 42, 32, 38, 95, 116, 212, 238, 237, 234, 186, 186, 181, - 175, 178, 169, 146, 120, 53, 29, 28, 18, 46, 46, 56, 55, 38, 67, 88, - 120, 80, 114, 108, 106, 104, 110, 99, 64, 48, 80, 127, 114, 120, 92, 95, - 108, 89, 96, 97, 96, 53, 18, 106, 119, 104, 110, 116, 110, 112, 93, 84, - 84, 46, 103, 108, 130, 229, 241, 241, 220, 115, 112, 118, 119, 130, 151, 165, - 171, 165, 159, 159, 154, 138, 142, 150, 150, 123, 99, 44, 46, 68, 48, 60, - 63, 69, 72, 73, 72, 97, 99, 128, 135, 130, 159, 202, 240, 246, 250, 248, - 229, 136, 123, 112, 60, 44, 38, 42, 56, 60, 68, 79, 92, 135, 217, 225, - 224, 135, 120, 126, 130, 120, 124, 116, 116, 126, 127, 110, 34, 29, 42, 48, - 52, 96, 102, 89, 85, 81, 22, 127, 132, 124, 138, 202, 216, 185, 122, 120, - 135, 142, 151, 158, 169, 169, 178, 178, 161, 124, 127, 144, 171, 195, 209, 205, - 233, 217, 216, 130, 128, 130, 130, 136, 131, 120, 97, 37, 25, 24, 32, 60, - 61, 69, 93, 100, 108, 132, 233, 240, 232, 123, 115, 124, 134, 148, 159, 169, - 173, 167, 158, 154, 146, 119, 55, 44, 71, 84, 89, 89, 83, 29, 166, 166, - 177, 165, 161, 157, 139, 138, 153, 157, 130, 93, 155, 193, 131, 103, 119, 124, - 128, 135, 131, 158, 162, 174, 162, 173, 179, 193, 199, 209, 178, 151, 171, 194, - 221, 226, 228, 225, 226, 189, 173, 173, 182, 185, 182, 187, 185, 186, 179, 170, - 163, 166, 150, 131, 95, 115, 132, 153, 138, 63, 38, 115, 169, 183, 179, 190, - 202, 232, 229, 228, 120, 116, 127, 140, 135, 148, 161, 170, 169, 163, 154, 146, - 128, 73, 61, 83, 139, 154, 163, 167, 167, 169, 162, 153, 162, 120, 55, 131, - 162, 167, 158, 158, 153, 151, 151, 158, 139, 118, 42, 161, 159, 150, 146, 142, - 140, 130, 124, 123, 110, 108, 99, 96, 96, 95, 84, 81, 79, 76, 72, 92, - 106, 170, 213, 224, 202, 178, 189, 183, 177, 174, 163, 153, 144, 107, 16, 25, - 40, 85, 96, 100, 99, 48, 57, 63, 45, 40, 79, 40, 18, 12, 122, 107, - 80, 69, 103, 118, 111, 111, 110, 108, 119, 139, 147, 146, 144, 139, 122, 131, - 130, 111, 89, 75, 73, 64, 83, 83, 102, 73, 63, 61, 64, 79, 120, 177, - 216, 234, 241, 237, 216, 169, 95, 69, 37, 18, 13, 13, 14, 20, 38, 46, - 46, 40, 52, 115, 218, 224, 230, 214, 99, 97, 116, 126, 127, 143, 122, 124, - 130, 148, 143, 135, 140, 119, 34, 30, 40, 77, 75, 45, 56, 45, 61, 45, - 49, 45, 75, 162, 210, 214, 214, 197, 127, 108, 116, 132, 146, 140, 150, 151, - 139, 120, 119, 134, 139, 123, 49, 37, 37, 41, 69, 75, 67, 52, 57, 64, - 187, 208, 170, 120, 128, 128, 142, 146, 154, 162, 166, 155, 155, 159, 161, 169, - 169, 143, 88, 57, 42, 57, 81, 84, 135, 214, 217, 171, 169, 179, 189, 193, - 195, 194, 183, 153, 162, 181, 174, 162, 155, 144, 136, 139, 139, 112, 92, 84, - 87, 97, 193, 221, 169, 159, 171, 147, 150, 187, 198, 206, 208, 201, 148, 77, - 37, 40, 103, 159, 222, 237, 238, 234, 191, 187, 177, 175, 177, 166, 139, 108, - 34, 28, 26, 22, 55, 48, 53, 56, 41, 46, 119, 124, 114, 118, 112, 107, - 107, 104, 95, 64, 53, 83, 130, 97, 104, 93, 112, 99, 89, 99, 96, 95, - 60, 24, 107, 120, 100, 97, 99, 87, 100, 89, 80, 65, 69, 104, 118, 178, - 230, 246, 240, 217, 116, 115, 120, 112, 124, 146, 159, 166, 171, 167, 162, 157, - 147, 132, 138, 154, 140, 108, 48, 48, 53, 60, 61, 79, 83, 77, 73, 79, - 92, 111, 134, 132, 147, 194, 238, 245, 249, 249, 248, 173, 124, 123, 99, 48, - 40, 26, 44, 52, 61, 75, 79, 91, 187, 214, 221, 212, 131, 123, 128, 134, - 123, 124, 126, 111, 118, 126, 115, 40, 32, 32, 46, 80, 93, 102, 80, 83, - 81, 18, 123, 132, 124, 126, 148, 204, 199, 128, 122, 130, 138, 147, 148, 157, - 154, 181, 183, 182, 174, 189, 201, 205, 212, 210, 218, 209, 217, 169, 130, 130, - 136, 140, 135, 126, 120, 46, 28, 24, 22, 42, 56, 64, 72, 92, 99, 108, - 190, 234, 237, 233, 124, 111, 124, 132, 147, 155, 167, 169, 170, 165, 157, 151, - 144, 72, 52, 53, 85, 91, 89, 87, 37, 119, 170, 177, 171, 167, 177, 162, - 157, 155, 148, 155, 87, 107, 190, 147, 107, 110, 123, 127, 131, 132, 138, 163, - 165, 161, 169, 174, 186, 191, 208, 216, 212, 220, 221, 226, 224, 224, 229, 212, - 189, 167, 170, 150, 171, 177, 185, 185, 183, 185, 175, 173, 166, 166, 146, 123, - 116, 139, 151, 87, 57, 32, 104, 169, 170, 173, 175, 187, 229, 238, 228, 122, - 116, 126, 138, 132, 154, 163, 169, 166, 165, 158, 148, 139, 92, 67, 97, 132, - 153, 166, 166, 169, 170, 170, 169, 151, 132, 52, 124, 163, 165, 154, 155, 151, - 153, 153, 153, 128, 118, 48, 120, 161, 139, 140, 143, 140, 128, 119, 127, 126, - 115, 107, 91, 91, 83, 80, 79, 75, 77, 88, 106, 112, 187, 218, 226, 191, - 175, 186, 182, 177, 174, 165, 150, 139, 67, 16, 25, 41, 102, 96, 100, 106, - 69, 42, 56, 59, 33, 33, 38, 20, 10, 104, 92, 72, 61, 52, 81, 119, - 115, 111, 108, 106, 114, 140, 151, 148, 151, 142, 124, 123, 118, 151, 123, 111, - 107, 112, 116, 123, 123, 124, 123, 146, 183, 213, 229, 240, 238, 236, 224, 193, - 112, 80, 42, 20, 13, 10, 12, 16, 30, 41, 33, 44, 44, 123, 186, 233, - 226, 229, 221, 114, 97, 108, 120, 135, 140, 127, 132, 124, 135, 136, 136, 138, - 127, 92, 65, 33, 68, 79, 77, 56, 55, 60, 71, 48, 60, 95, 183, 208, - 212, 217, 159, 112, 116, 122, 130, 135, 148, 148, 150, 148, 138, 115, 122, 136, - 128, 99, 51, 45, 45, 75, 56, 60, 52, 56, 55, 165, 206, 170, 118, 126, - 128, 140, 148, 154, 159, 163, 151, 151, 146, 146, 154, 162, 153, 104, 59, 30, - 53, 73, 85, 114, 198, 216, 179, 166, 177, 186, 189, 193, 194, 195, 183, 157, - 162, 175, 171, 162, 155, 150, 139, 139, 136, 108, 84, 91, 92, 142, 229, 182, - 162, 169, 151, 187, 193, 206, 212, 210, 212, 194, 118, 49, 55, 114, 190, 234, - 237, 238, 229, 187, 186, 183, 177, 174, 154, 139, 88, 29, 26, 26, 36, 52, - 56, 45, 60, 51, 44, 108, 123, 112, 118, 107, 107, 115, 104, 103, 71, 55, - 85, 122, 110, 104, 93, 102, 84, 97, 92, 95, 97, 59, 14, 112, 119, 92, - 100, 92, 96, 81, 65, 69, 99, 89, 103, 124, 220, 238, 234, 242, 206, 118, - 120, 122, 123, 116, 135, 157, 165, 167, 169, 166, 162, 158, 142, 146, 140, 159, - 123, 106, 89, 85, 95, 97, 99, 100, 108, 108, 104, 103, 122, 138, 131, 191, - 234, 238, 242, 248, 245, 224, 130, 126, 119, 69, 45, 38, 34, 48, 56, 69, - 75, 85, 186, 214, 214, 222, 204, 118, 132, 139, 130, 136, 136, 140, 131, 112, - 127, 122, 52, 28, 32, 67, 77, 80, 97, 102, 76, 73, 18, 120, 124, 124, - 128, 127, 150, 201, 136, 122, 127, 131, 138, 140, 140, 142, 144, 159, 187, 186, - 197, 199, 209, 214, 216, 206, 212, 193, 130, 128, 138, 139, 138, 128, 127, 65, - 28, 24, 21, 21, 56, 63, 68, 91, 96, 103, 128, 217, 230, 236, 230, 126, - 115, 122, 131, 140, 151, 163, 167, 169, 167, 159, 150, 136, 116, 67, 52, 56, - 92, 88, 87, 45, 115, 170, 178, 157, 169, 174, 148, 171, 151, 150, 147, 100, - 79, 181, 185, 115, 100, 118, 127, 131, 130, 130, 147, 148, 158, 169, 175, 177, - 183, 189, 204, 201, 212, 218, 218, 222, 220, 213, 198, 179, 169, 147, 147, 146, - 151, 171, 174, 183, 182, 178, 169, 169, 170, 166, 138, 120, 147, 112, 61, 34, - 37, 96, 165, 173, 179, 179, 195, 230, 234, 230, 128, 120, 126, 135, 135, 163, - 165, 167, 167, 165, 158, 147, 142, 131, 79, 112, 140, 161, 158, 166, 167, 163, - 167, 171, 163, 147, 71, 127, 163, 167, 155, 148, 157, 155, 147, 151, 134, 116, - 45, 135, 155, 144, 148, 135, 136, 128, 134, 123, 136, 122, 118, 107, 97, 88, - 84, 79, 75, 80, 75, 107, 126, 209, 222, 225, 170, 169, 186, 185, 177, 171, - 163, 148, 136, 57, 17, 24, 42, 99, 100, 106, 92, 77, 42, 44, 56, 64, - 16, 42, 20, 10, 97, 93, 75, 71, 65, 45, 56, 85, 115, 116, 111, 107, - 111, 134, 153, 146, 136, 130, 122, 154, 170, 181, 179, 187, 193, 189, 194, 190, - 197, 209, 216, 229, 233, 236, 234, 224, 222, 182, 130, 79, 44, 22, 14, 12, - 13, 22, 32, 38, 34, 60, 116, 162, 189, 216, 214, 222, 230, 214, 119, 91, - 116, 112, 123, 138, 151, 154, 135, 128, 127, 140, 138, 144, 122, 107, 108, 110, - 118, 104, 83, 64, 51, 69, 46, 68, 138, 201, 209, 210, 206, 155, 119, 110, - 114, 130, 143, 148, 138, 154, 153, 144, 135, 115, 128, 128, 114, 96, 59, 55, - 76, 72, 59, 53, 44, 55, 130, 210, 185, 115, 123, 130, 143, 148, 154, 161, - 143, 139, 135, 132, 131, 135, 148, 153, 131, 96, 64, 36, 60, 77, 100, 157, - 210, 182, 163, 169, 178, 185, 187, 186, 190, 189, 177, 158, 169, 175, 167, 162, - 150, 139, 138, 134, 100, 87, 81, 87, 93, 190, 220, 163, 163, 147, 194, 205, - 212, 214, 214, 214, 214, 186, 134, 142, 191, 229, 238, 238, 238, 221, 195, 189, - 182, 178, 167, 143, 126, 52, 26, 24, 26, 38, 59, 55, 68, 68, 57, 45, - 112, 126, 88, 114, 100, 96, 112, 118, 104, 91, 55, 68, 124, 92, 104, 92, - 88, 87, 100, 93, 84, 100, 45, 20, 106, 115, 89, 95, 81, 85, 95, 91, - 95, 100, 107, 150, 213, 230, 238, 240, 236, 193, 119, 124, 114, 124, 128, 119, - 144, 157, 162, 165, 162, 162, 161, 159, 150, 134, 150, 163, 124, 120, 122, 120, - 120, 126, 123, 123, 122, 120, 115, 126, 154, 197, 232, 236, 240, 245, 244, 237, - 148, 123, 128, 114, 57, 40, 34, 40, 63, 67, 68, 81, 189, 212, 217, 220, - 213, 205, 127, 119, 131, 126, 144, 130, 136, 132, 136, 119, 123, 104, 32, 51, - 37, 40, 80, 99, 99, 80, 61, 30, 112, 123, 127, 114, 118, 124, 136, 182, - 174, 128, 128, 127, 131, 132, 132, 132, 135, 135, 136, 147, 165, 170, 173, 182, - 187, 165, 130, 132, 132, 132, 130, 126, 120, 56, 28, 22, 21, 18, 29, 44, - 56, 72, 93, 97, 108, 191, 229, 230, 234, 225, 128, 119, 127, 134, 140, 148, - 161, 167, 167, 169, 163, 158, 144, 142, 112, 80, 65, 61, 67, 88, 44, 122, - 171, 178, 177, 163, 157, 153, 153, 169, 142, 148, 95, 65, 158, 182, 140, 99, - 108, 124, 128, 132, 128, 128, 132, 157, 167, 163, 174, 169, 169, 165, 159, 181, - 191, 197, 205, 202, 190, 166, 143, 147, 144, 143, 144, 147, 146, 150, 163, 165, - 162, 159, 165, 157, 147, 131, 138, 110, 59, 30, 37, 37, 92, 155, 175, 190, - 177, 208, 222, 230, 230, 134, 120, 120, 136, 154, 165, 173, 167, 165, 165, 158, - 153, 140, 146, 124, 97, 89, 108, 135, 159, 167, 165, 165, 174, 144, 169, 67, - 104, 161, 161, 155, 159, 159, 153, 151, 150, 131, 119, 28, 135, 154, 162, 153, - 144, 139, 134, 127, 122, 140, 135, 103, 115, 108, 107, 100, 88, 89, 87, 89, - 93, 148, 220, 229, 225, 161, 163, 181, 183, 177, 171, 162, 150, 135, 46, 20, - 25, 41, 99, 97, 102, 79, 34, 32, 22, 24, 17, 18, 25, 14, 13, 87, - 83, 72, 59, 56, 59, 45, 37, 53, 84, 107, 112, 108, 111, 118, 128, 135, - 142, 142, 146, 146, 158, 177, 189, 199, 205, 213, 210, 214, 221, 226, 228, 224, - 222, 220, 202, 163, 119, 76, 40, 21, 14, 12, 12, 20, 26, 41, 32, 127, - 169, 206, 217, 201, 209, 209, 218, 214, 159, 115, 92, 140, 120, 130, 136, 138, - 131, 138, 144, 136, 131, 151, 138, 140, 134, 142, 148, 165, 143, 128, 100, 77, - 40, 40, 72, 162, 198, 202, 204, 210, 146, 122, 119, 119, 148, 150, 142, 142, - 138, 135, 138, 143, 132, 112, 130, 126, 111, 85, 110, 93, 87, 51, 59, 48, - 51, 92, 193, 195, 132, 114, 130, 140, 143, 143, 142, 138, 132, 130, 123, 122, - 120, 123, 139, 139, 114, 79, 29, 46, 71, 87, 111, 186, 201, 158, 163, 171, - 179, 181, 183, 185, 189, 187, 165, 158, 171, 173, 161, 144, 143, 135, 110, 71, - 49, 72, 81, 87, 114, 214, 177, 170, 154, 197, 206, 217, 217, 220, 214, 222, - 216, 212, 217, 233, 234, 234, 237, 237, 209, 190, 191, 186, 174, 147, 136, 91, - 30, 25, 24, 29, 46, 59, 57, 67, 63, 64, 41, 96, 95, 119, 106, 115, - 122, 118, 115, 104, 102, 52, 60, 89, 118, 115, 80, 91, 84, 92, 99, 96, - 95, 52, 17, 102, 107, 106, 89, 88, 88, 93, 100, 130, 183, 201, 226, 222, - 234, 229, 234, 232, 161, 122, 123, 130, 136, 148, 128, 123, 143, 150, 150, 150, - 153, 157, 157, 159, 150, 143, 157, 166, 157, 177, 185, 195, 204, 209, 212, 216, - 221, 224, 222, 226, 228, 230, 236, 241, 242, 230, 162, 123, 128, 126, 92, 41, - 34, 33, 45, 65, 69, 100, 165, 228, 214, 212, 225, 221, 167, 132, 135, 142, - 138, 140, 134, 146, 130, 134, 122, 120, 104, 76, 61, 40, 38, 38, 93, 97, - 76, 77, 26, 112, 116, 114, 112, 112, 107, 120, 124, 128, 131, 132, 158, 159, - 154, 151, 151, 147, 144, 142, 136, 136, 134, 134, 134, 135, 132, 130, 130, 126, - 126, 122, 89, 41, 26, 22, 20, 18, 24, 59, 52, 68, 89, 97, 104, 171, - 217, 225, 228, 232, 218, 127, 120, 122, 134, 140, 144, 148, 157, 162, 162, 159, - 154, 153, 147, 148, 122, 111, 100, 83, 63, 42, 95, 171, 167, 175, 144, 169, - 165, 165, 167, 146, 148, 106, 72, 126, 175, 186, 118, 107, 116, 124, 124, 127, - 128, 131, 134, 135, 139, 138, 138, 147, 135, 134, 131, 132, 136, 134, 132, 134, - 136, 136, 142, 143, 144, 147, 146, 144, 148, 146, 142, 140, 140, 140, 135, 144, - 144, 114, 55, 32, 28, 52, 33, 91, 154, 161, 170, 212, 217, 217, 229, 222, - 131, 127, 128, 135, 157, 162, 166, 161, 166, 166, 161, 158, 148, 139, 144, 153, - 140, 116, 118, 107, 159, 162, 161, 158, 143, 150, 72, 88, 167, 155, 155, 157, - 155, 151, 148, 140, 124, 115, 41, 131, 153, 154, 153, 128, 132, 127, 120, 111, - 108, 110, 96, 115, 115, 112, 106, 97, 100, 97, 104, 108, 170, 228, 229, 218, - 153, 158, 167, 179, 179, 170, 163, 150, 132, 41, 21, 24, 46, 97, 99, 102, - 16, 16, 13, 22, 12, 13, 30, 21, 17, 9, 75, 73, 72, 61, 79, 63, - 57, 45, 33, 33, 46, 69, 97, 107, 110, 108, 108, 115, 114, 123, 123, 128, - 134, 148, 171, 182, 190, 205, 209, 206, 208, 208, 204, 186, 163, 120, 83, 61, - 36, 21, 14, 9, 12, 10, 18, 28, 28, 102, 230, 191, 202, 194, 206, 205, - 213, 181, 146, 123, 110, 119, 120, 120, 116, 122, 115, 120, 119, 123, 122, 126, - 130, 124, 134, 147, 136, 140, 140, 135, 136, 153, 76, 38, 57, 95, 218, 190, - 194, 199, 202, 139, 123, 128, 139, 123, 143, 142, 139, 127, 130, 127, 127, 127, - 124, 126, 127, 112, 118, 115, 107, 79, 49, 51, 52, 46, 59, 151, 198, 157, - 110, 128, 132, 136, 139, 138, 131, 130, 123, 120, 118, 112, 111, 107, 114, 127, - 88, 77, 69, 55, 68, 85, 136, 204, 169, 159, 166, 169, 167, 174, 177, 182, - 186, 181, 161, 161, 166, 154, 143, 143, 123, 76, 42, 40, 40, 81, 79, 79, - 169, 190, 182, 140, 190, 205, 208, 213, 218, 224, 222, 225, 224, 226, 233, 232, - 236, 233, 225, 199, 195, 189, 183, 169, 138, 104, 45, 28, 25, 24, 24, 51, - 59, 57, 61, 68, 67, 44, 75, 104, 118, 115, 97, 103, 96, 111, 91, 68, - 56, 53, 91, 120, 99, 76, 93, 91, 92, 97, 104, 69, 52, 13, 91, 103, - 95, 97, 63, 85, 106, 198, 218, 214, 218, 238, 221, 232, 246, 229, 204, 130, - 123, 124, 144, 146, 138, 146, 136, 134, 134, 131, 135, 138, 131, 135, 139, 144, - 153, 150, 139, 174, 175, 187, 195, 204, 208, 213, 217, 220, 222, 225, 228, 232, - 233, 234, 232, 206, 144, 122, 124, 131, 122, 61, 36, 33, 36, 55, 65, 104, - 191, 198, 204, 213, 218, 236, 214, 150, 130, 119, 127, 127, 140, 136, 126, 139, - 126, 126, 134, 107, 91, 84, 75, 61, 36, 55, 95, 71, 75, 24, 108, 118, - 110, 88, 80, 85, 95, 93, 89, 88, 88, 102, 116, 120, 123, 119, 115, 119, - 123, 122, 122, 120, 118, 119, 123, 122, 120, 112, 108, 83, 44, 32, 24, 21, - 18, 16, 21, 28, 48, 56, 88, 95, 106, 175, 214, 218, 220, 225, 228, 163, - 127, 118, 127, 142, 138, 139, 146, 144, 151, 154, 159, 158, 153, 150, 143, 144, - 155, 153, 118, 88, 72, 46, 128, 173, 146, 170, 144, 165, 153, 159, 139, 148, - 140, 59, 116, 166, 165, 165, 157, 150, 147, 148, 143, 120, 119, 123, 124, 130, - 131, 131, 128, 127, 134, 127, 112, 108, 102, 96, 96, 108, 122, 128, 136, 140, - 142, 139, 132, 138, 139, 142, 143, 143, 142, 142, 134, 112, 55, 41, 30, 25, - 53, 32, 91, 158, 170, 213, 222, 220, 218, 230, 202, 131, 123, 136, 143, 146, - 153, 159, 163, 163, 163, 161, 157, 158, 154, 146, 144, 144, 161, 155, 134, 115, - 116, 120, 139, 131, 146, 68, 89, 165, 163, 157, 157, 157, 139, 142, 150, 110, - 114, 48, 136, 162, 151, 140, 132, 126, 119, 106, 104, 104, 96, 123, 112, 110, - 111, 103, 99, 102, 80, 107, 114, 185, 226, 232, 216, 147, 151, 157, 171, 178, - 169, 161, 150, 126, 30, 22, 22, 42, 97, 96, 100, 12, 17, 17, 24, 13, - 24, 36, 36, 16, 8, 68, 67, 61, 71, 52, 49, 41, 37, 34, 32, 26, - 22, 33, 41, 64, 83, 97, 100, 106, 106, 106, 107, 108, 115, 123, 130, 134, - 142, 159, 158, 151, 148, 119, 91, 75, 52, 25, 20, 18, 14, 9, 10, 14, - 12, 30, 37, 30, 144, 190, 213, 193, 195, 179, 158, 136, 124, 112, 92, 87, - 83, 85, 89, 92, 95, 96, 99, 103, 104, 103, 106, 107, 112, 118, 120, 120, - 119, 123, 126, 127, 114, 77, 37, 68, 153, 175, 181, 155, 158, 136, 130, 108, - 114, 119, 112, 119, 119, 122, 115, 126, 127, 119, 131, 127, 122, 112, 110, 110, - 106, 96, 45, 25, 33, 48, 41, 45, 104, 178, 186, 108, 120, 118, 120, 122, - 122, 119, 123, 118, 118, 114, 112, 108, 110, 106, 103, 95, 85, 49, 46, 53, - 67, 100, 163, 181, 155, 159, 165, 163, 158, 167, 171, 173, 178, 175, 165, 146, - 144, 147, 130, 91, 53, 38, 32, 32, 59, 76, 80, 138, 204, 182, 158, 170, - 191, 205, 206, 210, 210, 209, 209, 210, 208, 210, 210, 212, 209, 202, 191, 186, - 182, 173, 143, 116, 42, 24, 24, 24, 25, 28, 52, 51, 55, 64, 61, 65, - 57, 53, 56, 61, 73, 55, 57, 65, 57, 57, 75, 72, 64, 65, 73, 79, - 91, 79, 80, 80, 80, 76, 79, 45, 10, 48, 85, 89, 68, 73, 89, 169, - 210, 210, 214, 228, 248, 221, 217, 210, 159, 131, 123, 128, 138, 140, 140, 143, - 143, 140, 138, 132, 136, 139, 135, 134, 130, 127, 128, 130, 131, 128, 128, 130, - 130, 139, 147, 165, 189, 194, 206, 206, 204, 201, 205, 205, 193, 166, 126, 120, - 123, 130, 131, 107, 37, 30, 21, 60, 60, 85, 177, 193, 198, 213, 206, 208, - 181, 150, 136, 120, 138, 127, 126, 130, 134, 116, 122, 112, 119, 110, 130, 115, - 116, 104, 89, 37, 46, 95, 67, 68, 28, 112, 111, 76, 76, 69, 75, 71, - 72, 63, 61, 53, 49, 46, 46, 48, 44, 42, 41, 42, 38, 37, 34, 30, - 33, 37, 34, 33, 30, 28, 28, 22, 20, 18, 17, 17, 22, 37, 51, 42, - 88, 87, 107, 174, 208, 206, 205, 217, 221, 191, 142, 126, 131, 140, 136, 138, - 142, 139, 142, 143, 142, 148, 143, 139, 146, 144, 131, 132, 136, 161, 144, 72, - 45, 110, 114, 118, 120, 126, 128, 135, 135, 140, 139, 104, 37, 91, 124, 142, - 127, 116, 110, 116, 116, 120, 123, 120, 118, 116, 123, 123, 116, 114, 111, 88, - 55, 37, 33, 29, 30, 30, 36, 68, 102, 110, 114, 116, 112, 107, 108, 112, - 111, 110, 110, 107, 97, 61, 44, 34, 28, 25, 42, 60, 42, 148, 189, 204, - 216, 209, 199, 221, 218, 150, 128, 131, 143, 138, 138, 138, 146, 148, 150, 150, - 148, 147, 148, 146, 151, 150, 144, 146, 163, 158, 147, 131, 126, 120, 122, 102, - 85, 97, 134, 148, 159, 150, 151, 136, 140, 147, 126, 112, 42, 131, 135, 130, - 124, 108, 104, 91, 107, 112, 104, 93, 89, 95, 114, 111, 116, 107, 106, 99, - 112, 123, 199, 230, 232, 213, 144, 150, 154, 165, 173, 167, 161, 146, 107, 25, - 24, 21, 44, 81, 88, 87, 30, 25, 24, 26, 26, 33, 28, 25, 13, 6, - 56, 61, 45, 48, 44, 41, 32, 33, 26, 26, 22, 21, 20, 21, 17, 17, - 22, 34, 41, 55, 67, 89, 89, 91, 89, 85, 87, 81, 77, 75, 71, 59, - 36, 24, 20, 16, 14, 12, 8, 8, 16, 22, 21, 17, 25, 18, 20, 76, - 124, 144, 138, 135, 138, 88, 76, 65, 60, 44, 24, 25, 24, 21, 21, 22, - 24, 26, 28, 33, 33, 32, 37, 69, 80, 87, 85, 83, 81, 96, 88, 63, - 33, 46, 64, 128, 130, 140, 139, 143, 116, 93, 84, 85, 100, 102, 99, 97, - 103, 103, 110, 107, 106, 106, 108, 103, 96, 92, 93, 85, 49, 22, 22, 20, - 24, 44, 34, 42, 107, 128, 110, 115, 92, 110, 111, 116, 114, 114, 112, 108, - 103, 102, 96, 104, 96, 97, 96, 81, 26, 30, 65, 45, 75, 100, 166, 171, - 154, 159, 158, 158, 158, 161, 162, 161, 155, 150, 146, 144, 130, 103, 55, 38, - 34, 36, 38, 45, 80, 76, 171, 191, 189, 173, 126, 157, 189, 193, 195, 198, - 198, 197, 195, 191, 185, 183, 186, 187, 185, 182, 167, 148, 136, 108, 45, 26, - 24, 24, 33, 42, 37, 45, 33, 36, 53, 56, 61, 60, 65, 68, 84, 73, - 76, 73, 79, 79, 77, 75, 76, 73, 63, 79, 77, 52, 44, 24, 22, 34, - 33, 32, 30, 12, 29, 34, 46, 71, 65, 87, 162, 206, 220, 210, 212, 185, - 158, 142, 131, 123, 131, 124, 135, 134, 135, 135, 136, 136, 135, 131, 131, 130, - 128, 127, 127, 119, 124, 126, 126, 126, 127, 123, 124, 123, 120, 119, 118, 118, - 118, 120, 122, 122, 119, 118, 116, 116, 118, 118, 123, 127, 132, 127, 60, 25, - 28, 32, 60, 57, 144, 193, 189, 197, 209, 181, 147, 139, 124, 120, 108, 114, - 112, 108, 114, 110, 108, 100, 104, 106, 106, 104, 111, 103, 96, 92, 40, 55, - 72, 64, 56, 34, 107, 111, 77, 71, 69, 68, 67, 67, 61, 52, 46, 36, - 42, 37, 36, 36, 36, 32, 32, 32, 28, 25, 22, 26, 25, 24, 22, 21, - 18, 17, 17, 14, 21, 20, 26, 44, 34, 42, 56, 85, 95, 135, 195, 202, - 212, 204, 179, 163, 136, 128, 138, 132, 138, 132, 135, 130, 128, 131, 138, 138, - 139, 138, 134, 138, 138, 132, 130, 131, 138, 128, 46, 89, 103, 106, 104, 96, - 112, 108, 114, 106, 124, 119, 63, 37, 67, 75, 77, 68, 60, 49, 51, 42, - 42, 41, 45, 37, 36, 34, 34, 32, 32, 32, 30, 28, 25, 25, 22, 25, - 25, 29, 28, 30, 28, 26, 28, 29, 28, 26, 22, 28, 28, 29, 32, 32, - 29, 29, 25, 17, 25, 65, 65, 48, 154, 194, 220, 212, 216, 206, 174, 150, - 136, 132, 134, 136, 132, 126, 134, 136, 136, 140, 143, 143, 139, 135, 138, 134, - 127, 130, 147, 146, 148, 118, 128, 127, 135, 127, 112, 114, 106, 120, 126, 131, - 126, 135, 130, 143, 134, 115, 108, 25, 135, 148, 108, 95, 123, 139, 163, 186, - 177, 136, 111, 79, 85, 65, 87, 88, 93, 81, 102, 110, 146, 217, 229, 237, - 209, 140, 144, 148, 161, 170, 166, 154, 142, 75, 22, 22, 21, 48, 42, 33, - 40, 1, 5, 5, 10, 12, 13, 14, 13, 13, 6, 13, 16, 9, 10, 13, - 12, 9, 8, 8, 9, 8, 6, 5, 6, 5, 5, 5, 6, 6, 10, 9, - 8, 10, 10, 14, 13, 14, 13, 13, 13, 13, 13, 12, 10, 8, 5, 6, - 14, 25, 18, 26, 30, 28, 17, 17, 28, 20, 10, 24, 33, 32, 29, 26, - 16, 22, 24, 16, 12, 13, 13, 13, 12, 10, 12, 12, 12, 12, 14, 13, - 10, 8, 10, 13, 13, 13, 18, 21, 5, 9, 20, 20, 25, 14, 32, 44, - 46, 65, 30, 4, 5, 14, 16, 13, 13, 14, 16, 13, 13, 16, 13, 13, - 14, 16, 20, 20, 18, 18, 17, 22, 26, 34, 44, 41, 34, 26, 33, 30, - 25, 20, 9, 10, 16, 13, 12, 10, 10, 8, 8, 12, 6, 5, 10, 16, - 8, 8, 14, 12, 14, 17, 16, 29, 65, 99, 159, 161, 148, 147, 151, 150, - 154, 157, 153, 150, 144, 140, 128, 91, 49, 37, 33, 34, 33, 24, 48, 76, - 75, 159, 189, 202, 183, 139, 114, 114, 131, 126, 124, 119, 134, 127, 123, 120, - 120, 120, 123, 119, 118, 114, 69, 55, 33, 24, 24, 26, 28, 25, 24, 12, - 10, 26, 10, 10, 10, 12, 30, 10, 9, 20, 21, 10, 10, 20, 12, 12, - 10, 12, 20, 37, 34, 51, 49, 85, 99, 106, 104, 91, 83, 52, 12, 81, - 89, 89, 51, 67, 81, 112, 139, 157, 142, 139, 127, 111, 107, 108, 112, 114, - 112, 130, 130, 124, 128, 128, 131, 130, 128, 128, 128, 124, 127, 127, 124, 126, - 126, 126, 127, 124, 123, 123, 122, 122, 120, 120, 120, 119, 118, 120, 119, 119, - 119, 119, 120, 122, 124, 128, 131, 128, 96, 32, 24, 26, 28, 44, 53, 108, - 166, 183, 153, 144, 116, 102, 95, 97, 97, 100, 100, 100, 102, 102, 106, 106, - 106, 104, 108, 100, 100, 99, 102, 99, 73, 51, 51, 61, 64, 56, 32, 100, - 64, 57, 46, 44, 42, 42, 32, 33, 28, 26, 18, 17, 16, 16, 14, 16, - 14, 14, 14, 13, 13, 13, 14, 16, 17, 18, 20, 20, 21, 22, 26, 33, - 37, 53, 33, 42, 55, 97, 91, 107, 178, 175, 165, 153, 147, 138, 138, 130, - 123, 126, 126, 127, 126, 122, 122, 123, 122, 120, 128, 123, 126, 127, 120, 114, - 108, 110, 115, 114, 46, 72, 14, 10, 17, 12, 9, 12, 8, 16, 17, 6, - 21, 17, 8, 46, 42, 25, 8, 36, 18, 4, 4, 5, 8, 10, 12, 13, - 16, 16, 16, 16, 14, 13, 16, 17, 21, 22, 24, 22, 29, 29, 30, 25, - 24, 21, 21, 22, 22, 17, 22, 22, 22, 21, 20, 20, 13, 17, 21, 37, - 68, 72, 51, 166, 175, 191, 178, 177, 157, 135, 134, 128, 123, 124, 116, 120, - 120, 116, 118, 126, 127, 130, 128, 128, 124, 123, 120, 122, 120, 120, 116, 103, - 67, 36, 28, 34, 38, 37, 34, 48, 41, 36, 51, 69, 72, 69, 67, 87, - 91, 85, 33, 135, 99, 118, 146, 181, 191, 195, 197, 195, 193, 146, 107, 51, - 97, 120, 118, 112, 108, 110, 118, 161, 225, 236, 237, 198, 138, 143, 148, 161, - 167, 163, 151, 136, 46, 24, 22, 33, 46, 71, 79, 95, 56, 53, 53, 49, - 24, 12, 10, 8, 8, 9, 0, 1, 1, 5, 1, 1, 2, 4, 1, 2, - 4, 6, 5, 5, 6, 8, 8, 4, 1, 4, 2, 4, 2, 2, 2, 2, - 2, 2, 4, 4, 5, 6, 6, 9, 14, 16, 24, 20, 28, 30, 28, 34, - 38, 40, 49, 45, 20, 24, 34, 44, 30, 26, 22, 21, 24, 24, 22, 21, - 22, 24, 24, 21, 20, 18, 18, 21, 25, 22, 20, 18, 17, 14, 13, 18, - 26, 32, 13, 22, 33, 16, 17, 14, 36, 33, 42, 48, 45, 38, 33, 30, - 33, 32, 30, 28, 32, 29, 30, 28, 29, 32, 32, 29, 30, 30, 24, 26, - 26, 30, 24, 29, 55, 46, 49, 49, 52, 46, 33, 38, 34, 34, 37, 40, - 37, 32, 32, 33, 32, 28, 30, 32, 29, 26, 33, 34, 30, 30, 37, 44, - 45, 57, 63, 52, 52, 100, 148, 155, 163, 148, 154, 148, 153, 143, 146, 131, - 119, 72, 41, 37, 34, 24, 24, 24, 38, 67, 76, 140, 175, 198, 208, 181, - 127, 88, 67, 64, 61, 56, 57, 48, 46, 44, 48, 41, 44, 44, 42, 38, - 41, 36, 40, 38, 41, 30, 48, 38, 48, 41, 41, 41, 41, 41, 38, 38, - 38, 30, 9, 33, 100, 131, 89, 96, 99, 100, 95, 83, 89, 96, 107, 130, - 119, 128, 130, 100, 107, 104, 115, 102, 80, 18, 92, 88, 102, 99, 56, 71, - 81, 99, 85, 83, 81, 73, 73, 64, 60, 57, 49, 52, 41, 40, 36, 34, - 32, 30, 29, 33, 30, 33, 30, 30, 29, 30, 29, 30, 29, 29, 28, 33, - 30, 33, 32, 30, 33, 38, 42, 63, 96, 110, 119, 123, 124, 127, 126, 128, - 131, 127, 114, 45, 26, 21, 18, 30, 61, 49, 65, 73, 71, 72, 73, 75, - 29, 22, 21, 21, 20, 20, 20, 20, 17, 17, 18, 18, 24, 25, 24, 28, - 29, 29, 32, 30, 14, 8, 14, 12, 14, 34, 41, 64, 79, 71, 91, 95, - 84, 73, 88, 84, 72, 12, 49, 71, 68, 68, 49, 61, 46, 63, 38, 25, - 34, 48, 79, 85, 81, 81, 80, 84, 79, 81, 83, 75, 72, 32, 61, 89, - 100, 97, 118, 131, 135, 136, 124, 119, 110, 107, 100, 85, 69, 73, 60, 63, - 57, 55, 49, 52, 49, 51, 49, 51, 49, 53, 53, 55, 53, 60, 60, 53, - 17, 30, 103, 107, 114, 124, 124, 122, 130, 126, 128, 130, 76, 25, 104, 111, - 118, 111, 111, 102, 106, 67, 38, 25, 20, 13, 25, 21, 24, 18, 18, 17, - 20, 18, 13, 17, 14, 17, 8, 18, 22, 22, 14, 25, 21, 14, 9, 9, - 13, 13, 16, 18, 21, 21, 21, 26, 25, 44, 55, 69, 76, 46, 161, 142, - 146, 136, 138, 127, 111, 88, 75, 72, 56, 53, 48, 52, 41, 40, 40, 41, - 37, 38, 36, 33, 32, 30, 33, 32, 34, 34, 30, 34, 65, 68, 84, 91, - 84, 91, 103, 118, 130, 120, 107, 81, 80, 59, 56, 87, 89, 95, 88, 124, - 146, 186, 202, 201, 195, 218, 197, 187, 139, 114, 71, 107, 123, 127, 122, 122, - 115, 138, 191, 226, 236, 237, 185, 135, 139, 146, 158, 163, 158, 147, 114, 32, - 24, 26, 30, 67, 97, 122, 135, 108, 93, 83, 79, 48, 45, 37, 32, 12, - 1, 17, 68, 73, 67, 60, 71, 77, 67, 61, 57, 60, 63, 65, 71, 65, - 65, 55, 46, 25, 20, 14, 14, 13, 12, 13, 14, 20, 21, 18, 20, 21, - 26, 25, 28, 30, 30, 26, 37, 45, 53, 60, 55, 65, 59, 67, 55, 36, - 14, 65, 52, 33, 30, 30, 26, 28, 26, 26, 28, 26, 20, 26, 33, 34, - 30, 29, 29, 33, 26, 21, 16, 13, 13, 9, 12, 24, 24, 20, 17, 22, - 22, 21, 25, 20, 5, 52, 41, 34, 33, 33, 29, 38, 32, 28, 28, 30, - 28, 26, 17, 20, 33, 26, 28, 29, 32, 24, 32, 26, 25, 26, 51, 55, - 48, 49, 49, 52, 51, 53, 45, 12, 69, 57, 41, 42, 32, 36, 37, 34, - 33, 34, 36, 33, 37, 37, 40, 40, 38, 40, 42, 42, 52, 56, 60, 48, - 55, 135, 144, 142, 146, 136, 134, 131, 130, 112, 69, 55, 44, 40, 34, 38, - 28, 22, 36, 64, 96, 89, 143, 195, 202, 208, 166, 104, 59, 42, 37, 64, - 42, 42, 40, 46, 46, 44, 41, 45, 46, 46, 45, 41, 42, 38, 40, 38, - 41, 40, 37, 42, 48, 49, 49, 55, 56, 55, 60, 49, 32, 6, 108, 130, - 122, 116, 102, 103, 99, 122, 108, 118, 71, 99, 108, 106, 100, 112, 115, 104, - 104, 110, 114, 73, 13, 80, 97, 99, 104, 85, 60, 71, 77, 53, 45, 44, - 59, 41, 44, 41, 41, 38, 40, 29, 25, 25, 22, 25, 20, 20, 22, 22, - 22, 22, 21, 21, 21, 21, 21, 20, 20, 18, 21, 20, 20, 20, 20, 21, - 21, 20, 22, 26, 32, 40, 51, 64, 77, 87, 95, 95, 79, 44, 26, 25, - 24, 26, 36, 64, 65, 61, 48, 52, 53, 46, 56, 46, 46, 42, 40, 41, - 37, 32, 30, 30, 28, 26, 26, 21, 24, 22, 21, 21, 17, 17, 18, 18, - 22, 41, 26, 52, 37, 89, 134, 139, 142, 138, 140, 136, 135, 134, 103, 81, - 4, 103, 81, 85, 77, 72, 89, 104, 75, 77, 68, 36, 93, 112, 111, 107, - 104, 108, 104, 106, 102, 93, 88, 72, 30, 102, 103, 96, 114, 120, 123, 124, - 112, 111, 96, 99, 77, 61, 63, 60, 55, 48, 44, 40, 36, 34, 34, 29, - 30, 30, 29, 24, 24, 21, 21, 21, 20, 17, 16, 26, 24, 116, 128, 126, - 128, 135, 135, 135, 135, 138, 142, 87, 29, 143, 136, 134, 136, 132, 132, 132, - 112, 97, 77, 52, 14, 36, 84, 79, 41, 48, 71, 67, 41, 49, 61, 56, - 37, 51, 73, 68, 75, 72, 89, 71, 73, 63, 33, 8, 21, 41, 61, 44, - 44, 49, 52, 52, 59, 73, 81, 80, 40, 131, 120, 119, 87, 96, 88, 83, - 63, 64, 65, 63, 49, 48, 51, 51, 45, 45, 45, 44, 42, 44, 44, 42, - 44, 49, 49, 49, 51, 56, 71, 71, 87, 99, 110, 131, 91, 91, 131, 116, - 107, 120, 135, 139, 132, 120, 118, 108, 68, 131, 154, 182, 204, 197, 202, 206, - 178, 154, 132, 142, 106, 71, 104, 126, 135, 140, 134, 124, 148, 210, 228, 234, - 234, 169, 134, 139, 146, 157, 158, 150, 140, 77, 25, 25, 25, 32, 64, 116, - 138, 154, 65, 65, 68, 71, 45, 65, 48, 40, 12, 1, 77, 68, 57, 55, - 55, 52, 46, 59, 56, 55, 49, 51, 53, 49, 42, 44, 48, 45, 63, 57, - 37, 21, 20, 13, 28, 41, 42, 42, 42, 40, 38, 36, 38, 34, 28, 17, - 26, 55, 63, 69, 63, 67, 63, 69, 71, 60, 46, 17, 65, 53, 51, 42, - 46, 45, 41, 40, 36, 34, 32, 17, 32, 45, 55, 49, 48, 42, 45, 40, - 30, 29, 28, 24, 9, 42, 42, 42, 51, 28, 33, 48, 29, 25, 28, 10, - 53, 65, 56, 59, 56, 44, 42, 32, 28, 34, 28, 10, 20, 64, 34, 57, - 42, 51, 37, 49, 37, 25, 16, 14, 28, 46, 56, 56, 52, 52, 63, 53, - 48, 41, 9, 68, 72, 42, 51, 42, 42, 41, 42, 46, 40, 38, 28, 21, - 34, 40, 51, 37, 44, 46, 53, 51, 52, 56, 59, 48, 111, 140, 123, 89, - 75, 69, 67, 56, 53, 46, 46, 37, 34, 38, 30, 26, 42, 59, 67, 89, - 93, 182, 195, 206, 204, 158, 103, 48, 42, 41, 41, 41, 41, 44, 51, 51, - 51, 69, 93, 134, 146, 163, 173, 165, 153, 110, 64, 49, 44, 40, 42, 44, - 41, 40, 42, 42, 46, 55, 52, 51, 28, 118, 128, 100, 88, 88, 89, 87, - 84, 102, 68, 84, 118, 120, 103, 118, 99, 104, 96, 104, 104, 118, 73, 12, - 85, 91, 108, 95, 87, 81, 53, 51, 48, 64, 64, 40, 33, 32, 33, 38, - 25, 29, 21, 21, 20, 17, 20, 18, 18, 20, 20, 20, 20, 18, 20, 21, - 20, 20, 20, 20, 20, 22, 26, 32, 28, 32, 32, 32, 28, 24, 21, 22, - 21, 24, 25, 25, 25, 26, 28, 25, 26, 24, 25, 14, 28, 67, 73, 72, - 65, 65, 63, 59, 55, 51, 48, 46, 49, 44, 42, 41, 37, 37, 34, 33, - 30, 29, 29, 29, 30, 26, 26, 28, 25, 28, 36, 46, 59, 61, 61, 72, - 112, 140, 139, 132, 132, 123, 120, 122, 128, 112, 88, 9, 97, 89, 96, 81, - 88, 91, 91, 81, 83, 79, 36, 99, 127, 135, 128, 120, 127, 132, 131, 111, - 110, 95, 76, 30, 91, 93, 112, 139, 142, 110, 104, 123, 96, 72, 71, 65, - 69, 71, 55, 49, 46, 38, 41, 38, 37, 34, 30, 30, 29, 29, 28, 25, - 24, 22, 24, 22, 20, 18, 40, 45, 127, 115, 122, 126, 135, 135, 132, 134, - 128, 153, 89, 34, 139, 147, 147, 148, 146, 146, 140, 127, 114, 87, 61, 13, - 76, 100, 106, 80, 77, 48, 56, 69, 64, 45, 49, 46, 49, 100, 123, 120, - 120, 115, 118, 108, 83, 63, 10, 96, 106, 96, 95, 88, 85, 84, 81, 77, - 80, 85, 91, 46, 114, 158, 114, 104, 81, 73, 81, 67, 64, 67, 61, 51, - 49, 53, 52, 46, 48, 49, 48, 49, 45, 46, 49, 51, 49, 56, 60, 60, - 61, 77, 83, 97, 91, 102, 80, 77, 112, 122, 147, 134, 120, 123, 126, 119, - 119, 107, 92, 120, 154, 154, 195, 199, 201, 197, 170, 132, 123, 126, 130, 110, - 72, 97, 124, 130, 132, 118, 131, 169, 218, 228, 236, 229, 148, 134, 138, 144, - 155, 153, 146, 120, 42, 26, 25, 25, 20, 64, 116, 140, 153, 22, 29, 26, - 17, 21, 20, 52, 36, 10, 4, 55, 75, 53, 68, 52, 46, 49, 44, 41, - 38, 28, 24, 37, 52, 68, 68, 60, 61, 42, 48, 55, 38, 24, 17, 33, - 44, 40, 45, 40, 44, 42, 37, 38, 42, 17, 17, 44, 68, 73, 68, 71, - 59, 65, 63, 51, 46, 34, 18, 60, 57, 49, 48, 51, 44, 48, 38, 41, - 44, 34, 21, 37, 41, 48, 48, 49, 60, 55, 52, 41, 40, 29, 24, 12, - 45, 52, 42, 52, 51, 46, 42, 48, 28, 25, 8, 45, 65, 77, 81, 81, - 59, 61, 48, 42, 32, 29, 9, 49, 73, 69, 64, 60, 57, 56, 59, 48, - 42, 26, 13, 34, 53, 59, 44, 42, 51, 55, 55, 57, 29, 2, 77, 79, - 73, 56, 36, 40, 30, 42, 37, 34, 37, 25, 17, 33, 72, 61, 61, 59, - 59, 55, 53, 53, 56, 67, 46, 127, 135, 118, 91, 79, 65, 64, 57, 53, - 44, 44, 36, 26, 25, 33, 38, 59, 61, 97, 95, 126, 179, 206, 205, 208, - 143, 102, 72, 67, 69, 59, 55, 59, 73, 89, 120, 154, 187, 210, 221, 226, - 229, 229, 222, 224, 216, 193, 163, 134, 79, 55, 42, 44, 42, 44, 41, 40, - 52, 49, 46, 9, 84, 127, 81, 76, 91, 92, 87, 85, 96, 69, 89, 108, - 118, 115, 111, 116, 111, 104, 110, 107, 111, 68, 12, 85, 89, 99, 93, 85, - 56, 56, 55, 53, 57, 44, 25, 76, 61, 51, 45, 51, 63, 44, 49, 46, - 42, 38, 36, 41, 38, 49, 49, 49, 42, 41, 41, 40, 36, 34, 36, 34, - 56, 49, 53, 51, 59, 57, 59, 52, 51, 40, 30, 25, 28, 25, 22, 22, - 22, 22, 24, 21, 26, 25, 9, 36, 69, 87, 92, 95, 93, 96, 91, 91, - 76, 64, 56, 87, 92, 69, 67, 68, 57, 56, 68, 67, 28, 10, 45, 63, - 73, 48, 38, 48, 57, 38, 67, 59, 65, 60, 67, 115, 138, 134, 131, 132, - 123, 123, 106, 118, 127, 67, 12, 75, 103, 96, 112, 112, 120, 122, 95, 112, - 69, 37, 91, 130, 140, 138, 134, 131, 142, 127, 132, 112, 99, 85, 32, 92, - 91, 102, 114, 132, 161, 138, 128, 83, 87, 68, 84, 118, 112, 106, 77, 87, - 87, 89, 81, 79, 69, 63, 51, 53, 51, 48, 48, 44, 44, 42, 41, 42, - 36, 45, 25, 102, 135, 143, 135, 128, 132, 146, 139, 131, 147, 89, 38, 123, - 147, 147, 143, 143, 138, 157, 127, 114, 112, 60, 14, 80, 104, 87, 115, 88, - 102, 76, 80, 81, 102, 63, 48, 75, 120, 135, 134, 130, 128, 123, 118, 84, - 72, 24, 100, 108, 102, 102, 99, 96, 97, 92, 88, 68, 91, 95, 51, 115, - 138, 126, 143, 127, 135, 138, 111, 93, 89, 80, 72, 75, 76, 64, 69, 69, - 69, 68, 68, 68, 68, 68, 69, 71, 75, 76, 73, 77, 81, 91, 79, 106, - 127, 99, 51, 108, 115, 111, 111, 123, 114, 120, 112, 111, 107, 91, 128, 161, - 163, 201, 191, 198, 167, 132, 126, 122, 147, 116, 103, 65, 96, 110, 120, 118, - 120, 136, 182, 221, 225, 232, 213, 138, 134, 139, 146, 154, 150, 140, 85, 30, - 26, 25, 26, 16, 64, 114, 132, 154, 16, 14, 33, 36, 30, 29, 32, 20, - 9, 10, 53, 64, 63, 53, 68, 49, 56, 48, 53, 40, 26, 20, 52, 60, - 59, 46, 38, 40, 41, 48, 45, 51, 26, 16, 45, 46, 42, 45, 38, 38, - 36, 33, 34, 48, 17, 16, 44, 69, 69, 76, 75, 51, 52, 52, 53, 49, - 29, 18, 60, 51, 45, 53, 46, 55, 48, 42, 41, 48, 36, 25, 41, 48, - 61, 49, 38, 60, 49, 67, 48, 42, 36, 28, 13, 40, 56, 55, 45, 41, - 41, 42, 46, 32, 28, 8, 55, 72, 76, 72, 76, 80, 60, 67, 52, 42, - 32, 6, 59, 71, 81, 69, 67, 65, 69, 63, 61, 57, 25, 13, 57, 60, - 67, 61, 45, 53, 72, 60, 52, 41, 8, 81, 77, 68, 61, 46, 38, 41, - 52, 55, 53, 48, 30, 13, 67, 75, 76, 73, 72, 61, 63, 59, 59, 65, - 65, 57, 116, 134, 120, 107, 91, 75, 68, 60, 51, 44, 45, 29, 25, 36, - 37, 57, 56, 72, 93, 84, 97, 191, 199, 217, 186, 138, 104, 122, 127, 118, - 126, 135, 158, 177, 201, 213, 224, 228, 229, 229, 228, 224, 224, 225, 222, 217, - 218, 213, 213, 185, 122, 59, 44, 42, 42, 46, 44, 51, 57, 33, 8, 84, - 128, 99, 84, 112, 92, 112, 97, 83, 60, 88, 123, 122, 108, 116, 108, 123, - 118, 100, 99, 107, 81, 16, 91, 89, 100, 96, 96, 76, 72, 53, 65, 56, - 60, 45, 67, 84, 81, 63, 61, 53, 61, 57, 56, 55, 56, 37, 33, 49, - 51, 53, 59, 52, 56, 56, 56, 57, 56, 49, 45, 55, 64, 61, 63, 59, - 61, 60, 60, 59, 40, 63, 67, 68, 67, 60, 60, 37, 34, 33, 30, 32, - 25, 10, 44, 77, 95, 96, 93, 96, 96, 100, 95, 87, 73, 63, 79, 102, - 80, 91, 89, 89, 71, 61, 72, 63, 16, 75, 80, 81, 79, 77, 71, 67, - 64, 63, 57, 63, 67, 57, 102, 130, 134, 128, 131, 116, 116, 110, 120, 102, - 88, 16, 92, 99, 116, 100, 102, 108, 110, 112, 111, 80, 51, 114, 131, 132, - 135, 136, 143, 146, 143, 140, 127, 107, 81, 32, 92, 93, 116, 104, 123, 134, - 151, 139, 87, 88, 69, 91, 126, 112, 110, 107, 107, 104, 106, 110, 103, 83, - 79, 65, 93, 99, 97, 93, 92, 73, 69, 80, 83, 59, 38, 80, 127, 135, - 124, 135, 128, 140, 138, 139, 134, 151, 96, 45, 132, 147, 147, 154, 140, 140, - 132, 136, 112, 115, 61, 14, 89, 112, 103, 136, 106, 110, 119, 106, 92, 103, - 64, 49, 108, 135, 128, 126, 123, 124, 123, 132, 85, 61, 10, 80, 114, 107, - 130, 108, 106, 84, 99, 96, 91, 96, 99, 61, 127, 135, 147, 128, 138, 136, - 140, 128, 128, 95, 88, 57, 41, 73, 75, 77, 77, 76, 68, 71, 79, 67, - 48, 63, 95, 110, 114, 110, 76, 75, 75, 81, 96, 130, 112, 53, 110, 107, - 111, 110, 122, 115, 116, 118, 116, 104, 95, 134, 163, 175, 198, 199, 173, 139, - 124, 118, 138, 144, 130, 97, 71, 87, 112, 115, 114, 127, 158, 205, 224, 229, - 233, 193, 131, 132, 139, 151, 150, 144, 123, 41, 29, 28, 28, 26, 36, 59, - 122, 131, 143, 61, 12, 12, 21, 13, 28, 29, 46, 9, 1, 44, 73, 59, - 56, 65, 59, 52, 48, 49, 34, 29, 18, 49, 52, 38, 46, 52, 51, 71, - 57, 45, 52, 32, 24, 48, 48, 52, 52, 53, 46, 48, 37, 33, 45, 18, - 14, 56, 72, 68, 68, 68, 48, 63, 56, 61, 46, 37, 22, 53, 59, 42, - 59, 60, 44, 46, 51, 48, 49, 38, 25, 46, 56, 55, 51, 38, 52, 45, - 60, 56, 49, 37, 28, 5, 42, 42, 55, 48, 42, 41, 45, 46, 32, 28, - 9, 49, 69, 71, 63, 59, 59, 60, 57, 56, 42, 29, 6, 65, 83, 80, - 71, 71, 63, 73, 71, 64, 56, 36, 14, 57, 63, 69, 53, 64, 53, 65, - 59, 51, 42, 8, 77, 68, 61, 56, 56, 44, 46, 60, 63, 57, 48, 29, - 14, 68, 71, 80, 76, 77, 64, 68, 68, 61, 55, 55, 51, 103, 128, 126, - 102, 107, 97, 79, 73, 57, 53, 30, 20, 29, 52, 60, 60, 75, 65, 89, - 83, 95, 167, 209, 212, 181, 126, 96, 119, 189, 194, 198, 206, 210, 216, 222, - 224, 225, 224, 218, 213, 201, 197, 198, 186, 179, 167, 170, 173, 189, 205, 205, - 162, 76, 51, 41, 41, 44, 46, 48, 28, 8, 104, 138, 108, 91, 88, 99, - 87, 95, 93, 53, 88, 118, 118, 103, 103, 104, 104, 107, 104, 103, 102, 80, - 16, 91, 81, 99, 92, 97, 95, 84, 72, 61, 55, 49, 46, 75, 83, 71, - 76, 76, 59, 75, 79, 81, 69, 52, 36, 44, 76, 93, 89, 57, 57, 59, - 63, 65, 65, 67, 37, 52, 88, 84, 85, 84, 67, 65, 68, 64, 65, 45, - 63, 76, 75, 77, 69, 69, 60, 55, 55, 52, 48, 28, 9, 71, 80, 96, - 104, 107, 104, 95, 83, 102, 91, 80, 51, 80, 84, 103, 87, 85, 93, 89, - 80, 79, 69, 6, 84, 84, 68, 91, 91, 53, 59, 91, 81, 87, 69, 67, - 51, 100, 132, 136, 122, 119, 114, 111, 123, 100, 107, 88, 4, 93, 100, 128, - 107, 99, 96, 100, 111, 123, 83, 53, 120, 136, 143, 144, 136, 130, 131, 144, - 148, 134, 115, 84, 33, 89, 89, 99, 92, 116, 139, 135, 122, 89, 91, 76, - 95, 126, 122, 115, 114, 111, 112, 110, 107, 108, 107, 85, 69, 99, 104, 110, - 107, 104, 102, 100, 97, 97, 63, 28, 112, 97, 126, 126, 131, 136, 138, 142, - 134, 132, 144, 104, 46, 139, 148, 150, 154, 155, 155, 131, 142, 116, 116, 67, - 16, 88, 118, 123, 120, 104, 104, 104, 107, 115, 104, 69, 48, 123, 138, 138, - 107, 118, 130, 126, 132, 84, 68, 9, 124, 115, 111, 108, 111, 114, 118, 120, - 123, 124, 103, 107, 63, 120, 154, 139, 140, 138, 142, 132, 131, 130, 119, 111, - 37, 57, 80, 106, 103, 85, 89, 91, 99, 93, 79, 51, 97, 100, 126, 111, - 97, 119, 122, 112, 96, 126, 118, 110, 55, 104, 103, 120, 118, 119, 116, 111, - 112, 118, 103, 91, 119, 166, 166, 213, 187, 154, 126, 123, 127, 144, 150, 128, - 95, 68, 81, 106, 112, 116, 138, 190, 213, 214, 229, 225, 153, 127, 132, 146, - 147, 143, 131, 67, 30, 28, 26, 30, 29, 38, 61, 123, 127, 134, 64, 12, - 12, 25, 28, 38, 29, 33, 9, 1, 53, 63, 52, 64, 64, 61, 59, 57, - 45, 33, 24, 18, 49, 38, 46, 44, 63, 63, 67, 51, 53, 49, 41, 22, - 55, 68, 65, 64, 56, 57, 45, 40, 33, 37, 14, 34, 60, 67, 65, 53, - 60, 38, 42, 40, 44, 46, 45, 22, 45, 56, 42, 37, 44, 49, 55, 60, - 46, 44, 48, 24, 46, 53, 48, 45, 46, 57, 49, 67, 56, 55, 38, 26, - 6, 36, 51, 56, 44, 60, 46, 42, 42, 32, 29, 12, 52, 75, 65, 63, - 63, 65, 64, 57, 60, 44, 29, 6, 60, 63, 73, 73, 73, 73, 79, 73, - 72, 57, 30, 25, 61, 60, 69, 59, 65, 65, 79, 57, 48, 37, 6, 79, - 79, 67, 60, 57, 73, 73, 73, 72, 67, 49, 29, 12, 71, 79, 80, 73, - 76, 72, 75, 79, 64, 65, 69, 48, 91, 120, 122, 112, 95, 102, 87, 81, - 64, 73, 34, 18, 44, 56, 75, 77, 75, 65, 112, 85, 107, 123, 189, 206, - 183, 122, 110, 118, 157, 190, 198, 202, 208, 210, 210, 213, 206, 201, 193, 174, - 155, 150, 150, 151, 143, 147, 142, 148, 153, 151, 162, 187, 177, 87, 41, 41, - 46, 45, 46, 44, 22, 111, 116, 111, 91, 89, 97, 87, 92, 85, 53, 84, - 120, 114, 106, 110, 102, 104, 96, 111, 110, 100, 77, 16, 85, 79, 106, 108, - 100, 87, 76, 63, 64, 57, 51, 24, 69, 92, 76, 83, 69, 73, 84, 87, - 88, 77, 52, 36, 63, 93, 92, 100, 97, 73, 73, 72, 65, 76, 61, 36, - 83, 87, 92, 91, 92, 85, 72, 69, 71, 69, 46, 75, 79, 87, 83, 83, - 79, 71, 61, 61, 56, 51, 28, 8, 76, 93, 99, 81, 95, 104, 106, 83, - 95, 95, 79, 44, 81, 88, 100, 95, 103, 107, 88, 95, 79, 72, 8, 93, - 88, 83, 85, 83, 89, 88, 95, 92, 95, 88, 68, 71, 103, 140, 122, 123, - 118, 124, 115, 114, 120, 103, 92, 5, 100, 106, 103, 102, 128, 120, 128, 112, - 107, 87, 49, 115, 132, 139, 147, 144, 139, 140, 142, 135, 139, 115, 84, 33, - 88, 92, 100, 100, 126, 89, 97, 100, 88, 95, 77, 96, 124, 123, 126, 104, - 122, 119, 116, 114, 116, 112, 96, 71, 91, 110, 122, 120, 119, 116, 115, 114, - 100, 64, 29, 106, 138, 131, 127, 140, 139, 142, 139, 132, 127, 142, 96, 55, - 138, 150, 143, 143, 143, 140, 144, 138, 114, 118, 73, 20, 102, 124, 99, 111, - 85, 124, 111, 127, 119, 100, 64, 59, 118, 143, 127, 122, 115, 134, 131, 130, - 81, 65, 9, 120, 128, 115, 118, 119, 122, 123, 127, 128, 127, 106, 110, 68, - 119, 146, 142, 124, 126, 123, 119, 123, 120, 120, 108, 30, 75, 112, 131, 115, - 111, 102, 122, 119, 96, 83, 46, 97, 118, 119, 128, 119, 120, 112, 120, 127, - 134, 118, 103, 56, 103, 131, 100, 114, 112, 114, 112, 115, 111, 100, 84, 124, - 139, 150, 171, 183, 163, 128, 122, 132, 151, 150, 111, 104, 73, 85, 110, 107, - 132, 173, 210, 214, 218, 226, 201, 131, 128, 135, 148, 143, 135, 95, 34, 28, - 29, 28, 34, 30, 9, 76, 126, 134, 139, 9, 16, 29, 49, 45, 34, 26, - 32, 8, 1, 59, 67, 56, 61, 63, 59, 46, 63, 40, 32, 24, 16, 48, - 75, 79, 68, 68, 67, 53, 46, 46, 49, 42, 25, 25, 46, 51, 44, 48, - 45, 48, 38, 36, 38, 17, 36, 64, 69, 51, 46, 44, 45, 44, 46, 46, - 45, 42, 24, 40, 63, 49, 45, 38, 45, 34, 41, 36, 37, 48, 26, 49, - 56, 49, 53, 57, 56, 53, 45, 48, 59, 37, 25, 5, 40, 44, 57, 46, - 48, 53, 44, 41, 36, 29, 8, 40, 73, 65, 65, 67, 65, 61, 61, 56, - 42, 30, 4, 41, 80, 67, 80, 73, 76, 79, 77, 69, 69, 29, 10, 55, - 67, 72, 65, 60, 61, 59, 60, 56, 29, 1, 75, 72, 56, 65, 59, 56, - 55, 59, 57, 64, 48, 28, 10, 72, 67, 73, 72, 71, 73, 81, 91, 68, - 67, 67, 53, 71, 116, 119, 110, 93, 99, 88, 85, 79, 69, 41, 21, 52, - 72, 76, 72, 69, 68, 111, 91, 114, 92, 159, 214, 186, 114, 106, 107, 127, - 138, 163, 174, 183, 186, 189, 181, 166, 148, 140, 147, 148, 150, 153, 162, 163, - 167, 154, 147, 140, 135, 140, 143, 178, 155, 84, 37, 46, 42, 41, 40, 10, - 89, 112, 107, 75, 88, 102, 92, 95, 80, 55, 85, 116, 119, 112, 104, 110, - 104, 104, 115, 108, 102, 76, 20, 80, 84, 85, 91, 93, 93, 77, 63, 65, - 61, 56, 24, 51, 84, 87, 85, 97, 97, 112, 111, 108, 84, 57, 16, 65, - 95, 93, 100, 88, 83, 87, 106, 97, 79, 65, 34, 83, 87, 95, 87, 85, - 91, 87, 85, 72, 68, 52, 73, 85, 87, 85, 83, 83, 79, 72, 67, 61, - 51, 30, 6, 77, 97, 75, 81, 89, 111, 99, 95, 99, 89, 79, 48, 93, - 93, 102, 92, 100, 95, 97, 99, 83, 56, 9, 92, 96, 115, 95, 93, 97, - 110, 97, 95, 93, 103, 79, 57, 87, 126, 136, 138, 130, 124, 131, 138, 116, - 108, 64, 1, 84, 111, 110, 120, 131, 120, 122, 119, 106, 88, 48, 93, 132, - 135, 140, 139, 140, 142, 139, 146, 144, 134, 85, 34, 87, 87, 100, 116, 97, - 115, 100, 99, 84, 97, 83, 99, 108, 131, 130, 111, 114, 128, 130, 120, 126, - 122, 110, 75, 93, 123, 95, 114, 127, 126, 122, 119, 103, 72, 34, 128, 138, - 138, 144, 142, 136, 135, 130, 131, 132, 146, 97, 71, 93, 147, 143, 140, 142, - 138, 138, 134, 115, 111, 71, 21, 97, 123, 116, 115, 122, 115, 123, 110, 110, - 92, 69, 56, 118, 132, 131, 110, 131, 120, 126, 131, 83, 72, 8, 112, 124, - 118, 116, 142, 143, 150, 148, 146, 132, 108, 112, 71, 115, 154, 148, 147, 139, - 138, 118, 120, 123, 115, 87, 55, 100, 116, 115, 119, 122, 122, 119, 108, 102, - 89, 42, 103, 128, 122, 95, 120, 115, 123, 120, 131, 138, 120, 115, 40, 102, - 122, 103, 103, 107, 112, 112, 115, 108, 112, 79, 116, 140, 155, 171, 170, 183, - 130, 122, 148, 161, 139, 106, 95, 99, 100, 110, 130, 167, 199, 214, 216, 226, - 217, 157, 126, 132, 144, 142, 132, 107, 44, 29, 29, 29, 32, 34, 32, 12, - 61, 128, 150, 143, 17, 20, 21, 21, 22, 30, 33, 20, 8, 1, 37, 65, - 55, 56, 55, 56, 60, 49, 34, 30, 25, 13, 51, 49, 56, 46, 63, 51, - 48, 42, 38, 38, 36, 36, 26, 30, 38, 36, 44, 42, 44, 34, 33, 36, - 13, 41, 59, 56, 49, 52, 55, 52, 46, 52, 44, 60, 41, 26, 40, 61, - 59, 60, 51, 53, 44, 42, 41, 49, 36, 29, 55, 60, 56, 63, 51, 52, - 57, 53, 55, 41, 37, 29, 9, 33, 52, 55, 53, 49, 56, 46, 45, 36, - 32, 12, 65, 73, 79, 80, 71, 67, 67, 65, 61, 41, 30, 2, 57, 81, - 69, 76, 77, 77, 85, 76, 72, 63, 41, 12, 59, 73, 77, 63, 64, 63, - 63, 65, 51, 45, 5, 71, 84, 71, 84, 73, 84, 76, 73, 71, 67, 49, - 28, 10, 77, 75, 76, 84, 72, 69, 67, 79, 79, 64, 71, 52, 63, 110, - 112, 107, 107, 95, 91, 91, 84, 76, 44, 21, 60, 75, 77, 77, 84, 104, - 88, 111, 80, 120, 97, 201, 198, 128, 115, 107, 115, 122, 134, 138, 140, 144, - 140, 139, 132, 123, 120, 120, 123, 139, 150, 159, 162, 163, 165, 153, 148, 148, - 146, 136, 144, 174, 95, 37, 41, 44, 44, 33, 10, 85, 122, 107, 92, 92, - 95, 93, 97, 77, 44, 83, 114, 124, 123, 116, 115, 115, 116, 119, 106, 99, - 79, 29, 80, 85, 93, 87, 80, 72, 71, 56, 65, 68, 48, 57, 69, 100, - 108, 96, 100, 96, 108, 92, 85, 84, 52, 16, 73, 97, 103, 93, 96, 95, - 93, 96, 95, 75, 68, 30, 99, 88, 96, 83, 92, 87, 89, 91, 91, 72, - 52, 71, 80, 79, 79, 79, 81, 75, 73, 71, 71, 52, 33, 10, 83, 100, - 97, 73, 100, 80, 80, 92, 91, 87, 77, 51, 88, 103, 103, 95, 92, 95, - 99, 100, 80, 77, 28, 95, 96, 99, 114, 102, 100, 102, 108, 108, 110, 108, - 99, 67, 87, 111, 119, 122, 120, 104, 114, 110, 110, 104, 96, 12, 88, 116, - 115, 116, 119, 115, 111, 106, 108, 102, 75, 69, 120, 131, 131, 131, 128, 132, - 134, 132, 132, 124, 92, 34, 87, 89, 83, 93, 87, 111, 103, 102, 102, 116, - 100, 83, 110, 104, 108, 103, 112, 110, 115, 115, 119, 119, 119, 111, 88, 106, - 110, 97, 111, 115, 108, 120, 114, 79, 28, 103, 138, 131, 134, 135, 134, 130, - 131, 140, 143, 147, 107, 59, 76, 142, 148, 146, 148, 140, 139, 112, 112, 100, - 69, 22, 97, 124, 123, 128, 122, 130, 126, 124, 122, 89, 75, 56, 123, 150, - 134, 107, 110, 130, 128, 142, 91, 61, 8, 83, 130, 118, 136, 135, 123, 120, - 123, 136, 140, 108, 112, 73, 115, 146, 154, 144, 136, 135, 111, 124, 122, 123, - 77, 44, 111, 124, 131, 119, 115, 115, 114, 110, 100, 76, 44, 115, 132, 116, - 132, 134, 132, 135, 131, 130, 135, 138, 115, 33, 104, 102, 99, 103, 114, 107, - 106, 102, 106, 93, 63, 130, 136, 114, 144, 140, 175, 159, 120, 134, 158, 155, - 110, 103, 106, 118, 147, 173, 197, 206, 209, 224, 221, 171, 124, 128, 140, 138, - 127, 99, 42, 30, 30, 28, 29, 33, 37, 30, 45, 95, 128, 147, 155, 10, - 10, 10, 12, 12, 12, 12, 12, 8, 4, 13, 37, 64, 71, 51, 52, 33, - 33, 32, 18, 22, 13, 46, 42, 38, 42, 40, 42, 40, 32, 28, 26, 28, - 26, 30, 38, 40, 33, 32, 33, 33, 30, 36, 25, 13, 52, 57, 63, 46, - 48, 40, 41, 38, 38, 37, 41, 42, 33, 29, 45, 42, 37, 41, 41, 57, - 46, 44, 49, 45, 40, 38, 41, 45, 51, 44, 38, 37, 38, 38, 36, 36, - 28, 4, 32, 52, 48, 46, 45, 44, 45, 45, 49, 30, 13, 46, 60, 57, - 59, 59, 60, 57, 69, 60, 41, 28, 4, 61, 80, 76, 71, 69, 73, 65, - 72, 69, 59, 33, 6, 56, 61, 72, 72, 64, 72, 71, 65, 48, 44, 5, - 64, 72, 69, 69, 68, 68, 67, 65, 64, 64, 46, 26, 9, 72, 73, 79, - 75, 80, 75, 81, 69, 75, 76, 68, 56, 53, 85, 111, 99, 92, 83, 69, - 73, 77, 72, 48, 20, 55, 73, 95, 88, 107, 119, 91, 124, 124, 112, 84, - 124, 183, 139, 107, 106, 114, 119, 120, 115, 127, 124, 127, 120, 116, 112, 114, - 118, 155, 161, 138, 158, 167, 163, 161, 170, 157, 154, 151, 150, 146, 170, 91, - 32, 36, 40, 42, 28, 6, 79, 108, 106, 93, 88, 95, 93, 89, 79, 42, - 83, 99, 115, 114, 107, 106, 103, 103, 100, 92, 89, 79, 24, 40, 71, 73, - 51, 45, 63, 63, 40, 42, 51, 52, 60, 72, 92, 102, 92, 89, 87, 89, - 87, 85, 85, 45, 29, 65, 93, 107, 102, 102, 107, 96, 99, 95, 77, 67, - 33, 87, 84, 89, 84, 80, 79, 68, 65, 83, 80, 75, 75, 60, 63, 63, - 63, 59, 57, 59, 61, 57, 55, 32, 8, 87, 104, 67, 69, 75, 71, 72, - 72, 76, 81, 75, 73, 71, 73, 87, 87, 76, 76, 75, 76, 71, 80, 6, - 96, 96, 99, 93, 95, 97, 102, 99, 100, 95, 102, 100, 93, 71, 71, 83, - 87, 84, 84, 89, 89, 89, 93, 100, 8, 53, 112, 112, 110, 110, 106, 73, - 71, 76, 81, 99, 97, 77, 97, 108, 103, 108, 106, 111, 116, 116, 108, 85, - 36, 77, 73, 84, 92, 87, 89, 95, 100, 65, 63, 67, 110, 112, 116, 119, - 120, 119, 123, 124, 124, 122, 126, 119, 119, 118, 123, 123, 126, 124, 104, 104, - 122, 107, 83, 34, 132, 139, 130, 139, 143, 138, 144, 146, 134, 122, 118, 111, - 67, 64, 136, 128, 143, 104, 104, 104, 91, 97, 91, 69, 25, 96, 119, 115, - 93, 119, 119, 124, 104, 107, 95, 71, 46, 126, 142, 120, 123, 108, 127, 122, - 142, 77, 65, 8, 127, 130, 119, 128, 124, 126, 124, 124, 120, 120, 118, 116, - 83, 85, 116, 136, 131, 118, 107, 115, 114, 110, 122, 120, 44, 110, 126, 124, - 122, 120, 116, 114, 108, 102, 85, 44, 103, 131, 131, 128, 128, 132, 132, 123, - 127, 124, 118, 81, 37, 87, 110, 97, 89, 93, 100, 110, 106, 104, 91, 84, - 110, 120, 118, 128, 148, 132, 178, 128, 127, 157, 158, 157, 154, 155, 171, 190, - 191, 198, 202, 216, 214, 171, 122, 128, 136, 127, 119, 97, 46, 30, 30, 26, - 32, 32, 34, 30, 28, 40, 49, 120, 124, 127, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4, 9, 8, 10, 12, 13, 13, 20, 14, 17, 20, 20, 13, - 16, 13, 14, 14, 12, 12, 13, 10, 12, 9, 12, 10, 16, 12, 16, 14, - 26, 34, 40, 38, 29, 18, 13, 41, 45, 48, 40, 37, 32, 40, 37, 32, - 41, 38, 36, 33, 37, 41, 51, 40, 41, 40, 40, 40, 41, 38, 38, 38, - 38, 37, 22, 24, 17, 12, 12, 12, 10, 10, 9, 12, 5, 12, 12, 14, - 16, 17, 20, 37, 42, 37, 29, 17, 4, 37, 52, 26, 33, 40, 53, 28, - 38, 38, 22, 4, 29, 41, 33, 33, 41, 41, 34, 34, 42, 42, 17, 6, - 32, 41, 30, 41, 37, 37, 28, 44, 36, 20, 6, 17, 41, 41, 40, 40, - 44, 45, 42, 44, 45, 44, 24, 8, 53, 77, 73, 57, 56, 68, 69, 51, - 56, 63, 71, 61, 65, 68, 64, 59, 67, 63, 64, 57, 56, 55, 44, 21, - 56, 85, 87, 76, 73, 88, 89, 85, 93, 116, 119, 153, 185, 177, 119, 111, - 103, 115, 106, 61, 52, 52, 53, 52, 49, 52, 51, 91, 112, 170, 131, 135, - 163, 165, 167, 163, 161, 167, 154, 155, 147, 169, 100, 36, 33, 38, 28, 36, - 14, 37, 61, 85, 110, 107, 102, 112, 80, 72, 45, 76, 85, 104, 104, 97, - 80, 73, 69, 65, 65, 51, 40, 52, 59, 49, 53, 51, 51, 44, 45, 44, - 44, 36, 38, 37, 46, 80, 79, 87, 91, 87, 99, 81, 91, 77, 29, 26, - 60, 89, 84, 76, 85, 88, 83, 80, 83, 79, 67, 36, 88, 85, 72, 80, - 80, 79, 79, 81, 76, 73, 72, 69, 75, 73, 71, 72, 71, 68, 65, 65, - 64, 60, 57, 8, 57, 67, 61, 63, 67, 68, 67, 69, 73, 73, 72, 68, - 75, 72, 73, 72, 69, 68, 68, 71, 63, 56, 6, 65, 76, 69, 75, 75, - 80, 83, 81, 84, 87, 89, 89, 76, 88, 96, 89, 79, 99, 96, 84, 68, - 100, 85, 65, 26, 64, 55, 45, 46, 49, 38, 44, 46, 41, 42, 46, 42, - 63, 75, 64, 60, 87, 96, 87, 69, 95, 96, 59, 41, 68, 34, 37, 36, - 34, 29, 30, 32, 32, 25, 24, 33, 24, 22, 22, 28, 26, 26, 29, 33, - 34, 34, 37, 41, 46, 52, 57, 60, 69, 120, 118, 124, 107, 76, 32, 116, - 139, 127, 134, 139, 134, 131, 123, 122, 112, 112, 95, 92, 60, 88, 85, 95, - 102, 95, 72, 68, 60, 55, 72, 28, 57, 49, 48, 67, 68, 79, 100, 79, - 73, 75, 63, 63, 92, 111, 115, 111, 110, 114, 104, 104, 79, 60, 8, 127, - 127, 131, 131, 130, 131, 131, 131, 132, 131, 130, 127, 124, 126, 124, 123, 128, - 126, 127, 124, 124, 122, 122, 110, 40, 102, 104, 119, 114, 115, 107, 87, 103, - 112, 80, 44, 44, 42, 51, 55, 46, 48, 46, 61, 79, 76, 73, 71, 33, - 79, 59, 57, 63, 64, 59, 55, 63, 53, 44, 93, 80, 26, 97, 97, 104, - 116, 169, 146, 124, 138, 162, 162, 170, 177, 183, 189, 198, 202, 210, 206, 174, - 126, 128, 127, 118, 110, 81, 45, 34, 29, 29, 34, 32, 26, 32, 18, 20, - 26, 26, 42, 46, 46, 48, 46, 51, 51, 53, 48, 55, 48, 4, 1, 24, - 49, 48, 36, 41, 37, 18, 16, 17, 14, 16, 13, 8, 14, 30, 38, 52, - 53, 65, 64, 77, 81, 65, 49, 68, 73, 68, 57, 29, 18, 17, 13, 25, - 22, 13, 24, 26, 21, 22, 17, 18, 12, 14, 13, 13, 13, 13, 9, 9, - 8, 9, 6, 8, 8, 8, 6, 8, 8, 8, 6, 9, 17, 45, 59, 67, - 65, 69, 68, 69, 61, 61, 30, 5, 72, 99, 97, 80, 46, 44, 38, 22, - 22, 30, 24, 5, 1, 10, 8, 10, 1, 8, 5, 1, 1, 6, 5, 0, - 0, 8, 1, 1, 1, 2, 1, 1, 4, 6, 8, 1, 1, 4, 13, 1, - 0, 4, 1, 2, 0, 0, 4, 0, 0, 0, 1, 1, 1, 1, 1, 1, - 2, 14, 5, 20, 16, 21, 20, 22, 28, 34, 51, 51, 55, 64, 45, 45, - 37, 41, 37, 34, 34, 29, 26, 40, 33, 36, 22, 55, 59, 57, 67, 79, - 80, 75, 104, 88, 122, 144, 157, 205, 201, 158, 116, 107, 108, 107, 37, 36, - 36, 45, 41, 38, 44, 44, 64, 104, 161, 169, 134, 131, 159, 162, 166, 166, - 171, 153, 153, 166, 159, 96, 32, 30, 32, 21, 6, 25, 34, 36, 42, 32, - 32, 45, 48, 57, 79, 45, 69, 80, 75, 56, 53, 56, 55, 36, 37, 38, - 28, 20, 12, 13, 13, 9, 8, 8, 6, 6, 5, 5, 4, 4, 2, 1, - 1, 1, 0, 0, 0, 6, 8, 12, 10, 14, 16, 22, 26, 34, 33, 37, - 48, 45, 60, 76, 81, 64, 37, 77, 65, 65, 53, 44, 44, 38, 33, 29, - 30, 22, 16, 14, 21, 10, 9, 8, 24, 6, 5, 5, 26, 4, 2, 1, - 4, 2, 1, 1, 4, 4, 4, 6, 9, 6, 9, 13, 14, 4, 8, 22, - 25, 5, 10, 34, 36, 29, 8, 26, 25, 5, 4, 20, 4, 4, 14, 16, - 1, 1, 0, 10, 2, 0, 8, 10, 0, 0, 0, 9, 0, 0, 24, 30, - 37, 68, 102, 80, 91, 112, 124, 116, 99, 72, 48, 84, 123, 120, 103, 110, - 48, 38, 37, 33, 34, 30, 25, 20, 57, 64, 57, 64, 77, 79, 73, 80, - 95, 76, 8, 29, 126, 147, 103, 112, 130, 144, 114, 119, 122, 116, 115, 119, - 135, 135, 120, 79, 60, 72, 75, 106, 77, 33, 83, 88, 88, 85, 92, 91, - 91, 93, 95, 93, 104, 92, 89, 72, 45, 37, 46, 65, 36, 41, 88, 120, - 130, 108, 30, 96, 124, 128, 83, 67, 56, 72, 45, 51, 42, 96, 75, 65, - 59, 56, 60, 59, 63, 68, 76, 68, 60, 38, 48, 88, 93, 97, 93, 100, - 100, 103, 99, 115, 115, 103, 102, 108, 115, 107, 106, 122, 114, 102, 102, 119, - 107, 46, 55, 100, 96, 97, 81, 85, 93, 96, 111, 111, 114, 46, 114, 154, - 151, 130, 144, 140, 139, 99, 87, 84, 51, 37, 20, 45, 69, 92, 87, 92, - 95, 104, 96, 107, 108, 41, 75, 138, 178, 128, 130, 136, 116, 189, 162, 148, - 155, 130, 132, 136, 153, 157, 165, 162, 163, 148, 135, 136, 116, 88, 77, 56, - 36, 32, 30, 29, 33, 38, 45, 52, 59, 65, 72, 6, 64, 159, 157, 151, - 80, 77, 72, 71, 52, 60, 51, 56, 14, 4, 22, 26, 25, 29, 40, 37, - 38, 40, 33, 33, 13, 5, 40, 93, 103, 87, 89, 88, 87, 76, 72, 57, - 73, 79, 79, 81, 71, 85, 83, 75, 64, 53, 25, 26, 12, 16, 21, 30, - 36, 48, 53, 75, 61, 69, 52, 37, 33, 44, 85, 89, 84, 76, 96, 85, - 63, 93, 79, 81, 73, 80, 76, 85, 99, 80, 77, 63, 73, 77, 64, 73, - 63, 33, 8, 72, 96, 93, 87, 96, 96, 75, 84, 48, 32, 24, 37, 53, - 52, 53, 44, 40, 26, 40, 29, 9, 10, 2, 22, 106, 100, 71, 75, 96, - 95, 75, 75, 72, 26, 2, 18, 67, 81, 53, 56, 55, 52, 61, 53, 28, - 12, 45, 60, 61, 48, 45, 48, 48, 45, 44, 36, 32, 4, 6, 87, 104, - 102, 85, 102, 75, 34, 25, 22, 21, 18, 20, 24, 40, 59, 63, 68, 71, - 75, 83, 81, 79, 61, 22, 93, 99, 100, 85, 118, 93, 99, 88, 97, 139, - 154, 210, 213, 201, 185, 126, 111, 106, 116, 36, 34, 37, 36, 38, 32, 33, - 49, 61, 102, 181, 185, 126, 134, 120, 136, 142, 139, 135, 163, 159, 147, 107, - 79, 30, 29, 25, 30, 33, 34, 87, 99, 83, 83, 60, 49, 49, 46, 63, - 33, 30, 38, 55, 57, 60, 52, 55, 53, 76, 72, 73, 77, 120, 120, 130, - 119, 128, 122, 118, 130, 127, 122, 122, 112, 114, 115, 119, 128, 116, 119, 110, - 87, 91, 84, 73, 30, 14, 91, 132, 140, 103, 99, 84, 77, 65, 71, 49, - 56, 40, 46, 61, 63, 65, 52, 61, 68, 91, 61, 55, 61, 102, 135, 139, - 116, 103, 127, 128, 111, 106, 127, 119, 28, 6, 65, 143, 103, 108, 107, 114, - 112, 120, 128, 130, 126, 120, 127, 131, 147, 131, 131, 131, 134, 130, 127, 42, - 14, 37, 120, 150, 115, 120, 124, 126, 126, 132, 136, 138, 136, 131, 142, 155, - 148, 147, 147, 144, 140, 120, 139, 135, 55, 4, 81, 116, 143, 148, 146, 143, - 144, 142, 144, 130, 95, 45, 92, 136, 132, 132, 130, 130, 131, 122, 118, 110, - 60, 48, 118, 139, 140, 140, 140, 135, 102, 112, 128, 96, 88, 8, 135, 136, - 130, 136, 135, 136, 135, 142, 135, 138, 130, 130, 84, 128, 146, 135, 112, 135, - 131, 122, 115, 93, 37, 32, 28, 25, 25, 25, 22, 24, 22, 20, 22, 21, - 25, 24, 34, 114, 134, 126, 122, 136, 123, 114, 138, 147, 114, 32, 112, 143, - 128, 123, 114, 118, 104, 118, 128, 104, 68, 48, 118, 131, 130, 126, 118, 102, - 69, 55, 52, 49, 25, 0, 0, 25, 16, 0, 0, 18, 10, 0, 0, 12, - 8, 1, 6, 8, 8, 5, 21, 8, 9, 12, 33, 13, 16, 53, 104, 116, - 153, 161, 165, 165, 166, 163, 114, 132, 46, 127, 162, 154, 155, 159, 155, 143, - 151, 155, 136, 118, 83, 22, 114, 157, 170, 173, 167, 171, 166, 159, 116, 123, - 37, 181, 185, 179, 177, 171, 183, 179, 175, 107, 118, 100, 115, 112, 122, 142, - 142, 140, 136, 139, 138, 126, 103, 84, 55, 41, 38, 40, 34, 46, 38, 48, - 57, 60, 81, 92, 83, 80, 40, 142, 165, 186, 186, 24, 36, 36, 60, 53, - 60, 46, 57, 18, 4, 32, 30, 44, 22, 36, 38, 22, 42, 44, 32, 14, - 4, 84, 84, 73, 46, 49, 44, 44, 37, 48, 40, 57, 44, 59, 56, 84, - 84, 76, 80, 71, 72, 38, 30, 12, 53, 77, 75, 79, 73, 80, 76, 87, - 102, 64, 56, 57, 42, 63, 99, 88, 68, 73, 89, 99, 103, 99, 83, 81, - 84, 67, 68, 77, 77, 71, 72, 63, 60, 59, 61, 65, 38, 5, 83, 97, - 91, 93, 87, 87, 85, 91, 71, 48, 24, 44, 56, 52, 60, 51, 52, 56, - 67, 57, 25, 4, 12, 81, 103, 91, 85, 85, 87, 92, 92, 89, 85, 32, - 0, 89, 96, 100, 95, 88, 84, 88, 81, 76, 52, 13, 69, 61, 57, 46, - 51, 40, 41, 30, 29, 30, 36, 2, 5, 87, 103, 106, 103, 100, 95, 92, - 99, 91, 87, 73, 81, 65, 79, 97, 91, 96, 93, 107, 110, 103, 93, 61, - 24, 102, 116, 108, 123, 97, 111, 95, 97, 124, 155, 208, 209, 205, 208, 178, - 118, 110, 114, 116, 41, 34, 30, 40, 38, 34, 53, 46, 69, 97, 193, 194, - 131, 128, 135, 130, 104, 112, 110, 95, 89, 97, 87, 63, 26, 28, 25, 37, - 30, 61, 110, 104, 106, 95, 97, 99, 89, 92, 60, 38, 56, 124, 131, 122, - 119, 120, 128, 111, 126, 81, 114, 99, 89, 111, 108, 120, 115, 103, 112, 116, - 103, 106, 111, 103, 107, 102, 76, 75, 92, 81, 75, 81, 79, 81, 73, 32, - 13, 107, 150, 136, 130, 142, 140, 115, 130, 138, 102, 83, 41, 80, 130, 135, - 135, 132, 127, 134, 135, 131, 144, 128, 95, 93, 99, 103, 102, 107, 112, 106, - 118, 112, 124, 73, 9, 143, 138, 91, 107, 130, 127, 135, 110, 130, 139, 135, - 123, 92, 100, 107, 102, 97, 107, 107, 103, 97, 49, 0, 131, 162, 153, 161, - 154, 162, 158, 159, 154, 155, 158, 153, 127, 95, 123, 128, 130, 131, 132, 131, - 123, 123, 122, 56, 32, 106, 134, 143, 131, 128, 135, 132, 132, 132, 139, 99, - 57, 108, 138, 128, 132, 128, 138, 127, 114, 122, 114, 67, 41, 123, 131, 124, - 142, 122, 138, 142, 136, 123, 95, 89, 13, 130, 134, 118, 118, 118, 135, 136, - 138, 134, 138, 108, 73, 115, 147, 142, 135, 135, 136, 136, 132, 92, 103, 42, - 48, 143, 153, 124, 118, 138, 147, 134, 134, 144, 131, 128, 120, 130, 132, 159, - 161, 157, 155, 146, 128, 142, 144, 128, 36, 118, 143, 135, 130, 126, 123, 120, - 106, 110, 83, 55, 88, 167, 171, 179, 165, 171, 163, 157, 148, 122, 71, 32, - 95, 140, 143, 123, 138, 132, 138, 111, 130, 134, 120, 106, 102, 153, 158, 157, - 151, 169, 169, 144, 151, 177, 157, 67, 59, 131, 165, 167, 166, 161, 161, 153, - 161, 124, 122, 49, 128, 163, 147, 154, 155, 159, 159, 157, 157, 155, 146, 107, - 24, 136, 170, 173, 169, 169, 169, 166, 157, 118, 104, 32, 190, 179, 167, 177, - 185, 147, 194, 191, 159, 110, 92, 85, 84, 87, 89, 92, 92, 87, 85, 84, - 69, 56, 48, 42, 40, 36, 42, 45, 46, 55, 63, 76, 80, 91, 89, 92, - 89, 17, 146, 171, 177, 178, 16, 20, 30, 45, 53, 46, 45, 51, 9, 1, - 25, 28, 36, 33, 28, 28, 38, 33, 40, 26, 12, 4, 84, 77, 44, 33, - 45, 44, 67, 52, 33, 36, 48, 37, 56, 72, 48, 68, 71, 69, 71, 68, - 69, 29, 13, 68, 80, 81, 61, 57, 52, 48, 44, 40, 34, 52, 51, 40, - 96, 99, 88, 77, 85, 83, 80, 69, 85, 67, 63, 49, 84, 84, 64, 59, - 56, 61, 61, 63, 52, 60, 53, 36, 5, 76, 87, 81, 93, 87, 85, 77, - 80, 65, 48, 25, 51, 42, 64, 72, 71, 77, 83, 73, 53, 25, 5, 1, - 108, 100, 76, 79, 80, 76, 76, 71, 77, 75, 32, 10, 95, 72, 77, 79, - 83, 89, 88, 89, 71, 63, 17, 63, 52, 44, 37, 24, 16, 36, 25, 17, - 29, 37, 2, 4, 83, 102, 91, 87, 79, 85, 96, 97, 89, 87, 60, 48, - 95, 112, 108, 102, 96, 102, 99, 104, 103, 91, 67, 25, 99, 107, 119, 111, - 135, 116, 96, 106, 130, 183, 210, 209, 206, 202, 146, 115, 112, 111, 106, 32, - 30, 32, 36, 26, 42, 53, 44, 67, 99, 205, 201, 183, 128, 132, 154, 142, - 140, 140, 135, 136, 118, 107, 61, 28, 26, 28, 37, 28, 65, 111, 97, 110, - 103, 100, 96, 100, 88, 67, 36, 97, 115, 111, 116, 116, 112, 106, 103, 93, - 120, 104, 80, 107, 127, 127, 120, 110, 112, 96, 102, 99, 112, 100, 93, 63, - 91, 91, 77, 79, 79, 79, 87, 87, 89, 68, 38, 12, 99, 154, 139, 140, - 132, 132, 142, 140, 144, 144, 93, 44, 108, 140, 143, 138, 144, 134, 139, 135, - 127, 127, 93, 103, 132, 130, 127, 122, 115, 119, 126, 127, 120, 120, 89, 14, - 140, 89, 143, 138, 103, 106, 136, 124, 114, 115, 124, 75, 100, 131, 136, 139, - 132, 128, 131, 116, 115, 52, 24, 136, 162, 154, 143, 144, 150, 154, 153, 155, - 151, 153, 131, 102, 143, 144, 143, 139, 139, 139, 130, 130, 130, 115, 73, 6, - 99, 139, 138, 128, 131, 132, 142, 142, 138, 140, 97, 56, 111, 130, 122, 131, - 118, 124, 116, 119, 131, 114, 63, 38, 116, 127, 126, 136, 132, 144, 142, 138, - 124, 104, 84, 10, 85, 130, 120, 119, 119, 116, 131, 120, 134, 118, 99, 72, - 116, 147, 143, 139, 136, 140, 138, 134, 106, 110, 42, 91, 154, 150, 148, 150, - 153, 148, 150, 148, 139, 135, 134, 87, 132, 162, 154, 148, 153, 150, 148, 151, - 143, 153, 123, 40, 114, 122, 147, 123, 115, 122, 110, 110, 100, 76, 52, 110, - 171, 177, 169, 171, 167, 177, 171, 165, 138, 103, 42, 93, 103, 89, 124, 151, - 162, 95, 91, 134, 108, 89, 112, 140, 123, 158, 167, 177, 167, 162, 162, 165, - 170, 159, 102, 83, 135, 163, 157, 159, 159, 154, 150, 158, 120, 120, 49, 130, - 159, 161, 151, 155, 159, 150, 154, 155, 155, 147, 107, 18, 143, 173, 167, 161, - 148, 163, 162, 153, 120, 102, 25, 154, 182, 165, 183, 187, 178, 178, 126, 165, - 155, 139, 93, 106, 71, 68, 69, 64, 64, 60, 57, 55, 51, 46, 41, 42, - 49, 52, 63, 64, 73, 73, 79, 92, 96, 93, 91, 89, 10, 150, 170, 175, - 166, 72, 61, 55, 18, 22, 49, 40, 52, 9, 1, 28, 33, 38, 55, 33, - 29, 25, 30, 34, 17, 6, 4, 59, 84, 37, 41, 28, 49, 33, 51, 33, - 40, 56, 45, 56, 64, 49, 44, 63, 80, 73, 56, 68, 33, 12, 61, 80, - 53, 55, 48, 44, 44, 37, 34, 44, 37, 21, 14, 97, 96, 84, 88, 75, - 81, 76, 75, 89, 60, 64, 45, 77, 77, 61, 63, 63, 56, 73, 75, 63, - 56, 68, 33, 5, 71, 88, 83, 87, 80, 72, 67, 95, 85, 49, 34, 30, - 51, 52, 71, 63, 45, 55, 63, 49, 0, 4, 1, 69, 99, 73, 80, 76, - 83, 75, 83, 81, 81, 34, 1, 61, 87, 89, 69, 67, 72, 73, 103, 84, - 41, 20, 28, 49, 49, 36, 21, 26, 14, 21, 18, 18, 26, 1, 4, 76, - 97, 102, 80, 73, 77, 80, 79, 75, 60, 63, 52, 110, 111, 102, 122, 95, - 102, 99, 102, 103, 95, 72, 29, 102, 108, 106, 84, 81, 99, 91, 116, 157, - 212, 212, 209, 199, 150, 119, 108, 110, 122, 64, 30, 29, 30, 33, 44, 46, - 56, 55, 81, 104, 208, 210, 195, 128, 132, 135, 153, 157, 158, 157, 151, 142, - 124, 69, 26, 28, 24, 34, 24, 53, 106, 99, 104, 103, 115, 111, 100, 92, - 73, 37, 100, 111, 111, 107, 112, 118, 104, 103, 97, 104, 100, 71, 104, 126, - 104, 103, 118, 106, 106, 100, 99, 103, 107, 92, 59, 89, 106, 102, 95, 83, - 73, 92, 72, 76, 65, 37, 12, 120, 143, 131, 134, 139, 140, 139, 139, 136, - 126, 102, 51, 118, 140, 131, 130, 128, 128, 127, 128, 123, 100, 83, 112, 132, - 119, 122, 124, 126, 123, 124, 123, 123, 127, 64, 13, 73, 134, 99, 130, 132, - 127, 131, 135, 134, 127, 107, 71, 102, 131, 127, 120, 114, 120, 122, 128, 120, - 49, 18, 106, 161, 151, 161, 153, 148, 153, 157, 155, 158, 143, 127, 104, 144, - 150, 135, 139, 140, 136, 140, 142, 134, 106, 71, 4, 93, 136, 135, 124, 128, - 131, 136, 131, 134, 130, 99, 68, 96, 140, 123, 116, 127, 119, 130, 124, 119, - 103, 63, 37, 89, 120, 122, 123, 126, 134, 135, 140, 123, 102, 87, 0, 83, - 135, 115, 123, 120, 119, 127, 119, 134, 111, 89, 55, 120, 146, 143, 143, 127, - 132, 134, 140, 131, 122, 45, 127, 161, 150, 135, 143, 143, 144, 142, 148, 147, - 134, 107, 84, 134, 162, 151, 153, 151, 150, 144, 143, 143, 148, 119, 51, 111, - 128, 123, 124, 116, 111, 112, 108, 99, 75, 48, 91, 166, 174, 167, 171, 171, - 170, 169, 178, 143, 110, 38, 93, 95, 146, 116, 126, 167, 108, 138, 143, 104, - 130, 140, 96, 143, 175, 173, 171, 166, 173, 171, 171, 170, 159, 122, 63, 147, - 162, 162, 153, 150, 148, 136, 161, 124, 124, 64, 130, 163, 167, 155, 143, 144, - 151, 148, 146, 157, 122, 87, 16, 146, 169, 157, 157, 143, 154, 134, 127, 123, - 112, 30, 166, 181, 179, 170, 174, 146, 182, 140, 140, 158, 151, 131, 99, 71, - 67, 64, 63, 57, 53, 49, 49, 46, 45, 41, 55, 63, 69, 72, 84, 123, - 79, 92, 96, 106, 99, 104, 91, 5, 151, 170, 171, 178, 13, 18, 18, 46, - 24, 20, 37, 38, 13, 2, 25, 20, 34, 33, 29, 33, 30, 42, 29, 18, - 17, 4, 64, 73, 52, 29, 48, 34, 34, 30, 36, 46, 44, 37, 60, 69, - 67, 49, 65, 83, 67, 55, 79, 33, 14, 51, 75, 46, 48, 42, 36, 57, - 52, 49, 46, 36, 28, 13, 99, 95, 88, 79, 73, 83, 64, 65, 69, 53, - 56, 42, 80, 79, 63, 67, 64, 69, 52, 61, 72, 56, 59, 34, 6, 73, - 85, 72, 104, 88, 71, 76, 87, 77, 55, 34, 46, 41, 48, 36, 20, 33, - 34, 26, 38, 6, 4, 1, 68, 95, 71, 79, 81, 80, 81, 85, 83, 77, - 33, 1, 68, 81, 80, 76, 69, 67, 68, 83, 77, 44, 20, 57, 67, 26, - 30, 14, 34, 16, 17, 30, 26, 25, 2, 2, 84, 100, 95, 77, 81, 85, - 88, 84, 72, 64, 42, 48, 107, 115, 100, 108, 89, 103, 112, 111, 102, 88, - 68, 36, 88, 99, 107, 89, 81, 93, 81, 114, 193, 208, 209, 204, 157, 124, - 107, 112, 119, 72, 45, 28, 30, 32, 33, 44, 48, 56, 56, 76, 102, 214, - 213, 202, 128, 128, 136, 139, 147, 153, 155, 157, 148, 128, 69, 25, 25, 21, - 37, 21, 59, 107, 96, 102, 100, 112, 112, 99, 104, 64, 38, 89, 111, 118, - 127, 127, 130, 104, 97, 92, 104, 88, 67, 99, 124, 111, 110, 102, 112, 112, - 111, 97, 115, 106, 87, 57, 97, 97, 92, 79, 75, 67, 71, 69, 75, 61, - 32, 9, 119, 146, 146, 130, 148, 136, 132, 135, 130, 132, 100, 61, 104, 139, - 126, 124, 120, 136, 122, 108, 119, 104, 73, 112, 136, 122, 122, 122, 120, 126, - 120, 120, 124, 128, 65, 12, 93, 132, 136, 102, 103, 130, 123, 120, 122, 124, - 108, 65, 96, 143, 134, 111, 128, 139, 128, 116, 115, 46, 0, 128, 155, 158, - 157, 150, 153, 142, 147, 147, 147, 144, 118, 97, 143, 143, 131, 135, 139, 142, - 139, 139, 124, 123, 71, 6, 110, 134, 131, 132, 127, 130, 123, 135, 135, 131, - 107, 65, 103, 134, 119, 119, 128, 128, 127, 130, 126, 104, 71, 32, 107, 124, - 119, 146, 132, 142, 140, 126, 123, 110, 79, 5, 124, 120, 115, 120, 115, 112, - 122, 115, 138, 115, 87, 59, 116, 144, 148, 142, 144, 136, 131, 131, 130, 112, - 55, 97, 157, 159, 148, 147, 140, 130, 134, 134, 135, 97, 87, 59, 130, 157, - 146, 144, 139, 132, 140, 143, 150, 146, 116, 57, 103, 140, 123, 116, 122, 131, - 122, 126, 95, 85, 42, 96, 175, 175, 165, 174, 171, 167, 166, 174, 132, 110, - 38, 87, 96, 103, 136, 135, 123, 135, 143, 124, 130, 144, 140, 36, 136, 173, - 167, 173, 177, 167, 177, 178, 177, 166, 111, 68, 139, 161, 140, 139, 147, 146, - 155, 143, 161, 136, 65, 131, 159, 163, 153, 154, 158, 154, 146, 153, 148, 144, - 114, 13, 132, 173, 158, 161, 143, 148, 138, 122, 124, 123, 26, 182, 186, 177, - 175, 148, 143, 157, 167, 144, 134, 155, 148, 130, 69, 104, 97, 96, 99, 99, - 95, 91, 99, 100, 84, 52, 61, 77, 89, 127, 127, 127, 107, 110, 111, 108, - 103, 95, 57, 158, 169, 173, 163, 75, 75, 40, 41, 48, 40, 37, 59, 17, - 2, 13, 30, 36, 25, 45, 26, 29, 24, 30, 17, 8, 2, 64, 79, 46, - 51, 49, 37, 46, 45, 38, 45, 38, 33, 53, 60, 60, 38, 65, 72, 64, - 52, 76, 33, 16, 53, 75, 53, 56, 32, 37, 55, 42, 40, 40, 37, 41, - 30, 103, 104, 73, 87, 57, 73, 67, 69, 65, 61, 60, 44, 79, 72, 64, - 67, 73, 56, 65, 69, 69, 53, 59, 36, 5, 69, 80, 87, 80, 91, 68, - 73, 97, 71, 55, 29, 51, 60, 38, 46, 52, 46, 45, 32, 21, 14, 4, - 9, 75, 96, 85, 83, 85, 91, 93, 85, 88, 75, 33, 0, 79, 83, 64, - 77, 76, 67, 69, 72, 67, 55, 25, 52, 60, 44, 26, 18, 32, 10, 18, - 20, 18, 24, 1, 2, 89, 99, 96, 87, 85, 80, 89, 95, 77, 63, 46, - 61, 115, 108, 106, 96, 85, 103, 104, 95, 91, 89, 67, 37, 91, 103, 110, - 93, 104, 79, 75, 111, 199, 210, 205, 165, 124, 104, 126, 64, 61, 44, 29, - 29, 28, 34, 32, 37, 46, 51, 60, 87, 127, 213, 213, 205, 126, 126, 134, - 136, 139, 143, 153, 157, 148, 126, 60, 24, 22, 21, 29, 26, 64, 106, 96, - 100, 100, 115, 103, 106, 84, 73, 49, 89, 120, 111, 123, 115, 114, 119, 111, - 91, 102, 88, 64, 103, 124, 120, 96, 122, 103, 106, 97, 114, 108, 102, 77, - 61, 81, 96, 85, 76, 68, 65, 71, 69, 79, 56, 33, 8, 120, 146, 130, - 130, 139, 148, 139, 130, 142, 135, 104, 63, 96, 140, 130, 122, 138, 128, 115, - 120, 107, 92, 65, 112, 139, 122, 128, 132, 130, 134, 136, 127, 122, 124, 75, - 21, 96, 128, 134, 106, 126, 131, 128, 123, 127, 120, 107, 61, 95, 132, 130, - 123, 120, 119, 120, 116, 118, 51, 0, 120, 155, 157, 158, 154, 155, 151, 150, - 148, 147, 142, 81, 110, 146, 138, 131, 140, 146, 139, 130, 120, 119, 118, 67, - 40, 122, 135, 132, 130, 127, 135, 128, 138, 136, 135, 110, 77, 108, 140, 118, - 112, 126, 130, 130, 119, 116, 104, 71, 29, 103, 118, 134, 139, 131, 139, 128, - 126, 124, 110, 84, 22, 116, 118, 107, 112, 107, 112, 136, 111, 127, 114, 84, - 56, 108, 146, 144, 143, 146, 142, 123, 130, 123, 114, 60, 91, 155, 147, 148, - 130, 135, 142, 154, 134, 135, 102, 92, 95, 132, 155, 147, 142, 140, 150, 144, - 148, 150, 146, 128, 60, 111, 130, 124, 114, 107, 122, 112, 128, 104, 79, 46, - 112, 174, 174, 167, 175, 169, 169, 173, 174, 146, 110, 40, 97, 92, 102, 131, - 118, 130, 157, 115, 126, 110, 139, 99, 29, 144, 173, 174, 178, 177, 171, 169, - 171, 169, 163, 115, 75, 134, 163, 139, 130, 147, 134, 155, 158, 143, 139, 67, - 124, 165, 159, 154, 157, 143, 150, 146, 135, 146, 144, 111, 13, 140, 170, 166, - 161, 142, 134, 124, 123, 124, 110, 32, 186, 181, 178, 151, 173, 174, 132, 167, - 138, 158, 155, 154, 130, 71, 110, 114, 123, 120, 114, 114, 111, 119, 106, 83, - 55, 67, 76, 123, 114, 127, 124, 116, 116, 110, 112, 111, 103, 14, 155, 170, - 169, 155, 30, 53, 57, 51, 45, 36, 38, 37, 12, 0, 25, 25, 30, 32, - 22, 21, 25, 25, 26, 17, 8, 2, 56, 67, 37, 34, 37, 37, 44, 42, - 40, 28, 38, 26, 57, 59, 57, 33, 60, 51, 49, 51, 59, 32, 17, 33, - 67, 52, 61, 41, 44, 53, 56, 57, 52, 34, 42, 29, 103, 88, 80, 91, - 65, 83, 64, 69, 63, 65, 59, 46, 76, 72, 65, 55, 60, 53, 71, 59, - 65, 53, 49, 34, 5, 75, 69, 68, 81, 80, 71, 72, 80, 71, 56, 29, - 41, 34, 42, 30, 25, 26, 40, 40, 9, 4, 4, 2, 73, 96, 73, 79, - 95, 93, 79, 84, 89, 75, 34, 12, 83, 80, 65, 79, 73, 64, 71, 69, - 72, 64, 29, 57, 53, 64, 28, 21, 44, 16, 16, 17, 30, 22, 1, 1, - 88, 88, 99, 87, 83, 69, 87, 95, 79, 67, 45, 71, 119, 106, 95, 92, - 91, 107, 96, 88, 80, 81, 73, 38, 85, 103, 102, 102, 77, 77, 87, 106, - 194, 204, 175, 126, 107, 111, 63, 42, 30, 28, 26, 28, 28, 32, 28, 38, - 49, 53, 75, 93, 175, 216, 214, 208, 126, 126, 134, 138, 138, 143, 153, 154, - 146, 120, 38, 24, 22, 13, 29, 25, 64, 104, 93, 102, 102, 110, 103, 104, - 85, 67, 42, 95, 110, 115, 114, 107, 100, 100, 100, 97, 95, 75, 59, 100, - 122, 123, 104, 108, 97, 111, 111, 114, 106, 96, 79, 56, 87, 95, 85, 84, - 87, 88, 85, 80, 80, 48, 33, 8, 95, 146, 131, 130, 118, 142, 148, 136, - 134, 134, 104, 69, 97, 136, 124, 132, 127, 136, 114, 116, 108, 88, 68, 123, - 140, 127, 126, 136, 131, 134, 127, 126, 122, 116, 91, 25, 112, 127, 131, 110, - 124, 130, 126, 126, 122, 120, 102, 55, 89, 135, 130, 135, 120, 124, 131, 122, - 115, 52, 14, 123, 157, 163, 138, 135, 153, 150, 148, 140, 143, 138, 71, 106, - 148, 139, 136, 139, 150, 146, 134, 127, 111, 110, 76, 9, 107, 136, 128, 126, - 124, 134, 134, 136, 135, 138, 114, 68, 100, 135, 123, 136, 107, 104, 122, 124, - 119, 103, 65, 25, 104, 112, 112, 143, 131, 127, 127, 124, 126, 111, 83, 22, - 77, 110, 108, 104, 110, 110, 140, 108, 123, 111, 83, 46, 114, 142, 154, 144, - 151, 146, 136, 126, 122, 107, 61, 97, 153, 146, 146, 118, 138, 136, 143, 136, - 115, 106, 91, 84, 136, 153, 136, 144, 144, 130, 127, 136, 131, 134, 126, 60, - 108, 127, 127, 114, 118, 111, 116, 111, 110, 73, 45, 119, 166, 174, 163, 167, - 171, 167, 170, 174, 127, 106, 46, 96, 92, 106, 128, 120, 115, 130, 118, 122, - 119, 95, 123, 59, 144, 173, 177, 182, 167, 171, 175, 175, 173, 161, 118, 79, - 132, 159, 155, 147, 147, 144, 143, 144, 123, 131, 71, 106, 108, 159, 143, 153, - 155, 154, 148, 150, 146, 143, 108, 9, 140, 169, 165, 158, 147, 139, 161, 118, - 134, 111, 28, 134, 182, 169, 162, 161, 155, 150, 150, 169, 147, 159, 158, 124, - 67, 108, 122, 128, 128, 128, 122, 111, 115, 110, 107, 71, 83, 93, 134, 136, - 130, 123, 108, 116, 118, 110, 111, 99, 6, 161, 166, 170, 159, 14, 63, 68, - 40, 41, 48, 32, 34, 9, 0, 14, 30, 36, 29, 26, 30, 38, 40, 20, - 13, 4, 2, 49, 61, 38, 65, 36, 51, 42, 36, 44, 38, 41, 28, 45, - 77, 46, 33, 63, 57, 53, 53, 63, 36, 18, 29, 65, 45, 63, 34, 46, - 38, 44, 60, 45, 33, 22, 6, 100, 91, 76, 71, 80, 69, 79, 73, 71, - 61, 60, 42, 76, 71, 59, 63, 52, 53, 60, 63, 59, 55, 52, 34, 5, - 71, 83, 77, 83, 77, 61, 71, 76, 79, 57, 44, 33, 44, 61, 52, 46, - 52, 28, 22, 9, 0, 2, 1, 64, 92, 88, 80, 83, 92, 81, 87, 77, - 65, 36, 1, 60, 79, 61, 80, 73, 77, 59, 68, 81, 52, 33, 17, 51, - 52, 22, 22, 32, 17, 12, 21, 18, 20, 0, 0, 84, 95, 96, 88, 87, - 89, 89, 87, 76, 61, 48, 75, 118, 93, 103, 103, 97, 97, 96, 108, 102, - 77, 72, 40, 85, 99, 104, 102, 97, 89, 75, 99, 181, 208, 171, 114, 95, - 104, 52, 40, 29, 26, 32, 28, 26, 33, 29, 55, 51, 49, 77, 107, 191, - 222, 217, 210, 127, 126, 132, 138, 142, 147, 153, 151, 138, 93, 26, 22, 22, - 20, 32, 25, 65, 99, 93, 102, 104, 97, 107, 99, 68, 75, 42, 87, 107, - 107, 106, 104, 104, 114, 102, 97, 102, 87, 53, 104, 115, 132, 110, 104, 106, - 108, 110, 111, 95, 93, 57, 73, 79, 87, 83, 80, 77, 81, 71, 75, 77, - 56, 38, 6, 128, 146, 131, 124, 120, 126, 127, 131, 127, 123, 115, 80, 102, - 140, 124, 136, 128, 128, 102, 118, 91, 91, 63, 116, 136, 123, 126, 130, 140, - 126, 128, 124, 120, 112, 72, 22, 69, 99, 128, 123, 132, 123, 124, 132, 123, - 114, 91, 52, 79, 122, 127, 138, 134, 132, 118, 119, 122, 51, 10, 112, 158, - 158, 153, 151, 144, 150, 144, 144, 148, 118, 63, 118, 144, 140, 128, 139, 151, - 136, 130, 120, 116, 100, 83, 6, 93, 136, 127, 116, 127, 126, 126, 136, 130, - 128, 107, 84, 96, 132, 122, 122, 131, 102, 103, 104, 108, 104, 60, 24, 92, - 103, 108, 139, 139, 136, 130, 123, 128, 111, 87, 21, 81, 115, 103, 100, 103, - 107, 115, 119, 107, 108, 73, 36, 112, 138, 150, 140, 144, 144, 140, 122, 123, - 112, 64, 84, 140, 140, 167, 132, 142, 118, 112, 122, 95, 91, 91, 64, 138, - 151, 142, 139, 143, 136, 140, 132, 134, 127, 123, 64, 99, 127, 127, 120, 118, - 104, 122, 119, 108, 75, 38, 118, 165, 170, 171, 173, 171, 161, 171, 175, 136, - 106, 37, 97, 93, 135, 118, 111, 116, 153, 124, 127, 104, 100, 135, 60, 154, - 166, 178, 175, 174, 170, 171, 166, 166, 165, 140, 81, 110, 161, 150, 150, 132, - 140, 126, 120, 139, 128, 80, 93, 142, 163, 155, 153, 148, 150, 150, 151, 139, - 124, 81, 8, 130, 159, 163, 158, 162, 151, 136, 119, 135, 115, 24, 166, 181, - 162, 171, 163, 165, 154, 151, 151, 144, 158, 157, 132, 65, 120, 127, 134, 126, - 130, 108, 123, 124, 127, 106, 68, 76, 142, 132, 134, 128, 130, 127, 123, 130, - 112, 112, 102, 1, 150, 169, 158, 161, 24, 48, 73, 64, 36, 30, 33, 32, - 10, 1, 20, 26, 33, 40, 45, 34, 26, 24, 17, 9, 4, 4, 46, 55, - 61, 42, 65, 55, 44, 44, 40, 48, 33, 24, 49, 59, 51, 48, 30, 40, - 44, 40, 38, 37, 18, 33, 51, 42, 51, 53, 51, 48, 45, 45, 45, 45, - 24, 13, 91, 84, 57, 57, 69, 84, 81, 64, 83, 59, 55, 38, 64, 72, - 64, 57, 61, 57, 57, 60, 51, 53, 56, 34, 6, 69, 72, 48, 63, 61, - 45, 46, 63, 57, 60, 45, 28, 34, 21, 33, 16, 20, 18, 22, 21, 0, - 2, 8, 63, 88, 69, 75, 77, 76, 77, 89, 83, 59, 36, 1, 59, 77, - 64, 76, 77, 69, 68, 72, 69, 55, 24, 13, 30, 24, 30, 22, 30, 26, - 32, 25, 29, 18, 0, 0, 88, 99, 87, 89, 92, 106, 96, 83, 67, 64, - 34, 87, 118, 108, 112, 102, 104, 97, 84, 89, 95, 89, 73, 42, 81, 97, - 106, 100, 96, 75, 71, 84, 138, 209, 174, 122, 103, 106, 57, 44, 29, 36, - 37, 30, 32, 30, 32, 37, 51, 72, 95, 150, 212, 222, 221, 205, 128, 127, - 134, 139, 147, 153, 154, 148, 127, 52, 24, 21, 18, 21, 37, 22, 60, 97, - 97, 108, 103, 107, 104, 100, 81, 69, 41, 56, 102, 107, 89, 96, 93, 84, - 102, 100, 97, 80, 51, 92, 111, 114, 114, 108, 108, 108, 107, 107, 100, 87, - 52, 59, 87, 93, 97, 89, 87, 77, 89, 81, 67, 48, 26, 5, 128, 143, - 138, 102, 102, 99, 112, 92, 108, 111, 106, 84, 84, 123, 128, 124, 124, 123, - 100, 116, 87, 84, 52, 104, 131, 126, 126, 130, 127, 126, 123, 123, 123, 122, - 67, 21, 103, 126, 144, 126, 132, 130, 122, 120, 114, 112, 97, 46, 73, 85, - 118, 127, 132, 122, 128, 118, 119, 44, 28, 115, 144, 151, 147, 143, 146, 148, - 147, 144, 139, 115, 55, 112, 119, 143, 144, 148, 142, 132, 124, 120, 107, 114, - 65, 4, 124, 130, 127, 112, 124, 122, 119, 116, 115, 116, 116, 87, 65, 116, - 135, 108, 114, 93, 104, 108, 114, 107, 83, 18, 97, 106, 127, 132, 127, 131, - 128, 128, 127, 119, 84, 29, 85, 99, 99, 95, 93, 87, 96, 99, 102, 104, - 73, 33, 75, 132, 144, 144, 135, 127, 115, 123, 123, 112, 72, 73, 104, 136, - 132, 134, 108, 112, 108, 112, 120, 83, 76, 41, 136, 147, 131, 139, 143, 139, - 139, 132, 142, 128, 124, 79, 79, 132, 123, 122, 119, 106, 106, 119, 110, 76, - 51, 107, 167, 163, 171, 171, 170, 169, 171, 174, 124, 106, 38, 100, 103, 130, - 123, 106, 106, 102, 110, 126, 102, 120, 136, 18, 135, 161, 163, 173, 162, 169, - 154, 170, 163, 169, 131, 85, 111, 143, 135, 136, 142, 131, 134, 140, 122, 132, - 103, 89, 139, 146, 148, 116, 119, 123, 144, 148, 130, 127, 119, 6, 135, 161, - 167, 159, 153, 157, 155, 130, 134, 124, 21, 181, 186, 157, 167, 170, 161, 159, - 167, 167, 155, 157, 155, 126, 64, 103, 120, 119, 123, 124, 122, 115, 122, 123, - 106, 68, 76, 138, 131, 135, 130, 143, 139, 120, 114, 112, 114, 107, 59, 162, - 163, 162, 153, 22, 29, 34, 42, 51, 44, 44, 24, 9, 1, 14, 18, 21, - 18, 17, 18, 17, 18, 17, 12, 4, 1, 40, 59, 61, 64, 52, 46, 48, - 49, 48, 45, 28, 20, 46, 46, 52, 52, 55, 41, 45, 41, 37, 37, 34, - 32, 24, 24, 24, 22, 26, 25, 26, 28, 28, 30, 34, 18, 102, 81, 73, - 79, 69, 69, 71, 71, 71, 64, 60, 41, 76, 73, 59, 60, 56, 48, 52, - 45, 49, 49, 53, 33, 6, 67, 69, 64, 63, 60, 76, 57, 56, 48, 61, - 29, 22, 30, 17, 14, 13, 12, 13, 12, 10, 8, 2, 1, 45, 87, 80, - 80, 77, 87, 83, 85, 69, 69, 37, 1, 56, 73, 64, 56, 77, 76, 71, - 59, 61, 45, 40, 32, 20, 20, 13, 8, 5, 5, 6, 5, 4, 5, 0, - 1, 96, 96, 96, 89, 88, 84, 81, 80, 55, 56, 34, 80, 112, 106, 96, - 91, 92, 92, 84, 83, 84, 80, 75, 45, 55, 87, 93, 89, 79, 56, 76, - 72, 112, 193, 195, 153, 99, 126, 93, 51, 44, 37, 42, 38, 38, 41, 46, - 44, 76, 84, 128, 204, 221, 221, 222, 199, 127, 127, 134, 143, 150, 155, 150, - 136, 75, 24, 21, 20, 20, 20, 28, 30, 56, 87, 91, 92, 91, 89, 84, - 81, 87, 81, 52, 60, 100, 108, 87, 91, 96, 92, 93, 95, 84, 76, 48, - 72, 104, 110, 93, 89, 104, 107, 93, 95, 95, 76, 46, 56, 61, 53, 53, - 52, 61, 55, 46, 45, 36, 40, 24, 6, 114, 132, 139, 132, 124, 124, 128, - 130, 122, 123, 118, 118, 118, 85, 93, 97, 99, 99, 119, 118, 108, 85, 48, - 99, 130, 127, 130, 123, 124, 124, 127, 122, 120, 116, 80, 32, 100, 106, 110, - 112, 111, 111, 118, 110, 111, 96, 95, 41, 72, 80, 115, 112, 110, 108, 107, - 107, 100, 51, 0, 28, 79, 93, 83, 80, 92, 104, 96, 89, 103, 91, 41, - 64, 72, 81, 85, 97, 99, 95, 100, 99, 115, 103, 59, 36, 126, 127, 130, - 131, 123, 119, 123, 122, 116, 116, 110, 112, 81, 85, 93, 100, 99, 95, 118, - 118, 92, 108, 81, 16, 93, 96, 140, 128, 127, 130, 127, 126, 122, 120, 91, - 2, 72, 97, 84, 83, 87, 93, 95, 104, 100, 104, 63, 30, 56, 123, 123, - 111, 111, 119, 120, 107, 110, 115, 106, 67, 81, 100, 104, 89, 89, 100, 91, - 85, 97, 89, 81, 76, 132, 147, 143, 140, 136, 140, 140, 134, 135, 139, 132, - 79, 72, 112, 120, 123, 115, 93, 111, 112, 111, 77, 38, 115, 169, 166, 167, - 173, 167, 175, 169, 171, 143, 104, 37, 99, 99, 119, 99, 115, 100, 96, 103, - 97, 100, 104, 108, 33, 128, 151, 144, 120, 126, 136, 136, 136, 123, 116, 112, - 130, 138, 131, 134, 135, 130, 138, 135, 139, 130, 131, 130, 92, 99, 107, 108, - 118, 110, 116, 111, 135, 126, 126, 111, 4, 130, 153, 154, 157, 157, 161, 150, - 123, 130, 119, 25, 178, 179, 163, 162, 163, 154, 153, 154, 157, 155, 151, 140, - 120, 64, 108, 108, 126, 122, 128, 128, 130, 124, 123, 106, 68, 85, 140, 132, - 118, 116, 119, 116, 119, 118, 115, 112, 111, 10, 159, 158, 161, 153, 10, 10, - 12, 12, 12, 13, 14, 9, 4, 0, 14, 14, 13, 5, 13, 12, 9, 9, - 16, 13, 8, 1, 24, 56, 53, 49, 46, 29, 25, 22, 30, 26, 25, 17, - 28, 30, 29, 28, 26, 29, 29, 26, 26, 25, 25, 22, 25, 16, 10, 8, - 9, 14, 5, 2, 4, 4, 4, 16, 99, 63, 76, 36, 71, 68, 63, 36, - 65, 61, 56, 40, 69, 71, 51, 46, 42, 41, 36, 38, 38, 38, 29, 14, - 9, 34, 29, 30, 28, 26, 29, 28, 28, 25, 24, 21, 17, 13, 12, 13, - 10, 9, 8, 10, 6, 6, 5, 0, 18, 64, 69, 48, 53, 73, 67, 60, - 63, 61, 34, 16, 48, 64, 67, 61, 53, 52, 49, 46, 42, 44, 18, 10, - 6, 5, 10, 18, 24, 16, 8, 10, 10, 9, 1, 0, 85, 56, 69, 65, - 68, 72, 73, 79, 56, 51, 32, 72, 88, 95, 91, 85, 88, 84, 80, 77, - 81, 87, 77, 75, 75, 73, 52, 56, 72, 71, 63, 68, 77, 174, 202, 166, - 119, 116, 116, 81, 49, 37, 49, 48, 45, 42, 48, 72, 84, 123, 193, 218, - 221, 224, 220, 170, 126, 130, 136, 148, 151, 151, 142, 102, 32, 21, 20, 18, - 21, 22, 26, 30, 40, 73, 75, 71, 61, 75, 75, 65, 67, 73, 63, 57, - 89, 80, 81, 68, 68, 64, 63, 65, 67, 75, 41, 34, 33, 48, 41, 41, - 42, 49, 55, 72, 83, 59, 42, 44, 48, 48, 44, 42, 42, 42, 33, 33, - 34, 25, 30, 4, 18, 81, 95, 81, 84, 89, 103, 93, 97, 99, 99, 97, - 92, 103, 106, 107, 107, 112, 111, 112, 97, 84, 59, 85, 120, 122, 124, 111, - 110, 107, 106, 93, 102, 96, 73, 34, 59, 63, 57, 61, 63, 67, 68, 73, - 72, 73, 69, 42, 61, 33, 37, 38, 30, 26, 25, 30, 29, 28, 8, 8, - 14, 32, 13, 13, 26, 42, 22, 24, 40, 45, 52, 45, 17, 36, 41, 44, - 57, 79, 61, 76, 89, 87, 75, 0, 45, 76, 84, 84, 84, 89, 92, 84, - 85, 91, 84, 89, 83, 99, 91, 100, 95, 99, 77, 103, 88, 106, 77, 41, - 81, 89, 130, 124, 124, 123, 122, 112, 118, 118, 76, 37, 68, 48, 56, 37, - 38, 40, 53, 26, 24, 30, 49, 28, 34, 34, 44, 42, 48, 52, 57, 65, - 71, 91, 103, 103, 107, 108, 97, 99, 97, 96, 95, 92, 89, 89, 80, 71, - 134, 132, 131, 128, 111, 118, 124, 123, 112, 112, 99, 102, 100, 104, 115, 102, - 96, 91, 89, 85, 88, 64, 36, 111, 134, 158, 161, 153, 150, 150, 155, 147, - 122, 96, 48, 103, 93, 107, 103, 103, 95, 99, 97, 99, 93, 99, 120, 41, - 44, 48, 37, 34, 59, 73, 80, 85, 93, 115, 123, 116, 99, 122, 126, 122, - 123, 122, 127, 123, 130, 124, 119, 115, 135, 134, 127, 115, 131, 126, 126, 97, - 130, 130, 107, 4, 91, 128, 151, 107, 116, 130, 148, 127, 122, 115, 22, 128, - 174, 161, 153, 153, 153, 147, 140, 102, 93, 83, 72, 64, 72, 65, 76, 114, - 118, 112, 127, 124, 132, 119, 120, 93, 91, 111, 114, 110, 116, 114, 102, 84, - 128, 83, 75, 64, 38, 97, 100, 132, 134, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 4, 9, 2, 0, 42, - 12, 12, 10, 12, 20, 14, 9, 9, 18, 16, 9, 6, 5, 6, 5, 5, - 4, 6, 5, 5, 4, 5, 4, 5, 22, 38, 42, 41, 44, 73, 61, 76, - 59, 32, 4, 108, 68, 83, 63, 52, 48, 48, 46, 55, 56, 56, 37, 34, - 34, 34, 29, 26, 24, 18, 17, 14, 14, 9, 9, 9, 8, 6, 6, 5, - 5, 4, 4, 2, 2, 2, 1, 1, 5, 5, 1, 0, 1, 2, 0, 0, - 1, 2, 0, 16, 12, 12, 16, 14, 33, 59, 36, 42, 52, 32, 1, 44, - 14, 20, 16, 17, 13, 17, 13, 16, 9, 8, 9, 12, 24, 51, 44, 60, - 65, 71, 60, 72, 68, 42, 0, 97, 84, 84, 73, 68, 64, 64, 51, 61, - 52, 30, 59, 59, 64, 60, 60, 61, 64, 64, 64, 61, 68, 64, 63, 63, - 42, 33, 33, 34, 42, 73, 72, 77, 123, 190, 182, 123, 87, 157, 108, 85, - 85, 89, 91, 91, 89, 88, 111, 161, 204, 220, 222, 221, 221, 212, 140, 127, - 134, 147, 150, 147, 140, 111, 37, 22, 21, 18, 18, 24, 25, 14, 30, 41, - 37, 42, 46, 48, 48, 49, 51, 56, 65, 67, 60, 64, 52, 53, 59, 52, - 57, 64, 83, 77, 80, 48, 59, 106, 110, 99, 89, 69, 71, 69, 64, 41, - 34, 37, 6, 0, 26, 5, 4, 5, 17, 0, 4, 4, 0, 0, 25, 28, - 20, 17, 17, 24, 22, 20, 21, 25, 28, 28, 29, 33, 36, 41, 49, 52, - 57, 60, 67, 71, 80, 59, 64, 83, 80, 57, 59, 63, 60, 44, 44, 51, - 37, 25, 6, 21, 8, 33, 36, 18, 13, 28, 29, 17, 17, 26, 28, 76, - 92, 104, 108, 103, 116, 110, 112, 84, 79, 5, 21, 143, 157, 107, 104, 132, - 146, 92, 112, 114, 60, 29, 57, 136, 136, 87, 88, 92, 68, 68, 63, 79, - 46, 33, 9, 6, 5, 40, 10, 6, 10, 34, 22, 12, 20, 44, 37, 36, - 38, 52, 51, 46, 83, 72, 60, 59, 100, 57, 17, 75, 34, 44, 36, 41, - 34, 34, 30, 33, 21, 18, 37, 26, 51, 68, 77, 81, 88, 107, 104, 102, - 103, 85, 22, 107, 142, 150, 122, 135, 102, 84, 77, 52, 52, 44, 44, 57, - 48, 65, 37, 42, 63, 45, 57, 64, 68, 69, 57, 102, 93, 120, 110, 104, - 95, 112, 110, 104, 100, 104, 102, 95, 68, 48, 46, 41, 42, 40, 42, 41, - 53, 37, 40, 56, 67, 60, 89, 95, 87, 64, 100, 108, 71, 41, 87, 83, - 79, 77, 77, 71, 76, 87, 96, 103, 106, 142, 12, 61, 170, 170, 115, 119, - 110, 108, 95, 79, 45, 28, 22, 20, 18, 17, 16, 14, 13, 12, 10, 9, - 40, 38, 6, 4, 49, 40, 2, 1, 40, 26, 0, 4, 36, 1, 2, 46, - 48, 65, 68, 69, 72, 79, 84, 124, 118, 24, 128, 166, 115, 106, 102, 99, - 99, 107, 104, 99, 119, 111, 104, 81, 95, 106, 95, 65, 60, 56, 60, 73, - 89, 83, 81, 72, 72, 69, 73, 76, 71, 60, 57, 57, 51, 36, 34, 32, - 29, 25, 24, 18, 33, 40, 40, 24, 38, 21, 32, 26, 1, 0, 14, 49, - 48, 32, 32, 34, 25, 18, 10, 5, 0, 1, 6, 33, 36, 28, 36, 42, - 63, 52, 42, 36, 24, 5, 48, 65, 67, 57, 42, 60, 46, 59, 55, 51, - 17, 4, 60, 102, 95, 92, 91, 85, 85, 84, 92, 67, 30, 6, 108, 68, - 73, 108, 100, 84, 67, 73, 53, 38, 20, 32, 38, 44, 45, 52, 51, 49, - 59, 63, 59, 38, 59, 55, 104, 106, 106, 107, 114, 108, 102, 107, 115, 102, - 87, 83, 103, 99, 93, 102, 100, 95, 84, 79, 95, 75, 17, 1, 63, 103, - 102, 79, 64, 48, 38, 34, 18, 13, 10, 1, 10, 45, 51, 56, 48, 59, - 61, 65, 63, 67, 42, 1, 53, 114, 126, 130, 126, 124, 108, 118, 107, 80, - 42, 0, 93, 84, 100, 96, 104, 96, 93, 81, 69, 52, 29, 12, 10, 10, - 10, 13, 13, 12, 16, 14, 14, 14, 20, 21, 24, 65, 71, 89, 87, 85, - 115, 108, 91, 81, 132, 190, 139, 95, 120, 134, 130, 143, 139, 127, 134, 147, - 158, 198, 216, 218, 222, 222, 220, 220, 159, 128, 132, 144, 146, 142, 134, 96, - 36, 22, 21, 18, 25, 21, 18, 26, 41, 45, 56, 88, 103, 96, 79, 77, - 64, 60, 60, 51, 46, 44, 71, 104, 122, 116, 128, 100, 102, 112, 91, 84, - 45, 83, 130, 115, 97, 97, 112, 103, 106, 77, 73, 67, 9, 18, 144, 142, - 106, 97, 111, 111, 107, 99, 119, 97, 49, 13, 40, 96, 115, 108, 111, 112, - 120, 110, 111, 108, 102, 88, 107, 111, 119, 115, 111, 85, 67, 53, 37, 38, - 45, 34, 38, 71, 67, 81, 75, 85, 87, 96, 95, 88, 76, 10, 29, 85, - 96, 102, 96, 93, 96, 93, 97, 100, 93, 104, 89, 120, 136, 140, 136, 136, - 132, 119, 114, 85, 10, 131, 143, 130, 140, 132, 138, 131, 139, 135, 115, 72, - 22, 127, 147, 150, 135, 138, 144, 138, 108, 126, 128, 87, 73, 9, 24, 155, - 151, 102, 97, 148, 147, 112, 95, 118, 116, 65, 21, 67, 144, 140, 87, 88, - 84, 79, 71, 65, 57, 9, 24, 61, 68, 72, 69, 84, 89, 87, 92, 99, - 89, 0, 55, 153, 157, 154, 157, 158, 153, 150, 150, 118, 89, 21, 116, 153, - 144, 146, 153, 153, 153, 150, 134, 103, 87, 20, 56, 177, 170, 110, 106, 103, - 96, 84, 51, 26, 37, 22, 22, 21, 25, 21, 22, 20, 21, 18, 22, 21, - 22, 21, 30, 38, 103, 123, 128, 128, 114, 142, 130, 85, 40, 91, 154, 151, - 142, 92, 95, 44, 34, 34, 25, 29, 20, 61, 80, 150, 153, 153, 158, 154, - 162, 158, 158, 128, 139, 17, 139, 187, 182, 178, 187, 178, 178, 177, 177, 171, - 167, 136, 130, 161, 143, 140, 144, 157, 151, 153, 146, 139, 79, 0, 37, 136, - 181, 106, 135, 144, 171, 110, 147, 140, 52, 1, 135, 159, 154, 111, 154, 148, - 151, 88, 79, 114, 24, 134, 122, 143, 150, 159, 169, 167, 162, 165, 173, 169, - 140, 100, 87, 108, 139, 140, 136, 136, 136, 112, 88, 79, 85, 57, 69, 83, - 97, 102, 111, 112, 116, 124, 134, 135, 140, 139, 150, 157, 162, 166, 169, 83, - 59, 68, 60, 53, 55, 21, 28, 4, 0, 40, 34, 57, 51, 42, 46, 42, - 41, 36, 33, 6, 1, 51, 83, 84, 79, 76, 64, 80, 77, 67, 38, 28, - 6, 65, 63, 53, 44, 41, 63, 48, 45, 42, 49, 20, 2, 81, 99, 71, - 76, 85, 100, 77, 80, 59, 68, 33, 10, 116, 88, 65, 60, 45, 65, 77, - 97, 104, 92, 73, 88, 106, 93, 96, 103, 93, 95, 99, 89, 96, 80, 89, - 76, 71, 102, 88, 73, 83, 85, 75, 67, 64, 68, 84, 57, 72, 88, 104, - 108, 93, 93, 83, 76, 85, 84, 41, 0, 81, 97, 123, 85, 91, 67, 76, - 75, 68, 53, 32, 8, 69, 112, 108, 108, 100, 99, 64, 85, 88, 72, 48, - 1, 103, 127, 110, 96, 83, 106, 95, 87, 89, 77, 41, 0, 110, 80, 88, - 93, 89, 88, 89, 91, 79, 67, 29, 34, 110, 92, 84, 88, 103, 103, 85, - 84, 81, 79, 76, 72, 77, 72, 115, 122, 119, 106, 104, 106, 97, 71, 84, - 179, 157, 106, 84, 165, 173, 182, 195, 204, 208, 210, 214, 217, 221, 221, 216, - 220, 213, 163, 132, 138, 143, 138, 135, 107, 63, 33, 24, 21, 18, 25, 18, - 28, 36, 49, 42, 40, 79, 119, 134, 124, 123, 126, 134, 130, 134, 112, 102, - 104, 114, 127, 127, 115, 107, 115, 107, 104, 99, 88, 52, 79, 130, 124, 111, - 100, 99, 95, 107, 115, 84, 72, 0, 146, 150, 131, 134, 130, 131, 128, 111, - 108, 104, 102, 108, 12, 143, 139, 128, 130, 123, 128, 118, 119, 120, 123, 119, - 95, 76, 116, 123, 118, 114, 99, 100, 111, 116, 73, 40, 68, 126, 128, 134, - 120, 130, 128, 126, 116, 118, 107, 79, 6, 139, 135, 143, 138, 128, 126, 119, - 111, 115, 111, 93, 95, 138, 157, 154, 144, 144, 136, 138, 140, 114, 89, 5, - 148, 140, 140, 134, 130, 128, 127, 127, 132, 124, 76, 25, 140, 154, 138, 123, - 131, 126, 142, 139, 128, 116, 89, 83, 2, 158, 159, 153, 95, 110, 143, 140, - 115, 115, 118, 120, 75, 24, 139, 151, 138, 136, 139, 134, 147, 104, 84, 96, - 8, 72, 146, 159, 162, 154, 151, 146, 144, 147, 143, 106, 28, 139, 162, 159, - 154, 146, 140, 147, 150, 147, 138, 99, 18, 132, 159, 132, 147, 140, 142, 143, - 148, 148, 134, 97, 16, 153, 182, 153, 148, 158, 154, 150, 110, 132, 128, 127, - 128, 140, 159, 143, 140, 144, 147, 147, 142, 147, 148, 127, 124, 134, 132, 118, - 126, 134, 131, 155, 150, 143, 96, 41, 108, 169, 155, 148, 153, 131, 143, 140, - 118, 112, 88, 69, 126, 161, 171, 178, 173, 173, 170, 171, 162, 158, 140, 122, - 30, 158, 183, 191, 181, 185, 179, 148, 143, 144, 134, 127, 163, 163, 159, 120, - 124, 158, 158, 123, 127, 128, 153, 91, 0, 135, 181, 167, 165, 163, 158, 163, - 161, 162, 161, 89, 2, 147, 159, 166, 169, 174, 169, 170, 162, 104, 122, 28, - 167, 142, 166, 171, 170, 166, 147, 161, 167, 162, 136, 136, 99, 79, 124, 138, - 132, 138, 134, 135, 134, 130, 119, 92, 64, 81, 126, 166, 173, 179, 171, 167, - 150, 150, 135, 147, 155, 127, 130, 140, 178, 154, 112, 92, 61, 75, 87, 65, - 85, 22, 0, 0, 42, 49, 56, 51, 29, 32, 4, 24, 22, 26, 8, 2, - 69, 89, 73, 65, 63, 65, 71, 81, 75, 41, 25, 6, 67, 71, 83, 96, - 75, 87, 73, 71, 52, 49, 22, 2, 69, 96, 69, 69, 55, 59, 63, 56, - 44, 46, 29, 9, 115, 85, 80, 48, 59, 59, 61, 64, 45, 69, 81, 76, - 55, 53, 64, 64, 65, 46, 42, 67, 49, 52, 81, 57, 103, 87, 93, 88, - 75, 83, 80, 83, 79, 67, 71, 53, 96, 119, 102, 84, 95, 91, 89, 95, - 89, 83, 45, 1, 85, 100, 127, 83, 72, 88, 63, 80, 64, 56, 36, 21, - 88, 107, 95, 102, 102, 91, 87, 91, 88, 84, 48, 0, 100, 128, 75, 84, - 91, 91, 83, 107, 84, 89, 45, 0, 104, 76, 85, 84, 81, 84, 83, 85, - 83, 63, 30, 102, 103, 99, 85, 73, 92, 99, 88, 80, 93, 81, 93, 76, - 52, 112, 126, 112, 92, 85, 91, 106, 107, 68, 65, 138, 166, 114, 79, 118, - 123, 142, 162, 187, 199, 208, 210, 209, 210, 217, 201, 178, 155, 127, 138, 135, - 120, 99, 63, 34, 24, 25, 22, 21, 22, 20, 25, 34, 45, 42, 48, 46, - 79, 120, 132, 132, 131, 126, 122, 126, 128, 107, 104, 80, 128, 126, 106, 108, - 118, 119, 116, 108, 81, 102, 49, 76, 119, 115, 108, 108, 106, 99, 104, 107, - 87, 72, 14, 150, 148, 144, 126, 119, 119, 116, 106, 106, 106, 118, 108, 12, - 142, 127, 122, 123, 132, 127, 124, 132, 122, 120, 103, 60, 104, 151, 132, 122, - 119, 114, 114, 123, 118, 79, 55, 118, 124, 120, 116, 115, 123, 130, 115, 114, - 104, 99, 89, 25, 140, 124, 127, 131, 143, 136, 124, 119, 112, 102, 72, 123, - 159, 143, 135, 144, 135, 123, 115, 122, 97, 84, 0, 106, 139, 132, 122, 115, - 122, 131, 131, 142, 120, 77, 18, 127, 151, 131, 127, 107, 119, 123, 128, 115, - 92, 95, 84, 6, 150, 128, 147, 135, 138, 130, 127, 132, 128, 144, 124, 80, - 22, 146, 153, 135, 131, 128, 127, 127, 132, 92, 106, 10, 130, 158, 157, 151, - 138, 153, 151, 146, 131, 131, 99, 18, 143, 161, 148, 144, 140, 130, 128, 126, - 126, 120, 96, 16, 130, 153, 146, 148, 146, 132, 139, 138, 143, 142, 99, 22, - 143, 170, 171, 170, 162, 154, 132, 161, 127, 119, 108, 114, 147, 158, 167, 142, - 148, 153, 153, 147, 139, 146, 146, 127, 87, 154, 165, 155, 155, 144, 143, 143, - 138, 106, 38, 107, 167, 157, 154, 150, 144, 150, 143, 146, 118, 92, 73, 135, - 174, 169, 166, 165, 165, 166, 165, 169, 170, 124, 135, 24, 153, 178, 190, 187, - 185, 167, 167, 185, 182, 179, 175, 114, 104, 161, 165, 151, 147, 143, 144, 139, - 143, 144, 93, 32, 174, 177, 163, 167, 162, 167, 169, 167, 161, 161, 93, 0, - 143, 159, 163, 159, 157, 158, 154, 162, 120, 124, 30, 178, 153, 142, 167, 161, - 159, 159, 163, 151, 144, 150, 139, 75, 102, 135, 136, 134, 130, 128, 130, 128, - 132, 119, 84, 55, 116, 186, 191, 179, 178, 177, 153, 169, 161, 146, 147, 130, - 122, 183, 195, 206, 209, 30, 37, 79, 65, 24, 48, 81, 21, 0, 0, 36, - 65, 51, 20, 20, 29, 29, 17, 0, 22, 5, 2, 53, 93, 69, 76, 65, - 60, 59, 61, 81, 44, 28, 12, 38, 76, 75, 55, 67, 83, 79, 45, 45, - 49, 21, 2, 89, 91, 89, 67, 75, 77, 61, 75, 51, 67, 33, 2, 108, - 92, 79, 48, 40, 49, 67, 60, 63, 59, 53, 59, 49, 81, 57, 56, 69, - 63, 65, 64, 61, 49, 44, 32, 103, 89, 91, 84, 69, 72, 64, 61, 81, - 72, 63, 53, 114, 115, 85, 77, 73, 83, 88, 80, 79, 97, 41, 0, 89, - 107, 111, 67, 73, 87, 80, 96, 95, 77, 38, 6, 106, 106, 110, 92, 104, - 97, 88, 91, 87, 71, 49, 0, 95, 122, 73, 87, 81, 97, 100, 103, 88, - 72, 45, 0, 104, 85, 88, 93, 91, 81, 83, 81, 87, 68, 29, 102, 97, - 89, 93, 100, 96, 85, 89, 88, 81, 80, 69, 46, 68, 119, 118, 111, 87, - 91, 93, 83, 104, 71, 60, 120, 166, 115, 75, 87, 104, 116, 123, 131, 155, - 167, 177, 174, 170, 166, 146, 132, 132, 126, 107, 84, 52, 36, 24, 21, 20, - 20, 26, 17, 20, 34, 34, 41, 44, 52, 48, 42, 83, 136, 138, 135, 116, - 122, 111, 110, 99, 97, 68, 112, 134, 106, 110, 127, 111, 107, 103, 108, 87, - 100, 60, 63, 119, 116, 108, 120, 102, 111, 106, 106, 93, 71, 12, 100, 143, - 130, 134, 144, 127, 122, 118, 107, 104, 108, 69, 16, 102, 120, 126, 132, 126, - 124, 115, 118, 119, 103, 93, 61, 111, 147, 122, 119, 130, 138, 135, 123, 110, - 81, 41, 116, 132, 124, 118, 116, 112, 126, 120, 106, 102, 96, 88, 5, 119, - 119, 130, 116, 135, 144, 138, 119, 115, 93, 53, 120, 161, 143, 140, 142, 134, - 119, 119, 111, 104, 92, 2, 122, 144, 144, 114, 124, 128, 124, 136, 134, 131, - 81, 17, 131, 151, 128, 124, 120, 122, 116, 106, 115, 96, 89, 88, 5, 114, - 128, 106, 138, 139, 132, 132, 130, 130, 126, 122, 89, 21, 132, 146, 128, 127, - 138, 140, 138, 132, 112, 108, 2, 139, 161, 146, 146, 146, 138, 135, 131, 124, - 127, 99, 8, 138, 161, 148, 136, 143, 128, 126, 128, 126, 127, 99, 13, 128, - 154, 154, 146, 155, 154, 153, 142, 143, 118, 102, 20, 138, 169, 174, 169, 171, - 163, 173, 174, 169, 162, 106, 143, 169, 155, 142, 135, 142, 142, 140, 123, 127, - 134, 118, 77, 96, 170, 167, 142, 153, 153, 157, 136, 138, 114, 51, 107, 163, - 155, 150, 158, 157, 151, 150, 147, 124, 99, 72, 136, 177, 169, 163, 165, 170, - 170, 163, 162, 167, 123, 136, 9, 150, 175, 179, 186, 189, 166, 169, 177, 179, - 175, 171, 106, 140, 170, 159, 140, 151, 139, 144, 138, 140, 143, 95, 0, 127, - 171, 166, 165, 157, 163, 162, 167, 167, 155, 96, 0, 154, 159, 155, 163, 161, - 159, 154, 162, 158, 130, 32, 177, 140, 148, 170, 161, 167, 161, 155, 155, 147, - 148, 144, 71, 81, 136, 138, 131, 132, 134, 131, 126, 132, 124, 91, 55, 161, - 190, 177, 173, 174, 139, 162, 177, 169, 155, 154, 102, 127, 189, 206, 187, 163, - 72, 72, 83, 26, 40, 48, 68, 16, 0, 1, 33, 63, 52, 6, 16, 18, - 36, 1, 0, 29, 1, 1, 44, 83, 72, 65, 77, 85, 59, 56, 67, 46, - 29, 8, 77, 87, 75, 55, 61, 76, 77, 49, 46, 49, 22, 2, 76, 89, - 61, 73, 76, 65, 71, 64, 52, 52, 32, 4, 106, 81, 76, 45, 48, 48, - 71, 64, 63, 55, 45, 64, 73, 72, 77, 72, 48, 52, 63, 49, 53, 61, - 65, 28, 100, 100, 89, 69, 72, 63, 81, 61, 73, 69, 67, 57, 111, 112, - 68, 68, 73, 77, 63, 76, 77, 76, 42, 1, 89, 103, 119, 79, 88, 72, - 63, 64, 89, 55, 38, 0, 93, 97, 116, 96, 104, 92, 91, 88, 71, 80, - 49, 0, 107, 120, 83, 96, 93, 93, 84, 100, 95, 83, 45, 0, 96, 96, - 88, 88, 87, 83, 83, 81, 83, 65, 33, 65, 85, 104, 92, 80, 96, 85, - 84, 89, 84, 77, 68, 41, 96, 120, 115, 106, 97, 84, 89, 95, 108, 80, - 59, 111, 166, 127, 95, 67, 69, 69, 76, 95, 115, 119, 123, 127, 123, 122, - 119, 93, 71, 51, 37, 28, 25, 25, 21, 18, 21, 25, 18, 36, 40, 41, - 42, 48, 51, 52, 52, 44, 76, 130, 120, 110, 95, 108, 111, 110, 97, 79, - 68, 118, 127, 106, 119, 111, 112, 97, 96, 114, 99, 103, 65, 53, 110, 115, - 106, 104, 107, 103, 97, 100, 83, 73, 9, 103, 142, 139, 148, 131, 99, 97, - 108, 99, 114, 115, 73, 13, 110, 130, 124, 128, 114, 118, 118, 119, 106, 106, - 96, 57, 111, 151, 130, 116, 118, 112, 110, 127, 111, 80, 42, 100, 132, 124, - 128, 124, 114, 120, 108, 103, 104, 92, 87, 4, 110, 128, 130, 116, 130, 140, - 136, 115, 103, 93, 53, 122, 163, 131, 132, 123, 132, 119, 122, 106, 110, 88, - 5, 136, 143, 138, 115, 122, 130, 132, 127, 132, 126, 85, 12, 143, 153, 127, - 120, 120, 107, 119, 119, 100, 99, 96, 83, 2, 122, 155, 143, 140, 136, 132, - 127, 136, 130, 132, 122, 81, 13, 132, 148, 127, 130, 128, 128, 124, 131, 95, - 104, 2, 138, 158, 138, 147, 136, 131, 134, 124, 130, 106, 99, 22, 147, 159, - 144, 135, 127, 132, 123, 123, 115, 128, 97, 12, 128, 151, 154, 140, 139, 143, - 138, 138, 142, 124, 104, 13, 147, 177, 171, 179, 163, 169, 163, 167, 162, 158, - 75, 143, 161, 155, 148, 143, 138, 138, 135, 134, 135, 119, 128, 75, 148, 175, - 174, 140, 159, 148, 150, 135, 135, 120, 60, 107, 169, 159, 155, 157, 159, 148, - 148, 150, 144, 95, 51, 123, 173, 161, 155, 155, 158, 161, 158, 150, 170, 138, - 136, 12, 162, 179, 178, 186, 181, 171, 166, 166, 185, 173, 170, 95, 143, 173, - 154, 142, 146, 135, 132, 138, 134, 140, 99, 0, 132, 174, 163, 161, 161, 162, - 161, 153, 161, 146, 106, 0, 144, 157, 162, 162, 167, 163, 155, 158, 130, 131, - 40, 179, 146, 150, 171, 158, 171, 157, 155, 161, 150, 148, 134, 65, 104, 138, - 136, 124, 126, 120, 119, 119, 130, 114, 75, 89, 163, 189, 170, 169, 174, 150, - 147, 159, 144, 143, 144, 95, 161, 195, 197, 163, 163, 80, 83, 22, 30, 45, - 34, 60, 34, 2, 0, 37, 68, 53, 10, 8, 16, 29, 1, 0, 24, 2, - 1, 40, 89, 76, 71, 52, 68, 72, 57, 60, 61, 33, 10, 75, 76, 73, - 65, 44, 49, 60, 44, 46, 45, 21, 1, 76, 92, 65, 67, 67, 64, 77, - 68, 53, 56, 34, 5, 110, 93, 72, 44, 45, 48, 48, 53, 65, 60, 42, - 84, 85, 72, 71, 49, 49, 73, 83, 49, 71, 67, 71, 41, 111, 84, 69, - 64, 71, 60, 81, 59, 80, 67, 56, 60, 115, 103, 68, 76, 60, 73, 80, - 96, 75, 75, 46, 0, 85, 106, 119, 77, 77, 75, 65, 64, 99, 53, 41, - 5, 100, 112, 99, 87, 99, 81, 81, 88, 72, 83, 51, 1, 103, 126, 83, - 81, 91, 89, 93, 100, 93, 77, 46, 0, 99, 89, 89, 96, 83, 83, 85, - 79, 75, 65, 36, 67, 88, 93, 91, 89, 96, 85, 77, 81, 76, 83, 72, - 34, 97, 120, 118, 92, 100, 81, 92, 103, 93, 87, 56, 102, 163, 135, 106, - 87, 69, 59, 53, 53, 48, 48, 46, 48, 51, 45, 41, 37, 30, 30, 28, - 26, 22, 22, 21, 25, 14, 24, 41, 48, 55, 56, 55, 52, 51, 53, 55, - 44, 77, 135, 111, 115, 115, 111, 102, 122, 110, 96, 51, 112, 128, 106, 123, - 104, 95, 95, 93, 110, 102, 102, 69, 37, 111, 122, 124, 120, 119, 114, 107, - 99, 88, 73, 2, 103, 135, 124, 139, 99, 93, 106, 108, 100, 104, 110, 100, - 8, 142, 135, 114, 136, 118, 107, 106, 108, 106, 120, 100, 56, 118, 142, 126, - 124, 112, 112, 107, 120, 115, 83, 46, 99, 130, 142, 151, 120, 110, 104, 106, - 104, 108, 102, 83, 0, 153, 123, 124, 116, 128, 126, 136, 116, 104, 99, 51, - 122, 162, 143, 138, 120, 130, 118, 119, 103, 115, 97, 0, 146, 143, 144, 116, - 120, 120, 136, 136, 135, 131, 85, 16, 142, 155, 128, 120, 116, 107, 104, 122, - 97, 103, 97, 91, 4, 165, 163, 142, 147, 123, 132, 143, 124, 122, 134, 122, - 87, 10, 139, 148, 127, 127, 128, 158, 134, 136, 95, 106, 1, 139, 159, 139, - 144, 131, 136, 126, 124, 127, 132, 103, 30, 143, 158, 134, 143, 127, 126, 128, - 127, 120, 134, 100, 9, 131, 154, 147, 138, 139, 143, 155, 140, 138, 135, 106, - 10, 148, 182, 171, 173, 163, 159, 161, 162, 163, 151, 71, 146, 169, 148, 162, - 153, 143, 139, 135, 127, 130, 122, 128, 65, 150, 170, 166, 143, 162, 159, 134, - 140, 118, 106, 56, 110, 170, 151, 154, 155, 143, 142, 139, 144, 148, 97, 61, - 128, 173, 169, 158, 151, 151, 144, 153, 155, 167, 146, 132, 12, 166, 186, 185, - 183, 166, 165, 166, 166, 182, 166, 170, 87, 147, 171, 155, 136, 144, 136, 132, - 139, 142, 143, 97, 0, 148, 171, 166, 163, 159, 165, 162, 165, 155, 147, 100, - 1, 153, 158, 158, 154, 157, 169, 158, 161, 138, 130, 48, 170, 153, 153, 140, - 134, 175, 155, 151, 154, 158, 138, 135, 61, 104, 122, 134, 132, 140, 135, 135, - 126, 128, 108, 68, 108, 182, 186, 169, 170, 167, 150, 165, 165, 146, 146, 142, - 92, 159, 195, 173, 175, 174, 81, 65, 20, 34, 42, 29, 60, 14, 0, 0, - 24, 60, 44, 12, 20, 8, 37, 1, 17, 34, 4, 0, 20, 71, 83, 65, - 71, 65, 51, 46, 60, 67, 26, 12, 52, 81, 55, 67, 72, 52, 65, 48, - 45, 59, 24, 2, 76, 89, 52, 55, 85, 64, 59, 49, 44, 46, 34, 2, - 107, 92, 87, 46, 49, 45, 49, 48, 63, 59, 42, 89, 80, 73, 52, 48, - 60, 99, 49, 52, 52, 65, 84, 38, 99, 77, 75, 72, 68, 63, 88, 59, - 72, 64, 37, 65, 116, 116, 69, 103, 67, 67, 81, 102, 72, 71, 52, 0, - 84, 99, 107, 76, 85, 72, 67, 61, 95, 57, 42, 13, 96, 112, 92, 92, - 83, 79, 104, 88, 79, 75, 53, 0, 100, 127, 73, 93, 91, 85, 88, 107, - 84, 76, 46, 0, 95, 88, 92, 87, 75, 80, 81, 80, 85, 63, 37, 65, - 103, 75, 88, 91, 100, 87, 96, 93, 65, 88, 63, 30, 108, 127, 115, 102, - 99, 80, 83, 103, 89, 88, 56, 95, 157, 140, 116, 106, 93, 84, 61, 52, - 48, 44, 41, 40, 37, 36, 34, 32, 30, 28, 26, 26, 25, 26, 26, 12, - 22, 42, 57, 61, 57, 64, 65, 65, 68, 57, 59, 52, 72, 144, 116, 104, - 118, 112, 111, 107, 107, 102, 42, 114, 120, 106, 106, 106, 95, 111, 102, 100, - 100, 106, 72, 32, 96, 119, 126, 108, 104, 100, 103, 99, 89, 75, 10, 115, - 134, 127, 134, 95, 96, 115, 99, 100, 112, 116, 106, 8, 138, 128, 116, 135, - 111, 110, 111, 102, 100, 119, 97, 45, 112, 155, 123, 115, 116, 116, 111, 123, - 114, 84, 52, 91, 138, 140, 122, 111, 120, 104, 119, 116, 114, 102, 92, 17, - 147, 115, 131, 112, 126, 110, 146, 114, 106, 96, 51, 123, 161, 135, 140, 124, - 124, 127, 107, 104, 103, 93, 0, 126, 142, 143, 115, 128, 116, 124, 127, 138, - 118, 87, 10, 139, 155, 131, 126, 118, 116, 115, 119, 103, 95, 103, 89, 2, - 158, 170, 139, 142, 124, 135, 131, 135, 120, 124, 119, 88, 14, 134, 155, 130, - 131, 146, 147, 136, 128, 97, 106, 10, 143, 159, 131, 138, 126, 126, 127, 132, - 127, 131, 106, 13, 143, 159, 143, 144, 138, 142, 139, 140, 122, 135, 104, 6, - 136, 148, 143, 143, 162, 139, 135, 138, 142, 143, 111, 18, 179, 179, 173, 167, - 162, 171, 161, 163, 162, 158, 77, 151, 159, 161, 153, 159, 148, 138, 138, 127, - 128, 122, 123, 59, 157, 175, 163, 140, 153, 147, 136, 134, 139, 111, 60, 112, - 173, 150, 147, 143, 139, 136, 138, 143, 143, 100, 89, 126, 173, 173, 157, 150, - 139, 161, 151, 144, 165, 142, 135, 10, 162, 185, 182, 181, 169, 165, 163, 167, - 171, 167, 166, 83, 154, 175, 150, 138, 135, 131, 130, 138, 128, 150, 102, 22, - 170, 175, 163, 162, 165, 162, 157, 163, 155, 148, 108, 0, 161, 163, 158, 159, - 158, 157, 159, 161, 132, 138, 55, 155, 157, 147, 166, 158, 174, 153, 153, 162, - 159, 143, 128, 46, 110, 128, 122, 126, 124, 131, 130, 120, 130, 97, 65, 114, - 191, 178, 167, 169, 163, 165, 167, 185, 158, 155, 142, 83, 169, 194, 171, 179, - 181, 87, 26, 16, 40, 30, 25, 81, 12, 0, 0, 26, 42, 55, 14, 38, - 12, 28, 1, 5, 21, 6, 2, 28, 61, 83, 80, 77, 48, 81, 59, 56, - 73, 28, 12, 29, 81, 79, 55, 55, 56, 41, 56, 51, 46, 25, 1, 87, - 99, 55, 55, 52, 64, 69, 45, 45, 49, 34, 1, 107, 93, 83, 46, 42, - 44, 69, 51, 51, 55, 38, 92, 65, 55, 48, 57, 92, 55, 52, 59, 65, - 53, 65, 21, 102, 83, 65, 68, 59, 61, 91, 56, 71, 61, 44, 80, 118, - 102, 73, 100, 72, 63, 73, 106, 69, 67, 51, 0, 83, 87, 118, 75, 73, - 63, 68, 63, 110, 69, 52, 5, 99, 115, 85, 85, 77, 77, 103, 83, 77, - 69, 56, 0, 88, 126, 85, 81, 83, 84, 81, 106, 77, 76, 45, 0, 103, - 77, 85, 77, 75, 75, 80, 77, 79, 65, 38, 32, 67, 112, 89, 83, 68, - 81, 69, 71, 69, 91, 67, 28, 120, 123, 120, 89, 107, 83, 81, 102, 83, - 85, 60, 83, 144, 138, 140, 108, 103, 92, 80, 67, 63, 52, 48, 42, 38, - 38, 36, 38, 36, 40, 36, 36, 34, 30, 40, 10, 40, 61, 63, 61, 79, - 76, 83, 88, 87, 60, 59, 44, 71, 150, 115, 126, 92, 118, 126, 93, 104, - 99, 44, 107, 120, 107, 110, 99, 95, 119, 102, 103, 99, 110, 76, 36, 100, - 118, 119, 108, 100, 102, 103, 102, 88, 75, 8, 118, 131, 124, 146, 93, 96, - 106, 96, 100, 102, 107, 73, 8, 102, 124, 108, 143, 115, 114, 110, 103, 104, - 122, 99, 40, 111, 155, 118, 115, 118, 111, 119, 110, 108, 87, 49, 103, 136, - 144, 111, 111, 104, 115, 112, 106, 103, 99, 91, 2, 131, 119, 126, 111, 131, - 108, 134, 114, 104, 93, 32, 118, 161, 139, 143, 124, 122, 114, 112, 108, 107, - 92, 0, 131, 135, 154, 112, 119, 118, 118, 126, 140, 123, 88, 8, 142, 159, - 132, 135, 114, 122, 112, 127, 104, 93, 100, 92, 0, 130, 139, 116, 151, 124, - 134, 124, 134, 120, 126, 118, 88, 12, 139, 159, 130, 126, 146, 132, 132, 130, - 114, 110, 0, 142, 154, 139, 124, 123, 126, 122, 144, 128, 139, 110, 5, 130, - 158, 153, 135, 139, 135, 132, 130, 119, 139, 107, 6, 134, 150, 140, 157, 165, - 150, 135, 138, 139, 131, 112, 13, 161, 174, 178, 163, 161, 174, 159, 159, 158, - 159, 71, 158, 169, 147, 155, 153, 147, 131, 151, 128, 127, 131, 122, 53, 159, - 171, 142, 162, 134, 136, 143, 138, 139, 122, 76, 84, 167, 148, 143, 142, 132, - 143, 126, 143, 146, 108, 68, 122, 169, 177, 155, 142, 138, 165, 151, 143, 171, - 135, 139, 6, 166, 186, 178, 165, 163, 161, 169, 181, 171, 161, 170, 67, 157, - 170, 161, 136, 135, 126, 132, 139, 138, 139, 107, 0, 136, 171, 155, 155, 155, - 161, 157, 165, 147, 165, 107, 0, 153, 161, 158, 155, 151, 159, 158, 157, 153, - 148, 60, 102, 182, 147, 153, 154, 169, 153, 150, 161, 166, 143, 123, 36, 111, - 126, 123, 123, 122, 124, 122, 119, 131, 96, 59, 123, 183, 170, 163, 169, 155, - 167, 154, 181, 167, 165, 142, 71, 170, 197, 173, 182, 167, 87, 21, 24, 29, - 33, 24, 83, 12, 0, 0, 16, 33, 63, 8, 48, 8, 22, 0, 12, 5, - 10, 1, 10, 51, 89, 85, 89, 44, 77, 95, 38, 81, 25, 13, 12, 95, - 85, 42, 41, 44, 60, 60, 44, 44, 25, 1, 91, 102, 57, 46, 51, 51, - 46, 46, 45, 49, 36, 1, 107, 95, 93, 46, 45, 46, 51, 52, 49, 48, - 33, 97, 59, 51, 46, 93, 69, 48, 53, 56, 67, 57, 52, 18, 88, 85, - 63, 57, 57, 61, 102, 55, 67, 60, 41, 91, 122, 108, 69, 103, 59, 68, - 73, 108, 68, 68, 55, 0, 75, 83, 118, 63, 77, 63, 72, 63, 131, 57, - 49, 0, 110, 115, 81, 83, 75, 75, 111, 79, 73, 71, 55, 0, 80, 124, - 80, 81, 77, 75, 83, 118, 81, 81, 48, 0, 91, 83, 81, 73, 72, 83, - 76, 77, 72, 60, 41, 38, 67, 115, 115, 69, 83, 75, 64, 69, 65, 107, - 64, 24, 116, 127, 131, 92, 114, 112, 79, 95, 84, 77, 59, 77, 131, 140, - 131, 128, 107, 97, 89, 83, 75, 65, 52, 52, 51, 48, 46, 46, 34, 37, - 36, 33, 30, 30, 45, 8, 42, 65, 55, 77, 71, 71, 89, 107, 104, 81, - 59, 53, 63, 153, 110, 131, 93, 124, 108, 97, 102, 87, 37, 110, 116, 104, - 108, 99, 96, 128, 97, 104, 96, 123, 83, 40, 102, 112, 100, 102, 103, 103, - 97, 104, 89, 72, 1, 120, 120, 120, 158, 93, 95, 100, 95, 102, 100, 112, - 84, 4, 110, 128, 110, 143, 112, 114, 106, 104, 99, 130, 92, 33, 114, 165, - 115, 116, 115, 108, 106, 107, 106, 87, 55, 91, 139, 118, 111, 108, 108, 107, - 110, 114, 107, 96, 89, 2, 144, 119, 122, 110, 140, 107, 146, 108, 100, 87, - 30, 115, 161, 130, 148, 118, 118, 119, 108, 100, 112, 97, 1, 148, 135, 146, - 111, 122, 139, 140, 126, 147, 127, 92, 5, 155, 166, 135, 135, 112, 116, 115, - 138, 116, 91, 104, 92, 0, 134, 158, 138, 151, 124, 130, 127, 142, 116, 130, - 119, 93, 6, 143, 154, 130, 128, 150, 128, 136, 128, 103, 110, 0, 146, 163, - 136, 123, 128, 114, 120, 150, 130, 111, 107, 4, 131, 157, 161, 135, 134, 131, - 127, 114, 118, 150, 108, 5, 132, 146, 142, 157, 173, 136, 135, 138, 140, 146, - 119, 8, 166, 182, 182, 163, 155, 178, 155, 155, 155, 155, 44, 165, 167, 162, - 147, 163, 147, 134, 143, 124, 127, 120, 126, 38, 167, 171, 143, 169, 131, 142, - 139, 138, 138, 122, 84, 71, 169, 148, 143, 132, 154, 143, 128, 143, 139, 107, - 72, 96, 144, 182, 154, 144, 134, 159, 147, 138, 165, 144, 132, 6, 169, 189, - 179, 161, 161, 161, 166, 181, 169, 163, 169, 52, 162, 170, 162, 134, 130, 123, - 131, 131, 131, 135, 114, 0, 131, 171, 146, 147, 146, 155, 157, 171, 147, 150, - 115, 0, 150, 159, 161, 155, 151, 153, 154, 161, 157, 135, 104, 68, 182, 162, - 151, 159, 167, 155, 147, 161, 151, 153, 118, 29, 102, 127, 128, 140, 116, 124, - 116, 119, 131, 89, 48, 127, 186, 165, 163, 170, 153, 170, 162, 175, 154, 157, - 146, 56, 182, 194, 167, 167, 166 }; diff --git a/applications/plugins/CImgPlugin/extlibs/CImg/examples/img/logo.bmp b/applications/plugins/CImgPlugin/extlibs/CImg/examples/img/logo.bmp deleted file mode 100644 index 4b21da3965d391489a4182fb7e799c9c3f1dc5b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90534 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�|K8zQTYLvtnJ)hI&wb?v&;0N#^gP;^Y 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