001/* 002 * Licensed under the Apache License, Version 2.0 (the "License"); 003 * you may not use this file except in compliance with the License. 004 * You may obtain a copy of the License at 005 * 006 * http://www.apache.org/licenses/LICENSE-2.0 007 * 008 * Unless required by applicable law or agreed to in writing, software 009 * distributed under the License is distributed on an "AS IS" BASIS, 010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 011 * See the License for the specific language governing permissions and 012 * limitations under the License. 013 * under the License. 014 */ 015 016package org.apache.commons.imaging.formats.jpeg.segments; 017 018import static org.apache.commons.imaging.common.BinaryFunctions.read2Bytes; 019import static org.apache.commons.imaging.common.BinaryFunctions.readByte; 020 021import java.io.ByteArrayInputStream; 022import java.io.IOException; 023import java.io.InputStream; 024import java.util.ArrayList; 025import java.util.List; 026 027import org.apache.commons.imaging.ImagingException; 028 029public class DqtSegment extends AbstractSegment { 030 public static class QuantizationTable { 031 public final int precision; 032 public final int destinationIdentifier; 033 private final int[] elements; 034 035 public QuantizationTable(final int precision, final int destinationIdentifier, final int[] elements) { 036 this.precision = precision; 037 this.destinationIdentifier = destinationIdentifier; 038 this.elements = elements; 039 } 040 041 /** 042 * @return the elements 043 */ 044 public int[] getElements() { 045 return elements; 046 } 047 } 048 049 public final List<QuantizationTable> quantizationTables = new ArrayList<>(); 050 051 public DqtSegment(final int marker, final byte[] segmentData) throws ImagingException, IOException { 052 this(marker, segmentData.length, new ByteArrayInputStream(segmentData)); 053 } 054 055 public DqtSegment(final int marker, int length, final InputStream is) throws ImagingException, IOException { 056 super(marker, length); 057 058 while (length > 0) { 059 final int precisionAndDestination = readByte("QuantizationTablePrecisionAndDestination", is, "Not a Valid JPEG File"); 060 length--; 061 final int precision = precisionAndDestination >> 4 & 0xf; 062 final int destinationIdentifier = precisionAndDestination & 0xf; 063 064 final int[] elements = new int[64]; 065 for (int i = 0; i < 64; i++) { 066 if (precision == 0) { 067 elements[i] = 0xff & readByte("QuantizationTableElement", is, "Not a Valid JPEG File"); 068 length--; 069 } else if (precision == 1) { 070 elements[i] = read2Bytes("QuantizationTableElement", is, "Not a Valid JPEG File", getByteOrder()); 071 length -= 2; 072 } else { 073 throw new ImagingException("Quantization table precision '" + precision + "' is invalid"); 074 } 075 } 076 077 quantizationTables.add(new QuantizationTable(precision, destinationIdentifier, elements)); 078 } 079 } 080 081 @Override 082 public String getDescription() { 083 return "DQT (" + getSegmentType() + ")"; 084 } 085}