blob: 35f1e2394aaadea812de1e69f748f6e3525f2620 [file] [log] [blame]
/*
* 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.imaging.icc;
import java.awt.color.ICC_Profile;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.imaging.common.BinaryFileParser;
import org.apache.commons.imaging.common.bytesource.ByteSource;
import org.apache.commons.imaging.common.bytesource.ByteSourceArray;
import org.apache.commons.imaging.common.bytesource.ByteSourceFile;
import org.apache.commons.imaging.util.CachingInputStream;
import org.apache.commons.imaging.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;
}
}