1 Commits

Author SHA1 Message Date
875e31a39a Rebase this commit to abort Chinese translation. 2025-04-18 17:00:23 +08:00
14 changed files with 63 additions and 57 deletions

View File

@@ -6,7 +6,6 @@
<element id="file-copy" path="$PROJECT_DIR$/META-INF/MANIFEST.MF" />
</element>
<element id="module-output" name="stegsolve" />
<element id="extracted-dir" path="$PROJECT_DIR$/flatlaf-3.1.1.jar" path-in-jar="/" />
</root>
</artifact>
</component>

9
.idea/artifacts/stegsolve_jar.xml generated Normal file
View File

@@ -0,0 +1,9 @@
<component name="ArtifactManager">
<artifact type="jar" name="stegsolve:jar">
<output-path>$PROJECT_DIR$/out/artifacts/stegsolve_jar</output-path>
<root id="archive" name="stegsolve.jar">
<element id="module-output" name="stegsolve" />
<element id="extracted-dir" path="$USER_HOME$/Desktop/flatlaf-3.1.1.jar" path-in-jar="/" />
</root>
</artifact>
</component>

1
.idea/vcs.xml generated
View File

@@ -2,5 +2,6 @@
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -1,26 +1,23 @@
# StegSolve Legacy
# StegSolve
合并统一基于[原作者 Caesum 的 Java 代码](http://www.caesum.com/handbook/Stegsolve.jar)的各主要流传版本 StegSolve并进一步优化使用体验。
StegSolve的升级修复版本!
可在本仓库的 tags 中找到各版本的原始提交记录,以便对比。
## Todo (PRs welcome)
- [ ] 新增选项:图像缩放适应窗口大小(即拖动窗口边缘时始终让图像占满)
- [ ] 默认焦点放在切换图像而不是缩放(键盘方向键符合跟随焦点的惯例,但默认应该是切换图像)
- [ ] 子窗口添加缩放条
- [ ] 鼠标拖拽调整视图位置,滚轮缩放
- [ ] 十六进制文本域默认滚动至顶部,新增选项:仅显示十六进制/仅显示不带空格的文本,以便无需导出直接复制
## 1.5 changes [(by @souno-io, 2023-06-21)](https://github.com/souno-io/Stegsolve)
![](./img.png)
## 1.5 changes
- 汉化部分内容
- 美化界面为 JetBrains 风格
- 修复原来 1.4 版本的帧浏览器、合并图片等功能的不显示图片 bug
- 美化界面为Jetbrians风格
- 修复原来1.4版本的帧浏览器、合并图片等功能的不显示图片bug
## 1.4 changes [(by @Giotino, 2018-12-11)](https://github.com/Giotino/stegsolve)
## 1.4 changes
- Added zoom to image
- Added drag&drop zone for files
- Added "all" option to channel planes in "Data Extract"
- Added horizontal scrolling (Shift+Mousewheel)
# Special Thanks
Special thanks to [JetBrains](https://www.jetbrains.com) for their support to this project.
[![](https://raw.githubusercontent.com/ffffffff0x/BerylEnigma/master/assets/img/JetBrains.png)](https://www.jetbrains.com)

BIN
img.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="true">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/stegsolve" isTestSource="false" packagePrefix="stegsolve" />
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="flatlaf-3.1.1" level="project" />
<orderEntry type="library" name="flatlaf-3.1.11" level="project" />
</component>
</module>

View File

@@ -43,7 +43,7 @@ public class AboutFrame extends javax.swing.JFrame {
jEditorPane1.setContentType("text/html");
jEditorPane1.setEditable(false);
jEditorPane1.setText("<html>\n<center><b>Stegsolve Legacy</b></center>\n<br>\nStegsolve is a stegano solver for challenges. It provides these main functions:\n<ul>\n<li>A quick view of different bit planes and some simple transformations.</li>\n<li>Data extraction from planes. This can be row order or column order, with bits treated as a bitstream and converted into bytes.</li>\n<li>Some simple checking of file formats and reporting on the filesize, additional bytes, file holes, etc. This is highly dependent upon the type of image.</li>\n<li>Stereogram solver - simply change the offset until the image becomes visible.</li>\n<li>Frame browser for animated images. This should also work for viewing layers in multi-layered PNG files.</li>\n<li>Image combiner to combine two images in a variety of ways and browse through the different combinations.</li>\n</ul>\n<p>Copy/Cut and paste is available from most text using CTRL-C to copy, CTRL-V to paste and CTRL-X for cut.\n<p>If an image fails to load, for example because it is corrupt, then file analysis will still open the file that you just tried to view. It may, however, crash out before reporting the information that you want to know. This will work though on images where the PNG has corrupted CRC values for example.\n</html>\n");
jEditorPane1.setText("<html>\n<center><b>Stegsolve v1.5 by Souno Inherited in Caesum<br>Mod by Giotino</b></center>\n<br>\nStegsolve is a stegano solver for challenges. It provides these main functions:\n<ul>\n<li>A quick view of different bit planes and some simple transformations.</li>\n<li>Data extraction from planes. This can be row order or column order, with bits treated as a bitstream and converted into bytes.</li>\n<li>Some simple checking of file formats and reporting on the filesize, additional bytes, file holes, etc. This is highly dependent upon the type of image.</li>\n<li>Stereogram solver - simply change the offset until the image becomes visible.</li>\n<li>Frame browser for animated images. This should also work for viewing layers in multi-layered PNG files.</li>\n<li>Image combiner to combine two images in a variety of ways and browse through the different combinations.</li>\n</ul>\n<p>Copy/Cut and paste is available from most text using CTRL-C to copy, CTRL-V to paste and CTRL-X for cut.\n<p>If an image fails to load, for example because it is corrupt, then file analysis will still open the file that you just tried to view. It may, however, crash out before reporting the information that you want to know. This will work though on images where the PNG has corrupted CRC values for example.\n</html>\n");
jEditorPane1.setMinimumSize(new java.awt.Dimension(150, 150));
jEditorPane1.setPreferredSize(new java.awt.Dimension(150, 150));
jScrollPane1.setViewportView(jEditorPane1);

View File

@@ -192,7 +192,7 @@ public class Combiner extends JFrame
}
catch (Exception e)
{
JOptionPane.showMessageDialog(this, "写入文件失败: "+e.toString());
JOptionPane.showMessageDialog(this, "Failed to write file: "+e.toString());
}
}
}

View File

@@ -39,9 +39,9 @@ public class FileAnalysis extends javax.swing.JFrame {
{
rep = new StringBuilder();
rep.append("<html><center><b>");
rep.append("文件格式报告");
rep.append("File format report");
rep.append("</b></center>");
rep.append(("<br>文件: "+ifile.getName()));
rep.append(("<br>File: "+ifile.getName()));
try{
FileInputStream fis = new FileInputStream(ifile);
f = new byte[(int)ifile.length()];
@@ -51,7 +51,7 @@ public class FileAnalysis extends javax.swing.JFrame {
}
catch(Exception e)
{
rep.append(("读取文件时出错: "+e.toString()));
rep.append(("Error reading file: "+e.toString()));
}
rep.append("</html>");
report.setText(rep.toString());
@@ -66,7 +66,7 @@ public class FileAnalysis extends javax.swing.JFrame {
// analyse f, write report to rep
if(f.length<4)
{
rep.append("<br>文件太短?");
rep.append("<br>file too short?");
return;
}
if(f[0] == 'B' && f[1] == 'M')
@@ -78,7 +78,7 @@ public class FileAnalysis extends javax.swing.JFrame {
analyse_gif();
else if(f[0]==(byte)0xff && f[1]==(byte)0xd8)
analyse_jpg();
else rep.append("<br>文件格式分析代码尚未完成!");
else rep.append("<br>File format analysis code not done yet!");
}
/**
@@ -90,8 +90,8 @@ public class FileAnalysis extends javax.swing.JFrame {
cpos = analyse_jpg_sections(cpos);
if(cpos<f.length)
{
rep.append(("<br>文件末尾的附加字节数 = " +(f.length-cpos)));
rep.append("<br>转储附加字节:");
rep.append(("<br>Additional bytes at end of file = " +(f.length-cpos)));
rep.append("<br>Dump of additional bytes:");
fdump(cpos, f.length);
}
}
@@ -105,12 +105,12 @@ public class FileAnalysis extends javax.swing.JFrame {
{
if(f[pos]==(byte)0xff && f[pos+1]==(byte)0xd8)
{
rep.append("<br>图像的开头");
rep.append("<br>Start of Image");
pos+=2;
}
else if(f[pos] == (byte) 0xff && f[pos + 1] == (byte) 0xd9)
{
rep.append("<br><br>图像结尾");
rep.append("<br><br>End of Image");
pos+=2;
return pos;
}
@@ -932,7 +932,7 @@ public class FileAnalysis extends javax.swing.JFrame {
OKButton = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle("文件格式分析");
setTitle("File Format Analysis");
jPanel1.setMinimumSize(new java.awt.Dimension(400, 300));
jPanel1.setPreferredSize(new java.awt.Dimension(400, 350));
@@ -941,7 +941,7 @@ public class FileAnalysis extends javax.swing.JFrame {
jScrollPane1.setPreferredSize(new java.awt.Dimension(400, 260));
report.setContentType("text/html");
report.setFont(new java.awt.Font("微软雅黑", 0, 14)); // NOI18N
report.setFont(new java.awt.Font("Courier New", 0, 14)); // NOI18N
jScrollPane1.setViewportView(report);
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
@@ -960,7 +960,7 @@ public class FileAnalysis extends javax.swing.JFrame {
jPanel2.setMinimumSize(new java.awt.Dimension(400, 35));
jPanel2.setPreferredSize(new java.awt.Dimension(400, 35));
OKButton.setText("确认");
OKButton.setText("OK");
OKButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
OKButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {

View File

@@ -97,7 +97,7 @@ public class FrameBrowser extends JFrame
frames.add(bnext);
numframes++;
}
System.out.println("总帧数 " + numframes);
System.out.println("total frames " + numframes);
}
catch (IOException e)
{

View File

@@ -148,52 +148,52 @@ public class StegSolve extends JFrame {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
menuFile.setText("文件");
menuFile.setText("File");
fileOpen.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, 0));
fileOpen.setText("打开");
fileOpen.setText("Open");
fileOpen.addActionListener(this::fileOpenActionPerformed);
menuFile.add(fileOpen);
fileSave.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0));
fileSave.setText("另存为");
fileSave.setText("Save As");
fileSave.addActionListener(this::fileSaveActionPerformed);
menuFile.add(fileSave);
fileExit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, 0));
fileExit.setText("退出");
fileExit.setText("Exit");
fileExit.addActionListener(this::fileExitActionPerformed);
menuFile.add(fileExit);
menuBar.add(menuFile);
menuAnalyse.setText("分析");
menuAnalyse.setText("Analyse");
analyseFormat.setText("文件格式");
analyseFormat.setText("File Format");
analyseFormat.addActionListener(this::analyseFormatActionPerformed);
menuAnalyse.add(analyseFormat);
analyseExtract.setText("数据提取");
analyseExtract.setText("Data Extract");
analyseExtract.addActionListener(this::analyseExtractActionPerformed);
menuAnalyse.add(analyseExtract);
stereoSolve.setText("立体视图");
stereoSolve.setText("Stereogram Solver");
stereoSolve.addActionListener(this::stereoSolveActionPerformed);
menuAnalyse.add(stereoSolve);
frameBrowse.setText("帧浏览器");
frameBrowse.setText("Frame Browser");
frameBrowse.addActionListener(this::frameBrowseActionPerformed);
menuAnalyse.add(frameBrowse);
imageCombine.setText("图像合成器");
imageCombine.setText("Image Combiner");
imageCombine.addActionListener(this::imageCombineActionPerformed);
menuAnalyse.add(imageCombine);
menuBar.add(menuAnalyse);
menuHelp.setText("帮助");
menuHelp.setText("Help");
about.setText("关于");
about.setText("About");
about.addActionListener(this::aboutActionPerformed);
menuHelp.add(about);
@@ -265,7 +265,7 @@ public class StegSolve extends JFrame {
forwardButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "forward");
forwardButton.getActionMap().put("forward", forwardButtonPress);
this.setTitle("StegSolve Legacy");
this.setTitle("StegSolve 1.5 by Souno (龙腾四季专版)");
this.setMaximumSize(getToolkit().getScreenSize());
pack();
@@ -368,7 +368,7 @@ public class StegSolve extends JFrame {
JFileChooser fileChooser = new JFileChooser(System.getProperty("user.dir"));
FileNameExtensionFilter filter = new FileNameExtensionFilter("Images", "jpg", "jpeg", "gif", "bmp", "png");
fileChooser.setFileFilter(filter);
fileChooser.setDialogTitle("选择要合并的图像");
fileChooser.setDialogTitle("Select image to combine with");
int rVal = fileChooser.showOpenDialog(this);
System.setProperty("user.dir", fileChooser.getCurrentDirectory().getAbsolutePath());
if (rVal == JFileChooser.APPROVE_OPTION) {
@@ -378,7 +378,7 @@ public class StegSolve extends JFrame {
bi2 = ImageIO.read(sfile);
new Combiner(bi, bi2).setVisible(true);
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "加载文件失败: " + e.toString());
JOptionPane.showMessageDialog(this, "Failed to load file: " + e.toString());
}
}
}
@@ -412,7 +412,7 @@ public class StegSolve extends JFrame {
else
ImageIO.write(bi, sfile.getName().substring(rns), sfile);
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "写入文件失败: " + e.toString());
JOptionPane.showMessageDialog(this, "Failed to write file: " + e.toString());
}
}
}
@@ -447,7 +447,7 @@ public class StegSolve extends JFrame {
newImage();
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(this, "加载文件失败: " + e.toString());
JOptionPane.showMessageDialog(this, "Failed to load file: " + e.toString());
}
}

View File

@@ -78,7 +78,7 @@ public class StereoTransform {
*/
public String getText()
{
return "偏移量: "+transNum;
return "Offset: "+transNum;
}
/**

View File

@@ -375,9 +375,9 @@ public class Transform {
switch(transNum)
{
case 0:
return "正常图像";
return "Normal Image";
case 1:
return "颜色反转 (Xor)";
return "Colour Inversion (Xor)";
case 2:
case 3:
case 4:
@@ -429,7 +429,7 @@ public class Transform {
case 40:
return "Random colour map 3";
case 41:
return "灰度";
return "Gray bits";
default:
return "";
}

View File

@@ -26,7 +26,7 @@ public class ZoomSlider extends JPanel {
private List<SliderChangeListener> changeListeners = new ArrayList<>();
ZoomSlider(int min, int max, int defaultValue) {
JLabel tip = new JLabel("缩放:");
JLabel tip = new JLabel("Zoom:");
add(tip);