Untitled
unknown
plain_text
a month ago
6.6 kB
2
Indexable
Never
#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(int
Leave a Comment