001 /* 002 * ReduceRGB 003 * 004 * Copyright (c) 2003 Marco Schmidt. 005 * All rights reserved. 006 */ 007 008 package net.sourceforge.jiu.color.reduction; 009 010 import net.sourceforge.jiu.data.PixelImage; 011 import net.sourceforge.jiu.data.RGB24Image; 012 import net.sourceforge.jiu.data.RGB48Image; 013 import net.sourceforge.jiu.ops.ImageToImageOperation; 014 import net.sourceforge.jiu.ops.MissingParameterException; 015 import net.sourceforge.jiu.ops.WrongParameterException; 016 017 /** 018 * Reduces the color depth of RGB truecolor images. 019 * This class uses a simple approach, it just drops some of the 020 * lowest bits and scales the value back to eight or sixteen bits per sample. 021 * <h3>Supported image classes</h3> 022 * This class works with {@link net.sourceforge.jiu.data.RGB24Image} 023 * and {@link net.sourceforge.jiu.data.RGB48Image}. 024 * <h3>Usage example</h3> 025 * Reduce a 24 bits per pixel RGB image to 15 bits per pixel: 026 * <pre> 027 * RGB24Image inputImage = ...; // initialize 028 * ReduceRGB reduce = new ReduceRGB(); 029 * reduce.setBits(5); 030 * reduce.setInputImage(inputImage); 031 * reduce.process(); 032 * PixelImage reducedImage = reduce.getOutputImage(); 033 * </pre> 034 * @author Marco Schmidt 035 * @since 0.12.0 036 * @see net.sourceforge.jiu.color.reduction.ReduceShadesOfGray 037 */ 038 public class ReduceRGB extends ImageToImageOperation 039 { 040 /** 041 * Number of significant bits per channel in the destination RGB image. 042 */ 043 private Integer destBits; 044 045 /*private byte[] createByteLut(int inDepth) 046 { 047 int outDepth = destBits.intValue(); 048 lut = new int[1 << inDepth]; 049 final int SHIFT = inDepth - outDepth; 050 final int MAX_IN_VALUE = (1 << inDepth) - 1; 051 final int MAX_OUT_VALUE = (1 << outDepth) - 1; 052 for (int i = 0; i < lut.length; i++) 053 { 054 int value = i >> SHIFT; 055 lut[i] = (value * MAX_IN_VALUE) / MAX_OUT_VALUE; 056 } 057 }*/ 058 059 060 public void process() throws MissingParameterException, WrongParameterException 061 { 062 if (destBits == null) 063 { 064 throw new MissingParameterException("The number of destination bits has not been specified."); 065 } 066 ensureInputImageIsAvailable(); 067 ensureImagesHaveSameResolution(); 068 PixelImage in = getInputImage(); 069 boolean rgb24 = in instanceof RGB24Image; 070 boolean rgb48 = in instanceof RGB48Image; 071 if (!(rgb24 || rgb48)) 072 { 073 throw new WrongParameterException("Input image must be either RGB24Image or RGB48Image."); 074 } 075 PixelImage out = getOutputImage(); 076 int bits = destBits.intValue(); 077 if (bits <= 8) 078 { 079 } 080 else 081 if (bits <= 16) 082 { 083 } 084 else 085 { 086 } 087 } 088 089 /** 090 * Specifies the number of bits the output image is supposed to have. 091 * @param bits number of bits in output image, from 1 to 15 092 * @throws IllegalArgumentException if bits is smaller than 1 or larger than 15 093 */ 094 public void setBits(int bits) 095 { 096 if (bits < 1) 097 { 098 throw new IllegalArgumentException("Number of bits must be 1 or larger."); 099 } 100 if (bits > 15) 101 { 102 throw new IllegalArgumentException("Number of bits must be 15 or smaller."); 103 } 104 destBits = new Integer(bits); 105 } 106 }