1 package net.myvietnam.mvncore.thirdparty; 2 6 10 16 import java.awt.AWTException ; 17 import java.awt.Frame ; 18 import java.awt.Image ; 19 import java.awt.MediaTracker ; 20 import java.awt.image.PixelGrabber ; 21 import java.io.BufferedOutputStream ; 22 import java.io.IOException ; 23 import java.io.OutputStream ; 24 import java.util.Vector ; 25 26 30 31 public class JpegEncoder extends Frame 32 { 33 Thread runner; 34 BufferedOutputStream outStream; 35 Image image; 36 JpegInfo JpegObj; 37 Huffman Huf; 38 DCT dct; 39 int imageHeight, imageWidth; 40 int Quality; 41 int code; 42 public static int[] jpegNaturalOrder = { 43 0, 1, 8, 16, 9, 2, 3, 10, 44 17, 24, 32, 25, 18, 11, 4, 5, 45 12, 19, 26, 33, 40, 48, 41, 34, 46 27, 20, 13, 6, 7, 14, 21, 28, 47 35, 42, 49, 56, 57, 50, 43, 36, 48 29, 22, 15, 23, 30, 37, 44, 51, 49 58, 59, 52, 45, 38, 31, 39, 46, 50 53, 60, 61, 54, 47, 55, 62, 63, 51 }; 52 53 public JpegEncoder(Image image, int quality, OutputStream out) 54 { 55 MediaTracker tracker = new MediaTracker (this); 56 tracker.addImage(image, 0); 57 try { 58 tracker.waitForID(0); 59 } 60 catch (InterruptedException e) { 61 } 63 68 Quality=quality; 69 70 74 JpegObj = new JpegInfo(image); 75 76 imageHeight=JpegObj.imageHeight; 77 imageWidth=JpegObj.imageWidth; 78 outStream = new BufferedOutputStream (out); 79 dct = new DCT(Quality); 80 Huf=new Huffman(imageWidth,imageHeight); 81 } 82 83 public void setQuality(int quality) { 84 dct = new DCT(quality); 85 } 86 87 public int getQuality() { 88 return Quality; 89 } 90 91 public void Compress() { 92 WriteHeaders(outStream); 93 WriteCompressedData(outStream); 94 WriteEOI(outStream); 95 try { 96 outStream.flush(); 97 } catch (IOException e) { 98 System.out.println("IO Error: " + e.getMessage()); 100 } 101 } 102 103 public void WriteCompressedData(BufferedOutputStream outStream) { 104 int i, j, r, c,a ,b; 105 int comp, xpos, ypos, xblockoffset, yblockoffset; 106 float inputArray[][]; 107 float dctArray1[][] = new float[8][8]; 108 double dctArray2[][] = new double[8][8]; 109 int dctArray3[] = new int[8*8]; 110 111 116 117 int lastDCvalue[] = new int[JpegObj.NumberOfComponents]; 118 int MinBlockWidth, MinBlockHeight; 122 MinBlockWidth = ((imageWidth%8 != 0) ? (int) (Math.floor(imageWidth/8d) + 1)*8 : imageWidth); 125 MinBlockHeight = ((imageHeight%8 != 0) ? (int) (Math.floor(imageHeight/8d) + 1)*8: imageHeight); 126 for (comp = 0; comp < JpegObj.NumberOfComponents; comp++) { 127 MinBlockWidth = Math.min(MinBlockWidth, JpegObj.BlockWidth[comp]); 128 MinBlockHeight = Math.min(MinBlockHeight, JpegObj.BlockHeight[comp]); 129 } 130 xpos = 0; 131 for (r = 0; r < MinBlockHeight; r++) { 132 for (c = 0; c < MinBlockWidth; c++) { 133 xpos = c*8; 134 ypos = r*8; 135 for (comp = 0; comp < JpegObj.NumberOfComponents; comp++) { 136 inputArray = JpegObj.Components[comp]; 139 140 for(i = 0; i < JpegObj.VsampFactor[comp]; i++) { 141 for(j = 0; j < JpegObj.HsampFactor[comp]; j++) { 142 xblockoffset = j * 8; 143 yblockoffset = i * 8; 144 for (a = 0; a < 8; a++) { 145 for (b = 0; b < 8; b++) { 146 147 152 dctArray1[a][b] = inputArray[ypos + yblockoffset + a][xpos + xblockoffset + b]; 153 } 154 } 155 dctArray2 = dct.forwardDCT(dctArray1); 159 dctArray3 = dct.quantizeBlock(dctArray2, JpegObj.QtableNumber[comp]); 160 Huf.HuffmanBlockEncoder(outStream, dctArray3, lastDCvalue[comp], JpegObj.DCtableNumber[comp], JpegObj.ACtableNumber[comp]); 167 lastDCvalue[comp] = dctArray3[0]; 168 } 169 } 170 } 171 } 172 } 173 Huf.flushBuffer(outStream); 174 } 175 176 public void WriteEOI(BufferedOutputStream out) { 177 byte[] EOI = {(byte) 0xFF, (byte) 0xD9}; 178 WriteMarker(EOI, out); 179 } 180 181 public void WriteHeaders(BufferedOutputStream out) { 182 int i, j, index, offset, length; 183 int tempArray[]; 184 185 byte[] SOI = {(byte) 0xFF, (byte) 0xD8}; 187 WriteMarker(SOI, out); 188 189 byte JFIF[] = new byte[18]; 192 JFIF[0] = (byte) 0xff; 193 JFIF[1] = (byte) 0xe0; 194 JFIF[2] = (byte) 0x00; 195 JFIF[3] = (byte) 0x10; 196 JFIF[4] = (byte) 0x4a; 197 JFIF[5] = (byte) 0x46; 198 JFIF[6] = (byte) 0x49; 199 JFIF[7] = (byte) 0x46; 200 JFIF[8] = (byte) 0x00; 201 JFIF[9] = (byte) 0x01; 202 JFIF[10] = (byte) 0x00; 203 JFIF[11] = (byte) 0x00; 204 JFIF[12] = (byte) 0x00; 205 JFIF[13] = (byte) 0x01; 206 JFIF[14] = (byte) 0x00; 207 JFIF[15] = (byte) 0x01; 208 JFIF[16] = (byte) 0x00; 209 JFIF[17] = (byte) 0x00; 210 WriteArray(JFIF, out); 211 212 String comment = new String (); 214 comment = JpegObj.getComment(); 215 length = comment.length(); 216 byte COM[] = new byte[length + 4]; 217 COM[0] = (byte) 0xFF; 218 COM[1] = (byte) 0xFE; 219 COM[2] = (byte) ((length >> 8) & 0xFF); 220 COM[3] = (byte) (length & 0xFF); 221 java.lang.System.arraycopy(JpegObj.Comment.getBytes(), 0, COM, 4, JpegObj.Comment.length()); 222 WriteArray(COM, out); 223 224 byte DQT[] = new byte[134]; 227 DQT[0] = (byte) 0xFF; 228 DQT[1] = (byte) 0xDB; 229 DQT[2] = (byte) 0x00; 230 DQT[3] = (byte) 0x84; 231 offset = 4; 232 for (i = 0; i < 2; i++) { 233 DQT[offset++] = (byte) ((0 << 4) + i); 234 tempArray = dct.quantum[i]; 235 for (j = 0; j < 64; j++) { 236 DQT[offset++] = (byte) tempArray[jpegNaturalOrder[j]]; 237 } 238 } 239 WriteArray(DQT, out); 240 241 byte SOF[] = new byte[19]; 243 SOF[0] = (byte) 0xFF; 244 SOF[1] = (byte) 0xC0; 245 SOF[2] = (byte) 0x00; 246 SOF[3] = (byte) 17; 247 SOF[4] = (byte) JpegObj.Precision; 248 SOF[5] = (byte) ((JpegObj.imageHeight >> 8) & 0xFF); 249 SOF[6] = (byte) ((JpegObj.imageHeight) & 0xFF); 250 SOF[7] = (byte) ((JpegObj.imageWidth >> 8) & 0xFF); 251 SOF[8] = (byte) ((JpegObj.imageWidth) & 0xFF); 252 SOF[9] = (byte) JpegObj.NumberOfComponents; 253 index = 10; 254 for (i = 0; i < SOF[9]; i++) { 255 SOF[index++] = (byte) JpegObj.CompID[i]; 256 SOF[index++] = (byte) ((JpegObj.HsampFactor[i] << 4) + JpegObj.VsampFactor[i]); 257 SOF[index++] = (byte) JpegObj.QtableNumber[i]; 258 } 259 WriteArray(SOF, out); 260 261 byte DHT1[], DHT2[], DHT3[], DHT4[]; 263 int bytes, temp, oldindex, intermediateindex; 264 length = 2; 265 index = 4; 266 oldindex = 4; 267 DHT1 = new byte[17]; 268 DHT4 = new byte[4]; 269 DHT4[0] = (byte) 0xFF; 270 DHT4[1] = (byte) 0xC4; 271 for (i = 0; i < 4; i++ ) { 272 bytes = 0; 273 DHT1[index++ - oldindex] = (byte) ((int[]) Huf.bits.elementAt(i))[0]; 274 for (j = 1; j < 17; j++) { 275 temp = ((int[]) Huf.bits.elementAt(i))[j]; 276 DHT1[index++ - oldindex] =(byte) temp; 277 bytes += temp; 278 } 279 intermediateindex = index; 280 DHT2 = new byte[bytes]; 281 for (j = 0; j < bytes; j++) { 282 DHT2[index++ - intermediateindex] = (byte) ((int[]) Huf.val.elementAt(i))[j]; 283 } 284 DHT3 = new byte[index]; 285 java.lang.System.arraycopy(DHT4, 0, DHT3, 0, oldindex); 286 java.lang.System.arraycopy(DHT1, 0, DHT3, oldindex, 17); 287 java.lang.System.arraycopy(DHT2, 0, DHT3, oldindex + 17, bytes); 288 DHT4 = DHT3; 289 oldindex = index; 290 } 291 DHT4[2] = (byte) (((index - 2) >> 8)& 0xFF); 292 DHT4[3] = (byte) ((index -2) & 0xFF); 293 WriteArray(DHT4, out); 294 295 296 byte SOS[] = new byte[14]; 298 SOS[0] = (byte) 0xFF; 299 SOS[1] = (byte) 0xDA; 300 SOS[2] = (byte) 0x00; 301 SOS[3] = (byte) 12; 302 SOS[4] = (byte) JpegObj.NumberOfComponents; 303 index = 5; 304 for (i = 0; i < SOS[4]; i++) { 305 SOS[index++] = (byte) JpegObj.CompID[i]; 306 SOS[index++] = (byte) ((JpegObj.DCtableNumber[i] << 4) + JpegObj.ACtableNumber[i]); 307 } 308 SOS[index++] = (byte) JpegObj.Ss; 309 SOS[index++] = (byte) JpegObj.Se; 310 SOS[index++] = (byte) ((JpegObj.Ah << 4) + JpegObj.Al); 311 WriteArray(SOS, out); 312 313 } 314 315 void WriteMarker(byte[] data, BufferedOutputStream out) { 316 try { 317 out.write(data, 0, 2); 318 } catch (IOException e) { 319 System.out.println("IO Error: " + e.getMessage()); 321 } 322 } 323 324 void WriteArray(byte[] data, BufferedOutputStream out) { 325 int length; 326 try { 327 length = ((data[2] & 0xFF) << 8) + (data[3] & 0xFF) + 2; 328 out.write(data, 0, length); 329 } catch (IOException e) { 330 System.out.println("IO Error: " + e.getMessage()); 332 } 333 } 334 } 335 336 339 342 343 class DCT 344 { 345 348 public int N = 8; 349 350 353 public int QUALITY = 80; 354 355 public int quantum[][] = new int[2][]; 356 public double Divisors[][] = new double[2][]; 357 358 361 public int quantum_luminance[] = new int[N*N]; 362 public double DivisorsLuminance[] = new double[N*N]; 363 364 367 public int quantum_chrominance[] = new int[N*N]; 368 public double DivisorsChrominance[] = new double[N*N]; 369 370 380 public DCT(int QUALITY) 381 { 382 initMatrix(QUALITY); 383 } 384 385 386 390 private void initMatrix(int quality) 391 { 392 double[] AANscaleFactor = { 1.0, 1.387039845, 1.306562965, 1.175875602, 393 1.0, 0.785694958, 0.541196100, 0.275899379}; 394 int i; 395 int j; 396 int index; 397 int Quality; 398 int temp; 399 400 403 Quality = quality; 404 if (Quality <= 0) 405 Quality = 1; 406 if (Quality > 100) 407 Quality = 100; 408 if (Quality < 50) 409 Quality = 5000 / Quality; 410 else 411 Quality = 200 - Quality * 2; 412 413 415 quantum_luminance[0]=16; 416 quantum_luminance[1]=11; 417 quantum_luminance[2]=10; 418 quantum_luminance[3]=16; 419 quantum_luminance[4]=24; 420 quantum_luminance[5]=40; 421 quantum_luminance[6]=51; 422 quantum_luminance[7]=61; 423 quantum_luminance[8]=12; 424 quantum_luminance[9]=12; 425 quantum_luminance[10]=14; 426 quantum_luminance[11]=19; 427 quantum_luminance[12]=26; 428 quantum_luminance[13]=58; 429 quantum_luminance[14]=60; 430 quantum_luminance[15]=55; 431 quantum_luminance[16]=14; 432 quantum_luminance[17]=13; 433 quantum_luminance[18]=16; 434 quantum_luminance[19]=24; 435 quantum_luminance[20]=40; 436 quantum_luminance[21]=57; 437 quantum_luminance[22]=69; 438 quantum_luminance[23]=56; 439 quantum_luminance[24]=14; 440 quantum_luminance[25]=17; 441 quantum_luminance[26]=22; 442 quantum_luminance[27]=29; 443 quantum_luminance[28]=51; 444 quantum_luminance[29]=87; 445 quantum_luminance[30]=80; 446 quantum_luminance[31]=62; 447 quantum_luminance[32]=18; 448 quantum_luminance[33]=22; 449 quantum_luminance[34]=37; 450 quantum_luminance[35]=56; 451 quantum_luminance[36]=68; 452 quantum_luminance[37]=109; 453 quantum_luminance[38]=103; 454 quantum_luminance[39]=77; 455 quantum_luminance[40]=24; 456 quantum_luminance[41]=35; 457 quantum_luminance[42]=55; 458 quantum_luminance[43]=64; 459 quantum_luminance[44]=81; 460 quantum_luminance[45]=104; 461 quantum_luminance[46]=113; 462 quantum_luminance[47]=92; 463 quantum_luminance[48]=49; 464 quantum_luminance[49]=64; 465 quantum_luminance[50]=78; 466 quantum_luminance[51]=87; 467 quantum_luminance[52]=103; 468 quantum_luminance[53]=121; 469 quantum_luminance[54]=120; 470 quantum_luminance[55]=101; 471 quantum_luminance[56]=72; 472 quantum_luminance[57]=92; 473 quantum_luminance[58]=95; 474 quantum_luminance[59]=98; 475 quantum_luminance[60]=112; 476 quantum_luminance[61]=100; 477 quantum_luminance[62]=103; 478 quantum_luminance[63]=99; 479 480 for (j = 0; j < 64; j++) 481 { 482 temp = (quantum_luminance[j] * Quality + 50) / 100; 483 if ( temp <= 0) temp = 1; 484 if (temp > 255) temp = 255; 485 quantum_luminance[j] = temp; 486 } 487 index = 0; 488 for (i = 0; i < 8; i++) { 489 for (j = 0; j < 8; j++) { 490 DivisorsLuminance[index] = 1d/(8d * quantum_luminance[index] * AANscaleFactor[i] * AANscaleFactor[j]); 496 index++; 497 } 498 } 499 500 501 503 quantum_chrominance[0]=17; 504 quantum_chrominance[1]=18; 505 quantum_chrominance[2]=24; 506 quantum_chrominance[3]=47; 507 quantum_chrominance[4]=99; 508 quantum_chrominance[5]=99; 509 quantum_chrominance[6]=99; 510 quantum_chrominance[7]=99; 511 quantum_chrominance[8]=18; 512 quantum_chrominance[9]=21; 513 quantum_chrominance[10]=26; 514 quantum_chrominance[11]=66; 515 quantum_chrominance[12]=99; 516 quantum_chrominance[13]=99; 517 quantum_chrominance[14]=99; 518 quantum_chrominance[15]=99; 519 quantum_chrominance[16]=24; 520 quantum_chrominance[17]=26; 521 quantum_chrominance[18]=56; 522 quantum_chrominance[19]=99; 523 quantum_chrominance[20]=99; 524 quantum_chrominance[21]=99; 525 quantum_chrominance[22]=99; 526 quantum_chrominance[23]=99; 527 quantum_chrominance[24]=47; 528 quantum_chrominance[25]=66; 529 quantum_chrominance[26]=99; 530 quantum_chrominance[27]=99; 531 quantum_chrominance[28]=99; 532 quantum_chrominance[29]=99; 533 quantum_chrominance[30]=99; 534 quantum_chrominance[31]=99; 535 quantum_chrominance[32]=99; 536 quantum_chrominance[33]=99; 537 quantum_chrominance[34]=99; 538 quantum_chrominance[35]=99; 539 quantum_chrominance[36]=99; 540 quantum_chrominance[37]=99; 541 quantum_chrominance[38]=99; 542 quantum_chrominance[39]=99; 543 quantum_chrominance[40]=99; 544 quantum_chrominance[41]=99; 545 quantum_chrominance[42]=99; 546 quantum_chrominance[43]=99; 547 quantum_chrominance[44]=99; 548 quantum_chrominance[45]=99; 549 quantum_chrominance[46]=99; 550 quantum_chrominance[47]=99; 551 quantum_chrominance[48]=99; 552 quantum_chrominance[49]=99; 553 quantum_chrominance[50]=99; 554 quantum_chrominance[51]=99; 555 quantum_chrominance[52]=99; 556 quantum_chrominance[53]=99; 557 quantum_chrominance[54]=99; 558 quantum_chrominance[55]=99; 559 quantum_chrominance[56]=99; 560 quantum_chrominance[57]=99; 561 quantum_chrominance[58]=99; 562 quantum_chrominance[59]=99; 563 quantum_chrominance[60]=99; 564 quantum_chrominance[61]=99; 565 quantum_chrominance[62]=99; 566 quantum_chrominance[63]=99; 567 568 for (j = 0; j < 64; j++) 569 { 570 temp = (quantum_chrominance[j] * Quality + 50) / 100; 571 if ( temp <= 0) temp = 1; 572 if (temp >= 255) temp = 255; 573 quantum_chrominance[j] = temp; 574 } 575 index = 0; 576 for (i = 0; i < 8; i++) { 577 for (j = 0; j < 8; j++) { 578 DivisorsChrominance[index] = 1d/(8d * quantum_chrominance[index] * AANscaleFactor[i] * AANscaleFactor[j]); 584 index++; 585 } 586 } 587 588 590 quantum[0] = quantum_luminance; 591 Divisors[0] = DivisorsLuminance; 592 quantum[1] = quantum_chrominance; 593 Divisors[1] = DivisorsChrominance; 594 595 596 } 597 598 606 607 610 public double[][] forwardDCTExtreme(float input[][]) 611 { 612 double output[][] = new double[N][N]; 613 int v, u, x, y; 619 for (v = 0; v < 8; v++) { 620 for (u = 0; u < 8; u++) { 621 for (x = 0; x < 8; x++) { 622 for (y = 0; y < 8; y++) { 623 output[v][u] += input[x][y]*Math.cos(((2*x + 1)*(double)u*Math.PI)/16d)*Math.cos(((2*y + 1)*(double)v*Math.PI)/16d); 624 } 625 } 626 output[v][u] *= 0.25d*((u == 0) ? (1d/Math.sqrt(2)) : 1d)*((v == 0) ? (1d/Math.sqrt(2)) : 1d); 627 } 628 } 629 return output; 630 } 631 632 633 637 public double[][] forwardDCT(float input[][]) 638 { 639 double output[][] = new double[N][N]; 640 double tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; 641 double tmp10, tmp11, tmp12, tmp13; 642 double z1, z2, z3, z4, z5, z11, z13; 643 int i; 644 int j; 645 646 for (i = 0; i < 8; i++) { 648 for(j = 0; j < 8; j++) { 649 output[i][j] = input[i][j] - 128d; 650 652 } 653 } 654 655 for (i = 0; i < 8; i++) { 656 tmp0 = output[i][0] + output[i][7]; 657 tmp7 = output[i][0] - output[i][7]; 658 tmp1 = output[i][1] + output[i][6]; 659 tmp6 = output[i][1] - output[i][6]; 660 tmp2 = output[i][2] + output[i][5]; 661 tmp5 = output[i][2] - output[i][5]; 662 tmp3 = output[i][3] + output[i][4]; 663 tmp4 = output[i][3] - output[i][4]; 664 665 tmp10 = tmp0 + tmp3; 666 tmp13 = tmp0 - tmp3; 667 tmp11 = tmp1 + tmp2; 668 tmp12 = tmp1 - tmp2; 669 670 output[i][0] = tmp10 + tmp11; 671 output[i][4] = tmp10 - tmp11; 672 673 z1 = (tmp12 + tmp13) * 0.707106781d; 674 output[i][2] = tmp13 + z1; 675 output[i][6] = tmp13 - z1; 676 677 tmp10 = tmp4 + tmp5; 678 tmp11 = tmp5 + tmp6; 679 tmp12 = tmp6 + tmp7; 680 681 z5 = (tmp10 - tmp12) * 0.382683433d; 682 z2 = 0.541196100d * tmp10 + z5; 683 z4 = 1.306562965d * tmp12 + z5; 684 z3 = tmp11 * 0.707106781d; 685 686 z11 = tmp7 + z3; 687 z13 = tmp7 - z3; 688 689 output[i][5] = z13 + z2; 690 output[i][3] = z13 - z2; 691 output[i][1] = z11 + z4; 692 output[i][7] = z11 - z4; 693 } 694 695 for (i = 0; i < 8; i++) { 696 tmp0 = output[0][i] + output[7][i]; 697 tmp7 = output[0][i] - output[7][i]; 698 tmp1 = output[1][i] + output[6][i]; 699 tmp6 = output[1][i] - output[6][i]; 700 tmp2 = output[2][i] + output[5][i]; 701 tmp5 = output[2][i] - output[5][i]; 702 tmp3 = output[3][i] + output[4][i]; 703 tmp4 = output[3][i] - output[4][i]; 704 705 tmp10 = tmp0 + tmp3; 706 tmp13 = tmp0 - tmp3; 707 tmp11 = tmp1 + tmp2; 708 tmp12 = tmp1 - tmp2; 709 710 output[0][i] = tmp10 + tmp11; 711 output[4][i] = tmp10 - tmp11; 712 713 z1 = (tmp12 + tmp13) * 0.707106781d; 714 output[2][i] = tmp13 + z1; 715 output[6][i] = tmp13 - z1; 716 717 tmp10 = tmp4 + tmp5; 718 tmp11 = tmp5 + tmp6; 719 tmp12 = tmp6 + tmp7; 720 721 z5 = (tmp10 - tmp12) * 0.382683433d; 722 z2 = 0.541196100d * tmp10 + z5; 723 z4 = 1.306562965d * tmp12 + z5; 724 z3 = tmp11 * 0.707106781d; 725 726 z11 = tmp7 + z3; 727 z13 = tmp7 - z3; 728 729 output[5][i] = z13 + z2; 730 output[3][i] = z13 - z2; 731 output[1][i] = z11 + z4; 732 output[7][i] = z11 - z4; 733 } 734 735 return output; 736 } 737 738 741 public int[] quantizeBlock(double inputData[][], int code) 742 { 743 int outputData[] = new int[N*N]; 744 int i, j; 745 int index; 746 index = 0; 747 for (i = 0; i < 8; i++) { 748 for (j = 0; j < 8; j++) { 749 outputData[index] = (int)(Math.round(inputData[i][j] * Divisors[code][index])); 751 index++; 753 } 754 } 755 756 return outputData; 757 } 758 759 763 public int[] quantizeBlockExtreme(double inputData[][], int code) 764 { 765 int outputData[] = new int[N*N]; 766 int i, j; 767 int index; 768 index = 0; 769 for (i = 0; i < 8; i++) { 770 for (j = 0; j < 8; j++) { 771 outputData[index] = (int)(Math.round(inputData[i][j] / quantum[code][index])); 772 index++; 773 } 774 } 775 776 return outputData; 777 } 778 } 779 780 784 class Huffman 785 { 786 int bufferPutBits, bufferPutBuffer; 787 public int ImageHeight; 788 public int ImageWidth; 789 public int DC_matrix0[][]; 790 public int AC_matrix0[][]; 791 public int DC_matrix1[][]; 792 public int AC_matrix1[][]; 793 public int DC_matrix[][][]; 794 public int AC_matrix[][][]; 795 public int code; 796 public int NumOfDCTables; 797 public int NumOfACTables; 798 public int[] bitsDCluminance = { 0x00, 0, 1, 5, 1, 1,1,1,1,1,0,0,0,0,0,0,0}; 799 public int[] valDCluminance = { 0,1,2,3,4,5,6,7,8,9,10,11 }; 800 public int[] bitsDCchrominance = { 0x01,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0 }; 801 public int[] valDCchrominance = { 0,1,2,3,4,5,6,7,8,9,10,11 }; 802 public int[] bitsACluminance = {0x10,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d }; 803 public int[] valACluminance = 804 { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 805 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 806 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 807 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 808 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 809 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 810 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 811 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 812 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 813 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 814 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 815 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 816 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 817 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 818 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 819 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 820 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 821 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 822 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 823 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 824 0xf9, 0xfa }; 825 public int[] bitsACchrominance = { 0x11,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77 }; 826 public int[] valACchrominance = 827 { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 828 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 829 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 830 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 831 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 832 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 833 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 834 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 835 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 836 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 837 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 838 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 839 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 840 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 841 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 842 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 843 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 844 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 845 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 846 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 847 0xf9, 0xfa }; 848 public Vector bits; 849 public Vector val; 850 851 855 public static int[] jpegNaturalOrder = { 856 0, 1, 8, 16, 9, 2, 3, 10, 857 17, 24, 32, 25, 18, 11, 4, 5, 858 12, 19, 26, 33, 40, 48, 41, 34, 859 27, 20, 13, 6, 7, 14, 21, 28, 860 35, 42, 49, 56, 57, 50, 43, 36, 861 29, 22, 15, 23, 30, 37, 44, 51, 862 58, 59, 52, 45, 38, 31, 39, 46, 863 53, 60, 61, 54, 47, 55, 62, 63, 864 }; 865 868 public Huffman(int Width,int Height) 869 { 870 871 bits = new Vector (); 872 bits.addElement(bitsDCluminance); 873 bits.addElement(bitsACluminance); 874 bits.addElement(bitsDCchrominance); 875 bits.addElement(bitsACchrominance); 876 val = new Vector (); 877 val.addElement(valDCluminance); 878 val.addElement(valACluminance); 879 val.addElement(valDCchrominance); 880 val.addElement(valACchrominance); 881 initHuf(); 882 ImageWidth=Width; 884 ImageHeight=Height; 885 886 } 887 888 892 893 public void HuffmanBlockEncoder(BufferedOutputStream outStream, int zigzag[], int prec, int DCcode, int ACcode) 894 { 895 int temp, temp2, nbits, k, r, i; 896 897 NumOfDCTables = 2; 898 NumOfACTables = 2; 899 900 902 temp = temp2 = zigzag[0] - prec; 903 if(temp < 0) { 904 temp = -temp; 905 temp2--; 906 } 907 nbits = 0; 908 while (temp != 0) { 909 nbits++; 910 temp >>= 1; 911 } 912 bufferIt(outStream, DC_matrix[DCcode][nbits][0], DC_matrix[DCcode][nbits][1]); 914 if (nbits != 0) { 916 bufferIt(outStream, temp2, nbits); 917 } 918 919 921 r = 0; 922 923 for (k = 1; k < 64; k++) { 924 if ((temp = zigzag[jpegNaturalOrder[k]]) == 0) { 925 r++; 926 } 927 else { 928 while (r > 15) { 929 bufferIt(outStream, AC_matrix[ACcode][0xF0][0], AC_matrix[ACcode][0xF0][1]); 930 r -= 16; 931 } 932 temp2 = temp; 933 if (temp < 0) { 934 temp = -temp; 935 temp2--; 936 } 937 nbits = 1; 938 while ((temp >>= 1) != 0) { 939 nbits++; 940 } 941 i = (r << 4) + nbits; 942 bufferIt(outStream, AC_matrix[ACcode][i][0], AC_matrix[ACcode][i][1]); 943 bufferIt(outStream, temp2, nbits); 944 945 r = 0; 946 } 947 } 948 949 if (r > 0) { 950 bufferIt(outStream, AC_matrix[ACcode][0][0], AC_matrix[ACcode][0][1]); 951 } 952 953 } 954 955 958 void bufferIt(BufferedOutputStream outStream, int code,int size) 959 { 960 int PutBuffer = code; 961 int PutBits = bufferPutBits; 962 963 PutBuffer &= (1 << size) - 1; 964 PutBits += size; 965 PutBuffer <<= 24 - PutBits; 966 PutBuffer |= bufferPutBuffer; 967 968 while(PutBits >= 8) { 969 int c = ((PutBuffer >> 16) & 0xFF); 970 try 971 { 972 outStream.write(c); 973 } 974 catch (IOException e) { 975 System.out.println("IO Error: " + e.getMessage()); 977 } 978 if (c == 0xFF) { 979 try 980 { 981 outStream.write(0); 982 } 983 catch (IOException e) { 984 System.out.println("IO Error: " + e.getMessage()); 986 } 987 } 988 PutBuffer <<= 8; 989 PutBits -= 8; 990 } 991 bufferPutBuffer = PutBuffer; 992 bufferPutBits = PutBits; 993 994 } 995 996 void flushBuffer(BufferedOutputStream outStream) { 997 int PutBuffer = bufferPutBuffer; 998 int PutBits = bufferPutBits; 999 while (PutBits >= 8) { 1000 int c = ((PutBuffer >> 16) & 0xFF); 1001 try 1002 { 1003 outStream.write(c); 1004 } 1005 catch (IOException e) { 1006 System.out.println("IO Error: " + e.getMessage()); 1008 } 1009 if (c == 0xFF) { 1010 try { 1011 outStream.write(0); 1012 } 1013 catch (IOException e) { 1014 System.out.println("IO Error: " + e.getMessage()); 1016 } 1017 } 1018 PutBuffer <<= 8; 1019 PutBits -= 8; 1020 } 1021 if (PutBits > 0) { 1022 int c = ((PutBuffer >> 16) & 0xFF); 1023 try 1024 { 1025 outStream.write(c); 1026 } 1027 catch (IOException e) { 1028 System.out.println("IO Error: " + e.getMessage()); 1030 } 1031 } 1032 } 1033 1034 1039 1040 public void initHuf() 1041 { 1042 DC_matrix0=new int[12][2]; 1043 DC_matrix1=new int[12][2]; 1044 AC_matrix0=new int[255][2]; 1045 AC_matrix1=new int[255][2]; 1046 DC_matrix = new int[2][][]; 1047 AC_matrix = new int[2][][]; 1048 int p, l, i, lastp, si, code; 1049 int[] huffsize = new int[257]; 1050 int[] huffcode= new int[257]; 1051 1052 1056 1057 p = 0; 1058 for (l = 1; l <= 16; l++) 1059 { 1060 for (i = 1; i <= bitsDCchrominance[l]; i++) 1061 { 1062 huffsize[p++] = l; 1063 } 1064 } 1065 huffsize[p] = 0; 1066 lastp = p; 1067 1068 code = 0; 1069 si = huffsize[0]; 1070 p = 0; 1071 while(huffsize[p] != 0) 1072 { 1073 while(huffsize[p] == si) 1074 { 1075 huffcode[p++] = code; 1076 code++; 1077 } 1078 code <<= 1; 1079 si++; 1080 } 1081 1082 for (p = 0; p < lastp; p++) 1083 { 1084 DC_matrix1[valDCchrominance[p]][0] = huffcode[p]; 1085 DC_matrix1[valDCchrominance[p]][1] = huffsize[p]; 1086 } 1087 1088 1092 1093 p = 0; 1094 for (l = 1; l <= 16; l++) 1095 { 1096 for (i = 1; i <= bitsACchrominance[l]; i++) 1097 { 1098 huffsize[p++] = l; 1099 } 1100 } 1101 huffsize[p] = 0; 1102 lastp = p; 1103 1104 code = 0; 1105 si = huffsize[0]; 1106 p = 0; 1107 while(huffsize[p] != 0) 1108 { 1109 while(huffsize[p] == si) 1110 { 1111 huffcode[p++] = code; 1112 code++; 1113 } 1114 code <<= 1; 1115 si++; 1116 } 1117 1118 for (p = 0; p < lastp; p++) 1119 { 1120 AC_matrix1[valACchrominance[p]][0] = huffcode[p]; 1121 AC_matrix1[valACchrominance[p]][1] = huffsize[p]; 1122 } 1123 1124 1128 p = 0; 1129 for (l = 1; l <= 16; l++) 1130 { 1131 for (i = 1; i <= bitsDCluminance[l]; i++) 1132 { 1133 huffsize[p++] = l; 1134 } 1135 } 1136 huffsize[p] = 0; 1137 lastp = p; 1138 1139 code = 0; 1140 si = huffsize[0]; 1141 p = 0; 1142 while(huffsize[p] != 0) 1143 { 1144 while(huffsize[p] == si) 1145 { 1146 huffcode[p++] = code; 1147 code++; 1148 } 1149 code <<= 1; 1150 si++; 1151 } 1152 1153 for (p = 0; p < lastp; p++) 1154 { 1155 DC_matrix0[valDCluminance[p]][0] = huffcode[p]; 1156 DC_matrix0[valDCluminance[p]][1] = huffsize[p]; 1157 } 1158 1159 1163 1164 p = 0; 1165 for (l = 1; l <= 16; l++) 1166 { 1167 for (i = 1; i <= bitsACluminance[l]; i++) 1168 { 1169 huffsize[p++] = l; 1170 } 1171 } 1172 huffsize[p] = 0; 1173 lastp = p; 1174 1175 code = 0; 1176 si = huffsize[0]; 1177 p = 0; 1178 while(huffsize[p] != 0) 1179 { 1180 while(huffsize[p] == si) 1181 { 1182 huffcode[p++] = code; 1183 code++; 1184 } 1185 code <<= 1; 1186 si++; 1187 } 1188 for (int q = 0; q < lastp; q++) 1189 { 1190 AC_matrix0[valACluminance[q]][0] = huffcode[q]; 1191 AC_matrix0[valACluminance[q]][1] = huffsize[q]; 1192 } 1193 1194 DC_matrix[0] = DC_matrix0; 1195 DC_matrix[1] = DC_matrix1; 1196 AC_matrix[0] = AC_matrix0; 1197 AC_matrix[1] = AC_matrix1; 1198 } 1199 1200} 1201 1202 1206 1207class JpegInfo 1208{ 1209 String Comment; 1210 public Image imageobj; 1211 public int imageHeight; 1212 public int imageWidth; 1213 public int BlockWidth[]; 1214 public int BlockHeight[]; 1215 1216 public int Precision = 8; 1218 public int NumberOfComponents = 3; 1219 public float Components[][][]; 1220 public int[] CompID = {1, 2, 3}; 1221 public int[] HsampFactor = {1, 1, 1}; 1222 public int[] VsampFactor = {1, 1, 1}; 1223 public int[] QtableNumber = {0, 1, 1}; 1224 public int[] DCtableNumber = {0, 1, 1}; 1225 public int[] ACtableNumber = {0, 1, 1}; 1226 public boolean[] lastColumnIsDummy = {false, false, false}; 1227 public boolean[] lastRowIsDummy = {false, false, false}; 1228 public int Ss = 0; 1229 public int Se = 63; 1230 public int Ah = 0; 1231 public int Al = 0; 1232 public int compWidth[], compHeight[]; 1233 public int MaxHsampFactor; 1234 public int MaxVsampFactor; 1235 1236 1237 public JpegInfo(Image image) 1238 { 1239 Components = new float[NumberOfComponents][][]; 1240 compWidth = new int[NumberOfComponents]; 1241 compHeight = new int[NumberOfComponents]; 1242 BlockWidth = new int[NumberOfComponents]; 1243 BlockHeight = new int[NumberOfComponents]; 1244 imageobj = image; 1245 imageWidth = image.getWidth(null); 1246 imageHeight = image.getHeight(null); 1247 Comment = "JPEG Encoder Copyright 1998, James R. Weeks and BioElectroMech. "; 1248 getYCCArray(); 1249 } 1250 1251 public void setComment(String comment) { 1252 Comment.concat(comment); 1253 } 1254 1255 public String getComment() { 1256 return Comment; 1257 } 1258 1259 1263 1264 private void getYCCArray() 1265 { 1266 int values[] = new int[imageWidth * imageHeight]; 1267 int r, g, b, y, x; 1268 PixelGrabber grabber = new PixelGrabber (imageobj.getSource(), 0, 0, imageWidth, imageHeight, values, 0, imageWidth); 1274 MaxHsampFactor = 1; 1275 MaxVsampFactor = 1; 1276 for (y = 0; y < NumberOfComponents; y++) { 1277 MaxHsampFactor = Math.max(MaxHsampFactor, HsampFactor[y]); 1278 MaxVsampFactor = Math.max(MaxVsampFactor, VsampFactor[y]); 1279 } 1280 for (y = 0; y < NumberOfComponents; y++) { 1281 compWidth[y] = (((imageWidth%8 != 0) ? ((int) Math.ceil(imageWidth/8d))*8 : imageWidth)/MaxHsampFactor)*HsampFactor[y]; 1282 if (compWidth[y] != ((imageWidth/MaxHsampFactor)*HsampFactor[y])) { 1283 lastColumnIsDummy[y] = true; 1284 } 1285 BlockWidth[y] = (int) Math.ceil(compWidth[y]/8d); 1290 compHeight[y] = (((imageHeight%8 != 0) ? ((int) Math.ceil(imageHeight/8d))*8: imageHeight)/MaxVsampFactor)*VsampFactor[y]; 1291 if (compHeight[y] != ((imageHeight/MaxVsampFactor)*VsampFactor[y])) { 1292 lastRowIsDummy[y] = true; 1293 } 1294 BlockHeight[y] = (int) Math.ceil(compHeight[y]/8d); 1295 } 1296 try 1297 { 1298 if(grabber.grabPixels() != true) 1299 { 1300 try 1301 { 1302 throw new AWTException ("Grabber returned false: " + grabber.status()); 1303 } 1304 catch (Exception e) 1305 { 1306 } 1308 } 1309 } 1310 catch (InterruptedException e) 1311 { 1312 } 1314 float Y[][] = new float[compHeight[0]][compWidth[0]]; 1315 float Cr1[][] = new float[compHeight[0]][compWidth[0]]; 1316 float Cb1[][] = new float[compHeight[0]][compWidth[0]]; 1317 int index = 0; 1320 for (y = 0; y < imageHeight; ++y) 1321 { 1322 for (x = 0; x < imageWidth; ++x) 1323 { 1324 r = ((values[index] >> 16) & 0xff); 1325 g = ((values[index] >> 8) & 0xff); 1326 b = (values[index] & 0xff); 1327 1328 Y[y][x] = (float)(0.299 * r + 0.587 * g + 0.114 * b); 1335 Cb1[y][x] = 128 + (float)(-0.16874 * r - 0.33126 * g + 0.5 * b); 1336 Cr1[y][x] = 128 + (float)(0.5 * r - 0.41869 * g - 0.08131 * b); 1337 index++; 1338 } 1339 } 1340 1341 1347 Components[0] = Y; 1348 Components[1] = Cb1; 1350 Components[2] = Cr1; 1352 } 1353 1354 float[][] DownSample(float[][] C, int comp) 1355 { 1356 int inrow, incol; 1357 int outrow, outcol; 1358 float output[][]; 1359 int bias; 1361 inrow = 0; 1362 incol = 0; 1363 output = new float[compHeight[comp]][compWidth[comp]]; 1364 for (outrow = 0; outrow < compHeight[comp]; outrow++) { 1365 bias = 1; 1366 for (outcol = 0; outcol < compWidth[comp]; outcol++) { 1367 output[outrow][outcol] = (C[inrow][incol++] + C[inrow++][incol--] + C[inrow][incol++] + C[inrow--][incol++] + bias)/4f; 1368 bias ^= 3; 1369 } 1370 inrow += 2; 1371 incol = 0; 1372 } 1373 return output; 1374 } 1375} 1376 | Popular Tags |