1. hey guys need some help please.Here is an application program for Image steganography.I'm not getting any errors but don't know why the message could not be hidden inside an Image file.
  2. Someone please help me with this and tell me where am I doing wrong ?
  3.  
  4. [Code=java]
  5.  
  6. Main class
  7.  
  8. import java.io.File;
  9.  
  10. import java.awt.Container;
  11. import java.awt.event.ActionEvent;
  12. import java.awt.image.BufferedImage;
  13. import java.awt.event.ActionListener;
  14.  
  15. import javax.swing.JPanel;
  16. import javax.swing.JLabel;
  17. import javax.swing.JButton;
  18. import javax.swing.ImageIcon;
  19. import javax.swing.JMenuItem;
  20. import javax.swing.JTextArea;
  21. import javax.imageio.ImageIO;
  22. import javax.swing.JOptionPane;
  23. import javax.swing.JFileChooser;
  24.  
  25. /*
  26. *Steganography_Controller Class
  27. */
  28. public class Steganography_Controller
  29. {
  30. //Program Variables
  31. private Steganography_View view;
  32. private Steganography model;
  33.  
  34. //Panel Displays
  35. private JPanel decode_panel;
  36. private JPanel encode_panel;
  37. //Panel Variables
  38. private JTextArea input;
  39. private JButton encodeButton,decodeButton;
  40. private JLabel image_input;
  41. //Menu Variables
  42. private JMenuItem encode;
  43. private JMenuItem decode;
  44. private JMenuItem exit;
  45.  
  46. //action event classes
  47. private Encode enc;
  48. private Decode dec;
  49. private EncodeButton encButton;
  50. private DecodeButton decButton;
  51.  
  52. //decode variable
  53. private String stat_path = "";
  54. private String stat_name = "";
  55.  
  56. /*
  57. *Constructor to initialize view, model and environment variables
  58. *@param aView A GUI class, to be saved as view
  59. *@param aModel A model class, to be saved as model
  60. */
  61. public Steganography_Controller(Steganography_View aView, Steganography aModel)
  62. {
  63. //program variables
  64. view = aView;
  65. model = aModel;
  66.  
  67. //assign View Variables
  68. //2 views
  69. encode_panel = view.getTextPanel();
  70. decode_panel = view.getImagePanel();
  71. //2 data options
  72. input = view.getText();
  73. image_input = view.getImageInput();
  74. //2 buttons
  75. encodeButton = view.getEButton();
  76. decodeButton = view.getDButton();
  77. //menu
  78. encode = view.getEncode();
  79. decode = view.getDecode();
  80. exit = view.getExit();
  81.  
  82. //assign action events
  83. enc = new Encode();
  84. encode.addActionListener(enc);
  85. dec = new Decode();
  86. decode.addActionListener(dec);
  87. exit.addActionListener(new Exit());
  88. encButton = new EncodeButton();
  89. encodeButton.addActionListener(encButton);
  90. decButton = new DecodeButton();
  91. decodeButton.addActionListener(decButton);
  92.  
  93. //encode view as default
  94. encode_view();
  95. }
  96.  
  97. /*
  98. *Updates the single panel to display the Encode View.
  99. */
  100. private void encode_view()
  101. {
  102. update();
  103. view.setContentPane(encode_panel);
  104. view.setVisible(true);
  105. }
  106.  
  107. /*
  108. *Updates the single panel to display the Decode View.
  109. */
  110. private void decode_view()
  111. {
  112. update();
  113. view.setContentPane(decode_panel);
  114. view.setVisible(true);
  115. }
  116.  
  117. /*
  118. *Encode Class - handles the Encode menu item
  119. */
  120. private class Encode implements ActionListener
  121. {
  122. /*
  123. *handles the click event
  124. *@param e The ActionEvent Object
  125. */
  126. public void actionPerformed(ActionEvent e)
  127. {
  128. encode_view(); //show the encode view
  129. }
  130. }
  131.  
  132. /*
  133. *Decode Class - handles the Decode menu item
  134. */
  135. private class Decode implements ActionListener
  136. {
  137. /*
  138. *handles the click event
  139. *@param e The ActionEvent Object
  140. */
  141. public void actionPerformed(ActionEvent e)
  142. {
  143. decode_view(); //show the decode view
  144.  
  145. //start path of displayed File Chooser
  146. JFileChooser chooser = new JFileChooser("./");
  147. chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
  148. chooser.setFileFilter(new Image_Filter());
  149. int returnVal = chooser.showOpenDialog(view);
  150. if (returnVal == JFileChooser.APPROVE_OPTION){
  151. File directory = chooser.getSelectedFile();
  152. try{
  153. String image = directory.getPath();
  154. stat_name = directory.getName();
  155. stat_path = directory.getPath();
  156. stat_path = stat_path.substring(0,stat_path.length()-stat_name.length()-1);
  157. stat_name = stat_name.substring(0, stat_name.length()-4);
  158. image_input.setIcon(new ImageIcon(ImageIO.read(new File(image))));
  159. }
  160. catch(Exception except) {
  161. //msg if opening fails
  162. JOptionPane.showMessageDialog(view, "The File cannot be opened!",
  163. "Error!", JOptionPane.INFORMATION_MESSAGE);
  164. }
  165. }
  166. }
  167. }
  168.  
  169. /*
  170. *Exit Class - handles the Exit menu item
  171. */
  172. private class Exit implements ActionListener
  173. {
  174. /*
  175. *handles the click event
  176. *@param e The ActionEvent Object
  177. */
  178. public void actionPerformed(ActionEvent e)
  179. {
  180. System.exit(0); //exit the program
  181. }
  182. }
  183.  
  184. /*
  185. *Encode Button Class - handles the Encode Button item
  186. */
  187. private class EncodeButton implements ActionListener
  188. {
  189. /*
  190. *handles the click event
  191. *@param e The ActionEvent Object
  192. */
  193. public void actionPerformed(ActionEvent e)
  194. {
  195. //start path of displayed File Chooser
  196. JFileChooser chooser = new JFileChooser("./");
  197. chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
  198. chooser.setFileFilter(new Image_Filter());
  199. int returnVal = chooser.showOpenDialog(view);
  200. if (returnVal == JFileChooser.APPROVE_OPTION){
  201. File directory = chooser.getSelectedFile();
  202. try{
  203. String text = input.getText();
  204. String ext = Image_Filter.getExtension(directory);
  205. String name = directory.getName();
  206. String path = directory.getPath();
  207. path = path.substring(0,path.length()-name.length()-1);
  208. name = name.substring(0, name.length()-4);
  209.  
  210. String stegan = JOptionPane.showInputDialog(view,
  211. "Enter output file name:", "File name",
  212. JOptionPane.PLAIN_MESSAGE);
  213.  
  214. if(model.encode(path,name,ext,stegan,text))
  215. {
  216. JOptionPane.showMessageDialog(view, "The Image was encoded Successfully!",
  217. "Success!", JOptionPane.INFORMATION_MESSAGE);
  218. }
  219. else
  220. {
  221. JOptionPane.showMessageDialog(view, "The Image could not be encoded!",
  222. "Error!", JOptionPane.INFORMATION_MESSAGE);
  223. }
  224. //display the new image
  225. decode_view();
  226. image_input.setIcon(new ImageIcon(ImageIO.read(new File(path + "/" + stegan + ".png"))));
  227. }
  228. catch(Exception except) {
  229. //msg if opening fails
  230. JOptionPane.showMessageDialog(view, "The File cannot be opened!",
  231. "Error!", JOptionPane.INFORMATION_MESSAGE);
  232. }
  233. }
  234. }
  235.  
  236. }
  237.  
  238. /*
  239. *Decode Button Class - handles the Decode Button item
  240. */
  241. private class DecodeButton implements ActionListener
  242. {
  243. /*
  244. *handles the click event
  245. *@param e The ActionEvent Object
  246. */
  247. public void actionPerformed(ActionEvent e)
  248. {
  249. String message = model.decode(stat_path, stat_name);
  250. System.out.println(stat_path + ", " + stat_name);
  251. if(message != "")
  252. {
  253. encode_view();
  254. JOptionPane.showMessageDialog(view, "The Image was decoded Successfully!",
  255. "Success!", JOptionPane.INFORMATION_MESSAGE);
  256. input.setText(message);
  257. }
  258. else
  259. {
  260. JOptionPane.showMessageDialog(view, "The Image could not be decoded!",
  261. "Error!", JOptionPane.INFORMATION_MESSAGE);
  262. }
  263. }
  264. }
  265.  
  266. /*
  267. *Updates the variables to an initial state
  268. */
  269. public void update()
  270. {
  271. input.setText(""); //clear textarea
  272. image_input.setIcon(null); //clear image
  273. stat_path = ""; //clear path
  274. stat_name = ""; //clear name
  275. }
  276.  
  277. /*
  278. *Main Method for testing
  279. */
  280. public static void main(String args[])
  281. {
  282. new Steganography_Controller(
  283. new Steganography_View("Steganography"),
  284. new Steganography()
  285. );
  286. }
  287. }
  288.  
  289.  
  290. Front end
  291.  
  292. import java.awt.Color;
  293. import java.awt.Insets;
  294. import java.awt.Container;
  295. import java.awt.GridBagLayout;
  296. import java.awt.GridBagConstraints;
  297.  
  298. import javax.swing.JMenu;
  299. import javax.swing.JFrame;
  300. import javax.swing.JPanel;
  301. import javax.swing.JLabel;
  302. import javax.swing.JButton;
  303. import javax.swing.JMenuBar;
  304. import javax.swing.JMenuItem;
  305. import javax.swing.JTextArea;
  306. import javax.swing.JScrollBar;
  307. import javax.swing.JScrollPane;
  308. import javax.swing.BorderFactory;
  309.  
  310. /*
  311. *Class Steganography_View
  312. */
  313. public class Steganography_View extends JFrame
  314. {
  315. //sie variables for window
  316. private static int WIDTH = 500;
  317. private static int HEIGHT = 400;
  318.  
  319. //elements for JPanel
  320. private JTextArea input;
  321. private JScrollBar scroll,scroll2;
  322. private JButton encodeButton,decodeButton;
  323. private JLabel image_input;
  324.  
  325. //elements for Menu
  326. private JMenu file;
  327. private JMenuItem encode;
  328. private JMenuItem decode;
  329. private JMenuItem exit;
  330.  
  331. /*
  332. *Constructor for Steganography_View class
  333. *@param name Used to set the title on the JFrame
  334. */
  335. public Steganography_View(String name)
  336. {
  337. //set the title of the JFrame
  338. super(name);
  339.  
  340. //Menubar
  341. JMenuBar menu = new JMenuBar();
  342.  
  343. JMenu file = new JMenu("File"); file.setMnemonic('F');
  344. encode = new JMenuItem("Encode"); encode.setMnemonic('E'); file.add(encode);
  345. decode = new JMenuItem("Decode"); decode.setMnemonic('D'); file.add(decode);
  346. file.addSeparator();
  347. exit = new JMenuItem("Exit"); exit.setMnemonic('x'); file.add(exit);
  348.  
  349. menu.add(file);
  350. setJMenuBar(menu);
  351.  
  352. // display rules
  353. setResizable(true); //allow window to be resized: true?false
  354. setBackground(Color.lightGray); //background color of window: Color(int,int,int) or Color.name
  355. setLocation(100,100); //location on the screen to display window
  356. setDefaultCloseOperation(EXIT_ON_CLOSE);//what to do on close operation: exit, do_nothing, etc
  357. setSize(WIDTH,HEIGHT); //set the size of the window
  358. setVisible(true); //show the window: true?false
  359. }
  360.  
  361. /*
  362. *@return The menu item 'Encode'
  363. */
  364. public JMenuItem getEncode() { return encode; }
  365. /*
  366. *@return The menu item 'Decode'
  367. */
  368. public JMenuItem getDecode() { return decode; }
  369. /*
  370. *@return The menu item 'Exit'
  371. */
  372. public JMenuItem getExit() { return exit; }
  373. /*
  374. *@return The TextArea containing the text to encode
  375. */
  376. public JTextArea getText() { return input; }
  377. /*
  378. *@return The JLabel containing the image to decode text from
  379. */
  380. public JLabel getImageInput() { return image_input; }
  381. /*
  382. *@return The JPanel displaying the Encode View
  383. */
  384. public JPanel getTextPanel() { return new Text_Panel(); }
  385. /*
  386. *@return The JPanel displaying the Decode View
  387. */
  388. public JPanel getImagePanel() { return new Image_Panel(); }
  389. /*
  390. *@return The Encode button
  391. */
  392. public JButton getEButton() { return encodeButton; }
  393. /*
  394. *@return The Decode button
  395. */
  396. public JButton getDButton() { return decodeButton; }
  397.  
  398. /*
  399. *Class Text_Panel
  400. */
  401. private class Text_Panel extends JPanel
  402. {
  403. /*
  404. *Constructor to enter text to be encoded
  405. */
  406. public Text_Panel()
  407. {
  408. //setup GridBagLayout
  409. GridBagLayout layout = new GridBagLayout();
  410. GridBagConstraints layoutConstraints = new GridBagConstraints();
  411. setLayout(layout);
  412.  
  413. input = new JTextArea(10,10);
  414. layoutConstraints.gridx = 0; layoutConstraints.gridy = 0;
  415. layoutConstraints.gridwidth = 1; layoutConstraints.gridheight = 1;
  416. layoutConstraints.fill = GridBagConstraints.BOTH;
  417. layoutConstraints.insets = new Insets(0,0,0,0);
  418. layoutConstraints.anchor = GridBagConstraints.CENTER;
  419. layoutConstraints.weightx = 1.0; layoutConstraints.weighty = 50.0;
  420. JScrollPane scroll = new JScrollPane(input,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
  421. JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
  422. layout.setConstraints(scroll,layoutConstraints);
  423. scroll.setBorder(BorderFactory.createLineBorder(Color.BLACK,1));
  424. add(scroll);
  425.  
  426. encodeButton = new JButton("Encode Now");
  427. layoutConstraints.gridx = 0; layoutConstraints.gridy = 1;
  428. layoutConstraints.gridwidth = 1; layoutConstraints.gridheight = 1;
  429. layoutConstraints.fill = GridBagConstraints.BOTH;
  430. layoutConstraints.insets = new Insets(0,-5,-5,-5);
  431. layoutConstraints.anchor = GridBagConstraints.CENTER;
  432. layoutConstraints.weightx = 1.0; layoutConstraints.weighty = 1.0;
  433. layout.setConstraints(encodeButton,layoutConstraints);
  434. add(encodeButton);
  435.  
  436. //set basic display
  437. setBackground(Color.lightGray);
  438. setBorder(BorderFactory.createLineBorder(Color.BLACK,1));
  439. }
  440. }
  441.  
  442. /*
  443. *Class Image_Panel
  444. */
  445. private class Image_Panel extends JPanel
  446. {
  447. /*
  448. *Constructor for displaying an image to be decoded
  449. */
  450. public Image_Panel()
  451. {
  452. //setup GridBagLayout
  453. GridBagLayout layout = new GridBagLayout();
  454. GridBagConstraints layoutConstraints = new GridBagConstraints();
  455. setLayout(layout);
  456.  
  457. image_input = new JLabel();
  458. layoutConstraints.gridx = 0; layoutConstraints.gridy = 0;
  459. layoutConstraints.gridwidth = 1; layoutConstraints.gridheight = 1;
  460. layoutConstraints.fill = GridBagConstraints.BOTH;
  461. layoutConstraints.insets = new Insets(0,0,0,0);
  462. layoutConstraints.anchor = GridBagConstraints.CENTER;
  463. layoutConstraints.weightx = 1.0; layoutConstraints.weighty = 50.0;
  464. JScrollPane scroll2 = new JScrollPane(image_input,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
  465. JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
  466. layout.setConstraints(scroll2,layoutConstraints);
  467. scroll2.setBorder(BorderFactory.createLineBorder(Color.BLACK,1));
  468. image_input.setHorizontalAlignment(JLabel.CENTER);
  469. add(scroll2);
  470.  
  471. decodeButton = new JButton("Decode Now");
  472. layoutConstraints.gridx = 0; layoutConstraints.gridy = 1;
  473. layoutConstraints.gridwidth = 1; layoutConstraints.gridheight = 1;
  474. layoutConstraints.fill = GridBagConstraints.BOTH;
  475. layoutConstraints.insets = new Insets(0,-5,-5,-5);
  476. layoutConstraints.anchor = GridBagConstraints.CENTER;
  477. layoutConstraints.weightx = 1.0; layoutConstraints.weighty = 1.0;
  478. layout.setConstraints(decodeButton,layoutConstraints);
  479. add(decodeButton);
  480.  
  481. //set basic display
  482. setBackground(Color.lightGray);
  483. setBorder(BorderFactory.createLineBorder(Color.BLACK,1));
  484. }
  485. }
  486.  
  487. /*
  488. *Main Method for testing
  489. */
  490. public static void main(String args[])
  491. {
  492. new Steganography_View("Steganography");
  493. }
  494. }
  495.  
  496.  
  497. Image filter class
  498.  
  499. import java.io.*;
  500.  
  501. /*
  502. *Image_Filter Class
  503. */
  504. public class Image_Filter extends javax.swing.filechooser.FileFilter
  505. {
  506. /*
  507. *Determines if the extension is of the defined types
  508. *@param ext Extension of a file
  509. *@return Returns true if the extension is 'jpg' or 'png'
  510. */
  511. protected boolean isImageFile(String ext)
  512. {
  513. return (ext.equals("jpg")||ext.equals("png"));
  514. }
  515.  
  516. /*
  517. *Determines if the file is a directory or accepted extension
  518. *@param f The File to run the directory/proper extension check on
  519. *@return Returns true if the File is a directory or accepted extension
  520. */
  521. public boolean accept(File f)
  522. {
  523. if (f.isDirectory())
  524. {
  525. return true;
  526. }
  527.  
  528. String extension = getExtension(f);
  529. if (extension.equals("jpg")||extension.equals("png"))
  530. {
  531. return true;
  532. }
  533. return false;
  534. }
  535.  
  536. /*
  537. *Supplies File type description
  538. *@return Returns the String description
  539. */
  540. public String getDescription()
  541. {
  542. return "Supported Image Files";
  543. }
  544.  
  545. /*
  546. *Determines the Extension
  547. *@param f File to return the extension of
  548. *@return Returns the String representing the extension
  549. */
  550. protected static String getExtension(File f)
  551. {
  552. String s = f.getName();
  553. int i = s.lastIndexOf('.');
  554. if (i > 0 && i < s.length() - 1)
  555. return s.substring(i+1).toLowerCase();
  556. return "";
  557. }
  558. }
  559.  
  560. New class
  561.  
  562. import java.io.File;
  563.  
  564. import java.awt.Point;
  565. import java.awt.Graphics2D;
  566. import java.awt.image.BufferedImage;
  567. import java.awt.image.WritableRaster;
  568. import java.awt.image.DataBufferByte;
  569.  
  570. import javax.imageio.ImageIO;
  571. import javax.swing.JOptionPane;
  572.  
  573. /*
  574. *Class Steganography
  575. */
  576. public class Steganography
  577. {
  578.  
  579. /*
  580. *Steganography Empty Constructor
  581. */
  582. public Steganography()
  583. {
  584. }
  585.  
  586. /*
  587. *Encrypt an image with text, the output file will be of type .png
  588. *@param path The path (folder) containing the image to modify
  589. *@param original The name of the image to modify
  590. *@param ext1 The extension type of the image to modify (jpg, png)
  591. *@param stegan The output name of the file
  592. *@param message The text to hide in the image
  593. *@param type integer representing either basic or advanced encoding
  594. */
  595. public boolean encode(String path, String original, String ext1, String stegan, String message)
  596. {
  597. String file_name = image_path(path,original,ext1);
  598. BufferedImage image_orig = getImage(file_name);
  599.  
  600. //user space is not necessary for Encrypting
  601. BufferedImage image = user_space(image_orig);
  602. image = add_text(image,message);
  603.  
  604. return(setImage(image,new File(image_path(path,stegan,"png")),"png"));
  605. }
  606.  
  607. /*
  608. *Decrypt assumes the image being used is of type .png, extracts the hidden text from an image
  609. *@param path The path (folder) containing the image to extract the message from
  610. *@param name The name of the image to extract the message from
  611. *@param type integer representing either basic or advanced encoding
  612. */
  613. public String decode(String path, String name)
  614. {
  615. byte[] decode;
  616. try
  617. {
  618. //user space is necessary for decrypting
  619. BufferedImage image = user_space(getImage(image_path(path,name,"png")));
  620. decode = decode_text(get_byte_data(image));
  621. return(new String(decode));
  622. }
  623. catch(Exception e)
  624. {
  625. JOptionPane.showMessageDialog(null,
  626. "There is no hidden message in this image!","Error",
  627. JOptionPane.ERROR_MESSAGE);
  628. return "";
  629. }
  630. }
  631.  
  632. /*
  633. *Returns the complete path of a file, in the form: path\name.ext
  634. *@param path The path (folder) of the file
  635. *@param name The name of the file
  636. *@param ext The extension of the file
  637. *@return A String representing the complete path of a file
  638. */
  639. private String image_path(String path, String name, String ext)
  640. {
  641. return path + "/" + name + "." + ext;
  642. }
  643.  
  644. /*
  645. *Get method to return an image file
  646. *@param f The complete path name of the image.
  647. *@return A BufferedImage of the supplied file path
  648. *@see Steganography.image_path
  649. */
  650. private BufferedImage getImage(String f)
  651. {
  652. BufferedImage image = null;
  653. File file = new File(f);
  654.  
  655. try
  656. {
  657. image = ImageIO.read(file);
  658. }
  659. catch(Exception ex)
  660. {
  661. JOptionPane.showMessageDialog(null,
  662. "Image could not be read!","Error",JOptionPane.ERROR_MESSAGE);
  663. }
  664. return image;
  665. }
  666.  
  667. /*
  668. *Set method to save an image file
  669. *@param image The image file to save
  670. *@param file File to save the image to
  671. *@param ext The extension and thus format of the file to be saved
  672. *@return Returns true if the save is succesful
  673. */
  674. private boolean setImage(BufferedImage image, File file, String ext)
  675. {
  676. try
  677. {
  678. file.delete(); //delete resources used by the File
  679. ImageIO.write(image,ext,file);
  680. return true;
  681. }
  682. catch(Exception e)
  683. {
  684. JOptionPane.showMessageDialog(null,
  685. "File could not be saved!","Error",JOptionPane.ERROR_MESSAGE);
  686. return false;
  687. }
  688. }
  689.  
  690. /*
  691. *Handles the addition of text into an image
  692. *@param image The image to add hidden text to
  693. *@param text The text to hide in the image
  694. *@return Returns the image with the text embedded in it
  695. */
  696. private BufferedImage add_text(BufferedImage image, String text)
  697. {
  698. //convert all items to byte arrays: image, message, message length
  699. byte img[] = get_byte_data(image);
  700. byte msg[] = text.getBytes();
  701. byte len[] = bit_conversion(msg.length);
  702. try
  703. {
  704. encode_text(img, len, 0); //0 first positiong
  705. encode_text(img, msg, 32); //4 bytes of space for length: 4bytes*8bit = 32 bits
  706. }
  707. catch(Exception e)
  708. {
  709. JOptionPane.showMessageDialog(null,
  710. "Target File cannot hold message!", "Error",JOptionPane.ERROR_MESSAGE);
  711. }
  712. return image;
  713. }
  714.  
  715. /*
  716. *Creates a user space version of a Buffered Image, for editing and saving bytes
  717. *@param image The image to put into user space, removes compression interferences
  718. *@return The user space version of the supplied image
  719. */
  720. private BufferedImage user_space(BufferedImage image)
  721. {
  722. //create new_img with the attributes of image
  723. BufferedImage new_img = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
  724. Graphics2D graphics = new_img.createGraphics();
  725. graphics.drawRenderedImage(image, null);
  726. graphics.dispose(); //release all allocated memory for this image
  727. return new_img;
  728. }
  729.  
  730. /*
  731. *Gets the byte array of an image
  732. *@param image The image to get byte data from
  733. *@return Returns the byte array of the image supplied
  734. *@see Raster
  735. *@see WritableRaster
  736. *@see DataBufferByte
  737. */
  738. private byte[] get_byte_data(BufferedImage image)
  739. {
  740. WritableRaster raster = image.getRaster();
  741. DataBufferByte buffer = (DataBufferByte)raster.getDataBuffer();
  742. return buffer.getData();
  743. }
  744.  
  745. /*
  746. *Gernerates proper byte format of an integer
  747. *@param i The integer to convert
  748. *@return Returns a byte[4] array converting the supplied integer into bytes
  749. */
  750. private byte[] bit_conversion(int i)
  751. {
  752. //originally integers (ints) cast into bytes
  753. //byte byte7 = (byte)((i & 0xFF00000000000000L) >>> 56);
  754. //byte byte6 = (byte)((i & 0x00FF000000000000L) >>> 48);
  755. //byte byte5 = (byte)((i & 0x0000FF0000000000L) >>> 40);
  756. //byte byte4 = (byte)((i & 0x000000FF00000000L) >>> 32);
  757.  
  758. //only using 4 bytes
  759. byte byte3 = (byte)((i & 0xFF000000) >>> 24); //0
  760. byte byte2 = (byte)((i & 0x00FF0000) >>> 16); //0
  761. byte byte1 = (byte)((i & 0x0000FF00) >>> 8 ); //0
  762. byte byte0 = (byte)((i & 0x000000FF) );
  763. //{0,0,0,byte0} is equivalent, since all shifts >=8 will be 0
  764. return(new byte[]{byte3,byte2,byte1,byte0});
  765. }
  766.  
  767. /*
  768. *Encode an array of bytes into another array of bytes at a supplied offset
  769. *@param image Array of data representing an image
  770. *@param addition Array of data to add to the supplied image data array
  771. *@param offset The offset into the image array to add the addition data
  772. *@return Returns data Array of merged image and addition data
  773. */
  774. private byte[] encode_text(byte[] image, byte[] addition, int offset)
  775. {
  776. //check that the data + offset will fit in the image
  777. if(addition.length + offset > image.length)
  778. {
  779. throw new IllegalArgumentException("File not long enough!");
  780. }
  781. //loop through each addition byte
  782. for(int i=0; i<addition.length; ++i)
  783. {
  784. //loop through the 8 bits of each byte
  785. int add = addition[i];
  786. for(int bit=7; bit>=0; --bit, ++offset) //ensure the new offset value carries on through both loops
  787. {
  788. //assign an integer to b, shifted by bit spaces AND 1
  789. //a single bit of the current byte
  790. int b = (add >>> bit) & 1;
  791. //assign the bit by taking: [(previous byte value) AND 0xfe] OR bit to add
  792. //changes the last bit of the byte in the image to be the bit of addition
  793. image[offset] = (byte)((image[offset] & 0xFE) | b );
  794. }
  795. }
  796. return image;
  797. }
  798.  
  799. /*
  800. *Retrieves hidden text from an image
  801. *@param image Array of data, representing an image
  802. *@return Array of data which contains the hidden text
  803. */
  804. private byte[] decode_text(byte[] image)
  805. {
  806. int length = 0;
  807. int offset = 32;
  808. //loop through 32 bytes of data to determine text length
  809. for(int i=0; i<32; ++i) //i=24 will also work, as only the 4th byte contains real data
  810. {
  811. length = (length << 1) | (image[i] & 1);
  812. }
  813.  
  814. byte[] result = new byte[length];
  815.  
  816. //loop through each byte of text
  817. for(int b=0; b<result.length; ++b )
  818. {
  819. //loop through each bit within a byte of text
  820. for(int i=0; i<8; ++i, ++offset)
  821. {
  822. //assign bit: [(new byte value) << 1] OR [(text byte) AND 1]
  823. result[b] = (byte)((result[b] << 1) | (image[offset] & 1));
  824. }
  825. }
  826. return result;
  827. }
  828.  
  829.  
  830. }
  831.  
  832.  
  833. [/Code]