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 return value will be interpolated between the minimum and maximum value for this 023 * entry. 024 * <p> 025 * In keeping with the conventions of many Geographic Information Systems (GIS) and art applications, this instance "covered" values in the range v0 ≤ f < 026 * v1. Thus, a value that exactly matches the upper bound of the range is not considered "covered". 027 */ 028public class PaletteEntryForRange implements PaletteEntry { 029 030 private final float v0; 031 private final float v1; 032 private final float r0; 033 private final float r1; 034 private final float g0; 035 private final float g1; 036 private final float b0; 037 private final float b1; 038 private final float a0; 039 private final float a1; 040 041 /** 042 * Constructs a palette entry for the range of values v0 ≤ f < v1. A single color will be returned for all values in range 043 * 044 * @param v0 the lower bounds (inclusive) of the covered range of values 045 * @param v1 the upper bounds (non-inclusive) of the covered range of value 046 * @param color the color assigned to value v0 047 */ 048 public PaletteEntryForRange(final float v0, final float v1, final Color color) { 049 this.v0 = v0; 050 this.v1 = v1; 051 final float deltaV = v1 - v0; 052 // check for range volation 053 if (deltaV <= 0 || Float.isNaN(deltaV)) { 054 throw new IllegalArgumentException("Specified values must be v0<v1"); 055 } 056 if (color == null) { 057 throw new IllegalArgumentException("Null colors not allowed"); 058 } 059 060 final int argb0 = color.getRGB(); 061 a0 = argb0 >> 24 & 0xff; 062 r0 = argb0 >> 16 & 0xff; 063 g0 = argb0 >> 8 & 0xff; 064 b0 = argb0 & 0xff; 065 066 final int argb1 = color.getRGB(); 067 a1 = argb1 >> 24 & 0xff; 068 r1 = argb1 >> 16 & 0xff; 069 g1 = argb1 >> 8 & 0xff; 070 b1 = argb1 & 0xff; 071 } 072 073 /** 074 * Constructs a palette entry for the range of values v0 ≤ f < v1. The return color value will be interpolated between the two specified colors. 075 * 076 * @param v0 the lower bounds (inclusive) of the covered range of values 077 * @param v1 the upper bounds (non-inclusive) of the covered range of value 078 * @param color0 the color assigned to value v0 079 * @param color1 the color assigned to value v1 080 */ 081 public PaletteEntryForRange(final float v0, final float v1, final Color color0, final Color color1) { 082 this.v0 = v0; 083 this.v1 = v1; 084 final float deltaV = v1 - v0; 085 // check for range volation 086 if (deltaV <= 0 || Float.isNaN(deltaV)) { 087 throw new IllegalArgumentException("Specified values must be v0<v1"); 088 } 089 if (color0 == null || color1 == null) { 090 throw new IllegalArgumentException("Null colors not allowed"); 091 } 092 final int argb0 = color0.getRGB(); 093 a0 = argb0 >> 24 & 0xff; 094 r0 = argb0 >> 16 & 0xff; 095 g0 = argb0 >> 8 & 0xff; 096 b0 = argb0 & 0xff; 097 098 final int argb1 = color1.getRGB(); 099 a1 = argb1 >> 24 & 0xff; 100 r1 = argb1 >> 16 & 0xff; 101 g1 = argb1 >> 8 & 0xff; 102 b1 = argb1 & 0xff; 103 } 104 105 @Override 106 public boolean coversSingleEntry() { 107 return false; 108 } 109 110 @Override 111 public int getArgb(final float f) { 112 if (v0 <= f && f <= v1) { 113 final float t = (f - v0) / (v1 - v0); 114 final int a = (int) (t * (a1 - a0) + a0 + 0.5); 115 final int r = (int) (t * (r1 - r0) + r0 + 0.5); 116 final int g = (int) (t * (g1 - g0) + g0 + 0.5); 117 final int b = (int) (t * (b1 - b0) + b0 + 0.5); 118 return ((a << 8 | r) << 8 | g) << 8 | b; 119 } 120 return 0; 121 } 122 123 @Override 124 public Color getColor(final float f) { 125 if (v0 <= f && f <= v1) { 126 final float t = (f - v0) / (v1 - v0); 127 final int a = (int) (t * (a1 - a0) + a0 + 0.5); 128 final int r = (int) (t * (r1 - r0) + r0 + 0.5); 129 final int g = (int) (t * (g1 - g0) + g0 + 0.5); 130 final int b = (int) (t * (b1 - b0) + b0 + 0.5); 131 return new Color(r, g, b, a); 132 } 133 return null; 134 } 135 136 @Override 137 public float getLowerBound() { 138 return v0; 139 } 140 141 @Override 142 public float getUpperBound() { 143 return v1; 144 } 145 146 @Override 147 public boolean isCovered(final float f) { 148 return v0 <= f && f < v1; 149 } 150 151 @Override 152 public String toString() { 153 return "PaletteEntry for range " + v0 + ", " + v1; 154 } 155}