recovery_gui_common : apply rotation logic following with fota_gui_common 88/247988/3
authordyamy-lee <dyamy.lee@samsung.com>
Wed, 18 Nov 2020 06:13:55 +0000 (15:13 +0900)
committerdyamy-lee <dyamy.lee@samsung.com>
Mon, 23 Nov 2020 08:41:18 +0000 (17:41 +0900)
Change-Id: Ic5406dd52e6610be5d1d2af68405f8163bf5ae3b

recovery_gui_common/CMakeLists.txt
recovery_gui_common/recovery_gr_direct_common.c
recovery_gui_common/recovery_png.c
recovery_gui_common/recovery_png.h

index a88d3dc59feb280e32c06fd530395535a4c65810..af4ef769a96b6ad58d671c74d4c1ce7ef90374d9 100644 (file)
@@ -22,6 +22,7 @@ MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
 
 INCLUDE(FindPkgConfig)
 pkg_check_modules(gui_pkgs REQUIRED
+       pixman-1
        libtbm
        libtdm
        libpng
@@ -57,6 +58,7 @@ ADD_EXECUTABLE(${RECOVERY_GUI_COMMON} ${GUI_SRCS_COMMON})
 TARGET_LINK_LIBRARIES(${RECOVERY_GUI_COMMON} ${gui_pkgs_LDFLAGS} ${LIBS} -lpthread)
 
 ADD_DEFINITIONS("-DRESDIR=\"${RESDIR}\"")
+ADD_DEFINITIONS("-DROTATE=0")
 #INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/res/common/images DESTINATION ${RESDIR_COMMON})
 
 INSTALL(TARGETS ${RECOVERY_GUI_COMMON} DESTINATION ${BINDIR})
index b7e9d712e66b559e737f61457c29f37a7c6f2292..021ae2c204390cca081351340a65320f3f9a0c65 100644 (file)
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <pixman.h>
 
 #include "recovery_gui_general.h"
 #include "recovery_png.h"
 #define MAX_PATH 256
 #define MAX_FILE_PATH           512
 
+#if !defined(ROTATE)
+#define ROTATE 0
+#endif
+
 #if !defined(RESDIR)
 #define RESDIR                 "/usr/share/res"
 #endif
@@ -55,6 +60,10 @@ const int x_offset_main_bg_text_pos = 518;
 const int y_offset_main_bg_text_pos = 300;
 const int x_offset_prog_bar_img_pos = 240;
 const int y_offset_prog_bar_img_pos = 355;
+int rotate_step = 0;
+int rollback_step = 0;
+int img_buf_width = 0;
+int img_buf_height = 0;
 
 FbInfo s_fbi;
 tdm_if_disp s_disp;
@@ -153,7 +162,7 @@ void fb_clear_screen(FbInfo *fbi, unsigned int color)
 /*-----------------------------------------------------------------------------
   _gr_direct_fill_rect
  ----------------------------------------------------------------------------*/
-static void _gr_direct_fill_rect(FbInfo *fbi, s32 x, s32 y, s32 w, s32 h, u32 color)
+static void _gr_direct_fill_rect(tbm_surface_info_s *surface_info, s32 x, s32 y, s32 w, s32 h, u32 color)
 {
        unsigned int *fb_buf_int = NULL;
        unsigned int *fb_buf_cur = NULL;
@@ -161,26 +170,26 @@ static void _gr_direct_fill_rect(FbInfo *fbi, s32 x, s32 y, s32 w, s32 h, u32 co
        s32 dy = 0;
        s32 wb = 0;
 
-       if (NULL == fbi)
+       if (NULL == surface_info)
                return;
 
        dx = w;
        dy = h;
        wb = w * sizeof(u32);
 
-       fb_buf_int = (unsigned int *)fbi->buf[FRONT_BUFFER];
-       fb_buf_int += y * fbi->w + x;
+       fb_buf_int = (unsigned int *)surface_info->planes[0].ptr;
+       fb_buf_int += y * surface_info->width + x;
        fb_buf_cur = fb_buf_int;
 
        while (dx--)
                *fb_buf_cur++ = color;
 
        fb_buf_cur -= w;
-       fb_buf_cur += fbi->w;
+       fb_buf_cur += surface_info->width;
        dy--;
        while (dy--) {
                memcpy((void*)fb_buf_cur, (void*)fb_buf_int, wb);
-               fb_buf_cur += fbi->w;
+               fb_buf_cur += surface_info->width;
        }
 
 }
@@ -216,10 +225,38 @@ static void _gr_direct_clear_screen(FbInfo *fbi, u32 color)
        }
 }
 
