Untitled
unknown
plain_text
a year ago
6.6 kB
11
Indexable
#include <stdio.h>
#include <stdlib.h>
#include <png.h>
#include <math.h>
#define BLOCK_SIZE 8
// Function to perform DCT on an 8x8 block
void dct(double block[BLOCK_SIZE][BLOCK_SIZE]) {
double alpha, beta, sum;
double tmp[BLOCK_SIZE][BLOCK_SIZE];
for (int u = 0; u < BLOCK_SIZE; u++) {
for (int v = 0; v < BLOCK_SIZE; v++) {
sum = 0.0;
for (int x = 0; x < BLOCK_SIZE; x++) {
for (int y = 0; y < BLOCK_SIZE; y++) {
sum += block[x][y] *
cos(((2 * x + 1) * u * M_PI) / (2 * BLOCK_SIZE)) *
cos(((2 * y + 1) * v * M_PI) / (2 * BLOCK_SIZE));
}
}
alpha = (u == 0) ? sqrt(1.0 / BLOCK_SIZE) : sqrt(2.0 / BLOCK_SIZE);
beta = (v == 0) ? sqrt(1.0 / BLOCK_SIZE) : sqrt(2.0 / BLOCK_SIZE);
tmp[u][v] = alpha * beta * sum;
}
}
// Copy the result back to the original block
for (int i = 0; i < BLOCK_SIZE; i++) {
for (int j = 0; j < BLOCK_SIZE; j++) {
block[i][j] = tmp[i][j];
}
}
}
// Function to perform Inverse DCT on an 8x8 block
void inverse_dct(double block[BLOCK_SIZE][BLOCK_SIZE]) {
double alpha, beta, sum;
double tmp[BLOCK_SIZE][BLOCK_SIZE];
for (int x = 0; x < BLOCK_SIZE; x++) {
for (int y = 0; y < BLOCK_SIZE; y++) {
sum = 0.0;
for (int u = 0; u < BLOCK_SIZE; u++) {
for (int v = 0; v < BLOCK_SIZE; v++) {
alpha = (u == 0) ? sqrt(1.0 / BLOCK_SIZE) : sqrt(2.0 / BLOCK_SIZE);
beta = (v == 0) ? sqrt(1.0 / BLOCK_SIZE) : sqrt(2.0 / BLOCK_SIZE);
sum += alpha * beta * block[u][v] *
cos(((2 * x + 1) * u * M_PI) / (2 * BLOCK_SIZE)) *
cos(((2 * y + 1) * v * M_PI) / (2 * BLOCK_SIZE));
}
}
tmp[x][y] = sum;
}
}
// Copy the result back to the original block
for (int i = 0; i < BLOCK_SIZE; i++) {
for (int j = 0; j < BLOCK_SIZE; j++) {
block[i][j] = tmp[i][j];
}
}
}
// Function to read a PNG image using libpng
void read_png_file(const char *filename, png_bytep **image, int *width, int *height) {
FILE *fp = fopen(filename, "rb");
if (!fp) {
perror("File opening failed");
return;
}
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png) abort();
png_infop info = png_create_info_struct(png);
if (!info) abort();
if (setjmp(png_jmpbuf(png))) abort();
png_init_io(png, fp);
png_read_info(png, info);
*width = png_get_image_width(png, info);
*height = png_get_image_height(png, info);
png_byte color_type = png_get_color_type(png, info);
png_byte bit_depth = png_get_bit_depth(png, info);
if (bit_depth == 16)
png_set_strip_16(png);
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb(png);
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_expand_gray_1_2_4_to_8(png);
if (png_get_valid(png, info, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(png);
if (color_type == PNG_COLOR_TYPE_RGB ||
color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_PALETTE)
png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
if (color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png);
png_read_update_info(png, info);
*image = (png_bytep*)malloc(sizeof(png_bytep) * (*height));
for (int y = 0; y < *height; y++) {
(*image)[y] = (png_byte*)malloc(png_get_rowbytes(png, info));
}
png_read_image(png, *image);
fclose(fp);
png_destroy_read_struct(&png, &info, NULL);
}
// Function to write a PNG image using libpng
void write_png_file(const char *filename, png_bytep *image, int width, int height) {
FILE *fp = fopen(filename, "wb");
if (!fp) {
perror("File opening failed");
return;
}
png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png) abort();
png_infop info = png_create_info_struct(png);
if (!info) abort();
if (setjmp(png_jmpbuf(png))) abort();
png_init_io(png, fp);
png_set_IHDR(
png,
info,
width, height,
8,
PNG_COLOR_TYPE_RGBA,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT
);
png_write_info(png, info);
png_write_image(png, image);
png_write_end(png, NULL);
fclose(fp);
png_destroy_write_struct(&png, &info);
}
// Function to embed a message into an image using DCT
void embed_message(png_bytep *image, int width, int height, const char *message) {
int msg_index = 0;
int msg_length = strlen(message) * 8;
double block[BLOCK_SIZE][BLOCK_SIZE];
for (int y = 0; y < height; y += BLOCK_SIZE) {
for (int x = 0; x < width; x += BLOCK_SIZE) {
// Load an 8x8 block
for (int i = 0; i < BLOCK_SIZE; i++) {
for (int j = 0; j < BLOCK_SIZE; j++) {
if (y + i < height && x + j < width) {
block[i][j] = (double)image[y + i][4 * (x + j)]; // Using red channel for simplicity
} else {
block[i][j] = 0.0;
}
}
}
// Perform DCT on the block
dct(block);
// Embed a bit of the message into the DCT coefficients
if (msg_index < msg_length) {
int bit = (message[msg_index / 8] >> (7 - (msg_index % 8))) & 1;
if (block[1][1] > 0) {
block[1][1] = bit ? fabs(block[1][1]) : -fabs(block[1][1]);
} else {
block[1][1] = bit ? -fabs(block[1][1]) : fabs(block[1][1]);
}
msg_index++;
}
// Perform inverse DCT on the block
inverse_dct(block);
// Store the modified block back into the image
for (int i = 0; i < BLOCK_SIZE; i++) {
for (int j = 0; j < BLOCK_SIZE; j++) {
if (y + i < height && x + j < width) {
image[y + i][4 * (x + j)] = (png_byte)fmin(fmax(block[i][j], 0.0), 255.0);
}
}
}
}
}
}
int main(intEditor is loading...
Leave a Comment