X-Git-Url: http://www2.svjatoslav.eu/gitweb/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Feu%2Fsvjatoslav%2Fmeviz%2Fhtmlindexer%2FUtils.java;h=172ec446fb1f00f7a380c4e2f5fcbf308f67c49b;hb=ed57ca76172f5984eee2d08de841fa7b7bb21b29;hp=ab711a5ffdaf506328cec2b9c453263e18c331f3;hpb=d9c80f1c1b5cd3cccb681bddcc2b13a312cf9a1f;p=meviz.git diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/Utils.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/Utils.java index ab711a5..172ec44 100755 --- a/src/main/java/eu/svjatoslav/meviz/htmlindexer/Utils.java +++ b/src/main/java/eu/svjatoslav/meviz/htmlindexer/Utils.java @@ -1,125 +1,257 @@ /* * Meviz - Various tools collection to work with multimedia. - * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu - * + * Copyright (C) 2012 -- 2019, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu + * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public License - * as published by the Free Software Foundation. - */ + * modify it under the terms of version 3 of the GNU Lesser General Public License + * or later as published by the Free Software Foundation. +*/ package eu.svjatoslav.meviz.htmlindexer; +import eu.svjatoslav.meviz.htmlindexer.layouts.Layout; +import eu.svjatoslav.meviz.htmlindexer.layouts.MixedLayout; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.imageio.ImageReader; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.metadata.IIOMetadataNode; +import java.awt.*; import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.File; -import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; +import java.util.ArrayList; import java.util.HashSet; import java.util.zip.CRC32; -import javax.imageio.ImageIO; - -import eu.svjatoslav.meviz.htmlindexer.layouts.MixedLayout; +import static org.openimaj.image.ImageUtilities.createBufferedImage; +import static org.openimaj.image.ImageUtilities.readMBF; public class Utils { + private static File lastLoadedFile; + private static BufferedImage lastLoadedBufferedImage; + + /** + * Load image into {@link BufferedImage} and return it. Caches last loaded + * image to speed up subsequent loading attempts. + * + * @throws ImageFormatError + * @throws IOException + */ + public static BufferedImage getBufferedImage(final File file) + throws ImageFormatError, IOException { + if (file.equals(lastLoadedFile)) + return lastLoadedBufferedImage; + + lastLoadedBufferedImage = createBufferedImage(readMBF(file)); + lastLoadedFile = file; + + if (lastLoadedBufferedImage == null) { + System.out.println("Error reading image: " + file); + throw new ImageFormatError("File: " + file + + " is not a valid image."); + + } + + return lastLoadedBufferedImage; + } + + public static File getLayoutIndexFile(final Layout layout, + final File directoryToIndex) { + + final String indexFilePath = directoryToIndex.getAbsolutePath() + + "/index" + layout.getFileNameSuffix() + ".html"; + + return new File(indexFilePath); + } + + public static HashSet getLayouts() { + final HashSet layouts = new HashSet<>(); + layouts.add(new MixedLayout()); + return layouts; + } + + public static String getStringCrcAsHex(final String input) { + + // create a new CRC-calculating object + final CRC32 crc = new CRC32(); + + // loop, calculating CRC for each byte of the string + // There is no CRC16.update(byte[]) method. + for (final byte b : input.getBytes()) + crc.update(b); + + // note use crc.value, not crc.getValue() + + return Integer.toHexString((int) crc.getValue()) + .toUpperCase(); + } + + public static File getThumbnailsDirectory(final File directoryToIndex) { + return new File(getThumbnailsDirectoryPath(directoryToIndex)); + } + + public static String getThumbnailsDirectoryPath(final File directoryToIndex) { + return directoryToIndex.getAbsolutePath() + "/" + + Constants.THUMBNAILS_DIRECTORY_NAME + "/"; + } + + public static boolean isMevizGeneratedIndexFile(final File indexFile) + throws IOException { + + boolean isMevizFile = false; + + final FileReader fileReader = new FileReader(indexFile); + final BufferedReader reader = new BufferedReader(fileReader); - private static File lastLoadedFile; + parseFile: + { + while (true) { + final String line = reader.readLine(); - private static BufferedImage lastLoadedBufferedImage; + if (line == null) + break parseFile; - /** - * Load image into {@link BufferedImage} and return it. Caches last loaded - * image to speed up subsequent loading attempts. - * - * @throws ImageFormatError - * @throws IOException - */ - public static BufferedImage getBufferedImage(final File file) - throws ImageFormatError, IOException { - if (file.equals(lastLoadedFile)) - return lastLoadedBufferedImage; + if (line.contains(Constants.HTML_MAGIC_STRING)) { + isMevizFile = true; + break parseFile; + } + } + } - System.out.println("Loading image: " + file.getPath()); - lastLoadedBufferedImage = ImageIO.read(file); - lastLoadedFile = file; + reader.close(); + fileReader.close(); + return isMevizFile; + } - if (lastLoadedBufferedImage == null) - throw new ImageFormatError("File: " + file - + " is not a valid image."); + /** + * TODO: URL path component is encoded differently from URL query parameter. + * Also some URL encoding might work for HTML on local filesystem, while other + * stuff works for web. Things must be cleared up here. Currently they are mixed and + * hacked together. + */ + public static String urlEncode(String string) { + if (string.startsWith("./")) + string = string.substring(2); - return lastLoadedBufferedImage; - } + // TODO: get rid of UrlParamEncoder. + return UrlParamEncoder.encode(string); + // +// try { +// return URLEncoder.encode(string, UTF_8).replace("+", "%20"); +// } catch (UnsupportedEncodingException e) { +// throw new RuntimeException(e); +// } + } - public static File getLayoutIndexFile(final Layout layout, - final File directoryToIndex) { + public static ImageFrame[] readGIF(ImageReader reader) throws IOException { + ArrayList frames = new ArrayList(2); - final String indexFilePath = directoryToIndex.getAbsolutePath() - + "/index" + layout.getFileNameSuffix() + ".html"; + int width = -1; + int height = -1; - return new File(indexFilePath); - } + IIOMetadata metadata = reader.getStreamMetadata(); + if (metadata != null) { + IIOMetadataNode globalRoot = (IIOMetadataNode) metadata.getAsTree(metadata.getNativeMetadataFormatName()); - public static HashSet getLayouts() { - final HashSet layouts = new HashSet(); - layouts.add(new MixedLayout()); - return layouts; - } + NodeList globalScreenDescriptor = globalRoot.getElementsByTagName("LogicalScreenDescriptor"); - public static String getStringCrcAsHex(final String input) { + if (globalScreenDescriptor != null && globalScreenDescriptor.getLength() > 0) { + IIOMetadataNode screenDescriptor = (IIOMetadataNode) globalScreenDescriptor.item(0); - // create a new CRC-calculating object - final CRC32 crc = new CRC32(); + if (screenDescriptor != null) { + width = Integer.parseInt(screenDescriptor.getAttribute("logicalScreenWidth")); + height = Integer.parseInt(screenDescriptor.getAttribute("logicalScreenHeight")); + } + } + } - // loop, calculating CRC for each byte of the string - // There is no CRC16.update(byte[]) method. - for (final byte b : input.getBytes()) - crc.update(b); + BufferedImage master = null; + Graphics2D masterGraphics = null; - // note use crc.value, not crc.getValue() - final String hex = Integer.toHexString((int) crc.getValue()) - .toUpperCase(); + for (int frameIndex = 0;; frameIndex++) { + BufferedImage image; + try { + image = reader.read(frameIndex); + } catch (IndexOutOfBoundsException io) { + break; + } - // System.out.println("Input string: " + input); - // System.out.println("Result: " + hex); + if (width == -1 || height == -1) { + width = image.getWidth(); + height = image.getHeight(); + } - return hex; - } + IIOMetadataNode root = (IIOMetadataNode) reader.getImageMetadata(frameIndex).getAsTree("javax_imageio_gif_image_1.0"); + IIOMetadataNode gce = (IIOMetadataNode) root.getElementsByTagName("GraphicControlExtension").item(0); + int delay = Integer.valueOf(gce.getAttribute("delayTime")); + String disposal = gce.getAttribute("disposalMethod"); - public static File getThumbnailsDirectory(final File directoryToIndex) { - return new File(getThumbnailsDirectoryPath(directoryToIndex)); - } + int x = 0; + int y = 0; - public static String getThumbnailsDirectoryPath(final File directoryToIndex) { - return directoryToIndex.getAbsolutePath() + "/" - + Constants.THUMBNAILS_DIRECTORY_NAME + "/"; - } + if (master == null) { + master = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + masterGraphics = master.createGraphics(); + masterGraphics.setBackground(new Color(0, 0, 0, 0)); + } else { + NodeList children = root.getChildNodes(); + for (int nodeIndex = 0; nodeIndex < children.getLength(); nodeIndex++) { + Node nodeItem = children.item(nodeIndex); + if (nodeItem.getNodeName().equals("ImageDescriptor")) { + NamedNodeMap map = nodeItem.getAttributes(); + x = Integer.valueOf(map.getNamedItem("imageLeftPosition").getNodeValue()); + y = Integer.valueOf(map.getNamedItem("imageTopPosition").getNodeValue()); + } + } + } + masterGraphics.drawImage(image, x, y, null); - public static boolean isMevizGeneratedIndexFile(final File indexFile) - throws FileNotFoundException, IOException { + BufferedImage copy = new BufferedImage(master.getColorModel(), master.copyData(null), master.isAlphaPremultiplied(), null); + frames.add(new ImageFrame(copy, delay, disposal)); - boolean isMevizFile = false; + if (disposal.equals("restoreToPrevious")) { + BufferedImage from = null; + for (int i = frameIndex - 1; i >= 0; i--) { + if (!frames.get(i).getDisposal().equals("restoreToPrevious") || frameIndex == 0) { + from = frames.get(i).image; + break; + } + } - final FileReader fileReader = new FileReader(indexFile); - final BufferedReader reader = new BufferedReader(fileReader); + master = new BufferedImage(from.getColorModel(), from.copyData(null), from.isAlphaPremultiplied(), null); + masterGraphics = master.createGraphics(); + masterGraphics.setBackground(new Color(0, 0, 0, 0)); + } else if (disposal.equals("restoreToBackgroundColor")) { + masterGraphics.clearRect(x, y, image.getWidth(), image.getHeight()); + } + } + reader.dispose(); - parseFile: { - while (true) { - final String line = reader.readLine(); + return frames.toArray(new ImageFrame[frames.size()]); + } - if (line == null) - break parseFile; + public static class ImageFrame { + private final int delay; + public BufferedImage image; + private final String disposal; - if (line.contains(Constants.HTML_MAGIC_STRING)) { - isMevizFile = true; - break parseFile; - } - } - } + public ImageFrame(BufferedImage image, int delay, String disposal) { + this.image = image; + this.delay = delay; + this.disposal = disposal; + } - reader.close(); - fileReader.close(); - return isMevizFile; - } + public int getDelay() { + return delay; + } + public String getDisposal() { + return disposal; + } + } }