+static void _gr_direct_clear_screen_init(tbm_surface_info_s *surface_info, u32 color)
+{
+       unsigned int *fb_buf_int = NULL;
+       unsigned int *fb_buf_cur = NULL;
+       s32 dx = 0;
+       s32 dy = 0;
+       s32 w = 0;
+
+       if (NULL == surface_info)
+               return;
+
+       dx = surface_info->width;
+       dy = surface_info->height;
+       w = surface_info->width * sizeof(u32);
+
+       fb_buf_int = (unsigned int *)surface_info->planes[0].ptr;
+       fb_buf_cur = fb_buf_int;
+
+       while (dx--)
+               *fb_buf_cur++ = color;
+
+       dy--;
+       while (dy--) {
+               memcpy((void*)fb_buf_cur, (void*)fb_buf_int, w);
+               fb_buf_cur += surface_info->width;
+       }
+}
+
 /*-----------------------------------------------------------------------------
   _gr_direct_draw_text
  ----------------------------------------------------------------------------*/
-static void _gr_direct_draw_text(FbInfo *fbi, int percent)
+static void _gr_direct_draw_text(tbm_surface_info_s *surface_info, int percent)
 {
        char img_name[MAX_PATH];
        int img_x;
@@ -241,7 +278,8 @@ static void _gr_direct_draw_text(FbInfo *fbi, int percent)
                if (read_png_file(img_name) < 0)
                        return;
 
-               draw_png_img_xy(fbi, img_x, img_y);
+               //draw_png_img_xy(fbi, img_x, img_y);
+               draw_png_img_original(surface_info->planes[0].ptr, img_x, img_y, surface_info->width, surface_info->height, surface_info->planes[0].stride);
                release_png_res();
        }
 
@@ -255,7 +293,8 @@ static void _gr_direct_draw_text(FbInfo *fbi, int percent)
                if (read_png_file(img_name) < 0)
                        return;
 
-               draw_png_img_xy(fbi, img_x, img_y);
+               //draw_png_img_xy(fbi, img_x, img_y);
+               draw_png_img_original(surface_info->planes[0].ptr, img_x, img_y, surface_info->width, surface_info->height, surface_info->planes[0].stride);
                release_png_res();
        }
 
@@ -266,7 +305,8 @@ static void _gr_direct_draw_text(FbInfo *fbi, int percent)
        if (read_png_file(img_name) < 0)
                return;
 
-       draw_png_img_xy(fbi, img_x, img_y);
+       //draw_png_img_xy(fbi, img_x, img_y);
+       draw_png_img_original(surface_info->planes[0].ptr, img_x, img_y, surface_info->width, surface_info->height, surface_info->planes[0].stride);
        release_png_res();
 
        img_x += 13;
@@ -275,14 +315,15 @@ static void _gr_direct_draw_text(FbInfo *fbi, int percent)
        if (read_png_file(img_name) < 0)
                return;
 
-       draw_png_img_xy(fbi, img_x, img_y);
+       //draw_png_img_xy(fbi, img_x, img_y);
+       draw_png_img_original(surface_info->planes[0].ptr, img_x, img_y, surface_info->width, surface_info->height, surface_info->planes[0].stride);
        release_png_res();
 }
 
 /*-----------------------------------------------------------------------------
   _gr_direct_draw_prog_text
  ----------------------------------------------------------------------------*/
