/** * Method to embed the message into the cover data * * @param msg Message to be embedded * @param msgFileName Name of the message file. If this value is provided, then the filename * should be embedded in the cover data * @param cover Cover data into which message needs to be embedded * @param coverFileName Name of the cover file * @param stegoFileName Name of the output stego file * @return Stego data containing the message * @throws OpenStegoException */ public byte[] embedData( byte[] msg, String msgFileName, byte[] cover, String coverFileName, String stegoFileName) throws OpenStegoException { BufferedImage image = null; List<int[][]> yuv = null; DWT dwt = null; ImageTree dwtTree = null; ImageTree p = null; Signature sig = null; Pixel pixel1 = null; Pixel pixel2 = null; Pixel pixel3 = null; int[][] luminance = null; int imgType = 0; int origWidth = 0; int origHeight = 0; int cols = 0; int rows = 0; int n = 0; double temp = 0.0; // Cover file is mandatory if (cover == null) { throw new OpenStegoException(null, NAMESPACE, DWTXieErrors.ERR_NO_COVER_FILE); } else { image = ImageUtil.byteArrayToImage(cover, coverFileName); } imgType = image.getType(); origWidth = image.getWidth(); origHeight = image.getHeight(); image = ImageUtil.makeImageSquare(image); cols = image.getWidth(); rows = image.getHeight(); yuv = ImageUtil.getYuvFromImage(image); luminance = yuv.get(0); sig = new Signature(msg); // Wavelet transform dwt = new DWT(cols, rows, sig.filterID, sig.embeddingLevel, sig.waveletFilterMethod); dwtTree = dwt.forwardDWT(luminance); p = dwtTree; // Consider each resolution level while (p.getLevel() < sig.embeddingLevel) { // Descend one level p = p.getCoarse(); } // Repeat binary watermark by sliding a 3-pixel window of approximation image for (int row = 0; row < p.getImage().getHeight(); row++) { for (int col = 0; col < p.getImage().getWidth() - 3; col += 3) { // Get all three approximation pixels in window pixel1 = new Pixel(0, DWTUtil.getPixel(p.getImage(), col + 0, row)); pixel2 = new Pixel(1, DWTUtil.getPixel(p.getImage(), col + 1, row)); pixel3 = new Pixel(2, DWTUtil.getPixel(p.getImage(), col + 2, row)); // Bring selected pixels in ascending order if (pixel1.value > pixel2.value) { swapPix(pixel1, pixel2); } if (pixel2.value > pixel3.value) { swapPix(pixel2, pixel3); } if (pixel1.value > pixel2.value) { swapPix(pixel1, pixel2); } // Apply watermarking transformation (modify median pixel) temp = wmTransform( sig.embeddingStrength, pixel1.value, pixel2.value, pixel3.value, getWatermarkBit(sig.watermark, n % (sig.watermarkLength * 8))); // Write modified pixel DWTUtil.setPixel(p.getImage(), col + pixel2.pos, row, temp); n++; } } dwt.inverseDWT(dwtTree, luminance); yuv.set(0, luminance); image = ImageUtil.cropImage(ImageUtil.getImageFromYuv(yuv, imgType), origWidth, origHeight); return ImageUtil.imageToByteArray(image, stegoFileName, this); }
/** * Method to extract the message from the stego data * * @param stegoData Stego data containing the message * @param stegoFileName Name of the stego file * @param origSigData Optional signature data file for watermark * @return Extracted message * @throws OpenStegoException */ public byte[] extractData(byte[] stegoData, String stegoFileName, byte[] origSigData) throws OpenStegoException { List<Integer> sigBitList = new ArrayList<Integer>(); BufferedImage image = null; DWT dwt = null; ImageTree dwtTree = null; ImageTree p = null; Signature sig = null; Pixel pixel1 = null; Pixel pixel2 = null; Pixel pixel3 = null; int[][] luminance = null; int cols = 0; int rows = 0; int n = 0; image = ImageUtil.makeImageSquare(ImageUtil.byteArrayToImage(stegoData, stegoFileName)); cols = image.getWidth(); rows = image.getHeight(); luminance = ImageUtil.getYuvFromImage(image).get(0); sig = new Signature(origSigData); // Wavelet transform dwt = new DWT(cols, rows, sig.filterID, sig.embeddingLevel, sig.waveletFilterMethod); dwtTree = dwt.forwardDWT(luminance); p = dwtTree; // Consider each resolution level while (p.getLevel() < sig.embeddingLevel) { // Descend one level p = p.getCoarse(); } // Repeat binary watermark by sliding a 3-pixel window of approximation image for (int row = 0; row < p.getImage().getHeight(); row++) { for (int col = 0; col < p.getImage().getWidth() - 3; col += 3) { // Get all three approximation pixels in window pixel1 = new Pixel(0, DWTUtil.getPixel(p.getImage(), col + 0, row)); pixel2 = new Pixel(1, DWTUtil.getPixel(p.getImage(), col + 1, row)); pixel3 = new Pixel(2, DWTUtil.getPixel(p.getImage(), col + 2, row)); // Bring selected pixels in ascending order if (pixel1.value > pixel2.value) { swapPix(pixel1, pixel2); } if (pixel2.value > pixel3.value) { swapPix(pixel2, pixel3); } if (pixel1.value > pixel2.value) { swapPix(pixel1, pixel2); } // Apply inverse watermarking transformation to get the bit value sigBitList.add( invWmTransform(sig.embeddingStrength, pixel1.value, pixel2.value, pixel3.value)); n++; } } sig.setWatermark(convertBitListToByteArray(sigBitList)); return sig.getSigData(); }