Showing the changes to libavfilter (1 of 1 file). Show all
Unified · Split
| @@ -40,6 +40,8 @@ struct color_ref { · 39 unmodified lines | |||
| 40 | /* Store a range of colors */ | 40 | /* Store a range of colors */ |
| 41 | struct range_box { | 41 | struct range_box { |
| 42 | uint32_t color; // average color | 42 | uint32_t color; // average color |
| 43 | int major_axis; // best axis candidate for cutting the box | ||
| 44 | uint64_t weight; // sum of all the weights of the colors | ||
| 43 | int64_t variance; // overall variance of the box (how much the colors are spread) | 45 | int64_t variance; // overall variance of the box (how much the colors are spread) |
| 44 | int start; // index in PaletteGenContext->refs | 46 | int start; // index in PaletteGenContext->refs |
| 45 | int len; // number of referenced colors | 47 | int len; // number of referenced colors |
| @@ -143,6 +145,35 @@ static av_always_inline int diff(const uint32_t a, const uint32_t b) · 97 unmodified lines | |||
| 143 | return dr*dr + dg*dg + db*db; | 145 | return dr*dr + dg*dg + db*db; |
| 144 | } | 146 | } |
| 145 | 147 | ||
| 148 | static void compute_box_stats(PaletteGenContext *s, struct range_box *box) | ||
| 149 | { | ||
| 150 | int rr, gr, br; | ||
| 151 | |||
| 152 | /* compute the box weight (sum all the weights of the colors in the | ||
| 153 | * range) and its boundings */ | ||
| 154 | uint8_t min[3] = {0xff, 0xff, 0xff}; | ||
| 155 | uint8_t max[3] = {0x00, 0x00, 0x00}; | ||
| 156 | box->weight = 0; | ||
| 157 | for (int i = box->start; i < box->start + box->len; i++) { | ||
| 158 | const struct color_ref *ref = s->refs[i]; | ||
| 159 | const uint32_t rgb = ref->color; | ||
| 160 | const uint8_t r = rgb >> 16 & 0xff, g = rgb >> 8 & 0xff, b = rgb & 0xff; | ||
| 161 | min[0] = FFMIN(r, min[0]), max[0] = FFMAX(r, max[0]); | ||
| 162 | min[1] = FFMIN(g, min[1]), max[1] = FFMAX(g, max[1]); | ||
| 163 | min[2] = FFMIN(b, min[2]), max[2] = FFMAX(b, max[2]); | ||
| 164 | box->weight += ref->count; | ||
| 165 | } | ||
| 166 | |||
| 167 | /* define the axis to sort by according to the widest range of colors */ | ||
| 168 | rr = max[0] - min[0]; | ||
| 169 | gr = max[1] - min[1]; | ||
| 170 | br = max[2] - min[2]; | ||
| 171 | box->major_axis = 1; // pick green by default (the color the eye is the most sensitive to) | ||
| 172 | if (br >= rr && br >= gr) box->major_axis = 2; | ||
| 173 | if (rr >= gr && rr >= br) box->major_axis = 0; | ||
| 174 | if (gr >= rr && gr >= br) box->major_axis = 1; // prefer green again | ||
| 175 | } | ||
| 176 | |||
| 146 | /** | 177 | /** |
| 147 | * Find the next box to split: pick the one with the highest variance | 178 | * Find the next box to split: pick the one with the highest variance |
| 148 | */ | 179 | */ |
| @@ -324,35 +355,16 @@ static AVFrame *get_palette_frame(AVFilterContext *ctx) · 175 unmodified lines | |||
| 324 | s->nb_boxes = 1; | 355 | s->nb_boxes = 1; |
| 325 | 356 | ||
| 326 | while (box && box->len > 1) { | 357 | while (box && box->len > 1) { |
| 327 | int i, rr, gr, br, longest; | 358 | int i, longest; |
| 328 | uint64_t median, box_weight = 0; | 359 | uint64_t median, box_weight; |
| 329 | |||
| 330 | /* compute the box weight (sum all the weights of the colors in the | ||
| 331 | * range) and its boundings */ | ||
| 332 | uint8_t min[3] = {0xff, 0xff, 0xff}; | ||
| 333 | uint8_t max[3] = {0x00, 0x00, 0x00}; | ||
| 334 | for (i = box->start; i < box->start + box->len; i++) { | ||
| 335 | const struct color_ref *ref = s->refs[i]; | ||
| 336 | const uint32_t rgb = ref->color; | ||
| 337 | const uint8_t r = rgb >> 16 & 0xff, g = rgb >> 8 & 0xff, b = rgb & 0xff; | ||
| 338 | min[0] = FFMIN(r, min[0]), max[0] = FFMAX(r, max[0]); | ||
| 339 | min[1] = FFMIN(g, min[1]), max[1] = FFMAX(g, max[1]); | ||
| 340 | min[2] = FFMIN(b, min[2]), max[2] = FFMAX(b, max[2]); | ||
| 341 | box_weight += ref->count; | ||
| 342 | } | ||
| 343 | 360 | ||
| 344 | /* define the axis to sort by according to the widest range of colors */ | 361 | compute_box_stats(s, box); |
| 345 | rr = max[0] - min[0]; | 362 | longest = box->major_axis; |
| 346 | gr = max[1] - min[1]; | 363 | box_weight = box->weight; |
| 347 | br = max[2] - min[2]; | ||
| 348 | longest = 1; // pick green by default (the color the eye is the most sensitive to) | ||
| 349 | if (br >= rr && br >= gr) longest = 2; | ||
| 350 | if (rr >= gr && rr >= br) longest = 0; | ||
| 351 | if (gr >= rr && gr >= br) longest = 1; // prefer green again | ||
| 352 | 364 | ||
| 353 | ff_dlog(ctx, "box #%02X [%6d..%-6d] (%6d) w:%-6"PRIu64" ranges:[%2x %2x %2x] sort by %c (already sorted:%c) ", | 365 | ff_dlog(ctx, "box #%02X [%6d..%-6d] (%6d) w:%-6"PRIu64" sort by %c (already sorted:%c) ", |
| 354 | box_id, box->start, box->start + box->len - 1, box->len, box_weight, | 366 | box_id, box->start, box->start + box->len - 1, box->len, box_weight, |
| 355 | rr, gr, br, "rgb"[longest], box->sorted_by == longest ? 'y':'n'); | 367 | "rgb"[longest], box->sorted_by == longest ? 'y':'n'); |
| 356 | 368 | ||
| 357 | /* sort the range by its longest axis if it's not already sorted */ | 369 | /* sort the range by its longest axis if it's not already sorted */ |
| 358 | if (box->sorted_by != longest) { | 370 | if (box->sorted_by != longest) { |