[Title] added maru_rotozomm function
authorgiwoong.kim <giwoong.kim@samsung.com>
Fri, 3 Aug 2012 12:30:09 +0000 (21:30 +0900)
committergiwoong.kim <giwoong.kim@samsung.com>
Fri, 3 Aug 2012 12:30:09 +0000 (21:30 +0900)
[Type] feature
[Module] Emulator / skin
[Priority] major
[Jira#]
[Redmine#]
[Problem]
[Cause] anti-aliasing
[Solution]
[TestCase] RockPaperScissors

tizen/src/maru_sdl.c
tizen/src/maru_sdl_rotozoom.h [new file with mode: 0644]

index ed3bc4ded8a4e72a79a773c2bc4961f7041c4998..aeeff69fdac3eb2e0573742777a0ba1f1bad256b 100644 (file)
@@ -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 (file)
index 0000000..d4c747f
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * Rotation & Scaling of SDL surface
+ *
+ * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ *
+ * 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 <SDL.h>
+#include <SDL_syswm.h>
+
+
+#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_ */