www in docker support

This commit is contained in:
MaddoScientisto 2026-04-22 18:41:37 +02:00
commit c227fce036
2145 changed files with 399596 additions and 58 deletions

View file

@ -0,0 +1,30 @@
package org.jcodec.common.model;
import java.nio.ByteBuffer;
import org.jcodec.common.AudioFormat;
public class AudioBuffer {
protected ByteBuffer data;
protected AudioFormat format;
protected int nFrames;
public AudioBuffer(ByteBuffer data, AudioFormat format, int nFrames) {
this.data = data;
this.format = format;
this.nFrames = nFrames;
}
public ByteBuffer getData() {
return this.data;
}
public AudioFormat getFormat() {
return this.format;
}
public int getNFrames() {
return this.nFrames;
}
}

View file

@ -0,0 +1,38 @@
package org.jcodec.common.model;
import java.nio.ByteBuffer;
import org.jcodec.common.AudioFormat;
public class AudioFrame extends AudioBuffer {
private long pts;
private long duration;
private long timescale;
private int frameNo;
public AudioFrame(ByteBuffer buffer, AudioFormat format, int nFrames, long pts, long duration, long timescale, int frameNo) {
super(buffer, format, nFrames);
this.pts = pts;
this.duration = duration;
this.timescale = timescale;
this.frameNo = frameNo;
}
public long getPts() {
return this.pts;
}
public long getDuration() {
return this.duration;
}
public long getTimescale() {
return this.timescale;
}
public int getFrameNo() {
return this.frameNo;
}
}

View file

@ -0,0 +1,5 @@
package org.jcodec.common.model;
public enum ChannelLabel {
MONO, STEREO_LEFT, STEREO_RIGHT, LEFT_TOTAL, RIGHT_TOTAL, FRONT_LEFT, FRONT_RIGHT, CENTER, LFE, REAR_LEFT, REAR_RIGHT, FRONT_CENTER_LEFT, FRONT_CENTER_RIGHT, REAR_CENTER, SIDE_LEFT, SIDE_RIGHT;
}

View file

@ -0,0 +1,102 @@
package org.jcodec.common.model;
public final class ColorSpace {
public static final int MAX_PLANES = 4;
public int nComp;
public int[] compPlane;
public int[] compWidth;
public int[] compHeight;
public boolean planar;
private String _name;
public int bitsPerPixel;
private ColorSpace(String name, int nComp, int[] compPlane, int[] compWidth, int[] compHeight, boolean planar) {
this._name = name;
this.nComp = nComp;
this.compPlane = compPlane;
this.compWidth = compWidth;
this.compHeight = compHeight;
this.planar = planar;
this.bitsPerPixel = calcBitsPerPixel(nComp, compWidth, compHeight);
}
public String toString() {
return this._name;
}
private static int calcBitsPerPixel(int nComp, int[] compWidth, int[] compHeight) {
int bitsPerPixel = 0;
for (int i = 0; i < nComp; i++)
bitsPerPixel += 8 >> compWidth[i] >> compHeight[i];
return bitsPerPixel;
}
public int getWidthMask() {
return ((this.nComp > 1) ? this.compWidth[1] : 0) ^ 0xFFFFFFFF;
}
public int getHeightMask() {
return ((this.nComp > 1) ? this.compHeight[1] : 0) ^ 0xFFFFFFFF;
}
public boolean matches(ColorSpace inputColor) {
if (inputColor == this)
return true;
if (inputColor == ANY || this == ANY)
return true;
if ((inputColor == ANY_INTERLEAVED || this == ANY_INTERLEAVED || inputColor == ANY_PLANAR || this == ANY_PLANAR) && inputColor.planar == this.planar)
return true;
return false;
}
public Size compSize(Size size, int comp) {
if (this.compWidth[comp] == 0 && this.compHeight[comp] == 0)
return size;
return new Size(size.getWidth() >> this.compWidth[comp], size.getHeight() >> this.compHeight[comp]);
}
private static final int[] _000 = new int[] { 0, 0, 0 };
private static final int[] _011 = new int[] { 0, 1, 1 };
private static final int[] _012 = new int[] { 0, 1, 2 };
public static final ColorSpace BGR = new ColorSpace("BGR", 3, _000, _000, _000, false);
public static final ColorSpace RGB = new ColorSpace("RGB", 3, _000, _000, _000, false);
public static final ColorSpace YUV420 = new ColorSpace("YUV420", 3, _012, _011, _011, true);
public static final ColorSpace YUV420J = new ColorSpace("YUV420J", 3, _012, _011, _011, true);
public static final ColorSpace YUV422 = new ColorSpace("YUV422", 3, _012, _011, _000, true);
public static final ColorSpace YUV422J = new ColorSpace("YUV422J", 3, _012, _011, _000, true);
public static final ColorSpace YUV444 = new ColorSpace("YUV444", 3, _012, _000, _000, true);
public static final ColorSpace YUV444J = new ColorSpace("YUV444J", 3, _012, _000, _000, true);
public static final ColorSpace YUV422_10 = new ColorSpace("YUV422_10", 3, _012, _011, _000, true);
public static final ColorSpace GREY = new ColorSpace("GREY", 1, new int[] { 0 }, new int[] { 0 }, new int[] { 0 }, true);
public static final ColorSpace MONO = new ColorSpace("MONO", 1, _000, _000, _000, true);
public static final ColorSpace YUV444_10 = new ColorSpace("YUV444_10", 3, _012, _000, _000, true);
public static final ColorSpace ANY = new ColorSpace("ANY", 0, null, null, null, true);
public static final ColorSpace ANY_PLANAR = new ColorSpace("ANY_PLANAR", 0, null, null, null, true);
public static final ColorSpace ANY_INTERLEAVED = new ColorSpace("ANY_INTERLEAVED", 0, null, null, null, false);
public static final ColorSpace SAME = new ColorSpace("SAME", 0, null, null, null, false);
}

