Skini ovaj fajl
http://www.matf.bg.ac.yu/r4rg/vjezbe/texture.tar.gz tu imas dva fajla image.c i image.h gde mozes da vidis kako se radi sa libpng bibliotekom direktno. A evo i ovako code odatle izvucen.
Code:
/* image.h */
#ifndef image_h
#define image_h
/* Struktura podataka koja predstavlja sliku. */
typedef struct Image {
int width, height; /* Sirina i visina slike. */
char *pixels; /* Polje sa pikselima slike. Svaki piksel je
* predstavljen sa R, G, B i A komponentama
* duzine jednog bajta. */
} Image;
/*
* Funkcija image_init() kreira i incijalizuje strukturu podataka koja
* predstavlja sliku.
*/
Image *image_init(int width, int height);
/* Funkcija image_done() unistava strukturu podataka koja predstavlja sliku. */
void image_done(Image * image);
/*
* Funkcija image_read() ucitava sliku iz fajla sa datim imenom. Fajl mora
* biti u PNG formatu i to sa 4 komponente po pikselu.
*/
void image_read(Image * image, char *filename);
/*
* Funkcija image_write() upisuje sliku u fajl sa datim imenom. Upis se vrsi
* u PNG formatu i to sa 4 komponente po pikselu.
*/
void image_write(Image * image, char *filename);
#endif
i sama implementacija
Code:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <png.h>
#include "image.h"
Image *
image_init(int width, int height)
{
Image *image; /* Pokazivac na strukturu koja predstavlja
* sliku. */
/* Provjerava se validnost date sirine i visine slike. */
assert(width >= 0 && height >= 0);
/* Alocira se memorija za sliku. */
image = (Image *) malloc(sizeof(Image));
assert(image != NULL);
/*
* Postavljaju se sirina i visina slike i eventualno se alocira
* memorija za piksele slike.
*/
image->width = width;
image->height = height;
if (width == 0 && height == 0)
image->pixels = NULL;
else {
image->pixels = (char *)malloc(4 * width * height * sizeof(char));
assert(image->pixels != NULL);
}
return image;
}
void
image_done(Image * image)
{
/*
* Oslobadja se memorija koju su zauzimali pikseli slike, a potom i
* memorija koju je zauzimala struktura koja opisuje sliku.
*/
free(image->pixels);
free(image);
}
void
image_read(Image * image, char *filename)
{
FILE *file; /* Fajl u kome se nalazi slika. */
png_structp png_ptr;/* Struktura koja opisuje proces citanja
* slike iz fajla. */
png_infop info_ptr; /* Struktura sa informacijama o
* slici. */
png_uint_32 width, height; /* Sirina i visina slike. */
int bit_depth, color_type; /* Broj bita po komponenti
* piksela i nacin na koji su
* predstavljeni pikseli. */
png_bytep *row_pointers; /* Lista pokazivaca na redove piksela
* slike. */
int i; /* Brojac u petljama. */
/*
* Oslobadja se memorija koju su eventualno ranije zauzimali pikseli
* slike.
*/
free(image->pixels);
image->pixels = NULL;
/* Otvara se fajl za citanje slike. */
file = fopen(filename, "rb");
assert(file != NULL);
/* Kreira se objekat za citanje slike. */
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
assert(png_ptr != NULL);
/* Kreira se objekat za informacije o slici. */
info_ptr = png_create_info_struct(png_ptr);
assert(info_ptr != NULL);
/* Podesava se obrada gresaka. */
assert(setjmp(png_jmpbuf(png_ptr)) == 0);
/* Specificira se ulazni stream za citanje slike. */
png_init_io(png_ptr, file);
/*
* Ucitava se zaglavlje slike i provjerava da li je u pitanju slika
* sa 8 bita po komponentni, kao i da je slika u RGBA formatu.
*/
png_read_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
NULL, NULL, NULL);
assert(bit_depth == 8);
assert(color_type == PNG_COLOR_TYPE_RGB_ALPHA);
/*
* Pamte se sirina i visina slike i alocira se memorija za ucitavanje
* piksela slike.
*/
image->width = width;
image->height = height;
image->pixels = (char *)malloc(4 * width * height * sizeof(char));
assert(image->pixels != NULL);
/*
* Alocira se memorija i popunjava se lista pokazivaca na lokacije na
* koje ce biti smjesteni redovi slike. Tom prilikom se obezbjedjuje
* da slika bude upisana u memoriju pocev od donjeg reda.
*/
row_pointers = png_malloc(png_ptr, height * sizeof(png_bytep));
assert(row_pointers != NULL);
for (i = 0; i < height; i++)
row_pointers[i] = image->pixels + 4 * (height - 1 - i) * width;
png_set_rows(png_ptr, info_ptr, row_pointers);
/* Ucitava se slika. */
png_read_image(png_ptr, row_pointers);
/* Oslobadja se lista pokazivaca na redove slike. */
png_free(png_ptr, row_pointers);
/*
* Unistavaju se objekat za citanje slike i objekat sa informacijama
* o slici.
*/
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
/* Zatvara se fajl iz koga je citana slika. */
fclose(file);
}
void
image_write(Image * image, char *filename)
{
FILE *file; /* Fajl u koji ce biti upisana slika. */
png_structp png_ptr;/* Struktura koja opisuje proces upisa slike
* u fajl. */
png_infop info_ptr; /* Struktura sa informacijama o
* slici. */
png_bytep *row_pointers; /* Lista pokazivaca na redove piksela
* slike. */
int i; /* Brojac u petljama. */
/* Otvara se fajl u koji ce biti upisana slika. */
file = fopen(filename, "wb");
assert(file != NULL);
/* Kreira se objekat za ispis slike. */
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
assert(png_ptr != NULL);
/* Kreira se objekat za informacije o slici. */
info_ptr = png_create_info_struct(png_ptr);
assert(info_ptr != NULL);
/* Podesava se obrada gresaka. */
assert(setjmp(png_jmpbuf(png_ptr)) == 0);
/* Specificira se izlazni stream za ispis slike. */
png_init_io(png_ptr, file);
/* Postavljaju se podaci u zaglavlje slike. */
png_set_IHDR(png_ptr, info_ptr, image->width, image->height, 8,
PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
/*
* Alocira se memorija i popunjava se lista pokazivaca na lokacije na
* kojima se nalaze redovi slike. Tom prilikom se obezbjedjuje da
* slika bude upisana u fajl pocev od gornjeg reda.
*/
row_pointers = png_malloc(png_ptr, image->height * sizeof(png_bytep));
assert(row_pointers != NULL);
for (i = 0; i < image->height; i++)
row_pointers[i] =
image->pixels + 4 * (image->height - 1 - i) * image->width;
png_set_rows(png_ptr, info_ptr, row_pointers);
/* Upisuje se slika u fajl. */
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
/* Oslobadja se lista pokazivaca na redove slike. */
png_free(png_ptr, row_pointers);
/*
* Unistavaju se objekat za ispisivanje slike i objekat sa
* informacijama o slici.
*/
png_destroy_write_struct(&png_ptr, &info_ptr);
/* Zatvara se fajl u koga je upisana slika. */
fclose(file);
}