r45040 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r45039‎ | r45040 | r45041 >
Date:20:03, 25 December 2008
Author:oggk
Status:deferred
Tags:
Comment:
This large commit brings support for Kate overlay streams
(eg, for use as subtitles).

There are 3 main parts to this commit:
- jkate is an implementation of a Kate decoder
- jtiger is a simple renderer for Kate streams
- a few new elements: Selector, Overlay, KateDec, KateOverlay

KateDec depends on jkate.
KateOverlay depends on jkate and jtiger.
jtiger depends on jkate.

The 'kateIndex' property may be used to select a Kate stream
to display, by zero based index. By default, none is selected.

The new elements are:
Selector: selects one link among many (eg, receive data on
any number of sink pads, and forward only one of them)
Overlay: base class allowing to modify an image.
TextOverlay: sample use of Overlay that displays a text string
on incoming video.
KateOverlay: overlays a Kate stream on incoming video.
KateDec: decodes a Kate stream.

Improvements to the renderer will be made. At the moment, it
supports only simple text and image streams (in particular, it
can handle all streams created by ffmpeg2theora).

More information about Kate streams may be found at:
http://wiki.xiph.org/index.php/OggKate

Any question, just let me know at ogg.k.ogg.k (-at-) [googlemail]
dot com. I'm new to Java, so hopefully I've not broken anything.
Tested on x86 and x86_64.
Modified paths:
  • /trunk/cortado/HACKING (modified) (history)
  • /trunk/cortado/README (modified) (history)
  • /trunk/cortado/build.xml (modified) (history)
  • /trunk/cortado/plugins.ini (modified) (history)
  • /trunk/cortado/src/com/fluendo/examples/Player.java (modified) (history)
  • /trunk/cortado/src/com/fluendo/jkate (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/Bitmap.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/Bitwise.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/Color.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/Comment.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/Curve.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/Decode.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/Event.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/FontMapping.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/FontRange.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/Info.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/KateBitmapType.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/KateCurveType.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/KateException.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/KateMarkupType.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/KateMotionMapping.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/KateMotionSemantics.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/KateSpaceMetric.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/KateTextDirectionality.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/KateTextEncoding.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/KateWrapMode.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/Motion.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/Palette.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/README (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/RLE.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/Region.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/Result.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/State.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/Style.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jkate/Tracker.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jst/Element.java (modified) (history)
  • /trunk/cortado/src/com/fluendo/jst/Sink.java (modified) (history)
  • /trunk/cortado/src/com/fluendo/jtiger (added) (history)
  • /trunk/cortado/src/com/fluendo/jtiger/Item.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jtiger/README (added) (history)
  • /trunk/cortado/src/com/fluendo/jtiger/Renderer.java (added) (history)
  • /trunk/cortado/src/com/fluendo/jtiger/TigerBitmap.java (added) (history)
  • /trunk/cortado/src/com/fluendo/player/Cortado.java (modified) (history)
  • /trunk/cortado/src/com/fluendo/player/CortadoPipeline.java (modified) (history)
  • /trunk/cortado/src/com/fluendo/plugin/KateDec.java (added) (history)
  • /trunk/cortado/src/com/fluendo/plugin/KateOverlay.java (added) (history)
  • /trunk/cortado/src/com/fluendo/plugin/OggDemux.java (modified) (history)
  • /trunk/cortado/src/com/fluendo/plugin/OggPayload.java (modified) (history)
  • /trunk/cortado/src/com/fluendo/plugin/Overlay.java (added) (history)
  • /trunk/cortado/src/com/fluendo/plugin/Selector.java (added) (history)
  • /trunk/cortado/src/com/fluendo/plugin/TextOverlay.java (added) (history)
  • /trunk/cortado/src/com/fluendo/plugin/TheoraDec.java (modified) (history)
  • /trunk/cortado/src/com/fluendo/plugin/VorbisDec.java (modified) (history)

Diff [purge]

Index: trunk/cortado/HACKING
@@ -9,6 +9,8 @@
1010 - utils: utitity classes used by jst, jheora, examples
1111 - jst: a java port of the GStreamer 0.10 design
1212 - jheora: a java implementation of the Theora video codec
 13+ - jkate: a basic java implementation of the Kate codec
 14+ - jtiger: a basic Kate stream renderer (simple text/images only for now)
1315 - codecs: additional codecs; currently contains the Smoke codec
1416 - plugin: plugins implementing/wrapping sources/decoders/sinks
1517 - examples: example programs
Index: trunk/cortado/src/com/fluendo/jst/Element.java
@@ -464,4 +464,8 @@
465465 public boolean query (Query query) {
466466 return false;
467467 }
 468+
 469+ public Pad requestSinkPad(Pad peer) {
 470+ return null;
 471+ }
468472 }
Index: trunk/cortado/src/com/fluendo/jst/Sink.java
@@ -29,7 +29,7 @@
3030 private boolean needPreroll;
3131 private Clock.ClockID clockID;
3232 protected boolean discont;
33 - protected long segStart;
 33+ protected long segStart = 0;
3434 protected long segStop;
3535 protected long segPosition;
3636 protected long pauseTime;
@@ -352,11 +352,11 @@
353353 synchronized (this) {
354354 if (currentState == PLAY) {
355355 if (clock != null) {
356 - position = clock.getTime() - baseTime + segPosition;
 356+ position = clock.getTime() - baseTime + segPosition + segStart;
357357 }
358358 }
359359 else {
360 - position = pauseTime + segPosition;
 360+ position = pauseTime + segPosition + segStart;
361361 }
362362 }
363363 query.setPosition(Format.TIME, position);
Index: trunk/cortado/src/com/fluendo/jtiger/Renderer.java
@@ -0,0 +1,62 @@
 2+/* JTiger
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JTiger are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jtiger;
 23+
 24+import java.util.*;
 25+import java.awt.*;
 26+import java.awt.image.*;
 27+
 28+public class Renderer {
 29+ private Vector items = new Vector();
 30+
 31+ /**
 32+ * Add a new event to the renderer.
 33+ */
 34+ public void add(com.fluendo.jkate.Event ev) {
 35+ items.addElement(new Item(ev));
 36+ }
 37+
 38+ /**
 39+ * Update the renderer, and all the events it tracks.
 40+ * Returns 1 if there is nothing to draw, as an optimization
 41+ */
 42+ public int update(Component c, double t) {
 43+ for (int n=0; n<items.size(); ++n) {
 44+ boolean ret = ((Item)items.get(n)).update(c, t);
 45+ if (!ret) {
 46+ items.removeElementAt(n);
 47+ --n;
 48+ }
 49+ }
 50+ if (items.size() == 0)
 51+ return 1;
 52+ return 0;
 53+ }
 54+
 55+ /**
 56+ * Renders onto the given image.
 57+ */
 58+ public void render(Component c, BufferedImage bimg) {
 59+ for (int n=0; n<items.size(); ++n) {
 60+ ((Item)items.get(n)).render(c, bimg);
 61+ }
 62+ }
 63+}
Index: trunk/cortado/src/com/fluendo/jtiger/TigerBitmap.java
@@ -0,0 +1,93 @@
 2+/* JTiger
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JTiger are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jtiger;
 23+
 24+import java.util.*;
 25+import java.awt.*;
 26+import java.awt.image.*;
 27+import com.fluendo.jkate.*;
 28+import com.fluendo.utils.*;
 29+
 30+public class TigerBitmap {
 31+ private Image image;
 32+ private Image scaled_image;
 33+
 34+ /**
 35+ * Create a new TigerBitmap from a Kate bitmap and optional palette.
 36+ */
 37+ public TigerBitmap(Bitmap kb, Palette kp)
 38+ {
 39+ if (kb == null) {
 40+ image = null;
 41+ }
 42+ else if (kb.bpp == 0) {
 43+ /* PNG */
 44+ image = createPNGBitmap(kb, kp);
 45+ }
 46+ else {
 47+ if (kp == null) {
 48+ image = null;
 49+ }
 50+ else {
 51+ image = createPalettedBitmap(kb, kp);
 52+ }
 53+ }
 54+ }
 55+
 56+ /**
 57+ * Returns a scaled version of the image.
 58+ */
 59+ public Image getScaled(int width, int height)
 60+ {
 61+ if (scaled_image == null || width != scaled_image.getWidth(null) || height != scaled_image.getHeight(null)) {
 62+ scaled_image = image.getScaledInstance(width, height, BufferedImage.SCALE_SMOOTH); // TODO: quality setting
 63+ }
 64+ return scaled_image;
 65+ }
 66+
 67+ /**
 68+ * Create an image from bits representing a PNG image.
 69+ */
 70+ private Image createPNGBitmap(Bitmap kb, Palette kp)
 71+ {
 72+ Debug.warning("PNG bitmaps not supported yet");
 73+ return null;
 74+ }
 75+
 76+ /**
 77+ * Create a paletted image.
 78+ */
 79+ private Image createPalettedBitmap(Bitmap kb, Palette kp)
 80+ {
 81+ byte[] cmap = new byte[4*kp.colors.length];
 82+ for (int n=0; n<kp.colors.length; ++n) {
 83+ cmap[n*4+0] = kp.colors[n].r;
 84+ cmap[n*4+1] = kp.colors[n].g;
 85+ cmap[n*4+2] = kp.colors[n].b;
 86+ cmap[n*4+3] = kp.colors[n].a;
 87+ }
 88+ IndexColorModel icm = new IndexColorModel(kb.bpp, kp.colors.length, cmap, 0, true);
 89+ BufferedImage img = new BufferedImage(kb.width, kb.height, BufferedImage.TYPE_BYTE_INDEXED, icm);
 90+ WritableRaster r = img.getRaster();
 91+ r.setDataElements(0, 0, kb.width, kb.height, kb.pixels);
 92+ return img;
 93+ }
 94+}
Index: trunk/cortado/src/com/fluendo/jtiger/README
@@ -0,0 +1,3 @@
 2+JTiger is a very basic renderer for Kate streams.
 3+
 4+At the moment, only raw text is supported.
Index: trunk/cortado/src/com/fluendo/jtiger/Item.java
@@ -0,0 +1,192 @@
 2+/* JTiger
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JTiger are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jtiger;
 23+
 24+import java.util.*;
 25+import java.awt.*;
 26+import java.awt.image.*;
 27+import java.awt.font.*;
 28+import java.text.*;
 29+import com.fluendo.jkate.Event;
 30+import com.fluendo.jkate.Tracker;
 31+import com.fluendo.utils.*;
 32+
 33+public class Item {
 34+ private Tracker kin = null;
 35+ private boolean alive = false;
 36+ private Font font = null;
 37+ private String text = null;
 38+ private TigerBitmap background_image = null;
 39+
 40+ private int width = -1;
 41+ private int height = -1;
 42+
 43+ private float region_x;
 44+ private float region_y;
 45+ private float region_w;
 46+ private float region_h;
 47+
 48+
 49+ /**
 50+ * Create a new item from a Kate event.
 51+ */
 52+ public Item(com.fluendo.jkate.Event ev) {
 53+ this.kin = new Tracker(ev);
 54+ text = null;
 55+ if (ev.text != null && ev.text.length > 0) {
 56+ try {
 57+ text = new String(ev.text, "UTF8");
 58+ }
 59+ catch (Exception e) {
 60+ Debug.warning("Failed to convert text from UTF-8 - text will not display");
 61+ text = null;
 62+ }
 63+ }
 64+ }
 65+
 66+ /**
 67+ * Create a font suitable for displaying on the given component
 68+ */
 69+ protected void createFont(Component c) {
 70+ Dimension d = c.getSize();
 71+ int font_size = d.width / 32;
 72+ if (font_size < 12) font_size = 12;
 73+ font = new Font("sans", Font.BOLD, font_size); // TODO: should be selectable ?
 74+ }
 75+
 76+ /**
 77+ * Regenerate any cached data to match any relevant changes in the
 78+ * given component
 79+ */
 80+ protected void updateCachedData(Component c) {
 81+ Dimension d = c.getSize();
 82+ if (d.width == width && d.height == height)
 83+ return;
 84+
 85+ createFont(c);
 86+
 87+ width = d.width;
 88+ height = d.height;
 89+ }
 90+
 91+ /**
 92+ * Updates the item at the given time.
 93+ * returns true for alive, false for dead
 94+ */
 95+ public boolean update(Component c, double t) {
 96+ com.fluendo.jkate.Event ev = kin.ev;
 97+ if (ev == null) return false;
 98+ if (t >= ev.end_time) return false;
 99+
 100+ if (t < ev.start_time) {
 101+ alive = false;
 102+ }
 103+ else {
 104+ alive = true;
 105+ }
 106+
 107+ Dimension d = c.getSize();
 108+ return kin.update(t-ev.start_time, d, d);
 109+ }
 110+
 111+ /**
 112+ * Set up the region.
 113+ */
 114+ public void setupRegion(Component c) {
 115+ if (kin.has[Tracker.has_region]) {
 116+ region_x = kin.region_x;
 117+ region_y = kin.region_y;
 118+ region_w = kin.region_w;
 119+ region_h = kin.region_h;
 120+ }
 121+ else {
 122+ Dimension d = c.getSize();
 123+ region_x = d.width * 0.1f;
 124+ region_y = d.height * 0.8f;
 125+ region_w = d.width * 0.8f;
 126+ region_h = d.height * 0.1f;
 127+ }
 128+ }
 129+
 130+ /**
 131+ * Renders the item on the given image.
 132+ */
 133+ public void render(Component c, BufferedImage bimg) {
 134+ com.fluendo.jkate.Event ev = kin.ev;
 135+
 136+ if (!alive)
 137+ return;
 138+
 139+ updateCachedData(c);
 140+
 141+ setupRegion(c);
 142+ renderBackground(bimg);
 143+ renderText(bimg);
 144+ }
 145+
 146+ /**
 147+ * Render a background for the item, if approrpiate.
 148+ * The background may be a color, or an image.
 149+ */
 150+ public void renderBackground(BufferedImage bimg)
 151+ {
 152+ if (kin.ev.bitmap != null) {
 153+ if (background_image == null) {
 154+ background_image = new TigerBitmap(kin.ev.bitmap, kin.ev.palette);
 155+ }
 156+
 157+ Graphics2D g = bimg.createGraphics();
 158+ int rx = (int)(region_x+0.5), ry = (int)(region_y+0.5);
 159+ int rw = (int)(region_w+0.5), rh = (int)(region_h+0.5);
 160+ g.drawImage(background_image.getScaled(rw, rh), rx, ry, null);
 161+ g.dispose();
 162+ }
 163+ }
 164+
 165+ /**
 166+ * Render text text for the item, if approrpiate.
 167+ */
 168+ public void renderText(BufferedImage bimg)
 169+ {
 170+ if (text == null)
 171+ return;
 172+
 173+ Graphics2D g = bimg.createGraphics();
 174+
 175+ AttributedString atext = new AttributedString(text, font.getAttributes());
 176+ AttributedCharacterIterator text_it = atext.getIterator();
 177+ int text_end = text_it.getEndIndex();
 178+ g.setColor(Color.white);
 179+
 180+ FontRenderContext frc = g.getFontRenderContext();
 181+ LineBreakMeasurer lbm = new LineBreakMeasurer(text_it, frc);
 182+ float dy = 0.0f;
 183+ while (lbm.getPosition() < text_end) {
 184+ TextLayout layout = lbm.nextLayout(region_w);
 185+ dy += layout.getAscent();
 186+ float tw = layout.getAdvance();
 187+ layout.draw(g, region_x+((region_w-tw)/2), region_y+dy);
 188+ dy += layout.getDescent() + layout.getLeading();
 189+ }
 190+
 191+ g.dispose();
 192+ }
 193+}
Index: trunk/cortado/src/com/fluendo/player/CortadoPipeline.java
@@ -18,6 +18,7 @@
1919
2020 package com.fluendo.player;
2121
 22+import java.util.*;
2223 import java.awt.*;
2324 import java.net.URL;
2425
@@ -31,6 +32,7 @@
3233 private String password;
3334 private boolean enableAudio;
3435 private boolean enableVideo;
 36+ private int enableKate;
3537 private Component component;
3638 private int bufferSize = -1;
3739 private int bufferLow = -1;
@@ -46,8 +48,12 @@
4749 private Element videosink;
4850 private Element audiosink;
4951 private Element v_queue, a_queue;
50 - private Pad asinkpad, vsinkpad;
 52+ private Element overlay;
 53+ private Pad asinkpad, ovsinkpad, oksinkpad;
5154 private Pad apad, vpad;
 55+ private Vector katedec = new Vector();
 56+ private Vector k_queue = new Vector();
 57+ private Element kselector = null;