View file

@ -0,0 +1,61 @@
package org.jcodec.common.model;
import java.util.List;
public class Frame {
private Picture pic;
private RationalLarge pts;
private RationalLarge duration;
private Rational pixelAspect;
private TapeTimecode tapeTimecode;
private int frameNo;
private List<String> messages;
public Frame(Picture pic, RationalLarge pts, RationalLarge duration, Rational pixelAspect, int frameNo, TapeTimecode tapeTimecode, List<String> messages) {
this.pic = pic;
this.pts = pts;
this.duration = duration;
this.pixelAspect = pixelAspect;
this.tapeTimecode = tapeTimecode;
this.frameNo = frameNo;
this.messages = messages;
}
public Picture getPic() {
return this.pic;
}
public RationalLarge getPts() {
return this.pts;
}
public RationalLarge getDuration() {
return this.duration;
}
public Rational getPixelAspect() {
return this.pixelAspect;
}
public TapeTimecode getTapeTimecode() {
return this.tapeTimecode;
}
public int getFrameNo() {
return this.frameNo;
}
public List<String> getMessages() {
return this.messages;
}
public boolean isAvailable() {
return true;
}
}

View file

@ -0,0 +1,165 @@
package org.jcodec.common.model;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
public final class Label {
private static final List<Label> _values = new ArrayList<>();
public static final Label Unknown = new Label(-1);
public static final Label Unused = new Label(0);
public static final Label UseCoordinates = new Label(100);
public static final Label Left = new Label(1);
public static final Label Right = new Label(2);
public static final Label Center = new Label(3);
public static final Label LFEScreen = new Label(4);
public static final Label LeftSurround = new Label(5);
public static final Label RightSurround = new Label(6);
public static final Label LeftCenter = new Label(7);
public static final Label RightCenter = new Label(8);
public static final Label CenterSurround = new Label(9);
public static final Label LeftSurroundDirect = new Label(10);
public static final Label RightSurroundDirect = new Label(11);
public static final Label TopCenterSurround = new Label(12);
public static final Label VerticalHeightLeft = new Label(13);
public static final Label VerticalHeightCenter = new Label(14);
public static final Label VerticalHeightRight = new Label(15);
public static final Label TopBackLeft = new Label(16);
public static final Label TopBackCenter = new Label(17);
public static final Label TopBackRight = new Label(18);
public static final Label RearSurroundLeft = new Label(33);
public static final Label RearSurroundRight = new Label(34);
public static final Label LeftWide = new Label(35);
public static final Label RightWide = new Label(36);
public static final Label LFE2 = new Label(37);
public static final Label LeftTotal = new Label(38);
public static final Label RightTotal = new Label(39);
public static final Label HearingImpaired = new Label(40);
public static final Label Narration = new Label(41);
public static final Label Mono = new Label(42);
public static final Label DialogCentricMix = new Label(43);
public static final Label CenterSurroundDirect = new Label(44);
public static final Label Ambisonic_W = new Label(200);
public static final Label Ambisonic_X = new Label(201);
public static final Label Ambisonic_Y = new Label(202);
public static final Label Ambisonic_Z = new Label(203);
public static final Label MS_Mid = new Label(204);
public static final Label MS_Side = new Label(205);
public static final Label XY_X = new Label(206);
public static final Label XY_Y = new Label(207);
public static final Label HeadphonesLeft = new Label(301);
public static final Label HeadphonesRight = new Label(302);
public static final Label ClickTrack = new Label(304);
public static final Label ForeignLanguage = new Label(305);
public static final Label Discrete = new Label(400);
public static final Label Discrete_0 = new Label(65536);
public static final Label Discrete_1 = new Label(65537);
public static final Label Discrete_2 = new Label(65538);
public static final Label Discrete_3 = new Label(65539);
public static final Label Discrete_4 = new Label(65540);
public static final Label Discrete_5 = new Label(65541);
public static final Label Discrete_6 = new Label(65542);
public static final Label Discrete_7 = new Label(65543);
public static final Label Discrete_8 = new Label(65544);
public static final Label Discrete_9 = new Label(65545);
public static final Label Discrete_10 = new Label(65546);
public static final Label Discrete_11 = new Label(65547);
public static final Label Discrete_12 = new Label(65548);
public static final Label Discrete_13 = new Label(65549);
public static final Label Discrete_14 = new Label(65550);
public static final Label Discrete_15 = new Label(65551);
public static final Label Discrete_65535 = new Label(131071);
final int labelVal;
public final long bitmapVal;
public static final Pattern channelMappingRegex = Pattern.compile("[_\\ \\.][a-zA-Z]+$");
private Label(int val) {
this.labelVal = val;
this.bitmapVal = (this.labelVal > 18 || this.labelVal < 1) ? 0L : (long)(1 << this.labelVal - 1);
_values.add(this);
}
public static Label[] values() {
return _values.<Label>toArray(new Label[0]);
}
public static Label getByVal(int val) {
Label[] values = values();
for (int i = 0; i < values.length; i++) {
Label label = values[i];
if (label.labelVal == val)
return label;
}
return Mono;
}
public int getVal() {
return this.labelVal;
}
}

View file

