001: /**
002: * JPGImage.java
003: *
004: * The authors make NO WARRANTY or representation, either express or implied,
005: * with respect to this software, its quality, accuracy, merchantability, or
006: * fitness for a particular purpose. This software is provided "AS IS", and you,
007: * its user, assume the entire risk as to its quality and accuracy.
008: *
009: * This software is copyright (C) 1991-1998, Thomas G. Lane.
010: * All Rights Reserved except as specified below.
011: *
012: * Permission is hereby granted to use, copy, modify, and distribute this
013: * software (or portions thereof) for any purpose, without fee, subject to these
014: * conditions:
015: * (1) If any part of the source code for this software is distributed, then this
016: * README file must be included, with this copyright and no-warranty notice
017: * unaltered; and any additions, deletions, or changes to the original files
018: * must be clearly indicated in accompanying documentation.
019: * (2) If only executable code is distributed, then the accompanying
020: * documentation must state that "this software is based in part on the work of
021: * the Independent JPEG Group".
022: * (3) Permission for use of this software is granted only if the user accepts
023: * full responsibility for any undesirable consequences; the authors accept
024: * NO LIABILITY for damages of any kind.
025: *
026: * These conditions apply to any software derived from or based on the IJG code,
027: * not just to the unmodified library. If you use our work, you ought to
028: * acknowledge us.
029: *
030: * Permission is NOT granted for the use of any IJG author's name or company name
031: * in advertising or publicity relating to this software or products derived from
032: * it. This software may be referred to only as "the Independent JPEG Group's
033: * software".
034: *
035: * We specifically permit and encourage the use of this software as the basis of
036: * commercial products, provided that all warranty or liability claims are
037: * assumed by the product vendor.
038: */package com.pdfjet;
039:
040: import java.lang.*;
041: import java.io.*;
042: import java.util.*;
043:
044: //>>>>pdfjet {
045: public class JPGImage {
046:
047: static final char M_SOF0 = (char) 0x00C0; // Start Of Frame N
048: static final char M_SOF1 = (char) 0x00C1; // N indicates which compression process
049: static final char M_SOF2 = (char) 0x00C2; // Only SOF0-SOF2 are now in common use
050: static final char M_SOF3 = (char) 0x00C3;
051: static final char M_SOF5 = (char) 0x00C5; // NB: codes C4 and CC are NOT SOF markers
052: static final char M_SOF6 = (char) 0x00C6;
053: static final char M_SOF7 = (char) 0x00C7;
054: static final char M_SOF9 = (char) 0x00C9;
055: static final char M_SOF10 = (char) 0x00CA;
056: static final char M_SOF11 = (char) 0x00CB;
057: static final char M_SOF13 = (char) 0x00CD;
058: static final char M_SOF14 = (char) 0x00CE;
059: static final char M_SOF15 = (char) 0x00CF;
060:
061: static final char M_SOS = (char) 0x00DA; // Start Of Scan (begins compressed data)
062:
063: protected int width = 0;
064: protected int height = 0;
065: protected int colors = 0;
066:
067: private String fileName = null;
068:
069: public JPGImage(String fileName) throws Exception {
070: this .fileName = fileName;
071:
072: FileInputStream fis = new FileInputStream(fileName);
073: char ch1 = (char) fis.read();
074: char ch2 = (char) fis.read();
075: if (ch1 == 0x00FF && ch2 == 0x00D8) {
076: boolean foundSOFn = false;
077: for (;;) {
078: char ch = nextMarker(fis);
079: switch (ch) {
080: // Note that marker codes 0xC4, 0xC8, 0xCC are not,
081: // and must not be treated as SOFn. C4 in particular
082: // is actually DHT.
083: case M_SOF0: // Baseline
084: case M_SOF1: // Extended sequential, Huffman
085: case M_SOF2: // Progressive, Huffman
086: case M_SOF3: // Lossless, Huffman
087: case M_SOF5: // Differential sequential, Huffman
088: case M_SOF6: // Differential progressive, Huffman
089: case M_SOF7: // Differential lossless, Huffman
090: case M_SOF9: // Extended sequential, arithmetic
091: case M_SOF10: // Progressive, arithmetic
092: case M_SOF11: // Lossless, arithmetic
093: case M_SOF13: // Differential sequential, arithmetic
094: case M_SOF14: // Differential progressive, arithmetic
095: case M_SOF15: // Differential lossless, arithmetic
096: // Skip 3 bytes to get to the image height and width
097: fis.read();
098: fis.read();
099: fis.read();
100: height = readTwoBytes(fis);
101: width = readTwoBytes(fis);
102: colors = fis.read();
103: foundSOFn = true;
104: break;
105:
106: default:
107: skipVariable(fis);
108: break;
109: }
110:
111: if (foundSOFn)
112: break;
113: }
114: } else {
115: throw new Exception();
116: }
117:
118: fis.close();
119: }
120:
121: private int readTwoBytes(FileInputStream fis) throws Exception {
122: int value = fis.read();
123: value <<= 8;
124: value |= fis.read();
125: return value;
126: }
127:
128: // Find the next JPEG marker and return its marker code.
129: // We expect at least one FF byte, possibly more if the compressor
130: // used FFs to pad the file.
131: // There could also be non-FF garbage between markers. The treatment
132: // of such garbage is unspecified; we choose to skip over it but emit
133: // a warning msg.
134: // NB: this routine must not be used after seeing SOS marker, since
135: // it will not deal correctly with FF/00 sequences in the compressed
136: // image data...
137: private char nextMarker(FileInputStream fis) throws Exception {
138: int discarded_bytes = 0;
139: char ch = ' ';
140:
141: // Find 0xFF byte; count and skip any non-FFs.
142: ch = (char) fis.read();
143: while (ch != 0x00FF) {
144: discarded_bytes++;
145: ch = (char) fis.read();
146: }
147:
148: // Get marker code byte, swallowing any duplicate FF bytes. Extra FFs
149: // are legal as pad bytes, so don't count them in discarded_bytes.
150: do {
151: ch = (char) fis.read();
152: } while (ch == 0x00FF);
153:
154: if (discarded_bytes != 0) {
155: throw new Exception();
156: }
157:
158: return ch;
159: }
160:
161: // Most types of marker are followed by a variable-length parameter
162: // segment. This routine skips over the parameters for any marker we
163: // don't otherwise want to process.
164: // Note that we MUST skip the parameter segment explicitly in order
165: // not to be fooled by 0xFF bytes that might appear within the
166: // parameter segment such bytes do NOT introduce new markers.
167: private void skipVariable(FileInputStream fis) throws Exception {
168: // Get the marker parameter length count
169: int length = readTwoBytes(fis);
170:
171: // Length includes itself, so must be at least 2
172: if (length < 2) {
173: throw new Exception();
174: }
175: length -= 2;
176: // Skip over the remaining bytes
177: while (length > 0) {
178: fis.read();
179: length--;
180: }
181: }
182:
183: } // End of JPGImage.java
184: //>>>>}
|