1 package com.google.zxing.qrcode.detector;
4 * TODO need to reimplement this from scratch. This is derived from jai-core from Sun
5 * and it is not clear we can redistribute this modification.
7 final class JAIPerspectiveTransform {
9 private float m00, m01, m02, m10, m11, m12, m20, m21, m22;
11 JAIPerspectiveTransform() {
12 m00 = m11 = m22 = 1.0f;
13 m01 = m02 = m10 = m12 = m20 = m21 = 0.0f;
16 private void makeAdjoint() {
17 float m00p = m11 * m22 - m12 * m21;
18 float m01p = m12 * m20 - m10 * m22; // flipped sign
19 float m02p = m10 * m21 - m11 * m20;
20 float m10p = m02 * m21 - m01 * m22; // flipped sign
21 float m11p = m00 * m22 - m02 * m20;
22 float m12p = m01 * m20 - m00 * m21; // flipped sign
23 float m20p = m01 * m12 - m02 * m11;
24 float m21p = m02 * m10 - m00 * m12; // flipped sign
25 float m22p = m00 * m11 - m01 * m10;
26 // Transpose and copy sub-determinants
38 private static void getSquareToQuad(float x0, float y0,
42 JAIPerspectiveTransform tx) {
43 float dx3 = x0 - x1 + x2 - x3;
44 float dy3 = y0 - y1 + y2 - y3;
46 if ((dx3 == 0.0f) && (dy3 == 0.0f)) { // to do: use tolerance
60 float invdet = 1.0f / (dx1 * dy2 - dx2 * dy1);
61 tx.m20 = (dx3 * dy2 - dx2 * dy3) * invdet;
62 tx.m21 = (dx1 * dy3 - dx3 * dy1) * invdet;
63 tx.m00 = x1 - x0 + tx.m20 * x1;
64 tx.m01 = x3 - x0 + tx.m21 * x3;
66 tx.m10 = y1 - y0 + tx.m20 * y1;
67 tx.m11 = y3 - y0 + tx.m21 * y3;
72 private static JAIPerspectiveTransform getSquareToQuad(float x0, float y0,
76 JAIPerspectiveTransform tx = new JAIPerspectiveTransform();
77 getSquareToQuad(x0, y0, x1, y1, x2, y2, x3, y3, tx);
81 private static JAIPerspectiveTransform getQuadToSquare(float x0, float y0,
85 JAIPerspectiveTransform tx = new JAIPerspectiveTransform();
86 getSquareToQuad(x0, y0, x1, y1, x2, y2, x3, y3, tx);
91 static JAIPerspectiveTransform getQuadToQuad(float x0, float y0,
98 float x3p, float y3p) {
99 JAIPerspectiveTransform tx1 = getQuadToSquare(x0, y0, x1, y1, x2, y2, x3, y3);
100 JAIPerspectiveTransform tx2 = getSquareToQuad(x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p);
101 tx1.concatenate(tx2);
105 private void concatenate(JAIPerspectiveTransform Tx) {
106 float m00p = m00 * Tx.m00 + m10 * Tx.m01 + m20 * Tx.m02;
107 float m10p = m00 * Tx.m10 + m10 * Tx.m11 + m20 * Tx.m12;
108 float m20p = m00 * Tx.m20 + m10 * Tx.m21 + m20 * Tx.m22;
109 float m01p = m01 * Tx.m00 + m11 * Tx.m01 + m21 * Tx.m02;
110 float m11p = m01 * Tx.m10 + m11 * Tx.m11 + m21 * Tx.m12;
111 float m21p = m01 * Tx.m20 + m11 * Tx.m21 + m21 * Tx.m22;
112 float m02p = m02 * Tx.m00 + m12 * Tx.m01 + m22 * Tx.m02;
113 float m12p = m02 * Tx.m10 + m12 * Tx.m11 + m22 * Tx.m12;
114 float m22p = m02 * Tx.m20 + m12 * Tx.m21 + m22 * Tx.m22;
126 void transform(float[] points) {
127 int max = points.length;
128 for (int offset = 0; offset < max; offset += 2) {
129 float x = points[offset];
130 float y = points[offset + 1];
131 float w = m20 * x + m21 * y + m22;
134 points[offset + 1] = y;
136 float oneOverW = 1.0f / w;
137 points[offset] = (m00 * x + m01 * y + m02) * oneOverW;
138 points[offset + 1] = (m10 * x + m11 * y + m12) * oneOverW;