<p>This view allows the user to transform a source image into a new image with a different pixel format and size. Internally, when the <strong>Change pixel format</strong> button is clicked, the <span style="font-family: Courier New,Courier,monospace;">_change_format</span> callback is called and the <span style="font-family: Courier New,Courier,monospace;">_process</span> method executed:</p>
<pre class="prettyprint">
+int image_sample_util_resize(const int src_w, const int src_h, const uchar *src, const int dest_w, const int dest_h, uchar *dest)
+{
+ if (src_w <= 0 || src_h <= 0 || !src || dest_w <= 0 || dest_h <= 0 || !dest)
+ {
+ return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+ }
+
+ int h = 0, w = 0;
+ float t, u, coef;
+ t = u = coef = 0.0;
+ float c1, c2, c3, c4;
+ c1 = c2 = c3 = c4 = 0.0;
+ u_int32_t pixel1, pixel2, pixel3, pixel4;
+ pixel1 = pixel2 = pixel3 = pixel4 = 0;
+ u_int32_t *pixel_res = NULL;
+ u_int32_t red, green, blue, alpha;
+ red = green = blue = alpha = 0;
+
+ int i = 0, j = 0;
+ for (j = 0; j < dest_h; j++)
+ {
+ coef = (float) (j) / (float) (dest_h - 1) * (src_h - 1);
+ h = (int) floor(coef);
+ if (h < 0)
+ {
+ h = 0;
+ }
+ else
+ {
+ if (h >= src_h - 1)
+ {
+ h = src_h - 2;
+ }
+ }
+ u = coef - h;
+
+ for (i = 0; i < dest_w; i++)
+ {
+ coef = (float) (i) / (float) (dest_w - 1) * (src_w - 1);
+ w = (int) floor(coef);
+ if (w < 0)
+ {
+ w = 0;
+ }
+ else
+ {
+ if (w >= src_w - 1)
+ {
+ w = src_w - 2;
+ }
+ }
+ t = coef - w;
+
+ c1 = (1 - t) * (1 - u);
+ c2 = t * (1 - u);
+ c3 = t * u;
+ c4 = (1 - t) * u;
+
+ pixel1 = *((u_int32_t*) (src + BRGA_BPP * (h * src_w + w)));
+ pixel2 = *((u_int32_t*) (src + BRGA_BPP * (h * src_w + w + 1)));
+ pixel3 = *((u_int32_t*) (src + BRGA_BPP * ((h + 1) * src_w + w + 1)));
+ pixel4 = *((u_int32_t*) (src + BRGA_BPP * ((h + 1) * src_w + w)));
+
+ blue = (uchar) pixel1 * c1 + (uchar) pixel2 * c2
+ + (uchar) pixel3 * c3 + (uchar) pixel4 * c4;
+ green = (uchar) (pixel1 >> 8) * c1
+ + (uchar) (pixel2 >> 8) * c2
+ + (uchar) (pixel3 >> 8) * c3
+ + (uchar) (pixel4 >> 8) * c4;
+ red = (uchar) (pixel1 >> 16) * c1
+ + (uchar) (pixel2 >> 16) * c2
+ + (uchar) (pixel3 >> 16) * c3
+ + (uchar) (pixel4 >> 16) * c4;
+ alpha = (uchar) (pixel1 >> 24) * c1
+ + (uchar) (pixel2 >> 24) * c2
+ + (uchar) (pixel3 >> 24) * c3
+ + (uchar) (pixel4 >> 24) * c4;
+
+ pixel_res = (u_int32_t*)(dest + BRGA_BPP * (i + j * dest_w));
+ *pixel_res = ((u_int32_t) alpha << 24) | ((u_int32_t) red << 16)
+ | ((u_int32_t) green << 8) | (blue);
+ }
+ }
+ return IMAGE_UTIL_ERROR_NONE;
+}
+
static bool _process(image_converter_view *view, double scale)
{
RETVM_IF(NULL == view, false, "view is NULL");
dest_buff = malloc(dest_size);
RETVM_IF(NULL == dest_buff, false, "malloc destination buffer error %d", dest_size);
- error = image_util_resize(dest_buff, &dest_width , &dest_height, src_buff, w, h, IMAGE_UTIL_COLORSPACE_BGRA8888);
+ error = image_sample_util_resize(w, h, src_buff, dest_width , dest_height, dest_buff);
if (IMAGE_UTIL_ERROR_NONE == error)
{
Evas_Object* im = evas_object_image_filled_add(evas_object_evas_get(view->layout));
}
else
{
- INF("Image buffer manipulation: image_util_resize error");
+ INF("Image buffer manipulation: image_sample_util_resize error");
result = false;
}
free(dest_buff);
<p>This view allows the user to extract frames from the input video stream. Internally, when the frame slider is changed, the <span style="font-family: Courier New,Courier,monospace;">_sliderbar_changed_cb</span> callback is called and the <span style="font-family: Courier New,Courier,monospace;">frame_extractor_frame_get</span> method is executed:</p>
<pre class="prettyprint">
+static inline rgb16 bgra_to_rgb(const bgra32 src)
+{
+ rgb16 result = (rgb16)
+ ( ((src.r >> (RGB32_CHANEL_BIT_SIZE - RGB16_R_SIZE)) << RGB16_R_SHIFT)
+ | ((src.g >> (RGB32_CHANEL_BIT_SIZE - RGB16_G_SIZE)) << RGB16_G_SHIFT)
+ | ((src.b >> (RGB32_CHANEL_BIT_SIZE - RGB16_B_SIZE)) << RGB16_B_SHIFT));
+ return result;
+}
+
+static inline bgra32 rgb_to_bgra(const rgb16 src)
+{
+ bgra32 result = {};
+ result.r = (uchar)( src >> RGB16_R_SHIFT) << (RGB32_CHANEL_BIT_SIZE - RGB16_R_SIZE);
+ result.g = (uchar)( src >> RGB16_G_SHIFT) << (RGB32_CHANEL_BIT_SIZE - RGB16_G_SIZE);
+ result.b = (uchar)( src >> RGB16_B_SHIFT) << (RGB32_CHANEL_BIT_SIZE - RGB16_B_SIZE);
+ result.a = RGB32_DEFAULT_ALPHA;
+ return result;
+}
+
+static uchar clamp(int x)
+{
+ if (x > 255)
+ {
+ x = 255;
+ }
+ else if (x < 0)
+ {
+ x = 0;
+ }
+ return x;
+}
+
+static inline uchar bgra_to_yuv_y(const bgra32 src)
+{
+ return ((66*src.r + 129*src.g + 25*src.b) >> 8) + 16;
+}
+
+static inline uchar bgra_to_yuv_u(const bgra32 src)
+{
+ return ((-38*src.r + -74*src.g + 112*src.b) >> 8) + 128;
+}
+
+static inline uchar bgra_to_yuv_v(const bgra32 src)
+{
+ return ((112*src.r + -94*src.g + -18*src.b) >> 8) + 128;
+}
+
+static inline uchar yuv_to_r(const uchar yuv_y, const uchar yuv_u, const uchar yuv_v)
+{
+ return clamp(yuv_y + 1.402 * (yuv_v - 128));
+}
+
+static inline uchar yuv_to_g(const uchar yuv_y, const uchar yuv_u, const uchar yuv_v)
+{
+ return clamp(yuv_y - 0.344 * (yuv_u - 128) - 0.714 * (yuv_v - 128));
+}
+
+static inline uchar yuv_to_b(const uchar yuv_y, const uchar yuv_u, const uchar yuv_v)
+{
+ return clamp(yuv_y + 1.772 * (yuv_u - 128));
+}
+
+static void _convert_bgra8888_to_yuv420( uchar *dest, const uchar *src,
+ const int width, const int height,
+ const int d_size, const int s_size)
+{
+ unsigned int src_stride = (s_size / height);
+ unsigned int pix_count = width * height;
+ unsigned int upos = pix_count;
+ unsigned int vpos = upos + upos / 4;
+
+ unsigned int y;
+ for (y = 0; y < height; ++y )
+ {
+ const bgra32* src_pixel = (const bgra32*) &(src[y * src_stride]);
+ unsigned int dest_line_pos = width * y;
+
+ if( !(y % 2) )
+ {
+ unsigned int x;
+ for (x = 0; x < width; x += 2 )
+ {
+ bgra32 pixel = src_pixel[x];
+
+ dest[dest_line_pos + x] = bgra_to_yuv_y(pixel);
+ dest[upos++] = bgra_to_yuv_u(pixel);
+ dest[vpos++] = bgra_to_yuv_v(pixel);
+
+ pixel = src_pixel[x + 1];
+ dest[dest_line_pos + x + 1] = bgra_to_yuv_y(pixel);
+ }
+ }
+ else
+ {
+ unsigned int x;
+ for (x = 0; x < width; ++x)
+ {
+ dest[dest_line_pos + x] = bgra_to_yuv_y( src_pixel[x] );
+ }
+ }
+ }
+}
+
+static void _convert_bgra8888_to_rgb565( uchar *dest, const uchar *src,
+ const int width, const int height,
+ const int d_size, const int s_size)
+{
+ unsigned int src_stride = (s_size / height);
+ unsigned int dest_stride = (d_size / height);
+
+ unsigned int y;
+ for (y = 0; y < height; ++y)
+ {
+ const bgra32* src_pixel = (const bgra32*) &(src[y * src_stride]);
+ rgb16* dest_pixel = (rgb16*) &(dest[y * dest_stride]);
+ unsigned int x;
+ for (x = 0; x < width; ++x)
+ {
+ dest_pixel[x] = bgra_to_rgb( src_pixel[x]);
+ }
+ }
+}
+
+static void _convert_rgb565_to_yuv420( uchar *dest, const uchar *src,
+ const int width, const int height,
+ const int d_size, const int s_size)
+{
+ unsigned int src_stride = (s_size / height);
+ unsigned int pix_count = width * height;
+ unsigned int upos = pix_count;
+ unsigned int vpos = upos + upos / 4;
+
+ unsigned int y;
+ for (y = 0; y < height; ++y )
+ {
+ const rgb16* src_pixel = (const rgb16*) &(src[y * src_stride]);
+ unsigned int dest_line_pos = width * y;
+
+ if ( !(y % 2) )
+ {
+ unsigned int x;
+ for (x = 0; x < width; x += 2 )
+ {
+ bgra32 pixel = rgb_to_bgra(src_pixel[x]);
+
+ dest[dest_line_pos + x] = bgra_to_yuv_y(pixel);
+ dest[upos++] = bgra_to_yuv_u(pixel);
+ dest[vpos++] = bgra_to_yuv_v(pixel);
+
+ pixel = rgb_to_bgra(src_pixel[x + 1]);
+ dest[dest_line_pos + x + 1] = bgra_to_yuv_y(pixel);
+ }
+ }
+ else
+ {
+ unsigned int x;
+ for (x = 0; x < width; ++x)
+ {
+ bgra32 pixel = rgb_to_bgra(src_pixel[x]);
+ dest[dest_line_pos + x] = bgra_to_yuv_y(pixel);
+ }
+ }
+ }
+}
+
+static void _convert_rgb565_to_bgra8888( uchar *dest, const uchar *src,
+ const int width, const int height,
+ const int d_size, const int s_size)
+{
+ unsigned int src_stride = (s_size / height);
+ unsigned int dest_stride = (d_size / height);
+
+ unsigned int y;
+ for (y = 0; y < height; ++y)
+ {
+ const rgb16* src_pixel = (const rgb16*) &(src[y * src_stride]);
+ bgra32* dest_pixel = (bgra32*) &(dest[y * dest_stride]);
+ unsigned int x;
+ for (x = 0; x < width; ++x)
+ {
+ dest_pixel[x] = rgb_to_bgra( src_pixel[x]);
+ }
+ }
+}
+
+static void _convert_yuv420_to_rgb565( uchar *dest, const uchar *src,
+ const int width, const int height,
+ const int d_size, const int s_size)
+{
+ unsigned int pix_count = width * height;
+ unsigned int dest_stride = (d_size / height);
+
+ unsigned int y;
+ for (y = 0; y < height; y++)
+ {
+ rgb16* dest_pixel = (rgb16*) &(dest[y*dest_stride]);
+ unsigned int x;
+ for (x = 0; x < width; x++)
+ {
+ uchar yuv_y = src[ y*width + x];
+ uchar yuv_u = src[ (int)(pix_count + (y/2)*(width/2) + x/2)];
+ uchar yuv_v = src[ (int)(pix_count*1.25 + (y/2)*(width/2) + x/2)];
+
+ dest_pixel[x] =
+ ( ( yuv_to_r(yuv_y, yuv_u, yuv_v) >> (RGB32_CHANEL_BIT_SIZE - RGB16_R_SIZE)) << RGB16_R_SHIFT)
+ | ((yuv_to_g(yuv_y, yuv_u, yuv_v) >> (RGB32_CHANEL_BIT_SIZE - RGB16_G_SIZE)) << RGB16_G_SHIFT)
+ | ((yuv_to_b(yuv_y, yuv_u, yuv_v) >> (RGB32_CHANEL_BIT_SIZE - RGB16_B_SIZE)) << RGB16_B_SHIFT);
+ }
+ }
+}
+
+static void _convert_yuv420_to_bgra8888( uchar *dest, const uchar *src,
+ const int width, const int height,
+ const int d_size, const int s_size)
+{
+ unsigned int pix_count = width * height;
+ unsigned int dest_stride = (d_size / height);
+
+ unsigned int y;
+ for (y = 0; y < height; y++)
+ {
+ bgra32* dest_pixel = (bgra32*) &(dest[dest_stride * y]);
+ unsigned int x;
+ for (x = 0; x < width; x++)
+ {
+ uchar yuv_y = src[ y*width + x];
+ uchar yuv_u = src[ (int)(pix_count + (y/2)*(width/2) + x/2)];
+ uchar yuv_v = src[ (int)(pix_count*1.25 + (y/2)*(width/2) + x/2)];
+
+ dest_pixel[x].r = yuv_to_r(yuv_y, yuv_u, yuv_v);
+ dest_pixel[x].g = yuv_to_g(yuv_y, yuv_u, yuv_v);
+ dest_pixel[x].b = yuv_to_b(yuv_y, yuv_u, yuv_v);
+ dest_pixel[x].a = RGB32_DEFAULT_ALPHA;
+ }
+ }
+}
+
+static void _convert_yuv422_to_bgra8888( uchar *dest, const uchar *src,
+ const int width, const int height,
+ const int d_size, const int s_size)
+{
+ unsigned int dest_stride = (d_size / height);
+ uchar yuv_u, yuv_v, yuv_y1, yuv_y2;
+ yuv_u = yuv_v = yuv_y1 = yuv_y2 = 0;
+ unsigned int y;
+ for (y = 0; y < height; y++)
+ {
+ bgra32* dest_pixel = (bgra32*) &(dest[dest_stride * y]);
+ const uchar * src_line = &(src[2 * y * width]);
+ unsigned int x;
+ for (x = 0; x < width; x += 2)
+ {
+ yuv_y1 = src_line[2 * x + 1];
+ yuv_y2 = src_line[2 * x + 3];
+ yuv_u = src_line[2 * x];
+ yuv_v = src_line[2 * x + 2];
+
+ dest_pixel[x].r = yuv_to_r(yuv_y1, yuv_u, yuv_v);
+ dest_pixel[x].g = yuv_to_g(yuv_y1, yuv_u, yuv_v);
+ dest_pixel[x].b = yuv_to_b(yuv_y1, yuv_u, yuv_v);
+ dest_pixel[x].a = RGB32_DEFAULT_ALPHA;
+
+ dest_pixel[x + 1].r = yuv_to_r(yuv_y2, yuv_u, yuv_v);
+ dest_pixel[x + 1].g = yuv_to_g(yuv_y2, yuv_u, yuv_v);
+ dest_pixel[x + 1].b = yuv_to_b(yuv_y2, yuv_u, yuv_v);
+ dest_pixel[x + 1].a = RGB32_DEFAULT_ALPHA;
+ }
+ }
+}
+
+static void _convert_rgb888_to_bgra8888( uchar *dest, const uchar *src,
+ const int width, const int height,
+ const int d_size, const int s_size)
+{
+ unsigned int src_stride = (s_size / height);
+ unsigned int dest_stride = (d_size / height);
+
+ unsigned int y;
+ for (y = 0; y < height; ++y)
+ {
+ const uchar* src_pixel = &(src[y * src_stride]);
+ bgra32* dest_pixel = (bgra32*) &(dest[y * dest_stride]);
+ unsigned int x;
+ for (x = 0; x < width; ++x)
+ {
+ dest_pixel[x].r = src_pixel[RGB24_BPP * x];
+ dest_pixel[x].g = src_pixel[RGB24_BPP * x + 1];
+ dest_pixel[x].b = src_pixel[RGB24_BPP * x + 2];
+ dest_pixel[x].a = RGB32_DEFAULT_ALPHA;
+ }
+ }
+}
+
+int image_sample_util_convert_colorspace( uchar *dest , image_util_colorspace_e dest_colorspace,
+ const uchar *src , int width, int height,
+ image_util_colorspace_e src_colorspace)
+{
+ RETVM_IF(NULL == src, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "source buffer in NULL");
+ RETVM_IF(NULL == dest, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "destination buffer in NULL");
+ RETVM_IF(width <= 0 || height <= 0, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "width or heightis incorrect");
+ int error = IMAGE_UTIL_ERROR_NONE;
+
+
+ if (IMAGE_UTIL_COLORSPACE_BGRA8888 != src_colorspace
+ && IMAGE_UTIL_COLORSPACE_RGB565 != src_colorspace
+ && IMAGE_UTIL_COLORSPACE_I420 != src_colorspace
+ && IMAGE_UTIL_COLORSPACE_UYVY != src_colorspace
+ && IMAGE_UTIL_COLORSPACE_RGB888 != src_colorspace)
+ {
+ ERR("src_colorspace not supported yet");
+ return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
+ }
+
+ if (IMAGE_UTIL_COLORSPACE_BGRA8888 != dest_colorspace
+ && IMAGE_UTIL_COLORSPACE_RGB565 != dest_colorspace
+ && IMAGE_UTIL_COLORSPACE_I420 != dest_colorspace)
+ {
+ ERR("dest_colorspace not supported yet");
+ return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
+ }
+
+ unsigned int dest_size = 0;
+ error = image_util_calculate_buffer_size(width, height, dest_colorspace, &dest_size);
+ RETVM_IF(IMAGE_UTIL_ERROR_NONE != error, error, "image_util_calculate_buffer_size error");
+ unsigned int src_size = 0;
+ error = image_util_calculate_buffer_size(width, height, src_colorspace, &src_size);
+ RETVM_IF(IMAGE_UTIL_ERROR_NONE != error, error, "image_util_calculate_buffer_size error");
+
+ if (dest_colorspace == src_colorspace)
+ {
+ memcpy(dest, src, src_size);
+ return error;
+ }
+
+
+ if (IMAGE_UTIL_COLORSPACE_BGRA8888 == src_colorspace)
+ {
+ if (IMAGE_UTIL_COLORSPACE_I420 == dest_colorspace)
+ {
+ _convert_bgra8888_to_yuv420(dest, src, width, height, dest_size, src_size);
+ }
+ else
+ {
+ _convert_bgra8888_to_rgb565(dest, src, width, height, dest_size, src_size);
+ }
+ }
+ else if (IMAGE_UTIL_COLORSPACE_RGB565 == src_colorspace)
+ {
+ if (IMAGE_UTIL_COLORSPACE_I420 == dest_colorspace)
+ {
+ _convert_rgb565_to_yuv420(dest, src, width, height, dest_size, src_size);
+ }
+ else
+ {
+ _convert_rgb565_to_bgra8888(dest, src, width, height, dest_size, src_size);
+ }
+ }
+ else if (IMAGE_UTIL_COLORSPACE_I420 == src_colorspace)
+ {
+ if (IMAGE_UTIL_COLORSPACE_RGB565 == dest_colorspace)
+ {
+ _convert_yuv420_to_rgb565(dest, src, width, height, dest_size, src_size);
+ }
+ else
+ {
+ _convert_yuv420_to_bgra8888(dest, src, width, height, dest_size, src_size);
+ }
+ }
+ else if (IMAGE_UTIL_COLORSPACE_UYVY == src_colorspace)
+ {
+ if (IMAGE_UTIL_COLORSPACE_BGRA8888 == dest_colorspace)
+ {
+ _convert_yuv422_to_bgra8888(dest, src, width, height, dest_size, src_size);
+ }
+ else
+ {
+ ERR("dest_colorspace not supported yet");
+ return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
+ }
+ }
+ else
+ {
+ if (IMAGE_UTIL_COLORSPACE_BGRA8888 == dest_colorspace)
+ {
+ _convert_rgb888_to_bgra8888(dest, src, width, height, dest_size, src_size);
+ }
+ else
+ {
+ ERR("dest_colorspace not supported yet");
+ return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
+ }
+ }
+
+ return error;
+}
+
bool frame_extractor_frame_get(const frame_extractor *extractor, unsigned char **frame, int pos)
{
bool result = false;
*frame = malloc(size + (extractor->width * extractor->height) * ARGB_PIXEL_SIZE);
if (*frame)
{
- error = image_util_convert_colorspace(*frame , IMAGE_UTIL_COLORSPACE_BGRA8888, buf, extractor->width, extractor->height, IMAGE_UTIL_COLORSPACE_RGB888);
+ error = image_sample_util_convert_colorspace(*frame , IMAGE_UTIL_COLORSPACE_BGRA8888, buf, extractor->width, extractor->height, IMAGE_UTIL_COLORSPACE_RGB888);
if (IMAGE_UTIL_ERROR_NONE == error)
{
result = true;