5258
5359 public boolean usingJavaX = false;
5460
@@ -115,7 +121,7 @@
116122
117123 pad.link(v_queue.getPad("sink"));
118124 v_queue.getPad("src").link(videodec.getPad("sink"));
119 - if (!videodec.getPad("src").link(vsinkpad)) {
 125+ if (!videodec.getPad("src").link(ovsinkpad)) {
120126 postMessage (Message.newError (this, "videosink already linked"));
121127 return;
122128 }
@@ -132,7 +138,7 @@
133139 videodec.setProperty ("component", component);
134140
135141 pad.link(videodec.getPad("sink"));
136 - if (!videodec.getPad("src").link(vsinkpad)) {
 142+ if (!videodec.getPad("src").link(ovsinkpad)) {
137143 postMessage (Message.newError (this, "videosink already linked"));
138144 return;
139145 }
@@ -146,7 +152,7 @@
147153 videodec.setProperty ("component", component);
148154
149155 pad.link(videodec.getPad("sink"));
150 - if (!videodec.getPad("src").link(vsinkpad)) {
 156+ if (!videodec.getPad("src").link(ovsinkpad)) {
151157 postMessage (Message.newError (this, "videosink already linked"));
152158 return;
153159 }
@@ -154,13 +160,85 @@
155161
156162 videodec.setState (PAUSE);
157163 }
 164+ else if (enableVideo && mime.equals("application/x-kate")) {
 165+ Element tmp_k_queue, tmp_katedec, tmp_katesink;
 166+ Pad tmp_kpad, tmp_ksinkpad;
 167+ int kate_index = katedec.size();
 168+
 169+ Debug.debug("Found Kate stream, setting up pipeline branch");
 170+
 171+ /* dynamically create a queue/decoder/overlay pipeline */
 172+ tmp_k_queue = ElementFactory.makeByName("queue", "k_queue"+kate_index);
 173+ if (tmp_k_queue == null) {
 174+ noSuchElement ("queue");
 175+ return;
 176+ }
 177+
 178+ tmp_katedec = ElementFactory.makeByName("katedec", "katedec"+kate_index);
 179+ if (tmp_katedec == null) {
 180+ noSuchElement ("katedec");
 181+ return;
 182+ }
 183+
 184+ /* The selector is created when the first Kate stream is encountered */
 185+ if (kselector == null) {
 186+ Debug.debug("No Kate selector yet, creating one");
 187+ kselector = ElementFactory.makeByName("selector", "selector");
 188+ if (kselector == null) {
 189+ noSuchElement ("selector");
 190+ return;
 191+ }
 192+ add(kselector);
 193+ if (!kselector.getPad("src").link(oksinkpad)) {
 194+ postMessage (Message.newError (this, "Failed linking Kate selector to overlay"));
 195+ return;
 196+ }
 197+ kselector.setState (PAUSE);
 198+ }
 199+ tmp_katesink = kselector;
 200+
 201+ add(tmp_k_queue);
 202+ add(tmp_katedec);
 203+
 204+ tmp_kpad = pad;
 205+ tmp_ksinkpad = tmp_katesink.getPad("sink");
 206+
 207+ /* link new elements together */
 208+ if (!pad.link(tmp_k_queue.getPad("sink"))) {
 209+ postMessage (Message.newError (this, "Failed to link new Kate stream to queue"));
 210+ return;
 211+ }
 212+ if (!tmp_k_queue.getPad("src").link(tmp_katedec.getPad("sink"))) {
 213+ postMessage (Message.newError (this, "Failed to link new Kate queue to decoder"));
 214+ return;
 215+ }
 216+
 217+ Pad new_selector_pad = kselector.requestSinkPad(tmp_katedec.getPad("src"));
 218+ if (!tmp_katedec.getPad("src").link(new_selector_pad)) {
 219+ postMessage (Message.newError (this, "kate sink already linked"));
 220+ return;
 221+ }
 222+
 223+ tmp_katedec.setState (PAUSE);
 224+ tmp_k_queue.setState (PAUSE);
 225+
 226+ /* add to the lists */
 227+ katedec.addElement(tmp_katedec);
 228+ k_queue.addElement(tmp_k_queue);
 229+
 230+ /* if we have just added the one that was selected, link it now */
 231+ if (enableKate == katedec.size()-1) {
 232+ doEnableKateIndex(enableKate);
 233+ }
 234+ }
158235 }
159236
160237 public void padRemoved(Pad pad) {
161238 pad.unlink();
162239 if (pad == vpad) {
163240 Debug.log(Debug.INFO, "video pad removed "+pad);
164 - vsinkpad.unlink();
 241+ ovsinkpad.unlink();
 242+ //oksinkpad.unlink(); // needed ????
165243 vpad = null;
166244 }
167245 else if (pad == apad) {
@@ -172,6 +250,7 @@
173251
174252 public void noMorePads() {
175253 boolean changed = false;
 254+ Element el;
176255
177256 Debug.log(Debug.INFO, "all streams detected");
178257
@@ -185,8 +264,26 @@
186265 if (vpad == null && enableVideo) {
187266 Debug.log(Debug.INFO, "file has no video, remove videosink");
188267 videosink.setState(STOP);
 268+ overlay.setState(STOP);
 269+ for (int n=0; n<katedec.size(); ++n) {
 270+ el = (Element)katedec.get(n);
 271+ el.setState(STOP);
 272+ remove(el);
 273+ el = (Element)k_queue.get(n);
 274+ el.setState(STOP);
 275+ remove(el);
 276+ }
 277+ if (kselector != null) {
 278+ kselector.setState(STOP);
 279+ remove(kselector);
 280+ kselector = null;
 281+ }
189282 remove (videosink);
 283+ remove (overlay);
 284+ katedec.clear();
 285+ k_queue.clear();
190286 videosink = null;
 287+ overlay = null;
191288 changed = true;
192289 }
193290 if (changed)
@@ -199,6 +296,7 @@
200297 enableAudio = true;
201298 enableVideo = true;
202299 application = cortado;
 300+ enableKate = -1; /* none by default */
203301 }
204302
205303 public void setUrl(String anUrl) {
@@ -228,6 +326,40 @@
229327 return enableVideo;
230328 }
231329
 330+ /**
 331+ * Selects the Kate stream index (if any) to enable.
 332+ * The first Kate stream has index 0, the second has index 1, etc.
 333+ * A negative index will enable none.
 334+ */
 335+ public void enableKateIndex(int idx) {
 336+ if (idx == enableKate) return;
 337+ doEnableKateIndex(idx);
 338+ }
 339+
 340+ /**
 341+ * Enables the given Kate stream, by index.
 342+ * A negative index will enable none.
 343+ */
 344+ private void doEnableKateIndex(int idx)
 345+ {
 346+ if (kselector != null) {
 347+ Debug.info("Switching Kate streams from "+enableKate+" to "+idx);
 348+ kselector.setProperty("selected", new Integer(idx));
 349+ }
 350+ else {
 351+ Debug.warning("Switching Kate stream request, but no Kate selector exists");
 352+ }
 353+
 354+ enableKate = idx;
 355+ }
 356+
 357+ /**
 358+ * Returns the index of the currently enabled Kate stream (negative if none)
 359+ */
 360+ public int getEnabledKateIndex() {
 361+ return enableKate;
 362+ }
 363+
232364 public void setComponent(Component c) {
233365 component = c;
234366 }
@@ -410,8 +542,22 @@
411543 resize(component.getSize());
412544
413545 videosink.setProperty ("max-lateness", Long.toString(Clock.MSECOND * 20));
414 - vsinkpad = videosink.getPad("sink");
415546 add(videosink);
 547+
 548+ /* TODO: we need that in case there are kate streams, but could be
 549+ better to build it only when kate streams are actually found later */
 550+ overlay = ElementFactory.makeByName("kateoverlay", "overlay");
 551+ if (overlay == null) {
 552+ noSuchElement ("overlay");
 553+ return false;
 554+ }
 555+ ovsinkpad = overlay.getPad("videosink");
 556+ oksinkpad = overlay.getPad("katesink");
 557+ add(overlay);
 558+
 559+ overlay.setProperty ("component", component);
 560+
 561+ overlay.getPad("videosrc").link(videosink.getPad("sink"));
416562 }
417563 if (audiosink == null && videosink == null) {
418564 postMessage(Message.newError(this, "Both audio and video are disabled, can't play anything"));
@@ -445,6 +591,7 @@
446592 }
447593
448594 private boolean cleanup() {
 595+ int n;
449596 Debug.log(Debug.INFO, "cleanup");
450597 if (httpsrc != null) {
451598 remove (httpsrc);
@@ -458,8 +605,13 @@
459606 if (videosink != null) {
460607 remove (videosink);
461608 videosink = null;
462 - vsinkpad = null;
463609 }
 610+ if (overlay != null) {
 611+ remove (overlay);
 612+ overlay = null;
 613+ ovsinkpad = null;
 614+ oksinkpad = null;
 615+ }
464616 if (buffer != null) {
465617 remove (buffer);
466618 buffer = null;
@@ -485,6 +637,23 @@
486638 remove(audiodec);
487639 audiodec = null;
488640 }
 641+
 642+ for (n=0; n<katedec.size(); ++n) {
 643+ if (k_queue.get(n) != null) {
 644+ remove ((Element)k_queue.get(n));
 645+ }
 646+ if (katedec.get(n) != null) {
 647+ remove((Element)katedec.get(n));
 648+ }
 649+ }
 650+ k_queue.clear();
 651+ katedec.clear();
 652+
 653+ if (kselector != null) {
 654+ remove(kselector);
 655+ kselector = null;
 656+ }
 657+
489658 return true;
490659 }
491660
Index: trunk/cortado/src/com/fluendo/player/Cortado.java
@@ -34,6 +34,7 @@
3535 private String urlString;
3636 private boolean audio;
3737 private boolean video;
 38+ private int kateIndex;
3839 private boolean showSpeaker;
3940 private boolean keepAspect;
4041 private boolean autoPlay;
@@ -100,6 +101,7 @@
101102 "Total duration of the file in seconds (default unknown)"},
102103 {"audio", "boolean", "Enable audio playback (default true)"},
103104 {"video", "boolean", "Enable video playback (default true)"},
 105+ {"kateIndex", "boolean", "Enable playback of a particular Kate stream (default -1 (none))"},
104106 {"statusHeight", "int", "The height of the status area (default 12)"},
105107 {"autoPlay", "boolean", "Automatically start playback (default true)"},
106108 {"showStatus", "enum", "Show status area (auto|show|hide) (default auto)"},
@@ -223,6 +225,7 @@
224226 durationParam = getDoubleParam("duration", -1.0);
225227 audio = getBoolParam("audio", true);
226228 video = getBoolParam("video", true);
 229+ kateIndex = getIntParam("kateIndex", -1);
227230 statusHeight = getIntParam("statusHeight", 12);
228231 autoPlay = getBoolParam("autoPlay", true);
229232 showStatus = getEnumParam("showStatus", showStatusVals, "auto");
@@ -257,6 +260,7 @@
258261 pipeline.setPassword(password);
259262 pipeline.enableAudio(audio);
260263 pipeline.enableVideo(video);
 264+ pipeline.enableKateIndex(kateIndex);
261265 pipeline.setBufferSize(bufferSize);
262266 pipeline.setBufferLow(bufferLow);
263267 pipeline.setBufferHigh(bufferHigh);
Index: trunk/cortado/src/com/fluendo/examples/Player.java
@@ -38,6 +38,7 @@
3939 applet.setParam ("keepaspect", "true");
4040 applet.setParam ("video", "true");
4141 applet.setParam ("audio", "true");
 42+ applet.setParam ("kateIndex", "0");
4243 //applet.setParam ("audio", "false");
4344 applet.setParam ("bufferSize", "200");
4445 applet.setParam ("userId", "wim");
Index: trunk/cortado/src/com/fluendo/jkate/Bitmap.java
@@ -0,0 +1,37 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+/**
 25+ * A Bitmap definition.
 26+ */
 27+public class Bitmap
 28+{
 29+ public int width;
 30+ public int height;
 31+ public int bpp;
 32+ public KateBitmapType type;
 33+ public int palette;
 34+ public byte[] pixels;
 35+ public int size;
 36+ public int x_offset;
 37+ public int y_offset;
 38+}
Index: trunk/cortado/src/com/fluendo/jkate/README
@@ -0,0 +1,4 @@
 2+JKate is a simple Kate stream decoder.
 3+
 4+At the moment, only text is supported.
 5+
Index: trunk/cortado/src/com/fluendo/jkate/Result.java
@@ -0,0 +1,35 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+public final class Result {
 25+ public static final int KATE_E_NOT_FOUND = -1;
 26+ public static final int KATE_E_INVALID_PARAMETER = -2;
 27+ public static final int KATE_E_OUT_OF_MEMORY = -3;
 28+ public static final int KATE_E_BAD_GRANULE = -4;
 29+ public static final int KATE_E_INIT = -5;
 30+ public static final int KATE_E_BAD_PACKET = -6;
 31+ public static final int KATE_E_TEXT = -7;
 32+ public static final int KATE_E_LIMIT = -8;
 33+ public static final int KATE_E_VERSION = -9;
 34+ public static final int KATE_E_NOT_KATE = -10;
 35+ public static final int KATE_E_BAD_TAG = -11;
 36+}
Index: trunk/cortado/src/com/fluendo/jkate/Color.java
@@ -0,0 +1,29 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+public class Color
 25+{
 26+ public byte r;
 27+ public byte g;
 28+ public byte b;
 29+ public byte a;
 30+}
Index: trunk/cortado/src/com/fluendo/jkate/State.java
@@ -0,0 +1,128 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+import com.jcraft.jogg.*;
 25+import com.fluendo.utils.*;
 26+
 27+public class State
 28+{
 29+ long granulepos;
 30+
 31+ private Decode dec;
 32+ private Event ev = null;
 33+
 34+ public void clear()
 35+ {
 36+ }
 37+
 38+ /**
 39+ * Initialize for decoding.
 40+ */
 41+ public int decodeInit(Info ki)
 42+ {
 43+ dec = new Decode(ki);
 44+ granulepos=-1;
 45+
 46+ return(0);
 47+ }
 48+
 49+ /**
 50+ * Decode a Kate data packet.
 51+ * Headers are supposed to have been parsed already.
 52+ * An event may be generated, and will then be available from decodeEventOut.
 53+ */
 54+ public int decodePacketin (Packet op)
 55+ {
 56+ long ret;
 57+ byte type;
 58+
 59+ ev = null;
 60+
 61+ dec.opb.readinit(op.packet_base, op.packet, op.bytes);
 62+
 63+ /* get packet type */
 64+ type = (byte)dec.opb.read(8);
 65+ Debug.log(Debug.DEBUG, "decodePacketin: got packet type "+type);
 66+
 67+ /* ignore headers */
 68+ if ((type & 0x80) != 0)
 69+ return 0;
 70+
 71+ switch (type) {
 72+ case 0x00:
 73+ ev = new Event(dec.info);
 74+ ret = dec.decodeTextPacket(ev);
 75+
 76+ if(ret < 0) {
 77+ ev = null;
 78+ return (int) ret;
 79+ }
 80+
 81+ if(op.granulepos>-1)
 82+ granulepos=op.granulepos;
 83+ else{
 84+ if(granulepos==-1){
 85+ granulepos=0;
 86+ }
 87+ }
 88+
 89+ return 0;
 90+
 91+ case 0x01:
 92+ /* keepalive */
 93+ return 0;
 94+
 95+ case 0x7f:
 96+ /* eos */
 97+ return 1;
 98+
 99+ default:
 100+ Debug.debug("Kate packet type "+type+" ignored");
 101+ return 0;
 102+ }
 103+ }
 104+
 105+ /**
 106+ * Returns the event (if any) generated from the last decoded packet.
 107+ */
 108+ public Event decodeEventOut ()
 109+ {
 110+ return ev;
 111+ }
 112+
 113+ /**
 114+ * Returns, in seconds, absolute time of current packet in given
 115+ * logical stream
 116+ */
 117+ public double granuleTime(long granulepos)
 118+ {
 119+ return dec.granuleTime(granulepos);
 120+ }
 121+
 122+ /**
 123+ * Returns, in seconds, duration in granule units
 124+ */
 125+ public double granuleDuration(long granulepos)
 126+ {
 127+ return dec.granuleDuration(granulepos);
 128+ }
 129+}
Index: trunk/cortado/src/com/fluendo/jkate/Event.java
@@ -0,0 +1,69 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+public class Event
 25+{
 26+ public Info ki = null;
 27+
 28+ public long start;
 29+ public long duration;
 30+ public long backlink;
 31+ public double start_time;
 32+ public double end_time;
 33+
 34+ public int id = -1;
 35+
 36+ public KateTextEncoding text_encoding;
 37+ public KateTextDirectionality text_directionality;
 38+ public KateMarkupType markup_type;
 39+ public byte[] language;
 40+
 41+ public Region kr = null;
 42+ public Style ks = null;
 43+ public Style ks2 = null;
 44+ public Motion motions[] = null;
 45+ public Palette palette = null;
 46+ public Bitmap bitmap = null;
 47+ public FontMapping font_mapping = null;
 48+
 49+ public byte text[];
 50+
 51+ /**
 52+ * Initialize an event to safe defaults.
 53+ */
 54+ public Event(Info ki) {
 55+ this.ki = ki;
 56+ id = -1;
 57+ kr = null;
 58+ ks = null;
 59+ ks2 = null;
 60+ motions = null;
 61+ palette = null;
 62+ bitmap = null;
 63+ text = null;
 64+ font_mapping = null;
 65+ text_encoding = ki.text_encoding;
 66+ text_directionality = ki.text_directionality;
 67+ markup_type = ki.markup_type;
 68+ language = null;
 69+ }
 70+}
Index: trunk/cortado/src/com/fluendo/jkate/KateMotionSemantics.java
@@ -0,0 +1,119 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+public class KateMotionSemantics {
 25+ public static final KateMotionSemantics kate_motion_semantics_time = new KateMotionSemantics ();
 26+ public static final KateMotionSemantics kate_motion_semantics_z = new KateMotionSemantics ();
 27+ public static final KateMotionSemantics kate_motion_semantics_region_position = new KateMotionSemantics ();
 28+ public static final KateMotionSemantics kate_motion_semantics_region_size = new KateMotionSemantics ();
 29+ public static final KateMotionSemantics kate_motion_semantics_text_alignment_int = new KateMotionSemantics ();
 30+ public static final KateMotionSemantics kate_motion_semantics_text_alignment_ext = new KateMotionSemantics ();
 31+ public static final KateMotionSemantics kate_motion_semantics_text_position = new KateMotionSemantics ();
 32+ public static final KateMotionSemantics kate_motion_semantics_text_size = new KateMotionSemantics ();
 33+ public static final KateMotionSemantics kate_motion_semantics_marker1_position = new KateMotionSemantics ();
 34+ public static final KateMotionSemantics kate_motion_semantics_marker2_position = new KateMotionSemantics ();
 35+ public static final KateMotionSemantics kate_motion_semantics_marker3_position = new KateMotionSemantics ();
 36+ public static final KateMotionSemantics kate_motion_semantics_marker4_position = new KateMotionSemantics ();
 37+ public static final KateMotionSemantics kate_motion_semantics_glyph_pointer_1 = new KateMotionSemantics ();
 38+ public static final KateMotionSemantics kate_motion_semantics_glyph_pointer_2 = new KateMotionSemantics ();
 39+ public static final KateMotionSemantics kate_motion_semantics_glyph_pointer_3 = new KateMotionSemantics ();
 40+ public static final KateMotionSemantics kate_motion_semantics_glyph_pointer_4 = new KateMotionSemantics ();
 41+ public static final KateMotionSemantics kate_motion_semantics_text_color_rg = new KateMotionSemantics ();
 42+ public static final KateMotionSemantics kate_motion_semantics_text_color_ba = new KateMotionSemantics ();
 43+ public static final KateMotionSemantics kate_motion_semantics_background_color_rg = new KateMotionSemantics ();
 44+ public static final KateMotionSemantics kate_motion_semantics_background_color_ba = new KateMotionSemantics ();
 45+ public static final KateMotionSemantics kate_motion_semantics_draw_color_rg = new KateMotionSemantics ();
 46+ public static final KateMotionSemantics kate_motion_semantics_draw_color_ba = new KateMotionSemantics ();
 47+ public static final KateMotionSemantics kate_motion_semantics_style_morph = new KateMotionSemantics ();
 48+ public static final KateMotionSemantics kate_motion_semantics_text_path = new KateMotionSemantics ();
 49+ public static final KateMotionSemantics kate_motion_semantics_text_path_section = new KateMotionSemantics ();
 50+ public static final KateMotionSemantics kate_motion_semantics_draw = new KateMotionSemantics ();
 51+ public static final KateMotionSemantics kate_motion_semantics_text_visible_section = new KateMotionSemantics ();
 52+ public static final KateMotionSemantics kate_motion_semantics_horizontal_margins = new KateMotionSemantics ();
 53+ public static final KateMotionSemantics kate_motion_semantics_vertical_margins = new KateMotionSemantics ();
 54+ public static final KateMotionSemantics kate_motion_semantics_bitmap_position = new KateMotionSemantics ();
 55+ public static final KateMotionSemantics kate_motion_semantics_bitmap_size = new KateMotionSemantics ();
 56+ public static final KateMotionSemantics kate_motion_semantics_marker1_bitmap = new KateMotionSemantics ();
 57+ public static final KateMotionSemantics kate_motion_semantics_marker2_bitmap = new KateMotionSemantics ();
 58+ public static final KateMotionSemantics kate_motion_semantics_marker3_bitmap = new KateMotionSemantics ();
 59+ public static final KateMotionSemantics kate_motion_semantics_marker4_bitmap = new KateMotionSemantics ();
 60+ public static final KateMotionSemantics kate_motion_semantics_glyph_pointer_1_bitmap = new KateMotionSemantics ();
 61+ public static final KateMotionSemantics kate_motion_semantics_glyph_pointer_2_bitmap = new KateMotionSemantics ();
 62+ public static final KateMotionSemantics kate_motion_semantics_glyph_pointer_3_bitmap = new KateMotionSemantics ();
 63+ public static final KateMotionSemantics kate_motion_semantics_glyph_pointer_4_bitmap = new KateMotionSemantics ();
 64+ public static final KateMotionSemantics kate_motion_semantics_draw_width = new KateMotionSemantics ();
 65+
 66+ private static final KateMotionSemantics[] list = {
 67+ kate_motion_semantics_time,
 68+ kate_motion_semantics_z,
 69+ kate_motion_semantics_region_position,
 70+ kate_motion_semantics_region_size,
 71+ kate_motion_semantics_text_alignment_int,
 72+ kate_motion_semantics_text_alignment_ext,
 73+ kate_motion_semantics_text_position,
 74+ kate_motion_semantics_text_size,
 75+ kate_motion_semantics_marker1_position,
 76+ kate_motion_semantics_marker2_position,
 77+ kate_motion_semantics_marker3_position,
 78+ kate_motion_semantics_marker4_position,
 79+ kate_motion_semantics_glyph_pointer_1,
 80+ kate_motion_semantics_glyph_pointer_2,
 81+ kate_motion_semantics_glyph_pointer_3,
 82+ kate_motion_semantics_glyph_pointer_4,
 83+ kate_motion_semantics_text_color_rg,
 84+ kate_motion_semantics_text_color_ba,
 85+ kate_motion_semantics_background_color_rg,
 86+ kate_motion_semantics_background_color_ba,
 87+ kate_motion_semantics_draw_color_rg,
 88+ kate_motion_semantics_draw_color_ba,
 89+ kate_motion_semantics_style_morph,
 90+ kate_motion_semantics_text_path,
 91+ kate_motion_semantics_text_path_section,
 92+ kate_motion_semantics_draw,
 93+ kate_motion_semantics_text_visible_section,
 94+ kate_motion_semantics_horizontal_margins,
 95+ kate_motion_semantics_vertical_margins,
 96+ kate_motion_semantics_bitmap_position,
 97+ kate_motion_semantics_bitmap_size,
 98+ kate_motion_semantics_marker1_bitmap,
 99+ kate_motion_semantics_marker2_bitmap,
 100+ kate_motion_semantics_marker3_bitmap,
 101+ kate_motion_semantics_marker4_bitmap,
 102+ kate_motion_semantics_glyph_pointer_1_bitmap,
 103+ kate_motion_semantics_glyph_pointer_2_bitmap,
 104+ kate_motion_semantics_glyph_pointer_3_bitmap,
 105+ kate_motion_semantics_glyph_pointer_4_bitmap,
 106+ kate_motion_semantics_draw_width,
 107+ };
 108+
 109+ private KateMotionSemantics() {
 110+ }
 111+
 112+ /**
 113+ * Create a KateMotionSemantics object from an integer.
 114+ */
 115+ public static KateMotionSemantics CreateMotionSemantics(int idx) throws KateException {
 116+ if (idx < 0 || idx >= list.length)
 117+ throw new KateException("Motion semantics "+idx+" out of bounds");
 118+ return list[idx];
 119+ }
 120+}
Index: trunk/cortado/src/com/fluendo/jkate/RLE.java
@@ -0,0 +1,296 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+import com.jcraft.jogg.*;
 25+
 26+/**
 27+ * RLE decoding routines.
 28+ */
 29+public class RLE
 30+{
 31+ private static final int KATE_RLE_RUN_LENGTH_BITS_BASIC = 4;
 32+ private static final int KATE_RLE_RUN_LENGTH_BITS_BASIC_IN_DELTA = 3;
 33+ private static final int KATE_RLE_RUN_LENGTH_BITS_BASIC_STARTEND = 3;
 34+ private static final int KATE_RLE_RUN_LENGTH_BITS_BASIC_STOP = 6;
 35+ private static final int KATE_RLE_RUN_LENGTH_BITS_DELTA = 6;
 36+ private static final int KATE_RLE_RUN_LENGTH_BITS_BASIC_STARTEND_START = 9;
 37+ private static final int KATE_RLE_RUN_LENGTH_BITS_BASIC_STARTEND_END = 8;
 38+ private static final int KATE_RLE_RUN_LENGTH_BITS_BASIC_STOP_START = 8;
 39+ private static final int KATE_RLE_RUN_LENGTH_BITS_BASIC_IN_DELTA_STOP = 3;
 40+ private static final int KATE_RLE_RUN_LENGTH_BITS_DELTA_STOP = 5;
 41+ private static final int KATE_RLE_RUN_LENGTH_BITS_BASIC_ZERO = 8;
 42+ private static final int KATE_RLE_RUN_LENGTH_BITS_BASIC_NON_ZERO = 3;
 43+
 44+ private static final int KATE_RLE_TYPE_EMPTY = 0;
 45+ private static final int KATE_RLE_TYPE_BASIC = 1;
 46+ private static final int KATE_RLE_TYPE_DELTA = 2;
 47+ private static final int KATE_RLE_TYPE_BASIC_STOP = 3;
 48+ private static final int KATE_RLE_TYPE_BASIC_STARTEND = 4;
 49+ private static final int KATE_RLE_TYPE_DELTA_STOP = 5;
 50+ private static final int KATE_RLE_TYPE_BASIC_ZERO = 6;
 51+
 52+ private static final int KATE_RLE_TYPE_BITS = 3;
 53+
 54+ private static int decodeLineEmpty(Buffer opb, int width, byte pixels[], int offset, int bits, byte zero)
 55+ {
 56+ for (int n=0; n<width; ++n)
 57+ pixels[offset+n] = zero;
 58+ return 0;
 59+ }
 60+
 61+ private static int decodeLineBasic(Buffer opb, int width, byte pixels[], int offset, int bits, byte zero)
 62+ {
 63+ final int run_length_bits = KATE_RLE_RUN_LENGTH_BITS_BASIC;
 64+ int p = 0;
 65+ int count = width;
 66+ while (count > 0) {
 67+ int run_length = 1+opb.read(run_length_bits);
 68+ if (run_length == 0 || run_length > count)
 69+ return -1;
 70+ byte value = (byte)opb.read(bits);
 71+ for (int n=0; n<run_length; ++n)
 72+ pixels[offset+p++] = value;
 73+ count -= run_length;
 74+ }
 75+ return 0;
 76+ }
 77+
 78+ private static int decodeLineDelta(Buffer opb, int width, byte pixels[], int offset, int bits, byte zero)
 79+ {
 80+ final int run_length_delta_bits = KATE_RLE_RUN_LENGTH_BITS_DELTA;
 81+ final int run_length_basic_bits = KATE_RLE_RUN_LENGTH_BITS_BASIC_IN_DELTA;
 82+ int p = 0;
 83+ int count = width;
 84+ while (count > 0) {
 85+ int type = opb.read1();
 86+ if (type != 0) {
 87+ int run_length = 1+opb.read(run_length_delta_bits);
 88+ if (run_length == 0 || run_length > count)
 89+ return -1;
 90+ if (offset > 0) {
 91+ for (int n=0; n<run_length; ++n) {
 92+ pixels[offset+p] = pixels[offset+p-width];
 93+ ++p;
 94+ }
 95+ }
 96+ else {
 97+ for (int n=0; n<run_length; ++n)
 98+ pixels[offset+p++] = zero;
 99+ }
 100+ count -= run_length;
 101+ }
 102+ else {
 103+ int run_length = 1 + opb.read(run_length_basic_bits);
 104+ if (run_length == 0 || run_length > count)
 105+ return -1;
 106+ byte value = (byte)opb.read(bits);
 107+ for (int n=0; n<run_length; ++n)
 108+ pixels[offset+p++] = value;
 109+ count -= run_length;
 110+ }
 111+ }
 112+ return 0;
 113+ }
 114+
 115+ private static int decodeLineBasicStartEnd(Buffer opb, int width, byte pixels[], int offset, int bits, byte zero)
 116+ {
 117+ final int run_length_bits = KATE_RLE_RUN_LENGTH_BITS_BASIC_STARTEND;
 118+ int run_length;
 119+ int count = width;
 120+ int p = 0;
 121+
 122+ run_length = opb.read(KATE_RLE_RUN_LENGTH_BITS_BASIC_STARTEND_START);
 123+ if (run_length > 0) {
 124+ if (run_length > count)
 125+ return -1;
 126+ for (int n=0; n<run_length; ++n)
 127+ pixels[offset+p++] = zero;
 128+ count -= run_length;
 129+ }
 130+
 131+ run_length = opb.read(KATE_RLE_RUN_LENGTH_BITS_BASIC_STARTEND_END);
 132+ if (run_length > 0) {
 133+ if (run_length > count)
 134+ return -1;
 135+ for (int n=0; n<run_length; ++n)
 136+ pixels[offset+width-1-n] = zero;
 137+ count -= run_length;
 138+ }
 139+
 140+ while (count > 0) {
 141+ run_length = 1 + opb.read(run_length_bits);
 142+ if (run_length == 0 || run_length > count)
 143+ return -1;
 144+ byte value = (byte)opb.read(bits);
 145+ for (int n=0; n<run_length; ++n)
 146+ pixels[offset+p++] = value;
 147+ count -= run_length;
 148+ }
 149+
 150+ return 0;
 151+ }
 152+
 153+ private static int decodeLineBasicStop(Buffer opb, int width, byte pixels[], int offset, int bits, byte zero)
 154+ {
 155+ final int run_length_bits = KATE_RLE_RUN_LENGTH_BITS_BASIC_STOP;
 156+ int run_length;
 157+ int count = width;
 158+ int p = 0;
 159+
 160+ run_length = opb.read(KATE_RLE_RUN_LENGTH_BITS_BASIC_STOP_START);
 161+ if (run_length > 0) {
 162+ if (run_length > count)
 163+ return -1;
 164+ for (int n=0; n<run_length; ++n)
 165+ pixels[offset+p++] = zero;
 166+ count -= run_length;
 167+ }
 168+
 169+ while (count > 0) {
 170+ run_length = opb.read(run_length_bits);
 171+ if (run_length > count)
 172+ return -1;
 173+ if (run_length == 0) {
 174+ for (int n=0; n<run_length; ++n)
 175+ pixels[offset+p++] = zero;
 176+ break;
 177+ }
 178+ byte value = (byte)opb.read(bits);
 179+ for (int n=0; n<run_length; ++n)
 180+ pixels[offset+p++] = value;
 181+ count -= run_length;
 182+ }
 183+
 184+ return 0;
 185+ }
 186+
 187+ private static int decodeLineDeltaStop(Buffer opb, int width, byte pixels[], int offset, int bits, byte zero)
 188+ {
 189+ final int run_length_delta_bits = KATE_RLE_RUN_LENGTH_BITS_DELTA_STOP;
 190+ final int run_length_basic_bits = KATE_RLE_RUN_LENGTH_BITS_BASIC_IN_DELTA_STOP;
 191+ int run_length;
 192+ int count = width;
 193+ int p = 0;
 194+
 195+ while (count > 0) {
 196+ int type = opb.read1();
 197+ if (type != 0) {
 198+ run_length = 1 + opb.read(run_length_delta_bits);
 199+ if (run_length == 0 || run_length > count)
 200+ return -1;
 201+ if (offset > 0) {
 202+ for (int n=0; n<run_length; ++n) {
 203+ pixels[offset+p] = pixels[offset+p-width];
 204+ ++p;
 205+ }
 206+ }
 207+ else {
 208+ for (int n=0; n<run_length; ++n)
 209+ pixels[offset+p++] = zero;
 210+ }
 211+ }
 212+ else {
 213+ run_length = opb.read(run_length_basic_bits);
 214+ if (run_length == 0) {
 215+ for (int n=0; n<run_length; ++n)
 216+ pixels[offset+p++] = zero;
 217+ break;
 218+ }
 219+ if (run_length > count)
 220+ return -1;
 221+ byte value = (byte)opb.read(bits);
 222+ for (int n=0; n<run_length; ++n)
 223+ pixels[offset+p++] = value;
 224+ }
 225+ count -= run_length;
 226+ }
 227+
 228+ return 0;
 229+ }
 230+
 231+ private static int decodeLineBasicZero(Buffer opb, int width, byte pixels[], int offset, int bits, byte zero)
 232+ {
 233+ final int run_length_bits_zero = KATE_RLE_RUN_LENGTH_BITS_BASIC_ZERO;
 234+ final int run_length_bits_non_zero = KATE_RLE_RUN_LENGTH_BITS_BASIC_NON_ZERO;
 235+ int run_length;
 236+ int count = width;
 237+ int p = 0;
 238+
 239+ while (count > 0) {
 240+ byte value = (byte)opb.read(bits);
 241+ if (value == zero) {
 242+ run_length = 1 + opb.read(run_length_bits_zero);
 243+ }
 244+ else {
 245+ run_length = 1 + opb.read(run_length_bits_non_zero);
 246+ }
 247+ if (run_length == 0 || run_length > count)
 248+ return -1;
 249+ for (int n=0; n<run_length; ++n)
 250+ pixels[offset+p++] = value;
 251+ count -= run_length;
 252+ }
 253+
 254+ return 0;
 255+ }
 256+
 257+ public static byte[] decodeRLE(Buffer opb, int width, int height, int bpp)
 258+ {
 259+ byte[] pixels = new byte[width*height];
 260+ int offset = 0;
 261+ int ret;
 262+ byte zero = (byte)opb.read(bpp);
 263+ while (height > 0) {
 264+ int type = opb.read(KATE_RLE_TYPE_BITS);
 265+ switch (type) {
 266+ case KATE_RLE_TYPE_EMPTY:
 267+ ret = decodeLineEmpty(opb, width, pixels, offset, bpp, zero);
 268+ break;
 269+ case KATE_RLE_TYPE_DELTA:
 270+ ret = decodeLineDelta(opb, width, pixels, offset, bpp, zero);
 271+ break;
 272+ case KATE_RLE_TYPE_BASIC:
 273+ ret = decodeLineBasic(opb, width, pixels, offset, bpp, zero);
 274+ break;
 275+ case KATE_RLE_TYPE_BASIC_STARTEND:
 276+ ret = decodeLineBasicStartEnd(opb, width, pixels, offset, bpp, zero);
 277+ break;
 278+ case KATE_RLE_TYPE_BASIC_STOP:
 279+ ret = decodeLineBasicStop(opb, width, pixels, offset, bpp, zero);
 280+ break;
 281+ case KATE_RLE_TYPE_DELTA_STOP:
 282+ ret = decodeLineDeltaStop(opb, width, pixels, offset, bpp, zero);
 283+ break;
 284+ case KATE_RLE_TYPE_BASIC_ZERO:
 285+ ret = decodeLineBasicZero(opb, width, pixels, offset, bpp, zero);
 286+ break;
 287+ default:
 288+ return null;
 289+ }
 290+ if (ret != 0)
 291+ return null;
 292+ offset += width;
 293+ --height;
 294+ }
 295+ return pixels;
 296+ }
 297+}
Index: trunk/cortado/src/com/fluendo/jkate/FontMapping.java
@@ -0,0 +1,29 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+/**
 25+ * A set of ranges defining a mapping from code points to bitmaps.
 26+ */
 27+class FontMapping
 28+{
 29+ FontRange ranges[];
 30+}
Index: trunk/cortado/src/com/fluendo/jkate/Region.java
@@ -0,0 +1,35 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+/**
 25+ * A region definition, for placement of text/images.
 26+ */
 27+public class Region
 28+{
 29+ public KateSpaceMetric metric;
 30+ public int x;
 31+ public int y;
 32+ public int w;
 33+ public int h;
 34+ public int style;
 35+ public boolean clip;
 36+}
Index: trunk/cortado/src/com/fluendo/jkate/KateWrapMode.java
@@ -0,0 +1,43 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+public class KateWrapMode {
 25+ public static final KateWrapMode kate_wrap_word = new KateWrapMode ();
 26+ public static final KateWrapMode kate_wrap_none = new KateWrapMode ();
 27+
 28+ private static final KateWrapMode[] list = {
 29+ kate_wrap_word,
 30+ kate_wrap_none,
 31+ };
 32+
 33+ private KateWrapMode() {
 34+ }
 35+
 36+ /**
 37+ * Create a KateWrapMode object from an integer.
 38+ */
 39+ public static KateWrapMode CreateWrapMode(int idx) throws KateException {
 40+ if (idx < 0 || idx >= list.length)
 41+ throw new KateException("Wrap mode "+idx+" out of bounds");
 42+ return list[idx];
 43+ }
 44+}
Index: trunk/cortado/src/com/fluendo/jkate/Decode.java
@@ -0,0 +1,238 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+import com.jcraft.jogg.*;
 25+import com.fluendo.utils.*;
 26+
 27+public final class Decode {
 28+
 29+ Buffer opb = new Buffer();
 30+ Info info;
 31+
 32+ public Decode (Info i) {
 33+ info = i;
 34+ }
 35+
 36+ /**
 37+ * Decode a text data packet (packet type 0x00), and fills the passed event
 38+ * from the decoded data.
 39+ */
 40+ int decodeTextPacket(Event ev)
 41+ {
 42+ ev.ki = info;
 43+
 44+ ev.start = Bitwise.read64(opb);
 45+ ev.duration = Bitwise.read64(opb);
 46+ ev.backlink = Bitwise.read64(opb);
 47+
 48+ ev.start_time = granuleDuration(ev.start);
 49+ ev.end_time = ev.start_time+granuleDuration(ev.duration);
 50+
 51+ /* text */
 52+ int len = Bitwise.read32(opb);
 53+ ev.text = new byte[len];
 54+ Bitwise.readbuf(opb, ev.text, len);
 55+
 56+ /* event ID */
 57+ ev.id = -1;
 58+ if (opb.read1() != 0) {
 59+ ev.id = Bitwise.read32v(opb);
 60+ }
 61+
 62+ /* motions */
 63+ ev.motions = null;
 64+ if (opb.read1() != 0) {
 65+ int nmotions = Bitwise.read32v(opb);
 66+ if (nmotions < 0)
 67+ return -1;
 68+ ev.motions = new Motion[nmotions];
 69+ for (int n=0; n<nmotions; ++n) {
 70+ if (opb.read1() != 0) {
 71+ int idx = Bitwise.read32v(opb);
 72+ if (idx < 0 || idx >= info.motions.length)
 73+ return -1;
 74+ ev.motions[n] = info.motions[idx];
 75+ }
 76+ else {
 77+ try {
 78+ ev.motions[n] = info.unpackMotion(opb);
 79+ }
 80+ catch (KateException ke) {
 81+ return Result.KATE_E_BAD_PACKET;
 82+ }
 83+ }
 84+ }
 85+ }
 86+
 87+ /* overrides */
 88+ if (opb.read1() != 0) {
 89+ try {
 90+ if (opb.read1() != 0)
 91+ ev.text_encoding = KateTextEncoding.CreateTextEncoding(opb.read(8));
 92+ if (opb.read1() != 0)
 93+ ev.text_directionality = KateTextDirectionality.CreateTextDirectionality(opb.read(8));
 94+ }
 95+ catch (KateException ke) {
 96+ return Result.KATE_E_BAD_PACKET;
 97+ }
 98+
 99+ /* language override */
 100+ if (opb.read1() != 0) {
 101+ int nbytes = Bitwise.read32v(opb);
 102+ if (nbytes < 0)
 103+ return Result.KATE_E_BAD_PACKET;
 104+ if (nbytes > 0) {
 105+ ev.language=new byte[nbytes];
 106+ Bitwise.readbuf(opb, ev.language, nbytes);
 107+ }
 108+ }
 109+
 110+ /* region override */
 111+ if (opb.read1() != 0) {
 112+ int idx = Bitwise.read32v(opb);
 113+ if (idx < 0 || idx >= info.regions.length)
 114+ return Result.KATE_E_BAD_PACKET;
 115+ ev.kr = info.regions[idx];
 116+ }
 117+ if (opb.read1() != 0) {
 118+ try {
 119+ ev.kr = info.unpackRegion(opb);
 120+ }
 121+ catch (KateException ke) {
 122+ return Result.KATE_E_BAD_PACKET;
 123+ }
 124+ }
 125+
 126+ /* style override */
 127+ if (opb.read1() != 0) {
 128+ int idx = Bitwise.read32v(opb);
 129+ if (idx < 0 || idx >= info.styles.length)
 130+ return Result.KATE_E_BAD_PACKET;
 131+ ev.ks = info.styles[idx];
 132+ }
 133+ if (opb.read1() != 0) {
 134+ try {
 135+ ev.ks = info.unpackStyle(opb);
 136+ }
 137+ catch (KateException ke) {
 138+ return Result.KATE_E_BAD_PACKET;
 139+ }
 140+ }
 141+ if (opb.read1() != 0) {
 142+ int idx = Bitwise.read32v(opb);
 143+ if (idx < 0 || idx >= info.styles.length)
 144+ return Result.KATE_E_BAD_PACKET;
 145+ ev.ks2 = info.styles[idx];
 146+ }
 147+ if (opb.read1() != 0) {
 148+ try {
 149+ ev.ks2 = info.unpackStyle(opb);
 150+ }
 151+ catch (KateException ke) {
 152+ return Result.KATE_E_BAD_PACKET;
 153+ }
 154+ }
 155+
 156+ /* font mapping */
 157+ if (opb.read1() != 0) {
 158+ int idx = Bitwise.read32v(opb);
 159+ if (idx < 0 || idx >= info.font_mappings.length)
 160+ return Result.KATE_E_BAD_PACKET;
 161+ ev.font_mapping = info.font_mappings[idx];
 162+ }
 163+ }
 164+
 165+ /* new in 0.2: palettes/bitmaps/markup type */
 166+ if (((info.bitstream_version_major<<8) | info.bitstream_version_minor) >= 0x0002) {
 167+ Bitwise.read32v(opb);
 168+ if (opb.read1() != 0) {
 169+ if (opb.read1() != 0) {
 170+ int idx = Bitwise.read32v(opb);
 171+ if (idx < 0 || idx >= info.palettes.length)
 172+ return Result.KATE_E_BAD_PACKET;
 173+ ev.palette = info.palettes[idx];
 174+ }
 175+ if (opb.read1() != 0) {
 176+ try {
 177+ ev.palette = info.unpackPalette(opb);
 178+ }
 179+ catch (KateException e) {
 180+ return Result.KATE_E_BAD_PACKET;
 181+ }
 182+ }
 183+ if (opb.read1() != 0) {
 184+ int idx = Bitwise.read32v(opb);
 185+ if (idx < 0 || idx >= info.bitmaps.length)
 186+ return Result.KATE_E_BAD_PACKET;
 187+ ev.bitmap = info.bitmaps[idx];
 188+ }
 189+ if (opb.read1() != 0) {
 190+ try {
 191+ ev.bitmap = info.unpackBitmap(opb);
 192+ }
 193+ catch (KateException e) {
 194+ return Result.KATE_E_BAD_PACKET;
 195+ }
 196+ }
 197+ if (opb.read1() != 0) {
 198+ try {
 199+ ev.markup_type = KateMarkupType.CreateMarkupType(opb.read(8));
 200+ }
 201+ catch (KateException e) {
 202+ return Result.KATE_E_BAD_PACKET;
 203+ }
 204+ }
 205+ }
 206+ }
 207+
 208+// TODO: remainder
 209+ return 0;
 210+ }
 211+
 212+ /**
 213+ * Convert a granule to a time.
 214+ */
 215+ public double granuleTime(long granulepos)
 216+ {
 217+ if(granulepos>=0){
 218+ long base=granulepos>>info.granule_shift;
 219+ long offset=granulepos-(base<<info.granule_shift);
 220+
 221+ return (base+offset)*
 222+ ((double)info.gps_denominator/info.gps_numerator);
 223+ }
 224+ return(-1);
 225+ }
 226+
 227+ /**
 228+ * Convert a time in granule units to a duration.
 229+ */
 230+ public double granuleDuration(long granule)
 231+ {
 232+ if(granule>=0){
 233+ return (granule)*
 234+ ((double)info.gps_denominator/info.gps_numerator);
 235+ }
 236+ return(-1);
 237+ }
 238+
 239+}
Index: trunk/cortado/src/com/fluendo/jkate/FontRange.java
@@ -0,0 +1,32 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+/**
 25+ * A code point range mapping to a set of bitmaps.
 26+ */
 27+public class FontRange
 28+{
 29+ int first_code_point;
 30+ int last_code_point;
 31+ int first_bitmap;
 32+}
 33+
Index: trunk/cortado/src/com/fluendo/jkate/KateBitmapType.java
@@ -0,0 +1,43 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+public class KateBitmapType {
 25+ public static final KateBitmapType kate_bitmap_type_paletted = new KateBitmapType ();
 26+ public static final KateBitmapType kate_bitmap_type_png = new KateBitmapType ();
 27+
 28+ private static final KateBitmapType[] list = {
 29+ kate_bitmap_type_paletted,
 30+ kate_bitmap_type_png,
 31+ };
 32+
 33+ private KateBitmapType() {
 34+ }
 35+
 36+ /**
 37+ * Create a KateBitmapType object from an integer.
 38+ */
 39+ public static KateBitmapType CreateBitmapType(int idx) throws KateException {
 40+ if (idx < 0 || idx >= list.length)
 41+ throw new KateException("Bitmap type "+idx+" out of bounds");
 42+ return list[idx];
 43+ }
 44+}
Index: trunk/cortado/src/com/fluendo/jkate/Curve.java
@@ -0,0 +1,31 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+/**
 25+ * A curve definition, splines, segments, etc.
 26+ */
 27+public class Curve
 28+{
 29+ public KateCurveType type;
 30+ public int npts;
 31+ public double pts[][];
 32+}
Index: trunk/cortado/src/com/fluendo/jkate/KateMotionMapping.java
@@ -0,0 +1,51 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+public class KateMotionMapping {
 25+ public static final KateMotionMapping kate_motion_mapping_none = new KateMotionMapping ();
 26+ public static final KateMotionMapping kate_motion_mapping_frame = new KateMotionMapping ();
 27+ public static final KateMotionMapping kate_motion_mapping_window = new KateMotionMapping ();
 28+ public static final KateMotionMapping kate_motion_mapping_region = new KateMotionMapping ();
 29+ public static final KateMotionMapping kate_motion_mapping_event_duration = new KateMotionMapping ();
 30+ public static final KateMotionMapping kate_motion_mapping_bitmap_size = new KateMotionMapping ();
 31+
 32+ private static final KateMotionMapping[] list = {
 33+ kate_motion_mapping_none,
 34+ kate_motion_mapping_frame,
 35+ kate_motion_mapping_window,
 36+ kate_motion_mapping_region,
 37+ kate_motion_mapping_event_duration,
 38+ kate_motion_mapping_bitmap_size,
 39+ };
 40+
 41+ private KateMotionMapping() {
 42+ }
 43+
 44+ /**
 45+ * Create a KateMotionMapping object from an integer.
 46+ */
 47+ public static KateMotionMapping CreateMotionMapping(int idx) throws KateException {
 48+ if (idx < 0 || idx >= list.length)
 49+ throw new KateException("Motion mapping "+idx+" out of bounds");
 50+ return list[idx];
 51+ }
 52+}
Index: trunk/cortado/src/com/fluendo/jkate/KateCurveType.java
@@ -0,0 +1,51 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+public class KateCurveType {
 25+ public static final KateCurveType kate_curve_none = new KateCurveType ();
 26+ public static final KateCurveType kate_curve_static = new KateCurveType ();
 27+ public static final KateCurveType kate_curve_linear = new KateCurveType ();
 28+ public static final KateCurveType kate_curve_catmull_rom_spline = new KateCurveType ();
 29+ public static final KateCurveType kate_curve_bezier_cubic_spline = new KateCurveType ();
 30+ public static final KateCurveType kate_curve_bspline = new KateCurveType ();
 31+
 32+ private static final KateCurveType[] list = {
 33+ kate_curve_none,
 34+ kate_curve_static,
 35+ kate_curve_linear,
 36+ kate_curve_catmull_rom_spline,
 37+ kate_curve_bezier_cubic_spline,
 38+ kate_curve_bspline,
 39+ };
 40+
 41+ private KateCurveType() {
 42+ }
 43+
 44+ /**
 45+ * Create a KateCurveType object from an integer.
 46+ */
 47+ public static KateCurveType CreateCurveType(int idx) throws KateException {
 48+ if (idx < 0 || idx >= list.length)
 49+ throw new KateException("Curve type "+idx+" out of bounds");
 50+ return list[idx];
 51+ }
 52+}
Index: trunk/cortado/src/com/fluendo/jkate/Info.java
@@ -0,0 +1,742 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+import com.jcraft.jogg.*;
 25+import com.fluendo.utils.*;
 26+
 27+public class Info {
 28+ public int bitstream_version_major = -1;
 29+ public int bitstream_version_minor = -1;
 30+ public KateTextEncoding text_encoding;
 31+ public KateTextDirectionality text_directionality;
 32+ public int num_headers = 0;
 33+ public int granule_shift;
 34+ public int gps_numerator;
 35+ public int gps_denominator;
 36+ public byte language[];
 37+ public byte category[];
 38+ public Region regions[];
 39+ public Style styles[];
 40+ public Curve curves[];
 41+ public Motion motions[];
 42+ public Palette palettes[];
 43+ public Bitmap bitmaps[];
 44+ public FontRange font_ranges[];
 45+ public FontMapping font_mappings[];
 46+
 47+ public KateMarkupType markup_type;
 48+ public int original_canvas_width;
 49+ public int original_canvas_height;
 50+
 51+ /* used to track which header we need to decode next */
 52+ private int probe = 0;
 53+
 54+ /**
 55+ * Read a packet canvas size (width or height).
 56+ * Format defined in the Kate specification.
 57+ */
 58+ private static int read_canvas_size(Buffer opb)
 59+ {
 60+ int value, base, shift;
 61+
 62+ value = opb.read(8) | (opb.read(8)<<8);
 63+ base = value>>4;
 64+ shift = value&15;
 65+ return base<<shift;
 66+ }
 67+
 68+ /**
 69+ * Decodes a Kate info header packet and fills the class data with
 70+ * what was found in it.
 71+ */
 72+ private int unpackInfo(Buffer opb){
 73+ int reserved, tmp;
 74+
 75+ bitstream_version_major = (byte)opb.read(8);
 76+ bitstream_version_minor = (byte)opb.read(8);
 77+ Debug.info("Kate bitstream v"+bitstream_version_major+"."+bitstream_version_minor);
 78+
 79+ if (bitstream_version_major > 0)
 80+ return Result.KATE_E_VERSION;
 81+
 82+ num_headers = (int)opb.read(8);
 83+ if (num_headers < 1)
 84+ return Result.KATE_E_BAD_PACKET;
 85+ tmp = opb.read(8);
 86+ if (tmp != 0)
 87+ return Result.KATE_E_BAD_PACKET;
 88+ try {
 89+ text_encoding = KateTextEncoding.CreateTextEncoding(tmp);
 90+ text_directionality = KateTextDirectionality.CreateTextDirectionality(opb.read(8));
 91+ }
 92+ catch (KateException e) {
 93+ return Result.KATE_E_BAD_PACKET;
 94+ }
 95+ reserved = opb.read(8);
 96+ if (bitstream_version_major==0 && bitstream_version_minor<3) {
 97+ if (reserved != 0)
 98+ return Result.KATE_E_BAD_PACKET;
 99+ }
 100+ granule_shift = opb.read(8);
 101+
 102+ original_canvas_width = read_canvas_size(opb);
 103+ original_canvas_height = read_canvas_size(opb);
 104+
 105+ reserved = Bitwise.read32(opb);
 106+ if (bitstream_version_major==0 && bitstream_version_minor<3) {
 107+ if (reserved != 0)
 108+ return Result.KATE_E_BAD_PACKET;
 109+ }
 110+
 111+ gps_numerator = Bitwise.read32(opb);
 112+ gps_denominator = Bitwise.read32(opb);
 113+
 114+ if (granule_shift >= 64)
 115+ return Result.KATE_E_BAD_PACKET;
 116+ if (gps_numerator == 0 || gps_denominator == 0)
 117+ return Result.KATE_E_BAD_PACKET;
 118+
 119+ language=new byte[16];
 120+ Bitwise.readbuf(opb, language, 16);
 121+ if (language[15] != 0)
 122+ return Result.KATE_E_BAD_PACKET;
 123+
 124+ category=new byte[16];
 125+ Bitwise.readbuf(opb, category, 16);
 126+ if (category[15] != 0)
 127+ return Result.KATE_E_BAD_PACKET;
 128+
 129+ /* end of packet */
 130+ if (opb.read(1) != -1)
 131+ return (Result.KATE_E_BAD_PACKET);
 132+
 133+ return(0);
 134+ }
 135+
 136+ /**
 137+ * Checks that we have reached the end of the packet.
 138+ */
 139+ static int checkEOP(Buffer opb) {
 140+ int bits = 7 & (8 - (opb.bits()&7));
 141+ if (bits > 0) {
 142+ if (opb.read(bits) != 0)
 143+ return Result.KATE_E_BAD_PACKET;
 144+ }
 145+ if (opb.look1() != -1)
 146+ return (Result.KATE_E_BAD_PACKET);
 147+ return 0;
 148+ }
 149+
 150+ /**
 151+ * Decodes a Vorbis comment packet.
 152+ * straight copy of the jheora one
 153+ */
 154+ private int unpackComment (Comment kc, Buffer opb)
 155+ {
 156+ int i;
 157+ int len;
 158+ byte[] tmp;
 159+ int comments;
 160+
 161+ len = Bitwise.read32(opb);
 162+ if(len<0)
 163+ return(Result.KATE_E_BAD_PACKET);
 164+
 165+ tmp=new byte[len];
 166+ Bitwise.readbuf(opb, tmp, len);
 167+ kc.vendor=new String(tmp);
 168+
 169+ comments = Bitwise.read32(opb);
 170+ if(comments<0) {
 171+ kc.clear();
 172+ return Result.KATE_E_BAD_PACKET;
 173+ }
 174+ kc.user_comments=new String[comments];
 175+ for(i=0;i<comments;i++){
 176+ len = Bitwise.read32(opb);
 177+ if(len<0) {
 178+ kc.clear();
 179+ return Result.KATE_E_BAD_PACKET;
 180+ }
 181+
 182+ tmp=new byte[len];
 183+ Bitwise.readbuf(opb,tmp,len);
 184+ kc.user_comments[i]=new String(tmp);
 185+ }
 186+ return 0;
 187+ }
 188+
 189+ /**
 190+ * Decode a single region.
 191+ */
 192+ public Region unpackRegion (Buffer opb) throws KateException
 193+ {
 194+ Region kr = new Region();
 195+
 196+ kr.metric = KateSpaceMetric.CreateSpaceMetric(opb.read(8));
 197+ kr.x = Bitwise.read32v(opb);
 198+ kr.y = Bitwise.read32v(opb);
 199+ kr.w = Bitwise.read32v(opb);
 200+ kr.h = Bitwise.read32v(opb);
 201+ kr.style = Bitwise.read32v(opb);
 202+
 203+ if (((bitstream_version_major<<8) | bitstream_version_minor) >= 0x0002) {
 204+ Bitwise.read32v(opb);
 205+ kr.clip = (opb.read1() != 0);
 206+ }
 207+ else {
 208+ kr.clip = false;
 209+ }
 210+
 211+ Bitwise.skipWarp(opb);
 212+
 213+ return kr;
 214+ }
 215+
 216+ /**
 217+ * Decode the regions header packet.
 218+ */
 219+ private int unpackRegions (Buffer opb)
 220+ {
 221+ int nregions = Bitwise.read32v(opb);
 222+ if (nregions < 0) return Result.KATE_E_BAD_PACKET;
 223+ regions = new Region[nregions];
 224+ for (int n=0; n<nregions; ++n) {
 225+ try {
 226+ regions[n] = unpackRegion(opb);
 227+ }
 228+ catch (KateException ke) {
 229+ regions = null;
 230+ return Result.KATE_E_BAD_PACKET;
 231+ }
 232+ }
 233+
 234+ Bitwise.skipWarp(opb);
 235+
 236+ /* end of packet */
 237+ return checkEOP(opb);
 238+ }
 239+
 240+ /**
 241+ * Decode a color.
 242+ */
 243+ private Color unpackColor (Buffer opb)
 244+ {
 245+ Color color = new Color();
 246+ color.r = (byte)opb.read(8);
 247+ color.g = (byte)opb.read(8);
 248+ color.b = (byte)opb.read(8);
 249+ color.a = (byte)opb.read(8);
 250+ return color;
 251+ }
 252+
 253+ /**
 254+ * Decode a single style.
 255+ */
 256+ public Style unpackStyle (Buffer opb) throws KateException
 257+ {
 258+ Style ks = new Style();
 259+
 260+ double floats[][] = Bitwise.readFloats(opb, 8, 1);
 261+ int idx = 0;
 262+ ks.halign = floats[0][idx++];
 263+ ks.valign = floats[0][idx++];
 264+ ks.font_width = floats[0][idx++];
 265+ ks.font_height = floats[0][idx++];
 266+ ks.left_margin = floats[0][idx++];
 267+ ks.top_margin = floats[0][idx++];
 268+ ks.right_margin = floats[0][idx++];
 269+ ks.bottom_margin = floats[0][idx++];
 270+ ks.text_color = unpackColor(opb);
 271+ ks.background_color = unpackColor(opb);
 272+ ks.draw_color = unpackColor(opb);
 273+ ks.font_metric = KateSpaceMetric.CreateSpaceMetric(opb.read(8));
 274+ ks.margin_metric = KateSpaceMetric.CreateSpaceMetric(opb.read(8));
 275+ ks.bold = opb.read1() != 0;
 276+ ks.italics = opb.read1() != 0;
 277+ ks.underline = opb.read1() != 0;
 278+ ks.strike = opb.read1() != 0;
 279+
 280+ if (((bitstream_version_major<<8) | bitstream_version_minor) >= 0x0002) {
 281+ Bitwise.read32v(opb);
 282+ ks.justify = opb.read1() != 0;
 283+ int len = Bitwise.read32v(opb);
 284+ if (len < 0)
 285+ throw new KateBadPacketException();
 286+ byte s[] = new byte[len];
 287+ Bitwise.readbuf(opb, s, len);
 288+ ks.font = new String(s);
 289+ }
 290+ else {
 291+ ks.justify = false;
 292+ ks.font = null;
 293+ }
 294+
 295+ if (((bitstream_version_major<<8) | bitstream_version_minor) >= 0x0004) {
 296+ Bitwise.read32v(opb);
 297+ ks.wrap_mode = KateWrapMode.CreateWrapMode(Bitwise.read32v(opb));
 298+ }
 299+ else {
 300+ ks.wrap_mode = KateWrapMode.kate_wrap_word;
 301+ }
 302+
 303+ Bitwise.skipWarp(opb);
 304+
 305+ return ks;
 306+ }
 307+
 308+ /**
 309+ * Decode the styles header packet.
 310+ */
 311+ private int unpackStyles (Buffer opb)
 312+ {
 313+ int nstyles = Bitwise.read32v(opb);
 314+ if (nstyles < 0) return Result.KATE_E_BAD_PACKET;
 315+ styles = new Style[nstyles];
 316+ for (int n=0; n<nstyles; ++n) {
 317+ try {
 318+ styles[n] = unpackStyle(opb);
 319+ }
 320+ catch (KateException ke) {
 321+ styles = null;
 322+ return Result.KATE_E_BAD_PACKET;
 323+ }
 324+ }
 325+
 326+ Bitwise.skipWarp(opb);
 327+
 328+ /* end of packet */
 329+ return checkEOP(opb);
 330+ }
 331+
 332+ /**
 333+ * Decode a single curve.
 334+ */
 335+ private Curve unpackCurve (Buffer opb) throws KateException
 336+ {
 337+ Curve kc = new Curve();
 338+
 339+ kc.type = KateCurveType.CreateCurveType(opb.read(8));
 340+ kc.npts = Bitwise.read32v(opb);
 341+ if (kc.npts < 0)
 342+ throw new KateBadPacketException();
 343+ Bitwise.skipWarp(opb);
 344+
 345+ kc.pts = Bitwise.readFloats(opb, kc.npts, 2);
 346+
 347+ return kc;
 348+ }
 349+
 350+ /**
 351+ * Decode the curves header packet.
 352+ */
 353+ private int unpackCurves (Buffer opb)
 354+ {
 355+ int ncurves = Bitwise.read32v(opb);
 356+ if (ncurves < 0) return Result.KATE_E_BAD_PACKET;
 357+ curves = new Curve[ncurves];
 358+ for (int n=0; n<ncurves; ++n) {
 359+ try {
 360+ curves[n] = unpackCurve(opb);
 361+ }
 362+ catch (KateException ke) {
 363+ curves = null;
 364+ return Result.KATE_E_BAD_PACKET;
 365+ }
 366+ }
 367+
 368+ Bitwise.skipWarp(opb);
 369+
 370+ /* end of packet */
 371+ return checkEOP(opb);
 372+ }
 373+
 374+ /**
 375+ * Decode a single motion.
 376+ */
 377+ public Motion unpackMotion (Buffer opb) throws KateException
 378+ {
 379+ Motion km = new Motion();
 380+
 381+ int ncurves = Bitwise.read32v(opb);
 382+ if (ncurves < 0)
 383+ throw new KateBadPacketException();
 384+ km.curves = new Curve[ncurves];
 385+ for (int n=0; n<ncurves; ++n) {
 386+ if (opb.read1() != 0) {
 387+ int idx = Bitwise.read32v(opb);
 388+ if (idx < 0 || idx >= this.curves.length)
 389+ throw new KateBadPacketException();
 390+ km.curves[n] = this.curves[idx];
 391+ }
 392+ else {
 393+ km.curves[n] = unpackCurve(opb);
 394+ }
 395+ }
 396+
 397+ double floats[][] = Bitwise.readFloats(opb, ncurves, 1);
 398+ km.durations = new double[ncurves];
 399+ for (int n=0; n<ncurves; ++n) {
 400+ km.durations[n] = floats[0][n];
 401+ }
 402+
 403+ km.x_mapping = KateMotionMapping.CreateMotionMapping(opb.read(8));
 404+ km.y_mapping = KateMotionMapping.CreateMotionMapping(opb.read(8));
 405+ km.semantics = KateMotionSemantics.CreateMotionSemantics(opb.read(8));
 406+ km.periodic = (opb.read1() != 0);
 407+
 408+ Bitwise.skipWarp(opb);
 409+
 410+ return km;
 411+ }
 412+
 413+ /**
 414+ * Decode the motions header packet.
 415+ */
 416+ private int unpackMotions (Buffer opb)
 417+ {
 418+ int nmotions = Bitwise.read32v(opb);
 419+ if (nmotions < 0) return Result.KATE_E_BAD_PACKET;
 420+ motions = new Motion[nmotions];
 421+ for (int n=0; n<nmotions; ++n) {
 422+ try {
 423+ motions[n] = unpackMotion(opb);
 424+ }
 425+ catch (KateException ke) {
 426+ motions = null;
 427+ return Result.KATE_E_BAD_PACKET;
 428+ }
 429+ }
 430+
 431+ Bitwise.skipWarp(opb);
 432+
 433+ /* end of packet */
 434+ return checkEOP(opb);
 435+ }
 436+
 437+ /**
 438+ * Decode a single palette.
 439+ */
 440+ public Palette unpackPalette (Buffer opb) throws KateException
 441+ {
 442+ Palette kp = new Palette();
 443+
 444+ int ncolors = opb.read(8)+1;
 445+ kp.colors = new Color[ncolors];
 446+ for (int n=0; n<ncolors; ++n) {
 447+ kp.colors[n] = unpackColor(opb);
 448+ }
 449+
 450+ Bitwise.skipWarp(opb);
 451+
 452+ return kp;
 453+ }
 454+
 455+ /**
 456+ * Decodes the palettes packet.
 457+ */
 458+ private int unpackPalettes (Buffer opb)
 459+ {
 460+ int npalettes = Bitwise.read32v(opb);
 461+ if (npalettes < 0) return Result.KATE_E_BAD_PACKET;
 462+ palettes = new Palette[npalettes];
 463+ for (int n=0; n<npalettes; ++n) {
 464+ try {
 465+ palettes[n] = unpackPalette(opb);
 466+ }
 467+ catch (KateException ke) {
 468+ palettes = null;
 469+ return Result.KATE_E_BAD_PACKET;
 470+ }
 471+ }
 472+
 473+ Bitwise.skipWarp(opb);
 474+
 475+ /* end of packet */
 476+ return checkEOP(opb);
 477+ }
 478+
 479+ /**
 480+ * Decode a single bitmap.
 481+ */
 482+ public Bitmap unpackBitmap (Buffer opb) throws KateException
 483+ {
 484+ Bitmap kb = new Bitmap();
 485+
 486+ kb.width = Bitwise.read32v(opb);
 487+ kb.height = Bitwise.read32v(opb);
 488+ kb.bpp = opb.read(8);
 489+ if (kb.width < 0 || kb.height < 0 || kb.bpp < 0 || kb.bpp > 8)
 490+ throw new KateBadPacketException();
 491+
 492+ if (kb.bpp == 0) {
 493+ kb.type = KateBitmapType.CreateBitmapType(opb.read(8));
 494+ kb.palette = -1;
 495+ if (kb.type == KateBitmapType.kate_bitmap_type_paletted) {
 496+ int encoding = opb.read(8);
 497+ switch (encoding) {
 498+ case 1: /* RLE */
 499+ kb.bpp = Bitwise.read32v(opb);
 500+ kb.palette = Bitwise.read32v(opb);
 501+ kb.pixels = RLE.decodeRLE(opb, kb.width, kb.height, kb.bpp);
 502+ break;
 503+ default:
 504+ Debug.warning("Unsupported bitmap type");
 505+ throw new KateBadPacketException();
 506+ }
 507+ }
 508+ else if (kb.type == KateBitmapType.kate_bitmap_type_png) {
 509+ kb.size = Bitwise.read32(opb);
 510+ kb.pixels = new byte[kb.size];
 511+ Bitwise.readbuf(opb, kb.pixels, kb.size);
 512+ }
 513+ else {
 514+ Debug.warning("Unsupported bitmap type");
 515+ throw new KateBadPacketException();
 516+ }
 517+ }
 518+ else {
 519+ kb.type = KateBitmapType.kate_bitmap_type_paletted;
 520+ kb.palette = Bitwise.read32v(opb);
 521+ int npixels = kb.width * kb.height;
 522+ kb.pixels = new byte[npixels];
 523+ for (int n=0; n<npixels; ++n)
 524+ kb.pixels[n] = (byte)opb.read(kb.bpp);
 525+ }
 526+
 527+ if (((bitstream_version_major<<8) | bitstream_version_minor) >= 0x0004) {
 528+ Bitwise.read32v(opb);
 529+ kb.x_offset = Bitwise.read32v(opb);
 530+ kb.y_offset = Bitwise.read32v(opb);
 531+ }
 532+ else {
 533+ kb.x_offset = 0;
 534+ kb.y_offset = 0;
 535+ }
 536+
 537+ Bitwise.skipWarp(opb);
 538+
 539+ return kb;
 540+ }
 541+
 542+ /**
 543+ * Decodes the bitmaps packet.
 544+ */
 545+ private int unpackBitmaps (Buffer opb)
 546+ {
 547+ int nbitmaps = Bitwise.read32v(opb);
 548+ if (nbitmaps < 0) return Result.KATE_E_BAD_PACKET;
 549+ bitmaps = new Bitmap[nbitmaps];
 550+ for (int n=0; n<nbitmaps; ++n) {
 551+ try {
 552+ bitmaps[n] = unpackBitmap(opb);
 553+ }
 554+ catch (KateException ke) {
 555+ bitmaps = null;
 556+ return Result.KATE_E_BAD_PACKET;
 557+ }
 558+ }
 559+
 560+ Bitwise.skipWarp(opb);
 561+
 562+ /* end of packet */
 563+ return checkEOP(opb);
 564+ }
 565+
 566+ /**
 567+ * Decodes a single font range.
 568+ */
 569+ private FontRange unpackFontRange (Buffer opb)
 570+ {
 571+ FontRange fr = new FontRange();
 572+ fr.first_code_point = Bitwise.read32v(opb);
 573+ fr.last_code_point = Bitwise.read32v(opb);
 574+ fr.first_bitmap = Bitwise.read32v(opb);
 575+ Bitwise.skipWarp(opb);
 576+ return fr;
 577+ }
 578+
 579+ /**
 580+ * Decodes the font ranges/mappings packet.
 581+ */
 582+ private int unpackFontMappings (Buffer opb)
 583+ {
 584+ int nranges = Bitwise.read32v(opb);
 585+ if (nranges < 0)
 586+ return Result.KATE_E_BAD_PACKET;
 587+ if (nranges > 0) {
 588+ font_ranges = new FontRange[nranges];
 589+ for (int n=0; n<nranges; ++n) {
 590+ font_ranges[n] = unpackFontRange(opb);
 591+ }
 592+ }
 593+
 594+ int nmappings = Bitwise.read32v(opb);
 595+ if (nmappings < 0)
 596+ return Result.KATE_E_BAD_PACKET;
 597+ if (nmappings > 0) {
 598+ font_mappings = new FontMapping[nmappings];
 599+ for (int n=0; n<nmappings; ++n) {
 600+ nranges = Bitwise.read32v(opb);
 601+ if (nranges < 0)
 602+ return Result.KATE_E_BAD_PACKET;
 603+ if (nranges > 0) {
 604+ FontRange fr[] = new FontRange[nranges];
 605+ for (int l=0; l<nranges; ++l) {
 606+ if (opb.read1() != 0) {
 607+ int idx = Bitwise.read32v(opb);
 608+ if (idx < 0 || idx >= this.font_ranges.length)
 609+ return Result.KATE_E_BAD_PACKET;
 610+ fr[l] = this.font_ranges[idx];
 611+ }
 612+ else {
 613+ fr[l] = unpackFontRange(opb);
 614+ }
 615+ }
 616+ font_mappings[n].ranges = fr;
 617+ }
 618+ else {
 619+ font_mappings[n] = null;
 620+ }
 621+ }
 622+ }
 623+
 624+ Bitwise.skipWarp(opb);
 625+
 626+ /* end of packet */
 627+ return checkEOP(opb);
 628+ }
 629+
 630+ /**
 631+ * Resets the header decoder to the start, so a new stream may be decoded.
 632+ */
 633+ public void clear() {
 634+ num_headers = 0;
 635+ regions = null;
 636+ styles = null;
 637+ curves = null;
 638+ motions = null;
 639+ probe = 0;
 640+ }
 641+
 642+ /**
 643+ * Decodes a Kate header, updating the info with the data decoded from the header.
 644+ * If the next expected header is decoded properly, the next header will be expected.
 645+ * Headers beyond the ones we know about are ignored.
 646+ */
 647+ public int decodeHeader (Comment kc, Packet op)
 648+ {
 649+ long ret;
 650+ Buffer opb = new Buffer();
 651+
 652+ opb.readinit (op.packet_base, op.packet, op.bytes);
 653+
 654+ {
 655+ byte[] id = new byte[7];
 656+ int typeflag;
 657+
 658+ typeflag = opb.read(8);
 659+
 660+ /* header types have the MSB set */
 661+ if((typeflag & 0x80) == 0) {
 662+ return Result.KATE_E_BAD_PACKET;
 663+ }
 664+
 665+ /* Kate header magic */
 666+ Bitwise.readbuf(opb,id,7);
 667+ if (!"kate\0\0\0".equals(new String(id))) {
 668+ return Result.KATE_E_NOT_KATE;
 669+ }
 670+
 671+ if (op.packetno < num_headers) {
 672+ if (probe != op.packetno) return Result.KATE_E_BAD_PACKET;
 673+ }
 674+
 675+ /* reserved 0 byte */
 676+ if (opb.read(8) != 0)
 677+ return Result.KATE_E_BAD_PACKET;
 678+
 679+ Debug.debug("decodeHeader: packet type "+typeflag+", probe "+probe);
 680+
 681+ /* ensure packets are received in order */
 682+ switch(probe){
 683+ case 0:
 684+ if(op.b_o_s == 0){
 685+ /* Not the initial packet */
 686+ return Result.KATE_E_BAD_PACKET;
 687+ }
 688+ ret = unpackInfo(opb);
 689+ break;
 690+
 691+ case 1:
 692+ ret = unpackComment(kc,opb);
 693+ break;
 694+
 695+ case 2:
 696+ ret = unpackRegions(opb);
 697+ break;
 698+
 699+ case 3:
 700+ ret = unpackStyles(opb);
 701+ break;
 702+
 703+ case 4:
 704+ ret = unpackCurves(opb);
 705+ break;
 706+
 707+ case 5:
 708+ ret = unpackMotions(opb);
 709+ break;
 710+
 711+ case 6:
 712+ ret = unpackPalettes(opb);
 713+ break;
 714+
 715+ case 7:
 716+ ret = unpackBitmaps(opb);
 717+ break;
 718+
 719+ case 8:
 720+ ret = unpackFontMappings(opb);
 721+ /* last known header, we can init for decode */
 722+ if (ret == 0) {
 723+ Debug.debug("Found last known header, returning 1");
 724+ ret = 1;
 725+ }
 726+ break;
 727+
 728+ default:
 729+ /* ignore any trailing header packets for forward compatibility */
 730+ ret = 0;
 731+ break;
 732+ }
 733+ }
 734+
 735+ /* decode was successful, we're now expecting the next packet in sequence */
 736+ if (ret >= 0) {
 737+ ++probe;
 738+ }
 739+
 740+ return (int)ret;
 741+ }
 742+}
 743+
Index: trunk/cortado/src/com/fluendo/jkate/Tracker.java
@@ -0,0 +1,96 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+import java.util.*;
 25+import java.awt.*;
 26+import com.fluendo.utils.*;
 27+
 28+public final class Tracker {
 29+
 30+ private Dimension window;
 31+ private Dimension frame;
 32+
 33+ public com.fluendo.jkate.Event ev = null;
 34+
 35+ public boolean has[] = new boolean[64];
 36+ public static final int has_region = 0;
 37+ public static final int has_text_alignment_int = 1;
 38+ public static final int has_text_alignment_ext = 2;
 39+
 40+ public float region_x;
 41+ public float region_y;
 42+ public float region_w;
 43+ public float region_h;
 44+
 45+ public Tracker (com.fluendo.jkate.Event ev) {
 46+ this.ev = ev;
 47+ }
 48+
 49+ /**
 50+ * Update the tracker at the given time for the given image's dimensions.
 51+ */
 52+ public boolean update(double t, Dimension window, Dimension frame)
 53+ {
 54+ this.window = window;
 55+ this.frame = frame;
 56+
 57+ /* find current region and style, if any */
 58+ Region kr = ev.kr;
 59+ Style ks = ev.ks;
 60+ if (ks == null && kr != null && kr.style >= 0) {
 61+ ks = ev.ki.styles[kr.style];
 62+ }
 63+
 64+ /* start with nothing */
 65+ for (int n=0; n<has.length; ++n) has[n] = false;
 66+
 67+ /* define region */
 68+ if (kr != null) {
 69+ if (kr.metric == KateSpaceMetric.kate_metric_percentage) {
 70+ region_x = kr.x * frame.width / 100.0f;
 71+ region_y = kr.y * frame.height / 100.0f;
 72+ region_w = kr.w * frame.width / 100.0f;
 73+ region_h = kr.h * frame.height / 100.0f;
 74+ }
 75+ else if (kr.metric == KateSpaceMetric.kate_metric_millionths) {
 76+ region_x = kr.x * frame.width / 1000000.0f;
 77+ region_y = kr.y * frame.height / 1000000.0f;
 78+ region_w = kr.w * frame.width / 1000000.0f;
 79+ region_h = kr.h * frame.height / 1000000.0f;
 80+ }
 81+ else if (kr.metric == KateSpaceMetric.kate_metric_pixels) {
 82+ region_x = kr.x;
 83+ region_y = kr.y;
 84+ region_w = kr.w;
 85+ region_h = kr.h;
 86+ }
 87+ else {
 88+ Debug.debug("Invalid metrics");
 89+ return false;
 90+ }
 91+ has[has_region] = true;
 92+ }
 93+
 94+ return true;
 95+ }
 96+
 97+}
Index: trunk/cortado/src/com/fluendo/jkate/KateTextDirectionality.java
@@ -0,0 +1,47 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+public class KateTextDirectionality {
 25+ public static final KateTextDirectionality kate_l2r_t2b = new KateTextDirectionality ();
 26+ public static final KateTextDirectionality kate_r2l_t2b = new KateTextDirectionality ();
 27+ public static final KateTextDirectionality kate_t2b_r2l = new KateTextDirectionality ();
 28+ public static final KateTextDirectionality kate_t2b_l2r = new KateTextDirectionality ();
 29+
 30+ private static final KateTextDirectionality[] list = {
 31+ kate_l2r_t2b,
 32+ kate_r2l_t2b,
 33+ kate_t2b_r2l,
 34+ kate_t2b_l2r
 35+ };
 36+
 37+ private KateTextDirectionality() {
 38+ }
 39+
 40+ /**
 41+ * Create a KateTextDirectionality object from an integer.
 42+ */
 43+ public static KateTextDirectionality CreateTextDirectionality(int idx) throws KateException {
 44+ if (idx < 0 || idx >= list.length)
 45+ throw new KateException("Text directionality "+idx+" out of bounds");
 46+ return list[idx];
 47+ }
 48+}
Index: trunk/cortado/src/com/fluendo/jkate/Palette.java
@@ -0,0 +1,29 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+/**
 25+ * A Palette definition, containing between 0 and 256 colors.
 26+ */
 27+public class Palette
 28+{
 29+ public Color colors[] = null;
 30+}
Index: trunk/cortado/src/com/fluendo/jkate/KateTextEncoding.java
@@ -0,0 +1,41 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+public class KateTextEncoding {
 25+ public static final KateTextEncoding kate_utf8 = new KateTextEncoding ();
 26+
 27+ private static final KateTextEncoding[] list = {
 28+ kate_utf8,
 29+ };
 30+
 31+ private KateTextEncoding() {
 32+ }
 33+
 34+ /**
 35+ * Create a KateTextEncoding object from an integer.
 36+ */
 37+ public static KateTextEncoding CreateTextEncoding(int idx) throws KateException {
 38+ if (idx < 0 || idx >= list.length)
 39+ throw new KateException("Text encoding "+idx+" out of bounds");
 40+ return list[idx];
 41+ }
 42+}
Index: trunk/cortado/src/com/fluendo/jkate/Style.java
@@ -0,0 +1,54 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+/**
 25+ * A style definition.
 26+ */
 27+
 28+public class Style
 29+{
 30+ public double halign;
 31+ public double valign;
 32+
 33+ public Color text_color;
 34+ public Color background_color;
 35+ public Color draw_color;
 36+
 37+ public KateSpaceMetric font_metric;
 38+ public double font_width;
 39+ public double font_height;
 40+
 41+ public KateSpaceMetric margin_metric;
 42+ public double left_margin;
 43+ public double top_margin;
 44+ public double right_margin;
 45+ public double bottom_margin;
 46+
 47+ public boolean bold;
 48+ public boolean italics;
 49+ public boolean underline;
 50+ public boolean strike;
 51+ public boolean justify;
 52+ public KateWrapMode wrap_mode;
 53+
 54+ public String font;
 55+}
Index: trunk/cortado/src/com/fluendo/jkate/Comment.java
@@ -0,0 +1,35 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+/**
 25+ * Vorbis comments are used in Kate streams too.
 26+ */
 27+public class Comment {
 28+ String[] user_comments;
 29+ String vendor;
 30+
 31+
 32+ public void clear() {
 33+ user_comments = null;
 34+ vendor = null;
 35+ }
 36+}
Index: trunk/cortado/src/com/fluendo/jkate/KateException.java
@@ -0,0 +1,30 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+class KateException extends java.lang.Exception {
 25+ public KateException(String s) { super(); }
 26+}
 27+
 28+class KateBadPacketException extends KateException {
 29+ public KateBadPacketException() { super("Bad packet"); }
 30+}
 31+
Index: trunk/cortado/src/com/fluendo/jkate/KateSpaceMetric.java
@@ -0,0 +1,45 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+public class KateSpaceMetric {
 25+ public static final KateSpaceMetric kate_metric_pixels = new KateSpaceMetric ();
 26+ public static final KateSpaceMetric kate_metric_percentage = new KateSpaceMetric ();
 27+ public static final KateSpaceMetric kate_metric_millionths = new KateSpaceMetric ();
 28+
 29+ private static final KateSpaceMetric[] list = {
 30+ kate_metric_pixels,
 31+ kate_metric_percentage,
 32+ kate_metric_millionths,
 33+ };
 34+
 35+ private KateSpaceMetric() {
 36+ }
 37+
 38+ /**
 39+ * Create a KateSpaceMetric object from an integer.
 40+ */
 41+ public static KateSpaceMetric CreateSpaceMetric(int idx) throws KateException {
 42+ if (idx < 0 || idx >= list.length)
 43+ throw new KateException("Space metrics "+idx+" out of bounds");
 44+ return list[idx];
 45+ }
 46+}
Index: trunk/cortado/src/com/fluendo/jkate/Motion.java
@@ -0,0 +1,35 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+/**
 25+ * A motion definition, composed of a series of curves
 26+ */
 27+public class Motion
 28+{
 29+ public Curve curves[];
 30+ public double durations[];
 31+ KateMotionMapping x_mapping;
 32+ KateMotionMapping y_mapping;
 33+ KateMotionSemantics semantics;
 34+ boolean periodic;
 35+}
 36+
Index: trunk/cortado/src/com/fluendo/jkate/KateMarkupType.java
@@ -0,0 +1,43 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+public class KateMarkupType {
 25+ public static final KateMarkupType kate_markup_none = new KateMarkupType ();
 26+ public static final KateMarkupType kate_markup_simple = new KateMarkupType ();
 27+
 28+ private static final KateMarkupType[] list = {
 29+ kate_markup_none,
 30+ kate_markup_simple,
 31+ };
 32+
 33+ private KateMarkupType() {
 34+ }
 35+
 36+ /**
 37+ * Create a KateMarkupType object from an integer.
 38+ */
 39+ public static KateMarkupType CreateMarkupType(int idx) throws KateException {
 40+ if (idx < 0 || idx >= list.length)
 41+ throw new KateException("Markup type "+idx+" out of bounds");
 42+ return list[idx];
 43+ }
 44+}
Index: trunk/cortado/src/com/fluendo/jkate/Bitwise.java
@@ -0,0 +1,154 @@
 2+/* JKate
 3+ * Copyright (C) 2008 ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 4+ *
 5+ * Parts of JKate are based on code by Wim Taymans <wim@fluendo.com>
 6+ *
 7+ * This program is free software; you can redistribute it and/or
 8+ * modify it under the terms of the GNU Library General Public License
 9+ * as published by the Free Software Foundation; either version 2 of
 10+ * the License, or (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU Library General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU Library General Public
 18+ * License along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20+ */
 21+
 22+package com.fluendo.jkate;
 23+
 24+import com.jcraft.jogg.*;
 25+
 26+/**
 27+ * Various methods to read data from a bitstream.
 28+ */
 29+public class Bitwise {
 30+
 31+ /**
 32+ * Read a number of bytes into a buffer.
 33+ */
 34+ static void readbuf(Buffer opb, byte[] buf, int len)
 35+ {
 36+ for (int i=0; i<len; i++) {
 37+ buf[i] = (byte)opb.read(8);
 38+ }
 39+ }
 40+
 41+ /**
 42+ * Read a little endian 32 bit integer.
 43+ */
 44+ static int read32(Buffer opb)
 45+ {
 46+ int value;
 47+
 48+ value = opb.read(8);
 49+ value |= opb.read(8) << 8;
 50+ value |= opb.read(8) << 16;
 51+ value |= opb.read(8) << 24;
 52+
 53+ return value;
 54+ }
 55+
 56+ /**
 57+ * Read a variable size integer.
 58+ * Format defined in the Kate specification.
 59+ */
 60+ static int read32v(Buffer opb)
 61+ {
 62+ int value;
 63+
 64+ value = opb.read(4);
 65+ if (value == 15) {
 66+ int sign = opb.read(1);
 67+ int bits = opb.read(5)+1;
 68+ value = opb.read(bits);
 69+ if (sign != 0) value = -value;
 70+ }
 71+
 72+ return value;
 73+ }
 74+
 75+ /**
 76+ * Read a little endian 64 bit integer.
 77+ */
 78+ static long read64(Buffer opb)
 79+ {
 80+ long vl, vh;
 81+ vl = (long)read32(opb);
 82+ vh = (long)read32(opb);
 83+ return vl | (vh<<32);
 84+ }
 85+
 86+ /**
 87+ * Read a (possibly multiple) warp.
 88+ * Used to skip over unhandled data from newer (bit still compatible)
 89+ * bitstream versions.
 90+ */
 91+ static int skipWarp(Buffer opb)
 92+ {
 93+ while (true) {
 94+ int bits = read32v(opb);
 95+ if (bits == 0)
 96+ break;
 97+ if (bits < 0)
 98+ return Result.KATE_E_BAD_PACKET;
 99+ opb.adv(bits);
 100+ }
 101+
 102+ return 0;
 103+ }
 104+
 105+ static private final int fp_bits = (4*8);
 106+ static private final int fp_cuts_bits = fp_bits/2-1;
 107+ static private final int fp_cuts_bits_bits = 4;
 108+ static private final int fp_sign_bit = 0x80000000;
 109+ private static int[] readFixed(Buffer opb, int count) {
 110+ int head = opb.read(fp_cuts_bits_bits);
 111+ int tail = opb.read(fp_cuts_bits_bits);
 112+ int bits = fp_bits - head - tail;
 113+ int values[] = new int[count];
 114+ int n = 0;
 115+ while (count-- > 0) {
 116+ int sign = 0;
 117+ if (head > 0)
 118+ sign = opb.read1();
 119+ int v = opb.read(bits);
 120+ v <<= tail;
 121+ if (sign != 0)
 122+ v = -v;
 123+ values[n++] = v;
 124+ }
 125+ return values;
 126+ }
 127+ static private double fixedToFloat(int v) {
 128+ return ((double)v) / (1<<16);
 129+ }
 130+
 131+ /**
 132+ * Read an array of float channels.
 133+ * Float format defined in the Kate specification.
 134+ */
 135+ static double[][] readFloats(Buffer opb, int count, int streams) {
 136+ if (count*streams == 0)
 137+ return null;
 138+ if (streams > 1) {
 139+ if (opb.read1() != 0) {
 140+ count *= streams;
 141+ streams = 1;
 142+ }
 143+ }
 144+
 145+ double values[][] = new double[streams][];
 146+ for (int s=0; s<streams; ++s) {
 147+ int ints[] = readFixed(opb, count);
 148+ values[s] = new double[count];
 149+ for (int c=0; c<count; ++c) {
 150+ values[s][c] = fixedToFloat(ints[c]);
 151+ }
 152+ }
 153+ return values;
 154+ }
 155+}
Index: trunk/cortado/src/com/fluendo/plugin/KateDec.java
@@ -0,0 +1,334 @@
 2+/* Copyright (C) <2008> ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 3+ * based on code Copyright (C) <2004> Wim Taymans <wim@fluendo.com>
 4+ *
 5+ * This library is free software; you can redistribute it and/or
 6+ * modify it under the terms of the GNU Library General Public
 7+ * License as published by the Free Software Foundation; either
 8+ * version 2 of the License, or (at your option) any later version.
 9+ *
 10+ * This library 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 GNU
 13+ * Library General Public License for more details.
 14+ *
 15+ * You should have received a copy of the GNU Library General Public
 16+ * License along with this library; if not, write to the
 17+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 18+ * Boston, MA 02111-1307, USA.
 19+ */
 20+
 21+package com.fluendo.plugin;
 22+
 23+import java.util.*;
 24+import com.jcraft.jogg.*;
 25+import com.fluendo.jkate.*;
 26+import com.fluendo.jst.*;
 27+import com.fluendo.utils.*;
 28+
 29+/**
 30+ * Katedec is a decoder element for the Kate stream format.
 31+ * See http://wiki.xiph.org/index.php/OggKate for more information.
 32+ * Kate streams may be multiplexed in Ogg.
 33+ * The Katedec element accepts Kate packets (presumably demultiplexed by an
 34+ * Ogg demuxer element) on its sink, and generates Kate events on its source.
 35+ * Kate events are Kate specific structures, which may then be interpreted
 36+ * by a renderer.
 37+*/
 38+public class KateDec extends Element implements OggPayload
 39+{
 40+ /* Kate magic: 0x80 (BOS header) followed by "kate\0\0\0" */
 41+ private static final byte[] signature = { -128, 0x6b, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00 };
 42+
 43+ private Info ki;
 44+ private Comment kc;
 45+ private State k;
 46+ private Packet op;
 47+ private int packetno;
 48+
 49+ private long basetime = 0;
 50+ private long lastTs;
 51+ private boolean haveDecoder = false;
 52+
 53+ /*
 54+ * OggPayload interface
 55+ */
 56+ public boolean isType (Packet op)
 57+ {
 58+ return typeFind (op.packet_base, op.packet, op.bytes) > 0;
 59+ }
 60+ public boolean isKeyFrame (Packet op)
 61+ {
 62+ return true;
 63+ }
 64+
 65+ /**
 66+ * A discontinuous codec will not cause the pipeline to wait for data if starving
 67+ */
 68+ public boolean isDiscontinuous ()
 69+ {
 70+ return true;
 71+ }
 72+ public int takeHeader (Packet op)
 73+ {
 74+ int ret = ki.decodeHeader(kc, op);
 75+ if (ret > 0) {
 76+ k.decodeInit(ki);
 77+ Debug.debug("Kate decoder ready");
 78+ haveDecoder = true;
 79+ }
 80+ return ret;
 81+ }
 82+ public boolean isHeader (Packet op)
 83+ {
 84+ return (op.packet_base[op.packet] & 0x80) == 0x80;
 85+ }
 86+ public long getFirstTs (Vector packets)
 87+ {
 88+ int len = packets.size();
 89+ int i;
 90+ long time;
 91+ com.fluendo.jst.Buffer data = null;
 92+
 93+ /* first find buffer with valid offset */
 94+ for (i=0; i<len; i++) {
 95+ data = (com.fluendo.jst.Buffer) packets.elementAt(i);
 96+
 97+ if (data.time_offset != -1)
 98+ break;
 99+ }
 100+ if (i == packets.size())
 101+ return -1;
 102+
 103+ time = granuleToTime (data.time_offset);
 104+
 105+ data = (com.fluendo.jst.Buffer) packets.elementAt(0);
 106+ data.timestamp = time - (long) ((i+1) * (Clock.SECOND * ki.gps_denominator / ki.gps_numerator));
 107+
 108+ return time;
 109+ }
 110+
 111+ /**
 112+ * Converts a granule position to its time equivalent
 113+ */
 114+ public long granuleToTime (long gp)
 115+ {
 116+ long res;
 117+
 118+ if (gp < 0 || !haveDecoder)
 119+ return -1;
 120+
 121+ res = (long) (k.granuleTime(gp) * Clock.SECOND);
 122+
 123+ return res;
 124+ }
 125+
 126+ /**
 127+ * Converts a granule position to its duration equivalent
 128+ */
 129+ public long granuleToDuration (long gp)
 130+ {
 131+ long res;
 132+
 133+ if (gp < 0 || !haveDecoder)
 134+ return -1;
 135+
 136+ res = (long) (k.granuleDuration(gp) * Clock.SECOND);
 137+
 138+ return res;
 139+ }
 140+
 141+ private Pad srcPad = new Pad(Pad.SRC, "src") {
 142+ protected boolean eventFunc (com.fluendo.jst.Event event) {
 143+ return sinkPad.pushEvent(event);
 144+ }
 145+ };
 146+
 147+ private Pad sinkPad = new Pad(Pad.SINK, "sink") {
 148+ protected boolean eventFunc (com.fluendo.jst.Event event) {
 149+ boolean result;
 150+
 151+ switch (event.getType()) {
 152+ case com.fluendo.jst.Event.FLUSH_START:
 153+ result = srcPad.pushEvent (event);
 154+ synchronized (streamLock) {
 155+ Debug.log(Debug.DEBUG, "synced "+this);
 156+ }
 157+ break;
 158+ case com.fluendo.jst.Event.FLUSH_STOP:
 159+ result = srcPad.pushEvent(event);
 160+ break;
 161+ case com.fluendo.jst.Event.EOS:
 162+ Debug.log(Debug.INFO, "got EOS "+this);
 163+ result = srcPad.pushEvent(event);
 164+ break;
 165+ case com.fluendo.jst.Event.NEWSEGMENT:
 166+ basetime = event.parseNewsegmentStart();
 167+ Debug.info("new segment: base time "+basetime);
 168+ result = srcPad.pushEvent(event);
 169+ break;
 170+ default:
 171+ result = srcPad.pushEvent(event);
 172+ break;
 173+ }
 174+ return result;
 175+ }
 176+
 177+ /**
 178+ * receives Kate packets, and generates Kate events
 179+ */
 180+ protected int chainFunc (com.fluendo.jst.Buffer buf) {
 181+ int result;
 182+ long timestamp;
 183+
 184+ Debug.log( Debug.DEBUG, parent.getName() + " <<< " + buf );
 185+
 186+ op.packet_base = buf.data;
 187+ op.packet = buf.offset;
 188+ op.bytes = buf.length;
 189+ op.b_o_s = (packetno == 0 ? 1 : 0);
 190+ op.e_o_s = 0;
 191+ op.packetno = packetno;
 192+ timestamp = buf.timestamp;
 193+
 194+ Debug.log(Debug.DEBUG, "Kate chainFunc with packetno "+packetno+", haveDecoder "+haveDecoder);
 195+
 196+// if (buf.isFlagSet (com.fluendo.jst.Buffer.FLAG_DISCONT)) {
 197+// Debug.log(Debug.INFO, "kate: got discont");
 198+// /* should flush, if we keep events to handle repeats in the future */
 199+// lastTs = -1;
 200+// }
 201+
 202+ if (!haveDecoder) {
 203+ //System.out.println ("decoding header");
 204+ result = takeHeader(op);
 205+ if (result < 0){
 206+ buf.free();
 207+ // error case; not a kate header
 208+ Debug.log(Debug.ERROR, "does not contain Kate data.");
 209+ return ERROR;
 210+ }
 211+ else if (result > 0) {
 212+ // we've decoded all headers
 213+ Debug.log(Debug.DEBUG, "Kate initialized for decoding");
 214+
 215+ /* we're sending raw kate_event structures */
 216+ caps = new Caps ("application/x-kate-event");
 217+ }
 218+ buf.free();
 219+ packetno++;
 220+
 221+ return OK;
 222+ }
 223+ else {
 224+ if ((op.packet_base[op.packet] & 0x80) == 0x80) {
 225+ Debug.log(Debug.DEBUG, "ignoring header");
 226+ buf.free();
 227+ return OK;
 228+ }
 229+
 230+ if (timestamp != -1) {
 231+ lastTs = timestamp;
 232+ }
 233+
 234+ if (true) {
 235+ try{
 236+ result = k.decodePacketin(op);
 237+ if (result < 0) {
 238+ buf.free();
 239+ Debug.log(Debug.ERROR, "Error Decoding Kate.");
 240+ postMessage (Message.newError (this, "Error decoding Kate"));
 241+ return ERROR;
 242+ }
 243+ com.fluendo.jkate.Event ev = k.decodeEventOut();
 244+ if (ev != null) {
 245+ buf.object = ev;
 246+ buf.caps = caps;
 247+ buf.timestamp = granuleToDuration(ev.start);
 248+ buf.timestampEnd = buf.timestamp + granuleToDuration(ev.duration);
 249+ Debug.log( Debug.DEBUG, parent.getName() + " >>> " + buf );
 250+ Debug.debug("Got Kate text: "+new String(ev.text)+" from "+buf.timestamp+" to "+buf.timestampEnd+", basetime "+basetime);
 251+ result = srcPad.push(buf);
 252+ Debug.log(Debug.DEBUG, "push returned "+result);
 253+ }
 254+ else {
 255+ Debug.debug("Got no event");
 256+ buf.free();
 257+ result = OK;
 258+ }
 259+ }
 260+ catch (Exception e) {
 261+ e.printStackTrace();
 262+ postMessage (Message.newError (this, e.getMessage()));
 263+ result = ERROR;
 264+ }
 265+ }
 266+ else {
 267+ result = OK;
 268+ buf.free();
 269+ }
 270+ }
 271+ packetno++;
 272+
 273+ return result;
 274+ }
 275+
 276+ protected boolean activateFunc (int mode)
 277+ {
 278+ return true;
 279+ }
 280+ };
 281+
 282+ public KateDec() {
 283+ super();
 284+
 285+ ki = new Info();
 286+ kc = new Comment();
 287+ k = new State();
 288+ op = new Packet();
 289+
 290+ addPad (srcPad);
 291+ addPad (sinkPad);
 292+ }
 293+
 294+ protected int changeState (int transition) {
 295+ int res;
 296+
 297+ switch (transition) {
 298+ case STOP_PAUSE:
 299+ lastTs = -1;
 300+ packetno = 0;
 301+ break;
 302+ default:
 303+ break;
 304+ }
 305+
 306+ res = super.changeState (transition);
 307+
 308+ switch (transition) {
 309+ case PAUSE_STOP:
 310+ ki.clear();
 311+ kc.clear();
 312+ k.clear();
 313+ break;
 314+ default:
 315+ break;
 316+ }
 317+
 318+ return res;
 319+ }
 320+
 321+ public String getFactoryName ()
 322+ {
 323+ return "katedec";
 324+ }
 325+ public String getMime ()
 326+ {
 327+ return "application/x-kate";
 328+ }
 329+ public int typeFind (byte[] data, int offset, int length)
 330+ {
 331+ if (MemUtils.startsWith (data, offset, length, signature))
 332+ return 10;
 333+ return -1;
 334+ }
 335+}
Index: trunk/cortado/src/com/fluendo/plugin/OggDemux.java
@@ -41,7 +41,8 @@
4242
4343 private OggPayload payloads[] = {
4444 new TheoraDec(),
45 - new VorbisDec()
 45+ new VorbisDec(),
 46+ new KateDec()
4647 };
4748
4849 class OggStream extends Pad {
@@ -222,15 +223,20 @@
223224 complete = true;
224225 return Pad.OK;
225226 }
 227+
226228 /* first read all the headers */
227229 if (!haveHeaders) {
228230 if (payload.isHeader(op)) {
229 - if (payload.takeHeader (op) < 0) {
 231+ int result = payload.takeHeader (op);
 232+ if (result < 0) {
230233 postMessage (Message.newError (this, "cannot read header"));
231234 return Pad.ERROR;
232235 }
233236 com.fluendo.jst.Buffer data = bufferFromPacket (op);
234237 headers.addElement(data);
 238+ if (result > 0) {
 239+ haveHeaders = true;
 240+ }
235241 }
236242 else {
237243 haveHeaders = true;
@@ -238,6 +244,10 @@
239245 }
240246 /* if we have all the headers we can stream */
241247 if (haveHeaders) {
 248+ /* discontinuous codecs do not need to wait for data to allow playback */
 249+ if (!complete && payload.isDiscontinuous()) {
 250+ complete = true;
 251+ }
242252 if (complete && started) {
243253 int ret;
244254 com.fluendo.jst.Buffer data = bufferFromPacket (op);
Index: trunk/cortado/src/com/fluendo/plugin/VorbisDec.java
@@ -56,6 +56,10 @@
5757 {
5858 return true;
5959 }
 60+ public boolean isDiscontinuous ()
 61+ {
 62+ return false;
 63+ }
6064 public long getFirstTs (Vector packets)
6165 {
6266 int len = packets.size();
Index: trunk/cortado/src/com/fluendo/plugin/Selector.java
@@ -0,0 +1,137 @@
 2+/* Copyright (C) <2008> ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 3+ *
 4+ * This library is free software; you can redistribute it and/or
 5+ * modify it under the terms of the GNU Library General Public
 6+ * License as published by the Free Software Foundation; either
 7+ * version 2 of the License, or (at your option) any later version.
 8+ *
 9+ * This library is distributed in the hope that it will be useful,
 10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 12+ * Library General Public License for more details.
 13+ *
 14+ * You should have received a copy of the GNU Library General Public
 15+ * License along with this library; if not, write to the
 16+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 17+ * Boston, MA 02111-1307, USA.
 18+ */
 19+
 20+package com.fluendo.plugin;
 21+
 22+import java.util.*;
 23+import java.awt.*;
 24+import com.fluendo.jst.*;
 25+import com.fluendo.utils.*;
 26+
 27+/**
 28+ * This element receives data from N sinks, and selects one of them
 29+ * to send from its source.
 30+ */
 31+public class Selector extends Element
 32+{
 33+ private Vector sinks = new Vector();
 34+ int selected = -1;
 35+ Pad selectedPad = null;
 36+
 37+ private Pad srcPad = new Pad(Pad.SRC, "src") {
 38+ /**
 39+ * Pushes the event to every sink.
 40+ */
 41+ protected boolean eventFunc (com.fluendo.jst.Event event) {
 42+ boolean ret = true;
 43+ for (int n=0; n<sinks.size(); ++n) {
 44+ ret &= ((Pad)sinks.get(n)).pushEvent(event);
 45+ }
 46+ return ret;
 47+ }
 48+ };
 49+
 50+ private int findPad (Pad pad) {
 51+ for (int n=0; n<sinks.size(); ++n) {
 52+ if (sinks.get(n) == pad)
 53+ return n;
 54+ }
 55+ return -1;
 56+ }
 57+
 58+ /**
 59+ * Requests a new sink pad to be created for the given peer.
 60+ * The caps do not matter, as Selector is a caps agnostic element.
 61+ */
 62+ public Pad requestSinkPad(Pad peer) {
 63+ Pad pad = new Pad(Pad.SINK, "sink"+sinks.size()) {
 64+ protected boolean eventFunc (com.fluendo.jst.Event event) {
 65+ if (selectedPad == this) {
 66+ return srcPad.pushEvent (event);
 67+ }
 68+ return true;
 69+ }
 70+
 71+ protected int chainFunc (com.fluendo.jst.Buffer buf) {
 72+ int result = Pad.OK;
 73+
 74+ //Debug.log( Debug.DEBUG, parent.getName() + " <<< " + buf );
 75+ Debug.debug("Selector got "+buf.caps+" buffer on "+this.toString());
 76+
 77+ if (selectedPad == this) {
 78+ Debug.debug("what a coincidence, we're selected - pushing");
 79+ result = srcPad.push(buf);
 80+ }
 81+
 82+ return result;
 83+ }
 84+
 85+ protected boolean activateFunc (int mode)
 86+ {
 87+ return true;
 88+ }
 89+ };
 90+
 91+ sinks.addElement(pad);
 92+ addPad(pad);
 93+ return pad;
 94+ }
 95+
 96+ public Selector() {
 97+ super();
 98+
 99+ addPad (srcPad);
 100+ }
 101+
 102+ /**
 103+ * The selected sink may be selected via the "selected" property - negative to select nothing
 104+ */
 105+ public boolean setProperty (String name, java.lang.Object value) {
 106+ if (name.equals("selected")) {
 107+ int new_selected = Integer.valueOf(value.toString()).intValue();
 108+ Debug.info("Selector: request to select "+new_selected+" (from "+selected+"), within 0-"+(sinks.size()-1));
 109+ if (new_selected < 0 || new_selected >= sinks.size()) {
 110+ selected = -1;
 111+ selectedPad = null;
 112+ }
 113+ else {
 114+ selected = new_selected;
 115+ selectedPad = (Pad)sinks.get(selected);
 116+ }
 117+ }
 118+ else {
 119+ return super.setProperty(name, value);
 120+ }
 121+
 122+ return true;
 123+ }
 124+
 125+ public java.lang.Object getProperty (String name) {
 126+ if (name.equals("selected")) {
 127+ return new Integer(selected);
 128+ }
 129+ else {
 130+ return super.getProperty(name);
 131+ }
 132+ }
 133+
 134+ public String getFactoryName ()
 135+ {
 136+ return "selector";
 137+ }
 138+}
Index: trunk/cortado/src/com/fluendo/plugin/Overlay.java
@@ -0,0 +1,122 @@
 2+/* Copyright (C) <2008> ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 3+ *
 4+ * This library is free software; you can redistribute it and/or
 5+ * modify it under the terms of the GNU Library General Public
 6+ * License as published by the Free Software Foundation; either
 7+ * version 2 of the License, or (at your option) any later version.
 8+ *
 9+ * This library is distributed in the hope that it will be useful,
 10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 12+ * Library General Public License for more details.
 13+ *
 14+ * You should have received a copy of the GNU Library General Public
 15+ * License along with this library; if not, write to the
 16+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 17+ * Boston, MA 02111-1307, USA.
 18+ */
 19+
 20+package com.fluendo.plugin;
 21+
 22+import java.util.*;
 23+import java.awt.*;
 24+import com.fluendo.jst.*;
 25+import com.fluendo.utils.*;
 26+
 27+/**
 28+ * This is a base overlay element, just passes images from sink to source.
 29+ * Extend this and override the overlay function to draw something onto
 30+ * images as they go from sink to source.
 31+ */
 32+public class Overlay extends Element
 33+{
 34+ protected Component component;
 35+
 36+ private Pad videoSrcPad = new Pad(Pad.SRC, "videosrc") {
 37+ protected boolean eventFunc (com.fluendo.jst.Event event) {
 38+ return videoSinkPad.pushEvent(event);
 39+ }
 40+ };
 41+
 42+ private Pad videoSinkPad = new Pad(Pad.SINK, "videosink") {
 43+ protected boolean eventFunc (com.fluendo.jst.Event event) {
 44+ return videoSrcPad.pushEvent (event);
 45+ }
 46+
 47+ /**
 48+ * Receives an image, allows a derived class to overlay whatever it wants on it,
 49+ * and sends it to the video source pad.
 50+ */
 51+ protected int chainFunc (com.fluendo.jst.Buffer buf) {
 52+ int result;
 53+
 54+ Debug.log( Debug.DEBUG, parent.getName() + " <<< " + buf );
 55+
 56+ overlay(buf);
 57+
 58+ result = videoSrcPad.push(buf);
 59+ if (result != Pad.OK) {
 60+ Debug.log( Debug.WARNING, parent.getName() + ": failed to push buffer to video source pad: "+result);
 61+ }
 62+
 63+ return result;
 64+ }
 65+
 66+ protected boolean activateFunc (int mode)
 67+ {
 68+ return true;
 69+ }
 70+ };
 71+
 72+ public Overlay() {
 73+ super();
 74+
 75+ addPad (videoSinkPad);
 76+ addPad (videoSrcPad);
 77+ }
 78+
 79+ /**
 80+ * this function may be overridden to draw whatever the derived
 81+ * class wants onto the incoming image.
 82+ * By default, the image is passed without alteration.
 83+ */
 84+ protected void overlay(com.fluendo.jst.Buffer buf) {
 85+ /* straight pass through by default */
 86+ }
 87+
 88+ public boolean setProperty (String name, java.lang.Object value) {
 89+ if (name.equals("component")) {
 90+ component = (Component) value;
 91+ }
 92+ else {
 93+ return super.setProperty(name, value);
 94+ }
 95+
 96+ return true;
 97+ }
 98+
 99+ public java.lang.Object getProperty (String name) {
 100+ if (name.equals("component")) {
 101+ return component;
 102+ }
 103+ else {
 104+ return super.getProperty(name);
 105+ }
 106+ }
 107+
 108+ /* from the video sink code, I do not understand what this does semantically,
 109+ the frame would be 0x0 sized. Maybe just to avoid possible null dereference,
 110+ but I suspect there might be something more clever, so it goes in for safety */
 111+ protected int changeState (int transition) {
 112+ if (currentState == STOP && pendingState == PAUSE && component == null) {
 113+ Frame frame = new Frame();
 114+ component = (Component) frame;
 115+ }
 116+ return super.changeState(transition);
 117+ }
 118+
 119+ public String getFactoryName ()
 120+ {
 121+ return "overlay";
 122+ }
 123+}
Index: trunk/cortado/src/com/fluendo/plugin/TextOverlay.java
@@ -0,0 +1,114 @@
 2+/* Copyright (C) <2008> ogg.k.ogg.k <ogg.k.ogg.k@googlecode.com>
 3+ *
 4+ * This library is free software; you can redistribute it and/or
 5+ * modify it under the terms of the GNU Library General Public
 6+ * License as published by the Free Software Foundation; either
 7+ * version 2 of the License, or (at your option) any later version.
 8+ *
 9+ * This library is distributed in the hope that it will be useful,
 10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 12+ * Library General Public License for more details.
 13+ *
 14+ * You should have received a copy of the GNU Library General Public
 15+ * License along with this library; if not, write to the
 16+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 17+ * Boston, MA 02111-1307, USA.
 18+ */
 19+
 20+package com.fluendo.plugin;
 21+
 22+import java.util.*;
 23+import java.awt.*;
 24+import java.awt.image.*;
 25+import com.fluendo.jst.*;
 26+import com.fluendo.utils.*;
 27+
 28+/**
 29+ * This class displays a simple text string on top of incoming video.
 30+ */
 31+public class TextOverlay extends Overlay
 32+{
 33+ private BufferedImage bimg = null;
 34+ private Font font = null;
 35+ private String text = null;
 36+
 37+ public TextOverlay() {
 38+ super();
 39+ }
 40+
 41+ /**
 42+ * Display a text string (from a property) onto the image.
 43+ */
 44+ protected void overlay(com.fluendo.jst.Buffer buf) {
 45+ Image img;
 46+
 47+ /* img retrieval from VideoSink.java */
 48+ if (buf.object instanceof ImageProducer) {
 49+ img = component.createImage((ImageProducer)buf.object);
 50+ }
 51+ else if (buf.object instanceof Image) {
 52+ img = (Image)buf.object;
 53+ }
 54+ else {
 55+ System.out.println(this+": unknown buffer received "+buf);
 56+ return;
 57+ }
 58+
 59+ Dimension d = component.getSize();
 60+ int x = 0;
 61+ int y = 0;
 62+ int w = d.width;
 63+ int h = d.height;
 64+
 65+ /* based on a java SDK example */
 66+ if (bimg == null || bimg.getWidth() != w || bimg.getHeight() != h) {
 67+ bimg = component.getGraphicsConfiguration().createCompatibleImage(w, h);
 68+ int font_size = w / 32;
 69+ if (font_size < 12) font_size = 12;
 70+ font = new Font("sans", Font.BOLD, font_size); // TODO: should be selectable ?
 71+ }
 72+
 73+ Graphics2D g2 = bimg.createGraphics();
 74+ g2.drawImage(img, x, y, w, h, null);
 75+
 76+ /* render text on top */
 77+ if (text != null) {
 78+ double tw;
 79+ g2.setFont(font);
 80+ g2.setColor(Color.white);
 81+ FontMetrics fm = g2.getFontMetrics();
 82+ tw = fm.stringWidth(text);
 83+ g2.drawString(text, x+(int)((w-tw)/2), y+(int)(h*0.85));
 84+ }
 85+
 86+ g2.dispose();
 87+
 88+ buf.object = bimg;
 89+ }
 90+
 91+ public boolean setProperty (String name, java.lang.Object value) {
 92+ if (name.equals("text")) {
 93+ text = value.toString();
 94+ }
 95+ else {
 96+ return super.setProperty(name, value);
 97+ }
 98+
 99+ return true;
 100+ }
 101+
 102+ public java.lang.Object getProperty (String name) {
 103+ if (name.equals("text")) {
 104+ return text;
 105+ }
 106+ else {
 107+ return super.getProperty(name);
 108+ }
 109+ }
 110+
 111+ public String getFactoryName ()
 112+ {
 113+ return "textoverlay";
 114+ }
 115+}
Index: trunk/cortado/src/com/fluendo/plugin/KateOverlay.java
@@ -0,0 +1,121 @@
 2+/* Copyright (C) <2008> ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
 3+ *
 4+ * This library is free software; you can redistribute it and/or
 5+ * modify it under the terms of the GNU Library General Public
 6+ * License as published by the Free Software Foundation; either
 7+ * version 2 of the License, or (at your option) any later version.
 8+ *
 9+ * This library is distributed in the hope that it will be useful,
 10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 12+ * Library General Public License for more details.
 13+ *
 14+ * You should have received a copy of the GNU Library General Public
 15+ * License along with this library; if not, write to the
 16+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 17+ * Boston, MA 02111-1307, USA.
 18+ */
 19+
 20+package com.fluendo.plugin;
 21+
 22+import java.util.*;
 23+import java.awt.*;
 24+import java.awt.image.*;
 25+import com.fluendo.jst.*;
 26+import com.fluendo.jkate.Event;
 27+import com.fluendo.jtiger.Renderer;
 28+import com.fluendo.utils.*;
 29+
 30+/* This element renders a Kate stream on incoming video */
 31+public class KateOverlay extends Overlay
 32+{
 33+ private BufferedImage bimg = null;
 34+ private Font font = null;
 35+ private String text = null;
 36+ private Renderer tr = new Renderer();
 37+
 38+ private Pad kateSinkPad = new Pad(Pad.SINK, "katesink") {
 39+ protected boolean eventFunc (com.fluendo.jst.Event event) {
 40+ /* don't propagate, the video sink is the master */
 41+ return true;
 42+ }
 43+
 44+ /**
 45+ * This pad receives Kate events, and add them to the renderer.
 46+ * They will be removed from it as they become inactive.
 47+ */
 48+ protected synchronized int chainFunc (com.fluendo.jst.Buffer buf) {
 49+ addKateEvent((com.fluendo.jkate.Event)buf.object);
 50+ return Pad.OK;
 51+ }
 52+ };
 53+
 54+ /**
 55+ * Create a new Kate overlay
 56+ */
 57+ public KateOverlay() {
 58+ super();
 59+ addPad(kateSinkPad);
 60+ }
 61+
 62+
 63+ /**
 64+ * Add a new Kate event to the renderer.
 65+ * This needs locking so the Kate events are not changed while the
 66+ * overlay is rendering them to an image.
 67+ */
 68+ protected synchronized void addKateEvent(com.fluendo.jkate.Event ev) {
 69+ tr.add(ev);
 70+ Debug.log(Debug.DEBUG, "Kate overlay got Kate event: "+new String(ev.text));
 71+ }
 72+
 73+ /**
 74+ * Overlay the Kate renderer onto the given image.
 75+ */
 76+ protected synchronized void overlay(com.fluendo.jst.Buffer buf) {
 77+ Image img;
 78+
 79+ if (buf.object instanceof ImageProducer) {
 80+ img = component.createImage((ImageProducer)buf.object);
 81+ }
 82+ else if (buf.object instanceof Image) {
 83+ img = (Image)buf.object;
 84+ }
 85+ else {
 86+ System.out.println(this+": unknown buffer received "+buf);
 87+ return;
 88+ }
 89+
 90+ /* before rendering, we update the state of the events; for now this
 91+ just weeds out old ones, but at some point motions could be tracked. */
 92+ int ret = tr.update(component, buf.timestamp/(double)Clock.SECOND);
 93+ /* if there are no Kate events active, just return the buffer as is */
 94+ if (ret == 1)
 95+ return;
 96+
 97+ Dimension d = component.getSize();
 98+ int x = 0;
 99+ int y = 0;
 100+ int w = d.width;
 101+ int h = d.height;
 102+
 103+ if (bimg == null || bimg.getWidth() != w || bimg.getHeight() != h) {
 104+ bimg = component.getGraphicsConfiguration().createCompatibleImage(w, h);
 105+ }
 106+
 107+ Graphics2D g2 = bimg.createGraphics();
 108+ g2.drawImage(img, x, y, w, h, null);
 109+
 110+ /* render Kate stream on top */
 111+ tr.render(component, bimg);
 112+
 113+ g2.dispose();
 114+
 115+ buf.object = bimg;
 116+ }
 117+
 118+ public String getFactoryName ()
 119+ {
 120+ return "kateoverlay";
 121+ }
 122+}
Index: trunk/cortado/src/com/fluendo/plugin/OggPayload.java
@@ -30,6 +30,7 @@
3131 public boolean isType (Packet op);
3232 /**
3333 * Initialize the payload with a header packet.
 34+ * Returns < 0 for error, 0 if OK, 1 if OK and ready for decoding data.
3435 */
3536 public int takeHeader (Packet op);
3637 /**
@@ -52,5 +53,10 @@
5354 * Get mime type
5455 */
5556 public String getMime ();
 57+ /**
 58+ * Check if the stream is discontinuous (eg, no need to wait
 59+ * for data on this stream before playing)
 60+ */
 61+ public boolean isDiscontinuous ();
5662 }
5763
Index: trunk/cortado/src/com/fluendo/plugin/TheoraDec.java
@@ -66,6 +66,10 @@
6767 {
6868 return ts.isKeyframe(op);
6969 }
 70+ public boolean isDiscontinuous ()
 71+ {
 72+ return false;
 73+ }
7074 public long getFirstTs (Vector packets)
7175 {
7276 int len = packets.size();
Index: trunk/cortado/README
@@ -7,6 +7,8 @@
88 - JST, a port of the GStreamer 0.10 design to Java
99 - jcraft, a copy of the JCraft JOgg/Jorbis code
1010 - jheora, an implementation of Theora in Java
 11+- jkate, an implementation of a basic Kate decoder in Java
 12+- jtiger, a basic Kate renderer (simple text/images only for now)
1113 - codecs (currently only containing the Smoke codec, a variant on Jpeg)
1214 - JST plugins for:
1315 - HTTP source element
@@ -15,6 +17,9 @@
1618 - Vorbis and MuLaw audio decoders
1719 - Java 1.1 sun.audio API audio sink
1820 - Java 1.4 javax.sound.sampled API audio sink
 21+ - Overlay element
 22+ - Kate text decoder and overlay
 23+ - Selector element
1924 - examples
2025 - applets
2126
@@ -152,6 +157,13 @@
153158 resources to play an audio stream. true or false.
154159 Defaults to true
155160
 161+ kateIndex: int
 162+ Use text from the given Kate stream (indexed from zero).
 163+ The first Kate stream found will have index 0, the second will
 164+ have index 1, etc.
 165+ At most one Kate stream may be enabled at a time.
 166+ Defaults to -1 (none)
 167+
156168 statusHeight: int
157169 The height of the status area (default 12)
158170
Index: trunk/cortado/build.xml
@@ -175,11 +175,14 @@
176176 <condition property="plugin.Vorbis.false">
177177 <contains string="${exclude}" substring="Vorbis" casesensitive="false" />
178178 </condition>
 179+ <condition property="plugin.Kate.false">
 180+ <contains string="${exclude}" substring="Kate" casesensitive="false" />
 181+ </condition>
179182 </target>
180183
181184 <!-- generate includes and plugins.ini based on contents of exclude -->
182185 <target name="includes"
183 - depends="plugins,includes-delete,include-JPEG,include-Mulaw,include-Multipart,include-Ogg,include-Smoke,include-Theora,include-Vorbis">
 186+ depends="plugins,includes-delete,include-JPEG,include-Mulaw,include-Multipart,include-Ogg,include-Smoke,include-Theora,include-Vorbis,include-Kate">
184187 <echo>Generating ${out.buildtyped}/includes</echo>
185188 </target>
186189
@@ -192,8 +195,11 @@
193196 com/fluendo/jst/*
194197 com/fluendo/plugin/AudioSink*
195198 com/fluendo/plugin/VideoSink**
 199+com/fluendo/plugin/FakeSink*
 200+com/fluendo/plugin/Overlay*
196201 com/fluendo/plugin/HTTPSrc*
197202 com/fluendo/plugin/Queue*
 203+com/fluendo/plugin/Selector*
198204 plugins.ini
199205 </echo>
200206 <echo file="${out.buildtyped}/plugins.ini"
@@ -202,6 +208,9 @@
203209 com.fluendo.plugin.AudioSinkJ2
204210 com.fluendo.plugin.AudioSinkSA
205211 com.fluendo.plugin.Queue
 212+com.fluendo.plugin.FakeSink
 213+com.fluendo.plugin.Overlay
 214+com.fluendo.plugin.Selector
206215 </echo>
207216
208217 </target>
@@ -280,6 +289,19 @@
281290 </echo>
282291 </target>
283292
 293+ <target name="include-Kate" unless="plugin.Kate.false">
 294+ <echo>Including Kate</echo>
 295+ <echo file="${out.buildtyped}/includes" append="true"
 296+>com/fluendo/jkate/*
 297+com/fluendo/jtiger/*
 298+com/fluendo/plugin/Kate*
 299+</echo>
 300+ <echo file="${out.buildtyped}/plugins.ini" append="true"
 301+>com.fluendo.plugin.KateDec
 302+com.fluendo.plugin.KateOverlay
 303+</echo>
 304+ </target>
 305+
284306 <!-- COMPILATION -->
285307
286308 <!-- FIXME: not used currently -->
@@ -358,6 +380,36 @@
359381 </javac>
360382 </target>
361383
 384+ <target name="compile-jkate"
 385+ description="compile com.fluendo.jkate source"
 386+ depends="init,compile-utils,compile-jcraft"
 387+ >
 388+ <javac
 389+ srcdir="${src}"
 390+ destdir="${out.buildtyped}"
 391+ target="1.1" source="1.3"
 392+ debug="${build.isdebug}" debuglevel="${build.debuglevel}"
 393+ >
 394+ <include name="com/fluendo/jkate/**" />
 395+ <compilerarg line="${build.flags}" />
 396+ </javac>
 397+ </target>
 398+
 399+ <target name="compile-jtiger"
 400+ description="compile com.fluendo.jtiger source"
 401+ depends="init,compile-utils,compile-jkate"
 402+ >
 403+ <javac
 404+ srcdir="${src}"
 405+ destdir="${out.buildtyped}"
 406+ target="1.1" source="1.3"
 407+ debug="${build.isdebug}" debuglevel="${build.debuglevel}"
 408+ >
 409+ <include name="com/fluendo/jtiger/**" />
 410+ <compilerarg line="${build.flags}" />
 411+ </javac>
 412+ </target>
 413+
362414 <target name="compile-codecs"
363415 description="compile com.fluendo.codecs source"
364416 depends="init,compile-utils"
@@ -439,7 +491,7 @@
440492
441493 <target name="compile"
442494 description="compile the source"
443 - depends="init,compile-stubs,compile-jcraft,compile-jst,compile-jheora,compile-codecs,compile-plugin,compile-player,compile-examples" />
 495+ depends="init,compile-stubs,compile-jcraft,compile-jst,compile-jheora,compile-jkate,compile-jtiger,compile-codecs,compile-plugin,compile-player,compile-examples" />
444496
445497 <!-- only here for reference -->
446498 <target name="oldcompile">
@@ -494,6 +546,16 @@
495547 includes="com/fluendo/jheora/*" />
496548 </target>
497549
 550+ <target name="jar-jkate" depends="compile-jkate">
 551+ <jar jarfile="${out.dist}/${build.type}/jkate.jar" basedir="${out.buildtyped}"
 552+ includes="com/fluendo/jkate/*" />
 553+ </target>
 554+
 555+ <target name="jar-jtiger" depends="compile-jtiger">
 556+ <jar jarfile="${out.dist}/${build.type}/jtiger.jar" basedir="${out.buildtyped}"
 557+ includes="com/fluendo/jtiger/*" />
 558+ </target>
 559+
498560 <target name="jar-jst" depends="compile-jst">
499561 <jar jarfile="${out.dist}/${build.type}/jst.jar" basedir="${out.buildtyped}"
500562 includes="com/fluendo/jst/*" />
@@ -515,7 +577,7 @@
516578 <target name="applet-ovt" depends="compile"
517579 description="generate the Ogg/Vorbis+Theora applet">
518580 <antcall target="includes">
519 - <param name="exclude" value="Smoke,Jpeg,Multipart,Mulaw" />
 581+ <param name="exclude" value="Smoke,Jpeg,Multipart,Mulaw,Kate" />
520582 </antcall>
521583 <jar jarfile="${out.dist}/applet/cortado-ovt-${build.type}-${real_version}.jar"
522584 includesfile="${out.buildtyped}/includes"
@@ -526,7 +588,7 @@
527589 <target name="applet-ov" depends="compile"
528590 description="generate the Ogg/Vorbis applet">
529591 <antcall target="includes">
530 - <param name="exclude" value="Smoke,Jpeg,Multipart,Mulaw,Theora" />
 592+ <param name="exclude" value="Smoke,Jpeg,Multipart,Mulaw,Theora,Kate" />
531593 </antcall>
532594 <jar jarfile="${out.dist}/applet/cortado-ov-${build.type}-${real_version}.jar"
533595 includesfile="${out.buildtyped}/includes"
@@ -534,10 +596,21 @@
535597 </jar>
536598 </target>
537599
 600+ <target name="applet-ovtk" depends="compile"
 601+ description="generate the Ogg/Vorbis+Theora+Kate applet">
 602+ <antcall target="includes">
 603+ <param name="exclude" value="Smoke,Jpeg,Multipart,Mulaw" />
 604+ </antcall>
 605+ <jar jarfile="${out.dist}/applet/cortado-ovtk-${build.type}-${real_version}.jar"
 606+ includesfile="${out.buildtyped}/includes"
 607+ basedir="${out.buildtyped}">
 608+ </jar>
 609+ </target>
 610+
538611 <target name="applet-mmjs" depends="compile"
539612 description="generate the Multipart/Mulaw+Smoke+Jpeg applet">
540613 <antcall target="includes">
541 - <param name="exclude" value="Ogg,Vorbis,Theora" />
 614+ <param name="exclude" value="Ogg,Vorbis,Theora,Kate" />
542615 </antcall>
543616 <jar jarfile="${out.dist}/applet/cortado-mmjs-${build.type}-${real_version}.jar"
544617 includesfile="${out.buildtyped}/includes"
@@ -546,10 +619,10 @@
547620 </target>
548621
549622
550 - <target name="applet" depends="applet-ovt,applet-ov,applet-mmjs"
 623+ <target name="applet" depends="applet-ovt,applet-ov,applet-ovtk,applet-mmjs"
551624 description="generate all applets" />
552625
553 - <target name="jar" depends="jar-jcraft,jar-utils,jar-jheora,jar-jst,jar-codecs,jar-plugin,jar-player"
 626+ <target name="jar" depends="jar-jcraft,jar-utils,jar-jheora,jar-jkate,jar-jtiger,jar-jst,jar-codecs,jar-plugin,jar-player"
554627 description="generate all jar files" />
555628
556629 <!-- instead of using depends, which doesn't necessarily preserve order,
@@ -641,6 +714,8 @@
642715 <include name="src/com/jcraft/jogg/*.java" />
643716 <include name="src/com/jcraft/jorbis/*.java" />
644717 <include name="src/com/fluendo/jheora/*.java" />
 718+ <include name="src/com/fluendo/jkate/*.java" />
 719+ <include name="src/com/fluendo/jtiger/*.java" />
645720 <include name="src/com/fluendo/player/*.java" />
646721 <include name="src/com/fluendo/utils/*.java" />
647722 <include name="src/com/fluendo/codecs/*.java" />
Index: trunk/cortado/plugins.ini
@@ -3,9 +3,14 @@
44 com.fluendo.plugin.VideoSink
55 com.fluendo.plugin.AudioSinkJ2
66 com.fluendo.plugin.AudioSinkSA
 7+com.fluendo.plugin.Overlay
 8+com.fluendo.plugin.TextOverlay
 9+com.fluendo.plugin.KateOverlay
 10+com.fluendo.plugin.Selector
711 com.fluendo.plugin.OggDemux
812 com.fluendo.plugin.TheoraDec
913 com.fluendo.plugin.VorbisDec
 14+com.fluendo.plugin.KateDec
1015 com.fluendo.plugin.Queue
1116 com.fluendo.plugin.MultipartDemux
1217 com.fluendo.plugin.JPEGDec

Status & tagging log