From: giwoong.kim Date: Fri, 3 Aug 2012 12:30:09 +0000 (+0900) Subject: [Title] added maru_rotozomm function X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.1~1528^2~27 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0aadabe11018e60bb026319f50f9c48e56ed9a90;p=sdk%2Femulator%2Fqemu.git [Title] added maru_rotozomm function [Type] feature [Module] Emulator / skin [Priority] major [Jira#] [Redmine#] [Problem] [Cause] anti-aliasing [Solution] [TestCase] RockPaperScissors --- diff --git a/tizen/src/maru_sdl.c b/tizen/src/maru_sdl.c index ed3bc4ded8..aeeff69fda 100644 --- a/tizen/src/maru_sdl.c +++ b/tizen/src/maru_sdl.c @@ -33,6 +33,7 @@ #include "maru_sdl.h" #include "emul_state.h" #include "sdl_rotate.h" +#include "maru_sdl_rotozoom.h" #include "maru_finger.h" #include "hw/maru_pm.h" #include "debug_ch.h" @@ -347,15 +348,19 @@ static void qemu_update(void) { //sdl surface SDL_Surface *processing_screen = NULL; - if (current_scale_factor != 1.0 || current_screen_degree != 0.0) { + if (current_scale_factor <= 0.5) { + /* zoom filter : c00 c0-1 c01 c-10 c10 */ + processing_screen = maru_rotozoom(surface_qemu, (int)current_screen_degree, current_scale_factor); + SDL_BlitSurface(processing_screen, NULL, surface_screen, NULL); + } else if (current_scale_factor != 1.0 || current_screen_degree != 0.0) { // workaround // set color key 'magenta' surface_qemu->format->colorkey = 0xFF00FF; - //image processing + /* zoom filter : c00 c01 c10 c11 */ processing_screen = rotozoomSurface(surface_qemu, current_screen_degree, current_scale_factor, 1); SDL_BlitSurface(processing_screen, NULL, surface_screen, NULL); - } else { + } else { //as-is SDL_BlitSurface(surface_qemu, NULL, surface_screen, NULL); } diff --git a/tizen/src/maru_sdl_rotozoom.h b/tizen/src/maru_sdl_rotozoom.h new file mode 100644 index 0000000000..d4c747fbfc --- /dev/null +++ b/tizen/src/maru_sdl_rotozoom.h @@ -0,0 +1,214 @@ +/* + * Rotation & Scaling of SDL surface + * + * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * GiWoong Kim + * SeokYeon Hwang + * YeongKyoon Lee + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributors: + * - S-Core Co., Ltd + * + */ + + +#ifndef MARU_SDL_ROTOZOOM_H_ +#define MARU_SDL_ROTOZOOM_H_ + +#include +#include + + +#define R_CHANNEL_MASK 0x00ff0000 +#define G_CHANNEL_MASK 0x0000ff00 +#define B_CHANNEL_MASK 0x000000ff + +SDL_Surface *maru_rotozoom(SDL_Surface *rz_src, int angle, double zoom); + +static void interpolate_pixel_cpy(unsigned int *dst, unsigned int *src_addr, unsigned int src_w, unsigned int src_h, int x, int y) +{ +#if 0 + int i, j, n, m; + double mask[3][3] = { {0., 0.19, 0.}, {0.19, 0.24, 0.19}, {0., 0.19, 0.} }; + double sum_r = 0; //0x00ff0000 + double sum_g = 0; //0x0000ff00 + double sum_b = 0; //0x000000ff + int index; + + n = 0; + for(i = x - 1; i <= x + 1; i++, n++) { + m = 0; + for(j = y - 1; j <= y + 1; j++, m++) { + if (mask[n][m] == 0 || i < 0 || i > src_h || j < 0 || j > src_w) { //outline + index = (x * src_w) + y; + sum_r += mask[n][m] * (double)((src_addr[index] & 0x00ff0000) >> 16); + sum_g += mask[n][m] * (double)((src_addr[index] & 0x0000ff00) >> 8); + sum_b += mask[n][m] * (double)(src_addr[index] & 0x000000ff); + } else { + index = (i * src_w) + j; + sum_r += mask[n][m] * (double)((src_addr[index] & 0x00ff0000) >> 16); + sum_g += mask[n][m] * (double)((src_addr[index] & 0x0000ff00) >> 8); + sum_b += mask[n][m] * (double)(src_addr[index] & 0x000000ff); + } + } + } + + *dst = 0 | (((unsigned int) round(sum_r)) << 16) | + (((unsigned int) round(sum_g)) << 8) | + (((unsigned int) round(sum_b)) & 0x000000ff); +#endif + + unsigned int sum_r = 0; //0x00ff0000 + unsigned int sum_g = 0; //0x0000ff00 + unsigned int sum_b = 0; //0x000000ff + + unsigned int index = (x * src_w) + y; + unsigned int index_w = (y - 1 < 0) ? index : index - 1; + unsigned int index_e = (y + 1 > src_w) ? index : index + 1; + unsigned int index_n = (x - 1 < 0) ? index : ((x - 1) * src_w) + y; + unsigned int index_s = (x + 1 > src_h) ? index : ((x + 1) * src_w) + y; + + sum_r = (src_addr[index] & R_CHANNEL_MASK) + + (src_addr[index_w] & R_CHANNEL_MASK) + (src_addr[index_e] & R_CHANNEL_MASK) + + (src_addr[index_n] & R_CHANNEL_MASK) + (src_addr[index_s] & R_CHANNEL_MASK); + + sum_g = (src_addr[index] & G_CHANNEL_MASK) + + (src_addr[index_w] & G_CHANNEL_MASK) + (src_addr[index_e] & G_CHANNEL_MASK) + + (src_addr[index_n] & G_CHANNEL_MASK) + (src_addr[index_s] & G_CHANNEL_MASK); + + sum_b = (src_addr[index] & B_CHANNEL_MASK) + + (src_addr[index_w] & B_CHANNEL_MASK) + (src_addr[index_e] & B_CHANNEL_MASK) + + (src_addr[index_n] & B_CHANNEL_MASK) + (src_addr[index_s] & B_CHANNEL_MASK); + + *dst = 0xff000000 | ((sum_r / 5) & R_CHANNEL_MASK) | ((sum_g / 5) & G_CHANNEL_MASK) | ((sum_b / 5) & B_CHANNEL_MASK); +} + +//TODO: optimization +SDL_Surface *maru_rotozoom(SDL_Surface *rz_src, int angle, double zoom) +{ +#define PRECISION 4096 +#define SHIFT 12 + + int i, j; + SDL_Surface *rz_dst; + unsigned int dst_width = (unsigned int)(rz_src->w * zoom); + unsigned int dst_height = (unsigned int)(rz_src->h * zoom); + + switch(angle) { + case 90: + case 270: + rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dst_height, dst_width, 32, + rz_src->format->Rmask, rz_src->format->Gmask, + rz_src->format->Bmask, rz_src->format->Amask); + break; + case 0: + case 180: + default: + rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dst_width, dst_height, 32, + rz_src->format->Rmask, rz_src->format->Gmask, + rz_src->format->Bmask, rz_src->format->Amask); + break; + } //TODO: exile + + unsigned int sx = (rz_src->w) * PRECISION / dst_width; + unsigned int sy = (rz_src->h) * PRECISION / dst_height; //TODO: exile + unsigned int row_index = 0; + unsigned int col_index = 0; + + unsigned int *out = NULL; + unsigned int *row = NULL; + + SDL_LockSurface(rz_src); + + switch(angle) { + case 0: + out = (unsigned int *) rz_dst->pixels; + + for (i = 0; i < dst_height; i++, out += dst_width) { + row_index = (i * sy) >> SHIFT; + row = ((unsigned int *) rz_src->pixels) + (row_index * rz_src->w); + + for (j = 0; j < dst_width; j++) { + col_index = (sx * j) >> SHIFT; + //out[j] = row[col_index]; + interpolate_pixel_cpy(&out[j], ((unsigned int *) rz_src->pixels), + rz_src->w, rz_src->h, row_index, col_index); + } + } + break; + + case 90: //landscape + for (i = 0; i < dst_height; i++) { + row_index = (i * sy) >> SHIFT; + row = ((unsigned int *) rz_src->pixels) + (row_index * rz_src->w); + + out = ((unsigned int *) rz_dst->pixels) + i; + + for (j = 0; j < dst_width; j++, out += dst_height) { + col_index = (sx * j) >> SHIFT; + //out[0] = row[rz_src->w - col_index - 1]; + interpolate_pixel_cpy(&out[0], ((unsigned int *) rz_src->pixels), + rz_src->w, rz_src->h, row_index, rz_src->w - col_index - 1); + } + } + break; + + case 180: + out = (unsigned int *) rz_dst->pixels; + + for (i = 0; i < dst_height; i++, out += dst_width) { + row_index = ((dst_height - i - 1) * sy) >> SHIFT; + row = ((unsigned int *) rz_src->pixels) + (row_index * rz_src->w); + + for (j = 0; j < dst_width; j++) { + col_index = (sx * j) >> SHIFT; + //out[dst_width - j - 1] = row[col_index]; + interpolate_pixel_cpy(&out[dst_width - j - 1], ((unsigned int *) rz_src->pixels), + rz_src->w, rz_src->h, row_index, col_index); + } + } + break; + + case 270: //reverse landscape + for (i = 0; i < dst_height; i++) { + row_index = ((dst_height - i - 1) * sy) >> SHIFT; + row = ((unsigned int *) rz_src->pixels) + (row_index * rz_src->w); + + out = ((unsigned int *) rz_dst->pixels) + i; + + for (j = 0; j < dst_width; j++, out += dst_height) { + col_index = (sx * j) >> SHIFT; + //out[0] = row[col_index]; + interpolate_pixel_cpy(&out[0], ((unsigned int *) rz_src->pixels), + rz_src->w, rz_src->h, row_index, col_index); + } + } + break; + + default: + fprintf(stdout, "not supported angle factor (angle=%d)\n", angle); + return NULL; + } + + SDL_UnlockSurface(rz_src); + + return rz_dst; +} + +#endif /* MARU_SDL_ROTOZOOM_H_ */