-
Notifications
You must be signed in to change notification settings - Fork 10
/
PngInfo.java
110 lines (100 loc) · 5.31 KB
/
PngInfo.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package net.ellerton.japng;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import net.ellerton.japng.argb8888.Argb8888BitmapSequence;
import net.ellerton.japng.chunks.PngFrameControl;
import net.ellerton.japng.error.PngException;
import net.ellerton.japng.map.PngChunkMap;
import net.ellerton.japng.util.PngContainer;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Dump basic information about named PNG files to console.
*/
public class PngInfo {
static class Config {
@Parameter(names = { "-v", "-verbose" }, description = "Level of verbosity")
private Integer verbosity = 0;
@Parameter(names = { "-h", "--help"}, description = "Show help", help = true)
private boolean help;
@Parameter(description = "<filename> ....")
private List<String> filenames = new ArrayList<String>();
public boolean verbose() {
return verbosity > 0;
}
}
public static void main(String[] args) {
Config config = new Config();
JCommander commander = new JCommander(config, args);
if (config.filenames.isEmpty() || config.help) {
commander.usage();
return;
}
for (String filename : config.filenames) {
process(config, filename);
}
}
private static void process(Config config, String filename) {
File f = new File(filename);
if (!f.exists()) {
System.err.println(filename+": no such file");
return;
}
if (!f.isFile() || !f.canRead()) {
System.err.println(filename+": not a file or can not read");
return;
}
try (FileInputStream fis = new FileInputStream(f)) {
PngContainer info = Png.readContainer(fis);
System.out.println(String.format("%s: PNG type %d (%s)", filename, info.header.colourType.code, info.header.colourType.name));
if (config.verbose()) {
System.out.println(String.format("%s: %s", filename, info.header.colourType.descriptino));
}
System.out.println(String.format("%s: width: %d", filename, info.header.width));
System.out.println(String.format("%s: height: %d", filename, info.header.height));
System.out.println(String.format("%s: interlaced: %s", filename, info.header.isInterlaced() ? "yes" : "no"));
if (config.verbose()) {
System.out.println(String.format("%s: bit-depth: %d (bits-per-pixel-channel)", filename, info.header.bitDepth));
System.out.println(String.format("%s: bits-per-pixel: %d", filename, info.header.bitsPerPixel));
System.out.println(String.format("%s: bytes-per-row: %d", filename, info.header.bytesPerRow));
}
System.out.println(String.format("%s: animated? %s", filename, info.isAnimated() ? "yes" : "no"));
if (info.isAnimated()) {
int n = info.animationControl.numFrames;
System.out.println(String.format("%s: animation frames: %d", filename, n));
System.out.println(String.format("%s: animation repeats: %s", filename, info.animationControl.loopForever() ? "infinite" : ""+info.animationControl.numPlays));
System.out.println(String.format("%s: default image before animation: %s", filename, info.hasDefaultImage ? "yes" : "no"));
int i=0;
for (PngFrameControl frame : info.animationFrames) {
i++;
System.out.println(String.format("%s: frame %2d of %2d: size %d x %d pixels", filename, i, n, frame.width, frame.height));
System.out.println(String.format("%s: frame %2d of %2d: position %d, %d", filename, i, n, frame.xOffset, frame.yOffset));
System.out.println(String.format("%s: frame %2d of %2d: duration %d/%d = %d milliseconds", filename, i, n, frame.delayNumerator, frame.delayDenominator, frame.getDelayMilliseconds()));
System.out.println(String.format("%s: frame %2d of %2d: dipose = %s", filename, i, n, frame.disposeOp));
System.out.println(String.format("%s: frame %2d of %2d: blend = %s", filename, i, n, frame.blendOp));
}
i = 0;
n = info.chunks.size();
for (PngChunkMap chunk : info.chunks) {
i++;
System.out.println(String.format("%s: chunk %2d of %2d: %s at %7d for %7d bytes (%s, %s, %s, %s)",
filename, i, n, chunk.code.letters, chunk.dataPosition, chunk.dataLength,
chunk.code.isAncillary() ? "ancillary" : "critical",
chunk.code.isPrivate() ? "private" : "public",
chunk.code.isReserved() ? "reserved" :"not reserved",
chunk.code.isSafeToCopy() ? "safe-to-copy" : "not safe to copy"
));
}
} else {
// nop
}
} catch (IOException e) {
System.err.println(filename+": IO error: "+e.getMessage());
} catch (PngException e) {
System.err.println(filename+": PNG error: "+e.getMessage());
}
}
}