-static void _gr_direct_draw_prog_text(FbInfo *fbi, int percent)
+static void _gr_direct_draw_prog_text(tbm_surface_info_s *surface_info, int percent)
 {
        if (percent <= 0)
                percent = 0;
@@ -290,11 +331,11 @@ static void _gr_direct_draw_prog_text(FbInfo *fbi, int percent)
        if (percent > 100)
                percent = 100;
 
-       _gr_direct_fill_rect(fbi, 610, 395, 65, 41, COLOR_BLACK);
-       _gr_direct_draw_text(fbi, percent);
+       _gr_direct_fill_rect(surface_info, 610, 395, 65, 41, COLOR_BLACK);
+       _gr_direct_draw_text(surface_info, percent);
 }
 
-static void _gr_direct_draw_main_prog_img(FbInfo *fbi, int percent)
+static void _gr_direct_draw_main_prog_img(tbm_surface_info_s *surface_info, int percent)
 {
        int img_x = 0;
        int img_y = 0;
@@ -305,14 +346,15 @@ static void _gr_direct_draw_main_prog_img(FbInfo *fbi, int percent)
        img_x = x_offset_prog_bar_img_pos;
        img_y = y_offset_prog_bar_img_pos;
 
-       draw_png_img_xy(fbi, img_x, img_y);
+       //draw_png_img_xy(fbi, img_x, img_y);
+       draw_png_img_original(surface_info->planes[0].ptr, img_x, img_y, surface_info->width, surface_info->height, surface_info->planes[0].stride);
        release_png_res();
 }
 
 /*-----------------------------------------------------------------------------
   _gr_direct_draw_main_img
  ----------------------------------------------------------------------------*/
-static void _gr_direct_draw_main_img(FbInfo *fbi)
+static void _gr_direct_draw_main_img(tbm_surface_info_s *surface_info)
 {
        int img_x = 0;
        int img_y = 0;
@@ -323,7 +365,8 @@ static void _gr_direct_draw_main_img(FbInfo *fbi)
        img_x = 0;
        img_y = 0;
 
-       draw_png_img_xy(fbi, img_x, img_y);
+       //draw_png_img_xy(fbi, img_x, img_y);
+       draw_png_img_original(surface_info->planes[0].ptr, img_x, img_y, surface_info->width, surface_info->height, surface_info->planes[0].stride);
        release_png_res();
 
        if (read_png_file(IMG_BASE MAIN_TEXT_NAME) < 0)
@@ -332,34 +375,118 @@ static void _gr_direct_draw_main_img(FbInfo *fbi)
        img_x = x_offset_main_bg_text_pos;
        img_y = y_offset_main_bg_text_pos;
 
-       draw_png_img_xy(fbi, img_x, img_y);
+       //draw_png_img_xy(fbi, img_x, img_y);
+       draw_png_img_original(surface_info->planes[0].ptr, img_x, img_y, surface_info->width, surface_info->height, surface_info->planes[0].stride);
        release_png_res();
 
 }
 
