diff options
Diffstat (limited to 'converter/other')
-rw-r--r-- | converter/other/bmptopnm.c | 6 | ||||
-rw-r--r-- | converter/other/cameratopam/camera.c | 6 | ||||
-rw-r--r-- | converter/other/cameratopam/foveon.c | 2 | ||||
-rw-r--r-- | converter/other/fiasco/codec/approx.c | 563 | ||||
-rw-r--r-- | converter/other/pamtosvg/vector.c | 2 | ||||
-rw-r--r-- | converter/other/pamtotiff.c | 81 | ||||
-rw-r--r-- | converter/other/svgtopam.c | 253 | ||||
-rw-r--r-- | converter/other/tifftopnm.c | 2 |
8 files changed, 483 insertions, 432 deletions
diff --git a/converter/other/bmptopnm.c b/converter/other/bmptopnm.c index 49e730fd..018b8326 100644 --- a/converter/other/bmptopnm.c +++ b/converter/other/bmptopnm.c @@ -1400,8 +1400,8 @@ isValidBmpBpp(unsigned int const cBitCount) { static void readBmp(FILE * const ifP, unsigned char *** const bmpRasterP, - int * const colsP, - int * const rowsP, + unsigned int * const colsP, + unsigned int * const rowsP, bool * const grayPresentP, bool * const colorPresentP, unsigned int * const cBitCountP, @@ -1566,7 +1566,7 @@ main(int argc, const char ** argv) { black and white and whether it has colors other than black, white, and gray. */ - int cols, rows; + unsigned int cols, rows; unsigned char ** bmpRaster; /* The raster part of the BMP image, as a row x column array, with each element being a raw byte from the BMP raster. Note that diff --git a/converter/other/cameratopam/camera.c b/converter/other/cameratopam/camera.c index 503551f1..f6196777 100644 --- a/converter/other/cameratopam/camera.c +++ b/converter/other/cameratopam/camera.c @@ -1023,6 +1023,7 @@ static void sony_decrypt (unsigned *data, int len, int start, int key) { static uint32_t pad[128]; unsigned int p; + unsigned int i; if (start) { for (p=0; p < 4; p++) @@ -1047,8 +1048,9 @@ static void sony_decrypt (unsigned *data, int len, int start, int key) pad[p] = u.word; } } - while (len--) - *data++ ^= pad[p++ & 0x7f] = pad[(p+1) & 0x7f] ^ pad[(p+65) & 0x7f]; + for (i = 0, p = 0; i < len; ++i, ++p) { + *data++ ^= pad[p & 0x7f] = pad[(p+1) & 0x7f] ^ pad[(p+65) & 0x7f]; + } } void diff --git a/converter/other/cameratopam/foveon.c b/converter/other/cameratopam/foveon.c index a3e5449a..992f3883 100644 --- a/converter/other/cameratopam/foveon.c +++ b/converter/other/cameratopam/foveon.c @@ -1,6 +1,6 @@ /* This code is licensed to the public by its copyright owners under GPL. */ -#define _XOPEN_SOURCE /* get M_PI */ +#define _XOPEN_SOURCE 500 /* get M_PI in math.h */ #include <stdio.h> #include <assert.h> diff --git a/converter/other/fiasco/codec/approx.c b/converter/other/fiasco/codec/approx.c index d47bac62..d8fefcaa 100644 --- a/converter/other/fiasco/codec/approx.c +++ b/converter/other/fiasco/codec/approx.c @@ -294,9 +294,9 @@ static bool_t used [MAXSTATES]; static void matching_pursuit (mp_t *mp, bool_t full_search, real_t price, - unsigned max_edges, int y_state, const range_t *range, - const domain_pool_t *domain_pool, const coeff_t *coeff, - const wfa_t *wfa, const coding_t *c) + unsigned max_edges, int y_state, const range_t *range, + const domain_pool_t *domain_pool, const coeff_t *coeff, + const wfa_t *wfa, const coding_t *c) /* * Find an approximation of the current 'range' with a linear * combination of vectors of the 'domain_pool'. The linear @@ -320,303 +320,310 @@ matching_pursuit (mp_t *mp, bool_t full_search, real_t price, * vectors, factors, rate, distortion and costs are stored in 'mp' */ { - unsigned n; /* current vector of the OB */ - int index; /* best fitting domain image */ - unsigned domain; /* counter */ - real_t norm; /* norm of range image */ - real_t additional_bits; /* bits for mc, nd, and tree */ - word_t *domain_blocks; /* current set of domain images */ - const real_t min_norm = 2e-3; /* lower bound of norm */ - unsigned best_n = 0; - unsigned size = size_of_level (range->level); + unsigned n; /* current vector of the OB */ + int index; /* best fitting domain image */ + unsigned domain; /* counter */ + real_t norm; /* norm of range image */ + real_t additional_bits; /* bits for mc, nd, and tree */ + word_t *domain_blocks; /* current set of domain images */ + const real_t min_norm = 2e-3; /* lower bound of norm */ + unsigned best_n = 0; + unsigned size = size_of_level (range->level); - /* - * Initialize domain pool and inner product arrays - */ - domain_blocks = domain_pool->generate (range->level, y_state, wfa, - domain_pool->model); - for (domain = 0; domain_blocks [domain] >= 0; domain++) - { - used [domain] = NO; - rem_denominator [domain] /* norm of domain */ - = get_ip_state_state (domain_blocks [domain], domain_blocks [domain], - range->level, c); - if (rem_denominator [domain] / size < min_norm) - used [domain] = YES; /* don't use domains with small norm */ - else - rem_numerator [domain] /* inner product <s_domain, b> */ - = get_ip_image_state (range->image, range->address, - range->level, domain_blocks [domain], c); - if (!used [domain] && fabs (rem_numerator [domain]) < min_norm) - used [domain] = YES; - } + /* + * Initialize domain pool and inner product arrays + */ + domain_blocks = domain_pool->generate (range->level, y_state, wfa, + domain_pool->model); + for (domain = 0; domain_blocks [domain] >= 0; domain++) + { + used [domain] = NO; + rem_denominator [domain] = /* norm of domain */ + get_ip_state_state (domain_blocks [domain], domain_blocks [domain], + range->level, c); + if (rem_denominator [domain] / size < min_norm) + used [domain] = YES; /* don't use domains with small norm */ + else + rem_numerator [domain] /* inner product <s_domain, b> */ + = get_ip_image_state (range->image, range->address, + range->level, domain_blocks [domain], c); + if (!used [domain] && fabs (rem_numerator [domain]) < min_norm) + used [domain] = YES; + } - /* - * Exclude all domain blocks given in array 'mp->exclude' - */ - for (n = 0; isdomain (mp->exclude [n]); n++) - used [mp->exclude [n]] = YES; + /* + * Exclude all domain blocks given in array 'mp->exclude' + */ + for (n = 0; isdomain (mp->exclude [n]); n++) + used [mp->exclude [n]] = YES; - /* - * Compute the approximation costs if 'range' is approximated with - * no linear combination, i.e. the error is equal to the square - * of the image norm and the size of the automaton is determined by - * storing only zero elements in the current matrix row - */ - for (norm = 0, n = 0; n < size; n++) - norm += square (c->pixels [range->address * size + n]); - - additional_bits = range->tree_bits + range->mv_tree_bits - + range->mv_coord_bits + range->nd_tree_bits - + range->nd_weights_bits; - - mp->err = norm; - mp->weights_bits = 0; - mp->matrix_bits = domain_pool->bits (domain_blocks, NULL, range->level, - y_state, wfa, domain_pool->model); - mp->costs = (mp->matrix_bits + mp->weights_bits - + additional_bits) * price + mp->err; - - n = 0; - do - { - /* - * Current approximation is: b = d_0 o_0 + ... + d_(n-1) o_(n-1) - * with corresponding costs 'range->err + range->bits * p'. - * For all remaining state images s_i (used[s_i] == NO) set - * o_n : = s_i - \sum(k = 0, ... , n-1) {(<s_i, o_k> / ||o_k||^2) o_k} - * and try to beat current costs. - * Choose that vector for the next orthogonalization step, - * which has minimal costs: s_index. - * (No progress is indicated by index == -1) - */ - - real_t min_matrix_bits = 0; - real_t min_weights_bits = 0; - real_t min_error = 0; - real_t min_weight [MAXEDGES]; - real_t min_costs = full_search ? MAXCOSTS : mp->costs; - - for (index = -1, domain = 0; domain_blocks [domain] >= 0; domain++) - if (!used [domain]) - { - real_t matrix_bits, weights_bits; + /* + * Compute the approximation costs if 'range' is approximated with + * no linear combination, i.e. the error is equal to the square + * of the image norm and the size of the automaton is determined by + * storing only zero elements in the current matrix row + */ + for (norm = 0, n = 0; n < size; n++) + norm += square (c->pixels [range->address * size + n]); + + additional_bits = range->tree_bits + range->mv_tree_bits + + range->mv_coord_bits + range->nd_tree_bits + + range->nd_weights_bits; + + mp->err = norm; + mp->weights_bits = 0; + mp->matrix_bits = domain_pool->bits (domain_blocks, NULL, range->level, + y_state, wfa, domain_pool->model); + mp->costs = (mp->matrix_bits + mp->weights_bits + + additional_bits) * price + mp->err; + + n = 0; + do + { /* - * To speed up the search through the domain images, - * the costs of using domain image 'domain' as next vector - * can be approximated in a first step: - * improvement of image quality - * <= square (rem_numerator[domain]) / rem_denominator[domain] + * Current approximation is: b = d_0 o_0 + ... + d_(n-1) o_(n-1) + * with corresponding costs 'range->err + range->bits * p'. + * For all remaining state images s_i (used[s_i] == NO) set + * o_n : = s_i - \sum(k = 0, ... , n-1) {(<s_i, o_k> / ||o_k||^2) o_k} + * and try to beat current costs. + * Choose that vector for the next orthogonalization step, + * which has minimal costs: s_index. + * (No progress is indicated by index == -1) */ - { - word_t vectors [MAXEDGES + 1]; - word_t states [MAXEDGES + 1]; - real_t weights [MAXEDGES + 1]; - unsigned i, k; + + real_t min_matrix_bits = 0; + real_t min_weights_bits = 0; + real_t min_error = 0; + real_t min_weight [MAXEDGES]; + real_t min_costs = full_search ? MAXCOSTS : mp->costs; + + for (index = -1, domain = 0; domain_blocks [domain] >= 0; domain++) + if (!used [domain]) + { + real_t matrix_bits, weights_bits; + /* + * To speed up the search through the domain images, + * the costs of using domain image 'domain' as next vector + * can be approximated in a first step: + * improvement of image quality + * <= square (rem_numerator[domain]) / rem_denominator[domain] + */ + { + word_t vectors [MAXEDGES + 1]; + word_t states [MAXEDGES + 1]; + real_t weights [MAXEDGES + 1]; + unsigned i, k; - for (i = 0, k = 0; k < n; k++) - if (mp->weight [k] != 0) - { - vectors [i] = mp->indices [k]; - states [i] = domain_blocks [vectors [i]]; - weights [i] = mp->weight [k]; - i++; - } - vectors [i] = domain; - states [i] = domain_blocks [domain]; - weights [i] = 0.5; - vectors [i + 1] = -1; - states [i + 1] = -1; - - weights_bits = coeff->bits (weights, states, range->level, - coeff); - matrix_bits = domain_pool->bits (domain_blocks, vectors, - range->level, y_state, - wfa, domain_pool->model); - } - if (((matrix_bits + weights_bits + additional_bits) * price + - mp->err - - square (rem_numerator [domain]) / rem_denominator [domain]) - < min_costs) - { - /* - * 1.) Compute the weights (linear factors) c_i of the - * linear combination - * b = c_0 v_0 + ... + c_(n-1) v_(n-1) + c_n v_'domain' - * Use backward substitution to obtain c_i from the linear - * factors of the lin. comb. b = d_0 o_0 + ... + d_n o_n - * of the corresponding orthogonal vectors {o_0, ..., o_n}. - * Vector o_n of the orthogonal basis is obtained by using - * vector 'v_domain' in step n of the Gram Schmidt - * orthogonalization (see above for definition of o_n). - * Recursive formula for the coefficients c_i: - * c_n := <b, o_n> / ||o_n||^2 - * for i = n - 1, ... , 0: - * c_i := <b, o_i> / ||o_i||^2 + - * \sum (k = i + 1, ... , n){ c_k <v_k, o_i> - * / ||o_i||^2 } - * 2.) Because linear factors are stored with reduced precision - * factor c_i is rounded with the given precision in step i - * of the recursive formula. - */ - - unsigned k; /* counter */ - int l; /* counter */ - real_t m_bits; /* number of matrix bits to store */ - real_t w_bits; /* number of weights bits to store */ - real_t r [MAXEDGES]; /* rounded linear factors */ - real_t f [MAXEDGES]; /* linear factors */ - int v [MAXEDGES]; /* mapping of domains to vectors */ - real_t costs; /* current approximation costs */ - real_t m_err; /* current approximation error */ - - f [n] = rem_numerator [domain] / rem_denominator [domain]; - v [n] = domain; /* corresponding mapping */ - for (k = 0; k < n; k++) - { - f [k] = ip_image_ortho_vector [k] / norm_ortho_vector [k]; - v [k] = mp->indices [k]; - } + for (i = 0, k = 0; k < n; k++) + if (mp->weight [k] != 0) + { + vectors [i] = mp->indices [k]; + states [i] = domain_blocks [vectors [i]]; + weights [i] = mp->weight [k]; + i++; + } + vectors [i] = domain; + states [i] = domain_blocks [domain]; + weights [i] = 0.5; + vectors [i + 1] = -1; + states [i + 1] = -1; + + weights_bits = coeff->bits (weights, states, range->level, + coeff); + matrix_bits = domain_pool->bits (domain_blocks, vectors, + range->level, y_state, + wfa, domain_pool->model); + } + if (((matrix_bits + weights_bits + additional_bits) * price + + mp->err - + square (rem_numerator[domain]) / rem_denominator[domain]) + < min_costs) + { + /* + * 1.) Compute the weights (linear factors) c_i of the + * linear combination + * b = c_0 v_0 + ... + c_(n-1) v_(n-1) + c_n v_'domain' + * Use backward substitution to obtain c_i from the linear + * factors of the lin. comb. b = d_0 o_0 + ... + d_n o_n + * of the corresponding orthogonal vectors {o_0, ..., o_n}. + * Vector o_n of the orthogonal basis is obtained by using + * vector 'v_domain' in step n of the Gram Schmidt + * orthogonalization (see above for definition of o_n). + * Recursive formula for the coefficients c_i: + * c_n := <b, o_n> / ||o_n||^2 + * for i = n - 1, ... , 0: + * c_i := <b, o_i> / ||o_i||^2 + + * \sum (k = i + 1, ... , n){ c_k <v_k, o_i> + * / ||o_i||^2 } + * 2.) Because linear factors are stored with reduced + * precision factor c_i is rounded with the given + * precision in step i of the recursive formula. + */ + + unsigned k; /* counter */ + int l; /* counter */ + real_t m_bits; /* number of matrix bits to store */ + real_t w_bits; /* number of weights bits to store */ + real_t r [MAXEDGES]; /* rounded linear factors */ + real_t f [MAXEDGES]; /* linear factors */ + int v [MAXEDGES]; /* mapping of domains to vectors*/ + real_t costs; /* current approximation costs */ + real_t m_err; /* current approximation error */ + + f [n] = rem_numerator [domain] / rem_denominator [domain]; + v [n] = domain; /* corresponding mapping */ + for (k = 0; k < n; k++) + { + f[k] = ip_image_ortho_vector[k] / norm_ortho_vector[k]; + v [k] = mp->indices [k]; + } - for (l = n; l >= 0; l--) - { - rpf_t *rpf = domain_blocks [v [l]] - ? coeff->rpf : coeff->dc_rpf; + for (l = n; l >= 0; --l) { + rpf_t * const rpf = domain_blocks[v[l]] + ? coeff->rpf : coeff->dc_rpf; + + unsigned int k; - r [l] = f [l] = btor (rtob (f [l], rpf), rpf); + r[l] = f[l] = btor(rtob(f[l], rpf), rpf); + + { + real_t const fl = f[l]; - for (k = 0; k < (unsigned) l; k++) - f [k] -= f [l] * ip_domain_ortho_vector [v [l]][k] - / norm_ortho_vector [k] ; - } - - /* - * Compute the number of output bits of the linear combination - * and store the weights with reduced precision. The - * resulting linear combination is - * b = r_0 v_0 + ... + r_(n-1) v_(n-1) + r_n v_'domain' - */ - { - word_t vectors [MAXEDGES + 1]; - word_t states [MAXEDGES + 1]; - real_t weights [MAXEDGES + 1]; - int i; + for (k = 0; k < l; ++k) { + f[k] -= fl * ip_domain_ortho_vector[v[l]][k] + / norm_ortho_vector[k]; + } + } + } + + /* + * Compute the number of output bits of the linear + * combination and store the weights with reduced + * precision. The resulting linear combination is + * b = r_0 v_0 + ... + r_(n-1) v_(n-1) + r_n v_'domain' + */ + { + word_t vectors [MAXEDGES + 1]; + word_t states [MAXEDGES + 1]; + real_t weights [MAXEDGES + 1]; + int i; - for (i = 0, k = 0; k <= n; k++) - if (f [k] != 0) - { - vectors [i] = v [k]; - states [i] = domain_blocks [v [k]]; - weights [i] = f [k]; - i++; - } - vectors [i] = -1; - states [i] = -1; - - w_bits = coeff->bits (weights, states, range->level, coeff); - m_bits = domain_pool->bits (domain_blocks, vectors, - range->level, y_state, - wfa, domain_pool->model); - } + for (i = 0, k = 0; k <= n; k++) + if (f [k] != 0) + { + vectors [i] = v [k]; + states [i] = domain_blocks [v [k]]; + weights [i] = f [k]; + i++; + } + vectors [i] = -1; + states [i] = -1; + + w_bits = + coeff->bits(weights, states, range->level, coeff); + m_bits = domain_pool->bits (domain_blocks, vectors, + range->level, y_state, + wfa, domain_pool->model); + } - /* - * To compute the approximation error, the corresponding - * linear factors of the linear combination - * b = r_0 o_0 + ... + r_(n-1) o_(n-1) + r_n o_'domain' - * with orthogonal vectors must be computed with following - * formula: - * r_i := r_i + - * \sum (k = i + 1, ... , n) { r_k <v_k, o_i> - * / ||o_i||^2 } - */ - for (l = 0; (unsigned) l <= n; l++) - { - /* - * compute <v_n, o_n> - */ - real_t a; - - a = get_ip_state_state (domain_blocks [v [l]], - domain_blocks [domain], - range->level, c); - for (k = 0; k < n; k++) - a -= ip_domain_ortho_vector [v [l]][k] - / norm_ortho_vector [k] - * ip_domain_ortho_vector [domain][k]; - ip_domain_ortho_vector [v [l]][n] = a; - } - norm_ortho_vector [n] = rem_denominator [domain]; - ip_image_ortho_vector [n] = rem_numerator [domain]; + /* + * To compute the approximation error, the corresponding + * linear factors of the linear combination + * b = r_0 o_0 + ... + r_(n-1) o_(n-1) + r_n o_'domain' + * with orthogonal vectors must be computed with following + * formula: + * r_i := r_i + + * \sum (k = i + 1, ... , n) { r_k <v_k, o_i> + * / ||o_i||^2 } + */ + for (l = 0; (unsigned) l <= n; l++) + { + /* + * compute <v_n, o_n> + */ + real_t a; + + a = get_ip_state_state (domain_blocks [v [l]], + domain_blocks [domain], + range->level, c); + for (k = 0; k < n; k++) + a -= ip_domain_ortho_vector [v [l]][k] + / norm_ortho_vector [k] + * ip_domain_ortho_vector [domain][k]; + ip_domain_ortho_vector [v [l]][n] = a; + } + norm_ortho_vector [n] = rem_denominator [domain]; + ip_image_ortho_vector [n] = rem_numerator [domain]; - for (k = 0; k <= n; k++) - for (l = k + 1; (unsigned) l <= n; l++) - r [k] += ip_domain_ortho_vector [v [l]][k] * r [l] - / norm_ortho_vector [k]; - /* - * Compute approximation error: - * error := ||b||^2 + - * \sum (k = 0, ... , n){r_k^2 ||o_k||^2 - 2 r_k <b, o_k>} - */ - m_err = norm; - for (k = 0; k <= n; k++) - m_err += square (r [k]) * norm_ortho_vector [k] - - 2 * r [k] * ip_image_ortho_vector [k]; - if (m_err < 0) /* TODO: return MAXCOSTS */ - warning ("Negative image norm: %f" - " (current domain: %d, level = %d)", - (double) m_err, domain, range->level); - - costs = (m_bits + w_bits + additional_bits) * price + m_err; - if (costs < min_costs) /* found a better approximation */ - { - index = domain; - min_costs = costs; - min_matrix_bits = m_bits; - min_weights_bits = w_bits; - min_error = m_err; - for (k = 0; k <= n; k++) - min_weight [k] = f [k]; - } - } - } + for (k = 0; k <= n; k++) + for (l = k + 1; (unsigned) l <= n; l++) + r [k] += ip_domain_ortho_vector [v [l]][k] * r [l] + / norm_ortho_vector [k]; + /* + * Compute approximation error: + * error := ||b||^2 + + * \sum (k = 0, ... , n){r_k^2 ||o_k||^2 - 2 r_k <b, o_k>} + */ + m_err = norm; + for (k = 0; k <= n; k++) + m_err += square (r [k]) * norm_ortho_vector [k] + - 2 * r [k] * ip_image_ortho_vector [k]; + if (m_err < 0) /* TODO: return MAXCOSTS */ + warning ("Negative image norm: %f" + " (current domain: %d, level = %d)", + (double) m_err, domain, range->level); + + costs = (m_bits + w_bits + additional_bits) * price + m_err; + if (costs < min_costs) /* found a better approximation */ + { + index = domain; + min_costs = costs; + min_matrix_bits = m_bits; + min_weights_bits = w_bits; + min_error = m_err; + for (k = 0; k <= n; k++) + min_weight [k] = f [k]; + } + } + } - if (index >= 0) /* found a better approximation */ - { - if (min_costs < mp->costs) - { - unsigned k; + if (index >= 0) /* found a better approximation */ + { + if (min_costs < mp->costs) + { + unsigned k; - mp->costs = min_costs; - mp->err = min_error; - mp->matrix_bits = min_matrix_bits; - mp->weights_bits = min_weights_bits; + mp->costs = min_costs; + mp->err = min_error; + mp->matrix_bits = min_matrix_bits; + mp->weights_bits = min_weights_bits; - for (k = 0; k <= n; k++) - mp->weight [k] = min_weight [k]; + for (k = 0; k <= n; k++) + mp->weight [k] = min_weight [k]; - best_n = n + 1; - } + best_n = n + 1; + } - mp->indices [n] = index; - mp->into [n] = domain_blocks [index]; + mp->indices [n] = index; + mp->into [n] = domain_blocks [index]; - used [index] = YES; + used [index] = YES; - /* - * Gram-Schmidt orthogonalization step n - */ - orthogonalize (index, n, range->level, min_norm, domain_blocks, c); - n++; - } - } - while (n < max_edges && index >= 0); + /* + * Gram-Schmidt orthogonalization step n + */ + orthogonalize (index, n, range->level, min_norm, domain_blocks, c); + n++; + } + } + while (n < max_edges && index >= 0); - mp->indices [best_n] = NO_EDGE; + mp->indices [best_n] = NO_EDGE; - mp->costs = (mp->matrix_bits + mp->weights_bits + additional_bits) * price - + mp->err; + mp->costs = (mp->matrix_bits + mp->weights_bits + additional_bits) * price + + mp->err; - Free (domain_blocks); + Free (domain_blocks); } static void diff --git a/converter/other/pamtosvg/vector.c b/converter/other/pamtosvg/vector.c index 0a5ef3a9..771e5f27 100644 --- a/converter/other/pamtosvg/vector.c +++ b/converter/other/pamtosvg/vector.c @@ -1,6 +1,6 @@ /* vector.c: vector/point operations. */ -#define _XOPEN_SOURCE /* Make sure M_PI is in <math.h> */ +#define _XOPEN_SOURCE 500 /* get M_PI in math.h */ #include <math.h> #include <errno.h> #include <assert.h> diff --git a/converter/other/pamtotiff.c b/converter/other/pamtotiff.c index 32057e55..139b1fd7 100644 --- a/converter/other/pamtotiff.c +++ b/converter/other/pamtotiff.c @@ -136,6 +136,44 @@ validateTagList(struct optNameValue const taglist[]) { static void +parseIndexbits(bool const indexbitsSpec, + char ** const indexbits, + CmdlineInfo * const cmdlineP) { + + if (indexbitsSpec) { + unsigned int i; + + /* Set initial values */ + cmdlineP->indexsizeAllowed.b1 = FALSE; + cmdlineP->indexsizeAllowed.b2 = FALSE; + cmdlineP->indexsizeAllowed.b4 = FALSE; + cmdlineP->indexsizeAllowed.b8 = FALSE; + + for (i = 0; indexbits[i]; ++i) { + const char * const thisItem = indexbits[i]; + if (streq(thisItem, "1")) + cmdlineP->indexsizeAllowed.b1 = TRUE; + else if (streq(thisItem, "2")) + cmdlineP->indexsizeAllowed.b2 = TRUE; + else if (streq(thisItem, "4")) + cmdlineP->indexsizeAllowed.b4 = TRUE; + else if (streq(thisItem, "8")) + cmdlineP->indexsizeAllowed.b8 = TRUE; + else + pm_error("Invalid item in -indexbits list: '%s'. " + "We recognize only 1, 2, 4, and 8", thisItem); + } + } else { + cmdlineP->indexsizeAllowed.b1 = FALSE; + cmdlineP->indexsizeAllowed.b2 = FALSE; + cmdlineP->indexsizeAllowed.b4 = FALSE; + cmdlineP->indexsizeAllowed.b8 = TRUE; + } +} + + + +static void parseCommandLine(int argc, const char ** const argv, CmdlineInfo * const cmdlineP) { @@ -149,7 +187,7 @@ parseCommandLine(int argc, unsigned int none, packbits, lzw, g3, g4, msb2lsb, lsb2msb, opt_2d, fill; unsigned int flate, adobeflate; - char * indexbits; + char ** indexbits; char * resolutionunit; unsigned int appendSpec, outputSpec, predictorSpec, rowsperstripSpec, @@ -192,7 +230,7 @@ parseCommandLine(int argc, &yresolutionSpec, 0); OPTENT3(0, "resolutionunit", OPT_STRING, &resolutionunit, &resolutionunitSpec, 0); - OPTENT3(0, "indexbits", OPT_STRING, &indexbits, + OPTENT3(0, "indexbits", OPT_STRINGLIST, &indexbits, &indexbitsSpec, 0); OPTENT3(0, "tag", OPT_NAMELIST, &cmdlineP->taglist, &tagSpec, 0); @@ -302,35 +340,16 @@ parseCommandLine(int argc, } else cmdlineP->resolutionunit = RESUNIT_INCH; - if (indexbitsSpec) { - if (strstr(indexbits, "1")) - cmdlineP->indexsizeAllowed.b1 = TRUE; - else - cmdlineP->indexsizeAllowed.b1 = FALSE; - if (strstr(indexbits, "2")) - cmdlineP->indexsizeAllowed.b2 = TRUE; - else - cmdlineP->indexsizeAllowed.b2 = FALSE; - if (strstr(indexbits, "4")) - cmdlineP->indexsizeAllowed.b4 = TRUE; - else - cmdlineP->indexsizeAllowed.b4 = FALSE; - if (strstr(indexbits, "8")) - cmdlineP->indexsizeAllowed.b8 = TRUE; - else - cmdlineP->indexsizeAllowed.b8 = FALSE; - } else { - cmdlineP->indexsizeAllowed.b1 = FALSE; - cmdlineP->indexsizeAllowed.b2 = FALSE; - cmdlineP->indexsizeAllowed.b4 = FALSE; - cmdlineP->indexsizeAllowed.b8 = TRUE; - } + parseIndexbits(indexbitsSpec, indexbits, cmdlineP); + + if (indexbitsSpec) + free(indexbits); if (tagSpec) validateTagList(cmdlineP->taglist); else { MALLOCARRAY_NOFAIL(cmdlineP->taglist, 1); - cmdlineP->taglist[0].name = NULL; + cmdlineP->taglist[0].name = NULL; cmdlineP->taglist[0].value = NULL; } @@ -346,6 +365,14 @@ parseCommandLine(int argc, static void +freeCmdline(CmdlineInfo const cmdline) { + + pm_optDestroyNameValueList(cmdline.taglist); +} + + + +static void fillRowOfSubBytePixels(struct pam * const pamP, const tuple * const tuplerow, unsigned char * const buf, @@ -1280,6 +1307,8 @@ main(int argc, const char *argv[]) { closeTiffGenerator(cmdline.writeMethod, tifP, ofd); pm_close(ifP); + freeCmdline(cmdline); + return 0; } diff --git a/converter/other/svgtopam.c b/converter/other/svgtopam.c index 09e3a24e..ca6f4dc7 100644 --- a/converter/other/svgtopam.c +++ b/converter/other/svgtopam.c @@ -147,36 +147,36 @@ typedef struct { unsigned int height; pixel ** pixels; pixval maxval; -} canvas; +} Canvas; typedef struct { pixel fillColor; -} style; +} Style; typedef struct { const char * pathText; /* This is e.g. "M0 0 L1 1 L9 8 Z" */ - style style; + Style style; /* This is the style as given by a 'style' attribute of <path> */ unsigned int pathTextLength; /* This is the length in characters of 'pathText'. It's redundant with 'pathText' and exists for convenience. */ -} path; +} Path; static void createPath(const char * const pathText, - style const style, - path ** const pathPP) { + Style const style, + Path ** const pathPP) { /*---------------------------------------------------------------------------- Create a path as described by a <path> element whose "style" attribute indicates style 'style' and whose "d" attribute indicates path data 'pathText'. -----------------------------------------------------------------------------*/ bool error; - path * pathP; + Path * pathP; MALLOCVAR(pathP); if (pathP == NULL) @@ -204,7 +204,7 @@ createPath(const char * const pathText, static void -destroyPath(path * const pathP) { +destroyPath(Path * const pathP) { assert(pathP->pathTextLength == strlen(pathP->pathText)); @@ -218,13 +218,13 @@ destroyPath(path * const pathP) { typedef struct { unsigned int x; unsigned int y; -} point; +} Point; -static point +static Point makePoint(unsigned int const x, unsigned int const y) { - point p; + Point p; p.x = x; p.y = y; @@ -233,7 +233,7 @@ makePoint(unsigned int const x, } static ppmd_point -makePpmdPoint(point const arg) { +makePpmdPoint(Point const arg) { ppmd_point p; @@ -248,16 +248,16 @@ typedef enum { PATH_LINETO, PATH_CLOSEPATH, PATH_CUBIC -} pathCommandVerb; +} PathCommandVerb; typedef struct { - point dest; -} pathMovetoArgs; + Point dest; +} PathMovetoArgs; typedef struct { /* Draw a line segment from current point to 'dest' */ - point dest; -} pathLinetoArgs; + Point dest; +} PathLinetoArgs; typedef struct { /* Draw a cubic spline from current point to 'dest' with control points @@ -272,19 +272,19 @@ typedef struct { A cubic curve is a plot of a polynomial equation of degree 3 (or less, for our purposes). */ - point dest; - point ctl1; - point ctl2; -} pathCubicArgs; + Point dest; + Point ctl1; + Point ctl2; +} PathCubicArgs; typedef struct { - pathCommandVerb verb; + PathCommandVerb verb; union { - pathMovetoArgs moveto; - pathLinetoArgs lineto; - pathCubicArgs cubic; + PathMovetoArgs moveto; + PathLinetoArgs lineto; + PathCubicArgs cubic; } args; -} pathCommand; +} PathCommand; @@ -292,15 +292,15 @@ typedef struct { /*---------------------------------------------------------------------------- This is an object for reading through a path from beginning to end. -----------------------------------------------------------------------------*/ - path * pathP; + Path * pathP; unsigned int cursor; -} pathReader; +} PathReader; static void -createPathReader(path * const pathP, - pathReader ** const pathReaderPP) { +pathReader_create(Path * const pathP, + PathReader ** const pathReaderPP) { - pathReader * pathReaderP; + PathReader * pathReaderP; MALLOCVAR_NOFAIL(pathReaderP); @@ -311,18 +311,31 @@ createPathReader(path * const pathP, } static void -destroyPathReader(pathReader * const pathReaderP) { +pathReader_destroy(PathReader * const pathReaderP) { free(pathReaderP); } +static const char * +pathReader_context(PathReader * const pathReaderP) { + + const char * retval; + + pm_asprintf(&retval, "Character position %u (starting at 0) in '%s'", + pathReaderP->cursor, pathReaderP->pathP->pathText); + + return retval; +} + + + static void -skipWhiteSpace(pathReader * const pathReaderP) { +pathReader_skipWhiteSpace(PathReader * const pathReaderP) { /*---------------------------------------------------------------------------- Move the cursor over any white space where it now points. -----------------------------------------------------------------------------*/ - const path * const pathP = pathReaderP->pathP; + const Path * const pathP = pathReaderP->pathP; while (isspace(pathP->pathText[pathReaderP->cursor]) && pathReaderP->cursor < pathP->pathTextLength) @@ -332,10 +345,10 @@ skipWhiteSpace(pathReader * const pathReaderP) { static void -getNumber(pathReader * const pathReaderP, - unsigned int * const numberP) { +pathReader_getNumber(PathReader * const pathReaderP, + unsigned int * const numberP) { - const path * const pathP = pathReaderP->pathP; + const Path * const pathP = pathReaderP->pathP; const char * const pathText = pathP->pathText; size_t const pathTextLength = pathP->pathTextLength; @@ -343,7 +356,10 @@ getNumber(pathReader * const pathReaderP, if (pathReaderP->cursor >= pathTextLength) pm_error("Path description ends where a number was expected."); - else { + else if (!isdigit(pathText[pathReaderP->cursor])) { + pm_error("Character '%c' instead of a digit where number expected", + pathText[pathReaderP->cursor]); + } else { unsigned int number; number = 0; /* initial value */ @@ -353,6 +369,10 @@ getNumber(pathReader * const pathReaderP, number = 10 * number + (pathText[pathReaderP->cursor] - '0'); ++pathReaderP->cursor; } + if (pathText[pathReaderP->cursor] == '.') + pm_error("Number contains decimal point. This program does not " + "know how to deal with fractional positions"); + *numberP = number; } } @@ -360,15 +380,15 @@ getNumber(pathReader * const pathReaderP, static void -getNextCommand(pathReader * const pathReaderP, - pathCommand * const pathCommandP, - bool * const endOfPathP) { +pathReader_getNextCommand(PathReader * const pathReaderP, + PathCommand * const pathCommandP, + bool * const endOfPathP) { - const path * const pathP = pathReaderP->pathP; + const Path * const pathP = pathReaderP->pathP; const char * const pathText = pathP->pathText; size_t const pathTextLength = pathP->pathTextLength; - skipWhiteSpace(pathReaderP); + pathReader_skipWhiteSpace(pathReaderP); if (pathReaderP->cursor >= pathTextLength) *endOfPathP = true; @@ -376,67 +396,79 @@ getNextCommand(pathReader * const pathReaderP, switch (pathText[pathReaderP->cursor++]) { case 'M': pathCommandP->verb = PATH_MOVETO; - skipWhiteSpace(pathReaderP); - getNumber(pathReaderP, &pathCommandP->args.moveto.dest.x); - skipWhiteSpace(pathReaderP); - getNumber(pathReaderP, &pathCommandP->args.moveto.dest.y); + pathReader_skipWhiteSpace(pathReaderP); + pathReader_getNumber(pathReaderP, + &pathCommandP->args.moveto.dest.x); + pathReader_skipWhiteSpace(pathReaderP); + pathReader_getNumber(pathReaderP, + &pathCommandP->args.moveto.dest.y); break; case 'L': pathCommandP->verb = PATH_LINETO; - skipWhiteSpace(pathReaderP); - getNumber(pathReaderP, &pathCommandP->args.lineto.dest.x); - skipWhiteSpace(pathReaderP); - getNumber(pathReaderP, &pathCommandP->args.lineto.dest.y); + pathReader_skipWhiteSpace(pathReaderP); + pathReader_getNumber(pathReaderP, + &pathCommandP->args.lineto.dest.x); + pathReader_skipWhiteSpace(pathReaderP); + pathReader_getNumber(pathReaderP, + &pathCommandP->args.lineto.dest.y); break; case 'C': pathCommandP->verb = PATH_CUBIC; - skipWhiteSpace(pathReaderP); - getNumber(pathReaderP, &pathCommandP->args.cubic.ctl1.x); - skipWhiteSpace(pathReaderP); - getNumber(pathReaderP, &pathCommandP->args.cubic.ctl1.y); - skipWhiteSpace(pathReaderP); - getNumber(pathReaderP, &pathCommandP->args.cubic.ctl2.x); - skipWhiteSpace(pathReaderP); - getNumber(pathReaderP, &pathCommandP->args.cubic.ctl2.y); - skipWhiteSpace(pathReaderP); - getNumber(pathReaderP, &pathCommandP->args.cubic.dest.x); - skipWhiteSpace(pathReaderP); - getNumber(pathReaderP, &pathCommandP->args.cubic.dest.y); + pathReader_skipWhiteSpace(pathReaderP); + pathReader_getNumber(pathReaderP, &pathCommandP->args.cubic.ctl1.x); + pathReader_skipWhiteSpace(pathReaderP); + pathReader_getNumber(pathReaderP, &pathCommandP->args.cubic.ctl1.y); + pathReader_skipWhiteSpace(pathReaderP); + pathReader_getNumber(pathReaderP, &pathCommandP->args.cubic.ctl2.x); + pathReader_skipWhiteSpace(pathReaderP); + pathReader_getNumber(pathReaderP, &pathCommandP->args.cubic.ctl2.y); + pathReader_skipWhiteSpace(pathReaderP); + pathReader_getNumber(pathReaderP, &pathCommandP->args.cubic.dest.x); + pathReader_skipWhiteSpace(pathReaderP); + pathReader_getNumber(pathReaderP, &pathCommandP->args.cubic.dest.y); break; case 'z': pathCommandP->verb = PATH_CLOSEPATH; break; - default: - pm_error("Unrecognized command in <path>: '%c'", - pathText[pathReaderP->cursor++]); + default: { + const char * const context = pathReader_context(pathReaderP); + + pm_errormsg("Unrecognized command in <path>: '%c'. %s", + pathText[pathReaderP->cursor++], context); + + pm_strfree(context); + + pm_longjmp(); + } } } } + static void -outlineObject(path * const pathP, +outlineObject(Path * const pathP, struct fillobj * const fillObjP) { /*---------------------------------------------------------------------------- Create a fill object, which contains and outline of the object and can be used with ppmd_fill() to fill the figure. The outline is as described by *pathP. -----------------------------------------------------------------------------*/ - pathReader * pathReaderP; + PathReader * pathReaderP; bool endOfPath; - point currentPos; - point subpathStart; + Point currentPos; + Point subpathStart; /* Point at which the current subpath starts */ endOfPath = false; subpathStart = makePoint(0,0); currentPos = subpathStart; - createPathReader(pathP, &pathReaderP); + pathReader_create(pathP, &pathReaderP); while (!endOfPath) { - pathCommand pathCommand; - getNextCommand(pathReaderP, &pathCommand, &endOfPath); + PathCommand pathCommand; + pathReader_getNextCommand(pathReaderP, &pathCommand, &endOfPath); if (!endOfPath) { switch (pathCommand.verb) { case PATH_MOVETO: @@ -448,7 +480,7 @@ outlineObject(path * const pathP, currentPos = subpathStart; break; case PATH_LINETO: { - point const dest = pathCommand.args.lineto.dest; + Point const dest = pathCommand.args.lineto.dest; if (traceDraw) pm_message("Lining to (%u, %u)", dest.x, dest.y); ppmd_line(NULL, 0, 0, 0, @@ -466,12 +498,14 @@ outlineObject(path * const pathP, currentPos = subpathStart; break; case PATH_CUBIC: { - point const dest = pathCommand.args.cubic.dest; - point const ctl1 = pathCommand.args.cubic.ctl1; - point const ctl2 = pathCommand.args.cubic.ctl2; + Point const dest = pathCommand.args.cubic.dest; + Point const ctl1 = pathCommand.args.cubic.ctl1; + Point const ctl2 = pathCommand.args.cubic.ctl2; if (traceDraw) pm_message("Doing cubic spline to (%u, %u)", dest.x, dest.y); + pm_error("SVG image contains a cubic spline path. " + "This program cannot process cubic splines."); /* We need to write ppmd_spline4() */ ppmd_spline4p(NULL, 0, 0, 0, makePpmdPoint(currentPos), @@ -484,14 +518,14 @@ outlineObject(path * const pathP, } } } - destroyPathReader(pathReaderP); + pathReader_destroy(pathReaderP); } static void -drawPath(canvas * const canvasP, - path * const pathP) { +drawPath(Canvas * const canvasP, + Path * const pathP) { /*---------------------------------------------------------------------------- Draw the path 'pathP' on the canvas 'canvasP'. -----------------------------------------------------------------------------*/ @@ -518,10 +552,10 @@ drawPath(canvas * const canvasP, -static style +static Style interpretStyle(const char * const styleAttr) { - style style; + Style style; char * buffer; @@ -582,7 +616,7 @@ interpretStyle(const char * const styleAttr) { static void getPathAttributes(xmlTextReaderPtr const xmlReaderP, - style * const styleP, + Style * const styleP, const char ** const pathP) { const char * const style = getAttribute(xmlReaderP, "style"); @@ -628,11 +662,11 @@ processSubPathNode(xmlTextReaderPtr const xmlReaderP, static void processPathElement(xmlTextReaderPtr const xmlReaderP, - canvas * const canvasP) { + Canvas * const canvasP) { - style style; + Style style; const char * pathData; - path * pathP; + Path * pathP; bool endOfPath; assert(xmlTextReaderNodeType(xmlReaderP) == XML_READER_TYPE_ELEMENT); @@ -670,29 +704,6 @@ processPathElement(xmlTextReaderPtr const xmlReaderP, static void -stringToUint(const char * const string, - unsigned int * const uintP, - const char ** const errorP) { - - /* TODO: move this to nstring.c */ - - if (strlen(string) == 0) - pm_asprintf(errorP, "Value is a null string"); - else { - char * tailptr; - - *uintP = strtoul(string, &tailptr, 10); - - if (*tailptr != '\0') - pm_asprintf(errorP, "Non-numeric crap in string: '%s'", tailptr); - else - *errorP = NULL; - } -} - - - -static void getSvgAttributes(xmlTextReaderPtr const xmlReaderP, unsigned int * const colsP, unsigned int * const rowsP) { @@ -702,14 +713,16 @@ getSvgAttributes(xmlTextReaderPtr const xmlReaderP, const char * error; - stringToUint(width, colsP, &error); + pm_string_to_uint(width, colsP, &error); if (error) { - pm_error("'width' attribute of <svg> has invalid value. %s", error); + pm_error("'width' attribute of <svg> has invalid value '%s'. %s", + width, error); pm_strfree(error); } - stringToUint(height, rowsP, &error); + pm_string_to_uint(height, rowsP, &error); if (error) { - pm_error("'height' attribute of <svg> has invalid value. %s", error); + pm_error("'height' attribute of <svg> has invalid value '%s'. %s", + height, error); pm_strfree(error); } } @@ -718,7 +731,7 @@ getSvgAttributes(xmlTextReaderPtr const xmlReaderP, static void processSubSvgElement(xmlTextReaderPtr const xmlReaderP, - canvas * const canvasP) { + Canvas * const canvasP) { const char * const nodeName = currentNodeName(xmlReaderP); @@ -735,7 +748,7 @@ processSubSvgElement(xmlTextReaderPtr const xmlReaderP, static void processSubSvgNode(xmlTextReaderPtr const xmlReaderP, - canvas * const canvasP, + Canvas * const canvasP, bool * const endOfSvgP) { xmlReaderTypes const nodeType = xmlTextReaderNodeType(xmlReaderP); @@ -765,9 +778,9 @@ static void createCanvas(unsigned int const width, unsigned int const height, pixval const maxval, - canvas ** const canvasPP) { + Canvas ** const canvasPP) { - canvas * canvasP; + Canvas * canvasP; MALLOCVAR_NOFAIL(canvasP); @@ -782,7 +795,7 @@ createCanvas(unsigned int const width, static void -destroyCanvas(canvas * const canvasP) { +destroyCanvas(Canvas * const canvasP) { ppm_freearray(canvasP->pixels, canvasP->height); @@ -793,7 +806,7 @@ destroyCanvas(canvas * const canvasP) { static void writePam(FILE * const ofP, - canvas * const canvasP) { + Canvas * const canvasP) { unsigned int row; struct pam pam; @@ -839,7 +852,7 @@ processSvgElement(xmlTextReaderPtr const xmlReaderP, unsigned int width, height; bool endOfSvg; - canvas * canvasP; + Canvas * canvasP; assert(xmlTextReaderNodeType(xmlReaderP) == XML_READER_TYPE_ELEMENT); assert(streq(currentNodeName(xmlReaderP), "svg")); diff --git a/converter/other/tifftopnm.c b/converter/other/tifftopnm.c index e72aff5e..c1e7af85 100644 --- a/converter/other/tifftopnm.c +++ b/converter/other/tifftopnm.c @@ -191,7 +191,7 @@ getBps(TIFF * const tif, if (bps < 1 || (bps > 8 && bps != 16 && bps != 32)) pm_error("This program can process Tiff images with only " - "1-8 or 16 bits per sample. The input Tiff image " + "1-8 or 16 or 32 bits per sample. The input Tiff image " "has %hu bits per sample.", bps); else *bpsP = bps; |