001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.imaging.formats.tiff.photometricinterpreters.floatingpoint; 018 019import java.awt.Color; 020 021/** 022 * Provides a palette entry for colors associated with a range of values. The 023 * return value will be interpolated between the minimum and maximum value for 024 * this entry. 025 * <p> 026 * In keeping with the conventions of many Geographic Information Systems (GIS) 027 * and art applications, this instance "covered" values in the range v0 ≤ f 028 * < v1. Thus, a value that exactly matches the upper bound of the range is 029 * not considered "covered". 030 */ 031public class PaletteEntryForRange implements PaletteEntry { 032 033 private final float v0; 034 private final float v1; 035 private final float r0; 036 private final float r1; 037 private final float g0; 038 private final float g1; 039 private final float b0; 040 private final float b1; 041 private final float a0; 042 private final float a1; 043 044 /** 045 * Constructs a palette entry for the range of values v0 ≤ f < v1. The 046 * return color value will be interpolated between the two specified colors. 047 * 048 * @param v0 the lower bounds (inclusive) of the covered range of values 049 * @param v1 the upper bounds (non-inclusive) of the covered range of value 050 * @param color0 the color assigned to value v0 051 * @param color1 the color assigned to value v1 052 */ 053 public PaletteEntryForRange(final float v0, final float v1, final Color color0, final Color color1) { 054 this.v0 = v0; 055 this.v1 = v1; 056 final float deltaV = v1 - v0; 057 // check for range volation 058 if (deltaV <= 0 || Float.isNaN(deltaV)) { 059 throw new IllegalArgumentException("Specified values must be v0<v1"); 060 } 061 if (color0 == null || color1 == null) { 062 throw new IllegalArgumentException("Null colors not allowed"); 063 } 064 final int argb0 = color0.getRGB(); 065 a0 = (argb0 >> 24) & 0xff; 066 r0 = (argb0 >> 16) & 0xff; 067 g0 = (argb0 >> 8) & 0xff; 068 b0 = argb0 & 0xff; 069 070 final int argb1 = color1.getRGB(); 071 a1 = (argb1 >> 24) & 0xff; 072 r1 = (argb1 >> 16) & 0xff; 073 g1 = (argb1 >> 8) & 0xff; 074 b1 = argb1 & 0xff; 075 } 076 077 /** 078 * Constructs a palette entry for the range of values v0 ≤ f < v1. A 079 * single color will be returned for all values in range 080 * 081 * @param v0 the lower bounds (inclusive) of the covered range of values 082 * @param v1 the upper bounds (non-inclusive) of the covered range of value 083 * @param color the color assigned to value v0 084 */ 085 public PaletteEntryForRange(final float v0, final float v1, final Color color) { 086 this.v0 = v0; 087 this.v1 = v1; 088 final float deltaV = v1 - v0; 089 // check for range volation 090 if (deltaV <= 0 || Float.isNaN(deltaV)) { 091 throw new IllegalArgumentException("Specified values must be v0<v1"); 092 } 093 if (color == null) { 094 throw new IllegalArgumentException("Null colors not allowed"); 095 } 096 097 final int argb0 = color.getRGB(); 098 a0 = (argb0 >> 24) & 0xff; 099 r0 = (argb0 >> 16) & 0xff; 100 g0 = (argb0 >> 8) & 0xff; 101 b0 = argb0 & 0xff; 102 103 final int argb1 = color.getRGB(); 104 a1 = (argb1 >> 24) & 0xff; 105 r1 = (argb1 >> 16) & 0xff; 106 g1 = (argb1 >> 8) & 0xff; 107 b1 = argb1 & 0xff; 108 } 109 110 @Override 111 public boolean isCovered(final float f) { 112 return v0 <= f && f < v1; 113 } 114 115 @Override 116 public int getARGB(final float f) { 117 if (v0 <= f && f <= v1) { 118 final float t = (f - v0) / (v1 - v0); 119 final int a = (int) (t * (a1 - a0) + a0 + 0.5); 120 final int r = (int) (t * (r1 - r0) + r0 + 0.5); 121 final int g = (int) (t * (g1 - g0) + g0 + 0.5); 122 final int b = (int) (t * (b1 - b0) + b0 + 0.5); 123 return (((((a << 8) | r) << 8) | g) << 8) | b; 124 } 125 return 0; 126 } 127 128 @Override 129 public Color getColor(final float f) { 130 if (v0 <= f && f <= v1) { 131 final float t = (f - v0) / (v1 - v0); 132 final int a = (int) (t * (a1 - a0) + a0 + 0.5); 133 final int r = (int) (t * (r1 - r0) + r0 + 0.5); 134 final int g = (int) (t * (g1 - g0) + g0 + 0.5); 135 final int b = (int) (t * (b1 - b0) + b0 + 0.5); 136 return new Color(r, g, b, a); 137 } 138 return null; 139 } 140 141 @Override 142 public boolean coversSingleEntry() { 143 return false; 144 } 145 146 @Override 147 public float getLowerBound() { 148 return v0; 149 } 150 151 @Override 152 public float getUpperBound() { 153 return v1; 154 } 155 156 @Override 157 public String toString() { 158 return "PaletteEntry for range " + v0 + ", " + v1; 159 } 160}