0

This is a Link Embedding Messages in Digital Images using JAVA, they provide the sample code also, but when i tried to embed over 38 characters, it will give different output when i run the decode part. I am using 111x115 (6.38k) image.

my question is in this article, it said n=(p-32)/8 , n is the maximum length of message and P is the number of pixels. so if i calculate the image i used, it will be n=(6380-32)/8=793.5. Since like i could store 793.5 characters in this image, but when i tried to put more than 38 characters, it will give me different output when i did decode part. (under 38 character is fine)

Jarek Huang
  • 119
  • 3
  • 17
  • What was the message you tried to hide? It shouldn't be a problem with the storage capacity, as the program warns you when you don't have enough space. My guess is something goes wrong with the embedding. – Reti43 Jan 23 '14 at 16:03
  • This is the [image](https://dl.dropboxusercontent.com/u/14562196/test.png) i used, and for the message i just put the 39's A letter (AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA), and it generated different [result](https://dl.dropboxusercontent.com/u/14562196/post/DECODE%20result.png) ; [Embed message](https://dl.dropboxusercontent.com/u/14562196/post/embed.png) ; [Result from console](https://dl.dropboxusercontent.com/u/14562196/post/CONSOLE.png) – Jarek Huang Jan 23 '14 at 18:01
  • I won't be able to run this code on my machine for a few days, so I recommend you try the following. Run the program and for every embedding character (not the message length) print the coordinates of the embedding pixel, the original pixel value and what it changes to. Similarly, for the decoding process, print the coordinates of the pixels you're reading and their values. Any discrepancies between the encoding and decoding will give hints about the problem. From your results, only one character differs, so it could be as few as one offending bits. – Reti43 Jan 23 '14 at 18:38
  • Ok, I will try to run it as the same way you said. Thank you again. – Jarek Huang Jan 23 '14 at 19:24

1 Answers1

1

Right, I found the bug! And as I was expecting, some pixels were getting overwritten. The problem is in the embedByte function, specifically, in the conditions of the for loops.

for(int i=startX; i<maxX && count<8; i++) {
   for(int j=startY; j<maxY && count<8; j++) {

Each loop will iterate until you either reach the end of the row/column or the count reaches 8. The problem arises when you terminate because the end of the row/column has been reached. To demonstrate this, this is what happens for your image.

The first character is embedded in pixels (0, 32), (0, 33), ..., (0, 39). This is all straightforward until you reach the 11th character, where you get the following.

(0, 112)
(0, 113)
(0, 114)
(1, 112)
(1, 113)
(1, 114)
(2, 112)
(2, 113)

The reason for this mess is at (0, 114). At j=114, the j loop has reached its limit and exits. Since count is not 8 yet, we go back to the i loop, which increments by 1 and then enters the j loop again, which starts at startY=112. This explains (1, 112) and what comes next. These pixels shouldn't have been changed yet, since they will be overwritten during the 25th character (normally written for the first time). Instead, you should have gotten this:

(0, 112)
(0, 113)
(0, 114)
(1, 0)
(1, 1)
(1, 2)
(1, 3)
(1, 4)

To achieve this, once you have reached the edge with j, you want to reset startY. You can do this by adding the following code inside the j loop.

if(j==maxY-1) {
   startY = 0;
}

Similarly, you want to add this correction in the extractByte function for the decoding process.

Observation

Since you can fit approximately 14 characters in 115 pixels, this is when the problem arises. This explains the 11 -> 25 -> 39. By coincidence, the sharing pixels that 11 and 25 write, embed the same bit and the bug is not expressed. But with the introduction of 39, 25 is affected.

Reti43
  • 9,656
  • 3
  • 28
  • 44
  • Hi Reti, Do you mind i ask, in this site they said "example uses only the least significant bit of the alpha part of a pixel.", but where i can see in the code they only use "least significant bit of the alpha part of a pixel". Is that the set/getBitValue?? – Jarek Huang Jan 24 '14 at 14:45
  • Yes, exactly. The page explains what the `getRGB` method does from the java.awt.image.BufferedImage class. The `set/getBitValue` takes as an input the object `int location`. For location = 0, this is the LSB of the alpha component, for location = 8 the LSB of the red component, and so on. – Reti43 Jan 24 '14 at 15:46
  • Since like location = count; `getBitValue(int n, int location)`, but if location =count, it will have two value from either `embedInteger` and `embedByte` ?? – Jarek Huang Jan 24 '14 at 16:02
  • 1
    Sorry, I read it too quickly. `getBitValue` extracts the nth bit from the embedding character byte, which is why you need count as the input. `setBitValue` IS method that embeds the said bit to a specific location in the RGBA value. This location is controlled by the object `storageBit`. And that is indeed set to 0, hence the LSB of the alpha component. – Reti43 Jan 24 '14 at 16:10
  • Could you correct me if i say it wrong. You said " `getBitValue` extracts the nth bit from the embedding character byte", it means convert each character byte to bit?? and if i want to embed message to LSB of the Red component, i only need to change the location by the object `storageBit` to 8?? (all `storeageBit` from `embedInteger`, `embedByte` and `setBitValue`?? – Jarek Huang Jan 24 '14 at 16:26
  • It's the storageBit in the input of `embedInteger` and `embedByte` that you need to change. Since you have created a question about this specific topic, let's take it there. It's considered off topic here since this has been about a different question, which has already been resolved. – Reti43 Jan 24 '14 at 16:34
  • Sorry about that. I really learned a lot from you recently. Thank you very much be that patience to teach me. Thank you. – Jarek Huang Jan 24 '14 at 16:39
  • Hi Reti, Could you help me with [this](http://stackoverflow.com/questions/21344280/getting-setting-a-bit-value-from-image)(<=link) because i am still not clear with `getBitValue(int n, int location)` and `setBitValue(int n, int location, int bit)` Thank you – Jarek Huang Jan 24 '14 at 23:21
  • When embed message character one by one, the first character will be embedded in (0,33), am i right? – Jarek Huang Jan 25 '14 at 16:08
  • 1
    No. In Java, like in other languages, indexing starts at 0. So if you have 115 pixels which you call 1-115, their indices are 0-114. That's why maxY is 114. So, the first 32 pixels are 0-31 and the 33rd is at index 32. – Reti43 Jan 25 '14 at 16:16