1%% options 2 3copyright owner = Dirk Krause 4copyright year = 2011-xxxx 5SPDX-License-Identifier: BSD-3-Clause 6 7%% header 8 9#ifdef __cplusplus 10extern "C" { 11#endif 12 13/** Check bits per component really used and alpha and color usage. 14 As a result of this function (bp->cf)->realbits, 15 (bp->cf)->realcolor, and (bp->cf)->realalpha is set. 16 @param bp Bitmap image file to check. 17 @param at Analysis type, DK3_BIF_ANALYSIS_xxx, 18 @param pcomm Communicator object. 19 @param minpb Minimum progress bar value (0-1000). 20 @param maxpb Maximum progress bar value (0-1000). 21 see @ref bifanalysis. 22*/ 23void 24dk3bif_analyze_progress( 25 dk3_bif_t *bp, 26 int at, 27 void *pcomm, 28 int minpb, 29 int maxpb 30); 31 32/** Check bits per component really used and alpha and color usage. 33 As a result of this function (bp->cf)->realbits, 34 (bp->cf)->realcolor, and (bp->cf)->realalpha is set. 35 @param bp Bitmap image file to check. 36 @param at Analysis type, DK3_BIF_ANALYSIS_xxx, 37 see @ref bifanalysis. 38*/ 39void 40dk3bif_analyze(dk3_bif_t *bp, int at); 41 42#ifdef __cplusplus 43} 44#endif 45 46 47 48%% module 49 50#include "dk3conf.h" 51#include <libdk3c/dk3const.h> 52#include <libdk3c/dk3mem.h> 53#include <libdk3c/dk3str.h> 54#include <libdk3c/dk3sf.h> 55#include <libdk3c/dk3sto.h> 56#include <libdk3bif/dk3bif.h> 57#include <libdk3bif/dk3bifa.h> 58#include <libdk3bif/dk3pixre.h> 59#include <libdk3c/dk3ma.h> 60#include <libdk3c/dk3bits.h> 61#include <libdk3c/dk3app.h> 62 63#include <stdio.h> 64 65#if DK3_USE_WX 66#include <wx/wx.h> 67#include <wx/thread.h> 68#include <libdk3wx/DkWxCommunicator.h> 69#endif 70 71#include <libdk3c/dk3unused.h> 72 73 74 75$!trace-include 76 77 78 79/** Default texts for debug messages in bit depth analysis. 80*/ 81static dkChar const * const dk3bif_analysis_msg[] = { 82$!string-table macro=dkT 83# 84# 0 85# 86Image analysis: Original image is color image. 87# 88# 1 89# 90Image analysis: Original image is grayscaled image. 91# 92# 2 93# 94Image analysis: Can reduce image to grayscaled image. 95# 96# 3 97# 98Image analysis: Really a color image. 99# 100# 4 101# 102Image analysis: Original image contains alpha channel. 103# 104# 5 105# 106Image analysis: No alpha channel in original image. 107# 108# 6 109# 110Image analysis: Alpha channel is used. 111# 112# 7 113# 114Image analysis: Alpha channel is not used. 115# 116# 8 9 117# 118Image analysis: Original image contains 119 bits per component. 120# 121# 10 11 122# 123Image analysis: Output image contains 124 bits per component. 125$!end 126}; 127 128 129 130#if 0 131/** Find number of significant bits in pixel value. 132 @param v Pixel value to inspect. 133 @param nbits Bits per component information from image. 134 @return Number of significant bits in @a v. 135*/ 136static 137size_t 138dk3bif_real_bits(dk3_bif_pixel_t v, size_t nbits) 139{ 140 size_t back = 1; 141 int st = 0; 142 size_t i; 143 size_t j; 144 $? "+ dk3bif_real_bits %u %u", (unsigned)v, (unsigned)nbits 145 for(i = 0; i < nbits; i++) { 146 j = nbits - i - 1; 147 if(i == 0) { 148 if(v & dk3bits_get(j)) { 149 st = 1; 150 } else { 151 st = 0; 152 } 153 back = 1; 154 } else { 155 if(v & dk3bits_get(j)) { 156 if(st == 0) { 157 back = i + 1; 158 } 159 st = 1; 160 } else { 161 if(st == 1) { 162 back = i + 1; 163 } 164 st = 0; 165 } 166 } 167 } $? "- dk3bif_real_bits %u", (unsigned)back 168 return back; 169} 170#endif 171 172 173 174#if DK3_USE_WX 175/** Show progress during image analysis. 176 Progress is only shown when the module is compiled with 177 DK3_USE_WX defined unequal zero. 178 @param pc Communicator object. 179 @param minpb Minimum progress bar value (0-1000). 180 @param maxpb Maximum progress bar value (0-1000). 181 @param h Image height (number of lines). 182 @param y Current line completed. 183*/ 184static 185void 186dk3bif_show_lines_progress( 187 void *pc, 188 int minpb, 189 int maxpb, 190 dk3_bif_coord_t h, 191 dk3_bif_coord_t y 192) 193{ 194 DkWxCommunicator *pComm; 195 unsigned long umax; 196 unsigned long umin; 197 unsigned long uh; 198 unsigned long uy; 199 int ec = 0; 200 if((pc) && (maxpb > minpb) && (h)) { 201 pComm = (DkWxCommunicator *)pc; 202 umax = (unsigned long)maxpb; 203 umin = (unsigned long)minpb; 204 uh = (unsigned long)h; 205 uy = (unsigned long)y; 206 /* umax = umin + (uy + 1UL) * (umax - umin) / (uh); */ 207 umax = dk3ma_ul_add_ok( 208 umin, 209 dk3ma_ul_div_ok( 210 dk3ma_ul_mul_ok( 211 dk3ma_ul_add_ok(uy, 1UL, &ec), 212 dk3ma_ul_sub_ok(umax, umin, &ec), 213 &ec 214 ), 215 uh, 216 &ec 217 ), 218 &ec 219 ); 220 if(ec == 0) { 221 ec = (int)umax; 222 if((minpb <= ec) && (ec <= maxpb)) { 223 pComm->updateGauge(ec); 224 } 225 } 226 } 227} 228#endif 229 230 231 232/** Structure to analyze bit depth of an image frame. 233*/ 234typedef struct { 235 dk3_pixel_resample_t r01; /**< Pixel resampling to 1 bit. */ 236 dk3_pixel_resample_t r02; /**< Pixel resampling to 2 bit. */ 237 dk3_pixel_resample_t r04; /**< Pixel resampling to 4 bit. */ 238 dk3_pixel_resample_t r08; /**< Pixel resampling to 8 bit. */ 239 dk3_pixel_resample_t r12; /**< Pixel resampling to 12 bit. */ 240 int finished; /**< Flag: Analysis finished. */ 241 int f01; /**< Flag: Can resample to 1 bit. */ 242 int f02; /**< Flag: Can resample to 2 bit. */ 243 int f04; /**< Flag: Can resample to 4 bit. */ 244 int f08; /**< Flag: Can resample to 8 bit. */ 245 int f12; /**< Flag: Can resample to 12 bit. */ 246} dk3_bif_analyze_bitdepth_t; 247 248 249 250/** Set up analysis structure. 251 @param p Bitdepth analysis structure. 252 @param at Analysis type. 253 @param srcw Source bit width. 254*/ 255static 256void 257dk3bif_analyze_setup_structure( 258 dk3_bif_analyze_bitdepth_t *p, 259 size_t srcw 260) 261{ 262 p->f01 = 0; p->f02 = 0; p->f04 = 0; p->f08 = 0; p->f12 = 0; 263 dk3pixre_set(&(p->r01), srcw, 1); 264 dk3pixre_set(&(p->r02), srcw, 2); 265 dk3pixre_set(&(p->r04), srcw, 4); 266 dk3pixre_set(&(p->r08), srcw, 8); 267 dk3pixre_set(&(p->r12), srcw, 12); 268 p->finished = 1; 269 if ( 1 < srcw) { p->f01 = 1; p->finished = 0; } 270 if ( 2 < srcw) { p->f02 = 1; } 271 if ( 4 < srcw) { p->f04 = 1; } 272 if ( 8 < srcw) { p->f08 = 1; } 273 if (12 < srcw) { p->f12 = 1; } 274} 275 276 277 278/** Analyse one pixel value. 279 @param p Bit depth analysis structure. 280 @param v Value to analyze. 281*/ 282static 283void 284dk3bif_analyze_check_bitvalue( 285 dk3_bif_analyze_bitdepth_t *p, 286 dk3_bif_pixel_t v 287) 288{ 289 int changed = 0; 290 if (p->f01) { 291 if (!(dk3pixre_can_convert(&(p->r01), v))) { 292 p->f01 = 0; 293 changed = 1; 294 } 295 } 296 if (p->f02) { 297 if (!(dk3pixre_can_convert(&(p->r02), v))) { 298 p->f02 = 0; 299 changed = 1; 300 } 301 } 302 if (p->f04) { 303 if (!(dk3pixre_can_convert(&(p->r04), v))) { 304 p->f04 = 0; 305 changed = 1; 306 } 307 } 308 if (p->f08) { 309 if (!(dk3pixre_can_convert(&(p->r08), v))) { 310 p->f08 = 0; 311 changed = 1; 312 } 313 } 314 if (p->f12) { 315 if (!(dk3pixre_can_convert(&(p->r12), v))) { 316 p->f12 = 0; 317 changed = 1; 318 } 319 } 320 if (changed) { 321 if (!((p->f01) || (p->f02) || (p->f04) || (p->f08) || (p->f12))) { 322 p->finished = 1; 323 } 324 } 325} 326 327 328 329void 330dk3bif_analyze_progress( 331 dk3_bif_t *bp, 332 int at, 333 void *DK3_ARG_UNUSED(pcomm), 334 int DK3_ARG_UNUSED(minpb), 335 int DK3_ARG_UNUSED(maxpb) 336) 337{ 338 dk3_bif_analyze_bitdepth_t ana; 339 dk3_bif_coord_t x; 340 dk3_bif_coord_t y; 341 int cc; 342 int found_color; 343 int found_alpha; 344 int search_color; 345 int search_alpha; 346 dk3_bif_pixel_t maxval; 347 dk3_bif_pixel_t r; 348 dk3_bif_pixel_t g; 349 dk3_bif_pixel_t b; 350 dk3_bif_pixel_t a; 351 352 DK3_UNUSED_ARG(pcomm) 353 DK3_UNUSED_ARG(minpb) 354 DK3_UNUSED_ARG(maxpb) 355 if (bp) { 356 if (bp->cf) { 357 /* Default values for all color space types. 358 */ 359 (bp->cf)->realbits = (bp->cf)->bits; 360 (bp->cf)->realcolor = 0; 361 (bp->cf)->realalpha = 0; 362 363 switch ((bp->cf)->cs) { 364 365 /* For some color space we can not do the analysis. 366 */ 367 case DK3_COLOR_SPACE_HSB: 368 case DK3_COLOR_SPACE_YCCK: 369 case DK3_COLOR_SPACE_YCbCr: 370 case DK3_COLOR_SPACE_CMYK: 371 { 372 (bp->cf)->realcolor = 1; 373 (bp->cf)->realalpha = 1; 374 } 375 break; 376 377 /* Do analysis. 378 */ 379 default: { 380 /* Default values. 381 */ 382 (bp->cf)->realcolor = 0; 383 (bp->cf)->realalpha = 0; 384 search_alpha = 0; 385 search_color = 0; 386 switch ((bp->cf)->cs) { 387 case DK3_COLOR_SPACE_GRAY_ALPHA: 388 case DK3_COLOR_SPACE_RGBA: { 389 if (DK3_BIF_ANALYSIS_ALPHA & at) { 390 search_alpha = 1; 391 } else { 392 (bp->cf)->realalpha = 1; 393 } 394 } break; 395 } 396 switch ((bp->cf)->cs) { 397 case DK3_COLOR_SPACE_RGB: 398 case DK3_COLOR_SPACE_RGBA: { 399 if (DK3_BIF_ANALYSIS_COLOR & at) { 400 search_color = 1; 401 } else { 402 (bp->cf)->realcolor = 1; 403 } 404 } break; 405 } 406 407 /* Do analysis 408 */ 409 dk3bif_analyze_setup_structure(&ana, (bp->cf)->bits); 410 maxval = dk3pixre_maximum_for_width((bp->cf)->bits); 411 found_color = 0; 412 found_alpha = 0; 413 switch ((bp->cf)->cs) { 414 case DK3_COLOR_SPACE_GRAY_ALPHA: 415 case DK3_COLOR_SPACE_RGBA: 416 { 417 if((bp->cf)->bgr != (bp->cf)->bgg) { found_color = 1; } 418 if((bp->cf)->bgr != (bp->cf)->bgb) { found_color = 1; } 419 if (DK3_BIF_ANALYSIS_BITS & at) { 420 dk3bif_analyze_check_bitvalue(&ana, (bp->cf)->bgr); 421 dk3bif_analyze_check_bitvalue(&ana, (bp->cf)->bgg); 422 dk3bif_analyze_check_bitvalue(&ana, (bp->cf)->bgb); 423 } 424 } break; 425 } 426 cc = 1; 427 for (y = 0; ((y < (bp->cf)->h) && (cc)); y++) { 428 for (x = 0; ((x < (bp->cf)->w) && (cc)); x++) { 429 switch ((bp->cf)->cs) { 430 case DK3_COLOR_SPACE_GRAY: { 431 r = dk3bif_get_pixel_component_not_resampled(bp, x, y, 0); 432 if (DK3_BIF_ANALYSIS_BITS & at) { 433 dk3bif_analyze_check_bitvalue(&ana, r); 434 } 435 } break; 436 case DK3_COLOR_SPACE_GRAY_ALPHA: { 437 r = dk3bif_get_pixel_component_not_resampled(bp, x, y, 0); 438 a = dk3bif_get_pixel_component_not_resampled(bp, x, y, 3); 439 if (DK3_BIF_ANALYSIS_BITS & at) { 440 dk3bif_analyze_check_bitvalue(&ana, r); 441 dk3bif_analyze_check_bitvalue(&ana, a); 442 } 443 if (search_alpha) { 444 if (maxval != a) { found_alpha = 1; } 445 } 446 } break; 447 case DK3_COLOR_SPACE_RGB: { 448 r = dk3bif_get_pixel_component_not_resampled(bp, x, y, 0); 449 g = dk3bif_get_pixel_component_not_resampled(bp, x, y, 1); 450 b = dk3bif_get_pixel_component_not_resampled(bp, x, y, 2); 451 if (DK3_BIF_ANALYSIS_BITS & at) { 452 dk3bif_analyze_check_bitvalue(&ana, r); 453 dk3bif_analyze_check_bitvalue(&ana, g); 454 dk3bif_analyze_check_bitvalue(&ana, b); 455 } 456 if (search_color) { 457 if((r != g) || (r != b)) { found_color = 1; } 458 } 459 } break; 460 case DK3_COLOR_SPACE_RGBA: { 461 r = dk3bif_get_pixel_component_not_resampled(bp, x, y, 0); 462 g = dk3bif_get_pixel_component_not_resampled(bp, x, y, 1); 463 b = dk3bif_get_pixel_component_not_resampled(bp, x, y, 2); 464 a = dk3bif_get_pixel_component_not_resampled(bp, x, y, 3); 465 if (DK3_BIF_ANALYSIS_BITS & at) { 466 dk3bif_analyze_check_bitvalue(&ana, r); 467 dk3bif_analyze_check_bitvalue(&ana, g); 468 dk3bif_analyze_check_bitvalue(&ana, b); 469 dk3bif_analyze_check_bitvalue(&ana, a); 470 } 471 if (search_color) { 472 if((r != g) || (r != b)) { found_color = 1; } 473 } 474 if (search_alpha) { 475 if (maxval != a) { found_alpha = 1; } 476 } 477 } break; 478 } 479 cc = 0; 480 if (DK3_BIF_ANALYSIS_BITS & at) { 481 if(!(ana.finished)) { cc = 1; } 482 } 483 if (search_color) { 484 if(!(found_color)) { cc = 1; } 485 } 486 if (search_alpha) { 487 if(!(found_alpha)) { cc = 1; } 488 } 489 } 490#if DK3_USE_WX 491 dk3bif_show_lines_progress(pcomm, minpb, maxpb, (bp->cf)->h, y); 492#endif 493 } 494 495 /* After analysis apply results. 496 */ 497 if (DK3_BIF_ANALYSIS_BITS & at) { 498 if (ana.f01) { 499 (bp->cf)->realbits = 1; 500 } else { 501 if (ana.f02) { 502 (bp->cf)->realbits = 2; 503 } else { 504 if (ana.f04) { 505 (bp->cf)->realbits = 4; 506 } else { 507 if (ana.f08) { 508 (bp->cf)->realbits = 8; 509 } else { 510 if (ana.f12) { 511 (bp->cf)->realbits = 12; 512 } 513 } 514 } 515 } 516 } 517 } 518 if (search_color) { 519 (bp->cf)->realcolor = found_color; 520 } 521 if (search_alpha) { 522 (bp->cf)->realalpha = found_alpha; 523 } 524 if (bp->app) { 525 if (DK3_LL_DEBUG <= dk3app_max_log_level(bp->app)) { 526 dkChar buffer[128]; 527 dkChar const * const *msg; 528 msg = dk3app_messages( 529 bp->app, dkT("dk3bifa.str"), dk3bif_analysis_msg 530 ); 531 if (DK3_BIF_ANALYSIS_COLOR & at) { 532 switch ((bp->cf)->cs) { 533 case DK3_COLOR_SPACE_RGB: 534 case DK3_COLOR_SPACE_RGBA: { 535 /* Original image: color */ 536 dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 0); 537 if (found_color) { 538 dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 3); 539 } else { 540 /* Grayscale image */ 541 dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 2); 542 } 543 } break; 544 default: { 545 /* Gray image */ 546 dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 1); 547 } break; 548 } 549 } 550 if (DK3_BIF_ANALYSIS_ALPHA & at) { 551 switch ((bp->cf)->cs) { 552 case DK3_COLOR_SPACE_GRAY_ALPHA: 553 case DK3_COLOR_SPACE_RGBA: { 554 dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 4); 555 if (found_alpha) { 556 /* Alpha data found */ 557 dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 6); 558 } else { 559 /* No real alpha data */ 560 dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 7); 561 } 562 } break; 563 default: { 564 /* No alpha channel in image */ 565 dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 5); 566 } break; 567 } 568 } 569 if (DK3_BIF_ANALYSIS_BITS & at) { 570#if VERSION_BEFORE_20140716 571 /* Original bits per component */ 572 dk3sf_sprintf3(buffer, dkT("%u"), (unsigned)((bp->cf)->bits)); 573 dk3app_log_3(bp->app, DK3_LL_DEBUG, msg, 8, 9, buffer); 574 /* Output bits per component */ 575 dk3sf_sprintf3(buffer,dkT("%u"),(unsigned)((bp->cf)->realbits)); 576 dk3app_log_3(bp->app, DK3_LL_DEBUG, msg, 10, 11, buffer); 577#else 578 int res; 579 res = dk3ma_um_to_string( 580 buffer, DK3_SIZEOF(buffer,dkChar), 581 (dk3_um_t)((bp->cf)->bits) 582 ); 583 if (0 != res) { 584 dk3app_log_3(bp->app, DK3_LL_DEBUG, msg, 8, 9, buffer); 585 } 586 res = dk3ma_um_to_string( 587 buffer, DK3_SIZEOF(buffer,dkChar), 588 (dk3_um_t)((bp->cf)->realbits) 589 ); 590 if (0 != res) { 591 dk3app_log_3(bp->app, DK3_LL_DEBUG, msg, 10, 11, buffer); 592 } 593#endif 594 } 595 } 596 } 597 } break; 598 } 599 } 600 } 601#if DK3_USE_WX 602 dk3bif_show_lines_progress(pcomm, minpb, maxpb, 1UL, 0UL); 603#endif 604} 605 606 607 608void 609dk3bif_analyze(dk3_bif_t *bp, int at) 610{ 611 dk3bif_analyze_progress(bp, at, NULL, 0, 1000); 612} 613 614 615