package org.jcodec.containers.webp;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
import org.jcodec.common.Demuxer;
import org.jcodec.common.DemuxerTrack;
import org.jcodec.common.DemuxerTrackMeta;
import org.jcodec.common.JCodecUtil;
import org.jcodec.common.io.DataReader;
import org.jcodec.common.io.SeekableByteChannel;
import org.jcodec.common.logging.Logger;
import org.jcodec.common.model.Packet;
import org.jcodec.common.model.Packet.FrameType;
/**
* This class is part of JCodec ( www.jcodec.org ) This software is distributed
* under FreeBSD License
*
* Reads integer samples from the wav file
*
* @author Stanislav Vitvitskiy
*/
public class WebpDemuxer implements Demuxer, DemuxerTrack {
public final static int FOURCC_RIFF = 0x46464952; // 'RIFF'
public final static int FOURCC_WEBP = 0x50424557; // 'WEBP'
public final static int FOURCC_VP8 = 0x20385056; // 'VP8 '
public final static int FOURCC_ICCP = 0x50434349;
public final static int FOURCC_ANIM = 0x4d494e41;
public final static int FOURCC_ANMF = 0x464d4e41;
public final static int FOURCC_XMP = 0x20504d58;
public final static int FOURCC_EXIF = 0x46495845;
public final static int FOURCC_ALPH = 0x48504c41;
public final static int FOURCC_VP8L = 0x4c385056;
public final static int FOURCC_VP8X = 0x58385056;
private ArrayList<DemuxerTrack> vt;
private boolean headerRead;
private DataReader raf;
private boolean done;
public WebpDemuxer(SeekableByteChannel channel) {
this.raf = DataReader.createDataReader(channel, ByteOrder.LITTLE_ENDIAN);
vt = new ArrayList<DemuxerTrack>();
vt.add(this);
}
@Override
public void close() throws IOException {
raf.close();
}
@Override
public Packet nextFrame() throws IOException {
if (done)
return null;
if (!headerRead) {
readHeader();
headerRead = true;
}
int fourCC = raf.readInt();
int size = raf.readInt();
done = true;
switch (fourCC) {
case FOURCC_VP8:
byte[] b = new byte[size];
raf.readFully(b);
return new Packet(ByteBuffer.wrap(b), 0, 25, 1, 0, FrameType.KEY, null, 0);
case FOURCC_ICCP:
case FOURCC_ANIM:
case FOURCC_ANMF:
case FOURCC_XMP:
case FOURCC_EXIF:
case FOURCC_ALPH:
case FOURCC_VP8L:
case FOURCC_VP8X:
default:
Logger.warn("Skipping unsupported chunk: " + JCodecUtil.dwToFourCC(fourCC) + ".");
byte[] b1 = new byte[size];
raf.readFully(b1);
}
return null;
}
private void readHeader() throws IOException {
if (raf.readInt() != FOURCC_RIFF)
throw new IOException("Invalid RIFF file.");
int size = raf.readInt(); // Size must be sane
if (raf.readInt() != FOURCC_WEBP)
throw new IOException("Not a WEBP file.");
}
@Override
public DemuxerTrackMeta getMeta() {
// TODO Auto-generated method stub
return null;
}
@Override
public List<? extends DemuxerTrack> getTracks() {
return vt;
}
@Override
public List<? extends DemuxerTrack> getVideoTracks() {
return vt;
}
@Override
public List<? extends DemuxerTrack> getAudioTracks() {
return new ArrayList<DemuxerTrack>();
}
public static int probe(final ByteBuffer b_) {
ByteBuffer b = b_.duplicate();
if (b.remaining() < 12)
return 0;
b.order(ByteOrder.LITTLE_ENDIAN);
if (b.getInt() != FOURCC_RIFF)
return 0;
int size = b.getInt(); // Size must be sane
if (b.getInt() != FOURCC_WEBP)
return 0;
return 100;
}
}