%% options copyright owner = Dirk Krause copyright year = 2011-2013 license = bsd %% header #ifdef __cplusplus extern "C" { #endif /** Check bits per component really used and alpha and color usage. As a result of this function (bp->cf)->realbits, (bp->cf)->realcolor, and (bp->cf)->realalpha is set. @param bp Bitmap image file to check. @param at Analysis type, DK3_BIF_ANALYSIS_xxx, @param pcomm Communicator object. @param minpb Minimum progress bar value (0-1000). @param maxpb Maximum progress bar value (0-1000). see @ref bifanalysis. */ void dk3bif_analyze_progress( dk3_bif_t *bp, int at, void *pcomm, int minpb, int maxpb ); /** Check bits per component really used and alpha and color usage. As a result of this function (bp->cf)->realbits, (bp->cf)->realcolor, and (bp->cf)->realalpha is set. @param bp Bitmap image file to check. @param at Analysis type, DK3_BIF_ANALYSIS_xxx, see @ref bifanalysis. */ void dk3bif_analyze(dk3_bif_t *bp, int at); #ifdef __cplusplus } #endif %% module #include "dk3const.h" #include "dk3mem.h" #include "dk3str.h" #include "dk3sf.h" #include "dk3sto.h" #include "dk3bif.h" #include "dk3bifa.h" #include "dk3pixre.h" #include "dk3ma.h" #include "dk3bits.h" #include "dk3app.h" #if DK3_USE_WX #include #include #include "DkWxCommunicator.h" #endif $!trace-include /** Find number of significant bits in pixel value. @param v Pixel value to inspect. @param nbits Bits per component information from image. @return Number of significant bits in @a v. */ static size_t dk3bif_real_bits(dk3_bif_pixel_t v, size_t nbits) { size_t back = 1; int st = 0; size_t i; size_t j; $? "+ dk3bif_real_bits %u %u", (unsigned)v, (unsigned)nbits for(i = 0; i < nbits; i++) { j = nbits - i - 1; if(i == 0) { if(v & dk3bits_get(j)) { st = 1; } else { st = 0; } back = 1; } else { if(v & dk3bits_get(j)) { if(st == 0) { back = i + 1; } st = 1; } else { if(st == 1) { back = i + 1; } st = 0; } } } $? "- dk3bif_real_bits %u", (unsigned)back return back; } #if DK3_USE_WX /** Show progress during image analysis. Progress is only shown when the module is compiled with DK3_USE_WX defined unequal zero. @param pc Communicator object. @param minpb Minimum progress bar value (0-1000). @param maxpb Maximum progress bar value (0-1000). @param h Image height (number of lines). @param y Current line completed. */ static void dk3bif_show_lines_progress( void *pc, int minpb, int maxpb, dk3_bif_coord_t h, dk3_bif_coord_t y ) { DkWxCommunicator *pComm; unsigned long umax; unsigned long umin; unsigned long uh; unsigned long uy; int ec = 0; if((pc) && (maxpb > minpb) && (h)) { pComm = (DkWxCommunicator *)pc; umax = (unsigned long)maxpb; umin = (unsigned long)minpb; uh = (unsigned long)h; uy = (unsigned long)y; /* umax = umin + (uy + 1UL) * (umax - umin) / (uh); */ umax = dk3ma_ul_add_ok( umin, dk3ma_ul_div_ok( dk3ma_ul_mul_ok( dk3ma_ul_add_ok(uy, 1UL, &ec), dk3ma_ul_sub_ok(umax, umin, &ec), &ec ), uh, &ec ), &ec ); if(ec == 0) { ec = (int)umax; if((minpb <= ec) && (ec <= maxpb)) { pComm->updateGauge(ec); } } } } #endif void dk3bif_analyze_progress( dk3_bif_t *bp, int at, void *pcomm, int minpb, int maxpb ) { dk3_bif_coord_t x; dk3_bif_coord_t y; dk3_bif_pixel_t r; dk3_bif_pixel_t g; dk3_bif_pixel_t b; dk3_bif_pixel_t a; dk3_bif_pixel_t maxval; int cc; size_t bits; $? "+ dk3bif_analyze" maxval = (dk3_bif_pixel_t)0U; for(bits = 0; bits < (bp->cf)->bits; bits++) { maxval |= dk3bits_get(bits); } if(bp) { if(bp->cf) { switch((bp->cf)->cs) { case DK3_COLOR_SPACE_HSB: case DK3_COLOR_SPACE_YCCK: case DK3_COLOR_SPACE_YCbCr: case DK3_COLOR_SPACE_CMYK: { (bp->cf)->realbits = (bp->cf)->bits; (bp->cf)->realcolor = 1; (bp->cf)->realalpha = 1; } break; default: { (bp->cf)->realbits = 1; (bp->cf)->realcolor = 0; (bp->cf)->realalpha = 0; switch((bp->cf)->cs) { case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_RGBA: { /* If there is an alpha channel we have to investigate the background colors too. */ if((bp->cf)->bgr != (bp->cf)->bgg) { (bp->cf)->realcolor = 1; } if((bp->cf)->bgr != (bp->cf)->bgb) { (bp->cf)->realcolor = 1; } bits = dk3bif_real_bits((bp->cf)->bgr, (bp->cf)->bits); if(bits > (bp->cf)->realbits) { (bp->cf)->realbits = bits; } bits = dk3bif_real_bits((bp->cf)->bgg, (bp->cf)->bits); if(bits > (bp->cf)->realbits) { (bp->cf)->realbits = bits; } bits = dk3bif_real_bits((bp->cf)->bgb, (bp->cf)->bits); if(bits > (bp->cf)->realbits) { (bp->cf)->realbits = bits; } } break; } cc = 1; for(y = 0; (y < (bp->cf)->h) && (cc); y++) { for(x = 0; (x < (bp->cf)->w) && (cc); x++) { switch((bp->cf)->cs) { case DK3_COLOR_SPACE_GRAY: { r = dk3bif_get_pixel_component_not_resampled(bp, x, y, 0); bits = dk3bif_real_bits(r, (bp->cf)->bits); if(bits > (bp->cf)->realbits) { (bp->cf)->realbits = bits; } } break; case DK3_COLOR_SPACE_GRAY_ALPHA: { r = dk3bif_get_pixel_component_not_resampled(bp, x, y, 0); a = dk3bif_get_pixel_component_not_resampled(bp, x, y, 3); if(a != maxval) { (bp->cf)->realalpha = 1; } bits = dk3bif_real_bits(r, (bp->cf)->bits); if(bits > (bp->cf)->realbits) { (bp->cf)->realbits = bits; } bits = dk3bif_real_bits(a, (bp->cf)->bits); if(bits > (bp->cf)->realbits) { (bp->cf)->realbits = bits; } } break; case DK3_COLOR_SPACE_RGB: { r = dk3bif_get_pixel_component_not_resampled(bp, x, y, 0); g = dk3bif_get_pixel_component_not_resampled(bp, x, y, 1); b = dk3bif_get_pixel_component_not_resampled(bp, x, y, 2); if(r != g) { (bp->cf)->realcolor = 1; } if(r != b) { (bp->cf)->realcolor = 1; } bits = dk3bif_real_bits(r, (bp->cf)->bits); if(bits > (bp->cf)->realbits) { (bp->cf)->realbits = bits; } bits = dk3bif_real_bits(g, (bp->cf)->bits); if(bits > (bp->cf)->realbits) { (bp->cf)->realbits = bits; } bits = dk3bif_real_bits(b, (bp->cf)->bits); if(bits > (bp->cf)->realbits) { (bp->cf)->realbits = bits; } } break; case DK3_COLOR_SPACE_RGBA: { r = dk3bif_get_pixel_component_not_resampled(bp, x, y, 0); g = dk3bif_get_pixel_component_not_resampled(bp, x, y, 1); b = dk3bif_get_pixel_component_not_resampled(bp, x, y, 2); a = dk3bif_get_pixel_component_not_resampled(bp, x, y, 3); if(a != maxval) { (bp->cf)->realalpha = 1; } if(r != g) { (bp->cf)->realcolor = 1; } if(r != b) { (bp->cf)->realcolor = 1; } bits = dk3bif_real_bits(r, (bp->cf)->bits); if(bits > (bp->cf)->realbits) { (bp->cf)->realbits = bits; } bits = dk3bif_real_bits(g, (bp->cf)->bits); if(bits > (bp->cf)->realbits) { (bp->cf)->realbits = bits; } bits = dk3bif_real_bits(b, (bp->cf)->bits); if(bits > (bp->cf)->realbits) { (bp->cf)->realbits = bits; } bits = dk3bif_real_bits(a, (bp->cf)->bits); if(bits > (bp->cf)->realbits) { (bp->cf)->realbits = bits; } } break; } /* Stop analysis if results are satisfying, no more change to expect. */ cc = 0; if(at & DK3_BIF_ANALYSIS_BITS) { if((bp->cf)->realbits < (bp->cf)->bits) { cc = 1; } } if(!(cc)) { if(at & DK3_BIF_ANALYSIS_COLOR) { switch((bp->cf)->cs) { case DK3_COLOR_SPACE_GRAY: case DK3_COLOR_SPACE_GRAY_ALPHA: { } break; default: { if(!((bp->cf)->realcolor)) { cc = 1; } } break; } } } if(!(cc)) { if(at & DK3_BIF_ANALYSIS_ALPHA) { switch((bp->cf)->cs) { case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_RGBA: { if(!((bp->cf)->realalpha)) { cc = 1; } } break; } } } } #if DK3_USE_WX dk3bif_show_lines_progress(pcomm, minpb, maxpb, (bp->cf)->h, y); #endif } } break; } $? ". bits=%u color=%d", (unsigned)((bp->cf)->realbits), (bp->cf)->realcolor } } #if DK3_USE_WX dk3bif_show_lines_progress(pcomm, minpb, maxpb, 1UL, 0UL); #endif $? "- dk3bif_analyze" } void dk3bif_analyze(dk3_bif_t *bp, int at) { dk3bif_analyze_progress(bp, at, NULL, 0, 1000); }