The variance computation is simple enough now (since we can use the axis squared errors) that it doesn't need to have a complex lazy computation logic.
Showing the changes to libavfilter (1 of 1 file). Show all
Unified · Split
| @@ -135,16 +135,6 @@ static int cmp_color(const void *a, const void *b) · 134 unmodified lines | ||
| 135 | 135 | return FFDIFFSIGN(box1->color , box2->color); |
| 136 | 136 | } |
| 137 | 137 | |
| 138 | −static av_always_inline int diff(const uint32_t a, const uint32_t b) | |
| 139 | −{ | |
| 140 | − const uint8_t c1[] = {a >> 16 & 0xff, a >> 8 & 0xff, a & 0xff}; | |
| 141 | − const uint8_t c2[] = {b >> 16 & 0xff, b >> 8 & 0xff, b & 0xff}; | |
| 142 | − const int dr = c1[0] - c2[0]; | |
| 143 | − const int dg = c1[1] - c2[1]; | |
| 144 | − const int db = c1[2] - c2[2]; | |
| 145 | − return dr*dr + dg*dg + db*db; | |
| 146 | −} | |
| 147 | − | |
| 148 | 138 | static void compute_box_stats(PaletteGenContext *s, struct range_box *box) |
| 149 | 139 | { |
| 150 | 140 | int avg[3]; |
| @@ -180,6 +170,8 @@ static void compute_box_stats(PaletteGenContext *s, struct range_box *box) · 29 unmodified lines | ||
| 180 | 170 | if (er2[2] >= er2[0] && er2[2] >= er2[1]) box->major_axis = 2; |
| 181 | 171 | if (er2[0] >= er2[1] && er2[0] >= er2[2]) box->major_axis = 0; |
| 182 | 172 | if (er2[1] >= er2[0] && er2[1] >= er2[2]) box->major_axis = 1; // prefer green again |
| 173 | + | |
| 174 | + box->variance = er2[0] + er2[1] + er2[2]; | |
| 183 | 175 | } |
| 184 | 176 | |
| 185 | 177 | /** |
| @@ -187,7 +179,7 @@ static void compute_box_stats(PaletteGenContext *s, struct range_box *box) · 1 unmodified line | ||
| 187 | 179 | */ |
| 188 | 180 | static int get_next_box_id_to_split(PaletteGenContext *s) |
| 189 | 181 | { |
| 190 | − int box_id, i, best_box_id = -1; | |
| 182 | + int box_id, best_box_id = -1; | |
| 191 | 183 | int64_t max_variance = -1; |
| 192 | 184 | |
| 193 | 185 | if (s->nb_boxes == s->max_colors - s->reserve_transparent) |
| @@ -195,24 +187,9 @@ static int get_next_box_id_to_split(PaletteGenContext *s) · 1 unmodified line | ||
| 195 | 187 | |
| 196 | 188 | for (box_id = 0; box_id < s->nb_boxes; box_id++) { |
| 197 | 189 | struct range_box *box = &s->boxes[box_id]; |
| 198 | − | |
| 199 | − if (s->boxes[box_id].len >= 2) { | |
| 200 | − | |
| 201 | − if (box->variance == -1) { | |
| 202 | − int64_t variance = 0; | |
| 203 | − | |
| 204 | − for (i = 0; i < box->len; i++) { | |
| 205 | − const struct color_ref *ref = s->refs[box->start + i]; | |
| 206 | − variance += diff(ref->color, box->color) * ref->count; | |
| 207 | − } | |
| 208 | − box->variance = variance; | |
| 209 | − } | |
| 210 | − if (box->variance > max_variance) { | |
| 211 | − best_box_id = box_id; | |
| 212 | − max_variance = box->variance; | |
| 213 | − } | |
| 214 | − } else { | |
| 215 | − box->variance = -1; | |
| 190 | + if (s->boxes[box_id].len >= 2 && box->variance > max_variance) { | |
| 191 | + best_box_id = box_id; | |
| 192 | + max_variance = box->variance; | |
| 216 | 193 | } |
| 217 | 194 | } |
| 218 | 195 | return best_box_id; |
| @@ -261,8 +238,8 @@ static void split_box(PaletteGenContext *s, struct range_box *box, int n) · 42 unmodified lines | ||
| 261 | 238 | |
| 262 | 239 | box->color = get_avg_color(s->refs, box); |
| 263 | 240 | new_box->color = get_avg_color(s->refs, new_box); |
| 264 | − box->variance = -1; | |
| 265 | − new_box->variance = -1; | |
| 241 | + compute_box_stats(s, box); | |
| 242 | + compute_box_stats(s, new_box); | |
| 266 | 243 | } |
| 267 | 244 | |
| 268 | 245 | /** |
| @@ -359,14 +336,13 @@ static AVFrame *get_palette_frame(AVFilterContext *ctx) · 90 unmodified lines | ||
| 359 | 336 | box->len = s->nb_refs; |
| 360 | 337 | box->sorted_by = -1; |
| 361 | 338 | box->color = get_avg_color(s->refs, box); |
| 362 | − box->variance = -1; | |
| 339 | + compute_box_stats(s, box); | |
| 363 | 340 | s->nb_boxes = 1; |
| 364 | 341 | |
| 365 | 342 | while (box && box->len > 1) { |
| 366 | 343 | int i; |
| 367 | 344 | uint64_t median, box_weight; |
| 368 | 345 | |
| 369 | − compute_box_stats(s, box); | |
| 370 | 346 | box_weight = box->weight; |
| 371 | 347 | |
| 372 | 348 | ff_dlog(ctx, "box #%02X [%6d..%-6d] (%6d) w:%-6"PRIu64" sort by %c (already sorted:%c) ", |