520 lines
No EOL
15 KiB
Java
520 lines
No EOL
15 KiB
Java
import java.awt.*;
|
||
import java.awt.event.*;
|
||
import javax.swing.*;
|
||
import java.io.*;
|
||
|
||
|
||
class Edit extends JComponent {
|
||
Datei file;
|
||
int pos, subpos, modus;
|
||
int ueberschreiben=1;
|
||
int breite, hoehe, proZeile, luecke, anzahl;
|
||
|
||
String searchString="";
|
||
int searchPos = -1;
|
||
|
||
BMPHexEditor parent;
|
||
|
||
|
||
class myKeyListener implements KeyListener
|
||
{
|
||
public void keyPressed( KeyEvent k )
|
||
{
|
||
int iHeight = getSize().height;
|
||
|
||
if (k.getKeyCode()==8) delete(-1);
|
||
if (k.getKeyCode()==127) delete(0);
|
||
if (k.getKeyCode()==37) movePos(-1);
|
||
if (k.getKeyCode()==39) movePos(1);
|
||
if (k.getKeyCode()==38) movePos(-proZeile);
|
||
if (k.getKeyCode()==40) movePos(proZeile);
|
||
if (k.getKeyCode()==33) movePos(-proZeile*(iHeight/hoehe));
|
||
if (k.getKeyCode()==34) movePos(proZeile*(iHeight/hoehe));
|
||
|
||
}
|
||
public void keyReleased(KeyEvent k){}
|
||
|
||
public void keyTyped(KeyEvent k){
|
||
// System.out.println( "Typed:"+k.getKeyCode()+"|"+k.getKeyChar() );
|
||
switch(modus) {
|
||
case 1: {
|
||
if (k.getKeyChar()>='0' && k.getKeyChar()<='1') modifyByte(k.getKeyChar());
|
||
break;
|
||
}
|
||
case 2: {
|
||
if (k.getKeyChar()>='0' && k.getKeyChar()<='9') modifyByte(k.getKeyChar());
|
||
if (k.getKeyChar()>='a' && k.getKeyChar()<='f') modifyByte(k.getKeyChar());
|
||
if (k.getKeyChar()>='A' && k.getKeyChar()<='F') modifyByte(k.getKeyChar());
|
||
break;
|
||
}
|
||
default: {
|
||
if (k.getKeyCode()!= 127) modifyByte(k.getKeyChar());
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
class myMouseListener implements MouseListener
|
||
{
|
||
public void mouseClicked( MouseEvent m )
|
||
{
|
||
moveToMousePos(m.getX(),m.getY() );
|
||
}
|
||
public void mouseExited(MouseEvent e) {
|
||
}
|
||
public void mouseEntered(MouseEvent e) {
|
||
}
|
||
public void mousePressed(MouseEvent e) {
|
||
// System.out.println("Test");
|
||
}
|
||
public void mouseReleased(MouseEvent e) {
|
||
}
|
||
|
||
|
||
}
|
||
|
||
public Edit(BMPHexEditor p){
|
||
super();
|
||
parent = p;
|
||
file = null;
|
||
pos = 0;
|
||
subpos = 0;
|
||
addKeyListener(new myKeyListener());
|
||
addMouseListener(new myMouseListener());
|
||
modus = 1;
|
||
}
|
||
|
||
public void adjustTextMetrics()
|
||
{
|
||
int iWidth = getSize().width;
|
||
int iHeight = getSize().height;
|
||
Graphics g = getGraphics();
|
||
|
||
g.setFont(new Font("Monospaced",Font.PLAIN,12));
|
||
FontMetrics fm = g.getFontMetrics( g.getFont() );
|
||
|
||
hoehe = fm.getHeight();
|
||
switch (modus) {
|
||
case 1: breite = fm.stringWidth("01010101")+4; luecke = 4; anzahl = 8;
|
||
break;
|
||
case 2: breite = fm.stringWidth("FF")+4; luecke = 4; anzahl = 2;
|
||
break;
|
||
default : breite = fm.stringWidth("F"); luecke = 0; anzahl = 1;
|
||
}
|
||
|
||
proZeile = iWidth / breite;
|
||
}
|
||
|
||
public void paint(Graphics g){
|
||
String s;
|
||
int iWidth = getSize().width;
|
||
int iHeight = getSize().height;
|
||
|
||
Rectangle r = getVisibleRect();
|
||
|
||
adjustTextMetrics();
|
||
|
||
g.setFont(new Font("Monospaced",Font.PLAIN,12));
|
||
g.setColor( Color.black );
|
||
int zeile, spalte;
|
||
|
||
if (file != null) {
|
||
|
||
// BMP-Bild interpretieren
|
||
String info;
|
||
int bilddaten = file.getDWORD(10);
|
||
int bbreite = file.getDWORD(18);
|
||
int bhoehe = file.getDWORD(22);
|
||
int farbtiefe = file.getWORD(28);
|
||
int compression = 0;
|
||
int min = 0; int max = -1;
|
||
int xx = -1; int yy = -1;
|
||
|
||
|
||
switch (pos) {
|
||
case 0: case 1:
|
||
info = "Byte 1+2 immer 'BM' zur Kennzeichnung eines BMP-Bildes";
|
||
min = 0; max = 1;
|
||
break;
|
||
case 2: case 3: case 4: case 5:
|
||
int i = file.getDWORD(2);
|
||
info = "Byte 3-6 Dateigr<67><72>e: "+i+" Bytes (unsicher)";
|
||
min = 2; max = 5;
|
||
break;
|
||
case 6: case 7: case 8: case 9:
|
||
info = "Byte 7-10 reservierte Bytes (keine Bedeutung)";
|
||
min = 6; max = 9;
|
||
break;
|
||
case 10: case 11: case 12: case 13:
|
||
info = "Byte 11-14 Bilddaten beginnen bei Byte Nr. "+bilddaten;
|
||
min = 10; max = 13;
|
||
break;
|
||
case 14: case 15: case 16: case 17:
|
||
i = file.getDWORD(14);
|
||
info = "Byte 15-18 Gr<47><72>e des Headers: "+i+" Byte";
|
||
min = 14; max = 17;
|
||
break;
|
||
case 18: case 19: case 20: case 21:
|
||
info = "Byte 19-22 Breite des Bildes: "+bbreite+" Pixel";
|
||
min = 18; max = 21;
|
||
break;
|
||
case 22: case 23: case 24: case 25:
|
||
if (bhoehe<0) {
|
||
info = "Byte 23-26 H<>he des Bildes: "+(-bhoehe)+" Pixel und Top-Down-Bitmap";
|
||
} else {
|
||
info = "Byte 23-26 H<>he des Bildes: "+bhoehe+" Pixel und Bottum-Up-Bitmap";
|
||
}
|
||
min = 22; max = 25;
|
||
break;
|
||
case 28: case 29:
|
||
if (farbtiefe<=8) {
|
||
info = "Byte 29+30: Farbtiefe "+farbtiefe+" Bit pro Pixel mit Farbpalette";
|
||
}
|
||
else {
|
||
info = "Byte 29+30: Farbtiefe "+farbtiefe+" Bit pro Pixel ohne Farbpalette";
|
||
}
|
||
min = 28; max = 29;
|
||
break;
|
||
case 30: case 31: case 32: case 33:
|
||
compression = file.getDWORD(30);
|
||
if (compression == 0) {
|
||
info = "Byte 31-34: Komprimierung: Die Bilddaten sind unkomprimiert";
|
||
}
|
||
else {
|
||
info = "Byte 31-34: Komprimierung: Die Bilddaten sind RunLength komprimiert";
|
||
}
|
||
min = 30; max = 33;
|
||
break;
|
||
case 34: case 35: case 36: case 37:
|
||
i = file.getDWORD(34);
|
||
info = "Byte 35-38 Gr<47><72>e der Bilddaten: "+i+" Byte (kann auch 0 sein)";
|
||
min = 34; max = 37;
|
||
break;
|
||
case 38: case 39: case 40: case 41:
|
||
i = file.getDWORD(38);
|
||
info = "Byte 39-42 Horizontale Aufl<66>sung "+i+" Pixel pro Meter (meist 0 gesetzt)";
|
||
min = 38; max = 41;
|
||
break;
|
||
case 42: case 43: case 44: case 45:
|
||
i = file.getDWORD(42);
|
||
info = "Byte 43-46 Vertikale Aufl<66>sung "+i+" Pixel pro Meter (meist 0 gesetzt)";
|
||
min = 42; max = 45;
|
||
break;
|
||
case 46: case 47: case 48: case 49:
|
||
i = file.getDWORD(38);
|
||
info = "Byte 47-50 Anzahl der Farben in der Palette "+i+" (0 = maximale Anzahl)";
|
||
min = 46; max = 49;
|
||
break;
|
||
case 50: case 51: case 52: case 53:
|
||
i = file.getDWORD(38);
|
||
info = "Byte 51-54 Anzahl der benutzten Farben im Bild "+i+" (0 = alle Farben)";
|
||
min = 50; max = 53;
|
||
break;
|
||
|
||
default:
|
||
info = "sonstige Daten";
|
||
if (pos >= 54 && pos < bilddaten) {
|
||
min = max = pos;
|
||
min = min -(pos-54) % 4;
|
||
max = max + 3-(pos-54) % 4;
|
||
|
||
info = "Byte "+(pos+1)+" Farbe Nr. "+(pos-54)/4+" der Palette ";
|
||
if ((pos-54) % 4==0) {
|
||
info = info + " (Blauanteil)";
|
||
}
|
||
if ((pos-54) % 4==1) {
|
||
info = info + " (Gr<47>nanteil)";
|
||
}
|
||
if ((pos-54) % 4==2) {
|
||
info = info + " (Rotanteil)";
|
||
}
|
||
if ((pos-54) % 4==3) {
|
||
info = info + " (immer 0)";
|
||
}
|
||
}
|
||
if (pos >= bilddaten) {
|
||
min = max = pos;
|
||
// immer auf 4 Byte mit Nullen aufgef<65>llt
|
||
int bbreite_angepasst = bbreite*farbtiefe/8+3;
|
||
bbreite_angepasst = bbreite_angepasst - bbreite_angepasst % 4;
|
||
|
||
yy = (pos-bilddaten) / bbreite_angepasst +1;
|
||
int pos_in_zeile = ((pos-bilddaten) - (yy-1)*bbreite_angepasst);
|
||
xx = pos_in_zeile*8 / farbtiefe +1;
|
||
if (bhoehe > 0) {
|
||
yy = bhoehe - yy +1;
|
||
}
|
||
if (farbtiefe == 1) {
|
||
info = "Byte "+(pos+1)+" Farbenummer des Pixels an Pos ("+xx+"/"+yy+") und der n<>chsten 7 Pixel";
|
||
}
|
||
if (farbtiefe == 2) {
|
||
info = "Byte "+(pos+1)+" Farbenummer des Pixels an Pos ("+xx+"/"+yy+") und der n<>chsten 3 Pixel";
|
||
}
|
||
if (farbtiefe == 4) {
|
||
info = "Byte "+(pos+1)+" Farbnummer des Pixels an Pos ("+xx+"/"+yy+") und des n<>chsten Pixels";
|
||
}
|
||
if (farbtiefe == 8) {
|
||
info = "Byte "+(pos+1)+" Farbnummer des Pixels an Pos ("+xx+"/"+yy+")";
|
||
}
|
||
if (farbtiefe > 8) {
|
||
info = "Byte "+(pos+1)+" Farbe des Pixels an Pos ("+xx+"/"+yy+")";
|
||
if ((pos_in_zeile) % 3==0) {
|
||
info = info + " (Blauanteil)";
|
||
}
|
||
if ((pos_in_zeile) % 3==1) {
|
||
info = info + " (Gr<47>nanteil)";
|
||
}
|
||
if ((pos_in_zeile) % 3==2) {
|
||
info = info + " (Rotanteil)";
|
||
}
|
||
min = min -(pos_in_zeile) % 3;
|
||
max = max + 2-(pos_in_zeile) % 3;
|
||
}
|
||
if (xx > bbreite) { // Dummybytes
|
||
info = "Byte "+(pos+1)+" keine Bedeutung";
|
||
min = max = pos;
|
||
}
|
||
parent.posChanged(xx,yy);
|
||
|
||
}
|
||
}
|
||
|
||
|
||
int laenge = file.getLength();
|
||
|
||
zeile = 0;
|
||
spalte = 0;
|
||
|
||
int start = (int)(r.getY() / hoehe) * proZeile;
|
||
int ende = ((int) ((r.getY()+r.getHeight()) / hoehe)+1)*proZeile;
|
||
zeile = (int) (r.getY() / hoehe);
|
||
spalte = 0;
|
||
for (int i=start; i<ende && i<laenge; i++){
|
||
|
||
if (file.getSearchByte(i) == 1) {
|
||
g.setColor( Color.red);
|
||
g.fillRect((spalte)*breite+luecke/2-1,4+(zeile)*hoehe-1,breite-luecke/2+1,hoehe+2);
|
||
g.setColor( Color.black);
|
||
}
|
||
|
||
if (i>=min && i<=max) {
|
||
g.setColor( Color.lightGray);
|
||
g.fillRect((spalte)*breite+luecke/2,4+(zeile)*hoehe,breite-luecke/2-1,hoehe);
|
||
g.setColor( Color.black);
|
||
}
|
||
|
||
if (i==pos) {
|
||
g.setColor( Color.yellow);
|
||
g.fillRect((spalte)*breite+luecke/2,4+(zeile)*hoehe,breite-luecke/2-1,hoehe);
|
||
if (subpos != 0) {
|
||
g.setColor( Color.red);
|
||
g.fillRect((spalte)*breite+subpos*(breite-luecke)/anzahl+luecke/2,4+(zeile)*hoehe,(breite-luecke/2)/anzahl-1,hoehe);
|
||
}
|
||
g.setColor( Color.black);
|
||
}
|
||
switch (modus) {
|
||
case 1: s = file.getByteBinary(i);
|
||
break;
|
||
case 2: s = file.getByteHex(i);
|
||
break;
|
||
default : s = file.getByteChar(i);
|
||
|
||
}
|
||
g.drawString(s,(spalte)*breite+luecke/2,hoehe+(zeile)*hoehe);
|
||
spalte++;
|
||
|
||
if (spalte >= proZeile) {
|
||
zeile++;
|
||
spalte = 0;
|
||
}
|
||
}
|
||
|
||
if (pos<ende && pos==laenge) { // Cursor steht hinter dem letzten Zeichen => leeres Rechteck zeichnen
|
||
g.setColor( Color.lightGray);
|
||
g.fillRect((spalte)*breite+luecke/2,4+(zeile)*hoehe,breite-luecke/2-1,hoehe);
|
||
g.setColor( Color.black);
|
||
}
|
||
|
||
parent.showLabels(file.getByteBinary(pos), file.getByteHex(pos), file.getByteChar(pos),info);
|
||
}
|
||
}
|
||
|
||
public void setDatei(Datei file) {
|
||
this.file = file;
|
||
pos = 0;
|
||
subpos = 0;
|
||
}
|
||
|
||
public Datei getDatei(){
|
||
return file;
|
||
}
|
||
|
||
public Dimension getPreferredSize()
|
||
{
|
||
adjustTextMetrics();
|
||
|
||
if (file == null)
|
||
{
|
||
return new Dimension( 300, 200 );
|
||
}
|
||
else
|
||
{
|
||
int laenge = file.getLength();
|
||
|
||
int komponentenhoehe = hoehe+(laenge/proZeile)*hoehe+5;
|
||
if (komponentenhoehe < 200) {
|
||
komponentenhoehe = 200;
|
||
}
|
||
return new Dimension( 300, komponentenhoehe);
|
||
|
||
}
|
||
}
|
||
|
||
public Dimension getMinimumSize()
|
||
{
|
||
return getPreferredSize();
|
||
}
|
||
|
||
public void setMode( int i) {
|
||
modus = i;
|
||
subpos = 0;
|
||
repaint();
|
||
}
|
||
|
||
public void setUeberschreiben(int i) {
|
||
ueberschreiben = i;
|
||
}
|
||
|
||
public int getUeberschreiben() {
|
||
return ueberschreiben;
|
||
}
|
||
|
||
public void movePos ( int i ){
|
||
if (file!=null) {
|
||
subpos = 0;
|
||
pos += i;
|
||
if (pos < 0) pos = 0;
|
||
if (pos > file.getLength()) pos = file.getLength();
|
||
repaint();
|
||
}
|
||
}
|
||
|
||
public void moveToMousePos(int x, int y) {
|
||
if (file!=null) {
|
||
pos = (y / hoehe)*proZeile + (x / breite);
|
||
subpos = 0;
|
||
if (pos < 0) pos = 0;
|
||
if (pos > file.getLength()) pos = file.getLength();
|
||
repaint();
|
||
}
|
||
}
|
||
|
||
public void moveToPos(int x, int y) {
|
||
int bilddaten = file.getDWORD(10);
|
||
int bbreite = file.getDWORD(18);
|
||
int bhoehe = file.getDWORD(22);
|
||
int farbtiefe = file.getWORD(28);
|
||
if (bhoehe > 0) {
|
||
pos = (bhoehe - y)*bbreite +x-1;
|
||
}
|
||
else {
|
||
pos = (y-1)*bbreite + x-1;
|
||
}
|
||
pos = pos * farbtiefe / 8;
|
||
pos += bilddaten;
|
||
|
||
parent.scrollTo(0, pos / proZeile * hoehe - 100);
|
||
repaint();
|
||
|
||
}
|
||
|
||
public int compare(File vergleichDatei) {
|
||
int gefunden = -1;
|
||
if (file!=null)
|
||
{
|
||
gefunden = file.compare(vergleichDatei);
|
||
}
|
||
repaint();
|
||
return gefunden;
|
||
}
|
||
|
||
|
||
public int search(String s) {
|
||
int gefunden = -1;
|
||
if (file!=null)
|
||
{
|
||
String s2="";
|
||
char b;
|
||
for (int i = 0; i < s.length(); i++)
|
||
{
|
||
b = s.charAt(i);
|
||
if (modus==1 && (b == '0' || b == '1')) s2 = s2 + b;
|
||
if (modus==2 && ((b >= '0' && b <= '9')|| (b>='A' && b <='F') || (b>='a' && b<='f'))) s2 = s2+b;
|
||
if (modus==3) s2 = s2+b;
|
||
}
|
||
if (modus==2) s2 = s2.toUpperCase();
|
||
if (s2.length()>0) gefunden = file.search(s2,modus);
|
||
}
|
||
repaint();
|
||
return gefunden;
|
||
}
|
||
|
||
public void delete( int i) {
|
||
if (file != null && pos+i>0 && pos+i<file.getLength()) {
|
||
file.deleteByte(pos+i);
|
||
subpos = 0;
|
||
pos += i;
|
||
if (pos > file.getLength()) pos--;
|
||
}
|
||
repaint();
|
||
}
|
||
|
||
public void modifyByte( char c ) {
|
||
String s;
|
||
if (file != null) {
|
||
if (pos == file.getLength() || (subpos == 0 && !(ueberschreiben==1))) file.insertByte(pos);
|
||
|
||
switch (modus) {
|
||
case 1: s = file.getByteBinary(pos);
|
||
break;
|
||
case 2: s = file.getByteHex(pos);
|
||
break;
|
||
default : s = file.getByteChar(pos);
|
||
}
|
||
|
||
|
||
s = s.substring(0,subpos)+c+s.substring(subpos+1);
|
||
subpos++;
|
||
|
||
int maxSubpos;
|
||
switch (modus) {
|
||
case 1: maxSubpos = 7;
|
||
file.setByteBinary(pos,s);
|
||
break;
|
||
case 2: maxSubpos = 1;
|
||
file.setByteHex(pos,s);
|
||
break;
|
||
default : maxSubpos = 0;
|
||
file.setByteChar(pos,c);
|
||
}
|
||
|
||
if (subpos > maxSubpos)
|
||
{
|
||
subpos = 0;
|
||
movePos(1);
|
||
}
|
||
repaint();
|
||
parent.fileChanged();
|
||
}
|
||
}
|
||
|
||
public void keyPressed ( KeyEvent e){
|
||
}
|
||
public void keyReleased ( KeyEvent e ){
|
||
}
|
||
|
||
public boolean isFocusable() {
|
||
return true;
|
||
}
|
||
|
||
} |