001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.swt.internal.image;
011:
012: final class JPEGQuantizationTable extends JPEGVariableSizeSegment {
013: public static byte[] DefaultLuminanceQTable = { (byte) 255,
014: (byte) 219, 0, 67, 0, 16, 11, 10, 16, 24, 40, 51, 61, 12,
015: 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56,
016: 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56, 68, 109,
017: 103, 77, 24, 35, 55, 64, 81, 104, 113, 92, 49, 64, 78, 87,
018: 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99 };
019: public static byte[] DefaultChrominanceQTable = { (byte) 255,
020: (byte) 219, 0, 67, 1, 17, 18, 24, 47, 99, 99, 99, 99, 18,
021: 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99,
022: 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
023: 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
024: 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 };
025:
026: public JPEGQuantizationTable(byte[] reference) {
027: super (reference);
028: }
029:
030: public JPEGQuantizationTable(LEDataInputStream byteStream) {
031: super (byteStream);
032: }
033:
034: public static JPEGQuantizationTable defaultChrominanceTable() {
035: byte[] data = new byte[DefaultChrominanceQTable.length];
036: System.arraycopy(DefaultChrominanceQTable, 0, data, 0,
037: data.length);
038: return new JPEGQuantizationTable(data);
039: }
040:
041: public static JPEGQuantizationTable defaultLuminanceTable() {
042: byte[] data = new byte[DefaultLuminanceQTable.length];
043: System.arraycopy(DefaultLuminanceQTable, 0, data, 0,
044: data.length);
045: return new JPEGQuantizationTable(data);
046: }
047:
048: public int[] getQuantizationTablesKeys() {
049: int[] keys = new int[4];
050: int keysIndex = 0;
051: int totalLength = getSegmentLength() - 2;
052: int ofs = 4;
053: while (totalLength > 64) {
054: int tq = reference[ofs] & 0xF;
055: int pq = (reference[ofs] & 0xFF) >> 4;
056: if (pq == 0) {
057: ofs += 65;
058: totalLength -= 65;
059: } else {
060: ofs += 129;
061: totalLength -= 129;
062: }
063: if (keysIndex >= keys.length) {
064: int[] newKeys = new int[keys.length + 4];
065: System.arraycopy(keys, 0, newKeys, 0, keys.length);
066: keys = newKeys;
067: }
068: keys[keysIndex] = tq;
069: keysIndex++;
070: }
071: int[] newKeys = new int[keysIndex];
072: System.arraycopy(keys, 0, newKeys, 0, keysIndex);
073: return newKeys;
074: }
075:
076: public int[][] getQuantizationTablesValues() {
077: int[][] values = new int[4][];
078: int valuesIndex = 0;
079: int totalLength = getSegmentLength() - 2;
080: int ofs = 4;
081: while (totalLength > 64) {
082: int[] qk = new int[64];
083: int pq = (reference[ofs] & 0xFF) >> 4;
084: if (pq == 0) {
085: for (int i = 0; i < qk.length; i++) {
086: qk[i] = reference[ofs + i + 1] & 0xFF;
087: }
088: ofs += 65;
089: totalLength -= 65;
090: } else {
091: for (int i = 0; i < qk.length; i++) {
092: int idx = (i - 1) * 2;
093: qk[i] = (reference[ofs + idx + 1] & 0xFF) * 256
094: + (reference[ofs + idx + 2] & 0xFF);
095: }
096: ofs += 129;
097: totalLength -= 129;
098: }
099: if (valuesIndex >= values.length) {
100: int[][] newValues = new int[values.length + 4][];
101: System
102: .arraycopy(values, 0, newValues, 0,
103: values.length);
104: values = newValues;
105: }
106: values[valuesIndex] = qk;
107: valuesIndex++;
108: }
109: int[][] newValues = new int[valuesIndex][];
110: System.arraycopy(values, 0, newValues, 0, valuesIndex);
111: return newValues;
112: }
113:
114: public void scaleBy(int qualityFactor) {
115: int qFactor = qualityFactor;
116: if (qFactor <= 0) {
117: qFactor = 1;
118: }
119: if (qFactor > 100) {
120: qFactor = 100;
121: }
122: if (qFactor < 50) {
123: qFactor = 5000 / qFactor;
124: } else {
125: qFactor = 200 - (qFactor * 2);
126: }
127: int totalLength = getSegmentLength() - 2;
128: int ofs = 4;
129: while (totalLength > 64) {
130: // int tq = reference[ofs] & 0xFF;
131: int pq = (reference[ofs] & 0xFF) >> 4;
132: if (pq == 0) {
133: for (int i = ofs + 1; i <= ofs + 64; i++) {
134: int temp = ((reference[i] & 0xFF) * qFactor + 50) / 100;
135: if (temp <= 0)
136: temp = 1;
137: if (temp > 255)
138: temp = 255;
139: reference[i] = (byte) temp;
140: }
141: ofs += 65;
142: totalLength -= 65;
143: } else {
144: for (int i = ofs + 1; i <= ofs + 128; i += 2) {
145: int temp = (((reference[i] & 0xFF) * 256 + (reference[i + 1] & 0xFF))
146: * qFactor + 50) / 100;
147: if (temp <= 0)
148: temp = 1;
149: if (temp > 32767)
150: temp = 32767;
151: reference[i] = (byte) (temp >> 8);
152: reference[i + 1] = (byte) (temp & 0xFF);
153: }
154: ofs += 129;
155: totalLength -= 129;
156: }
157: }
158: }
159:
160: public int signature() {
161: return JPEGFileFormat.DQT;
162: }
163: }
|