View Javadoc
1   /*
2    *  Licensed under the Apache License, Version 2.0 (the "License");
3    *  you may not use this file except in compliance with the License.
4    *  You may obtain a copy of the License at
5    *
6    *       http://www.apache.org/licenses/LICENSE-2.0
7    *
8    *  Unless required by applicable law or agreed to in writing, software
9    *  distributed under the License is distributed on an "AS IS" BASIS,
10   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11   *  See the License for the specific language governing permissions and
12   *  limitations under the License.
13   *  under the License.
14   */
15  
16  package org.apache.commons.imaging.formats.jpeg.segments;
17  
18  import static org.apache.commons.imaging.common.BinaryFunctions.read2Bytes;
19  import static org.apache.commons.imaging.common.BinaryFunctions.readByte;
20  
21  import java.io.ByteArrayInputStream;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.util.ArrayList;
25  import java.util.List;
26  
27  import org.apache.commons.imaging.ImagingException;
28  
29  public class DqtSegment extends AbstractSegment {
30      public static class QuantizationTable {
31          public final int precision;
32          public final int destinationIdentifier;
33          private final int[] elements;
34  
35          public QuantizationTable(final int precision, final int destinationIdentifier, final int[] elements) {
36              this.precision = precision;
37              this.destinationIdentifier = destinationIdentifier;
38              this.elements = elements;
39          }
40  
41          /**
42           * @return the elements
43           */
44          public int[] getElements() {
45              return elements;
46          }
47      }
48  
49      public final List<QuantizationTable> quantizationTables = new ArrayList<>();
50  
51      public DqtSegment(final int marker, final byte[] segmentData) throws ImagingException, IOException {
52          this(marker, segmentData.length, new ByteArrayInputStream(segmentData));
53      }
54  
55      public DqtSegment(final int marker, int length, final InputStream is) throws ImagingException, IOException {
56          super(marker, length);
57  
58          while (length > 0) {
59              final int precisionAndDestination = readByte("QuantizationTablePrecisionAndDestination", is, "Not a Valid JPEG File");
60              length--;
61              final int precision = precisionAndDestination >> 4 & 0xf;
62              final int destinationIdentifier = precisionAndDestination & 0xf;
63  
64              final int[] elements = new int[64];
65              for (int i = 0; i < 64; i++) {
66                  if (precision == 0) {
67                      elements[i] = 0xff & readByte("QuantizationTableElement", is, "Not a Valid JPEG File");
68                      length--;
69                  } else if (precision == 1) {
70                      elements[i] = read2Bytes("QuantizationTableElement", is, "Not a Valid JPEG File", getByteOrder());
71                      length -= 2;
72                  } else {
73                      throw new ImagingException("Quantization table precision '" + precision + "' is invalid");
74                  }
75              }
76  
77              quantizationTables.add(new QuantizationTable(precision, destinationIdentifier, elements));
78          }
79      }
80  
81      @Override
82      public String getDescription() {
83          return "DQT (" + getSegmentType() + ")";
84      }
85  }