Je la refais vu que je me suis bien planté dans mon copier coller du code source, désolé...
Bonjour à tous,
A l'aide de la libpng je cherche à écrire des images au format PNG en niveau de gris sur 16 bits (pas de transparence).
1/ Je voudrais tout d'abord savoir si cela est bien supporté par la librairie (il me semble que oui)
2/ Voici le code que j'utilise :
[code]
int ecrirePNG(const char *nomFichier, short tab[DIM_Y][DIM_X])
{
/* --- declarations --- */
int x, y, n = 0;
FILE *fic = NULL;
png_structp png_ptr;
png_infop info_ptr;
png_time modtime;
png_text text[4];
png_byte buffer[2*DIM_X];
double LSB;
short min, max;
int i,j;
/* --- fin declarations --- */
memset(buffer,0,sizeof(buffer));
fic = fopen(nomFichier,"wb");
if (fic == NULL)
{
return (EXIT_FAILURE);
}
/* on cree une png read struct */
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(!png_ptr)
{
fclose(fic);
return(EXIT_FAILURE);
}
/* on cree une png info struct */
info_ptr = png_create_info_struct(png_ptr);
if(!info_ptr)
{
fclose(fic);
png_destroy_write_struct(&png_ptr, NULL);
return(EXIT_FAILURE);
}
/* on ecrit dans un fichier */
png_init_io(png_ptr,fic);
/* type de compression */
png_set_compression_level(png_ptr, Z_NO_COMPRESSION); /* Z_BEST_SPEED / Z_BEST_COMPRESSION / Z_NO_COMPRESSION */
/* infos de l'image */
png_set_IHDR( png_ptr,
info_ptr,
DIM_X,
DIM_Y,
16,
PNG_COLOR_TYPE_GRAY,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
png_write_info(png_ptr, info_ptr);
/* ecrit l'image ligne par ligne */
for (y = 0; y < DIM_Y; y++)
{
n = 0;
for (x = 0; x < DIM_X; x++)
{
/*buffer[n] = round( ((double)tab[y][x] - min) / LSB );
buffer[n+1] = 0;*/
buffer[n] = tab[y][x];
buffer[n+1] = tab[y][x] >> 8; /* non pris en compte */
n += 2;
}
png_write_row(png_ptr, buffer);
}
/* fin ecriture PNG */
png_write_end(png_ptr, info_ptr);
/* liberation */
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(fic);
return (EXIT_SUCCESS);
}
[/code]
Quelques explications sur le code :
- la fonction "png_write_row" ne prend en second argument que des unsigned char (8 bits) donc il me semble que
le principe pour écrire des unsigned short (16 bits) c'est de passer l'octet LSB du mot 16 bits puis l'octet MSB (cela a pour conséquence de doubler la taille du buffer)
- le code en commentaire dans la double boucle me permet de passer mes images sur 8 bits et dans ce cas c'est OK
(car le MSB est à 0) donc le principe du § précédent me paraît cohérent.
Le problème c'est que le MSB ne semble pas pris en compte, du coup je n'ai pas les résultats voulu.
Toute aide sera la bienvenue, merci d'avance