GNU Classpath (0.95) | |
Frames | No Frames |
1: /* IIOParam.java -- 2: Copyright (C) 2004 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.imageio; 40: 41: import java.awt.Point; 42: import java.awt.Rectangle; 43: 44: /** 45: * An IIOParam stores parameters used when encoding or decoding image 46: * streams. ImageReadParam and ImageWriteParam extend this abstract 47: * base class. 48: * 49: * IIOParams allow control over how source pixels converted into 50: * destination pixels. This conversion can take place between a 51: * stream and in-memory image data, when an image reader is doing the 52: * conversion, or a writer can be doing the conversion from an 53: * in-memory source to a stream destination. 54: * 55: * An image reader can be restricted to only read from a given region; 56: * likewise a writer can be restricted to only write output to a given 57: * region. 58: * 59: * For image readers and writers, IIOParam supports image pixelation 60: * -- where the input image is approximated by the output image using 61: * larger-sized pixel blocks. For example: FIXME 62: * 63: * IIOParams can control how pixels are combined into larger blocks 64: * using sub-sampling matrices. For example: FIXME 65: * 66: * They can also control which source bands are read and written; this 67: * example reads the RGBA (red, green, blue, transparency) data from a 68: * PNG image and outputs just the red and transparency bands: FIXME 69: * 70: * @author Thomas Fitzsimmons (fitzsim@redhat.com) 71: * @author Michael Koch (konqueror@gmx.de) 72: */ 73: public abstract class IIOParam 74: { 75: /** 76: * The controller called by this IIOParam to retrieve parameters. 77: */ 78: protected IIOParamController controller = null; 79: 80: /** 81: * The default controller called by this IIOParam to retrieve 82: * parameters. 83: */ 84: protected IIOParamController defaultController = null; 85: 86: /** 87: * The offset in the destination where the upper-left 88: * decoded/encoded pixel should be located. 89: */ 90: protected Point destinationOffset = new Point(0, 0); 91: 92: /** 93: * Sets the output colour type when writing or the destination image 94: * type when reading. 95: */ 96: protected ImageTypeSpecifier destinationType = null; 97: 98: /** 99: * An array indicating which source bands will be used or null. 100: */ 101: protected int[] sourceBands = null; 102: 103: /** 104: * The source pixel region or null. 105: */ 106: protected Rectangle sourceRegion = null; 107: 108: /** 109: * Sample every sourceXSubsampling'th pixel in the source image when 110: * pixelating the destination image in the horizontal direction. 111: */ 112: protected int sourceXSubsampling = 1; 113: 114: /** 115: * Sample every sourceYSubsampling'th pixel in the source image when 116: * pixelating the destination image in the vertical direction. 117: */ 118: protected int sourceYSubsampling = 1; 119: 120: /** 121: * Start sampling at this horizontal offset within the source region 122: * when pixelating the destination image in the horizontal 123: * direction. 124: */ 125: protected int subsamplingXOffset = 0; 126: 127: /** 128: * Start sampling at this vertical offset within the source region 129: * when pixelating the destination image in the vertical direction. 130: */ 131: protected int subsamplingYOffset = 0; 132: 133: /** 134: * Indicates whether or not the controller has been explicitly set 135: * to null. 136: */ 137: private boolean no_controller = false; 138: 139: /** 140: * Constructs an IIOParam object. 141: */ 142: protected IIOParam() 143: { 144: } 145: 146: /** 147: * Activates the parameter controller by calling its activate method 148: * and passing it this IIOParam. A true return value indicates that 149: * this IIOParam's values are ready for the next read or write 150: * operation. A return value of false means that this IIOParam's 151: * values have not been affected because the controller operations 152: * were cancelled. 153: * 154: * @return true if parameters were successfully set, false if 155: * parameters were not changed 156: */ 157: public boolean activateController() 158: { 159: if (controller == null) 160: { 161: if (defaultController == null || no_controller) 162: return false; 163: else 164: return defaultController.activate (this); 165: } 166: else 167: return controller.activate(this); 168: } 169: 170: /** 171: * Retrieve the currently set controller if one has been set, or the 172: * default controller, or null if the controller has been explicitly 173: * set to null. 174: * 175: * @return the currently used controller or null 176: */ 177: public IIOParamController getController() 178: { 179: return controller == null ? 180: (no_controller ? null : defaultController) : controller; 181: } 182: 183: /** 184: * Retrieve the default controller regardless of whether or not a 185: * non-default controller has been set. The default controller may 186: * be null. 187: * 188: * @return the default controller or null 189: */ 190: public IIOParamController getDefaultController() 191: { 192: return defaultController; 193: } 194: 195: /** 196: * Retrieve the offset in the destination where the upper-left 197: * decoded/encoded pixel should be located. (0, 0) by default. 198: * 199: * @return the destination offset 200: */ 201: public Point getDestinationOffset() 202: { 203: return destinationOffset; 204: } 205: 206: /** 207: * Retrieve the currently set image-type specifier or null if none 208: * has been set. 209: * 210: * @return the current image-type specifier or null 211: */ 212: public ImageTypeSpecifier getDestinationType() 213: { 214: return destinationType; 215: } 216: 217: /** 218: * Retrieve the current source band values or null if source band 219: * values have not been set. 220: * 221: * The returned array is a copy of this IIOParam's source band 222: * array. 223: * 224: * @return the current set of source band values or null 225: */ 226: public int[] getSourceBands() 227: { 228: if (sourceBands == null) 229: return null; 230: 231: int[] sourceBandsCopy = new int[sourceBands.length]; 232: System.arraycopy (sourceBands, 0, sourceBandsCopy, 0, sourceBands.length); 233: return sourceBandsCopy; 234: } 235: 236: /** 237: * Retrieve the source rectangle from which pixels should be read or 238: * null if no source region has been set. 239: * 240: * @return the current source region or null 241: */ 242: public Rectangle getSourceRegion() 243: { 244: return sourceRegion; 245: } 246: 247: /** 248: * Retrieve the number of pixel columns to advance before taking a 249: * pixel sample. 250: * 251: * @return the horizontal sub-sampling interval 252: */ 253: public int getSourceXSubsampling() 254: { 255: return sourceXSubsampling; 256: } 257: 258: /** 259: * Retrieve the number of pixel rows to advance before taking a 260: * pixel sample. 261: * 262: * @return the vertical sub-sampling interval 263: */ 264: public int getSourceYSubsampling() 265: { 266: return sourceYSubsampling; 267: } 268: 269: /** 270: * Retrieve the number of pixel columns to advance before taking any 271: * pixel samples. 272: * 273: * @return the horizontal sub-sampling offset 274: */ 275: public int getSubsamplingXOffset() 276: { 277: return subsamplingXOffset; 278: } 279: 280: /** 281: * Retrieve the number of pixel rows to advance before taking any 282: * pixel samples. 283: * 284: * @return the vertical sub-sampling offset 285: */ 286: public int getSubsamplingYOffset() 287: { 288: return subsamplingYOffset; 289: } 290: 291: /** 292: * Check if a non-null controller is currently available. 293: * 294: * @return true if getController returns a non-null value, false if 295: * getController returns null 296: */ 297: public boolean hasController() 298: { 299: return getController() != null; 300: } 301: 302: /** 303: * Sets the controller for this IIOParam. This is the controller 304: * that will be activated when activateController is called. The 305: * argument controller overrides this IIOParam's default controller. 306: * If the argument is null then no controller will be set, not even 307: * the default one. To reset the default controller call 308: * setController(getDefaultController()). 309: * 310: * @param controller the controller to set or null 311: */ 312: public void setController(IIOParamController controller) 313: { 314: if (controller == defaultController) 315: { 316: this.controller = null; 317: no_controller = false; 318: } 319: else 320: { 321: no_controller = (controller == null); 322: this.controller = controller; 323: } 324: } 325: 326: /** 327: * Set the destination image type. 328: * 329: * If this value is set on an image reader then its read method will 330: * return a new BufferedImage of the specified destination type. In 331: * this case any destination image set using setDestination() is 332: * ignored. 333: * 334: * If this is set on an image writer then the destination type 335: * affects only the colour model of the destination image. The 336: * destination type's SampleModel is ignored. The destination 337: * type's ColorModel will override the source image's colour model. 338: * 339: * @param destinationType the sample and colour models of the 340: * destination image 341: */ 342: public void setDestinationType (ImageTypeSpecifier destinationType) 343: { 344: this.destinationType = destinationType; 345: } 346: 347: /** 348: * Specify the destination pixel offset. Image writers are only 349: * affected by this setting when ImageWriter.replacePixels is called 350: * in which case the offset is into the region of pixels being 351: * changed. 352: * 353: * @param destinationOffset the offset where pixel writing should 354: * begin 355: */ 356: public void setDestinationOffset(Point destinationOffset) 357: { 358: if (destinationOffset == null) 359: throw new IllegalArgumentException("destinationOffset is null"); 360: 361: this.destinationOffset = destinationOffset; 362: } 363: 364: /** 365: * Set the indices of the source bands to be used. Duplicate 366: * indices are not allowed. A value of null means use all source 367: * bands. The argument array is copied and stored, so subsequent 368: * updates to it will not be reflected in this IIOParam. 369: * 370: * @param sourceBands the array of source bands to use 371: */ 372: public void setSourceBands(int[] sourceBands) 373: { 374: int[] sourceBandsCopy = new int[sourceBands.length]; 375: System.arraycopy (sourceBands, 0, sourceBandsCopy, 0, sourceBands.length); 376: this.sourceBands = sourceBandsCopy; 377: } 378: 379: /** 380: * Set the source region from which to read. The number of pixels 381: * sampled from the source region depends on the source sub-sampling 382: * settings. If the combination of this sourceRegion and the 383: * current sub-sampling settings would result in no pixels being 384: * sampled then an IllegalStateException will be thrown. 385: * 386: * The source region is specified in the source image coordinate 387: * system which has point (0, 0) at the top-left and increases down 388: * and to the right. The argument source region is clipped to the 389: * image boundaries at read-time. 390: * 391: * A null argument sets the source region to null meaning that the 392: * whole image should be read. 393: * 394: * @param sourceRegion the rectangular source region 395: * 396: * @exception IllegalArgumentException if sourceRegion has width or 397: * height <= 0 or x or y < 0 398: * @exception IllegalStateException if the given sourceRegion and 399: * the current sampling settings would produce zero samples 400: */ 401: public void setSourceRegion(Rectangle sourceRegion) 402: { 403: if (sourceRegion != null 404: && (sourceRegion.x < 0 405: || sourceRegion.y < 0 406: || sourceRegion.width <= 0 407: || sourceRegion.height <= 0)) 408: throw new IllegalArgumentException("illegal source region"); 409: 410: if (sourceRegion != null) 411: { 412: int num_rows = 413: (sourceRegion.height - subsamplingYOffset + sourceYSubsampling - 1) 414: / sourceYSubsampling; 415: 416: int num_columns = 417: (sourceRegion.width - subsamplingXOffset + sourceXSubsampling - 1) 418: / sourceXSubsampling; 419: 420: if (num_rows <= 0 || num_columns <= 0) 421: throw new IllegalStateException("zero pixels in source region"); 422: } 423: 424: this.sourceRegion = sourceRegion; 425: } 426: 427: /** 428: * Set the source sampling intervals and offsets. Every 429: * sourceXSubsampling'th pixel horizontally and 430: * sourceYSubsampling'th pixel vertically will be sampled. Sampling 431: * will being a the subsamplingXOffset'th column and the 432: * subsamplingYOffset'th row. 433: * 434: * Horizontally, the number of sampled pixels will be: 435: * 436: * floor((width - subsamplingXOffset + sourceXSubsampling - 1) / sourceXSubsampling) 437: * 438: * Vertically: 439: * 440: * floor((height - subsamplingYOffset + sourceYSubsampling - 1) / sourceYSubsampling) 441: * 442: * If the current source region setting is such that the given 443: * sub-sampling arguments would produce zero pixel samples, an 444: * IllegalStateException is thrown. 445: * 446: * The offset parameters can be used to make source regions overlap 447: * when tiling across an image. This can eliminate seams and 448: * better-tile images whose width or height is not a multiple of the 449: * sampling interval. 450: * 451: * @param sourceXSubsampling the horizontal sampling interval 452: * @param sourceYSubsampling the vertical sampling interval 453: * @param subsamplingXOffset the horizontal offset of the initial 454: * sample 455: * @param subsamplingYOffset the vertical offset of the initial 456: * sample 457: * 458: * @exception IllegalArgumentException if either subsamplingXOffset 459: * or subsamplingYOffset is < 0 460: * @exception IllegalStateException if the current source region 461: * combined with the given sub-sampling parameters would produce 462: * zero pixel samples 463: */ 464: public void setSourceSubsampling(int sourceXSubsampling, int sourceYSubsampling, 465: int subsamplingXOffset, int subsamplingYOffset) 466: { 467: if (subsamplingXOffset < 0 || subsamplingYOffset < 0) 468: throw new IllegalArgumentException("subsampling offset < 0"); 469: 470: if (sourceRegion != null) 471: { 472: int num_rows = 473: (sourceRegion.height - subsamplingYOffset + sourceYSubsampling - 1) 474: / sourceYSubsampling; 475: 476: int num_columns = 477: (sourceRegion.width - subsamplingXOffset + sourceXSubsampling - 1) 478: / sourceXSubsampling; 479: 480: if (num_rows <= 0 || num_columns <= 0) 481: throw new IllegalStateException("subsampling parameters would" 482: + " produce zero pixel samples" 483: + " in source region"); 484: } 485: 486: this.sourceXSubsampling = sourceXSubsampling; 487: this.sourceYSubsampling = sourceYSubsampling; 488: this.subsamplingXOffset = subsamplingXOffset; 489: this.subsamplingYOffset = subsamplingYOffset; 490: } 491: }
GNU Classpath (0.95) |