001 /* 002 * BorderSampleGenerator 003 * 004 * Copyright (c) 2002, 2003 Marco Schmidt. 005 * All rights reserved. 006 */ 007 008 package net.sourceforge.jiu.filters; 009 010 import net.sourceforge.jiu.data.IntegerImage; 011 012 /** 013 * Abstract base class for classes that fill an <code>int</code> array with samples 014 * from a rectangular region of an image's channel by 015 * (1) copying <code>int</code> samples from an {@link net.sourceforge.jiu.data.IntegerImage} object 016 * and by (2) generating samples that lie outside of the image. 017 * To be used by {@link ConvolutionKernelFilter} and other operations 018 * that require rectangular parts of an image that may not lie fully 019 * inside of the image. 020 * @author Marco Schmidt 021 * @since 0.10.0 022 */ 023 public abstract class BorderSampleGenerator 024 { 025 private int areaWidth; 026 private int areaHeight; 027 private int channelIndex; 028 private IntegerImage image; 029 030 /** 031 * Initialize width and height of the area to be covered in every call to 032 * {@link #fill}, also provides the image to be used for data copying. 033 * The current channel is set to 0. 034 * @param integerImage the image from which samples will be copied 035 * @param areaWidth number of columns of the area to be covered in {@link #fill} 036 * @param areaHeight number of rows of the area to be covered in {@link #fill} 037 */ 038 public BorderSampleGenerator(IntegerImage integerImage, int areaWidth, int areaHeight) 039 { 040 image = integerImage; 041 if (image == null) 042 { 043 throw new IllegalArgumentException("The image argument must be non-null."); 044 } 045 this.areaWidth = areaWidth; 046 if (areaWidth < 1 || (areaWidth % 2) == 0) 047 { 048 throw new IllegalArgumentException("Area width must be a positive odd number."); 049 } 050 this.areaHeight = areaHeight; 051 if (areaHeight < 1 || (areaHeight % 2) == 0) 052 { 053 throw new IllegalArgumentException("Area height must be a positive odd number."); 054 } 055 } 056 057 /** 058 * Fills the argument array with samples from the current channel of the image 059 * given to the constructor, generating samples that lie outside of the image. 060 * The samples are copied (or generated) from the row y to row y + areaHeight - 1, 061 * and within each row from column x to x + areaWidth - 1. 062 * <p> 063 * The implementation of this method is left to the child classes. 064 * There are different ways to generate new samples, and each child class 065 * is supposed to implement another way. 066 * Obviously, the child classes also must copy samples from the image. 067 * @param x leftmost column to be copied or generated 068 * @param y top row to be copied or generated 069 * @param samples array to which samples will be written; must have at least 070 * {@link #getAreaWidth} times {@link #getAreaHeight} elements 071 */ 072 public abstract void fill(int x, int y, int[] samples); 073 074 /** 075 * Returns the number of rows from which data is copied or generated 076 * with every call to {@link #fill}. 077 * @return number or rows of a fill area 078 */ 079 public int getAreaHeight() 080 { 081 return areaHeight; 082 } 083 084 /** 085 * Returns the number of columns from which data is copied or generated 086 * with every call to {@link #fill}. 087 * @return number or columns of a fill area 088 */ 089 public int getAreaWidth() 090 { 091 return areaWidth; 092 } 093 094 /** 095 * Returns the index of the channel of the image from which data is copied. 096 * @see #setChannelIndex 097 * @return number or rows 098 */ 099 public int getChannelIndex() 100 { 101 return channelIndex; 102 } 103 104 /** 105 * Returns the image from which data is copied. 106 * @return image object 107 */ 108 public IntegerImage getImage() 109 { 110 return image; 111 } 112 113 /** 114 * Sets the channel from which data is copied in {@link #fill}. 115 * @return channel index 116 * @see #getChannelIndex 117 */ 118 public void setChannelIndex(int newChannelIndex) 119 { 120 if (newChannelIndex < 0 || newChannelIndex >= image.getNumChannels()) 121 { 122 throw new IllegalArgumentException("Illegal channel index: " + 123 newChannelIndex + " (must be from 0 to " + 124 (image.getNumChannels() - 1) + ")."); 125 } 126 else 127 { 128 channelIndex = newChannelIndex; 129 } 130 } 131 }