1. /*
  2. * @(#)JPEG.java 1.14 03/01/23
  3. *
  4. * Copyright 2003 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.IIOMetadataFormatImpl;
  9. import javax.imageio.ImageTypeSpecifier;
  10. import javax.imageio.plugins.jpeg.JPEGQTable;
  11. import javax.imageio.plugins.jpeg.JPEGHuffmanTable;
  12. import java.awt.image.ColorModel;
  13. import java.awt.image.BufferedImage;
  14. import java.awt.image.DataBuffer;
  15. import java.awt.color.ColorSpace;
  16. import java.awt.color.ICC_ColorSpace;
  17. /**
  18. * A class containing JPEG-related constants, definitions, and
  19. * static methods. This class and its constants must be public so that
  20. * <code>JPEGImageWriteParam</code> can see it.
  21. */
  22. public class JPEG {
  23. // List of all the JPEG markers (pre-JPEG2000)
  24. /** For temporary use in arithmetic coding */
  25. public static final int TEM = 0x01;
  26. // Codes 0x02 - 0xBF are reserved
  27. // SOF markers for Nondifferential Huffman coding
  28. /** Baseline DCT */
  29. public static final int SOF0 = 0xC0;
  30. /** Extended Sequential DCT */
  31. public static final int SOF1 = 0xC1;
  32. /** Progressive DCT */
  33. public static final int SOF2 = 0xC2;
  34. /** Lossless Sequential */
  35. public static final int SOF3 = 0xC3;
  36. /** Define Huffman Tables */
  37. public static final int DHT = 0xC4;
  38. // SOF markers for Differential Huffman coding
  39. /** Differential Sequential DCT */
  40. public static final int SOF5 = 0xC5;
  41. /** Differential Progressive DCT */
  42. public static final int SOF6 = 0xC6;
  43. /** Differential Lossless */
  44. public static final int SOF7 = 0xC7;
  45. /** Reserved for JPEG extensions */
  46. public static final int JPG = 0xC8;
  47. // SOF markers for Nondifferential arithmetic coding
  48. /** Extended Sequential DCT, Arithmetic coding */
  49. public static final int SOF9 = 0xC9;
  50. /** Progressive DCT, Arithmetic coding */
  51. public static final int SOF10 = 0xCA;
  52. /** Lossless Sequential, Arithmetic coding */
  53. public static final int SOF11 = 0xCB;
  54. /** Define Arithmetic conditioning tables */
  55. public static final int DAC = 0xCC;
  56. // SOF markers for Differential arithmetic coding
  57. /** Differential Sequential DCT, Arithmetic coding */
  58. public static final int SOF13 = 0xCD;
  59. /** Differential Progressive DCT, Arithmetic coding */
  60. public static final int SOF14 = 0xCE;
  61. /** Differential Lossless, Arithmetic coding */
  62. public static final int SOF15 = 0xCF;
  63. // Restart Markers
  64. public static final int RST0 = 0xD0;
  65. public static final int RST1 = 0xD1;
  66. public static final int RST2 = 0xD2;
  67. public static final int RST3 = 0xD3;
  68. public static final int RST4 = 0xD4;
  69. public static final int RST5 = 0xD5;
  70. public static final int RST6 = 0xD6;
  71. public static final int RST7 = 0xD7;
  72. /** Number of restart markers */
  73. public static final int RESTART_RANGE = 8;
  74. /** Start of Image */
  75. public static final int SOI = 0xD8;
  76. /** End of Image */
  77. public static final int EOI = 0xD9;
  78. /** Start of Scan */
  79. public static final int SOS = 0xDA;
  80. /** Define Quantisation Tables */
  81. public static final int DQT = 0xDB;
  82. /** Define Number of lines */
  83. public static final int DNL = 0xDC;
  84. /** Define Restart Interval */
  85. public static final int DRI = 0xDD;
  86. /** Define Heirarchical progression */
  87. public static final int DHP = 0xDE;
  88. /** Expand reference image(s) */
  89. public static final int EXP = 0xDF;
  90. // Application markers
  91. /** APP0 used by JFIF */
  92. public static final int APP0 = 0xE0;
  93. public static final int APP1 = 0xE1;
  94. public static final int APP2 = 0xE2;
  95. public static final int APP3 = 0xE3;
  96. public static final int APP4 = 0xE4;
  97. public static final int APP5 = 0xE5;
  98. public static final int APP6 = 0xE6;
  99. public static final int APP7 = 0xE7;
  100. public static final int APP8 = 0xE8;
  101. public static final int APP9 = 0xE9;
  102. public static final int APP10 = 0xEA;
  103. public static final int APP11 = 0xEB;
  104. public static final int APP12 = 0xEC;
  105. public static final int APP13 = 0xED;
  106. /** APP14 used by Adobe */
  107. public static final int APP14 = 0xEE;
  108. public static final int APP15 = 0xEF;
  109. // codes 0xF0 to 0xFD are reserved
  110. /** Comment marker */
  111. public static final int COM = 0xFE;
  112. // JFIF Resolution units
  113. /** The X and Y units simply indicate the aspect ratio of the pixels. */
  114. public static final int DENSITY_UNIT_ASPECT_RATIO = 0;
  115. /** Pixel density is in pixels per inch. */
  116. public static final int DENSITY_UNIT_DOTS_INCH = 1;
  117. /** Pixel density is in pixels per centemeter. */
  118. public static final int DENSITY_UNIT_DOTS_CM = 2;
  119. /** The max known value for DENSITY_UNIT */
  120. public static final int NUM_DENSITY_UNIT = 3;
  121. // Adobe transform values
  122. public static final int ADOBE_IMPOSSIBLE = -1;
  123. public static final int ADOBE_UNKNOWN = 0;
  124. public static final int ADOBE_YCC = 1;
  125. public static final int ADOBE_YCCK = 2;
  126. // Spi initialization stuff
  127. public static final String vendor = "Sun Microsystems, Inc.";
  128. public static final String version = "0.5";
  129. // Names of the formats we can read or write
  130. public static final String [] names = {"JPEG", "jpeg", "JPG", "jpg"};
  131. public static final String [] suffixes = {"jpg", "jpeg"};
  132. public static final String [] MIMETypes = {"image/jpeg"};
  133. public static final String nativeImageMetadataFormatName =
  134. "javax_imageio_jpeg_image_1.0";
  135. public static final String nativeImageMetadataFormatClassName =
  136. "com.sun.imageio.plugins.jpeg.JPEGImageMetadataFormat";
  137. public static final String nativeStreamMetadataFormatName =
  138. "javax_imageio_jpeg_stream_1.0";
  139. public static final String nativeStreamMetadataFormatClassName =
  140. "com.sun.imageio.plugins.jpeg.JPEGStreamMetadataFormat";
  141. // IJG Color codes.
  142. public static final int JCS_UNKNOWN = 0; // error/unspecified
  143. public static final int JCS_GRAYSCALE = 1; // monochrome
  144. public static final int JCS_RGB = 2; // red/green/blue
  145. public static final int JCS_YCbCr = 3; // Y/Cb/Cr (also known as YUV)
  146. public static final int JCS_CMYK = 4; // C/M/Y/K
  147. public static final int JCS_YCC = 5; // PhotoYCC
  148. public static final int JCS_RGBA = 6; // RGB-Alpha
  149. public static final int JCS_YCbCrA = 7; // Y/Cb/Cr/Alpha
  150. // 8 and 9 were old "Legacy" codes which the old code never identified
  151. // on reading anyway. Support for writing them is being dropped, too.
  152. public static final int JCS_YCCA = 10; // PhotoYCC-Alpha
  153. public static final int JCS_YCCK = 11; // Y/Cb/Cr/K
  154. public static final int NUM_JCS_CODES = JCS_YCCK+1;
  155. /** IJG can handle up to 4-channel JPEGs */
  156. public static final int [] [] bandOffsets = {{0},
  157. {0, 1},
  158. {0, 1, 2},
  159. {0, 1, 2, 3}};
  160. public static final int [] bOffsRGB = { 2, 1, 0 };
  161. protected static final ColorSpace sRGB =
  162. ColorSpace.getInstance(ColorSpace.CS_sRGB);
  163. protected static ColorSpace YCC = null; // Can't be final
  164. static {
  165. try {
  166. YCC = ColorSpace.getInstance(ColorSpace.CS_PYCC);
  167. } catch (IllegalArgumentException e) {
  168. // PYCC.pf may not always be installed
  169. }
  170. }
  171. // Default value for ImageWriteParam
  172. public static final float DEFAULT_QUALITY = 0.75F;
  173. /**
  174. * Returns <code>true</code> if the given <code>ColorSpace</code>
  175. * object is an instance of ICC_ColorSpace but is not one of the
  176. * standard <code>ColorSpaces</code> returned by
  177. * <code>ColorSpace.getInstance()</code>.
  178. */
  179. static boolean isNonStandardICC(ColorSpace cs) {
  180. boolean retval = false;
  181. if ((cs instanceof ICC_ColorSpace)
  182. && (!cs.isCS_sRGB())
  183. && (!cs.equals(ColorSpace.getInstance(ColorSpace.CS_CIEXYZ)))
  184. && (!cs.equals(ColorSpace.getInstance(ColorSpace.CS_GRAY)))
  185. && (!cs.equals(ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB)))
  186. && (!cs.equals(ColorSpace.getInstance(ColorSpace.CS_PYCC)))
  187. ) {
  188. retval = true;
  189. }
  190. return retval;
  191. }
  192. /**
  193. * Returns <code>true</code> if the given imageType can be used
  194. * in a JFIF file. If <code>input</code> is true, then the
  195. * image type is considered before colorspace conversion.
  196. */
  197. static boolean isJFIFcompliant(ImageTypeSpecifier imageType,
  198. boolean input) {
  199. ColorModel cm = imageType.getColorModel();
  200. // Can't have alpha
  201. if (cm.hasAlpha()) {
  202. return false;
  203. }
  204. // Gray is OK, always
  205. int numComponents = imageType.getNumComponents();
  206. if (numComponents == 1) {
  207. return true;
  208. }
  209. // If it isn't gray, it must have 3 channels
  210. if (numComponents != 3) {
  211. return false;
  212. }
  213. if (input) {
  214. // Must be RGB
  215. if (cm.getColorSpace().getType() == ColorSpace.TYPE_RGB) {
  216. return true;
  217. }
  218. } else {
  219. // Must be YCbCr
  220. if (cm.getColorSpace().getType() == ColorSpace.TYPE_YCbCr) {
  221. return true;
  222. }
  223. }
  224. return false;
  225. }
  226. /**
  227. * Given an image type, return the Adobe transform corresponding to
  228. * that type, or ADOBE_IMPOSSIBLE if the image type is incompatible
  229. * with an Adobe marker segment. If <code>input</code> is true, then
  230. * the image type is considered before colorspace conversion.
  231. */
  232. static int transformForType(ImageTypeSpecifier imageType, boolean input) {
  233. int retval = ADOBE_IMPOSSIBLE;
  234. ColorModel cm = imageType.getColorModel();
  235. switch (cm.getColorSpace().getType()) {
  236. case ColorSpace.TYPE_GRAY:
  237. retval = ADOBE_UNKNOWN;
  238. break;
  239. case ColorSpace.TYPE_RGB:
  240. retval = input ? ADOBE_YCC : ADOBE_UNKNOWN;
  241. break;
  242. case ColorSpace.TYPE_YCbCr:
  243. retval = ADOBE_YCC;
  244. break;
  245. case ColorSpace.TYPE_CMYK:
  246. retval = input ? ADOBE_YCCK : ADOBE_IMPOSSIBLE;
  247. }
  248. return retval;
  249. }
  250. /**
  251. * Converts an ImageWriteParam (i.e. IJG) non-linear quality value
  252. * to a float suitable for passing to JPEGQTable.getScaledInstance().
  253. */
  254. static float convertToLinearQuality(float quality) {
  255. // The following is converted from the IJG code.
  256. if (quality <= 0.0F) {
  257. quality = 0.01F;
  258. }
  259. if (quality > 1.00F) {
  260. quality = 1.00F;
  261. }
  262. if (quality < 0.5F) {
  263. quality = 0.5F / quality;
  264. } else {
  265. quality = 2.0F - (quality * 2.0F);
  266. }
  267. return quality;
  268. }
  269. /**
  270. * Return an array of default, visually lossless quantization tables.
  271. */
  272. static JPEGQTable [] getDefaultQTables() {
  273. JPEGQTable [] qTables = new JPEGQTable[2];
  274. qTables[0] = JPEGQTable.K1Div2Luminance;
  275. qTables[1] = JPEGQTable.K2Div2Chrominance;
  276. return qTables;
  277. }
  278. /**
  279. * Return an array of default Huffman tables.
  280. */
  281. static JPEGHuffmanTable [] getDefaultHuffmanTables(boolean wantDC) {
  282. JPEGHuffmanTable [] tables = new JPEGHuffmanTable[2];
  283. if (wantDC) {
  284. tables[0] = JPEGHuffmanTable.StdDCLuminance;
  285. tables[1] = JPEGHuffmanTable.StdDCChrominance;
  286. } else {
  287. tables[0] = JPEGHuffmanTable.StdACLuminance;
  288. tables[1] = JPEGHuffmanTable.StdACChrominance;
  289. }
  290. return tables;
  291. }
  292. }