001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.components.source.impl;
018:
019: import java.io.BufferedInputStream;
020: import java.io.IOException;
021:
022: import org.apache.avalon.framework.thread.ThreadSafe;
023: import org.apache.excalibur.source.Source;
024: import org.apache.excalibur.source.SourceException;
025:
026: /**
027: * This source inspector adds extra attributes for image files.
028: *
029: * @author <a href="mailto:stephan@apache.org">Stephan Michels</a>
030: * @author <a href="mailto:balld@webslingerZ.com">Donald A. Ball Jr.</a>
031: * @version CVS $Id: JPEGSourceInspector.java 433543 2006-08-22 06:22:54Z crossley $
032: */
033: public class JPEGSourceInspector extends AbstractImageSourceInspector
034: implements ThreadSafe {
035:
036: public JPEGSourceInspector() {
037: }
038:
039: /**
040: * Checks the source uri for the .jp(e)g extension.
041: */
042: protected final boolean isImageMimeType(Source source) {
043: final String uri = source.getURI();
044: final int index = uri.lastIndexOf('.');
045: if (index != -1) {
046: String extension = uri.substring(index);
047: return extension.equalsIgnoreCase(".jpg")
048: || extension.equalsIgnoreCase(".JPEG");
049: }
050: return false;
051: }
052:
053: /**
054: * Checks that this is in fact a jpeg file.
055: */
056: protected final boolean isImageFileType(Source source)
057: throws SourceException {
058: BufferedInputStream in = null;
059: try {
060: in = new BufferedInputStream(source.getInputStream());
061: byte[] buf = new byte[2];
062: int count = in.read(buf, 0, 2);
063: if (count < 2)
064: return false;
065:
066: if ((buf[0] == (byte) 0xFF) && (buf[1] == (byte) 0xD8))
067: return true;
068: } catch (IOException ioe) {
069: throw new SourceException("Could not read source", ioe);
070: } finally {
071: if (in != null)
072: try {
073: in.close();
074: } catch (Exception e) {
075: }
076: }
077: return false;
078: }
079:
080: /**
081: * returns width as first element, height as second
082: */
083: protected final int[] getImageSize(Source source)
084: throws SourceException {
085: BufferedInputStream in = null;
086: try {
087: in = new BufferedInputStream(source.getInputStream());
088: // check for "magic" header
089: byte[] buf = new byte[2];
090: int count = in.read(buf, 0, 2);
091: if (count < 2)
092: throw new SourceException("Not a valid Jpeg file!");
093: if ((buf[0]) != (byte) 0xFF || (buf[1]) != (byte) 0xD8)
094: throw new SourceException("Not a valid Jpeg file!");
095:
096: int width = 0;
097: int height = 0;
098:
099: boolean done = false;
100: int ch = 0;
101:
102: try {
103: while (ch != 0xDA && !done) {
104: /* Find next marker (JPEG markers begin with 0xFF) */
105: while (ch != 0xFF) {
106: ch = in.read();
107: }
108: /* JPEG markers can be padded with unlimited 0xFF's */
109: while (ch == 0xFF) {
110: ch = in.read();
111: }
112: /* Now, ch contains the value of the marker. */
113: if (ch >= 0xC0 && ch <= 0xC3) {
114: // skip 3 bytes
115: in.read();
116: in.read();
117: in.read();
118: height = 256 * in.read();
119: height += in.read();
120: width = 256 * in.read();
121: width += in.read();
122: done = true;
123: } else {
124: /* We MUST skip variables, since FF's within variable names
125: are NOT valid JPEG markers */
126: int length = 256 * in.read();
127: length += in.read();
128: if (length < 2)
129: throw new RuntimeException(
130: "Erroneous JPEG marker length");
131: for (int foo = 0; foo < length - 2; foo++)
132: in.read();
133: }
134: }
135: } catch (Exception e) {
136: throw new SourceException("Not a valid Jpeg file!", e);
137: }
138:
139: int[] dim = { width, height };
140: return dim;
141:
142: } catch (IOException ioe) {
143: throw new SourceException("Could not read source", ioe);
144: } finally {
145: if (in != null)
146: try {
147: in.close();
148: } catch (Exception e) {
149: }
150: }
151: }
152:
153: }
|