}
};
+
+// Sum up the color/alpha components inside the masked region.
+// Called by get_color().
+//
+void get_color_pixels_accumulate (uint16_t * mask,
+ uint16_t * rgba,
+ float * sum_weight,
+ float * sum_r,
+ float * sum_g,
+ float * sum_b,
+ float * sum_a
+ ) {
+
+
+ // The sum of a 64x64 tile fits into a 32 bit integer, but the sum
+ // of an arbitrary number of tiles may not fit. We assume that we
+ // are processing a single tile at a time, so we can use integers.
+ // But for the result we need floats.
+
+ uint32_t weight = 0;
+ uint32_t r = 0;
+ uint32_t g = 0;
+ uint32_t b = 0;
+ uint32_t a = 0;
+
+ while (1) {
+ for (; mask[0]; mask++, rgba+=4) {
+ uint32_t opa = mask[0];
+ weight += opa;
+ r += opa*rgba[0]/(1<<15);
+ g += opa*rgba[1]/(1<<15);
+ b += opa*rgba[2]/(1<<15);
+ a += opa*rgba[3]/(1<<15);
+
+ }
+ if (!mask[1]) break;
+ rgba += mask[1];
+ mask += 2;
+ }
+
+ // convert integer to float outside the performance critical loop
+ *sum_weight += weight;
+ *sum_r += r;
+ *sum_g += g;
+ *sum_b += b;
+ *sum_a += a;
+};
+
const float aspect_ratio = 1.0;
const float angle = 0.0;
- float sum_r, sum_g, sum_b, sum_a, sum_weight;
- sum_r = sum_g = sum_b = sum_a = sum_weight = 0.0;
+ float sum_weight, sum_r, sum_g, sum_b, sum_a;
+ sum_weight = sum_r = sum_g = sum_b = sum_a = 0.0;
// in case we return with an error
*color_r = 0.0;
aspect_ratio, angle
);
- // accumulate
-
- // the sum of a 64x64 tile fits into a 32 bit integer
- // (but not the sum of an arbitrary number of tiles)
- uint32_t sum_weight_tmp = 0;
- uint32_t sum_a_tmp = 0;
- uint32_t sum_r_tmp = 0;
- uint32_t sum_g_tmp = 0;
- uint32_t sum_b_tmp = 0;
-
- uint16_t * mask_p = mask;
- while (1) {
- for (; mask_p[0]; mask_p++, rgba_p+=4) {
- uint32_t opa = mask_p[0];
- sum_weight_tmp += opa;
- sum_r_tmp += opa*rgba_p[0]/(1<<15);
- sum_g_tmp += opa*rgba_p[1]/(1<<15);
- sum_b_tmp += opa*rgba_p[2]/(1<<15);
- sum_a_tmp += opa*rgba_p[3]/(1<<15);
-
- }
- if (!mask_p[1]) break;
- rgba_p += mask_p[1];
- mask_p += 2;
- }
+ get_color_pixels_accumulate (mask, rgba_p,
+ &sum_weight, &sum_r, &sum_g, &sum_b, &sum_a);
- // conver to float outside the critical loop
- sum_weight += sum_weight_tmp;
- sum_r += sum_r_tmp;
- sum_g += sum_g_tmp;
- sum_b += sum_b_tmp;
- sum_a += sum_a_tmp;
}
}