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