1. /*
  2. * @(#)JPEGImageMetadataFormat.java 1.12 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.imageio.plugins.jpeg;
  8. import javax.imageio.metadata.IIOMetadataFormat;
  9. import javax.imageio.metadata.IIOMetadataFormatImpl;
  10. import javax.imageio.ImageTypeSpecifier;
  11. import java.awt.color.ICC_Profile;
  12. import java.awt.color.ColorSpace;
  13. import java.awt.image.ColorModel;
  14. import java.util.List;
  15. import java.util.ArrayList;
  16. public class JPEGImageMetadataFormat extends JPEGMetadataFormat {
  17. private static JPEGImageMetadataFormat theInstance = null;
  18. private JPEGImageMetadataFormat() {
  19. super(JPEG.nativeImageMetadataFormatName,
  20. CHILD_POLICY_ALL);
  21. addElement("JPEGvariety",
  22. JPEG.nativeImageMetadataFormatName,
  23. CHILD_POLICY_CHOICE);
  24. addElement("markerSequence",
  25. JPEG.nativeImageMetadataFormatName,
  26. CHILD_POLICY_SEQUENCE);
  27. addElement("app0JFIF", "JPEGvariety", CHILD_POLICY_SOME);
  28. addStreamElements("markerSequence");
  29. addElement("app14Adobe", "markerSequence", CHILD_POLICY_EMPTY);
  30. addElement("sof", "markerSequence", 1, 4);
  31. addElement("sos", "markerSequence", 1, 4);
  32. addElement("JFXX", "app0JFIF", 1, Integer.MAX_VALUE);
  33. addElement("app0JFXX", "JFXX", CHILD_POLICY_CHOICE);
  34. addElement("app2ICC", "app0JFIF", CHILD_POLICY_EMPTY);
  35. addAttribute("app0JFIF",
  36. "majorVersion",
  37. DATATYPE_INTEGER,
  38. false,
  39. "1",
  40. "0", "255",
  41. true, true);
  42. addAttribute("app0JFIF",
  43. "minorVersion",
  44. DATATYPE_INTEGER,
  45. false,
  46. "2",
  47. "0", "255",
  48. true, true);
  49. List resUnits = new ArrayList();
  50. resUnits.add("0");
  51. resUnits.add("1");
  52. resUnits.add("2");
  53. addAttribute("app0JFIF",
  54. "resUnits",
  55. DATATYPE_INTEGER,
  56. false,
  57. "0",
  58. resUnits);
  59. addAttribute("app0JFIF",
  60. "Xdensity",
  61. DATATYPE_INTEGER,
  62. false,
  63. "1",
  64. "1", "65535",
  65. true, true);
  66. addAttribute("app0JFIF",
  67. "Ydensity",
  68. DATATYPE_INTEGER,
  69. false,
  70. "1",
  71. "1", "65535",
  72. true, true);
  73. addAttribute("app0JFIF",
  74. "thumbWidth",
  75. DATATYPE_INTEGER,
  76. false,
  77. "0",
  78. "0", "255",
  79. true, true);
  80. addAttribute("app0JFIF",
  81. "thumbHeight",
  82. DATATYPE_INTEGER,
  83. false,
  84. "0",
  85. "0", "255",
  86. true, true);
  87. addElement("JFIFthumbJPEG", "app0JFXX", CHILD_POLICY_SOME);
  88. addElement("JFIFthumbPalette", "app0JFXX", CHILD_POLICY_EMPTY);
  89. addElement("JFIFthumbRGB", "app0JFXX", CHILD_POLICY_EMPTY);
  90. List codes = new ArrayList();
  91. codes.add("16"); // Hex 10
  92. codes.add("17"); // Hex 11
  93. codes.add("19"); // Hex 13
  94. addAttribute("app0JFXX",
  95. "extensionCode",
  96. DATATYPE_INTEGER,
  97. false,
  98. null,
  99. codes);
  100. addChildElement("markerSequence", "JFIFthumbJPEG");
  101. addAttribute("JFIFthumbPalette",
  102. "thumbWidth",
  103. DATATYPE_INTEGER,
  104. false,
  105. null,
  106. "0", "255",
  107. true, true);
  108. addAttribute("JFIFthumbPalette",
  109. "thumbHeight",
  110. DATATYPE_INTEGER,
  111. false,
  112. null,
  113. "0", "255",
  114. true, true);
  115. addAttribute("JFIFthumbRGB",
  116. "thumbWidth",
  117. DATATYPE_INTEGER,
  118. false,
  119. null,
  120. "0", "255",
  121. true, true);
  122. addAttribute("JFIFthumbRGB",
  123. "thumbHeight",
  124. DATATYPE_INTEGER,
  125. false,
  126. null,
  127. "0", "255",
  128. true, true);
  129. addObjectValue("app2ICC", ICC_Profile.class, false, null);
  130. addAttribute("app14Adobe",
  131. "version",
  132. DATATYPE_INTEGER,
  133. false,
  134. "100",
  135. "100", "255",
  136. true, true);
  137. addAttribute("app14Adobe",
  138. "flags0",
  139. DATATYPE_INTEGER,
  140. false,
  141. "0",
  142. "0", "65535",
  143. true, true);
  144. addAttribute("app14Adobe",
  145. "flags1",
  146. DATATYPE_INTEGER,
  147. false,
  148. "0",
  149. "0", "65535",
  150. true, true);
  151. List transforms = new ArrayList();
  152. transforms.add("0");
  153. transforms.add("1");
  154. transforms.add("2");
  155. addAttribute("app14Adobe",
  156. "transform",
  157. DATATYPE_INTEGER,
  158. true,
  159. null,
  160. transforms);
  161. addElement("componentSpec", "sof", CHILD_POLICY_EMPTY);
  162. List procs = new ArrayList();
  163. procs.add("0");
  164. procs.add("1");
  165. procs.add("2");
  166. addAttribute("sof",
  167. "process",
  168. DATATYPE_INTEGER,
  169. false,
  170. null,
  171. procs);
  172. addAttribute("sof",
  173. "samplePrecision",
  174. DATATYPE_INTEGER,
  175. false,
  176. "8");
  177. addAttribute("sof",
  178. "numLines",
  179. DATATYPE_INTEGER,
  180. false,
  181. null,
  182. "0", "65535",
  183. true, true);
  184. addAttribute("sof",
  185. "samplesPerLine",
  186. DATATYPE_INTEGER,
  187. false,
  188. null,
  189. "0", "65535",
  190. true, true);
  191. List comps = new ArrayList();
  192. comps.add("1");
  193. comps.add("2");
  194. comps.add("3");
  195. comps.add("4");
  196. addAttribute("sof",
  197. "numFrameComponents",
  198. DATATYPE_INTEGER,
  199. false,
  200. null,
  201. comps);
  202. addAttribute("componentSpec",
  203. "componentId",
  204. DATATYPE_INTEGER,
  205. true,
  206. null,
  207. "0", "255",
  208. true, true);
  209. addAttribute("componentSpec",
  210. "HsamplingFactor",
  211. DATATYPE_INTEGER,
  212. true,
  213. null,
  214. "1", "255",
  215. true, true);
  216. addAttribute("componentSpec",
  217. "VsamplingFactor",
  218. DATATYPE_INTEGER,
  219. true,
  220. null,
  221. "1", "255",
  222. true, true);
  223. List tabids = new ArrayList();
  224. tabids.add("0");
  225. tabids.add("1");
  226. tabids.add("2");
  227. tabids.add("3");
  228. addAttribute("componentSpec",
  229. "QtableSelector",
  230. DATATYPE_INTEGER,
  231. true,
  232. null,
  233. tabids);
  234. addElement("scanComponentSpec", "sos", CHILD_POLICY_EMPTY);
  235. addAttribute("sos",
  236. "numScanComponents",
  237. DATATYPE_INTEGER,
  238. true,
  239. null,
  240. comps);
  241. addAttribute("sos",
  242. "startSpectralSelection",
  243. DATATYPE_INTEGER,
  244. false,
  245. "0",
  246. "0", "63",
  247. true, true);
  248. addAttribute("sos",
  249. "endSpectralSelection",
  250. DATATYPE_INTEGER,
  251. false,
  252. "63",
  253. "0", "63",
  254. true, true);
  255. addAttribute("sos",
  256. "approxHigh",
  257. DATATYPE_INTEGER,
  258. false,
  259. "0",
  260. "0", "15",
  261. true, true);
  262. addAttribute("sos",
  263. "approxLow",
  264. DATATYPE_INTEGER,
  265. false,
  266. "0",
  267. "0", "15",
  268. true, true);
  269. addAttribute("scanComponentSpec",
  270. "componentSelector",
  271. DATATYPE_INTEGER,
  272. true,
  273. null,
  274. "0", "255",
  275. true, true);
  276. addAttribute("scanComponentSpec",
  277. "dcHuffTable",
  278. DATATYPE_INTEGER,
  279. true,
  280. null,
  281. tabids);
  282. addAttribute("scanComponentSpec",
  283. "acHuffTable",
  284. DATATYPE_INTEGER,
  285. true,
  286. null,
  287. tabids);
  288. }
  289. public boolean canNodeAppear(String elementName,
  290. ImageTypeSpecifier imageType) {
  291. // All images can have these
  292. if (elementName.equals(getRootName())
  293. || elementName.equals("JPEGvariety")
  294. || isInSubtree(elementName, "markerSequence")) {
  295. return true;
  296. }
  297. // If it is an element in the app0jfif subtree, just check
  298. // that the image type is JFIF compliant.
  299. if ((isInSubtree(elementName, "app0JFIF"))
  300. && JPEG.isJFIFcompliant(imageType, true)) {
  301. return true;
  302. }
  303. return false;
  304. }
  305. public static synchronized IIOMetadataFormat getInstance() {
  306. if (theInstance == null) {
  307. theInstance = new JPEGImageMetadataFormat();
  308. }
  309. return theInstance;
  310. }
  311. }