|\ /|     scroll down for older posts.
= o.o =

Freitag, 26. August 2016

Nearest Mean Interpolation: a method to scale up images

Here is a nice and clean method of scaling up an image to double its size:

screenshot of a comment in pepperpickle's source code

I found it in the research paper that describes the HCRHide image steganography algorithm: https://www.researchgate.net/publication/272307744_A_high-capacity_reversible_data_hiding_method_HCRHide

The main quality of this algorithm is that the original image can be reconstructed without any loss of color information. Pixels a, b, c and d are taken from the original image. the three lambda-pixels we get for each original pixel can be used to store information steganographically. Here is my golang implementation of the NMI scaling-algorithm:

// scaleNMI scales up an image using the NMI method (Nearest Mean
// Interpolation)
Here is how NMI works:
four neighbouring pixels of the original image are obtained:
|    |    |
| a  | b  |
|    |    |
| c  | d  |

between those pixels, new ones are inserted:
|    |    |    |
| a  | λ₁ | b  |
|    |    |    |
| λ₂ | λ₃ | λ₄ |
|    |    |    |
| c  | λ₅ | d  |

The color values for the new pixels are calculated using the following


Those are calculated in the next pixel set as λ₁ and λ₂:

The original formula for λ₃ is:

Per pass, the image is scaled up to double its size.
func scaleNMI(src image.Image) image.Image {
        bounds := src.Bounds()
        w, h := bounds.Max.X, bounds.Max.Y
        dest := image.NewRGBA(image.Rect(0, 0, w*2, h*2))
        dX, dY := 0, 0

        for x := 0; x < w; x++ {
        for y := 0; y < h; y++ {
        a := src.At(x, y)
        b := src.At(x+1, y)
        c := src.At(x, y+1)
        d := src.At(x+1, y+1)

        if x > w-2 {
        b = a
        d = a
        if y > h-2 {
        c = a
        d = a

        aR, aG, aB, aA := a.RGBA()
        bR, bG, bB, bA := b.RGBA()
        cR, cG, cB, cA := c.RGBA()
        dR, dG, dB, dA := d.RGBA()

        l1R, l1G, l1B, l1A :=
        ((aR + bR) / 2), // >> 1: divide by 2
        ((aG + bG) / 2),
        ((aB + bB) / 2),
        ((aA + bA) / 2)
        l2R, l2G, l2B, l2A :=
        ((aR + cR) / 2),
        ((aG + cG) / 2),
        ((aB + cB) / 2),
        ((aA + cA) / 2)
        l3R, l3G, l3B, l3A :=
        ((aR + bR + cR + dR) / 4), // >> 2: divide by 4
        ((aG + bG + cG + dG) / 4),
        ((aB + bB + cB + dB) / 4),
        ((aA + bA + cA + dA) / 4)

        dest.Set(dX, dY, color.RGBA{
        uint8(aR / 256), // >> 8 divide by 256
        uint8(aG / 256),
        uint8(aB / 256),
        uint8(aA / 256)})
        dest.Set(dX+1, dY, color.RGBA{
        uint8(l1R / 256),
        uint8(l1G / 256),
        uint8(l1B / 256),
        uint8(l1A / 256)})
        dest.Set(dX, dY+1, color.RGBA{
        uint8(l2R / 256),
        uint8(l2G / 256),
        uint8(l2B / 256),
        uint8(l2A / 256)})
        dest.Set(dX+1, dY+1, color.RGBA{
        uint8(l3R / 256),
        uint8(l3G / 256),
        uint8(l3B / 256),
        uint8(l3A / 256)})

        dY += 2
        dY = 0
        dX += 2

        return dest

Montag, 22. August 2016

Steganography: A Visual Comparison Of Least Significant Bit Embedding Methods In Images

Bonbon for reading this: here is an image of a Beluga whale. It contains the whole novel "Moby Dick" by Herman Melville, which is in the public domain and was taken from Project Gutenberg:

This image can be decrypted with the current stable version of pepperpickle, v0.0.3.
The decryption password is: mobydick

Credits: taken from Wikipedia; original photo by Steve Snodgrass, licensed under CC-by-SA

I've been adding more flexibility to my development version of pepperpickle, and made some tests. Here are a few results.
I recommend scrolling down first, to get an overview of the changes in image quality.

The original images I used are as follows:

Baboon, Lena and sweet peppers, each 256x256 pixels in size.

I have embedded random data in the whole available storage space. When using only the Least Significant Bit (LSB) for embedding, an additional storage space of 24576 bytes for each image can be achieved, which is quite a lot:

As can be seen, there is no visual difference between the stego images and the originals. Using the second LSB and the first LSB, an additional storage capacity of 49152 bytes per image can be achieved. Yet, I had to slightly turn down the most intensive color values to compensate for an integer overflow I am currently weeding out:

Apart from being slightly brighter, there is also no visual difference between the images. This will change drastically later on, but first, let's try the method of threshold-based embedding I wrote about earlier.
This gives us varying storage capacity, 41278 bytes for Baboon, 43434 bytes for Lena and a whopping 63528 bytes for the peppers:

Still an excellent image quality...
With 3 LSBs we get 73728 bytes per image:

Nothing critical, yet.
Let's try 4 LSBs. 98304 bytes per image are used for data storage:

Apart from some artefacts due to the aforementioned overflow bug, the image quality is still quite acceptable.
Let's go for 5 LSBs (122880  bytes):

We're losing quite some quality now, but the noisy Baboon image is a good carrier.
6 LSBs (147456 bytes):

The image quality is now unacceptably low. The noise dominates the image information.
For completeness' sake here are 7 LSBs (172032 bytes):

Using an additional bit would completely destroy the image and result in random noise:

random noise or encrypted data? Who can tell...

When we zoom into the noise, we get something that resembles some newer artwork by Bridget Riley, whose art I honestly admire (hint for art historians and steganalysts alike: maybe she embedded something in her paintings...):

Sonntag, 21. August 2016


After a lot of theoretical work I am in the middle of completely rewriting pepperpickle. Currently I am half through the encryption/embedding process...

Sonntag, 14. August 2016

Steganography: an algorithm for threshold based embedding

I am doing a little bit of research lately because steganography has become an interesting hobby of mine.

The first "real" algorithm that will make it into pepperpickle's feature set is "Threshold-based" as discussed in the following paper by Khan, Shah, Naeem et al.:

It is strikingly simple to implement and, according to the authors, improves the payload and Signal-to-Noise-Ratio - let's see :)

here is how it works:
Threshold-based embedding. I found no traces of steganography in this image.

I propose the following addition, though:
If a pixel is completely white (255, 255, 255) or black (0, 0, 0), leave it as it is to make steganalysis a little bit harder.

Samstag, 6. August 2016

pixelblorb v0.0.1 released!

I proudly announce the release of pixelblorb.

pixelblorb is a simple command line tool to extract an image's pixel data as text output.

Although its intended purpose is to aid in steganalysis, it can also be used to inspect color information and as a means to further process images.

The source code and README is available at github:

Binary releases for Windows, Linux-amd64, Mac OS X and FreeBSD-amd64 can be downloaded here:

As always, feature requests, bug reports and comments are greatly welcome.

Montag, 1. August 2016

'still' life