+void _copy_buffers_by_rotate(void *srcptr, int srcw, int srch, int srcstride,
+                                                 void *dstptr, int dstw, int dsth, int dststride,
+                                                 int sx, int sy, int sw, int sh,
+                                                 int dx, int dy, int dw, int dh, int rstep)
+{
+       pixman_image_t *src_img = NULL, *dst_img = NULL;
+       pixman_op_t op;
+
+       int buf_width;
+
+       buf_width = srcstride/4;
+       src_img = pixman_image_create_bits(PIXMAN_a8r8g8b8, buf_width, srch, (uint32_t*)srcptr, srcstride);
+       if(!src_img)
+       {
+               LOG("No source image.\n");
+               return;
+       }
+
+       buf_width = dststride/4;
+       dst_img = pixman_image_create_bits(PIXMAN_a8r8g8b8, buf_width, dsth, (uint32_t*)dstptr, dststride);
+
+       struct pixman_f_transform ft;
+       double scale_x, scale_y;
+       pixman_transform_t t;
+       pixman_f_transform_init_identity(&ft);
+
+       if (rstep > 0) {
+               int c = 0, s = 0, tx = 0, ty = 0;
+               switch (rstep) {
+               case 1:
+                       c = 0, s = -1, tx = -dw;
+                       break;
+               case 2:
+                       c = -1, s = 0, tx = -dw, ty = -dh;
+                       break;
+               case 3:
+                       c = 0, s = 1, ty = -dh;
+                       break;
+               }
+               pixman_f_transform_translate(&ft, NULL, tx, ty);
+               pixman_f_transform_rotate(&ft, NULL, c, s);
+       }
+
+       if (rstep % 2 == 0) {
+               scale_x = (double)sw / dw;
+               scale_y = (double)sh / dh;
+       } else {
+               scale_x = (double)sw / dh;
+               scale_y = (double)sh / dw;
+       }
+       pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
+       pixman_f_transform_translate(&ft, NULL, sx, sy);
+       pixman_transform_from_pixman_f_transform(&t, &ft);
+       pixman_image_set_transform(src_img, &t);
+
+
+       op = PIXMAN_OP_SRC;
+       pixman_image_composite(op, src_img, NULL, dst_img, 0, 0, 0, 0, dx, dy, dw, dh);
+
+       if (src_img)
+               pixman_image_unref(src_img);
+       if (dst_img)
+               pixman_image_unref(dst_img);
+}
+
 /*-----------------------------------------------------------------------------
   __init_screen
  ----------------------------------------------------------------------------*/
 static void __init_screen(FbInfo *fbi)
 {
-       _gr_direct_clear_screen(fbi, COLOR_BLACK);
+       /* create tbm_surface for original image */
+       tbm_surface_h tbm_surface_ori = NULL;
+       tbm_surface_info_s surface_info_ori;
+       tbm_surface_ori = tbm_surface_create(img_buf_width, img_buf_height, TBM_FORMAT_ARGB8888);  // rotated width, height
+       if(!tbm_surface_ori){
+               LOG("failed to tbm_surface_create\n");
+       }
+       tbm_surface_map(tbm_surface_ori, TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE, &surface_info_ori);
+
+
+       _gr_direct_clear_screen_init(&surface_info_ori, COLOR_BLACK);
+
+       _gr_direct_draw_main_img(&surface_info_ori);
 
-       //_gr_direct_draw_text_img(fbi);
+       _gr_direct_draw_main_prog_img(&surface_info_ori, 0);
 
-       _gr_direct_draw_main_img(fbi);
+       _gr_direct_draw_prog_text(&surface_info_ori, 0);
 
-       _gr_direct_draw_main_prog_img(fbi, 0);
 
-       _gr_direct_draw_prog_text(fbi, 0);
+       _copy_buffers_by_rotate(surface_info_ori.planes[0].ptr, surface_info_ori.width, surface_info_ori.height, surface_info_ori.planes[0].stride,
+                                       fbi->buf[0], fbi->w, fbi->h, fbi->w * RGB32_PITCH,
+                                       0,0,surface_info_ori.width, surface_info_ori.height,
+                                       0,0,fbi->w, fbi->h, rotate_step);
+       tbm_surface_unmap(tbm_surface_ori);
+       tbm_surface_destroy(tbm_surface_ori);
 }
 
