001/*******************************************************************************
002 * This software is provided as a supplement to the authors' textbooks on digital
003 *  image processing published by Springer-Verlag in various languages and editions.
004 * Permission to use and distribute this software is granted under the BSD 2-Clause 
005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 
006 * Copyright (c) 2006-2016 Wilhelm Burger, Mark J. Burge. All rights reserved. 
007 * Visit http://imagingbook.com for additional details.
008 *******************************************************************************/
009
010package imagingbook.pub.dct;
011import ij.IJ;
012import ij.process.FloatProcessor;
013
014/**
015 * This class provides the functionality for calculating the DCT in 2D.
016 * @author W. Burger
017 * @version 2014-04-13 (changed massively)
018 */
019
020public class Dct2d {
021        
022        public Dct2d() {
023        }
024        
025        public FloatProcessor DCT(FloatProcessor g) {
026                float[][] data = g.getFloatArray();     // this is always a duplicate array!
027                DCT(data);
028                return new FloatProcessor(data);
029        }
030        
031        public void DCT(float[][] data) {
032                applyTo(data, true);
033        }
034        
035        public FloatProcessor iDCT(FloatProcessor G) {
036                float[][] data = G.getFloatArray();     
037                iDCT(data);
038                return new FloatProcessor(data);
039        }
040        
041        public void iDCT(float[][] data) {
042                applyTo(data, true);
043        }
044        
045//      @Deprecated
046//      public FloatProcessor applyTo(FloatProcessor fp, boolean forward) {
047//              float[][] data = fp.getFloatArray();    // this is always a duplicate array!
048//              applyTo(data, forward);
049//              return new FloatProcessor(data);
050//      }
051        
052        // in-place 2D DCT
053        private void applyTo(final float[][] data, final boolean forward) {
054                final int width = data.length;
055                final int height = data[0].length;
056                
057                // do the rows:
058                double[] row = new double[width];
059                Dct1d dct1R = new Dct1d(width);
060                for (int v = 0; v < height; v++) {
061                        IJ.showProgress(v, height);
062                        getRow(data, v, row);
063                        if (forward)
064                                dct1R.DCT(row);
065                        else
066                                dct1R.iDCT(row);
067                        setRow(data, v, row);
068                }
069
070                // do the columns:
071                double[] col = new double[height];
072                Dct1d dct1C = new Dct1d(height);
073                for (int u = 0; u < width; u++) {
074                        IJ.showProgress(u, width);
075                        getCol(data, u, col);
076                        if (forward)
077                                dct1C.DCT(col);
078                        else
079                                dct1C.iDCT(col);
080                        setCol(data, u, col);
081                }
082        }
083
084        
085        private void getRow(float[][] data, int v, double[] row) {
086                final int width = data.length;
087                for (int u = 0; u < width; u++) {
088                        row[u] = data[u][v];
089                }
090        }
091        
092        private void setRow(float[][] data, int v, double[] row) {
093                final int width = data.length;
094                for (int u = 0; u < width; u++) {
095                        data[u][v] = (float) row[u];
096                }
097        }
098        
099        private void getCol(float[][] data, int u, double[] column) {
100                final int height = data[0].length;
101                for (int v = 0; v < height; v++) {
102                        column[v] = data[u][v];
103                }
104        }
105        
106        private void setCol(float[][] data, int u, double[] column) {
107                final int height = data[0].length;
108                for (int v = 0; v < height; v++) {
109                        data[u][v] = (float) column[v];
110                }
111        }
112
113}
114
115