Click here to Skip to main content
15,888,269 members
Articles / Desktop Programming / MFC

Porcupine

Rate me:
Please Sign up or sign in to vote.
4.78/5 (25 votes)
15 Sep 2009CPOL4 min read 570.5K   15.4K   118   80
A library for visible and invisible image watermarking

Porcupine ScreenShot

Introduction

Porcupine deals with digital image watermarking. You can embed any visible watermark like a text or another image in any position, or store information invisibly inside using a secret key (password).

Digital watermarking is a type of Steganography. In this field, except for the storage capacity of the host, the integrity of the information embedded to the host is very important. It is a technique which allows the dissimulation of information that verifies the owner, in digital sound, video, or image (in this case). The information can be encrypted. It constitutes a group of bits containing information about the creator, the owner, or the signal itself. Digital watermarking aims to validate the host and the undeniable identity of the legal owner. It provides a way for controlling host signals and represents the rightful holder. It also discourages illegal reproduction, and provides a way for safe distribution via the internet.

Some applications of digital watermarking:

  • The protection of intellectual rights, which is the most important application. When an illegal reproduction is detected, the offender should suffer the consequences of the law.
  • The proof of authenticity. The host must carry the digital signature of the creator.
  • The integrity of the host, if it continues to carry the digital signature.
  • The dissuasion of reproduction (copy control), caused by the fear of the probability that the offenders will be perceptible and suffer the consequences of the law.
  • The transmission of information without becoming perceptible from a third person, thanks to the invisible placement inside the host and its likely encrypted form.

Porcupine supports all of the known image formats (BMP, GIF, ICO, TGA, JPEG, PNG, TIFF, JPEG-2000, etc.).

Features

Visible Watermarking

  • Text Watermarking: Embeds a text on the image with the color and position of your choice. Each time, the text color selected and the pixel colors behind the text are checked. If they are the same, the text color changes automatically.
  • Image Watermarking: Embeds an image of your choice. Embedding options are via logical AND, OR, XOR, adding or subtracting, or drawing using the alpha channel.

Image 2

Invisible Watermarking

