/* Copyright (C) 2017-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). 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: dk4bifa.ctr */ /** @file dk4bifa.c The dk4bifa module. */ #line 86 "dk4bifa.ctr" #ifndef DK4CONF_H_INCLUDED #include "dk4conf.h" #endif #ifndef DK4BIFTY_H_INCLUDED #include "dk4bifty.h" #endif #ifndef DK4BIFA_H_INCLUDED #include "dk4bifa.h" #endif #ifndef DK4PXBIT_H_INCLUDED #include "dk4pxbit.h" #endif #ifndef DK4PXRES_H_INCLUDED #include "dk4pxres.h" #endif #ifndef DK4BIF_H_INCLUDED #include "dk4bif.h" #endif #if DK4_HAVE_ASSERT_H #ifndef ASSERT_H_INCLUDED #include #define ASSERT_H_INCLUDED 1 #endif #endif #line 120 "dk4bifa.ctr" /** Test for various resamplers whether the value can be resampled without quality loss. @param pxr Array of pixel resamplers to 1, 2, 4, 8 and 12 bit. @param pxo Array of can-use flags for the pixel resamplers. @param changed Address of change flag. @param value Pixel sample value to test. @param ori_bd Original bit depth. */ static void dk4bif_ana_bd( dk4_px_resample_t *pxr, int *pxo, int *changed, dk4_px_t value, dk4_px_bit_depth_t ori_bd ) { #if DK4_USE_ASSERT assert(NULL != pxr); assert(NULL != pxo); assert(NULL != changed); #endif if (1 < ori_bd) { if (0 != pxo[0]) { if (0 == dk4pxres_check(&(pxr[0]), value)) { pxo[0] = 0; *changed = 1; } } if (2 < ori_bd) { if (0 != pxo[1]) { if (0 == dk4pxres_check(&(pxr[1]), value)) { pxo[1] = 0; *changed = 1; } } if (4 < ori_bd) { if (0 != pxo[2]) { if (0 == dk4pxres_check(&(pxr[2]), value)) { pxo[2] = 0; *changed = 1; } } if (8 < ori_bd) { if (0 != pxo[3]) { if (0 == dk4pxres_check(&(pxr[3]), value)) { pxo[3] = 0; *changed = 1; } } if (12 < ori_bd) { if (0 != pxo[4]) { if (0 == dk4pxres_check(&(pxr[4]), value)) { pxo[4] = 0; *changed = 1; } } } } } } } } int dk4bif_analyze( int *pcs, dk4_px_bit_depth_t *pbd, dk4_bif_t const *bif, int anb, int anc, int ana, dk4_er_t *erp ) { dk4_px_resample_t pxr[8]; /* Pixel resampling structures */ dk4_px_t pix[8]; /* Pixel component values */ int pxo[8]; /* Pixel resampling ok */ size_t i; /* Traverse resampling structures */ dk4_bif_dim_t x; /* Current column number */ dk4_bif_dim_t y; /* Current row number */ dk4_bif_dim_t w; /* Image width */ dk4_bif_dim_t h; /* Image height */ dk4_px_t max = 1; /* Maximum value for bit depth */ int ori_cs = 0; /* Original color space */ int back = 0; /* Function result */ int f_col = 0; /* Flag: Found colored pixel */ int f_alp = 0; /* Flag: Found pixel with alpha */ int cc = 1; /* Flag: Can continue */ int changed = 0; /* Flag: Change in loop pass */ dk4_px_bit_depth_t ori_bd = 8; /* Original bit depth */ #line 219 "dk4bifa.ctr" #if DK4_USE_ASSERT assert(NULL != bif); #endif /* Check arguments */ if (NULL == bif) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if ((NULL == pcs) && ((0 != anc) || (0 != ana))) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if ((NULL == pbd) && (0 != anb)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } /* All arguments ok */ back = 1; /* Correct analysis for color space (i.e. no need to check for colors if color space is gray) */ ori_cs = dk4bif_get_color_space(bif); ori_bd = dk4bif_get_original_bit_depth(bif); #line 248 "dk4bifa.ctr" #line 249 "dk4bifa.ctr" max = dk4pxbit_get_max(ori_bd); switch (ori_cs) { case DK4_CS_GRAY : { anc = 0; ana = 0; } break; case DK4_CS_GRAY_ALPHA : { anc = 0; } break; case DK4_CS_RGB : { ana = 0; } break; case DK4_CS_RGB_ALPHA : { ana = 0; } break; case DK4_CS_CMYK : { ana = 0; } break; } /* If no analysis to execute, skip processing */ if ((0 == anb) && (0 == anc) && (0 == ana)) { if (NULL != pcs) { *pcs = ori_cs; } if (NULL != pbd) { *pbd = ori_bd; } goto finished; } /* Mark all bit depths as available */ for (i = 0; i < 5; i++) { dk4pxres_init(&(pxr[i])); pxo[i] = 1; } /* Set up pixel resampling structures to test bit depth conversions */ (void)dk4pxres_setup(&(pxr[0]), ori_bd, 1); (void)dk4pxres_setup(&(pxr[1]), ori_bd, 2); (void)dk4pxres_setup(&(pxr[2]), ori_bd, 4); (void)dk4pxres_setup(&(pxr[3]), ori_bd, 8); (void)dk4pxres_setup(&(pxr[4]), ori_bd, 12); if (NULL != bif->cf) { if (0 != bif->cf->fmres) { (void)dk4pxres_setup_from_maxval(&(pxr[0]), bif->cf->fmrmv, 1); (void)dk4pxres_setup_from_maxval(&(pxr[1]), bif->cf->fmrmv, 2); (void)dk4pxres_setup_from_maxval(&(pxr[2]), bif->cf->fmrmv, 4); (void)dk4pxres_setup_from_maxval(&(pxr[3]), bif->cf->fmrmv, 8); (void)dk4pxres_setup_from_maxval(&(pxr[4]), bif->cf->fmrmv, 12); } } /* Obtain image dimensions */ w = dk4bif_get_width(bif); h = dk4bif_get_height(bif); /* Traverse image */ for (y = 0; ((0 != cc) && (y < h)); y++) { for (x = 0; ((0 != cc) && (x < w)); x++) { changed = 0; if (0 != dk4bif_get_pixel(pix, 8, bif, y, x, ori_cs)) { /* Implementation, do the checks */ switch (ori_cs) { case DK4_CS_GRAY : { if (0 != anb) { dk4bif_ana_bd(pxr, pxo, &changed, pix[0], ori_bd); } } break; case DK4_CS_GRAY_ALPHA : { if (0 != anb) { dk4bif_ana_bd(pxr, pxo, &changed, pix[0], ori_bd); dk4bif_ana_bd(pxr, pxo, &changed, pix[1], ori_bd); } if (0 != ana) { if (0 == f_alp) { if (max > pix[1]) { f_alp = 1; changed = 1; } } } } break; case DK4_CS_RGB : { if (0 != anb) { dk4bif_ana_bd(pxr, pxo, &changed, pix[0], ori_bd); dk4bif_ana_bd(pxr, pxo, &changed, pix[1], ori_bd); dk4bif_ana_bd(pxr, pxo, &changed, pix[2], ori_bd); } if (0 != anc) { if (0 == f_col) { if (pix[0] != pix[1]) { f_col = 1; changed = 1; } if (pix[0] != pix[2]) { f_col = 1; changed = 1; } } } } break; case DK4_CS_RGB_ALPHA : { if (0 != anb) { dk4bif_ana_bd(pxr, pxo, &changed, pix[0], ori_bd); dk4bif_ana_bd(pxr, pxo, &changed, pix[1], ori_bd); dk4bif_ana_bd(pxr, pxo, &changed, pix[2], ori_bd); dk4bif_ana_bd(pxr, pxo, &changed, pix[3], ori_bd); } if (0 != anc) { if (0 == f_col) { if (pix[0] != pix[1]) { f_col = 1; changed = 1; } if (pix[0] != pix[2]) { f_col = 1; changed = 1; } } } if (0 != ana) { if (0 == f_alp) { if (max > pix[3]) { f_alp = 1; changed = 1; } } } } break; case DK4_CS_CMYK : { if (0 != anb) { dk4bif_ana_bd(pxr, pxo, &changed, pix[0], ori_bd); dk4bif_ana_bd(pxr, pxo, &changed, pix[1], ori_bd); dk4bif_ana_bd(pxr, pxo, &changed, pix[2], ori_bd); dk4bif_ana_bd(pxr, pxo, &changed, pix[3], ori_bd); } if (0 != anc) { if (0 == f_col) { if (0 < pix[0]) { f_col = 1; changed = 1; } if (0 < pix[1]) { f_col = 1; changed = 1; } if (0 < pix[2]) { f_col = 1; changed = 1; } } } } break; } } else { cc = 0; back = 0; dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } /* Check whether we must continue */ if (0 != changed) { cc = 0; if ((0 != ana) && (0 == f_alp)) { cc = 1; } else { if ((0 != anc) && (0 == f_col)) { cc = 1; } else { if (12 < ori_bd) { if (0 != pxo[4]) { cc = 1; } if (0 != pxo[3]) { cc = 1; } if (0 != pxo[2]) { cc = 1; } if (0 != pxo[1]) { cc = 1; } if (0 != pxo[0]) { cc = 1; } } else { if (8 < ori_bd) { if (0 != pxo[3]) { cc = 1; } if (0 != pxo[2]) { cc = 1; } if (0 != pxo[1]) { cc = 1; } if (0 != pxo[0]) { cc = 1; } } else { if (4 < ori_bd) { if (0 != pxo[2]) { cc = 1; } if (0 != pxo[1]) { cc = 1; } if (0 != pxo[0]) { cc = 1; } } else { if (2 < ori_bd) { if (0 != pxo[1]) { cc = 1; } if (0 != pxo[0]) { cc = 1; } } else { if (1 < ori_bd) { if (0 != pxo[0]) { cc = 1; } } } } } } } } } } } /* Transfer results to result variables */ if (0 != back) { if (NULL != pcs) { /* Set result color space */ switch (ori_cs) { case DK4_CS_GRAY : { *pcs = DK4_CS_GRAY; } break; case DK4_CS_GRAY_ALPHA : { if ((0 != f_alp) || (0 == ana)) { *pcs = DK4_CS_GRAY_ALPHA; } else { *pcs = DK4_CS_GRAY; } } break; case DK4_CS_RGB : { if (0 != f_col) { *pcs = DK4_CS_RGB; } else { *pcs = DK4_CS_GRAY; } } break; case DK4_CS_RGB_ALPHA : { if ((0 != f_alp) || (0 == ana)) { if (0 != f_col) { *pcs = DK4_CS_RGB_ALPHA; } else { *pcs = DK4_CS_GRAY_ALPHA; } } else { if (0 != f_col) { *pcs = DK4_CS_RGB; } else { *pcs = DK4_CS_GRAY; } } } break; case DK4_CS_CMYK : { if (0 != f_col) { *pcs = DK4_CS_CMYK; } else { *pcs = DK4_CS_GRAY; } } break; } } if (NULL != pbd) { /* Set result bit depth */ if (0 != pxo[0]) { *pbd = 1; } else { if (0 != pxo[1]) { *pbd = 2; } else { if (0 != pxo[2]) { *pbd = 4; } else { if (0 != pxo[3]) { *pbd = 8; } else { if (0 != pxo[4]) { *pbd = 12; } else { if (1 < ori_bd) { if (2 < ori_bd) { if (4 < ori_bd) { if (8 < ori_bd) { *pbd = 12; } else { *pbd = 8; } } else { *pbd = 4; } } else { *pbd = 2; } } else { *pbd = 1; } } } } } } } } finished: #if TRACE_DEBUG if (NULL != pcs) { #line 556 "dk4bifa.ctr" } if (NULL != pbd) { #line 559 "dk4bifa.ctr" } #endif #line 562 "dk4bifa.ctr" return back; } /* vim: set ai sw=4 ts=4 : */