@ -0,0 +1,133 @@
package org.jcodec.common.model;
import java.nio.ByteBuffer;
import java.util.Comparator;
public class Packet {
public ByteBuffer data;
public long pts;
public int timescale;
public long duration;
public long frameNo;
public FrameType frameType;
public TapeTimecode tapeTimecode;
public int displayOrder;
public enum FrameType {
KEY, INTER, UNKNOWN;
}
public static Packet createPacket(ByteBuffer data, long pts, int timescale, long duration, long frameNo, FrameType frameType, TapeTimecode tapeTimecode) {
return new Packet(data, pts, timescale, duration, frameNo, frameType, tapeTimecode, 0);
}
public static Packet createPacketWithData(Packet other, ByteBuffer data) {
return new Packet(data, other.pts, other.timescale, other.duration, other.frameNo, other.frameType, other.tapeTimecode, other.displayOrder);
}
public Packet(ByteBuffer data, long pts, int timescale, long duration, long frameNo, FrameType frameType, TapeTimecode tapeTimecode, int displayOrder) {
this.data = data;
this.pts = pts;
this.timescale = timescale;
this.duration = duration;
this.frameNo = frameNo;
this.frameType = frameType;
this.tapeTimecode = tapeTimecode;
this.displayOrder = displayOrder;
}
public ByteBuffer getData() {
return this.data.duplicate();
}
public long getPts() {
return this.pts;
}
public int getTimescale() {
return this.timescale;
}
public long getDuration() {
return this.duration;
}
public long getFrameNo() {
return this.frameNo;
}
public void setTimescale(int timescale) {
this.timescale = timescale;
}
public TapeTimecode getTapeTimecode() {
return this.tapeTimecode;
}
public void setTapeTimecode(TapeTimecode tapeTimecode) {
this.tapeTimecode = tapeTimecode;
}
public int getDisplayOrder() {
return this.displayOrder;
}
public void setDisplayOrder(int displayOrder) {
this.displayOrder = displayOrder;
}
public FrameType getFrameType() {
return this.frameType;
}
public void setFrameType(FrameType frameType) {
this.frameType = frameType;
}
public RationalLarge getPtsR() {
return RationalLarge.R(this.pts, (long)this.timescale);
}
public double getPtsD() {
return (double)this.pts / (double)this.timescale;
}
public double getDurationD() {
return (double)this.duration / (double)this.timescale;
}
public void setData(ByteBuffer data) {
this.data = data;
}
public void setPts(long pts) {
this.pts = pts;
}
public static final Comparator<Packet> FRAME_ASC = new Comparator<>() {
public int compare(Packet o1, Packet o2) {
if (o1 == null && o2 == null)
return 0;
if (o1 == null)
return -1;
if (o2 == null)
return 1;
return (o1.frameNo < o2.frameNo) ? -1 : ((o1.frameNo == o2.frameNo) ? 0 : 1);
}
};
public void setDuration(long duration) {
this.duration = duration;
}
public boolean isKeyFrame() {
return (this.frameType == FrameType.KEY);
}
}

View file

