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.ImageReadException; 028 029public class DqtSegment extends Segment { 030 public final List<QuantizationTable> quantizationTables = new ArrayList<>(); 031 032 public static class QuantizationTable { 033 public final int precision; 034 public final int destinationIdentifier; 035 private final int[] elements; 036 037 public QuantizationTable(final int precision, final int destinationIdentifier, 038 final int[] elements) { 039 this.precision = precision; 040 this.destinationIdentifier = destinationIdentifier; 041 this.elements = elements; 042 } 043 044 /** 045 * @return the elements 046 */ 047 public int[] getElements() { 048 return elements; 049 } 050 } 051 052 public DqtSegment(final int marker, final byte[] segmentData) 053 throws ImageReadException, IOException { 054 this(marker, segmentData.length, new ByteArrayInputStream(segmentData)); 055 } 056 057 public DqtSegment(final int marker, int length, final InputStream is) 058 throws ImageReadException, IOException { 059 super(marker, length); 060 061 while (length > 0) { 062 final int precisionAndDestination = readByte( 063 "QuantizationTablePrecisionAndDestination", is, 064 "Not a Valid JPEG File"); 065 length--; 066 final int precision = (precisionAndDestination >> 4) & 0xf; 067 final int destinationIdentifier = precisionAndDestination & 0xf; 068 069 final int[] elements = new int[64]; 070 for (int i = 0; i < 64; i++) { 071 if (precision == 0) { 072 elements[i] = 0xff & readByte("QuantizationTableElement", 073 is, "Not a Valid JPEG File"); 074 length--; 075 } else if (precision == 1) { 076 elements[i] = read2Bytes("QuantizationTableElement", is, "Not a Valid JPEG File", getByteOrder()); 077 length -= 2; 078 } else { 079 throw new ImageReadException( 080 "Quantization table precision '" + precision 081 + "' is invalid"); 082 } 083 } 084 085 quantizationTables.add(new QuantizationTable(precision, 086 destinationIdentifier, elements)); 087 } 088 } 089 090 @Override 091 public String getDescription() { 092 return "DQT (" + getSegmentType() + ")"; 093 } 094}