📄 subpicture.java
字号:
setScreenPosition(bitmap.getX(), bitmap.getY(), bitmap.getMaxX() - 1, bitmap.getMaxY() - 1);
setControlBlockPosition(control_block_pos, bottom_field_start_pos);
setPGCsection();
out.write(sections); //write control_block
if ((out.size() & 1) == 1)
out.write((byte)255);
out.flush();
picture_packet = out.toByteArray();
int size = picture_packet.length - 10;
picture_packet[10] = (byte)(0xFF & size>>>8);
picture_packet[11] = (byte)(0xFF & size);
picture_packet[12] = (byte)(0xFF & pack>>>8);
picture_packet[13] = (byte)(0xFF & pack);
for (int a=0; a < 4; a++)
picture_packet[a + 2] = (byte)(0xFF & bitmap.getInTime()>>>(a*8));
picture_packet[onscreen_time_pos] = (byte)(0xFF & bitmap.getPlayTime()>>>8);
picture_packet[onscreen_time_pos + 1] = (byte)(0xFF & bitmap.getPlayTime());
}
catch (IOException e)
{
X.Msg(Resource.getString("subpicture.msg1"));
}
read_from_Image = false;
return picture_packet;
}
// write last nibble, if it was not aligned
private void alignRLE()
{
if (nibble == 0)
return;
else
{
out.write((byte)val);
val = nibble = 0;
}
}
private void updateRLE(int l, int color_index)
{
if (l < 1)
return;
// color_index shall not exceed value 3!
int pgc_color = getUserColorTableIndex(color_index);
pgc_color = bitmap.getColorIndex(pgc_color);
l = l<<2 | pgc_color; // combine bits + color_index
// new byte begin
if (nibble == 0)
{
if (l > 0xFF) // 16
{
out.write((byte)(0xFF & l>>>8));
out.write((byte)(0xFF & l));
}
else if (l > 0x3F) // 12
{
out.write((byte)(0xFF & l>>>4));
val = 0xF0 & l<<4;
nibble = 4;
}
else if (l > 0xF) // 8
{
out.write((byte)(0xFF & l));
}
else // 4
{
val = 0xF0 & l<<4;
nibble = 4;
}
}
else // middle of byte
{
if (l > 0xFF) // 16
{
out.write((byte)(val | (0xF & l>>>12)));
out.write((byte)(0xFF & l>>>4));
val = 0xF0 & l<<4;
}
else if (l > 0x3F) // 12
{
out.write((byte)(val | (0xF & l>>>8)));
out.write((byte)(0xFF & l));
val = nibble = 0;
}
else if (l > 0xF) // 8
{
out.write((byte)(val | (0xF & l>>>4)));
val = 0xF0 & l<<4;
}
else // 4
{
out.write((byte)(val | (0xF & l)));
val = nibble = 0;
}
}
}
private void setScreenPosition(int minX, int minY, int maxX, int maxY)
{
// set planned pic pos. on tvscreen
sections[9] = (byte)(minX>>>4);
sections[10] = (byte)(minX<<4 | maxX>>>8);
sections[11] = (byte)maxX;
sections[12] = (byte)(minY>>>4);
sections[13] = (byte)(minY<<4 | maxY>>>8);
sections[14] = (byte)maxY;
}
private void setControlBlockPosition(int control_block_pos, int bottom_field_start_pos)
{
// top_field
sections[16] = 0;
sections[17] = 4;
// bottom_field
sections[18] = (byte)(0xFF & bottom_field_start_pos>>>8);
sections[19] = (byte)(0xFF & bottom_field_start_pos);
// control_block
sections[0] = sections[24] = (byte)(0xFF & control_block_pos>>>8);
sections[1] = sections[25] = (byte)(0xFF & control_block_pos);
}
private void setPGCsection()
{
int pgc_values = setPGClinks();
// color index 3,2 + 1,0
sections[3] = (byte)(0xFF & pgc_values>>>8);
sections[4] = (byte)(0xFF & pgc_values);
// alpha index 3,2 + 1,0
sections[6] = (byte)(0xFF & pgc_values>>>24);
sections[7] = (byte)(0xFF & pgc_values>>>16);
}
public int setPGClinks()
{
Object pgc_color_links[] = bitmap.getColorIndices();
Object pgc_alpha_links[] = getUserColorTableArray();
int pgc_colors = 0xFE10;
int pgc_alphas = 0xFFF9;
int pgc_color_value, pgc_alpha_value;
for (int a=0; a < 4; a++)
{
if (a < pgc_color_links.length)
{
pgc_color_value = 0xF & Integer.parseInt(pgc_color_links[a].toString());
pgc_alpha_value = 0xF & Integer.parseInt(pgc_alpha_links[pgc_color_value].toString())>>>28;
pgc_colors = (pgc_colors & ~(0xF<<(a * 4))) | pgc_color_value<<(a * 4);
pgc_alphas = (pgc_alphas & ~(0xF<<(a * 4))) | pgc_alpha_value<<(a * 4);
}
}
if (read_from_Image)
// pgc_alphas &= (0xFFF0 | default_alpha);
pgc_alphas &= (0xFFF0 | modified_alpha);
return (pgc_alphas<<16 | pgc_colors);
}
public void set2()
{
option[2] = option[7];
}
//DM26052004 081.7 int03 add
public int getMaximumLines()
{
return option[8];
}
/*** set user data ("Font pointsize; Backgr. Alpha value; Yoffset; Xoffset; Screenwidth"); **/
public int set(String nm, String values)
{
resetUserColorTable();
System.arraycopy(standard_values, 0, option, 0, standard_values.length);
StringTokenizer st = new StringTokenizer(values, ";");
int a=0;
while (st.hasMoreTokens() && a < option.length)
{
option[a] = Integer.parseInt(st.nextToken());
a++;
}
line_offset = option[0] + 2;
default_alpha = 0xF & option[1];
font = new Font(nm, Font.BOLD, option[0]);
font_alt = new Font(nm, Font.BOLD | Font.ITALIC, option[0]); //DM30122003 081.6 int10 add
font_std = new Font("Tahoma", Font.PLAIN, 14); //DM01032004 081.6 int18 add
return option[7];
}
private int[] getColorTable(int flag)
{
//define alternative color_table here
if (flag == 0)
return default_sup_colors;
else
return default_teletext_colors;
}
//DM05052004 081.7 int02 new
private void setArea()
{
Rect[0] = bitmap.getX();
Rect[1] = bitmap.getY();
Rect[2] = bitmap.getWidth();
Rect[3] = bitmap.getHeight();
pos[0] = bitmap.getX();
pos[1] = bitmap.getY();
pos[2] = bitmap.getMaxX();
pos[3] = bitmap.getMaxY();
}
//DM05052004 081.7 int02 new
public String getArea()
{
String string = "";
string += "x " + Rect[0];
string += " y " + Rect[1];
string += " w " + Rect[2];
string += " h " + Rect[3];
string += " x1 " + pos[0];
string += " y1 " + pos[1];
string += " x2 " + pos[2];
string += " y2 " + pos[3];
return string;
}
public void run()
{}
//DM08032004 081.6 int18 new
private int paintVideoSize()
{
int[] video_basics = X.getVideoBasics();
if (video_basics[0]==0) // H
video_basics[0] = 720;
if (video_basics[1]==0) // V
video_basics[1] = 576;
//deep red background to verify picture rectangle with given video resolution
big.setColor(new Color(0xFF550000));
big.fillRect(0, 0, w, h);
//picture area which the subpicture must not exceed, have to adjust to the hor. middle of it
big.setColor(Color.gray);
big.fillRect(0, 0, video_basics[0], video_basics[1]); //DM20042004 081.7 int02 changed
return video_basics[1];
}
//DM28022004 081.6 int18 new
private int Get_Bits(byte buf[], int BPos[], int N)
{
int Pos, Val;
Pos = BPos[1]>>>3;
if (Pos >= buf.length - 4)
{
global_error = true;
BPos[1] += N;
BPos[0] = BPos[1]>>>3;
return 0;
}
Val =(0xFF & buf[Pos])<<24 |
(0xFF & buf[Pos + 1])<<16 |
(0xFF & buf[Pos + 2])<<8 |
(0xFF & buf[Pos + 3]);
Val <<= BPos[1] & 7;
Val >>>= 32-N;
BPos[1] += N;
BPos[0] = BPos[1]>>>3;
return Val;
}
//DM28022004 081.6 int18 new
private int Show_Bits(byte buf[], int BPos[], int N)
{
int Pos, Val;
Pos = BPos[1]>>>3;
if (Pos >= buf.length - 4)
{
global_error = true;
return 0;
}
Val =(0xFF & buf[Pos])<<24 |
(0xFF & buf[Pos + 1])<<16 |
(0xFF & buf[Pos + 2])<<8 |
(0xFF & buf[Pos + 3]);
Val <<= BPos[1] & 7;
Val >>>= 32 - N;
return Val;
}
//DM28022004 081.6 int18 new
private void Flush_Bits(int BPos[], int N)
{
BPos[1] += N;
BPos[0] = BPos[1]>>>3;
}
//DM28022004 081.6 int18 new
private void align_Bits(int BPos[])
{
if ((1 & BPos[1]>>>2) != 0)
Flush_Bits( BPos, 4);
}
//DM25072004 081.7 int07 add
public String isForced_Msg()
{
String str = null;
//change of status occured
if ((isforced_status & 1) == 0)
{
if ((isforced_status & 2) > 0)
str = Resource.getString("subpicture.msg.forced.no");
else
str = Resource.getString("subpicture.msg.forced.yes");
}
isforced_status |= 1;
return str;
}
//DM25072004 081.7 int07 add
public void reset()
{
isforced_status = 0;
}
//DM14052004 081.7 int02 add
public int decode_picture(byte packet[], int off, boolean decode)
{
return decode_picture(packet, off, decode, 0, false, true);
}
//DM28022004 081.6 int18 new
//DM05052004 081.7 int02 changed
public int decode_picture(byte packet[], int off, boolean decode, long pts, boolean save, boolean visible)
{
read_from_Image = false;
global_error = false;
boolean simple_picture = false;
int picture_length = packet.length;
byte data[] = new byte[picture_length +4];
System.arraycopy(packet, 0, data, 0, picture_length);
int BPos[] = { off, off<<3 }; //BytePos, BitPos
int position[] = new int[4];
int start_pos[] = new int[3];
int print_colors[] = new int[4];
if (BPos[0] > picture_length-4)
return -4;
int packetlength = Get_Bits(data, BPos, 16); // required pack length
//DM13042004 081.7 int01 add
//DM28042004 081.7 int02 changed
if (Show_Bits(data, BPos, 24) == 0xF) // DVB subpicture: 8bit padding 0x00 + 8bit subtitle_stream_id 0x00 + start of subtitle segment 0x0F
{
//DM15072004 081.7 int06 add
big.setFont(font_std);
int ret = dvb.decodeDVBSubpicture(data, BPos, big, bimg, pts, save, visible);
if (ret > -2)
repaint();
return ret;
}
if (BPos[0] + packetlength != picture_length + 2)
return -5;
start_pos[2] = Get_Bits(data, BPos, 16) - 2;
Flush_Bits(BPos, start_pos[2]<<3); // jump to sections chunk
int playtime_pos = Get_Bits(data, BPos, 16); //fixed pos, so it must follow the 1st ctrl sequ,
if (playtime_pos == start_pos[2] + 2)
{
playtime_pos = packetlength;
simple_picture = true;
X.Msg(Resource.getString("subpicture.msg2"));
}
else
start_pos[2] += off+2;
int color_table[] = getColorTable(0);
//DM26052004 081.7 int03 changed
while (BPos[0] < off + playtime_pos) // read sections chunk
{
int cmd_switch = Get_Bits(data, BPos, 8);
switch(cmd_switch)
{
case 0: // force display
//DM25072004 081.7 int07 changed
isforced_status = (isforced_status & 5) != 5 ? 4 : 5;
break;
case 1: // start display
//DM25072004 081.7 int07 changed
isforced_status = (isforced_status & 3) != 3 ? 2 : 3;
break;
case 2: // stop display
case 0xFF: // end of ctrl sequ.
break;
case 3: // 4 color links
for (int b=0; b<4; b++)
print_colors[3 - b] |= (color_table[Get_Bits(data, BPos, 4)] & 0xFFFFFF);
break;
case 4: // alpha blending
for (int b=0; b<4; b++)
print_colors[3 - b] |= (0x11 * (0xF ^ Get_Bits(data, BPos, 4)))<<24;
break;
case 5: // x,y pos.
for (int b=0; b<4; b++)
position[b] = Get_Bits(data, BPos, 12);
break;
case 6: // pos. of decode_start of a field
for (int b=0; b<2; b++)
start_pos[b] = Get_Bits(data, BPos, 16);
break;
default:
X.Msg(Resource.getString("subpicture.msg3") + ": " + cmd_switch);
}
}
if (off + playtime_pos != BPos[0])
return -6;
int playtime = 0;
if (!simple_picture)
{
playtime = Get_Bits(data, BPos, 16);
if (playtime_pos != Get_Bits(data, BPos, 16))
return -7;
if (Get_Bits(data, BPos, 8) != 2)
return -8;
Flush_Bits( BPos, ((BPos[0] & 1) != 1) ? 16 : 8 );
}
if (BPos[0] != picture_length)
return -9;
if (global_error)
return -3;
if (!decode)
return (playtime * 1000); //DM26052004 081.7 int03 changed , 900
for (int b=0; b<2; b++)
start_pos[b] += off;
paintVideoSize();
int y0 = position[2];
int width = position[1] - position[0] + 1;
int height = position[3] - position[2] + 1;
big.setColor(Color.white);
big.drawRect(position[0] - 1, y0 - 1, width + 1, height + 1);
big.setFont(font_std);
big.drawString("x" + position[0] + ", y" + position[2] + " / " + width + "*" + height, position[0] - 1, y0 - 5);
for (int b=0; b<2; b++)
{
int Val=0, x1 = position[0], y1 = y0 + b;
BPos[1] = (BPos[0] = start_pos[b])<<3; // top_field at first
while (BPos[0] < start_pos[b+1]) // stop at pos_marker
{
if ((Val = Get_Bits(data, BPos, 4)) > 3) //4..F (0..3 never encodable)
{
big.setColor(new Color(print_colors[Val & 3]));
big.drawLine(x1, y1, (x1 += Val>>>2), y1);
}
else if ((Val = Val<<4 | Get_Bits(data, BPos, 4)) > 0xF) //10..3F
{
big.setColor(new Color(print_colors[Val & 3]));
big.drawLine(x1, y1, (x1 += Val>>>2), y1);
}
else if ((Val = Val<<4 | Get_Bits(data, BPos, 4)) > 0x3F) //40..FF
{
big.setColor(new Color(print_colors[Val & 3]));
big.drawLine(x1, y1, (x1 += Val>>>2), y1);
}
else if ((Val = Val<<4 | Get_Bits(data, BPos, 4)) > 0) //100..3FF
{
big.setColor(new Color(print_colors[Val & 3]));
big.drawLine(x1, y1, (x1 += Val>>>2), y1);
}
else // 0 forced carriage return
{
x1 = position[0];
y1 += 2;
align_Bits(BPos);
continue;
}
/**
if (x1 >= position[1]) // line end, carriage return
{
x1=position[0];
y1+=2;
align_Bits(BPos);
}
**/
}
}
repaint();
if (global_error)
return -3;
return (playtime * 1000); //DM26052004 081.7 int03 changed, 900
}
} // end inner class
} // end class
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -