// + SOF_segments.size());
final List<Segment> jfifSegments = readSegments(byteSource,
new int[] { JpegConstants.JFIF_MARKER, }, true);
final SofnSegment fSOFNSegment = (SofnSegment) SOF_segments.get(0);
// SofnSegment fSOFNSegment = (SofnSegment) findSegment(segments,
// SOFNmarkers);
if (fSOFNSegment == null) {
throw new ImageReadException("No SOFN Data Found.");
}
final int width = fSOFNSegment.width;
final int height = fSOFNSegment.height;
JfifSegment jfifSegment = null;
if ((jfifSegments != null) && (!jfifSegments.isEmpty())) {
jfifSegment = (JfifSegment) jfifSegments.get(0);
}
final List<Segment> app14Segments = readSegments(byteSource, new int[] { JpegConstants.JPEG_APP14_MARKER}, true);
App14Segment app14Segment = null;
if (app14Segments != null && !app14Segments.isEmpty()) {
app14Segment = (App14Segment) app14Segments.get(0);
}
// JfifSegment fTheJFIFSegment = (JfifSegment) findSegment(segments,
// kJFIFMarker);
double xDensity = -1.0;
double yDensity = -1.0;
double unitsPerInch = -1.0;
// int JFIF_major_version;
// int JFIF_minor_version;
String formatDetails;
if (jfifSegment != null) {
xDensity = jfifSegment.xDensity;
yDensity = jfifSegment.yDensity;
final int densityUnits = jfifSegment.densityUnits;
// JFIF_major_version = fTheJFIFSegment.JFIF_major_version;
// JFIF_minor_version = fTheJFIFSegment.JFIF_minor_version;
formatDetails = "Jpeg/JFIF v." + jfifSegment.jfifMajorVersion + "."
+ jfifSegment.jfifMinorVersion;
switch (densityUnits) {
case 0:
break;
case 1: // inches
unitsPerInch = 1.0;
break;
case 2: // cms
unitsPerInch = 2.54;
break;
default:
break;
}
} else {
final JpegImageMetadata metadata = (JpegImageMetadata) getMetadata(
byteSource, params);
if (metadata != null) {
{
final TiffField field = metadata
.findEXIFValue(TiffTagConstants.TIFF_TAG_XRESOLUTION);
if (field != null) {
xDensity = ((Number) field.getValue()).doubleValue();
}
}
{
final TiffField field = metadata
.findEXIFValue(TiffTagConstants.TIFF_TAG_YRESOLUTION);
if (field != null) {
yDensity = ((Number) field.getValue()).doubleValue();
}
}
{
final TiffField field = metadata
.findEXIFValue(TiffTagConstants.TIFF_TAG_RESOLUTION_UNIT);
if (field != null) {
final int densityUnits = ((Number) field.getValue()).intValue();
switch (densityUnits) {
case 1:
break;
case 2: // inches
unitsPerInch = 1.0;
break;
case 3: // cms
unitsPerInch = 2.54;
break;
default:
break;
}
}
}
}
formatDetails = "Jpeg/DCM";
}
int physicalHeightDpi = -1;
float physicalHeightInch = -1;
int physicalWidthDpi = -1;
float physicalWidthInch = -1;
if (unitsPerInch > 0) {
physicalWidthDpi = (int) Math.round(xDensity * unitsPerInch);
physicalWidthInch = (float) (width / (xDensity * unitsPerInch));
physicalHeightDpi = (int) Math.round(yDensity * unitsPerInch);
physicalHeightInch = (float) (height / (yDensity * unitsPerInch));
}
final List<String> comments = new ArrayList<String>();
final List<Segment> commentSegments = readSegments(byteSource,
new int[] { JpegConstants.COM_MARKER}, false);
for (Segment commentSegment : commentSegments) {
final ComSegment comSegment = (ComSegment) commentSegment;
String comment = "";
try {
comment = new String(comSegment.getComment(), "UTF-8");
} catch (final UnsupportedEncodingException cannotHappen) { // NOPMD - can't happen
}
comments.add(comment);
}
final int numberOfComponents = fSOFNSegment.numberOfComponents;
final int precision = fSOFNSegment.precision;
final int bitsPerPixel = numberOfComponents * precision;
final ImageFormat format = ImageFormats.JPEG;
final String formatName = "JPEG (Joint Photographic Experts Group) Format";
final String mimeType = "image/jpeg";
// we ought to count images, but don't yet.
final int numberOfImages = 1;
// not accurate ... only reflects first
final boolean progressive = fSOFNSegment.marker == JpegConstants.SOF2_MARKER;
boolean transparent = false;
final boolean usesPalette = false; // TODO: inaccurate.
// See http://docs.oracle.com/javase/6/docs/api/javax/imageio/metadata/doc-files/jpeg_metadata.html#color
int colorType = ImageInfo.COLOR_TYPE_UNKNOWN;
// Some images have both JFIF/APP0 and APP14.
// JFIF is meant to win but in them APP14 is clearly right, so make it win.
if (app14Segment != null && app14Segment.isAdobeJpegSegment()) {
final int colorTransform = app14Segment.getAdobeColorTransform();
if (colorTransform == App14Segment.ADOBE_COLOR_TRANSFORM_UNKNOWN) {
if (numberOfComponents == 3) {
colorType = ImageInfo.COLOR_TYPE_RGB;
} else if (numberOfComponents == 4) {
colorType = ImageInfo.COLOR_TYPE_CMYK;
}
} else if (colorTransform == App14Segment.ADOBE_COLOR_TRANSFORM_YCbCr) {
colorType = ImageInfo.COLOR_TYPE_YCbCr;
} else if (colorTransform == App14Segment.ADOBE_COLOR_TRANSFORM_YCCK) {
colorType = ImageInfo.COLOR_TYPE_YCCK;
}
} else if (jfifSegment != null) {
if (numberOfComponents == 1) {
colorType = ImageInfo.COLOR_TYPE_GRAYSCALE;
} else if (numberOfComponents == 3) {
colorType = ImageInfo.COLOR_TYPE_YCbCr;
}
} else {
if (numberOfComponents == 1) {
colorType = ImageInfo.COLOR_TYPE_GRAYSCALE;
} else if (numberOfComponents == 2) {
colorType = ImageInfo.COLOR_TYPE_GRAYSCALE;
transparent = true;
} else if (numberOfComponents == 3 || numberOfComponents == 4) {
boolean have1 = false;
boolean have2 = false;
boolean have3 = false;
boolean have4 = false;
boolean haveOther = false;
for (final SofnSegment.Component component : fSOFNSegment.getComponents()) {
final int id = component.componentIdentifier;
if (id == 1) {
have1 = true;
} else if (id == 2) {
have2 = true;
} else if (id == 3) {
have3 = true;
} else if (id == 4) {
have4 = true;
} else {
haveOther = true;
}
}
if (numberOfComponents == 3 && have1 && have2 && have3 && !have4 && !haveOther) {
colorType = ImageInfo.COLOR_TYPE_YCbCr;
} else if (numberOfComponents == 4 && have1 && have2 && have3 && have4 && !haveOther) {
colorType = ImageInfo.COLOR_TYPE_YCbCr;
transparent = true;
} else {
boolean haveR = false;
boolean haveG = false;
boolean haveB = false;
boolean haveA = false;
boolean haveC = false;
boolean havec = false;
boolean haveY = false;
for (final SofnSegment.Component component : fSOFNSegment.getComponents()) {
final int id = component.componentIdentifier;
if (id == 'R') {
haveR = true;
} else if (id == 'G') {
haveG = true;
} else if (id == 'B') {
haveB = true;
} else if (id == 'A') {
haveA = true;
} else if (id == 'C') {
haveC = true;
} else if (id == 'c') {
havec = true;
} else if (id == 'Y') {
haveY = true;
}
}
if (haveR && haveG && haveB && !haveA && !haveC && !havec && !haveY) {
colorType = ImageInfo.COLOR_TYPE_RGB;
} else if (haveR && haveG && haveB && haveA && !haveC && !havec && !haveY) {
colorType = ImageInfo.COLOR_TYPE_RGB;
transparent = true;
} else if (haveY && haveC && havec && !haveR && !haveG && !haveB && !haveA) {
colorType = ImageInfo.COLOR_TYPE_YCC;
} else if (haveY && haveC && havec && haveA && !haveR && !haveG && !haveB) {
colorType = ImageInfo.COLOR_TYPE_YCC;
transparent = true;
} else {
int minHorizontalSamplingFactor = Integer.MAX_VALUE;
int maxHorizontalSmaplingFactor = Integer.MIN_VALUE;
int minVerticalSamplingFactor = Integer.MAX_VALUE;
int maxVerticalSamplingFactor = Integer.MIN_VALUE;
for (final SofnSegment.Component component : fSOFNSegment.getComponents()) {
if (minHorizontalSamplingFactor > component.horizontalSamplingFactor) {
minHorizontalSamplingFactor = component.horizontalSamplingFactor;
}
if (maxHorizontalSmaplingFactor < component.horizontalSamplingFactor) {
maxHorizontalSmaplingFactor = component.horizontalSamplingFactor;