PageRenderTime 52ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/src/org/eclipse/swt/internal/image/JPEGFileFormat.d

https://github.com/yurigoro/org.eclipse.swt.win32.win32.x86
D | 1903 lines | 1738 code | 40 blank | 125 comment | 317 complexity | 668425e91c7ccb422e2cb2a2888c7e1a MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*******************************************************************************
  2. * Copyright (c) 2000, 2008 IBM Corporation and others.
  3. * All rights reserved. This source file is made available under the terms contained in the README file
  4. * accompanying this program. The README file should be located in the about_files directory of the
  5. * plug-in that contains this source file.
  6. *
  7. * Contributors:
  8. * IBM Corporation - initial API and implementation
  9. * Port to the D programming language:
  10. * Frank Benoit <benoit@tionex.de>
  11. *******************************************************************************/
  12. module org.eclipse.swt.internal.image.JPEGFileFormat;
  13. import org.eclipse.swt.SWT;
  14. import org.eclipse.swt.internal.image.JPEGFrameHeader;
  15. import org.eclipse.swt.internal.image.JPEGScanHeader;
  16. import org.eclipse.swt.internal.image.JPEGHuffmanTable;
  17. import org.eclipse.swt.internal.image.JPEGAppn;
  18. import org.eclipse.swt.internal.image.JPEGSegment;
  19. import org.eclipse.swt.internal.image.FileFormat;
  20. import org.eclipse.swt.internal.image.JPEGComment;
  21. import org.eclipse.swt.internal.image.JPEGArithmeticConditioningTable;
  22. import org.eclipse.swt.internal.image.JPEGRestartInterval;
  23. import org.eclipse.swt.internal.image.JPEGQuantizationTable;
  24. import org.eclipse.swt.internal.image.JPEGStartOfImage;
  25. import org.eclipse.swt.internal.image.JPEGDecoder;
  26. import org.eclipse.swt.internal.image.JPEGEndOfImage;
  27. import java.lang.all;
  28. import org.eclipse.swt.graphics.RGB;
  29. import org.eclipse.swt.graphics.PaletteData;
  30. final class JPEGFileFormat : FileFormat {
  31. int restartInterval;
  32. JPEGFrameHeader frameHeader;
  33. int imageWidth, imageHeight;
  34. int interleavedMcuCols, interleavedMcuRows;
  35. int maxV, maxH;
  36. bool progressive;
  37. int samplePrecision;
  38. int nComponents;
  39. int[][] frameComponents;
  40. int[] componentIds;
  41. byte[][] imageComponents;
  42. int[] dataUnit;
  43. int[][][] dataUnits;
  44. int[] precedingDCs;
  45. JPEGScanHeader scanHeader;
  46. byte[] dataBuffer;
  47. int currentBitCount;
  48. int bufferCurrentPosition;
  49. int restartsToGo;
  50. int nextRestartNumber;
  51. JPEGHuffmanTable[] acHuffmanTables;
  52. JPEGHuffmanTable[] dcHuffmanTables;
  53. int[][] quantizationTables;
  54. int currentByte;
  55. int encoderQFactor = 75;
  56. int eobrun = 0;
  57. /* JPEGConstants */
  58. public static const int DCTSIZE = 8;
  59. public static const int DCTSIZESQR = 64;
  60. /* JPEGFixedPointConstants */
  61. public static const int FIX_0_899976223 = 7373;
  62. public static const int FIX_1_961570560 = 16069;
  63. public static const int FIX_2_053119869 = 16819;
  64. public static const int FIX_0_298631336 = 2446;
  65. public static const int FIX_1_847759065 = 15137;
  66. public static const int FIX_1_175875602 = 9633;
  67. public static const int FIX_3_072711026 = 25172;
  68. public static const int FIX_0_765366865 = 6270;
  69. public static const int FIX_2_562915447 = 20995;
  70. public static const int FIX_0_541196100 = 4433;
  71. public static const int FIX_0_390180644 = 3196;
  72. public static const int FIX_1_501321110 = 12299;
  73. /* JPEGMarkerCodes */
  74. public static const int APP0 = 0xFFE0;
  75. public static const int APP15 = 0xFFEF;
  76. public static const int COM = 0xFFFE;
  77. public static const int DAC = 0xFFCC;
  78. public static const int DHP = 0xFFDE;
  79. public static const int DHT = 0xFFC4;
  80. public static const int DNL = 0xFFDC;
  81. public static const int DRI = 0xFFDD;
  82. public static const int DQT = 0xFFDB;
  83. public static const int EOI = 0xFFD9;
  84. public static const int EXP = 0xFFDF;
  85. public static const int JPG = 0xFFC8;
  86. public static const int JPG0 = 0xFFF0;
  87. public static const int JPG13 = 0xFFFD;
  88. public static const int RST0 = 0xFFD0;
  89. public static const int RST1 = 0xFFD1;
  90. public static const int RST2 = 0xFFD2;
  91. public static const int RST3 = 0xFFD3;
  92. public static const int RST4 = 0xFFD4;
  93. public static const int RST5 = 0xFFD5;
  94. public static const int RST6 = 0xFFD6;
  95. public static const int RST7 = 0xFFD7;
  96. public static const int SOF0 = 0xFFC0;
  97. public static const int SOF1 = 0xFFC1;
  98. public static const int SOF2 = 0xFFC2;
  99. public static const int SOF3 = 0xFFC3;
  100. public static const int SOF5 = 0xFFC5;
  101. public static const int SOF6 = 0xFFC6;
  102. public static const int SOF7 = 0xFFC7;
  103. public static const int SOF9 = 0xFFC9;
  104. public static const int SOF10 = 0xFFCA;
  105. public static const int SOF11 = 0xFFCB;
  106. public static const int SOF13 = 0xFFCD;
  107. public static const int SOF14 = 0xFFCE;
  108. public static const int SOF15 = 0xFFCF;
  109. public static const int SOI = 0xFFD8;
  110. public static const int SOS = 0xFFDA;
  111. public static const int TEM = 0xFF01;
  112. /* JPEGFrameComponentParameterConstants */
  113. public static const int TQI = 0;
  114. public static const int HI = 1;
  115. public static const int VI = 2;
  116. public static const int CW = 3;
  117. public static const int CH = 4;
  118. /* JPEGScanComponentParameterConstants */
  119. public static const int DC = 0;
  120. public static const int AC = 1;
  121. /* JFIF Component Constants */
  122. public static const int ID_Y = 1 - 1;
  123. public static const int ID_CB = 2 - 1;
  124. public static const int ID_CR = 3 - 1;
  125. mixin(gshared!(`public static /*const*/ RGB[] RGB16;`));
  126. public static const int[] ExtendTest = [
  127. 0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,
  128. 4096, 8192, 16384, 32768, 65536, 131072, 262144
  129. ];
  130. public static const int[] ExtendOffset = [
  131. 0, -1, -3, -7, -15, -31, -63, -127, -255, -511, -1023, -2047,
  132. -4095, -8191, -16383, -32767, -65535, -131071, -262143
  133. ];
  134. public static const int[] ZigZag8x8 = [
  135. 0, 1, 8, 16, 9, 2, 3, 10,
  136. 17, 24, 32, 25, 18, 11, 4, 5,
  137. 12, 19, 26, 33, 40, 48, 41, 34,
  138. 27, 20, 13, 6, 7, 14, 21, 28,
  139. 35, 42, 49, 56, 57, 50, 43, 36,
  140. 29, 22, 15, 23, 30, 37, 44, 51,
  141. 58, 59, 52, 45, 38, 31, 39, 46,
  142. 53, 60, 61, 54, 47, 55, 62, 63
  143. ];
  144. mixin(gshared!(`public static int[] CrRTable, CbBTable, CrGTable, CbGTable;`));
  145. mixin(gshared!(`public static int[] RYTable, GYTable, BYTable,
  146. RCbTable, GCbTable, BCbTable, RCrTable, GCrTable, BCrTable, NBitsTable;`));
  147. //public static void static_this() {
  148. mixin(sharedStaticThis!(`{
  149. RGB16 = [
  150. new RGB(0,0,0),
  151. new RGB(0x80,0,0),
  152. new RGB(0,0x80,0),
  153. new RGB(0x80,0x80,0),
  154. new RGB(0,0,0x80),
  155. new RGB(0x80,0,0x80),
  156. new RGB(0,0x80,0x80),
  157. new RGB(0xC0,0xC0,0xC0),
  158. new RGB(0x80,0x80,0x80),
  159. new RGB(0xFF,0,0),
  160. new RGB(0,0xFF,0),
  161. new RGB(0xFF,0xFF,0),
  162. new RGB(0,0,0xFF),
  163. new RGB(0xFF,0,0xFF),
  164. new RGB(0,0xFF,0xFF),
  165. new RGB(0xFF,0xFF,0xFF)
  166. ];
  167. int [] rYTable = new int[256];
  168. int [] gYTable = new int[256];
  169. int [] bYTable = new int[256];
  170. int [] rCbTable = new int[256];
  171. int [] gCbTable = new int[256];
  172. int [] bCbTable = new int[256];
  173. int [] rCrTable = new int[256];
  174. int [] gCrTable = new int[256];
  175. int [] bCrTable = new int[256];
  176. for (int i = 0; i < 256; i++) {
  177. rYTable[i] = i * 19595;
  178. gYTable[i] = i * 38470;
  179. bYTable[i] = i * 7471 + 32768;
  180. rCbTable[i] = i * -11059;
  181. gCbTable[i] = i * -21709;
  182. bCbTable[i] = i * 32768 + 8388608;
  183. gCrTable[i] = i * -27439;
  184. bCrTable[i] = i * -5329;
  185. }
  186. RYTable = rYTable;
  187. GYTable = gYTable;
  188. BYTable = bYTable;
  189. RCbTable = rCbTable;
  190. GCbTable = gCbTable;
  191. BCbTable = bCbTable;
  192. RCrTable = bCbTable;
  193. GCrTable = gCrTable;
  194. BCrTable = bCrTable;
  195. /* Initialize YCbCr-RGB Tables */
  196. int [] crRTable = new int[256];
  197. int [] cbBTable = new int[256];
  198. int [] crGTable = new int[256];
  199. int [] cbGTable = new int[256];
  200. for (int i = 0; i < 256; i++) {
  201. int x2 = 2 * i - 255;
  202. crRTable[i] = (45941 * x2 + 32768) >> 16;
  203. cbBTable[i] = (58065 * x2 + 32768) >> 16;
  204. crGTable[i] = -23401 * x2;
  205. cbGTable[i] = -11277 * x2 + 32768;
  206. }
  207. CrRTable = crRTable;
  208. CbBTable = cbBTable;
  209. CrGTable = crGTable;
  210. CbGTable = cbGTable;
  211. /* Initialize BitCount Table */
  212. int nBits = 1;
  213. int power2 = 2;
  214. int [] nBitsTable = new int[2048];
  215. nBitsTable[0] = 0;
  216. for (int i = 1; i < nBitsTable.length; i++) {
  217. if (!(i < power2)) {
  218. nBits++;
  219. power2 *= 2;
  220. }
  221. nBitsTable[i] = nBits;
  222. }
  223. NBitsTable = nBitsTable;
  224. }`));
  225. void compress(ImageData image, byte[] dataYComp, byte[] dataCbComp, byte[] dataCrComp) {
  226. int srcWidth = image.width;
  227. int srcHeight = image.height;
  228. int vhFactor = maxV * maxH;
  229. int[] frameComponent;
  230. imageComponents = new byte[][](nComponents);
  231. for (int i = 0; i < nComponents; i++) {
  232. frameComponent = frameComponents[componentIds[i]];
  233. imageComponents[i] = new byte[frameComponent[CW] * frameComponent[CH]];
  234. }
  235. frameComponent = frameComponents[componentIds[ID_Y]];
  236. for (int yPos = 0; yPos < srcHeight; yPos++) {
  237. int srcOfs = yPos * srcWidth;
  238. int dstOfs = yPos * frameComponent[CW];
  239. System.arraycopy(dataYComp, srcOfs, imageComponents[ID_Y], dstOfs, srcWidth);
  240. }
  241. frameComponent = frameComponents[componentIds[ID_CB]];
  242. for (int yPos = 0; yPos < srcHeight / maxV; yPos++) {
  243. int destRowIndex = yPos * frameComponent[CW];
  244. for (int xPos = 0; xPos < srcWidth / maxH; xPos++) {
  245. int sum = 0;
  246. for (int iv = 0; iv < maxV; iv++) {
  247. int srcIndex = (yPos * maxV + iv) * srcWidth + (xPos * maxH);
  248. for (int ih = 0; ih < maxH; ih++) {
  249. sum += dataCbComp[srcIndex + ih] & 0xFF;
  250. }
  251. }
  252. imageComponents[ID_CB][destRowIndex + xPos] = cast(byte)(sum / vhFactor);
  253. }
  254. }
  255. frameComponent = frameComponents[componentIds[ID_CR]];
  256. for (int yPos = 0; yPos < srcHeight / maxV; yPos++) {
  257. int destRowIndex = yPos * frameComponent[CW];
  258. for (int xPos = 0; xPos < srcWidth / maxH; xPos++) {
  259. int sum = 0;
  260. for (int iv = 0; iv < maxV; iv++) {
  261. int srcIndex = (yPos * maxV + iv) * srcWidth + (xPos * maxH);
  262. for (int ih = 0; ih < maxH; ih++) {
  263. sum += dataCrComp[srcIndex + ih] & 0xFF;
  264. }
  265. }
  266. imageComponents[ID_CR][destRowIndex + xPos] = cast(byte)(sum / vhFactor);
  267. }
  268. }
  269. for (int iComp = 0; iComp < nComponents; iComp++) {
  270. byte[] imageComponent = imageComponents[iComp];
  271. frameComponent = frameComponents[componentIds[iComp]];
  272. int hFactor = frameComponent[HI];
  273. int vFactor = frameComponent[VI];
  274. int componentWidth = frameComponent[CW];
  275. int componentHeight = frameComponent[CH];
  276. int compressedWidth = srcWidth / (maxH / hFactor);
  277. int compressedHeight = srcHeight / (maxV / vFactor);
  278. if (compressedWidth < componentWidth) {
  279. int delta = componentWidth - compressedWidth;
  280. for (int yPos = 0; yPos < compressedHeight; yPos++) {
  281. int dstOfs = ((yPos + 1) * componentWidth - delta);
  282. int dataValue = imageComponent[(dstOfs > 0) ? dstOfs - 1 : 0] & 0xFF;
  283. for (int i = 0; i < delta; i++) {
  284. imageComponent[dstOfs + i] = cast(byte)dataValue;
  285. }
  286. }
  287. }
  288. if (compressedHeight < componentHeight) {
  289. int srcOfs = (compressedHeight > 0) ? (compressedHeight - 1) * componentWidth : 1;
  290. for (int yPos = (compressedHeight > 0) ? compressedHeight : 1; yPos <= componentHeight; yPos++) {
  291. int dstOfs = (yPos - 1) * componentWidth;
  292. System.arraycopy(imageComponent, srcOfs, imageComponent, dstOfs, componentWidth);
  293. }
  294. }
  295. }
  296. }
  297. void convert4BitRGBToYCbCr(ImageData image) {
  298. RGB[] rgbs = image.getRGBs();
  299. int paletteSize = rgbs.length;
  300. byte[] yComp = new byte[paletteSize];
  301. byte[] cbComp = new byte[paletteSize];
  302. byte[] crComp = new byte[paletteSize];
  303. int srcWidth = image.width;
  304. int srcHeight = image.height;
  305. for (int i = 0; i < paletteSize; i++) {
  306. RGB color = rgbs[i];
  307. int r = color.red;
  308. int g = color.green;
  309. int b = color.blue;
  310. int n = RYTable[r] + GYTable[g] + BYTable[b];
  311. yComp[i] = cast(byte)(n >> 16);
  312. if ((n < 0) && ((n & 0xFFFF) !is 0)) yComp[i]--;
  313. n = RCbTable[r] + GCbTable[g] + BCbTable[b];
  314. cbComp[i] = cast(byte)(n >> 16);
  315. if ((n < 0) && ((n & 0xFFFF) !is 0)) cbComp[i]--;
  316. n = RCrTable[r] + GCrTable[g] + BCrTable[b];
  317. crComp[i] = cast(byte)(n >> 16);
  318. if ((n < 0) && ((n & 0xFFFF) !is 0)) crComp[i]--;
  319. }
  320. int bSize = srcWidth * srcHeight;
  321. byte[] dataYComp = new byte[bSize];
  322. byte[] dataCbComp = new byte[bSize];
  323. byte[] dataCrComp = new byte[bSize];
  324. byte[] origData = image.data;
  325. int bytesPerLine = image.bytesPerLine;
  326. int maxScanlineByte = srcWidth >> 1;
  327. for (int yPos = 0; yPos < srcHeight; yPos++) {
  328. for (int xPos = 0; xPos < maxScanlineByte; xPos++) {
  329. int srcIndex = yPos * bytesPerLine + xPos;
  330. int dstIndex = yPos * srcWidth + (xPos * 2);
  331. int value2 = origData[srcIndex] & 0xFF;
  332. int value1 = value2 >> 4;
  333. value2 &= 0x0F;
  334. dataYComp[dstIndex] = yComp[value1];
  335. dataCbComp[dstIndex] = cbComp[value1];
  336. dataCrComp[dstIndex] = crComp[value1];
  337. dataYComp[dstIndex + 1] = yComp[value2];
  338. dataCbComp[dstIndex + 1] = cbComp[value2];
  339. dataCrComp[dstIndex + 1] = crComp[value2];
  340. }
  341. }
  342. compress(image, dataYComp, dataCbComp, dataCrComp);
  343. }
  344. void convert8BitRGBToYCbCr(ImageData image) {
  345. RGB[] rgbs = image.getRGBs();
  346. int paletteSize = rgbs.length;
  347. byte[] yComp = new byte[paletteSize];
  348. byte[] cbComp = new byte[paletteSize];
  349. byte[] crComp = new byte[paletteSize];
  350. int srcWidth = image.width;
  351. int srcHeight = image.height;
  352. for (int i = 0; i < paletteSize; i++) {
  353. RGB color = rgbs[i];
  354. int r = color.red;
  355. int g = color.green;
  356. int b = color.blue;
  357. int n = RYTable[r] + GYTable[g] + BYTable[b];
  358. yComp[i] = cast(byte)(n >> 16);
  359. if ((n < 0) && ((n & 0xFFFF) !is 0)) yComp[i]--;
  360. n = RCbTable[r] + GCbTable[g] + BCbTable[b];
  361. cbComp[i] = cast(byte)(n >> 16);
  362. if ((n < 0) && ((n & 0xFFFF) !is 0)) cbComp[i]--;
  363. n = RCrTable[r] + GCrTable[g] + BCrTable[b];
  364. crComp[i] = cast(byte)(n >> 16);
  365. if ((n < 0) && ((n & 0xFFFF) !is 0)) crComp[i]--;
  366. }
  367. int dstWidth = image.width;
  368. int dstHeight = srcHeight;
  369. int stride = ((srcWidth + 3) >> 2) << 2;
  370. int bSize = dstWidth * dstHeight;
  371. byte[] dataYComp = new byte[bSize];
  372. byte[] dataCbComp = new byte[bSize];
  373. byte[] dataCrComp = new byte[bSize];
  374. byte[] origData = image.data;
  375. for (int yPos = 0; yPos < srcHeight; yPos++) {
  376. int srcRowIndex = yPos * stride;
  377. int dstRowIndex = yPos * dstWidth;
  378. for (int xPos = 0; xPos < srcWidth; xPos++) {
  379. int value = origData[srcRowIndex + xPos] & 0xFF;
  380. int dstIndex = dstRowIndex + xPos;
  381. dataYComp[dstIndex] = yComp[value];
  382. dataCbComp[dstIndex] = cbComp[value];
  383. dataCrComp[dstIndex] = crComp[value];
  384. }
  385. }
  386. compress(image, dataYComp, dataCbComp, dataCrComp);
  387. }
  388. byte[] convertCMYKToRGB() {
  389. /* Unsupported CMYK format. Answer an empty byte array. */
  390. return new byte[0];
  391. }
  392. void convertImageToYCbCr(ImageData image) {
  393. switch (image.depth) {
  394. case 4:
  395. convert4BitRGBToYCbCr(image);
  396. return;
  397. case 8:
  398. convert8BitRGBToYCbCr(image);
  399. return;
  400. case 16:
  401. case 24:
  402. case 32:
  403. convertMultiRGBToYCbCr(image);
  404. return;
  405. default:
  406. SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
  407. }
  408. return;
  409. }
  410. void convertMultiRGBToYCbCr(ImageData image) {
  411. int srcWidth = image.width;
  412. int srcHeight = image.height;
  413. int bSize = srcWidth * srcHeight;
  414. byte[] dataYComp = new byte[bSize];
  415. byte[] dataCbComp = new byte[bSize];
  416. byte[] dataCrComp = new byte[bSize];
  417. PaletteData palette = image.palette;
  418. int[] buffer = new int[srcWidth];
  419. if (palette.isDirect) {
  420. int redMask = palette.redMask;
  421. int greenMask = palette.greenMask;
  422. int blueMask = palette.blueMask;
  423. int redShift = palette.redShift;
  424. int greenShift = palette.greenShift;
  425. int blueShift = palette.blueShift;
  426. for (int yPos = 0; yPos < srcHeight; yPos++) {
  427. image.getPixels(0, yPos, srcWidth, buffer, 0);
  428. int dstRowIndex = yPos * srcWidth;
  429. for (int xPos = 0; xPos < srcWidth; xPos++) {
  430. int pixel = buffer[xPos];
  431. int dstDataIndex = dstRowIndex + xPos;
  432. int r = pixel & redMask;
  433. r = (redShift < 0) ? r >>> -redShift : r << redShift;
  434. int g = pixel & greenMask;
  435. g = (greenShift < 0) ? g >>> -greenShift : g << greenShift;
  436. int b = pixel & blueMask;
  437. b = (blueShift < 0) ? b >>> -blueShift : b << blueShift;
  438. dataYComp[dstDataIndex] = cast(byte)((RYTable[r] + GYTable[g] + BYTable[b]) >> 16);
  439. dataCbComp[dstDataIndex] = cast(byte)((RCbTable[r] + GCbTable[g] + BCbTable[b]) >> 16);
  440. dataCrComp[dstDataIndex] = cast(byte)((RCrTable[r] + GCrTable[g] + BCrTable[b]) >> 16);
  441. }
  442. }
  443. } else {
  444. for (int yPos = 0; yPos < srcHeight; yPos++) {
  445. image.getPixels(0, yPos, srcWidth, buffer, 0);
  446. int dstRowIndex = yPos * srcWidth;
  447. for (int xPos = 0; xPos < srcWidth; xPos++) {
  448. int pixel = buffer[xPos];
  449. int dstDataIndex = dstRowIndex + xPos;
  450. RGB rgb = palette.getRGB(pixel);
  451. int r = rgb.red;
  452. int g = rgb.green;
  453. int b = rgb.blue;
  454. dataYComp[dstDataIndex] = cast(byte)((RYTable[r] + GYTable[g] + BYTable[b]) >> 16);
  455. dataCbComp[dstDataIndex] = cast(byte)((RCbTable[r] + GCbTable[g] + BCbTable[b]) >> 16);
  456. dataCrComp[dstDataIndex] = cast(byte)((RCrTable[r] + GCrTable[g] + BCrTable[b]) >> 16);
  457. }
  458. }
  459. }
  460. compress(image, dataYComp, dataCbComp, dataCrComp);
  461. }
  462. byte[] convertYToRGB() {
  463. int compWidth = frameComponents[componentIds[ID_Y]][CW];
  464. int bytesPerLine = (((imageWidth * 8 + 7) / 8) + 3) / 4 * 4;
  465. byte[] data = new byte[bytesPerLine * imageHeight];
  466. byte[] yComp = imageComponents[ID_Y];
  467. int destIndex = 0;
  468. for (int i = 0; i < imageHeight; i++) {
  469. int srcIndex = i * compWidth;
  470. for (int j = 0; j < bytesPerLine; j++) {
  471. int y = yComp[srcIndex] & 0xFF;
  472. if (y < 0) {
  473. y = 0;
  474. } else {
  475. if (y > 255) y = 255;
  476. }
  477. if (j >= imageWidth) {
  478. y = 0;
  479. }
  480. data[destIndex] = cast(byte)y;
  481. srcIndex++;
  482. destIndex++;
  483. }
  484. }
  485. return data;
  486. }
  487. byte[] convertYCbCrToRGB() {
  488. /**
  489. * Convert existing image components into an RGB format.
  490. * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
  491. * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
  492. * The conversion equations to be implemented are therefore
  493. * R = Y + 1.40200 * Cr
  494. * G = Y - 0.34414 * Cb - 0.71414 * Cr
  495. * B = Y + 1.77200 * Cb
  496. * where Cb and Cr represent the incoming values less MAXJSAMPLE/2.
  497. * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
  498. *
  499. * To avoid floating-point arithmetic, we represent the fractional constants
  500. * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
  501. * the products by 2^16, with appropriate rounding, to get the correct answer.
  502. * Notice that Y, being an integral input, does not contribute any fraction
  503. * so it need not participate in the rounding.
  504. *
  505. * For even more speed, we avoid doing any multiplications in the inner loop
  506. * by precalculating the constants times Cb and Cr for all possible values.
  507. * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
  508. * for 12-bit samples it is still acceptable. It's not very reasonable for
  509. * 16-bit samples, but if you want lossless storage you shouldn't be changing
  510. * colorspace anyway.
  511. * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
  512. * values for the G calculation are left scaled up, since we must add them
  513. * together before rounding.
  514. */
  515. int bSize = imageWidth * imageHeight * nComponents;
  516. byte[] rgbData = new byte[bSize];
  517. int destIndex = 0;
  518. expandImageComponents();
  519. byte[] yComp = imageComponents[ID_Y];
  520. byte[] cbComp = imageComponents[ID_CB];
  521. byte[] crComp = imageComponents[ID_CR];
  522. int compWidth = frameComponents[componentIds[ID_Y]][CW];
  523. for (int v = 0; v < imageHeight; v++) {
  524. int srcIndex = v * compWidth;
  525. for (int i = 0; i < imageWidth; i++) {
  526. int y = yComp[srcIndex] & 0xFF;
  527. int cb = cbComp[srcIndex] & 0xFF;
  528. int cr = crComp[srcIndex] & 0xFF;
  529. int r = y + CrRTable[cr];
  530. int g = y + ((CbGTable[cb] + CrGTable[cr]) >> 16);
  531. int b = y + CbBTable[cb];
  532. if (r < 0) {
  533. r = 0;
  534. } else {
  535. if (r > 255) r = 255;
  536. }
  537. if (g < 0) {
  538. g = 0;
  539. } else {
  540. if (g > 255) g = 255;
  541. }
  542. if (b < 0) {
  543. b = 0;
  544. } else {
  545. if (b > 255) b = 255;
  546. }
  547. rgbData[destIndex] = cast(byte)b;
  548. rgbData[destIndex + 1] = cast(byte)g;
  549. rgbData[destIndex + 2] = cast(byte)r;
  550. destIndex += 3;
  551. srcIndex++;
  552. }
  553. }
  554. return rgbData;
  555. }
  556. void decodeACCoefficients(int[] dataUnit, int iComp) {
  557. int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
  558. JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
  559. int k = 1;
  560. while (k < 64) {
  561. int rs = decodeUsingTable(acTable);
  562. int r = rs >> 4;
  563. int s = rs & 0xF;
  564. if (s is 0) {
  565. if (r is 15) {
  566. k += 16;
  567. } else {
  568. break;
  569. }
  570. } else {
  571. k += r;
  572. int bits = receive(s);
  573. dataUnit[ZigZag8x8[k]] = extendBy(bits, s);
  574. k++;
  575. }
  576. }
  577. }
  578. void decodeACFirstCoefficients(int[] dataUnit, int iComp, int start, int end, int approxBit) {
  579. if (eobrun > 0) {
  580. eobrun--;
  581. return;
  582. }
  583. int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
  584. JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
  585. int k = start;
  586. while (k <= end) {
  587. int rs = decodeUsingTable(acTable);
  588. int r = rs >> 4;
  589. int s = rs & 0xF;
  590. if (s is 0) {
  591. if (r is 15) {
  592. k += 16;
  593. } else {
  594. eobrun = (1 << r) + receive(r) - 1;
  595. break;
  596. }
  597. } else {
  598. k += r;
  599. int bits = receive(s);
  600. dataUnit[ZigZag8x8[k]] = extendBy(bits, s) << approxBit;
  601. k++;
  602. }
  603. }
  604. }
  605. void decodeACRefineCoefficients(int[] dataUnit, int iComp, int start, int end, int approxBit) {
  606. int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
  607. JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
  608. int k = start;
  609. while (k <= end) {
  610. if (eobrun > 0) {
  611. while (k <= end) {
  612. int zzIndex = ZigZag8x8[k];
  613. if (dataUnit[zzIndex] !is 0) {
  614. dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit);
  615. }
  616. k++;
  617. }
  618. eobrun--;
  619. } else {
  620. int rs = decodeUsingTable(acTable);
  621. int r = rs >> 4;
  622. int s = rs & 0xF;
  623. if (s is 0) {
  624. if (r is 15) {
  625. int zeros = 0;
  626. while (zeros < 16 && k <= end) {
  627. int zzIndex = ZigZag8x8[k];
  628. if (dataUnit[zzIndex] !is 0) {
  629. dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit);
  630. } else {
  631. zeros++;
  632. }
  633. k++;
  634. }
  635. } else {
  636. eobrun = (1 << r) + receive(r);
  637. }
  638. } else {
  639. int bit = receive(s);
  640. int zeros = 0;
  641. int zzIndex = ZigZag8x8[k];
  642. while ((zeros < r || dataUnit[zzIndex] !is 0) && k <= end) {
  643. if (dataUnit[zzIndex] !is 0) {
  644. dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit);
  645. } else {
  646. zeros++;
  647. }
  648. k++;
  649. zzIndex = ZigZag8x8[k];
  650. }
  651. if (bit !is 0) {
  652. dataUnit[zzIndex] = 1 << approxBit;
  653. } else {
  654. dataUnit[zzIndex] = -1 << approxBit;
  655. }
  656. k++;
  657. }
  658. }
  659. }
  660. }
  661. int refineAC(int ac, int approxBit) {
  662. if (ac > 0) {
  663. int bit = nextBit();
  664. if (bit !is 0) {
  665. ac += 1 << approxBit;
  666. }
  667. } else if (ac < 0) {
  668. int bit = nextBit();
  669. if (bit !is 0) {
  670. ac += -1 << approxBit;
  671. }
  672. }
  673. return ac;
  674. }
  675. void decodeDCCoefficient(int[] dataUnit, int iComp, bool first, int approxBit) {
  676. int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
  677. JPEGHuffmanTable dcTable = dcHuffmanTables[sParams[DC]];
  678. int lastDC = 0;
  679. if (progressive && !first) {
  680. int bit = nextBit();
  681. lastDC = dataUnit[0] + (bit << approxBit);
  682. } else {
  683. lastDC = precedingDCs[iComp];
  684. int nBits = decodeUsingTable(dcTable);
  685. if (nBits !is 0) {
  686. int bits = receive(nBits);
  687. int diff = extendBy(bits, nBits);
  688. lastDC += diff;
  689. precedingDCs[iComp] = lastDC;
  690. }
  691. if (progressive) {
  692. lastDC = lastDC << approxBit;
  693. }
  694. }
  695. dataUnit[0] = lastDC;
  696. }
  697. void dequantize(int[] dataUnit, int iComp) {
  698. int[] qTable = quantizationTables[frameComponents[componentIds[iComp]][TQI]];
  699. for (int i = 0; i < dataUnit.length; i++) {
  700. int zzIndex = ZigZag8x8[i];
  701. dataUnit[zzIndex] = dataUnit[zzIndex] * qTable[i];
  702. }
  703. }
  704. byte[] decodeImageComponents() {
  705. if (nComponents is 3) { // compIds 1, 2, 3
  706. return convertYCbCrToRGB();
  707. }
  708. // if (nComponents is 3) { // compIds 1, 4, 5
  709. // Unsupported CMYK format.
  710. // return convertYIQToRGB();
  711. // }
  712. if (nComponents is 4) {
  713. return convertCMYKToRGB();
  714. }
  715. return convertYToRGB();
  716. }
  717. void decodeMCUAtXAndY(int xmcu, int ymcu, int nComponentsInScan, bool first, int start, int end, int approxBit) {
  718. for (int iComp = 0; iComp < nComponentsInScan; iComp++) {
  719. int scanComponent = iComp;
  720. while (scanHeader.componentParameters[componentIds[scanComponent]] is null) {
  721. scanComponent++;
  722. }
  723. int[] frameComponent = frameComponents[componentIds[scanComponent]];
  724. int hi = frameComponent[HI];
  725. int vi = frameComponent[VI];
  726. if (nComponentsInScan is 1) {
  727. hi = 1;
  728. vi = 1;
  729. }
  730. int compWidth = frameComponent[CW];
  731. for (int ivi = 0; ivi < vi; ivi++) {
  732. for (int ihi = 0; ihi < hi; ihi++) {
  733. if (progressive) {
  734. // Progressive: First scan - create a new data unit.
  735. // Subsequent scans - refine the existing data unit.
  736. int index = (ymcu * vi + ivi) * compWidth + xmcu * hi + ihi;
  737. dataUnit = dataUnits[scanComponent][index];
  738. if (dataUnit is null) {
  739. dataUnit = new int[64];
  740. dataUnits[scanComponent][index] = dataUnit;
  741. }
  742. } else {
  743. // Sequential: Clear and reuse the data unit buffer.
  744. for (int i = 0; i < dataUnit.length; i++) {
  745. dataUnit[i] = 0;
  746. }
  747. }
  748. if (!progressive || scanHeader.isDCProgressiveScan()) {
  749. decodeDCCoefficient(dataUnit, scanComponent, first, approxBit);
  750. }
  751. if (!progressive) {
  752. decodeACCoefficients(dataUnit, scanComponent);
  753. } else {
  754. if (scanHeader.isACProgressiveScan()) {
  755. if (first) {
  756. decodeACFirstCoefficients(dataUnit, scanComponent, start, end, approxBit);
  757. } else {
  758. decodeACRefineCoefficients(dataUnit, scanComponent, start, end, approxBit);
  759. }
  760. }
  761. if (loader.hasListeners()) {
  762. // Dequantization, IDCT, up-sampling and color conversion
  763. // are done on a copy of the coefficient data in order to
  764. // display the image incrementally.
  765. int[] temp = dataUnit;
  766. dataUnit = new int[64];
  767. System.arraycopy(temp, 0, dataUnit, 0, 64);
  768. }
  769. }
  770. if (!progressive || (progressive && loader.hasListeners())) {
  771. dequantize(dataUnit, scanComponent);
  772. inverseDCT(dataUnit);
  773. storeData(dataUnit, scanComponent, xmcu, ymcu, hi, ihi, vi, ivi);
  774. }
  775. }
  776. }
  777. }
  778. }
  779. void decodeScan() {
  780. if (progressive && !scanHeader.verifyProgressiveScan()) {
  781. SWT.error(SWT.ERROR_INVALID_IMAGE);
  782. }
  783. int nComponentsInScan = scanHeader.getNumberOfImageComponents();
  784. int mcuRowsInScan = interleavedMcuRows;
  785. int mcusPerRow = interleavedMcuCols;
  786. if (nComponentsInScan is 1) {
  787. // Non-interleaved.
  788. int scanComponent = 0;
  789. while (scanHeader.componentParameters[componentIds[scanComponent]] is null) {
  790. scanComponent++;
  791. }
  792. int[] frameComponent = frameComponents[componentIds[scanComponent]];
  793. int hi = frameComponent[HI];
  794. int vi = frameComponent[VI];
  795. int mcuWidth = DCTSIZE * maxH / hi;
  796. int mcuHeight = DCTSIZE * maxV / vi;
  797. mcusPerRow = (imageWidth + mcuWidth - 1) / mcuWidth;
  798. mcuRowsInScan = (imageHeight + mcuHeight - 1) / mcuHeight;
  799. }
  800. bool first = scanHeader.isFirstScan();
  801. int start = scanHeader.getStartOfSpectralSelection();
  802. int end = scanHeader.getEndOfSpectralSelection();
  803. int approxBit = scanHeader.getApproxBitPositionLow();
  804. restartsToGo = restartInterval;
  805. nextRestartNumber = 0;
  806. for (int ymcu = 0; ymcu < mcuRowsInScan; ymcu++) {
  807. for (int xmcu = 0; xmcu < mcusPerRow; xmcu++) {
  808. if (restartInterval !is 0) {
  809. if (restartsToGo is 0) processRestartInterval();
  810. restartsToGo--;
  811. }
  812. decodeMCUAtXAndY(xmcu, ymcu, nComponentsInScan, first, start, end, approxBit);
  813. }
  814. }
  815. }
  816. int decodeUsingTable(JPEGHuffmanTable huffmanTable) {
  817. int i = 0;
  818. int[] maxCodes = huffmanTable.getDhMaxCodes();
  819. int[] minCodes = huffmanTable.getDhMinCodes();
  820. int[] valPtrs = huffmanTable.getDhValPtrs();
  821. int[] huffVals = huffmanTable.getDhValues();
  822. int code = nextBit();
  823. while (code > maxCodes[i]) {
  824. code = code * 2 + nextBit();
  825. i++;
  826. }
  827. int j = valPtrs[i] + code - minCodes[i];
  828. return huffVals[j];
  829. }
  830. void emit(int huffCode, int nBits) {
  831. if (nBits is 0) {
  832. SWT.error(SWT.ERROR_INVALID_IMAGE);
  833. }
  834. int[] power2m1 = [
  835. 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191,
  836. 16383, 32767, 65535, 131125
  837. ];
  838. int code = (huffCode & power2m1[nBits - 1]) << (24 - nBits - currentBitCount);
  839. byte[] codeBuffer = new byte[4];
  840. codeBuffer[0] = cast(byte)(code & 0xFF);
  841. codeBuffer[1] = cast(byte)((code >> 8) & 0xFF);
  842. codeBuffer[2] = cast(byte)((code >> 16) & 0xFF);
  843. codeBuffer[3] = cast(byte)((code >> 24) & 0xFF);
  844. int abs = nBits - (8 - currentBitCount);
  845. if (abs < 0) abs = -abs;
  846. if ((abs >> 3) > 0) {
  847. currentByte += codeBuffer[2];
  848. emitByte(cast(byte)currentByte);
  849. emitByte(codeBuffer[1]);
  850. currentByte = codeBuffer[0];
  851. currentBitCount += nBits - 16;
  852. } else {
  853. currentBitCount += nBits;
  854. if (currentBitCount >= 8) {
  855. currentByte += codeBuffer[2];
  856. emitByte(cast(byte)currentByte);
  857. currentByte = codeBuffer[1];
  858. currentBitCount -= 8;
  859. } else {
  860. currentByte += codeBuffer[2];
  861. }
  862. }
  863. }
  864. void emitByte(byte byteValue) {
  865. if (bufferCurrentPosition >= 512) {
  866. resetOutputBuffer();
  867. }
  868. dataBuffer[bufferCurrentPosition] = byteValue;
  869. bufferCurrentPosition++;
  870. if (byteValue is -1) {
  871. emitByte(cast(byte)0);
  872. }
  873. }
  874. void encodeACCoefficients(int[] dataUnit, int iComp) {
  875. int[] sParams = scanHeader.componentParameters[iComp];
  876. JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
  877. int[] ehCodes = acTable.ehCodes;
  878. byte[] ehSizes = acTable.ehCodeLengths;
  879. int r = 0;
  880. int k = 1;
  881. while (k < 64) {
  882. k++;
  883. int acValue = dataUnit[ZigZag8x8[k - 1]];
  884. if (acValue is 0) {
  885. if (k is 64) {
  886. emit(ehCodes[0], ehSizes[0] & 0xFF);
  887. } else {
  888. r++;
  889. }
  890. } else {
  891. while (r > 15) {
  892. emit(ehCodes[0xF0], ehSizes[0xF0] & 0xFF);
  893. r -= 16;
  894. }
  895. if (acValue < 0) {
  896. int absACValue = acValue;
  897. if (absACValue < 0) absACValue = -absACValue;
  898. int nBits = NBitsTable[absACValue];
  899. int rs = r * 16 + nBits;
  900. emit(ehCodes[rs], ehSizes[rs] & 0xFF);
  901. emit(0xFFFFFF - absACValue, nBits);
  902. } else {
  903. int nBits = NBitsTable[acValue];
  904. int rs = r * 16 + nBits;
  905. emit(ehCodes[rs], ehSizes[rs] & 0xFF);
  906. emit(acValue, nBits);
  907. }
  908. r = 0;
  909. }
  910. }
  911. }
  912. void encodeDCCoefficients(int[] dataUnit, int iComp) {
  913. int[] sParams = scanHeader.componentParameters[iComp];
  914. JPEGHuffmanTable dcTable = dcHuffmanTables[sParams[DC]];
  915. int lastDC = precedingDCs[iComp];
  916. int dcValue = dataUnit[0];
  917. int diff = dcValue - lastDC;
  918. precedingDCs[iComp] = dcValue;
  919. if (diff < 0) {
  920. int absDiff = 0 - diff;
  921. int nBits = NBitsTable[absDiff];
  922. emit(dcTable.ehCodes[nBits], dcTable.ehCodeLengths[nBits]);
  923. emit(0xFFFFFF - absDiff, nBits);
  924. } else {
  925. int nBits = NBitsTable[diff];
  926. emit(dcTable.ehCodes[nBits], dcTable.ehCodeLengths[nBits]);
  927. if (nBits !is 0) {
  928. emit(diff, nBits);
  929. }
  930. }
  931. }
  932. void encodeMCUAtXAndY(int xmcu, int ymcu) {
  933. int nComponentsInScan = scanHeader.getNumberOfImageComponents();
  934. dataUnit = new int[64];
  935. for (int iComp = 0; iComp < nComponentsInScan; iComp++) {
  936. int[] frameComponent = frameComponents[componentIds[iComp]];
  937. int hi = frameComponent[HI];
  938. int vi = frameComponent[VI];
  939. for (int ivi = 0; ivi < vi; ivi++) {
  940. for (int ihi = 0; ihi < hi; ihi++) {
  941. extractData(dataUnit, iComp, xmcu, ymcu, ihi, ivi);
  942. forwardDCT(dataUnit);
  943. quantizeData(dataUnit, iComp);
  944. encodeDCCoefficients(dataUnit, iComp);
  945. encodeACCoefficients(dataUnit, iComp);
  946. }
  947. }
  948. }
  949. }
  950. void encodeScan() {
  951. for (int ymcu = 0; ymcu < interleavedMcuRows; ymcu++) {
  952. for (int xmcu = 0; xmcu < interleavedMcuCols; xmcu++) {
  953. encodeMCUAtXAndY(xmcu, ymcu);
  954. }
  955. }
  956. if (currentBitCount !is 0) {
  957. emitByte(cast(byte)currentByte);
  958. }
  959. resetOutputBuffer();
  960. }
  961. void expandImageComponents() {
  962. for (int iComp = 0; iComp < nComponents; iComp++) {
  963. int[] frameComponent = frameComponents[componentIds[iComp]];
  964. int hi = frameComponent[HI];
  965. int vi = frameComponent[VI];
  966. int upH = maxH / hi;
  967. int upV = maxV / vi;
  968. if ((upH * upV) > 1) {
  969. byte[] component = imageComponents[iComp];
  970. int compWidth = frameComponent[CW];
  971. int compHeight = frameComponent[CH];
  972. int upCompWidth = compWidth * upH;
  973. int upCompHeight = compHeight * upV;
  974. ImageData src = new ImageData(compWidth, compHeight, 8, new PaletteData(RGB16), 4, component);
  975. ImageData dest = src.scaledTo(upCompWidth, upCompHeight);
  976. imageComponents[iComp] = dest.data;
  977. }
  978. }
  979. }
  980. int extendBy(int diff, int t) {
  981. if (diff < ExtendTest[t]) {
  982. return diff + ExtendOffset[t];
  983. } else {
  984. return diff;
  985. }
  986. }
  987. void extractData(int[] dataUnit, int iComp, int xmcu, int ymcu, int ihi, int ivi) {
  988. byte[] compImage = imageComponents[iComp];
  989. int[] frameComponent = frameComponents[componentIds[iComp]];
  990. int hi = frameComponent[HI];
  991. int vi = frameComponent[VI];
  992. int compWidth = frameComponent[CW];
  993. int srcIndex = ((ymcu * vi + ivi) * compWidth * DCTSIZE) + ((xmcu * hi + ihi) * DCTSIZE);
  994. int destIndex = 0;
  995. for (int i = 0; i < DCTSIZE; i++) {
  996. for (int col = 0; col < DCTSIZE; col++) {
  997. dataUnit[destIndex] = (compImage[srcIndex + col] & 0xFF) - 128;
  998. destIndex++;
  999. }
  1000. srcIndex += compWidth;
  1001. }
  1002. }
  1003. void forwardDCT(int[] dataUnit) {
  1004. for (int row = 0; row < 8; row++) {
  1005. int rIndex = row * DCTSIZE;
  1006. int tmp0 = dataUnit[rIndex] + dataUnit[rIndex + 7];
  1007. int tmp7 = dataUnit[rIndex] - dataUnit[rIndex + 7];
  1008. int tmp1 = dataUnit[rIndex + 1] + dataUnit[rIndex + 6];
  1009. int tmp6 = dataUnit[rIndex + 1] - dataUnit[rIndex + 6];
  1010. int tmp2 = dataUnit[rIndex + 2] + dataUnit[rIndex + 5];
  1011. int tmp5 = dataUnit[rIndex + 2] - dataUnit[rIndex + 5];
  1012. int tmp3 = dataUnit[rIndex + 3] + dataUnit[rIndex + 4];
  1013. int tmp4 = dataUnit[rIndex + 3] - dataUnit[rIndex + 4];
  1014. /**
  1015. * Even part per LL&M figure 1 --- note that published figure
  1016. * is faulty; rotator 'sqrt(2)*c1' should be 'sqrt(2)*c6'.
  1017. */
  1018. int tmp10 = tmp0 + tmp3;
  1019. int tmp13 = tmp0 - tmp3;
  1020. int tmp11 = tmp1 + tmp2;
  1021. int tmp12 = tmp1 - tmp2;
  1022. dataUnit[rIndex] = (tmp10 + tmp11) * 4;
  1023. dataUnit[rIndex + 4] = (tmp10 - tmp11) * 4;
  1024. int z1 = (tmp12 + tmp13) * FIX_0_541196100;
  1025. int n = z1 + (tmp13 * FIX_0_765366865) + 1024;
  1026. dataUnit[rIndex + 2] = n >> 11;
  1027. if ((n < 0) && ((n & 0x07FF) !is 0)) dataUnit[rIndex + 2]--;
  1028. n = z1 + (tmp12 * (0 - FIX_1_847759065)) + 1024;
  1029. dataUnit[rIndex + 6] = n >> 11;
  1030. if ((n < 0) && ((n & 0x07FF) !is 0)) dataUnit[rIndex + 6]--;
  1031. /**
  1032. * Odd part per figure 8 --- note paper omits factor of sqrt(2).
  1033. * cK represents cos(K*pi/16).
  1034. * i0..i3 in the paper are tmp4..tmp7 here.
  1035. */
  1036. z1 = tmp4 + tmp7;
  1037. int z2 = tmp5 + tmp6;
  1038. int z3 = tmp4 + tmp6;
  1039. int z4 = tmp5 + tmp7;
  1040. int z5 = (z3 + z4) * FIX_1_175875602; // sqrt(2) * c3
  1041. tmp4 *= FIX_0_298631336; // sqrt(2) * (-c1+c3+c5-c7)
  1042. tmp5 *= FIX_2_053119869; // sqrt(2) * ( c1+c3-c5+c7)
  1043. tmp6 *= FIX_3_072711026; // sqrt(2) * ( c1+c3+c5-c7)
  1044. tmp7 *= FIX_1_501321110; // sqrt(2) * ( c1+c3-c5-c7)
  1045. z1 *= 0 - FIX_0_899976223; // sqrt(2) * (c7-c3)
  1046. z2 *= 0 - FIX_2_562915447; // sqrt(2) * (-c1-c3)
  1047. z3 *= 0 - FIX_1_961570560; // sqrt(2) * (-c3-c5)
  1048. z4 *= 0 - FIX_0_390180644; // sqrt(2) * (c5-c3)
  1049. z3 += z5;
  1050. z4 += z5;
  1051. n = tmp4 + z1 + z3 + 1024;
  1052. dataUnit[rIndex + 7] = n >> 11;
  1053. if ((n < 0) && ((n & 0x07FF) !is 0)) dataUnit[rIndex + 7]--;
  1054. n = tmp5 + z2 + z4 + 1024;
  1055. dataUnit[rIndex + 5] = n >> 11;
  1056. if ((n < 0) && ((n & 0x07FF) !is 0)) dataUnit[rIndex + 5]--;
  1057. n = tmp6 + z2 + z3 + 1024;
  1058. dataUnit[rIndex + 3] = n >> 11;
  1059. if ((n < 0) && ((n & 0x07FF) !is 0)) dataUnit[rIndex + 3]--;
  1060. n = tmp7 + z1 + z4 + 1024;
  1061. dataUnit[rIndex + 1] = n >> 11;
  1062. if ((n < 0) && ((n & 0x07FF) !is 0)) dataUnit[rIndex + 1]--;
  1063. }
  1064. /**
  1065. * Pass 2: process columns.
  1066. * Note that we must descale the results by a factor of 8 is 2**3,
  1067. * and also undo the PASS1_BITS scaling.
  1068. */
  1069. for (int col = 0; col < 8; col++) {
  1070. int c0 = col;
  1071. int c1 = col + 8;
  1072. int c2 = col + 16;
  1073. int c3 = col + 24;
  1074. int c4 = col + 32;
  1075. int c5 = col + 40;
  1076. int c6 = col + 48;
  1077. int c7 = col + 56;
  1078. int tmp0 = dataUnit[c0] + dataUnit[c7];
  1079. int tmp7 = dataUnit[c0] - dataUnit[c7];
  1080. int tmp1 = dataUnit[c1] + dataUnit[c6];
  1081. int tmp6 = dataUnit[c1] - dataUnit[c6];
  1082. int tmp2 = dataUnit[c2] + dataUnit[c5];
  1083. int tmp5 = dataUnit[c2] - dataUnit[c5];
  1084. int tmp3 = dataUnit[c3] + dataUnit[c4];
  1085. int tmp4 = dataUnit[c3] - dataUnit[c4];
  1086. /**
  1087. * Even part per LL&M figure 1 --- note that published figure
  1088. * is faulty; rotator 'sqrt(2)*c1' should be 'sqrt(2)*c6'.
  1089. */
  1090. int tmp10 = tmp0 + tmp3;
  1091. int tmp13 = tmp0 - tmp3;
  1092. int tmp11 = tmp1 + tmp2;
  1093. int tmp12 = tmp1 - tmp2;
  1094. int n = tmp10 + tmp11 + 16;
  1095. dataUnit[c0] = n >> 5;
  1096. if ((n < 0) && ((n & 0x1F) !is 0)) dataUnit[c0]--;
  1097. n = tmp10 - tmp11 + 16;
  1098. dataUnit[c4] = n >> 5;
  1099. if ((n < 0) && ((n & 0x1F) !is 0)) dataUnit[c4]--;
  1100. int z1 = (tmp12 + tmp13) * FIX_0_541196100;
  1101. n = z1 + (tmp13 * FIX_0_765366865) + 131072;
  1102. dataUnit[c2] = n >> 18;
  1103. if ((n < 0) && ((n & 0x3FFFF) !is 0)) dataUnit[c2]--;
  1104. n = z1 + (tmp12 * (0 - FIX_1_847759065)) + 131072;
  1105. dataUnit[c6] = n >> 18;
  1106. if ((n < 0) && ((n & 0x3FFFF) !is 0)) dataUnit[c6]--;
  1107. /**
  1108. * Odd part per figure 8 --- note paper omits factor of sqrt(2).
  1109. * cK represents cos(K*pi/16).
  1110. * i0..i3 in the paper are tmp4..tmp7 here.
  1111. */
  1112. z1 = tmp4 + tmp7;
  1113. int z2 = tmp5 + tmp6;
  1114. int z3 = tmp4 + tmp6;
  1115. int z4 = tmp5 + tmp7;
  1116. int z5 = (z3 + z4) * FIX_1_175875602; // sqrt(2) * c3
  1117. tmp4 *= FIX_0_298631336; // sqrt(2) * (-c1+c3+c5-c7)
  1118. tmp5 *= FIX_2_053119869; // sqrt(2) * ( c1+c3-c5+c7)
  1119. tmp6 *= FIX_3_072711026; // sqrt(2) * ( c1+c3+c5-c7)
  1120. tmp7 *= FIX_1_501321110; // sqrt(2) * ( c1+c3-c5-c7)
  1121. z1 *= 0 - FIX_0_899976223; // sqrt(2) * (c7-c3)
  1122. z2 *= 0 - FIX_2_562915447; // sqrt(2) * (-c1-c3)
  1123. z3 *= 0 - FIX_1_961570560; // sqrt(2) * (-c3-c5)
  1124. z4 *= 0 - FIX_0_390180644; // sqrt(2) * (c5-c3)
  1125. z3 += z5;
  1126. z4 += z5;
  1127. n = tmp4 + z1 + z3 + 131072;
  1128. dataUnit[c7] = n >> 18;
  1129. if ((n < 0) && ((n & 0x3FFFF) !is 0)) dataUnit[c7]--;
  1130. n = tmp5 + z2 + z4 + 131072;
  1131. dataUnit[c5] = n >> 18;
  1132. if ((n < 0) && ((n & 0x3FFFF) !is 0)) dataUnit[c5]--;
  1133. n = tmp6 + z2 + z3 + 131072;
  1134. dataUnit[c3] = n >> 18;
  1135. if ((n < 0) && ((n & 0x3FFFF) !is 0)) dataUnit[c3]--;
  1136. n = tmp7 + z1 + z4 + 131072;
  1137. dataUnit[c1] = n >> 18;
  1138. if ((n < 0) && ((n & 0x3FFFF) !is 0)) dataUnit[c1]--;
  1139. }
  1140. }
  1141. void getAPP0() {
  1142. JPEGAppn appn = new JPEGAppn(inputStream);
  1143. if (!appn.verify()) {
  1144. SWT.error(SWT.ERROR_INVALID_IMAGE);
  1145. }
  1146. }
  1147. void getCOM() {
  1148. new JPEGComment(inputStream);
  1149. }
  1150. void getDAC() {
  1151. new JPEGArithmeticConditioningTable(inputStream);
  1152. }
  1153. void getDHT() {
  1154. JPEGHuffmanTable dht = new JPEGHuffmanTable(inputStream);
  1155. if (!dht.verify()) {
  1156. SWT.error(SWT.ERROR_INVALID_IMAGE);
  1157. }
  1158. if (acHuffmanTables is null) {
  1159. acHuffmanTables = new JPEGHuffmanTable[4];
  1160. }
  1161. if (dcHuffmanTables is null) {
  1162. dcHuffmanTables = new JPEGHuffmanTable[4];
  1163. }
  1164. JPEGHuffmanTable[] dhtTables = dht.getAllTables();
  1165. for (int i = 0; i < dhtTables.length; i++) {
  1166. JPEGHuffmanTable dhtTable = dhtTables[i];
  1167. if (dhtTable.getTableClass() is 0) {
  1168. dcHuffmanTables[dhtTable.getTableIdentifier()] = dhtTable;
  1169. } else {
  1170. acHuffmanTables[dhtTable.getTableIdentifier()] = dhtTable;
  1171. }
  1172. }
  1173. }
  1174. void getDNL() {
  1175. new JPEGRestartInterval(inputStream);
  1176. }
  1177. void getDQT() {
  1178. JPEGQuantizationTable dqt = new JPEGQuantizationTable(inputStream);
  1179. int[][] currentTables = quantizationTables;
  1180. if (currentTables is null) {
  1181. currentTables = new int[][](4);
  1182. }
  1183. int[] dqtTablesKeys = dqt.getQuantizationTablesKeys();
  1184. int[][] dqtTablesValues = dqt.getQuantizationTablesValues();
  1185. for (int i = 0; i < dqtTablesKeys.length; i++) {
  1186. int index = dqtTablesKeys[i];
  1187. currentTables[index] = dqtTablesValues[i];
  1188. }
  1189. quantizationTables = currentTables;
  1190. }
  1191. void getDRI() {
  1192. JPEGRestartInterval dri = new JPEGRestartInterval(inputStream);
  1193. if (!dri.verify()) {
  1194. SWT.error(SWT.ERROR_INVALID_IMAGE);
  1195. }
  1196. restartInterval = dri.getRestartInterval();
  1197. }
  1198. void inverseDCT(int[] dataUnit) {
  1199. for (int row = 0; row < 8; row++) {
  1200. int rIndex = row * DCTSIZE;
  1201. /**
  1202. * Due to quantization, we will usually find that many of the input
  1203. * coefficients are zero, especially the AC terms. We can exploit this
  1204. * by short-circuiting the IDCT calculation for any row in which all
  1205. * the AC terms are zero. In that case each output is equal to the
  1206. * DC coefficient (with scale factor as needed).
  1207. * With typical images and quantization tables, half or more of the
  1208. * row DCT calculations can be simplified this way.
  1209. */
  1210. if (isZeroInRow(dataUnit, rIndex)) {
  1211. int dcVal = dataUnit[rIndex] << 2;
  1212. for (int i = rIndex + 7; i >= rIndex; i--) {
  1213. dataUnit[i] = dcVal;
  1214. }
  1215. } else {
  1216. /**
  1217. * Even part: reverse the even part of the forward DCT.
  1218. * The rotator is sqrt(2)*c(-6).
  1219. */
  1220. int z2 = dataUnit[rIndex + 2];
  1221. int z3 = dataUnit[rIndex + 6];
  1222. int z1 = (z2 + z3) * FIX_0_541196100;
  1223. int tmp2 = z1 + (z3 * (0 - FIX_1_847759065));
  1224. int tmp3 = z1 + (z2 * FIX_0_765366865);
  1225. int tmp0 = (dataUnit[rIndex] + dataUnit[rIndex + 4]) << 13;
  1226. int tmp1 = (dataUnit[rIndex] - dataUnit[rIndex + 4]) << 13;
  1227. int tmp10 = tmp0 + tmp3;
  1228. int tmp13 = tmp0 - tmp3;
  1229. int tmp11 = tmp1 + tmp2;
  1230. int tmp12 = tmp1 - tmp2;
  1231. /**
  1232. * Odd part per figure 8; the matrix is unitary and hence its
  1233. * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
  1234. */
  1235. tmp0 = dataUnit[rIndex + 7];
  1236. tmp1 = dataUnit[rIndex + 5];
  1237. tmp2 = dataUnit[rIndex + 3];
  1238. tmp3 = dataUnit[rIndex + 1];
  1239. z1 = tmp0 + tmp3;
  1240. z2 = tmp1 + tmp2;
  1241. z3 = tmp0 + tmp2;
  1242. int z4 = tmp1 + tmp3;
  1243. int z5 = (z3 + z4) * FIX_1_175875602; /* sqrt(2) * c3 */
  1244. tmp0 *= FIX_0_298631336; /* sqrt(2) * (-c1+c3+c5-c7) */
  1245. tmp1 *= FIX_2_053119869; /* sqrt(2) * ( c1+c3-c5+c7) */
  1246. tmp2 *= FIX_3_072711026; /* sqrt(2) * ( c1+c3+c5-c7) */
  1247. tmp3 *= FIX_1_501321110; /* sqrt(2) * ( c1+c3-c5-c7) */
  1248. z1 *= 0 - FIX_0_899976223; /* sqrt(2) * (c7-c3) */
  1249. z2 *= 0 - FIX_2_562915447; /* sqrt(2) * (-c1-c3) */
  1250. z3 *= 0 - FIX_1_961570560; /* sqrt(2) * (-c3-c5) */
  1251. z4 *= 0 - FIX_0_390180644; /* sqrt(2) * (c5-c3) */
  1252. z3 += z5;
  1253. z4 += z5;
  1254. tmp0 += z1 + z3;
  1255. tmp1 += z2 + z4;
  1256. tmp2 += z2 + z3;
  1257. tmp3 += z1 + z4;
  1258. dataUnit[rIndex] = (tmp10 + tmp3 + 1024) >> 11;
  1259. dataUnit[rIndex + 7] = (tmp10 - tmp3 + 1024) >> 11;
  1260. dataUnit[rIndex + 1] = (tmp11 + tmp2 + 1024) >> 11;
  1261. dataUnit[rIndex + 6] = (tmp11 - tmp2 + 1024) >> 11;
  1262. dataUnit[rIndex + 2] = (tmp12 + tmp1 + 1024) >> 11;
  1263. dataUnit[rIndex + 5] = (tmp12 - tmp1 + 1024) >> 11;
  1264. dataUnit[rIndex + 3] = (tmp13 + tmp0 + 1024) >> 11;
  1265. dataUnit[rIndex + 4] = (tmp13 - tmp0 + 1024) >> 11;
  1266. }
  1267. }
  1268. /**
  1269. * Pass 2: process columns.
  1270. * Note that we must descale the …

Large files files are truncated, but you can click here to view the full file