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-2023 Wilhelm Burger, Mark J. Burge. All rights reserved. 007 * Visit https://imagingbook.com for additional details. 008 ******************************************************************************/ 009package imagingbook.spectral.dft; 010 011/** 012 * <p> 013 * Direct (slow) implementation of the 2-dimensional DFT using tabulated sine 014 * and cosine values. Note that this class has no public constructor - 015 * instantiate sub-class {@link Dft2dDirect.Float} or {@link Dft2dDirect.Double} 016 * instead, as shown below. See Ch. 19 of [1] for additional details. 017 * </p> 018 * <p> 019 * Usage example (for {@code float} data): 020 * </p> 021 * <pre> 022 * float[][] re = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {-2, -1, 0}}; 023 * float[][] im = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; 024 * int w = re.length; // w = 4 025 * int h = re[0].length; // h = 3 026 * Dft2d.Float dft = new Dft2dDirect.Float(w, h); 027 * dct.forward(re, im); // re/im now is the 2D DFT spectrum 028 * dct.inverse(re, im); // re/im now is the original 2D signal 029 * ...</pre> 030 * <p> 031 * [1] W. Burger, M.J. Burge, <em>Digital Image Processing – An Algorithmic 032 * Introduction</em>, 3rd ed, Springer (2022). 033 * </p> 034 * 035 * @author WB 036 * @see Dft1dDirect 037 */ 038public abstract class Dft2dDirect extends Dft2dImp { 039 040 private Dft2dDirect(int width, int height, ScalingMode sm) { 041 super(width, height, sm); 042 } 043 044 // ------------------------------------------------------------------------- 045 046 /** 047 * Two-dimensional DFT implementation using {@code float} data. 048 */ 049 public static class Float extends Dft2dDirect implements Dft2d.Float { 050 051 /** 052 * Constructor using a specific scaling mode. 053 * 054 * @param sm the scaling mode 055 * @param width width of the data array (dimension 0) 056 * @param height height of the data array (dimension 1) 057 */ 058 public Float(int width, int height, ScalingMode sm) { 059 super(width, height, sm); 060 } 061 062 /** 063 * Constructor using the default scaling mode. 064 * 065 * @param width width of the data array (dimension 0) 066 * @param height height of the data array (dimension 1) 067 */ 068 public Float(int width, int height) { 069 this(width, height, ScalingMode.DEFAULT); 070 } 071 072 // ------------------- 073 074 @Override 075 public Dft1d.Float get1dDft(int size) { 076 return new Dft1dDirect.Float(size, this.sm); 077 } 078 079 } 080 081 // ------------------------------------------------------------------------- 082 083 /** 084 * Two-dimensional DFT implementation using {@code double} data. 085 */ 086 public static class Double extends Dft2dDirect implements Dft2d.Double { 087 088 /** 089 * Constructor using a specific scaling mode. 090 * 091 * @param width width of the data array (dimension 0) 092 * @param height height of the data array (dimension 1) 093 * @param sm the scaling mode 094 */ 095 public Double(int width, int height, ScalingMode sm) { 096 super(width, height, sm); 097 } 098 099 /** 100 * Constructor using the default scaling mode. 101 * 102 * @param width width of the data array (dimension 0) 103 * @param height height of the data array (dimension 1) 104 */ 105 public Double(int width, int height) { 106 this(width, height, ScalingMode.DEFAULT); 107 } 108 109 // ------------------- 110 111 @Override 112 public Dft1d.Double get1dDft(int size) { 113 return new Dft1dDirect.Double(size, this.sm); 114 } 115 116 } 117}