/*
* Copyright 1998-2016 Linux.org.ru
* Licensed 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.
*/
package ru.org.linux.util.image;
import ru.org.linux.util.BadImageException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
/**
* Gets image dimensions by parsing file headers.
* <p/>
* currently supported file types: Jpeg Gif Png
*/
public class ImageInfo{
private int height = -1;
private int width = -1;
private int size = 0;
private final String filename;
@SuppressWarnings("UseOfSystemOutOrSystemErr")
public static void main(String[] args) throws Exception {
ImageInfo info = new ImageInfo(args[0]);
if (info.width > info.height) {
System.out.print("horizontal ");
} else {
System.out.print("vertical ");
}
System.out.println(info.width + " " + info.height);
}
/**
* constructs image from filename
* <p/>
* file type is determined from file's extension
*/
public ImageInfo(String filename) throws BadImageException, IOException {
this.filename = filename;
FileInputStream fileStream = null;
try {
fileStream = new FileInputStream(filename);
size = (int) new File(filename).length();
String lowname = filename.toLowerCase();
if (lowname.endsWith("gif")) {
getGifInfo(fileStream);
} else if (lowname.endsWith("jpg") || lowname.endsWith("jpeg")) {
getJpgInfo(fileStream);
} else if (lowname.endsWith("png")) {
getPngInfo(fileStream);
} else {
throw new BadImageException("Invalid image extension");
}
if (height == -1 || width == -1) {
throw new BadImageException();
}
} finally {
if (fileStream != null) {
fileStream.close();
}
}
}
public ImageInfo(File file, String extension) throws BadImageException, IOException {
filename = file.getName();
FileInputStream fileStream = null;
try {
fileStream = new FileInputStream(file);
size = fileStream.available();
if ("gif".equals(extension)) {
getGifInfo(fileStream);
} else if ("jpg".equals(extension) || "jpeg".equals(extension)) {
getJpgInfo(fileStream);
} else if ("png".equals(extension)) {
getPngInfo(fileStream);
} else {
throw new BadImageException("Invalid image extension");
}
if (height == -1 || width == -1) {
throw new BadImageException();
}
} finally {
if (fileStream != null) {
fileStream.close();
}
}
}
private void getGifInfo(FileInputStream fileStream) throws IOException, BadImageException {
byte[] bytes = new byte[13];
int bytesread = fileStream.read(bytes);
if (bytesread == 13) {
String header = new String(bytes);
if ("GIF".equals(header.substring(0, 3))) //It's a gif, continue processing
{
width = shortLittleEndian(bytes[6], bytes[7]);
height = shortLittleEndian(bytes[8], bytes[9]);
} else {
throw new BadImageException("Bad GIF image: "+filename);
}
}
}
private void getPngInfo(FileInputStream fileStream) throws IOException, BadImageException {
byte[] bytes = new byte[24];
int bytesread = fileStream.read(bytes);
if (bytesread == 24) {
String header = new String(bytes);
if ("PNG".equals(header.substring(1, 4))) {
width = intBigEndian(bytes[16], bytes[17], bytes[18], bytes[19]);
height = intBigEndian(bytes[20], bytes[21], bytes[22], bytes[23]);
} else {
throw new BadImageException("Bad PNG image: "+filename);
}
}
}
private void getJpgInfo(FileInputStream fileStream) throws IOException, BadImageException {
if (fileStream.read() == 0xFF && fileStream.read() == 0xD8) {
while (true) {
int marker;
do {
marker = fileStream.read();
} while (marker != 0xFF);
do {
marker = fileStream.read();
} while (marker == 0xFF);
if (((marker >= 0xC0) && (marker <= 0xC3)) || ((marker >= 0xC5) && (marker <= 0xCB)) || ((marker >= 0xCD) && (marker <= 0xCF)))
{
fileStream.skip(3);
height = shortBigEndian((byte) fileStream.read(), (byte) fileStream.read());
width = shortBigEndian((byte) fileStream.read(), (byte) fileStream.read());
break;
} else {
int skip = shortBigEndian((byte) fileStream.read(), (byte) fileStream.read()) - 2;
if (skip<0) {
throw new BadImageException("Bad JPG image: "+filename);
}
fileStream.skip(skip);
}
}
} else {
throw new BadImageException("Bad JPG image: "+filename);
}
}
private static short shortBigEndian(byte firstRead, byte lastRead) {
return (short) (((firstRead & 0xFF) << 8) | lastRead & 0xFF);
}
private static short shortLittleEndian(byte firstRead, byte lastRead) {
return shortBigEndian(lastRead, firstRead);
}
private static int intBigEndian(byte a1, byte a2, byte a3, byte a4) {
return ((a1 & 0xFF) << 24) | ((a2 & 0xFF) << 16) | ((a3 & 0xFF) << 8) | a4 & 0xFF;
}
public int getHeight() {
return height;
}
public int getWidth() {
return width;
}
/**
* get file size
*/
public int getSize() {
return size;
}
/**
* get file size in user-printable form
*/
public String getSizeString() {
return size / 1024 + " Kb";
}
/**
* get HTML code for inclusion into IMG tag
*/
public String getCode() {
return "width=" + width + " height=" + height;
}
}