From d24f2ec6249a99e828ad6638b9ae597b4d8126a8 Mon Sep 17 00:00:00 2001 From: Vasiliy Bout Date: Thu, 8 Jul 2010 15:31:21 +0000 Subject: [PATCH] git-svn-id: https://only.mawhrin.net/repos/FBReaderJ/trunk@1566 6a642e6f-84f6-412e-ac94-c4a38d5a04b0 --- .../fbreader/formats/fb2/FB2CoverReader.java | 122 ++++++++++++++++++ .../fbreader/formats/fb2/FB2Plugin.java | 3 +- .../fbreader/formats/fb2/FB2Tag.java | 5 +- .../fbreader/formats/oeb/OEBCoverReader.java | 2 +- 4 files changed, 128 insertions(+), 4 deletions(-) create mode 100644 src/org/geometerplus/fbreader/formats/fb2/FB2CoverReader.java diff --git a/src/org/geometerplus/fbreader/formats/fb2/FB2CoverReader.java b/src/org/geometerplus/fbreader/formats/fb2/FB2CoverReader.java new file mode 100644 index 000000000..0aa51a07f --- /dev/null +++ b/src/org/geometerplus/fbreader/formats/fb2/FB2CoverReader.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2010 Geometer Plus + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +package org.geometerplus.fbreader.formats.fb2; + +import java.util.*; + +import org.geometerplus.zlibrary.core.filesystem.ZLFile; +import org.geometerplus.zlibrary.core.image.ZLImage; +import org.geometerplus.zlibrary.core.xml.*; + +import org.geometerplus.fbreader.constants.XMLNamespace; + + +public class FB2CoverReader extends ZLXMLReaderAdapter { + + private boolean myReadCoverPage; + private String myImageReference; + private Base64EncodedImage myImage; + + + public ZLImage readCover(ZLFile file) { + myReadCoverPage = false; + myImageReference = null; + read(file); + return myImage; + } + + + private String myXLinkPrefix; + + @Override + public boolean processNamespaces() { + return true; + } + + public void namespaceMapChangedHandler(HashMap namespaceMap) { + myXLinkPrefix = null; + for (Map.Entry entry : namespaceMap.entrySet()) { + if (XMLNamespace.XLink.equals(entry.getValue())) { + myXLinkPrefix = entry.getKey() + ":"; + break; + } + } + } + + + @Override + public boolean startElementHandler(String tagName, ZLStringMap attributes) { + switch (FB2Tag.getTagByName(tagName)) { + case FB2Tag.COVERPAGE: + myReadCoverPage = true; + break; + case FB2Tag.IMAGE: + if (myReadCoverPage) { + if (myXLinkPrefix == null) { + break; + } + final String href = attributes.getValue((myXLinkPrefix + "href").intern()); + if (href != null && href.length() > 1 && href.charAt(0) == '#') { + myImageReference = href.substring(1); + } + } + break; + case FB2Tag.BINARY: + if (myImageReference != null) { + final String id = attributes.getValue("id"); + final String contentType = attributes.getValue("content-type"); + if (id != null && contentType != null && myImageReference.equals(id)) { + // FIXME: make different Base64EncodedImage constructor to use another cache for covers + myImage = new Base64EncodedImage((contentType != null) ? contentType : "image/auto"); + } + } + break; + } + return false; + } + + @Override + public boolean endElementHandler(String tag) { + switch (FB2Tag.getTagByName(tag)) { + case FB2Tag.COVERPAGE: + myReadCoverPage = false; + break; + case FB2Tag.DESCRIPTION: + if (myImageReference == null) { + return true; + } + break; + case FB2Tag.BINARY: + if (myImage != null) { + myImage.close(); + return true; + } + break; + } + return false; + } + + @Override + public void characterDataHandler(char[] data, int start, int length) { + if (length > 0 && myImage != null) { + myImage.addData(data, start, length); + } + } +} diff --git a/src/org/geometerplus/fbreader/formats/fb2/FB2Plugin.java b/src/org/geometerplus/fbreader/formats/fb2/FB2Plugin.java index 266d61bd4..2855b9d37 100644 --- a/src/org/geometerplus/fbreader/formats/fb2/FB2Plugin.java +++ b/src/org/geometerplus/fbreader/formats/fb2/FB2Plugin.java @@ -43,7 +43,6 @@ public class FB2Plugin extends FormatPlugin { @Override public ZLImage readCover(Book book) { - // TODO: implement - return null; + return new FB2CoverReader().readCover(book.File); } } diff --git a/src/org/geometerplus/fbreader/formats/fb2/FB2Tag.java b/src/org/geometerplus/fbreader/formats/fb2/FB2Tag.java index 51123f2a5..0dbff5672 100644 --- a/src/org/geometerplus/fbreader/formats/fb2/FB2Tag.java +++ b/src/org/geometerplus/fbreader/formats/fb2/FB2Tag.java @@ -59,8 +59,10 @@ final class FB2Tag { public static final byte SEQUENCE = 33; public static final byte GENRE = 34; + public static final byte DESCRIPTION = 35; - private static final HashMap ourTagByName = new HashMap(256, 0.2f); + + private static final HashMap ourTagByName = new HashMap(256, 0.2f); private static final Byte ourUnknownTag; static { @@ -101,6 +103,7 @@ final class FB2Tag { ourTagByName.put("author", AUTHOR); ourTagByName.put("lang", LANG); ourTagByName.put("genre", GENRE); + ourTagByName.put("description", DESCRIPTION); } public static byte getTagByName(String name) { diff --git a/src/org/geometerplus/fbreader/formats/oeb/OEBCoverReader.java b/src/org/geometerplus/fbreader/formats/oeb/OEBCoverReader.java index dd1f49f49..728df05e5 100644 --- a/src/org/geometerplus/fbreader/formats/oeb/OEBCoverReader.java +++ b/src/org/geometerplus/fbreader/formats/oeb/OEBCoverReader.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2010 Geometer Plus + * Copyright (C) 2010 Geometer Plus * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by