Ejemplo n.º 1
0
void
image_upsize(image_s * pdest, image_s * psrc, int32_t width, int32_t height)
{
	int32_t vx, vy;
#if !defined __i386__ && !defined __x86_64__
	int32_t rx, ry;
	pix vcol;

	if((pdest == NULL) || (psrc == NULL))
		return;

	for(vy = 0; vy < height; vy++)
	{
		for(vx = 0; vx < width; vx++)
		{
			rx = ((vx * psrc->width) / width);
			ry = ((vy * psrc->height) / height);
			vcol = get_pix(psrc, rx, ry);
#else
	pix   vcol,vcol1,vcol2,vcol3,vcol4;
	float rx,ry;
	float width_scale, height_scale;
	float x_dist, y_dist;

	width_scale  = (float)psrc->width  / (float)width;
	height_scale = (float)psrc->height / (float)height;

	for(vy = 0;vy < height; vy++)
	{
		for(vx = 0;vx < width; vx++)
		{
			rx = vx * width_scale;
			ry = vy * height_scale;
			vcol1 = get_pix(psrc, (int32_t)rx, (int32_t)ry);
			vcol2 = get_pix(psrc, ((int32_t)rx)+1, (int32_t)ry);
			vcol3 = get_pix(psrc, (int32_t)rx, ((int32_t)ry)+1);
			vcol4 = get_pix(psrc, ((int32_t)rx)+1, ((int32_t)ry)+1);

			x_dist = rx - ((float)((int32_t)rx));
			y_dist = ry - ((float)((int32_t)ry));
			vcol = COL_FULL( (uint8_t)((COL_RED(vcol1)*(1.0-x_dist)
			                  + COL_RED(vcol2)*(x_dist))*(1.0-y_dist)
			                  + (COL_RED(vcol3)*(1.0-x_dist)
			                  + COL_RED(vcol4)*(x_dist))*(y_dist)),
			                 (uint8_t)((COL_GREEN(vcol1)*(1.0-x_dist)
			                  + COL_GREEN(vcol2)*(x_dist))*(1.0-y_dist)
			                  + (COL_GREEN(vcol3)*(1.0-x_dist)
			                  + COL_GREEN(vcol4)*(x_dist))*(y_dist)),
			                 (uint8_t)((COL_BLUE(vcol1)*(1.0-x_dist)
			                  + COL_BLUE(vcol2)*(x_dist))*(1.0-y_dist)
			                  + (COL_BLUE(vcol3)*(1.0-x_dist)
			                  + COL_BLUE(vcol4)*(x_dist))*(y_dist)),
			                 (uint8_t)((COL_ALPHA(vcol1)*(1.0-x_dist)
			                  + COL_ALPHA(vcol2)*(x_dist))*(1.0-y_dist)
			                  + (COL_ALPHA(vcol3)*(1.0-x_dist)
			                  + COL_ALPHA(vcol4)*(x_dist))*(y_dist))
			               );
#endif
			put_pix_alpha_replace(pdest, vx, vy, vcol);
		}
	}
}

void
image_downsize(image_s * pdest, image_s * psrc, int32_t width, int32_t height)
{
	int32_t vx, vy;
	pix vcol;
	int32_t i, j;
#if !defined __i386__ && !defined __x86_64__
	int32_t rx, ry, rx_next, ry_next;
	int red, green, blue, alpha;
	int factor;

	if((pdest == NULL) || (psrc == NULL))
		return;

	for(vy = 0; vy < height; vy++)
	{
		for(vx = 0; vx < width; vx++)
		{

			rx = ((vx * psrc->width) / width);
			ry = ((vy * psrc->height) / height);

			red = green = blue = alpha = 0;

			rx_next = rx + (psrc->width / width);
			ry_next = ry + (psrc->width / width);
			factor = 0;

			for( j = rx; j < rx_next; j++)
			{
				for( i = ry; i < ry_next; i++)
				{
					factor += 1;
					vcol = get_pix(psrc, j, i);

					red   += COL_RED(vcol);
					green += COL_GREEN(vcol);
					blue  += COL_BLUE(vcol);
					alpha += COL_ALPHA(vcol);
				}
			}

			red   /= factor;
			green /= factor;
			blue  /= factor;
			alpha /= factor;

			/* on sature les valeurs */
			red   = (red   > 255) ? 255 : ((red   < 0) ? 0 : red  );
			green = (green > 255) ? 255 : ((green < 0) ? 0 : green);
			blue  = (blue  > 255) ? 255 : ((blue  < 0) ? 0 : blue );
			alpha = (alpha > 255) ? 255 : ((alpha < 0) ? 0 : alpha);
#else
	float rx,ry;
	float width_scale, height_scale;
	float red, green, blue, alpha;
	int32_t half_square_width, half_square_height;
	float round_width, round_height;

	if( (pdest == NULL) || (psrc == NULL) )
		return;

	width_scale  = (float)psrc->width  / (float)width;
	height_scale = (float)psrc->height / (float)height;

	half_square_width  = (int32_t)(width_scale  / 2.0);
	half_square_height = (int32_t)(height_scale / 2.0);
	round_width  = (width_scale  / 2.0) - (float)half_square_width;
	round_height = (height_scale / 2.0) - (float)half_square_height;
	if(round_width  > 0.0)
		half_square_width++;
	else
		round_width = 1.0;
	if(round_height > 0.0)
		half_square_height++;
	else
		round_height = 1.0;

	for(vy = 0;vy < height; vy++)  
	{
		for(vx = 0;vx < width; vx++)
		{
			rx = vx * width_scale;
			ry = vy * height_scale;
			vcol = get_pix(psrc, (int32_t)rx, (int32_t)ry);

			red = green = blue = alpha = 0.0;

			for(j=0;j<half_square_height<<1;j++)
			{
				for(i=0;i<half_square_width<<1;i++)
				{
					vcol = get_pix(psrc, ((int32_t)rx)-half_square_width+i,
					                     ((int32_t)ry)-half_square_height+j);
          
					if(((j == 0) || (j == (half_square_height<<1)-1)) && 
					   ((i == 0) || (i == (half_square_width<<1)-1)))
					{
						red   += round_width*round_height*(float)COL_RED  (vcol);
						green += round_width*round_height*(float)COL_GREEN(vcol);
						blue  += round_width*round_height*(float)COL_BLUE (vcol);
						alpha += round_width*round_height*(float)COL_ALPHA(vcol);
					}
					else if((j == 0) || (j == (half_square_height<<1)-1))
					{
						red   += round_height*(float)COL_RED  (vcol);
						green += round_height*(float)COL_GREEN(vcol);
						blue  += round_height*(float)COL_BLUE (vcol);
						alpha += round_height*(float)COL_ALPHA(vcol);
					}
					else if((i == 0) || (i == (half_square_width<<1)-1))
					{
						red   += round_width*(float)COL_RED  (vcol);
						green += round_width*(float)COL_GREEN(vcol);
						blue  += round_width*(float)COL_BLUE (vcol);
						alpha += round_width*(float)COL_ALPHA(vcol);
					}
					else
					{
						red   += (float)COL_RED  (vcol);
						green += (float)COL_GREEN(vcol);
						blue  += (float)COL_BLUE (vcol);
						alpha += (float)COL_ALPHA(vcol);
					}
				}
			}
      
			red   /= width_scale*height_scale;
			green /= width_scale*height_scale;
			blue  /= width_scale*height_scale;
			alpha /= width_scale*height_scale;
      
			/* on sature les valeurs */
			red   = (red   > 255.0)? 255.0 : ((red   < 0.0)? 0.0:red  );
			green = (green > 255.0)? 255.0 : ((green < 0.0)? 0.0:green);
			blue  = (blue  > 255.0)? 255.0 : ((blue  < 0.0)? 0.0:blue );
			alpha = (alpha > 255.0)? 255.0 : ((alpha < 0.0)? 0.0:alpha);
#endif
			put_pix_alpha_replace(pdest, vx, vy,
					      COL_FULL((uint8_t)red, (uint8_t)green, (uint8_t)blue, (uint8_t)alpha));
		}
	}
}

image_s *
image_resize(image_s * src_image, int32_t width, int32_t height)
{
	image_s * dst_image;

	dst_image = image_new(width, height);
	if( !dst_image )
		return NULL;
	if( (src_image->width < width) || (src_image->height < height) )
		image_upsize(dst_image, src_image, width, height);
	else
		image_downsize(dst_image, src_image, width, height);

	return dst_image;
}


unsigned char *
image_save_to_jpeg_buf(image_s * pimage, int * size)
{
	struct jpeg_compress_struct cinfo;
	struct jpeg_error_mgr jerr;
	JSAMPROW row_pointer[1];
	int row_stride;
	char *data;
	int i, x;
	struct my_dst_mgr dst;

	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_compress(&cinfo);
	jpeg_memory_dest(&cinfo, &dst);
	cinfo.image_width = pimage->width;
	cinfo.image_height = pimage->height;
	cinfo.input_components = 3;
	cinfo.in_color_space = JCS_RGB;
	jpeg_set_defaults(&cinfo);
	jpeg_set_quality(&cinfo, JPEG_QUALITY, TRUE);
	jpeg_start_compress(&cinfo, TRUE);
	row_stride = cinfo.image_width * 3;
	if((data = malloc(row_stride)) == NULL)
	{
		DPRINTF(E_WARN, L_METADATA, "malloc failed\n");
		if (dst.buf)
			free(dst.buf);
		jpeg_destroy_compress(&cinfo);
		return NULL;
	}
	i = 0;
	while(cinfo.next_scanline < cinfo.image_height)
	{
		for(x = 0; x < pimage->width; x++)
		{
			data[x * 3]     = COL_RED(pimage->buf[i]);
			data[x * 3 + 1] = COL_GREEN(pimage->buf[i]);
			data[x * 3 + 2] = COL_BLUE(pimage->buf[i]);
			i++;
		}
		row_pointer[0] = (unsigned char *)data;
		jpeg_write_scanlines(&cinfo, row_pointer, 1);
	}
	jpeg_finish_compress(&cinfo);
	*size = dst.used;
	free(data);
	jpeg_destroy_compress(&cinfo);

	return dst.buf;
}

char *
image_save_to_jpeg_file(image_s * pimage, char * path)
{
	int nwritten, size = 0;
	unsigned char * buf;
	FILE * dst_file;

	buf = image_save_to_jpeg_buf(pimage, &size);
	if( !buf )
		return NULL;
 	dst_file = fopen(path, "w");
	if( !dst_file )
	{
		free(buf);
		return NULL;
	}
	nwritten = fwrite(buf, 1, size, dst_file);
	fclose(dst_file);
	free(buf);

	return (nwritten == size) ? path : NULL;
}
Ejemplo n.º 2
0
static void
set_user_icon_from_png (char *path, uint32_t bgcolor)
{
	int j, alpha;
	image_s *img = image_new_from_png (path, 1, NULL, 0, 1, 0, &alpha);
	image_s *img_sm, *img_lrg;
	struct icon_struct newicons;
	double n, scale_lrg, scale_sm;

	if (img == (image_s *)NULL)
	{
		DPRINTF (E_WARN, L_GENERAL,
				"Unable to load icon file \"%s\".\n", path);
		return;
	}

	n = (img->height > img->width) ? img->height : img->width;
	scale_lrg = 120.0 / n;
	scale_sm = 48.0 / n;

	if ((img_lrg = image_resize (img,
					xround (img->width*scale_lrg),
					xround(img->height*scale_lrg))) == (image_s *)NULL)
	{
		DPRINTF (E_ERROR, L_GENERAL,
				"Failed to rescale large icon image (%s).\n", path);
		image_free (img);
		return;
	}

	if ((img_sm = image_resize (img,
					xround(img->width*scale_sm),
					xround(img->height*scale_sm))) == (image_s *)NULL)
	{
		DPRINTF (E_ERROR, L_GENERAL,
				"Failed to rescale small icon image (%s).\n", path);
		image_free (img);
		image_free (img_lrg);
		return;
	}

	image_free (img);

	for (j = ICON_FIRST; j <= ICON_LAST; j++)
		newicons.dynamic[j] = 1;

	if ((newicons.size[ICON_PNG_LRG] = image_save_to_png (img_lrg, NULL,
			&newicons.icon[ICON_PNG_LRG], alpha, 9)) < 0)
	{
		DPRINTF (E_ERROR, L_GENERAL,
				"Failed to create large PNG icon (%s).\n", path);
		newicons.icon[ICON_PNG_LRG] = icons.icon[ICON_PNG_LRG];
		newicons.size[ICON_PNG_LRG] = icons.size[ICON_PNG_LRG];
		newicons.dynamic[ICON_PNG_LRG] = icons.dynamic[ICON_PNG_LRG];
	}

	if ((newicons.size[ICON_PNG_SM] = image_save_to_png (img_sm, NULL,
			&newicons.icon[ICON_PNG_SM], alpha, 9)) < 0)
	{
		DPRINTF (E_ERROR, L_GENERAL,
				"Failed to create small PNG icon (%s).\n", path);
		newicons.icon[ICON_PNG_SM] = icons.icon[ICON_PNG_SM];
		newicons.size[ICON_PNG_SM] = icons.size[ICON_PNG_SM];
		newicons.dynamic[ICON_PNG_SM] = icons.dynamic[ICON_PNG_SM];
	}

	if (alpha)
	{
		image_bgcolor_composite (img_lrg, bgcolor, -1);
		image_bgcolor_composite (img_sm, bgcolor, -1);
	}

	if (!(newicons.icon[ICON_JPEG_LRG] = image_save_to_jpeg_buf (img_lrg,
			&newicons.size[ICON_JPEG_LRG])))
	{
		DPRINTF (E_ERROR, L_GENERAL,
				"Failed to create large JPEG icon (%s).\n", path);
		newicons.icon[ICON_JPEG_LRG] = icons.icon[ICON_JPEG_LRG];
		newicons.size[ICON_JPEG_LRG] = icons.size[ICON_JPEG_LRG];
		newicons.dynamic[ICON_JPEG_LRG] = icons.dynamic[ICON_JPEG_LRG];
	}

	if (!(newicons.icon[ICON_JPEG_SM] = image_save_to_jpeg_buf (img_sm,
			&newicons.size[ICON_JPEG_SM])))
	{
		DPRINTF (E_ERROR, L_GENERAL,
				"Failed to create small JPEG icon (%s).\n", path);
		newicons.icon[ICON_JPEG_SM] = icons.icon[ICON_JPEG_SM];
		newicons.size[ICON_JPEG_SM] = icons.size[ICON_JPEG_SM];
		newicons.dynamic[ICON_JPEG_SM] = icons.dynamic[ICON_JPEG_SM];
	}

	image_free (img_sm);
	image_free (img_lrg);
	destroy_icons (&icons);
	icons = newicons;
}