+template <class T>
+void
+component (
+ int n,
+ Image* base,
+ shared_ptr<const Image> other,
+ shared_ptr<const Image> rgba,
+ int start_base_x, int start_base_y,
+ int start_other_x, int start_other_y
+ )
+{
+ dcp::Size const base_size = base->sample_size(n);
+ dcp::Size const other_size = other->sample_size(n);
+ for (int by = start_base_y, oy = start_other_y; by < base_size.height && oy < other_size.height; ++by, ++oy) {
+ /* base image */
+ T* bp = ((T*) (base->data()[n] + by * base->stride()[n])) + start_base_x;
+ /* overlay image */
+ T* op = ((T*) (other->data()[n] + oy * other->stride()[n]));
+ /* original RGBA for alpha channel */
+ uint8_t* rp = rgba->data()[0] + oy * rgba->stride()[0];
+ for (int bx = start_base_x, ox = start_other_x; bx < base_size.width && ox < other_size.width; ++bx, ++ox) {
+ float const alpha = float (rp[3]) / 255;
+ *bp = *op * alpha + *bp * (1 - alpha);
+ ++bp;
+ ++op;
+ rp += 4;
+ }
+ }
+}
+