1 10 package org.eclipse.swt.internal.image; 11 12 13 import org.eclipse.swt.*; 14 import org.eclipse.swt.graphics.*; 15 import java.io.*; 16 17 final class JPEGFileFormat extends FileFormat { 18 int restartInterval; 19 JPEGFrameHeader frameHeader; 20 int imageWidth, imageHeight; 21 int interleavedMcuCols, interleavedMcuRows; 22 int maxV, maxH; 23 boolean progressive; 24 int samplePrecision; 25 int nComponents; 26 int[][] frameComponents; 27 int[] componentIds; 28 byte[][] imageComponents; 29 int[] dataUnit; 30 int[][][] dataUnits; 31 int[] precedingDCs; 32 JPEGScanHeader scanHeader; 33 byte[] dataBuffer; 34 int currentBitCount; 35 int bufferCurrentPosition; 36 int restartsToGo; 37 int nextRestartNumber; 38 JPEGHuffmanTable[] acHuffmanTables; 39 JPEGHuffmanTable[] dcHuffmanTables; 40 int[][] quantizationTables; 41 int currentByte; 42 int encoderQFactor = 75; 43 int eobrun = 0; 44 45 public static final int DCTSIZE = 8; 46 public static final int DCTSIZESQR = 64; 47 48 public static final int FIX_0_899976223 = 7373; 49 public static final int FIX_1_961570560 = 16069; 50 public static final int FIX_2_053119869 = 16819; 51 public static final int FIX_0_298631336 = 2446; 52 public static final int FIX_1_847759065 = 15137; 53 public static final int FIX_1_175875602 = 9633; 54 public static final int FIX_3_072711026 = 25172; 55 public static final int FIX_0_765366865 = 6270; 56 public static final int FIX_2_562915447 = 20995; 57 public static final int FIX_0_541196100 = 4433; 58 public static final int FIX_0_390180644 = 3196; 59 public static final int FIX_1_501321110 = 12299; 60 61 public static final int APP0 = 0xFFE0; 62 public static final int APP15 = 0xFFEF; 63 public static final int COM = 0xFFFE; 64 public static final int DAC = 0xFFCC; 65 public static final int DHP = 0xFFDE; 66 public static final int DHT = 0xFFC4; 67 public static final int DNL = 0xFFDC; 68 public static final int DRI = 0xFFDD; 69 public static final int DQT = 0xFFDB; 70 public static final int EOI = 0xFFD9; 71 public static final int EXP = 0xFFDF; 72 public static final int JPG = 0xFFC8; 73 public static final int JPG0 = 0xFFF0; 74 public static final int JPG13 = 0xFFFD; 75 public static final int RST0 = 0xFFD0; 76 public static final int RST1 = 0xFFD1; 77 public static final int RST2 = 0xFFD2; 78 public static final int RST3 = 0xFFD3; 79 public static final int RST4 = 0xFFD4; 80 public static final int RST5 = 0xFFD5; 81 public static final int RST6 = 0xFFD6; 82 public static final int RST7 = 0xFFD7; 83 public static final int SOF0 = 0xFFC0; 84 public static final int SOF1 = 0xFFC1; 85 public static final int SOF2 = 0xFFC2; 86 public static final int SOF3 = 0xFFC3; 87 public static final int SOF5 = 0xFFC5; 88 public static final int SOF6 = 0xFFC6; 89 public static final int SOF7 = 0xFFC7; 90 public static final int SOF9 = 0xFFC9; 91 public static final int SOF10 = 0xFFCA; 92 public static final int SOF11 = 0xFFCB; 93 public static final int SOF13 = 0xFFCD; 94 public static final int SOF14 = 0xFFCE; 95 public static final int SOF15 = 0xFFCF; 96 public static final int SOI = 0xFFD8; 97 public static final int SOS = 0xFFDA; 98 public static final int TEM = 0xFF01; 99 100 public static final int TQI = 0; 101 public static final int HI = 1; 102 public static final int VI = 2; 103 public static final int CW = 3; 104 public static final int CH = 4; 105 106 public static final int DC = 0; 107 public static final int AC = 1; 108 109 public static final int ID_Y = 1 - 1; 110 public static final int ID_CB = 2 - 1; 111 public static final int ID_CR = 3 - 1; 112 public static final RGB[] RGB16 = new RGB[] { 113 new RGB(0,0,0), 114 new RGB(0x80,0,0), 115 new RGB(0,0x80,0), 116 new RGB(0x80,0x80,0), 117 new RGB(0,0,0x80), 118 new RGB(0x80,0,0x80), 119 new RGB(0,0x80,0x80), 120 new RGB(0xC0,0xC0,0xC0), 121 new RGB(0x80,0x80,0x80), 122 new RGB(0xFF,0,0), 123 new RGB(0,0xFF,0), 124 new RGB(0xFF,0xFF,0), 125 new RGB(0,0,0xFF), 126 new RGB(0xFF,0,0xFF), 127 new RGB(0,0xFF,0xFF), 128 new RGB(0xFF,0xFF,0xFF), 129 }; 130 public static final int[] ExtendTest = { 131 0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 132 4096, 8192, 16384, 32768, 65536, 131072, 262144 133 }; 134 public static final int[] ExtendOffset = new int[] { 135 0, -1, -3, -7, -15, -31, -63, -127, -255, -511, -1023, -2047, 136 -4095, -8191, -16383, -32767, -65535, -131071, -262143 137 }; 138 public static final int[] ZigZag8x8 = { 139 0, 1, 8, 16, 9, 2, 3, 10, 140 17, 24, 32, 25, 18, 11, 4, 5, 141 12, 19, 26, 33, 40, 48, 41, 34, 142 27, 20, 13, 6, 7, 14, 21, 28, 143 35, 42, 49, 56, 57, 50, 43, 36, 144 29, 22, 15, 23, 30, 37, 44, 51, 145 58, 59, 52, 45, 38, 31, 39, 46, 146 53, 60, 61, 54, 47, 55, 62, 63 147 }; 148 149 public static int[] CrRTable, CbBTable, CrGTable, CbGTable; 150 public static int[] RYTable, GYTable, BYTable, 151 RCbTable, GCbTable, BCbTable, RCrTable, GCrTable, BCrTable, NBitsTable; 152 static { 153 initialize(); 154 } 155 void compress(ImageData image, byte[] dataYComp, byte[] dataCbComp, byte[] dataCrComp) { 156 int srcWidth = image.width; 157 int srcHeight = image.height; 158 int vhFactor = maxV * maxH; 159 int[] frameComponent; 160 imageComponents = new byte[nComponents][]; 161 for (int i = 0; i < nComponents; i++) { 162 frameComponent = frameComponents[componentIds[i]]; 163 imageComponents[i] = new byte[frameComponent[CW] * frameComponent[CH]]; 164 } 165 frameComponent = frameComponents[componentIds[ID_Y]]; 166 for (int yPos = 0; yPos < srcHeight; yPos++) { 167 int srcOfs = yPos * srcWidth; 168 int dstOfs = yPos * frameComponent[CW]; 169 System.arraycopy(dataYComp, srcOfs, imageComponents[ID_Y], dstOfs, srcWidth); 170 } 171 frameComponent = frameComponents[componentIds[ID_CB]]; 172 for (int yPos = 0; yPos < srcHeight / maxV; yPos++) { 173 int destRowIndex = yPos * frameComponent[CW]; 174 for (int xPos = 0; xPos < srcWidth / maxH; xPos++) { 175 int sum = 0; 176 for (int iv = 0; iv < maxV; iv++) { 177 int srcIndex = (yPos * maxV + iv) * srcWidth + (xPos * maxH); 178 for (int ih = 0; ih < maxH; ih++) { 179 sum += dataCbComp[srcIndex + ih] & 0xFF; 180 } 181 } 182 imageComponents[ID_CB][destRowIndex + xPos] = (byte)(sum / vhFactor); 183 } 184 } 185 frameComponent = frameComponents[componentIds[ID_CR]]; 186 for (int yPos = 0; yPos < srcHeight / maxV; yPos++) { 187 int destRowIndex = yPos * frameComponent[CW]; 188 for (int xPos = 0; xPos < srcWidth / maxH; xPos++) { 189 int sum = 0; 190 for (int iv = 0; iv < maxV; iv++) { 191 int srcIndex = (yPos * maxV + iv) * srcWidth + (xPos * maxH); 192 for (int ih = 0; ih < maxH; ih++) { 193 sum += dataCrComp[srcIndex + ih] & 0xFF; 194 } 195 } 196 imageComponents[ID_CR][destRowIndex + xPos] = (byte)(sum / vhFactor); 197 } 198 } 199 for (int iComp = 0; iComp < nComponents; iComp++) { 200 byte[] imageComponent = imageComponents[iComp]; 201 frameComponent = frameComponents[componentIds[iComp]]; 202 int hFactor = frameComponent[HI]; 203 int vFactor = frameComponent[VI]; 204 int componentWidth = frameComponent[CW]; 205 int componentHeight = frameComponent[CH]; 206 int compressedWidth = srcWidth / (maxH / hFactor); 207 int compressedHeight = srcHeight / (maxV / vFactor); 208 if (compressedWidth < componentWidth) { 209 int delta = componentWidth - compressedWidth; 210 for (int yPos = 0; yPos < compressedHeight; yPos++) { 211 int dstOfs = ((yPos + 1) * componentWidth - delta); 212 int dataValue = imageComponent[dstOfs - 1] & 0xFF; 213 for (int i = 0; i < delta; i++) { 214 imageComponent[dstOfs + i] = (byte)dataValue; 215 } 216 } 217 } 218 if (compressedHeight < componentHeight) { 219 int srcOfs = (compressedHeight - 1) * componentWidth; 220 for (int yPos = compressedHeight; yPos <= componentHeight; yPos++) { 221 int dstOfs = (yPos - 1) * componentWidth; 222 System.arraycopy(imageComponent, srcOfs, imageComponent, dstOfs, componentWidth); 223 } 224 } 225 } 226 } 227 void convert4BitRGBToYCbCr(ImageData image) { 228 RGB[] rgbs = image.getRGBs(); 229 int paletteSize = rgbs.length; 230 byte[] yComp = new byte[paletteSize]; 231 byte[] cbComp = new byte[paletteSize]; 232 byte[] crComp = new byte[paletteSize]; 233 int srcWidth = image.width; 234 int srcHeight = image.height; 235 for (int i = 0; i < paletteSize; i++) { 236 RGB color = rgbs[i]; 237 int r = color.red; 238 int g = color.green; 239 int b = color.blue; 240 int n = RYTable[r] + GYTable[g] + BYTable[b]; 241 yComp[i] = (byte)(n >> 16); 242 if ((n < 0) && ((n & 0xFFFF) != 0)) yComp[i]--; 243 n = RCbTable[r] + GCbTable[g] + BCbTable[b]; 244 cbComp[i] = (byte)(n >> 16); 245 if ((n < 0) && ((n & 0xFFFF) != 0)) cbComp[i]--; 246 n = RCrTable[r] + GCrTable[g] + BCrTable[b]; 247 crComp[i] = (byte)(n >> 16); 248 if ((n < 0) && ((n & 0xFFFF) != 0)) crComp[i]--; 249 } 250 int bSize = srcWidth * srcHeight; 251 byte[] dataYComp = new byte[bSize]; 252 byte[] dataCbComp = new byte[bSize]; 253 byte[] dataCrComp = new byte[bSize]; 254 byte[] origData = image.data; 255 int bytesPerLine = image.bytesPerLine; 256 int maxScanlineByte = srcWidth >> 1; 257 for (int yPos = 0; yPos < srcHeight; yPos++) { 258 for (int xPos = 0; xPos < maxScanlineByte; xPos++) { 259 int srcIndex = yPos * bytesPerLine + xPos; 260 int dstIndex = yPos * srcWidth + (xPos * 2); 261 int value2 = origData[srcIndex] & 0xFF; 262 int value1 = value2 >> 4; 263 value2 &= 0x0F; 264 dataYComp[dstIndex] = yComp[value1]; 265 dataCbComp[dstIndex] = cbComp[value1]; 266 dataCrComp[dstIndex] = crComp[value1]; 267 dataYComp[dstIndex + 1] = yComp[value2]; 268 dataCbComp[dstIndex + 1] = cbComp[value2]; 269 dataCrComp[dstIndex + 1] = crComp[value2]; 270 } 271 } 272 compress(image, dataYComp, dataCbComp, dataCrComp); 273 } 274 void convert8BitRGBToYCbCr(ImageData image) { 275 RGB[] rgbs = image.getRGBs(); 276 int paletteSize = rgbs.length; 277 byte[] yComp = new byte[paletteSize]; 278 byte[] cbComp = new byte[paletteSize]; 279 byte[] crComp = new byte[paletteSize]; 280 int srcWidth = image.width; 281 int srcHeight = image.height; 282 for (int i = 0; i < paletteSize; i++) { 283 RGB color = rgbs[i]; 284 int r = color.red; 285 int g = color.green; 286 int b = color.blue; 287 int n = RYTable[r] + GYTable[g] + BYTable[b]; 288 yComp[i] = (byte)(n >> 16); 289 if ((n < 0) && ((n & 0xFFFF) != 0)) yComp[i]--; 290 n = RCbTable[r] + GCbTable[g] + BCbTable[b]; 291 cbComp[i] = (byte)(n >> 16); 292 if ((n < 0) && ((n & 0xFFFF) != 0)) cbComp[i]--; 293 n = RCrTable[r] + GCrTable[g] + BCrTable[b]; 294 crComp[i] = (byte)(n >> 16); 295 if ((n < 0) && ((n & 0xFFFF) != 0)) crComp[i]--; 296 } 297 int dstWidth = image.width; 298 int dstHeight = srcHeight; 299 int stride = ((srcWidth + 3) >> 2) << 2; 300 int bSize = dstWidth * dstHeight; 301 byte[] dataYComp = new byte[bSize]; 302 byte[] dataCbComp = new byte[bSize]; 303 byte[] dataCrComp = new byte[bSize]; 304 byte[] origData = image.data; 305 for (int yPos = 0; yPos < srcHeight; yPos++) { 306 int srcRowIndex = yPos * stride; 307 int dstRowIndex = yPos * dstWidth; 308 for (int xPos = 0; xPos < srcWidth; xPos++) { 309 int value = origData[srcRowIndex + xPos] & 0xFF; 310 int dstIndex = dstRowIndex + xPos; 311 dataYComp[dstIndex] = yComp[value]; 312 dataCbComp[dstIndex] = cbComp[value]; 313 dataCrComp[dstIndex] = crComp[value]; 314 } 315 } 316 compress(image, dataYComp, dataCbComp, dataCrComp); 317 } 318 byte[] convertCMYKToRGB() { 319 320 return new byte[0]; 321 } 322 void convertImageToYCbCr(ImageData image) { 323 switch (image.depth) { 324 case 4: 325 convert4BitRGBToYCbCr(image); 326 return; 327 case 8: 328 convert8BitRGBToYCbCr(image); 329 return; 330 case 16: 331 case 24: 332 case 32: 333 convertMultiRGBToYCbCr(image); 334 return; 335 default: 336 SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); 337 } 338 return; 339 } 340 void convertMultiRGBToYCbCr(ImageData image) { 341 int srcWidth = image.width; 342 int srcHeight = image.height; 343 int bSize = srcWidth * srcHeight; 344 byte[] dataYComp = new byte[bSize]; 345 byte[] dataCbComp = new byte[bSize]; 346 byte[] dataCrComp = new byte[bSize]; 347 PaletteData palette = image.palette; 348 int[] buffer = new int[srcWidth]; 349 if (palette.isDirect) { 350 int redMask = palette.redMask; 351 int greenMask = palette.greenMask; 352 int blueMask = palette.blueMask; 353 int redShift = palette.redShift; 354 int greenShift = palette.greenShift; 355 int blueShift = palette.blueShift; 356 for (int yPos = 0; yPos < srcHeight; yPos++) { 357 image.getPixels(0, yPos, srcWidth, buffer, 0); 358 int dstRowIndex = yPos * srcWidth; 359 for (int xPos = 0; xPos < srcWidth; xPos++) { 360 int pixel = buffer[xPos]; 361 int dstDataIndex = dstRowIndex + xPos; 362 int r = pixel & redMask; 363 r = (redShift < 0) ? r >>> -redShift : r << redShift; 364 int g = pixel & greenMask; 365 g = (greenShift < 0) ? g >>> -greenShift : g << greenShift; 366 int b = pixel & blueMask; 367 b = (blueShift < 0) ? b >>> -blueShift : b << blueShift; 368 dataYComp[dstDataIndex] = (byte)((RYTable[r] + GYTable[g] + BYTable[b]) >> 16); 369 dataCbComp[dstDataIndex] = (byte)((RCbTable[r] + GCbTable[g] + BCbTable[b]) >> 16); 370 dataCrComp[dstDataIndex] = (byte)((RCrTable[r] + GCrTable[g] + BCrTable[b]) >> 16); 371 } 372 } 373 } else { 374 for (int yPos = 0; yPos < srcHeight; yPos++) { 375 image.getPixels(0, yPos, srcWidth, buffer, 0); 376 int dstRowIndex = yPos * srcWidth; 377 for (int xPos = 0; xPos < srcWidth; xPos++) { 378 int pixel = buffer[xPos]; 379 int dstDataIndex = dstRowIndex + xPos; 380 RGB rgb = palette.getRGB(pixel); 381 int r = rgb.red; 382 int g = rgb.green; 383 int b = rgb.blue; 384 dataYComp[dstDataIndex] = (byte)((RYTable[r] + GYTable[g] + BYTable[b]) >> 16); 385 dataCbComp[dstDataIndex] = (byte)((RCbTable[r] + GCbTable[g] + BCbTable[b]) >> 16); 386 dataCrComp[dstDataIndex] = (byte)((RCrTable[r] + GCrTable[g] + BCrTable[b]) >> 16); 387 } 388 } 389 } 390 compress(image, dataYComp, dataCbComp, dataCrComp); 391 } 392 byte[] convertYToRGB() { 393 int compWidth = frameComponents[componentIds[ID_Y]][CW]; 394 int bytesPerLine = (((imageWidth * 8 + 7) / 8) + 3) / 4 * 4; 395 byte[] data = new byte[bytesPerLine * imageHeight]; 396 byte[] yComp = imageComponents[ID_Y]; 397 int destIndex = 0; 398 for (int i = 0; i < imageHeight; i++) { 399 int srcIndex = i * compWidth; 400 for (int j = 0; j < bytesPerLine; j++) { 401 int y = yComp[srcIndex] & 0xFF; 402 if (y < 0) { 403 y = 0; 404 } else { 405 if (y > 255) y = 255; 406 } 407 if (j >= imageWidth) { 408 y = 0; 409 } 410 data[destIndex] = (byte)y; 411 srcIndex++; 412 destIndex++; 413 } 414 } 415 return data; 416 } 417 byte[] convertYCbCrToRGB() { 418 445 int bSize = imageWidth * imageHeight * nComponents; 446 byte[] rgbData = new byte[bSize]; 447 int destIndex = 0; 448 expandImageComponents(); 449 byte[] yComp = imageComponents[ID_Y]; 450 byte[] cbComp = imageComponents[ID_CB]; 451 byte[] crComp = imageComponents[ID_CR]; 452 int compWidth = frameComponents[componentIds[ID_Y]][CW]; 453 for (int v = 0; v < imageHeight; v++) { 454 int srcIndex = v * compWidth; 455 for (int i = 0; i < imageWidth; i++) { 456 int y = yComp[srcIndex] & 0xFF; 457 int cb = cbComp[srcIndex] & 0xFF; 458 int cr = crComp[srcIndex] & 0xFF; 459 int r = y + CrRTable[cr]; 460 int g = y + ((CbGTable[cb] + CrGTable[cr]) >> 16); 461 int b = y + CbBTable[cb]; 462 if (r < 0) { 463 r = 0; 464 } else { 465 if (r > 255) r = 255; 466 } 467 if (g < 0) { 468 g = 0; 469 } else { 470 if (g > 255) g = 255; 471 } 472 if (b < 0) { 473 b = 0; 474 } else { 475 if (b > 255) b = 255; 476 } 477 rgbData[destIndex] = (byte)b; 478 rgbData[destIndex + 1] = (byte)g; 479 rgbData[destIndex + 2] = (byte)r; 480 destIndex += 3; 481 srcIndex++; 482 } 483 } 484 return rgbData; 485 } 486 void decodeACCoefficients(int[] dataUnit, int iComp) { 487 int[] sParams = scanHeader.componentParameters[componentIds[iComp]]; 488 JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]]; 489 int k = 1; 490 while (k < 64) { 491 int rs = decodeUsingTable(acTable); 492 int r = rs >> 4; 493 int s = rs & 0xF; 494 if (s == 0) { 495 if (r == 15) { 496 k += 16; 497 } else { 498 break; 499 } 500 } else { 501 k += r; 502 int bits = receive(s); 503 dataUnit[ZigZag8x8[k]] = extendBy(bits, s); 504 k++; 505 } 506 } 507 } 508 void decodeACFirstCoefficients(int[] dataUnit, int iComp, int start, int end, int approxBit) { 509 if (eobrun > 0) { 510 eobrun--; 511 return; 512 } 513 int[] sParams = scanHeader.componentParameters[componentIds[iComp]]; 514 JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]]; 515 int k = start; 516 while (k <= end) { 517 int rs = decodeUsingTable(acTable); 518 int r = rs >> 4; 519 int s = rs & 0xF; 520 if (s == 0) { 521 if (r == 15) { 522 k += 16; 523 } else { 524 eobrun = (1 << r) + receive(r) - 1; 525 break; 526 } 527 } else { 528 k += r; 529 int bits = receive(s); 530 dataUnit[ZigZag8x8[k]] = extendBy(bits, s) << approxBit; 531 k++; 532 } 533 } 534 } 535 void decodeACRefineCoefficients(int[] dataUnit, int iComp, int start, int end, int approxBit) { 536 int[] sParams = scanHeader.componentParameters[componentIds[iComp]]; 537 JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]]; 538 int k = start; 539 while (k <= end) { 540 if (eobrun > 0) { 541 while (k <= end) { 542 int zzIndex = ZigZag8x8[k]; 543 if (dataUnit[zzIndex] != 0) { 544 dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit); 545 } 546 k++; 547 } 548 eobrun--; 549 } else { 550 int rs = decodeUsingTable(acTable); 551 int r = rs >> 4; 552 int s = rs & 0xF; 553 if (s == 0) { 554 if (r == 15) { 555 int zeros = 0; 556 while (zeros < 16 && k <= end) { 557 int zzIndex = ZigZag8x8[k]; 558 if (dataUnit[zzIndex] != 0) { 559 dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit); 560 } else { 561 zeros++; 562 } 563 k++; 564 } 565 } else { 566 eobrun = (1 << r) + receive(r); 567 } 568 } else { 569 int bit = receive(s); 570 int zeros = 0; 571 int zzIndex = ZigZag8x8[k]; 572 while ((zeros < r || dataUnit[zzIndex] != 0) && k <= end) { 573 if (dataUnit[zzIndex] != 0) { 574 dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit); 575 } else { 576 zeros++; 577 } 578 k++; 579 zzIndex = ZigZag8x8[k]; 580 } 581 if (bit != 0) { 582 dataUnit[zzIndex] = 1 << approxBit; 583 } else { 584 dataUnit[zzIndex] = -1 << approxBit; 585 } 586 k++; 587 } 588 } 589 } 590 } 591 int refineAC(int ac, int approxBit) { 592 if (ac > 0) { 593 int bit = nextBit(); 594 if (bit != 0) { 595 ac += 1 << approxBit; 596 } 597 } else if (ac < 0) { 598 int bit = nextBit(); 599 if (bit != 0) { 600 ac += -1 << approxBit; 601 } 602 } 603 return ac; 604 } 605 void decodeDCCoefficient(int[] dataUnit, int iComp, boolean first, int approxBit) { 606 int[] sParams = scanHeader.componentParameters[componentIds[iComp]]; 607 JPEGHuffmanTable dcTable = dcHuffmanTables[sParams[DC]]; 608 int lastDC = 0; 609 if (progressive && !first) { 610 int bit = nextBit(); 611 lastDC = dataUnit[0] + (bit << approxBit); 612 } else { 613 lastDC = precedingDCs[iComp]; 614 int nBits = decodeUsingTable(dcTable); 615 if (nBits != 0) { 616 int bits = receive(nBits); 617 int diff = extendBy(bits, nBits); 618 lastDC += diff; 619 precedingDCs[iComp] = lastDC; 620 } 621 if (progressive) { 622 lastDC = lastDC << approxBit; 623 } 624 } 625 dataUnit[0] = lastDC; 626 } 627 void dequantize(int[] dataUnit, int iComp) { 628 int[] qTable = quantizationTables[frameComponents[componentIds[iComp]][TQI]]; 629 for (int i = 0; i < dataUnit.length; i++) { 630 int zzIndex = ZigZag8x8[i]; 631 dataUnit[zzIndex] = dataUnit[zzIndex] * qTable[i]; 632 } 633 } 634 byte[] decodeImageComponents() { 635 if (nComponents == 3) { return convertYCbCrToRGB(); 637 } 638 if (nComponents == 4) { 643 return convertCMYKToRGB(); 644 } 645 return convertYToRGB(); 646 } 647 void decodeMCUAtXAndY(int xmcu, int ymcu, int nComponentsInScan, boolean first, int start, int end, int approxBit) { 648 for (int iComp = 0; iComp < nComponentsInScan; iComp++) { 649 int scanComponent = iComp; 650 while (scanHeader.componentParameters[componentIds[scanComponent]] == null) { 651 scanComponent++; 652 } 653 int[] frameComponent = frameComponents[componentIds[scanComponent]]; 654 int hi = frameComponent[HI]; 655 int vi = frameComponent[VI]; 656 if (nComponentsInScan == 1) { 657 hi = 1; 658 vi = 1; 659 } 660 int compWidth = frameComponent[CW]; 661 for (int ivi = 0; ivi < vi; ivi++) { 662 for (int ihi = 0; ihi < hi; ihi++) { 663 if (progressive) { 664 int index = (ymcu * vi + ivi) * compWidth + xmcu * hi + ihi; 667 dataUnit = dataUnits[scanComponent][index]; 668 if (dataUnit == null) { 669 dataUnit = new int[64]; 670 dataUnits[scanComponent][index] = dataUnit; 671 } 672 } else { 673 for (int i = 0; i < dataUnit.length; i++) { 675 dataUnit[i] = 0; 676 } 677 } 678 if (!progressive || scanHeader.isDCProgressiveScan()) { 679 decodeDCCoefficient(dataUnit, scanComponent, first, approxBit); 680 } 681 if (!progressive) { 682 decodeACCoefficients(dataUnit, scanComponent); 683 } else { 684 if (scanHeader.isACProgressiveScan()) { 685 if (first) { 686 decodeACFirstCoefficients(dataUnit, scanComponent, start, end, approxBit); 687 } else { 688 decodeACRefineCoefficients(dataUnit, scanComponent, start, end, approxBit); 689 } 690 } 691 if (loader.hasListeners()) { 692 int[] temp = dataUnit; 696 dataUnit = new int[64]; 697 System.arraycopy(temp, 0, dataUnit, 0, 64); 698 } 699 } 700 if (!progressive || (progressive && loader.hasListeners())) { 701 dequantize(dataUnit, scanComponent); 702 inverseDCT(dataUnit); 703 storeData(dataUnit, scanComponent, xmcu, ymcu, hi, ihi, vi, ivi); 704 } 705 } 706 } 707 } 708 } 709 void decodeScan() { 710 if (progressive && !scanHeader.verifyProgressiveScan()) { 711 SWT.error(SWT.ERROR_INVALID_IMAGE); 712 } 713 int nComponentsInScan = scanHeader.getNumberOfImageComponents(); 714 int mcuRowsInScan = interleavedMcuRows; 715 int mcusPerRow = interleavedMcuCols; 716 if (nComponentsInScan == 1) { 717 int scanComponent = 0; 719 while (scanHeader.componentParameters[componentIds[scanComponent]] == null) { 720 scanComponent++; 721 } 722 int[] frameComponent = frameComponents[componentIds[scanComponent]]; 723 int hi = frameComponent[HI]; 724 int vi = frameComponent[VI]; 725 int mcuWidth = DCTSIZE * maxH / hi; 726 int mcuHeight = DCTSIZE * maxV / vi; 727 mcusPerRow = (imageWidth + mcuWidth - 1) / mcuWidth; 728 mcuRowsInScan = (imageHeight + mcuHeight - 1) / mcuHeight; 729 } 730 boolean first = scanHeader.isFirstScan(); 731 int start = scanHeader.getStartOfSpectralSelection(); 732 int end = scanHeader.getEndOfSpectralSelection(); 733 int approxBit = scanHeader.getApproxBitPositionLow(); 734 restartsToGo = restartInterval; 735 nextRestartNumber = 0; 736 for (int ymcu = 0; ymcu < mcuRowsInScan; ymcu++) { 737 for (int xmcu = 0; xmcu < mcusPerRow; xmcu++) { 738 if (restartInterval != 0) { 739 if (restartsToGo == 0) processRestartInterval(); 740 restartsToGo--; 741 } 742 decodeMCUAtXAndY(xmcu, ymcu, nComponentsInScan, first, start, end, approxBit); 743 } 744 } 745 } 746 int decodeUsingTable(JPEGHuffmanTable huffmanTable) { 747 int i = 0; 748 int[] maxCodes = huffmanTable.getDhMaxCodes(); 749 int[] minCodes = huffmanTable.getDhMinCodes(); 750 int[] valPtrs = huffmanTable.getDhValPtrs(); 751 int[] huffVals = huffmanTable.getDhValues(); 752 int code = nextBit(); 753 while (code > maxCodes[i]) { 754 code = code * 2 + nextBit(); 755 i++; 756 } 757 int j = valPtrs[i] + code - minCodes[i]; 758 return huffVals[j]; 759 } 760 void emit(int huffCode, int nBits) { 761 if (nBits == 0) { 762 SWT.error(SWT.ERROR_INVALID_IMAGE); 763 } 764 int[] power2m1 = new int[] { 765 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 766 16383, 32767, 65535, 131125 767 }; 768 int code = (huffCode & power2m1[nBits - 1]) << (24 - nBits - currentBitCount); 769 byte[] codeBuffer = new byte[4]; 770 codeBuffer[0] = (byte)(code & 0xFF); 771 codeBuffer[1] = (byte)((code >> 8) & 0xFF); 772 codeBuffer[2] = (byte)((code >> 16) & 0xFF); 773 codeBuffer[3] = (byte)((code >> 24) & 0xFF); 774 int abs = nBits - (8 - currentBitCount); 775 if (abs < 0) abs = -abs; 776 if ((abs >> 3) > 0) { 777 currentByte += codeBuffer[2]; 778 emitByte((byte)currentByte); 779 emitByte(codeBuffer[1]); 780 currentByte = codeBuffer[0]; 781 currentBitCount += nBits - 16; 782 } else { 783 currentBitCount += nBits; 784 if (currentBitCount >= 8) { 785 currentByte += codeBuffer[2]; 786 emitByte((byte)currentByte); 787 currentByte = codeBuffer[1]; 788 currentBitCount -= 8; 789 } else { 790 currentByte += codeBuffer[2]; 791 } 792 } 793 } 794 void emitByte(byte byteValue) { 795 if (bufferCurrentPosition >= 512) { 796 resetOutputBuffer(); 797 } 798 dataBuffer[bufferCurrentPosition] = byteValue; 799 bufferCurrentPosition++; 800 if (byteValue == -1) { 801 emitByte((byte)0); 802 } 803 } 804 void encodeACCoefficients(int[] dataUnit, int iComp) { 805 int[] sParams = scanHeader.componentParameters[iComp]; 806 JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]]; 807 int[] ehCodes = acTable.ehCodes; 808 byte[] ehSizes = acTable.ehCodeLengths; 809 int r = 0; 810 int k = 1; 811 while (k < 64) { 812 k++; 813 int acValue = dataUnit[ZigZag8x8[k - 1]]; 814 if (acValue == 0) { 815 if (k == 64) { 816 emit(ehCodes[0], ehSizes[0] & 0xFF); 817 } else { 818 r++; 819 } 820 } else { 821 while (r > 15) { 822 emit(ehCodes[0xF0], ehSizes[0xF0] & 0xFF); 823 r -= 16; 824 } 825 if (acValue < 0) { 826 int absACValue = acValue; 827 if (absACValue < 0) absACValue = -absACValue; 828 int nBits = NBitsTable[absACValue]; 829 int rs = r * 16 + nBits; 830 emit(ehCodes[rs], ehSizes[rs] & 0xFF); 831 emit(0xFFFFFF - absACValue, nBits); 832 } else { 833 int nBits = NBitsTable[acValue]; 834 int rs = r * 16 + nBits; 835 emit(ehCodes[rs], ehSizes[rs] & 0xFF); 836 emit(acValue, nBits); 837 } 838 r = 0; 839 } 840 } 841 } 842 void encodeDCCoefficients(int[] dataUnit, int iComp) { 843 int[] sParams = scanHeader.componentParameters[iComp]; 844 JPEGHuffmanTable dcTable = dcHuffmanTables[sParams[DC]]; 845 int lastDC = precedingDCs[iComp]; 846 int dcValue = dataUnit[0]; 847 int diff = dcValue - lastDC; 848 precedingDCs[iComp] = dcValue; 849 if (diff < 0) { 850 int absDiff = 0 - diff; 851 int nBits = NBitsTable[absDiff]; 852 emit(dcTable.ehCodes[nBits], dcTable.ehCodeLengths[nBits]); 853 emit(0xFFFFFF - absDiff, nBits); 854 } else { 855 int nBits = NBitsTable[diff]; 856 emit(dcTable.ehCodes[nBits], dcTable.ehCodeLengths[nBits]); 857 if (nBits != 0) { 858 emit(diff, nBits); 859 } 860 } 861 } 862 void encodeMCUAtXAndY(int xmcu, int ymcu) { 863 int nComponentsInScan = scanHeader.getNumberOfImageComponents(); 864 dataUnit = new int[64]; 865 for (int iComp = 0; iComp < nComponentsInScan; iComp++) { 866 int[] frameComponent = frameComponents[componentIds[iComp]]; 867 int hi = frameComponent[HI]; 868 int vi = frameComponent[VI]; 869 for (int ivi = 0; ivi < vi; ivi++) { 870 for (int ihi = 0; ihi < hi; ihi++) { 871 extractData(dataUnit, iComp, xmcu, ymcu, ihi, ivi); 872 forwardDCT(dataUnit); 873 quantizeData(dataUnit, iComp); 874 encodeDCCoefficients(dataUnit, iComp); 875 encodeACCoefficients(dataUnit, iComp); 876 } 877 } 878 } 879 } 880 void encodeScan() { 881 for (int ymcu = 0; ymcu < interleavedMcuRows; ymcu++) { 882 for (int xmcu = 0; xmcu < interleavedMcuCols; xmcu++) { 883 encodeMCUAtXAndY(xmcu, ymcu); 884 } 885 } 886 if (currentBitCount != 0) { 887 emitByte((byte)currentByte); 888 } 889 resetOutputBuffer(); 890 } 891 void expandImageComponents() { 892 for (int iComp = 0; iComp < nComponents; iComp++) { 893 int[] frameComponent = frameComponents[componentIds[iComp]]; 894 int hi = frameComponent[HI]; 895 int vi = frameComponent[VI]; 896 int upH = maxH / hi; 897 int upV = maxV / vi; 898 if ((upH * upV) > 1) { 899 byte[] component = imageComponents[iComp]; 900 int compWidth = frameComponent[CW]; 901 int compHeight = frameComponent[CH]; 902 int upCompWidth = compWidth * upH; 903 int upCompHeight = compHeight * upV; 904 ImageData src = new ImageData(compWidth, compHeight, 8, new PaletteData(RGB16), 4, component); 905 ImageData dest = src.scaledTo(upCompWidth, upCompHeight); 906 imageComponents[iComp] = dest.data; 907 } 908 } 909 } 910 int extendBy(int diff, int t) { 911 if (diff < ExtendTest[t]) { 912 return diff + ExtendOffset[t]; 913 } else { 914 return diff; 915 } 916 } 917 void extractData(int[] dataUnit, int iComp, int xmcu, int ymcu, int ihi, int ivi) { 918 byte[] compImage = imageComponents[iComp]; 919 int[] frameComponent = frameComponents[componentIds[iComp]]; 920 int hi = frameComponent[HI]; 921 int vi = frameComponent[VI]; 922 int compWidth = frameComponent[CW]; 923 int srcIndex = ((ymcu * vi + ivi) * compWidth * DCTSIZE) + ((xmcu * hi + ihi) * DCTSIZE); 924 int destIndex = 0; 925 for (int i = 0; i < DCTSIZE; i++) { 926 for (int col = 0; col < DCTSIZE; col++) { 927 dataUnit[destIndex] = (compImage[srcIndex + col] & 0xFF) - 128; 928 destIndex++; 929 } 930 srcIndex += compWidth; 931 } 932 } 933 void forwardDCT(int[] dataUnit) { 934 for (int row = 0; row < 8; row++) { 935 int rIndex = row * DCTSIZE; 936 int tmp0 = dataUnit[rIndex] + dataUnit[rIndex + 7]; 937 int tmp7 = dataUnit[rIndex] - dataUnit[rIndex + 7]; 938 int tmp1 = dataUnit[rIndex + 1] + dataUnit[rIndex + 6]; 939 int tmp6 = dataUnit[rIndex + 1] - dataUnit[rIndex + 6]; 940 int tmp2 = dataUnit[rIndex + 2] + dataUnit[rIndex + 5]; 941 int tmp5 = dataUnit[rIndex + 2] - dataUnit[rIndex + 5]; 942 int tmp3 = dataUnit[rIndex + 3] + dataUnit[rIndex + 4]; 943 int tmp4 = dataUnit[rIndex + 3] - dataUnit[rIndex + 4]; 944 945 949 int tmp10 = tmp0 + tmp3; 950 int tmp13 = tmp0 - tmp3; 951 int tmp11 = tmp1 + tmp2; 952 int tmp12 = tmp1 - tmp2; 953 954 dataUnit[rIndex] = (tmp10 + tmp11) * 4; 955 dataUnit[rIndex + 4] = (tmp10 - tmp11) * 4; 956 957 int z1 = (tmp12 + tmp13) * FIX_0_541196100; 958 int n = z1 + (tmp13 * FIX_0_765366865) + 1024; 959 dataUnit[rIndex + 2] = n >> 11; 960 if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 2]--; 961 n = z1 + (tmp12 * (0 - FIX_1_847759065)) + 1024; 962 dataUnit[rIndex + 6] = n >> 11; 963 if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 6]--; 964 965 970 z1 = tmp4 + tmp7; 971 int z2 = tmp5 + tmp6; 972 int z3 = tmp4 + tmp6; 973 int z4 = tmp5 + tmp7; 974 int z5 = (z3 + z4) * FIX_1_175875602; 976 tmp4 *= FIX_0_298631336; tmp5 *= FIX_2_053119869; tmp6 *= FIX_3_072711026; tmp7 *= FIX_1_501321110; z1 *= 0 - FIX_0_899976223; z2 *= 0 - FIX_2_562915447; z3 *= 0 - FIX_1_961570560; z4 *= 0 - FIX_0_390180644; 985 z3 += z5; 986 z4 += z5; 987 988 n = tmp4 + z1 + z3 + 1024; 989 dataUnit[rIndex + 7] = n >> 11; 990 if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 7]--; 991 n = tmp5 + z2 + z4 + 1024; 992 dataUnit[rIndex + 5] = n >> 11; 993 if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 5]--; 994 n = tmp6 + z2 + z3 + 1024; 995 dataUnit[rIndex + 3] = n >> 11; 996 if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 3]--; 997 n = tmp7 + z1 + z4 + 1024; 998 dataUnit[rIndex + 1] = n >> 11; 999 if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 1]--; 1000 } 1001 1002 1007 for (int col = 0; col < 8; col++) { 1008 int c0 = col; 1009 int c1 = col + 8; 1010 int c2 = col + 16; 1011 int c3 = col + 24; 1012 int c4 = col + 32; 1013 int c5 = col + 40; 1014 int c6 = col + 48; 1015 int c7 = col + 56; 1016 int tmp0 = dataUnit[c0] + dataUnit[c7]; 1017 int tmp7 = dataUnit[c0] - dataUnit[c7]; 1018 int tmp1 = dataUnit[c1] + dataUnit[c6]; 1019 int tmp6 = dataUnit[c1] - dataUnit[c6]; 1020 int tmp2 = dataUnit[c2] + dataUnit[c5]; 1021 int tmp5 = dataUnit[c2] - dataUnit[c5]; 1022 int tmp3 = dataUnit[c3] + dataUnit[c4]; 1023 int tmp4 = dataUnit[c3] - dataUnit[c4]; 1024 1025 1029 int tmp10 = tmp0 + tmp3; 1030 int tmp13 = tmp0 - tmp3; 1031 int tmp11 = tmp1 + tmp2; 1032 int tmp12 = tmp1 - tmp2; 1033 1034 int n = tmp10 + tmp11 + 16; 1035 dataUnit[c0] = n >> 5; 1036 if ((n < 0) && ((n & 0x1F) != 0)) dataUnit[c0]--; 1037 n = tmp10 - tmp11 + 16; 1038 dataUnit[c4] = n >> 5; 1039 if ((n < 0) && ((n & 0x1F) != 0)) dataUnit[c4]--; 1040 1041 int z1 = (tmp12 + tmp13) * FIX_0_541196100; 1042 n = z1 + (tmp13 * FIX_0_765366865) + 131072; 1043 dataUnit[c2] = n >> 18; 1044 if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c2]--; 1045 n = z1 + (tmp12 * (0 - FIX_1_847759065)) + 131072; 1046 dataUnit[c6] = n >> 18; 1047 if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c6]--; 1048 1049 1054 z1 = tmp4 + tmp7; 1055 int z2 = tmp5 + tmp6; 1056 int z3 = tmp4 + tmp6; 1057 int z4 = tmp5 + tmp7; 1058 int z5 = (z3 + z4) * FIX_1_175875602; 1060 tmp4 *= FIX_0_298631336; tmp5 *= FIX_2_053119869; tmp6 *= FIX_3_072711026; tmp7 *= FIX_1_501321110; z1 *= 0 - FIX_0_899976223; z2 *= 0 - FIX_2_562915447; z3 *= 0 - FIX_1_961570560; z4 *= 0 - FIX_0_390180644; 1069 z3 += z5; 1070 z4 += z5; 1071 1072 n = tmp4 + z1 + z3 + 131072; 1073 dataUnit[c7] = n >> 18; 1074 if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c7]--; 1075 n = tmp5 + z2 + z4 + 131072; 1076 dataUnit[c5] = n >> 18; 1077 if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c5]--; 1078 n = tmp6 + z2 + z3 + 131072; 1079 dataUnit[c3] = n >> 18; 1080 if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c3]--; 1081 n = tmp7 + z1 + z4 + 131072; 1082 dataUnit[c1] = n >> 18; 1083 if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c1]--; 1084 } 1085} 1086void getAPP0() { 1087 JPEGAppn appn = new JPEGAppn(inputStream); 1088 if (!appn.verify()) { 1089 SWT.error(SWT.ERROR_INVALID_IMAGE); 1090 } 1091} 1092void getCOM() { 1093 new JPEGComment(inputStream); 1094} 1095void getDAC() { 1096 new JPEGArithmeticConditioningTable(inputStream); 1097} 1098void getDHT() { 1099 JPEGHuffmanTable dht = new JPEGHuffmanTable(inputStream); 1100 if (!dht.verify()) { 1101 SWT.error(SWT.ERROR_INVALID_IMAGE); 1102 } 1103 if (acHuffmanTables == null) { 1104 acHuffmanTables = new JPEGHuffmanTable[4]; 1105 } 1106 if (dcHuffmanTables == null) { 1107 dcHuffmanTables = new JPEGHuffmanTable[4]; 1108 } 1109 JPEGHuffmanTable[] dhtTables = dht.getAllTables(); 1110 for (int i = 0; i < dhtTables.length; i++) { 1111 JPEGHuffmanTable dhtTable = dhtTables[i]; 1112 if (dhtTable.getTableClass() == 0) { 1113 dcHuffmanTables[dhtTable.getTableIdentifier()] = dhtTable; 1114 } else { 1115 acHuffmanTables[dhtTable.getTableIdentifier()] = dhtTable; 1116 } 1117 } 1118} 1119void getDNL() { 1120 new JPEGRestartInterval(inputStream); 1121} 1122void getDQT() { 1123 JPEGQuantizationTable dqt = new JPEGQuantizationTable(inputStream); 1124 int[][] currentTables = quantizationTables; 1125 if (currentTables == null) { 1126 currentTables = new int[4][]; 1127 } 1128 int[] dqtTablesKeys = dqt.getQuantizationTablesKeys(); 1129 int[][] dqtTablesValues = dqt.getQuantizationTablesValues(); 1130 for (int i = 0; i < dqtTablesKeys.length; i++) { 1131 int index = dqtTablesKeys[i]; 1132 currentTables[index] = dqtTablesValues[i]; 1133 } 1134 quantizationTables = currentTables; 1135} 1136void getDRI() { 1137 JPEGRestartInterval dri = new JPEGRestartInterval(inputStream); 1138 if (!dri.verify()) { 1139 SWT.error(SWT.ERROR_INVALID_IMAGE); 1140 } 1141 restartInterval = dri.getRestartInterval(); 1142} 1143static void initialize() { 1144 initializeRGBYCbCrTables(); 1145 initializeYCbCrRGBTables(); 1146 initializeBitCountTable(); 1147} 1148static void initializeBitCountTable() { 1149 int nBits = 1; 1150 int power2 = 2; 1151 NBitsTable = new int[2048]; 1152 NBitsTable[0] = 0; 1153 for (int i = 1; i < NBitsTable.length; i++) { 1154 if (!(i < power2)) { 1155 nBits++; 1156 power2 *= 2; 1157 } 1158 NBitsTable[i] = nBits; 1159 } 1160} 1161static void initializeRGBYCbCrTables() { 1162 RYTable = new int[256]; 1163 GYTable = new int[256]; 1164 BYTable = new int[256]; 1165 RCbTable = new int[256]; 1166 GCbTable = new int[256]; 1167 BCbTable = new int[256]; 1168 RCrTable = BCbTable; 1169 GCrTable = new int[256]; 1170 BCrTable = new int[256]; 1171 for (int i = 0; i < 256; i++) { 1172 RYTable[i] = i * 19595; 1173 GYTable[i] = i * 38470; 1174 BYTable[i] = i * 7471 + 32768; 1175 RCbTable[i] = i * -11059; 1176 GCbTable[i] = i * -21709; 1177 BCbTable[i] = i * 32768 + 8388608; 1178 GCrTable[i] = i * -27439; 1179 BCrTable[i] = i * -5329; 1180 } 1181} 1182static void initializeYCbCrRGBTables() { 1183 CrRTable = new int[256]; 1184 CbBTable = new int[256]; 1185 CrGTable = new int[256]; 1186 CbGTable = new int[256]; 1187 for (int i = 0; i < 256; i++) { 1188 int x2 = 2 * i - 255; 1189 CrRTable[i] = (45941 * x2 + 32768) >> 16; 1190 CbBTable[i] = (58065 * x2 + 32768) >> 16; 1191 CrGTable[i] = -23401 * x2; 1192 CbGTable[i] = -11277 * x2 + 32768; 1193 } 1194} 1195void inverseDCT(int[] dataUnit) { 1196 for (int row = 0; row < 8; row++) { 1197 int rIndex = row * DCTSIZE; 1198 1207 if (isZeroInRow(dataUnit, rIndex)) { 1208 int dcVal = dataUnit[rIndex] << 2; 1209 for (int i = rIndex + 7; i >= rIndex; i--) { 1210 dataUnit[i] = dcVal; 1211 } 1212 } else { 1213 1217 int z2 = dataUnit[rIndex + 2]; 1218 int z3 = dataUnit[rIndex + 6]; 1219 int z1 = (z2 + z3) * FIX_0_541196100; 1220 int tmp2 = z1 + (z3 * (0 - FIX_1_847759065)); 1221 int tmp3 = z1 + (z2 * FIX_0_765366865); 1222 int tmp0 = (dataUnit[rIndex] + dataUnit[rIndex + 4]) << 13; 1223 int tmp1 = (dataUnit[rIndex] - dataUnit[rIndex + 4]) << 13; 1224 int tmp10 = tmp0 + tmp3; 1225 int tmp13 = tmp0 - tmp3; 1226 int tmp11 = tmp1 + tmp2; 1227 int tmp12 = tmp1 - tmp2; 1228 1232 tmp0 = dataUnit[rIndex + 7]; 1233 tmp1 = dataUnit[rIndex + 5]; 1234 tmp2 = dataUnit[rIndex + 3]; 1235 tmp3 = dataUnit[rIndex + 1]; 1236 z1 = tmp0 + tmp3; 1237 z2 = tmp1 + tmp2; 1238 z3 = tmp0 + tmp2; 1239 int z4 = tmp1 + tmp3; 1240 int z5 = (z3 + z4) * FIX_1_175875602; 1241 1242 tmp0 *= FIX_0_298631336; 1243 tmp1 *= FIX_2_053119869; 1244 tmp2 *= FIX_3_072711026; 1245 tmp3 *= FIX_1_501321110; 1246 z1 *= 0 - FIX_0_899976223; 1247 z2 *= 0 - FIX_2_562915447; 1248 z3 *= 0 - FIX_1_961570560; 1249 z4 *= 0 - FIX_0_390180644; 1250 1251 z3 += z5; 1252 z4 += z5; 1253 tmp0 += z1 + z3; 1254 tmp1 += z2 + z4; 1255 tmp2 += z2 + z3; 1256 tmp3 += z1 + z4; 1257 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 1273 for (int col = 0; col < 8; col++) { 1274 int c0 = col; 1275 int c1 = col + 8; 1276 int c2 = col + 16; 1277 int c3 = col + 24; 1278 int c4 = col + 32; 1279 int c5 = col + 40; 1280 int c6 = col + 48; 1281 int c7 = col + 56; 1282 if (isZeroInColumn(dataUnit, col)) { 1283 int dcVal = (dataUnit[c0] + 16) >> 5; 1284 dataUnit[c0] = dcVal; 1285 dataUnit[c1] = dcVal; 1286 dataUnit[c2] = dcVal; 1287 dataUnit[c3] = dcVal; 1288 dataUnit[c4] = dcVal; 1289 dataUnit[c5] = dcVal; 1290 dataUnit[c6] = dcVal; 1291 dataUnit[c7] = dcVal; 1292 } else { 1293 1297 int z0 = dataUnit[c0]; 1298 int z2 = dataUnit[c2]; 1299 int z3 = dataUnit[c6]; 1300 int z4 = dataUnit[c4]; 1301 int z1 = (z2 + z3) * FIX_0_541196100; 1302 int tmp2 = z1 + (z3 * (0 - FIX_1_847759065)); 1303 int tmp3 = z1 + (z2 * FIX_0_765366865); 1304 int tmp0 = (z0 + z4) << 13; 1305 int tmp1 = (z0 - z4) << 13; 1306 int tmp10 = tmp0 + tmp3; 1307 int tmp13 = tmp0 - tmp3; 1308 int tmp11 = tmp1 + tmp2; 1309 int tmp12 = tmp1 - tmp2; 1310 1314 tmp0 = dataUnit[c7]; 1315 tmp1 = dataUnit[c5]; 1316 tmp2 = dataUnit[c3]; 1317 tmp3 = dataUnit[c1]; 1318 z1 = tmp0 + tmp3; 1319 z2 = tmp1 + tmp2; 1320 z3 = tmp0 + tmp2; 1321 z4 = tmp1 + tmp3; 1322 z0 = (z3 + z4) * FIX_1_175875602; 1323 1324 tmp0 *= FIX_0_298631336; 1325 tmp1 *= FIX_2_053119869; 1326 tmp2 *= FIX_3_072711026; 1327 tmp3 *= FIX_1_501321110; 1328 z1 *= 0 - FIX_0_899976223; 1329 z2 *= 0 - FIX_2_562915447; 1330 z3 *= 0 - FIX_1_961570560; 1331 z4 *= 0 - FIX_0_390180644; 1332 1333 z3 += z0; 1334 z4 += z0; 1335 1336 tmp0 += z1 + z3; 1337 tmp1 += z2 + z4; 1338 tmp2 += z2 + z3; 1339 tmp3 += z1 + z4; 1340 1341 1342 dataUnit[c0] = (tmp10 + tmp3 + 131072) >> 18; 1343 dataUnit[c7] = (tmp10 - tmp3 + 131072) >> 18; 1344 dataUnit[c1] = (tmp11 + tmp2 + 131072) >> 18; 1345 dataUnit[c6] = (tmp11 - tmp2 + 131072) >> 18; 1346 dataUnit[c2] = (tmp12 + tmp1 + 131072) >> 18; 1347 dataUnit[c5] = (tmp12 - tmp1 + 131072) >> 18; 1348 dataUnit[c3] = (tmp13 + tmp0 + 131072) >> 18; 1349 dataUnit[c4] = (tmp13 - tmp0 + 131072) >> 18; 1350 } 1351 } 1352} 1353boolean isFileFormat(LEDataInputStream stream) { 1354 try { 1355 JPEGStartOfImage soi = new JPEGStartOfImage(stream); 1356 stream.unread(soi.reference); 1357 return soi.verify(); } catch (Exception e) { 1359 return false; 1360 } 1361} 1362boolean isZeroInColumn(int[] dataUnit, int col) { 1363 return dataUnit[col + 8] == 0 && dataUnit[col + 16] == 0 1364 && dataUnit[col + 24] == 0 && dataUnit[col + 32] == 0 1365 && dataUnit[col + 40] == 0 && dataUnit[col + 48] == 0 1366 && dataUnit[col + 56] == 0; 1367} 1368boolean isZeroInRow(int[] dataUnit, int rIndex) { 1369 return dataUnit[rIndex + 1] == 0 && dataUnit[rIndex + 2] == 0 1370 && dataUnit[rIndex + 3] == 0 && dataUnit[rIndex + 4] == 0 1371 && dataUnit[rIndex + 5] == 0 && dataUnit[rIndex + 6] == 0 1372 && dataUnit[rIndex + 7] == 0; 1373} 1374ImageData[] loadFromByteStream() { 1375 if (System.getProperty("org.eclipse.swt.internal.image.JPEGFileFormat_3.2") == null) { 1377 return JPEGDecoder.loadFromByteStream(inputStream, loader); 1378 } 1379 JPEGStartOfImage soi = new JPEGStartOfImage(inputStream); 1380 if (!soi.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE); 1381 restartInterval = 0; 1382 1383 1384 processTables(); 1385 1386 1387 frameHeader = new JPEGFrameHeader(inputStream); 1388 if (!frameHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE); 1389 imageWidth = frameHeader.getSamplesPerLine(); 1390 imageHeight = frameHeader.getNumberOfLines(); 1391 maxH = frameHeader.getMaxHFactor(); 1392 maxV = frameHeader.getMaxVFactor(); 1393 int mcuWidth = maxH * DCTSIZE; 1394 int mcuHeight = maxV * DCTSIZE; 1395 interleavedMcuCols = (imageWidth + mcuWidth - 1) / mcuWidth; 1396 interleavedMcuRows = (imageHeight + mcuHeight - 1) / mcuHeight; 1397 progressive = frameHeader.isProgressive(); 1398 samplePrecision = frameHeader.getSamplePrecision(); 1399 nComponents = frameHeader.getNumberOfImageComponents(); 1400 frameComponents = frameHeader.componentParameters; 1401 componentIds = frameHeader.componentIdentifiers; 1402 imageComponents = new byte[nComponents][]; 1403 if (progressive) { 1404 dataUnits = new int[nComponents][][]; 1406 } else { 1407 dataUnit = new int[8 * 8]; 1409 } 1410 for (int i = 0; i < nComponents; i++) { 1411 int[] frameComponent = frameComponents[componentIds[i]]; 1412 int bufferSize = frameComponent[CW] * frameComponent[CH]; 1413 imageComponents[i] = new byte[bufferSize]; 1414 if (progressive) { 1415 dataUnits[i] = new int[bufferSize][]; 1416 } 1417 } 1418 1419 1420 processTables(); 1421 1422 1423 scanHeader = new JPEGScanHeader(inputStream); 1424 if (!scanHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE); 1425 1426 1427 int progressiveScanCount = 0; 1428 boolean done = false; 1429 while(!done) { 1430 resetInputBuffer(); 1431 precedingDCs = new int[4]; 1432 decodeScan(); 1433 if (progressive && loader.hasListeners()) { 1434 ImageData imageData = createImageData(); 1435 loader.notifyListeners(new ImageLoaderEvent(loader, imageData, progressiveScanCount, false)); 1436 progressiveScanCount++; 1437 } 1438 1439 1440 int delta = 512 - bufferCurrentPosition - 1; 1441 if (delta > 0) { 1442 byte[] unreadBuffer = new byte[delta]; 1443 System.arraycopy(dataBuffer, bufferCurrentPosition + 1, unreadBuffer, 0, delta); 1444 try { 1445 inputStream.unread(unreadBuffer); 1446 } catch (IOException e) { 1447 SWT.error(SWT.ERROR_IO, e); 1448 } 1449 } 1450 1451 1452 JPEGSegment jpegSegment = processTables(); 1453 if (jpegSegment == null || jpegSegment.getSegmentMarker() == EOI) { 1454 done = true; 1455 } else { 1456 scanHeader = new JPEGScanHeader(inputStream); 1457 if (!scanHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE); 1458 } 1459 } 1460 1461 if (progressive) { 1462 for (int ymcu = 0; ymcu < interleavedMcuRows; ymcu++) { 1463 for (int xmcu = 0; xmcu < interleavedMcuCols; xmcu++) { 1464 for (int iComp = 0; iComp < nComponents; iComp++) { 1465 int[] frameComponent = frameComponents[componentIds[iComp]]; 1466 int hi = frameComponent[HI]; 1467 int vi = frameComponent[VI]; 1468 int compWidth = frameComponent[CW]; 1469 for (int ivi = 0; ivi < vi; ivi++) { 1470 for (int ihi = 0; ihi < hi; ihi++) { 1471 int index = (ymcu * vi + ivi) * compWidth + xmcu * hi + ihi; 1472 dataUnit = dataUnits[iComp][index]; 1473 dequantize(dataUnit, iComp); 1474 inverseDCT(dataUnit); 1475 storeData(dataUnit, iComp, xmcu, ymcu, hi, ihi, vi, ivi); 1476 } 1477 } 1478 } 1479 } 1480 } 1481 dataUnits = null; } 1483 ImageData imageData = createImageData(); 1484 if (progressive && loader.hasListeners()) { 1485 loader.notifyListeners(new ImageLoaderEvent(loader, imageData, progressiveScanCount, true)); 1486 } 1487 return new ImageData[] {imageData}; 1488} 1489ImageData createImageData() { 1490 return ImageData.internal_new( 1491 imageWidth, 1492 imageHeight, 1493 nComponents * samplePrecision, 1494 setUpPalette(), 1495 nComponents == 1 ? 4 : 1, 1496 decodeImageComponents(), 1497 0, 1498 null, 1499 null, 1500 -1, 1501 -1, 1502 SWT.IMAGE_JPEG, 1503 0, 1504 0, 1505 0, 1506 0); 1507} 1508int nextBit() { 1509 if (currentBitCount != 0) { 1510 currentBitCount--; 1511 currentByte *= 2; 1512 if (currentByte > 255) { 1513 currentByte -= 256; 1514 return 1; 1515 } else { 1516 return 0; 1517 } 1518 } 1519 bufferCurrentPosition++; 1520 if (bufferCurrentPosition >= 512) { 1521 resetInputBuffer(); 1522 bufferCurrentPosition = 0; 1523 } 1524 currentByte = dataBuffer[bufferCurrentPosition] & 0xFF; 1525 currentBitCount = 8; 1526 byte nextByte; 1527 if (bufferCurrentPosition == 511) { 1528 resetInputBuffer(); 1529 currentBitCount = 8; 1530 nextByte = dataBuffer[0]; 1531 } else { 1532 nextByte = dataBuffer[bufferCurrentPosition + 1]; 1533 } 1534 if (currentByte == 0xFF) { 1535 if (nextByte == 0) { 1536 bufferCurrentPosition ++; 1537 currentBitCount--; 1538 currentByte *= 2; 1539 if (currentByte > 255) { 1540 currentByte -= 256; 1541 return 1; 1542 } else { 1543 return 0; 1544 } 1545 } else { 1546 if ((nextByte & 0xFF) + 0xFF00 == DNL) { 1547 getDNL(); 1548 return 0; 1549 } else { 1550 SWT.error(SWT.ERROR_INVALID_IMAGE); 1551 return 0; 1552 } 1553 } 1554 } else { 1555 currentBitCount--; 1556 currentByte *= 2; 1557 if (currentByte > 255) { 1558 currentByte -= 256; 1559 return 1; 1560 } else { 1561 return 0; 1562 } 1563 } 1564} 1565void processRestartInterval() { 1566 do { 1567 bufferCurrentPosition++; 1568 if (bufferCurrentPosition > 511) { 1569 resetInputBuffer(); 1570 bufferCurrentPosition = 0; 1571 } 1572 currentByte = dataBuffer[bufferCurrentPosition] & 0xFF; 1573 } while (currentByte != 0xFF); 1574 while (currentByte == 0xFF) { 1575 bufferCurrentPosition++; 1576 if (bufferCurrentPosition > 511) { 1577 resetInputBuffer(); 1578 bufferCurrentPosition = 0; 1579 } 1580 currentByte = dataBuffer[bufferCurrentPosition] & 0xFF; 1581 } 1582 if (currentByte != ((RST0 + nextRestartNumber) & 0xFF)) { 1583 SWT.error(SWT.ERROR_INVALID_IMAGE); 1584 } 1585 bufferCurrentPosition++; 1586 if (bufferCurrentPosition > 511) { 1587 resetInputBuffer(); 1588 bufferCurrentPosition = 0; 1589 } 1590 currentByte = dataBuffer[bufferCurrentPosition] & 0xFF; 1591 currentBitCount = 8; 1592 restartsToGo = restartInterval; 1593 nextRestartNumber = (nextRestartNumber + 1) & 0x7; 1594 precedingDCs = new int[4]; 1595 eobrun = 0; 1596} 1597 1598JPEGSegment processTables() { 1599 while (true) { 1600 JPEGSegment jpegSegment = seekUnspecifiedMarker(inputStream); 1601 if (jpegSegment == null) return null; 1602 JPEGFrameHeader sof = new JPEGFrameHeader(jpegSegment.reference); 1603 if (sof.verify()) { 1604 return jpegSegment; 1605 } 1606 int marker = jpegSegment.getSegmentMarker(); 1607 switch (marker) { 1608 case SOI: SWT.error(SWT.ERROR_INVALID_IMAGE); 1610 case EOI: 1611 case SOS: 1612 return jpegSegment; 1613 case DQT: 1614 getDQT(); 1615 break; 1616 case DHT: 1617 getDHT(); 1618 break; 1619 case DAC: 1620 getDAC(); 1621 break; 1622 case DRI: 1623 getDRI(); 1624 break; 1625 case APP0: 1626 getAPP0(); 1627 break; 1628 case COM: 1629 getCOM(); 1630 break; 1631 default: 1632 skipSegmentFrom(inputStream); 1633 1634 } 1635 } 1636} 1637void quantizeData(int[] dataUnit, int iComp) { 1638 int[] qTable = quantizationTables[frameComponents[componentIds[iComp]][TQI]]; 1639 for (int i = 0; i < dataUnit.length; i++) { 1640 int zzIndex = ZigZag8x8[i]; 1641 int data = dataUnit[zzIndex]; 1642 int absData = data < 0 ? 0 - data : data; 1643 int qValue = qTable[i]; 1644 int q2 = qValue >> 1; 1645 absData += q2; 1646 if (absData < qValue) { 1647 dataUnit[zzIndex] = 0; 1648 } else { 1649 absData /= qValue; 1650 if (data >= 0) { 1651 dataUnit[zzIndex] = absData; 1652 } else { 1653 dataUnit[zzIndex] = 0 - absData; 1654 } 1655 } 1656 } 1657} 1658int receive(int nBits) { 1659 int v = 0; 1660 for (int i = 0; i < nBits; i++) { 1661 v = v * 2 + nextBit(); 1662 } 1663 return v; 1664} 1665void resetInputBuffer() { 1666 if (dataBuffer == null) { 1667 dataBuffer = new byte[512]; 1668 } 1669 try { 1670 inputStream.read(dataBuffer); 1671 } catch (IOException e) { 1672 SWT.error(SWT.ERROR_IO, e); 1673 } 1674 currentBitCount = 0; 1675 bufferCurrentPosition = -1; 1676} 1677void resetOutputBuffer() { 1678 if (dataBuffer == null) { 1679 dataBuffer = new byte[512]; 1680 } else { 1681 try { 1682 outputStream.write(dataBuffer, 0, bufferCurrentPosition); 1683 } catch (IOException e) { 1684 SWT.error(SWT.ERROR_IO, e); 1685 } 1686 } 1687 bufferCurrentPosition = 0; 1688} 1689static JPEGSegment seekUnspecifiedMarker(LEDataInputStream byteStream) { 1690 byte[] byteArray = new byte[2]; 1691 try { 1692 while (true) { 1693 if (byteStream.read(byteArray, 0, 1) != 1) return null; 1694 if (byteArray[0] == (byte) 0xFF) { 1695 if (byteStream.read(byteArray, 1, 1) != 1) return null; 1696 if (byteArray[1] != (byte) 0xFF && byteArray[1] != 0) { 1697 byteStream.unread(byteArray); 1698 return new JPEGSegment(byteArray); 1699 } 1700 } 1701 } 1702 } catch (IOException e) { 1703 SWT.error(SWT.ERROR_IO, e); 1704 } 1705 return null; 1706} 1707PaletteData setUpPalette() { 1708 if (nComponents == 1) { 1709 RGB[] entries = new RGB[256]; 1710 for (int i = 0; i < 256; i++) { 1711 entries[i] = new RGB(i, i, i); 1712 } 1713 return new PaletteData(entries); 1714 } 1715 return new PaletteData(0xFF, 0xFF00, 0xFF0000); 1716} 1717static void skipSegmentFrom(LEDataInputStream byteStream) { 1718 try { 1719 byte[] byteArray = new byte[4]; 1720 JPEGSegment jpegSegment = new JPEGSegment(byteArray); 1721 1722 if (byteStream.read(byteArray) != byteArray.length) { 1723 SWT.error(SWT.ERROR_INVALID_IMAGE); 1724 } 1725 if (!(byteArray[0] == -1 && byteArray[1] != 0 && byteArray[1] != -1)) { 1726 SWT.error(SWT.ERROR_INVALID_IMAGE); 1727 } 1728 int delta = jpegSegment.getSegmentLength() - 2; 1729 byteStream.skip(delta); 1730 } catch (Exception e) { 1731 SWT.error(SWT.ERROR_IO, e); 1732 } 1733} 1734void storeData(int[] dataUnit, int iComp, int xmcu, int ymcu, int hi, int ihi, int vi, int ivi) { 1735 byte[] compImage = imageComponents[iComp]; 1736 int[] frameComponent = frameComponents[componentIds[iComp]]; 1737 int compWidth = frameComponent[CW]; 1738 int destIndex = ((ymcu * vi + ivi) * compWidth * DCTSIZE) + ((xmcu * hi + ihi) * DCTSIZE); 1739 int srcIndex = 0; 1740 for (int i = 0; i < DCTSIZE; i++) { 1741 for (int col = 0; col < DCTSIZE; col++) { 1742 int x = dataUnit[srcIndex] + 128; 1743 if (x < 0) { 1744 x = 0; 1745 } else { 1746 if (x > 255) x = 255; 1747 } 1748 compImage[destIndex + col] = (byte)x; 1749 srcIndex++; 1750 } 1751 destIndex += compWidth; 1752 } 1753} 1754void unloadIntoByteStream(ImageLoader loader) { 1755 ImageData image = loader.data[0]; 1756 if (!new JPEGStartOfImage().writeToStream(outputStream)) { 1757 SWT.error(SWT.ERROR_IO); 1758 } 1759 JPEGAppn appn = new JPEGAppn(new byte[] {(byte)0xFF, (byte)0xE0, 0, 0x10, 0x4A, 0x46, 0x49, 0x46, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0}); 1760 if (!appn.writeToStream(outputStream)) { 1761 SWT.error(SWT.ERROR_IO); 1762 } 1763 quantizationTables = new int[4][]; 1764 JPEGQuantizationTable chromDQT = JPEGQuantizationTable.defaultChrominanceTable(); 1765 chromDQT.scaleBy(encoderQFactor); 1766 int[] jpegDQTKeys = chromDQT.getQuantizationTablesKeys(); 1767 int[][] jpegDQTValues = chromDQT.getQuantizationTablesValues(); 1768 for (int i = 0; i < jpegDQTKeys.length; i++) { 1769 quantizationTables[jpegDQTKeys[i]] = jpegDQTValues[i]; 1770 } 1771 JPEGQuantizationTable lumDQT = JPEGQuantizationTable.defaultLuminanceTable(); 1772 lumDQT.scaleBy(encoderQFactor); 1773 jpegDQTKeys = lumDQT.getQuantizationTablesKeys(); 1774 jpegDQTValues = lumDQT.getQuantizationTablesValues(); 1775 for (int i = 0; i < jpegDQTKeys.length; i++) { 1776 quantizationTables[jpegDQTKeys[i]] = jpegDQTValues[i]; 1777 } 1778 if (!lumDQT.writeToStream(outputStream)) { 1779 SWT.error(SWT.ERROR_IO); 1780 } 1781 if (!chromDQT.writeToStream(outputStream)) { 1782 SWT.error(SWT.ERROR_IO); 1783 } 1784 int frameLength, scanLength, precision; 1785 int[][] frameParams, scanParams; 1786 if (image.depth == 1) { 1787 frameLength = 11; 1788 frameParams = new int[1][]; 1789 frameParams[0] = new int[] {1, 1, 1, 0, 0}; 1790 scanParams = new int[1][]; 1791 scanParams[0] = new int[] {0, 0}; 1792 scanLength = 8; 1793 nComponents = 1; 1794 precision = 1; 1795 } else { 1796 frameLength = 17; 1797 frameParams = new int[3][]; 1798 frameParams[0] = new int[] {0, 2, 2, 0, 0}; 1799 frameParams[1] = new int[] {1, 1, 1, 0, 0}; 1800 frameParams[2] = new int[] {1, 1, 1, 0, 0}; 1801 scanParams = new int[3][]; 1802 scanParams[0] = new int[] {0, 0}; 1803 scanParams[1] = new int[] {1, 1}; 1804 scanParams[2] = new int[] {1, 1}; 1805 scanLength = 12; 1806 nComponents = 3; 1807 precision = 8; 1808 } 1809 imageWidth = image.width; 1810 imageHeight = image.height; 1811 frameHeader = new JPEGFrameHeader(new byte[19]); 1812 frameHeader.setSegmentMarker(SOF0); 1813 frameHeader.setSegmentLength(frameLength); 1814 frameHeader.setSamplePrecision(precision); 1815 frameHeader.setSamplesPerLine(imageWidth); 1816 frameHeader.setNumberOfLines(imageHeight); 1817 frameHeader.setNumberOfImageComponents(nComponents); 1818 frameHeader.componentParameters = frameParams; 1819 frameHeader.componentIdentifiers = new int[] {0, 1, 2}; 1820 frameHeader.initializeContents(); 1821 if (!frameHeader.writeToStream(outputStream)) { 1822 SWT.error(SWT.ERROR_IO); 1823 } 1824 frameComponents = frameParams; 1825 componentIds = frameHeader.componentIdentifiers; 1826 maxH = frameHeader.getMaxHFactor(); 1827 maxV = frameHeader.getMaxVFactor(); 1828 int mcuWidth = maxH * DCTSIZE; 1829 int mcuHeight = maxV * DCTSIZE; 1830 interleavedMcuCols = (imageWidth + mcuWidth - 1) / mcuWidth; 1831 interleavedMcuRows = (imageHeight + mcuHeight - 1) / mcuHeight; 1832 acHuffmanTables = new JPEGHuffmanTable[4]; 1833 dcHuffmanTables = new JPEGHuffmanTable[4]; 1834 JPEGHuffmanTable[] dhtTables = new JPEGHuffmanTable[] { 1835 JPEGHuffmanTable.getDefaultDCLuminanceTable(), 1836 JPEGHuffmanTable.getDefaultDCChrominanceTable(), 1837 JPEGHuffmanTable.getDefaultACLuminanceTable(), 1838 JPEGHuffmanTable.getDefaultACChrominanceTable() 1839 }; 1840 for (int i = 0; i < dhtTables.length; i++) { 1841 JPEGHuffmanTable dhtTable = dhtTables[i]; 1842 if (!dhtTable.writeToStream(outputStream)) { 1843 SWT.error(SWT.ERROR_IO); 1844 } 1845 JPEGHuffmanTable[] allTables = dhtTable.getAllTables(); 1846 for (int j = 0; j < allTables.length; j++) { 1847 JPEGHuffmanTable huffmanTable = allTables[j]; 1848 if (huffmanTable.getTableClass() == 0) { 1849 dcHuffmanTables[huffmanTable.getTableIdentifier()] = huffmanTable; 1850 } else { 1851 acHuffmanTables[huffmanTable.getTableIdentifier()] = huffmanTable; 1852 } 1853 } 1854 } 1855 precedingDCs = new int[4]; 1856 scanHeader = new JPEGScanHeader(new byte[14]); 1857 scanHeader.setSegmentMarker(SOS); 1858 scanHeader.setSegmentLength(scanLength); 1859 scanHeader.setNumberOfImageComponents(nComponents); 1860 scanHeader.setStartOfSpectralSelection(0); 1861 scanHeader.setEndOfSpectralSelection(63); 1862 scanHeader.componentParameters = scanParams; 1863 scanHeader.initializeContents(); 1864 if (!scanHeader.writeToStream(outputStream)) { 1865 SWT.error(SWT.ERROR_IO); 1866 } 1867 convertImageToYCbCr(image); 1868 resetOutputBuffer(); 1869 currentByte = 0; 1870 currentBitCount = 0; 1871 encodeScan(); 1872 if (!new JPEGEndOfImage().writeToStream(outputStream)) { 1873 SWT.error(SWT.ERROR_IO); 1874 } 1875} 1876} 1877 | Popular Tags |