@ -0,0 +1,307 @@
package org.jcodec.common.model;
import java.util.Arrays;
import org.jcodec.common.tools.MathUtil;
public class Picture {
private ColorSpace color;
private int width;
private int height;
private byte[][] data;
private byte[][] lowBits;
private int lowBitsNum;
private Rect crop;
public static Picture createPicture(int width, int height, byte[][] data, ColorSpace color) {
return new Picture(width, height, data, null, color, 0, new Rect(0, 0, width, height));
}
public static Picture createPictureHiBD(int width, int height, byte[][] data, byte[][] lowBits, ColorSpace color, int lowBitsNum) {
return new Picture(width, height, data, lowBits, color, lowBitsNum, new Rect(0, 0, width, height));
}
public Picture(int width, int height, byte[][] data, byte[][] lowBits, ColorSpace color, int lowBitsNum, Rect crop) {
this.width = width;
this.height = height;
this.data = data;
this.lowBits = lowBits;
this.color = color;
this.lowBitsNum = lowBitsNum;
this.crop = crop;
if (color != null)
for (int i = 0; i < color.nComp; i++) {
int mask = 255 >> 8 - color.compWidth[i];
if ((width & mask) != 0)
throw new IllegalArgumentException("Component " + i + " width should be a multiple of " + (1 << color.compWidth[i]) + " for colorspace: " + String.valueOf(color));
if (crop != null && (crop.getWidth() & mask) != 0)
throw new IllegalArgumentException("Component " + i + " cropped width should be a multiple of " + (1 << color.compWidth[i]) + " for colorspace: " + String.valueOf(color));
mask = 255 >> 8 - color.compHeight[i];
if ((height & mask) != 0)
throw new IllegalArgumentException("Component " + i + " height should be a multiple of " + (1 << color.compHeight[i]) + " for colorspace: " + String.valueOf(color));
if (crop != null && (crop.getHeight() & mask) != 0)
throw new IllegalArgumentException("Component " + i + " cropped height should be a multiple of " + (1 << color.compHeight[i]) + " for colorspace: " + String.valueOf(color));
}
}
public static Picture copyPicture(Picture other) {
return new Picture(other.width, other.height, other.data, other.lowBits, other.color, 0, other.crop);
}
public static Picture create(int width, int height, ColorSpace colorSpace) {
return createCropped(width, height, colorSpace, null);
}
public static Picture createCropped(int width, int height, ColorSpace colorSpace, Rect crop) {
int[] planeSizes = new int[4];
for (int i = 0; i < colorSpace.nComp; i++)
planeSizes[colorSpace.compPlane[i]] = planeSizes[colorSpace.compPlane[i]] + (width >> colorSpace.compWidth[i]) * (height >> colorSpace.compHeight[i]);
int nPlanes = 0;
for (int j = 0; j < 4; j++)
nPlanes += (planeSizes[j] != 0) ? 1 : 0;
byte[][] data = new byte[nPlanes][];
for (int k = 0, plane = 0; k < 4; k++) {
if (planeSizes[k] != 0)
data[plane++] = new byte[planeSizes[k]];
}
return new Picture(width, height, data, null, colorSpace, 0, crop);
}
public static Picture createCroppedHiBD(int width, int height, int lowBitsNum, ColorSpace colorSpace, Rect crop) {
Picture result = createCropped(width, height, colorSpace, crop);
if (lowBitsNum <= 0)
return result;
byte[][] data = result.getData();
int nPlanes = data.length;
byte[][] lowBits = new byte[nPlanes][];
for (int i = 0, plane = 0; i < nPlanes; i++)
lowBits[plane++] = new byte[(data[i]).length];
result.setLowBits(lowBits);
result.setLowBitsNum(lowBitsNum);
return result;
}
private void setLowBitsNum(int lowBitsNum) {
this.lowBitsNum = lowBitsNum;
}
private void setLowBits(byte[][] lowBits) {
this.lowBits = lowBits;
}
public int getWidth() {
return this.width;
}
public int getHeight() {
return this.height;
}
public byte[] getPlaneData(int plane) {
return this.data[plane];
}
public ColorSpace getColor() {
return this.color;
}
public byte[][] getData() {
return this.data;
}
public byte[][] getLowBits() {
return this.lowBits;
}
public Rect getCrop() {
return this.crop;
}
public int getPlaneWidth(int plane) {
return this.width >> this.color.compWidth[plane];
}
public int getPlaneHeight(int plane) {
return this.height >> this.color.compHeight[plane];
}
public boolean compatible(Picture src) {
return (src.color == this.color && src.width == this.width && src.height == this.height);
}
public Picture createCompatible() {
return create(this.width, this.height, this.color);
}
public void copyFrom(Picture src) {
if (!compatible(src))
throw new IllegalArgumentException("Can not copy to incompatible picture");
for (int plane = 0; plane < this.color.nComp; plane++) {
if (this.data[plane] != null)
System.arraycopy(src.data[plane], 0, this.data[plane], 0, (this.width >> this.color.compWidth[plane]) * (this.height >> this.color.compHeight[plane]));
}
}
public Picture cloneCropped() {
if (cropNeeded())
return cropped();
Picture clone = createCompatible();
clone.copyFrom(this);
return clone;
}
public Picture cropped() {
if (!cropNeeded())
return this;
Picture result = create(this.crop.getWidth(), this.crop.getHeight(), this.color);
if (this.color.planar) {
for (int plane = 0; plane < this.data.length; plane++) {
if (this.data[plane] != null)
cropSub(this.data[plane], this.crop.getX() >> this.color.compWidth[plane], this.crop.getY() >> this.color.compHeight[plane],
this.crop.getWidth() >> this.color.compWidth[plane], this.crop.getHeight() >> this.color.compHeight[plane], this.width >> this.color.compWidth[plane],
this.crop.getWidth() >> this.color.compWidth[plane], result.data[plane]);
}
} else {
cropSub(this.data[0], this.crop.getX(), this.crop.getY(), this.crop.getWidth(),
this.crop.getHeight(), this.width * this.color.nComp, this.crop.getWidth() * this.color.nComp, result.data[0]);
}
return result;
}
protected boolean cropNeeded() {
return (this.crop != null && (
this.crop.getX() != 0 || this.crop.getY() != 0 || this.crop.getWidth() != this.width || this.crop.getHeight() != this.height));
}
private void cropSub(byte[] src, int x, int y, int w, int h, int srcStride, int dstStride, byte[] tgt) {
int srcOff = y * srcStride + x, dstOff = 0;
for (int i = 0; i < h; i++) {
for (int j = 0; j < dstStride; j++)
tgt[dstOff + j] = src[srcOff + j];
srcOff += srcStride;
dstOff += dstStride;
}
}
public void setCrop(Rect crop) {
this.crop = crop;
}
public int getCroppedWidth() {
return (this.crop == null) ? this.width : this.crop.getWidth();
}
public int getCroppedHeight() {
return (this.crop == null) ? this.height : this.crop.getHeight();
}
public int getLowBitsNum() {
return this.lowBitsNum;
}
public static Picture fromPictureHiBD(PictureHiBD pic) {
int lowBitsNum = pic.getBitDepth() - 8;
int lowBitsRound = 1 << lowBitsNum >> 1;
Picture result = createCroppedHiBD(pic.getWidth(), pic.getHeight(), lowBitsNum, pic.getColor(),
pic.getCrop());
for (int i = 0; i < Math.min((pic.getData()).length, (result.getData()).length); i++) {
for (int j = 0; j < Math.min((pic.getData()[i]).length, (result.getData()[i]).length); j++) {
int val = pic.getData()[i][j];
int round = MathUtil.clip(val + lowBitsRound >> lowBitsNum, 0, 255);
result.getData()[i][j] = (byte)(round - 128);
}
}
byte[][] lowBits = result.getLowBits();
if (lowBits != null)
for (int j = 0; j < Math.min((pic.getData()).length, (result.getData()).length); j++) {
for (int k = 0; k < Math.min((pic.getData()[j]).length, (result.getData()[j]).length); k++) {
int val = pic.getData()[j][k];
int round = MathUtil.clip(val + lowBitsRound >> lowBitsNum, 0, 255);
lowBits[j][k] = (byte)(val - (round << 2));
}
}
return result;
}
public PictureHiBD toPictureHiBD() {
PictureHiBD create = PictureHiBD.doCreate(this.width, this.height, this.color, this.lowBitsNum + 8, this.crop);
return toPictureHiBDInternal(create);
}
public PictureHiBD toPictureHiBDWithBuffer(int[][] buffer) {
PictureHiBD create = new PictureHiBD(this.width, this.height, buffer, this.color, this.lowBitsNum + 8, this.crop);
return toPictureHiBDInternal(create);
}
private PictureHiBD toPictureHiBDInternal(PictureHiBD pic) {
int[][] dstData = pic.getData();
for (int i = 0; i < this.data.length; i++) {
int planeSize = getPlaneWidth(i) * getPlaneHeight(i);
for (int j = 0; j < planeSize; j++)
dstData[i][j] = this.data[i][j] + 128 << this.lowBitsNum;
}
if (this.lowBits != null)
for (int j = 0; j < this.lowBits.length; j++) {
int planeSize = getPlaneWidth(j) * getPlaneHeight(j);
for (int k = 0; k < planeSize; k++)
dstData[j][k] = dstData[j][k] + this.lowBits[j][k];
}
return pic;
}
public void fill(int val) {
for (int i = 0; i < this.data.length; i++)
Arrays.fill(this.data[i], (byte)val);
}
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof Picture))
return false;
Picture other = (Picture)obj;
if (other.getCroppedWidth() != getCroppedWidth() || other.getCroppedHeight() != getCroppedHeight() ||
other.getColor() != this.color)
return false;
for (int i = 0; i < (getData()).length; i++) {
if (!planeEquals(other, i))
return false;
}
return true;
}
private boolean planeEquals(Picture other, int plane) {
int cw = this.color.compWidth[plane];
int ch = this.color.compHeight[plane];
int offA = (other.getCrop() == null) ? 0 : ((other.getCrop().getX() >> cw) + (other.getCrop().getY() >> ch) * (
other.getWidth() >> cw));
int offB = (this.crop == null) ? 0 : ((this.crop.getX() >> cw) + (this.crop.getY() >> ch) * (this.width >> cw));
byte[] planeData = other.getPlaneData(plane);
for (int i = 0; i < getCroppedHeight() >> ch; i++, offA += other.getWidth() >> cw, offB += this.width >> cw) {
for (int j = 0; j < getCroppedWidth() >> cw; j++) {
if (planeData[offA + j] != this.data[plane][offB + j])
return false;
}
}
return true;
}
public int getStartX() {
return (this.crop == null) ? 0 : this.crop.getX();
}
public int getStartY() {
return (this.crop == null) ? 0 : this.crop.getY();
}
public boolean isHiBD() {
return (this.lowBits != null);
}
public Size getSize() {
return new Size(this.width, this.height);
}
}

