PageRenderTime 51ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/components/forks/poi/src/loci/poi/hssf/usermodel/HSSFPalette.java

http://github.com/openmicroscopy/bioformats
Java | 237 lines | 131 code | 16 blank | 90 comment | 22 complexity | 8b713ef6194009c2b34b9be50096af38 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, Apache-2.0, BSD-2-Clause, MPL-2.0-no-copyleft-exception
  1. /*
  2. * #%L
  3. * Fork of Apache Jakarta POI.
  4. * %%
  5. * Copyright (C) 2008 - 2013 Open Microscopy Environment:
  6. * - Board of Regents of the University of Wisconsin-Madison
  7. * - Glencoe Software, Inc.
  8. * - University of Dundee
  9. * %%
  10. * Licensed under the Apache License, Version 2.0 (the "License");
  11. * you may not use this file except in compliance with the License.
  12. * You may obtain a copy of the License at
  13. *
  14. * http://www.apache.org/licenses/LICENSE-2.0
  15. *
  16. * Unless required by applicable law or agreed to in writing, software
  17. * distributed under the License is distributed on an "AS IS" BASIS,
  18. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19. * See the License for the specific language governing permissions and
  20. * limitations under the License.
  21. * #L%
  22. */
  23. /* ====================================================================
  24. Licensed to the Apache Software Foundation (ASF) under one or more
  25. contributor license agreements. See the NOTICE file distributed with
  26. this work for additional information regarding copyright ownership.
  27. The ASF licenses this file to You under the Apache License, Version 2.0
  28. (the "License"); you may not use this file except in compliance with
  29. the License. You may obtain a copy of the License at
  30. http://www.apache.org/licenses/LICENSE-2.0
  31. Unless required by applicable law or agreed to in writing, software
  32. distributed under the License is distributed on an "AS IS" BASIS,
  33. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  34. See the License for the specific language governing permissions and
  35. limitations under the License.
  36. ==================================================================== */
  37. package loci.poi.hssf.usermodel;
  38. import loci.poi.hssf.record.PaletteRecord;
  39. import loci.poi.hssf.util.HSSFColor;
  40. /**
  41. * Represents a workbook color palette.
  42. * Internally, the XLS format refers to colors using an offset into the palette
  43. * record. Thus, the first color in the palette has the index 0x8, the second
  44. * has the index 0x9, etc. through 0x40
  45. *
  46. * @author Brian Sanders (bsanders at risklabs dot com)
  47. */
  48. public class HSSFPalette
  49. {
  50. private PaletteRecord palette;
  51. protected HSSFPalette(PaletteRecord palette)
  52. {
  53. this.palette = palette;
  54. }
  55. /**
  56. * Retrieves the color at a given index
  57. *
  58. * @param index the palette index, between 0x8 to 0x40 inclusive
  59. * @return the color, or null if the index is not populated
  60. */
  61. public HSSFColor getColor(short index)
  62. {
  63. //Handle the special AUTOMATIC case
  64. if (index == HSSFColor.AUTOMATIC.index)
  65. return HSSFColor.AUTOMATIC.getInstance();
  66. else {
  67. byte[] b = palette.getColor(index);
  68. if (b != null)
  69. {
  70. return new CustomColor(index, b);
  71. }
  72. }
  73. return null;
  74. }
  75. /**
  76. * Finds the first occurance of a given color
  77. *
  78. * @param red the RGB red component, between 0 and 255 inclusive
  79. * @param green the RGB green component, between 0 and 255 inclusive
  80. * @param blue the RGB blue component, between 0 and 255 inclusive
  81. * @return the color, or null if the color does not exist in this palette
  82. */
  83. public HSSFColor findColor(byte red, byte green, byte blue)
  84. {
  85. byte[] b = palette.getColor(PaletteRecord.FIRST_COLOR_INDEX);
  86. for (short i = (short) PaletteRecord.FIRST_COLOR_INDEX; b != null;
  87. b = palette.getColor(++i))
  88. {
  89. if (b[0] == red && b[1] == green && b[2] == blue)
  90. {
  91. return new CustomColor(i, b);
  92. }
  93. }
  94. return null;
  95. }
  96. /**
  97. * Finds the closest matching color in the custom palette. The
  98. * method for finding the distance between the colors is fairly
  99. * primative.
  100. *
  101. * @param red The red component of the color to match.
  102. * @param green The green component of the color to match.
  103. * @param blue The blue component of the color to match.
  104. * @return The closest color or null if there are no custom
  105. * colors currently defined.
  106. */
  107. public HSSFColor findSimilarColor(byte red, byte green, byte blue)
  108. {
  109. HSSFColor result = null;
  110. int minColorDistance = Integer.MAX_VALUE;
  111. byte[] b = palette.getColor(PaletteRecord.FIRST_COLOR_INDEX);
  112. for (short i = (short) PaletteRecord.FIRST_COLOR_INDEX; b != null;
  113. b = palette.getColor(++i))
  114. {
  115. int colorDistance = red - b[0] + green - b[1] + blue - b[2];
  116. if (colorDistance < minColorDistance)
  117. {
  118. result = getColor(i);
  119. }
  120. }
  121. return result;
  122. }
  123. /**
  124. * Sets the color at the given offset
  125. *
  126. * @param index the palette index, between 0x8 to 0x40 inclusive
  127. * @param red the RGB red component, between 0 and 255 inclusive
  128. * @param green the RGB green component, between 0 and 255 inclusive
  129. * @param blue the RGB blue component, between 0 and 255 inclusive
  130. */
  131. public void setColorAtIndex(short index, byte red, byte green, byte blue)
  132. {
  133. palette.setColor(index, red, green, blue);
  134. }
  135. /**
  136. * Adds a new color into an empty color slot.
  137. * @param red The red component
  138. * @param green The green component
  139. * @param blue The blue component
  140. *
  141. * @return The new custom color.
  142. *
  143. * @throws RuntimeException if there are more more free color indexes.
  144. */
  145. public HSSFColor addColor( byte red, byte green, byte blue )
  146. {
  147. byte[] b = palette.getColor(PaletteRecord.FIRST_COLOR_INDEX);
  148. short i;
  149. for (i = (short) PaletteRecord.FIRST_COLOR_INDEX; i < PaletteRecord.STANDARD_PALETTE_SIZE + PaletteRecord.FIRST_COLOR_INDEX; b = palette.getColor(++i))
  150. {
  151. if (b == null)
  152. {
  153. setColorAtIndex( i, red, green, blue );
  154. return getColor(i);
  155. }
  156. }
  157. throw new RuntimeException("Could not find free color index");
  158. }
  159. private static class CustomColor extends HSSFColor
  160. {
  161. private short byteOffset;
  162. private byte red;
  163. private byte green;
  164. private byte blue;
  165. private CustomColor(short byteOffset, byte[] colors)
  166. {
  167. this(byteOffset, colors[0], colors[1], colors[2]);
  168. }
  169. private CustomColor(short byteOffset, byte red, byte green, byte blue)
  170. {
  171. this.byteOffset = byteOffset;
  172. this.red = red;
  173. this.green = green;
  174. this.blue = blue;
  175. }
  176. public short getIndex()
  177. {
  178. return byteOffset;
  179. }
  180. public short[] getTriplet()
  181. {
  182. return new short[]
  183. {
  184. (short) (red & 0xff),
  185. (short) (green & 0xff),
  186. (short) (blue & 0xff)
  187. };
  188. }
  189. public String getHexString()
  190. {
  191. StringBuffer sb = new StringBuffer();
  192. sb.append(getGnumericPart(red));
  193. sb.append(':');
  194. sb.append(getGnumericPart(green));
  195. sb.append(':');
  196. sb.append(getGnumericPart(blue));
  197. return sb.toString();
  198. }
  199. private String getGnumericPart(byte color)
  200. {
  201. String s;
  202. if (color == 0)
  203. {
  204. s = "0";
  205. }
  206. else
  207. {
  208. int c = color & 0xff; //as unsigned
  209. c = (c << 8) | c; //pad to 16-bit
  210. s = Integer.toHexString(c).toUpperCase();
  211. while (s.length() < 4)
  212. {
  213. s = "0" + s;
  214. }
  215. }
  216. return s;
  217. }
  218. }
  219. }