// 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); } }
// 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); } }