View file

@ -0,0 +1,189 @@
package org.jcodec.common.model;
public class PictureHiBD {
private ColorSpace color;
private int width;
private int height;
private int[][] data;
private Rect crop;
private int bitDepth;
public static PictureHiBD createPicture(int width, int height, int[][] data, ColorSpace color) {
return new PictureHiBD(width, height, data, color, 8, new Rect(0, 0, width, height));
}
public static PictureHiBD createPictureWithDepth(int width, int height, int[][] data, ColorSpace color, int bitDepth) {
return new PictureHiBD(width, height, data, color, bitDepth, new Rect(0, 0, width, height));
}
public static PictureHiBD createPictureCropped(int width, int height, int[][] data, ColorSpace color, Rect crop) {
return new PictureHiBD(width, height, data, color, 8, crop);
}
public PictureHiBD(int width, int height, int[][] data, ColorSpace color, int bitDepth, Rect crop) {
this.width = width;
this.height = height;
this.data = data;
this.color = color;
this.crop = crop;
this.bitDepth = bitDepth;
}
public static PictureHiBD clonePicture(PictureHiBD other) {
return new PictureHiBD(other.width, other.height, other.data, other.color, other.bitDepth, other.crop);
}
public static PictureHiBD create(int width, int height, ColorSpace colorSpace) {
return doCreate(width, height, colorSpace, 8, null);
}
public static PictureHiBD createWithDepth(int width, int height, ColorSpace colorSpace, int bitDepth) {
return doCreate(width, height, colorSpace, bitDepth, null);
}
public static PictureHiBD createCropped(int width, int height, ColorSpace colorSpace, Rect crop) {
return doCreate(width, height, colorSpace, 8, crop);
}
public static PictureHiBD doCreate(int width, int height, ColorSpace colorSpace, int bitDepth, Rect crop) {
int[] planeSizes = new int[4];
for (int i = 0; i < colorSpace.nComp; i++)
planeSizes[colorSpace.compPlane[i]] = planeSizes[colorSpace.compPlane[i]] + (width >> colorSpace.compWidth[i]) * (height >> colorSpace.compHeight[i]);
int nPlanes = 0;
for (int j = 0; j < 4; j++)
nPlanes += (planeSizes[j] != 0) ? 1 : 0;
int[][] data = new int[nPlanes][];
for (int k = 0, plane = 0; k < 4; k++) {
if (planeSizes[k] != 0)
data[plane++] = new int[planeSizes[k]];
}
return new PictureHiBD(width, height, data, colorSpace, 8, crop);
}
public int getWidth() {
return this.width;
}
public int getHeight() {
return this.height;
}
public int[] getPlaneData(int plane) {
return this.data[plane];
}
public ColorSpace getColor() {
return this.color;
}
public int[][] getData() {
return this.data;
}
public Rect getCrop() {
return this.crop;
}
public int getPlaneWidth(int plane) {
return this.width >> this.color.compWidth[plane];
}
public int getPlaneHeight(int plane) {
return this.height >> this.color.compHeight[plane];
}
public boolean compatible(PictureHiBD src) {
return (src.color == this.color && src.width == this.width && src.height == this.height);
}
public PictureHiBD createCompatible() {
return create(this.width, this.height, this.color);
}
public void copyFrom(PictureHiBD src) {
if (!compatible(src))
throw new IllegalArgumentException("Can not copy to incompatible picture");
for (int plane = 0; plane < this.color.nComp; plane++) {
if (this.data[plane] != null)
System.arraycopy(src.data[plane], 0, this.data[plane], 0, (this.width >> this.color.compWidth[plane]) * (this.height >> this.color.compHeight[plane]));
}
}
public PictureHiBD cropped() {
if (this.crop == null || (
this.crop.getX() == 0 && this.crop.getY() == 0 && this.crop.getWidth() == this.width && this.crop.getHeight() == this.height))
return this;
PictureHiBD result = create(this.crop.getWidth(), this.crop.getHeight(), this.color);
for (int plane = 0; plane < this.color.nComp; plane++) {
if (this.data[plane] != null)
cropSub(this.data[plane], this.crop.getX() >> this.color.compWidth[plane], this.crop.getY() >> this.color.compHeight[plane],
this.crop.getWidth() >> this.color.compWidth[plane], this.crop.getHeight() >> this.color.compHeight[plane], this.width >> this.color.compWidth[plane], result.data[plane]);
}
return result;
}
private void cropSub(int[] src, int x, int y, int w, int h, int srcStride, int[] tgt) {
int srcOff = y * srcStride + x, dstOff = 0;
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++)
tgt[dstOff + j] = src[srcOff + j];
srcOff += srcStride;
dstOff += w;
}
}
public void setCrop(Rect crop) {
this.crop = crop;
}
public int getCroppedWidth() {
return (this.crop == null) ? this.width : this.crop.getWidth();
}
public int getCroppedHeight() {
return (this.crop == null) ? this.height : this.crop.getHeight();
}
public void setBitDepth(int bitDepth) {
this.bitDepth = bitDepth;
}
public int getBitDepth() {
return this.bitDepth;
}
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof PictureHiBD))
return false;
PictureHiBD other = (PictureHiBD)obj;
if (other.getCroppedWidth() != getCroppedWidth() || other.getCroppedHeight() != getCroppedHeight() ||
other.getColor() != this.color)
return false;
for (int i = 0; i < (getData()).length; i++) {
if (!planeEquals(other, i))
return false;
}
return true;
}
private boolean planeEquals(PictureHiBD other, int plane) {
int cw = this.color.compWidth[plane];
int ch = this.color.compHeight[plane];
int offA = (other.getCrop() == null) ? 0 : ((
other.getCrop().getX() >> cw) + (other.getCrop().getY() >> ch) * (other.getWidth() >> cw));
int offB = (this.crop == null) ? 0 : ((this.crop.getX() >> cw) + (this.crop.getY() >> ch) * (this.width >> cw));
int[] planeData = other.getPlaneData(plane);
for (int i = 0; i < getCroppedHeight() >> ch; i++, offA += other.getWidth() >> cw, offB += this.width >> cw) {
for (int j = 0; j < getCroppedWidth() >> cw; j++) {
if (planeData[offA + j] != this.data[plane][offB + j])
return false;
}
}
return true;
}
}

