/* * Image Scaling Functions * Copyright (c) 2010 Sebastian Dröge * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "vs_fill_borders.h" #include "gstvideoscaleorc.h" #if G_BYTE_ORDER == G_LITTLE_ENDIAN #define READ_UINT32(ptr) GST_READ_UINT32_LE(ptr) #define READ_UINT16(ptr) GST_READ_UINT16_LE(ptr) #else #define READ_UINT32(ptr) GST_READ_UINT32_BE(ptr) #define READ_UINT16(ptr) GST_READ_UINT16_BE(ptr) #endif void vs_fill_borders_RGBA (const VSImage * dest, const uint8_t * val) { int i; int top = dest->border_top, bottom = dest->border_bottom; int left = dest->border_left, right = dest->border_right; int width = dest->width; int height = dest->height; int real_width = dest->real_width; int stride = dest->stride; int tmp, tmp2; uint8_t *data; uint32_t v = READ_UINT32 (val); data = dest->real_pixels; for (i = 0; i < top; i++) { video_scale_orc_splat_u32 ((uint32_t *) data, v, real_width); data += stride; } if (left || right) { tmp = height; tmp2 = (left + width) * 4; for (i = 0; i < tmp; i++) { video_scale_orc_splat_u32 ((uint32_t *) data, v, left); video_scale_orc_splat_u32 ((uint32_t *) (data + tmp2), v, right); data += stride; } } else { data += stride * height; } for (i = 0; i < bottom; i++) { video_scale_orc_splat_u32 ((uint32_t *) data, v, real_width); data += stride; } } static void _memset_u24 (uint8_t * data, uint8_t val1, uint8_t val2, uint8_t val3, unsigned int n) { unsigned int i; for (i = 0; i < n; i++) { data[0] = val1; data[1] = val2; data[2] = val3; data += 3; } } void vs_fill_borders_RGB (const VSImage * dest, const uint8_t * val) { int i; int top = dest->border_top, bottom = dest->border_bottom; int left = dest->border_left, right = dest->border_right; int width = dest->width; int height = dest->height; int real_width = dest->real_width; int stride = dest->stride; int tmp, tmp2; uint8_t *data; data = dest->real_pixels; for (i = 0; i < top; i++) { _memset_u24 (data, val[0], val[1], val[2], real_width); data += stride; } if (left || right) { tmp = height; tmp2 = (left + width) * 3; for (i = 0; i < tmp; i++) { _memset_u24 (data, val[0], val[1], val[2], left); _memset_u24 (data + tmp2, val[0], val[1], val[2], right); data += stride; } } else { data += stride * height; } for (i = 0; i < bottom; i++) { _memset_u24 (data, val[0], val[1], val[2], real_width); data += stride; } } void vs_fill_borders_YUYV (const VSImage * dest, const uint8_t * val) { int i, j; int top = dest->border_top, bottom = dest->border_bottom; int left = dest->border_left, right = dest->border_right; int width = dest->width; int height = dest->height; int real_width = dest->real_width; int stride = dest->stride; int tmp, tmp2; uint8_t *data; data = dest->real_pixels; for (i = 0; i < top; i++) { for (j = 0; j < real_width; j++) { data[2 * j] = val[0]; data[2 * j + 1] = (j % 2 == 0) ? val[1] : val[3]; } data += stride; } if (left || right) { tmp = height; tmp2 = (left + width) * 2; for (i = 0; i < tmp; i++) { for (j = 0; j < left; j++) { data[2 * j] = val[0]; data[2 * j + 1] = (j % 2 == 0) ? val[1] : val[3]; } for (j = 0; j < right; j++) { data[tmp2 + 2 * j] = val[0]; data[tmp2 + 2 * j + 1] = (j % 2 == 0) ? val[1] : val[3]; } data += stride; } } else { data += stride * height; } for (i = 0; i < bottom; i++) { for (j = 0; j < real_width; j++) { data[2 * j] = val[0]; data[2 * j + 1] = (j % 2 == 0) ? val[1] : val[3]; } data += stride; } } void vs_fill_borders_UYVY (const VSImage * dest, const uint8_t * val) { int i, j; int top = dest->border_top, bottom = dest->border_bottom; int left = dest->border_left, right = dest->border_right; int width = dest->width; int height = dest->height; int real_width = dest->real_width; int stride = dest->stride; int tmp, tmp2; uint8_t *data; data = dest->real_pixels; for (i = 0; i < top; i++) { for (j = 0; j < real_width; j++) { data[2 * j] = (j % 2 == 0) ? val[0] : val[2]; data[2 * j + 1] = val[1]; } data += stride; } if (left || right) { tmp = height; tmp2 = (left + width) * 2; for (i = 0; i < tmp; i++) { for (j = 0; j < left; j++) { data[2 * j] = (j % 2 == 0) ? val[0] : val[2]; data[2 * j + 1] = val[1]; } for (j = 0; j < right; j++) { data[tmp2 + 2 * j] = (j % 2 == 0) ? val[0] : val[2]; data[tmp2 + 2 * j + 1] = val[1]; } data += stride; } } else { data += stride * height; } for (i = 0; i < bottom; i++) { for (j = 0; j < real_width; j++) { data[2 * j] = (j % 2 == 0) ? val[0] : val[2]; data[2 * j + 1] = val[1]; } data += stride; } } void vs_fill_borders_Y (const VSImage * dest, const uint8_t * val) { int i; int top = dest->border_top, bottom = dest->border_bottom; int left = dest->border_left, right = dest->border_right; int width = dest->width; int height = dest->height; int real_width = dest->real_width; int stride = dest->stride; int tmp, tmp2; uint8_t *data; data = dest->real_pixels; for (i = 0; i < top; i++) { memset (data, *val, real_width); data += stride; } if (left || right) { tmp = height; tmp2 = left + width; for (i = 0; i < tmp; i++) { memset (data, *val, left); memset (data + tmp2, *val, right); data += stride; } } else { data += stride * height; } for (i = 0; i < bottom; i++) { memset (data, *val, real_width); data += stride; } } void vs_fill_borders_Y16 (const VSImage * dest, const uint16_t val) { int i; int top = dest->border_top, bottom = dest->border_bottom; int left = dest->border_left, right = dest->border_right; int width = dest->width; int height = dest->height; int real_width = dest->real_width; int stride = dest->stride; int tmp, tmp2; uint8_t *data; data = dest->real_pixels; for (i = 0; i < top; i++) { video_scale_orc_splat_u16 ((uint16_t *) data, val, real_width); data += stride; } if (left || right) { tmp = height; tmp2 = (left + width) * 2; for (i = 0; i < tmp; i++) { video_scale_orc_splat_u16 ((uint16_t *) data, val, left); video_scale_orc_splat_u16 ((uint16_t *) (data + tmp2), val, right); data += stride; } } else { data += stride * height; } for (i = 0; i < bottom; i++) { video_scale_orc_splat_u16 ((uint16_t *) data, val, real_width); data += stride; } } void vs_fill_borders_RGB565 (const VSImage * dest, const uint8_t * val) { int i; int top = dest->border_top, bottom = dest->border_bottom; int left = dest->border_left, right = dest->border_right; int width = dest->width; int height = dest->height; int real_width = dest->real_width; int stride = dest->stride; int tmp, tmp2; uint8_t *data; uint16_t v = READ_UINT16 (val); data = dest->real_pixels; for (i = 0; i < top; i++) { video_scale_orc_splat_u16 ((uint16_t *) data, v, real_width); data += stride; } if (left || right) { tmp = height; tmp2 = (left + width) * 2; for (i = 0; i < tmp; i++) { video_scale_orc_splat_u16 ((uint16_t *) data, v, left); video_scale_orc_splat_u16 ((uint16_t *) (data + tmp2), v, right); data += stride; } } else { data += stride * height; } for (i = 0; i < bottom; i++) { video_scale_orc_splat_u16 ((uint16_t *) data, v, real_width); data += stride; } } void vs_fill_borders_RGB555 (const VSImage * dest, const uint8_t * val) { int i; int top = dest->border_top, bottom = dest->border_bottom; int left = dest->border_left, right = dest->border_right; int width = dest->width; int height = dest->height; int real_width = dest->real_width; int stride = dest->stride; int tmp, tmp2; uint8_t *data; uint16_t v = READ_UINT16 (val); data = dest->real_pixels; for (i = 0; i < top; i++) { video_scale_orc_splat_u16 ((uint16_t *) data, v, real_width); data += stride; } if (left || right) { tmp = height; tmp2 = (left + width) * 2; for (i = 0; i < tmp; i++) { video_scale_orc_splat_u16 ((uint16_t *) data, v, left); video_scale_orc_splat_u16 ((uint16_t *) (data + tmp2), v, right); data += stride; } } else { data += stride * height; } for (i = 0; i < bottom; i++) { video_scale_orc_splat_u16 ((uint16_t *) data, v, real_width); data += stride; } } void vs_fill_borders_AYUV64 (const VSImage * dest, const uint8_t * val) { int i; int top = dest->border_top, bottom = dest->border_bottom; int left = dest->border_left, right = dest->border_right; int width = dest->width; int height = dest->height; int real_width = dest->real_width; int stride = dest->stride; int tmp, tmp2; uint8_t *data; uint64_t v; v = (((guint32) val[0]) << 8) | (((guint32) val[1]) << 24) | (((guint64) val[2]) << 40) | (((guint64) val[3]) << 56); data = dest->real_pixels; for (i = 0; i < top; i++) { video_scale_orc_splat_u64 ((uint64_t *) data, v, real_width); data += stride; } if (left || right) { tmp = height; tmp2 = (left + width) * 8; for (i = 0; i < tmp; i++) { video_scale_orc_splat_u64 ((uint64_t *) data, v, left); video_scale_orc_splat_u64 ((uint64_t *) (data + tmp2), v, right); data += stride; } } else { data += stride * height; } for (i = 0; i < bottom; i++) { video_scale_orc_splat_u64 ((uint64_t *) data, v, real_width); data += stride; } }