class Parameters extends ProjectiveTransformer.Parameters {
        protected Parameters() {
            identityColorParameters = new double[numGains + numBiases];
            if (numGains > 0) {
                A = CvMat.create(3, 3);
                cvSetIdentity(A);
            }
            if (numBiases > 0) {
                b = CvMat.create(3, 1);
                cvSetZero(b);
            }

            switch (numGains) {
                case 0: assert (A == null); break;
                case 1: identityColorParameters[0] =
                            (A.get(0) + A.get(4) + A.get(8))/3; break;
                case 3: identityColorParameters[0] = A.get(0);
                        identityColorParameters[1] = A.get(4);
                        identityColorParameters[2] = A.get(8); break;
                case 9: A.get(0, identityColorParameters, 0, 9); break;
                default: assert (false);
            }
            switch (numBiases) {
                case 0: assert (b == null); break;
                case 1: identityColorParameters[numGains] =
                            (b.get(0) + b.get(1) + b.get(2))/3;   break;
                case 3: b.get(0, identityColorParameters, numGains, 3); break;
                default: assert (false);
            }

            reset(false);
        }

        protected double[] colorParameters = null, identityColorParameters = null;
        private CvMat A = null, b = null;

        public double[] getColorParameters() {
            return colorParameters;
        }
        public double[] getIdentityColorParameters() {
            return identityColorParameters;
        }

        @Override public int size() {
            return super.size() + numGains + numBiases;
        }
        @Override public double get(int i) {
            int s = super.size();
            if (i < s) {
                return super.get(i);
            } else {
                return colorParameters[i-s];
            }
        }
        @Override public void set(int i, double p) {
            int s = super.size();
            if (i < s) {
                super.set(i, p);
            } else {
                if (colorParameters[i-s] != p) {
                    colorParameters[i-s] = p;
                    setUpdateNeeded(true);
                }
            }
        }
        @Override public void reset(boolean asIdentity) {
            super.reset(asIdentity);
            resetColor(asIdentity);
        }
        public void resetColor(boolean asIdentity) {
            if (identityColorParameters != null) {
                if (!Arrays.equals(colorParameters, identityColorParameters) ||
                        fakeIdentity != asIdentity) {
                    fakeIdentity = asIdentity;
                    colorParameters = identityColorParameters.clone();
                    setUpdateNeeded(true);
                }
            }
        }
//        @Override public boolean addDelta(int i, double scale) {
//            int s = super.size();
//            if (i < s) {
//                return super.addDelta(i, scale);
//            } else {
//                // gradient varies linearly with intensity, so
//                // the increment value is not very important, but
//                // referenceCameraImage is good only for the value 1,
//                // so let's use that
//                int channel = i-s;
//                colorParameters[channel] += scale;//1;
//                setUpdateNeeded(true);
//                return false;
//            }
//        }
        @Override public void compose(ImageTransformer.Parameters p1, boolean inverse1,
                ImageTransformer.Parameters p2, boolean inverse2) {
            super.compose(p1, inverse1, p2, inverse2);
            composeColor(p1, inverse1, p2, inverse2);
        }
        public void composeColor(ImageTransformer.Parameters p1, boolean inverse1,
                ImageTransformer.Parameters p2, boolean inverse2) {
            assert (!inverse1 && !inverse2);

            Parameters pp1 = (Parameters)p1, pp2 = (Parameters)p2;
            CvMat A1 = pp1.getA(), b1 = pp1.getB();
            CvMat A2 = pp2.getA(), b2 = pp2.getB();

            if (b != null) {
                if (pp1.fakeIdentity && X != null) {
                    CvMat temp = temp3x1.get();
                    cvMatMul(X, b1, temp);
                    b1 = temp;
                }

                if (A2 == null && b2 == null) {
                    cvCopy(b1, b);
                } else if (b1 == null) {
                    cvCopy(b2, b);
                } else if (b2 == null) {
                    cvMatMul(A2, b1, b);
                } else {
                    cvGEMM(A2, b1, 1.0,  b2, 1.0,  b, 0);
                }
            }

            if (A != null) {
                if (A1 == null) {
                    cvCopy(A2, A);
                } else if (A2 == null) {
                    cvCopy(A1, A);
                } else {
                    cvMatMul(A2, A1, A);
                }
            }

            switch (numGains) {
                case 0: assert (A == null); break;
                case 1: colorParameters[0] =
                            (A.get(0) + A.get(4) + A.get(8))/3; break;
                case 3: colorParameters[0] = A.get(0);
                        colorParameters[1] = A.get(4);
                        colorParameters[2] = A.get(8); break;
                case 9: A.get(0, colorParameters, 0, 9); break;
                default: assert (false);
            }
            switch (numBiases) {
                case 0: assert (b == null); break;
                case 1: colorParameters[numGains] =
                            (b.get(0) + b.get(1) + b.get(2))/3;   break;
                case 3: b.get(0, colorParameters, numGains, 3); break;
                default: assert (false);
            }
        }

