Low-level loader of JPEG DCT coefficients, based on libjpeg.
Project description
Stegojpeg
A low-level JPEG loader for acquiring DCT coefficients and quantization tables. It uses libjpeg for reading of the JPEG format.
Setup
Package stegojpeg
is developed for Python3. Install using pip (or pip3) with
pip3 install stegojpeg
For now, libjpeg
is linked dynamically and hence must be installed manually.
If the pip command fails on jpeglib.h: No such file or directory, libjpeg
is missing.
apt-get install libjpeg-dev # ubuntu
brew install jpeg # mac
Usage
There is a file input.jpeg
of dimensions H x W. Get its DCT (discrete cosine transform) coefficients and quantization matrices in numpy tensor with
import stegojpeg
im = stegojpeg.JPEG("input.jpeg") # load metadata
Y,CbCr,qt = im.read_dct() # load data
We receive three values
- Luminance DCT coefficients as numpy array of shape (1,H/8,W/8,8,8)
- Chrominance DCT coefficients as numpy array of shape (2,H/8/2,W/8/2,8,8) for subsampling 4:2:2
- Quantization tables as numpy array of shape (3,8,8)
DCT coefficients are commonly used to embed a steganographic message to. Once done, create a file with modified DCT with
im.write_dct("output.jpeg", Y, CbCr) # write data
Read the spatial representation of input.jpeg
with
im = stegojpeg.JPEG("input.jpeg")
spatial = im.read_spatial()
The reading can be parameterized with spatial color space, dithering mode, dct method and various boolean flags. For not-specified parameters, default of libjpeg is used.
spatial = im.read_spatial(
out_color_space = "JCS_GRAYSCALE", # color space of output
dither_mode = "JDITHER_FS", # dithering mode
dct_method = "JDCT_FLOAT", # dct method
flags = ["DO_FANCY_UPSAMPLING", "DO_BLOCK_SMOOTHING"] # flags to be set true
)
Writing of a spatial representation is done with
im.write_spatial("output.jpeg", spatial)
If you do not specify the second parameter, the original source data is used.
Similarly to reading there are parameters for writing that you can use. Based on the source of libjpeg default, if not specified.
im.write_spatial(
"output.jpeg",
spatial,
in_color_space = "JCS_RGB", # color space of input
dct_method = "JDCT_ISLOW", # dct method
samp_factor = (2,1,1), # sampling factor
quality = 75, # compression quality
smoothing_factor = 0, # smoothing factor
flags = ["QUANTIZE_COLORS","WRITE_JFIF_HEADER"]
)
Dependencies and platforms
Tested on MacOS and Linux. There is a known bug which is planned to be fixed in the future.
For the installation you need
- C compiler (gcc, clang)
- libjpeg + properly configured environment (so compiler & linker can find it)
Future extensions
-
Static linking of libjpeg = libjpeg will be distributed with the stegojpeg and linked statically. The arguments pro are
- Removal of the external dependency.
- Manual control of the libjpeg version. Ability to select in runtime.
-
Possible to make changes in quantization tables = for now modifications are only possible on DCT coefficients
-
Independence on source file = to write matrices you need the object you used for reading, because metadata are copied. I would like this to be independent, so the writing is state-less and the memory can be released
import stegojpeg
with stegojpeg.JPEG("input.jpeg") as im:
Y,CbCr,qt = im.read_dct() # read DCT
# modify here
im.write_dct("output.jpeg", Y, CbCr) # write DCT
# load RGB
import numpy as np
from PIL import Image
im1 = np.array(Image.open("input.jpeg")) # original
im2 = np.array(Image.open("output.jpeg")) # modified
- Fix Windows installation = make sure the library can be installed on Windows
Credits
Developed by Martin Benes.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.