Added background for transparent images
authorMyhailo Danylenko <isbear@ukrpost.net>
Fri, 06 Nov 2009 12:14:13 +0200
changeset 3 c920fcf835c7
parent 2 c1ee5fae2549
child 4 43eb96df8612
Added background for transparent images
avatar.c
avatar.rc
--- a/avatar.c	Fri Nov 06 01:12:12 2009 +0200
+++ b/avatar.c	Fri Nov 06 12:14:13 2009 +0200
@@ -65,9 +65,9 @@
 }
 
 // reads file and returns array of pointers to image rows in
-// grayscale 8-bit with alpha-channel format (i.e. two bytes per pixel)
+// grayscale 8-bit without alpha-channel format (i.e. one byte per pixel)
 // after use just do g_free of this pointer - all data are in one memory chunk
-static png_bytep *png_read_file (const char *file, int *rheight, int *rwidth)
+static png_bytep *png_read_file (const char *file, int *rheight, int *rwidth, png_uint_16 background)
 {
 	FILE        *fd       = fopen (file, "rb");
 	png_infop    info_ptr;
@@ -122,19 +122,26 @@
 		png_byte color_type = info_ptr->color_type;
 		png_byte bit_depth  = info_ptr->bit_depth;
 
-		// trying to convert anything to grayscale 8-bit color with alpha channel
-		if (color_type == PNG_COLOR_TYPE_PALETTE) // XXX
+		// trying to convert anything to grayscale 8-bit without alpha channel
+		if (color_type == PNG_COLOR_TYPE_PALETTE)
 			png_set_palette_to_rgb (png_ptr);
 		if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
 			png_set_expand_gray_1_2_4_to_8 (png_ptr);
-		if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_PALETTE /* ??? */) // XXX
-			png_set_add_alpha (png_ptr, 0xff, PNG_FILLER_AFTER);
 		if (bit_depth == 16)
 			png_set_strip_16 (png_ptr);
 		if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
 			png_set_tRNS_to_alpha (png_ptr);
-		if (color_type == PNG_COLOR_TYPE_PALETTE /* ??? */ || color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) // XXX
+		if (color_type & PNG_COLOR_MASK_COLOR)
 			png_set_rgb_to_gray_fixed (png_ptr, 1, -1, -1);
+		if (color_type & PNG_COLOR_MASK_ALPHA) {
+			png_color_16 my_background = {
+				.red   = background,
+				.green = background,
+				.blue  = background,
+				.gray  = background,
+			};
+			png_set_background (png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+		}
 
 		// renew information in info structure
 		png_read_update_info (png_ptr, info_ptr);
@@ -318,9 +325,8 @@
 		return NULL;
 
 	{ // fill aa image from png buffer with scaling
-		int       height, width;
-		const int bpp = 2;
-		int       y;
+		int height, width;
+		int y;
 
 		height = aa_imgheight (context);
 		width  = aa_imgwidth (context);
@@ -340,11 +346,11 @@
 
 				// just arithmetic average
 				for (cy = 0; cy < finalratioh; ++cy) {
-					png_bytep row = row_pointer[cy] + (startx + x * finalratiow) * bpp;
+					png_bytep row = row_pointer[cy] + startx + x * finalratiow;
 					int       cx;
 
 					for (cx = 0; cx < finalratiow; ++cx)
-						color += row[cx * bpp] * row[cx * bpp + 1] / 255;
+						color += row[cx];
 				}
 
 				color /= finalratioh * finalratiow;
@@ -570,7 +576,11 @@
 		}
 	}
 
-	row_pointers = png_read_file (file, &width, &height);
+	{
+		png_uint_16 background = settings_opt_get_int ("avatar_background");
+	
+		row_pointers = png_read_file (file, &width, &height, background);
+	}
 
 	if (!row_pointers) {
 		scr_LogPrint (LPRINT_LOGNORM, "avatar: Cannot decode png data from file %s.", file);
--- a/avatar.rc	Fri Nov 06 01:12:12 2009 +0200
+++ b/avatar.rc	Fri Nov 06 12:14:13 2009 +0200
@@ -20,6 +20,12 @@
 set avatar_max_width  = 110
 set avatar_max_height = 40
 
+# Background color to use for transparent images.
+# In fact in range 0..65535, but looks like actually matter only
+# first 9 bits (what does 9th bit I do not know, but it definitely
+# changes resulting image a bit)
+set avatar_background = 255
+
 load pep
 load avatar