        public CvMat getA() {
            update();
            return A;
        }
        public CvMat getB() {
            update();
            return b;
        }

        @Override protected void update() {<FILL_FUNCTION_BODY>}

        @Override public Parameters clone() {
            Parameters p = new Parameters();
            p.set(this);
            return p;
        }
    }

            if (!isUpdateNeeded()) {
                return;
            }

            switch (numGains) {
                case 0: assert (A == null); break;
                case 1: A.put(0, colorParameters[0]);
                        A.put(4, colorParameters[0]);
                        A.put(8, colorParameters[0]); break;
                case 3: A.put(0, colorParameters[0]);
                        A.put(4, colorParameters[1]);
                        A.put(8, colorParameters[2]); break;
                case 9: A.put(0, colorParameters, 0, 9); break;
                default: assert (false);
            }
            switch (numBiases) {
                case 0: assert (b == null); break;
                case 1: b.put(0, colorParameters[numGains]);
                        b.put(1, colorParameters[numGains]);
                        b.put(2, colorParameters[numGains]);    break;
                case 3: b.put(0, colorParameters, numGains, 3); break;
                default: assert (false);
            }

            super.update();
            setUpdateNeeded(false);
        
<methods>public void <init>() ,public void <init>(double[]) ,public void <init>(org.bytedeco.javacv.ProjectiveDevice, org.bytedeco.javacv.ProjectiveDevice, CvMat, double[], double[]) ,public void <init>(CvMat, CvMat, CvMat, CvMat, CvMat, double[], double[]) ,public org.bytedeco.javacv.ProjectiveTransformer.Parameters createParameters() ,public CvScalar getFillColor() ,public CvMat getInvK1() ,public CvMat getInvK2() ,public CvMat getK1() ,public CvMat getK2() ,public CvMat getN() ,public CvMat getR() ,public double[] getReferencePoints1() ,public double[] getReferencePoints2() ,public CvMat getT() ,public void setFillColor(CvScalar) ,public void transform(IplImage, IplImage, CvRect, int, org.bytedeco.javacv.ImageTransformer.Parameters, boolean) ,public void transform(CvMat, CvMat, org.bytedeco.javacv.ImageTransformer.Parameters, boolean) ,public void transform(org.bytedeco.javacv.ImageTransformer.Data[], CvRect, org.bytedeco.javacv.ImageTransformer.Parameters[], boolean[]) <variables>protected CvMat[] H,protected static ThreadLocal<CvMat> H3x3,protected CvMat K1,protected CvMat K2,protected CvMat R,protected CvScalar fillColor,protected CvMat invK1,protected CvMat invK2,protected KernelData kernelData,protected CvMat n,protected static ThreadLocal<CvMat> pts4x1,protected double[] referencePoints1,protected double[] referencePoints2,protected CvMat t