/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id: PreloaderWMF.java 1608162 2014-07-06 05:34:16Z gadams $ */

package org.apache.fop.image.loader.batik;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.xml.transform.Source;

import org.apache.commons.io.EndianUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.batik.transcoder.wmf.WMFConstants;
import org.apache.batik.transcoder.wmf.tosvg.WMFRecordStore;

import org.apache.xmlgraphics.image.loader.ImageContext;
import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.ImageSize;
import org.apache.xmlgraphics.image.loader.impl.AbstractImagePreloader;
import org.apache.xmlgraphics.image.loader.util.ImageUtil;
import org.apache.xmlgraphics.io.XmlSourceUtil;

import org.apache.fop.util.UnclosableInputStream;

Image preloader for WMF images (Windows Metafile).
/** * Image preloader for WMF images (Windows Metafile). */
public class PreloaderWMF extends AbstractImagePreloader {
Logger instance
/** Logger instance */
private static Log log = LogFactory.getLog(PreloaderWMF.class); private boolean batikAvailable = true;
{@inheritDoc}
/** {@inheritDoc} */
public ImageInfo preloadImage(String uri, Source src, ImageContext context) throws IOException { if (!ImageUtil.hasInputStream(src)) { return null; } ImageInfo info = null; if (batikAvailable) { try { Loader loader = new Loader(); info = loader.getImage(uri, src, context); } catch (NoClassDefFoundError e) { batikAvailable = false; log.warn("Batik not in class path", e); return null; } } if (info != null) { XmlSourceUtil.closeQuietly(src); //Image is fully read } return info; }
This method is put in another class so that the class loader does not attempt to load Batik related classes when constructing the WMFPreloader class.
/** * This method is put in another class so that the class loader does not * attempt to load Batik related classes when constructing the WMFPreloader * class. */
private final class Loader { private Loader() { } private ImageInfo getImage(String uri, Source src, ImageContext context) { // parse document and get the size attributes of the svg element InputStream in = new UnclosableInputStream(XmlSourceUtil.needInputStream(src)); try { in.mark(4 + 1); DataInputStream din = new DataInputStream(in); int magic = EndianUtils.swapInteger(din.readInt()); din.reset(); if (magic != WMFConstants.META_ALDUS_APM) { IOUtils.closeQuietly(din); return null; //Not a WMF file } WMFRecordStore wmfStore = new WMFRecordStore(); wmfStore.read(din); IOUtils.closeQuietly(din); int width = wmfStore.getWidthUnits(); int height = wmfStore.getHeightUnits(); int dpi = wmfStore.getMetaFileUnitsPerInch(); ImageInfo info = new ImageInfo(uri, "image/x-wmf"); ImageSize size = new ImageSize(); size.setSizeInPixels(width, height); size.setResolution(dpi); size.calcSizeFromPixels(); info.setSize(size); ImageWMF img = new ImageWMF(info, wmfStore); info.getCustomObjects().put(ImageInfo.ORIGINAL_IMAGE, img); return info; } catch (NoClassDefFoundError ncdfe) { try { in.reset(); } catch (IOException ioe) { // we're more interested in the original exception } batikAvailable = false; log.warn("Batik not in class path", ncdfe); return null; } catch (IOException e) { // If the svg is invalid then it throws an IOException // so there is no way of knowing if it is an svg document log.debug("Error while trying to load stream as an WMF file: " + e.getMessage()); // assuming any exception means this document is not svg // or could not be loaded for some reason try { in.reset(); } catch (IOException ioe) { // we're more interested in the original exception } return null; } } } }