/* WARNING: This file was generated by dkct. Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk3bifa.ctr */ /* Copyright (C) 2011-2017, Dirk Krause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file dk3bifa.c The dk3bifa module. */ #line 49 "dk3bifa.ctr" #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" #include #if DK3_USE_WX #include #include #include "DkWxCommunicator.h" #endif #line 73 "dk3bifa.ctr" /** Default texts for debug messages in bit depth analysis. */ static dkChar const * const dk3bif_analysis_msg[] = { /* 0 */ dkT("Image analysis: Original image is color image."), /* 1 */ dkT("Image analysis: Original image is greyscaled image."), /* 2 */ dkT("Image analysis: Can reduce image to greyscaled image."), /* 3 */ dkT("Image analysis: Really a color image."), /* 4 */ dkT("Image analysis: Original image contains alpha channel."), /* 5 */ dkT("Image analysis: No alpha channel in original image."), /* 6 */ dkT("Image analysis: Alpha channel is used."), /* 7 */ dkT("Image analysis: Alpha channel is not used."), /* 8 */ dkT("Image analysis: Original image contains "), /* 9 */ dkT(" bits per component."), /* 10 */ dkT("Image analysis: Output image contains "), /* 11 */ dkT(" bits per component."), NULL #line 123 "dk3bifa.ctr" }; #if 0 /** 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; #line 142 "dk3bifa.ctr" 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; } } } #line 165 "dk3bifa.ctr" return back; } #endif #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 /** Structure to analyze bit depth of an image frame. */ typedef struct { dk3_pixel_resample_t r01; /**< Pixel resampling to 1 bit. */ dk3_pixel_resample_t r02; /**< Pixel resampling to 2 bit. */ dk3_pixel_resample_t r04; /**< Pixel resampling to 4 bit. */ dk3_pixel_resample_t r08; /**< Pixel resampling to 8 bit. */ dk3_pixel_resample_t r12; /**< Pixel resampling to 12 bit. */ int finished; /**< Flag: Analysis finished. */ int f01; /**< Flag: Can resample to 1 bit. */ int f02; /**< Flag: Can resample to 2 bit. */ int f04; /**< Flag: Can resample to 4 bit. */ int f08; /**< Flag: Can resample to 8 bit. */ int f12; /**< Flag: Can resample to 12 bit. */ } dk3_bif_analyze_bitdepth_t; /** Set up analysis structure. @param p Bitdepth analysis structure. @param at Analysis type. @param srcw Source bit width. */ static void dk3bif_analyze_setup_structure( dk3_bif_analyze_bitdepth_t *p, int at, size_t srcw ) { p->f01 = 0; p->f02 = 0; p->f04 = 0; p->f08 = 0; p->f12 = 0; dk3pixre_set(&(p->r01), srcw, 1); dk3pixre_set(&(p->r02), srcw, 2); dk3pixre_set(&(p->r04), srcw, 4); dk3pixre_set(&(p->r08), srcw, 8); dk3pixre_set(&(p->r12), srcw, 12); p->finished = 1; if ( 1 < srcw) { p->f01 = 1; p->finished = 0; } if ( 2 < srcw) { p->f02 = 1; } if ( 4 < srcw) { p->f04 = 1; } if ( 8 < srcw) { p->f08 = 1; } if (12 < srcw) { p->f12 = 1; } } /** Analyse one pixel value. @param p Bit depth analysis structure. @param v Value to analyze. */ static void dk3bif_analyze_check_bitvalue( dk3_bif_analyze_bitdepth_t *p, dk3_bif_pixel_t v ) { int changed = 0; if (p->f01) { if (!(dk3pixre_can_convert(&(p->r01), v))) { p->f01 = 0; changed = 1; } } if (p->f02) { if (!(dk3pixre_can_convert(&(p->r02), v))) { p->f02 = 0; changed = 1; } } if (p->f04) { if (!(dk3pixre_can_convert(&(p->r04), v))) { p->f04 = 0; changed = 1; } } if (p->f08) { if (!(dk3pixre_can_convert(&(p->r08), v))) { p->f08 = 0; changed = 1; } } if (p->f12) { if (!(dk3pixre_can_convert(&(p->r12), v))) { p->f12 = 0; changed = 1; } } if (changed) { if (!((p->f01) || (p->f02) || (p->f04) || (p->f08) || (p->f12))) { p->finished = 1; } } } void dk3bif_analyze_progress( dk3_bif_t *bp, int at, void *pcomm, int minpb, int maxpb ) { dk3_bif_analyze_bitdepth_t ana; dk3_bif_coord_t x; dk3_bif_coord_t y; int cc; int found_color; int found_alpha; int search_color; int search_alpha; dk3_bif_pixel_t maxval; dk3_bif_pixel_t r; dk3_bif_pixel_t g; dk3_bif_pixel_t b; dk3_bif_pixel_t a; if (bp) { if (bp->cf) { /* Default values for all color space types. */ (bp->cf)->realbits = (bp->cf)->bits; (bp->cf)->realcolor = 0; (bp->cf)->realalpha = 0; switch ((bp->cf)->cs) { /* For some color space we can not do the analysis. */ case DK3_COLOR_SPACE_HSB: case DK3_COLOR_SPACE_YCCK: case DK3_COLOR_SPACE_YCbCr: case DK3_COLOR_SPACE_CMYK: { (bp->cf)->realcolor = 1; (bp->cf)->realalpha = 1; } break; /* Do analysis. */ default: { /* Default values. */ (bp->cf)->realcolor = 0; (bp->cf)->realalpha = 0; search_alpha = 0; search_color = 0; switch ((bp->cf)->cs) { case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_RGBA: { if (DK3_BIF_ANALYSIS_ALPHA & at) { search_alpha = 1; } else { (bp->cf)->realalpha = 1; } } break; } switch ((bp->cf)->cs) { case DK3_COLOR_SPACE_RGB: case DK3_COLOR_SPACE_RGBA: { if (DK3_BIF_ANALYSIS_COLOR & at) { search_color = 1; } else { (bp->cf)->realcolor = 1; } } break; } /* Do analysis */ dk3bif_analyze_setup_structure(&ana, at, (bp->cf)->bits); maxval = dk3pixre_maximum_for_width((bp->cf)->bits); found_color = 0; found_alpha = 0; switch ((bp->cf)->cs) { case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_RGBA: { if((bp->cf)->bgr != (bp->cf)->bgg) { found_color = 1; } if((bp->cf)->bgr != (bp->cf)->bgb) { found_color = 1; } if (DK3_BIF_ANALYSIS_BITS & at) { dk3bif_analyze_check_bitvalue(&ana, (bp->cf)->bgr); dk3bif_analyze_check_bitvalue(&ana, (bp->cf)->bgg); dk3bif_analyze_check_bitvalue(&ana, (bp->cf)->bgb); } } 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); if (DK3_BIF_ANALYSIS_BITS & at) { dk3bif_analyze_check_bitvalue(&ana, r); } } 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 (DK3_BIF_ANALYSIS_BITS & at) { dk3bif_analyze_check_bitvalue(&ana, r); dk3bif_analyze_check_bitvalue(&ana, a); } if (search_alpha) { if (maxval != a) { found_alpha = 1; } } } 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 (DK3_BIF_ANALYSIS_BITS & at) { dk3bif_analyze_check_bitvalue(&ana, r); dk3bif_analyze_check_bitvalue(&ana, g); dk3bif_analyze_check_bitvalue(&ana, b); } if (search_color) { if((r != g) || (r != b)) { found_color = 1; } } } 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 (DK3_BIF_ANALYSIS_BITS & at) { dk3bif_analyze_check_bitvalue(&ana, r); dk3bif_analyze_check_bitvalue(&ana, g); dk3bif_analyze_check_bitvalue(&ana, b); dk3bif_analyze_check_bitvalue(&ana, a); } if (search_color) { if((r != g) || (r != b)) { found_color = 1; } } if (search_alpha) { if (maxval != a) { found_alpha = 1; } } } break; } cc = 0; if (DK3_BIF_ANALYSIS_BITS & at) { if(!(ana.finished)) { cc = 1; } } if (search_color) { if(!(found_color)) { cc = 1; } } if (search_alpha) { if(!(found_alpha)) { cc = 1; } } } #if DK3_USE_WX dk3bif_show_lines_progress(pcomm, minpb, maxpb, (bp->cf)->h, y); #endif } /* After analysis apply results. */ if (DK3_BIF_ANALYSIS_BITS & at) { if (ana.f01) { (bp->cf)->realbits = 1; } else { if (ana.f02) { (bp->cf)->realbits = 2; } else { if (ana.f04) { (bp->cf)->realbits = 4; } else { if (ana.f08) { (bp->cf)->realbits = 8; } else { if (ana.f12) { (bp->cf)->realbits = 12; } } } } } } if (search_color) { (bp->cf)->realcolor = found_color; } if (search_alpha) { (bp->cf)->realalpha = found_alpha; } if (bp->app) { if (DK3_LL_DEBUG <= dk3app_max_log_level(bp->app)) { dkChar buffer[128]; dkChar const * const *msg; msg = dk3app_messages( bp->app, dkT("dk3bifa.str"), dk3bif_analysis_msg ); if (DK3_BIF_ANALYSIS_COLOR & at) { switch ((bp->cf)->cs) { case DK3_COLOR_SPACE_RGB: case DK3_COLOR_SPACE_RGBA: { /* Original image: color */ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 0); if (found_color) { dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 3); } else { /* Grayscale image */ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 2); } } break; default: { /* Gray image */ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 1); } break; } } if (DK3_BIF_ANALYSIS_ALPHA & at) { switch ((bp->cf)->cs) { case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_RGBA: { dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 4); if (found_alpha) { /* Alpha data found */ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 6); } else { /* No real alpha data */ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 7); } } break; default: { /* No alpha channel in image */ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 5); } break; } } if (DK3_BIF_ANALYSIS_BITS & at) { #if VERSION_BEFORE_20140716 /* Original bits per component */ dk3sf_sprintf3(buffer, dkT("%u"), (unsigned)((bp->cf)->bits)); dk3app_log_3(bp->app, DK3_LL_DEBUG, msg, 8, 9, buffer); /* Output bits per component */ dk3sf_sprintf3(buffer,dkT("%u"),(unsigned)((bp->cf)->realbits)); dk3app_log_3(bp->app, DK3_LL_DEBUG, msg, 10, 11, buffer); #else int res; res = dk3ma_um_to_string( buffer, DK3_SIZEOF(buffer,dkChar), (dk3_um_t)((bp->cf)->bits) ); if (0 != res) { dk3app_log_3(bp->app, DK3_LL_DEBUG, msg, 8, 9, buffer); } res = dk3ma_um_to_string( buffer, DK3_SIZEOF(buffer,dkChar), (dk3_um_t)((bp->cf)->realbits) ); if (0 != res) { dk3app_log_3(bp->app, DK3_LL_DEBUG, msg, 10, 11, buffer); } #endif } } } } break; } } } #if DK3_USE_WX dk3bif_show_lines_progress(pcomm, minpb, maxpb, 1UL, 0UL); #endif } void dk3bif_analyze(dk3_bif_t *bp, int at) { dk3bif_analyze_progress(bp, at, NULL, 0, 1000); }