1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
| MaClasse::loadPNG(const char *filename) //intitialise le fichier et s'assure qu'il s'agit bien d'un PNG
{
bool cod_ret = false;
fp = fopen (filename, "rb");
if (!fp)
{
fprintf (stderr, "error: couldn't open \"%s\"!\n", filename);
return false;
}
// lecture des 8 premiers octets
fread (magic, 1, sizeof (magic), fp);
// comparaison des 8 octets avec la signature PNG
if (!png_check_sig (magic, sizeof (magic)))
{
fprintf (stderr, "error: \"%s\" is not a valid PNG image!\n",filename);
fclose (fp);
return false;
}
// SI le test est réussi, on est sûr qu'il s'agit d'un PNG
// création d'une structure png
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
{
fclose (fp);
return false;
}
// création d'une structure png info
png_infop info_ptr = png_create_info_struct (png_ptr);
if (!info_ptr)
{
fclose (fp);
png_destroy_read_struct (&png_ptr, NULL, NULL);
return false;
}
// initialise libpng pour utiliser la fonction fread() du C standard avec notre pointeur sur FILE
png_init_io (png_ptr, fp);
// signaler à libpng que l'on a déjà lu les 8 premiers octets du fichier
png_set_sig_bytes (png_ptr, sizeof (magic));
//On peut maintenant lire le fichier
// On commence par lire les infos du fichier
png_read_info (png_ptr, info_ptr);
// on récupère des informations de l'en-tête
_bit_depth = png_get_bit_depth (png_ptr, info_ptr);
_color_type = png_get_color_type (png_ptr, info_ptr);
//on met à jours les infos de la structure pour appliquer les transformations
png_read_update_info (png_ptr, info_ptr);
//charger les informations mises à jour dans les attributs de la classe
png_get_IHDR (png_ptr, info_ptr,
(png_uint_32*)&_largeur, // set _largeur
(png_uint_32*)&_longueur, // set _longueur
&_bit_depth, // set nb bits/pixel
&_color_type, // set type codage couleur
&_compress_method, // set type de compression(une seule definie pour l'instant
&_filter_method, // set méthode de filtrage (voir png.h)
&_interlace_method); // set méthode d'entrelacement
//On récupère la taille des données compressées
_compressed_buffer_size = png_get_compression_buffer_size( png_ptr);
//On recalcule le nombre de bits/pixel(en décompressé) à partir du nombre de bits/couleur et le type de couleur
setBitDepth(_color_type);
//On recalcule la taille en octets de l'image à partir du nombre d'octets par pixel
setTaille();
//
fpos_t positionAfterIDAT;
int result = fgetpos(fp,&positionAfterIDAT);
unsigned int lenIN = 0;
// Après récupération de l'entête, le pointeur de fichier est positionné juste après "IDAT"
if(result==0)
{
fpos_t positionBufferSize = positionAfterIDAT-8;
if(positionBufferSize>=0)
{
result = fsetpos(fp,&positionBufferSize);
BYTE sizeBuffer[4];
fread(&sizeBuffer,4,1,fp);
for(int i=0;i<4;i++)
{
lenIN += (DWORD)(pow(256,i)*sizeBuffer[3-i]);
}
result = fsetpos(fp,&positionAfterIDAT);
}
}
if(lenIN)
{
unsigned long length =_taille+1024; //nécessaire car le buffer de sortie est plus grand que la taille attendue
LPBYTE buff_IN = new BYTE[lenIN];
LPBYTE buff_OUT = new BYTE[length];
memset(buff_IN,0,lenIN);
memset(buff_OUT, 0, length);
fread (/*(void*)*/buff_IN, 1, lenIN, fp);
int coderr = uncompress(buff_OUT,&length,buff_IN,lenIN);
FILE *fw;
fw=fopen("essai.raw","wb");
fwrite(buff_OUT,length,1,fw);
fclose(fw);
if(coderr==Z_OK)
{
setBuffer(_taille,buff_OUT);
cod_ret = true;
}
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
delete[] buff_IN;
delete[] buff_OUT;
}
fclose(fp);
return cod_ret;
} |
Partager