HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Image Stenography using LSB technique

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
techniqueimageusingstenographylsb

Problem

The program can be used to hide an image within another image and later extract the hidden image. This is done by concealing the secret image within the lowest bits of the apparent image. Example of a cat hidden within a tree.

I split it into 2 programs to make commandline args parsing easier, Crypt and Decrypt.

Info.h

//Info.h
#pragma once
#include 

const int keySpace = 6;
typedef uint16_t PTYPE;

unsigned int bitMax(int bits) {
    return (unsigned int)pow(2, bits) - 1;
}


Crypt.h

//Crypt.h
#include "CImg.h"
#include "Info.h"

#include 
#include 
#include 
#include 

using namespace cimg_library;
using std::string;

std::map parseCMD(int argc, char *argv[]);

template
void encrypt(CImg& apparent, CImg& secret, std::map args) {
    if (!apparent.containsXYZC(secret.width() - 1, secret.height() - 1, secret.depth() - 1, secret.spectrum() - 1)) { //Check that secret fits inside apparent.
        throw std::invalid_argument("Secret is out of bounds of apparent.");
    }

    int bitDepth = std::stoi(args["bitdepth"]) / apparent.spectrum();
    int secretBitDepth = std::stoi(args["secretbitdepth"]) / secret.spectrum();

    apparent.normalize(0, bitMax(bitDepth));
    secret.normalize(0, bitMax(secretBitDepth));

    T secretMask = ~bitMax(secretBitDepth);

    cimg_forXYZC(apparent, x, y, z, v) {
        apparent.atXYZC(x, y, z, v) = (apparent.atXYZC(x, y, z, v) & secretMask) | secret.atXYZC(x, y, z, v); //Set apparent's *secretBitDepth* least significant bits to secret's value. 
    }
}

//Sets the R value of the first *keySpace* pixels of apparent to the binary value of the rotational key.
template
void sign(CImg& img, int key) {
    if (key > bitMax(keySpace)) {
        std::stringstream ss;
        ss  bitKey(key);
    for (int i = 0; i < keySpace; i++) {
        img.atXYZC(i, 0, 0, 0) = bitKey[i];
    }
}


Crypt.cpp

```
//Crypt.cpp
#include "Crypt.h"

#include

int main(int argc, char *argv[]) {
auto args = parseCMD(argc, argv);

CIm

Solution

Include all the headers you need

Info.h doesn't include required header for pow function (math.h)

Use const references when you don't want to modify parameters to avoid unnecessary copying

encrypt function in Crypt.h

template 
void encrypt(CImg& apparent, CImg& secret, std::map args)


should be

template 
void encrypt(CImg& apparent, CImg& secret, std::map const& args)


Do the all the conversions you need before supplying parameters to functions

int bitDepth = std::stoi(args["bitdepth"]) / apparent.spectrum();


This is not good since args["bitdepth"] can simply not convert into integer, you should've processed the arguments separately. The same holds for other arguments. This means you should rewrite parseCMD function or use some arguments parsing library.

Code Snippets

template<typename T> 
void encrypt(CImg<T>& apparent, CImg<T>& secret, std::map<string, string> args)
template<typename T> 
void encrypt(CImg<T>& apparent, CImg<T>& secret, std::map<string, string> const& args)
int bitDepth = std::stoi(args["bitdepth"]) / apparent.spectrum();

Context

StackExchange Code Review Q#133962, answer score: 2

Revisions (0)

No revisions yet.