| /******************************************************************************* |
| * Copyright (c) 2000, 2004 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.swt.internal.image; |
| |
| |
| import org.eclipse.swt.*; |
| |
| final class JPEGFrameHeader extends JPEGVariableSizeSegment { |
| int maxVFactor; |
| int maxHFactor; |
| public int[] componentIdentifiers; |
| public int[][] componentParameters; |
| |
| public JPEGFrameHeader(byte[] reference) { |
| super(reference); |
| } |
| |
| public JPEGFrameHeader(LEDataInputStream byteStream) { |
| super(byteStream); |
| initializeComponentParameters(); |
| } |
| |
| public int getSamplePrecision() { |
| return reference[4] & 0xFF; |
| } |
| |
| public int getNumberOfLines() { |
| return (reference[5] & 0xFF) << 8 | (reference[6] & 0xFF); |
| } |
| |
| public int getSamplesPerLine() { |
| return (reference[7] & 0xFF) << 8 | (reference[8] & 0xFF); |
| } |
| |
| public int getNumberOfImageComponents() { |
| return reference[9] & 0xFF; |
| } |
| |
| public void setSamplePrecision(int precision) { |
| reference[4] = (byte)(precision & 0xFF); |
| } |
| |
| public void setNumberOfLines(int anInteger) { |
| reference[5] = (byte)((anInteger & 0xFF00) >> 8); |
| reference[6] = (byte)(anInteger & 0xFF); |
| } |
| |
| public void setSamplesPerLine(int samples) { |
| reference[7] = (byte)((samples & 0xFF00) >> 8); |
| reference[8] = (byte)(samples & 0xFF); |
| } |
| |
| public void setNumberOfImageComponents(int anInteger) { |
| reference[9] = (byte)(anInteger & 0xFF); |
| } |
| |
| public int getMaxHFactor() { |
| return maxHFactor; |
| } |
| |
| public int getMaxVFactor() { |
| return maxVFactor; |
| } |
| |
| public void setMaxHFactor(int anInteger) { |
| maxHFactor = anInteger; |
| } |
| |
| public void setMaxVFactor(int anInteger) { |
| maxVFactor = anInteger; |
| } |
| |
| /* Used when decoding. */ |
| void initializeComponentParameters() { |
| int nf = getNumberOfImageComponents(); |
| componentIdentifiers = new int[nf]; |
| int[][] compSpecParams = new int[0][]; |
| int hmax = 1; |
| int vmax = 1; |
| for (int i = 0; i < nf; i++) { |
| int ofs = i * 3 + 10; |
| int ci = reference[ofs] & 0xFF; |
| componentIdentifiers[i] = ci; |
| int hi = (reference[ofs + 1] & 0xFF) / 16; |
| int vi = (reference[ofs + 1] & 0xFF) % 16; |
| int tqi = reference[ofs + 2] & 0xFF; |
| if (hi > hmax) { |
| hmax = hi; |
| } |
| if (vi > vmax) { |
| vmax = vi; |
| } |
| int[] compParam = new int[5]; |
| compParam[0] = tqi; |
| compParam[1] = hi; |
| compParam[2] = vi; |
| if (compSpecParams.length <= ci) { |
| int[][] newParams = new int[ci + 1][]; |
| System.arraycopy(compSpecParams, 0, newParams, 0, compSpecParams.length); |
| compSpecParams = newParams; |
| } |
| compSpecParams[ci] = compParam; |
| } |
| int x = getSamplesPerLine(); |
| int y = getNumberOfLines(); |
| int[] multiples = new int[] { 8, 16, 24, 32 }; |
| for (int i = 0; i < nf; i++) { |
| int[] compParam = compSpecParams[componentIdentifiers[i]]; |
| int hi = compParam[1]; |
| int vi = compParam[2]; |
| int compWidth = (x * hi + hmax - 1) / hmax; |
| int compHeight = (y * vi + vmax - 1) / vmax; |
| int dsWidth = roundUpToMultiple(compWidth, multiples[hi - 1]); |
| int dsHeight = roundUpToMultiple(compHeight, multiples[vi - 1]); |
| compParam[3] = dsWidth; |
| compParam[4] = dsHeight; |
| } |
| setMaxHFactor(hmax); |
| setMaxVFactor(vmax); |
| componentParameters = compSpecParams; |
| } |
| |
| /* Used when encoding. */ |
| public void initializeContents() { |
| int nf = getNumberOfImageComponents(); |
| if (nf == 0 || nf != componentParameters.length) { |
| SWT.error(SWT.ERROR_INVALID_IMAGE); |
| } |
| int hmax = 0; |
| int vmax = 0; |
| int[][] compSpecParams = componentParameters; |
| for (int i = 0; i < nf; i++) { |
| int ofs = i * 3 + 10; |
| int[] compParam = compSpecParams[componentIdentifiers[i]]; |
| int hi = compParam[1]; |
| int vi = compParam[2]; |
| if (hi * vi > 4) { |
| SWT.error(SWT.ERROR_INVALID_IMAGE); |
| } |
| reference[ofs] = (byte)(i + 1); |
| reference[ofs + 1] = (byte)(hi * 16 + vi); |
| reference[ofs + 2] = (byte)(compParam[0]); |
| if (hi > hmax) hmax = hi; |
| if (vi > vmax) vmax = vi; |
| } |
| int x = getSamplesPerLine(); |
| int y = getNumberOfLines(); |
| int[] multiples = new int[] {8, 16, 24, 32}; |
| for (int i = 0; i < nf; i++) { |
| int[] compParam = compSpecParams[componentIdentifiers[i]]; |
| int hi = compParam[1]; |
| int vi = compParam[2]; |
| int compWidth = (x * hi + hmax - 1) / hmax; |
| int compHeight = (y * vi + vmax - 1) / vmax; |
| int dsWidth = roundUpToMultiple(compWidth, multiples[hi - 1]); |
| int dsHeight = roundUpToMultiple(compHeight, multiples[vi - 1]); |
| compParam[3] = dsWidth; |
| compParam[4] = dsHeight; |
| } |
| setMaxHFactor(hmax); |
| setMaxVFactor(vmax); |
| } |
| |
| int roundUpToMultiple(int anInteger, int mInteger) { |
| int a = anInteger + mInteger - 1; |
| return a - (a % mInteger); |
| } |
| |
| /* |
| * Verify the information contained in the receiver is correct. |
| * Answer true if the header contains a valid marker. Otherwise, |
| * answer false. Valid Start Of Frame markers are: |
| * SOF_0 - Baseline DCT, Huffman coding |
| * SOF_1 - Extended sequential DCT, Huffman coding |
| * SOF_2 - Progressive DCT, Huffman coding |
| * SOF_3 - Lossless (sequential), Huffman coding |
| * SOF_5 - Differential sequential, Huffman coding |
| * SOF_6 - Differential progressive, Huffman coding |
| * SOF_7 - Differential lossless, Huffman coding |
| * SOF_9 - Extended sequential DCT, arithmetic coding |
| * SOF_10 - Progressive DCT, arithmetic coding |
| * SOF_11 - Lossless (sequential), arithmetic coding |
| * SOF_13 - Differential sequential, arithmetic coding |
| * SOF_14 - Differential progressive, arithmetic coding |
| * SOF_15 - Differential lossless, arithmetic coding |
| */ |
| public boolean verify() { |
| int marker = getSegmentMarker(); |
| return (marker >= JPEGFileFormat.SOF0 && marker <= JPEGFileFormat.SOF3) || |
| (marker >= JPEGFileFormat.SOF5 && marker <= JPEGFileFormat.SOF7) || |
| (marker >= JPEGFileFormat.SOF9 && marker <= JPEGFileFormat.SOF11) || |
| (marker >= JPEGFileFormat.SOF13 && marker <= JPEGFileFormat.SOF15); |
| } |
| |
| public boolean isProgressive() { |
| int marker = getSegmentMarker(); |
| return marker == JPEGFileFormat.SOF2 |
| || marker == JPEGFileFormat.SOF6 |
| || marker == JPEGFileFormat.SOF10 |
| || marker == JPEGFileFormat.SOF14; |
| } |
| |
| public boolean isArithmeticCoding() { |
| return getSegmentMarker() >= JPEGFileFormat.SOF9; |
| } |
| } |