Spatial Domain

  • LSB manipulation: Hides any file in the Least Significant Bit of pixels chosen by a certain equation. This could be done randomly but that way, there should be a certain threshold on the file size to be watermarked (random numbers can not be given forever). The equation solution solves this issue, and exploits the image dimensions. Furthermore, there are two "LSB watermarking" options with different pixel positions for multiple watermarking. This type of watermark is considered a "fragile watermark". It can be destroyed with the slightest manipulation (so don't save the image as JPEG). The information is protected via XOR scrambling or Blowfish encryption.

Image 3

Example

Watermarked

Attack Results

Attacks

  • Patchwork: This is a statistical method that adds a Gaussian distribution. There is no information stored. The distribution is added randomly, and its existence proves the authenticity of the image.

Image 6

Example

Patchwork example

Attack Results

Attack Results

Frequency Domain

  • DCT Watermarking: Embeds information in the frequency domain. This is done using the 2-D Discrete Cosine Transform. The information is stored in the low-mid frequencies of the image. The storage capacity of this technique is very poor. In most cases, one or two words are enough. To prevent image destruction, the user is required to give the smallest DCT coefficient above which the watermark will be inserted. If a small coefficient, which doesn't contribute to the image creation, is changed, the image will be destroyed. This method is considered a robust watermarking method. Porcupine uses only grayscale images for this technique.

Image 9

Image 10

Example and attack results

DCT example

  • Batch Watermarking: This option allows you to simultaneously put a visible or invisible watermark in a number of images. The "LSB watermark" and "Patchwork" options save the final images in BMP format as it is a format with no compression.

Among others, there is also an FTP upload available for uploading your watermarked images, a text reader, and a PSNR calculator.

Image Library

Basic Image Processing Classes in:

Porcupine Index Theory

CxImage

eikonaDoc.h
eikonaView.h
mass.h

To run the program, you have to download the CxImage Library and do a batch build. Then download the Porcupine source and place the folder inside the CxImage folder, along with the others (bin, CxImage, Debug, demo, etc..). Download the required LIBs and place them inside the Porcupine source folder. Since you want to mess with the source code and have Visual Studio installed, you probably don't need the required DLLs. You're ready to go.

Image 12

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Greece Greece
Physicist/SW Engineer

Comments and Discussions

 
QuestionHow ? Pin
dew18-Nov-07 23:12
dew18-Nov-07 23:12 
AnswerRe: How ? Pin
Lampros Giampouras19-Nov-07 4:13
Lampros Giampouras19-Nov-07 4:13 
GeneralRe: How ? Pin
dew19-Nov-07 4:30
dew19-Nov-07 4:30 
GeneralRe: How ? Pin
Lampros Giampouras19-Nov-07 6:03
Lampros Giampouras19-Nov-07 6:03 
GeneralRe: How ? Pin
dew19-Nov-07 6:08
dew19-Nov-07 6:08 
GeneralRe: How ? Pin
dew21-Nov-07 5:26
dew21-Nov-07 5:26 
GeneralRe: How ? Pin
Lampros Giampouras6-Dec-07 14:18
Lampros Giampouras6-Dec-07 14:18 
GeneralRe: How ? Pin
Sarbashish Bhattacharjee8-Dec-08 4:03
Sarbashish Bhattacharjee8-Dec-08 4:03 
Hi Lampros,
I have followed your instruction in compiling the code. I am using VC++ 6.0 First I have downloaded the CxImage Library and do a batch build. everything goes smoothly. Then I have placed the Porcupine source files and the required LIB's and do a compilation. I get the following errors:-

eikonaView.cpp
d:\watermark\cximage\eikonaview.cpp(409) : warning C4018: '<' : signed/unsigned mismatch
lumiance.cpp
d:\watermark\cximage\lumiance.cpp(63) : warning C4244: '=' : conversion from 'int' to 'float', possible loss of data
MainFrm.cpp
Generating Code...
Compiling...
mass.cpp
Matrix.cpp
d:\watermark\cximage\matrix.cpp(677) : error C2374: 'i' : redefinition; multiple initialization
d:\watermark\cximage\matrix.cpp(669) : see declaration of 'i'
d:\watermark\cximage\matrix.cpp(714) : error C2374: 'i' : redefinition; multiple initialization
d:\watermark\cximage\matrix.cpp(706) : see declaration of 'i'

I got rid of the error "error C2374: 'i' : redefinition; multiple initialization" by putting a

#define for if(0);else for

in the matrix.cpp file declaration. After that I get the following error message:

Deleting intermediate files and output files for project 'eikona - Win32 Debug'.
--------------------Configuration: eikona - Win32 Debug--------------------
Compiling resources...
Compiling...
StdAfx.cpp
Compiling...
BlowFish.cpp
ChildFrm.cpp
dctdialog.cpp
dpassword.cpp
eikona.cpp
eikonaDoc.cpp
d:\watermark\cximage\eikonadoc.cpp(1393) : warning C4244: '=' : conversion from 'double' to 'unsigned char', possible loss of data
d:\watermark\cximage\eikonadoc.cpp(1496) : warning C4244: 'initializing' : conversion from 'double' to 'int', possible loss of data
Generating Code...
Compiling...
eikonaView.cpp
d:\watermark\cximage\eikonaview.cpp(409) : warning C4018: '<' : signed/unsigned mismatch
ftpaccess.cpp
ImInfo.cpp
jpegquality.cpp
lumiance.cpp
d:\watermark\cximage\lumiance.cpp(63) : warning C4244: '=' : conversion from 'int' to 'float', possible loss of data
MainFrm.cpp
Generating Code...
Compiling...
mass.cpp
Matrix.cpp
Mixer.cpp
noise.cpp
password.cpp
pixelcolor.cpp
Generating Code...
Compiling...
progress.cpp
psnr.cpp
quickmenu.cpp
result.cpp
rotate.cpp
seed.cpp
Generating Code...
Compiling...
spatialtext.cpp
statistical.cpp
technical.cpp
text.cpp
textr.cpp
thresh.cpp
Generating Code...
Compiling...
urldialog.cpp
WebGrab.cpp
Generating Code...
Linking...
Creating library Debug/eikona.lib and object Debug/eikona.exp
eikona.obj : error LNK2001: unresolved external symbol "public: virtual long __thiscall CxMemFile::Scanf(char const *,void *)" (?Scanf@CxMemFile@@UAEJPBDPAX@Z)
eikonaDoc.obj : error LNK2001: unresolved external symbol "public: virtual long __thiscall CxMemFile::Scanf(char const *,void *)" (?Scanf@CxMemFile@@UAEJPBDPAX@Z)
eikonaView.obj : error LNK2001: unresolved external symbol "public: virtual long __thiscall CxMemFile::Scanf(char const *,void *)" (?Scanf@CxMemFile@@UAEJPBDPAX@Z)
mass.obj : error LNK2001: unresolved external symbol "public: virtual long __thiscall CxMemFile::Scanf(char const *,void *)" (?Scanf@CxMemFile@@UAEJPBDPAX@Z)
eikona.obj : error LNK2001: unresolved external symbol "public: virtual char * __thiscall CxMemFile::GetS(char *,int)" (?GetS@CxMemFile@@UAEPADPADH@Z)
eikonaDoc.obj : error LNK2001: unresolved external symbol "public: virtual char * __thiscall CxMemFile::GetS(char *,int)" (?GetS@CxMemFile@@UAEPADPADH@Z)
eikonaView.obj : error LNK2001: unresolved external symbol "public: virtual char * __thiscall CxMemFile::GetS(char *,int)" (?GetS@CxMemFile@@UAEPADPADH@Z)
mass.obj : error LNK2001: unresolved external symbol "public: virtual char * __thiscall CxMemFile::GetS(char *,int)" (?GetS@CxMemFile@@UAEPADPADH@Z)
eikona.obj : error LNK2001: unresolved external symbol "public: bool __thiscall CxImage::DestroyFrames(void)" (?DestroyFrames@CxImage@@QAE_NXZ)
eikonaDoc.obj : error LNK2001: unresolved external symbol "public: bool __thiscall CxImage::DestroyFrames(void)" (?DestroyFrames@CxImage@@QAE_NXZ)
eikonaView.obj : error LNK2001: unresolved external symbol "public: bool __thiscall CxImage::DestroyFrames(void)" (?DestroyFrames@CxImage@@QAE_NXZ)
mass.obj : error LNK2001: unresolved external symbol "public: bool __thiscall CxImage::DestroyFrames(void)" (?DestroyFrames@CxImage@@QAE_NXZ)
eikonaView.obj : error LNK2001: unresolved external symbol "public: bool __thiscall CxImage::AlphaCreate(void)" (?AlphaCreate@CxImage@@QAE_NXZ)
mass.obj : error LNK2001: unresolved external symbol "public: bool __thiscall CxImage::AlphaCreate(void)" (?AlphaCreate@CxImage@@QAE_NXZ)
Debug/eikona.exe : fatal error LNK1120: 4 unresolved externals
Error executing link.exe.

eikona.exe - 15 error(s), 4 warning(s)

I tried all sorts of combinations but I failed to make it work.

Can anyone help me in solving the problem.

With Regards,

Sarbashish Bhattacharjee
GeneralRe: How ? Pin
Roberto_Rwk28-Nov-07 21:01
Roberto_Rwk28-Nov-07 21:01 
GeneralRe: How ? Pin
pycolle2-Jan-08 4:11
pycolle2-Jan-08 4:11 
QuestionHow to run porcupine? Pin
Dipangkur3-May-08 8:41
Dipangkur3-May-08 8:41 
AnswerRe: How to run porcupine? Pin
Lampros Giampouras3-May-08 23:50
Lampros Giampouras3-May-08 23:50 
GeneralRe: How to run porcupine? Pin
Dipangkur4-May-08 16:46
Dipangkur4-May-08 16:46 
GeneralRe: How to run porcupine? Pin
hvd_hut6-Nov-08 22:17
hvd_hut6-Nov-08 22:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.