1 /*
2 * subdivide.c: Recursive subdivision of range images
3 *
4 * Written by: Ullrich Hafner
5 *
6 * This file is part of FIASCO (Fractal Image And Sequence COdec)
7 * Copyright (C) 1994-2000 Ullrich Hafner
8 */
9
10 /*
11 * $Date: 2000/07/15 17:59:31 $
12 * $Author: hafner $
13 * $Revision: 5.4 $
14 * $State: Exp $
15 */
16
17 #include "config.h"
18
19 #include <string.h>
20
21 #include "pm_c_util.h"
22
23 #include "types.h"
24 #include "macros.h"
25 #include "error.h"
26
27 #include "image.h"
28 #include "cwfa.h"
29 #include "approx.h"
30 #include "ip.h"
31 #include "bintree.h"
32 #include "control.h"
33 #include "prediction.h"
34 #include "domain-pool.h"
35 #include "mwfa.h"
36 #include "misc.h"
37 #include "subdivide.h"
38 #include "list.h"
39 #include "coeff.h"
40 #include "wfalib.h"
41
42 /*****************************************************************************
43
44 prototypes
45
46 *****************************************************************************/
47
48 static void
49 init_new_state (bool_t auxiliary_state, bool_t delta, range_t *range,
50 const range_t *child, const int *y_state,
51 wfa_t *wfa, coding_t *c);
52 static void
53 init_range (range_t *range, const image_t *image, unsigned band,
54 const wfa_t *wfa, coding_t *c);
55
56 /*****************************************************************************
57
58 public code
59
60 *****************************************************************************/
61
62 real_t
subdivide(real_t max_costs,unsigned band,int y_state,range_t * range,wfa_t * wfa,coding_t * c,bool_t prediction,bool_t delta)63 subdivide (real_t max_costs, unsigned band, int y_state, range_t *range,
64 wfa_t *wfa, coding_t *c, bool_t prediction, bool_t delta)
65 /*
66 * Subdivide the current 'range' recursively and decide whether
67 * a linear combination, a recursive subdivision, or a prediction is
68 * the best choice of approximation.
69 * 'band' is the current color band, 'y_state' is the corresponding
70 * state of the Y color component (color image compression only).
71 * If 'prediction' is TRUE then also test motion compensation or
72 * nondeterministic approximation.
73 * If 'delta' is TRUE then current range is already predicted.
74 *
75 * Return value:
76 * costs of the best approximation or MAXCOSTS if costs exceed 'max_costs'
77 *
78 * Side effects:
79 * 'range' factors and costs of linear combination are modified
80 * 'wfa' new transitions and prediction coefficients are added
81 * 'c' pixels and inner products are updated
82 */
83 {
84 real_t subdivide_costs; /* Costs arising from approx. the current
85 range with two children */
86 real_t lincomb_costs; /* Costs arising from approx. the current
87 range with a linear combination */
88 int new_y_state [MAXLABELS]; /* Corresponding state of Y */
89 real_t price; /* Approximation costs multiplier */
90 bool_t try_mc; /* YES: try MC prediction */
91 bool_t try_nd; /* YES: try ND prediction */
92 unsigned states; /* Number of states before the
93 recursive subdivision starts */
94 void *domain_model; /* copy of domain pool model */
95 void *d_domain_model; /* copy of delta domain pool model */
96 void *lc_domain_model; /* copy of domain pool model */
97 void *lc_d_domain_model; /* copy of delta domain pool model */
98 void *coeff_model; /* copy of coefficients model */
99 void *d_coeff_model; /* copy of delta coefficients model */
100 void *lc_coeff_model; /* copy of coefficients model */
101 void *lc_d_coeff_model; /* copy of delta coefficients model */
102 tree_t tree_model; /* copy of tree model */
103 tree_t p_tree_model; /* copy of pred. tree model */
104 range_t lrange; /* range of lin. comb. approx. */
105 range_t rrange; /* range of recursive approx. */
106 range_t child [MAXLABELS]; /* new children of the current range */
107 static unsigned percent = 0; /* status of progress meter */
108
109 if (wfa->wfainfo->level == range->level)
110 percent = 0;
111
112 range->into [0] = NO_EDGE; /* default approximation: empty */
113 range->tree = RANGE;
114
115 if (range->level < 3) /* Don't process small ranges */
116 return MAXCOSTS;
117
118 /*
119 * If image permutation (tiling) is performed and the tiling level
120 * is reached then get coordinates of the new block.
121 */
122 if (c->tiling->exponent
123 && range->level == wfa->wfainfo->level - c->tiling->exponent)
124 {
125 unsigned width, height; /* size of range (dummies)*/
126
127 if (c->tiling->vorder [range->global_address] < 0)
128 return 0; /* nothing to do */
129 else
130 locate_subimage (wfa->wfainfo->level, range->level,
131 c->tiling->vorder [range->global_address],
132 &range->x, &range->y, &width, &height);
133 }
134
135 if (range->x >= c->mt->original->width ||
136 range->y >= c->mt->original->height)
137 return 0; /* range is not visible */
138
139 /*
140 * Check whether prediction is allowed or not
141 * mc == motion compensation, nd == nondeterminism
142 */
143 try_mc = (prediction && c->mt->frame_type != I_FRAME
144 && range->level >= wfa->wfainfo->p_min_level
145 && range->level <= wfa->wfainfo->p_max_level
146 && (range->x + width_of_level (range->level)
147 <= c->mt->original->width)
148 && (range->y + height_of_level (range->level)
149 <= c->mt->original->height));
150
151 try_nd = (prediction && c->mt->frame_type == I_FRAME
152 && range->level >= wfa->wfainfo->p_min_level
153 && range->level <= wfa->wfainfo->p_max_level);
154
155 if (try_mc)
156 clear_norms_table (range->level, wfa->wfainfo, c->mt);
157
158
159 /*
160 * Check if current range must be initialized. I.e. range pixels must
161 * be copied from entire image to bintree pixel buffer. Moreover,
162 * all inner products tables must be initialized.
163 */
164 if (range->level == c->options.lc_max_level)
165 init_range (range, c->mt->original, band, wfa, c);
166
167 price = c->price;
168 if (band != Y)
169 price *= c->options.chroma_decrease; /* less quality for chroma bands */
170
171 /*
172 * Compute children of corresponding state in Y band
173 */
174 if (band != Y) /* Cb and Cr bands only */
175 {
176 unsigned label;
177
178 for (label = 0; label < MAXLABELS; label++)
179 if (ischild (y_state))
180 new_y_state [label] = wfa->tree [y_state][label];
181 else
182 new_y_state [label] = RANGE;
183 }
184 else
185 new_y_state [0] = new_y_state [1] = RANGE;
186
187 /*
188 * Store contents of all models that may get modified during recursion
189 */
190 domain_model = c->domain_pool->model_duplicate (c->domain_pool->model);
191 d_domain_model = c->d_domain_pool->model_duplicate (c->d_domain_pool->model);
192 coeff_model = c->coeff->model_duplicate (c->coeff, c->coeff->model);
193 d_coeff_model = c->d_coeff->model_duplicate (c->d_coeff, c->d_coeff->model);
194 tree_model = c->tree;
195 p_tree_model = c->p_tree;
196 states = wfa->states;
197
198 /*
199 * First alternative of range approximation:
200 * Compute costs of linear combination.
201 */
202 if (range->level <= c->options.lc_max_level) /* range is small enough */
203 {
204 lrange = *range;
205 lrange.tree = RANGE;
206 lrange.tree_bits = tree_bits (LEAF, lrange.level, &c->tree);
207 lrange.matrix_bits = 0;
208 lrange.weights_bits = 0;
209 lrange.mv_tree_bits = try_mc ? 1 : 0; /* mc allowed but not used */
210 lrange.mv_coord_bits = 0;
211 lrange.nd_tree_bits = 0;
212 lrange.nd_weights_bits = 0;
213 lrange.prediction = NO;
214
215 lincomb_costs
216 = approximate_range (max_costs, price, c->options.max_elements,
217 y_state, &lrange,
218 (delta ? c->d_domain_pool : c->domain_pool),
219 (delta ? c->d_coeff : c->coeff), wfa, c);
220 }
221 else
222 lincomb_costs = MAXCOSTS;
223
224 /*
225 * Store contents of models that have been modified
226 * by approximate_range () above ...
227 */
228 lc_domain_model = c->domain_pool->model;
229 lc_d_domain_model = c->d_domain_pool->model;
230 lc_coeff_model = c->coeff->model;
231 lc_d_coeff_model = c->d_coeff->model;
232 /*
233 * ... and restore them with values before lc
234 */
235 c->domain_pool->model = c->domain_pool->model_duplicate (domain_model);
236 c->d_domain_pool->model = c->d_domain_pool->model_duplicate (d_domain_model);
237 c->coeff->model = c->coeff->model_duplicate (c->coeff, coeff_model);
238 c->d_coeff->model = c->d_coeff->model_duplicate (c->d_coeff,
239 d_coeff_model);
240
241 /*
242 * Second alternative of range approximation:
243 * Compute costs of recursive subdivision.
244 */
245 if (range->level > c->options.lc_min_level) /* range is large enough */
246 {
247 unsigned label;
248
249 memset (&child [0], 0, 2 * sizeof (range_t)); /* initialize children */
250
251 /*
252 * Initialize a new range for recursive approximation
253 */
254 rrange = *range;
255 rrange.tree_bits = tree_bits (CHILD, rrange.level, &c->tree);
256 rrange.matrix_bits = 0;
257 rrange.weights_bits = 0;
258 rrange.err = 0;
259 rrange.mv_tree_bits = try_mc ? 1 : 0; /* mc allowed but not used */
260 rrange.mv_coord_bits = 0;
261 rrange.nd_tree_bits = try_nd ?
262 tree_bits (CHILD, lrange.level, &c->p_tree): 0;
263 rrange.nd_weights_bits = 0;
264 rrange.prediction = NO;
265
266 /*
267 * Initialize the cost function and subdivide the current range.
268 * Every child is approximated by a recursive call of subdivide()
269 */
270 subdivide_costs = (rrange.tree_bits + rrange.weights_bits
271 + rrange.matrix_bits + rrange.mv_tree_bits
272 + rrange.mv_coord_bits + rrange.nd_tree_bits
273 + rrange.nd_weights_bits) * price;
274
275 for (label = 0; label < MAXLABELS; label++)
276 {
277 real_t remaining_costs; /* upper limit for next recursion */
278
279 child[label].image = rrange.image * MAXLABELS + label + 1;
280 child[label].address = rrange.address * MAXLABELS + label;
281 child[label].global_address = rrange.global_address * MAXLABELS
282 + label;
283 child[label].level = rrange.level - 1;
284 child[label].x = rrange.level & 1
285 ? rrange.x
286 : (rrange.x
287 + label * width_of_level (rrange.level - 1));
288 child[label].y = rrange.level & 1
289 ? (rrange.y
290 + label * height_of_level (rrange.level - 1))
291 : rrange.y;
292
293 /*
294 * If necessary compute the inner products of the new states
295 * (generated during the recursive approximation of child [0])
296 */
297 if (label && rrange.level <= c->options.lc_max_level)
298 compute_ip_images_state (child[label].image, child[label].address,
299 child[label].level, 1, states, wfa, c);
300 /*
301 * Call subdivide() for both children.
302 * Abort the recursion if 'subdivide_costs' exceed 'lincomb_costs'
303 * or 'max_costs'.
304 */
305 remaining_costs = MIN(lincomb_costs, max_costs) - subdivide_costs;
306
307 if (remaining_costs > 0) /* still a way for improvement */
308 {
309 subdivide_costs += subdivide (remaining_costs, band,
310 new_y_state [label], &child [label],
311 wfa, c, prediction, delta);
312 }
313 else if (try_mc && child[label].level >= wfa->wfainfo->p_min_level)
314 {
315 fill_norms_table (child[label].x, child[label].y,
316 child[label].level, wfa->wfainfo, c->mt);
317 }
318
319 if (try_mc)
320 update_norms_table (rrange.level, wfa->wfainfo, c->mt);
321
322 /*
323 * Update of progress meter
324 */
325 if (c->options.progress_meter != FIASCO_PROGRESS_NONE)
326 {
327 if (c->options.progress_meter == FIASCO_PROGRESS_PERCENT)
328 {
329 unsigned new_percent; /* new status of progress meter */
330
331 new_percent = (child[label].global_address + 1) * 100.0
332 / (1 << (wfa->wfainfo->level - child[label].level));
333 if (new_percent > percent)
334 {
335 percent = new_percent;
336 info ("%3d%% \r", percent);
337 }
338 }
339 else if (c->options.progress_meter == FIASCO_PROGRESS_BAR)
340 {
341 unsigned new_percent; /* new status of progress meter */
342
343 new_percent = (child[label].global_address + 1) * 50.0
344 / (1 << (wfa->wfainfo->level
345 - child[label].level));
346 for (; new_percent > percent; percent++)
347 {
348 info ("#");
349 }
350 }
351 }
352
353 /*
354 * If costs of subdivision exceed costs of linear combination
355 * then abort recursion.
356 */
357 if (subdivide_costs >= MIN(lincomb_costs, max_costs))
358 {
359 subdivide_costs = MAXCOSTS;
360 break;
361 }
362 rrange.err += child [label].err;
363 rrange.tree_bits += child [label].tree_bits;
364 rrange.matrix_bits += child [label].matrix_bits;
365 rrange.weights_bits += child [label].weights_bits;
366 rrange.mv_tree_bits += child [label].mv_tree_bits;
367 rrange.mv_coord_bits += child [label].mv_coord_bits;
368 rrange.nd_weights_bits += child [label].nd_weights_bits;
369 rrange.nd_tree_bits += child [label].nd_tree_bits;
370
371 tree_update (ischild (child [label].tree) ? CHILD : LEAF,
372 child [label].level, &c->tree);
373 tree_update (child [label].prediction ? LEAF : CHILD,
374 child [label].level, &c->p_tree);
375 }
376 }
377 else
378 subdivide_costs = MAXCOSTS;
379
380 /*
381 * Third alternative of range approximation:
382 * Predict range via motion compensation or nondeterminism and
383 * approximate delta image.
384 */
385 if (try_mc || try_nd) /* try prediction */
386 {
387 real_t prediction_costs; /* Costs arising from approx. the current
388 range with prediction */
389
390 prediction_costs
391 = predict_range (MIN(MIN(lincomb_costs, subdivide_costs),
392 max_costs),
393 price, range, wfa, c, band, y_state, states,
394 &tree_model, &p_tree_model, domain_model,
395 d_domain_model, coeff_model, d_coeff_model);
396 if (prediction_costs < MAXCOSTS) /* prediction has smallest costs */
397 {
398 c->domain_pool->model_free (domain_model);
399 c->d_domain_pool->model_free (d_domain_model);
400 c->domain_pool->model_free (lc_domain_model);
401 c->d_domain_pool->model_free (lc_d_domain_model);
402 c->coeff->model_free (coeff_model);
403 c->d_coeff->model_free (d_coeff_model);
404 c->coeff->model_free (lc_coeff_model);
405 c->d_coeff->model_free (lc_d_coeff_model);
406
407 return prediction_costs;
408 }
409 }
410
411 if (lincomb_costs >= MAXCOSTS && subdivide_costs >= MAXCOSTS)
412 {
413 /*
414 * Return MAXCOSTS if neither a linear combination nor a recursive
415 * subdivision yield costs less than 'max_costs'
416 */
417 c->domain_pool->model_free (c->domain_pool->model);
418 c->d_domain_pool->model_free (c->d_domain_pool->model);
419 c->domain_pool->model_free (lc_domain_model);
420 c->d_domain_pool->model_free (lc_d_domain_model);
421
422 c->coeff->model_free (c->coeff->model);
423 c->d_coeff->model_free (c->d_coeff->model);
424 c->coeff->model_free (lc_coeff_model);
425 c->d_coeff->model_free (lc_d_coeff_model);
426
427 c->domain_pool->model = domain_model;
428 c->d_domain_pool->model = d_domain_model;
429 c->coeff->model = coeff_model;
430 c->d_coeff->model = d_coeff_model;
431 c->tree = tree_model;
432 c->p_tree = p_tree_model;
433
434 if (wfa->states != states)
435 remove_states (states, wfa);
436
437 return MAXCOSTS;
438 }
439 else if (lincomb_costs < subdivide_costs)
440 {
441 /*
442 * Use the linear combination: The factors of the linear combination
443 * are stored already in 'range', so revert the probability models
444 * only.
445 */
446 c->domain_pool->model_free (c->domain_pool->model);
447 c->d_domain_pool->model_free (c->d_domain_pool->model);
448 c->domain_pool->model_free (domain_model);
449 c->d_domain_pool->model_free (d_domain_model);
450
451 c->coeff->model_free (c->coeff->model);
452 c->d_coeff->model_free (c->d_coeff->model);
453 c->coeff->model_free (coeff_model);
454 c->d_coeff->model_free (d_coeff_model);
455
456 c->domain_pool->model = lc_domain_model;
457 c->d_domain_pool->model = lc_d_domain_model;
458 c->coeff->model = lc_coeff_model;
459 c->d_coeff->model = lc_d_coeff_model;
460 c->tree = tree_model;
461 c->p_tree = p_tree_model;
462
463 *range = lrange;
464
465 if (wfa->states != states)
466 remove_states (states, wfa);
467
468 return lincomb_costs;
469 }
470 else
471 {
472 /*
473 * Use the recursive subdivision: Generate a new state with transitions
474 * given in child[].
475 * Don't use state in linear combinations in any of the following cases:
476 * - if color component is Cb or Cr
477 * - if level of state > tiling level
478 * - if state is (partially) outside image geometry
479 */
480 if (band > Y
481 || (c->tiling->exponent
482 && rrange.level > wfa->wfainfo->level - c->tiling->exponent)
483 || (range->x + width_of_level (range->level)
484 > c->mt->original->width)
485 || (range->y + height_of_level (range->level)
486 > c->mt->original->height))
487 init_new_state (YES, delta, &rrange, child, new_y_state, wfa, c);
488 else
489 init_new_state (NO, delta, &rrange, child, new_y_state, wfa, c);
490
491 *range = rrange;
492
493 c->domain_pool->model_free (domain_model);
494 c->d_domain_pool->model_free (d_domain_model);
495 c->domain_pool->model_free (lc_domain_model);
496 c->d_domain_pool->model_free (lc_d_domain_model);
497 c->coeff->model_free (coeff_model);
498 c->d_coeff->model_free (d_coeff_model);
499 c->coeff->model_free (lc_coeff_model);
500 c->d_coeff->model_free (lc_d_coeff_model);
501
502 return subdivide_costs;
503 }
504 }
505
506 void
cut_to_bintree(real_t * dst,const word_t * src,unsigned src_width,unsigned src_height,unsigned x0,unsigned y0,unsigned width,unsigned height)507 cut_to_bintree (real_t *dst, const word_t *src,
508 unsigned src_width, unsigned src_height,
509 unsigned x0, unsigned y0, unsigned width, unsigned height)
510 /*
511 * Cut region ('x0', 'y0', 'width', 'height') of the pixel array 'src'.
512 * Size of image is given by 'src_width' x 'src_height'.
513 * 'dst' pixels are converted to bintree order and real format.
514 *
515 * No return value.
516 *
517 * Side effects:
518 * 'dst []' is filled with corresponding region.
519 */
520 {
521 const unsigned mask01 = 0x555555; /* binary ...010101010101 */
522 const unsigned mask10 = 0xaaaaaa; /* binary ...101010101010 */
523 const unsigned mask01plus1 = mask01 + 1; /* binary ...010101010110 */
524 const unsigned mask10plus1 = mask10 + 1; /* binary ...101010101011 */
525 unsigned x, y; /* pixel coordinates */
526 unsigned xmask, ymask; /* address conversion */
527
528 if (width != height && width != (height >> 1))
529 error ("Bintree cutting requires special type of images.");
530
531 ymask = 0;
532 for (y = y0; y < y0 + height; y++, ymask = (ymask + mask10plus1) & mask01)
533 {
534 xmask = 0;
535 for (x = x0; x < x0 + width; x++, xmask = (xmask + mask01plus1) & mask10)
536 {
537 if (y >= src_height || x >= src_width)
538 dst [xmask | ymask] = 0;
539 else
540 dst [xmask | ymask] = src [y * src_width + x] / 16;
541 }
542 }
543 }
544
545 /*****************************************************************************
546
547 private code
548
549 *****************************************************************************/
550
551 static void
init_new_state(bool_t auxiliary_state,bool_t delta,range_t * range,const range_t * child,const int * y_state,wfa_t * wfa,coding_t * c)552 init_new_state (bool_t auxiliary_state, bool_t delta, range_t *range,
553 const range_t *child, const int *y_state,
554 wfa_t *wfa, coding_t *c)
555 /*
556 * Initializes a new state with all parameters needed for the encoding step.
557 * If flag 'auxiliary_state' is set then don't insert state into domain pools.
558 * If flag 'delta' is set then state represents a delta image (prediction via
559 * nondeterminism or motion compensation).
560 * 'range' the current range image,
561 * 'child []' the left and right children of 'range'.
562 *
563 * No return value.
564 *
565 * Side effects:
566 * New state is appended to 'wfa' (and also its inner products and images
567 * are computed and stored in 'c')
568 */
569 {
570 unsigned label;
571 bool_t state_is_domain = NO;
572
573 if (!auxiliary_state)
574 {
575 if (!delta || c->options.delta_domains)
576 state_is_domain = c->domain_pool->append (wfa->states, range->level,
577 wfa, c->domain_pool->model);
578 if (delta || c->options.normal_domains)
579 state_is_domain = c->d_domain_pool->append (wfa->states, range->level,
580 wfa,
581 c->d_domain_pool->model)
582 || state_is_domain;
583 }
584 else
585 state_is_domain = NO;
586
587 range->into [0] = NO_EDGE;
588 range->tree = wfa->states;
589
590 for (label = 0; label < MAXLABELS; label++)
591 {
592 wfa->tree [wfa->states][label] = child [label].tree;
593 wfa->y_state [wfa->states][label] = y_state [label];
594 wfa->mv_tree [wfa->states][label] = child [label].mv;
595 wfa->x [wfa->states][label] = child [label].x;
596 wfa->y [wfa->states][label] = child [label].y;
597 wfa->prediction [wfa->states][label] = child [label].prediction;
598
599 append_transitions (wfa->states, label, child [label].weight,
600 child [label].into, wfa);
601 }
602 wfa->delta_state [wfa->states] = delta;
603
604 if (range->err < 0)
605 warning ("Negative image norm: %f, %f", child [0].err, child [1].err);
606
607 /* state_is_domain = YES; */
608
609 append_state (!state_is_domain,
610 compute_final_distribution (wfa->states, wfa),
611 range->level, wfa, c);
612 }
613
614 static void
init_range(range_t * range,const image_t * image,unsigned band,const wfa_t * wfa,coding_t * c)615 init_range (range_t *range, const image_t *image, unsigned band,
616 const wfa_t *wfa, coding_t *c)
617 /*
618 * Read a new 'range' of the image 'image_name' (current color component
619 * is 'band') and compute the new inner product arrays.
620 *
621 * No return value.
622 *
623 * Side effects:
624 * 'c->pixels' are filled with pixel values of image block
625 * 'c->ip_images_state' are computed with respect to new image block
626 * 'range->address' and 'range->image' are initialized with zero
627 */
628 {
629 unsigned state;
630
631 /*
632 * Clear already computed products
633 */
634 for (state = 0; state < wfa->states; state++)
635 if (need_image (state, wfa))
636 memset (c->ip_images_state[state], 0,
637 size_of_tree (c->products_level) * sizeof(real_t));
638
639 cut_to_bintree (c->pixels, image->pixels [band],
640 image->width, image->height,
641 range->x, range->y, width_of_level (range->level),
642 height_of_level (range->level));
643
644 range->address = range->image = 0;
645 compute_ip_images_state (0, 0, range->level, 1, 0, wfa, c);
646 }
647
648
649