avatar.c
changeset 3 c920fcf835c7
parent 1 285017b7713c
child 6 a0231d43ae53
equal deleted inserted replaced
2:c1ee5fae2549 3:c920fcf835c7
    63 {
    63 {
    64 	g_free (chunk);
    64 	g_free (chunk);
    65 }
    65 }
    66 
    66 
    67 // reads file and returns array of pointers to image rows in
    67 // reads file and returns array of pointers to image rows in
    68 // grayscale 8-bit with alpha-channel format (i.e. two bytes per pixel)
    68 // grayscale 8-bit without alpha-channel format (i.e. one byte per pixel)
    69 // after use just do g_free of this pointer - all data are in one memory chunk
    69 // after use just do g_free of this pointer - all data are in one memory chunk
    70 static png_bytep *png_read_file (const char *file, int *rheight, int *rwidth)
    70 static png_bytep *png_read_file (const char *file, int *rheight, int *rwidth, png_uint_16 background)
    71 {
    71 {
    72 	FILE        *fd       = fopen (file, "rb");
    72 	FILE        *fd       = fopen (file, "rb");
    73 	png_infop    info_ptr;
    73 	png_infop    info_ptr;
    74 	png_structp  png_ptr;
    74 	png_structp  png_ptr;
    75 	int          rowbytes;
    75 	int          rowbytes;
   120 
   120 
   121 	{ // set up transformations
   121 	{ // set up transformations
   122 		png_byte color_type = info_ptr->color_type;
   122 		png_byte color_type = info_ptr->color_type;
   123 		png_byte bit_depth  = info_ptr->bit_depth;
   123 		png_byte bit_depth  = info_ptr->bit_depth;
   124 
   124 
   125 		// trying to convert anything to grayscale 8-bit color with alpha channel
   125 		// trying to convert anything to grayscale 8-bit without alpha channel
   126 		if (color_type == PNG_COLOR_TYPE_PALETTE) // XXX
   126 		if (color_type == PNG_COLOR_TYPE_PALETTE)
   127 			png_set_palette_to_rgb (png_ptr);
   127 			png_set_palette_to_rgb (png_ptr);
   128 		if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
   128 		if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
   129 			png_set_expand_gray_1_2_4_to_8 (png_ptr);
   129 			png_set_expand_gray_1_2_4_to_8 (png_ptr);
   130 		if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_PALETTE /* ??? */) // XXX
       
   131 			png_set_add_alpha (png_ptr, 0xff, PNG_FILLER_AFTER);
       
   132 		if (bit_depth == 16)
   130 		if (bit_depth == 16)
   133 			png_set_strip_16 (png_ptr);
   131 			png_set_strip_16 (png_ptr);
   134 		if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
   132 		if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
   135 			png_set_tRNS_to_alpha (png_ptr);
   133 			png_set_tRNS_to_alpha (png_ptr);
   136 		if (color_type == PNG_COLOR_TYPE_PALETTE /* ??? */ || color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) // XXX
   134 		if (color_type & PNG_COLOR_MASK_COLOR)
   137 			png_set_rgb_to_gray_fixed (png_ptr, 1, -1, -1);
   135 			png_set_rgb_to_gray_fixed (png_ptr, 1, -1, -1);
       
   136 		if (color_type & PNG_COLOR_MASK_ALPHA) {
       
   137 			png_color_16 my_background = {
       
   138 				.red   = background,
       
   139 				.green = background,
       
   140 				.blue  = background,
       
   141 				.gray  = background,
       
   142 			};
       
   143 			png_set_background (png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
       
   144 		}
   138 
   145 
   139 		// renew information in info structure
   146 		// renew information in info structure
   140 		png_read_update_info (png_ptr, info_ptr);
   147 		png_read_update_info (png_ptr, info_ptr);
   141 	}
   148 	}
   142 
   149 
   316 
   323 
   317 	if (context == NULL)
   324 	if (context == NULL)
   318 		return NULL;
   325 		return NULL;
   319 
   326 
   320 	{ // fill aa image from png buffer with scaling
   327 	{ // fill aa image from png buffer with scaling
   321 		int       height, width;
   328 		int height, width;
   322 		const int bpp = 2;
   329 		int y;
   323 		int       y;
       
   324 
   330 
   325 		height = aa_imgheight (context);
   331 		height = aa_imgheight (context);
   326 		width  = aa_imgwidth (context);
   332 		width  = aa_imgwidth (context);
   327 		
   333 		
   328 		if (height > finalh)
   334 		if (height > finalh)
   338 				unsigned int  color = 0;
   344 				unsigned int  color = 0;
   339 				unsigned int  cy;
   345 				unsigned int  cy;
   340 
   346 
   341 				// just arithmetic average
   347 				// just arithmetic average
   342 				for (cy = 0; cy < finalratioh; ++cy) {
   348 				for (cy = 0; cy < finalratioh; ++cy) {
   343 					png_bytep row = row_pointer[cy] + (startx + x * finalratiow) * bpp;
   349 					png_bytep row = row_pointer[cy] + startx + x * finalratiow;
   344 					int       cx;
   350 					int       cx;
   345 
   351 
   346 					for (cx = 0; cx < finalratiow; ++cx)
   352 					for (cx = 0; cx < finalratiow; ++cx)
   347 						color += row[cx * bpp] * row[cx * bpp + 1] / 255;
   353 						color += row[cx];
   348 				}
   354 				}
   349 
   355 
   350 				color /= finalratioh * finalratiow;
   356 				color /= finalratioh * finalratiow;
   351 
   357 
   352 				aa_putpixel (context, x, y, color);
   358 				aa_putpixel (context, x, y, color);
   568 
   574 
   569 			return TRUE;
   575 			return TRUE;
   570 		}
   576 		}
   571 	}
   577 	}
   572 
   578 
   573 	row_pointers = png_read_file (file, &width, &height);
   579 	{
       
   580 		png_uint_16 background = settings_opt_get_int ("avatar_background");
       
   581 	
       
   582 		row_pointers = png_read_file (file, &width, &height, background);
       
   583 	}
   574 
   584 
   575 	if (!row_pointers) {
   585 	if (!row_pointers) {
   576 		scr_LogPrint (LPRINT_LOGNORM, "avatar: Cannot decode png data from file %s.", file);
   586 		scr_LogPrint (LPRINT_LOGNORM, "avatar: Cannot decode png data from file %s.", file);
   577 		return FALSE;
   587 		return FALSE;
   578 	}
   588 	}