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