-static void _gr_direct_progress_bar(FbInfo *fbi, int progress)
+static void _gr_direct_progress_bar(tbm_surface_info_s *surface_info, int progress)
 {
        char img_name[MAX_PATH];
 
        static int prog_pre = 0;
        int count = 0;
        int prog_cnt = 0;
+       int img_x = 0;
+       int img_y = 0;
 
        if (progress <= 0)
                return;
@@ -369,6 +496,10 @@ static void _gr_direct_progress_bar(FbInfo *fbi, int progress)
 
        prog_cnt = progress;
 
+
+       img_x = x_offset_prog_bar_img_pos;
+       img_y = y_offset_prog_bar_img_pos;
+
        for (; prog_pre <= prog_cnt; prog_pre++) {
                LOG("prog_pre/prog_cnt : %d, %d \n", prog_pre , prog_cnt);
 
@@ -379,15 +510,18 @@ static void _gr_direct_progress_bar(FbInfo *fbi, int progress)
                        return;
                }
 
-               draw_png_img_xy(fbi, 240, 355);
+               //draw_png_img_xy(fbi, 240, 355);
+               draw_png_img_original(surface_info->planes[0].ptr, img_x, img_y, surface_info->width, surface_info->height, surface_info->planes[0].stride);
                release_png_res();
 
                s_saved_percent = prog_pre;
 
-               count++;
-
-               if (count > 3)
-                       break;
+               if(progress != 100)
+               {
+                       count++;
+                       if (count > 3)
+                               break;
+               }
        }
 }
 
@@ -409,11 +543,34 @@ void recovery_gr_direct_progress(void)
        LOG("recovery_gr_direct_progress progress : %d \n", s_percent_to_draw);
 
        if (s_percent_to_draw > 0) {
-               _gr_direct_progress_bar(&s_fbi, s_percent_to_draw);
-               _gr_direct_draw_prog_text(&s_fbi, s_saved_percent);
+               /* create tbm_surface for original image */
+               tbm_surface_h tbm_surface_ori = NULL;
+               tbm_surface_info_s surface_info_ori;
+
+               tbm_surface_ori = tbm_surface_create(img_buf_width, img_buf_height, TBM_FORMAT_ARGB8888);  // rotated width, height
+               if(!tbm_surface_ori){
+                       LOG("failed to tbm_surface_create\n");
+               }
+               tbm_surface_map(tbm_surface_ori, TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE, &surface_info_ori);
+               // need to keep previous image
+               _copy_buffers_by_rotate(s_fbi.buf[0], s_fbi.w, s_fbi.h, s_fbi.w * RGB32_PITCH,
+                               surface_info_ori.planes[0].ptr, surface_info_ori.width, surface_info_ori.height, surface_info_ori.planes[0].stride,
+                               0,0,s_fbi.w, s_fbi.h,
+                               0,0,surface_info_ori.width, surface_info_ori.height, rollback_step);
+
+               _gr_direct_progress_bar(&surface_info_ori, s_percent_to_draw);
+               _gr_direct_draw_prog_text(&surface_info_ori, s_saved_percent);
+
+               _copy_buffers_by_rotate(surface_info_ori.planes[0].ptr, surface_info_ori.width, surface_info_ori.height, surface_info_ori.planes[0].stride,
+                                       s_fbi.buf[0], s_fbi.w, s_fbi.h, s_fbi.w * RGB32_PITCH,
+                                       0,0,surface_info_ori.width, surface_info_ori.height,
+                                       0,0,s_fbi.w, s_fbi.h, rotate_step);
+               tbm_surface_unmap(tbm_surface_ori);
+               tbm_surface_destroy(tbm_surface_ori);
        } else if (s_percent_to_draw == 0) {
                        s_saved_percent = 0;
        }
+
        _gr_direct_update_screen();
 }
 
@@ -457,6 +614,35 @@ void recovery_gr_direct_clear_screen(u32 color)
        _gr_direct_update_screen();
 }
 
+void _get_rotate(void)
+{
+       char *rotate_state = getenv("ROTATE_STATE");
+       int rotate_angle = -1;
+       if(!rotate_state)
+       {
+               rotate_angle = ROTATE;
+       }
+       else
+       {
+               rotate_angle = atoi(rotate_state);
+       }
+
+       LOG("Print Rotate Angle value = %d\n", rotate_angle);
+
+       rotate_step = (rotate_angle + 360) / 90 % 4;
+       rollback_step = (4 - rotate_step) % 4;
+       LOG("rotate_step = %d, rollback_step = %d\n", rotate_step, rollback_step);
+
+       if (rotate_step % 2 == 0) {
+               img_buf_width = s_fbi.w;
+               img_buf_height = s_fbi.h;
+       } else {
+               img_buf_width = s_fbi.h;
+               img_buf_height = s_fbi.w;
+       }
+       LOG("Print Img buffer(=image w,h) width = %d, height = %d\n", img_buf_width, img_buf_height);
+}
+
 /*-----------------------------------------------------------------------------
   recovery_gr_direct_init
  ----------------------------------------------------------------------------*/
@@ -466,6 +652,7 @@ int recovery_gr_direct_init(void)
        if (fb_open(&s_fbi) < 0)
                LOG("fb_open failed \n");
 
+       _get_rotate();
        __init_screen(&s_fbi);
 
        tdm_if_lcd_on(&s_disp);
index 21f7083788935187efd54a282a2ccd91f8dfca35..957e6fe85c3874830422e4be47da8f83b36077bb 100644 (file)
@@ -381,6 +381,123 @@ void draw_png_img_xy(FbInfo *fbi, int x1, int y1)
 
 }
 
