001/* ***** BEGIN LICENSE BLOCK ***** 002 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 003 * 004 * The contents of this file are subject to the Mozilla Public License Version 005 * 1.1 (the "License"); you may not use this file except in compliance with 006 * the License. You may obtain a copy of the License at 007 * http://www.mozilla.org/MPL/ 008 * 009 * Software distributed under the License is distributed on an "AS IS" basis, 010 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 011 * for the specific language governing rights and limitations under the 012 * License. 013 * 014 * The Original Code is part of dcm4che, an implementation of DICOM(TM) in 015 * Java(TM), hosted at https://github.com/gunterze/dcm4che. 016 * 017 * The Initial Developer of the Original Code is 018 * Agfa Healthcare. 019 * Portions created by the Initial Developer are Copyright (C) 2013 020 * the Initial Developer. All Rights Reserved. 021 * 022 * Contributor(s): 023 * See @authors listed below 024 * 025 * Alternatively, the contents of this file may be used under the terms of 026 * either the GNU General Public License Version 2 or later (the "GPL"), or 027 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 028 * in which case the provisions of the GPL or the LGPL are applicable instead 029 * of those above. If you wish to allow use of your version of this file only 030 * under the terms of either the GPL or the LGPL, and not to allow others to 031 * use your version of this file under the terms of the MPL, indicate your 032 * decision by deleting the provisions above and replace them with the notice 033 * and other provisions required by the GPL or the LGPL. If you do not delete 034 * the provisions above, a recipient may use your version of this file under 035 * the terms of any one of the MPL, the GPL or the LGPL. 036 * 037 * ***** END LICENSE BLOCK ***** */ 038 039package org.dcm4che3.imageio.codec.jpeg; 040 041import org.dcm4che3.util.ByteUtils; 042 043/** 044 * @author Gunter Zeilinger <gunterze@gmail.com> 045 * 046 */ 047public class SOFSegment { 048 049 private final byte[] data; 050 private final int offset; 051 private final int numComponents; 052 053 public SOFSegment(byte[] data, int offset) { 054 this.data = data; 055 this.offset = offset; 056 this.numComponents = data[offset+8] & 255; 057 getQTableSelector(numComponents-1); 058 } 059 060 public int offset() { 061 return offset; 062 } 063 064 public int getMarker() { 065 return data[offset] & 255; 066 } 067 068 public int getHeaderLength() { 069 return ByteUtils.bytesToUShortBE(data, offset+1); 070 } 071 072 public int getPrecision() { 073 return data[offset+3] & 255; 074 } 075 076 public int getY() { 077 return ByteUtils.bytesToUShortBE(data, offset+4); 078 } 079 080 public int getX() { 081 return ByteUtils.bytesToUShortBE(data, offset+6); 082 } 083 084 public int getNumComponents() { 085 return numComponents; 086 } 087 088 public int getComponentID(int index) { 089 return data[offset+9+index*3] & 255; 090 } 091 092 public int getXSubsampling(int index) { 093 return (data[offset+10+index*3]>>4) & 15; 094 } 095 096 public int getYSubsampling(int index) { 097 return (data[offset+10+index*3]) & 15; 098 } 099 100 public int getQTableSelector(int index) { 101 return data[offset+11+index*3] & 255; 102 } 103 104 @Override 105 public String toString() { 106 StringBuilder sb = new StringBuilder(); 107 sb.append("SOF").append(getMarker()-0xC0) 108 .append("[Lf=").append(getHeaderLength()) 109 .append(", P=").append(getPrecision()) 110 .append(", Y=").append(getY()) 111 .append(", X=").append(getX()) 112 .append(", Nf=").append(numComponents); 113 for (int i = 0; i < numComponents; i++) { 114 sb.append(", C").append(i+1).append('=').append(getComponentID(i)) 115 .append(", H").append(i+1).append('=').append(getXSubsampling(i)) 116 .append(", V").append(i+1).append('=').append(getYSubsampling(i)) 117 .append(", Tq").append(i+1).append('=').append(getQTableSelector(i)); 118 } 119 sb.append(']'); 120 return sb.toString(); 121 } 122}