📄 jpegencoder.java
字号:
if (coeff[shuffledIndex] == 0) continue; // skip zeroes _examined++; if (coeff[shuffledIndex] > 0) { if ((coeff[shuffledIndex]&1) != nextBitToEmbed) { coeff[shuffledIndex]--; // decrease absolute value _changed++; } } else { if ((coeff[shuffledIndex]&1) == nextBitToEmbed) { coeff[shuffledIndex]++; // decrease absolute value _changed++; } } if (coeff[shuffledIndex] != 0) { // The coefficient is still nonzero. We // successfully embedded "nextBitToEmbed". // We will read a new bit to embed now. if (availableBitsToEmbed==0) { // If the byte of embedded text is // empty, we will get a new one. try { if (embeddedData.available()==0) break; byteToEmbed=embeddedData.read(); byteToEmbed ^= random.getNextByte(); } catch (Exception e) { e.printStackTrace(); break; } availableBitsToEmbed=8; } nextBitToEmbed = byteToEmbed & 1; byteToEmbed >>= 1; availableBitsToEmbed--; _embedded++; } else _thrown++; } }if (_examined > 0) System.out.println(_examined+" coefficients examined");System.out.println(_changed+" coefficients changed (efficiency: " +(_embedded/_changed)+"."+(((_embedded*10)/_changed)%10) +" bits per change)");System.out.println(_thrown+" coefficients thrown (zeroed)");System.out.println(_embedded+" bits ("+_embedded/8+" bytes) embedded"); }System.out.println("Starting Huffman Encoding."); // Do the Huffman Encoding now. shuffledIndex=0; for (r = 0; r < MinBlockHeight; r++) { for (c = 0; c < MinBlockWidth; c++) { for (comp = 0; comp < JpegObj.NumberOfComponents; comp++) { for(i = 0; i < JpegObj.VsampFactor[comp]; i++) { for(j = 0; j < JpegObj.HsampFactor[comp]; j++) { System.arraycopy(coeff, shuffledIndex, dctArray3, 0, 64); Huf.HuffmanBlockEncoder(outStream, dctArray3, lastDCvalue[comp], JpegObj.DCtableNumber[comp], JpegObj.ACtableNumber[comp]); lastDCvalue[comp] = dctArray3[0]; shuffledIndex += 64; } } } } } Huf.flushBuffer(outStream); } public void WriteEOI(BufferedOutputStream out) { byte[] EOI = {(byte) 0xFF, (byte) 0xD9}; WriteMarker(EOI, out); } public void WriteHeaders(BufferedOutputStream out) { int i, j, index, offset, length; int tempArray[];// the SOI marker byte[] SOI = {(byte) 0xFF, (byte) 0xD8}; WriteMarker(SOI, out);// The order of the following headers is quiet inconsequential.// the JFIF header byte JFIF[] = new byte[18]; JFIF[0] = (byte) 0xff; // app0 marker JFIF[1] = (byte) 0xe0; JFIF[2] = (byte) 0x00; // length JFIF[3] = (byte) 0x10; JFIF[4] = (byte) 0x4a; // "JFIF" JFIF[5] = (byte) 0x46; JFIF[6] = (byte) 0x49; JFIF[7] = (byte) 0x46; JFIF[8] = (byte) 0x00; JFIF[9] = (byte) 0x01; // 1.01 JFIF[10] = (byte) 0x01; JFIF[11] = (byte) 0x00; JFIF[12] = (byte) 0x00; JFIF[13] = (byte) 0x01; JFIF[14] = (byte) 0x00; JFIF[15] = (byte) 0x01; JFIF[16] = (byte) 0x00; JFIF[17] = (byte) 0x00; if (JpegObj.getComment().equals("JPEG Encoder Copyright 1998, James R. Weeks and BioElectroMech. ")) JFIF[10] = (byte) 0x00; // 1.00 WriteArray(JFIF, out);// Comment Header String comment = new String(); comment = JpegObj.getComment(); length = comment.length(); if (length != 0) { byte COM[] = new byte[length + 4]; COM[0] = (byte) 0xFF; COM[1] = (byte) 0xFE; COM[2] = (byte) ((length >> 8) & 0xFF); COM[3] = (byte) (length & 0xFF); java.lang.System.arraycopy(JpegObj.Comment.getBytes(), 0, COM, 4, JpegObj.Comment.length()); WriteArray(COM, out); }// The DQT header// 0 is the luminance index and 1 is the chrominance index byte DQT[] = new byte[134]; DQT[0] = (byte) 0xFF; DQT[1] = (byte) 0xDB; DQT[2] = (byte) 0x00; DQT[3] = (byte) 0x84; offset = 4; for (i = 0; i < 2; i++) { DQT[offset++] = (byte) ((0 << 4) + i); tempArray = (int[]) dct.quantum[i]; for (j = 0; j < 64; j++) { DQT[offset++] = (byte) tempArray[jpegNaturalOrder[j]]; } } WriteArray(DQT, out);// Start of Frame Header byte SOF[] = new byte[19]; SOF[0] = (byte) 0xFF; SOF[1] = (byte) 0xC0; SOF[2] = (byte) 0x00; SOF[3] = (byte) 17; SOF[4] = (byte) JpegObj.Precision; SOF[5] = (byte) ((JpegObj.imageHeight >> 8) & 0xFF); SOF[6] = (byte) ((JpegObj.imageHeight) & 0xFF); SOF[7] = (byte) ((JpegObj.imageWidth >> 8) & 0xFF); SOF[8] = (byte) ((JpegObj.imageWidth) & 0xFF); SOF[9] = (byte) JpegObj.NumberOfComponents; index = 10; for (i = 0; i < SOF[9]; i++) { SOF[index++] = (byte) JpegObj.CompID[i]; SOF[index++] = (byte) ((JpegObj.HsampFactor[i] << 4) + JpegObj.VsampFactor[i]); SOF[index++] = (byte) JpegObj.QtableNumber[i]; } WriteArray(SOF, out);// The DHT Header byte DHT1[], DHT2[], DHT3[], DHT4[]; int bytes, temp, oldindex, intermediateindex; length = 2; index = 4; oldindex = 4; DHT1 = new byte[17]; DHT4 = new byte[4]; DHT4[0] = (byte) 0xFF; DHT4[1] = (byte) 0xC4; for (i = 0; i < 4; i++ ) { bytes = 0; DHT1[index++ - oldindex] = (byte) ((int[]) Huf.bits.elementAt(i))[0]; for (j = 1; j < 17; j++) { temp = ((int[]) Huf.bits.elementAt(i))[j]; DHT1[index++ - oldindex] =(byte) temp; bytes += temp; } intermediateindex = index; DHT2 = new byte[bytes]; for (j = 0; j < bytes; j++) { DHT2[index++ - intermediateindex] = (byte) ((int[]) Huf.val.elementAt(i))[j]; } DHT3 = new byte[index]; java.lang.System.arraycopy(DHT4, 0, DHT3, 0, oldindex); java.lang.System.arraycopy(DHT1, 0, DHT3, oldindex, 17); java.lang.System.arraycopy(DHT2, 0, DHT3, oldindex + 17, bytes); DHT4 = DHT3; oldindex = index; } DHT4[2] = (byte) (((index - 2) >> 8)& 0xFF); DHT4[3] = (byte) ((index -2) & 0xFF); WriteArray(DHT4, out);// Start of Scan Header byte SOS[] = new byte[14]; SOS[0] = (byte) 0xFF; SOS[1] = (byte) 0xDA; SOS[2] = (byte) 0x00; SOS[3] = (byte) 12; SOS[4] = (byte) JpegObj.NumberOfComponents; index = 5; for (i = 0; i < SOS[4]; i++) { SOS[index++] = (byte) JpegObj.CompID[i]; SOS[index++] = (byte) ((JpegObj.DCtableNumber[i] << 4) + JpegObj.ACtableNumber[i]); } SOS[index++] = (byte) JpegObj.Ss; SOS[index++] = (byte) JpegObj.Se; SOS[index++] = (byte) ((JpegObj.Ah << 4) + JpegObj.Al); WriteArray(SOS, out); } void WriteMarker(byte[] data, BufferedOutputStream out) { try { out.write(data, 0, 2); } catch (IOException e) { System.out.println("IO Error: " + e.getMessage()); } } void WriteArray(byte[] data, BufferedOutputStream out) { int i, length; try { length = (((int) (data[2] & 0xFF)) << 8) + (int) (data[3] & 0xFF) + 2; out.write(data, 0, length); } catch (IOException e) { System.out.println("IO Error: " + e.getMessage()); } }}// This class incorporates quality scaling as implemented in the JPEG-6a// library. /* * DCT - A Java implementation of the Discreet Cosine Transform */class DCT{ /** * DCT Block Size - default 8 */ public int N = 8; /** * Image Quality (0-100) - default 80 (good image / good compression) */ public int QUALITY = 80; public Object quantum[] = new Object[2]; public Object Divisors[] = new Object[2]; /** * Quantitization Matrix for luminace. */ public int quantum_luminance[] = new int[N*N]; public double DivisorsLuminance[] = new double[N*N]; /** * Quantitization Matrix for chrominance. */ public int quantum_chrominance[] = new int[N*N]; public double DivisorsChrominance[] = new double[N*N]; /** * Constructs a new DCT object. Initializes the cosine transform matrix * these are used when computing the DCT and it's inverse. This also * initializes the run length counters and the ZigZag sequence. Note that * the image quality can be worse than 25 however the image will be * extemely pixelated, usually to a block size of N. * * @param QUALITY The quality of the image (0 worst - 100 best) * */ public DCT(int QUALITY) { initMatrix(QUALITY); } /* * This method sets up the quantization matrix for luminance and * chrominance using the Quality parameter. */ private void initMatrix(int quality) { double[] AANscaleFactor = { 1.0, 1.387039845, 1.306562965, 1.175875602, 1.0, 0.785694958, 0.541196100, 0.275899379}; int i; int j; int index; int Quality; int temp;// converting quality setting to that specified in the jpeg_quality_scaling// method in the IJG Jpeg-6a C libraries Quality = quality; if (Quality <= 0) Quality = 1; if (Quality > 100) Quality = 100; if (Quality < 50) Quality = 5000 / Quality; else Quality = 200 - Quality * 2;// Creating the luminance matrix quantum_luminance[0]=16; quantum_luminance[1]=11; quantum_luminance[2]=10; quantum_luminance[3]=16; quantum_luminance[4]=24; quantum_luminance[5]=40; quantum_luminance[6]=51; quantum_luminance[7]=61; quantum_luminance[8]=12; quantum_luminance[9]=12; quantum_luminance[10]=14; quantum_luminance[11]=19; quantum_luminance[12]=26; quantum_luminance[13]=58; quantum_luminance[14]=60; quantum_luminance[15]=55; quantum_luminance[16]=14; quantum_luminance[17]=13; quantum_luminance[18]=16; quantum_luminance[19]=24; quantum_luminance[20]=40; quantum_luminance[21]=57; quantum_luminance[22]=69; quantum_luminance[23]=56; quantum_luminance[24]=14; quantum_luminance[25]=17; quantum_luminance[26]=22; quantum_luminance[27]=29; quantum_luminance[28]=51; quantum_luminance[29]=87; quantum_luminance[30]=80; quantum_luminance[31]=62; quantum_luminance[32]=18; quantum_luminance[33]=22; quantum_luminance[34]=37; quantum_luminance[35]=56; quantum_luminance[36]=68; quantum_luminance[37]=109; quantum_luminance[38]=103; quantum_luminance[39]=77; quantum_luminance[40]=24; quantum_luminance[41]=35; quantum_luminance[42]=55; quantum_luminance[43]=64; quantum_luminance[44]=81; quantum_luminance[45]=104; quantum_luminance[46]=113; quantum_luminance[47]=92; quantum_luminance[48]=49; quantum_luminance[49]=64; quantum_luminance[50]=78; quantum_luminance[51]=87; quantum_luminance[52]=103; quantum_luminance[53]=121; quantum_luminance[54]=120; quantum_luminance[55]=101; quantum_luminance[56]=72; quantum_luminance[57]=92; quantum_luminance[58]=95; quantum_luminance[59]=98; quantum_luminance[60]=112; quantum_luminance[61]=100; quantum_luminance[62]=103; quantum_luminance[63]=99; for (j = 0; j < 64; j++) { temp = (quantum_luminance[j] * Quality + 50) / 100; if ( temp <= 0) temp = 1; if (temp > 255) temp = 255; quantum_luminance[j] = temp; } index = 0; for (i = 0; i < 8; i++) { for (j = 0; j < 8; j++) {// The divisors for the LL&M method (the slow integer method used in// jpeg 6a library). This method is currently (04/04/98) incompletely// implemented.// DivisorsLuminance[index] = ((double) quantum_luminance[index]) << 3;// The divisors for the AAN method (the float method used in jpeg 6a library. DivisorsLuminance[index] = (double) ((double)1.0/((double) quantum_luminance[index] * AANscaleFactor[i] * AANscaleFactor[j] * (double) 8.0)); index++; } }// Creating the chrominance matrix quantum_chrominance[0]=17; quantum_chrominance[1]=18; quantum_chrominance[2]=24; quantum_chrominance[3]=47; quantum_chrominance[4]=99; quantum_chrominance[5]=99; quantum_chrominance[6]=99; quantum_chrominance[7]=99; quantum_chrominance[8]=18; quantum_chrominance[9]=21; quantum_chrominance[10]=26; quantum_chrominance[11]=66; quantum_chrominance[12]=99; quantum_chrominance[13]=99; quantum_chrominance[14]=99; quantum_chrominance[15]=99; quantum_chrominance[16]=24; quantum_chrominance[17]=26; quantum_chrominance[18]=56; quantum_chrominance[19]=99; quantum_chrominance[20]=99; quantum_chrominance[21]=99; quantum_chrominance[22]=99; quantum_chrominance[23]=99; quantum_chrominance[24]=47; quantum_chrominance[25]=66; quantum_chrominance[26]=99; quantum_chrominance[27]=99; quantum_chrominance[28]=99; quantum_chrominance[29]=99; quantum_chrominance[30]=99; quantum_chrominance[31]=99; quantum_chrominance[32]=99; quantum_chrominance[33]=99; quantum_chrominance[34]=99; quantum_chrominance[35]=99; quantum_chrominance[36]=99;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -