diff --git a/src/image.c b/src/image.c index 342a355..4e402bc 100644 --- a/src/image.c +++ b/src/image.c @@ -680,9 +680,84 @@ void cammy_image_copy(cammy_image *dest, } } +static void bitmap_copy_channel(cammy_image *dest, + cammy_image *src, + cammy_image_point *to, + cammy_image_region *from, + int channel) { + size_t x, y; + + int channels_dest = depth_channels(dest->depth), + channels_src = depth_channels(src->depth); + + for (y=from->y; yy + from->height; y++) { + if (y >= dest->height) { + break; + } + + for (x=0; xx + from->width; x++) { + uint8_t v; + + if (x >= dest->width) { + break; + } + + v = bitmap_read_channel(src->buf, x, y, src->width, channels_src, channel); + + bitmap_write(dest->buf, x, y, from->width, channels_dest, 0, 0, 0); + bitmap_write_channel(dest->buf, x, y, from->width, channels_dest, channel, v); + } + } +} + int cammy_image_split(cammy_image *image, cammy_image **r, cammy_image **g, cammy_image **b) { + struct { + cammy_image **output; + int channel; + } outputs[3] = { + { r, 0 }, + { g, 1 }, + { b, 2 } + }; + + int i; + + if (image->format != CAMMY_IMAGE_BITMAP) { + goto error_invalid_format; + } + + for (i=0; i<3; i++) { + cammy_image **output = outputs[i].output; + + cammy_image_point to = { + 0, 0 + }; + + cammy_image_region from = { + 0, 0, image->width, image->height + }; + + if ((*output = cammy_image_new(image->format, + image->depth, + image->palette, + image->width, + image->height)) == NULL) { + goto error_image_new; + } + + bitmap_copy_channel(*output, image, &to, &from, i); + } + return 0; + +error_image_new: + while (--i >= 0) { + cammy_image_destroy(*(outputs[i].output)); + } + +error_invalid_format: + return -1; }