mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2026-04-30 00:00:01 -04:00
TMI-113: Worked around a rather nasty bug in com.sun.imageio.plugins.jpeg.AdobeMarkerSegment by filtering out all APP14/Adobe marker segments from the stream (and re-inserting to metadata later).
This commit is contained in:
+20
-14
@@ -155,24 +155,30 @@ final class JPEGImage10MetadataCleaner {
|
||||
}
|
||||
}
|
||||
|
||||
// Special case: Broken AdobeDCT segment, inconsistent with SOF, use values from SOF
|
||||
if (adobeDCT != null && (adobeDCT.getTransform() == AdobeDCTSegment.YCCK && sof.componentsInFrame() < 4 ||
|
||||
if (adobeDCT != null) {
|
||||
// Special case: Broken AdobeDCT segment, inconsistent with SOF, use values from SOF
|
||||
if ((adobeDCT.getTransform() == AdobeDCTSegment.YCCK && sof.componentsInFrame() < 4 ||
|
||||
adobeDCT.getTransform() == AdobeDCTSegment.YCC && sof.componentsInFrame() < 3)) {
|
||||
reader.processWarningOccurred(String.format(
|
||||
"Invalid Adobe App14 marker. Indicates %s data, but SOF%d has %d color component(s). " +
|
||||
"Ignoring Adobe App14 marker.",
|
||||
adobeDCT.getTransform() == AdobeDCTSegment.YCCK ? "YCCK/CMYK" : "YCC/RGB",
|
||||
sof.marker & 0xf, sof.componentsInFrame()
|
||||
));
|
||||
|
||||
reader.processWarningOccurred(String.format(
|
||||
"Invalid Adobe App14 marker. Indicates %s data, but SOF%d has %d color component(s). " +
|
||||
"Ignoring Adobe App14 marker.",
|
||||
adobeDCT.getTransform() == AdobeDCTSegment.YCCK ? "YCCK/CMYK" : "YCC/RGB",
|
||||
sof.marker & 0xf, sof.componentsInFrame()
|
||||
));
|
||||
|
||||
// Remove bad AdobeDCT
|
||||
NodeList app14Adobe = tree.getElementsByTagName("app14Adobe");
|
||||
for (int i = app14Adobe.getLength() - 1; i >= 0; i--) {
|
||||
Node item = app14Adobe.item(i);
|
||||
item.getParentNode().removeChild(item);
|
||||
// We don't add this as unknown marker, as we are certain it's bogus by now
|
||||
}
|
||||
else {
|
||||
// Otherwise, add back the Adobe tag we filtered out in JPEGSegmentImageInputStream
|
||||
IIOMetadataNode app14Adobe = new IIOMetadataNode("app14Adobe");
|
||||
app14Adobe.setAttribute("version", String.valueOf(adobeDCT.getVersion()));
|
||||
app14Adobe.setAttribute("flags0", String.valueOf(adobeDCT.getFlags0()));
|
||||
app14Adobe.setAttribute("flags1", String.valueOf(adobeDCT.getFlags1()));
|
||||
app14Adobe.setAttribute("transform", String.valueOf(adobeDCT.getTransform()));
|
||||
|
||||
// We don't add this as unknown marker, as we are certain it's bogus by now
|
||||
markerSequence.insertBefore(app14Adobe, markerSequence.getFirstChild());
|
||||
}
|
||||
}
|
||||
|
||||
Node next = null;
|
||||
|
||||
+7
-3
@@ -117,9 +117,9 @@ final class JPEGSegmentImageInputStream extends ImageInputStreamImpl {
|
||||
marker = 0xff00 | stream.readUnsignedByte();
|
||||
}
|
||||
|
||||
// TODO: Optionally skip JFIF only for non-JFIF conformant streams
|
||||
// TODO: Refactor to make various segments optional, we probably only want the "Adobe" APP14 segment, 'Exif' APP1 and very few others
|
||||
if (isAppSegmentMarker(marker) && !(marker == JPEG.APP1 && isAppSegmentWithId("Exif", stream)) && marker != JPEG.APP14) {
|
||||
// TODO: Should we just skip all app marker segments?
|
||||
// We are now handling all important segments ourselves
|
||||
if (isAppSegmentMarker(marker) && !(marker == JPEG.APP1 && isAppSegmentWithId("Exif", stream))) {
|
||||
int length = stream.readUnsignedShort(); // Length including length field itself
|
||||
stream.seek(realPosition + 2 + length); // Skip marker (2) + length
|
||||
}
|
||||
@@ -133,8 +133,12 @@ final class JPEGSegmentImageInputStream extends ImageInputStreamImpl {
|
||||
|
||||
if (marker == JPEG.SOS) {
|
||||
// Treat rest of stream as a single segment (scanning for EOI is too much work)
|
||||
// TODO: For progressive, there will be more than one SOS...
|
||||
length = Long.MAX_VALUE - realPosition;
|
||||
}
|
||||
// else if (marker == JPEG.APP14 && isAppSegmentWithId("Adobe", stream)) {
|
||||
// length = 16;
|
||||
// }
|
||||
else {
|
||||
// Length including length field itself
|
||||
length = stream.readUnsignedShort() + 2;
|
||||
|
||||
Reference in New Issue
Block a user