| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.commons.sanselan.icc; |
| |
| import java.awt.color.ICC_Profile; |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| |
| import org.apache.commons.sanselan.common.BinaryFileParser; |
| import org.apache.commons.sanselan.common.bytesource.ByteSource; |
| import org.apache.commons.sanselan.common.bytesource.ByteSourceArray; |
| import org.apache.commons.sanselan.common.bytesource.ByteSourceFile; |
| import org.apache.commons.sanselan.util.CachingInputStream; |
| import org.apache.commons.sanselan.util.Debug; |
| |
| public class IccProfileParser extends BinaryFileParser implements IccConstants |
| { |
| public IccProfileParser() |
| { |
| this.setByteOrder(BYTE_ORDER_NETWORK); |
| } |
| |
| public IccProfileInfo getICCProfileInfo(ICC_Profile icc_profile) |
| { |
| if (icc_profile == null) |
| return null; |
| |
| return getICCProfileInfo(new ByteSourceArray(icc_profile.getData())); |
| } |
| |
| public IccProfileInfo getICCProfileInfo(byte bytes[]) |
| { |
| if (bytes == null) |
| return null; |
| |
| return getICCProfileInfo(new ByteSourceArray(bytes)); |
| } |
| |
| public IccProfileInfo getICCProfileInfo(File file) |
| { |
| if (file == null) |
| return null; |
| |
| return getICCProfileInfo(new ByteSourceFile(file)); |
| } |
| |
| public IccProfileInfo getICCProfileInfo(ByteSource byteSource) |
| { |
| |
| InputStream is = null; |
| |
| try |
| { |
| |
| IccProfileInfo result; |
| { |
| is = byteSource.getInputStream(); |
| |
| result = readICCProfileInfo(is); |
| } |
| |
| if (result == null) |
| return null; |
| |
| is.close(); |
| is = null; |
| |
| for (int i = 0; i < result.tags.length; i++) |
| { |
| IccTag tag = result.tags[i]; |
| byte bytes[] = byteSource.getBlock(tag.offset, tag.length); |
| // Debug.debug("bytes: " + bytes.length); |
| tag.setData(bytes); |
| // tag.dump("\t" + i + ": "); |
| } |
| // result.fillInTagData(byteSource); |
| |
| return result; |
| } |
| catch (Exception e) |
| { |
| // Debug.debug("Error: " + file.getAbsolutePath()); |
| Debug.debug(e); |
| } |
| finally |
| { |
| try |
| { |
| if (is != null) |
| is.close(); |
| } |
| catch (Exception e) |
| { |
| Debug.debug(e); |
| } |
| |
| } |
| |
| if (debug) |
| Debug.debug(); |
| |
| return null; |
| } |
| |
| private IccProfileInfo readICCProfileInfo(InputStream is) |
| { |
| CachingInputStream cis = new CachingInputStream(is); |
| is = cis; |
| |
| if (debug) |
| Debug.debug(); |
| |
| // setDebug(true); |
| |
| // if (debug) |
| // Debug.debug("length: " + length); |
| |
| try |
| { |
| int ProfileSize = read4Bytes("ProfileSize", is, |
| "Not a Valid ICC Profile"); |
| |
| // if (length != ProfileSize) |
| // { |
| // // Debug.debug("Unexpected Length data expected: " + Integer.toHexString((int) length) |
| // // + ", encoded: " + Integer.toHexString(ProfileSize)); |
| // // Debug.debug("Unexpected Length data: " + length |
| // // + ", length: " + ProfileSize); |
| // // throw new Error("asd"); |
| // return null; |
| // } |
| |
| int CMMTypeSignature = read4Bytes("Signature", is, |
| "Not a Valid ICC Profile"); |
| if (debug) |
| printCharQuad("CMMTypeSignature", CMMTypeSignature); |
| |
| int ProfileVersion = read4Bytes("ProfileVersion", is, |
| "Not a Valid ICC Profile"); |
| |
| int ProfileDeviceClassSignature = read4Bytes( |
| "ProfileDeviceClassSignature", is, |
| "Not a Valid ICC Profile"); |
| if (debug) |
| printCharQuad("ProfileDeviceClassSignature", |
| ProfileDeviceClassSignature); |
| |
| int ColorSpace = read4Bytes("ColorSpace", is, |
| "Not a Valid ICC Profile"); |
| if (debug) |
| printCharQuad("ColorSpace", ColorSpace); |
| |
| int ProfileConnectionSpace = read4Bytes("ProfileConnectionSpace", |
| is, "Not a Valid ICC Profile"); |
| if (debug) |
| printCharQuad("ProfileConnectionSpace", ProfileConnectionSpace); |
| |
| skipBytes(is, 12, "Not a Valid ICC Profile"); |
| |
| int ProfileFileSignature = read4Bytes("ProfileFileSignature", is, |
| "Not a Valid ICC Profile"); |
| if (debug) |
| printCharQuad("ProfileFileSignature", ProfileFileSignature); |
| |
| int PrimaryPlatformSignature = read4Bytes( |
| "PrimaryPlatformSignature", is, "Not a Valid ICC Profile"); |
| if (debug) |
| printCharQuad("PrimaryPlatformSignature", |
| PrimaryPlatformSignature); |
| |
| int VariousFlags = read4Bytes("ProfileFileSignature", is, |
| "Not a Valid ICC Profile"); |
| if (debug) |
| printCharQuad("ProfileFileSignature", ProfileFileSignature); |
| |
| int DeviceManufacturer = read4Bytes("ProfileFileSignature", is, |
| "Not a Valid ICC Profile"); |
| if (debug) |
| printCharQuad("DeviceManufacturer", DeviceManufacturer); |
| |
| int DeviceModel = read4Bytes("DeviceModel", is, |
| "Not a Valid ICC Profile"); |
| if (debug) |
| printCharQuad("DeviceModel", DeviceModel); |
| |
| skipBytes(is, 8, "Not a Valid ICC Profile"); |
| |
| int RenderingIntent = read4Bytes("RenderingIntent", is, |
| "Not a Valid ICC Profile"); |
| if (debug) |
| printCharQuad("RenderingIntent", RenderingIntent); |
| |
| skipBytes(is, 12, "Not a Valid ICC Profile"); |
| |
| int ProfileCreatorSignature = read4Bytes("ProfileCreatorSignature", |
| is, "Not a Valid ICC Profile"); |
| if (debug) |
| printCharQuad("ProfileCreatorSignature", |
| ProfileCreatorSignature); |
| |
| byte ProfileID[] = null; |
| skipBytes(is, 16, "Not a Valid ICC Profile"); |
| // readByteArray("ProfileID", 16, is, |
| // "Not a Valid ICC Profile"); |
| // if (debug) |
| // System.out |
| // .println("ProfileID: '" + new String(ProfileID) + "'"); |
| |
| skipBytes(is, 28, "Not a Valid ICC Profile"); |
| |
| // this.setDebug(true); |
| |
| int TagCount = read4Bytes("TagCount", is, "Not a Valid ICC Profile"); |
| |
| // List tags = new ArrayList(); |
| IccTag tags[] = new IccTag[TagCount]; |
| |
| for (int i = 0; i < TagCount; i++) |
| { |
| int TagSignature = read4Bytes("TagSignature[" + i + "]", is, |
| "Not a Valid ICC Profile"); |
| // Debug.debug("TagSignature t " |
| // + Integer.toHexString(TagSignature)); |
| |
| // this.printCharQuad("TagSignature", TagSignature); |
| int OffsetToData = read4Bytes("OffsetToData[" + i + "]", is, |
| "Not a Valid ICC Profile"); |
| int ElementSize = read4Bytes("ElementSize[" + i + "]", is, |
| "Not a Valid ICC Profile"); |
| |
| IccTagType fIccTagType = getIccTagType(TagSignature); |
| // if (fIccTagType == null) |
| // throw new Error("oops."); |
| |
| // System.out |
| // .println("\t[" |
| // + i |
| // + "]: " |
| // + ((fIccTagType == null) |
| // ? "unknown" |
| // : fIccTagType.name)); |
| // Debug.debug(); |
| |
| IccTag tag = new IccTag(TagSignature, OffsetToData, |
| ElementSize, fIccTagType); |
| // tag.dump("\t" + i + ": "); |
| tags[i] = tag; |
| // tags .add(tag); |
| } |
| |
| { |
| // read stream to end, filling cache. |
| while (is.read() >= 0) |
| { /* do nothing */ } |
| } |
| |
| byte data[] = cis.getCache(); |
| |
| if (data.length < ProfileSize) |
| throw new IOException("Couldn't read ICC Profile."); |
| |
| IccProfileInfo result = new IccProfileInfo(data, ProfileSize, |
| CMMTypeSignature, ProfileVersion, |
| ProfileDeviceClassSignature, ColorSpace, |
| ProfileConnectionSpace, ProfileFileSignature, |
| PrimaryPlatformSignature, VariousFlags, DeviceManufacturer, |
| DeviceModel, RenderingIntent, ProfileCreatorSignature, |
| ProfileID, tags); |
| |
| if (debug) |
| Debug.debug("issRGB: " + result.issRGB()); |
| |
| return result; |
| } |
| catch (Exception e) |
| { |
| Debug.debug(e); |
| } |
| |
| return null; |
| } |
| |
| private IccTagType getIccTagType(int quad) |
| { |
| for (IccTagType iccTagType : IccTagTypes.values()) { |
| if (iccTagType.getSignature() == quad) { |
| return iccTagType; |
| } |
| } |
| |
| return null; |
| } |
| |
| public Boolean issRGB(ICC_Profile icc_profile) |
| { |
| if (icc_profile == null) |
| return null; |
| |
| return issRGB(new ByteSourceArray(icc_profile.getData())); |
| } |
| |
| public Boolean issRGB(byte bytes[]) |
| { |
| if (bytes == null) |
| return null; |
| |
| return issRGB(new ByteSourceArray(bytes)); |
| } |
| |
| public Boolean issRGB(File file) |
| { |
| if (file == null) |
| return null; |
| |
| return issRGB(new ByteSourceFile(file)); |
| } |
| |
| public Boolean issRGB(ByteSource byteSource) |
| { |
| try |
| { |
| if (debug) |
| Debug.debug(); |
| |
| // setDebug(true); |
| |
| // long length = byteSource.getLength(); |
| // |
| // if (debug) |
| // Debug.debug("length: " + length); |
| |
| InputStream is = null; |
| try { |
| is = byteSource.getInputStream(); |
| |
| int ProfileSize = read4Bytes("ProfileSize", is, |
| "Not a Valid ICC Profile"); |
| |
| // if (length != ProfileSize) |
| // return null; |
| |
| this.skipBytes(is, 4 * 5); |
| |
| skipBytes(is, 12, "Not a Valid ICC Profile"); |
| |
| this.skipBytes(is, 4 * 3); |
| |
| int DeviceManufacturer = read4Bytes("ProfileFileSignature", is, |
| "Not a Valid ICC Profile"); |
| if (debug) |
| printCharQuad("DeviceManufacturer", DeviceManufacturer); |
| |
| int DeviceModel = read4Bytes("DeviceModel", is, |
| "Not a Valid ICC Profile"); |
| if (debug) |
| printCharQuad("DeviceModel", DeviceModel); |
| |
| boolean result = ((DeviceManufacturer == IEC) && (DeviceModel == sRGB)); |
| |
| return result; |
| } finally { |
| if (is != null) { |
| try { |
| is.close(); |
| } catch (IOException ignore) { |
| } |
| } |
| } |
| } |
| catch (Exception e) |
| { |
| Debug.debug(e); |
| } |
| |
| return null; |
| } |
| |
| } |