View file

@ -0,0 +1,20 @@
package org.jcodec.common.model;
public class Plane {
int[] data;
Size size;
public Plane(int[] data, Size size) {
this.data = data;
this.size = size;
}
public int[] getData() {
return this.data;
}
public Size getSize() {
return this.size;
}
}

View file

@ -0,0 +1,20 @@
package org.jcodec.common.model;
public class Point {
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
}

View file

@ -0,0 +1,204 @@
package org.jcodec.common.model;
import org.jcodec.common.tools.MathUtil;
public class Rational {
public static final Rational ONE = new Rational(1, 1);
public static final Rational HALF = new Rational(1, 2);
public static final Rational ZERO = new Rational(0, 1);
public final int num;
public final int den;
public static Rational R(int num, int den) {
return new Rational(num, den);
}
public static Rational R1(int num) {
return R(num, 1);
}
public Rational(int num, int den) {
this.num = num;
this.den = den;
}
public int getNum() {
return this.num;
}
public int getDen() {
return this.den;
}
public static Rational parseRational(String string) {
return parse(string);
}
public static Rational parse(String string) {
int idx = string.indexOf(":");
if (idx < 0)
idx = string.indexOf("/");
if (idx > 0) {
String num = string.substring(0, idx);
String den = string.substring(idx + 1);
return new Rational(Integer.parseInt(num), Integer.parseInt(den));
}
return R(Integer.parseInt(string), 1);
}
public int hashCode() {
int prime = 31;
int result = 1;
result = 31 * result + this.den;
result = 31 * result + this.num;
return result;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Rational other = (Rational)obj;
if (this.den != other.den)
return false;
if (this.num != other.num)
return false;
return true;
}
public int multiplyS(int val) {
return (int)((long)this.num * (long)val / (long)this.den);
}
public int divideS(int val) {
return (int)((long)this.den * (long)val / (long)this.num);
}
public int divideByS(int val) {
return this.num / (this.den * val);
}
public long multiplyLong(long val) {
return (long)this.num * val / (long)this.den;
}
public long divideLong(long val) {
return (long)this.den * val / (long)this.num;
}
public Rational flip() {
return new Rational(this.den, this.num);
}
public boolean smallerThen(Rational sec) {
return (this.num * sec.den < sec.num * this.den);
}
public boolean greaterThen(Rational sec) {
return (this.num * sec.den > sec.num * this.den);
}
public boolean smallerOrEqualTo(Rational sec) {
return (this.num * sec.den <= sec.num * this.den);
}
public boolean greaterOrEqualTo(Rational sec) {
return (this.num * sec.den >= sec.num * this.den);
}
public boolean equalsRational(Rational other) {
return (this.num * other.den == other.num * this.den);
}
public Rational plus(Rational other) {
return reduce(this.num * other.den + other.num * this.den, this.den * other.den);
}
public RationalLarge plusLarge(RationalLarge other) {
return RationalLarge.reduceLong((long)this.num * other.den + other.num * (long)this.den, (long)this.den * other.den);
}
public Rational minus(Rational other) {
return reduce(this.num * other.den - other.num * this.den, this.den * other.den);
}
public RationalLarge minusLarge(RationalLarge other) {
return RationalLarge.reduceLong((long)this.num * other.den - other.num * (long)this.den, (long)this.den * other.den);
}
public Rational plusInt(int scalar) {
return new Rational(this.num + scalar * this.den, this.den);
}
public Rational minusInt(int scalar) {
return new Rational(this.num - scalar * this.den, this.den);
}
public Rational multiplyInt(int scalar) {
return new Rational(this.num * scalar, this.den);
}
public Rational divideInt(int scalar) {
return new Rational(this.den * scalar, this.num);
}
public Rational divideByInt(int scalar) {
return new Rational(this.num, this.den * scalar);
}
public Rational multiply(Rational other) {
return reduce(this.num * other.num, this.den * other.den);
}
public RationalLarge multiplyLarge(RationalLarge other) {
return RationalLarge.reduceLong((long)this.num * other.num, (long)this.den * other.den);
}
public Rational divide(Rational other) {
return reduce(other.num * this.den, other.den * this.num);
}
public RationalLarge divideLarge(RationalLarge other) {
return RationalLarge.reduceLong(other.num * (long)this.den, other.den * (long)this.num);
}
public Rational divideBy(Rational other) {
return reduce(this.num * other.den, this.den * other.num);
}
public RationalLarge divideByLarge(RationalLarge other) {
return RationalLarge.reduceLong((long)this.num * other.den, (long)this.den * other.num);
}
public float scalar() {
return (float)this.num / (float)this.den;
}
public int scalarClip() {
return this.num / this.den;
}
public static Rational reduce(int num, int den) {
int gcd = MathUtil.gcd(num, den);
return new Rational(num / gcd, den / gcd);
}
public static Rational reduceRational(Rational r) {
return reduce(r.getNum(), r.getDen());
}
public String toString() {
return "" + this.num + "/" + this.num;
}
public double toDouble() {
return (double)this.num / (double)this.den;
}
}

