1:
37:
38: package ;
39:
40: import ;
41: import ;
42: import ;
43:
44: import ;
45:
46:
50: public class JPEGComponent
51: {
52: public byte factorH, factorV, component_id, quant_id;
53: public int width = 0, height = 0, maxV = 0, maxH = 0;
54: public HuffmanTable ACTable;
55: public HuffmanTable DCTable;
56: public int[] quantizationTable;
57: public double previousDC = 0;
58: ArrayList data = new ArrayList();
59:
60:
68: public JPEGComponent(byte id, byte factorHorizontal, byte factorVertical,
69: byte quantizationID)
70: {
71: component_id = id;
72: factorH = factorHorizontal;
73: factorV = factorVertical;
74: quant_id = quantizationID;
75: }
76:
77:
85: public void padMCU(int index, int length)
86: {
87: double[] src = (double[]) data.get(index - 1);
88: for (int i = 0; i < length; i++)
89: data.add(index, src);
90: }
91:
92:
95: public void resetInterval()
96: {
97: previousDC = 0;
98: }
99:
100:
103: public void quantitizeData()
104: {
105: for (int i = 0; i < data.size(); i++)
106: {
107: double[] mydata = (double[]) data.get(i);
108: for (int j = 0; j < mydata.length; j++)
109: mydata[j] *= quantizationTable[j];
110: }
111: }
112:
113: public void setDCTable(JPEGHuffmanTable table)
114: {
115: DCTable = new HuffmanTable(table);
116: }
117:
118: public void setACTable(JPEGHuffmanTable table)
119: {
120: ACTable = new HuffmanTable(table);
121: }
122:
123:
126: public void idctData(DCT myDCT)
127: {
128: for (int i = 0; i < data.size(); i++)
129: data.add(i,myDCT.fast_idct(ZigZag.decode8x8_map((double[]) data.remove(i))));
130: }
131:
132:
137: public void scaleByFactors()
138: {
139: int factorUpVertical = maxV / factorV;
140: int factorUpHorizontal = maxH / factorH;
141:
142: if (factorUpVertical > 1)
143: {
144: for (int i = 0; i < data.size(); i++)
145: {
146: double[][] src = (double[][]) data.remove(i);
147: double[][] dest =
148: new double[src.length * factorUpVertical][src[0].length];
149: for (int j = 0; j < src.length; j++)
150: {
151: for (int u = 0; u < factorUpVertical; u++)
152: {
153: dest[j * factorUpVertical + u] = src[j];
154: }
155: }
156: data.add(i, dest);
157: }
158: }
159:
160: if (factorUpHorizontal > 1)
161: {
162: for (int i = 0; i < data.size(); i++)
163: {
164: double[][] src = (double[][]) data.remove(i);
165: double[][] dest =
166: new double[src.length][src[0].length * factorUpHorizontal];
167: for (int j = 0; j < src.length; j++)
168: {
169: for (int u = 0; u < src[0].length; u++)
170: {
171: for (int v = 0; v < factorUpHorizontal; v++)
172: dest[j][u * factorUpHorizontal + v] = src[j][u];
173: }
174: }
175: data.add(i, dest);
176: }
177: }
178: }
179:
180:
190: public void writeBlock(WritableRaster raster, double[][] data,
191: int compIndex, int x, int y)
192: {
193: for (int yIndex = 0; yIndex < data.length; yIndex++)
194: {
195: for (int xIndex = 0; xIndex < data[yIndex].length; xIndex++)
196: {
197:
198:
199:
200: if (x + xIndex < raster.getWidth()
201: && y + yIndex < raster.getHeight())
202: raster.setSample(x + xIndex, y + yIndex, compIndex,
203: data[yIndex][xIndex]);
204: }
205: }
206: }
207:
208:
217: public void writeData(WritableRaster raster, int componentIndex)
218: {
219: int x = 0, y = 0, lastblockheight = 0, incrementblock = 0;
220:
221:
222: while(data.size() > 0)
223: {
224: int blockwidth = 0;
225: int blockheight = 0;
226:
227: if (x >= raster.getWidth())
228: {
229: x = 0;
230: y += incrementblock;
231: }
232:
233:
234:
235:
236: for (int factorVIndex = 0; factorVIndex < factorV; factorVIndex++)
237: {
238: blockwidth = 0;
239:
240: for (int factorHIndex = 0; factorHIndex < factorH; factorHIndex++)
241: {
242:
243:
244: double[][] blockdata = (double[][]) data.remove(0);
245:
246:
247:
248: writeBlock(raster, blockdata, componentIndex, x, y);
249: blockwidth += blockdata[0].length;
250: x += blockdata[0].length;
251: blockheight = blockdata.length;
252: }
253: y += blockheight;
254: x -= blockwidth;
255: lastblockheight += blockheight;
256: }
257: y -= lastblockheight;
258: incrementblock = lastblockheight;
259: lastblockheight = 0;
260: x += blockwidth;
261: }
262: }
263:
264:
269: public void setQuantizationTable(int[] quanttable)
270: {
271: quantizationTable = quanttable;
272: }
273:
274:
281: public void readComponentMCU(JPEGImageInputStream stream)
282: throws JPEGException, IOException
283: {
284: for (int i = 0; i < factorH * factorV; i++)
285: {
286: double dc = decode_dc_coefficient(stream);
287: double[] datablock = decode_ac_coefficients(stream);
288: datablock[0] = dc;
289: data.add(datablock);
290: }
291: }
292:
293:
303: public double decode_dc_coefficient(JPEGImageInputStream JPEGStream)
304: throws JPEGException, IOException
305: {
306: int t = DCTable.decode(JPEGStream);
307: double diff = JPEGStream.readBits(t);
308: diff = HuffmanTable.extend((int) diff, t);
309: diff = (previousDC + diff);
310: previousDC = diff;
311: return diff;
312: }
313:
314:
324: public double[] decode_ac_coefficients(JPEGImageInputStream JPEGStream)
325: throws JPEGException, IOException
326: {
327: double[] zz = new double[64];
328:
329: for (int k = 1; k < 64; k++)
330: {
331: int s = ACTable.decode(JPEGStream);
332: int r = s >> 4;
333: s &= 15;
334:
335: if (s != 0)
336: {
337: k += r;
338: r = (int) JPEGStream.readBits(s);
339: s = HuffmanTable.extend(r, s);
340: zz[k] = s;
341: }
342: else
343: {
344: if (r != 15)
345: return (zz);
346: k += 15;
347: }
348: }
349: return zz;
350: }
351: }