From f0478bb14d8e5aa8e82b5c3f83e99eb0bb3d4676 Mon Sep 17 00:00:00 2001 From: luc Date: Fri, 20 Nov 2015 09:38:16 +0100 Subject: [PATCH] BMP and ICO image formats support : integrated /haraldk/TwelveMonkeys imageio-bmp-3.2 library. - better BMP format flavours support - handle PNG encoded icons - handle transparency Added some javadoc url references to .classpath --- .classpath | 221 ++++++++++-------- build.xml | 1 + lib/imageio-bmp-3.2.jar | Bin 0 -> 54771 bytes pom.xml | 5 + source/net/yacy/document/ImageParser.java | 95 +++----- .../document/parser/images/bmpParser.java | 9 + .../parser/images/genericImageParser.java | 33 +-- .../document/parser/images/icoParser.java | 10 +- 8 files changed, 179 insertions(+), 195 deletions(-) create mode 100755 lib/imageio-bmp-3.2.jar diff --git a/.classpath b/.classpath index e29121a32..988565a6d 100644 --- a/.classpath +++ b/.classpath @@ -1,102 +1,119 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build.xml b/build.xml index 95d4ff99f..6c94fe8f4 100644 --- a/build.xml +++ b/build.xml @@ -182,6 +182,7 @@ + diff --git a/lib/imageio-bmp-3.2.jar b/lib/imageio-bmp-3.2.jar new file mode 100755 index 0000000000000000000000000000000000000000..1946caefe402a9d4feccbc57d92dcf8eb50c0a73 GIT binary patch literal 54771 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 56.1 + + com.twelvemonkeys.imageio + imageio-bmp + 3.2 + com.twelvemonkeys.imageio imageio-tiff diff --git a/source/net/yacy/document/ImageParser.java b/source/net/yacy/document/ImageParser.java index aaff10437..b66518a37 100644 --- a/source/net/yacy/document/ImageParser.java +++ b/source/net/yacy/document/ImageParser.java @@ -20,82 +20,43 @@ package net.yacy.document; -import java.awt.Container; import java.awt.Image; -import java.awt.MediaTracker; +import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.IOException; import javax.imageio.ImageIO; import net.yacy.cora.util.ConcurrentLog; -import net.yacy.document.parser.images.bmpParser; -import net.yacy.document.parser.images.icoParser; public class ImageParser { - public static final Image parse(final String filename, final byte[] source) { - final MediaTracker mediaTracker = new MediaTracker(new Container()); - Image image = null; - if (((filename.endsWith(".ico")) || (filename.endsWith(".bmp"))) && (bmpParser.isBMP(source))) { - // parse image with BMP parser - image = bmpParser.parse(source).getImage(); - if (image == null) { - if (ConcurrentLog.isFine("IMAGEPARSER")) { - ConcurrentLog.fine("IMAGEPARSER", "IMAGEPARSER.parse : bmpParser failed for " + filename); - } - return null; - } - } else if ((filename.endsWith(".ico")) && (icoParser.isICO(source))) { - // parse image with ICO parser - icoParser icoparser; - try { - icoparser = new icoParser(source); - image = icoparser.getImage(0); - } catch (final Throwable e) { - if (ConcurrentLog.isFine("IMAGEPARSER")) { - ConcurrentLog.fine("IMAGEPARSER", "IMAGEPARSER.parse : could not parse image " + filename, e); - } - } - if (image == null) { - if (ConcurrentLog.isFine("IMAGEPARSER")) { - ConcurrentLog.fine("IMAGEPARSER", "IMAGEPARSER.parse : icoParser failed for " + filename); - } - return null; - } - } else { - try { - image = ImageIO.read(new ByteArrayInputStream(source)); - } catch(IOException e) { - if (ConcurrentLog.isFine("IMAGEPARSER")) { - ConcurrentLog.fine("IMAGEPARSER", "IMAGEPARSER.parse : could not parse image " + filename, e); - } - } - if (image == null) { - if (ConcurrentLog.isFine("IMAGEPARSER")) { - ConcurrentLog.fine("IMAGEPARSER", "IMAGEPARSER.parse : ImageIO failed for " + filename); - } - return null; - } - } - if (image == null) { - return null; - } - - final int handle = image.hashCode(); - mediaTracker.addImage(image, handle); - try { - mediaTracker.waitForID(handle); - - if (mediaTracker.isErrorID(handle)) { // true if status ERRORD during loading (happens on not supported formats too) - mediaTracker.removeImage(image, handle); - image = null; // return null to indicate source not handled - } - } catch (final InterruptedException e) { - return null; - } - - return image; - } + /** + * @param filename source image file url + * @param source image content as bytes + * @return an Image instance parsed from image content bytes, or null if no parser can handle image format or an error occured + */ + public static final Image parse(final String filename, final byte[] source) { + BufferedImage image = null; + try { + image = ImageIO.read(new ByteArrayInputStream(source)); + /* + * With ImageIO.read, image is already loaded as a complete BufferedImage, no need to wait + * full loading with a MediaTracker + */ + } catch (IOException e) { + if (ConcurrentLog.isFine("IMAGEPARSER")) { + ConcurrentLog.fine("IMAGEPARSER", "IMAGEPARSER.parse : could not parse image " + filename, e); + } + } + if (image == null) { + if (ConcurrentLog.isFine("IMAGEPARSER")) { + ConcurrentLog.fine("IMAGEPARSER", "IMAGEPARSER.parse : ImageIO failed for " + filename); + } + return null; + } + + return image; + } } diff --git a/source/net/yacy/document/parser/images/bmpParser.java b/source/net/yacy/document/parser/images/bmpParser.java index 33a3fc9cf..694a83f99 100644 --- a/source/net/yacy/document/parser/images/bmpParser.java +++ b/source/net/yacy/document/parser/images/bmpParser.java @@ -32,8 +32,17 @@ import java.io.IOException; import javax.imageio.ImageIO; +import com.twelvemonkeys.imageio.plugins.bmp.BMPImageReader; + import net.yacy.cora.util.ConcurrentLog; +/** + * + * @deprecated use ImageIO {@link BMPImageReader} from github.com/haraldk/TwelveMonkeys + * library (imageio-bmp-3.2.jar), which as better BMP format + * variants support + */ +@Deprecated public class bmpParser { // this is a implementation of http://de.wikipedia.org/wiki/Windows_Bitmap diff --git a/source/net/yacy/document/parser/images/genericImageParser.java b/source/net/yacy/document/parser/images/genericImageParser.java index 74e04f779..78d645fd9 100644 --- a/source/net/yacy/document/parser/images/genericImageParser.java +++ b/source/net/yacy/document/parser/images/genericImageParser.java @@ -46,6 +46,13 @@ import java.util.Set; import javax.imageio.ImageIO; +import com.drew.imaging.jpeg.JpegMetadataReader; +import com.drew.lang.GeoLocation; +import com.drew.metadata.Directory; +import com.drew.metadata.Metadata; +import com.drew.metadata.Tag; +import com.drew.metadata.exif.GpsDirectory; + import net.yacy.cora.document.id.AnchorURL; import net.yacy.cora.document.id.DigestURL; import net.yacy.cora.document.id.MultiProtocolURL; @@ -55,16 +62,8 @@ import net.yacy.document.Document; import net.yacy.document.Parser; import net.yacy.document.VocabularyScraper; import net.yacy.document.parser.html.ImageEntry; -import net.yacy.document.parser.images.bmpParser.IMAGEMAP; import net.yacy.kelondro.util.FileUtils; -import com.drew.imaging.jpeg.JpegMetadataReader; -import com.drew.lang.GeoLocation; -import com.drew.metadata.Directory; -import com.drew.metadata.Metadata; -import com.drew.metadata.Tag; -import com.drew.metadata.exif.GpsDirectory; - /** * Parser for images, bmp and jpeg and all supported by the Java Image I/O API * by default java ImageIO supports bmp, gif, jpg, jpeg, png, wbmp (tif if jai-imageio is in classpath/registered) @@ -75,11 +74,9 @@ public class genericImageParser extends AbstractParser implements Parser { public genericImageParser() { super("Generic Image Parser"); - SUPPORTED_EXTENSIONS.add("bmp"); SUPPORTED_EXTENSIONS.add("jpe"); // not listed in ImageIO extension but sometimes uses for jpeg SUPPORTED_EXTENSIONS.addAll(Arrays.asList(ImageIO.getReaderFileSuffixes())); - SUPPORTED_MIME_TYPES.add("image/bmp"); SUPPORTED_MIME_TYPES.add("image/jpg"); // this is in fact a 'wrong' mime type. We leave it here because that is a common error that occurs in the internet frequently SUPPORTED_MIME_TYPES.addAll(Arrays.asList(ImageIO.getReaderMIMETypes())); } @@ -102,21 +99,7 @@ public class genericImageParser extends AbstractParser implements Parser { String ext = MultiProtocolURL.getFileExtension(filename); double gpslat = 0; double gpslon = 0; - if (mimeType.equals("image/bmp") || ext.equals("bmp")) { - byte[] b; - try { - b = FileUtils.read(source); - } catch (final IOException e) { - ConcurrentLog.logException(e); - throw new Parser.Failure(e.getMessage(), location); - } - if (bmpParser.isBMP(b)) { - final IMAGEMAP imap = bmpParser.parse(b); - ii = parseJavaImage(location, imap.getImage()); - } else { - throw new Parser.Failure("Not supported by bmpParser", location); - } - } else if (mimeType.equals("image/jpeg") || ext.equals("jpg") || ext.equals("jpeg") || ext.equals("jpe")) { + if (mimeType.equals("image/jpeg") || ext.equals("jpg") || ext.equals("jpeg") || ext.equals("jpe")) { // use the exif parser from // http://www.drewnoakes.com/drewnoakes.com/code/exif/ // javadoc is at: http://www.drewnoakes.com/drewnoakes.com/code/exif/javadoc/ diff --git a/source/net/yacy/document/parser/images/icoParser.java b/source/net/yacy/document/parser/images/icoParser.java index 4ff965387..3036a0219 100644 --- a/source/net/yacy/document/parser/images/icoParser.java +++ b/source/net/yacy/document/parser/images/icoParser.java @@ -32,9 +32,17 @@ import java.io.IOException; import javax.imageio.ImageIO; -import net.yacy.cora.util.ConcurrentLog; +import com.twelvemonkeys.imageio.plugins.bmp.ICOImageReader; +import net.yacy.cora.util.ConcurrentLog; +/** +* +* @deprecated use ImageIO {@link ICOImageReader} from github.com/haraldk/TwelveMonkeys +* library (imageio-bmp-3.2.jar), which as better BMP format +* variants support, and support PNG encoded icons. +*/ +@Deprecated public class icoParser { // this is a implementation of http://msdn2.microsoft.com/en-us/library/ms997538(d=printer).aspx