View file

@ -0,0 +1,179 @@
package org.jcodec.common.model;
import org.jcodec.common.StringUtils;
import org.jcodec.common.tools.MathUtil;
public class RationalLarge {
public static final RationalLarge ONE = new RationalLarge(1L, 1L);
public static final RationalLarge HALF = new RationalLarge(1L, 2L);
public static final RationalLarge ZERO = new RationalLarge(0L, 1L);
final long num;
final long den;
public RationalLarge(long num, long den) {
this.num = num;
this.den = den;
}
public long getNum() {
return this.num;
}
public long getDen() {
return this.den;
}
public static RationalLarge parse(String string) {
String[] split = StringUtils.splitS(string, ":");
return (split.length > 1) ? R(Long.parseLong(split[0]), Long.parseLong(split[1])) :
R(Long.parseLong(string), 1L);
}
public int hashCode() {
int prime = 31;
int result = 1;
result = 31 * result + (int)(this.den ^ this.den >>> 32L);
result = 31 * result + (int)(this.num ^ this.num >>> 32L);
return result;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
RationalLarge other = (RationalLarge)obj;
if (this.den != other.den)
return false;
if (this.num != other.num)
return false;
return true;
}
public long multiplyS(long scalar) {
return this.num * scalar / this.den;
}
public long divideS(long scalar) {
return this.den * scalar / this.num;
}
public long divideByS(long scalar) {
return this.num / (this.den * scalar);
}
public RationalLarge flip() {
return new RationalLarge(this.den, this.num);
}
public static RationalLarge R(long num, long den) {
return new RationalLarge(num, den);
}
public static RationalLarge R1(long num) {
return R(num, 1L);
}
public boolean lessThen(RationalLarge sec) {
return (this.num * sec.den < sec.num * this.den);
}
public boolean greaterThen(RationalLarge sec) {
return (this.num * sec.den > sec.num * this.den);
}
public boolean smallerOrEqualTo(RationalLarge sec) {
return (this.num * sec.den <= sec.num * this.den);
}
public boolean greaterOrEqualTo(RationalLarge sec) {
return (this.num * sec.den >= sec.num * this.den);
}
public boolean equalsLarge(RationalLarge other) {
return (this.num * other.den == other.num * this.den);
}
public RationalLarge plus(RationalLarge other) {
return reduceLong(this.num * other.den + other.num * this.den, this.den * other.den);
}
public RationalLarge plusR(Rational other) {
return reduceLong(this.num * (long)other.den + (long)other.num * this.den, this.den * (long)other.den);
}
public RationalLarge minus(RationalLarge other) {
return reduceLong(this.num * other.den - other.num * this.den, this.den * other.den);
}
public RationalLarge minusR(Rational other) {
return reduceLong(this.num * (long)other.den - (long)other.num * this.den, this.den * (long)other.den);
}
public RationalLarge plusLong(long scalar) {
return new RationalLarge(this.num + scalar * this.den, this.den);
}
public RationalLarge minusLong(long scalar) {
return new RationalLarge(this.num - scalar * this.den, this.den);
}
public RationalLarge multiplyLong(long scalar) {
return new RationalLarge(this.num * scalar, this.den);
}
public RationalLarge divideLong(long scalar) {
return new RationalLarge(this.den * scalar, this.num);
}
public RationalLarge divideByLong(long scalar) {
return new RationalLarge(this.num, this.den * scalar);
}
public RationalLarge multiply(RationalLarge other) {
return reduceLong(this.num * other.num, this.den * other.den);
}
public RationalLarge multiplyR(Rational other) {
return reduceLong(this.num * (long)other.num, this.den * (long)other.den);
}
public RationalLarge divideRL(RationalLarge other) {
return reduceLong(other.num * this.den, other.den * this.num);
}
public RationalLarge divideR(Rational other) {
return reduceLong((long)other.num * this.den, (long)other.den * this.num);
}
public RationalLarge divideBy(RationalLarge other) {
return reduceLong(this.num * other.den, this.den * other.num);
}
public RationalLarge divideByR(Rational other) {
return reduceLong(this.num * (long)other.den, this.den * (long)other.num);
}
public double scalar() {
return (double)this.num / (double)this.den;
}
public long scalarClip() {
return this.num / this.den;
}
public String toString() {
return "" + this.num + ":" + this.num;
}
public static RationalLarge reduceLong(long num, long den) {
long gcd = MathUtil.gcdLong(num, den);
return new RationalLarge(num / gcd, den / gcd);
}
}

