Blame view

msteg/steganography/F3.py 3.13 KB
6cbb3879   Chunk   F4 updated.
1
2
3
"""
<p>This module implements the F3 steganography algorithm invented by
Andreas Westfeld.</p>
548d95dc   Chunk   steganography(F3 ...
4
5

It embeds a secret message in JPEG DCT coefficients.
b69b6985   Chunk   py module refract...
6
It differs from simpler algorithms such as JSteg by subtracting the
548d95dc   Chunk   steganography(F3 ...
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
absolute DCT value if the currently embedded bit and the LSB of the DCT
value are not equal. DCT coefficients with value 0 are ignored.<br />
If a DCT coefficient is equal to 1 or -1 the current bit
is embedded repeatedly in order to make non-ambiguous extraction possible.
"""
import time
import math
import numpy as np
from StegBase import *
from common import *


class F3(StegBase):
    """ This module has two methods: <i>embed_raw_data</i> to embed data
    with the F3 algorithm and <i>extract_raw_data</i> to extract data
    which was embedded previously. """

    def __init__(self):
        """
        Constructor of the F3 class.
        """
        StegBase.__init__(self)

    def embed_raw_data(self, src_cover, src_hidden, tgt_stego):
        """ This method embeds arbitrary data into a cover image.
        The cover image must be a JPEG.

        src_cover - A valid pathname to an image file which serves as cover image
        (the image which the secret image is embedded into).
6cbb3879   Chunk   F4 updated.
36

548d95dc   Chunk   steganography(F3 ...
37
38
39
40
41
42
43
44
45
46
        src_hidden - A valid pathname to an arbitrary file that is supposed to be
        embedded into the cover image.

        tgt_stego - Target pathname of the resulting stego image. You should save to a
        PNG or another lossless format, because many LSBs don't survive
        lossy compression.
        """
        self.t0 = time.time()
        StegBase._post_embed_actions(self, src_cover, src_hidden, tgt_stego)

6cbb3879   Chunk   F4 updated.
47
    def extract_raw_data(self, src_steg, tgt_hidden):
548d95dc   Chunk   steganography(F3 ...
48
        """ This method extracts secret data from a stego image. It is
6cbb3879   Chunk   F4 updated.
49
        (obviously) the inverse operation of embed_raw_data.
548d95dc   Chunk   steganography(F3 ...
50
51
52
53
54
55
56
57
58
59
60

        src_stego - A valid pathname to an image file which serves as stego image.

        tgt_hidden - A pathname denoting where the extracted data should be saved to.
        """
        self.t0 = time.time()
        StegBase._post_extract_actions(self, src_steg, tgt_hidden)

    def _raw_embed(self, cov_data, hid_data, status_begin=0):
        """
        cov_data - 4-D numpy.int32 array
c9fdeb00   Chunk   LSB and F4 added.
61
        hid_data - 1-D numpy.uint8 array
548d95dc   Chunk   steganography(F3 ...
62
63
64
65
66
67
        """
        hid_data = bytes2bits(hid_data)
        i = 0
        cnt = -1
        for x in np.nditer(cov_data, op_flags=['readwrite']):
            cnt = cnt + 1
45a82355   Chunk   staged.
68
            if x == 0 or cnt % 64 == 0: continue
548d95dc   Chunk   steganography(F3 ...
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

            m = hid_data[i]
            if x & 1 != m:
                x[...] -= math.copysign(1, x)
                if x == 0: continue
            i += 1
            if i == hid_data.size: break

        return cov_data

    def _raw_extract(self, steg_data, num_bits):
        """
        Just a small helper function to extract hidden data.
        """
        hid_data = np.zeros(num_bits, np.uint8)
45a82355   Chunk   staged.
84
        j = 0
548d95dc   Chunk   steganography(F3 ...
85
86
87
        cnt = -1
        for x in np.nditer(steg_data):
            cnt = cnt + 1