001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.imaging.formats.jpeg.segments; 018 019import static org.apache.commons.imaging.common.BinaryFunctions.read2Bytes; 020import static org.apache.commons.imaging.common.BinaryFunctions.readByte; 021 022import java.io.ByteArrayInputStream; 023import java.io.IOException; 024import java.io.InputStream; 025import java.util.logging.Level; 026import java.util.logging.Logger; 027 028import org.apache.commons.imaging.formats.jpeg.JpegConstants; 029 030public class SofnSegment extends Segment { 031 032 private static final Logger LOGGER = Logger.getLogger(SofnSegment.class.getName()); 033 034 public final int width; 035 public final int height; 036 public final int numberOfComponents; 037 public final int precision; 038 private final Component[] components; 039 040 public static class Component { 041 public final int componentIdentifier; 042 public final int horizontalSamplingFactor; 043 public final int verticalSamplingFactor; 044 public final int quantTabDestSelector; 045 046 public Component(final int componentIdentifier, final int horizontalSamplingFactor, 047 final int veritcalSamplingFactor, final int quantTabDestSelector) { 048 this.componentIdentifier = componentIdentifier; 049 this.horizontalSamplingFactor = horizontalSamplingFactor; 050 this.verticalSamplingFactor = veritcalSamplingFactor; 051 this.quantTabDestSelector = quantTabDestSelector; 052 } 053 } 054 055 public SofnSegment(final int marker, final byte[] segmentData) throws IOException { 056 this(marker, segmentData.length, new ByteArrayInputStream(segmentData)); 057 } 058 059 public SofnSegment(final int marker, final int markerLength, final InputStream is) 060 throws IOException { 061 super(marker, markerLength); 062 063 if (LOGGER.isLoggable(Level.FINEST)) { 064 LOGGER.finest("SOF0Segment marker_length: " + markerLength); 065 } 066 067 precision = readByte("Data_precision", is, "Not a Valid JPEG File"); 068 height = read2Bytes("Image_height", is, "Not a Valid JPEG File", getByteOrder()); 069 width = read2Bytes("Image_Width", is, "Not a Valid JPEG File", getByteOrder()); 070 numberOfComponents = readByte("Number_of_components", is, 071 "Not a Valid JPEG File"); 072 components = new Component[numberOfComponents]; 073 for (int i = 0; i < numberOfComponents; i++) { 074 final int componentIdentifier = readByte("ComponentIdentifier", is, 075 "Not a Valid JPEG File"); 076 077 final int hvSamplingFactors = readByte("SamplingFactors", is, 078 "Not a Valid JPEG File"); 079 final int horizontalSamplingFactor = (hvSamplingFactors >> 4) & 0xf; 080 final int verticalSamplingFactor = hvSamplingFactors & 0xf; 081 final int quantTabDestSelector = readByte("QuantTabDestSel", is, 082 "Not a Valid JPEG File"); 083 components[i] = new Component(componentIdentifier, 084 horizontalSamplingFactor, verticalSamplingFactor, 085 quantTabDestSelector); 086 } 087 } 088 089 /** 090 * Returns a copy of all the components. 091 * @return the components 092 */ 093 public Component[] getComponents() { 094 return components.clone(); 095 } 096 097 /** 098 * Returns the component at the specified index. 099 * @param index the array index 100 * @return the component 101 */ 102 public Component getComponents(final int index) { 103 return components[index]; 104 } 105 106 107 @Override 108 public String getDescription() { 109 return "SOFN (SOF" + (marker - JpegConstants.SOF0_MARKER) + ") (" 110 + getSegmentType() + ")"; 111 } 112 113}