Source Code Cross Referenced for JpegEncoder.java in  » Forum » mvnforum-1.1 » net » myvietnam » mvncore » thirdparty » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Forum » mvnforum 1.1 » net.myvietnam.mvncore.thirdparty 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package net.myvietnam.mvncore.thirdparty;
0002:
0003:        // Version 1.0a
0004:        // Copyright (C) 1998, James R. Weeks and BioElectroMech.
0005:        // Visit BioElectroMech at www.obrador.com.  Email James@obrador.com.
0006:
0007:        // See license.txt for details about the allowed used of this software.
0008:        // This software is based in part on the work of the Independent JPEG Group.
0009:        // See IJGreadme.txt for details about the Independent JPEG Group's license.
0010:
0011:        // This encoder is inspired by the Java Jpeg encoder by Florian Raemy,
0012:        // studwww.eurecom.fr/~raemy.
0013:        // It borrows a great deal of code and structure from the Independent
0014:        // Jpeg Group's Jpeg 6a library, Copyright Thomas G. Lane.
0015:        // See license.txt for details.
0016:
0017:        import java.awt.AWTException;
0018:        import java.awt.Frame;
0019:        import java.awt.Image;
0020:        import java.awt.MediaTracker;
0021:        import java.awt.image.PixelGrabber;
0022:        import java.io.BufferedOutputStream;
0023:        import java.io.IOException;
0024:        import java.io.OutputStream;
0025:        import java.util.Vector;
0026:
0027:        /*
0028:         * JpegEncoder - The JPEG main program which performs a jpeg compression of
0029:         * an image.
0030:         */
0031:
0032:        public class JpegEncoder extends Frame {
0033:            Thread runner;
0034:            BufferedOutputStream outStream;
0035:            Image image;
0036:            JpegInfo JpegObj;
0037:            Huffman Huf;
0038:            DCT dct;
0039:            int imageHeight, imageWidth;
0040:            int Quality;
0041:            int code;
0042:            public static int[] jpegNaturalOrder = { 0, 1, 8, 16, 9, 2, 3, 10,
0043:                    17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41,
0044:                    34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50,
0045:                    43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38,
0046:                    31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63, };
0047:
0048:            public JpegEncoder(Image image, int quality, OutputStream out) {
0049:                MediaTracker tracker = new MediaTracker(this );
0050:                tracker.addImage(image, 0);
0051:                try {
0052:                    tracker.waitForID(0);
0053:                } catch (InterruptedException e) {
0054:                    //TODO
0055:                }
0056:                /*
0057:                 * Quality of the image.
0058:                 * 0 to 100 and from bad image quality, high compression to good
0059:                 * image quality low compression
0060:                 */
0061:                Quality = quality;
0062:
0063:                /*
0064:                 * Getting picture information
0065:                 * It takes the Width, Height and RGB scans of the image.
0066:                 */
0067:                JpegObj = new JpegInfo(image);
0068:
0069:                imageHeight = JpegObj.imageHeight;
0070:                imageWidth = JpegObj.imageWidth;
0071:                outStream = new BufferedOutputStream(out);
0072:                dct = new DCT(Quality);
0073:                Huf = new Huffman(imageWidth, imageHeight);
0074:            }
0075:
0076:            public void setQuality(int quality) {
0077:                dct = new DCT(quality);
0078:            }
0079:
0080:            public int getQuality() {
0081:                return Quality;
0082:            }
0083:
0084:            public void Compress() {
0085:                WriteHeaders(outStream);
0086:                WriteCompressedData(outStream);
0087:                WriteEOI(outStream);
0088:                try {
0089:                    outStream.flush();
0090:                } catch (IOException e) {
0091:                    //TODO
0092:                    System.out.println("IO Error: " + e.getMessage());
0093:                }
0094:            }
0095:
0096:            public void WriteCompressedData(BufferedOutputStream outStream) {
0097:                int i, j, r, c, a, b;
0098:                int comp, xpos, ypos, xblockoffset, yblockoffset;
0099:                float inputArray[][];
0100:                float dctArray1[][] = new float[8][8];
0101:                double dctArray2[][] = new double[8][8];
0102:                int dctArray3[] = new int[8 * 8];
0103:
0104:                /*
0105:                 * This method controls the compression of the image.
0106:                 * Starting at the upper left of the image, it compresses 8x8 blocks
0107:                 * of data until the entire image has been compressed.
0108:                 */
0109:
0110:                int lastDCvalue[] = new int[JpegObj.NumberOfComponents];
0111:                //int zeroArray[] = new int[64]; // initialized to hold all zeros
0112:                //int Width = 0, Height = 0;
0113:                //int nothing = 0, not;
0114:                int MinBlockWidth, MinBlockHeight;
0115:                // This initial setting of MinBlockWidth and MinBlockHeight is done to
0116:                // ensure they start with values larger than will actually be the case.
0117:                MinBlockWidth = ((imageWidth % 8 != 0) ? (int) (Math
0118:                        .floor(imageWidth / 8d) + 1) * 8 : imageWidth);
0119:                MinBlockHeight = ((imageHeight % 8 != 0) ? (int) (Math
0120:                        .floor(imageHeight / 8d) + 1) * 8 : imageHeight);
0121:                for (comp = 0; comp < JpegObj.NumberOfComponents; comp++) {
0122:                    MinBlockWidth = Math.min(MinBlockWidth,
0123:                            JpegObj.BlockWidth[comp]);
0124:                    MinBlockHeight = Math.min(MinBlockHeight,
0125:                            JpegObj.BlockHeight[comp]);
0126:                }
0127:                xpos = 0;
0128:                for (r = 0; r < MinBlockHeight; r++) {
0129:                    for (c = 0; c < MinBlockWidth; c++) {
0130:                        xpos = c * 8;
0131:                        ypos = r * 8;
0132:                        for (comp = 0; comp < JpegObj.NumberOfComponents; comp++) {
0133:                            //Width = JpegObj.BlockWidth[comp];
0134:                            //Height = JpegObj.BlockHeight[comp];
0135:                            inputArray = JpegObj.Components[comp];
0136:
0137:                            for (i = 0; i < JpegObj.VsampFactor[comp]; i++) {
0138:                                for (j = 0; j < JpegObj.HsampFactor[comp]; j++) {
0139:                                    xblockoffset = j * 8;
0140:                                    yblockoffset = i * 8;
0141:                                    for (a = 0; a < 8; a++) {
0142:                                        for (b = 0; b < 8; b++) {
0143:
0144:                                            // I believe this is where the dirty line at the bottom of the image is
0145:                                            // coming from.  I need to do a check here to make sure I'm not reading past
0146:                                            // image data.
0147:                                            // This seems to not be a big issue right now. (04/04/98)
0148:
0149:                                            dctArray1[a][b] = inputArray[ypos
0150:                                                    + yblockoffset + a][xpos
0151:                                                    + xblockoffset + b];
0152:                                        }
0153:                                    }
0154:                                    // The following code commented out because on some images this technique
0155:                                    // results in poor right and bottom borders.
0156:                                    //                        if ((!JpegObj.lastColumnIsDummy[comp] || c < Width - 1) && (!JpegObj.lastRowIsDummy[comp] || r < Height - 1)) {
0157:                                    dctArray2 = dct.forwardDCT(dctArray1);
0158:                                    dctArray3 = dct.quantizeBlock(dctArray2,
0159:                                            JpegObj.QtableNumber[comp]);
0160:                                    //                        }
0161:                                    //                        else {
0162:                                    //                           zeroArray[0] = dctArray3[0];
0163:                                    //                           zeroArray[0] = lastDCvalue[comp];
0164:                                    //                           dctArray3 = zeroArray;
0165:                                    //                        }
0166:                                    Huf.HuffmanBlockEncoder(outStream,
0167:                                            dctArray3, lastDCvalue[comp],
0168:                                            JpegObj.DCtableNumber[comp],
0169:                                            JpegObj.ACtableNumber[comp]);
0170:                                    lastDCvalue[comp] = dctArray3[0];
0171:                                }
0172:                            }
0173:                        }
0174:                    }
0175:                }
0176:                Huf.flushBuffer(outStream);
0177:            }
0178:
0179:            public void WriteEOI(BufferedOutputStream out) {
0180:                byte[] EOI = { (byte) 0xFF, (byte) 0xD9 };
0181:                WriteMarker(EOI, out);
0182:            }
0183:
0184:            public void WriteHeaders(BufferedOutputStream out) {
0185:                int i, j, index, offset, length;
0186:                int tempArray[];
0187:
0188:                // the SOI marker
0189:                byte[] SOI = { (byte) 0xFF, (byte) 0xD8 };
0190:                WriteMarker(SOI, out);
0191:
0192:                // The order of the following headers is quiet inconsequential.
0193:                // the JFIF header
0194:                byte JFIF[] = new byte[18];
0195:                JFIF[0] = (byte) 0xff;
0196:                JFIF[1] = (byte) 0xe0;
0197:                JFIF[2] = (byte) 0x00;
0198:                JFIF[3] = (byte) 0x10;
0199:                JFIF[4] = (byte) 0x4a;
0200:                JFIF[5] = (byte) 0x46;
0201:                JFIF[6] = (byte) 0x49;
0202:                JFIF[7] = (byte) 0x46;
0203:                JFIF[8] = (byte) 0x00;
0204:                JFIF[9] = (byte) 0x01;
0205:                JFIF[10] = (byte) 0x00;
0206:                JFIF[11] = (byte) 0x00;
0207:                JFIF[12] = (byte) 0x00;
0208:                JFIF[13] = (byte) 0x01;
0209:                JFIF[14] = (byte) 0x00;
0210:                JFIF[15] = (byte) 0x01;
0211:                JFIF[16] = (byte) 0x00;
0212:                JFIF[17] = (byte) 0x00;
0213:                WriteArray(JFIF, out);
0214:
0215:                // Comment Header
0216:                String comment = new String();
0217:                comment = JpegObj.getComment();
0218:                length = comment.length();
0219:                byte COM[] = new byte[length + 4];
0220:                COM[0] = (byte) 0xFF;
0221:                COM[1] = (byte) 0xFE;
0222:                COM[2] = (byte) ((length >> 8) & 0xFF);
0223:                COM[3] = (byte) (length & 0xFF);
0224:                java.lang.System.arraycopy(JpegObj.Comment.getBytes(), 0, COM,
0225:                        4, JpegObj.Comment.length());
0226:                WriteArray(COM, out);
0227:
0228:                // The DQT header
0229:                // 0 is the luminance index and 1 is the chrominance index
0230:                byte DQT[] = new byte[134];
0231:                DQT[0] = (byte) 0xFF;
0232:                DQT[1] = (byte) 0xDB;
0233:                DQT[2] = (byte) 0x00;
0234:                DQT[3] = (byte) 0x84;
0235:                offset = 4;
0236:                for (i = 0; i < 2; i++) {
0237:                    DQT[offset++] = (byte) ((0 << 4) + i);
0238:                    tempArray = dct.quantum[i];
0239:                    for (j = 0; j < 64; j++) {
0240:                        DQT[offset++] = (byte) tempArray[jpegNaturalOrder[j]];
0241:                    }
0242:                }
0243:                WriteArray(DQT, out);
0244:
0245:                // Start of Frame Header
0246:                byte SOF[] = new byte[19];
0247:                SOF[0] = (byte) 0xFF;
0248:                SOF[1] = (byte) 0xC0;
0249:                SOF[2] = (byte) 0x00;
0250:                SOF[3] = (byte) 17;
0251:                SOF[4] = (byte) JpegObj.Precision;
0252:                SOF[5] = (byte) ((JpegObj.imageHeight >> 8) & 0xFF);
0253:                SOF[6] = (byte) ((JpegObj.imageHeight) & 0xFF);
0254:                SOF[7] = (byte) ((JpegObj.imageWidth >> 8) & 0xFF);
0255:                SOF[8] = (byte) ((JpegObj.imageWidth) & 0xFF);
0256:                SOF[9] = (byte) JpegObj.NumberOfComponents;
0257:                index = 10;
0258:                for (i = 0; i < SOF[9]; i++) {
0259:                    SOF[index++] = (byte) JpegObj.CompID[i];
0260:                    SOF[index++] = (byte) ((JpegObj.HsampFactor[i] << 4) + JpegObj.VsampFactor[i]);
0261:                    SOF[index++] = (byte) JpegObj.QtableNumber[i];
0262:                }
0263:                WriteArray(SOF, out);
0264:
0265:                // The DHT Header
0266:                byte DHT1[], DHT2[], DHT3[], DHT4[];
0267:                int bytes, temp, oldindex, intermediateindex;
0268:                length = 2;
0269:                index = 4;
0270:                oldindex = 4;
0271:                DHT1 = new byte[17];
0272:                DHT4 = new byte[4];
0273:                DHT4[0] = (byte) 0xFF;
0274:                DHT4[1] = (byte) 0xC4;
0275:                for (i = 0; i < 4; i++) {
0276:                    bytes = 0;
0277:                    DHT1[index++ - oldindex] = (byte) ((int[]) Huf.bits
0278:                            .elementAt(i))[0];
0279:                    for (j = 1; j < 17; j++) {
0280:                        temp = ((int[]) Huf.bits.elementAt(i))[j];
0281:                        DHT1[index++ - oldindex] = (byte) temp;
0282:                        bytes += temp;
0283:                    }
0284:                    intermediateindex = index;
0285:                    DHT2 = new byte[bytes];
0286:                    for (j = 0; j < bytes; j++) {
0287:                        DHT2[index++ - intermediateindex] = (byte) ((int[]) Huf.val
0288:                                .elementAt(i))[j];
0289:                    }
0290:                    DHT3 = new byte[index];
0291:                    java.lang.System.arraycopy(DHT4, 0, DHT3, 0, oldindex);
0292:                    java.lang.System.arraycopy(DHT1, 0, DHT3, oldindex, 17);
0293:                    java.lang.System.arraycopy(DHT2, 0, DHT3, oldindex + 17,
0294:                            bytes);
0295:                    DHT4 = DHT3;
0296:                    oldindex = index;
0297:                }
0298:                DHT4[2] = (byte) (((index - 2) >> 8) & 0xFF);
0299:                DHT4[3] = (byte) ((index - 2) & 0xFF);
0300:                WriteArray(DHT4, out);
0301:
0302:                // Start of Scan Header
0303:                byte SOS[] = new byte[14];
0304:                SOS[0] = (byte) 0xFF;
0305:                SOS[1] = (byte) 0xDA;
0306:                SOS[2] = (byte) 0x00;
0307:                SOS[3] = (byte) 12;
0308:                SOS[4] = (byte) JpegObj.NumberOfComponents;
0309:                index = 5;
0310:                for (i = 0; i < SOS[4]; i++) {
0311:                    SOS[index++] = (byte) JpegObj.CompID[i];
0312:                    SOS[index++] = (byte) ((JpegObj.DCtableNumber[i] << 4) + JpegObj.ACtableNumber[i]);
0313:                }
0314:                SOS[index++] = (byte) JpegObj.Ss;
0315:                SOS[index++] = (byte) JpegObj.Se;
0316:                SOS[index++] = (byte) ((JpegObj.Ah << 4) + JpegObj.Al);
0317:                WriteArray(SOS, out);
0318:
0319:            }
0320:
0321:            void WriteMarker(byte[] data, BufferedOutputStream out) {
0322:                try {
0323:                    out.write(data, 0, 2);
0324:                } catch (IOException e) {
0325:                    //TODO
0326:                    System.out.println("IO Error: " + e.getMessage());
0327:                }
0328:            }
0329:
0330:            void WriteArray(byte[] data, BufferedOutputStream out) {
0331:                int length;
0332:                try {
0333:                    length = ((data[2] & 0xFF) << 8) + (data[3] & 0xFF) + 2;
0334:                    out.write(data, 0, length);
0335:                } catch (IOException e) {
0336:                    //TODO
0337:                    System.out.println("IO Error: " + e.getMessage());
0338:                }
0339:            }
0340:        }
0341:
0342:        // This class incorporates quality scaling as implemented in the JPEG-6a
0343:        // library.
0344:
0345:        /*
0346:         * DCT - A Java implementation of the Discreet Cosine Transform
0347:         */
0348:
0349:        class DCT {
0350:            /**
0351:             * DCT Block Size - default 8
0352:             */
0353:            public int N = 8;
0354:
0355:            /**
0356:             * Image Quality (0-100) - default 80 (good image / good compression)
0357:             */
0358:            public int QUALITY = 80;
0359:
0360:            public int quantum[][] = new int[2][];
0361:            public double Divisors[][] = new double[2][];
0362:
0363:            /**
0364:             * Quantitization Matrix for luminace.
0365:             */
0366:            public int quantum_luminance[] = new int[N * N];
0367:            public double DivisorsLuminance[] = new double[N * N];
0368:
0369:            /**
0370:             * Quantitization Matrix for chrominance.
0371:             */
0372:            public int quantum_chrominance[] = new int[N * N];
0373:            public double DivisorsChrominance[] = new double[N * N];
0374:
0375:            /**
0376:             * Constructs a new DCT object. Initializes the cosine transform matrix
0377:             * these are used when computing the DCT and it's inverse. This also
0378:             * initializes the run length counters and the ZigZag sequence. Note that
0379:             * the image quality can be worse than 25 however the image will be
0380:             * extemely pixelated, usually to a block size of N.
0381:             *
0382:             * @param QUALITY The quality of the image (0 worst - 100 best)
0383:             *
0384:             */
0385:            public DCT(int QUALITY) {
0386:                initMatrix(QUALITY);
0387:            }
0388:
0389:            /*
0390:             * This method sets up the quantization matrix for luminance and
0391:             * chrominance using the Quality parameter.
0392:             */
0393:            private void initMatrix(int quality) {
0394:                double[] AANscaleFactor = { 1.0, 1.387039845, 1.306562965,
0395:                        1.175875602, 1.0, 0.785694958, 0.541196100, 0.275899379 };
0396:                int i;
0397:                int j;
0398:                int index;
0399:                int Quality;
0400:                int temp;
0401:
0402:                // converting quality setting to that specified in the jpeg_quality_scaling
0403:                // method in the IJG Jpeg-6a C libraries
0404:
0405:                Quality = quality;
0406:                if (Quality <= 0)
0407:                    Quality = 1;
0408:                if (Quality > 100)
0409:                    Quality = 100;
0410:                if (Quality < 50)
0411:                    Quality = 5000 / Quality;
0412:                else
0413:                    Quality = 200 - Quality * 2;
0414:
0415:                // Creating the luminance matrix
0416:
0417:                quantum_luminance[0] = 16;
0418:                quantum_luminance[1] = 11;
0419:                quantum_luminance[2] = 10;
0420:                quantum_luminance[3] = 16;
0421:                quantum_luminance[4] = 24;
0422:                quantum_luminance[5] = 40;
0423:                quantum_luminance[6] = 51;
0424:                quantum_luminance[7] = 61;
0425:                quantum_luminance[8] = 12;
0426:                quantum_luminance[9] = 12;
0427:                quantum_luminance[10] = 14;
0428:                quantum_luminance[11] = 19;
0429:                quantum_luminance[12] = 26;
0430:                quantum_luminance[13] = 58;
0431:                quantum_luminance[14] = 60;
0432:                quantum_luminance[15] = 55;
0433:                quantum_luminance[16] = 14;
0434:                quantum_luminance[17] = 13;
0435:                quantum_luminance[18] = 16;
0436:                quantum_luminance[19] = 24;
0437:                quantum_luminance[20] = 40;
0438:                quantum_luminance[21] = 57;
0439:                quantum_luminance[22] = 69;
0440:                quantum_luminance[23] = 56;
0441:                quantum_luminance[24] = 14;
0442:                quantum_luminance[25] = 17;
0443:                quantum_luminance[26] = 22;
0444:                quantum_luminance[27] = 29;
0445:                quantum_luminance[28] = 51;
0446:                quantum_luminance[29] = 87;
0447:                quantum_luminance[30] = 80;
0448:                quantum_luminance[31] = 62;
0449:                quantum_luminance[32] = 18;
0450:                quantum_luminance[33] = 22;
0451:                quantum_luminance[34] = 37;
0452:                quantum_luminance[35] = 56;
0453:                quantum_luminance[36] = 68;
0454:                quantum_luminance[37] = 109;
0455:                quantum_luminance[38] = 103;
0456:                quantum_luminance[39] = 77;
0457:                quantum_luminance[40] = 24;
0458:                quantum_luminance[41] = 35;
0459:                quantum_luminance[42] = 55;
0460:                quantum_luminance[43] = 64;
0461:                quantum_luminance[44] = 81;
0462:                quantum_luminance[45] = 104;
0463:                quantum_luminance[46] = 113;
0464:                quantum_luminance[47] = 92;
0465:                quantum_luminance[48] = 49;
0466:                quantum_luminance[49] = 64;
0467:                quantum_luminance[50] = 78;
0468:                quantum_luminance[51] = 87;
0469:                quantum_luminance[52] = 103;
0470:                quantum_luminance[53] = 121;
0471:                quantum_luminance[54] = 120;
0472:                quantum_luminance[55] = 101;
0473:                quantum_luminance[56] = 72;
0474:                quantum_luminance[57] = 92;
0475:                quantum_luminance[58] = 95;
0476:                quantum_luminance[59] = 98;
0477:                quantum_luminance[60] = 112;
0478:                quantum_luminance[61] = 100;
0479:                quantum_luminance[62] = 103;
0480:                quantum_luminance[63] = 99;
0481:
0482:                for (j = 0; j < 64; j++) {
0483:                    temp = (quantum_luminance[j] * Quality + 50) / 100;
0484:                    if (temp <= 0)
0485:                        temp = 1;
0486:                    if (temp > 255)
0487:                        temp = 255;
0488:                    quantum_luminance[j] = temp;
0489:                }
0490:                index = 0;
0491:                for (i = 0; i < 8; i++) {
0492:                    for (j = 0; j < 8; j++) {
0493:                        // The divisors for the LL&M method (the slow integer method used in
0494:                        // jpeg 6a library).  This method is currently (04/04/98) incompletely
0495:                        // implemented.
0496:                        //                        DivisorsLuminance[index] = ((double) quantum_luminance[index]) << 3;
0497:                        // The divisors for the AAN method (the float method used in jpeg 6a library.
0498:                        DivisorsLuminance[index] = 1d / (8d
0499:                                * quantum_luminance[index] * AANscaleFactor[i] * AANscaleFactor[j]);
0500:                        index++;
0501:                    }
0502:                }
0503:
0504:                // Creating the chrominance matrix
0505:
0506:                quantum_chrominance[0] = 17;
0507:                quantum_chrominance[1] = 18;
0508:                quantum_chrominance[2] = 24;
0509:                quantum_chrominance[3] = 47;
0510:                quantum_chrominance[4] = 99;
0511:                quantum_chrominance[5] = 99;
0512:                quantum_chrominance[6] = 99;
0513:                quantum_chrominance[7] = 99;
0514:                quantum_chrominance[8] = 18;
0515:                quantum_chrominance[9] = 21;
0516:                quantum_chrominance[10] = 26;
0517:                quantum_chrominance[11] = 66;
0518:                quantum_chrominance[12] = 99;
0519:                quantum_chrominance[13] = 99;
0520:                quantum_chrominance[14] = 99;
0521:                quantum_chrominance[15] = 99;
0522:                quantum_chrominance[16] = 24;
0523:                quantum_chrominance[17] = 26;
0524:                quantum_chrominance[18] = 56;
0525:                quantum_chrominance[19] = 99;
0526:                quantum_chrominance[20] = 99;
0527:                quantum_chrominance[21] = 99;
0528:                quantum_chrominance[22] = 99;
0529:                quantum_chrominance[23] = 99;
0530:                quantum_chrominance[24] = 47;
0531:                quantum_chrominance[25] = 66;
0532:                quantum_chrominance[26] = 99;
0533:                quantum_chrominance[27] = 99;
0534:                quantum_chrominance[28] = 99;
0535:                quantum_chrominance[29] = 99;
0536:                quantum_chrominance[30] = 99;
0537:                quantum_chrominance[31] = 99;
0538:                quantum_chrominance[32] = 99;
0539:                quantum_chrominance[33] = 99;
0540:                quantum_chrominance[34] = 99;
0541:                quantum_chrominance[35] = 99;
0542:                quantum_chrominance[36] = 99;
0543:                quantum_chrominance[37] = 99;
0544:                quantum_chrominance[38] = 99;
0545:                quantum_chrominance[39] = 99;
0546:                quantum_chrominance[40] = 99;
0547:                quantum_chrominance[41] = 99;
0548:                quantum_chrominance[42] = 99;
0549:                quantum_chrominance[43] = 99;
0550:                quantum_chrominance[44] = 99;
0551:                quantum_chrominance[45] = 99;
0552:                quantum_chrominance[46] = 99;
0553:                quantum_chrominance[47] = 99;
0554:                quantum_chrominance[48] = 99;
0555:                quantum_chrominance[49] = 99;
0556:                quantum_chrominance[50] = 99;
0557:                quantum_chrominance[51] = 99;
0558:                quantum_chrominance[52] = 99;
0559:                quantum_chrominance[53] = 99;
0560:                quantum_chrominance[54] = 99;
0561:                quantum_chrominance[55] = 99;
0562:                quantum_chrominance[56] = 99;
0563:                quantum_chrominance[57] = 99;
0564:                quantum_chrominance[58] = 99;
0565:                quantum_chrominance[59] = 99;
0566:                quantum_chrominance[60] = 99;
0567:                quantum_chrominance[61] = 99;
0568:                quantum_chrominance[62] = 99;
0569:                quantum_chrominance[63] = 99;
0570:
0571:                for (j = 0; j < 64; j++) {
0572:                    temp = (quantum_chrominance[j] * Quality + 50) / 100;
0573:                    if (temp <= 0)
0574:                        temp = 1;
0575:                    if (temp >= 255)
0576:                        temp = 255;
0577:                    quantum_chrominance[j] = temp;
0578:                }
0579:                index = 0;
0580:                for (i = 0; i < 8; i++) {
0581:                    for (j = 0; j < 8; j++) {
0582:                        // The divisors for the LL&M method (the slow integer method used in
0583:                        // jpeg 6a library).  This method is currently (04/04/98) incompletely
0584:                        // implemented.
0585:                        //                        DivisorsChrominance[index] = ((double) quantum_chrominance[index]) << 3;
0586:                        // The divisors for the AAN method (the float method used in jpeg 6a library.
0587:                        DivisorsChrominance[index] = 1d / (8d
0588:                                * quantum_chrominance[index]
0589:                                * AANscaleFactor[i] * AANscaleFactor[j]);
0590:                        index++;
0591:                    }
0592:                }
0593:
0594:                // quantum and Divisors are objects used to hold the appropriate matices
0595:
0596:                quantum[0] = quantum_luminance;
0597:                Divisors[0] = DivisorsLuminance;
0598:                quantum[1] = quantum_chrominance;
0599:                Divisors[1] = DivisorsChrominance;
0600:
0601:            }
0602:
0603:            /*
0604:             * This method preforms forward DCT on a block of image data using
0605:             * the literal method specified for a 2-D Discrete Cosine Transform.
0606:             * It is included as a curiosity and can give you an idea of the
0607:             * difference in the compression result (the resulting image quality)
0608:             * by comparing its output to the output of the AAN method below.
0609:             * It is ridiculously inefficient.
0610:             */
0611:
0612:            // For now the final output is unusable.  The associated quantization step
0613:            // needs some tweaking.  If you get this part working, please let me know.
0614:            public double[][] forwardDCTExtreme(float input[][]) {
0615:                double output[][] = new double[N][N];
0616:                //double tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
0617:                //double tmp10, tmp11, tmp12, tmp13;
0618:                //double z1, z2, z3, z4, z5, z11, z13;
0619:                //int i;
0620:                //int j;
0621:                int v, u, x, y;
0622:                for (v = 0; v < 8; v++) {
0623:                    for (u = 0; u < 8; u++) {
0624:                        for (x = 0; x < 8; x++) {
0625:                            for (y = 0; y < 8; y++) {
0626:                                output[v][u] += input[x][y]
0627:                                        * Math
0628:                                                .cos(((2 * x + 1) * (double) u * Math.PI) / 16d)
0629:                                        * Math
0630:                                                .cos(((2 * y + 1) * (double) v * Math.PI) / 16d);
0631:                            }
0632:                        }
0633:                        output[v][u] *= 0.25d
0634:                                * ((u == 0) ? (1d / Math.sqrt(2)) : 1d)
0635:                                * ((v == 0) ? (1d / Math.sqrt(2)) : 1d);
0636:                    }
0637:                }
0638:                return output;
0639:            }
0640:
0641:            /*
0642:             * This method preforms a DCT on a block of image data using the AAN
0643:             * method as implemented in the IJG Jpeg-6a library.
0644:             */
0645:            public double[][] forwardDCT(float input[][]) {
0646:                double output[][] = new double[N][N];
0647:                double tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
0648:                double tmp10, tmp11, tmp12, tmp13;
0649:                double z1, z2, z3, z4, z5, z11, z13;
0650:                int i;
0651:                int j;
0652:
0653:                // Subtracts 128 from the input values
0654:                for (i = 0; i < 8; i++) {
0655:                    for (j = 0; j < 8; j++) {
0656:                        output[i][j] = input[i][j] - 128d;
0657:                        //                        input[i][j] -= 128;
0658:
0659:                    }
0660:                }
0661:
0662:                for (i = 0; i < 8; i++) {
0663:                    tmp0 = output[i][0] + output[i][7];
0664:                    tmp7 = output[i][0] - output[i][7];
0665:                    tmp1 = output[i][1] + output[i][6];
0666:                    tmp6 = output[i][1] - output[i][6];
0667:                    tmp2 = output[i][2] + output[i][5];
0668:                    tmp5 = output[i][2] - output[i][5];
0669:                    tmp3 = output[i][3] + output[i][4];
0670:                    tmp4 = output[i][3] - output[i][4];
0671:
0672:                    tmp10 = tmp0 + tmp3;
0673:                    tmp13 = tmp0 - tmp3;
0674:                    tmp11 = tmp1 + tmp2;
0675:                    tmp12 = tmp1 - tmp2;
0676:
0677:                    output[i][0] = tmp10 + tmp11;
0678:                    output[i][4] = tmp10 - tmp11;
0679:
0680:                    z1 = (tmp12 + tmp13) * 0.707106781d;
0681:                    output[i][2] = tmp13 + z1;
0682:                    output[i][6] = tmp13 - z1;
0683:
0684:                    tmp10 = tmp4 + tmp5;
0685:                    tmp11 = tmp5 + tmp6;
0686:                    tmp12 = tmp6 + tmp7;
0687:
0688:                    z5 = (tmp10 - tmp12) * 0.382683433d;
0689:                    z2 = 0.541196100d * tmp10 + z5;
0690:                    z4 = 1.306562965d * tmp12 + z5;
0691:                    z3 = tmp11 * 0.707106781d;
0692:
0693:                    z11 = tmp7 + z3;
0694:                    z13 = tmp7 - z3;
0695:
0696:                    output[i][5] = z13 + z2;
0697:                    output[i][3] = z13 - z2;
0698:                    output[i][1] = z11 + z4;
0699:                    output[i][7] = z11 - z4;
0700:                }
0701:
0702:                for (i = 0; i < 8; i++) {
0703:                    tmp0 = output[0][i] + output[7][i];
0704:                    tmp7 = output[0][i] - output[7][i];
0705:                    tmp1 = output[1][i] + output[6][i];
0706:                    tmp6 = output[1][i] - output[6][i];
0707:                    tmp2 = output[2][i] + output[5][i];
0708:                    tmp5 = output[2][i] - output[5][i];
0709:                    tmp3 = output[3][i] + output[4][i];
0710:                    tmp4 = output[3][i] - output[4][i];
0711:
0712:                    tmp10 = tmp0 + tmp3;
0713:                    tmp13 = tmp0 - tmp3;
0714:                    tmp11 = tmp1 + tmp2;
0715:                    tmp12 = tmp1 - tmp2;
0716:
0717:                    output[0][i] = tmp10 + tmp11;
0718:                    output[4][i] = tmp10 - tmp11;
0719:
0720:                    z1 = (tmp12 + tmp13) * 0.707106781d;
0721:                    output[2][i] = tmp13 + z1;
0722:                    output[6][i] = tmp13 - z1;
0723:
0724:                    tmp10 = tmp4 + tmp5;
0725:                    tmp11 = tmp5 + tmp6;
0726:                    tmp12 = tmp6 + tmp7;
0727:
0728:                    z5 = (tmp10 - tmp12) * 0.382683433d;
0729:                    z2 = 0.541196100d * tmp10 + z5;
0730:                    z4 = 1.306562965d * tmp12 + z5;
0731:                    z3 = tmp11 * 0.707106781d;
0732:
0733:                    z11 = tmp7 + z3;
0734:                    z13 = tmp7 - z3;
0735:
0736:                    output[5][i] = z13 + z2;
0737:                    output[3][i] = z13 - z2;
0738:                    output[1][i] = z11 + z4;
0739:                    output[7][i] = z11 - z4;
0740:                }
0741:
0742:                return output;
0743:            }
0744:
0745:            /*
0746:             * This method quantitizes data and rounds it to the nearest integer.
0747:             */
0748:            public int[] quantizeBlock(double inputData[][], int code) {
0749:                int outputData[] = new int[N * N];
0750:                int i, j;
0751:                int index;
0752:                index = 0;
0753:                for (i = 0; i < 8; i++) {
0754:                    for (j = 0; j < 8; j++) {
0755:                        // The second line results in significantly better compression.
0756:                        outputData[index] = (int) (Math.round(inputData[i][j]
0757:                                * Divisors[code][index]));
0758:                        //                        outputData[index] = (int)(((inputData[i][j] * (((double[]) (Divisors[code]))[index])) + 16384.5) -16384);
0759:                        index++;
0760:                    }
0761:                }
0762:
0763:                return outputData;
0764:            }
0765:
0766:            /*
0767:             * This is the method for quantizing a block DCT'ed with forwardDCTExtreme
0768:             * This method quantitizes data and rounds it to the nearest integer.
0769:             */
0770:            public int[] quantizeBlockExtreme(double inputData[][], int code) {
0771:                int outputData[] = new int[N * N];
0772:                int i, j;
0773:                int index;
0774:                index = 0;
0775:                for (i = 0; i < 8; i++) {
0776:                    for (j = 0; j < 8; j++) {
0777:                        outputData[index] = (int) (Math.round(inputData[i][j]
0778:                                / quantum[code][index]));
0779:                        index++;
0780:                    }
0781:                }
0782:
0783:                return outputData;
0784:            }
0785:        }
0786:
0787:        // This class was modified by James R. Weeks on 3/27/98.
0788:        // It now incorporates Huffman table derivation as in the C jpeg library
0789:        // from the IJG, Jpeg-6a.
0790:
0791:        class Huffman {
0792:            int bufferPutBits, bufferPutBuffer;
0793:            public int ImageHeight;
0794:            public int ImageWidth;
0795:            public int DC_matrix0[][];
0796:            public int AC_matrix0[][];
0797:            public int DC_matrix1[][];
0798:            public int AC_matrix1[][];
0799:            public int DC_matrix[][][];
0800:            public int AC_matrix[][][];
0801:            public int code;
0802:            public int NumOfDCTables;
0803:            public int NumOfACTables;
0804:            public int[] bitsDCluminance = { 0x00, 0, 1, 5, 1, 1, 1, 1, 1, 1,
0805:                    0, 0, 0, 0, 0, 0, 0 };
0806:            public int[] valDCluminance = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
0807:                    11 };
0808:            public int[] bitsDCchrominance = { 0x01, 0, 3, 1, 1, 1, 1, 1, 1, 1,
0809:                    1, 1, 0, 0, 0, 0, 0 };
0810:            public int[] valDCchrominance = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
0811:                    11 };
0812:            public int[] bitsACluminance = { 0x10, 0, 2, 1, 3, 3, 2, 4, 3, 5,
0813:                    5, 4, 4, 0, 0, 1, 0x7d };
0814:            public int[] valACluminance = { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
0815:                    0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
0816:                    0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42,
0817:                    0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72,
0818:                    0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26,
0819:                    0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0820:                    0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53,
0821:                    0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65,
0822:                    0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77,
0823:                    0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
0824:                    0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,
0825:                    0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2,
0826:                    0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
0827:                    0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
0828:                    0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4,
0829:                    0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4,
0830:                    0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa };
0831:            public int[] bitsACchrominance = { 0x11, 0, 2, 1, 2, 4, 4, 3, 4, 7,
0832:                    5, 4, 4, 0, 1, 2, 0x77 };
0833:            public int[] valACchrominance = { 0x00, 0x01, 0x02, 0x03, 0x11,
0834:                    0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61,
0835:                    0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1,
0836:                    0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72,
0837:                    0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18,
0838:                    0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37,
0839:                    0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
0840:                    0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63,
0841:                    0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75,
0842:                    0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86,
0843:                    0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0844:                    0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
0845:                    0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
0846:                    0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,
0847:                    0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2,
0848:                    0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3,
0849:                    0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa };
0850:            public Vector bits;
0851:            public Vector val;
0852:
0853:            /*
0854:             * jpegNaturalOrder[i] is the natural-order position of the i'th element
0855:             * of zigzag order.
0856:             */
0857:            public static int[] jpegNaturalOrder = { 0, 1, 8, 16, 9, 2, 3, 10,
0858:                    17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41,
0859:                    34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50,
0860:                    43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38,
0861:                    31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63, };
0862:
0863:            /*
0864:             * The Huffman class constructor
0865:             */
0866:            public Huffman(int Width, int Height) {
0867:
0868:                bits = new Vector();
0869:                bits.addElement(bitsDCluminance);
0870:                bits.addElement(bitsACluminance);
0871:                bits.addElement(bitsDCchrominance);
0872:                bits.addElement(bitsACchrominance);
0873:                val = new Vector();
0874:                val.addElement(valDCluminance);
0875:                val.addElement(valACluminance);
0876:                val.addElement(valDCchrominance);
0877:                val.addElement(valACchrominance);
0878:                initHuf();
0879:                //code=code;
0880:                ImageWidth = Width;
0881:                ImageHeight = Height;
0882:
0883:            }
0884:
0885:            /**
0886:             * HuffmanBlockEncoder run length encodes and Huffman encodes the quantized
0887:             * data.
0888:             **/
0889:
0890:            public void HuffmanBlockEncoder(BufferedOutputStream outStream,
0891:                    int zigzag[], int prec, int DCcode, int ACcode) {
0892:                int temp, temp2, nbits, k, r, i;
0893:
0894:                NumOfDCTables = 2;
0895:                NumOfACTables = 2;
0896:
0897:                // The DC portion
0898:
0899:                temp = temp2 = zigzag[0] - prec;
0900:                if (temp < 0) {
0901:                    temp = -temp;
0902:                    temp2--;
0903:                }
0904:                nbits = 0;
0905:                while (temp != 0) {
0906:                    nbits++;
0907:                    temp >>= 1;
0908:                }
0909:                //        if (nbits > 11) nbits = 11;
0910:                bufferIt(outStream, DC_matrix[DCcode][nbits][0],
0911:                        DC_matrix[DCcode][nbits][1]);
0912:                // The arguments in bufferIt are code and size.
0913:                if (nbits != 0) {
0914:                    bufferIt(outStream, temp2, nbits);
0915:                }
0916:
0917:                // The AC portion
0918:
0919:                r = 0;
0920:
0921:                for (k = 1; k < 64; k++) {
0922:                    if ((temp = zigzag[jpegNaturalOrder[k]]) == 0) {
0923:                        r++;
0924:                    } else {
0925:                        while (r > 15) {
0926:                            bufferIt(outStream, AC_matrix[ACcode][0xF0][0],
0927:                                    AC_matrix[ACcode][0xF0][1]);
0928:                            r -= 16;
0929:                        }
0930:                        temp2 = temp;
0931:                        if (temp < 0) {
0932:                            temp = -temp;
0933:                            temp2--;
0934:                        }
0935:                        nbits = 1;
0936:                        while ((temp >>= 1) != 0) {
0937:                            nbits++;
0938:                        }
0939:                        i = (r << 4) + nbits;
0940:                        bufferIt(outStream, AC_matrix[ACcode][i][0],
0941:                                AC_matrix[ACcode][i][1]);
0942:                        bufferIt(outStream, temp2, nbits);
0943:
0944:                        r = 0;
0945:                    }
0946:                }
0947:
0948:                if (r > 0) {
0949:                    bufferIt(outStream, AC_matrix[ACcode][0][0],
0950:                            AC_matrix[ACcode][0][1]);
0951:                }
0952:
0953:            }
0954:
0955:            // Uses an integer long (32 bits) buffer to store the Huffman encoded bits
0956:            // and sends them to outStream by the byte.
0957:
0958:            void bufferIt(BufferedOutputStream outStream, int code, int size) {
0959:                int PutBuffer = code;
0960:                int PutBits = bufferPutBits;
0961:
0962:                PutBuffer &= (1 << size) - 1;
0963:                PutBits += size;
0964:                PutBuffer <<= 24 - PutBits;
0965:                PutBuffer |= bufferPutBuffer;
0966:
0967:                while (PutBits >= 8) {
0968:                    int c = ((PutBuffer >> 16) & 0xFF);
0969:                    try {
0970:                        outStream.write(c);
0971:                    } catch (IOException e) {
0972:                        //TODO
0973:                        System.out.println("IO Error: " + e.getMessage());
0974:                    }
0975:                    if (c == 0xFF) {
0976:                        try {
0977:                            outStream.write(0);
0978:                        } catch (IOException e) {
0979:                            //TODO
0980:                            System.out.println("IO Error: " + e.getMessage());
0981:                        }
0982:                    }
0983:                    PutBuffer <<= 8;
0984:                    PutBits -= 8;
0985:                }
0986:                bufferPutBuffer = PutBuffer;
0987:                bufferPutBits = PutBits;
0988:
0989:            }
0990:
0991:            void flushBuffer(BufferedOutputStream outStream) {
0992:                int PutBuffer = bufferPutBuffer;
0993:                int PutBits = bufferPutBits;
0994:                while (PutBits >= 8) {
0995:                    int c = ((PutBuffer >> 16) & 0xFF);
0996:                    try {
0997:                        outStream.write(c);
0998:                    } catch (IOException e) {
0999:                        //TODO
1000:                        System.out.println("IO Error: " + e.getMessage());
1001:                    }
1002:                    if (c == 0xFF) {
1003:                        try {
1004:                            outStream.write(0);
1005:                        } catch (IOException e) {
1006:                            //TODO
1007:                            System.out.println("IO Error: " + e.getMessage());
1008:                        }
1009:                    }
1010:                    PutBuffer <<= 8;
1011:                    PutBits -= 8;
1012:                }
1013:                if (PutBits > 0) {
1014:                    int c = ((PutBuffer >> 16) & 0xFF);
1015:                    try {
1016:                        outStream.write(c);
1017:                    } catch (IOException e) {
1018:                        //TODO
1019:                        System.out.println("IO Error: " + e.getMessage());
1020:                    }
1021:                }
1022:            }
1023:
1024:            /*
1025:             * Initialisation of the Huffman codes for Luminance and Chrominance.
1026:             * This code results in the same tables created in the IJG Jpeg-6a
1027:             * library.
1028:             */
1029:
1030:            public void initHuf() {
1031:                DC_matrix0 = new int[12][2];
1032:                DC_matrix1 = new int[12][2];
1033:                AC_matrix0 = new int[255][2];
1034:                AC_matrix1 = new int[255][2];
1035:                DC_matrix = new int[2][][];
1036:                AC_matrix = new int[2][][];
1037:                int p, l, i, lastp, si, code;
1038:                int[] huffsize = new int[257];
1039:                int[] huffcode = new int[257];
1040:
1041:                /*
1042:                 * init of the DC values for the chrominance
1043:                 * [][0] is the code   [][1] is the number of bit
1044:                 */
1045:
1046:                p = 0;
1047:                for (l = 1; l <= 16; l++) {
1048:                    for (i = 1; i <= bitsDCchrominance[l]; i++) {
1049:                        huffsize[p++] = l;
1050:                    }
1051:                }
1052:                huffsize[p] = 0;
1053:                lastp = p;
1054:
1055:                code = 0;
1056:                si = huffsize[0];
1057:                p = 0;
1058:                while (huffsize[p] != 0) {
1059:                    while (huffsize[p] == si) {
1060:                        huffcode[p++] = code;
1061:                        code++;
1062:                    }
1063:                    code <<= 1;
1064:                    si++;
1065:                }
1066:
1067:                for (p = 0; p < lastp; p++) {
1068:                    DC_matrix1[valDCchrominance[p]][0] = huffcode[p];
1069:                    DC_matrix1[valDCchrominance[p]][1] = huffsize[p];
1070:                }
1071:
1072:                /*
1073:                 * Init of the AC hufmann code for the chrominance
1074:                 * matrix [][][0] is the code & matrix[][][1] is the number of bit needed
1075:                 */
1076:
1077:                p = 0;
1078:                for (l = 1; l <= 16; l++) {
1079:                    for (i = 1; i <= bitsACchrominance[l]; i++) {
1080:                        huffsize[p++] = l;
1081:                    }
1082:                }
1083:                huffsize[p] = 0;
1084:                lastp = p;
1085:
1086:                code = 0;
1087:                si = huffsize[0];
1088:                p = 0;
1089:                while (huffsize[p] != 0) {
1090:                    while (huffsize[p] == si) {
1091:                        huffcode[p++] = code;
1092:                        code++;
1093:                    }
1094:                    code <<= 1;
1095:                    si++;
1096:                }
1097:
1098:                for (p = 0; p < lastp; p++) {
1099:                    AC_matrix1[valACchrominance[p]][0] = huffcode[p];
1100:                    AC_matrix1[valACchrominance[p]][1] = huffsize[p];
1101:                }
1102:
1103:                /*
1104:                 * init of the DC values for the luminance
1105:                 * [][0] is the code   [][1] is the number of bit
1106:                 */
1107:                p = 0;
1108:                for (l = 1; l <= 16; l++) {
1109:                    for (i = 1; i <= bitsDCluminance[l]; i++) {
1110:                        huffsize[p++] = l;
1111:                    }
1112:                }
1113:                huffsize[p] = 0;
1114:                lastp = p;
1115:
1116:                code = 0;
1117:                si = huffsize[0];
1118:                p = 0;
1119:                while (huffsize[p] != 0) {
1120:                    while (huffsize[p] == si) {
1121:                        huffcode[p++] = code;
1122:                        code++;
1123:                    }
1124:                    code <<= 1;
1125:                    si++;
1126:                }
1127:
1128:                for (p = 0; p < lastp; p++) {
1129:                    DC_matrix0[valDCluminance[p]][0] = huffcode[p];
1130:                    DC_matrix0[valDCluminance[p]][1] = huffsize[p];
1131:                }
1132:
1133:                /*
1134:                 * Init of the AC hufmann code for luminance
1135:                 * matrix [][][0] is the code & matrix[][][1] is the number of bit
1136:                 */
1137:
1138:                p = 0;
1139:                for (l = 1; l <= 16; l++) {
1140:                    for (i = 1; i <= bitsACluminance[l]; i++) {
1141:                        huffsize[p++] = l;
1142:                    }
1143:                }
1144:                huffsize[p] = 0;
1145:                lastp = p;
1146:
1147:                code = 0;
1148:                si = huffsize[0];
1149:                p = 0;
1150:                while (huffsize[p] != 0) {
1151:                    while (huffsize[p] == si) {
1152:                        huffcode[p++] = code;
1153:                        code++;
1154:                    }
1155:                    code <<= 1;
1156:                    si++;
1157:                }
1158:                for (int q = 0; q < lastp; q++) {
1159:                    AC_matrix0[valACluminance[q]][0] = huffcode[q];
1160:                    AC_matrix0[valACluminance[q]][1] = huffsize[q];
1161:                }
1162:
1163:                DC_matrix[0] = DC_matrix0;
1164:                DC_matrix[1] = DC_matrix1;
1165:                AC_matrix[0] = AC_matrix0;
1166:                AC_matrix[1] = AC_matrix1;
1167:            }
1168:
1169:        }
1170:
1171:        /*
1172:         * JpegInfo - Given an image, sets default information about it and divides
1173:         * it into its constituant components, downsizing those that need to be.
1174:         */
1175:
1176:        class JpegInfo {
1177:            String Comment;
1178:            public Image imageobj;
1179:            public int imageHeight;
1180:            public int imageWidth;
1181:            public int BlockWidth[];
1182:            public int BlockHeight[];
1183:
1184:            // the following are set as the default
1185:            public int Precision = 8;
1186:            public int NumberOfComponents = 3;
1187:            public float Components[][][];
1188:            public int[] CompID = { 1, 2, 3 };
1189:            public int[] HsampFactor = { 1, 1, 1 };
1190:            public int[] VsampFactor = { 1, 1, 1 };
1191:            public int[] QtableNumber = { 0, 1, 1 };
1192:            public int[] DCtableNumber = { 0, 1, 1 };
1193:            public int[] ACtableNumber = { 0, 1, 1 };
1194:            public boolean[] lastColumnIsDummy = { false, false, false };
1195:            public boolean[] lastRowIsDummy = { false, false, false };
1196:            public int Ss = 0;
1197:            public int Se = 63;
1198:            public int Ah = 0;
1199:            public int Al = 0;
1200:            public int compWidth[], compHeight[];
1201:            public int MaxHsampFactor;
1202:            public int MaxVsampFactor;
1203:
1204:            public JpegInfo(Image image) {
1205:                Components = new float[NumberOfComponents][][];
1206:                compWidth = new int[NumberOfComponents];
1207:                compHeight = new int[NumberOfComponents];
1208:                BlockWidth = new int[NumberOfComponents];
1209:                BlockHeight = new int[NumberOfComponents];
1210:                imageobj = image;
1211:                imageWidth = image.getWidth(null);
1212:                imageHeight = image.getHeight(null);
1213:                Comment = "JPEG Encoder Copyright 1998, James R. Weeks and BioElectroMech.  ";
1214:                getYCCArray();
1215:            }
1216:
1217:            public void setComment(String comment) {
1218:                Comment.concat(comment);
1219:            }
1220:
1221:            public String getComment() {
1222:                return Comment;
1223:            }
1224:
1225:            /*
1226:             * This method creates and fills three arrays, Y, Cb, and Cr using the
1227:             * input image.
1228:             */
1229:
1230:            private void getYCCArray() {
1231:                int values[] = new int[imageWidth * imageHeight];
1232:                int r, g, b, y, x;
1233:                // In order to minimize the chance that grabPixels will throw an exception
1234:                // it may be necessary to grab some pixels every few scanlines and process
1235:                // those before going for more.  The time expense may be prohibitive.
1236:                // However, for a situation where memory overhead is a concern, this may be
1237:                // the only choice.
1238:                PixelGrabber grabber = new PixelGrabber(imageobj.getSource(),
1239:                        0, 0, imageWidth, imageHeight, values, 0, imageWidth);
1240:                MaxHsampFactor = 1;
1241:                MaxVsampFactor = 1;
1242:                for (y = 0; y < NumberOfComponents; y++) {
1243:                    MaxHsampFactor = Math.max(MaxHsampFactor, HsampFactor[y]);
1244:                    MaxVsampFactor = Math.max(MaxVsampFactor, VsampFactor[y]);
1245:                }
1246:                for (y = 0; y < NumberOfComponents; y++) {
1247:                    compWidth[y] = (((imageWidth % 8 != 0) ? ((int) Math
1248:                            .ceil(imageWidth / 8d)) * 8 : imageWidth) / MaxHsampFactor)
1249:                            * HsampFactor[y];
1250:                    if (compWidth[y] != ((imageWidth / MaxHsampFactor) * HsampFactor[y])) {
1251:                        lastColumnIsDummy[y] = true;
1252:                    }
1253:                    // results in a multiple of 8 for compWidth
1254:                    // this will make the rest of the program fail for the unlikely
1255:                    // event that someone tries to compress an 16 x 16 pixel image
1256:                    // which would of course be worse than pointless
1257:                    BlockWidth[y] = (int) Math.ceil(compWidth[y] / 8d);
1258:                    compHeight[y] = (((imageHeight % 8 != 0) ? ((int) Math
1259:                            .ceil(imageHeight / 8d)) * 8 : imageHeight) / MaxVsampFactor)
1260:                            * VsampFactor[y];
1261:                    if (compHeight[y] != ((imageHeight / MaxVsampFactor) * VsampFactor[y])) {
1262:                        lastRowIsDummy[y] = true;
1263:                    }
1264:                    BlockHeight[y] = (int) Math.ceil(compHeight[y] / 8d);
1265:                }
1266:                try {
1267:                    if (grabber.grabPixels() != true) {
1268:                        try {
1269:                            throw new AWTException("Grabber returned false: "
1270:                                    + grabber.status());
1271:                        } catch (Exception e) {
1272:                            //TODO
1273:                        }
1274:                    }
1275:                } catch (InterruptedException e) {
1276:                    //TODO
1277:                }
1278:                float Y[][] = new float[compHeight[0]][compWidth[0]];
1279:                float Cr1[][] = new float[compHeight[0]][compWidth[0]];
1280:                float Cb1[][] = new float[compHeight[0]][compWidth[0]];
1281:                //float Cb2[][] = new float[compHeight[1]][compWidth[1]];
1282:                //float Cr2[][] = new float[compHeight[2]][compWidth[2]];
1283:                int index = 0;
1284:                for (y = 0; y < imageHeight; ++y) {
1285:                    for (x = 0; x < imageWidth; ++x) {
1286:                        r = ((values[index] >> 16) & 0xff);
1287:                        g = ((values[index] >> 8) & 0xff);
1288:                        b = (values[index] & 0xff);
1289:
1290:                        // The following three lines are a more correct color conversion but
1291:                        // the current conversion technique is sufficient and results in a higher
1292:                        // compression rate.
1293:                        //                Y[y][x] = 16 + (float)(0.8588*(0.299 * (float)r + 0.587 * (float)g + 0.114 * (float)b ));
1294:                        //                Cb1[y][x] = 128 + (float)(0.8784*(-0.16874 * (float)r - 0.33126 * (float)g + 0.5 * (float)b));
1295:                        //                Cr1[y][x] = 128 + (float)(0.8784*(0.5 * (float)r - 0.41869 * (float)g - 0.08131 * (float)b));
1296:                        Y[y][x] = (float) (0.299 * r + 0.587 * g + 0.114 * b);
1297:                        Cb1[y][x] = 128 + (float) (-0.16874 * r - 0.33126 * g + 0.5 * b);
1298:                        Cr1[y][x] = 128 + (float) (0.5 * r - 0.41869 * g - 0.08131 * b);
1299:                        index++;
1300:                    }
1301:                }
1302:
1303:                // Need a way to set the H and V sample factors before allowing downsampling.
1304:                // For now (04/04/98) downsampling must be hard coded.
1305:                // Until a better downsampler is implemented, this will not be done.
1306:                // Downsampling is currently supported.  The downsampling method here
1307:                // is a simple box filter.
1308:
1309:                Components[0] = Y;
1310:                //        Cb2 = DownSample(Cb1, 1);
1311:                Components[1] = Cb1;
1312:                //        Cr2 = DownSample(Cr1, 2);
1313:                Components[2] = Cr1;
1314:            }
1315:
1316:            float[][] DownSample(float[][] C, int comp) {
1317:                int inrow, incol;
1318:                int outrow, outcol;
1319:                float output[][];
1320:                //int temp;
1321:                int bias;
1322:                inrow = 0;
1323:                incol = 0;
1324:                output = new float[compHeight[comp]][compWidth[comp]];
1325:                for (outrow = 0; outrow < compHeight[comp]; outrow++) {
1326:                    bias = 1;
1327:                    for (outcol = 0; outcol < compWidth[comp]; outcol++) {
1328:                        output[outrow][outcol] = (C[inrow][incol++]
1329:                                + C[inrow++][incol--] + C[inrow][incol++]
1330:                                + C[inrow--][incol++] + bias) / 4f;
1331:                        bias ^= 3;
1332:                    }
1333:                    inrow += 2;
1334:                    incol = 0;
1335:                }
1336:                return output;
1337:            }
1338:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.