+/*-----------------------------------------------------------------------------
+  draw_png_img_original()
+ ----------------------------------------------------------------------------*/
+void draw_png_img_original(void *fbi, int x1, int y1, int fbi_w, int fbi_h, int fbi_stride)
+{
+       unsigned int *fb_buf_cur = NULL;
+       int bpp;
+       int x, y;
+       int end_width, end_height;
+       /* temp patch - lcd resoultion for qualcomm */
+
+       fb_buf_cur = (unsigned int *)fbi;
+
+       /* check out range */
+       if ((x1 > fbi_w ) || (y1 > fbi_h)) {
+               LOG("[draw_png_img_xy] output range exceeds frame buffer range \n");
+                       return;
+       }
+       if(x1 + png_img_width > fbi_w)
+               end_width = fbi_w- x1;
+       else
+               end_width = png_img_width;
+       if(y1 + png_img_height > fbi_h)
+               end_height = fbi_h - y1;
+       else
+               end_height = png_img_height;
+
+       LOG("png_color_type = [%d]", png_color_type);
+       if (png_color_type == PNG_COLOR_TYPE_RGB) {
+               bpp = 3;
+               LOG("png color type is PNG_COLOR_TYPE_RGB, png_color_type = [%d]\n", png_color_type);
+       } else if (png_color_type == PNG_COLOR_TYPE_RGBA) {
+               bpp = 4;
+               LOG("png color type is PNG_COLOR_TYPE_RGBA, png_color_type = [%d]\n", png_color_type);
+       } else {
+               LOG("[draw_png_img_xy] png type does not match RGB or RGBA \n");
+
+               LOG("[draw_png_img_xy] png type does not match RGB or RGBA, png_color_type = [%d] \n", png_color_type);
+               return;
+       }
+
+       /* temp patch - lcd resoultion for qualcomm */
+       for (y = 0; y < png_img_height; y++) {
+               if(y > end_height) continue;
+               fb_buf_cur = (unsigned int *) (fbi  + ((y1 + y) * fbi_stride));
+               fb_buf_cur += x1;
+               png_byte *row = (png_byte *) row_pointers[y];
+               for (x = 0; x < png_img_width; x++) {
+                       if(x > end_width) continue;
+                       if (bpp == 3) {
+                               if (png_bit_depth == 8) {
+                                       (*fb_buf_cur) = ((*fb_buf_cur)&0xff000000) |
+                                           (row[0] << 16) | (row[1] << 8) | (row[2]);
+                                       row += bpp;
+                               } else if (png_bit_depth == 16) {
+                                       (*fb_buf_cur) = ((*fb_buf_cur)&0xff000000) |
+                                           (row[0] << 16) | (row[2] << 8) | (row[4]);
+                                       row += bpp*2;
+                               }
+                       } else if (bpp == 4) {
+                               if (png_bit_depth == 8) {
+                                       if (row[3] != 0) {
+                                               char r1, g1, b1, a1;
+                                               char r2, g2, b2, a2;
+                                               char r3, g3, b3, a3;
+                                               // background pixel
+                                               b1 = ((*fb_buf_cur)&0x000000ff);
+                                               g1 = ((*fb_buf_cur)&0x0000ff00)>>8;
+                                               r1 = ((*fb_buf_cur)&0x00ff0000)>>16;
+                                               a1 = ((*fb_buf_cur)&0xff000000)>>24;
+                                               // new pixel
+                                               r2 = row[0];
+                                               g2 = row[1];
+                                               b2 = row[2];
+                                               a2 = row[3];
+                                               // blended pixel
+                                               r3 = (r2 * a2 + r1 * (0xff - a2)) >> 8 ;
+                                               g3 = (g2 * a2 + g1 * (0xff - a2)) >> 8;
+                                               b3 = (b2 * a2 + b1 * (0xff - a2)) >> 8;
+                                               a3 = a1;
+                                               (*fb_buf_cur) = (a3 << 24) |
+                                                   (r3 << 16) | (g3 << 8) | (b3);
+                                       }
+                                       row += bpp;
+                               } else if (png_bit_depth == 16) {
+                                       if (row[6] != 0) {
+                                               short r1, g1, b1, a1;
+                                               short r2, g2, b2, a2;
+                                               char r3, g3, b3, a3;
+                                               // background pixel
+                                               b1 = ((*fb_buf_cur)&0x000000ff)<<8;
+                                               g1 = ((*fb_buf_cur)&0x0000ff00);
+                                               r1 = ((*fb_buf_cur)&0x00ff0000)>>8;
+                                               a1 = ((*fb_buf_cur)&0xff000000)>>16;
+                                               // new pixel
+                                               r2 = (row[0]<<8) + row[1];
+                                               g2 = (row[2]<<8) + row[3];
+                                               b2 = (row[4]<<8) + row[5];
+                                               a2 = (row[6]<<8) + row[7];
+                                               // blended pixel
+                                               r3 = (r2 * a2 + r1 * (0xffff - a2)) >> 24;
+                                               g3 = (g2 * a2 + g1 * (0xffff - a2)) >> 24;
+                                               b3 = (b2 * a2 + b1 * (0xffff - a2)) >> 24;
+                                               a3 = a1 >> 8;
+                                               (*fb_buf_cur) = (a3 << 24) |
+                                                       (r3 << 16) | (g3 << 8) | (b3);
+                                       }
+                                       row += bpp*2;
+                               }
+                       }
+                       fb_buf_cur++;
+               }
+       }
+
+}
+
+
 /*-----------------------------------------------------------------------------
   draw_png_mask_xy()
   - draw pixel only when alpha>0 of given png image
index c8b9e0000444cd1d54bdfa27aaa0891330981c16..c576a83e5504ed4081a767d824ad26c439a7d7d0 100644 (file)
@@ -23,6 +23,7 @@
 
 extern int read_png_file(char *file_name);
 extern void draw_png_img_xy(FbInfo *fbi, int x1, int y1);
+extern void draw_png_img_original(void *fbi, int x1, int y1, int fbi_w, int fbi_h, int fbi_stride);
 extern void draw_png_img_clip_xy(FbInfo *fbi, int x1, int y1, int cx, int cy, int cw, int ch);
 extern void draw_png_mask_xy(FbInfo *fbi, int x1, int y1, char r, char g, char b);
 extern void release_png_res(void);