1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.imaging.formats.jpeg.segments;
18
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.logging.Level;
25 import java.util.logging.Logger;
26
27 import org.apache.commons.imaging.common.Allocator;
28
29 public class SosSegment extends AbstractSegment {
30
31 public static class Component {
32 static final int SHALLOW_SIZE = 24;
33 public final int scanComponentSelector;
34 public final int dcCodingTableSelector;
35 public final int acCodingTableSelector;
36
37 public Component(final int scanComponentSelector, final int dcCodingTableSelector, final int acCodingTableSelector) {
38 this.scanComponentSelector = scanComponentSelector;
39 this.dcCodingTableSelector = dcCodingTableSelector;
40 this.acCodingTableSelector = acCodingTableSelector;
41 }
42 }
43
44 private static final Logger LOGGER = Logger.getLogger(SosSegment.class.getName());
45 public final int numberOfComponents;
46 private final Component[] components;
47 public final int startOfSpectralSelection;
48 public final int endOfSpectralSelection;
49 public final int successiveApproximationBitHigh;
50
51 public final int successiveApproximationBitLow;
52
53 public SosSegment(final int marker, final byte[] segmentData) throws IOException {
54 this(marker, segmentData.length, new ByteArrayInputStream(segmentData));
55 }
56
57 public SosSegment(final int marker, final int markerLength, final InputStream is) throws IOException {
58 super(marker, markerLength);
59
60 if (LOGGER.isLoggable(Level.FINEST)) {
61 LOGGER.finest("SosSegment markerLength: " + markerLength);
62 }
63
64
65
66 numberOfComponents = readByte("numberOfComponents", is, "Not a Valid JPEG File");
67
68
69
70 components = Allocator.array(numberOfComponents, Component[]::new, Component.SHALLOW_SIZE);
71 for (int i = 0; i < numberOfComponents; i++) {
72 final int scanComponentSelector = readByte("scanComponentSelector", is, "Not a Valid JPEG File");
73
74
75 final int acDcEntropyCodingTableSelector = readByte("acDcEntropyCodingTableSelector", is, "Not a Valid JPEG File");
76
77
78
79 final int dcCodingTableSelector = acDcEntropyCodingTableSelector >> 4 & 0xf;
80 final int acCodingTableSelector = acDcEntropyCodingTableSelector & 0xf;
81 components[i] = new Component(scanComponentSelector, dcCodingTableSelector, acCodingTableSelector);
82 }
83
84 startOfSpectralSelection = readByte("startOfSpectralSelection", is, "Not a Valid JPEG File");
85
86 endOfSpectralSelection = readByte("endOfSpectralSelection", is, "Not a Valid JPEG File");
87
88 final int successiveApproximationBitPosition = readByte("successiveApproximationBitPosition", is, "Not a Valid JPEG File");
89
90
91 successiveApproximationBitHigh = successiveApproximationBitPosition >> 4 & 0xf;
92 successiveApproximationBitLow = successiveApproximationBitPosition & 0xf;
93 }
94
95
96
97
98
99
100 public Component[] getComponents() {
101 return components.clone();
102 }
103
104
105
106
107
108
109
110 public Component getComponents(final int index) {
111 return components[index];
112 }
113
114 @Override
115 public String getDescription() {
116 return "SOS (" + getSegmentType() + ")";
117 }
118
119 }