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