2
com.sixlegs.png - Java package to read and display PNG images
3
Copyright (C) 1998-2006 Chris Nokleberg
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation; either version 2 of the License, or
8
(at your option) any later version.
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
Linking this library statically or dynamically with other modules is
20
making a combined work based on this library. Thus, the terms and
21
conditions of the GNU General Public License cover the whole
24
As a special exception, the copyright holders of this library give you
25
permission to link this library with independent modules to produce an
26
executable, regardless of the license terms of these independent
27
modules, and to copy and distribute the resulting executable under
28
terms of your choice, provided that you also meet, for each linked
29
independent module, the terms and conditions of the license of that
30
module. An independent module is a module which is not derived from
31
or based on this library. If you modify this library, you may extend
32
this exception to your version of the library, but you are not
33
obligated to do so. If you do not wish to do so, delete this
34
exception statement from your version.
37
package com.sixlegs.png.examples;
39
import com.sixlegs.png.*;
40
import java.awt.image.BufferedImage;
42
import java.text.DecimalFormat;
45
public class ExtractFrames
47
public static void main(String[] args)
50
DecimalFormat fmt = new DecimalFormat("000");
51
for (int i = 0; i < args.length; i++) {
52
File in = new File(args[i]);
53
PngSplitter splitter = new PngSplitter(in);
54
int numFrames = splitter.getNumFrames();
55
for (int frame = 0; frame < numFrames; frame++) {
56
File out = new File(fmt.format(frame) + "-" + in.getName());
58
System.err.println("File exists, skipping: " + out);
61
System.err.println("Writing " + out);
62
splitter.write(out, frame);
67
private static class PngSplitter
70
private static final PngConfig CONFIG = new PngConfig.Builder()
72
.readLimit(PngConfig.READ_EXCEPT_DATA)
76
private List<Chunk> commonBefore = new ArrayList<Chunk>();
77
private List<Chunk> commonAfter = new ArrayList<Chunk>();
78
private List<Chunk> data = new ArrayList<Chunk>();
79
private List<Chunk> bySequence = new ArrayList<Chunk>();
80
private List<List<Chunk>> byFrame = new ArrayList<List<Chunk>>();
81
private byte[] buf = new byte[0x2000];
83
public PngSplitter(File in)
90
List<Chunk> cur = null;
91
for (Chunk chunk : bySequence) {
92
if (chunk.type == AnimatedPngImage.fcTL) {
93
byFrame.add(cur = new ArrayList<Chunk>());
100
public int getNumFrames()
102
return byFrame.size();
105
public void write(File file, int index)
108
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
109
ChunkWriter cw = new ChunkWriter();
111
out.writeLong(PngConstants.SIGNATURE);
112
echo(out, commonBefore);
113
echo(out, byFrame.get(index));
114
echo(out, commonAfter);
120
private void echo(DataOutput out, List<Chunk> chunks)
123
ChunkWriter cw = new ChunkWriter();
124
RandomAccessFile rf = new RandomAccessFile(in, "r");
126
for (Chunk chunk : chunks) {
127
cw.start(chunk.type);
128
rf.seek(chunk.offset);
129
rf.readFully(buf, 0, chunk.length);
130
cw.write(buf, 0, chunk.length);
139
protected void readChunk(int type, DataInput in, long offset, int length)
142
Chunk chunk = new Chunk();
144
chunk.offset = offset;
145
chunk.length = length;
147
case PngConstants.IDAT:
150
case AnimatedPngImage.acTL:
152
case AnimatedPngImage.fdAT:
153
chunk.type = PngConstants.IDAT;
157
case AnimatedPngImage.fcTL:
158
int seq = in.readInt();
159
while (bySequence.size() <= seq)
160
bySequence.add(null);
161
bySequence.set(seq, chunk);
164
(data.isEmpty() ? commonBefore : commonAfter).add(chunk);
165
super.readChunk(type, in, offset, length);
170
private static class Chunk
176
public String toString()
178
return PngConstants.getChunkName(type);