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