Files
AK2-stuff/lab5-v3/png.c
T

148 lines
2.6 KiB
C

#include <png.h>
#include <stdio.h>
#include <stdlib.h>
#define ERROR \
fprintf (stderr, "ERROR at %s:%d.\n", __FILE__, __LINE__) ; \
return -1 ;
#define HEADER_SIZE (1)
void filter(unsigned char * M, unsigned char * W, int width, int height);
unsigned long long timestamp();
int main (int argc, char ** argv)
{
if (2 != argc)
{
printf ("\nUsage:\n\n%s file_name.png\n\n", argv[0]) ;
return 0 ;
}
const char * file_name = argv [1] ;
unsigned char header [HEADER_SIZE] ;
FILE *fp = fopen (file_name, "rb");
if (NULL == fp)
{
fprintf (stderr, "Can not open file \"%s\".\n", file_name) ;
ERROR
}
if (fread (header, 1, HEADER_SIZE, fp) != HEADER_SIZE)
{
ERROR
}
if (0 != png_sig_cmp (header, 0, HEADER_SIZE))
{
ERROR
}
png_structp png_ptr =
png_create_read_struct
(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
if (NULL == png_ptr)
{
ERROR
}
png_infop info_ptr = png_create_info_struct (png_ptr);
if (NULL == info_ptr)
{
png_destroy_read_struct (& png_ptr, NULL, NULL);
ERROR
}
if (setjmp (png_jmpbuf (png_ptr)))
{
png_destroy_read_struct (& png_ptr, & info_ptr, NULL);
ERROR
}
png_init_io (png_ptr, fp);
png_set_sig_bytes (png_ptr, HEADER_SIZE);
png_read_info (png_ptr, info_ptr);
png_uint_32 width, height;
int bit_depth, color_type;
png_get_IHDR
(
png_ptr, info_ptr,
& width, & height, & bit_depth, & color_type,
NULL, NULL, NULL
);
if (8 != bit_depth)
{
ERROR
}
if (0 != color_type)
{
ERROR
}
size_t size = width ;
size *= height ;
unsigned char * M = malloc (size) ;
png_bytep ps [height] ;
ps [0] = M ;
for (unsigned i = 1 ; i < height ; i++)
{
ps [i] = ps [i-1] + width ;
}
png_set_rows (png_ptr, info_ptr, ps);
png_read_image (png_ptr, ps) ;
printf
(
"Image %s loaded:\n"
"\twidth = %lu\n"
"\theight = %lu\n"
"\tbit_depth = %u\n"
"\tcolor_type = %u\n"
, file_name, width, height, bit_depth, color_type
) ;
unsigned char * W = malloc (size) ;
unsigned long long tstart = timestamp();
filter (M, W, width, height) ;
unsigned long long tstop = timestamp();
printf("\nTSC cycles: %llu\n", tstop-tstart);
png_structp write_png_ptr =
png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (NULL == write_png_ptr)
{
ERROR
}
for (unsigned i = 0 ; i < height ; i++)
{
ps [i] += W - M ;
}
png_set_rows (write_png_ptr, info_ptr, ps);
FILE *fwp = fopen ("out.png", "wb");
if (NULL == fwp)
{
ERROR
}
png_init_io (write_png_ptr, fwp);
png_write_png (write_png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
fclose (fwp);
return 0;
}