Ejemplo n.º 1
0
// Strip alpha channel if there are no actual transparent pixels, etc.
void iw_optimize_image(struct iw_context *ctx)
{
	struct iw_opt_ctx *optctx;

	optctx = &ctx->optctx;

	memset(optctx,0,sizeof(struct iw_opt_ctx));
	optctx->width = ctx->img2.width;
	optctx->height = ctx->img2.height;
	optctx->imgtype = ctx->img2.imgtype;
	optctx->bit_depth = ctx->img2.bit_depth;
	optctx->bpr = ctx->img2.bpr;
	optctx->pixelsptr = ctx->img2.pixels;
	optctx->has_transparency=0;
	optctx->has_partial_transparency=0;
	optctx->has_16bit_precision=0;
	optctx->has_color=0;

	if(ctx->img2.sampletype!=IW_SAMPLETYPE_UINT) {
		return;
	}

	make_transparent_pixels_black(ctx,&ctx->img2);

	if(!iw_opt_scanpixels(ctx,optctx)) {
		goto noscan;
	}

	if(optctx->imgtype==IW_IMGTYPE_RGBA && optctx->bit_depth==16 && !optctx->has_16bit_precision) {
		iw_opt_16_to_8(ctx,optctx,4);
	}

	if(optctx->imgtype==IW_IMGTYPE_RGB && optctx->bit_depth==16 && !optctx->has_16bit_precision) {
		iw_opt_16_to_8(ctx,optctx,3);
	}

	if(optctx->imgtype==IW_IMGTYPE_GRAYA && optctx->bit_depth==16 && !optctx->has_16bit_precision) {
		iw_opt_16_to_8(ctx,optctx,2);
	}

	if(optctx->imgtype==IW_IMGTYPE_GRAY && optctx->bit_depth==16 && !optctx->has_16bit_precision) {
		iw_opt_16_to_8(ctx,optctx,1);
	}

	if(optctx->imgtype==IW_IMGTYPE_RGBA && optctx->bit_depth==8 && !optctx->has_transparency && ctx->opt_strip_alpha) {
		iw_opt_copychannels_8(ctx,optctx,IW_IMGTYPE_RGB,0,1,2); // RGBA -> RGB
	}

	if(optctx->imgtype==IW_IMGTYPE_RGBA && optctx->bit_depth==16 && !optctx->has_transparency && ctx->opt_strip_alpha) {
		iw_opt_copychannels_16(ctx,optctx,IW_IMGTYPE_RGB,0,1,2); // RGBA -> RGB (16)
	}

	if(optctx->imgtype==IW_IMGTYPE_GRAYA && optctx->bit_depth==16 && !optctx->has_transparency && ctx->opt_strip_alpha) {
		iw_opt_copychannels_16(ctx,optctx,IW_IMGTYPE_GRAY,0, 0,0); // GA -> G (16)
	}

	if(optctx->imgtype==IW_IMGTYPE_GRAYA && optctx->bit_depth==8 && !optctx->has_transparency && ctx->opt_strip_alpha) {
		iw_opt_copychannels_8(ctx,optctx,IW_IMGTYPE_GRAY,0, 0,0); // GA -> G
	}

	if(optctx->imgtype==IW_IMGTYPE_RGB && optctx->bit_depth==8 && !optctx->has_color &&
	   (ctx->output_profile&IW_PROFILE_GRAYSCALE) && ctx->opt_grayscale)
	{
		iw_opt_copychannels_8(ctx,optctx,IW_IMGTYPE_GRAY,0, 0,0); // RGB -> G
	}

	if(optctx->imgtype==IW_IMGTYPE_RGB && optctx->bit_depth==16 && !optctx->has_color &&
	   (ctx->output_profile&IW_PROFILE_GRAYSCALE) && ctx->opt_grayscale)
	{
		iw_opt_copychannels_16(ctx,optctx,IW_IMGTYPE_GRAY,0, 0,0); // RGB -> G (16)
	}

	if(optctx->imgtype==IW_IMGTYPE_RGBA && optctx->bit_depth==8 && !optctx->has_color &&
	   (ctx->output_profile&IW_PROFILE_GRAYSCALE) && ctx->opt_grayscale)
	{
		iw_opt_copychannels_8(ctx,optctx,IW_IMGTYPE_GRAYA,0,3, 0); // RGBA -> GA
	}

	if(optctx->imgtype==IW_IMGTYPE_RGBA && optctx->bit_depth==16 && !optctx->has_color &&
	   (ctx->output_profile&IW_PROFILE_GRAYSCALE) && ctx->opt_grayscale)
	{
		iw_opt_copychannels_16(ctx,optctx,IW_IMGTYPE_GRAYA,0,3, 0); // RGBA -> GA (16)
	}

noscan:

	iwopt_try_pal_lowgray_optimization(ctx,optctx);

	// Try to convert an alpha channel to binary transparency.

	if(optctx->imgtype==IW_IMGTYPE_RGBA && optctx->bit_depth==8 && !optctx->has_partial_transparency) {
		iwopt_try_rgb8_binary_trns(ctx,optctx);
	}

	if(optctx->imgtype==IW_IMGTYPE_RGBA && optctx->bit_depth==16 && !optctx->has_partial_transparency) {
		iwopt_try_rgb16_binary_trns(ctx,optctx);
	}

	if(optctx->imgtype==IW_IMGTYPE_GRAYA && optctx->bit_depth==8 && !optctx->has_partial_transparency) {
		iwopt_try_gray8_binary_trns(ctx,optctx);
	}

	if(optctx->imgtype==IW_IMGTYPE_GRAYA && optctx->bit_depth==16 && !optctx->has_partial_transparency) {
		iwopt_try_gray16_binary_trns(ctx,optctx);
	}
}
Ejemplo n.º 2
0
// Strip alpha channel if there are no actual transparent pixels, etc.
void iwpvt_optimize_image(struct iw_context *ctx)
{
	struct iw_opt_ctx *optctx;
	int k;

	optctx = &ctx->optctx;

	//iw_zeromem(optctx,sizeof(struct iw_opt_ctx));
	optctx->width = ctx->img2.width;
	optctx->height = ctx->img2.height;
	optctx->imgtype = ctx->img2.imgtype;
	optctx->bit_depth = ctx->img2.bit_depth;
	optctx->bpr = ctx->img2.bpr;
	optctx->pixelsptr = ctx->img2.pixels;
	//optctx->has_transparency=0;
	//optctx->has_partial_transparency=0;
	//optctx->has_16bit_precision=0;
	//optctx->has_color=0;
	if(ctx->img2.has_bkgdlabel) {
		optctx->has_bkgdlabel = ctx->img2.has_bkgdlabel;
		for(k=0;k<4;k++) {
			optctx->bkgdlabel[k] = iw_color_get_int_sample(&ctx->img2.bkgdlabel, k,
				ctx->img2.bit_depth==8?255:65535);
		}
	}

	if(ctx->img2.sampletype!=IW_SAMPLETYPE_UINT) {
		return;
	}

	if(ctx->reduced_output_maxcolor_flag) {
		return;
	}

	make_transparent_pixels_black(ctx,&ctx->img2);

	if(optctx->has_bkgdlabel) {
		// The optimization routines are responsible for ensuring that the
		// background color label can easily be written to the optimized image.
		// For example, they may have to add a color to the palette just for
		// the background color.
		// They are NOT responsible for telling the image encoder module
		// precisely how to write the background color. The encoder will be
		// given the background color in RGB format, and it will have to figure
		// out what to do with it. For example, it may have to search for that
		// color in the palette.

		// If the background color label exists, and is non-gray,
		// make sure we don't write a grayscale image
		// (assuming we're writing to a PNG-like format).
		if(optctx->bkgdlabel[0] != optctx->bkgdlabel[1] ||
			optctx->bkgdlabel[0] != optctx->bkgdlabel[2])
		{
			optctx->has_color = 1;
		}

		// If 16-bit precision is desired, and the background color cannot be
		// losslessly reduced to 8-bit precision, use 16-bit precision.
		if(optctx->bit_depth==16) {
			if(optctx->bkgdlabel[0]%257!=0 || optctx->bkgdlabel[1]%257!=0 ||
				optctx->bkgdlabel[2]%257!=0)
			{
				optctx->has_16bit_precision=1;
			}
		}
	}

	if(!iw_opt_scanpixels(ctx,optctx)) {
		goto noscan;
	}

	if(optctx->imgtype==IW_IMGTYPE_RGBA && optctx->bit_depth==16 && !optctx->has_16bit_precision) {
		iw_opt_16_to_8(ctx,optctx,4);
	}

	if(optctx->imgtype==IW_IMGTYPE_RGB && optctx->bit_depth==16 && !optctx->has_16bit_precision) {
		iw_opt_16_to_8(ctx,optctx,3);
	}

	if(optctx->imgtype==IW_IMGTYPE_GRAYA && optctx->bit_depth==16 && !optctx->has_16bit_precision) {
		iw_opt_16_to_8(ctx,optctx,2);
	}

	if(optctx->imgtype==IW_IMGTYPE_GRAY && optctx->bit_depth==16 && !optctx->has_16bit_precision) {
		iw_opt_16_to_8(ctx,optctx,1);
	}

	if(optctx->imgtype==IW_IMGTYPE_RGBA && optctx->bit_depth==8 && !optctx->has_transparency && ctx->opt_strip_alpha) {
		iw_opt_copychannels_8(ctx,optctx,IW_IMGTYPE_RGB,0,1,2); // RGBA -> RGB
	}

	if(optctx->imgtype==IW_IMGTYPE_RGBA && optctx->bit_depth==16 && !optctx->has_transparency && ctx->opt_strip_alpha) {
		iw_opt_copychannels_16(ctx,optctx,IW_IMGTYPE_RGB,0,1,2); // RGBA -> RGB (16)
	}

	if(optctx->imgtype==IW_IMGTYPE_GRAYA && optctx->bit_depth==16 && !optctx->has_transparency && ctx->opt_strip_alpha) {
		iw_opt_copychannels_16(ctx,optctx,IW_IMGTYPE_GRAY,0, 0,0); // GA -> G (16)
	}

	if(optctx->imgtype==IW_IMGTYPE_GRAYA && optctx->bit_depth==8 && !optctx->has_transparency && ctx->opt_strip_alpha) {
		iw_opt_copychannels_8(ctx,optctx,IW_IMGTYPE_GRAY,0, 0,0); // GA -> G
	}

	if(optctx->imgtype==IW_IMGTYPE_RGB && optctx->bit_depth==8 && !optctx->has_color &&
	   (ctx->output_profile&IW_PROFILE_GRAYSCALE) && ctx->opt_grayscale)
	{
		iw_opt_copychannels_8(ctx,optctx,IW_IMGTYPE_GRAY,0, 0,0); // RGB -> G
	}

	if(optctx->imgtype==IW_IMGTYPE_RGB && optctx->bit_depth==16 && !optctx->has_color &&
	   (ctx->output_profile&IW_PROFILE_GRAYSCALE) && ctx->opt_grayscale)
	{
		iw_opt_copychannels_16(ctx,optctx,IW_IMGTYPE_GRAY,0, 0,0); // RGB -> G (16)
	}

	if(optctx->imgtype==IW_IMGTYPE_RGBA && optctx->bit_depth==8 && !optctx->has_color &&
	   (ctx->output_profile&IW_PROFILE_GRAYSCALE) && ctx->opt_grayscale)
	{
		iw_opt_copychannels_8(ctx,optctx,IW_IMGTYPE_GRAYA,0,3, 0); // RGBA -> GA
	}

	if(optctx->imgtype==IW_IMGTYPE_RGBA && optctx->bit_depth==16 && !optctx->has_color &&
	   (ctx->output_profile&IW_PROFILE_GRAYSCALE) && ctx->opt_grayscale)
	{
		iw_opt_copychannels_16(ctx,optctx,IW_IMGTYPE_GRAYA,0,3, 0); // RGBA -> GA (16)
	}

noscan:

	iwopt_try_pal_lowgray_optimization(ctx,optctx);

	// Try to convert an alpha channel to binary transparency.

	if(optctx->imgtype==IW_IMGTYPE_RGBA && optctx->bit_depth==8 && !optctx->has_partial_transparency) {
		iwopt_try_rgb8_binary_trns(ctx,optctx);
	}

	if(optctx->imgtype==IW_IMGTYPE_RGBA && optctx->bit_depth==16 && !optctx->has_partial_transparency) {
		iwopt_try_rgb16_binary_trns(ctx,optctx);
	}

	if(optctx->imgtype==IW_IMGTYPE_GRAYA && optctx->bit_depth==8 && !optctx->has_partial_transparency) {
		iwopt_try_gray8_binary_trns(ctx,optctx);
	}

	if(optctx->imgtype==IW_IMGTYPE_GRAYA && optctx->bit_depth==16 && !optctx->has_partial_transparency) {
		iwopt_try_gray16_binary_trns(ctx,optctx);
	}
}