View file

@ -0,0 +1,67 @@
package org.jcodec.common.model;
public class Rect {
private int x;
private int y;
private int width;
private int height;
public Rect(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public int getWidth() {
return this.width;
}
public int getHeight() {
return this.height;
}
public int hashCode() {
int prime = 31;
int result = 1;
result = 31 * result + this.height;
result = 31 * result + this.width;
result = 31 * result + this.x;
result = 31 * result + this.y;
return result;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Rect other = (Rect)obj;
if (this.height != other.height)
return false;
if (this.width != other.width)
return false;
if (this.x != other.x)
return false;
if (this.y != other.y)
return false;
return true;
}
public String toString() {
return "Rect [x=" + this.x + ", y=" + this.y + ", width=" + this.width + ", height=" + this.height + "]";
}
}

View file

@ -0,0 +1,43 @@
package org.jcodec.common.model;
public class Size {
private int width;
private int height;
public Size(int width, int height) {
this.width = width;
this.height = height;
}
public int getWidth() {
return this.width;
}
public int getHeight() {
return this.height;
}
public int hashCode() {
int prime = 31;
int result = 1;
result = 31 * result + this.height;
result = 31 * result + this.width;
return result;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Size other = (Size)obj;
if (this.height != other.height)
return false;
if (this.width != other.width)
return false;
return true;
}
}

View file

@ -0,0 +1,68 @@
package org.jcodec.common.model;
import org.jcodec.common.StringUtils;
public class TapeTimecode {
public static final TapeTimecode ZERO_TAPE_TIMECODE = new TapeTimecode((short)0, (byte)0, (byte)0, (byte)0, false, 0);
private final short hour;
private final byte minute;
private final byte second;
private final byte frame;
private final boolean dropFrame;
private final int tapeFps;
public TapeTimecode(short hour, byte minute, byte second, byte frame, boolean dropFrame, int tapeFps) {
this.hour = hour;
this.minute = minute;
this.second = second;
this.frame = frame;
this.dropFrame = dropFrame;
this.tapeFps = tapeFps;
}
public short getHour() {
return this.hour;
}
public byte getMinute() {
return this.minute;
}
public byte getSecond() {
return this.second;
}
public byte getFrame() {
return this.frame;
}
public boolean isDropFrame() {
return this.dropFrame;
}
public int getTapeFps() {
return this.tapeFps;
}
public String toString() {
return StringUtils.zeroPad2(this.hour) + ":" + StringUtils.zeroPad2(this.hour) + ":" +
StringUtils.zeroPad2(this.minute) +
StringUtils.zeroPad2(this.second) + (this.dropFrame ? ";" : ":");
}
public static TapeTimecode tapeTimecode(long frame, boolean dropFrame, int tapeFps) {
if (dropFrame) {
long D = frame / 17982L;
long M = frame % 17982L;
frame += 18L * D + 2L * (M - 2L) / 1798L;
}
long sec = frame / (long)tapeFps;
return new TapeTimecode((short)(int)(sec / 3600L), (byte)(int)(sec / 60L % 60L), (byte)(int)(sec % 60L), (byte)(int)(frame % (long)tapeFps), dropFrame, tapeFps);
}
}

View file

@ -0,0 +1,5 @@
package org.jcodec.common.model;
public enum Unit {
FRAME, SEC;
}